if and goto for slot_language
This commit is contained in:
parent
9885841eb4
commit
2c7944af85
@ -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
|
||||
|
14
lib/slot_language/check_maker.rb
Normal file
14
lib/slot_language/check_maker.rb
Normal 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
|
@ -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"
|
||||
|
@ -6,7 +6,7 @@ module SlotLanguage
|
||||
SlotCompiler.compile(input)
|
||||
end
|
||||
def compile_class(input)
|
||||
compile.class
|
||||
compile(input).class
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user