Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/main/c/bindings.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
4 changes: 3 additions & 1 deletion src/main/cup/parser.cup
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ parser code {:
:};

terminal String LITREAL;
terminal String LITINT;
terminal PLUS, MINUS, TIMES, DIV;
terminal LPAREN, RPAREN;

Expand Down Expand Up @@ -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; :}
;
120 changes: 73 additions & 47 deletions src/main/java/absyn/ExpBinOp.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import javaslang.collection.Tree;
import parse.Loc;
import types.INT;
import types.REAL;
import types.Type;

Expand All @@ -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<String> 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<String> 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);
}
}
}
33 changes: 33 additions & 0 deletions src/main/java/absyn/ExpInt.java
Original file line number Diff line number Diff line change
@@ -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<String> 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);
}
}
42 changes: 21 additions & 21 deletions src/main/java/absyn/ExpReal.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> 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<String> 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);
}
}
6 changes: 5 additions & 1 deletion src/main/java/codegen/Generator.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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());
}

Expand All @@ -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);
}

Expand Down
15 changes: 15 additions & 0 deletions src/main/java/types/INT.java
Original file line number Diff line number Diff line change
@@ -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";
}

}
5 changes: 3 additions & 2 deletions src/main/jflex/lexer.jflex
Original file line number Diff line number Diff line change
Expand Up @@ -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); }
Expand Down