# Author:: Eric Crane (mailto:eric.crane@mac.com) # Copyright:: Copyright (c) 2019 Eric Crane. All rights reserved. # # An object path name. # Path and name elements are separated by periods. # module GlooLang module Core class Pn < Baseo ROOT = 'root'.freeze IT = 'it'.freeze ERROR = 'error'.freeze CONTEXT = '@'.freeze attr_reader :src, :elements # # Set up the object given a source string, # ie: the full path and name. # def initialize( engine, src ) @engine = engine set_to src end # # Reference to the root object path. # def self.root( engine ) return Pn.new( engine, ROOT ) end # # Reference to it. # def self.it( engine ) return Pn.new( engine, IT ) end # # Reference to the error message. # def self.error( engine ) return Pn.new( engine, ERROR ) end # # Does the pathname reference refer to the root? # def root? return @src.downcase == ROOT end # # Does the pathname reference refer to it? # def it? return @src.downcase == IT end # # Does the pathname reference refer to error? # def error? return @src.downcase == ERROR end # # Does the pathname reference refer to the gloo system object? # def gloo_sys? return false unless @elements&.count&.positive? o = @elements.first.downcase return true if o == GlooLang::Core::GlooSystem.typename return true if o == GlooLang::Core::GlooSystem.short_typename return false end # # Get the string representation of the pathname. # def to_s return @src end # # Set the object pathname to the given value. # def set_to( value ) @src = value.nil? ? nil : value.strip @elements = @src.nil? ? [] : @src.split( '.' ) end # # Convert the raw string to a list of segments. # def segments return @elements end # # Get the name element. # def name return '' unless self.named? return @elements.last end # # Does the value include path elements? # def named? return @elements.count.positive? end # # Does the value include a name? # def includes_path? return @elements.count > 1 end # # Does the path start with the context? # def includes_context? return @src.start_with?( "#{CONTEXT}." ) end # # Expand the context so we have the full path. # def expand_context # return unless @engine.heap.context self.set_to( "#{@engine.heap.context}#{@src[1..-1]}" ) end # # Get the parent that contains the object referenced. # def get_parent o = @engine.heap.root if self.includes_path? @elements[ 0..-2 ].each do |e| o = o.find_child( e ) if o.nil? @engine.log.error "Object '#{e}' was not found." return nil end end end return o end # # Does the object at the path exist? # def exists? return true if self.root? return true if self.it? return true if self.error? parent = self.get_parent return false unless parent return parent.contains_child? name end # # Is the reference to a color? # def named_color? colors = %w[red blue green white black yellow] return true if colors.include?( @src.downcase ) end # # Resolve the pathname reference. # Find the object referenced or return nil if it is not found. # def resolve return @engine.heap.root if self.root? return @engine.heap.it if self.it? return @engine.heap.error if self.error? return GlooLang::Core::GlooSystem.new( @engine, self ) if self.gloo_sys? if Here.includes_here_ref?( @elements ) Here.expand_here( @engine, self ) end if self.includes_context? expand_context end parent = self.get_parent return nil unless parent obj = parent.find_child( self.name ) return GlooLang::Objs::Alias.resolve_alias( @engine, obj, self.src ) end end end end