rename phisol to soml

This commit is contained in:
Torsten Ruger 2015-10-23 14:22:55 +03:00
parent 991cc0519f
commit e0c5bc4c11
31 changed files with 60 additions and 97 deletions

View File

@ -9,9 +9,9 @@ Salama is about native code generation in and of ruby.
It is probably best to read the [The Book](http://dancinglightning.gitbooks.io/the-object-machine/content/) first.
The current third rewrite adds a system language, with the idea of compiling ruby to that language, Phisol.
The original ruby parser has been remodeled to parse Phisol and later we will use whitequarks
parser to parse ruby. Then it will be ruby --> Phisol --> assembler --> binary .
The current third rewrite adds a system language, with the idea of compiling ruby to that language, Soml.
The original ruby parser has been remodeled to parse Soml and later we will use whitequarks
parser to parse ruby. Then it will be ruby --> Soml --> assembler --> binary .
## Done
@ -69,11 +69,11 @@ As said, "Hello world" comes out and does use syscall 4.
Also the program stops by syscall exit.
The full list is on the net and involves mostly just work.
### Parse Phisol
### Parse Soml
Parse Phisol, using Parslet. This has been separated out as it's own gem, [salama-reader](https://github.com/salama/salama-reader).
Parse Soml, using Parslet. This has been separated out as it's own gem, [salama-reader](https://github.com/salama/salama-reader).
Phisol is now fully typed (all variables, arguments and return). Also it has statements, unlike ruby
Soml is now fully typed (all variables, arguments and return). Also it has statements, unlike ruby
where everything is an statements. Statements have no value. Otherwise it is quite basic, and
it's main purpose is to have an oo system language to compile to.
@ -108,11 +108,11 @@ exchange format, have the core read that, and use the mechanism to achieve langu
## Status
Currently all the work is on the Phisol front. Also documenting the *small* change of a new language.
Currently all the work is on the Soml front. Also documenting the *small* change of a new language.
I'll do some simple string and fibo examples in Phisol next.
I'll do some simple string and fibo examples in Soml next.
Next will be the multiple return feature and then to try to compile ruby to Phisol.
Next will be the multiple return feature and then to try to compile ruby to Soml.
## Future

View File

@ -1,7 +1,15 @@
## Notice of change
The stuff below, like the whole of Parfait, was written before soml. Ie before there was a seperate
language to compile a higher language to. Soml is not so dynamic, could do without much of the
ObjectSpace that is the core of Parfait.
So things will change. How will become clear when soml is finished.
### Parfait: a thin layer
Parfait is the run-time of the **vm**.
To be more precise, it is that part of the run-time needed to boot ruby.
To be more precise, it is that part of the run-time needed to boot soml.
The run-time needs to contain quite a lot of functionality for a dynamic system.
And a large part of that functionality must actually be used at compile time too.
@ -10,7 +18,7 @@ We reuse the Parfait code at compile-time, to create the data for the compiled v
To do this the vm (re) defines the object memory (in parfait_adapter).
To do the actual compiling we parse and compile the parfait code and inline it to
appropriate places (ie send, get_instance_variable etc). We have to inline to avoid recursion.
appropriate places.
A work in progress that started from here : http://salama.github.io/2014/06/10/more-clarity.html
went on here http://salama.github.io/2014/07/05/layers-vs-passes.html
@ -25,31 +33,9 @@ It's too simple: just slips off the mind like a fish into water.
Parfait has a brother, the Builtin module. Builtin contains everything that can not be coded in ruby,
but we still need (things like List access).
#### Example: Message send
It felt a little stupid that it took me so long to notice that sending a message is very closely
related to the existing ruby method Object.send
Off course Object.send takes symbol and the arguments and has the receiver, so all the elements of our
Message are there. And the process that Object.send needs to do is exactly that:
send that message, ie find the correct method according to the old walk up the inheritance tree rules and dispatch it.
And as all this happens at runtime, "all" we have to do is code this logic. And since it is at runtime,
we can do it in ruby (as i said, this get's compiled and run, just like the program).
But what about the infinite loop problem:
There was a little step left out: Off course the method gets compiled at compile-time and so
we don't just blindly dispatch: we catch the simple cases that we know about:
layout, type instance variables and compile time known functions.
Part of those are some that we just don't allow to be overridden.
Also what in ruby is object.send is Message.send in salama, as it is the message we are sending and
which defines all the data we need (not the object). The object receives, it does not send.
### Vm vs language- core
Parfait is not the language (ie ruby) core library. Core library functionality differs between
Parfait is not the language core library. Core library functionality differs between
languages and so the language core lib must be on top of the vm parfait.
To make this point clear, i have started using different names for the core classes. Hopefully
@ -57,8 +43,3 @@ more sensible ones, ie List instead of Array, Dictionary instead of Hash.
Also Parfait is meant to be as thin as humanly possibly, so extra (nice to have) functionality
will be in future modules.
So the Namespace of the Runtime is actually Parfait (not nothing as in ruby).
Only in the require does one later have to be clever and see which vm one is running in and either
require or not. Maybe one doesn't even have to be so clever, we'll see (as requiring an existing
module should result in noop)

View File

@ -5,21 +5,12 @@
# It allows for access to those variables basically
# A Message and a Frame make up the two sides of message passing:
# A Message (see details there) is created by the sender and control is transferred
# A Message (see details there) is created by the caller and control is transferred
# A Frame is created by the receiver
# PS: it turns out that both messages and frames are created at compile, not run-time, and
# just constantly reused. Each message has a frame object ready and ist also linked
# to the next message.
# The better way to say above is that a messages is *used* by the caller, and a frame by the callee.
# In static languages these two objects are one, because the method is known at compile time.
# In that case the whole frame is usually on the stack, for leaves even omitted and all data is
# held in registers
#
# In a dynamic language the method is dynamically resolved, and so the size of the frame is not
# know to the caller
# Also exceptions (with the possibility of retry) and the idea of being able to take and store
# bindings make it, to say the very least, unsensibly tricky to store them on the stack. So we don't.
# The better way to say above is that a message is *used* by the caller, and a frame by the callee.
# Also at runtime Messages and Frames remain completely "normal" objects. Ie have layouts and so on.
# Which resolves the dichotomy of objects on the stack or heap. Sama sama.

View File

@ -5,7 +5,7 @@ require "register/positioned"
require "register/padding"
require "register/parfait_adapter"
require "phisol/compiler"
require "soml/compiler"
require "register/method_source"

View File

@ -5,7 +5,7 @@ The RegisterMachine, is an abstract machine with registers. Think of it as an ar
normal instruction names. It is not however an abstraction of existing hardware, but only
of that subset that we need.
Our primary objective is to compile Phisol to this level, so the register machine has:
Our primary objective is to compile Soml to this level, so the register machine has:
- object access instructions
- object load
- object oriented call semantics

View File

@ -17,8 +17,8 @@ Slightly more here : http://salama.github.io/2014/06/10/more-clarity.html (then
The Builtin module is scattered into several files, but that is just so the file doesn't get too long.
Note: This is about to change slightly with the arrival of Phisol. Phisol is a lower level function,
Note: This is about to change slightly with the arrival of Soml. Soml is a lower level function,
and as such there is not much that we need that can not be expressed in it. My current thinking
is that i can code anything in Phisol and will only need the Phisol instruction set.
is that i can code anything in Soml and will only need the Soml instruction set.
So this whole Builtin approach may blow over in the next months. It had already become clear that
mostly this was going to be about memory access, which in Phisol is part of the language.
mostly this was going to be about memory access, which in Soml is part of the language.

View File

@ -128,7 +128,7 @@ module Register
syntax = @parser.parse_with_debug(bytes)
parts = Parser::Transform.new.apply(syntax)
#puts parts.inspect
Phisol::Compiler.compile( parts )
Soml::Compiler.compile( parts )
end
private

View File

@ -1,4 +1,4 @@
module Phisol
module Soml
class Compiler < AST::Processor
def initialize()

View File

@ -23,7 +23,7 @@ The compiler has a method for each type for ast, named along on_xxx with xxx as
#### Compiler holds scope
The Compiler instance can hold arbitrary scope needed during the compilation. Since we compile Phisol
The Compiler instance can hold arbitrary scope needed during the compilation. Since we compile Soml
(a static language) things have become more simple.
A class statement sets the current @clazz scope , a method definition the @method.
@ -45,22 +45,13 @@ The general structure of the instructions is a graph
Since the machine is virtual, we have to define it, and since it is oo we define it in objects.
Also it is important to define how instructions operate, which is is in a physical machine would
be by changing the contents of registers or some stack.
be by changing the contents of registers or some stack.
Our machine is not a register machine, but an object machine: it operates directly on objects and
also has no separate stack, only objects. There are a number of objects which are accessible,
and one can think of these (their addresses) as register contents.
(And one wouldn't be far off as that is the implementation.)
also has no separate stack, only objects. There is only one object which is accessible,
basically meaning pinned to a register, the Message.
The objects the machine works on are:
- Message
- Frame
- Self
- NewMessage
and working on means, these are the only objects which the machine accesses.
Ie all others would have to be moved first.
One can think of the Message as an oo replacement of the stack.
When a Method needs to make a call, it creates a NewMessage object.
Messages contain return addresses (yes, plural) and arguments.
@ -69,10 +60,10 @@ The important thing here is that Messages and Frames are normal objects.
### Distinctly future proof
Phisol is designed to be used as an implementation language for a higher oo language. Some, or
Soml is designed to be used as an implementation language for a higher oo language. Some, or
even many, features may not make sense on their own. But these features, like several return
addresses, are important to implement the higher language.
In fact, Phisol's main purpose is not even to be written. The main purpose is to have a language to
In fact, Soml's main purpose is not even to be written. The main purpose is to have a language to
compile ruby to. In the same way that the assembler layer in salama is not designed to be written,
we just need it to create our layers.

View File

@ -1,4 +1,4 @@
module Phisol
module Soml
Compiler.class_eval do
def on_assignment statement

View File

@ -1,4 +1,4 @@
module Phisol
module Soml
# collection of the simple ones, int and strings and such
Compiler.class_eval do

View File

@ -1,4 +1,4 @@
module Phisol
module Soml
Compiler.class_eval do
def on_call statement

View File

@ -1,4 +1,4 @@
module Phisol
module Soml
Compiler.class_eval do
def on_class_field statement

View File

@ -1,4 +1,4 @@
module Phisol
module Soml
Compiler.class_eval do
def on_class statement

View File

@ -1,4 +1,4 @@
module Phisol
module Soml
Compiler.class_eval do
# attr_reader :values

View File

@ -1,4 +1,4 @@
module Phisol
module Soml
Compiler.class_eval do
def on_field_access statement

View File

@ -1,4 +1,4 @@
module Phisol
module Soml
Compiler.class_eval do
include AST::Sexp

View File

@ -1,4 +1,4 @@
module Phisol
module Soml
Compiler.class_eval do
def on_function statement

View File

@ -1,4 +1,4 @@
module Phisol
module Soml
Compiler.class_eval do
# if - attr_reader :cond, :if_true, :if_false

View File

@ -1,4 +1,4 @@
module Phisol
module Soml
Compiler.class_eval do
# attr_reader :name

View File

@ -1,4 +1,4 @@
module Phisol
module Soml
Compiler.class_eval do
def on_operator_value statement

View File

@ -1,4 +1,4 @@
module Phisol
module Soml
Compiler.class_eval do
# return attr_reader :statement

View File

@ -1,4 +1,4 @@
module Phisol
module Soml
Compiler.class_eval do
def on_statements statement

View File

@ -1,4 +1,4 @@
module Phisol
module Soml
Compiler.class_eval do
def on_while_statement statement

View File

@ -13,7 +13,7 @@ module Register
# derived classes are Boot/Meta Class and StringConstant
class ObjectConstant < Constant
# def type
# Phisol::Reference
# Soml::Reference
# end
def clazz
raise "abstract #{self}"

View File

@ -1,7 +1,7 @@
require_relative '../../helper'
require 'parslet/convenience'
Phisol::Compiler.class_eval do
Soml::Compiler.class_eval do
def set_main main
@clazz = Register.machine.space.get_class_by_name :Object
@method = main
@ -21,7 +21,7 @@ module CompilerHelper
syntax = parser.parse_with_debug(@string_input)
parts = Parser::Transform.new.apply(syntax)
#puts parts.inspect
compiler = Phisol::Compiler.new
compiler = Soml::Compiler.new
set_main(compiler)
produced = compiler.process( parts )
assert @output , "No output given"

View File

@ -18,7 +18,7 @@ class AddTest < MiniTest::Test
s(:int, 5),
s(:int, 7)))))))
Phisol::Compiler.compile( code )
Soml::Compiler.compile( code )
machine.collect
@interpreter = Interpreter::Interpreter.new
@interpreter.start Register.machine.init

