57 lines
1.8 KiB
Haxe
57 lines
1.8 KiB
Haxe
package kiss;
|
|
|
|
import haxe.macro.Expr;
|
|
import haxe.macro.Context;
|
|
import kiss.Reader;
|
|
import kiss.Types;
|
|
|
|
using kiss.Helpers;
|
|
|
|
// Special forms convert Kiss reader expressions into Haxe macro expressions
|
|
typedef SpecialFormFunction = (args:Array<ReaderExp>, convert:ExprConversion) -> Expr;
|
|
|
|
class SpecialForms {
|
|
public static function builtins() {
|
|
var map:Map<String, SpecialFormFunction> = [];
|
|
|
|
map["begin"] = (args:Array<ReaderExp>, convert:ExprConversion) -> {
|
|
pos: Context.currentPos(),
|
|
expr: EBlock([for (bodyExp in args) convert(bodyExp)])
|
|
};
|
|
|
|
map["nth"] = (args:Array<ReaderExp>, convert:ExprConversion) -> {
|
|
pos: Context.currentPos(),
|
|
expr: EArray(convert(args[0]), convert(args[1]))
|
|
};
|
|
|
|
// TODO first through tenth
|
|
|
|
map["<"] = foldComparison("_min");
|
|
map["<="] = foldComparison("min");
|
|
map[">"] = foldComparison("_max");
|
|
map[">="] = foldComparison("max");
|
|
map["="] = foldComparison("_eq");
|
|
|
|
map["if"] = (args:Array<ReaderExp>, convert:ExprConversion) -> {
|
|
if (args.length < 2 || args.length > 3) {
|
|
throw 'if statement has wrong number of arguments: ${args.length}';
|
|
}
|
|
|
|
var condition = macro Prelude.truthy(${convert(args[0])});
|
|
var thenExp = convert(args[1]);
|
|
var elseExp = if (args.length > 2) convert(args[2]) else null;
|
|
|
|
EIf(condition, thenExp, elseExp).withPos();
|
|
};
|
|
|
|
return map;
|
|
}
|
|
|
|
static function foldComparison(func:String) {
|
|
return (args:Array<ReaderExp>, convert:ExprConversion) -> {
|
|
pos: Context.currentPos(),
|
|
expr: EBinop(OpEq, convert(args[0]), convert(CallExp(Symbol(func), args)))
|
|
};
|
|
}
|
|
}
|