Selaa lähdekoodia

Function stuff, probably

kindlich 6 vuotta sitten
vanhempi
commit
51efcfdc9a
No known key found for this signature in database

+ 40
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaCapturedExpressionVisitor.java Näytä tiedosto

@@ -0,0 +1,40 @@
1
+package org.openzen.zenscript.javabytecode.compiler;
2
+
3
+import org.openzen.zenscript.codemodel.expression.*;
4
+
5
+public class JavaCapturedExpressionVisitor implements CapturedExpressionVisitor<Void> {
6
+
7
+    public final JavaExpressionVisitor expressionVisitor;
8
+
9
+    public JavaCapturedExpressionVisitor(JavaExpressionVisitor expressionVisitor) {
10
+        this.expressionVisitor = expressionVisitor;
11
+    }
12
+
13
+    @Override
14
+    public Void visitCapturedThis(CapturedThisExpression expression) {
15
+        return null;
16
+    }
17
+
18
+    @Override
19
+    public Void visitCapturedParameter(CapturedParameterExpression expression) {
20
+        return null;
21
+    }
22
+
23
+    @Override
24
+    public Void visitCapturedLocal(CapturedLocalVariableExpression expression) {
25
+        new GetLocalVariableExpression(expression.position, expression.variable)
26
+                .accept(expressionVisitor);
27
+        return null;
28
+    }
29
+
30
+    @Override
31
+    public Void visitCapturedDirect(CapturedDirectExpression expression) {
32
+        return null;
33
+    }
34
+
35
+    @Override
36
+    public Void visitRecaptured(CapturedClosureExpression expression) {
37
+        expression.value.accept(this);
38
+        return null;
39
+    }
40
+}

+ 201
- 86
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java Näytä tiedosto

@@ -1,10 +1,13 @@
1 1
 package org.openzen.zenscript.javabytecode.compiler;
2 2
 
3 3
 import org.objectweb.asm.Label;
4
+import org.objectweb.asm.Opcodes;
4 5
 import org.objectweb.asm.Type;
5 6
 import org.openzen.zenscript.codemodel.CompareType;
6 7
 import org.openzen.zenscript.codemodel.expression.*;
7 8
 import org.openzen.zenscript.codemodel.member.DefinitionMember;
9
+import org.openzen.zenscript.codemodel.statement.ReturnStatement;
10
+import org.openzen.zenscript.codemodel.type.BasicTypeID;
8 11
 import org.openzen.zenscript.codemodel.type.DefinitionTypeID;
9 12
 import org.openzen.zenscript.codemodel.type.ITypeID;
10 13
 import org.openzen.zenscript.implementations.IntRange;
@@ -12,14 +15,15 @@ import org.openzen.zenscript.javabytecode.*;
12 15
 import org.openzen.zenscript.shared.CompileException;
13 16
 import org.openzen.zenscript.shared.CompileExceptionCode;
14 17
 
18
+import java.util.Arrays;
15 19
 import java.util.Map;
16
-import org.objectweb.asm.Opcodes;
20
+import java.util.StringJoiner;
17 21
 
18 22
 public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
19
-	private static final JavaMethodInfo MAP_PUT = JavaMethodInfo.get(Opcodes.ACC_PUBLIC, Map.class, "put", Object.class, Object.class, Object.class);
20
-	
23
+    private static final JavaMethodInfo MAP_PUT = JavaMethodInfo.get(Opcodes.ACC_PUBLIC, Map.class, "put", Object.class, Object.class, Object.class);
24
+
21 25
     private final JavaWriter javaWriter;
22
-	
26
+
23 27
     public JavaExpressionVisitor(JavaWriter javaWriter) {
24 28
         this.javaWriter = javaWriter;
25 29
     }
@@ -76,15 +80,15 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
76 80
         final Type operatorType = Type.getType(CompareType.class);
77 81
         javaWriter.getStaticField(operatorType.getInternalName(), expression.operator.name(), operatorType.getDescriptor());
78 82
 
