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.
- checksums.yaml +7 -0
- data/History.txt +112 -0
- data/License.txt +282 -0
- data/Manifest.txt +144 -0
- data/README.rdoc +1 -0
- data/Rakefile +142 -0
- data/bin/rad +302 -0
- data/lib/examples/add_hysteresis.rb +13 -0
- data/lib/examples/basic_blink.rb +10 -0
- data/lib/examples/blink_m_address_assignment.rb +104 -0
- data/lib/examples/blink_m_hello.rb +14 -0
- data/lib/examples/blink_m_multi.rb +61 -0
- data/lib/examples/blink_with_serial.rb +16 -0
- data/lib/examples/configure_pa_lcd_boot.rb +91 -0
- data/lib/examples/debounce_methods.rb +49 -0
- data/lib/examples/external_variable_fu.rb +26 -0
- data/lib/examples/external_variables.rb +32 -0
- data/lib/examples/first_sound.rb +23 -0
- data/lib/examples/frequency_generator.rb +30 -0
- data/lib/examples/hello_array.rb +48 -0
- data/lib/examples/hello_array2.rb +112 -0
- data/lib/examples/hello_array_eeprom.rb +59 -0
- data/lib/examples/hello_clock.rb +84 -0
- data/lib/examples/hello_eeprom.rb +51 -0
- data/lib/examples/hello_eeprom_lcdpa.rb +81 -0
- data/lib/examples/hello_format_print.rb +94 -0
- data/lib/examples/hello_lcd_charset.rb +75 -0
- data/lib/examples/hello_pa_lcd.rb +59 -0
- data/lib/examples/hello_servos.rb +88 -0
- data/lib/examples/hello_spectra_sound.rb +38 -0
- data/lib/examples/hello_world.rb +11 -0
- data/lib/examples/hello_xbee.rb +12 -0
- data/lib/examples/hysteresis_duel.rb +39 -0
- data/lib/examples/i2c_with_clock_chip.rb +124 -0
- data/lib/examples/midi_beat_box.rb +86 -0
- data/lib/examples/midi_scales.rb +94 -0
- data/lib/examples/motor_knob.rb +30 -0
- data/lib/examples/servo_buttons.rb +23 -0
- data/lib/examples/servo_calibrate_continuous.rb +92 -0
- data/lib/examples/servo_throttle.rb +40 -0
- data/lib/examples/software_serial.rb +10 -0
- data/lib/examples/sparkfun_lcd.rb +48 -0
- data/lib/examples/spectra_soft_pot.rb +34 -0
- data/lib/examples/times_method.rb +8 -0
- data/lib/examples/toggle.rb +10 -0
- data/lib/examples/twitter.rb +57 -0
- data/lib/examples/two_wire.rb +14 -0
- data/lib/libraries/AFSoftSerial/AFSoftSerial.cpp +321 -0
- data/lib/libraries/AFSoftSerial/AFSoftSerial.h +61 -0
- data/lib/libraries/AFSoftSerial/keywords.txt +18 -0
- data/lib/libraries/AF_XPort/AF_XPort.cpp +166 -0
- data/lib/libraries/AF_XPort/AF_XPort.h +48 -0
- data/lib/libraries/DS1307/DS1307.cpp +162 -0
- data/lib/libraries/DS1307/DS1307.h +66 -0
- data/lib/libraries/DS1307/keywords.txt +18 -0
- data/lib/libraries/FrequencyTimer2/FrequencyTimer2.cpp +144 -0
- data/lib/libraries/FrequencyTimer2/FrequencyTimer2.h +42 -0
- data/lib/libraries/FrequencyTimer2/keywords.txt +22 -0
- data/lib/libraries/I2CEEPROM/I2CEEPROM.cpp +120 -0
- data/lib/libraries/I2CEEPROM/I2CEEPROM.h +70 -0
- data/lib/libraries/I2CEEPROM/keywords.txt +21 -0
- data/lib/libraries/LoopTimer/LoopTimer.cpp +35 -0
- data/lib/libraries/LoopTimer/LoopTimer.h +34 -0
- data/lib/libraries/LoopTimer/keywords.txt +27 -0
- data/lib/libraries/OneWire/OneWire.cpp +194 -0
- data/lib/libraries/OneWire/OneWire.h +63 -0
- data/lib/libraries/OneWire/keywords.txt +35 -0
- data/lib/libraries/OneWire/readme.txt +13 -0
- data/lib/libraries/SWSerLCDpa/SWSerLCDpa.cpp +296 -0
- data/lib/libraries/SWSerLCDpa/SWSerLCDpa.h +69 -0
- data/lib/libraries/SWSerLCDsf/SWSerLCDsf.cpp +311 -0
- data/lib/libraries/SWSerLCDsf/SWSerLCDsf.h +67 -0
- data/lib/libraries/Servo/Servo.cpp +192 -0
- data/lib/libraries/Servo/Servo.h +61 -0
- data/lib/libraries/Stepper/Stepper.cpp +220 -0
- data/lib/libraries/Stepper/Stepper.h +86 -0
- data/lib/libraries/Stepper/keywords.txt +28 -0
- data/lib/libraries/Wire/Wire.cpp +262 -0
- data/lib/libraries/Wire/Wire.h +67 -0
- data/lib/libraries/Wire/keywords.txt +31 -0
- data/lib/libraries/Wire/twi.h +57 -0
- data/lib/libraries/Wire/utility/twi.c +449 -0
- data/lib/libraries/Wire/utility/twi.h +57 -0
- data/lib/plugins/bitwise_ops.rb +54 -0
- data/lib/plugins/blink.rb +25 -0
- data/lib/plugins/blink_m.rb +356 -0
- data/lib/plugins/debounce.rb +138 -0
- data/lib/plugins/debug_output_to_lcd.rb +71 -0
- data/lib/plugins/hysteresis.rb +52 -0
- data/lib/plugins/input_output_state.rb +84 -0
- data/lib/plugins/lcd_padding.rb +58 -0
- data/lib/plugins/mem_test.rb +37 -0
- data/lib/plugins/midi.rb +60 -0
- data/lib/plugins/parallax_ping.rb +50 -0
- data/lib/plugins/servo_pulse.rb +31 -0
- data/lib/plugins/servo_setup.rb +86 -0
- data/lib/plugins/smoother.rb +54 -0
- data/lib/plugins/spark_fun_serial_lcd.rb +100 -0
- data/lib/plugins/spectra_symbol.rb +79 -0
- data/lib/plugins/twitter_connect.rb +145 -0
- data/lib/rad/README.rdoc +5 -0
- data/lib/rad/arduino_plugin.rb +246 -0
- data/lib/rad/arduino_sketch.rb +628 -0
- data/lib/rad/darwin_installer.rb +23 -0
- data/lib/rad/generators/makefile/makefile.erb +243 -0
- data/lib/rad/generators/makefile/makefile.rb +38 -0
- data/lib/rad/hardware_library.rb +813 -0
- data/lib/rad/init.rb +15 -0
- data/lib/rad/linux_installer.rb +132 -0
- data/lib/rad/progressbar.rb +236 -0
- data/lib/rad/rad_processor.rb +128 -0
- data/lib/rad/rad_rewriter.rb +94 -0
- data/lib/rad/rad_type_checker.rb +26 -0
- data/lib/rad/sim/arduino_sketch.rb +57 -0
- data/lib/rad/sketch_compiler.rb +47 -0
- data/lib/rad/tasks/build_and_make.rake +210 -0
- data/lib/rad/tasks/rad.rb +2 -0
- data/lib/rad/todo.txt +13 -0
- data/lib/rad/variable_processing.rb +153 -0
- data/lib/rad/version.rb +9 -0
- data/lib/rad.rb +5 -0
- data/scripts/txt2html +67 -0
- data/setup.rb +1585 -0
- data/spec/examples/hello_world.rb +11 -0
- data/spec/examples/serial_motor.rb +12 -0
- data/spec/models/arduino_sketch_spec.rb +82 -0
- data/spec/models/sketch_compiler_spec.rb +96 -0
- data/spec/models/spec_helper.rb +2 -0
- data/spec/sim/hello_world_spec.rb +42 -0
- data/spec/spec.opts +1 -0
- data/test/hello_world_test/Makefile +436 -0
- data/test/hello_world_test/hello_world.cpp +23 -0
- data/test/test_array_processing.rb +179 -0
- data/test/test_plugin_loading.rb +151 -0
- data/test/test_translation_post_processing.rb +185 -0
- data/test/test_variable_processing.rb +238 -0
- data/website/examples/assembler_test.rb.html +73 -0
- data/website/examples/gps_reader.rb.html +39 -0
- data/website/examples/hello_world.rb.html +38 -0
- data/website/examples/serial_motor.rb.html +41 -0
- data/website/index.html +178 -0
- data/website/index.txt +64 -0
- data/website/javascripts/rounded_corners_lite.inc.js +285 -0
- data/website/stylesheets/screen.css +169 -0
- data/website/template.rhtml +48 -0
- metadata +222 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# TODO:
|
|
2
|
+
# compilation
|
|
3
|
+
# gather pieces of code we need as strings
|
|
4
|
+
# translate non-loop methods
|
|
5
|
+
# do plugin stuff
|
|
6
|
+
# deal with examples/ exception
|
|
7
|
+
# manage upload process
|
|
8
|
+
# compose_setup should move in here entirely
|
|
9
|
+
|
|
10
|
+
# require 'arduino_sketch'
|
|
11
|
+
|
|
12
|
+
class SketchCompiler
|
|
13
|
+
attr_accessor :path, :body, :klass, :target_dir, :name
|
|
14
|
+
|
|
15
|
+
def initialize path_to_sketch
|
|
16
|
+
@path = File.expand_path(path_to_sketch)
|
|
17
|
+
@body = open(@path).read
|
|
18
|
+
@name = @path.split("/").last.split(".").first
|
|
19
|
+
@klass = @name.split(".").first.split("_").collect{|c| c.capitalize}.join("")
|
|
20
|
+
@target_dir = parent_dir
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def parent_dir
|
|
24
|
+
self.path.split("/")[0..@path.split("/").length-2].join("/")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def build_dir
|
|
28
|
+
"#{self.target_dir}/#{self.name}"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def create_build_dir! optional_path_prefix=nil
|
|
32
|
+
self.target_dir = optional_path_prefix if optional_path_prefix
|
|
33
|
+
mkdir_p build_dir
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def process_constants
|
|
37
|
+
self.body.gsub!("HIGH", "1")
|
|
38
|
+
self.body.gsub!("LOW", "0")
|
|
39
|
+
self.body.gsub!("ON", "1")
|
|
40
|
+
self.body.gsub!("OFF", "0")
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def sketch_methods
|
|
44
|
+
self.body.scan(/^\s*def\s.\w*/).collect{ |m| m.gsub(/\s*def\s*/, "") }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + "/../init.rb")
|
|
2
|
+
require 'ruby_to_ansi_c'
|
|
3
|
+
|
|
4
|
+
C_VAR_TYPES = "unsigned|int|long|double|str|char|byte|bool"
|
|
5
|
+
|
|
6
|
+
# incredibly primitive tests
|
|
7
|
+
# rake test:compile or rake test:upload
|
|
8
|
+
# runs through all sketches in the example directory
|
|
9
|
+
|
|
10
|
+
def run_tests(sketch, type)
|
|
11
|
+
sh %{rake make:#{type} sketch=examples/#{sketch}}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
namespace :test do
|
|
15
|
+
|
|
16
|
+
desc "iterate through all the sketches in the example directory"
|
|
17
|
+
task :upload => :gather do
|
|
18
|
+
@examples.each {|e| run_tests(e, "upload")}
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
task :compile => :gather do
|
|
22
|
+
|
|
23
|
+
@examples.each {|e| run_tests(e, "compile")}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
desc "gather all tests"
|
|
27
|
+
task :gather do # => "make:upload" do
|
|
28
|
+
@examples = []
|
|
29
|
+
if ENV['sketch']
|
|
30
|
+
@examples << ENV['sketch']
|
|
31
|
+
else
|
|
32
|
+
Dir.entries( File.expand_path("#{RAD_ROOT}/examples/") ).each do |f|
|
|
33
|
+
@examples << f.split('.').first if (f =~ /\.rb$/)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
namespace :make do
|
|
42
|
+
|
|
43
|
+
desc "compile the sketch and then upload it to your Arduino board"
|
|
44
|
+
task :upload => :compile do
|
|
45
|
+
if Makefile.hardware_params['physical_reset']
|
|
46
|
+
puts "Reset the Arduino and hit enter.\n==If your board doesn't need it, you can turn off this prompt in config/software.yml=="
|
|
47
|
+
STDIN.gets.chomp
|
|
48
|
+
end
|
|
49
|
+
sh %{cd #{@sketch.build_dir}; make upload}
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
desc "generate a makefile and use it to compile the .cpp"
|
|
53
|
+
task :compile => [:clean_sketch_dir, "build:sketch"] do # should also depend on "build:sketch"
|
|
54
|
+
Makefile.compose_for_sketch( @sketch.build_dir )
|
|
55
|
+
|
|
56
|
+
# not allowed? sh %{export PATH=#{Makefile.software_params[:arduino_root]}/tools/avr/bin:$PATH}
|
|
57
|
+
sh %{cd #{@sketch.build_dir}; make depend; make}
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
desc "generate a makefile and use it to compile the .cpp using the current .cpp file"
|
|
61
|
+
task :compile_cpp => ["build:sketch_dir", "build:gather_required_plugins", "build:plugin_setup", "build:setup", :clean_sketch_dir] do # should also depend on "build:sketch"
|
|
62
|
+
Makefile.compose_for_sketch( @sketch.build_dir )
|
|
63
|
+
# not allowed? sh %{export PATH=#{Makefile.software_params[:arduino_root]}/tools/avr/bin:$PATH}
|
|
64
|
+
sh %{cd #{@sketch.build_dir}; make depend; make}
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
desc "generate a makefile and use it to compile the .cpp and upload it using current .cpp file"
|
|
68
|
+
task :upload_cpp => ["build:sketch_dir", "build:gather_required_plugins", "build:plugin_setup", "build:setup", :clean_sketch_dir] do # should also depend on "build:sketch"
|
|
69
|
+
Makefile.compose_for_sketch( @sketch.build_dir )
|
|
70
|
+
# not allowed? sh %{export PATH=#{Makefile.software_params[:arduino_root]}/tools/avr/bin:$PATH}
|
|
71
|
+
sh %{cd #{@sketch.build_dir}; make depend; make upload}
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
task :clean_sketch_dir => ["build:file_list", "build:sketch_dir"] do
|
|
75
|
+
FileList.new(Dir.entries("#{@sketch.build_dir}")).exclude("#{@sketch.name}.cpp").exclude(/^\./).each do |f|
|
|
76
|
+
sh %{rm #{@sketch.build_dir}/#{f}}
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
namespace :build do
|
|
83
|
+
|
|
84
|
+
desc "actually build the sketch"
|
|
85
|
+
task :sketch => [:file_list, :sketch_dir, :gather_required_plugins, :plugin_setup, :setup] do
|
|
86
|
+
c_methods = []
|
|
87
|
+
sketch_signatures = []
|
|
88
|
+
# until we better understand RubyToC let's see what's happening on errors
|
|
89
|
+
@sketch.sketch_methods.each do |meth|
|
|
90
|
+
raw_rtc_meth = RADProcessor.translate(constantize(@sketch.klass), meth)
|
|
91
|
+
puts "Translator Error: #{raw_rtc_meth.inspect}" if raw_rtc_meth =~ /\/\/ ERROR:/
|
|
92
|
+
c_methods << raw_rtc_meth unless meth == "setup"
|
|
93
|
+
# treat the setup method differently
|
|
94
|
+
@additional_setup = [] if meth == "setup"
|
|
95
|
+
raw_rtc_meth.each {|m| @additional_setup << ArduinoSketch.add_to_setup(m) } if meth == "setup"
|
|
96
|
+
end
|
|
97
|
+
c_methods.each {|meth| sketch_signatures << "#{meth.scan(/^\w*\s?\*?\n.*\)/)[0].gsub("\n", " ")};" }
|
|
98
|
+
clean_c_methods = []
|
|
99
|
+
# remove external variables that were previously injected
|
|
100
|
+
c_methods.join("\n").each { |meth| clean_c_methods << ArduinoSketch.post_process_ruby_to_c_methods(meth) }
|
|
101
|
+
c_methods_with_timer = clean_c_methods.join.gsub(/loop\(\)\s\{/,"loop() {")
|
|
102
|
+
# last chance to add/change setup
|
|
103
|
+
@setup[2] << sketch_signatures.join("\n") unless sketch_signatures.empty?
|
|
104
|
+
# add special setup method to existing setup if present
|
|
105
|
+
if @additional_setup
|
|
106
|
+
@setup[2] << "void additional_setup();" # declaration
|
|
107
|
+
@setup[4] << "\tadditional_setup();" # call from setup
|
|
108
|
+
@setup[5] << @additional_setup.join("") #
|
|
109
|
+
end
|
|
110
|
+
result = "#{@setup.join( "\n" )}\n#{c_methods_with_timer}\n"
|
|
111
|
+
File.open("#{@sketch.build_dir}/#{@sketch.name}.cpp", "w"){|f| f << result}
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# needs to write the library include and the method signatures
|
|
115
|
+
desc "build setup function"
|
|
116
|
+
task :setup do
|
|
117
|
+
eval "class #{@sketch.klass} < ArduinoSketch; end;"
|
|
118
|
+
|
|
119
|
+
@@as = HardwareLibrary.new
|
|
120
|
+
|
|
121
|
+
delegate_methods = @@as.methods - Object.new.methods
|
|
122
|
+
delegate_methods.reject!{|m| m == "compose_setup"}
|
|
123
|
+
|
|
124
|
+
delegate_methods.each do |meth|
|
|
125
|
+
constantize(@sketch.klass).module_eval <<-CODE
|
|
126
|
+
def self.#{meth}(*args)
|
|
127
|
+
@@as.#{meth}(*args)
|
|
128
|
+
end
|
|
129
|
+
CODE
|
|
130
|
+
end
|
|
131
|
+
# allow variable declaration without quotes: @foo = int
|
|
132
|
+
["long","unsigned","int","byte","short"].each do |type|
|
|
133
|
+
constantize(@sketch.klass).module_eval <<-CODE
|
|
134
|
+
def self.#{type}
|
|
135
|
+
return "#{type}"
|
|
136
|
+
end
|
|
137
|
+
CODE
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
@sketch.process_constants
|
|
141
|
+
|
|
142
|
+
eval ArduinoSketch.pre_process(@sketch.body)
|
|
143
|
+
@@as.process_external_vars(constantize(@sketch.klass))
|
|
144
|
+
@setup = @@as.compose_setup
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
desc "add plugin methods"
|
|
148
|
+
task :plugin_setup do
|
|
149
|
+
$plugins_to_load.each do |name|
|
|
150
|
+
klass = name.split(".").first.split("_").collect{|c| c.capitalize}.join("")
|
|
151
|
+
eval "class #{klass} < ArduinoPlugin; end;"
|
|
152
|
+
|
|
153
|
+
@@ps = ArduinoPlugin.new
|
|
154
|
+
plugin_delegate_methods = @@ps.methods - Object.new.methods
|
|
155
|
+
plugin_delegate_methods.reject!{|m| m == "compose_setup"}
|
|
156
|
+
|
|
157
|
+
plugin_delegate_methods.each do |meth|
|
|
158
|
+
constantize(klass).module_eval <<-CODE
|
|
159
|
+
def self.#{meth}(*args)
|
|
160
|
+
@@ps.#{meth}(*args)
|
|
161
|
+
end
|
|
162
|
+
CODE
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
eval ArduinoPlugin.process(File.read("vendor/plugins/#{name}"))
|
|
166
|
+
|
|
167
|
+
end
|
|
168
|
+
@@no_plugins = ArduinoPlugin.new if @plugin_names.empty?
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
desc "determine which plugins to load based on use of methods in sketch"
|
|
172
|
+
task :gather_required_plugins do
|
|
173
|
+
@plugin_names.each do |name|
|
|
174
|
+
ArduinoPlugin.check_for_plugin_use(@sketch.body, File.read("vendor/plugins/#{name}"), name )
|
|
175
|
+
end
|
|
176
|
+
puts "#{$plugins_to_load.length} of #{$plugin_methods_hash.length} plugins are being loaded: #{$plugins_to_load.join(", ")}"
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
desc "setup target directory named after your sketch class"
|
|
180
|
+
task :sketch_dir => [:file_list] do
|
|
181
|
+
@sketch.create_build_dir!
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
task :file_list do
|
|
185
|
+
# take another look at this, since if the root directory name is changed, everything breaks
|
|
186
|
+
# perhaps we generate a constant when the project is generated an pop it here or in the init file
|
|
187
|
+
if ENV['sketch']
|
|
188
|
+
@sketch = SketchCompiler.new File.expand_path("#{ENV['sketch']}.rb")
|
|
189
|
+
else
|
|
190
|
+
# assume the only .rb file in the sketch dir is the sketch:
|
|
191
|
+
@sketch = SketchCompiler.new Dir.glob("#{File.expand_path(File.dirname(__FILE__))}/../../../*.rb").first
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
@plugin_names = []
|
|
195
|
+
Dir.entries( File.expand_path("#{RAD_ROOT}/vendor/plugins/") ).each do |f|
|
|
196
|
+
if (f =~ /\.rb$/)
|
|
197
|
+
@plugin_names << f
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
#yoinked from Rails
|
|
204
|
+
def constantize(camel_cased_word)
|
|
205
|
+
unless /\A(?:::)?([A-Z]\w*(?:::[A-Z]\w*)*)\z/ =~ camel_cased_word
|
|
206
|
+
raise NameError, "#{camel_cased_word.inspect} is not a valid constant name!"
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
Object.module_eval("::#{$1}", __FILE__, __LINE__)
|
|
210
|
+
end
|
data/lib/rad/todo.txt
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
TODO:
|
|
2
|
+
=====
|
|
3
|
+
|
|
4
|
+
Future:
|
|
5
|
+
- complete library system: script/install library some_library
|
|
6
|
+
- bin/rad:
|
|
7
|
+
- setup and use a ~/.rad for new project defaults
|
|
8
|
+
- put repository on git
|
|
9
|
+
- project gallery (examples with movies)
|
|
10
|
+
- testing framework
|
|
11
|
+
- implement wire lib
|
|
12
|
+
- subclasses of ArduinoSketch (should just work, but what are they for?)
|
|
13
|
+
- simulator
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
module ExternalVariableProcessing
|
|
2
|
+
# issues
|
|
3
|
+
# testing
|
|
4
|
+
# add checking for colon
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
## need to clean this up
|
|
8
|
+
## need to test
|
|
9
|
+
def process_external_vars(klass)
|
|
10
|
+
vars = eval "#{klass}.instance_variables"
|
|
11
|
+
local_vars = []
|
|
12
|
+
vars.each { |v| local_vars << ":#{v.gsub("@", "")}" }
|
|
13
|
+
loc_vars = local_vars.join(", ")
|
|
14
|
+
# add accessors
|
|
15
|
+
klass.module_eval "class << self; attr_accessor #{loc_vars} end"
|
|
16
|
+
local_vars.each do |symbol|
|
|
17
|
+
name = symbol.gsub(":","")
|
|
18
|
+
t_var = eval "#{klass}.#{name}"
|
|
19
|
+
pre_process_vars(name, t_var)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def pre_process_vars(name, var)
|
|
25
|
+
# puts
|
|
26
|
+
# puts
|
|
27
|
+
case var
|
|
28
|
+
when Integer
|
|
29
|
+
# puts "pre_process: #{name}, #{var}, #{var.inspect} got #{var.class} 29"
|
|
30
|
+
value = var
|
|
31
|
+
type = "int"
|
|
32
|
+
post_process_vars(name, type, value)
|
|
33
|
+
when Float
|
|
34
|
+
# puts "pre_process: #{name}, #{var}, #{var.inspect} got #{var.class} 34"
|
|
35
|
+
value = var
|
|
36
|
+
type = "float"
|
|
37
|
+
post_process_vars(name, type, value)
|
|
38
|
+
when String
|
|
39
|
+
# puts "pre_process: #{name}, #{var.inspect} got #{var.class} on 39"
|
|
40
|
+
if var.match(",").nil? && var =~ /long|byte|unsigned|int|short/
|
|
41
|
+
# puts "pre_process #{name}, #{var.inspect} got #{var.class} level three sublevel"
|
|
42
|
+
type = var
|
|
43
|
+
value = nil
|
|
44
|
+
post_process_vars(name, type, value)
|
|
45
|
+
else
|
|
46
|
+
value = var.split(",").first.lstrip
|
|
47
|
+
type = var.split(",")[1].nil? ? nil : var.split(",")[1].lstrip
|
|
48
|
+
translate_variables( name , type, value )
|
|
49
|
+
end
|
|
50
|
+
when TrueClass
|
|
51
|
+
# puts "pre_process: #{name}, #{var}, #{var.inspect} got #{var.class} on 50"
|
|
52
|
+
value = 1
|
|
53
|
+
type = "bool"
|
|
54
|
+
post_process_vars(name, type, value)
|
|
55
|
+
when FalseClass
|
|
56
|
+
# puts "pre_process: #{name}, #{var}, #{var.inspect} got #{var.class} on 55"
|
|
57
|
+
value = 0
|
|
58
|
+
type = "bool"
|
|
59
|
+
post_process_vars(name, type, value)
|
|
60
|
+
when Array
|
|
61
|
+
post_process_arrays(name, var)
|
|
62
|
+
else
|
|
63
|
+
raise ArgumentError, "not sure what to do here... got #{name} with value #{var} which is a #{var.class}"
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def translate_variables(name, type = nil, value = nil)
|
|
69
|
+
|
|
70
|
+
unless type.nil?
|
|
71
|
+
check_variable_type(type)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# classify the values
|
|
75
|
+
if value.class == Fixnum
|
|
76
|
+
# puts "translate_variables: #{name}, #{value}, #{type} is a fixnum, got #{value.class} on 74"
|
|
77
|
+
elsif value.class == Float
|
|
78
|
+
# puts "translate_variables: #{name}, #{value}, #{type} is a float, got #{value.class} on 76"
|
|
79
|
+
elsif value =~ /^-(\d|x)*$/
|
|
80
|
+
value = value.to_i
|
|
81
|
+
type = "int" if type.nil?
|
|
82
|
+
elsif value =~ /^-(\d|\.|x)*$/
|
|
83
|
+
value = value.to_f
|
|
84
|
+
unless type.nil?
|
|
85
|
+
raise ArgumentError, "#{value} should be a float got #{type}" unless type == "float"
|
|
86
|
+
end
|
|
87
|
+
type = "float" if type.nil?
|
|
88
|
+
|
|
89
|
+
elsif value[0,1] !~ /\d/
|
|
90
|
+
# puts value[0,1]
|
|
91
|
+
# puts "translate_variables: #{name}, #{value}, #{type} is a number of some type, got #{value.class} on 79"
|
|
92
|
+
type = "char*"
|
|
93
|
+
value = "\"#{value}\""
|
|
94
|
+
elsif value !~ /(\.|x)/
|
|
95
|
+
# puts "translate_variables: #{name}, #{value}, #{type} is an integer, got #{value.class} on 83"
|
|
96
|
+
value = value.to_i
|
|
97
|
+
type = "int" if type.nil?
|
|
98
|
+
elsif value =~ /(\d*\.\d*)/ # and no
|
|
99
|
+
# puts "translate_variables: #{name}, #{value}, #{type} is a float, got #{value.class} on 87"
|
|
100
|
+
value = value.to_f
|
|
101
|
+
type = "float"
|
|
102
|
+
elsif value =~ /0x\d\d/
|
|
103
|
+
# puts "translate_variables: #{name}, #{value}, #{type} is a byte, got #{value.class} on 91"
|
|
104
|
+
type = "byte"
|
|
105
|
+
else
|
|
106
|
+
raise ArgumentError, "not sure what to do with a value of #{value} with a type like #{type}"
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
post_process_vars(name, type, value)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def post_process_vars(name, type, value = nil)
|
|
115
|
+
value = " = #{value}" if value
|
|
116
|
+
$external_var_identifiers << "__#{name}" unless $external_var_identifiers.include?("__#{name}")
|
|
117
|
+
$external_vars << "#{type} __#{name}#{value};"
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def post_process_arrays(name, var)
|
|
121
|
+
type = c_type(var[0])
|
|
122
|
+
$array_types[name] = type
|
|
123
|
+
assignment = var.inspect.gsub("[","{").gsub("]","}")
|
|
124
|
+
c_style_array = "#{type} __#{name}[] = #{assignment};"
|
|
125
|
+
$external_var_identifiers << "__#{name}" unless $external_var_identifiers.include?("__#{name}")
|
|
126
|
+
$external_array_vars << c_style_array unless $external_array_vars.include?(c_style_array)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def check_variable_type(type)
|
|
130
|
+
unless type =~ /#{C_VAR_TYPES}/
|
|
131
|
+
raise ArgumentError, "the following variable types are supported \n #{C_VAR_TYPES.gsub("|",", ")} got #{type}"
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def c_type(typ)
|
|
136
|
+
type =
|
|
137
|
+
case typ
|
|
138
|
+
when Integer
|
|
139
|
+
"int"
|
|
140
|
+
when String
|
|
141
|
+
"char*"
|
|
142
|
+
when TrueClass
|
|
143
|
+
"bool"
|
|
144
|
+
when FalseClass
|
|
145
|
+
"bool"
|
|
146
|
+
else
|
|
147
|
+
raise "Bug! Unknown type #{typ.inspect} in c_type"
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
type
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
end
|
data/lib/rad/version.rb
ADDED
data/lib/rad.rb
ADDED
data/scripts/txt2html
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'rubygems'
|
|
4
|
+
require 'redcloth'
|
|
5
|
+
require 'syntax/convertors/html'
|
|
6
|
+
require 'erb'
|
|
7
|
+
require File.dirname(__FILE__) + '/../lib/rad/version.rb'
|
|
8
|
+
|
|
9
|
+
version = Rad::VERSION::STRING
|
|
10
|
+
download = 'http://rubyforge.org/projects/rad'
|
|
11
|
+
|
|
12
|
+
class Fixnum
|
|
13
|
+
def ordinal
|
|
14
|
+
# teens
|
|
15
|
+
return 'th' if (10..19).include?(self % 100)
|
|
16
|
+
# others
|
|
17
|
+
case self % 10
|
|
18
|
+
when 1: return 'st'
|
|
19
|
+
when 2: return 'nd'
|
|
20
|
+
when 3: return 'rd'
|
|
21
|
+
else return 'th'
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class Time
|
|
27
|
+
def pretty
|
|
28
|
+
return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def convert_syntax(syntax, source)
|
|
33
|
+
return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
if ARGV.length >= 1
|
|
37
|
+
src, template = ARGV
|
|
38
|
+
template ||= File.dirname(__FILE__) + '/../website/template.rhtml'
|
|
39
|
+
|
|
40
|
+
else
|
|
41
|
+
puts("Usage: #{File.split($0).last} source.txt [template.rhtml] > output.html")
|
|
42
|
+
exit!
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
template = ERB.new(File.open(template).read)
|
|
46
|
+
|
|
47
|
+
title = nil
|
|
48
|
+
body = nil
|
|
49
|
+
File.open(src) do |fsrc|
|
|
50
|
+
title_text = fsrc.readline
|
|
51
|
+
body_text = fsrc.read
|
|
52
|
+
syntax_items = []
|
|
53
|
+
body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</>!m){
|
|
54
|
+
ident = syntax_items.length
|
|
55
|
+
element, syntax, source = $1, $2, $3
|
|
56
|
+
syntax_items << "<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>"
|
|
57
|
+
"syntax-temp-#{ident}"
|
|
58
|
+
}
|
|
59
|
+
title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
|
|
60
|
+
body = RedCloth.new(body_text).to_html
|
|
61
|
+
body.gsub!(%r!(?:<pre><code>)?syntax-temp-(d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
|
|
62
|
+
end
|
|
63
|
+
stat = File.stat(src)
|
|
64
|
+
created = stat.ctime
|
|
65
|
+
modified = stat.mtime
|
|
66
|
+
|
|
67
|
+
$stdout << template.result(binding)
|