refactored and reworked functions in scarpet
This commit is contained in:
1 parent
3feb7bffbb
commit
95b85928f9
17 files changed
+360
-218
No files matched your search
@@ -2,7 +2,7 @@ package carpet.fakes;
|
|||||||
|
|
||||||
import carpet.script.CarpetContext;
|
import carpet.script.CarpetContext;
|
||||||
import carpet.script.CarpetEventServer;
|
import carpet.script.CarpetEventServer;
|
||||||
import carpet.script.ScriptHost;
|
import carpet.script.value.FunctionValue;
|
||||||
import carpet.script.value.Value;
|
import carpet.script.value.Value;
|
||||||
import net.minecraft.entity.damage.DamageSource;
|
import net.minecraft.entity.damage.DamageSource;
|
||||||
|
|
||||||
@@ -13,10 +13,10 @@ public interface EntityInterface
|
|||||||
float getMainYaw(float partialTicks);
|
float getMainYaw(float partialTicks);
|
||||||
//scarpet part
|
//scarpet part
|
||||||
void onDeathCallback(String reason);
|
void onDeathCallback(String reason);
|
||||||
void setDeathCallback(CarpetContext cc, String function, List<Value> extraArgs);
|
void setDeathCallback(CarpetContext cc, FunctionValue function, List<Value> extraArgs);
|
||||||
void onDamageCallback(float amount, DamageSource source);
|
void onDamageCallback(float amount, DamageSource source);
|
||||||
void setDamageCallback(CarpetContext cc, String function, List<Value> extraArgs);
|
void setDamageCallback(CarpetContext cc, FunctionValue function, List<Value> extraArgs);
|
||||||
void setRemovedCallback(CarpetContext cc, String function, List<Value> extraArgs);
|
void setRemovedCallback(CarpetContext cc, FunctionValue function, List<Value> extraArgs);
|
||||||
void setTickCallback(CarpetContext cc, String function, List<Value> extraArgs);
|
void setTickCallback(CarpetContext cc, FunctionValue function, List<Value> extraArgs);
|
||||||
CarpetEventServer.ScheduledCall getTickCallback();
|
CarpetEventServer.ScheduledCall getTickCallback();
|
||||||
}
|
}
|
||||||
@@ -4,12 +4,10 @@ import carpet.CarpetServer;
|
|||||||
import carpet.fakes.EntityInterface;
|
import carpet.fakes.EntityInterface;
|
||||||
import carpet.script.CarpetContext;
|
import carpet.script.CarpetContext;
|
||||||
import carpet.script.CarpetEventServer;
|
import carpet.script.CarpetEventServer;
|
||||||
import carpet.script.ScriptHost;
|
import carpet.script.value.FunctionValue;
|
||||||
import carpet.script.value.Value;
|
import carpet.script.value.Value;
|
||||||
import carpet.settings.CarpetSettings;
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.damage.DamageSource;
|
import net.minecraft.entity.damage.DamageSource;
|
||||||
import org.lwjgl.system.CallbackI;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
@@ -27,23 +25,20 @@ public abstract class Entity_scarpetEventsMixin implements EntityInterface
|
|||||||
private CarpetEventServer.ScheduledCall tickCall;
|
private CarpetEventServer.ScheduledCall tickCall;
|
||||||
private CarpetEventServer.ScheduledCall damageCall;
|
private CarpetEventServer.ScheduledCall damageCall;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDeathCallback(CarpetContext cc, String function, List<Value> extraArgs)
|
public void setDeathCallback(CarpetContext cc, FunctionValue function, List<Value> extraArgs)
|
||||||
{
|
{
|
||||||
deathCall = CarpetServer.scriptServer.events.makeDeathCall(cc, function, extraArgs);
|
deathCall = CarpetServer.scriptServer.events.makeDeathCall(cc, function, extraArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setRemovedCallback(CarpetContext cc, String function, List<Value> extraArgs)
|
public void setRemovedCallback(CarpetContext cc, FunctionValue function, List<Value> extraArgs)
|
||||||
{
|
{
|
||||||
removeCall = CarpetServer.scriptServer.events.makeRemovedCall(cc, function, extraArgs);
|
removeCall = CarpetServer.scriptServer.events.makeRemovedCall(cc, function, extraArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setTickCallback(CarpetContext cc, String function, List<Value> extraArgs)
|
public void setTickCallback(CarpetContext cc, FunctionValue function, List<Value> extraArgs)
|
||||||
{
|
{
|
||||||
tickCall = CarpetServer.scriptServer.events.makeTickCall(cc, function, extraArgs);
|
tickCall = CarpetServer.scriptServer.events.makeTickCall(cc, function, extraArgs);
|
||||||
}
|
}
|
||||||
@@ -55,7 +50,7 @@ public abstract class Entity_scarpetEventsMixin implements EntityInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setDamageCallback(CarpetContext cc, String function, List<Value> extraArgs)
|
public void setDamageCallback(CarpetContext cc, FunctionValue function, List<Value> extraArgs)
|
||||||
{
|
{
|
||||||
damageCall = CarpetServer.scriptServer.events.makeDamageCall(cc, function, extraArgs);
|
damageCall = CarpetServer.scriptServer.events.makeDamageCall(cc, function, extraArgs);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package carpet.script;
|
|||||||
import carpet.CarpetServer;
|
import carpet.CarpetServer;
|
||||||
import carpet.script.value.BlockValue;
|
import carpet.script.value.BlockValue;
|
||||||
import carpet.script.value.EntityValue;
|
import carpet.script.value.EntityValue;
|
||||||
|
import carpet.script.value.FunctionValue;
|
||||||
import carpet.script.value.ListValue;
|
import carpet.script.value.ListValue;
|
||||||
import carpet.script.value.NumericValue;
|
import carpet.script.value.NumericValue;
|
||||||
import carpet.script.value.StringValue;
|
import carpet.script.value.StringValue;
|
||||||
@@ -19,6 +20,7 @@ import net.minecraft.util.math.BlockPos;
|
|||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.dimension.DimensionType;
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -39,9 +41,9 @@ public class CarpetEventServer
|
|||||||
public static class Callback
|
public static class Callback
|
||||||
{
|
{
|
||||||
public String host;
|
public String host;
|
||||||
public String udf;
|
public FunctionValue udf;
|
||||||
|
|
||||||
public Callback(String host, String udf)
|
public Callback(String host, FunctionValue udf)
|
||||||
{
|
{
|
||||||
this.host = host;
|
this.host = host;
|
||||||
this.udf = udf;
|
this.udf = udf;
|
||||||
@@ -50,7 +52,7 @@ public class CarpetEventServer
|
|||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return udf+((host==null)?"":"(from "+host+")");
|
return udf.getString()+((host==null)?"":"(from "+host+")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +63,7 @@ public class CarpetEventServer
|
|||||||
public BlockPos context_origin;
|
public BlockPos context_origin;
|
||||||
public long dueTime;
|
public long dueTime;
|
||||||
|
|
||||||
public ScheduledCall(CarpetContext context, String udf, List<LazyValue> args, long dueTime)
|
public ScheduledCall(CarpetContext context, FunctionValue udf, List<LazyValue> args, long dueTime)
|
||||||
{
|
{
|
||||||
super(context.host.getName(), udf);
|
super(context.host.getName(), udf);
|
||||||
this.args = args;
|
this.args = args;
|
||||||
@@ -119,7 +121,7 @@ public class CarpetEventServer
|
|||||||
// impossible call to add
|
// impossible call to add
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
UserDefinedFunction udf = host.globalFunctions.get(funName);
|
FunctionValue udf = host.globalFunctions.get(funName);
|
||||||
if (udf == null || udf.getArguments().size() != reqArgs)
|
if (udf == null || udf.getArguments().size() != reqArgs)
|
||||||
{
|
{
|
||||||
// call won't match arguments
|
// call won't match arguments
|
||||||
@@ -127,13 +129,13 @@ public class CarpetEventServer
|
|||||||
}
|
}
|
||||||
//all clear
|
//all clear
|
||||||
//remove duplicates
|
//remove duplicates
|
||||||
removeEventCall(hostName, funName);
|
removeEventCall(hostName, udf.getString());
|
||||||
callList.add(new Callback(hostName, funName));
|
callList.add(new Callback(hostName, udf));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
public void removeEventCall(String hostName, String callName)
|
public void removeEventCall(String hostName, String funName)
|
||||||
{
|
{
|
||||||
callList.removeIf((c)-> c.udf.equalsIgnoreCase(callName) && ( hostName == null || c.host.equalsIgnoreCase(hostName) ) );
|
callList.removeIf((c)-> c.udf.getString().equals(funName) && ( hostName == null || c.host.equalsIgnoreCase(hostName) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeAllCalls(String hostName)
|
public void removeAllCalls(String hostName)
|
||||||
@@ -445,7 +447,7 @@ public class CarpetEventServer
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
public void scheduleCall(CarpetContext context, String function, List<LazyValue> args, long due)
|
public void scheduleCall(CarpetContext context, FunctionValue function, List<LazyValue> args, long due)
|
||||||
{
|
{
|
||||||
scheduledCalls.add(new ScheduledCall(context, function, args, due));
|
scheduledCalls.add(new ScheduledCall(context, function, args, due));
|
||||||
}
|
}
|
||||||
@@ -464,8 +466,8 @@ public class CarpetEventServer
|
|||||||
|
|
||||||
if (!Event.byName.containsKey(event))
|
if (!Event.byName.containsKey(event))
|
||||||
return false;
|
return false;
|
||||||
Callback callback= decodeCallback(funName);
|
Pair<String,String> call = decodeCallback(funName);
|
||||||
Event.byName.get(event).handler.removeEventCall(callback.host, callback.udf);
|
Event.byName.get(event).handler.removeEventCall(call.getLeft(), call.getRight());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -474,21 +476,20 @@ public class CarpetEventServer
|
|||||||
Event.byName.values().forEach((e) -> e.handler.removeAllCalls(hostName));
|
Event.byName.values().forEach((e) -> e.handler.removeAllCalls(hostName));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Callback decodeCallback(String funName)
|
private Pair<String,String> decodeCallback(String funName)
|
||||||
{
|
{
|
||||||
Pattern find = Pattern.compile("(\\w+)\\(from (\\w+)\\)");
|
Pattern find = Pattern.compile("(\\w+)\\(from (\\w+)\\)");
|
||||||
Matcher matcher = find.matcher(funName);
|
Matcher matcher = find.matcher(funName);
|
||||||
if(matcher.matches())
|
if(matcher.matches())
|
||||||
{
|
{
|
||||||
return new Callback(matcher.group(2), matcher.group(1));
|
return Pair.of(matcher.group(2), matcher.group(1));
|
||||||
}
|
}
|
||||||
return new Callback(null, funName);
|
return Pair.of(null, funName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ScheduledCall makeEventCall(CarpetContext cc, String function, List<Value> extraArgs, int argCount)
|
private ScheduledCall makeEventCall(CarpetContext cc, FunctionValue function, List<Value> extraArgs, int argCount)
|
||||||
{
|
{
|
||||||
UserDefinedFunction udf = cc.host.globalFunctions.get(function);
|
if (function == null || (function.getArguments().size()-(extraArgs == null ? 0 : extraArgs.size())) != argCount)
|
||||||
if (udf == null || (udf.getArguments().size()-(extraArgs == null ? 0 : extraArgs.size())) != argCount)
|
|
||||||
{
|
{
|
||||||
// call won't match arguments
|
// call won't match arguments
|
||||||
return null;
|
return null;
|
||||||
@@ -503,19 +504,19 @@ public class CarpetEventServer
|
|||||||
return new ScheduledCall(cc, function, lazyArgs, 0);
|
return new ScheduledCall(cc, function, lazyArgs, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScheduledCall makeDeathCall(CarpetContext cc, String function, List<Value> extraArgs)
|
public ScheduledCall makeDeathCall(CarpetContext cc, FunctionValue function, List<Value> extraArgs)
|
||||||
{
|
{
|
||||||
return makeEventCall(cc, function, extraArgs, 2);
|
return makeEventCall(cc, function, extraArgs, 2);
|
||||||
}
|
}
|
||||||
public ScheduledCall makeRemovedCall(CarpetContext cc, String function, List<Value> extraArgs)
|
public ScheduledCall makeRemovedCall(CarpetContext cc, FunctionValue function, List<Value> extraArgs)
|
||||||
{
|
{
|
||||||
return makeEventCall(cc, function, extraArgs, 1);
|
return makeEventCall(cc, function, extraArgs, 1);
|
||||||
}
|
}
|
||||||
public ScheduledCall makeTickCall(CarpetContext cc, String function, List<Value> extraArgs)
|
public ScheduledCall makeTickCall(CarpetContext cc, FunctionValue function, List<Value> extraArgs)
|
||||||
{
|
{
|
||||||
return makeEventCall(cc, function, extraArgs, 1);
|
return makeEventCall(cc, function, extraArgs, 1);
|
||||||
}
|
}
|
||||||
public ScheduledCall makeDamageCall(CarpetContext cc, String function, List<Value> extraArgs)
|
public ScheduledCall makeDamageCall(CarpetContext cc, FunctionValue function, List<Value> extraArgs)
|
||||||
{
|
{
|
||||||
return makeEventCall(cc, function, extraArgs, 4);
|
return makeEventCall(cc, function, extraArgs, 4);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,12 @@ import carpet.fakes.MinecraftServerInterface;
|
|||||||
import carpet.helpers.FeatureGenerator;
|
import carpet.helpers.FeatureGenerator;
|
||||||
import carpet.script.Fluff.TriFunction;
|
import carpet.script.Fluff.TriFunction;
|
||||||
import carpet.script.exception.CarpetExpressionException;
|
import carpet.script.exception.CarpetExpressionException;
|
||||||
|
import carpet.script.exception.ExitStatement;
|
||||||
import carpet.script.exception.ExpressionException;
|
import carpet.script.exception.ExpressionException;
|
||||||
import carpet.script.exception.InternalExpressionException;
|
import carpet.script.exception.InternalExpressionException;
|
||||||
import carpet.script.value.BlockValue;
|
import carpet.script.value.BlockValue;
|
||||||
import carpet.script.value.EntityValue;
|
import carpet.script.value.EntityValue;
|
||||||
|
import carpet.script.value.FunctionValue;
|
||||||
import carpet.script.value.LazyListValue;
|
import carpet.script.value.LazyListValue;
|
||||||
import carpet.script.value.ListValue;
|
import carpet.script.value.ListValue;
|
||||||
import carpet.script.value.NBTSerializableValue;
|
import carpet.script.value.NBTSerializableValue;
|
||||||
@@ -2012,9 +2014,16 @@ public class CarpetExpression
|
|||||||
throw new InternalExpressionException("First argument to entity_event should be an entity");
|
throw new InternalExpressionException("First argument to entity_event should be an entity");
|
||||||
String what = lv.get(1).evalValue(c).getString();
|
String what = lv.get(1).evalValue(c).getString();
|
||||||
Value functionValue = lv.get(2).evalValue(c);
|
Value functionValue = lv.get(2).evalValue(c);
|
||||||
String function = null;
|
if (functionValue instanceof NullValue)
|
||||||
if (!(functionValue instanceof NullValue))
|
functionValue = null;
|
||||||
function = functionValue.getString();
|
else if (!(functionValue instanceof FunctionValue))
|
||||||
|
{
|
||||||
|
String name = functionValue.getString();
|
||||||
|
functionValue = c.host.globalFunctions.get(name);
|
||||||
|
if (functionValue == null)
|
||||||
|
throw new InternalExpressionException("Function "+name+" is not defined yet");
|
||||||
|
}
|
||||||
|
FunctionValue function = (FunctionValue)functionValue;
|
||||||
List<Value> args = null;
|
List<Value> args = null;
|
||||||
if (lv.size()==4)
|
if (lv.size()==4)
|
||||||
args = Collections.singletonList(lv.get(3).evalValue(c));
|
args = Collections.singletonList(lv.get(3).evalValue(c));
|
||||||
@@ -2928,7 +2937,7 @@ public class CarpetExpression
|
|||||||
CarpetServer.scriptServer.tickStart = System.nanoTime(); // for the next tick
|
CarpetServer.scriptServer.tickStart = System.nanoTime(); // for the next tick
|
||||||
Thread.yield();
|
Thread.yield();
|
||||||
if(CarpetServer.scriptServer.stopAll)
|
if(CarpetServer.scriptServer.stopAll)
|
||||||
throw new Expression.ExitStatement(Value.NULL);
|
throw new ExitStatement(Value.NULL);
|
||||||
return (cc, tt) -> Value.TRUE;
|
return (cc, tt) -> Value.TRUE;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -3002,20 +3011,28 @@ public class CarpetExpression
|
|||||||
if (lv.size()<2)
|
if (lv.size()<2)
|
||||||
throw new InternalExpressionException("'schedule' should have at least 2 arguments, delay and call name");
|
throw new InternalExpressionException("'schedule' should have at least 2 arguments, delay and call name");
|
||||||
Long delay = NumericValue.asNumber(lv.get(0).evalValue(c)).getLong();
|
Long delay = NumericValue.asNumber(lv.get(0).evalValue(c)).getLong();
|
||||||
String funname = lv.get(1).evalValue(c).getString();
|
|
||||||
|
Value functionValue = lv.get(1).evalValue(c);
|
||||||
|
if (!(functionValue instanceof FunctionValue))
|
||||||
|
{
|
||||||
|
String name = functionValue.getString();
|
||||||
|
functionValue = c.host.globalFunctions.get(name);
|
||||||
|
if (functionValue == null)
|
||||||
|
throw new InternalExpressionException("Function "+name+" is not defined yet");
|
||||||
|
}
|
||||||
|
FunctionValue function = (FunctionValue)functionValue;
|
||||||
|
|
||||||
CarpetContext cc = (CarpetContext)c;
|
CarpetContext cc = (CarpetContext)c;
|
||||||
if (!cc.host.globalFunctions.containsKey(funname))
|
|
||||||
throw new InternalExpressionException("Function "+funname+" is not defined");
|
|
||||||
List<LazyValue> args = new ArrayList<>();
|
List<LazyValue> args = new ArrayList<>();
|
||||||
for (int i=2; i < lv.size(); i++)
|
for (int i=2; i < lv.size(); i++)
|
||||||
{
|
{
|
||||||
Value arg = lv.get(i).evalValue(cc);
|
Value arg = lv.get(i).evalValue(cc);
|
||||||
args.add( (_c, _t) -> arg);
|
args.add( (_c, _t) -> arg);
|
||||||
}
|
}
|
||||||
if (cc.host.globalFunctions.get(funname).getArguments().size() != args.size())
|
if (function.getArguments().size() != args.size())
|
||||||
throw new InternalExpressionException("Function "+funname+" takes "+
|
throw new InternalExpressionException("Function "+function.getString()+" takes "+
|
||||||
cc.host.globalFunctions.get(funname).getArguments().size()+" arguments, "+args.size()+" provided.");
|
function.getArguments().size()+" arguments, "+args.size()+" provided.");
|
||||||
CarpetServer.scriptServer.events.scheduleCall(cc, funname, args, delay);
|
CarpetServer.scriptServer.events.scheduleCall(cc, function, args, delay);
|
||||||
return (c_, t_) -> Value.TRUE;
|
return (c_, t_) -> Value.TRUE;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package carpet.script;
|
package carpet.script;
|
||||||
|
|
||||||
import carpet.script.bundled.BundledModule;
|
import carpet.script.bundled.BundledModule;
|
||||||
|
import carpet.script.value.FunctionValue;
|
||||||
import carpet.script.value.MapValue;
|
import carpet.script.value.MapValue;
|
||||||
import carpet.script.value.StringValue;
|
import carpet.script.value.StringValue;
|
||||||
import carpet.settings.CarpetSettings;
|
import carpet.settings.CarpetSettings;
|
||||||
@@ -365,19 +366,19 @@ public class CarpetScriptServer
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean runas(ServerCommandSource source, String hostname, String udf_name, List<LazyValue> argv)
|
public boolean runas(ServerCommandSource source, String hostname, FunctionValue udf, List<LazyValue> argv)
|
||||||
{
|
{
|
||||||
return runas(BlockPos.ORIGIN, source, hostname, udf_name, argv);
|
return runas(BlockPos.ORIGIN, source, hostname, udf, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean runas(BlockPos origin, ServerCommandSource source, String hostname, String udf_name, List<LazyValue> argv)
|
public boolean runas(BlockPos origin, ServerCommandSource source, String hostname, FunctionValue udf, List<LazyValue> argv)
|
||||||
{
|
{
|
||||||
ScriptHost host = globalHost;
|
ScriptHost host = globalHost;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (hostname != null)
|
if (hostname != null)
|
||||||
host = modules.get(hostname).retrieveForExecution(source);
|
host = modules.get(hostname).retrieveForExecution(source);
|
||||||
host.callUDF(origin, source, host.globalFunctions.get(udf_name), argv);
|
host.callUDF(origin, source, udf, argv);
|
||||||
}
|
}
|
||||||
catch (NullPointerException | InvalidCallbackException npe)
|
catch (NullPointerException | InvalidCallbackException npe)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class Context
|
|||||||
return host.globalVariables.get(name);
|
return host.globalVariables.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setVariable(String name, LazyValue lv)
|
public void setVariable(String name, LazyValue lv)
|
||||||
{
|
{
|
||||||
if (name.startsWith("global_"))
|
if (name.startsWith("global_"))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,11 +11,15 @@ import carpet.script.Fluff.QuadFunction;
|
|||||||
import carpet.script.Fluff.QuinnFunction;
|
import carpet.script.Fluff.QuinnFunction;
|
||||||
import carpet.script.Fluff.SexFunction;
|
import carpet.script.Fluff.SexFunction;
|
||||||
import carpet.script.Fluff.TriFunction;
|
import carpet.script.Fluff.TriFunction;
|
||||||
|
import carpet.script.exception.ExitStatement;
|
||||||
import carpet.script.exception.ExpressionException;
|
import carpet.script.exception.ExpressionException;
|
||||||
import carpet.script.exception.InternalExpressionException;
|
import carpet.script.exception.InternalExpressionException;
|
||||||
|
import carpet.script.exception.ReturnStatement;
|
||||||
|
import carpet.script.exception.ThrowStatement;
|
||||||
import carpet.script.value.AbstractListValue;
|
import carpet.script.value.AbstractListValue;
|
||||||
import carpet.script.value.ContainerValueInterface;
|
import carpet.script.value.ContainerValueInterface;
|
||||||
import carpet.script.value.FunctionSignatureValue;
|
import carpet.script.value.FunctionSignatureValue;
|
||||||
|
import carpet.script.value.FunctionValue;
|
||||||
import carpet.script.value.GlobalValue;
|
import carpet.script.value.GlobalValue;
|
||||||
import carpet.script.value.LContainerValue;
|
import carpet.script.value.LContainerValue;
|
||||||
import carpet.script.value.LazyListValue;
|
import carpet.script.value.LazyListValue;
|
||||||
@@ -389,31 +393,6 @@ public class Expression implements Cloneable
|
|||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Exception thrown to terminate execution mid expression (aka return statement) */
|
|
||||||
static class ExitStatement extends RuntimeException
|
|
||||||
{
|
|
||||||
Value retval;
|
|
||||||
ExitStatement(Value value)
|
|
||||||
{
|
|
||||||
retval = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static class ReturnStatement extends ExitStatement
|
|
||||||
{
|
|
||||||
|
|
||||||
ReturnStatement(Value value)
|
|
||||||
{
|
|
||||||
super(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static class ThrowStatement extends ExitStatement
|
|
||||||
{
|
|
||||||
ThrowStatement(Value value)
|
|
||||||
{
|
|
||||||
super(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static List<String> getExpressionSnippet(Tokenizer.Token token, Expression expr)
|
static List<String> getExpressionSnippet(Tokenizer.Token token, Expression expr)
|
||||||
{
|
{
|
||||||
@@ -679,22 +658,11 @@ public class Expression implements Cloneable
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
private void addContextFunction(Context context, String name, Expression expr, Tokenizer.Token token, List<String> arguments, List<String> globals, LazyValue code)
|
private FunctionValue addContextFunction(Context context, String name, Expression expr, Tokenizer.Token token, List<String> arguments, List<String> globals, LazyValue code)
|
||||||
{
|
{
|
||||||
name = name.toLowerCase(Locale.ROOT);
|
name = name.toLowerCase(Locale.ROOT);
|
||||||
if (functions.containsKey(name))
|
if (functions.containsKey(name))
|
||||||
throw new ExpressionException(expr, token, "Function "+name+" would mask a built-in function");
|
throw new ExpressionException(expr, token, "Function "+name+" would mask a built-in function");
|
||||||
Expression function_context;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
function_context = expr.clone();
|
|
||||||
function_context.name = name;
|
|
||||||
}
|
|
||||||
catch (CloneNotSupportedException e)
|
|
||||||
{
|
|
||||||
throw new ExpressionException(expr, token, "Problems in allocating global function "+name);
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, LazyValue> contextValues = new HashMap<>();
|
Map<String, LazyValue> contextValues = new HashMap<>();
|
||||||
for (String global : globals)
|
for (String global : globals)
|
||||||
{
|
{
|
||||||
@@ -708,67 +676,12 @@ public class Expression implements Cloneable
|
|||||||
contextValues.put(global, lv);
|
contextValues.put(global, lv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (contextValues.isEmpty()) contextValues = null;
|
||||||
|
|
||||||
context.host.globalFunctions.put(name, new UserDefinedFunction(arguments, function_context, token)
|
FunctionValue result = new FunctionValue(expr, token, name, code, arguments, contextValues);
|
||||||
{
|
// do not store lambda definitions
|
||||||
@Override
|
if (!name.equals("_")) context.host.globalFunctions.put(name, result);
|
||||||
public LazyValue lazyEval(Context c, Integer type, Expression e, Tokenizer.Token t, List<LazyValue> lazyParams)
|
return result;
|
||||||
{
|
|
||||||
if (arguments.size() != lazyParams.size()) // something that might be subject to change in the future
|
|
||||||
{
|
|
||||||
throw new ExpressionException(e, t,
|
|
||||||
"Incorrect number of arguments for function "+name+
|
|
||||||
". Should be "+arguments.size()+", not "+lazyParams.size()+" like "+arguments
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Context newFrame = c.recreate();
|
|
||||||
|
|
||||||
contextValues.forEach(newFrame::setVariable);
|
|
||||||
for (int i=0; i<arguments.size(); i++)
|
|
||||||
{
|
|
||||||
String arg = arguments.get(i);
|
|
||||||
Value val = lazyParams.get(i).evalValue(c).reboundedTo(arg);
|
|
||||||
newFrame.setVariable(arg, (cc, tt) -> val);
|
|
||||||
}
|
|
||||||
Value retVal;
|
|
||||||
boolean rethrow = false;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
retVal = code.evalValue(newFrame, type); // todo not sure if we need to propagete type / consider boolean context in defined functions - answer seems ye
|
|
||||||
}
|
|
||||||
catch (ReturnStatement returnStatement)
|
|
||||||
{
|
|
||||||
retVal = returnStatement.retval;
|
|
||||||
}
|
|
||||||
catch (ThrowStatement throwStatement) // might not be really necessary
|
|
||||||
{
|
|
||||||
retVal = throwStatement.retval;
|
|
||||||
rethrow = true;
|
|
||||||
}
|
|
||||||
catch (InternalExpressionException exc)
|
|
||||||
{
|
|
||||||
throw new ExpressionException(function_context, t, exc.getMessage());
|
|
||||||
}
|
|
||||||
catch (ArithmeticException exc)
|
|
||||||
{
|
|
||||||
throw new ExpressionException(function_context, t, "Your math is wrong, "+exc.getMessage());
|
|
||||||
}
|
|
||||||
catch (ExitStatement | ExpressionException exit)
|
|
||||||
{
|
|
||||||
throw exit;
|
|
||||||
}
|
|
||||||
catch (Exception exc)
|
|
||||||
{
|
|
||||||
throw new ExpressionException(e, t, "Error while evaluating expression: "+exc.getMessage());
|
|
||||||
}
|
|
||||||
if (rethrow)
|
|
||||||
{
|
|
||||||
throw new ThrowStatement(retVal);
|
|
||||||
}
|
|
||||||
Value otherRetVal = retVal;
|
|
||||||
return (cc, tt) -> otherRetVal;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -944,12 +857,15 @@ public class Expression implements Cloneable
|
|||||||
addLazyFunctionWithDelegation("call",-1, (c, t, expr, tok, lv) -> { // adjust based on c
|
addLazyFunctionWithDelegation("call",-1, (c, t, expr, tok, lv) -> { // adjust based on c
|
||||||
if (lv.size() == 0)
|
if (lv.size() == 0)
|
||||||
throw new InternalExpressionException("'call' expects at least function name to call");
|
throw new InternalExpressionException("'call' expects at least function name to call");
|
||||||
String name = lv.get(0).evalValue(c).getString();
|
|
||||||
//lv.remove(lv.size()-1); // aint gonna cut it // maybe it will because of the eager eval changes
|
//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
|
if (t != Context.SIGNATURE) // just call the function
|
||||||
{
|
{
|
||||||
if (!c.host.globalFunctions.containsKey(name))
|
Value functionValue = lv.get(0).evalValue(c);
|
||||||
|
if (!(functionValue instanceof FunctionValue))
|
||||||
{
|
{
|
||||||
|
String name = functionValue.getString();
|
||||||
|
functionValue = c.host.globalFunctions.get(name);
|
||||||
|
if (functionValue == null)
|
||||||
throw new InternalExpressionException("Function "+name+" is not defined yet");
|
throw new InternalExpressionException("Function "+name+" is not defined yet");
|
||||||
}
|
}
|
||||||
List<LazyValue> lvargs = new ArrayList<>(lv.size()-1);
|
List<LazyValue> lvargs = new ArrayList<>(lv.size()-1);
|
||||||
@@ -957,12 +873,12 @@ public class Expression implements Cloneable
|
|||||||
{
|
{
|
||||||
lvargs.add(lv.get(i));
|
lvargs.add(lv.get(i));
|
||||||
}
|
}
|
||||||
UserDefinedFunction acf = c.host.globalFunctions.get(name);
|
FunctionValue fun = (FunctionValue)functionValue;
|
||||||
Value retval = acf.lazyEval(c, t, acf.expression, acf.token, lvargs).evalValue(c);
|
Value retval = fun.callInContext(expr, c, t, fun.getExpression(), fun.getToken(), lvargs).evalValue(c);
|
||||||
return (cc, tt) -> retval; ///!!!! dono might need to store expr and token in statics? (e? t?)
|
return (cc, tt) -> retval; ///!!!! dono might need to store expr and token in statics? (e? t?)
|
||||||
}
|
}
|
||||||
|
|
||||||
// gimme signature
|
// gimme signature
|
||||||
|
String name = lv.get(0).evalValue(c).getString();
|
||||||
List<String> args = new ArrayList<>();
|
List<String> args = new ArrayList<>();
|
||||||
List<String> globals = new ArrayList<>();
|
List<String> globals = new ArrayList<>();
|
||||||
for (int i = 1; i < lv.size(); i++)
|
for (int i = 1; i < lv.size(); i++)
|
||||||
@@ -981,8 +897,6 @@ public class Expression implements Cloneable
|
|||||||
args.add(v.boundVariable);
|
args.add(v.boundVariable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (name.equals("_"))
|
|
||||||
name = "__lambda_"+tok.lineno+"_"+tok.linepos;
|
|
||||||
Value retval = new FunctionSignatureValue(name, args, globals);
|
Value retval = new FunctionSignatureValue(name, args, globals);
|
||||||
return (cc, tt) -> retval;
|
return (cc, tt) -> retval;
|
||||||
});
|
});
|
||||||
@@ -1003,20 +917,11 @@ public class Expression implements Cloneable
|
|||||||
addLazyBinaryOperatorWithDelegation("->", precedence.get("def->"), false, (c, type, e, t, lv1, lv2) ->
|
addLazyBinaryOperatorWithDelegation("->", precedence.get("def->"), false, (c, type, e, t, lv1, lv2) ->
|
||||||
{
|
{
|
||||||
Value v1 = lv1.evalValue(c, Context.SIGNATURE);
|
Value v1 = lv1.evalValue(c, Context.SIGNATURE);
|
||||||
String result;
|
if (!(v1 instanceof FunctionSignatureValue))
|
||||||
if (v1 instanceof FunctionSignatureValue)
|
throw new InternalExpressionException("'->' operator requires a function signature on the LHS");
|
||||||
{
|
|
||||||
FunctionSignatureValue sign = (FunctionSignatureValue) v1;
|
FunctionSignatureValue sign = (FunctionSignatureValue) v1;
|
||||||
addContextFunction(c, sign.getName(), e, t, sign.getArgs(), sign.getGlobals(), lv2);
|
Value result = addContextFunction(c, sign.getName(), e, t, sign.getArgs(), sign.getGlobals(), lv2);
|
||||||
result = sign.getName();
|
return (cc, tt) -> result;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
v1.assertAssignable();
|
|
||||||
c.setVariable(v1.getVariable(), lv2);
|
|
||||||
result = v1.getVariable();
|
|
||||||
}
|
|
||||||
return (cc, tt) -> new StringValue(result);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
addFunction("exit", (lv) -> { throw new ExitStatement(lv.size()==0?Value.NULL:lv.get(0)); });
|
addFunction("exit", (lv) -> { throw new ExitStatement(lv.size()==0?Value.NULL:lv.get(0)); });
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package carpet.script;
|
package carpet.script;
|
||||||
|
|
||||||
import carpet.CarpetServer;
|
import carpet.script.exception.ExpressionException;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -26,6 +26,20 @@ public class ExpressionInspector
|
|||||||
return e.getName();
|
return e.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Expression Expression_cloneWithName(Expression e, String name, Tokenizer.Token token)
|
||||||
|
{
|
||||||
|
Expression copy = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
copy = e.clone();
|
||||||
|
}
|
||||||
|
catch (CloneNotSupportedException ex)
|
||||||
|
{
|
||||||
|
throw new ExpressionException(e, token, "Problems in allocating global function "+name);
|
||||||
|
}
|
||||||
|
return copy.withName(name);
|
||||||
|
}
|
||||||
|
|
||||||
private static TreeSet<String> scarpetFunctions;
|
private static TreeSet<String> scarpetFunctions;
|
||||||
private static TreeSet<String> APIFunctions;
|
private static TreeSet<String> APIFunctions;
|
||||||
static
|
static
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package carpet.script;
|
|||||||
|
|
||||||
import carpet.CarpetServer;
|
import carpet.CarpetServer;
|
||||||
import carpet.script.bundled.ModuleInterface;
|
import carpet.script.bundled.ModuleInterface;
|
||||||
|
import carpet.script.value.FunctionValue;
|
||||||
import carpet.settings.CarpetSettings;
|
import carpet.settings.CarpetSettings;
|
||||||
import carpet.script.exception.ExpressionException;
|
import carpet.script.exception.ExpressionException;
|
||||||
import carpet.script.exception.InvalidCallbackException;
|
import carpet.script.exception.InvalidCallbackException;
|
||||||
@@ -20,7 +21,6 @@ import net.minecraft.util.math.BlockPos;
|
|||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -31,7 +31,7 @@ import static java.lang.Math.max;
|
|||||||
public class ScriptHost
|
public class ScriptHost
|
||||||
{
|
{
|
||||||
private final Map<String, ScriptHost> userHosts = new Object2ObjectOpenHashMap<>();
|
private final Map<String, ScriptHost> userHosts = new Object2ObjectOpenHashMap<>();
|
||||||
public Map<String, UserDefinedFunction> globalFunctions = new Object2ObjectOpenHashMap<>();
|
public Map<String, FunctionValue> globalFunctions = new Object2ObjectOpenHashMap<>();
|
||||||
public Map<String, LazyValue> globalVariables = new Object2ObjectOpenHashMap<>();
|
public Map<String, LazyValue> globalVariables = new Object2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
private Tag globalState;
|
private Tag globalState;
|
||||||
@@ -118,8 +118,8 @@ public class ScriptHost
|
|||||||
{
|
{
|
||||||
if (CarpetServer.scriptServer.stopAll)
|
if (CarpetServer.scriptServer.stopAll)
|
||||||
return "SCARPET PAUSED";
|
return "SCARPET PAUSED";
|
||||||
UserDefinedFunction acf = globalFunctions.get(call);
|
FunctionValue function = globalFunctions.get(call);
|
||||||
if (acf == null)
|
if (function == null)
|
||||||
return "UNDEFINED";
|
return "UNDEFINED";
|
||||||
List<LazyValue> argv = new ArrayList<>();
|
List<LazyValue> argv = new ArrayList<>();
|
||||||
if (coords != null)
|
if (coords != null)
|
||||||
@@ -185,7 +185,7 @@ public class ScriptHost
|
|||||||
return "Fail: "+tok.surface+" is not allowed in invoke";
|
return "Fail: "+tok.surface+" is not allowed in invoke";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
List<String> args = acf.getArguments();
|
List<String> args = function.getArguments();
|
||||||
if (argv.size() != args.size())
|
if (argv.size() != args.size())
|
||||||
{
|
{
|
||||||
String error = "Fail: stored function "+call+" takes "+args.size()+" arguments, not "+argv.size()+ ":\n";
|
String error = "Fail: stored function "+call+" takes "+args.size()+" arguments, not "+argv.size()+ ":\n";
|
||||||
@@ -200,7 +200,7 @@ public class ScriptHost
|
|||||||
// TODO: this is just for now - invoke would be able to invoke other hosts scripts
|
// TODO: this is just for now - invoke would be able to invoke other hosts scripts
|
||||||
Context context = new CarpetContext(this, source, BlockPos.ORIGIN);
|
Context context = new CarpetContext(this, source, BlockPos.ORIGIN);
|
||||||
return Expression.evalValue(
|
return Expression.evalValue(
|
||||||
() -> acf.lazyEval(context, Context.VOID, acf.expression, acf.token, argv),
|
() -> function.lazyEval(context, Context.VOID, function.getExpression(), function.getToken(), argv),
|
||||||
context,
|
context,
|
||||||
Context.VOID
|
Context.VOID
|
||||||
).getString();
|
).getString();
|
||||||
@@ -211,13 +211,11 @@ public class ScriptHost
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Value callUDF(BlockPos pos, ServerCommandSource source, UserDefinedFunction acf, List<LazyValue> argv) throws InvalidCallbackException
|
public Value callUDF(BlockPos pos, ServerCommandSource source, FunctionValue fun, List<LazyValue> argv) throws InvalidCallbackException
|
||||||
{
|
{
|
||||||
if (CarpetServer.scriptServer.stopAll)
|
if (CarpetServer.scriptServer.stopAll)
|
||||||
return Value.NULL;
|
return Value.NULL;
|
||||||
|
if (argv.size() != fun.getArguments().size())
|
||||||
List<String> args = acf.getArguments();
|
|
||||||
if (argv.size() != args.size())
|
|
||||||
{
|
{
|
||||||
throw new InvalidCallbackException();
|
throw new InvalidCallbackException();
|
||||||
}
|
}
|
||||||
@@ -226,7 +224,7 @@ public class ScriptHost
|
|||||||
// TODO: this is just for now - invoke would be able to invoke other hosts scripts
|
// TODO: this is just for now - invoke would be able to invoke other hosts scripts
|
||||||
Context context = new CarpetContext(this, source, pos);
|
Context context = new CarpetContext(this, source, pos);
|
||||||
return Expression.evalValue(
|
return Expression.evalValue(
|
||||||
() -> acf.lazyEval(context, Context.VOID, acf.expression, acf.token, argv),
|
() -> fun.lazyEval(context, Context.VOID, fun.getExpression(), fun.getToken(), argv),
|
||||||
context,
|
context,
|
||||||
Context.VOID);
|
Context.VOID);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
package carpet.script;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public abstract class UserDefinedFunction extends Fluff.AbstractLazyFunction implements Fluff.ILazyFunction
|
|
||||||
{
|
|
||||||
protected List<String> arguments;
|
|
||||||
protected Expression expression;
|
|
||||||
protected Tokenizer.Token token;
|
|
||||||
UserDefinedFunction(List<String> args, Expression expr, Tokenizer.Token t)
|
|
||||||
{
|
|
||||||
super(args.size());
|
|
||||||
arguments = args;
|
|
||||||
expression = expr;
|
|
||||||
token = t;
|
|
||||||
}
|
|
||||||
public List<String> getArguments()
|
|
||||||
{
|
|
||||||
return arguments;
|
|
||||||
}
|
|
||||||
public Expression getExpression()
|
|
||||||
{
|
|
||||||
return expression;
|
|
||||||
}
|
|
||||||
public Tokenizer.Token getToken()
|
|
||||||
{
|
|
||||||
return token;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package carpet.script.exception;
|
||||||
|
|
||||||
|
import carpet.script.value.Value;
|
||||||
|
|
||||||
|
/* Exception thrown to terminate execution mid expression (aka return statement) */
|
||||||
|
public class ExitStatement extends RuntimeException
|
||||||
|
{
|
||||||
|
public Value retval;
|
||||||
|
public ExitStatement(Value value)
|
||||||
|
{
|
||||||
|
retval = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package carpet.script.exception;
|
||||||
|
|
||||||
|
import carpet.script.value.Value;
|
||||||
|
|
||||||
|
public class ReturnStatement extends ExitStatement
|
||||||
|
{
|
||||||
|
|
||||||
|
public ReturnStatement(Value value)
|
||||||
|
{
|
||||||
|
super(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package carpet.script.exception;
|
||||||
|
|
||||||
|
import carpet.script.value.Value;
|
||||||
|
|
||||||
|
public class ThrowStatement extends ExitStatement
|
||||||
|
{
|
||||||
|
public ThrowStatement(Value value)
|
||||||
|
{
|
||||||
|
super(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -775,14 +775,14 @@ public class EntityValue extends Value
|
|||||||
// "nbt" <-big one, for now use run('data merge entity ...
|
// "nbt" <-big one, for now use run('data merge entity ...
|
||||||
}};
|
}};
|
||||||
|
|
||||||
public void setEvent(CarpetContext cc, String event, String fun, List<Value> args)
|
public void setEvent(CarpetContext cc, String event, FunctionValue fun, List<Value> args)
|
||||||
{
|
{
|
||||||
if (!(events.containsKey(event)))
|
if (!(events.containsKey(event)))
|
||||||
throw new InternalExpressionException("Unknown entity event: " + event);
|
throw new InternalExpressionException("Unknown entity event: " + event);
|
||||||
events.get(event).accept(cc, entity, fun, args);
|
events.get(event).accept(cc, entity, fun, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<String, Fluff.QuadConsumer<CarpetContext, Entity, String, List<Value>>> events = new HashMap<String, Fluff.QuadConsumer<CarpetContext, Entity, String, List<Value>>>() {{
|
private static Map<String, Fluff.QuadConsumer<CarpetContext, Entity, FunctionValue, List<Value>>> events = new HashMap<String, Fluff.QuadConsumer<CarpetContext, Entity, FunctionValue, List<Value>>>() {{
|
||||||
put("on_death", (c, e, f, l) -> ((EntityInterface)e).setDeathCallback(c, f, l));
|
put("on_death", (c, e, f, l) -> ((EntityInterface)e).setDeathCallback(c, f, l));
|
||||||
put("on_removed", (c, e, f, l) -> ((EntityInterface)e).setRemovedCallback(c, f, l));
|
put("on_removed", (c, e, f, l) -> ((EntityInterface)e).setRemovedCallback(c, f, l));
|
||||||
put("on_tick", (c, e, f, l) -> ((EntityInterface)e).setTickCallback(c, f, l));
|
put("on_tick", (c, e, f, l) -> ((EntityInterface)e).setTickCallback(c, f, l));
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
package carpet.script.value;
|
package carpet.script.value;
|
||||||
|
|
||||||
import carpet.script.exception.ExpressionException;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class FunctionSignatureValue extends FrameworkValue
|
public class FunctionSignatureValue extends FrameworkValue
|
||||||
@@ -10,7 +8,6 @@ public class FunctionSignatureValue extends FrameworkValue
|
|||||||
private List<String> arguments;
|
private List<String> arguments;
|
||||||
private List<String> globals;
|
private List<String> globals;
|
||||||
|
|
||||||
|
|
||||||
public FunctionSignatureValue(String name, List<String> args, List<String> globals)
|
public FunctionSignatureValue(String name, List<String> args, List<String> globals)
|
||||||
{
|
{
|
||||||
this.identifier = name;
|
this.identifier = name;
|
||||||
|
|||||||
@@ -0,0 +1,204 @@
|
|||||||
|
package carpet.script.value;
|
||||||
|
|
||||||
|
import carpet.script.Context;
|
||||||
|
import carpet.script.Expression;
|
||||||
|
import carpet.script.ExpressionInspector;
|
||||||
|
import carpet.script.Fluff;
|
||||||
|
import carpet.script.LazyValue;
|
||||||
|
import carpet.script.Tokenizer;
|
||||||
|
import carpet.script.exception.ExitStatement;
|
||||||
|
import carpet.script.exception.ExpressionException;
|
||||||
|
import carpet.script.exception.InternalExpressionException;
|
||||||
|
import carpet.script.exception.ReturnStatement;
|
||||||
|
import carpet.script.exception.ThrowStatement;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class FunctionValue extends Value implements Fluff.ILazyFunction
|
||||||
|
{
|
||||||
|
private Expression expression;
|
||||||
|
private Tokenizer.Token token;
|
||||||
|
private String name;
|
||||||
|
private LazyValue body;
|
||||||
|
private Map<String, LazyValue> outerState;
|
||||||
|
private List<String> args;
|
||||||
|
private static long variantCounter = 1;
|
||||||
|
private long variant;
|
||||||
|
|
||||||
|
public FunctionValue(Expression expression, Tokenizer.Token token, String name, LazyValue body, List<String> args)
|
||||||
|
{
|
||||||
|
this.expression = expression;
|
||||||
|
this.token = token;
|
||||||
|
this.name = name;
|
||||||
|
this.body = body;
|
||||||
|
this.args = args;
|
||||||
|
this.outerState = null;
|
||||||
|
variant = 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FunctionValue(Expression expression, Tokenizer.Token token, String name, LazyValue body, List<String> args, Map<String, LazyValue> outerState)
|
||||||
|
{
|
||||||
|
this.expression = expression;
|
||||||
|
this.token = token;
|
||||||
|
this.name = name;
|
||||||
|
this.body = body;
|
||||||
|
this.args = args;
|
||||||
|
this.outerState = outerState;
|
||||||
|
variant = variantCounter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getString()
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getBoolean()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Value clone()
|
||||||
|
{
|
||||||
|
FunctionValue ret = new FunctionValue(expression, token, name, body, args);
|
||||||
|
ret.outerState = this.outerState;
|
||||||
|
ret.variant = this.variant;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return name.hashCode()+(int)variant;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o)
|
||||||
|
{
|
||||||
|
if (o instanceof FunctionValue)
|
||||||
|
return name.equals(((FunctionValue) o).name) && variant == ((FunctionValue) o).variant;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(final Value o)
|
||||||
|
{
|
||||||
|
if (o instanceof FunctionValue)
|
||||||
|
{
|
||||||
|
int nameSame = this.name.compareTo(((FunctionValue) o).name);
|
||||||
|
if (nameSame != 0)
|
||||||
|
return nameSame;
|
||||||
|
return (int) (variant-((FunctionValue) o).variant);
|
||||||
|
}
|
||||||
|
return getString().compareTo(o.getString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double readNumber()
|
||||||
|
{
|
||||||
|
throw new InternalExpressionException("Function value has no numeric value");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Value slice(long from, long to)
|
||||||
|
{
|
||||||
|
throw new InternalExpressionException("Cannot slice a function");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getNumParams()
|
||||||
|
{
|
||||||
|
return args.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean numParamsVaries()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LazyValue callInContext(Expression callingExpression, Context c, Integer type, Expression e, Tokenizer.Token t, List<LazyValue> lazyParams)
|
||||||
|
{
|
||||||
|
// this hole thing might not be really needed
|
||||||
|
Expression callContext = ExpressionInspector.Expression_cloneWithName(callingExpression, name, t);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return lazyEval(c, type, e, t, lazyParams);
|
||||||
|
}
|
||||||
|
catch (InternalExpressionException exc)
|
||||||
|
{
|
||||||
|
throw new ExpressionException(callContext, t, exc.getMessage());
|
||||||
|
}
|
||||||
|
catch (ArithmeticException exc)
|
||||||
|
{
|
||||||
|
throw new ExpressionException(callContext, t, "Your math is wrong, "+exc.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LazyValue lazyEval(Context c, Integer type, Expression e, Tokenizer.Token t, List<LazyValue> lazyParams)
|
||||||
|
{
|
||||||
|
if (args.size() != lazyParams.size()) // something that might be subject to change in the future
|
||||||
|
// in case we add variable arguments
|
||||||
|
{
|
||||||
|
throw new ExpressionException(e, t,
|
||||||
|
"Incorrect number of arguments for function "+name+
|
||||||
|
". Should be "+args.size()+", not "+lazyParams.size()+" like "+args
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Context newFrame = c.recreate();
|
||||||
|
|
||||||
|
if (outerState != null) outerState.forEach(newFrame::setVariable);
|
||||||
|
for (int i=0; i<args.size(); i++)
|
||||||
|
{
|
||||||
|
String arg = args.get(i);
|
||||||
|
Value val = lazyParams.get(i).evalValue(c).reboundedTo(arg);
|
||||||
|
newFrame.setVariable(arg, (cc, tt) -> val);
|
||||||
|
}
|
||||||
|
Value retVal;
|
||||||
|
boolean rethrow = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
retVal = body.evalValue(newFrame, type); // todo not sure if we need to propagete type / consider boolean context in defined functions - answer seems ye
|
||||||
|
}
|
||||||
|
catch (ReturnStatement returnStatement)
|
||||||
|
{
|
||||||
|
retVal = returnStatement.retval;
|
||||||
|
}
|
||||||
|
catch (ThrowStatement throwStatement) // might not be really necessary
|
||||||
|
{
|
||||||
|
retVal = throwStatement.retval;
|
||||||
|
rethrow = true;
|
||||||
|
}
|
||||||
|
catch (ArithmeticException | ExitStatement | ExpressionException exc)
|
||||||
|
{
|
||||||
|
throw exc; // rethrow so could be contextualized if needed
|
||||||
|
}
|
||||||
|
catch (Exception exc)
|
||||||
|
{
|
||||||
|
throw new ExpressionException(e, t, "Error while evaluating expression: "+exc.getMessage());
|
||||||
|
}
|
||||||
|
if (rethrow)
|
||||||
|
{
|
||||||
|
throw new ThrowStatement(retVal);
|
||||||
|
}
|
||||||
|
Value otherRetVal = retVal;
|
||||||
|
return (cc, tt) -> otherRetVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Expression getExpression()
|
||||||
|
{
|
||||||
|
return expression;
|
||||||
|
}
|
||||||
|
public Tokenizer.Token getToken()
|
||||||
|
{
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
public List<String> getArguments()
|
||||||
|
{
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package carpet.settings;
|
|||||||
import carpet.CarpetServer;
|
import carpet.CarpetServer;
|
||||||
import carpet.utils.Messenger;
|
import carpet.utils.Messenger;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
import com.mojang.brigadier.CommandDispatcher;
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||||
@@ -264,8 +265,10 @@ public class SettingsManager
|
|||||||
String lcSearch = search.toLowerCase(Locale.ROOT);
|
String lcSearch = search.toLowerCase(Locale.ROOT);
|
||||||
return rules.values().stream().filter(rule ->
|
return rules.values().stream().filter(rule ->
|
||||||
{
|
{
|
||||||
if (rule.name.toLowerCase(Locale.ROOT).contains(lcSearch)) return true;
|
if (rule.name.toLowerCase(Locale.ROOT).contains(lcSearch)) return true; // substring match, case insensitive
|
||||||
for (String c : rule.categories) if (c.toLowerCase(Locale.ROOT).equals(search)) return true;
|
for (String c : rule.categories) if (c.equals(search)) return true; // category exactly, case sensitive
|
||||||
|
if (Sets.newHashSet(rule.description.toLowerCase(Locale.ROOT).split("\\W+")).contains(lcSearch))
|
||||||
|
return true; // contains full term in description, but case insensitive
|
||||||
return false;
|
return false;
|
||||||
}).collect(ImmutableList.toImmutableList());
|
}).collect(ImmutableList.toImmutableList());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user