Talk:*lang

From Esolang
Jump to navigation Jump to search

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)