Skip to content

Commit

Permalink
generating code for function call expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
rigel-star committed Aug 2, 2024
1 parent 2b670c9 commit 491872a
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 17 deletions.
7 changes: 3 additions & 4 deletions examples/input1.bic
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
def extern calc_sum_till(x: integer) -> integer;
def extern print_int(x: integer) -> void;

let c = 500;

def main() -> void {
let a: integer = 500;
let b: integer = a + c;
let a: integer = 300;
let b: integer = calc_sum_till(a);
print_int(b);
}
3 changes: 2 additions & 1 deletion src/ast/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ pub struct SubscriptExpr {
#[derive(Clone, Debug)]
pub struct FuncCallExpr {
pub symtbl_pos: usize, // position of the function being called in the symbol table,
// args
pub result_type: LitTypeVariant, // function return type
// args
pub args: Vec<Expr>
}

#[derive(Clone, Debug)]
Expand Down
29 changes: 29 additions & 0 deletions src/code_gen/aarch64/aarch64_codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,35 @@ impl<'aarch64> CodeGen for Aarch64CodeGen<'aarch64> {
let reg_name: String = self.reg_manager.borrow().name(expr_reg);
println!("str {}, [sp, #{}]", reg_name, symbol.local_offset);
}

fn gen_func_call_expr(&mut self, func_call_expr: &crate::ast::FuncCallExpr) -> usize {
let func_info: FunctionInfo = if let Some(ctx_rc) = &self.ctx {
let ctx_borrow = ctx_rc.borrow_mut();
if let Some(symbol) = ctx_borrow.sym_table.get_symbol(func_call_expr.symtbl_pos) {
if let Some(func_info) = ctx_borrow.func_table.get(&symbol.name) {
func_info.clone()
} else {
panic!("function info not found");
}
} else {
panic!("undefined symbol");
}
} else {
panic!("No context provided for code generation");
};
let args: &Vec<crate::ast::Expr> = &func_call_expr.args;
for expr in args {
let reg: usize = self.gen_expr(expr, ASTOperation::AST_FUNC_CALL, 0xFFFFFFFF, ASTOperation::AST_NONE);
let reg_name: String = self.reg_manager.borrow().name(reg);
println!("mov x0, {}", reg_name);
}
let mut reg_mgr = self.reg_manager.borrow_mut();
let alloced_reg: usize = reg_mgr.allocate();
let alloced_reg_name: String = reg_mgr.name(alloced_reg);
println!("bl _{}", func_info.name);
println!("mov {}, x0", alloced_reg_name);
alloced_reg
}
}

impl<'aarch64> Aarch64CodeGen<'aarch64> {
Expand Down
7 changes: 5 additions & 2 deletions src/code_gen/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use std::cell::RefMut;
use crate::ast::ASTKind;
use crate::ast::BinExpr;
use crate::ast::Expr;
use crate::ast::FuncCallExpr;
use crate::ast::FuncCallStmt;
use crate::ast::LitValExpr;
use crate::ast::Stmt;
Expand Down Expand Up @@ -197,8 +198,8 @@ 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),
},
Expr::FuncCall(func_call) => self.gen_func_call_expr(func_call),
}
}

Expand Down Expand Up @@ -310,6 +311,8 @@ pub trait CodeGen {

fn gen_func_call_stmt(&mut self, func_call_stmt: &FuncCallStmt);

fn gen_func_call_expr(&mut self, func_call_expr: &FuncCallExpr) -> usize;

fn gen_local_var_decl_stmt(&mut self, var_decl_stmt: &VarDeclStmt, expr_ast: &Expr);

fn reg_manager(&self) -> RefMut<RegManager>;
Expand Down
10 changes: 5 additions & 5 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,22 +42,22 @@ use symbol::*;
use tokenizer::Tokenizer;

fn main() {
let tokener = Rc::new(RefCell::new(Tokenizer::new()));
let parsr = Rc::new(RefCell::new(Parser::new()));
let tokener: Rc<RefCell<Tokenizer>> = Rc::new(RefCell::new(Tokenizer::new()));
let parsr: Rc<RefCell<Parser>> = Rc::new(RefCell::new(Parser::new()));
let mut symt: Symtable<Symbol> = Symtable::new();
let mut funct: FunctionInfoTable = FunctionInfoTable::new();
let mut file1: SourceFile =
SourceFile::new("/Users/rigelstar/Desktop/KagatiFoundation/bichara/examples/input1.bic");
let mut source_files: Vec<&mut SourceFile> = vec![&mut file1];
let ctx = Rc::new(RefCell::new(CompilerCtx::new(&mut symt, &mut funct)));
let ctx: Rc<RefCell<CompilerCtx>> = Rc::new(RefCell::new(CompilerCtx::new(&mut symt, &mut funct)));
let rm: RefCell<RegManager> = RefCell::new(RegManager::new({
let mut regs: Vec<String> = vec![];
for i in 0..8 {
for i in 0..20 {
regs.push(format!("x{}", i));
}
regs
}));
let mut cg = Aarch64CodeGen::new(rm);
let mut cg: Aarch64CodeGen = Aarch64CodeGen::new(rm);
for sf in &mut source_files {
let read_res: Result<i32, std::io::Error> = sf.read();
if let Err(e) = read_res {
Expand Down
15 changes: 10 additions & 5 deletions src/parser/parser_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -953,7 +953,7 @@ impl<'parser> Parser<'parser> {
))
}
TokenKind::T_IDENTIFIER => {
// Identifiers in a global variable declaration expression is not allowed.
// Identifiers in a global variable declaration expression are not allowed.
if self.is_scope_global() {
return Err(Box::new(BErr::new(BErrType::TypeError(BTypeErr::InitializerNotAConstant {
lexeme: current_token.lexeme.clone()
Expand Down Expand Up @@ -1097,10 +1097,15 @@ impl<'parser> Parser<'parser> {
)
} else {
Ok(AST::create_leaf(
ASTKind::ExprAST(Expr::FuncCall(FuncCallExpr {
symtbl_pos: sym_index,
result_type: called_symbol.lit_type,
})),
ASTKind::ExprAST(
Expr::FuncCall(
FuncCallExpr {
symtbl_pos: sym_index,
result_type: called_symbol.lit_type,
args: func_args
}
)
),
ASTOperation::AST_FUNC_CALL,
called_symbol.lit_type,
))
Expand Down
1 change: 1 addition & 0 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ pub fn infer_type_from_expr(expr: &Expr) -> LitTypeVariant {
left_type
},
Expr::Ident(ident) => ident.result_type,
Expr::FuncCall(func_call_expr) => func_call_expr.result_type,
_ => {
// I am gonna ignore these types for now (as they are not needed right now)
panic!("Cannot infer type of the expression.");
Expand Down

0 comments on commit 491872a

Please sign in to comment.