From e23d8257d048b0f521e329d1562c05ff6dc738ae Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Sat, 11 May 2024 01:19:44 +0200 Subject: [PATCH] make `let` a statement & support parsing for let --- src/expr.rs | 17 ++---- src/lexer.rs | 6 ++- src/main.rs | 108 +++++++++++++++----------------------- src/parser.rs | 12 +++++ src/procedure_compiler.rs | 29 +++++----- 5 files changed, 77 insertions(+), 95 deletions(-) diff --git a/src/expr.rs b/src/expr.rs index bef3d0c..9c85731 100644 --- a/src/expr.rs +++ b/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 @@ -39,11 +43,6 @@ pub enum LTExpr { arg_type: Option< laddertypes::TypeTerm >, val_expr: Box }, - Let { - name: String, - val: Box, - body: Box - }, Branch { condition: Box, if_expr: Box, @@ -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) -> Self { LTExpr::Application { head: Box::new( head ), diff --git a/src/lexer.rs b/src/lexer.rs index e2c53b9..2941c6a 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -10,6 +10,8 @@ pub enum LTIRToken { // TripleQuote(String), Lambda, + AssignType, + AssignValue, ExprOpen, ExprClose, @@ -83,11 +85,13 @@ where It: Iterator // 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 => { diff --git a/src/main.rs b/src/main.rs index 5aee775..0b3dba9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -50,6 +50,15 @@ fn main() { ~" ); + main_scope.write().unwrap() + .declare_static_parse( + "pfxstr", + " + ~" + ); + 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") ); diff --git a/src/parser.rs b/src/parser.rs index dce3bd6..5a81a07 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -66,6 +66,18 @@ where It: Iterator 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)?; diff --git a/src/procedure_compiler.rs b/src/procedure_compiler.rs index 9c75334..7d69841 100644 --- a/src/procedure_compiler.rs +++ b/src/procedure_compiler.rs @@ -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()