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.