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
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
|