neo_rad 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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