yadriggy 1.1.0 → 1.2.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/.yardopts +3 -0
- data/README.md +12 -9
- data/Rakefile +5 -0
- data/lib/yadriggy.rb +1 -1
- data/lib/yadriggy/algebra.rb +31 -3
- data/lib/yadriggy/assert.rb +8 -8
- data/lib/yadriggy/ast.rb +71 -15
- data/lib/yadriggy/ast_location.rb +1 -1
- data/lib/yadriggy/c/c.rb +5 -5
- data/lib/yadriggy/c/codegen.rb +12 -27
- data/lib/yadriggy/c/config.rb +1 -1
- data/lib/yadriggy/c/ctype.rb +5 -5
- data/lib/yadriggy/c/ctypecheck.rb +6 -6
- data/lib/yadriggy/c/ffi.rb +8 -8
- data/lib/yadriggy/checker.rb +60 -26
- data/lib/yadriggy/eval.rb +5 -1
- data/lib/yadriggy/eval_all.rb +13 -0
- data/lib/yadriggy/pretty_print.rb +14 -6
- data/lib/yadriggy/py.rb +11 -0
- data/lib/yadriggy/py/codegen.rb +457 -0
- data/lib/yadriggy/py/import.rb +90 -0
- data/lib/yadriggy/py/py_typechecker.rb +62 -0
- data/lib/yadriggy/py/python.rb +130 -0
- data/lib/yadriggy/ruby_typecheck.rb +96 -45
- data/lib/yadriggy/ruby_typeinfer.rb +60 -25
- data/lib/yadriggy/source_code.rb +27 -17
- data/lib/yadriggy/syntax.rb +23 -8
- data/lib/yadriggy/type.rb +38 -38
- data/lib/yadriggy/typecheck.rb +18 -5
- data/lib/yadriggy/version.rb +1 -1
- data/yadriggy.gemspec +2 -1
- metadata +24 -4
data/lib/yadriggy/c/codegen.rb
CHANGED
@@ -23,25 +23,11 @@ module Yadriggy
|
|
23
23
|
@typechecker = typechecker
|
24
24
|
@func_counter = 0
|
25
25
|
@func_names = {}
|
26
|
-
@nerrors = 0
|
27
|
-
@messages = []
|
28
26
|
@public_methods = {}
|
29
27
|
public_methods.each {|m| @public_methods[m.tree] = m.tree }
|
30
28
|
@gvariables = {}
|
31
29
|
end
|
32
30
|
|
33
|
-
# Tests whether a type error was found.
|
34
|
-
#
|
35
|
-
def errors?
|
36
|
-
@nerrors > 0
|
37
|
-
end
|
38
|
-
|
39
|
-
# Gets an array of error messages.
|
40
|
-
#
|
41
|
-
def error_messages
|
42
|
-
@messages
|
43
|
-
end
|
44
|
-
|
45
31
|
# Gets the type checker.
|
46
32
|
#
|
47
33
|
def typechecker
|
@@ -99,7 +85,7 @@ module Yadriggy
|
|
99
85
|
rule(InstanceVariable) do
|
100
86
|
t = @typechecker.type(ast)
|
101
87
|
vname = @gvariables[InstanceType.role(t)&.object]
|
102
|
-
error(ast, 'unknown instance variable') if vname.nil?
|
88
|
+
error!(ast, 'unknown instance variable') if vname.nil?
|
103
89
|
@printer << vname
|
104
90
|
end
|
105
91
|
|
@@ -153,7 +139,7 @@ module Yadriggy
|
|
153
139
|
end
|
154
140
|
|
155
141
|
rule(Dots) do
|
156
|
-
error(ast, 'a range object is not available')
|
142
|
+
error!(ast, 'a range object is not available')
|
157
143
|
end
|
158
144
|
|
159
145
|
rule(Call) do
|
@@ -199,7 +185,7 @@ module Yadriggy
|
|
199
185
|
rule(Conditional) do
|
200
186
|
case ast.op
|
201
187
|
when :unless, :unless_mod
|
202
|
-
error(ast, "a bad control statement")
|
188
|
+
error!(ast, "a bad control statement")
|
203
189
|
when :ifop
|
204
190
|
@printer << '('
|
205
191
|
check(ast.cond)
|
@@ -230,7 +216,7 @@ module Yadriggy
|
|
230
216
|
rule(Loop) do
|
231
217
|
case ast.op
|
232
218
|
when :until, :while_mod, :until_mod
|
233
|
-
error(ast, "#{ast.op} is not available")
|
219
|
+
error!(ast, "#{ast.op} is not available")
|
234
220
|
else
|
235
221
|
@printer << 'while ('
|
236
222
|
check(ast.cond)
|
@@ -355,7 +341,7 @@ module Yadriggy
|
|
355
341
|
parameters(expr, fname_str, mt)
|
356
342
|
@printer << ';' << :nl
|
357
343
|
else
|
358
|
-
error(expr, "bad method #{fname_str}")
|
344
|
+
error!(expr, "bad method #{fname_str}")
|
359
345
|
end
|
360
346
|
self
|
361
347
|
end
|
@@ -373,7 +359,7 @@ module Yadriggy
|
|
373
359
|
#
|
374
360
|
# @param [Array<String>] func_names the names of the generated
|
375
361
|
# functions.
|
376
|
-
# @param [Array<Type>]
|
362
|
+
# @param [Array<Type>] func_types the types of the original methods.
|
377
363
|
# @return [Array<String>, Array<Type>] the names and types.
|
378
364
|
def expand_functions(func_names, func_types)
|
379
365
|
return func_names, func_types
|
@@ -421,7 +407,7 @@ module Yadriggy
|
|
421
407
|
if mt
|
422
408
|
parameters(expr, fname, mt)
|
423
409
|
else
|
424
|
-
error(expr, 'not a function')
|
410
|
+
error!(expr, 'not a function')
|
425
411
|
end
|
426
412
|
|
427
413
|
@printer << ' {'
|
@@ -449,7 +435,7 @@ module Yadriggy
|
|
449
435
|
@printer << c_type(param_types[i]) << ' ' << p.name
|
450
436
|
end
|
451
437
|
else
|
452
|
-
error(expr, 'bad parameter types')
|
438
|
+
error!(expr, 'bad parameter types')
|
453
439
|
end
|
454
440
|
@printer << ')'
|
455
441
|
end
|
@@ -458,7 +444,7 @@ module Yadriggy
|
|
458
444
|
def local_var_declarations(def_or_block)
|
459
445
|
local_vars = @typechecker.local_vars_table[def_or_block]
|
460
446
|
if local_vars.nil?
|
461
|
-
error(def_or_block, 'bad function definition or block')
|
447
|
+
error!(def_or_block, 'bad function definition or block')
|
462
448
|
else
|
463
449
|
local_vars.each do |name, type|
|
464
450
|
@printer << c_type(type) << ' ' << name.to_s << ';' << :nl
|
@@ -471,11 +457,10 @@ module Yadriggy
|
|
471
457
|
CFI::c_type_name(type)
|
472
458
|
end
|
473
459
|
|
474
|
-
|
475
|
-
|
476
|
-
|
460
|
+
# @api private
|
461
|
+
def error_group
|
462
|
+
'code generation'
|
477
463
|
end
|
478
|
-
|
479
464
|
end # end of CodeGen
|
480
465
|
end
|
481
466
|
end
|
data/lib/yadriggy/c/config.rb
CHANGED
@@ -42,7 +42,7 @@ module Yadriggy
|
|
42
42
|
|
43
43
|
# Compiler option for OpenCL
|
44
44
|
# @return [String]
|
45
|
-
OpenCLoptions = '-framework opencl '
|
45
|
+
OpenCLoptions = '-framework opencl -DCL_SILENCE_DEPRECATION '
|
46
46
|
|
47
47
|
# Lines inserted in the generated OpenCL source file.
|
48
48
|
OpenCLHeaders = [ '#include <OpenCL/opencl.h>' ]
|
data/lib/yadriggy/c/ctype.rb
CHANGED
@@ -17,7 +17,7 @@ module Yadriggy
|
|
17
17
|
class Float32
|
18
18
|
end
|
19
19
|
|
20
|
-
# @private
|
20
|
+
# @api private
|
21
21
|
# An alias `RubyClass[Float32]`.
|
22
22
|
Float32Type = RubyClass[Float32]
|
23
23
|
|
@@ -33,11 +33,11 @@ module Yadriggy
|
|
33
33
|
include Yadriggy::C::CType
|
34
34
|
end
|
35
35
|
|
36
|
-
# @private
|
36
|
+
# @api private
|
37
37
|
# Array type available only in C code.
|
38
38
|
# See also {IntArray} and {FloatArray} in `ffi.rb`.
|
39
39
|
class CArray < IvarObj
|
40
|
-
# @private
|
40
|
+
# @api private
|
41
41
|
def typedecl(arg) end
|
42
42
|
|
43
43
|
# debug mode.
|
@@ -53,14 +53,14 @@ module Yadriggy
|
|
53
53
|
@debug = false
|
54
54
|
end
|
55
55
|
|
56
|
-
# @private
|
56
|
+
# @api private
|
57
57
|
# @abstract
|
58
58
|
# @return [Type] the element type.
|
59
59
|
def type()
|
60
60
|
Undef
|
61
61
|
end
|
62
62
|
|
63
|
-
# @private
|
63
|
+
# @api private
|
64
64
|
def check_range(indexes)
|
65
65
|
raise 'wrong number of indexes' unless indexes.size == @sizes.size
|
66
66
|
indexes.each_index do |i|
|
@@ -96,7 +96,7 @@ module Yadriggy
|
|
96
96
|
Void
|
97
97
|
end
|
98
98
|
|
99
|
-
# @private
|
99
|
+
# @api private
|
100
100
|
# @param [ASTnode] type_expr
|
101
101
|
def typedecl_type(type_expr)
|
102
102
|
if type_expr.is_a?(Call)
|
@@ -116,7 +116,7 @@ module Yadriggy
|
|
116
116
|
end
|
117
117
|
end
|
118
118
|
|
119
|
-
# @private
|
119
|
+
# @api private
|
120
120
|
def declare_type(name, name_ast, t)
|
121
121
|
if name == 'return' || name == 'foreign'
|
122
122
|
type_assert(valid_type?(t) || t == Void,
|
@@ -135,7 +135,7 @@ module Yadriggy
|
|
135
135
|
end
|
136
136
|
end
|
137
137
|
|
138
|
-
# @private
|
138
|
+
# @api private
|
139
139
|
def check_duplicate(name, t)
|
140
140
|
old_type = type_env.bound_name?(name)
|
141
141
|
type_assert(old_type.nil? || old_type == t,
|
@@ -204,7 +204,7 @@ module Yadriggy
|
|
204
204
|
binary_cexpr_type(ast.op, t1, t2)
|
205
205
|
end
|
206
206
|
|
207
|
-
# @private
|
207
|
+
# @api private
|
208
208
|
def binary_cexpr_type(op, t1, t2)
|
209
209
|
case op
|
210
210
|
when :+, :-, :*, :/
|
@@ -316,8 +316,8 @@ module Yadriggy
|
|
316
316
|
# Specifies the names of methods with a block.
|
317
317
|
#
|
318
318
|
# @param [String] name a method name.
|
319
|
-
# @see
|
320
|
-
# @see
|
319
|
+
# @see CodeGen#call_with_block
|
320
|
+
# @see #typecheck_call_with_block
|
321
321
|
def method_with_block?(name)
|
322
322
|
name == 'times'
|
323
323
|
end
|
data/lib/yadriggy/c/ffi.rb
CHANGED
@@ -130,7 +130,7 @@ module Yadriggy
|
|
130
130
|
end
|
131
131
|
end
|
132
132
|
|
133
|
-
# @private
|
133
|
+
# @api private
|
134
134
|
# Attaches functions to a module. The functions are retrieved
|
135
135
|
# from the library generated by compiling Ruby methods.
|
136
136
|
#
|
@@ -159,7 +159,7 @@ module Yadriggy
|
|
159
159
|
module_obj
|
160
160
|
end
|
161
161
|
|
162
|
-
# @private
|
162
|
+
# @api private
|
163
163
|
# Generates a Ruby source file. When the file is executed,
|
164
164
|
# it retrieves functions from the library generated by
|
165
165
|
# compiling Ruby methods, and then it attaches the functions
|
@@ -199,7 +199,7 @@ module Yadriggy
|
|
199
199
|
file_name
|
200
200
|
end
|
201
201
|
|
202
|
-
# @private
|
202
|
+
# @api private
|
203
203
|
def self.invoker_name(mtype)
|
204
204
|
case ArrayType.role(MethodType.role(mtype)&.result_type)&.element_type
|
205
205
|
when RubyClass::Integer
|
@@ -213,25 +213,25 @@ module Yadriggy
|
|
213
213
|
end
|
214
214
|
end
|
215
215
|
|
216
|
-
# @private
|
216
|
+
# @api private
|
217
217
|
def self.invoke_int(module_obj, func_name, args)
|
218
218
|
r = invoke(module_obj, func_name, args)
|
219
219
|
IntArray.new(0, r)
|
220
220
|
end
|
221
221
|
|
222
|
-
# @private
|
222
|
+
# @api private
|
223
223
|
def self.invoke_float(module_obj, func_name, args)
|
224
224
|
r = invoke(module_obj, func_name, args)
|
225
225
|
FloatArray.new(0, r)
|
226
226
|
end
|
227
227
|
|
228
|
-
# @private
|
228
|
+
# @api private
|
229
229
|
def self.invoke_float32(module_obj, func_name, args)
|
230
230
|
r = invoke(module_obj, func_name, args)
|
231
231
|
Float32Array.new(0, r)
|
232
232
|
end
|
233
233
|
|
234
|
-
# @private
|
234
|
+
# @api private
|
235
235
|
def self.invoke(module_obj, func_name, args)
|
236
236
|
args2 = args.map do |e|
|
237
237
|
if e.is_a?(IntArray) || e.is_a?(FloatArray) || e.is_a?(Float32Array)
|
@@ -243,7 +243,7 @@ module Yadriggy
|
|
243
243
|
module_obj.method(func_name).call(*args2)
|
244
244
|
end
|
245
245
|
|
246
|
-
# @private
|
246
|
+
# @api private
|
247
247
|
# C Function Interface
|
248
248
|
module CFI
|
249
249
|
def self.param_types(method_type)
|
data/lib/yadriggy/checker.rb
CHANGED
@@ -24,13 +24,13 @@ module Yadriggy
|
|
24
24
|
@rule_declarators[node_type] = self
|
25
25
|
end
|
26
26
|
|
27
|
-
# @private
|
27
|
+
# @api private
|
28
28
|
# Initializes this class if necessary.
|
29
29
|
def self.check_init_class
|
30
30
|
init_class if @rules.nil?
|
31
31
|
end
|
32
32
|
|
33
|
-
# @private
|
33
|
+
# @api private
|
34
34
|
# @return [Array<Hash>] all the rules defined so far.
|
35
35
|
def self.all_rules
|
36
36
|
[@rules, @rule_declarators]
|
@@ -48,7 +48,7 @@ module Yadriggy
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
-
# @private
|
51
|
+
# @api private
|
52
52
|
# internal-use only. Don't call this.
|
53
53
|
# @return [Pair<Proc,Class>] a rule and the class declaring it, or nil.
|
54
54
|
#
|
@@ -77,17 +77,68 @@ module Yadriggy
|
|
77
77
|
# Initializes the object.
|
78
78
|
def initialize
|
79
79
|
self.class.check_init_class
|
80
|
-
@
|
80
|
+
@nerrors = 0
|
81
|
+
@messages = []
|
81
82
|
@check_list = []
|
82
83
|
@current_ast = nil
|
83
84
|
@current_env = nil
|
84
85
|
@rule_declarator = nil
|
85
86
|
end
|
86
87
|
|
87
|
-
#
|
88
|
-
#
|
89
|
-
|
90
|
-
|
88
|
+
# Tests whether a type error was found.
|
89
|
+
# @return [Boolean] true if an error message is recorded.
|
90
|
+
#
|
91
|
+
def errors?
|
92
|
+
@nerrors > 0
|
93
|
+
end
|
94
|
+
|
95
|
+
# Gets an array of error messages.
|
96
|
+
# @return [Array<String>] error messages or `[]`.
|
97
|
+
#
|
98
|
+
def error_messages
|
99
|
+
@messages
|
100
|
+
end
|
101
|
+
|
102
|
+
# The last error message.
|
103
|
+
#
|
104
|
+
# @return [String|nil] the message.
|
105
|
+
def last_error
|
106
|
+
@messages.last
|
107
|
+
end
|
108
|
+
|
109
|
+
# Throws an error.
|
110
|
+
#
|
111
|
+
# @param [ASTnode] an_ast the AST causing the error.
|
112
|
+
# @param [String] msg the error message.
|
113
|
+
# @return [void] always throws an exception.
|
114
|
+
def error_found!(an_ast, msg='')
|
115
|
+
emsg = error!(an_ast, msg)
|
116
|
+
raise CheckError.new(emsg)
|
117
|
+
end
|
118
|
+
|
119
|
+
# Records an error message.
|
120
|
+
#
|
121
|
+
# @param [ASTnode] an_ast the AST causing the error.
|
122
|
+
# @param [String] msg the error message.
|
123
|
+
#
|
124
|
+
def error!(an_ast, msg='')
|
125
|
+
loc = if an_ast.is_a?(ASTnode)
|
126
|
+
an_ast.source_location_string
|
127
|
+
else
|
128
|
+
''
|
129
|
+
end
|
130
|
+
emsg = "#{loc} DSL #{error_group} error. #{msg}"
|
131
|
+
@nerrors += 1
|
132
|
+
@messages << emsg
|
133
|
+
binding.pry if Yadriggy.debug > 1
|
134
|
+
emsg
|
135
|
+
end
|
136
|
+
|
137
|
+
# @api private
|
138
|
+
# The returned value is inserted into an error messagge
|
139
|
+
# as the error category.
|
140
|
+
def error_group
|
141
|
+
''
|
91
142
|
end
|
92
143
|
|
93
144
|
# Applies rules to the given AST.
|
@@ -136,7 +187,7 @@ module Yadriggy
|
|
136
187
|
end
|
137
188
|
end
|
138
189
|
|
139
|
-
# @private
|
190
|
+
# @api private
|
140
191
|
# internal use only
|
141
192
|
def apply_typing_rule(rule, an_ast, ast_tenv)
|
142
193
|
if rule.nil?
|
@@ -194,23 +245,6 @@ module Yadriggy
|
|
194
245
|
@check_list << [cur_ast, cur_env, proc]
|
195
246
|
end
|
196
247
|
|
197
|
-
# @private
|
198
|
-
def error_found!(an_ast, msg='')
|
199
|
-
loc = if an_ast.is_a?(ASTnode)
|
200
|
-
an_ast.source_location_string
|
201
|
-
else
|
202
|
-
''
|
203
|
-
end
|
204
|
-
@error = "#{loc} DSL #{error_group} error. #{msg}"
|
205
|
-
binding.pry if Yadriggy.debug > 1
|
206
|
-
raise CheckError.new(@error)
|
207
|
-
end
|
208
|
-
|
209
|
-
# @private
|
210
|
-
def error_group
|
211
|
-
''
|
212
|
-
end
|
213
|
-
|
214
248
|
init_class
|
215
249
|
end
|
216
250
|
end
|
data/lib/yadriggy/eval.rb
CHANGED
@@ -115,7 +115,11 @@ module Yadriggy
|
|
115
115
|
end
|
116
116
|
|
117
117
|
def assign(expr)
|
118
|
-
|
118
|
+
if expr.left.is_a?(Array) || expr.right.is_a?(Array)
|
119
|
+
raise NotImplementedError.new('multiple assignment')
|
120
|
+
else
|
121
|
+
binary(expr)
|
122
|
+
end
|
119
123
|
end
|
120
124
|
|
121
125
|
def array_ref(expr)
|
data/lib/yadriggy/eval_all.rb
CHANGED
@@ -51,6 +51,19 @@ module Yadriggy
|
|
51
51
|
evaluate(expr.right)
|
52
52
|
end
|
53
53
|
|
54
|
+
def assign(expr)
|
55
|
+
if expr.right.is_a?(Array)
|
56
|
+
expr.right.each {|e| evaluate(e) }
|
57
|
+
else
|
58
|
+
evaluate(expr.right)
|
59
|
+
end
|
60
|
+
if expr.left.is_a?(Array)
|
61
|
+
expr.left.each {|e| evaluate(e) }
|
62
|
+
else
|
63
|
+
evaluate(expr.left)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
54
67
|
def hash(expr)
|
55
68
|
expr.pairs.each {|p| p.each {|e| evaluate(e) }}
|
56
69
|
end
|
@@ -33,9 +33,17 @@ module Yadriggy
|
|
33
33
|
end
|
34
34
|
|
35
35
|
rule(Assign) do
|
36
|
-
|
36
|
+
if ast.left.is_a?(Array)
|
37
|
+
print_each(ast.left, true)
|
38
|
+
else
|
39
|
+
print(ast.left)
|
40
|
+
end
|
37
41
|
@printer << ' ' << ast.op << ' '
|
38
|
-
|
42
|
+
if ast.right.is_a?(Array)
|
43
|
+
print_each(ast.right, true)
|
44
|
+
else
|
45
|
+
print(ast.right)
|
46
|
+
end
|
39
47
|
end
|
40
48
|
|
41
49
|
rule(Name) do
|
@@ -137,7 +145,7 @@ module Yadriggy
|
|
137
145
|
is_cmd = ast.is_a?(Command)
|
138
146
|
print(ast.receiver) if ast.receiver
|
139
147
|
@printer << ast.op if ast.op
|
140
|
-
@printer << ast.name.name
|
148
|
+
@printer << ast.name.name if ast.name
|
141
149
|
print_arguments(ast.args, ast.block_arg, ast.block, is_cmd)
|
142
150
|
end
|
143
151
|
|
@@ -276,7 +284,7 @@ module Yadriggy
|
|
276
284
|
end
|
277
285
|
end
|
278
286
|
|
279
|
-
# @private
|
287
|
+
# @api private
|
280
288
|
def print_parameters(params_ast)
|
281
289
|
is_first = true
|
282
290
|
is_first = print_each(params_ast.params, is_first)
|
@@ -458,7 +466,7 @@ module Yadriggy
|
|
458
466
|
end
|
459
467
|
end
|
460
468
|
|
461
|
-
# @private
|
469
|
+
# @api private
|
462
470
|
def print_each(array, first)
|
463
471
|
array.each do |e|
|
464
472
|
if e
|
@@ -473,7 +481,7 @@ module Yadriggy
|
|
473
481
|
first
|
474
482
|
end
|
475
483
|
|
476
|
-
# @private
|
484
|
+
# @api private
|
477
485
|
def print_list(array, first)
|
478
486
|
array.each do |e|
|
479
487
|
if e
|