2024-05-05 18:19:28 +02:00
|
|
|
use {
|
2024-05-12 18:58:39 +02:00
|
|
|
crate::expr::LTExpr,
|
2024-05-08 13:09:49 +02:00
|
|
|
std::{
|
|
|
|
collections::HashMap,
|
|
|
|
sync::{Arc, RwLock},
|
|
|
|
},
|
2024-05-05 18:19:28 +02:00
|
|
|
};
|
|
|
|
|
2024-05-08 13:09:49 +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>,
|
2024-05-08 13:09:49 +02:00
|
|
|
},
|
|
|
|
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-08 13:09:49 +02:00
|
|
|
}
|
2024-05-05 18:19:28 +02:00
|
|
|
|
2024-05-08 13:09:49 +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 {
|
2024-05-08 13:09:49 +02:00
|
|
|
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-08 13:09:49 +02:00
|
|
|
}
|
|
|
|
}
|
2024-05-05 18:19:28 +02:00
|
|
|
}
|
|
|
|
|
2024-05-08 13:09:49 +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>,
|
2024-05-08 13:09:49 +02:00
|
|
|
|
|
|
|
/* 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
|
|
|
}
|
|
|
|
|
2024-05-08 13:09:49 +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())),
|
2024-05-08 13:09:49 +02:00
|
|
|
frame_size: 0,
|
2024-05-12 18:58:39 +02:00
|
|
|
parent: None,
|
2024-05-08 13:09:49 +02:00
|
|
|
}))
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2024-05-08 13:09:49 +02:00
|
|
|
pub fn get_frame_size(&self) -> usize {
|
|
|
|
self.frame_size
|
2024-05-05 18:19:28 +02:00
|
|
|
}
|
|
|
|
|
2024-05-08 13:09:49 +02:00
|
|
|
pub fn get(&self, name: &str) -> Option<SymbolDef> {
|
2024-05-12 18:58:39 +02:00
|
|
|
match self.symbols.get(name) {
|
2024-05-08 13:09:49 +02:00
|
|
|
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-08 13:09:49 +02:00
|
|
|
}),
|
2024-05-12 18:58:39 +02:00
|
|
|
x => x.clone(),
|
2024-05-08 13:09:49 +02:00
|
|
|
}
|
|
|
|
} 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-08 13:09:49 +02:00
|
|
|
}
|
|
|
|
}
|
2024-05-12 18:58:39 +02:00
|
|
|
*/
|
2024-05-08 13:09:49 +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,
|
2024-05-08 13:09:49 +02:00
|
|
|
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
|
|
|
) {
|
2024-05-08 13:09:49 +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-08 13:09:49 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2024-05-12 18:58:39 +02:00
|
|
|
pub fn declare_proc(
|
|
|
|
&mut self,
|
2024-05-08 13:09:49 +02:00
|
|
|
name: String,
|
2024-05-12 18:58:39 +02:00
|
|
|
in_types: Vec<laddertypes::TypeTerm>,
|
|
|
|
out_types: Vec<laddertypes::TypeTerm>,
|
2024-05-08 13:09:49 +02:00
|
|
|
) {
|
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-08 13:09:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//<><><><><>
|
|
|
|
|
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
|
|
|
}
|
2024-05-08 13:09:49 +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 });
|
2024-05-08 13:09:49 +02:00
|
|
|
|
|
|
|
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");
|
2024-05-08 13:09:49 +02:00
|
|
|
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-08 13:09:49 +02:00
|
|
|
}
|
2024-05-05 18:19:28 +02:00
|
|
|
}
|