anachronauts / jeff65

a compiler targeting the Commodore 64 with gold-syntax
GNU General Public License v3.0
6 stars 0 forks source link

Hello world program #52

Open jdpage opened 6 years ago

jdpage commented 6 years ago

Just to make the goal clear for the "Hello world!" milestone, here's the test program:

use kernal

fun print(text: &[u8])
  for c: u8 in text do
    kernal.chrout(c)
  end
endfun

fun main()
  print("hello, world!\n")
endfun

Original commentary:

So, what's interesting here? Well, we have some basic control flow, a function call, all good. We have a slice. Additionally, we have a KERNAL call. KERNAL calls have "weird" (in jeff65 terms) calling conventions, so this could (provisionally) be done in a few ways:

  1. kernal.chrout is a real, honest-to-god linker symbol with type fun(u8), value 0xffd2, and an associated calling convention.
  2. kernal.chrout is a compiler intrinsic which emits the appropriate assembly directly.
  3. kernal.chrout is a real function implemented in assembly which puts its argument in the A register and then does jsr $ffd2.

Each of this is interesting in a different way. Doing 1 right out of the gate means that we ensure that our code generation for function calls isn't hard-coded to a particular convention, but means we have to support two of them. Doing 2 might just be a bad idea--my gut feeling is that that's not really what compiler intrinsics are for. Doing 3 means that we implement the ability to (a) load the symbol table from referenced units and use it, and (b) link multiple units together. (I think technically we can already do that last thing, but there's no support for it in the command-line driver.)

Obviously 1 is the "correct" way to do it long-term, but 3 is good enough for now I think.

For bonus points, implement an "improvement" pass (NFCE terminology) which notices that the range variable c is only used as a function argument, and loads it directly into the argument slot for the kernal.chrout function.

jdpage commented 6 years ago

An alternative program would be:

use console
fun main()
  console.print("hello, world!\n")
endfun

Where console.print is implemented directly in assembly. This means that we don't implement any control flow, though.

jdpage commented 6 years ago

Woody, I've assigned this to you to review. Once we've decided on the actual goal, you can either assign it back to me to create the issues, or do it yourself, and then either hang onto the issue or un-assign it.