From 8619ac82ffff8e675805efca5922da8d167c1048 Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Thu, 22 Jul 2021 16:11:41 -0600 Subject: [PATCH] undefreadermacro --- kiss/src/kiss/Macros.hx | 34 ++++++++++++++++++---- projects/aoc/src/year2020/FerrySimDSL.kiss | 1 + 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/kiss/src/kiss/Macros.hx b/kiss/src/kiss/Macros.hx index 38bd91d9..427ec6a5 100644 --- a/kiss/src/kiss/Macros.hx +++ b/kiss/src/kiss/Macros.hx @@ -317,7 +317,7 @@ class Macros { ]); }; - function stringsThatMatch(exp:ReaderExp) { + function stringsThatMatch(exp:ReaderExp, formName:String) { return switch (exp.def) { case StrExp(s): [s]; @@ -328,11 +328,11 @@ class Macros { case StrExp(s): s; default: - throw CompileError.fromExp(s, 'initiator list of defreadermacro must only contain strings'); + throw CompileError.fromExp(s, 'initiator list of $formName must only contain strings'); } ]; default: - throw CompileError.fromExp(exp, 'first argument to defreadermacro should be a String or list of strings'); + throw CompileError.fromExp(exp, 'first argument to $formName should be a String or list of strings'); }; } @@ -440,7 +440,7 @@ class Macros { }; macros["defreadermacro"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { - wholeExp.checkNumArgs(3, null, '(defreadermacro ["[startingString]" or [startingStrings...]] [[streamArgName]] [body...])'); + 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 @@ -451,9 +451,9 @@ class Macros { var strings = switch (exps[0].def) { case MetaExp("start", stringsExp): table = k.startOfLineReadTable; - stringsThatMatch(stringsExp); + stringsThatMatch(stringsExp, "defreadermacro"); default: - stringsThatMatch(exps[0]); + stringsThatMatch(exps[0], "defreadermacro"); }; for (s in strings) { switch (exps[1].def) { @@ -475,6 +475,28 @@ class Macros { return null; }; + 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 + var table = k.readTable; + + // reader macros can define a list of strings that will trigger the macro. When there are multiple, + // this macro will undefine all of them + var strings = switch (exps[0].def) { + case MetaExp("start", stringsExp): + table = k.startOfLineReadTable; + stringsThatMatch(stringsExp, "undefreadermacro"); + default: + stringsThatMatch(exps[0], "undefreadermacro"); + }; + for (s in strings) { + table.remove(s); + } + return null; + }; + macros["defalias"] = (wholeExp:ReaderExp, exps:Array, k:KissState) -> { wholeExp.checkNumArgs(2, 2, "(defalias [[&call or &ident] whenItsThis] [makeItThis])"); var aliasMap:Map = null; diff --git a/projects/aoc/src/year2020/FerrySimDSL.kiss b/projects/aoc/src/year2020/FerrySimDSL.kiss index 07b62a52..69ccc6a6 100644 --- a/projects/aoc/src/year2020/FerrySimDSL.kiss +++ b/projects/aoc/src/year2020/FerrySimDSL.kiss @@ -48,6 +48,7 @@ (defreadermacro "L" [stream] `emptySeat) (defreadermacro "#" [stream] `fullSeat) (defreadermacro "." [stream] `floor) +(undefreadermacro "...") (defreadermacro &start "" [stream] `(state.push ,(ReaderExp.ListExp (readExpArray stream #|"\n"|#)))) \ No newline at end of file