Class: RubimCode
- Inherits:
-
Object
show all
- Defined in:
- lib/rubimc.rb,
lib/rubimc.rb,
lib/version.rb,
lib/rubimc/printer.rb,
lib/rubimc/io_ports.rb,
lib/rubimc/control_structures.rb
Overview
RubimCode CORE # # Author: Evgeny Danilov # Created at 2016 March-14 #
Defined Under Namespace
Classes: CC_ARGS, Interrupts, Isolator, LoopCounter, Printer, UserArray, UserClass, UserIO, UserInput, UserOutput, UserVariable
Constant Summary
collapse
- VERSION =
"0.2.2"
- @@rubim_defined_values =
[]
Class Attribute Summary collapse
Class Method Summary
collapse
-
.clear_c(str) ⇒ Object
-
.init_io(mcu_class, rb_type, var, port: nil, pin: nil, type: "normal") ⇒ Object
-
.init_vars(type_cc, *variables) ⇒ Object
type_cc - тип переменной в С-программе variables - набор инициализируемых переменных.
-
.perror(error_message) ⇒ Object
-
.pout(str = "") ⇒ Object
-
.rubim_begin ⇒ Object
-
.rubim_break ⇒ Object
-
.rubim_cbit(var, bit) ⇒ Object
-
.rubim_cond(cond, type = "if", &block) ⇒ Object
instructions “if” & “unless”.
-
.rubim_cycle(type = "while", cond = "true", &block) ⇒ Object
instructions “while” & “until”.
-
.rubim_else ⇒ Object
-
.rubim_elsif(cond) ⇒ Object
-
.rubim_end ⇒ Object
-
.rubim_if(cond, &block) ⇒ Object
-
.rubim_ifmod(cond) ⇒ Object
-
.rubim_loop(&block) ⇒ Object
-
.rubim_next ⇒ Object
ToDo: in ‘else’ and ‘elsif’ set return_val, like in rubim_if (need to change preprocessor).
-
.rubim_sbit(var, bit) ⇒ Object
-
.rubim_tbit(var, bit) ⇒ Object
-
.rubim_tmpif(tmp) ⇒ Object
-
.rubim_unless(cond, &block) ⇒ Object
-
.rubim_unlessmod(cond) ⇒ Object
-
.rubim_until(cond) ⇒ Object
-
.rubim_untilmod(cond) ⇒ Object
-
.rubim_while(cond, &block) ⇒ Object
-
.rubim_whilemod(cond) ⇒ Object
Class Attribute Details
Returns the value of attribute level.
19
20
21
|
# File 'lib/rubimc/printer.rb', line 19
def level
@level
end
|
Class Method Details
.clear_c(str) ⇒ Object
64
65
66
67
68
|
# File 'lib/rubimc/printer.rb', line 64
def clear_c(str)
pout "// generate with clear_c function"
pout str
pout "// end clear_c function"
end
|
.init_io(mcu_class, rb_type, var, port: nil, pin: nil, type: "normal") ⇒ Object
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
# File 'lib/rubimc/io_ports.rb', line 1
def RubimCode.init_io(mcu_class, rb_type, var, port: nil, pin: nil, type: "normal")
if port.nil? or pin.nil?
RubimCode.perror "Необходимо указать порт и пин для выхода #{var}"
elsif not mcu_class::PORTS.include? port.to_sym
RubimCode.perror "У микроконтроллера #{mcu_class::MCU_NAME} нет порта #{port}"
elsif not mcu_class::PORTS[port.to_sym].include? pin.to_i
RubimCode.perror "У микроконтроллера #{mcu_class::MCU_NAME} нет порта пина #{pin} для порта #{port}"
elsif not var.is_a? Symbol
RubimCode.perror "Unknown type of parameters for helper #{__method__}"
end
if type == "normal"
var_name = var.to_s.gsub(/^[@$]/, "")
if rb_type == 'output'
return RubimCode::UserOutput.new(var_name, port: port, pin: pin, type: type)
elsif rb_type == 'input'
return RubimCode::UserInput.new(var_name, port: port, pin: pin, type: type)
end
elsif type == "tri-state"
RubimCode.perror "В данный момент тип выхода 'z-state' не реализован"
else
RubimCode.perror "Неизвестный тип выхода '#{type}'"
end
end
|
.init_vars(type_cc, *variables) ⇒ Object
type_cc - тип переменной в С-программе variables - набор инициализируемых переменных
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
# File 'lib/rubimc/init_var.rb', line 7
def RubimCode.init_vars(type_cc, *variables)
vars_cc = ""
rubim_vars = []
variables.each {|var|
if var.is_a? Hash
RubimCode.perror "Ошибка. В текущей версии нельзя назначать переменным значения при объявлении"
elsif var.is_a? Symbol
var_str = var.to_s
var_name = var_str.gsub(/^[@$]/, "")
new_var = RubimCode::UserVariable.new("#{var_name}", type_cc)
rubim_vars << new_var
case var_str[0..1]
when /$./
RubimCode.perror "Ruby-like global variables are not supported yet. Use 'integer :@#{var_name}'"
when /@@/
RubimCode.perror "Ruby-like class variables are not supported yet. Use 'integer :@#{var_name}'"
when /@./
RubimCode::Printer.instance_vars_cc << new_var
else
RubimCode::Isolator.local_variables << var_name if RubimCode::Isolator.enabled
vars_cc += "#{var_name}, "
end
else
RubimCode.perror "Unknown type of parameters for helper #{__method__}"
end
}
if rubim_vars.empty?
RubimCode.perror "No variables for initialize"
end
unless vars_cc.empty?
vars_cc.chomp!(", ")
RubimCode.pout ("#{type_cc} #{vars_cc};")
end
if rubim_vars.count == 1
return rubim_vars[0]
else
return rubim_vars
end
end
|
.perror(error_message) ⇒ Object
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
# File 'lib/rubimc/printer.rb', line 24
def perror(error_message)
if error_message.nil? or error_message.to_s.nil?
raise ArgumentError, "error message is not string"
end
error_message += "\n"
code_ptr = caller_locations(2)
code_ptr.each do |place|
place = place.to_s
place.gsub!(/\/release\//, '/')
error_message += "\tfrom #{place}\n"
end
puts "#ERROR: #{error_message}"
exit 1
end
|
.pout(str = "") ⇒ Object
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
# File 'lib/rubimc/printer.rb', line 40
def pout(str = "")
return if RubimCode::Printer.sandbox == true
if str.nil? or str.to_s.nil?
raise ArgumentError, "str is nil"
else
@level = 0 if @level.nil?
res_str = " "*4*@level + str.to_s
if RubimCode::Printer.pout_destination.in? [:default, nil]
puts res_str
unless defined? TEST_MODE
File.open("#{ARGV[0]}", 'a+') {|file| file.puts(res_str) }
end
elsif RubimCode::Printer.pout_destination == :h_file
unless defined? TEST_MODE
h_name = ARGV[0].gsub(/\.c$/, '') + ".h"
File.open("#{h_name}", 'a+') {|file| file.puts(res_str) }
end
else
RubimCode::Printer.pout_destination.concat(res_str).concat("\n")
end
end
end
|
.rubim_begin ⇒ Object
53
|
# File 'lib/rubimc/control_structures.rb', line 53
def rubim_begin(); pout "{"; @level+=1; true; end
|
.rubim_break ⇒ Object
62
|
# File 'lib/rubimc/control_structures.rb', line 62
def rubim_break; pout "break;" end
|
.rubim_cbit(var, bit) ⇒ Object
40
|
# File 'lib/rubimc/io_ports.rb', line 40
def rubim_cbit(var, bit); "#{var} &= ~(1<<#{bit});"; end
|
.rubim_cond(cond, type = "if", &block) ⇒ Object
instructions “if” & “unless”
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
# File 'lib/rubimc/control_structures.rb', line 7
def rubim_cond(cond, type="if", &block)
if @@rubim_defined_values.include? @level
pout "__rubim__rval#{@level} = 0;"
else
pout "int __rubim__rval#{@level} = 0;"
end
@@rubim_defined_values << @level
if type=="if"
pout "if (#{cond}) {"
elsif type=="unless"
pout "if (!(#{cond})) {"
end
@level += 1
ret_val = yield
pout "__rubim__rval#{@level-1} = #{ret_val};" if ret_val!="__rubim__noreturn"
pout "}"
@level -= 1
return RubimCode::UserVariable.new("__rubim__rval#{@level}", 'tmp_int')
end
|
.rubim_cycle(type = "while", cond = "true", &block) ⇒ Object
instructions “while” & “until”
32
33
34
35
36
37
38
|
# File 'lib/rubimc/control_structures.rb', line 32
def rubim_cycle(type="while", cond="true", &block)
pout "#{type} (#{cond}) {"
@level+=1
yield
pout "}"
@level-=1
end
|
.rubim_else ⇒ Object
57
|
# File 'lib/rubimc/control_structures.rb', line 57
def rubim_else(); @level-=1; pout "} else {"; @level+=1; end
|
.rubim_elsif(cond) ⇒ Object
58
|
# File 'lib/rubimc/control_structures.rb', line 58
def rubim_elsif(cond); @level-=1; pout "} else if (#{cond}) {"; @level+=1; end
|
.rubim_end ⇒ Object
54
|
# File 'lib/rubimc/control_structures.rb', line 54
def rubim_end(); pout "}"; @level-=1; "__rubim__noreturn"; end
|
.rubim_if(cond, &block) ⇒ Object
41
|
# File 'lib/rubimc/control_structures.rb', line 41
def rubim_if(cond, &block); rubim_cond(cond, "if", &block); end
|
.rubim_ifmod(cond) ⇒ Object
48
|
# File 'lib/rubimc/control_structures.rb', line 48
def rubim_ifmod(cond); pout "if (#{cond}) {"; @level+=1; true; end
|
.rubim_loop(&block) ⇒ Object
45
|
# File 'lib/rubimc/control_structures.rb', line 45
def rubim_loop(&block); rubim_cycle("while", "true", &block); end
|
.rubim_next ⇒ Object
ToDo: in ‘else’ and ‘elsif’ set return_val, like in rubim_if (need to change preprocessor)
61
|
# File 'lib/rubimc/control_structures.rb', line 61
def rubim_next; pout "continue;" end
|
.rubim_sbit(var, bit) ⇒ Object
39
|
# File 'lib/rubimc/io_ports.rb', line 39
def rubim_sbit(var, bit); "#{var} |= 1<<#{bit};"; end
|
.rubim_tbit(var, bit) ⇒ Object
41
|
# File 'lib/rubimc/io_ports.rb', line 41
def rubim_tbit(var, bit); "#{var} ^= 1<<#{bit};"; end
|
.rubim_tmpif(tmp) ⇒ Object
55
|
# File 'lib/rubimc/control_structures.rb', line 55
def rubim_tmpif(tmp); end
|
.rubim_unless(cond, &block) ⇒ Object
42
|
# File 'lib/rubimc/control_structures.rb', line 42
def rubim_unless(cond, &block); rubim_cond(cond, "unless", &block); end
|
.rubim_unlessmod(cond) ⇒ Object
49
|
# File 'lib/rubimc/control_structures.rb', line 49
def rubim_unlessmod(cond); pout "if (!(#{cond})) {"; @level+=1; true; end
|
.rubim_until(cond) ⇒ Object
44
|
# File 'lib/rubimc/control_structures.rb', line 44
def rubim_until(cond); rubim_cycle("until", cond, &block); end
|
.rubim_untilmod(cond) ⇒ Object
51
|
# File 'lib/rubimc/control_structures.rb', line 51
def rubim_untilmod(cond); pout "} until (#{cond});"; @level-=1; end
|
.rubim_while(cond, &block) ⇒ Object
43
|
# File 'lib/rubimc/control_structures.rb', line 43
def rubim_while(cond, &block); rubim_cycle("while", cond, &block); end
|
.rubim_whilemod(cond) ⇒ Object
50
|
# File 'lib/rubimc/control_structures.rb', line 50
def rubim_whilemod(cond); pout "} while (#{cond});"; @level-=1; end
|