arbol 0.0.2

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.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/bin/arbol +25 -0
  3. data/lib/arbol.rb +45 -0
  4. data/lib/base.rb +397 -0
  5. data/lib/builder.rb +102 -0
  6. data/lib/documentation.rb +19 -0
  7. data/lib/dsl.rb +168 -0
  8. data/lib/functions/add.rb +70 -0
  9. data/lib/functions/add_constrain.rb +70 -0
  10. data/lib/functions/add_modulo.rb +70 -0
  11. data/lib/functions/analog_pin.rb +316 -0
  12. data/lib/functions/choose.rb +74 -0
  13. data/lib/functions/const.rb +63 -0
  14. data/lib/functions/create_lookup.rb +63 -0
  15. data/lib/functions/create_ref.rb +48 -0
  16. data/lib/functions/crossfade.rb +73 -0
  17. data/lib/functions/divide.rb +70 -0
  18. data/lib/functions/feedback.rb +65 -0
  19. data/lib/functions/feedback_offset.rb +69 -0
  20. data/lib/functions/gamma.rb +61 -0
  21. data/lib/functions/greater_than.rb +70 -0
  22. data/lib/functions/greater_than_equals.rb +70 -0
  23. data/lib/functions/lamp_phase.rb +39 -0
  24. data/lib/functions/less_than.rb +70 -0
  25. data/lib/functions/less_than_equals.rb +70 -0
  26. data/lib/functions/lfo_square.rb +68 -0
  27. data/lib/functions/lfo_triangle.rb +72 -0
  28. data/lib/functions/lookup.rb +86 -0
  29. data/lib/functions/max.rb +70 -0
  30. data/lib/functions/min.rb +70 -0
  31. data/lib/functions/minus.rb +70 -0
  32. data/lib/functions/modulo.rb +70 -0
  33. data/lib/functions/noise.rb +49 -0
  34. data/lib/functions/noise_pixel.rb +49 -0
  35. data/lib/functions/phasor.rb +96 -0
  36. data/lib/functions/ref.rb +34 -0
  37. data/lib/functions/scale.rb +71 -0
  38. data/lib/functions/table.rb +16 -0
  39. data/lib/functions/times.rb +70 -0
  40. data/lib/functions/triangle.rb +69 -0
  41. data/lib/templates/arduino_library.ino.erb +75 -0
  42. metadata +84 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2a728cceb0dceb116c2f6fa8b2925924c20cb884
