From ff389ecf255fcb1daa72d7b4de2e07e720b318f8 Mon Sep 17 00:00:00 2001 From: Nat Quayle Nelson Date: Wed, 18 Nov 2020 14:42:43 -0700 Subject: [PATCH] Read typed expressions --- src/kiss/FieldForms.hx | 4 ++-- src/kiss/Reader.hx | 14 +++++++++++--- src/test/cases/BasicTestCase.kiss | 2 +- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/kiss/FieldForms.hx b/src/kiss/FieldForms.hx index 0fda5e82..fa76c371 100644 --- a/src/kiss/FieldForms.hx +++ b/src/kiss/FieldForms.hx @@ -77,10 +77,10 @@ class FieldForms { for (funcArg in funcArgs) { name: switch (funcArg) { - case Symbol(name): + case Symbol(name) | TypedExp(_, Symbol(name)): name; default: - throw '$funcArg should be a symbol for a function argument'; + throw '$funcArg should be a symbol or typed symbol for a function argument'; }, type: null } diff --git a/src/kiss/Reader.hx b/src/kiss/Reader.hx index cc985929..1c96c93f 100644 --- a/src/kiss/Reader.hx +++ b/src/kiss/Reader.hx @@ -8,7 +8,8 @@ enum ReaderExp { ListExp(exps:Array); // [v1 v2 v3] StrExp(s:String); // "literal" Symbol(name:String); // s - RawHaxe(code:String); + RawHaxe(code:String); // #| haxeCode() |# + TypedExp(path:String, exp:ReaderExp); // :type [exp] } typedef ReadFunction = (Stream) -> Null; @@ -31,12 +32,19 @@ class Reader { null; }; readTable["#|"] = (stream) -> RawHaxe(stream.expect("closing |#", () -> stream.takeUntilAndDrop("|#"))); - // Unquote is syntactic sugar for calling a Quote (Void->T) + // For defmacrofuns, unquoting with , is syntactic sugar for calling a Quote (Void->T) readTable[","] = (stream) -> CallExp(assertRead(stream, readTable), []); + // If/when proper defmacro is added, reading every Unquote directly as a CallExp won't work anymore + + readTable[":"] = (stream) -> TypedExp(nextToken(stream, "a type path"), assertRead(stream, readTable)); return readTable; } + static function nextToken(stream:Stream, expect:String) { + return stream.expect(expect, () -> stream.takeUntilOneOf([")", "]", "/*", "\n", " "])); + } + public static function assertRead(stream:Stream, readTable:Map):ReaderExp { var position = stream.position(); return switch (read(stream, readTable)) { @@ -66,7 +74,7 @@ class Reader { } } - return Some(Symbol(stream.expect("a symbol name", () -> stream.takeUntilOneOf([")", "]", "/*", "\n", " "])))); + return Some(Symbol(nextToken(stream, "a symbol name"))); } public static function readExpArray(stream:Stream, end:String, readTable:Map):Array { diff --git a/src/test/cases/BasicTestCase.kiss b/src/test/cases/BasicTestCase.kiss index 533bbc40..d92e2343 100644 --- a/src/test/cases/BasicTestCase.kiss +++ b/src/test/cases/BasicTestCase.kiss @@ -68,7 +68,7 @@ ,intOp) // I think this causes doTwiceInt's runtime function to be typed as requiring Quote and returning Int -(defun incrementTwice [val] +(defun incrementTwice [:Int val] (doTwiceInt ++val)) (defmacrofun doTwiceString [stringOp]