Переглянути джерело

Simplified handling of switch cases.

Stan Hebben 6 роки тому
джерело
коміт
f89d5f93ae

+ 3
- 3
CodeModel/src/main/java/org/openzen/zenscript/codemodel/statement/SwitchCase.java Переглянути файл

@@ -6,17 +6,17 @@
6 6
 package org.openzen.zenscript.codemodel.statement;
7 7
 
8 8
 import java.util.List;
9
-import org.openzen.zenscript.codemodel.expression.Expression;
9
+import org.openzen.zenscript.codemodel.expression.switchvalue.SwitchValue;
10 10
 
11 11
 /**
12 12
  *
13 13
  * @author Hoofdgebruiker
14 14
  */
15 15
 public class SwitchCase {
16
-	public final Expression value;
16
+	public final SwitchValue value;
17 17
 	public final List<Statement> statements;
18 18
 	
19
-	public SwitchCase(Expression value, List<Statement> statements) {
19
+	public SwitchCase(SwitchValue value, List<Statement> statements) {
20 20
 		this.value = value;
21 21
 		this.statements = statements;
22 22
 	}

+ 37
- 49
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/CompilerUtils.java Переглянути файл

@@ -7,6 +7,13 @@ import org.openzen.zenscript.codemodel.FunctionParameter;
7 7
 import org.openzen.zenscript.codemodel.HighLevelDefinition;
8 8
 import org.openzen.zenscript.codemodel.Modifiers;
9 9
 import org.openzen.zenscript.codemodel.expression.*;
10
+import org.openzen.zenscript.codemodel.expression.switchvalue.CharSwitchValue;
11
+import org.openzen.zenscript.codemodel.expression.switchvalue.EnumConstantSwitchValue;
12
+import org.openzen.zenscript.codemodel.expression.switchvalue.IntSwitchValue;
13
+import org.openzen.zenscript.codemodel.expression.switchvalue.StringSwitchValue;
14
+import org.openzen.zenscript.codemodel.expression.switchvalue.SwitchValue;
15
+import org.openzen.zenscript.codemodel.expression.switchvalue.SwitchValueVisitor;
16
+import org.openzen.zenscript.codemodel.expression.switchvalue.VariantOptionSwitchValue;
10 17
 import org.openzen.zenscript.codemodel.member.FieldMember;
11 18
 import org.openzen.zenscript.codemodel.member.IDefinitionMember;
12 19
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
@@ -116,54 +123,35 @@ public class CompilerUtils {
116 123
     }
117 124
 
118 125
 
119
-    public static int getKeyForSwitch(Expression expression) {
120
-        if (expression.type instanceof BasicTypeID)
121
-            switch ((BasicTypeID) expression.type) {
122
-                case BOOL:
123
-                    if (expression instanceof ConstantBoolExpression)
124
-                        return ((ConstantBoolExpression) expression).value ? 1 : 0;
125
-                    break;
126
-                case BYTE:
127
-                    if (expression instanceof ConstantByteExpression)
128
-                        return ((ConstantByteExpression) expression).value;
129
-                    break;
130
-                case SBYTE:
131
-                    if (expression instanceof ConstantSByteExpression)
132
-                        return ((ConstantSByteExpression) expression).value;
133
-                    break;
134
-                case SHORT:
135
-                    if(expression instanceof ConstantShortExpression)
136
-                        return ((ConstantShortExpression) expression).value;
137
-                    break;
138
-                case USHORT:
139
-                    if (expression instanceof ConstantUShortExpression)
140
-                        return ((ConstantUShortExpression) expression).value;
141
-                    break;
142
-                case INT:
143
-                    if (expression instanceof ConstantIntExpression)
144
-                        return ((ConstantIntExpression) expression).value;
145
-                    break;
146
-                case UINT:
147
-                    if (expression instanceof ConstantUIntExpression)
148
-                        return ((ConstantUIntExpression) expression).value;
149
-                    break;
150
-                case LONG:
151
-                    if(expression instanceof ConstantLongExpression)
152
-                        return (int)((ConstantLongExpression) expression).value;
153
-                    break;
154
-                case ULONG:
155
-                    if(expression instanceof ConstantULongExpression)
156
-                        return (int)((ConstantULongExpression) expression).value;
157
-                    break;
158
-                case CHAR:
159
-                    if(expression instanceof ConstantCharExpression)
160
-                        return ((ConstantCharExpression) expression).value;
161
-                    break;
162
-                case STRING:
163
-                    if(expression instanceof ConstantStringExpression)
164
-                        return ((ConstantStringExpression) expression).value.hashCode();
165
-                    break;
166
-            }
167
-            throw new RuntimeException("Cannot switch over expression " + expression);
126
+    public static int getKeyForSwitch(SwitchValue expression) {
127
+		return expression.accept(new SwitchKeyVisitor());
168 128
     }
129
+	
130
+	private static class SwitchKeyVisitor implements SwitchValueVisitor<Integer> {
131
+
132
+		@Override
133
+		public Integer acceptInt(IntSwitchValue value) {
134
+			return value.value;
135
+		}
136
+
137
+		@Override
138
+		public Integer acceptChar(CharSwitchValue value) {
139
+			return (int)value.value;
140
+		}
141
+
142
+		@Override
143
+		public Integer acceptString(StringSwitchValue value) {
144
+			return value.value.hashCode();
145
+		}
146
+
147
+		@Override
148
+		public Integer acceptEnumConstant(EnumConstantSwitchValue value) {
149
+			return value.constant.value;
150
+		}
151
+
152
+		@Override
153
+		public Integer acceptVariantOption(VariantOptionSwitchValue value) {
154
+			throw new UnsupportedOperationException("Not there yet");
155
+		}
156
+	}
169 157
 }

+ 14
- 0
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionInt.java Переглянути файл

@@ -15,10 +15,16 @@ import org.openzen.zenscript.codemodel.expression.ConstantUIntExpression;
15 15
 import org.openzen.zenscript.codemodel.expression.ConstantULongExpression;
16 16
 import org.openzen.zenscript.codemodel.expression.ConstantUShortExpression;
17 17
 import org.openzen.zenscript.codemodel.expression.Expression;
18
+import org.openzen.zenscript.codemodel.expression.switchvalue.CharSwitchValue;
19
+import org.openzen.zenscript.codemodel.expression.switchvalue.IntSwitchValue;
20
+import org.openzen.zenscript.codemodel.expression.switchvalue.StringSwitchValue;
21
+import org.openzen.zenscript.codemodel.expression.switchvalue.SwitchValue;
18 22
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
19 23
 import org.openzen.zenscript.codemodel.type.ITypeID;
20 24
 import org.openzen.zenscript.linker.ExpressionScope;
21 25
 import org.openzen.zenscript.shared.CodePosition;
26
+import org.openzen.zenscript.shared.CompileException;
27
+import org.openzen.zenscript.shared.CompileExceptionCode;
22 28
 
23 29
 /**
24 30
  *
@@ -66,6 +72,14 @@ public class ParsedExpressionInt extends ParsedExpression {
66 72
 		else
67 73
 			return new ConstantLongExpression(position, value);
68 74
 	}
75
+	
76
+	@Override
77
+	public SwitchValue compileToSwitchValue(ITypeID type, ExpressionScope scope) {
78
+		if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE)
79
+			throw new CompileException(position, CompileExceptionCode.INVALID_SWITCH_CASE, "value is too large for a switch case");
80
+		
81
+		return new IntSwitchValue((int) value);
82
+	}
69 83
 
70 84
 	@Override
71 85
 	public boolean hasStrongType() {

+ 20
- 0
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedExpressionString.java Переглянути файл

@@ -7,10 +7,16 @@ package org.openzen.zenscript.parser.expression;
7 7
 
8 8
 import org.openzen.zenscript.codemodel.expression.ConstantCharExpression;
9 9
 import org.openzen.zenscript.codemodel.expression.ConstantStringExpression;
10
+import org.openzen.zenscript.codemodel.expression.switchvalue.CharSwitchValue;
11
+import org.openzen.zenscript.codemodel.expression.switchvalue.StringSwitchValue;
12
+import org.openzen.zenscript.codemodel.expression.switchvalue.SwitchValue;
10 13
 import org.openzen.zenscript.codemodel.partial.IPartialExpression;
11 14
 import org.openzen.zenscript.codemodel.type.BasicTypeID;
15
+import org.openzen.zenscript.codemodel.type.ITypeID;
12 16
 import org.openzen.zenscript.linker.ExpressionScope;
13 17
 import org.openzen.zenscript.shared.CodePosition;
18
+import org.openzen.zenscript.shared.CompileException;
19
+import org.openzen.zenscript.shared.CompileExceptionCode;
14 20
 
15 21
 /**
16 22
  *
@@ -38,6 +44,20 @@ public class ParsedExpressionString extends ParsedExpression {
38 44
 		
39 45
 		return new ConstantStringExpression(position, value);
40 46
 	}
47
+	
48
+	@Override
49
+	public SwitchValue compileToSwitchValue(ITypeID type, ExpressionScope scope) {
50
+		if (type == BasicTypeID.CHAR) {
51
+			if (value.length() != 1)
52
+				throw new CompileException(position, CompileExceptionCode.INVALID_SWITCH_CASE, "char value expected but string given");
53
+			
54
+			return new CharSwitchValue(value.charAt(0));
55
+		} else if (type == BasicTypeID.STRING) {
56
+			return new StringSwitchValue(value);
57
+		} else {
58
+			throw new CompileException(position, CompileExceptionCode.INVALID_SWITCH_CASE, "Can only use string keys for string values");
59
+		}
60
+	}
41 61
 
42 62
 	@Override
43 63
 	public boolean hasStrongType() {

+ 1
- 2
Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedStatementSwitch.java Переглянути файл

@@ -10,7 +10,6 @@ import java.util.function.Function;
10 10
 import org.openzen.zenscript.codemodel.FunctionHeader;
11 11
 import org.openzen.zenscript.codemodel.WhitespaceInfo;
12 12
 import org.openzen.zenscript.codemodel.expression.Expression;
13
-import org.openzen.zenscript.codemodel.expression.GetLocalVariableExpression;
14 13
 import org.openzen.zenscript.codemodel.partial.IPartialExpression;
15 14
 import org.openzen.zenscript.codemodel.statement.LoopStatement;
16 15
 import org.openzen.zenscript.codemodel.statement.Statement;
@@ -46,7 +45,7 @@ public class ParsedStatementSwitch extends ParsedStatement {
46 45
 		SwitchScope innerScope = new SwitchScope(scope, result);
47 46
 		
48 47
 		for (ParsedSwitchCase switchCase : cases) {
49
-			result.cases.add(switchCase.compile(innerScope));
48
+			result.cases.add(switchCase.compile(result.value.type, innerScope));
50 49
 		}
51 50
 		
52 51
 		return result;

+ 4
- 3
Parser/src/main/java/org/openzen/zenscript/parser/statements/ParsedSwitchCase.java Переглянути файл

@@ -7,9 +7,10 @@ package org.openzen.zenscript.parser.statements;
7 7
 
8 8
 import java.util.ArrayList;
9 9
 import java.util.List;
10
-import org.openzen.zenscript.codemodel.expression.Expression;
10
+import org.openzen.zenscript.codemodel.expression.switchvalue.SwitchValue;
11 11
 import org.openzen.zenscript.codemodel.statement.Statement;
12 12
 import org.openzen.zenscript.codemodel.statement.SwitchCase;
13
+import org.openzen.zenscript.codemodel.type.ITypeID;
13 14
 import org.openzen.zenscript.linker.ExpressionScope;
14 15
 import org.openzen.zenscript.linker.StatementScope;
15 16
 import org.openzen.zenscript.parser.expression.ParsedExpression;
@@ -26,8 +27,8 @@ public class ParsedSwitchCase {
26 27
 		this.value = value;
27 28
 	}
28 29
 	
29
-	public SwitchCase compile(StatementScope scope) {
30
-		Expression cValue = value == null ? null : value.compile(new ExpressionScope(scope)).eval();
30
+	public SwitchCase compile(ITypeID type, StatementScope scope) {
31
+		SwitchValue cValue = value == null ? null : value.compileToSwitchValue(type, new ExpressionScope(scope));
31 32
 		List<Statement> cStatements = new ArrayList<>();
32 33
 		for (ParsedStatement statement : statements) {
33 34
 			cStatements.add(statement.compile(scope));

Завантаження…
Відмінити
Зберегти