diff options
Diffstat (limited to 'ipl/packs/idol/builtins.iol')
-rw-r--r-- | ipl/packs/idol/builtins.iol | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/ipl/packs/idol/builtins.iol b/ipl/packs/idol/builtins.iol new file mode 100644 index 0000000..36403da --- /dev/null +++ b/ipl/packs/idol/builtins.iol @@ -0,0 +1,170 @@ +# %W% %G% +# +# Builtin Icon objects, roughly corresponding to the language builtins. +# (These are not builtin to the Idol interpreter!) +# +# Taxonomy of builtin types: +# +# __Object___ +# _-' `-_ +# _-' `-_ +# Collection Atom_ +# / | \ _' `-. +# Stack Queue Vector _-' Number +# \ / / | \ _-' / \ +# Deque / | \ _' Integer Real +# \ / | \ / +# List Table String +# +# + +# +# this is the Smalltalk-style ideal root of an inheritance hierarchy. +# add your favorite methods here. +# +class Object() + # return the class name as a string + method class() + return image(self)[8:find("_",image(self))] + end + # generate the field names as strings + method fieldnames() + i := 1 + every s := name(!(self.__state)) do { + if i>2 then s ? { tab(find(".")+1); suspend tab(0) } + i +:= 1 + } + end + # generate the method names as strings + method methodnames() + every s := name(!(self.__methods)) do { + s ? { tab(find(".")+1); suspend tab(0) } + } + end +end + +# Collections support Icon's *?! operators +class Collection : Object (theCollection) + method size() + return *self.theCollection + end + method foreach() + suspend !self.theCollection + end + method random() + return ?self.theCollection + end +end + +# Vectors have the ability to access individual elements +class Vector : Collection() + method getElement(i) + return self.theCollection[i] + end + method setElement(i,v) + return self.theCollection[i] := v + end +end + +class Table : Vector(initialvalue,theCollection) +initially + self.theCollection := table(self.initialvalue) +end + +# +# The field theCollection is explicitly named so that subclasses of Stack +# and Queue use these automatic initializations. The / operator is used +# to reduce the number of throw-away list allocations for subclasses which +# >don't< inherit theCollection from Stack or Queue (e.g. class List). +# It also allows initialization by constructor. If one wanted to +# guarantee that all Stacks start out empty but still allow class List +# to be explicitly intitialized, one could remove the / here, and name +# theCollection in class List, causing its initially section to override +# the superclass with respect to the field theCollection. I choose here +# to maximize code sharing rather than protecting my Stack class. +# +# When allowing initialization by constructor one might consider +# checking the type of the input to guarantee it conforms to the +# type expected by the class. +# +class Stack : Collection(theCollection) + method push(value) + push(self.theCollection,value) + end + method pop() + return pop(self.theCollection) + end +initially + /self.theCollection := [] +end + +class Queue : Collection(theCollection) + method get() + return get(self.theCollection) + end + method put(value) + put(self.theCollection,value) + end +initially + /self.theCollection := [] +end + +# Deques are a first example of multiple inheritance. +class Deque : Queue : Stack() +end + +# +# List inherits Queue's theCollection initialization, because Queue is the +# first class on List's (transitively closed) superclass list to name +# theCollection explicitly +# +class List : Deque : Vector() + method concat(l) + return List(self.theCollection ||| l) + end +end + +class Atom : Object(public val) + method asString() + return string(self.val) + end + method asInteger() + return integer(self.val) + end + method asReal() + return real(self.val) + end +end + +class Number : Atom () + method plus(n) + return self.val + n$val() + end + method minus(n) + return self.val - n$val() + end + method times(n) + return self.val * n$val() + end + method divide(n) + return self.val / n$val() + end +end + +class Integer : Number() +initially + if not (self.val := integer(self.val)) then + stop("can't make Integer from ",image(self.val)) +end + +class Real : Number() +initially + if not (self.val := real(self.val)) then + stop("can't make Real from ",image(self.val)) +end + +class String : Vector : Atom() + method concat(s) + return self.theCollection || s + end +end |