Skip to content

Commit

Permalink
Initialize structure for Analyzer.
Browse files Browse the repository at this point in the history
  • Loading branch information
Jaredanwolfgang committed Dec 3, 2024
1 parent 445cee8 commit 56eefa1
Show file tree
Hide file tree
Showing 9 changed files with 432 additions and 6 deletions.
41 changes: 41 additions & 0 deletions src/analyser/src/impls.rs
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
}
}
}
27 changes: 25 additions & 2 deletions src/analyser/src/lib.rs
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);
}
}
42 changes: 42 additions & 0 deletions src/analyser/src/scope.rs
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()
}
}
41 changes: 41 additions & 0 deletions src/analyser/src/symbol.rs
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
}
64 changes: 64 additions & 0 deletions src/analyser/src/table.rs
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 added src/analyser/src/typer.rs
Empty file.
Loading

0 comments on commit 56eefa1

Please sign in to comment.