Skip to content

Commit

Permalink
separating function call statement parsing and function call expressi…
Browse files Browse the repository at this point in the history
…on parsing
  • Loading branch information
rigel-star committed Jul 25, 2024
1 parent 7c99d02 commit 618e734
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 21 deletions.
8 changes: 7 additions & 1 deletion examples/input1.bic
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
let b = 34;
def print_me() -> void {
let a = 222;
}

def main() -> void {
print_me();
}
9 changes: 6 additions & 3 deletions src/ast/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<LitType, BTypeErr> = bin.left.eval();
let right_evaled: Result<LitType, BTypeErr> = bin.right.eval();
if let (Ok(left_type), Ok(right_type)) = (left_evaled, right_evaled) {
let compat_res = are_compatible_for_operation::<LitType>(&left_type, &right_type, bin.operation);
let compat_res: (bool, LitTypeVariant) = are_compatible_for_operation::<LitType>(&left_type, &right_type, bin.operation);
if !compat_res.0 {
return Err(BTypeErr::IncompatibleTypes {
first_type: left_type.to_string(),
Expand Down Expand Up @@ -106,6 +106,9 @@ impl Expr {
panic!()
}
}
Expr::Ident(_) => {
panic!("Identifiers in an expression is not supported at compile-time expression evaluation.");
}
_ => panic!()
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/ast/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -29,4 +34,5 @@ pub enum Stmt {
Assignment(AssignStmt),
VarDecl(VarDeclStmt),
LValue(usize), // usize for symbol table position of this left value
FuncCall(FuncCallStmt)
}
9 changes: 9 additions & 0 deletions src/code_gen/aarch64/aarch64_codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,15 @@ impl<'aarch64> CodeGen for Aarch64CodeGen<'aarch64> {
fn reg_manager(&self) -> RefMut<RegManager> {
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> {
Expand Down
21 changes: 19 additions & 2 deletions src/code_gen/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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),
}
}
Expand Down Expand Up @@ -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<RegManager>;
}
68 changes: 53 additions & 15 deletions src/parser/parser_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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<Symbol> = 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() {
Expand Down Expand Up @@ -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()?;
Expand Down Expand Up @@ -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(
Expand All @@ -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<usize> {
Expand Down

0 comments on commit 618e734

Please sign in to comment.