mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
(sorry for making this all one commit)
Fiddled with the backbone for scripts some more. VCS are now suppported in sets but configuration/non-svn-systems missing Linux build now uses precompiled headers (build time--) A couple warning fixes too. git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@1427 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
+15
-9
@@ -51,7 +51,7 @@ ScriptValueP Context::eval(const Script& script, bool useScope) {
|
||||
// Evaluate the current instruction
|
||||
Instruction i = *instr++;
|
||||
// If a scope is created, destroy it at end of block.
|
||||
scoped_ptr<LocalScope> scope;
|
||||
scoped_ptr<LocalScope> new_scope;
|
||||
|
||||
switch (i.instr) {
|
||||
case I_NOP: break;
|
||||
@@ -126,7 +126,7 @@ ScriptValueP Context::eval(const Script& script, bool useScope) {
|
||||
}
|
||||
|
||||
// Function call
|
||||
case I_CALL: scope.reset(new LocalScope(*this)); //new scope
|
||||
case I_CALL: new_scope.reset(new LocalScope(*this)); //new scope
|
||||
case I_TAILCALL: {
|
||||
// prepare arguments
|
||||
for (unsigned int j = 0 ; j < i.data ; ++j) {
|
||||
@@ -144,7 +144,7 @@ ScriptValueP Context::eval(const Script& script, bool useScope) {
|
||||
Profiler prof(timer, function);
|
||||
#endif
|
||||
// get function and call
|
||||
stack.back() = stack.back()->eval(*this);
|
||||
stack.back() = stack.back()->eval(*this, false);
|
||||
// finish profiling
|
||||
#if USE_SCRIPT_PROFILING
|
||||
//profile_add(function, timer.time());
|
||||
@@ -366,7 +366,14 @@ class ScriptCompose : public ScriptValue {
|
||||
|
||||
virtual ScriptType type() const { return SCRIPT_FUNCTION; }
|
||||
virtual String typeName() const { return _("function composition"); }
|
||||
virtual ScriptValueP eval(Context& ctx) const {
|
||||
|
||||
virtual ScriptValueP dependencies(Context& ctx, const Dependency& dep) const {
|
||||
ctx.setVariable(SCRIPT_VAR_input, a->dependencies(ctx, dep));
|
||||
return b->dependencies(ctx, dep);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ScriptValueP do_eval(Context& ctx, bool openScope) const {
|
||||
#if USE_SCRIPT_PROFILING
|
||||
Timer timer;
|
||||
{
|
||||
@@ -382,14 +389,13 @@ class ScriptCompose : public ScriptValue {
|
||||
return b->eval(ctx);
|
||||
}
|
||||
#else
|
||||
// Always open a scope for a; variables it makes need to be
|
||||
// cleared for b's call.
|
||||
ctx.setVariable(SCRIPT_VAR_input, a->eval(ctx));
|
||||
return b->eval(ctx);
|
||||
return b->eval(ctx, openScope);
|
||||
#endif
|
||||
}
|
||||
virtual ScriptValueP dependencies(Context& ctx, const Dependency& dep) const {
|
||||
ctx.setVariable(SCRIPT_VAR_input, a->dependencies(ctx, dep));
|
||||
return b->dependencies(ctx, dep);
|
||||
}
|
||||
|
||||
private:
|
||||
ScriptValueP a,b;
|
||||
};
|
||||
|
||||
@@ -173,8 +173,6 @@ ScriptValueP Context::dependencies(const Dependency& dep, const Script& script)
|
||||
|
||||
// Analyze the current instruction
|
||||
Instruction i = *instr++;
|
||||
// If a scope is created, destroy it at end of block.
|
||||
scoped_ptr<LocalScope> scope;
|
||||
switch (i.instr) {
|
||||
case I_NOP: break;
|
||||
// Push a constant (as normal)
|
||||
@@ -263,8 +261,10 @@ ScriptValueP Context::dependencies(const Dependency& dep, const Script& script)
|
||||
}
|
||||
|
||||
// Function call (as normal)
|
||||
case I_CALL: scope.reset(new LocalScope(*this)); //new scope
|
||||
case I_TAILCALL: {
|
||||
// Don't optimize tail calls; we may not jump as we normally do
|
||||
case I_CALL: case I_TAILCALL: {
|
||||
// open a new scope
|
||||
LocalScope new_scope(*this);
|
||||
// prepare arguments
|
||||
for (unsigned int j = 0 ; j < i.data ; ++j) {
|
||||
setVariable((Variable)instr[i.data - j - 1].data, stack.back());
|
||||
|
||||
@@ -59,10 +59,10 @@
|
||||
{ return SCRIPT_FUNCTION; } \
|
||||
virtual String typeName() const \
|
||||
{ return _("built-in function '") _(#name) _("'"); } \
|
||||
virtual ScriptValueP eval(Context&) const; \
|
||||
virtual ScriptValueP do_eval(Context&, bool) const; \
|
||||
}; \
|
||||
ScriptValueP script_##name(new ScriptBuiltIn_##name); \
|
||||
ScriptValueP ScriptBuiltIn_##name::eval(Context& ctx) const
|
||||
ScriptValueP ScriptBuiltIn_##name::do_eval(Context& ctx, bool) const
|
||||
|
||||
/// Return a value from a SCRIPT_FUNCTION
|
||||
#define SCRIPT_RETURN(value) return to_script(value)
|
||||
@@ -160,7 +160,8 @@ inline Type from_script(const ScriptValueP& v, Variable var) {
|
||||
inline ScriptRule_##funname(const type1& name1) : name1(name1) {} \
|
||||
virtual ScriptType type() const { return SCRIPT_FUNCTION; } \
|
||||
virtual String typeName() const { return _(#funname)_("_rule"); } \
|
||||
virtual ScriptValueP eval(Context& ctx) const; \
|
||||
protected: \
|
||||
virtual ScriptValueP do_eval(Context& ctx, bool) const; \
|
||||
private: \
|
||||
type1 name1; \
|
||||
}; \
|
||||
@@ -172,7 +173,7 @@ inline Type from_script(const ScriptValueP& v, Variable var) {
|
||||
SCRIPT_PARAM_N(type1, str1, name1); \
|
||||
return ScriptRule_##funname(name1).eval(ctx); \
|
||||
} \
|
||||
ScriptValueP ScriptRule_##funname::eval(Context& ctx) const
|
||||
ScriptValueP ScriptRule_##funname::do_eval(Context& ctx, bool) const
|
||||
|
||||
/// Utility for defining a script rule with two parameters
|
||||
#define SCRIPT_RULE_2(funname, type1, name1, type2, name2) \
|
||||
@@ -199,8 +200,9 @@ inline Type from_script(const ScriptValueP& v, Variable var) {
|
||||
: name1(name1), name2(name2) {} \
|
||||
virtual ScriptType type() const { return SCRIPT_FUNCTION; } \
|
||||
virtual String typeName() const { return _(#funname)_("_rule"); } \
|
||||
virtual ScriptValueP eval(Context& ctx) const; \
|
||||
dep \
|
||||
protected: \
|
||||
virtual ScriptValueP do_eval(Context& ctx, bool) const; \
|
||||
private: \
|
||||
type1 name1; \
|
||||
type2 name2; \
|
||||
@@ -216,7 +218,7 @@ inline Type from_script(const ScriptValueP& v, Variable var) {
|
||||
return ScriptRule_##funname(name1, name2).eval(ctx); \
|
||||
} \
|
||||
more \
|
||||
ScriptValueP ScriptRule_##funname::eval(Context& ctx) const
|
||||
ScriptValueP ScriptRule_##funname::do_eval(Context& ctx, bool) const
|
||||
|
||||
#define SCRIPT_RULE_2_DEPENDENCIES(name) \
|
||||
ScriptValueP ScriptRule_##name::dependencies(Context& ctx, const Dependency& dep) const
|
||||
|
||||
@@ -89,8 +89,8 @@ ScriptType Script::type() const {
|
||||
String Script::typeName() const {
|
||||
return _("function");
|
||||
}
|
||||
ScriptValueP Script::eval(Context& ctx) const {
|
||||
return ctx.eval(*this);
|
||||
ScriptValueP Script::do_eval(Context& ctx, bool openScope) const {
|
||||
return ctx.eval(*this, openScope);
|
||||
}
|
||||
ScriptValueP Script::dependencies(Context& ctx, const Dependency& dep) const {
|
||||
return ctx.dependencies(dep, *this);
|
||||
@@ -239,11 +239,12 @@ String Script::dumpInstr(unsigned int pos, Instruction i) const {
|
||||
const Instruction* Script::backtraceSkip(const Instruction* instr, int to_skip) const {
|
||||
unsigned int initial = instr - &instructions[0];
|
||||
for (;instr >= &instructions[0] &&
|
||||
(to_skip || // we have something to skip
|
||||
(to_skip || (// we have something to skip
|
||||
instr >= &instructions[1] && (
|
||||
(instr-1)->instr == I_JUMP // always look inside a jump
|
||||
|| (instr-1)->instr == I_NOP // and skip nops
|
||||
)
|
||||
)
|
||||
) ; --instr) {
|
||||
// skip an instruction
|
||||
switch (instr->instr) {
|
||||
@@ -317,7 +318,7 @@ const Instruction* Script::backtraceSkip(const Instruction* instr, int to_skip)
|
||||
}
|
||||
|
||||
String Script::instructionName(const Instruction* instr) const {
|
||||
if (instr < &instructions[0] || instr >= &instructions[instructions.size()]) return _("??\?");
|
||||
if (instr < &instructions[0] || instr >= &instructions[0] + instructions.size()) return _("??\?");
|
||||
if (instr->instr == I_GET_VAR) {
|
||||
return variable_to_string((Variable)instr->data);
|
||||
} else if (instr->instr == I_MEMBER_C) {
|
||||
|
||||
@@ -165,7 +165,6 @@ class Script : public ScriptValue {
|
||||
|
||||
virtual ScriptType type() const;
|
||||
virtual String typeName() const;
|
||||
virtual ScriptValueP eval(Context& ctx) const;
|
||||
virtual ScriptValueP dependencies(Context& ctx, const Dependency&) const;
|
||||
|
||||
/// Add a jump instruction, later comeFrom should be called on the returned value
|
||||
@@ -194,7 +193,10 @@ class Script : public ScriptValue {
|
||||
String dumpScript() const;
|
||||
/// Output an instruction in a human readable format
|
||||
String dumpInstr(unsigned int pos, Instruction i) const;
|
||||
|
||||
|
||||
protected:
|
||||
virtual ScriptValueP do_eval(Context& ctx, bool openScope) const;
|
||||
|
||||
private:
|
||||
/// Data of the instructions that make up this script
|
||||
vector<Instruction> instructions;
|
||||
|
||||
+11
-3
@@ -84,9 +84,12 @@ class ScriptDelayedError : public ScriptValue {
|
||||
// these can propagate the error
|
||||
virtual ScriptValueP getMember(const String& name) const;
|
||||
virtual ScriptValueP dependencyMember(const String& name, const Dependency&) const;
|
||||
virtual ScriptValueP eval(Context&) const;
|
||||
virtual ScriptValueP dependencies(Context&, const Dependency&) const;
|
||||
virtual ScriptValueP makeIterator(const ScriptValueP& thisP) const;
|
||||
|
||||
protected:
|
||||
virtual ScriptValueP do_eval(Context&, bool openScope) const;
|
||||
|
||||
private:
|
||||
ScriptError error; // the error message
|
||||
};
|
||||
@@ -349,7 +352,6 @@ class ScriptClosure : public ScriptValue {
|
||||
|
||||
virtual ScriptType type() const;
|
||||
virtual String typeName() const;
|
||||
virtual ScriptValueP eval(Context& ctx) const;
|
||||
virtual ScriptValueP dependencies(Context& ctx, const Dependency& dep) const;
|
||||
|
||||
/// Add a binding
|
||||
@@ -365,6 +367,9 @@ class ScriptClosure : public ScriptValue {
|
||||
/// The default argument bindings
|
||||
vector<pair<Variable,ScriptValueP> > bindings;
|
||||
|
||||
protected:
|
||||
virtual ScriptValueP do_eval(Context& ctx, bool openScope) const;
|
||||
|
||||
private:
|
||||
/// Apply the bindings in a context
|
||||
void applyBindings(Context& ctx) const;
|
||||
@@ -376,7 +381,10 @@ class ScriptRule : public ScriptValue {
|
||||
inline ScriptRule(const ScriptValueP& fun) : fun(fun) {}
|
||||
virtual ScriptType type() const;
|
||||
virtual String typeName() const;
|
||||
virtual ScriptValueP eval(Context& ctx) const;
|
||||
|
||||
protected:
|
||||
virtual ScriptValueP do_eval(Context& ctx, bool openScope) const;
|
||||
|
||||
private:
|
||||
ScriptValueP fun;
|
||||
};
|
||||
|
||||
@@ -25,7 +25,7 @@ ScriptValue::operator bool() const { throw Script
|
||||
ScriptValue::operator double() const { throw ScriptErrorConversion(typeName(), _TYPE_("double" )); }
|
||||
ScriptValue::operator AColor() const { throw ScriptErrorConversion(typeName(), _TYPE_("color" )); }
|
||||
ScriptValue::operator wxDateTime() const { throw ScriptErrorConversion(typeName(), _TYPE_("date" )); }
|
||||
ScriptValueP ScriptValue::eval(Context&) const { return delay_error(ScriptErrorConversion(typeName(), _TYPE_("function"))); }
|
||||
ScriptValueP ScriptValue::do_eval(Context&, bool) const { return delay_error(ScriptErrorConversion(typeName(), _TYPE_("function"))); }
|
||||
ScriptValueP ScriptValue::next(ScriptValueP* key_out) { throw InternalError(_("Can't convert from ")+typeName()+_(" to iterator")); }
|
||||
ScriptValueP ScriptValue::makeIterator(const ScriptValueP&) const { return delay_error(ScriptErrorConversion(typeName(), _TYPE_("collection"))); }
|
||||
int ScriptValue::itemCount() const { throw ScriptErrorConversion(typeName(), _TYPE_("collection")); }
|
||||
@@ -113,7 +113,7 @@ int ScriptDelayedError::itemCount() const { throw error; }
|
||||
CompareWhat ScriptDelayedError::compareAs(String&, void const*&) const { throw error; }
|
||||
ScriptValueP ScriptDelayedError::getMember(const String&) const { return new_intrusive1<ScriptDelayedError>(error); }
|
||||
ScriptValueP ScriptDelayedError::dependencyMember(const String&, const Dependency&) const { return new_intrusive1<ScriptDelayedError>(error); }
|
||||
ScriptValueP ScriptDelayedError::eval(Context&) const { return new_intrusive1<ScriptDelayedError>(error); }
|
||||
ScriptValueP ScriptDelayedError::do_eval(Context&, bool) const { return new_intrusive1<ScriptDelayedError>(error); }
|
||||
ScriptValueP ScriptDelayedError::dependencies(Context&, const Dependency&) const { return new_intrusive1<ScriptDelayedError>(error); }
|
||||
ScriptValueP ScriptDelayedError::makeIterator(const ScriptValueP& thisP) const { return thisP; }
|
||||
|
||||
@@ -370,7 +370,9 @@ class ScriptNil : public ScriptValue {
|
||||
virtual GeneratedImageP toImage(const ScriptValueP&) const {
|
||||
return new_intrusive<BlankImage>();
|
||||
}
|
||||
virtual ScriptValueP eval(Context& ctx) const {
|
||||
|
||||
protected:
|
||||
virtual ScriptValueP do_eval(Context& ctx, bool) const {
|
||||
// nil(input) == input
|
||||
return ctx.getVariable(SCRIPT_VAR_input);
|
||||
}
|
||||
@@ -513,10 +515,10 @@ ScriptValueP ScriptClosure::simplify() {
|
||||
return fun->simplifyClosure(*this);
|
||||
}
|
||||
|
||||
ScriptValueP ScriptClosure::eval(Context& ctx) const {
|
||||
LocalScope scope(ctx);
|
||||
ScriptValueP ScriptClosure::do_eval(Context& ctx, bool openScope) const {
|
||||
scoped_ptr<LocalScope> scope(openScope ? new LocalScope(ctx) : nullptr);
|
||||
applyBindings(ctx);
|
||||
return fun->eval(ctx);
|
||||
return fun->eval(ctx, openScope);
|
||||
}
|
||||
ScriptValueP ScriptClosure::dependencies(Context& ctx, const Dependency& dep) const {
|
||||
LocalScope scope(ctx);
|
||||
@@ -534,6 +536,6 @@ void ScriptClosure::applyBindings(Context& ctx) const {
|
||||
|
||||
ScriptType ScriptRule::type() const { return SCRIPT_FUNCTION; }
|
||||
String ScriptRule::typeName() const { return fun->typeName() + _(" rule"); }
|
||||
ScriptValueP ScriptRule::eval(Context& ctx) const {
|
||||
ScriptValueP ScriptRule::do_eval(Context& ctx, bool openScope) const {
|
||||
return ctx.makeClosure(fun);
|
||||
}
|
||||
|
||||
@@ -97,7 +97,9 @@ class ScriptValue : public IntrusivePtrBaseWithDelete {
|
||||
virtual ScriptValueP dependencyName(const ScriptValue& container, const Dependency&) const;
|
||||
|
||||
/// Evaluate this value (if it is a function)
|
||||
virtual ScriptValueP eval(Context&) const;
|
||||
ScriptValueP eval(Context& ctx, bool openScope = true) const {
|
||||
return do_eval(ctx, openScope);
|
||||
}
|
||||
/// Mark the scripts that this function depends on
|
||||
/** Return value is an abstract version of the return value of eval */
|
||||
virtual ScriptValueP dependencies(Context&, const Dependency&) const;
|
||||
@@ -117,6 +119,9 @@ class ScriptValue : public IntrusivePtrBaseWithDelete {
|
||||
virtual int itemCount() const;
|
||||
/// Get a member at the given index
|
||||
virtual ScriptValueP getIndex(int index) const;
|
||||
|
||||
protected:
|
||||
virtual ScriptValueP do_eval(Context& ctx, bool openScope) const;
|
||||
};
|
||||
|
||||
extern ScriptValueP script_nil; ///< The preallocated nil value
|
||||
|
||||
Reference in New Issue
Block a user