Allow unquoting primitive strings and numbers

This commit is contained in:
2021-11-27 18:57:13 -07:00
parent d122106a14
commit d50396eee3
2 changed files with 14 additions and 16 deletions

View File

@@ -427,7 +427,8 @@ class Helpers {
return value; return value;
} }
function innerRunAtCompileTime(exp:ReaderExp) { function innerRunAtCompileTime(exp:ReaderExp) {
return compileTimeValueToReaderExp(innerRunAtCompileTimeDynamic(exp), exp); var v:Dynamic = innerRunAtCompileTimeDynamic(exp);
return compileTimeValueToReaderExp(v, exp);
} }
interp.variables.set("eval", innerRunAtCompileTimeDynamic); interp.variables.set("eval", innerRunAtCompileTimeDynamic);
@@ -461,16 +462,21 @@ class Helpers {
// The value could be either a ReaderExp, ReaderExpDef, Array of ReaderExp/ReaderExpDefs, or something else entirely, // The value could be either a ReaderExp, ReaderExpDef, Array of ReaderExp/ReaderExpDefs, or something else entirely,
// but it needs to be a ReaderExp for evalUnquotes() // but it needs to be a ReaderExp for evalUnquotes()
static function compileTimeValueToReaderExp(e:Dynamic, source:ReaderExp):ReaderExp { static function compileTimeValueToReaderExp(e:Dynamic, source:ReaderExp):ReaderExp {
// TODO if it's a string, return a StrExp. That way, symbolNameValue() won't be required
// TODO if it's a number, return a Symbol(number.toString()).
return if (Std.isOfType(e, Array)) { return if (Std.isOfType(e, Array)) {
var arr:Array<Dynamic> = e; var arr:Array<Dynamic> = e;
var listExps = arr.map(compileTimeValueToReaderExp.bind(_, source)); var listExps = arr.map(compileTimeValueToReaderExp.bind(_, source));
ListExp(listExps).withPosOf(source); ListExp(listExps).withPosOf(source);
} else if (e.def == null) { } else if (Std.isOfType(e, Float) || Std.isOfType(e, Int)) {
Symbol(Std.string(e)).withPosOf(source);
} else if (Std.isOfType(e, String)) {
var s:String = e;
StrExp(s).withPosOf(source);
} else if (Std.isOfType(e, ReaderExpDef)) {
(e : ReaderExpDef).withPosOf(source); (e : ReaderExpDef).withPosOf(source);
} else { } else if (e.pos != null && e.def != null) {
(e : ReaderExp); (e : ReaderExp);
} else {
throw CompileError.fromExp(source, 'Value $e cannot be used as a Kiss expression');
} }
} }
@@ -530,16 +536,8 @@ class Helpers {
KeyValueExp(recurse(keyExp), recurse(valueExp)); KeyValueExp(recurse(keyExp), recurse(valueExp));
case Unquote(innerExp): case Unquote(innerExp):
var unquoteValue:Dynamic = innerRunAtCompileTime(innerExp); var unquoteValue:Dynamic = innerRunAtCompileTime(innerExp);
if (unquoteValue == null) { compileTimeValueToReaderExp(unquoteValue, exp).def;
throw CompileError.fromExp(innerExp, "unquote evaluated to null"); case MetaExp(meta, innerExp):
} else if (Std.isOfType(unquoteValue, ReaderExpDef)) {
unquoteValue;
} else if (Reflect.getProperty(unquoteValue, "def") != null) {
unquoteValue.def;
} else {
throw CompileError.fromExp(exp, "unquote didn't evaluate to a ReaderExp or ReaderExpDef");
};
case MetaExp(meta, innerExp):
MetaExp(meta, recurse(innerExp)); MetaExp(meta, recurse(innerExp));
default: default:
throw CompileError.fromExp(exp, 'unquote evaluation not implemented'); throw CompileError.fromExp(exp, 'unquote evaluation not implemented');

View File

@@ -1147,7 +1147,7 @@ class Macros {
static var exprCaseFunctions:Map<String, ReaderExp->ReaderExp> = []; static var exprCaseFunctions:Map<String, ReaderExp->ReaderExp> = [];
public static function exprCase(id:String, toMatchValue:ReaderExp, i:KissInterp):ReaderExp { public static function exprCase(id:String, toMatchValue:ReaderExp, i:KissInterp):ReaderExp {
return i.variables["Helpers"].runAtCompileTime(exprCaseFunctions[id](toMatchValue)); return i.variables["Helpers"].eval(exprCaseFunctions[id](toMatchValue));
} }
static function matchExpr(pattern:ReaderExp, instance:ReaderExp):Bool { static function matchExpr(pattern:ReaderExp, instance:ReaderExp):Bool {