This commit is contained in:
LunarAkai 2025-08-10 09:51:27 +02:00
commit 42e6b66eb5
6 changed files with 86 additions and 26 deletions

View file

@ -3,28 +3,43 @@ use crate::language_frontend::abstract_syntax_tree::definitions::*;
// Option and Result -> define in Std // Option and Result -> define in Std
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub enum Expr { pub enum Expr {
Ident(String), // var/fun_name
Ident(Identifier),
// 4
IntLiteral(i64), IntLiteral(i64),
// 12.5
FloatLiteral(f64), FloatLiteral(f64),
// "eepy"
StringLiteral(String), StringLiteral(String),
// true
BoolLiteral(bool), BoolLiteral(bool),
// 'c'
CharLiteral(char), CharLiteral(char),
// var x = intPlusOne(12)
CallExpr(Call), CallExpr(Call),
// !x
UnaryExpr(Unary), UnaryExpr(Unary),
// 1 + 11
BinaryExpr(Binary), BinaryExpr(Binary),
// x = 64
AssignmentExpr(Assignment), AssignmentExpr(Assignment),
// var foo = "bar"
VarExpr(Var), VarExpr(Var),
// if(...) { ... } else { ... }
Condition(Condition),
// fun helloWorld() { ... }
FunctionExpr(Function), FunctionExpr(Function),
Error, Error,

View file

@ -2,23 +2,21 @@ use std::{ops::Range, rc::Rc};
use crate::language_frontend::abstract_syntax_tree::ast::Expr; use crate::language_frontend::abstract_syntax_tree::ast::Expr;
/// Abstract Syntax Tree // Abstract Syntax Tree
pub type BlockStatement = Vec<Statement>;
pub type BlockExpression = Vec<Expr>;
pub type Span = Range<usize>; pub type Span = Range<usize>;
#[derive(Clone, Debug, PartialEq)]
pub enum Statement {
Var(Ident, Option<Type>),
}
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub enum BinaryOp { pub enum BinaryOp {
// Arithmetic
Multiply, Multiply,
Divide, Divide,
Add, Add,
Substract, Substract,
// Comparision
Equals, Equals,
NotEquals, NotEquals,
Less, Less,
@ -26,15 +24,16 @@ pub enum BinaryOp {
Greater, Greater,
GreaterEquals, GreaterEquals,
// Logical
And, And,
Or, Or,
// todo: bitwise
} }
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub enum UnaryOp { pub enum UnaryOp {
Not, Not,
Minus, Negate,
Plus,
} }
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
@ -82,19 +81,20 @@ impl Value {
// Structs // Structs
//--------------------------------------- //---------------------------------------
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct Ident(pub Rc<str>); pub struct Identifier(pub String);
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct While { pub struct While {
pub condition: Expr, pub condition: Box<Expr>,
pub body: BlockStatement, pub body: BlockExpression,
} }
/// Example: `if (a > 12) { ... }`
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct Condition { pub struct Condition {
pub condition: Expr, pub condition: Box<Expr>,
pub if_body: BlockStatement, pub if_body: BlockExpression,
pub else_body: Option<BlockStatement>, pub else_body: Option<BlockExpression>,
} }
/// Example: `x = y` /// Example: `x = y`
@ -108,7 +108,7 @@ pub struct Assignment {
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct Var { pub struct Var {
pub ty: Option<Type>, pub ty: Option<Type>,
pub ident: String, pub ident: Identifier,
pub value: Box<Expr>, pub value: Box<Expr>,
} }
@ -145,14 +145,17 @@ pub struct Binary {
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct Function { pub struct Function {
pub name: String, pub name: String,
pub params: Option<Vec<(Ident, Type)>>, pub params: Option<Vec<(Identifier, Type)>>,
pub return_type: Option<Type>, pub return_type: Option<Type>,
pub body: Option<Vec<Expr>>, pub body: Option<BlockExpression>,
pub body_expr: Option<Box<Expr>>, pub body_expr: Option<Box<Expr>>, // ' -> (return)'
} }
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub struct Call { pub struct Call {
pub callee: Box<Expr>, /// name of the function being called
pub name: Box<Identifier>,
/// arguments supplied
pub arguments: Vec<Expr>, pub arguments: Vec<Expr>,
} }

View file

@ -115,7 +115,7 @@ where
.map(|(name, rhs)| { .map(|(name, rhs)| {
Expr::VarExpr(Var { Expr::VarExpr(Var {
ty: None, ty: None,
ident: name, ident: Identifier(String::from(name)),
value: Box::new(rhs), value: Box::new(rhs),
}) })
}); });
@ -157,12 +157,12 @@ mod tests {
#[test] #[test]
fn test_unary_expr() { fn test_unary_expr() {
let negate_two = parse("-2"); let negate_two = parse("!2");
assert!(negate_two.is_ok()); assert!(negate_two.is_ok());
assert_eq!( assert_eq!(
negate_two.clone().unwrap(), negate_two.clone().unwrap(),
vec![Expr::UnaryExpr(Unary { vec![Expr::UnaryExpr(Unary {
operator: UnaryOp::Minus, operator: UnaryOp::Negate,
operand: Box::new(Expr::IntLiteral(2)), operand: Box::new(Expr::IntLiteral(2)),
})] })]
) )
@ -176,7 +176,7 @@ mod tests {
var_bool.clone().unwrap(), var_bool.clone().unwrap(),
vec![Expr::VarExpr(Var { vec![Expr::VarExpr(Var {
ty: None, ty: None,
ident: String::from("isUwU"), ident: Identifier(String::from("isUwU")),
value: Box::new(Expr::BoolLiteral(true)) value: Box::new(Expr::BoolLiteral(true))
})] })]
) )
@ -204,7 +204,7 @@ mod tests {
var_without_expl_type.clone().unwrap(), var_without_expl_type.clone().unwrap(),
vec![Expr::VarExpr(Var { vec![Expr::VarExpr(Var {
ty: None, ty: None,
ident: String::from("x"), ident: Identifier(String::from("x")),
value: Box::new(Expr::IntLiteral(12)) value: Box::new(Expr::IntLiteral(12))
})] })]
) )
@ -225,6 +225,7 @@ mod tests {
#[test] #[test]
fn test_function_decl() { fn test_function_decl() {
// test without a body or args
let empty_fun = parse("fun helloWorld() { }"); let empty_fun = parse("fun helloWorld() { }");
assert!(empty_fun.is_ok()); assert!(empty_fun.is_ok());
assert_eq!( assert_eq!(
@ -238,6 +239,7 @@ mod tests {
})] })]
); );
// tests if empty new lines within a function works
let empty_fun_with_new_lines = parse( let empty_fun_with_new_lines = parse(
r"fun emptyMulLines() { r"fun emptyMulLines() {
@ -255,6 +257,7 @@ mod tests {
})] })]
); );
// tests for return expr in functions
let fun_that_returns_int = parse( let fun_that_returns_int = parse(
r"fun returnsInt(): int { r"fun returnsInt(): int {
-> 12 -> 12

37
src/llvm_backend/llvm.rs Normal file
View file

@ -0,0 +1,37 @@
use chumsky::prelude::todo;
use inkwell::{
OptimizationLevel,
builder::{self, Builder},
context::Context,
execution_engine::ExecutionEngine,
module::Module,
types::BasicTypeEnum,
values::{BasicValueEnum, FunctionValue},
};
use crate::language_frontend::abstract_syntax_tree::{
ast::Expr,
definitions::{Function, Type},
};
pub struct CodeGen<'ctx> {
pub(crate) context: &'ctx Context,
pub(crate) module: Module<'ctx>,
pub(crate) builder: Builder<'ctx>,
pub(crate) exec_engine: ExecutionEngine<'ctx>,
}
impl<'ctx> CodeGen<'ctx> {
pub fn new(context: &'ctx Context, module_name: &str, opt_level: OptimizationLevel) -> Self {
let module = context.create_module(module_name);
let exec_engine = module.create_jit_execution_engine(opt_level).unwrap();
let builder = context.create_builder();
CodeGen {
context,
module,
builder,
exec_engine,
}
}
}

1
src/llvm_backend/mod.rs Normal file
View file

@ -0,0 +1 @@
pub mod llvm;

View file

@ -3,6 +3,7 @@ use chumsky::input::{Input, Stream};
use logos::Logos; use logos::Logos;
mod language_frontend; mod language_frontend;
mod llvm_backend;
use crate::{ use crate::{
language_frontend::abstract_syntax_tree::parser::parse, language_frontend::lexer::tokens::Token, language_frontend::abstract_syntax_tree::parser::parse, language_frontend::lexer::tokens::Token,