diff --git a/src/main/java/com/ruke/vrjassc/translator/expression/ModuloExpression.java b/src/main/java/com/ruke/vrjassc/translator/expression/ModuloExpression.java new file mode 100644 index 0000000..0988d8c --- /dev/null +++ b/src/main/java/com/ruke/vrjassc/translator/expression/ModuloExpression.java @@ -0,0 +1,20 @@ +package com.ruke.vrjassc.translator.expression; + +public class ModuloExpression extends Expression { + + Expression a; + Expression b; + + public ModuloExpression(Expression a, Expression b) { + this.a = a; + this.b = b; + + this.a.setParent(this); + this.b.setParent(this); + } + + @Override + public String translate() { + return "ModuloReal(" + this.a.translate() + "," + this.b.translate() + ")"; + } +} diff --git a/src/main/java/com/ruke/vrjassc/vrjassc/phase/TranslationPhase.java b/src/main/java/com/ruke/vrjassc/vrjassc/phase/TranslationPhase.java index 0ae3a85..c7142ac 100644 --- a/src/main/java/com/ruke/vrjassc/vrjassc/phase/TranslationPhase.java +++ b/src/main/java/com/ruke/vrjassc/vrjassc/phase/TranslationPhase.java @@ -124,6 +124,14 @@ public Expression visitInteger(IntegerContext ctx) { return new RawExpression(ctx.getText(), this.scope.resolve("integer")); } + @Override + public Expression visitModulo(ModuloContext ctx) { + Expression a = this.visit(ctx.left); + Expression b = this.visit(ctx.right); + + return new ModuloExpression(a, b); + } + @Override public Expression visitDiv(DivContext ctx) { Expression a = this.visit(ctx.left); diff --git a/src/test/java/com/ruke/vrjassc/vrjassc/compiler/FunctionTest.java b/src/test/java/com/ruke/vrjassc/vrjassc/compiler/FunctionTest.java index 4a96f7d..a66dfbe 100644 --- a/src/test/java/com/ruke/vrjassc/vrjassc/compiler/FunctionTest.java +++ b/src/test/java/com/ruke/vrjassc/vrjassc/compiler/FunctionTest.java @@ -8,6 +8,25 @@ public class FunctionTest extends TestHelper { + @Test + public void modulo() { + String code = + "function foo\n" + + "local integer i = 2 % 1\n" + + "local real r = 2.1 % 1\n" + + "end"; + + String expected = + "globals\n" + + "endglobals\n" + + "function foo takes nothing returns nothing\n" + + "local integer i=ModuloReal(2,1)\n" + + "local real r=ModuloReal(2.1,1)\n" + + "endfunction"; + + assertEquals(expected, this.run(code)); + } + @Test public void continueStatement() { String code = diff --git a/vrjass.g4 b/vrjass.g4 index 925c223..9b90039 100644 --- a/vrjass.g4 +++ b/vrjass.g4 @@ -51,6 +51,7 @@ expression | cast #ignoreCastExpression | MINUS expression #Negative | NOT expression #Not + | left=expression MOD right=expression #Modulo | left=expression DIV right=expression #Div | left=expression TIMES right=expression #Mult | left=expression MINUS right=expression #Minus @@ -303,6 +304,7 @@ PAREN_RIGHT: ')'; BRACKET_LEFT: '['; BRACKET_RIGHT: ']'; COMMA: ','; +MOD: '%'; DIV: '/'; TIMES: '*'; MINUS: '-';