KeyValueExps allow map literals

This commit is contained in:
2020-12-07 18:28:12 -07:00
parent c0c5e3a4df
commit 0b8d1a00e1
4 changed files with 32 additions and 3 deletions

View File

@@ -135,8 +135,18 @@ class Kiss {
ECast(convert(innerExp), if (type.length > 0) Helpers.parseComplexType(type, exp) else null).withMacroPosOf(wholeExp);
*/
case ListExp(elements):
var arrayDecl = EArrayDecl([for (elementExp in elements) convert(elementExp)]).withMacroPosOf(exp);
if (k.wrapListExps) {
var isMap = false;
var arrayDecl = EArrayDecl([
for (elementExp in elements) {
switch (elementExp.def) {
case KeyValueExp(_, _):
isMap = true;
default:
}
convert(elementExp);
}
]).withMacroPosOf(exp);
if (!isMap && k.wrapListExps) {
ENew({
pack: ["kiss"],
name: "List"
@@ -148,6 +158,8 @@ class Kiss {
Context.parse(code, exp.macroPos());
case FieldExp(field, innerExp):
EField(convert(innerExp), field).withMacroPosOf(exp);
case KeyValueExp(keyExp, valueExp):
EBinop(OpArrow, convert(keyExp), convert(valueExp)).withMacroPosOf(exp);
default:
throw CompileError.fromExp(exp, 'conversion not implemented');
};

View File

@@ -19,6 +19,7 @@ enum ReaderExpDef {
TypedExp(path:String, exp:ReaderExp); // :type [exp]
MetaExp(meta:String, exp:ReaderExp); // &meta [exp]
FieldExp(field:String, exp:ReaderExp); // .field [exp]
KeyValueExp(key:ReaderExp, value:ReaderExp); // =>key value
}
typedef ReadFunction = (Stream) -> Null<ReaderExpDef>;
@@ -57,6 +58,9 @@ class Reader {
// Lets you dot-access a function result without binding it to a name
readTable["."] = (stream:Stream) -> FieldExp(nextToken(stream, "a field name"), assertRead(stream, readTable));
// Lets you construct key-value pairs for map literals or for-loops
readTable["=>"] = (stream:Stream) -> KeyValueExp(assertRead(stream, readTable), assertRead(stream, readTable));
// Because macro keys are sorted by length and peekChars(0) returns "", this will be used as the default reader macro:
readTable[""] = (stream) -> Symbol(nextToken(stream, "a symbol name"));
// TODO make - A macro for numerical negation
@@ -173,6 +177,8 @@ class Reader {
'&$meta ${exp.def.toString()}';
case FieldExp(field, exp):
'.$field ${exp.def.toString()}';
case KeyValueExp(keyExp, valueExp):
'=>${keyExp.def.toString()} ${valueExp.def.toString()}';
}
}
}

View File

@@ -242,6 +242,10 @@ class BasicTestCase extends Test {
function testCase() {
_testCase();
}
function testMaps() {
_testMaps();
}
}
class BasicObject {

View File

@@ -339,4 +339,11 @@
((Some "hey") (Assert.pass))
(otherwise (Assert.fail)))
(Assert.equals 5 (case (toOption 0)
(otherwise 5))))
(otherwise 5))))
(defun _testMaps []
(deflocal :Map<String,String> myMap [=>"hey" "you"
=>"found" "me"])
(Assert.equals "you" (dict-get myMap "hey"))
(Assert.equals "me" (dict-get myMap "found"))
)