79
-		// TODO: should be implemented properly
80
-		JavaMethodInfo compareMethod = JavaMethodInfo.get(
81
-				0,
82
-				ZenUtils.class,
83
-				"compare",
84
-				boolean.class,
85
-				getForEquals(expression.left.type),
86
-				getForEquals(expression.right.type),
87
-				CompareType.class);
83
+        // TODO: should be implemented properly
84
+        JavaMethodInfo compareMethod = JavaMethodInfo.get(
85
+                0,
86
+                ZenUtils.class,
87
+                "compare",
88
+                boolean.class,
89
+                getForEquals(expression.left.type),
90
+                getForEquals(expression.right.type),
91
+                CompareType.class);
88 92
         javaWriter.invokeStatic(compareMethod);
89 93
 
90 94
         return null;
@@ -115,6 +119,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
115 119
 
116 120
     @Override
117 121
     public Void visitCapturedClosure(CapturedClosureExpression expression) {
122
+        expression.value.accept(this);
118 123
         return null;
119 124
     }
120 125
 
@@ -125,6 +130,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
125 130
 
126 131
     @Override
127 132
     public Void visitCapturedLocalVariable(CapturedLocalVariableExpression expression) {
133
+        new GetLocalVariableExpression(expression.position, expression.variable).accept(this);
128 134
         return null;
129 135
     }
130 136
 
@@ -275,15 +281,15 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
275 281
     @Override
276 282
     public Void visitConstructorThisCall(ConstructorThisCallExpression expression) {
277 283
         Type type = expression.objectType.accept(JavaTypeVisitor.INSTANCE);
278
-		
279
-		if (javaWriter.method.javaClass.isEnum) {
280
-			javaWriter.loadObject(0);
281
-			javaWriter.loadObject(1);
282
-			javaWriter.loadInt(2);
283
-		} else {
284
-			javaWriter.loadObject(0);
285
-		}
286
-		
284
+
285
+        if (javaWriter.method.javaClass.isEnum) {
286
+            javaWriter.loadObject(0);
287
+            javaWriter.loadObject(1);
288
+            javaWriter.loadInt(2);
289
+        } else {
290
+            javaWriter.loadObject(0);
291
+        }
292
+
287 293
         for (Expression argument : expression.arguments.arguments) {
288 294
             argument.accept(this);
289 295
         }
@@ -299,8 +305,8 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
299 305
         }
300 306
         //No super calls in enums possible, and that's already handled in the enum constructor itself.
301 307
         javaWriter.invokeSpecial(expression.objectType.accept(JavaTypeClassVisitor.INSTANCE), "<init>", CompilerUtils.calcDesc(expression.constructor.header, false));
302
-		
303
-		CompilerUtils.writeDefaultFieldInitializers(javaWriter, javaWriter.forDefinition, false);
308
+
309
+        CompilerUtils.writeDefaultFieldInitializers(javaWriter, javaWriter.forDefinition, false);
304 310
         return null;
305 311
     }
306 312
 
@@ -313,9 +319,64 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
313 319
 
314 320
     @Override
315 321
     public Void visitFunction(FunctionExpression expression) {
322
+        if (expression.header.parameters.length == 0 && expression.body instanceof ReturnStatement && expression.body.hasTag(MatchExpression.class) && expression.closure.captures.isEmpty()) {
323
+            ((ReturnStatement) expression.body).value.accept(this);
324
+            return null;
325
+        }
326
+        final String signature = calcFunctionSignature(expression.closure, expression.header.returnType);
327
+        final String name = "lambda" + expression.hashCode();
328
+
329
+        final JavaMethodInfo methodInfo = new JavaMethodInfo(javaWriter.method.javaClass, name, signature, Opcodes.ACC_STATIC | Opcodes.ACC_PRIVATE);
330
+        JavaWriter functionWriter = new JavaWriter(javaWriter.clazzVisitor, methodInfo, null, signature, null);
331
+
332
+        for (CapturedExpression capture : expression.closure.captures) {
333
+            capture.accept(new JavaCapturedExpressionVisitor(this));
334
+        }
335
+
336
+        javaWriter.invokeStatic(methodInfo);
337
+
338
+        functionWriter.start();
339
+        expression.body.accept(new JavaStatementVisitor(new JavaExpressionVisitor(functionWriter) {
340
+            @Override
341
+            public Void visitGetLocalVariable(GetLocalVariableExpression varExpression) {
342
+                final int position = calculateMemberPosition(varExpression, expression);
343
+                if (position < 0)
344
+                    throw new CompileException(varExpression.position, CompileExceptionCode.INTERNAL_ERROR, "Captured Statement error");
345
+                functionWriter.load(varExpression.variable.type.accept(JavaTypeVisitor.INSTANCE), position);
346
+                return null;
347
+            }
348
+        }));
349
+
350
+
351
+        functionWriter.ret();
352
+        functionWriter.end();
353
+
316 354
         return null;
317 355
     }
