Permalink
Browse files

And some more changes

  • Loading branch information...
1 parent 1e63e20 commit d21fcee46e1d97ed1f9d04299d916d506110fa94 @matthewd committed Nov 20, 2010
Showing with 79 additions and 41 deletions.
  1. +1 −1 bin/rasp
  2. +1 −1 lib/rasp/ast.rb
  3. +0 −1 lib/rasp/ast/block.rb
  4. +5 −5 lib/rasp/ast/expression.rb
  5. +39 −18 lib/rasp/ast/flow.rb
  6. +16 −5 lib/rasp/ast/simple.rb
  7. +7 −4 lib/rasp/compiler.rb
  8. +10 −6 lib/rasp/parser.citrus
View
2 bin/rasp
@@ -6,7 +6,7 @@ $: << File.join(File.dirname(File.dirname(__FILE__)), "lib")
require 'rasp'
-filename = 't/math.vbs'
+filename = ARGV.shift || 't/math.vbs'
parse = Rasp::Parser.parse(File.read(filename), :consume => true)
#puts parse.dump
View
2 lib/rasp/ast.rb
@@ -8,7 +8,7 @@ def self.math_op(match, op=nil)
def self.binary_op(klass, lhs, ary, op_attr=nil, attr=:rhs)
lhs = lhs.value
- ary = ary.matches
+ ary = ary.matches.dup
until ary.empty?
curr = ary.shift
rhs = curr.send(attr).value
View
1 lib/rasp/ast/block.rb
@@ -11,7 +11,6 @@ def global; self; end
def bytecode(g)
g.push_state self
statements.each do |s|
- p s
s.bytecode(g)
end
g.pop_state
View
10 lib/rasp/ast/expression.rb
@@ -25,17 +25,17 @@ class EqvOp < BinaryOp
end
class XorOp < BinaryOp
def op_bytecode(g)
- g.send :^
+ g.send :^, 1
end
end
class OrOp < BinaryOp
def op_bytecode(g)
- g.send :|
+ g.send :|, 1
end
end
class AndOp < BinaryOp
def op_bytecode(g)
- g.send :&
+ g.send :&, 1
end
end
class NotOp < UnaryOp
@@ -47,7 +47,7 @@ def initialize(operator, lhs, rhs)
@operator = operator
end
def op_bytecode(g)
- g.send @operator.to_sym
+ g.send @operator.to_sym, 1
end
end
class StringAppend < BinaryOp
@@ -63,7 +63,7 @@ def initialize(operator, lhs, rhs)
@operator = operator
end
def op_bytecode(g)
- g.send @operator.to_sym
+ g.send @operator.to_sym, 1
end
end
class UnaryPlus < UnaryOp
View
57 lib/rasp/ast/flow.rb
@@ -10,7 +10,9 @@ def bytecode(g)
top = g.new_label
top.set!
- @body.bytecode(g)
+ @body.each do |s|
+ s.bytecode(g)
+ end
g.goto top
end
end
@@ -57,24 +59,35 @@ def initialize(var, start, finish, step, body)
@var, @start, @finish, @step = var, start, finish, step
end
def bytecode(g)
- # TODO
+ # FIXME
if g.state.scope.variables.key? var
loop_var = g.state.scope.variable(var).reference
else
loop_var = g.state.scope.global.variable(var).reference
end
+
+ finish_var = Rubinius::Compiler::LocalVariable.new(g.state.scope.allocate_slot).reference
@finish.bytecode(g)
- @step.bytecode(g) if @step
+ finish_var.set_bytecode(g)
+
unless Rasp::AST::Literal === @step || @step.nil?
+ step_var = Rubinius::Compiler::LocalVariable.new(g.state.scope.allocate_slot).reference
+ dir_var = Rubinius::Compiler::LocalVariable.new(g.state.scope.allocate_slot).reference
+
+ @step.bytecode(g) if @step
g.dup
+ step_var.set_bytecode(g)
g.meta_push_0
g.send_stack :<, 1
+ dir_var.set_bytecode(g)
end
@start.bytecode(g)
loop_var.set_bytecode(g)
+
loop_body = g.new_label
loop_body.set!
+
@body.each do |s|
#s.bytecode(g)
end
@@ -83,16 +96,17 @@ def bytecode(g)
# Step is constant
if @step
- g.dup_many 2 # @step, @finish, ...
+ @step.bytecode(g)
loop_var.get_bytecode(g)
g.send_stack :+, 1
else
- g.dup # @finish, ...
loop_var.get_bytecode(g)
g.send_vcall :inc
end
g.dup
loop_var.set_bytecode(g)
+ finish_var.get_bytecode(g)
+ g.swap
if @step.nil? || @step.value > 0
# Always working forwards
@@ -107,11 +121,7 @@ def bytecode(g)
g.gif loop_body
- if @step
- g.pop_many 2
- else
- g.pop
- end
+ # finish_var is done now; can we get rid of it?
else
raise "dynstep!"
# Dynamic step; have to work out which way we're going at runtime
@@ -127,13 +137,16 @@ def bytecode(g)
check_backwards = g.new_label
end_loop = g.new_label
- g.dup_many 3 # loop_backwards, @step, @finish, ...
+ finish_var.get_bytecode(g)
+ step_var.get_bytecode(g)
loop_var.get_bytecode(g)
g.send_stack :+, 1
g.dup
loop_var.set_bytecode(g)
+ dir_var.get_bytecode(g)
g.git check_backwards
+
g.send_stack :>, 1
g.gif loop_body
g.goto end_loop
@@ -143,7 +156,6 @@ def bytecode(g)
g.gif loop_body
end_loop.set!
- g.pop_many 3
end
end
end
@@ -165,19 +177,28 @@ def initialize(condition, true_body, false_body)
end
def bytecode(g)
- done = g.new_label
false_label = g.new_label
@condition.bytecode(g)
g.giz false_label
- @true_body.bytecode(g)
- g.goto done
+ @true_body.each do |s|
+ s.bytecode(g)
+ end
- false_label.set!
- @false_body.bytecode(g)
+ if @false_body && @false_body.size > 0
+ done = g.new_label
+ g.goto done
- done.set!
+ false_label.set!
+ @false_body.each do |s|
+ s.bytecode(g)
+ end
+
+ done.set!
+ else
+ false_label.set!
+ end
end
end
View
21 lib/rasp/ast/simple.rb
@@ -3,9 +3,20 @@ module Rasp::AST
class Statement < Node
end
class Assignment < Statement
- attr_accessor :var, :value
- def initialize(var, value)
- @var, @value = var, value
+ attr_accessor :var, :newval
+ def initialize(var, newval)
+ @var, @newval = var, newval
+ end
+ def bytecode(g)
+ if g.state.scope.variables.key? var
+ ref = g.state.scope.variable(var).reference
+ else
+ ref = g.state.scope.global.variable(var).reference
+ end
+
+ @newval.bytecode(g)
+ ref.set_bytecode(g)
+ g.pop
end
end
class SetAssignment < Assignment
@@ -16,8 +27,8 @@ def bytecode(g)
raise "Duplicate constant: #@var"
end
- # @value is syntactically guaranteed to be a Literal.
- g.constants[@var] = @value.value
+ # @newval is syntactically guaranteed to be a Literal.
+ g.constants[@var] = @newval.value
end
end
class Declaration < Statement
View
11 lib/rasp/compiler.rb
@@ -39,6 +39,9 @@ def compile(ast, filename="(rasp)", line_number=1)
g.ret
g.close
+ g.local_count = ast.local_count
+ g.local_names = ast.local_names
+
g.encode
cm = g.package ::Rubinius::CompiledMethod
puts cm.decode if $DEBUG
@@ -59,20 +62,20 @@ def initialize
end
def giz(label)
- dup_top
+ dup
gif label
meta_push_0
- meta_send_op_eq find_literal(:==)
+ meta_send_op_equal find_literal(:==)
git label
end
def gnz(label)
f = new_label
- dup_top
+ dup
gif f # if it's false, don't compare to zero; just continue
meta_push_0
- meta_send_op_eq find_literal(:==)
+ meta_send_op_equal find_literal(:==)
gif label
f.set!
View
16 lib/rasp/parser.citrus
@@ -69,7 +69,7 @@ grammar Rasp::Parser
`for` SP `each` SP identifier SP `in` SP expression ENDSTATEMENT statement* `next` ENDSTATEMENT
end
rule do_loop
- (`do` ENDSTATEMENT statement* `loop` ENDSTATEMENT
+ ((`do` ENDSTATEMENT body:statement* `loop` ENDSTATEMENT) { Rasp::AST::Loop.new :do, body.matches.map {|m| m.value }.compact }
|`do` SP (`while` | `until`) SP expression ENDSTATEMENT statement* `loop` ENDSTATEMENT
|`do` ENDSTATEMENT statement* `loop` SP (`while` | `until`) SP expression ENDSTATEMENT
|`while` SP expression ENDSTATEMENT statement* `wend` ENDSTATEMENT
@@ -80,7 +80,11 @@ grammar Rasp::Parser
{ Rasp::AST::ForLoop.new(identifier.value, start.value, finish.value, first(:step) && first(:step).value, body.matches.map {|m| m.value }) }
end
rule single_line_if
- `if` SP expression SP `then` SP (single_line_if | simple_statement_chain (SP `else` SP (single_line_if | simple_statement_chain EOL) | EOL) )
+ (`if` SP expression SP `then` SP truepart:(single:single_line_if { [single] } | list:simple_statement_chain) (SP `else` SP falsepart:(single:single_line_if | list:simple_statement_chain EOL) | EOL) )
+ {
+ false_list = first(:falsepart) && (falsepart.first(:single) ? [falsepart.single.value] : falsepart.list.value)
+ Rasp::AST::If.new(expression.value, truepart.value, false_list)
+ }
end
rule full_if_block
`if` SP expression SP `then` ENDSTATEMENT statement*
@@ -89,7 +93,7 @@ grammar Rasp::Parser
`end` SP `if` ENDSTATEMENT
end
rule simple_statement_chain
- (simple_statement SP? ":" SP?)* simple_statement
+ ((simple_statement SP? ":" SP?)* simple_statement) { find(:simple_statement).map {|s| s.value } }
end
rule simple_statement
(assignment
@@ -108,10 +112,10 @@ grammar Rasp::Parser
| (`on` SP `error` SP `goto` SP "0") { Rasp::AST::ErrorControl.new(false) }
end
rule exit_statement
- (`exit` SP type:(`sub` | `function` | `property` | `do` | `for`)) { Rasp::AST::ExitStatement.new type.downcase.to_sym }
+ (`exit` SP extype:(`sub` | `function` | `property` | `do` | `for`)) { Rasp::AST::ExitStatement.new extype.downcase.to_sym }
end
rule assignment
- (objvalue SP? "=" SP? expression
+ ((objvalue SP? "=" SP? expression) { Rasp::AST::Assignment.new(objvalue.value.name, expression.value) }
|`set` SP objvalue SP? "=" SP? expression
)
end
@@ -266,7 +270,7 @@ grammar Rasp::Parser
/[+-]?[0-9]+/ { Rasp::AST::Integer.new to_i }
end
rule float
- /[0-9]+.[0-9]+/ { Rasp::AST::Float.new to_f }
+ /[0-9]+\.[0-9]+/ { Rasp::AST::Float.new to_f }
end
rule string
/"([^"]|"")*"/ { Rasp::AST::String.new to_s }

0 comments on commit d21fcee

Please sign in to comment.