diff --git a/src/kiss/Kiss.hx b/src/kiss/Kiss.hx index de84e55f..c89b228c 100644 --- a/src/kiss/Kiss.hx +++ b/src/kiss/Kiss.hx @@ -132,6 +132,8 @@ class Kiss { ]).withMacroPosOf(exp); case RawHaxe(code): Context.parse(code, exp.macroPos()); + case FieldExp(field, innerExp): + EField(convert(innerExp), field).withMacroPosOf(exp); default: throw CompileError.fromExp(exp, 'conversion not implemented'); }; diff --git a/src/kiss/Reader.hx b/src/kiss/Reader.hx index 5e7ef3d3..5bb681d2 100644 --- a/src/kiss/Reader.hx +++ b/src/kiss/Reader.hx @@ -18,6 +18,7 @@ enum ReaderExpDef { RawHaxe(code:String); // #| haxeCode() |# TypedExp(path:String, exp:ReaderExp); // :type [exp] MetaExp(meta:String, exp:ReaderExp); // &meta [exp] + FieldExp(field:String, exp:ReaderExp); // .field [exp] } typedef ReadFunction = (Stream) -> Null; @@ -53,6 +54,9 @@ class Reader { // Helpful for defining predicates to pass to Haxe functions: 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: readTable[""] = (stream) -> Symbol(nextToken(stream, "a symbol name")); @@ -166,6 +170,8 @@ class Reader { case MetaExp(meta, exp): // &meta '&$meta ${exp.def.toString()}'; + case FieldExp(field, exp): + '.$field ${exp.def.toString()}'; } } } diff --git a/src/test/cases/BasicTestCase.hx b/src/test/cases/BasicTestCase.hx index 5a0753d2..38f77dc4 100644 --- a/src/test/cases/BasicTestCase.hx +++ b/src/test/cases/BasicTestCase.hx @@ -5,6 +5,8 @@ import utest.Assert; import kiss.Prelude; import kiss.List; +using StringTools; + @:build(kiss.Kiss.build("src/test/cases/BasicTestCase.kiss")) class BasicTestCase extends Test { function testStaticVar() { @@ -226,4 +228,8 @@ class BasicTestCase extends Test { Assert.equals("aboop", myCombined2); Assert.equals("ab", myCombined3); } + + function testFieldExps() { + _testFieldExps(); + } } diff --git a/src/test/cases/BasicTestCase.kiss b/src/test/cases/BasicTestCase.kiss index f5069e92..672d47b8 100644 --- a/src/test/cases/BasicTestCase.kiss +++ b/src/test/cases/BasicTestCase.kiss @@ -258,4 +258,8 @@ (defvar myCombined1 (myCombinedOptRest "a" "b" "c" "d")) (defvar myCombined2 (myCombinedOptRest "a")) -(defvar myCombined3 (myCombinedOptRest "a" "b")) \ No newline at end of file +(defvar myCombined3 (myCombinedOptRest "a" "b")) + +(defun _testFieldExps [] + (Assert.equals "hey" (.trim " hey ")) + (Assert.equals "e" (.charAt (.trim " hey ") 1))) \ No newline at end of file