Talk:*lang
An example of a linked list as a stack
; program demonstrating pushing values to a ; linked list and retrieving those values for printing new *newline; declare printable constant ; pre-initialisation new *safe_return; forward declare for fall-through new *clearEnvironment; new *return; return declarations so the returns don't jump new *inner_return; new *push_mangled_return; new *callValue_mangled_return; new *pointer; register declarations so they can be safely dereferenced new *push_value; back *safe_return; safe_return = &&clearEnvironment; ; define functions new *innerSetNewline; *pointer = *pointer; back *inner_return; value = newline; back *return; new *setNewline; inner_return = &&innerSetNewline; back **safe_return; back **inner_return; back *return; new *0; define printable constants new *1; new *2; new *3; new *4; new *5; new *6; new *7; new *8; new *9; new *innerSet0; *pointer = *pointer; back *inner_return; value = 0; back *return; new *set0; inner_return = &&innerSet0; back **safe_return; back **inner_return; back *return; new *innerSet1; *pointer = *pointer; back *inner_return; value = 1; back *return; new *set1; inner_return = &&innerSet1; back **safe_return; back **inner_return; back *return; new *innerSet2; *pointer = *pointer; back *inner_return; value = 2; back *return; new *set2; inner_return = &&innerSet2; back **safe_return; back **inner_return; back *return; new *innerSet3; *pointer = *pointer; back *inner_return; value = 3; back *return; new *set3; inner_return = &&innerSet3; back **safe_return; back **inner_return; back *return; new *innerSet4; *pointer = *pointer; back *inner_return; value = 4; back *return; new *set4; inner_return = &&innerSet4; back **safe_return; back **inner_return; back *return; new *innerSet5; *pointer = *pointer; back *inner_return; value = 5; back *return; new *set5; inner_return = &&innerSet5; back **safe_return; back **inner_return; back *return; new *innerSet6; *pointer = *pointer; back *inner_return; value = 6; back *return; new *set6; inner_return = &&innerSet6; back **safe_return; back **inner_return; back *return; new *innerSet7; *pointer = *pointer; back *inner_return; value = 7; back *return; new *set7; inner_return = &&innerSet7; back **safe_return; back **inner_return; back *return; new *innerSet8; *pointer = *pointer; back *inner_return; value = 8; back *return; new *set8; inner_return = &&innerSet8; back **safe_return; back **inner_return; back *return; new *innerSet9; *pointer = *pointer; back *inner_return; value = 9; back *return; new *set9; inner_return = &&innerSet9; back **safe_return; back **inner_return; back *return; new *callValue; callValue_mangled_return = return; new *inner_return; hack to handle unintended return when jumping to inner_return return = &&pointer; back **safe_return; back **return; back *callValue_mangled_return; new *push; pointer = &pointer; push_mangled_return = return; return = &&push_value; back **safe_return; back **return; back *push_mangled_return; ; post-initialisation new *safe_return; clearEnvironment = safe_return; make initialisation calls fall-through ; program start new *loop_condition; new *loop_stop; pointer = loop_condition; push_value = setNewline; return = &&push; back **return; push_value = set8; return = &&push; back **return; push_value = set0; return = &&push; back **return; push_value = set0; return = &&push; back **return; push_value = set8; return = &&push; back **return; push_value = set5; return = &&push; back **return; *loop_condition = *loop_stop; return = &&callValue; back **return; out value; temp = pointer; pointer = *pointer; *temp = loop_condition; back *loop_condition;
Starting from the end of the program, from the section labelled program start, there are a few variables defined for popping all the values off of the stack in a loop at the end. I haven't spent much time on loops yet, so this is still a bit clunky. Then all the values for the string "58008\n" are pushed onto the stack in reverse order. The values are all popped off of the stack and printed.
The rest of the program is just boilerplate. If we start reading from the top, the program starts with a comment I added to describe the program, and the first character constant (a newline). The pre-initialisation defines a function, in this case clearEnvironment which is useful for stopping unwanted jumps when initialising the rest of the functions. It sets all the variables that might be used as jumps to point to themselves, so that anything like back *var;
will resolve to the same line and be skipped.
The functions all start with a function name like new *functionName
. This example doesn't use a call stack, so while most functions use return to store the return location, a few functions which call other functions use their own return variable. inner_return
for example.
The line *pointer = *pointer
is repeated for every value that we want to be able to store on the stack. It is not possible to store values directly on a stack, so instead we store functions. Then the functions are called to retrieve the value and put it in the value register.
This is definitely precursor work, and the next steps are probably introducing proper numbers (I think for a number n will be handled by setting value to a list of length n), and implementing a proper call stack. --JJRubes (talk) 06:18, 25 May 2025 (UTC)