Skip to content

Commit 2e99128

Browse files
committed
Implement the phraseme group loader and dynamic pattern generation
1 parent 8425038 commit 2e99128

File tree

7 files changed

+84
-17
lines changed

7 files changed

+84
-17
lines changed

examples/current_test.light

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ main {
33
send "Hello Light" to console
44

55
// Print <boolean> type
6-
//send
6+
send
77
> true
88
> to the console
99

light-core/src/main/java/org/panda_lang/light/framework/language/architecture/linguistic/phraseme/LightPhrasemeLinguisticExpression.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import org.panda_lang.light.framework.design.architecture.linguistic.LinguisticUtils;
66
import org.panda_lang.light.framework.design.architecture.linguistic.type.Type;
77
import org.panda_lang.panda.framework.design.runtime.ExecutableBranch;
8+
import org.panda_lang.panda.utilities.commons.arrays.ArrayUtils;
89

910
public class LightPhrasemeLinguisticExpression implements LinguisticExpression {
1011

@@ -13,6 +14,10 @@ public class LightPhrasemeLinguisticExpression implements LinguisticExpression {
1314
private final Type<?> returnType;
1415

1516
public LightPhrasemeLinguisticExpression(Type<?>[] parameterTypes, PhrasemeCallback callback, Type<?> returnType) {
17+
if (ArrayUtils.contains(parameterTypes, null)) {
18+
throw new IllegalArgumentException("Parameter types cannot contain null");
19+
}
20+
1621
this.parameterTypes = parameterTypes;
1722
this.callback = callback;
1823
this.returnType = returnType;

light-core/src/main/java/org/panda_lang/light/framework/language/architecture/linguistic/phraseme/loader/PhrasemeGroupLoader.java

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99
import org.panda_lang.light.framework.language.architecture.linguistic.phraseme.loader.annotations.PhrasemeVariant;
1010
import org.panda_lang.panda.utilities.annotations.AnnotationsScannerProcess;
1111
import org.panda_lang.panda.utilities.commons.ReflectionUtils;
12+
import org.panda_lang.panda.utilities.commons.objects.StringUtils;
1213

1314
import java.lang.reflect.Method;
1415
import java.util.ArrayList;
1516
import java.util.Collection;
17+
import java.util.stream.Stream;
1618

1719
class PhrasemeGroupLoader {
1820

@@ -25,32 +27,34 @@ protected Collection<Phraseme> load(Context context, AnnotationsScannerProcess p
2527
.selectTypesAnnotatedWith(PhrasemeGroup.class);
2628

2729
for (Class<?> clazz : selected) {
28-
Phraseme phraseme = loadPhrasemeGroup(context, clazz);
29-
phrasemes.add(phraseme);
30+
phrasemes.addAll(loadPhrasemeGroup(context, clazz));
3031
}
3132

3233
return phrasemes;
3334
}
3435

35-
private Phraseme loadPhrasemeGroup(Context context, Class<?> clazz) throws Exception {
36+
private Collection<Phraseme> loadPhrasemeGroup(Context context, Class<?> clazz) throws Exception {
3637
PhrasemeGroup group = clazz.getAnnotation(PhrasemeGroup.class);
3738

38-
LinguisticPattern pattern = LinguisticPattern.builder()
39-
.compile(group.value())
40-
.build();
41-
42-
LightPhraseme phraseme = new LightPhraseme(pattern, context.getType(group.returnType()));
4339
Collection<Method> variantMethods = ReflectionUtils.getMethodsAnnotatedWith(clazz, PhrasemeVariant.class);
40+
Collection<Phraseme> phrasemes = new ArrayList<>(variantMethods.size());
4441

4542
for (Method variantMethod : variantMethods) {
46-
Phraseme variantPhraseme = loadPhraseme(pattern, context, variantMethod);
47-
phraseme.merge(variantPhraseme);
43+
phrasemes.add(loadPhraseme(group.value(), context, variantMethod));
4844
}
4945

50-
return phraseme;
46+
return phrasemes;
5147
}
5248

53-
private Phraseme loadPhraseme(LinguisticPattern pattern, Context context, Method method) throws Exception {
49+
private Phraseme loadPhraseme(String patternScheme, Context context, Method method) throws Exception {
50+
String preparedPattern = StringUtils.replaceRespectively(patternScheme, "<?>", Stream.of(method.getParameterTypes())
51+
.map(clazz -> "<" + clazz.getSimpleName() + ">")
52+
.toArray(String[]::new));
53+
54+
LinguisticPattern pattern = LinguisticPattern.builder()
55+
.compile(preparedPattern)
56+
.build();
57+
5458
LinguisticExpression expression = methodLoader.load(context, method);
5559
return new LightPhraseme(pattern, expression.getType(), expression);
5660
}

light-core/src/main/java/org/panda_lang/light/framework/language/architecture/linguistic/phraseme/loader/PhrasemeMethodLoader.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.panda_lang.light.framework.language.architecture.linguistic.phraseme.loader;
22

3+
import org.panda_lang.light.LightException;
34
import org.panda_lang.light.framework.design.architecture.linguistic.Context;
45
import org.panda_lang.light.framework.design.architecture.linguistic.LinguisticExpression;
56
import org.panda_lang.light.framework.design.architecture.linguistic.type.Type;
@@ -32,7 +33,14 @@ public Object call(ExecutableBranch branch, Object[] convertedParameters) {
3233
Type<?>[] parameterTypes = new Type[method.getParameterCount()];
3334

3435
for (int i = 0; i < parameterTypes.length; i++) {
35-
parameterTypes[i] = context.getType(method.getParameterTypes()[i]);
36+
Class<?> typeClass = method.getParameterTypes()[i];
37+
Type<?> type = context.getType(typeClass);
38+
39+
if (type == null) {
40+
throw new LightException("Cannot recognize type " + typeClass);
41+
}
42+
43+
parameterTypes[i] = type;
3644
}
3745

3846
return new LightPhrasemeLinguisticExpression(parameterTypes, callback, returnType);

light-core/src/main/java/org/panda_lang/light/framework/language/resource/DefaultLightTypes.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@ public Types generate() {
3333

3434
types.registerElement(LightType.<Void> builder()
3535
.name("void")
36-
.associated(void.class)
36+
.associated(Void.class)
3737
.build());
3838

3939
types.registerElement(LightType.<Boolean> builder()
4040
.name("boolean")
4141
.plural("booleans")
42-
.associated(Boolean.class)
42+
.associated(boolean.class)
4343
.transformer(sentence -> (sentence.equals("true") || sentence.equals("false")) ? Boolean.parseBoolean(sentence) : null)
4444
.build());
4545

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package org.panda_lang.light.framework.design.interpreter.pattern.linguistic;
2+
3+
import org.junit.jupiter.api.Test;
4+
import org.panda_lang.panda.framework.language.interpreter.pattern.lexical.LexicalPattern;
5+
import org.panda_lang.panda.framework.language.interpreter.pattern.lexical.extractor.LexicalExtractorResult;
6+
import org.panda_lang.panda.utilities.commons.BenchmarkUtils;
7+
8+
import java.util.ArrayList;
9+
import java.util.Collection;
10+
11+
public class LexicalPatternTest {
12+
13+
private final Collection<LexicalPattern<?>> patterns = new ArrayList<>(1_000_000);
14+
15+
@Test
16+
public void testPerformance() {
17+
fill();
18+
19+
BenchmarkUtils.execute("LexicalPattern ", () -> {
20+
for (int i = 0; i < 10000; i++) {
21+
match();
22+
}
23+
});
24+
}
25+
26+
private void match() {
27+
for (LexicalPattern<?> pattern : patterns) {
28+
LexicalExtractorResult<?> result = pattern.extract("matched");
29+
30+
if (result.isMatched()) {
31+
break;
32+
}
33+
}
34+
}
35+
36+
private void fill() {
37+
LexicalPattern pattern = LexicalPattern.builder()
38+
.compile("send message:<string> to [the] console")
39+
.build();
40+
41+
for (int i = 0; i < 1000; i++) {
42+
patterns.add(pattern);
43+
}
44+
45+
patterns.add(LexicalPattern.builder()
46+
.compile("matched")
47+
.build());
48+
}
49+
50+
}

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
<dependency>
5656
<groupId>org.panda-lang</groupId>
5757
<artifactId>panda</artifactId>
58-
<version>indev-0.9.2</version>
58+
<version>indev-18.10.5</version>
5959
</dependency>
6060

6161
<!-- Tests -->

0 commit comments

Comments
 (0)