This commit is contained in:
2020-11-19 13:00:42 -07:00
parent 8ee2fa5bca
commit 70917e5295
3 changed files with 48 additions and 2 deletions

View File

@@ -6,6 +6,7 @@ import kiss.Reader;
import kiss.Types;
using kiss.Helpers;
using kiss.Prelude;
// Special forms convert Kiss reader expressions into Haxe macro expressions
typedef SpecialFormFunction = (args:Array<ReaderExp>, convert:ExprConversion) -> Expr;
@@ -34,7 +35,40 @@ class SpecialForms {
// TODO special form for local var declaration
// TODO let
map["let"] = (args:Array<ReaderExp>, convert:ExprConversion) -> {
var bindingList = switch (args[0]) {
case ListExp(bindingExps) if (bindingExps.length > 0 && bindingExps.length % 2 == 0):
bindingExps;
default:
throw '${args[0]} should be a list expression with an even number of sub expressions';
};
var bindingPairs = bindingList.groups(2);
var varDefs = [
for (bindingPair in bindingPairs)
{
name: switch (bindingPair[0]) {
case Symbol(name) | TypedExp(_, Symbol(name)):
name;
default:
throw 'first element of binding pair $bindingPair should be a symbol or typed symbol';
},
type: switch (bindingPair[0]) {
case TypedExp(type, _):
Helpers.parseTypePath(type);
default: null;
},
isFinal: true, // Let's give (let...) variable immutability a try
expr: convert(bindingPair[1])
}
];
var body = args.slice(1);
if (body.length == 0) {
throw '(let....) expression with bindings $bindingPairs needs a body';
}
EBlock([EVars(varDefs).withPos(), EBlock(body.map(convert)).withPos()]).withPos();
};
// TODO special form for lambda

View File

@@ -146,4 +146,8 @@ class BasicTestCase extends Test {
Assert.equals([[1, 2], [3, 4]].toString(), BasicTestCase.myGroups1().toString());
Assert.equals([[1, 2, 3], [4]].toString(), BasicTestCase.myGroups2().toString());
}
function testLet() {
_testLet();
}
}

View File

@@ -92,3 +92,11 @@
(defun myGroups2 []
(Prelude.groups [1 2 3 4] 3 true))
(defun _testLet []
(let [a 5
b 6
:String c "stuff"]
(Assert.equals 5 a)
(Assert.equals 6 b)
(Assert.equals "stuff" c)))