/* --------------------------------------------------------- * * __________ 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 static com.sector91.util.StringTemplate.$; import com.sector91.delta.script.DScriptErr; import com.sector91.delta.script.DScriptExecutor; import com.sector91.delta.script.objects.DS_Callable; import com.sector91.delta.script.objects.DS_Indexable; 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 GetInstr extends DSInstr { public final DS_Tag cachedTag; protected GetInstr(int start, short len, String head, DSInstr[] tail) { super(start, len, head, tail); cachedTag = DS_Tag.tag(head); } public DS_Object exec(DS_Scope scope, DScriptExecutor executor) throws DScriptErr { try { final DS_Object obj = scope.get(cachedTag); if (obj == null) throw new DScriptErr(head() + " is undefined in this scope.", this, DScriptErr.T_UNDEFINED); return obj; } catch (RuntimeException ex) {throw rethrow(ex);} } public InstrType type() {return InstrType.GET;} } final class SetInstr extends DSInstr { public final DS_Tag cachedTag; protected SetInstr(int start, short len, String head, DSInstr[] tail) { super(start, len, head, tail); cachedTag = DS_Tag.tag(head); } public DS_Object exec(DS_Scope scope, DScriptExecutor executor) throws DScriptErr { try { final DS_Object val = tail()[0].exec(scope, executor); scope.set(cachedTag, val); return val; } catch (RuntimeException ex) {throw rethrow(ex);} } public InstrType type() {return InstrType.SET;} } final class DotGetInstr extends DSInstr { public final DS_Tag cachedTag; protected DotGetInstr(int start, short len, String head, DSInstr[] tail) { super(start, len, head, tail); cachedTag = DS_Tag.tag(head); } public DS_Object exec(DS_Scope scope, DScriptExecutor executor) throws DScriptErr { try { final DS_Object target = tail()[0].exec(scope, executor); return target.dotGet(cachedTag); } catch (DScriptErr ex) {throw rethrow(ex);} catch (RuntimeException ex) {throw rethrow(ex);} } public InstrType type() {return InstrType.DOTGET;} } final class DotSetInstr extends DSInstr { public final DS_Tag cachedTag; protected DotSetInstr(int start, short len, String head, DSInstr[] tail) { super(start, len, head, tail); cachedTag = DS_Tag.tag(head); } public DS_Object exec(DS_Scope scope, DScriptExecutor executor) throws DScriptErr { try { final DS_Object target = tail()[0].exec(scope, executor); final DS_Object val = tail()[1].exec(scope, executor); target.dotSet(cachedTag, val); return val; } catch (DScriptErr ex) {throw rethrow(ex);} catch (RuntimeException ex) {throw rethrow(ex);} } public InstrType type() {return InstrType.DOTSET;} } final class DefInstr extends DSInstr { public final DS_Tag cachedTag; protected DefInstr(int start, short len, String head, DSInstr[] tail) { super(start, len, head, tail); cachedTag = DS_Tag.tag(head); } public DS_Object exec(DS_Scope scope, DScriptExecutor executor) throws DScriptErr { try { final DS_Object val = tail()[0].exec(scope, executor); scope.setLocal(cachedTag, val); return val; } catch (RuntimeException ex) {throw rethrow(ex);} } public InstrType type() {return InstrType.DEF;} } final class SpecialVarInstr extends DSInstr { public final DS_Tag cachedTag; protected SpecialVarInstr(int start, short len, String head, DSInstr[] tail) { super(start, len, head, tail); cachedTag = DS_Tag.tag(head); } public DS_Object exec(DS_Scope scope, DScriptExecutor executor) throws DScriptErr { try {return scope.getSpecial(cachedTag);} catch (DScriptErr ex) {throw rethrow(ex);} catch (RuntimeException ex) {throw rethrow(ex);} } public InstrType type() {return InstrType.$VAR;} } final class DotSpecialVarInstr extends DSInstr { public final DS_Tag cachedTag; protected DotSpecialVarInstr(int start, short len, String head, DSInstr[] tail) { super(start, len, head, tail); cachedTag = DS_Tag.tag(head); } public DS_Object exec(DS_Scope scope, DScriptExecutor executor) throws DScriptErr { try { final DS_Object target = tail[0].exec(scope, executor); if (target instanceof DS_Scope) return ((DS_Scope)target).getSpecial(cachedTag); else throw new DScriptErr("Cannot access the special" + " variable " + head + " of an object of type " + target.getTypeName() + "; special variables only exist for" + " scopes.", DScriptErr.T_UNDEFINED); } catch (DScriptErr ex) {throw rethrow(ex);} catch (RuntimeException ex) {throw rethrow(ex);} } public InstrType type() {return InstrType.DOT$VAR;} } final class IndexInstr extends DSInstr { protected IndexInstr(int start, short len, String head, DSInstr[] tail) {super(start, len, head, tail);} public DS_Object exec(DS_Scope scope, DScriptExecutor executor) throws DScriptErr { try { final DS_Object indexable = tail[0].exec(scope, executor); if (indexable instanceof DS_Indexable) return ((DS_Indexable)indexable).getIndex( tail[1].exec(scope,executor)); else throw DScriptErr.invalidOperation("index", indexable); } catch (DScriptErr ex) {throw rethrow(ex);} catch (RuntimeException ex) {throw rethrow(ex);} } public InstrType type() {return InstrType.INDEX;} } final class IndexSetInstr extends DSInstr { protected IndexSetInstr(int start, short len, String head, DSInstr[] tail) {super(start, len, head, tail);} public DS_Object exec(DS_Scope scope, DScriptExecutor executor) throws DScriptErr { try { final DS_Object indexable = tail[0].exec(scope, executor); if (indexable instanceof DS_Indexable) { return ((DS_Indexable)indexable).setIndex( tail[1].exec(scope, executor), tail[2].exec(scope, executor)); } else throw DScriptErr.invalidOperation("index", indexable); } catch (DScriptErr ex) {throw rethrow(ex);} catch (RuntimeException ex) {throw rethrow(ex);} } public InstrType type() {return InstrType.INDEXSET;} } final class FieldInstr extends DSInstr { public final DS_Tag cachedTag; FieldInstr(int start, short len, String head, DSInstr[] tail) { super(start, len, head, tail); cachedTag = DS_Tag.tag(head); } public DS_Object exec(DS_Scope scope, DScriptExecutor executor) throws DScriptErr { try { final DS_Object val = tail()[0].exec(scope, executor); if (!(val instanceof DS_Callable)) throw new DScriptErr($("A dynamic field must be a" + " callable object; attempted to create dynamic field '{}'" + " with a non-callable {}.", cachedTag.stringValue(), val.getTypeName()), DScriptErr.T_NOT_CALLABLE, DScriptErr.T_INVALID_TYPE); scope.createDynamicField(cachedTag, (DS_Callable)val); return val; } catch (DScriptErr ex) {throw rethrow(ex);} catch (RuntimeException ex) {throw rethrow(ex);} } public InstrType type() {return InstrType.FIELD;} }