rpiet 0.1 → 0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/Gemfile +12 -0
  4. data/bin/color_wheel +84 -0
  5. data/bin/image_gen +39 -0
  6. data/bin/rpiet +68 -11
  7. data/images/counter.txt +7 -0
  8. data/lib/rpiet/asg/graph_interpreter.rb +39 -0
  9. data/lib/rpiet/asg/parser.rb +156 -0
  10. data/lib/rpiet/asg/visitor.rb +66 -0
  11. data/lib/rpiet/asg.rb +336 -0
  12. data/lib/rpiet/codel_chooser.rb +32 -4
  13. data/lib/rpiet/color.rb +70 -25
  14. data/lib/rpiet/cycle.rb +18 -7
  15. data/lib/rpiet/debugger/debugger.rb +298 -0
  16. data/lib/rpiet/debugger/stylesheet.css +88 -0
  17. data/lib/rpiet/direction_pointer.rb +49 -18
  18. data/lib/rpiet/event_handler.rb +62 -7
  19. data/lib/rpiet/group.rb +25 -8
  20. data/lib/rpiet/image/ascii_image.rb +8 -20
  21. data/lib/rpiet/image/image.rb +8 -3
  22. data/lib/rpiet/image/url_image.rb +28 -14
  23. data/lib/rpiet/interpreter.rb +72 -72
  24. data/lib/rpiet/ir/assembler.rb +87 -0
  25. data/lib/rpiet/ir/builder.rb +255 -0
  26. data/lib/rpiet/ir/cfg.rb +494 -0
  27. data/lib/rpiet/ir/instructions.rb +536 -0
  28. data/lib/rpiet/ir/ir_cfg_interpreter.rb +23 -0
  29. data/lib/rpiet/ir/ir_interpreter.rb +101 -0
  30. data/lib/rpiet/ir/ir_native_interpreter.rb +77 -0
  31. data/lib/rpiet/ir/jruby_backend.rb +279 -0
  32. data/lib/rpiet/ir/operands.rb +28 -0
  33. data/lib/rpiet/ir/passes/data_flow_problem.rb +32 -0
  34. data/lib/rpiet/ir/passes/flow_graph_node.rb +76 -0
  35. data/lib/rpiet/ir/passes/peephole.rb +214 -0
  36. data/lib/rpiet/ir/passes/push_pop_elimination_pass.rb +112 -0
  37. data/lib/rpiet/live_machine_state.rb +15 -0
  38. data/lib/rpiet/machine.rb +62 -32
  39. data/lib/rpiet/source.rb +83 -0
  40. data/lib/rpiet/version.rb +1 -1
  41. data/lib/rpiet.rb +2 -2
  42. data/rpiet.gemspec +19 -0
  43. data/spec/asg/visitor_spec.rb +41 -0
  44. data/spec/cycle_spec.rb +34 -34
  45. data/spec/direction_pointer_spec.rb +33 -6
  46. data/spec/group_spec.rb +73 -48
  47. data/spec/interpreter_spec.rb +161 -12
  48. data/spec/ir/assembler_spec.rb +122 -0
  49. data/spec/ir/builder_spec.rb +20 -0
  50. data/spec/ir/cfg_spec.rb +151 -0
  51. data/spec/ir/ir_interpreter_spec.rb +102 -0
  52. data/spec/ir/passes/push_pop_elimination_pass_spec.rb +34 -0
  53. data/spec/machine_spec.rb +5 -3
  54. data/spec/source_spec.rb +69 -0
  55. data/spec/spec_helper.rb +78 -0
  56. metadata +54 -16
  57. data/images/nfib.png +0 -0
@@ -0,0 +1,34 @@
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/rpiet/ir/cfg'
3
+ require_relative '../../../lib/rpiet/ir/passes/push_pop_elimination_pass'
4
+
5
+ describe "RPiet::IR::Passes:PushPopElimination" do
6
+ let(:gtr) {
7
+ assemble <<~EOS
8
+ push 10
9
+ push 5
10
+ 10 != 2 true
11
+ push 0
12
+ jump end
13
+ label true
14
+ push 1
15
+ label end
16
+ v1 = pop
17
+ v2 = pop
18
+ v3 = pop
19
+ v4 = v3 / v2
20
+ push v4
21
+ exit
22
+ EOS
23
+ }
24
+
25
+ it "can eliminate v2+v3 pops" do
26
+ instructions = gtr
27
+ puts "(initial) # of instr: #{instructions.length}"
28
+ @cfg = RPiet::IR::CFG.new(instructions)
29
+ push_pop_elim = RPiet::IR::Passes::PushPopEliminationProblem.new(@cfg)
30
+ push_pop_elim.debug = true
31
+ push_pop_elim.run
32
+ puts "instructions: #{@cfg.instructions.map { |i| i.disasm }.join("\n")}"
33
+ end
34
+ end
data/spec/machine_spec.rb CHANGED
@@ -1,8 +1,10 @@
1
- require 'rpiet/machine'
1
+ require_relative '../lib/rpiet/machine'
2
2
 
