moo/moo/kernel/Apex.moo

390 lines
9.0 KiB
Smalltalk
Raw Normal View History

class Apex(nil)
{
}
class(#limited) Error(Apex)
{
pooldic Code
{
ENOERR := #\E0.
EGENERIC := #\E1.
ENOIMPL := #\E2.
ESYSERR := #\E3.
EINTERN := #\E4.
ESYSMEM := #\E5.
EOOMEM := #\E6.
EINVAL := #\E7.
ENOENT := #\E8.
EPERM := #\E12.
ERANGE := #\E20.
ELIMIT := #\E9999.
## add more items...
}
}
/*
pooldic Error.Code
{
ENOERR := #\E0.
EGENERIC := #\E1.
ENOIMPL := #\E2.
ESYSERR := #\E3.
EINTERN := #\E4.
ESYSMEM := #\E5.
EOOMEM := #\E6.
EINVAL := #\E7.
ENOENT := #\E8.
EPERM := #\E12.
ERANGE := #\E20.
ELIMIT := #\E9999.
## 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
{
## -------------------------------------------------------
## -------------------------------------------------------
method(#dual) dump
{
2015-10-15 14:40:08 +00:00
<primitive: #_dump>
}
## -------------------------------------------------------
## -------------------------------------------------------
method(#dual) yourself { ^self }
## -------------------------------------------------------
2017-04-26 15:31:07 +00:00
## INSTANTIATION & INITIALIZATION
## -------------------------------------------------------
method(#class,#primitive,#lenient) _basicNew.
method(#class,#primitive,#lenient) _basicNew: size.
method(#class,#primitive) basicNew.
method(#class,#primitive) basicNew: size.
/* 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
method(#class) basicNew: size
{
<primitive: #Apex__basicNew:>
self primitiveFailed(thisContext method)
}*/
method(#class) new
2015-10-15 14:40:08 +00:00
{
| x |
x := self basicNew.
x initialize. ## TODO: assess if it's good to call 'initialize' from new
2015-10-15 14:40:08 +00:00
^x.
}
method(#class) new: anInteger
2015-10-15 14:40:08 +00:00
{
| x |
x := self basicNew: anInteger.
x initialize. ## TODO: assess if it's good to call 'initialize' from new.
2015-10-15 14:40:08 +00:00
^x.
}
method initialize
2015-10-15 14:40:08 +00:00
{
/* a subclass may override this method */
2015-10-15 14:40:08 +00:00
^self.
}
## -------------------------------------------------------
## -------------------------------------------------------
2017-12-03 17:08:04 +00:00
method(#dual,#primitive,#lenient) _shallowCopy.
method(#dual,#primitive) shallowCopy.
method(#dual,#primitive,#lenient) _copy. ## alias to _shallowCopy
method(#dual,#primitive) copy. ## alias to shallowCopy
## -------------------------------------------------------
## -------------------------------------------------------
method(#dual,#primitive,#lenient) _basicSize.
method(#dual,#primitive) basicSize.
2017-12-03 17:08:04 +00:00
method(#dual,#primitive) basicAt: index.
method(#dual,#primitive) basicAt: index put: value.
method(#dual,#primitive) basicFillFrom: sindex with: value count: count.
method(#dual,#primitive) basicShiftFrom: sindex to: dindex count: count.
/* ------------------------------------------------------------------
* FINALIZATION SUPPORT
* ------------------------------------------------------------------ */
method(#dual,#primitive) addToBeFinalized.
2017-12-03 17:08:04 +00:00
method(#dual,#primitive) removeToBeFinalized.
/* ------------------------------------------------------------------
* HASHING
* ------------------------------------------------------------------ */
2017-12-03 17:08:04 +00:00
method(#dual,#primitive) hash.
/*
2017-04-26 15:31:07 +00:00
method(#dual) hash
{
2017-12-03 17:08:04 +00:00
<primitive: #Apex_hash>
self subclassResponsibility: #hash
}*/
/* ------------------------------------------------------------------
* IDENTITY TEST
* ------------------------------------------------------------------ */
2017-12-03 17:08:04 +00:00
## check if the receiver is identical to anObject.
## this doesn't compare the contents
method(#dual, #primitive) == anObject.
2017-04-26 15:31:07 +00:00
method(#dual) ~~ anObject
{
2017-12-03 17:08:04 +00:00
<primitive: #'Apex_~~'>
^(self == anObject) not.
}
/* ------------------------------------------------------------------
* EQUALITY TEST
* ------------------------------------------------------------------ */
2017-04-26 15:31:07 +00:00
method(#dual) = anObject
{
2017-12-03 17:08:04 +00:00
<primitive: #'Apex_='>
self subclassResponsibility: #=
}
2017-04-26 15:31:07 +00:00
method(#dual) ~= anObject
{
2017-12-03 17:08:04 +00:00
<primitive: #'Apex_~='>
^(self = anObject) not.
}
2017-04-26 15:31:07 +00:00
/* ------------------------------------------------------------------
* COMMON QUERIES
* ------------------------------------------------------------------ */
method(#dual,#primitive) class.
2017-12-03 17:08:04 +00:00
2017-04-26 15:31:07 +00:00
method(#dual) isNil
{
## ^self == nil.
^false
}
2017-04-26 15:31:07 +00:00
method(#dual) notNil
{
## ^(self == nil) not
## ^self ~= nil.
^true.
}
2017-04-26 15:31:07 +00:00
method(#dual) isError
{
^false
}
2017-04-26 15:31:07 +00:00
method(#dual) notError
{
^true
}
2016-05-07 01:37:44 +00:00
## -------------------------------------------------------
## -------------------------------------------------------
method(#class) inheritsFrom: aClass
2016-05-07 01:37:44 +00:00
{
| c |
c := self superclass.
/* [c notNil] whileTrue: [
2016-05-07 01:37:44 +00:00
[ c == aClass ] ifTrue: [^true].
c := c superclass.
]. */
while (c notNil)
{
if (c == aClass) { ^true }.
c := c superclass.
}.
2016-05-07 01:37:44 +00:00
^false
}
method(#class) isMemberOf: aClass
2016-05-07 01:37:44 +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
}
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-12-03 17:08:04 +00:00
<primitive: #Apex_isKindOf:>
2016-05-07 01:37:44 +00:00
^(self isMemberOf: aClass) or: [self class inheritsFrom: aClass].
}
## -------------------------------------------------------
## -------------------------------------------------------
2017-12-03 17:08:04 +00:00
method(#dual,#primitive) respondsTo: selector.
## -------------------------------------------------------
## -------------------------------------------------------
2017-12-03 17:08:04 +00:00
method(#dual,#variadic,#primitive) perform(selector).
2017-04-26 15:31:07 +00:00
method(#dual) perform: selector
{
2017-12-03 17:08:04 +00:00
<primitive: #Apex_perform>
self primitiveFailed
}
2017-04-26 15:31:07 +00:00
method(#dual) perform: selector with: arg1
{
2017-12-03 17:08:04 +00:00
<primitive: #Apex_perform>
self primitiveFailed
}
2017-04-26 15:31:07 +00:00
method(#dual) perform: selector with: arg1 with: arg2
{
2017-12-03 17:08:04 +00:00
<primitive: #Apex_perform>
self primitiveFailed
}
2017-04-26 15:31:07 +00:00
method(#dual) perform: selector with: arg1 with: arg2 with: arg3
{
2017-12-03 17:08:04 +00:00
<primitive: #Apex_perform>
self primitiveFailed
}
/* ------------------------------------------------------------------
* COMMON ERROR/EXCEPTION HANDLERS
* ------------------------------------------------------------------ */
2017-04-26 15:31:07 +00:00
method(#dual) error: msgText
{
/* TODO: implement this
Error signal: msgText. */
msgText dump.
}
}
2016-05-13 15:10:34 +00:00
class Object(Apex)
2016-05-13 15:10:34 +00:00
{
}
class UndefinedObject(Apex)
2016-05-13 15:10:34 +00:00
{
method isNil
2016-05-13 15:10:34 +00:00
{
^true
}
method notNil
2016-05-13 15:10:34 +00:00
{
^false.
}
method handleException: exception
{
('### EXCEPTION NOT HANDLED #### ' & exception class name & ' - ' & exception messageText) dump.
## TODO: debug the current process???? "
## TODO: ensure to execute ensure blocks as well....
####Processor activeProcess terminate.
}
2016-05-13 15:10:34 +00:00
}
2017-03-08 14:48:12 +00:00
extend Error
{
/* ----------------------------
2017-03-08 14:48:12 +00:00
TODO: support nested pooldic/constant declaration...
2017-03-08 14:48:12 +00:00
pooldic/const
{
NONE := #\e0.
GENERIC := #\e1.
}
-------------------------------- */
method isError
{
^true
}
method notError
{
^false
}
method(#primitive) asCharacter.
method asError { ^self }
method(#primitive) asInteger.
method(#primitive) asString.
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.
}
}