lt-core/src/symbols.rs

231 lines
6.1 KiB
Rust
Raw Normal View History

2024-05-05 18:19:28 +02:00
use {
2024-05-12 18:58:39 +02:00
crate::expr::LTExpr,
std::{
collections::HashMap,
sync::{Arc, RwLock},
},
2024-05-05 18:19:28 +02:00
};
#[derive(Clone, Debug)]
pub enum SymbolDef {
FrameRef {
typ: laddertypes::TypeTerm,
stack_ref: tisc::VM_Word,
},
StaticRef {
typ: laddertypes::TypeTerm,
2024-05-12 18:58:39 +02:00
link_addr: Option<tisc::VM_Word>,
},
Procedure {
2024-05-12 18:58:39 +02:00
in_types: Vec<laddertypes::TypeTerm>,
out_types: Vec<laddertypes::TypeTerm>,
link_addr: Option<tisc::VM_Word>,
},
}
2024-05-05 18:19:28 +02:00
impl SymbolDef {
2024-05-12 18:58:39 +02:00
pub fn get_type(
&self,
typectx: &Arc<RwLock<laddertypes::dict::TypeDict>>,
) -> laddertypes::TypeTerm {
match self {
2024-05-12 18:58:39 +02:00
SymbolDef::FrameRef { typ, stack_ref: _ } => typ.clone(),
SymbolDef::StaticRef { typ, link_addr: _ } => typ.clone(),
SymbolDef::Procedure {
in_types,
out_types,
link_addr: _,
} => laddertypes::TypeTerm::App(vec![
typectx
.write()
.unwrap()
.parse("Fn")
.expect("parse typeterm"),
laddertypes::TypeTerm::App(in_types.clone()),
laddertypes::TypeTerm::App(out_types.clone()),
]),
}
}
2024-05-05 18:19:28 +02:00
}
/* Describes a lexical scope of symbols
*/
pub struct Scope {
/* definition of runtime symbols
*/
2024-05-12 18:58:39 +02:00
symbols: HashMap<String, SymbolDef>,
/* type symbols
*/
pub typectx: Arc<RwLock<laddertypes::TypeDict>>,
/* number of words required for
* the stack frame of this scope
*/
frame_size: usize,
/* parent scope whose all
* symbols are inherited
2024-05-12 18:58:39 +02:00
*/
parent: Option<Arc<RwLock<Scope>>>,
2024-05-05 18:19:28 +02:00
}
impl Scope {
pub fn new() -> Arc<RwLock<Self>> {
Arc::new(RwLock::new(Scope {
2024-05-05 18:19:28 +02:00
symbols: HashMap::new(),
2024-05-12 18:58:39 +02:00
typectx: Arc::new(RwLock::new(laddertypes::dict::TypeDict::new())),
frame_size: 0,
2024-05-12 18:58:39 +02:00
parent: None,
}))
}
pub fn with_parent(parent: &Arc<RwLock<Scope>>) -> Arc<RwLock<Self>> {
let s = Scope {
symbols: HashMap::new(),
// todo: create proper child scope
typectx: parent.read().unwrap().typectx.clone(),
frame_size: 0,
parent: Some(parent.clone()),
};
Arc::new(RwLock::new(s))
2024-05-05 18:19:28 +02:00
}
pub fn get_frame_size(&self) -> usize {
self.frame_size
2024-05-05 18:19:28 +02:00
}
pub fn get(&self, name: &str) -> Option<SymbolDef> {
2024-05-12 18:58:39 +02:00
match self.symbols.get(name) {
Some(def) => Some(def.clone()),
None => {
if let Some(parent) = self.parent.as_ref() {
2024-05-12 18:58:39 +02:00
match parent.read().unwrap().get(name) {
Some(SymbolDef::FrameRef { typ, stack_ref }) => Some(SymbolDef::FrameRef {
typ: typ.clone(),
stack_ref: stack_ref + self.get_frame_size() as i64,
}),
2024-05-12 18:58:39 +02:00
x => x.clone(),
}
} else {
None
}
}
}
}
2024-05-12 18:58:39 +02:00
/*
pub fn get_link_addr(&self, name: &str) -> Option<tisc::VM_Word> {
match self.get(name) {
Some(SymbolDef::Procedure{ in_types:_, out_types:_, link_addr }) => {
link_addr
}
Some(SymbolDef::StaticRef { typ:_, link_addr }) => {
link_addr
}
Some(SymbolDef::FrameRef { typ:_, stack_ref:_ }) => None,
None => None
}
}
2024-05-12 18:58:39 +02:00
*/
//<><><><><><>
2024-05-05 18:19:28 +02:00
2024-05-12 18:58:39 +02:00
pub fn declare_proc_parse(
&mut self,
name: &str,
type_vars: Vec<&str>,
2024-05-05 18:19:28 +02:00
in_types: Vec<&str>,
2024-05-12 18:58:39 +02:00
out_types: Vec<&str>,
2024-05-05 18:19:28 +02:00
) {
for v in type_vars {
self.typectx.write().unwrap().add_varname(v.into());
}
self.declare_proc(
String::from(name),
2024-05-12 18:58:39 +02:00
in_types
.into_iter()
.map(|t| {
self.typectx
.write()
.unwrap()
.parse(t)
.expect("parse typeterm")
})
.collect(),
out_types
.into_iter()
.map(|t| {
self.typectx
.write()
.unwrap()
.parse(t)
.expect("parse typeterm")
})
.collect(),
);
}
2024-05-12 18:58:39 +02:00
pub fn declare_proc(
&mut self,
name: String,
2024-05-12 18:58:39 +02:00
in_types: Vec<laddertypes::TypeTerm>,
out_types: Vec<laddertypes::TypeTerm>,
) {
2024-05-12 18:58:39 +02:00
self.symbols.insert(
name,
SymbolDef::Procedure {
link_addr: None, //LinkAddr::Relative{ name, offset: 0 },
in_types,
out_types,
},
);
}
//<><><><><>
2024-05-12 18:58:39 +02:00
pub fn declare_var_parse(&mut self, name: &str, typ: &str) {
let typ = self
.typectx
.write()
.unwrap()
.parse(typ)
.expect("parse typeterm");
self.declare_var(String::from(name), typ);
2024-05-05 18:19:28 +02:00
}
pub fn declare_var(&mut self, name: String, typ: laddertypes::TypeTerm) -> tisc::VM_Word {
let stack_ref = self.frame_size as tisc::VM_Word;
self.frame_size += 1;
2024-05-12 18:58:39 +02:00
self.symbols
.insert(name, SymbolDef::FrameRef { typ, stack_ref });
stack_ref
}
//<><><><><><>
2024-05-12 18:58:39 +02:00
pub fn declare_static_parse(&mut self, name: &str, typ: &str) {
let typ = self
.typectx
.write()
.unwrap()
.parse(typ)
.expect("parse typeterm");
self.declare_static(String::from(name), typ);
}
2024-05-12 18:58:39 +02:00
pub fn declare_static(&mut self, name: String, typ: laddertypes::TypeTerm) {
self.symbols.insert(
name,
SymbolDef::StaticRef {
typ,
link_addr: None,
},
);
}
2024-05-05 18:19:28 +02:00
}