2012 - Element
This is a language that I invented in early 2012 to be a simple golfing language. By this, I mean that there is very little to no operator overloading. The operators are also simpler and fewer in number than most modern golfing languages.
The most interesting features of this language are its data structures. There are two stacks and a hash that are used to store information.
The m-stack is the main stack, where arithmetic and most other operations take place. When data is inputted or printed, this is where it goes or is retrieved from.
The c-stack is the control stack. This is where boolean arithmetic takes place. The top values of the c-stack are used by If and While loops as the condition.
The hash is where variables are stored. The ;
and ~
store and retrieve data from the hash, respectively.
Element is a very weakly typed language. It uses Perl's ability to freely interpret numbers as strings and vice-versa.
While I'm at it, I might as well include all the documentation for the language. You can find the original 2012 interpreter, written in Perl, right here. Update: I have created a more usable version, which you can find right here.
OP the operator. Each operator is a single character
STACK tells what stacks are affected and how many are popped or pushed
"o" stands for "other effect"
HASH tells if it involves the hash
x & y represent two values that are already on the stack, so the effect of
the operator can be more easily described
OP STACK HASH DESCRIPTION
text ->m --whenever a bare word appears, it pushes that string onto
the main stack
_ o->m --inputs a word and pushes onto main stack
` m->o --output. pops from main stack and prints
xy; mm-> yes --variable assignment. the top stack element y is assigned
the value x
~ m->m yes --variable retrieval. pops from main stack, pushes contents
of the element with that name
x? m->c --test. pops x and pushes 0 onto control stack if x is '0' or
an empty string, else pushes 1
><= m->c --comparison. pops two numbers off of stack and performs
test, pushes 1 onto control stack if true and 0 if false
' m->c --pops from main stack and pushes onto control stack
" c->m --pops from control stack and pushes onto main stack
&| cc->c --AND/OR. pops two items from control stack, performs and/or
respectively, and pushes result back onto control stack
! c->c --NOT. pops a number off of control stack, pushes 1 if 0 or
empty string, 0 otherwise
[] c --FOR statement (view the top number number from control stack
and eval those many times)
{} c --WHILE (loop until top number on control stack is 0, also
does not pop)
# m-> --discard. pops from main stack and destroys
( m->mm --pops from main stack, removes first character, pushes the
remaining string onto stack, and pushes the removed character
onto stack
) m->mm --pops from main stack, removes last character, pushes the
remaining string onto stack, and pushes the removed character
onto stack
+-*/%^ mm->m --arithmetic. pops two most recent items, adds/negates
/multiplies/divides/modulates/exponentiates them, and places
the result on the stack
xy@ mm->o --move. pops x and y and moves xth thing in stack to move to
place y in stack
x$ m->m --length. pops x and pushs length of x onto the stack
xy: mm->o --duplication. pops x and y and pushes x onto the stack y times
xy. mm->m --concatination. pops x and y and pushes x concatonated with y
\ o --escapes out of next character, so it isn't an operator and can
be pushed onto the stack
, m->mm --character conversion. pops from main stack, coverts it to char
and pushes, and converts to num and pushes
Newlines and spaces separate different elements to be pushed
onto the stack individually, but can pushed onto the stack using \
Task 1 - Print Text
Element\ was\ made\ in\ 2012\!`
One of the more awkward parts of the language is the lack of string delimiters, which is why escape characters are needed in this string. The `
at the end prints the string.
Task 2 - ASCII Art N
_+n;n~'[[3:?!y~=|1+2:n~=|[N]![\ ]`"#]\
`y~1+y;0]
Here, you will witness some stack manipulation. To make the explanation a little easier to format, I'll replace the newline with an L
.
_+n;n~'[[3:?!y~=|1+2:n~=|[N]![\ ]`"#]\L`y~1+y;0]
_+n; input a line, make sure it's in number format with "+" and store it in n
n~'[ use this number to control a FOR loop
[ another FOR loop. We carefully make sure that n remains on top of the c-stack
3: duplicate the top (maybe empty) item of the stack, our X position, 3 times.
?! if it's equal to zero or undefined
y~=| or it's equal to the Y position
1+2:n~=| or it's equal to n once incremented (duplicating saves it for next iteration)
[N] push N
![\ ] else push a space
` output whatever was just pushed
"# discard the test results so that n remains on top of the c-stack
] end the X position FOR loop
\L` print a newline, but the L should be an actual newline
y~1+y; increment the Y position
0 put zero as the top item on the stack, this is our reset X position
] end the Y position FOR loop
This answer
Task 3 - GCD
__!{2:0 2@%2:?}#`
This is a stack-based method.
__ input the two numbers
! the c-stack starts empty, we negate it so that the while loop starts
{ } a WHILE loop. Repeats while the c-stack has a true value on top
2: duplicate the top value on the m-stack
0 2@ take the top item on the stack and move it behind the other two #s
% modulo operation
2: duplicate the result
? test condition for the loop. Repeat if the result is non-zero
# remove the pesky zero result from the m-stack
` print the resulting number
Here's a slightly more golfed version:
__!{3:~2@%2:?}#`
Basically, you make an additional copy of the variable and then use ~
to retrieve it's assigned value, which is zero by default. This avoids the need for a space to separate the numbers.