rpiet 0.1 → 0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/Gemfile +12 -0
- data/bin/color_wheel +84 -0
- data/bin/image_gen +39 -0
- data/bin/rpiet +68 -11
- data/images/counter.txt +7 -0
- data/lib/rpiet/asg/graph_interpreter.rb +39 -0
- data/lib/rpiet/asg/parser.rb +156 -0
- data/lib/rpiet/asg/visitor.rb +66 -0
- data/lib/rpiet/asg.rb +336 -0
- data/lib/rpiet/codel_chooser.rb +32 -4
- data/lib/rpiet/color.rb +70 -25
- data/lib/rpiet/cycle.rb +18 -7
- data/lib/rpiet/debugger/debugger.rb +298 -0
- data/lib/rpiet/debugger/stylesheet.css +88 -0
- data/lib/rpiet/direction_pointer.rb +49 -18
- data/lib/rpiet/event_handler.rb +62 -7
- data/lib/rpiet/group.rb +25 -8
- data/lib/rpiet/image/ascii_image.rb +8 -20
- data/lib/rpiet/image/image.rb +8 -3
- data/lib/rpiet/image/url_image.rb +28 -14
- data/lib/rpiet/interpreter.rb +72 -72
- data/lib/rpiet/ir/assembler.rb +87 -0
- data/lib/rpiet/ir/builder.rb +255 -0
- data/lib/rpiet/ir/cfg.rb +494 -0
- data/lib/rpiet/ir/instructions.rb +536 -0
- data/lib/rpiet/ir/ir_cfg_interpreter.rb +23 -0
- data/lib/rpiet/ir/ir_interpreter.rb +101 -0
- data/lib/rpiet/ir/ir_native_interpreter.rb +77 -0
- data/lib/rpiet/ir/jruby_backend.rb +279 -0
- data/lib/rpiet/ir/operands.rb +28 -0
- data/lib/rpiet/ir/passes/data_flow_problem.rb +32 -0
- data/lib/rpiet/ir/passes/flow_graph_node.rb +76 -0
- data/lib/rpiet/ir/passes/peephole.rb +214 -0
- data/lib/rpiet/ir/passes/push_pop_elimination_pass.rb +112 -0
- data/lib/rpiet/live_machine_state.rb +15 -0
- data/lib/rpiet/machine.rb +62 -32
- data/lib/rpiet/source.rb +83 -0
- data/lib/rpiet/version.rb +1 -1
- data/lib/rpiet.rb +2 -2
- data/rpiet.gemspec +19 -0
- data/spec/asg/visitor_spec.rb +41 -0
- data/spec/cycle_spec.rb +34 -34
- data/spec/direction_pointer_spec.rb +33 -6
- data/spec/group_spec.rb +73 -48
- data/spec/interpreter_spec.rb +161 -12
- data/spec/ir/assembler_spec.rb +122 -0
- data/spec/ir/builder_spec.rb +20 -0
- data/spec/ir/cfg_spec.rb +151 -0
- data/spec/ir/ir_interpreter_spec.rb +102 -0
- data/spec/ir/passes/push_pop_elimination_pass_spec.rb +34 -0
- data/spec/machine_spec.rb +5 -3
- data/spec/source_spec.rb +69 -0
- data/spec/spec_helper.rb +78 -0
- metadata +54 -16
- 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
|
-
|
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.
|
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.
|
23
|
+
expect(machine.stack).to eq [100, 115, 101]
|
22
24
|
end
|
23
25
|
end
|
data/spec/source_spec.rb
ADDED
@@ -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
|
data/spec/spec_helper.rb
ADDED
@@ -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
|
-
|
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:
|
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:
|
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:
|
67
|
-
MA==
|
68
|
-
none: false
|
99
|
+
version: '0'
|
69
100
|
requirements: []
|
70
|
-
|
71
|
-
rubygems_version: 1.8.24
|
101
|
+
rubygems_version: 3.3.26
|
72
102
|
signing_key:
|
73
|
-
specification_version:
|
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
|