|
@@ -1,5 +1,4 @@
|
|
import { Store } from './store/store';
|
|
import { Store } from './store/store';
|
|
-import { StoreObject } from './store/storeObject';
|
|
|
|
import { StoreObjectArray } from './store/storeObjectArray';
|
|
import { StoreObjectArray } from './store/storeObjectArray';
|
|
import { Modes } from './modes';
|
|
import { Modes } from './modes';
|
|
import { Context } from './context';
|
|
import { Context } from './context';
|
|
@@ -17,8 +16,11 @@ import { Config } from '../util/config';
|
|
import { ProcessorErrorFactory } from './error/processorErrorFactory';
|
|
import { ProcessorErrorFactory } from './error/processorErrorFactory';
|
|
import { RuntimeError } from './error/runtimeError';
|
|
import { RuntimeError } from './error/runtimeError';
|
|
import { Location } from '../memory/location';
|
|
import { Location } from '../memory/location';
|
|
-import { StoreValue } from './store/store_value';
|
|
|
|
-import { StoreValueRef } from './store/store_value_ref';
|
|
|
|
|
|
+import { StoreValue } from './store/value/store_value';
|
|
|
|
+import { StoreValueRef } from './store/value/store_value_ref';
|
|
|
|
+import { ArrayStoreValue } from './store/value/array_store_value';
|
|
|
|
+import { ArrayStoreValueRef } from './store/value/array_store_value_ref';
|
|
|
|
+import { StoreValueAddress } from './store/value/store_value_address';
|
|
|
|
|
|
export class IVProgProcessor {
|
|
export class IVProgProcessor {
|
|
|
|
|
|
@@ -126,7 +128,7 @@ export class IVProgProcessor {
|
|
|
|
|
|
runFunction (func, actualParameters, store) {
|
|
runFunction (func, actualParameters, store) {
|
|
const funcName = func.isMain ? IVProgProcessor.MAIN_INTERNAL_ID : func.name;
|
|
const funcName = func.isMain ? IVProgProcessor.MAIN_INTERNAL_ID : func.name;
|
|
- let funcStore = new Store(funcName);
|
|
|
|
|
|
+ const funcStore = new Store(funcName);
|
|
funcStore.extendStore(this.globalStore);
|
|
funcStore.extendStore(this.globalStore);
|
|
let returnStoreObject = null;
|
|
let returnStoreObject = null;
|
|
if(func.returnType instanceof ArrayType) {
|
|
if(func.returnType instanceof ArrayType) {
|
|
@@ -153,53 +155,65 @@ export class IVProgProcessor {
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
- associateParameters (formalList, actualList, callerStore, calleeStore) {
|
|
|
|
- const funcName = calleeStore.name === IVProgProcessor.MAIN_INTERNAL_ID ?
|
|
|
|
- LanguageDefinedFunction.getMainFunctionName() : calleeStore.name;
|
|
|
|
|
|
+ associateParameters (formal_params, effective_params, caller_store, callee_store) {
|
|
|
|
+ const funcName = callee_store.name === IVProgProcessor.MAIN_INTERNAL_ID ?
|
|
|
|
+ LanguageDefinedFunction.getMainFunctionName() : callee_store.name;
|
|
|
|
|
|
- if (formalList.length != actualList.length) {
|
|
|
|
- throw ProcessorErrorFactory.invalid_parameters_size(funcName, formalList.length, actualList.length);
|
|
|
|
|
|
+ if (formal_params.length != effective_params.length) {
|
|
|
|
+ throw ProcessorErrorFactory.invalid_parameters_size(funcName, formal_params.length, effective_params.length);
|
|
}
|
|
}
|
|
- const promises$ = actualList.map(actualParameter => this.evaluateExpression(callerStore, actualParameter));
|
|
|
|
|
|
+ const promises$ = effective_params.map(actual_param => this.evaluateExpression(caller_store, actual_param));
|
|
return Promise.all(promises$).then(values => {
|
|
return Promise.all(promises$).then(values => {
|
|
for (let i = 0; i < values.length; i++) {
|
|
for (let i = 0; i < values.length; i++) {
|
|
- const stoObj = values[i];
|
|
|
|
- // console.log(calleeStore.name);
|
|
|
|
- // console.log(stoObj);
|
|
|
|
- const exp = actualList[i];
|
|
|
|
|
|
+ const sto_value = values[i];
|
|
|
|
+ // console.log(callee_store.name);
|
|
|
|
+ // console.log(sto_value);
|
|
|
|
+ const exp = effective_params[i];
|
|
let shouldTypeCast = false;
|
|
let shouldTypeCast = false;
|
|
- const formalParameter = formalList[i];
|
|
|
|
- if(!formalParameter.type.isCompatible(stoObj.type)) {
|
|
|
|
|
|
+ const formalParameter = formal_params[i];
|
|
|
|
+ if(!formalParameter.type.isCompatible(sto_value.type)) {
|
|
if (Config.enable_type_casting && !formalParameter.byRef
|
|
if (Config.enable_type_casting && !formalParameter.byRef
|
|
- && Store.canImplicitTypeCast(formalParameter.type, stoObj.type)) {
|
|
|
|
|
|
+ && Store.canImplicitTypeCast(formalParameter.type, sto_value.type)) {
|
|
shouldTypeCast = true;
|
|
shouldTypeCast = true;
|
|
} else {
|
|
} else {
|
|
throw ProcessorErrorFactory.invalid_parameter_type(funcName, exp.toString());
|
|
throw ProcessorErrorFactory.invalid_parameter_type(funcName, exp.toString());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- if(formalParameter.byRef && !stoObj.inStore()) {
|
|
|
|
|
|
+ if(formalParameter.byRef && !sto_value.inStore()) {
|
|
throw ProcessorErrorFactory.invalid_ref(funcName, exp.toString());
|
|
throw ProcessorErrorFactory.invalid_ref(funcName, exp.toString());
|
|
}
|
|
}
|
|
|
|
|
|
if(formalParameter.byRef) {
|
|
if(formalParameter.byRef) {
|
|
|
|
+ const realObj = caller_store.getStoreObject(sto_value.id);
|
|
let ref = null;
|
|
let ref = null;
|
|
- if (stoObj instanceof StoreObjectArrayAddress) {
|
|
|
|
- ref = new StoreObjectArrayAddressRef(callerStore.getStoreObject(stoObj.id));
|
|
|
|
|
|
+ if(sto_value instanceof ArrayStoreValue) {
|
|
|
|
+ // it's a vector or matrix...
|
|
|
|
+ const values = sto_value.get();
|
|
|
|
+ const array_type = sto_value.type;
|
|
|
|
+ const addresses = values.map( v => realObj.getLocAddressOf(v.line, v.column));
|
|
|
|
+ const columns = sto_value.isVector() ? 0 : sto_value.columns;
|
|
|
|
+ ref = new ArrayStoreValueRef(array_type, values, addresses, sto_value.lines, columns, realObj.id);
|
|
} else {
|
|
} else {
|
|
- const realObj = callerStore.getStoreObject(stoObj.id);
|
|
|
|
- ref = new StoreValueRef(realObj.type, realObj.value, realObj.locAddress, realObj.id);
|
|
|
|
|
|
+ if(sto_value instanceof StoreValueAddress) {
|
|
|
|
+ const line = sto_value.line;
|
|
|
|
+ const column = sto_value.column;
|
|
|
|
+ ref = new StoreValueRef(sto_value.type, sto_value.get(),
|
|
|
|
+ realObj.getLocAddressOf(line, column), realObj.id);
|
|
|
|
+ } else {
|
|
|
|
+ ref = new StoreValueRef(sto_value.type, sto_value.get(), realObj.locAddress, realObj.id);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- calleeStore.insertStore(formalParameter.id, ref);
|
|
|
|
|
|
+ callee_store.insertStore(formalParameter.id, ref);
|
|
} else {
|
|
} else {
|
|
- let realValue = stoObj;
|
|
|
|
|
|
+ let realValue = sto_value;
|
|
if (shouldTypeCast) {
|
|
if (shouldTypeCast) {
|
|
realValue = Store.doImplicitCasting(formalParameter.type, realValue);
|
|
realValue = Store.doImplicitCasting(formalParameter.type, realValue);
|
|
}
|
|
}
|
|
- calleeStore.insertStore(formalParameter.id, realValue);
|
|
|
|
|
|
+ callee_store.insertStore(formalParameter.id, realValue);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- return calleeStore;
|
|
|
|
|
|
+ return callee_store;
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
@@ -454,7 +468,7 @@ export class IVProgProcessor {
|
|
const info = stringInfo[0];
|
|
const info = stringInfo[0];
|
|
return Promise.reject(ProcessorErrorFactory.invalid_return_type_full(funcName, info.type, info.dim, cmd.sourceInfo));
|
|
return Promise.reject(ProcessorErrorFactory.invalid_return_type_full(funcName, info.type, info.dim, cmd.sourceInfo));
|
|
} else {
|
|
} else {
|
|
- let realValue = this.parseStoreObjectValue(vl);
|
|
|
|
|
|
+ const realValue = this.parseStoreObjectValue(vl);
|
|
store.updateStore('$', realValue);
|
|
store.updateStore('$', realValue);
|
|
store.mode = Modes.RETURN;
|
|
store.mode = Modes.RETURN;
|
|
return Promise.resolve(store);
|
|
return Promise.resolve(store);
|
|
@@ -549,7 +563,7 @@ export class IVProgProcessor {
|
|
const type = mustBeArray.type.innerType;
|
|
const type = mustBeArray.type.innerType;
|
|
const stringInfo = type.stringInfo();
|
|
const stringInfo = type.stringInfo();
|
|
const info = stringInfo[0];
|
|
const info = stringInfo[0];
|
|
- const exp = cmd.expression.toString();
|
|
|
|
|
|
+ // const exp = cmd.expression.toString();
|
|
return Promise.reject(ProcessorErrorFactory.incompatible_types_full(info.type, info.dim, cmd.sourceInfo));
|
|
return Promise.reject(ProcessorErrorFactory.incompatible_types_full(info.type, info.dim, cmd.sourceInfo));
|
|
}
|
|
}
|
|
actualValue = Store.doImplicitCasting(mustBeArray.type.innerType, value);
|
|
actualValue = Store.doImplicitCasting(mustBeArray.type.innerType, value);
|
|
@@ -583,66 +597,14 @@ export class IVProgProcessor {
|
|
try {
|
|
try {
|
|
let $value = Promise.resolve(null);
|
|
let $value = Promise.resolve(null);
|
|
if(cmd instanceof Commands.ArrayDeclaration) {
|
|
if(cmd instanceof Commands.ArrayDeclaration) {
|
|
- if(cmd.initial !== null) {
|
|
|
|
- // array can only be initialized by a literal....
|
|
|
|
- $value = this.evaluateArrayLiteral(store, cmd.initial, cmd.type);
|
|
|
|
- }
|
|
|
|
- const $lines = this.evaluateExpression(store, cmd.lines);
|
|
|
|
- const $columns = cmd.columns === null ? null: this.evaluateExpression(store, cmd.columns);
|
|
|
|
- return Promise.all([$lines, $columns, $value]).then(values => {
|
|
|
|
- const lineSO = values[0];
|
|
|
|
- if(!Types.INTEGER.isCompatible(lineSO.type)) {
|
|
|
|
- return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(cmd.sourceInfo));
|
|
|
|
- }
|
|
|
|
- const line = lineSO.get();
|
|
|
|
- if(line < 0) {
|
|
|
|
- throw ProcessorErrorFactory.array_dimension_not_positive_full(cmd.sourceInfo);
|
|
|
|
- }
|
|
|
|
- const columnSO = values[1];
|
|
|
|
- let column = null
|
|
|
|
- if (columnSO !== null) {
|
|
|
|
- if(!Types.INTEGER.isCompatible(columnSO.type)) {
|
|
|
|
- return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(cmd.sourceInfo));
|
|
|
|
- }
|
|
|
|
- column = columnSO.get();
|
|
|
|
- if(column < 0) {
|
|
|
|
- throw ProcessorErrorFactory.array_dimension_not_positive_full(cmd.sourceInfo);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- const value = values[2];
|
|
|
|
- const temp = new StoreObjectArray(cmd.type, line, column, null);
|
|
|
|
- store.insertStore(cmd.id, temp);
|
|
|
|
- let realValue = value;
|
|
|
|
- if (value !== null) {
|
|
|
|
- if(value instanceof StoreObjectArrayAddress) {
|
|
|
|
- if(value.type instanceof ArrayType) {
|
|
|
|
- realValue = Object.assign(new StoreObjectArray(null,null,null), value.refValue);
|
|
|
|
- } else {
|
|
|
|
- // TODO - update StoObj
|
|
|
|
- realValue = Object.assign(new StoreObject(null,null), value.refValue);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- realValue = new StoreObjectArray(cmd.type, line, column, [])
|
|
|
|
- if(column !== null) {
|
|
|
|
- for (let i = 0; i < line; i++) {
|
|
|
|
- realValue.value.push(new StoreObjectArray(new ArrayType(cmd.type.innerType, 1), column, null, []));
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- realValue.readOnly = cmd.isConst;
|
|
|
|
- store.updateStore(cmd.id, realValue);
|
|
|
|
- return store;
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
|
|
+ return this.executeArrayDeclaration(store, cmd);
|
|
} else {
|
|
} else {
|
|
if(cmd.initial !== null) {
|
|
if(cmd.initial !== null) {
|
|
$value = this.evaluateExpression(store, cmd.initial);
|
|
$value = this.evaluateExpression(store, cmd.initial);
|
|
}
|
|
}
|
|
- const temp = new StoreValue(cmd.type, null);
|
|
|
|
- store.insertStore(cmd.id, temp);
|
|
|
|
return $value.then(vl => {
|
|
return $value.then(vl => {
|
|
let realValue = vl;
|
|
let realValue = vl;
|
|
|
|
+ let temp = null;
|
|
if (vl !== null) {
|
|
if (vl !== null) {
|
|
if(!vl.type.isCompatible(cmd.type)) {
|
|
if(!vl.type.isCompatible(cmd.type)) {
|
|
if(Config.enable_type_casting && Store.canImplicitTypeCast(cmd.type, vl.type)) {
|
|
if(Config.enable_type_casting && Store.canImplicitTypeCast(cmd.type, vl.type)) {
|
|
@@ -653,19 +615,11 @@ export class IVProgProcessor {
|
|
return Promise.reject(ProcessorErrorFactory.incompatible_types_full(info.type, info.dim, cmd.sourceInfo));
|
|
return Promise.reject(ProcessorErrorFactory.incompatible_types_full(info.type, info.dim, cmd.sourceInfo));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- if(vl instanceof StoreObjectArrayAddress) {
|
|
|
|
- if(vl.type instanceof ArrayType) {
|
|
|
|
- return Promise.reject(new Error("!!!Critical Error: Compatibility check failed, a Type accepts a ArrayType"))
|
|
|
|
- } else {
|
|
|
|
- // TODO - update StoObj
|
|
|
|
- realValue = Object.assign(new StoreObject(null,null), vl.refValue);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ temp = new StoreValue(cmd.type, realValue.get(), null, cmd.isConst);
|
|
} else {
|
|
} else {
|
|
- realValue = new StoreValue(cmd.type, 0);
|
|
|
|
|
|
+ temp = new StoreValue(cmd.type, null, null, cmd.isConst);
|
|
}
|
|
}
|
|
- realValue.isConst = cmd.isConst;
|
|
|
|
- store.updateStore(cmd.id, realValue);
|
|
|
|
|
|
+ store.insertStore(cmd.id, temp);
|
|
return store;
|
|
return store;
|
|
});
|
|
});
|
|
}
|
|
}
|
|
@@ -674,6 +628,50 @@ export class IVProgProcessor {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ *
|
|
|
|
+ * @param {Store} store
|
|
|
|
+ * @param {Commands.ArrayDeclaration} cmd
|
|
|
|
+ */
|
|
|
|
+ executeArrayDeclaration (store, cmd) {
|
|
|
|
+ const $lines = this.evaluateExpression(store, cmd.lines);
|
|
|
|
+ const $columns = cmd.columns === null ? null: this.evaluateExpression(store, cmd.columns);
|
|
|
|
+ return Promise.all([$lines, $columns]).then(([line_sv, column_sv]) => {
|
|
|
|
+ if(!Types.INTEGER.isCompatible(line_sv.type)) {
|
|
|
|
+ return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(cmd.sourceInfo));
|
|
|
|
+ }
|
|
|
|
+ const line = line_sv.get().toNumber();
|
|
|
|
+ if(line < 0) {
|
|
|
|
+ throw ProcessorErrorFactory.array_dimension_not_positive_full(cmd.sourceInfo);
|
|
|
|
+ }
|
|
|
|
+ let column = null
|
|
|
|
+ if (column_sv !== null) {
|
|
|
|
+ if(!Types.INTEGER.isCompatible(column_sv.type)) {
|
|
|
|
+ return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(cmd.sourceInfo));
|
|
|
|
+ }
|
|
|
|
+ column = column_sv.get().toNumber();
|
|
|
|
+ if(column < 0) {
|
|
|
|
+ throw ProcessorErrorFactory.array_dimension_not_positive_full(cmd.sourceInfo);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ let $value = Promise.resolve(null);
|
|
|
|
+ if(cmd.initial !== null) {
|
|
|
|
+ // array can only be initialized by a literal....
|
|
|
|
+ $value = this.evaluateArrayLiteral(store, cmd.initial, cmd.type, line, column);
|
|
|
|
+ }
|
|
|
|
+ return $value.then(vector_list => {
|
|
|
|
+ let temp = null;
|
|
|
|
+ if (vector_list !== null) {
|
|
|
|
+ temp = new ArrayStoreValue(cmd.type, vector_list, line, column, null, cmd.isConst);
|
|
|
|
+ } else {
|
|
|
|
+ temp = new ArrayStoreValue(cmd.type, [], line, column, null, cmd.isConst);
|
|
|
|
+ }
|
|
|
|
+ store.insertStore(cmd.id, temp);
|
|
|
|
+ return store;
|
|
|
|
+ })
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+
|
|
evaluateExpression (store, exp) {
|
|
evaluateExpression (store, exp) {
|
|
if (exp instanceof Expressions.UnaryApp) {
|
|
if (exp instanceof Expressions.UnaryApp) {
|
|
return this.evaluateUnaryApp(store, exp);
|
|
return this.evaluateUnaryApp(store, exp);
|
|
@@ -728,57 +726,22 @@ export class IVProgProcessor {
|
|
* @param {Expressions.ArrayLiteral} exp
|
|
* @param {Expressions.ArrayLiteral} exp
|
|
* @param {ArrayType} type
|
|
* @param {ArrayType} type
|
|
*/
|
|
*/
|
|
- evaluateArrayLiteral (store, exp, type) {
|
|
|
|
- const errorHelperFunction = (validationResult, exp) => {
|
|
|
|
- const errorCode = validationResult[0];
|
|
|
|
- let expectedColumns = null;
|
|
|
|
- let actualColumns = null;
|
|
|
|
- switch(errorCode) {
|
|
|
|
- case StoreObjectArray.WRONG_COLUMN_NUMBER: {
|
|
|
|
- expectedColumns = validationResult[1];
|
|
|
|
- actualColumns = validationResult[2];
|
|
|
|
- return Promise.reject(ProcessorErrorFactory.invalid_array_literal_column_full(expectedColumns, actualColumns, exp.sourceInfo));
|
|
|
|
- }
|
|
|
|
- case StoreObjectArray.WRONG_LINE_NUMBER: {
|
|
|
|
- const lineValue = validationResult[1];
|
|
|
|
- return Promise.reject(ProcessorErrorFactory.invalid_array_literal_line_full(arr.lines, lineValue, exp.sourceInfo));
|
|
|
|
- }
|
|
|
|
- case StoreObjectArray.WRONG_TYPE: {
|
|
|
|
- let line = null;
|
|
|
|
- let strExp = null;
|
|
|
|
- if (validationResult.length > 2) {
|
|
|
|
- line = validationResult[1];
|
|
|
|
- const column = validationResult[2];
|
|
|
|
- strExp = exp.value[line].value[column].toString()
|
|
|
|
- } else {
|
|
|
|
- line = validationResult[1];
|
|
|
|
- strExp = exp.value[line].toString()
|
|
|
|
- }
|
|
|
|
- // TODO - fix error message
|
|
|
|
- return Promise.reject(ProcessorErrorFactory.invalid_array_literal_type_full(strExp, exp.sourceInfo)); }
|
|
|
|
- }
|
|
|
|
- };
|
|
|
|
|
|
+ evaluateArrayLiteral (store, exp, type, lines, columns) {
|
|
if(!exp.isVector) {
|
|
if(!exp.isVector) {
|
|
- const $matrix = this.evaluateMatrix(store, exp.value, type);
|
|
|
|
- return $matrix.then(list => {
|
|
|
|
- const arr = new StoreObjectArray(type, list.length, list[0].lines, list);
|
|
|
|
- const checkResult = arr.isValid;
|
|
|
|
- if(checkResult.length == 0)
|
|
|
|
- return Promise.resolve(arr);
|
|
|
|
- else {
|
|
|
|
- return errorHelperFunction(checkResult, exp);
|
|
|
|
- }
|
|
|
|
|
|
+ if(columns == null) {
|
|
|
|
+ throw new Error("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);
|
|
});
|
|
});
|
|
} else {
|
|
} else {
|
|
- return this.evaluateVector(store, exp.value, type).then(list => {
|
|
|
|
- const type = new ArrayType(list[0].type, 1);
|
|
|
|
- const stoArray = new StoreObjectArray(type, list.length, null, list);
|
|
|
|
- const checkResult = stoArray.isValid;
|
|
|
|
- if(checkResult.length == 0)
|
|
|
|
- return Promise.resolve(stoArray);
|
|
|
|
- else {
|
|
|
|
- return errorHelperFunction(checkResult, exp);
|
|
|
|
- }
|
|
|
|
|
|
+ if(columns != null) {
|
|
|
|
+ throw new Error("Matrix cannot be initialized by a vector");
|
|
|
|
+ }
|
|
|
|
+ return this.evaluateVector(store, exp, type, lines).then(list => {
|
|
|
|
+ return Promise.resolve(list);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -786,21 +749,26 @@ export class IVProgProcessor {
|
|
/**
|
|
/**
|
|
* Evalautes a list of literals and expression composing the vector
|
|
* Evalautes a list of literals and expression composing the vector
|
|
* @param {Store} store
|
|
* @param {Store} store
|
|
- * @param {Literal[]} exps
|
|
|
|
|
|
+ * @param {Expressions.ArrayLiteral} exps
|
|
* @param {ArrayType} type
|
|
* @param {ArrayType} type
|
|
- * @returns {Promise<StoreObject[]>} store object list
|
|
|
|
|
|
+ * @param {number} n_elements
|
|
|
|
+ * @returns {Promise<StoreValue[]>} store object list
|
|
*/
|
|
*/
|
|
- evaluateVector (store, exps, type) {
|
|
|
|
- const actual_values = Promise.all(exps.map( exp => this.evaluateExpression(store, exp)));
|
|
|
|
|
|
+ evaluateVector (store, exps, type, n_elements) {
|
|
|
|
+ const values = exps.value;
|
|
|
|
+ if(n_elements !== values.length) {
|
|
|
|
+ throw new Error("invalid number of elements to array literal...");
|
|
|
|
+ }
|
|
|
|
+ const actual_values = Promise.all(values.map( exp => this.evaluateExpression(store, exp)));
|
|
return actual_values.then( values => {
|
|
return actual_values.then( values => {
|
|
return values.map((v, index) => {
|
|
return values.map((v, index) => {
|
|
if(!type.canAccept(v.type)) {
|
|
if(!type.canAccept(v.type)) {
|
|
if (!Config.enable_type_casting || !Store.canImplicitTypeCast(type.innerType, v.type)) {
|
|
if (!Config.enable_type_casting || !Store.canImplicitTypeCast(type.innerType, v.type)) {
|
|
- const stringInfo = v.type.stringInfo();
|
|
|
|
- const info = stringInfo[0];
|
|
|
|
- const exp_str = exps[index].toString();
|
|
|
|
|
|
+ // const stringInfo = v.type.stringInfo();
|
|
|
|
+ // const info = stringInfo[0];
|
|
|
|
+ const exp_str = values[index].toString();
|
|
// TODO - fix error message
|
|
// TODO - fix error message
|
|
- throw ProcessorErrorFactory.invalid_array_literal_type_full(exp_str, exps[index].sourceInfo);
|
|
|
|
|
|
+ throw ProcessorErrorFactory.invalid_array_literal_type_full(exp_str, values[index].sourceInfo);
|
|
}
|
|
}
|
|
const new_value = Store.doImplicitCasting(type.innerType, v);
|
|
const new_value = Store.doImplicitCasting(type.innerType, v);
|
|
return new_value;
|
|
return new_value;
|
|
@@ -813,17 +781,19 @@ export class IVProgProcessor {
|
|
/**
|
|
/**
|
|
* Evaluates a list of array literals composing the matrix
|
|
* Evaluates a list of array literals composing the matrix
|
|
* @param {Store} store
|
|
* @param {Store} store
|
|
- * @param {Expressions.ArrayLiteral[]} exps
|
|
|
|
- * @param {ArrayType} type
|
|
|
|
|
|
+ * @param {Expressions.ArrayLiteral} exps
|
|
|
|
+ * @param {ArrayType} type
|
|
|
|
+ * @returns {Promise<StoreValue[]>[]}
|
|
*/
|
|
*/
|
|
- evaluateMatrix (store, exps, type) {
|
|
|
|
- return Promise.all(exps.map( vector => {
|
|
|
|
|
|
+ evaluateMatrix (store, exps, type, lines, columns) {
|
|
|
|
+ const values = exps.value;
|
|
|
|
+ if(values.length !== lines) {
|
|
|
|
+ throw new Error("Invalid number of lines to matrix literal...");
|
|
|
|
+ }
|
|
|
|
+ return values.map( vector => {
|
|
const vec_type = new ArrayType(type.innerType, 1);
|
|
const vec_type = new ArrayType(type.innerType, 1);
|
|
- const $vector = this.evaluateVector(store, vector.value, vec_type);
|
|
|
|
- return $vector.then(list => {
|
|
|
|
- return new StoreObjectArray(vec_type, list.length, null, list)
|
|
|
|
- });
|
|
|
|
- } ));
|
|
|
|
|
|
+ return this.evaluateVector(store, vector, vec_type, columns);
|
|
|
|
+ });
|
|
}
|
|
}
|
|
|
|
|
|
evaluateLiteral (_, exp) {
|
|
evaluateLiteral (_, exp) {
|
|
@@ -833,36 +803,35 @@ export class IVProgProcessor {
|
|
evaluateVariableLiteral (store, exp) {
|
|
evaluateVariableLiteral (store, exp) {
|
|
try {
|
|
try {
|
|
const val = store.applyStore(exp.id);
|
|
const val = store.applyStore(exp.id);
|
|
- if (val instanceof StoreObjectArray) {
|
|
|
|
- return Promise.resolve(Object.assign(new StoreObjectArray(null,null,null,null), val));
|
|
|
|
- } else {
|
|
|
|
- return Promise.resolve(val);
|
|
|
|
- }
|
|
|
|
|
|
+ return Promise.resolve(val);
|
|
|
|
+ // if (val instanceof StoreObjectArray) {
|
|
|
|
+ // return Promise.resolve(Object.assign(new StoreObjectArray(null,null,null,null), val));
|
|
|
|
+ // } else {
|
|
|
|
+ // return Promise.resolve(val);
|
|
|
|
+ // }
|
|
} catch (error) {
|
|
} catch (error) {
|
|
return Promise.reject(error);
|
|
return Promise.reject(error);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
evaluateArrayAccess (store, exp) {
|
|
evaluateArrayAccess (store, exp) {
|
|
- const mustBeArray = store.applyStore(exp.id);
|
|
|
|
|
|
+ const mustBeArray = store.getStoreObject(exp.id);
|
|
if (!(mustBeArray.type instanceof ArrayType)) {
|
|
if (!(mustBeArray.type instanceof ArrayType)) {
|
|
return Promise.reject(ProcessorErrorFactory.invalid_array_access_full(exp.id, exp.sourceInfo));
|
|
return Promise.reject(ProcessorErrorFactory.invalid_array_access_full(exp.id, exp.sourceInfo));
|
|
}
|
|
}
|
|
const $line = this.evaluateExpression(store, exp.line);
|
|
const $line = this.evaluateExpression(store, exp.line);
|
|
const $column = this.evaluateExpression(store, exp.column);
|
|
const $column = this.evaluateExpression(store, exp.column);
|
|
- return Promise.all([$line, $column]).then(values => {
|
|
|
|
- const lineSO = values[0];
|
|
|
|
- const columnSO = values[1];
|
|
|
|
- if(!Types.INTEGER.isCompatible(lineSO.type)) {
|
|
|
|
|
|
+ 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));
|
|
return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(exp.sourceInfo));
|
|
}
|
|
}
|
|
- const line = lineSO.get();
|
|
|
|
|
|
+ const line = line_sv.get().toNumber();
|
|
let column = null;
|
|
let column = null;
|
|
- if(columnSO !== null) {
|
|
|
|
- if(!Types.INTEGER.isCompatible(columnSO.type)) {
|
|
|
|
|
|
+ if(column_sv !== null) {
|
|
|
|
+ if(!Types.INTEGER.isCompatible(column_sv.type)) {
|
|
return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(exp.sourceInfo));
|
|
return Promise.reject(ProcessorErrorFactory.array_dimension_not_int_full(exp.sourceInfo));
|
|
}
|
|
}
|
|
- column = columnSO.get();
|
|
|
|
|
|
+ column = column_sv.get().toNumber();
|
|
}
|
|
}
|
|
|
|
|
|
if (line >= mustBeArray.lines) {
|
|
if (line >= mustBeArray.lines) {
|
|
@@ -874,7 +843,7 @@ export class IVProgProcessor {
|
|
} else if (line < 0) {
|
|
} else if (line < 0) {
|
|
throw ProcessorErrorFactory.array_dimension_not_positive_full(exp.sourceInfo);
|
|
throw ProcessorErrorFactory.array_dimension_not_positive_full(exp.sourceInfo);
|
|
}
|
|
}
|
|
- if (column !== null && mustBeArray.columns === null ){
|
|
|
|
|
|
+ if (column !== null && mustBeArray.columns === 0 ){
|
|
return Promise.reject(ProcessorErrorFactory.vector_not_matrix_full(exp.id, exp.sourceInfo));
|
|
return Promise.reject(ProcessorErrorFactory.vector_not_matrix_full(exp.id, exp.sourceInfo));
|
|
}
|
|
}
|
|
if(column !== null ) {
|
|
if(column !== null ) {
|
|
@@ -883,9 +852,24 @@ export class IVProgProcessor {
|
|
} else if (column < 0) {
|
|
} else if (column < 0) {
|
|
throw ProcessorErrorFactory.array_dimension_not_positive_full(exp.sourceInfo);
|
|
throw ProcessorErrorFactory.array_dimension_not_positive_full(exp.sourceInfo);
|
|
}
|
|
}
|
|
-
|
|
|
|
}
|
|
}
|
|
- return Promise.resolve(new StoreObjectArrayAddress(mustBeArray.id, line, column, store));
|
|
|
|
|
|
+ const result = mustBeArray.getAt(line, column);
|
|
|
|
+ const type = mustBeArray.type.innerType;
|
|
|
|
+ if(Array.isArray(result)) {
|
|
|
|
+ let l = 0;
|
|
|
|
+ const values = result.map(v => {
|
|
|
|
+ if(!Array.isArray(v)) {
|
|
|
|
+ return new StoreValueAddress(type.innerType, v, l++, undefined, mustBeArray.id, mustBeArray.readOnly);
|
|
|
|
+ } else {
|
|
|
|
+ throw new Error("Indexing 3D structure....");
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ return Promise.resolve(new ArrayStoreValue(new ArrayType(type, 1),
|
|
|
|
+ values, mustBeArray.columns, null, mustBeArray.id, mustBeArray.readOnly))
|
|
|
|
+ } else {
|
|
|
|
+ return Promise.resolve(new StoreValueAddress(type, result, line, column, mustBeArray.id, mustBeArray.readOnly));
|
|
|
|
+ }
|
|
|
|
+ //return Promise.resolve(mustBeArray.getAt(line, column));
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|