.field expressions

This commit is contained in:
2020-12-01 15:17:56 -07:00
parent bba189febb
commit 638bce5483
4 changed files with 19 additions and 1 deletions

View File

@@ -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');
}; };

View File

@@ -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()}';
} }
} }
} }

View File

@@ -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();
}
} }

View File

@@ -258,4 +258,8 @@
(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)))