Class: CSquare::Function

Inherits:
Base
  • Object
show all
Defined in:
lib/csquare/function.rb

Overview

Represents a C function template.

Constant Summary

Constants inherited from Base

Base::EXTRA_TYPE_NAMES

Instance Attribute Summary

Attributes inherited from Base

#entity, #parser

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#code

Constructor Details

#initialize(code, type_names) ⇒ Function

Returns a new instance of Function.

Raises:

  • (SyntaxError)


3
4
5
6
7
# File 'lib/csquare/function.rb', line 3

def initialize code, type_names
  super code, type_names
  @decorated_name = false
  raise(SyntaxError, "expected function definition") unless entity.FunctionDef?
end

Class Method Details

.find_broken_ast(tree) ⇒ Object



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/csquare/function.rb', line 157

def find_broken_ast tree
  begin
    tree.to_s
    return nil
  rescue TypeError
    tree.each do |e|
      x = CSquare::Function.find_broken_ast(e)
      unless x.nil?
        require "pry"
        binding.pry
      end
    end
    return tree
  end
end

Instance Method Details

#cloneObject

Make a deep copy of this function.



10
11
12
# File 'lib/csquare/function.rb', line 10

def clone
  CSquare::Function.new(self.code, @parser.type_names.to_a)
end

#declarationObject

Return the function declaration for the header file



15
16
17
18
# File 'lib/csquare/function.rb', line 15

def declaration
  t = @entity.type
  "#{t.type.to_s} #{name}(#{t.params.to_s});"
end

#decorate_calls!(blueprint, type_symbol) ⇒ Object

Given all function calls, figure out what they should instead be and change the tree as we go.



106
107
108
# File 'lib/csquare/function.rb', line 106

def decorate_calls! blueprint, type_symbol
  @entity.recursively_decorate_calls! blueprint, type_symbol
end

#decorate_name!(type_symbol) ⇒ Object



24
25
26
27
28
# File 'lib/csquare/function.rb', line 24

def decorate_name! type_symbol
  @entity.name = decorated_name(type_symbol)
  @decorated_name = true
  self
end

#decorated_name(type_symbol) ⇒ Object



30
31
32
# File 'lib/csquare/function.rb', line 30

def decorated_name type_symbol
  @decorated_name ? @entity.name : "#{@entity.name}_#{type_symbol}"
end

#definitionObject



48
49
50
# File 'lib/csquare/function.rb', line 48

def definition
  @entity.def
end

#has_local?(var, blueprint = nil) ⇒ Boolean

Is some local identifier in use?

Returns:

  • (Boolean)


130
131
132
# File 'lib/csquare/function.rb', line 130

def has_local? var, blueprint=nil
  @entity.has_local? var, blueprint
end

#locals(as = nil) ⇒ Object

Return a hash of function local variables => types. You may pass :string as the sole argument if you want



44
45
46
# File 'lib/csquare/function.rb', line 44

def locals(as=nil)
  @entity.def.locals(as)
end

#locals_and_types(blueprint) ⇒ Object

Return a list of local variables, function names, parameters, etc; hashed to type (string).



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/csquare/function.rb', line 112

def locals_and_types blueprint
  vars_and_types = blueprint.generator.externs.merge(blueprint.externs).
                      merge(params).
                      merge(locals)

  # Go through and remove const indicators, as these will only get in the way
  vars_and_types.each_pair do |var, type|
    if type.is_a?(C::DirectType)
      vars_and_types[var].const = false
      vars_and_types[var] = vars_and_types[var].to_s
    end
  end

  vars_and_types
end

#mutate!(blueprint, new_type_symbol, params = nil) ⇒ Object



141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/csquare/function.rb', line 141

def mutate! blueprint, new_type_symbol, params = nil

  # Create a frozen duplicate of this function, that hasn't had its typenames changed.
  f = self.clone

  self.decorate_name! new_type_symbol

  self.entity.recombine! f, blueprint, new_type_symbol

  self.replace_types!(params || blueprint.params(new_type_symbol))

  self
end

#nameObject



34
35
36
# File 'lib/csquare/function.rb', line 34

def name
  @entity.name
end

#params(as = nil) ⇒ Object

Return a hash of function parameters => types. Passing the argument :string will return type strings instead of CAST types.



39
40
41
# File 'lib/csquare/function.rb', line 39

def params(as=nil)
  @entity.params(as)
end

#rename!(new_name) ⇒ Object



20
21
22
# File 'lib/csquare/function.rb', line 20

def rename! new_name
  @entity.name = new_name
end

#replace_types!(h) ⇒ Object

Given some hash of typenames to replacement types, change all parameters and declarations.

Hash should consist of string values only.



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/csquare/function.rb', line 86

def replace_types! h
  # STDERR.puts "parser typenames: #{@parser.type_names.inspect}"

  h.each_value do |new_typename|
    @parser.type_names << new_typename
    C.default_parser.type_names << new_typename
  end

  # Replace the types in the function prototype
  @entity.entries[0].replace_types! h

  # Recurse down into function blocks
  @entity.entries[1].replace_types! h

  # Replace typecasts
  @entity.recursively_replace_casts! h
end

#return_typeObject



52
53
54
# File 'lib/csquare/function.rb', line 52

def return_type
  @entity.type.type
end

#template_locals(typenames) ⇒ Object

Get those local variables which we need to watch when applying templates, based on the template typenames given (only argument).



71
72
73
74
75
76
77
78
79
80
# File 'lib/csquare/function.rb', line 71

def template_locals typenames
  watch_locals = {}

  locals.each_pair do |varname, fdec|
    if typenames.include?(fdec.underlying_typename)
      watch_locals[varname] = fdec.underlying_typename
    end
  end
  watch_locals
end

#template_params(typenames) ⇒ Object

Get those parameters which we need to watch, based on the template typenames given (as an argument).



58
59
60
61
62
63
64
65
66
67
# File 'lib/csquare/function.rb', line 58

def template_params typenames
  watch_params = {}

  params.each_pair do |varname, fparam|
    if typenames.include?(fparam.underlying_typename)
      watch_params[varname] = fparam.underlying_typename
    end
  end
  watch_params
end

#type_of(var, blueprint = nil) ⇒ Object

Return the type associated with some variable. Optionally can look for globals if blueprint is given.



136
137
138
# File 'lib/csquare/function.rb', line 136

def type_of var, blueprint=nil
  @entity.type_of var, blueprint
end