Completely change naming conventions of field forms and definition macros. Close #32

This commit is contained in:
2021-07-24 14:22:10 -06:00
parent 016474e893
commit 5d43feb97b
15 changed files with 184 additions and 181 deletions

View File

@@ -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();
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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};
}
};

View File

@@ -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))))

View File

@@ -1 +1 @@
(defun loadedFunction [] "loaded")
(function loadedFunction [] "loaded")

View File

@@ -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!

View File

@@ -1,4 +1,4 @@
(defun myFun []
(function myFun []
(localVar something 5)
// This comment used to cause a hard-to-track-down error!
)
)

View File

@@ -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))))

View File

@@ -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")}])|#)

View File

@@ -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)))))

View File

@@ -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))

View File

@@ -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)))

View File

@@ -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))