Class: Gisele::VM::Bytecode

Inherits:
Object
  • Object
show all
Defined in:
lib/gisele/vm/bytecode.rb,
lib/gisele/vm/bytecode/builder.rb,
lib/gisele/vm/bytecode/grammar.rb,
lib/gisele/vm/bytecode/printer.rb

Defined Under Namespace

Modules: Grammar Classes: Builder, Printer

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(sexpr) ⇒ Bytecode

Returns a new instance of Bytecode.



8
9
10
# File 'lib/gisele/vm/bytecode.rb', line 8

def initialize(sexpr)
  @sexpr = sexpr
end

Class Method Details

.build(namespace = nil) {|builder| ... } ⇒ Object

Yields:



30
31
32
33
34
# File 'lib/gisele/vm/bytecode.rb', line 30

def self.build(namespace = nil)
  builder = builder(namespace)
  yield(builder)
  Bytecode.new(builder.to_a)
end

.builder(namespace = nil) ⇒ Object



26
27
28
# File 'lib/gisele/vm/bytecode.rb', line 26

def self.builder(namespace = nil)
  Builder.new(namespace)
end

.coerce(arg) ⇒ Object



12
13
14
15
16
17
18
19
20
# File 'lib/gisele/vm/bytecode.rb', line 12

def self.coerce(arg)
  case arg
  when Bytecode           then arg
  when String, Path       then parse(arg)
  when Grammar            then Bytecode.new(arg)
  else
    raise ArgumentError, "Invalid bytecode source: #{arg}"
  end
end

.parse(source) ⇒ Object



22
23
24
# File 'lib/gisele/vm/bytecode.rb', line 22

def self.parse(source)
  Bytecode.new(Grammar.sexpr(source))
end

Instance Method Details

#+(other) ⇒ Object



36
37
38
39
# File 'lib/gisele/vm/bytecode.rb', line 36

def +(other)
  other = Bytecode.coerce(other)
  Bytecode.new [:gvm] + to_a[1..-1] + other.to_a[1..-1]
end

#[](label) ⇒ Object Also known as: fetch



41
42
43
44
# File 'lib/gisele/vm/bytecode.rb', line 41

def [](label)
  block = index[label]
  block ? block[2..-1] : nil
end

#to_aObject



47
48
49
# File 'lib/gisele/vm/bytecode.rb', line 47

def to_a
  @sexpr
end

#to_sObject



51
52
53
# File 'lib/gisele/vm/bytecode.rb', line 51

def to_s
  Printer.call(to_a)
end

#verify!Object



55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/gisele/vm/bytecode.rb', line 55

def verify!
  unless (Bytecode::Grammar === @sexpr)
    sexpr.sexpr_body.each do |block|
      next if Bytecode::Grammar[:block] === block
      invalid = block.sexpr_body[1..-1].find{|i|
        !(Bytecode::Grammar[:instruction]===i)
      }
      raise InvalidBytecodeError, "Bad instruction: #{invalid}"
    end
  end
  self
end