diff --git a/examples/input1.bic b/examples/input1.bic index b39b04c..87a4476 100644 --- a/examples/input1.bic +++ b/examples/input1.bic @@ -1 +1,7 @@ -let b = 34; \ No newline at end of file +def print_me() -> void { + let a = 222; +} + +def main() -> void { + print_me(); +} \ No newline at end of file diff --git a/src/ast/expr.rs b/src/ast/expr.rs index 9618c68..7acc33b 100644 --- a/src/ast/expr.rs +++ b/src/ast/expr.rs @@ -74,10 +74,10 @@ impl Expr { match self { Expr::LitVal(lit_val) => Ok(lit_val.value.clone()), Expr::Binary(bin) => { - let left_evaled = bin.left.eval(); - let right_evaled = bin.right.eval(); + let left_evaled: Result = bin.left.eval(); + let right_evaled: Result = bin.right.eval(); if let (Ok(left_type), Ok(right_type)) = (left_evaled, right_evaled) { - let compat_res = are_compatible_for_operation::(&left_type, &right_type, bin.operation); + let compat_res: (bool, LitTypeVariant) = are_compatible_for_operation::(&left_type, &right_type, bin.operation); if !compat_res.0 { return Err(BTypeErr::IncompatibleTypes { first_type: left_type.to_string(), @@ -106,6 +106,9 @@ impl Expr { panic!() } } + Expr::Ident(_) => { + panic!("Identifiers in an expression is not supported at compile-time expression evaluation."); + } _ => panic!() } } diff --git a/src/ast/stmt.rs b/src/ast/stmt.rs index 3d30ee4..528fb71 100644 --- a/src/ast/stmt.rs +++ b/src/ast/stmt.rs @@ -18,6 +18,11 @@ pub struct AssignStmt { pub symtbl_pos: usize } +#[derive(Clone, Debug)] +pub struct FuncCallStmt { + pub symtbl_pos: usize +} + #[derive(Clone, Debug)] pub enum Stmt { Glue, @@ -29,4 +34,5 @@ pub enum Stmt { Assignment(AssignStmt), VarDecl(VarDeclStmt), LValue(usize), // usize for symbol table position of this left value + FuncCall(FuncCallStmt) } \ No newline at end of file diff --git a/src/code_gen/aarch64/aarch64_codegen.rs b/src/code_gen/aarch64/aarch64_codegen.rs index 74c7598..c660fe6 100644 --- a/src/code_gen/aarch64/aarch64_codegen.rs +++ b/src/code_gen/aarch64/aarch64_codegen.rs @@ -376,6 +376,15 @@ impl<'aarch64> CodeGen for Aarch64CodeGen<'aarch64> { fn reg_manager(&self) -> RefMut { self.reg_manager.borrow_mut() } + + fn gen_func_call_stmt(&mut self, symbol_id: usize) { + if let Some(ctx_rc) = &self.ctx { + let ctx_borrow = ctx_rc.borrow_mut(); + if let Some(symbol) = ctx_borrow.sym_table.get_symbol(symbol_id) { + println!("call {}", symbol.name); + } + } + } } impl<'aarch64> Aarch64CodeGen<'aarch64> { diff --git a/src/code_gen/codegen.rs b/src/code_gen/codegen.rs index 9230565..92f608c 100644 --- a/src/code_gen/codegen.rs +++ b/src/code_gen/codegen.rs @@ -24,6 +24,8 @@ SOFTWARE. use std::cell::RefMut; +use crate::ast; +use crate::ast::ASTKind; use crate::ast::BinExpr; use crate::ast::Expr; use crate::ast::LitValExpr; @@ -119,7 +121,20 @@ pub trait CodeGen { } return 0xFFFFFFFF; } - else if ast_node.operation == ASTOperation::AST_RETURN { + else if ast_node.operation == ASTOperation::AST_FUNC_CALL { + if ast_node.result_type == LitTypeVariant::Void { + if let ASTKind::StmtAST(func_call_stmt) = &ast_node.kind { + match func_call_stmt { + Stmt::FuncCall(func_call) => { + self.gen_func_call_stmt(func_call.symtbl_pos); + }, + _ => return 0xFFFFFFFF + } + } + } + 0xFFFFFFFF + } + else if ast_node.operation == ASTOperation::AST_RETURN { let possible_ret_stmt: Stmt = ast_node.kind.clone().unwrap_stmt(); let return_expr: &AST = ast_node.left.as_ref().unwrap(); let result_reg: usize = self.gen_expr(&return_expr.kind.clone().unwrap_expr(), ast_node.operation, reg, parent_ast_kind); @@ -184,7 +199,7 @@ pub trait CodeGen { Expr::Subscript(subs) => { let index_reg: usize = self.gen_expr(&subs.index, curr_ast_kind, reg, parent_ast_kind); self.gen_array_access2(subs.symtbl_pos, index_reg) - }, + } _ => panic!("Error: Unknown Expr type '{:?}'", expr), } } @@ -299,5 +314,7 @@ pub trait CodeGen { fn gen_return_stmt(&mut self, result_reg: usize, _func_id: usize) -> usize; + fn gen_func_call_stmt(&mut self, symbol_id: usize); + fn reg_manager(&self) -> RefMut; } \ No newline at end of file diff --git a/src/parser/parser_impl.rs b/src/parser/parser_impl.rs index 40eb49f..78c1570 100644 --- a/src/parser/parser_impl.rs +++ b/src/parser/parser_impl.rs @@ -28,6 +28,7 @@ use crate::ast::AssignStmt; use crate::ast::BinExpr; use crate::ast::Expr; use crate::ast::FuncCallExpr; +use crate::ast::FuncCallStmt; use crate::ast::FuncDeclStmt; use crate::ast::IdentExpr; use crate::ast::LitValExpr; @@ -183,7 +184,7 @@ impl<'parser> Parser<'parser> { fn parse_single_stmt(&mut self) -> ParseResult2 { match self.current_token.kind { TokenKind::KW_LET => self.parse_var_decl_stmt(), - TokenKind::T_IDENTIFIER => self.parse_assignment_stmt(), + TokenKind::T_IDENTIFIER => self.assign_stmt_or_func_call(), TokenKind::KW_IF => self.parse_if_stmt(), TokenKind::KW_WHILE => self.parse_while_stmt(), TokenKind::KW_FOR => self.parse_for_stmt(), @@ -277,9 +278,7 @@ impl<'parser> Parser<'parser> { let function_body_res: ParseResult2 = self.parse_compound_stmt(); let function_body: AST = match function_body_res { Ok(ast) => ast, - Err(err) => { - panic!("{:?}", err); - } + Err(err) => return Err(err) }; let temp_func_id: usize = self.current_function_id; self.current_function_id = INVALID_FUNC_ID; // function parsing done; exiting out of function body @@ -670,8 +669,30 @@ impl<'parser> Parser<'parser> { } } - fn parse_assignment_stmt(&mut self) -> ParseResult2 { + fn assign_stmt_or_func_call(&mut self) -> ParseResult2 { let id_token: Token = self.token_match(TokenKind::T_IDENTIFIER).clone(); + let tok_kind_after_id_tok: TokenKind = self.current_token.kind; + if tok_kind_after_id_tok != TokenKind::T_LPAREN { + self.parse_assignment_stmt(id_token) + } else { + let mut symbol_pos: usize = 0; + let symbol: Option = if let Some(ctx_rc) = &mut self.ctx { + let ctx_borrow = ctx_rc.borrow_mut(); + let sym_pos = ctx_borrow.sym_table.find_symbol(&id_token.lexeme); + if let Some(sp) = sym_pos { + symbol_pos = sp; + ctx_borrow.sym_table.get_symbol(sp).cloned() + } else { None } + } else { None }; + if let Some(sym) = symbol { + self.parse_func_call_expr(&sym, symbol_pos, &id_token) + } else { + Err(Box::new(BErr::undefined_symbol(self.get_current_file_name(), id_token))) + } + } + } + + fn parse_assignment_stmt(&mut self, id_token: Token) -> ParseResult2 { let symbol_search_result: Option<(usize, StorageClass)> = self.find_symbol(&id_token.lexeme); if symbol_search_result.is_none() { @@ -707,7 +728,7 @@ impl<'parser> Parser<'parser> { // Check if we are assigning to a type other than SymbolType::Variable. If yes, panic! if symbol.sym_type != SymbolType::Variable { // self.skip_past(TokenKind::T_SEMICOLON); - panic!("Assigning to type '{:?}' is not allowed!", symbol.sym_type); + panic!("Assigning to type '{:?}' is not allowed! '{:?}'", symbol.sym_type, symbol); } _ = self.token_match(TokenKind::T_EQUAL); let mut bin_expr_ast_node: AST = self.parse_equality()?; @@ -972,7 +993,7 @@ impl<'parser> Parser<'parser> { sym_index: usize, sym_token: &Token, ) -> ParseResult2 { - let current_file = self.get_current_file_name(); + let current_file: String = self.get_current_file_name(); _ = self.token_match(TokenKind::T_LPAREN); if called_symbol.sym_type != SymbolType::Function { return Err(Box::new(BErr::noncallable_ident( @@ -981,17 +1002,34 @@ impl<'parser> Parser<'parser> { ))); } _ = self.token_match(TokenKind::T_RPAREN); + // Allocating extra 16 bytes to store x29(Frame Pointer), and x30(Link Register). // Storing and then loading them is collectively called a Frame Record. self.local_offset += 16; - Ok(AST::create_leaf( - ASTKind::ExprAST(Expr::FuncCall(FuncCallExpr { - symtbl_pos: sym_index, - result_type: called_symbol.lit_type, - })), - ASTOperation::AST_FUNC_CALL, - called_symbol.lit_type, - )) + + if called_symbol.lit_type == LitTypeVariant::Void { + _ = self.token_match(TokenKind::T_SEMICOLON); + Ok(AST::create_leaf( + ASTKind::StmtAST( + Stmt::FuncCall( + FuncCallStmt { + symtbl_pos: sym_index + } + )), + ASTOperation::AST_FUNC_CALL, + LitTypeVariant::Void + ) + ) + } else { + Ok(AST::create_leaf( + ASTKind::ExprAST(Expr::FuncCall(FuncCallExpr { + symtbl_pos: sym_index, + result_type: called_symbol.lit_type, + })), + ASTOperation::AST_FUNC_CALL, + called_symbol.lit_type, + )) + } } fn add_symbol_global(&mut self, sym: Symbol) -> Option {