Skip to content
Snippets Groups Projects
Commit b6c8023e authored by Julien Lopez's avatar Julien Lopez
Browse files

- Begin implementation of QIR evaluation, not integrated yet

- Remove useless operators
- Minor improvments in GreedyReduceVisitor
parent bfd698f5
No related branches found
No related tags found
No related merge requests found
package qir.ast.expression.relational;
import com.oracle.truffle.api.source.*;
import qir.ast.*;
import qir.util.*;
/**
* The {@link QIRGreaterOrEqual} represents an expression that is true if and only if the
* {@link #left} expression is "greater or equal" to the {@link #right} expression.
*/
public final class QIRGreaterOrEqual extends QIRNode {
/**
* The left side of the {@link QIRGreaterOrEqual} operator.
*/
private final QIRNode left;
/**
* The right side of the {@link QIRGreaterOrEqual} operator.
*/
private final QIRNode right;
public QIRGreaterOrEqual(final SourceSection source, final QIRNode left, final QIRNode right) {
super(source);
this.left = left;
this.right = right;
}
public final QIRNode getLeft() {
return left;
}
public final QIRNode getRight() {
return right;
}
@Override
public final String toString() {
return left + " >= " + right;
}
@Override
public boolean equals(Object other) {
if (other instanceof QIRAny)
return true;
if (!(other instanceof QIRGreaterOrEqual))
return false;
return left.equals(((QIRGreaterOrEqual) other).left) && right.equals(((QIRGreaterOrEqual) other).right);
}
@Override
public final <T> T accept(final IQIRVisitor<T> visitor) {
return visitor.visit(this);
}
}
\ No newline at end of file
package qir.ast.expression.relational;
import com.oracle.truffle.api.source.*;
import qir.ast.*;
import qir.util.*;
/**
* The {@link QIRGreaterThan} represents an expression that is true if and only if the {@link #left}
* expression is "greater than" the {@link #right} expression.
*/
public final class QIRGreaterThan extends QIRNode {
/**
* The left side of the {@link QIRGreaterThan} operator.
*/
private final QIRNode left;
/**
* The right side of the {@link QIRGreaterThan} operator.
*/
private final QIRNode right;
public QIRGreaterThan(final SourceSection source, final QIRNode left, final QIRNode right) {
super(source);
this.left = left;
this.right = right;
}
public final QIRNode getLeft() {
return left;
}
public final QIRNode getRight() {
return right;
}
@Override
public final String toString() {
return left + " > " + right;
}
@Override
public boolean equals(Object other) {
if (other instanceof QIRAny)
return true;
if (!(other instanceof QIRGreaterThan))
return false;
return left.equals(((QIRGreaterThan) other).left) && right.equals(((QIRGreaterThan) other).right);
}
@Override
public final <T> T accept(final IQIRVisitor<T> visitor) {
return visitor.visit(this);
}
}
\ No newline at end of file
package qir.ast.expression.relational;
import com.oracle.truffle.api.source.*;
import qir.ast.*;
import qir.util.*;
/**
* The {@link QIRNotEqual} represents an expression that is true if and only if the {@link #left}
* expression and the {@link #right} expression are different.
*/
public final class QIRNotEqual extends QIRNode {
/**
* The left side of the {@link QIRNotEqual} operator.
*/
private final QIRNode left;
/**
* The right side of the {@link QIRNotEqual} operator.
*/
private final QIRNode right;
public QIRNotEqual(final SourceSection source, final QIRNode left, final QIRNode right) {
super(source);
this.left = left;
this.right = right;
}
public final QIRNode getLeft() {
return left;
}
public final QIRNode getRight() {
return right;
}
@Override
public final String toString() {
return left + " != " + right;
}
@Override
public boolean equals(Object other) {
if (other instanceof QIRAny)
return true;
if (!(other instanceof QIRNotEqual))
return false;
return left.equals(((QIRNotEqual) other).left) && right.equals(((QIRNotEqual) other).right);
}
@Override
public final <T> T accept(final IQIRVisitor<T> visitor) {
return visitor.visit(this);
}
}
\ No newline at end of file
......@@ -187,16 +187,6 @@ public final class QIRSQLVisitor implements IQIRVisitor<String> {
return "(" + qirEqual.getLeft().accept(this) + ") = (" + qirEqual.getRight().accept(this) + ")";
}
@Override
public final String visit(final QIRGreaterOrEqual qirGreaterOrEqual) {
return "(" + qirGreaterOrEqual.getLeft().accept(this) + ") >= (" + qirGreaterOrEqual.getRight().accept(this) + ")";
}
@Override
public final String visit(final QIRGreaterThan qirGreaterThan) {
return "(" + qirGreaterThan.getLeft().accept(this) + ") > (" + qirGreaterThan.getRight().accept(this) + ")";
}
@Override
public final String visit(final QIRLowerOrEqual qirLowerOrEqual) {
return "(" + qirLowerOrEqual.getLeft().accept(this) + ") <= (" + qirLowerOrEqual.getRight().accept(this) + ")";
......@@ -207,11 +197,6 @@ public final class QIRSQLVisitor implements IQIRVisitor<String> {
return "(" + qirLowerThan.getLeft().accept(this) + ") < (" + qirLowerThan.getRight().accept(this) + ")";
}
@Override
public final String visit(final QIRNotEqual qirNotEqual) {
return "(" + qirNotEqual.getLeft().accept(this) + ") != (" + qirNotEqual.getRight().accept(this) + ")";
}
@Override
public final String visit(final QIRNot qirNot) {
return "NOT (" + qirNot.getChild().accept(this) + ")";
......
......@@ -10,12 +10,17 @@ import qir.ast.expression.arithmetic.*;
import qir.ast.expression.logic.*;
import qir.ast.expression.relational.*;
import qir.ast.operator.*;
import qir.ast.value.QIRBaseValue;
import qir.ast.value.QIRBigNumber;
import qir.ast.value.QIRBoolean;
import qir.ast.value.QIRNumber;
import qir.ast.value.QIRString;
import qir.util.IQIRVisitor;
/**
* The QIR greedy normalization module. TODO: Check behavior if reduction fails, especially in
* ldestr.
*/
public final class QIRGreedyReduceVisitor implements IQIRVisitor<QIRNode> {
private final HashMap<String, QIRNode> env = new HashMap<>();
......@@ -64,23 +69,28 @@ public final class QIRGreedyReduceVisitor implements IQIRVisitor<QIRNode> {
final QIRNode left = qirApply.getLeft().accept(this);
final QIRNode right = ((qirApply.getRight() != null) ? qirApply.getRight().accept(this) : null);
if (left instanceof QIRLambda) {
final QIRLambda fun = (QIRLambda) left;
final QIRVariable var = fun.getVar();
if (var == null)
return fun.getBody();
final String varName = var.getId();
env.put(varName, right);
final QIRLambda res = (QIRLambda) fun.accept(this);
env.remove(varName);
return res.getBody();
}
return new QIRApply(qirApply.getSourceSection(), left, right);
if (!(left instanceof QIRLambda))
return new QIRApply(qirApply.getSourceSection(), left, right);
final QIRLambda fun = (QIRLambda) left;
final QIRVariable var = fun.getVar();
if (var == null)
return fun.getBody();
final String varName = var.getId();
env.put(varName, right);
final QIRLambda res = (QIRLambda) fun.accept(this);
env.remove(varName);
return res.getBody();
}
@Override
public final QIRNode visit(final QIRIf qirIf) {
return new QIRIf(qirIf.getSourceSection(), qirIf.getCondition().accept(this), qirIf.getThenNode().accept(this), qirIf.getElseNode().accept(this));
final QIRNode cond = qirIf.getCondition().accept(this);
if (cond.equals(new QIRBoolean(null, true)))
return qirIf.getThenNode().accept(this);
if (cond.equals(new QIRBoolean(null, false)))
return qirIf.getElseNode().accept(this);
return new QIRIf(qirIf.getSourceSection(), cond, qirIf.getThenNode().accept(this), qirIf.getElseNode().accept(this));
}
@Override
......@@ -120,17 +130,14 @@ public final class QIRGreedyReduceVisitor implements IQIRVisitor<QIRNode> {
@Override
public final QIRNode visit(final QIREqual qirEqual) {
return new QIREqual(qirEqual.getSourceSection(), qirEqual.getLeft().accept(this), qirEqual.getRight().accept(this));
}
@Override
public final QIRNode visit(final QIRGreaterOrEqual qirGreaterOrEqual) {
return new QIRGreaterOrEqual(qirGreaterOrEqual.getSourceSection(), qirGreaterOrEqual.getLeft().accept(this), qirGreaterOrEqual.getRight().accept(this));
}
final QIRNode left = qirEqual.getLeft().accept(this);
final QIRNode right = qirEqual.getRight().accept(this);
@Override
public final QIRNode visit(final QIRGreaterThan qirGreaterThan) {
return new QIRGreaterThan(qirGreaterThan.getSourceSection(), qirGreaterThan.getLeft().accept(this), qirGreaterThan.getRight().accept(this));
if (left.equals(right))
return new QIRBoolean(null, true);
if (left instanceof QIRBaseValue<?> && right instanceof QIRBaseValue<?>)
return new QIRBoolean(null, false);
return new QIREqual(qirEqual.getSourceSection(), left, right);
}
@Override
......@@ -143,11 +150,6 @@ public final class QIRGreedyReduceVisitor implements IQIRVisitor<QIRNode> {
return new QIRLowerThan(qirLowerThan.getSourceSection(), qirLowerThan.getLeft().accept(this), qirLowerThan.getRight().accept(this));
}
@Override
public final QIRNode visit(final QIRNotEqual qirNotEqual) {
return new QIRNotEqual(qirNotEqual.getSourceSection(), qirNotEqual.getLeft().accept(this), qirNotEqual.getRight().accept(this));
}
@Override
public final QIRNode visit(final QIRNot qirNot) {
return new QIRNot(qirNot.getSourceSection(), qirNot.getChild().accept(this));
......@@ -179,30 +181,27 @@ public final class QIRGreedyReduceVisitor implements IQIRVisitor<QIRNode> {
final QIRNode ifEmpty = qirLdestr.getIfEmpty().accept(this);
final QIRNode handler = qirLdestr.getHandler().accept(this);
if (list instanceof QIRLnil) {
if (list instanceof QIRLnil)
return ifEmpty;
}
if (list instanceof QIRLcons) {
final QIRLcons lcons = (QIRLcons) list;
final QIRNode value = lcons.getValue().accept(this);
final QIRNode tail = lcons.getTail().accept(this);
if (handler instanceof QIRLambda) {
final QIRLambda fun = (QIRLambda) handler;
final QIRNode body = fun.getBody();
final String varName = fun.getVar().getId();
env.put(varName, value);
if (body instanceof QIRLambda)
env.put(((QIRLambda) body).getVar().getId(), tail);
final QIRNode result = fun.accept(this);
env.remove(varName);
if (body instanceof QIRLambda)
env.remove(((QIRLambda) body).getVar().getId());
return result;
}
SourceSection src = SourceSection.createUnavailable("QIR", "Apply");
if (!(list instanceof QIRLcons))
return new QIRLdestr(qirLdestr.getSourceSection(), list, ifEmpty, handler);
final QIRLcons lcons = (QIRLcons) list;
final QIRNode value = lcons.getValue().accept(this);
final QIRNode tail = lcons.getTail().accept(this);
// If handler is not a function with two arguments
if (!(handler instanceof QIRLambda) || !(((QIRLambda) handler).getBody() instanceof QIRLambda)) {
final SourceSection src = SourceSection.createUnavailable("QIR", "Apply");
return new QIRApply(src, new QIRApply(src, handler, value), tail);
}
return new QIRLdestr(qirLdestr.getSourceSection(), list, ifEmpty, handler);
// else we put the two arguments in the environment then try to evaluate the body
final QIRNode body = ((QIRLambda) handler).getBody();
env.put(((QIRLambda) handler).getVar().getId(), value);
env.put(((QIRLambda) body).getVar().getId(), tail);
final QIRNode result = ((QIRLambda) body).getBody().accept(this);
env.remove(((QIRLambda) handler).getVar().getId());
env.remove(((QIRLambda) body).getVar().getId());
return result;
}
@Override
......@@ -219,14 +218,10 @@ public final class QIRGreedyReduceVisitor implements IQIRVisitor<QIRNode> {
public final QIRNode visit(final QIRTdestr qirTdestr) {
final QIRNode tuple = qirTdestr.getTuple().accept(this);
final String colName = qirTdestr.getColName();
QIRNode current = tuple;
while (current instanceof QIRTcons) {
final QIRTcons currentTuple = (QIRTcons) current;
if (colName == currentTuple.getId())
return currentTuple.getValue();
current = currentTuple.getTail();
}
for (QIRNode current = tuple; current instanceof QIRTcons; current = ((QIRTcons) current).getTail())
if (colName == ((QIRTcons) current).getId())
return ((QIRTcons) current).getValue();
return new QIRTdestr(qirTdestr.getSourceSection(), tuple, colName);
}
......
......@@ -55,16 +55,10 @@ public interface IQIRVisitor<T> {
public abstract T visit(final QIREqual qirEqual);
public abstract T visit(final QIRGreaterOrEqual qirGreaterOrEqual);
public abstract T visit(final QIRGreaterThan qirGreaterThan);
public abstract T visit(final QIRLowerOrEqual qirLowerOrEqual);
public abstract T visit(final QIRLowerThan qirLowerThan);
public abstract T visit(final QIRNotEqual qirNotEqual);
public abstract T visit(final QIRNot qirNot);
public abstract T visit(final QIRTable qirTable);
......
package qir.util;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashMap;
import qir.ast.*;
import qir.ast.data.*;
import qir.ast.expression.arithmetic.*;
import qir.ast.expression.logic.*;
import qir.ast.expression.relational.*;
import qir.ast.operator.*;
import qir.ast.value.*;
public final class QIREvaluationVisitor implements IQIRVisitor<QIRNode> {
private final HashMap<String, QIRNode> env = new HashMap<>();
@Override
public QIRNode visit(QIRProject qirProject) {
final QIRNode formatter = qirProject.getFormatter().accept(this);
final QIRNode input = qirProject.getChild().accept(this);
final Deque<QIRNode> tmp = new ArrayDeque<>();
QIRList result = QIRLnil.getInstance();
if (input instanceof QIRLnil)
return input;
if (!(input instanceof QIRLcons))
throw new QIRException("[QIR] Typing error: project expected list as input, got: " + input.getClass().getName() + ".");
for (QIRNode e = input; e instanceof QIRLcons; e = ((QIRLcons) e).getTail())
tmp.push(new QIRApply(null, formatter, e).accept(this));
while (!tmp.isEmpty())
result = new QIRLcons(null, tmp.pop(), result);
return result;
}
@Override
public QIRNode visit(QIRScan qirScan) {
final QIRNode table = qirScan.getTable().accept(this);
if (!(table instanceof QIRTable))
throw new QIRException("[QIR] Typing error: scan expected table as input, got: " + table.getClass().getName() + ".");
throw new QIRException("[QIR] Scan not implemented yet.");
}
@Override
public QIRNode visit(QIRFilter qirFilter) {
final QIRNode filter = qirFilter.getFilter().accept(this);
final QIRNode input = qirFilter.getChild().accept(this);
final Deque<QIRNode> tmp = new ArrayDeque<>();
QIRList result = QIRLnil.getInstance();
if (input instanceof QIRLnil)
return input;
if (!(input instanceof QIRLcons))
throw new QIRException("[QIR] Typing error: project expected list as input, got: " + input.getClass().getName() + ".");
for (QIRNode e = input; e instanceof QIRLcons; e = ((QIRLcons) e).getTail()) {
final QIRNode pass = new QIRApply(null, filter, e).accept(this);
if (pass.equals(new QIRBoolean(null, true)))
tmp.push(e);
else if (!pass.equals(new QIRBoolean(null, false)))
throw new QIRException("[QIR] Typing error: filter expected function returning boolean as configuration, got: " + filter + ".");
}
while (!tmp.isEmpty())
result = new QIRLcons(null, tmp.pop(), result);
return result;
}
@Override
public QIRNode visit(QIRGroup qirGroup) {
throw new QIRException("[QIR] Group not implemented yet.");
}
@Override
public QIRNode visit(QIROrder qirOrder) {
throw new QIRException("[QIR] Order not implemented yet.");
}
@Override
public QIRNode visit(QIRJoin qirJoin) {
throw new QIRException("[QIR] Join not implemented yet.");
}
@Override
public QIRNode visit(QIRLimit qirLimit) {
return qirLimit;
}
@Override
public QIRNode visit(QIRVariable qirVariable) {
return env.get(qirVariable.getId());
}
@Override
public QIRNode visit(QIRLambda qirLambda) {
return qirLambda;
}
@Override
public QIRNode visit(QIRApply qirApply) {
final QIRNode left = qirApply.getLeft().accept(this);
final QIRNode right = ((qirApply.getRight() != null) ? qirApply.getRight().accept(this) : null);
if (left instanceof QIRLambda) {
final QIRLambda fun = (QIRLambda) left;
final QIRVariable var = fun.getVar();
if (var == null)
return fun.getBody();
final String varName = var.getId();
env.put(varName, right);
final QIRLambda res = (QIRLambda) fun.accept(this);
env.remove(varName);
return res.getBody();
}
if (left instanceof QIRTruffleNode)
throw new QIRException("[QIR] Evaluation of Truffle application not implemented yet.");
throw new QIRException("[QIR] Typing error: expected function on left side of application, got: " + left.getClass().getName() + ".");
}
@Override
public QIRNode visit(QIRIf qirIf) {
final QIRNode cond = qirIf.getCondition().accept(this);
if (cond.equals(new QIRBoolean(null, true)))
return qirIf.getThenNode().accept(this);
if (cond.equals(new QIRBoolean(null, false)))
return qirIf.getElseNode().accept(this);
throw new QIRException("[QIR] Typing error: expected boolean on condition of if statement, got: " + cond.getClass().getName() + ".");
}
@Override
public QIRNode visit(QIRPlus qirPlus) {
final QIRNode left = qirPlus.getLeft().accept(this);
final QIRNode right = qirPlus.getRight().accept(this);
if (left instanceof QIRNumber && right instanceof QIRNumber)
return new QIRNumber(qirPlus.getSourceSection(), ((QIRNumber) left).getValue() + ((QIRNumber) right).getValue());
if (left instanceof QIRString && right instanceof QIRString)
return new QIRString(qirPlus.getSourceSection(), ((QIRString) left).getValue() + ((QIRString) right).getValue());
if (left instanceof QIRBigNumber && right instanceof QIRBigNumber)
return new QIRBigNumber(qirPlus.getSourceSection(), ((QIRBigNumber) left).getValue().add(((QIRBigNumber) right).getValue()));
throw new QIRException("[QIR] Typing error: binary operator + not defined for: " + left.getClass().getName() + " and " + right.getClass().getName() + ".");
}
@Override
public QIRNode visit(QIRMinus qirMinus) {
final QIRNode left = qirMinus.getLeft().accept(this);
final QIRNode right = qirMinus.getRight().accept(this);
if (left instanceof QIRNumber && right instanceof QIRNumber)
return new QIRNumber(qirMinus.getSourceSection(), ((QIRNumber) left).getValue() - ((QIRNumber) right).getValue());
if (left instanceof QIRBigNumber && right instanceof QIRBigNumber)
return new QIRBigNumber(qirMinus.getSourceSection(), ((QIRBigNumber) left).getValue().subtract(((QIRBigNumber) right).getValue()));
throw new QIRException("[QIR] Typing error: binary operator - not defined for: " + left.getClass().getName() + " and " + right.getClass().getName() + ".");
}
@Override
public QIRNode visit(QIRStar qirStar) {
final QIRNode left = qirStar.getLeft().accept(this);
final QIRNode right = qirStar.getRight().accept(this);
if (left instanceof QIRNumber && right instanceof QIRNumber)
return new QIRNumber(qirStar.getSourceSection(), ((QIRNumber) left).getValue() * ((QIRNumber) right).getValue());
if (left instanceof QIRBigNumber && right instanceof QIRBigNumber)
return new QIRBigNumber(qirStar.getSourceSection(), ((QIRBigNumber) left).getValue().multiply(((QIRBigNumber) right).getValue()));
throw new QIRException("[QIR] Typing error: binary operator * not defined for: " + left.getClass().getName() + " and " + right.getClass().getName() + ".");
}
@Override
public QIRNode visit(QIRDiv qirDiv) {
final QIRNode left = qirDiv.getLeft().accept(this);
final QIRNode right = qirDiv.getRight().accept(this);
if (left instanceof QIRNumber && right instanceof QIRNumber)
return new QIRNumber(qirDiv.getSourceSection(), ((QIRNumber) left).getValue() / ((QIRNumber) right).getValue());
if (left instanceof QIRBigNumber && right instanceof QIRBigNumber)
return new QIRBigNumber(qirDiv.getSourceSection(), ((QIRBigNumber) left).getValue().divide(((QIRBigNumber) right).getValue()));
throw new QIRException("[QIR] Typing error: binary operator / not defined for: " + left.getClass().getName() + " and " + right.getClass().getName() + ".");
}
@Override
public QIRNode visit(QIRMod qirMod) {
final QIRNode left = qirMod.getLeft().accept(this);
final QIRNode right = qirMod.getRight().accept(this);
if (left instanceof QIRNumber && right instanceof QIRNumber)
return new QIRNumber(qirMod.getSourceSection(), ((QIRNumber) left).getValue() % ((QIRNumber) right).getValue());
if (left instanceof QIRBigNumber && right instanceof QIRBigNumber)
return new QIRBigNumber(qirMod.getSourceSection(), ((QIRBigNumber) left).getValue().mod(((QIRBigNumber) right).getValue()));
throw new QIRException("[QIR] Typing error: binary operator % not defined for: " + left.getClass().getName() + " and " + right.getClass().getName() + ".");
}
@Override
public QIRNode visit(QIRAnd qirAnd) {
final QIRNode left = qirAnd.getLeft().accept(this);
final QIRNode right = qirAnd.getRight().accept(this);
if (left instanceof QIRBoolean && right instanceof QIRBoolean)
return new QIRBoolean(qirAnd.getSourceSection(), ((QIRBoolean) left).getValue() && ((QIRBoolean) right).getValue());
throw new QIRException("[QIR] Typing error: binary operator && not defined for: " + left.getClass().getName() + " and " + right.getClass().getName() + ".");
}
@Override
public QIRNode visit(QIROr qirOr) {
final QIRNode left = qirOr.getLeft().accept(this);
final QIRNode right = qirOr.getRight().accept(this);
if (left instanceof QIRBoolean && right instanceof QIRBoolean)
return new QIRBoolean(qirOr.getSourceSection(), ((QIRBoolean) left).getValue() || ((QIRBoolean) right).getValue());
throw new QIRException("[QIR] Typing error: binary operator || not defined for: " + left.getClass().getName() + " and " + right.getClass().getName() + ".");
}
@Override
public QIRNode visit(QIREqual qirEqual) {
final QIRNode left = qirEqual.getLeft().accept(this);
final QIRNode right = qirEqual.getRight().accept(this);
if (left instanceof QIRNumber && right instanceof QIRNumber)
return new QIRBoolean(qirEqual.getSourceSection(), ((QIRNumber) left).getValue() == ((QIRNumber) right).getValue());
if (left instanceof QIRString && right instanceof QIRString)
return new QIRBoolean(qirEqual.getSourceSection(), ((QIRString) left).getValue().equals(((QIRString) right).getValue()));
if (left instanceof QIRBoolean && right instanceof QIRBoolean)
return new QIRBoolean(qirEqual.getSourceSection(), ((QIRBoolean) left).getValue() == ((QIRBoolean) right).getValue());
if (left instanceof QIRBigNumber && right instanceof QIRBigNumber)
return new QIRBoolean(qirEqual.getSourceSection(), ((QIRBigNumber) left).getValue().equals(((QIRBigNumber) right).getValue()));
throw new QIRException("[QIR] Typing error: binary operator == not defined for: " + left.getClass().getName() + " and " + right.getClass().getName() + ".");
}
@Override
public QIRNode visit(QIRLowerOrEqual qirLowerOrEqual) {
final QIRNode left = qirLowerOrEqual.getLeft().accept(this);
final QIRNode right = qirLowerOrEqual.getRight().accept(this);
if (left instanceof QIRNumber && right instanceof QIRNumber)
return new QIRBoolean(qirLowerOrEqual.getSourceSection(), ((QIRNumber) left).getValue() <= ((QIRNumber) right).getValue());
if (left instanceof QIRString && right instanceof QIRString)
return new QIRBoolean(qirLowerOrEqual.getSourceSection(), ((QIRString) left).getValue().compareTo(((QIRString) right).getValue()) <= 0);
if (left instanceof QIRBigNumber && right instanceof QIRBigNumber)
return new QIRBoolean(qirLowerOrEqual.getSourceSection(), ((QIRBigNumber) left).getValue().compareTo(((QIRBigNumber) right).getValue()) <= 0);
throw new QIRException("[QIR] Typing error: binary operator <= not defined for: " + left.getClass().getName() + " and " + right.getClass().getName() + ".");
}
@Override
public QIRNode visit(QIRLowerThan qirLowerThan) {
final QIRNode left = qirLowerThan.getLeft().accept(this);
final QIRNode right = qirLowerThan.getRight().accept(this);
if (left instanceof QIRNumber && right instanceof QIRNumber)
return new QIRBoolean(qirLowerThan.getSourceSection(), ((QIRNumber) left).getValue() < ((QIRNumber) right).getValue());
if (left instanceof QIRString && right instanceof QIRString)
return new QIRBoolean(qirLowerThan.getSourceSection(), ((QIRString) left).getValue().compareTo(((QIRString) right).getValue()) < 0);
if (left instanceof QIRBigNumber && right instanceof QIRBigNumber)
return new QIRBoolean(qirLowerThan.getSourceSection(), ((QIRBigNumber) left).getValue().compareTo(((QIRBigNumber) right).getValue()) < 0);
throw new QIRException("[QIR] Typing error: binary operator < not defined for: " + left.getClass().getName() + " and " + right.getClass().getName() + ".");
}
@Override
public QIRNode visit(QIRNot qirNot) {
final QIRNode expr = qirNot.getChild().accept(this);
if (expr instanceof QIRBoolean)
return new QIRBoolean(qirNot.getSourceSection(), !((QIRBoolean) expr).getValue());
throw new QIRException("[QIR] Typing error: binary operator ! not defined for: " + expr.getClass().getName() + ".");
}
@Override
public QIRNode visit(QIRTable qirTable) {
return qirTable;
}
@Override
public QIRNode visit(QIRLnil qirLnil) {
return qirLnil;
}
@Override
public QIRNode visit(QIRLcons qirLcons) {
return new QIRLcons(qirLcons.getSourceSection(), qirLcons.getValue().accept(this), qirLcons.getTail().accept(this));
}
@Override
public QIRNode visit(QIRLdestr qirLdestr) {
final QIRNode list = qirLdestr.getList().accept(this);
final QIRNode ifEmpty = qirLdestr.getIfEmpty().accept(this);
final QIRNode handler = qirLdestr.getHandler().accept(this);
if (list instanceof QIRLnil)
return ifEmpty;
if (!(list instanceof QIRLcons))
throw new QIRException("[QIR] Typing error: destructor of list expected list as entry, got: " + list.getClass().getName() + ".");
final QIRLcons lcons = (QIRLcons) list;
final QIRNode value = lcons.getValue().accept(this);
final QIRNode tail = lcons.getTail().accept(this);
// If handler is not a function with two arguments
if (!(handler instanceof QIRLambda) || !(((QIRLambda) handler).getBody() instanceof QIRLambda))
throw new QIRException("[QIR] Typing error: destructor of list expected function with two arguments as handler, got: " + handler + ".");
// else we put the two arguments in the environment then try to evaluate the body
final QIRNode body = ((QIRLambda) handler).getBody();
env.put(((QIRLambda) handler).getVar().getId(), value);
env.put(((QIRLambda) body).getVar().getId(), tail);
final QIRNode result = ((QIRLambda) body).getBody().accept(this);
env.remove(((QIRLambda) handler).getVar().getId());
env.remove(((QIRLambda) body).getVar().getId());
return result;
}
@Override
public QIRNode visit(QIRTnil qirTnil) {
return qirTnil;
}
@Override
public QIRNode visit(QIRTcons qirTcons) {
return new QIRTcons(qirTcons.getSourceSection(), qirTcons.getId(), qirTcons.getValue().accept(this), qirTcons.getTail().accept(this));
}
@Override
public QIRNode visit(QIRTdestr qirTdestr) {
final QIRNode tuple = qirTdestr.getTuple().accept(this);
final String colName = qirTdestr.getColName();
for (QIRNode current = tuple; current instanceof QIRTcons; current = ((QIRTcons) current).getTail())
if (colName == ((QIRTcons) current).getId())
return ((QIRTcons) current).getValue();
throw new QIRException("[QIR] Typing error: destructor of tuple could not find " + colName + " in tuple " + tuple + ".");
}
@Override
public QIRNode visit(QIRString qirString) {
return qirString;
}
@Override
public QIRNode visit(QIRNumber qirNumber) {
return qirNumber;
}
@Override
public QIRNode visit(QIRBigNumber qirBigNumber) {
return qirBigNumber;
}
@Override
public QIRNode visit(QIRBoolean qirBoolean) {
return qirBoolean;
}
@Override
public QIRNode visit(QIRNull qirNull) {
return qirNull;
}
@Override
public QIRNode visit(QIRTruffleNode qirTruffleNode) {
throw new QIRException("[QIR] Evaluation of Truffle node not implemented yet.");
}
}
\ No newline at end of file
......@@ -135,18 +135,6 @@ public final class QIRFreeVarsVisitor implements IQIRVisitor<Map<String, QIRVari
return qirEqual.getRight().accept(this);
}
@Override
public final Map<String, QIRVariable> visit(final QIRGreaterOrEqual qirGreaterOrEqual) {
qirGreaterOrEqual.getLeft().accept(this);
return qirGreaterOrEqual.getRight().accept(this);
}
@Override
public final Map<String, QIRVariable> visit(final QIRGreaterThan qirGreaterThan) {
qirGreaterThan.getLeft().accept(this);
return qirGreaterThan.getRight().accept(this);
}
@Override
public final Map<String, QIRVariable> visit(final QIRLowerOrEqual qirLowerOrEqual) {
qirLowerOrEqual.getLeft().accept(this);
......@@ -159,12 +147,6 @@ public final class QIRFreeVarsVisitor implements IQIRVisitor<Map<String, QIRVari
return qirLowerThan.getRight().accept(this);
}
@Override
public final Map<String, QIRVariable> visit(final QIRNotEqual qirNotEqual) {
qirNotEqual.getLeft().accept(this);
return qirNotEqual.getRight().accept(this);
}
@Override
public final Map<String, QIRVariable> visit(final QIRNot qirNot) {
return qirNot.getChild().accept(this);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment