if and goto for slot_language

This commit is contained in:
Torsten Rüger 2019-10-05 14:49:45 +03:00
parent 9885841eb4
commit 2c7944af85
5 changed files with 59 additions and 11 deletions

View File

@ -10,11 +10,11 @@ The Problem with the current way is that some of the slot_machine instruction ar
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
is still ok, 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,
I thought 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.
@ -23,7 +23,7 @@ really all operate on the same context.
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
cpu knows its 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
@ -41,10 +41,15 @@ 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.
Since we are not defining methods, there is no seperate scope. We create objects that
will transform to SlotMachine Instructions _in_ the scope of the current method.
In other words they will have access to the compiler and the callable, when transforming
to SlotMachine (similar to Sol in that way). This means at compile time we have
can use the frame type and constants, while we can always assume the Message (and not
much else) at runtime.
As the scope is "fixed", we will use the file scope, ie one file defines one
instruction/macro, 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

View File

@ -0,0 +1,14 @@
module SlotLanguage
class CheckMaker
attr_reader :check , :left , :right, :goto
def initialize(check , left , right)
@check = check
@left = left
@right = right
end
def set_goto(go)
@goto = go
end
end
end

View File

@ -16,19 +16,27 @@ module SlotLanguage
not_implemented(node)
end
def on_send(statement)
#puts statement
kids = statement.children.dup
receiver = process(kids.shift) || MessageSlot.new
name = kids.shift
return label(name) if(name.to_s.end_with?("_label"))
return goto(name,kids) if(name == :goto)
return check(name,receiver, kids) if(name == :==)
SlotMaker.new( name , receiver )
end
def on_lvasgn expression
#puts expression
name = expression.children[0]
value = process(expression.children[1])
Sol::LocalAssignment.new(name,value)
end
def on_if(expression)
condition = process(expression.children[0])
condition.set_goto( process(expression.children[1]) )
condition
end
def on_begin(exp)
process(exp.first)
end
def on_ivar expression
Sol::InstanceVariable.new(instance_name(expression.children.first))
end
@ -40,8 +48,21 @@ module SlotLanguage
def label(name)
SlotMachine::Label.new(name.to_s , name)
end
def goto(name , args)
# error handling would not hurt
label = process(args.first)
SlotMachine::Jump.new( label )
end
def check(name , receiver , kids)
raise "Only ==, not #{name}" unless name == :==
raise "Familiy too large #{kids}" if kids.length > 1
puts "Kids " + kids.to_s
right = process(kids.first)
CheckMaker.new(name , receiver , right)
end
end
end
require_relative "named_slot"
require_relative "message_slot"
require_relative "slot_maker"
require_relative "check_maker"

View File

@ -6,7 +6,7 @@ module SlotLanguage
SlotCompiler.compile(input)
end
def compile_class(input)
compile.class
compile(input).class
end
end
end

View File

@ -19,7 +19,15 @@ module SlotLanguage
assert_equal :while_label , label.name
end
def test_slot_load
compile("a = @b")
assert_equal Sol::LocalAssignment , compile_class("a = @b")
end
def test_goto
assert_equal SlotMachine::Jump , compile_class("goto(exit_label)")
end
def test_if
check = compile("goto(exit_label) if(a == b)")
assert_equal CheckMaker , check.class
assert_equal SlotMachine::Jump , check.goto.class
end
end
end