From d6a0bbf2af77e2d521a88c1cd3603148e98d03e9 Mon Sep 17 00:00:00 2001 From: Joscha Date: Tue, 22 Nov 2022 12:56:09 +0100 Subject: [PATCH] Desugar simple anonymous function definitions --- src/desugar.rs | 1 + src/desugar/expr.rs | 3 +- src/desugar/func_def.rs | 161 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 163 insertions(+), 2 deletions(-) create mode 100644 src/desugar/func_def.rs diff --git a/src/desugar.rs b/src/desugar.rs index e1d23c1..2be2a3f 100644 --- a/src/desugar.rs +++ b/src/desugar.rs @@ -2,6 +2,7 @@ mod basic; mod call; mod expr; mod field; +mod func_def; mod lit; mod program; mod table_constr; diff --git a/src/desugar/expr.rs b/src/desugar/expr.rs index 7a8a197..01c6862 100644 --- a/src/desugar/expr.rs +++ b/src/desugar/expr.rs @@ -13,8 +13,7 @@ impl Expr { Self::Var(var) => var.desugar(), Self::TableConstr(constr) => constr.desugar(), Self::TableDestr(destr) => destr.desugar(), - - Self::FuncDef(def) => (Self::FuncDef(def), false), // TODO Implement + Self::FuncDef(def) => def.desugar(), Self::Paren { s0, diff --git a/src/desugar/func_def.rs b/src/desugar/func_def.rs new file mode 100644 index 0000000..7a6b362 --- /dev/null +++ b/src/desugar/func_def.rs @@ -0,0 +1,161 @@ +use crate::ast::{ + BoundedSeparated, Call, Expr, FuncDef, Ident, Lit, Space, TableConstr, TableConstrElem, + TableLit, TableLitElem, Var, +}; +use crate::builtin::Builtin; + +impl FuncDef { + pub fn desugar(self) -> (Expr, bool) { + match self { + Self::AnonNoArg { + s0, + s1, + s2, + body, + span, + } => { + // `function s0 ( s1 ) s2 body` + // -> `{ '{ quote: body }, scope: 'scope() }` + let quote = Expr::Lit(Lit::Table(TableLit(BoundedSeparated { + elems: vec![( + Space::empty(span), + TableLitElem::Named { + name: Ident::new("quote", span), + s0: Space::empty(span), + s1: Space::empty(span), + value: body, + span, + }, + Space::empty(span), + )], + trailing: None, + span, + }))); + let scope = Expr::Call(Call::NoArg { + expr: Box::new(Expr::Lit(Lit::Builtin(Builtin::Scope, span))), + s0: Space::empty(span), + s1: Space::empty(span), + span, + }); + let new = Expr::TableConstr(TableConstr(BoundedSeparated { + elems: vec![ + ( + Space::empty(span), + TableConstrElem::Lit(TableLitElem::Positional(Box::new(quote))), + Space::empty(span), + ), + ( + Space::empty(span), + TableConstrElem::Lit(TableLitElem::Named { + name: Ident::new("scope", span), + s0: Space::empty(span), + s1: Space::empty(span), + value: Box::new(scope), + span, + }), + Space::empty(span), + ), + ], + trailing: None, + span, + })); + (new, true) + } + + Self::AnonArg { + s0, + s1, + arg, + s2, + s3, + body, + span, + } => { + // `function s0 ( s1 arg s2 ) s3 body` + // -> `function ( ) '{ local arg = 'arg(), body }` + let arg_call = Expr::Call(Call::NoArg { + expr: Box::new(Expr::Lit(Lit::Builtin(Builtin::Arg, span))), + s0: Space::empty(span), + s1: Space::empty(span), + span, + }); + let arg_assign = Expr::Var(Var::AssignIdent { + local: Some(Space::empty(span)), + name: arg, + s0: Space::empty(span), + s1: Space::empty(span), + value: Box::new(arg_call), + span, + }); + let body_elems = vec![ + ( + Space::empty(span), + TableLitElem::Positional(Box::new(arg_assign)), + Space::empty(span), + ), + ( + Space::empty(span), + TableLitElem::Positional(body), + Space::empty(span), + ), + ]; + let body = Expr::Lit(Lit::Table(TableLit(BoundedSeparated { + elems: body_elems, + trailing: None, + span, + }))); + let new = Expr::FuncDef(Self::AnonNoArg { + s0: Space::empty(span), + s1: Space::empty(span), + s2: Space::empty(span), + body: Box::new(body), + span, + }); + (new, true) + } + + Self::AnonDestr { + s0, + pattern, + s1, + body, + span, + } => todo!(), + + Self::NamedNoArg { + local, + s0, + name, + s1, + s2, + s3, + body, + span, + } => todo!(), + + Self::NamedArg { + local, + s0, + name, + s1, + s2, + arg, + s3, + s4, + body, + span, + } => todo!(), + + Self::NamedDestr { + local, + s0, + name, + s1, + pattern, + s2, + body, + span, + } => todo!(), + } + } +}