Completely change naming conventions of field forms and definition macros. Close #32
This commit is contained in:
@@ -34,12 +34,9 @@ class CompileError {
|
||||
firstPos + '-' + lastPos.substr(justLineAndColumnIdx);
|
||||
}
|
||||
|
||||
var failed = if (warning) "warning!"; else "failed!";
|
||||
var failed = if (warning) "warning"; else "failed";
|
||||
|
||||
return '\nKiss compilation $failed\n'
|
||||
+ posPrefix
|
||||
+ ": "
|
||||
+ message
|
||||
return '$posPrefix: Kiss compilation $failed: $message'
|
||||
+ "\nFrom:"
|
||||
+ [for (exp in exps) exp.def.toString()].toString();
|
||||
}
|
||||
|
||||
@@ -29,22 +29,22 @@ class FieldForms {
|
||||
map[newName] = form;
|
||||
}
|
||||
|
||||
map["defvar"] = varOrProperty.bind("classVar");
|
||||
renameAndDeprecate("defvar", "classVar");
|
||||
map["defprop"] = varOrProperty.bind("classProp");
|
||||
renameAndDeprecate("defprop", "classProp");
|
||||
map["defvar"] = varOrProperty.bind("var");
|
||||
renameAndDeprecate("defvar", "var");
|
||||
map["defprop"] = varOrProperty.bind("prop");
|
||||
renameAndDeprecate("defprop", "prop");
|
||||
|
||||
map["defun"] = funcOrMethod.bind("classFunction");
|
||||
renameAndDeprecate("defun", "classFunction");
|
||||
map["defmethod"] = funcOrMethod.bind("classMethod");
|
||||
renameAndDeprecate("defmethod", "classMethod");
|
||||
map["defun"] = funcOrMethod.bind("function");
|
||||
renameAndDeprecate("defun", "function");
|
||||
map["defmethod"] = funcOrMethod.bind("method");
|
||||
renameAndDeprecate("defmethod", "method");
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
static function fieldAccess(formName:String, fieldName:String, nameExp:ReaderExp, ?access:Array<Access>) {
|
||||
if (access == null) {
|
||||
access = if (["defvar", "defprop", "classVar", "classProp"].indexOf(formName) != -1) {
|
||||
access = if (["defvar", "defprop", "var", "prop"].indexOf(formName) != -1) {
|
||||
[AFinal];
|
||||
} else {
|
||||
[];
|
||||
@@ -69,7 +69,7 @@ class FieldForms {
|
||||
access.push(AFinal);
|
||||
fieldAccess(formName, fieldName, nameExp, access);
|
||||
default:
|
||||
if (["defvar", "defun", "classVar", "classFunction"].indexOf(formName) != -1) {
|
||||
if (["defvar", "defun", "var", "function"].indexOf(formName) != -1) {
|
||||
access.push(AStatic);
|
||||
}
|
||||
access.push(if (fieldName.startsWith("_")) APrivate else APublic);
|
||||
|
||||
@@ -340,7 +340,7 @@ class Macros {
|
||||
}
|
||||
|
||||
macros["defmacro"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) -> {
|
||||
wholeExp.checkNumArgs(3, null, '(defmacro [name] [[args...]] [body...])');
|
||||
wholeExp.checkNumArgs(3, null, '(defMacro [name] [[args...]] [body...])');
|
||||
|
||||
var name = switch (exps[0].def) {
|
||||
case Symbol(name): name;
|
||||
@@ -439,9 +439,10 @@ class Macros {
|
||||
|
||||
null;
|
||||
};
|
||||
renameAndDeprecate("defmacro", "defMacro");
|
||||
|
||||
macros["undefmacro"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) -> {
|
||||
wholeExp.checkNumArgs(1, 1, '(undefmacro [name])');
|
||||
wholeExp.checkNumArgs(1, 1, '(undefMacro [name])');
|
||||
|
||||
var name = switch (exps[0].def) {
|
||||
case Symbol(name): name;
|
||||
@@ -451,9 +452,10 @@ class Macros {
|
||||
k.macros.remove(name);
|
||||
null;
|
||||
};
|
||||
renameAndDeprecate("undefmacro", "undefMacro");
|
||||
|
||||
macros["defreadermacro"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) -> {
|
||||
wholeExp.checkNumArgs(3, null, '(defreadermacro [optional &start] ["[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
|
||||
@@ -464,9 +466,9 @@ class Macros {
|
||||
var strings = switch (exps[0].def) {
|
||||
case MetaExp("start", stringsExp):
|
||||
table = k.startOfLineReadTable;
|
||||
stringsThatMatch(stringsExp, "defreadermacro");
|
||||
stringsThatMatch(stringsExp, "defReaderMacro");
|
||||
default:
|
||||
stringsThatMatch(exps[0], "defreadermacro");
|
||||
stringsThatMatch(exps[0], "defReaderMacro");
|
||||
};
|
||||
for (s in strings) {
|
||||
switch (exps[1].def) {
|
||||
@@ -487,9 +489,10 @@ class Macros {
|
||||
|
||||
return null;
|
||||
};
|
||||
renameAndDeprecate("defreadermacro", "defReaderMacro");
|
||||
|
||||
macros["undefreadermacro"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) -> {
|
||||
wholeExp.checkNumArgs(1, 1, '(undefreadermacro [optional &start] ["[startingString]" or [startingStrings...]])');
|
||||
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
|
||||
@@ -509,6 +512,7 @@ class Macros {
|
||||
}
|
||||
return null;
|
||||
};
|
||||
renameAndDeprecate("undefreadermacro", "undefReaderMacro");
|
||||
|
||||
// Having this floating out here is sketchy, but should work out fine because the variable is always re-set
|
||||
// through the next function before being used in defalias or undefalias
|
||||
@@ -535,20 +539,22 @@ class Macros {
|
||||
}
|
||||
|
||||
macros["defalias"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) -> {
|
||||
wholeExp.checkNumArgs(2, 2, "(defalias [[&call or &ident] whenItsThis] [makeItThis])");
|
||||
var name = getAliasName(k, exps[0], "defalias");
|
||||
wholeExp.checkNumArgs(2, 2, "(defAlias [[&call or &ident] whenItsThis] [makeItThis])");
|
||||
var name = getAliasName(k, exps[0], "defAlias");
|
||||
|
||||
aliasMap[name] = exps[1].def;
|
||||
return null;
|
||||
};
|
||||
renameAndDeprecate("defalias", "defAlias");
|
||||
|
||||
macros["undefalias"] = (wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) -> {
|
||||
wholeExp.checkNumArgs(1, 1, "(undefalias [[&call or &ident] alias])");
|
||||
var name = getAliasName(k, exps[0], "undefalias");
|
||||
wholeExp.checkNumArgs(1, 1, "(undefAlias [[&call or &ident] alias])");
|
||||
var name = getAliasName(k, exps[0], "undefAlias");
|
||||
|
||||
aliasMap.remove(name);
|
||||
return null;
|
||||
};
|
||||
renameAndDeprecate("undefalias", "undefAlias");
|
||||
|
||||
// Macros that null-check and extract patterns from enums (inspired by Rust)
|
||||
function ifLet(wholeExp:ReaderExp, exps:Array<ReaderExp>, k:KissState) {
|
||||
@@ -661,11 +667,11 @@ class Macros {
|
||||
|
||||
var propertyDefs = [for (bindingPair in bindingPairs) {
|
||||
var b = bindingPair[0].expBuilder();
|
||||
b.call(b.symbol("defprop"), [bindingPair[0]]);
|
||||
b.call(b.symbol("prop"), [bindingPair[0]]);
|
||||
}];
|
||||
var propertySetExps = [for (bindingPair in bindingPairs) {
|
||||
var b = bindingPair[1].expBuilder();
|
||||
b.call(b.symbol("set"), [b.symbol(Helpers.varName("a defprop property binding", bindingPair[0])), bindingPair[1]]);
|
||||
b.call(b.symbol("set"), [b.symbol(Helpers.varName("a prop property binding", bindingPair[0])), bindingPair[1]]);
|
||||
}];
|
||||
|
||||
var argList = [];
|
||||
@@ -676,7 +682,7 @@ class Macros {
|
||||
case MetaExp("prop", propExp):
|
||||
argList.push(propExp);
|
||||
propertyDefs.push(
|
||||
b.call(b.symbol("defprop"), [propExp]));
|
||||
b.call(b.symbol("prop"), [propExp]));
|
||||
// TODO allow &prop &mut or &mut &prop
|
||||
switch (propExp.def) {
|
||||
case TypedExp(_, {pos: _, def: Symbol(name)}):
|
||||
@@ -693,7 +699,7 @@ class Macros {
|
||||
var b = wholeExp.expBuilder();
|
||||
|
||||
return b.begin(propertyDefs.concat([
|
||||
b.call(b.symbol("defmethod"), [
|
||||
b.call(b.symbol("method"), [
|
||||
b.symbol("new"),
|
||||
b.list(argList)
|
||||
].concat(propertySetExps).concat(exps.slice(2)))
|
||||
@@ -715,8 +721,8 @@ class Macros {
|
||||
return b.call(b.symbol("when"), [flag, b.call(b.symbol("set"), [flag, b.symbol("false")])].concat(exps));
|
||||
}
|
||||
|
||||
macros["once"] = once.bind("defvar");
|
||||
macros["oncePerInstance"] = once.bind("defprop");
|
||||
macros["once"] = once.bind("var");
|
||||
macros["oncePerInstance"] = once.bind("prop");
|
||||
|
||||
// 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
|
||||
|
||||
@@ -226,7 +226,7 @@ class SpecialForms {
|
||||
case KeyValueExp(_, _): k.convert(namesExp);
|
||||
default: {
|
||||
bodyExps.insert(0,
|
||||
CallExp(Symbol("deflocal").withPosOf(args[2]), [namesExp, Symbol(uniqueVarName).withPosOf(args[2])]).withPosOf(args[2]));
|
||||
CallExp(Symbol("localVar").withPosOf(args[2]), [namesExp, Symbol(uniqueVarName).withPosOf(args[2])]).withPosOf(args[2]));
|
||||
macro $i{uniqueVarName};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,80 +1,80 @@
|
||||
// (load) brings in the fields and compile-time definitions of another Kiss file
|
||||
(load "BasicTestCaseExtra.kiss")
|
||||
|
||||
// (defvar) declares static variables
|
||||
(defvar message "Howdy")
|
||||
// (var) declares static variables
|
||||
(var message "Howdy")
|
||||
|
||||
// #| ... |# parses and injects raw Haxe code
|
||||
(defvar mathResult #|5 + 6 * 3|#) // Order of operations will apply
|
||||
(var mathResult #|5 + 6 * 3|#) // Order of operations will apply
|
||||
|
||||
// (defun) declares static functions
|
||||
(defun myFloor [num]
|
||||
// (function) declares static functions
|
||||
(function myFloor [num]
|
||||
// funcalls can use dot access
|
||||
(Math.floor num))
|
||||
|
||||
// functions are resolved in the macro context
|
||||
(defvar funResult (myFloor 7.5))
|
||||
(var funResult (myFloor 7.5))
|
||||
|
||||
// (defprop) declares instance variables
|
||||
(defprop myField 5)
|
||||
// (prop) declares instance variables
|
||||
(prop myField 5)
|
||||
|
||||
// (defmethod) declares instance methods
|
||||
(defmethod myMethod [] this.myField)
|
||||
// (method) declares instance methods
|
||||
(method myMethod [] this.myField)
|
||||
|
||||
// [...] returns a Kiss array (they have special features and convert implicitly)
|
||||
(defvar myArray [1 2 3])
|
||||
(var myArray [1 2 3])
|
||||
|
||||
// Array access is via nth
|
||||
(defvar myArrayLast (nth myArray -1))
|
||||
(var myArrayLast (nth myArray -1))
|
||||
|
||||
// (collect) turns iterators to arrays
|
||||
(defun _testCollect []
|
||||
(function _testCollect []
|
||||
(Assert.equals "[0,1,2]" (Std.string (collect (range 3)))))
|
||||
|
||||
// Variadic math uses haxe's Lambda.fold under the hood
|
||||
(defvar mySum (+ 1 2 3))
|
||||
(var mySum (+ 1 2 3))
|
||||
|
||||
(defvar myDifference (- 5 4 3))
|
||||
(var myDifference (- 5 4 3))
|
||||
|
||||
(defun _testMultiplication []
|
||||
(function _testMultiplication []
|
||||
(Assert.equals 60 (* 2 5 6))
|
||||
(Assert.equals 5522401584 (* 84 289 89 71 36))
|
||||
(Assert.equals "heyheyhey" (* "hey" 3)))
|
||||
|
||||
// All math operations return floats, none truncate by default
|
||||
(defvar myQuotient (/ 6 3 2 2))
|
||||
(var myQuotient (/ 6 3 2 2))
|
||||
|
||||
(defvar myRemainder (% 10 6))
|
||||
(var myRemainder (% 10 6))
|
||||
|
||||
(defvar myPower (^ 2 8))
|
||||
(var myPower (^ 2 8))
|
||||
|
||||
(defvar &mut myNum 6)
|
||||
(defvar myInc ++myNum)
|
||||
(var &mut myNum 6)
|
||||
(var myInc ++myNum)
|
||||
|
||||
(defvar myMin (min 9 3 7 1))
|
||||
(defvar myMax (max 9 3 7 1))
|
||||
(var myMin (min 9 3 7 1))
|
||||
(var myMax (max 9 3 7 1))
|
||||
|
||||
(defun _testLessThan []
|
||||
(function _testLessThan []
|
||||
(Assert.isTrue (< 1 2 3 4))
|
||||
(Assert.isFalse (< 1 1 3 4))
|
||||
(Assert.isFalse (< 1 12 12)))
|
||||
|
||||
(defun _testLesserEqual []
|
||||
(function _testLesserEqual []
|
||||
(Assert.isTrue (<= 1 2 3 4))
|
||||
(Assert.isTrue (<= 1 1 3 4))
|
||||
(Assert.isFalse (<= 1 12 11)))
|
||||
|
||||
(defun _testGreaterThan []
|
||||
(function _testGreaterThan []
|
||||
(Assert.isTrue (> 4 3 2 1))
|
||||
(Assert.isFalse (> 4 4 2 1))
|
||||
(Assert.isFalse (> 9 3 3)))
|
||||
|
||||
(defun _testGreaterEqual []
|
||||
(function _testGreaterEqual []
|
||||
(Assert.isTrue (>= 4 3 2 1))
|
||||
(Assert.isTrue (>= 4 4 2 1))
|
||||
(Assert.isFalse (>= 9 4 5)))
|
||||
|
||||
(defun _testEqual []
|
||||
(function _testEqual []
|
||||
(Assert.isTrue (= 1 1 1 1))
|
||||
(Assert.isFalse (= 1 2 1 1))
|
||||
(Assert.isTrue (= "hey" "hey" "hey"))
|
||||
@@ -83,7 +83,7 @@
|
||||
(Assert.isFalse (= true false true))
|
||||
(Assert.isTrue (= false false false)))
|
||||
|
||||
(defun _testIf []
|
||||
(function _testIf []
|
||||
(Assert.equals true (if 1 true false))
|
||||
(Assert.equals true (if 0 true false))
|
||||
(Assert.equals true (if -1 true false))
|
||||
@@ -97,28 +97,28 @@
|
||||
(Assert.equals 5 (if true 5))
|
||||
(Assert.equals null (if false 5)))
|
||||
|
||||
(defvar :Int myInt 8)
|
||||
(var :Int myInt 8)
|
||||
|
||||
(defun myTryCatch [:Any e]
|
||||
(function myTryCatch [:Any e]
|
||||
(try
|
||||
(throw e)
|
||||
(catch [:String error] 5)
|
||||
(catch [:Int error] 6)
|
||||
(catch [error] 7)))
|
||||
|
||||
(defun myTypeCheck []
|
||||
(function myTypeCheck []
|
||||
(the Int 5))
|
||||
|
||||
(defun _testConcat []
|
||||
(function _testConcat []
|
||||
(Assert.equals (.toString [1 2 3 4]) (.toString (concat [1] [2 3] [4]))))
|
||||
|
||||
(defun _testGroups []
|
||||
(function _testGroups []
|
||||
(Assert.equals (.toString [[1 2] [3 4]]) (.toString (groups [1 2 3 4] 2)))
|
||||
(Assert.equals (.toString [[1 2 3] [4]]) (.toString (groups [1 2 3 4] 3 Keep)))
|
||||
(try (begin (groups [1 2 3 4] 3 Throw) (Assert.fail))
|
||||
(catch [error] (Assert.pass))))
|
||||
|
||||
(defun _testZip []
|
||||
(function _testZip []
|
||||
(Assert.equals (.toString [[1 2] [3 4]]) (.toString (zipThrow [1 3] [2 4])))
|
||||
(Assert.equals (.toString [[1 2] [3 null]]) (.toString (zipKeep [1 3] [2])))
|
||||
(Assert.equals (.toString [[1 2] [null 4]]) (.toString (zipKeep [1 null] [2 4])))
|
||||
@@ -130,11 +130,11 @@
|
||||
(Assert.equals (.toString [[1 2]]) (.toString (zipDrop [1 2 3 4] [2])))
|
||||
(Assert.equals (.toString [[1 2] [3 4]]) (.toString (apply zipThrow [[1 3] [2 4]]))))
|
||||
|
||||
(defun _testEnumerate []
|
||||
(function _testEnumerate []
|
||||
(Assert.equals (.toString [[0 1] [1 2]]) (.toString (enumerate [1 2])))
|
||||
(Assert.equals (.toString [[1 1] [2 2]]) (.toString (enumerate [1 2] 1))))
|
||||
|
||||
(defun _testLet []
|
||||
(function _testLet []
|
||||
(let [a 5
|
||||
b 6
|
||||
:String c "stuff"]
|
||||
@@ -146,50 +146,50 @@
|
||||
(set a "str2")
|
||||
(Assert.equals "str2" a)))
|
||||
|
||||
(defvar myConstructedString (new String "sup"))
|
||||
(var myConstructedString (new String "sup"))
|
||||
|
||||
(defvar myCond1 (cond
|
||||
(var myCond1 (cond
|
||||
((= 5 6) "not this")
|
||||
((= 8 9) "not this either")
|
||||
((= 1 1) "this one")
|
||||
(true "not the default")))
|
||||
|
||||
(defvar myCond2 (cond
|
||||
(var myCond2 (cond
|
||||
((= 5 6) "not this")
|
||||
((= 8 9) "not this either")
|
||||
((= 2 1) "not the third one")
|
||||
(true "the default")))
|
||||
|
||||
(defvar myCond3 (cond
|
||||
(var myCond3 (cond
|
||||
((= 5 5) "this")
|
||||
(true "default")))
|
||||
|
||||
(defvar myCondFallthrough (cond
|
||||
(var myCondFallthrough (cond
|
||||
(false "not this")))
|
||||
|
||||
(defvar myOr1 (or null 5))
|
||||
(var myOr1 (or null 5))
|
||||
|
||||
(defvar myAnd1 (and 5 6))
|
||||
(defvar myAnd2 (and false 5 6))
|
||||
(defvar myAnd3 (and 5 false 6))
|
||||
(var myAnd1 (and 5 6))
|
||||
(var myAnd2 (and false 5 6))
|
||||
(var myAnd3 (and 5 false 6))
|
||||
|
||||
(defun mySetLocal []
|
||||
(function mySetLocal []
|
||||
(localVar &mut loc "one thing")
|
||||
(set loc "another thing")
|
||||
loc)
|
||||
|
||||
(defvar myNot1 (not 5))
|
||||
(defvar myNot2 !5)
|
||||
(var myNot1 (not 5))
|
||||
(var myNot2 !5)
|
||||
|
||||
(defvar myFilteredList (begin
|
||||
(var myFilteredList (begin
|
||||
(localVar l [-1 -2 5 -3 6])
|
||||
(l.filter (lambda [v] (< 0 v)))))
|
||||
|
||||
(defvar myWhen1 (when true 5 6))
|
||||
(var myWhen1 (when true 5 6))
|
||||
|
||||
(defvar myListOfTen [1 2 3 4 5 6 7 8 9 10])
|
||||
(var myListOfTen [1 2 3 4 5 6 7 8 9 10])
|
||||
|
||||
(defun _testQuickNths []
|
||||
(function _testQuickNths []
|
||||
(Assert.equals 1 (first myListOfTen))
|
||||
(Assert.equals 2 (second myListOfTen))
|
||||
(Assert.equals 3 (third myListOfTen))
|
||||
@@ -202,7 +202,7 @@
|
||||
(Assert.equals 10 (tenth myListOfTen))
|
||||
(Assert.equals 10 (last myListOfTen)))
|
||||
|
||||
(defun _testListDestructuring []
|
||||
(function _testListDestructuring []
|
||||
(localVar [a b c d &mut e f g h i j] myListOfTen)
|
||||
(Assert.equals 1 a)
|
||||
(Assert.equals 2 b)
|
||||
@@ -232,9 +232,9 @@
|
||||
(Assert.equals 10 j)))
|
||||
|
||||
|
||||
(defvar myMetaList [myListOfTen myListOfTen myListOfTen])
|
||||
(var myMetaList [myListOfTen myListOfTen myListOfTen])
|
||||
|
||||
(defun _testDoFor []
|
||||
(function _testDoFor []
|
||||
(localVar &mut c 0)
|
||||
(doFor v myListOfTen
|
||||
(Assert.equals (+ c 1) v)
|
||||
@@ -251,7 +251,7 @@
|
||||
(Assert.equals 9 i)
|
||||
(Assert.equals 10 j)))
|
||||
|
||||
(defun _testFor []
|
||||
(function _testFor []
|
||||
(localVar incrementedList (for v myListOfTen (+ 1 v)))
|
||||
(let [[a b c d e f g h i j] incrementedList]
|
||||
(Assert.equals 2 a)
|
||||
@@ -270,34 +270,34 @@
|
||||
(Assert.equals 5 e)
|
||||
(Assert.equals 10 i)))
|
||||
|
||||
(defun myOptionalFunc [a &opt b c]
|
||||
(function myOptionalFunc [a &opt b c]
|
||||
(Assert.equals 5 a)
|
||||
(Assert.equals null b)
|
||||
(Assert.equals 6 (or c 6))) // (or [optionalVar] [defaultValue]) is the convention for default values
|
||||
|
||||
(defun myRestSum [firstOne &rest :List<Int> others]
|
||||
(function myRestSum [firstOne &rest :List<Int> others]
|
||||
(localVar &mut sum firstOne)
|
||||
(doFor nextOne others (set sum (+ sum nextOne)))
|
||||
sum)
|
||||
|
||||
(defvar myRest1 (myRestSum 5))
|
||||
(defvar myRest2 (myRestSum 1 1 1 1 1))
|
||||
(defvar myRest3 (myRestSum 1 2 2))
|
||||
(var myRest1 (myRestSum 5))
|
||||
(var myRest2 (myRestSum 1 1 1 1 1))
|
||||
(var myRest3 (myRestSum 1 2 2))
|
||||
|
||||
(defun myCombinedOptRest [firstOne &opt secondOne &rest :List<String> thirdAndMore]
|
||||
(function myCombinedOptRest [firstOne &opt secondOne &rest :List<String> thirdAndMore]
|
||||
(localVar &mut concatString (+ firstOne (or secondOne "boop")))
|
||||
(doFor str thirdAndMore (set concatString (+ concatString str)))
|
||||
concatString)
|
||||
|
||||
(defvar myCombined1 (myCombinedOptRest "a" "b" "c" "d"))
|
||||
(defvar myCombined2 (myCombinedOptRest "a"))
|
||||
(defvar myCombined3 (myCombinedOptRest "a" "b"))
|
||||
(var myCombined1 (myCombinedOptRest "a" "b" "c" "d"))
|
||||
(var myCombined2 (myCombinedOptRest "a"))
|
||||
(var myCombined3 (myCombinedOptRest "a" "b"))
|
||||
|
||||
(defun _testFieldExps []
|
||||
(function _testFieldExps []
|
||||
(Assert.equals "hey" (.trim " hey "))
|
||||
(Assert.equals "e" (.charAt (.trim " hey ") 1)))
|
||||
|
||||
(defun _testBreakContinue []
|
||||
(function _testBreakContinue []
|
||||
(let [[a b c]
|
||||
(for val [1 2 3 4 5 6 7 8]
|
||||
(if (> val 6)
|
||||
@@ -309,7 +309,7 @@
|
||||
(Assert.equals 4 b)
|
||||
(Assert.equals 6 c)))
|
||||
|
||||
(defun _testAssert []
|
||||
(function _testAssert []
|
||||
(try
|
||||
(assert false (+ "false " "should " "have " "been " "true"))
|
||||
(catch [:String message]
|
||||
@@ -318,13 +318,13 @@
|
||||
(assert true)
|
||||
(assert ![]))
|
||||
|
||||
(defun _testApply []
|
||||
(function _testApply []
|
||||
(Assert.equals 6 (apply + [1 2 3])))
|
||||
|
||||
(defun applyWithMethod [obj]
|
||||
(function applyWithMethod [obj]
|
||||
(apply .multiply obj [6]))
|
||||
|
||||
(defun _testAnonymousObject []
|
||||
(function _testAnonymousObject []
|
||||
(let [obj
|
||||
(object
|
||||
a "string A"
|
||||
@@ -332,10 +332,10 @@
|
||||
(Assert.equals "string A" obj.a)
|
||||
(Assert.equals 5 obj.b)))
|
||||
|
||||
(defun toOption [:Dynamic value]
|
||||
(function toOption [:Dynamic value]
|
||||
(if value (Some value) None))
|
||||
|
||||
(defun _testCase []
|
||||
(function _testCase []
|
||||
(case (toOption [])
|
||||
(None (Assert.pass))
|
||||
((Some value) (Assert.fail)))
|
||||
@@ -375,7 +375,7 @@
|
||||
(Assert.isTrue (Type.enumEq (Some 5) inner)))
|
||||
(otherwise (Assert.fail))))
|
||||
|
||||
(defun _testMaps []
|
||||
(function _testMaps []
|
||||
(localVar :Map<String,String> myMap [=>"hey" "you"
|
||||
=>"found" "me"])
|
||||
(Assert.equals "you" (dictGet myMap "hey"))
|
||||
@@ -389,7 +389,7 @@
|
||||
(Assert.equals "you" v1)
|
||||
(Assert.equals "me" v2)))
|
||||
|
||||
(defun _testRange []
|
||||
(function _testRange []
|
||||
// With just one arg, it's the max:
|
||||
(localVar &mut :kiss.List<Int> myList (for i (range 5) i))
|
||||
(Assert.equals 4 (nth myList -1))
|
||||
@@ -403,32 +403,32 @@
|
||||
(Assert.equals 9 (second myList))
|
||||
(Assert.equals 15 (last myList)))
|
||||
|
||||
(defun _testRest []
|
||||
(function _testRest []
|
||||
(Assert.equals (.toString [2 3 4]) (.toString (rest [1 2 3 4]))))
|
||||
|
||||
(defun doSomething [:Int->Int func]
|
||||
(function doSomething [:Int->Int func]
|
||||
(func 5))
|
||||
|
||||
(defun itsAMonster [:Null<Map<String,Map<String,Array<String>>>> monsterArg] "but it still compiles")
|
||||
(function itsAMonster [:Null<Map<String,Map<String,Array<String>>>> monsterArg] "but it still compiles")
|
||||
|
||||
(defun _testTypeParsing []
|
||||
(function _testTypeParsing []
|
||||
// Do stuff with functions that take complex type parameters, mostly just to check if it compiles
|
||||
(Assert.equals 5 (doSomething (lambda [i] i)))
|
||||
(Assert.equals 7 (doSomething (lambda [i] (+ i 2))))
|
||||
// Pass null to the really crazy one because I'm lazy:
|
||||
(Assert.equals "but it still compiles" (itsAMonster null)))
|
||||
|
||||
(defmacro defconstfunc [name const] `(defun ,name [] ,const))
|
||||
(defMacro defconstfunc [name const] `(function ,name [] ,const))
|
||||
|
||||
(defconstfunc func5 5)
|
||||
(defconstfunc funcHello "hello")
|
||||
|
||||
(defun _testDefmacro []
|
||||
(function _testDefmacro []
|
||||
(Assert.equals 5 (func5))
|
||||
(Assert.equals "hello" (funcHello)))
|
||||
|
||||
(defvar &mut welcomeCount 0)
|
||||
(defmacro macroWithLogic [name]
|
||||
(var &mut welcomeCount 0)
|
||||
(defMacro macroWithLogic [name]
|
||||
(localVar message1 (ReaderExp.StrExp "Welcome "))
|
||||
(localVar message2 (ReaderExp.StrExp " (Guest #"))
|
||||
(localVar message3 (ReaderExp.StrExp ")"))
|
||||
@@ -436,16 +436,16 @@
|
||||
`(begin (set welcomeCount (+ welcomeCount 1))
|
||||
(+ ,message1 ,name ,message2 (Std.string welcomeCount) ,message3)))
|
||||
|
||||
(defun _testDefmacroWithLogic []
|
||||
(function _testDefmacroWithLogic []
|
||||
(Assert.equals "Welcome Stevo (Guest #1)" (macroWithLogic "Stevo"))
|
||||
(Assert.equals "Welcome Bob (Guest #2)" (macroWithLogic "Bob")))
|
||||
|
||||
// Make sure built-in call aliases don't override user-defined variables
|
||||
(defun _testCallAlias []
|
||||
(function _testCallAlias []
|
||||
(let [map [=>"hey" "you"]]
|
||||
(Assert.equals "you" (dictGet map "hey"))))
|
||||
|
||||
(defun _testAssignArith []
|
||||
(function _testAssignArith []
|
||||
(localVar &mut num 5)
|
||||
(+= num 5 6)
|
||||
(Assert.equals 16 num)
|
||||
@@ -460,7 +460,7 @@
|
||||
(-= num 5 6)
|
||||
(Assert.equals -10 num))
|
||||
|
||||
(defun _testPatternLets []
|
||||
(function _testPatternLets []
|
||||
(let [some5 (Some 5)
|
||||
some6 (Some 6)
|
||||
none None
|
||||
@@ -484,11 +484,11 @@
|
||||
(Assert.fail))
|
||||
(Assert.equals 2 v))))
|
||||
|
||||
(defun _testRawString []
|
||||
(function _testRawString []
|
||||
(Assert.equals #| "\\" |# #"\"#)
|
||||
(Assert.equals #| "\"#" |# ##""#"##))
|
||||
|
||||
(defun _testKissStrings []
|
||||
(function _testKissStrings []
|
||||
(Assert.equals #| "\\\t\r\n\"$" |# "\\\t\r\n\"\$")
|
||||
(let [str "it's"
|
||||
num 3
|
||||
@@ -497,7 +497,7 @@
|
||||
// string interpolation:
|
||||
(Assert.equals "it's 3asy as [a,b,c] [1,2,3]" "$str ${num}asy as $l1 $l2")))
|
||||
|
||||
(defun _testArrowLambdas []
|
||||
(function _testArrowLambdas []
|
||||
(let [withArgs
|
||||
->[arg1 arg2] (+ arg1 arg2)
|
||||
withArg
|
||||
@@ -515,13 +515,13 @@
|
||||
(void)
|
||||
(Assert.equals 6 num)))
|
||||
|
||||
(defvar &mut voidRan false)
|
||||
(defun :Void myVoid [] (set voidRan true))
|
||||
(defun _testVoid []
|
||||
(var &mut voidRan false)
|
||||
(function :Void myVoid [] (set voidRan true))
|
||||
(function _testVoid []
|
||||
(myVoid)
|
||||
(Assert.isTrue voidRan))
|
||||
|
||||
(defun _testLetThrow []
|
||||
(function _testLetThrow []
|
||||
(try
|
||||
{
|
||||
(letThrow
|
||||
@@ -529,4 +529,4 @@
|
||||
(catch [e] (Assert.fail)))
|
||||
(Assert.fail)}
|
||||
(catch [:String e]
|
||||
(Assert.equals "the error we want" e))))
|
||||
(Assert.equals "the error we want" e))))
|
||||
|
||||
@@ -1 +1 @@
|
||||
(defun loadedFunction [] "loaded")
|
||||
(function loadedFunction [] "loaded")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
(defun myFun []
|
||||
(function myFun []
|
||||
(localVar something 5)
|
||||
)
|
||||
|
||||
// This comment used to cause a hard-to-track-down error!
|
||||
// This comment used to cause a hard-to-track-down error!
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
(defun myFun []
|
||||
(function myFun []
|
||||
(localVar something 5)
|
||||
// This comment used to cause a hard-to-track-down error!
|
||||
)
|
||||
)
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
(defvar runningInHaxe (#if interp true false))
|
||||
(defvar runningInPyOrJs (#if (or py js) true false))
|
||||
(var runningInHaxe (#if interp true false))
|
||||
(var runningInPyOrJs (#if (or py js) true false))
|
||||
|
||||
(defun number []
|
||||
(function number []
|
||||
(let [&mut num 5]
|
||||
(#when interp
|
||||
(+= num 5)
|
||||
(-= num 4))
|
||||
num))
|
||||
|
||||
(defun number2 []
|
||||
(function number2 []
|
||||
(let [&mut num 12]
|
||||
(#unless interp
|
||||
(+= num 5)
|
||||
(-= num 8))
|
||||
num))
|
||||
|
||||
(defvar targetLanguage
|
||||
(var targetLanguage
|
||||
(#cond
|
||||
(cpp "C++")
|
||||
(cs "C#")
|
||||
@@ -24,10 +24,10 @@
|
||||
(js "JavaScript")
|
||||
(python "Python")))
|
||||
|
||||
(defun _testCase []
|
||||
(function _testCase []
|
||||
(#case var1ForCase
|
||||
("var1" (Assert.pass))
|
||||
(otherwise (Assert.fail)))
|
||||
(#case var2ForCase
|
||||
("var2" (Assert.pass))
|
||||
(otherwise (Assert.fail))))
|
||||
(otherwise (Assert.fail))))
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
// TODO make a better position reification scheme here
|
||||
(defreadermacro "goop" [stream] #|ReaderExp.CallExp({pos: {file: "bleh", line: 1, column: 1, absoluteChar: 1}, def: ReaderExp.Symbol("Assert.isTrue")}, [{pos: {file: "bleh", line: 1, column: 1, absoluteChar: 1}, def: ReaderExp.Symbol("true")}])|#)
|
||||
(defreadermacro "gloop" [stream] #|ReaderExp.CallExp({pos: {file: "bleh", line: 1, column: 1, absoluteChar: 1}, def: ReaderExp.Symbol("Assert.isFalse")}, [{pos: {file: "bleh", line: 1, column: 1, absoluteChar: 1}, def: ReaderExp.Symbol("false")}])|#)
|
||||
(defReaderMacro "goop" [stream] #|ReaderExp.CallExp({pos: {file: "bleh", line: 1, column: 1, absoluteChar: 1}, def: ReaderExp.Symbol("Assert.isTrue")}, [{pos: {file: "bleh", line: 1, column: 1, absoluteChar: 1}, def: ReaderExp.Symbol("true")}])|#)
|
||||
(defReaderMacro "gloop" [stream] #|ReaderExp.CallExp({pos: {file: "bleh", line: 1, column: 1, absoluteChar: 1}, def: ReaderExp.Symbol("Assert.isFalse")}, [{pos: {file: "bleh", line: 1, column: 1, absoluteChar: 1}, def: ReaderExp.Symbol("false")}])|#)
|
||||
@@ -1,4 +1,4 @@
|
||||
(defun _testListEating []
|
||||
(function _testListEating []
|
||||
// TODO document that list-eating only works on explictly Array-typed variables
|
||||
(let [:Array<Int> l [1 2 3 4]]
|
||||
(case l
|
||||
@@ -29,4 +29,4 @@
|
||||
(Assert.equals (.toString [1 2 3]) (.toString rest))
|
||||
(Assert.equals 4 last))
|
||||
(otherwise
|
||||
(Assert.fail)))))
|
||||
(Assert.fail)))))
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
(defmacro defMultiple [varName funcName]
|
||||
(defMacro defMultiple [varName funcName]
|
||||
`{
|
||||
(defvar ,varName 5)
|
||||
(defun ,funcName [] 6)})
|
||||
(var ,varName 5)
|
||||
(function ,funcName [] 6)})
|
||||
|
||||
(defMultiple myVar myFunc)
|
||||
|
||||
(defmacro variadicPlus [&rest l]
|
||||
(defMacro variadicPlus [&rest l]
|
||||
`(+ ,@l))
|
||||
(defmacro listPlus [l]
|
||||
(defMacro listPlus [l]
|
||||
`(+ ,@l))
|
||||
|
||||
// Both forms of passing expression lists to macros should work:
|
||||
(defun sum1 [] (variadicPlus 1 2 3))
|
||||
(defun sum2 [] (listPlus [1 2 3]))
|
||||
(function sum1 [] (variadicPlus 1 2 3))
|
||||
(function sum2 [] (listPlus [1 2 3]))
|
||||
|
||||
// You should be able to run list comprehensions on expressions
|
||||
// and put the pieces back together in a modular way
|
||||
(defmacro altDefun [name args &body body]
|
||||
(defMacro altDefun [name args &body body]
|
||||
(let [argPairs
|
||||
(groups (expList args) 2)
|
||||
untypedArgs
|
||||
@@ -30,22 +30,22 @@
|
||||
(print name)
|
||||
(letBindings.push `(the ,type ,name)))
|
||||
(print letBindings)
|
||||
`(defun ,name ,untypedArgs
|
||||
`(function ,name ,untypedArgs
|
||||
(let ,letBindings ,@body))))
|
||||
|
||||
(altDefun nameAndNumber [name String number Int]
|
||||
"$name $number")
|
||||
|
||||
// If for whatever reason, you wanted to make a variable called print
|
||||
(undefalias &call print)
|
||||
(defvar print 9)
|
||||
(undefAlias &call print)
|
||||
(var print 9)
|
||||
|
||||
(defalias &ident alias 5)
|
||||
(undefalias &ident alias)
|
||||
(defvar alias 9)
|
||||
(defun aliasValue [] alias)
|
||||
(defAlias &ident alias 5)
|
||||
(undefAlias &ident alias)
|
||||
(var alias 9)
|
||||
(function aliasValue [] alias)
|
||||
|
||||
// If for whatever reason, you wanted to make a function called and
|
||||
(undefmacro and)
|
||||
(defun and [a b] (+ a b))
|
||||
(defun andValue [] (and 5 6))
|
||||
(undefMacro and)
|
||||
(function and [a b] (+ a b))
|
||||
(function andValue [] (and 5 6))
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
(defvar &mut staticCount 0)
|
||||
(defvar &mut instanceCount 0)
|
||||
(var &mut staticCount 0)
|
||||
(var &mut instanceCount 0)
|
||||
|
||||
(defmethod new []
|
||||
(method new []
|
||||
(once
|
||||
(+= staticCount 1))
|
||||
(oncePerInstance
|
||||
(+= instanceCount 1)))
|
||||
(+= instanceCount 1)))
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
(defreadermacro &start "!" [stream]
|
||||
(defReaderMacro &start "!" [stream]
|
||||
(let [line (stream.expect "a string line" (lambda [] (stream.takeLine)))]
|
||||
(ReaderExp.StrExp line)))
|
||||
|
||||
(defun myLine []
|
||||
(function myLine []
|
||||
!String that takes the rest of the line
|
||||
)
|
||||
|
||||
(defun myBool []
|
||||
(function myBool []
|
||||
(begin !false))
|
||||
|
||||
(defalias &call pluppers +)
|
||||
(defalias &ident fluffers 5)
|
||||
(defalias &ident buffers 4)
|
||||
(defAlias &call pluppers +)
|
||||
(defAlias &ident fluffers 5)
|
||||
(defAlias &ident buffers 4)
|
||||
|
||||
(defvar mySum (pluppers fluffers buffers))
|
||||
(var mySum (pluppers fluffers buffers))
|
||||
|
||||
// Read b c directly as strings
|
||||
(defreadermacro ["b" "c"] [stream] #|ReaderExp.StrExp(stream.expect("b, or c", function () stream.takeChars(1)))|#)
|
||||
(defReaderMacro ["b" "c"] [stream] #|ReaderExp.StrExp(stream.expect("b, or c", function () stream.takeChars(1)))|#)
|
||||
|
||||
(defvar str1 b)
|
||||
(defvar str2 c)
|
||||
(var str1 b)
|
||||
(var str2 c)
|
||||
|
||||
// rassert asserts the next expression without parens
|
||||
(defreadermacro "rassert" [stream] `(assert ,(read stream)))
|
||||
(defReaderMacro "rassert" [stream] `(assert ,(read stream)))
|
||||
|
||||
(defun _testQuasiquoteMacro []
|
||||
(function _testQuasiquoteMacro []
|
||||
rassert [5]
|
||||
rassert b
|
||||
rassert fluffers
|
||||
(Assert.pass))
|
||||
(Assert.pass))
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
(defun :Void main []
|
||||
(print "Hello world!"))
|
||||
(function :Void main []
|
||||
(print "Hello world!"))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(load "UtilMacros.kiss")
|
||||
(defun :Void main []
|
||||
(function :Void main []
|
||||
(year 2018
|
||||
(Solutions2018.run))
|
||||
(year 2020
|
||||
(Solutions2020.run)))
|
||||
(Solutions2020.run)))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
(defun readLines [file]
|
||||
(function readLines [file]
|
||||
(.filter
|
||||
(.map
|
||||
// TODO implement escape sequences in kiss string literals
|
||||
@@ -6,7 +6,7 @@
|
||||
StringTools.trim)
|
||||
(lambda [l] (< 0 l.length))))
|
||||
|
||||
(defun readParagraphLines [file]
|
||||
(function readParagraphLines [file]
|
||||
(.filter
|
||||
(for paragraph
|
||||
(.split
|
||||
@@ -18,7 +18,7 @@
|
||||
(lambda [lines] (< 0 lines.length))))
|
||||
|
||||
// TODO won't need to specify type here if last is not a quickNth
|
||||
(defun :kiss.List<Int> readInts [file] (let [lines (readLines file)] (lines.map Std.parseInt)))
|
||||
(function :kiss.List<Int> readInts [file] (let [lines (readLines file)] (lines.map Std.parseInt)))
|
||||
|
||||
(defun countChar [char str]
|
||||
(count (str.split "") (lambda [c] ?(= c char))))
|
||||
(function countChar [char str]
|
||||
(count (str.split "") (lambda [c] ?(= c char))))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(load "../UtilMacros.kiss")
|
||||
|
||||
(defun run []
|
||||
(function run []
|
||||
(day 1
|
||||
(let [inputs
|
||||
(.slice (.split (sys.io.File.getContent "src/year2018/inputs/day1.txt") "\n") 0 -1)
|
||||
@@ -31,4 +31,4 @@
|
||||
(dayTodo 22)
|
||||
(dayTodo 23)
|
||||
(dayTodo 24)
|
||||
(dayTodo 25))
|
||||
(dayTodo 25))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(defun differences [:kiss.List<Int> ratings]
|
||||
(function differences [:kiss.List<Int> ratings]
|
||||
(for pair (pairs ratings) (- 0 (apply - pair))))
|
||||
|
||||
(defun distribution [:kiss.List<Int> numbers]
|
||||
(function distribution [:kiss.List<Int> numbers]
|
||||
(let [:Map<Int,Int> dist (new Map)]
|
||||
(doFor num numbers
|
||||
(dictSet dist num
|
||||
@@ -10,7 +10,7 @@
|
||||
1)))
|
||||
dist))
|
||||
|
||||
(defun &dynamic arrangementCount [:kiss.List<Int> ratings startingIndex]
|
||||
(function &dynamic arrangementCount [:kiss.List<Int> ratings startingIndex]
|
||||
(if (= startingIndex (- ratings.length 1)) 1
|
||||
(let [&mut :Int64 sum 0
|
||||
startingRating (nth ratings startingIndex)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(defun bagColor [:String bag]
|
||||
(function bagColor [:String bag]
|
||||
(bag.substr 0 (Math.floor (- (bag.indexOf "bag") 1))))
|
||||
|
||||
(defun parseRule [:String line :ParentMap parentMap :ChildMap childMap]
|
||||
(function parseRule [:String line :ParentMap parentMap :ChildMap childMap]
|
||||
(unless (<= 0 (line.indexOf "contain no other bags"))
|
||||
(let [[containerStr contents] (line.split "contain ")
|
||||
contentStrs (contents.split ", ")]
|
||||
@@ -15,17 +15,17 @@
|
||||
(.push (dictGet childMap (bagColor colorStr)) (bagColor containerStr))))
|
||||
(dictSet parentMap (bagColor containerStr) innerMap))))
|
||||
|
||||
(defun findIndirectContainers [color :ChildMap childMap :Map<String,Bool> outMap]
|
||||
(function findIndirectContainers [color :ChildMap childMap :Map<String,Bool> outMap]
|
||||
(when (childMap.exists color)
|
||||
(doFor parentColor (dictGet childMap color)
|
||||
(dictSet outMap parentColor true)
|
||||
(findIndirectContainers parentColor childMap outMap))))
|
||||
|
||||
(defun totalChildBags [bag :ParentMap parentMap]
|
||||
(function totalChildBags [bag :ParentMap parentMap]
|
||||
(if (parentMap.exists bag)
|
||||
(begin
|
||||
(localVar &mut sum 0)
|
||||
(doFor =>childColor quantity (dictGet parentMap bag)
|
||||
(set sum (+ sum quantity (* quantity (totalChildBags childColor parentMap)))))
|
||||
sum)
|
||||
0))
|
||||
0))
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
(defprop &mut accumulator 0)
|
||||
(prop &mut accumulator 0)
|
||||
|
||||
(defmethod setBreakPoint [] (addBreakPoint instructionPointer))
|
||||
(method setBreakPoint [] (addBreakPoint instructionPointer))
|
||||
|
||||
(defmethod nop [v :Dynamic self] (self.setBreakPoint))
|
||||
(defmethod acc [v :Dynamic self] (self.setBreakPoint) (set self.accumulator (+ self.accumulator v)))
|
||||
(defmethod jmp [v :Dynamic self]
|
||||
(method nop [v :Dynamic self] (self.setBreakPoint))
|
||||
(method acc [v :Dynamic self] (self.setBreakPoint) (set self.accumulator (+ self.accumulator v)))
|
||||
(method jmp [v :Dynamic self]
|
||||
(self.setBreakPoint)
|
||||
(set self.instructionPointer (+ self.instructionPointer (- v 1))))
|
||||
(set self.instructionPointer (+ self.instructionPointer (- v 1))))
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
(load "BootCodeCommon.kiss")
|
||||
|
||||
(defvar :Map<Int,Bool> instructionsTested (new Map<Int,Bool>))
|
||||
(defprop &mut forked false)
|
||||
(defprop &mut forkedAt -1)
|
||||
(var :Map<Int,Bool> instructionsTested (new Map<Int,Bool>))
|
||||
(prop &mut forked false)
|
||||
(prop &mut forkedAt -1)
|
||||
|
||||
(defreadermacro ["jmp" "nop"] [stream]
|
||||
(let [inst
|
||||
@@ -35,4 +35,4 @@
|
||||
])))))
|
||||
|
||||
// Define the default reader LAST because default readers tend to break everything
|
||||
(load "BootCodeDSL.kiss")
|
||||
(load "BootCodeDSL.kiss")
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
(defun countAnyYes [:Array<String> group]
|
||||
(function countAnyYes [:Array<String> group]
|
||||
(countWhereYes group (lambda [c] (< 0 c))))
|
||||
|
||||
(defun countAllYes [:Array<String> group]
|
||||
(function countAllYes [:Array<String> group]
|
||||
(countWhereYes group (lambda [c] (= c group.length))))
|
||||
|
||||
(defun countWhereYes [:Array<String> group predicate]
|
||||
(function countWhereYes [:Array<String> group predicate]
|
||||
(let [yesDict (new Map<String,Int>)]
|
||||
(doFor person group
|
||||
(doFor question (person.split "")
|
||||
(dictSet yesDict question
|
||||
(+ 1
|
||||
(if (yesDict.exists question) (dictGet yesDict question) 0)))))
|
||||
(count yesDict predicate)))
|
||||
(count yesDict predicate)))
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
(defprop &mut x 0)
|
||||
(defprop &mut y 0)
|
||||
(prop &mut x 0)
|
||||
(prop &mut y 0)
|
||||
// 0 is east
|
||||
// 1 is south
|
||||
// 2 is west
|
||||
// 3 is north
|
||||
(defprop &mut facing 0)
|
||||
(prop &mut facing 0)
|
||||
|
||||
(defun fixFacing [f]
|
||||
(function fixFacing [f]
|
||||
(Math.floor (% (if (> 0 f) (+ 4 f) f) 4)))
|
||||
|
||||
(defmethod N [num]
|
||||
(classMethod N [num]
|
||||
(set y (+ y num)))
|
||||
(defmethod S [num]
|
||||
(classMethod S [num]
|
||||
(set y (- y num)))
|
||||
(defmethod E [num]
|
||||
(classMethod E [num]
|
||||
(set x (+ x num)))
|
||||
(defmethod W [num]
|
||||
(classMethod W [num]
|
||||
(set x (- x num)))
|
||||
(defmethod R [angle]
|
||||
(classMethod R [angle]
|
||||
(set facing (fixFacing (+ facing (/ angle 90)))))
|
||||
(defmethod L [angle]
|
||||
(classMethod L [angle]
|
||||
(set facing (fixFacing (- facing (/ angle 90)))))
|
||||
(defmethod F [num]
|
||||
(classMethod F [num]
|
||||
(case facing
|
||||
(0 (E num))
|
||||
(1 (S num))
|
||||
@@ -35,4 +35,4 @@
|
||||
null
|
||||
`(,(ReaderExp.Symbol
|
||||
(stream.expect "a ship command" (lambda [] (stream.takeChars 1))))
|
||||
,(ReaderExp.Symbol (stream.expect "a number argument" (lambda [] (stream.takeUntilAndDrop #|"\n"|#)))))))
|
||||
,(ReaderExp.Symbol (stream.expect "a number argument" (lambda [] (stream.takeUntilAndDrop #|"\n"|#)))))))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(defun :FerrySquare floor [:Array<FerrySquare> n :SeatsChanged changed] floor)
|
||||
(function :FerrySquare floor [:Array<FerrySquare> n :SeatsChanged changed] floor)
|
||||
|
||||
(defun :FerrySquare emptySeat [:Array<FerrySquare> n :SeatsChanged changed]
|
||||
(function :FerrySquare emptySeat [:Array<FerrySquare> n :SeatsChanged changed]
|
||||
// Empty seats with completely empty neighbors, fill up
|
||||
(cond
|
||||
((= true (apply = (for neighbor n #|neighbor != fullSeat|#)))
|
||||
@@ -8,7 +8,7 @@
|
||||
fullSeat)
|
||||
(true emptySeat)))
|
||||
|
||||
(defun :FerrySquare fullSeat [:Array<FerrySquare> n :SeatsChanged changed]
|
||||
(function :FerrySquare fullSeat [:Array<FerrySquare> n :SeatsChanged changed]
|
||||
// Full seats with 4 or more full neighbors become empty
|
||||
(cond
|
||||
((<= 4 (count n (lambda [neighbor] #|neighbor == fullSeat|#)))
|
||||
@@ -16,7 +16,7 @@
|
||||
emptySeat)
|
||||
(true fullSeat)))
|
||||
|
||||
(defun neighbors [x y :Array<Array<FerrySquare>> grid]
|
||||
(function neighbors [x y :Array<Array<FerrySquare>> grid]
|
||||
(localVar &mut n [])
|
||||
(doFor xx (range (- x 1) (+ x 2))
|
||||
(doFor yy (range (- y 1) (+ y 2))
|
||||
@@ -25,9 +25,9 @@
|
||||
(n.push (nth (nth grid yy) xx))))))
|
||||
n)
|
||||
|
||||
(defprop &mut :Array<Array<FerrySquare>> state [])
|
||||
(prop &mut :Array<Array<FerrySquare>> state [])
|
||||
|
||||
(defmethod simulate []
|
||||
(method simulate []
|
||||
(localVar changed (object changed false))
|
||||
(set state
|
||||
(for rowIdx (range state.length)
|
||||
@@ -35,10 +35,10 @@
|
||||
(for seatIdx (range row.length) ((nth row seatIdx) (neighbors seatIdx rowIdx state) changed)))))
|
||||
changed.changed)
|
||||
|
||||
(defmethod fullSimulate []
|
||||
(method fullSimulate []
|
||||
(when (simulate) (fullSimulate)))
|
||||
|
||||
(defmethod countFullSeats []
|
||||
(method countFullSeats []
|
||||
(apply +
|
||||
(for :Array<FerrySquare> row state
|
||||
(apply +
|
||||
@@ -51,4 +51,4 @@
|
||||
(undefreadermacro "...")
|
||||
|
||||
(defreadermacro &start "" [stream]
|
||||
`(state.push ,(ReaderExp.ListExp (readExpArray stream #|"\n"|#))))
|
||||
`(state.push ,(ReaderExp.ListExp (readExpArray stream #|"\n"|#))))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
(defun readPassport [:Stream stream &opt :Map<String,String> pp]
|
||||
(function readPassport [:Stream stream &opt :Map<String,String> pp]
|
||||
(set pp (or pp (new Map<String,String>)))
|
||||
(when (stream.isEmpty) (return pp))
|
||||
(let [key (stream.expect "passport key" (lambda [] (stream.takeUntilAndDrop ":")))
|
||||
@@ -8,7 +8,7 @@
|
||||
(begin (stream.dropWhitespace) pp)
|
||||
(begin (stream.dropWhitespace) (readPassport stream pp))))
|
||||
|
||||
(defun checkPassport [:Map<String,String> pp strict]
|
||||
(function checkPassport [:Map<String,String> pp strict]
|
||||
(doFor key ["byr" "iyr" "eyr" "hgt" "hcl" "ecl" "pid"]
|
||||
(if !(pp.exists key) (return false)))
|
||||
(when strict
|
||||
@@ -32,8 +32,8 @@
|
||||
(unless (and (= 9 pid.length) (Std.parseInt pid)) (return false))))
|
||||
(return true))
|
||||
|
||||
(defun countValidPassports [:Stream stream &opt strict c]
|
||||
(function countValidPassports [:Stream stream &opt strict c]
|
||||
(unless c (set c 0))
|
||||
(if (stream.isEmpty)
|
||||
c
|
||||
(countValidPassports stream strict (if (checkPassport (readPassport stream) strict) (+ c 1) c))))
|
||||
(countValidPassports stream strict (if (checkPassport (readPassport stream) strict) (+ c 1) c))))
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
|
||||
(defun parsePasswordCheck1 [:String ruleStr]
|
||||
(function parsePasswordCheck1 [:String ruleStr]
|
||||
(let [[min max letter]
|
||||
(.split (ruleStr.replace " " "-") "-")]
|
||||
(lambda [password] (<= (Std.parseInt min) (Util.countChar letter password) (Std.parseInt max)))))
|
||||
|
||||
(defun parsePasswordCheck2 [:String ruleStr]
|
||||
(function parsePasswordCheck2 [:String ruleStr]
|
||||
(let [[a b letter]
|
||||
(.split (ruleStr.replace " " "-") "-")
|
||||
aIdx (- (Std.parseInt a) 1)
|
||||
bIdx (- (Std.parseInt b) 1)]
|
||||
(lambda [password] (= 1 (Util.countChar letter (+ (.charAt password aIdx) (.charAt password bIdx)))))))
|
||||
|
||||
(defun validateInputLine [:String line ruleParser]
|
||||
(function validateInputLine [:String line ruleParser]
|
||||
(let [[rule password]
|
||||
(line.split ": ")]
|
||||
((ruleParser rule) password)))
|
||||
((ruleParser rule) password)))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Airplane seating
|
||||
|
||||
(defun search [:Array<String> letters min max rowOrColumn]
|
||||
(function search [:Array<String> letters min max rowOrColumn]
|
||||
(if (= min max)
|
||||
min
|
||||
(let [middle (Math.floor (/ (+ min max) 2))]
|
||||
@@ -11,7 +11,7 @@
|
||||
(["R" "column"] (search letters (+ 1 middle) max rowOrColumn))
|
||||
(otherwise (throw "invalid search call"))))))
|
||||
|
||||
(defun seatId [:String boardingPass]
|
||||
(function seatId [:String boardingPass]
|
||||
(+
|
||||
(* 8 (search (.split (boardingPass.substr 0 7) "") 0 127 "row"))
|
||||
(search (.split (boardingPass.substr 7) "") 0 7 "column")))
|
||||
(search (.split (boardingPass.substr 7) "") 0 7 "column")))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(load "../UtilMacros.kiss")
|
||||
|
||||
(defun run []
|
||||
(function run []
|
||||
(day 1
|
||||
(let [p (SummingTuples.pairWithSum 2020 [1721 979 366 299 675 1456])]
|
||||
(assert (and (has p 1721) (has p 299)) "pairWithSum is broken"))
|
||||
@@ -156,4 +156,4 @@
|
||||
(dayTodo 22)
|
||||
(dayTodo 23)
|
||||
(dayTodo 24)
|
||||
(dayTodo 25))
|
||||
(dayTodo 25))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
(defun :kiss.List<Int> pairWithSum [sum :kiss.List<Int> numbers]
|
||||
(function :kiss.List<Int> pairWithSum [sum :kiss.List<Int> numbers]
|
||||
// Put the numbers in a map for random access. This gives an O(n) solution
|
||||
(localVar :Map<Int,Int> numbersMap (new Map))
|
||||
(doFor number numbers
|
||||
@@ -8,7 +8,7 @@
|
||||
(return [number requiredForPair]))))
|
||||
null)
|
||||
|
||||
(defun :kiss.List<Int> trioWithSum [sum :kiss.List<Int> numbers]
|
||||
(function :kiss.List<Int> trioWithSum [sum :kiss.List<Int> numbers]
|
||||
(doFor number numbers
|
||||
(let [requiredForTrio (- sum number)
|
||||
pairThatSatisfies (pairWithSum requiredForTrio numbers)]
|
||||
@@ -16,7 +16,7 @@
|
||||
(return [number (nth pairThatSatisfies 0) (nth pairThatSatisfies 1)]))))
|
||||
null)
|
||||
|
||||
(defun contiguousSumTuple [sum :kiss.List<Int> numbers]
|
||||
(function contiguousSumTuple [sum :kiss.List<Int> numbers]
|
||||
(doFor i (range numbers.length)
|
||||
(localVar &mut testSum (nth numbers i))
|
||||
(doFor j (range (+ i 1) numbers.length)
|
||||
@@ -26,4 +26,4 @@
|
||||
(return (numbers.slice i (+ j 1))))
|
||||
((> testSum sum)
|
||||
(break)))))
|
||||
null)
|
||||
null)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
(defun path [:kiss.List<String> hillTile x0 y0 dx dy]
|
||||
(function path [:kiss.List<String> hillTile x0 y0 dx dy]
|
||||
(if (>= y0 .length hillTile)
|
||||
[]
|
||||
(concat [(.charAt (nth hillTile y0) (Math.floor (% x0 .length (nth hillTile y0))))] (path hillTile (+ x0 dx) (+ y0 dy) dx dy))))
|
||||
|
||||
(defun pathString [:kiss.List<String> hillTile x0 y0 dx dy] (.join (path hillTile x0 y0 dx dy) ""))
|
||||
(function pathString [:kiss.List<String> hillTile x0 y0 dx dy] (.join (path hillTile x0 y0 dx dy) ""))
|
||||
|
||||
(defun pathTrees [:kiss.List<String> hillTile x0 y0 dx dy] (Util.countChar "#" (pathString hillTile x0 y0 dx dy)))
|
||||
(function pathTrees [:kiss.List<String> hillTile x0 y0 dx dy] (Util.countChar "#" (pathString hillTile x0 y0 dx dy)))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
(defun firstOffender [preambleLength :kiss.List<Int> input]
|
||||
(function firstOffender [preambleLength :kiss.List<Int> input]
|
||||
(doFor idx (range preambleLength input.length)
|
||||
(unless (SummingTuples.pairWithSum (nth input idx) (input.slice (- idx preambleLength) idx))
|
||||
(return (nth input idx))))
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
(defun :Void main []
|
||||
(print "Hello world!"))
|
||||
(function :Void main []
|
||||
(print "Hello world!"))
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
[:Map<String,Surface> _surfaces (new Map)])
|
||||
|
||||
// TODO don't allow overriding a key -- use a macro so all load___() calls check their maps first
|
||||
(defmethod loadSurface [key path]
|
||||
(method loadSurface [key path]
|
||||
(dictSet _surfaces key (Surface.fromString (backend.loadText path))))
|
||||
|
||||
// TODO runtime-assert that the key exists. Use a macro so all get___() calls check their maps first
|
||||
(defmethod getSurface [key]
|
||||
(method getSurface [key]
|
||||
(dictGet _surfaces key))
|
||||
|
||||
// TODO freeSurface() etc.
|
||||
// TODO freeSurface() etc.
|
||||
|
||||
@@ -8,33 +8,33 @@
|
||||
|
||||
(fill (or fillColor Black)))
|
||||
|
||||
(defmethod fill [:Color color]
|
||||
(method fill [:Color color]
|
||||
(red.fill 0 area color.r)
|
||||
(green.fill 0 area color.g)
|
||||
(blue.fill 0 area color.b))
|
||||
|
||||
(defmethod _index [x y]
|
||||
(method _index [x y]
|
||||
(+ x (* y width)))
|
||||
|
||||
(defmacro withIndex [idxName xName yName &body body]
|
||||
`(let [,idxName (_index ,xName ,yName)]
|
||||
,@body))
|
||||
|
||||
(defmethod getPixel [x y]
|
||||
(method getPixel [x y]
|
||||
(withIndex idx x y
|
||||
(object r (red.get idx) g (green.get idx) b (blue.get idx))))
|
||||
|
||||
(defmethod setPixel [x y color]
|
||||
(method setPixel [x y color]
|
||||
(withIndex idx x y
|
||||
(red.set idx color.r)
|
||||
(green.set idx color.g)
|
||||
(blue.set idx color.b)))
|
||||
|
||||
(defun equal [c1 c2]
|
||||
(function equal [c1 c2]
|
||||
(and (= c1.r c2.r) (= c1.g c2.g) (= c1.b c2.b)))
|
||||
|
||||
(defvar Black (object r 0 g 0 b 0))
|
||||
(defvar Red (object r 255 g 0 b 0))
|
||||
(defvar Green (object r 0 g 255 b 0))
|
||||
(defvar Blue (object r 0 g 0 b 255))
|
||||
(defvar White (object r 255 g 255 b 255))
|
||||
(var Black (object r 0 g 0 b 0))
|
||||
(var Red (object r 255 g 0 b 0))
|
||||
(var Green (object r 0 g 255 b 0))
|
||||
(var Blue (object r 0 g 0 b 255))
|
||||
(var White (object r 255 g 255 b 255))
|
||||
|
||||
@@ -16,10 +16,10 @@
|
||||
(graphicsBackend.initialize title width height letterWidth letterHeight)
|
||||
(gameLogic.initialize assets))
|
||||
|
||||
(defmethod update [:Float deltaSeconds]
|
||||
(method update [:Float deltaSeconds]
|
||||
(gameLogic.update this deltaSeconds))
|
||||
|
||||
(defmethod draw []
|
||||
(method draw []
|
||||
(let [&mut changedGraphics false]
|
||||
(gameLogic.draw (lambda [] (set changedGraphics true) graphics) assets)
|
||||
(when changedGraphics (graphicsBackend.draw graphics))))
|
||||
(when changedGraphics (graphicsBackend.draw graphics))))
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
(defmethod new [width height]
|
||||
(super width height))
|
||||
(method new [width height]
|
||||
(super width height))
|
||||
|
||||
@@ -3,5 +3,5 @@
|
||||
:Int height _height
|
||||
:Array<Array<T>> rows (for _ (range height) (for _ (range width) defaultValue))])
|
||||
|
||||
(defmethod getCell [x y] (nth (nth rows y) x))
|
||||
(defmethod setCell [x y value] (setNth (nth rows y) x value))
|
||||
(method getCell [x y] (nth (nth rows y) x))
|
||||
(method setCell [x y value] (setNth (nth rows y) x value))
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
:Int height _height
|
||||
:Array<String> rows (for _ (range height) (* (or letter " ") width))])
|
||||
|
||||
(defmethod getChar [x y]
|
||||
(method getChar [x y]
|
||||
(.charAt (nth rows y) x))
|
||||
|
||||
(defmethod setChar [x y char]
|
||||
(method setChar [x y char]
|
||||
(let [row (nth rows y)
|
||||
left (row.substr 0 x)
|
||||
right (row.substr (+ x 1))]
|
||||
(setNth rows y "${left}${char}${right}")))
|
||||
(setNth rows y "${left}${char}${right}")))
|
||||
|
||||
@@ -7,34 +7,34 @@
|
||||
:Grid<Bool> opacity (new Grid width height true)
|
||||
:Grid<String> specialInfo (new Grid width height "")])
|
||||
|
||||
(defmethod getBackgroundColor [x y]
|
||||
(method getBackgroundColor [x y]
|
||||
(backgroundColors.getPixel x y))
|
||||
|
||||
(defmethod setBackgroundColor [x y color]
|
||||
(method setBackgroundColor [x y color]
|
||||
(backgroundColors.setPixel x y color))
|
||||
|
||||
(defmethod getLetter [x y]
|
||||
(method getLetter [x y]
|
||||
(object char (letters.getChar x y) color (letterColors.getPixel x y)))
|
||||
|
||||
(defmethod setLetter [x y letter]
|
||||
(method setLetter [x y letter]
|
||||
(letters.setChar x y letter.char)
|
||||
(letterColors.setPixel x y letter.color))
|
||||
|
||||
(defmethod isCellOpaque [x y]
|
||||
(method isCellOpaque [x y]
|
||||
(opacity.getCell x y))
|
||||
|
||||
(defmethod setCellOpacity [x y value]
|
||||
(method setCellOpacity [x y value]
|
||||
(opacity.setCell x y value))
|
||||
|
||||
(defmethod getSpecialInfo [x y]
|
||||
(method getSpecialInfo [x y]
|
||||
(specialInfo.getCell x y))
|
||||
|
||||
(defmethod setSpecialInfo [x y value]
|
||||
(method setSpecialInfo [x y value]
|
||||
(specialInfo.setCell x y value))
|
||||
|
||||
// TODO rectangle type
|
||||
// TODO optional source rectangle argument
|
||||
(defmethod blitSurface [:Surface surface x y]
|
||||
(method blitSurface [:Surface surface x y]
|
||||
(doFor [srcX destX] (the kiss.List<kiss.List<Int>> (zipDrop (range surface.width) (range x (+ x surface.width))))
|
||||
(when (< -1 destX width)
|
||||
(doFor [srcY destY] (the kiss.List<kiss.List<Int>> (zipDrop (range 0 surface.height) (range y (+ y surface.height))))
|
||||
@@ -46,7 +46,7 @@
|
||||
// Cover transparent cells in the lower surface with opaque ones
|
||||
(setCellOpacity destX destY true)))))))
|
||||
|
||||
(defun fromString [text]
|
||||
(function fromString [text]
|
||||
(let [stream (Stream.fromString text)
|
||||
:Map<String,Color> colors (new Map)
|
||||
:Map<String,String> infoCodes (new Map)
|
||||
@@ -95,4 +95,4 @@
|
||||
(doFor x (range width)
|
||||
(surface.specialInfo.setCell x y (dictGet infoCodes (stream.expect "a special info code" ->{(stream.takeChars 1)}))))
|
||||
(stream.dropString "\n"))
|
||||
surface)))))
|
||||
surface)))))
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
(defnew [])
|
||||
|
||||
(defmethod loadText [filePath] (Assets.getText filePath))
|
||||
(method loadText [filePath] (Assets.getText filePath))
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
(defprop &mut :FlxGroup backgroundColors null)
|
||||
(defprop &mut :FlxGroup letters null)
|
||||
(defprop &mut :Int letterWidth 0)
|
||||
(defprop &mut :Int letterHeight 0)
|
||||
(defprop &mut :FlxBitmapFont font null)
|
||||
(prop &mut :FlxGroup backgroundColors null)
|
||||
(prop &mut :FlxGroup letters null)
|
||||
(prop &mut :Int letterWidth 0)
|
||||
(prop &mut :Int letterHeight 0)
|
||||
(prop &mut :FlxBitmapFont font null)
|
||||
|
||||
(defnew [_state
|
||||
_fontAsset
|
||||
@@ -13,14 +13,14 @@
|
||||
:FlxRect region _region
|
||||
:FlxPoint spacing _spacing])
|
||||
|
||||
(defmethod :Void initialize [:String title :Int width :Int height :Int _letterWidth :Int _letterHeight]
|
||||
(method :Void initialize [:String title :Int width :Int height :Int _letterWidth :Int _letterHeight]
|
||||
(set letterWidth _letterWidth)
|
||||
(set letterHeight _letterHeight)
|
||||
(set font (FlxBitmapFont.fromMonospace fontAsset fontLetters (new FlxPoint letterWidth letterHeight) region spacing))
|
||||
(set backgroundColors (new FlxGroup))
|
||||
(set letters (new FlxGroup)))
|
||||
|
||||
(defmethod :Void draw [:Graphics graphics]
|
||||
(method :Void draw [:Graphics graphics]
|
||||
(backgroundColors.kill)
|
||||
(set backgroundColors (new FlxGroup))
|
||||
(letters.kill)
|
||||
@@ -42,4 +42,4 @@
|
||||
(set text.textColor (FlxColor.fromRGB color.r color.g color.b))
|
||||
(letters.add text))))))
|
||||
(state.add backgroundColors)
|
||||
(state.add letters))
|
||||
(state.add letters))
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
(defnew [])
|
||||
|
||||
(defmethod loadText [filePath] (File.getContent filePath))
|
||||
(method loadText [filePath] (File.getContent filePath))
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
(defprop &mut :Int letterWidth 0)
|
||||
(defprop &mut :Int letterHeight 0)
|
||||
(defprop &mut :Int drawCalled 0)
|
||||
(prop &mut :Int letterWidth 0)
|
||||
(prop &mut :Int letterHeight 0)
|
||||
(prop &mut :Int drawCalled 0)
|
||||
|
||||
(defnew [])
|
||||
|
||||
(defmethod :Void initialize [:String title :Int width :Int height :Int _letterWidth :Int _letterHeight]
|
||||
(method :Void initialize [:String title :Int width :Int height :Int _letterWidth :Int _letterHeight]
|
||||
(set letterWidth _letterWidth)
|
||||
(set letterHeight _letterHeight))
|
||||
|
||||
(defmethod :Void draw [:Graphics graphics]
|
||||
(+= drawCalled 1))
|
||||
(method :Void draw [:Graphics graphics]
|
||||
(+= drawCalled 1))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
(defun :Void main []
|
||||
(function :Void main []
|
||||
(let [[jsonFile workingDir]
|
||||
(Sys.args)
|
||||
json
|
||||
@@ -13,4 +13,4 @@
|
||||
(versionParts.join ".")]
|
||||
(print "Bumping version of $jsonFile from $oldVersion -> $newVersion")
|
||||
(set json.version newVersion)
|
||||
(File.saveContent (joinPath workingDir jsonFile) (Json.stringify json "\t")))))
|
||||
(File.saveContent (joinPath workingDir jsonFile) (Json.stringify json "\t")))))
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
(defnew [])
|
||||
|
||||
(defmethod :Void initialize [:Assets assets]
|
||||
(method :Void initialize [:Assets assets]
|
||||
(assets.loadSurface "laptop" AssetPaths.laptop__srf))
|
||||
(defmethod :Void update [:Game game :Float deltaSeconds] 0)
|
||||
(defmethod :Void draw [:Void->Graphics graphics :Assets assets]
|
||||
(method :Void update [:Game game :Float deltaSeconds] 0)
|
||||
(method :Void draw [:Void->Graphics graphics :Assets assets]
|
||||
(oncePerInstance
|
||||
(.blitSurface (graphics) (assets.getSurface "laptop") 0 0)))
|
||||
(.blitSurface (graphics) (assets.getSurface "laptop") 0 0)))
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
(defmethod new [:Float x :Float y]
|
||||
(method new [:Float x :Float y]
|
||||
(super x y)
|
||||
(loadGraphic AssetPaths.coin__png false 8 8))
|
||||
|
||||
(defmethod &override :Void kill []
|
||||
(method &override :Void kill []
|
||||
(set alive false)
|
||||
(FlxTween.tween
|
||||
this
|
||||
@@ -14,5 +14,5 @@
|
||||
ease FlxEase.circOut
|
||||
onComplete finishKill)))
|
||||
|
||||
(defmethod finishKill [_]
|
||||
(set exists false))
|
||||
(method finishKill [_]
|
||||
(set exists false))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
(defvar &inline :Float SPEED 140)
|
||||
(var &inline :Float SPEED 140)
|
||||
|
||||
(defnew [:Float x :Float y :EnemyType _type]
|
||||
[:EnemyType type _type
|
||||
@@ -29,7 +29,7 @@
|
||||
(set offset.x 4)
|
||||
(set offset.y 2))
|
||||
|
||||
(defmethod &override :Void update [:Float elapsed]
|
||||
(method &override :Void update [:Float elapsed]
|
||||
(when (and
|
||||
(or !(= velocity.x 0) !(= velocity.y 0))
|
||||
(= touching FlxObject.NONE))
|
||||
@@ -54,7 +54,7 @@
|
||||
(brain.update elapsed)
|
||||
(super.update elapsed))
|
||||
|
||||
(defmethod :Void idle [:Float elapsed]
|
||||
(method :Void idle [:Float elapsed]
|
||||
(cond
|
||||
(seesPlayer
|
||||
// TODO (the FSM) here should not be necessary!
|
||||
@@ -74,7 +74,7 @@
|
||||
(true
|
||||
(-= idleTimer elapsed))))
|
||||
|
||||
(defmethod :Void chase [:Float elapsed]
|
||||
(method :Void chase [:Float elapsed]
|
||||
(if !seesPlayer
|
||||
(set brain.activeState idle)
|
||||
(FlxVelocity.moveTowardsPoint this playerPosition (Std.int SPEED))))
|
||||
(FlxVelocity.moveTowardsPoint this playerPosition (Std.int SPEED))))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(defprop &mut :Float->Void activeState null)
|
||||
(prop &mut :Float->Void activeState null)
|
||||
|
||||
(defmethod new [:Float->Void initialState]
|
||||
(method new [:Float->Void initialState]
|
||||
(set activeState initialState))
|
||||
|
||||
(defmethod :Void update [:Float elapsed]
|
||||
(activeState elapsed))
|
||||
(method :Void update [:Float elapsed]
|
||||
(activeState elapsed))
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
(defmethod new []
|
||||
(method new []
|
||||
(super)
|
||||
(addChild (new FlxGame 320 240 MenuState)))
|
||||
(addChild (new FlxGame 320 240 MenuState)))
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
(defprop &mut :FlxButton playButton null)
|
||||
(prop &mut :FlxButton playButton null)
|
||||
|
||||
(defmethod &override :Void create []
|
||||
(method &override :Void create []
|
||||
(set playButton (new FlxButton 0 0 "Play" clickPlay))
|
||||
(playButton.screenCenter)
|
||||
(add playButton))
|
||||
|
||||
(defun clickPlay []
|
||||
(FlxG.switchState (new PlayState)))
|
||||
(function clickPlay []
|
||||
(FlxG.switchState (new PlayState)))
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
(defprop &mut :Player player null)
|
||||
(defprop &mut :FlxOgmo3Loader map null)
|
||||
(defprop &mut :FlxTilemap walls null)
|
||||
(defprop &mut :FlxTypedGroup<Coin> coins null)
|
||||
(defprop &mut :FlxTypedGroup<Enemy> enemies null)
|
||||
(prop &mut :Player player null)
|
||||
(prop &mut :FlxOgmo3Loader map null)
|
||||
(prop &mut :FlxTilemap walls null)
|
||||
(prop &mut :FlxTypedGroup<Coin> coins null)
|
||||
(prop &mut :FlxTypedGroup<Enemy> enemies null)
|
||||
|
||||
(defmethod &override :Void create []
|
||||
(method &override :Void create []
|
||||
(set map (new FlxOgmo3Loader AssetPaths.turnBasedRPG__ogmo AssetPaths.room_001__json))
|
||||
(set walls (map.loadTilemap AssetPaths.tiles__png "walls"))
|
||||
(walls.follow)
|
||||
@@ -19,7 +19,7 @@
|
||||
(FlxG.camera.follow player TOPDOWN 1)
|
||||
(super.create))
|
||||
|
||||
(defmethod :Void placeEntities [:EntityData entity]
|
||||
(method :Void placeEntities [:EntityData entity]
|
||||
(case entity.name
|
||||
("player"
|
||||
(set player (new Player entity.x entity.y))
|
||||
@@ -31,14 +31,14 @@
|
||||
("boss"
|
||||
(enemies.add (new Enemy (+ entity.x 4) entity.y BOSS)))))
|
||||
|
||||
(defmethod &override :Void update [:Float elapsed]
|
||||
(method &override :Void update [:Float elapsed]
|
||||
(super.update elapsed)
|
||||
(FlxG.collide player walls)
|
||||
(FlxG.overlap player coins playerTouchCoin)
|
||||
(FlxG.collide enemies walls)
|
||||
(enemies.forEachAlive checkEnemyVision))
|
||||
|
||||
(defmethod :Void checkEnemyVision [:Enemy enemy]
|
||||
(method :Void checkEnemyVision [:Enemy enemy]
|
||||
(if (walls.ray (enemy.getMidpoint) (player.getMidpoint))
|
||||
{
|
||||
(set enemy.seesPlayer true)
|
||||
@@ -46,6 +46,6 @@
|
||||
}
|
||||
(set enemy.seesPlayer false)))
|
||||
|
||||
(defmethod playerTouchCoin [:Player player :Coin coin]
|
||||
(method playerTouchCoin [:Player player :Coin coin]
|
||||
(when (and player.alive player.exists coin.alive coin.exists)
|
||||
(coin.kill)))
|
||||
(coin.kill)))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(defvar &inline :Float SPEED 200)
|
||||
(var &inline :Float SPEED 200)
|
||||
|
||||
(defmethod new [:Float x :Float y]
|
||||
(method new [:Float x :Float y]
|
||||
(super x y)
|
||||
(loadGraphic AssetPaths.player__png true 16 16)
|
||||
(setFacingFlip FlxObject.LEFT false false)
|
||||
@@ -12,7 +12,7 @@
|
||||
(setSize 8 8)
|
||||
(offset.set 4 4))
|
||||
|
||||
(defmethod :Void updateMovement []
|
||||
(method :Void updateMovement []
|
||||
(let [[&mut up &mut down &mut left &mut right]
|
||||
(map [[UP W] [DOWN S] [LEFT A] [RIGHT D]] FlxG.keys.anyPressed)]
|
||||
(when (and up down)
|
||||
@@ -62,6 +62,6 @@
|
||||
(otherwise
|
||||
(return))))))
|
||||
|
||||
(defmethod &override update [:Float elapsed]
|
||||
(method &override update [:Float elapsed]
|
||||
(updateMovement)
|
||||
(super.update elapsed))
|
||||
(super.update elapsed))
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
/**
|
||||
* Helper functions
|
||||
*/
|
||||
(defun selectedText []
|
||||
(function selectedText []
|
||||
(if (and activeTextEditor .selection activeTextEditor)
|
||||
(let [document
|
||||
// TODO should be able to use activeTextEditor.document and have the alias still work
|
||||
@@ -35,12 +35,12 @@
|
||||
|
||||
// TODO make an async annotation that throws an error if the promise is not wrapped in awaitLet or awaitBegin or returned by an async function?
|
||||
// but in some cases it doesn't matter and there are so many edge cases.
|
||||
(defun insertAt [:vscode.Position pos text]
|
||||
(function insertAt [:vscode.Position pos text]
|
||||
(.edit activeTextEditor
|
||||
(lambda [e]
|
||||
(e.insert pos text))))
|
||||
|
||||
(defun insert [text]
|
||||
(function insert [text]
|
||||
// TODO this let is because identifier alias dot access is broken:
|
||||
(let [editor activeTextEditor]
|
||||
(insertAt editor.selection.active text)))
|
||||
@@ -49,18 +49,18 @@
|
||||
* State
|
||||
*/
|
||||
|
||||
(defvar :Map<String,Command> commands (new Map))
|
||||
(defvar :Map<String,ShortcutKey> commandShortcuts (new Map))
|
||||
(var :Map<String,Command> commands (new Map))
|
||||
(var :Map<String,ShortcutKey> commandShortcuts (new Map))
|
||||
|
||||
(defvar &mut :String lastCommand null)
|
||||
(defvar parser (new Parser))
|
||||
(defvar interp (new Interp))
|
||||
(var &mut :String lastCommand null)
|
||||
(var parser (new Parser))
|
||||
(var interp (new Interp))
|
||||
|
||||
/**
|
||||
* Functionality
|
||||
*/
|
||||
|
||||
(defun :Dynamic evalString [:String kissStr]
|
||||
(function :Dynamic evalString [:String kissStr]
|
||||
(try
|
||||
(interp.execute
|
||||
(parser.parseString
|
||||
@@ -69,16 +69,16 @@
|
||||
(errorMessage "Error `${e}` from $kissStr")
|
||||
null)))
|
||||
|
||||
(defun :Void evalAndPrint [&opt :String selectedText]
|
||||
(function :Void evalAndPrint [&opt :String selectedText]
|
||||
(if selectedText
|
||||
(infoMessage (Std.string (evalString selectedText))))
|
||||
|
||||
(awaitLet [kissStr (inputBox)]
|
||||
(infoMessage (Std.string (evalString kissStr)))))
|
||||
|
||||
(defun :Void runCommand [&opt command] (_runCommand command))
|
||||
(function :Void runCommand [&opt command] (_runCommand command))
|
||||
|
||||
(defun :Void _runCommand [&opt command inputText]
|
||||
(function :Void _runCommand [&opt command inputText]
|
||||
(unless inputText (set inputText (selectedText)))
|
||||
(if command
|
||||
{(set lastCommand command) ((dictGet commands command) inputText)}
|
||||
@@ -95,13 +95,13 @@
|
||||
(set lastCommand chosenCommand.label)
|
||||
((dictGet commands chosenCommand.label) inputText))))))
|
||||
|
||||
(defun :Void runLastCommand [&opt _]
|
||||
(function :Void runLastCommand [&opt _]
|
||||
(if lastCommand
|
||||
(runCommand lastCommand)
|
||||
(errorMessage "No Kiss command was run previously.")))
|
||||
|
||||
(defvar &mut :vscode.WebviewPanel shortcutPanel null)
|
||||
(defun :Void showShortcutPanel [&opt :Map<String,ShortcutKey> prefixMap]
|
||||
(var &mut :vscode.WebviewPanel shortcutPanel null)
|
||||
(function :Void showShortcutPanel [&opt :Map<String,ShortcutKey> prefixMap]
|
||||
// Preserve the selected text and focused document before opening the webview:
|
||||
(let [inputText (selectedText)]
|
||||
// When called without a prefixMap, if a shortcut panel is still open, close it and start over:
|
||||
@@ -133,7 +133,7 @@
|
||||
{(warningMessage "$key is not mapped to a shortcut in this context")(return)}))))
|
||||
(set shortcutPanel.webview.html (shortcutPanelHtml prefixMap))))
|
||||
|
||||
(defun shortcutPanelHtml [:Map<String,ShortcutKey> prefixMap]
|
||||
(function shortcutPanelHtml [:Map<String,ShortcutKey> prefixMap]
|
||||
(let [shortcutParagraphs
|
||||
(for =>key shortcutKey prefixMap
|
||||
"<p><strong>${key}</strong> - $(case shortcutKey
|
||||
@@ -159,11 +159,11 @@
|
||||
</body>
|
||||
</html>"))
|
||||
|
||||
(defun :Void runKeyboardShortcut [&opt _]
|
||||
(function :Void runKeyboardShortcut [&opt _]
|
||||
(showShortcutPanel))
|
||||
|
||||
// Extract [k]eyboard [s]hortcuts from a string:
|
||||
(defun extractKeyboardShortcuts [str &opt :Stream stream :String shortcuts]
|
||||
(function extractKeyboardShortcuts [str &opt :Stream stream :String shortcuts]
|
||||
(unless stream (set stream (Stream.fromString str)))
|
||||
(unless shortcuts (set shortcuts ""))
|
||||
(case (stream.takeUntilAndDrop "[")
|
||||
@@ -177,7 +177,7 @@
|
||||
(None
|
||||
shortcuts)))
|
||||
|
||||
(defun :Void registerShortcut [keys description &opt :Map<String,ShortcutKey> prefixMap]
|
||||
(function :Void registerShortcut [keys description &opt :Map<String,ShortcutKey> prefixMap]
|
||||
(unless prefixMap (set prefixMap commandShortcuts))
|
||||
(let [firstKey (keys.shift)]
|
||||
(cond
|
||||
@@ -199,16 +199,16 @@
|
||||
(registerShortcut keys description innerPrefixMap))
|
||||
(dictSet prefixMap firstKey (Final description)))))))
|
||||
|
||||
(defun registerCommand [description command]
|
||||
(function registerCommand [description command]
|
||||
(dictSet commands description command)
|
||||
(whenLet [keyboardShortcut (extractKeyboardShortcuts description)]
|
||||
(registerShortcut (keyboardShortcut.split "") description)))
|
||||
|
||||
// Register a VSCode command (built-in, or from an extension)
|
||||
(defun registerExistingCommand [description command]
|
||||
(function registerExistingCommand [description command]
|
||||
(registerCommand description (lambda :Void [&opt _] (executeCommand command))))
|
||||
|
||||
(defun :Void registerBuiltins []
|
||||
(function :Void registerBuiltins []
|
||||
(set Prelude.print
|
||||
->[v] {
|
||||
(infoMessage (Std.string v))
|
||||
@@ -220,7 +220,7 @@
|
||||
(registerCommand "[n]ew kiss class" newKissClass))
|
||||
|
||||
// TODO standardize this with KissInterp
|
||||
(defun :Void prepareInterp []
|
||||
(function :Void prepareInterp []
|
||||
(interp.variables.set "kiss"
|
||||
(object
|
||||
Prelude
|
||||
@@ -244,7 +244,7 @@
|
||||
(awaitLet [,v (inputBox)]
|
||||
,@body)))
|
||||
|
||||
(defun :Void newKissClass [&opt _]
|
||||
(function :Void newKissClass [&opt _]
|
||||
(awaitLet [className (inputBox)]
|
||||
(let [currentFile
|
||||
.fileName .document activeTextEditor
|
||||
@@ -275,4 +275,4 @@ import kiss.List;
|
||||
class ${className} {}
|
||||
")
|
||||
(File.saveContent kissFile "")
|
||||
(Vscode.window.showTextDocument (Uri.file kissFile)))))
|
||||
(Vscode.window.showTextDocument (Uri.file kissFile)))))
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
(defun init []
|
||||
(return))
|
||||
(function init []
|
||||
(return))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(defun :Void init []
|
||||
(function :Void init []
|
||||
(registerCommand "print a nice message"
|
||||
(lambda :Void [&opt selectedText]
|
||||
(infoMessage "Hello world!")
|
||||
(when selectedText
|
||||
(infoMessage (+ "Also, " selectedText))))))
|
||||
(infoMessage (+ "Also, " selectedText))))))
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
(defun userHome [] (or (Sys.getEnv "MSYSHOME") (Sys.getEnv "HOME") (Sys.getEnv "UserProfile")))
|
||||
(defun userConfigDir []
|
||||
(function userHome [] (or (Sys.getEnv "MSYSHOME") (Sys.getEnv "HOME") (Sys.getEnv "UserProfile")))
|
||||
(function userConfigDir []
|
||||
(joinPath
|
||||
(userHome)
|
||||
".kiss"))
|
||||
|
||||
(defvar &mut activeConfigDir "")
|
||||
(defvar &mut lastConfigDir "")
|
||||
(defvar &mut builtinConfigDir "")
|
||||
(defvar &mut :KissConfig config null)
|
||||
(var &mut activeConfigDir "")
|
||||
(var &mut lastConfigDir "")
|
||||
(var &mut builtinConfigDir "")
|
||||
(var &mut :KissConfig config null)
|
||||
|
||||
(defun walkDirectory [basePath directory :String->Void processFile :String->Void processSubdirectory]
|
||||
(function walkDirectory [basePath directory :String->Void processFile :String->Void processSubdirectory]
|
||||
(doFor fileOrFolder (FileSystem.readDirectory (joinPath basePath directory))
|
||||
(case fileOrFolder
|
||||
((when (FileSystem.isDirectory (joinPath basePath directory folder)) folder)
|
||||
@@ -19,7 +19,7 @@
|
||||
(file
|
||||
(processFile (joinPath directory file))))))
|
||||
|
||||
(defun :Void tryLoadConfig [&opt :String text]
|
||||
(function :Void tryLoadConfig [&opt :String text]
|
||||
// TODO if a config object is active and a shortcut panel is open, dispose the panel before we lose the handle in the current config object
|
||||
|
||||
// If a backup exists, delete it
|
||||
@@ -97,7 +97,7 @@
|
||||
(Vscode.window.showErrorMessage errorMessage))))))))
|
||||
|
||||
(#unless test
|
||||
(defun _activate [:ExtensionContext context]
|
||||
(function _activate [:ExtensionContext context]
|
||||
(context.subscriptions.push
|
||||
(Vscode.commands.registerCommand
|
||||
"kiss.reloadConfig"
|
||||
@@ -134,7 +134,7 @@
|
||||
(set lastConfigDir (joinPath (userHome) ".kiss-vscode" "lastActiveConfig"))
|
||||
(tryLoadConfig)))
|
||||
|
||||
(defun :Void main []
|
||||
(function :Void main []
|
||||
(#when test
|
||||
(set builtinConfigDir "config")
|
||||
(set activeConfigDir "_activeConfig")
|
||||
@@ -142,4 +142,4 @@
|
||||
(tryLoadConfig)
|
||||
// Load the config twice more to make sure it moves the last active config out of the way properly:
|
||||
(tryLoadConfig)
|
||||
(tryLoadConfig)))
|
||||
(tryLoadConfig)))
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
</dict>
|
||||
</dict>
|
||||
<key>match</key>
|
||||
<string>(?:\()((?i:defmacro|defun|classFunction|classMethod|def[A-Z]\S+))\s+((?:\w|[+\-<>/*&=.?!$%:@\[\]^{}~#|])+)</string>
|
||||
<string>(?:\()((?i:defmacro|defMacro|defun|function|defmethod|method|def[A-Z]\S+))\s+((?:\w|[+\-<>/*&=.?!$%:@\[\]^{}~#|])+)</string>
|
||||
<key>name</key>
|
||||
<string>meta.function.kiss</string>
|
||||
</dict>
|
||||
@@ -57,23 +57,6 @@
|
||||
<key>name</key>
|
||||
<string>meta.function-parameters.kiss</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
<key>1</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>storage.type.function-type.kiss</string>
|
||||
</dict>
|
||||
<key>2</key>
|
||||
<dict>
|
||||
<key>name</key>
|
||||
<string>entity.name.type.kiss</string>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>match</key>
|
||||
<string>(?:\()((?i:deftype|defstruct))\s+((?:\w|[+\-<>/*&=.?!$%:@\[\]^{}~#|])+)</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>captures</key>
|
||||
<dict>
|
||||
@@ -89,7 +72,7 @@
|
||||
</dict>
|
||||
</dict>
|
||||
<key>match</key>
|
||||
<string>(?:\()((?i:defvar|defprop|classVar|classProp))\s+((?:\w|[+\-<>/*&=.?!$%:@\[\]^{}~#|])+)</string>
|
||||
<string>(?:\()((?i:defvar|defprop|var|prop))\s+((?:\w|[+\-<>/*&=.?!$%:@\[\]^{}~#|])+)</string>
|
||||
</dict>
|
||||
<!-- <dict>
|
||||
<key>captures</key>
|
||||
@@ -133,7 +116,7 @@
|
||||
<dict>
|
||||
<key>match</key>
|
||||
<!-- TODO cut this down and add some missing ones -->
|
||||
<string>(?<=\()(?i:\*|\*\*|\*\*\*|\+|\+\+|\+\+\+|\-|/|//|///|/=|<|<=|=|>|>=|and|apply|assert|begin|break|case|catch|concat|cond|continue|count|defMacro|defReaderMacro|defun|classMethod|classFunction|defvar|classVar|classProp|for|doFor|eighth|eval|fifth|first|fourth|localFunction|localVar|symbol|if|load|withFunction|withFunctions|lambda|last|let|loop|map|max|min|ninth|not|nth|setNth|getDict|setDict|or|otherwise|print|rest|return|reversed|second|set|sixth|Some|sort|symbolName|symbolNameValue|tenth|the|third|throw|trace|when|unless|ifLet|whenLet|unlessLet|forCase|doForCase|with[A-Z]\S+)(?=\s+)</string>
|
||||
<string>(?<=\()(?i:\*|\*\*|\*\*\*|\+|\+\+|\+\+\+|\-|/|//|///|/=|<|<=|=|>|>=|and|apply|assert|begin|break|case|catch|concat|cond|continue|count|defMacro|defReaderMacro|defun|defmethod|method|function|defvar|var|defprop|prop|for|doFor|eighth|eval|fifth|first|fourth|localFunction|localVar|symbol|if|load|withFunction|withFunctions|lambda|last|let|loop|map|max|min|ninth|not|nth|setNth|getDict|setDict|or|otherwise|print|rest|return|reversed|second|set|sixth|Some|sort|symbolName|symbolNameValue|tenth|the|third|throw|trace|when|unless|ifLet|whenLet|unlessLet|forCase|doForCase|with[A-Z]\S+)(?=\s+)</string>
|
||||
<key>name</key>
|
||||
<string>keyword.control.kiss</string>
|
||||
</dict>
|
||||
|
||||
@@ -10,14 +10,14 @@
|
||||
(let [entryFiles (FileSystem.readDirectory entryDir)]
|
||||
(for file entryFiles =>(file.withoutExtension) (the Entry (Json.parse (File.getContent (joinPath archiveDir "entries" file)))))))])
|
||||
|
||||
(defmethod addSystem [:System system]
|
||||
(method addSystem [:System system]
|
||||
// Assign entries to the Systems that care about them
|
||||
(doFor =>id entry entries
|
||||
(system.checkEntryInOrOut this entry))
|
||||
(systems.push system)
|
||||
system)
|
||||
|
||||
(defmethod :Entry createEntry [:Entry->Dynamic initializer] // initializer returns Dynamic so ->:Void isn't required
|
||||
(method :Entry createEntry [:Entry->Dynamic initializer] // initializer returns Dynamic so ->:Void isn't required
|
||||
(let [e (_newEntry)]
|
||||
(initializer e)
|
||||
(dictSet entries e.id e)
|
||||
@@ -26,20 +26,20 @@
|
||||
|
||||
// After modifying an entry, this must be called. If you are writing in a createEntry initializer or a system's processEntry function, this will happen automatically.
|
||||
// Otherwise, you can guarantee it happens automatically by using the (withWritableEntry) macro in Lib.kiss
|
||||
(defmethod refreshEntry [:Entry e]
|
||||
(method refreshEntry [:Entry e]
|
||||
(_saveEntry e)
|
||||
(doFor system systems
|
||||
(system.checkEntryInOrOut this e)))
|
||||
|
||||
(defmethod _saveEntry [:Entry e]
|
||||
(method _saveEntry [:Entry e]
|
||||
(File.saveContent
|
||||
(joinPath archiveDir "entries" (e.id.withExtension "json"))
|
||||
(Json.stringify e)))
|
||||
|
||||
(defmethod componentData [:Entry e :String componentType]
|
||||
(method componentData [:Entry e :String componentType]
|
||||
(haxe.Json.parse (File.getContent (joinPath archiveDir "components" "$(dictGet e.components componentType).json"))))
|
||||
|
||||
(defmethod fullData [:Entry e]
|
||||
(method fullData [:Entry e]
|
||||
(object
|
||||
id e.id
|
||||
components
|
||||
@@ -48,11 +48,11 @@
|
||||
files
|
||||
e.files))
|
||||
|
||||
(defmethod fullString [:Entry e]
|
||||
(method fullString [:Entry e]
|
||||
(haxe.Json.stringify (fullData e) null "\t"))
|
||||
|
||||
(defun :Entry _newEntry []
|
||||
(function :Entry _newEntry []
|
||||
(object
|
||||
id (Uuid.v4)
|
||||
components (new Map)
|
||||
files []))
|
||||
files []))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(load "Lib.kiss")
|
||||
|
||||
(defmethod :Void _collectAndValidateArg [:CommandArg arg :Dynamic->Void continuation]
|
||||
(method :Void _collectAndValidateArg [:CommandArg arg :Dynamic->Void continuation]
|
||||
(case arg.type
|
||||
(SelectedEntry
|
||||
(if (= 1 selectedEntries.length)
|
||||
@@ -91,11 +91,11 @@
|
||||
min
|
||||
max))))
|
||||
|
||||
(defmethod :Void->Void _composeArgCollector [:Array<Dynamic> collectedArgs :CommandArg arg :Void->Void lastCollector]
|
||||
(method :Void->Void _composeArgCollector [:Array<Dynamic> collectedArgs :CommandArg arg :Void->Void lastCollector]
|
||||
(lambda :Void []
|
||||
(_collectAndValidateArg arg ->:Void [:Dynamic argValue] {(collectedArgs.push argValue) (lastCollector)})))
|
||||
|
||||
(defmethod :Void runCommand [:Command command]
|
||||
(method :Void runCommand [:Command command]
|
||||
(let [collectedArgs
|
||||
[]
|
||||
&mut lastCollector
|
||||
@@ -125,7 +125,7 @@
|
||||
(for [name type] argPairs
|
||||
`(object name ,(symbolName name) type ,type))]
|
||||
`{
|
||||
(defmethod ,name [,@methodArgs] ,@body)
|
||||
(method ,name [,@methodArgs] ,@body)
|
||||
(dictSet commands ,(symbolName name) (object args [,@commandArgs] handler (the Function ,name)))}))
|
||||
|
||||
(defnew [&prop :Archive archive
|
||||
@@ -184,4 +184,4 @@
|
||||
(selectEntries (filter archive.entries ->e (tagsMatch archive e tagsBoolExp))))
|
||||
|
||||
(defcommand selectByComponents [componentsBoolExp (Text null)]
|
||||
(selectEntries (filter archive.entries ->e (componentsMatch e componentsBoolExp)))))
|
||||
(selectEntries (filter archive.entries ->e (componentsMatch e componentsBoolExp)))))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
(defun eval [:String expStr :Array<String> activeConditions]
|
||||
(function eval [:String expStr :Array<String> activeConditions]
|
||||
(let [hscriptExp
|
||||
(.parseString (new Parser)
|
||||
(Prelude.convertToHScript expStr))
|
||||
@@ -6,4 +6,4 @@
|
||||
(new BoolExpInterp)]
|
||||
(doFor condition activeConditions
|
||||
(interp.variables.set condition true))
|
||||
?(interp.execute hscriptExp)))
|
||||
?(interp.execute hscriptExp)))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(load "Lib.kiss")
|
||||
|
||||
(defun :Void main []
|
||||
(function :Void main []
|
||||
(let [[archiveDir] (Sys.args)
|
||||
controller
|
||||
(new ArchiveController
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
(defnew [])
|
||||
|
||||
(defmethod :Void enterText [prompt resolve maxLength]
|
||||
(method :Void enterText [prompt resolve maxLength]
|
||||
(Sys.print "$prompt ")
|
||||
(loop
|
||||
(let [entered (.toString (.readLine (Sys.stdin)))]
|
||||
@@ -25,7 +25,7 @@
|
||||
{(resolve entered)
|
||||
(break)}))))
|
||||
|
||||
(defmethod :Void enterNumber [prompt resolve min max &opt inStepsOf]
|
||||
(method :Void enterNumber [prompt resolve min max &opt inStepsOf]
|
||||
(Sys.print "$prompt ")
|
||||
(loop
|
||||
(let [entered (Std.parseFloat (.toString (.readLine (Sys.stdin))))]
|
||||
@@ -37,10 +37,10 @@
|
||||
{(resolve entered)
|
||||
(break)}))))
|
||||
|
||||
(defmethod :Void chooseEntry [prompt :Archive archive resolve]
|
||||
(method :Void chooseEntry [prompt :Archive archive resolve]
|
||||
(_chooseEntry prompt archive resolve ->(chooseEntry "empty name doesn't match any entries. Try again?" archive resolve)))
|
||||
|
||||
(defmethod :Void _chooseEntry [prompt :Archive archive resolve onEmptyString]
|
||||
(method :Void _chooseEntry [prompt :Archive archive resolve onEmptyString]
|
||||
// TODO allow narrowing down with a tag string
|
||||
(enterText "entry name for $prompt"
|
||||
->name {
|
||||
@@ -59,10 +59,10 @@
|
||||
(multipleEntries (throw "ambiguous between multiple entries")))))}
|
||||
Math.POSITIVE_INFINITY))
|
||||
|
||||
(defmethod :Void chooseEntries [prompt archive resolve min max]
|
||||
(method :Void chooseEntries [prompt archive resolve min max]
|
||||
(_chooseEntries prompt archive resolve min max []))
|
||||
|
||||
(defmethod :Void _chooseEntries [prompt archive resolve min max :Array<Entry> collectedEntries]
|
||||
(method :Void _chooseEntries [prompt archive resolve min max :Array<Entry> collectedEntries]
|
||||
(let [onEmptyString
|
||||
->(if (<= min collectedEntries.length)
|
||||
(resolve collectedEntries)
|
||||
@@ -84,12 +84,12 @@
|
||||
(_chooseNextEntry)))
|
||||
|
||||
|
||||
(defmethod handleChanges [:Archive archive :ChangeSet changeSet]
|
||||
(method handleChanges [:Archive archive :ChangeSet changeSet]
|
||||
(doFor e changeSet
|
||||
(print (archive.fullString e))))
|
||||
|
||||
(defmethod :Void displayMessage [message]
|
||||
(method :Void displayMessage [message]
|
||||
(print message))
|
||||
|
||||
(defmethod :Void reportError [error]
|
||||
(print error))
|
||||
(method :Void reportError [error]
|
||||
(print error))
|
||||
|
||||
@@ -64,13 +64,13 @@
|
||||
(= ,value (readComponent ,archive e ,componentType))))
|
||||
,process))
|
||||
|
||||
(defun tagList [archive e]
|
||||
(function tagList [archive e]
|
||||
(let [t
|
||||
(readComponent archive e Tags)]
|
||||
(collect (t.keys))))
|
||||
|
||||
(defun tagsMatch [archive e tagsBoolExp]
|
||||
(function tagsMatch [archive e tagsBoolExp]
|
||||
(BoolExpInterp.eval tagsBoolExp (tagList archive e)))
|
||||
|
||||
(defun componentsMatch [:nat.Entry e componentsBoolExp]
|
||||
(BoolExpInterp.eval componentsBoolExp (for =>cType cId e.components cType)))
|
||||
(function componentsMatch [:nat.Entry e componentsBoolExp]
|
||||
(BoolExpInterp.eval componentsBoolExp (for =>cType cId e.components cType)))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(defprop :Map<String,Entry> entries (new Map))
|
||||
(prop :Map<String,Entry> entries (new Map))
|
||||
|
||||
(defmethod :Void process [:Archive archive]
|
||||
(method :Void process [:Archive archive]
|
||||
(doFor e (entries.iterator)
|
||||
(processEntry archive e)
|
||||
(archive.refreshEntry e)))
|
||||
@@ -9,7 +9,7 @@
|
||||
&prop :EntryProcessor processEntry]
|
||||
[])
|
||||
|
||||
(defmethod :Void checkEntryInOrOut [:Archive archive :Entry e]
|
||||
(method :Void checkEntryInOrOut [:Archive archive :Entry e]
|
||||
(if (canProcessEntry archive e)
|
||||
(dictSet entries e.id e)
|
||||
(entries.remove e.id)))
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
(load "../nat/Lib.kiss")
|
||||
|
||||
|
||||
(defun :Void main []
|
||||
(function :Void main []
|
||||
(assert (BoolExpInterp.eval "true" []))
|
||||
(assert !(BoolExpInterp.eval "false" []))
|
||||
(assert !(BoolExpInterp.eval "flag" []))
|
||||
@@ -32,4 +32,4 @@
|
||||
[author Author
|
||||
name Name]
|
||||
(assert (= author "Rafael Krux"))
|
||||
(assert (= name "Adventure")))))
|
||||
(assert (= name "Adventure")))))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
(loadFrom "nat-archive-tool" "src/nat/Lib.kiss")
|
||||
|
||||
(defun :Void main []
|
||||
(print "Hello world!"))
|
||||
(function :Void main []
|
||||
(print "Hello world!"))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
(defun loadAll [:Array<String> paths :Function callback &opt :Array<PDFDocument> pdfs]
|
||||
(function loadAll [:Array<String> paths :Function callback &opt :Array<PDFDocument> pdfs]
|
||||
(unless pdfs (set pdfs []))
|
||||
(localVar nextPdf (paths.shift))
|
||||
(if (nextPdf.endsWith ".pdf")
|
||||
@@ -13,7 +13,7 @@
|
||||
// TODO add sequentialPerPDF argument (which, when used, .shift()s pages from the beginning of PDFs)
|
||||
// TODO add chunkSize argument (default 1, which specifies how many pages in order to pull from a random PDF. value of -1 means take the whole PDF, and remove it from the list)
|
||||
// TODO make output page limit optional
|
||||
(defun :Void main []
|
||||
(function :Void main []
|
||||
(let [[sourceDir numPages] (Sys.args)]
|
||||
(loadAll (for file (Fs.readdirSync sourceDir) (+ sourceDir "/" file))
|
||||
(lambda [:Array<PDFDocument> inputPdfs]
|
||||
|
||||
Reference in New Issue
Block a user