--- a/Block.st Mon Feb 20 10:49:52 2006 +0100
+++ b/Block.st Mon Feb 20 10:51:28 2006 +0100
@@ -520,6 +520,11 @@
a := 0.
[ 123 / a ] ifError:[self halt]
"
+!
+
+valueWithPossibleArgs:argArray
+ self halt.
+ ^ self
! !
!Block methodsFor:'Compatibility-V''Age'!
@@ -1340,6 +1345,292 @@
block := [:arg1 :arg2 | Transcript showCR:arg1. Transcript showCR:arg2 ].
block valueWithOptionalArgument:10 and:20.
"
+!
+
+valueWithOptionalArguments:argArray
+ "evaluate the receiver with arguments as required taken from argArray.
+ Only the required number of arguments is taken from argArray or nil;
+ (i.e. argArray may be larger than the required number).
+ If the size of the argArray is smaller than the number of arguments, an error is raised."
+
+ |numArgsProvided a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15|
+
+ (argArray notNil and:[(argArray class ~~ Array) and:[argArray isArray not]]) ifTrue:[
+ ^ self badArgumentArray:argArray
+ ].
+ (argArray size >= nargs) ifFalse:[
+ ^ self wrongNumberOfArguments:argArray size
+ ].
+%{
+ REGISTER OBJFUNC thecode;
+ OBJ home;
+ REGISTER OBJ *ap;
+ OBJ nA;
+ int __numArgsProvided = __intVal(numArgsProvided);
+
+#if defined(THIS_CONTEXT)
+ if (__ISVALID_ILC_LNO(__pilc))
+ __ContextInstPtr(__thisContext)->c_lineno = __ILC_LNO_AS_OBJ(__pilc);
+#endif
+ thecode = __BlockInstPtr(self)->b_code;
+
+ nA = __INST(nargs);
+
+ if (argArray == nil) {
+ ap = 0;
+ } else {
+ ap = __arrayVal(argArray); /* nonNil after above test (size is known to be ok) */
+ }
+
+#ifndef NEW_BLOCK_CALL
+ home = __BlockInstPtr(self)->b_home;
+ if (thecode != (OBJFUNC)nil) {
+ /* the most common case (0 args) here (without a switch) */
+
+ if (nA == __mkSmallInteger(0)) {
+ RETURN ( (*thecode)(home) );
+ }
+
+ switch ((INT)(nA)) {
+ default:
+ goto error;
+ case (INT)__mkSmallInteger(15):
+ RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], ap[9], ap[10], ap[11], ap[12], ap[13], ap[14]) );
+ case (INT)__mkSmallInteger(14):
+ RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], ap[9], ap[10], ap[11], ap[12], ap[13]) );
+ case (INT)__mkSmallInteger(13):
+ RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], ap[9], ap[10], ap[11], ap[12]) );
+ case (INT)__mkSmallInteger(12):
+ RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], ap[9], ap[10], ap[11]) );
+ case (INT)__mkSmallInteger(11):
+ RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], ap[9], ap[10]) );
+ case (INT)__mkSmallInteger(10):
+ RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], ap[9]) );
+ case (INT)__mkSmallInteger(9):
+ RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8]) );
+ case (INT)__mkSmallInteger(8):
+ RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7]) );
+ case (INT)__mkSmallInteger(7):
+ RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6]) );
+ case (INT)__mkSmallInteger(6):
+ RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5]) );
+ case (INT)__mkSmallInteger(5):
+ RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4]) );
+ case (INT)__mkSmallInteger(4):
+ RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3]) );
+ case (INT)__mkSmallInteger(3):
+ RETURN ( (*thecode)(home, ap[0], ap[1], ap[2]) );
+ case (INT)__mkSmallInteger(2):
+ RETURN ( (*thecode)(home, ap[0], ap[1]) );
+ case (INT)__mkSmallInteger(1):
+ RETURN ( (*thecode)(home, ap[0]) );
+ case (INT)__mkSmallInteger(0):
+ RETURN ( (*thecode)(home) );
+ break;
+ }
+ }
+#endif
+
+ if (nA != __mkSmallInteger(0)) {
+ ap = __arrayVal(argArray); /* nonNil after above test (size is known to be ok) */
+ switch ((INT)nA) {
+ default:
+ goto error;
+ case (INT)__mkSmallInteger(15):
+ a15 = ap[14];
+ case (INT)__mkSmallInteger(14):
+ a14 = ap[13];
+ case (INT)__mkSmallInteger(13):
+ a13 = ap[12];
+ case (INT)__mkSmallInteger(12):
+ a12 = ap[11];
+ case (INT)__mkSmallInteger(11):
+ a11 = ap[10];
+ case (INT)__mkSmallInteger(10):
+ a10 = ap[9];
+ case (INT)__mkSmallInteger(9):
+ a9 = ap[8];
+ case (INT)__mkSmallInteger(8):
+ a8 = ap[7];
+ case (INT)__mkSmallInteger(7):
+ a7 = ap[6];
+ case (INT)__mkSmallInteger(6):
+ a6 = ap[5];
+ case (INT)__mkSmallInteger(5):
+ a5 = ap[4];
+ case (INT)__mkSmallInteger(4):
+ a4 = ap[3];
+ case (INT)__mkSmallInteger(3):
+ a3 = ap[2];
+ case (INT)__mkSmallInteger(2):
+ a2 = ap[1];
+ case (INT)__mkSmallInteger(1):
+ a1 = ap[0];
+ case (INT)__mkSmallInteger(0):
+ break;
+ }
+ }
+#ifdef NEW_BLOCK_CALL
+ if (thecode != (OBJFUNC)nil) {
+ RETURN ( (*thecode)(self, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) );
+ }
+# ifdef PASS_ARG_POINTER
+ RETURN ( __interpret(self, __intVal(nA), nil, nil, nil, nil, &a1) );
+# else
+ RETURN ( __interpret(self, __intVal(nA), nil, nil, nil, nil, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) );
+# endif
+
+#else
+
+# ifdef PASS_ARG_POINTER
+ RETURN ( __interpret(self, __intVal(nA), nil, home, nil, nil, &a1) );
+# else
+ RETURN ( __interpret(self, __intVal(nA), nil, home, nil, nil, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) );
+# endif
+
+#endif
+
+error: ;
+%}.
+ "
+ the above code only supports up-to 15 arguments
+ "
+ ^ ArgumentError
+ raiseRequestWith:self
+ errorString:'only blocks with up-to 15 arguments supported'
+!
+
+valueWithPossibleArguments:argArray
+ "evaluate the receiver with arguments as required taken from argArray.
+ If argArray provides less than the required number of arguments,
+ nil is assumed for any remaining argument.
+ (i.e. argArray may be smaller than the required number).
+ Only the required number of arguments is taken from argArray or nil;
+ (i.e. argArray may be larger than the required number)."
+
+ |numArgsProvided a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15|
+
+ (argArray notNil and:[(argArray class ~~ Array) and:[argArray isArray not]]) ifTrue:[
+ ^ self badArgumentArray:argArray
+ ].
+ numArgsProvided := argArray size.
+%{
+ REGISTER OBJFUNC thecode;
+ OBJ home;
+ REGISTER OBJ *ap;
+ OBJ nA;
+ int __numArgsProvided = __intVal(numArgsProvided);
+
+#if defined(THIS_CONTEXT)
+ if (__ISVALID_ILC_LNO(__pilc))
+ __ContextInstPtr(__thisContext)->c_lineno = __ILC_LNO_AS_OBJ(__pilc);
+#endif
+ thecode = __BlockInstPtr(self)->b_code;
+
+ nA = __INST(nargs);
+
+ if (argArray == nil) {
+ ap = 0;
+ } else {
+ ap = __arrayVal(argArray); /* nonNil after above test (size is known to be ok) */
+ }
+ switch (__numArgsProvided) {
+ default:
+ case 15: a15 = ap[14];
+ case 14: a14 = ap[13];
+ case 13: a13 = ap[12];
+ case 12: a12 = ap[11];
+ case 11: a11 = ap[10];
+ case 10: a10 = ap[9];
+ case 9: a9 = ap[8];
+ case 8: a8 = ap[7];
+ case 7: a7 = ap[6];
+ case 6: a6 = ap[5];
+ case 5: a5 = ap[4];
+ case 4: a4 = ap[3];
+ case 3: a3 = ap[2];
+ case 2: a2 = ap[1];
+ case 1: a1 = ap[0];
+ case 0: ;
+ }
+
+#ifndef NEW_BLOCK_CALL
+ home = __BlockInstPtr(self)->b_home;
+ if (thecode != (OBJFUNC)nil) {
+ /* the most common case (0 args) here (without a switch) */
+
+ if (nA == __mkSmallInteger(0)) {
+ RETURN ( (*thecode)(home) );
+ }
+
+ switch ((INT)(nA)) {
+ default:
+ goto error;
+ case (INT)__mkSmallInteger(15):
+ RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) );
+ case (INT)__mkSmallInteger(14):
+ RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) );
+ case (INT)__mkSmallInteger(13):
+ RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) );
+ case (INT)__mkSmallInteger(12):
+ RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) );
+ case (INT)__mkSmallInteger(11):
+ RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) );
+ case (INT)__mkSmallInteger(10):
+ RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) );
+ case (INT)__mkSmallInteger(9):
+ RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7, a8, a9) );
+ case (INT)__mkSmallInteger(8):
+ RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7, a8) );
+ case (INT)__mkSmallInteger(7):
+ RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7) );
+ case (INT)__mkSmallInteger(6):
+ RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6) );
+ case (INT)__mkSmallInteger(5):
+ RETURN ( (*thecode)(home, a1, a2, a3, a4, a5) );
+ case (INT)__mkSmallInteger(4):
+ RETURN ( (*thecode)(home, a1, a2, a3, a4) );
+ case (INT)__mkSmallInteger(3):
+ RETURN ( (*thecode)(home, a1, a2, a3) );
+ case (INT)__mkSmallInteger(2):
+ RETURN ( (*thecode)(home, a1, a2) );
+ case (INT)__mkSmallInteger(1):
+ RETURN ( (*thecode)(home, a1) );
+ case (INT)__mkSmallInteger(0):
+ RETURN ( (*thecode)(home) );
+ break;
+ }
+ }
+#endif
+
+#ifdef NEW_BLOCK_CALL
+ if (thecode != (OBJFUNC)nil) {
+ RETURN ( (*thecode)(self, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) );
+ }
+# ifdef PASS_ARG_POINTER
+ RETURN ( __interpret(self, __intVal(nA), nil, nil, nil, nil, &a1) );
+# else
+ RETURN ( __interpret(self, __intVal(nA), nil, nil, nil, nil, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) );
+# endif
+
+#else
+
+# ifdef PASS_ARG_POINTER
+ RETURN ( __interpret(self, __intVal(nA), nil, home, nil, nil, &a1) );
+# else
+ RETURN ( __interpret(self, __intVal(nA), nil, home, nil, nil, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) );
+# endif
+
+#endif
+
+error: ;
+%}.
+ "
+ the above code only supports up-to 15 arguments
+ "
+ ^ ArgumentError
+ raiseRequestWith:self
+ errorString:'only blocks with up-to 15 arguments supported'
! !
!Block methodsFor:'exception handling'!
@@ -2265,7 +2556,7 @@
!Block class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/Block.st,v 1.147 2005-12-21 18:34:28 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/Block.st,v 1.148 2006-02-20 09:51:28 cg Exp $'
! !
Block initialize!