159 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Rexx
		
	
	
	
	
	
			
		
		
	
	
			159 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Rexx
		
	
	
	
	
	
#!/usr/bin/env rexx
 | 
						|
/** 
 | 
						|
 * The prolog code performs some simple tests for the different possibilities
 | 
						|
 * to create an Enumeration
 | 
						|
 *
 | 
						|
 *  a.  Only symbols as key/index, where the ascending integer values/items will
 | 
						|
 *      be done by the Enumeration  creation, starting at zero.
 | 
						|
 *
 | 
						|
 *  b.  Combination of keys with values, where the key/ndex can be an OORexx 
 | 
						|
 *      string and the values/items can be any OORexx object, inclusive numbers. 
 | 
						|
 *
 | 
						|
 *  c.  An array containing 2-item arrays where the 2-item arrays contain
 | 
						|
 *      the possible combination of the b. case, i.e array index 1 is a String,
 | 
						|
 *      array index 2 can be anything.
 | 
						|
 *  
 | 
						|
 **/
 | 
						|
level = .Enumeration~of(LOW,MEDIUM,HIGH,LEVELS)
 | 
						|
say '----  Automatic sequencing from 0 -----'
 | 
						|
say low '=' level[low]
 | 
						|
say 'There are' level['LEVELS'] 'levels'
 | 
						|
say medium '=' level[medium]
 | 
						|
say '----- Bitlevels -----'
 | 
						|
options = .Enumeration~of((BOLD,1),(ITALIC,2),(UNDERSCORE,4))
 | 
						|
say bold'+'italic '=' options[bold]+options[italic]
 | 
						|
say '----- Strings -----'
 | 
						|
colours = .Enumeration~of((RED,'800000'),(GREEN, '008000'),(BLUE,'000080'))
 | 
						|
say blue '=' colours[blue]
 | 
						|
say red '=' colours~red
 | 
						|
say '----- Objects -----'
 | 
						|
objects = .Enumeration~of((OBJ1, .object~new), (OBJ2, .array~new), ('obj3', .table~new))
 | 
						|
--say 'enum type =' objects~type
 | 
						|
say obj2 'is a' objects['oBj2']~class~id 'instance'
 | 
						|
say obj3 'is an instance of' objects~obj3 'class'
 | 
						|
say '----- 2-item Array -----'
 | 
						|
fonts = .array~of((ULTRALIGHT,100),(LIGHT,200),(MEDIUM, 500),(HEAVY,800), (ULTRAHEAVY,1000))
 | 
						|
font = .Enumeration~of(fonts)
 | 
						|
say 'The font''s MEDIUM weight is:' font~medium 
 | 
						|
 | 
						|
exit
 | 
						|
 | 
						|
::OPTIONS NOPROLOG
 | 
						|
 | 
						|
/**
 | 
						|
 *  Class: Enumeration
 | 
						|
 *
 | 
						|
 *  An OORexx implementation of the well known ENUM's in other languages like C(++),C#,
 | 
						|
 *  Java etc..
 | 
						|
 *
 | 
						|
 *  ENUMs are normally compile time defined and unmutable and function as symbols
 | 
						|
 *  for constant values. For simple cases those values are ascending integers
 | 
						|
 *  starting at 0, that don't need to be specified.
 | 
						|
 *  For more complex situations both the key (in OORex terms: index) and the value
 | 
						|
 *  (in OORexx: items) are provided as a 2-item array in the argument array.
 | 
						|
 *
 | 
						|
 *  One could think of this as a dynamic inplementation if the ::CONSTANT 
 | 
						|
 *  directive, as it seems there is no provision for that in the built-in classes
 | 
						|
 *
 | 
						|
 *  @version  0.8    
 | 
						|
 *
 | 
						|
 *  @author   Ruurd Idenburg (ruurd@idenburg.net)
 | 
						|
 *  
 | 
						|
 *  2024-10-27 Changed '~class~id' to 'isA'
 | 
						|
 *
 | 
						|
 **/
 | 
						|
