/* --------------------------------------------------------- *
* __________ 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()));
}
}