Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add JSON representation to those emitted by InstructionParser.
This is intended to be a machine-readable description of all
VM instructions to be used to produce arbitrary forms of
documentation and tooling for the VM without requiring integration
into InstructionParser itself.
  • Loading branch information
jemc committed Jun 29, 2015
1 parent 291c7c7 commit 86ed358
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 12 deletions.
100 changes: 88 additions & 12 deletions rakelib/instruction_parser.rb
@@ -1,3 +1,5 @@
require 'json'

# A simple parser to transform a description of the VM instructions into
# various implementation files.
#
Expand Down Expand Up @@ -480,11 +482,36 @@ def produced
@produced || @instruction.produced + ["..."]
end

def format(file)
def description
@description.join.gsub(/\n +/, " ").gsub(/\n +/, "\n").strip
end

def notes
@notes.join.gsub(/\n +/, " ").gsub(/\n +/, "\n").strip
end

def see_also
@see_also.map(&:strip)
end

def example
indent = @example.map { |str| str[/\A\s*/].size }.sort.first
@example.map { |str| str[indent..-1] }.join
end

def stack_before
@consumed && @consumed.map(&:strip)
end

def stack_after
@produced && @produced.map(&:strip)
end

def render_format(file)
file.puts %[<h3><a class="instruction" name="#{name}">#{name}(#{arguments})</a></h3>]
end

def stack_effect(file)
def render_stack_effect(file)
c = consumed
p = produced
n = c.size > p.size ? c.size : p.size
Expand All @@ -501,13 +528,13 @@ def stack_effect(file)
file.puts "</table>"
end

def description(file)
def render_description(file)
file.puts ""
file.puts @description
file.puts ""
end

def example(file)
def render_example(file)
return if @example.empty?

file.puts ""
Expand All @@ -516,7 +543,7 @@ def example(file)
file.puts ""
end

def see_also(file)
def render_see_also(file)
return if @see_also.empty?

file.puts "\n<h4>See Also</h4>"
Expand All @@ -528,7 +555,7 @@ def see_also(file)
file.puts "</ul>"
end

def notes(file)
def render_notes(file)
return if @notes.empty?

file.puts ""
Expand All @@ -546,12 +573,12 @@ def arguments
end

def render(file)
format file
description file
stack_effect file
example file
notes file
see_also file
render_format file
render_description file
render_stack_effect file
render_example file
render_notes file
render_see_also file
end
end

Expand All @@ -577,10 +604,39 @@ def initialize(parser, header, doc)
@doc = InstructionDocumentation.new(self).parse(doc)
@extra = nil
@produced_extra = nil
@produced_times = nil
@bytecode = self.class.bytecode
@control_flow = :next
end

def representation(section)
doc = { section: section, description: @doc.description }
doc[:stack_before] = @doc.stack_before if @doc.stack_before
doc[:stack_after] = @doc.stack_after if @doc.stack_after
doc[:notes] = @doc.notes if @doc.notes && !@doc.notes.empty?
doc[:see_also] = @doc.see_also if @doc.see_also && !@doc.see_also.empty?
doc[:example] = @doc.example if @doc.example && !@doc.example.empty?

consume = { static: static_read_effect }
consume[:extra] = @extra if @extra && @extra != 0

produce = { static: static_write_effect }
produce[:extra] = @produced_extra if @produced_extra && @produced_extra != 0
produce[:times] = @produced_times if @produced_times && @produced_times != 0

spec = {}
spec[:arguments] = @arguments if @arguments.any?
spec[:stack_effect] = { consume: consume, produce: produce }
spec[:control_flow] = @control_flow

{
opcode: bytecode,
name: name,
doc: doc,
spec: spec,
}
end

def parse
parse_header
parse_body
Expand Down Expand Up @@ -994,4 +1050,24 @@ def generate_documentation(filename)
end
end
end

def generate_json(filename)
File.open filename, "wb" do |file|
result = { defines: {}, instructions: [] }
current_section = nil

objects.each do |obj|
case obj
when Define
result[:defines][obj.name] = obj.value
when Section
current_section = obj.heading
when Instruction
result[:instructions] << obj.representation(current_section)
end
end

file.puts JSON.pretty_generate result
end
end
end
4 changes: 4 additions & 0 deletions rakelib/vm.rake
Expand Up @@ -312,6 +312,10 @@ file "vm/gen/instruction_effects.hpp" => insn_deps do |t|
generate_instruction_file iparser, :generate_stack_effects, t.name
end

file "vm/gen/instructions.json" => insn_deps do |t|
generate_instruction_file iparser, :generate_json, t.name
end

namespace :vm do
desc 'Run all VM tests. Uses its argument as a filter of tests to run.'
task :test, :filter do |task, args|
Expand Down

0 comments on commit 86ed358

Please sign in to comment.