From fcaaa5e9d59a590908db9a5c4db5c2510fb8d6d8 Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Sat, 17 Feb 2024 09:50:43 -0700 Subject: [PATCH] special form macroExpanders, (object) implementation --- src/kiss/Kiss.hx | 7 +++++++ src/kiss/SpecialForms.hx | 16 ++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/src/kiss/Kiss.hx b/src/kiss/Kiss.hx index edfe5b1..346892f 100644 --- a/src/kiss/Kiss.hx +++ b/src/kiss/Kiss.hx @@ -46,6 +46,7 @@ typedef KissState = { endOfFileReadTable:ReadTable, fieldForms:Map, specialForms:Map, + specialFormMacroExpanders:Map, macros:Map, formDocs:Map, doc:(String, Null, Null, ?String, ?String)->Void, @@ -100,6 +101,7 @@ class Kiss { endOfFileReadTable: new ReadTable(), fieldForms: new Map(), specialForms: null, + specialFormMacroExpanders: null, macros: null, formDocs: new Map(), doc: null, @@ -215,6 +217,7 @@ class Kiss { FieldForms.addBuiltins(k); k.specialForms = SpecialForms.builtins(k, context); + k.specialFormMacroExpanders = SpecialForms.builtinMacroExpanders(k, context); k.macros = Macros.builtins(k); return k; @@ -620,6 +623,7 @@ class Kiss { var macros = k.macros; var fieldForms = k.fieldForms; var specialForms = k.specialForms; + var specialFormMacroExpanders = k.specialFormMacroExpanders; var formDocs = k.formDocs; // Bind the table arguments of this function for easy recursive calling/passing @@ -735,6 +739,9 @@ class Kiss { case CallExp({pos: _, def: Symbol(specialForm)}, args) if (specialForms.exists(specialForm) && !macroExpandOnly): checkNumArgs(specialForm); Right(Kiss.measure(specialForm, ()->specialForms[specialForm](exp, args.copy(), k), true)); + case CallExp({pos: _, def: Symbol(specialForm)}, args) if (specialFormMacroExpanders.exists(specialForm) && macroExpandOnly): + checkNumArgs(specialForm); + Left(specialFormMacroExpanders[specialForm](exp, args.copy(), k)); case CallExp({pos: _, def: Symbol(alias)}, args) if (k.callAliases.exists(alias)): convert(CallExp(k.callAliases[alias].withPosOf(exp), args).withPosOf(exp)); case CallExp(func, args): diff --git a/src/kiss/SpecialForms.hx b/src/kiss/SpecialForms.hx index e92499e..c466b10 100644 --- a/src/kiss/SpecialForms.hx +++ b/src/kiss/SpecialForms.hx @@ -6,6 +6,7 @@ import kiss.Reader; import kiss.ReaderExp; import uuid.Uuid; import kiss.Kiss; +import kiss.Macros; using uuid.Uuid; using kiss.Reader; @@ -648,6 +649,21 @@ class SpecialForms { return map; } + + public static function builtinMacroExpanders(k:KissState, ?context:FrontendContext) { + var map:Map = []; + + // when macroExpanding an (object) expression, don't apply aliases to the field names + map["object"] = (wholeExp:ReaderExp, args:Array, k:KissState) -> { + var b = wholeExp.expBuilder(); + var pairs = Lambda.flatten([for (pair in args.groups(2)) { + [pair[0], Kiss.macroExpand(pair[1], k)]; + }]); + b.callSymbol("object", pairs); + }; + + return map; + } public static function caseOr(wholeExp:ReaderExp, args:Array, k:KissState):Expr { wholeExp.checkNumArgs(2, null, "(or )");