|
@@ -6,7 +6,10 @@ import { Operators } from './../ast/operators';
|
|
|
import { LanguageDefinedFunction } from './definedFunctions';
|
|
|
import { resultTypeAfterInfixOp, resultTypeAfterUnaryOp } from './compatibilityTable';
|
|
|
import * as Commands from './../ast/commands/';
|
|
|
+
|
|
|
+import { Command } from './../ast/commands/command'
|
|
|
import * as Expressions from './../ast/expressions/';
|
|
|
+import * as Utils from './../util/utils';
|
|
|
import { ArrayType } from './../typeSystem/array_type';
|
|
|
import { convertToString, toInt } from '../typeSystem/parsers';
|
|
|
import { Config } from '../util/config';
|
|
@@ -85,21 +88,20 @@ export class IVProgProcessor {
|
|
|
this.mode = Modes.RUN;
|
|
|
}
|
|
|
|
|
|
- interpretAST () {
|
|
|
+ async interpretAST () {
|
|
|
this.prepareState();
|
|
|
Location.clear();
|
|
|
- return this.initGlobal().then( _ => {
|
|
|
- const mainFunc = this.findMainFunction();
|
|
|
- if(mainFunc === null) {
|
|
|
- return Promise.reject(ProcessorErrorFactory.main_missing())
|
|
|
- }
|
|
|
- return this.runFunction(mainFunc, [], this.globalStore);
|
|
|
- });
|
|
|
+ await this.initGlobal();
|
|
|
+ const mainFunc = this.findMainFunction();
|
|
|
+ if (mainFunc === null) {
|
|
|
+ throw ProcessorErrorFactory.main_missing();
|
|
|
+ }
|
|
|
+ return this.runFunction(mainFunc, [], this.globalStore);
|
|
|
}
|
|
|
|
|
|
- initGlobal () {
|
|
|
+ async initGlobal () {
|
|
|
if(!this.checkContext(Context.BASE)) {
|
|
|
- return Promise.reject(ProcessorErrorFactory.invalid_global_var())
|
|
|
+ return ProcessorErrorFactory.invalid_global_var();
|
|
|
}
|
|
|
return this.executeCommands(this.globalStore, this.ast.global);
|
|
|
}
|
|
@@ -127,154 +129,147 @@ export class IVProgProcessor {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- runFunction (func, actualParameters, store) {
|
|
|
+ async runFunction (func, actualParameters, store) {
|
|
|
const funcName = func.isMain ? IVProgProcessor.MAIN_INTERNAL_ID : func.name;
|
|
|
const funcStore = new Store(funcName);
|
|
|
funcStore.extendStore(this.globalStore);
|
|
|
- return new Promise((resolve, reject) => {
|
|
|
- const run_lambda = () => {
|
|
|
- const newFuncStore$ = this.associateParameters(func.formalParameters, actualParameters, store, funcStore);
|
|
|
- newFuncStore$.then(sto => {
|
|
|
- this.context.push(Context.FUNCTION);
|
|
|
- this.stores.push(sto);
|
|
|
- return this.executeCommands(sto, func.variablesDeclarations)
|
|
|
- .then(stoWithVars => this.executeCommands(stoWithVars, func.commands)).then(finalSto => {
|
|
|
- this.stores.pop();
|
|
|
- this.context.pop();
|
|
|
- return finalSto;
|
|
|
- });
|
|
|
- }).then(resolve)
|
|
|
- .catch(reject);
|
|
|
- }
|
|
|
- run_lambda();
|
|
|
- });
|
|
|
-
|
|
|
+ await this.associateParameters(func.formalParameters, actualParameters, store, funcStore);
|
|
|
+ this.context.push(Context.FUNCTION);
|
|
|
+ this.stores.push(funcStore);
|
|
|
+ const stoWithVars = await this.executeCommands(funcStore, func.variablesDeclarations);
|
|
|
+ const finalSto = this.executeCommands(stoWithVars, func.commands);
|
|
|
+ this.stores.pop();
|
|
|
+ this.context.pop();
|
|
|
+ return finalSto;
|
|
|
}
|
|
|
|
|
|
- associateParameters (formal_params, effective_params, caller_store, callee_store) {
|
|
|
+ async associateParameters (formal_params, effective_params, caller_store, callee_store) {
|
|
|
const funcName = callee_store.name === IVProgProcessor.MAIN_INTERNAL_ID ?
|
|
|
LanguageDefinedFunction.getMainFunctionName() : callee_store.name;
|
|
|
|
|
|
if (formal_params.length != effective_params.length) {
|
|
|
- return Promise.reject(ProcessorErrorFactory.invalid_parameters_size(funcName, formal_params.length, effective_params.length))
|
|
|
+ throw ProcessorErrorFactory.invalid_parameters_size(funcName, formal_params.length, effective_params.length);
|
|
|
}
|
|
|
- const promises$ = effective_params.map(actual_param => this.evaluateExpression(caller_store, actual_param));
|
|
|
- return Promise.all(promises$).then(values => {
|
|
|
- for (let i = 0; i < values.length; i++) {
|
|
|
- const sto_value = values[i];
|
|
|
-
|
|
|
-
|
|
|
- const exp = effective_params[i];
|
|
|
- let shouldTypeCast = false;
|
|
|
- const formalParameter = formal_params[i];
|
|
|
- if(!formalParameter.type.isCompatible(sto_value.type)) {
|
|
|
- if (Config.enable_type_casting && !formalParameter.byRef
|
|
|
- && Store.canImplicitTypeCast(formalParameter.type, sto_value.type)) {
|
|
|
- shouldTypeCast = true;
|
|
|
- } else {
|
|
|
- return Promise.reject(ProcessorErrorFactory.invalid_parameter_type(funcName, exp.toString()))
|
|
|
- }
|
|
|
+ for (let i = 0; i < effective_params.length; i += 1) {
|
|
|
+ const actualParam = effective_params[i];
|
|
|
+ const actualValue = await this.evaluateExpression(caller_store, actualParam);
|
|
|
+ const exp = effective_params[i];
|
|
|
+ let shouldTypeCast = false;
|
|
|
+ const formalParameter = formal_params[i];
|
|
|
+ if(!formalParameter.type.isCompatible(actualValue.type)) {
|
|
|
+ if (Config.enable_type_casting && !formalParameter.byRef
|
|
|
+ && Store.canImplicitTypeCast(formalParameter.type, actualValue.type)) {
|
|
|
+ shouldTypeCast = true;
|
|
|
+ } else {
|
|
|
+ throw ProcessorErrorFactory.invalid_parameter_type(funcName, exp.toString());
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- if(formalParameter.byRef && !sto_value.inStore()) {
|
|
|
- return Promise.reject(ProcessorErrorFactory.invalid_ref(funcName, exp.toString()))
|
|
|
- }
|
|
|
+ if(formalParameter.byRef && !actualValue.inStore()) {
|
|
|
+ throw ProcessorErrorFactory.invalid_ref(funcName, exp.toString());
|
|
|
+ }
|
|
|
|
|
|
- if(formalParameter.byRef) {
|
|
|
- const realObj = caller_store.getStoreObject(sto_value.id);
|
|
|
- let ref = null;
|
|
|
- if(sto_value instanceof ArrayStoreValue) {
|
|
|
-
|
|
|
- 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 {
|
|
|
- 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);
|
|
|
- ref.setReferenceDimension(realObj.type.dimensions);
|
|
|
- } else {
|
|
|
- ref = new StoreValueRef(sto_value.type, sto_value.get(), realObj.locAddress, realObj.id);
|
|
|
- }
|
|
|
- }
|
|
|
- callee_store.insertStore(formalParameter.id, ref);
|
|
|
+ if(formalParameter.byRef) {
|
|
|
+ const realObj = caller_store.getStoreObject(actualValue.id);
|
|
|
+ let ref = null;
|
|
|
+ if(actualValue instanceof ArrayStoreValue) {
|
|
|
+
|
|
|
+ const values = actualValue.get();
|
|
|
+ const array_type = actualValue.type;
|
|
|
+ const addresses = values.map( v => realObj.getLocAddressOf(v.line, v.column));
|
|
|
+ const columns = actualValue.isVector() ? 0 : actualValue.columns;
|
|
|
+ ref = new ArrayStoreValueRef(array_type, values, addresses, actualValue.lines, columns, realObj.id);
|
|
|
} else {
|
|
|
- let realValue = sto_value;
|
|
|
- if (shouldTypeCast) {
|
|
|
- realValue = Store.doImplicitCasting(formalParameter.type, realValue);
|
|
|
+ if(actualValue instanceof StoreValueAddress) {
|
|
|
+ const line = actualValue.line;
|
|
|
+ const column = actualValue.column;
|
|
|
+ ref = new StoreValueRef(actualValue.type, actualValue.get(),
|
|
|
+ realObj.getLocAddressOf(line, column), realObj.id);
|
|
|
+ ref.setReferenceDimension(realObj.type.dimensions);
|
|
|
+ } else {
|
|
|
+ ref = new StoreValueRef(actualValue.type, actualValue.get(), realObj.locAddress, realObj.id);
|
|
|
}
|
|
|
- callee_store.insertStore(formalParameter.id, realValue);
|
|
|
}
|
|
|
+ callee_store.insertStore(formalParameter.id, ref);
|
|
|
+ } else {
|
|
|
+ let realValue = actualValue;
|
|
|
+ if (shouldTypeCast) {
|
|
|
+ realValue = Store.doImplicitCasting(formalParameter.type, realValue);
|
|
|
+ }
|
|
|
+ callee_store.insertStore(formalParameter.id, realValue);
|
|
|
}
|
|
|
- return callee_store;
|
|
|
- });
|
|
|
+ }
|
|
|
+ return callee_store;
|
|
|
}
|
|
|
|
|
|
- executeCommands (store, cmds) {
|
|
|
+
|
|
|
+ *
|
|
|
+ * @param {Store} store
|
|
|
+ * @param {Command[]} cmds
|
|
|
+ */
|
|
|
+ async executeCommands (store, cmds) {
|
|
|
|
|
|
- const partial = (fun, cmd) => (sto) => fun(sto, cmd);
|
|
|
- return cmds.reduce((lastCommand, next) => {
|
|
|
- const nextCommand = partial(this.executeCommand.bind(this), next);
|
|
|
- return lastCommand.then(nextCommand);
|
|
|
- }, Promise.resolve(store));
|
|
|
+ let sto = store;
|
|
|
+ for (let i = 0; i < cmds.length; i += 1) {
|
|
|
+ sto = await this.executeCommand(sto, cmds[i]);
|
|
|
+ }
|
|
|
+ return sto;
|
|
|
}
|
|
|
|
|
|
- executeCommand (store, cmd) {
|
|
|
+
|
|
|
+ *
|
|
|
+ * @param {Store} store
|
|
|
+ * @param {Command} cmd
|
|
|
+ */
|
|
|
+ async executeCommand (store, cmd) {
|
|
|
this.instruction_count += 1;
|
|
|
- return new Promise((resolve, reject) => {
|
|
|
- const command_lambda = () => {
|
|
|
- if(this.instruction_count >= Config.max_instruction_count) {
|
|
|
- return reject(ProcessorErrorFactory.exceed_max_instructions());
|
|
|
- } else if(this.forceKill) {
|
|
|
- return reject("FORCED_KILL!");
|
|
|
- } else if (store.mode === Modes.PAUSE) {
|
|
|
- return resolve(this.executeCommand(store, cmd));
|
|
|
- } else if(store.mode === Modes.RETURN) {
|
|
|
- return resolve(store);
|
|
|
- } else if(this.checkContext(Context.BREAKABLE) && store.mode === Modes.BREAK) {
|
|
|
- return resolve(store);
|
|
|
- } else if (this.mode === Modes.ABORT) {
|
|
|
- return reject(LocalizedStrings.getMessage('aborted_execution'));
|
|
|
- }
|
|
|
- if (cmd instanceof Commands.Declaration) {
|
|
|
- return resolve(this.executeDeclaration(store, cmd));
|
|
|
- } else if (cmd instanceof Commands.ArrayIndexAssign) {
|
|
|
- return resolve(this.executeArrayIndexAssign(store, cmd));
|
|
|
- } else if (cmd instanceof Commands.Assign) {
|
|
|
- return resolve(this.executeAssign(store, cmd));
|
|
|
- } else if (cmd instanceof Commands.Break) {
|
|
|
- return resolve(this.executeBreak(store, cmd));
|
|
|
- } else if (cmd instanceof Commands.Return) {
|
|
|
- return resolve(this.executeReturn(store, cmd));
|
|
|
- } else if (cmd instanceof Commands.IfThenElse) {
|
|
|
- return resolve(this.executeIfThenElse(store, cmd));
|
|
|
- } else if (cmd instanceof Commands.RepeatUntil) {
|
|
|
- return resolve(this.executeRepeatUntil(store, cmd));
|
|
|
- } else if (cmd instanceof Commands.While) {
|
|
|
- return resolve(this.executeWhile(store, cmd));
|
|
|
- } else if (cmd instanceof Commands.For) {
|
|
|
- return resolve(this.executeFor(store, cmd));
|
|
|
- } else if (cmd instanceof Commands.Switch) {
|
|
|
- return resolve(this.executeSwitch(store, cmd));
|
|
|
- } else if (cmd instanceof Expressions.FunctionCall) {
|
|
|
- return resolve(this.executeFunctionCall(store, cmd));
|
|
|
- } else if (cmd instanceof Commands.SysCall) {
|
|
|
- return resolve(this.executeSysCall(store, cmd));
|
|
|
- } else {
|
|
|
- return reject(ProcessorErrorFactory.unknown_command(cmd.sourceInfo))
|
|
|
- }
|
|
|
- };
|
|
|
- if(this.instruction_count % Config.suspend_threshold == 0) {
|
|
|
-
|
|
|
- setTimeout(command_lambda, 5);
|
|
|
- } else {
|
|
|
- command_lambda();
|
|
|
- }
|
|
|
- })
|
|
|
+ if(this.instruction_count % Config.suspend_threshold == 0) {
|
|
|
+
|
|
|
+ await Utils.sleep(5)
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if(this.instruction_count >= Config.max_instruction_count) {
|
|
|
+ throw ProcessorErrorFactory.exceed_max_instructions();
|
|
|
+ } else if(this.forceKill) {
|
|
|
+ throw "FORCED_KILL!";
|
|
|
+ } else if (store.mode === Modes.PAUSE) {
|
|
|
+ return this.executeCommand(store, cmd);
|
|
|
+ } else if(store.mode === Modes.RETURN) {
|
|
|
+ return store;
|
|
|
+ } else if (this.checkContext(Context.BREAKABLE) && store.mode === Modes.BREAK) {
|
|
|
+ return store;
|
|
|
+ } else if (this.mode === Modes.ABORT) {
|
|
|
+ throw LocalizedStrings.getMessage('aborted_execution');
|
|
|
+ }
|
|
|
+
|
|
|
+ if (cmd instanceof Commands.Declaration) {
|
|
|
+ return this.executeDeclaration(store, cmd);
|
|
|
+ } else if (cmd instanceof Commands.ArrayIndexAssign) {
|
|
|
+ return this.executeArrayIndexAssign(store, cmd);
|
|
|
+ } else if (cmd instanceof Commands.Assign) {
|
|
|
+ return this.executeAssign(store, cmd);
|
|
|
+ } else if (cmd instanceof Commands.Break) {
|
|
|
+ return this.executeBreak(store, cmd);
|
|
|
+ } else if (cmd instanceof Commands.Return) {
|
|
|
+ return this.executeReturn(store, cmd);
|
|
|
+ } else if (cmd instanceof Commands.IfThenElse) {
|
|
|
+ return this.executeIfThenElse(store, cmd);
|
|
|
+ } else if (cmd instanceof Commands.RepeatUntil) {
|
|
|
+ return this.executeRepeatUntil(store, cmd);
|
|
|
+ } else if (cmd instanceof Commands.While) {
|
|
|
+ return this.executeWhile(store, cmd);
|
|
|
+ } else if (cmd instanceof Commands.For) {
|
|
|
+ return this.executeFor(store, cmd);
|
|
|
+ } else if (cmd instanceof Commands.Switch) {
|
|
|
+ return this.executeSwitch(store, cmd);
|
|
|
+ } else if (cmd instanceof Expressions.FunctionCall) {
|
|
|
+ return this.executeFunctionCall(store, cmd);
|
|
|
+ } else if (cmd instanceof Commands.SysCall) {
|
|
|
+ return this.executeSysCall(store, cmd);
|
|
|
+ } else {
|
|
|
+ throw ProcessorErrorFactory.unknown_command(cmd.sourceInfo);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
executeSysCall (store, cmd) {
|
|
@@ -282,29 +277,24 @@ export class IVProgProcessor {
|
|
|
return func(store, cmd);
|
|
|
}
|
|
|
|
|
|
- executeFunctionCall (store, cmd) {
|
|
|
+ async executeFunctionCall (store, cmd) {
|
|
|
let func = null;
|
|
|
if(cmd.isMainCall) {
|
|
|
func = this.findMainFunction();
|
|
|
} else {
|
|
|
func = this.findFunction(cmd.id);
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
this.function_call_stack.push(cmd.sourceInfo);
|
|
|
- return this.runFunction(func, cmd.actualParameters, store)
|
|
|
- .then(sto => {
|
|
|
- sto.destroy();
|
|
|
- if(!Types.VOID.isCompatible(func.returnType) && sto.mode !== Modes.RETURN) {
|
|
|
- const funcName = func.name === IVProgProcessor.MAIN_INTERNAL_ID ?
|
|
|
- LanguageDefinedFunction.getMainFunctionName() : func.name;
|
|
|
- return Promise.reject(ProcessorErrorFactory.function_no_return(funcName));
|
|
|
- } else {
|
|
|
- this.function_call_stack.pop();
|
|
|
- return store;
|
|
|
- }
|
|
|
- });
|
|
|
+ const sto = await this.runFunction(func, cmd.actualParameters, store);
|
|
|
+ sto.destroy();
|
|
|
+ if(!Types.VOID.isCompatible(func.returnType) && sto.mode !== Modes.RETURN) {
|
|
|
+ const funcName = func.name === IVProgProcessor.MAIN_INTERNAL_ID ?
|
|
|
+ LanguageDefinedFunction.getMainFunctionName() : func.name;
|
|
|
+ throw ProcessorErrorFactory.function_no_return(funcName);
|
|
|
+ } else {
|
|
|
+ this.function_call_stack.pop();
|
|
|
+ return store;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
executeSwitch (store, cmd) {
|
|
@@ -732,71 +722,62 @@ export class IVProgProcessor {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- evaluateExpression (store, exp) {
|
|
|
+ async evaluateExpression (store, exp) {
|
|
|
this.instruction_count += 1;
|
|
|
- return new Promise((resolve, reject) => {
|
|
|
- const expression_lambda = () => {
|
|
|
- if (this.mode === Modes.ABORT) {
|
|
|
- return reject(LocalizedStrings.getMessage('aborted_execution'));
|
|
|
- }
|
|
|
- if(this.instruction_count >= Config.max_instruction_count) {
|
|
|
- return reject(new Error("Número de instruções excedeu o limite definido. Verifique se seu código não possui laços infinitos ou muitas chamadas de funções recursivas."))
|
|
|
- }
|
|
|
- if (exp instanceof Expressions.UnaryApp) {
|
|
|
- return resolve(this.evaluateUnaryApp(store, exp));
|
|
|
- } else if (exp instanceof Expressions.InfixApp) {
|
|
|
- return resolve(this.evaluateInfixApp(store, exp));
|
|
|
- } else if (exp instanceof Expressions.ArrayAccess) {
|
|
|
- return resolve(this.evaluateArrayAccess(store, exp));
|
|
|
- } else if (exp instanceof Expressions.VariableLiteral) {
|
|
|
- return resolve(this.evaluateVariableLiteral(store, exp));
|
|
|
- } else if (exp instanceof Expressions.IntLiteral) {
|
|
|
- return resolve(this.evaluateLiteral(store, exp));
|
|
|
- } else if (exp instanceof Expressions.RealLiteral) {
|
|
|
- return resolve(this.evaluateLiteral(store, exp));
|
|
|
- } else if (exp instanceof Expressions.BoolLiteral) {
|
|
|
- return resolve(this.evaluateLiteral(store, exp));
|
|
|
- } else if (exp instanceof Expressions.StringLiteral) {
|
|
|
- return resolve(this.evaluateLiteral(store, exp));
|
|
|
- } else if (exp instanceof Expressions.ArrayLiteral) {
|
|
|
- return reject(new Error("Internal Error: The system should not eval an array literal."))
|
|
|
- } else if (exp instanceof Expressions.FunctionCall) {
|
|
|
- return resolve(this.evaluateFunctionCall(store, exp));
|
|
|
- }
|
|
|
- return resolve(null);
|
|
|
- };
|
|
|
- if(this.instruction_count % Config.suspend_threshold == 0) {
|
|
|
-
|
|
|
- setTimeout(expression_lambda, 5);
|
|
|
- } else {
|
|
|
- expression_lambda();
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
+ if(this.instruction_count % Config.suspend_threshold == 0) {
|
|
|
+
|
|
|
+ await Utils.sleep(5);
|
|
|
+ }
|
|
|
+ if (this.mode === Modes.ABORT) {
|
|
|
+ throw LocalizedStrings.getMessage('aborted_execution');
|
|
|
+ }
|
|
|
+ if(this.instruction_count >= Config.max_instruction_count) {
|
|
|
+ throw new Error("Número de instruções excedeu o limite definido. Verifique se seu código não possui laços infinitos ou muitas chamadas de funções recursivas.");
|
|
|
+ }
|
|
|
+ if (exp instanceof Expressions.UnaryApp) {
|
|
|
+ return this.evaluateUnaryApp(store, exp);
|
|
|
+ } else if (exp instanceof Expressions.InfixApp) {
|
|
|
+ return this.evaluateInfixApp(store, exp);
|
|
|
+ } else if (exp instanceof Expressions.ArrayAccess) {
|
|
|
+ return this.evaluateArrayAccess(store, exp);
|
|
|
+ } else if (exp instanceof Expressions.VariableLiteral) {
|
|
|
+ return this.evaluateVariableLiteral(store, exp);
|
|
|
+ } else if (exp instanceof Expressions.IntLiteral) {
|
|
|
+ return this.evaluateLiteral(store, exp);
|
|
|
+ } else if (exp instanceof Expressions.RealLiteral) {
|
|
|
+ return this.evaluateLiteral(store, exp);
|
|
|
+ } else if (exp instanceof Expressions.BoolLiteral) {
|
|
|
+ return this.evaluateLiteral(store, exp);
|
|
|
+ } else if (exp instanceof Expressions.StringLiteral) {
|
|
|
+ return this.evaluateLiteral(store, exp);
|
|
|
+ } else if (exp instanceof Expressions.ArrayLiteral) {
|
|
|
+ throw new Error("Internal Error: The system should not eval an array literal.");
|
|
|
+ } else if (exp instanceof Expressions.FunctionCall) {
|
|
|
+ return this.evaluateFunctionCall(store, exp);
|
|
|
+ }
|
|
|
+ return null;
|
|
|
}
|
|
|
|
|
|
- evaluateFunctionCall (store, exp) {
|
|
|
+ async evaluateFunctionCall (store, exp) {
|
|
|
if(exp.isMainCall) {
|
|
|
- return Promise.reject(ProcessorErrorFactory.void_in_expression_full(LanguageDefinedFunction.getMainFunctionName(), exp.sourceInfo));
|
|
|
+ throw ProcessorErrorFactory.void_in_expression_full(LanguageDefinedFunction.getMainFunctionName(), exp.sourceInfo);
|
|
|
}
|
|
|
const func = this.findFunction(exp.id);
|
|
|
if(Types.VOID.isCompatible(func.returnType)) {
|
|
|
- return Promise.reject(ProcessorErrorFactory.void_in_expression_full(exp.id, exp.sourceInfo));
|
|
|
+ throw ProcessorErrorFactory.void_in_expression_full(exp.id, exp.sourceInfo);
|
|
|
}
|
|
|
if(this.function_call_stack.length >= Config.max_call_stack) {
|
|
|
- return Promise.reject(ProcessorErrorFactory.exceeded_recursive_calls(exp.sourceInfo));
|
|
|
+ throw ProcessorErrorFactory.exceeded_recursive_calls(exp.sourceInfo);
|
|
|
}
|
|
|
this.function_call_stack.push(exp.sourceInfo);
|
|
|
- const $newStore = this.runFunction(func, exp.actualParameters, store);
|
|
|
- return $newStore.then( sto => {
|
|
|
- if(sto.mode !== Modes.RETURN) {
|
|
|
- return Promise.reject(new Error("!!!Internal error: the function that was called did not have a return command or did not set the store mode properly -> "+exp.id));
|
|
|
- }
|
|
|
- const val = sto.applyStore('$');
|
|
|
- sto.destroy();
|
|
|
- this.function_call_stack.pop();
|
|
|
- return Promise.resolve(val);
|
|
|
- });
|
|
|
+ const sto = await this.runFunction(func, exp.actualParameters, store);
|
|
|
+ if(sto.mode !== Modes.RETURN) {
|
|
|
+ throw new Error("!!!Internal error: the function that was called did not have a return command or did not set the store mode properly -> "+exp.id);
|
|
|
+ }
|
|
|
+ const val = sto.applyStore('$');
|
|
|
+ sto.destroy();
|
|
|
+ this.function_call_stack.pop();
|
|
|
+ return val;
|
|
|
}
|
|
|
|
|
|
|