# absym.icn: Abbreviation table entry object for abtab.icn (q.v.) #-- $define AB_SYM_REVISION "$Revision: 1.2 $" $define AB_SYM_DATE "$Date: 1996/08/26 23:29:27 $" #================================================================ # Class AbSym: Each instance represents one abbreviation and # its current binding, if any. # An AbTab is basically a symbol table, and we have to deal # with the `forward reference' problem, that is, the case where # we may encounter a reference to a symbol before that symbol # has been defined. When we do, we create an AbSym with no # binding. # Later, when we encounter the definition of that symbol, # we attach a binding (in the form of an AbBind object) that # describes its definition. # Normally, each symbol should have exactly one binding. # If there is no binding for a symbol after we've read all # the input files, that's an error---a symbol was referred to # but never defined. # Also, in MOST cases, if we try to attach a binding to # a symbol that already has one, that's an error too: the # symbol is multiply defined. # However, there is a particular problem with clusters of names # that all abbreviate to the same code (e.g., Blackburnian # Warbler and Blackpoll Warbler would both be BLAWAR by the # rules). There is a special type of binding called a CollBind # that tracks these collisions. In this one case, if the # symbol has an existing CollBind binding and we are trying # to attach a new CollBind binding, rather than reporting a # multiple definition, we COMBINE the two CollBind bindings into # one new CollBind binding that includes all the disambiguations # (substitute, non-colliding abbreviations) in both bindings. # See the AbBind object for more details of the process of # combining bindings. #---------------------------------------------------------------- # EXPORTED METHODS #---------------------------------------------------------------- # Ab_Sym_New ( abbr ) # [ if abbr is an Abbr -> # returns a new AbSym object for abbreviation=(abbr), and # no binding # ] #-- # Ab_Sym_Abbr ( self ) # [ return the Abbr associated with self # ] #-- # Ab_Sym_Binding ( self ) # [ if self has no binding -> fail # | else -> # return self's current binding as an AbBind object # ] #-- # Ab_Sym_Bind ( self, abBind ) # [ if abBind is an AbBind object -> # if self has no binding -> # self := self with binding abBind # return &null # else if abBind can be combined with the existing binding # of self -> # self := self with its binding combined with abBind # return &null # else -> fail # ] #---------------------------------------------------------------- # STATE #---------------------------------------------------------------- record abSymTag ( abbr, # The abbreviation for which self describes the binding binding ) # An AbBind object, or &null #---------------------------------------------------------------- # INVARIANTS #---------------------------------------------------------------- # .abbr == an Abbr object # .binding == # if self has no binding -> &null # else -> the AbBind object describing its current binding state #---------------------------------------------------------------- # - - - A b _ S y m _ N e w - - - #-- 1996-08-19: Verified with Stavely procedure Ab_Sym_New ( abbr ) local self self := abSymTag ( ); self.abbr := abbr; return self; end # - - - A b _ S y m _ A b b r - - - #-- 1996-08-19: Verified with Stavely procedure Ab_Sym_Abbr ( self ) return self.abbr; end # - - - A b _ S y m _ B i n d i n g - - - #-- 1996-08-19: Verified with Stavely procedure Ab_Sym_Binding ( self ) return \ self.binding; end # - - - A b _ S y m _ B i n d - - - #-- 1996-08-19: Verified with Stavely procedure Ab_Sym_Bind ( self, abBind ) local combo # The combination of abBind and self.binding, if valid #-- 1 -- #-[ if self has no binding -> # self := self with abBind bound # return &null #-] if / self.binding then { self.binding := abBind; return; } #-- 2 -- #-[ if self's existing binding combines with abBind -> # combo := the combination of those two bindings # | else -> fail #-] if not ( combo := Ab_Bind_Combine ( self.binding, abBind ) ) then fail; #-- 3 -- #-[ self := self with combo as its binding # return &null #-] self.binding := combo; return; end # --- Ab_Sym_Bind ---