Skip to content

Commit

Permalink
array variables parsed
Browse files Browse the repository at this point in the history
  • Loading branch information
rigel-star committed Oct 26, 2024
1 parent b6ebb58 commit 8218e72
Show file tree
Hide file tree
Showing 14 changed files with 175 additions and 60 deletions.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,8 @@ Cargo.lock
# Added by cargo

/target
.vscode/
.vscode/

*.S
*.so
out
1 change: 1 addition & 0 deletions Lib/std/lib.bic
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
def extern print(x: msg) -> void;
2 changes: 0 additions & 2 deletions samples/sample1_input.bic

This file was deleted.

15 changes: 0 additions & 15 deletions samples/sample1_output.s

This file was deleted.

3 changes: 0 additions & 3 deletions samples/sample2_input.bic

This file was deleted.

27 changes: 0 additions & 27 deletions samples/sample2_output.s

This file was deleted.

1 change: 1 addition & 0 deletions src/ast/ast_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ pub enum ASTOperation {
AST_ARRAY_ACCESS, // access array element
AST_STRLIT, // string literal node
AST_VAR_DECL,
AST_ARR_VAR_DECL
}

impl ASTOperation {
Expand Down
8 changes: 8 additions & 0 deletions src/ast/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ pub struct VarDeclStmt {
pub class: StorageClass
}

#[derive(Clone, Debug)]
pub struct ArrVarDeclStmt {
pub symtbl_pos: usize,
pub class: StorageClass,
pub vals: Vec<Expr>
}

#[derive(Clone, Debug)]
pub struct AssignStmt {
pub symtbl_pos: usize
Expand All @@ -37,6 +44,7 @@ pub enum Stmt {
While,
Loop,
Break,
ArrVarDecl(ArrVarDeclStmt),
FuncDecl(FuncDeclStmt),
Return(ReturnStmt),
Assignment(AssignStmt),
Expand Down
28 changes: 27 additions & 1 deletion src/code_gen/aarch64/aarch64_codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,11 @@ impl<'aarch64> CodeGen for Aarch64CodeGen<'aarch64> {
let ctx_borrow = ctx_rc.borrow();
for symbol in ctx_borrow.sym_table.iter() {
// symbol information is not generated if any of the following conditions matches
if symbol.lit_type == LitTypeVariant::None || symbol.sym_type == SymbolType::Function || symbol.class != StorageClass::GLOBAL {
if
symbol.lit_type == LitTypeVariant::None
|| symbol.sym_type == SymbolType::Function
|| symbol.class != StorageClass::GLOBAL
{
continue;
}
if symbol.lit_type == LitTypeVariant::Str && symbol.sym_type == SymbolType::Constant {
Expand All @@ -91,6 +95,7 @@ impl<'aarch64> CodeGen for Aarch64CodeGen<'aarch64> {
Aarch64CodeGen::dump_global_with_alignment(symbol);
} else if symbol.sym_type == SymbolType::Array {
let array_data_size: usize = symbol.lit_type.size();
println!("here i come");
println!("{}:", symbol.name);
for _ in 0..symbol.size {
Aarch64CodeGen::alloc_data_space(array_data_size);
Expand Down Expand Up @@ -540,6 +545,27 @@ impl<'aarch64> CodeGen for Aarch64CodeGen<'aarch64> {
Ok(NO_REG)
}

fn gen_local_arr_var_decl_stmt(&mut self, arr_var_decl_stmt: &crate::ast::ArrVarDeclStmt) -> CodeGenResult {
let symbol: Symbol = if let Some(ctx_rc) = &self.ctx {
let ctx_borrow = ctx_rc.borrow();
if let Some(symbol) = ctx_borrow.sym_table.get_symbol(arr_var_decl_stmt.symtbl_pos) {
symbol.clone()
} else {
panic!("not possible to reach here");
}
} else {
return Err(CodeGenErr::NoContext);
};
let mut item_off_counter = symbol.local_offset;
for expr in &arr_var_decl_stmt.vals {
let expr_reg: usize = self.gen_expr(expr, ASTOperation::AST_ARR_VAR_DECL, NO_REG, ASTOperation::AST_NONE)?;
let reg_name: String = self.reg_manager.borrow().name(expr_reg, 0);
println!("str {}, [sp, #{}]", reg_name, item_off_counter);
item_off_counter += symbol.lit_type.size() as i32;
}
Ok(NO_REG)
}

fn gen_func_call_expr(&mut self, func_call_expr: &crate::ast::FuncCallExpr) -> CodeGenResult {
let func_info_res: Option<FunctionInfo> = if let Some(ctx_rc) = &self.ctx {
let ctx_borrow = ctx_rc.borrow_mut();
Expand Down
22 changes: 21 additions & 1 deletion src/code_gen/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ SOFTWARE.
use std::cell::RefMut;

use crate::ast::ASTKind;
use crate::ast::ArrVarDeclStmt;
use crate::ast::AssignStmt;
use crate::ast::BinExpr;
use crate::ast::Expr;
Expand Down Expand Up @@ -188,7 +189,24 @@ pub trait CodeGen {
}
Ok(NO_REG)
}
else if ast_node.operation == ASTOperation::AST_NONE || ast_node.operation == ASTOperation::AST_VAR_DECL {
else if ast_node.operation == ASTOperation::AST_ARR_VAR_DECL {
if let ASTKind::StmtAST(arr_var_decl) = &ast_node.kind {
return match arr_var_decl {
Stmt::ArrVarDecl(arr_var_decl_stmt) => {
if arr_var_decl_stmt.class != StorageClass::LOCAL {
Ok(NO_REG)
}
else {
self.gen_local_arr_var_decl_stmt(arr_var_decl_stmt)
}
},
_ => Ok(NO_REG)
}
}
Ok(NO_REG)
}
else if (ast_node.operation == ASTOperation::AST_NONE)
|| (ast_node.operation == ASTOperation::AST_ARR_VAR_DECL) {
return Ok(NO_REG);
}
else if ast_node.operation == ASTOperation::AST_ASSIGN {
Expand Down Expand Up @@ -362,6 +380,8 @@ pub trait CodeGen {
fn gen_func_call_expr(&mut self, func_call_expr: &FuncCallExpr) -> CodeGenResult;

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

fn gen_local_arr_var_decl_stmt(&mut self, arr_var_decl_stmt: &ArrVarDeclStmt) -> CodeGenResult;

fn gen_var_assignment_stmt(&mut self, assign_stmt: &AssignStmt, expr_ast: &Expr) -> CodeGenResult;

Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ fn main() {
let mut symt: Symtable<Symbol> = Symtable::new();
let mut funct: FunctionInfoTable = FunctionInfoTable::new();
let mut file1: SourceFile =
SourceFile::new("/Users/rigelstar/Desktop/KagatiFoundation/bichara/Lib/socket/lib.bic");
SourceFile::new("/Users/rigelstar/Desktop/KagatiFoundation/bichara/examples/main.bic");
let mut source_files: Vec<&mut SourceFile> = vec![&mut file1];
let ctx: Rc<RefCell<CompilerCtx>> = Rc::new(RefCell::new(CompilerCtx::new(&mut symt, &mut funct)));
let rm: RefCell<RegManager> = RefCell::new(
Expand Down
118 changes: 109 additions & 9 deletions src/parser/parser_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ SOFTWARE.

use crate::ast::ASTKind;
use crate::ast::ASTOperation;
use crate::ast::ArrVarDeclStmt;
use crate::ast::AssignStmt;
use crate::ast::BinExpr;
use crate::ast::Expr;
Expand Down Expand Up @@ -709,6 +710,12 @@ impl<'parser> Parser<'parser> {
// by the user.
if self.current_token.kind == TokenKind::T_COLON {
_ = self.token_match(TokenKind::T_COLON)?;

// '[' is for arrays
if self.current_token.kind == TokenKind::T_LBRACKET {
return self.parse_array_var_decl_stmt(&id_token);
}

var_type = self.parse_id_type();
self.skip_to_next_token();
}
Expand Down Expand Up @@ -832,9 +839,19 @@ impl<'parser> Parser<'parser> {
self.local_offset
}

fn _parse_array_var_decl_stmt(&mut self, mut sym: Symbol) -> ParseResult2 {
// TODO: Write comments
fn parse_array_var_decl_stmt(&mut self, id_token: &Token) -> ParseResult2 {
self.skip_to_next_token(); // skip '['
// array type
let array_type: LitTypeVariant = self.parse_id_type();
self.skip_to_next_token();

// semicolon before the array size
_ = self.token_match(TokenKind::T_SEMICOLON)?;

// array size
let array_size_token: Token = self.current_token.clone();

let mut array_size_type: TokenKind = TokenKind::T_NONE;
for t in [
TokenKind::T_INT_NUM,
Expand All @@ -851,17 +868,91 @@ impl<'parser> Parser<'parser> {
array_size_token.lexeme
);
}
let array_size: usize = array_size_token.lexeme.parse::<usize>().unwrap();

self.token_match(array_size_type)?;
self.token_match(TokenKind::T_RBRACKET)?;
self.token_match(TokenKind::T_SEMICOLON)?;
sym.sym_type = SymbolType::Array;
sym.size = array_size_token.lexeme.parse::<usize>().unwrap();
if sym.class == StorageClass::LOCAL {
self.add_symbol_local(sym);
self.token_match(TokenKind::T_EQUAL)?;


let sym: Symbol = Symbol::__new(
id_token.lexeme.clone(),
array_type,
SymbolType::Array,
array_size,
self.ident_var_class(),
self.gen_next_local_offset(array_type),
None
);

self.local_offset += (array_size * array_type.size()) as i32;

let symbol_add_pos: usize = if self.is_scope_global() {
self.add_symbol_global(sym.clone()).unwrap()
} else {
self.add_symbol_global(sym);
}
Err(Box::new(BErr::none())) // this indicates variable is declared without assignment
self.add_symbol_local(sym.clone()).unwrap()
};

let array_values: Vec<Expr> = self.parse_array_assign_values(sym.lit_type)?;

let final_result: Result<AST, Box<BErr>> = Ok(AST::new(
ASTKind::StmtAST(Stmt::ArrVarDecl(ArrVarDeclStmt {
symtbl_pos: symbol_add_pos,
vals: array_values,
class: sym.class
})),
ASTOperation::AST_ARR_VAR_DECL,
None,
None,
sym.lit_type,
));
_ = self.token_match(TokenKind::T_SEMICOLON)?;
final_result
}

// parsing array values
fn parse_array_assign_values(&mut self, lit_type: LitTypeVariant) -> Result<Vec<Expr>, Box<BErr>> {
_ = self.token_match(TokenKind::T_LBRACKET)?;
let mut vals: Vec<Expr> = vec![];
if self.current_token.kind != TokenKind::T_RBRACKET {
loop {
let argu: AST = self.parse_equality()?;
if argu.result_type != lit_type {
let _err: Box<BErr> = Box::new(BErr::new(
BErrType::TypeError(BTypeErr::AssignmentTypeMismatch {
var_type: lit_type.to_string(),
assigned_type: argu.result_type.to_string()
}),
self.get_current_file_name(),
self.current_token.clone()
));
if self.__panic_mode {
panic!("{:?}", _err);
}
return Err(_err);
}
vals.push(argu.kind.unwrap_expr());
let is_tok_comma: bool = self.current_token.kind == TokenKind::T_COMMA;
let is_tok_rparen: bool = self.current_token.kind == TokenKind::T_RBRACKET;
if !is_tok_comma && !is_tok_rparen {
let __err: Box<BErr> = Box::new(BErr::unexpected_token(
self.get_current_file_name(),
self.current_token.clone()
));
if self.__panic_mode {
panic!("{:?}", __err);
}
return Err(__err);
} else if is_tok_rparen {
break;
} else {
self.token_match(TokenKind::T_COMMA)?;
}
}
}

_ = self.token_match(TokenKind::T_RBRACKET)?;
Ok(vals)
}

fn parse_id_type(&mut self) -> LitTypeVariant {
Expand All @@ -876,6 +967,7 @@ impl<'parser> Parser<'parser> {
}
}

// TODO: Write comments
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;
Expand Down Expand Up @@ -1354,6 +1446,14 @@ impl<'parser> Parser<'parser> {
self.current_function_id == INVALID_FUNC_ID
}

fn ident_var_class(&self) -> StorageClass {
if self.is_scope_global() {
StorageClass::GLOBAL
} else {
StorageClass::LOCAL
}
}

fn token_match_no_advance(&mut self, kind: TokenKind) -> TokenMatch {
let current: Token = self.current_token.clone();
if kind != current.kind {
Expand Down
1 change: 1 addition & 0 deletions src/tokenizer/token_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ pub enum TokenKind {
KW_NULL,
KW_LOOP,
KW_IN,
KW_IMPORT,
KW_DEF, // for function declarations
_KW_END_, // keywords end here

Expand Down
1 change: 1 addition & 0 deletions src/tokenizer/tokenizer_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ lazy_static! {
_keys.insert("def", TokenKind::KW_DEF);
_keys.insert("str", TokenKind::KW_STR);
_keys.insert("in", TokenKind::KW_IN);
_keys.insert("import", TokenKind::KW_IMPORT);
_keys.insert("null", TokenKind::KW_NULL);
_keys
};
Expand Down

0 comments on commit 8218e72

Please sign in to comment.