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.
|
really quite complex. They are really more function than instructions.
|
||||||
|
|
||||||
This is especially true for everything around the dynamic call. Dynamic call itself
|
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
|
instruction that is too much, which in turn should use raise and now we really see
|
||||||
the point.
|
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
|
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
|
job. Calling implies switching of context, while resolve_method and raise and mm
|
||||||
really all operate on the same context.
|
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
|
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
|
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.
|
model.
|
||||||
|
|
||||||
While Ruby/Sol code only ever assumes the type of self, the Slot Machine assumes types
|
While Ruby/Sol code only ever assumes the type of self, the Slot Machine assumes types
|
||||||
@ -41,10 +41,15 @@ the message.
|
|||||||
|
|
||||||
## Syntax (projection)
|
## Syntax (projection)
|
||||||
|
|
||||||
Since we are not defining methods, etc, there is no scope. In other words the only
|
Since we are not defining methods, there is no seperate scope. We create objects that
|
||||||
"scope" is the current message and global constants. This also means we will
|
will transform to SlotMachine Instructions _in_ the scope of the current method.
|
||||||
use the file scope, ie one file defines one instruction, by convention of the
|
In other words they will have access to the compiler and the callable, when transforming
|
||||||
same name.
|
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:
|
For starters we will use ruby syntax, with these semantics:
|
||||||
- only globals and message (the literal) are valid variable names
|
- 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)
|
not_implemented(node)
|
||||||
end
|
end
|
||||||
def on_send(statement)
|
def on_send(statement)
|
||||||
#puts statement
|
|
||||||
kids = statement.children.dup
|
kids = statement.children.dup
|
||||||
receiver = process(kids.shift) || MessageSlot.new
|
receiver = process(kids.shift) || MessageSlot.new
|
||||||
name = kids.shift
|
name = kids.shift
|
||||||
return label(name) if(name.to_s.end_with?("_label"))
|
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 )
|
SlotMaker.new( name , receiver )
|
||||||
end
|
end
|
||||||
def on_lvasgn expression
|
def on_lvasgn expression
|
||||||
#puts expression
|
|
||||||
name = expression.children[0]
|
name = expression.children[0]
|
||||||
value = process(expression.children[1])
|
value = process(expression.children[1])
|
||||||
Sol::LocalAssignment.new(name,value)
|
Sol::LocalAssignment.new(name,value)
|
||||||
end
|
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
|
def on_ivar expression
|
||||||
Sol::InstanceVariable.new(instance_name(expression.children.first))
|
Sol::InstanceVariable.new(instance_name(expression.children.first))
|
||||||
end
|
end
|
||||||
@ -40,8 +48,21 @@ module SlotLanguage
|
|||||||
def label(name)
|
def label(name)
|
||||||
SlotMachine::Label.new(name.to_s , name)
|
SlotMachine::Label.new(name.to_s , name)
|
||||||
end
|
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
|
||||||
end
|
end
|
||||||
require_relative "named_slot"
|
require_relative "named_slot"
|
||||||
require_relative "message_slot"
|
require_relative "message_slot"
|
||||||
require_relative "slot_maker"
|
require_relative "slot_maker"
|
||||||
|
require_relative "check_maker"
|
||||||
|
@ -6,7 +6,7 @@ module SlotLanguage
|
|||||||
SlotCompiler.compile(input)
|
SlotCompiler.compile(input)
|
||||||
end
|
end
|
||||||
def compile_class(input)
|
def compile_class(input)
|
||||||
compile.class
|
compile(input).class
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -19,7 +19,15 @@ module SlotLanguage
|
|||||||
assert_equal :while_label , label.name
|
assert_equal :while_label , label.name
|
||||||
end
|
end
|
||||||
def test_slot_load
|
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
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user