3
3
  describe "RPiet::Machine" do
4
4
  it "can roll" do
5
5
  machine = RPiet::Machine.new
6
+ expect(machine.dp.direction).to eq(RPiet::Direction::RIGHT)
7
+ expect(machine.cc.ordinal).to eq(-1)
6
8
 
7
9
  [115, 100, 101, 2, 1].each do |value|
8
10
  machine.block_value = value
@@ -10,7 +12,7 @@ describe "RPiet::Machine" do
10
12
  end
11
13
 
12
14
  machine.roll
13
- machine.stack.should == [115, 101, 100]
15
+ expect(machine.stack).to eq [115, 101, 100]
14
16
 
15
17
  [3, 1].each do |value|
16
18
  machine.block_value = value
@@ -18,6 +20,6 @@ describe "RPiet::Machine" do
18
20
  end
19
21
 
20
22
  machine.roll
21
- machine.stack.should == [100, 115, 101]
23
+ expect(machine.stack).to eq [100, 115, 101]
22
24
  end
23
25
  end
@@ -0,0 +1,69 @@
1
+ require_relative 'spec_helper'
2
+ require_relative '../lib/rpiet/source'
3
+ require_relative '../lib/rpiet/color'
4
+
5
+ describe "RPiet::Source" do
6
+ let(:image1) do
7
+ create_image <<-EOS
8
+ nb db db db ly
9
+ nb db db ly ly
10
+ ng db db ly ly
11
+ ng db db ly ly
12
+ ng db db ly ..
13
+ ng lg lg lg ++
14
+ EOS
15
+ end
16
+
17
+ let(:image2) do
18
+ create_image <<-EOS, 2
19
+ db db ly ly
20
+ db db ly ly
21
+ ++ ++ ly ly
22
+ ++ ++ ly ly
23
+ ++ ++ ly ly
24
+ ++ ++ ly ly
25
+ EOS
26
+ end
27
+
28
+ let(:source1) { RPiet::Source.new image1 }
29
+ let(:source2) { RPiet::Source.new image2 }
30
+
31
+ it "knows its size" do
32
+ expect(source1.rows).to eq(6)
33
+ expect(source1.cols).to eq(5)
34
+ expect(source1.groups.size).to eq(7)
35
+ expect(source1.codel_size).to eq(1)
36
+ end
37
+
38
+ it "knows its size with different codel_size" do
39
+ expect(source2.rows).to eq(3)
40
+ expect(source2.cols).to eq(2)
41
+ expect(source2.groups.size).to eq(3)
42
+ expect(source2.codel_size).to eq(2)
43
+ end
44
+
45
+ it "#valid? knows invalid locations" do
46
+ expect(source1.valid?(-1, 0)).to be_falsey
47
+ expect(source1.valid?(0, -1)).to be_falsey
48
+ expect(source1.valid?(source1.cols, 0)).to be_falsey
49
+ expect(source1.valid?(0, source1.rows)).to be_falsey
50
+ expect(source1.valid?(4, 5)).to be_falsey # black codel
51
+ end
52
+
53
+ it "#valid? knows valid locations" do
54
+ expect(source1.valid?(0, 0)).to be_truthy
55
+ expect(source1.valid?(source1.cols-1, 0)).to be_truthy
56
+ expect(source1.valid?(0, source1.rows-1)).to be_truthy
57
+ expect(source1.valid?(4, 4)).to be_truthy # white codel
58
+ end
59
+
60
+ it "#group_at knows which group it is associated with" do
61
+ expect(source1.group_at(0, 0).color).to eq(RPiet::Color::BLUE)
62
+ expect(source1.group_at(1, 0).color).to eq(RPiet::Color::DARK_BLUE)
63
+ expect(source1.group_at(2, 0).color).to eq(RPiet::Color::DARK_BLUE)
64
+ expect(source1.group_at(4, 0).color).to eq(RPiet::Color::LIGHT_YELLOW)
65
+ expect(source1.group_at(4, 4).color).to eq(RPiet::Color::WHITE)
66
+ expect(source1.group_at(3, 5).color).to eq(RPiet::Color::LIGHT_GREEN)
67
+ expect(source1.group_at(4, 5).color).to eq(RPiet::Color::BLACK)
68
+ end
69
+ end
@@ -0,0 +1,78 @@
1
+ require_relative '../lib/rpiet/group'
2
+ require_relative '../lib/rpiet/image/ascii_image'
3
+ require_relative '../lib/rpiet/ir/assembler'
4
+ require_relative '../lib/rpiet/ir/ir_interpreter'
5
+
6
+ module SpecHelper
7
+ ##
8
+ # Takes a description of a group as an newline-delimited string
9
+ # where all '#' characters represent the group you want to create
10
+ # and any other character is insignificant. Here is a simple
11
+ # example of a group in the shape of a 'T':
12
+ #
13
+ # my_group_ascii << EOS
14
+ # ...#####...
15
+ # .....#.....
16
+ # .....#.....
17
+ # .....#.....
18
+ # EOS
19
+ #
20
+ def ascii_to_group_points(string)
21
+ points = []
22
+ string.split("\n").each_with_index do |line, j|
23
+ line.split('').each_with_index do |char, i|
24
+ points << [i, j] if char == '#'
25
+ end
26
+ end
27
+ points
28
+ end
29
+
30
+ def create_group(color, string)
31
+ RPiet::Group.new(color, *ascii_to_group_points(string)).tap { |g| g.calculate_corners }
32
+ end
33
+
34
+ def create_image(string, *r)
35
+ RPiet::Image::AsciiImage.new string, *r
36
+ end
37
+
38
+ def assemble(code)
39
+ RPiet::IR::Assembler.assemble(code)
40
+ end
41
+
42
+ def ir_interp(instructions)
43
+ RPiet::IR::IRInterpreter.new(instructions)
44
+ end
45
+ end
46
+
47
+ RSpec::Matchers.define(:be_label_operand) do |value|
48
+ description { 'is a label operand' }
49
+
50
+ match { |actual| actual.kind_of?(Symbol) && actual == value }
51
+ end
52
+
53
+ RSpec::Matchers.define(:be_numeric_operand) do |value|
54
+ description { 'is a numeric operand' }
55
+
56
+ match { |actual| actual.kind_of?(Integer) && actual == value }
57
+ end
58
+
59
+ RSpec::Matchers.define(:be_string_operand) do |value|
60
+ description { 'is a string operand' }
61
+
62
+ match { |actual| actual.kind_of?(String) && actual == value }
63
+ end
64
+
65
+ RSpec::Matchers.define(:be_variable_operand) do |name, value=nil|
66
+ description { 'is a variable operand' }
67
+
68
+ match do |actual|
69
+ actual.kind_of?(RPiet::IR::Operands::VariableOperand) && actual.name == name &&
70
+ (!value || actual.value == value)
71
+ end
72
+ end
73
+
74
+
75
+
76
+ RSpec.configure do |c|
77
+ c.include SpecHelper
78
+ end
metadata CHANGED
@@ -1,37 +1,47 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rpiet
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: '0.1'
4
+ version: '0.2'
6
5
  platform: ruby
