yadriggy 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|