Skip to content

Commit 6b33777

Browse files
Merge pull request #62 from CompilerProgramming/float
Add # operator to get array length
2 parents b05404c + 1a26888 commit 6b33777

30 files changed

Lines changed: 374 additions & 12 deletions

File tree

antlr-parser/src/main/antlr4/com/compilerprogramming/ezlang/antlr/EZLanguage.g4

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ multiplicationExpression
9191
;
9292

9393
unaryExpression
94-
: ('-' | '!') unaryExpression
94+
: ('-' | '!' | '#') unaryExpression
9595
| postfixExpression
9696
;
9797

@@ -183,4 +183,4 @@ LINE_COMMENT
183183
;
184184

185185

186-
ANY: . ;
186+
ANY: . ;

docs/ez-lang.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ Following table describes the available operators by their precedence (low to hi
222222
| ``%`` | | |
223223
+------------+-----------------+----------+
224224
| ``-`` | negate | Unary |
225+
| ``#`` | array length | Unary |
225226
| ``!`` | | |
226227
+------------+-----------------+----------+
227228
| ``(...)``, | function call, | Postfix |

lexer/src/main/java/com/compilerprogramming/ezlang/lexer/Lexer.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ public Token scan() {
154154
case ',':
155155
case '.':
156156
case '%':
157+
case '#':
157158
case '+':
158159
case '*':
159160
case ';':

lexer/src/test/java/com/compilerprogramming/ezlang/lexer/TestLexer.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public class TestLexer {
1212
public void testLexer() {
1313
String src = """
1414
// A comment
15-
Ident=,>=<>>=!=!1.5{0}11()[]+-*/ //Another comment
15+
Ident=,>=<>>=!=!1.5{0}11()[]+-*/# //Another comment
1616
""";
1717
Lexer lexer = new Lexer(src);
1818
Token[] expected = new Token[]{
@@ -37,7 +37,8 @@ public void testLexer() {
3737
Token.newPunct("+", 0),
3838
Token.newPunct("-", 0),
3939
Token.newPunct("*", 0),
40-
Token.newPunct("/", 0)
40+
Token.newPunct("/", 0),
41+
Token.newPunct("#", 0)
4142
};
4243

4344
List<Token> tokens = new ArrayList<>();

optvm/src/main/java/com/compilerprogramming/ezlang/compiler/SparseConditionalConstantPropagation.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,6 +452,11 @@ private static EZType operandType(Operand operand) {
452452
}
453453

454454
private static boolean evalUnary(LatticeElement cell, LatticeElement input, String unOp, EZType resultType) {
455+
if (unOp.equals("#")) {
456+
if (input.kind == F_TOP || input.kind == F_REF_TOP)
457+
return false;
458+
return cell.meetWithTypeBottom(resultType);
459+
}
455460
if (input.isIntegerConstant()) {
456461
long value = input.kind == F_INT_ZERO ? 0 : input.intValue;
457462
if (unOp.equals("-"))

optvm/src/main/java/com/compilerprogramming/ezlang/interpreter/Interpreter.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,9 @@ else if (arg instanceof Operand.NullConstantOperand) {
153153
else if (unaryValue instanceof Value.FloatValue floatValue && unaryInst.unop.equals("-")) {
154154
execStack.stack[base + unaryInst.result().frameSlot()] = new Value.FloatValue(-floatValue.value);
155155
}
156+
else if (unaryValue instanceof Value.ArrayValue arrayValue && unaryInst.unop.equals("#")) {
157+
execStack.stack[base + unaryInst.result().frameSlot()] = new Value.IntegerValue(arrayValue.values.size());
158+
}
156159
else
157160
throw new IllegalStateException("Unexpected unary operand: " + unaryOperand);
158161
}

optvm/src/test/java/com/compilerprogramming/ezlang/interpreter/TestInterpreter.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,4 +1031,18 @@ func main()->Int
10311031
integerValue.value == 1);
10321032
}
10331033

1034+
@Test
1035+
public void testArrayLengthUnaryOperator() {
1036+
String src = """
1037+
func foo()->Int {
1038+
var a = new [Int] {1,2,3,4}
1039+
var b = new [Int] {len=0,value=0}
1040+
return #a + #b
1041+
}
1042+
""";
1043+
var value = compileAndRun(src, "foo");
1044+
Assert.assertNotNull(value);
1045+
Assert.assertTrue(value instanceof Value.IntegerValue integerValue
1046+
&& integerValue.value == 4);
1047+
}
10341048
}

parser/src/main/java/com/compilerprogramming/ezlang/parser/Parser.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,8 @@ private AST.Expr parseMultiplication(Lexer lexer) {
329329

330330
private AST.Expr parseUnary(Lexer lexer) {
331331
if (isToken(currentToken, "-")
332-
|| isToken(currentToken, "!")) {
332+
|| isToken(currentToken, "!")
333+
|| isToken(currentToken, "#")) {
333334
var tok = currentToken;
334335
nextToken(lexer);
335336
return new AST.UnaryExpr(tok, parseUnary(lexer), tok.lineNumber);

registervm/src/main/java/com/compilerprogramming/ezlang/interpreter/Interpreter.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,9 @@ else if (arg instanceof Operand.NullConstantOperand) {
152152
else if (unaryValue instanceof Value.FloatValue floatValue && unaryInst.unop.equals("-")) {
153153
execStack.stack[base + unaryInst.result().frameSlot()] = new Value.FloatValue(-floatValue.value);
154154
}
155+
else if (unaryValue instanceof Value.ArrayValue arrayValue && unaryInst.unop.equals("#")) {
156+
execStack.stack[base + unaryInst.result().frameSlot()] = new Value.IntegerValue(arrayValue.values.size());
157+
}
155158
else
156159
throw new IllegalStateException("Unexpected unary operand: " + unaryOperand);
157160
}

registervm/src/test/java/com/compilerprogramming/ezlang/interpreter/TestInterpreter.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,4 +558,18 @@ func foo()->Float {
558558
Assert.assertTrue(value instanceof Value.FloatValue floatValue
559559
&& Math.abs(floatValue.value - 3.5) < 0.000001);
560560
}
561+
@Test
562+
public void testArrayLengthUnaryOperator() {
563+
String src = """
564+
func foo()->Int {
565+
var a = new [Int] {1,2,3}
566+
var b = new [Int] {len=0,value=0}
567+
return #a + #b
568+
}
569+
""";
570+
var value = compileAndRun(src, "foo");
571+
Assert.assertNotNull(value);
572+
Assert.assertTrue(value instanceof Value.IntegerValue integerValue
573+
&& integerValue.value == 3);
574+
}
561575
}

0 commit comments

Comments
 (0)