Fob

From Esolang
Jump to navigation Jump to search

Fob was created by Tslil Clingman, aka Hiato, in early 2010 and represented the author's wishes for a stack based, modal, argument-less-syntax and slightly obfuscated language. It came about as the product of many proto-esolangs horribly mutilated and then joined together in a haphazard manner.

Language Overview and Syntax

Fob is unique (or so the author believes) in that it combines a stack with a psuedo-asm accumulator. This has the effect of allowing the language to accommodate 'modes' viz., execution mode and accumulator mode. In execution mode (the default initial mode), every symbol is interpreted as a command and, if valid, immediately executed. If the symbol is not a command, it is interpreted as a comment and not parsed. In accumulator mode, every symbol is concatenated onto the accumulator. There is only one form of control structure. In order to loop, programmes must be quines or well designed state machines as the only available command to this end is to restart the programme. When restarting a programme, the stack and accumulator are persistent. As no instruction receives any arguments, this further allows the language to implement a second layer of silliness by allowing arbitrary strings to be interpreted as code. Notably missing from Fob is a means of input.

$ accumulator mode
# execution mode
: escape character (works as you may think)
< push to stack from accumulator
> pop from stack to standard output
. swap top two stack elements
/ rotate stack up
& wipe accumulator
% pop from stack to accumulator
= execute accumulator
? if acc=="", pop from the stack and disregard that element
@ restart programme (persistent stack and accumulator)

NOTE: When the accumulator is executed as code, the stack and accumulator remain as they were, with any changes being propagated back to the parent code. See implementation for details.

The question of Turing Completeness

The author is fairly confident in Fob being TC, in that through some clever encoding, it ought to be possible to simulate an arbitrary cyclic tag system. The author envisages the encoding as follows:

Consider an m-tag system, with alphabet {s0...sn} and transforms {t0...tn}. In order to simulate the system, each symbol needs to be encoded as a programme in fob that when read, and executed, will: insert a blank entry where it resided in the stack; delete m consecutive symbols (stack entries) adjacent to it; cycle forwards until the next blank entry (this seems to demand that the programme either contain a quine for the looping placing itself in the correct block and loading itself, or have a state system set up, and executes as an accumulator programme) at which point, cycle forwards K more entries, where K is the number of the transform for that symbol; load that transform programme. The transform programme will then cycle forward (by the same means, or otherwise) to the next blnak stack entry (as left by the symbol programme); insert the new symbol programme where the old one resided and pass execution to it.

Thus, visually, the layout on the stack might be:

 <Symbol A>
 <Symbol B>
 <Symbol C>
 <Blank entry>
 <Transform A>
 <Transform B>
 <Transform C>

Example code

The canonical Hello World:

 $Hello, World#<>
 $:#&$Hello, World!:#<>#= This version uses more interesting features

Powers of two, expressed as a tally:

 $:#&$1:#<<>&#<.&$:#.%&%<%<<>&#<.&%?<.&%=@

The first quine created in Fob (which may ultimately prove it's TC, thus proving the existence of arbitrarily many more), weighing in at 135 characters:

 $$#<&$::#<&$:#<&#<&$:#<=#<&$&//%<//<.&%<<%.%<&>/////%<<%.<&.%<.%/////<&.%<<&/.%%<&>%</%<////<&.%<<%/<&.%%<&>/%//<&.%<</&.%%%<&>>/>>#<=

Reference Implementation (in Python)

 def run(c,acc,stack):
 	s,a,e,l,re,o=stack,acc,True,False,False,""
 	print "Run: ",c
 	for t in c:
 		if not e:
 			if not l:
 				if t=='#': e=True
 				elif t==':': l=True
 				else: a+=t
 			else: a,l=a+t,False
 		else:
 			if t=='$': e=False
 			else:
 				if t=='<': s=[a]+s
 				elif t=='>': print "Output: ",s[0]; o+=s[0]; s=s[1:]
 				elif t=='&': a=""
 				elif t=='.': s[0],s[1]=s[1],s[0]
 				elif t=='%': a,s=a+s[0],s[1:]
 				elif t=='/': s=s[1:]+[s[0]]
 				elif t=='?':
 					if a=="": s=s[1:]
 				elif t=='=':
 					p=run(a,a,s)
 					a,s=p[0],p[1]
 					print "Back: ",c
 				elif t=='@': re=True; break
 		print a,s
 	if re: run(c,a,s)
 	else: 
 		if o!="": print "Output: ",o
 		return [a,s]
 run(raw_input("Code: "),"",[""])