goodbye soml

This commit is contained in:
Torsten Ruger
2016-12-19 18:56:35 +02:00
parent 1175a8eb97
commit 930d006417
6 changed files with 183 additions and 226 deletions

View File

@ -1,49 +1,41 @@
---
layout: typed
title: Parfait, soml's runtime
title: Parfait, a minimal runtime
---
#### Overview
Soml, like ruby, has open classes. This means that a class can be added to by loading another file
with the same class definition that adds fields or methods. The effect of this is that in designing
the runtime, we can concentrate on a minimal function set.
This means all the functionality the compiler need to get the job done, mostly class and type
structure related functionality with it's support.
### Value and Object
In soml object is not the root of the class hierarchy, but Value is. Integer, Float and Object are
derived from Value. So an integer is *not* an object, but still has a class and methods, just no
instance variables.
### Type and Class
Each object has a type that describes the instance variables and types of the object. It also
reference the class of the object. Type objects are constant, may not be changed over their
lifetime. When a field is added to a class, a new Type is created.
Each object has a type that describes the instance variables and basic types of the object.
Types also reference the class they implement.
Type objects are unique and constant, may not be changed over their lifetime.
When a field is added to a class, a new Type is created. For a given class and combination
of instance names and basic types, only one instance every exists describing that type (a bit
similar to symbols)
A Class describes a set of objects that respond to the same methods (methods are store in the class).
A Class describes a set of objects that respond to the same methods (the methods source is stored
in the RubyMethod class).
A Type describes a set of objects that have the same instance variables.
### Method, Message and Frame
The Method class describes a declared method. It carries a name, argument names and types and
several description of the code. The parsed ast is kept for later inlining, the register model
instruction stream for optimisation and further processing and finally the cpu specific binary
The TypedMethod class describes a callable method. It carries a name, argument and local variable
type and several descriptions of the code.
The typed ast is kept for debugging, the register model instruction stream for optimisation
and further processing and finally the cpu specific binary
represents the executable code.
When Methods are invoked, A message object (instance of Message class) is populated. Message objects
are created at compile time and form a linked list. The data in the Message holds the receiver,
return addresses, arguments and a frame. Frames are also created at compile time and just reused
at runtime.
When TypedMethods are invoked, A message object (instance of Message class) is populated.
Message objects are created at compile time and form a linked list.
The data in the Message holds the receiver, return addresses, arguments and a frame.
Frames are also created at compile time and just reused at runtime.
### Space and support
The single instance of Space hold a list of all Classes, which in turn hold the methods.
Also the space holds messages will hold memory management objects like pages.
The single instance of Space hold a list of all Types and all Classes, which in turn hold
the methods.
Also the space holds messages and will hold memory management objects like pages.
Words represent short immutable text and other word processing (buffers, text) is still tbd.
Lists are number indexed, starting at one, and dictionaries are mappings from words to objects.
Lists (aka Array) are number indexed, starting at one, and dictionaries (aka Hash) are mappings from words to objects.

View File

@ -3,70 +3,55 @@ layout: typed
title: Typed intermediate representation
---
### Disclaimer
### Intermediate representation
The som Language was a stepping stone: it will go. The basic idea is good and will stay, but the
parser, and thus it's existence as a standalone language, will go.
Compilers use different intermediate representations to go from the source code to a binary,
which would otherwise be too big a step.
What will remain is traditionally called an intermediate representation. Basically the layer into
which the soml compiler compiles to. As such these documents will be rewritten soon.
#### Top down designed language
Soml is a language that is designed to be compiled into, rather than written, like
other languages. It is the base for a higher system,
designed for the needs to compile ruby. It is not an endeavor to abstract from a
lower level, like other system languages, namely off course c.
Still it is a system language, or an object machine language, so almost as low level a
language as possible. Only assembler is really lower, and it could be argued that assembler
is not really a language, rather a data format for expressing binary code.
The **typed** intermediate representation is a strongly typed layer, between the dynamically typed
ruby above, and the register machine below. One can think of it as a mix between c and c++,
minus the syntax aspect. While in 2015, this layer existed as a language, (see soml-parser), it
is now a tree representation only.
##### Object oriented to the core, including calling convention
#### Object oriented to the core, including calling convention
Soml is completely object oriented and strongly typed. Types are modelled as classes and carry
information about instance variable names and their basic type. *Every* object stores a reference
to it's types, and while types are immutable, the reference may change. The basic types every
Types are modeled by the class Type and carry information about instance variable names
and their basic type. *Every object* stores a reference
to it's type, and while **types are immutable**, the reference may change. The basic types every
object is made up off, include at least integer and reference (pointer).
The object model, ie the basic properties of objects that the system relies on, is quite simple
and explained in the runtime section. It involves a single reference per object.
Also the object memory model is kept quite simple in that objects are always small multiples
Also the object memory model is kept quite simple in that object sizes are always small multiples
of the cache size of the hardware machine.
We use object encapsulation to build up larger looking objects from these basic blocks.
The calling convention is also object oriented, not stack based*. Message objects used to
define the data needed for invocation. They carry arguments, a frame and return addresses.
In Soml return addresses are pre-calculated and determined by the caller, and yes, there
Return addresses are pre-calculated and determined by the caller, and yes, there
are several. In fact there is one return address per basic type, plus one for exception.
A method invocation may thus be made to return to an entirely different location than the
caller.
\*(A stack, as used in c, is not typed and as such a source of problems)
\*(A stack, as used in c, is not typed, not object oriented, and as such a source of problems)
There is no non- object based memory in soml. The only global constants are instances of
classes that can be accessed by writing the class name in soml source.
There is no non- object based memory at all. The only global constants are instances of
classes that can be accessed by writing the class name in ruby source.
##### Syntax and runtime
#### Runtime / Parfait
Soml syntax is a mix between ruby and c. I is like ruby in the sense that semicolons and even
newlines are not neccessary unless they are. Soml still uses braces, but that will probably
be changed.
The typed representation layer depends on the higher layer to actually determine and instantiate
types (type objects, or objects of class Type). This includes method arguments and local variables.
But off course it is typed, so in argument or variable definitions the type must be specified
like in c. Type names are the class names they represent, but the "int" may be used for brevity
instead of Integer. Return types are also declared, though more for static analysis. As mentioned a
function may return to different addresses according to type. The compiler automatically inserts
errors for return types that are not handled by the caller.
The complete syntax and their translation is discussed [here](syntax.html)
The typed layer is mainly concerned in defining TypedMethods, for which argument or local variable
have specified type (like in c). Basic Type names are the class names they represent,
but the "int" may be used for brevity
instead of Integer.
As mentioned a function may return to different addresses according to type, though this is not
fully implemented.
As soml is the base for dynamic languages, all compile information is recorded in the runtime.
All information is off course object oriented, ie in the form off objects. This means a class
hierarchy, and this itself is off course part of the runtime. The runtime, Parfait, is kept
The runtime, Parfait, is kept
to a minimum, currently around 15 classes, described in detail [here](parfait.html).
Historically Parfait has been coded in ruby, as it was first needed in the compiler.
This had the additional benefit of providing solid test cases for the functionality.
Currently the process is to convert the code into soml, using the same compiler used to compile
ruby.