local function definition via let

This commit is contained in:
Michael Sippel 2024-05-11 18:07:58 +02:00
parent e23d8257d0
commit a6282c00eb
Signed by: senvas
GPG key ID: F96CF119C34B64A6
5 changed files with 103 additions and 100 deletions

View file

@ -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

View file

@ -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 );

View file

@ -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)?;

View file

@ -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);

View file

@ -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(
&LTExpr::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"