318 356
 
357
+    //TODO replace with visitor?
358
+    private static int calculateMemberPosition(GetLocalVariableExpression localVariableExpression, FunctionExpression expression) {
359
+        int h = expression.header.parameters.length;
360
+        for (CapturedExpression capture : expression.closure.captures) {
361
+            if (capture instanceof CapturedLocalVariableExpression && ((CapturedLocalVariableExpression) capture).variable == localVariableExpression.variable)
362
+                return h;
363
+            if (capture instanceof CapturedClosureExpression && ((CapturedClosureExpression) capture).value instanceof CapturedLocalVariableExpression && ((CapturedLocalVariableExpression) ((CapturedClosureExpression) capture).value).variable == localVariableExpression.variable)
364
+                return h;
365
+            h++;
366
+        }
367
+        return -1;
368
+    }
369
+
370
+    private String calcFunctionSignature(LambdaClosure closure, ITypeID type) {
371
+        StringJoiner joiner = new StringJoiner("", "(", ")");
372
+
373
+        for (CapturedExpression capture : closure.captures) {
374
+            String descriptor = capture.type.accept(JavaTypeVisitor.INSTANCE).getDescriptor();
375
+            joiner.add(descriptor);
376
+        }
377
+        return joiner.toString() + type.accept(JavaTypeVisitor.INSTANCE).getDescriptor();
378
+    }
379
+
319 380
     @Override
320 381
     public Void visitGenericCompare(GenericCompareExpression expression) {
321 382
         //TODO: What am I supposed to do here?
@@ -324,7 +385,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
324 385
 
325 386
     @Override
326 387
     public Void visitGetField(GetFieldExpression expression) {
327
-		expression.accept(this);
388
+        expression.accept(this);
328 389
         if (!checkAndGetFieldInfo(expression.field, false))
329 390
             throw new IllegalStateException("Missing field info on a field member!");
330 391
         return null;
@@ -332,7 +393,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
332 393
 
333 394
     @Override
334 395
     public Void visitGetFunctionParameter(GetFunctionParameterExpression expression) {
335
-		JavaParameterInfo parameter = expression.parameter.getTag(JavaParameterInfo.class);
396
+        JavaParameterInfo parameter = expression.parameter.getTag(JavaParameterInfo.class);
336 397
         javaWriter.load(Type.getType(expression.parameter.type.accept(JavaTypeClassVisitor.INSTANCE)), parameter.index);
337 398
         return null;
338 399
     }
@@ -403,11 +464,65 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
403 464
         }
404 465
         return null;
405 466
     }
406
-	
407
-	@Override
408
-	public Void visitMatch(MatchExpression expression) {
409
-		throw new UnsupportedOperationException();
410
-	}
467
+
468
+    @Override
469
+    public Void visitMatch(MatchExpression expression) {
470
+
471
+        final Label start = new Label();
472
+        final Label end = new Label();
473
+
474
+
475
+        javaWriter.label(start);
476
+        expression.value.accept(this);
477
+        if (expression.value.type == BasicTypeID.STRING)
478
+            javaWriter.invokeVirtual(new JavaMethodInfo(new JavaClassInfo("java/lang/Object"), "hashCode", "()I", 0));
479
+
480
+        final boolean hasNoDefault = hasNoDefault(expression);
481
+
482
+        final MatchExpression.Case[] cases = expression.cases;
483
+        final JavaSwitchLabel[] switchLabels = new JavaSwitchLabel[hasNoDefault ? cases.length : cases.length - 1];
484
+        final Label defaultLabel = new Label();
485
+
486
+        int i = 0;
487
+        for (final MatchExpression.Case matchCase : cases) {
488
+            if (matchCase.key != null) {
489
+                switchLabels[i++] = new JavaSwitchLabel(CompilerUtils.getKeyForSwitch(matchCase.key), new Label());
490
+            }
491
+        }
492
+
493
+        JavaSwitchLabel[] sortedSwitchLabels = Arrays.copyOf(switchLabels, switchLabels.length);
494
+        Arrays.sort(sortedSwitchLabels, (a, b) -> a.key - b.key);
495
+
496
+        javaWriter.lookupSwitch(defaultLabel, sortedSwitchLabels);
497
+
498
+        i = 0;
499
+        for (final MatchExpression.Case switchCase : cases) {
500
+            if (hasNoDefault || switchCase.key != null) {
501
+                javaWriter.label(switchLabels[i++].label);
502
+            } else {
503
+                javaWriter.label(defaultLabel);
504
+            }
505
+            switchCase.value.body.setTag(MatchExpression.class, expression);
506
+            switchCase.value.accept(this);
507
+            javaWriter.goTo(end);
508
+        }
509
+
510
+        if (hasNoDefault) {
511
+            javaWriter.label(defaultLabel);
512
+        }
513
+
514
+        javaWriter.label(end);
515
+
516
+
517
+        //throw new UnsupportedOperationException("Not yet implemented!");
518
+        return null;
519
+    }
520
+
521
+    private boolean hasNoDefault(MatchExpression switchStatement) {
522
+        for (MatchExpression.Case switchCase : switchStatement.cases)
523
+            if (switchCase.key == null) return false;
524
+        return true;
525
+    }
411 526
 
