/* --------------------------------------------------------- * * __________ D E L T A S C R I P T * * (_________() * * / === / - A fast, dynamic scripting language * * | == | - Version 4.13.11.0 * * / === / - Developed by Adam R. Nelson * * | = = | - 2011-2013 * * / === / - Distributed under GNU LGPL v3 * * (________() - http://github.com/ar-nelson/deltascript * * * * --------------------------------------------------------- */ package com.sector91.delta.script; import com.sector91.delta.script.instrs.DSInstr; import com.sector91.delta.script.objects.DS_Array; import com.sector91.delta.script.objects.DS_Callable; import com.sector91.delta.script.objects.DS_Object; import com.sector91.delta.script.objects.DS_Scope; import com.sector91.delta.script.objects.DS_String; public class DScriptExecutor { private final DSInstr instr; private final DS_Scope scope; private final DScriptContext context; public boolean functionCall, loopBreak, loopContinue, returnBreak; DScriptExecutor(DSInstr instr, DS_Scope scope, boolean functionCall, DScriptContext context) { this.instr = instr; this.scope = scope; this.functionCall = functionCall; this.context = context==null ? new DScriptContext() : context; } public DScriptContext getContext() {return context;} DS_Object execInstance() throws DScriptErr { DScriptContext.push(context); try {return instr.exec(scope, this);} catch (DScriptErr ex) {return tryToHandleError(scope, instr, ex);} finally {DScriptContext.pop();} } DS_Object execInstrAsFunctionCall(DSInstr instr, DS_Scope scope) throws DScriptErr { DScriptContext.push(context); try { if (functionCall) return instr.exec(scope, this); else { functionCall = true; final DS_Object retval = instr.exec(scope, this); functionCall = false; return retval; } } catch (Exception ex) {return tryToHandleError(scope, instr, ex);} finally {DScriptContext.pop();} } public DS_Object tryToHandleError(DS_Scope scope, DSInstr instr, Exception ex) throws DScriptErr { final DScriptErr dex; if (ex instanceof DScriptErr) dex = (DScriptErr)ex; else dex = new DScriptErr(ex.getMessage(), ex, instr); DS_Scope cs = scope; DS_Object err = scope.getLocal(DeltaScript.ERROR_FUNC_NAME); while (!cs.isRootScope() && (err == null || !(err instanceof DS_Callable) || scope.is(err))) { cs = cs.getParent(); err = cs.getLocal(DeltaScript.ERROR_FUNC_NAME); } if (cs.isRootScope()) throw dex; else return ((DS_Callable)err).call( new DS_String(dex.getMessage()), new DS_Array(dex.tags.toArray(new DS_Object[dex.tags.size()])), new DS_Array(dex.getInstrStackTrace())); } }