Added function call and function definition

This commit is contained in:
Marvin Kaiser
2019-11-18 16:39:12 +01:00
parent 9385618252
commit 13caee0667
8 changed files with 242 additions and 76 deletions

View File

@@ -2,76 +2,89 @@ package de.hsrm.compiler.Klang.visitors;
import de.hsrm.compiler.Klang.Value;
import de.hsrm.compiler.Klang.nodes.Block;
import de.hsrm.compiler.Klang.nodes.FunctionDefinition;
import de.hsrm.compiler.Klang.nodes.expressions.*;
import de.hsrm.compiler.Klang.nodes.statements.*;
public class EvalVisitor implements Visitor<Value> {
@Override
public Value visit(IntegerExpression e) {
return new Value(e.value);
@Override
public Value visit(IntegerExpression e) {
return new Value(e.value);
}
@Override
public Value visit(MultiplicativeExpression e) {
Value a = e.lhs.welcome(this);
Value b = e.rhs.welcome(this);
return new Value(a.asInteger() * b.asInteger());
}
@Override
public Value visit(AdditiveExpression e) {
Value a = e.lhs.welcome(this);
Value b = e.rhs.welcome(this);
return new Value(a.asInteger() + b.asInteger());
}
@Override
public Value visit(ModuloExpression e) {
Value a = e.lhs.welcome(this);
Value b = e.rhs.welcome(this);
return new Value(a.asInteger() % b.asInteger());
}
@Override
public Value visit(NegateExpression e) {
Value a = e.lhs.welcome(this);
return new Value(-a.asInteger());
}
@Override
public Value visit(IfStatement e) {
// In the future we have to make sure that the
// value is actually a type that we can use as boolean
Value condition = e.cond.welcome(this);
if (condition.asInteger() != 0) {
e.then.welcome(this);
} else if (e.alt != null) {
e.alt.welcome(this);
} else if (e.elif != null) {
e.elif.welcome(this);
}
@Override
public Value visit(MultiplicativeExpression e) {
Value a = e.lhs.welcome(this);
Value b = e.rhs.welcome(this);
return new Value(a.asInteger() * b.asInteger());
return null;
}
@Override
public Value visit(PrintStatement e) {
Value value = e.expression.welcome(this);
// In the future we have to determine of which type the value is
// before calling an "asX()" method
System.out.println(value.asInteger());
return null;
}
@Override
public Value visit(Block e) {
for (var stmt : e.statements) {
stmt.welcome(this);
}
return null;
}
@Override
public Value visit(AdditiveExpression e) {
Value a = e.lhs.welcome(this);
Value b = e.rhs.welcome(this);
return new Value(a.asInteger() + b.asInteger());
}
@Override
public Value visit(FunctionDefinition e) {
// TODO Auto-generated method stub
return null;
}
@Override
public Value visit(ModuloExpression e) {
Value a = e.lhs.welcome(this);
Value b = e.rhs.welcome(this);
return new Value(a.asInteger() % b.asInteger());
}
@Override
public Value visit(NegateExpression e) {
Value a = e.lhs.welcome(this);
return new Value(-a.asInteger());
}
@Override
public Value visit(IfStatement e) {
// In the future we have to make sure that the
// value is actually a type that we can use as boolean
Value condition = e.cond.welcome(this);
if (condition.asInteger() != 0) {
e.then.welcome(this);
} else if (e.alt != null) {
e.alt.welcome(this);
} else if (e.elif != null) {
e.elif.welcome(this);
}
return null;
}
@Override
public Value visit(PrintStatement e) {
Value value = e.expression.welcome(this);
// In the future we have to determine of which type the value is
// before calling an "asX()" method
System.out.println(value.asInteger());
return null;
}
@Override
public Value visit(Block e) {
for (var stmt: e.statements) {
stmt.welcome(this);
}
return null;
}
@Override
public Value visit(FunctionCall e) {
// TODO Auto-generated method stub
return null;
}
}

View File

@@ -53,6 +53,17 @@ public class PrettyPrintVisitor implements Visitor<Void> {
this.ex = ex;
}
@Override
public Void visit(Program e) {
for (var funcDef : e.funcs) {
funcDef.welcome(this);
ex.nl();
ex.nl();
}
e.expression.welcome(this);
return null;
}
@Override
public Void visit(IntegerExpression e) {
ex.write(e.value);
@@ -128,4 +139,40 @@ public class PrettyPrintVisitor implements Visitor<Void> {
return null;
}
@Override
public Void visit(FunctionDefinition e) {
ex.write("function ");
ex.write(e.name);
ex.write(" (");
boolean first = true;
for (String param : e.parameters) {
if (!first) {
ex.write(", ");
} else {
first = false;
}
ex.write(param);
}
ex.write(") ");
e.block.welcome(this);
return null;
}
@Override
public Void visit(FunctionCall e) {
ex.write(e.name);
ex.write("(");
boolean first = true;
for (Expression arg : e.arguments) {
if (!first) {
ex.write(", ");
} else {
first = false;
}
arg.welcome(this);
}
ex.write(");");
return null;
}
}

View File

@@ -1,6 +1,8 @@
package de.hsrm.compiler.Klang.visitors;
import de.hsrm.compiler.Klang.nodes.Block;
import de.hsrm.compiler.Klang.nodes.FunctionDefinition;
import de.hsrm.compiler.Klang.nodes.Program;
import de.hsrm.compiler.Klang.nodes.expressions.*;
import de.hsrm.compiler.Klang.nodes.statements.*;
@@ -13,4 +15,7 @@ public interface Visitor<R> {
R visit(IfStatement e);
R visit(PrintStatement e);
R visit(Block e);
R visit(FunctionDefinition e);
R visit(FunctionCall e);
R visit(Program e);
}