modules and imports
This commit is contained in:
1 parent
34bf877bc7
commit
4f65be946c
17 files changed
+479
-314
No files matched your search
@@ -37,6 +37,7 @@ import java.util.Locale;
|
|||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static net.minecraft.server.command.CommandManager.argument;
|
import static net.minecraft.server.command.CommandManager.argument;
|
||||||
import static net.minecraft.server.command.CommandManager.literal;
|
import static net.minecraft.server.command.CommandManager.literal;
|
||||||
@@ -78,7 +79,7 @@ public class ScriptCommand
|
|||||||
executes( (cc) -> { CarpetServer.scriptServer.stopAll = false; return 1;});
|
executes( (cc) -> { CarpetServer.scriptServer.stopAll = false; return 1;});
|
||||||
LiteralArgumentBuilder<ServerCommandSource> l = literal("run").
|
LiteralArgumentBuilder<ServerCommandSource> l = literal("run").
|
||||||
requires((player) -> player.hasPermissionLevel(2)).
|
requires((player) -> player.hasPermissionLevel(2)).
|
||||||
then(argument("expr", StringArgumentType.greedyString()).suggests((cc, bb) -> suggestCode(cc, bb)).
|
then(argument("expr", StringArgumentType.greedyString()).suggests(ScriptCommand::suggestCode).
|
||||||
executes((cc) -> compute(
|
executes((cc) -> compute(
|
||||||
cc,
|
cc,
|
||||||
StringArgumentType.getString(cc, "expr"))));
|
StringArgumentType.getString(cc, "expr"))));
|
||||||
@@ -141,7 +142,7 @@ public class ScriptCommand
|
|||||||
then(argument("from", BlockPosArgumentType.blockPos()).
|
then(argument("from", BlockPosArgumentType.blockPos()).
|
||||||
then(argument("to", BlockPosArgumentType.blockPos()).
|
then(argument("to", BlockPosArgumentType.blockPos()).
|
||||||
then(argument("expr", StringArgumentType.greedyString()).
|
then(argument("expr", StringArgumentType.greedyString()).
|
||||||
suggests((cc, bb) -> suggestCode(cc, bb)).
|
suggests(ScriptCommand::suggestCode).
|
||||||
executes( (cc) -> scriptScan(
|
executes( (cc) -> scriptScan(
|
||||||
cc,
|
cc,
|
||||||
BlockPosArgumentType.getBlockPos(cc, "origin"),
|
BlockPosArgumentType.getBlockPos(cc, "origin"),
|
||||||
@@ -288,7 +289,7 @@ public class ScriptCommand
|
|||||||
private static Collection<String> suggestFunctionCalls(CommandContext<ServerCommandSource> c)
|
private static Collection<String> suggestFunctionCalls(CommandContext<ServerCommandSource> c)
|
||||||
{
|
{
|
||||||
CarpetScriptHost host = getHost(c);
|
CarpetScriptHost host = getHost(c);
|
||||||
return host.getPublicFunctions();
|
return host.globaFunctionNames(host.myCode, s -> !s.startsWith("_")).sorted().collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
private static int listEvents(ServerCommandSource source)
|
private static int listEvents(ServerCommandSource source)
|
||||||
{
|
{
|
||||||
@@ -314,9 +315,8 @@ public class ScriptCommand
|
|||||||
ServerCommandSource source = context.getSource();
|
ServerCommandSource source = context.getSource();
|
||||||
|
|
||||||
Messenger.m(source, "lb Stored functions"+((host == CarpetServer.scriptServer.globalHost)?":":" in "+host.getName()+":"));
|
Messenger.m(source, "lb Stored functions"+((host == CarpetServer.scriptServer.globalHost)?":":" in "+host.getName()+":"));
|
||||||
for (String fname : host.getAvailableFunctions(all))
|
host.globaFunctionNames(host.myCode, (str) -> all || !str.startsWith("__")).sorted().forEach( (s) -> {
|
||||||
{
|
FunctionValue fun = host.getFunction(s);
|
||||||
FunctionValue fun = host.globalFunctions.get(fname);
|
|
||||||
Expression expr = fun.getExpression();
|
Expression expr = fun.getExpression();
|
||||||
Tokenizer.Token tok = fun.getToken();
|
Tokenizer.Token tok = fun.getToken();
|
||||||
List<String> snippet = ExpressionInspector.Expression_getExpressionSnippet(tok, expr);
|
List<String> snippet = ExpressionInspector.Expression_getExpressionSnippet(tok, expr);
|
||||||
@@ -326,16 +326,13 @@ public class ScriptCommand
|
|||||||
Messenger.m(source, "w "+snippetLine);
|
Messenger.m(source, "w "+snippetLine);
|
||||||
}
|
}
|
||||||
Messenger.m(source, "gi ----------------");
|
Messenger.m(source, "gi ----------------");
|
||||||
}
|
});
|
||||||
//Messenger.m(source, "w "+code);
|
//Messenger.m(source, "w "+code);
|
||||||
Messenger.m(source, "w ");
|
Messenger.m(source, "w ");
|
||||||
Messenger.m(source, "lb Global variables"+((host == CarpetServer.scriptServer.globalHost)?":":" in "+host.getName()+":"));
|
Messenger.m(source, "lb Global variables"+((host == CarpetServer.scriptServer.globalHost)?":":" in "+host.getName()+":"));
|
||||||
|
host.globaVariableNames(host.myCode, (s) -> s.startsWith("global_")).sorted().forEach( (s) -> {
|
||||||
for (String vname : host.globalVariables.keySet())
|
Messenger.m(source, "wb "+s+": ", "w "+ host.getGlobalVariable(s).evalValue(null).getPrettyString());
|
||||||
{
|
});
|
||||||
if (!vname.startsWith("global")) continue;
|
|
||||||
Messenger.m(source, "wb "+vname+": ", "w "+ host.globalVariables.get(vname).evalValue(null).getPrettyString());
|
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,7 +399,7 @@ public class ScriptCommand
|
|||||||
ServerCommandSource source = context.getSource();
|
ServerCommandSource source = context.getSource();
|
||||||
CarpetScriptHost host = getHost(context);
|
CarpetScriptHost host = getHost(context);
|
||||||
handleCall(source, host, () -> {
|
handleCall(source, host, () -> {
|
||||||
CarpetExpression ex = new CarpetExpression(expr, source, new BlockPos(0, 0, 0));
|
CarpetExpression ex = new CarpetExpression(host.myCode, expr, source, new BlockPos(0, 0, 0));
|
||||||
return ex.scriptRunCommand(host, new BlockPos(source.getPosition()));
|
return ex.scriptRunCommand(host, new BlockPos(source.getPosition()));
|
||||||
});
|
});
|
||||||
return 1;
|
return 1;
|
||||||
@@ -413,7 +410,8 @@ public class ScriptCommand
|
|||||||
ServerCommandSource source = context.getSource();
|
ServerCommandSource source = context.getSource();
|
||||||
CarpetScriptHost host = getHost(context);
|
CarpetScriptHost host = getHost(context);
|
||||||
MutableIntBoundingBox area = new MutableIntBoundingBox(a, b);
|
MutableIntBoundingBox area = new MutableIntBoundingBox(a, b);
|
||||||
CarpetExpression cexpr = new CarpetExpression(expr, source, origin);
|
CarpetExpression cexpr = new CarpetExpression(host.myCode, expr, source, origin);
|
||||||
|
|
||||||
int int_1 = area.getBlockCountX() * area.getBlockCountY() * area.getBlockCountZ();
|
int int_1 = area.getBlockCountX() * area.getBlockCountY() * area.getBlockCountZ();
|
||||||
if (int_1 > CarpetSettings.fillLimit)
|
if (int_1 > CarpetSettings.fillLimit)
|
||||||
{
|
{
|
||||||
@@ -463,7 +461,7 @@ public class ScriptCommand
|
|||||||
ServerCommandSource source = context.getSource();
|
ServerCommandSource source = context.getSource();
|
||||||
CarpetScriptHost host = getHost(context);
|
CarpetScriptHost host = getHost(context);
|
||||||
MutableIntBoundingBox area = new MutableIntBoundingBox(a, b);
|
MutableIntBoundingBox area = new MutableIntBoundingBox(a, b);
|
||||||
CarpetExpression cexpr = new CarpetExpression(expr, source, origin);
|
CarpetExpression cexpr = new CarpetExpression(host.myCode, expr, source, origin);
|
||||||
int int_1 = area.getBlockCountX() * area.getBlockCountY() * area.getBlockCountZ();
|
int int_1 = area.getBlockCountX() * area.getBlockCountY() * area.getBlockCountZ();
|
||||||
if (int_1 > CarpetSettings.fillLimit)
|
if (int_1 > CarpetSettings.fillLimit)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package carpet.script;
|
package carpet.script;
|
||||||
|
|
||||||
|
import carpet.script.value.Value;
|
||||||
import net.minecraft.server.command.ServerCommandSource;
|
import net.minecraft.server.command.ServerCommandSource;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
@@ -15,9 +16,17 @@ public class CarpetContext extends Context
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Context recreate()
|
public Context duplicate()
|
||||||
{
|
{
|
||||||
return new CarpetContext(this.host, this.s, this.origin);
|
return new CarpetContext(this.host, this.s, this.origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initialize()
|
||||||
|
{
|
||||||
|
super.initialize();
|
||||||
|
variables.put("_x", (c, t) -> Value.ZERO);
|
||||||
|
variables.put("_y", (c, t) -> Value.ZERO);
|
||||||
|
variables.put("_z", (c, t) -> Value.ZERO);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -130,7 +130,7 @@ public class CarpetEventServer
|
|||||||
// impossible call to add
|
// impossible call to add
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
FunctionValue udf = host.globalFunctions.get(funName);
|
FunctionValue udf = host.getFunction(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
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import carpet.helpers.FeatureGenerator;
|
|||||||
import carpet.mixins.ChunkTicketManager_scarpetMixin;
|
import carpet.mixins.ChunkTicketManager_scarpetMixin;
|
||||||
import carpet.mixins.ServerChunkManager_scarpetMixin;
|
import carpet.mixins.ServerChunkManager_scarpetMixin;
|
||||||
import carpet.script.Fluff.TriFunction;
|
import carpet.script.Fluff.TriFunction;
|
||||||
|
import carpet.script.bundled.Module;
|
||||||
import carpet.script.exception.CarpetExpressionException;
|
import carpet.script.exception.CarpetExpressionException;
|
||||||
import carpet.script.exception.ExitStatement;
|
import carpet.script.exception.ExitStatement;
|
||||||
import carpet.script.exception.ExpressionException;
|
import carpet.script.exception.ExpressionException;
|
||||||
@@ -2135,9 +2136,7 @@ public class CarpetExpression
|
|||||||
else if (!(functionValue instanceof FunctionValue))
|
else if (!(functionValue instanceof FunctionValue))
|
||||||
{
|
{
|
||||||
String name = functionValue.getString();
|
String name = functionValue.getString();
|
||||||
functionValue = c.host.globalFunctions.get(name);
|
functionValue = c.host.getAssertFunction(this.expr.module, name);
|
||||||
if (functionValue == null)
|
|
||||||
throw new InternalExpressionException("Function "+name+" is not defined yet");
|
|
||||||
}
|
}
|
||||||
FunctionValue function = (FunctionValue)functionValue;
|
FunctionValue function = (FunctionValue)functionValue;
|
||||||
List<Value> args = null;
|
List<Value> args = null;
|
||||||
@@ -3194,9 +3193,7 @@ public class CarpetExpression
|
|||||||
if (!(functionValue instanceof FunctionValue))
|
if (!(functionValue instanceof FunctionValue))
|
||||||
{
|
{
|
||||||
String name = functionValue.getString();
|
String name = functionValue.getString();
|
||||||
functionValue = c.host.globalFunctions.get(name);
|
functionValue = c.host.getAssertFunction(this.expr.module, name);
|
||||||
if (functionValue == null)
|
|
||||||
throw new InternalExpressionException("Function "+name+" is not defined yet");
|
|
||||||
}
|
}
|
||||||
FunctionValue function = (FunctionValue)functionValue;
|
FunctionValue function = (FunctionValue)functionValue;
|
||||||
|
|
||||||
@@ -3298,11 +3295,13 @@ public class CarpetExpression
|
|||||||
* @param source source
|
* @param source source
|
||||||
* @param origin origin
|
* @param origin origin
|
||||||
*/
|
*/
|
||||||
public CarpetExpression(String expression, ServerCommandSource source, BlockPos origin)
|
public CarpetExpression(Module module, String expression, ServerCommandSource source, BlockPos origin)
|
||||||
{
|
{
|
||||||
this.origin = origin;
|
this.origin = origin;
|
||||||
this.source = source;
|
this.source = source;
|
||||||
this.expr = new Expression(expression);
|
this.expr = new Expression(expression);
|
||||||
|
this.expr.asAModule(module);
|
||||||
|
|
||||||
|
|
||||||
API_BlockManipulation();
|
API_BlockManipulation();
|
||||||
API_EntityManipulation();
|
API_EntityManipulation();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package carpet.script;
|
package carpet.script;
|
||||||
|
|
||||||
import carpet.CarpetServer;
|
import carpet.CarpetServer;
|
||||||
import carpet.script.bundled.ModuleInterface;
|
import carpet.script.bundled.Module;
|
||||||
import carpet.script.exception.CarpetExpressionException;
|
import carpet.script.exception.CarpetExpressionException;
|
||||||
import carpet.script.exception.ExpressionException;
|
import carpet.script.exception.ExpressionException;
|
||||||
import carpet.script.exception.InternalExpressionException;
|
import carpet.script.exception.InternalExpressionException;
|
||||||
@@ -36,7 +36,7 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
private Tag globalState;
|
private Tag globalState;
|
||||||
private int saveTimeout;
|
private int saveTimeout;
|
||||||
|
|
||||||
private CarpetScriptHost(CarpetScriptServer server, ModuleInterface code, boolean perUser, ScriptHost parent)
|
private CarpetScriptHost(CarpetScriptServer server, Module code, boolean perUser, ScriptHost parent)
|
||||||
{
|
{
|
||||||
super(code, perUser, parent);
|
super(code, perUser, parent);
|
||||||
this.saveTimeout = 0;
|
this.saveTimeout = 0;
|
||||||
@@ -45,12 +45,9 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
globalState = loadState();
|
globalState = loadState();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CarpetScriptHost create(CarpetScriptServer scriptServer, ModuleInterface module, boolean perPlayer, ServerCommandSource source)
|
public static CarpetScriptHost create(CarpetScriptServer scriptServer, Module module, boolean perPlayer, ServerCommandSource source)
|
||||||
{
|
{
|
||||||
CarpetScriptHost host = new CarpetScriptHost(scriptServer, module, perPlayer, null );
|
CarpetScriptHost host = new CarpetScriptHost(scriptServer, module, perPlayer, null );
|
||||||
host.globalVariables.put("_x", (c, t) -> Value.ZERO);
|
|
||||||
host.globalVariables.put("_y", (c, t) -> Value.ZERO);
|
|
||||||
host.globalVariables.put("_z", (c, t) -> Value.ZERO);
|
|
||||||
// parse code and convert to expression
|
// parse code and convert to expression
|
||||||
if (module != null)
|
if (module != null)
|
||||||
{
|
{
|
||||||
@@ -63,8 +60,8 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
host.setChatErrorSnooper(source);
|
host.setChatErrorSnooper(source);
|
||||||
CarpetExpression ex = new CarpetExpression(code, source, new BlockPos(0, 0, 0));
|
CarpetExpression ex = new CarpetExpression(host.myCode, code, source, new BlockPos(0, 0, 0));
|
||||||
ex.getExpr().asAModule(module);
|
ex.getExpr().asATextSource();
|
||||||
ex.scriptRunCommand(host, new BlockPos(source.getPosition()));
|
ex.scriptRunCommand(host, new BlockPos(source.getPosition()));
|
||||||
}
|
}
|
||||||
catch (CarpetExpressionException e)
|
catch (CarpetExpressionException e)
|
||||||
@@ -85,11 +82,11 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addUserDefinedFunction(String funName, FunctionValue function)
|
public void addUserDefinedFunction(Module module, String funName, FunctionValue function)
|
||||||
{
|
{
|
||||||
super.addUserDefinedFunction(funName, function);
|
super.addUserDefinedFunction(module, funName, function);
|
||||||
// mcarpet
|
// mcarpet
|
||||||
if (funName.startsWith("__on_"))
|
if (funName.startsWith("__on_")) // here we can make a determination if we want to only accept events from main module.
|
||||||
{
|
{
|
||||||
// this is nasty, we have the host and function, yet we add it via names, but hey - works for now
|
// this is nasty, we have the host and function, yet we add it via names, but hey - works for now
|
||||||
String event = funName.replaceFirst("__on_","");
|
String event = funName.replaceFirst("__on_","");
|
||||||
@@ -99,35 +96,27 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ModuleInterface getModuleByName(String name)
|
protected Module getModuleByName(String name)
|
||||||
{
|
{
|
||||||
ModuleInterface module = scriptServer.getModule(name);
|
Module module = scriptServer.getModule(name);
|
||||||
if (module == null || module.getCode() == null)
|
if (module == null || module.getCode() == null)
|
||||||
throw new InternalExpressionException("Unable to locate package: "+name);
|
throw new InternalExpressionException("Unable to locate package: "+name);
|
||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean runModuleCode(Context c, ModuleInterface module)
|
protected void runModuleCode(Context c, Module module)
|
||||||
{
|
{
|
||||||
CarpetContext cc = (CarpetContext)c;
|
CarpetContext cc = (CarpetContext)c;
|
||||||
try
|
CarpetExpression ex = new CarpetExpression(module, module.getCode(), cc.s, cc.origin);
|
||||||
{
|
ex.getExpr().asATextSource();
|
||||||
CarpetExpression ex = new CarpetExpression(module.getCode(), cc.s, cc.origin);
|
ex.scriptRunCommand(this, cc.origin);
|
||||||
ex.getExpr().asAModule(module);
|
|
||||||
ex.scriptRunCommand(this, cc.origin);
|
|
||||||
}
|
|
||||||
catch (CarpetExpressionException e) // hopefully that error got reported already
|
|
||||||
{
|
|
||||||
throw new InternalExpressionException(e.getMessage());
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delFunction(String funName)
|
public void delFunction(Module module, String funName)
|
||||||
{
|
{
|
||||||
super.delFunction(funName);
|
super.delFunction(module, funName);
|
||||||
// mcarpet
|
// mcarpet
|
||||||
if (funName.startsWith("__on_"))
|
if (funName.startsWith("__on_"))
|
||||||
{
|
{
|
||||||
@@ -157,7 +146,7 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
{
|
{
|
||||||
if (CarpetServer.scriptServer.stopAll)
|
if (CarpetServer.scriptServer.stopAll)
|
||||||
return "SCARPET PAUSED";
|
return "SCARPET PAUSED";
|
||||||
FunctionValue function = globalFunctions.get(call);
|
FunctionValue function = getFunction(call);
|
||||||
if (function == null)
|
if (function == null)
|
||||||
return "UNDEFINED";
|
return "UNDEFINED";
|
||||||
List<LazyValue> argv = new ArrayList<>();
|
List<LazyValue> argv = new ArrayList<>();
|
||||||
@@ -170,9 +159,10 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
switch (tok.type)
|
switch (tok.type)
|
||||||
{
|
{
|
||||||
case VARIABLE:
|
case VARIABLE:
|
||||||
if (globalVariables.containsKey(tok.surface.toLowerCase(Locale.ROOT)))
|
LazyValue var = getGlobalVariable(tok.surface.toLowerCase(Locale.ROOT));
|
||||||
|
if (var != null)
|
||||||
{
|
{
|
||||||
argv.add(globalVariables.get(tok.surface.toLowerCase(Locale.ROOT)));
|
argv.add(var);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case STRINGPARAM:
|
case STRINGPARAM:
|
||||||
@@ -238,7 +228,7 @@ public class CarpetScriptHost extends 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 function.getExpression().evalValue(
|
||||||
() -> function.lazyEval(context, Context.VOID, function.getExpression(), function.getToken(), argv),
|
() -> function.lazyEval(context, Context.VOID, function.getExpression(), function.getToken(), argv),
|
||||||
context,
|
context,
|
||||||
Context.VOID
|
Context.VOID
|
||||||
@@ -262,7 +252,7 @@ public class CarpetScriptHost extends 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 fun.getExpression().evalValue(
|
||||||
() -> fun.lazyEval(context, Context.VOID, fun.getExpression(), fun.getToken(), argv),
|
() -> fun.lazyEval(context, Context.VOID, fun.getExpression(), fun.getToken(), argv),
|
||||||
context,
|
context,
|
||||||
Context.VOID);
|
Context.VOID);
|
||||||
@@ -281,7 +271,7 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
if (this.saveTimeout > 0)
|
if (this.saveTimeout > 0)
|
||||||
dumpState();
|
dumpState();
|
||||||
|
|
||||||
FunctionValue closing = globalFunctions.get("__on_close");
|
FunctionValue closing = getFunction("__on_close");
|
||||||
if (closing != null)
|
if (closing != null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -294,7 +284,7 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
}
|
}
|
||||||
userHosts.forEach((key, value) ->
|
userHosts.forEach((key, value) ->
|
||||||
{
|
{
|
||||||
FunctionValue userClosing = value.globalFunctions.get("__on_close");
|
FunctionValue userClosing = value.getFunction("__on_close");
|
||||||
if (userClosing != null)
|
if (userClosing != null)
|
||||||
{
|
{
|
||||||
ServerPlayerEntity player = CarpetServer.minecraft_server.getPlayerManager().getPlayer(key);
|
ServerPlayerEntity player = CarpetServer.minecraft_server.getPlayerManager().getPlayer(key);
|
||||||
@@ -373,7 +363,7 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
|
|
||||||
public void setChatErrorSnooper(ServerCommandSource source)
|
public void setChatErrorSnooper(ServerCommandSource source)
|
||||||
{
|
{
|
||||||
errorSnooper = (expr, token, message) ->
|
errorSnooper = (expr, /*Nullable*/ token, message) ->
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -383,29 +373,43 @@ public class CarpetScriptHost extends ScriptHost
|
|||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
String[] lines = expr.getCodeString().split("\n");
|
|
||||||
String shebang = message;
|
String shebang = message;
|
||||||
if (lines.length > 1)
|
if (expr.module != null)
|
||||||
{
|
{
|
||||||
shebang += " at line "+(token.lineno+1)+", pos "+(token.linepos+1);
|
shebang += " in " + expr.module.getName() + "";
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
shebang += " at pos "+(token.pos+1);
|
|
||||||
}
|
|
||||||
if (expr.getName() != null)
|
|
||||||
{
|
{
|
||||||
shebang += " in "+expr.getName()+"";
|
shebang += " in system chat";
|
||||||
}
|
}
|
||||||
Messenger.m(source, "r "+shebang);
|
if (token != null)
|
||||||
if (lines.length > 1 && token.lineno > 0)
|
|
||||||
{
|
{
|
||||||
Messenger.m(source, "l "+lines[token.lineno-1]);
|
String[] lines = expr.getCodeString().split("\n");
|
||||||
|
|
||||||
|
if (lines.length > 1)
|
||||||
|
{
|
||||||
|
shebang += " at line " + (token.lineno + 1) + ", pos " + (token.linepos + 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
shebang += " at pos " + (token.pos + 1);
|
||||||
|
}
|
||||||
|
Messenger.m(source, "r " + shebang);
|
||||||
|
if (lines.length > 1 && token.lineno > 0)
|
||||||
|
{
|
||||||
|
Messenger.m(source, "l " + lines[token.lineno - 1]);
|
||||||
|
}
|
||||||
|
Messenger.m(source, "l " + lines[token.lineno].substring(0, token.linepos), "r HERE>> ", "l " +
|
||||||
|
lines[token.lineno].substring(token.linepos));
|
||||||
|
if (lines.length > 1 && token.lineno < lines.length - 1)
|
||||||
|
{
|
||||||
|
Messenger.m(source, "l " + lines[token.lineno + 1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Messenger.m(source, "l "+lines[token.lineno].substring(0, token.linepos), "r HERE>> ", "l "+
|
else
|
||||||
lines[token.lineno].substring(token.linepos));
|
|
||||||
if (lines.length > 1 && token.lineno < lines.length-1)
|
|
||||||
{
|
{
|
||||||
Messenger.m(source, "l "+lines[token.lineno+1]);
|
Messenger.m(source, "r " + shebang);
|
||||||
}
|
}
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import carpet.script.value.StringValue;
|
|||||||
import carpet.CarpetSettings;
|
import carpet.CarpetSettings;
|
||||||
import carpet.CarpetServer;
|
import carpet.CarpetServer;
|
||||||
import carpet.script.bundled.FileModule;
|
import carpet.script.bundled.FileModule;
|
||||||
import carpet.script.bundled.ModuleInterface;
|
import carpet.script.bundled.Module;
|
||||||
import carpet.script.exception.InvalidCallbackException;
|
import carpet.script.exception.InvalidCallbackException;
|
||||||
import carpet.script.value.Value;
|
import carpet.script.value.Value;
|
||||||
import carpet.utils.Messenger;
|
import carpet.utils.Messenger;
|
||||||
@@ -40,7 +40,7 @@ public class CarpetScriptServer
|
|||||||
private final Set<String> holyMoly;
|
private final Set<String> holyMoly;
|
||||||
public final CarpetEventServer events;
|
public final CarpetEventServer events;
|
||||||
|
|
||||||
private static final List<ModuleInterface> bundledModuleData = new ArrayList<ModuleInterface>(){{
|
private static final List<Module> bundledModuleData = new ArrayList<Module>(){{
|
||||||
add(new BundledModule("camera"));
|
add(new BundledModule("camera"));
|
||||||
add(new BundledModule("event_test"));
|
add(new BundledModule("event_test"));
|
||||||
add(new BundledModule("stats_test"));
|
add(new BundledModule("stats_test"));
|
||||||
@@ -69,7 +69,7 @@ public class CarpetScriptServer
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ModuleInterface getModule(String name)
|
public Module getModule(String name)
|
||||||
{
|
{
|
||||||
File folder = CarpetServer.minecraft_server.getLevelStorage().resolveFile(
|
File folder = CarpetServer.minecraft_server.getLevelStorage().resolveFile(
|
||||||
CarpetServer.minecraft_server.getLevelName(), "scripts");
|
CarpetServer.minecraft_server.getLevelName(), "scripts");
|
||||||
@@ -82,7 +82,7 @@ public class CarpetScriptServer
|
|||||||
return new FileModule(script);
|
return new FileModule(script);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (ModuleInterface moduleData : bundledModuleData)
|
for (Module moduleData : bundledModuleData)
|
||||||
{
|
{
|
||||||
if (moduleData.getName().equalsIgnoreCase(name))
|
if (moduleData.getName().equalsIgnoreCase(name))
|
||||||
{
|
{
|
||||||
@@ -97,7 +97,7 @@ public class CarpetScriptServer
|
|||||||
List<String> moduleNames = new ArrayList<>();
|
List<String> moduleNames = new ArrayList<>();
|
||||||
if (includeBuiltIns)
|
if (includeBuiltIns)
|
||||||
{
|
{
|
||||||
for (ModuleInterface mi : bundledModuleData)
|
for (Module mi : bundledModuleData)
|
||||||
{
|
{
|
||||||
moduleNames.add(mi.getName());
|
moduleNames.add(mi.getName());
|
||||||
}
|
}
|
||||||
@@ -129,7 +129,7 @@ public class CarpetScriptServer
|
|||||||
{
|
{
|
||||||
//TODO add per player modules to support player actions better on a server
|
//TODO add per player modules to support player actions better on a server
|
||||||
name = name.toLowerCase(Locale.ROOT);
|
name = name.toLowerCase(Locale.ROOT);
|
||||||
ModuleInterface module = getModule(name);
|
Module module = getModule(name);
|
||||||
if (module == null)
|
if (module == null)
|
||||||
{
|
{
|
||||||
Messenger.m(source, "r Failed to add "+name+" app");
|
Messenger.m(source, "r Failed to add "+name+" app");
|
||||||
@@ -170,13 +170,13 @@ public class CarpetScriptServer
|
|||||||
private boolean addConfig(ServerCommandSource source, String hostName)
|
private boolean addConfig(ServerCommandSource source, String hostName)
|
||||||
{
|
{
|
||||||
CarpetScriptHost host = modules.get(hostName);
|
CarpetScriptHost host = modules.get(hostName);
|
||||||
if (host == null || !host.globalFunctions.containsKey("__config"))
|
if (host == null || host.getFunction("__config") == null)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Value ret = host.callUDF(BlockPos.ORIGIN, source, host.globalFunctions.get("__config"), Collections.emptyList());
|
Value ret = host.callUDF(BlockPos.ORIGIN, source, host.getFunction("__config"), Collections.emptyList());
|
||||||
if (!(ret instanceof MapValue)) return false;
|
if (!(ret instanceof MapValue)) return false;
|
||||||
Map<Value, Value> config = ((MapValue) ret).getMap();
|
Map<Value, Value> config = ((MapValue) ret).getMap();
|
||||||
host.setPerPlayer(config.getOrDefault(new StringValue("scope"), new StringValue("player")).getString().equalsIgnoreCase("player"));
|
host.setPerPlayer(config.getOrDefault(new StringValue("scope"), new StringValue("player")).getString().equalsIgnoreCase("player"));
|
||||||
@@ -195,7 +195,7 @@ public class CarpetScriptServer
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!host.globalFunctions.containsKey("__command"))
|
if (host.getFunction("__command") == null)
|
||||||
{
|
{
|
||||||
Messenger.m(source, "gi "+hostName+" app loaded.");
|
Messenger.m(source, "gi "+hostName+" app loaded.");
|
||||||
return;
|
return;
|
||||||
@@ -217,11 +217,11 @@ public class CarpetScriptServer
|
|||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
for (String function : host.getPublicFunctions())
|
for (String function : host.globaFunctionNames(host.myCode, s -> !s.startsWith("_")).sorted().collect(Collectors.toList()))
|
||||||
{
|
{
|
||||||
command = command.
|
command = command.
|
||||||
then(literal(function).
|
then(literal(function).
|
||||||
requires((player) -> modules.containsKey(hostName) && modules.get(hostName).getPublicFunctions().contains(function)).
|
requires((player) -> modules.containsKey(hostName) && modules.get(hostName).getFunction(function) != null).
|
||||||
executes( (c) -> {
|
executes( (c) -> {
|
||||||
String response = modules.get(hostName).retrieveForExecution(c.getSource()).
|
String response = modules.get(hostName).retrieveForExecution(c.getSource()).
|
||||||
call(c.getSource(), function,null,"");
|
call(c.getSource(), function,null,"");
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package carpet.script;
|
package carpet.script;
|
||||||
|
|
||||||
|
import carpet.script.value.Value;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -26,38 +28,26 @@ public class Context
|
|||||||
this.host = host;
|
this.host = host;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LazyValue getVariable(String name)
|
LazyValue getVariable(String name)
|
||||||
{
|
{
|
||||||
if (variables.containsKey(name))
|
return variables.get(name);
|
||||||
{
|
|
||||||
return variables.get(name);
|
|
||||||
}
|
|
||||||
return host.globalVariables.get(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setVariable(String name, LazyValue lv)
|
public void setVariable(String name, LazyValue lv)
|
||||||
{
|
{
|
||||||
if (name.startsWith("global_"))
|
|
||||||
{
|
|
||||||
host.globalVariables.put(name, lv);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
variables.put(name, lv);
|
variables.put(name, lv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
boolean isAVariable(String name)
|
|
||||||
{
|
|
||||||
return variables.containsKey(name) || host.globalVariables.containsKey(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void delVariable(String variable)
|
void delVariable(String variable)
|
||||||
{
|
{
|
||||||
variables.remove(variable);
|
variables.remove(variable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void removeVariablesMatching(String varname)
|
||||||
|
{
|
||||||
|
variables.entrySet().removeIf(e -> e.getKey().startsWith(varname));
|
||||||
|
}
|
||||||
|
|
||||||
public Context with(String variable, LazyValue lv)
|
public Context with(String variable, LazyValue lv)
|
||||||
{
|
{
|
||||||
variables.put(variable, lv);
|
variables.put(variable, lv);
|
||||||
@@ -70,6 +60,21 @@ public class Context
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Context recreate()
|
public Context recreate()
|
||||||
|
{
|
||||||
|
Context ctx = duplicate();
|
||||||
|
ctx.initialize();
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void initialize()
|
||||||
|
{
|
||||||
|
//special variables for second order functions so we don't need to check them all the time
|
||||||
|
variables.put("_", (c, t) -> Value.ZERO);
|
||||||
|
variables.put("_i", (c, t) -> Value.ZERO);
|
||||||
|
variables.put("_a", (c, t) -> Value.ZERO);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Context duplicate()
|
||||||
{
|
{
|
||||||
return new Context(this.host);
|
return new Context(this.host);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,12 +11,13 @@ 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.bundled.ModuleInterface;
|
import carpet.script.bundled.Module;
|
||||||
import carpet.script.exception.BreakStatement;
|
import carpet.script.exception.BreakStatement;
|
||||||
import carpet.script.exception.ContinueStatement;
|
import carpet.script.exception.ContinueStatement;
|
||||||
import carpet.script.exception.ExitStatement;
|
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.ResolvedException;
|
||||||
import carpet.script.exception.ReturnStatement;
|
import carpet.script.exception.ReturnStatement;
|
||||||
import carpet.script.exception.ThrowStatement;
|
import carpet.script.exception.ThrowStatement;
|
||||||
import carpet.script.value.AbstractListValue;
|
import carpet.script.value.AbstractListValue;
|
||||||
@@ -332,7 +333,7 @@ import static java.lang.Math.min;
|
|||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class Expression implements Cloneable
|
public class Expression
|
||||||
{
|
{
|
||||||
private static final Map<String, Integer> precedence = new HashMap<String,Integer>() {{
|
private static final Map<String, Integer> precedence = new HashMap<String,Integer>() {{
|
||||||
put("attribute~:", 80);
|
put("attribute~:", 80);
|
||||||
@@ -366,21 +367,18 @@ public class Expression implements Cloneable
|
|||||||
private boolean allowNewlineSubstitutions = true;
|
private boolean allowNewlineSubstitutions = true;
|
||||||
private boolean allowComments = false;
|
private boolean allowComments = false;
|
||||||
|
|
||||||
public ModuleInterface module = null;
|
public Module module = null;
|
||||||
|
|
||||||
void asAModule(ModuleInterface mi)
|
void asATextSource()
|
||||||
{
|
{
|
||||||
allowNewlineSubstitutions = false;
|
allowNewlineSubstitutions = false;
|
||||||
allowComments = true;
|
allowComments = true;
|
||||||
module = mi;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String name;
|
void asAModule(Module mi)
|
||||||
String getName() {return name;}
|
|
||||||
Expression withName(String alias)
|
|
||||||
{
|
{
|
||||||
name = alias;
|
|
||||||
return this;
|
module = mi;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Cached AST (Abstract Syntax Tree) (root) of the expression */
|
/** Cached AST (Abstract Syntax Tree) (root) of the expression */
|
||||||
@@ -393,18 +391,6 @@ public class Expression implements Cloneable
|
|||||||
private final Map<String, ILazyFunction> functions = new Object2ObjectOpenHashMap<>();
|
private final Map<String, ILazyFunction> functions = new Object2ObjectOpenHashMap<>();
|
||||||
Set<String> getFunctionNames() {return functions.keySet();}
|
Set<String> getFunctionNames() {return functions.keySet();}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Expression clone() throws CloneNotSupportedException
|
|
||||||
{
|
|
||||||
// very very shallow copy for global functions to grab the context for error msgs
|
|
||||||
Expression copy = (Expression) super.clone();
|
|
||||||
copy.expression = this.expression;
|
|
||||||
copy.name = this.name;
|
|
||||||
copy.module = this.module;
|
|
||||||
return copy;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static List<String> getExpressionSnippet(Tokenizer.Token token, Expression expr)
|
static List<String> getExpressionSnippet(Tokenizer.Token token, Expression expr)
|
||||||
{
|
{
|
||||||
String code = expr.getCodeString();
|
String code = expr.getCodeString();
|
||||||
@@ -561,7 +547,7 @@ public class Expression implements Cloneable
|
|||||||
return new ExpressionException(c, e, token, exc.getMessage(), ((InternalExpressionException) exc).stack);
|
return new ExpressionException(c, e, token, exc.getMessage(), ((InternalExpressionException) exc).stack);
|
||||||
if (exc instanceof ArithmeticException)
|
if (exc instanceof ArithmeticException)
|
||||||
return new ExpressionException(c, e, token, "Your math is wrong, "+exc.getMessage());
|
return new ExpressionException(c, e, token, "Your math is wrong, "+exc.getMessage());
|
||||||
if (exc instanceof ExpressionException)
|
if (exc instanceof ResolvedException)
|
||||||
return exc;
|
return exc;
|
||||||
// unexpected really - should be caught earlier and converted to InternalExpressionException
|
// unexpected really - should be caught earlier and converted to InternalExpressionException
|
||||||
exc.printStackTrace();
|
exc.printStackTrace();
|
||||||
@@ -669,29 +655,29 @@ public class Expression implements Cloneable
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
private FunctionValue 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> outers, LazyValue code)
|
||||||
{
|
{
|
||||||
name = name.toLowerCase(Locale.ROOT);
|
name = name.toLowerCase(Locale.ROOT);
|
||||||
if (functions.containsKey(name))
|
if (functions.containsKey(name))
|
||||||
throw new ExpressionException(context, expr, token, "Function "+name+" would mask a built-in function");
|
throw new ExpressionException(context, expr, token, "Function "+name+" would mask a built-in function");
|
||||||
Map<String, LazyValue> contextValues = new HashMap<>();
|
Map<String, LazyValue> contextValues = new HashMap<>();
|
||||||
for (String global : globals)
|
for (String outer : outers)
|
||||||
{
|
{
|
||||||
LazyValue lv = context.getVariable(global);
|
LazyValue lv = context.getVariable(outer);
|
||||||
if (lv == null)
|
if (lv == null)
|
||||||
{
|
{
|
||||||
throw new InternalExpressionException("Variable "+global+" needs to be defined in outer scope to be used as outer parameter");
|
throw new InternalExpressionException("Variable "+outer+" needs to be defined in outer scope to be used as outer parameter, and cannot be global");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
contextValues.put(global, lv);
|
contextValues.put(outer, lv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (contextValues.isEmpty()) contextValues = null;
|
if (contextValues.isEmpty()) contextValues = null;
|
||||||
|
|
||||||
FunctionValue result = new FunctionValue(expr, token, name, code, arguments, contextValues);
|
FunctionValue result = new FunctionValue(expr, token, name, code, arguments, contextValues);
|
||||||
// do not store lambda definitions
|
// do not store lambda definitions
|
||||||
if (!name.equals("_")) context.host.addUserDefinedFunction(name, result);
|
if (!name.equals("_")) context.host.addUserDefinedFunction(module, name, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -869,11 +855,13 @@ public class Expression implements Cloneable
|
|||||||
public void UserDefinedFunctionsAndControlFlow() // public just to get the javadoc right
|
public void UserDefinedFunctionsAndControlFlow() // public just to get the javadoc right
|
||||||
{
|
{
|
||||||
// artificial construct to handle user defined functions and function definitions
|
// artificial construct to handle user defined functions and function definitions
|
||||||
addLazyFunction("import", 1, (c, t, lv) ->
|
addLazyFunction("import", -1, (c, t, lv) ->
|
||||||
{
|
{
|
||||||
boolean success = c.host.importModule(c, lv.get(0).evalValue(c).getString());
|
if (lv.size() < 2) throw new InternalExpressionException("'import' needs at least a module name to import, and list of values to import");
|
||||||
Value ret = new NumericValue(success);
|
String moduleName = lv.get(0).evalValue(c).getString();
|
||||||
return (cc, tt) -> ret;
|
c.host.importModule(c, moduleName);
|
||||||
|
c.host.importNames(c, module, moduleName, lv.subList(1, lv.size()).stream().map((l) -> l.evalValue(c).getString()).collect(Collectors.toList()));
|
||||||
|
return (cc, tt) -> Value.NULL;
|
||||||
});
|
});
|
||||||
|
|
||||||
addLazyFunctionWithDelegation("call",-1, (c, t, expr, tok, lv) -> { // adjust based on c
|
addLazyFunctionWithDelegation("call",-1, (c, t, expr, tok, lv) -> { // adjust based on c
|
||||||
@@ -886,9 +874,7 @@ public class Expression implements Cloneable
|
|||||||
if (!(functionValue instanceof FunctionValue))
|
if (!(functionValue instanceof FunctionValue))
|
||||||
{
|
{
|
||||||
String name = functionValue.getString();
|
String name = functionValue.getString();
|
||||||
functionValue = c.host.globalFunctions.get(name);
|
functionValue = c.host.getAssertFunction(module, name);
|
||||||
if (functionValue == null)
|
|
||||||
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);
|
||||||
for (int i=1; i< lv.size(); i++)
|
for (int i=1; i< lv.size(); i++)
|
||||||
@@ -1255,7 +1241,7 @@ public class Expression implements Cloneable
|
|||||||
{
|
{
|
||||||
String lname = li.next().getVariable();
|
String lname = li.next().getVariable();
|
||||||
Value vval = ri.next().reboundedTo(lname);
|
Value vval = ri.next().reboundedTo(lname);
|
||||||
c.setVariable(lname, (cc, tt) -> vval);
|
setAnyVariable(c, lname, (cc, tt) -> vval);
|
||||||
}
|
}
|
||||||
return (cc, tt) -> Value.TRUE;
|
return (cc, tt) -> Value.TRUE;
|
||||||
}
|
}
|
||||||
@@ -1272,7 +1258,7 @@ public class Expression implements Cloneable
|
|||||||
String varname = v1.getVariable();
|
String varname = v1.getVariable();
|
||||||
Value copy = v2.reboundedTo(varname);
|
Value copy = v2.reboundedTo(varname);
|
||||||
LazyValue boundedLHS = (cc, tt) -> copy;
|
LazyValue boundedLHS = (cc, tt) -> copy;
|
||||||
c.setVariable(varname, boundedLHS);
|
setAnyVariable(c, varname, boundedLHS);
|
||||||
return boundedLHS;
|
return boundedLHS;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1294,7 +1280,7 @@ public class Expression implements Cloneable
|
|||||||
Value lval = li.next();
|
Value lval = li.next();
|
||||||
String lname = lval.getVariable();
|
String lname = lval.getVariable();
|
||||||
Value result = lval.add(ri.next()).bindTo(lname);
|
Value result = lval.add(ri.next()).bindTo(lname);
|
||||||
c.setVariable(lname, (cc, tt) -> result);
|
setAnyVariable(c, lname, (cc, tt) -> result);
|
||||||
}
|
}
|
||||||
return (cc, tt) -> Value.TRUE;
|
return (cc, tt) -> Value.TRUE;
|
||||||
}
|
}
|
||||||
@@ -1323,7 +1309,7 @@ public class Expression implements Cloneable
|
|||||||
Value result = v1.add(v2).bindTo(varname);
|
Value result = v1.add(v2).bindTo(varname);
|
||||||
boundedLHS = (cc, tt) -> result;
|
boundedLHS = (cc, tt) -> result;
|
||||||
}
|
}
|
||||||
c.setVariable(varname, boundedLHS);
|
setAnyVariable(c, varname, boundedLHS);
|
||||||
return boundedLHS;
|
return boundedLHS;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1349,8 +1335,8 @@ public class Expression implements Cloneable
|
|||||||
String rname = rval.getVariable();
|
String rname = rval.getVariable();
|
||||||
lval.reboundedTo(rname);
|
lval.reboundedTo(rname);
|
||||||
rval.reboundedTo(lname);
|
rval.reboundedTo(lname);
|
||||||
c.setVariable(lname, (cc, tt) -> rval);
|
setAnyVariable(c, lname, (cc, tt) -> rval);
|
||||||
c.setVariable(rname, (cc, tt) -> lval);
|
setAnyVariable(c, rname, (cc, tt) -> lval);
|
||||||
}
|
}
|
||||||
return (cc, tt) -> Value.TRUE;
|
return (cc, tt) -> Value.TRUE;
|
||||||
}
|
}
|
||||||
@@ -1360,8 +1346,8 @@ public class Expression implements Cloneable
|
|||||||
String rvalvar = v2.getVariable();
|
String rvalvar = v2.getVariable();
|
||||||
Value lval = v2.reboundedTo(lvalvar);
|
Value lval = v2.reboundedTo(lvalvar);
|
||||||
Value rval = v1.reboundedTo(rvalvar);
|
Value rval = v1.reboundedTo(rvalvar);
|
||||||
c.setVariable(lvalvar, (cc, tt) -> lval);
|
setAnyVariable(c, lvalvar, (cc, tt) -> lval);
|
||||||
c.setVariable(rvalvar, (cc, tt) -> rval);
|
setAnyVariable(c, rvalvar, (cc, tt) -> rval);
|
||||||
return (cc, tt) -> lval;
|
return (cc, tt) -> lval;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -2991,9 +2977,7 @@ public class Expression implements Cloneable
|
|||||||
|
|
||||||
addLazyFunction("var", 1, (c, t, lv) -> {
|
addLazyFunction("var", 1, (c, t, lv) -> {
|
||||||
String varname = lv.get(0).evalValue(c).getString();
|
String varname = lv.get(0).evalValue(c).getString();
|
||||||
if (!c.isAVariable(varname))
|
return getOrSetAnyVariable(c, varname);
|
||||||
c.setVariable(varname, (_c, _t ) -> Value.ZERO.reboundedTo(varname));
|
|
||||||
return c.getVariable(varname);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
addLazyFunction("undef", 1, (c, t, lv) ->
|
addLazyFunction("undef", 1, (c, t, lv) ->
|
||||||
@@ -3001,7 +2985,7 @@ public class Expression implements Cloneable
|
|||||||
Value remove = lv.get(0).evalValue(c);
|
Value remove = lv.get(0).evalValue(c);
|
||||||
if (remove instanceof FunctionValue)
|
if (remove instanceof FunctionValue)
|
||||||
{
|
{
|
||||||
c.host.delFunction(remove.getString());
|
c.host.delFunction(module, remove.getString());
|
||||||
return (cc, tt) -> Value.NULL;
|
return (cc, tt) -> Value.NULL;
|
||||||
}
|
}
|
||||||
String varname = remove.getString();
|
String varname = remove.getString();
|
||||||
@@ -3010,33 +2994,24 @@ public class Expression implements Cloneable
|
|||||||
varname = varname.replaceAll("\\*+$", "");
|
varname = varname.replaceAll("\\*+$", "");
|
||||||
if (isPrefix)
|
if (isPrefix)
|
||||||
{
|
{
|
||||||
for (String key: c.host.globalFunctions.keySet())
|
c.host.delFunctionWithPrefix(module, varname);
|
||||||
{
|
|
||||||
if (key.startsWith(varname)) c.host.delFunction(key);
|
|
||||||
}
|
|
||||||
if (varname.startsWith("global_"))
|
if (varname.startsWith("global_"))
|
||||||
{
|
{
|
||||||
for (String key : c.host.globalVariables.keySet())
|
c.host.delGlobalVariableWithPrefix(module, varname);
|
||||||
{
|
|
||||||
if (key.startsWith(varname)) c.host.delGlobalVariable(key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!varname.startsWith("_"))
|
else if (!varname.startsWith("_"))
|
||||||
{
|
{
|
||||||
for (String key : c.variables.keySet())
|
c.removeVariablesMatching(varname);
|
||||||
{
|
|
||||||
if (key.startsWith(varname)) c.delVariable(key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
c.host.delFunction(varname);
|
c.host.delFunction(module, varname);
|
||||||
if (varname.startsWith("global_"))
|
if (varname.startsWith("global_"))
|
||||||
{
|
{
|
||||||
c.host.delGlobalVariable(varname);
|
c.host.delGlobalVariable(module, varname);
|
||||||
}
|
}
|
||||||
if (!varname.startsWith("_"))
|
else if (!varname.startsWith("_"))
|
||||||
{
|
{
|
||||||
c.delVariable(varname);
|
c.delVariable(varname);
|
||||||
}
|
}
|
||||||
@@ -3044,25 +3019,17 @@ public class Expression implements Cloneable
|
|||||||
return (cc, tt) -> Value.NULL;
|
return (cc, tt) -> Value.NULL;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//deprecate
|
||||||
addLazyFunction("vars", 1, (c, t, lv) -> {
|
addLazyFunction("vars", 1, (c, t, lv) -> {
|
||||||
String prefix = lv.get(0).evalValue(c).getString();
|
String prefix = lv.get(0).evalValue(c).getString();
|
||||||
List<Value> values = new ArrayList<>();
|
List<Value> values = new ArrayList<>();
|
||||||
if (prefix.startsWith("global"))
|
if (prefix.startsWith("global"))
|
||||||
{
|
{
|
||||||
for (String k: c.host.globalVariables.keySet())
|
c.host.globaVariableNames(module, (s) -> s.startsWith(prefix)).forEach(s -> values.add(new StringValue(s)));
|
||||||
{
|
|
||||||
if (k.startsWith(prefix))
|
|
||||||
values.add(new StringValue(k));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (String k: c.getAllVariableNames())
|
c.getAllVariableNames().stream().filter(s -> s.startsWith(prefix)).forEach(s -> values.add(new StringValue(s)));
|
||||||
{
|
|
||||||
if (k.startsWith(prefix))
|
|
||||||
values.add(new StringValue(k));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Value retval = ListValue.wrap(values);
|
Value retval = ListValue.wrap(values);
|
||||||
return (cc, tt) -> retval;
|
return (cc, tt) -> retval;
|
||||||
@@ -3075,9 +3042,7 @@ public class Expression implements Cloneable
|
|||||||
if (!(funcDesc instanceof FunctionValue))
|
if (!(funcDesc instanceof FunctionValue))
|
||||||
{
|
{
|
||||||
String name = funcDesc.getString();
|
String name = funcDesc.getString();
|
||||||
funcDesc = c.host.globalFunctions.get(name);
|
funcDesc = c.host.getAssertFunction(module, name);
|
||||||
if (funcDesc == null)
|
|
||||||
throw new InternalExpressionException("Function "+name+" is not defined yet");
|
|
||||||
}
|
}
|
||||||
FunctionValue fun = (FunctionValue)funcDesc;
|
FunctionValue fun = (FunctionValue)funcDesc;
|
||||||
int extraargs = lv.size() - fun.getArguments().size();
|
int extraargs = lv.size() - fun.getArguments().size();
|
||||||
@@ -3127,6 +3092,33 @@ public class Expression implements Cloneable
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void setAnyVariable(Context c, String name, LazyValue lv)
|
||||||
|
{
|
||||||
|
if (name.startsWith("global_"))
|
||||||
|
{
|
||||||
|
c.host.setGlobalVariable(module, name, lv);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c.setVariable(name, lv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private LazyValue getOrSetAnyVariable(Context c, String name)
|
||||||
|
{
|
||||||
|
LazyValue var = null;
|
||||||
|
if (!name.startsWith("global_"))
|
||||||
|
{
|
||||||
|
var = c.getVariable(name);
|
||||||
|
if (var != null) return var;
|
||||||
|
}
|
||||||
|
var = c.host.getGlobalVariable(module, name);
|
||||||
|
if (var != null) return var;
|
||||||
|
var = (_c, _t ) -> Value.ZERO.reboundedTo(name);
|
||||||
|
setAnyVariable(c, name, var);
|
||||||
|
return var;
|
||||||
|
}
|
||||||
|
|
||||||
static final Expression none = new Expression("null");
|
static final Expression none = new Expression("null");
|
||||||
/**
|
/**
|
||||||
* @param expression .
|
* @param expression .
|
||||||
@@ -3143,6 +3135,7 @@ public class Expression implements Cloneable
|
|||||||
BasicDataStructures();
|
BasicDataStructures();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private List<Tokenizer.Token> shuntingYard(Context c)
|
private List<Tokenizer.Token> shuntingYard(Context c)
|
||||||
{
|
{
|
||||||
List<Tokenizer.Token> outputQueue = new ArrayList<>();
|
List<Tokenizer.Token> outputQueue = new ArrayList<>();
|
||||||
@@ -3267,7 +3260,7 @@ public class Expression implements Cloneable
|
|||||||
}
|
}
|
||||||
if (stack.isEmpty())
|
if (stack.isEmpty())
|
||||||
{
|
{
|
||||||
throw new ExpressionException(c, "Mismatched parentheses");
|
throw new ExpressionException(c, this, "Mismatched parentheses");
|
||||||
}
|
}
|
||||||
stack.pop();
|
stack.pop();
|
||||||
if (!stack.isEmpty() && stack.peek().type == Tokenizer.Token.TokenType.FUNCTION)
|
if (!stack.isEmpty() && stack.peek().type == Tokenizer.Token.TokenType.FUNCTION)
|
||||||
@@ -3325,7 +3318,7 @@ public class Expression implements Cloneable
|
|||||||
return evalValue(() -> ast, c, expectedType);
|
return evalValue(() -> ast, c, expectedType);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Value evalValue(Supplier<LazyValue> exprProvider, Context c, Integer expectedType)
|
Value evalValue(Supplier<LazyValue> exprProvider, Context c, Integer expectedType)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -3333,7 +3326,7 @@ public class Expression implements Cloneable
|
|||||||
}
|
}
|
||||||
catch (ContinueStatement | BreakStatement | ReturnStatement exc)
|
catch (ContinueStatement | BreakStatement | ReturnStatement exc)
|
||||||
{
|
{
|
||||||
throw new ExpressionException(c, "Control flow functions, like continue, break, or return, should only be used in loops and functions respectively.");
|
throw new ExpressionException(c, this, "Control flow functions, like continue, break, or return, should only be used in loops and functions respectively.");
|
||||||
}
|
}
|
||||||
catch (ExitStatement exit)
|
catch (ExitStatement exit)
|
||||||
{
|
{
|
||||||
@@ -3341,15 +3334,15 @@ public class Expression implements Cloneable
|
|||||||
}
|
}
|
||||||
catch (StackOverflowError ignored)
|
catch (StackOverflowError ignored)
|
||||||
{
|
{
|
||||||
throw new ExpressionException(c, "Your thoughts are too deep");
|
throw new ExpressionException(c, this, "Your thoughts are too deep");
|
||||||
}
|
}
|
||||||
catch (InternalExpressionException exc)
|
catch (InternalExpressionException exc)
|
||||||
{
|
{
|
||||||
throw new ExpressionException(c, "Your expression result is incorrect:"+exc.getMessage());
|
throw new ExpressionException(c, this, "Your expression result is incorrect:"+exc.getMessage());
|
||||||
}
|
}
|
||||||
catch (ArithmeticException exc)
|
catch (ArithmeticException exc)
|
||||||
{
|
{
|
||||||
throw new ExpressionException(c, "The final result is incorrect, "+exc.getMessage());
|
throw new ExpressionException(c, this, "The final result is incorrect, "+exc.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3376,15 +3369,7 @@ public class Expression implements Cloneable
|
|||||||
stack.push(result);
|
stack.push(result);
|
||||||
break;
|
break;
|
||||||
case VARIABLE:
|
case VARIABLE:
|
||||||
stack.push((c, t) ->
|
stack.push((c, t) -> getOrSetAnyVariable(c, token.surface).evalValue(c));
|
||||||
{
|
|
||||||
if (!c.isAVariable(token.surface)) // new variable
|
|
||||||
{
|
|
||||||
c.setVariable(token.surface, (cc, tt ) -> Value.ZERO.reboundedTo(token.surface));
|
|
||||||
}
|
|
||||||
LazyValue lazyVariable = c.getVariable(token.surface);
|
|
||||||
return lazyVariable.evalValue(c);
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
case FUNCTION:
|
case FUNCTION:
|
||||||
String name = token.surface.toLowerCase(Locale.ROOT);
|
String name = token.surface.toLowerCase(Locale.ROOT);
|
||||||
@@ -3507,15 +3492,15 @@ public class Expression implements Cloneable
|
|||||||
|
|
||||||
if (stack.size() > 1)
|
if (stack.size() > 1)
|
||||||
{
|
{
|
||||||
throw new ExpressionException(c, "Too many unhandled function parameter lists");
|
throw new ExpressionException(c, this, "Too many unhandled function parameter lists");
|
||||||
}
|
}
|
||||||
else if (stack.peek() > 1)
|
else if (stack.peek() > 1)
|
||||||
{
|
{
|
||||||
throw new ExpressionException(c, "Too many numbers or variables");
|
throw new ExpressionException(c, this, "Too many numbers or variables");
|
||||||
}
|
}
|
||||||
else if (stack.peek() < 1)
|
else if (stack.peek() < 1)
|
||||||
{
|
{
|
||||||
throw new ExpressionException(c, "Empty expression");
|
throw new ExpressionException(c, this, "Empty expression");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package carpet.script;
|
package carpet.script;
|
||||||
|
|
||||||
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;
|
||||||
@@ -21,31 +20,17 @@ public class ExpressionInspector
|
|||||||
return Expression.getExpressionSnippet(token, expr);
|
return Expression.getExpressionSnippet(token, expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String Expression_getName(Expression e)
|
public static String Expression_getModuleName(Expression e)
|
||||||
{
|
{
|
||||||
return e.getName();
|
return e.module == null?null:e.module.getName();
|
||||||
}
|
|
||||||
|
|
||||||
public static Expression Expression_cloneWithName(Expression e, Context c, String name, Tokenizer.Token token)
|
|
||||||
{
|
|
||||||
Expression copy;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
copy = e.clone();
|
|
||||||
}
|
|
||||||
catch (CloneNotSupportedException ex)
|
|
||||||
{
|
|
||||||
throw new ExpressionException(c, 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
|
||||||
{
|
{
|
||||||
Set<String> allFunctions = (new CarpetExpression("null", null, null)).getExpr().getFunctionNames();
|
Set<String> allFunctions = (new CarpetExpression(null, "null", null, null)).getExpr().getFunctionNames();
|
||||||
scarpetFunctions = new TreeSet<>(new Expression("null").getFunctionNames());
|
scarpetFunctions = new TreeSet<>(Expression.none.getFunctionNames());
|
||||||
APIFunctions = allFunctions.stream().filter(s -> !scarpetFunctions.contains(s)).collect(Collectors.toCollection(TreeSet::new));
|
APIFunctions = allFunctions.stream().filter(s -> !scarpetFunctions.contains(s)).collect(Collectors.toCollection(TreeSet::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -63,10 +48,8 @@ public class ExpressionInspector
|
|||||||
// not that useful in commandline, more so in external scripts, so skipping here
|
// not that useful in commandline, more so in external scripts, so skipping here
|
||||||
//scarpetMatches.addAll(CarpetServer.scriptServer.events.eventHandlers.keySet().stream().
|
//scarpetMatches.addAll(CarpetServer.scriptServer.events.eventHandlers.keySet().stream().
|
||||||
// filter(s -> s.startsWith(prefix) && s.length() <= maxLen).map(s -> "__"+s+"(").collect(Collectors.toList()));
|
// filter(s -> s.startsWith(prefix) && s.length() <= maxLen).map(s -> "__"+s+"(").collect(Collectors.toList()));
|
||||||
scarpetMatches.addAll(host.globalFunctions.keySet().stream().
|
scarpetMatches.addAll(host.globaFunctionNames(host.myCode, s -> s.startsWith(prefix)).map(s -> s+"(").collect(Collectors.toList()));
|
||||||
filter(s -> s.startsWith(prefix)).map(s -> s+"(").collect(Collectors.toList()));
|
scarpetMatches.addAll(host.globaVariableNames(host.myCode, s -> s.startsWith(prefix)).collect(Collectors.toList()));
|
||||||
scarpetMatches.addAll(host.globalVariables.keySet().stream().
|
|
||||||
filter(s -> s.startsWith(prefix)).collect(Collectors.toList()));
|
|
||||||
return scarpetMatches;
|
return scarpetMatches;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,111 +1,292 @@
|
|||||||
package carpet.script;
|
package carpet.script;
|
||||||
|
|
||||||
import carpet.script.bundled.ModuleInterface;
|
import carpet.script.bundled.Module;
|
||||||
|
import carpet.script.exception.InternalExpressionException;
|
||||||
import carpet.script.value.FunctionValue;
|
import carpet.script.value.FunctionValue;
|
||||||
import carpet.script.value.Value;
|
import carpet.script.value.Value;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public abstract class ScriptHost
|
public abstract class ScriptHost
|
||||||
{
|
{
|
||||||
|
public class ModuleData
|
||||||
|
{
|
||||||
|
Module parent;
|
||||||
|
public Map<String, FunctionValue> globalFunctions = new Object2ObjectOpenHashMap<>();
|
||||||
|
public Map<String, LazyValue> globalVariables = new Object2ObjectOpenHashMap<>();
|
||||||
|
public Map<String, ModuleData> functionImports = new Object2ObjectOpenHashMap<>(); // imported functions string to module
|
||||||
|
public Map<String, ModuleData> globalsImports = new Object2ObjectOpenHashMap<>(); // imported global variables string to module
|
||||||
|
public Map<String, ModuleData> futureImports = new Object2ObjectOpenHashMap<>(); // imports not known before used
|
||||||
|
|
||||||
|
public ModuleData(Module parent, ModuleData other)
|
||||||
|
{
|
||||||
|
// imports are just pointers, but they still point to the wrong modules (point to the parent)
|
||||||
|
this.parent = parent;
|
||||||
|
globalFunctions.putAll(other.globalFunctions);
|
||||||
|
other.globalVariables.forEach((key, value) ->
|
||||||
|
{
|
||||||
|
Value var = value.evalValue(null);
|
||||||
|
Value copy = var.deepcopy();
|
||||||
|
copy.boundVariable = var.boundVariable;
|
||||||
|
globalVariables.put(key, (c, t) -> copy);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setImportsBasedOn(ScriptHost host, ModuleData other)
|
||||||
|
{
|
||||||
|
// fixing imports
|
||||||
|
other.functionImports.forEach((name, targetData) -> {
|
||||||
|
functionImports.put(name, host.moduleData.get(targetData.parent));
|
||||||
|
});
|
||||||
|
other.globalsImports.forEach((name, targetData) -> {
|
||||||
|
globalsImports.put(name, host.moduleData.get(targetData.parent));
|
||||||
|
});
|
||||||
|
other.futureImports.forEach((name, targetData) -> {
|
||||||
|
futureImports.put(name, host.moduleData.get(targetData.parent));
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModuleData(Module parent)
|
||||||
|
{
|
||||||
|
this.parent = parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
protected final Map<String, ScriptHost> userHosts = new Object2ObjectOpenHashMap<>();
|
protected final Map<String, ScriptHost> userHosts = new Object2ObjectOpenHashMap<>();
|
||||||
public Map<String, FunctionValue> globalFunctions = new Object2ObjectOpenHashMap<>();
|
private Map<Module,ModuleData> moduleData = new HashMap<>(); // marking imports
|
||||||
public Map<String, LazyValue> globalVariables = new Object2ObjectOpenHashMap<>();
|
private Map<String,Module> modules = new HashMap<>();
|
||||||
private Set<String> imports = new HashSet<>();
|
|
||||||
|
|
||||||
protected ScriptHost parent;
|
protected ScriptHost parent;
|
||||||
protected boolean perUser;
|
protected boolean perUser;
|
||||||
|
|
||||||
//private String name;
|
|
||||||
public String getName() {return myCode==null?null:myCode.getName();}
|
public String getName() {return myCode==null?null:myCode.getName();}
|
||||||
|
|
||||||
protected final ModuleInterface myCode;
|
public final Module myCode;
|
||||||
|
|
||||||
public Fluff.TriFunction<Expression, Tokenizer.Token, String, List<String>> errorSnooper = null;
|
public Fluff.TriFunction<Expression, Tokenizer.Token, String, List<String>> errorSnooper = null;
|
||||||
|
|
||||||
ScriptHost(ModuleInterface code, boolean perUser, ScriptHost parent)
|
protected ScriptHost(Module code, boolean perUser, ScriptHost parent)
|
||||||
{
|
{
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
//this.name = name;
|
|
||||||
this.myCode = code;
|
this.myCode = code;
|
||||||
this.perUser = perUser;
|
this.perUser = perUser;
|
||||||
if (code != null) imports.add(code.getName());
|
ModuleData moduleData = new ModuleData(code);
|
||||||
globalVariables.put("euler", (c, t) -> Expression.euler);
|
initializeModuleGlobals(moduleData);
|
||||||
globalVariables.put("pi", (c, t) -> Expression.PI);
|
this.moduleData.put(code, moduleData);
|
||||||
globalVariables.put("null", (c, t) -> Value.NULL);
|
this.modules.put(code==null?null:code.getName(), code);
|
||||||
globalVariables.put("true", (c, t) -> Value.TRUE);
|
|
||||||
globalVariables.put("false", (c, t) -> Value.FALSE);
|
|
||||||
|
|
||||||
//special variables for second order functions so we don't need to check them all the time
|
|
||||||
globalVariables.put("_", (c, t) -> Value.ZERO);
|
|
||||||
globalVariables.put("_i", (c, t) -> Value.ZERO);
|
|
||||||
globalVariables.put("_a", (c, t) -> Value.ZERO);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addUserDefinedFunction(String funName, FunctionValue function)
|
void initializeModuleGlobals(ModuleData md)
|
||||||
{
|
{
|
||||||
globalFunctions.put(funName, function);
|
md.globalVariables.put("euler", (c, t) -> Expression.euler);
|
||||||
|
md.globalVariables.put("pi", (c, t) -> Expression.PI);
|
||||||
|
md.globalVariables.put("null", (c, t) -> Value.NULL);
|
||||||
|
md.globalVariables.put("true", (c, t) -> Value.TRUE);
|
||||||
|
md.globalVariables.put("false", (c, t) -> Value.FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean importModule(Context c, String moduleName)
|
public void importModule(Context c, String moduleName)
|
||||||
{
|
{
|
||||||
if (imports.contains(moduleName)) return false; // aready imported
|
if (modules.containsKey(moduleName)) return; // aready imported
|
||||||
ModuleInterface module = getModuleByName(moduleName);
|
Module module = getModuleByName(moduleName);
|
||||||
if (imports.contains(module.getName())) return false; // aready imported, once again, in case some discrepancies
|
if (modules.containsKey(module.getName())) return; // aready imported, once again, in case some discrepancies in names?
|
||||||
imports.add(module.getName());
|
modules.put(module.getName(), module);
|
||||||
if (runModuleCode(c, module))
|
ModuleData data = new ModuleData(module);
|
||||||
|
initializeModuleGlobals(data);
|
||||||
|
moduleData.put(module, data);
|
||||||
|
runModuleCode(c, module);
|
||||||
|
//moduleData.remove(module); // we are pooped already, but doesn't hurt to clean that up.
|
||||||
|
//modules.remove(module.getName());
|
||||||
|
//throw new InternalExpressionException("Failed to import a module "+moduleName);
|
||||||
|
}
|
||||||
|
public void importNames(Context c, Module targetModule, String sourceModuleName, List<String> identifiers )
|
||||||
|
{
|
||||||
|
if (!moduleData.containsKey(targetModule))
|
||||||
{
|
{
|
||||||
return true;
|
throw new InternalExpressionException("Cannot import to module that doesn't exist");
|
||||||
|
}
|
||||||
|
Module source = modules.get(sourceModuleName);
|
||||||
|
ModuleData sourceData = moduleData.get(source);
|
||||||
|
ModuleData targetData = moduleData.get(targetModule);
|
||||||
|
if (sourceData == null || targetData == null)
|
||||||
|
{
|
||||||
|
throw new InternalExpressionException("Cannot import from module that is not imported");
|
||||||
|
}
|
||||||
|
for (String identifier: identifiers)
|
||||||
|
{
|
||||||
|
if (sourceData.globalFunctions.containsKey(identifier))
|
||||||
|
{
|
||||||
|
targetData.functionImports.put(identifier, sourceData);
|
||||||
|
}
|
||||||
|
else if (sourceData.globalVariables.containsKey(identifier))
|
||||||
|
{
|
||||||
|
targetData.globalsImports.put(identifier, sourceData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
targetData.functionImports.put(identifier, sourceData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
imports.remove(module.getName());
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract ModuleInterface getModuleByName(String name); // this should be shell out in the executuor
|
protected abstract Module getModuleByName(String name); // this should be shell out in the executor
|
||||||
|
|
||||||
protected abstract boolean runModuleCode(Context c, ModuleInterface module); // this should be shell out in the executuor
|
protected abstract void runModuleCode(Context c, Module module); // this should be shell out in the executor
|
||||||
|
|
||||||
public void delFunction(String funName)
|
public FunctionValue getFunction(String name) { return getFunction(myCode, name); }
|
||||||
|
public FunctionValue getAssertFunction(Module module, String name)
|
||||||
{
|
{
|
||||||
globalFunctions.remove(funName);
|
FunctionValue ret = getFunction(module, name);
|
||||||
|
if (ret == null) throw new InternalExpressionException("Function "+name+" is not defined yet");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
private FunctionValue getFunction(Module module, String name)
|
||||||
|
{
|
||||||
|
ModuleData local = moduleData.get(module);
|
||||||
|
FunctionValue ret = local.globalFunctions.get(name); // most uses would be from local scope anyways
|
||||||
|
if (ret != null) return ret;
|
||||||
|
ModuleData target = local.functionImports.get(name);
|
||||||
|
if (target != null)
|
||||||
|
{
|
||||||
|
ret = target.globalFunctions.get(name);
|
||||||
|
if (ret != null) return ret;
|
||||||
|
}
|
||||||
|
// not in local scope - will need to travel over import links
|
||||||
|
target = local.futureImports.get(name);
|
||||||
|
if (target == null) return null;
|
||||||
|
target = findModuleDataFromFunctionImports(name, target, 0);
|
||||||
|
if (target == null) return null;
|
||||||
|
local.futureImports.remove(name);
|
||||||
|
local.functionImports.put(name, target);
|
||||||
|
return target.globalFunctions.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delGlobalVariable(String varName)
|
private ModuleData findModuleDataFromFunctionImports(String name, ModuleData source, int ttl)
|
||||||
{
|
{
|
||||||
globalVariables.remove(varName);
|
if (ttl > 10) throw new InternalExpressionException("Cannot import "+name+", either your imports are too deep or too loopy");
|
||||||
|
if (source.globalFunctions.containsKey(name))
|
||||||
|
return source;
|
||||||
|
if (source.functionImports.containsKey(name))
|
||||||
|
return findModuleDataFromFunctionImports(name, source.functionImports.get(name), ttl+1);
|
||||||
|
if (source.futureImports.containsKey(name))
|
||||||
|
return findModuleDataFromFunctionImports(name, source.futureImports.get(name), ttl+1);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LazyValue getGlobalVariable(String name) { return getGlobalVariable(myCode, name); }
|
||||||
|
public LazyValue getGlobalVariable(Module module, String name)
|
||||||
|
{
|
||||||
|
ModuleData local = moduleData.get(module);
|
||||||
|
LazyValue ret = local.globalVariables.get(name); // most uses would be from local scope anyways
|
||||||
|
if (ret != null) return ret;
|
||||||
|
ModuleData target = local.globalsImports.get(name);
|
||||||
|
if (target != null)
|
||||||
|
{
|
||||||
|
ret = target.globalVariables.get(name);
|
||||||
|
if (ret != null) return ret;
|
||||||
|
}
|
||||||
|
// not in local scope - will need to travel over import links
|
||||||
|
target = local.futureImports.get(name);
|
||||||
|
if (target == null) return null;
|
||||||
|
target = findModuleDataFromGlobalImports(name, target, 0);
|
||||||
|
if (target == null) return null;
|
||||||
|
local.futureImports.remove(name);
|
||||||
|
local.globalsImports.put(name, target);
|
||||||
|
return target.globalVariables.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ModuleData findModuleDataFromGlobalImports(String name, ModuleData source, int ttl)
|
||||||
|
{
|
||||||
|
if (ttl > 10) throw new InternalExpressionException("Cannot import "+name+", either your imports are too deep or too loopy");
|
||||||
|
if (source.globalVariables.containsKey(name))
|
||||||
|
return source;
|
||||||
|
if (source.globalsImports.containsKey(name))
|
||||||
|
return findModuleDataFromGlobalImports(name, source.globalsImports.get(name), ttl+1);
|
||||||
|
if (source.futureImports.containsKey(name))
|
||||||
|
return findModuleDataFromGlobalImports(name, source.futureImports.get(name), ttl+1);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delFunctionWithPrefix(Module module, String prefix)
|
||||||
|
{
|
||||||
|
ModuleData data = moduleData.get(module);
|
||||||
|
data.globalFunctions.entrySet().removeIf(e -> e.getKey().startsWith(prefix));
|
||||||
|
data.functionImports.entrySet().removeIf(e -> e.getKey().startsWith(prefix));
|
||||||
|
}
|
||||||
|
public void delFunction(Module module, String funName)
|
||||||
|
{
|
||||||
|
ModuleData data = moduleData.get(module);
|
||||||
|
data.globalFunctions.remove(funName);
|
||||||
|
data.functionImports.remove(funName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delGlobalVariableWithPrefix(Module module, String prefix)
|
||||||
|
{
|
||||||
|
ModuleData data = moduleData.get(module);
|
||||||
|
data.globalVariables.entrySet().removeIf(e -> e.getKey().startsWith(prefix));
|
||||||
|
data.globalsImports.entrySet().removeIf(e -> e.getKey().startsWith(prefix));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delGlobalVariable(Module module, String varName)
|
||||||
|
{
|
||||||
|
ModuleData data = moduleData.get(module);
|
||||||
|
data.globalFunctions.remove(varName);
|
||||||
|
data.functionImports.remove(varName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addUserDefinedFunction(Module module, String name, FunctionValue fun)
|
||||||
|
{
|
||||||
|
moduleData.get(module).globalFunctions.put(name, fun);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGlobalVariable(Module module, String name, LazyValue lv)
|
||||||
|
{
|
||||||
|
moduleData.get(module).globalVariables.put(name, lv);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stream<String> globaVariableNames(Module module, Predicate<String> predicate)
|
||||||
|
{
|
||||||
|
return Stream.concat(
|
||||||
|
moduleData.get(module).globalVariables.keySet().stream(),
|
||||||
|
moduleData.get(module).globalsImports.keySet().stream()
|
||||||
|
).filter(predicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stream<String> globaFunctionNames(Module module, Predicate<String> predicate)
|
||||||
|
{
|
||||||
|
return Stream.concat(
|
||||||
|
moduleData.get(module).globalFunctions.keySet().stream(),
|
||||||
|
moduleData.get(module).functionImports.keySet().stream()
|
||||||
|
).filter(predicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScriptHost retrieveForExecution(String /*Nullable*/ user)
|
public ScriptHost retrieveForExecution(String /*Nullable*/ user)
|
||||||
{
|
{
|
||||||
if (!perUser)
|
if (!perUser) return this;
|
||||||
return this;
|
ScriptHost oldUserHost = userHosts.get(user);
|
||||||
ScriptHost userHost = userHosts.get(user);
|
if (oldUserHost != null) return oldUserHost;
|
||||||
if (userHost != null)
|
ScriptHost userHost = this.duplicate();
|
||||||
return userHost;
|
userHost.modules.putAll(this.modules);
|
||||||
userHost = this.duplicate();
|
for (Map.Entry<Module, ScriptHost.ModuleData> e : this.moduleData.entrySet())
|
||||||
userHost.globalVariables.putAll(this.globalVariables);
|
{
|
||||||
userHost.globalFunctions.putAll(this.globalFunctions);
|
userHost.moduleData.put(e.getKey(), new ModuleData(e.getKey(), e.getValue()));
|
||||||
userHost.imports.addAll(this.imports);
|
}
|
||||||
|
// fixing imports
|
||||||
|
userHost.moduleData.forEach((module, data) ->
|
||||||
|
{
|
||||||
|
data.setImportsBasedOn(this, this.moduleData.get(data.parent));
|
||||||
|
});
|
||||||
userHosts.put(user, userHost);
|
userHosts.put(user, userHost);
|
||||||
return userHost;
|
return userHost;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract ScriptHost duplicate();
|
protected abstract ScriptHost duplicate();
|
||||||
|
|
||||||
public List<String> getPublicFunctions()
|
|
||||||
{
|
|
||||||
return globalFunctions.keySet().stream().filter((str) -> !str.startsWith("_")).sorted().collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
public List<String> getAvailableFunctions(boolean all)
|
|
||||||
{
|
|
||||||
return globalFunctions.keySet().stream().filter((str) -> all || !str.startsWith("__")).sorted().collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onClose() { }
|
public void onClose() { }
|
||||||
|
|
||||||
public void setPerPlayer(boolean isPerUser)
|
public void setPerPlayer(boolean isPerUser)
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import java.io.IOException;
|
|||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
public class BundledModule implements ModuleInterface
|
public class BundledModule extends Module
|
||||||
{
|
{
|
||||||
private String name;
|
private String name;
|
||||||
private String code;
|
private String code;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import java.io.IOException;
|
|||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
public class FileModule implements ModuleInterface
|
public class FileModule extends Module
|
||||||
{
|
{
|
||||||
private String name;
|
private String name;
|
||||||
private String code;
|
private String code;
|
||||||
|
|||||||
+12
-6
@@ -10,13 +10,13 @@ import java.nio.file.Files;
|
|||||||
import static carpet.script.bundled.FileModule.read;
|
import static carpet.script.bundled.FileModule.read;
|
||||||
import static carpet.script.bundled.FileModule.write;
|
import static carpet.script.bundled.FileModule.write;
|
||||||
|
|
||||||
public interface ModuleInterface
|
public abstract class Module
|
||||||
{
|
{
|
||||||
String getName();
|
public abstract String getName();
|
||||||
String getCode();
|
public abstract String getCode();
|
||||||
default boolean isInternal() {return true; }
|
public boolean isInternal() {return true; }
|
||||||
|
|
||||||
default Tag getData(String file)
|
public Tag getData(String file)
|
||||||
{
|
{
|
||||||
File dataFile = CarpetServer.minecraft_server.getLevelStorage().resolveFile(
|
File dataFile = CarpetServer.minecraft_server.getLevelStorage().resolveFile(
|
||||||
CarpetServer.minecraft_server.getLevelName(), "scripts/"+getName()+".data"+(file==null?"":"."+file)+".nbt");
|
CarpetServer.minecraft_server.getLevelName(), "scripts/"+getName()+".data"+(file==null?"":"."+file)+".nbt");
|
||||||
@@ -24,7 +24,7 @@ public interface ModuleInterface
|
|||||||
return read(dataFile);
|
return read(dataFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
default void saveData(String file, Tag globalState)
|
public void saveData(String file, Tag globalState)
|
||||||
{
|
{
|
||||||
File dataFile =CarpetServer.minecraft_server.getLevelStorage().resolveFile(
|
File dataFile =CarpetServer.minecraft_server.getLevelStorage().resolveFile(
|
||||||
CarpetServer.minecraft_server.getLevelName(), "scripts/"+getName()+".data"+(file==null?"":"."+file)+".nbt");
|
CarpetServer.minecraft_server.getLevelName(), "scripts/"+getName()+".data"+(file==null?"":"."+file)+".nbt");
|
||||||
@@ -41,4 +41,10 @@ public interface ModuleInterface
|
|||||||
write(globalState, dataFile);
|
write(globalState, dataFile);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
return getName().hashCode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -6,7 +6,7 @@ import net.minecraft.server.command.ServerCommandSource;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class CarpetExpressionException extends RuntimeException
|
public class CarpetExpressionException extends RuntimeException implements ResolvedException
|
||||||
{
|
{
|
||||||
public final List<FunctionValue> stack;
|
public final List<FunctionValue> stack;
|
||||||
|
|
||||||
|
|||||||
@@ -10,16 +10,17 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static carpet.script.ExpressionInspector.Expression_getExpressionSnippet;
|
import static carpet.script.ExpressionInspector.Expression_getExpressionSnippet;
|
||||||
import static carpet.script.ExpressionInspector.Expression_getName;
|
import static carpet.script.ExpressionInspector.Expression_getModuleName;
|
||||||
|
|
||||||
/* The expression evaluators exception class. */
|
/* The expression evaluators exception class. */
|
||||||
public class ExpressionException extends RuntimeException
|
public class ExpressionException extends RuntimeException implements ResolvedException
|
||||||
{
|
{
|
||||||
public final Context context;
|
public final Context context;
|
||||||
public final List<FunctionValue> stack = new ArrayList<>();
|
public final List<FunctionValue> stack = new ArrayList<>();
|
||||||
public ExpressionException(Context c, String message)
|
|
||||||
|
public ExpressionException(Context c, Expression e, String message)
|
||||||
{
|
{
|
||||||
super(makeMessage(c, null, null, message));
|
super(makeMessage(c, e, null, message));
|
||||||
context = c;
|
context = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,11 +36,12 @@ public class ExpressionException extends RuntimeException
|
|||||||
context = c;
|
context = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Fluff.TriFunction<Expression, Tokenizer.Token, String, List<String>> errorMaker = (expr, token, errmessage) ->
|
private static final Fluff.TriFunction<Expression, Tokenizer.Token, String, List<String>> errorMaker = (expr, /*Nullable*/ token, errmessage) ->
|
||||||
{
|
{
|
||||||
|
|
||||||
List<String> errMsg = new ArrayList<>();
|
List<String> errMsg = new ArrayList<>();
|
||||||
if (expr != null && token != null)
|
errmessage += Expression_getModuleName(expr) == null?"":(" in "+Expression_getModuleName(expr));
|
||||||
|
if (token != null)
|
||||||
{
|
{
|
||||||
List<String> snippet = Expression_getExpressionSnippet(token, expr);
|
List<String> snippet = Expression_getExpressionSnippet(token, expr);
|
||||||
errMsg.addAll(snippet);
|
errMsg.addAll(snippet);
|
||||||
@@ -52,11 +54,6 @@ public class ExpressionException extends RuntimeException
|
|||||||
{
|
{
|
||||||
errmessage += " at pos " + (token.pos + 1);
|
errmessage += " at pos " + (token.pos + 1);
|
||||||
}
|
}
|
||||||
if (Expression_getName(expr) != null)
|
|
||||||
{
|
|
||||||
errmessage += " (" + Expression_getName(expr) + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
errMsg.add(errmessage);
|
errMsg.add(errmessage);
|
||||||
return errMsg;
|
return errMsg;
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package carpet.script.exception;
|
||||||
|
|
||||||
|
public interface ResolvedException
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -6,7 +6,6 @@ import carpet.script.ExpressionInspector;
|
|||||||
import carpet.script.Fluff;
|
import carpet.script.Fluff;
|
||||||
import carpet.script.LazyValue;
|
import carpet.script.LazyValue;
|
||||||
import carpet.script.Tokenizer;
|
import carpet.script.Tokenizer;
|
||||||
import carpet.script.bundled.ModuleInterface;
|
|
||||||
import carpet.script.exception.BreakStatement;
|
import carpet.script.exception.BreakStatement;
|
||||||
import carpet.script.exception.ContinueStatement;
|
import carpet.script.exception.ContinueStatement;
|
||||||
import carpet.script.exception.ExitStatement;
|
import carpet.script.exception.ExitStatement;
|
||||||
@@ -128,11 +127,9 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
|||||||
|
|
||||||
public LazyValue callInContext(Expression callingExpression, Context c, Integer type, Expression e, Tokenizer.Token t, List<LazyValue> lazyParams)
|
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 (errata: needed to know the package to report with exceptions
|
|
||||||
Expression callContext = ExpressionInspector.Expression_cloneWithName(e, c, fullName(), t);
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return lazyEval(c, type, callContext, t, lazyParams);
|
return lazyEval(c, type, e, t, lazyParams);
|
||||||
}
|
}
|
||||||
catch (ExpressionException exc)
|
catch (ExpressionException exc)
|
||||||
{
|
{
|
||||||
@@ -142,12 +139,12 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
|||||||
catch (InternalExpressionException exc)
|
catch (InternalExpressionException exc)
|
||||||
{
|
{
|
||||||
exc.stack.add(this);
|
exc.stack.add(this);
|
||||||
throw new ExpressionException(c, callContext, t, exc.getMessage(), exc.stack);
|
throw new ExpressionException(c, e, t, exc.getMessage(), exc.stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (ArithmeticException exc)
|
catch (ArithmeticException exc)
|
||||||
{
|
{
|
||||||
throw new ExpressionException(c, callContext, t, "Your math is wrong, "+exc.getMessage(), Collections.singletonList(this));
|
throw new ExpressionException(c, e, t, "Your math is wrong, "+exc.getMessage(), Collections.singletonList(this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,14 +187,10 @@ public class FunctionValue extends Value implements Fluff.ILazyFunction
|
|||||||
retVal = throwStatement.retval;
|
retVal = throwStatement.retval;
|
||||||
rethrow = true;
|
rethrow = true;
|
||||||
}
|
}
|
||||||
catch (ArithmeticException | ExitStatement | ExpressionException | InternalExpressionException exc )
|
//catch (ArithmeticException | ExitStatement | ExpressionException | InternalExpressionException exc )
|
||||||
{
|
//{
|
||||||
throw exc; // rethrow so could be contextualized if needed
|
// throw exc; // rethrow so could be contextualized if needed
|
||||||
}
|
//}
|
||||||
catch (Exception exc)
|
|
||||||
{
|
|
||||||
throw new ExpressionException(c, e, t, "Error while evaluating expression: "+exc.getMessage());
|
|
||||||
}
|
|
||||||
if (rethrow)
|
if (rethrow)
|
||||||
{
|
{
|
||||||
throw new ThrowStatement(retVal);
|
throw new ThrowStatement(retVal);
|
||||||
|
|||||||
Reference in new issue
Block a user