dont be lazy refactor
This commit is contained in:
1 parent
a65d16c9ba
commit
74bd0bb81e
31 files changed
+1078
-1383
No files matched your search
@@ -64,10 +64,10 @@ public class Arithmetic {
|
||||
expression.addMathematicalUnaryIntFunction("floor", n -> (long)Math.floor(n));
|
||||
expression.addMathematicalUnaryIntFunction("ceil", n -> (long)Math.ceil(n));
|
||||
|
||||
expression.addLazyFunction("mandelbrot", 3, (c, t, lv) -> {
|
||||
double a0 = NumericValue.asNumber(lv.get(0).evalValue(c)).getDouble();
|
||||
double b0 = NumericValue.asNumber(lv.get(1).evalValue(c)).getDouble();
|
||||
long maxiter = NumericValue.asNumber(lv.get(2).evalValue(c)).getLong();
|
||||
expression.addContextFunction("mandelbrot", 3, (c, t, lv) -> {
|
||||
double a0 = NumericValue.asNumber(lv.get(0)).getDouble();
|
||||
double b0 = NumericValue.asNumber(lv.get(1)).getDouble();
|
||||
long maxiter = NumericValue.asNumber(lv.get(2)).getLong();
|
||||
double a = 0.0D;
|
||||
double b = 0.0D;
|
||||
long iter = 0;
|
||||
@@ -79,7 +79,7 @@ public class Arithmetic {
|
||||
iter++;
|
||||
}
|
||||
long iFinal = iter;
|
||||
return (cc, tt) -> new NumericValue(iFinal);
|
||||
return new NumericValue(iFinal);
|
||||
});
|
||||
|
||||
expression.addFunction("max", (lv) ->
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.util.stream.Collectors;
|
||||
public class ControlFlow {
|
||||
public static void apply(Expression expression) // public just to get the javadoc right
|
||||
{
|
||||
// needs to be lazy cause of custom contextualization
|
||||
expression.addLazyBinaryOperator(";", Operators.precedence.get("nextop;"), true, (c, t, lv1, lv2) ->
|
||||
{
|
||||
lv1.evalValue(c, Context.VOID);
|
||||
@@ -27,7 +28,7 @@ public class ControlFlow {
|
||||
return (cc, tt) -> v2;
|
||||
});
|
||||
|
||||
// if(cond1, expr1, cond2, expr2, ..., ?default) => value
|
||||
// obvious lazy due to conditional evaluation of arguments
|
||||
expression.addLazyFunction("if", -1, (c, t, lv) ->
|
||||
{
|
||||
if ( lv.size() < 2 )
|
||||
@@ -51,23 +52,24 @@ public class ControlFlow {
|
||||
|
||||
expression.addFunction("exit", (lv) -> { throw new ExitStatement(lv.size()==0?Value.NULL:lv.get(0)); });
|
||||
|
||||
expression.addLazyFunction("throw", -1, (c, t, lv)->
|
||||
expression.addFunction("throw", lv->
|
||||
{
|
||||
switch (lv.size())
|
||||
{
|
||||
case 0:
|
||||
throw new ThrowStatement(Value.NULL, Throwables.USER_DEFINED);
|
||||
case 1:
|
||||
throw new ThrowStatement(lv.get(0).evalValue(c), Throwables.USER_DEFINED );
|
||||
throw new ThrowStatement(lv.get(0), Throwables.USER_DEFINED );
|
||||
case 2:
|
||||
throw new ThrowStatement(lv.get(1).evalValue(c), Throwables.getTypeForException(lv.get(0).evalValue(c).getString()));
|
||||
throw new ThrowStatement(lv.get(1), Throwables.getTypeForException(lv.get(0).getString()));
|
||||
case 3:
|
||||
throw new ThrowStatement(lv.get(2).evalValue(c), Throwables.getTypeForException(lv.get(1).evalValue(c).getString()), lv.get(0).evalValue(c).getString());
|
||||
throw new ThrowStatement(lv.get(2), Throwables.getTypeForException(lv.get(1).getString()), lv.get(0).getString());
|
||||
default:
|
||||
throw new InternalExpressionException("throw() can't accept more than 3 parameters");
|
||||
}
|
||||
});
|
||||
|
||||
// needs to be lazy since execution of parameters but first one are conditional
|
||||
expression.addLazyFunction("try", -1, (c, t, lv) ->
|
||||
{
|
||||
if (lv.size()==0)
|
||||
|
||||
@@ -95,6 +95,7 @@ public class DataStructures {
|
||||
return ListValue.wrap(toSort);
|
||||
});
|
||||
|
||||
// needs lazy cause sort function is reused
|
||||
expression.addLazyFunction("sort_key", -1, (c, t, lv) -> //get working with iterators
|
||||
{
|
||||
if (lv.size() == 0)
|
||||
@@ -121,7 +122,8 @@ public class DataStructures {
|
||||
});
|
||||
//revering scope
|
||||
c.setVariable("_", __);
|
||||
return (cc, tt) -> ListValue.wrap(toSort);
|
||||
Value ret = ListValue.wrap(toSort);
|
||||
return (cc, tt) -> ret;
|
||||
});
|
||||
|
||||
expression.addFunction("range", (lv) ->
|
||||
@@ -147,18 +149,14 @@ public class DataStructures {
|
||||
: LazyListValue.rangeDouble(from.getDouble(), to.getDouble(), step.getDouble());
|
||||
});
|
||||
|
||||
expression.addLazyFunction("m", -1, (c, t, llv) ->
|
||||
expression.addTypedContextFunction("m", -1, Context.MAPDEF, (c, t, lv) ->
|
||||
{
|
||||
List<Value> lv = new ArrayList<>();
|
||||
for (LazyValue lazyParam : llv) {
|
||||
lv.add(lazyParam.evalValue(c, Context.MAPDEF)); // none type default by design
|
||||
}
|
||||
Value ret;
|
||||
if (lv.size() == 1 && lv.get(0) instanceof LazyListValue)
|
||||
ret = new MapValue(((LazyListValue) lv.get(0)).unroll());
|
||||
else
|
||||
ret = new MapValue(lv);
|
||||
return (cc, tt) -> ret;
|
||||
return ret;
|
||||
});
|
||||
|
||||
expression.addUnaryFunction("keys", v ->
|
||||
@@ -184,41 +182,23 @@ public class DataStructures {
|
||||
return Value.NULL;
|
||||
});
|
||||
|
||||
expression.addLazyBinaryOperator(":", Operators.precedence.get("attribute~:"),true, (c, t, container_lv, key_lv) ->
|
||||
expression.addBinaryContextOperator(":", Operators.precedence.get("attribute~:"),true, (c, t, container, address) ->
|
||||
{
|
||||
Value container = container_lv.evalValue(c);
|
||||
if (container instanceof LContainerValue)
|
||||
{
|
||||
ContainerValueInterface outerContainer = ((LContainerValue) container).getContainer();
|
||||
if (outerContainer == null)
|
||||
{
|
||||
Value innerLValue = new LContainerValue(null, null);
|
||||
return (cc, tt) -> innerLValue;
|
||||
}
|
||||
if (outerContainer == null) return LContainerValue.NULL_CONTAINER;
|
||||
Value innerContainer = outerContainer.get(((LContainerValue) container).getAddress());
|
||||
if (!(innerContainer instanceof ContainerValueInterface))
|
||||
{
|
||||
Value innerLValue = new LContainerValue(null, null);
|
||||
return (cc, tt) -> innerLValue;
|
||||
}
|
||||
Value innerLValue = new LContainerValue((ContainerValueInterface) innerContainer, key_lv.evalValue(c));
|
||||
return (cc, tt) -> innerLValue;
|
||||
if (!(innerContainer instanceof ContainerValueInterface)) return LContainerValue.NULL_CONTAINER;
|
||||
return new LContainerValue((ContainerValueInterface) innerContainer, address);
|
||||
}
|
||||
if (!(container instanceof ContainerValueInterface))
|
||||
if (t == Context.LVALUE)
|
||||
return (cc, tt) -> new LContainerValue(null, null);
|
||||
else
|
||||
return (cc, tt) -> Value.NULL;
|
||||
Value address = key_lv.evalValue(c);
|
||||
if (t != Context.LVALUE)
|
||||
{
|
||||
Value retVal = ((ContainerValueInterface) container).get(address);
|
||||
return (cc, ct) -> retVal;
|
||||
}
|
||||
Value retVal = new LContainerValue((ContainerValueInterface) container, address);
|
||||
return (cc, ct) -> retVal;
|
||||
return t == Context.LVALUE ? LContainerValue.NULL_CONTAINER : Value.NULL;
|
||||
if (t != Context.LVALUE) return ((ContainerValueInterface) container).get(address);
|
||||
return new LContainerValue((ContainerValueInterface) container, address);
|
||||
});
|
||||
|
||||
// lazy cause conditional typing - questionable
|
||||
expression.addLazyFunction("get", -1, (c, t, lv) ->
|
||||
{
|
||||
if (lv.size() == 0)
|
||||
@@ -227,10 +207,10 @@ public class DataStructures {
|
||||
{
|
||||
Value v = lv.get(0).evalValue(c, Context.LVALUE);
|
||||
if (!(v instanceof LContainerValue))
|
||||
return (cc, tt) -> Value.NULL;
|
||||
return LazyValue.NULL;
|
||||
ContainerValueInterface container = ((LContainerValue) v).getContainer();
|
||||
if (container == null)
|
||||
return (cc, tt) -> Value.NULL;
|
||||
return LazyValue.NULL;
|
||||
Value ret = container.get(((LContainerValue) v).getAddress());
|
||||
return (cc, tt) -> ret;
|
||||
}
|
||||
@@ -246,6 +226,7 @@ public class DataStructures {
|
||||
return (cc, tt) -> finalContainer;
|
||||
});
|
||||
|
||||
// same as `get`
|
||||
expression.addLazyFunction("has", -1, (c, t, lv) ->
|
||||
{
|
||||
if (lv.size() == 0)
|
||||
@@ -254,25 +235,26 @@ public class DataStructures {
|
||||
{
|
||||
Value v = lv.get(0).evalValue(c, Context.LVALUE);
|
||||
if (!(v instanceof LContainerValue))
|
||||
return (cc, tt) -> Value.NULL;
|
||||
return LazyValue.NULL;
|
||||
ContainerValueInterface container = ((LContainerValue) v).getContainer();
|
||||
if (container == null)
|
||||
return (cc, tt) -> Value.NULL;
|
||||
return LazyValue.NULL;
|
||||
Value ret = new NumericValue(container.has(((LContainerValue) v).getAddress()));
|
||||
return (cc, tt) -> ret;
|
||||
}
|
||||
Value container = lv.get(0).evalValue(c);
|
||||
for (int i = 1; i < lv.size()-1; i++)
|
||||
{
|
||||
if (!(container instanceof ContainerValueInterface)) return (cc, tt) -> Value.NULL;
|
||||
if (!(container instanceof ContainerValueInterface)) return LazyValue.NULL;
|
||||
container = ((ContainerValueInterface) container).get(lv.get(i).evalValue(c));
|
||||
}
|
||||
if (!(container instanceof ContainerValueInterface))
|
||||
return (cc, tt) -> Value.NULL;
|
||||
return LazyValue.NULL;
|
||||
Value ret = new NumericValue(((ContainerValueInterface) container).has(lv.get(lv.size()-1).evalValue(c)));
|
||||
return (cc, tt) -> ret;
|
||||
});
|
||||
|
||||
// same as `get`
|
||||
expression.addLazyFunction("put", -1, (c, t, lv) ->
|
||||
{
|
||||
if(lv.size()<2)
|
||||
@@ -285,7 +267,7 @@ public class DataStructures {
|
||||
ContainerValueInterface internalContainer = ((LContainerValue) container).getContainer();
|
||||
if (internalContainer == null)
|
||||
{
|
||||
return (cc, tt) -> Value.NULL;
|
||||
return LazyValue.NULL;
|
||||
}
|
||||
Value address = ((LContainerValue) container).getAddress();
|
||||
Value what = lv.get(1).evalValue(c);
|
||||
@@ -301,7 +283,7 @@ public class DataStructures {
|
||||
}
|
||||
if (!(container instanceof ContainerValueInterface))
|
||||
{
|
||||
return (cc, tt) -> Value.NULL;
|
||||
return LazyValue.NULL;
|
||||
}
|
||||
Value where = lv.get(1).evalValue(c);
|
||||
Value what = lv.get(2).evalValue(c);
|
||||
@@ -311,6 +293,7 @@ public class DataStructures {
|
||||
return (cc, tt) -> retVal;
|
||||
});
|
||||
|
||||
// same as `get`
|
||||
expression.addLazyFunction("delete", -1, (c, t, lv) ->
|
||||
{
|
||||
if (lv.size() == 0)
|
||||
@@ -319,21 +302,21 @@ public class DataStructures {
|
||||
{
|
||||
Value v = lv.get(0).evalValue(c, Context.LVALUE);
|
||||
if (!(v instanceof LContainerValue))
|
||||
return (cc, tt) -> Value.NULL;
|
||||
return LazyValue.NULL;
|
||||
ContainerValueInterface container = ((LContainerValue) v).getContainer();
|
||||
if (container == null)
|
||||
return (cc, tt) -> Value.NULL;
|
||||
return LazyValue.NULL;
|
||||
Value ret = new NumericValue(container.delete(((LContainerValue) v).getAddress()));
|
||||
return (cc, tt) -> ret;
|
||||
}
|
||||
Value container = lv.get(0).evalValue(c);
|
||||
for (int i = 1; i < lv.size()-1; i++)
|
||||
{
|
||||
if (!(container instanceof ContainerValueInterface)) return (cc, tt) -> Value.NULL;
|
||||
if (!(container instanceof ContainerValueInterface)) return LazyValue.NULL;
|
||||
container = ((ContainerValueInterface) container).get(lv.get(i).evalValue(c));
|
||||
}
|
||||
if (!(container instanceof ContainerValueInterface))
|
||||
return (cc, tt) -> Value.NULL;
|
||||
return LazyValue.NULL;
|
||||
Value ret = new NumericValue(((ContainerValueInterface) container).delete(lv.get(lv.size()-1).evalValue(c)));
|
||||
return (cc, tt) -> ret;
|
||||
});
|
||||
|
||||
@@ -2,12 +2,13 @@ package carpet.script.language;
|
||||
|
||||
import carpet.script.Context;
|
||||
import carpet.script.Expression;
|
||||
import carpet.script.LazyValue;
|
||||
import carpet.script.Fluff;
|
||||
import carpet.script.argument.FunctionArgument;
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
import carpet.script.exception.ReturnStatement;
|
||||
import carpet.script.value.AbstractListValue;
|
||||
import carpet.script.value.FunctionSignatureValue;
|
||||
import carpet.script.value.FunctionUnpackedArgumentsValue;
|
||||
import carpet.script.value.FunctionValue;
|
||||
import carpet.script.value.FunctionAnnotationValue;
|
||||
import carpet.script.value.ListValue;
|
||||
@@ -24,20 +25,20 @@ public class Functions {
|
||||
public static void apply(Expression expression) // public just to get the javadoc right
|
||||
{
|
||||
// artificial construct to handle user defined functions and function definitions
|
||||
expression.addLazyFunction("import", -1, (c, t, lv) ->
|
||||
expression.addContextFunction("import", -1, (c, t, lv) ->
|
||||
{
|
||||
if (lv.size() < 1) throw new InternalExpressionException("'import' needs at least a module name to import, and list of values to import");
|
||||
String moduleName = lv.get(0).evalValue(c).getString();
|
||||
String moduleName = lv.get(0).getString();
|
||||
c.host.importModule(c, moduleName);
|
||||
moduleName = moduleName.toLowerCase(Locale.ROOT);
|
||||
if (lv.size() > 1)
|
||||
c.host.importNames(c, expression.module, moduleName, lv.subList(1, lv.size()).stream().map((l) -> l.evalValue(c).getString()).collect(Collectors.toList()));
|
||||
c.host.importNames(c, expression.module, moduleName, lv.subList(1, lv.size()).stream().map(Value::getString).collect(Collectors.toList()));
|
||||
if (t == Context.VOID)
|
||||
return LazyValue.NULL;
|
||||
ListValue list = ListValue.wrap(c.host.availableImports(moduleName).map(StringValue::new).collect(Collectors.toList()));
|
||||
return (cc, tt) -> list;
|
||||
return Value.NULL;
|
||||
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)
|
||||
@@ -45,7 +46,8 @@ public class Functions {
|
||||
//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
|
||||
{
|
||||
FunctionArgument<LazyValue> functionArgument = FunctionArgument.findIn(c, expression.module, lv, 0, false, true);
|
||||
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);
|
||||
}
|
||||
@@ -63,7 +65,7 @@ public class Functions {
|
||||
}
|
||||
if (v instanceof FunctionAnnotationValue)
|
||||
{
|
||||
if (((FunctionAnnotationValue) v).type == 0)
|
||||
if (((FunctionAnnotationValue) v).type == FunctionAnnotationValue.Type.GLOBAL)
|
||||
{
|
||||
globals.add(v.boundVariable);
|
||||
}
|
||||
@@ -83,32 +85,37 @@ public class Functions {
|
||||
return (cc, tt) -> retval;
|
||||
});
|
||||
|
||||
expression.addLazyFunction("outer", 1, (c, t, lv) ->
|
||||
expression.addContextFunction("outer", 1, (c, t, lv) ->
|
||||
{
|
||||
if (t != Context.LOCALIZATION)
|
||||
throw new InternalExpressionException("Outer scoping of variables is only possible in function signatures.");
|
||||
return (cc, tt) -> new FunctionAnnotationValue(lv.get(0).evalValue(c), 0);
|
||||
return new FunctionAnnotationValue(lv.get(0), FunctionAnnotationValue.Type.GLOBAL);
|
||||
});
|
||||
|
||||
// lazy because of typed evaluation of the argument
|
||||
expression.addLazyUnaryOperator("...", Operators.precedence.get("def->..."), false, (c, t, lv) ->
|
||||
{
|
||||
if (t == Context.LOCALIZATION)
|
||||
return (cc, tt) -> new FunctionAnnotationValue(lv.evalValue(c), 1);
|
||||
if (t == Context.CALLARGS)
|
||||
{
|
||||
Value params = lv.evalValue(c, Context.NONE);
|
||||
if (params instanceof ListValue)
|
||||
return (cc, tt) -> params;
|
||||
if (!(params instanceof AbstractListValue))
|
||||
throw new InternalExpressionException("Unable to unpack a non-list");
|
||||
Value unpacked = ListValue.wrap(ImmutableList.copyOf(((AbstractListValue) params).iterator()));
|
||||
return (cc, tt) -> unpacked;
|
||||
}
|
||||
throw new InternalExpressionException("That functionality has not been implemented yet.");
|
||||
return (cc, tt) -> new FunctionAnnotationValue(lv.evalValue(c), FunctionAnnotationValue.Type.VARARG);
|
||||
|
||||
Value params = lv.evalValue(c, t);
|
||||
FunctionUnpackedArgumentsValue fuaval;
|
||||
if (params instanceof ListValue)
|
||||
{
|
||||
fuaval = new FunctionUnpackedArgumentsValue(((ListValue) params).getItems());
|
||||
return (cc, tt) -> fuaval;
|
||||
}
|
||||
if (!(params instanceof AbstractListValue))
|
||||
throw new InternalExpressionException("Unable to unpack a non-list");
|
||||
fuaval = new FunctionUnpackedArgumentsValue(
|
||||
ImmutableList.copyOf(((AbstractListValue) params).iterator())
|
||||
);
|
||||
return (cc, tt) -> fuaval;
|
||||
//throw new InternalExpressionException("That functionality has not been implemented yet.");
|
||||
});
|
||||
|
||||
//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) ->
|
||||
{
|
||||
if (type == Context.MAPDEF)
|
||||
|
||||
@@ -35,6 +35,7 @@ public class Loops {
|
||||
throw new InternalExpressionException("'continue' can only be called with zero or one argument");
|
||||
});
|
||||
|
||||
// lazy
|
||||
expression.addLazyFunction("while", 3, (c, t, lv) ->
|
||||
{
|
||||
long limit = NumericValue.asNumber(lv.get(1).evalValue(c)).getLong();
|
||||
|
||||
@@ -44,6 +44,7 @@ public class Operators {
|
||||
expression.addBinaryOperator("^", precedence.get("exponent^"), false, (v1, v2) ->
|
||||
new NumericValue(java.lang.Math.pow(NumericValue.asNumber(v1).getDouble(), NumericValue.asNumber(v2).getDouble())));
|
||||
|
||||
// lazy cause RHS is only conditional
|
||||
expression.addLazyBinaryOperator("&&", precedence.get("and&&"), false, (c, t, lv1, lv2) ->
|
||||
{
|
||||
Value v1 = lv1.evalValue(c, Context.BOOLEAN);
|
||||
@@ -51,6 +52,7 @@ public class Operators {
|
||||
return lv2;
|
||||
});
|
||||
|
||||
// lazy cause RHS is only conditional
|
||||
expression.addLazyBinaryOperator("||", precedence.get("or||"), false, (c, t, lv1, lv2) ->
|
||||
{
|
||||
Value v1 = lv1.evalValue(c, Context.BOOLEAN);
|
||||
@@ -73,6 +75,7 @@ public class Operators {
|
||||
expression.addBinaryOperator("!=", precedence.get("equal==!="), false, (v1, v2) ->
|
||||
v1.equals(v2) ? Value.FALSE : Value.TRUE);
|
||||
|
||||
// lazy cause of assignment which is non-trivial
|
||||
expression.addLazyBinaryOperator("=", precedence.get("assign=<>"), false, (c, t, lv1, lv2) ->
|
||||
{
|
||||
Value v1 = lv1.evalValue(c, Context.LVALUE);
|
||||
@@ -111,6 +114,7 @@ public class Operators {
|
||||
return boundedLHS;
|
||||
});
|
||||
|
||||
// lazy due to assignment
|
||||
expression.addLazyBinaryOperator("+=", precedence.get("assign=<>"), false, (c, t, lv1, lv2) ->
|
||||
{
|
||||
Value v1 = lv1.evalValue(c, Context.LVALUE);
|
||||
@@ -171,10 +175,8 @@ public class Operators {
|
||||
return boundedLHS;
|
||||
});
|
||||
|
||||
expression.addLazyBinaryOperator("<>", precedence.get("assign=<>"), false, (c, t, lv1, lv2) ->
|
||||
expression.addBinaryContextOperator("<>", precedence.get("assign=<>"), false, (c, t, v1, v2) ->
|
||||
{
|
||||
Value v1 = lv1.evalValue(c);
|
||||
Value v2 = lv2.evalValue(c);
|
||||
if (v1 instanceof ListValue.ListConstructorValue && v2 instanceof ListValue.ListConstructorValue)
|
||||
{
|
||||
List<Value> ll = ((ListValue)v1).getItems();
|
||||
@@ -196,7 +198,7 @@ public class Operators {
|
||||
expression.setAnyVariable(c, lname, (cc, tt) -> rval);
|
||||
expression.setAnyVariable(c, rname, (cc, tt) -> lval);
|
||||
}
|
||||
return (cc, tt) -> Value.TRUE;
|
||||
return Value.TRUE;
|
||||
}
|
||||
v1.assertAssignable();
|
||||
v2.assertAssignable();
|
||||
@@ -206,13 +208,14 @@ public class Operators {
|
||||
Value rval = v1.reboundedTo(rvalvar);
|
||||
expression.setAnyVariable(c, lvalvar, (cc, tt) -> lval);
|
||||
expression.setAnyVariable(c, rvalvar, (cc, tt) -> rval);
|
||||
return (cc, tt) -> lval;
|
||||
return lval;
|
||||
});
|
||||
|
||||
expression.addUnaryOperator("-", false, v -> NumericValue.asNumber(v).opposite());
|
||||
|
||||
expression.addUnaryOperator("+", false, NumericValue::asNumber);
|
||||
|
||||
// could be non-lazy, but who cares - its a small one.
|
||||
expression.addLazyUnaryOperator("!", precedence.get("unary+-!"), false, (c, t, lv)-> lv.evalValue(c, Context.BOOLEAN).getBoolean() ? (cc, tt)-> Value.FALSE : (cc, tt) -> Value.TRUE); // might need context boolean
|
||||
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import carpet.script.ScriptHost;
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
import carpet.script.utils.PerlinNoiseSampler;
|
||||
import carpet.script.utils.SimplexNoiseSampler;
|
||||
import carpet.script.value.BooleanValue;
|
||||
import carpet.script.value.FunctionValue;
|
||||
import carpet.script.value.ListValue;
|
||||
import carpet.script.value.NullValue;
|
||||
@@ -37,19 +38,15 @@ public class Sys {
|
||||
|
||||
expression.addUnaryFunction("copy", Value::deepcopy);
|
||||
|
||||
expression.addLazyFunction("bool", 1, (c, t, lv) ->
|
||||
expression.addTypedContextFunction("bool", 1, Context.BOOLEAN, (c, t, lv) ->
|
||||
{
|
||||
Value v = lv.get(0).evalValue(c, Context.BOOLEAN);
|
||||
Value v = lv.get(0);
|
||||
if (v instanceof StringValue)
|
||||
{
|
||||
String str = v.getString();
|
||||
if ("false".equalsIgnoreCase(str) || "null".equalsIgnoreCase(str))
|
||||
{
|
||||
return (cc, tt) -> Value.FALSE;
|
||||
}
|
||||
String str = v.getString().toLowerCase(Locale.ROOT);
|
||||
if ("false".equals(str) || "null".equals(str)) return Value.FALSE;
|
||||
}
|
||||
Value retval = v.getBoolean()?Value.TRUE:Value.FALSE;
|
||||
return (cc, tt) -> retval;
|
||||
return BooleanValue.of(v.getBoolean());
|
||||
});
|
||||
|
||||
expression.addUnaryFunction("number", v ->
|
||||
@@ -187,45 +184,40 @@ public class Sys {
|
||||
|
||||
expression.addUnaryFunction("type", v -> new StringValue(v.getTypeString()));
|
||||
expression.addUnaryFunction("length", v -> new NumericValue(v.length()));
|
||||
expression.addLazyFunction("rand", -1, (c, t, lv) ->
|
||||
expression.addContextFunction("rand", -1, (c, t, lv) ->
|
||||
{
|
||||
int argsize = lv.size();
|
||||
Random randomizer = Sys.randomizer;
|
||||
if (argsize != 1 && argsize != 2)
|
||||
throw new InternalExpressionException("'rand' takes one (range) or two arguments (range and seed)");
|
||||
if (argsize == 2) randomizer = c.host.getRandom(NumericValue.asNumber(lv.get(1).evalValue(c)).getLong());
|
||||
Value argument = lv.get(0).evalValue(c);
|
||||
if (argsize == 2) randomizer = c.host.getRandom(NumericValue.asNumber(lv.get(1)).getLong());
|
||||
Value argument = lv.get(0);
|
||||
if (argument instanceof ListValue)
|
||||
{
|
||||
List<Value> list = ((ListValue) argument).getItems();
|
||||
Value retval = list.get(randomizer.nextInt(list.size()));
|
||||
return (cc, tt) -> retval;
|
||||
return list.get(randomizer.nextInt(list.size()));
|
||||
}
|
||||
double value = NumericValue.asNumber(argument).getDouble()*randomizer.nextDouble();
|
||||
if (t == Context.BOOLEAN)
|
||||
{
|
||||
double rv = NumericValue.asNumber(argument).getDouble()*randomizer.nextFloat();
|
||||
Value retval = rv<1.0D?Value.FALSE:Value.TRUE;
|
||||
return (cc, tt) -> retval;
|
||||
}
|
||||
Value retval = new NumericValue(NumericValue.asNumber(argument).getDouble()*randomizer.nextDouble());
|
||||
return (cc, tt) -> retval;
|
||||
return BooleanValue.of(value >= 1.0D);
|
||||
return new NumericValue(value);
|
||||
});
|
||||
expression.addLazyFunction("reset_seed", 1, (c, t, lv) -> {
|
||||
boolean gotIt = c.host.resetRandom(NumericValue.asNumber(lv.get(0).evalValue(c)).getLong());
|
||||
return gotIt?LazyValue.TRUE:LazyValue.FALSE;
|
||||
expression.addContextFunction("reset_seed", 1, (c, t, lv) -> {
|
||||
boolean gotIt = c.host.resetRandom(NumericValue.asNumber(lv.get(0)).getLong());
|
||||
return BooleanValue.of(gotIt);
|
||||
});
|
||||
|
||||
expression.addLazyFunction("perlin", -1, (c, t, lv) ->
|
||||
expression.addFunction("perlin", lv ->
|
||||
{
|
||||
PerlinNoiseSampler sampler;
|
||||
Value x, y, z;
|
||||
|
||||
if (lv.size() >= 4)
|
||||
{
|
||||
x = lv.get(0).evalValue(c);
|
||||
y = lv.get(1).evalValue(c);
|
||||
z = lv.get(2).evalValue(c);
|
||||
sampler = PerlinNoiseSampler.getPerlin(NumericValue.asNumber(lv.get(3).evalValue(c)).getLong());
|
||||
x = lv.get(0);
|
||||
y = lv.get(1);
|
||||
z = lv.get(2);
|
||||
sampler = PerlinNoiseSampler.getPerlin(NumericValue.asNumber(lv.get(3)).getLong());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -234,12 +226,12 @@ public class Sys {
|
||||
z = Value.NULL;
|
||||
if (lv.size() == 0 )
|
||||
throw new InternalExpressionException("'perlin' requires at least one dimension to sample from");
|
||||
x = NumericValue.asNumber(lv.get(0).evalValue(c));
|
||||
x = NumericValue.asNumber(lv.get(0));
|
||||
if (lv.size() > 1)
|
||||
{
|
||||
y = NumericValue.asNumber(lv.get(1).evalValue(c));
|
||||
y = NumericValue.asNumber(lv.get(1));
|
||||
if (lv.size() > 2)
|
||||
z = NumericValue.asNumber(lv.get(2).evalValue(c));
|
||||
z = NumericValue.asNumber(lv.get(2));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,21 +247,20 @@ public class Sys {
|
||||
NumericValue.asNumber(x).getDouble(),
|
||||
NumericValue.asNumber(y).getDouble(),
|
||||
NumericValue.asNumber(z).getDouble());
|
||||
Value ret = new NumericValue(result);
|
||||
return (cc, tt) -> ret;
|
||||
return new NumericValue(result);
|
||||
});
|
||||
|
||||
expression.addLazyFunction("simplex", -1, (c, t, lv) ->
|
||||
expression.addFunction("simplex", lv ->
|
||||
{
|
||||
SimplexNoiseSampler sampler;
|
||||
Value x, y, z;
|
||||
|
||||
if (lv.size() >= 4)
|
||||
{
|
||||
x = lv.get(0).evalValue(c);
|
||||
y = lv.get(1).evalValue(c);
|
||||
z = lv.get(2).evalValue(c);
|
||||
sampler = SimplexNoiseSampler.getSimplex(NumericValue.asNumber(lv.get(3).evalValue(c)).getLong());
|
||||
x = lv.get(0);
|
||||
y = lv.get(1);
|
||||
z = lv.get(2);
|
||||
sampler = SimplexNoiseSampler.getSimplex(NumericValue.asNumber(lv.get(3)).getLong());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -277,10 +268,10 @@ public class Sys {
|
||||
z = Value.NULL;
|
||||
if (lv.size() < 2 )
|
||||
throw new InternalExpressionException("'simplex' requires at least two dimensions to sample from");
|
||||
x = NumericValue.asNumber(lv.get(0).evalValue(c));
|
||||
y = NumericValue.asNumber(lv.get(1).evalValue(c));
|
||||
x = NumericValue.asNumber(lv.get(0));
|
||||
y = NumericValue.asNumber(lv.get(1));
|
||||
if (lv.size() > 2)
|
||||
z = NumericValue.asNumber(lv.get(2).evalValue(c));
|
||||
z = NumericValue.asNumber(lv.get(2));
|
||||
}
|
||||
double result;
|
||||
|
||||
@@ -291,8 +282,7 @@ public class Sys {
|
||||
NumericValue.asNumber(x).getDouble(),
|
||||
NumericValue.asNumber(y).getDouble(),
|
||||
NumericValue.asNumber(z).getDouble());
|
||||
Value ret = new NumericValue(result);
|
||||
return (cc, tt) -> ret;
|
||||
return new NumericValue(result);
|
||||
});
|
||||
|
||||
expression.addUnaryFunction("print", (v) ->
|
||||
@@ -301,17 +291,11 @@ public class Sys {
|
||||
return v; // pass through for variables
|
||||
});
|
||||
|
||||
expression.addLazyFunction("time", 0, (c, t, lv) ->
|
||||
{
|
||||
Value time = new NumericValue((System.nanoTime() / 1000) / 1000.0);
|
||||
return (cc, tt) -> time;
|
||||
});
|
||||
expression.addContextFunction("time", 0, (c, t, lv) ->
|
||||
new NumericValue((System.nanoTime() / 1000.0) / 1000.0));
|
||||
|
||||
expression.addLazyFunction("unix_time", 0, (c, t, lv) ->
|
||||
{
|
||||
Value time = new NumericValue(System.currentTimeMillis());
|
||||
return (cc, tt) -> time;
|
||||
});
|
||||
expression.addContextFunction("unix_time", 0, (c, t, lv) ->
|
||||
new NumericValue(System.currentTimeMillis()));
|
||||
|
||||
expression.addFunction("convert_date", lv ->
|
||||
{
|
||||
@@ -324,7 +308,7 @@ public class Sys {
|
||||
cal.setTimeInMillis(NumericValue.asNumber(value, "timestamp").getLong());
|
||||
int weekday = cal.get(Calendar.DAY_OF_WEEK)-1;
|
||||
if (weekday == 0) weekday = 7;
|
||||
Value retVal = ListValue.ofNums(
|
||||
return ListValue.ofNums(
|
||||
cal.get(Calendar.YEAR),
|
||||
cal.get(Calendar.MONTH)+1,
|
||||
cal.get(Calendar.DAY_OF_MONTH),
|
||||
@@ -335,7 +319,6 @@ public class Sys {
|
||||
cal.get(Calendar.DAY_OF_YEAR),
|
||||
cal.get(Calendar.WEEK_OF_YEAR)
|
||||
);
|
||||
return retVal;
|
||||
}
|
||||
else if(value instanceof ListValue)
|
||||
{
|
||||
@@ -367,6 +350,7 @@ public class Sys {
|
||||
return new NumericValue(cal.getTimeInMillis());
|
||||
});
|
||||
|
||||
// lazy cause evaluates expression multiple times
|
||||
expression.addLazyFunction("profile_expr", 1, (c, t, lv) ->
|
||||
{
|
||||
LazyValue lazy = lv.get(0);
|
||||
@@ -381,19 +365,16 @@ public class Sys {
|
||||
return (cc, tt) -> res;
|
||||
});
|
||||
|
||||
expression.addLazyFunction("var", 1, (c, t, lv) ->
|
||||
{
|
||||
String varname = lv.get(0).evalValue(c).getString();
|
||||
return expression.getOrSetAnyVariable(c, varname);
|
||||
});
|
||||
expression.addContextFunction("var", 1, (c, t, lv) ->
|
||||
expression.getOrSetAnyVariable(c, lv.get(0).getString()).evalValue(c));
|
||||
|
||||
expression.addLazyFunction("undef", 1, (c, t, lv) ->
|
||||
expression.addContextFunction("undef", 1, (c, t, lv) ->
|
||||
{
|
||||
Value remove = lv.get(0).evalValue(c);
|
||||
Value remove = lv.get(0);
|
||||
if (remove instanceof FunctionValue)
|
||||
{
|
||||
c.host.delFunction(expression.module, remove.getString());
|
||||
return (cc, tt) -> Value.NULL;
|
||||
return Value.NULL;
|
||||
}
|
||||
String varname = remove.getString();
|
||||
boolean isPrefix = varname.endsWith("*");
|
||||
@@ -423,13 +404,13 @@ public class Sys {
|
||||
c.delVariable(varname);
|
||||
}
|
||||
}
|
||||
return (cc, tt) -> Value.NULL;
|
||||
return Value.NULL;
|
||||
});
|
||||
|
||||
//deprecate
|
||||
expression.addLazyFunction("vars", 1, (c, t, lv) ->
|
||||
expression.addContextFunction("vars", 1, (c, t, lv) ->
|
||||
{
|
||||
String prefix = lv.get(0).evalValue(c).getString();
|
||||
String prefix = lv.get(0).getString();
|
||||
List<Value> values = new ArrayList<>();
|
||||
if (prefix.startsWith("global"))
|
||||
{
|
||||
@@ -439,30 +420,25 @@ public class Sys {
|
||||
{
|
||||
c.getAllVariableNames().stream().filter(s -> s.startsWith(prefix)).forEach(s -> values.add(new StringValue(s)));
|
||||
}
|
||||
Value retval = ListValue.wrap(values);
|
||||
return (cc, tt) -> retval;
|
||||
return ListValue.wrap(values);
|
||||
});
|
||||
|
||||
// lazy cause default expression may not be executed if not needed
|
||||
expression.addLazyFunction("system_variable_get", -1, (c, t, lv) ->
|
||||
{
|
||||
if (lv.size() == 0) throw new InternalExpressionException("'system_variable_get' expects at least a key to be fetched");
|
||||
Value key = lv.get(0).evalValue(c);
|
||||
if (lv.size() > 1)
|
||||
{
|
||||
ScriptHost.systemGlobals.computeIfAbsent(key, k -> lv.get(1).evalValue(c));
|
||||
}
|
||||
if (lv.size() > 1) ScriptHost.systemGlobals.computeIfAbsent(key, k -> lv.get(1).evalValue(c));
|
||||
Value res = ScriptHost.systemGlobals.get(key);
|
||||
if (res!=null) return (cc, tt) -> res;
|
||||
return (cc, tt) -> Value.NULL;
|
||||
return LazyValue.NULL;
|
||||
});
|
||||
|
||||
expression.addLazyFunction("system_variable_set", 2, (c, t, lv) ->
|
||||
expression.addBinaryFunction("system_variable_set", (key, value) ->
|
||||
{
|
||||
Value key = lv.get(0).evalValue(c);
|
||||
Value value = lv.get(1).evalValue(c);
|
||||
Value res = ScriptHost.systemGlobals.put(key, value);
|
||||
if (res!=null) return (cc, tt) -> res;
|
||||
return (cc, tt) -> Value.NULL;
|
||||
if (res!=null) return res;
|
||||
return Value.NULL;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,9 @@
|
||||
package carpet.script.language;
|
||||
|
||||
import carpet.script.Expression;
|
||||
import carpet.script.LazyValue;
|
||||
import carpet.script.argument.FunctionArgument;
|
||||
import carpet.script.exception.ExitStatement;
|
||||
import carpet.script.exception.InternalExpressionException;
|
||||
import carpet.script.value.FunctionValue;
|
||||
import carpet.script.value.NumericValue;
|
||||
import carpet.script.value.ThreadValue;
|
||||
import carpet.script.value.Value;
|
||||
@@ -14,35 +12,30 @@ public class Threading
|
||||
{
|
||||
public static void apply(Expression expression)
|
||||
{
|
||||
expression.addLazyFunctionWithDelegation("task", -1, (c, t, expr, tok, lv) ->
|
||||
expression.addFunctionWithDelegation("task", -1, (c, t, expr, tok, lv) ->
|
||||
{
|
||||
if (lv.size() == 0)
|
||||
throw new InternalExpressionException("'task' requires at least function to call as a parameter");
|
||||
FunctionArgument<LazyValue> functionArgument = FunctionArgument.findIn(c, expression.module, lv, 0, false, true);
|
||||
ThreadValue thread = new ThreadValue(Value.NULL, functionArgument.function, expr, tok, c, functionArgument.unpackArgs(c));
|
||||
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 0, false, true);
|
||||
ThreadValue thread = new ThreadValue(Value.NULL, functionArgument.function, expr, tok, c, functionArgument.checkedArgs());
|
||||
Thread.yield();
|
||||
return (cc, tt) -> thread;
|
||||
return thread;
|
||||
});
|
||||
|
||||
expression.addLazyFunctionWithDelegation("task_thread", -1, (c, t, expr, tok, lv) ->
|
||||
expression.addFunctionWithDelegation("task_thread", -1, (c, t, expr, tok, lv) ->
|
||||
{
|
||||
if (lv.size() < 2)
|
||||
throw new InternalExpressionException("'task' requires at least function to call as a parameter");
|
||||
Value queue = lv.get(0).evalValue(c);
|
||||
FunctionArgument<LazyValue> functionArgument = FunctionArgument.findIn(c, expression.module, lv, 1, false, true);
|
||||
ThreadValue thread = new ThreadValue(queue, functionArgument.function, expr, tok, c, functionArgument.unpackArgs(c));
|
||||
Value queue = lv.get(0);
|
||||
FunctionArgument functionArgument = FunctionArgument.findIn(c, expression.module, lv, 1, false, true);
|
||||
ThreadValue thread = new ThreadValue(queue, functionArgument.function, expr, tok, c, functionArgument.checkedArgs());
|
||||
Thread.yield();
|
||||
return (cc, tt) -> thread;
|
||||
return thread;
|
||||
});
|
||||
|
||||
|
||||
expression.addLazyFunction("task_count", -1, (c, t, lv) ->
|
||||
{
|
||||
Value ret = (lv.size() > 0)?
|
||||
new NumericValue(c.host.taskCount(lv.get(0).evalValue(c))):
|
||||
new NumericValue(c.host.taskCount());
|
||||
return (cc, tt) -> ret;
|
||||
});
|
||||
expression.addContextFunction("task_count", -1, (c, t, lv) ->
|
||||
(lv.size() > 0)? new NumericValue(c.host.taskCount(lv.get(0))):new NumericValue(c.host.taskCount()));
|
||||
|
||||
expression.addUnaryFunction("task_value", (v) ->
|
||||
{
|
||||
@@ -72,6 +65,7 @@ public class Threading
|
||||
return new NumericValue(((ThreadValue) v).isFinished());
|
||||
});
|
||||
|
||||
// lazy cause expr is evaluated in the same type
|
||||
expression.addLazyFunction("synchronize", -1, (c, t, lv) ->
|
||||
{
|
||||
if (lv.size() == 0) throw new InternalExpressionException("'synchronize' require at least an expression to synchronize");
|
||||
@@ -89,6 +83,7 @@ public class Threading
|
||||
}
|
||||
});
|
||||
|
||||
// lazy since exception expression is very conditional
|
||||
expression.addLazyFunction("sleep", -1, (c, t, lv) ->
|
||||
{
|
||||
long time = lv.isEmpty()?0L:NumericValue.asNumber(lv.get(0).evalValue(c)).getLong();
|
||||
|
||||
Reference in new issue
Block a user