Skip to content

Commit 1a2eab9

Browse files
committed
Properties in user-defined types.
Also access fields from Java classes.
1 parent 338cd05 commit 1a2eab9

File tree

17 files changed

+369
-12
lines changed

17 files changed

+369
-12
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>org.byteskript</groupId>
88
<artifactId>byteskript</artifactId>
9-
<version>1.0.3</version>
9+
<version>1.0.4</version>
1010
<name>ByteSkript</name>
1111

1212
<properties>

src/main/java/org/byteskript/skript/api/syntax/Member.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
package org.byteskript.skript.api.syntax;
88

9+
import mx.kenzie.foundation.Type;
910
import org.byteskript.skript.api.LanguageElement;
1011
import org.byteskript.skript.api.Library;
1112
import org.byteskript.skript.compiler.CompileState;
@@ -30,4 +31,9 @@ public void onSectionExit(Context context, SectionMeta meta) {
3031
context.setState(CompileState.ROOT);
3132
}
3233

34+
@Override
35+
public boolean allowAsInputFor(Type type) {
36+
return false;
37+
}
38+
3339
}

src/main/java/org/byteskript/skript/compiler/AreaFlag.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
public enum AreaFlag implements Flag {
1212
IN_SYNTAX,
1313
IN_FUNCTION,
14+
IN_PROPERTY,
1415
IN_TYPE,
1516
IN_ABSTRACT_TYPE,
1617
IN_EVENT

src/main/java/org/byteskript/skript/compiler/FileContext.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@ public boolean hasHandle(String property, HandlerType type) {
359359
public MethodErasure useHandle(String property, HandlerType type) {
360360
this.usedProperties.putIfAbsent(type, new ArrayList<>());
361361
final List<PropertyAccessGenerator> list = this.usedProperties.get(type);
362+
boolean unused = true;
362363
for (Library library : this.libraries) {
363364
sub:
364365
for (PropertyHandler handler : library.getProperties()) {
@@ -369,15 +370,26 @@ public MethodErasure useHandle(String property, HandlerType type) {
369370
if (!generator.getName().equals(property)) continue;
370371
if (!generator.getType().equals(type)) continue;
371372
uses++;
373+
unused = false;
372374
generator.addUse(handler.holder(), handler.method());
373375
}
374376
if (uses == 0) {
375377
final PropertyAccessGenerator generator = new PropertyAccessGenerator(type, property);
376378
generator.addUse(handler.holder(), handler.method());
377379
list.add(generator);
380+
unused = false;
378381
}
379382
}
380383
}
384+
if (unused) check:{
385+
for (PropertyAccessGenerator generator : list) {
386+
if (!generator.getName().equals(property)) continue;
387+
if (!generator.getType().equals(type)) continue;
388+
break check;
389+
}
390+
final PropertyAccessGenerator generator = new PropertyAccessGenerator(type, property);
391+
list.add(generator);
392+
}
381393
final Type ret = type.expectReturn() ? CommonTypes.OBJECT : new Type(void.class);
382394
final Type[] params = type.expectInputs() ? new Type[]{CommonTypes.OBJECT, CommonTypes.OBJECT} : new Type[]{CommonTypes.OBJECT};
383395
return new MethodErasure(ret, "property_" + type.name() + "$" + property, params);

src/main/java/org/byteskript/skript/compiler/SkriptLangSpec.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@
5555
import org.byteskript.skript.lang.syntax.maths.*;
5656
import org.byteskript.skript.lang.syntax.timing.*;
5757
import org.byteskript.skript.lang.syntax.type.*;
58+
import org.byteskript.skript.lang.syntax.type.property.FinalEntry;
59+
import org.byteskript.skript.lang.syntax.type.property.LocalEntry;
60+
import org.byteskript.skript.lang.syntax.type.property.PropertyMember;
61+
import org.byteskript.skript.lang.syntax.type.property.TypeEntry;
5862
import org.byteskript.skript.lang.syntax.variable.AtomicVariableExpression;
5963
import org.byteskript.skript.lang.syntax.variable.GlobalVariableExpression;
6064
import org.byteskript.skript.lang.syntax.variable.ThreadVariableExpression;
@@ -116,6 +120,7 @@ private SkriptLangSpec() {
116120
registerSyntax(CompileState.ROOT,
117121
new TypeMember(),
118122
new TemplateTypeMember(),
123+
new PropertyMember(),
119124
new FunctionMember(),
120125
new NoArgsFunctionMember(),
121126
new Template()
@@ -128,7 +133,10 @@ private SkriptLangSpec() {
128133
new EffectEntry(),
129134
new ExpressionEntry(),
130135
new PropertyEntry(),
131-
new ModeEntry()
136+
new ModeEntry(),
137+
new TypeEntry(),
138+
new LocalEntry(),
139+
new FinalEntry()
132140
);
133141
registerSyntax(CompileState.CODE_BODY,
134142
new PrintEffect(),

src/main/java/org/byteskript/skript/compiler/structure/PropertyAccessGenerator.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import org.byteskript.skript.api.HandlerType;
1313
import org.byteskript.skript.compiler.CommonTypes;
1414
import org.byteskript.skript.compiler.Context;
15+
import org.byteskript.skript.lang.handler.StandardHandlers;
1516
import org.byteskript.skript.runtime.data.HandlerData;
1617
import org.objectweb.asm.Label;
1718

@@ -85,6 +86,24 @@ public void compile(Context context) {
8586
else method.writeCode(WriteInstruction.returnEmpty()); // return empty
8687
method.writeCode((writer, visitor) -> visitor.visitLabel(jump)); // end
8788
}
89+
field_property:
90+
{
91+
if (this.type == StandardHandlers.GET) method.writeCode((writer, visitor) -> {
92+
visitor.visitVarInsn(25, 0); // load holder
93+
visitor.visitLdcInsn(name);
94+
visitor.visitMethodInsn(184, "skript", "get_java_field", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", false);
95+
visitor.visitInsn(176); // areturn
96+
return;
97+
});
98+
else if (this.type == StandardHandlers.SET) method.writeCode((writer, visitor) -> {
99+
visitor.visitVarInsn(25, 0); // load holder
100+
visitor.visitLdcInsn(name);
101+
visitor.visitVarInsn(25, 1); // load value
102+
visitor.visitMethodInsn(184, "skript", "set_java_field", "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Void;", false);
103+
visitor.visitInsn(177); // return top
104+
return;
105+
});
106+
}
88107
if (this.type.expectReturn()) { // return null if requires result
89108
method.writeCode(WriteInstruction.pushNull());
90109
method.writeCode(WriteInstruction.returnObject());

src/main/java/org/byteskript/skript/lang/syntax/entry/Template.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
import org.byteskript.skript.compiler.*;
1313
import org.byteskript.skript.lang.element.StandardElements;
1414

15-
import java.util.regex.Matcher;
16-
1715
public class Template extends SimpleEntry {
1816

1917
public Template() {
@@ -41,17 +39,14 @@ public Pattern.Match match(String thing, Context context) {
4139
if (match == null) return null;
4240
final String name = match.groups()[0].trim();
4341
if (name.isEmpty()) {
44-
context.getError().addHint(this, "A type should be specified after the 'type:' entry.");
42+
context.getError().addHint(this, "A type should be specified after the 'template:' entry.");
4543
return null;
4644
}
4745
if (name.contains("\"")) {
4846
context.getError().addHint(this, "Type names should not be written inside quotation marks.");
4947
return null;
5048
}
51-
final String quote = java.util.regex.Pattern.quote(thing);
52-
final Matcher matcher = java.util.regex.Pattern.compile(quote).matcher(thing);
53-
matcher.find();
54-
return new Pattern.Match(matcher, name);
49+
return new Pattern.Match(Pattern.fakeMatcher(thing), name);
5550
}
5651

5752
@Override

src/main/java/org/byteskript/skript/lang/syntax/generic/PropertyExpression.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public Pattern.Match match(String thing, Context context) {
5353
final Matcher matcher = pattern.matcher(thing);
5454
if (!matcher.find()) return null;
5555
final String name = matcher.group("name");
56-
if (!context.hasHandle(name, context.getHandlerMode())) return null;
56+
// if (!context.hasHandle(name, context.getHandlerMode())) return null;
5757
final Matcher dummy = createDummy(thing, i, matcher);
5858
dummy.find();
5959
return new Pattern.Match(dummy, name, CommonTypes.OBJECT);
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright (c) 2021 ByteSkript org (Moderocky)
3+
* View the full licence information and permissions:
4+
* https://github.com/Moderocky/ByteSkript/blob/master/LICENSE
5+
*/
6+
7+
package org.byteskript.skript.lang.syntax.type.property;
8+
9+
import mx.kenzie.foundation.compiler.State;
10+
import org.byteskript.skript.api.syntax.SimpleEntry;
11+
import org.byteskript.skript.compiler.*;
12+
import org.byteskript.skript.lang.element.StandardElements;
13+
14+
public class FinalEntry extends SimpleEntry {
15+
16+
public FinalEntry() {
17+
super(SkriptLangSpec.LIBRARY, StandardElements.METADATA, "final: %Boolean%");
18+
}
19+
20+
@Override
21+
public void compile(Context context, Pattern.Match match) {
22+
final String name = (String) match.meta();
23+
final boolean value = Boolean.parseBoolean(name);
24+
if (value) context.getField().addModifiers(0x0010);
25+
else context.getField().removeModifiers(0x0010);
26+
context.setState(CompileState.MEMBER_BODY);
27+
}
28+
29+
@Override
30+
public Pattern.Match match(String thing, Context context) {
31+
if (!thing.startsWith("final: ")) return null;
32+
if (!thing.equals("final: true") && !thing.equals("final: false")) {
33+
context.getError().addHint(this, "A true/false value goes after the 'final:' entry.");
34+
return null;
35+
}
36+
return new Pattern.Match(Pattern.fakeMatcher(thing), thing.substring(7));
37+
}
38+
39+
@Override
40+
public boolean allowedIn(State state, Context context) {
41+
return context.getState() == CompileState.MEMBER_BODY
42+
&& context.hasFlag(AreaFlag.IN_TYPE)
43+
&& context.hasFlag(AreaFlag.IN_PROPERTY);
44+
}
45+
46+
47+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright (c) 2021 ByteSkript org (Moderocky)
3+
* View the full licence information and permissions:
4+
* https://github.com/Moderocky/ByteSkript/blob/master/LICENSE
5+
*/
6+
7+
package org.byteskript.skript.lang.syntax.type.property;
8+
9+
import mx.kenzie.foundation.compiler.State;
10+
import org.byteskript.skript.api.syntax.SimpleEntry;
11+
import org.byteskript.skript.compiler.*;
12+
import org.byteskript.skript.lang.element.StandardElements;
13+
14+
public class LocalEntry extends SimpleEntry {
15+
16+
public LocalEntry() {
17+
super(SkriptLangSpec.LIBRARY, StandardElements.METADATA, "local: %Boolean%");
18+
}
19+
20+
@Override
21+
public void compile(Context context, Pattern.Match match) {
22+
final String name = (String) match.meta();
23+
final boolean value = Boolean.parseBoolean(name);
24+
if (value) {
25+
context.getField().removeModifiers(0x0001);
26+
context.getField().addModifiers(0x0002);
27+
} else {
28+
context.getField().removeModifiers(0x0002);
29+
context.getField().addModifiers(0x0001);
30+
}
31+
context.setState(CompileState.MEMBER_BODY);
32+
}
33+
34+
@Override
35+
public Pattern.Match match(String thing, Context context) {
36+
if (!thing.startsWith("local: ")) return null;
37+
if (!thing.equals("local: true") && !thing.equals("local: false")) {
38+
context.getError().addHint(this, "A true/false value goes after the 'local:' entry.");
39+
return null;
40+
}
41+
return new Pattern.Match(Pattern.fakeMatcher(thing), thing.substring(7));
42+
}
43+
44+
@Override
45+
public boolean allowedIn(State state, Context context) {
46+
return context.getState() == CompileState.MEMBER_BODY
47+
&& context.hasFlag(AreaFlag.IN_TYPE)
48+
&& context.hasFlag(AreaFlag.IN_PROPERTY);
49+
}
50+
51+
52+
}

0 commit comments

Comments
 (0)