Class: Prattle::AST::Block

Inherits:
Node
  • Object
show all
Defined in:
lib/prattle/ast/block.rb

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Methods inherited from Node

#run

Constructor Details

- (Block) initialize(body, args)



10
11
12
13
# File 'lib/prattle/ast/block.rb', line 10

def initialize(body, args)
  @body = body
  @arguments = args
end

Instance Attribute Details

- (Object) arguments (readonly)

Returns the value of attribute arguments



15
16
17
# File 'lib/prattle/ast/block.rb', line 15

def arguments
  @arguments
end

- (Object) body (readonly)

Returns the value of attribute body



15
16
17
# File 'lib/prattle/ast/block.rb', line 15

def body
  @body
end

Class Method Details

+ (Object) grammar(g)



17
18
19
20
21
22
23
24
25
# File 'lib/prattle/ast/block.rb', line 17

def self.grammar(g)
  name = g.seq(":", g.t(/[a-zA-Z][a-zA-Z0-9_]*/), :sp)
  args = g.seq(:sp, g.t(g.kleene(name)), "|")

  g.block = g.seq('[', g.t(g.maybe(args)), :sp,
                       g.t(:expressions), :sp, ']') do |args,v|
    Block.new(v, Array(args))
  end
end

+ (Object) rule_name



6
7
8
# File 'lib/prattle/ast/block.rb', line 6

def self.rule_name
  "block"
end

Instance Method Details

- (Object) bytecode(g)



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/prattle/ast/block.rb', line 27

def bytecode(g)
  c = Rubinius::Generator.new
  c.name = :block
  c.file = :dynamic
  c.set_line 1

  scope = Evaluator::Scope.new(g.state.scope)
  c.push_state(scope)

  c.required_args = c.total_args = @arguments.size
  c.local_count = @arguments.size

  case @arguments.size
  when 0
    # Nothing
  when 1
    c.cast_for_single_block_arg
    c.set_local scope.add_variable(@arguments.first)
    c.pop
  else
    c.cast_for_multi_block_arg
    @arguments.each do |a|
      c.shift_array
      c.set_local scope.add_variable(a)
      c.pop
    end
    c.pop
  end

  @body.each_with_index do |node,idx|
    c.pop unless idx == 0
    node.bytecode(c)
  end

  c.ret
  c.close

  c.use_detected

  g.push_const :Kernel
  g.create_block c
  g.send_with_block :proc, 0
end