2016-07-31 16:58:39 +02:00
|
|
|
---
|
|
|
|
layout: news
|
|
|
|
author: Torsten
|
|
|
|
---
|
|
|
|
|
|
|
|
So, the plan, in short:
|
|
|
|
|
|
|
|
1. I need to work a little more on docs. Reading them i notice they are still not up to date
|
2016-12-18 16:45:50 +01:00
|
|
|
2. The Type system needs work
|
|
|
|
3. The Method-Function relationship needs to be created
|
|
|
|
4. Ruby compiler needs to be written
|
|
|
|
5. Parfait moves back completely into ruby land
|
|
|
|
6. Soml parser should be scrapped (or will become redundant by 2-4)
|
|
|
|
7. The memory model needs reworking (global not object based memory)
|
2016-07-31 16:58:39 +02:00
|
|
|
|
2016-12-18 16:45:50 +01:00
|
|
|
### 2. Type system
|
2016-07-31 16:58:39 +02:00
|
|
|
|
|
|
|
A Type is an ordered list of associations from name to BasicType (Object/Integer). The class exists
|
|
|
|
off course and has been implemented as an array with the names and BasicTypes laid out in sequence.
|
|
|
|
This is basically fine, but support for navigation is missing.
|
|
|
|
|
|
|
|
The whole type system is basically graph. A type *A* is connected to a type *B* if it has exactly
|
|
|
|
one different BasicType. So *A* needs to have **exactly** the same names, and **exactly** one
|
|
|
|
different BasicType. Another way of saying this is that the two types are related if in the class
|
|
|
|
that Type represents, exactly one variable changes type. This is off course exactly what happens
|
|
|
|
when an assignment assigns a different type.
|
|
|
|
|
|
|
|
*A* and *B* are also related when *A* has exactly one more name entry than *B* , but os otherwise
|
|
|
|
identical. This is what happens when a new variable is added too a class, or one is removed.
|
|
|
|
|
|
|
|
The implementation needs to establish this graph (possibly lazily), so that the traversal is fast.
|
|
|
|
The most likely implementation seems a hash, so a hashing function has to be designed and the equals
|
|
|
|
implemented.
|
|
|
|
|
2016-12-18 16:45:50 +01:00
|
|
|
### 3. Method-Function relationship
|
2016-07-31 16:58:39 +02:00
|
|
|
|
|
|
|
Just to get the naming clear: A method is at the ruby level, untyped. A Class has references to
|
|
|
|
Methods.
|
|
|
|
|
|
|
|
Whereas a Function is at the level below, fully typed.
|
|
|
|
Function's arguments and local variables have a BasicType.
|
|
|
|
Type has references to Functions.
|
|
|
|
|
|
|
|
A Function's type is fully described by the combination of the arguments Type and the Frame Type.
|
|
|
|
The Frame object is basically a wrapper for all local variables.
|
|
|
|
|
|
|
|
A (ruby) Method has N Function "implementations". One function for each different combination of
|
|
|
|
BasicTypes for arguments and local variables. Functions know which Method they belong to, because
|
|
|
|
their parent Type class holds a reference to the Class that the Type describes.
|
|
|
|
|
2016-12-18 16:45:50 +01:00
|
|
|
### 4. Ruby Compiler
|
2016-07-31 16:58:39 +02:00
|
|
|
|
|
|
|
Currently there is only the Function level and the soml compiler. The ruby level / compiler is
|
|
|
|
missing.
|
|
|
|
|
|
|
|
The Compiler generates Class objects, and Type objects as far as it can determine name and
|
|
|
|
BasicTypes of the instance variables.
|
|
|
|
|
|
|
|
Then it creates Method objects for every Method parsed. Finally it must create all functions that
|
|
|
|
needed. In a first brute-force approach this may mean creating functions for all possible
|
|
|
|
type combinations.
|
|
|
|
|
|
|
|
Call-sites must then be "linked". Linking here refers to the fact that the compiler can not
|
|
|
|
determine how to call a function before it is created. So the functions get created in a first pass
|
|
|
|
and calls and returns "linked" in a second. The return addresses used at the "soml" level are
|
|
|
|
dependent on the BasicType that is being returned. This involves associating the code labels (at
|
|
|
|
the function level) with the ast nodes they come from (at the method level). With this, the compiler
|
|
|
|
ensures that the type of the variable receiving the return value is correct.
|
|
|
|
|
2016-12-18 16:45:50 +01:00
|
|
|
### 5. Parfait in ruby
|
2016-07-31 16:58:39 +02:00
|
|
|
|
|
|
|
After SOML was originally written, parts of the run-time (parfait) was ported to soml. This was done with the
|
|
|
|
idea that the run-time is low level and thus needs to be fully typed. As it turns out this is only
|
|
|
|
partly correct, in the sense that there needs to exist Function definitions (in the sense above)
|
|
|
|
that implement basic functionality. But as the sub-chapter on the ruby compiler should explain,
|
|
|
|
this does not mean the code has to written in a typed language.
|
|
|
|
|
|
|
|
After the ruby-compiler is implemented, the run-time can be implemented in ruby. While this may seem
|
|
|
|
strange at first, one must remember that the ruby-compiler creates N Functions of each method for
|
|
|
|
all possible type combinations. This means if the ruby method is correctly implemented, error
|
|
|
|
handling, for type errors, will be correctly generated by the compiler.
|
|
|
|
|
2016-12-18 16:45:50 +01:00
|
|
|
### 6. SOML goodbye
|
2016-07-31 16:58:39 +02:00
|
|
|
|
|
|
|
By this time the soml language can be removed. Meaning the parser for the language and all
|
|
|
|
documentation is not needed. The ruby-complier compilers straight into the soml internal
|
|
|
|
representation (as the soml parser) and because parfait is back in ruby land, soml should be
|
|
|
|
removed. Which is a relief, because there are definitely enough languages in the world.
|
|
|
|
|
|
|
|
|
2016-12-18 16:45:50 +01:00
|
|
|
### 7. Memory model rework
|
2016-07-31 16:58:39 +02:00
|
|
|
|
|
|
|
Slightly unrelated to the above (read: can be done at the same time), the memory model needs to be
|
|
|
|
expanded. The current per object *fake* memory works fine, but leaves memory management in
|
|
|
|
the compiler.
|
|
|
|
|
|
|
|
Since ultimately memory management should be part of the run-time, the model needs to be changed
|
|
|
|
to a global one. This means class Page and Space should be implemented, and the *fake* memory
|
|
|
|
mapped to a global array.
|