make let a statement & support parsing for let

This commit is contained in:
Michael Sippel 2024-05-11 01:19:44 +02:00
parent d7c06d423e
commit e23d8257d0
Signed by: senvas
GPG key ID: F96CF119C34B64A6
5 changed files with 77 additions and 95 deletions

View file

@ -12,6 +12,10 @@ pub enum Statement {
var_id: String,
val_expr: LTExpr
},
LetAssign {
var_id: String,
val_expr: LTExpr,
},
WhileLoop {
condition: LTExpr,
body: Vec<Statement>
@ -39,11 +43,6 @@ pub enum LTExpr {
arg_type: Option< laddertypes::TypeTerm >,
val_expr: Box<LTExpr>
},
Let {
name: String,
val: Box<LTExpr>,
body: Box<LTExpr>
},
Branch {
condition: Box<LTExpr>,
if_expr: Box<LTExpr>,
@ -77,14 +76,6 @@ impl LTExpr {
}
}
pub fn let_expr(name: &str, val: LTExpr, body: LTExpr) -> Self {
LTExpr::Let {
name: String::from(name),
val: Box::new(val),
body: Box::new(body)
}
}
pub fn application(head: LTExpr, body: Vec<LTExpr>) -> Self {
LTExpr::Application {
head: Box::new( head ),

View file

@ -10,6 +10,8 @@ pub enum LTIRToken {
// TripleQuote(String),
Lambda,
AssignType,
AssignValue,
ExprOpen,
ExprClose,
@ -83,11 +85,13 @@ where It: Iterator<Item = char>
// determine token type
LexerState::Any => {
match c {
'λ' => { self.chars.next(); return Some(Ok(LTIRToken::Lambda)); },
'(' => { self.chars.next(); return Some(Ok(LTIRToken::ExprOpen)); },
')' => { self.chars.next(); return Some(Ok(LTIRToken::ExprClose)); },
'{' => { self.chars.next(); return Some(Ok(LTIRToken::BlockOpen)); },
'}' => { self.chars.next(); return Some(Ok(LTIRToken::BlockClose)); },
'λ' => { self.chars.next(); return Some(Ok(LTIRToken::Lambda)); },
':' => { self.chars.next(); return Some(Ok(LTIRToken::AssignType)); },
'=' => { self.chars.next(); return Some(Ok(LTIRToken::AssignValue)); },
';' => { self.chars.next(); return Some(Ok(LTIRToken::StatementSep)); },
'\'' => { self.chars.next(); state = LexerState::Char(None); },
c => {

View file

@ -50,6 +50,15 @@ fn main() {
~<NullTerminatedSeq machine::Word>"
);
main_scope.write().unwrap()
.declare_static_parse(
"pfxstr",
"<Seq Char
~Ascii
~machine::Word>
~<LengthPrefixedSeq machine::Word>"
);
main_scope.write().unwrap()
.declare_proc_parse(
"print-nullterm",
@ -61,31 +70,6 @@ fn main() {
],
vec![]);
/* link assembly-program to symbol
*/
linker.add_procedure(
"main",
compile(&main_scope, "{
print-nullterm hello-string;
}"));
linker.add_static("hello-string",
"Hallo Welt!\n\0"
.chars()
.map(|c| (c as u8) as tisc::VM_Word)
.collect());
linker.add_procedure(
"print-nullterm",
compile(&main_scope,
"λ str {
while (@ str) {
emit (@ str);
! str (i+ str 1);
}
}")
);
main_scope.write().unwrap().declare_proc_parse(
"print-lenprefix",
vec![],
@ -95,53 +79,45 @@ fn main() {
~machine::Word"
],
vec![]);
/*
linker.add_procedure(
"print-lenprefix",
compile(&main_scope,
/* link assembly-program to symbols
*/
linker.add_procedure("main", compile(&main_scope,
"{
print-lenprefix pfxstr;
}"));
linker.add_static("hello-string",
"Hallo Welt!\n\0"
.chars()
.map(|c| (c as u8) as tisc::VM_Word)
.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 ]
);
linker.add_procedure("print-nullterm", compile(&main_scope,
"λ str {
let len = (@ str);
! str = (i+ str 1);
let end = (i+ str len);
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);
}
}"
)
);
*/
/*
tisc::Assembler::new()
// calculate stop address
.inst( tisc::VM_Instruction::Dup )
.inst( tisc::VM_Instruction::Dup )
.inst( tisc::VM_Instruction::Fetch )
.lit(1)
.inst( tisc::VM_Instruction::Add )
.inst( tisc::VM_Instruction::Add )
.inst( tisc::VM_Instruction::Swap )
// emit until address == start address
.while_loop(
tisc::Assembler::new()
.lit( 2 )
.inst( tisc::VM_Instruction::Pick )
.lit( 2 )
.inst( tisc::VM_Instruction::Pick )
.call("i-"),
tisc::Assembler::new()
.inst( tisc::VM_Instruction::Dup )
.inst( tisc::VM_Instruction::Fetch )
.inst( tisc::VM_Instruction::Emit )
.lit( 1 )
.inst( tisc::VM_Instruction::Add )
)
.inst( tisc::VM_Instruction::Drop )
.inst( tisc::VM_Instruction::Drop )
.build()
*/
));
let main_addr = linker.get_link_addr(&"main".into()).expect("'main' not linked");
vm.load( linker.link_total().expect("could not link") );

View file

@ -66,6 +66,18 @@ where It: Iterator<Item = char>
val_expr
})
}
"let" => {
tokens.next();
let name = parse_symbol(tokens)?;
let _ = parse_expect(tokens, LTIRToken::AssignValue);
let val_expr = parse_expr(tokens)?;
let _ = parse_expect(tokens, LTIRToken::StatementSep)?;
Ok(Statement::LetAssign {
var_id: name,
val_expr
})
}
"while" => {
tokens.next();
let _ = parse_expect(tokens, LTIRToken::ExprOpen)?;

View file

@ -67,6 +67,20 @@ impl ProcedureCompiler {
}
}
}
Statement::LetAssign{ var_id, val_expr } => {
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;
@ -122,21 +136,6 @@ impl ProcedureCompiler {
}
self = self.compile(head);
},
LTExpr::Let { name, val, body } => {
self.symbols.write().unwrap()
.declare_var(
name.clone(),
laddertypes::TypeTerm::unit()
);
self = self.compile_statement(
&Statement::Assignment {
var_id: name.clone(),
val_expr: val.deref().clone()
}
);
self = self.compile(&body.deref().clone());
},
LTExpr::Abstraction { arg_id: arg_name, arg_type, val_expr } => {
let id = self.symbols
.write().unwrap()