Skip to content

Commit

Permalink
using Option type in Symtable instead of "sentinel" values
Browse files Browse the repository at this point in the history
  • Loading branch information
rigel-star committed Feb 28, 2024
1 parent 7e4ff59 commit d2a1168
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 61 deletions.
12 changes: 7 additions & 5 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,8 @@ impl ASTTraverser {
LitType::I32(int_idx) => *int_idx as usize,
_ => panic!("Not a valid symbol table indexing method"),
};
println!("{}:", self.sym_table.borrow().get_symbol(index).name);
let func_name: String = self.sym_table.borrow().get_symbol(index).unwrap().name.clone();
println!("{}:", func_name);
if let Some(body) = &*ast.left {
self.gen_ast(body, 0xFFFFFFFF, ast.operation);
}
Expand Down Expand Up @@ -420,12 +421,13 @@ impl ASTTraverser {
}

fn dump_gid_address_load_code_from_name(&self, reg_name: &str, id: &LitType) {
let symbol = match id {
LitType::I32(_idx) => self.sym_table.borrow().get_symbol(*_idx as usize).clone(),
let symbol: symtable::Symbol = match id {
LitType::I32(_idx) => self.sym_table.borrow().get_symbol(*_idx as usize).unwrap().clone(),
_ => panic!("Can't index symtable with this type: {:?}", id),
};
println!("adrp {}, {}@PAGE", reg_name, symbol.name);
println!("add {}, {}, {}@PAGEOFF", reg_name, reg_name, symbol.name);
let sym_name: &str = &symbol.name;
println!("adrp {}, {}@PAGE", reg_name, sym_name);
println!("add {}, {}, {}@PAGEOFF", reg_name, reg_name, sym_name);
}

fn _calc_id_offset(&self, id: &LitType) -> usize {
Expand Down
33 changes: 19 additions & 14 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,15 @@ impl Parser {
);
}
self.skip_to_next_token(); // skip return type
self.current_function_id = self.sym_table.borrow_mut().add_symbol(Symbol::new(
id_token.lexeme,
let function_id: Option<usize> = self.sym_table.borrow_mut().add_symbol(Symbol::new(
id_token.lexeme.clone(),
func_return_type,
SymbolType::Function,
));
if function_id.is_none() {
panic!("Symbol already defined: '{:?}'", id_token.lexeme);
}
self.current_function_id = function_id.unwrap();
let function_body: ParseResult = self.parse_compound_stmt();
let temp_func_id: usize = self.current_function_id;
self.current_function_id = 0xFFFFFFFF; // exiting out of function body
Expand All @@ -242,12 +246,11 @@ impl Parser {
Some("'return' statement outside a function is not valid."),
);
} else {
func_symbol = Some(
self.sym_table
.borrow()
.get_symbol(self.current_function_id)
.clone(),
);
let sym: Option<Symbol> = Some(self.sym_table.borrow().get_symbol(self.current_function_id).unwrap().clone());
if sym.is_none() {
panic!("Undefined function. ok");
}
func_symbol = sym;
void_ret_type = func_symbol.as_ref().unwrap().lit_type == LitTypeVariant::Void;
}
_ = self.token_match(TokenKind::KW_RETURN);
Expand Down Expand Up @@ -375,12 +378,13 @@ impl Parser {

fn parse_assignment_stmt(&mut self) -> ParseResult {
let id_token: Token = self.token_match(TokenKind::T_IDENTIFIER).clone();
let _id_index_symt: usize = self.sym_table.borrow().find_symbol(&id_token.lexeme);
if _id_index_symt == 0xFFFFFFFF {
let _id_index_symt_op: Option<usize> = self.sym_table.borrow().find_symbol(&id_token.lexeme);
if _id_index_symt_op.is_none() {
// if the symbol has not been defined
panic!("Assigning to an undefined symbol '{}'", id_token.lexeme);
}
let symbol: Symbol = self.sym_table.borrow().get_symbol(_id_index_symt).clone();
let _id_index_symt: usize = _id_index_symt_op.unwrap();
let symbol: Symbol = self.sym_table.borrow().get_symbol(_id_index_symt).unwrap().clone();
// Check if we are assigning to a type other than SymbolType::Variable. If yes, panic!
if symbol.sym_type != SymbolType::Variable {
panic!("Assigning to type '{:?}' is not allowed!", symbol.sym_type);
Expand Down Expand Up @@ -633,12 +637,13 @@ impl Parser {
Ok(ASTNode::make_leaf(ASTNodeKind::AST_STRLIT, LitType::I32(str_label as i32), LitTypeVariant::U8Ptr))
}
TokenKind::T_IDENTIFIER => {
let id_index: usize = self.sym_table.borrow().find_symbol(&current_token.lexeme);
if id_index == 0xFFFFFFFF {
let id_index_op: Option<usize> = self.sym_table.borrow().find_symbol(&current_token.lexeme);
if id_index_op.is_none() {
// if symbol has not been defined
return Err(ParseError::SymbolNotFound(current_token));
}
let symbol: Symbol = self.sym_table.borrow().get_symbol(id_index).clone();
let id_index: usize = id_index_op.unwrap();
let symbol: Symbol = self.sym_table.borrow().get_symbol(id_index).unwrap().clone();
let curr_tok_kind: TokenKind = self.current_token.kind;
if curr_tok_kind == TokenKind::T_LPAREN {
self.parse_func_call_expr(&symbol, id_index, &current_token)
Expand Down
59 changes: 17 additions & 42 deletions src/symtable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,13 @@ impl Symtable {
}
}

pub fn find_symbol(&self, name: &str) -> usize {
pub fn find_symbol(&self, name: &str) -> Option<usize> {
for (idx, n) in self.syms.iter().enumerate() {
if name == n.name {
return idx;
return Some(idx);
}
}
0xFFFFFFFF
None
}

fn next(&mut self) -> usize {
Expand All @@ -94,25 +94,24 @@ impl Symtable {
self.counter
}

pub fn add_symbol(&mut self, sym: Symbol) -> usize {
let mut pos: usize = self.find_symbol(&sym.name);
if pos != 0xFFFFFFFF {
return pos;
pub fn add_symbol(&mut self, sym: Symbol) -> Option<usize> {
if self.find_symbol(&sym.name).is_some() {
return None;
}
pos = self.next();
let act_pos: usize = self.next();
self.syms.push(sym);
pos - 1
Some(act_pos - 1)
}

// TODO: Convert return type to Option<&Symbol>
pub fn get_symbol(&self, idx: usize) -> &Symbol {
pub fn get_symbol(&self, idx: usize) -> Option<&Symbol> {
assert!(
idx < self.counter,
"value '{}' out of bounds for range '{}'",
idx,
self.counter
);
self.syms.get(idx).unwrap()
self.syms.get(idx)
}

pub fn remove_symbol(&mut self, index: usize) -> Symbol {
Expand All @@ -128,13 +127,13 @@ mod tests {
#[test]
fn test_symbol_addition() {
let mut table: Symtable = Symtable::new();
assert_eq!(
matches!(
table.add_symbol(Symbol::new(
String::from("number"),
super::LitTypeVariant::I32,
SymbolType::Variable
)),
0
Option::Some(0)
);
assert_eq!(table.syms.len(), 1);
assert_eq!(
Expand All @@ -143,39 +142,15 @@ mod tests {
super::LitTypeVariant::I32,
SymbolType::Variable
)),
1
Option::Some(1)
);
assert_eq!(
table.add_symbol(Symbol::new(
String::from("number3"),
super::LitTypeVariant::I32,
SymbolType::Variable
)),
2
);
assert_eq!(
table.add_symbol(Symbol::new(
String::from("number4"),
super::LitTypeVariant::I32,
SymbolType::Variable
)),
3
);
assert_eq!(
table.add_symbol(Symbol::new(
String::from("number5"),
super::LitTypeVariant::I32,
SymbolType::Variable
)),
4
);
assert_eq!(
table.add_symbol(Symbol::new(
String::from("number6"),
super::LitTypeVariant::I32,
SymbolType::Variable
)),
5
Option::Some(2)
);
}

Expand Down Expand Up @@ -210,9 +185,9 @@ mod tests {
super::LitTypeVariant::I32,
SymbolType::Variable,
));
assert_eq!(table.find_symbol("number2"), 0);
assert_eq!(table.find_symbol("number3"), 1);
assert_eq!(table.find_symbol("number4"), 2);
assert_eq!(table.find_symbol("number2"), Option::Some(0));
assert_eq!(table.find_symbol("number3"), Option::Some(1));
assert_eq!(table.find_symbol("number4"), Option::Some(2));
}

#[test]
Expand Down

0 comments on commit d2a1168

Please sign in to comment.