neo_rad 0.4.0

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 (146) hide show
  1. checksums.yaml +7 -0
  2. data/History.txt +112 -0
  3. data/License.txt +282 -0
  4. data/Manifest.txt +144 -0
  5. data/README.rdoc +1 -0
  6. data/Rakefile +142 -0
  7. data/bin/rad +302 -0
  8. data/lib/examples/add_hysteresis.rb +13 -0
  9. data/lib/examples/basic_blink.rb +10 -0
  10. data/lib/examples/blink_m_address_assignment.rb +104 -0
  11. data/lib/examples/blink_m_hello.rb +14 -0
  12. data/lib/examples/blink_m_multi.rb +61 -0
  13. data/lib/examples/blink_with_serial.rb +16 -0
  14. data/lib/examples/configure_pa_lcd_boot.rb +91 -0
  15. data/lib/examples/debounce_methods.rb +49 -0
  16. data/lib/examples/external_variable_fu.rb +26 -0
  17. data/lib/examples/external_variables.rb +32 -0
  18. data/lib/examples/first_sound.rb +23 -0
  19. data/lib/examples/frequency_generator.rb +30 -0
  20. data/lib/examples/hello_array.rb +48 -0
  21. data/lib/examples/hello_array2.rb +112 -0
  22. data/lib/examples/hello_array_eeprom.rb +59 -0
  23. data/lib/examples/hello_clock.rb +84 -0
  24. data/lib/examples/hello_eeprom.rb +51 -0
  25. data/lib/examples/hello_eeprom_lcdpa.rb +81 -0
  26. data/lib/examples/hello_format_print.rb +94 -0
  27. data/lib/examples/hello_lcd_charset.rb +75 -0
  28. data/lib/examples/hello_pa_lcd.rb +59 -0
  29. data/lib/examples/hello_servos.rb +88 -0
  30. data/lib/examples/hello_spectra_sound.rb +38 -0
  31. data/lib/examples/hello_world.rb +11 -0
  32. data/lib/examples/hello_xbee.rb +12 -0
  33. data/lib/examples/hysteresis_duel.rb +39 -0
  34. data/lib/examples/i2c_with_clock_chip.rb +124 -0
  35. data/lib/examples/midi_beat_box.rb +86 -0
  36. data/lib/examples/midi_scales.rb +94 -0
  37. data/lib/examples/motor_knob.rb +30 -0
  38. data/lib/examples/servo_buttons.rb +23 -0
  39. data/lib/examples/servo_calibrate_continuous.rb +92 -0
  40. data/lib/examples/servo_throttle.rb +40 -0
  41. data/lib/examples/software_serial.rb +10 -0
  42. data/lib/examples/sparkfun_lcd.rb +48 -0
  43. data/lib/examples/spectra_soft_pot.rb +34 -0
  44. data/lib/examples/times_method.rb +8 -0
  45. data/lib/examples/toggle.rb +10 -0
  46. data/lib/examples/twitter.rb +57 -0
  47. data/lib/examples/two_wire.rb +14 -0
  48. data/lib/libraries/AFSoftSerial/AFSoftSerial.cpp +321 -0
  49. data/lib/libraries/AFSoftSerial/AFSoftSerial.h +61 -0
  50. data/lib/libraries/AFSoftSerial/keywords.txt +18 -0
  51. data/lib/libraries/AF_XPort/AF_XPort.cpp +166 -0
  52. data/lib/libraries/AF_XPort/AF_XPort.h +48 -0
  53. data/lib/libraries/DS1307/DS1307.cpp +162 -0
  54. data/lib/libraries/DS1307/DS1307.h +66 -0
  55. data/lib/libraries/DS1307/keywords.txt +18 -0
  56. data/lib/libraries/FrequencyTimer2/FrequencyTimer2.cpp +144 -0
  57. data/lib/libraries/FrequencyTimer2/FrequencyTimer2.h +42 -0
  58. data/lib/libraries/FrequencyTimer2/keywords.txt +22 -0
  59. data/lib/libraries/I2CEEPROM/I2CEEPROM.cpp +120 -0
  60. data/lib/libraries/I2CEEPROM/I2CEEPROM.h +70 -0
  61. data/lib/libraries/I2CEEPROM/keywords.txt +21 -0
  62. data/lib/libraries/LoopTimer/LoopTimer.cpp +35 -0
  63. data/lib/libraries/LoopTimer/LoopTimer.h +34 -0
  64. data/lib/libraries/LoopTimer/keywords.txt +27 -0
  65. data/lib/libraries/OneWire/OneWire.cpp +194 -0
  66. data/lib/libraries/OneWire/OneWire.h +63 -0
  67. data/lib/libraries/OneWire/keywords.txt +35 -0
  68. data/lib/libraries/OneWire/readme.txt +13 -0
  69. data/lib/libraries/SWSerLCDpa/SWSerLCDpa.cpp +296 -0
  70. data/lib/libraries/SWSerLCDpa/SWSerLCDpa.h +69 -0
  71. data/lib/libraries/SWSerLCDsf/SWSerLCDsf.cpp +311 -0
  72. data/lib/libraries/SWSerLCDsf/SWSerLCDsf.h +67 -0
  73. data/lib/libraries/Servo/Servo.cpp +192 -0
  74. data/lib/libraries/Servo/Servo.h +61 -0
  75. data/lib/libraries/Stepper/Stepper.cpp +220 -0
  76. data/lib/libraries/Stepper/Stepper.h +86 -0
  77. data/lib/libraries/Stepper/keywords.txt +28 -0
  78. data/lib/libraries/Wire/Wire.cpp +262 -0
  79. data/lib/libraries/Wire/Wire.h +67 -0
  80. data/lib/libraries/Wire/keywords.txt +31 -0
  81. data/lib/libraries/Wire/twi.h +57 -0
  82. data/lib/libraries/Wire/utility/twi.c +449 -0
  83. data/lib/libraries/Wire/utility/twi.h +57 -0
  84. data/lib/plugins/bitwise_ops.rb +54 -0
  85. data/lib/plugins/blink.rb +25 -0
  86. data/lib/plugins/blink_m.rb +356 -0
  87. data/lib/plugins/debounce.rb +138 -0
  88. data/lib/plugins/debug_output_to_lcd.rb +71 -0
  89. data/lib/plugins/hysteresis.rb +52 -0
  90. data/lib/plugins/input_output_state.rb +84 -0
  91. data/lib/plugins/lcd_padding.rb +58 -0
  92. data/lib/plugins/mem_test.rb +37 -0
  93. data/lib/plugins/midi.rb +60 -0
  94. data/lib/plugins/parallax_ping.rb +50 -0
  95. data/lib/plugins/servo_pulse.rb +31 -0
  96. data/lib/plugins/servo_setup.rb +86 -0
  97. data/lib/plugins/smoother.rb +54 -0
  98. data/lib/plugins/spark_fun_serial_lcd.rb +100 -0
  99. data/lib/plugins/spectra_symbol.rb +79 -0
  100. data/lib/plugins/twitter_connect.rb +145 -0
  101. data/lib/rad/README.rdoc +5 -0
  102. data/lib/rad/arduino_plugin.rb +246 -0
  103. data/lib/rad/arduino_sketch.rb +628 -0
  104. data/lib/rad/darwin_installer.rb +23 -0
  105. data/lib/rad/generators/makefile/makefile.erb +243 -0
  106. data/lib/rad/generators/makefile/makefile.rb +38 -0
  107. data/lib/rad/hardware_library.rb +813 -0
  108. data/lib/rad/init.rb +15 -0
  109. data/lib/rad/linux_installer.rb +132 -0
  110. data/lib/rad/progressbar.rb +236 -0
  111. data/lib/rad/rad_processor.rb +128 -0
  112. data/lib/rad/rad_rewriter.rb +94 -0
  113. data/lib/rad/rad_type_checker.rb +26 -0
  114. data/lib/rad/sim/arduino_sketch.rb +57 -0
  115. data/lib/rad/sketch_compiler.rb +47 -0
  116. data/lib/rad/tasks/build_and_make.rake +210 -0
  117. data/lib/rad/tasks/rad.rb +2 -0
  118. data/lib/rad/todo.txt +13 -0
  119. data/lib/rad/variable_processing.rb +153 -0
  120. data/lib/rad/version.rb +9 -0
  121. data/lib/rad.rb +5 -0
  122. data/scripts/txt2html +67 -0
  123. data/setup.rb +1585 -0
  124. data/spec/examples/hello_world.rb +11 -0
  125. data/spec/examples/serial_motor.rb +12 -0
  126. data/spec/models/arduino_sketch_spec.rb +82 -0
  127. data/spec/models/sketch_compiler_spec.rb +96 -0
  128. data/spec/models/spec_helper.rb +2 -0
  129. data/spec/sim/hello_world_spec.rb +42 -0
  130. data/spec/spec.opts +1 -0
  131. data/test/hello_world_test/Makefile +436 -0
  132. data/test/hello_world_test/hello_world.cpp +23 -0
  133. data/test/test_array_processing.rb +179 -0
  134. data/test/test_plugin_loading.rb +151 -0
  135. data/test/test_translation_post_processing.rb +185 -0
  136. data/test/test_variable_processing.rb +238 -0
  137. data/website/examples/assembler_test.rb.html +73 -0
  138. data/website/examples/gps_reader.rb.html +39 -0
  139. data/website/examples/hello_world.rb.html +38 -0
  140. data/website/examples/serial_motor.rb.html +41 -0
  141. data/website/index.html +178 -0
  142. data/website/index.txt +64 -0
  143. data/website/javascripts/rounded_corners_lite.inc.js +285 -0
  144. data/website/stylesheets/screen.css +169 -0
  145. data/website/template.rhtml +48 -0
  146. metadata +222 -0
