6ZZOMSZRHZ67J5N64GYR4GO7JG3O45EJBRRNRDJS3T533VPVRCAAC
#############
# Functions #
#############
void run_tests(string name, array tests)
number count = 0
loop test in tests
if !equal(test[0], test[1])
Print(name + " " + count + ": fail")
Print("left: " + test[0])
Print("right: " + test[1])
end
count += 1
end
Print(name + " tests done.")
end
# test.sprak
Library for testing functions/programs.
## Usage
* TODO.
## Functions
### `run_tests`
Runs unit tests that test for equality of outputs
#### Type
`string -> [[A, A]] -> void`
#### Arguments
* `name`: Name of the curent test.
* `tests`: Array of output pairs to compare.
#### Examples
```sprak
# TODO
```
#### Imports
* equality.sprak
###############
# serde.sprak #
###############
string deserialise_string(string input)
string output = ""
bool escaped = false
loop character in input
if character != "\"
if character != '"'
output += character
end
else if escaped
output += character
escaped = false
else if character == '\'
escaped = true
end
end
return output
end
bool is_digit(string input)
number code = CharToInt(input)
if code >= -49
if code <= -40
return true
end
end
return false
end
# Types:
# * 0: none
# * 1: bool
# * 2: number
# * 3: string
# * 4: array
var deserialise_array(string input)
array accumulator = []
bool in_string = false
bool escaped = false
bool in_value = false
string buffer = ""
number key_type = 0
bool key_bool = false
number key_number = 0
string key_string = ""
number value_type = 0
bool value_bool = false
number value_number = 0
string value_string = ""
array contexts = []
loop character in input
bool is_numeric = false
if character == ":"
if !in_string
in_value = true
if key_type == 2
key_number = buffer
buffer = ""
end
else if in_value
value_string += ":"
else
key_string += ":"
end
else if character == ","
if !in_string
if key_type == 2
if value_type == 3
accumulator[key_number] = value_string
else if value_type == 2
value_number = buffer
accumulator[key_number] = value_number
else if value_type == 1
accumulator[key_number] = value_bool
end
else if key_type == 3
if value_type == 3
accumulator[key_string] = value_string
else if value_type == 2
value_number = buffer
accumulator[key_string] = value_number
else if value_type == 1
accumulator[key_string] = value_bool
end
else if key_type == 1
if value_type == 3
accumulator[key_bool] = value_string
else if value_type == 2
value_number = buffer
accumulator[key_bool] = value_number
else if value_type == 1
accumulator[key_bool] = value_bool
end
end
in_value = false
buffer = ""
key_string = ""
value_string = ""
else if in_value
value_string += ","
else
key_string += ","
end
else if is_digit(character)
is_numeric = true
else if character == "."
is_numeric = true
else if character == "-"
is_numeric = true
else if character == '"'
if !in_string
in_string = true
if in_value
value_type = 3
else
key_type = 3
end
else if !escaped
in_string = false
else if in_value
value_string += '"'
else
key_string += '"'
end
else if character == "t"
if !in_string
if in_value
value_bool = true
value_type = 1
else
key_bool = true
key_type = 1
end
else if in_value
value_string += "t"
else
key_string += "t"
end
else if character == "f"
if !in_string
if in_value
value_bool = false
value_type = 1
else
key_bool = false
key_type = 1
end
else if in_value
value_string += "f"
else
key_string += "f"
end
else if character == "{"
if !in_string
if key_type == 2
Append(contexts, [accumulator, key_type, key_number])
else if key_type == 0
Append(contexts, [accumulator, key_type])
else if key_type == 3
Append(contexts, [accumulator, key_type, key_string])
else
Append(contexts, [accumulator, key_type, key_bool])
end
accumulator = []
else
value_string += "{"
end
else if character == "}"
if !in_string
if key_type == 2
if value_type == 3
accumulator[key_number] = value_string
else if value_type == 2
value_number = buffer
accumulator[key_number] = value_number
else if value_type == 1
accumulator[key_number] = value_bool
end
else if key_type == 3
if value_type == 3
accumulator[key_string] = value_string
else if value_type == 2
value_number = buffer
accumulator[key_string] = value_number
else if value_type == 1
accumulator[key_string] = value_bool
end
else if key_type == 1
if value_type == 3
accumulator[key_bool] = value_string
else if value_type == 2
value_number = buffer
accumulator[key_bool] = value_number
else if value_type == 1
accumulator[key_bool] = value_bool
end
end
array last_context = contexts[Count(contexts) - 1]
array last_accumulator = last_context[0]
number last_key_type = last_context[1]
if last_key_type != 0
last_accumulator[last_context[2]] = accumulator
else
return accumulator
end
accumulator = last_accumulator
value_type = 4
Remove(contexts, Count(contexts) - 1)
else
value_string += "}"
end
else if character == "\"
if !escaped
escaped = true
else
escaped = false
if in_value
value_string += "\"
else
key_string += "\"
end
end
else if in_value
value_string += character
else
key_string += character
end
if is_numeric
if !in_string
buffer += character
if in_value
value_type = 2
else
key_type = 2
end
else if in_value
value_string += character
else
key_string += character
end
end
end
end
var deserialise(string input)
if input[0] == "{"
return deserialise_array(input)
else if is_digit(input[0])
number output = input
return output
else if input[0] == "-"
number output = input
return output
else if input[0] == '"'
return deserialise_string(input)
else if input == "t"
return true
else if input == "f"
return false
end
end
##################
# equality.sprak #
##################
bool equal_array(array first, array second)
if Count(first) == Count(second)
if "" + first == "" + second
loop key in GetIndexes(first)
if !HasIndex(second, key)
return false
else if !equal(first[key], second[key])
return false
end
end
return true
end
end
return false
end
bool equal(var first, var second)
string type_first = Type(first)
if type_first == Type(second)
if type_first != "array"
return first == second
end
return equal_array(first, second)
end
return false
end
###############
# array.sprak #
###############
bool has(var test_element, array input)
loop element in input
if equal(element, test_element)
return true
end
end
return false
end
#############
# Functions #
#############
array supply(array overrides, string function)
string MemoryAPI_thing = "FinanceComputer"
string TingrunnerAPI_thing = "PoliceOfficeInterior_MinistryOfficeWorkstationComputer_1"
string name = Name()
if HasIndex(overrides, "MemoryAPI")
MemoryAPI_thing = overrides["MemoryAPI"]
end
if HasIndex(overrides, "TingrunnerAPI")
TingrunnerAPI_thing = overrides["TingrunnerAPI"]
end
var MemoryAPI
if MemoryAPI_thing != name
MemoryAPI = Connect(MemoryAPI_thing)
else
return [false, "MemoryAPI unavailable."]
end
var TingrunnerAPI
if TingrunnerAPI_thing != name
TingrunnerAPI = Connect(TingrunnerAPI_thing)
else
return [false, "TingrunnerAPI unavailable."]
end
array skip_types = ["floppy", "navnode", "bed", "point", "seat", "locker", "memory", "portal", "character", "map", "suitcase", "goods"]
array skip_things = ["ComputerTerminalBoard1_ComputerTerminalBoard1", "Hotel_Diner_Fountain", "TrainingCube", "Internet_Internet_MediumComputer_10", "Internet_MediumComputer", "ArcadeHall_ArcadeMachine_ArcadeMachine_3"]
var load_buffer
if !HasIndex(overrides, "skip_types")
load_buffer = MemoryAPI.LoadMemory("skip_types")
if load_buffer != 0
skip_types = deserialise(load_buffer)
end
else
skip_types = overrides["skip_types"]
end
if !HasIndex(overrides, "skip_things")
load_buffer = MemoryAPI.LoadMemory("skip_things")
if load_buffer != 0
skip_things = deserialise(load_buffer)
end
else
skip_things = overrides["skip_things"]
end
if HasIndex(overrides, "more_skip_types")
loop type in overrides["more_skip_types"]
if !has(type, skip_types)
Append(skip_types, type)
end
end
end
if HasIndex(overrides, "more_skip_things")
loop thing in overrides["more_skip_things"]
if !has(thing, skip_things)
Append(skip_things, thing)
end
end
end
load_buffer = MemoryAPI.LoadMemory(function)
if load_buffer != 0
if load_buffer != name
if !has(load_buffer, skip_things)
if !has(TingrunnerAPI.GetTypeOfThing(load_buffer), skip_types)
var connection = Connect(load_buffer)
if connection.HasFunction(function)
return [true, connection]
end
end
end
end
end
load_buffer = 0
loop room in TingrunnerAPI.GetAllRooms()
loop thing in TingrunnerAPI.GetThingsInRoom(room)
if thing != name
if !has(thing, skip_things)
if !has(TingrunnerAPI.GetTypeOfThing(thing), skip_types)
var connection = Connect(thing)
if connection.HasFunction(function)
MemoryAPI.SaveMemory(function, thing)
return [true, connection]
end
end
end
end
end
end
return [false, "`" + function + "` not found."]
end
# supply.sprak
Library for supplying connections.
## Usage
* Once in a while, keep re-runnning the "skip.sprak" script until completion to update the list of types and things to skip.
* Don't use on "FinanceComputer" or "PoliceOfficeInterior_MinistryOfficeWorkstationComputer_1".
## Functions
### `supply`
Returns `[true, connection]` where `connection` is a connection to a thing that supplies the input function if anything in the game world is able to supply the function, otherwise `[false, error_message]` where `error_message` is a `string` about what caused the failure. If it hasn't yet been cached, the thing that supplies the function is then saved in the memory of "FinanceComputer" (or the thing overriding it) using the name of the function as key to speed up later access to the same function.
#### Type
`["MemoryAPI"?: string, "TingrunnerAPI"?: string, "skip_types"?: [string], "skip_things"?: [string], "more_skip_types"?: [string], "more_skip_things"?: [string]] -> string -> [true, connection] | [false, string]`
#### Arguments
* `overrides`: `array` that may contain data to replace or supplement variables used by the function.
* `function`: Function to find a connection for.
#### Examples
```sprak
var connection = supply([], "IsNight")
Say("" + connection[1].IsNight())
```
#### Imports
* serde.sprak
* `deserialise`
* equality.sprak
* array.sprak
* `has`
DisconnectAll()
###############
# serde.sprak #
###############
string serialise_string(string input)
string output = ""
loop character in input
if character == '"'
output += "\"
else if character == "\"
output += "\"
end
output += character
end
return '"' + output + '"'
end
string serialise_array(array input)
string output = ""
bool not_start = false
loop key in GetIndexes(input)
string key_type = Type(key)
if key_type != "array"
if not_start
output += ","
else
not_start = true
end
output += serialise(key) + ":" + serialise(input[key])
end
end
return "{" + output + "}"
end
string serialise(var input)
string input_type = Type(input)
if input_type == "unknown"
string output = ""
loop character in "" + input
if character != "i"
output += character
end
end
return output
else if input_type == "string"
return serialise_string(input)
else if input_type == "number"
return "" + input
else if input_type == "bool"
if input
return "t"
end
return "f"
else if input_type == "array"
return serialise_array(input)
end
end
string deserialise_string(string input)
string output = ""
bool escaped = false
loop character in input
if character != "\"
if character != '"'
output += character
end
else if escaped
output += character
escaped = false
else if character == '\'
escaped = true
end
end
return output
end
bool is_digit(string input)
number code = CharToInt(input)
if code >= -49
if code <= -40
return true
end
end
return false
end
# Types:
# * 0: none
# * 1: bool
# * 2: number
# * 3: string
# * 4: array
var deserialise_array(string input)
array accumulator = []
bool in_string = false
bool escaped = false
bool in_value = false
string buffer = ""
number key_type = 0
bool key_bool = false
number key_number = 0
string key_string = ""
number value_type = 0
bool value_bool = false
number value_number = 0
string value_string = ""
array contexts = []
loop character in input
bool is_numeric = false
if character == ":"
if !in_string
in_value = true
if key_type == 2
key_number = buffer
buffer = ""
end
else if in_value
value_string += ":"
else
key_string += ":"
end
else if character == ","
if !in_string
if key_type == 2
if value_type == 3
accumulator[key_number] = value_string
else if value_type == 2
value_number = buffer
accumulator[key_number] = value_number
else if value_type == 1
accumulator[key_number] = value_bool
end
else if key_type == 3
if value_type == 3
accumulator[key_string] = value_string
else if value_type == 2
value_number = buffer
accumulator[key_string] = value_number
else if value_type == 1
accumulator[key_string] = value_bool
end
else if key_type == 1
if value_type == 3
accumulator[key_bool] = value_string
else if value_type == 2
value_number = buffer
accumulator[key_bool] = value_number
else if value_type == 1
accumulator[key_bool] = value_bool
end
end
in_value = false
buffer = ""
key_string = ""
value_string = ""
else if in_value
value_string += ","
else
key_string += ","
end
else if is_digit(character)
is_numeric = true
else if character == "."
is_numeric = true
else if character == "-"
is_numeric = true
else if character == '"'
if !in_string
in_string = true
if in_value
value_type = 3
else
key_type = 3
end
else if !escaped
in_string = false
else if in_value
value_string += '"'
else
key_string += '"'
end
else if character == "t"
if !in_string
if in_value
value_bool = true
value_type = 1
else
key_bool = true
key_type = 1
end
else if in_value
value_string += "t"
else
key_string += "t"
end
else if character == "f"
if !in_string
if in_value
value_bool = false
value_type = 1
else
key_bool = false
key_type = 1
end
else if in_value
value_string += "f"
else
key_string += "f"
end
else if character == "{"
if !in_string
if key_type == 2
Append(contexts, [accumulator, key_type, key_number])
else if key_type == 0
Append(contexts, [accumulator, key_type])
else if key_type == 3
Append(contexts, [accumulator, key_type, key_string])
else
Append(contexts, [accumulator, key_type, key_bool])
end
accumulator = []
else
value_string += "{"
end
else if character == "}"
if !in_string
if key_type == 2
if value_type == 3
accumulator[key_number] = value_string
else if value_type == 2
value_number = buffer
accumulator[key_number] = value_number
else if value_type == 1
accumulator[key_number] = value_bool
end
else if key_type == 3
if value_type == 3
accumulator[key_string] = value_string
else if value_type == 2
value_number = buffer
accumulator[key_string] = value_number
else if value_type == 1
accumulator[key_string] = value_bool
end
else if key_type == 1
if value_type == 3
accumulator[key_bool] = value_string
else if value_type == 2
value_number = buffer
accumulator[key_bool] = value_number
else if value_type == 1
accumulator[key_bool] = value_bool
end
end
array last_context = contexts[Count(contexts) - 1]
array last_accumulator = last_context[0]
number last_key_type = last_context[1]
if last_key_type != 0
last_accumulator[last_context[2]] = accumulator
else
return accumulator
end
accumulator = last_accumulator
value_type = 4
Remove(contexts, Count(contexts) - 1)
else
value_string += "}"
end
else if character == "\"
if !escaped
escaped = true
else
escaped = false
if in_value
value_string += "\"
else
key_string += "\"
end
end
else if in_value
value_string += character
else
key_string += character
end
if is_numeric
if !in_string
buffer += character
if in_value
value_type = 2
else
key_type = 2
end
else if in_value
value_string += character
else
key_string += character
end
end
end
end
var deserialise(string input)
if input[0] == "{"
return deserialise_array(input)
else if is_digit(input[0])
number output = input
return output
else if input[0] == "-"
number output = input
return output
else if input[0] == '"'
return deserialise_string(input)
else if input == "t"
return true
else if input == "f"
return false
end
end
##################
# equality.sprak #
##################
bool equal_array(array first, array second)
if Count(first) == Count(second)
if "" + first == "" + second
loop key in GetIndexes(first)
if !HasIndex(second, key)
return false
else if !equal(first[key], second[key])
return false
end
end
return true
end
end
return false
end
bool equal(var first, var second)
string type_first = Type(first)
if type_first == Type(second)
if type_first != "array"
return first == second
end
return equal_array(first, second)
end
return false
end
###############
# array.sprak #
###############
bool has(array input, var test_element)
loop element in input
if equal(element, test_element)
return true
end
end
return false
end
#############
# Functions #
#############
bool no_SprakAPI(string thing)
return Connect(thing).HasFunction("") == 0
end
########
# Main #
########
ClearText()
string name = Name()
string MemoryAPI = Connect("FinanceComputer")
string TingrunnerAPI = Connect("PoliceOfficeInterior_MinistryOfficeWorkstationComputer_1")
array skip_types = []
skip_types[0] = "floppy"
array skip_things = []
var load_buffer = MemoryAPI.LoadMemory("skip_types")
if load_buffer != 0
skip_types = deserialise(load_buffer)
end
load_buffer = MemoryAPI.LoadMemory("skip_things")
if load_buffer != 0
skip_things = deserialise(load_buffer)
end
load_buffer = 0
bool seen_last_thing = false
string last_thing = ""
number number_buffer = Count(skip_things)
if number_buffer > 0
last_thing = skip_things[number_buffer - 1]
else
seen_last_thing = true
end
loop room in TingrunnerAPI.GetAllRooms()
loop thing in TingrunnerAPI.GetThingsInRoom(room)
if seen_last_thing
string thing_type = TingrunnerAPI.GetTypeOfThing(thing)
if thing != name
if !has(skip_types, thing_type)
if !has(skip_things, thing)
Append(skip_things, thing)
MemoryAPI.SaveMemory("skip_things", serialise(skip_things))
if no_SprakAPI(thing)
Append(skip_types, thing_type)
MemoryAPI.SaveMemory("skip_types", serialise(skip_types))
end
Remove(skip_things, Count(skip_things) - 1)
end
end
end
else if thing == last_thing
seen_last_thing = true
end
end
end
MemoryAPI.SaveMemory("skip_things", serialise(skip_things))
Say("Done.")
DisconnectAll()
# skip.sprak
Finds and saves the names of things with broken code and types with no SprakAPI (no `HasFunction` function). Saves the serialised results to the memory of "FinanceComputer" using the keys "skip_types" for the types "skip_things" for the names.
## Usage
* Don't run the code on "FinanceComputer" or "PoliceOfficeInterior_MinistryOfficeWorkstationComputer_1".
* Save the code onto a thing that has the `Say` and `Connect` functions. A drink would work, but a computer would be more ideal, as the latter's code execution speed can be increased using screwdrivers.
* Run the code until it causes an error or until completion. I recommend pausing the game whilst the code is running and periodically checking if it's done as pausing allows code to run faster. It is critical that the code is not interrupted whilst it's running (i.e., don't re-hack the thing/re-run the code) as this will cause incorrect outputs.
* Repeat the previous step until a notification appears with the "Done." message. I recommend saving after each time the code errors/finishes in case of accidents.
## Functions
### `no_SprakAPI`
Determines if the thing has SprakAPI.
#### Type
`string -> bool`
#### Arguments
* `thing`: Thing to test.
#### Examples
```sprak
# TODO
```
## Imports
* supply.sprak
* `hardcoded_supply`
* serde.sprak
* equality.sprak
* array.sprak
* `has`
##################
# equality.sprak #
##################
bool equal_array(array first, array second)
if Count(first) == Count(second) && "" + first == "" + second
loop key in GetIndexes(first)
if !HasIndex(second, key)
return false
else if !equal(first[key], second[key])
return false
end
end
return true
end
return false
end
bool equal(var first, var second)
string type_first = Type(first)
if type_first == Type(second)
if type_first != "array"
return first == second
end
return equal_array(first, second)
end
return false
end
##############
# test.sprak #
##############
void run_tests(string name, array tests)
number count = 0
loop test in tests
if !equal(test[0], test[1])
Print(name + " " + count + ": fail")
Print("left: " + test[0])
Print("right: " + test[1])
end
count += 1
end
Print(name + " tests done.")
end
#############
# Functions #
#############
void test_serialise_string()
string name = "serialise_string"
array tests = []
Append(tests, [serialise_string('a'), '"a"'])
Append(tests, [serialise_string(''), '""'])
Append(tests, [serialise_string('\'), '"\\"'])
Append(tests, [serialise_string('"'), '"\""'])
Append(tests, [serialise_string('\\'), '"\\\\"'])
run_tests(name, tests)
end
void test_serialise_array()
string name = "serialise_array"
array tests = []
Append(tests, [serialise_array([false]), '{0:f}'])
Append(tests, [serialise_array([-273.15]), '{0:-273.15}'])
Append(tests, [serialise_array([""]), '{0:""}'])
Append(tests, [serialise_array([[]]), '{0:{}}'])
Append(tests, [serialise_array([]), '{}'])
run_tests(name, tests)
end
void test_serialise()
string name = "serialise"
array tests = []
Append(tests, [serialise(false), 'f'])
Append(tests, [serialise(-273.15), '-273.15'])
Append(tests, [serialise(""), '""'])
Append(tests, [serialise([]), '{}'])
array a = [false]
array keys = GetIndexes(a)
Append(tests, [serialise(keys[0]), '0'])
run_tests(name, tests)
end
void test_deserialise_string()
string name = "deserialise_string"
array tests = []
Append(tests, [deserialise_string('"a"'), 'a'])
Append(tests, [deserialise_string('""'), ''])
Append(tests, [deserialise_string('"\\"'), '\'])
Append(tests, [deserialise_string('"\""'), '"'])
Append(tests, [deserialise_string('"\\\\"'), '\\'])
run_tests(name, tests)
end
void test_is_digit()
string name = "is_digit"
array tests = []
Append(tests, [is_digit("0"), true])
Append(tests, [is_digit("1"), true])
Append(tests, [is_digit("2"), true])
Append(tests, [is_digit("3"), true])
Append(tests, [is_digit("4"), true])
Append(tests, [is_digit("5"), true])
Append(tests, [is_digit("6"), true])
Append(tests, [is_digit("7"), true])
Append(tests, [is_digit("8"), true])
Append(tests, [is_digit("9"), true])
Append(tests, [is_digit("a"), false])
run_tests(name, tests)
end
void test_deserialise_array()
string name = "deserialise_array"
array tests = []
array a = []
a = deserialise_array('{0:f}')
Append(tests, [a, [false]])
a = deserialise_array('{0:-273.15}')
Append(tests, [a, [-273.15]])
a = deserialise_array('{0:"a"}')
Append(tests, [a, ["a"]])
a = deserialise_array('{0:""}')
Append(tests, [a, [""]])
a = deserialise_array('{0:{}}')
Append(tests, [a, [[]]])
a = deserialise_array('{}')
Append(tests, [a, []])
run_tests(name, tests)
end
void test_deserialise()
string name = "deserialise"
array tests = []
Append(tests, [deserialise('f'), false])
Append(tests, [deserialise('-273.15'), -273.15])
Append(tests, [deserialise('""'), ""])
Append(tests, [deserialise('{}'), []])
array a = [false]
array keys = GetIndexes(a)
number b = keys[0]
Append(tests, [deserialise('0'), b])
run_tests(name, tests)
end
DisconnectAll()
ClearText()
test_serialise_string()
test_serialise_array()
test_serialise()
test_deserialise_string()
test_is_digit()
test_deserialise_array()
test_deserialise()
###############
# serde.sprak #
###############
string serialise_string(string input)
string output = ""
loop character in input
if character == '"'
output += "\"
else if character == "\"
output += "\"
end
output += character
end
return '"' + output + '"'
end
string serialise_array(array input)
string output = ""
bool not_start = false
loop key in GetIndexes(input)
string key_type = Type(key)
if key_type != "array"
if not_start
output += ","
else
not_start = true
end
output += serialise(key) + ":" + serialise(input[key])
end
end
return "{" + output + "}"
end
string serialise(var input)
string input_type = Type(input)
if input_type == "unknown"
string output = ""
loop character in "" + input
if character != "i"
output += character
end
end
return output
else if input_type == "string"
return serialise_string(input)
else if input_type == "number"
return "" + input
else if input_type == "bool"
if input
return "t"
end
return "f"
else if input_type == "array"
return serialise_array(input)
end
end
string deserialise_string(string input)
string output = ""
bool escaped = false
loop character in input
if character != "\"
if character != '"'
output += character
end
else if escaped
output += character
escaped = false
else if character == '\'
escaped = true
end
end
return output
end
bool is_digit(string input)
number code = CharToInt(input)
if code >= -49
if code <= -40
return true
end
end
return false
end
# Types:
# * 0: none
# * 1: bool
# * 2: number
# * 3: string
# * 4: array
var deserialise_array(string input)
array accumulator = []
bool in_string = false
bool escaped = false
bool in_value = false
string buffer = ""
number key_type = 0
bool key_bool = false
number key_number = 0
string key_string = ""
number value_type = 0
bool value_bool = false
number value_number = 0
string value_string = ""
array contexts = []
loop character in input
bool is_numeric = false
if character == ":"
if !in_string
in_value = true
if key_type == 2
key_number = buffer
buffer = ""
end
else if in_value
value_string += ":"
else
key_string += ":"
end
else if character == ","
if !in_string
if key_type == 2
if value_type == 3
accumulator[key_number] = value_string
else if value_type == 2
value_number = buffer
accumulator[key_number] = value_number
else if value_type == 1
accumulator[key_number] = value_bool
end
else if key_type == 3
if value_type == 3
accumulator[key_string] = value_string
else if value_type == 2
value_number = buffer
accumulator[key_string] = value_number
else if value_type == 1
accumulator[key_string] = value_bool
end
else if key_type == 1
if value_type == 3
accumulator[key_bool] = value_string
else if value_type == 2
value_number = buffer
accumulator[key_bool] = value_number
else if value_type == 1
accumulator[key_bool] = value_bool
end
end
in_value = false
buffer = ""
key_string = ""
value_string = ""
else if in_value
value_string += ","
else
key_string += ","
end
else if is_digit(character)
is_numeric = true
else if character == "."
is_numeric = true
else if character == "-"
is_numeric = true
else if character == '"'
if !in_string
in_string = true
if in_value
value_type = 3
else
key_type = 3
end
else if !escaped
in_string = false
else if in_value
value_string += '"'
else
key_string += '"'
end
else if character == "t"
if !in_string
if in_value
value_bool = true
value_type = 1
else
key_bool = true
key_type = 1
end
else if in_value
value_string += "t"
else
key_string += "t"
end
else if character == "f"
if !in_string
if in_value
value_bool = false
value_type = 1
else
key_bool = false
key_type = 1
end
else if in_value
value_string += "f"
else
key_string += "f"
end
else if character == "{"
if !in_string
if key_type == 2
Append(contexts, [accumulator, key_type, key_number])
else if key_type == 0
Append(contexts, [accumulator, key_type])
else if key_type == 3
Append(contexts, [accumulator, key_type, key_string])
else
Append(contexts, [accumulator, key_type, key_bool])
end
accumulator = []
else
value_string += "{"
end
else if character == "}"
if !in_string
if key_type == 2
if value_type == 3
accumulator[key_number] = value_string
else if value_type == 2
value_number = buffer
accumulator[key_number] = value_number
else if value_type == 1
accumulator[key_number] = value_bool
end
else if key_type == 3
if value_type == 3
accumulator[key_string] = value_string
else if value_type == 2
value_number = buffer
accumulator[key_string] = value_number
else if value_type == 1
accumulator[key_string] = value_bool
end
else if key_type == 1
if value_type == 3
accumulator[key_bool] = value_string
else if value_type == 2
value_number = buffer
accumulator[key_bool] = value_number
else if value_type == 1
accumulator[key_bool] = value_bool
end
end
array last_context = contexts[Count(contexts) - 1]
array last_accumulator = last_context[0]
number last_key_type = last_context[1]
if last_key_type != 0
last_accumulator[last_context[2]] = accumulator
else
return accumulator
end
accumulator = last_accumulator
value_type = 4
Remove(contexts, Count(contexts) - 1)
else
value_string += "}"
end
else if character == "\"
if !escaped
escaped = true
else
escaped = false
if in_value
value_string += "\"
else
key_string += "\"
end
end
else if in_value
value_string += character
else
key_string += character
end
if is_numeric
if !in_string
buffer += character
if in_value
value_type = 2
else
key_type = 2
end
else if in_value
value_string += character
else
key_string += character
end
end
end
end
var deserialise(string input)
if input[0] == "{"
return deserialise_array(input)
else if is_digit(input[0])
number output = input
return output
else if input[0] == "-"
number output = input
return output
else if input[0] == '"'
return deserialise_string(input)
else if input == "t"
return true
else if input == "f"
return false
end
end
# serde.sprak
Library for (de)serialising data.
## Functions
### `serialise_string`
Returns the serialised form of input where `\` and `"` characters have been prepended with `\`.
#### Type
`string -> string`
#### Arguments
* `input`: String to serialise.
#### Examples
```sprak
Print(equal(serialise_string('foo"\\'), 'foo\"\\\\'))
```
### `serialise_array`
Returns the serialised version of an `array`. Excludes elements whose keys are not of type `bool`, `number`, `string`, or `unknown`. Keys of type `unknown` are assumed to be `array` indices and will be converted to `number`.
#### Type
`array -> string`
#### Arguments
* `input`: Array to serialise.
#### Examples
```sprak
Print(equal(serialise_array([true, false]), "{0:t,1:f}"))
```
### `serialise`
Returns the serialised version of the input. Assumes data of type `unknown` are `array` indices and are converted to `number`. Data of type `number` are rounded to include only up to 6 decimal places of precision.
#### Type
`var -> string`
#### Arguments
* `input`: Input to serialise.
#### Examples
```sprak
Print(equal(serialise(true), "t"))
Print(equal(serialise(false), "f"))
Print(equal(serialise(-273.15), "-273.15"))
Print(equal(serialise([true, "false"]) == '{0:t,1:"false"}'))
```
### `deserialise_string`
Returns the deserialised form of the input.
#### Type
`string -> string`
#### Arguments
* `input`: Serialised string to deserialise.
#### Examples
```sprak
Print(equal(deserialise_string('"foo\"\\\\"'), 'foo"\\'))
```
### `is_digit`
Determines if the input character is a numeric digit.
#### Type
`string -> bool`
#### Arguments
* `input`: Character to test.
#### Examples
```sprak
Print(is_digit(0))
Print(!is_digit(a))
```
### `deserialise_array`
Returns the deserialised form of the input.
Assumptions:
* "\\" and whitespace characters only occur in strings.
* Keys are only of type `bool`, `number` or `string`.
* Input is valid.
#### Type
`string -> array`
#### Arguments
* `input`: Serialised array to deserialise.
#### Examples
```sprak
Print(equal(deserialise_array("{0:t,1:f}"), [true, false]))
```
### `deserialise`
Returns the deserialised form of the input.
Assumptions:
* "\\" and whitespace characters only occur in strings.
* `array` keys are only of type `bool`, `number` or `string`.
* Input is valid.
#### Type
`string -> var`
#### Arguments
* `input`: Input to deserialise.
#### Examples
```sprak
Print(equal(deserialise("t"), true))
Print(equal(deserialise("f"), false))
Print(equal(deserialise("-273.15"), -273.15))
Print(equal(deserialise('{0:t,1:"false"}'), [true, "false"]))
```
## TODO
* Replace recursions with iterations in:
* `serialise_array` and `serialise`
* Add an option to serialise numbers using more precision.
bool equal_array(array first, array second)
if Count(first) == Count(second)
if "" + first == "" + second
loop key in GetIndexes(first)
if !HasIndex(second, key)
return false
else if !equal(first[key], second[key])
return false
end
end
return true
end
end
return false
end
bool equal(var first, var second)
string type_first = Type(first)
if type_first == Type(second)
if type_first != "array"
return first == second
end
return equal_array(first, second)
end
return false
end
# serde.sprak
Library for testing data equality.
## Functions
### `equal_array`
Determines if both inputs are equal to each other
#### Type
`array -> array -> bool`
#### Arguments
* `first`: Input to compare with `second`.
* `second`: Input to compare with `first`.
#### Examples
```sprak
# TODO
```
### `equal`
Determines if both inputs are equal to each other
#### Type
`var -> var -> bool`
#### Arguments
* `first`: Input to compare with `second`.
* `second`: Input to compare with `first`.
#### Examples
```sprak
Print(equal(true, true))
array a = []
a[1] = 1
a[0] = 0
Print(equal([0, 1], a)[1])
Print(!equal(true, false)[1])
array b = []
Append(b, [0])
array c = []
Append(c, b[0])
Print(!equal(b, b)[0])
```
{
"folders": [
{
"name": "else_heart_break_scripts",
"path": "."
},
{
"name": "else_heart_break",
"path": "../../../../else_heart_break"
},
{
"name": "sprak-language-extension",
"path": "../../../../projects/sprak-language-extension"
},
{
"path": "../else_heart_break_scripts.1639998913"
}
],
"settings": {}
}
###############
# array.sprak #
###############
bool has(var elem, array arr)
loop element in arr
if equal(element, elem)
return true
end
end
return false
end
# serde.sprak
Library for `array` data.
## Functions
### `has`
Determines if an array contains an element.
#### Type
`A -> array A -> bool`
#### Arguments
* `elem`: The value to search for.
* `arr`: Array to search in.
#### Examples
```sprak
# TODO
```
#### Imports
* equality.sprak
* `equal_array`
* `equal`
# else-Heart.Break
Code for items in the game [else Heart.Break()](http://elseheartbreak.com/ "else Heart.Break() Homepage").
---
## Notes
* `bool` operators in Sprak don't seem to short-circuit. Unconcise usage of conditionals in this project may have been used to emulate short-circuiting `bool` operators.
* Some functions have long execution durations and may stop after a while. To prevent this, pause the game when running them because they continue to run (and at a faster speed) even when the game is paused.
---
## License
This software is distributed and licensed under the terms of the [Blue Oak Model License 1.0.0](https://web.archive.org/web/20190309191626/https://blueoakcouncil.org/license/1.0.0).
### Contribution
Unless you explicitly state otherwise, any contribution submitted for inclusion in this software by you shall be licensed as above, without any additional terms or conditions.
# Blue Oak Model License
Version 1.0.0
## Purpose
This license gives everyone as much permission to work with
this software as possible, while protecting contributors
from liability.
## Acceptance
In order to receive this license, you must agree to its
rules. The rules of this license are both obligations
under that agreement and conditions to your license.
You must not do anything with this software that triggers
a rule that you cannot or will not follow.
## Copyright
Each contributor licenses you to do everything with this
software that would otherwise infringe that contributor's
copyright in it.
## Notices
You must ensure that everyone who gets a copy of
any part of this software from you, with or without
changes, also gets the text of this license or a link to
<https://blueoakcouncil.org/license/1.0.0>.
## Excuse
If anyone notifies you in writing that you have not
complied with [Notices](#notices), you can keep your
license by taking all practical steps to comply within 30
days after the notice. If you do not do so, your license
ends immediately.
## Patent
Each contributor licenses you to do everything with this
software that would otherwise infringe any patent claims
they can license or become able to license.
## Reliability
No contributor can revoke this license.
## No Liability
***As far as the law allows, this software comes as is,
without any warranty or condition, and no contributor
will be liable to anyone for any damages related to this
software or this license, under any kind of legal claim.***
.git
.DS_Store