/* --------------------------------------------------------- * * __________ 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.instrs; import java.util.ArrayList; import java.util.List; import com.sector91.delta.script.DScriptErr; import com.sector91.delta.script.DScriptExecutor; import com.sector91.delta.script.DeltaScript; import com.sector91.delta.script.objects.DS_Blank; import com.sector91.delta.script.objects.DS_Callable; import com.sector91.delta.script.objects.DS_Iterable; import com.sector91.delta.script.objects.DS_Object; import com.sector91.delta.script.objects.DS_Scope; import com.sector91.delta.script.objects.DS_Tag; final class CallInstr extends DSInstr { private final int numArgs; protected CallInstr(int start, short len, String head, DSInstr[] tail) { super(start, len, head, tail); boolean expand = false; for (DSInstr instr : tail[1].tail()) if (instr instanceof ExpandInstr) expand = true; numArgs = expand ? -1 : tail[1].tail().length; } public DS_Object exec(DS_Scope scope, DScriptExecutor executor) throws DScriptErr { try { DS_Object[] args; if (numArgs < 0) { final List<DS_Object> argsList = new ArrayList<DS_Object>(); for (DSInstr instr : tail[1].tail()) { if (instr instanceof ExpandInstr) { final DS_Iterable iterable = ((ExpandInstr)instr).exec( scope, executor); for (DS_Object obj : iterable) argsList.add(obj); } else argsList.add(instr.exec(scope, executor)); } args = argsList.toArray(new DS_Object[argsList.size()]); } else { args = new DS_Object[numArgs]; for (int i=0; i<numArgs; i++) args[i] = tail[1].tail()[i].exec(scope, executor); } DS_Object callable = tail[0].exec(scope, executor); try { return ((DS_Callable)callable).call(args); } catch (ClassCastException ex) { throw new DScriptErr("Attempted to call object of type " + callable.getTypeName() +", which is not callable.", DScriptErr.T_INVALID_TYPE, DScriptErr.T_NOT_CALLABLE); } } catch (DScriptErr ex) {throw rethrow(ex);} catch (RuntimeException ex) {throw rethrow(ex);} } public InstrType type() {return InstrType.CALL;} } final class StdLibInstr extends DSInstr { public final DS_Tag cachedTag; protected StdLibInstr(int start, short len, String car, DSInstr[] cdr) { super(start, len, car, cdr); cachedTag = DS_Tag.tag(car); } public DS_Object exec(DS_Scope scope, DScriptExecutor executor) throws DScriptErr { try {return DeltaScript.STDLIB.dotGet(cachedTag);} catch (DScriptErr ex) {throw rethrow(ex);} catch (RuntimeException ex) {throw rethrow(ex);} } public InstrType type() {return InstrType.STDLIB;} } final class IncludeInstr extends DSInstr { protected IncludeInstr(int start, short len, String head, DSInstr[] tail) {super(start, len, head, tail);} public DS_Object exec(DS_Scope scope, DScriptExecutor executor) throws DScriptErr { final DS_Scope scopeToInclude; final DS_Object toInclude = tail[0].exec(scope, executor); try {scopeToInclude = (DS_Scope)toInclude;} catch (ClassCastException ex) { throw new DScriptErr("The 'include' statement can only" + " include scopes. Got object of type '" + toInclude.getTypeName() + "' instead.", DScriptErr.T_INVALID_TYPE); } scope.include(scopeToInclude); return DS_Blank.BLANK; } public InstrType type() {return InstrType.INCLUDE;} } final class MetaInstr extends DSInstr { protected MetaInstr(int start, short len, String head, DSInstr[] tail) {super(start, len, head, tail);} public DS_Object exec(DS_Scope scope, DScriptExecutor executor) throws DScriptErr { // Does nothing. return DS_Blank.BLANK; } public InstrType type() {return InstrType.META;} }