data/lib/rad/init.rb ADDED
@@ -0,0 +1,15 @@
1
+ RAD_ROOT = "#{File.dirname(__FILE__)}/../.." unless defined?(RAD_ROOT)
2
+
3
+ unless defined?(PROJECT_DIR_NAME)
4
+ a = File.expand_path(File.expand_path("#{RAD_ROOT}")).split("/")
5
+ PROJECT_DIR_NAME = a[a.length-1]
6
+ end
7
+
8
+ PLUGIN_C_VAR_TYPES = "int|void|unsigned|long|short|uint8_t|static|byte|char\\*|uint8_t"
9
+
10
+ gem "ParseTree", "=2.2"
11
+
12
+ %w(generators/makefile/makefile.rb rad_processor.rb rad_rewriter.rb rad_type_checker.rb variable_processing.rb arduino_sketch.rb arduino_plugin.rb hardware_library.rb tasks/rad.rb sketch_compiler.rb).each do |path|
13
+ require File.expand_path("#{RAD_ROOT}/vendor/rad/#{path}")
14
+ end
15
+
@@ -0,0 +1,132 @@
1
+ class LinuxInstaller
2
+
3
+ # this is the thing we actually run to make something happen
4
+ def self.install!
5
+ puts "Welcome to the RAD Linux Installer!"
6
+ puts "-----------------------------------"
7
+ puts "Let's begin."
8
+ puts
9
+
10
+ check_or_warn_for_usb_driver
11
+
12
+ # of course we need rubygems
13
+ # maybe just rely on the user installing rubygems, because the ubuntu one sux
14
+ #check_or_install_package("rubygems")
15
+ #%x{gem update --system}
16
+
17
+ # we need java to make this ship float
18
+ check_or_nag_package("sun-java5-jre")
19
+
20
+ # remove a package that interferes with the arduino usb/serial driver
21
+ check_or_remove_package("brltty")
22
+
23
+ # install pre-requisites
24
+ check_or_install_package("binutils-avr")
25
+ check_or_install_package("gcc-avr")
26
+ check_or_install_package("avr-libc")
27
+ check_or_install_package("unzip")
28
+ check_or_install_package("wget")
29
+
30
+ # remove a probably out of date avrdude
31
+ check_or_remove_package("avrdude")
32
+
33
+ # install pre-requisites for avrdude if we wanted to build from source
34
+ # nah, it comes with the arduino binary
35
+ #check_or_install_package("gcc")
36
+ #check_or_install_package("bison")
37
+ #check_or_install_package("flex")
38
+ check_or_install_arduino
39
+ end
40
+
41
+ def self.check_or_install_package(package_name)
42
+ package = %x{dpkg --get-selections | grep #{package_name}}
43
+ if package.include?("\tinstall")
44
+ puts "#{package_name} installed!"
45
+ else
46
+ puts "installing #{package_name}..."
47
+ %x{apt-get install -y #{package_name}}
48
+ end
49
+ end
50
+
51
+ def self.check_or_nag_package(package_name, custom_msg = nil)
52
+ package = %x{dpkg --get-selections | grep #{package_name}}
53
+ if package.include?("\tinstall")
54
+ puts "#{package_name} installed!"
55
+ else
56
+ puts "you will need to manually install #{package_name}! use the command below."
57
+ if custom_msg
58
+ puts custom_msg
59
+ else
60
+ puts "sudo apt-get install #{package_name}"
61
+ end
62
+ exit
63
+ end
64
+ end
65
+
66
+ def self.check_or_remove_package(package_name)
67
+ package = %x{dpkg --get-selections | grep #{package_name}}
68
+
69
+ #an easier way to check for installed packages?
70
+ if package.include?("\tinstall")
71
+ puts "removing #{package_name}..."
72
+ %x{apt-get remove -y #{package_name}}
73
+ else
74
+ puts "#{package_name} previously uninstalled!"
75
+ end
76
+ end
77
+
78
+ def self.check_or_warn_for_usb_driver
79
+
80
+ # check if usb device recognized by system
81
+ puts "Please plug in your arduino to your usb port... [hit enter to continue]"
82
+ STDIN.gets # we patiently wait
83
+
84
+ usb = %x{dmesg | tail | grep "FTDI USB Serial" | grep -c "now attached"}
85
+
86
+ if usb.to_i == 0
87
+ # maybe we can be nice here and offer to download and install the driver package
88
+ puts "the system is not recognizing your usb-serial driver, please re-install"
89
+ exit
90
+ end
91
+ end
92
+
93
+ def self.check_or_install_arduino
94
+ if File.exist?("/usr/local/arduino-0012")
95
+ puts "arduino software previously installed at /usr/local/arduino-0012 !"
96
+ else
97
+ puts "installing arduino software..."
98
+ %x{cd /usr/local/; wget http://arduino.cc/files/arduino-0012-linux.tgz}
99
+ %x{tar -C /usr/local -xzf /usr/local/arduino-0012-linux.tgz}
100
+
101
+ %x{ln -s /usr/local/arduino-0012/arduino ~/Desktop/arduino}
102
+
103
+ # gotta patch it so it can run from command line or anywhere
104
+ arduino_file = File.open("/usr/local/arduino-0012/arduino") {|f| f.read}
105
+ new_doc = arduino_file.split("\n")
106
+ new_doc[1] = "cd /usr/local/arduino-0012"
107
+ File.open("/usr/local/arduino-0012/arduino", "w") {|f| f.puts new_doc }
108
+
109
+ %x{mkdir -p /usr/local/arduino-0012/hardware/tools/avr/bin}
110
+ # there is a difference from what the makefile expects to where it is
111
+ %x{ln -s /usr/bin/avr-gcc /usr/local/arduino-0012/hardware/tools/avr/bin/avr-gcc}
112
+ %x{ln -s /usr/bin/avr-g++ /usr/local/arduino-0012/hardware/tools/avr/bin/avr-g++}
113
+ %x{ln -s /usr/bin/avr-ar /usr/local/arduino-0012/hardware/tools/avr/bin/avr-ar}
114
+ %x{ln -s /usr/bin/avr-objcopy /usr/local/arduino-0012/hardware/tools/avr/bin/avr-objcopy}
115
+ %x{ln -s /usr/local/arduino-0012/hardware/tools/avrdude /usr/local/arduino-0012/hardware/tools/avr/bin/avrdude}
116
+ %x{ln -s /usr/local/arduino-0012/hardware/tools/avrdude.conf /usr/local/arduino-0012/hardware/tools/avr/etc/avrdude.conf}
117
+
118
+
119
+ puts
120
+ puts "************************************************************************"
121
+ puts "** please add /usr/local/arduino-0012 to your path! **"
122
+ puts "** you will also need to run sudo update-alternatives --config java **"
123
+ puts "** to choose java-1.50-sun as the default java **"
124
+ puts "************************************************************************"
125
+ puts
126
+ end
127
+
128
+ end
129
+ end
130
+
131
+
132
+
@@ -0,0 +1,236 @@
1
+ #
2
+ # Ruby/ProgressBar - a text progress bar library
3
+ #
4
+ # Copyright (C) 2001-2005 Satoru Takabayashi <satoru@namazu.org>
5
+ # All rights reserved.
6
+ # This is free software with ABSOLUTELY NO WARRANTY.
7
+ #
8
+ # You can redistribute it and/or modify it under the terms
9
+ # of Ruby's license.
10
+ #
11
+
12
+ class ProgressBar
13
+ VERSION = "0.9"
14
+
15
+ def initialize (title, total, out = STDERR)
16
+ @title = title
17
+ @total = total
18
+ @out = out
19
+ @terminal_width = 80
20
+ @bar_mark = "o"
21
+ @current = 0
22
+ @previous = 0
23
+ @finished_p = false
24
+ @start_time = Time.now
25
+ @previous_time = @start_time
26
+ @title_width = 14
27
+ @format = "%-#{@title_width}s %3d%% %s %s"
28
+ @format_arguments = [:title, :percentage, :bar, :stat]
29
+ clear
30
+ show
31
+ end
32
+ attr_reader :title
33
+ attr_reader :current
34
+ attr_reader :total
35
+ attr_accessor :start_time
36
+
37
+ private
38
+ def fmt_bar
39
+ bar_width = do_percentage * @terminal_width / 100
40
+ sprintf("|%s%s|",
41
+ @bar_mark * bar_width,
42
+ " " * (@terminal_width - bar_width))
43
+ end
44
+
45
+ def fmt_percentage
46
+ do_percentage
47
+ end
48
+
49
+ def fmt_stat
50
+ if @finished_p then elapsed else eta end
51
+ end
52
+
53
+ def fmt_stat_for_file_transfer
54
+ if @finished_p then
55
+ sprintf("%s %s %s", bytes, transfer_rate, elapsed)
56
+ else
57
+ sprintf("%s %s %s", bytes, transfer_rate, eta)
58
+ end
59
+ end
60
+
61
+ def fmt_title
62
+ @title[0,(@title_width - 1)] + ":"
63
+ end
64
+
65
+ def convert_bytes (bytes)
66
+ if bytes < 1024
67
+ sprintf("%6dB", bytes)
68
+ elsif bytes < 1024 * 1000 # 1000kb
69
+ sprintf("%5.1fKB", bytes.to_f / 1024)
70
+ elsif bytes < 1024 * 1024 * 1000 # 1000mb
71
+ sprintf("%5.1fMB", bytes.to_f / 1024 / 1024)
72
+ else
73
+ sprintf("%5.1fGB", bytes.to_f / 1024 / 1024 / 1024)
74
+ end
75
+ end
76
+
77
+ def transfer_rate
78
+ bytes_per_second = @current.to_f / (Time.now - @start_time)
79
+ sprintf("%s/s", convert_bytes(bytes_per_second))
80
+ end
81
+
82
+ def bytes
83
+ convert_bytes(@current)
84
+ end
85
+
86
+ def format_time (t)
87
+ t = t.to_i
88
+ sec = t % 60
89
+ min = (t / 60) % 60
90
+ hour = t / 3600
91
+ sprintf("%02d:%02d:%02d", hour, min, sec);
92
+ end
93
+
94
+ # ETA stands for Estimated Time of Arrival.
95
+ def eta
96
+ if @current == 0
97
+ "ETA: --:--:--"
98
+ else
99
+ elapsed = Time.now - @start_time
100
+ eta = elapsed * @total / @current - elapsed;
101
+ sprintf("ETA: %s", format_time(eta))
102
+ end
103
+ end
104
+
105
+ def elapsed
106
+ elapsed = Time.now - @start_time
107
+ sprintf("Time: %s", format_time(elapsed))
108
+ end
109
+
110
+ def eol
111
+ if @finished_p then "\n" else "\r" end
112
+ end
113
+
114
+ def do_percentage
115
+ if @total.zero?
116
+ 100
117
+ else
118
+ @current * 100 / @total
119
+ end
120
+ end
121
+
122
+ def get_width
123
+ # FIXME: I don't know how portable it is.
124
+ default_width = 80
125
+ begin
126
+ tiocgwinsz = 0x5413
127
+ data = [0, 0, 0, 0].pack("SSSS")
128
+ if @out.ioctl(tiocgwinsz, data) >= 0 then
129
+ rows, cols, xpixels, ypixels = data.unpack("SSSS")
130
+ if cols >= 0 then cols else default_width end
131
+ else
132
+ default_width
133
+ end
134
+ rescue Exception
135
+ default_width
136
+ end
137
+ end
138
+
139
+ def show
140
+ arguments = @format_arguments.map {|method|
141
+ method = sprintf("fmt_%s", method)
142
+ send(method)
143
+ }
144
+ line = sprintf(@format, *arguments)
145
+
146
+ width = get_width
147
+ if line.length == width - 1
148
+ @out.print(line + eol)
149
+ @out.flush
150
+ elsif line.length >= width
151
+ @terminal_width = [@terminal_width - (line.length - width + 1), 0].max
152
+ if @terminal_width == 0 then @out.print(line + eol) else show end
153
+ else # line.length < width - 1
154
+ @terminal_width += width - line.length + 1
155
+ show
156
+ end
157
+ @previous_time = Time.now
158
+ end
159
+
160
+ def show_if_needed
161
+ if @total.zero?
162
+ cur_percentage = 100
163
+ prev_percentage = 0
164
+ else
165
+ cur_percentage = (@current * 100 / @total).to_i
166
+ prev_percentage = (@previous * 100 / @total).to_i
167
+ end
168
+
169
+ # Use "!=" instead of ">" to support negative changes
170
+ if cur_percentage != prev_percentage ||
171
+ Time.now - @previous_time >= 1 || @finished_p
172
+ show
173
+ end
174
+ end
175
+
176
+ public
177
+ def clear
178
+ @out.print "\r"
179
+ @out.print(" " * (get_width - 1))
180
+ @out.print "\r"
181
+ end
182
+
183
+ def finish
184
+ @current = @total
185
+ @finished_p = true
186
+ show
187
+ end
188
+
189
+ def finished?
190
+ @finished_p
191
+ end
192
+
193
+ def file_transfer_mode
194
+ @format_arguments = [:title, :percentage, :bar, :stat_for_file_transfer]
195
+ end
196
+
197
+ def format= (format)
198
+ @format = format
199
+ end
200
+
201
+ def format_arguments= (arguments)
202
+ @format_arguments = arguments
203
+ end
204
+
205
+ def halt
206
+ @finished_p = true
207
+ show
208
+ end
209
+
210
+ def inc (step = 1)
211
+ @current += step
212
+ @current = @total if @current > @total
213
+ show_if_needed
214
+ @previous = @current
215
+ end
216
+
217
+ def set (count)
218
+ if count < 0 || count > @total
219
+ raise "invalid count: #{count} (total: #{@total})"
220
+ end
221
+ @current = count
222
+ show_if_needed
223
+ @previous = @current
224
+ end
225
+
226
+ def inspect
227
+ "#<ProgressBar:#{@current}/#{@total}>"
228
+ end
229
+ end
230
+
231
+ class ReversedProgressBar < ProgressBar
232
+ def do_percentage
233
+ 100 - super
234
+ end
235
+ end
236
+
@@ -0,0 +1,128 @@
1
+ require 'rubygems'
2
+ require 'ruby_to_ansi_c'
3
+
4
+ class RADProcessor < RubyToAnsiC
5
+
6
+ def self.translator
7
+ unless defined? @translator then
8
+ @translator = CompositeSexpProcessor.new
9
+ @translator << RADRewriter.new
10
+ @translator << RADTypeChecker.new
11
+ @translator << R2CRewriter.new
12
+ @translator << self.new
13
+ @translator.on_error_in(:defn) do |processor, exp, err|
14
+ result = processor.expected.new
15
+ case result
16
+ when Array then
17
+ result << :error
18
+ end
19
+ msg = "// ERROR: #{err.class}: #{err}"
20
+ msg += " in #{exp.inspect}" unless exp.nil? or $TESTING
21
+ msg += " from #{caller.join(', ')}" unless $TESTING
22
+ result << msg
23
+ result
24
+ end
25
+ end
26
+ @translator
27
+ end
28
+
29
+ def process_iasgn(exp)
30
+ name = exp.shift
31
+ val = process exp.shift
32
+ "__#{name.to_s.sub(/^@/, '')} = #{val}"
33
+ end
34
+
35
+ def process_ivar(exp)
36
+ name = exp.shift
37
+ "__#{name.to_s.sub(/^@/, '')}"
38
+ end
39
+
40
+ def process_iter(exp)
41
+ # the array identifer may be in one of two locations
42
+ # when using the instance variable (ivar) style it is located at exp[0][1][1]
43
+ if exp[0][1][1]
44
+ enum = exp[0][1][1]
45
+ enum = "__#{enum.to_s.sub(/^@/, '')}" if enum.to_s =~ /^@/
46
+ # for local variables it is located at exp[0][1][2]
47
+ elsif exp[0][1][2]
48
+ enum = exp[0][1][2]
49
+ end
50
+
51
+ out = []
52
+ # Only support enums in C-land # not sure if this comment if valid anymore
53
+ raise UnsupportedNodeError if exp[0][1].nil? # HACK ugly
54
+ @env.scope do
55
+
56
+ call = process exp.shift
57
+ var = process(exp.shift).intern # semi-HACK-y
58
+ body = process exp.shift
59
+
60
+ # array types from varible_processing>post_process_arrays and arduino_sketch>array
61
+ $array_types.each do |k,v|
62
+ @array_type = v if k == enum.to_s.sub(/^__/,"")
63
+ end
64
+
65
+ index_helper = $array_index_helpers.shift
66
+ index = "index_#{index_helper}" # solves redeclaration issue
67
+
68
+ body += ";" unless body =~ /[;}]\Z/
69
+ body.gsub!(/\n\n+/, "\n")
70
+
71
+ out << "unsigned int #{index};" # shouldn't need more than int
72
+ out << "for (#{index} = 0; #{index} < (int) (sizeof(#{enum}) / sizeof(#{enum}[0])); #{index}++) {"
73
+ out << "#{@array_type} #{var} = #{enum}[#{index}];"
74
+ out << body
75
+ out << "}"
76
+ end
77
+
78
+ return out.join("\n")
79
+ end
80
+
81
+ def process_lasgn(exp)
82
+ out = ""
83
+
84
+ var = exp.shift
85
+ value = exp.shift
86
+ # grab the size of the args, if any, before process converts to a string
87
+ arg_count = 0
88
+ arg_count = value.length - 1 if value.first == :array
89
+ args = value
90
+
91
+ exp_type = exp.sexp_type
92
+ @env.add var.to_sym, exp_type
93
+ var_type = self.class.c_type exp_type
94
+
95
+ if exp_type.list? then
96
+ assert_type args, :array
97
+
98
+ raise "array must be of one type" unless args.sexp_type == Type.homo
99
+
100
+ # HACK: until we figure out properly what to do w/ zarray
101
+ # before we know what its type is, we will default to long.
102
+ array_type = args.sexp_types.empty? ? 'void *' : self.class.c_type(args.sexp_types.first)
103
+ # we can fix array here..
104
+ args.shift # :arglist
105
+ out << "#{var} = (#{array_type}) malloc(sizeof(#{array_type}) * #{args.length});\n"
106
+ args.each_with_index do |o,i|
107
+ out << "#{var}[#{i}] = #{process o};\n"
108
+ end
109
+ else
110
+ out << "#{var} = #{process args}"
111
+ end
112
+
113
+ out.sub!(/;\n\Z/, '')
114
+
115
+ return out
116
+ end
117
+
118
+ def process_str(exp)
119
+ s = exp.shift.gsub(/\n/, '\\n')
120
+ if s.size == 1
121
+ return "\'#{s}\'"
122
+ else
123
+ return "\"#{s}\""
124
+ end
125
+ end
126
+
127
+
128
+ end
@@ -0,0 +1,94 @@
1
+ require 'ruby_to_ansi_c'
2
+
3
+ class RADRewriter < Rewriter
4
+
5
+ def process_iter(exp)
6
+ call = process exp.shift
7
+ var = process exp.shift
8
+ body = process exp.shift
9
+
10
+ var = s(:dasgn_curr, Unique.next) if var.nil?
11
+
12
+ assert_type call, :call
13
+
14
+ if call[2] != :each then # TODO: fix call[n] (api)
15
+ call.shift # :call
16
+ lhs = call.shift
17
+ method_name = call.shift
18
+
19
+ case method_name
20
+ when :downto then
21
+ var.shift #
22
+ start_value = lhs
23
+ finish_value = call.pop.pop # not sure about this
24
+ var_name = var.shift
25
+ body.find_and_replace_all(:dvar, :lvar)
26
+ result = s(:dummy,
27
+ s(:lasgn, var_name, start_value),
28
+ s(:while,
29
+ s(:call, s(:lvar, var_name), :>=,
30
+ s(:arglist, finish_value)),
31
+ s(:block,
32
+ body,
33
+ s(:lasgn, var_name,
34
+ s(:call, s(:lvar, var_name), :-,
35
+ s(:arglist, s(:lit, 1))))), true))
36
+ when :upto then
37
+ # REFACTOR: completely duped from above and direction changed
38
+ var.shift #
39
+ start_value = lhs
40
+ finish_value = call.pop.pop # not sure about this
41
+ var_name = var.shift
42
+ body.find_and_replace_all(:dvar, :lvar)
43
+ result = s(:dummy,
44
+ s(:lasgn, var_name, start_value),
45
+ s(:while,
46
+ s(:call, s(:lvar, var_name), :<=,
47
+ s(:arglist, finish_value)),
48
+ s(:block,
49
+ body,
50
+ s(:lasgn, var_name,
51
+ s(:call, s(:lvar, var_name), :+,
52
+ s(:arglist, s(:lit, 1))))), true))
53
+ when :times then
54
+ # REFACTOR: mostly duped from above and gave default start value of 0
55
+ # and a finish value that was the start value above
56
+ var.shift
57
+ start_value = s(:lit, 0)
58
+ finish_value = lhs
59
+ var_name = var.shift
60
+ body.find_and_replace_all(:dvar, :lvar)
61
+ result = s(:dummy,
62
+ s(:lasgn, var_name, start_value),
63
+ s(:while,
64
+ s(:call, s(:lvar, var_name), :<,
65
+ s(:arglist, finish_value)),
66
+ s(:block,
67
+ body,
68
+ s(:lasgn, var_name,
69
+ s(:call, s(:lvar, var_name), :+,
70
+ s(:arglist, s(:lit, 1))))), true))
71
+ when :define_method then
72
+ # BEFORE: [:iter, [:call, nil, :define_method, [:array, [:lit, :bmethod_added]]], [:dasgn_curr, :x], [:call, [:dvar, :x], :+, [:array, [:lit, 1]]]]
73
+ # we want to get it rewritten for the scope/block context, so:
74
+ # - throw call away
75
+ # - rewrite to args
76
+ # - plop body into a scope
77
+ # AFTER: [:block, [:args, :x], [:call, [:lvar, :x], :+, [:arglist, [:lit, 1]]]]
78
+ var.find_and_replace_all(:dasgn_curr, :args)
79
+ body.find_and_replace_all(:dvar, :lvar)
80
+ result = s(:block, var, body)
81
+ else
82
+ # HACK we butchered call up top
83
+ result = s(:iter, s(:call, lhs, method_name, call.shift), var, body)
84
+ end
85
+ else
86
+ if var.nil? then
87
+ var = s(:lvar, Unique.next)
88
+ end
89
+
90
+ s(:iter, call, var, body)
91
+ end
92
+ end
93
+
94
+ end
@@ -0,0 +1,26 @@
1
+ require 'ruby_to_ansi_c'
2
+
3
+ class RADTypeChecker < TypeChecker
4
+
5
+ def process_const(exp)
6
+ c = exp.shift
7
+ if c.to_s =~ /^[A-Z]/ then
8
+ # TODO: validate that it really is a const?
9
+ # uber hackery
10
+ # since constants are defined in the arduino_sketch define method and
11
+ # we can't inject them into the methods
12
+ # transport them here with a $define_types hash
13
+
14
+ $define_types.each do |k,v|
15
+ if k == c.to_s
16
+ @const_type = eval "Type.#{v}"
17
+ end
18
+ end
19
+ return t(:const, c, @const_type)
20
+ else
21
+ raise "I don't know what to do with const #{c.inspect}. It doesn't look like a class."
22
+ end
23
+ raise "need to finish process_const in #{self.class}"
24
+ end
25
+
26
+ end
@@ -0,0 +1,57 @@
1
+ ON = true
2
+ OFF = !ON
3
+ HIGH = ON
4
+ LOW = !HIGH
5
+
6
+ class ArduinoSketch
7
+ attr_accessor :pins
8
+
9
+ def initialize
10
+ @pins = self.class.instance_variable_get("@pins")
11
+ end
12
+
13
+ def self.output_pin(num, opts)
14
+ module_eval "@pins ||= []"
15
+ module_eval do
16
+ @pins << Pin.new( num, :type => :output )
17
+ end
18
+
19
+ if opts[:as]
20
+ module_eval <<-CODE
21
+ def #{opts[:as]}
22
+ pins.select{|p| p.num == #{num}}.first
23
+ end
24
+ CODE
25
+ end
26
+ end
27
+
28
+ def loop
29
+ end
30
+
31
+ def digitalWrite( pin, value )
32
+ to_change = pins.select{|p| p.num == pin.num}.first
33
+ to_change.value = value
34
+ end
35
+
36
+ def delay( millis )
37
+ end
38
+
39
+ # def serial_read
40
+ # end
41
+
42
+ # def serial_available
43
+ # end
44
+
45
+ # def blink
46
+ # end
47
+ end
48
+
49
+ class Pin
50
+ attr_accessor :num, :type, :value
51
+
52
+ def initialize num, opts
53
+ @num = num
54
+ @type = opts[:type]
55
+ @value = opts[:value] || false
56
+ end
57
+ end