412 527
     @Override
413 528
     public Void visitNew(NewExpression expression) {
@@ -460,23 +575,23 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
460 575
 
461 576
         return null;
462 577
     }
463
-	
464
-	@Override
465
-	public Void visitPostCall(PostCallExpression expression) {
466
-		expression.target.accept(this);
467
-		javaWriter.dup(expression.type.accept(new JavaTypeVisitor()));
578
+
579
+    @Override
580
+    public Void visitPostCall(PostCallExpression expression) {
581
+        expression.target.accept(this);
582
+        javaWriter.dup(expression.type.accept(new JavaTypeVisitor()));
468 583
         if (!checkAndExecuteByteCodeImplementation(expression.member) && !checkAndExecuteMethodInfo(expression.member))
469 584
             throw new IllegalStateException("Call target has no method info!");
470
-		
471
-		return null;
472
-	}
585
+
586
+        return null;
587
+    }
473 588
 
474 589
     @Override
475 590
     public Void visitRange(RangeExpression expression) {
476
-		// TODO: there are other kinds of ranges also; there should be a Range<T, T> type with creation of synthetic types
591
+        // TODO: there are other kinds of ranges also; there should be a Range<T, T> type with creation of synthetic types
477 592
         if (expression.from.type.accept(JavaTypeClassVisitor.INSTANCE) != int.class)
478 593
             throw new CompileException(expression.position, CompileExceptionCode.INTERNAL_ERROR, "Only integer ranges supported");
479
-		
594
+
480 595
         javaWriter.newObject(IntRange.class);
481 596
         javaWriter.dup();
482 597
         expression.from.accept(this);
@@ -486,26 +601,26 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
486 601
 
487 602
         return null;
488 603
     }
489
-	
490
-	@Override
491
-	public Void visitSameObject(SameObjectExpression expression) {
492
-		expression.left.accept(this);
493
-		expression.right.accept(this);
494
-		
495
-		Label end = new Label();
496
-		Label equal = new Label();
497
-		
498
-		if (expression.inverted)
499
-			javaWriter.ifACmpNe(equal);
500
-		else
501
-			javaWriter.ifACmpEq(equal);
502
-		javaWriter.iConst0();
503
-		javaWriter.goTo(end);
504
-		javaWriter.label(equal);
505
-		javaWriter.iConst1();
506
-		javaWriter.label(end);
507
-		return null;
508
-	}
604
+
605
+    @Override
606
+    public Void visitSameObject(SameObjectExpression expression) {
607
+        expression.left.accept(this);
608
+        expression.right.accept(this);
609
+
610
+        Label end = new Label();
611
+        Label equal = new Label();
612
+
613
+        if (expression.inverted)
614
+            javaWriter.ifACmpNe(equal);
615
+        else
616
+            javaWriter.ifACmpEq(equal);
617
+        javaWriter.iConst0();
618
+        javaWriter.goTo(end);
619
+        javaWriter.label(equal);
620
+        javaWriter.iConst1();
621
+        javaWriter.label(end);
622
+        return null;
623
+    }
509 624
 
510 625
     @Override
