diff options
author | Marcin Chrzanowski <marcin.j.chrzanowski@gmail.com> | 2019-11-13 21:06:46 +0100 |
---|---|---|
committer | Marcin Chrzanowski <marcin.j.chrzanowski@gmail.com> | 2019-11-13 21:06:46 +0100 |
commit | a014f22d8c8c5c15aa08500a02da0d0717d62b64 (patch) | |
tree | 129e978cb4675ffb4cb9c2b5e2d0c3a3981cb20c | |
parent | 530be09d2cf8e50ca4b3e172c847b361b2d710ad (diff) |
Pass interpreter tests
6 files changed, 240 insertions, 8 deletions
diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/interpreter/EnvironmentRow.java b/src/main/java/pl/edu/mimuw/cloudatlas/interpreter/EnvironmentRow.java new file mode 100644 index 0000000..76a9cf2 --- /dev/null +++ b/src/main/java/pl/edu/mimuw/cloudatlas/interpreter/EnvironmentRow.java @@ -0,0 +1,28 @@ +package pl.edu.mimuw.cloudatlas.interpreter; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import pl.edu.mimuw.cloudatlas.model.ValueNull; + +class EnvironmentRow extends Environment { + private final TableRow row; + private final Map<String, Integer> columns = new HashMap<String, Integer>(); + + public EnvironmentRow(TableRow row, List<String> columns) { + this.row = row; + int i = 0; + for(String c : columns) + this.columns.put(c, i++); + } + + public Result getIdent(String ident) { + try { + return new ResultSingle(row.getIth(columns.get(ident))); + } catch(NullPointerException exception) { + return new ResultSingle(ValueNull.getInstance()); + } + } +} + diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/interpreter/EnvironmentTable.java b/src/main/java/pl/edu/mimuw/cloudatlas/interpreter/EnvironmentTable.java new file mode 100644 index 0000000..bfaeb79 --- /dev/null +++ b/src/main/java/pl/edu/mimuw/cloudatlas/interpreter/EnvironmentTable.java @@ -0,0 +1,19 @@ +package pl.edu.mimuw.cloudatlas.interpreter; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import pl.edu.mimuw.cloudatlas.model.ValueNull; + +class EnvironmentTable extends Environment { + private final Table table; + + public EnvironmentTable(Table table) { + this.table = table; + } + + public Result getIdent(String ident) { + return new ResultColumn(table.getColumn(ident).getValue()); + } +} diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/interpreter/Functions.java b/src/main/java/pl/edu/mimuw/cloudatlas/interpreter/Functions.java index 2fcb9b3..2b44633 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/interpreter/Functions.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/interpreter/Functions.java @@ -77,8 +77,12 @@ class Functions { private static final UnaryOperation CEIL = new UnaryOperation() { @Override public Value perform(Value v) { - // TODO - throw new UnsupportedOperationException("CEIL Not yet implemented"); + if(v.getType().isCompatible(TypePrimitive.DOUBLE)) { + if(v.isNull()) + return new ValueDouble(null); + return new ValueDouble((double)Math.ceil(((ValueDouble)v).getValue())); + } + throw new IllegalArgumentException("Value must have type " + TypePrimitive.DOUBLE + "."); } }; @@ -96,8 +100,26 @@ class Functions { private static final AggregationOperation SUM = new AggregationOperation() { @Override public Value perform(ValueList values) { - // TODO - throw new UnsupportedOperationException("SUM Not yet implemented"); + Type elementType = ((TypeCollection)values.getType()).getElementType(); + PrimaryType primaryType = elementType.getPrimaryType(); + + if(primaryType != PrimaryType.INT && primaryType != PrimaryType.DOUBLE && primaryType != PrimaryType.DURATION + && primaryType != PrimaryType.NULL) { + throw new IllegalArgumentException("Aggregation doesn't support type: " + elementType + "."); + } + + ValueList nlist = Result.filterNullsList(values); + if(nlist.getValue() == null || nlist.isEmpty()) { + return ValueNull.getInstance(); + } + + Value result = nlist.get(0).getDefaultValue(); + + for(Value v : nlist) { + result = result.addValue(v); + } + + return result; } }; @@ -151,8 +173,20 @@ class Functions { private static final AggregationOperation OR = new AggregationOperation() { @Override public ValueBoolean perform(ValueList values) { // lazy - // TODO - throw new UnsupportedOperationException("OR Not yet implemented"); + ValueList nlist = Result.filterNullsList(values); + if(nlist.getValue() == null) { + return new ValueBoolean(null); + } else if(values.isEmpty()) { + return new ValueBoolean(false); + } + for(Value v : nlist) { + if(v.getType().isCompatible(TypePrimitive.BOOLEAN)) { + if(v.isNull() || ((ValueBoolean)v).getValue()) + return new ValueBoolean(true); + } else + throw new IllegalArgumentException("Aggregation doesn't support type: " + v.getType() + "."); + } + return new ValueBoolean(false); } }; diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/interpreter/Result.java b/src/main/java/pl/edu/mimuw/cloudatlas/interpreter/Result.java index e3a0862..0089504 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/interpreter/Result.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/interpreter/Result.java @@ -115,7 +115,7 @@ abstract class Result { private static final BinaryOperation REG_EXPR = new BinaryOperation() { @Override public Value perform(Value v1, Value v2) { - return v1.regExpr(v2); + return v2.regExpr(v1); } }; @@ -134,6 +134,7 @@ abstract class Result { }; protected abstract Result binaryOperationTyped(BinaryOperation operation, ResultSingle right); + protected abstract Result binaryOperationTyped(BinaryOperation operation, ResultColumn right); public Result binaryOperation(BinaryOperation operation, Result right) { return right.callMe(operation, this); @@ -156,7 +157,7 @@ abstract class Result { public Result transformOperation(TransformOperation operation) { // TODO - throw new UnsupportedOperationException("transforation Not yet implemented"); + throw new UnsupportedOperationException("transformation Not yet implemented"); } public Result isEqual(Result right) { diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/interpreter/ResultColumn.java b/src/main/java/pl/edu/mimuw/cloudatlas/interpreter/ResultColumn.java new file mode 100644 index 0000000..a0d5ecd --- /dev/null +++ b/src/main/java/pl/edu/mimuw/cloudatlas/interpreter/ResultColumn.java @@ -0,0 +1,136 @@ +package pl.edu.mimuw.cloudatlas.interpreter; + +import java.util.ArrayList; +import java.util.List; + +import pl.edu.mimuw.cloudatlas.model.Type; +import pl.edu.mimuw.cloudatlas.model.TypeCollection; +import pl.edu.mimuw.cloudatlas.model.Value; +import pl.edu.mimuw.cloudatlas.model.ValueBoolean; +import pl.edu.mimuw.cloudatlas.model.ValueList; + +class ResultColumn extends Result { + private final List<Value> column; + + public ResultColumn(List<Value> column) { + this.column = column; + } + + @Override + protected ResultColumn binaryOperationTyped(BinaryOperation operation, ResultSingle right) { + List<Value> results = new ArrayList<Value>(); + + for (Value value : column) { + results.add(operation.perform(value, right.getValue())); + } + + return new ResultColumn(results); + } + + protected ResultColumn binaryOperationTyped(BinaryOperation operation, ResultColumn right) { + List<Value> results = new ArrayList<Value>(); + + for (int i = 0; i < column.size(); i++) { + results.add(operation.perform(column.get(i), right.column.get(i))); + } + + return new ResultColumn(results); + } + + @Override + public ResultColumn unaryOperation(UnaryOperation operation) { + List<Value> results = new ArrayList<Value>(); + + for (Value value : column) { + results.add(operation.perform(value)); + } + return new ResultColumn(results); + } + + @Override + protected Result callMe(BinaryOperation operation, Result left) { + return left.binaryOperationTyped(operation, this); + } + + @Override + public Value getValue() { + throw new UnsupportedOperationException("Not a ResultSingle."); + } + + @Override + public ValueList getList() { + throw new UnsupportedOperationException("Not a ResultList."); + } + + @Override + public ValueList getColumn() { + return new ValueList(column, TypeCollection.computeElementType(column)); + } + + @Override + public ResultSingle aggregationOperation(AggregationOperation operation) { + return new ResultSingle(operation.perform(getColumn())); + } + + @Override + public Result transformOperation(TransformOperation operation) { + // TODO: this should be a ResultList + return new ResultColumn(operation.perform(getColumn())); + } + + @Override + public Result filterNulls() { + throw new UnsupportedOperationException("Operation filterNulls not supported yet."); + } + + @Override + public Result first(int size) { + List<Value> subList = column.subList(0, Math.min(size, column.size())); + return new ResultSingle(new ValueList(subList, TypeCollection.computeElementType(subList))); + } + + @Override + public Result last(int size) { + List<Value> subList = column.subList( + Math.max(0, column.size() - size), + column.size() + ); + return new ResultSingle(new ValueList(subList, TypeCollection.computeElementType(subList))); + } + + @Override + public Result random(int size) { + return new ResultColumn( + randomList( + new ValueList( + column, + TypeCollection.computeElementType(column) + ), + size + ) + ); + } + + @Override + public ResultColumn convertTo(Type to) { + List<Value> results = new ArrayList<Value>(); + + for (Value value : column) { + results.add(value.convertTo(to)); + } + + return new ResultColumn(results); + } + + @Override + public ResultSingle isNull() { + throw new UnsupportedOperationException("Operation isNull not supported yet."); + // return new ResultSingle(new ValueBoolean(value.isNull())); + } + + @Override + public Type getType() { + throw new UnsupportedOperationException("Operation getType not supported yet."); + // return value.getType(); + } +} diff --git a/src/main/java/pl/edu/mimuw/cloudatlas/interpreter/ResultSingle.java b/src/main/java/pl/edu/mimuw/cloudatlas/interpreter/ResultSingle.java index ada8f93..b77858b 100644 --- a/src/main/java/pl/edu/mimuw/cloudatlas/interpreter/ResultSingle.java +++ b/src/main/java/pl/edu/mimuw/cloudatlas/interpreter/ResultSingle.java @@ -24,6 +24,9 @@ package pl.edu.mimuw.cloudatlas.interpreter; +import java.util.ArrayList; +import java.util.List; + import pl.edu.mimuw.cloudatlas.model.Type; import pl.edu.mimuw.cloudatlas.model.Value; import pl.edu.mimuw.cloudatlas.model.ValueBoolean; @@ -41,6 +44,17 @@ class ResultSingle extends Result { return new ResultSingle(operation.perform(value, right.value)); } + @Override + protected ResultColumn binaryOperationTyped(BinaryOperation operation, ResultColumn right) { + List<Value> results = new ArrayList<Value>(); + + for (Value value : right.getColumn()) { + results.add(operation.perform(this.value, value)); + } + + return new ResultColumn(results); + } + @Override public ResultSingle unaryOperation(UnaryOperation operation) { return new ResultSingle(operation.perform(value)); |