dschmenk / PLASMA

Proto Language AsSeMbler for All (formerly Apple)
MIT License
189 stars 26 forks source link

Allow more flexibility for headers which only define constants #37

Closed ZornsLemma closed 6 years ago

ZornsLemma commented 6 years ago

This is motivated initially by my Acorn port, but I think it has potential value elsewhere.

To give the specific Acorn port example, inc/cmdsys.plh currently includes lots of Apple-specific constants (memory addresses, etc). I don't mind them being there, that's not a problem. I'd like to add a new file (let's say inc/acornconstants.plh for the sake of argument) which defines similar constants for Acorn machines. This header does not declare any functions (the constants are for use by reading/writing memory addresses or using the standard call() function), so there's no on-disk module to go with it.

But since there's no on-disk module, I can't use an 'import foo' block in inc/acornconstants.plh - it would create a run-time dependency on a 'foo' module, which doesn't exist (and I'd rather not have a dummy module just to work around this). But if I don't have an 'import' block, the include will only succeed if it comes after all other includes, because PLASMA requires that bare constants are defined after all import statements.

To make this more concrete and move away from the Acorn example, let's add a file inc/moreconst.plh to the standard PLASMA repo:

$ cat inc/moreconst.plh 
const foo = $1234
const bar = $5678

and let's use it in samplesrc/hello.pla:

$ cat samplesrc/hello.pla 
include "inc/moreconst.plh"
include "inc/cmdsys.plh"
puts("Hello, world.\n")
puti(foo); putln
done

When we try to build it, it fails:

$ make hello
./plasm -AMOW < samplesrc/hello.pla > samplesrc/hello.a

inc/cmdsys.plh    1: import cmdsys
                     ^
Error: Syntax error
makefile:216: recipe for target 'hello' failed
make: *** [hello] Error 1

If we switch the order of the two includes at the top of hello.pla, it builds fine. But I'd really rather not have to explain to users why this ordering is required, and the error which occurs when you get it wrong is not all that helpful.

One way to handle this would be to simply loosen the ordering constraints imposed by the PLASMA compiler so that 'const' definitions can appear in more places. I don't know how easy that would be.

Another alternative might be to allow 'import' to be used without a module name, like this:

$ cat inc/moreconst.plh
import // note this isn't "import foo", it's a bare "import" statement
    const foo = $1234
    const bar = $5678
end

which would be syntactically like a regular import but creates no dependency on another module.

In the past I worked around this by writing 'import cmdsys', which created a second redundant dependency on the cmdsys module but otherwise had the desired effect. I think a recent-ish version of the compiler started to complain if there were two 'import cmdsys' blocks in the same translation unit, but I just tried this with the latest compiler and it seems to work. I think one of the above solutions would be nicer, but if this use of cmdsys can be officially sanctioned that would be fine too.

I hope this makes sense, I appreciate it's a bit waffly. Let me know if you need any more information.

Cheers.

Steve

dschmenk commented 6 years ago

Steve-

I think the best solution to this is to create a symbolic link to a platform specific cmdsys.plh. I had to do this for the Commodore 64 because the zero page locations just wouldn't work that I used for the Apple. I have the platform specific versions of plvmzp.inc soft-link to the generic version. Any assembly routines compile just fine on each platform, as it's still source compatible. With the cmdsys library, it's meant to export a minimally consistent set of function, but adding platform specific defines and such shouldn't be a problem. Mostly its so that generic libraries and simple applications can be written platform agnostic. We could do the same thing for cmdsys.plh that I did with plvmzp.inc, allowing platform specific extensions to co-exist with a standard defined set of APIs.

I should fix the compiler to allow consts before imports. That should be allowed. import without a module name pretty much defeats the purpose of an import, though.

Let me know what you think of the platform specific cmdsys.plh, and look how I shoe-horned the plvmzp.inc in there. I think there is a much more elegant way to do it than the hack I came up with.

Dave...

ZornsLemma commented 6 years ago

Hi Dave,

Sorry I didn't reply earlier, I wanted to start on updating my port to use the new makefile structure first before I commented. I'm still in the middle of that but it seems to be working pretty well. I might have a few small suggestions but I'll save them until I've done more of my updates.

If you think it's best for cmdsys.plh to contain platform-specific stuff then I'm happy to go with that. My inclination was to try to avoid polluting it with stuff specific to my port, so my port currently has a new cmdsysac.plh containing Acorn-specific stuff and tries to leave cmdsys.plh alone. I had two motivations in terms of avoiding changing cmdsys.plh - firstly, if I added a new symbol it might clash with a symbol used in some existing Apple program which I was trying to port, and secondly that a user would be able to know whether they were using a standard function or something specific to my port.

The constants I mentioned in my message above are not in cmdsys.plh or cmdsysac.plh, because I wanted to try to a) cut down on namespace pollution and b) avoid the time/space overhead of pulling in this potentially quite big set of constants that most programs won't care about (I have the self-hosted compiler in mind here; the cross-compiler won't suffer noticeably from this). If you could fix the compiler to allow consts before imports I would probably prefer to keep these constants in a separate header.

To make this a bit more concrete, you might like to take a look at my 'merge7' branch - this is before I started the current work to switch to the new 'multiple platform' build system, for what it's worth. If you look at https://github.com/ZornsLemma/PLASMA/tree/merge7/src/inc you can see:

I hope this makes sense; I appreciate it hinges in part on the nature of a platform you're not familiar with. Let me know what you think or if you have any questions, of course.

Cheers.

Steve

dschmenk commented 6 years ago

Thanks Steve, I'll start looking things over. I'm still digesting the Commodore 64 differences. I've started a new 'devel' branch which has significant improvements to the VM and code generation. It shouldn't be too much work to integrate the improvements someday - they are all platform agnostic.

dschmenk commented 6 years ago

This should be resolved in the devel branch.