Dead Simple Language
====================
This is a dead simple language written in hare.
The only goal is to be a learning project and
have fun as learn, and maybe end up with a usefull tool.
========================================================
Licensed under GPL-3.0 or later
I wanted a simple language, but compiled.
I wanted something i can use comfortably.
Something I would have no problems with and enjoy.
Then I found it, Hare.
I then thought, why not write a language in hare, as I cannot think of real projects to do.
After i did some hours work on an interpreter, and the language itself i came to think about the back-end, QBE.
This is from their website:
QBE is a compiler backend that aims to provide 70% of the performance of industrial optimizing compilers in 10% of the code. QBE fosters language innovation by offering a compact user-friendly and performant backend. The size limit constrains QBE to focus on the essential and prevents embarking on a never-ending path of diminishing returns. So from this is looks quite good, if we take their words on it.
I then started to look at it [or, i saw a tsoding stream on it as i googled QBE].
It looked quite good [and a lot easier than llvm ir], so i started.
I started with just figuring out how to reliably have a stack, and mixing hare and qbe, while no actual data evaluation and results will be in hare, but rather just qbe .ssa source code generation.
So far this is implemented, may be missing one thing or two, but i think its most of it:
// [MATH]
// x y - => x - y | subtraction
// x y + => x + y | addition
// x y * => x * y | multiplication
// x y / => x / y | division
// [COMPARASON & CONDITIONALS & SIMULAR]
// x y = => x = y | equal
// x y != => x != y | not equal
// x ! => x xor 1 | not [or rather, xor 1]
// x y xor => x xor y | xor x with y
// x y > => x > y | greater than
// x y < => x < y | less than
// x y >= => x >= y | greater than or equal
// x y <= => x <= y | less than or equal
// [STACK]
// x drop => | removes top item of stack
// x y swap => y x | swaps the two top items of the stack
// x dup => x x | duplicate the top stack item
// 1 2 3 over => 3 1 2 | moves top two slots back
// [FUNCTIONS, VARIABLES, ...]
// x print => print(x) | print, sprint prints string [!... one place before]
// \n, \_ | \n puts('\n'), \_ puts(' ')
// -x goto => goto x | goto label. label made with :x where x is label
// y -x goif => if(y)goto x | if x is not 0 goto x
// x !var => var = x | saves x to var name
// x? => dup = x | gets x [varname] to top of stack
// x y fn => fn y(x) | makes function with name y and argname x
// x ret/iret => return x | ret returns 0 close block, iret converts to int and retSo thats it so far.
To end off is an example DeadSimple source code block:
!fun fn
11 print
5 ret
:start
$fun
\n !simple_math sprint \_
10 5 - 3 + 8 - 84 * 3 / print
11 11 <= print
1 0 != print
\n !goto sprint \_
5 !x save
-here goto
:here
55 print
?x 1 - dup !x save
-here goif
:end
\n !Hello, sprint \_ !World! sprint
1.5 1 + print \n
0 iretThis makes a simple function named fun:
!fun fn
11 print
5 retThis makes a variable x and a label here then subtracts 1 from x and if x is equal to zero don't goto
5 !x save
-here goto
:here
55 print
?x 1 - dup !x save
-here goifgoif jumps to label is nonzero value is on top of the stack before the goif and label-name.
Lastly 0 iret returns and exits block with 0, and iret to return an integer, so the return code isn't converted weirdly from float to int.
It is over at sourcehut [testing, like it so far].