From 983bc00a5d14229156ef31b94afeafac15d7c7d0 Mon Sep 17 00:00:00 2001 From: brenokeller Date: Sat, 29 Oct 2016 22:10:26 -0200 Subject: [PATCH] add 'int' type --- src/main/c/bindings.c | 4 + src/main/cup/parser.cup | 4 +- src/main/java/absyn/ExpBinOp.java | 120 ++++++++++++++++----------- src/main/java/absyn/ExpInt.java | 33 ++++++++ src/main/java/absyn/ExpReal.java | 42 +++++----- src/main/java/codegen/Generator.java | 6 +- src/main/java/types/INT.java | 15 ++++ src/main/jflex/lexer.jflex | 5 +- 8 files changed, 157 insertions(+), 72 deletions(-) create mode 100644 src/main/java/absyn/ExpInt.java create mode 100644 src/main/java/types/INT.java diff --git a/src/main/c/bindings.c b/src/main/c/bindings.c index 25bc552..c1f5b97 100644 --- a/src/main/c/bindings.c +++ b/src/main/c/bindings.c @@ -3,3 +3,7 @@ extern void __eplan_print_double(const double x) { printf("%f\n", x); } + +extern void __eplan_print_int(const int32_t x){ + printf("%"PRId32"\n",x); +} \ No newline at end of file diff --git a/src/main/cup/parser.cup b/src/main/cup/parser.cup index 0ed81ea..f9f302c 100644 --- a/src/main/cup/parser.cup +++ b/src/main/cup/parser.cup @@ -38,6 +38,7 @@ parser code {: :}; terminal String LITREAL; +terminal String LITINT; terminal PLUS, MINUS, TIMES, DIV; terminal LPAREN, RPAREN; @@ -65,7 +66,8 @@ term ::= ; factor ::= - LITREAL:x {: RESULT = new ExpReal(loc(xxleft,xxright), x); :} + LITINT:x {: RESULT = new ExpInt(loc(xxleft,xxright), x); :} +| LITREAL:x {: RESULT = new ExpReal(loc(xxleft,xxright), x); :} | MINUS:m factor:x {: RESULT = new ExpNegate(loc(mxleft,xxright), x); :} | LPAREN exp:x RPAREN {: RESULT = x; :} ; diff --git a/src/main/java/absyn/ExpBinOp.java b/src/main/java/absyn/ExpBinOp.java index 85cba44..16ab7a9 100644 --- a/src/main/java/absyn/ExpBinOp.java +++ b/src/main/java/absyn/ExpBinOp.java @@ -2,6 +2,7 @@ import javaslang.collection.Tree; import parse.Loc; +import types.INT; import types.REAL; import types.Type; @@ -11,51 +12,76 @@ public class ExpBinOp extends Exp { - public enum Op {PLUS, MINUS, TIMES, DIV} - - public final Op op; - public final Exp left; - public final Exp right; - - public ExpBinOp(Loc loc, Op op, Exp left, Exp right) { - super(loc); - this.op = op; - this.left = left; - this.right = right; - } - - @Override - public Tree.Node toTree() { - return Tree.of(annotateType("ExpBinOp: " + op), left.toTree(), right.toTree()); - } - - @Override - protected Type semantic_() { - final Type t_left = left.semantic(); - final Type t_right = right.semantic(); - if (! t_left.is(REAL.T)) - throw typeMismatch(left.loc, t_left, REAL.T); - if (! t_right.is(REAL.T)) - throw typeMismatch(right.loc, t_right, REAL.T); - return REAL.T; - } - - @Override - public LLVMValueRef translate(LLVMModuleRef module, LLVMBuilderRef builder) { - final LLVMValueRef v_left = left.translate(module, builder); - final LLVMValueRef v_right = right.translate(module, builder); - - switch (op) { - case PLUS: - return LLVMBuildFAdd(builder, v_left, v_right, "addtmp"); - case MINUS: - return LLVMBuildFSub(builder, v_left, v_right, "subtmp"); - case TIMES: - return LLVMBuildFMul(builder, v_left, v_right, "multmp"); - case DIV: - return LLVMBuildFDiv(builder, v_left, v_right, "divtmp"); - default: - throw fatal("unknown operator %s in binary operation", op); - } - } + public enum Op {PLUS, MINUS, TIMES, DIV} + + public final Op op; + public final Exp left; + public final Exp right; + + public ExpBinOp(Loc loc, Op op, Exp left, Exp right) { + super(loc); + this.op = op; + this.left = left; + this.right = right; + } + + @Override + public Tree.Node toTree() { + return Tree.of(annotateType("ExpBinOp: " + op), left.toTree(), right.toTree()); + } + + @Override + protected Type semantic_() { + final Type t_left = left.semantic(); + final Type t_right = right.semantic(); + if (t_left.is(INT.T)) { + if (!t_right.is(INT.T)) { + typeMismatch(right.loc, t_right, INT.T); + } + return t_left; + } else if (t_left.is(REAL.T)) { + if (!t_right.is(REAL.T)) { + typeMismatch(right.loc, t_right, REAL.T); + } + return t_left; + } else { + typeMismatch(left.loc, t_left, INT.T, REAL.T); + return REAL.T; + } + } + + @Override + public LLVMValueRef translate(LLVMModuleRef module, LLVMBuilderRef builder) { + final LLVMValueRef v_left = left.translate(module, builder); + final LLVMValueRef v_right = right.translate(module, builder); + + switch (op) { + case PLUS: + if (left.semantic().is(INT.T)) { + return LLVMBuildAdd(builder, v_left, v_right, "addtmp"); + } else { + return LLVMBuildFAdd(builder, v_left, v_right, "addtmp"); + } + case MINUS: + if (left.semantic().is(INT.T)) { + return LLVMBuildSub(builder, v_left, v_right, "subtmp"); + } else { + return LLVMBuildFSub(builder, v_left, v_right, "subtmp"); + } + case TIMES: + if (left.semantic().is(INT.T)) { + return LLVMBuildMul(builder, v_left, v_right, "multmp"); + } else { + return LLVMBuildFMul(builder, v_left, v_right, "multmp"); + } + case DIV: + if (left.semantic().is(INT.T)) { + return LLVMBuildSDiv(builder, v_left, v_right, "divtmp"); + } else { + return LLVMBuildFDiv(builder, v_left, v_right, "divtmp"); + } + default: + throw fatal("unknown operator %s in binary operation", op); + } + } } diff --git a/src/main/java/absyn/ExpInt.java b/src/main/java/absyn/ExpInt.java new file mode 100644 index 0000000..38824ef --- /dev/null +++ b/src/main/java/absyn/ExpInt.java @@ -0,0 +1,33 @@ +package absyn; + +import javaslang.collection.Tree; +import parse.Loc; +import types.INT; +import types.Type; + +import static org.bytedeco.javacpp.LLVM.*; + +public class ExpInt extends Exp { + + public final String value; + + public ExpInt(Loc loc, String value) { + super(loc); + this.value = value; + } + + @Override + public Tree.Node toTree() { + return Tree.of(annotateType("ExpInt: " + value)); + } + + @Override + protected Type semantic_() { + return INT.T; + } + + @Override + public LLVMValueRef translate(LLVMModuleRef module, LLVMBuilderRef builder) { + return LLVMConstIntOfString(LLVMInt32Type(), value, (byte) 10); + } +} \ No newline at end of file diff --git a/src/main/java/absyn/ExpReal.java b/src/main/java/absyn/ExpReal.java index 48b429c..b63de7e 100644 --- a/src/main/java/absyn/ExpReal.java +++ b/src/main/java/absyn/ExpReal.java @@ -9,25 +9,25 @@ public class ExpReal extends Exp { - public final String value; - - public ExpReal(Loc loc, String value) { - super(loc); - this.value = value; - } - - @Override - public Tree.Node toTree() { - return Tree.of(annotateType("ExpReal: " + value)); - } - - @Override - protected Type semantic_() { - return REAL.T; - } - - @Override - public LLVMValueRef translate(LLVMModuleRef module, LLVMBuilderRef builder) { - return LLVMConstRealOfString(LLVMDoubleType(), value); - } + public final String value; + + public ExpReal(Loc loc, String value) { + super(loc); + this.value = value; + } + + @Override + public Tree.Node toTree() { + return Tree.of(annotateType("ExpReal: " + value)); + } + + @Override + protected Type semantic_() { + return REAL.T; + } + + @Override + public LLVMValueRef translate(LLVMModuleRef module, LLVMBuilderRef builder) { + return LLVMConstRealOfString(LLVMDoubleType(), value); + } } diff --git a/src/main/java/codegen/Generator.java b/src/main/java/codegen/Generator.java index e44eb68..4850393 100644 --- a/src/main/java/codegen/Generator.java +++ b/src/main/java/codegen/Generator.java @@ -4,6 +4,7 @@ import org.bytedeco.javacpp.BytePointer; import org.bytedeco.javacpp.Pointer; import org.bytedeco.javacpp.PointerPointer; +import types.INT; import types.REAL; import types.Type; @@ -87,6 +88,7 @@ public static void addPrototype(LLVMModuleRef module, public static void addRuntime(LLVMModuleRef module, LLVMBuilderRef builder) { addPrototype(module, builder, "__eplan_print_double", LLVMVoidType(), LLVMDoubleType()); + addPrototype(module, builder, "__eplan_print_int", LLVMVoidType(), LLVMInt32Type()); addPrototype(module, builder, "llvm.pow.f64", LLVMDoubleType(), LLVMDoubleType(), LLVMDoubleType()); } @@ -97,7 +99,9 @@ public static LLVMValueRef addPrintResult(LLVMModuleRef module, if (t_exp instanceof REAL) { return addCall(module, builder, "__eplan_print_double", v_exp); } - + if (t_exp instanceof INT) { + return addCall(module, builder, "__eplan_print_int", v_exp); + } return LLVMConstReal(LLVMInt32Type(), 0); } diff --git a/src/main/java/types/INT.java b/src/main/java/types/INT.java new file mode 100644 index 0000000..45b6914 --- /dev/null +++ b/src/main/java/types/INT.java @@ -0,0 +1,15 @@ +package types; + +public class INT extends Type { + + public static final INT T = new INT(); + + private INT() { + } + + @Override + public String toString() { + return "int"; + } + +} \ No newline at end of file diff --git a/src/main/jflex/lexer.jflex b/src/main/jflex/lexer.jflex index 999764d..022b7a8 100644 --- a/src/main/jflex/lexer.jflex +++ b/src/main/jflex/lexer.jflex @@ -63,13 +63,14 @@ import java_cup.runtime.ComplexSymbolFactory; litint = [0-9]+ litfloat1 = [0-9]+ "." [0-9]* litfloat2 = [0-9]* "." [0-9]+ -litfloat3 = ({litint} | {litfloat1} | {litfloat2}) [eE] [+-]? {litint} -litreal = {litint} | {litfloat1} | {litfloat2} | {litfloat3} +litfloat3 = ({litfloat1} | {litfloat2}) [eE] [+-]? {litint} +litreal = {litfloat1} | {litfloat2} | {litfloat3} %% [ \t\f\n\r]+ { /* skip */ } +{litint} { return tok(LITINT, yytext()); } {litreal} { return tok(LITREAL, yytext()); } "+" { return tok(PLUS); }