sd:tinyc_developer_diary
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| sd:tinyc_developer_diary [2026/04/19 14:41] – appledog | sd:tinyc_developer_diary [2026/04/22 17:14] (current) – appledog | ||
|---|---|---|---|
| Line 813: | Line 813: | ||
| Now I know this sounds simple when I lay it out, but this took me 10 hours to fix. It's just a classic clobber-bug but it's a sign this code is starting to weigh me down. I just want to write some games. I don't understand why this has to be so hard. But even after all this I am pretty sure it is easier than writing a GCC or LLVM back end. | Now I know this sounds simple when I lay it out, but this took me 10 hours to fix. It's just a classic clobber-bug but it's a sign this code is starting to weigh me down. I just want to write some games. I don't understand why this has to be so hard. But even after all this I am pretty sure it is easier than writing a GCC or LLVM back end. | ||
| + | |||
| + | == Everything in bank 0! | ||
| + | I was such a fool to make the symbol table 16 bit. Now everything has to be in bank 0. But there' | ||
| + | |||
| + | I have a plan. What if we put the output ~2k before the source code? The tokenizer and other things seem to output less bytes than source code, so it should work. | ||
| + | |||
| + | So if HERE grows into the source area as source gets consumed, we can theoretically use up to 48KB for source code AND compiled code. This requires HERE to stay behind SRC at all times. It destroys the code as it compiles, but that's okay. The two pointers march through the memory, with HERE chasing SRC. The only problem is if the emitter somehow catches up with the source code pointer. | ||
| + | |||
| + | At this point I am very close to just rewriting the symbol table to be 32 bit. I mean this is already an insane asylum as it is, but, how hard could rewriting the emitters possibly be? :) | ||
| + | |||
| + | == Rewriting the symbol table | ||
| + | Unfortunately the symbol table had to be rewritten and all the emitters. This is not as bad as it sounds but it required a complete review. The good thing is I had a register map, where I used certain registers for certain things as a convention, or this would have been impossible. I will be sure to mention register conventions/ | ||
| + | |||
| + | 1. In every place where the symbol table was written or read, make sure a pointer (GLK) is used. Previously, A was used for this. This wasn't too bad because sym is a marker for symbol table functions. | ||
| + | |||
| + | 2. In parse function, emit_call, anything to do with backpatching, | ||
| + | |||
| + | 3. Anything which touches HERE or offset 18 of the symbol table. This is an easy search for ex. LDA [@HERE]. | ||
| + | |||
| + | It took a couple of hours. As I ran through various tests it struck me that there are a series of tests I went through a couple of times before to verify things work. As I ran through them again I had the insight to write them down. | ||
| + | |||
| + | === TinyC Test programs | ||
| + | These provide the test cases I used to check my compiler. In order. | ||
| + | |||
| + | ==== First | ||
| + | < | ||
| + | int main(void) { return 0; } | ||
| + | </ | ||
| + | |||
| + | ==== Symbol table | ||
| + | < | ||
| + | int main(void) { int a = 5; return a; } | ||
| + | </ | ||
| + | |||
| + | 24 bit: | ||
| + | < | ||
| + | .clear | ||
| + | int main(void) { | ||
| + | int a = 0x123456; | ||
| + | return a; | ||
| + | } | ||
| + | .compile | ||
| + | .run | ||
| + | </ | ||
| + | |||
| + | ==== Globals | ||
| + | We can't define them when we make them. It seems like I did something wrong here but I don't know how to fix it. Just define them in main. Whoop de doo. | ||
| + | |||
| + | < | ||
| + | int g; | ||
| + | int main(void) { | ||
| + | g = 42; | ||
| + | return g; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== function call | ||
| + | < | ||
| + | int a(int x) { return x + 1; } | ||
| + | int main(void) { return a(41); } | ||
| + | </ | ||
| + | |||
| + | two arguments: | ||
| + | |||
| + | < | ||
| + | .clear | ||
| + | int add(int a, int b) { return a + b; } | ||
| + | int main(void) { return add(20, 22); } | ||
| + | .compile | ||
| + | .run | ||
| + | </ | ||
| + | |||
| + | ==== Forward Declarations | ||
| + | Single | ||
| + | |||
| + | < | ||
| + | int a(int x); | ||
| + | int main(void) { return a(41); } | ||
| + | int helper(int x) { return x + 1; } | ||
| + | </ | ||
| + | |||
| + | multiple | ||
| + | |||
| + | < | ||
| + | int a(); | ||
| + | int main(void) { | ||
| + | return a() + a(); | ||
| + | } | ||
| + | int a() { return 5; } | ||
| + | </ | ||
| + | |||
| + | ==== Recursion | ||
| + | < | ||
| + | int even(int n); | ||
| + | int odd(int n); | ||
| + | int even(int n) { if (n == 0) { return 1; } return odd(n - 1); } | ||
| + | int odd(int n) { if (n == 0) { return 0; } return even(n - 1); } | ||
| + | int main(void) { return even(10); } | ||
| + | </ | ||
| + | |||
| + | ==== Built-in functions | ||
| + | < | ||
| + | int main(void) { | ||
| + | putchar(' | ||
| + | putchar(' | ||
| + | return 0; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | === Re-wiring pointers | ||
| + | Unfortunately the changes were far more in depth than I expected, and I had to spend an additional ten hours going over the code to fix pointers, the lexer, and everything in between. Oh, and yet more emitters I forgot needed to be changed. Even the REPL itself didn't print out the full return value. This makes me reconsider my choice to go with a 16 bit system. Should the SD-8516 have been 32 bit? Maybe, maybe not. In the end, it works. A 16 bit system can run a 32 bit c, no problem. I mean, look at Commodore BASIC 2.0. It used floats for ints. Steve Wozniak even made a Sweet-16 so that it could use 16 bit registers. We can do 32 bit in the languages. No problem. We are not going to get any practical advantage from going 32 bit internal since we're running on WASM which is 64 bit native anyways. See? We can have our cake and eat it too here. | ||
sd/tinyc_developer_diary.1776609673.txt.gz · Last modified: by appledog
