Class: RADProcessor

Inherits:
RubyToAnsiC
  • Object
show all
Defined in:
lib/rad/rad_processor.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.translatorObject



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/rad/rad_processor.rb', line 6

def self.translator
  unless defined? @translator then
    @translator = CompositeSexpProcessor.new
    @translator << RADRewriter.new
    @translator << RADTypeChecker.new
    @translator << R2CRewriter.new
    @translator << self.new
    @translator.on_error_in(:defn) do |processor, exp, err|
      result = processor.expected.new
      case result
      when Array then
        result << :error
      end
      msg = "// ERROR: #{err.class}: #{err}"
      msg += " in #{exp.inspect}" unless exp.nil? or $TESTING
      msg += " from #{caller.join(', ')}" unless $TESTING
      result << msg
      result
    end
  end
  @translator
end

Instance Method Details

#process_iasgn(exp) ⇒ Object



29
30
31
32
33
# File 'lib/rad/rad_processor.rb', line 29

def process_iasgn(exp)
  name = exp.shift
  val = process exp.shift
  "__#{name.to_s.sub(/^@/, '')} = #{val}"
end

#process_iter(exp) ⇒ Object

Raises:

  • (UnsupportedNodeError)


40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/rad/rad_processor.rb', line 40

def process_iter(exp)
  # the array identifer may be in one of two locations
  # when using the instance variable (ivar) style it is located at exp[0][1][1]
  if exp[0][1][1]
    enum = exp[0][1][1]
    enum = "__#{enum.to_s.sub(/^@/, '')}" if enum.to_s =~ /^@/
  # for local variables it is located at exp[0][1][2]  
  elsif exp[0][1][2]
    enum = exp[0][1][2]
  end
  
  out = []
  # Only support enums in C-land # not sure if this comment if valid anymore
  raise UnsupportedNodeError if exp[0][1].nil? # HACK ugly
  @env.scope do
    
    call = process exp.shift
    var  = process(exp.shift).intern # semi-HACK-y 
    body = process exp.shift
    
    # array types from varible_processing>post_process_arrays and arduino_sketch>array
    $array_types.each do |k,v|
          @array_type = v if k == enum.to_s.sub(/^__/,"")
    end
    
    index_helper = $array_index_helpers.shift
    index = "index_#{index_helper}" # solves redeclaration issue

    body += ";" unless body =~ /[;}]\Z/
    body.gsub!(/\n\n+/, "\n")

    out << "unsigned int #{index};" # shouldn't need more than int
    out << "for (#{index} = 0; #{index} < (int) (sizeof(#{enum}) / sizeof(#{enum}[0])); #{index}++) {"   
    out << "#{@array_type} #{var} = #{enum}[#{index}];"
    out << body
    out << "}"
  end

  return out.join("\n")
end

#process_ivar(exp) ⇒ Object



35
36
37
38
# File 'lib/rad/rad_processor.rb', line 35

def process_ivar(exp)
  name = exp.shift
  "__#{name.to_s.sub(/^@/, '')}"
end

#process_lasgn(exp) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/rad/rad_processor.rb', line 81

def process_lasgn(exp)
  out = ""

  var = exp.shift
  value = exp.shift
  # grab the size of the args, if any, before process converts to a string
  arg_count = 0
  arg_count = value.length - 1 if value.first == :array
  args = value

  exp_type = exp.sexp_type
  @env.add var.to_sym, exp_type
  var_type = self.class.c_type exp_type

  if exp_type.list? then
    assert_type args, :array

    raise "array must be of one type" unless args.sexp_type == Type.homo

    # HACK: until we figure out properly what to do w/ zarray
    # before we know what its type is, we will default to long.
    array_type = args.sexp_types.empty? ? 'void *' : self.class.c_type(args.sexp_types.first)
    # we can fix array here..
    args.shift # :arglist
    out << "#{var} = (#{array_type}) malloc(sizeof(#{array_type}) * #{args.length});\n"
    args.each_with_index do |o,i|
      out << "#{var}[#{i}] = #{process o};\n"
    end
  else
    out << "#{var} = #{process args}"
  end

  out.sub!(/;\n\Z/, '')

  return out
end

#process_str(exp) ⇒ Object



118
119
120
121
122
123
124
125
# File 'lib/rad/rad_processor.rb', line 118

def process_str(exp)
  s = exp.shift.gsub(/\n/, '\\n')
  if s.size == 1
    return "\'#{s}\'"
  else
    return "\"#{s}\""
  end
end