ZeptoBasic
Jump to navigation
Jump to search
ZeptoBasic is a minimal BASIC clone, built on top of Python, designed by User:nooodl in December 2012.
Language overview
ZeptoBasic programs are a sequence of commands, separated by newlines. There are two datatypes in ZeptoBasic: numbers and strings.
ZeptoBasic commands are tokenized into:
- String values, surrounded by double quotes.
- Numbers, non-string tokens matching
-?[0-9]*
. - Identifiers, any other series of non-whitespace characters. (These are valid variable names.)
Instructions
Command | Description |
---|---|
label name
|
Mark a label, name, on this line. |
goto name
|
Jump to the label name. |
set var value
|
Set var to value, which is either a string or a number. |
print var
|
Prints var, followed by a newline. |
input var prompt
|
Ask for a value to be placed in var, prompting with prompt, a string. |
if v1 cmp v2 label
|
Evaluates v1 and v2, and compares them using cmp, which is one of lt , le , eq , ne , gt , ge .
|
get var a vind
|
Evaluates the value vind, then sets var to the variable a.(x) , where (x) is replaced by the value of vind.
|
put a vind vnew
|
Stores the value of vnew into the variable a.(x) , where (x) is replaced by the value of vind.
|
op var v
|
Sets var to the value of applying op to var and v, where op is one of add (addition), sub (subtraction), mul (multiplication), div (division), mod (modulo), pow (power).
Adding two strings concatenates them; multiplying a string by a number repeats it. |
Examples
Hello World
print "Hello, world!"
Factorial
input n "Number to calculate n! of: " set acc 1 label loop mul acc n sub n 1 if n gt 0 loop print acc
Arrays
put a 0 65 put a 1 34 put a 2 86 put a 3 15 put a 4 91 set i 0 label loop get j a i mul j j print j add i 1 if i lt 5 loop
Implementation
The original implementation by User:nooodl, in Python:
import re, operator, sys ops = operator.__dict__ code = map(re.compile(r'"[^"]*"|\S+').findall, sys.stdin.read().split('\n')) labels, vs, pc = {}, {}, 0 def v(s): if s[0] == '"': return s[1:-1] elif s[0] in '-0123456789': return int(s) return vs[s] while pc < len(code): l = code[pc] if l == [] or l[0] == 'label': pass elif l[0] == 'goto': pc = [x == ['label', l[1]] for x in code].index(True) elif l[0] == 'set': vs[l[1]] = v(l[2]) elif l[0] == 'print': print v(l[1]) elif l[0] == 'input': vs[l[1]] = v(raw_input(v(l[2]))) elif l[0] == 'if': if ops[l[2]](v(l[1]), v(l[3])): pc = [x == ['label', l[4]] for x in code].index(True) elif l[0] == 'get': vs[l[1]] = vs[l[2] + '.' + str(v(l[3]))] elif l[0] == 'put': vs[l[1] + '.' + str(v(l[2]))] = v(l[3]) else: vs[l[1]] = ops[l[0]](vs[l[1]], v(l[2])) pc += 1
Computation class
ZeptoBasic is Turing-complete; the following Python program converts a brainfuck program to ZeptoBasic:
import sys code = sys.stdin.read() # The tape size can be adjusted here; by default, it's 300. print '''\ set p 0 set i 299 label setup put tape i 0 sub i 1 if i ge 0 setup ''' li = 0 lstack = [] for i in code: if i == '+': print 'get a tape p' print 'add a 1' print 'mod a 256' print 'put tape p a' if i == '-': print 'get a tape p' print 'sub a 1' print 'mod a 256' print 'put tape p a' if i == '>': print 'add p 1' print 'mod p 256' if i == '<': print 'sub p 1' print 'mod p 256' if i == '[': print 'label start{0}'.format(li) print 'get a tape p' print 'if a eq 0 end{0}'.format(li) lstack.append(li) li += 1 if i == ']': lp = lstack.pop() print 'get a tape p' print 'if a ne 0 start{0}'.format(lp) print 'label end{0}'.format(lp) if i == ',': print 'input a ""' print 'mod a 256' print 'put tape p a' if i == '.': print 'get a tape p' print 'print a'