View File

@ -24,10 +24,10 @@ HERE
syntax = Parser::Salama.new.parse_with_debug(@string_input)
parts = Parser::Transform.new.apply(syntax)
#puts parts.inspect
Phisol::Compiler.compile( parts )
Soml::Compiler.compile( parts )
machine.collect
# statements = Register.machine.boot.parse_and_compile @string_input
# Phisol::Compiler.compile( statements , Register.machine.space.get_main )
# Soml::Compiler.compile( statements , Register.machine.space.get_main )
@interpreter = Interpreter::Interpreter.new
@interpreter.start Register.machine.init
#show_ticks # get output of what is

View File

@ -52,10 +52,10 @@ HERE
syntax = Parser::Salama.new.parse_with_debug(@string_input)
parts = Parser::Transform.new.apply(syntax)
#puts parts.inspect
Phisol::Compiler.compile( parts )
Soml::Compiler.compile( parts )
machine.collect
# statements = Register.machine.boot.parse_and_compile @string_input
# Phisol::Compiler.compile( statements , Register.machine.space.get_main )
# Soml::Compiler.compile( statements , Register.machine.space.get_main )
@interpreter = Interpreter::Interpreter.new
@interpreter.start Register.machine.init
#show_ticks # get output of what is

View File

@ -18,7 +18,7 @@ class TestPuts < MiniTest::Test
s(:receiver,
s(:string, "Hello again")))))))
Phisol::Compiler.compile( code )
Soml::Compiler.compile( code )
machine.collect
@interpreter = Interpreter::Interpreter.new
@interpreter.start Register.machine.init