From f54f630b38afc240fcb07de2c8aa5c8252edd032 Mon Sep 17 00:00:00 2001 From: Michael Sippel Date: Sun, 12 May 2024 04:22:32 +0200 Subject: [PATCH] adapt Abstraction variant of LTExpr to allow multiple parameters This avoids unneccesary recursive chaining and also allows abstractions with zero parameters. --- src/expr.rs | 15 ++++++++------- src/main.rs | 12 +++++++++--- src/parser.rs | 11 +++++++---- src/procedure_compiler.rs | 28 +++++++++++++++------------- 4 files changed, 39 insertions(+), 27 deletions(-) diff --git a/src/expr.rs b/src/expr.rs index 9c85731..592d938 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -39,9 +39,8 @@ pub enum LTExpr { body: Vec }, Abstraction { - arg_id: String, - arg_type: Option< laddertypes::TypeTerm >, - val_expr: Box + args: Vec<(String, Option)>, + body: Box }, Branch { condition: Box, @@ -68,11 +67,13 @@ impl LTExpr { } } - pub fn abstraction(arg_id: &str, arg_typ: &str, val_expr: LTExpr) -> LTExpr { + pub fn abstraction(args: Vec<(&str, &str)>, val_expr: LTExpr) -> LTExpr { LTExpr::Abstraction { - arg_id: String::from(arg_id), - arg_type: None,//typectx.write().unwrap().parse(arg_typ).expect("parse typeterm"), - val_expr: Box::new(val_expr) + args: args.into_iter().map(|(arg_name, arg_type)| + ( arg_name.into(), None ) + //typectx.write().unwrap().parse(t).expect("parse typeterm") + ).collect(), + body: Box::new(val_expr) } } diff --git a/src/main.rs b/src/main.rs index db260a8..07b62a9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -80,13 +80,19 @@ fn main() { } }; - let hello = λ _ { + let hello = λ{ print-nullterm hello-string; print-lenprefix pfxstr; }; - let isquare = λx (i* x x); - hello 'X'; + hello; + + let isquare = λx (i* x x); + let magnitude2 = λx y { + i+ (isquare x) (isquare y); + }; + magnitude2 8 16; + emit '\n'; emit (i+ '0' (isquare 3)); emit '\n'; diff --git a/src/parser.rs b/src/parser.rs index d80724c..6a4f48b 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -175,13 +175,16 @@ where It: Iterator Ok(LTIRToken::Lambda) => { if children.len() == 0 { tokens.next(); - let name = parse_symbol(tokens)?; + + let mut args = Vec::new(); + while let Some(Ok(LTIRToken::Symbol(_))) = tokens.peek() { + args.push((parse_symbol(tokens)?, None)); + } let body = parse_expr(tokens)?; return Ok(LTExpr::Abstraction{ - arg_id: name, - arg_type: None, - val_expr: Box::new(body) + args, + body: Box::new(body) }); } else { return Err(ParseError::UnexpectedToken); diff --git a/src/procedure_compiler.rs b/src/procedure_compiler.rs index b7a23a4..a361146 100644 --- a/src/procedure_compiler.rs +++ b/src/procedure_compiler.rs @@ -100,7 +100,7 @@ impl ProcedureCompiler { } Statement::LetAssign{ var_id, val_expr } => { match val_expr { - LTExpr::Abstraction { arg_id:_, arg_type:_, val_expr:_ } => { + LTExpr::Abstraction { args:_, body:_ } => { self.symbols.write().unwrap() .declare_proc( var_id.clone(), @@ -186,18 +186,20 @@ impl ProcedureCompiler { } self = self.compile(head); } - LTExpr::Abstraction { arg_id: arg_name, arg_type, val_expr } => { - let id = self.symbols - .write().unwrap() - .declare_var( - arg_name.clone(), - laddertypes::TypeTerm::unit()); - - self.asm = self.asm - .lit( id ) - .call("data-frame-set"); - - self = self.compile(val_expr); + LTExpr::Abstraction { args, body } => { + for (arg_name, arg_type) in args.iter() { + let id = self.symbols + .write().unwrap() + .declare_var( + arg_name.clone(), + arg_type.clone().unwrap_or( + laddertypes::TypeTerm::unit()) + ); + self.asm = self.asm + .lit( id ) + .call("data-frame-set"); + } + self = self.compile(body); } LTExpr::Branch { condition, if_expr, else_expr } => { self = self.compile(condition);