diff --git a/kiss/src/kiss/FieldForms.hx b/kiss/src/kiss/FieldForms.hx index 647eec76..ecd45212 100644 --- a/kiss/src/kiss/FieldForms.hx +++ b/kiss/src/kiss/FieldForms.hx @@ -64,17 +64,6 @@ class FieldForms { }; } - static function fieldName(formName:String, nameExp:ReaderExp) { - return switch (nameExp.def) { - case Symbol(name): - name; - case MetaExp(_, nameExp) | TypedExp(_, nameExp): - fieldName(formName, nameExp); - default: - throw CompileError.fromExp(nameExp, 'The first argument to $formName should be a variable name, :Typed variable name, and/or &meta variable name.'); - }; - } - static function isVoid(nameExp:ReaderExp) { return switch (nameExp.def) { case MetaExp(_, nameExp): @@ -89,7 +78,7 @@ class FieldForms { static function varOrProperty(formName:String, wholeExp:ReaderExp, args:Array, k:KissState):Field { wholeExp.checkNumArgs(1, 3, '($formName [optional: &mut] [optional :type] [variable] [optional value])'); - var name = fieldName(formName, args[0]); + var name = Helpers.varName(formName, args[0]); var access = fieldAccess(formName, name, args[0]); return { @@ -107,7 +96,7 @@ class FieldForms { static function funcOrMethod(formName:String, wholeExp:ReaderExp, args:Array, k:KissState):Field { wholeExp.checkNumArgs(3, null, '($formName [optional :type] [name] [[argNames...]] [body...])'); - var name = fieldName(formName, args[0]); + var name = Helpers.varName(formName, args[0]); var access = fieldAccess(formName, name, args[0]); var returnsValue = !isVoid(args[0]); diff --git a/kiss/src/kiss/Helpers.hx b/kiss/src/kiss/Helpers.hx index 1894cf31..705da415 100644 --- a/kiss/src/kiss/Helpers.hx +++ b/kiss/src/kiss/Helpers.hx @@ -57,6 +57,17 @@ class Helpers { }; } + public static function varName(formName:String, nameExp:ReaderExp) { + return switch (nameExp.def) { + case Symbol(name): + name; + case MetaExp(_, nameExp) | TypedExp(_, nameExp): + varName(formName, nameExp); + default: + throw CompileError.fromExp(nameExp, 'The first argument to $formName should be a variable name, :Typed variable name, and/or &meta variable name.'); + }; + } + // TODO generic type parameter declarations public static function makeFunction(?name:ReaderExp, returnsValue:Bool, argList:ReaderExp, body:List, k:KissState):Function { if (name != null) { diff --git a/kiss/src/kiss/Macros.hx b/kiss/src/kiss/Macros.hx index 49b8ee31..8fc0525b 100644 --- a/kiss/src/kiss/Macros.hx +++ b/kiss/src/kiss/Macros.hx @@ -515,6 +515,24 @@ class Macros { macros["awaitLet"] = awaitLet; + // TODO test defnew + macros["defnew"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { + wholeExp.checkNumArgs(2, null, "(defnew [[args...]] [[property bindings...]] [body...]"); + var bindingList = exps[1].bindingList("defnew"); + var bindingPairs = Prelude.groups(bindingList, 2); + + var b = wholeExp.expBuilder(); + var propertyDefs = [for (bindingPair in bindingPairs) b.call(b.symbol("defprop"), [bindingPair[0]])]; + var propertySetExps = [for (bindingPair in bindingPairs) + b.call(b.symbol("set"), [b.symbol(Helpers.varName("a defprop property binding", bindingPair[0])), bindingPair[1]])]; + return b.begin(propertyDefs.concat([ + b.call(b.symbol("defmethod"), [ + b.symbol("new"), + exps[0] + ].concat(propertySetExps).concat(exps.slice(2))) + ])); + }; + return macros; }