7
6
  authors:
8
7
  - Thomas E. Enebo
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-10-24 00:00:00.000000000 Z
11
+ date: 2024-11-12 00:00:00.000000000 Z
13
12
  dependencies: []
14
13
  description: An implementation of the esoteric programming language Piet
15
14
  email: tom.enebo@gmail.com
16
15
  executables:
16
+ - color_wheel
17
+ - image_gen
17
18
  - rpiet
18
19
  extensions: []
19
20
  extra_rdoc_files: []
20
21
  files:
21
- - .gitignore
22
+ - ".gitignore"
23
+ - Gemfile
22
24
  - README.md
25
+ - bin/color_wheel
26
+ - bin/image_gen
23
27
  - bin/rpiet
24
28
  - images/.DS_Store
29
+ - images/counter.txt
25
30
  - images/cowsay.gif
26
31
  - images/helloworld-piet.gif
27
32
  - images/helloworld-pietbig.gif
28
33
  - images/hi.gif
29
34
  - images/loop2to0.gif
30
- - images/nfib.png
31
35
  - lib/rpiet.rb
36
+ - lib/rpiet/asg.rb
37
+ - lib/rpiet/asg/graph_interpreter.rb
38
+ - lib/rpiet/asg/parser.rb
39
+ - lib/rpiet/asg/visitor.rb
32
40
  - lib/rpiet/codel_chooser.rb
