Class: Plasma::Interpreter::PlasmaInterpreter

Inherits:
Object
  • Object
show all
Defined in:
lib/plasma/interpreter/plasma_interpreter.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializePlasmaInterpreter

Returns a new instance of PlasmaInterpreter.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/plasma/interpreter/plasma_interpreter.rb', line 6

def initialize
  @prompt = "-----|  "
  @comment = /##*[^#]+##*/

  @dir = File.dirname(__FILE__)
  @load_path = [PLASMA_PACKAGE_ROOT, 
                File.join(PLASMA_ROOT, 'include'), 
                @dir, 
                `pwd`.strip]

  @env = Env.new
  @env.bind!(:mu, self)
  @env.bind!(:env, @env)

  @plasma = PlasmaGrammarParser.new
  
  import 'plasma_core'
  merge 'core'
end

Instance Attribute Details

#envObject

Returns the value of attribute env.



4
5
6
# File 'lib/plasma/interpreter/plasma_interpreter.rb', line 4

def env
  @env
end

Instance Method Details

#evaluate(tree, env = nil) ⇒ Object



87
88
89
90
# File 'lib/plasma/interpreter/plasma_interpreter.rb', line 87

def evaluate(tree, env=nil)
  env ||= @env
  tree.evaluate(env)
end

#import(rb) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/plasma/interpreter/plasma_interpreter.rb', line 38

def import(rb)
  name = rb.split('/').last
  file = "#{rb}.rb"
  @load_path.each do |p|
    package = File.join(p, file)
    if File.exist? package
      load package
      @env.merge!(Plasma::Interpreter.const_get(name.classify).plasma(self))

      return true
    end
  end

  return false
end

#interpret(code, env = nil) ⇒ Object



92
93
94
95
# File 'lib/plasma/interpreter/plasma_interpreter.rb', line 92

def interpret(code, env=nil)
  tree = parse(strip(code))
  evaluate(tree, env)
end

#merge(plasma) ⇒ Object

Raises:



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/plasma/interpreter/plasma_interpreter.rb', line 54

def merge(plasma)
  name = plasma.split('/').last
  file = "#{plasma}.plasma"
  found = false
  value = nil
  
  @load_path.reverse_each do |p|
    package = File.join(p, file)
    if File.exist? package
      source = File.open(package, 'r')
      code = source.read.strip

      value = self.interpret(code)
      found = true
      break
    end
  end

  return value if found
  raise NoSuchSourceException.new(plasma), "no such source #{plasma}", caller
end

#parse(code) ⇒ Object

Raises:



80
81
82
83
84
85
# File 'lib/plasma/interpreter/plasma_interpreter.rb', line 80

def parse(code)
  tree = @plasma.parse(code)
  raise FailedToParseException.new, "failed to parse #{code}", caller if tree.nil? 

  return tree
end

#pathObject



34
35
36
# File 'lib/plasma/interpreter/plasma_interpreter.rb', line 34

def path
  @load_path
end

#replObject



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/plasma/interpreter/plasma_interpreter.rb', line 97

def repl
  while true
    begin
      STDOUT.write(@prompt)

      input = STDIN.readline.strip
      unless input.empty?

        value = interpret input

        STDOUT.write("  #{value.to_plasma}\n")
      end
    rescue EOFError => e
      break
    rescue Exception => e
      STDOUT.write("  #{e}\n")
    end
  end
end

#strip(code) ⇒ Object



76
77
78
# File 'lib/plasma/interpreter/plasma_interpreter.rb', line 76

def strip(code)
  code.gsub(@comment, '').strip
end

#to_plasmaObject



30
31
32
# File 'lib/plasma/interpreter/plasma_interpreter.rb', line 30

def to_plasma
  "eval"
end

#to_sObject



26
27
28
# File 'lib/plasma/interpreter/plasma_interpreter.rb', line 26

def to_s
  "plasma -- #{@env.keys}"
end