ruby-x.github.io/app/views/pages/misc/soml.html.haml
Torsten Ruger a42ca6e514 group the old and new ideas into misc
typed (file) still needs work, but at least the typed directory is gone
2018-04-11 20:53:49 +03:00

211 lines
7.6 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

= render "pages/misc/menu"
%h1= title "Soml Syntax"
Soml was a step on the way. While i was still thinking about VM's and c++ ,
the year was 2015.
%br
I had thought that some kind of typed layer was needed, and that one could
implement the higher level in a language. A typed language, sort of like c++,
that would be used to implement the code of ruby.
%br
A little like PyPy has a core that only uses a small set of python, that can,
a la crystal, be fully type inferred.
%br
This idea turned out to be wrong, or difficult. Because the bridge between the
typed an untyped was unclear or i didn't get it to work. The current system
works by typing self, but not it's instances. A difficult mix to express in a
language.
%br
This led me to abandon soml and rewrite the functionality as vool and mom layers.
But Soml was working, the parser is still about and there are some interesting
=link_to "benchmarks" , "soml_benchmarks.html"
that came from it and really validated the calling convention.
%h2 Top level Class and methods
%p The top level declarations in a file may only be class definitions
%pre
%code
:preserve
class Dictionary < Object
int add(Object o)
... statements
end
end
%p
The class hierarchy is explained in
= succeed "," do
%a{:href => "parfait.html"} here
%p
Methods must be typed, both arguments and return. Generally class names serve as types, but “int” can
be used as a shortcut for Integer.
%p
Code may not be outside method definitions, like in ruby. A compiled program starts at the builtin
method
= succeed "," do
%strong init
%strong Space.main
%p
Classes are represented by class objects (instances of class Class to be precise) and methods by
Method objects, so all information is available at runtime.
%h2 Expressions
%p
Soml distinguishes between expressions and statements. Expressions have value, statements perform an
action. Both are compiled to Register level instructions for the current method. Generally speaking
expressions store their value in a register and statements store those values elsewhere, possibly
after operating on them.
%p The subsections below correspond roughly to the parsers rule names.
%p
%strong Basic expressions
are numbers (integer or float), strings or names, either variable, argument,
field or class names. (normal details applicable). Special names include self (the current
receiver), and message (the currently executed method frame). These all resolve to a register
with contents.
%pre
%code
:preserve
23
"hi there"
argument_name
Object
%p
A
%strong field access
resolves to the fields value at the time. Fields must be defined by
field definitions, and are basically instance variables, but not hidden (see below).
The example below shows how to define local variables at the same time. Notice chaining, both for
field access and call, is not allowed.
%pre
%code
:preserve
Type l = self.type
Class c = l.object_class
Word n = c.name
%p
A
%strong Call expression
is a method call that resolves to the methods return value. If no receiver is
specified, self (the current receiver) is used. The receiver may be any of the basic expressions
above, so also class instances. The receiver type is known at compile time, as are all argument
types, so the class of the receiver is searched for a matching method. Many methods of the same
name may exist, but to issue a call, an exact match for the arguments must be found.
%pre
%code
:preserve
Class c = self.get_class()
c.get_super_class()
%p
An
%strong operator expression
is a binary expression, with either of the other expressions as left
and right operand, and an operator symbol between them. Operand types must be integer.
The symbols allowed are normal arithmetic and logical operations.
%pre
%code
:preserve
a + b
counter | 255
mask >> shift
%p
Operator expressions may be used in assignments and conditions, but not in calls, where the result
would have to be assigned beforehand. This is one of those cases where somls low level approach
shines through, as soml has no auto-generated temporary variables.
%h2 Statements
%p
We have seen the top level statements above. In methods the most interesting statements relate to
flow control and specifically how conditionals are expressed. This differs somewhat from other
languages, in that the condition is expressed explicitly (not implicitly like in c or ruby).
This lets the programmer express more precisely what is tested, and also opens an extensible
framework for more tests than available in other languages. Specifically overflow may be tested in
soml, without dropping down to assembler.
%p
An
%strong if statement
is started with the keyword if_ and then contains the branch type. The branch
type may be
= succeed "." do
%em plus, minus, zero, nonzero or overflow
%em If
may be continued with en
= succeed "," do
%em else
%em end
%pre
%code
:preserve
if_zero(a - 5)
....
else
....
end
%p
A
%strong while statement
is very much like an if, with off course the normal loop semantics, and
without the possible else.
%pre
%code
:preserve
while_plus( counter )
....
end
%p
A
%strong return statement
return a value from the current functions. There are no void functions.
%pre
%code
:preserve
return 5
%p
A
%strong field definition
is to declare an instance variable on an object. It starts with the keyword
field, must be in class (not method) scope and may not be assigned to.
%pre
%code
:preserve
class Class < Object
field List instance_methods
field Type object_type
field Word name
...
end
%p
A
%strong local variable definition
declares, and possibly assigns to, a local variable. Local variables
are stored in frame objects, in fact they are instance variables of the current frame object.
When resolving a name, the compiler checks argument names first, and then local variables.
%pre
%code
:preserve
int counter = 0
%p
Any of the expressions may be assigned to the variable at the time of definition. After a variable is
defined it may be assigned to with an
%strong assignment statement
any number of times. The assignment
is like an assignment during definition, without the leading type.
%pre
%code
:preserve
counter = 0
%p Any of the expressions, basic, call, operator, field access, may be assigned.
%h2 Code generation and scope
%p
Compiling generates two results simultaneously. The more obvious is code for a function, but also an
object structure of classes etc that capture the declarations. To understand the code part better
the register abstraction should be studied, and to understand the object structure the runtime.
%p
The register machine abstraction is very simple, and so is the code generation, in favour of a simple
model. Especially in the area of register assignment, there is no magic and only a few simple rules.
%p
The main one of those concerns main memory access ordering and states that object memory must
be consistent at the end of the statement. Since there is only only object memory in soml, this
concerns all assignments, since all variables are either named or indexed members of objects.
Also local variables are just members of the frame.
%p
This obviously does leave room for optimisations as preliminary benchmarks show. But benchmarks also
show that it is not such a bit issue and much more benefit can be achieved by inlining.