From 00da6b5977574a0564169172227d8aab45be188f Mon Sep 17 00:00:00 2001 From: Ben Longbons Date: Sat, 3 Jan 2015 21:07:56 -0800 Subject: Switch MATCH to separate begin/end macros The for loop trick turned out to be very prone to infinite loops at runtime. It's better to force compiler errors even if it's ugly. --- src/char/int_party.cpp | 42 ++++++--- src/char/inter.cpp | 3 +- src/compat/attr.hpp | 24 ----- src/compat/attr_test.cpp | 50 ---------- src/compat/option.hpp | 49 ++++++++-- src/compat/option_test.cpp | 32 ++++--- src/generic/db.hpp | 6 +- src/map/atcommand.cpp | 188 ++++++++++++++++++++----------------- src/map/battle.cpp | 8 +- src/map/clif.cpp | 16 ++-- src/map/itemdb.cpp | 12 ++- src/map/magic-expr.cpp | 144 +++++++++++++++------------- src/map/magic-interpreter-base.cpp | 17 ++-- src/map/magic-stmt.cpp | 54 ++++++----- src/map/magic-v2.cpp | 10 +- src/map/map.cpp | 44 +++++---- src/map/mob.cpp | 3 +- src/map/npc-parse.cpp | 26 ++--- src/map/party.cpp | 6 +- src/map/pc.cpp | 70 +++++++++----- src/map/script-call.cpp | 44 +++++---- src/map/script-fun.cpp | 122 ++++++++++++++++-------- src/map/script-parse.cpp | 5 +- src/map/trade.cpp | 14 ++- src/sexpr/fwd.hpp | 1 - src/sexpr/variant.hpp | 46 +++++++-- src/sexpr/variant_test.cpp | 32 ++++--- 27 files changed, 607 insertions(+), 461 deletions(-) delete mode 100644 src/compat/attr_test.cpp (limited to 'src') diff --git a/src/char/int_party.cpp b/src/char/int_party.cpp index 5000ff2..731669a 100644 --- a/src/char/int_party.cpp +++ b/src/char/int_party.cpp @@ -327,19 +327,23 @@ void mapif_party_created(Session *s, AccountId account_id, Option p_) { Packet_Fixed<0x3820> fixed_20; fixed_20.account_id = account_id; - if OPTION_IS_SOME_NOLOOP(p, p_) + OMATCH_BEGIN (p_) { - fixed_20.error = 0; - fixed_20.party_id = p.party_id; - fixed_20.party_name = p->name; - PRINTF("int_party: created! %d %s\n"_fmt, p.party_id, p->name); - } - else - { - fixed_20.error = 1; - fixed_20.party_id = PartyId(); - fixed_20.party_name = stringish("error"_s); + OMATCH_CASE_SOME (p) + { + fixed_20.error = 0; + fixed_20.party_id = p.party_id; + fixed_20.party_name = p->name; + PRINTF("int_party: created! %d %s\n"_fmt, p.party_id, p->name); + } + OMATCH_CASE_NONE () + { + fixed_20.error = 1; + fixed_20.party_id = PartyId(); + fixed_20.party_name = stringish("error"_s); + } } + OMATCH_END (); send_fpacket<0x3820, 35>(s, fixed_20); } @@ -524,10 +528,18 @@ static void mapif_parse_PartyInfo(Session *s, PartyId party_id) { Option> maybe_party_most = party_db.search(party_id); - if OPTION_IS_SOME_NOLOOP(party_most, maybe_party_most) - mapif_party_info(s, PartyPair{party_id, party_most}); - else - mapif_party_noinfo(s, party_id); + OMATCH_BEGIN (maybe_party_most) + { + OMATCH_CASE_SOME (party_most) + { + mapif_party_info(s, PartyPair{party_id, party_most}); + } + OMATCH_CASE_NONE () + { + mapif_party_noinfo(s, party_id); + } + } + OMATCH_END (); } // パーティ追加要求 diff --git a/src/char/inter.cpp b/src/char/inter.cpp index eccfc1b..c081825 100644 --- a/src/char/inter.cpp +++ b/src/char/inter.cpp @@ -270,7 +270,7 @@ void mapif_account_reg_reply(Session *s, AccountId account_id) Packet_Head<0x3804> head_04; head_04.account_id = account_id; std::vector> repeat_04; - if OPTION_IS_SOME_NOLOOP(reg, reg_) + OMATCH_BEGIN_SOME (reg, reg_) { repeat_04.resize(reg->reg_num); assert (reg->reg_num < ACCOUNT_REG_NUM); @@ -280,6 +280,7 @@ void mapif_account_reg_reply(Session *s, AccountId account_id) repeat_04[j].value = reg->reg[j].value; } } + OMATCH_END (); send_vpacket<0x3804, 8, 36>(s, head_04, repeat_04); } diff --git a/src/compat/attr.hpp b/src/compat/attr.hpp index 9ddf654..5ebef6d 100644 --- a/src/compat/attr.hpp +++ b/src/compat/attr.hpp @@ -30,28 +30,4 @@ namespace tmwa #endif #define JOIN(a, b) a##b - -// first loop: -// declare flag 'guard' (initially true) -// declare flag 'broken' (initially false) -// condition is 'guard' must be true, which is the case only for the first iteration -// post checks 'broken' and if set, break the loop -// second loop: -// declare public 'var' variable -// condition is that 'guard' must be true -// post sets 'guard' to false to make this loop run only once -// third loop: -// enable broken flag; it will remain set if 'break' is in the loop -// condition is that 'broken' must be true -// post sets 'broken' to false, which then fails the condition -// if user has a 'break' inside, then 'broken' will be true -// in either case, go back to the second loop's post -#define WITH_VAR_INLOOP(ty, var, expr) \ - for (bool JOIN(var, _guard) = true, JOIN(var, _broken) = false; JOIN(var, _guard); ({if (JOIN(var, _broken)) { break; } })) \ - for (ty var = expr; JOIN(var, _guard); JOIN(var, _guard) = false) \ - for (JOIN(var, _broken) = true; JOIN(var, _broken); JOIN(var, _broken) = false) -#define WITH_VAR_NOLOOP(ty, var, expr) \ - for (bool JOIN(var, _guard) = true, JOIN(var, _broken) = false; JOIN(var, _guard); ({if (JOIN(var, _broken)) {abort();} })) \ - for (ty var = expr; JOIN(var, _guard); JOIN(var, _guard) = false) \ - for (JOIN(var, _broken) = true; JOIN(var, _broken); JOIN(var, _broken) = false) } // namespace tmwa diff --git a/src/compat/attr_test.cpp b/src/compat/attr_test.cpp deleted file mode 100644 index eb9042d..0000000 --- a/src/compat/attr_test.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "attr.hpp" -// attr_test.cpp - Tests for attributes -// -// Copyright © 2014 Ben Longbons -// -// This file is part of The Mana World (Athena server) -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . - -#include - -#include "../poison.hpp" - - -namespace tmwa -{ -TEST(attr, withvar) -{ - int x = 41; - for (int i = 0; i < 2; ++i) - { - WITH_VAR_NOLOOP(auto, y, x + 1) - { - x = y; - } - } - EXPECT_EQ(x, 43); - for (int i = 0; i < 2; ++i) - { - if (i == 1) - WITH_VAR_INLOOP(auto, y, i) - { - x = y; - break; - } - } - EXPECT_EQ(x, 1); -} -} // namespace tmwa diff --git a/src/compat/option.hpp b/src/compat/option.hpp index 7beef6f..b6e7655 100644 --- a/src/compat/option.hpp +++ b/src/compat/option.hpp @@ -24,8 +24,6 @@ #include -#include "attr.hpp" - namespace tmwa { @@ -423,13 +421,46 @@ namespace option if (o.maybe_ref.is_none()) falsy; \ tmwa::option::option_unwrap(std::move(o)); \ }).maybe_ref_fun() -// immediately preceded by 'if'; not double-eval-safe -#define OPTION_IS_SOME_INLOOP(var, expr) \ - ((expr).is_some()) \ - WITH_VAR_INLOOP(auto&, var, *(expr).ptr_or(nullptr)) -#define OPTION_IS_SOME_NOLOOP(var, expr) \ - ((expr).is_some()) \ - WITH_VAR_NOLOOP(auto&, var, *(expr).ptr_or(nullptr)) + +#define OMATCH_BEGIN(expr) \ + { \ + auto&& _omatch_var = (expr); \ + switch (_omatch_var.is_some()) \ + { \ + { \ + { \ + /*}}}}*/ +#define OMATCH_END() \ + /*{{{{*/ \ + } \ + } \ + } \ + (void) _omatch_var; \ + } + +#define OMATCH_BEGIN_SOME(var, expr) \ + OMATCH_BEGIN (expr) \ + OMATCH_CASE_SOME (var) + +#define OMATCH_CASE_SOME(var) \ + /*{{{{*/ \ + } \ + break; \ + } \ + { \ + case true: \ + { \ + auto&& var = *_omatch_var.ptr_or(nullptr); \ + /*}}}}*/ +#define OMATCH_CASE_NONE() \ + /*{{{{*/ \ + } \ + break; \ + } \ + { \ + case false: \ + { \ + /*}}}}*/ } // namespace option //using option::Option; diff --git a/src/compat/option_test.cpp b/src/compat/option_test.cpp index f9cec0e..69f3a60 100644 --- a/src/compat/option_test.cpp +++ b/src/compat/option_test.cpp @@ -398,24 +398,32 @@ TEST(Option, unwrap) v = None; TRY_UNWRAP(fcr(), v = Some(1)); v = None; - if OPTION_IS_SOME_NOLOOP(o, v) + OMATCH_BEGIN (v) { - EXPECT_NE(o, o); - } - else - { - SUCCEED(); + OMATCH_CASE_SOME (o) + { + EXPECT_NE(o, o); + } + OMATCH_CASE_NONE () + { + SUCCEED(); + } } + OMATCH_END (); v = Some(1); - if OPTION_IS_SOME_NOLOOP(o, v) + OMATCH_BEGIN (v) { - EXPECT_EQ(o, 1); - } - else - { - FAIL(); + OMATCH_CASE_SOME (o) + { + EXPECT_EQ(o, 1); + } + OMATCH_CASE_NONE () + { + FAIL(); + } } + OMATCH_END (); } TEST(Option, flatten) diff --git a/src/generic/db.hpp b/src/generic/db.hpp index b0dcf0c..04ead79 100644 --- a/src/generic/db.hpp +++ b/src/generic/db.hpp @@ -115,10 +115,11 @@ public: V get(const K& k) { Option> vp = impl.search(k); - if OPTION_IS_SOME_NOLOOP(v, vp) + OMATCH_BEGIN_SOME (v, vp) { return *v; } + OMATCH_END (); return V(); } void put(const K& k, V v) @@ -162,10 +163,11 @@ public: Option> get(const K& k) { Option> up = impl.search(k); - if OPTION_IS_SOME_NOLOOP(u, up) + OMATCH_BEGIN_SOME (u, up) { return Some(borrow(*u->get())); } + OMATCH_END (); return None; } void put(const K& k, U v) diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp index bd1690d..f08d561 100644 --- a/src/map/atcommand.cpp +++ b/src/map/atcommand.cpp @@ -375,17 +375,24 @@ bool atcommand_config_read(ZString cfgName) continue; } Option> p_ = get_atcommandinfo_byname(w1); - if OPTION_IS_SOME_NOLOOP(p, p_) + OMATCH_BEGIN (p_) { - p->level = GmLevel::from(static_cast(atoi(w2.c_str()))); - } - else if (w1 == "import"_s) - rv &= atcommand_config_read(w2); - else - { - PRINTF("%s: bad line: %s\n"_fmt, cfgName, line); - rv = false; + OMATCH_CASE_SOME (p) + { + p->level = GmLevel::from(static_cast(atoi(w2.c_str()))); + } + OMATCH_CASE_NONE () + { + if (w1 == "import"_s) + rv &= atcommand_config_read(w2); + else + { + PRINTF("%s: bad line: %s\n"_fmt, cfgName, line); + rv = false; + } + } } + OMATCH_END (); } return rv; @@ -3406,41 +3413,45 @@ ATCE atcommand_partyrecall(Session *s, dumb_ptr sd, Option p_ = party_searchname(party_name); if (p_.is_none()) p_ = party_search(wrap(static_cast(atoi(message.c_str())))); - if OPTION_IS_SOME_NOLOOP(p, p_) + OMATCH_BEGIN (p_) { - count = 0; - for (io::FD i : iter_fds()) + OMATCH_CASE_SOME (p) { - Session *s2 = get_session(i); - if (!s2) - continue; - dumb_ptr pl_sd = dumb_ptr(static_cast(s2->session_data.get())); - if (pl_sd && pl_sd->state.auth - && sd->status_key.account_id != pl_sd->status_key.account_id - && pl_sd->status.party_id == p.party_id) + count = 0; + for (io::FD i : iter_fds()) { - if (pl_sd->bl_m->flag.get(MapFlag::NOWARP) - && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast(battle_config.any_warp_GM_min_level))))) - count++; - else - pc_setpos(pl_sd, sd->mapname_, sd->bl_x, sd->bl_y, BeingRemoveWhy::QUIT); + Session *s2 = get_session(i); + if (!s2) + continue; + dumb_ptr pl_sd = dumb_ptr(static_cast(s2->session_data.get())); + if (pl_sd && pl_sd->state.auth + && sd->status_key.account_id != pl_sd->status_key.account_id + && pl_sd->status.party_id == p.party_id) + { + if (pl_sd->bl_m->flag.get(MapFlag::NOWARP) + && !(pc_isGM(sd).satisfies(GmLevel::from(static_cast(battle_config.any_warp_GM_min_level))))) + count++; + else + pc_setpos(pl_sd, sd->mapname_, sd->bl_x, sd->bl_y, BeingRemoveWhy::QUIT); + } + } + AString output = STRPRINTF("All online characters of the %s party are near you."_fmt, p->name); + clif_displaymessage(s, output); + if (count) + { + output = STRPRINTF( + "Because you are not authorised to warp from some maps, %d player(s) have not been recalled."_fmt, + count); + clif_displaymessage(s, output); } } - AString output = STRPRINTF("All online characters of the %s party are near you."_fmt, p->name); - clif_displaymessage(s, output); - if (count) + OMATCH_CASE_NONE () { - output = STRPRINTF( - "Because you are not authorised to warp from some maps, %d player(s) have not been recalled."_fmt, - count); - clif_displaymessage(s, output); + clif_displaymessage(s, "Incorrect name or ID, or no one from the party is online."_s); + return ATCE::EXIST; } } - else - { - clif_displaymessage(s, "Incorrect name or ID, or no one from the party is online."_s); - return ATCE::EXIST; - } + OMATCH_END (); return ATCE::OKAY; } @@ -3588,26 +3599,30 @@ ATCE atcommand_partyspy(Session *s, dumb_ptr sd, Option p_ = party_searchname(party_name); if (p_.is_none()) p_ = party_search(wrap(static_cast(atoi(message.c_str())))); - if OPTION_IS_SOME_NOLOOP(p, p_) + OMATCH_BEGIN (p_) { - if (sd->partyspy == p.party_id) + OMATCH_CASE_SOME (p) { - sd->partyspy = PartyId(); - AString output = STRPRINTF("No longer spying on the %s party."_fmt, p->name); - clif_displaymessage(s, output); + if (sd->partyspy == p.party_id) + { + sd->partyspy = PartyId(); + AString output = STRPRINTF("No longer spying on the %s party."_fmt, p->name); + clif_displaymessage(s, output); + } + else + { + sd->partyspy = p.party_id; + AString output = STRPRINTF("Spying on the %s party."_fmt, p->name); + clif_displaymessage(s, output); + } } - else + OMATCH_CASE_NONE () { - sd->partyspy = p.party_id; - AString output = STRPRINTF("Spying on the %s party."_fmt, p->name); - clif_displaymessage(s, output); + clif_displaymessage(s, "Incorrect name or ID, or no one from the party is online."_s); + return ATCE::EXIST; } } - else - { - clif_displaymessage(s, "Incorrect name or ID, or no one from the party is online."_s); - return ATCE::EXIST; - } + OMATCH_END (); return ATCE::OKAY; } @@ -3962,51 +3977,55 @@ ATCE atcommand_character_storage_list(Session *s, dumb_ptr sd, { // you can look items only lower or same level Option> stor_ = account2storage2(pl_sd->status_key.account_id); - if OPTION_IS_SOME_NOLOOP(stor, stor_) + OMATCH_BEGIN (stor_) { - counter = 0; - count = 0; - for (SOff0 i : SOff0::iter()) + OMATCH_CASE_SOME (stor) { - if (!stor->storage_[i].nameid) - continue; - P item_data = TRY_UNWRAP(itemdb_exists(stor->storage_[i].nameid), continue); - + counter = 0; + count = 0; + for (SOff0 i : SOff0::iter()) { - counter = counter + stor->storage_[i].amount; - count++; - if (count == 1) + if (!stor->storage_[i].nameid) + continue; + P item_data = TRY_UNWRAP(itemdb_exists(stor->storage_[i].nameid), continue); + { - AString output = STRPRINTF( - "------ Storage items list of '%s' ------"_fmt, - pl_sd->status_key.name); + counter = counter + stor->storage_[i].amount; + count++; + if (count == 1) + { + AString output = STRPRINTF( + "------ Storage items list of '%s' ------"_fmt, + pl_sd->status_key.name); + clif_displaymessage(s, output); + } + AString output; + if (true) + output = STRPRINTF("%d %s (%s, id: %d)"_fmt, + stor->storage_[i].amount, + item_data->name, item_data->jname, + stor->storage_[i].nameid); clif_displaymessage(s, output); } - AString output; - if (true) - output = STRPRINTF("%d %s (%s, id: %d)"_fmt, - stor->storage_[i].amount, - item_data->name, item_data->jname, - stor->storage_[i].nameid); + } + if (count == 0) + clif_displaymessage(s, + "No item found in the storage of this player."_s); + else + { + AString output = STRPRINTF( + "%d item(s) found in %d kind(s) of items."_fmt, + counter, count); clif_displaymessage(s, output); } } - if (count == 0) - clif_displaymessage(s, - "No item found in the storage of this player."_s); - else + OMATCH_CASE_NONE () { - AString output = STRPRINTF( - "%d item(s) found in %d kind(s) of items."_fmt, - counter, count); - clif_displaymessage(s, output); + clif_displaymessage(s, "This player has no storage."_s); + return ATCE::OKAY; } } - else - { - clif_displaymessage(s, "This player has no storage."_s); - return ATCE::OKAY; - } + OMATCH_END (); } else { @@ -4426,12 +4445,13 @@ ATCE atcommand_adjcmdlvl(Session *s, dumb_ptr, Option> it_ = atcommand_info.search(cmd); { - if OPTION_IS_SOME_NOLOOP(it, it_) + OMATCH_BEGIN_SOME (it, it_) { it->level = newlev; clif_displaymessage(s, "@command level changed."_s); return ATCE::OKAY; } + OMATCH_END (); } clif_displaymessage(s, "@command not found."_s); diff --git a/src/map/battle.cpp b/src/map/battle.cpp index 0a6ffa7..96945a4 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -1400,8 +1400,11 @@ struct Damage battle_calc_pc_weapon_attack(dumb_ptr src, if (widx.ok()) { - if OPTION_IS_SOME_NOLOOP(sdidw, sd->inventory_data[widx]) + OMATCH_BEGIN_SOME (sdidw, sd->inventory_data[widx]) + { atkmin = atkmin * (80 + sdidw->wlv * 20) / 100; + } + OMATCH_END (); } if (sd->status.weapon == ItemLook::BOW) { //武器が弓矢の場合 @@ -1921,13 +1924,14 @@ ATK battle_weapon_attack(dumb_ptr src, dumb_ptr target, ItemNameId weapon; if (weapon_index.ok()) { - if OPTION_IS_SOME_NOLOOP(sdidw, sd->inventory_data[weapon_index]) + OMATCH_BEGIN_SOME (sdidw, sd->inventory_data[weapon_index]) { if (bool(sd->status.inventory[weapon_index].equip & EPOS::WEAPON)) { weapon = sdidw->nameid; } } + OMATCH_END (); } MAP_LOG("PC%d %s:%d,%d WPNDMG %s%d %d FOR %d WPN %d"_fmt, diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 61fa8c5..5329eff 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -401,7 +401,7 @@ int clif_send(const Buffer& buf, dumb_ptr bl, SendWho type) p_ = party_search(sd->status.party_id); } } - if OPTION_IS_SOME_NOLOOP(p, p_) + OMATCH_BEGIN_SOME (p, p_) { for (int i = 0; i < MAX_PARTY; i++) { @@ -440,6 +440,7 @@ int clif_send(const Buffer& buf, dumb_ptr bl, SendWho type) } } } + OMATCH_END (); } break; case SendWho::SELF: @@ -1231,19 +1232,18 @@ int clif_selllist(dumb_ptr sd) { if (!sd->status.inventory[i].nameid) continue; - if OPTION_IS_SOME_NOLOOP(sdidi, sd->inventory_data[i]) + OMATCH_BEGIN_SOME (sdidi, sd->inventory_data[i]) { int val = sdidi->value_sell; if (val < 0) - goto continue_outer; + continue; Packet_Repeat<0x00c7> info; info.ioff2 = i.shift(); info.base_price = val; info.actual_price = val; repeat_c7.push_back(info); } - continue_outer: - ; + OMATCH_END (); } send_packet_repeatonly<0x00c7, 4, 10>(s, repeat_c7); @@ -3555,11 +3555,12 @@ RecvResult clif_parse_GetCharNameRequest(Session *s, dumb_ptr { Option p_ = party_search(ssd->status.party_id); - if OPTION_IS_SOME_NOLOOP(p, p_) + OMATCH_BEGIN_SOME (p, p_) { party_name = p->name; send = 1; } + OMATCH_END (); } if (send) @@ -4088,7 +4089,7 @@ RecvResult clif_parse_EquipItem(Session *s, dumb_ptr sd) if (sd->npc_id) return rv; - if OPTION_IS_SOME_NOLOOP(sdidi, sd->inventory_data[index]) + OMATCH_BEGIN_SOME (sdidi, sd->inventory_data[index]) { EPOS epos = fixed.epos_ignored; if (sdidi->type == ItemType::ARROW) @@ -4097,6 +4098,7 @@ RecvResult clif_parse_EquipItem(Session *s, dumb_ptr sd) // Note: the EPOS argument to pc_equipitem is actually ignored pc_equipitem(sd, index, epos); } + OMATCH_END (); return rv; } diff --git a/src/map/itemdb.cpp b/src/map/itemdb.cpp index dbe2dd6..c2fd0e2 100644 --- a/src/map/itemdb.cpp +++ b/src/map/itemdb.cpp @@ -92,8 +92,11 @@ Option> itemdb_exists(ItemNameId nameid) Borrowed itemdb_search(ItemNameId nameid) { Option> id_ = item_db.search(nameid); - if OPTION_IS_SOME_NOLOOP(id, id_) + OMATCH_BEGIN_SOME (id, id_) + { return id; + } + OMATCH_END (); P id = item_db.init(nameid); @@ -172,13 +175,13 @@ bool itemdb_readdb(ZString filename) PRINTF("%s\n"_fmt, res.get_failure()); ast::item::ItemOrComment ioc = TRY_UNWRAP(std::move(res.get_success()), return false); - MATCH (ioc) + MATCH_BEGIN (ioc) { - CASE(const ast::item::Comment&, c) + MATCH_CASE (const ast::item::Comment&, c) { (void)c; } - CASE(const ast::item::Item&, item) + MATCH_CASE (const ast::item::Item&, item) { ln++; @@ -207,6 +210,7 @@ bool itemdb_readdb(ZString filename) *id = std::move(idv); } } + MATCH_END (); } } diff --git a/src/map/magic-expr.cpp b/src/map/magic-expr.cpp index 9cc4e33..f1f137d 100644 --- a/src/map/magic-expr.cpp +++ b/src/map/magic-expr.cpp @@ -58,14 +58,15 @@ void free_area(dumb_ptr area) if (!area) return; - MATCH (*area) + MATCH_BEGIN (*area) { - CASE (const AreaUnion&, a) + MATCH_CASE (const AreaUnion&, a) { free_area(a.a_union[0]); free_area(a.a_union[1]); } } + MATCH_END (); area.delete_(); } @@ -73,109 +74,111 @@ void free_area(dumb_ptr area) static dumb_ptr dup_area(dumb_ptr area) { - MATCH (*area) + MATCH_BEGIN (*area) { - CASE (const location_t&, loc) + MATCH_CASE (const location_t&, loc) { return dumb_ptr::make(loc); } - CASE (const AreaUnion&, a) + MATCH_CASE (const AreaUnion&, a) { AreaUnion u; u.a_union[0] = dup_area(a.a_union[0]); u.a_union[1] = dup_area(a.a_union[1]); return dumb_ptr::make(u); } - CASE (const AreaRect&, rect) + MATCH_CASE (const AreaRect&, rect) { return dumb_ptr::make(rect); } - CASE (const AreaBar&, bar) + MATCH_CASE (const AreaBar&, bar) { return dumb_ptr::make(bar); } } + MATCH_END (); abort(); } void magic_copy_var(val_t *dest, const val_t *src) { - MATCH (*src) + MATCH_BEGIN (*src) { - // mumble mumble not a public API ... - default: + MATCH_DEFAULT () { abort(); } - CASE (const ValUndef&, s) + MATCH_CASE (const ValUndef&, s) { *dest = s; } - CASE (const ValInt&, s) + MATCH_CASE (const ValInt&, s) { *dest = s; } - CASE (const ValDir&, s) + MATCH_CASE (const ValDir&, s) { *dest = s; } - CASE (const ValString&, s) + MATCH_CASE (const ValString&, s) { *dest = ValString{s.v_string}; } - CASE (const ValEntityInt&, s) + MATCH_CASE (const ValEntityInt&, s) { *dest = s; } - CASE (const ValEntityPtr&, s) + MATCH_CASE (const ValEntityPtr&, s) { *dest = s; } - CASE (const ValLocation&, s) + MATCH_CASE (const ValLocation&, s) { *dest = s; } - CASE (const ValArea&, s) + MATCH_CASE (const ValArea&, s) { *dest = ValArea{dup_area(s.v_area)}; } - CASE (const ValSpell&, s) + MATCH_CASE (const ValSpell&, s) { *dest = s; } - CASE (const ValInvocationInt&, s) + MATCH_CASE (const ValInvocationInt&, s) { *dest = s; } - CASE (const ValInvocationPtr&, s) + MATCH_CASE (const ValInvocationPtr&, s) { *dest = s; } - CASE (const ValFail&, s) + MATCH_CASE (const ValFail&, s) { *dest = s; } - CASE (const ValNegative1&, s) + MATCH_CASE (const ValNegative1&, s) { *dest = s; } } + MATCH_END (); } void magic_clear_var(val_t *v) { - MATCH (*v) + MATCH_BEGIN (*v) { - CASE (ValString&, s) + MATCH_CASE (ValString&, s) { (void)s; } - CASE (const ValArea&, a) + MATCH_CASE (const ValArea&, a) { free_area(a.v_area); } } + MATCH_END (); } static @@ -214,63 +217,64 @@ void stringify(val_t *v) }}; AString buf; - MATCH (*v) + MATCH_BEGIN (*v) { - default: + MATCH_DEFAULT () { abort(); } - CASE (const ValUndef&, x) + MATCH_CASE (const ValUndef&, x) { (void)x; buf = "UNDEF"_s; } - CASE (const ValInt&, x) + MATCH_CASE (const ValInt&, x) { buf = STRPRINTF("%i"_fmt, x.v_int); } - CASE (const ValString&, x) + MATCH_CASE (const ValString&, x) { (void)x; return; } - CASE (const ValDir&, x) + MATCH_CASE (const ValDir&, x) { buf = dirs[x.v_dir]; } - CASE (const ValEntityPtr&, x) + MATCH_CASE (const ValEntityPtr&, x) { buf = show_entity(x.v_entity); } - CASE (const ValLocation&, x) + MATCH_CASE (const ValLocation&, x) { buf = STRPRINTF("<\"%s\", %d, %d>"_fmt, x.v_location.m->name_, x.v_location.x, x.v_location.y); } - CASE (const ValArea&, x) + MATCH_CASE (const ValArea&, x) { buf = "%area"_s; free_area(x.v_area); } - CASE (const ValSpell&, x) + MATCH_CASE (const ValSpell&, x) { buf = x.v_spell->name; } - CASE (const ValInvocationInt&, x) + MATCH_CASE (const ValInvocationInt&, x) { dumb_ptr invocation_ = map_id2bl(x.v_iid)->is_spell(); buf = invocation_->spell->name; } - CASE (const ValInvocationPtr&, x) + MATCH_CASE (const ValInvocationPtr&, x) { dumb_ptr invocation_ = x.v_invocation; buf = invocation_->spell->name; } } + MATCH_END (); *v = ValString{buf}; } @@ -312,14 +316,15 @@ void make_location(val_t *v) { if (ValArea *a = v->get_if()) { - MATCH (*a->v_area) + MATCH_BEGIN (*a->v_area) { - CASE (const location_t&, location) + MATCH_CASE (const location_t&, location) { free_area(a->v_area); *v = ValLocation{location}; } } + MATCH_END (); } } @@ -587,14 +592,14 @@ int fun_if_then_else(dumb_ptr, val_t *result, Slice args) Borrowed magic_area_rect(int *x, int *y, int *width, int *height, area_t& area_) { - MATCH (area_) + MATCH_BEGIN (area_) { - CASE (const AreaUnion&, a) + MATCH_CASE (const AreaUnion&, a) { (void)a; abort(); } - CASE (const location_t&, a_loc) + MATCH_CASE (const location_t&, a_loc) { P m = a_loc.m; *x = a_loc.x; @@ -603,7 +608,7 @@ Borrowed magic_area_rect(int *x, int *y, int *width, int *height, *height = 1; return m; } - CASE (const AreaRect&, a_rect) + MATCH_CASE (const AreaRect&, a_rect) { P m = a_rect.loc.m; *x = a_rect.loc.x; @@ -612,7 +617,7 @@ Borrowed magic_area_rect(int *x, int *y, int *width, int *height, *height = a_rect.height; return m; } - CASE (const AreaBar&, a_bar) + MATCH_CASE (const AreaBar&, a_bar) { int tx = a_bar.loc.x; int ty = a_bar.loc.y; @@ -660,19 +665,20 @@ Borrowed magic_area_rect(int *x, int *y, int *width, int *height, return m; } } + MATCH_END (); abort(); } int magic_location_in_area(Borrowed m, int x, int y, dumb_ptr area) { - MATCH (*area) + MATCH_BEGIN (*area) { - CASE (const AreaUnion&, a) + MATCH_CASE (const AreaUnion&, a) { return magic_location_in_area(m, x, y, a.a_union[0]) || magic_location_in_area(m, x, y, a.a_union[1]); } - CASE (const location_t&, a_loc) + MATCH_CASE (const location_t&, a_loc) { (void)a_loc; // TODO this can be simplified @@ -682,7 +688,7 @@ int magic_location_in_area(Borrowed m, int x, int y, dumb_ptr && (x >= ax) && (y >= ay) && (x < ax + awidth) && (y < ay + aheight)); } - CASE (const AreaRect&, a_rect) + MATCH_CASE (const AreaRect&, a_rect) { (void)a_rect; // TODO this is too complicated @@ -692,7 +698,7 @@ int magic_location_in_area(Borrowed m, int x, int y, dumb_ptr && (x >= ax) && (y >= ay) && (x < ax + awidth) && (y < ay + aheight)); } - CASE (const AreaBar&, a_bar) + MATCH_CASE (const AreaBar&, a_bar) { (void)a_bar; // TODO this is wrong @@ -703,6 +709,7 @@ int magic_location_in_area(Borrowed m, int x, int y, dumb_ptr && (x < ax + awidth) && (y < ay + aheight)); } } + MATCH_END (); abort(); } @@ -1084,16 +1091,16 @@ int fun_line_of_sight(dumb_ptr, val_t *result, Slice args) void magic_random_location(location_t *dest, dumb_ptr area) { - MATCH (*area) + MATCH_BEGIN (*area) { - CASE (const AreaUnion&, a) + MATCH_CASE (const AreaUnion&, a) { if (random_::chance({a.a_union[0]->size, area->size})) magic_random_location(dest, a.a_union[0]); else magic_random_location(dest, a.a_union[1]); } - CASE (const location_t&, a_loc) + MATCH_CASE (const location_t&, a_loc) { (void)a_loc; // TODO this can be simplified @@ -1114,7 +1121,7 @@ void magic_random_location(location_t *dest, dumb_ptr area) dest->x = pair.first; dest->y = pair.second; } - CASE (const AreaRect&, a_rect) + MATCH_CASE (const AreaRect&, a_rect) { (void)a_rect; // TODO this can be simplified @@ -1135,7 +1142,7 @@ void magic_random_location(location_t *dest, dumb_ptr area) dest->x = pair.first; dest->y = pair.second; } - CASE (const AreaBar&, a_bar) + MATCH_CASE (const AreaBar&, a_bar) { (void)a_bar; // TODO this is wrong @@ -1157,6 +1164,7 @@ void magic_random_location(location_t *dest, dumb_ptr area) dest->y = pair.second; } } + MATCH_END (); } static @@ -1529,9 +1537,9 @@ int eval_location(dumb_ptr env, location_t *dest, const e_location_t *exp static dumb_ptr eval_area(dumb_ptr env, const e_area_t& expr_) { - MATCH (expr_) + MATCH_BEGIN (expr_) { - CASE (const e_location_t&, a_loc) + MATCH_CASE (const e_location_t&, a_loc) { location_t loc; if (eval_location(env, &loc, &a_loc)) @@ -1543,7 +1551,7 @@ dumb_ptr eval_area(dumb_ptr env, const e_area_t& expr_) return dumb_ptr::make(loc); } } - CASE (const ExprAreaUnion&, a) + MATCH_CASE (const ExprAreaUnion&, a) { AreaUnion u; bool fail = false; @@ -1565,7 +1573,7 @@ dumb_ptr eval_area(dumb_ptr env, const e_area_t& expr_) } return dumb_ptr::make(u); } - CASE (const ExprAreaRect&, a_rect) + MATCH_CASE (const ExprAreaRect&, a_rect) { val_t width, height; magic_eval(env, &width, a_rect.width); @@ -1591,7 +1599,7 @@ dumb_ptr eval_area(dumb_ptr env, const e_area_t& expr_) return nullptr; } } - CASE (const ExprAreaBar&, a_bar) + MATCH_CASE (const ExprAreaBar&, a_bar) { val_t width, depth, dir; magic_eval(env, &width, a_bar.width); @@ -1623,6 +1631,7 @@ dumb_ptr eval_area(dumb_ptr env, const e_area_t& expr_) } } } + MATCH_END (); abort(); } @@ -1741,14 +1750,14 @@ int magic_signature_check(ZString opname, ZString funname, ZString signature, void magic_eval(dumb_ptr env, val_t *dest, dumb_ptr expr) { - MATCH (*expr) + MATCH_BEGIN (*expr) { - CASE (const val_t&, e_val) + MATCH_CASE (const val_t&, e_val) { magic_copy_var(dest, &e_val); } - CASE (const e_location_t&, e_location) + MATCH_CASE (const e_location_t&, e_location) { location_t loc; if (eval_location(env, &loc, &e_location)) @@ -1756,14 +1765,14 @@ void magic_eval(dumb_ptr env, val_t *dest, dumb_ptr expr) else *dest = ValLocation{loc}; } - CASE (const e_area_t&, e_area) + MATCH_CASE (const e_area_t&, e_area) { if (dumb_ptr area = eval_area(env, e_area)) *dest = ValArea{area}; else *dest = ValFail(); } - CASE (const ExprFunApp&, e_funapp) + MATCH_CASE (const ExprFunApp&, e_funapp) { val_t arguments[MAX_ARGS]; int args_nr = e_funapp.args_nr; @@ -1797,12 +1806,12 @@ void magic_eval(dumb_ptr env, val_t *dest, dumb_ptr expr) for (i = 0; i < args_nr; ++i) magic_clear_var(&arguments[i]); } - CASE (const ExprId&, e) + MATCH_CASE (const ExprId&, e) { val_t& v = env->VAR(e.e_id); magic_copy_var(dest, &v); } - CASE (const ExprField&, e_field) + MATCH_CASE (const ExprField&, e_field) { val_t v; int id = e_field.id; @@ -1830,6 +1839,7 @@ void magic_eval(dumb_ptr env, val_t *dest, dumb_ptr expr) } } } + MATCH_END (); } int magic_eval_int(dumb_ptr env, dumb_ptr expr) diff --git a/src/map/magic-interpreter-base.cpp b/src/map/magic-interpreter-base.cpp index 7fde979..e0392e4 100644 --- a/src/map/magic-interpreter-base.cpp +++ b/src/map/magic-interpreter-base.cpp @@ -314,22 +314,22 @@ const effect_set_t *spellguard_check_sub(spellguard_check_t *check, if (guard == nullptr) return nullptr; - MATCH (*guard) + MATCH_BEGIN (*guard) { - CASE (const GuardCondition&, s) + MATCH_CASE (const GuardCondition&, s) { if (!magic_eval_int(env, s.s_condition)) return nullptr; } - CASE (const GuardComponents&, s) + MATCH_CASE (const GuardComponents&, s) { copy_components(&check->components, s.s_components); } - CASE (const GuardCatalysts&, s) + MATCH_CASE (const GuardCatalysts&, s) { copy_components(&check->catalysts, s.s_catalysts); } - CASE (const GuardChoice&, s) + MATCH_CASE (const GuardChoice&, s) { spellguard_check_t altcheck = *check; const effect_set_t *retval; @@ -351,15 +351,15 @@ const effect_set_t *spellguard_check_sub(spellguard_check_t *check, return spellguard_check_sub(check, s.s_alt, caster, env, near_miss); } - CASE (const GuardMana&, s) + MATCH_CASE (const GuardMana&, s) { check->mana += magic_eval_int(env, s.s_mana); } - CASE (const GuardCastTime&, s) + MATCH_CASE (const GuardCastTime&, s) { check->casttime += static_cast(magic_eval_int(env, s.s_casttime)); } - CASE (const effect_set_t&, s_effect) + MATCH_CASE (const effect_set_t&, s_effect) { if (spellguard_can_satisfy(check, caster, env, near_miss)) return &s_effect; @@ -367,6 +367,7 @@ const effect_set_t *spellguard_check_sub(spellguard_check_t *check, return nullptr; } } + MATCH_END (); return spellguard_check_sub(check, guard->next, caster, env, near_miss); } diff --git a/src/map/magic-stmt.cpp b/src/map/magic-stmt.cpp index d5e1a15..39b47fc 100644 --- a/src/map/magic-stmt.cpp +++ b/src/map/magic-stmt.cpp @@ -61,17 +61,18 @@ constexpr Species INVISIBLE_NPC = wrap(127); static void clear_activation_record(cont_activation_record_t *ar) { - MATCH (*ar) + MATCH_BEGIN (*ar) { - CASE (CarForEach&, c_foreach) + MATCH_CASE (CarForEach&, c_foreach) { c_foreach.entities_vp.delete_(); } - CASE (CarProc&, c_proc) + MATCH_CASE (CarProc&, c_proc) { c_proc.old_actualpa.delete_(); } } + MATCH_END (); } static @@ -998,9 +999,9 @@ dumb_ptr return_to_stack(dumb_ptr invocation_) { cont_activation_record_t *ar = &invocation_->stack.back(); - MATCH (*ar) + MATCH_BEGIN (*ar) { - CASE (const CarProc&, c_proc) + MATCH_CASE (const CarProc&, c_proc) { dumb_ptr ret = ar->return_location; for (int i = 0; i < c_proc.args_nr; i++) @@ -1017,7 +1018,7 @@ dumb_ptr return_to_stack(dumb_ptr invocation_) return ret; } - CASE (CarForEach&, c_foreach) + MATCH_CASE (CarForEach&, c_foreach) { BlockId entity_id; val_t *var = &invocation_->env->varu[c_foreach.id]; @@ -1048,7 +1049,7 @@ dumb_ptr return_to_stack(dumb_ptr invocation_) return c_foreach.body; } - CASE (CarFor&, c_for) + MATCH_CASE (CarFor&, c_for) { if (c_for.current > c_for.stop) { @@ -1065,6 +1066,7 @@ dumb_ptr return_to_stack(dumb_ptr invocation_) return c_for.body; } } + MATCH_END (); abort(); } } @@ -1136,14 +1138,14 @@ void find_entities_in_area(area_t& area_, std::vector *entities_vp, FOREACH_FILTER filter) { - MATCH (area_) + MATCH_BEGIN (area_) { - CASE (const AreaUnion&, a) + MATCH_CASE (const AreaUnion&, a) { find_entities_in_area(*a.a_union[0], entities_vp, filter); find_entities_in_area(*a.a_union[1], entities_vp, filter); } - CASE (const location_t&, a_loc) + MATCH_CASE (const location_t&, a_loc) { (void)a_loc; // TODO this can be simplified @@ -1155,7 +1157,7 @@ void find_entities_in_area(area_t& area_, x + width, y + height, BL::NUL /* filter elsewhere */); } - CASE (const AreaRect&, a_rect) + MATCH_CASE (const AreaRect&, a_rect) { (void)a_rect; // TODO this can be simplified @@ -1167,7 +1169,7 @@ void find_entities_in_area(area_t& area_, x + width, y + height, BL::NUL /* filter elsewhere */); } - CASE (const AreaBar&, a_bar) + MATCH_CASE (const AreaBar&, a_bar) { (void)a_bar; // TODO this is wrong @@ -1180,6 +1182,7 @@ void find_entities_in_area(area_t& area_, BL::NUL /* filter elsewhere */); } } + MATCH_END (); } static @@ -1312,13 +1315,13 @@ interval_t spell_run(dumb_ptr invocation_, int allow_delete) dumb_ptr next = e->next; int i; - MATCH (*e) + MATCH_BEGIN (*e) { - CASE (const EffectSkip&, e_) + MATCH_CASE (const EffectSkip&, e_) { (void)e_; } - CASE (const EffectAbort&, e_) + MATCH_CASE (const EffectAbort&, e_) { (void)e_; invocation_->flags |= INVOCATION_FLAG::ABORTED; @@ -1326,34 +1329,34 @@ interval_t spell_run(dumb_ptr invocation_, int allow_delete) clear_stack(invocation_); next = nullptr; } - CASE (const EffectEnd&, e_) + MATCH_CASE (const EffectEnd&, e_) { (void)e_; clear_stack(invocation_); next = nullptr; } - CASE (const EffectAssign&, e_assign) + MATCH_CASE (const EffectAssign&, e_assign) { magic_eval(invocation_->env, &invocation_->env->varu[e_assign.id], e_assign.expr); } - CASE (const EffectForEach&, e_foreach) + MATCH_CASE (const EffectForEach&, e_foreach) { next = run_foreach(invocation_, &e_foreach, next); } - CASE (const EffectFor&, e_for) + MATCH_CASE (const EffectFor&, e_for) { next = run_for (invocation_, &e_for, next); } - CASE (const EffectIf&, e_if) + MATCH_CASE (const EffectIf&, e_if) { if (magic_eval_int(invocation_->env, e_if.cond)) next = e_if.true_branch; else next = e_if.false_branch; } - CASE (const EffectSleep&, e_) + MATCH_CASE (const EffectSleep&, e_) { interval_t sleeptime = static_cast( magic_eval_int(invocation_->env, e_.e_sleep)); @@ -1361,7 +1364,7 @@ interval_t spell_run(dumb_ptr invocation_, int allow_delete) if (sleeptime > interval_t::zero()) return sleeptime; } - CASE (const EffectScript&, e_) + MATCH_CASE (const EffectScript&, e_) { dumb_ptr caster = map_id_is_player(invocation_->caster); if (caster) @@ -1408,12 +1411,12 @@ interval_t spell_run(dumb_ptr invocation_, int allow_delete) } REFRESH_INVOCATION; // Script may have killed the caster } - CASE (const EffectBreak&, e_) + MATCH_CASE (const EffectBreak&, e_) { (void)e_; next = return_to_stack(invocation_); } - CASE (const EffectOp&, e_op) + MATCH_CASE (const EffectOp&, e_op) { op_t *op = e_op.opp; val_t args[MAX_ARGS]; @@ -1432,11 +1435,12 @@ interval_t spell_run(dumb_ptr invocation_, int allow_delete) REFRESH_INVOCATION; // Effect may have killed the caster } - CASE (const EffectCall&, e_call) + MATCH_CASE (const EffectCall&, e_call) { next = run_call(invocation_, &e_call, next); } } + MATCH_END (); break_match: if (!next) diff --git a/src/map/magic-v2.cpp b/src/map/magic-v2.cpp index 204c774..7dfae08 100644 --- a/src/map/magic-v2.cpp +++ b/src/map/magic-v2.cpp @@ -139,14 +139,15 @@ namespace magic_v2 /* For FOR and FOREACH, we use special stack handlers and thus don't have to set * the continuation. It's only IF that we need to handle in this fashion. */ - MATCH (*src) + MATCH_BEGIN (*src) { - CASE (EffectIf&, e_if) + MATCH_CASE (EffectIf&, e_if) { set_effect_continuation(e_if.true_branch, continuation); set_effect_continuation(e_if.false_branch, continuation); } } + MATCH_END (); if (src->next) set_effect_continuation(src->next, continuation); @@ -177,13 +178,14 @@ namespace magic_v2 } /* If the premise is a disjunction, b is the continuation of _all_ branches */ - MATCH (*a) + MATCH_BEGIN (*a) { - CASE(const GuardChoice&, s) + MATCH_CASE (const GuardChoice&, s) { spellguard_implication(s.s_alt, b); } } + MATCH_END (); if (a->next) spellguard_implication(a->next, b); diff --git a/src/map/map.cpp b/src/map/map.cpp index 784319f..e2c38a7 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -1247,36 +1247,40 @@ void map_setcell(Borrowed m, int x, int y, MapCell t) int map_setipport(MapName name, IP4Address ip, int port) { Option> md_ = maps_db.get(name); - if OPTION_IS_SOME_NOLOOP(md, md_) + OMATCH_BEGIN (md_) { - if (md->gat) + OMATCH_CASE_SOME (md) { - // local -> check data - if (ip != clif_getip() || port != clif_getport()) + if (md->gat) { - PRINTF("from char server : %s -> %s:%d\n"_fmt, - name, ip, port); - return 1; + // local -> check data + if (ip != clif_getip() || port != clif_getport()) + { + PRINTF("from char server : %s -> %s:%d\n"_fmt, + name, ip, port); + return 1; + } + } + else + { + // update + P mdos = md.downcast_to(); + mdos->ip = ip; + mdos->port = port; } } - else + OMATCH_CASE_NONE () { - // update - P mdos = md.downcast_to(); + // not exist -> add new data + auto mdos = make_unique(); + mdos->name_ = name; + mdos->gat = nullptr; mdos->ip = ip; mdos->port = port; + maps_db.put(mdos->name_, std::move(mdos)); } } - else - { - // not exist -> add new data - auto mdos = make_unique(); - mdos->name_ = name; - mdos->gat = nullptr; - mdos->ip = ip; - mdos->port = port; - maps_db.put(mdos->name_, std::move(mdos)); - } + OMATCH_END (); return 0; } diff --git a/src/map/mob.cpp b/src/map/mob.cpp index 63db442..b01a4ff 100644 --- a/src/map/mob.cpp +++ b/src/map/mob.cpp @@ -2591,7 +2591,7 @@ int mob_damage(dumb_ptr src, dumb_ptr md, int damage, if (it == ptv.end()) { Option p_ = party_search(pid); - if OPTION_IS_SOME_NOLOOP(p, p_) + OMATCH_BEGIN_SOME (p, p_) { if (p->exp != 0) { @@ -2600,6 +2600,7 @@ int mob_damage(dumb_ptr src, dumb_ptr md, int damage, flag = 0; } } + OMATCH_END (); } else { diff --git a/src/map/npc-parse.cpp b/src/map/npc-parse.cpp index 8b47502..3df54c7 100644 --- a/src/map/npc-parse.cpp +++ b/src/map/npc-parse.cpp @@ -756,17 +756,17 @@ bool npc_load_script_map(ast::script::ScriptBody& body, ast::npc::ScriptMap& scr static bool npc_load_script_any(ast::npc::Script *script) { - MATCH (*script) + MATCH_BEGIN (*script) { - CASE (ast::npc::ScriptFunction&, script_function) + MATCH_CASE (ast::npc::ScriptFunction&, script_function) { return npc_load_script_function(script->body, script_function); } - CASE (ast::npc::ScriptNone&, script_none) + MATCH_CASE (ast::npc::ScriptNone&, script_none) { return npc_load_script_none(script->body, script_none); } - CASE (ast::npc::ScriptMapNone&, script_map_none) + MATCH_CASE (ast::npc::ScriptMapNone&, script_map_none) { auto& mapname = script_map_none.m; Option> m = map_mapname2mapid(mapname.data); @@ -777,7 +777,7 @@ bool npc_load_script_any(ast::npc::Script *script) } return npc_load_script_map_none(script->body, script_map_none); } - CASE (ast::npc::ScriptMap&, script_map) + MATCH_CASE (ast::npc::ScriptMap&, script_map) { auto& mapname = script_map.m; Option> m = map_mapname2mapid(mapname.data); @@ -789,6 +789,7 @@ bool npc_load_script_any(ast::npc::Script *script) return npc_load_script_map(script->body, script_map); } } + MATCH_END (); abort(); } @@ -827,14 +828,14 @@ bool load_one_npc(io::LineCharReader& fp, bool& done) PRINTF("%s\n"_fmt, res.get_failure()); ast::npc::TopLevel tl = TRY_UNWRAP(std::move(res.get_success()), return false); - MATCH (tl) + MATCH_BEGIN (tl) { - CASE (ast::npc::Comment&, c) + MATCH_CASE (ast::npc::Comment&, c) { (void)c; return true; } - CASE (ast::npc::Warp&, warp) + MATCH_CASE (ast::npc::Warp&, warp) { auto& mapname = warp.m; Option> m = map_mapname2mapid(mapname.data); @@ -845,7 +846,7 @@ bool load_one_npc(io::LineCharReader& fp, bool& done) } return npc_load_warp(warp); } - CASE (ast::npc::Shop&, shop) + MATCH_CASE (ast::npc::Shop&, shop) { auto& mapname = shop.m; Option> m = map_mapname2mapid(mapname.data); @@ -856,7 +857,7 @@ bool load_one_npc(io::LineCharReader& fp, bool& done) } return npc_load_shop(shop); } - CASE (ast::npc::Monster&, monster) + MATCH_CASE (ast::npc::Monster&, monster) { auto& mapname = monster.m; Option> m = map_mapname2mapid(mapname.data); @@ -867,7 +868,7 @@ bool load_one_npc(io::LineCharReader& fp, bool& done) } return npc_load_monster(monster); } - CASE (ast::npc::MapFlag&, mapflag) + MATCH_CASE (ast::npc::MapFlag&, mapflag) { auto& mapname = mapflag.m; Option> m = map_mapname2mapid(mapname.data); @@ -878,11 +879,12 @@ bool load_one_npc(io::LineCharReader& fp, bool& done) } return npc_load_mapflag(mapflag); } - CASE (ast::npc::Script&, script) + MATCH_CASE (ast::npc::Script&, script) { return npc_load_script_any(&script); } } + MATCH_END (); abort(); } diff --git a/src/map/party.cpp b/src/map/party.cpp index 0a9d2c5..b05f4f1 100644 --- a/src/map/party.cpp +++ b/src/map/party.cpp @@ -213,11 +213,12 @@ static PartyPair handle_info(const PartyPair sp) { Option p_ = party_search(sp.party_id); - if OPTION_IS_SOME_NOLOOP(p, p_) + OMATCH_BEGIN_SOME (p, p_) { *p.party_most = *sp.party_most; return p; } + OMATCH_END (); { PartyPair p{sp.party_id, party_db.init(sp.party_id)}; @@ -459,7 +460,7 @@ int party_member_leaved(PartyId party_id, AccountId account_id, CharName name) { dumb_ptr sd = map_id2sd(account_to_block(account_id)); Option p_ = party_search(party_id); - if OPTION_IS_SOME_NOLOOP(p, p_) + OMATCH_BEGIN_SOME (p, p_) { int i; for (i = 0; i < MAX_PARTY; i++) @@ -470,6 +471,7 @@ int party_member_leaved(PartyId party_id, AccountId account_id, CharName name) p->member[i].sd = nullptr; } } + OMATCH_END (); if (sd != nullptr && sd->status.party_id == party_id) { sd->status.party_id = PartyId(); diff --git a/src/map/pc.cpp b/src/map/pc.cpp index a38c05f..33d77fd 100644 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -555,14 +555,22 @@ int pc_setequipindex(dumb_ptr sd) sd->equip_index_maybe[j] = i; if (bool(sd->status.inventory[i].equip & EPOS::WEAPON)) { - if OPTION_IS_SOME_NOLOOP(sdidi, sd->inventory_data[i]) - sd->weapontype1 = sdidi->look; - else - sd->weapontype1 = ItemLook::NONE; + OMATCH_BEGIN (sd->inventory_data[i]) + { + OMATCH_CASE_SOME (sdidi) + { + sd->weapontype1 = sdidi->look; + } + OMATCH_CASE_NONE () + { + sd->weapontype1 = ItemLook::NONE; + } + } + OMATCH_END (); } if (bool(sd->status.inventory[i].equip & EPOS::SHIELD)) { - if OPTION_IS_SOME_NOLOOP(sdidi, sd->inventory_data[i]) + OMATCH_BEGIN_SOME (sdidi, sd->inventory_data[i]) { if (sdidi->type == ItemType::WEAPON) { @@ -570,6 +578,7 @@ int pc_setequipindex(dumb_ptr sd) assert(0 && "unreachable - offhand weapons are not supported"); } } + OMATCH_END (); } } } @@ -998,13 +1007,14 @@ int pc_calcstatus(dumb_ptr sd, int first) || sd->equip_index_maybe[EQUIP::LEGS] == index)) continue; - if OPTION_IS_SOME_NOLOOP(sdidi, sd->inventory_data[index]) + OMATCH_BEGIN_SOME (sdidi, sd->inventory_data[index]) { sd->spellpower_bonus_target += sdidi->magic_bonus; // used to apply cards } + OMATCH_END (); } #ifdef USE_ASTRAL_SOUL_SKILL @@ -1033,7 +1043,7 @@ int pc_calcstatus(dumb_ptr sd, int first) && (sd->equip_index_maybe[EQUIP::TORSO] == index || sd->equip_index_maybe[EQUIP::LEGS] == index)) continue; - if OPTION_IS_SOME_NOLOOP(sdidi, sd->inventory_data[index]) + OMATCH_BEGIN_SOME (sdidi, sd->inventory_data[index]) { sd->def += sdidi->def; if (sdidi->type == ItemType::WEAPON) @@ -1072,6 +1082,7 @@ int pc_calcstatus(dumb_ptr sd, int first) arg); } } + OMATCH_END (); } if (battle_is_unarmed(sd)) @@ -1084,7 +1095,7 @@ int pc_calcstatus(dumb_ptr sd, int first) if (aidx.ok()) { IOff0 index = aidx; - if OPTION_IS_SOME_NOLOOP(sdidi, sd->inventory_data[index]) + OMATCH_BEGIN_SOME (sdidi, sd->inventory_data[index]) { //まだ属性が入っていない argrec_t arg[2] = { @@ -1098,6 +1109,7 @@ int pc_calcstatus(dumb_ptr sd, int first) sd->state.lr_flag_is_arrow_2 = 0; sd->arrow_atk += sdidi->atk; } + OMATCH_END (); } sd->def += (refinedef + 50) / 100; @@ -2111,7 +2123,7 @@ int pc_useitem(dumb_ptr sd, IOff0 n) if (!n.ok()) return 0; - if OPTION_IS_SOME_NOLOOP(sdidn, sd->inventory_data[n]) + OMATCH_BEGIN_SOME (sdidn, sd->inventory_data[n]) { amount = sd->status.inventory[n].amount; if (!sd->status.inventory[n].nameid @@ -2128,6 +2140,7 @@ int pc_useitem(dumb_ptr sd, IOff0 n) run_script(ScriptPointer(script, 0), sd->bl_id, BlockId()); } + OMATCH_END (); return 0; } @@ -3172,8 +3185,11 @@ int pc_damage(dumb_ptr src, dumb_ptr sd, if (sd->status.party_id) { // on-the-fly party hp updates [Valaris] Option p_ = party_search(sd->status.party_id); - if OPTION_IS_SOME_NOLOOP(p, p_) + OMATCH_BEGIN_SOME (p, p_) + { clif_party_hp(p, sd); + } + OMATCH_END (); } // end addition [Valaris] return 0; @@ -3540,8 +3556,11 @@ int pc_heal(dumb_ptr sd, int hp, int sp) if (sd->status.party_id) { // on-the-fly party hp updates [Valaris] Option p_ = party_search(sd->status.party_id); - if OPTION_IS_SOME_NOLOOP(p, p_) + OMATCH_BEGIN_SOME (p, p_) + { clif_party_hp(p, sd); + } + OMATCH_END (); } // end addition [Valaris] return hp + sp; @@ -4191,7 +4210,7 @@ int pc_equipitem(dumb_ptr sd, IOff0 n, EPOS) ItemNameId view_i; ItemLook view_l = ItemLook::NONE; // TODO: This is ugly. - if OPTION_IS_SOME_NOLOOP(sdidn, sd->inventory_data[n]) + OMATCH_BEGIN_SOME (sdidn, sd->inventory_data[n]) { bool look_not_weapon = sdidn->look == ItemLook::NONE; bool equip_is_weapon = bool(sd->status.inventory[n].equip & EPOS::WEAPON); @@ -4202,6 +4221,7 @@ int pc_equipitem(dumb_ptr sd, IOff0 n, EPOS) else view_l = sdidn->look; } + OMATCH_END (); if (bool(sd->status.inventory[n].equip & EPOS::WEAPON)) { @@ -4211,23 +4231,27 @@ int pc_equipitem(dumb_ptr sd, IOff0 n, EPOS) } if (bool(sd->status.inventory[n].equip & EPOS::SHIELD)) { - if OPTION_IS_SOME_NOLOOP(sdidn, sd->inventory_data[n]) + OMATCH_BEGIN (sd->inventory_data[n]) { - if (sdidn->type == ItemType::WEAPON) + OMATCH_CASE_SOME (sdidn) { - sd->status.shield = ItemNameId(); - if (sd->status.inventory[n].equip == EPOS::SHIELD) - assert(0 && "unreachable - offhand weapons are not supported"); + if (sdidn->type == ItemType::WEAPON) + { + sd->status.shield = ItemNameId(); + if (sd->status.inventory[n].equip == EPOS::SHIELD) + assert(0 && "unreachable - offhand weapons are not supported"); + } + else if (sdidn->type == ItemType::ARMOR) + { + sd->status.shield = view_i; + } } - else if (sdidn->type == ItemType::ARMOR) + OMATCH_CASE_NONE () { - sd->status.shield = view_i; + sd->status.shield = ItemNameId(); } } - else - { - sd->status.shield = ItemNameId(); - } + OMATCH_END (); pc_calcweapontype(sd); clif_changelook(sd, LOOK::SHIELD, unwrap(sd->status.shield)); } diff --git a/src/map/script-call.cpp b/src/map/script-call.cpp index abab24d..5ac45e5 100644 --- a/src/map/script-call.cpp +++ b/src/map/script-call.cpp @@ -74,9 +74,9 @@ dumb_ptr script_rid2sd(ScriptState *st) */ void get_val(dumb_ptr sd, struct script_data *data) { - MATCH (*data) + MATCH_BEGIN (*data) { - CASE (const ScriptDataParam&, u) + MATCH_CASE (const ScriptDataParam&, u) { if (sd == nullptr) PRINTF("get_val error param SP::%d\n"_fmt, u.reg.sp()); @@ -85,7 +85,7 @@ void get_val(dumb_ptr sd, struct script_data *data) numi = pc_readparam(sd, u.reg.sp()); *data = ScriptDataInt{numi}; } - CASE (const ScriptDataVariable&, u) + MATCH_CASE (const ScriptDataVariable&, u) { ZString name_ = variable_names.outtern(u.reg.base()); VarName name = stringish(name_); @@ -108,8 +108,11 @@ void get_val(dumb_ptr sd, struct script_data *data) else if (prefix == '$') { Option> s_ = mapregstr_db.search(u.reg); - if OPTION_IS_SOME_NOLOOP(s, s_) + OMATCH_BEGIN_SOME (s, s_) + { str = *s; + } + OMATCH_END (); } else { @@ -152,6 +155,7 @@ void get_val(dumb_ptr sd, struct script_data *data) } } } + MATCH_END (); } void get_val(ScriptState *st, struct script_data *data) @@ -268,24 +272,27 @@ int conv_num(ScriptState *st, struct script_data *data) int rv = 0; get_val(st, data); assert (!data->is()); - MATCH (*data) + MATCH_BEGIN (*data) { - default: + MATCH_DEFAULT () + { abort(); - CASE (const ScriptDataStr&, u) + } + MATCH_CASE (const ScriptDataStr&, u) { RString p = u.str; rv = atoi(p.c_str()); } - CASE (const ScriptDataInt&, u) + MATCH_CASE (const ScriptDataInt&, u) { return u.numi; } - CASE (const ScriptDataPos&, u) + MATCH_CASE (const ScriptDataPos&, u) { return u.numi; } } + MATCH_END () *data = ScriptDataInt{rv}; return rv; } @@ -596,45 +603,46 @@ void run_func(ScriptState *st) PRINTF("stack dump :"_fmt); for (script_data& d : st->stack->stack_datav) { - MATCH (d) + MATCH_BEGIN (d) { - CASE (const ScriptDataInt&, u) + MATCH_CASE (const ScriptDataInt&, u) { PRINTF(" int(%d)"_fmt, u.numi); } - CASE (const ScriptDataRetInfo&, u) + MATCH_CASE (const ScriptDataRetInfo&, u) { PRINTF(" retinfo(%p)"_fmt, static_cast(&*u.script)); } - CASE (const ScriptDataParam&, u) + MATCH_CASE (const ScriptDataParam&, u) { PRINTF(" param(%d)"_fmt, u.reg.sp()); } - CASE (const ScriptDataVariable&, u) + MATCH_CASE (const ScriptDataVariable&, u) { PRINTF(" name(%s)[%d]"_fmt, variable_names.outtern(u.reg.base()), u.reg.index()); } - CASE (const ScriptDataArg&, u) + MATCH_CASE (const ScriptDataArg&, u) { (void)u; PRINTF(" arg"_fmt); } - CASE (const ScriptDataPos&, u) + MATCH_CASE (const ScriptDataPos&, u) { (void)u; PRINTF(" pos(%d)"_fmt, u.numi); } - CASE (const ScriptDataStr&, u) + MATCH_CASE (const ScriptDataStr&, u) { (void)u; PRINTF(" str(%s)"_fmt, u.str); } - CASE (const ScriptDataFuncRef&, u) + MATCH_CASE (const ScriptDataFuncRef&, u) { (void)u; PRINTF(" func(%s)"_fmt, builtin_functions[u.numi].name); } } + MATCH_END (); } PRINTF("\n"_fmt); } diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index f9334bc..cc28cd2 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -122,29 +122,33 @@ void builtin_callfunc(ScriptState *st) RString str = conv_str(st, &AARG(0)); Option> scr_ = userfunc_db.get(str); - if OPTION_IS_SOME_NOLOOP(scr, scr_) + OMATCH_BEGIN (scr_) { - int j = 0; - assert (st->start + 3 == st->end); + OMATCH_CASE_SOME (scr) + { + int j = 0; + assert (st->start + 3 == st->end); #if 0 - for (int i = st->start + 3; i < st->end; i++, j++) - push_copy(st->stack, i); + for (int i = st->start + 3; i < st->end; i++, j++) + push_copy(st->stack, i); #endif - push_int(st->stack, j); // 引数の数をプッシュ - push_int(st->stack, st->defsp); // 現在の基準スタックポインタをプッシュ - push_int(st->stack, st->scriptp.pos); // 現在のスクリプト位置をプッシュ - push_script(st->stack, TRY_UNWRAP(st->scriptp.code, abort())); // 現在のスクリプトをプッシュ + push_int(st->stack, j); // 引数の数をプッシュ + push_int(st->stack, st->defsp); // 現在の基準スタックポインタをプッシュ + push_int(st->stack, st->scriptp.pos); // 現在のスクリプト位置をプッシュ + push_script(st->stack, TRY_UNWRAP(st->scriptp.code, abort())); // 現在のスクリプトをプッシュ - st->scriptp = ScriptPointer(scr, 0); - st->defsp = st->start + 4 + j; - st->state = ScriptEndState::GOTO; - } - else - { - PRINTF("script:callfunc: function not found! [%s]\n"_fmt, str); - st->state = ScriptEndState::END; + st->scriptp = ScriptPointer(scr, 0); + st->defsp = st->start + 4 + j; + st->state = ScriptEndState::GOTO; + } + OMATCH_CASE_NONE () + { + PRINTF("script:callfunc: function not found! [%s]\n"_fmt, str); + st->state = ScriptEndState::END; + } } + OMATCH_END (); } /*========================================== @@ -618,24 +622,23 @@ int getarraysize(ScriptState *st, SIR reg) for (; i < 256; i++) { struct script_data vd = get_val2(st, reg.iplus(i)); - MATCH (vd) + MATCH_BEGIN (vd) { - CASE (const ScriptDataStr&, u) + MATCH_CASE (const ScriptDataStr&, u) { if (u.str[0]) c = i; - goto continue_outer; + continue; } - CASE (const ScriptDataInt&, u) + MATCH_CASE (const ScriptDataInt&, u) { if (u.numi) c = i; - goto continue_outer; + continue; } } + MATCH_END (); abort(); - continue_outer: - ; } return c + 1; } @@ -720,8 +723,11 @@ void builtin_countitem(ScriptState *st) { ZString name = ZString(conv_str(st, data)); Option> item_data_ = itemdb_searchname(name); - if OPTION_IS_SOME_NOLOOP(item_data, item_data_) + OMATCH_BEGIN_SOME (item_data, item_data_) + { nameid = item_data->nameid; + } + OMATCH_END (); } else nameid = wrap(conv_num(st, data)); @@ -763,8 +769,11 @@ void builtin_checkweight(ScriptState *st) { ZString name = ZString(conv_str(st, data)); Option> item_data_ = itemdb_searchname(name); - if OPTION_IS_SOME_NOLOOP(item_data, item_data_) + OMATCH_BEGIN_SOME (item_data, item_data_) + { nameid = item_data->nameid; + } + OMATCH_END (); } else nameid = wrap(conv_num(st, data)); @@ -808,8 +817,11 @@ void builtin_getitem(ScriptState *st) { ZString name = ZString(conv_str(st, data)); Option> item_data_ = itemdb_searchname(name); - if OPTION_IS_SOME_NOLOOP(item_data, item_data_) + OMATCH_BEGIN_SOME (item_data, item_data_) + { nameid = item_data->nameid; + } + OMATCH_END (); } else nameid = wrap(conv_num(st, data)); @@ -861,8 +873,11 @@ void builtin_makeitem(ScriptState *st) { ZString name = ZString(conv_str(st, data)); Option> item_data_ = itemdb_searchname(name); - if OPTION_IS_SOME_NOLOOP(item_data, item_data_) + OMATCH_BEGIN_SOME (item_data, item_data_) + { nameid = item_data->nameid; + } + OMATCH_END (); } else nameid = wrap(conv_num(st, data)); @@ -905,8 +920,11 @@ void builtin_delitem(ScriptState *st) { ZString name = ZString(conv_str(st, data)); Option> item_data_ = itemdb_searchname(name); - if OPTION_IS_SOME_NOLOOP(item_data, item_data_) + OMATCH_BEGIN_SOME (item_data, item_data_) + { nameid = item_data->nameid; + } + OMATCH_END (); } else nameid = wrap(conv_num(st, data)); @@ -1080,10 +1098,18 @@ void builtin_getequipid(ScriptState *st) if (i.ok()) { Option> item_ = sd->inventory_data[i]; - if OPTION_IS_SOME_NOLOOP(item, item_) - push_int(st->stack, unwrap(item->nameid)); - else - push_int(st->stack, 0); + OMATCH_BEGIN (item_) + { + OMATCH_CASE_SOME (item) + { + push_int(st->stack, unwrap(item->nameid)); + } + OMATCH_CASE_NONE () + { + push_int(st->stack, 0); + } + } + OMATCH_END (); } else { @@ -1109,10 +1135,18 @@ void builtin_getequipname(ScriptState *st) if (i.ok()) { Option> item_ = sd->inventory_data[i]; - if OPTION_IS_SOME_NOLOOP(item, item_) - buf = STRPRINTF("%s-[%s]"_fmt, pos_str[num - 1], item->jname); - else - buf = STRPRINTF("%s-[%s]"_fmt, pos_str[num - 1], pos_str[10]); + OMATCH_BEGIN (item_) + { + OMATCH_CASE_SOME (item) + { + buf = STRPRINTF("%s-[%s]"_fmt, pos_str[num - 1], item->jname); + } + OMATCH_CASE_NONE () + { + buf = STRPRINTF("%s-[%s]"_fmt, pos_str[num - 1], pos_str[10]); + } + } + OMATCH_END (); } else { @@ -1832,8 +1866,11 @@ void builtin_getareadropitem(ScriptState *st) { ZString name = ZString(conv_str(st, data)); Option> item_data_ = itemdb_searchname(name); - if OPTION_IS_SOME_NOLOOP(item_data, item_data_) + OMATCH_BEGIN_SOME (item_data, item_data_) + { item = item_data->nameid; + } + OMATCH_END (); } else item = wrap(conv_num(st, data)); @@ -2013,10 +2050,11 @@ void builtin_setmapflag(ScriptState *st) int i = conv_num(st, &AARG(1)); MapFlag mf = map_flag_from_int(i); Option> m_ = map_mapname2mapid(str); - if OPTION_IS_SOME_NOLOOP(m, m_) + OMATCH_BEGIN_SOME (m, m_) { m->flag.set(mf, 1); } + OMATCH_END (); } static @@ -2026,10 +2064,11 @@ void builtin_removemapflag(ScriptState *st) int i = conv_num(st, &AARG(1)); MapFlag mf = map_flag_from_int(i); Option> m_ = map_mapname2mapid(str); - if OPTION_IS_SOME_NOLOOP(m, m_) + OMATCH_BEGIN_SOME (m, m_) { m->flag.set(mf, 0); } + OMATCH_END (); } static @@ -2041,10 +2080,11 @@ void builtin_getmapflag(ScriptState *st) int i = conv_num(st, &AARG(1)); MapFlag mf = map_flag_from_int(i); Option> m_ = map_mapname2mapid(str); - if OPTION_IS_SOME_NOLOOP(m, m_) + OMATCH_BEGIN_SOME (m, m_) { r = m->flag.get(mf); } + OMATCH_END (); push_int(st->stack, r); } diff --git a/src/map/script-parse.cpp b/src/map/script-parse.cpp index 47e0def..6b41225 100644 --- a/src/map/script-parse.cpp +++ b/src/map/script-parse.cpp @@ -134,8 +134,11 @@ Option> search_strp(XString p) Borrowed add_strp(XString p) { Option> rv_ = search_strp(p); - if OPTION_IS_SOME_NOLOOP(rv, rv_) + OMATCH_BEGIN_SOME (rv, rv_) + { return rv; + } + OMATCH_END (); RString p2 = p; P datum = str_datam.init(p2); diff --git a/src/map/trade.cpp b/src/map/trade.cpp index 5ec63c9..bc6e98f 100644 --- a/src/map/trade.cpp +++ b/src/map/trade.cpp @@ -174,7 +174,7 @@ void trade_tradeadditem(dumb_ptr sd, IOff2 index, int amount) sd->status.inventory[index.unshift()].nameid) continue; - if OPTION_IS_SOME_INLOOP(id, target_sd->inventory_data[i]) + OMATCH_BEGIN_SOME (id, target_sd->inventory_data[i]) { if (id->type != ItemType::WEAPON && id->type != ItemType::ARMOR @@ -182,9 +182,12 @@ void trade_tradeadditem(dumb_ptr sd, IOff2 index, int amount) && id->type != ItemType::_8) { free_++; - break; + goto break_outer1; } } + OMATCH_END (); + break_outer1: + break; } if (target_sd->weight + trade_weight > @@ -231,7 +234,7 @@ void trade_tradeadditem(dumb_ptr sd, IOff2 index, int amount) sd->status. inventory[sd->deal_item_index[trade_i].unshift()].nameid) continue; - if OPTION_IS_SOME_INLOOP(id, target_sd->inventory_data[i]) + OMATCH_BEGIN_SOME (id, target_sd->inventory_data[i]) { if (id->type != ItemType::WEAPON && id->type != ItemType::ARMOR @@ -239,9 +242,12 @@ void trade_tradeadditem(dumb_ptr sd, IOff2 index, int amount) && id->type != ItemType::_8) { free_++; - break; + goto break_outer2; } } + OMATCH_END (); + break_outer2: + break; } } // used a slot, but might be cancelled out by stackable checks above diff --git a/src/sexpr/fwd.hpp b/src/sexpr/fwd.hpp index 41e21a1..b86d9fb 100644 --- a/src/sexpr/fwd.hpp +++ b/src/sexpr/fwd.hpp @@ -21,7 +21,6 @@ #include "../sanity.hpp" #include "../strings/fwd.hpp" // rank 1 -#include "../compat/fwd.hpp" // rank 2 #include "../io/fwd.hpp" // rank 4 // sexpr/fwd.hpp is rank 5 diff --git a/src/sexpr/variant.hpp b/src/sexpr/variant.hpp index 287a5f0..0eccc5a 100644 --- a/src/sexpr/variant.hpp +++ b/src/sexpr/variant.hpp @@ -23,8 +23,6 @@ #include #include -#include "../compat/attr.hpp" - #include "union.hpp" #include "void.hpp" @@ -35,14 +33,42 @@ namespace tmwa { namespace sexpr { -#define MATCH(expr) \ - WITH_VAR_NOLOOP(auto&&, _match_var, expr) \ - switch (tmwa::sexpr::VariantFriend::get_state(_match_var)) -#define TYPED_CASE(ty, var, look) \ - break; \ - case tmwa::sexpr::VariantFriend::get_state_for(): \ - WITH_VAR_INLOOP(ty, var, tmwa::sexpr::VariantFriend::unchecked_get(_match_var)) -#define CASE(ty, var) TYPED_CASE(ty, var, std::remove_const::type>::type) +#define MATCH_BEGIN(expr) \ + { \ + auto&& _match_var = (expr); \ + switch (tmwa::sexpr::VariantFriend::get_state(_match_var)) \ + { \ + { \ + { \ + /* }}}} */ +#define MATCH_END() \ + /* {{{{ */ \ + } \ + } \ + } \ + (void) _match_var; \ + } + +#define MATCH_CASE(ty, v) \ + /* {{{{ */ \ + } \ + break; \ + } \ + { \ + using _match_case_type = std::remove_const::type>::type; \ + case tmwa::sexpr::VariantFriend::get_state_for<_match_case_type, decltype(_match_var)>(): \ + { \ + ty v = tmwa::sexpr::VariantFriend::unchecked_get<_match_case_type>(_match_var); + /* }}}} */ +#define MATCH_DEFAULT() \ + /* {{{{ */ \ + } \ + break; \ + } \ + { \ + default: \ + { \ + /* }}}} */ template class Variant diff --git a/src/sexpr/variant_test.cpp b/src/sexpr/variant_test.cpp index bc378aa..c671264 100644 --- a/src/sexpr/variant_test.cpp +++ b/src/sexpr/variant_test.cpp @@ -77,42 +77,46 @@ TEST(variant, match) : sexpr::Variant(Foo(1)) {} }; + Sub v1; - MATCH (v1) + MATCH_BEGIN (v1) { - // This is not a public API, it's just for testing. - default: - FAIL(); - - CASE(Foo, f) + MATCH_DEFAULT () + { + FAIL(); + } + MATCH_CASE (Foo, f) { (void)f; SUCCEED(); } - CASE(Bar, b) + MATCH_CASE (Bar, b) { (void)b; FAIL(); } } + MATCH_END (); + v1.emplace(2); - MATCH (v1) + MATCH_BEGIN (v1) { - // This is not a public API, it's just for testing. - default: - FAIL(); - - CASE(Foo, f) + MATCH_DEFAULT () + { + FAIL(); + } + MATCH_CASE (Foo, f) { (void)f; FAIL(); } - CASE(Bar, b) + MATCH_CASE (Bar, b) { (void)b; SUCCEED(); } } + MATCH_END (); } TEST(variant, copymove1) -- cgit v1.2.3-70-g09d2