KeyValueExps allow map literals
This commit is contained in:
@@ -135,8 +135,18 @@ class Kiss {
|
|||||||
ECast(convert(innerExp), if (type.length > 0) Helpers.parseComplexType(type, exp) else null).withMacroPosOf(wholeExp);
|
ECast(convert(innerExp), if (type.length > 0) Helpers.parseComplexType(type, exp) else null).withMacroPosOf(wholeExp);
|
||||||
*/
|
*/
|
||||||
case ListExp(elements):
|
case ListExp(elements):
|
||||||
var arrayDecl = EArrayDecl([for (elementExp in elements) convert(elementExp)]).withMacroPosOf(exp);
|
var isMap = false;
|
||||||
if (k.wrapListExps) {
|
var arrayDecl = EArrayDecl([
|
||||||
|
for (elementExp in elements) {
|
||||||
|
switch (elementExp.def) {
|
||||||
|
case KeyValueExp(_, _):
|
||||||
|
isMap = true;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
convert(elementExp);
|
||||||
|
}
|
||||||
|
]).withMacroPosOf(exp);
|
||||||
|
if (!isMap && k.wrapListExps) {
|
||||||
ENew({
|
ENew({
|
||||||
pack: ["kiss"],
|
pack: ["kiss"],
|
||||||
name: "List"
|
name: "List"
|
||||||
@@ -148,6 +158,8 @@ class Kiss {
|
|||||||
Context.parse(code, exp.macroPos());
|
Context.parse(code, exp.macroPos());
|
||||||
case FieldExp(field, innerExp):
|
case FieldExp(field, innerExp):
|
||||||
EField(convert(innerExp), field).withMacroPosOf(exp);
|
EField(convert(innerExp), field).withMacroPosOf(exp);
|
||||||
|
case KeyValueExp(keyExp, valueExp):
|
||||||
|
EBinop(OpArrow, convert(keyExp), convert(valueExp)).withMacroPosOf(exp);
|
||||||
default:
|
default:
|
||||||
throw CompileError.fromExp(exp, 'conversion not implemented');
|
throw CompileError.fromExp(exp, 'conversion not implemented');
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ enum ReaderExpDef {
|
|||||||
TypedExp(path:String, exp:ReaderExp); // :type [exp]
|
TypedExp(path:String, exp:ReaderExp); // :type [exp]
|
||||||
MetaExp(meta:String, exp:ReaderExp); // &meta [exp]
|
MetaExp(meta:String, exp:ReaderExp); // &meta [exp]
|
||||||
FieldExp(field:String, exp:ReaderExp); // .field [exp]
|
FieldExp(field:String, exp:ReaderExp); // .field [exp]
|
||||||
|
KeyValueExp(key:ReaderExp, value:ReaderExp); // =>key value
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef ReadFunction = (Stream) -> Null<ReaderExpDef>;
|
typedef ReadFunction = (Stream) -> Null<ReaderExpDef>;
|
||||||
@@ -57,6 +58,9 @@ class Reader {
|
|||||||
// Lets you dot-access a function result without binding it to a name
|
// 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));
|
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:
|
// 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"));
|
readTable[""] = (stream) -> Symbol(nextToken(stream, "a symbol name"));
|
||||||
// TODO make - A macro for numerical negation
|
// TODO make - A macro for numerical negation
|
||||||
@@ -173,6 +177,8 @@ class Reader {
|
|||||||
'&$meta ${exp.def.toString()}';
|
'&$meta ${exp.def.toString()}';
|
||||||
case FieldExp(field, exp):
|
case FieldExp(field, exp):
|
||||||
'.$field ${exp.def.toString()}';
|
'.$field ${exp.def.toString()}';
|
||||||
|
case KeyValueExp(keyExp, valueExp):
|
||||||
|
'=>${keyExp.def.toString()} ${valueExp.def.toString()}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -242,6 +242,10 @@ class BasicTestCase extends Test {
|
|||||||
function testCase() {
|
function testCase() {
|
||||||
_testCase();
|
_testCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testMaps() {
|
||||||
|
_testMaps();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class BasicObject {
|
class BasicObject {
|
||||||
|
|||||||
@@ -340,3 +340,10 @@
|
|||||||
(otherwise (Assert.fail)))
|
(otherwise (Assert.fail)))
|
||||||
(Assert.equals 5 (case (toOption 0)
|
(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"))
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user