lt-core/src/symbols.rs

206 lines
5.5 KiB
Rust
Raw Normal View History

2024-05-05 18:19:28 +02:00
use {
std::{
collections::HashMap,
sync::{Arc, RwLock},
},
2024-05-05 18:19:28 +02:00
crate::expr::LTExpr
};
#[derive(Clone, Debug)]
pub enum SymbolDef {
FrameRef {
typ: laddertypes::TypeTerm,
stack_ref: tisc::VM_Word,
},
StaticRef {
typ: laddertypes::TypeTerm,
link_addr: Option< tisc::VM_Word >
},
Procedure {
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 {
pub fn get_type(&self, typectx: &Arc<RwLock<laddertypes::dict::TypeDict>>) -> laddertypes::TypeTerm {
match self {
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
*/
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
*/
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(),
typectx: Arc::new(RwLock::new( laddertypes::dict::TypeDict::new() )),
frame_size: 0,
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> {
match self.symbols.get(name) {
Some(def) => Some(def.clone()),
None => {
if let Some(parent) = self.parent.as_ref() {
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
}),
x => x.clone()
}
} else {
None
}
}
}
}
/*
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-05 18:19:28 +02:00
}
*/
//<><><><><><>
2024-05-05 18:19:28 +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>,
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),
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()
);
}
pub fn declare_proc(&mut self,
name: String,
in_types: Vec< laddertypes::TypeTerm >,
out_types: Vec< laddertypes::TypeTerm >
) {
self.symbols.insert(name, SymbolDef::Procedure {
link_addr: None,//LinkAddr::Relative{ name, offset: 0 },
in_types,
out_types
});
}
//<><><><><>
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;
self.symbols.insert(name, SymbolDef::FrameRef {
typ,
stack_ref
});
stack_ref
}
//<><><><><><>
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);
}
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
}