2017-01-06 09:53:40 +00:00
|
|
|
class Apex(nil)
|
2017-04-25 15:20:58 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-05-07 16:45:27 +00:00
|
|
|
class(#limited) Error(Apex)
|
2017-04-25 15:20:58 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
pooldic Error.Code
|
|
|
|
{
|
|
|
|
ENOERR := error(0).
|
|
|
|
EGENERIC := error(1).
|
|
|
|
ENOIMPL := error(2).
|
|
|
|
ESYSERR := error(3).
|
|
|
|
EINTERN := error(4).
|
|
|
|
ESYSMEM := error(5).
|
|
|
|
EOOMEM := error(6).
|
|
|
|
EINVAL := error(7).
|
|
|
|
ENOENT := error(8).
|
|
|
|
EPERM := error(12).
|
|
|
|
ERANGE := error(20).
|
|
|
|
(* add more items... *)
|
|
|
|
}
|
|
|
|
|
|
|
|
(*pooldic Error.Code2
|
|
|
|
{
|
|
|
|
>> CAN I SUPPORT this kind of redefnition? as of now, it's not accepted because
|
|
|
|
>> Error.Code2.EGENERIC is not a literal. Should i treate pooldic members as a constant
|
|
|
|
>> and treat it as if it's a literal like? then even if the defined value changes,
|
|
|
|
>> the definition here won't see the change... what is the best way to tackle this issue?
|
|
|
|
|
|
|
|
EGENERIC := Error.Code2.EGENERIC.
|
|
|
|
}*)
|
|
|
|
|
|
|
|
extend Apex
|
2015-10-08 14:26:04 +00:00
|
|
|
{
|
|
|
|
## -------------------------------------------------------
|
|
|
|
## -------------------------------------------------------
|
2017-05-07 16:45:27 +00:00
|
|
|
method(#dual) dump
|
2015-10-08 14:26:04 +00:00
|
|
|
{
|
2015-10-15 14:40:08 +00:00
|
|
|
<primitive: #_dump>
|
2015-10-08 14:26:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
## -------------------------------------------------------
|
|
|
|
## -------------------------------------------------------
|
2017-05-08 16:00:55 +00:00
|
|
|
method(#dual) yourself { ^self }
|
2015-10-08 14:26:04 +00:00
|
|
|
|
|
|
|
## -------------------------------------------------------
|
2017-04-26 15:31:07 +00:00
|
|
|
## INSTANTIATION & INITIALIZATION
|
2015-10-08 14:26:04 +00:00
|
|
|
## -------------------------------------------------------
|
2017-05-08 16:00:55 +00:00
|
|
|
method(#class,#primitive,#lenient) _basicNew.
|
|
|
|
method(#class,#primitive,#lenient) _basicNew: size.
|
2017-05-07 16:45:27 +00:00
|
|
|
|
2017-05-08 16:00:55 +00:00
|
|
|
method(#class,#primitive) basicNew.
|
|
|
|
method(#class,#primitive) basicNew: size.
|
2017-05-09 15:48:44 +00:00
|
|
|
(* the following definition is almost equivalent to the simpler definition
|
|
|
|
* method(#class,#primitive) basicNew: size.
|
|
|
|
* found above.
|
|
|
|
* in the following defintion, the primitiveFailed method is executed
|
|
|
|
* from the basicNew: context. but in the simpler definition, it is executed
|
|
|
|
* in the context of the caller of the basicNew:. the context of the basicNew:
|
|
|
|
* method is not even created
|
2017-02-14 08:29:30 +00:00
|
|
|
method(#class) basicNew: size
|
2015-10-08 14:26:04 +00:00
|
|
|
{
|
2017-05-08 16:00:55 +00:00
|
|
|
<primitive: #Apex__basicNew:>
|
2017-05-09 15:48:44 +00:00
|
|
|
self primitiveFailed(thisContext method)
|
2017-05-08 16:00:55 +00:00
|
|
|
}*)
|
2015-12-27 18:02:59 +00:00
|
|
|
|
2017-01-06 09:53:40 +00:00
|
|
|
method(#class) new
|
2015-10-15 14:40:08 +00:00
|
|
|
{
|
|
|
|
| x |
|
|
|
|
x := self basicNew.
|
2017-05-08 16:00:55 +00:00
|
|
|
x initialize. ## TODO: assess if it's good to call 'initialize' from new
|
2015-10-15 14:40:08 +00:00
|
|
|
^x.
|
|
|
|
}
|
|
|
|
|
2017-01-06 09:53:40 +00:00
|
|
|
method(#class) new: anInteger
|
2015-10-15 14:40:08 +00:00
|
|
|
{
|
|
|
|
| x |
|
|
|
|
x := self basicNew: anInteger.
|
2017-05-08 16:00:55 +00:00
|
|
|
x initialize. ## TODO: assess if it's good to call 'initialize' from new.
|
2015-10-15 14:40:08 +00:00
|
|
|
^x.
|
|
|
|
}
|
|
|
|
|
2017-01-06 09:53:40 +00:00
|
|
|
method initialize
|
2015-10-15 14:40:08 +00:00
|
|
|
{
|
2017-05-08 16:00:55 +00:00
|
|
|
(* a subclass may override this method *)
|
2015-10-15 14:40:08 +00:00
|
|
|
^self.
|
|
|
|
}
|
|
|
|
|
2015-10-30 15:36:37 +00:00
|
|
|
## -------------------------------------------------------
|
|
|
|
## -------------------------------------------------------
|
2017-05-16 02:04:18 +00:00
|
|
|
##method(#dual,#primitive,#lenient) _shallowCopy.
|
|
|
|
##method(#dual,#primitive) shallowCopy.
|
2017-05-08 16:00:55 +00:00
|
|
|
|
|
|
|
method(#dual) shallowCopy
|
2015-10-30 15:36:37 +00:00
|
|
|
{
|
|
|
|
<primitive: #_shallow_copy>
|
2017-05-16 02:04:18 +00:00
|
|
|
self primitiveFailed(thisContext method).
|
2015-10-30 15:36:37 +00:00
|
|
|
}
|
|
|
|
|
2017-05-08 16:00:55 +00:00
|
|
|
|
2015-10-08 14:26:04 +00:00
|
|
|
## -------------------------------------------------------
|
|
|
|
## -------------------------------------------------------
|
2017-05-08 16:00:55 +00:00
|
|
|
method(#dual,#primitive,#lenient) _basicSize.
|
|
|
|
method(#dual,#primitive) basicSize.
|
2015-10-08 14:26:04 +00:00
|
|
|
|
2017-04-26 03:09:55 +00:00
|
|
|
method(#dual) basicAt: index
|
2015-10-08 14:26:04 +00:00
|
|
|
{
|
2017-04-25 15:20:58 +00:00
|
|
|
| perr |
|
|
|
|
|
2015-10-15 14:40:08 +00:00
|
|
|
<primitive: #_basic_at>
|
2017-04-25 15:20:58 +00:00
|
|
|
|
|
|
|
## TODO: create a common method that translate a primitive error to some standard exceptions of primitive failure.
|
|
|
|
perr := thisProcess primError.
|
|
|
|
if (perr == Error.Code.ERANGE) { self index: index outOfRange: (self basicSize) }
|
|
|
|
elsif (perr == Error.Code.EPERM) { self messageProhibited: #basicAt }
|
|
|
|
else { self primitiveFailed }
|
2015-10-08 14:26:04 +00:00
|
|
|
}
|
|
|
|
|
2017-04-26 03:09:55 +00:00
|
|
|
method(#dual) basicAt: index put: anObject
|
2015-10-08 14:26:04 +00:00
|
|
|
{
|
2017-04-25 15:20:58 +00:00
|
|
|
| perr |
|
|
|
|
|
2015-10-15 14:40:08 +00:00
|
|
|
<primitive: #_basic_at_put>
|
2017-04-25 15:20:58 +00:00
|
|
|
|
|
|
|
perr := thisProcess primError.
|
|
|
|
if (perr == Error.Code.ERANGE) { self index: index outOfRange: (self basicSize) }
|
|
|
|
elsif (perr == Error.Code.EPERM) { self messageProhibited: #basicAt:put: }
|
|
|
|
else { self primitiveFailed }
|
2015-10-08 14:26:04 +00:00
|
|
|
}
|
|
|
|
|
2017-07-20 16:33:53 +00:00
|
|
|
(* ------------------------------------------------------------------
|
|
|
|
* FINALIZATION SUPPORT
|
|
|
|
* ------------------------------------------------------------------ *)
|
|
|
|
method(#dual,#primitive) addToBeFinalized.
|
|
|
|
##method(#dual,#primitive) removeToBeFinalized.
|
|
|
|
|
2017-01-06 09:53:40 +00:00
|
|
|
(* ------------------------------------------------------------------
|
|
|
|
* HASHING
|
|
|
|
* ------------------------------------------------------------------ *)
|
2017-04-26 15:31:07 +00:00
|
|
|
method(#dual) hash
|
2017-01-05 10:16:04 +00:00
|
|
|
{
|
|
|
|
<primitive: #_hash>
|
|
|
|
self subclassResponsibility: #hash
|
2015-10-08 14:26:04 +00:00
|
|
|
}
|
|
|
|
|
2017-01-06 09:53:40 +00:00
|
|
|
(* ------------------------------------------------------------------
|
|
|
|
* IDENTITY TEST
|
|
|
|
* ------------------------------------------------------------------ *)
|
2015-10-08 14:26:04 +00:00
|
|
|
|
2017-04-26 15:31:07 +00:00
|
|
|
method(#dual) == anObject
|
2015-10-08 14:26:04 +00:00
|
|
|
{
|
2016-12-28 13:42:12 +00:00
|
|
|
(* check if the receiver is identical to anObject.
|
|
|
|
* this doesn't compare the contents *)
|
2015-10-15 14:40:08 +00:00
|
|
|
<primitive: #_identical>
|
2017-01-06 09:53:40 +00:00
|
|
|
self primitiveFailed.
|
2015-10-08 14:26:04 +00:00
|
|
|
}
|
|
|
|
|
2017-04-26 15:31:07 +00:00
|
|
|
method(#dual) ~~ anObject
|
2015-10-08 14:26:04 +00:00
|
|
|
{
|
2015-10-15 14:40:08 +00:00
|
|
|
<primitive: #_not_identical>
|
2015-10-08 14:26:04 +00:00
|
|
|
^(self == anObject) not.
|
|
|
|
}
|
|
|
|
|
2017-01-06 09:53:40 +00:00
|
|
|
(* ------------------------------------------------------------------
|
|
|
|
* EQUALITY TEST
|
|
|
|
* ------------------------------------------------------------------ *)
|
2017-04-26 15:31:07 +00:00
|
|
|
method(#dual) = anObject
|
2017-01-06 09:53:40 +00:00
|
|
|
{
|
|
|
|
<primitive: #_equal>
|
|
|
|
self subclassResponsibility: #=
|
|
|
|
}
|
|
|
|
|
2017-04-26 15:31:07 +00:00
|
|
|
method(#dual) ~= anObject
|
2017-01-06 09:53:40 +00:00
|
|
|
{
|
|
|
|
<primitive: #_not_equal>
|
|
|
|
^(self = anObject) not.
|
|
|
|
}
|
2016-11-18 18:11:13 +00:00
|
|
|
|
2017-04-26 15:31:07 +00:00
|
|
|
|
2017-01-06 09:53:40 +00:00
|
|
|
(* ------------------------------------------------------------------
|
|
|
|
* COMMON QUERIES
|
|
|
|
* ------------------------------------------------------------------ *)
|
2016-11-18 18:11:13 +00:00
|
|
|
|
2017-05-08 16:00:55 +00:00
|
|
|
method(#dual,#primitive) class.
|
|
|
|
|
2017-04-26 15:31:07 +00:00
|
|
|
method(#dual) isNil
|
2015-10-08 14:26:04 +00:00
|
|
|
{
|
2017-11-24 17:40:20 +00:00
|
|
|
## ^self == nil.
|
2015-10-08 14:26:04 +00:00
|
|
|
^false
|
|
|
|
}
|
|
|
|
|
2017-04-26 15:31:07 +00:00
|
|
|
method(#dual) notNil
|
2015-10-08 14:26:04 +00:00
|
|
|
{
|
2017-11-24 17:40:20 +00:00
|
|
|
## ^(self == nil) not
|
|
|
|
## ^self ~= nil.
|
2015-10-08 14:26:04 +00:00
|
|
|
^true.
|
|
|
|
}
|
|
|
|
|
2017-04-26 15:31:07 +00:00
|
|
|
method(#dual) isError
|
2015-10-08 14:26:04 +00:00
|
|
|
{
|
|
|
|
^false
|
|
|
|
}
|
|
|
|
|
2017-04-26 15:31:07 +00:00
|
|
|
method(#dual) notError
|
2017-01-09 09:11:36 +00:00
|
|
|
{
|
|
|
|
^true
|
|
|
|
}
|
|
|
|
|
2016-05-07 01:37:44 +00:00
|
|
|
## -------------------------------------------------------
|
|
|
|
## -------------------------------------------------------
|
|
|
|
|
2017-01-06 09:53:40 +00:00
|
|
|
method(#class) inheritsFrom: aClass
|
2016-05-07 01:37:44 +00:00
|
|
|
{
|
|
|
|
| c |
|
|
|
|
c := self superclass.
|
2017-09-29 15:03:54 +00:00
|
|
|
(* [c notNil] whileTrue: [
|
2016-05-07 01:37:44 +00:00
|
|
|
[ c == aClass ] ifTrue: [^true].
|
|
|
|
c := c superclass.
|
2017-09-29 15:03:54 +00:00
|
|
|
]. *)
|
|
|
|
while (c notNil)
|
|
|
|
{
|
|
|
|
if (c == aClass) { ^true }.
|
|
|
|
c := c superclass.
|
|
|
|
}.
|
2016-05-07 01:37:44 +00:00
|
|
|
^false
|
|
|
|
}
|
|
|
|
|
2017-01-06 09:53:40 +00:00
|
|
|
method(#class) isMemberOf: aClass
|
2016-05-07 01:37:44 +00:00
|
|
|
{
|
2016-12-28 13:42:12 +00:00
|
|
|
(* a class object is an instance of Class
|
|
|
|
* but Class inherits from Apex. On the other hand,
|
|
|
|
* most of ordinary classes are under Object again under Apex.
|
|
|
|
* special consideration is required here. *)
|
2016-05-07 01:37:44 +00:00
|
|
|
^aClass == Class
|
|
|
|
}
|
|
|
|
|
2017-01-06 09:53:40 +00:00
|
|
|
method isMemberOf: aClass
|
2016-05-07 01:37:44 +00:00
|
|
|
{
|
|
|
|
^self class == aClass
|
|
|
|
}
|
|
|
|
|
2017-09-30 04:53:00 +00:00
|
|
|
method(#dual) isKindOf: aClass
|
2016-05-07 01:37:44 +00:00
|
|
|
{
|
2017-09-29 15:03:54 +00:00
|
|
|
<primitive: #_is_kind_of>
|
2016-05-07 01:37:44 +00:00
|
|
|
^(self isMemberOf: aClass) or: [self class inheritsFrom: aClass].
|
|
|
|
}
|
|
|
|
|
2017-03-19 14:18:37 +00:00
|
|
|
## -------------------------------------------------------
|
|
|
|
## -------------------------------------------------------
|
|
|
|
|
2017-04-26 15:31:07 +00:00
|
|
|
method(#dual) respondsTo: selector
|
2015-10-08 14:26:04 +00:00
|
|
|
{
|
2017-03-19 14:18:37 +00:00
|
|
|
<primitive: #_responds_to>
|
|
|
|
self primitiveFailed
|
2015-10-08 14:26:04 +00:00
|
|
|
}
|
|
|
|
|
2017-03-19 14:18:37 +00:00
|
|
|
## -------------------------------------------------------
|
|
|
|
## -------------------------------------------------------
|
|
|
|
|
2017-04-26 15:31:07 +00:00
|
|
|
method(#dual,#variadic) perform(selector)
|
2017-03-19 14:18:37 +00:00
|
|
|
{
|
|
|
|
<primitive: #_perform>
|
|
|
|
self primitiveFailed
|
|
|
|
}
|
2017-04-01 04:58:02 +00:00
|
|
|
|
2017-04-26 15:31:07 +00:00
|
|
|
method(#dual) perform: selector
|
2017-03-19 14:18:37 +00:00
|
|
|
{
|
|
|
|
<primitive: #_perform>
|
|
|
|
self primitiveFailed
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-04-26 15:31:07 +00:00
|
|
|
method(#dual) perform: selector with: arg1
|
2017-03-19 14:18:37 +00:00
|
|
|
{
|
|
|
|
<primitive: #_perform>
|
|
|
|
self primitiveFailed
|
|
|
|
}
|
|
|
|
|
2017-04-26 15:31:07 +00:00
|
|
|
method(#dual) perform: selector with: arg1 with: arg2
|
2017-03-19 14:18:37 +00:00
|
|
|
{
|
|
|
|
<primitive: #_perform>
|
|
|
|
self primitiveFailed
|
|
|
|
}
|
|
|
|
|
2017-04-26 15:31:07 +00:00
|
|
|
method(#dual) perform: selector with: arg1 with: arg2 with: arg3
|
2017-03-19 14:18:37 +00:00
|
|
|
{
|
|
|
|
<primitive: #_perform>
|
|
|
|
self primitiveFailed
|
|
|
|
}
|
|
|
|
|
2017-01-06 09:53:40 +00:00
|
|
|
(* ------------------------------------------------------------------
|
|
|
|
* COMMON ERROR/EXCEPTION HANDLERS
|
|
|
|
* ------------------------------------------------------------------ *)
|
2017-04-26 15:31:07 +00:00
|
|
|
method(#dual) error: msgText
|
2017-01-05 10:16:04 +00:00
|
|
|
{
|
2017-01-09 09:54:49 +00:00
|
|
|
(* TODO: implement this
|
|
|
|
Error signal: msgText. *)
|
2017-01-06 09:53:40 +00:00
|
|
|
msgText dump.
|
|
|
|
}
|
2015-10-08 14:26:04 +00:00
|
|
|
}
|
2016-05-13 15:10:34 +00:00
|
|
|
|
2017-01-06 09:53:40 +00:00
|
|
|
class Object(Apex)
|
2016-05-13 15:10:34 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2017-01-06 09:53:40 +00:00
|
|
|
class UndefinedObject(Apex)
|
2016-05-13 15:10:34 +00:00
|
|
|
{
|
2017-01-06 09:53:40 +00:00
|
|
|
method isNil
|
2016-05-13 15:10:34 +00:00
|
|
|
{
|
|
|
|
^true
|
|
|
|
}
|
|
|
|
|
2017-01-06 09:53:40 +00:00
|
|
|
method notNil
|
2016-05-13 15:10:34 +00:00
|
|
|
{
|
|
|
|
^false.
|
|
|
|
}
|
2016-06-22 13:43:49 +00:00
|
|
|
|
2017-01-06 09:53:40 +00:00
|
|
|
method handleException: exception
|
2016-06-22 13:43:49 +00:00
|
|
|
{
|
2016-12-13 15:18:19 +00:00
|
|
|
('### EXCEPTION NOT HANDLED #### ' & exception class name & ' - ' & exception messageText) dump.
|
2016-06-22 13:43:49 +00:00
|
|
|
## TODO: debug the current process???? "
|
|
|
|
## TODO: ensure to execute ensure blocks as well....
|
2016-06-23 15:35:28 +00:00
|
|
|
####Processor activeProcess terminate.
|
2016-06-22 13:43:49 +00:00
|
|
|
}
|
2016-05-13 15:10:34 +00:00
|
|
|
}
|
|
|
|
|
2017-01-05 10:16:04 +00:00
|
|
|
|
2017-03-08 14:48:12 +00:00
|
|
|
|
2017-03-08 13:53:41 +00:00
|
|
|
extend Error
|
2016-12-26 18:44:47 +00:00
|
|
|
{
|
2016-12-27 18:15:35 +00:00
|
|
|
(* ----------------------------
|
2017-03-08 14:48:12 +00:00
|
|
|
TODO: support nested pooldic/constant declaration...
|
2016-12-27 18:15:35 +00:00
|
|
|
|
2017-03-08 14:48:12 +00:00
|
|
|
pooldic/const
|
2016-12-27 18:15:35 +00:00
|
|
|
{
|
2017-03-08 13:53:41 +00:00
|
|
|
NONE := error(0).
|
|
|
|
GENERIC := error(1).
|
2016-12-27 18:15:35 +00:00
|
|
|
}
|
|
|
|
-------------------------------- *)
|
|
|
|
|
2017-01-06 09:53:40 +00:00
|
|
|
method isError
|
2016-12-26 18:44:47 +00:00
|
|
|
{
|
|
|
|
^true
|
|
|
|
}
|
2016-12-27 18:15:35 +00:00
|
|
|
|
2017-01-09 09:11:36 +00:00
|
|
|
method notError
|
|
|
|
{
|
|
|
|
^false
|
|
|
|
}
|
|
|
|
|
2017-04-01 04:58:02 +00:00
|
|
|
method(#primitive) asInteger.
|
|
|
|
method(#primitive) asCharacter.
|
|
|
|
method(#primitive) asString.
|
2017-11-21 15:05:12 +00:00
|
|
|
|
|
|
|
method signal
|
|
|
|
{
|
|
|
|
| exctx exblk retval actpos ctx |
|
|
|
|
|
|
|
|
exctx := (thisContext sender) findExceptionContext.
|
|
|
|
|
|
|
|
while (exctx notNil)
|
|
|
|
{
|
|
|
|
exblk := exctx findExceptionHandlerFor: (self class).
|
|
|
|
if (exblk notNil and: [actpos := exctx basicSize - 1. exctx basicAt: actpos])
|
|
|
|
{
|
|
|
|
exctx basicAt: actpos put: false.
|
|
|
|
[ retval := exblk value: self ] ensure: [ exctx basicAt: actpos put: true ].
|
|
|
|
thisContext unwindTo: (exctx sender) return: nil.
|
|
|
|
System return: retval to: (exctx sender).
|
|
|
|
}.
|
|
|
|
exctx := (exctx sender) findExceptionContext.
|
|
|
|
}.
|
|
|
|
|
|
|
|
## -----------------------------------------------------------------
|
|
|
|
## FATAL ERROR - no exception handler.
|
|
|
|
## -----------------------------------------------------------------
|
|
|
|
##thisContext unwindTo: nil return: nil.
|
|
|
|
##thisContext unwindTo: (Processor activeProcess initialContext) return: nil.
|
|
|
|
|
|
|
|
## TOOD: IMPROVE THIS EXPERIMENTAL BACKTRACE...
|
|
|
|
System logNl: '== BACKTRACE =='.
|
|
|
|
ctx := thisContext.
|
|
|
|
while (ctx notNil)
|
|
|
|
{
|
|
|
|
if (ctx class == MethodContext) { System logNl: (' ' & ctx method owner name & '>>' & ctx method name) }.
|
|
|
|
## TODO: include blockcontext???
|
|
|
|
ctx := ctx sender.
|
|
|
|
}.
|
|
|
|
System logNl: '== END OF BACKTRACE =='.
|
|
|
|
|
|
|
|
thisContext unwindTo: (thisProcess initialContext) return: nil.
|
|
|
|
('### ERROR NOT HANDLED #### ' & self class name & ' - ' & self asString) dump.
|
|
|
|
## TODO: debug the current process???? "
|
|
|
|
|
|
|
|
##Processor activeProcess terminate.
|
|
|
|
thisProcess terminate.
|
|
|
|
}
|
2016-12-26 18:44:47 +00:00
|
|
|
}
|