Read typed expressions

This commit is contained in:
2020-11-18 14:42:43 -07:00
parent 382d06d8c9
commit ff389ecf25
3 changed files with 14 additions and 6 deletions

View File

@@ -77,10 +77,10 @@ class FieldForms {
for (funcArg in funcArgs) for (funcArg in funcArgs)
{ {
name: switch (funcArg) { name: switch (funcArg) {
case Symbol(name): case Symbol(name) | TypedExp(_, Symbol(name)):
name; name;
default: 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 type: null
} }

View File

@@ -8,7 +8,8 @@ enum ReaderExp {
ListExp(exps:Array<ReaderExp>); // [v1 v2 v3] ListExp(exps:Array<ReaderExp>); // [v1 v2 v3]
StrExp(s:String); // "literal" StrExp(s:String); // "literal"
Symbol(name:String); // s Symbol(name:String); // s
RawHaxe(code:String); RawHaxe(code:String); // #| haxeCode() |#
TypedExp(path:String, exp:ReaderExp); // :type [exp]
} }
typedef ReadFunction = (Stream) -> Null<ReaderExp>; typedef ReadFunction = (Stream) -> Null<ReaderExp>;
@@ -31,12 +32,19 @@ class Reader {
null; null;
}; };
readTable["#|"] = (stream) -> RawHaxe(stream.expect("closing |#", () -> stream.takeUntilAndDrop("|#"))); 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), []); 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; return readTable;
} }
static function nextToken(stream:Stream, expect:String) {
return stream.expect(expect, () -> stream.takeUntilOneOf([")", "]", "/*", "\n", " "]));
}
public static function assertRead(stream:Stream, readTable:Map<String, ReadFunction>):ReaderExp { public static function assertRead(stream:Stream, readTable:Map<String, ReadFunction>):ReaderExp {
var position = stream.position(); var position = stream.position();
return switch (read(stream, readTable)) { 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<String, ReadFunction>):Array<ReaderExp> { public static function readExpArray(stream:Stream, end:String, readTable:Map<String, ReadFunction>):Array<ReaderExp> {

View File

@@ -68,7 +68,7 @@
,intOp) ,intOp)
// I think this causes doTwiceInt's runtime function to be typed as requiring Quote<Int> and returning Int // I think this causes doTwiceInt's runtime function to be typed as requiring Quote<Int> and returning Int
(defun incrementTwice [val] (defun incrementTwice [:Int val]
(doTwiceInt ++val)) (doTwiceInt ++val))
(defmacrofun doTwiceString [stringOp] (defmacrofun doTwiceString [stringOp]