ZeptoBasic

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.
 * Identifiers, any other series of non-whitespace characters. (These are valid variable names.)

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 > 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 = labels[l[4]] 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 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'
 * 1) The tape size can be adjusted here; by default, it's 300.