yadriggy 1.0.0 → 1.1.0
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.
- 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
|