25: Start adding Float Type
This commit is contained in:
@@ -87,6 +87,7 @@ expression
|
||||
atom
|
||||
: INTEGER_LITERAL #intAtom
|
||||
| BOOLEAN_LITERAL #boolAtom
|
||||
| FLOAT_LITERAL #floatAtom
|
||||
| IDENT #variable
|
||||
;
|
||||
|
||||
@@ -97,6 +98,7 @@ type_annotation
|
||||
type
|
||||
: INTEGER
|
||||
| BOOLEAN
|
||||
| FLOAT
|
||||
;
|
||||
|
||||
functionCall
|
||||
@@ -131,6 +133,7 @@ WHILE: 'while';
|
||||
DO: 'do';
|
||||
FOR: 'for';
|
||||
|
||||
PERIOD: '.';
|
||||
COL: ':';
|
||||
SCOL: ';';
|
||||
OBRK: '{';
|
||||
@@ -157,11 +160,16 @@ DIV: '/';
|
||||
|
||||
BOOLEAN: 'bool';
|
||||
INTEGER: 'int';
|
||||
FLOAT: 'float';
|
||||
|
||||
INTEGER_LITERAL
|
||||
: [0-9]+
|
||||
;
|
||||
|
||||
FLOAT_LITERAL
|
||||
: INTEGER_LITERAL PERIOD INTEGER_LITERAL
|
||||
;
|
||||
|
||||
BOOLEAN_LITERAL
|
||||
: 'true'
|
||||
| 'false'
|
||||
|
||||
@@ -18,6 +18,13 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
||||
Map<String, FunctionInformation> funcs;
|
||||
Type currentDeclaredReturnType;
|
||||
|
||||
private void checkNumeric(Node lhs, Node rhs, int line, int col) {
|
||||
if (!lhs.type.isNumericType() || !rhs.type.isNumericType()) {
|
||||
String error = "Only numeric types are allowed for this expression.";
|
||||
throw new RuntimeException(Helper.getErrorPrefix(line, col) + error);
|
||||
}
|
||||
}
|
||||
|
||||
public ContextAnalysis(Map<String, FunctionInformation> funcs) {
|
||||
this.funcs = funcs;
|
||||
}
|
||||
@@ -256,6 +263,10 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
||||
result.type = Type.getBooleanType();
|
||||
result.line = ctx.start.getLine();
|
||||
result.col = ctx.start.getCharPositionInLine();
|
||||
if (!lhs.type.equals(Type.getBooleanType()) || !rhs.type.equals(Type.getBooleanType())) {
|
||||
String error = "|| is only defined for bool.";
|
||||
throw new RuntimeException(Helper.getErrorPrefix(result.line, result.col) + error);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -267,6 +278,10 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
||||
result.type = Type.getBooleanType();
|
||||
result.line = ctx.start.getLine();
|
||||
result.col = ctx.start.getCharPositionInLine();
|
||||
if (!lhs.type.equals(Type.getBooleanType()) || !rhs.type.equals(Type.getBooleanType())) {
|
||||
String error = "&& is only defined for bool.";
|
||||
throw new RuntimeException(Helper.getErrorPrefix(result.line, result.col) + error);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -277,11 +292,15 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
||||
int line = ctx.start.getLine();
|
||||
int col = ctx.start.getCharPositionInLine();
|
||||
AdditionExpression result = new AdditionExpression((Expression) lhs, (Expression) rhs);
|
||||
|
||||
try {
|
||||
result.type = lhs.type.combine(rhs.type);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(Helper.getErrorPrefix(line, col) + e.getMessage());
|
||||
}
|
||||
|
||||
checkNumeric(lhs, rhs, line, col);
|
||||
|
||||
result.line = ctx.start.getLine();
|
||||
result.col = ctx.start.getCharPositionInLine();
|
||||
return result;
|
||||
@@ -319,9 +338,10 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
||||
int line = ctx.start.getLine();
|
||||
int col = ctx.start.getCharPositionInLine();
|
||||
|
||||
if (lhs.type != Type.getIntegerType() || rhs.type != Type.getIntegerType()) {
|
||||
String error = "Both operants of this expression have to be a number.";
|
||||
throw new RuntimeException(Helper.getErrorPrefix(line, col) + error);
|
||||
try {
|
||||
lhs.type.combine(rhs.type);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(Helper.getErrorPrefix(line, col) + e.getMessage());
|
||||
}
|
||||
|
||||
NotEqualityExpression result = new NotEqualityExpression((Expression) lhs, (Expression) rhs);
|
||||
@@ -338,11 +358,14 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
||||
int line = ctx.start.getLine();
|
||||
int col = ctx.start.getCharPositionInLine();
|
||||
|
||||
if (lhs.type != Type.getIntegerType() || rhs.type != Type.getIntegerType()) {
|
||||
String error = "Both operants of this expression have to be a number.";
|
||||
throw new RuntimeException(Helper.getErrorPrefix(line, col) + error);
|
||||
try {
|
||||
lhs.type.combine(rhs.type);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(Helper.getErrorPrefix(line, col) + e.getMessage());
|
||||
}
|
||||
|
||||
checkNumeric(lhs, rhs, line, col);
|
||||
|
||||
LTExpression result = new LTExpression((Expression) lhs, (Expression) rhs);
|
||||
result.type = Type.getBooleanType();
|
||||
result.line = line;
|
||||
@@ -357,8 +380,14 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
||||
int line = ctx.start.getLine();
|
||||
int col = ctx.start.getCharPositionInLine();
|
||||
|
||||
if (lhs.type != Type.getIntegerType() || rhs.type != Type.getIntegerType()) {
|
||||
String error = "Both operants of this expression have to be a number.";
|
||||
try {
|
||||
lhs.type.combine(rhs.type);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(Helper.getErrorPrefix(line, col) + e.getMessage());
|
||||
}
|
||||
|
||||
if (!lhs.type.isNumericType() || !rhs.type.isNumericType()) {
|
||||
String error = "Only numeric types are allowed for this expression.";
|
||||
throw new RuntimeException(Helper.getErrorPrefix(line, col) + error);
|
||||
}
|
||||
|
||||
@@ -376,11 +405,14 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
||||
int line = ctx.start.getLine();
|
||||
int col = ctx.start.getCharPositionInLine();
|
||||
|
||||
if (lhs.type != Type.getIntegerType() || rhs.type != Type.getIntegerType()) {
|
||||
String error = "Both operants of this expression have to be a number.";
|
||||
throw new RuntimeException(Helper.getErrorPrefix(line, col) + error);
|
||||
try {
|
||||
lhs.type.combine(rhs.type);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(Helper.getErrorPrefix(line, col) + e.getMessage());
|
||||
}
|
||||
|
||||
checkNumeric(lhs, rhs, line, col);
|
||||
|
||||
LTEExpression result = new LTEExpression((Expression) lhs, (Expression) rhs);
|
||||
result.type = Type.getBooleanType();
|
||||
result.line = line;
|
||||
@@ -395,11 +427,14 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
||||
int line = ctx.start.getLine();
|
||||
int col = ctx.start.getCharPositionInLine();
|
||||
|
||||
if (lhs.type != Type.getIntegerType() || rhs.type != Type.getIntegerType()) {
|
||||
String error = "Both operants of this expression have to be a number.";
|
||||
throw new RuntimeException(Helper.getErrorPrefix(line, col) + error);
|
||||
try {
|
||||
lhs.type.combine(rhs.type);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(Helper.getErrorPrefix(line, col) + e.getMessage());
|
||||
}
|
||||
|
||||
checkNumeric(lhs, rhs, line, col);
|
||||
|
||||
GTEExpression result = new GTEExpression((Expression) lhs, (Expression) rhs);
|
||||
result.type = Type.getBooleanType();
|
||||
result.line = line;
|
||||
@@ -414,11 +449,15 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
||||
int line = ctx.start.getLine();
|
||||
int col = ctx.start.getCharPositionInLine();
|
||||
SubstractionExpression result = new SubstractionExpression((Expression) lhs, (Expression) rhs);
|
||||
|
||||
try {
|
||||
result.type = lhs.type.combine(rhs.type);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(Helper.getErrorPrefix(line, col) + e.getMessage());
|
||||
}
|
||||
|
||||
checkNumeric(lhs, rhs, line, col);
|
||||
|
||||
result.line = line;
|
||||
result.col = col;
|
||||
return result;
|
||||
@@ -431,11 +470,15 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
||||
int line = ctx.start.getLine();
|
||||
int col = ctx.start.getCharPositionInLine();
|
||||
MultiplicationExpression result = new MultiplicationExpression((Expression) lhs, (Expression) rhs);
|
||||
|
||||
try {
|
||||
result.type = lhs.type.combine(rhs.type);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(Helper.getErrorPrefix(line, col) + e.getMessage());
|
||||
}
|
||||
|
||||
checkNumeric(lhs, rhs, line, col);
|
||||
|
||||
result.line = line;
|
||||
result.col = col;
|
||||
return result;
|
||||
@@ -448,11 +491,15 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
||||
int line = ctx.start.getLine();
|
||||
int col = ctx.start.getCharPositionInLine();
|
||||
DivisionExpression result = new DivisionExpression((Expression) lhs, (Expression) rhs);
|
||||
|
||||
try {
|
||||
result.type = lhs.type.combine(rhs.type);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(Helper.getErrorPrefix(line, col) + e.getMessage());
|
||||
}
|
||||
|
||||
checkNumeric(lhs, rhs, line, col);
|
||||
|
||||
result.line = line;
|
||||
result.col = col;
|
||||
return result;
|
||||
@@ -465,11 +512,20 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
||||
int line = ctx.start.getLine();
|
||||
int col = ctx.start.getCharPositionInLine();
|
||||
ModuloExpression result = new ModuloExpression((Expression) lhs, (Expression) rhs);
|
||||
|
||||
try {
|
||||
result.type = lhs.type.combine(rhs.type);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(Helper.getErrorPrefix(line, col) + e.getMessage());
|
||||
}
|
||||
|
||||
checkNumeric(lhs, rhs, line, col);
|
||||
|
||||
if (lhs.type.equals(Type.getFloatType()) || rhs.type.equals(Type.getFloatType())) {
|
||||
String error = "Only integers are allowed for modulo.";
|
||||
throw new RuntimeException(Helper.getErrorPrefix(line, col) + error);
|
||||
}
|
||||
|
||||
result.line = line;
|
||||
result.col = col;
|
||||
return result;
|
||||
@@ -482,6 +538,12 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
||||
result.type = expression.type;
|
||||
result.line = ctx.start.getLine();
|
||||
result.col = ctx.start.getCharPositionInLine();
|
||||
|
||||
if (!result.type.isNumericType()) {
|
||||
String error = "Only numeric types are allowed for this expression.";
|
||||
throw new RuntimeException(Helper.getErrorPrefix(result.line, result.col) + error);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -492,6 +554,12 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
||||
result.type = expression.type;
|
||||
result.line = ctx.start.getLine();
|
||||
result.col = ctx.start.getCharPositionInLine();
|
||||
|
||||
if (!result.type.equals(Type.getBooleanType())) {
|
||||
String error = "Only boolean type is allowed for this expression.";
|
||||
throw new RuntimeException(Helper.getErrorPrefix(result.line, result.col) + error);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -534,6 +602,15 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
||||
return n;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node visitFloatAtom(KlangParser.FloatAtomContext ctx) {
|
||||
Node n = new FloatExpression(Double.parseDouble(ctx.getText()));
|
||||
n.type = Type.getFloatType();
|
||||
n.line = ctx.start.getLine();
|
||||
n.col = ctx.start.getCharPositionInLine();
|
||||
return n;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node visitBoolAtom(KlangParser.BoolAtomContext ctx) {
|
||||
Node n = new BooleanExpression(ctx.getText().equals("true") ? true : false);
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
package de.hsrm.compiler.Klang;
|
||||
|
||||
import de.hsrm.compiler.Klang.types.Type;
|
||||
|
||||
public class Value {
|
||||
public Type type;
|
||||
private Object value;
|
||||
|
||||
public Value(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public Value(Object value, Type type) {
|
||||
this.value = value;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Object asObject() {
|
||||
return this.value;
|
||||
}
|
||||
@@ -14,6 +22,10 @@ public class Value {
|
||||
public int asInteger() {
|
||||
return (int) this.value;
|
||||
}
|
||||
|
||||
public double asFloat() {
|
||||
return (double) this.value;
|
||||
}
|
||||
|
||||
public boolean asBoolean() {
|
||||
return (boolean) this.value;
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package de.hsrm.compiler.Klang.nodes.expressions;
|
||||
|
||||
import de.hsrm.compiler.Klang.visitors.Visitor;
|
||||
|
||||
public class FloatExpression extends Expression {
|
||||
public double value;
|
||||
|
||||
public FloatExpression(double value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R> R welcome(Visitor<R> v) {
|
||||
return v.visit(this);
|
||||
}
|
||||
}
|
||||
40
src/main/java/de/hsrm/compiler/Klang/types/FloatType.java
Normal file
40
src/main/java/de/hsrm/compiler/Klang/types/FloatType.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package de.hsrm.compiler.Klang.types;
|
||||
|
||||
public class FloatType extends NumericType {
|
||||
|
||||
private static FloatType instance = null;
|
||||
|
||||
public static FloatType getType() {
|
||||
if (instance != null) {
|
||||
return instance;
|
||||
}
|
||||
instance = new FloatType();
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFloatType() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "float";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Type combine(Type that) {
|
||||
// Combining two equal types always works
|
||||
if (that.equals(this)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (that.equals(Type.getIntegerType())) {
|
||||
return Type.getFloatType();
|
||||
}
|
||||
|
||||
// Every remaining type will throw a RuntimeException
|
||||
throw new RuntimeException("Type missmatch: cannot combine " + this.getName() + " and " + that.getName());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package de.hsrm.compiler.Klang.types;
|
||||
|
||||
public class IntegerType extends PrimitiveType {
|
||||
public class IntegerType extends NumericType {
|
||||
|
||||
private static IntegerType instance = null;
|
||||
|
||||
@@ -29,8 +29,9 @@ public class IntegerType extends PrimitiveType {
|
||||
return this;
|
||||
}
|
||||
|
||||
// Check other possible combinations
|
||||
// if (that.equals(Type.getFloatType())) return Type.getFloatType();
|
||||
if (that.equals(Type.getFloatType())) {
|
||||
return Type.getFloatType();
|
||||
}
|
||||
|
||||
// Every remaining type will throw a RuntimeException
|
||||
throw new RuntimeException("Type missmatch: cannot combine " + this.getName() + " and " + that.getName());
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package de.hsrm.compiler.Klang.types;
|
||||
|
||||
public abstract class NumericType extends PrimitiveType {
|
||||
@Override
|
||||
public boolean isNumericType() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -14,4 +14,12 @@ public abstract class PrimitiveType extends Type {
|
||||
public boolean isBooleanType() {
|
||||
return false;
|
||||
};
|
||||
|
||||
public boolean isFloatType() {
|
||||
return false;
|
||||
};
|
||||
|
||||
public boolean isNumericType() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -12,10 +12,15 @@ public abstract class Type {
|
||||
return BooleanType.getType();
|
||||
}
|
||||
|
||||
public static FloatType getFloatType() {
|
||||
return FloatType.getType();
|
||||
}
|
||||
|
||||
public static Type getByName(String name) {
|
||||
switch (name) {
|
||||
case "bool": return getBooleanType();
|
||||
case "int": return getIntegerType();
|
||||
case "float": return getFloatType();
|
||||
default: throw new RuntimeException("Unknown type " + name);
|
||||
}
|
||||
}
|
||||
@@ -23,4 +28,5 @@ public abstract class Type {
|
||||
public abstract String getName();
|
||||
public abstract Type combine(Type that);
|
||||
public abstract boolean isPrimitiveType();
|
||||
public abstract boolean isNumericType();
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import de.hsrm.compiler.Klang.nodes.loops.DoWhileLoop;
|
||||
import de.hsrm.compiler.Klang.nodes.loops.ForLoop;
|
||||
import de.hsrm.compiler.Klang.nodes.loops.WhileLoop;
|
||||
import de.hsrm.compiler.Klang.nodes.statements.*;
|
||||
import de.hsrm.compiler.Klang.types.Type;
|
||||
|
||||
public class EvalVisitor implements Visitor<Value> {
|
||||
|
||||
@@ -21,115 +22,309 @@ public class EvalVisitor implements Visitor<Value> {
|
||||
|
||||
@Override
|
||||
public Value visit(IntegerExpression e) {
|
||||
return new Value(e.value);
|
||||
Value result = new Value(e.value);
|
||||
result.type = Type.getIntegerType();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value visit(FloatExpression e) {
|
||||
Value result = new Value(e.value);
|
||||
result.type = Type.getFloatType();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value visit(BooleanExpression e) {
|
||||
return new Value(e.value);
|
||||
Value result = new Value(e.value);
|
||||
result.type = Type.getBooleanType();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value visit(EqualityExpression e) {
|
||||
Value lhs = e.lhs.welcome(this);
|
||||
Value rhs = e.rhs.welcome(this);
|
||||
return new Value(lhs.asObject() == rhs.asObject());
|
||||
Type resultType = Type.getBooleanType();
|
||||
Type combineType = lhs.type.combine(rhs.type);
|
||||
|
||||
switch(combineType.getName()) {
|
||||
case "bool": {
|
||||
return new Value(lhs.asBoolean() == rhs.asBoolean(), resultType);
|
||||
}
|
||||
case "int": {
|
||||
return new Value(lhs.asInteger() == rhs.asInteger(), resultType);
|
||||
}
|
||||
case "float": {
|
||||
return new Value(lhs.asFloat() == rhs.asFloat(), resultType);
|
||||
}
|
||||
default: {
|
||||
return new Value(lhs.asObject() == rhs.asObject(), resultType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value visit(NotEqualityExpression e) {
|
||||
Value lhs = e.lhs.welcome(this);
|
||||
Value rhs = e.rhs.welcome(this);
|
||||
return new Value(lhs.asObject() != rhs.asObject());
|
||||
Type resultType = Type.getBooleanType();
|
||||
Type combineType = lhs.type.combine(rhs.type);
|
||||
|
||||
switch(combineType.getName()) {
|
||||
case "bool": {
|
||||
return new Value(lhs.asBoolean() != rhs.asBoolean(), resultType);
|
||||
}
|
||||
case "int": {
|
||||
return new Value(lhs.asInteger() != rhs.asInteger(), resultType);
|
||||
}
|
||||
case "float": {
|
||||
return new Value(lhs.asFloat() != rhs.asFloat(), resultType);
|
||||
}
|
||||
default: {
|
||||
return new Value(lhs.asObject() != rhs.asObject(), resultType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value visit(GTExpression e) {
|
||||
Value lhs = e.lhs.welcome(this);
|
||||
Value rhs = e.rhs.welcome(this);
|
||||
return new Value(lhs.asInteger() > rhs.asInteger());
|
||||
Type resultType = Type.getBooleanType();
|
||||
Type combineType = lhs.type.combine(rhs.type);
|
||||
|
||||
switch(combineType.getName()) {
|
||||
case "int": {
|
||||
return new Value(lhs.asInteger() > rhs.asInteger(), resultType);
|
||||
}
|
||||
case "float": {
|
||||
return new Value(lhs.asFloat() > rhs.asFloat(), resultType);
|
||||
}
|
||||
default: {
|
||||
throw new RuntimeException("Unknown Type encountered");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value visit(GTEExpression e) {
|
||||
Value lhs = e.lhs.welcome(this);
|
||||
Value rhs = e.rhs.welcome(this);
|
||||
return new Value(lhs.asInteger() >= rhs.asInteger());
|
||||
Type resultType = Type.getBooleanType();
|
||||
Type combineType = lhs.type.combine(rhs.type);
|
||||
|
||||
switch(combineType.getName()) {
|
||||
case "int": {
|
||||
return new Value(lhs.asInteger() >= rhs.asInteger(), resultType);
|
||||
}
|
||||
case "float": {
|
||||
return new Value(lhs.asFloat() >= rhs.asFloat(), resultType);
|
||||
}
|
||||
default: {
|
||||
throw new RuntimeException("Unknown Type encountered");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value visit(LTExpression e) {
|
||||
Value lhs = e.lhs.welcome(this);
|
||||
Value rhs = e.rhs.welcome(this);
|
||||
return new Value(lhs.asInteger() < rhs.asInteger());
|
||||
Type resultType = Type.getBooleanType();
|
||||
Type combineType = lhs.type.combine(rhs.type);
|
||||
|
||||
switch(combineType.getName()) {
|
||||
case "int": {
|
||||
return new Value(lhs.asInteger() < rhs.asInteger(), resultType);
|
||||
}
|
||||
case "float": {
|
||||
return new Value(lhs.asFloat() < rhs.asFloat(), resultType);
|
||||
}
|
||||
default: {
|
||||
throw new RuntimeException("Unknown Type encountered");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value visit(LTEExpression e) {
|
||||
Value lhs = e.lhs.welcome(this);
|
||||
Value rhs = e.rhs.welcome(this);
|
||||
return new Value(lhs.asInteger() <= rhs.asInteger());
|
||||
Type combineType = lhs.type.combine(rhs.type);
|
||||
Type resultType = Type.getBooleanType();
|
||||
|
||||
switch(combineType.getName()) {
|
||||
case "int": {
|
||||
return new Value(lhs.asInteger() <= rhs.asInteger(), resultType);
|
||||
}
|
||||
case "float": {
|
||||
return new Value(lhs.asFloat() <= rhs.asFloat(), resultType);
|
||||
}
|
||||
default: {
|
||||
throw new RuntimeException("Unknown Type encountered");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value visit(AdditionExpression e) {
|
||||
Value lhs = e.lhs.welcome(this);
|
||||
Value rhs = e.rhs.welcome(this);
|
||||
return new Value(lhs.asInteger() + rhs.asInteger());
|
||||
Type resultType = lhs.type.combine(rhs.type);
|
||||
|
||||
switch(resultType.getName()) {
|
||||
case "int": {
|
||||
return new Value(lhs.asInteger() + rhs.asInteger(), resultType);
|
||||
}
|
||||
case "float": {
|
||||
return new Value(lhs.asFloat() + rhs.asFloat(), resultType);
|
||||
}
|
||||
default: {
|
||||
throw new RuntimeException("Unknown Type encountered");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value visit(SubstractionExpression e) {
|
||||
Value lhs = e.lhs.welcome(this);
|
||||
Value rhs = e.rhs.welcome(this);
|
||||
return new Value(lhs.asInteger() - rhs.asInteger());
|
||||
Type resultType = lhs.type.combine(rhs.type);
|
||||
|
||||
switch(resultType.getName()) {
|
||||
case "int": {
|
||||
return new Value(lhs.asInteger() - rhs.asInteger(), resultType);
|
||||
}
|
||||
case "float": {
|
||||
return new Value(lhs.asFloat() - rhs.asFloat(), resultType);
|
||||
}
|
||||
default: {
|
||||
throw new RuntimeException("Unknown Type encountered");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value visit(MultiplicationExpression e) {
|
||||
Value lhs = e.lhs.welcome(this);
|
||||
Value rhs = e.rhs.welcome(this);
|
||||
return new Value(lhs.asInteger() * rhs.asInteger());
|
||||
Type resultType = lhs.type.combine(rhs.type);
|
||||
|
||||
switch(resultType.getName()) {
|
||||
case "int": {
|
||||
return new Value(lhs.asInteger() * rhs.asInteger(), resultType);
|
||||
}
|
||||
case "float": {
|
||||
return new Value(lhs.asFloat() * rhs.asFloat(), resultType);
|
||||
}
|
||||
default: {
|
||||
throw new RuntimeException("Unknown Type encountered");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value visit(DivisionExpression e) {
|
||||
Value lhs = e.lhs.welcome(this);
|
||||
Value rhs = e.rhs.welcome(this);
|
||||
return new Value(lhs.asInteger() / rhs.asInteger());
|
||||
Type resultType = lhs.type.combine(rhs.type);
|
||||
|
||||
switch(resultType.getName()) {
|
||||
case "int": {
|
||||
return new Value(lhs.asInteger() / rhs.asInteger(), resultType);
|
||||
}
|
||||
case "float": {
|
||||
return new Value(lhs.asFloat() / rhs.asFloat(), resultType);
|
||||
}
|
||||
default: {
|
||||
throw new RuntimeException("Unknown Type encountered");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value visit(ModuloExpression e) {
|
||||
Value lhs = e.lhs.welcome(this);
|
||||
Value rhs = e.rhs.welcome(this);
|
||||
return new Value(lhs.asInteger() % rhs.asInteger());
|
||||
Type resultType = lhs.type.combine(rhs.type);
|
||||
|
||||
switch(resultType.getName()) {
|
||||
case "int": {
|
||||
return new Value(lhs.asInteger() % rhs.asInteger(), resultType);
|
||||
}
|
||||
case "float": {
|
||||
return new Value(lhs.asFloat() % rhs.asFloat(), resultType);
|
||||
}
|
||||
default: {
|
||||
throw new RuntimeException("Unknown Type encountered");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value visit(NegateExpression e) {
|
||||
Value a = e.lhs.welcome(this);
|
||||
return new Value(-a.asInteger());
|
||||
Type resultType = a.type;
|
||||
|
||||
switch(resultType.getName()) {
|
||||
case "int": {
|
||||
return new Value(-a.asInteger(), resultType);
|
||||
}
|
||||
case "float": {
|
||||
return new Value(-a.asFloat(), resultType);
|
||||
}
|
||||
default: {
|
||||
throw new RuntimeException("Unknown Type encountered");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value visit(OrExpression e) {
|
||||
Value lhs = e.lhs.welcome(this);
|
||||
Value rhs = e.rhs.welcome(this);
|
||||
return new Value(lhs.asBoolean() || rhs.asBoolean());
|
||||
Type resultType = lhs.type.combine(rhs.type);
|
||||
|
||||
switch(resultType.getName()) {
|
||||
case "bool": {
|
||||
return new Value(lhs.asBoolean() || rhs.asBoolean(), resultType);
|
||||
}
|
||||
default: {
|
||||
throw new RuntimeException("Unknown Type encountered");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value visit(AndExpression e) {
|
||||
Value lhs = e.lhs.welcome(this);
|
||||
Value rhs = e.rhs.welcome(this);
|
||||
return new Value(lhs.asBoolean() && rhs.asBoolean());
|
||||
Type resultType = lhs.type.combine(rhs.type);
|
||||
|
||||
switch(resultType.getName()) {
|
||||
case "bool": {
|
||||
return new Value(lhs.asBoolean() && rhs.asBoolean(), resultType);
|
||||
}
|
||||
default: {
|
||||
throw new RuntimeException("Unknown Type encountered");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value visit(NotExpression e) {
|
||||
Value lhs = e.lhs.welcome(this);
|
||||
return new Value(!lhs.asBoolean());
|
||||
Type resultType = lhs.type;
|
||||
|
||||
switch(resultType.getName()) {
|
||||
case "bool": {
|
||||
return new Value(!lhs.asBoolean(), resultType);
|
||||
}
|
||||
default: {
|
||||
throw new RuntimeException("Unknown Type encountered");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -12,6 +12,7 @@ import de.hsrm.compiler.Klang.nodes.loops.DoWhileLoop;
|
||||
import de.hsrm.compiler.Klang.nodes.loops.ForLoop;
|
||||
import de.hsrm.compiler.Klang.nodes.loops.WhileLoop;
|
||||
import de.hsrm.compiler.Klang.nodes.statements.*;
|
||||
import de.hsrm.compiler.Klang.types.Type;
|
||||
|
||||
public class GenASM implements Visitor<Void> {
|
||||
|
||||
@@ -55,13 +56,83 @@ public class GenASM implements Visitor<Void> {
|
||||
}
|
||||
}
|
||||
|
||||
private class FloatWriter {
|
||||
private StringBuilder sb = new StringBuilder();
|
||||
private int id = -1;
|
||||
|
||||
public String getFloat(double d) {
|
||||
String binary = Long.toBinaryString(Double.doubleToLongBits(d));
|
||||
String upper = binary.substring(0, 30);
|
||||
String lower = binary.substring(31, 61);
|
||||
long first = Long.parseLong(lower, 2);
|
||||
long second = Long.parseLong(upper, 2);
|
||||
String lbl = ".FL" + ++id;
|
||||
sb.append(lbl);
|
||||
sb.append(":\n");
|
||||
sb.append("\t.long ");
|
||||
sb.append(first);
|
||||
sb.append("\n");
|
||||
sb.append("\t.long ");
|
||||
sb.append(second);
|
||||
sb.append("\n");
|
||||
return lbl;
|
||||
}
|
||||
|
||||
public String getNegateFloat() {
|
||||
String lbl = ".FL" + ++id;
|
||||
sb.append(lbl);
|
||||
sb.append(":\n");
|
||||
sb.append("\t.long ");
|
||||
sb.append("0");
|
||||
sb.append("\n");
|
||||
sb.append("\t.long ");
|
||||
sb.append("-2147483648");
|
||||
sb.append("\n");
|
||||
return lbl;
|
||||
}
|
||||
|
||||
public String getFloatSection() {
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public ExWriter ex;
|
||||
private FloatWriter fw = new FloatWriter();
|
||||
private String mainName;
|
||||
Map<String, Integer> env = new HashMap<>();
|
||||
Set<String> vars;
|
||||
String[] rs = { "%rdi", "%rsi", "%rdx", "%rcx", "%r8", "%r9" };
|
||||
String[] frs = {"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"};
|
||||
private int lCount = 0; // Invariante: lCount ist benutzt
|
||||
|
||||
private void intToFloat(String src, String dst) {
|
||||
this.ex.write(" cvtsi2sd " + src +", " + dst + "\n");
|
||||
}
|
||||
|
||||
private boolean prepareRegisters(Expression lhs, Expression rhs) {
|
||||
boolean lhsIsFloat = lhs.type.equals(Type.getFloatType());
|
||||
boolean rhsIsFloat = rhs.type.equals(Type.getFloatType());
|
||||
if (lhsIsFloat || rhsIsFloat) {
|
||||
lhs.welcome(this);
|
||||
if (!lhsIsFloat) {
|
||||
this.intToFloat("%rax", "%xmm1");
|
||||
} else {
|
||||
this.ex.write(" movsd %xmm0, %xmm1\n");
|
||||
}
|
||||
rhs.welcome(this);
|
||||
if (!rhsIsFloat) {
|
||||
this.intToFloat("%rax", "%xmm1");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
lhs.welcome(this);
|
||||
this.ex.write(" pushq %rax\n");
|
||||
rhs.welcome(this);
|
||||
this.ex.write(" popq %rbx\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public GenASM(ExWriter ex, String mainName) {
|
||||
this.ex = ex;
|
||||
this.mainName = mainName;
|
||||
@@ -78,6 +149,13 @@ public class GenASM implements Visitor<Void> {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(FloatExpression e) {
|
||||
String floatLabel = fw.getFloat(e.value);
|
||||
this.ex.write(" movsd " + floatLabel + "(%rip), %xmm0\n");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(BooleanExpression e) {
|
||||
this.ex.write(" movq $" + (e.value ? 1 : 0) + ", %rax\n");
|
||||
@@ -86,7 +164,11 @@ public class GenASM implements Visitor<Void> {
|
||||
|
||||
@Override
|
||||
public Void visit(Variable e) {
|
||||
this.ex.write(" movq " + this.env.get(e.name) + "(%rbp), %rax\n");
|
||||
if (e.type.equals(Type.getFloatType())) {
|
||||
this.ex.write(" movsd " + this.env.get(e.name) + "(%rbp), %xmm0\n");
|
||||
} else {
|
||||
this.ex.write(" movq " + this.env.get(e.name) + "(%rbp), %rax\n");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -95,19 +177,20 @@ public class GenASM implements Visitor<Void> {
|
||||
int lblTrue = ++lCount;
|
||||
int lblEnd = ++lCount;
|
||||
|
||||
e.lhs.welcome(this);
|
||||
this.ex.write(" pushq %rax\n");
|
||||
e.rhs.welcome(this);
|
||||
this.ex.write(" popq %rbx\n");
|
||||
this.ex.write(" cmp %rax, %rbx\n");
|
||||
this.ex.write(" je .L" + lblTrue + "\n");
|
||||
// false
|
||||
this.ex.write(" movq $0, %rax\n");
|
||||
this.ex.write(" jmp .L" + lblEnd + "\n");
|
||||
this.ex.write(".L" + lblTrue + ":\n");
|
||||
// true
|
||||
this.ex.write(" movq $1, %rax\n");
|
||||
this.ex.write(".L" + lblEnd + ":\n");
|
||||
boolean isFloatOperation = this.prepareRegisters(e.lhs, e.rhs);
|
||||
if (isFloatOperation) {
|
||||
this.ex.write(" ucomisd %xmm0, %xmm1\n");
|
||||
} else {
|
||||
this.ex.write(" cmp %rax, %rbx\n");
|
||||
}
|
||||
this.ex.write(" je .L" + lblTrue + "\n");
|
||||
// false
|
||||
this.ex.write(" movq $0, %rax\n");
|
||||
this.ex.write(" jmp .L" + lblEnd + "\n");
|
||||
this.ex.write(".L" + lblTrue + ":\n");
|
||||
// true
|
||||
this.ex.write(" movq $1, %rax\n");
|
||||
this.ex.write(".L" + lblEnd + ":\n");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -116,11 +199,12 @@ public class GenASM implements Visitor<Void> {
|
||||
int lblTrue = ++lCount;
|
||||
int lblEnd = ++lCount;
|
||||
|
||||
e.lhs.welcome(this);
|
||||
this.ex.write(" pushq %rax\n");
|
||||
e.rhs.welcome(this);
|
||||
this.ex.write(" popq %rbx\n");
|
||||
this.ex.write(" cmp %rax, %rbx\n");
|
||||
boolean isFloatOperation = this.prepareRegisters(e.lhs, e.rhs);
|
||||
if (isFloatOperation) {
|
||||
this.ex.write(" ucomisd %xmm0, %xmm1\n");
|
||||
} else {
|
||||
this.ex.write(" cmp %rax, %rbx\n");
|
||||
}
|
||||
this.ex.write(" jne .L" + lblTrue + "\n");
|
||||
// false
|
||||
this.ex.write(" movq $0, %rax\n");
|
||||
@@ -137,11 +221,12 @@ public class GenASM implements Visitor<Void> {
|
||||
int lblTrue = ++lCount;
|
||||
int lblEnd = ++lCount;
|
||||
|
||||
e.lhs.welcome(this);
|
||||
this.ex.write(" pushq %rax\n");
|
||||
e.rhs.welcome(this);
|
||||
this.ex.write(" popq %rbx\n");
|
||||
this.ex.write(" cmp %rax, %rbx\n");
|
||||
boolean isFloatOperation = this.prepareRegisters(e.lhs, e.rhs);
|
||||
if (isFloatOperation) {
|
||||
this.ex.write(" ucomisd %xmm0, %xmm1\n");
|
||||
} else {
|
||||
this.ex.write(" cmp %rax, %rbx\n");
|
||||
}
|
||||
this.ex.write(" jg .L" + lblTrue + "\n");
|
||||
// false
|
||||
this.ex.write(" movq $0, %rax\n");
|
||||
@@ -158,11 +243,13 @@ public class GenASM implements Visitor<Void> {
|
||||
int lblTrue = ++lCount;
|
||||
int lblEnd = ++lCount;
|
||||
|
||||
e.lhs.welcome(this);
|
||||
this.ex.write(" pushq %rax\n");
|
||||
e.rhs.welcome(this);
|
||||
this.ex.write(" popq %rbx\n");
|
||||
this.ex.write(" cmp %rax, %rbx\n");
|
||||
|
||||
boolean isFloatOperation = this.prepareRegisters(e.lhs, e.rhs);
|
||||
if (isFloatOperation) {
|
||||
this.ex.write(" ucomisd %xmm0, %xmm1\n");
|
||||
} else {
|
||||
this.ex.write(" cmp %rax, %rbx\n");
|
||||
}
|
||||
this.ex.write(" jge .L" + lblTrue + "\n");
|
||||
// false
|
||||
this.ex.write(" movq $0, %rax\n");
|
||||
@@ -179,11 +266,12 @@ public class GenASM implements Visitor<Void> {
|
||||
int lblTrue = ++lCount;
|
||||
int lblEnd = ++lCount;
|
||||
|
||||
e.lhs.welcome(this);
|
||||
this.ex.write(" pushq %rax\n");
|
||||
e.rhs.welcome(this);
|
||||
this.ex.write(" popq %rbx\n");
|
||||
this.ex.write(" cmp %rax, %rbx\n");
|
||||
boolean isFloatOperation = this.prepareRegisters(e.lhs, e.rhs);
|
||||
if (isFloatOperation) {
|
||||
this.ex.write(" ucomisd %xmm0, %xmm1\n");
|
||||
} else {
|
||||
this.ex.write(" cmp %rax, %rbx\n");
|
||||
}
|
||||
this.ex.write(" jl .L" + lblTrue + "\n");
|
||||
// false
|
||||
this.ex.write(" movq $0, %rax\n");
|
||||
@@ -200,11 +288,12 @@ public class GenASM implements Visitor<Void> {
|
||||
int lblTrue = ++lCount;
|
||||
int lblEnd = ++lCount;
|
||||
|
||||
e.lhs.welcome(this);
|
||||
this.ex.write(" pushq %rax\n");
|
||||
e.rhs.welcome(this);
|
||||
this.ex.write(" popq %rbx\n");
|
||||
this.ex.write(" cmp %rax, %rbx\n");
|
||||
boolean isFloatOperation = this.prepareRegisters(e.lhs, e.rhs);
|
||||
if (isFloatOperation) {
|
||||
this.ex.write(" ucomisd %xmm0, %xmm1\n");
|
||||
} else {
|
||||
this.ex.write(" cmp %rax, %rbx\n");
|
||||
}
|
||||
this.ex.write(" jle .L" + lblTrue + "\n");
|
||||
// false
|
||||
this.ex.write(" movq $0, %rax\n");
|
||||
@@ -218,43 +307,47 @@ public class GenASM implements Visitor<Void> {
|
||||
|
||||
@Override
|
||||
public Void visit(AdditionExpression e) {
|
||||
e.lhs.welcome(this);
|
||||
this.ex.write(" pushq %rax\n");
|
||||
e.rhs.welcome(this);
|
||||
this.ex.write(" popq %rbx\n");
|
||||
this.ex.write(" addq %rbx, %rax\n");
|
||||
boolean isFloatOperation = this.prepareRegisters(e.lhs, e.rhs);
|
||||
if (isFloatOperation) {
|
||||
this.ex.write(" addsd %xmm1, %xmm0\n");
|
||||
} else {
|
||||
this.ex.write(" addq %rbx, %rax\n");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(SubstractionExpression e) {
|
||||
e.rhs.welcome(this);
|
||||
this.ex.write(" pushq %rax\n");
|
||||
e.lhs.welcome(this);
|
||||
this.ex.write(" popq %rbx\n");
|
||||
this.ex.write(" subq %rbx, %rax\n");
|
||||
boolean isFloatOperation = this.prepareRegisters(e.lhs, e.rhs);
|
||||
if (isFloatOperation) {
|
||||
this.ex.write(" subsd %xmm1, %xmm0\n");
|
||||
} else {
|
||||
this.ex.write(" subq %rax, %rbx\n");
|
||||
this.ex.write(" movq %rbx, %rax\n");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(MultiplicationExpression e) {
|
||||
e.lhs.welcome(this);
|
||||
this.ex.write(" pushq %rax\n");
|
||||
e.rhs.welcome(this);
|
||||
this.ex.write(" popq %rbx\n");
|
||||
this.ex.write(" imulq %rbx, %rax\n");
|
||||
boolean isFloatOperation = this.prepareRegisters(e.lhs, e.rhs);
|
||||
if (isFloatOperation) {
|
||||
this.ex.write(" mulsd %xmm1, %xmm0\n");
|
||||
} else {
|
||||
this.ex.write(" imulq %rbx, %rax\n");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(DivisionExpression e) {
|
||||
e.lhs.welcome(this);
|
||||
this.ex.write(" pushq %rax\n");
|
||||
e.rhs.welcome(this);
|
||||
this.ex.write(" movq %rax, %rbx\n");
|
||||
this.ex.write(" popq %rax\n");
|
||||
this.ex.write(" xor %rdx, %rdx\n"); // clear upper part of division
|
||||
this.ex.write(" idiv %rbx\n"); // %rax/%rbx, quotient now in %rax
|
||||
boolean isFloatOperation = this.prepareRegisters(e.lhs, e.rhs);
|
||||
if (isFloatOperation) {
|
||||
this.ex.write(" divsd %xmm1, %xmm0\n");
|
||||
} else {
|
||||
this.ex.write(" xor %rdx, %rdx\n"); // clear upper part of division
|
||||
this.ex.write(" idiv %rbx\n"); // %rax/%rbx, quotient now in %rax
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -274,7 +367,13 @@ public class GenASM implements Visitor<Void> {
|
||||
@Override
|
||||
public Void visit(NegateExpression e) {
|
||||
e.lhs.welcome(this);
|
||||
this.ex.write(" neg %rax\n");
|
||||
if (e.lhs.type.equals(Type.getFloatType())) {
|
||||
String floatLabel = fw.getNegateFloat();
|
||||
this.ex.write(" movsd " + floatLabel + "(%rip), %xmm1\n");
|
||||
this.ex.write(" xorpd %xmm1, %xmm0\n");
|
||||
} else {
|
||||
this.ex.write(" neg %rax\n");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -497,7 +596,8 @@ public class GenASM implements Visitor<Void> {
|
||||
|
||||
// hole die anzahl der lokalen variablen
|
||||
this.vars = new TreeSet<String>();
|
||||
GetVars getvars = new GetVars(vars);
|
||||
HashMap<String, Type> types = new HashMap<String, Type>();
|
||||
GetVars getvars = new GetVars(vars, types);
|
||||
getvars.visit(e);
|
||||
|
||||
// Erzeuge ein environment
|
||||
@@ -532,6 +632,74 @@ public class GenASM implements Visitor<Void> {
|
||||
|
||||
@Override
|
||||
public Void visit(FunctionCall e) {
|
||||
/*
|
||||
Idee:
|
||||
Über arguments iterieren, sich für jedes Argument merken an welche Position es kommt
|
||||
Über e.arguments iterieren, jedes welcomen, ergebnis auf den stack pushen
|
||||
Vom stack in die jeweiligen register / den richtigen Platz auf den Stack pushen
|
||||
*/
|
||||
// // An xmmIdxy[i] steht ein index, der in e.arguments zeigt
|
||||
// // this.frs[i] = register | xmmIdxs[i] = index in arguments das in dieses register gehört
|
||||
// int[] xmmIdxs = new int[this.frs.length];
|
||||
// int fi = 0;
|
||||
// // Selbe Idee wie bei xmmIdxs
|
||||
// int[] rIdxs = new int[this.rs.length];
|
||||
// int ri = 0;
|
||||
//// Selbe Idee wie bei xmmIdxs
|
||||
// ArrayList<Integer> stackIdxs = new ArrayList<Integer>();
|
||||
//
|
||||
// // Go through arguments
|
||||
// // sort them into the memory regions they go when being passed to function later on
|
||||
// for (int i = 0; i < e.arguments.length; i++) {
|
||||
// var arg = e.arguments[i];
|
||||
// if (arg.type.equals(Type.getFloatType())) {
|
||||
// if (fi >= this.frs.length) {
|
||||
// // Float onto stack
|
||||
// stackIdxs.add(i);
|
||||
// } else {
|
||||
// // Float into float reg
|
||||
// xmmIdxs[fi] = i;
|
||||
// fi += 1;
|
||||
// }
|
||||
// } else {
|
||||
// if (ri >= this.rs.length) {
|
||||
// // bool/int onto stack
|
||||
// stackIdxs.add(i);
|
||||
// } else {
|
||||
// // bool/int into reg
|
||||
// rIdxs[ri] = i;
|
||||
// ri += 1;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Welcome the arguments in order
|
||||
// for (var arg : e.arguments) {
|
||||
// arg.welcome(this);
|
||||
// if (arg.type.equals(Type.getFloatType())) {
|
||||
// this.ex.write(" movq %xmm0, %rax\n");
|
||||
// this.ex.write(" pushq %rax\n");
|
||||
// } else {
|
||||
// this.ex.write(" pushq %rax\n");
|
||||
// }
|
||||
// }
|
||||
// // Move floats from stack to xmm registers
|
||||
// TODO: Check if indexInArguments is valid
|
||||
// for (int i = 0; i < xmmIdxs.length ; i++) {
|
||||
// int indexInArguments = xmmIdxs[i];
|
||||
// int rspOffset = (((e.arguments.length - indexInArguments) - 1) * 8) * -1;
|
||||
// this.ex.write(" movsd " + rspOffset + "(%rsp), " + this.frs[i] + "\n");
|
||||
// }
|
||||
|
||||
// // Move primitives from stack to all purpose registers
|
||||
// TODO: Check if indexInArguments is valid
|
||||
// for (int i = 0; i < rIdxs.length ; i++) {
|
||||
// int indexInArguments = rIdxs[i];
|
||||
// int rspOffset = (((e.arguments.length - indexInArguments) - 1) * 8) * -1;
|
||||
// this.ex.write(" movq " + rspOffset + "(%rsp), " + this.rs[i] + "\n");
|
||||
// }
|
||||
// int stackStart = (e.arguments.length - 1) * 8 * -1;
|
||||
|
||||
// Die ersten sechs params in die register schieben
|
||||
for (int i = 0; i < Math.min(this.rs.length, e.arguments.length); i++) {
|
||||
e.arguments[i].welcome(this);
|
||||
@@ -565,6 +733,10 @@ public class GenASM implements Visitor<Void> {
|
||||
this.ex.write(" movq %rbp, %rsp\n");
|
||||
this.ex.write(" popq %rbp\n");
|
||||
this.ex.write(" ret\n");
|
||||
|
||||
// PRINT FLOATS HERE
|
||||
this.ex.write("\n");
|
||||
this.ex.write(fw.getFloatSection());
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package de.hsrm.compiler.Klang.visitors;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import de.hsrm.compiler.Klang.nodes.*;
|
||||
@@ -8,13 +9,16 @@ import de.hsrm.compiler.Klang.nodes.loops.DoWhileLoop;
|
||||
import de.hsrm.compiler.Klang.nodes.loops.ForLoop;
|
||||
import de.hsrm.compiler.Klang.nodes.loops.WhileLoop;
|
||||
import de.hsrm.compiler.Klang.nodes.statements.*;
|
||||
import de.hsrm.compiler.Klang.types.Type;
|
||||
|
||||
class GetVars implements Visitor<Void> {
|
||||
|
||||
public Set<String> vars;
|
||||
public Map<String, Type> types;
|
||||
|
||||
public GetVars(Set<String> vars) {
|
||||
public GetVars(Set<String> vars, Map<String, Type> types) {
|
||||
this.vars = vars;
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -22,6 +26,11 @@ class GetVars implements Visitor<Void> {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(FloatExpression e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(BooleanExpression e) {
|
||||
return null;
|
||||
@@ -179,6 +188,7 @@ class GetVars implements Visitor<Void> {
|
||||
@Override
|
||||
public Void visit(VariableDeclaration e) {
|
||||
vars.add(e.name);
|
||||
types.put(e.name, e.type);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,12 @@ public class PrettyPrintVisitor implements Visitor<Void> {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(FloatExpression e) {
|
||||
ex.write(e.value);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(BooleanExpression e) {
|
||||
ex.write(e.value);
|
||||
|
||||
@@ -13,6 +13,7 @@ public interface Visitor<R> {
|
||||
R visit(AndExpression e);
|
||||
R visit (NotExpression e);
|
||||
R visit(IntegerExpression e);
|
||||
R visit(FloatExpression e);
|
||||
R visit(BooleanExpression e);
|
||||
R visit(Variable e);
|
||||
R visit(AdditionExpression e);
|
||||
|
||||
Reference in New Issue
Block a user