1: #!/usr/bin/env rexx
2: /* ---------------------------------------------------------------- */
3: /* Number class, a subclass of the String class */
4: /* Values can be any valid number. */
5: /* */
6: /* All arithmetic methods need to be defined here, because */
7: /* the result of the operation should be another object of */
8: /* the Number class, and the result of the String class operators */
9: /* always is a String class object. */
10: /* */
11: /* Note that subclasses of the Number class will yield results */
12: /* that belong to that particular receiver subclass. */
13: /* */
14: /* NOTE: Requieres oorexx 4.0 or later */
15: /* ---------------------------------------------------------------- */
16: /* */
17: /* Originally by Ruurd J. Idenburg */
18: /* */
19: /* No copyright, no licence, no guarantees or warrantees, be it */
20: /* explicit, implicit or whatever. Usage is totally and completely */
21: /* at the users own risk, the author shall not be liable for any */
22: /* damages whatsoever, for any reason whatsoever. */
23: /* */
24: /* Please keep this comment block intact when modifying this code */
25: /* and add a note with date and a description. */
26: /* */
27: /* ---------------------------------------------------------------- */
28: /* 2020/03/05 - Initial version approximately (RJI) */
29: /* 2022/02/14 - Support prefix + and - using forward to super (RJI) */
30: /* 2022/02/15 - 'UNKNOWN method to handle all .number methods (RJI) */
31: /* ---------------------------------------------------------------- */
32:
33: ::class number public subclass string
34:
35: ::attribute methods class private
36: ::attribute calculationResult private
37:
38: ::method activate class
39: -- all (hopefully) String methods that should result in .number instance
40: self~methods = ('+','-','/','*','%','//','**', -
41: abs,ceiling,floor,format,max,min,modulo,round,trunc)
42: -- remove them from method lookup chain, setting method objects to .nil
43: unknownMethods = .StringTable~new
44: do method over self~methods
45: unknownMethods[method] = .nil
46: end
47: -- make the methods unavailable so we can trap them in our UNKNOWN method
48: self~defineMethods(unknownMethods)
49:
50: ::method init
51: self~init:super
52: if (self)~datatype\='NUM' then do -- if self is not a number
53: raise syntax 93.904 array(1,self) -- then raise an error and quit
54: end
55:
56: ::method unknown
57: use arg method, args
58: -- if not a .String instance method return the nil object (.nil)
59: if ''~instanceMethod(method)~isNil then return .nil
60: -- pass the method and arguments to the superclass and wait for the result
61: forward class(super) message (method) arguments (args) continue
62: -- keep the result
63: self~calculationResult = result
64: -- if not an arithmetic operator/method return the result .String object
65: if \self~class~methods~allItems~hasItem(method) then do
66: return self~calculationResult
67: end
68: -- create an new .number instance as the result of the arithmetic operation
69: return self~class~new(self~calculationResult)
70: