.field expressions
This commit is contained in:
@@ -132,6 +132,8 @@ class Kiss {
|
|||||||
]).withMacroPosOf(exp);
|
]).withMacroPosOf(exp);
|
||||||
case RawHaxe(code):
|
case RawHaxe(code):
|
||||||
Context.parse(code, exp.macroPos());
|
Context.parse(code, exp.macroPos());
|
||||||
|
case FieldExp(field, innerExp):
|
||||||
|
EField(convert(innerExp), field).withMacroPosOf(exp);
|
||||||
default:
|
default:
|
||||||
throw CompileError.fromExp(exp, 'conversion not implemented');
|
throw CompileError.fromExp(exp, 'conversion not implemented');
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ enum ReaderExpDef {
|
|||||||
RawHaxe(code:String); // #| haxeCode() |#
|
RawHaxe(code:String); // #| haxeCode() |#
|
||||||
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]
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef ReadFunction = (Stream) -> Null<ReaderExpDef>;
|
typedef ReadFunction = (Stream) -> Null<ReaderExpDef>;
|
||||||
@@ -53,6 +54,9 @@ class Reader {
|
|||||||
// Helpful for defining predicates to pass to Haxe functions:
|
// Helpful for defining predicates to pass to Haxe functions:
|
||||||
readTable["?"] = (stream:Stream) -> CallExp(Symbol("Prelude.truthy").withPos(stream.position()), [assertRead(stream, readTable)]);
|
readTable["?"] = (stream:Stream) -> CallExp(Symbol("Prelude.truthy").withPos(stream.position()), [assertRead(stream, readTable)]);
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
|
||||||
// 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"));
|
||||||
|
|
||||||
@@ -166,6 +170,8 @@ class Reader {
|
|||||||
case MetaExp(meta, exp):
|
case MetaExp(meta, exp):
|
||||||
// &meta
|
// &meta
|
||||||
'&$meta ${exp.def.toString()}';
|
'&$meta ${exp.def.toString()}';
|
||||||
|
case FieldExp(field, exp):
|
||||||
|
'.$field ${exp.def.toString()}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import utest.Assert;
|
|||||||
import kiss.Prelude;
|
import kiss.Prelude;
|
||||||
import kiss.List;
|
import kiss.List;
|
||||||
|
|
||||||
|
using StringTools;
|
||||||
|
|
||||||
@:build(kiss.Kiss.build("src/test/cases/BasicTestCase.kiss"))
|
@:build(kiss.Kiss.build("src/test/cases/BasicTestCase.kiss"))
|
||||||
class BasicTestCase extends Test {
|
class BasicTestCase extends Test {
|
||||||
function testStaticVar() {
|
function testStaticVar() {
|
||||||
@@ -226,4 +228,8 @@ class BasicTestCase extends Test {
|
|||||||
Assert.equals("aboop", myCombined2);
|
Assert.equals("aboop", myCombined2);
|
||||||
Assert.equals("ab", myCombined3);
|
Assert.equals("ab", myCombined3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testFieldExps() {
|
||||||
|
_testFieldExps();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -259,3 +259,7 @@
|
|||||||
(defvar myCombined1 (myCombinedOptRest "a" "b" "c" "d"))
|
(defvar myCombined1 (myCombinedOptRest "a" "b" "c" "d"))
|
||||||
(defvar myCombined2 (myCombinedOptRest "a"))
|
(defvar myCombined2 (myCombinedOptRest "a"))
|
||||||
(defvar myCombined3 (myCombinedOptRest "a" "b"))
|
(defvar myCombined3 (myCombinedOptRest "a" "b"))
|
||||||
|
|
||||||
|
(defun _testFieldExps []
|
||||||
|
(Assert.equals "hey" (.trim " hey "))
|
||||||
|
(Assert.equals "e" (.charAt (.trim " hey ") 1)))
|
||||||
Reference in New Issue
Block a user