2024-05-05 18:19:28 +02:00
|
|
|
use {
|
2024-05-08 13:09:49 +02:00
|
|
|
std::{
|
|
|
|
collections::HashMap,
|
|
|
|
sync::{Arc, RwLock},
|
|
|
|
},
|
2024-05-05 18:19:28 +02:00
|
|
|
crate::expr::LTExpr
|
|
|
|
};
|
|
|
|
|
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,
|
|
|
|
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
|
|
|
|
2024-05-08 13:09:49 +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
|
|
|
}
|
|
|
|
|
2024-05-08 13:09:49 +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
|
|
|
}
|
|
|
|
|
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-08 13:09:49 +02:00
|
|
|
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
|
|
|
}
|
|
|
|
|
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> {
|
|
|
|
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-08 13:09:49 +02:00
|
|
|
*/
|
|
|
|
//<><><><><><>
|
2024-05-05 18:19:28 +02:00
|
|
|
|
2024-05-08 13:09:49 +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-08 13:09:49 +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),
|
|
|
|
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
|
|
|
);
|
|
|
|
}
|
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;
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|