Class: Prattle::Evaluator

Inherits:
Object
  • Object
show all
Defined in:
lib/prattle/evaluator.rb

Defined Under Namespace

Classes: Scope

Instance Method Summary (collapse)

Constructor Details

- (Evaluator) initialize(nodes, debug = false)



31
32
33
34
35
# File 'lib/prattle/evaluator.rb', line 31

def initialize(nodes, debug=false)
  @nodes = Array(nodes)
  @debug = debug
  @lobby = Lobby.new
end

Instance Method Details

- (Object) add_method(n)



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/prattle/evaluator.rb', line 69

def add_method(n)
  name = n.initial.receiver.name
  sig = n.cascades[0]
  body = n.cascades[1].arguments[0]

  puts "Adding method #{sig.method_name} to #{name}"

  begin
    const = Object.const_get(name)
  rescue NameError
    const = Class.new
    Object.const_set name, const
  end

  const.dynamic_method sig.method_name.to_sym do |g|
    g.total_args = sig.arguments.size
    g.required_args = g.total_args
    g.local_count = g.required_args

    scope = Scope.new
    g.push_state(scope)

    sig.arguments.each do |arg|
      scope.add_variable arg.name
    end

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

    g.ret
  end
end

- (Object) compile



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/prattle/evaluator.rb', line 118

def compile
  detect_methods
  cm = @lobby.metaclass.dynamic_method :call do |g|
    scope = Scope.new
    g.push_state(scope)

    if @nodes.empty?
      g.push :nil
    else
      @nodes.each_with_index do |node,idx|
        g.pop unless idx == 0
        node.bytecode(g)
      end
    end

    g.ret
  end

  puts cm.decode if @debug
end

- (Object) detect_methods



104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/prattle/evaluator.rb', line 104

def detect_methods
  @nodes.delete_if do |n|
    if n.kind_of? AST::CascadeSend
      init = n.initial
      if init.kind_of? AST::UnarySend and init.method_name == "define"
        add_method(n)
        next true
      end
    end

    false
  end
end

- (Object) run



139
140
141
142
# File 'lib/prattle/evaluator.rb', line 139

def run
  compile
  @lobby.call
end