implemented variables and function call evaluation
This commit is contained in:
@@ -87,6 +87,11 @@ public class ContextAnalysis extends KlangBaseVisitor<Node> {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node visitVariable(KlangParser.VariableContext ctx) {
|
||||
return new Variable(ctx.IDENT().getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node visitAtomExpression(KlangParser.AtomExpressionContext ctx) {
|
||||
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;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
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.Program;
|
||||
import de.hsrm.compiler.Klang.nodes.expressions.*;
|
||||
import de.hsrm.compiler.Klang.nodes.statements.*;
|
||||
|
||||
public class EvalVisitor implements Visitor<Value> {
|
||||
|
||||
Map<String, FunctionDefinition> funcs = new HashMap<>();
|
||||
Map<String, Value> env = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public Value visit(IntegerExpression e) {
|
||||
return new Value(e.value);
|
||||
@@ -40,6 +47,17 @@ public class EvalVisitor implements Visitor<Value> {
|
||||
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
|
||||
public Value visit(IfStatement e) {
|
||||
// In the future we have to make sure that the
|
||||
@@ -69,22 +87,55 @@ public class EvalVisitor implements Visitor<Value> {
|
||||
|
||||
@Override
|
||||
public Value visit(Block e) {
|
||||
Value result = null;
|
||||
for (var stmt : e.statements) {
|
||||
stmt.welcome(this);
|
||||
result = stmt.welcome(this);
|
||||
}
|
||||
return null;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value visit(FunctionDefinition e) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
// Ein Eval über eine FunDef macht keinen Sinn
|
||||
throw new RuntimeException("Wir sind im Eval und visiten eine Funktionsdefinition.. WUT?!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Value visit(FunctionCall e) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
// Die funktionsdefinition speichern
|
||||
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
|
||||
public Void visit(Program e) {
|
||||
for (var funcDef : e.funcs) {
|
||||
funcDef.welcome(this);
|
||||
ex.nl();
|
||||
ex.nl();
|
||||
}
|
||||
e.expression.welcome(this);
|
||||
return null;
|
||||
for (var funcDef : e.funcs) {
|
||||
funcDef.welcome(this);
|
||||
ex.nl();
|
||||
ex.nl();
|
||||
}
|
||||
e.expression.welcome(this);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -139,40 +139,46 @@ 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);
|
||||
@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;
|
||||
}
|
||||
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);
|
||||
@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;
|
||||
}
|
||||
|
||||
@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> {
|
||||
R visit(IntegerExpression e);
|
||||
R visit(Variable e);
|
||||
R visit(MultiplicativeExpression e);
|
||||
R visit(AdditiveExpression e);
|
||||
R visit(NegateExpression e);
|
||||
|
||||
Reference in New Issue
Block a user