summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormekolat <mekolat@users.noreply.github.com>2015-06-28 17:05:36 -0400
committermekolat <mekolat@users.noreply.github.com>2015-09-26 21:22:02 +0000
commitf085c1739a9fafd745492e9c424dd20b1615b7cf (patch)
tree98f091bac5dbc76fd4dcdfd1ee3fe89ff572b144
parent27a6ccd14809eb1c497adc398ecbecd0c0bd3c98 (diff)
downloadtmwa-f085c1739a9fafd745492e9c424dd20b1615b7cf.tar.gz
tmwa-f085c1739a9fafd745492e9c424dd20b1615b7cf.tar.bz2
tmwa-f085c1739a9fafd745492e9c424dd20b1615b7cf.tar.xz
tmwa-f085c1739a9fafd745492e9c424dd20b1615b7cf.zip
add elif and else builtins
-rw-r--r--src/map/script-call-internal.hpp1
-rw-r--r--src/map/script-fun.cpp60
-rw-r--r--src/map/script-parse.cpp3
3 files changed, 63 insertions, 1 deletions
diff --git a/src/map/script-call-internal.hpp b/src/map/script-call-internal.hpp
index b9b3a9f..a887eb8 100644
--- a/src/map/script-call-internal.hpp
+++ b/src/map/script-call-internal.hpp
@@ -54,6 +54,7 @@ public:
BlockId rid, oid;
ScriptPointer scriptp, new_scriptp;
int defsp, new_defsp, freeloop;
+ int is_true = 0;
};
void run_func(ScriptState *st);
diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp
index 5e55e53..2a50762 100644
--- a/src/map/script-fun.cpp
+++ b/src/map/script-fun.cpp
@@ -469,6 +469,64 @@ void builtin_if (ScriptState *st)
int sel, i;
sel = conv_num(st, &AARG(0));
+ st->is_true = sel ? 2 : 1;
+ if (!sel)
+ return;
+
+ // 関数名をコピー
+ push_copy(st->stack, st->start + 3);
+ // 間に引数マーカを入れて
+ push_int<ScriptDataArg>(st->stack, 0);
+ // 残りの引数をコピー
+ for (i = st->start + 4; i < st->end; i++)
+ {
+ push_copy(st->stack, i);
+ }
+ run_func(st);
+}
+
+static
+void builtin_else (ScriptState *st)
+{
+ int i;
+
+ if (st->is_true < 1)
+ {
+ PRINTF("builtin_else: no if statement!\n"_fmt);
+ abort();
+ }
+
+ if (st->is_true > 1)
+ return;
+
+ st->is_true = 0;
+ // 関数名をコピー
+ push_copy(st->stack, st->start + 2);
+ // 間に引数マーカを入れて
+ push_int<ScriptDataArg>(st->stack, 0);
+ // 残りの引数をコピー
+ for (i = st->start + 3; i < st->end; i++)
+ {
+ push_copy(st->stack, i);
+ }
+ run_func(st);
+}
+
+static
+void builtin_elif (ScriptState *st)
+{
+ int sel, i;
+
+ if (st->is_true < 1)
+ {
+ PRINTF("builtin_elif: no if statement!\n"_fmt);
+ abort();
+ }
+ if (st->is_true > 1)
+ return;
+
+ sel = conv_num(st, &AARG(0));
+ st->is_true = sel ? 2 : 1;
if (!sel)
return;
@@ -3149,6 +3207,8 @@ BuiltinFunction builtin_functions[] =
BUILTIN(heal, "ii?"_s, '\0'),
BUILTIN(input, "N"_s, '\0'),
BUILTIN(if, "iF*"_s, '\0'),
+ BUILTIN(elif, "iF*"_s, '\0'),
+ BUILTIN(else, "F*"_s, '\0'),
BUILTIN(set, "Ne"_s, '\0'),
BUILTIN(setarray, "Ne*"_s, '\0'),
BUILTIN(cleararray, "Nei"_s, '\0'),
diff --git a/src/map/script-parse.cpp b/src/map/script-parse.cpp
index 2c7305b..a785748 100644
--- a/src/map/script-parse.cpp
+++ b/src/map/script-parse.cpp
@@ -407,7 +407,8 @@ ZString::iterator ScriptBuffer::parse_simpleexpr(ZString::iterator p)
parse_cmdp = Some(ld); // warn_*_mismatch_paramnumのために必要
// why not just check l->str == "if"_s or std::string(p, p2) == "if"_s?
- if (Some(ld) == search_strp("if"_s)) // warn_cmd_no_commaのために必要
+ if (Some(ld) == search_strp("if"_s) || Some(ld) == search_strp("elif"_s)
+ || Some(ld) == search_strp("else"_s)) // warn_cmd_no_commaのために必要
parse_cmd_if++;
p = p2;