-
Ubiquitous libc
03/17/2019 at 02:20 • 2 commentsLibc Functions
As I parse the "self compiling" compiler I see just how ubiquitous "libc" is.
But I think I the "atomic" functions are:
- fgetc()
- fputc()
- feof()
- malloc()
- free()
Actually I only need a memory pointer to the "heap" for malloc() and free().
"feof()" makes the list as I need to know when input (serial) data is available.
I have actually coded in ActsL most of the functions I need:
- itoa() (no division used)
- getchar()
- putchar
- puts()
- gets()
- fputs()
- fgets()
- strcat()
- strcmp()
- strchr()
- strcpy()
- strlen()
- and others
Still more to code.
The ubiquitous fprintf()
"fprintf()" is a complex and large procedure for a simple compiler.
As the arguments are variable, the count needs to be given to the function in some manner. Perhaps a global variable for the argument count or a NULL delimiter on the stack.
Better to use fputs() and construct a string using strcpy(), strcat() and itoa().
Looking Forward
I was contemplating my TTA8 as a target (when I get it working!).
The memory page size is limited to 64 bytes but I have up to 255 pages. So it is doable.
I now have the "p code" (i.e CodeGen.h) specification for the CPU interpreter the emulate.
AlanX
-
Acts Language Elements
03/15/2019 at 08:31 • 0 commentsThe Acts Language Elements
Tarvo's original language specifications was:
- + - * / %
- & | ^ << >>
- == != < <= > >=
- deref <variable>
- =
- quoted string literals (i.e. "...")
- C style comments (i.e. /* ... */ and // ... \n)
- int <variable>
- ref <variable>
- <expression> arg <expression> arg ... call <functionname>
- fun <functionname> <statements> endfun
- <expression> return
- if <expression> then <statements> endif
- while <expression> do <statements> endwhile
- continue
- break
So pretty complete, actually his "actsl.a" program self compiles.
Hello World!
Here is the "Hello World!" program in ActsL:
int rtn int nul int buff fun init ref rtn ref nul = // Make null point to nulv (i.e. nul=&nulv) 32 arg call malloc ref buff = // Create a buffer (buff) for your string 0 return endfun fun PutStr buff arg call puts nul = // Print the buffer (buff) 0 return endfun fun main call init nul = // Initialise variables /* Copy "Hello World!" into a buffer (buff) */ "Hello World!" arg buff arg call strcpy nul = call PutStr nul = // Call print string 0 return // Return okay endfun
Okay, its a bit more complicated than it has to be but it show the language elements.
Another Code Example
An example of "his" code (although I have played a bit with it!), first in C:
void error (char *text) { printf ("%s:%d: %s\n", infile, line, text); exit (1); }
Now in ActsL:
fun error buff arg line arg infile arg "%s:%d: %s\n" arg call printf nul = 1 arg call exit nul = endfun
In his ActsL code he has use "buff" instead of "text" (not important), but he fails to use a return statement (a bit lazy and it cost me time to work this out!), and "nul" has been assigned the address of "nulv" during the initialisation (otherwise he should have used "ref nul =" and not "nul =").
Note, if your not careful with assignment (i.e. "="), it is very easy to generate a segment fault and no idea where the code error is!
Finally you will see he uses "printf()" and "exit()" from "libc". So even though his code self compiles, you need to be aware that it still uses libc.
Missing Language Elements
Although he can set arguments (i.e. "arg") for a call, an ActsL function (i.e. "fun"/"endfun") can not read then. Therefore I add:
- <expression> param
Here is an example of its use:
... fun test1 1 param return endfun ... 98 arg 99 arg call test1 nul = rtn arg "\nReturn %d\n" arg call printf nul = ...
"fun test1" was called with two arguments (98 and 99), the first parameter (=99) was returned.
Next, I added "else" to the set of commands.
Next, I added "// .. '\n'" comments to the set of commands (I like having both).
Finally, I tokenised "halt" when the EOF is found.
And I nearly forgot, added support for "_" in names and negative integers.
Final Notes
All variables are global. This is a bit of a pain, so I use lower case for code and will use upper case for library code.
And if you have not worked out, delimiters are white spaces (i.e. " \t\n").
As I intend to port the code to one of my home brew CPUs, I will not have the luxury of access to libc. I have made a start on this.
AlanX