From 0f541a3929b2cc2bde49c4e236c2874673d5b569 Mon Sep 17 00:00:00 2001 From: Yvon Date: Thu, 9 Jun 2022 17:48:28 +0300 Subject: [PATCH] Macros.hx improved documentation --- kiss/src/kiss/Macros.hx | 90 +++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 52 deletions(-) diff --git a/kiss/src/kiss/Macros.hx b/kiss/src/kiss/Macros.hx index c58486a8..ddfa2336 100644 --- a/kiss/src/kiss/Macros.hx +++ b/kiss/src/kiss/Macros.hx @@ -44,10 +44,8 @@ class Macros { throw KissError.fromExp(args[0], "only argument to load should be a string literal of a .kiss file path"); }; }; - + k.doc("loadFrom", 2, 2, '(loadFrom "" "")'); macros["loadFrom"] = (wholeExp:ReaderExp, args:Array, k:KissState) -> { - wholeExp.checkNumArgs(2, 2, '(loadFrom "" "")'); - var libPath = switch (args[0].def) { case StrExp(libName): Prelude.libPath(libName); @@ -63,8 +61,8 @@ class Macros { }; function destructiveVersion(op:String, assignOp:String) { + k.doc(assignOp, 2, null, '($assignOp )'); macros[assignOp] = (wholeExp:ReaderExp, exps:Array, k) -> { - wholeExp.checkNumArgs(2, null, '($assignOp [var] [v1] [values...])'); var b = wholeExp.expBuilder(); b.call( b.symbol("set"), [ @@ -98,7 +96,6 @@ class Macros { k.doc("apply", 2, 2, '(apply )' ); macros["apply"] = (wholeExp:ReaderExp, exps:Array, k) -> { var b = wholeExp.expBuilder(); - var callOn = switch (exps[0].def) { case FieldExp(field, exp): exp; @@ -147,7 +144,6 @@ class Macros { // Most conditional compilation macros are based on this macro: k.doc("#if", 2, 3, '(#if )' ); macros["#if"] = (wholeExp:ReaderExp, exps:Array, k) -> { - var b = wholeExp.expBuilder(); var conditionExp = exps.shift(); var thenExp = exps.shift(); @@ -178,10 +174,9 @@ class Macros { }; // But not this one: + k.doc("#case", 2, null, '(#case )>)'); macros["#case"] = (wholeExp:ReaderExp, exps:Array, k) -> { - wholeExp.checkNumArgs(2, null, '(#case [expression] [cases...] [optional: (otherwise [default])])'); var b = wholeExp.expBuilder(); - var caseVar = exps.shift(); var matchPatterns = []; var matchBodies = []; @@ -239,7 +234,6 @@ class Macros { macros["unless"] = bodyIf.bind("unless", "if", true); macros["#when"] = bodyIf.bind("#when", "#if", false); macros["#unless"] = bodyIf.bind("#unless", "#if", true); - macros["cond"] = cond.bind("cond", "if"); macros["#cond"] = cond.bind("#cond", "#if"); @@ -268,7 +262,6 @@ class Macros { k.doc("and", 1, null, "(and )"); function _and(wholeExp:ReaderExp, args:Array, k) { var b = wholeExp.expBuilder(); - var uniqueVarSymbol = b.symbol(); var firstVal = args.shift(); @@ -329,9 +322,8 @@ class Macros { ]) ]); }; - + k.doc("assertThrows", 1, 2, "(assertThrows )"); macros["assertThrows"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(1, 2, "(assertThrows [expression] [message])"); var b = wholeExp.expBuilder(); var expression = exps[0]; var basicMessage = '${expression.def.toString()} should have thrown an error'; @@ -368,10 +360,9 @@ class Macros { throw KissError.fromExp(exp, 'first argument to $formName should be a String or list of strings'); }; } - + + k.doc("defmacro", 3, null, '(defMacro [] )'); macros["defmacro"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(3, null, '(defMacro [name] [[args...]] [body...])'); - var name = switch (exps[0].def) { case Symbol(name): name; default: throw KissError.fromExp(exps[0], "macro name should be a symbol"); @@ -488,9 +479,8 @@ class Macros { }; renameAndDeprecate("defmacro", "defMacro"); + k.doc("undefmacro", 1, 1, '(undefMacro )'); macros["undefmacro"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(1, 1, '(undefMacro [name])'); - var name = switch (exps[0].def) { case Symbol(name): name; default: throw KissError.fromExp(exps[0], "macro name should be a symbol"); @@ -501,8 +491,8 @@ class Macros { }; renameAndDeprecate("undefmacro", "undefMacro"); + k.doc("defreadermacro", 3, null, '(defReaderMacro <"" or []> [] )'); macros["defreadermacro"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(3, null, '(defReaderMacro [optional &start] ["[startingString]" or [startingStrings...]] [[streamArgName]] [body...])'); // reader macros declared in the form (defreadermacro &start ...) will only be applied // at the beginning of lines @@ -571,8 +561,8 @@ class Macros { }; renameAndDeprecate("defreadermacro", "defReaderMacro"); + k.doc("undefreadermacro", 1, 1, '(undefReaderMacro ["" or ])'); macros["undefreadermacro"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(1, 1, '(undefReaderMacro [optional &start] ["[startingString]" or [startingStrings...]])'); // reader macros undeclared in the form (undefReaderMacro &start ...) will be removed from the table // for reader macros that must be at the beginning of lines // at the beginning of lines @@ -624,8 +614,8 @@ class Macros { }; } + k.doc("defalias", 2, 2, "(defAlias <<&call or &ident> whenItsThis> )"); macros["defalias"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(2, 2, "(defAlias [[&call or &ident] whenItsThis] [makeItThis])"); var name = getAliasName(k, exps[0], "defAlias"); aliasMap[name] = exps[1].def; @@ -633,8 +623,8 @@ class Macros { }; renameAndDeprecate("defalias", "defAlias"); + k.doc("undefalias", 1, 1, "(undefAlias <<&call or &ident> alias>)"); macros["undefalias"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(1, 1, "(undefAlias [[&call or &ident] alias])"); var name = getAliasName(k, exps[0], "undefAlias"); aliasMap.remove(name); @@ -648,7 +638,7 @@ class Macros { var thenExpStr = if (assertLet) "" else ""; var elseExpStr = if (assertLet) "" else " "; var maxArgs = if (assertLet) null else 3; - wholeExp.checkNumArgs(2, maxArgs, '($funcName [] ${thenExpStr}${elseExpStr})'); + k.doc(funcName, 2, maxArgs, '($funcName [] ${thenExpStr}${elseExpStr})'); var b = wholeExp.expBuilder(); var bindingList = exps[0].bindingList(funcName); @@ -681,11 +671,10 @@ class Macros { ]) ]); } - macros["ifLet"] = ifLet.bind(false); + k.doc('whenLet', 2, null, "(whenLet [] )"); macros["whenLet"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(2, null, "(whenLet [[enum bindings...]] [body...])"); var b = wholeExp.expBuilder(); b.callSymbol("ifLet", [ exps[0], @@ -694,8 +683,8 @@ class Macros { ]); }; + k.doc("unlessLet", 2, null, "(unlessLet [] )"); macros["unlessLet"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(2, null, "(unlessLet [[enum bindings...]] [body...])"); var b = wholeExp.expBuilder(); b.callSymbol("ifLet", [ exps[0], @@ -706,8 +695,8 @@ class Macros { macros["assertLet"] = ifLet.bind(true); + k.doc("awaitLet", 2, null, "(awaitLet [] )"); function awaitLet(wholeExp:ReaderExp, exps:Array, k:KissState) { - wholeExp.checkNumArgs(2, null, "(awaitLet [] )"); var bindingList = exps[0].bindingList("awaitLet"); var firstName = bindingList.shift(); @@ -747,11 +736,11 @@ class Macros { rejectionHandler ]); } - + macros["awaitLet"] = awaitLet; + k.doc("whileLet", 2, null, "(whileLet [] )"); macros["whileLet"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(2, null, "(whileLet [] )"); var b = wholeExp.expBuilder(); return b.callSymbol("loop", [ b.callSymbol("ifLet", [ @@ -763,9 +752,8 @@ class Macros { }; // TODO test defNew + k.doc("defnew", 1, null, "(defNew [] [] "); macros["defnew"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(1, null, "(defNew [[args...]] [[optional property bindings...]] [optional body...]"); - var args = exps.shift(); var bindingList = []; @@ -826,14 +814,14 @@ class Macros { }; renameAndDeprecate("defnew", "defNew"); + k.doc("collect", 1, 1, "(collect )"); macros["collect"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(1, 1, "(collect [iterator or iterable])"); var b = wholeExp.expBuilder(); b.call(b.symbol("for"), [b.symbol("elem"), exps[0], b.symbol("elem")]); }; function once(macroName:String, wholeExp:ReaderExp, exps:Array, k:KissState) { - wholeExp.checkNumArgs(1, null, '($macroName [body...])'); + k.doc(macroName, 1, null, '($macroName )'); var b = wholeExp.expBuilder(); var flag = b.symbol(); // define the field: @@ -844,9 +832,8 @@ class Macros { macros["once"] = once.bind("var"); macros["oncePerInstance"] = once.bind("prop"); + k.doc("defMacroVar", 2, 2, "(defMacroVar )"); macros["defMacroVar"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(2, 2, "(defMacroVar )"); - var name = exps[0].symbolNameValue(); k.macroVars[name] = Helpers.runAtCompileTimeDynamic(exps[1], k); @@ -854,17 +841,16 @@ class Macros { return null; }; + k.doc("setMacroVar",2, 2, "(setMacroVar )"); macros["setMacroVar"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(2, 2, "(setMacroVar )"); - var name = exps[0].symbolName().withPosOf(exps[0]); var b = wholeExp.expBuilder(); return b.callSymbol("_setMacroVar", [name, exps[1]]); }; + k.doc("defMacroFunction", 3, null, "(defMacroFunction [] )"); macros["defMacroFunction"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(3, null, "(defMacroFunction [] )"); var b = wholeExp.expBuilder(); var name = exps[0].symbolNameValue(); var lambdaExp = b.callSymbol("lambda", [exps[1]].concat(exps.slice(2))); @@ -879,13 +865,13 @@ class Macros { // Replace "try" with this in a try-catch statement to let all exceptions throw // their original call stacks. This is more convenient for debugging than trying to // comment out the "try" and its catches, and re-balance parens + k.doc("letThrow", 1, null, "(letThrow )"); macros["letThrow"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(1, null, "(letThrow )"); exps[0]; }; + k.doc("objectWith", 1, null, "(objectWith ]> )"); macros["objectWith"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(1, null, "(objectWith )"); var objectExps = try { var l = Helpers.bindingList(exps[0], "field bindings for objectWith", true); exps.shift(); @@ -909,8 +895,8 @@ class Macros { } // Macro for triggering collection of expressions throughout a Kiss file, to inject them later with collectedBlocks + k.doc("collectBlocks", 1, 2, "(collectBlocks )"); macros["collectBlocks"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(1, 2, "(collectBlocks )"); var blockName = try { exps[0].symbolNameValue(); } catch (notSymbolError:String) { @@ -925,8 +911,8 @@ class Macros { null; }; + k.doc("collectedBlocks", 1, 1, "(collectedBlocks )"); macros["collectedBlocks"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(1, 1, "(collectedBlocks )"); var blockName = try { exps[0].symbolNameValue(); } catch (notSymbolError:String) { @@ -939,8 +925,8 @@ class Macros { b.begin(k.collectedBlocks[blockName]); }; + k.doc("clamp", 2, 3, "(clamp )"); macros["clamp"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(2, 3, "(clamp )"); var b = wholeExp.expBuilder(); var maxExp = if (exps.length == 3) exps.pop() else b.symbol("null"); var expToSet = exps.shift(); @@ -966,10 +952,9 @@ class Macros { // The wildest code in Kiss to date // TODO test exprCase!! + k.doc("exprCase", 2, null, "(exprCase )"); macros["exprCase"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(2, null, "(exprCase [expr] [pattern callExps...])"); var toMatch = exps.shift(); - var b = wholeExp.expBuilder(); var functionKey = Uuid.v4(); @@ -992,8 +977,8 @@ class Macros { }; // Maybe the NEW wildest code in Kiss? + k.doc("#extern", 4, null, "(#extern [] )"); macros["#extern"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(4, null, "(#extern [] )"); var b = wholeExp.expBuilder(); // Skip all extern code generation if -D no-extern is provided to the compiler @@ -1094,8 +1079,8 @@ class Macros { ])); }; + k.doc("countingLambda", 3, null, "(countingLambda [] )"); macros["countingLambda"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(3, null, "(countingLambda [] )"); var b = wholeExp.expBuilder(); var countVarSymbol = exps[0]; @@ -1114,8 +1099,8 @@ class Macros { }; // Time a block's evaluation + k.doc("measureTime",1, null, "(time )"); macros["measureTime"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(1, null, "(time )"); var b = wholeExp.expBuilder(); return b.callSymbol("haxe.Timer.measure", [b.callSymbol("lambda", [b.list([])].concat(exps))]); @@ -1123,7 +1108,7 @@ class Macros { function indexOfMacro(last:Bool, wholeExp:ReaderExp, exps:Array, k:KissState) { var funcName = if (last) "lastIndexOf" else "indexOf"; - wholeExp.checkNumArgs(2, 3, '($funcName )'); + k.doc(funcName, 2, 3, '($funcName )'); var b = wholeExp.expBuilder(); var cases = [ b.callField(funcName, exps.shift(), exps), @@ -1139,15 +1124,15 @@ class Macros { macros["lastIndexOf"] = indexOfMacro.bind(true); // contains is a macro so it can be called on either an Array or a String + k.doc("contains", 2, 2, '(contains )'); macros["contains"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(2, 2, '(contains )'); var b = wholeExp.expBuilder(); return b.not(b.callSymbol("=", [b.symbol("-1"), b.callField("indexOf", exps[0], [exps[1]])])); } // Under the hood, quoted expressions are just Kiss strings for a KissInterp + k.doc("quote", 1, 1, '(quote )'); macros["quote"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(1, 1, '(quote )'); var b = wholeExp.expBuilder(); return b.str(Reader.toString(exps[0].def)); }; @@ -1157,8 +1142,8 @@ class Macros { // This is all complicated, and language- and platform-dependent. And slow, because it converts Kiss to HScript at runtime. // When (eval) is used in a static function, it cannot access instance variables. // (eval) should not be used for serious purposes. + k.doc("eval", 1, 1, '(eval )'); macros["eval"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(1, 1, '(eval )'); var b = wholeExp.expBuilder(); var className = Context.getLocalClass().toString(); var classSymbol = b.symbol(className); @@ -1199,7 +1184,7 @@ class Macros { function typedCallMacro(name:String, symbol:String, type:String) { macros[name] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(2, null, '($name )'); + k.doc(name, 2, null, '($name )'); var b = wholeExp.expBuilder(); b.callSymbol("the", [b.symbol(type), b.callSymbol('Prelude.$symbol', exps)]); }; @@ -1285,6 +1270,7 @@ class Macros { } // cond expands telescopically into a nested if expression + static function cond(formName:String, underlyingIf:String, wholeExp:ReaderExp, exps:Array, k:KissState) { wholeExp.checkNumArgs(1, null, '($formName [cases...])'); var b = wholeExp.expBuilder();