mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
+19
-1
@@ -106,6 +106,11 @@ ScriptValueP Context::eval(const Script& script, bool useScope) {
|
|||||||
setVariable((Variable)i.data, stack.back());
|
setVariable((Variable)i.data, stack.back());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// Set a global variable
|
||||||
|
case I_SET_GLB: {
|
||||||
|
setGlobalVariable((Variable)i.data, stack.back());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Get an object member
|
// Get an object member
|
||||||
case I_MEMBER_C: {
|
case I_MEMBER_C: {
|
||||||
@@ -270,13 +275,26 @@ void Context::setVariable(Variable name, const ScriptValueP& value) {
|
|||||||
assert((size_t)name < variable_names.size());
|
assert((size_t)name < variable_names.size());
|
||||||
#endif
|
#endif
|
||||||
VariableValue& var = variables[name];
|
VariableValue& var = variables[name];
|
||||||
if (var.level < level) {
|
if (var.level < level && !var.global_scope) {
|
||||||
// keep shadow copy
|
// keep shadow copy
|
||||||
Binding bind = {name, var};
|
Binding bind = {name, var};
|
||||||
shadowed.push_back(bind);
|
shadowed.push_back(bind);
|
||||||
|
}
|
||||||
|
if (!var.global_scope) {
|
||||||
|
var.global_scope = false;
|
||||||
}
|
}
|
||||||
var.level = level;
|
var.level = level;
|
||||||
var.value = value;
|
var.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::setGlobalVariable(Variable name, const ScriptValueP& value) {
|
||||||
|
#ifdef _DEBUG
|
||||||
|
assert((size_t)name < variable_names.size());
|
||||||
|
#endif
|
||||||
|
VariableValue& var = variables[name];
|
||||||
|
var.level = level;
|
||||||
|
var.value = value;
|
||||||
|
var.global_scope = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptValueP Context::getVariable(const String& name) {
|
ScriptValueP Context::getVariable(const String& name) {
|
||||||
|
|||||||
@@ -53,7 +53,8 @@ public:
|
|||||||
/// Set a variable to a new value (in the current scope)
|
/// Set a variable to a new value (in the current scope)
|
||||||
void setVariable(const String& name, const ScriptValueP& value);
|
void setVariable(const String& name, const ScriptValueP& value);
|
||||||
/// Set a variable to a new value (in the current scope)
|
/// Set a variable to a new value (in the current scope)
|
||||||
void setVariable(Variable name, const ScriptValueP& value);
|
void setVariable(Variable name, const ScriptValueP& value);
|
||||||
|
void setGlobalVariable(Variable name, const ScriptValueP& value);
|
||||||
|
|
||||||
/// Get the value of a variable, throws if it not set
|
/// Get the value of a variable, throws if it not set
|
||||||
ScriptValueP getVariable(const String& name);
|
ScriptValueP getVariable(const String& name);
|
||||||
@@ -88,7 +89,8 @@ public:// public for FOR_EACH
|
|||||||
struct VariableValue {
|
struct VariableValue {
|
||||||
VariableValue() : level(0) {}
|
VariableValue() : level(0) {}
|
||||||
unsigned int level; ///< Scope level on which this variable was set
|
unsigned int level; ///< Scope level on which this variable was set
|
||||||
ScriptValueP value; ///< Value of this variable
|
ScriptValueP value; ///< Value of this variable
|
||||||
|
bool global_scope = false; ///< Is this variable globally scoped?
|
||||||
};
|
};
|
||||||
/// Record of a variable binding that is being shadowed (overwritten) by another binding
|
/// Record of a variable binding that is being shadowed (overwritten) by another binding
|
||||||
struct Binding {
|
struct Binding {
|
||||||
|
|||||||
@@ -301,6 +301,11 @@ ScriptValueP Context::dependencies(const Dependency& dep, const Script& script)
|
|||||||
setVariable((Variable)i.data, stack.back());
|
setVariable((Variable)i.data, stack.back());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// Set a global variable (as normal)
|
||||||
|
case I_SET_GLB: {
|
||||||
|
setGlobalVariable((Variable)i.data, stack.back());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Simple instruction: unary
|
// Simple instruction: unary
|
||||||
case I_UNARY: {
|
case I_UNARY: {
|
||||||
|
|||||||
@@ -745,7 +745,11 @@ ExprType parseOper(TokenIterator& input, Script& script, Precedence minPrec, Ins
|
|||||||
return EXPR_FAILED;
|
return EXPR_FAILED;
|
||||||
}
|
}
|
||||||
script.getInstructions().pop_back();
|
script.getInstructions().pop_back();
|
||||||
type = parseOper(input, script, PREC_SET, I_SET_VAR, instr.data);
|
if(token==_("->")) {
|
||||||
|
type = parseOper(input, script, PREC_SET, I_SET_GLB, instr.data);
|
||||||
|
} else {
|
||||||
|
type = parseOper(input, script, PREC_SET, I_SET_VAR, instr.data);
|
||||||
|
}
|
||||||
if (type == EXPR_STATEMENT) {
|
if (type == EXPR_STATEMENT) {
|
||||||
input.add_error(_("Warning: the right hand side of an assignment should always yield a value."));
|
input.add_error(_("Warning: the right hand side of an assignment should always yield a value."));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -176,6 +176,7 @@ String Script::dumpInstr(unsigned int pos, Instruction i) const {
|
|||||||
case I_JUMP_SC_OR: ret += _("jump sc or"); break;
|
case I_JUMP_SC_OR: ret += _("jump sc or"); break;
|
||||||
case I_GET_VAR: ret += _("get"); break;
|
case I_GET_VAR: ret += _("get"); break;
|
||||||
case I_SET_VAR: ret += _("set"); break;
|
case I_SET_VAR: ret += _("set"); break;
|
||||||
|
case I_SET_GLB: ret += _("set_global"); break;
|
||||||
case I_MEMBER_C: ret += _("member_c"); break;
|
case I_MEMBER_C: ret += _("member_c"); break;
|
||||||
case I_LOOP: ret += _("loop"); break;
|
case I_LOOP: ret += _("loop"); break;
|
||||||
case I_LOOP_WITH_KEY:ret += _("loop with key"); break;
|
case I_LOOP_WITH_KEY:ret += _("loop with key"); break;
|
||||||
@@ -236,7 +237,7 @@ String Script::dumpInstr(unsigned int pos, Instruction i) const {
|
|||||||
case I_CALL: case I_CLOSURE: case I_DUP: // int
|
case I_CALL: case I_CLOSURE: case I_DUP: // int
|
||||||
ret += String::Format(_("\t%d"), i.data);
|
ret += String::Format(_("\t%d"), i.data);
|
||||||
break;
|
break;
|
||||||
case I_GET_VAR: case I_SET_VAR: case I_NOP: // variable
|
case I_GET_VAR: case I_SET_VAR: case I_NOP: case I_SET_GLB: // variable
|
||||||
ret += _("\t") + variable_to_string((Variable)i.data);
|
ret += _("\t") + variable_to_string((Variable)i.data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ enum InstructionType
|
|||||||
// Variables
|
// Variables
|
||||||
, I_GET_VAR = 4 ///< arg = var : find a variable, push its value onto the stack, it is an error if the variable is not found
|
, I_GET_VAR = 4 ///< arg = var : find a variable, push its value onto the stack, it is an error if the variable is not found
|
||||||
, I_SET_VAR = 5 ///< arg = var : assign the top value from the stack to a variable (doesn't pop)
|
, I_SET_VAR = 5 ///< arg = var : assign the top value from the stack to a variable (doesn't pop)
|
||||||
|
, I_SET_GLB = 21 ///< arg = var : assign the top value from the stack to a global variable (doesn't pop)
|
||||||
// Objects
|
// Objects
|
||||||
, I_MEMBER_C = 6 ///< arg = const name : finds a member of the top of the stack replaces the top of the stack with the member
|
, I_MEMBER_C = 6 ///< arg = const name : finds a member of the top of the stack replaces the top of the stack with the member
|
||||||
, I_LOOP = 7 ///< arg = address : loop over the elements of an iterator, which is the *second* element of the stack (this allows for combing the results of multiple iterations)
|
, I_LOOP = 7 ///< arg = address : loop over the elements of an iterator, which is the *second* element of the stack (this allows for combing the results of multiple iterations)
|
||||||
|
|||||||
Reference in New Issue
Block a user