ible
professional vim user
I came up with an esoteric programming language, and an interpreter for it...
At some point, I'd like to write this in C with much more matrix functionality (diagonalization, etc.), but it's easier to play with a new language on the internet, so I made a javascript interpreter for your enjoyment/puzzlement:
https://patchsoul.github.io/FAKE/
Click on the "Show Help" to get a good overview/tutorial of the possible stuffs. (I'll copy it into the spoiler below, though it will be easier to navigate at the site.) I saw MATL a few weeks back, and decided to create a similar language -- each letter/symbol is some function, functions operate on a stack, the operators/functions are postfix; though some functions have instructions (e.g. for branching) which appear on the right.
For example:
You can also create functions for things like ö, which is fun .
It's a bit of practice for some other programming languages I hope to write out someday...
There are probably bugs, and I haven't written in all the features from the README, and I'm not sure I will (at least for the javascript version). I'll probably at least put in random numbers... Feedback and feature requests are welcome, though they won't necessarily be heeded
Thought about putting this in the "Development Section", but it's not really a game or something specific to handheld devices...
At some point, I'd like to write this in C with much more matrix functionality (diagonalization, etc.), but it's easier to play with a new language on the internet, so I made a javascript interpreter for your enjoyment/puzzlement:
https://patchsoul.github.io/FAKE/
Click on the "Show Help" to get a good overview/tutorial of the possible stuffs. (I'll copy it into the spoiler below, though it will be easier to navigate at the site.) I saw MATL a few weeks back, and decided to create a similar language -- each letter/symbol is some function, functions operate on a stack, the operators/functions are postfix; though some functions have instructions (e.g. for branching) which appear on the right.
For example:
Code:
"hello world!" # prints hello world.
5 4 / # pushes 1.25 to the stack.
0!["First branch executed"]["Second branch executed"] # ! is a conditional branch, takes two instructions on the right, pops stack to figure out which one to execute.
'hello'z"Hello to `y`!" # creates a function `hello`, which prints "Hello to "+ whatever is on the top of the stack
'you' `hello`
'Q'z0.25 # create a function `Q`, which pushes 0.25 to the stack
Q # invoke any single-character function without backticks, or with, your choice :)
You can also create functions for things like ö, which is fun .
It may be easier to navigate this mess on the website, but here it is anyways ...
Code:
# Terminal Commands
# This terminal has super awesome features, with multi-line code areas possible.
# Navigate history with up and down arrows.
# Press enter to execute, and shift-enter to create a newline in the current code area.
# You can swap this behavior by clicking on the [Enter to execute] button above.
# Numbers and Basic Math: +- */ ^_
# # a hash symbol means ignore the remaining input to end-of-line, i.e. make a comment.
0.5 # push a number to the stack. a number begins with 0-9, so start with 0. to do fractions.
-5.3 # push a negative number to the stack, i.e. - is unary minus if 0-9 follows.
+-*/ # standard mathematical operators, postfix notation, operating on numbers already on the stack.
^ # power, takes NOS as base and TOS as exponent.
_ # natural log, determines ln of TOS.
# to take an arbitrary log, base B, of some number N:
# N_B_/ # infix: log_B(N) = log(N)/log(B)
# examples
0.5 2 - # result is -1.5
8.5 2 * # result is 17
5 3 ^ # result is 125
42_ # result is 3.737...
# Stack Operators: e dyYp ~ n
# TOS is "top of stack", and NOS is "next on stack."
e # identity operator, used for keeping track of stack index when printing the stack.
# executes next instruction as is.
# CANNOT be used to do scientific notation.
d # duplicate: deep copy of TOS.
y # copy: shallow copy TOS. numbers and strings get deep copied.
Y # double copy: shallow copy NOS and TOS, to same relative positions.
p # pop the TOS, i.e., remove it from the stack.
~ # swap the TOS and NOS.
n # push number of elements to stack.
# examples
5 4Y # yields 5 4 5 e4
6n # if nothing else in the stack, yields 6 e1
5d* # yields 25, duplicates 5 and multiplies together.
5y* # same as 5d*
1 2 3~ # yields 1 3 e2
# Statements via Various Parentheses: () [] {}
# All parentheses [] {} () create a statement based on the functions inside;
# A statement acts like a single instruction, but can be composed of multiple instructions.
# The statements () {} and () differ in their behavior, though.
[] # create a normal statement, which acts as one instruction.
{} # create a new stack; any internal instructions push elements to this stack.
# the new stack appears on the old stack as an array element.
() # this statement lowers the stack index without popping the original TOS. (NOS becomes TOS.)
# instructions inside the () will act on the original NOS as if it was the TOS.
# while the stack index is lowered,
# any elements which get pushed to the stack get inserted into the stack,
# and the original TOS gets moved up further.
# the original TOS will reappear at the end of the () statement.
# examples
{1 2 3} # pushes the array {1 2 3} to the stack.
[45.5 33.3] # yields 45.5 e33.3
1 5d(+) # yields 6 e5
# Strings, Print Strings, and Execution Strings: '' "" ``
'' # push a string to the stack.
"" # print string to output.
`` # execute the enclosed instruction.
# this is useful for multi-character instructions, e.g. `function`. (see "Function definitions".)
# `` can also be nested inside a '' or "" string, which executes the instruction inside
# and then pops the TOS to write to that point in the string. YAY for arbitrary code execution!
# examples
"hello world!" # this is the hello world program.
'this is a string' # pushed to stack.
3'what is the TOS? it is `y`.'
# `y` executes and duplicates what is on the stack (3), which gets popped and written into the string.
# Context-dependent Printing: ,;
# The comma and semi-colon are useful for printing the TOS to output,
# though in some circumstances (e.g. check out Matrix Definition) they will do different things.
, # print TOS and pop it, but don't use a newline after printing. (use a space.)
; # print TOS and pop it, appending a newline to the output.
# examples
'hello!'; # prints 'hello!' to output. could also be done with "hello!" (see Print Strings).
1,2,3,4,5; # prints "1 2 3 4 5" to output (newline after 5).
# Comparisons, Logic, and Conditional Branching: <=> ?&| !
< # push NOS < TOS (result is 0 or 1), after popping both.
> # push NOS > TOS (result is 0 or 1), after popping both.
= # check if NOS is equal to TOS (result is 0 or 1), after popping both.
? # push logical value of TOS (either 1 or 0), based on value of TOS.
& # push logical value (0 or 1) of NOS logical-AND TOS, after popping both.
| # push logical value (0 or 1) of NOS logical-OR TOS, after popping both.
! # NOT conditional: branch based on logical value of TOS, and pop it.
# execute first subsequent instruction if TOS was logically zero,
# otherwise execute the second instruction.
# examples
5 3 < # result is e0
4 4 = # result is e1
5 5 > # result is e0
6 0 > # result is e1
123? # stack is 123 e1
0? # stack is 0 e0
3 4& # stack is e1
0 3& # result is e0
3 0| # result is e1
0 0| # result is e0
0!["TOS was zero/null"100]["TOS was non-null"1000]
# end stack result is e100
3 4< !["got not branch (>=)"]["got yes branch (<)"]
# Loop Operators: j k l
# loops use the letters jkl, which are right in a row, and thus easy to remember!
l # loop statement; will loop over the next instruction if the jump operator is hit.
j # jump back to start of loop, or "continue", though this is required for a loop to repeat.
k # kill or quit loop, or "breaK", or kick out of loop prematurely.
# examples
10l[?!k"hello `y`!"1-j] # counts down from 10 to 1, leaves 0 on the stack.
# Function definitions: abc zZ
# Functions are defined with up to three subsequent instructions.
abc # pop the TOS, use a string to define a function name. abc are placeholders for instructions.
# the next instruction is interpreted as the function definition, which can use the placeholder instructions.
z # define a zero-instruction function, popping the TOS for a function name.
Z # define a variable zero-instruction function, popping TOS for a function name.
# i.e., the function can be changed later to something else.
# examples
'w'abl[a!kbj] # create a while loop with two instructions (`ab`);
# the first is executed to check whether to continue the loop, and if so, the second is executed
1 2 3 4 5wn["hi `y`"p]
# the first instruction is `n` (number of elements on stack), the second prints a string and pops the TOS
'H'z0.5 # create a constant variable function (pushes 0.5 to stack)
3H* # yields e1.5
'q'z[0.5^] # create a square root function
9q # yields e3
'inv'z[-1^] # create inverse function
9`inv` # yields e0.1111...
'Q'Z0.25 # create variable zero-instruction function
Q # yields e0.25
'Q'Z[4/] # redefine Q to divide; requires something on TOS
5Q # yields e1.25
# See also "Dictionary definitions" for some advanced function definition uses.
# Dictionary definitions: aa bb cc
# Dictionaries are simply functions with multiple instructions.
# They have their own context for functions.
# examples
'A'aa # create a dictionary A, which is an identity operation.
A['Z'z["hello arizona!"]] # create a subdictionary Z, defined only inside the A context.
AZ # call Z from within an A context, prints "hello arizona!"
'B'Aaa # create subdictionary B
'C'ABz["123"] # create sub-sub-function C
ABC # prints 123
AB['E'z"four score and seven years ago"]
ABE # prints iconic line.
# It can get way more complicated than this, but these are the fundamentals.
# Matrix Definitions: m ,;
# You can build matrices using the `m` command.
# `m` is a loop specification, so you can use the functions `j` and `k` to write the matrix.
m # take two arguments from the stack to get matrix dimensions (NOS for rows, TOS for columns), popping them,
# and execute next instruction to build the matrix.
, # in the instruction after `m`, this pushes the TOS to the matrix.
; # similarly, this pushes the TOS to the matrix, and fills the remainder of the row with zeroes.
# examples
2 2 m[1,0,0,1] # build 2x2 identity matrix.
# note that if the final instruction is to push a number to the stack,
# it will be pushed to the matrix. (i.e., the final 1 did not need a subsequent comma.)
2dm[1;0,1] # equivalent; d duplicates the 2, so the matrix is 2x2.
1 5m[1,2,3,4,5] # create a row vector
0 3dm[1+d,j] # creates a matrix using a loop; loop terminates once last element is written.
# Array/Stack Definitions: {} SP Sp Se
# You can build a new stack using squirrely braces: {'instructions go here'}
# You can think of the new stack as a resizable array, with dynamically-typed elements inside.
# The new stack will appear on your usual stack, and you can manipulate it with the following functions.
S # single-instruction dictionary for stack operations.
Sp # pop from the stack on the TOS, push it to the main stack.
SP # push the element on the TOS to the stack at the NOS.
Se # execute the next instruction using the stack on the TOS as the stack to manipulate.
# as a technical note, the \ context for Se is the root context,
# so that p inside the statement works to pop an element from the stack, rather than executing Sp
# example (run commands sequentially)
{1 2 3 'hello'} # pushes this new stack to the main stack.
Sp # result is {1 2 e3} e'hello' # pops 'hello' from new stack.
' and goodbye!'+SP # pushes 'hello and goodbye' onto the new stack.
Se["My message for you is `y`" # execute these instructions within/for the new stack.
l(n!k;j) # loop through the elements below the string (using the parentheses ()), printing them
] # return control the main stack
It's a bit of practice for some other programming languages I hope to write out someday...
There are probably bugs, and I haven't written in all the features from the README, and I'm not sure I will (at least for the javascript version). I'll probably at least put in random numbers... Feedback and feature requests are welcome, though they won't necessarily be heeded
Thought about putting this in the "Development Section", but it's not really a game or something specific to handheld devices...