2 # See compiler.rb for more information about the Compiler mode of
9 # Node is the representation of a node in the Abstract Syntax Tree
10 # (AST) of the Ruby code. It is typically fairly close in structure
11 # to the sexp produced by the parser but there are some transforms
12 # that are done at this stage:
14 # 1. Compiler special forms, such as Rubinius.asm which allows
15 # inline Rubinius "assembly" code. See plugins.rb for more of
17 # 2. Combining redundant and removing obsolete nodes from the tree.
18 # The current parser is still mostly MatzRuby's and therefore
19 # contains some artifacts that we have no need for.
20 # 3. Optimizations. At this time, there are not that many nor will
21 # there ever be huge amounts.
22 # 4. Sexp transformations, somewhat akin to Lisp macros. These
23 # allow modifying the sexp, and therefore the code produced,
24 # as it is being compiled. The mechanism is currently very raw
25 # and the only transform supported is conditional compilation
26 # (e.g. not including debug statements in the bytecode at all.)
27 # Look for Rubinius.compile_if.
29 # The compiler is based on the Visitor pattern, and this stage is no
30 # different. First, for every type of sexp node possible in Ruby code,
31 # one of these Node subclasses will provide a handler (even if to just
32 # skip over the node.) The #kind method provides this mapping; for
33 # example, the Iter node is kind :iter. The nodes register the kinds
34 # they provide for lookups.
36 # The general model is simple. Each node has a #consume method, it
37 # may either be the default one defined in Node or a custom one if one
38 # is needed. When the sexp is fed here, the kind mapping is used to
39 # determine the kind of Node to construct, and the rest of the sexp is
40 # fed to it. Typically the Node then goes through what is next in the
41 # sexp, asking each layer to construct itself and #consume anything
42 # even further down the chain all the way until nothing of the sexp
43 # remains. At this point those recursive calls start rolling back up
44 # higher and higher, and the Nodes at each layer compose themselves of
45 # the constituent parts they get back from in exchange for the sexp
46 # they provided. Verification happens here, to ensure the AST is sane.
47 # Most optimization occurs at the point before the sub-sexp would be
48 # processed; for example a normal Call node (:call is the normal
49 # method call representation) would have its arguments and body sent
50 # for processing, but if the Call detects a special form starting with
51 # +Rubinius+, it produces the special code for that instead and may
52 # even completely omit processing parts of the sexp that a normal
55 # Some Node classes are a bit fancier in their #consume: ClosedScope
56 # Node subclasses manage a scope for local variables and so on, for
57 # example. The basic idea of having its children produce the subtree
58 # underneath it and then organising those bits to send back to its
59 # parent in turn is still the same, they just have additional things
60 # they are responsible for.
62 # In the end, the caller will be left with a single top-level Node
63 # object (usually a Script) which then hierarchically contains the
64 # rest of the AST. This object graph can then be passed on to the
65 # bytecode producer. See bytecode.rb for that.
70 def self.kind(name=nil)
71 return @kind unless name
76 def self.create(compiler, sexp)
81 # Anywhere within, a piece of code may throw the symbol for the
82 # node type that it wishes to unwind the processing branch to.
83 # If this happens, then the thrown substitute value (defaulting
84 # to nil) is returned instead of the normal node product.
86 # For example, Call#consume can detect the Rubinius.compile_if
87 # construct and throw :newline which causes this method's return
88 # value to be nil. So this Newline and the entire rest of the
89 # expression are replaced by a nil output, which should be
90 # then handled or optimized away by the node upstream (usually
93 # Whoever uses the throw MUST ensure that the sexp and the AST
94 # are in a sane state. We do not worry about it here.
96 args = node.consume(sexp)
99 if node.respond_to? :normalize
100 node = node.normalize(*args)
104 rescue ArgumentError => e
105 raise ArgumentError, "#{kind} (#{self}) takes #{args.size} argument(s): passed #{args.inspect} (#{e.message})", e.context
112 def initialize(compiler)
120 @compiler.convert_sexp(x)
124 # This lets nil come back from convert_sexp which means
125 # leave it out of the stream. This is primarily so that
126 # expressions can be optimized away and wont be seen at
127 # all in the output stream.
131 v = @compiler.convert_sexp(x)
132 out << v unless v.nil?
148 def set(tag, val=true, &b)
149 @compiler.set(tag, val, &b)
153 kind = self.class.kind
155 prefix = "Compiler:#{self.class.kind}"
157 prefix = self.class.name
169 obj.nil? ? Nil.new(@compiler) : obj
172 def use_plugin(g, kind, *args)
173 @compiler.plugins[kind].find do |plug|
174 plug.handle(g, self, *args)
178 #--- Start of Node subclasses
180 # ClosedScope is a metanode in that it does not exist in Ruby code;
181 # it merely abstracts common functionality of various real Ruby nodes
182 # that must control a local variable scope. These classes will exist
183 # as subclasses of ClosedScope below.
185 # Most notably, LocalScope objects are kept to maintain a hierarchy
186 # of visibility and availability for the runtime.
187 class ClosedScope < Node
193 @top_scope = create_scope()
195 @all_scopes = [@top_scope]
198 @visibility = :public
201 attr_accessor :visibility
207 attr_accessor :use_eval
217 def consume(sexp, iter=false, eval=false)
218 set(:scope => self, :iter => iter, :eval => eval) do
219 out = convert(sexp[0])
220 @all_scopes.each do |scope|
233 scope = create_scope()
234 @block_scope << scope
244 def find_local(name, in_block=false, allocate=true)
245 # If the caller is not in a block, things can only
246 # be in the top_context. Easy enough, return out of the Hash
247 # (which might created in for us automatically)
249 if allocate or @top_scope.key?(name)
250 return [@top_scope[name], nil]
256 # They're asking from inside a block, look in the current
257 # block scopes as well as top_scope
259 if @block_scope.empty?
260 raise Error, "You can't be in a block, there are no block scopes"
267 @block_scope.reverse_each do |scope|
280 # Not found in an outstanding block scope, look in the
283 if @top_scope.key?(name)
284 lcl = @top_scope[name]
288 # This not found. create it.
289 in_scope = @block_scope.last
292 lcl.created_in_block!(idx)
293 if in_scope.from_eval
306 def find_ivar_index(name)
310 def add_ivar_as_slot(name, slot)
311 @ivar_as_slot["@#{name}".to_sym] = slot
315 return nil if @use_eval
316 # This is correct. the first one is 1, not 0.
331 # Snippit was a special type of a scope, not exactly a Script but
332 # not something else either. Currently it only provides abstract
333 # support for eval, for example.
335 class Snippit < ClosedScope
338 def consume(sexp, iter=false, eval=false)
339 set(:family, self) do
340 super(sexp, iter, eval)
351 class Expression < Snippit
355 # EvalExpression is a special node and does not appear in the Ruby
356 # parse tree itself. It is inserted as the top-level scope when an
357 # eval is run, which allows managing the specialized behaviour that
360 class EvalExpression < Expression
361 kind :eval_expression
364 super(sexp, @in_iter, true)
374 unless comp.custom_scopes?
375 raise ArgumentError, "only use with custom scopes"
378 @top_scope, @block_scope, @all_scopes, @context = comp.create_scopes
379 @slot = @top_scope.size
381 if @block_scope.empty?
382 @my_scope = @top_scope
385 @my_scope = @block_scope.last
389 # Setup stuff so allocate_slot works
390 @my_scope.scope = self
391 @slot = @my_scope.size
395 locals = @context.locals
398 if @my_scope.size > 0
399 @context.locals = Tuple.new(@my_scope.size)
400 @context.method.local_names = @my_scope.encoded_order
402 elsif @my_scope.size > locals.size
403 @context.locals = locals.enlarge(@my_scope.size)
404 @context.method.local_names = @my_scope.encoded_order
410 # Script is a special node, and does not exist in normal Ruby code.
411 # It represents the top-level of a .rb file, and as such is the most
412 # common top-level container.
414 class Script < ClosedScope
428 # Newline handles :newline nodes, which are inserted by the parser to
429 # allow keeping track of the file and line a certain sexp was produced
430 # from. In addition to that metadata, it contains within it a Block of
431 # the actual Ruby code (as sexp) that makes up that particular line.
433 # Sexp tag: +:newline+
439 @compiler.set_position sexp[1], sexp[0]
443 def args(line, file, child=nil)
444 @line, @file, @child = line, file, child
447 attr_accessor :line, :file, :child
454 # True is the literal +true+.
467 # False is the literal +false+.
480 # Nil is the literal +nil+.
493 # Self is the literal +self+.
506 # And represents either +and+ or +&&+.
507 # The precedence difference between the
508 # two has been resolved by the parser so
509 # both types map into this one node (but
510 # their child and parent nodes could be
513 # It contains both the left and the right
529 def args(left, right)
530 @left, @right = left, right
533 attr_accessor :left, :right
536 # Or represents either +or+ or +||+.
537 # The precedence difference between the
538 # two has been resolved by the parser so
539 # both types map into this node although
540 # their contexts (parents and children)
543 # It contains both the left and the right
560 # Not is either +not+ or +!+. The precedence
561 # has been resolved by the parser, the two
562 # types may have different parents and children
563 # because of it, though.
565 # It contains the expression to negate.
587 # Negate represents a negative numeric literal.
588 # It contains the Ruby object for the absolute
589 # value, the node itself is used as the negative
592 # Sexp tag: +:negate+
609 # NumberLiteral is generated from a Literal node that
610 # represents a Fixnum literal as a convenience. It
611 # contains the actual number in a Ruby Fixnum. These
612 # are positive numbers only; a combination of Negate
613 # and Literal is used for negatives.
622 class NumberLiteral < Node
632 # Literal is the default representation of any literal
633 # object value in the code, such as a number representing
634 # a Float. Fixnums and Regexps are delegated to be processed
635 # by NumberLiteral and RegexLiteral respectively, but any
636 # other is contained within as an object.
638 # The remaining literals will also have special treatment
639 # in that they are stored in the Literals Tuple of the
640 # CompiledMethod so that they are accessible to runtime
661 nd = NumberLiteral.new(@compiler)
665 nd = RegexLiteral.new(@compiler)
666 nd.args(value.source, value.options)
676 # RegexLiteral is a regular expression literal.
677 # It is usually generated directly but may also
678 # be delegated to by Literal. Each RegexLiteral
679 # contains the source (which is actually a String)
680 # and a Fixnum representing the regexp options in
681 # effect. These two bits of information are used
682 # to create the actual object through Regexp.new
685 # Sexp tag: +:regex+ (Note missing "p.")
689 # puts "matched" if /foo/ =~ variable
692 class RegexLiteral < Node
695 def args(source, options)
696 @source, @options = source, options
699 attr_accessor :source, :options
702 # StringLiteral is a nondynamic string literal.
703 # It contains the Ruby String object corresponding
704 # to the real given character sequence. Since these
705 # objects are stored in the Literals Tuple, you will
706 # often see bytecode that performs a +string_dup+,
707 # which just makes a copy of the stored one so that
708 # the user can modify his version.
717 class StringLiteral < Node
724 attr_accessor :string
728 # DynamicString is a dynamic string literal; i.e.,
729 # one with an interpolated component. There are a
730 # few notable things: the parser will process any
731 # interpolations which themselves contain a string
732 # literal into a plain string literal instead of
733 # a dynamic string. The latter will only be in
734 # effect for variable interpolation etc.
736 # Each dynamic string consists of two things: string
737 # literals for the nondynamic parts and :evstr nodes
738 # for the parts that need to be evaluated. The :dstr
739 # node itself contains the starting literal (if any),
740 # but all subsequent ones appear as additional :str
741 # nodes interspersed with :evstrs. The :evstr nodes
742 # are any executable code, so they will eventually
743 # be unwrapped and the sexp there translated to AST.
749 # puts "Hi #{name}, howzit?"
750 # ^^^^^^^^^^^^^^^^^^^^^
755 # , [:evstr, [:vcall, :name]]
756 # , [:str, ", howzit?"]
760 class DynamicString < StringLiteral
771 # DynamicRegex is a dynamic regexp literal, i.e.
772 # one with an interpolated component. These behave
773 # the same as DynamicStrings (they actually use :str
774 # and :evstr nodes also), please see above for a more
775 # thorough explanation.
783 class DynamicRegex < DynamicString
793 # DynamicOnceRegex is identical to DynamicRegex, with
794 # the exception that the interpolation is only run once.
795 # This is done using the +o+ flag to the literal. Please
796 # see DynamicRegex for more detailed documentation.
798 # Sexp tag: +:dregx_once+
802 # /a#{b}c/o # Note the +o+ option
804 class DynamicOnceRegex < DynamicRegex
808 # Implicit regexp matching node. A Match is created if
809 # there is a regexp literal in a condition without an
810 # object to match against (or indeed the matching op.)
811 # Ruby allows this form to match against +$_+ which is
812 # a predefined global always set to the last line of
813 # input read into the program.
820 # puts "Uh-uh, you said 'foo'" if /foo/
826 # Essentially same as :match2, just using $_
828 pattern = RegexLiteral.new @compiler
829 pattern.args *sexp # Pattern, options
831 last_input = GVar.new @compiler
832 last_input.name = :$_
834 [pattern, last_input]
837 def args(pattern, target)
838 @pattern, @target = pattern, target
841 attr_accessor :pattern, :target
844 # Match2 is a regexp match where the regexp literal is on the
845 # left hand side of the match operator. This node is generated
846 # any time such an event occurs. Naturally, the parser is not
847 # able to determine whether a variable is a Regexp, so it only
848 # works with a regexp literal. See also Match3.
850 # Sexp tag: +:match2+
854 # /this/ =~ "matches this"
860 def args(pattern, target)
861 @pattern, @target = pattern, target
864 attr_accessor :pattern, :target
867 # Match3 is a regexp match where the regexp literal is on the
868 # right hand side of the match operator. This node is generated
869 # any time such an event occurs. Naturally, the parser is not
870 # able to determine whether a variable is a Regexp, so it only
871 # works with a regexp literal. See also Match2.
873 # Sexp tag: +:match3+
877 # "this matches" =~ /this/
883 def args(pattern, target)
884 @pattern, @target = pattern, target
887 attr_accessor :target, :pattern
890 # BackRef is any one of the predefined (thread-) global variables
891 # that are set after each regexp match operation, except the numbered
892 # ones. A BackRef can be $`, $', $& etc. The second character is
893 # stored to create the entire variable. See also NthRef.
895 # Sexp tag: +:back_ref+
899 # /fo(o)/ =~ variable
908 @kind = kind.chr.to_sym
914 # NthRef is one of the numbered groups from the last regexp match.
915 # The node contains the numeric value, which will then be combined
916 # with $ to make the global at runtime. Technically there is no
917 # limitation (up to the thousands) on the number of backrefs but
918 # Win32 does limit it to 10. See also BackRef for the other regexp
919 # match automatic (thread-) globals.
921 # Sexp tag: +:nth_ref+
925 # /(f)oo/ =~ variable
940 # If is the safe and familiar conditional as well as
941 # the inverse: +unless+. The parser simply constructs
942 # a negated version of the +if+ on those occasions.
943 # The contents are the condition expression as well
944 # as the expressions for then and else.
950 # if true; puts "hi"; end
956 def args(cond, thn, els)
957 @condition, @then, @else = cond, thn, els
960 attr_accessor :condition, :then, :else
963 # While is the standard conditional looping construct.
964 # It contains the condition itself as well as the body
965 # to run; in addition, it may also indicate that the
966 # condition should be checked before or after the first
967 # loop, default of course being before. The syntax for
974 # # Condition first (optionally add +do+ after the condition.)
980 # # Run once first. +end+ and +while+ must be on the same line
989 def args(cond, body, check_first=true)
990 @condition, @body, @check_first = cond, expand(body), check_first
993 attr_accessor :condition, :body, :check_first
996 # Until is same as a +while not+. See While for further
997 # documentation. May also be used pre- or postcondition.
1003 # # Condition first (optionally add +do+ after the condition.)
1009 # # Run once first. +end+ and +until+ must be on the same line
1019 # +Block+ is a special node: it is part of Ruby's semantics rather than
1020 # syntax. Notably, a Block is NOT a Ruby block (a Proc object.) A Block
1021 # simply encapsulates multiple expressions into a group. For example, an
1022 # +if+ expression that has a single line inside it does not have a Block,
1023 # but one that has two lines will have both of those lines encapsulated
1024 # inside a Block. It has no fancy purpose apart from grouping.
1026 # Sexp tag: +:block+
1032 # baz < These will all be inside the :block
1036 # Sexp from example (Newline nodes omitted):
1057 # +Scope+ is another special node type. It represents the scope
1058 # inside a logical Ruby unit such as a method definition or a
1059 # class definition. Curiously, though, the Scope is not where
1060 # the variable scoping etc. happens: for that, see ClosedScope
1061 # and its subclasses. For example in a method definition, the
1062 # Define node itself is the ClosedScope, but it in turn has a
1063 # Scope object encapsulated inside. To make things stranger,
1064 # the Scope object itself contains the Block of code (method
1065 # body, for example) but _also the names of local variables_
1066 # inside that code block. The locals are *actually* managed
1067 # by the ClosedScope, though. So for the purposes of Rubinius
1068 # compilation, you can sort of ignore the Scope node except
1069 # for its semantic meaning.
1071 # Sexp tag: +:scope+
1076 # ... < Scope object created inside the Define
1083 if sexp.size == 1 or sexp[0].nil?
1087 # Handle def self.foo; end, which unlike def foo; end does not generate a block
1088 if sexp[0].first == :args
1089 sexp[0] = [:block, sexp[0], [:nil]]
1092 sexp[0] = convert(sexp[0])
1096 def args(block, locals)
1097 @block, @locals = block, locals
1100 attr_accessor :block, :locals
1107 # +Arguments+ is for the representation of a method _definition's_
1108 # argument list. It contains four sub-nodes, one each for required
1109 # args, optional args, splat name and default value expressions. A
1110 # block argument is actually not noted at this level because in the
1111 # sexp, it is a sibling to this node, all contained inside the method
1112 # definition. The block argument is added to the node later by the
1113 # Define node in its normalisation process.
1115 # There are a few interesting details: because default values can
1116 # be any expressions (try it, you can use a block, a class, define
1117 # another function etc.), the entire expression subtree is stored.
1118 # The optional arguments are just the variable names, and the values
1119 # are first processed into their own little AST subtrees which are
1120 # then stored in a mapping whence they may be executed at runtime
1121 # if the default value is needed.
1123 # The Arguments node performs quite a bit of other normalisation
1124 # also, as well as coordinating setting up the arguments as local
1125 # variables with the appropriate LocalScope and providing the
1126 # arity calculation for this method. See further documentation
1127 # about those operations in the individual methods of Arity.
1133 # def foo(a, b = lambda { :moo }, *c, &d)
1134 # ^^^^^^^^^^^^^^^^^^^^^^^^^^
1135 # These go in the node.
1136 # Block arg processed
1141 class Arguments < Node
1144 # [[:obj], [], nil, nil]
1145 # required, optional, splat, defaults
1149 return [[], [], nil, nil]
1152 # Strip the parser calculated index of splat
1153 if sexp[2] and !sexp[2].empty?
1154 sexp[2] = sexp[2].first
1162 defaults.map! do |node|
1163 # HACK: Fix parse_tree bug when an optional arg has a default value
1164 # that is an :iter. For example, the following:
1165 # def foo(output = 1, b = lambda {|n| output * n})
1166 # generates a sexp where the optional args are [:output, :n], rather
1167 # than [:output, :b]. To fix this, we pick up the name of the :lasgn,
1168 # in the defaults, and set the corresponding optional arg if the
1169 # :lasgn is an :iter.
1170 type = node[2].first rescue nil
1186 def args(req, optional, splat, defaults)
1188 @required, @optional, @splat, @defaults = req, optional, splat, defaults
1190 # The splat has no name, so give it a name that a user can't actually
1191 # give, so that we can still use it (ie, for super)
1192 if @splat.kind_of? TrueClass
1193 @splat = :@anon_splat
1199 attr_accessor :required, :optional, :splat, :defaults, :block_arg
1202 if !@optional.empty? or @splat
1203 return -(@required.size + 1)
1206 return @required.size
1213 @required.map! do |var|
1214 var, depth = scope.find_local(var)
1220 @optional.map! do |var|
1221 var, depth = scope.find_local(var)
1222 var.argument!(i, true)
1227 if @splat.kind_of? Symbol
1228 var, depth = scope.find_local(@splat)
1229 var.argument!(i, true)
1233 @mapped_defaults = {}
1236 @defaults.each do |x|
1237 @mapped_defaults[x.name] = x
1244 # +Undef+ is the keyword +undef+, #undefine_method does not have any
1245 # special handling that would make it processable here and thus is
1246 # just a normal method call. Two data are retained: first naturally
1247 # the name of the method in question which can be either just the name
1248 # as a plain identifier or given as a Symbol. The other information
1249 # is whether the undef occurs inside a Module definition scope. The
1250 # undef keyword is somewhat surprising in its behaviour: it always
1251 # tries to undefine the given method in the module that the line is
1252 # _lexically_ enclosed in, so this must be known for the cases it is
1253 # used outside the Module definition scopes. This also excludes any
1254 # use in the block form of Module.new, which may be surprising altough
1255 # consistent with closure behaviour.
1257 # Sexp tag: +:undef+
1272 if scope.is? Node::Class or scope.is? Node::Module
1279 attr_accessor :name, :in_module
1287 if @in_block = get(:iter)
1288 @check_var, _ = get(:scope).find_local :@lre
1292 attr_accessor :value, :in_block
1310 def args(cond, body = nil)
1311 @body = expand(body)
1315 if cond.is? ArrayLiteral
1316 cond.body.each do |c|
1317 # Inner when means splat.
1322 @splat = c.conditions
1333 attr_reader :body, :conditions, :splat
1343 [convert(sexp[0]), sexp[1], convert(sexp[2])]
1346 def args(recv, whens, els)
1347 @receiver, @whens, @else = recv, whens, els
1354 attr_accessor :receiver, :whens, :else
1357 # ManyIf represents a case statement with no receiver, i.e.
1364 # :many_if contains an array of whens and an else
1365 # the whens are in turn an array of condition expressions,
1366 # followed by a body
1373 [whens, convert(sexp[1])]
1376 def args(whens, els)
1385 attr_accessor :whens, :else
1388 class LocalVariable < Node
1396 @variable, @depth = scope.find_local name, true
1398 @variable, @depth = scope.find_local name
1408 def from_variable(var, depth=nil)
1416 class LocalAssignment < LocalVariable
1419 def args(name, val=nil)
1420 # val will be nil if this is e.g. an lasgn inside an masgn
1427 attr_accessor :name, :value, :variable
1429 def from_variable(var, value=nil)
1444 class LocalAccess < LocalVariable
1462 attr_accessor :child
1465 class OpAssignOr < Node
1468 def args(left, right)
1469 @left, @right = left, right
1472 attr_accessor :left, :right
1475 class OpAssignAnd < OpAssignOr
1479 class OpAssign1 < Node
1483 # Value to be op-assigned is always first element of value
1484 sexp[2].shift # Discard :array token
1485 val = convert(sexp[2].shift)
1486 # Remaining elements in value are index args excluding final nil marker
1488 while sexp[2].size > 1 do
1489 idx << convert(sexp[2].shift)
1491 [convert(sexp[0]), sexp[1], idx, val]
1494 def args(obj, kind, index, value)
1495 @object, @kind, @index, @value = obj, kind, index, value
1498 attr_accessor :object, :kind, :value, :index
1501 class OpAssign2 < Node
1504 def args(obj, method, kind, assign, value)
1505 @object, @method, @kind, @value = obj, method, kind, value
1511 @assign = str.to_sym
1515 attr_accessor :object, :method, :kind, :assign, :value
1518 class ArrayLiteral < Node
1521 # We do this to get around having to do *body in
1522 # args. 1024 is the max number of args, so if an
1523 # array had more elements that than, args would
1524 # get an args error. This lets us leave it as an
1527 sexp.map! { |s| convert(s) }
1538 class EmptyArray < Node
1542 class HashLiteral < Node
1552 class ImplicitHash < HashLiteral
1556 class DynamicArguments < Node
1559 class Splat < DynamicArguments
1566 attr_accessor :child
1570 class ConcatArgs < DynamicArguments
1573 def args(rest, array)
1576 if rest.kind_of? Array # When does this happen?
1583 attr_accessor :array, :rest
1586 class PushArgs < DynamicArguments
1589 def args(array, item)
1591 unless array.is? Splat
1592 raise Error, "Unknown form of argspush: #{array.class}"
1595 @array = array.child
1598 attr_accessor :array, :item
1601 class AccessSlot < Node
1609 class SetSlot < Node
1611 @index, @value = idx, val
1614 attr_reader :index, :value
1622 if fam and idx = fam.find_ivar_index(name)
1623 ac = AccessSlot.new @compiler
1636 class IVarAssign < Node
1639 def normalize(name, val=nil)
1641 if fam and idx = fam.find_ivar_index(name)
1642 ac = SetSlot.new @compiler
1660 attr_accessor :name, :value
1673 class GVarAssign < Node
1676 def args(name, value=nil)
1677 @name, @value = name, value
1680 attr_accessor :name, :value
1691 class ConstFind < Node
1701 class ConstAccess < Node
1704 def args(parent, name)
1705 @parent, @name = parent, name
1708 attr_accessor :parent, :name
1710 def normalize(one, two=nil)
1715 node = ConstFind.new(@compiler)
1723 class ConstAtTop < Node
1733 class ConstSet < Node
1736 def args(simp, val, complex)
1743 elsif complex.is? ConstAtTop
1745 @name = complex.name
1747 @parent = complex.parent
1748 @name = complex.name
1752 attr_accessor :from_top, :parent, :value, :name
1755 class ToArray < Node
1762 attr_accessor :child
1765 class SClass < ClosedScope
1769 @object, @body = obj, body
1773 [convert(sexp[0]), super([sexp[1]])]
1776 attr_accessor :object, :body
1779 class Class < ClosedScope
1782 def args(name, parent, sup, body)
1783 @name, @parent, @superclass, @body = name, parent, sup, body
1787 name = convert(sexp[0])
1790 if name.is? ConstFind or name.is? ConstAtTop
1793 parent = name.parent
1796 # We have to set this before converting the body, because
1797 # we'll need to know it to use find_ivar_index properly.
1799 if sup and sup[0] == :const
1800 @superclass_name = sup[1]
1802 @superclass_name = nil
1806 @namespace = get(:namespace)
1808 body = set(:family => self, :namespace => sym) do
1812 [sym, parent, convert(sexp[1]), body]
1815 attr_accessor :name, :parent, :superclass, :body
1817 def find_ivar_index(name)
1822 if tbl = Bootstrap::HINTS[@name]
1824 elsif @superclass_name
1825 if tbl = Bootstrap::HINTS[@superclass_name]
1839 class Module < ClosedScope
1842 def args(name, parent, body)
1843 @name, @parent, @body = name, parent, body
1847 name = convert(sexp[0])
1850 if name.is? ConstFind
1852 elsif name.is? ConstAtTop
1855 parent = name.parent
1858 body = set(:namespace, sym) do
1865 attr_accessor :name, :body, :parent
1882 class RescueCondition < Node
1885 def args(cond, body, nxt)
1886 @body, @next = body, nxt
1888 cf = ConstFind.new(@compiler)
1889 cf.args :StandardError
1891 elsif cond.is? ArrayLiteral
1892 @conditions = cond.body
1894 elsif cond.is? Splat
1897 elsif cond.is? ConcatArgs
1898 @conditions = cond.rest
1901 raise Error, "Unknown rescue condition form"
1905 @body = Nil.new(@compiler)
1909 attr_accessor :conditions, :splat, :body, :next
1915 def args(body, res, els)
1916 @body, @rescue, @else = body, res, els
1920 body, res, els = *sexp
1929 if body.first == :resbody
1938 body = convert(body)
1945 body = convert(body)
1955 attr_accessor :body, :rescue, :else
1958 class Defined < Node
1964 expr[1] = convert(expr[1])
1974 attr_accessor :expression
1982 set(:in_ensure, opts) do
1983 sexp[0] = convert(sexp[0])
1986 # Propagate did_return up to an outer ensure
1987 if ens = get(:in_ensure)
1988 ens[:did_return] = opts[:did_return]
1994 [sexp[0], convert(sexp[1]), opts[:did_return], outer]
1997 def args(body, ens, ret, outer)
1998 @body, @ensure = body, ens
2000 @outer_ensure = outer
2002 if @in_block = get(:iter)
2003 @check_var, _ = get(:scope).find_local :@lre
2006 # Handle a 'bug' in parsetree
2007 if @ensure == [:nil]
2012 attr_accessor :body, :ensure, :did_return, :outer_ensure
2020 @in_rescue = get(:in_rescue)
2022 if ens = get(:in_ensure)
2023 ens[:did_return] = true
2029 if @in_block = get(:iter)
2030 @check_var, _ = get(:scope).find_local :@lre
2034 attr_accessor :value, :in_rescue, :in_ensure, :in_block, :check_var
2040 def args(assigns, splat, source=:bogus)
2041 if source == :bogus # Only two args supplied, therefore no assigns
2046 @assigns, @splat, @source = assigns, splat, source
2052 attr_accessor :assigns, :splat, :source, :in_block
2055 @assigns.nil? and (@splat.equal?(true) or @splat.nil?)
2059 return [] if splat.equal?(true) or splat.nil?
2064 return [] if assigns.nil?
2065 assigns.body.map { |i| i.kind_of?(MAsgn) ? i.required : i.name }.flatten
2069 class Define < ClosedScope
2074 scope = set(:iter => false, :in_ensure => false) do
2078 body = scope.block.body
2081 if body.first.is? BlockAsArgument
2089 return [name, scope, args]
2092 def args(name, body, args)
2093 @name, @body, @arguments = name, expand(body), args
2096 attr_accessor :name, :body, :arguments
2099 class DefineSingleton < Define
2105 out.unshift convert(object)
2110 def args(obj, name, body, args)
2113 super(name, body, args)
2116 attr_accessor :object
2119 class MethodCall < Node
2121 def initialize(comp)
2127 elsif scope.is? Module
2129 elsif scope.is? Script
2137 if obj.kind_of? Iter
2138 @check_var, _ = get(:scope).find_local :@lre
2144 attr_reader :block, :check_var
2145 attr_accessor :scope
2148 class Call < MethodCall
2151 # Args could be an array, splat or argscat
2153 @in_block = get(:iter)
2155 return unless @arguments
2157 if @arguments.is? ArrayLiteral
2158 @arguments = @arguments.body
2159 @argcount = @arguments.size
2165 # Rubinius.compile_if is easiest to detect here; if it is found,
2166 # we throw immediately to unwind this processing branch back to
2167 # wherever it is that the conditional compiler wants us to go.
2170 use_plugin self, :conditional_compilation, sexp
2174 def args(object, meth, args=nil)
2175 @object, @method, @arguments = object, meth, args
2180 attr_accessor :object, :method, :arguments, :argcount
2181 attr_reader :in_block
2184 @arguments.nil? or @arguments.empty?
2188 @arguments.nil? or @arguments.kind_of? Array
2202 elsif @arguments.kind_of? Array
2203 return @arguments.size
2213 def normalize(meth, args=nil)
2214 @method, @arguments = meth, args
2218 return detect_special_forms()
2221 attr_accessor :method, :arguments
2223 def detect_special_forms
2224 # Detect ivar as index.
2225 if @method == :ivar_as_index
2227 if args.size == 1 and args[0].is? ImplicitHash
2228 family = get(:family)
2230 0.step(hsh.size-1, 2) do |i|
2231 family.add_ivar_as_slot hsh[i].value, hsh[i+1].value
2257 var, dep = scope.find_local meth, true, false
2259 var, dep = scope.find_local meth, false, false
2263 lv = LocalAccess.new(@compiler)
2264 lv.from_variable(var, dep)
2279 attr_accessor :method
2282 class PostExe < FCall
2284 # Treat a :postexe node as if it were a call to at_exit
2285 def self.create(compiler, sexp)
2286 sexp = [:fcall, :at_exit]
2287 super(compiler, sexp)
2291 class AttrAssign < Call
2294 def args(obj, meth, args=nil)
2295 @object, @method = obj, meth
2298 # Strange. nil is passed when it's self. Whatevs.
2299 @object = Self.new @compiler if @object.nil?
2301 if @method.to_s[-1] != ?=
2302 @method = "#{@method}=".to_sym
2307 # NOTE: []= has special semantics. It can be passed any number of arguments,
2308 # NOTE: PushArgs is for syntax h[*s] = 3, we have to handle it special
2310 # When we're in an masgn, there are no arguments
2311 return unless @arguments
2313 if @arguments.kind_of? Array
2314 @rhs_expression = @arguments.pop
2315 elsif @arguments.is? PushArgs
2316 @rhs_expression = nil
2318 raise Error, "unknown argument form to attrassgn"
2327 ["#{@object}.#{@method}"]
2335 @method = get(:scope)
2341 attr_accessor :arguments
2344 class ZSuper < Super
2348 @method = get(:scope)
2355 def args(args, direct=false)
2356 if direct and args.kind_of? ArrayLiteral
2357 @arguments = args.body
2358 elsif args.kind_of? DynamicArguments
2367 attr_accessor :arguments
2370 class BlockAsArgument < Node
2373 def args(name, position=nil)
2378 @variable, @depth = scope.find_local name
2379 @variable.in_locals!
2382 attr_accessor :name, :variable, :depth
2391 class IterArgs < Node
2399 return [] if @child.nil?
2401 if @child.is? LocalAssignment
2404 @child.assigns.body.map { |i| i.name }
2415 optional.empty? ? required.size : -(required.size + optional.size)
2429 return [] if @child.nil?
2433 attr_accessor :child
2440 # Conditional compilation support. If a conditional section is
2441 # matched as compilable, :iter is thrown to be caught here. We
2442 # strip out this unnecessary surrounding block including its
2443 # Newline and replace it with our contents. The condition may
2444 # seem a bit strange but it is because the catch returns nil
2445 # if :iter _is_ thrown, otherwise it returns the block value
2447 unless catch(:iter) { sexp[0] = convert(sexp[0]) }
2448 throw :newline, convert(sexp[2])
2453 # Get rid of the linked list of dasgn_curr's at the top
2454 # of a block in at iter.
2455 if sexp.length > 2 # Fix for empty block
2457 if first.kind_of?(Array) and first[0] == :dasgn_curr
2458 if first[2].nil? or first[2][0] == :dasgn_curr
2459 sexp[2].delete_at(1)
2464 if c.is? FCall and c.method == :loop
2465 sexp[1] = convert(sexp[1])
2466 sexp[2] = convert(sexp[2])
2472 @locals = get(:scope).new_block_scope do
2474 sexp[1] = convert([:iter_args, sexp[1]])
2477 sexp[2] = convert(sexp[2])
2484 def normalize(c, a, b)
2485 @arguments, @body = a, expand(b)
2487 if c.is? FCall and c.method == :loop
2488 n = Loop.new(@compiler)
2498 attr_accessor :arguments, :body, :locals
2504 # [[:newline, 1, "(eval)", [:dot2, [:lit, 1], [:lit, 2]]], [:lasgn, :x, 0]]
2506 # [[:call, [:newline, 1, "(eval)", [:dot2, [:lit, 1], [:lit, 2]]], :each], [:lasgn, :x, 0] ]
2507 def self.create(compiler, sexp)
2509 # sexp[1] is the enumeration for each
2510 # sexp[2] is the arguments
2511 # sexp[3] is the body, if any
2512 sexp = [sexp[0], [:call, sexp[1], :each], sexp[2], sexp[3]]
2513 super(compiler, sexp)
2517 converted = convert(sexp[0])
2518 sexp[0] = converted # enum for the 'each' call
2520 # 'declare' the vars outside the for.
2527 if vars.first == :masgn
2529 1.upto(ary.size - 1) do |i|
2530 scope.find_local ary[i][1], block if ary[i].first == :lasgn
2533 scope.find_local vars[1], block if vars.first == :lasgn
2537 @locals = get(:scope).new_block_scope do
2539 sexp[1] = convert([:iter_args, sexp[1]]) # local var assignment
2542 sexp[2] = convert(sexp[2]) # body
2549 def normalize(c, arguments, body)
2550 @arguments, @body = arguments, expand(body)
2557 class BlockPass < Node
2560 def normalize(blk, call)
2567 attr_accessor :block
2570 class ExecuteString < StringLiteral
2576 # Evstrs appear as a part of a dstr, dynamic string.
2577 # The evstr part is the code to be evaluated while
2578 # the dstr puts the whole thing together.
2580 # Interestingly, an evstr that only contains string
2581 # literals such as "#{'foo'}" is parsed to a plain
2582 # string literal. This is the same for dregx.
2583 class ToString < Node
2586 # Expected input is a sub-sexp that represents the
2587 # code to be run when evaluating or empty sexp.
2589 sexp = [[:str, ""]] if sexp.empty?
2597 attr_accessor :child
2600 class DynamicExecuteString < DynamicString
2604 class DynamicSymbol < Node
2615 def args(current, name)
2616 @current, @new = current, name
2619 attr_accessor :current, :new
2625 def args(current, name)
2626 @current, @new = current, name
2629 attr_accessor :current, :new
2635 def args(start, fin)
2636 @start, @finish = start, fin
2639 attr_accessor :start, :finish
2642 class RangeExclude < Range
2646 class CVarAssign < Node
2650 @name, @value = name, val
2651 @in_module = get(:scope).module_body?
2654 attr_accessor :name, :value
2657 class CVarDeclare < CVarAssign
2666 @in_module = get(:scope).module_body?