Class: Twostroke::Runtime::VM

Inherits:
Object
  • Object
show all
Defined in:
lib/twostroke/runtime/vm.rb

Defined Under Namespace

Classes: Frame

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(bytecode) ⇒ VM

Returns a new instance of VM.



6
7
8
9
10
11
12
# File 'lib/twostroke/runtime/vm.rb', line 6

def initialize(bytecode)
  @bytecode = bytecode
  @global_scope = GlobalScope.new self
  @lib = {}
  @name_args = {}
  @vm_eval_counter = 0
end

Instance Attribute Details

#bytecodeObject

Returns the value of attribute bytecode.



3
4
5
# File 'lib/twostroke/runtime/vm.rb', line 3

def bytecode
  @bytecode
end

#global_scopeObject (readonly)

Returns the value of attribute global_scope.



4
5
6
# File 'lib/twostroke/runtime/vm.rb', line 4

def global_scope
  @global_scope
end

#libObject (readonly)

Returns the value of attribute lib.



4
5
6
# File 'lib/twostroke/runtime/vm.rb', line 4

def lib
  @lib
end

Instance Method Details

#eval(source, scope = nil, this = nil) ⇒ Object



34
35
36
37
38
39
40
41
42
43
# File 'lib/twostroke/runtime/vm.rb', line 34

def eval(source, scope = nil, this = nil)
  parser = Twostroke::Parser.new Twostroke::Lexer.new source
  parser.parse
  prefix = "#{@vm_eval_counter += 1}_"
  compiler = Twostroke::Compiler::TSASM.new parser.statements, prefix
  compiler.compile
  compiler.bytecode[:"#{prefix}main"][-2] = [:ret]
  bytecode.merge! compiler.bytecode
  execute :"#{prefix}main", scope, this
end

#execute(section = :main, scope = nil, this = nil) ⇒ Object



14
15
16
# File 'lib/twostroke/runtime/vm.rb', line 14

def execute(section = :main, scope = nil, this = nil)
  Frame.new(self, section).execute scope, this
end

#section_name_args(section) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
# File 'lib/twostroke/runtime/vm.rb', line 22

def section_name_args(section)
  unless @name_args[section]
    ops = bytecode[section].take_while { |ins,arg| [:".name", :".arg"].include? ins }
    @name_args[section] = [
      ops.select { |ins,arg| :".name" == ins }.map { |ins,arg| arg }.first,
      ops.select { |ins,arg| :".arg" == ins }.map { |ins,arg| arg.to_s }
    ]
  else
    @name_args[section]
  end
end

#throw_error(type, message) ⇒ Object



18
19
20
# File 'lib/twostroke/runtime/vm.rb', line 18

def throw_error(type, message)
  throw :exception, lib[type].(nil, global_scope.root_object, [Types::String.new(message)])
end