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
_+'[y~1+y;0[1+4:"2:'=1=|y~=|\ [#N]`"#]\
`]
Here, you will witness some stack manipulation. To make the explanation a little easier to format, I'll replace the newline with an L
and the space with an S
.
_+'[y~1+y;0[1+4:"2:'=1=|y~=|\S[#N]`"#]\L`]
_+' input line, convert to #, move to c-stack
[ FOR loop
y~1+y; increment the y-pos
0 set the x-pos (the top # on the stack) to zero
[ FOR loop
1+4: increment x-pos and make 3 additional copies (4 is total #)
"2:' make a copy of the N size on the main stack
= if x-pos == size
1= or if x-pos == 1
y~=| of if x-pos == y-pos
\S (always) push a space
[ the IF body (technically a FOR loop)
#N if true, remove the space and push an N
] end IF
` output the pushed character
"# remove the result of the conditional
] end x-pos FOR
\L` output a newline
] end y-pos FOR
After doing some extreme golfing of this answer, I found a 39 byte solution, although it is much more complicated.
_'1[y~+y;[#1+3:"2:'%2<y~=|\ [#N]`"]\
`]
Task 3 - GCD
__'{"3:~2@%'}`
This is a stack-based method.
__ input the two numbers
' use one of the number as a condition so the WHILE loop starts
{ } a WHILE loop. Repeats while the c-stack has a true value on top
" get the number back from the c-stack to do operations on it
3: make it so that there are threes copies on the stack
~ takes one of the copies from earlier and converts it to a zero
2@ take the top item on the stack and move it behind the other two #s
% modulo operation
' use this number as the condition
` since one number is zero (and on the c-stack) print the
other number, which is on m-stack