Class: Namespace

Inherits:
Object
  • Object
show all
Extended by:
TSort
Defined in:
lib/cast_off/compile/namespace/namespace.rb

Overview

“To compile a thing is to manage its namespace.” – a nameless developer

Constant Summary collapse

UUIDNS =

This is used to limit the UUID namespace

UUID.parse 'urn:uuid:71614e1a-0cb4-11df-bc41-5769366ff630'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name = nil) ⇒ Namespace

I originally implemented this as a simple Struct.new, but I needed some validations over setter methods, so I now have my own impl.

A C object has at most four attributes. Normally 3 and 4 are exclusive, but not required to be.

  1. A name to refer to that object

  2. Type of that object

  3. Static definition of that object

  4. Dynamic initializer for that object



194
195
196
197
198
199
200
201
# File 'lib/cast_off/compile/namespace/namespace.rb', line 194

def initialize name = nil
  @name           = name
  @declaration    = nil
  @definition     = nil
  @initialization = nil
  @expression     = nil
  @dependencies   = Array.new
end

Instance Attribute Details

#declarationObject (readonly)

Returns the value of attribute declaration.



203
204
205
# File 'lib/cast_off/compile/namespace/namespace.rb', line 203

def declaration
  @declaration
end

#definitionObject (readonly)

Returns the value of attribute definition.



203
204
205
# File 'lib/cast_off/compile/namespace/namespace.rb', line 203

def definition
  @definition
end

#dependenciesObject (readonly)

Returns the value of attribute dependencies.



203
204
205
# File 'lib/cast_off/compile/namespace/namespace.rb', line 203

def dependencies
  @dependencies
end

#expressionObject (readonly)

Returns the value of attribute expression.



203
204
205
# File 'lib/cast_off/compile/namespace/namespace.rb', line 203

def expression
  @expression
end

#initializationObject (readonly)

Returns the value of attribute initialization.



203
204
205
# File 'lib/cast_off/compile/namespace/namespace.rb', line 203

def initialization
  @initialization
end

#nameObject (readonly)

Returns the value of attribute name.



203
204
205
# File 'lib/cast_off/compile/namespace/namespace.rb', line 203

def name
  @name
end

Class Method Details

.eachObject

Atomic each



164
165
166
167
168
# File 'lib/cast_off/compile/namespace/namespace.rb', line 164

def each
  @barenames.each_value do |n|
    yield n
  end
end

.each_funcsObject

Iterates over functions



141
142
143
144
145
146
147
148
149
150
151
# File 'lib/cast_off/compile/namespace/namespace.rb', line 141

def each_funcs
  # Functions are also not depended each other.
  a = @barenames.values
  a.map! do |n| n.definition end
  a.reject! do |e|
    not %r/^[a-zA-Z0-9_]+\(/.match e
  end
  a.each do |e|
    yield e
  end
end

.each_initializersObject

Iterates over initializers



154
155
156
157
158
159
160
161
# File 'lib/cast_off/compile/namespace/namespace.rb', line 154

def each_initializers
  # Initializers do depend each other.  Order matters here.
  tsort_each do |n|
    if i = n.initialization
      yield i
    end
  end
end

.each_nonstatic_declsObject

Iterates over non-static declarations



134
135
136
137
138
# File 'lib/cast_off/compile/namespace/namespace.rb', line 134

def each_nonstatic_decls
  split_decls.last.each do |e|
    yield e
  end
end

.each_static_declsObject

Iterates over static declarations



127
128
129
130
131
# File 'lib/cast_off/compile/namespace/namespace.rb', line 127

def each_static_decls
  split_decls.first.each do |e|
    yield e
  end
end

.namegen(desired = UUID.new.to_s, realuniq = false) ⇒ Object

This is aliased to class method “new”. Generates a name unique in this namespace, taking as much as possible from what’s desired.

Note however, that an identical argument desired generates a same name on multiple invocations unless realuniq is true.



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
# File 'lib/cast_off/compile/namespace/namespace.rb', line 58

def namegen desired = UUID.new.to_s, realuniq = false
  a = @desired2names.fetch desired, Array.new
  return a.first if not realuniq and not a.empty?
  n = nil
  cand0 = as_tr_cpp desired.to_s
  cand1 = cand0
  while @barenames.has_key? cand1
    n ||= 1
    n += 1
    cand1 = cand0 + n.to_s
  end
  if cand1.length <= @limit
    # OK, take this
    name = old_new @prefix + cand1
    a.push name
    @desired2names.store desired, a
    @barenames.store cand1, name
    return name
  elsif @phasechange
    # name too long, use UUID#to_s
    u = UUIDNS.new_sha1 desired.to_s
    return new u.to_s, realuniq
  else
    # yet too long, now use Integer#to_s
    u = UUIDNS.new_sha1 desired.to_s
    v = u.to_i.to_s @radix
    return new v, realuniq
  end
end

.new(namemax = 31, prefix = 'yarv_') ⇒ Object

creates a new namespace.



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
# File 'lib/cast_off/compile/namespace/namespace.rb', line 19

def self.new namemax = 31, prefix = 'yarv_'
  limit = namemax - prefix.length
  if limit <= 0
    raise ArgumentError, "offered namespace too narrow"
  elsif 128.0 / limit > 36
    # Integer#to_s takes  radix of range up  to 36.  This limit  is due to
    # UUIDs to be safely represented in the namespace.
    raise ArgumentError, "offered namespace too narrow: at least 128bits are needed."
  else
    Class.new self do
      @namemax       = namemax
      @prefix        = prefix
      @limit         = limit
      @phasechange   = UUIDNS.to_s.length <= limit
      bpc            = 128.0 / limit
      radixf         = 2 ** bpc
      @radix         = radixf.ceil
      @desired2names = Hash.new
      @barenames     = Hash.new
      @topology      = Hash.new
      class << self
        alias new namegen
        private
        m = Class.instance_method :new
        define_method :old_new, m
      end
      self
    end
  end
end

.tsort_each_child(e) ⇒ Object

tsort’s travarsal enumerator



178
179
180
181
182
# File 'lib/cast_off/compile/namespace/namespace.rb', line 178

def tsort_each_child e
  e.each do |i|
    yield i
  end
end

.tsort_each_nodeObject

tsort’s key enumerator



171
172
173
174
175
# File 'lib/cast_off/compile/namespace/namespace.rb', line 171

def tsort_each_node
  each do |i|
    yield i
  end
end

Instance Method Details

#depends(obj) ⇒ Object



238
239
240
241
# File 'lib/cast_off/compile/namespace/namespace.rb', line 238

def depends obj
  @dependencies.push obj
  obj
end

#eachObject



232
233
234
235
236
# File 'lib/cast_off/compile/namespace/namespace.rb', line 232

def each
  @dependencies.each do |i|
    yield i
  end
end

#force_set_decl!(decl) ⇒ Object

dangerous. do not use this.



223
224
225
226
# File 'lib/cast_off/compile/namespace/namespace.rb', line 223

def force_set_decl! decl
  @declaration = decl
  @definition = nil
end

#to_sObject



228
229
230
# File 'lib/cast_off/compile/namespace/namespace.rb', line 228

def to_s
  @expression or @name
end