script compile time optimizations.
This commit is contained in:
1 parent
06c9aea326
commit
8d97ab26a9
27 files changed
+1071
-193
No files matched your search
@@ -3,6 +3,8 @@ package carpet.script.language;
|
||||
import carpet.script.Context;
|
||||
import carpet.script.Expression;
|
||||
import carpet.script.Fluff;
|
||||
import carpet.script.LazyValue;
|
||||
import carpet.script.Tokenizer;
|
||||
import carpet.script.argument.FunctionArgument;
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
import carpet.script.exception.ReturnStatement;
|
||||
@@ -35,53 +37,75 @@ public class Functions {
|
||||
return ListValue.wrap(c.host.availableImports(moduleName).map(StringValue::new).collect(Collectors.toList()));
|
||||
});
|
||||
|
||||
|
||||
// needs to be lazy because of custom context of execution of arguments as a signature
|
||||
expression.addLazyFunctionWithDelegation("call",-1, (c, t, expr, tok, lv) ->
|
||||
{ // adjust based on c
|
||||
if (lv.size() == 0)
|
||||
throw new InternalExpressionException("'call' expects at least function name to call");
|
||||
//lv.remove(lv.size()-1); // aint gonna cut it // maybe it will because of the eager eval changes
|
||||
if (t != Context.SIGNATURE) // just call the function
|
||||
expression.addCustomFunction("call", new Fluff.AbstractLazyFunction(-1, "call") {
|
||||
@Override
|
||||
public LazyValue lazyEval(Context c, Context.Type t, Expression expr, Tokenizer.Token tok, List<LazyValue> lv)
|
||||
{
|
||||
List<Value> args = Fluff.AbstractFunction.unpackLazy(lv, c, Context.NONE);
|
||||
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, args, 0, false, true);
|
||||
FunctionValue fun = functionArgument.function;
|
||||
return fun.callInContext(c, t, functionArgument.args);
|
||||
}
|
||||
// gimme signature
|
||||
String name = lv.get(0).evalValue(c, Context.NONE).getString();
|
||||
List<String> args = new ArrayList<>();
|
||||
List<String> globals = new ArrayList<>();
|
||||
String varArgs = null;
|
||||
for (int i = 1; i < lv.size(); i++)
|
||||
{
|
||||
Value v = lv.get(i).evalValue(c, Context.LOCALIZATION);
|
||||
if (!v.isBound())
|
||||
if (lv.size() == 0)
|
||||
throw new InternalExpressionException("'call' expects at least function name to call");
|
||||
//lv.remove(lv.size()-1); // aint gonna cut it // maybe it will because of the eager eval changes
|
||||
if (t != Context.SIGNATURE) // just call the function
|
||||
{
|
||||
throw new InternalExpressionException("Only variables can be used in function signature, not " + v.getString());
|
||||
List<Value> args = Fluff.AbstractFunction.unpackLazy(lv, c, Context.NONE);
|
||||
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, args, 0, false, true);
|
||||
FunctionValue fun = functionArgument.function;
|
||||
return fun.callInContext(c, t, functionArgument.args);
|
||||
}
|
||||
if (v instanceof FunctionAnnotationValue)
|
||||
// gimme signature
|
||||
String name = lv.get(0).evalValue(c, Context.NONE).getString();
|
||||
List<String> args = new ArrayList<>();
|
||||
List<String> globals = new ArrayList<>();
|
||||
String varArgs = null;
|
||||
for (int i = 1; i < lv.size(); i++)
|
||||
{
|
||||
if (((FunctionAnnotationValue) v).type == FunctionAnnotationValue.Type.GLOBAL)
|
||||
Value v = lv.get(i).evalValue(c, Context.LOCALIZATION);
|
||||
if (!v.isBound())
|
||||
{
|
||||
globals.add(v.boundVariable);
|
||||
throw new InternalExpressionException("Only variables can be used in function signature, not " + v.getString());
|
||||
}
|
||||
if (v instanceof FunctionAnnotationValue)
|
||||
{
|
||||
if (((FunctionAnnotationValue) v).type == FunctionAnnotationValue.Type.GLOBAL)
|
||||
{
|
||||
globals.add(v.boundVariable);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (varArgs != null)
|
||||
throw new InternalExpressionException("Variable argument identifier is already defined as "+varArgs+", trying to overwrite with "+v.boundVariable);
|
||||
varArgs = v.boundVariable;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (varArgs != null)
|
||||
throw new InternalExpressionException("Variable argument identifier is already defined as "+varArgs+", trying to overwrite with "+v.boundVariable);
|
||||
varArgs = v.boundVariable;
|
||||
args.add(v.boundVariable);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
args.add(v.boundVariable);
|
||||
}
|
||||
Value retval = new FunctionSignatureValue(name, args, varArgs, globals);
|
||||
return (cc, tt) -> retval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean pure()
|
||||
{
|
||||
return false; //true for sinature, but lets leave it for later
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean transitive() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Context.Type staticType(Context.Type outerType)
|
||||
{
|
||||
return outerType==Context.SIGNATURE?Context.LOCALIZATION:Context.NONE;
|
||||
}
|
||||
Value retval = new FunctionSignatureValue(name, args, varArgs, globals);
|
||||
return (cc, tt) -> retval;
|
||||
});
|
||||
|
||||
|
||||
expression.addContextFunction("outer", 1, (c, t, lv) ->
|
||||
{
|
||||
if (t != Context.LOCALIZATION)
|
||||
@@ -91,7 +115,7 @@ public class Functions {
|
||||
|
||||
//assigns const procedure to the lhs, returning its previous value
|
||||
// must be lazy due to RHS being an expression to save to execute
|
||||
expression.addLazyBinaryOperatorWithDelegation("->", Operators.precedence.get("def->"), false, (c, type, e, t, lv1, lv2) ->
|
||||
expression.addLazyBinaryOperatorWithDelegation("->", Operators.precedence.get("def->"), false, false, (c, type, e, t, lv1, lv2) ->
|
||||
{
|
||||
if (type == Context.MAPDEF)
|
||||
{
|
||||
@@ -106,6 +130,6 @@ public class Functions {
|
||||
return (cc, tt) -> result;
|
||||
});
|
||||
|
||||
expression.addFunction("return", (lv) -> { throw new ReturnStatement(lv.size()==0?Value.NULL:lv.get(0));} );
|
||||
expression.addImpureFunction("return", (lv) -> { throw new ReturnStatement(lv.size()==0?Value.NULL:lv.get(0));} );
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user