1
+ require 'json'
2
+
1
3
# A simple parser to transform a description of the VM instructions into
2
4
# various implementation files.
3
5
#
@@ -480,11 +482,36 @@ def produced
480
482
@produced || @instruction . produced + [ "..." ]
481
483
end
482
484
483
- def format ( file )
485
+ def description
486
+ @description . join . gsub ( /\n +/ , " " ) . gsub ( /\n +/ , "\n " ) . strip
487
+ end
488
+
489
+ def notes
490
+ @notes . join . gsub ( /\n +/ , " " ) . gsub ( /\n +/ , "\n " ) . strip
491
+ end
492
+
493
+ def see_also
494
+ @see_also . map ( &:strip )
495
+ end
496
+
497
+ def example
498
+ indent = @example . map { |str | str [ /\A \s */ ] . size } . sort . first
499
+ @example . map { |str | str [ indent ..-1 ] } . join
500
+ end
501
+
502
+ def stack_before
503
+ @consumed && @consumed . map ( &:strip )
504
+ end
505
+
506
+ def stack_after
507
+ @produced && @produced . map ( &:strip )
508
+ end
509
+
510
+ def render_format ( file )
484
511
file . puts %[<h3><a class="instruction" name="#{ name } ">#{ name } (#{ arguments } )</a></h3>]
485
512
end
486
513
487
- def stack_effect ( file )
514
+ def render_stack_effect ( file )
488
515
c = consumed
489
516
p = produced
490
517
n = c . size > p . size ? c . size : p . size
@@ -501,13 +528,13 @@ def stack_effect(file)
501
528
file . puts "</table>"
502
529
end
503
530
504
- def description ( file )
531
+ def render_description ( file )
505
532
file . puts ""
506
533
file . puts @description
507
534
file . puts ""
508
535
end
509
536
510
- def example ( file )
537
+ def render_example ( file )
511
538
return if @example . empty?
512
539
513
540
file . puts ""
@@ -516,7 +543,7 @@ def example(file)
516
543
file . puts ""
517
544
end
518
545
519
- def see_also ( file )
546
+ def render_see_also ( file )
520
547
return if @see_also . empty?
521
548
522
549
file . puts "\n <h4>See Also</h4>"
@@ -528,7 +555,7 @@ def see_also(file)
528
555
file . puts "</ul>"
529
556
end
530
557
531
- def notes ( file )
558
+ def render_notes ( file )
532
559
return if @notes . empty?
533
560
534
561
file . puts ""
@@ -546,12 +573,12 @@ def arguments
546
573
end
547
574
548
575
def render ( file )
549
- format file
550
- description file
551
- stack_effect file
552
- example file
553
- notes file
554
- see_also file
576
+ render_format file
577
+ render_description file
578
+ render_stack_effect file
579
+ render_example file
580
+ render_notes file
581
+ render_see_also file
555
582
end
556
583
end
557
584
@@ -577,10 +604,39 @@ def initialize(parser, header, doc)
577
604
@doc = InstructionDocumentation . new ( self ) . parse ( doc )
578
605
@extra = nil
579
606
@produced_extra = nil
607
+ @produced_times = nil
580
608
@bytecode = self . class . bytecode
581
609
@control_flow = :next
582
610
end
583
611
612
+ def representation ( section )
613
+ doc = { section : section , description : @doc . description }
614
+ doc [ :stack_before ] = @doc . stack_before if @doc . stack_before
615
+ doc [ :stack_after ] = @doc . stack_after if @doc . stack_after
616
+ doc [ :notes ] = @doc . notes if @doc . notes && !@doc . notes . empty?
617
+ doc [ :see_also ] = @doc . see_also if @doc . see_also && !@doc . see_also . empty?
618
+ doc [ :example ] = @doc . example if @doc . example && !@doc . example . empty?
619
+
620
+ consume = { static : static_read_effect }
621
+ consume [ :extra ] = @extra if @extra && @extra != 0
622
+
623
+ produce = { static : static_write_effect }
624
+ produce [ :extra ] = @produced_extra if @produced_extra && @produced_extra != 0
625
+ produce [ :times ] = @produced_times if @produced_times && @produced_times != 0
626
+
627
+ spec = { }
628
+ spec [ :arguments ] = @arguments if @arguments . any?
629
+ spec [ :stack_effect ] = { consume : consume , produce : produce }
630
+ spec [ :control_flow ] = @control_flow
631
+
632
+ {
633
+ opcode : bytecode ,
634
+ name : name ,
635
+ doc : doc ,
636
+ spec : spec ,
637
+ }
638
+ end
639
+
584
640
def parse
585
641
parse_header
586
642
parse_body
@@ -994,4 +1050,24 @@ def generate_documentation(filename)
994
1050
end
995
1051
end
996
1052
end
1053
+
1054
+ def generate_json ( filename )
1055
+ File . open filename , "wb" do |file |
1056
+ result = { defines : { } , instructions : [ ] }
1057
+ current_section = nil
1058
+
1059
+ objects . each do |obj |
1060
+ case obj
1061
+ when Define
1062
+ result [ :defines ] [ obj . name ] = obj . value
1063
+ when Section
1064
+ current_section = obj . heading
1065
+ when Instruction
1066
+ result [ :instructions ] << obj . representation ( current_section )
1067
+ end
1068
+ end
1069
+
1070
+ file . puts JSON . pretty_generate result
1071
+ end
1072
+ end
997
1073
end
0 commit comments