ComeFrom2

From Esolang
Jump to navigation Jump to search

ComeFrom 2 is a language that explores the implications of the only flow control in a program being 'come from x' and 'conditionally, come from x'. It is the successor to ComeFrom. The rest of the language is quite simple, consisting only of a handful of functions and two stacks. It features advanced debugging capabilities, actually telling you where the error was and what caused it.

ComeFrom is an esoteric programming language designed by David Roberts in 2012. He revisited it in 2015 using Javascript after Cube Trains, which housed with its original implementation, was found to be an esoteric game.

Running

A web IDE is available at the CFL2 github page. Be sure to check out the manual there!

Syntax

+, -, *, /, % Infix operators. Add, subtract, multiply, divide, or take the modulo of the next number to be pushed to the stack with the number currently on the stack. Only addition works with strings, concatenating them.
<, =, > Infix operators. Compare the number currently on the stack with the next to be put on the stack, returning 1 if the assertion was true and 0 if not.
^ Infix operator. Raise the number on the stack to the power of the next number to be put on the stack.
calljs Call a javascript function. For example, take the stack ['Enter your password:', 1, 'prompt<window']. When calljs is executed it will prompt the user to enter their password and put the result on the stack. The newest value on the stack is the name of the function to call. eg; 'prompt<window' calls Javascript's window.prompt function. The number indicates the arity of the function, and then pops that many variables off the stack to feed to the function. A value which is not a number, boolean, or string is interpreted as nil. See also: readjs
comefrom Come from a line number to this line.
comefromif Comes from a line number to this line, IF the top value on the stack is truthy. The value is not removed from stack. Truthy values are anything other than #0, $, nul, or the empty stack.
depth Puts the size of the stack prior to the instruction to the stack.
drop Removes the first value on the stack.
dup Takes the first value on the stack and adds it to the stack twice, duplicating it.
log Pop a value to stack, and print it to the javascript console. See also: print, println
nop Take no action. Very easy to implement!
not Logically negate the first value on the stack. (In CFL, truthy values are anything other than #0, $, or nul.)
num Cast the top value on the stack to a number. See also: str
print Print and remove the top value of the stack. See also: log, println
println Print and remove the top value of the stack. Advance the cursor to a new line. See also: log, print
reach Reach back in the stack, read a value, and push the read value to the stack. Does not remove the read value. 10 #5, 20 #1, 30 reach is equivalent to 10 #5, 20 dup.
readjs Read a javascript value as given by the js path string on top of the stack. For example, to read Math.PI, we'd push $PI<Math to the stack and then invoke readjs. See also: calljs
str Cast the top value on the stack to a string. See also: num
swap Reverse the position of the top two values on the stack.

Counting to 10

With annotated source!

Line Number Instruction Annotation
10 #0 Push zero to the stack. This is the number we start counting from.
20 comefrom 120 Come from line 120. This kicks off the next increment loop.
30 +
40 #1 Increment by one.
50 dup
55 dup Duplicate the incremented number twice. There are now three versions of what we just incremented, instead of one.
60 <
70 #10 The first version is compared with 10, resulting in a boolean value on stack. Line 100 comes from here if the duplicated value is less than 10, continuing the loop. (Line 90 would have lead to line 130 otherwise, skipping the comefrom on line 20.)
80 drop Drop the comparison, no longer important as we've exited the loop.
100 comefromif 75 Jump over the line 130 comefrom and the line 80 drop to continue the loop.
120 drop Drop the comparison, no longer important as we're continuing the loop.
130 comefrom 90 Come from line 90 to skip the line 20 comefrom on line 120, if the line 100 comefromif didn't happen.
145 drop Drop the second version of the number, which would otherwise have been incremented on the next loop. This leaves us with a clean stack listing #1 to #10.

99 Bottles of Beer

 0 !99 Bottles v1.0.0
 10 #99
 19 nul
 20 comefromif 205
 21 drop
 30 dup
 40 str
 45 dup
 50 + 
 60 $ bottles of beer on the wall,,
 70 println
 80 +
 90 $ bottles of beer.\nTake one down,, pass it around,,
 100 println
 120 -
 130 #1
 140 dup
 145 swap
 150 str
 155 +
 160 $ bottles of beer on the wall.\n
 170 println
 180 dup
 190 >
 200 #2
 215 $1 bottle of beer on the wall,,\n1 bottle of beer.
 214 $Take one down,, pass it around,,\nno more bottles of beer on the wall.\n
 213 $No more bottles of beer on the wall,,\nno more bottles of beer.
 212 $Go to the store,, buy some more,,
 211 $99 bottles of beer on the wall.\n
 210 $... oh fine I'll stop now.
 218 !loop until we've printed the entire stack we just filled
 219 comefromif 220
 220 println

External resources