furnace 0.4.0.beta.1 → 0.4.0.beta.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 (49) hide show
  1. checksums.yaml +7 -0
  2. data/.travis.yml +6 -0
  3. data/INSTRUMENT.md +250 -0
  4. data/Rakefile +1 -1
  5. data/lib/furnace.rb +10 -6
  6. data/lib/furnace/ast/node.rb +15 -1
  7. data/lib/furnace/awesome_printer.rb +121 -0
  8. data/lib/furnace/context.rb +0 -0
  9. data/lib/furnace/ssa.rb +7 -25
  10. data/lib/furnace/ssa/argument.rb +14 -10
  11. data/lib/furnace/ssa/basic_block.rb +70 -25
  12. data/lib/furnace/ssa/builder.rb +11 -7
  13. data/lib/furnace/ssa/constant.rb +19 -11
  14. data/lib/furnace/ssa/event_stream.rb +145 -0
  15. data/lib/furnace/ssa/function.rb +78 -57
  16. data/lib/furnace/ssa/generic_instruction.rb +12 -5
  17. data/lib/furnace/ssa/instruction.rb +50 -35
  18. data/lib/furnace/ssa/instruction_syntax.rb +9 -25
  19. data/lib/furnace/ssa/instructions/branch.rb +2 -2
  20. data/lib/furnace/ssa/instructions/phi.rb +12 -10
  21. data/lib/furnace/ssa/instructions/return.rb +3 -3
  22. data/lib/furnace/ssa/instructions/return_value.rb +11 -0
  23. data/lib/furnace/ssa/instrumentation.rb +33 -0
  24. data/lib/furnace/ssa/module.rb +5 -1
  25. data/lib/furnace/ssa/named_value.rb +31 -10
  26. data/lib/furnace/ssa/terminator_instruction.rb +6 -6
  27. data/lib/furnace/ssa/types/basic_block.rb +4 -8
  28. data/lib/furnace/ssa/types/function.rb +4 -8
  29. data/lib/furnace/ssa/user.rb +14 -15
  30. data/lib/furnace/ssa/value.rb +9 -5
  31. data/lib/furnace/transform/iterative.rb +20 -4
  32. data/lib/furnace/type.rb +9 -0
  33. data/lib/furnace/type/bottom.rb +11 -0
  34. data/lib/furnace/type/top.rb +72 -0
  35. data/lib/furnace/type/value.rb +13 -0
  36. data/lib/furnace/type/variable.rb +61 -0
  37. data/lib/furnace/version.rb +1 -1
  38. data/test/{test_helper.rb → helper.rb} +28 -3
  39. data/test/{ast_test.rb → test_ast.rb} +13 -1
  40. data/test/test_awesome_printer.rb +148 -0
  41. data/test/{ssa_test.rb → test_ssa.rb} +276 -315
  42. data/test/{transform_test.rb → test_transform.rb} +2 -2
  43. data/test/test_type.rb +138 -0
  44. metadata +83 -105
  45. data/lib/furnace/graphviz.rb +0 -49
  46. data/lib/furnace/ssa/generic_type.rb +0 -16
  47. data/lib/furnace/ssa/pretty_printer.rb +0 -113
  48. data/lib/furnace/ssa/type.rb +0 -27
  49. data/lib/furnace/ssa/types/void.rb +0 -15
@@ -1,4 +1,4 @@
1
- require_relative 'test_helper'
1
+ require_relative 'helper'
2
2
 
3
3
  describe Transform do
4
4
  class Context
@@ -71,4 +71,4 @@ describe Transform do
71
71
  pipeline.run(@context).should == false
72
72
  end
73
73
  end
