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);
|
||||
*/
|
||||
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');
|
||||
};
|
||||
|
@@ -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()}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -242,6 +242,10 @@ class BasicTestCase extends Test {
|
||||
function testCase() {
|
||||
_testCase();
|
||||
}
|
||||
|
||||
function testMaps() {
|
||||
_testMaps();
|
||||
}
|
||||
}
|
||||
|
||||
class BasicObject {
|
||||
|
@@ -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"))
|
||||
)
|
Reference in New Issue
Block a user