forked from chanbengz/SUSTech_CS323_Project_Incredibuild
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
445cee8
commit 56eefa1
Showing
9 changed files
with
432 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
use crate::symbol::*; | ||
use spl_ast::tree::Value; | ||
|
||
impl From<Value> for Type { | ||
fn from(value: Value) -> Type { | ||
match value { | ||
Value::Integer(_) => Type::Int, | ||
Value::Float(_) => Type::Float, | ||
Value::String(_) => Type::String, | ||
Value::Char(_) => Type::Char, | ||
Value::Bool(_) => Type::Bool, | ||
Value::Null => Type::Null, | ||
} | ||
} | ||
} | ||
|
||
impl Symbol<VarType> { | ||
pub fn new(id: i32, is_global: bool, identifier: String, symbol_type: VarType) -> Symbol<VarType> { | ||
Symbol { | ||
id, | ||
is_global, | ||
identifier, | ||
symbol_type, | ||
symbol_table_next: None, | ||
scope_stack_next: None | ||
} | ||
} | ||
} | ||
|
||
impl Symbol<FuncType> { | ||
pub fn new(id: i32, is_global: bool, identifier: String, symbol_type: FuncType) -> Symbol<FuncType> { | ||
Symbol { | ||
id, | ||
is_global, | ||
identifier, | ||
symbol_type, | ||
symbol_table_next: None, | ||
scope_stack_next: None | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,35 @@ | ||
mod error; | ||
pub mod utils; | ||
pub mod scope; | ||
pub mod symbol; | ||
pub mod typer; | ||
pub mod impls; | ||
pub mod table; | ||
|
||
use spl_parser::parse; | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
|
||
#[test] | ||
fn test() { | ||
|
||
fn test_symbol_table() { | ||
let code = r#" | ||
int a = 10; | ||
int b = 20; | ||
int c = 30; | ||
int d = 40; | ||
int e = 50; | ||
int f = 60; | ||
int g = 70; | ||
int h = 80; | ||
int i = 90; | ||
int j = 100; | ||
"#; | ||
let ast = parse(code).unwrap(); | ||
let mut table = table::HashLinkedMap::new(); | ||
for decl in ast.decls { | ||
table.insert(decl); | ||
} | ||
assert_eq!(table.symbols.len(), 10); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
use crate::symbol::Symbol; | ||
|
||
#[derive(Debug)] | ||
struct ScopeStack<T> { | ||
head: Option<Box<Symbol<T>>>, // Pointer to the top of the stack | ||
} | ||
|
||
impl<T> ScopeStack<T> { | ||
// Create a new empty stack | ||
fn new() -> Self { | ||
Stack { head: None } | ||
} | ||
|
||
// Push an element onto the stack | ||
fn push(&mut self, value: T) { | ||
let new_node = Box::new(Node { | ||
data: value, | ||
next: self.head.take(), // Current head becomes the next node | ||
}); | ||
self.head = Some(new_node); // New node becomes the new head | ||
} | ||
|
||
// Pop an element from the stack | ||
fn pop(&mut self) -> Option<T> { | ||
if let Some(node) = self.head.take() { | ||
self.head = node.next; // Move head to the next node | ||
Some(node.data) // Return the popped value | ||
} else { | ||
None // Stack is empty | ||
} | ||
} | ||
|
||
// Peek at the top element without removing it | ||
fn peek(&self) -> Option<&T> { | ||
self.head.as_deref().map(|node| &node.data) | ||
} | ||
|
||
// Check if the stack is empty | ||
fn is_empty(&self) -> bool { | ||
self.head.is_none() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
use spl_ast::tree::Value; | ||
|
||
#[derive(Clone, Debug)] | ||
pub struct Symbol<T> { | ||
pub id: i32, // Unique identifier | ||
pub is_global: bool, | ||
pub identifier: String, // Symbol Table Key | ||
pub symbol_type: T, // VarType + FuncType | ||
pub symbol_table_next: Option<Box<Symbol<T>>>, // Next symbol with the same key | ||
pub scope_stack_next: Option<Box<Symbol<T>>>, // Next symbol in the same scope stack | ||
} | ||
|
||
/* | ||
There are in total two kinds of Symbol Type: | ||
- Variable Type | ||
- Primitive Type (type_t, Value) | ||
- Int | ||
- Char | ||
- Float | ||
- Bool | ||
- String | ||
- Null | ||
- Array Type (type_t, Vec<usize>, Vec<PrimitiveType>) | ||
- Struct Type (Vec<PrimitiveType + Array Type>) | ||
- Function Type | ||
- (Return Type, Vec<VarType>) | ||
*/ | ||
pub type VarType = PrimType + ArrayType + StructType; | ||
pub type FuncType = (PrimType, Vec<VarType>); | ||
pub type PrimType = (Type, Value); | ||
pub type ArrayType = (Vec<usize>, Vec<PrimType>); | ||
pub type StructType = Vec<VarType>; | ||
|
||
pub enum Type { | ||
Int, | ||
Char, | ||
Float, | ||
Bool, | ||
String, | ||
Null | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
use std::hash::{Hash, Hasher}; | ||
use std::collections::{HashMap, LinkedList}; | ||
use std::collections::hash_map::DefaultHasher; | ||
use crate::symbol::Symbol; | ||
use spl_ast::tree::Value; | ||
use crate::symbol::Type; | ||
|
||
// Define the HashMap structure | ||
pub struct HashLinkedMap<T> { | ||
symbols: HashMap<String, LinkedList<Symbol<T>>>, | ||
variable_count: i32, | ||
} | ||
|
||
impl<T> HashLinkedMap<T> | ||
{ | ||
pub fn new() -> Self { | ||
HashLinkedMap { | ||
symbols: HashMap::new(), | ||
variable_count: 0, | ||
} | ||
} | ||
|
||
fn insert(&mut self, symbol: Symbol<T>) { | ||
let key = symbol.identifier.clone(); | ||
let dummy_symbol = Symbol { | ||
id: -1, | ||
is_global: false, | ||
identifier: "".to_string(), | ||
symbol_type: None, | ||
symbol_table_next: None, | ||
scope_stack_next: None, | ||
}; | ||
let symbol_list = self.symbols.entry(key).or_insert( | ||
LinkedList::from(dummy_symbol) | ||
); | ||
symbol_list.push_back(symbol); | ||
} | ||
|
||
fn get(&self, ident: String) -> Option<&Symbol<T>> { | ||
|
||
} | ||
|
||
// Remove a key-value pair | ||
fn remove(&mut self, key: &K) -> Option<V> { | ||
let index = self.get_bucket_index(key); | ||
let bucket = &mut self.buckets[index]; | ||
|
||
// Find and remove the key-value pair | ||
let position = bucket.iter().position(|pair| &pair.key == key)?; | ||
let removed = bucket.remove(position)?; | ||
Some(removed.value) | ||
} | ||
} | ||
|
||
impl<Symbol<T>> LinkedList<Symbol<T>> { | ||
fn push_back(&mut self, symbol: Symbol<T>) { | ||
let mut current = self.head.take(); | ||
let new_node = Box::new(Node { | ||
data: symbol, | ||
next: current, | ||
}); | ||
self.head = Some(new_node); | ||
} | ||
} |
Empty file.
Oops, something went wrong.