::CLASS Enumeration PUBLIC
 | 
						|
 | 
						|
::METHOD of PUBLIC CLASS
 | 
						|
-- get the enum arguments as an array
 | 
						|
  if arg(1)~isA(.String)
 | 
						|
-- case a. above 
 | 
						|
    then do
 | 
						|
      args = arg(1,'A')
 | 
						|
-- creation will generate the ascending integer sequence
 | 
						|
      simple = .true
 | 
						|
    end
 | 
						|
    else do 
 | 
						|
      if arg(1)~isA(.Array) & arg(1)[1]~isA(.Array) then do
 | 
						|
-- case c. above
 | 
						|
        args = arg(1)
 | 
						|
      end
 | 
						|
      else do
 | 
						|
-- case b. above
 | 
						|
        args = arg(1,'A')
 | 
						|
      end
 | 
						|
-- creation does not need the provide the values
 | 
						|
      simple = .false
 | 
						|
    end
 | 
						|
-- create the supporting table, caseless, as keys/indexes should be
 | 
						|
-- unique and case differences would make it error prone   
 | 
						|
  table = .caselessStringTable~new
 | 
						|
-- create an instance of this class
 | 
						|
  me = self~new
 | 
						|
-- give access to the table for the instance
 | 
						|
  me~enum = table
 | 
						|
-- preset the simpleness (one or two things per argument)
 | 
						|
--  simple = .false
 | 
						|
-- do we have a 2-item array per argument
 | 
						|
--  if args[1]~class~id='String' then simple=.true
 | 
						|
  loop arg=1 to args~last
 | 
						|
-- if sparse item iterate the loop
 | 
						|
  if \args~hasIndex(arg) then iterate
 | 
						|
  if simple then do
 | 
						|
-- get key, set index of the key minus 1 as value
 | 
						|
      key = args[arg]
 | 
						|
      value = args~index(key)-1
 | 
						|
    end
 | 
						|
-- get key and value from the argument array
 | 
						|
    else do
 | 
						|
      key = args[arg][1]
 | 
						|
      value = args[arg][2]
 | 
						|
    end
 | 
						|
-- and store the map member  
 | 
						|
    table[key]= value
 | 
						|
  end
 | 
						|
return me
 | 
						|
 | 
						|
::ATTRIBUTE enum PRIVATE
 | 
						|
 | 
						|
::METHOD '[]'
 | 
						|
  use strict arg key
 | 
						|
return self~enum[key]
 | 
						|
 | 
						|
/**
 | 
						|
 * The next 3 methods forward the message to the embedded
 | 
						|
 * caselessStringtable, that will return it's result'
 | 
						|
 **/
 | 
						|
::METHOD items
 | 
						|
return self~enum~items
 | 
						|
 | 
						|
::METHOD allindexes
 | 
						|
return self~enum~allindexes
 | 
						|
 | 
						|
::METHOD allitems
 | 
						|
return self~enum~allitems
 | 
						|
 | 
						|
/**
 | 
						|
 * Method: unknown
 | 
						|
 *
 | 
						|
 * Allows to use the enum symbol to be used as a message
 | 
						|
 *
 | 
						|
 * @param string - the method name of the message
 | 
						|
 *
 | 
						|
 * @param array - an array with the original arguments
 | 
						|
 *
 | 
						|
 * @returns result  - the result of the forwarded method
 | 
						|
 *                    if valid method for the enum otherwise
 | 
						|
 *                    raises a syntax error.
 | 
						|
 **/
 | 
						|
::METHOD unknown PRIVATE
 | 
						|
  use strict arg methodName, rest
 | 
						|
-- Make sure there is an index with the methodName
 | 
						|
  if self~enum~hasIndex(methodName) 
 | 
						|
    then return self~enum[methodName~upper]
 | 
						|
-- if not raise a syntax error
 | 
						|
    else raise syntax 97.001 array(self,methodName)
 | 
						|
exit  
 | 
						|
 | 
						|
::REQUIRES 'caselessStringTable.cls'
 |