Skip to content

Commit c3e1119

Browse files
committed
Thread-local and global variables. Fix deleting variables.
1 parent 2d278d1 commit c3e1119

21 files changed

+459
-26
lines changed

src/main/java/mx/kenzie/skript/compiler/SkriptLangSpec.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@
4242
import mx.kenzie.skript.lang.syntax.map.MapCreator;
4343
import mx.kenzie.skript.lang.syntax.maths.*;
4444
import mx.kenzie.skript.lang.syntax.timing.*;
45+
import mx.kenzie.skript.lang.syntax.variable.AtomicVariableExpression;
46+
import mx.kenzie.skript.lang.syntax.variable.GlobalVariableExpression;
47+
import mx.kenzie.skript.lang.syntax.variable.ThreadVariableExpression;
48+
import mx.kenzie.skript.lang.syntax.variable.VariableExpression;
4549
import mx.kenzie.skript.runtime.internal.IOHandlers;
4650
import mx.kenzie.skript.runtime.type.DataList;
4751
import mx.kenzie.skript.runtime.type.DataMap;
@@ -119,6 +123,7 @@ private SkriptLangSpec() {
119123
new RemoveEffect(),
120124
new AssertEffect(),
121125
new ExitEffect(),
126+
new ExitThreadEffect(),
122127
new RunWithAsyncEffect(),
123128
new RunWithEffect(),
124129
new RunAsyncEffect(),
@@ -135,7 +140,9 @@ private SkriptLangSpec() {
135140
new ImplicitArrayCreator(),
136141
new BracketExpression(),
137142
new BooleanLiteral(),
143+
new ThreadVariableExpression(),
138144
new AtomicVariableExpression(),
145+
new GlobalVariableExpression(),
139146
new VariableExpression(),
140147
new IsArray(),
141148
new IsOfType(),

src/main/java/mx/kenzie/skript/lang/syntax/control/DeleteEffect.java

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import mx.kenzie.skript.error.ScriptParseError;
99
import mx.kenzie.skript.lang.element.StandardElements;
1010
import mx.kenzie.skript.lang.handler.StandardHandlers;
11+
import mx.kenzie.skript.lang.syntax.variable.VariableExpression;
1112

1213
import java.lang.reflect.Method;
1314

@@ -19,7 +20,7 @@ public DeleteEffect() {
1920

2021
@Override
2122
public Pattern.Match match(String thing, Context context) {
22-
if (thing.startsWith("delete {")) return null;
23+
if (!thing.startsWith("delete ")) return null;
2324
return super.match(thing, context);
2425
}
2526

@@ -28,6 +29,9 @@ public void preCompile(Context context, Pattern.Match match) {
2829
final ElementTree tree = context.getLine();
2930
final ElementTree[] inputs = tree.nested();
3031
assert inputs.length == 1;
32+
inputs[0].type = StandardHandlers.DELETE;
33+
if (inputs[0].current() instanceof VariableExpression)
34+
return; // variables have to handle their own deletion
3135
if (!(inputs[0].current() instanceof final Referent referent))
3236
throw new ScriptParseError(context.lineNumber(), "Syntax '" + inputs[0].current()
3337
.name() + "' cannot be deleted.");
@@ -44,10 +48,12 @@ public void compile(Context context, Pattern.Match match) throws Throwable {
4448
assert method != null;
4549
final ElementTree tree = context.getLine();
4650
final ElementTree[] inputs = tree.nested();
47-
final Referent referent = (Referent) inputs[0].current();
48-
final Method target = referent.getHandler(StandardHandlers.DELETE);
49-
assert target != null;
50-
this.writeCall(method, target, context);
51+
if (!(inputs[0].current() instanceof VariableExpression)) { // variables have to handle their own deletion
52+
final Referent referent = (Referent) inputs[0].current();
53+
final Method target = referent.getHandler(StandardHandlers.DELETE);
54+
assert target != null;
55+
this.writeCall(method, target, context);
56+
}
5157
context.setState(CompileState.CODE_BODY);
5258
}
5359

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package mx.kenzie.skript.lang.syntax.flow;
2+
3+
import mx.kenzie.foundation.MethodBuilder;
4+
import mx.kenzie.foundation.WriteInstruction;
5+
import mx.kenzie.skript.api.syntax.Effect;
6+
import mx.kenzie.skript.compiler.CompileState;
7+
import mx.kenzie.skript.compiler.Context;
8+
import mx.kenzie.skript.compiler.Pattern;
9+
import mx.kenzie.skript.compiler.SkriptLangSpec;
10+
import mx.kenzie.skript.lang.element.StandardElements;
11+
12+
public class ExitThreadEffect extends Effect {
13+
14+
public ExitThreadEffect() {
15+
super(SkriptLangSpec.LIBRARY, StandardElements.EFFECT, "(exit|stop) %Thread%");
16+
}
17+
18+
@Override
19+
public Pattern.Match match(String thing, Context context) {
20+
if (!thing.startsWith("exit ") && !thing.startsWith("stop ")) return null;
21+
return super.match(thing, context);
22+
}
23+
24+
@Override
25+
public void compile(Context context, Pattern.Match match) throws Throwable {
26+
final MethodBuilder method = context.getMethod();
27+
assert method != null;
28+
method.writeCode(WriteInstruction.invokeVirtual(Thread.class.getMethod("stop")));
29+
context.setState(CompileState.CODE_BODY);
30+
}
31+
32+
}

src/main/java/mx/kenzie/skript/lang/syntax/flow/execute/RunEffect.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import mx.kenzie.skript.lang.element.StandardElements;
1111
import mx.kenzie.skript.lang.handler.StandardHandlers;
1212
import mx.kenzie.skript.lang.syntax.flow.lambda.RunnableSection;
13-
import mx.kenzie.skript.lang.syntax.generic.VariableExpression;
13+
import mx.kenzie.skript.lang.syntax.variable.VariableExpression;
1414
import mx.kenzie.skript.runtime.internal.Member;
1515

1616
import java.lang.reflect.Method;

src/main/java/mx/kenzie/skript/lang/syntax/flow/loop/LoopInSection.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import mx.kenzie.skript.error.ScriptParseError;
1313
import mx.kenzie.skript.lang.element.StandardElements;
1414
import mx.kenzie.skript.lang.handler.StandardHandlers;
15-
import mx.kenzie.skript.lang.syntax.generic.VariableExpression;
15+
import mx.kenzie.skript.lang.syntax.variable.VariableExpression;
1616
import mx.kenzie.skript.runtime.internal.OperatorHandler;
1717
import org.objectweb.asm.Label;
1818
import org.objectweb.asm.Opcodes;

src/main/java/mx/kenzie/skript/lang/syntax/timing/MillisecondsExpression.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
public class MillisecondsExpression extends SimpleExpression {
1616

1717
public MillisecondsExpression() {
18-
super(SkriptLangSpec.LIBRARY, StandardElements.EXPRESSION, "%Integer% milli[ ]second[s]");
18+
super(SkriptLangSpec.LIBRARY, StandardElements.EXPRESSION, "%Integer% m[illi[ ]]s[econd[s]]");
1919
try {
2020
handlers.put(StandardHandlers.FIND, this.getClass().getMethod("find", Object.class));
2121
} catch (NoSuchMethodException e) {
@@ -30,7 +30,6 @@ public boolean allowAsInputFor(Type type) {
3030

3131
@Override
3232
public Pattern.Match match(String thing, Context context) {
33-
if (!thing.endsWith("seconds") && !thing.endsWith("second")) return null;
3433
return super.match(thing, context);
3534
}
3635

src/main/java/mx/kenzie/skript/lang/syntax/generic/AtomicVariableExpression.java renamed to src/main/java/mx/kenzie/skript/lang/syntax/variable/AtomicVariableExpression.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,22 @@
1-
package mx.kenzie.skript.lang.syntax.generic;
1+
package mx.kenzie.skript.lang.syntax.variable;
22

33
import mx.kenzie.foundation.MethodBuilder;
44
import mx.kenzie.foundation.Type;
55
import mx.kenzie.skript.api.Referent;
6-
import mx.kenzie.skript.api.syntax.SimpleExpression;
76
import mx.kenzie.skript.compiler.*;
87
import mx.kenzie.skript.compiler.structure.PreVariable;
9-
import mx.kenzie.skript.lang.element.StandardElements;
108
import mx.kenzie.skript.lang.handler.StandardHandlers;
119
import mx.kenzie.skript.runtime.type.AtomicVariable;
1210

1311
import java.lang.reflect.Method;
1412
import java.util.regex.Matcher;
1513

16-
public class AtomicVariableExpression extends SimpleExpression implements Referent {
14+
public class AtomicVariableExpression extends VariableExpression implements Referent {
1715

1816
private static final java.util.regex.Pattern PATTERN = java.util.regex.Pattern.compile("\\{(?<name>@" + SkriptLangSpec.IDENTIFIER + ")\\}");
1917

2018
public AtomicVariableExpression() {
21-
super(SkriptLangSpec.LIBRARY, StandardElements.EXPRESSION, "variable");
19+
super();
2220
try {
2321
handlers.put(StandardHandlers.GET, AtomicVariable.class.getMethod("get", Object.class));
2422
handlers.put(StandardHandlers.FIND, AtomicVariable.class.getMethod("get", Object.class));
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package mx.kenzie.skript.lang.syntax.variable;
2+
3+
import mx.kenzie.foundation.MethodBuilder;
4+
import mx.kenzie.foundation.Type;
5+
import mx.kenzie.foundation.WriteInstruction;
6+
import mx.kenzie.skript.api.Referent;
7+
import mx.kenzie.skript.compiler.CommonTypes;
8+
import mx.kenzie.skript.compiler.Context;
9+
import mx.kenzie.skript.compiler.Pattern;
10+
import mx.kenzie.skript.compiler.SkriptLangSpec;
11+
import mx.kenzie.skript.lang.handler.StandardHandlers;
12+
import mx.kenzie.skript.runtime.internal.GlobalVariableMap;
13+
14+
import java.lang.reflect.Method;
15+
import java.util.regex.Matcher;
16+
17+
public class GlobalVariableExpression extends VariableExpression implements Referent {
18+
19+
private static final java.util.regex.Pattern PATTERN = java.util.regex.Pattern.compile("\\{(?<name>!" + SkriptLangSpec.IDENTIFIER + ")\\}");
20+
21+
public GlobalVariableExpression() {
22+
super();
23+
try {
24+
handlers.put(StandardHandlers.GET, GlobalVariableMap.class.getMethod("getVariable", Object.class));
25+
handlers.put(StandardHandlers.FIND, GlobalVariableMap.class.getMethod("getVariable", Object.class));
26+
handlers.put(StandardHandlers.SET, GlobalVariableMap.class.getMethod("setVariable", Object.class, Object.class));
27+
handlers.put(StandardHandlers.DELETE, GlobalVariableMap.class.getMethod("deleteVariable", Object.class));
28+
} catch (NoSuchMethodException e) {
29+
e.printStackTrace();
30+
}
31+
}
32+
33+
@Override
34+
public boolean allowAsInputFor(Type type) {
35+
return true;
36+
}
37+
38+
@Override
39+
public Pattern.Match match(String thing, Context context) {
40+
if (thing.length() < 4) return null;
41+
if (thing.charAt(1) != '!') return null;
42+
if (thing.charAt(0) != '{') return null;
43+
if (!thing.endsWith("}")) return null;
44+
final Matcher matcher = PATTERN.matcher(thing);
45+
if (!matcher.find()) return null;
46+
return new Pattern.Match(matcher);
47+
}
48+
49+
@Override
50+
public Type getHolderType() {
51+
return CommonTypes.VOID;
52+
}
53+
54+
@Override
55+
public void compile(Context context, Pattern.Match match) {
56+
final MethodBuilder method = context.getMethod();
57+
assert method != null;
58+
final String name = match.matcher().group("name");
59+
method.writeCode(WriteInstruction.loadConstant(name));
60+
if (context.getHandlerMode().expectInputs())
61+
method.writeCode(WriteInstruction.swap()); // name, arg
62+
final Method target = handlers.get(context.getHandlerMode());
63+
assert target != null;
64+
this.writeCall(method, target, context);
65+
}
66+
67+
@Override
68+
public Type getReturnType() {
69+
return CommonTypes.OBJECT;
70+
}
71+
72+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package mx.kenzie.skript.lang.syntax.variable;
2+
3+
import mx.kenzie.foundation.MethodBuilder;
4+
import mx.kenzie.foundation.Type;
5+
import mx.kenzie.foundation.WriteInstruction;
6+
import mx.kenzie.skript.api.Referent;
7+
import mx.kenzie.skript.compiler.CommonTypes;
8+
import mx.kenzie.skript.compiler.Context;
9+
import mx.kenzie.skript.compiler.Pattern;
10+
import mx.kenzie.skript.compiler.SkriptLangSpec;
11+
import mx.kenzie.skript.lang.handler.StandardHandlers;
12+
import mx.kenzie.skript.runtime.internal.ThreadVariableMap;
13+
14+
import java.lang.reflect.Method;
15+
import java.util.regex.Matcher;
16+
17+
public class ThreadVariableExpression extends VariableExpression implements Referent {
18+
19+
private static final java.util.regex.Pattern PATTERN = java.util.regex.Pattern.compile("\\{(?<name>_" + SkriptLangSpec.IDENTIFIER + ")\\}");
20+
21+
public ThreadVariableExpression() {
22+
super();
23+
try {
24+
handlers.put(StandardHandlers.GET, ThreadVariableMap.class.getMethod("getVariable", Object.class));
25+
handlers.put(StandardHandlers.FIND, ThreadVariableMap.class.getMethod("getVariable", Object.class));
26+
handlers.put(StandardHandlers.SET, ThreadVariableMap.class.getMethod("setVariable", Object.class, Object.class));
27+
handlers.put(StandardHandlers.DELETE, ThreadVariableMap.class.getMethod("deleteVariable", Object.class));
28+
} catch (NoSuchMethodException e) {
29+
e.printStackTrace();
30+
}
31+
}
32+
33+
@Override
34+
public boolean allowAsInputFor(Type type) {
35+
return true;
36+
}
37+
38+
@Override
39+
public Pattern.Match match(String thing, Context context) {
40+
if (thing.length() < 4) return null;
41+
if (thing.charAt(1) != '_') return null;
42+
if (thing.charAt(0) != '{') return null;
43+
if (!thing.endsWith("}")) return null;
44+
final Matcher matcher = PATTERN.matcher(thing);
45+
if (!matcher.find()) return null;
46+
return new Pattern.Match(matcher);
47+
}
48+
49+
@Override
50+
public Type getHolderType() {
51+
return CommonTypes.VOID;
52+
}
53+
54+
@Override
55+
public void compile(Context context, Pattern.Match match) {
56+
final MethodBuilder method = context.getMethod();
57+
assert method != null;
58+
final String name = match.matcher().group("name");
59+
method.writeCode(WriteInstruction.loadConstant(name));
60+
if (context.getHandlerMode().expectInputs())
61+
method.writeCode(WriteInstruction.swap()); // name, arg
62+
final Method target = handlers.get(context.getHandlerMode());
63+
assert target != null;
64+
this.writeCall(method, target, context);
65+
}
66+
67+
@Override
68+
public Type getReturnType() {
69+
return CommonTypes.OBJECT;
70+
}
71+
72+
}

src/main/java/mx/kenzie/skript/lang/syntax/generic/VariableExpression.java renamed to src/main/java/mx/kenzie/skript/lang/syntax/variable/VariableExpression.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
package mx.kenzie.skript.lang.syntax.generic;
1+
package mx.kenzie.skript.lang.syntax.variable;
22

33
import mx.kenzie.foundation.MethodBuilder;
44
import mx.kenzie.foundation.Type;
5+
import mx.kenzie.foundation.WriteInstruction;
56
import mx.kenzie.skript.api.Referent;
67
import mx.kenzie.skript.api.syntax.SimpleExpression;
78
import mx.kenzie.skript.compiler.CommonTypes;
@@ -40,6 +41,8 @@ public Pattern.Match match(String thing, Context context) {
4041
if (thing.length() < 3) return null;
4142
if (thing.charAt(0) != '{') return null;
4243
if (thing.charAt(1) == '@') return null;
44+
if (thing.charAt(1) == '_') return null;
45+
if (thing.charAt(1) == '!') return null;
4346
if (!thing.endsWith("}")) return null;
4447
final Matcher matcher = PATTERN.matcher(thing);
4548
if (!matcher.find()) return null;
@@ -77,6 +80,9 @@ public void compile(Context context, Pattern.Match match) {
7780
method.writeCode(variable.store(slot));
7881
} else if (context.getHandlerMode().equals(StandardHandlers.GET)) {
7982
method.writeCode(variable.load(slot));
83+
} else if (context.getHandlerMode().equals(StandardHandlers.DELETE)) {
84+
method.writeCode(WriteInstruction.pushNull());
85+
method.writeCode(variable.store(slot));
8086
}
8187
}
8288

0 commit comments

Comments
 (0)