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).
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
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.