diff --git a/src/language_frontend/abstract_syntax_tree/definitions.rs b/src/language_frontend/abstract_syntax_tree/definitions.rs index aaf0001..b8be826 100644 --- a/src/language_frontend/abstract_syntax_tree/definitions.rs +++ b/src/language_frontend/abstract_syntax_tree/definitions.rs @@ -148,7 +148,7 @@ pub struct Function { pub params: Option>, pub return_type: Option, pub body: Option, - pub body_expr: Option>, // ' -> (return)' + pub return_expr: Box>, // ' -> (return)' } #[derive(Clone, Debug, PartialEq)] diff --git a/src/language_frontend/abstract_syntax_tree/mod.rs b/src/language_frontend/abstract_syntax_tree/mod.rs index 1687eca..a1f9b61 100644 --- a/src/language_frontend/abstract_syntax_tree/mod.rs +++ b/src/language_frontend/abstract_syntax_tree/mod.rs @@ -1,3 +1,52 @@ pub mod ast; pub mod definitions; pub mod parser; + +#[macro_export] +macro_rules! token { + (var) => { + just(Token::Var) + }; + (=) => { + just(Token::Assign) + }; + (if) => { + just(Token::If) + }; + (else) => { + just(Token::Else) + }; + (->) => { + just(Token::Return) + }; + (:) => { + just(Token::Colon) + }; + (,) => { + just(Token::Comma) + }; + (*) => { + just(Token::Multiply) + }; + (/) => { + just(Token::Divide) + }; + (+) => { + just(Token::Add) + }; + (-) => { + just(Token::Substract) + }; + (lp) => { + just(Token::LParen) + }; + (rp) => { + just(Token::RParen) + }; + (lbrace) => { + just(Token::LBrace) + }; + (rbrace) => { + just(Token::RBrace) + }; +} diff --git a/src/language_frontend/abstract_syntax_tree/parser.rs b/src/language_frontend/abstract_syntax_tree/parser.rs index cb385a2..14c7690 100644 --- a/src/language_frontend/abstract_syntax_tree/parser.rs +++ b/src/language_frontend/abstract_syntax_tree/parser.rs @@ -1,6 +1,7 @@ use chumsky::{ Boxed, ConfigIterParser, IterParser, ParseResult, Parser, combinator::Or, + container::Seq, error::{Rich, Simple}, extra, input::{Input, Stream, ValueInput}, @@ -14,11 +15,15 @@ use chumsky::{ newline, whitespace, }, }; +use inkwell::Either; use logos::{Logos, source}; -use crate::language_frontend::{ - abstract_syntax_tree::{ast::Expr, definitions::*}, - lexer::tokens::Token, +use crate::{ + language_frontend::{ + abstract_syntax_tree::{ast::Expr, definitions::*}, + lexer::tokens::Token, + }, + token, }; // goal of parsing is to construct an abstract syntax tree @@ -50,15 +55,13 @@ where Token::StringLiteral(s) => Expr::StringLiteral(s), } .labelled("value") - .or(expr - .clone() - .delimited_by(just(Token::LParen), just(Token::RParen))); + .or(expr.clone().delimited_by(token!(lp), token!(rp))); // Product let mul_div = atom.clone().foldl( choice(( - just(Token::Multiply).to(BinaryOp::Multiply), - just(Token::Divide).to(BinaryOp::Divide), + token!(*).to(BinaryOp::Multiply), + token!(/).to(BinaryOp::Divide), )) .then(atom) .then_ignore(just(Token::NewLine).or_not()) @@ -75,8 +78,8 @@ where // Sum let add_sub = mul_div.clone().foldl( choice(( - just(Token::Add).to(BinaryOp::Add), - just(Token::Substract).to(BinaryOp::Substract), + token!(+).to(BinaryOp::Add), + token!(-).to(BinaryOp::Substract), )) .then(mul_div) .then_ignore(just(Token::NewLine).or_not()) @@ -91,7 +94,7 @@ where ); let assign_expr = ident - .then_ignore(just(Token::Assign)) + .then_ignore(token!(=)) .then(expr.clone()) .map(|(name, value)| { Expr::AssignmentExpr(Assignment { @@ -104,9 +107,9 @@ where }); let decl = recursive(|decl| { - let var = just(Token::Var) + let var = token!(var) .ignore_then(ident) - .then_ignore(just(Token::Assign)) + .then_ignore(token!(=)) .then(expr.clone()) .then_ignore(just(Token::NewLine).or_not()) .map(|(name, rhs)| { @@ -124,11 +127,9 @@ where just(Token::StringType).to(Type::String), )); - let return_type_parser = just(Token::Colon).ignore_then(type_parser.clone()).or_not(); + let return_type_parser = token!(:).ignore_then(type_parser.clone()).or_not(); - let return_expr = just(Token::Return) - .ignore_then(expr.clone()) - .map(|expr| (expr)); + let return_expr = token!(->).ignore_then(expr.clone()).map(|expr| expr); //--------------------------------------------------------------------------------------- // Function Parser @@ -138,33 +139,33 @@ where .then( // arguments ident - .then_ignore(just(Token::Colon)) + .then_ignore(token!(:)) .then(type_parser.clone()) - .separated_by(just(Token::Comma)) + .separated_by(token!(,)) .allow_trailing() .collect::>() - .delimited_by(just(Token::LParen), just(Token::RParen)) + .delimited_by(token!(lp), token!(rp)) .or_not(), ) .then(return_type_parser.clone()) // return type - .then_ignore(just(Token::LBrace)) // { + .then_ignore(token!(lbrace)) // { .then_ignore(just(Token::NewLine).repeated().or_not()) - .then_ignore(return_expr.or_not()) .then( expr.clone() .then_ignore(just(Token::NewLine)) .repeated() - .collect::>(), + .collect::>() + .then(return_expr.or_not()), ) .then_ignore(just(Token::NewLine).repeated().or_not()) - .then_ignore(just(Token::RBrace)) // } - .map(|(((name, params), return_ty), stmts)| { + .then_ignore(token!(rbrace)) // } + .map(|(((name, params), return_ty), (stmts, return_value))| { Expr::FunctionExpr(Function { name: name, params, return_type: return_ty, body: Some(stmts), - body_expr: None, + return_expr: Box::new(return_value), }) }); @@ -261,7 +262,7 @@ mod tests { params: Some([].to_vec()), return_type: None, body: Some([].to_vec()), - body_expr: None, + return_expr: Box::new(None), })] ); @@ -279,7 +280,7 @@ mod tests { params: Some([].to_vec()), return_type: None, body: Some([].to_vec()), - body_expr: None, + return_expr: Box::new(None), })] ); @@ -292,12 +293,32 @@ mod tests { ); assert_eq!( fun_that_returns_int.clone().unwrap(), + vec![Expr::FunctionExpr(Function { + name: String::from("returnsInt"), + params: Some([].to_vec()), + return_type: Some(Type::Integer), + body: Some([].to_vec()), + return_expr: Box::new(Some(Expr::IntLiteral(12))), + })] + ); + + // tests for return expr with previous statements in functions + let fun_multi_line_return = parse( + r"fun returnsInt(): int { + var x = 12 + x = x + 1 + -> x + } + ", + ); + assert_eq!( + fun_multi_line_return.clone().unwrap(), vec![Expr::FunctionExpr(Function { name: String::from("returnsInt"), params: Some([].to_vec()), return_type: Some(Type::Integer), body: Some(vec![Expr::IntLiteral(12)]), - body_expr: Some(Box::new(Expr::ReturnExpr)), + return_expr: Box::new(Some(Expr::ReturnExpr)), })] ) } diff --git a/src/llvm_backend/llvm.rs b/src/llvm_backend/llvm.rs index f7c1d42..3ddba9e 100644 --- a/src/llvm_backend/llvm.rs +++ b/src/llvm_backend/llvm.rs @@ -34,4 +34,6 @@ impl<'ctx> CodeGen<'ctx> { exec_engine, } } + + fn compile_expr(&mut self, expr: &Expr) {} }