Read typed expressions
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
|
@@ -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> {
|
||||||
|
@@ -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]
|
||||||
|
Reference in New Issue
Block a user