Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Resurrect ConcatArgs. All array compiler specs pass.
Like a nauseatingly sweet cake, the compiler currently has
3 thick layers of obfuscating logic: 1) the sexp rewriting,
2) the sexp consumption and args methods, 3) the bytecode
generation. The compiler is a bad marriage between a sexp
processor and an object-oriented compiler. All this is built
on the often confusing foundation of MRI's parse tree.

I mean, seriously, rewrite argscat into splats that are wrapped
in arrays so other nodes can take them apart again? Seriously?

So I am the divorce judge and this union is being destroyed.
Sorry, sexps, you get nothing. Dismissed. Goodbye. Objects,
you get stripped of your twisty internal logic, to the extent
reasonable. How? By creating more classes as appropriate that
each do their own simple thing.

Again, this is a WIP, but the general principle is that if a
thing needs a particular form, it should be a particular thing,
not some murky shape-shifter.
  • Loading branch information
Brian Ford committed Aug 4, 2009
1 parent c092623 commit c795d1b
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 34 deletions.
6 changes: 3 additions & 3 deletions lib/ext/melbourne/visitor.cpp
Expand Up @@ -443,9 +443,9 @@ namespace melbourne {
break;
}
case NODE_ARGSCAT: {
VALUE head = process_parse_tree(parse_state, ptp, node->nd_head, locals);
VALUE body = process_parse_tree(parse_state, ptp, node->nd_body, locals);
tree = rb_funcall(ptp, rb_sArgsCat, 3, line, head, body);
VALUE array = process_parse_tree(parse_state, ptp, node->nd_head, locals);
VALUE rest = process_parse_tree(parse_state, ptp, node->nd_body, locals);
tree = rb_funcall(ptp, rb_sArgsCat, 3, line, array, rest);
break;
}
case NODE_ARGSPUSH: {
Expand Down
64 changes: 41 additions & 23 deletions lib/melbourne/nodes.rb
Expand Up @@ -134,9 +134,17 @@ def self.from(p, args, defaults, splat)
class ArrayLiteral < Node
def self.from(p, array)
node = ArrayLiteral.new p.compiler
node.args array
node.body = array
node
end

def bytecode(g)
@body.each do |x|
x.bytecode(g)
end

g.make_array @body.size
end
end

class AttrAssign < Call
Expand Down Expand Up @@ -276,6 +284,22 @@ def nest_scope(scope)
end
end

class ConcatArgs < DynamicArguments
def self.from(p, array, rest)
node = ConcatArgs.new p.compiler
node.array = array
node.rest = rest
node
end

def bytecode(g)
@array.bytecode(g)
@rest.bytecode(g)
g.cast_array
g.send :+, 1
end
end

class ConstAccess < Node
def self.from(p, outer, name)
node = ConstAccess.new p.compiler
Expand Down Expand Up @@ -408,6 +432,12 @@ def self.from(p, str, array)
end
end

class EmptyArray < Node
def self.from(p)
EmptyArray.new p.compiler
end
end

class Ensure < Node
def self.from(p, head, ensr)
node = Ensure.new p.compiler
Expand Down Expand Up @@ -593,27 +623,6 @@ def bytecode(g)
end
end

class SLocalAssignment < LocalAssignment
def self.from(p, name, expr)
node = SLocalAssignment.new p.compiler
node.name = name
node.value = expr
node
end

def bytecode(g)
pos(g)

if @value
@value.bytecode(g)
g.cast_array
g.send :+, 1
end

@variable.set_bytecode(g)
end
end

class LocalVariable < Node
def find_local(allocate=true)
iter = find_parent Iter, ClosedScope
Expand Down Expand Up @@ -874,11 +883,20 @@ def bytecode(g)
end

class Splat < DynamicArguments
attr_accessor :value

def self.from(p, expr)
node = Splat.new p.compiler
node.args
node.value = expr
node
end

def bytecode(g)
g.make_array 0
@value.bytecode(g)
g.cast_array
g.send :+, 1
end
end

class StringLiteral < Node
Expand Down
12 changes: 4 additions & 8 deletions lib/melbourne/processor.rb
Expand Up @@ -51,8 +51,8 @@ def process_args(line, args, defaults, splat)
AST::Arguments.from self, args, defaults, splat
end

def process_argscat(line, normal, splat)
AST::ArgList.from self, normal, splat
def process_argscat(line, array, rest)
AST::ConcatArgs.from self, array, rest
end

def process_argspush(line, splat, value)
Expand Down Expand Up @@ -242,11 +242,7 @@ def process_ivar(line, name)
end

def process_lasgn(line, name, expr)
if expr.kind_of? AST::SValue
AST::SLocalAssignment.from self, name, expr
else
AST::LocalAssignment.from self, name, expr
end
AST::LocalAssignment.from self, name, expr
end

def process_lit(line, sym)
Expand Down Expand Up @@ -415,7 +411,7 @@ def process_yield(line, expr, flags)
end

def process_zarray(line)
AST::ArrayLiteral.from self, []
AST::EmptyArray.from self
end

def process_zsuper(line)
Expand Down

0 comments on commit c795d1b

Please sign in to comment.