The start.zoo file provided with the Yazoo source files exists to provide an interactive command prompt for the user. It also performs some minor housekeeping chores, runs user.zoo and provides a few definitions of its own, etc. We won't say much about the bulk of this script, other than that it generally works, but there are a few variables and functions that might be of interest to the user. Most variables within start.zoo are invisible to the user living inside its workspace, but there are some, where noted, which can be accessed by the user, because start.zoo explicitly aliases them into the user's workspace.
The twelve variables and functions that follow are members of start.zoo that it makes available to the user. It is best not to go too rough on them, since it's pretty easy to crash start.zoo if they get disrupted.
disasm:
if set to `true' or `on', causes errors to be flagged using the disassembler. When Yazoo flags a runtime error, it normally reprints the offending line from the pre-compiled source script alongside the error message. There is an alternative, which is to have it spit out the original bytecode instead. The bytecode is made somewhat less unreadable by the so-called `disassembler' (which takes Yazoo bytecode, not real machine code), but is still more difficult than the original script. One advantage is that the error can be flagged more precisely in bytecode. Disassembly is normally the method of last resort, for cases when Yazoo cannot find the original code for some reason. Used by the author to satisfy the odd craving for a rush of bytecode.
calculator:
causes the results of incomplete expressions to be printed from the command prompt. This only applies to expressions that are not assigned to variables, or used in any other way. For example, if the user types
a = 5 + 2
then nothing will be printed, regardless of whether calculator is on or off. However, if the user were to enter just
5 + 2
then the answer `7' will be printed if, and only if, calculator is set to on.
From the perspective of the start.zoo, `incomplete expressions' are simply tokens within the workspace. Because these tokens are generally never used again, the prune package in start.zoo removes all the workspace tokens after every entry from the user. The calculator mode works by printing out tokens just before they are deleted.
The main reason for the calculator mode is that it saves the user from typing print(...) for every value he may want to calculate. The drawback is that sometimes things are printed that the user doesn't want. For example, functions may return error codes that are normally discarded, which will show up as incessant 0s, etc. that can get annoying -- or worse, enormous blocks of data that expound voluminously onto the screen. Despite the potential disadvantages, the calculator defaults to on.
One standing problem is that the calculator doesn't necessarily know the order in which the arguments were entered (in the case of, say, `5, 3, 2'). For that reason it is best to group multiple results by braces.
calculator_function():
: the function the calculator uses to print. user.zoo by default aliases this function to sprint(). To change the function one would type, e.g., calculator_function = @printl.
ans:
: short for "answer". This is whatever the calculator last printed. Void if the calculator hasn't printed anything yet.
The following three user-accessible variables allow one to compile code that is compatible with the user's own variable names.
AllNames:
the list of member names that have been defined so far. With each entry from the command prompt, this list is needed to sync the names in the current command with what has been defined so far. If this list goes then everything goes. By passing AllNames to the compiler the user can compile code that can access other externally-defined members by name.
YH_Lines[]:
an array of strings, two per transformed script, containing information about where line breaks in the original text would fall in the compiled bytecodes. When an error occurs in a script, Yazoo tries to use this array to figure out which line of original text to display, rather than show a disassembly. The array is two-dimensional: YH_Lines[5][1] is the name of the file that code number 5 was compiled from, and YH_Lines[5][2] is a single string which gives the positions of all line-breaks for that entire script. This latter string is returned by compile() via the optional third argument. Upon an error, start.zoo writes the file name in the first string, and uses the second string to figure out which line in that file to display.
ScriptStrings[]:
an array of strings, each containing the original text of a script that was compiled. By adding compiled scripts to this array, the user enables start.zoo to write out the offending source line at the site of any error. Each element of ScriptStrings corresponds to the respective code number; i.e. ScriptStrings[6] is the script whose code ID (as returned by transform(), or variable_code_ID(), etc.) is 6.
The next array is used by go() and jump in user.zoo.
go_path[]:
a proxy array containing the search path, beginning with root and ending with the current working variable. This array is modified by go() and jump(), and is occasionally reset by start.zoo if it detects a problem. The user can add a small coding section to go_path which start.zoo will run if it needs to reset the path; the restriction is that the coding section should not declare any variables or run any functions or problems will start happening. user.zoo uses the coding section of go_path to reset the pwd variable.
The following two error lists and one function are made accessible to the user in the workspace.
LLErrorStrings:
contains the names of each linked-list error according to their error codes; so for example LLErrorStrings[1] corresponds to error code number 1. Linked-list errors can be thrown to the user's C routines when they use linked list routines for string-processing.
CompileErrorStrings:
the error strings that compile() outputs.
RuntimeErrorString()
syntax: (string) error_string = RuntimeErrorString((numeric) error_code [, (numeric) code_word_at_error])
This function returns the text of a runtime error (or transformation error -- they use the same error list). The first argument is the error code; the optional second argument is the signed long word in the bytecode where the error was flagged (the location of an error that was given by R_error_index), in order to back out the name of the member that caused the problem. If the second argument is provided, and if the error was member-related error and Yazoo always throws the flag where the offending member ID was written in the bytecode, then RuntimeErrorString() can fill in a member name in the error message. For example:
> print(RuntimeErrorString(8))
member not defined
> print(RuntimeErrorString(8, 1))
member 'AllNames' not defined
In an interactive session member ID 1 corresponds to the AllNames variable.
Notice that RuntimeErrorString() lacks an `s' at the end of its name, whereas the two other error lists are both plural.
disassemble()
syntax: [(string) disassembly = ] disassemble((string) compiled_code or { (string) compiled_code, (numeric) start_pos } [, (Boolean) write_output [, (string) namespace [, (Boolean) expand_functions [, (numeric) flagpoint]]]]
The disassemble() function returns a textual interpretation of compiled Yazoo bytecode. The required first argument is a string containing the bytecode. The function will return the `disassembly' as a readable string unless the second argument is passed as false. If a namespace is provided in the third argument, then the disassembler will substitute member names for member numbers. The command-line namespace is AllNames. If given, the fourth argument determines whether inlined code definitions are disassembled (if true; this is the default), or skipped with an ellipsis if false. The fifth argument tells the disassembler to flag a certain location in the code, which is useful for marking errors in the code. The flag position is the index, starting from one, of the compiled long-integer word that caused the error; the default value of 0 causes no flag to be drawn. Arguments 2-5 are all optional and can be skipped or passed with a `*' to use the default values.
For example, suppose we wanted to flag the location of a warning (as these would not normally be disassembled). We could extract the bytecode and view some sensible representation of it by writing:
original_code :: disasm_code :: string
original_code = variable_code(R_warning_script, 1)
disasm_code = disassemble(original_code, *, *, *, R_warning_index)
print("Error ", R_warning_code, ":\n\n", disasm_code)
An alternative use for the disassembler is to skip over bytecode expressions, and one can do this by passing both the compiled code and a starting word index together within braces in the first argument. In this case the disassembler will only disassemble up to the end of the expression, and if the starting word index was passed in a variable then that variable will be updated to the beginning of the next expression. For example, we can use this feature to write a function that finds the Nth sentence in a compiled expression.
go_to_Nth_sentence :: {
code
code_string := args[1]
N := args[2]
code_index := @args[3]
code_index = 1
for (n :: ulong) in [1, N-1]
disassemble( { code_string, code_index }, false )
endf
}
Skipping over code is much faster if we don't have to generate the bytecode text, which is why we passed a false second argument to disassemble().
The following two classes in start.zoo are only used internally, but the user might like to know that they do what they do.
R_Backup:
contains functions that save the registers after each command from the prompt has executed, and retrieves them again before the next command executes. From the user's point of view, this effectively isolates the registers from the influences of start.zoo.
PrunePackage:
weeds out tokens and hidden members from the user's workspace. Tokens are created all the time in the normal course of operation, notably when the user's functions, or certain built-in Yazoo functions, are called but not assigned explicitly to a variable. Hidden members are also created with function calls. The following line generates both a token and a hidden member:
> do_something()
Both tokens and hidden members would ordinarily prevent the memory associated with these objects from being freed when the user no longer needed them. To prevent this, the PrunePackage removes all direct members of the workspace variable that have either a negative ID or have the hidden flag set. It then runs SpringCleaning() for good measure. The workspace is pruned after each entry from the user has finished executing.
Workspace tokens are almost completely decoupled from the rest of the code once they are created, so deleting them should be quite innocuous. The only way that the user could even detect the pruning would be to notice that, say, this[1218] or root[1218] mysteriously disappears between command-prompt entries. It would be a peculiar style, but if the user wants to use workspace tokens for storing valuables then he should consider commenting out the PruneMembers() invocation in start.zoo.
If the calculator option is set, then tokens get to print their contents as a final act before the execution. Hidden members get no such privileges.
Last update: July 28, 2013