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()
|
if c.is_whitespace()
|
||||||
|| *c == '(' || *c == ')'
|
|| *c == '(' || *c == ')'
|
||||||
|| *c == '{' || *c == '}'
|
|| *c == '{' || *c == '}'
|
||||||
|| *c == ';'
|
|| *c == ';' || *c == '=' || *c == ':'
|
||||||
{
|
{
|
||||||
// finish the current token
|
// finish the current token
|
||||||
|
|
||||||
|
|
77
src/main.rs
77
src/main.rs
|
@ -17,7 +17,7 @@ use crate::{
|
||||||
procedure_compiler::ProcedureCompiler
|
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)
|
ProcedureCompiler::new(scope)
|
||||||
.compile(
|
.compile(
|
||||||
&parser::parse_expr(
|
&parser::parse_expr(
|
||||||
|
@ -26,8 +26,7 @@ fn compile(scope: &Arc<RwLock<Scope>>, source: &str) -> Vec< tisc::assembler::As
|
||||||
).peekable()
|
).peekable()
|
||||||
).expect("syntax error")
|
).expect("syntax error")
|
||||||
)
|
)
|
||||||
.into_asm()
|
.into_asm(&name.into())
|
||||||
.build()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
@ -59,34 +58,38 @@ fn main() {
|
||||||
~<LengthPrefixedSeq machine::Word>"
|
~<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
|
/* link assembly-program to symbols
|
||||||
*/
|
*/
|
||||||
linker.add_procedure("main", compile(&main_scope,
|
linker.add_procedure("main", compile(&main_scope,
|
||||||
|
"main",
|
||||||
"{
|
"{
|
||||||
|
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;
|
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",
|
linker.add_static("hello-string",
|
||||||
|
@ -96,29 +99,9 @@ fn main() {
|
||||||
.collect());
|
.collect());
|
||||||
|
|
||||||
linker.add_static("pfxstr",
|
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");
|
let main_addr = linker.get_link_addr(&"main".into()).expect("'main' not linked");
|
||||||
vm.load( linker.link_total().expect("could not link") );
|
vm.load( linker.link_total().expect("could not link") );
|
||||||
vm.execute( main_addr );
|
vm.execute( main_addr );
|
||||||
|
|
|
@ -57,6 +57,7 @@ where It: Iterator<Item = char>
|
||||||
match sym.as_str() {
|
match sym.as_str() {
|
||||||
"!" => {
|
"!" => {
|
||||||
tokens.next();
|
tokens.next();
|
||||||
|
// todo accept address-expression instead of symbol
|
||||||
let name = parse_symbol(tokens)?;
|
let name = parse_symbol(tokens)?;
|
||||||
let val_expr = parse_expr(tokens)?;
|
let val_expr = parse_expr(tokens)?;
|
||||||
let _ = parse_expect(tokens, LTIRToken::StatementSep)?;
|
let _ = parse_expect(tokens, LTIRToken::StatementSep)?;
|
||||||
|
|
|
@ -4,6 +4,10 @@ use {
|
||||||
sync::{Arc, RwLock},
|
sync::{Arc, RwLock},
|
||||||
ops::Deref,
|
ops::Deref,
|
||||||
},
|
},
|
||||||
|
tisc::{
|
||||||
|
assembler::AssemblyWord,
|
||||||
|
linker::LinkAddr
|
||||||
|
},
|
||||||
crate::{
|
crate::{
|
||||||
expr::{LTExpr, Statement},
|
expr::{LTExpr, Statement},
|
||||||
symbols::{Scope, SymbolDef}
|
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;
|
let data_frame_size = self.symbols.read().unwrap().get_frame_size() as i64;
|
||||||
tisc::Assembler::new()
|
|
||||||
|
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)
|
.lit(data_frame_size)
|
||||||
.call("data-frame-alloc")
|
.call("data-frame-alloc");
|
||||||
.join(self.asm)
|
}
|
||||||
|
entry = entry
|
||||||
|
.call_symbol( LinkAddr::Relative{ symbol: "__subroutines__".into(), offset: body_addr });
|
||||||
|
|
||||||
|
if data_frame_size > 0 {
|
||||||
|
entry = entry
|
||||||
.lit(data_frame_size)
|
.lit(data_frame_size)
|
||||||
.call("data-frame-drop")
|
.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) {
|
pub fn verify(&self) {
|
||||||
|
@ -68,12 +99,29 @@ impl ProcedureCompiler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Statement::LetAssign{ var_id, val_expr } => {
|
Statement::LetAssign{ var_id, val_expr } => {
|
||||||
|
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.linker.add_procedure(
|
||||||
|
var_id,
|
||||||
|
lambda_procedure
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
self.symbols.write().unwrap()
|
self.symbols.write().unwrap()
|
||||||
.declare_var(
|
.declare_var(
|
||||||
var_id.clone(),
|
var_id.clone(),
|
||||||
laddertypes::TypeTerm::unit()
|
laddertypes::TypeTerm::unit()
|
||||||
);
|
);
|
||||||
|
|
||||||
self = self.compile_statement(
|
self = self.compile_statement(
|
||||||
&Statement::Assignment {
|
&Statement::Assignment {
|
||||||
var_id: var_id.clone(),
|
var_id: var_id.clone(),
|
||||||
|
@ -81,6 +129,8 @@ impl ProcedureCompiler {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Statement::WhileLoop { condition, body } => {
|
Statement::WhileLoop { condition, body } => {
|
||||||
let asm = self.asm;
|
let asm = self.asm;
|
||||||
|
|
||||||
|
@ -126,7 +176,7 @@ impl ProcedureCompiler {
|
||||||
eprintln!("undefined symbol '{}'!", symbol);
|
eprintln!("undefined symbol '{}'!", symbol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
LTExpr::Literal { typ, val } => {
|
LTExpr::Literal { typ, val } => {
|
||||||
self.asm = self.asm.lit( *val );
|
self.asm = self.asm.lit( *val );
|
||||||
}
|
}
|
||||||
|
@ -135,7 +185,7 @@ impl ProcedureCompiler {
|
||||||
self = self.compile(arg);
|
self = self.compile(arg);
|
||||||
}
|
}
|
||||||
self = self.compile(head);
|
self = self.compile(head);
|
||||||
},
|
}
|
||||||
LTExpr::Abstraction { arg_id: arg_name, arg_type, val_expr } => {
|
LTExpr::Abstraction { arg_id: arg_name, arg_type, val_expr } => {
|
||||||
let id = self.symbols
|
let id = self.symbols
|
||||||
.write().unwrap()
|
.write().unwrap()
|
||||||
|
@ -148,7 +198,7 @@ impl ProcedureCompiler {
|
||||||
.call("data-frame-set");
|
.call("data-frame-set");
|
||||||
|
|
||||||
self = self.compile(val_expr);
|
self = self.compile(val_expr);
|
||||||
},
|
}
|
||||||
LTExpr::Branch { condition, if_expr, else_expr } => {
|
LTExpr::Branch { condition, if_expr, else_expr } => {
|
||||||
self = self.compile(condition);
|
self = self.compile(condition);
|
||||||
|
|
||||||
|
|
|
@ -193,37 +193,6 @@ pub fn init_runtime(linker: &mut Linker) -> Arc<RwLock<Scope>> {
|
||||||
.build()
|
.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(
|
symbols.write().unwrap().declare_static_parse(
|
||||||
"data-frame-ptr",
|
"data-frame-ptr",
|
||||||
"<MutRef <Seq machine::Word>>~machine::Address~machine::Word"
|
"<MutRef <Seq machine::Word>>~machine::Address~machine::Word"
|
||||||
|
|
Loading…
Reference in a new issue