diff options
author | Ben Longbons <b.r.longbons@gmail.com> | 2014-07-23 23:55:41 -0700 |
---|---|---|
committer | Ben Longbons <b.r.longbons@gmail.com> | 2014-08-05 17:41:35 -0700 |
commit | a7f64f0b39cb7141f16608c171b20bee452fd024 (patch) | |
tree | 6ceb293db3488161d4d5a620536560506e63134f /src/map/magic-interpreter.hpp | |
parent | 7abac74323e2566173ea586e9acadac1ebf59098 (diff) | |
download | tmwa-a7f64f0b39cb7141f16608c171b20bee452fd024.tar.gz tmwa-a7f64f0b39cb7141f16608c171b20bee452fd024.tar.bz2 tmwa-a7f64f0b39cb7141f16608c171b20bee452fd024.tar.xz tmwa-a7f64f0b39cb7141f16608c171b20bee452fd024.zip |
In magic, use Variant for all the old anonymous nested unions
Diffstat (limited to 'src/map/magic-interpreter.hpp')
-rw-r--r-- | src/map/magic-interpreter.hpp | 580 |
1 files changed, 385 insertions, 195 deletions
diff --git a/src/map/magic-interpreter.hpp b/src/map/magic-interpreter.hpp index 62ab504..01775b3 100644 --- a/src/map/magic-interpreter.hpp +++ b/src/map/magic-interpreter.hpp @@ -32,6 +32,8 @@ #include "../generic/fwd.hpp" +#include "../sexpr/variant.hpp" + #include "../net/timer.t.hpp" #include "../mmo/ids.hpp" @@ -52,55 +54,133 @@ struct location_t int x, y; }; -struct area_t +struct AreaUnion +{ + dumb_ptr<area_t> a_union[2]; +}; +struct AreaRect +{ + location_t loc; + int width, height; +}; +struct AreaBar +{ + location_t loc; + int width, depth; + DIR dir; +}; + +using AreaVariantBase = Variant< + location_t, + AreaUnion, + AreaRect, + AreaBar +>; + +struct area_t : AreaVariantBase { - union au - { - location_t a_loc; - struct - { - location_t loc; - int width, depth; - DIR dir; - } a_bar; - struct - { - location_t loc; - int width, height; - } a_rect; - dumb_ptr<area_t> a_union[2]; - - au() { really_memzero_this(this); } - ~au() = default; - au(const au&) = default; - au& operator = (const au&) = default; - } a; int size; - AREA ty; + + area_t() = delete; + area_t(area_t&&) = default; + area_t(const area_t&) = delete; + area_t& operator = (area_t&&) = default; + area_t& operator = (const area_t&) = delete; + + area_t(location_t v, int sz) : AreaVariantBase(std::move(v)), size(sz) {} + area_t(AreaUnion v, int sz) : AreaVariantBase(std::move(v)), size(sz) {} + area_t(AreaRect v, int sz) : AreaVariantBase(std::move(v)), size(sz) {} + area_t(AreaBar v, int sz) : AreaVariantBase(std::move(v)), size(sz) {} }; -struct val_t +struct ValUndef { - union vu - { - int v_int; - DIR v_dir; - dumb_string v_string; - /* Used ONLY during operation/function invocation; otherwise we use v_int */ - dumb_ptr<block_list> v_entity; - dumb_ptr<area_t> v_area; - location_t v_location; - /* Used ONLY during operation/function invocation; otherwise we use v_int */ - dumb_ptr<invocation> v_invocation; - dumb_ptr<spell_t> v_spell; - - vu() { really_memzero_this(this); } - ~vu() = default; - vu(const vu&) = default; - vu& operator = (const vu&) = default; - } v; - TYPE ty; }; +struct ValInt +{ + int v_int; +}; +struct ValDir +{ + DIR v_dir; +}; +struct ValString +{ + dumb_string v_string; +}; +struct ValEntityInt +{ + BlockId v_eid; +}; +struct ValEntityPtr +{ + dumb_ptr<block_list> v_entity; +}; +struct ValLocation +{ + location_t v_location; +}; +struct ValArea +{ + dumb_ptr<area_t> v_area; +}; +struct ValSpell +{ + dumb_ptr<spell_t> v_spell; +}; +struct ValInvocationInt +{ + BlockId v_iid; +}; +struct ValInvocationPtr +{ + dumb_ptr<invocation> v_invocation; +}; +struct ValFail +{ +}; +struct ValNegative1 +{ +}; + +using ValVariantBase = Variant< + ValUndef, + ValInt, + ValDir, + ValString, + ValEntityInt, + ValEntityPtr, + ValLocation, + ValArea, + ValSpell, + ValInvocationInt, + ValInvocationPtr, + ValFail, + ValNegative1 +>; +struct val_t : ValVariantBase +{ + val_t() noexcept : ValVariantBase(ValUndef{}) {} + val_t(val_t&&) = default; + val_t(const val_t&) = delete; + val_t& operator = (val_t&&) = default; + val_t& operator = (const val_t&) = delete; + + val_t(ValUndef v) : ValVariantBase(std::move(v)) {} + val_t(ValInt v) : ValVariantBase(std::move(v)) {} + val_t(ValDir v) : ValVariantBase(std::move(v)) {} + val_t(ValString v) : ValVariantBase(std::move(v)) {} + val_t(ValEntityInt v) : ValVariantBase(std::move(v)) {} + val_t(ValEntityPtr v) : ValVariantBase(std::move(v)) {} + val_t(ValLocation v) : ValVariantBase(std::move(v)) {} + val_t(ValArea v) : ValVariantBase(std::move(v)) {} + val_t(ValSpell v) : ValVariantBase(std::move(v)) {} + val_t(ValInvocationInt v) : ValVariantBase(std::move(v)) {} + val_t(ValInvocationPtr v) : ValVariantBase(std::move(v)) {} + val_t(ValFail v) : ValVariantBase(std::move(v)) {} + val_t(ValNegative1 v) : ValVariantBase(std::move(v)) {} +}; + /* ----------- */ /* Expressions */ @@ -108,115 +188,187 @@ struct val_t #define MAX_ARGS 7 /* Max. # of args used in builtin primitive functions */ +struct e_area_t; + struct e_location_t { dumb_ptr<expr_t> m, x, y; + + e_location_t() noexcept : m(), x(), y() {} +}; +struct ExprAreaUnion +{ + dumb_ptr<e_area_t> a_union[2]; +}; +struct ExprAreaRect +{ + e_location_t loc; + dumb_ptr<expr_t> width, height; +}; +struct ExprAreaBar +{ + e_location_t loc; + dumb_ptr<expr_t> width, depth, dir; }; -struct e_area_t +using ExprAreaVariantBase = Variant< + e_location_t, + ExprAreaUnion, + ExprAreaRect, + ExprAreaBar +>; + +struct e_area_t : ExprAreaVariantBase { - union a0 - { - e_location_t a_loc; - struct - { - e_location_t loc; - dumb_ptr<expr_t> width, depth, dir; - } a_bar; - struct - { - e_location_t loc; - dumb_ptr<expr_t> width, height; - } a_rect; - dumb_ptr<e_area_t> a_union[2]; - - a0() { really_memzero_this(this); } - ~a0() = default; - a0(const a0&) = default; - a0& operator = (const a0&) = default; - } a; - AREA ty; -}; - -struct expr_t -{ - union eu - { - val_t e_val; - e_location_t e_location; - e_area_t e_area; - struct - { - fun_t *funp; - int line_nr, column; - int args_nr; - dumb_ptr<expr_t> args[MAX_ARGS]; - } e_funapp; - int e_id; - struct - { - dumb_ptr<expr_t> expr; - int id; - } e_field; - - eu() { really_memzero_this(this); } - ~eu() = default; - eu(const eu&) = default; - eu& operator = (const eu&) = default; - } e; - EXPR ty; -}; - -struct effect_t + e_area_t() = delete; + e_area_t(e_area_t&&) = default; + e_area_t(const e_area_t&) = delete; + e_area_t& operator = (e_area_t&&) = default; + e_area_t& operator = (const e_area_t&) = delete; + + e_area_t(e_location_t v) : ExprAreaVariantBase(std::move(v)) {} + e_area_t(ExprAreaUnion v) : ExprAreaVariantBase(std::move(v)) {} + e_area_t(ExprAreaRect v) : ExprAreaVariantBase(std::move(v)) {} + e_area_t(ExprAreaBar v) : ExprAreaVariantBase(std::move(v)) {} +}; + +struct ExprFunApp +{ + fun_t *funp; + int line_nr, column; + int args_nr; + dumb_ptr<expr_t> args[MAX_ARGS]; +}; +struct ExprId +{ + int e_id; +}; +struct ExprField +{ + dumb_ptr<expr_t> expr; + int id; +}; + +using ExprVariantBase = Variant< + val_t, + e_location_t, + e_area_t, + ExprFunApp, + ExprId, + ExprField +>; +struct expr_t : ExprVariantBase +{ + expr_t() = delete; + expr_t(expr_t&&) = default; + expr_t(const expr_t&) = delete; + expr_t& operator = (expr_t&&) = default; + expr_t& operator = (const expr_t&) = delete; + + expr_t(val_t v) : ExprVariantBase(std::move(v)) {} + expr_t(e_location_t v) : ExprVariantBase(std::move(v)) {} + expr_t(e_area_t v) : ExprVariantBase(std::move(v)) {} + expr_t(ExprFunApp v) : ExprVariantBase(std::move(v)) {} + expr_t(ExprId v) : ExprVariantBase(std::move(v)) {} + expr_t(ExprField v) : ExprVariantBase(std::move(v)) {} +}; + + +struct effect_t; + +struct EffectSkip +{ +}; +struct EffectAbort +{ +}; +struct EffectAssign +{ + int id; + dumb_ptr<expr_t> expr; +}; +struct EffectForEach +{ + int id; + dumb_ptr<expr_t> area; + dumb_ptr<effect_t> body; + FOREACH_FILTER filter; +}; +struct EffectFor +{ + int id; + dumb_ptr<expr_t> start, stop; + dumb_ptr<effect_t> body; +}; +struct EffectIf +{ + dumb_ptr<expr_t> cond; + dumb_ptr<effect_t> true_branch, false_branch; +}; +struct EffectSleep +{ + dumb_ptr<expr_t> e_sleep; /* sleep time */ +}; +struct EffectScript +{ + dumb_ptr<const ScriptBuffer> e_script; +}; +struct EffectBreak +{ +}; +struct EffectOp +{ + op_t *opp; + int args_nr; + int line_nr, column; + dumb_ptr<expr_t> args[MAX_ARGS]; +}; +struct EffectEnd +{ +}; +struct EffectCall +{ + std::vector<int> *formalv; + dumb_ptr<std::vector<dumb_ptr<expr_t>>> actualvp; + dumb_ptr<effect_t> body; +}; + +using EffectVariantBase = Variant< + EffectSkip, + EffectAbort, + EffectAssign, + EffectForEach, + EffectFor, + EffectIf, + EffectSleep, + EffectScript, + EffectBreak, + EffectOp, + EffectEnd, + EffectCall +>; +struct effect_t : EffectVariantBase { dumb_ptr<effect_t> next; - union e0 - { - struct - { - int id; - dumb_ptr<expr_t> expr; - } e_assign; - struct - { - int id; - dumb_ptr<expr_t> area; - dumb_ptr<effect_t> body; - FOREACH_FILTER filter; - } e_foreach; - struct - { - int id; - dumb_ptr<expr_t> start, stop; - dumb_ptr<effect_t> body; - } e_for; - struct - { - dumb_ptr<expr_t> cond; - dumb_ptr<effect_t> true_branch, false_branch; - } e_if; - dumb_ptr<expr_t> e_sleep; /* sleep time */ - dumb_ptr<const ScriptBuffer> e_script; - struct - { - op_t *opp; - int args_nr; - int line_nr, column; - dumb_ptr<expr_t> args[MAX_ARGS]; - } e_op; - struct - { - std::vector<int> *formalv; - dumb_ptr<std::vector<dumb_ptr<expr_t>>> actualvp; - dumb_ptr<effect_t> body; - } e_call; - - e0() { really_memzero_this(this); } - ~e0() = default; - e0(const e0&) = default; - e0& operator = (const e0&) = default; - } e; - EFFECT ty; + + effect_t() = delete; + effect_t(effect_t&&) = default; + effect_t(const effect_t&) = delete; + effect_t& operator = (effect_t&&) = default; + effect_t& operator = (const effect_t&) = delete; + + effect_t(EffectSkip v, dumb_ptr<effect_t> n) : EffectVariantBase(std::move(v)), next(n) {} + effect_t(EffectAbort v, dumb_ptr<effect_t> n) : EffectVariantBase(std::move(v)), next(n) {} + effect_t(EffectAssign v, dumb_ptr<effect_t> n) : EffectVariantBase(std::move(v)), next(n) {} + effect_t(EffectForEach v, dumb_ptr<effect_t> n) : EffectVariantBase(std::move(v)), next(n) {} + effect_t(EffectFor v, dumb_ptr<effect_t> n) : EffectVariantBase(std::move(v)), next(n) {} + effect_t(EffectIf v, dumb_ptr<effect_t> n) : EffectVariantBase(std::move(v)), next(n) {} + effect_t(EffectSleep v, dumb_ptr<effect_t> n) : EffectVariantBase(std::move(v)), next(n) {} + effect_t(EffectScript v, dumb_ptr<effect_t> n) : EffectVariantBase(std::move(v)), next(n) {} + effect_t(EffectBreak v, dumb_ptr<effect_t> n) : EffectVariantBase(std::move(v)), next(n) {} + effect_t(EffectOp v, dumb_ptr<effect_t> n) : EffectVariantBase(std::move(v)), next(n) {} + effect_t(EffectEnd v, dumb_ptr<effect_t> n) : EffectVariantBase(std::move(v)), next(n) {} + effect_t(EffectCall v, dumb_ptr<effect_t> n) : EffectVariantBase(std::move(v)), next(n) {} }; /* ---------- */ @@ -231,29 +383,62 @@ struct component_t }; +struct spellguard_t; +struct GuardCondition +{ + dumb_ptr<expr_t> s_condition; +}; +struct GuardMana +{ + dumb_ptr<expr_t> s_mana; +}; +struct GuardCastTime +{ + dumb_ptr<expr_t> s_casttime; +}; +struct GuardComponents +{ + dumb_ptr<component_t> s_components; +}; +struct GuardCatalysts +{ + dumb_ptr<component_t> s_catalysts; +}; +struct GuardChoice +{ + dumb_ptr<spellguard_t> s_alt; /* either `next' or `s.s_alt' */ +}; struct effect_set_t { dumb_ptr<effect_t> effect, at_trigger, at_end; }; -struct spellguard_t +using SpellGuardVariantBase = Variant< + GuardCondition, + GuardMana, + GuardCastTime, + GuardComponents, + GuardCatalysts, + GuardChoice, + effect_set_t +>; +struct spellguard_t : SpellGuardVariantBase { dumb_ptr<spellguard_t> next; - union su - { - dumb_ptr<expr_t> s_condition; - dumb_ptr<expr_t> s_mana; - dumb_ptr<expr_t> s_casttime; - dumb_ptr<component_t> s_components; - dumb_ptr<component_t> s_catalysts; - dumb_ptr<spellguard_t> s_alt; /* either `next' or `s.s_alt' */ - effect_set_t s_effect; - su() { really_memzero_this(this); } - ~su() = default; - su(const su&) = default; - su& operator = (const su&) = default; - } s; - SPELLGUARD ty; + + spellguard_t() = delete; + spellguard_t(spellguard_t&&) = default; + spellguard_t(const spellguard_t&) = delete; + spellguard_t& operator = (spellguard_t&&) = default; + spellguard_t& operator = (const spellguard_t&) = delete; + + spellguard_t(GuardCondition v, dumb_ptr<spellguard_t> n) : SpellGuardVariantBase(std::move(v)), next(n) {} + spellguard_t(GuardMana v, dumb_ptr<spellguard_t> n) : SpellGuardVariantBase(std::move(v)), next(n) {} + spellguard_t(GuardCastTime v, dumb_ptr<spellguard_t> n) : SpellGuardVariantBase(std::move(v)), next(n) {} + spellguard_t(GuardComponents v, dumb_ptr<spellguard_t> n) : SpellGuardVariantBase(std::move(v)), next(n) {} + spellguard_t(GuardCatalysts v, dumb_ptr<spellguard_t> n) : SpellGuardVariantBase(std::move(v)), next(n) {} + spellguard_t(GuardChoice v, dumb_ptr<spellguard_t> n) : SpellGuardVariantBase(std::move(v)), next(n) {} + spellguard_t(effect_set_t v, dumb_ptr<spellguard_t> n) : SpellGuardVariantBase(std::move(v)), next(n) {} }; /* ------ */ @@ -330,7 +515,7 @@ struct env_t val_t& VAR(size_t i) { assert (varu); - if (varu[i].ty == TYPE::UNDEF) + if (varu[i].is<ValUndef>()) return base_env->varv[i].val; else return varu[i]; @@ -338,41 +523,47 @@ struct env_t }; -#define MAX_STACK_SIZE 32 +struct CarForEach +{ + int id; + bool ty_is_spell_not_entity; + dumb_ptr<effect_t> body; + dumb_ptr<std::vector<BlockId>> entities_vp; + int index; +}; +struct CarFor +{ + int id; + dumb_ptr<effect_t> body; + int current; + int stop; +}; +struct CarProc +{ + int args_nr; + int *formalap; + dumb_ptr<val_t[]> old_actualpa; +}; + +using CarVariantBase = Variant< + CarForEach, + CarFor, + CarProc +>; -struct cont_activation_record_t +struct cont_activation_record_t : CarVariantBase { dumb_ptr<effect_t> return_location; - union cu - { - struct - { - int id; - TYPE ty; - dumb_ptr<effect_t> body; - dumb_ptr<std::vector<BlockId>> entities_vp; - int index; - } c_foreach; - struct - { - int id; - dumb_ptr<effect_t> body; - int current; - int stop; - } c_for; - struct - { - int args_nr; - int *formalap; - dumb_ptr<val_t[]> old_actualpa; - } c_proc; - - cu() { really_memzero_this(this); } - ~cu() = default; - cu(const cu&) = default; - cu& operator = (const cu&) = default; - } c; - CONT_STACK ty; + + cont_activation_record_t() = delete; + cont_activation_record_t(cont_activation_record_t&&) = default; + cont_activation_record_t(const cont_activation_record_t&) = delete; + cont_activation_record_t& operator = (cont_activation_record_t&&) = default; + cont_activation_record_t& operator = (const cont_activation_record_t&) = delete; + + cont_activation_record_t(CarForEach v, dumb_ptr<effect_t> rl) : CarVariantBase(std::move(v)), return_location(rl) {} + cont_activation_record_t(CarFor v, dumb_ptr<effect_t> rl) : CarVariantBase(std::move(v)), return_location(rl) {} + cont_activation_record_t(CarProc v, dumb_ptr<effect_t> rl) : CarVariantBase(std::move(v)), return_location(rl) {} }; struct status_change_ref_t @@ -393,8 +584,7 @@ struct invocation : block_list Timer timer; /* spell timer, if any */ - int stack_size; - cont_activation_record_t stack[MAX_STACK_SIZE]; + std::vector<cont_activation_record_t> stack; int script_pos; /* Script position; if nonzero, resume the script we were running. */ dumb_ptr<effect_t> current_effect; |