I'm writing my text adventure scripting language again. I've been through this project about five times already in the past so am flying along at the moment. I've got global variables and arrays working and function calls without parameters yet.
Inside functions, global variable assignments, maths and printing operations are now working, as well as return statements.
Arbitrarily complex math expressions are also now up and running - both compile time and run time and the virtual machine is being developed in parrellel with the compiler.
Now need to go and get array values working inside functions then look at function parameters (by value and by reference) and local variables.
[LATER] Reference and value function parameters now working, as well as function overloading. Local variables up and running as well. Forgot to support const for everything at the start and was a bit of a pain going back over and implementing it as an afterthought but I guess that is just poor planning for you.
For consitency, it supports const returns from functions and const reference parameters but these are the most pointless features in a programming language ever since functions can only return by value and, since every variable is four bytes large, there is no real difference between a const reference parameter and a const by-value parameter.
Arrays can only be globals in this language. I'm going to implement static local variables next and I'm pretty sure it will be effortless to have local static arrays since the compiler is just going to pass back control to the routines that parse declaring global variables, but rely on the fact that the symbol table stack is in the function scope to keep the static variable scope local.
It is generating rather bloated byte-code for accessing array values since it is using the math stack to calculate the addresses so I might add some array specific instructions to the vm to pare this down a bit.
However, the following program:
x(int &a){ a=a-10;}int b[3]={ 20,30,40 };main(){ out b[1],end; x(b[1]); out b[1],end;}
produces the following output from the dissassembler
ds: 135ts: 147ss: 148program: 0: setax 40 5: call 6: mpop 7: end 8: peek 0 13: movar 14: get 15: mpush 16: setrx 10 21: mpush 22: sub 23: peek 0 28: movar 29: mpop 30: put 31: mpush 32: mpop 33: setrx 0 38: mpush 39: ret 40: setrx 1 45: mpush 46: setrx 4 51: mpush 52: mul 53: setrx 0 58: mpush 59: add 60: mpop 61: movar 62: get 63: mpush 64: mpop 65: outn 66: outnl 67: setrx 1 72: mpush 73: setrx 4 78: mpush 79: mul 80: setrx 0 85: mpush 86: add 87: mpop 88: push 89: setax 8 94: call 95: popn 4 100: mpop 101: setrx 1 106: mpush 107: setrx 4 112: mpush 113: mul 114: setrx 0 119: mpush 120: add 121: mpop 122: movar 123: get 124: mpush 125: mpop 126: outn 127: outnl 128: setrx 0 133: mpush 134: ret data: 0: 20 4: 30 8: 40text: 0: ""
and the expected output when run with the vm. Not exactly an optimising compiler, but I don't care.