74
- end
74
+ end
@@ -0,0 +1,138 @@
1
+ require_relative 'helper'
2
+
3
+ describe Type do
4
+ describe Type::Top do
5
+ before do
6
+ @type = Type::Top.new
7
+ end
8
+
9
+ it 'converts to type' do
10
+ @type.to_type.should.be.equal @type
11
+ end
12
+
13
+ it 'is a singleton' do
14
+ @type.should.be.equal @type
15
+ end
16
+
17
+ it 'should be ==, eql?, subtype_of? and have the same hash as itself' do
18
+ @type.should == @type
19
+ @type.should.be.eql @type
20
+ @type.should.be.subtype_of @type
21
+ @type.hash.should == @type.hash
22
+ end
23
+
24
+ it 'can replace itself' do
25
+ @type.replace_type_with(@type, Type::Bottom.new).
26
+ should == Type::Bottom.new
27
+ @type.replace_type_with(Type::Bottom.new, nil).
28
+ should == @type
29
+ end
30
+
31
+ it 'can specialize only itself' do
32
+ @type.specialize(@type).should == {}
33
+ -> { @type.specialize(Type::Bottom.new) }.should.raise(ArgumentError)
34
+ end
35
+
36
+ it 'pretty prints' do
37
+ @type.awesome_print.should == 'top'
38
+ end
39
+ end
40
+
41
+ describe Type::Bottom do
42
+ before do
43
+ @type = Type::Bottom.new
44
+ end
45
+
46
+ it 'converts to string' do
47
+ @type.to_s.should == 'bottom'
48
+ end
49
+
50
+ it 'pretty prints' do
51
+ @type.awesome_print.should == 'bottom'
52
+ end
53
+ end
54
+
55
+ describe Type::Value do
56
+ before do
57
+ @type = Type::Value.new(1)
58
+ end
59
+
60
+ it 'allows to retrieve value' do
61
+ @type.value.should == 1
62
+ end
63
+
64
+ it 'is a singleton' do
65
+ @type.should.be.equal Type::Value.new(1)
66
+ end
67
+
68
+ it 'converts to string as \'value' do
69
+ @type.to_s.should == %{'1}
70
+ end
71
+
72
+ it 'pretty prints' do
73
+ @type.awesome_print.should == '\'1'
74
+ end
75
+ end
76
+
77
+ describe Type::Variable do
78
+ before do
79
+ @var = Type::Variable.new
80
+ end
81
+
82
+ it 'allocates distinct instances' do
83
+ Type::Variable.new.
84
+ should.not.equal? Type::Variable.new
85
+ end
86
+
87
+ it 'converts to type' do
88
+ @var.to_type.should.equal? @var
89
+ end
90
+
91
+ it 'is a subtype of itself' do
92
+ @var.should.be.subtype_of @var
93
+ end
94
+
95
+ it 'is a supertype of itself' do
96
+ @var.should.be.supertype_of @var
97
+ end
98
+
99
+ it 'compares by identity' do
100
+ @var.should == @var
101
+ @var.should.not == Type::Variable.new
102
+ end
103
+
104
+ it 'can replace itself' do
105
+ @var.replace_type_with(@var, Type::Bottom.new).
106
+ should == Type::Bottom.new
107
+ @var.replace_type_with(Type::Bottom.new, nil).
108
+ should == @var
109
+ end
110
+
111
+ it 'specializes' do
112
+ @var.specialize(Type::Top.new).
113
+ should == { @var => Type::Top.new }
114
+ end
115
+
116
+ it 'pretty prints' do
117
+ @var.awesome_print.should == '~a'
118
+ end
119
+ end
120
+
121
+ describe Type::Variable::Annotator do
122
+ before do
123
+ @annotator = Type::Variable::Annotator.new
124
+ end
125
+
126
+ it 'annotates variables with successive letters' do
127
+ var1, var2 = 2.times.map { Type::Variable.new }
128
+
129
+ @annotator.annotate(var1).should == 'a'
130
+ @annotator.annotate(var1).should == 'a'
131
+ @annotator.annotate(var2).should == 'b'
132
+ end
133
+
134
+ it 'only annotates type variables' do
135
+ -> { @annotator.annotate(:foo) }.should.raise(ArgumentError)
136
+ end
137
+ end
138
+ end
metadata CHANGED
@@ -1,149 +1,126 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: furnace
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: 6
5
- version: 0.4.0.beta.1
4
+ version: 0.4.0.beta.2
6
5
  platform: ruby
7
6
  authors:
8
7
  - Peter Zotov
9
- autorequire:
8
+ autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-01-10 00:00:00.000000000 Z
11
+ date: 2013-03-31 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: ansi
16
- version_requirements: !ruby/object:Gem::Requirement
17
- requirements:
18
- - - ">="
19
- - !ruby/object:Gem::Version
20
- version: !binary |-
21
- MA==
22
- none: false
23
15
  requirement: !ruby/object:Gem::Requirement
24
16
  requirements:
25
- - - ">="
17
+ - - '>='
26
18
  - !ruby/object:Gem::Version
27
- version: !binary |-
28
- MA==
29
- none: false
30
- prerelease: false
19
+ version: '0'
31
20
  type: :runtime
32
- - !ruby/object:Gem::Dependency
33
- name: rake
21
+ prerelease: false
34
22
  version_requirements: !ruby/object:Gem::Requirement
35
23
  requirements:
36
- - - "~>"
24
+ - - '>='
37
25
  - !ruby/object:Gem::Version
38
- version: '10.0'
39
- none: false
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
40
29
  requirement: !ruby/object:Gem::Requirement
41
30
  requirements:
42
- - - "~>"
31
+ - - ~>
43
32
  - !ruby/object:Gem::Version
44
33
  version: '10.0'
45
- none: false
46
- prerelease: false
47
34
  type: :development
48
- - !ruby/object:Gem::Dependency
49
- name: bacon
35
+ prerelease: false
50
36
  version_requirements: !ruby/object:Gem::Requirement
51
37
  requirements:
52
- - - "~>"
38
+ - - ~>
53
39
  - !ruby/object:Gem::Version
54
- version: '1.2'
55
- none: false
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bacon
56
43
  requirement: !ruby/object:Gem::Requirement
57
44
  requirements:
58
- - - "~>"
45
+ - - ~>
59
46
  - !ruby/object:Gem::Version
60
47
  version: '1.2'
61
- none: false
62
- prerelease: false
63
48
  type: :development
64
- - !ruby/object:Gem::Dependency
65
- name: bacon-colored_output
49
+ prerelease: false
66
50
  version_requirements: !ruby/object:Gem::Requirement
67
51
  requirements:
68
- - - ">="
52
+ - - ~>
69
53
  - !ruby/object:Gem::Version
70
- version: !binary |-
71
- MA==
72
- none: false
54
+ version: '1.2'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bacon-colored_output
73
57
  requirement: !ruby/object:Gem::Requirement
74
58
  requirements:
75
- - - ">="
59
+ - - '>='
76
60
  - !ruby/object:Gem::Version
77
- version: !binary |-
78
- MA==
79
- none: false
80
- prerelease: false
61
+ version: '0'
81
62
  type: :development
82
- - !ruby/object:Gem::Dependency
83
- name: simplecov
63
+ prerelease: false
84
64
  version_requirements: !ruby/object:Gem::Requirement
85
65
  requirements:
86
- - - ">="
66
+ - - '>='
87
67
  - !ruby/object:Gem::Version
88
- version: !binary |-
89
- MA==
90
- none: false
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: simplecov
91
71
  requirement: !ruby/object:Gem::Requirement
92
72
  requirements:
93
- - - ">="
73
+ - - '>='
94
74
  - !ruby/object:Gem::Version
95
- version: !binary |-
96
- MA==
97
- none: false
98
- prerelease: false
75
+ version: '0'
99
76
  type: :development
100
- - !ruby/object:Gem::Dependency
101
- name: yard
77
+ prerelease: false
102
78
  version_requirements: !ruby/object:Gem::Requirement
103
79
  requirements:
104
- - - ">="
80
+ - - '>='
105
81
  - !ruby/object:Gem::Version
106
- version: !binary |-
107
- MA==
108
- none: false
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: yard
109
85
  requirement: !ruby/object:Gem::Requirement
110
86
  requirements:
111
- - - ">="
87
+ - - '>='
112
88
  - !ruby/object:Gem::Version
113
- version: !binary |-
114
- MA==
115
- none: false
116
- prerelease: false
89
+ version: '0'
117
90
  type: :development
118
- - !ruby/object:Gem::Dependency
119
- name: kramdown
91
+ prerelease: false
120
92
  version_requirements: !ruby/object:Gem::Requirement
121
93
  requirements:
122
- - - ">="
94
+ - - '>='
123
95
  - !ruby/object:Gem::Version
124
- version: !binary |-
125
- MA==
126
- none: false
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: kramdown
127
99
  requirement: !ruby/object:Gem::Requirement
128
100
  requirements:
129
- - - ">="
101
+ - - '>='
130
102
  - !ruby/object:Gem::Version
131
- version: !binary |-
132
- MA==
133
- none: false
134
- prerelease: false
103
+ version: '0'
135
104
  type: :development
136
- description: Furnace is a static code analysis framework for dynamic languages, aimed at efficient type and behavior inference.
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: Furnace is a static code analysis framework for dynamic languages, aimed
112
+ at efficient type and behavior inference.
137
113
  email:
138
114
  - whitequark@whitequark.org
139
115
  executables: []
140
116
  extensions: []
141
117
  extra_rdoc_files: []
142
118
  files:
143
- - ".gitignore"
144
- - ".travis.yml"
145
- - ".yardopts"
119
+ - .gitignore
120
+ - .travis.yml
121
+ - .yardopts
146
122
  - Gemfile
123
+ - INSTRUMENT.md
147
124
  - LICENSE.MIT
148
125
  - Rakefile
149
126
  - furnace.gemspec
@@ -152,65 +129,66 @@ files:
152
129
  - lib/furnace/ast/node.rb
153
130
  - lib/furnace/ast/processor.rb
154
131
  - lib/furnace/ast/sexp.rb
155
- - lib/furnace/graphviz.rb
132
+ - lib/furnace/awesome_printer.rb
133
+ - lib/furnace/context.rb
156
134
  - lib/furnace/ssa.rb
157
135
  - lib/furnace/ssa/argument.rb
158
136
  - lib/furnace/ssa/basic_block.rb
159
137
  - lib/furnace/ssa/builder.rb
160
138
  - lib/furnace/ssa/constant.rb
139
+ - lib/furnace/ssa/event_stream.rb
161
140
  - lib/furnace/ssa/function.rb
162
141
  - lib/furnace/ssa/generic_instruction.rb
163
- - lib/furnace/ssa/generic_type.rb
164
142
  - lib/furnace/ssa/instruction.rb
165
143
  - lib/furnace/ssa/instruction_syntax.rb
166
144
  - lib/furnace/ssa/instructions/branch.rb
167
145
  - lib/furnace/ssa/instructions/phi.rb
168
146
  - lib/furnace/ssa/instructions/return.rb
147
+ - lib/furnace/ssa/instructions/return_value.rb
148
+ - lib/furnace/ssa/instrumentation.rb
169
149
  - lib/furnace/ssa/module.rb
170
150
  - lib/furnace/ssa/named_value.rb
171
- - lib/furnace/ssa/pretty_printer.rb
172
151
  - lib/furnace/ssa/terminator_instruction.rb
173
- - lib/furnace/ssa/type.rb
174
152
  - lib/furnace/ssa/types/basic_block.rb
175
153
  - lib/furnace/ssa/types/function.rb
176
- - lib/furnace/ssa/types/void.rb
177
154
  - lib/furnace/ssa/user.rb
178
155
  - lib/furnace/ssa/value.rb
179
156
  - lib/furnace/transform/iterative.rb
180
157
  - lib/furnace/transform/pipeline.rb
158
+ - lib/furnace/type.rb
159
+ - lib/furnace/type/bottom.rb
160
+ - lib/furnace/type/top.rb
161
+ - lib/furnace/type/value.rb
162
+ - lib/furnace/type/variable.rb
181
163
  - lib/furnace/version.rb
182
- - test/ast_test.rb
183
- - test/ssa_test.rb
184
- - test/test_helper.rb
185
- - test/transform_test.rb
164
+ - test/helper.rb
165
+ - test/test_ast.rb
166
+ - test/test_awesome_printer.rb
167
+ - test/test_ssa.rb
168
+ - test/test_transform.rb
169
+ - test/test_type.rb
186
170
  homepage: http://github.com/whitequark/furnace
187
171
  licenses: []
188
- post_install_message:
172
+ metadata: {}
173
+ post_install_message:
189
174
  rdoc_options: []
190
175
  require_paths:
191
176
  - lib
192
177
  required_ruby_version: !ruby/object:Gem::Requirement
193
178
  requirements:
194
- - - ">="
179
+ - - '>='
195
180
  - !ruby/object:Gem::Version
196
- segments:
197
- - 0
198
- hash: 2
199
- version: !binary |-
200
- MA==
201
- none: false
181
+ version: '0'
202
182
  required_rubygems_version: !ruby/object:Gem::Requirement
203
183
  requirements:
204
- - - !binary |-
205
- Pg==
184
+ - - '>'
206
185
  - !ruby/object:Gem::Version
207
186
  version: 1.3.1
208
- none: false
209
187
  requirements: []
210
- rubyforge_project:
211
- rubygems_version: 1.8.24
212
- signing_key:
213
- specification_version: 3
188
+ rubyforge_project:
189
+ rubygems_version: 2.0.0
190
+ signing_key:
191
+ specification_version: 4
214
192
  summary: A static code analysis framework
215
193
  test_files: []
216
- has_rdoc:
194
+ has_rdoc:
@@ -1,49 +0,0 @@
1
- require 'furnace'
2
-
3
- class Furnace::Graphviz
4
- def initialize
5
- @code = "digraph {\n"
6
- @code << "node [labeljust=l,nojustify=true,fontname=monospace];"
7
- @code << "rankdir=TB;\n"
8
-
9
- yield self
10
-
11
- @code << "}"
12
- end
13
-
14
- def node(name, content, options={})
15
- content.gsub!("&", "&amp;")
16
- content.gsub!(">", "&gt;")
17
- content.gsub!("<", "&lt;")
18
- content.gsub!(/\*\*(.+?)\*\*/, '<b>\1</b>')
19
- content = content.lines.map { |l| %Q{<tr><td align="left">#{l}</td></tr>} }.join
20
-
21
- if content.empty?
22
- label = "<&lt;empty&gt;>"
23
- else
24
- label = "<<table border=\"0\">#{content}</table>>"
25
- end
26
-
27
- options = options.merge({
28
- shape: 'box',
29
- label: label
30
- })
31
-
32
- @code << %Q{"#{name.inspect}" #{graphviz_options(options)};\n}
33
- end
34
-
35
- def edge(from, to, label="", options={})
36
- options = options.merge({
37
- label: label.inspect
38
- })
39
- @code << %Q{"#{from.inspect}" -> "#{to.inspect}" #{graphviz_options(options)};\n}
40
- end
41
-
42
- def to_s
43
- @code
44
- end
45
-
46
- def graphviz_options(options)
47
- "[#{options.map { |k,v| "#{k}=#{v}" }.join(",")}]"
48
- end
49
- end