yadriggy 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/yadriggy/algebra.rb +1 -1
- data/lib/yadriggy/assert.rb +223 -0
- data/lib/yadriggy/ast.rb +3 -3
- data/lib/yadriggy/ast_value.rb +6 -6
- data/lib/yadriggy/c/c.rb +1 -1
- data/lib/yadriggy/c/codegen.rb +2 -2
- data/lib/yadriggy/c/ctypecheck.rb +2 -2
- data/lib/yadriggy/eval_all.rb +1 -1
- data/lib/yadriggy/pretty_print.rb +1 -1
- data/lib/yadriggy/ruby_typecheck.rb +1 -1
- data/lib/yadriggy/ruby_typeinfer.rb +2 -2
- data/lib/yadriggy/syntax.rb +1 -1
- data/lib/yadriggy/version.rb +1 -1
- metadata +3 -3
- data/lib/yadriggy/c1.rb +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 990b3b201219b7511cbcf4554f24b3dc9bd14128
|
4
|
+
data.tar.gz: 6a45aaa8d3f036656f787d7979dbd7954f636d34
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c295ef7bb85cefc84a43ac7459e28477e082bb28f093a797a1bde44fc02ac8578d802255bbb01f984056da4de554a1c6f9451a32d8b649b7122dacf25604bf36
|
7
|
+
data.tar.gz: 39b8d8ad06e9374558229724038f9db1f5edee7dc79f94fa3e470229784e3379dbf743754d6d731dcdbd9cf82f22bb1a046ad37d0cdb10aeb4d5976cacf05889
|
data/lib/yadriggy/algebra.rb
CHANGED
@@ -0,0 +1,223 @@
|
|
1
|
+
# Copyright (C) 2017- Shigeru Chiba. All rights reserved.
|
2
|
+
|
3
|
+
require 'yadriggy'
|
4
|
+
|
5
|
+
module Yadriggy
|
6
|
+
# Power assert by Yadriggy
|
7
|
+
module Assert
|
8
|
+
|
9
|
+
# Checks the given assertion is correct and prints the result
|
10
|
+
# if the assertion fails.
|
11
|
+
#
|
12
|
+
# @param [Proc] block the assertion.
|
13
|
+
def self.assert(&block)
|
14
|
+
reason = Reason.new
|
15
|
+
begin
|
16
|
+
res = assertion(reason, block)
|
17
|
+
puts_reason(reason) unless res
|
18
|
+
return res
|
19
|
+
rescue AssertFailure => evar
|
20
|
+
puts_reason(evar.reason, evar)
|
21
|
+
raise evar.cause
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# @private
|
26
|
+
def self.puts_reason(reason, evar=nil)
|
27
|
+
puts '--- Yadriggy::Assert ---'
|
28
|
+
print evar.cause.class.name, ': ' if evar&.cause
|
29
|
+
puts evar.message if evar&.message
|
30
|
+
puts(reason.ast.source_location_string)
|
31
|
+
puts(reason.show)
|
32
|
+
puts '------------------------'
|
33
|
+
end
|
34
|
+
|
35
|
+
# Checks the given assertion is correct.
|
36
|
+
#
|
37
|
+
# @param [Reason] reason the object where the reason that the assertion
|
38
|
+
# fails will be stored.
|
39
|
+
# @param [Proc] block the assertion.
|
40
|
+
# @return [Object] the result of executing the given block.
|
41
|
+
def self.assertion(reason, block)
|
42
|
+
return if block.nil?
|
43
|
+
ast = Yadriggy::reify(block)
|
44
|
+
begin
|
45
|
+
results = {}
|
46
|
+
reason.setup(ast.tree.body, results)
|
47
|
+
run_ast(ast.tree.body, block.binding, results)[1]
|
48
|
+
rescue => evar
|
49
|
+
raise AssertFailure.new(reason, evar.message, evar)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Reason that an assertion fails.
|
54
|
+
class Reason
|
55
|
+
# @private
|
56
|
+
def setup(ast, results)
|
57
|
+
@ast = ast
|
58
|
+
@results = results
|
59
|
+
end
|
60
|
+
|
61
|
+
# Gets the AST of the block given to {#assertion}.
|
62
|
+
# @return [ASTnode] an abstract syntax tree.
|
63
|
+
def ast() @ast end
|
64
|
+
|
65
|
+
# Gets the detailed results.
|
66
|
+
# @return [Hash<ASTnode,Pair<String,Object>>] a map from sub-expressions
|
67
|
+
# to their source and resulting vales. The sub-expressions are {ASTnode}
|
68
|
+
# objects.
|
69
|
+
def results() @results end
|
70
|
+
|
71
|
+
# Gets the text showing the values of the sub-expressions.
|
72
|
+
# @return [Array<String>] an array of lines.
|
73
|
+
def show
|
74
|
+
output = []
|
75
|
+
header = show2(@ast, '', output)
|
76
|
+
output << header
|
77
|
+
src, value = @results[ast]
|
78
|
+
if src.nil?
|
79
|
+
pp = PrettyPrinter.new(Printer.new(2))
|
80
|
+
pp.print(ast)
|
81
|
+
output << pp.printer.output
|
82
|
+
else
|
83
|
+
output << src
|
84
|
+
end
|
85
|
+
output.reverse!
|
86
|
+
end
|
87
|
+
|
88
|
+
# @private
|
89
|
+
# @return [String] the new header.
|
90
|
+
def show2(ast, header, output)
|
91
|
+
if ast.is_a?(Paren)
|
92
|
+
show2(ast.expression, header + ' ', output) + ' '
|
93
|
+
elsif ast.is_a?(Call) && ast.block_arg.nil? && ast.block.nil?
|
94
|
+
header2 = show2(ast.receiver, header, output)
|
95
|
+
src2, value2 = @results[ast.receiver]
|
96
|
+
src, value = @results[ast]
|
97
|
+
if src.nil?
|
98
|
+
src = PrettyPrinter.ast_to_s(ast)
|
99
|
+
if src2.nil?
|
100
|
+
"#{header}#{' ' * src.size}"
|
101
|
+
else
|
102
|
+
"#{header2}#{' ' * (src.size - src2.size)}"
|
103
|
+
end
|
104
|
+
else
|
105
|
+
output << "#{header2} #{str_rep(value)}"
|
106
|
+
"#{header2} |#{' ' * (src.size - src2.size - 2)}"
|
107
|
+
end
|
108
|
+
elsif ast.is_a?(Binary)
|
109
|
+
header = show2(ast.left, header, output)
|
110
|
+
src, value = @results[ast]
|
111
|
+
if src.nil?
|
112
|
+
header = header + ' '
|
113
|
+
else
|
114
|
+
output << "#{header} #{str_rep(value)}"
|
115
|
+
header = "#{header} | #{' ' * (ast.op.to_s.size - 1)}"
|
116
|
+
end
|
117
|
+
show2(ast.right, header, output)
|
118
|
+
elsif ast.is_a?(Unary)
|
119
|
+
src, value = @results[ast]
|
120
|
+
if src.nil?
|
121
|
+
header = header + ' '
|
122
|
+
else
|
123
|
+
output << "#{header}#{str_rep(value)}"
|
124
|
+
header = "#{header}|"
|
125
|
+
end
|
126
|
+
show2(ast.operand, header, output)
|
127
|
+
else
|
128
|
+
src, value = @results[ast]
|
129
|
+
if src.nil?
|
130
|
+
src = PrettyPrinter.ast_to_s(ast)
|
131
|
+
return "#{header}#{' ' * src.size}"
|
132
|
+
else
|
133
|
+
output << header + str_rep(value)
|
134
|
+
"#{header}|#{' ' * (src.size - 1)}"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
# @private
|
140
|
+
# Obtains the text representation of the given value.
|
141
|
+
def str_rep(v)
|
142
|
+
max = 70
|
143
|
+
str = v.inspect
|
144
|
+
if str.length < max
|
145
|
+
str
|
146
|
+
else
|
147
|
+
str[0, max] + '...'
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# Exception thrown by {#assertion}.
|
153
|
+
#
|
154
|
+
class AssertFailure < StandardError
|
155
|
+
def initialize(reason, msg=nil, cause=nil)
|
156
|
+
super(msg)
|
157
|
+
@reason = reason
|
158
|
+
@cause = cause
|
159
|
+
end
|
160
|
+
|
161
|
+
# Gets the cause.
|
162
|
+
# @return [StandardError] an exception.
|
163
|
+
def cause() @cause end
|
164
|
+
|
165
|
+
# Gets the reason.
|
166
|
+
# @return [Reason] the reason.
|
167
|
+
def reason() @reason end
|
168
|
+
end
|
169
|
+
|
170
|
+
# @private
|
171
|
+
# Executes the given AST and records the result.
|
172
|
+
# @param [ASTnode] ast the given AST.
|
173
|
+
# @param [Binding] blk_binding the binding for executing the AST.
|
174
|
+
# @param [Hash<ASTnode,Pair<String,Object>>] results a map from ASTs
|
175
|
+
# to their source and values.
|
176
|
+
# @return [Pair<String,Object>] the result of the execution of the given AST.
|
177
|
+
# It is also recorded in `results`.
|
178
|
+
# The first element is the source code and the second one is the resulting value.
|
179
|
+
def self.run_ast(ast, blk_binding, results)
|
180
|
+
if ast.is_a?(Paren)
|
181
|
+
res = run_ast(ast.expression, blk_binding, results)
|
182
|
+
src = "(#{res[0]})"
|
183
|
+
results[ast] = [src, res[1]]
|
184
|
+
elsif ast.is_a?(Call) && ast.block_arg.nil? && ast.block.nil?
|
185
|
+
if ast.receiver.nil?
|
186
|
+
receiver = ['self', blk_binding.eval('self')]
|
187
|
+
else
|
188
|
+
receiver = run_ast(ast.receiver, blk_binding, results)
|
189
|
+
end
|
190
|
+
args = ast.args.map {|e| run_ast(e, blk_binding, results) }
|
191
|
+
arg_values = args.map {|e| e[1] }
|
192
|
+
res = receiver[1].send(ast.name.name, *arg_values)
|
193
|
+
arg_src = args.each_with_object('') do |e, code|
|
194
|
+
code << ', ' if code.size > 0
|
195
|
+
code << e[0]
|
196
|
+
end
|
197
|
+
src = "#{receiver[0]}.#{ast.name.name.to_s}(#{arg_src.to_s})"
|
198
|
+
results[ast] = [src, res]
|
199
|
+
elsif ast.is_a?(Binary)
|
200
|
+
left_value = run_ast(ast.left, blk_binding, results)
|
201
|
+
right_value = run_ast(ast.right, blk_binding, results)
|
202
|
+
res = left_value[1].send(ast.op, right_value[1])
|
203
|
+
results[ast] = ["#{left_value[0]} #{ast.op.to_s} #{right_value[0]}", res]
|
204
|
+
elsif ast.is_a?(Unary)
|
205
|
+
value = run_ast(ast.operand, blk_binding, results)
|
206
|
+
res = value[1].send(ast.op)
|
207
|
+
results[ast] = ["#{ast.real_operator.to_s}#{value[0]}", res]
|
208
|
+
else
|
209
|
+
results[ast] = eval_by_ruby(ast, blk_binding)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
# @private
|
214
|
+
# Eval the AST by the RubyVM
|
215
|
+
# @return [Pair<String,Object>] an array. The first element is the source code
|
216
|
+
# and the second element is the resulting value.
|
217
|
+
def self.eval_by_ruby(ast, blk_binding)
|
218
|
+
src = PrettyPrinter.ast_to_s(ast)
|
219
|
+
loc = ast.source_location
|
220
|
+
[src, eval(src, blk_binding, loc[0], loc[1])]
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
data/lib/yadriggy/ast.rb
CHANGED
@@ -587,14 +587,14 @@ module Yadriggy
|
|
587
587
|
attr_reader :op
|
588
588
|
|
589
589
|
# @return [ASTnode] the operand.
|
590
|
-
attr_reader :
|
590
|
+
attr_reader :operand
|
591
591
|
|
592
592
|
def self.tag() :unary end
|
593
593
|
|
594
594
|
def initialize(sexp)
|
595
595
|
@op = sexp[1]
|
596
|
-
@
|
597
|
-
add_child(@
|
596
|
+
@operand = to_node(sexp[2])
|
597
|
+
add_child(@operand)
|
598
598
|
end
|
599
599
|
|
600
600
|
# Returns the real operator name.
|
data/lib/yadriggy/ast_value.rb
CHANGED
@@ -326,19 +326,19 @@ module Yadriggy
|
|
326
326
|
|
327
327
|
class Unary
|
328
328
|
def value()
|
329
|
-
send_op_to_value(@
|
329
|
+
send_op_to_value(@operand.value)
|
330
330
|
end
|
331
331
|
|
332
332
|
def value_in_class(klass)
|
333
|
-
send_op_to_value(@
|
333
|
+
send_op_to_value(@operand.value_in_class(klass))
|
334
334
|
end
|
335
335
|
|
336
336
|
def const_value()
|
337
|
-
send_op_to_value(@
|
337
|
+
send_op_to_value(@operand.const_value)
|
338
338
|
end
|
339
339
|
|
340
340
|
def const_value_in_class(klass)
|
341
|
-
send_op_to_value(@
|
341
|
+
send_op_to_value(@operand.const_value_in_class(klass))
|
342
342
|
end
|
343
343
|
|
344
344
|
private
|
@@ -357,7 +357,7 @@ module Yadriggy
|
|
357
357
|
end
|
358
358
|
|
359
359
|
def value_in_class(klass)
|
360
|
-
send_op_to_value(@
|
360
|
+
send_op_to_value(@left.value_in_class(klass),
|
361
361
|
@right.value_in_class(klass))
|
362
362
|
end
|
363
363
|
|
@@ -366,7 +366,7 @@ module Yadriggy
|
|
366
366
|
end
|
367
367
|
|
368
368
|
def const_value_in_class(klass)
|
369
|
-
send_op_to_value(@
|
369
|
+
send_op_to_value(@left.const_value_in_class(klass),
|
370
370
|
@right.const_value_in_class(klass))
|
371
371
|
end
|
372
372
|
|
data/lib/yadriggy/c/c.rb
CHANGED
@@ -57,7 +57,7 @@ module Yadriggy
|
|
57
57
|
typedecl <= Call +
|
58
58
|
{ name: typedecl_name, args: [ typedecl_hash ] }
|
59
59
|
|
60
|
-
return_type <= Unary + {
|
60
|
+
return_type <= Unary + { operand: Const | ConstPathRef | arrayof }
|
61
61
|
func_body <= return_type | stmnt |
|
62
62
|
Exprs + { expressions: [ (return_type), stmnt ] }
|
63
63
|
|
data/lib/yadriggy/c/codegen.rb
CHANGED
@@ -134,7 +134,7 @@ module Yadriggy
|
|
134
134
|
|
135
135
|
rule(Unary) do
|
136
136
|
@printer << ast.real_operator.to_s
|
137
|
-
check(ast.
|
137
|
+
check(ast.operand)
|
138
138
|
end
|
139
139
|
|
140
140
|
rule(Binary) do
|
@@ -153,7 +153,7 @@ module Yadriggy
|
|
153
153
|
end
|
154
154
|
|
155
155
|
rule(Dots) do
|
156
|
-
error(
|
156
|
+
error(ast, 'a range object is not available')
|
157
157
|
end
|
158
158
|
|
159
159
|
rule(Call) do
|
@@ -143,7 +143,7 @@ module Yadriggy
|
|
143
143
|
end
|
144
144
|
|
145
145
|
rule(:return_type) do
|
146
|
-
typedecl_type(ast.
|
146
|
+
typedecl_type(ast.operand)
|
147
147
|
end
|
148
148
|
|
149
149
|
rule(Number) do
|
@@ -248,7 +248,7 @@ module Yadriggy
|
|
248
248
|
end
|
249
249
|
|
250
250
|
rule(Unary) do
|
251
|
-
t = type(ast.
|
251
|
+
t = type(ast.operand)
|
252
252
|
type_assert(ast.op == :-@, "bad operator: #{ast.op}")
|
253
253
|
t
|
254
254
|
end
|
data/lib/yadriggy/eval_all.rb
CHANGED
@@ -169,7 +169,7 @@ module Yadriggy
|
|
169
169
|
|
170
170
|
# +@, -@, !, ~, not
|
171
171
|
rule(Unary) do
|
172
|
-
expr_t = type(ast.
|
172
|
+
expr_t = type(ast.operand)
|
173
173
|
op = ast.op
|
174
174
|
if op == :! || op == :not
|
175
175
|
RubyClass::Boolean
|
@@ -178,7 +178,7 @@ module Yadriggy
|
|
178
178
|
((op == :+@ || op == :-@) && expr_t <= RubyClass::Numeric)
|
179
179
|
expr_t
|
180
180
|
else
|
181
|
-
call_expr = Call.make(receiver: ast.
|
181
|
+
call_expr = Call.make(receiver: ast.operand, name: op,
|
182
182
|
parent: ast.parent)
|
183
183
|
get_call_expr_type(call_expr, type_env, op)
|
184
184
|
end
|
data/lib/yadriggy/syntax.rb
CHANGED
@@ -477,7 +477,7 @@ module Yadriggy
|
|
477
477
|
ArrayRefField <= ArrayRef
|
478
478
|
Assign <= Binary
|
479
479
|
Dots <= Binary
|
480
|
-
Unary <= { op: Symbol,
|
480
|
+
Unary <= { op: Symbol, operand: expr }
|
481
481
|
ConstPathRef <= { scope: (ConstPathRef | Const), name: Const }
|
482
482
|
ConstPathField <= ConstPathRef
|
483
483
|
StringLiteral <= { value: String }
|
data/lib/yadriggy/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yadriggy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shigeru Chiba
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-07-
|
11
|
+
date: 2018-07-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ffi
|
@@ -96,6 +96,7 @@ files:
|
|
96
96
|
- Rakefile
|
97
97
|
- lib/yadriggy.rb
|
98
98
|
- lib/yadriggy/algebra.rb
|
99
|
+
- lib/yadriggy/assert.rb
|
99
100
|
- lib/yadriggy/ast.rb
|
100
101
|
- lib/yadriggy/ast_location.rb
|
101
102
|
- lib/yadriggy/ast_value.rb
|
@@ -108,7 +109,6 @@ files:
|
|
108
109
|
- lib/yadriggy/c/ffi.rb
|
109
110
|
- lib/yadriggy/c/opencl.rb
|
110
111
|
- lib/yadriggy/c/program.rb
|
111
|
-
- lib/yadriggy/c1.rb
|
112
112
|
- lib/yadriggy/checker.rb
|
113
113
|
- lib/yadriggy/eval.rb
|
114
114
|
- lib/yadriggy/eval_all.rb
|