blob: ea3aa8033df44d3f3063a67b70d632819877e556 [file] [log] [blame]
class LocalSituation
attr_accessor :globals,:local
def initialize(globals)
@globals = globals
@local = nil
end
def package=(qualified)
if(@local)
raise QSyntaxError.new(<<ERROR_MSG)
You are redefining the package path.
Stuff might break if you do that.
Other options include: using another header file, and just using the same namespace.
If you are confident that you need this you can remove this check at
#{__FILE__}:#{__LINE__}.
Or file a feature request.
But that would be weird...
Wot. Wot.
ERROR_MSG
end
@local = @globals.space
qualified.names.each do |name|
@local = @local.get_make(name)
end
end
def register(value)
if(!@local)
raise QError.new(<<ERROR_MSG)
There is no package path defined, This is a big problem because
we are kindof expecting you to have a package path...
use a :
package my_super.cool.project;
statement to remedy this situation. (or file a feature request)
Wot. Wot.
ERROR_MSG
end
@local[value.name] = value
value.parent = @local if(value.respond_to?(:parent=))
value.loc = @local
end
def bind(bind_to)
return BoundSituation.new(self,bind_to)
end
end
class BoundSituation < LocalSituation
def initialize(locals,bind_to)
@globals = locals.globals
@local = bind_to
end
end
class NameSpace
attr_accessor :parent,:name
def initialize(name = nil,parent = nil)
@name = name
@parent = parent
@spaces = {}
end
def []=(key,val)
if(old_val = @spaces[key])
old_val = old_val.created_by if(old_val.respond_to?(:created_by) && old_val.created_by)
if(old_val.respond_to?(:q_stack_name))
old_val = old_val.q_stack_name
else
old_val = "eh, it is a #{old_val.class} thats all I know..."
end
raise QNamespaceCollision.new(<<ERROR_MSG)
Woah! The name #{queue_name(key).inspect} is already taken by some chap at #{old_val}.
\tFind somewhere else to peddle your wares.
\tWot. Wot.
ERROR_MSG
end
@spaces[key] = val
end
def to_cpp_id(name)
txt = @name + "::" + name
return @parent.to_cpp_id(txt) if(@parent && parent.name)
return "::" + txt
end
def queue_name(queue)
get_name() + "." + queue
end
def [](key)
#puts "getting #{get_name}.#{key}"
@spaces[key]
end
def get_make(name)
@spaces[name] ||= self.class.new(name,self)
end
def get_name()
if(@parent)
return "#{@parent.get_name}.#{@name}"
else
return "#{@name}"
end
end
def create(cpp_tree)
if(@parent && @parent.name)
parent = cpp_tree.get(@parent)
else
parent = cpp_tree
end
return cpp_tree.add_namespace(@name,parent)
end
def to_s()
"<NameSpace: #{get_name()}>"
end
def inspect()
"<NameSpace: #{get_name()}>"
end
def root()
return self if(@parent == nil)
return @parent.root
end
end
class Globals
attr_accessor :space
def initialize()
@space = NameSpace.new()
@space.get_make("aos")
@include_paths = []
end
def paths()
@include_paths
end
def add_path(path)
@include_paths << path
end
def find_file(filename)
@include_paths.each do |path_name|
new_path = File.expand_path(path_name) + "/" + filename
if(File.exists?(new_path))
return new_path
end
end
raise QImportNotFoundError.new(<<ERROR_MSG)
Problem Loading:#{filename.inspect} I looked in:
\t#{(@include_paths.collect {|name| name.inspect}).join("\n\t")}
\tbut alas, it was nowhere to be found.
\tIt is popular to include the top of the repository as the include path start,
\tand then reference off of that.
\tI would suggest doing that and then trying to build again.
\tWot. Wot.
ERROR_MSG
end
end
class QualifiedName
attr_accessor :names,:off_root
def initialize(names,off_root = false)
@names = names
@off_root = off_root
end
def test_lookup(namespace)
@names.each do |name|
return nil if(!namespace.respond_to?(:[]))
namespace = namespace[name]
return nil if(!namespace)
end
return namespace
end
def is_simple?()
return !@off_root && @names.length == 1
end
def to_simple()
return @names[-1]
end
def to_s()
if(@off_root)
return ".#{@names.join(".")}"
else
return @names.join(".")
end
end
def lookup(locals)
if(@off_root)
local = locals.globals.space
else
local = locals.local
end
target = nil
while(!target && local)
target = test_lookup(local)
local = local.parent
end
return target if(target)
if(@off_root)
raise QError.new(<<ERROR_MSG)
I was looking for .#{@names.join(".")}, but alas, it was not under
\tthe root namespace.
\tI'm really sorry old chap.
\tWot. Wot.
ERROR_MSG
else
raise QError.new(<<ERROR_MSG)
I was looking for #{@names.join(".")}, but alas, I could not find
\tit in #{locals.local.get_name} or any parent namespaces.
\tI'm really sorry old chap.
\tWot. Wot.
ERROR_MSG
end
end
def self.parse(tokens)
names = []
off_root = (tokens.peak == :tDot)
tokens.next if(off_root)
names << tokens.expect(:tWord).data
while(tokens.peak == :tDot)
tokens.next
names << tokens.expect(:tWord).data
end
return self.new(names,off_root)
end
end