Top Level Namespace
Defined Under Namespace
Modules: Arbol, RefineBasics
Classes: Add, AddConstrain, AddModulo, AnalogPin, ArbolHash, ArbolTable, Base, Choose, Const, CreateLookup, CreateRef, Crossfade, Divide, Feedback, FeedbackOffset, Gamma, GreaterThan, GreaterThanEquals, LFOSquare, LFOTriangle, LampPhase, LessThan, LessThanEquals, Lookup, Maximum, Minimum, Minus, Modulo, Noise, NoisePixel, PhaseTriangle, Phasor, Ref, Scale, Times, TsortableHash
Instance Method Summary
collapse
-
#add(op1, op2) ⇒ Object
-
#add_constrain(op1, op2) ⇒ Object
-
#add_modulo(op1, op2) ⇒ Object
-
#analog_pin(pin:, in_lo: 0, in_hi: 1.0, out_lo: 0, out_hi: 1.0, threshold: nil, window: nil, feedback: nil) ⇒ Object
-
#builder(params) ⇒ Object
new instance of the class specified by params.
-
#choose(choice, op1, op2) ⇒ Object
-
#coerce_array(input) ⇒ Array
coerces a scalar value to an array of 3 elements.
-
#create_ref(identifier, value) ⇒ Object
-
#create_table_ref(identifier, value) ⇒ Object
-
#crossfade(fader, channel1, channel2) ⇒ Object
-
#custom_arduino_script_body(structure) ⇒ Object
-
#divide(numerator, denominator) ⇒ Object
-
#feedback(input, feedback) ⇒ Object
-
#feedback_offset(input, feedback, offset) ⇒ Object
-
#gamma(input) ⇒ Object
-
#greater_than(left, right) ⇒ Object
-
#greater_than_equals(left, right) ⇒ Object
-
#ino_from_tree(tree) ⇒ Object
creates an ino file from a tree structure.
-
#interpret_dsl(script_text, scope) ⇒ Object
converts dsl text to an arbol tree structure.
-
#interpret_file(file_path, scope) ⇒ Object
interprets a file into an arbol tree structure.
-
#interpret_json(json_text) ⇒ Hash
converts a json string to an arbol tree structure.
-
#lamp_phase ⇒ Object
-
#less_than(left, right) ⇒ Object
-
#less_than_equals(left, right) ⇒ Object
-
#lfo_square(cycle_ms) ⇒ Object
-
#lfo_triangle(cycle_ms) ⇒ Object
-
#lookup(table, index) ⇒ Object
-
#max(op1, op2) ⇒ Object
-
#min(op1, op2) ⇒ Object
-
#minus(op1, op2) ⇒ Object
-
#mod(op1, op2) ⇒ Object
-
#my_const(value) ⇒ Object
given a slightly different name to avoid.
-
#noise ⇒ Object
-
#noise_pixel ⇒ Object
-
#phasor(cycles) ⇒ Object
-
#ref(identifier) ⇒ Object
-
#remove_comments(script) ⇒ String
removes comments from the dsl script.
-
#resolve(val) ⇒ Object
resolves an input object to a structure appropriate for the tree.
-
#resolve_float(val) ⇒ Object
-
#resolve_integer(val) ⇒ Object
-
#resolve_lookup(val) ⇒ Object
-
#resolve_lookup_table(val) ⇒ Object
-
#resolve_pin_reference(val) ⇒ Object
-
#resolve_positive_scalar(val) ⇒ Object
-
#resolve_table_reference(table_ref) ⇒ Object
-
#scale(input, lo_in, hi_in, lo_out, hi_out) ⇒ Object
-
#scale_correctly(val) ⇒ Integer
scales float values to the integer scale representation.
-
#script_split(script) ⇒ Array<String>
separates declarations by ; delimiter.
-
#script_to_file(script, path) ⇒ Object
write the script to file.
-
#stmts_to_structure(stmts, scope) ⇒ Object
converts an array of statements to an arbol tree structure.
-
#strip(lamps, pin, calc) ⇒ Hash
top level object to create a neopixel strip.
-
#table(contents) ⇒ Object
really this is just a pass through for arrays used in lookup table creation.
-
#times(op1, op2) ⇒ Object
-
#triangle(phase) ⇒ Object
Instance Method Details
#add(op1, op2) ⇒ Object
64
65
66
67
68
69
70
|
# File 'lib/functions/add.rb', line 64
def add(op1, op2)
h = ArbolHash.new
h[:type] = 'add'
h[:op1] = resolve(op1)
h[:op2] = resolve(op2)
h
end
|
#add_constrain(op1, op2) ⇒ Object
64
65
66
67
68
69
70
|
# File 'lib/functions/add_constrain.rb', line 64
def add_constrain(op1, op2)
h = ArbolHash.new
h[:type] = 'add_constrain'
h[:op1] = resolve(op1)
h[:op2] = resolve(op2)
h
end
|
#add_modulo(op1, op2) ⇒ Object
64
65
66
67
68
69
70
|
# File 'lib/functions/add_modulo.rb', line 64
def add_modulo(op1, op2)
h = ArbolHash.new
h[:type] = 'add_modulo'
h[:op1] = resolve(op1)
h[:op2] = resolve(op2)
h
end
|
#analog_pin(pin:, in_lo: 0, in_hi: 1.0, out_lo: 0, out_hi: 1.0, threshold: nil, window: nil, feedback: nil) ⇒ Object
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
|
# File 'lib/functions/analog_pin.rb', line 240
def analog_pin(
pin:,
in_lo: 0,
in_hi: 1.0,
out_lo: 0,
out_hi: 1.0,
threshold: nil,
window: nil,
feedback: nil
)
h = ArbolHash.new
h[:type] = 'analog_pin'
h[:pin] = resolve_pin_reference(pin)
h[:scale] = 0
h[:scale] = 1 if in_lo != 0
h[:scale] = 1 if in_hi != 1.0
h[:scale] = 1 if out_lo != 0
h[:scale] = 1 if out_hi != 1.0
h[:in_lo] = resolve_positive_scalar(in_lo)
h[:in_hi] = resolve_positive_scalar(in_hi)
h[:out_lo] = resolve_positive_scalar(out_lo)
h[:out_hi] = resolve_positive_scalar(out_hi)
if threshold
h[:threshold] = resolve_positive_scalar(threshold)
else
h[:threshold] = -1
end
if window
h[:window] = resolve_float(window)
else
h[:window] = 0.0
end
if feedback
h[:feedback] = resolve_positive_scalar(feedback)
else
h[:feedback] = 0
end
puts(h)
h
end
|
#builder(params) ⇒ Object
new instance of the class specified by params
28
29
30
31
|
# File 'lib/builder.rb', line 28
def builder(params)
Arbol.class_map[params[:type]].new(params)
end
|
#choose(choice, op1, op2) ⇒ Object
67
68
69
70
71
72
73
74
|
# File 'lib/functions/choose.rb', line 67
def choose(choice, op1, op2)
h = ArbolHash.new
h[:type] = 'choose'
h[:choice] = resolve(choice)
h[:op1] = resolve(op1)
h[:op2] = resolve(op2)
h
end
|
#coerce_array(input) ⇒ Array
coerces a scalar value to an array of 3 elements.
68
69
70
71
72
73
74
|
# File 'lib/dsl.rb', line 68
def coerce_array(input)
if input.class == Array
input
else
[input, input, input]
end
end
|
#create_ref(identifier, value) ⇒ Object
36
37
38
39
40
41
42
43
44
45
46
47
48
|
# File 'lib/functions/create_ref.rb', line 36
def create_ref(identifier, value)
h = ArbolHash.new
if value.class == ArbolTable
h[:type] = 'create_lookup'
h[:identifier] = identifier
h[:value] = resolve_lookup(value.table)
else
h[:type] = 'create_ref'
h[:identifier] = identifier
h[:value] = resolve(value)
end
h
end
|
#create_table_ref(identifier, value) ⇒ Object
57
58
59
60
61
62
63
|
# File 'lib/functions/create_lookup.rb', line 57
def create_table_ref(identifier, value)
h = ArbolHash.new
h[:type] = 'create_lookup'
h[:identifier] = identifier
h[:value] = resolve_lookup(value)
h
end
|
#crossfade(fader, channel1, channel2) ⇒ Object
66
67
68
69
70
71
72
73
|
# File 'lib/functions/crossfade.rb', line 66
def crossfade(fader, channel1, channel2)
h = ArbolHash.new
h[:type] = 'crossfade'
h[:fader] = resolve(fader)
h[:channel1] = resolve(channel1)
h[:channel2] = resolve(channel2)
h
end
|
#custom_arduino_script_body(structure) ⇒ Object
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
# File 'lib/builder.rb', line 33
def custom_arduino_script_body(structure)
ref_builders = []
structure[:refs].each do |ref|
this_ref = builder(
ref
)
this_ref.resolve_frame_optimized
ref_builders << this_ref
end
t = builder(
structure[:calc]
)
t.resolve_frame_optimized
ts = TsortableHash.new
ref_builders.each { |r| r.append_tsortable(ts) }
t.append_tsortable(ts)
pixel_scope_code = {}
top_level_scope_code = {}
cycle_scope_code = {}
ref_builders.each { |r| r.add_arduino_code(pixel_scope_code) }
ref_builders.each { |r| r.add_cycle_level_scope(cycle_scope_code) }
ref_builders.each { |r| r.add_top_level_scope(top_level_scope_code) }
t.add_arduino_code(pixel_scope_code)
t.add_cycle_level_scope(cycle_scope_code)
t.add_top_level_scope(top_level_scope_code)
pixel_scope = []
top_level_scope = []
cycle_scope = []
t = ts.tsort
t.each do |func|
pixel_scope_code[func].each do |stmt|
pixel_scope << stmt
end
cycle_scope_code[func].each do |stmt|
cycle_scope << stmt
end
top_level_scope_code[func].each do |stmt|
top_level_scope << stmt
end
end
pixel_scope << ''
pixel_scope << "// output"
pixel_scope << "strip.setPixelColor(i, (byte)long_mult(255, #{t.last}[0]), (byte)long_mult(255, #{t.last}[1]), (byte)long_mult(255, #{t.last}[2]));"
return top_level_scope, cycle_scope, pixel_scope
end
|
#divide(numerator, denominator) ⇒ Object
64
65
66
67
68
69
70
|
# File 'lib/functions/divide.rb', line 64
def divide(numerator, denominator)
h = ArbolHash.new
h[:type] = 'add'
h[:numerator] = resolve(numerator)
h[:denominator] = resolve(denominator)
h
end
|
#feedback(input, feedback) ⇒ Object
59
60
61
62
63
64
65
|
# File 'lib/functions/feedback.rb', line 59
def feedback(input, feedback)
h = ArbolHash.new
h[:type] = 'feedback'
h[:input] = resolve(input)
h[:feedback] = resolve(feedback)
h
end
|
#feedback_offset(input, feedback, offset) ⇒ Object
62
63
64
65
66
67
68
69
|
# File 'lib/functions/feedback_offset.rb', line 62
def feedback_offset(input, feedback, offset)
h = ArbolHash.new
h[:type] = 'feedback_offset'
h[:input] = resolve(input)
h[:feedback] = resolve(feedback)
h[:offset] = resolve(offset)
h
end
|
#gamma(input) ⇒ Object
56
57
58
59
60
61
|
# File 'lib/functions/gamma.rb', line 56
def gamma(input)
h = ArbolHash.new
h[:type] = 'gamma'
h[:input] = resolve(input)
h
end
|
#greater_than(left, right) ⇒ Object
64
65
66
67
68
69
70
|
# File 'lib/functions/greater_than.rb', line 64
def greater_than(left, right)
h = ArbolHash.new
h[:type] = 'greater_than'
h[:left] = resolve(left)
h[:right] = resolve(right)
h
end
|
#greater_than_equals(left, right) ⇒ Object
64
65
66
67
68
69
70
|
# File 'lib/functions/greater_than_equals.rb', line 64
def greater_than_equals(left, right)
h = ArbolHash.new
h[:type] = 'greater_than_equals'
h[:left] = resolve(left)
h[:right] = resolve(right)
h
end
|
#ino_from_tree(tree) ⇒ Object
creates an ino file from a tree structure.
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
# File 'lib/arbol.rb', line 21
def ino_from_tree(tree)
pp tree
tls, cycle, body = custom_arduino_script_body(tree)
tls = tls.join("\n")
cycle = cycle.join("\n")
body = body.join("\n")
integer_scale = 8192
pixels = tree[:lamps]
pin = tree[:pin]
code = Arbol.libs.join("\n\n")
ERB.new(
IO.read(
"#{File.dirname(__FILE__)}/templates/arduino_library.ino.erb"
)
).result(binding)
end
|
#interpret_dsl(script_text, scope) ⇒ Object
converts dsl text to an arbol tree structure
149
150
151
152
153
154
155
156
157
158
|
# File 'lib/dsl.rb', line 149
def interpret_dsl(script_text, scope)
stmts_to_structure(
script_split(
(
script_text
)
),
scope
)
end
|
#interpret_file(file_path, scope) ⇒ Object
interprets a file into an arbol tree structure
12
13
14
15
16
17
18
|
# File 'lib/arbol.rb', line 12
def interpret_file(file_path, scope)
if file_path.match(/\.rb$/)
return interpret_dsl(File.read(file_path), scope)
elsif file_path.match(/\.json$/)
return interpret_json(File.read(file_path))
end
end
|
#interpret_json(json_text) ⇒ Hash
converts a json string to an arbol tree structure
163
164
165
166
167
168
|
# File 'lib/dsl.rb', line 163
def interpret_json(json_text)
JSON.parse(
json_text,
symbolize_names: true
)
end
|
#lamp_phase ⇒ Object
35
36
37
38
39
|
# File 'lib/functions/lamp_phase.rb', line 35
def lamp_phase
h = ArbolHash.new
h[:type] = 'lamp_phase'
h
end
|
#less_than(left, right) ⇒ Object
64
65
66
67
68
69
70
|
# File 'lib/functions/less_than.rb', line 64
def less_than(left, right)
h = ArbolHash.new
h[:type] = 'less_than'
h[:left] = resolve(left)
h[:right] = resolve(right)
h
end
|
#less_than_equals(left, right) ⇒ Object
64
65
66
67
68
69
70
|
# File 'lib/functions/less_than_equals.rb', line 64
def less_than_equals(left, right)
h = ArbolHash.new
h[:type] = 'less_than_equals'
h[:left] = resolve(left)
h[:right] = resolve(right)
h
end
|
#lfo_square(cycle_ms) ⇒ Object
63
64
65
66
67
68
|
# File 'lib/functions/lfo_square.rb', line 63
def lfo_square(cycle_ms)
h = ArbolHash.new
h[:type] = 'lfo_square'
h[:cycle_ms] = resolve(cycle_ms)
h
end
|
#lfo_triangle(cycle_ms) ⇒ Object
67
68
69
70
71
72
|
# File 'lib/functions/lfo_triangle.rb', line 67
def lfo_triangle(cycle_ms)
h = ArbolHash.new
h[:type] = 'lfo_triangle'
h[:cycle_ms] = resolve(cycle_ms)
h
end
|
#lookup(table, index) ⇒ Object
#max(op1, op2) ⇒ Object
64
65
66
67
68
69
70
|
# File 'lib/functions/max.rb', line 64
def max(op1, op2)
h = ArbolHash.new
h[:type] = 'max'
h[:op1] = resolve(op1)
h[:op2] = resolve(op2)
h
end
|
#min(op1, op2) ⇒ Object
64
65
66
67
68
69
70
|
# File 'lib/functions/min.rb', line 64
def min(op1, op2)
h = ArbolHash.new
h[:type] = 'min'
h[:op1] = resolve(op1)
h[:op2] = resolve(op2)
h
end
|
#minus(op1, op2) ⇒ Object
64
65
66
67
68
69
70
|
# File 'lib/functions/minus.rb', line 64
def minus(op1, op2)
h = ArbolHash.new
h[:type] = 'minus'
h[:op1] = resolve(op1)
h[:op2] = resolve(op2)
h
end
|
#mod(op1, op2) ⇒ Object
64
65
66
67
68
69
70
|
# File 'lib/functions/modulo.rb', line 64
def mod(op1, op2)
h = ArbolHash.new
h[:type] = 'modulo'
h[:op1] = resolve(op1)
h[:op2] = resolve(op2)
h
end
|
#my_const(value) ⇒ Object
given a slightly different name to avoid
58
59
60
61
62
63
|
# File 'lib/functions/const.rb', line 58
def my_const(value)
{
type: "const",
value: coerce_array(value)
}
end
|
#noise ⇒ Object
45
46
47
48
49
|
# File 'lib/functions/noise.rb', line 45
def noise
h = ArbolHash.new
h[:type] = 'noise'
h
end
|
#noise_pixel ⇒ Object
45
46
47
48
49
|
# File 'lib/functions/noise_pixel.rb', line 45
def noise_pixel
h = ArbolHash.new
h[:type] = 'noise_pixel'
h
end
|
#phasor(cycles) ⇒ Object
91
92
93
94
95
96
|
# File 'lib/functions/phasor.rb', line 91
def phasor(cycles)
h = ArbolHash.new
h[:type] = 'phasor'
h[:cycles] = resolve(cycles)
h
end
|
#ref(identifier) ⇒ Object
29
30
31
32
33
34
|
# File 'lib/functions/ref.rb', line 29
def ref(identifier)
h = ArbolHash.new
h[:type] = 'ref'
h[:identifier] = identifier
h
end
|
removes comments from the dsl script
93
94
95
96
97
98
99
100
101
102
103
|
# File 'lib/dsl.rb', line 93
def (script)
t = []
script.split("\n").each do |line|
if line.match(/\#/)
t << line.split('#',2)[0]
else
t << line
end
end
t.join("\n")
end
|
#resolve(val) ⇒ Object
resolves an input object to a structure appropriate for the tree.
#resolve_float(val) ⇒ Object
37
38
39
40
41
42
43
|
# File 'lib/dsl.rb', line 37
def resolve_float(val)
if val.class == Float
val
else
raise "#{val} is not an float"
end
end
|
#resolve_integer(val) ⇒ Object
29
30
31
32
33
34
35
|
# File 'lib/dsl.rb', line 29
def resolve_integer(val)
if val.class == Integer
val
else
raise "#{val} is not an integer"
end
end
|
#resolve_lookup(val) ⇒ Object
44
45
46
47
48
49
50
51
52
53
54
55
|
# File 'lib/functions/create_lookup.rb', line 44
def resolve_lookup(val)
puts val
puts val.class
raise "table definition must be an array" unless val.class == Array
val.map do |v|
case
when [Integer, Float].include?(v.class)
then 3.times.map { scale_correctly(v) }
when v.class == Array then v.map { |i| scale_correctly(i) }
end
end
end
|
#resolve_lookup_table(val) ⇒ Object
25
26
27
|
# File 'lib/dsl.rb', line 25
def resolve_lookup_table(val)
val.map { |v| resolve(val) }
end
|
#resolve_pin_reference(val) ⇒ Object
57
58
59
60
61
62
63
|
# File 'lib/dsl.rb', line 57
def resolve_pin_reference(val)
if val.match(/(^A\d+$|^\d+$)/)
val
else
raise "#{val} is not a valid pin reference"
end
end
|
#resolve_positive_scalar(val) ⇒ Object
45
46
47
48
49
50
51
52
53
54
55
|
# File 'lib/dsl.rb', line 45
def resolve_positive_scalar(val)
if [Integer, Float].include?(val.class)
if val >= 0
scale_correctly(val)
else
raise "#{} val should be positive"
end
else
raise "#{val} must be a positive scalar number"
end
end
|
#resolve_table_reference(table_ref) ⇒ Object
72
73
74
75
76
77
78
|
# File 'lib/functions/lookup.rb', line 72
def resolve_table_reference(table_ref)
if $tables.has_key?(table_ref)
table_ref
else
raise "table #{table_ref} invalid"
end
end
|
#scale(input, lo_in, hi_in, lo_out, hi_out) ⇒ Object
62
63
64
65
66
67
68
69
70
71
|
# File 'lib/functions/scale.rb', line 62
def scale(input, lo_in, hi_in, lo_out, hi_out)
h = ArbolHash.new
h[:type] = 'scale'
h[:input] = resolve(input)
h[:lo_in] = resolve(lo_in)
h[:hi_in] = resolve(hi_in)
h[:lo_out] = resolve(lo_out)
h[:hi_out] = resolve(hi_out)
h
end
|
#scale_correctly(val) ⇒ Integer
scales float values to the integer scale representation.
4
5
6
7
8
9
|
# File 'lib/dsl.rb', line 4
def scale_correctly(val)
case
when val.class == Integer then return val
when val.class == Float then return (val * 8192).to_i
end
end
|
#script_split(script) ⇒ Array<String>
separates declarations by ; delimiter
108
109
110
|
# File 'lib/dsl.rb', line 108
def script_split(script)
script.split(';').select { |l| l.strip != '' }
end
|
#script_to_file(script, path) ⇒ Object
40
41
42
43
44
45
|
# File 'lib/arbol.rb', line 40
def script_to_file(script, path)
puts "writing to script file #{path}"
File.open(path, 'w') do |f|
f.puts(script)
end
end
|
#stmts_to_structure(stmts, scope) ⇒ Object
converts an array of statements to an arbol tree structure
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
# File 'lib/dsl.rb', line 116
def stmts_to_structure(stmts, scope)
refs = []
refinjects = ['using RefineBasics; ']
stmts.each do |stmt|
if stmt.match(/(\w|\s)+={1}(\w|\s)+/)
ref_name = stmt.match(/\w+/)[0]
statements = "#{refinjects.join('')}#{stmt.split('=', 2)[1]}"
this_ref = create_ref(
ref_name,
eval(statements, scope)
)
refinject = "#{ref_name} = ref('#{ref_name}');"
refs << this_ref
refinjects << refinject
elsif stmt.match('strip')
statements = "#{refinjects.join('')} #{stmt}"
retval = eval(statements, scope)
retval[:refs] = refs
return retval
end
end
end
|
#strip(lamps, pin, calc) ⇒ Hash
top level object to create a neopixel strip
81
82
83
84
85
86
87
88
|
# File 'lib/dsl.rb', line 81
def strip(lamps, pin, calc)
{
type: 'physical_strip',
lamps: lamps,
pin: pin,
calc: resolve(calc)
}
end
|
#table(contents) ⇒ Object
really this is just a pass through for arrays used in lookup table creation
12
13
14
15
16
|
# File 'lib/functions/table.rb', line 12
def table(contents)
if contents.class == Array
ArbolTable.new(contents)
end
end
|
#times(op1, op2) ⇒ Object
64
65
66
67
68
69
70
|
# File 'lib/functions/times.rb', line 64
def times(op1, op2)
h = ArbolHash.new
h[:type] = 'times'
h[:op1] = resolve(op1)
h[:op2] = resolve(op2)
h
end
|
#triangle(phase) ⇒ Object
64
65
66
67
68
69
|
# File 'lib/functions/triangle.rb', line 64
def triangle(phase)
h = ArbolHash.new
h[:type] = 'triangle'
h[:phase] = resolve(phase)
h
end
|