starting to implement register allocation by first creating SA
Single Assignment means a register is only every assigned a value once. Hence for any operation involving another register, a new register is created.
We do this with a naming scheme for the registers in dot notation (as it would be in c) which means 2 registers with the same name, should have the same contents. This does not apply to temporaries, but that is another day.
Starting WIP now, and will create many red commits before merging when green.
Just added the compiler, that can parse Slot directly into SlotMachine code (no language layer in between)
Still unclear wheather the Maker is a thing, but since it was in the Language layer i did not remove it (yet)
Otherwise just the compiler and all the tests, moved from the slot_language.
slots used to ba an array of symbols
Now we have an object for each slot, that holds the name and the next_slot
relatively easy change, though quite broad
Since we already have Macros. Macros are nothing more than a list of SlotMachine Instructions. This is what we are aiming to create (which is also what is created in Sol .to_slot)
So the idea came to slot the MacroMaker in there after its done
Simple is really the descriptive name for the layer
Sure, it is "virtual" but that is not as important as the fact that it is simple (or simplified)
Also objct (based really) is better, since orientated implies it is a little like that, but only orientated, not really it. Sol only has objects, nothing else
Just cause i was renaming anyway
Just for future, as this gives us a way to know immediately in the type, which represent normal, and which singleton classes
Also instantiate singleton class lazily (with singleton type)
This makes the type of class single, ie unique, immediately when it is used, ie methods or variables defined.
Fixes a design mistake, where all singletonn classes shared the same type, and thus unique methods per class were impossible
(Also some misc in commit)
the typed method has to be created in the to_pafait pass for it to work correctly, ie for the sends to have something to call
also means that when during compilation creating (raising?) a method, not only vool. but also callable has to be created
resolve had the wrong approach, sort of class based oo
It took methods from "derived" types and just used them
To be correct, those methods would have to be recompiled for the current type, rubyx is type, not class based.
Started on that, still soe strange hang though
Later, type and method analysis may reveal "compatible" types (down only off course) where one could use the exact same code, but that is phase 2
both in mom and risc method complers
alll just compilers now, all linked
Required to move some code down into callable_compiler but all in all quite little. cleaner
seems more appropriate, as it is the class for a single object
Also seems to be called that on the net (don't remember where the meta came from, but it's gone)
after some serious recursive thinking it now actually makes sense.
The key was to change the actual type of the class that the meta_class manages
For objects it's (still) ok just to change the instance_type, but since the class object exists and has type, when adding instance variables, that actual type has to change
Since some weeks, Parfait uses instance variables instead of generated attribute getters (that needed type)
This makes it possible to simplify the boot process, getting rid of separate boot Space and class versions.
It is still quite order dependent, but all "normal" ruby code, (less magic) so easier to understand.
Also moved all code that can never run at runtime into the adapter. This included Space and Object new, space as the space will only ever be created at compile time and object, since that is quite different at run-time (which is where i am working towards)
as they are just the type of the meta_class, that was relatively simple.
I feel this is what oo is meant to be, instance variables and methods for the objects, and since classes are objects, for them too.
Class variables seem like a design mistake, weird scoping rules and no data hiding (left as an exercise to the reader)
args and locals got inlined into message, forgot to delete then
ripples out due to type creation
small type class api change, more ripples, but also more consistent
the "old" way of generating compilers is now obsolete
we can use ruby code with mom macros to achieve the same
Three step wip
remove old builtin
fix tests (including adding necessary methods)
fixup and inclusion of builtin code to parfait
was using exit, since raise is not implemented. This was ambiguous as all programs exit.
Using :died as special kernel code and bending it, and reporting it in interpreter.
opted to hack require to be getting on
need require for the test helper
and the files in lib/parfait
General require mechanism would still be ok, but require_ralative means implementing file source, which needs to be dragged around. I'll make an issue
Compiler now removes the module Parfait scope
and also the ::Parfait:: Scope in module names
Which means we can compile scoped code
and get unscoped code. for Parfait
Handy for tests too
I call it macro because it lets you insert basically arbitrary risc code into the ruby level. The way it works:
Reserve namespace X
map any X.some_call to a Mom instruction
by the name SomeCall
which must take the same args in constructor as given
And obviously produce whatever risc it wants
Hoping to rewrite builtin around this idea (with the existing Mom builtn instructions)