|
@@ -285,7 +285,7 @@ export class IVProgProcessor {
|
|
|
*
|
|
|
* @returns {Promise<Store>}
|
|
|
*/
|
|
|
- executeSysCall (store, cmd) {
|
|
|
+ async executeSysCall (store, cmd) {
|
|
|
const func = cmd.langFunc.bind(this);
|
|
|
return func(store, cmd);
|
|
|
}
|
|
@@ -793,24 +793,21 @@ export class IVProgProcessor {
|
|
|
* @param {Store} store
|
|
|
* @param {Expressions.ArrayLiteral} exp
|
|
|
* @param {ArrayType} type
|
|
|
+ *
|
|
|
+ * @returns {Promise<StoreValue[]>}
|
|
|
*/
|
|
|
- evaluateArrayLiteral (store, exp, type, lines, columns) {
|
|
|
- if(!exp.isVector) {
|
|
|
+ async evaluateArrayLiteral (store, exp, type, lines, columns) {
|
|
|
+ if (!exp.isVector) {
|
|
|
if(columns == null) {
|
|
|
- return Promise.reject(new Error("This should never happen: Vector cannot be initialized by a matrix"));
|
|
|
+ throw new Error("This should never happen: Vector cannot be initialized by a matrix");
|
|
|
}
|
|
|
- const $matrix = this.evaluateMatrix(store, exp, type, lines, columns);
|
|
|
- return Promise.all($matrix).then(vectorList => {
|
|
|
- const values = vectorList.reduce((prev, next) => prev.concat(next), []);
|
|
|
- return Promise.resolve(values);
|
|
|
- });
|
|
|
+ const storeValueMatrix = await this.evaluateMatrix(store, exp, type, lines, columns);
|
|
|
+ return storeValueMatrix.reduce( (prev, next) => prev.concat(next), []);
|
|
|
} else {
|
|
|
if(columns != null) {
|
|
|
- return Promise.reject(new Error("This should never happen: Matrix cannot be initialized by a vector"));
|
|
|
+ throw new Error("This should never happen: Matrix cannot be initialized by a vector");
|
|
|
}
|
|
|
- return this.evaluateVector(store, exp, type, lines).then(list => {
|
|
|
- return Promise.resolve(list);
|
|
|
- });
|
|
|
+ return this.evaluateVector(store, exp, type, lines)
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -820,29 +817,29 @@ export class IVProgProcessor {
|
|
|
* @param {Expressions.ArrayLiteral} exps
|
|
|
* @param {ArrayType} type
|
|
|
* @param {number} n_elements
|
|
|
+ *
|
|
|
* @returns {Promise<StoreValue[]>} store object list
|
|
|
*/
|
|
|
- evaluateVector (store, exps, type, n_elements) {
|
|
|
+ async evaluateVector (store, exps, type, n_elements) {
|
|
|
const values = exps.value;
|
|
|
- if(n_elements !== values.length) {
|
|
|
- return Promise.reject(ProcessorErrorFactory.invalid_number_elements_vector(n_elements, exps.toString(), values.length, exps.sourceInfo));
|
|
|
+ if (n_elements !== values.length) {
|
|
|
+ throw ProcessorErrorFactory.invalid_number_elements_vector(n_elements, exps.toString(),
|
|
|
+ values.length, exps.sourceInfo);
|
|
|
}
|
|
|
- const actual_values = Promise.all(values.map( exp => this.evaluateExpression(store, exp)));
|
|
|
- return actual_values.then( values => {
|
|
|
- return values.map((v, index) => {
|
|
|
- if(!type.canAccept(v.type, 1)) {
|
|
|
- if (!Config.enable_type_casting || !Store.canImplicitTypeCast(type.innerType, v.type)) {
|
|
|
- // const stringInfo = v.type.stringInfo();
|
|
|
- // const info = stringInfo[0];
|
|
|
- const exp_str = values[index].toString();
|
|
|
- // TODO - fix error message
|
|
|
- return Promise.reject(ProcessorErrorFactory.invalid_array_literal_type_full(exp_str, values[index].sourceInfo));
|
|
|
- }
|
|
|
- const new_value = Store.doImplicitCasting(type.innerType, v);
|
|
|
- return new_value;
|
|
|
+ const actualValues = await Promise.all(values.map( exp => this.evaluateExpression(store, exp)));
|
|
|
+ return actualValues.map( (v, index) => {
|
|
|
+ if(!type.canAccept(v.type, 1)) {
|
|
|
+ if (!Config.enable_type_casting || !Store.canImplicitTypeCast(type.innerType, v.type)) {
|
|
|
+ // const stringInfo = v.type.stringInfo();
|
|
|
+ // const info = stringInfo[0];
|
|
|
+ const exp_str = values[index].toString();
|
|
|
+ // TODO - fix error message
|
|
|
+ throw ProcessorErrorFactory.invalid_array_literal_type_full(exp_str, values[index].sourceInfo);
|
|
|
}
|
|
|
- return v;
|
|
|
- });
|
|
|
+ const newValue = Store.doImplicitCasting(type.innerType, v);
|
|
|
+ return newValue;
|
|
|
+ }
|
|
|
+ return v;
|
|
|
});
|
|
|
}
|
|
|
|
|
@@ -851,265 +848,295 @@ export class IVProgProcessor {
|
|
|
* @param {Store} store
|
|
|
* @param {Expressions.ArrayLiteral} exps
|
|
|
* @param {ArrayType} type
|
|
|
- * @returns {Promise<StoreValue[]>[]}
|
|
|
+ *
|
|
|
+ * @returns {Promise<StoreValue[][]>}
|
|
|
*/
|
|
|
- evaluateMatrix (store, exps, type, lines, columns) {
|
|
|
+ async evaluateMatrix (store, exps, type, lines, columns) {
|
|
|
const values = exps.value;
|
|
|
if(values.length !== lines) {
|
|
|
- return Promise.reject(ProcessorErrorFactory.invalid_number_lines_matrix(lines,exps.toString(),values.length, exps.sourceInfo));
|
|
|
+ throw ProcessorErrorFactory.invalid_number_lines_matrix(lines, exps.toString(), values.length,
|
|
|
+ exps.sourceInfo);
|
|
|
}
|
|
|
- return values.map( vector => {
|
|
|
+ const vectors = values.map( vector => {
|
|
|
const vec_type = new ArrayType(type.innerType, 1);
|
|
|
return this.evaluateVector(store, vector, vec_type, columns);
|
|
|
});
|
|
|
+ return await Promise.all(vectors);
|
|
|
}
|
|
|
|
|
|
- evaluateLiteral (_, exp) {
|
|
|
- return Promise.resolve(new StoreValue(exp.type, exp.value));
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @param {Store} _
|
|
|
+ * @param {import('../ast/expressions/literal').Literal} exp
|
|
|
+ *
|
|
|
+ * @returns {import('./store/value/istore_value').IStoreValue}
|
|
|
+ */
|
|
|
+ async evaluateLiteral (_, exp) {
|
|
|
+ return new StoreValue(exp.type, exp.value);
|
|
|
}
|
|
|
|
|
|
- evaluateVariableLiteral (store, exp) {
|
|
|
- try {
|
|
|
- const val = store.applyStore(exp.id);
|
|
|
- return Promise.resolve(val);
|
|
|
- } catch (error) {
|
|
|
- return Promise.reject(error);
|
|
|
- }
|
|
|
+
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @param {Store} store
|
|
|
+ * @param {Expressions.VariableLiteral} exp
|
|
|
+ *
|
|
|
+ * @returns {import('./store/value/istore_value').IStoreValue}
|
|
|
+ */
|
|
|
+ async evaluateVariableLiteral (store, exp) {
|
|
|
+ const val = store.applyStore(exp.id);
|
|
|
+ return val;
|
|
|
}
|
|
|
|
|
|
- evaluateArrayAccess (store, exp) {
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @param {Store} store
|
|
|
+ * @param {Expressions.ArrayAccess} exp
|
|
|
+ *
|
|
|
+ * @returns {import('./store/value/istore_value').IStoreValue}
|
|
|
+ */
|
|
|
+ async evaluateArrayAccess (store, exp) {
|
|
|
const mustBeArray = store.getStoreObject(exp.id);
|
|
|
if (!(mustBeArray.type instanceof ArrayType)) {
|
|
|
- return Promise.reject(ProcessorErrorFactory.invalid_array_access_full(exp.id, exp.sourceInfo));
|
|
|
+ throw ProcessorErrorFactory.invalid_array_access_full(exp.id, exp.sourceInfo);
|
|
|
}
|
|
|
- const $line = this.evaluateExpression(store, exp.line);
|
|
|
- const $column = this.evaluateExpression(store, exp.column);
|
|
|
- return Promise.all([$line, $column]).then(([line_sv, column_sv]) => {
|
|
|
- if(!Types.INTEGER.isCompatible(line_sv.type)) {
|
|
|
- return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(exp.sourceInfo));
|
|
|
- }
|
|
|
- const line = line_sv.get().toNumber();
|
|
|
- let column = null;
|
|
|
- if(column_sv !== null) {
|
|
|
- if(!Types.INTEGER.isCompatible(column_sv.type)) {
|
|
|
- return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(exp.sourceInfo));
|
|
|
- }
|
|
|
- column = column_sv.get().toNumber();
|
|
|
- }
|
|
|
-
|
|
|
- if (line >= mustBeArray.lines) {
|
|
|
- if(mustBeArray.isVector) {
|
|
|
- return Promise.reject(ProcessorErrorFactory.vector_line_outbounds_full(exp.id, line, mustBeArray.lines, exp.sourceInfo));
|
|
|
- } else {
|
|
|
- return Promise.reject(ProcessorErrorFactory.matrix_line_outbounds_full(exp.id, line, mustBeArray.lines, exp.sourceInfo));
|
|
|
- }
|
|
|
- } else if (line < 0) {
|
|
|
- return Promise.reject(ProcessorErrorFactory.array_dimension_not_positive_full(exp.sourceInfo));
|
|
|
- }
|
|
|
- if (column !== null && mustBeArray.columns === 0 ){
|
|
|
- return Promise.reject(ProcessorErrorFactory.vector_not_matrix_full(exp.id, exp.sourceInfo));
|
|
|
- }
|
|
|
- if(column !== null ) {
|
|
|
- if (column >= mustBeArray.columns) {
|
|
|
- return Promise.reject(ProcessorErrorFactory.matrix_column_outbounds_full(exp.id, column,mustBeArray.columns, exp.sourceInfo));
|
|
|
- } else if (column < 0) {
|
|
|
- return Promise.reject(ProcessorErrorFactory.array_dimension_not_positive_full(exp.sourceInfo));
|
|
|
- }
|
|
|
+ const lineSV = await this.evaluateExpression(store, exp.line);
|
|
|
+ if(!Types.INTEGER.isCompatible(lineSV.type)) {
|
|
|
+ throw ProcessorErrorFactory.array_dimension_not_int_full(exp.sourceInfo);
|
|
|
+ }
|
|
|
+ const line = lineSV.get().toNumber();
|
|
|
+ const columnSV = await this.evaluateExpression(store, exp.column);
|
|
|
+ let column = null;
|
|
|
+ if(columnSV !== null) {
|
|
|
+ if(!Types.INTEGER.isCompatible(columnSV.type)) {
|
|
|
+ throw ProcessorErrorFactory.array_dimension_not_int_full(exp.sourceInfo);
|
|
|
}
|
|
|
- const result = mustBeArray.getAt(line, column);
|
|
|
- const type = mustBeArray.type.innerType;
|
|
|
- if(Array.isArray(result)) {
|
|
|
- const values = result.map((v, c) => {
|
|
|
- return new StoreValueAddress(type, v, line, c, mustBeArray.id, mustBeArray.readOnly);
|
|
|
- });
|
|
|
- return Promise.resolve(new ArrayStoreValue(new ArrayType(type, 1),
|
|
|
- values, mustBeArray.columns, null, mustBeArray.id, mustBeArray.readOnly))
|
|
|
+ column = columnSV.get().toNumber();
|
|
|
+ }
|
|
|
+ if (line >= mustBeArray.lines) {
|
|
|
+ if (mustBeArray.isVector) {
|
|
|
+ throw ProcessorErrorFactory.vector_line_outbounds_full(exp.id, line, mustBeArray.lines,
|
|
|
+ exp.sourceInfo);
|
|
|
} else {
|
|
|
- return Promise.resolve(new StoreValueAddress(type, result, line, column, mustBeArray.id, mustBeArray.readOnly));
|
|
|
+ throw ProcessorErrorFactory.matrix_line_outbounds_full(exp.id, line, mustBeArray.lines,
|
|
|
+ exp.sourceInfo);
|
|
|
}
|
|
|
- });
|
|
|
+ } else if (line < 0) {
|
|
|
+ throw ProcessorErrorFactory.array_dimension_not_positive_full(exp.sourceInfo);
|
|
|
+ }
|
|
|
+ if (column !== null && mustBeArray.columns === 0 ){
|
|
|
+ throw ProcessorErrorFactory.vector_not_matrix_full(exp.id, exp.sourceInfo);
|
|
|
+ }
|
|
|
+ if (column !== null ) {
|
|
|
+ if (column >= mustBeArray.columns) {
|
|
|
+ throw ProcessorErrorFactory.matrix_column_outbounds_full(exp.id, column,mustBeArray.columns,
|
|
|
+ exp.sourceInfo);
|
|
|
+ } else if (column < 0) {
|
|
|
+ throw ProcessorErrorFactory.array_dimension_not_positive_full(exp.sourceInfo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const result = mustBeArray.getAt(line, column);
|
|
|
+ const type = mustBeArray.type.innerType;
|
|
|
+ if (Array.isArray(result)) {
|
|
|
+ const values = result.map((val, col) => {
|
|
|
+ return new StoreValueAddress(type, val, line, col, mustBeArray.id, mustBeArray.readOnly);
|
|
|
+ });
|
|
|
+ return new ArrayStoreValue(new ArrayType(type, 1),
|
|
|
+ values, mustBeArray.columns, null, mustBeArray.id, mustBeArray.readOnly);
|
|
|
+ } else {
|
|
|
+ return new StoreValueAddress(type, result, line, column, mustBeArray.id, mustBeArray.readOnly);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- evaluateUnaryApp (store, unaryApp) {
|
|
|
- const $left = this.evaluateExpression(store, unaryApp.left);
|
|
|
- return $left.then( left => {
|
|
|
- const resultType = resultTypeAfterUnaryOp(unaryApp.op, left.type);
|
|
|
- if (Types.UNDEFINED.isCompatible(resultType)) {
|
|
|
- const stringInfo = left.type.stringInfo();
|
|
|
- const info = stringInfo[0];
|
|
|
- return Promise.reject(ProcessorErrorFactory.invalid_unary_op_full(unaryApp.op, info.type, info.dim, unaryApp.sourceInfo));
|
|
|
- }
|
|
|
- switch (unaryApp.op.ord) {
|
|
|
- case Operators.ADD.ord:
|
|
|
- return new StoreValue(resultType, left.get());
|
|
|
- case Operators.SUB.ord:
|
|
|
- return new StoreValue(resultType, left.get().negated());
|
|
|
- case Operators.NOT.ord:
|
|
|
- return new StoreValue(resultType, !left.get());
|
|
|
- default:
|
|
|
- return Promise.reject(new RuntimeError('!!!Critical Invalid UnaryApp '+ unaryApp.op));
|
|
|
- }
|
|
|
- });
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @param {Store} store
|
|
|
+ * @param {Expressions.UnaryApp} unaryApp
|
|
|
+ *
|
|
|
+ * @returns {import('./store/value/istore_value').IStoreValue}
|
|
|
+ */
|
|
|
+ async evaluateUnaryApp (store, unaryApp) {
|
|
|
+ const left = await this.evaluateExpression(store, unaryApp.left);
|
|
|
+ const resultType = resultTypeAfterUnaryOp(unaryApp.op, left.type);
|
|
|
+ if (Types.UNDEFINED.isCompatible(resultType)) {
|
|
|
+ const stringInfo = left.type.stringInfo();
|
|
|
+ const info = stringInfo[0];
|
|
|
+ throw ProcessorErrorFactory.invalid_unary_op_full(unaryApp.op, info.type, info.dim,
|
|
|
+ unaryApp.sourceInfo);
|
|
|
+ }
|
|
|
+ switch (unaryApp.op.ord) {
|
|
|
+ case Operators.ADD.ord:
|
|
|
+ return new StoreValue(resultType, left.get());
|
|
|
+ case Operators.SUB.ord:
|
|
|
+ return new StoreValue(resultType, left.get().negated());
|
|
|
+ case Operators.NOT.ord:
|
|
|
+ return new StoreValue(resultType, !left.get());
|
|
|
+ default:
|
|
|
+ throw new RuntimeError('!!!Critical Invalid UnaryApp '+ unaryApp.op);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- evaluateInfixApp (store, infixApp) {
|
|
|
- const $left = this.evaluateExpression(store, infixApp.left);
|
|
|
- const $right = this.evaluateExpression(store, infixApp.right);
|
|
|
- return Promise.all([$left, $right]).then(values => {
|
|
|
- let shouldImplicitCast = false;
|
|
|
- const left = values[0];
|
|
|
- const right = values[1];
|
|
|
- let resultType = resultTypeAfterInfixOp(infixApp.op, left.type, right.type);
|
|
|
- if (Types.UNDEFINED.isCompatible(resultType)) {
|
|
|
- if (Config.enable_type_casting && Store.canImplicitTypeCast(left.type, right.type)) {
|
|
|
- shouldImplicitCast = true;
|
|
|
+ /**
|
|
|
+ *
|
|
|
+ * @param {Store} store
|
|
|
+ * @param {Expressions.InfixApp} infixApp
|
|
|
+ *
|
|
|
+ * @returns {import('./store/value/istore_value').IStoreValue}
|
|
|
+ */
|
|
|
+ async evaluateInfixApp (store, infixApp) {
|
|
|
+ const left = await this.evaluateExpression(store, infixApp.left);
|
|
|
+ const right = await this.evaluateExpression(store, infixApp.right);
|
|
|
+ let shouldImplicitCast = false;
|
|
|
+ let resultType = resultTypeAfterInfixOp(infixApp.op, left.type, right.type);
|
|
|
+ if (Types.UNDEFINED.isCompatible(resultType)) {
|
|
|
+ if (Config.enable_type_casting && Store.canImplicitTypeCast(left.type, right.type)) {
|
|
|
+ shouldImplicitCast = true;
|
|
|
+ } else {
|
|
|
+ const stringInfoLeft = left.type.stringInfo();
|
|
|
+ const infoLeft = stringInfoLeft[0];
|
|
|
+ const stringInfoRight = right.type.stringInfo();
|
|
|
+ const infoRight = stringInfoRight[0];
|
|
|
+ throw ProcessorErrorFactory.invalid_infix_op_full(infixApp.op, infoLeft.type, infoLeft.dim,
|
|
|
+ infoRight.type,infoRight.dim,infixApp.sourceInfo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ let result = null;
|
|
|
+ switch (infixApp.op.ord) {
|
|
|
+ case Operators.ADD.ord: {
|
|
|
+ if (Types.STRING.isCompatible(left.type)) {
|
|
|
+ const rightStr = convertToString(right.get(), right.type);
|
|
|
+ return new StoreValue(resultType, (left.get() + rightStr));
|
|
|
+ } else if (Types.STRING.isCompatible(right.type)) {
|
|
|
+ const leftStr = convertToString(left.get(), left.type);
|
|
|
+ return new StoreValue(resultType, (leftStr + right.get()));
|
|
|
} else {
|
|
|
- const stringInfoLeft = left.type.stringInfo();
|
|
|
- const infoLeft = stringInfoLeft[0];
|
|
|
- const stringInfoRight = right.type.stringInfo();
|
|
|
- const infoRight = stringInfoRight[0];
|
|
|
- return Promise.reject(ProcessorErrorFactory.invalid_infix_op_full(infixApp.op, infoLeft.type, infoLeft.dim,
|
|
|
- infoRight.type,infoRight.dim,infixApp.sourceInfo));
|
|
|
+ return new StoreValue(resultType, (left.get().plus(right.get())));
|
|
|
}
|
|
|
}
|
|
|
- let result = null;
|
|
|
- switch (infixApp.op.ord) {
|
|
|
- case Operators.ADD.ord: {
|
|
|
- if(Types.STRING.isCompatible(left.type)) {
|
|
|
- const rightStr = convertToString(right.get(), right.type);
|
|
|
- return new StoreValue(resultType, (left.get() + rightStr));
|
|
|
- } else if (Types.STRING.isCompatible(right.type)) {
|
|
|
- const leftStr = convertToString(left.get(), left.type);
|
|
|
- return new StoreValue(resultType, (leftStr + right.get()));
|
|
|
- } else {
|
|
|
- return new StoreValue(resultType, (left.get().plus(right.get())));
|
|
|
- }
|
|
|
- }
|
|
|
- case Operators.SUB.ord:
|
|
|
- return new StoreValue(resultType, (left.get().minus(right.get())));
|
|
|
- case Operators.MULT.ord: {
|
|
|
- result = left.get().times(right.get());
|
|
|
- return new StoreValue(resultType, result);
|
|
|
+ case Operators.SUB.ord:
|
|
|
+ return new StoreValue(resultType, (left.get().minus(right.get())));
|
|
|
+ case Operators.MULT.ord: {
|
|
|
+ result = left.get().times(right.get());
|
|
|
+ return new StoreValue(resultType, result);
|
|
|
+ }
|
|
|
+ case Operators.DIV.ord: {
|
|
|
+ if(right.get() == 0) {
|
|
|
+ throw ProcessorErrorFactory.divsion_by_zero_full(infixApp.toString(), infixApp.sourceInfo);
|
|
|
}
|
|
|
- case Operators.DIV.ord: {
|
|
|
- if(right.get() == 0) {
|
|
|
- return Promise.reject(ProcessorErrorFactory.divsion_by_zero_full(infixApp.toString(), infixApp.sourceInfo));
|
|
|
- }
|
|
|
- if (Types.INTEGER.isCompatible(resultType))
|
|
|
- result = left.get().divToInt(right.get());
|
|
|
- else
|
|
|
- result = left.get().div(right.get());
|
|
|
- return new StoreValue(resultType, (result));
|
|
|
+ if (Types.INTEGER.isCompatible(resultType))
|
|
|
+ result = left.get().divToInt(right.get());
|
|
|
+ else
|
|
|
+ result = left.get().div(right.get());
|
|
|
+ return new StoreValue(resultType, (result));
|
|
|
+ }
|
|
|
+ case Operators.MOD.ord: {
|
|
|
+ let leftValue = left.get();
|
|
|
+ let rightValue = right.get();
|
|
|
+ if(shouldImplicitCast) {
|
|
|
+ resultType = Types.INTEGER;
|
|
|
+ leftValue = leftValue.trunc();
|
|
|
+ rightValue = rightValue.trunc();
|
|
|
}
|
|
|
- case Operators.MOD.ord: {
|
|
|
- let leftValue = left.get();
|
|
|
- let rightValue = right.get();
|
|
|
- if(shouldImplicitCast) {
|
|
|
- resultType = Types.INTEGER;
|
|
|
+ result = leftValue.modulo(rightValue);
|
|
|
+ return new StoreValue(resultType, (result));
|
|
|
+ }
|
|
|
+ case Operators.GT.ord: {
|
|
|
+ let leftValue = left.get();
|
|
|
+ let rightValue = right.get();
|
|
|
+ if (Types.STRING.isCompatible(left.type)) {
|
|
|
+ result = leftValue.length > rightValue.length;
|
|
|
+ } else {
|
|
|
+ if (shouldImplicitCast) {
|
|
|
+ resultType = Types.BOOLEAN;
|
|
|
leftValue = leftValue.trunc();
|
|
|
rightValue = rightValue.trunc();
|
|
|
}
|
|
|
- result = leftValue.modulo(rightValue);
|
|
|
- return new StoreValue(resultType, (result));
|
|
|
- }
|
|
|
- case Operators.GT.ord: {
|
|
|
- let leftValue = left.get();
|
|
|
- let rightValue = right.get();
|
|
|
- if (Types.STRING.isCompatible(left.type)) {
|
|
|
- result = leftValue.length > rightValue.length;
|
|
|
- } else {
|
|
|
- if (shouldImplicitCast) {
|
|
|
- resultType = Types.BOOLEAN;
|
|
|
- leftValue = leftValue.trunc();
|
|
|
- rightValue = rightValue.trunc();
|
|
|
- }
|
|
|
- result = leftValue.gt(rightValue);
|
|
|
- }
|
|
|
- return new StoreValue(resultType, result);
|
|
|
+ result = leftValue.gt(rightValue);
|
|
|
}
|
|
|
- case Operators.GE.ord: {
|
|
|
- let leftValue = left.get();
|
|
|
- let rightValue = right.get();
|
|
|
- if (Types.STRING.isCompatible(left.type)) {
|
|
|
- result = leftValue.length >= rightValue.length;
|
|
|
- } else {
|
|
|
- if (shouldImplicitCast) {
|
|
|
- resultType = Types.BOOLEAN;
|
|
|
- leftValue = leftValue.trunc();
|
|
|
- rightValue = rightValue.trunc();
|
|
|
- }
|
|
|
- result = leftValue.gte(rightValue);
|
|
|
+ return new StoreValue(resultType, result);
|
|
|
+ }
|
|
|
+ case Operators.GE.ord: {
|
|
|
+ let leftValue = left.get();
|
|
|
+ let rightValue = right.get();
|
|
|
+ if (Types.STRING.isCompatible(left.type)) {
|
|
|
+ result = leftValue.length >= rightValue.length;
|
|
|
+ } else {
|
|
|
+ if (shouldImplicitCast) {
|
|
|
+ resultType = Types.BOOLEAN;
|
|
|
+ leftValue = leftValue.trunc();
|
|
|
+ rightValue = rightValue.trunc();
|
|
|
}
|
|
|
- return new StoreValue(resultType, result);
|
|
|
+ result = leftValue.gte(rightValue);
|
|
|
}
|
|
|
- case Operators.LT.ord: {
|
|
|
- let leftValue = left.get();
|
|
|
- let rightValue = right.get();
|
|
|
- if (Types.STRING.isCompatible(left.type)) {
|
|
|
- result = leftValue.length < rightValue.length;
|
|
|
- } else {
|
|
|
- if (shouldImplicitCast) {
|
|
|
- resultType = Types.BOOLEAN;
|
|
|
- leftValue = leftValue.trunc();
|
|
|
- rightValue = rightValue.trunc();
|
|
|
- }
|
|
|
- result = leftValue.lt(rightValue);
|
|
|
+ return new StoreValue(resultType, result);
|
|
|
+ }
|
|
|
+ case Operators.LT.ord: {
|
|
|
+ let leftValue = left.get();
|
|
|
+ let rightValue = right.get();
|
|
|
+ if (Types.STRING.isCompatible(left.type)) {
|
|
|
+ result = leftValue.length < rightValue.length;
|
|
|
+ } else {
|
|
|
+ if (shouldImplicitCast) {
|
|
|
+ resultType = Types.BOOLEAN;
|
|
|
+ leftValue = leftValue.trunc();
|
|
|
+ rightValue = rightValue.trunc();
|
|
|
}
|
|
|
- return new StoreValue(resultType, (result));
|
|
|
+ result = leftValue.lt(rightValue);
|
|
|
}
|
|
|
- case Operators.LE.ord: {
|
|
|
- let leftValue = left.get();
|
|
|
- let rightValue = right.get();
|
|
|
- if (Types.STRING.isCompatible(left.type)) {
|
|
|
- result = leftValue.length <= rightValue.length;
|
|
|
- } else {
|
|
|
- if (shouldImplicitCast) {
|
|
|
- resultType = Types.BOOLEAN;
|
|
|
- leftValue = leftValue.trunc();
|
|
|
- rightValue = rightValue.trunc();
|
|
|
- }
|
|
|
- result = leftValue.lte(rightValue);
|
|
|
+ return new StoreValue(resultType, (result));
|
|
|
+ }
|
|
|
+ case Operators.LE.ord: {
|
|
|
+ let leftValue = left.get();
|
|
|
+ let rightValue = right.get();
|
|
|
+ if (Types.STRING.isCompatible(left.type)) {
|
|
|
+ result = leftValue.length <= rightValue.length;
|
|
|
+ } else {
|
|
|
+ if (shouldImplicitCast) {
|
|
|
+ resultType = Types.BOOLEAN;
|
|
|
+ leftValue = leftValue.trunc();
|
|
|
+ rightValue = rightValue.trunc();
|
|
|
}
|
|
|
- return new StoreValue(resultType, result);
|
|
|
+ result = leftValue.lte(rightValue);
|
|
|
}
|
|
|
- case Operators.EQ.ord: {
|
|
|
- let leftValue = left.get();
|
|
|
- let rightValue = right.get();
|
|
|
- if (Types.INTEGER.isCompatible(left.type) || Types.REAL.isCompatible(left.type)) {
|
|
|
- if (shouldImplicitCast) {
|
|
|
- resultType = Types.BOOLEAN;
|
|
|
- leftValue = leftValue.trunc();
|
|
|
- rightValue = rightValue.trunc();
|
|
|
- }
|
|
|
- result = leftValue.eq(rightValue);
|
|
|
- } else {
|
|
|
- result = leftValue === rightValue;
|
|
|
+ return new StoreValue(resultType, result);
|
|
|
+ }
|
|
|
+ case Operators.EQ.ord: {
|
|
|
+ let leftValue = left.get();
|
|
|
+ let rightValue = right.get();
|
|
|
+ if (Types.INTEGER.isCompatible(left.type) || Types.REAL.isCompatible(left.type)) {
|
|
|
+ if (shouldImplicitCast) {
|
|
|
+ resultType = Types.BOOLEAN;
|
|
|
+ leftValue = leftValue.trunc();
|
|
|
+ rightValue = rightValue.trunc();
|
|
|
}
|
|
|
- return new StoreValue(resultType, result);
|
|
|
+ result = leftValue.eq(rightValue);
|
|
|
+ } else {
|
|
|
+ result = leftValue === rightValue;
|
|
|
}
|
|
|
- case Operators.NEQ.ord: {
|
|
|
- let leftValue = left.get();
|
|
|
- let rightValue = right.get();
|
|
|
- if (Types.INTEGER.isCompatible(left.type) || Types.REAL.isCompatible(left.type)) {
|
|
|
- if (shouldImplicitCast) {
|
|
|
- resultType = Types.BOOLEAN;
|
|
|
- leftValue = leftValue.trunc();
|
|
|
- rightValue = rightValue.trunc();
|
|
|
- }
|
|
|
- result = !leftValue.eq(rightValue);
|
|
|
- } else {
|
|
|
- result = leftValue !== rightValue;
|
|
|
+ return new StoreValue(resultType, result);
|
|
|
+ }
|
|
|
+ case Operators.NEQ.ord: {
|
|
|
+ let leftValue = left.get();
|
|
|
+ let rightValue = right.get();
|
|
|
+ if (Types.INTEGER.isCompatible(left.type) || Types.REAL.isCompatible(left.type)) {
|
|
|
+ if (shouldImplicitCast) {
|
|
|
+ resultType = Types.BOOLEAN;
|
|
|
+ leftValue = leftValue.trunc();
|
|
|
+ rightValue = rightValue.trunc();
|
|
|
}
|
|
|
- return new StoreValue(resultType, result);
|
|
|
+ result = !leftValue.eq(rightValue);
|
|
|
+ } else {
|
|
|
+ result = leftValue !== rightValue;
|
|
|
}
|
|
|
- case Operators.AND.ord:
|
|
|
- return new StoreValue(resultType, (left.get() && right.get()));
|
|
|
- case Operators.OR.ord:
|
|
|
- return new StoreValue(resultType, (left.get() || right.get()));
|
|
|
- default:
|
|
|
- return Promise.reject(new RuntimeError('!!!Critical Invalid InfixApp '+ infixApp.op));
|
|
|
+ return new StoreValue(resultType, result);
|
|
|
}
|
|
|
- });
|
|
|
+ case Operators.AND.ord:
|
|
|
+ return new StoreValue(resultType, (left.get() && right.get()));
|
|
|
+ case Operators.OR.ord:
|
|
|
+ return new StoreValue(resultType, (left.get() || right.get()));
|
|
|
+ default:
|
|
|
+ throw new RuntimeError('!!!Critical Invalid InfixApp '+ infixApp.op);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
}
|