From f085c1739a9fafd745492e9c424dd20b1615b7cf Mon Sep 17 00:00:00 2001 From: mekolat Date: Sun, 28 Jun 2015 17:05:36 -0400 Subject: add elif and else builtins --- src/map/script-call-internal.hpp | 1 + src/map/script-fun.cpp | 60 ++++++++++++++++++++++++++++++++++++++++ src/map/script-parse.cpp | 3 +- 3 files changed, 63 insertions(+), 1 deletion(-) 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(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(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; -- cgit v1.2.3-70-g09d2 From f71cd5c75c153046074f61987f681529abec75b0 Mon Sep 17 00:00:00 2001 From: mekolat Date: Thu, 20 Aug 2015 11:05:40 -0400 Subject: add builtin_if_then_else --- src/map/script-fun.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index 2a50762..6ef05ee 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -485,6 +485,13 @@ void builtin_if (ScriptState *st) run_func(st); } +static +void builtin_if_then_else (ScriptState *st) +{ + int condition = conv_num(st, &AARG(0)); + push_copy(st->stack, st->start + (condition ? 3 : 4)); +} + static void builtin_else (ScriptState *st) { @@ -3317,6 +3324,7 @@ BuiltinFunction builtin_functions[] = BUILTIN(getmap, ""_s, 's'), BUILTIN(mapexit, ""_s, '\0'), BUILTIN(freeloop, "i"_s, '\0'), + BUILTIN(if_then_else, "iii"_s, '.'), {nullptr, ""_s, ""_s, '\0'}, }; } // namespace map -- cgit v1.2.3-70-g09d2 From 6ec62e5c355408bdb8c828868d6f3ae0eabafd52 Mon Sep 17 00:00:00 2001 From: mekolat Date: Sat, 13 Jun 2015 13:36:44 -0400 Subject: add builtin_explode --- src/map/script-fun.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index 6ef05ee..496cc91 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -2387,6 +2387,49 @@ void builtin_getpartnerid2(ScriptState *st) push_int(st->stack, unwrap(sd->status.partner_id)); } +static +void builtin_explode(ScriptState *st) +{ + dumb_ptr sd = nullptr; + SIR reg = AARG(0).get_if()->reg; + ZString name = variable_names.outtern(reg.base()); + const char separator = conv_str(st, &AARG(2))[0]; + RString str = conv_str(st, &AARG(1)); + RString val; + char prefix = name.front(); + char postfix = name.back(); + + if (prefix != '$' && prefix != '@') + { + PRINTF("builtin_explode: illegal scope!\n"_fmt); + return; + } + if (prefix != '$') + sd = script_rid2sd(st); + + for (int j = 0; j < 256; j++) + { + auto find = std::find(str.begin(), str.end(), separator); + if (find == str.end()) + { + if (postfix == '$') + set_reg(sd, VariableCode::VARIABLE, reg.iplus(j), str); + else + set_reg(sd, VariableCode::VARIABLE, reg.iplus(j), atoi(str.c_str())); + break; + } + { + val = str.xislice_h(find); + str = str.xislice_t(find + 1); + + if (postfix == '$') + set_reg(sd, VariableCode::VARIABLE, reg.iplus(j), val); + else + set_reg(sd, VariableCode::VARIABLE, reg.iplus(j), atoi(val.c_str())); + } + } +} + /*========================================== * PCの所持品情報読み取り *------------------------------------------ @@ -3290,6 +3333,7 @@ BuiltinFunction builtin_functions[] = BUILTIN(getitemlink, "I"_s, 's'), BUILTIN(getspellinvocation, "s"_s, 's'), BUILTIN(getpartnerid2, ""_s, 'i'), + BUILTIN(explode, "Nss"_s, '\0'), BUILTIN(getinventorylist, ""_s, '\0'), BUILTIN(getactivatedpoolskilllist, ""_s, '\0'), BUILTIN(getunactivatedpoolskilllist, ""_s, '\0'), -- cgit v1.2.3-70-g09d2 From 66626c7f79f1d1a07847b5d9de5591412d047603 Mon Sep 17 00:00:00 2001 From: mekolat Date: Tue, 18 Aug 2015 16:13:52 -0400 Subject: add builtins sqrt, cbrt, pow --- src/map/script-fun.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index 496cc91..f85a181 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -310,6 +310,24 @@ void builtin_rand(ScriptState *st) } } +static +void builtin_sqrt(ScriptState *st) +{ + push_int(st->stack, static_cast(sqrt(conv_num(st, &AARG(0))))); +} + +static +void builtin_cbrt(ScriptState *st) +{ + push_int(st->stack, static_cast(cbrt(conv_num(st, &AARG(0))))); +} + +static +void builtin_pow(ScriptState *st) +{ + push_int(st->stack, static_cast(pow(conv_num(st, &AARG(0)), conv_num(st, &AARG(1))))); +} + /*========================================== * Check whether the PC is at the specified location *------------------------------------------ @@ -3369,6 +3387,9 @@ BuiltinFunction builtin_functions[] = BUILTIN(mapexit, ""_s, '\0'), BUILTIN(freeloop, "i"_s, '\0'), BUILTIN(if_then_else, "iii"_s, '.'), + BUILTIN(sqrt, "i"_s, 'i'), + BUILTIN(cbrt, "i"_s, 'i'), + BUILTIN(pow, "ii"_s, 'i'), {nullptr, ""_s, ""_s, '\0'}, }; } // namespace map -- cgit v1.2.3-70-g09d2 From f78d7fea310ba0b3d587e7409ea0b56e5bc9dbd0 Mon Sep 17 00:00:00 2001 From: mekolat Date: Tue, 18 Aug 2015 15:39:39 -0400 Subject: add max and min builtins --- src/map/script-fun.cpp | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index f85a181..23702e5 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -310,6 +310,66 @@ void builtin_rand(ScriptState *st) } } +static +void builtin_max(ScriptState *st) +{ + int max=0, num; + if (HARG(1)) + { + max = conv_num(st, &AARG(0)); + for (int i = 1; HARG(i); i++) + { + num = conv_num(st, &AARG(i)); + if (num > max) + max = num; + } + } + else + { + SIR reg = AARG(0).get_if()->reg; + ZString name = variable_names.outtern(reg.base()); + char prefix = name.front(); + if (prefix != '$' && prefix != '@' && prefix != '.') + { + PRINTF("builtin_max: illegal scope!\n"_fmt); + return; + } + for (int i = reg.index(); i < 256; i++) + { + struct script_data vd = get_val2(st, reg.iplus(i)); + MATCH_BEGIN (vd) + { + MATCH_CASE (const ScriptDataInt&, u) + { + if (u.numi > max) + max = u.numi; + continue; + } + } + MATCH_END (); + abort(); + } + } + + push_int(st->stack, max); +} + +static +void builtin_min(ScriptState *st) +{ + int min, num; + min = conv_num(st, &AARG(0)); + + for (int i = 1; HARG(i); i++) + { + num = conv_num(st, &AARG(i)); + if (num < min) + min = num; + } + + push_int(st->stack, min); +} + static void builtin_sqrt(ScriptState *st) { @@ -3387,6 +3447,8 @@ BuiltinFunction builtin_functions[] = BUILTIN(mapexit, ""_s, '\0'), BUILTIN(freeloop, "i"_s, '\0'), BUILTIN(if_then_else, "iii"_s, '.'), + BUILTIN(max, "e?*"_s, 'i'), + BUILTIN(min, "ii*"_s, 'i'), BUILTIN(sqrt, "i"_s, 'i'), BUILTIN(cbrt, "i"_s, 'i'), BUILTIN(pow, "ii"_s, 'i'), -- cgit v1.2.3-70-g09d2 From 69f5372502cb99fb9fe7f53ecd59ff2377237a5b Mon Sep 17 00:00:00 2001 From: mekolat Date: Thu, 24 Sep 2015 23:28:47 +0000 Subject: add arithmetic mean builtin --- src/map/script-fun.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index 23702e5..2407b37 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -370,6 +370,18 @@ void builtin_min(ScriptState *st) push_int(st->stack, min); } +static +void builtin_average(ScriptState *st) +{ + int total, i; + total = conv_num(st, &AARG(0)); + + for (i = 1; HARG(i); i++) + total += conv_num(st, &AARG(i)); + + push_int(st->stack, (total / i)); +} + static void builtin_sqrt(ScriptState *st) { @@ -3449,6 +3461,7 @@ BuiltinFunction builtin_functions[] = BUILTIN(if_then_else, "iii"_s, '.'), BUILTIN(max, "e?*"_s, 'i'), BUILTIN(min, "ii*"_s, 'i'), + BUILTIN(average, "ii*"_s, 'i'), BUILTIN(sqrt, "i"_s, 'i'), BUILTIN(cbrt, "i"_s, 'i'), BUILTIN(pow, "ii"_s, 'i'), -- cgit v1.2.3-70-g09d2 From 3d1770b8cc9e596ac33757ace64462ad3d90a15c Mon Sep 17 00:00:00 2001 From: mekolat Date: Thu, 17 Sep 2015 20:21:57 -0400 Subject: add array_search --- src/map/script-fun.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index 2407b37..a06eb1b 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -820,6 +820,54 @@ void builtin_getelementofarray(ScriptState *st) } } +static +void builtin_array_search(ScriptState *st) +{ + ZString needle_str = ZString(conv_str(st, &AARG(0))); + int needle_int = conv_num(st, &AARG(0)); + SIR reg = AARG(1).get_if()->reg; // haystack + ZString name = variable_names.outtern(reg.base()); + char prefix = name.front(); + int i, c; + + if (prefix != '$' && prefix != '@' && prefix != '.') + { + PRINTF("builtin_array_search: illegal scope!\n"_fmt); + return; + } + + i = reg.index(); c = -1; + for (; i < 256; i++) + { + struct script_data vd = get_val2(st, reg.iplus(i)); + MATCH_BEGIN (vd) + { + MATCH_CASE (const ScriptDataStr&, u) + { + if (u.str == needle_str) + { + c = i; + goto Out; + } + continue; + } + MATCH_CASE (const ScriptDataInt&, u) + { + if (u.numi == needle_int) + { + c = i; + goto Out; + } + continue; + } + } + MATCH_END (); + abort(); + } + Out: + push_int(st->stack, c); +} + static void builtin_wgm(ScriptState *st) { @@ -3354,6 +3402,7 @@ BuiltinFunction builtin_functions[] = BUILTIN(cleararray, "Nei"_s, '\0'), BUILTIN(getarraysize, "N"_s, 'i'), BUILTIN(getelementofarray, "Ni"_s, '.'), + BUILTIN(array_search, "eN"_s, 'i'), BUILTIN(setlook, "ii"_s, '\0'), BUILTIN(countitem, "I"_s, 'i'), BUILTIN(checkweight, "Ii"_s, 'i'), -- cgit v1.2.3-70-g09d2