Skip to content

Commit

Permalink
WIP: Type checker
Browse files Browse the repository at this point in the history
  • Loading branch information
YerinAlexey committed Mar 22, 2024
1 parent 14f2af2 commit 0e55691
Show file tree
Hide file tree
Showing 10 changed files with 1,034 additions and 97 deletions.
3 changes: 3 additions & 0 deletions src/check/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod scope;
pub mod tree;
pub mod types;
102 changes: 102 additions & 0 deletions src/check/scope.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
use crate::check::types;
use std::collections::HashMap;

pub type Id = usize;
pub type InnerId = usize;
pub type VariableId = (Id, InnerId);

#[derive(Debug)]
pub struct Scope {
parent: Option<Id>,
is_loop: bool,
name_map: HashMap<String, InnerId>,
type_map: Vec<types::Id>,
}

impl Scope {
pub fn lookup(&self, name: &str) -> Option<(InnerId, types::Id)> {
self.name_map
.get(name)
.map(|inner_id| (*inner_id, self.type_map[*inner_id]))
}

pub fn insert(&mut self, name: String, ty: types::Id) -> InnerId {
let inner_id = self.type_map.len();
self.type_map.push(ty);
self.name_map.insert(name, inner_id);
inner_id
}
}

#[derive(Debug)]
pub struct Table {
scopes: Vec<Scope>,
}

impl Table {
pub fn new() -> Self {
Self { scopes: vec![] }
}

pub fn lookup(&self, scope: Id, name: &str) -> Option<(VariableId, types::Id)> {
let scope_obj = &self.scopes[scope];
match scope_obj.lookup(name) {
Some((inner_id, ty)) => Some(((scope, inner_id), ty)),
None => match scope_obj.parent {
Some(parent) => self.lookup(parent, name),
None => None,
},
}
}

pub fn nearest_loop(&self, scope: Id) -> Option<Id> {
let scope_obj = &self.scopes[scope];
if scope_obj.is_loop {
Some(scope)
} else {
match scope_obj.parent {
Some(parent) => self.nearest_loop(parent),
None => None,
}
}
}

pub fn insert(&mut self, scope: Id, name: String, ty: types::Id) -> VariableId {
let scope_obj = &mut self.scopes[scope];
let inner_id = scope_obj.insert(name, ty);
(scope, inner_id)
}

pub fn push_root(&mut self) -> Id {
let id = self.scopes.len();
self.scopes.push(Scope {
parent: None,
is_loop: false,
name_map: HashMap::new(),
type_map: Vec::new(),
});
id
}

pub fn push_loop(&mut self, parent: Id) -> Id {
let id = self.scopes.len();
self.scopes.push(Scope {
parent: Some(parent),
is_loop: true,
name_map: HashMap::new(),
type_map: Vec::new(),
});
id
}

pub fn push(&mut self, parent: Id) -> Id {
let id = self.scopes.len();
self.scopes.push(Scope {
parent: Some(parent),
is_loop: false,
name_map: HashMap::new(),
type_map: Vec::new(),
});
id
}
}
Loading

0 comments on commit 0e55691

Please sign in to comment.