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.
- checksums.yaml +7 -0
- data/bin/arbol +25 -0
- data/lib/arbol.rb +45 -0
- data/lib/base.rb +397 -0
- data/lib/builder.rb +102 -0
- data/lib/documentation.rb +19 -0
- data/lib/dsl.rb +168 -0
- data/lib/functions/add.rb +70 -0
- data/lib/functions/add_constrain.rb +70 -0
- data/lib/functions/add_modulo.rb +70 -0
- data/lib/functions/analog_pin.rb +316 -0
- data/lib/functions/choose.rb +74 -0
- data/lib/functions/const.rb +63 -0
- data/lib/functions/create_lookup.rb +63 -0
- data/lib/functions/create_ref.rb +48 -0
- data/lib/functions/crossfade.rb +73 -0
- data/lib/functions/divide.rb +70 -0
- data/lib/functions/feedback.rb +65 -0
- data/lib/functions/feedback_offset.rb +69 -0
- data/lib/functions/gamma.rb +61 -0
- data/lib/functions/greater_than.rb +70 -0
- data/lib/functions/greater_than_equals.rb +70 -0
- data/lib/functions/lamp_phase.rb +39 -0
- data/lib/functions/less_than.rb +70 -0
- data/lib/functions/less_than_equals.rb +70 -0
- data/lib/functions/lfo_square.rb +68 -0
- data/lib/functions/lfo_triangle.rb +72 -0
- data/lib/functions/lookup.rb +86 -0
- data/lib/functions/max.rb +70 -0
- data/lib/functions/min.rb +70 -0
- data/lib/functions/minus.rb +70 -0
- data/lib/functions/modulo.rb +70 -0
- data/lib/functions/noise.rb +49 -0
- data/lib/functions/noise_pixel.rb +49 -0
- data/lib/functions/phasor.rb +96 -0
- data/lib/functions/ref.rb +34 -0
- data/lib/functions/scale.rb +71 -0
- data/lib/functions/table.rb +16 -0
- data/lib/functions/times.rb +70 -0
- data/lib/functions/triangle.rb +69 -0
- data/lib/templates/arduino_library.ino.erb +75 -0
- metadata +84 -0
checksums.yaml
ADDED
@@ -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
|
data/bin/arbol
ADDED
@@ -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
|
+
)
|
data/lib/arbol.rb
ADDED
@@ -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
|
data/lib/base.rb
ADDED
@@ -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
|