diff --git a/lib/rubyx.rb b/lib/rubyx.rb index d160d88b..3f738ea3 100644 --- a/lib/rubyx.rb +++ b/lib/rubyx.rb @@ -4,6 +4,7 @@ require_relative "util" require_relative "elf/object_writer" require_relative "risc" require_relative "slot_machine/slot_machine" +require_relative "slot_language/slot_compiler" require_relative "arm/arm_machine" require_relative "arm/arm_platform" require_relative "sol/statement" diff --git a/lib/slot_language/README.md b/lib/slot_language/README.md new file mode 100644 index 00000000..ff514b2d --- /dev/null +++ b/lib/slot_language/README.md @@ -0,0 +1,57 @@ +# Slot Language + +This is a new layer / approach to create code for the next level, the slot_machine. + +In essence the slot_language lets us code the slot_machine. + +## Problem + +The Problem with the current way is that some of the slot_machine instruction are +really quite complex. They are really more function than instructions. + +This is especially true for everything around the dynamic call. Dynamic call itself +is still or, but resolve_method is too much. And it even uses method_missing, another +instruction that is too much, which in turn should use raise and now we really see +the point. + +I though about making those "super" instruction real methods and just calling them, +but the calling overhead is just too much, and really it is the wrong tool for the +job. Calling implies switching of context, while resolve_method and raise and mm +really all operate on the same context. + +## The Slot Machine + +The Slot Machine is a kind of memory based, oo abstraction of the risc machine, that in +turn mirrors a cpu relatively closely. The machine "knows" the message in the way a +cpu knows it's registers. And the oo part means it also knows the parfait object +model. + +While Ruby/Sol code only ever assumes the type of self, the Slot Machine assumes types +of the whole of Parfait. The main instruction after which the machine is named is +the SlotLoad, which moves one instance variable to another. + +## Code for the Machine + +Since the Slot and SlotMachine have proven useful abstractions, this introduces the +SlotLanguage as a way to create code for the SlotMachine. + +The SlotMachine defines no methods on objects and passes no objects. While it has call +and return, these are defined in terms of jumps and use, like all Slot instructions, +the message. + +## Syntax (projection) + +Since we are not defining methods, etc, there is no scope. In other words the only +"scope" is the current message and global constants. This also means we will +use the file scope, ie one file defines one instruction, by convention of the +same name. + +For starters we will use ruby syntax, with these semantics: +- only globals and message (the literal) are valid variable names +- dot will mean pointer traversal, sort of like c (no calling) +- names on right hand of dot must be instance variables of left +- equal will mean assignment in the SlotLoad kind of sense +- some macro mechanism is called for (tbd) +- maybe labels have to be created (sort of like the risc dsl) + +The result of a compilation will be a SlotMachine Macro diff --git a/lib/slot_language/message_slot.rb b/lib/slot_language/message_slot.rb new file mode 100644 index 00000000..b40418b7 --- /dev/null +++ b/lib/slot_language/message_slot.rb @@ -0,0 +1,5 @@ +module SlotLanguage + class MessageSlot + + end +end diff --git a/lib/slot_language/named_slot.rb b/lib/slot_language/named_slot.rb new file mode 100644 index 00000000..15ded2b6 --- /dev/null +++ b/lib/slot_language/named_slot.rb @@ -0,0 +1,5 @@ +module SlotLanguage + class NamedSlot + + end +end diff --git a/lib/slot_language/slot_compiler.rb b/lib/slot_language/slot_compiler.rb new file mode 100644 index 00000000..d8b488cc --- /dev/null +++ b/lib/slot_language/slot_compiler.rb @@ -0,0 +1,29 @@ +require "parser/current" +require "ast" + +module SlotLanguage + class SlotCompiler < AST::Processor + + def self.compile(input) + ast = Parser::CurrentRuby.parse( input ) + self.new.process(ast) + end + def not_implemented(node) + raise "Not implemented #{node.type}" + end + # default to error, so non implemented stuff shows early + def handler_missing(node) + not_implemented(node) + end + def on_send(statement) + kids = statement.children.dup + receiver = process(kids.shift) || MessageSlot.new + name = kids.shift + raise "Kids #{kids}" unless kids.empty? + SlotMaker.new( name , receiver ) + end + end +end +require_relative "named_slot" +require_relative "message_slot" +require_relative "slot_maker" diff --git a/lib/slot_language/slot_maker.rb b/lib/slot_language/slot_maker.rb new file mode 100644 index 00000000..767445a1 --- /dev/null +++ b/lib/slot_language/slot_maker.rb @@ -0,0 +1,7 @@ +module SlotLanguage + class SlotMaker + def initialize(name , more) + + end + end +end diff --git a/test/slot_language/helper.rb b/test/slot_language/helper.rb new file mode 100644 index 00000000..ea82ec10 --- /dev/null +++ b/test/slot_language/helper.rb @@ -0,0 +1,12 @@ +require_relative "../helper" + +module SlotLanguage + module SlotHelper + def compile(input) + SlotCompiler.compile(input) + end + def compile_class(input) + compile.class + end + end +end diff --git a/test/slot_language/test_slot_compiler.rb b/test/slot_language/test_slot_compiler.rb new file mode 100644 index 00000000..5e851001 --- /dev/null +++ b/test/slot_language/test_slot_compiler.rb @@ -0,0 +1,15 @@ +require_relative "helper" + +module SlotLanguage + class TestSlotCompiler < MiniTest::Test + def test_init + assert SlotCompiler.new + end + def test_compile + assert_equal SlotMaker , SlotCompiler.compile("a").class + end + def test_fail_args + assert_raises{ SlotCompiler.compile("a(1)")} + end + end +end