SMITH#
After the success of Microsofts C#, which is a extension of C++, I thought it befitting to do something similar to one of the most fun-to-write languages on the planet: SMITH. SMITH is widely used mainly because it does away completely with GOTOs, LOOPs and all that, making LOOP design very simple: there are none. (This is not quite true, but remember: when C# says it does not have pointers, this is not quite true, either).
Outstanding Features!
SMITH# relies entirely on code self modification to perform profane things such as loops and recursion. That much was already implemented in SMITH. However, SMITH# provides many extensions that make programming even more easier, by providing things such as:
- Alternate keywords to suit your moods. For example, if you hesitate typing "+" for religious reasons (it reminds you of a rare christian symbol) you can just type "add" instead.
- SMITH# does not discriminate between data and code. Generally speaking, discrimination is almost always a bad thing ! More specifically, SMITH# does away with registers.
- SMITH# does not discriminate between relative and absolute addressing, there is only absolute addressing. For convenience, you can do absolute indirect addressing, if you insist. [The PC-relative addressing in SMITH went against the fundamental design principles of SMITH, in my mind]
- SMITH# does not use "immediates". Why use something else, when you have absolute addressing to fit all your needs ? I think, the use of immediates in SMITH just made that language too complicated for the average programmer.
- SMITH# is a freeform language, that is very easy to obfuscate, so as to make training for the IOCCC possible.
- SMITH# introductes the concept of citing, which has been around in theoretical papers for a long time, but to my knowledge has never been used in a programming language of considerable scale before.
- The instruction set has been at the same time reduced and expanded: basically, it is a whole different opcode set compared with plain SMITH#, but, once again, the situation reminds one of C#.
- Support for OPP.
Now that I got you wet for SMITH#, here is a documented version of Hello World in SMITH#:
; string declaration
cite "Hello, World"
; helper variables
a: cite 0
b: cite 1
c: cite 2
e: cite eval(stop)
f: cite eval(h-g)
i: cite 1
j: cite eval(g)
l: cite eval(k+2-h+g)
m: cite eval(d)
; copy current character to the variable a
g: copy 1,a,b
; evaluate: a = ( a == 0 ) ? b : 0;
norm =,a,b
; if a was 0, a stop instruction will be copied to m-indirect.
; m defaults to label d; and will be increased by the total
; codesize once the code gets duplicated
copy e,^m,a
; output current character
d: output 1
; i is the read position, and it is increased by two, because
; every "cite" instruction takes up two cells, so i now points
; to the next character
add c,i
; patch code originating from labels g/d (the "current characters")
copy i,g,b
copy i,d,b
; correct helper variables by whole code size
add f,j
add f,m
add f,l
; l "points" to the second argument of the next copy instruction
; and is replaced by the actual new PC position [just corrected]
copy j,^l,b
; copy whole code to next instruction
k: copy eval(g),0,f
h:
""Hello, World"a:"0b:"<>c:"?(:=)e:"?(.)f:"?(h-g)i:"1j:
"?(g)l:"?(k+2-h+g)m:"?(d)g::=<>,a,b@=,a,b:=e,^m,a d:
<<1+c,i:=i,g,b:=i,d,b+f,j+f,m+f,l:=j,^l,b k::=?(g),=,f
h:+a,b
Yes! both are valid SMITH# code, and both implement the same basic functionallity. Great, eh ?! Here is a documented fibonacci code:
; FIBONACCI in SMITH# !!!
; INPUT: Variable a
; OUTPUT: Variable e
; Results should look somewhat like this:
; 1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765
a: cite 10
e: cite 1
; handle the "a<2" case
sub a,g
norm >,g,d
copy h,eval(b),g
b: cite 0
c: cite 0
d: cite 1
f: cite 0
g: cite 2
h: cite stop
i: cite 1
j: cite 0
l: cite eval(k) ; must be corrected
o: cite eval(n-(n-m)) ; target position
p: cite eval(n-m) ; codesize
copy a,b,i ; b = a-1
sub i,b
; the next 4 lines implement the "while(c<b)" logic.
; if c is >= b, then stop
m: copy b,j,i
sub c,j
norm <=,j,i
copy h,^l,j
k: copy e,f,i ; f = e + d
add d,f
copy e,d,i ; d = e
copy f,e,i ; e = f
add i,c ; c += 1
add p,o ; correct code positions
add p,l
copy eval(m),^o,p ; duplicate loop code
n:
and again, the runtime optimized version:
a:<>10>=a,g;p:<>?(n-m)<f,e,i<=i,c<=p,o<=p
e:"1@>,g,d;"1@>,g"1@>,g(n-m)<f,e,i<=-<=>3
b:<>0<h,?(b),g;c-&~3b:<>0<h,?(b),g-?(b),g
c:"0<a,b,i;?(d+2*a)-d:<>1>=i,b"1@>,g,d;"1
d:<>1>=i,b;m)<e,d,i;b:<>0<h,?(b),g?(n-d:<
f:"0; k::=?(g),=,f(n-m)<f,e,i<="a:"0b:"<>
m:<b,j,i;b@=,a,b:<>0<h,?(b),g>1>=i,bc:"?.
g:<>2>=c,j;<>2>=c,j(n-m)<f,e,i<=h+g)mb:"<
h:"=@<=,j,i;,g,b:=i,d,b+f,j+f,m+f,l:g&~1=
i:<>1<h,^l,j;<<1+c,i:=i,g,b:b:<>0<h,?(b),
j:"0;b:<>0<h,?(b),g<>2>=c,j"?(g)l:"?(k+2-
k:<e,f,i;:"?(d)g::=<>,a,b@=,a,b:=e,b k::@
l:<>?(k)<=d,f;l:<>?(k)<=d,f b:<>0<h,?(b),
o:"?(m)<e,d,i;b:<>0<h,?(b),g?(n-m)<f,e,i<
p:<>?(n-m)<f,e,i<=i,c<=p,o<=p,l<?(m),^o,p
n:"0
Download
SMITH# has a BSD-style license.
- You can download the full SMITH# distribution, which includes both Win32 binaries and sourcecode, from here.
- You can download the full SMITH# distribution for Linux here.
- You can download the distribution for the AMIGA here. (Tested with WinUAE only, comments welcome). Note that the binary had to be renamed to "smith", because # is a wildcard token on the Amiga.