Top Level Namespace

Defined Under Namespace

Modules: CTokenizer, CType, Caphir, DBC, OCL, ParseErrorHandler, Preprocessor Classes: Module, ParserSettings, SearchPath, String

Instance Method Summary collapse

Instance Method Details

#expand_function(conditions, context, body, start_line, line_info) ⇒ Object



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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
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
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/dbc/expand_function.rb', line 8

def expand_function(conditions, context, body, start_line, line_info)
  raise 'should be a function' unless context.function?

  context_str = context.short_name
  f_cond = conditions[context_str]

  outstr = ''
  outstr << "\n"

  pre_text = ''      # preconditions

  post_text = ''   # postconditions

  inv_text = ''      # invariants

  final_text = ''    # stuff at the end


  if f_cond
    # get the conditions

    f_cond.conditions.each do |c|
      case c.type
        when "pre"
          pre_text
        when "post"
          post_text
        else
          raise ParseError, "unexpected condition type: #{c.type} for #{context_str}"
      end << c.to_cexp("\t")
    end
    # set up old values

    f_cond.old_values.each do |identifier, var_used|
      # figures out the type of identifiers such as a->b->c

      begin
        p_type = context.evaluate(identifier)
      rescue CType::EvaluationError
        raise CType::EvaluationError, "#{line_info}: in #{context_str}, #{$!} for #{identifier}"
      end
      # initializations

      outstr << "\t" << p_type.to_init_s(var_used)
      outstr << ' = ' << identifier << ";\n"
    end
  end

  context.parameters.each do |p|
    inv = conditions[p.short_name]
    if inv then inv.conditions.each do |c|
      raise ParseError, "expecting invariant got #{c.long_type} for #{p.to_s}" \
        unless c.type == "inv"
      exp_str = c.to_cexp("\t", context_str)
      # fix me - this could be better

      sub_str = '\1' + p.identifier + '\2'
      exp_str.gsub!(/(\W)self(\W+)/, sub_str)
      inv_text << exp_str
    end; end
  end
  
  if pre_text.empty? and post_text.empty? and inv_text.empty?
    # we're done early

    return body.collect! { |t| t.at(1) }.join
  end

  void_return_type = (context.base_type.to_s == 'void')

  unless void_return_type or (post_text.empty? and inv_text.empty?)
    outstr << "\t" << context.base_type.to_init_s('ocl__ret_val') << ";\n"
  end
  
  # output invariants and preconditions

  outstr << "\t/* Invariants: */\n" << inv_text unless inv_text.empty?
  outstr << "\t/* Preconditions: */\n" << pre_text unless pre_text.empty?

  outstr << "{\n"
  outstr << '#line ' << start_line.to_s << "\n" if line_info

  # output function body

  if post_text.empty? and inv_text.empty?
    outstr << body.collect! do |t|
      start_line += CTokenizer.line_count(t = t.at(1))
      t
    end.join
  else
    output_label = false
    if void_return_type
      outstr << body.collect do |t|
        start_line += CTokenizer.line_count( t = t.at(1) )
        if t == 'return'
          output_label = true
          'goto ocl__return_here'
        else
          t
        end
      end.join # do

    else
      until body.empty?
        start_line += CTokenizer.line_count( t = body.shift.at(1) )
        if t == 'return'
          output_label = true
          outstr << '{ ocl__ret_val = ( '
          until body.empty?
            start_line += CTokenizer.line_count( t = body.shift.at(1) )
            break if t == ';'
            outstr << t
          end
          outstr << ' ); goto ocl__return_here; }'
        else
          outstr << t
        end
      end # until

    end # if

    outstr << "\nocl__return_here:\n" if output_label
    # must explicitly return the return value unless return value is void

    final_text << "\treturn ocl__ret_val;\n" unless void_return_type
  end
  outstr << "\n"

  # output postconditions and invariants

  outstr << "\t/* Postconditions: */\n" << post_text unless post_text.empty?
  outstr << "\t/* Invariants: */\n" << inv_text unless inv_text.empty?

  outstr << final_text
  outstr << "}\n"
  outstr << '#line ' << start_line.to_s << "\n" if line_info
  outstr
end

#expand_version(pre, version) ⇒ Object

Removes dots and zero pads



5
6
7
8
9
# File 'lib/caphir/preprocessor_conf.rb', line 5

def expand_version(pre, version)
  version.delete!('.')
  (3 - version.length).times { version << '0' }
  "#{pre}#{version}"
end