fixup symbol export
This commit is contained in:
parent
489d9886e3
commit
45869fdd30
4 changed files with 69 additions and 19 deletions
|
@ -77,14 +77,13 @@ impl ProcedureCompiler {
|
||||||
self.linker.link_relative(&self.proc_symbol).expect("link error");
|
self.linker.link_relative(&self.proc_symbol).expect("link error");
|
||||||
|
|
||||||
let mut export_symbols = self.scope.read().unwrap().export();
|
let mut export_symbols = self.scope.read().unwrap().export();
|
||||||
//eprintln!("proc compiler export = {:?}\ncode= {:?}", export_symbols, code);
|
|
||||||
(
|
(
|
||||||
export_symbols,
|
export_symbols,
|
||||||
code
|
code
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile_statement(mut self, statement: &Statement, enable_export: bool) -> Self {
|
pub fn compile_statement(mut self, statement: &Statement) -> Self {
|
||||||
match statement {
|
match statement {
|
||||||
Statement::Assignment { name_region, var_id, val_expr } => {
|
Statement::Assignment { name_region, var_id, val_expr } => {
|
||||||
self = self.compile_expr(val_expr, true);
|
self = self.compile_expr(val_expr, true);
|
||||||
|
@ -93,7 +92,7 @@ impl ProcedureCompiler {
|
||||||
Some(SymbolDef::FrameRef { typ, stack_ref }) => {
|
Some(SymbolDef::FrameRef { typ, stack_ref }) => {
|
||||||
self.asm = self.asm.lit(stack_ref).call("data-frame-set");
|
self.asm = self.asm.lit(stack_ref).call("data-frame-set");
|
||||||
}
|
}
|
||||||
Some(SymbolDef::StaticRef { typ, link_addr }) => {
|
Some(SymbolDef::StaticRef { typ, link_addr, export }) => {
|
||||||
self.asm = self
|
self.asm = self
|
||||||
.asm
|
.asm
|
||||||
.static_ref(var_id.as_str())
|
.static_ref(var_id.as_str())
|
||||||
|
@ -146,7 +145,7 @@ impl ProcedureCompiler {
|
||||||
name_region: *name_region,
|
name_region: *name_region,
|
||||||
var_id: var_id.clone(),
|
var_id: var_id.clone(),
|
||||||
val_expr: val_expr.clone(),
|
val_expr: val_expr.clone(),
|
||||||
}, false);
|
});
|
||||||
|
|
||||||
self.frame_size += 1;
|
self.frame_size += 1;
|
||||||
}
|
}
|
||||||
|
@ -173,7 +172,7 @@ impl ProcedureCompiler {
|
||||||
Some(SymbolDef::FrameRef { typ, stack_ref }) => {
|
Some(SymbolDef::FrameRef { typ, stack_ref }) => {
|
||||||
self.asm = self.asm.lit(stack_ref).call("data-frame-get");
|
self.asm = self.asm.lit(stack_ref).call("data-frame-get");
|
||||||
}
|
}
|
||||||
Some(SymbolDef::StaticRef { typ, link_addr }) => {
|
Some(SymbolDef::StaticRef { typ, link_addr, export }) => {
|
||||||
self.asm = self.asm.static_ref(symbol.as_str());
|
self.asm = self.asm.static_ref(symbol.as_str());
|
||||||
}
|
}
|
||||||
Some(SymbolDef::Procedure {
|
Some(SymbolDef::Procedure {
|
||||||
|
@ -280,19 +279,18 @@ impl ProcedureCompiler {
|
||||||
self.linker.add_procedure( &abs_symbol, abs_code );
|
self.linker.add_procedure( &abs_symbol, abs_code );
|
||||||
self.asm = self.asm.call( &abs_symbol );
|
self.asm = self.asm.call( &abs_symbol );
|
||||||
}
|
}
|
||||||
LTExpr::Block { region, scope, statements } => {
|
LTExpr::ExportBlock{ region, scope, statements }
|
||||||
|
| LTExpr::Block { region, scope, statements } => {
|
||||||
let block_symbol = self.make_subroutine_symbol();
|
let block_symbol = self.make_subroutine_symbol();
|
||||||
let mut block_compiler = ProcedureCompiler::new( block_symbol.clone(), scope.clone() );
|
let mut block_compiler = ProcedureCompiler::new( block_symbol.clone(), scope.clone() );
|
||||||
for stmnt in statements.iter() {
|
for stmnt in statements.iter() {
|
||||||
block_compiler = block_compiler.compile_statement( stmnt, true );
|
block_compiler = block_compiler.compile_statement( stmnt );
|
||||||
}
|
}
|
||||||
let (block_export_symbols, mut block_code) = block_compiler.get_bytecode();
|
let (block_export_symbols, mut block_code) = block_compiler.get_bytecode();
|
||||||
self.scope.write().unwrap().import( block_export_symbols );
|
self.scope.write().unwrap().import( block_export_symbols );
|
||||||
self.linker.add_procedure( &block_symbol, block_code.clone() );
|
self.linker.add_procedure( &block_symbol, block_code.clone() );
|
||||||
self.asm = self.asm.call( &block_symbol );
|
self.asm = self.asm.call( &block_symbol );
|
||||||
}
|
}
|
||||||
LTExpr::ExportBlock{ region, scope, statements } => {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ pub enum SymbolDef {
|
||||||
StaticRef {
|
StaticRef {
|
||||||
typ: laddertypes::TypeTerm,
|
typ: laddertypes::TypeTerm,
|
||||||
link_addr: Option<tisc::VM_Word>,
|
link_addr: Option<tisc::VM_Word>,
|
||||||
|
export: bool
|
||||||
},
|
},
|
||||||
Procedure {
|
Procedure {
|
||||||
in_types: Vec<laddertypes::TypeTerm>,
|
in_types: Vec<laddertypes::TypeTerm>,
|
||||||
|
@ -36,7 +37,7 @@ impl SymbolDef {
|
||||||
) -> laddertypes::TypeTerm {
|
) -> laddertypes::TypeTerm {
|
||||||
match self {
|
match self {
|
||||||
SymbolDef::FrameRef { typ, stack_ref: _ } => typ.clone(),
|
SymbolDef::FrameRef { typ, stack_ref: _ } => typ.clone(),
|
||||||
SymbolDef::StaticRef { typ, link_addr: _ } => typ.clone(),
|
SymbolDef::StaticRef { typ, link_addr: _, export: _ } => typ.clone(),
|
||||||
SymbolDef::Procedure {
|
SymbolDef::Procedure {
|
||||||
in_types,
|
in_types,
|
||||||
out_types,
|
out_types,
|
||||||
|
@ -153,6 +154,7 @@ impl Scope {
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|(name, def)|
|
.filter(|(name, def)|
|
||||||
match def {
|
match def {
|
||||||
|
SymbolDef::StaticRef { typ:_, link_addr:_, export } => *export,
|
||||||
SymbolDef::Procedure { in_types:_, out_types:_, link_addr:_, export } => *export,
|
SymbolDef::Procedure { in_types:_, out_types:_, link_addr:_, export } => *export,
|
||||||
_ => false
|
_ => false
|
||||||
}
|
}
|
||||||
|
@ -215,8 +217,7 @@ impl Scope {
|
||||||
export:_
|
export:_
|
||||||
} => {
|
} => {
|
||||||
if let Some(offset) = linker.get_link_addr( name ) {
|
if let Some(offset) = linker.get_link_addr( name ) {
|
||||||
eprintln!("update link addr {} @ {} + {}", name, base_symbol, offset);
|
// eprintln!("update link addr {} @ {} + {}", name, base_symbol, offset);
|
||||||
|
|
||||||
*link_addr = LinkAddr::Relative{
|
*link_addr = LinkAddr::Relative{
|
||||||
symbol: base_symbol.clone(),
|
symbol: base_symbol.clone(),
|
||||||
offset
|
offset
|
||||||
|
@ -319,15 +320,17 @@ impl Scope {
|
||||||
let typ = self
|
let typ = self
|
||||||
.parse(typ)
|
.parse(typ)
|
||||||
.expect("parse typeterm");
|
.expect("parse typeterm");
|
||||||
self.declare_static(String::from(name), typ);
|
self.declare_static(String::from(name), typ, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn declare_static(&mut self, name: String, typ: laddertypes::TypeTerm) {
|
pub fn declare_static(&mut self, name: String, typ: laddertypes::TypeTerm, export: bool) {
|
||||||
|
eprintln!("add {} export {}", name, export);
|
||||||
self.symbols.insert(
|
self.symbols.insert(
|
||||||
name,
|
name,
|
||||||
SymbolDef::StaticRef {
|
SymbolDef::StaticRef {
|
||||||
typ,
|
typ,
|
||||||
link_addr: None,
|
link_addr: None,
|
||||||
|
export
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,21 @@ impl LTExpr {
|
||||||
Err(TypeError::Todo)
|
Err(TypeError::Todo)
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
pub fn export_symbols(&self) -> Vec< (String, SymbolDef) > {
|
||||||
|
match self {
|
||||||
|
LTExpr::Block{ region, scope, statements }
|
||||||
|
| LTExpr::ExportBlock{
|
||||||
|
region,
|
||||||
|
scope,
|
||||||
|
statements
|
||||||
|
} => {
|
||||||
|
scope.read().unwrap().export()
|
||||||
|
}
|
||||||
|
|
||||||
|
_ => vec![]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn infer_type(&self, scope: &Arc<RwLock<Scope>>) -> TypeTag
|
pub fn infer_type(&self, scope: &Arc<RwLock<Scope>>) -> TypeTag
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
|
@ -230,8 +245,15 @@ impl LTExpr {
|
||||||
LTExpr::Block{ region, scope, statements } => {
|
LTExpr::Block{ region, scope, statements } => {
|
||||||
let mut types = Vec::new();
|
let mut types = Vec::new();
|
||||||
|
|
||||||
|
let enable_export =
|
||||||
|
match self {
|
||||||
|
LTExpr::ExportBlock{ region:_, scope:_, statements:_ } => true,
|
||||||
|
_ => false
|
||||||
|
};
|
||||||
|
eprintln!(" .. in block (export={}) ", enable_export);
|
||||||
|
|
||||||
for s in statements {
|
for s in statements {
|
||||||
match s.infer_type(scope) {
|
match s.infer_type(scope, enable_export) {
|
||||||
Ok(Some(t)) => {
|
Ok(Some(t)) => {
|
||||||
if !t.is_empty() {
|
if !t.is_empty() {
|
||||||
types.insert(0, t);
|
types.insert(0, t);
|
||||||
|
@ -255,7 +277,7 @@ impl LTExpr {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Statement {
|
impl Statement {
|
||||||
pub fn infer_type(&self, scope: &Arc<RwLock<Scope>>) -> Result< Option<laddertypes::SugaredTypeTerm> , Vec<TypeError> > {
|
pub fn infer_type(&self, scope: &Arc<RwLock<Scope>>, enable_export: bool) -> Result< Option<laddertypes::SugaredTypeTerm> , Vec<TypeError> > {
|
||||||
match self {
|
match self {
|
||||||
Statement::LetAssign{ name_region, typ, var_id, val_expr } => {
|
Statement::LetAssign{ name_region, typ, var_id, val_expr } => {
|
||||||
let typ = val_expr.infer_type( scope )?;
|
let typ = val_expr.infer_type( scope )?;
|
||||||
|
@ -275,14 +297,14 @@ impl Statement {
|
||||||
var_id.clone(),
|
var_id.clone(),
|
||||||
in_types,
|
in_types,
|
||||||
out_types,
|
out_types,
|
||||||
true
|
enable_export
|
||||||
);
|
);
|
||||||
|
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let id = scope.write().unwrap().declare_var(var_id.clone(), typ);
|
let id = scope.write().unwrap().declare_var(var_id.clone(), typ);
|
||||||
eprintln!("TYPING declare var = {}", id);
|
eprintln!("TYPING declare var ({}) = {}, export ={}", var_id, id, enable_export);
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -291,6 +313,10 @@ impl Statement {
|
||||||
Statement::Expr(expr) => {
|
Statement::Expr(expr) => {
|
||||||
let t = expr.infer_type(scope)?;
|
let t = expr.infer_type(scope)?;
|
||||||
|
|
||||||
|
let symb = expr.export_symbols();
|
||||||
|
eprintln!("expr statement: import symbols from expr {:?}", symb);
|
||||||
|
scope.write().unwrap().import( symb );
|
||||||
|
|
||||||
if t != laddertypes::TypeTerm::App(vec![]) {
|
if t != laddertypes::TypeTerm::App(vec![]) {
|
||||||
let st = t.sugar(&mut scope.clone());
|
let st = t.sugar(&mut scope.clone());
|
||||||
Ok(Some(st))
|
Ok(Some(st))
|
||||||
|
|
|
@ -53,6 +53,18 @@ fn main() {
|
||||||
.export()
|
.export()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|(symbol, def)| match def {
|
.filter_map(|(symbol, def)| match def {
|
||||||
|
ltcore::symbols::SymbolDef::StaticRef { typ, link_addr, export } => {
|
||||||
|
eprintln!("runtime export static REF {}", export);
|
||||||
|
if export {
|
||||||
|
if let Some(addr)= link_addr {
|
||||||
|
Some((symbol, addr))
|
||||||
|
} else {
|
||||||
|
Some((symbol.clone(), runtime_linker.get_link_addr(&symbol).unwrap_or(-1)))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
ltcore::symbols::SymbolDef::Procedure { in_types:_, out_types:_, link_addr, export } => {
|
ltcore::symbols::SymbolDef::Procedure { in_types:_, out_types:_, link_addr, export } => {
|
||||||
if true {
|
if true {
|
||||||
match link_addr {
|
match link_addr {
|
||||||
|
@ -198,6 +210,17 @@ fn main() {
|
||||||
.export()
|
.export()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|(symbol, def)| match def {
|
.filter_map(|(symbol, def)| match def {
|
||||||
|
ltcore::symbols::SymbolDef::StaticRef { typ, link_addr, export } => {
|
||||||
|
if export {
|
||||||
|
if let Some(addr)= link_addr {
|
||||||
|
Some((symbol.clone(), addr))
|
||||||
|
} else {
|
||||||
|
Some((symbol.clone(), linker.get_link_addr(&symbol).unwrap_or(-1)))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
ltcore::symbols::SymbolDef::Procedure { in_types:_, out_types:_, link_addr, export } => {
|
ltcore::symbols::SymbolDef::Procedure { in_types:_, out_types:_, link_addr, export } => {
|
||||||
if export {
|
if export {
|
||||||
match link_addr {
|
match link_addr {
|
||||||
|
|
Loading…
Reference in a new issue