local function definition via let
This commit is contained in:
parent
e23d8257d0
commit
a6282c00eb
5 changed files with 103 additions and 100 deletions
|
@ -143,7 +143,7 @@ where It: Iterator<Item = char>
|
|||
if c.is_whitespace()
|
||||
|| *c == '(' || *c == ')'
|
||||
|| *c == '{' || *c == '}'
|
||||
|| *c == ';'
|
||||
|| *c == ';' || *c == '=' || *c == ':'
|
||||
{
|
||||
// finish the current token
|
||||
|
||||
|
|
79
src/main.rs
79
src/main.rs
|
@ -17,7 +17,7 @@ use crate::{
|
|||
procedure_compiler::ProcedureCompiler
|
||||
};
|
||||
|
||||
fn compile(scope: &Arc<RwLock<Scope>>, source: &str) -> Vec< tisc::assembler::AssemblyWord > {
|
||||
fn compile(scope: &Arc<RwLock<Scope>>, name: &str, source: &str) -> Vec< tisc::assembler::AssemblyWord > {
|
||||
ProcedureCompiler::new(scope)
|
||||
.compile(
|
||||
&parser::parse_expr(
|
||||
|
@ -26,8 +26,7 @@ fn compile(scope: &Arc<RwLock<Scope>>, source: &str) -> Vec< tisc::assembler::As
|
|||
).peekable()
|
||||
).expect("syntax error")
|
||||
)
|
||||
.into_asm()
|
||||
.build()
|
||||
.into_asm(&name.into())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -59,34 +58,38 @@ fn main() {
|
|||
~<LengthPrefixedSeq machine::Word>"
|
||||
);
|
||||
|
||||
main_scope.write().unwrap()
|
||||
.declare_proc_parse(
|
||||
"print-nullterm",
|
||||
vec![],
|
||||
vec![
|
||||
"<Ref <Seq Char~Ascii~machine::Word>~<NullTerminatedSeq machine::Word>>
|
||||
~machine::Address
|
||||
~machine::Word"
|
||||
],
|
||||
vec![]);
|
||||
|
||||
main_scope.write().unwrap().declare_proc_parse(
|
||||
"print-lenprefix",
|
||||
vec![],
|
||||
vec![
|
||||
"<Ref <Seq Char~Ascii~machine::Word>~<LengthPrefixedSeq machine::Word>>
|
||||
~machine::Address
|
||||
~machine::Word"
|
||||
],
|
||||
vec![]);
|
||||
|
||||
|
||||
|
||||
/* link assembly-program to symbols
|
||||
*/
|
||||
linker.add_procedure("main", compile(&main_scope,
|
||||
"main",
|
||||
"{
|
||||
print-lenprefix pfxstr;
|
||||
let print-nullterm = λstr {
|
||||
while (@ str) {
|
||||
emit (@ str);
|
||||
! str (i+ str 1);
|
||||
}
|
||||
};
|
||||
|
||||
let print-lenprefix = λstr {
|
||||
let len = (@ str);
|
||||
! str (i+ str 1);
|
||||
let end = (i+ str len);
|
||||
while (i- str end) {
|
||||
emit (@ str);
|
||||
! str (i+ str 1);
|
||||
}
|
||||
};
|
||||
|
||||
let hello = λ _ {
|
||||
print-nullterm hello-string;
|
||||
print-lenprefix pfxstr;
|
||||
};
|
||||
let isquare = λx (i* x x);
|
||||
|
||||
hello 'X';
|
||||
emit '\n';
|
||||
emit (i+ '0' (isquare 3));
|
||||
emit '\n';
|
||||
}"));
|
||||
|
||||
linker.add_static("hello-string",
|
||||
|
@ -96,29 +99,9 @@ fn main() {
|
|||
.collect());
|
||||
|
||||
linker.add_static("pfxstr",
|
||||
vec![ 4, 'a' as tisc::VM_Word, 'b' as tisc::VM_Word, 'c' as tisc::VM_Word, 'd' as tisc::VM_Word ]
|
||||
vec![ 3, 'a' as tisc::VM_Word, 'b' as tisc::VM_Word, 'c' as tisc::VM_Word, 'd' as tisc::VM_Word ]
|
||||
);
|
||||
|
||||
linker.add_procedure("print-nullterm", compile(&main_scope,
|
||||
"λ str {
|
||||
while (@ str) {
|
||||
emit (@ str);
|
||||
! str (i+ str 1);
|
||||
}
|
||||
}"));
|
||||
|
||||
linker.add_procedure("print-lenprefix", compile(&main_scope,
|
||||
"λ str {
|
||||
let len = @ str;
|
||||
! str (i+ str 1);
|
||||
let end = i+ str len;
|
||||
while (i- str end) {
|
||||
emit (@ str);
|
||||
! str (i+ str 1);
|
||||
}
|
||||
}"
|
||||
));
|
||||
|
||||
let main_addr = linker.get_link_addr(&"main".into()).expect("'main' not linked");
|
||||
vm.load( linker.link_total().expect("could not link") );
|
||||
vm.execute( main_addr );
|
||||
|
|
|
@ -57,6 +57,7 @@ where It: Iterator<Item = char>
|
|||
match sym.as_str() {
|
||||
"!" => {
|
||||
tokens.next();
|
||||
// todo accept address-expression instead of symbol
|
||||
let name = parse_symbol(tokens)?;
|
||||
let val_expr = parse_expr(tokens)?;
|
||||
let _ = parse_expect(tokens, LTIRToken::StatementSep)?;
|
||||
|
|
|
@ -4,6 +4,10 @@ use {
|
|||
sync::{Arc, RwLock},
|
||||
ops::Deref,
|
||||
},
|
||||
tisc::{
|
||||
assembler::AssemblyWord,
|
||||
linker::LinkAddr
|
||||
},
|
||||
crate::{
|
||||
expr::{LTExpr, Statement},
|
||||
symbols::{Scope, SymbolDef}
|
||||
|
@ -27,14 +31,41 @@ impl ProcedureCompiler {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn into_asm(self) -> tisc::Assembler {
|
||||
pub fn into_asm(mut self, proc_symbol: &String) -> Vec< tisc::assembler::AssemblyWord > {
|
||||
let data_frame_size = self.symbols.read().unwrap().get_frame_size() as i64;
|
||||
tisc::Assembler::new()
|
||||
.lit(data_frame_size)
|
||||
.call("data-frame-alloc")
|
||||
.join(self.asm)
|
||||
.lit(data_frame_size)
|
||||
.call("data-frame-drop")
|
||||
|
||||
let body = self.asm.build();
|
||||
self.linker.add_procedure("__procedure_body__", body);
|
||||
let body_addr = self.linker.get_link_addr(&"__procedure_body__".into()).unwrap();
|
||||
let subroutines = self.linker.link_relative(&"__subroutines__".into()).expect("link error");
|
||||
|
||||
let mut entry = tisc::Assembler::new();
|
||||
if data_frame_size > 0 {
|
||||
entry = entry
|
||||
.lit(data_frame_size)
|
||||
.call("data-frame-alloc");
|
||||
}
|
||||
entry = entry
|
||||
.call_symbol( LinkAddr::Relative{ symbol: "__subroutines__".into(), offset: body_addr });
|
||||
|
||||
if data_frame_size > 0 {
|
||||
entry = entry
|
||||
.lit(data_frame_size)
|
||||
.call("data-frame-drop");
|
||||
}
|
||||
|
||||
let mut superlink = tisc::Linker::new();
|
||||
superlink.add_procedure("", entry.build());
|
||||
superlink.add_procedure("__subroutines__", subroutines);
|
||||
|
||||
let bytecode = superlink.link_relative(proc_symbol).expect("link error");
|
||||
/*
|
||||
eprintln!("\n\n{}:", proc_symbol);
|
||||
for (i,w) in tisc::assembler::disassemble(&bytecode).iter().enumerate() {
|
||||
eprintln!("{}:\t\t{}", i, w);
|
||||
}
|
||||
*/
|
||||
bytecode
|
||||
}
|
||||
|
||||
pub fn verify(&self) {
|
||||
|
@ -68,18 +99,37 @@ impl ProcedureCompiler {
|
|||
}
|
||||
}
|
||||
Statement::LetAssign{ var_id, val_expr } => {
|
||||
self.symbols.write().unwrap()
|
||||
.declare_var(
|
||||
var_id.clone(),
|
||||
laddertypes::TypeTerm::unit()
|
||||
);
|
||||
match val_expr {
|
||||
LTExpr::Abstraction { arg_id:_, arg_type:_, val_expr:_ } => {
|
||||
self.symbols.write().unwrap()
|
||||
.declare_proc(
|
||||
var_id.clone(),
|
||||
vec![],vec![]
|
||||
);
|
||||
let lambda_procedure =
|
||||
ProcedureCompiler::new(&self.symbols)
|
||||
.compile( val_expr )
|
||||
.into_asm( var_id );
|
||||
|
||||
self = self.compile_statement(
|
||||
&Statement::Assignment {
|
||||
var_id: var_id.clone(),
|
||||
val_expr: val_expr.clone()
|
||||
self.linker.add_procedure(
|
||||
var_id,
|
||||
lambda_procedure
|
||||
);
|
||||
}
|
||||
);
|
||||
_ => {
|
||||
self.symbols.write().unwrap()
|
||||
.declare_var(
|
||||
var_id.clone(),
|
||||
laddertypes::TypeTerm::unit()
|
||||
);
|
||||
self = self.compile_statement(
|
||||
&Statement::Assignment {
|
||||
var_id: var_id.clone(),
|
||||
val_expr: val_expr.clone()
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Statement::WhileLoop { condition, body } => {
|
||||
let asm = self.asm;
|
||||
|
@ -126,7 +176,7 @@ impl ProcedureCompiler {
|
|||
eprintln!("undefined symbol '{}'!", symbol);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
LTExpr::Literal { typ, val } => {
|
||||
self.asm = self.asm.lit( *val );
|
||||
}
|
||||
|
@ -135,7 +185,7 @@ impl ProcedureCompiler {
|
|||
self = self.compile(arg);
|
||||
}
|
||||
self = self.compile(head);
|
||||
},
|
||||
}
|
||||
LTExpr::Abstraction { arg_id: arg_name, arg_type, val_expr } => {
|
||||
let id = self.symbols
|
||||
.write().unwrap()
|
||||
|
@ -148,7 +198,7 @@ impl ProcedureCompiler {
|
|||
.call("data-frame-set");
|
||||
|
||||
self = self.compile(val_expr);
|
||||
},
|
||||
}
|
||||
LTExpr::Branch { condition, if_expr, else_expr } => {
|
||||
self = self.compile(condition);
|
||||
|
||||
|
|
|
@ -193,37 +193,6 @@ pub fn init_runtime(linker: &mut Linker) -> Arc<RwLock<Scope>> {
|
|||
.build()
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
* let isquare = λx.(i* x x);
|
||||
*/
|
||||
symbols.write().unwrap().declare_proc_parse(
|
||||
"isquare",
|
||||
vec![],
|
||||
vec![ "ℤ_2^64~machine::UInt64~machine::Word" ],
|
||||
vec![ "ℤ_2^64~machine::UInt64~machine::Word" ]);
|
||||
|
||||
linker.add_procedure(
|
||||
"isquare",
|
||||
ProcedureCompiler::new(&symbols)
|
||||
.compile(
|
||||
<Expr::abstraction(
|
||||
"x",
|
||||
"ℤ_2^64~machine::UInt64~machine::Word",
|
||||
|
||||
LTExpr::application(
|
||||
LTExpr::symbol("i*"),
|
||||
vec![
|
||||
LTExpr::symbol("x"),
|
||||
LTExpr::symbol("x")
|
||||
]
|
||||
)
|
||||
)
|
||||
)
|
||||
.into_asm()
|
||||
.build()
|
||||
);
|
||||
|
||||
symbols.write().unwrap().declare_static_parse(
|
||||
"data-frame-ptr",
|
||||
"<MutRef <Seq machine::Word>>~machine::Address~machine::Word"
|
||||
|
|
Loading…
Reference in a new issue