33
41
  - lib/rpiet/color.rb
34
42
  - lib/rpiet/cycle.rb
43
+ - lib/rpiet/debugger/debugger.rb
44
+ - lib/rpiet/debugger/stylesheet.css
35
45
  - lib/rpiet/direction_pointer.rb
36
46
  - lib/rpiet/event_handler.rb
37
47
  - lib/rpiet/group.rb
@@ -39,42 +49,70 @@ files:
39
49
  - lib/rpiet/image/image.rb
40
50
  - lib/rpiet/image/url_image.rb
41
51
  - lib/rpiet/interpreter.rb
52
+ - lib/rpiet/ir/assembler.rb
53
+ - lib/rpiet/ir/builder.rb
54
+ - lib/rpiet/ir/cfg.rb
55
+ - lib/rpiet/ir/instructions.rb
56
+ - lib/rpiet/ir/ir_cfg_interpreter.rb
57
+ - lib/rpiet/ir/ir_interpreter.rb
58
+ - lib/rpiet/ir/ir_native_interpreter.rb
59
+ - lib/rpiet/ir/jruby_backend.rb
60
+ - lib/rpiet/ir/operands.rb
61
+ - lib/rpiet/ir/passes/data_flow_problem.rb
62
+ - lib/rpiet/ir/passes/flow_graph_node.rb
63
+ - lib/rpiet/ir/passes/peephole.rb
64
+ - lib/rpiet/ir/passes/push_pop_elimination_pass.rb
65
+ - lib/rpiet/live_machine_state.rb
42
66
  - lib/rpiet/machine.rb
67
+ - lib/rpiet/source.rb
43
68
  - lib/rpiet/version.rb
69
+ - rpiet.gemspec
70
+ - spec/asg/visitor_spec.rb
44
71
  - spec/cycle_spec.rb
45
72
  - spec/direction_pointer_spec.rb
46
73
  - spec/group_spec.rb
47
74
  - spec/interpreter_spec.rb
75
+ - spec/ir/assembler_spec.rb
76
+ - spec/ir/builder_spec.rb
77
+ - spec/ir/cfg_spec.rb
78
+ - spec/ir/ir_interpreter_spec.rb
79
+ - spec/ir/passes/push_pop_elimination_pass_spec.rb
48
80
  - spec/machine_spec.rb
81
+ - spec/source_spec.rb
82
+ - spec/spec_helper.rb
49
83
  homepage: http://github.com/enebo/rpiet
50
84
  licenses: []
85
+ metadata: {}
51
86
  post_install_message:
52
87
  rdoc_options: []
53
88
  require_paths:
54
89
  - lib
55
90
  required_ruby_version: !ruby/object:Gem::Requirement
56
91
  requirements:
57
- - - ! '>='
92
+ - - ">="
58
93
  - !ruby/object:Gem::Version
59
- version: !binary |-
60
- MA==
61
- none: false
94
+ version: '0'
62
95
  required_rubygems_version: !ruby/object:Gem::Requirement
63
96
  requirements:
64
- - - ! '>='
97
+ - - ">="
65
98
  - !ruby/object:Gem::Version
66
- version: !binary |-
67
- MA==
68
- none: false
99
+ version: '0'
69
100
  requirements: []
70
- rubyforge_project:
71
- rubygems_version: 1.8.24
101
+ rubygems_version: 3.3.26
72
102
  signing_key:
73
- specification_version: 3
103
+ specification_version: 4
74
104
  summary: A Piet runtime
75
105
  test_files:
106
+ - spec/asg/visitor_spec.rb
76
107
  - spec/cycle_spec.rb
77
108
  - spec/direction_pointer_spec.rb
78
109
  - spec/group_spec.rb
79
110
  - spec/interpreter_spec.rb
111
+ - spec/ir/assembler_spec.rb
112
+ - spec/ir/builder_spec.rb
113
+ - spec/ir/cfg_spec.rb
114
+ - spec/ir/ir_interpreter_spec.rb
115
+ - spec/ir/passes/push_pop_elimination_pass_spec.rb
80
116
  - spec/machine_spec.rb
117
+ - spec/source_spec.rb
118
+ - spec/spec_helper.rb
data/images/nfib.png DELETED
Binary file