511 626
     public Void visitSetField(SetFieldExpression expression) {
@@ -519,7 +634,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
519 634
     @Override
520 635
     public Void visitSetFunctionParameter(SetFunctionParameterExpression expression) {
521 636
         expression.value.accept(this);
522
-		JavaParameterInfo parameter = expression.parameter.getTag(JavaParameterInfo.class);
637
+        JavaParameterInfo parameter = expression.parameter.getTag(JavaParameterInfo.class);
523 638
         javaWriter.store(expression.type.accept(JavaTypeVisitor.INSTANCE), parameter.index);
524 639
         return null;
525 640
     }
@@ -561,11 +676,11 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
561 676
     public Void visitStaticSetter(StaticSetterExpression expression) {
562 677
         return null;
563 678
     }
564
-	
565
-	@Override
566
-	public Void visitSupertypeCast(SupertypeCastExpression expression) {
567
-		return null; // nothing to do
568
-	}
679
+
680
+    @Override
681
+    public Void visitSupertypeCast(SupertypeCastExpression expression) {
682
+        return null; // nothing to do
683
+    }
569 684
 
570 685
     @Override
571 686
     public Void visitThis(ThisExpression expression) {
@@ -573,30 +688,30 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void> {
573 688
         return null;
574 689
     }
575 690
 
576
-	@Override
577
-	public Void visitTryConvert(TryConvertExpression expression) {
578
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
579
-	}
691
+    @Override
692
+    public Void visitTryConvert(TryConvertExpression expression) {
693
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
694
+    }
695
+
696
+    @Override
697
+    public Void visitTryRethrowAsException(TryRethrowAsExceptionExpression expression) {
698
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
699
+    }
580 700
 
581
-	@Override
582
-	public Void visitTryRethrowAsException(TryRethrowAsExceptionExpression expression) {
583
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
584
-	}
701
+    @Override
702
+    public Void visitTryRethrowAsResult(TryRethrowAsResultExpression expression) {
703
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
704
+    }
585 705
 
586
-	@Override
587
-	public Void visitTryRethrowAsResult(TryRethrowAsResultExpression expression) {
588
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
589
-	}
590
-	
591
-	@Override
592
-	public Void visitVariantValue(VariantValueExpression expression) {
593
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
594
-	}
706
+    @Override
707
+    public Void visitVariantValue(VariantValueExpression expression) {
708
+        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
709
+    }
595 710
 
596 711
     @Override
597 712
     public Void visitWrapOptional(WrapOptionalExpression expression) {
598
-		// TODO: convert basic types (char, int, float, ...) to their boxed (Character, Integer, Float, ...) counterparts
599
-		// -- any object type values can just be passed as-is
713
+        // TODO: convert basic types (char, int, float, ...) to their boxed (Character, Integer, Float, ...) counterparts
714
+        // -- any object type values can just be passed as-is
600 715
         expression.value.accept(this);
601 716
         return null;
602 717
     }

+ 17
- 12
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaStatementVisitor.java Näytä tiedosto

@@ -13,7 +13,7 @@ import java.util.List;
13 13
 
14 14
 public class JavaStatementVisitor implements StatementVisitor<Boolean> {
15 15
     private final JavaWriter javaWriter;
16
-    public final JavaExpressionVisitor expressionVisitor;
16
+    public JavaExpressionVisitor expressionVisitor;
17 17
 
18 18
     /**
19 19
      * @param javaWriter the method writer that compiles the statement
@@ -23,6 +23,11 @@ public class JavaStatementVisitor implements StatementVisitor<Boolean> {
23 23
         this.expressionVisitor = new JavaExpressionVisitor(javaWriter);
24 24
     }
25 25
 
26
+    public JavaStatementVisitor(JavaExpressionVisitor expressionVisitor) {
27
+        this.javaWriter = expressionVisitor.getJavaWriter();
28
+        this.expressionVisitor = expressionVisitor;
29
+    }
30
+
26 31
     @Override
27 32
     public Boolean visitBlock(BlockStatement statement) {
28 33
         Boolean returns = false;
@@ -156,25 +161,25 @@ public class JavaStatementVisitor implements StatementVisitor<Boolean> {
156 161
 
157 162
         javaWriter.label(start);
158 163
         statement.value.accept(expressionVisitor);
159
-        if(statement.value.type == BasicTypeID.STRING)
164
+        if (statement.value.type == BasicTypeID.STRING)
160 165
             javaWriter.invokeVirtual(new JavaMethodInfo(new JavaClassInfo("java/lang/Object"), "hashCode", "()I", 0));
161 166
         boolean out = false;
162 167
 
163 168
         final boolean hasNoDefault = hasNoDefault(statement);
164 169
 
165 170
         final List<SwitchCase> cases = statement.cases;
166
-		final JavaSwitchLabel[] switchLabels = new JavaSwitchLabel[hasNoDefault ? cases.size() : cases.size() - 1];
171
+        final JavaSwitchLabel[] switchLabels = new JavaSwitchLabel[hasNoDefault ? cases.size() : cases.size() - 1];
167 172
         final Label defaultLabel = new Label();
168
-		
173
+
169 174
         int i = 0;
170 175
         for (final SwitchCase switchCase : cases) {
171 176
             if (switchCase.value != null) {
172
-				switchLabels[i++] = new JavaSwitchLabel(CompilerUtils.getKeyForSwitch(switchCase.value), new Label());
173
-			}
174
-		}
175
-		
176
-		JavaSwitchLabel[] sortedSwitchLabels = Arrays.copyOf(switchLabels, switchLabels.length);
177
-		Arrays.sort(sortedSwitchLabels, (a, b) -> a.key - b.key);
177
+                switchLabels[i++] = new JavaSwitchLabel(CompilerUtils.getKeyForSwitch(switchCase.value), new Label());
178
+            }
179
+        }
180
+
181
+        JavaSwitchLabel[] sortedSwitchLabels = Arrays.copyOf(switchLabels, switchLabels.length);
182
+        Arrays.sort(sortedSwitchLabels, (a, b) -> a.key - b.key);
178 183
 
179 184
         javaWriter.lookupSwitch(defaultLabel, sortedSwitchLabels);
180 185
 
@@ -190,7 +195,7 @@ public class JavaStatementVisitor implements StatementVisitor<Boolean> {
190 195
             }
191 196
         }
192 197
 
193
-        if(hasNoDefault)
198
+        if (hasNoDefault)
194 199
             javaWriter.label(defaultLabel);
195 200
 
196 201
         javaWriter.label(end);
@@ -204,7 +209,7 @@ public class JavaStatementVisitor implements StatementVisitor<Boolean> {
204 209
         for (SwitchCase switchCase : switchStatement.cases)
205 210
             if (switchCase.value == null) return false;
206 211
         return true;
207
-	}
212
+    }
208 213
 
209 214
     @Override
210 215
     public Boolean visitThrow(ThrowStatement statement) {

+ 66
- 65
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaWriter.java Näytä tiedosto

@@ -2,7 +2,11 @@ package org.openzen.zenscript.javabytecode.compiler;
2 2
 
3 3
 import org.objectweb.asm.*;
4 4
 import org.objectweb.asm.commons.LocalVariablesSorter;
5
+import org.openzen.zenscript.codemodel.HighLevelDefinition;
6
+import org.openzen.zenscript.javabytecode.JavaClassInfo;
5 7
 import org.openzen.zenscript.javabytecode.JavaLocalVariableInfo;
8
+import org.openzen.zenscript.javabytecode.JavaMethodInfo;
9
+import org.openzen.zenscript.javabytecode.JavaParameterInfo;
6 10
 import org.openzen.zenscript.shared.CodePosition;
7 11
 
8 12
 import java.lang.reflect.Field;
@@ -12,41 +16,38 @@ import java.util.List;
12 16
 import java.util.Map;
13 17
 
14 18
 import static org.objectweb.asm.Opcodes.*;
15
-import org.openzen.zenscript.codemodel.HighLevelDefinition;
16
-import org.openzen.zenscript.javabytecode.JavaClassInfo;
17
-import org.openzen.zenscript.javabytecode.JavaMethodInfo;
18
-import org.openzen.zenscript.javabytecode.JavaParameterInfo;
19 19
 
20 20
 public class JavaWriter {
21
-	private static final JavaClassInfo T_STRING = new JavaClassInfo("java/lang/String");
22
-	private static final JavaMethodInfo STRING_CONCAT = new JavaMethodInfo(
23
-			T_STRING,
24
-			"concat",
25
-			"(Ljava/lang/String;)Ljava/lang/String;",
26
-			Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC);
27
-	
28
-	public final JavaMethodInfo method;
29
-	public final HighLevelDefinition forDefinition;
30
-	
21
+    private static final JavaClassInfo T_STRING = new JavaClassInfo("java/lang/String");
22
+    private static final JavaMethodInfo STRING_CONCAT = new JavaMethodInfo(
23
+            T_STRING,
24
+            "concat",
25
+            "(Ljava/lang/String;)Ljava/lang/String;",
26
+            Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC);
27
+
28
+    public final JavaMethodInfo method;
29
+    public final HighLevelDefinition forDefinition;
30
+
31 31
     private final LocalVariablesSorter visitor;
32 32
     private final List<JavaLocalVariableInfo> localVariableInfos = new ArrayList<>();
33
+    public final ClassVisitor clazzVisitor;
33 34
     private boolean debug = false;
34 35
     private boolean nameVariables = true;
35 36
     private int labelIndex = 1;
36 37
     private Map<Label, String> labelNames = new HashMap<>();
37 38
 
38 39
     public JavaWriter(
39
-			ClassVisitor visitor,
40
-			boolean nameVariables,
41
-			JavaMethodInfo method,
42
-			HighLevelDefinition forDefinition,
43
-			String signature,
44
-			String[] exceptions,
45
-			String... annotations)
46
-	{
47
-		this.method = method;
48
-		this.forDefinition = forDefinition;
49
-		
40
+            ClassVisitor visitor,
41
+            boolean nameVariables,
42
+            JavaMethodInfo method,
43
+            HighLevelDefinition forDefinition,
44
+            String signature,
45
+            String[] exceptions,
46
+            String... annotations) {
47
+        this.clazzVisitor = visitor;
48
+        this.method = method;
49
+        this.forDefinition = forDefinition;
50
+
50 51
         final MethodVisitor methodVisitor = visitor.visitMethod(method.modifiers, method.name, method.descriptor, signature, exceptions);
51 52
 
52 53
         for (String annotation : annotations) {
@@ -174,13 +175,13 @@ public class JavaWriter {
174 175
 
175 176
         visitor.visitInsn(DUP);
176 177
     }
177
-	
178
-	public void dup(Type type) {
178
+
179
+    public void dup(Type type) {
179 180
         if (debug)
180 181
             System.out.println("dup");
181
-		
182
-		visitor.visitInsn(type.getSize() == 2 ? DUP2 : DUP);
183
-	}
182
+
183
+        visitor.visitInsn(type.getSize() == 2 ? DUP2 : DUP);
184
+    }
184 185
 
185 186
     public void dup(boolean large) {
186 187
         if (debug)
@@ -237,34 +238,34 @@ public class JavaWriter {
237 238
 
238 239
         visitor.visitVarInsn(type.getOpcode(ILOAD), local);
239 240
     }
240
-	
241
-	public void load(JavaParameterInfo parameter) {
241
+
242
+    public void load(JavaParameterInfo parameter) {
242 243
         if (debug)
243 244
             System.out.println("load " + parameter.index);
244 245
 
245 246
         visitor.visitVarInsn(parameter.type.getOpcode(ILOAD), parameter.index);
246
-	}
247
-	
248
-	public void load(JavaLocalVariableInfo localVariable) {
247
+    }
248
+
249
+    public void load(JavaLocalVariableInfo localVariable) {
249 250
         if (debug)
250 251
             System.out.println("load " + localVariable.local);
251 252
 
252 253
         visitor.visitVarInsn(localVariable.type.getOpcode(ILOAD), localVariable.local);
253
-	}
254
-	
255
-	public void store(JavaParameterInfo parameter) {
254
+    }
255
+
256
+    public void store(JavaParameterInfo parameter) {
256 257
         if (debug)
257 258
             System.out.println("store " + parameter.index);
258 259
 
259 260
         visitor.visitVarInsn(parameter.type.getOpcode(ISTORE), parameter.index);
260
-	}
261
-	
262
-	public void store(JavaLocalVariableInfo localVariable) {
261
+    }
262
+
263
+    public void store(JavaLocalVariableInfo localVariable) {
263 264
         if (debug)
264 265
             System.out.println("store " + localVariable.local);
265 266
 
266 267
         visitor.visitVarInsn(localVariable.type.getOpcode(ISTORE), localVariable.local);
267
-	}
268
+    }
268 269
 
269 270
     public void storeInt(int local) {
270 271
         if (debug)
@@ -641,10 +642,10 @@ public class JavaWriter {
641 642
     public void iinc(int local) {
642 643
         iinc(local, 1);
643 644
     }
644
-	
645
-	public void idec(int local) {
646
-		iinc(local, -1);
647
-	}
645
+
646
+    public void idec(int local) {
647
+        iinc(local, -1);
648
+    }
648 649
 
649 650
     public void iinc(int local, int increment) {
650 651
         if (debug)
@@ -778,15 +779,15 @@ public class JavaWriter {
778 779
 
779 780
         visitor.visitTypeInsn(INSTANCEOF, clsName);
780 781
     }
781
-	
782
-	public void invokeStatic(JavaMethodInfo method) {
783
-		visitor.visitMethodInsn(
784
-				INVOKESTATIC,
785
-				method.javaClass.internalClassName,
786
-				method.name,
787
-				method.descriptor,
788
-				false);
789
-	}
782
+
783
+    public void invokeStatic(JavaMethodInfo method) {
784
+        visitor.visitMethodInsn(
785
+                INVOKESTATIC,
786
+                method.javaClass.internalClassName,
787
+                method.name,
788
+                method.descriptor,
789
+                false);
790
+    }
790 791
 
791 792
     public void invokeSpecial(String owner, String name, String descriptor) {
792 793
         if (debug)
@@ -798,13 +799,13 @@ public class JavaWriter {
798 799
     public void invokeSpecial(Class owner, String name, String descriptor) {
799 800
         invokeSpecial(Type.getInternalName(owner), name, descriptor);
800 801
     }
801
-	
802
-	public void invokeVirtual(JavaMethodInfo method) {
802
+
803
+    public void invokeVirtual(JavaMethodInfo method) {
803 804
         if (debug)
804 805
             System.out.println("invokeVirtual " + method.javaClass.internalClassName + '.' + method.name + method.descriptor);
805 806
 
806 807
         visitor.visitMethodInsn(INVOKEVIRTUAL, method.javaClass.internalClassName, method.name, method.descriptor, false);
807
-	}
808
+    }
808 809
 
809 810
     public void invokeInterface(JavaMethodInfo method) {
810 811
         if (debug)
@@ -1129,13 +1130,13 @@ public class JavaWriter {
1129 1130
     }
1130 1131
 
1131 1132
     public void lookupSwitch(Label defaultLabel, JavaSwitchLabel[] switchLabels) {
1132
-		int[] keys = new int[switchLabels.length];
1133
-		Label[] labels = new Label[switchLabels.length];
1134
-		for (int i = 0; i < switchLabels.length; i++) {
1135
-			keys[i] = switchLabels[i].key;
1136
-			labels[i] = switchLabels[i].label;
1137
-		}
1138
-		
1133
+        int[] keys = new int[switchLabels.length];
1134
+        Label[] labels = new Label[switchLabels.length];
1135
+        for (int i = 0; i < switchLabels.length; i++) {
1136
+            keys[i] = switchLabels[i].key;
1137
+            labels[i] = switchLabels[i].label;
1138
+        }
1139
+
1139 1140
         visitor.visitLookupSwitchInsn(defaultLabel, keys, labels);
1140 1141
     }
1141 1142
 

+ 26
- 0
ScriptingExample/scripts/match.zs Näytä tiedosto

@@ -0,0 +1,26 @@
1
+val test as int = 10;
2
+val tt1 = "tt";
3
+val tt2 = "tt3";
4
+val tt4 = "tt5";
5
+
6
+
7
+println(match 10 {
8
+	1 => "one",
9
+	10 => "yo",
10
+	//tt1 === "tt1" for some compiler issue it takes the variable as string input?
11
+	100 => match tt1 {
12
+		"10" => "t",
13
+		"tt1" => tt1,
14
+		"tt2" => tt1 + tt4,
15
+		default => tt4
16
+	},
17
+	default => tt2
18
+});
19
+
20
+
21
+println(tt1);
22
+
23
+//println(match test {
24
+//	case 1 : "tt",
25
+//	default : "kk"
26
+//});

Loading…
Peruuta
Tallenna