class RubimCode
RubimCode
CORE #
#
Author: Evgeny Danilov # Created at 2016 March-14 #
Constants
- VERSION
Attributes
level[RW]
Public Class Methods
clear_c(str)
click to toggle source
# 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")
click to toggle source
# 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)
click to toggle source
type_cc - тип переменной в С-программе variables - набор инициализируемых переменных
# File lib/rubimc/init_var.rb, line 7 def RubimCode.init_vars(type_cc, *variables) vars_cc = "" rubim_vars = [] variables.each {|var| # ToDo - поиск уже объявленных переменных и выдача предупреждений if var.is_a? Hash # ToDo RubimCode.perror "Ошибка. В текущей версии нельзя назначать переменным значения при объявлении" # key = var.keys.first # instance_variable_set("@#{key.to_s}" , UserVariable.new("#{key.to_s}")) # vars_cc += "#{key.to_s}=#{var[key]}, " 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 /$./ # define GLOBAL variable RubimCode.perror "Ruby-like global variables are not supported yet. Use 'integer :@#{var_name}'" when /@@/ # define CLASS variable RubimCode.perror "Ruby-like class variables are not supported yet. Use 'integer :@#{var_name}'" when /@./ # define INSTANCE variable (in C it defined as global - outside the 'main' function) RubimCode::Printer.instance_vars_cc << new_var else # define LOCAL variable (in C it defined as local) 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)
click to toggle source
# 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 = "")
click to toggle source
# File lib/rubimc/printer.rb, line 40 def pout(str = "") return if RubimCode::Printer.sandbox == true # don`t print output in sandbox 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()
click to toggle source
# File lib/rubimc/control_structures.rb, line 53 def rubim_begin(); pout "{"; @level+=1; true; end
rubim_break()
click to toggle source
# File lib/rubimc/control_structures.rb, line 62 def rubim_break; pout "break;" end
rubim_cbit(var, bit)
click to toggle source
# File lib/rubimc/io_ports.rb, line 40 def rubim_cbit(var, bit); "#{var} &= ~(1<<#{bit});"; end
rubim_cond(cond, type="if") { || ... }
click to toggle source
instructions “if” & “unless”
# File lib/rubimc/control_structures.rb, line 7 def rubim_cond(cond, type="if", &block) # ToDo: auto-define type of ret_value # use:: __rubim__rval__int, __rubim__rval__float, e.t. 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") { || ... }
click to toggle source
instructions “while” & “until”
# 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()
click to toggle source
# File lib/rubimc/control_structures.rb, line 57 def rubim_else(); @level-=1; pout "} else {"; @level+=1; end
rubim_elsif(cond)
click to toggle source
# File lib/rubimc/control_structures.rb, line 58 def rubim_elsif(cond); @level-=1; pout "} else if (#{cond}) {"; @level+=1; end
rubim_end()
click to toggle source
# File lib/rubimc/control_structures.rb, line 54 def rubim_end(); pout "}"; @level-=1; "__rubim__noreturn"; end
rubim_if(cond, &block)
click to toggle source
flat instructions
# File lib/rubimc/control_structures.rb, line 41 def rubim_if(cond, &block); rubim_cond(cond, "if", &block); end
rubim_ifmod(cond)
click to toggle source
modify instructions
# File lib/rubimc/control_structures.rb, line 48 def rubim_ifmod(cond); pout "if (#{cond}) {"; @level+=1; true; end
rubim_loop(&block)
click to toggle source
# File lib/rubimc/control_structures.rb, line 45 def rubim_loop(&block); rubim_cycle("while", "true", &block); end
rubim_next()
click to toggle source
ToDo: in ‘else’ and ‘elsif’ set return_val, like in rubim_if
(need to change preprocessor)
# File lib/rubimc/control_structures.rb, line 61 def rubim_next; pout "continue;" end
rubim_sbit(var, bit)
click to toggle source
# File lib/rubimc/io_ports.rb, line 39 def rubim_sbit(var, bit); "#{var} |= 1<<#{bit};"; end
rubim_tbit(var, bit)
click to toggle source
# File lib/rubimc/io_ports.rb, line 41 def rubim_tbit(var, bit); "#{var} ^= 1<<#{bit};"; end
rubim_tmpif(tmp)
click to toggle source
# File lib/rubimc/control_structures.rb, line 55 def rubim_tmpif(tmp); end
rubim_unless(cond, &block)
click to toggle source
# File lib/rubimc/control_structures.rb, line 42 def rubim_unless(cond, &block); rubim_cond(cond, "unless", &block); end
rubim_unlessmod(cond)
click to toggle source
# File lib/rubimc/control_structures.rb, line 49 def rubim_unlessmod(cond); pout "if (!(#{cond})) {"; @level+=1; true; end
rubim_until(cond)
click to toggle source
# File lib/rubimc/control_structures.rb, line 44 def rubim_until(cond); rubim_cycle("until", cond, &block); end
rubim_untilmod(cond)
click to toggle source
# File lib/rubimc/control_structures.rb, line 51 def rubim_untilmod(cond); pout "} until (#{cond});"; @level-=1; end
rubim_while(cond, &block)
click to toggle source
# File lib/rubimc/control_structures.rb, line 43 def rubim_while(cond, &block); rubim_cycle("while", cond, &block); end
rubim_whilemod(cond)
click to toggle source
# File lib/rubimc/control_structures.rb, line 50 def rubim_whilemod(cond); pout "} while (#{cond});"; @level-=1; end