implemented variables and function call evaluation
This commit is contained in:
@@ -52,6 +52,7 @@ arguments
|
|||||||
|
|
||||||
atom
|
atom
|
||||||
: INTEGER_LITERAL #intAtom
|
: INTEGER_LITERAL #intAtom
|
||||||
|
| IDENT # variable
|
||||||
;
|
;
|
||||||
|
|
||||||
PRINT: 'print';
|
PRINT: 'print';
|
||||||
|
|||||||
@@ -87,6 +87,11 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Node visitVariable(KlangParser.VariableContext ctx) {
|
||||||
|
return new Variable(ctx.IDENT().getText());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node visitAtomExpression(KlangParser.AtomExpressionContext ctx) {
|
public Node visitAtomExpression(KlangParser.AtomExpressionContext ctx) {
|
||||||
return this.visit(ctx.atom());
|
return this.visit(ctx.atom());
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package de.hsrm.compiler.Klang.nodes.expressions;
|
||||||
|
|
||||||
|
import de.hsrm.compiler.Klang.visitors.Visitor;
|
||||||
|
|
||||||
|
public class Variable extends Expression {
|
||||||
|
|
||||||
|
public String name;
|
||||||
|
|
||||||
|
public Variable(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <R> R welcome(Visitor<R> v) {
|
||||||
|
return v.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,13 +1,20 @@
|
|||||||
package de.hsrm.compiler.Klang.visitors;
|
package de.hsrm.compiler.Klang.visitors;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import de.hsrm.compiler.Klang.Value;
|
import de.hsrm.compiler.Klang.Value;
|
||||||
import de.hsrm.compiler.Klang.nodes.Block;
|
import de.hsrm.compiler.Klang.nodes.Block;
|
||||||
import de.hsrm.compiler.Klang.nodes.FunctionDefinition;
|
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.expressions.*;
|
||||||
import de.hsrm.compiler.Klang.nodes.statements.*;
|
import de.hsrm.compiler.Klang.nodes.statements.*;
|
||||||
|
|
||||||
public class EvalVisitor implements Visitor<Value> {
|
public class EvalVisitor implements Visitor<Value> {
|
||||||
|
|
||||||
|
Map<String, FunctionDefinition> funcs = new HashMap<>();
|
||||||
|
Map<String, Value> env = new HashMap<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value visit(IntegerExpression e) {
|
public Value visit(IntegerExpression e) {
|
||||||
return new Value(e.value);
|
return new Value(e.value);
|
||||||
@@ -40,6 +47,17 @@ public class EvalVisitor implements Visitor<Value> {
|
|||||||
return new Value(-a.asInteger());
|
return new Value(-a.asInteger());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Value visit(Variable e) {
|
||||||
|
Value result = this.env.get(e.name);
|
||||||
|
|
||||||
|
if (result == null) {
|
||||||
|
throw new RuntimeException("Variable with name " +e.name + " not found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value visit(IfStatement e) {
|
public Value visit(IfStatement e) {
|
||||||
// In the future we have to make sure that the
|
// In the future we have to make sure that the
|
||||||
@@ -69,22 +87,55 @@ public class EvalVisitor implements Visitor<Value> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value visit(Block e) {
|
public Value visit(Block e) {
|
||||||
|
Value result = null;
|
||||||
for (var stmt : e.statements) {
|
for (var stmt : e.statements) {
|
||||||
stmt.welcome(this);
|
result = stmt.welcome(this);
|
||||||
}
|
}
|
||||||
return null;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value visit(FunctionDefinition e) {
|
public Value visit(FunctionDefinition e) {
|
||||||
// TODO Auto-generated method stub
|
// Ein Eval über eine FunDef macht keinen Sinn
|
||||||
return null;
|
throw new RuntimeException("Wir sind im Eval und visiten eine Funktionsdefinition.. WUT?!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value visit(FunctionCall e) {
|
public Value visit(FunctionCall e) {
|
||||||
// TODO Auto-generated method stub
|
// Die funktionsdefinition speichern
|
||||||
return null;
|
FunctionDefinition func = this.funcs.get(e.name);
|
||||||
|
|
||||||
|
// Stelle sicher, dass die Länge der argumente und parameter übereinstimmen
|
||||||
|
if (e.arguments.length != func.parameters.length) {
|
||||||
|
throw new RuntimeException("Error with function call " +e.name + ": Number of parameters wrong");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Baue ein neues environment
|
||||||
|
Map<String, Value> newEnv = new HashMap<>();
|
||||||
|
for (int i = 0; i < func.parameters.length; i++) {
|
||||||
|
newEnv.put(func.parameters[i], e.arguments[i].welcome(this));
|
||||||
|
}
|
||||||
|
var oldEnv = this.env;
|
||||||
|
this.env = newEnv;
|
||||||
|
|
||||||
|
// Execute
|
||||||
|
Value result = func.block.welcome(this);
|
||||||
|
|
||||||
|
// Das alte env wiederherstellen
|
||||||
|
this.env = oldEnv;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Value visit(Program e) {
|
||||||
|
// Funktionsdefinitionen für die Auswertung
|
||||||
|
// von Funktionsaufrufen speichern
|
||||||
|
for (var funcDef: e.funcs) {
|
||||||
|
this.funcs.put(funcDef.name, funcDef);
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.expression.welcome(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -55,13 +55,13 @@ public class PrettyPrintVisitor implements Visitor<Void> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visit(Program e) {
|
public Void visit(Program e) {
|
||||||
for (var funcDef : e.funcs) {
|
for (var funcDef : e.funcs) {
|
||||||
funcDef.welcome(this);
|
funcDef.welcome(this);
|
||||||
ex.nl();
|
ex.nl();
|
||||||
ex.nl();
|
ex.nl();
|
||||||
}
|
}
|
||||||
e.expression.welcome(this);
|
e.expression.welcome(this);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -139,40 +139,46 @@ public class PrettyPrintVisitor implements Visitor<Void> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visit(FunctionDefinition e) {
|
public Void visit(FunctionDefinition e) {
|
||||||
ex.write("function ");
|
ex.write("function ");
|
||||||
ex.write(e.name);
|
ex.write(e.name);
|
||||||
ex.write(" (");
|
ex.write(" (");
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
for (String param : e.parameters) {
|
for (String param : e.parameters) {
|
||||||
if (!first) {
|
if (!first) {
|
||||||
ex.write(", ");
|
ex.write(", ");
|
||||||
} else {
|
} else {
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
ex.write(param);
|
ex.write(param);
|
||||||
|
}
|
||||||
|
ex.write(") ");
|
||||||
|
e.block.welcome(this);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
ex.write(") ");
|
|
||||||
e.block.welcome(this);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Void visit(FunctionCall e) {
|
public Void visit(FunctionCall e) {
|
||||||
ex.write(e.name);
|
ex.write(e.name);
|
||||||
ex.write("(");
|
ex.write("(");
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
for (Expression arg : e.arguments) {
|
for (Expression arg : e.arguments) {
|
||||||
if (!first) {
|
if (!first) {
|
||||||
ex.write(", ");
|
ex.write(", ");
|
||||||
} else {
|
} else {
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
arg.welcome(this);
|
arg.welcome(this);
|
||||||
|
}
|
||||||
|
ex.write(");");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Void visit(Variable e) {
|
||||||
|
ex.write(e.name);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
ex.write(");");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,7 @@ import de.hsrm.compiler.Klang.nodes.statements.*;
|
|||||||
|
|
||||||
public interface Visitor<R> {
|
public interface Visitor<R> {
|
||||||
R visit(IntegerExpression e);
|
R visit(IntegerExpression e);
|
||||||
|
R visit(Variable e);
|
||||||
R visit(MultiplicativeExpression e);
|
R visit(MultiplicativeExpression e);
|
||||||
R visit(AdditiveExpression e);
|
R visit(AdditiveExpression e);
|
||||||
R visit(NegateExpression e);
|
R visit(NegateExpression e);
|
||||||
|
|||||||
Reference in New Issue
Block a user