mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
Make == script operator to work correctly on collections (lists)
git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@992 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -251,7 +251,10 @@ ScriptValueP Context::makeClosure(const ScriptValueP& fun) {
|
||||
if (variables[var].level < level) break;
|
||||
closure->addBinding(var, variables[var].value);
|
||||
}
|
||||
return closure;
|
||||
// can we simplify?
|
||||
ScriptValueP better = closure->simplify();
|
||||
if (better) return better;
|
||||
else return closure;
|
||||
}
|
||||
|
||||
|
||||
@@ -392,8 +395,8 @@ void instrBinary (BinaryInstructionType i, ScriptValueP& a, const ScriptValueP&
|
||||
case I_AND: OPERATOR_I(&&);
|
||||
case I_OR: OPERATOR_I(||);
|
||||
case I_XOR: a = to_script((bool)*a != (bool)*b); break;
|
||||
case I_EQ: a = to_script( equal(*a,*b)); break;
|
||||
case I_NEQ: a = to_script(!equal(*a,*b)); break;
|
||||
case I_EQ: a = to_script( equal(a,b)); break;
|
||||
case I_NEQ: a = to_script(!equal(a,b)); break;
|
||||
case I_LT: OPERATOR_DI(<);
|
||||
case I_GT: OPERATOR_DI(>);
|
||||
case I_LE: OPERATOR_DI(<=);
|
||||
|
||||
@@ -215,7 +215,7 @@ int position_in_vector(const ScriptValueP& of, const ScriptValueP& in, const Scr
|
||||
ScriptValueP it = in->makeIterator(in);
|
||||
int i = 0;
|
||||
while (ScriptValueP v = it->next()) {
|
||||
if (equal(*of, *v)) return i;
|
||||
if (equal(of, v)) return i;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
@@ -384,17 +384,10 @@ SCRIPT_FUNCTION(keyword_usage) {
|
||||
// ----------------------------------------------------------------------------- : Rule form
|
||||
|
||||
/// Turn a script function into a rule, a.k.a. a delayed closure
|
||||
class ScriptRule : public ScriptValue {
|
||||
public:
|
||||
inline ScriptRule(const ScriptValueP& fun) : fun(fun) {}
|
||||
virtual ScriptType type() const { return SCRIPT_FUNCTION; }
|
||||
virtual String typeName() const { return fun->typeName() + _(" rule"); }
|
||||
virtual ScriptValueP eval(Context& ctx) const {
|
||||
return ctx.makeClosure(fun);
|
||||
}
|
||||
private:
|
||||
ScriptValueP fun;
|
||||
};
|
||||
SCRIPT_FUNCTION(rule) {
|
||||
SCRIPT_PARAM(ScriptValueP, input);
|
||||
return new_intrusive1<ScriptRule>(input);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Init
|
||||
|
||||
|
||||
+11
-2
@@ -321,6 +321,17 @@ class ScriptClosure : public ScriptValue {
|
||||
void applyBindings(Context& ctx) const;
|
||||
};
|
||||
|
||||
/// Turn a script function into a rule, a.k.a. a delayed closure
|
||||
class ScriptRule : public ScriptValue {
|
||||
public:
|
||||
inline ScriptRule(const ScriptValueP& fun) : fun(fun) {}
|
||||
virtual ScriptType type() const;
|
||||
virtual String typeName() const;
|
||||
virtual ScriptValueP eval(Context& ctx) const;
|
||||
private:
|
||||
ScriptValueP fun;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : Creating
|
||||
|
||||
/// Convert a value to a script value
|
||||
@@ -360,7 +371,5 @@ template <> inline bool from_script<bool> (const ScriptValueP& va
|
||||
template <> inline Color from_script<Color> (const ScriptValueP& value) { return (AColor)*value; }
|
||||
template <> inline AColor from_script<AColor> (const ScriptValueP& value) { return *value; }
|
||||
|
||||
void from_script(const ScriptValueP& value, wxRegEx& out);
|
||||
|
||||
// ----------------------------------------------------------------------------- : EOF
|
||||
#endif
|
||||
|
||||
+22
-12
@@ -38,19 +38,30 @@ ScriptValueP ScriptValue::dependencyMember(const String& name, const Dependency&
|
||||
ScriptValueP ScriptValue::dependencies(Context&, const Dependency&) const { return dependency_dummy; }
|
||||
|
||||
/// compare script values for equallity
|
||||
bool equal(const ScriptValue& a, const ScriptValue& b) {
|
||||
if (&a == &b) return true;
|
||||
ScriptType at = a.type(), bt = b.type();
|
||||
bool equal(const ScriptValueP& a, const ScriptValueP& b) {
|
||||
if (a == b) return true;
|
||||
ScriptType at = a->type(), bt = b->type();
|
||||
if (at == bt && at == SCRIPT_INT) {
|
||||
return (int)a == (int)b;
|
||||
return (int)*a == (int)*b;
|
||||
} else if ((at == SCRIPT_INT || at == SCRIPT_DOUBLE) &&
|
||||
(bt == SCRIPT_INT || bt == SCRIPT_DOUBLE)) {
|
||||
return (double)a == (double)b;
|
||||
return (double)*a == (double)*b;
|
||||
} else if (at == SCRIPT_COLLECTION && bt == SCRIPT_COLLECTION) {
|
||||
// compare each element
|
||||
if (a->itemCount() != b->itemCount()) return false;
|
||||
ScriptValueP a_it = a->makeIterator(a);
|
||||
ScriptValueP b_it = b->makeIterator(b);
|
||||
while (true) {
|
||||
ScriptValueP a_v = a_it->next();
|
||||
ScriptValueP b_v = b_it->next();
|
||||
if (!a_v || !b_v) return a_v == b_v;
|
||||
if (!equal(a_v, b_v)) return false;
|
||||
}
|
||||
} else {
|
||||
String as, bs;
|
||||
const void* ap, *bp;
|
||||
CompareWhat aw = a.compareAs(as, ap);
|
||||
CompareWhat bw = b.compareAs(bs, bp);
|
||||
CompareWhat aw = a->compareAs(as, ap);
|
||||
CompareWhat bw = b->compareAs(bs, bp);
|
||||
// compare pointers or strings
|
||||
if (aw == COMPARE_AS_STRING || bw == COMPARE_AS_STRING) {
|
||||
return as == bs;
|
||||
@@ -402,10 +413,9 @@ void ScriptClosure::applyBindings(Context& ctx) const {
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Destructing
|
||||
|
||||
void from_script(const ScriptValueP& value, wxRegEx& regex) {
|
||||
if (!regex.Compile(*value, wxRE_ADVANCED)) {
|
||||
throw ScriptError(_ERROR_2_("can't convert", value->typeName(), _TYPE_("regex")));
|
||||
}
|
||||
ScriptType ScriptRule::type() const { return SCRIPT_FUNCTION; }
|
||||
String ScriptRule::typeName() const { return fun->typeName() + _(" rule"); }
|
||||
ScriptValueP ScriptRule::eval(Context& ctx) const {
|
||||
return ctx.makeClosure(fun);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ enum ScriptType
|
||||
, SCRIPT_FUNCTION
|
||||
, SCRIPT_OBJECT // Only ScriptObject
|
||||
, SCRIPT_COLLECTION
|
||||
, SCRIPT_REGEX
|
||||
, SCRIPT_ITERATOR
|
||||
, SCRIPT_DUMMY
|
||||
, SCRIPT_ERROR
|
||||
@@ -102,7 +103,7 @@ extern ScriptValueP script_false; ///< The preallocated false value
|
||||
extern ScriptValueP dependency_dummy; ///< Dummy value used during dependency analysis
|
||||
|
||||
/// compare script values for equallity
|
||||
bool equal(const ScriptValue& a, const ScriptValue& b);
|
||||
bool equal(const ScriptValueP& a, const ScriptValueP& b);
|
||||
|
||||
// ----------------------------------------------------------------------------- : EOF
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user