make let
a statement & support parsing for let
This commit is contained in:
parent
d7c06d423e
commit
e23d8257d0
5 changed files with 77 additions and 95 deletions
17
src/expr.rs
17
src/expr.rs
|
@ -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 ),
|
||||
|
|
|
@ -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 => {
|
||||
|
|
108
src/main.rs
108
src/main.rs
|
@ -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") );
|
||||
|
|
|
@ -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)?;
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in a new issue