mirror of
https://github.com/sfall-team/sfall.git
synced 2026-07-27 16:52:34 -07:00
Added support for nested array expressions
Fixed load_array script function not accepting floats as array keys. Added arrays testcase script. Updated header files.
This commit is contained in:
@@ -475,6 +475,7 @@
|
|||||||
#define OBJ_DATA_DAMAGE_FLAGS (0x44)
|
#define OBJ_DATA_DAMAGE_FLAGS (0x44)
|
||||||
#define OBJ_DATA_DAMAGE_LAST_TURN (0x48)
|
#define OBJ_DATA_DAMAGE_LAST_TURN (0x48)
|
||||||
#define OBJ_DATA_WHO_HIT_ME (0x54) // current target of the critter
|
#define OBJ_DATA_WHO_HIT_ME (0x54) // current target of the critter
|
||||||
|
#define OBJ_DATA_CRITTER_HP (0x58)
|
||||||
|
|
||||||
// compute attack result data offsets
|
// compute attack result data offsets
|
||||||
#define C_ATTACK_SOURCE (0x00)
|
#define C_ATTACK_SOURCE (0x00)
|
||||||
|
|||||||
@@ -35,8 +35,11 @@ procedure array_keys(variable array);
|
|||||||
// list of array values (useful for maps)
|
// list of array values (useful for maps)
|
||||||
procedure array_values(variable array);
|
procedure array_values(variable array);
|
||||||
|
|
||||||
|
// fix_array for multi-dimensional arrays
|
||||||
|
procedure fix_array_deep(variable array, variable levels := 1);
|
||||||
|
|
||||||
// makes given array permanent and returns it
|
// makes given array permanent and returns it
|
||||||
procedure array_fixed(variable array);
|
procedure array_fixed(variable array, variable levels := 1);
|
||||||
|
|
||||||
// returns temp array containing a subarray starting from $index with $count elements
|
// returns temp array containing a subarray starting from $index with $count elements
|
||||||
// negative $index means index from the end of array
|
// negative $index means index from the end of array
|
||||||
@@ -246,13 +249,28 @@ end
|
|||||||
/**
|
/**
|
||||||
* Sets given array as permanent and returns it.
|
* Sets given array as permanent and returns it.
|
||||||
* @arg {array} array
|
* @arg {array} array
|
||||||
|
* @arg {int} levels - Number of depth levels for a multi-dimensional array
|
||||||
* @ret {array}
|
* @ret {array}
|
||||||
*/
|
*/
|
||||||
procedure array_fixed(variable array) begin
|
procedure array_fixed(variable array, variable levels) begin
|
||||||
fix_array(array);
|
call fix_array_deep(array, levels);
|
||||||
return array;
|
return array;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes a multi-dimensional temp array permenant.
|
||||||
|
* @arg {array} array
|
||||||
|
* @arg {int} levels - Number of depth levels for a multi-dimensional array
|
||||||
|
*/
|
||||||
|
procedure fix_array_deep(variable array, variable levels) begin
|
||||||
|
fix_array(array);
|
||||||
|
if (levels > 1) then begin
|
||||||
|
foreach (variable subArray in array) begin
|
||||||
|
call fix_array_deep(subArray, levels - 1);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a slice of a given list array as a new temp array.
|
* Returns a slice of a given list array as a new temp array.
|
||||||
* @arg {list} array
|
* @arg {list} array
|
||||||
@@ -757,7 +775,7 @@ end
|
|||||||
procedure debug_array_str_deep(variable arr, variable levels, variable prefix := false) begin
|
procedure debug_array_str_deep(variable arr, variable levels, variable prefix := false) begin
|
||||||
#define _newline if (levels > 1) then s += "\n";
|
#define _newline if (levels > 1) then s += "\n";
|
||||||
#define _indent ii := 0; while (ii < levels - 1) do begin s += " "; ii++; end
|
#define _indent ii := 0; while (ii < levels - 1) do begin s += " "; ii++; end
|
||||||
#define _value(v) (v if (levels <= 1 or not array_exists(v)) else debug_array_str_deep(v, levels - 1))
|
#define _value(v) (v if (levels <= 1 or typeof(v) != VALTYPE_INT or not array_exists(v)) else debug_array_str_deep(v, levels - 1))
|
||||||
variable i := 0, ii, k, v, s, len;
|
variable i := 0, ii, k, v, s, len;
|
||||||
len := len_array(arr);
|
len := len_array(arr);
|
||||||
if (array_is_map(arr)) then begin // print assoc array
|
if (array_is_map(arr)) then begin // print assoc array
|
||||||
@@ -776,7 +794,6 @@ procedure debug_array_str_deep(variable arr, variable levels, variable prefix :=
|
|||||||
s += "}";
|
s += "}";
|
||||||
end else begin // print list
|
end else begin // print list
|
||||||
s := ("List("+len+"): [") if prefix else "[";
|
s := ("List("+len+"): [") if prefix else "[";
|
||||||
_newline
|
|
||||||
while i < len do begin
|
while i < len do begin
|
||||||
_newline
|
_newline
|
||||||
v := get_array(arr, i);
|
v := get_array(arr, i);
|
||||||
|
|||||||
@@ -0,0 +1,211 @@
|
|||||||
|
#include "../headers/sfall.h"
|
||||||
|
#include "../headers/lib.arrays.h"
|
||||||
|
#include "../headers/lib.strings.h"
|
||||||
|
|
||||||
|
variable test_suite_errors := 0;
|
||||||
|
variable test_suite_verbose := true;
|
||||||
|
|
||||||
|
#ifndef assertEquals
|
||||||
|
procedure assertEquals(variable desc, variable a, variable b) begin
|
||||||
|
if (a != b or typeof(a) != typeof(b)) then begin
|
||||||
|
display_msg("Assertion failed \""+desc+"\": "+a+" != "+b);
|
||||||
|
test_suite_errors ++;
|
||||||
|
end else if (test_suite_verbose) then begin
|
||||||
|
display_msg("Assert \""+desc+"\" ok");
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
procedure assertNotEquals(variable desc, variable a, variable b) begin
|
||||||
|
if (a == b) then begin
|
||||||
|
display_msg("Assertion failed \""+desc+"\": "+a+" == "+b);
|
||||||
|
test_suite_errors ++;
|
||||||
|
end else if (test_suite_verbose) then begin
|
||||||
|
display_msg("Assert \""+desc+"\" ok");
|
||||||
|
end
|
||||||
|
end
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ARRAY_MAX_STRING (1024)
|
||||||
|
#define ARRAY_MAX_SIZE (100000)
|
||||||
|
|
||||||
|
procedure array_test_suite begin
|
||||||
|
variable arr, i, arr2, map, k, v, s;
|
||||||
|
test_suite_errors := 0;
|
||||||
|
|
||||||
|
display_msg("Testing utility functions...");
|
||||||
|
call assertEquals("strlen", strlen("testing"), 7);
|
||||||
|
call assertEquals("substr 1", substr("testing", 4, 2), "in");
|
||||||
|
call assertEquals("substr 2", substr("testing", 1, -1), "estin");
|
||||||
|
call assertEquals("substr 3", substr("testing", -5, 5), "sting");
|
||||||
|
call assertEquals("typeof 1", typeof(1), VALTYPE_INT);
|
||||||
|
call assertEquals("typeof 2", typeof(1.0), VALTYPE_FLOAT);
|
||||||
|
call assertEquals("typeof 3", typeof("1.0"), VALTYPE_STR);
|
||||||
|
|
||||||
|
// Basic array functionality
|
||||||
|
display_msg("Testing basic arrays functionality...");
|
||||||
|
arr := create_array(5,0);
|
||||||
|
call assertEquals("array size", len_array(arr), 5);
|
||||||
|
arr[0]:=100;
|
||||||
|
call assertEquals("get array", get_array(arr, 0), 100);
|
||||||
|
arr[1]:=5.555;
|
||||||
|
call assertEquals("get array float", get_array(arr, 1), 5.555);
|
||||||
|
arr[2]:="hello";
|
||||||
|
call assertEquals("get array str", get_array(arr, 2), "hello");
|
||||||
|
call assertEquals("get array invalid index", get_array(arr, -1), 0);
|
||||||
|
call assertEquals("get array invalid index", get_array(arr, 6), 0);
|
||||||
|
resize_array(arr, 77);
|
||||||
|
call assertEquals("list resize", len_array(arr), 77);
|
||||||
|
resize_array(arr, ARRAY_MAX_SIZE + 100);
|
||||||
|
call assertEquals("resize max", len_array(arr), ARRAY_MAX_SIZE);
|
||||||
|
free_array(arr);
|
||||||
|
call assertEquals("not exists check", len_array(arr), -1);
|
||||||
|
arr := create_array(ARRAY_MAX_SIZE + 100, 0);
|
||||||
|
call assertEquals("create max", len_array(arr), ARRAY_MAX_SIZE);
|
||||||
|
|
||||||
|
free_array(arr);
|
||||||
|
arr := [6, 1, 10, "one", 10, "two", 5, "three"];
|
||||||
|
arr[0] := "wtf";
|
||||||
|
//display_msg(debug_array_str(arr));
|
||||||
|
call assertEquals("scan list", scan_array(arr, 10), 2);
|
||||||
|
call assertEquals("scan list 2", scan_array(arr, "two"), 5);
|
||||||
|
call assertEquals("array_key", array_key(arr, 5), 5);
|
||||||
|
call assertEquals("array_key out of range", array_key(arr, 9), 0);
|
||||||
|
call assertEquals("is list", array_key(arr, -1), 0);
|
||||||
|
|
||||||
|
call assertEquals("get array as substr", get_array("NiCe", 1), "i");
|
||||||
|
|
||||||
|
arr := [78, 12, 99, 1, -5];
|
||||||
|
sort_array(arr);
|
||||||
|
call assertEquals("sort ASC", arrays_equal(arr, [-5, 1, 12, 78, 99]), true);
|
||||||
|
|
||||||
|
arr := ["Albert", "John", "Mike", "David"];
|
||||||
|
sort_array_reverse(arr);
|
||||||
|
call assertEquals("sort DESC", arrays_equal(arr, ["Mike", "John", "David", "Albert"]), true);
|
||||||
|
reverse_array(arr);
|
||||||
|
call assertEquals("reverse list", arrays_equal(arr, ["Albert", "David", "John", "Mike"]), true);
|
||||||
|
shuffle_array(arr);
|
||||||
|
call assertEquals("shuffle list 1", arrays_equal(arr, ["Albert", "David", "John", "Mike"]), false);
|
||||||
|
call assertEquals("shuffle list 2", len_array(arr), 4);
|
||||||
|
if (test_suite_verbose) then display_array(arr);
|
||||||
|
|
||||||
|
// some additional stuff
|
||||||
|
call assertEquals("string_split", get_array(string_split("this+is+good", "+"), 2), "good");
|
||||||
|
call assertEquals("string_split 2", len_array(string_split("advice", "")), 6);
|
||||||
|
s := "";
|
||||||
|
for (i := 0; i < ARRAY_MAX_STRING+30; i+=10) begin
|
||||||
|
s += "Verbosity.";
|
||||||
|
end
|
||||||
|
arr[0] := s;
|
||||||
|
call assertEquals("array max string", strlen(arr[0]), ARRAY_MAX_STRING-1);
|
||||||
|
|
||||||
|
// ASSOC ARRAYS TEST
|
||||||
|
display_msg("Testing associative arrays...");
|
||||||
|
arr := create_array(-1,0);
|
||||||
|
call assertEquals("is map", array_key(arr, -1), 1);
|
||||||
|
call assertEquals("exists check", len_array(arr), 0);
|
||||||
|
arr["123"] := 100;
|
||||||
|
call assertEquals("set/get str=>int", arr["123"], 100);
|
||||||
|
arr["123"] := 50;
|
||||||
|
call assertEquals("overwrite 1", arr["123"], 50);
|
||||||
|
call assertEquals("overwrite 2", len_array(arr), 1);
|
||||||
|
arr[-1] := "wtf";
|
||||||
|
call assertEquals("set/get int=>str", arr[-1], "wtf");
|
||||||
|
arr[3.14] := 0.00001;
|
||||||
|
call assertEquals("set/get float=>float", arr[3.14], 0.00001);
|
||||||
|
arr["fourth"] := "elem";
|
||||||
|
call assertEquals("map size", len_array(arr), 4);
|
||||||
|
arr[-1] := 0;
|
||||||
|
call assertEquals("unset key: length", len_array(arr), 3);
|
||||||
|
call assertEquals("unset key: hashmap", arr[3.14], 0.00001);
|
||||||
|
call assertEquals("key not exist", arr[777], 0);
|
||||||
|
free_array(arr);
|
||||||
|
call assertEquals("not exists check", len_array(arr), -1);
|
||||||
|
arr := {6:5, 1.001:0.5, 10:"A", 5:0, "wtf":1.1, 10:0.0001, "some":"What"}; // 7 here
|
||||||
|
// 10:"A" will be overwritten by 10:0.0001
|
||||||
|
call assertEquals("assoc array expr", len_array(arr), 6); // 6 actual
|
||||||
|
|
||||||
|
call assertEquals("scan map 1", scan_array(arr, 1.1), "wtf");
|
||||||
|
call assertEquals("scan map 2", scan_array(arr, 5), 6);
|
||||||
|
call assertEquals("scan map 3", scan_array(arr, "What"), "some");
|
||||||
|
call assertEquals("array_key 1", array_key(arr, 0), 6);
|
||||||
|
call assertEquals("array_key 2", array_key(arr, 4), "wtf");
|
||||||
|
call assertEquals("array_key 3", array_key(arr, 1), 1.001);
|
||||||
|
|
||||||
|
resize_array(arr, 2);
|
||||||
|
call assertEquals("map resize 1", len_array(arr), 2);
|
||||||
|
call assertEquals("map resize 2", arrays_equal(arr, {6:5, 1.001:0.5}), true);
|
||||||
|
resize_array(arr, 0);
|
||||||
|
call assertEquals("map clear", len_array(arr), 0);
|
||||||
|
|
||||||
|
display_msg("Testing foreach...");
|
||||||
|
s := "ar";
|
||||||
|
arr := [6, 10, 0.5, "wtf"];
|
||||||
|
foreach v in arr begin
|
||||||
|
s += v;
|
||||||
|
end
|
||||||
|
call assertEquals("foreach 1", s, "ar6100.50000wtf");
|
||||||
|
s := "ar2=";
|
||||||
|
arr := {"name": "John", "hp": 25, 0: 5.5};
|
||||||
|
foreach k: v in arr begin
|
||||||
|
s += k+":"+v+";";
|
||||||
|
end
|
||||||
|
call assertEquals("foreach 2", s, "ar2=name:John;hp:25;0:5.50000;");
|
||||||
|
|
||||||
|
|
||||||
|
display_msg("Testing save/load...");
|
||||||
|
arr := [2,1];
|
||||||
|
arr2 := {1:2};
|
||||||
|
s := "wtf";
|
||||||
|
k := 1;
|
||||||
|
if (arr and arr2[k]) then s := "ok";
|
||||||
|
call assertEquals("bracket syntax", s, "ok");
|
||||||
|
save_array("myarray", arr);
|
||||||
|
call assertEquals("load 1", load_array("myarray"), arr);
|
||||||
|
save_array("myarray", arr2);
|
||||||
|
call assertEquals("load 2", load_array("myarray"), arr2);
|
||||||
|
free_array(arr2);
|
||||||
|
call assertEquals("not exists check", len_array(arr2), -1);
|
||||||
|
call assertEquals("load fail", load_array("myarray"), 0);
|
||||||
|
save_array(0.1, arr);
|
||||||
|
call assertEquals("save as float", load_array(0.1), arr);
|
||||||
|
arr2 := list_saved_arrays; // list of array names
|
||||||
|
//display_msg(debug_array_str(arr2));
|
||||||
|
call assertNotEquals("saved arrays 1", scan_array(arr2, 0.1), -1);
|
||||||
|
call assertEquals("saved arrays 2", scan_array(arr2, "myarray"), -1);
|
||||||
|
save_array(0, arr);
|
||||||
|
call assertEquals("unsave array 1", load_array(0.1), 0);
|
||||||
|
call assertEquals("unsave array 2", len_array(arr), 2);
|
||||||
|
call assertEquals("saved arrays 3", len_array(list_saved_arrays), len_array(arr2) - 1);
|
||||||
|
|
||||||
|
display_msg("Testing nested expressions...");
|
||||||
|
arr := [["one", "two"], {"three": "four"}];
|
||||||
|
call assertEquals("nested 1", arr[0][1], "two");
|
||||||
|
call assertEquals("nested 2", arr[1].three, "four");
|
||||||
|
|
||||||
|
display_msg("All tests finished with "+test_suite_errors+" errors.");
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
procedure arrays_lib_tests begin
|
||||||
|
variable arr, i, arr2, map, k, v, s;
|
||||||
|
test_suite_errors := 0;
|
||||||
|
|
||||||
|
call assertEquals("array_equals 1", arrays_equal([9, 7, 2, 1], [9, 7, 2, 1]), true);
|
||||||
|
call assertEquals("array_equals 2", arrays_equal([9, 7, 0, 1], [9, 7, 2, 1]), false);
|
||||||
|
call assertEquals("array_equals 3", arrays_equal([1, 1, 1, 1], [1, 1, 1]), false);
|
||||||
|
call assertEquals("array_equals 4", arrays_equal([], []), true);
|
||||||
|
call assertEquals("array_equals 5", arrays_equal({}, []), false);
|
||||||
|
call assertEquals("array_equals 6", arrays_equal({1: 1.0, 2: 2.0}, {1: 1.000, 2: 2.000}), true);
|
||||||
|
call assertEquals("array_equals 7", arrays_equal({"name": "John", "dept": 15.20}, {"name": "John"}), false);
|
||||||
|
|
||||||
|
arr := array_transform(array_filter(string_split(",23,1,ghh 6 6,77.1 ", ","), @string_null_or_empty, true), @string_to_float);
|
||||||
|
call assertEquals("array_filter 1", arrays_equal(arr, [23.0,1.0,0.0,77.1]), true);
|
||||||
|
display_msg("All tests finished with "+test_suite_errors+" errors.");
|
||||||
|
end
|
||||||
|
|
||||||
|
procedure start begin
|
||||||
|
if not game_loaded then return;
|
||||||
|
|
||||||
|
call array_test_suite;
|
||||||
|
call arrays_lib_tests;
|
||||||
|
end
|
||||||
@@ -45,7 +45,9 @@ ArrayKeysMap savedArrays;
|
|||||||
// auto-incremented ID
|
// auto-incremented ID
|
||||||
DWORD nextArrayID = 1;
|
DWORD nextArrayID = 1;
|
||||||
// special array ID for array expressions, contains the ID number of the currently created array
|
// special array ID for array expressions, contains the ID number of the currently created array
|
||||||
DWORD stackArrayId;
|
DWORD expressionArrayId;
|
||||||
|
// special stack for array expressions, contains ID numbers of the currently created arrays
|
||||||
|
std::vector<DWORD> arrayExpressionStack;
|
||||||
|
|
||||||
static char get_all_arrays_special_key[] = "...all_arrays...";
|
static char get_all_arrays_special_key[] = "...all_arrays...";
|
||||||
|
|
||||||
@@ -429,7 +431,19 @@ DWORD CreateArray(int len, DWORD flags) {
|
|||||||
// var.key = sArrayElement(nextArrayID, DATATYPE_INT);
|
// var.key = sArrayElement(nextArrayID, DATATYPE_INT);
|
||||||
// savedArrays[var.key] = nextArrayID;
|
// savedArrays[var.key] = nextArrayID;
|
||||||
//}
|
//}
|
||||||
stackArrayId = nextArrayID;
|
if ((flags & ARRAYFLAG_EXPR_PUSH) != 0) {
|
||||||
|
// When creating array for sub-expression, make sure to add array for base expression to stack
|
||||||
|
// This is messy, but required to support older scripts:
|
||||||
|
// - We must always assign expressionArrayId for one-layer expressions from older scripts to work like they did before
|
||||||
|
// - We can't directly push first arrayID into stack b/c no way to distinguish between start of an expression and normal temp_array call
|
||||||
|
// - Compiler will only add this flag for temp_array call generated from a sub-expression
|
||||||
|
// - So only on this second call we know we are in expression and expressionArrayId definitely contains arrayId of the first layer
|
||||||
|
if (arrayExpressionStack.empty() && expressionArrayId != 0) {
|
||||||
|
arrayExpressionStack.push_back(expressionArrayId);
|
||||||
|
}
|
||||||
|
arrayExpressionStack.push_back(nextArrayID);
|
||||||
|
}
|
||||||
|
expressionArrayId = nextArrayID;
|
||||||
arrays[nextArrayID] = var;
|
arrays[nextArrayID] = var;
|
||||||
return nextArrayID++;
|
return nextArrayID++;
|
||||||
}
|
}
|
||||||
@@ -757,16 +771,31 @@ void SaveArray(const ScriptValue& key, DWORD id) {
|
|||||||
|
|
||||||
Should always return 0!
|
Should always return 0!
|
||||||
*/
|
*/
|
||||||
long StackArray(const ScriptValue& key, const ScriptValue& val) {
|
void SetArrayFromExpression(const ScriptValue& key, const ScriptValue& val) {
|
||||||
if (stackArrayId == 0 || !ArrayExists(stackArrayId)) return 0;
|
DWORD arrayId = !arrayExpressionStack.empty()
|
||||||
|
? arrayExpressionStack.back()
|
||||||
|
: expressionArrayId;
|
||||||
|
|
||||||
if (!arrays[stackArrayId].isAssoc()) { // automatically resize array to fit one new element
|
if (arrayId == 0 || !ArrayExists(arrayId)) return;
|
||||||
size_t size = arrays[stackArrayId].val.size();
|
|
||||||
if (size >= ARRAY_MAX_SIZE) return 0;
|
if (!arrays[arrayId].isAssoc()) { // automatically resize array to fit one new element
|
||||||
if (key.rawValue() >= size) arrays[stackArrayId].val.resize(size + 1);
|
size_t size = arrays[arrayId].val.size();
|
||||||
|
if (size >= ARRAY_MAX_SIZE) return;
|
||||||
|
if (key.rawValue() >= size) arrays[arrayId].val.resize(size + 1);
|
||||||
|
}
|
||||||
|
SetArray(arrayId, key, val, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PopExpressionArray() {
|
||||||
|
if (arrayExpressionStack.empty()) return;
|
||||||
|
|
||||||
|
arrayExpressionStack.pop_back();
|
||||||
|
|
||||||
|
// Reversing the hack from CreateArray
|
||||||
|
if (arrayExpressionStack.size() == 1) {
|
||||||
|
expressionArrayId = arrayExpressionStack.back();
|
||||||
|
arrayExpressionStack.pop_back();
|
||||||
}
|
}
|
||||||
SetArray(stackArrayId, key, val, false);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sArrayVar* GetRawArray(DWORD id) {
|
sArrayVar* GetRawArray(DWORD id) {
|
||||||
|
|||||||
@@ -109,6 +109,8 @@ struct sArrayVarOld
|
|||||||
#define ARRAYFLAG_ASSOC (1) // is map
|
#define ARRAYFLAG_ASSOC (1) // is map
|
||||||
#define ARRAYFLAG_CONSTVAL (2) // don't update value of key if the key exists in map
|
#define ARRAYFLAG_CONSTVAL (2) // don't update value of key if the key exists in map
|
||||||
#define ARRAYFLAG_RESERVED (4)
|
#define ARRAYFLAG_RESERVED (4)
|
||||||
|
#define ARRAYFLAG_EXPR_PUSH (32) // is created as part of array sub-expression
|
||||||
|
#define ARRAYFLAG_EXPR_POP (64) // is used to indicate end of array sub-expression, not used in actual array
|
||||||
|
|
||||||
typedef std::unordered_map<sArrayElement, DWORD, sArrayElement_HashFunc, sArrayElement_EqualFunc> ArrayKeysMap;
|
typedef std::unordered_map<sArrayElement, DWORD, sArrayElement_HashFunc, sArrayElement_EqualFunc> ArrayKeysMap;
|
||||||
|
|
||||||
@@ -224,8 +226,11 @@ DWORD LoadArray(const ScriptValue& key);
|
|||||||
// make array saved into the savegame with associated key
|
// make array saved into the savegame with associated key
|
||||||
void SaveArray(const ScriptValue& key, DWORD id);
|
void SaveArray(const ScriptValue& key, DWORD id);
|
||||||
|
|
||||||
// special function that powers array expressions
|
// sets array element from array expression
|
||||||
long StackArray(const ScriptValue& key, const ScriptValue& val);
|
void SetArrayFromExpression(const ScriptValue& key, const ScriptValue& val);
|
||||||
|
|
||||||
|
// used to indicate the end of array sub-expression
|
||||||
|
void PopExpressionArray();
|
||||||
|
|
||||||
sArrayVar* GetRawArray(DWORD id);
|
sArrayVar* GetRawArray(DWORD id);
|
||||||
|
|
||||||
|
|||||||
@@ -90,7 +90,15 @@ void op_resize_array(OpcodeContext& ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void op_temp_array(OpcodeContext& ctx) {
|
void op_temp_array(OpcodeContext& ctx) {
|
||||||
DWORD arrayId = CreateTempArray(ctx.arg(0).rawValue(), ctx.arg(1).rawValue());
|
const ScriptValue& flags = ctx.arg(1);
|
||||||
|
|
||||||
|
// Special case for array sub-expressions.
|
||||||
|
if ((flags.rawValue() & ARRAYFLAG_EXPR_POP) != 0) {
|
||||||
|
PopExpressionArray();
|
||||||
|
ctx.setReturn(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DWORD arrayId = CreateTempArray(ctx.arg(0).rawValue(), flags.rawValue());
|
||||||
ctx.setReturn(arrayId);
|
ctx.setReturn(arrayId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,10 +128,9 @@ void op_get_array_key(OpcodeContext& ctx) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void op_stack_array(OpcodeContext& ctx) {
|
void op_arrayexpr(OpcodeContext& ctx) {
|
||||||
ctx.setReturn(
|
SetArrayFromExpression(ctx.arg(0), ctx.arg(1));
|
||||||
StackArray(ctx.arg(0), ctx.arg(1))
|
ctx.setReturn(0);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// object LISTS
|
// object LISTS
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ void op_load_array(OpcodeContext&);
|
|||||||
|
|
||||||
void op_get_array_key(OpcodeContext&);
|
void op_get_array_key(OpcodeContext&);
|
||||||
|
|
||||||
void op_stack_array(OpcodeContext&);
|
void op_arrayexpr(OpcodeContext&);
|
||||||
|
|
||||||
void op_list_begin(OpcodeContext&);
|
void op_list_begin(OpcodeContext&);
|
||||||
|
|
||||||
|
|||||||
@@ -192,9 +192,9 @@ static SfallOpcodeInfo opcodeInfoArray[] = {
|
|||||||
// 0x252 // RESERVED
|
// 0x252 // RESERVED
|
||||||
{0x253, "typeof", op_typeof, 1, true},
|
{0x253, "typeof", op_typeof, 1, true},
|
||||||
{0x254, "save_array", op_save_array, 2, false, 0, {ARG_ANY, ARG_OBJECT}},
|
{0x254, "save_array", op_save_array, 2, false, 0, {ARG_ANY, ARG_OBJECT}},
|
||||||
{0x255, "load_array", op_load_array, 1, true, -1, {ARG_INTSTR}},
|
{0x255, "load_array", op_load_array, 1, true, -1, {ARG_ANY}},
|
||||||
{0x256, "array_key", op_get_array_key, 2, true, 0, {ARG_INT, ARG_INT}},
|
{0x256, "array_key", op_get_array_key, 2, true, 0, {ARG_INT, ARG_INT}},
|
||||||
{0x257, "arrayexpr", op_stack_array, 2, true},
|
{0x257, "arrayexpr", op_arrayexpr, 2, true},
|
||||||
// 0x258 // RESERVED for arrays
|
// 0x258 // RESERVED for arrays
|
||||||
// 0x259 // RESERVED for arrays
|
// 0x259 // RESERVED for arrays
|
||||||
{0x25a, "reg_anim_destroy", op_reg_anim_destroy, 1, false, 0, {ARG_OBJECT}},
|
{0x25a, "reg_anim_destroy", op_reg_anim_destroy, 1, false, 0, {ARG_OBJECT}},
|
||||||
|
|||||||
Reference in New Issue
Block a user