4
+ data.tar.gz: 26bb9a7f5dd197a3c97a3ec9442dad7ba33874aa
5
+ SHA512:
6
+ metadata.gz: ef26b9938d68ca5b33531090ae0c771da1cc305da4ec6a977fc061d085ada4652e33965ace15aa2388e440b580b73d9a86d4bc459c79c862f4177a3f4c736f76
7
+ data.tar.gz: dc709ab7bfa715079df2fc98b737198d04662e8badc3a3f126b4d44878e8ad7a4fc64b0c21d7c819670744285b9e2cc8e8e5f9f04bda811b61fe5697f33e3a9d
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'arbol'
4
+
5
+ # Arbol::Documentation.new.output_all_documentation
6
+
7
+ unless ARGV[0]
8
+ puts "you need to provide an input file"
9
+ exit(-1)
10
+ end
11
+
12
+ unless ARGV[1]
13
+ puts "you need to provide an output file"
14
+ exit(-1)
15
+ end
16
+
17
+ script_to_file(
18
+ ino_from_tree(
19
+ interpret_file(
20
+ ARGV[0],
21
+ binding
22
+ )
23
+ ),
24
+ ARGV[1]
25
+ )
@@ -0,0 +1,45 @@
1
+ require 'pp'
2
+ require_relative 'builder.rb'
3
+ require_relative 'dsl.rb'
4
+ require_relative 'documentation.rb'
5
+
6
+ # now that class_map is created.. import all functions
7
+ Dir.glob("#{File.dirname(__FILE__)}/functions/*.rb").each do |mod|
8
+ require_relative mod
9
+ end
10
+
11
+ # interprets a file into an arbol tree structure
12
+ def interpret_file(file_path, scope)
13
+ if file_path.match(/\.rb$/)
14
+ return interpret_dsl(File.read(file_path), scope)
15
+ elsif file_path.match(/\.json$/)
16
+ return interpret_json(File.read(file_path))
17
+ end
18
+ end
19
+
20
+ # creates an ino file from a tree structure.
21
+ def ino_from_tree(tree)
22
+ pp tree
23
+ tls, cycle, body = custom_arduino_script_body(tree)
24
+ # these are resolved inside the ERB
25
+ tls = tls.join("\n")
26
+ cycle = cycle.join("\n")
27
+ body = body.join("\n")
28
+ integer_scale = 8192
29
+ pixels = tree[:lamps]
30
+ pin = tree[:pin]
31
+ code = Arbol.libs.join("\n\n")
32
+ ERB.new(
33
+ IO.read(
34
+ "#{File.dirname(__FILE__)}/templates/arduino_library.ino.erb"
35
+ )
36
+ ).result(binding)
37
+ end
38
+
39
+ # write the script to file
40
+ def script_to_file(script, path)
41
+ puts "writing to script file #{path}"
42
+ File.open(path, 'w') do |f|
43
+ f.puts(script)
44
+ end
45
+ end
@@ -0,0 +1,397 @@
1
+ require 'securerandom'
2
+ require 'tsort'
3
+
4
+ class TsortableHash < Hash
5
+ include TSort
6
+ alias tsort_each_node each_key
7
+ def tsort_each_child(node, &block)
8
+ fetch(node).each(&block)
9
+ end
10
+ end
11
+
12
+ class ArbolHash < Hash
13
+ def +(y)
14
+ h = ArbolHash.new
15
+ h[:type] = 'add'
16
+ h[:op1] = self.to_h
17
+ h[:op2] = resolve(y)
18
+ h
19
+ end
20
+
21
+ def -(y)
22
+ h = ArbolHash.new
23
+ h[:type] = 'minus'
24
+ h[:op1] = self.to_h
25
+ h[:op2] = resolve(y)
26
+ h
27
+ end
28
+
29
+ def *(y)
30
+ h = ArbolHash.new
31
+ h[:type] = 'times'
32
+ h[:op1] = self.to_h
33
+ h[:op2] = resolve(y)
34
+ h
35
+ end
36
+
37
+ def /(y)
38
+ h = ArbolHash.new
39
+ h[:type] = 'divide'
40
+ h[:op1] = self.to_h
41
+ h[:op2] = resolve(y)
42
+ h
43
+ end
44
+
45
+ def %(y)
46
+ h = ArbolHash.new
47
+ h[:type] = 'modulo'
48
+ h[:op1] = self.to_h
49
+ h[:op2] = resolve(y)
50
+ h
51
+ end
52
+
53
+ def >(y)
54
+ h = ArbolHash.new
55
+ h[:type] = 'greater_than'
56
+ h[:left] = self.to_h
57
+ h[:right] = resolve(y)
58
+ h
59
+ end
60
+
61
+ def >=(y)
62
+ h = ArbolHash.new
63
+ h[:type] = 'greater_than_equals'
64
+ h[:left] = self.to_h
65
+ h[:right] = resolve(y)
66
+ h
67
+ end
68
+
69
+ def <(y)
70
+ h = ArbolHash.new
71
+ h[:type] = 'less_than'
72
+ h[:left] = self.to_h
73
+ h[:right] = resolve(y)
74
+ h
75
+ end
76
+
77
+ def <=(y)
78
+ h = ArbolHash.new
79
+ h[:type] = 'less_than_equals'
80
+ h[:left] = self.to_h
81
+ h[:right] = resolve(y)
82
+ h
83
+ end
84
+ end
85
+
86
+ module RefineBasics
87
+ refine Integer do
88
+ def +(y)
89
+ h = ArbolHash.new
90
+ h[:type] = 'add'
91
+ h[:op1] = resolve(self.to_i)
92
+ h[:op2] = resolve(y)
93
+ h
94
+ end
95
+
96
+ def -(y)
97
+ h = ArbolHash.new
98
+ h[:type] = 'minus'
99
+ h[:op1] = resolve(self.to_i)
100
+ h[:op2] = resolve(y)
101
+ h
102
+ end
103
+
104
+ def *(y)
105
+ h = ArbolHash.new
106
+ h[:type] = 'times'
107
+ h[:op1] = resolve(self.to_i)
108
+ h[:op2] = resolve(y)
109
+ h
110
+ end
111
+
112
+ def /(y)
113
+ h = ArbolHash.new
114
+ h[:type] = 'divide'
115
+ h[:op1] = resolve(self.to_i)
116
+ h[:op2] = resolve(y)
117
+ h
118
+ end
119
+
120
+ def %(y)
121
+ h = ArbolHash.new
122
+ h[:type] = 'modulo'
123
+ h[:op1] = resolve(self.to_i)
124
+ h[:op2] = resolve(y)
125
+ h
126
+ end
127
+
128
+ def >(y)
129
+ h = ArbolHash.new
130
+ h[:type] = 'greater_than'
131
+ h[:left] = self.to_i
132
+ h[:right] = resolve(y)
133
+ h
134
+ end
135
+
136
+ def >=(y)
137
+ h = ArbolHash.new
138
+ h[:type] = 'greater_than_equals'
139
+ h[:left] = self.to_i
140
+ h[:right] = resolve(y)
141
+ h
142
+ end
143
+
144
+ def <(y)
145
+ h = ArbolHash.new
146
+ h[:type] = 'less_than'
147
+ h[:left] = self.to_i
148
+ h[:right] = resolve(y)
149
+ h
150
+ end
151
+
152
+ def <=(y)
153
+ h = ArbolHash.new
154
+ h[:type] = 'less_than_equals'
155
+ h[:left] = self.to_i
156
+ h[:right] = resolve(y)
157
+ h
158
+ end
159
+ end
160
+
161
+ refine Float do
162
+ def +(y)
163
+ h = ArbolHash.new
164
+ h[:type] = 'add'
165
+ h[:op1] = resolve(self.to_f)
166
+ h[:op2] = resolve(y)
167
+ h
168
+ end
169
+
170
+ def -(y)
171
+ h = ArbolHash.new
172
+ h[:type] = 'minus'
173
+ h[:op1] = resolve(self.to_f)
174
+ h[:op2] = resolve(y)
175
+ h
176
+ end
177
+
178
+ def *(y)
179
+ h = ArbolHash.new
180
+ h[:type] = 'times'
181
+ h[:op1] = resolve(self.to_f)
182
+ h[:op2] = resolve(y)
183
+ h
184
+ end
185
+
186
+ def /(y)
187
+ h = ArbolHash.new
188
+ h[:type] = 'divide'
189
+ h[:op1] = resolve(self.to_f)
190
+ h[:op2] = resolve(y)
191
+ h
192
+ end
193
+
194
+ def %(y)
195
+ h = ArbolHash.new
196
+ h[:type] = 'modulo'
197
+ h[:op1] = resolve(self.to_f)
198
+ h[:op2] = resolve(y)
199
+ h
200
+ end
201
+
202
+ def >(y)
203
+ h = ArbolHash.new
204
+ h[:type] = 'greater_than'
205
+ h[:left] = self.to_f
206
+ h[:right] = resolve(y)
207
+ h
208
+ end
209
+
210
+ def >=(y)
211
+ h = ArbolHash.new
212
+ h[:type] = 'greater_than_equals'
213
+ h[:left] = self.to_f
214
+ h[:right] = resolve(y)
215
+ h
216
+ end
217
+
218
+ def <(y)
219
+ h = ArbolHash.new
220
+ h[:type] = 'less_than'
221
+ h[:left] = self.to_f
222
+ h[:right] = resolve(y)
223
+ h
224
+ end
225
+
226
+ def <=(y)
227
+ h = ArbolHash.new
228
+ h[:type] = 'less_than_equals'
229
+ h[:left] = self.to_f
230
+ h[:right] = resolve(y)
231
+ h
232
+ end
233
+ end
234
+
235
+ refine Array do
236
+ def +(y)
237
+ h = ArbolHash.new
238
+ h[:type] = 'add'
239
+ h[:op1] = resolve(self.to_a)
240
+ h[:op2] = resolve(y)
241
+ h
242
+ end
243
+
244
+ def -(y)
245
+ h = ArbolHash.new
246
+ h[:type] = 'minus'
247
+ h[:op1] = resolve(self.to_a)
248
+ h[:op2] = resolve(y)
249
+ h
250
+ end
251
+
252
+ def *(y)
253
+ h = ArbolHash.new
254
+ h[:type] = 'times'
255
+ h[:op1] = resolve(self.to_a)
256
+ h[:op2] = resolve(y)
257
+ h
258
+ end
259
+
260
+ def /(y)
261
+ h = ArbolHash.new
262
+ h[:type] = 'divide'
263
+ h[:op1] = resolve(self.to_a)
264
+ h[:op2] = resolve(y)
265
+ h
266
+ end
267
+
268
+ def %(y)
269
+ h = ArbolHash.new
270
+ h[:type] = 'modulo'
271
+ h[:op1] = resolve(self.to_a)
272
+ h[:op2] = resolve(y)
273
+ h
274
+ end
275
+
276
+ def >(y)
277
+ h = ArbolHash.new
278
+ h[:type] = 'greater_than'
279
+ h[:left] = self.to_a
280
+ h[:right] = resolve(y)
281
+ h
282
+ end
283
+
284
+ def >=(y)
285
+ h = ArbolHash.new
286
+ h[:type] = 'greater_than_equals'
287
+ h[:left] = self.to_a
288
+ h[:right] = resolve(y)
289
+ h
290
+ end
291
+
292
+ def <(y)
293
+ h = ArbolHash.new
294
+ h[:type] = 'less_than'
295
+ h[:left] = self.to_a
296
+ h[:right] = resolve(y)
297
+ h
298
+ end
299
+
300
+ def <=(y)
301
+ h = ArbolHash.new
302
+ h[:type] = 'less_than_equals'
303
+ h[:left] = self.to_a
304
+ h[:right] = resolve(y)
305
+ h
306
+ end
307
+ end
308
+ end
309
+
310
+ class Base
311
+ attr_accessor :name
312
+ attr_accessor :frame_optimized
313
+
314
+ def initialize(params)
315
+ @frame_optimized = true # default
316
+ @name = "#{self.class}_#{SecureRandom.uuid.to_s.gsub('-','')}"
317
+ param_keys.each do |k|
318
+ self.send("#{k.to_sym}=", params[k])
319
+ end
320
+ buildit
321
+ end
322
+
323
+ def buildit
324
+ param_keys.each do |k|
325
+ # puts "resolving #{k}"
326
+ self.send("#{k.to_sym}=", builder(self.send("#{k.to_s}")))
327
+ # puts "#{k} resolved"
328
+ end
329
+ end
330
+
331
+ def param_keys
332
+ []
333
+ end
334
+
335
+ def depends_on
336
+ return [] if param_keys == []
337
+ param_keys.map { |k| self.send("#{k}").name }
338
+ end
339
+
340
+ def arduino_code
341
+ []
342
+ end
343
+
344
+ def resolve_frame_optimized
345
+ # first resolve the children
346
+ param_keys.each do |k|
347
+ self.send("#{k}").resolve_frame_optimized
348
+ end
349
+
350
+ # check to see if any of the children can not be optimized
351
+ param_keys.each do |k|
352
+ # if so... mark self as false
353
+ if self.send("#{k}").frame_optimized == false
354
+ @frame_optimized = false
355
+ end
356
+ end
357
+ end
358
+
359
+ # only executed once per cycle
360
+ def cycle_level_arduino_code
361
+ []
362
+ end
363
+
364
+ # code to be executed in the top level scope.
365
+ # used for constant declaration
366
+ def top_level_scope_arduino_code
367
+ []
368
+ end
369
+
370
+ def append_tsortable(tsortable)
371
+ tsortable[@name] = depends_on
372
+ param_keys.each do |k|
373
+ self.send("#{k}").append_tsortable(tsortable)
374
+ end
375
+ end
376
+
377
+ def add_arduino_code(ir)
378
+ ir[@name] = arduino_code
379
+ param_keys.each do |k|
380
+ self.send("#{k}").add_arduino_code(ir)
381
+ end
382
+ end
383
+
384
+ def add_cycle_level_scope(ir)
385
+ ir[@name] = cycle_level_arduino_code
386
+ param_keys.each do |k|
387
+ self.send("#{k}").add_cycle_level_scope(ir)
388
+ end
389
+ end
390
+
391
+ def add_top_level_scope(ir)
392
+ ir[@name] = top_level_scope_code
393
+ param_keys.each do |k|
394
+ self.send("#{k}").add_top_level_scope(ir)
395
+ end
396
+ end
397
+ end