yadriggy 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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>] func_names the types of the original methods.
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
- def error(ast, msg)
475
- @nerrors += 1
476
- @messages << "#{ast.source_location_string}: #{msg}"
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
@@ -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>' ]
@@ -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 {CodeGen#call_with_block}
320
- # @see {#typecheck_call_with_block}
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
@@ -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)
@@ -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
- @error = nil
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
- # @return [String] an error message when the last invocation of check()
88
- # returns nil.
89
- def error
90
- @error || ''
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
@@ -115,7 +115,11 @@ module Yadriggy
115
115
  end
116
116
 
117
117
  def assign(expr)
118
- binary(expr)
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)
@@ -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
- print(ast.left)
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
- print(ast.right)
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