From: <bi...@us...> - 2007-05-31 09:32:31
|
Revision: 421 http://svn.sourceforge.net/oorexx/?rev=421&view=rev Author: bigrixx Date: 2007-05-31 02:32:32 -0700 (Thu, 31 May 2007) Log Message: ----------- [ oorexx-Bugs-1728782 ] Queue-hasindex bug [ oorexx-Bugs-1728785 ] Queue-hasindex: trap [ oorexx-Bugs-1728786 ] Queue-next: wrong result [ oorexx-Bugs-1728787 ] Queue-previuos: wrong result [ oorexx-Bugs-1728790 ] Queue-next, wrong result # 2 [ oorexx-Bugs-1728791 ] Queue-previous: wrong result # 2 Modified Paths: -------------- interpreter-3.x/trunk/kernel/classes/QueueClass.cpp interpreter-3.x/trunk/kernel/messages/DocErrorMessages.sgml interpreter-3.x/trunk/kernel/messages/RexxErrorCodes.h interpreter-3.x/trunk/kernel/messages/RexxMessageNumbers.h interpreter-3.x/trunk/kernel/messages/RexxMessageTable.h interpreter-3.x/trunk/kernel/messages/rexxmsg.xml interpreter-3.x/trunk/kernel/platform/windows/winmsgtb.rc Modified: interpreter-3.x/trunk/kernel/classes/QueueClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/QueueClass.cpp 2007-05-30 18:35:43 UTC (rev 420) +++ interpreter-3.x/trunk/kernel/classes/QueueClass.cpp 2007-05-31 09:32:32 UTC (rev 421) @@ -118,27 +118,27 @@ RexxInteger *integerIndex = (RexxInteger *)REQUEST_INTEGER(index); if (integerIndex == TheNilObject) { - report_exception1(Error_Incorrect_method_index, index); + report_exception1(Error_Incorrect_method_queue_index, index); } // and positive wholenumber_t item_index = integerIndex->value; if (item_index < 1) { - report_exception1(Error_Incorrect_method_index, index); + report_exception1(Error_Incorrect_method_queue_index, index); } // we need to iterate through the entries to locate this - LISTENTRY *listIndex = ENTRY_POINTER(this->first); - while (listIndex != NULL) + long listIndex = this->first; + while (listIndex != LIST_END) { // have we reached the entry? return the item item_index--; if (item_index == 0) { - return listIndex; + return ENTRY_POINTER(listIndex); } // step to the next entry - listIndex = ENTRY_POINTER(listIndex->next); + listIndex = ENTRY_POINTER(listIndex)->next; } return NULL; // this queue item not found } @@ -156,7 +156,7 @@ LISTENTRY *list_index = this->locateEntry(index, IntegerTwo); if (list_index == NULL) /* not a valid index? */ /* raise an error */ - report_exception1(Error_Incorrect_method_index, index); + report_exception1(Error_Incorrect_method_queue_index, index); OrefSet(this->table, list_index->value, value); return OREF_NULL; /* return nothing at all */ } @@ -324,7 +324,7 @@ element = this->locateEntry(index, (RexxObject *)IntegerOne); if (element == NULL) /* not a valid index? */ { - report_exception1(Error_Incorrect_method_index, index); + report_exception1(Error_Incorrect_method_queue_index, index); } if (element->next == LIST_END) /* no next item? */ @@ -351,7 +351,7 @@ element = this->locateEntry(index, (RexxObject *)IntegerOne); if (element == NULL) /* not a valid index? */ /* raise an error */ - report_exception1(Error_Incorrect_method_index, index); + report_exception1(Error_Incorrect_method_queue_index, index); if (element->previous == LIST_END) /* no previous item? */ return TheNilObject; /* just return .nil */ @@ -375,13 +375,16 @@ long counter = 0; while (current != LIST_END) { + counter++; if (current == target) { - return counter + 1; + return counter; } current = ENTRY_POINTER(current)->next; } + + return 0; } Modified: interpreter-3.x/trunk/kernel/messages/DocErrorMessages.sgml =================================================================== --- interpreter-3.x/trunk/kernel/messages/DocErrorMessages.sgml 2007-05-30 18:35:43 UTC (rev 420) +++ interpreter-3.x/trunk/kernel/messages/DocErrorMessages.sgml 2007-05-31 09:32:32 UTC (rev 421) @@ -2941,6 +2941,12 @@ <para>Method <emphasis>name</emphasis> is ABSTRACT and cannot be directly invoked</para> </listitem> </varlistentry> +<varlistentry> +<term>966</term> +<listitem> +<para>Incorrect queue index "<emphasis>index</emphasis>"</para> +</listitem> +</varlistentry> </variablelist> </section> <section id="ERR97"> Modified: interpreter-3.x/trunk/kernel/messages/RexxErrorCodes.h =================================================================== --- interpreter-3.x/trunk/kernel/messages/RexxErrorCodes.h 2007-05-30 18:35:43 UTC (rev 420) +++ interpreter-3.x/trunk/kernel/messages/RexxErrorCodes.h 2007-05-31 09:32:32 UTC (rev 421) @@ -472,6 +472,7 @@ #define Error_Unsupported_method 93963 #define Error_Application_error 93964 #define Error_Incorrect_method_abstract 93965 +#define Error_Incorrect_method_queue_index 93966 #define Error_No_method 97000 #define Error_No_method_name 97001 #define Error_No_method_user_defined 97900 Modified: interpreter-3.x/trunk/kernel/messages/RexxMessageNumbers.h =================================================================== --- interpreter-3.x/trunk/kernel/messages/RexxMessageNumbers.h 2007-05-30 18:35:43 UTC (rev 420) +++ interpreter-3.x/trunk/kernel/messages/RexxMessageNumbers.h 2007-05-31 09:32:32 UTC (rev 421) @@ -593,6 +593,7 @@ #define Error_Invalid_whole_number_compareto_msg 666 #define Error_Invalid_whole_number_compare_msg 667 #define Error_Execution_sparse_array_msg 668 +#define Error_Incorrect_method_queue_index_msg 669 #endif Modified: interpreter-3.x/trunk/kernel/messages/RexxMessageTable.h =================================================================== --- interpreter-3.x/trunk/kernel/messages/RexxMessageTable.h 2007-05-30 18:35:43 UTC (rev 420) +++ interpreter-3.x/trunk/kernel/messages/RexxMessageTable.h 2007-05-31 09:32:32 UTC (rev 421) @@ -474,6 +474,7 @@ MINOR(Error_Unsupported_method) MINOR(Error_Application_error) MINOR(Error_Incorrect_method_abstract) + MINOR(Error_Incorrect_method_queue_index) MAJOR(Error_No_method) MINOR(Error_No_method_name) MINOR(Error_No_method_user_defined) Modified: interpreter-3.x/trunk/kernel/messages/rexxmsg.xml =================================================================== --- interpreter-3.x/trunk/kernel/messages/rexxmsg.xml 2007-05-30 18:35:43 UTC (rev 420) +++ interpreter-3.x/trunk/kernel/messages/rexxmsg.xml 2007-05-31 09:32:32 UTC (rev 421) @@ -4018,6 +4018,15 @@ <SymbolicName>Error_Incorrect_method_abstract</SymbolicName> <Text>Method <Sub position="1" name="name"/> is ABSTRACT and cannot be directly invoked</Text> </SubMessage> + <SubMessage> + <Code>93</Code> + <Subcode>966</Subcode> + <MessageNumber>669</MessageNumber> + <Component>Rexx</Component> + <Severity>Warning</Severity> + <SymbolicName>Error_Incorrect_method_queue_index</SymbolicName> + <Text>Incorrect queue index <q><Sub position="1" name="index"/></q></Text> + </SubMessage> </Subcodes> </Message> <Message> Modified: interpreter-3.x/trunk/kernel/platform/windows/winmsgtb.rc =================================================================== --- interpreter-3.x/trunk/kernel/platform/windows/winmsgtb.rc 2007-05-30 18:35:43 UTC (rev 420) +++ interpreter-3.x/trunk/kernel/platform/windows/winmsgtb.rc 2007-05-31 09:32:32 UTC (rev 421) @@ -593,6 +593,7 @@ Error_Invalid_whole_number_compareto "Result of a COMPARETO method call did not result in a whole number; found ""&1""" Error_Invalid_whole_number_compare "Result of a COMPARE method call did not result in a whole number; found ""&1""" Error_Execution_sparse_array "Missing array element at position &1" + Error_Incorrect_method_queue_index "Incorrect queue index ""&1""" END This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2007-06-02 22:23:31
|
Revision: 426 http://svn.sourceforge.net/oorexx/?rev=426&view=rev Author: bigrixx Date: 2007-06-02 15:23:33 -0700 (Sat, 02 Jun 2007) Log Message: ----------- [ 1730051 ] "new" method of "Supplier" not reflectable ? [ 1730060 ] 'arrayIn' missing from 'InputStream' ? [ 1730062 ] 'arrayIn' and 'arrayOut' missing from 'InputOutputStream' ? Modified Paths: -------------- interpreter-3.x/trunk/kernel/RexxClasses/StreamClasses.orx interpreter-3.x/trunk/kernel/runtime/Setup.cpp Modified: interpreter-3.x/trunk/kernel/RexxClasses/StreamClasses.orx =================================================================== --- interpreter-3.x/trunk/kernel/RexxClasses/StreamClasses.orx 2007-06-02 16:28:26 UTC (rev 425) +++ interpreter-3.x/trunk/kernel/RexxClasses/StreamClasses.orx 2007-06-02 22:23:33 UTC (rev 426) @@ -110,7 +110,19 @@ ::method position raise syntax 93.963 -- not supported by default...this is optional +::method arrayIn + array = .array~new + signal on notready + + do forever + array~append(self~linein) + end + +notready: + return array + + ::CLASS 'InputOutputStream' public MIXINCLASS Object ::method charout abstract -- all of the base input/output operations must be implemented @@ -123,7 +135,25 @@ ::method open -- these are nops by default ::method close +::method arrayIn + array = .array~new + signal on notready + + do forever + array~append(self~linein) + end + +notready: + return array + +::method arrayOut + use strict arg lines + + do line over lines + self~lineout(line) + end + ::method position raise syntax 93.963 -- not supported by default...this is optional Modified: interpreter-3.x/trunk/kernel/runtime/Setup.cpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/Setup.cpp 2007-06-02 16:28:26 UTC (rev 425) +++ interpreter-3.x/trunk/kernel/runtime/Setup.cpp 2007-06-02 22:23:33 UTC (rev 426) @@ -1461,7 +1461,11 @@ /* Add the NEW methods to the class */ /* behaviour mdict */ defineKernelMethod(CHAR_NEW, TheSupplierClassBehaviour, CPPMSUPCL(RexxSupplierClass::newRexx), A_COUNT); + /* set the scope of the methods to */ + /* this classes oref */ + TheSupplierClassBehaviour->setMethodDictionaryScope(TheSupplierClass); + /* Add the instance methods to the */ /* instance behaviour mdict */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2007-06-04 18:52:35
|
Revision: 428 http://svn.sourceforge.net/oorexx/?rev=428&view=rev Author: bigrixx Date: 2007-06-04 11:52:36 -0700 (Mon, 04 Jun 2007) Log Message: ----------- [ 1730796 ] Allow collection's "putall" method to accept a supplier [ 1730798 ] Allow collection's "appendAll" method to accept a supplier Plus change StreamSupplier to be a Supplier subclass, plus reorgnize the supplier class to have an INIT method. Modified Paths: -------------- interpreter-3.x/trunk/kernel/RexxClasses/CoreClasses.orx interpreter-3.x/trunk/kernel/RexxClasses/StreamClasses.orx interpreter-3.x/trunk/kernel/classes/SupplierClass.cpp interpreter-3.x/trunk/kernel/classes/SupplierClass.hpp interpreter-3.x/trunk/kernel/runtime/Setup.cpp Modified: interpreter-3.x/trunk/kernel/RexxClasses/CoreClasses.orx =================================================================== --- interpreter-3.x/trunk/kernel/RexxClasses/CoreClasses.orx 2007-06-04 14:31:48 UTC (rev 427) +++ interpreter-3.x/trunk/kernel/RexxClasses/CoreClasses.orx 2007-06-04 18:52:36 UTC (rev 428) @@ -91,6 +91,16 @@ .orderedcollection~!rexxdefined .mapcollection~!rexxdefined +supplier_methods = .table~new + +supplier_methods~put(.methods~supplier_allitems, 'ALLITEMS') +supplier_methods~put(.methods~supplier_allindexes, 'ALLINDEXES') +supplier_methods~put(.methods~supplier_getarrays, 'GETARRAYS') +supplier_methods~put(.methods~supplier_supplier, 'SUPPLIER') + +.supplier~!define_methods(supplier_methods) +.supplier~!rexxdefined + .environment~setentry('COLLECTION', .collection) .environment~setentry('ORDEREDCOLLECTION', .orderedcollection) .environment~setentry('MAPCOLLECTION', .mapcollection) @@ -161,6 +171,49 @@ /* ********************************************************************************************* */ /*============================================================================*/ +/* Additional S U P P L I E R methods */ +/*============================================================================*/ +::method supplier_allItems + expose items + use strict arg -- enforces no arguments + + self~getArrays + + return items + + +::method supplier_allIndexes + expose indexes + use strict arg -- enforces no arguments + + self~getArrays + + return indexes + + +::method supplier_getArrays private + expose indexes items + + if \var('INDEXES') then do + indexes = .array~new + items = .array~new + + do while self~available + indexes~append(self~index) + items~append(self~item) + self~next + end + end + + +::method supplier_supplier + use strict arg + return self + + + + +/*============================================================================*/ /* A R R A Y set methods */ /*============================================================================*/ @@ -700,6 +753,7 @@ signal on nomethod supplier = other~supplier /* get an other supplier */ + do while supplier~available /* loop over the other collection */ self~put(supplier~item, supplier~index) -- putting the item using the same index supplier~next Modified: interpreter-3.x/trunk/kernel/RexxClasses/StreamClasses.orx =================================================================== --- interpreter-3.x/trunk/kernel/RexxClasses/StreamClasses.orx 2007-06-04 14:31:48 UTC (rev 427) +++ interpreter-3.x/trunk/kernel/RexxClasses/StreamClasses.orx 2007-06-04 18:52:36 UTC (rev 428) @@ -397,7 +397,8 @@ use strict arg return .StreamSupplier~new(self) /* return a stream supplier */ -::CLASS 'StreamSupplier' /* stream supplier class */ +::CLASS 'StreamSupplier' subclass 'Supplier' /* stream supplier class */ + ::METHOD init /* initialization method */ /* access the state information */ expose stream position line available transient @@ -446,12 +447,12 @@ ::METHOD index /* get the current supplier index */ expose position available /* access needed object variables */ use strict arg -if (arg() > 0) then /* too many arguments? */ - raise syntax 93.902 array (0) /* raise an error */ if \available then /* already reached the end? */ raise syntax 93.937 /* this is an error */ +return position + /*****************************************************************/ /* Create the rx_queue class and define its associated methods */ /*****************************************************************/ Modified: interpreter-3.x/trunk/kernel/classes/SupplierClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/SupplierClass.cpp 2007-06-04 14:31:48 UTC (rev 427) +++ interpreter-3.x/trunk/kernel/classes/SupplierClass.cpp 2007-06-04 18:52:36 UTC (rev 428) @@ -47,6 +47,7 @@ #include "ArrayClass.hpp" #include "SupplierClass.hpp" + RexxSupplier::RexxSupplier( RexxArray *values, /* array of values */ RexxArray *indexes ) /* array of indexes */ @@ -61,6 +62,14 @@ } +RexxSupplier::RexxSupplier() +/****************************************************************************/ +/* Function: Initialize a supplier */ +/****************************************************************************/ +{ +} + + void RexxSupplier::live() /******************************************************************************/ /* Function: Normal garbage collection live marking */ @@ -182,6 +191,41 @@ return newObject; /* return the new object */ } + +/** + * Supplier initializer for suppliers created via + * .supplier~new(values, indexes). + * + * @param values The values array object + * @param indexes The indexes array object + * + * @return Nothing + */ +RexxObject *RexxSupplier::initRexx(RexxArray *values, RexxArray *indexes) +{ + required_arg(values, ONE); // both values are required + required_arg(indexes, TWO); + + // now verify both values + RexxArray *new_values = REQUEST_ARRAY(values); + RexxArray *new_indexes = REQUEST_ARRAY(indexes); + if (new_values == (RexxArray *)TheNilObject || new_values->getDimension() != 1) + { + report_exception1(Error_Incorrect_method_noarray, values); + } + if (new_indexes == (RexxArray *)TheNilObject || new_indexes->getDimension() != 1) + { + report_exception1(Error_Incorrect_method_noarray, indexes); + } + + OrefSet(this, this->values, new_values); + OrefSet(this, this->indexes, new_indexes); + this->position = 1; + return OREF_NULL; +} + + + RexxObject *RexxSupplierClass::newRexx( RexxObject **init_args, /* subclass init arguments */ size_t argCount) /* count of arguments */ @@ -189,37 +233,13 @@ /* Function: Public REXX supplier new method */ /****************************************************************************/ { - RexxObject *values; /* array of collection values */ - RexxObject *indexes; /* array of collection indexes */ - RexxArray *new_values; /* converted values array */ - RexxArray *new_indexes; /* converted indexes array */ - RexxObject *newObject; /* newly created object */ - - /* break up the arguments */ - process_new_args(init_args, argCount, &init_args, &argCount, 2, &values, &indexes); - required_arg(values, ONE); /* first argument is required */ - required_arg(indexes, TWO); /* as is the second */ - - /* get arrays for both values and */ - new_values = REQUEST_ARRAY(values); - /* and the indices arguments */ - new_indexes = REQUEST_ARRAY(indexes); - /* didn't convert? */ - if (new_values == (RexxArray *)TheNilObject || new_values->getDimension() != 1) - /* raise an error */ - report_exception1(Error_Incorrect_method_noarray, values); - /* didn't convert? */ - if (new_indexes == (RexxArray *)TheNilObject || new_indexes->getDimension() != 1) - /* raise an error */ - report_exception1(Error_Incorrect_method_noarray, indexes); - /* create the new supplier */ - newObject = new RexxSupplier(new_values, new_indexes); - BehaviourSet(newObject, this->instanceBehaviour); - if (this->uninitDefined()) { - newObject->hasUninit(); - } - + RexxObject *newObject = new RexxSupplier(); + BehaviourSet(newObject, this->instanceBehaviour); + if (this->uninitDefined()) + { + newObject->hasUninit(); + } /* Initialize the new instance */ - newObject->sendMessage(OREF_INIT, init_args, argCount); - return newObject; /* return the new supplier */ + newObject->sendMessage(OREF_INIT, init_args, argCount); + return newObject; /* return the new supplier */ } Modified: interpreter-3.x/trunk/kernel/classes/SupplierClass.hpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/SupplierClass.hpp 2007-06-04 14:31:48 UTC (rev 427) +++ interpreter-3.x/trunk/kernel/classes/SupplierClass.hpp 2007-06-04 18:52:36 UTC (rev 428) @@ -48,6 +48,7 @@ public: inline RexxSupplier(RESTORETYPE restoreType) { ; }; RexxSupplier(RexxArray *, RexxArray *); + RexxSupplier(); void *operator new(size_t); inline void *operator new(size_t size, void *ptr) { return ptr; }; @@ -59,6 +60,7 @@ RexxObject *next(); RexxObject *value(); RexxObject *index(); + RexxObject *initRexx(RexxArray *values, RexxArray *indexes); RexxArray *values; /* array of values */ RexxArray *indexes; /* array of indexes */ Modified: interpreter-3.x/trunk/kernel/runtime/Setup.cpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/Setup.cpp 2007-06-04 14:31:48 UTC (rev 427) +++ interpreter-3.x/trunk/kernel/runtime/Setup.cpp 2007-06-04 18:52:36 UTC (rev 428) @@ -482,6 +482,7 @@ CPPMSUP(RexxSupplier::next), CPPMSUP(RexxSupplier::value), CPPMSUP(RexxSupplier::index), +CPPMSUP(RexxSupplier::initRexx), CPPMSUPCL(RexxSupplierClass::newRexx), @@ -1473,6 +1474,7 @@ defineKernelMethod(CHAR_INDEX ,TheSupplierBehaviour, CPPMSUP(RexxSupplier::index), 0); defineKernelMethod(CHAR_NEXT ,TheSupplierBehaviour, CPPMSUP(RexxSupplier::next), 0); defineKernelMethod(CHAR_ITEM ,TheSupplierBehaviour, CPPMSUP(RexxSupplier::value), 0); + defineKernelMethod(CHAR_INIT ,TheSupplierBehaviour, CPPMSUP(RexxSupplier::initRexx), 2); /* set the scope of the methods to */ /* this classes oref */ @@ -1480,7 +1482,7 @@ /* Now call the class subclassable */ /* method */ - TheSupplierClass->subClassable("Supplier", true); + TheSupplierClass->subClassable("Supplier", false); /***************************************************************************/ /* TABLE */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2007-06-07 21:56:08
|
Revision: 439 http://svn.sourceforge.net/oorexx/?rev=439&view=rev Author: bigrixx Date: 2007-06-07 14:56:10 -0700 (Thu, 07 Jun 2007) Log Message: ----------- [ 1732747 ] Please add a method 'INSERT' to the Queue class Modified Paths: -------------- interpreter-3.x/trunk/kernel/classes/ListClass.cpp interpreter-3.x/trunk/kernel/classes/QueueClass.cpp interpreter-3.x/trunk/kernel/classes/QueueClass.hpp interpreter-3.x/trunk/kernel/runtime/Setup.cpp Modified: interpreter-3.x/trunk/kernel/classes/ListClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/ListClass.cpp 2007-06-07 18:47:44 UTC (rev 438) +++ interpreter-3.x/trunk/kernel/classes/ListClass.cpp 2007-06-07 21:56:10 UTC (rev 439) @@ -441,6 +441,7 @@ } } + RexxObject *RexxList::insertRexx( RexxObject *value, /* new value to add */ RexxObject *index) /* addition insertion index */ Modified: interpreter-3.x/trunk/kernel/classes/QueueClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/QueueClass.cpp 2007-06-07 18:47:44 UTC (rev 438) +++ interpreter-3.x/trunk/kernel/classes/QueueClass.cpp 2007-06-07 21:56:10 UTC (rev 439) @@ -177,6 +177,81 @@ return (RexxObject *)result; /* return this item */ } + +/** + * Insert an item into the queue at a specific index position. + * + * @param value The value to insert. + * @param index The index. This can be omitted, which inserts at the end, .nil + * which inserts at the beginning, or a valid existing index. + * + * @return The inserted object's index. + */ +RexxObject *RexxQueue::insert(RexxObject *value, RexxObject *index) +{ + LISTENTRY *element; /* list element */ + LISTENTRY *new_element; /* new insertion element */ + long new_index; /* index of new inserted item */ + + required_arg(value, ONE); /* must have a value to insert */ + + /* make sure we have room to insert */ + new_index = this->getFree(); + /* point to the actual element */ + new_element = ENTRY_POINTER(new_index); + if (index == TheNilObject) /* inserting at the front? */ + element = NULL; /* flag this as new */ + else if (index == OREF_NULL) { /* inserting at the end? */ + if (this->last == LIST_END) /* currently empty? */ + element = NULL; /* just use the front insert code */ + else /* insert after the last element */ + element = ENTRY_POINTER(this->last); + } + else { + /* locate this entry */ + element = this->locateEntry(index, IntegerTwo); + if (element == NULL) /* index doesn't exist? */ + /* raise an error */ + report_exception1(Error_Incorrect_method_queue_index, index); + } + this->count++; /* increase our count */ + /* set the value */ + OrefSet(this->table, new_element->value, value); + if (element == NULL) { /* adding at the front */ + if (this->last == LIST_END) { /* first element added? */ + this->first = new_index; /* set this as the first */ + this->last = new_index; /* and the last */ + new_element->next = LIST_END; /* this is the last element */ + new_element->previous = LIST_END;/* in both directions */ + } + else { /* adding at the front */ + + new_element->next = this->first; /* previous is current first */ + new_element->previous = LIST_END;/* nothing before this */ + /* point to the first element */ + element = ENTRY_POINTER(this->first); + element->previous = new_index; /* point it at the new entry */ + this->first = new_index; /* this is the new first element */ + } + } + else { /* have a real insertion point */ + /* set the next pointer */ + new_element->previous = ENTRY_INDEX(element); + + if (element->next == LIST_END) /* inserting at the end? */ + this->last = new_index; /* new first element */ + else /* fudge the next element */ + ENTRY_POINTER(element->next)->previous = new_index; + new_element->next = element->next; /* insert after this element */ + element->next = new_index; /* new following one */ + /* point at the insertion point */ + new_element->previous = ENTRY_INDEX(element); + } + /* return this index item */ + return (RexxObject *)new_integer(entryToIndex(new_index)); +} + + RexxObject *RexxQueue::remove(RexxObject *index) /******************************************************************************/ /* Function: Remove a given queue item */ Modified: interpreter-3.x/trunk/kernel/classes/QueueClass.hpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/QueueClass.hpp 2007-06-07 18:47:44 UTC (rev 438) +++ interpreter-3.x/trunk/kernel/classes/QueueClass.hpp 2007-06-07 21:56:10 UTC (rev 439) @@ -73,6 +73,7 @@ RexxObject *next(RexxObject *); RexxObject *previous(RexxObject *); long entryToIndex(long target); + RexxObject *insert(RexxObject *, RexxObject *); inline RexxObject *pop() { return this->removeFirst();}; inline void push(RexxObject *obj) { this->addFirst(obj);}; Modified: interpreter-3.x/trunk/kernel/runtime/Setup.cpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/Setup.cpp 2007-06-07 18:47:44 UTC (rev 438) +++ interpreter-3.x/trunk/kernel/runtime/Setup.cpp 2007-06-07 21:56:10 UTC (rev 439) @@ -332,6 +332,7 @@ CPPML(RexxQueue::lastRexx), CPPML(RexxQueue::next), CPPML(RexxQueue::previous), +CPPML(RexxQueue::insert), CPPMQ(RexxQueue::newRexx), CPPMQ(RexxQueue::ofRexx), @@ -1072,6 +1073,7 @@ defineKernelMethod(CHAR_LAST ,TheQueueBehaviour, CPPMQ(RexxQueue::lastRexx), 0); defineKernelMethod(CHAR_NEXT ,TheQueueBehaviour, CPPMQ(RexxQueue::next), 1); defineKernelMethod(CHAR_PREVIOUS ,TheQueueBehaviour, CPPMQ(RexxQueue::previous), 1); + defineKernelMethod(CHAR_INSERT ,TheQueueBehaviour, CPPML(RexxQueue::insert), 2); /* set the scope of the methods to */ /* this classes oref */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2007-06-12 15:06:59
|
Revision: 460 http://svn.sourceforge.net/oorexx/?rev=460&view=rev Author: bigrixx Date: 2007-06-12 08:06:57 -0700 (Tue, 12 Jun 2007) Log Message: ----------- [ 1735294 ] Wrong symbol serving as label on END ? Modified Paths: -------------- interpreter-3.x/trunk/kernel/messages/DocErrorMessages.sgml interpreter-3.x/trunk/kernel/messages/rexxmsg.xml interpreter-3.x/trunk/kernel/platform/windows/winmsgtb.rc Modified: interpreter-3.x/trunk/kernel/messages/DocErrorMessages.sgml =================================================================== --- interpreter-3.x/trunk/kernel/messages/DocErrorMessages.sgml 2007-06-12 13:58:41 UTC (rev 459) +++ interpreter-3.x/trunk/kernel/messages/DocErrorMessages.sgml 2007-06-12 15:06:57 UTC (rev 460) @@ -255,7 +255,7 @@ <varlistentry> <term>002</term> <listitem> -<para>Symbol following END ("<emphasis>symbol</emphasis>") must either match control variable or LABEL of block specification ("<emphasis>control_variable</emphasis>" on line <emphasis>line_number</emphasis>) or be omitted</para> +<para>Symbol following END ("<emphasis>symbol</emphasis>") must match block specification name ("<emphasis>control_variable</emphasis>") on line <emphasis>line_number</emphasis> or be omitted</para> </listitem> </varlistentry> <varlistentry> @@ -267,7 +267,7 @@ <varlistentry> <term>004</term> <listitem> -<para>Symbol following END ("<emphasis>symbol</emphasis>") must match LABEL of SELECT specification ("<emphasis>control_variable</emphasis>" on line <emphasis>line_number</emphasis>) or be omitted</para> +<para>Symbol following END ("<emphasis>symbol</emphasis>") must match LABEL of SELECT specification ("<emphasis>control_variable</emphasis>") on line <emphasis>line_number</emphasis> or be omitted</para> </listitem> </varlistentry> <varlistentry> Modified: interpreter-3.x/trunk/kernel/messages/rexxmsg.xml =================================================================== --- interpreter-3.x/trunk/kernel/messages/rexxmsg.xml 2007-06-12 13:58:41 UTC (rev 459) +++ interpreter-3.x/trunk/kernel/messages/rexxmsg.xml 2007-06-12 15:06:57 UTC (rev 460) @@ -332,7 +332,7 @@ <Component>Rexx</Component> <Severity>Warning</Severity> <SymbolicName>Error_Unexpected_end_control</SymbolicName> - <Text>Symbol following END (<q><Sub position="1" name="symbol"/></q>) must either match control variable or LABEL of block specification (<q><Sub position="2" name="control_variable"/></q> on line <Sub position="3" name="line_number"/>) or be omitted</Text> + <Text>Symbol following END (<q><Sub position="1" name="symbol"/></q>) must match block specification name (<q><Sub position="2" name="control_variable"/></q>) on line <Sub position="3" name="line_number"/> or be omitted</Text> </SubMessage> <SubMessage> <Code>10</Code> @@ -368,7 +368,7 @@ <Component>Rexx</Component> <Severity>Warning</Severity> <SymbolicName>Error_Unexpected_end_select</SymbolicName> - <Text>Symbol following END (<q><Sub position="1" name="symbol"/></q>) must match LABEL of SELECT specification (<q><Sub position="2" name="control_variable"/></q> on line <Sub position="3" name="line_number"/>) or be omitted</Text> + <Text>Symbol following END (<q><Sub position="1" name="symbol"/></q>) must match LABEL of SELECT specification (<q><Sub position="2" name="control_variable"/></q>) on line <Sub position="3" name="line_number"/> or be omitted</Text> </SubMessage> <SubMessage> <Code>10</Code> Modified: interpreter-3.x/trunk/kernel/platform/windows/winmsgtb.rc =================================================================== --- interpreter-3.x/trunk/kernel/platform/windows/winmsgtb.rc 2007-06-12 13:58:41 UTC (rev 459) +++ interpreter-3.x/trunk/kernel/platform/windows/winmsgtb.rc 2007-06-12 15:06:57 UTC (rev 460) @@ -150,11 +150,11 @@ Error_Unexpected_when_when "WHEN has no corresponding SELECT" Error_Unexpected_when_otherwise "OTHERWISE has no corresponding SELECT" Error_Unexpected_end_nodo "END has no corresponding DO or SELECT" - Error_Unexpected_end_control "Symbol following END (""&1"") must either match control variable or LABEL of block specification (""&2"" on line &3) or be omitted" + Error_Unexpected_end_control "Symbol following END (""&1"") must match block specification name (""&2"") on line &3 or be omitted" Error_Unexpected_end_nocontrol "END corresponding to block on line &2 must not have a symbol following it because there is no LABEL or control variable; found ""&1""" Error_Unexpected_end_then "END must not immediately follow THEN" Error_Unexpected_end_else "END must not immediately follow ELSE" - Error_Unexpected_end_select "Symbol following END (""&1"") must match LABEL of SELECT specification (""&2"" on line &3) or be omitted" + Error_Unexpected_end_select "Symbol following END (""&1"") must match LABEL of SELECT specification (""&2"") on line &3 or be omitted" Error_Control_stack_full "Insufficient control stack space; cannot continue execution" Error_Invalid_character_char "Incorrect character in program ""&1"" ('&2'X)" Error_Incomplete_do_do "DO instruction on line &1 requires matching END" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2007-06-13 21:34:57
|
Revision: 468 http://svn.sourceforge.net/oorexx/?rev=468&view=rev Author: bigrixx Date: 2007-06-13 14:34:59 -0700 (Wed, 13 Jun 2007) Log Message: ----------- [ 1736555 ] Add/Enchance Operators Modified Paths: -------------- interpreter-3.x/trunk/kernel/parser/InstructionParser.cpp interpreter-3.x/trunk/kernel/parser/Scanner.cpp interpreter-3.x/trunk/kernel/parser/SourceFile.cpp interpreter-3.x/trunk/kernel/parser/SourceFile.hpp interpreter-3.x/trunk/kernel/parser/Token.cpp interpreter-3.x/trunk/kernel/parser/Token.hpp interpreter-3.x/trunk/kernel/runtime/GlobalNames.h interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp Modified: interpreter-3.x/trunk/kernel/parser/InstructionParser.cpp =================================================================== --- interpreter-3.x/trunk/kernel/parser/InstructionParser.cpp 2007-06-13 21:12:11 UTC (rev 467) +++ interpreter-3.x/trunk/kernel/parser/InstructionParser.cpp 2007-06-13 21:34:59 UTC (rev 468) @@ -59,6 +59,7 @@ #include "SourceFile.hpp" /* this is part of source */ #include "ExpressionMessage.hpp" +#include "ExpressionOperator.hpp" #include "RexxInstruction.hpp" /* base REXX instruction class */ #include "AssignmentInstruction.hpp" /* keyword <expression> instructions */ @@ -177,6 +178,37 @@ return (RexxInstruction *)newObject; /* done, return this */ } + +/** + * Create a special assignment op of the form "variable (op)= expr". + * + * @param target The assignment target variable. + * @param operation The operator token. classId is TOKEN_ASSIGNMENT, the subclass + * is the type of the operation to perform. + * + * @return The constructed instruction object. + */ +RexxInstruction *RexxSource::assignmentOpNew(RexxToken *target, RexxToken *operation) +{ + this->needVariable(target); // make sure this is a variable + // we require an expression for the additional part, which is required + RexxObject *expression = this->expression(TERM_EOC); + if (expression == OREF_NULL) + { + report_error(Error_Invalid_expression_assign); + } + + // we need an evaluator for both the expression and the assignment + RexxObject *variable = addText(target); + // now add a binary operator to this expression tree + expression = (RexxObject *)new RexxBinaryOperator(operation->subclass, variable, expression); + + // now everything is the same as an assignment operator + RexxObject *newObject = new_instruction(ASSIGNMENT, Assignment); + new ((void *)newObject) RexxInstructionAssignment((RexxVariableBase *)variable, expression); + return (RexxInstruction *)newObject; /* done, return this */ +} + RexxInstruction *RexxSource::callNew() /****************************************************************************/ /* Function: Create a new CALL translator object */ @@ -1158,6 +1190,38 @@ return (RexxInstruction *)newObject; /* done, return this */ } + +/** + * Create a message term pseudo assignment instruction for a + * shortcut operator. The instruction is of the form + * "messageTerm (op)= expr". + * + * @param message The target message term. + * @param operation The operation to perform in the expansion. + * @param expression The expression (which is the right-hand term of the eventual + * expression). + * + * @return The constructed message operator. + */ +RexxInstruction *RexxSource::messageAssignmentOpNew(RexxExpressionMessage *message, RexxToken *operation, RexxObject *expression) +{ + hold(message); // lock this temporarily + // make a copy of the message term for use in the expression + RexxObject *retriever = message->copy(); + + message->makeAssignment(this); // convert into an assignment message (the original message term) + + // now add a binary operator to this expression tree + expression = (RexxObject *)new RexxBinaryOperator(operation->subclass, retriever, expression); + + // allocate a new object. NB: a message instruction gets an extra argument, so we don't subtract one. + RexxObject *newObject = new_variable_instruction(MESSAGE, Message, sizeof(RexxInstructionMessage) + (message->argumentCount) * sizeof(OREF)); + /* Initialize this new method */ + new ((void *)newObject) RexxInstructionMessage(message, expression); + return (RexxInstruction *)newObject; /* done, return this */ +} + + RexxInstruction *RexxSource::nopNew() /****************************************************************************/ /* Function: Create a NOP instruction object */ Modified: interpreter-3.x/trunk/kernel/parser/Scanner.cpp =================================================================== --- interpreter-3.x/trunk/kernel/parser/Scanner.cpp 2007-06-13 21:12:11 UTC (rev 467) +++ interpreter-3.x/trunk/kernel/parser/Scanner.cpp 2007-06-13 21:34:59 UTC (rev 468) @@ -435,6 +435,7 @@ #define GETCHAR() ((UCHAR)(this->current[this->line_offset])) #define MORELINE() (this->line_offset < this->current_length) #define OPERATOR(op) (this->clause->newToken(TOKEN_OPERATOR, OPERATOR_##op, (RexxString *)OREF_##op, &location)) +#define CHECK_ASSIGNMENT(op, token) (token->checkAssignment(this, (RexxString *)OREF_ASSIGNMENT_##op)) void RexxSource::endLocation( LOCATIONINFO *location ) /* token location information */ @@ -1302,73 +1303,85 @@ case '+': /* plus sign */ /* addition operator */ token = OPERATOR(PLUS); /* this is an operator class */ + CHECK_ASSIGNMENT(PLUS, token); // this is allowed as an assignment shortcut break; case '-': /* minus sign */ /* subtraction operator */ token = OPERATOR(SUBTRACT); /* this is an operator class */ + CHECK_ASSIGNMENT(SUBTRACT, token); // this is allowed as an assignment shortcut break; case '%': /* percent sign */ /* integer divide operator */ token = OPERATOR(INTDIV); /* this is an operator class */ + CHECK_ASSIGNMENT(INTDIV, token); // this is allowed as an assignment shortcut break; case '/': /* forward slash */ -#ifdef NONSAA - /* next one an equal sign? */ - if (this->nextSpecial('=', &location)) { - /* have an equal sign after that? */ - if (this->nextSpecial('=', &location)) - /* this is the /== operator */ - token = OPERATOR(STRICT_BACKSLASH_EQUAL); - else /* this is the /= operator */ - token = OPERATOR(BACKSLASH_EQUAL); - } - /* next one a slash also? */ - else if (this->nextSpecial('/', &location)) - /* this is the remainder operator */ - token = OPERATOR(REMAINDER); - else - token = OPERATOR(DIVIDE); /* this is the divide operator */ - break; -#else /* this is division */ /* next one a slash also? */ if (this->nextSpecial('/', &location)) + { + + token = OPERATOR(REMAINDER); + CHECK_ASSIGNMENT(REMAINDER, token); // this is allowed as an assignment shortcut + } /* this is an operator class */ - token = OPERATOR(REMAINDER); else - token = OPERATOR(DIVIDE); /* this is an operator class */ + { + token = OPERATOR(DIVIDE); /* this is an operator class */ + CHECK_ASSIGNMENT(DIVIDE, token); // this is allowed as an assignment shortcut + } break; -#endif case '*': /* asterisk? */ /* this is multiply */ /* next one a star also? */ if (this->nextSpecial('*', &location)) - token = OPERATOR(POWER); /* this is an operator class */ + { + token = OPERATOR(POWER); /* this is an operator class */ + CHECK_ASSIGNMENT(POWER, token); // this is allowed as an assignment shortcut + } else /* this is an operator class */ - token = OPERATOR(MULTIPLY); + { + + token = OPERATOR(MULTIPLY); + CHECK_ASSIGNMENT(MULTIPLY, token); // this is allowed as an assignment shortcut + } break; case '&': /* ampersand? */ /* this is the and operator */ /* next one an ampersand also? */ if (this->nextSpecial('&', &location)) - token = OPERATOR(XOR); /* this is an operator class */ + { + + token = OPERATOR(XOR); /* this is an operator class */ + CHECK_ASSIGNMENT(XOR, token); // this is allowed as an assignment shortcut + } else /* this is an operator class */ - token = OPERATOR(AND); + { + token = OPERATOR(AND); + CHECK_ASSIGNMENT(AND, token); // this is allowed as an assignment shortcut + } break; case '|': /* vertical bar? */ /* this is an or operator */ /* next one a vertical bar also? */ if (this->nextSpecial('|', &location)) + { /* this is a concatenation */ - token = OPERATOR(CONCATENATE); + token = OPERATOR(CONCATENATE); + CHECK_ASSIGNMENT(CONCATENATE, token); // this is allowed as an assignment shortcut + } else /* this is an operator class */ - token = OPERATOR(OR); /* this is the OR operator */ + { + + token = OPERATOR(OR); /* this is the OR operator */ + CHECK_ASSIGNMENT(OR, token); // this is allowed as an assignment shortcut + } break; case '=': /* equal sign? */ Modified: interpreter-3.x/trunk/kernel/parser/SourceFile.cpp =================================================================== --- interpreter-3.x/trunk/kernel/parser/SourceFile.cpp 2007-06-13 21:12:11 UTC (rev 467) +++ interpreter-3.x/trunk/kernel/parser/SourceFile.cpp 2007-06-13 21:34:59 UTC (rev 468) @@ -2400,287 +2400,335 @@ /* Function: Process an individual REXX clause */ /******************************************************************************/ { - RexxToken *first; /* first token of clause */ - RexxToken *second; /* second token of clause */ - RexxInstruction *instruction; /* current working instruction */ - RexxObject *term; /* term for a message send */ - RexxObject *subexpression; /* subexpression of a clause */ - INT keyword; /* resolved instruction keyword */ + RexxToken *first; /* first token of clause */ + RexxToken *second; /* second token of clause */ + RexxInstruction *instruction; /* current working instruction */ + RexxObject *term; /* term for a message send */ + RexxObject *subexpression; /* subexpression of a clause */ + INT keyword; /* resolved instruction keyword */ - instruction = OREF_NULL; /* default to no instruction found */ - first = nextReal(); /* get the first token */ + instruction = OREF_NULL; /* default to no instruction found */ + first = nextReal(); /* get the first token */ - if (first->classId == TOKEN_DCOLON) {/* reached the end of a block? */ - firstToken(); /* reset the location */ - this->reclaimClause(); /* give back the clause */ - } - else { /* have a real instruction to process*/ - second = nextToken(); /* now get the second token */ - /* is this a label? (can be either */ - /* a symbol or a literal) */ - if ((first->classId == TOKEN_SYMBOL || first->classId == TOKEN_LITERAL) && second->classId == TOKEN_COLON) { - if (this->flags&_interpret) /* is this an interpret? */ - /* this is an error */ - report_error_token(Error_Unexpected_label_interpret, first); - firstToken(); /* reset to the beginning */ - instruction = this->labelNew(); /* create a label instruction */ - second = nextToken(); /* get the next token */ - /* not the end of the clause? */ - if (second->classId != TOKEN_EOC) { - previousToken(); /* give this token back */ - trimClause(); /* make this start of the clause */ - this->reclaimClause(); /* give the remaining clause back */ - } + if (first->classId == TOKEN_DCOLON) + {/* reached the end of a block? */ + firstToken(); /* reset the location */ + this->reclaimClause(); /* give back the clause */ } - /* is this an invalid assignment */ - /* (symbol followed by ==) */ - else if (first->classId == TOKEN_SYMBOL && second->subclass == OPERATOR_STRICT_EQUAL) - /* this is an invalid expression */ - report_error_token(Error_Invalid_expression_general, second); - /* is this an assignment (symbol */ - /* followed by an equal sign?) */ - else if (first->classId == TOKEN_SYMBOL && second->subclass == OPERATOR_EQUAL) { - /* create the clause */ - instruction = this->assignmentNew(first); - } - else { /* some other type of instruction */ - /* we need to skip over the first */ - /* term of the instruction to */ - /* determine the type of clause, */ - /* including recognition of keyword */ - /* instructions */ - firstToken(); /* reset to the first token */ - term = this->messageTerm(); /* get the first term of instruction */ - second = nextToken(); /* get the next token */ - /* have some form of message term? */ - if (term != OREF_NULL && second->classId == TOKEN_EOC) - /* create a message send instruction */ - instruction = this->messageNew((RexxExpressionMessage *)term); - else if (term != OREF_NULL && second->subclass == OPERATOR_STRICT_EQUAL) - /* this is an invalid expression */ - report_error_token(Error_Invalid_expression_general, second); - else if (term != OREF_NULL && second->subclass == OPERATOR_EQUAL) { - this->saveObject(term); /* protect this */ - /* parse off the subexpression */ - subexpression = this->subExpression(TERM_EOC); - if (subexpression == OREF_NULL)/* nothing there? */ - /* have an error */ - report_error_token(Error_Invalid_expression_general, second); - /* create a message send instruction */ - instruction = this->messageAssignmentNew((RexxExpressionMessage *)term, subexpression); - this->toss(term); /* release the term */ - } - /* still not good? */ - else { /* ok, now we can look for keywords */ + else + { /* have a real instruction to process*/ + second = nextToken(); /* now get the second token */ + /* is this a label? (can be either */ + /* a symbol or a literal) */ + if ((first->classId == TOKEN_SYMBOL || first->classId == TOKEN_LITERAL) && second->classId == TOKEN_COLON) + { + if (this->flags&_interpret) /* is this an interpret? */ + /* this is an error */ + report_error_token(Error_Unexpected_label_interpret, first); + firstToken(); /* reset to the beginning */ + instruction = this->labelNew(); /* create a label instruction */ + second = nextToken(); /* get the next token */ + /* not the end of the clause? */ + if (second->classId != TOKEN_EOC) + { + previousToken(); /* give this token back */ + trimClause(); /* make this start of the clause */ + this->reclaimClause(); /* give the remaining clause back */ + } + return instruction; + } + + // this is potentially an assignment of the form "symbol = expr" + if (first->classId == TOKEN_SYMBOL) + { + // "symbol == expr" is considered an error + if (second->subclass == OPERATOR_STRICT_EQUAL) + { + report_error_token(Error_Invalid_expression_general, second); + } + // true assignment instruction? + if (second->subclass == OPERATOR_EQUAL) + { + return this->assignmentNew(first); + } + // this could be a special assignment operator such as "symbol += expr" + else if (second->classId == TOKEN_ASSIGNMENT) + { + return this->assignmentOpNew(first, second); + } + // other + + } + + /* some other type of instruction */ + /* we need to skip over the first */ + /* term of the instruction to */ + /* determine the type of clause, */ + /* including recognition of keyword */ + /* instructions */ + firstToken(); /* reset to the first token */ + term = this->messageTerm(); /* get the first term of instruction */ + second = nextToken(); /* get the next token */ + + + // some sort of recognizable message term? Need to check for the + // special cases. + if (term != OREF_NULL) + { + // if parsing the message term consumed everything, this is a message instruction + if (second->classId == TOKEN_EOC) + { + return this->messageNew((RexxExpressionMessage *)term); + } + else if (second->subclass == OPERATOR_STRICT_EQUAL) + { + // messageterm == something is an invalid assignment + report_error_token(Error_Invalid_expression_general, second); + } + // messageterm = something is a pseudo assignment + else if (second->subclass == OPERATOR_EQUAL) + { + this->saveObject(term); /* protect this */ + // we need an expression following the op token + subexpression = this->subExpression(TERM_EOC); + if (subexpression == OREF_NULL) + { + report_error_token(Error_Invalid_expression_general, second); + } + // this is a message assignment + instruction = this->messageAssignmentNew((RexxExpressionMessage *)term, subexpression); + this->toss(term); /* release the term */ + return instruction; + } + // one of the special operator forms? + else if (second->classId == TOKEN_ASSIGNMENT) + { + this->saveObject(term); /* protect this */ + // we need an expression following the op token + subexpression = this->subExpression(TERM_EOC); + if (subexpression == OREF_NULL) + { + report_error_token(Error_Invalid_expression_general, second); + } + // this is a message assignment + instruction = this->messageAssignmentOpNew((RexxExpressionMessage *)term, second, subexpression); + this->toss(term); /* release the term */ + return instruction; + } + } + + // ok, none of the special cases passed....not start the keyword processing + firstToken(); /* reset to the first token */ first = nextToken(); /* get the first token again */ /* is first a symbol that matches a */ /* defined REXX keyword? */ - if (first->classId == TOKEN_SYMBOL && (keyword = this->keyword(first))) { + if (first->classId == TOKEN_SYMBOL && (keyword = this->keyword(first))) + { - switch (keyword) { /* process each instruction type */ + switch (keyword) + { /* process each instruction type */ - case KEYWORD_NOP: /* NOP instruction */ - /* add the instruction to the parse */ - instruction = this->nopNew(); - break; + case KEYWORD_NOP: /* NOP instruction */ + /* add the instruction to the parse */ + instruction = this->nopNew(); + break; - case KEYWORD_DROP: /* DROP instruction */ - /* add the instruction to the parse */ - instruction = this->dropNew(); - break; + case KEYWORD_DROP: /* DROP instruction */ + /* add the instruction to the parse */ + instruction = this->dropNew(); + break; - case KEYWORD_SIGNAL: /* various forms of SIGNAL */ - /* add the instruction to the parse */ - instruction = this->signalNew(); - break; + case KEYWORD_SIGNAL: /* various forms of SIGNAL */ + /* add the instruction to the parse */ + instruction = this->signalNew(); + break; - case KEYWORD_CALL: /* various forms of CALL */ - /* add the instruction to the parse */ - instruction = this->callNew(); - break; + case KEYWORD_CALL: /* various forms of CALL */ + /* add the instruction to the parse */ + instruction = this->callNew(); + break; - case KEYWORD_RAISE: /* RAISE instruction */ - /* add the instruction to the parse */ - instruction = this->raiseNew(); - break; + case KEYWORD_RAISE: /* RAISE instruction */ + /* add the instruction to the parse */ + instruction = this->raiseNew(); + break; - case KEYWORD_ADDRESS: /* ADDRESS instruction */ - /* add the instruction to the parse */ - instruction = this->addressNew(); - break; + case KEYWORD_ADDRESS: /* ADDRESS instruction */ + /* add the instruction to the parse */ + instruction = this->addressNew(); + break; - case KEYWORD_NUMERIC: /* NUMERIC instruction */ - /* add the instruction to the parse */ - instruction = this->numericNew(); - break; + case KEYWORD_NUMERIC: /* NUMERIC instruction */ + /* add the instruction to the parse */ + instruction = this->numericNew(); + break; - case KEYWORD_TRACE: /* TRACE instruction */ - /* add the instruction to the parse */ - instruction = this->traceNew(); - break; + case KEYWORD_TRACE: /* TRACE instruction */ + /* add the instruction to the parse */ + instruction = this->traceNew(); + break; - case KEYWORD_DO: /* all variations of DO instruction */ - /* add the instruction to the parse */ - instruction = this->doNew(); - break; + case KEYWORD_DO: /* all variations of DO instruction */ + /* add the instruction to the parse */ + instruction = this->doNew(); + break; - case KEYWORD_LOOP: /* all variations of LOOP instruction */ - /* add the instruction to the parse */ - instruction = this->loopNew(); - break; + case KEYWORD_LOOP: /* all variations of LOOP instruction */ + /* add the instruction to the parse */ + instruction = this->loopNew(); + break; - case KEYWORD_EXIT: /* EXIT instruction */ - /* add the instruction to the parse */ - instruction = this->exitNew(); - break; + case KEYWORD_EXIT: /* EXIT instruction */ + /* add the instruction to the parse */ + instruction = this->exitNew(); + break; - case KEYWORD_INTERPRET: /* INTERPRET instruction */ - /* add the instruction to the parse */ - instruction = this->interpretNew(); - break; + case KEYWORD_INTERPRET: /* INTERPRET instruction */ + /* add the instruction to the parse */ + instruction = this->interpretNew(); + break; - case KEYWORD_PUSH: /* PUSH instruction */ - /* add the instruction to the parse */ - instruction = this->queueNew(QUEUE_LIFO); - break; + case KEYWORD_PUSH: /* PUSH instruction */ + /* add the instruction to the parse */ + instruction = this->queueNew(QUEUE_LIFO); + break; - case KEYWORD_QUEUE: /* QUEUE instruction */ - /* add the instruction to the parse */ - instruction = this->queueNew(QUEUE_FIFO); - break; + case KEYWORD_QUEUE: /* QUEUE instruction */ + /* add the instruction to the parse */ + instruction = this->queueNew(QUEUE_FIFO); + break; - case KEYWORD_REPLY: /* REPLY instruction */ - /* interpreted? */ - if (this->flags&_interpret) - report_error(Error_Translation_reply_interpret); - /* add the instruction to the parse */ - instruction = this->replyNew(); - break; + case KEYWORD_REPLY: /* REPLY instruction */ + /* interpreted? */ + if (this->flags&_interpret) + report_error(Error_Translation_reply_interpret); + /* add the instruction to the parse */ + instruction = this->replyNew(); + break; - case KEYWORD_RETURN: /* RETURN instruction */ - /* add the instruction to the parse */ - instruction = this->returnNew(); - break; + case KEYWORD_RETURN: /* RETURN instruction */ + /* add the instruction to the parse */ + instruction = this->returnNew(); + break; - case KEYWORD_IF: /* IF instruction */ - /* add the instruction to the parse */ - instruction = this->ifNew(KEYWORD_IF); - break; + case KEYWORD_IF: /* IF instruction */ + /* add the instruction to the parse */ + instruction = this->ifNew(KEYWORD_IF); + break; - case KEYWORD_ITERATE: /* ITERATE instruction */ - /* add the instruction to the parse */ - instruction = this->leaveNew(KEYWORD_ITERATE); - break; + case KEYWORD_ITERATE: /* ITERATE instruction */ + /* add the instruction to the parse */ + instruction = this->leaveNew(KEYWORD_ITERATE); + break; - case KEYWORD_LEAVE: /* LEAVE instruction */ - /* add the instruction to the parse */ - instruction = this->leaveNew(KEYWORD_LEAVE); - break; + case KEYWORD_LEAVE: /* LEAVE instruction */ + /* add the instruction to the parse */ + instruction = this->leaveNew(KEYWORD_LEAVE); + break; - case KEYWORD_EXPOSE: /* EXPOSE instruction */ - /* interpreted? */ - if (this->flags&_interpret) - report_error(Error_Translation_expose_interpret); - /* add the instruction to the parse */ - instruction = this->exposeNew(); - break; + case KEYWORD_EXPOSE: /* EXPOSE instruction */ + /* interpreted? */ + if (this->flags&_interpret) + report_error(Error_Translation_expose_interpret); + /* add the instruction to the parse */ + instruction = this->exposeNew(); + break; - case KEYWORD_FORWARD: /* FORWARD instruction */ - /* interpreted? */ - if (this->flags&_interpret) - report_error(Error_Translation_forward_interpret); - /* add the instruction to the parse */ - instruction = this->forwardNew(); - break; + case KEYWORD_FORWARD: /* FORWARD instruction */ + /* interpreted? */ + if (this->flags&_interpret) + report_error(Error_Translation_forward_interpret); + /* add the instruction to the parse */ + instruction = this->forwardNew(); + break; - case KEYWORD_PROCEDURE: /* PROCEDURE instruction */ - /* add the instruction to the parse */ - instruction = this->procedureNew(); - break; + case KEYWORD_PROCEDURE: /* PROCEDURE instruction */ + /* add the instruction to the parse */ + instruction = this->procedureNew(); + break; - case KEYWORD_GUARD: /* GUARD instruction */ - /* interpreted? */ - if (this->flags&_interpret) - report_error(Error_Translation_guard_interpret); - /* add the instruction to the parse */ - instruction = this->guardNew(); - break; + case KEYWORD_GUARD: /* GUARD instruction */ + /* interpreted? */ + if (this->flags&_interpret) + report_error(Error_Translation_guard_interpret); + /* add the instruction to the parse */ + instruction = this->guardNew(); + break; - case KEYWORD_USE: /* USE instruction */ - /* interpreted? */ - if (this->flags&_interpret) - report_error(Error_Translation_use_interpret); - /* add the instruction to the parse */ - instruction = this->useNew(); - break; + case KEYWORD_USE: /* USE instruction */ + /* interpreted? */ + if (this->flags&_interpret) + report_error(Error_Translation_use_interpret); + /* add the instruction to the parse */ + instruction = this->useNew(); + break; - case KEYWORD_ARG: /* ARG instruction */ - /* add the instruction to the parse */ - instruction = this->parseNew(SUBKEY_ARG); - break; + case KEYWORD_ARG: /* ARG instruction */ + /* add the instruction to the parse */ + instruction = this->parseNew(SUBKEY_ARG); + break; - case KEYWORD_PULL: /* PULL instruction */ - /* add the instruction to the parse */ - instruction = this->parseNew(SUBKEY_PULL); - break; + case KEYWORD_PULL: /* PULL instruction */ + /* add the instruction to the parse */ + instruction = this->parseNew(SUBKEY_PULL); + break; - case KEYWORD_PARSE: /* PARSE instruction */ - /* add the instruction to the parse */ - instruction = this->parseNew(KEYWORD_PARSE); - break; + case KEYWORD_PARSE: /* PARSE instruction */ + /* add the instruction to the parse */ + instruction = this->parseNew(KEYWORD_PARSE); + break; - case KEYWORD_SAY: /* SAY instruction */ - /* add the instruction to the parse */ - instruction = this->sayNew(); - break; + case KEYWORD_SAY: /* SAY instruction */ + /* add the instruction to the parse */ + instruction = this->sayNew(); + break; - case KEYWORD_OPTIONS: /* OPTIONS instruction */ - /* add the instruction to the parse */ - instruction = this->optionsNew(); - break; + case KEYWORD_OPTIONS: /* OPTIONS instruction */ + /* add the instruction to the parse */ + instruction = this->optionsNew(); + break; - case KEYWORD_SELECT: /* SELECT instruction */ - /* add the instruction to the parse */ - instruction = this->selectNew(); - break; + case KEYWORD_SELECT: /* SELECT instruction */ + /* add the instruction to the parse */ + instruction = this->selectNew(); + break; - case KEYWORD_WHEN: /* WHEN in an SELECT instruction */ - /* add the instruction to the parse */ - instruction = this->ifNew(KEYWORD_WHEN); - break; + case KEYWORD_WHEN: /* WHEN in an SELECT instruction */ + /* add the instruction to the parse */ + instruction = this->ifNew(KEYWORD_WHEN); + break; - case KEYWORD_OTHERWISE: /* OTHERWISE in a SELECT */ - /* add the instruction to the parse */ - instruction = this->otherwiseNew(first); - break; + case KEYWORD_OTHERWISE: /* OTHERWISE in a SELECT */ + /* add the instruction to the parse */ + instruction = this->otherwiseNew(first); + break; - case KEYWORD_ELSE: /* unexpected ELSE */ - /* add the instruction to the parse */ - instruction = this->elseNew(first); - break; + case KEYWORD_ELSE: /* unexpected ELSE */ + /* add the instruction to the parse */ + instruction = this->elseNew(first); + break; - case KEYWORD_END: /* END for a block construct */ - /* add the instruction to the parse */ - instruction = this->endNew(); - break; + case KEYWORD_END: /* END for a block construct */ + /* add the instruction to the parse */ + instruction = this->endNew(); + break; - case KEYWORD_THEN: /* unexpected THEN */ - /* raise an error */ - report_error(Error_Unexpected_then_then); - break; + case KEYWORD_THEN: /* unexpected THEN */ + /* raise an error */ + report_error(Error_Unexpected_then_then); + break; - } + } } - else { /* this is a "command" instruction */ - firstToken(); /* reset to the first token */ - /* process this instruction */ - instruction = this->commandNew(); + else + { /* this is a "command" instruction */ + firstToken(); /* reset to the first token */ + /* process this instruction */ + instruction = this->commandNew(); } - } } - } - return instruction; /* return the created instruction */ + return instruction; /* return the created instruction */ } RexxVariableBase *RexxSource::addVariable( @@ -3275,6 +3323,12 @@ this->pushTerm(right); /* add the term to the term stack */ break; + case TOKEN_ASSIGNMENT: + // special assignment token in a bad context. We report this as an error. + /* this is an invalid expression */ + report_error_token(Error_Invalid_expression_general, token); + break; + case TOKEN_COMMA: /* found a comma in the expression */ /* should have been trapped as an */ /* expression terminator, so this is */ Modified: interpreter-3.x/trunk/kernel/parser/SourceFile.hpp =================================================================== --- interpreter-3.x/trunk/kernel/parser/SourceFile.hpp 2007-06-13 21:12:11 UTC (rev 467) +++ interpreter-3.x/trunk/kernel/parser/SourceFile.hpp 2007-06-13 21:34:59 UTC (rev 468) @@ -209,6 +209,7 @@ RexxInstruction *addressNew(); RexxInstruction *assignmentNew(RexxToken *); + RexxInstruction *assignmentOpNew(RexxToken *, RexxToken *); RexxInstruction *callNew(); RexxInstruction *commandNew(); RexxInstruction *doNew(); @@ -231,6 +232,7 @@ RexxInstruction *leaveNew(INT); RexxInstruction *messageNew(RexxExpressionMessage *); RexxInstruction *messageAssignmentNew(RexxExpressionMessage *, RexxObject *); + RexxInstruction *messageAssignmentOpNew(RexxExpressionMessage *, RexxToken *, RexxObject *); RexxInstruction *nopNew(); RexxInstruction *numericNew(); RexxInstruction *optionsNew(); Modified: interpreter-3.x/trunk/kernel/parser/Token.cpp =================================================================== --- interpreter-3.x/trunk/kernel/parser/Token.cpp 2007-06-13 21:12:11 UTC (rev 467) +++ interpreter-3.x/trunk/kernel/parser/Token.cpp 2007-06-13 21:34:59 UTC (rev 468) @@ -46,6 +46,7 @@ #include "RexxCore.h" #include "StringClass.hpp" #include "Token.hpp" +#include "SourceFile.hpp" RexxToken::RexxToken( int classId, /* class of token */ @@ -124,6 +125,26 @@ } /* endif */ } + +/** + * Check and update this token for the special assignment forms + * (+=, -=, etc.). + * + * @param source The source for the original operator token. + */ +void RexxToken::checkAssignment(RexxSource *source, RexxString *newValue) +{ + // check if the next character is a special assignment shortcut + if (source->nextSpecial('=', &location)) + { + // this is a special type, which uses the same subtype. + classId = TOKEN_ASSIGNMENT; + // this is the new string value of the token + value = newValue; + } +} + + void *RexxToken::operator new(size_t size) /******************************************************************************/ /* Function: Create a new token object */ Modified: interpreter-3.x/trunk/kernel/parser/Token.hpp =================================================================== --- interpreter-3.x/trunk/kernel/parser/Token.hpp 2007-06-13 21:12:11 UTC (rev 467) +++ interpreter-3.x/trunk/kernel/parser/Token.hpp 2007-06-13 21:34:59 UTC (rev 468) @@ -88,6 +88,7 @@ #define TOKEN_SQRIGHT TOKEN_SQLEFT + 1 #define TOKEN_DCOLON TOKEN_SQRIGHT + 1 #define TOKEN_CONTINUE TOKEN_DCOLON + 1 +#define TOKEN_ASSIGNMENT TOKEN_CONTINUE + 1 /* token extended types - symbols */ #define SYMBOL_CONSTANT 1251 @@ -135,6 +136,7 @@ #define OPERATOR_XOR OPERATOR_OR + 1 #define OPERATOR_BACKSLASH OPERATOR_XOR + 1 + /* token extended types - instruction keywords */ #define KEYWORD_ADDRESS 1 #define KEYWORD_ARG KEYWORD_ADDRESS + 1 @@ -407,6 +409,7 @@ inline void setNumeric(INT value) { this->numeric = value; }; inline void getLocation(PLOCATIONINFO location) { *location = this->location; } inline void setLocation(PLOCATIONINFO location) { this->location = *location; } + void checkAssignment(RexxSource *source, RexxString *newValue); LOCATIONINFO location; /* token source location */ RexxString *value; /* token string value */ Modified: interpreter-3.x/trunk/kernel/runtime/GlobalNames.h =================================================================== --- interpreter-3.x/trunk/kernel/runtime/GlobalNames.h 2007-06-13 21:12:11 UTC (rev 467) +++ interpreter-3.x/trunk/kernel/runtime/GlobalNames.h 2007-06-13 21:34:59 UTC (rev 468) @@ -47,6 +47,7 @@ GLOBAL_NAME(ADDITIONAL, CHAR_ADDITIONAL) GLOBAL_NAME(ADDRESS, CHAR_ADDRESS) GLOBAL_NAME(AND, CHAR_AND) + GLOBAL_NAME(ASSIGNMENT_AND, CHAR_ASSIGNMENT_AND) GLOBAL_NAME(ANY, CHAR_ANY) GLOBAL_NAME(ARGUMENTS, CHAR_ARGUMENTS) GLOBAL_NAME(ARRAYSYM, CHAR_ARRAY) @@ -67,12 +68,14 @@ GLOBAL_NAME(COMPARE, CHAR_COMPARE) GLOBAL_NAME(COMPARETO, CHAR_COMPARETO) GLOBAL_NAME(CONCATENATE, CHAR_CONCATENATE) + GLOBAL_NAME(ASSIGNMENT_CONCATENATE, CHAR_ASSIGNMENT_CONCATENATE) GLOBAL_NAME(CONDITION, CHAR_CONDITION) GLOBAL_NAME(CSELF, CHAR_CSELF) GLOBAL_NAME(DEFAULTNAME, CHAR_DEFAULTNAME) GLOBAL_NAME(DELAY, CHAR_DELAY) GLOBAL_NAME(DESCRIPTION, CHAR_DESCRIPTION) GLOBAL_NAME(DIVIDE, CHAR_DIVIDE) + GLOBAL_NAME(ASSIGNMENT_DIVIDE, CHAR_ASSIGNMENT_DIVIDE) GLOBAL_NAME(DSOM, CHAR_DSOM) GLOBAL_NAME(ENGINEERING, CHAR_ENGINEERING) GLOBAL_NAME(ENVIRONMENT, CHAR_ENVIRONMENT) @@ -98,6 +101,7 @@ GLOBAL_NAME(INSERT, CHAR_INSERT) GLOBAL_NAME(INSTRUCTION, CHAR_INSTRUCTION) GLOBAL_NAME(INTDIV, CHAR_INTDIV) + GLOBAL_NAME(ASSIGNMENT_INTDIV, CHAR_ASSIGNMENT_INTDIV) GLOBAL_NAME(LESSTHAN, CHAR_LESSTHAN) GLOBAL_NAME(LESSTHAN_EQUAL, CHAR_LESSTHAN_EQUAL) GLOBAL_NAME(LESSTHAN_GREATERTHAN, CHAR_LESSTHAN_GREATERTHAN) @@ -112,6 +116,7 @@ GLOBAL_NAME(METHODNAME, CHAR_METHODNAME) GLOBAL_NAME(METHODS, CHAR_METHODS) GLOBAL_NAME(MULTIPLY, CHAR_MULTIPLY) + GLOBAL_NAME(ASSIGNMENT_MULTIPLY, CHAR_ASSIGNMENT_MULTIPLY) GLOBAL_NAME(NAME, CHAR_NAME) GLOBAL_NAME(NAME_MESSAGE, CHAR_MESSAGE) GLOBAL_NAME(NEW, CHAR_NEW) @@ -125,11 +130,14 @@ GLOBAL_NAME(OFF, CHAR_OFF) GLOBAL_NAME(ON, CHAR_ON) GLOBAL_NAME(OR, CHAR_OR) + GLOBAL_NAME(ASSIGNMENT_OR, CHAR_ASSIGNMENT_OR) GLOBAL_NAME(OUTPUT, CHAR_OUTPUT) GLOBAL_NAME(PERIOD, CHAR_PERIOD) GLOBAL_NAME(PLUS, CHAR_PLUS) + GLOBAL_NAME(ASSIGNMENT_PLUS, CHAR_ASSIGNMENT_PLUS) GLOBAL_NAME(POSITION, CHAR_POSITION) GLOBAL_NAME(POWER, CHAR_POWER) + GLOBAL_NAME(ASSIGNMENT_POWER, CHAR_ASSIGNMENT_POWER) GLOBAL_NAME(PROGRAM, CHAR_PROGRAM) GLOBAL_NAME(PROPAGATE, CHAR_PROPAGATE) GLOBAL_NAME(PROPAGATED, CHAR_PROPAGATED) @@ -141,6 +149,7 @@ GLOBAL_NAME(QUERY, CHAR_QUERY) GLOBAL_NAME(RC, CHAR_RC) GLOBAL_NAME(REMAINDER, CHAR_REMAINDER) + GLOBAL_NAME(ASSIGNMENT_REMAINDER, CHAR_ASSIGNMENT_REMAINDER) GLOBAL_NAME(REQUEST, CHAR_REQUEST) GLOBAL_NAME(REQUIRES, CHAR_REQUIRES) GLOBAL_NAME(RESULT, CHAR_RESULT) @@ -184,6 +193,7 @@ GLOBAL_NAME(STRINGSYM, CHAR_STRINGSYM) GLOBAL_NAME(SUBROUTINE, CHAR_SUBROUTINE) GLOBAL_NAME(SUBTRACT, CHAR_SUBTRACT) + GLOBAL_NAME(ASSIGNMENT_SUBTRACT, CHAR_ASSIGNMENT_SUBTRACT) GLOBAL_NAME(SUPER, CHAR_SUPER) GLOBAL_NAME(SUPPLIERSYM, CHAR_SUPPLIER) GLOBAL_NAME(SYNTAX, CHAR_SYNTAX) @@ -198,5 +208,6 @@ GLOBAL_NAME(VERSION, CHAR_VERSION) GLOBAL_NAME(WPS, CHAR_WPS) GLOBAL_NAME(XOR, CHAR_XOR) + GLOBAL_NAME(ASSIGNMENT_XOR, CHAR_ASSIGNMENT_XOR) GLOBAL_NAME(ZERO_STRING, CHAR_ZERO) Modified: interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp 2007-06-13 21:12:11 UTC (rev 467) +++ interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp 2007-06-13 21:34:59 UTC (rev 468) @@ -382,6 +382,7 @@ /* Language operators */ CHARCONSTANT(AND, "&"); +CHARCONSTANT(ASSIGNMENT_AND, "&="); CHARCONSTANT(BACKSLASH, "\\"); CHARCONSTANT(BACKSLASH_EQUAL, "\\="); CHARCONSTANT(BACKSLASH_GREATERTHAN, "\\>"); @@ -389,20 +390,28 @@ CHARCONSTANT(BRACKETS, "[]"); CHARCONSTANT(BRACKETSEQUAL, "[]="); CHARCONSTANT(CONCATENATE, "||"); +CHARCONSTANT(ASSIGNMENT_CONCATENATE, "||="); CHARCONSTANT(DIVIDE, "/"); +CHARCONSTANT(ASSIGNMENT_DIVIDE, "/="); CHARCONSTANT(EQUAL, "="); CHARCONSTANT(GREATERTHAN, ">"); CHARCONSTANT(GREATERTHAN_EQUAL, ">="); CHARCONSTANT(GREATERTHAN_LESSTHAN, "><"); CHARCONSTANT(INTDIV, "%"); +CHARCONSTANT(ASSIGNMENT_INTDIV, "%="); CHARCONSTANT(LESSTHAN, "<"); CHARCONSTANT(LESSTHAN_EQUAL, "<="); CHARCONSTANT(LESSTHAN_GREATERTHAN, "<>"); CHARCONSTANT(MULTIPLY, "*"); +CHARCONSTANT(ASSIGNMENT_MULTIPLY, "*="); CHARCONSTANT(OR, "|"); +CHARCONSTANT(ASSIGNMENT_OR, "|="); CHARCONSTANT(PLUS, "+"); +CHARCONSTANT(ASSIGNMENT_PLUS, "+="); CHARCONSTANT(POWER, "**"); +CHARCONSTANT(ASSIGNMENT_POWER, "**="); CHARCONSTANT(REMAINDER, "//"); +CHARCONSTANT(ASSIGNMENT_REMAINDER, "//="); CHARCONSTANT(STRICT_BACKSLASH_EQUAL, "\\=="); CHARCONSTANT(STRICT_BACKSLASH_GREATERTHAN, "\\>>"); CHARCONSTANT(STRICT_BACKSLASH_LESSTHAN, "\\<<"); @@ -412,7 +421,9 @@ CHARCONSTANT(STRICT_LESSTHAN, "<<"); CHARCONSTANT(STRICT_LESSTHAN_EQUAL, "<<="); CHARCONSTANT(SUBTRACT, "-"); +CHARCONSTANT(ASSIGNMENT_SUBTRACT, "-="); CHARCONSTANT(XOR, "&&"); +CHARCONSTANT(ASSIGNMENT_XOR, "&&="); CHARCONSTANT(ELLIPSIS, "..."); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2007-06-14 12:53:47
|
Revision: 472 http://svn.sourceforge.net/oorexx/?rev=472&view=rev Author: bigrixx Date: 2007-06-14 05:53:38 -0700 (Thu, 14 Jun 2007) Log Message: ----------- Add an identityHash method that will return a unique hash value for each object instance. Modified Paths: -------------- interpreter-3.x/trunk/kernel/classes/ObjectClass.cpp interpreter-3.x/trunk/kernel/classes/ObjectClass.hpp interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp interpreter-3.x/trunk/kernel/runtime/Setup.cpp Modified: interpreter-3.x/trunk/kernel/classes/ObjectClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/ObjectClass.cpp 2007-06-14 06:13:55 UTC (rev 471) +++ interpreter-3.x/trunk/kernel/classes/ObjectClass.cpp 2007-06-14 12:53:38 UTC (rev 472) @@ -1892,6 +1892,20 @@ return OREF_NULL; /* this is basically a no-op */ } + +/** + * Return a unique identity hash value for this object. This + * hash will be unique among the set of currently active Rexx + * objects. + * + * @return The identity hash value as an integer object. + */ +RexxInteger *RexxObject::identityHashRexx() +{ + return new_integer(this->identityHash()); +} + + void RexxObject::uninit(void) /******************************************************************************/ /* Function: Exported Object INIT method */ Modified: interpreter-3.x/trunk/kernel/classes/ObjectClass.hpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/ObjectClass.hpp 2007-06-14 06:13:55 UTC (rev 471) +++ interpreter-3.x/trunk/kernel/classes/ObjectClass.hpp 2007-06-14 12:53:38 UTC (rev 472) @@ -101,6 +101,8 @@ virtual ULONG hash() { return HASHVALUE(this); } ULONG getHashValue() { return HASHVALUE(this); } + inline ULONG identityHash() { return HASHOREF(this); } + virtual BOOL truthValue(LONG); virtual RexxString *makeString(); virtual void copyIntoTail(RexxCompoundTail *buffer); @@ -281,6 +283,8 @@ RexxObject *strictEqual(RexxObject *); RexxInteger *strictNotEqual(RexxObject *other); + RexxInteger *identityHashRexx(); + RexxString *stringRexx(); RexxObject *makeStringRexx(); RexxObject *makeArrayRexx(); Modified: interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp 2007-06-14 06:13:55 UTC (rev 471) +++ interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp 2007-06-14 12:53:38 UTC (rev 472) @@ -292,19 +292,8 @@ CHARCONSTANT(SETUID, "SETUID"); CHARCONSTANT(SETUNGUARDED, "SETUNGUARDED"); CHARCONSTANT(SHORT, "SHORT"); -CHARCONSTANT(SHRIEKCLASS, "!CLASS"); -CHARCONSTANT(SHRIEKCLASS_IMPORT, "!CLASS_IMPORT"); -CHARCONSTANT(SHRIEKDUMP, "!DUMP"); -CHARCONSTANT(SHRIEKGUTCHECK, "!GUTCHECK"); -CHARCONSTANT(SHRIEKHASUNINIT, "!HASUNINIT"); -CHARCONSTANT(SHRIEKIMPORT, "!IMPORT"); -CHARCONSTANT(SHRIEKOREF, "!OREF"); CHARCONSTANT(SHRIEKREXXDEFINED, "!REXXDEFINED"); CHARCONSTANT(SHRIEKRUN, "!RUN"); -CHARCONSTANT(SHRIEKSERVER_WAIT, "!SERVER_WAIT"); -CHARCONSTANT(SHRIEK_STREAMS, "!STREAMS"); -CHARCONSTANT(SHRIEKSOMSERVER_INITDSOM, "!SOMSERVER_INITDSOM"); -CHARCONSTANT(SHRIEKSOMSERVER_INITDSOMWPS, "!SOMSERVER_INITDSOMWPS"); CHARCONSTANT(SIGL, "SIGL"); CHARCONSTANT(SIGNAL, "SIGNAL"); CHARCONSTANT(SIZE, "SIZE"); @@ -469,9 +458,8 @@ CHARCONSTANT(DIGITS, "DIGITS"); CHARCONSTANT(FORM, "FORM"); CHARCONSTANT(FORMAT, "FORMAT"); -CHARCONSTANT(SHRIEK_FORMAT, "!FORMAT"); -CHARCONSTANT(SHRIEK_TRUNC, "!TRUNC"); CHARCONSTANT(FUZZ, "FUZZ"); +CHARCONSTANT(IDENTITYHASH, "IDENTITYHASH"); CHARCONSTANT(INSERT, "INSERT"); CHARCONSTANT(LASTPOS, "LASTPOS"); CHARCONSTANT(LEFT, "LEFT"); Modified: interpreter-3.x/trunk/kernel/runtime/Setup.cpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/Setup.cpp 2007-06-14 06:13:55 UTC (rev 471) +++ interpreter-3.x/trunk/kernel/runtime/Setup.cpp 2007-06-14 12:53:38 UTC (rev 472) @@ -110,6 +110,7 @@ CPPM(RexxObject::freeSOMObjRexx), CPPM(RexxObject::SOMObjRexx), CPPM(RexxObject::serverRexx), +CPPM(RexxObject::identityHashRexx), CPPM(RexxObject::newRexx), @@ -800,6 +801,7 @@ defineKernelMethod(CHAR_ISA ,TheObjectBehaviour, CPPM(RexxObject::isInstanceOfRexx), 1); defineKernelMethod(CHAR_INSTANCEMETHOD ,TheObjectBehaviour, CPPM(RexxObject::instanceMethodRexx), 1); defineKernelMethod(CHAR_INSTANCEMETHODS ,TheObjectBehaviour, CPPM(RexxObject::instanceMethodsRexx), 1); + defineKernelMethod(CHAR_IDENTITYHASH ,TheObjectBehaviour, CPPM(RexxObject::identityHashRexx), 0); definePrivateKernelMethod(CHAR_RUN ,TheObjectBehaviour, CPPM(RexxObject::run), A_COUNT); definePrivateKernelMethod(CHAR_SETMETHOD ,TheObjectBehaviour, CPPM(RexxObject::setMethod), 3); definePrivateKernelMethod(CHAR_UNSETMETHOD ,TheObjectBehaviour, CPPM(RexxObject::unsetMethod), 1); @@ -1531,19 +1533,6 @@ /* These classes don't have any class methods */ /* and are not subclassed from object */ - /***************************************************************************/ - /* MEMORY */ - /***************************************************************************/ -#ifdef EXPOSE_MEMORY - defineKernelMethod(CHAR_RECLAIM,TheMemoryBehaviour, CPPMMEM(RexxMemory::reclaim), 0); - defineKernelMethod(CHAR_SETDUMP,TheMemoryBehaviour, CPPMMEM(RexxMemory::setDump), 1); - defineKernelMethod(CHAR_SETPARMS,TheMemoryBehaviour, CPPMMEM(RexxMemory::setParms), 2); - defineKernelMethod(CHAR_SHRIEKDUMP,TheMemoryBehaviour, CPPMMEM(RexxMemory::dump), 0); - defineKernelMethod(CHAR_SHRIEKGUTCHECK,TheMemoryBehaviour, CPPMMEM(RexxMemory::getCheck), 0); - /* set the scope of the methods to this classes oref */ - TheMemoryBehaviour->setMethodDictionaryScope(TheMemoryObject); -#endif - /* put the kernel-provided public objects in the environment directory */ kernel_public(CHAR_ARRAY ,TheArrayClass ,TheEnvironment); kernel_public(CHAR_CLASS ,TheClassClass ,TheEnvironment); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2007-06-15 13:15:57
|
Revision: 475 http://svn.sourceforge.net/oorexx/?rev=475&view=rev Author: bigrixx Date: 2007-06-15 06:15:59 -0700 (Fri, 15 Jun 2007) Log Message: ----------- [ 1737816 ] Add caseless versions of countstr() and changestr(). Modified Paths: -------------- interpreter-3.x/trunk/kernel/classes/StringClass.hpp interpreter-3.x/trunk/kernel/classes/StringClassMisc.cpp interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp interpreter-3.x/trunk/kernel/runtime/Setup.cpp Modified: interpreter-3.x/trunk/kernel/classes/StringClass.hpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/StringClass.hpp 2007-06-14 23:56:45 UTC (rev 474) +++ interpreter-3.x/trunk/kernel/classes/StringClass.hpp 2007-06-15 13:15:59 UTC (rev 475) @@ -184,6 +184,7 @@ /* the following methods are in */ /* OKBMISC */ RexxString *changeStr(RexxString *, RexxString *); + RexxString *caselessChangeStr(RexxString *, RexxString *); RexxInteger *abbrev(RexxString *, RexxInteger *); RexxInteger *compare(RexxString *, RexxString *); RexxString *copies(RexxInteger *); @@ -205,6 +206,8 @@ RexxInteger *verify(RexxString *, RexxString *, RexxInteger *); RexxInteger *countStrRexx(RexxString *); size_t countStr(RexxString *); + RexxInteger *caselessCountStrRexx(RexxString *); + size_t caselessCountStr(RexxString *); /* the following methods are in */ /* OKBBITS */ RexxString *bitAnd(RexxString *, RexxString *); Modified: interpreter-3.x/trunk/kernel/classes/StringClassMisc.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/StringClassMisc.cpp 2007-06-14 23:56:45 UTC (rev 474) +++ interpreter-3.x/trunk/kernel/classes/StringClassMisc.cpp 2007-06-15 13:15:59 UTC (rev 475) @@ -769,6 +769,41 @@ return new_integer(count); /* return the count as an object */ } +size_t RexxString::caselessCountStr(RexxString *needle) +/******************************************************************************/ +/* Function: Count occurrences of one string in another. */ +/******************************************************************************/ +{ + size_t count; /* count of strings */ + size_t match; /* last match position */ + size_t needlelength ; /* length of the needle */ + + count = 0; /* no matches yet */ + /* get the length of the needle */ + needlelength = needle->length; + /* get the first match position */ + match = this->caselessPos(needle, 0); + while (match != 0) { /* while we're getting matches */ + count = count + 1; /* count this match */ + /* do the next search */ + match = this->caselessPos(needle, match + needlelength - 1); + } + return count; /* return the match count */ +} + +RexxInteger *RexxString::caselessCountStrRexx(RexxString *needle) +/******************************************************************************/ +/* Function: Count occurrences of one string in another. */ +/******************************************************************************/ +{ + size_t count; /* count of strings */ + + /* force needle to a string */ + needle = REQUIRED_STRING(needle, ARG_ONE); + count = this->caselessCountStr(needle); /* do the counting */ + return new_integer(count); /* return the count as an object */ +} + RexxString *RexxString::changeStr(RexxString *needle, RexxString *newNeedle) /******************************************************************************/ @@ -822,6 +857,60 @@ return result; /* finished */ } +RexxString *RexxString::caselessChangeStr(RexxString *needle, + RexxString *newNeedle) +/******************************************************************************/ +/* Function: Change strings into another string. */ +/******************************************************************************/ +{ + size_t start; /* converted start position */ + size_t match; /* last match position */ + size_t needleLength; /* length of the needle */ + size_t newLength; /* length of the replacement string */ + size_t matches; /* number of replacements */ + size_t copyLength; /* length to copy */ + PCHAR source; /* point to the string source */ + PCHAR copy; /* current copy position */ + PCHAR newPtr; /* pointer to replacement data */ + RexxString *result; /* returned result string */ + /* force needle to a string */ + needle = REQUIRED_STRING(needle, ARG_ONE); + /* newneedle must be a string two */ + newNeedle = REQUIRED_STRING(newNeedle, ARG_TWO); + matches = this->caselessCountStr(needle); /* find the number of replacements */ + needleLength = needle->length; /* get the length of the needle */ + newLength = newNeedle->length; /* and the replacement length */ + /* get a proper sized string */ + result = (RexxString *)raw_string(this->length - (matches * needleLength) + (matches * newLength)); + copy = result->stringData; /* point to the copy location */ + source = this->stringData; /* and out own data */ + /* and the string to replace */ + newPtr = newNeedle->stringData; + start = 0; /* set a zero starting point */ + for (;;) { /* loop forever */ + match = this->caselessPos(needle, start); /* look for the next occurrence */ + if (match == 0) /* not found? */ + break; /* get out of here */ + copyLength = (match - 1) - start; /* get the next length to copy */ + if (copyLength != 0) { /* something to copy? */ + /* add on the next string section */ + memcpy(copy, source + start, copyLength); + copy += copyLength; /* step over the copied part */ + } + if (newLength != 0) { /* something to replace with? */ + memcpy(copy, newPtr, newLength); /* copy over the new segment */ + copy += newLength; /* and step it over also */ + } + start = match + needleLength - 1; /* step to the next position */ + } + if (start < this->length) /* some remainder left? */ + /* add it on */ + memcpy(copy, source + start, this->length - start); + result->generateHash(); /* now finishe off this string */ + return result; /* finished */ +} + + RexxInteger *RexxString::posRexx( RexxString *needle, /* search string */ RexxInteger *pstart) /* starting position */ Modified: interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp 2007-06-14 23:56:45 UTC (rev 474) +++ interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp 2007-06-15 13:15:59 UTC (rev 475) @@ -431,12 +431,14 @@ CHARCONSTANT(CENTER, "CENTER"); CHARCONSTANT(CENTRE, "CENTRE"); CHARCONSTANT(CHANGESTR, "CHANGESTR"); +CHARCONSTANT(CASELESSCHANGESTR, "CASELESSCHANGESTR"); CHARCONSTANT(CHARIN, "CHARIN"); CHARCONSTANT(CHAROUT, "CHAROUT"); CHARCONSTANT(CHARS, "CHARS"); CHARCONSTANT(COMPARE, "COMPARE"); CHARCONSTANT(COPIES, "COPIES"); CHARCONSTANT(COUNTSTR, "COUNTSTR"); +CHARCONSTANT(CASELESSCOUNTSTR, "CASELESSCOUNTSTR"); CHARCONSTANT(D2C, "D2C"); CHARCONSTANT(D2X, "D2X"); CHARCONSTANT(DATATYPE, "DATATYPE"); Modified: interpreter-3.x/trunk/kernel/runtime/Setup.cpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/Setup.cpp 2007-06-14 23:56:45 UTC (rev 474) +++ interpreter-3.x/trunk/kernel/runtime/Setup.cpp 2007-06-15 13:15:59 UTC (rev 475) @@ -419,7 +419,9 @@ /* following methods are in OKBMISC */ CPPMSTR(RexxString::changeStr), +CPPMSTR(RexxString::caselessChangeStr), CPPMSTR(RexxString::countStrRexx), +CPPMSTR(RexxString::caselessCountStrRexx), CPPMSTR(RexxString::abbrev), CPPMSTR(RexxString::compare), CPPMSTR(RexxString::copies), @@ -1218,9 +1220,11 @@ defineKernelMethod(CHAR_WORDS ,TheStringBehaviour, CPPMSTR(RexxString::words), 0); defineKernelMethod(CHAR_ABBREV ,TheStringBehaviour, CPPMSTR(RexxString::abbrev), 2); defineKernelMethod(CHAR_CHANGESTR ,TheStringBehaviour, CPPMSTR(RexxString::changeStr), 2); + defineKernelMethod(CHAR_CASELESSCHANGESTR ,TheStringBehaviour, CPPMSTR(RexxString::caselessChangeStr), 2); defineKernelMethod(CHAR_COMPARE ,TheStringBehaviour, CPPMSTR(RexxString::compare), 2); defineKernelMethod(CHAR_COPIES ,TheStringBehaviour, CPPMSTR(RexxString::copies), 1); defineKernelMethod(CHAR_COUNTSTR ,TheStringBehaviour, CPPMSTR(RexxString::countStrRexx), 1); + defineKernelMethod(CHAR_CASELESSCOUNTSTR ,TheStringBehaviour, CPPMSTR(RexxString::caselessCountStrRexx), 1); defineKernelMethod(CHAR_LASTPOS ,TheStringBehaviour, CPPMSTR(RexxString::lastPosRexx), 2); defineKernelMethod(CHAR_POS ,TheStringBehaviour, CPPMSTR(RexxString::posRexx), 2); defineKernelMethod(CHAR_CASELESSLASTPOS ,TheStringBehaviour, CPPMSTR(RexxString::caselessLastPosRexx), 2); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2007-06-21 14:04:23
|
Revision: 488 http://svn.sourceforge.net/oorexx/?rev=488&view=rev Author: bigrixx Date: 2007-06-21 07:04:24 -0700 (Thu, 21 Jun 2007) Log Message: ----------- [ 1740585 ] Stem default value bug Modified Paths: -------------- interpreter-3.x/trunk/kernel/classes/StemClass.cpp interpreter-3.x/trunk/kernel/messages/DocErrorMessages.sgml interpreter-3.x/trunk/kernel/messages/RexxErrorCodes.h interpreter-3.x/trunk/kernel/messages/RexxMessageNumbers.h interpreter-3.x/trunk/kernel/messages/RexxMessageTable.h interpreter-3.x/trunk/kernel/messages/rexxmsg.xml interpreter-3.x/trunk/kernel/platform/windows/winmsgtb.rc Modified: interpreter-3.x/trunk/kernel/classes/StemClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/StemClass.cpp 2007-06-21 12:55:18 UTC (rev 487) +++ interpreter-3.x/trunk/kernel/classes/StemClass.cpp 2007-06-21 14:04:24 UTC (rev 488) @@ -350,6 +350,10 @@ report_exception1(Error_Incorrect_method_noarg, IntegerOne); if (argCount == 1) { /* just setting the default value? */ + if (OTYPE(Stem, new_value)) // stem value as default? don't allow this as it leads to recursion loops + { + report_exception(Error_Execution_nostem); + } /* set the new default value */ OrefSet(this, this->value, new_value); this->tails.clear(); /* clear out the dictionary */ Modified: interpreter-3.x/trunk/kernel/messages/DocErrorMessages.sgml =================================================================== --- interpreter-3.x/trunk/kernel/messages/DocErrorMessages.sgml 2007-06-21 12:55:18 UTC (rev 487) +++ interpreter-3.x/trunk/kernel/messages/DocErrorMessages.sgml 2007-06-21 14:04:24 UTC (rev 488) @@ -3312,6 +3312,12 @@ </para> </listitem> </varlistentry> +<varlistentry> +<term>976</term> +<listitem> +<para>Stem object default value cannot be another stem object</para> +</listitem> +</varlistentry> </variablelist> </section> <section id="ERR99"> Modified: interpreter-3.x/trunk/kernel/messages/RexxErrorCodes.h =================================================================== --- interpreter-3.x/trunk/kernel/messages/RexxErrorCodes.h 2007-06-21 12:55:18 UTC (rev 487) +++ interpreter-3.x/trunk/kernel/messages/RexxErrorCodes.h 2007-06-21 14:04:24 UTC (rev 488) @@ -531,6 +531,7 @@ #define Error_Invalid_data_type_for_objspec 98974 #define Error_Execution_class_server_not_installed 98952 #define Error_Execution_sparse_array 98975 +#define Error_Execution_nostem 98976 #define Error_Translation 99000 #define Error_Translation_user_defined 99900 #define Error_Translation_duplicate_class 99901 Modified: interpreter-3.x/trunk/kernel/messages/RexxMessageNumbers.h =================================================================== --- interpreter-3.x/trunk/kernel/messages/RexxMessageNumbers.h 2007-06-21 12:55:18 UTC (rev 487) +++ interpreter-3.x/trunk/kernel/messages/RexxMessageNumbers.h 2007-06-21 14:04:24 UTC (rev 488) @@ -594,6 +594,7 @@ #define Error_Invalid_whole_number_compare_msg 667 #define Error_Execution_sparse_array_msg 668 #define Error_Incorrect_method_queue_index_msg 669 +#define Error_Execution_nostem_msg 670 #endif Modified: interpreter-3.x/trunk/kernel/messages/RexxMessageTable.h =================================================================== --- interpreter-3.x/trunk/kernel/messages/RexxMessageTable.h 2007-06-21 12:55:18 UTC (rev 487) +++ interpreter-3.x/trunk/kernel/messages/RexxMessageTable.h 2007-06-21 14:04:24 UTC (rev 488) @@ -533,6 +533,7 @@ MINOR(Error_Invalid_data_type_for_objspec) MINOR(Error_Execution_class_server_not_installed) MINOR(Error_Execution_sparse_array) + MINOR(Error_Execution_nostem) MAJOR(Error_Translation) MINOR(Error_Translation_user_defined) MINOR(Error_Translation_duplicate_class) Modified: interpreter-3.x/trunk/kernel/messages/rexxmsg.xml =================================================================== --- interpreter-3.x/trunk/kernel/messages/rexxmsg.xml 2007-06-21 12:55:18 UTC (rev 487) +++ interpreter-3.x/trunk/kernel/messages/rexxmsg.xml 2007-06-21 14:04:24 UTC (rev 488) @@ -4555,6 +4555,15 @@ <SymbolicName>Error_Execution_sparse_array</SymbolicName> <Text>Missing array element at position <Sub position="1" name="position"/></Text> </SubMessage> + <SubMessage> + <Code>98</Code> + <Subcode>976</Subcode> + <MessageNumber>670</MessageNumber> + <Component>Rexx</Component> + <Severity>Error</Severity> + <SymbolicName>Error_Execution_nostem</SymbolicName> + <Text>Stem object default value cannot be another stem object</Text> + </SubMessage> </Subcodes> </Message> <Message> Modified: interpreter-3.x/trunk/kernel/platform/windows/winmsgtb.rc =================================================================== --- interpreter-3.x/trunk/kernel/platform/windows/winmsgtb.rc 2007-06-21 12:55:18 UTC (rev 487) +++ interpreter-3.x/trunk/kernel/platform/windows/winmsgtb.rc 2007-06-21 14:04:24 UTC (rev 488) @@ -594,6 +594,7 @@ Error_Invalid_whole_number_compare "Result of a COMPARE method call did not result in a whole number; found ""&1""" Error_Execution_sparse_array "Missing array element at position &1" Error_Incorrect_method_queue_index "Incorrect queue index ""&1""" + Error_Execution_nostem "Stem object default value cannot be another stem object" END This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2007-06-22 18:19:04
|
Revision: 498 http://svn.sourceforge.net/oorexx/?rev=498&view=rev Author: bigrixx Date: 2007-06-22 11:19:05 -0700 (Fri, 22 Jun 2007) Log Message: ----------- [ 1741618 ] Please add method 'caselessWordPos' to the String class Modified Paths: -------------- interpreter-3.x/trunk/kernel/classes/StringClass.hpp interpreter-3.x/trunk/kernel/classes/StringClassWord.cpp interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp interpreter-3.x/trunk/kernel/runtime/Setup.cpp Modified: interpreter-3.x/trunk/kernel/classes/StringClass.hpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/StringClass.hpp 2007-06-22 15:31:46 UTC (rev 497) +++ interpreter-3.x/trunk/kernel/classes/StringClass.hpp 2007-06-22 18:19:05 UTC (rev 498) @@ -180,6 +180,7 @@ RexxInteger *wordIndex(RexxInteger *); RexxInteger *wordLength(RexxInteger *); RexxInteger *wordPos(RexxString *, RexxInteger *); + RexxInteger *caselessWordPos(RexxString *, RexxInteger *); RexxInteger *words(); /* the following methods are in */ /* OKBMISC */ Modified: interpreter-3.x/trunk/kernel/classes/StringClassWord.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/StringClassWord.cpp 2007-06-22 15:31:46 UTC (rev 497) +++ interpreter-3.x/trunk/kernel/classes/StringClassWord.cpp 2007-06-22 18:19:05 UTC (rev 498) @@ -649,6 +649,102 @@ return Retval; /* return the position */ } + +RexxInteger *RexxString::caselessWordPos(RexxString *phrase, RexxInteger *pstart) +{ + phrase = get_string(phrase, ARG_ONE);/* get the phrase we are looking for */ + stringsize_t needleLength = phrase->length; /* get the length also */ + /* get starting position, the default*/ + /* is the first word */ + stringsize_t count = optional_position(pstart, 1, ARG_TWO); + + stringchar_t *needle = (stringchar_t *)phrase->getStringData(); /* get friendly pointer */ + stringchar_t *haystack = (stringchar_t *)this->getStringData(); /* and the second also */ + stringsize_t haystackLength = this->length; /* get the haystack length */ + /* count the words in needle */ + stringsize_t needleWords = WordCount((PCHAR)needle, needleLength); + /* and haystack */ + stringsize_t haystackWords = WordCount((PCHAR)haystack, haystackLength); + /* if search string is longer */ + /* or no words in search */ + /* or count is longer than */ + /* haystack, this is a failure */ + if (needleWords > (haystackWords - count + 1) || needleWords == 0 || count > haystackWords) + { + return IntegerZero; + } + + stringchar_t *nextHaystack; + stringchar_t *nextNeedle; + /* point at first word */ + stringsize_t haystackWordLength = NextWord((PCHAR *)&haystack, &haystackLength, (PCHAR *)&nextHaystack); + /* now skip over count-1 */ + for (stringsize_t i = count - 1; i && haystackWordLength != 0; i--) + { + haystack = nextHaystack; /* step past current word */ + /* find the next word */ + haystackWordLength = NextWord((PCHAR *)&haystack, &haystackLength, (PCHAR *)&nextHaystack); + } + /* get number of searches */ + stringsize_t searchCount = (haystackWords - needleWords - count) + 2; + /* position at first needle */ + stringsize_t firstNeedle = NextWord((PCHAR *)&needle, &needleLength, (PCHAR *)&nextNeedle); + /* loop for the possible times */ + for (; searchCount; searchCount--) + { + stringsize_t needleWordLength = firstNeedle; /* set the length */ + stringchar_t *needlePosition = needle; /* get the start of phrase */ + stringchar_t *haystackPosition = haystack; /* and the target string loop */ + /* for needlewords */ + stringchar_t *nextHaystackPtr = nextHaystack; /* copy nextword information */ + stringchar_t *nextNeedlePtr = nextNeedle; + /* including the lengths */ + stringsize_t haystackScanLength = haystackLength; + stringsize_t needleScanLength = needleLength; + + stringsize_t i; + + for (i = needleWords; i; i--) + { + // length mismatch, can't be a match + + if (haystackWordLength != needleWordLength) + { + break; + } + + // now compare the two words, using a caseless comparison + // if the words don't match, terminate now + if (CaselessCompare(needlePosition, haystackPosition, needleWordLength)) + { + break; /* get out fast. */ + } + + /* the last words matched, so */ + /* continue searching. */ + + /* set new search information */ + haystackPosition = nextHaystackPtr; + needlePosition = nextNeedlePtr; + /* Scan off the next word */ + haystackWordLength = NextWord((PCHAR *)&haystackPosition, &haystackScanLength, (PCHAR *)&nextHaystackPtr); + /* repeat for the needle */ + needleWordLength = NextWord((PCHAR *)&needlePosition, &needleScanLength, (PCHAR *)&nextNeedlePtr); + } + + if (i == 0) /* all words matched, we */ + { + return new_integer(count); // return the position + } + haystack = nextHaystack; /* set the search position */ + /* step to next haytack pos */ + haystackWordLength = NextWord((PCHAR *)&haystack, &haystackLength, (PCHAR *)&nextHaystack); + count++; /* remember the word position */ + } + + return IntegerZero; // not found +} + /* the WORDS function */ /******************************************************************************/ /* Arguments: none */ Modified: interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp 2007-06-22 15:31:46 UTC (rev 497) +++ interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp 2007-06-22 18:19:05 UTC (rev 498) @@ -496,6 +496,7 @@ CHARCONSTANT(WORDINDEX, "WORDINDEX"); CHARCONSTANT(WORDLENGTH, "WORDLENGTH"); CHARCONSTANT(WORDPOS, "WORDPOS"); +CHARCONSTANT(CASELESSWORDPOS, "CASELESSWORDPOS"); CHARCONSTANT(WORDS, "WORDS"); CHARCONSTANT(X2B, "X2B"); CHARCONSTANT(X2C, "X2C"); Modified: interpreter-3.x/trunk/kernel/runtime/Setup.cpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/Setup.cpp 2007-06-22 15:31:46 UTC (rev 497) +++ interpreter-3.x/trunk/kernel/runtime/Setup.cpp 2007-06-22 18:19:05 UTC (rev 498) @@ -413,6 +413,7 @@ CPPMSTR(RexxString::wordIndex), CPPMSTR(RexxString::wordLength), CPPMSTR(RexxString::wordPos), +CPPMSTR(RexxString::caselessWordPos), CPPMSTR(RexxString::words), /* following methods are in OKBMISC */ @@ -1215,6 +1216,7 @@ defineKernelMethod(CHAR_WORDINDEX ,TheStringBehaviour, CPPMSTR(RexxString::wordIndex), 1); defineKernelMethod(CHAR_WORDLENGTH ,TheStringBehaviour, CPPMSTR(RexxString::wordLength), 1); defineKernelMethod(CHAR_WORDPOS ,TheStringBehaviour, CPPMSTR(RexxString::wordPos), 2); + defineKernelMethod(CHAR_CASELESSWORDPOS ,TheStringBehaviour, CPPMSTR(RexxString::caselessWordPos), 2); defineKernelMethod(CHAR_WORDS ,TheStringBehaviour, CPPMSTR(RexxString::words), 0); defineKernelMethod(CHAR_ABBREV ,TheStringBehaviour, CPPMSTR(RexxString::abbrev), 2); defineKernelMethod(CHAR_CHANGESTR ,TheStringBehaviour, CPPMSTR(RexxString::changeStr), 2); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2007-06-24 21:15:09
|
Revision: 501 http://svn.sourceforge.net/oorexx/?rev=501&view=rev Author: bigrixx Date: 2007-06-24 14:15:09 -0700 (Sun, 24 Jun 2007) Log Message: ----------- [ 1742538 ] Please add method "caselessCompare" to "String" class Modified Paths: -------------- interpreter-3.x/trunk/kernel/classes/StringClass.hpp interpreter-3.x/trunk/kernel/classes/StringClassMisc.cpp interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp interpreter-3.x/trunk/kernel/runtime/Setup.cpp Modified: interpreter-3.x/trunk/kernel/classes/StringClass.hpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/StringClass.hpp 2007-06-24 04:24:11 UTC (rev 500) +++ interpreter-3.x/trunk/kernel/classes/StringClass.hpp 2007-06-24 21:15:09 UTC (rev 501) @@ -188,6 +188,7 @@ RexxString *caselessChangeStr(RexxString *, RexxString *); RexxInteger *abbrev(RexxString *, RexxInteger *); RexxInteger *compare(RexxString *, RexxString *); + RexxInteger *caselessCompare(RexxString *, RexxString *); RexxString *copies(RexxInteger *); RexxObject *dataType(RexxString *); Modified: interpreter-3.x/trunk/kernel/classes/StringClassMisc.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/StringClassMisc.cpp 2007-06-24 04:24:11 UTC (rev 500) +++ interpreter-3.x/trunk/kernel/classes/StringClassMisc.cpp 2007-06-24 21:15:09 UTC (rev 501) @@ -419,6 +419,7 @@ return (rc) ? IntegerOne : IntegerZero; } + RexxInteger *RexxString::compare( RexxString *string2, /* other string to compare against */ RexxString *pad) /* optional padding character */ @@ -484,6 +485,70 @@ return Retval; /* return result string */ } + +/** + * Caseless version of the compare() method. + * + * @param string2 The string to compare to. + * @param pad The padding character used for length mismatches. + * + * @return 0 if the two strings are equal (with padding applied), otherwise + * it returns the mismatch position. + */ +RexxInteger *RexxString::caselessCompare(RexxString *other, RexxString *pad) +{ + stringsize_t length1 = this->getLength(); /* get this strings length */ + /* validate the compare string */ + other = get_string(other, ARG_ONE); + stringsize_t length2 = other->getLength(); /* get the length also */ + // we uppercase the pad character now since this is caseless + stringchar_t padChar = toupper(get_pad(pad, ' ', ARG_TWO)); + + stringchar_t *string1; + stringchar_t *string2; + stringsize_t lead; + stringsize_t remainder; + + // is the first longer? + if (length1 > length2) + { + string1 = (stringchar_t *)this->getStringData(); /* make arg 1 first string */ + /* arg 2 is second string */ + string2 = (stringchar_t *)other->getStringData(); + lead = length2; /* get shorter length */ + remainder = length1 - lead; /* get trailing size */ + } + else + { + string1 = (stringchar_t *)other->getStringData(); /* make arg 2 first string */ + string2 = (stringchar_t *)this->getStringData(); /* arg 1 is second string */ + lead = length1; /* get shorter length */ + remainder = length2 - lead; /* get trailing size */ + } + stringsize_t i = 0; /* set the start */ + // compare the leading parts + for (stringsize_t i = 0; i < lead; i++) + { + // have a mismatch? + if (toupper(string1[i]) != toupper(string2[i])) + { + return new_integer(i+1); // return the mismatch position + } + } + string1 += lead; // step to the remainder and scan + for (stringsize_t i = 0; i < remainder; i++) + { + // mismatch on the pad? + if (toupper(string1[i]) != padChar) + { + // this is the mismatch position, return it + return new_integer(lead + i + 1); + } + } + return IntegerZero; // no mismatch, return the failure indicator +} + + RexxString *RexxString::copies(RexxInteger *copies) /******************************************************************************/ /* Function: String class COPIES method/function */ Modified: interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp 2007-06-24 04:24:11 UTC (rev 500) +++ interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp 2007-06-24 21:15:09 UTC (rev 501) @@ -83,6 +83,7 @@ CHARCONSTANT(CALL_PROGRAM, "CALL_PROGRAM"); CHARCONSTANT(CALL_STRING, "CALL_STRING"); CHARCONSTANT(CASELESSCOMPARETO, "CASELESSCOMPARETO"); +CHARCONSTANT(CASELESSCOMPARE, "CASELESSCOMPARE"); CHARCONSTANT(CASELESSEQUALS, "CASELESSEQUALS"); CHARCONSTANT(CASELESSLASTPOS, "CASELESSLASTPOS"); CHARCONSTANT(CASELESSMATCH, "CASELESSMATCH"); Modified: interpreter-3.x/trunk/kernel/runtime/Setup.cpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/Setup.cpp 2007-06-24 04:24:11 UTC (rev 500) +++ interpreter-3.x/trunk/kernel/runtime/Setup.cpp 2007-06-24 21:15:09 UTC (rev 501) @@ -424,6 +424,7 @@ CPPMSTR(RexxString::caselessCountStrRexx), CPPMSTR(RexxString::abbrev), CPPMSTR(RexxString::compare), +CPPMSTR(RexxString::caselessCompare), CPPMSTR(RexxString::copies), CPPMSTR(RexxString::dataType), CPPMSTR(RexxString::lastPosRexx), @@ -1222,6 +1223,7 @@ defineKernelMethod(CHAR_CHANGESTR ,TheStringBehaviour, CPPMSTR(RexxString::changeStr), 2); defineKernelMethod(CHAR_CASELESSCHANGESTR ,TheStringBehaviour, CPPMSTR(RexxString::caselessChangeStr), 2); defineKernelMethod(CHAR_COMPARE ,TheStringBehaviour, CPPMSTR(RexxString::compare), 2); + defineKernelMethod(CHAR_CASELESSCOMPARE ,TheStringBehaviour, CPPMSTR(RexxString::caselessCompare), 2); defineKernelMethod(CHAR_COPIES ,TheStringBehaviour, CPPMSTR(RexxString::copies), 1); defineKernelMethod(CHAR_COUNTSTR ,TheStringBehaviour, CPPMSTR(RexxString::countStrRexx), 1); defineKernelMethod(CHAR_CASELESSCOUNTSTR ,TheStringBehaviour, CPPMSTR(RexxString::caselessCountStrRexx), 1); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2007-06-27 19:23:15
|
Revision: 515 http://svn.sourceforge.net/oorexx/?rev=515&view=rev Author: bigrixx Date: 2007-06-27 12:23:16 -0700 (Wed, 27 Jun 2007) Log Message: ----------- [ 1744421 ] Improve output from TRACE I Modified Paths: -------------- interpreter-3.x/trunk/kernel/expression/ExpressionDotVariable.cpp interpreter-3.x/trunk/kernel/expression/ExpressionFunction.cpp interpreter-3.x/trunk/kernel/expression/ExpressionMessage.cpp interpreter-3.x/trunk/kernel/expression/ExpressionOperator.cpp interpreter-3.x/trunk/kernel/expression/ExpressionOperator.hpp interpreter-3.x/trunk/kernel/expression/ExpressionStem.cpp interpreter-3.x/trunk/kernel/expression/ExpressionVariable.cpp interpreter-3.x/trunk/kernel/instructions/CallInstruction.cpp interpreter-3.x/trunk/kernel/instructions/MessageInstruction.cpp interpreter-3.x/trunk/kernel/parser/InstructionParser.cpp interpreter-3.x/trunk/kernel/parser/SourceFile.cpp interpreter-3.x/trunk/kernel/runtime/RexxActivation.cpp interpreter-3.x/trunk/kernel/runtime/RexxActivation.hpp interpreter-3.x/trunk/kernel/runtime/RexxCore.h Modified: interpreter-3.x/trunk/kernel/expression/ExpressionDotVariable.cpp =================================================================== --- interpreter-3.x/trunk/kernel/expression/ExpressionDotVariable.cpp 2007-06-27 19:23:01 UTC (rev 514) +++ interpreter-3.x/trunk/kernel/expression/ExpressionDotVariable.cpp 2007-06-27 19:23:16 UTC (rev 515) @@ -107,13 +107,10 @@ if (result == OREF_NULL) { /* not there? */ /* add a period to the name */ result = this->variableName->concatToCstring(CHAR_PERIOD); - /* trace if necessary */ - context->traceIntermediate(result, TRACE_PREFIX_LITERAL); } - else - /* trace if necessary */ - context->traceIntermediate(result, TRACE_PREFIX_VARIABLE); stack->push(result); /* place on the evaluation stack */ + /* trace if necessary */ + context->traceDotVariable(variableName, result); return result; /* also return the result */ } Modified: interpreter-3.x/trunk/kernel/expression/ExpressionFunction.cpp =================================================================== --- interpreter-3.x/trunk/kernel/expression/ExpressionFunction.cpp 2007-06-27 19:23:01 UTC (rev 514) +++ interpreter-3.x/trunk/kernel/expression/ExpressionFunction.cpp 2007-06-27 19:23:16 UTC (rev 515) @@ -102,8 +102,6 @@ /* have a builtin function? */ if (this->builtin_index != NO_BUILTIN) { this->flags |= function_builtin; /* this is a builtin function */ - /* cast off the routine name */ - OrefSet(this, this->u_name, OREF_NULL); } else this->flags |= function_external;/* have an external routine */ @@ -182,13 +180,13 @@ if (this->arguments[i] != OREF_NULL) { /* evaluate the expression */ result = this->arguments[i]->evaluate(context, stack); - - context->traceResult(result); /* trace if necessary */ + /* trace if necessary */ + context->traceIntermediate(result, TRACE_PREFIX_ARGUMENT); } else { stack->push(OREF_NULL); /* push an non-existent argument */ /* trace if necessary */ - context->traceResult(OREF_NULLSTRING); + context->traceIntermediate(OREF_NULLSTRING, TRACE_PREFIX_ARGUMENT); } } @@ -220,7 +218,7 @@ stack->push(result); /* push onto the stack */ if ((this->flags&function_type_mask) != function_builtin) discard(result); /* trace if necessary */ - context->traceIntermediate(result, TRACE_PREFIX_FUNCTION); + context->traceFunction(u_name, result); return result; /* and return this to the caller */ } Modified: interpreter-3.x/trunk/kernel/expression/ExpressionMessage.cpp =================================================================== --- interpreter-3.x/trunk/kernel/expression/ExpressionMessage.cpp 2007-06-27 19:23:01 UTC (rev 514) +++ interpreter-3.x/trunk/kernel/expression/ExpressionMessage.cpp 2007-06-27 19:23:16 UTC (rev 515) @@ -116,13 +116,13 @@ if (this->arguments[i] != OREF_NULL) { /* evaluate the expression */ result = this->arguments[i]->evaluate(context, stack); - - context->traceResult(result); /* trace if necessary */ + /* trace if necessary */ + context->traceIntermediate(result, TRACE_PREFIX_ARGUMENT); } else { stack->push(OREF_NULL); /* push an non-existent argument */ /* trace if necessary */ - context->traceResult(OREF_NULLSTRING); + context->traceIntermediate(OREF_NULLSTRING, TRACE_PREFIX_ARGUMENT); } } if (super == OREF_NULL) /* no super class override? */ @@ -141,7 +141,7 @@ /* need to raise an exception */ report_exception1(Error_No_result_object_message, this->u_name); /* trace if necessary */ - context->traceIntermediate(result, TRACE_PREFIX_MESSAGE); + context->traceMessage(u_name, result); return result; /* return the result */ } Modified: interpreter-3.x/trunk/kernel/expression/ExpressionOperator.cpp =================================================================== --- interpreter-3.x/trunk/kernel/expression/ExpressionOperator.cpp 2007-06-27 19:23:01 UTC (rev 514) +++ interpreter-3.x/trunk/kernel/expression/ExpressionOperator.cpp 2007-06-27 19:23:16 UTC (rev 515) @@ -47,6 +47,7 @@ #include "ExpressionOperator.hpp" RexxExpressionOperator::RexxExpressionOperator( + RexxString *name, /* character name of operator */ INT oper, /* operator index */ RexxObject *left, /* left expression objects */ RexxObject *right) /* right expression objects */ @@ -56,6 +57,7 @@ { ClearObject(this); /* start completely clean */ /* just fill in the three terms */ + this->u_name = name; this->oper = oper; OrefSet(this, this->left_term, left); OrefSet(this, this->right_term, right); @@ -82,14 +84,14 @@ /* replace top two stack elements */ stack->operatorResult(result); /* with this one */ /* trace if necessary */ - context->traceIntermediate(result, TRACE_PREFIX_OPERATOR); + context->traceOperator(u_name, result); } else { /* prefix operator */ /* process this directly */ result = callOperatorMethod(left_term, this->oper, OREF_NULL); stack->prefixResult(result); /* replace the top element */ /* trace if necessary */ - context->traceIntermediate(result, TRACE_PREFIX_PREFIX); + context->tracePrefix(u_name, result); } return result; /* return the result */ } @@ -114,7 +116,7 @@ /* replace top two stack elements */ stack->operatorResult(result); /* with this one */ /* trace if necessary */ - context->traceIntermediate(result, TRACE_PREFIX_OPERATOR); + context->traceOperator(u_name, result); return result; /* return the result */ } @@ -134,7 +136,7 @@ result = callOperatorMethod(left_term, this->oper, OREF_NULL); stack->prefixResult(result); /* replace the top element */ /* trace if necessary */ - context->traceIntermediate(result, TRACE_PREFIX_PREFIX); + context->tracePrefix(u_name, result); return result; /* return the result */ } @@ -144,6 +146,7 @@ /******************************************************************************/ { setUpMemoryMark + memory_mark(this->u_name); memory_mark(this->left_term); memory_mark(this->right_term); cleanUpMemoryMark @@ -155,6 +158,7 @@ /******************************************************************************/ { setUpMemoryMarkGeneral + memory_mark_general(this->u_name); memory_mark_general(this->left_term); memory_mark_general(this->right_term); cleanUpMemoryMarkGeneral @@ -167,6 +171,7 @@ { setUpFlatten(RexxExpressionOperator) + flatten_reference(newThis->u_name, envelope); flatten_reference(newThis->left_term, envelope); flatten_reference(newThis->right_term, envelope); Modified: interpreter-3.x/trunk/kernel/expression/ExpressionOperator.hpp =================================================================== --- interpreter-3.x/trunk/kernel/expression/ExpressionOperator.hpp 2007-06-27 19:23:01 UTC (rev 514) +++ interpreter-3.x/trunk/kernel/expression/ExpressionOperator.hpp 2007-06-27 19:23:16 UTC (rev 515) @@ -47,7 +47,7 @@ class RexxExpressionOperator : public RexxInternalObject { public: inline RexxExpressionOperator() { ; } - RexxExpressionOperator(INT, RexxObject *, RexxObject *); + RexxExpressionOperator(RexxString *name, INT, RexxObject *, RexxObject *); inline RexxExpressionOperator(RESTORETYPE restoreType) { ; }; void live(); void liveGeneral(); @@ -63,8 +63,8 @@ class RexxBinaryOperator : public RexxExpressionOperator { public: - inline RexxBinaryOperator(INT oper, RexxObject *left, RexxObject *right) - : RexxExpressionOperator(oper, left, right) { ; } + inline RexxBinaryOperator(RexxString *name, INT oper, RexxObject *left, RexxObject *right) + : RexxExpressionOperator(name, oper, left, right) { ; } inline RexxBinaryOperator(RESTORETYPE restoreType) { ; }; void *operator new(size_t); inline void *operator new(size_t size, void *ptr) {return ptr;}; @@ -73,8 +73,8 @@ class RexxUnaryOperator : public RexxExpressionOperator { public: - inline RexxUnaryOperator(INT oper, RexxObject *left) - : RexxExpressionOperator(oper, left, OREF_NULL) { ; } + inline RexxUnaryOperator(RexxString *name, INT oper, RexxObject *left) + : RexxExpressionOperator(name, oper, left, OREF_NULL) { ; } inline RexxUnaryOperator(RESTORETYPE restoreType) { ; }; void *operator new(size_t); inline void *operator new(size_t size, void *ptr) {return ptr;}; Modified: interpreter-3.x/trunk/kernel/expression/ExpressionStem.cpp =================================================================== --- interpreter-3.x/trunk/kernel/expression/ExpressionStem.cpp 2007-06-27 19:23:01 UTC (rev 514) +++ interpreter-3.x/trunk/kernel/expression/ExpressionStem.cpp 2007-06-27 19:23:16 UTC (rev 515) @@ -115,7 +115,7 @@ /* unexpectedly */ stack->push(value); /* place on the evaluation stack */ /* trace if necessary */ - context->traceIntermediate(value, TRACE_PREFIX_VARIABLE); + context->traceVariable(stem, value); return value; /* return the located variable */ } Modified: interpreter-3.x/trunk/kernel/expression/ExpressionVariable.cpp =================================================================== --- interpreter-3.x/trunk/kernel/expression/ExpressionVariable.cpp 2007-06-27 19:23:01 UTC (rev 514) +++ interpreter-3.x/trunk/kernel/expression/ExpressionVariable.cpp 2007-06-27 19:23:16 UTC (rev 515) @@ -149,7 +149,7 @@ } stack->push(value); /* place on the evaluation stack */ /* trace if necessary */ - context->traceIntermediate(value, TRACE_PREFIX_VARIABLE); + context->traceVariable(variableName, value); return value; /* return the located variable */ } Modified: interpreter-3.x/trunk/kernel/instructions/CallInstruction.cpp =================================================================== --- interpreter-3.x/trunk/kernel/instructions/CallInstruction.cpp 2007-06-27 19:23:01 UTC (rev 514) +++ interpreter-3.x/trunk/kernel/instructions/CallInstruction.cpp 2007-06-27 19:23:16 UTC (rev 515) @@ -229,12 +229,13 @@ /* evaluate the expression */ result = this->arguments[i]->evaluate(context, stack); - context->traceResult(result); /* trace if necessary */ + /* trace if necessary */ + context->traceIntermediate(result, TRACE_PREFIX_ARGUMENT); } else { stack->push(OREF_NULL); /* push an non-existent argument */ /* trace if necessary */ - context->traceResult(OREF_NULLSTRING); + context->traceIntermediate(OREF_NULLSTRING, TRACE_PREFIX_ARGUMENT); } } switch (type) { /* process various call types */ Modified: interpreter-3.x/trunk/kernel/instructions/MessageInstruction.cpp =================================================================== --- interpreter-3.x/trunk/kernel/instructions/MessageInstruction.cpp 2007-06-27 19:23:01 UTC (rev 514) +++ interpreter-3.x/trunk/kernel/instructions/MessageInstruction.cpp 2007-06-27 19:23:16 UTC (rev 515) @@ -193,13 +193,13 @@ if (this->arguments[i] != OREF_NULL) { /* evaluate the expression */ result = this->arguments[i]->evaluate(context, stack); - - context->traceResult(result); /* trace if necessary */ + /* trace if necessary */ + context->traceIntermediate(result, TRACE_PREFIX_ARGUMENT); } else { stack->push(OREF_NULL); /* push an non-existent argument */ /* trace if necessary */ - context->traceResult(OREF_NULLSTRING); + context->traceIntermediate(OREF_NULLSTRING, TRACE_PREFIX_ARGUMENT); } } if (super == OREF_NULL) /* no super class override? */ Modified: interpreter-3.x/trunk/kernel/parser/InstructionParser.cpp =================================================================== --- interpreter-3.x/trunk/kernel/parser/InstructionParser.cpp 2007-06-27 19:23:01 UTC (rev 514) +++ interpreter-3.x/trunk/kernel/parser/InstructionParser.cpp 2007-06-27 19:23:16 UTC (rev 515) @@ -200,8 +200,10 @@ // we need an evaluator for both the expression and the assignment RexxObject *variable = addText(target); + // we need the operator name from the composite + RexxString *opName = operation->value->extract(0, operation->value->getLength() - 1); // now add a binary operator to this expression tree - expression = (RexxObject *)new RexxBinaryOperator(operation->subclass, variable, expression); + expression = (RexxObject *)new RexxBinaryOperator(opName, operation->subclass, variable, expression); // now everything is the same as an assignment operator RexxObject *newObject = new_instruction(ASSIGNMENT, Assignment); @@ -1211,8 +1213,11 @@ message->makeAssignment(this); // convert into an assignment message (the original message term) + + // we need the operator name from the composite + RexxString *opName = operation->value->extract(0, operation->value->getLength() - 1); // now add a binary operator to this expression tree - expression = (RexxObject *)new RexxBinaryOperator(operation->subclass, retriever, expression); + expression = (RexxObject *)new RexxBinaryOperator(opName, operation->subclass, retriever, expression); // allocate a new object. NB: a message instruction gets an extra argument, so we don't subtract one. RexxObject *newObject = new_variable_instruction(MESSAGE, Message, sizeof(RexxInstructionMessage) + (message->argumentCount) * sizeof(OREF)); Modified: interpreter-3.x/trunk/kernel/parser/SourceFile.cpp =================================================================== --- interpreter-3.x/trunk/kernel/parser/SourceFile.cpp 2007-06-27 19:23:01 UTC (rev 514) +++ interpreter-3.x/trunk/kernel/parser/SourceFile.cpp 2007-06-27 19:23:16 UTC (rev 515) @@ -3310,7 +3310,8 @@ /* this is an invalid expression */ report_error_token(Error_Invalid_expression_general, token); /* create a new operation */ - subexpression = (RexxObject *)new RexxBinaryOperator(this->popOperator()->subclass, left, right); + RexxToken *op = popOperator(); + subexpression = (RexxObject *)new RexxBinaryOperator(op->value, op->subclass, left, right); /* push this back on the term stack */ this->pushTerm(subexpression); } @@ -3361,7 +3362,7 @@ /* this is an invalid expression */ report_error_token(Error_Invalid_expression_general, token); /* create a new operation */ - subexpression = (RexxObject *)new RexxBinaryOperator (token->subclass, left, right); + subexpression = (RexxObject *)new RexxBinaryOperator (token->value, token->subclass, left, right); this->pushTerm(subexpression); /* push this back on the term stack */ token = this->popOperator(); /* get top operator token */ } @@ -3669,7 +3670,7 @@ /* this is an error */ report_error_token(Error_Invalid_expression_prefix, token); /* create the new operator term */ - term = (RexxObject *)new RexxUnaryOperator(token->subclass, term); + term = (RexxObject *)new RexxUnaryOperator(token->value, token->subclass, term); break; default: /* other operators not allowed here */ Modified: interpreter-3.x/trunk/kernel/runtime/RexxActivation.cpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/RexxActivation.cpp 2007-06-27 19:23:01 UTC (rev 514) +++ interpreter-3.x/trunk/kernel/runtime/RexxActivation.cpp 2007-06-27 19:23:16 UTC (rev 515) @@ -2327,12 +2327,20 @@ ">>>", /* TRACE_PREFIX_RESULT */ ">.>", /* TRACE_PREFIX_DUMMY */ ">V>", /* TRACE_PREFIX_VARIABLE */ + ">D>", /* TRACE_PREFIX_DOTVARIABLE */ ">L>", /* TRACE_PREFIX_LITERAL */ ">F>", /* TRACE_PREFIX_FUNCTION */ ">P>", /* TRACE_PREFIX_PREFIX */ ">O>", /* TRACE_PREFIX_OPERATOR */ - ">C>", /* TRACE_PREFIX_COMPOUND */ - ">M>" /* TRACE_PREFIX_MESSAGE */ + "=C=", /* TRACE_PREFIX_COMPOUND */ + ">M>", /* TRACE_PREFIX_MESSAGE */ + ">,>", /* TRACE_PREFIX_ARGUMENT */ + "=V=", /* TRACE_PREFIX_VARIABLE_NAME */ + "=D=", /* TRACE_PREFIX_DOTVARIABLE_NAME */ + "=F=", /* TRACE_PREFIX_FUNCTION_NAME */ + "=O=", /* TRACE_PREFIX_OPERATOR_NAME */ + "=P=", /* TRACE_PREFIX_PREFIX_NAME */ + "=M=", /* TRACE_PREFIX_MESSAGE_NAME */ }; /* extra space required to format a */ Modified: interpreter-3.x/trunk/kernel/runtime/RexxActivation.hpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/RexxActivation.hpp 2007-06-27 19:23:01 UTC (rev 514) +++ interpreter-3.x/trunk/kernel/runtime/RexxActivation.hpp 2007-06-27 19:23:16 UTC (rev 515) @@ -340,6 +340,18 @@ inline ACTIVATION_SETTINGS * getGlobalSettings() {return &(this->settings.global_settings);}; inline LONG getIndent() {return this->settings.traceindent;}; inline void traceIntermediate(RexxObject * v, int p) { if (this->settings.intermediate_trace) this->traceValue(v, p); }; + inline void traceVariable(RexxString *n, RexxObject *v) + { if (this->settings.intermediate_trace) { this->traceValue(n, TRACE_PREFIX_VARIABLE_NAME); this->traceValue(v, TRACE_PREFIX_VARIABLE);} }; + inline void traceDotVariable(RexxString *n, RexxObject *v) + { if (this->settings.intermediate_trace) { this->traceValue(n->concatToCstring(CHAR_PERIOD), TRACE_PREFIX_DOTVARIABLE_NAME); this->traceValue(v, TRACE_PREFIX_DOTVARIABLE);} }; + inline void traceFunction(RexxString *n, RexxObject *v) + { if (this->settings.intermediate_trace) { this->traceValue(n, TRACE_PREFIX_FUNCTION_NAME); this->traceValue(v, TRACE_PREFIX_FUNCTION);} }; + inline void traceMessage(RexxString *n, RexxObject *v) + { if (this->settings.intermediate_trace) { this->traceValue(n, TRACE_PREFIX_MESSAGE_NAME); this->traceValue(v, TRACE_PREFIX_MESSAGE);} }; + inline void traceOperator(RexxString *n, RexxObject *v) + { if (this->settings.intermediate_trace) { this->traceValue(n, TRACE_PREFIX_OPERATOR_NAME); this->traceValue(v, TRACE_PREFIX_OPERATOR);} }; + inline void tracePrefix(RexxString *n, RexxObject *v) + { if (this->settings.intermediate_trace) { this->traceValue(n, TRACE_PREFIX_PREFIX_NAME); this->traceValue(v, TRACE_PREFIX_PREFIX);} }; inline void traceCompoundName(RexxString *stem, RexxCompoundTail *tail) { if (this->settings.intermediate_trace) this->traceValue(tail->createCompoundName(stem), TRACE_PREFIX_COMPOUND); }; inline void traceCompoundName(RexxString *stem, RexxString *tail) { if (this->settings.intermediate_trace) this->traceValue(stem->concat(tail), TRACE_PREFIX_COMPOUND); }; inline void traceResult(RexxObject * v) { if ((this->settings.flags&trace_results) || (this->settings.dbg_flags&dbg_trace)) this->traceValue(v, TRACE_PREFIX_RESULT); }; Modified: interpreter-3.x/trunk/kernel/runtime/RexxCore.h =================================================================== --- interpreter-3.x/trunk/kernel/runtime/RexxCore.h 2007-06-27 19:23:01 UTC (rev 514) +++ interpreter-3.x/trunk/kernel/runtime/RexxCore.h 2007-06-27 19:23:16 UTC (rev 515) @@ -106,12 +106,20 @@ TRACE_PREFIX_RESULT , TRACE_PREFIX_DUMMY , TRACE_PREFIX_VARIABLE , + TRACE_PREFIX_DOTVARIABLE , TRACE_PREFIX_LITERAL , TRACE_PREFIX_FUNCTION , TRACE_PREFIX_PREFIX , TRACE_PREFIX_OPERATOR , TRACE_PREFIX_COMPOUND , - TRACE_PREFIX_MESSAGE + TRACE_PREFIX_MESSAGE , + TRACE_PREFIX_ARGUMENT , + TRACE_PREFIX_VARIABLE_NAME, + TRACE_PREFIX_DOTVARIABLE_NAME, + TRACE_PREFIX_FUNCTION_NAME, + TRACE_PREFIX_OPERATOR_NAME, + TRACE_PREFIX_PREFIX_NAME, + TRACE_PREFIX_MESSAGE_NAME, }; #define MAX_TRACEBACK_LIST 80 /* 40 messages are displayed */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2007-06-29 13:31:49
|
Revision: 528 http://svn.sourceforge.net/oorexx/?rev=528&view=rev Author: bigrixx Date: 2007-06-29 06:31:47 -0700 (Fri, 29 Jun 2007) Log Message: ----------- Update the TRACE I values based on MFC comments. Modified Paths: -------------- interpreter-3.x/trunk/kernel/classes/StringClass.hpp interpreter-3.x/trunk/kernel/expression/ExpressionCompoundVariable.cpp interpreter-3.x/trunk/kernel/expression/ExpressionVariable.cpp interpreter-3.x/trunk/kernel/expression/ExpressionVariable.hpp interpreter-3.x/trunk/kernel/runtime/RexxActivation.cpp interpreter-3.x/trunk/kernel/runtime/RexxActivation.hpp interpreter-3.x/trunk/kernel/runtime/RexxCompoundTail.cpp interpreter-3.x/trunk/kernel/runtime/RexxCompoundTail.hpp interpreter-3.x/trunk/kernel/runtime/RexxCore.h Modified: interpreter-3.x/trunk/kernel/classes/StringClass.hpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/StringClass.hpp 2007-06-29 12:44:32 UTC (rev 527) +++ interpreter-3.x/trunk/kernel/classes/StringClass.hpp 2007-06-29 13:31:47 UTC (rev 528) @@ -303,6 +303,7 @@ inline size_t getLength() { return this->length; }; inline PCHAR getStringData() { return this->stringData; }; inline void put(size_t s, const void *b, int l) { memcpy((this->stringData+s),b,(size_t)l); }; + inline void put(size_t s, RexxString *o) { put(s, o->getStringData(), o->getLength()); }; inline void set(size_t s,int c,int l) { memset((this->stringData+s),c,(size_t)l); }; inline char getChar(size_t p) { return *(this->stringData+p); }; inline char putChar(size_t p,char c) { return *(this->stringData+p) = c; }; Modified: interpreter-3.x/trunk/kernel/expression/ExpressionCompoundVariable.cpp =================================================================== --- interpreter-3.x/trunk/kernel/expression/ExpressionCompoundVariable.cpp 2007-06-29 12:44:32 UTC (rev 527) +++ interpreter-3.x/trunk/kernel/expression/ExpressionCompoundVariable.cpp 2007-06-29 13:31:47 UTC (rev 528) @@ -304,7 +304,7 @@ /* have the stem expose this */ stem_table->expose(variable); /* trace resolved compound name */ - context->traceCompoundName(stem, variable->getName()); + context->traceCompoundName(stem, (RexxObject **)&tails[0], tailCount, variable->getName()); } @@ -332,7 +332,7 @@ /* tracing intermediate values? */ if (context->tracingIntermediates()) { /* trace resolved compound name */ - context->traceCompoundName(stem, variable->getName()); + context->traceCompoundName(stem, (RexxObject **)&tails[0], tailCount, variable->getName()); } } Modified: interpreter-3.x/trunk/kernel/expression/ExpressionVariable.cpp =================================================================== --- interpreter-3.x/trunk/kernel/expression/ExpressionVariable.cpp 2007-06-29 12:44:32 UTC (rev 527) +++ interpreter-3.x/trunk/kernel/expression/ExpressionVariable.cpp 2007-06-29 13:31:47 UTC (rev 528) @@ -305,7 +305,17 @@ context->putLocalVariable(old_variable, index); } +/** + * Return the name of this variable. + * + * @return The string value of the variable name. + */ +RexxString *RexxParseVariable::getName() +{ + return variableName; +} + void *RexxParseVariable::operator new(size_t size) /******************************************************************************/ /* Function: Create a REXX variable translator object */ Modified: interpreter-3.x/trunk/kernel/expression/ExpressionVariable.hpp =================================================================== --- interpreter-3.x/trunk/kernel/expression/ExpressionVariable.hpp 2007-06-29 12:44:32 UTC (rev 527) +++ interpreter-3.x/trunk/kernel/expression/ExpressionVariable.hpp 2007-06-29 13:31:47 UTC (rev 528) @@ -67,7 +67,7 @@ void clearGuard(RexxActivation *); void expose(RexxActivation *, RexxExpressionStack *, RexxVariableDictionary *); void procedureExpose(RexxActivation *, RexxActivation *, RexxExpressionStack *); - + RexxString *getName(); /* name of the variable is in hash */ LONG index; /* lookaside table index */ }; Modified: interpreter-3.x/trunk/kernel/runtime/RexxActivation.cpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/RexxActivation.cpp 2007-06-29 12:44:32 UTC (rev 527) +++ interpreter-3.x/trunk/kernel/runtime/RexxActivation.cpp 2007-06-29 13:31:47 UTC (rev 528) @@ -2332,15 +2332,9 @@ ">F>", /* TRACE_PREFIX_FUNCTION */ ">P>", /* TRACE_PREFIX_PREFIX */ ">O>", /* TRACE_PREFIX_OPERATOR */ - "=C=", /* TRACE_PREFIX_COMPOUND */ + ">C>", /* TRACE_PREFIX_COMPOUND */ ">M>", /* TRACE_PREFIX_MESSAGE */ - ">,>", /* TRACE_PREFIX_ARGUMENT */ - "=V=", /* TRACE_PREFIX_VARIABLE_NAME */ - "=E=", /* TRACE_PREFIX_DOTVARIABLE_NAME */ - "=F=", /* TRACE_PREFIX_FUNCTION_NAME */ - "=O=", /* TRACE_PREFIX_OPERATOR_NAME */ - "=P=", /* TRACE_PREFIX_PREFIX_NAME */ - "=M=", /* TRACE_PREFIX_MESSAGE_NAME */ + ">A>", /* TRACE_PREFIX_ARGUMENT */ }; /* extra space required to format a */ @@ -2359,6 +2353,10 @@ #define PREFIX_OFFSET (LINENUMBER + 1) /* location of the prefix field */ #define PREFIX_LENGTH 3 /* length of the prefix flag */ #define INDENT_SPACING 2 /* spaces per indentation amount */ +// marker used for tagged traces to separate tag from the value +#define VALUE_MARKER " => " +// over head for adding quotes +#define QUOTES_OVERHEAD 2 void RexxActivation::traceValue( /* trace an intermediate value */ @@ -2402,6 +2400,195 @@ discard(buffer); } + +/** + * Trace an entry that's of the form 'tag => "value"'. + * + * @param prefix The trace prefix tag to use. + * @param tagPrefix Any prefix string added to the tag. Use mostly for adding + * the "." to traced environment variables. + * @param quoteTag Indicates whether the tag should be quoted or not. Operator + * names are quoted. + * @param tag The tag name. + * @param value The associated trace value. + */ +void RexxActivation::traceTaggedValue(int prefix, stringchar_t *tagPrefix, bool quoteTag, + RexxString *tag, RexxObject * value) +{ + // the trace settings would normally require us to trace this, but there are conditions + // where we just skip doing this anyway. + if (this->settings.flags&trace_suppress || this->debug_pause || value == OREF_NULL || !source->traceable()) + { + return; + } + + // get the string value from the traced object. + RexxString *stringValue = value->stringValue(); + // protect against negative indent values (belt and braces) + if (this->settings.traceindent < 0) + { + + this->settings.traceindent = 0; + } + + // now calculate the length of the traced string + stringsize_t outLength = tag->getLength() + stringValue->getLength(); + // these are fixed overheads + outLength += TRACE_OVERHEAD + strlen(VALUE_MARKER); + // now the indent spacing + outLength += this->settings.traceindent * INDENT_SPACING; + // now other conditionals + outLength += quoteTag ? QUOTES_OVERHEAD : 0; + // this is usually null, but dot variables add a "." to the tag. + outLength += tagPrefix == NULL ? 0 : strlen((char *)tagPrefix); + + // now get a buffer to write this out into + RexxString *buffer = raw_string(outLength); + save(buffer); + + // get a cursor for filling in the formatted data + stringsize_t dataOffset = TRACE_OVERHEAD + this->settings.traceindent * INDENT_SPACING - 2; + /* insert the leading blanks */ + buffer->set(0, ' ', TRACE_OVERHEAD + this->settings.traceindent * INDENT_SPACING); + /* add the trace prefix */ + buffer->put(PREFIX_OFFSET, trace_prefix_table[prefix], PREFIX_LENGTH); + + // if this is a quoted tag (operators do this), add quotes before coping the tag + if (quoteTag) + { + buffer->putChar(dataOffset, '\"'); + dataOffset++; + } + // is the tag prefixed? Add this before the name + if (tagPrefix != NULL) + { + stringsize_t prefixLength = strlen((char *)tagPrefix); + buffer->put(dataOffset, tagPrefix, prefixLength); + dataOffset += prefixLength; + } + + // add in the tag name + buffer->put(dataOffset, tag); + dataOffset += tag->getLength(); + + // might need a closing quote. + if (quoteTag) + { + buffer->putChar(dataOffset, '\"'); + dataOffset++; + } + + // now add the data marker + buffer->put(dataOffset, VALUE_MARKER, strlen(VALUE_MARKER)); + dataOffset += strlen(VALUE_MARKER); + + // the leading quote around the value + buffer->putChar(dataOffset, '\"'); + dataOffset++; + + // the traced value + buffer->put(dataOffset, stringValue); + dataOffset += stringValue->getLength(); + + // and finally, the trailing quote + buffer->putChar(dataOffset, '\"'); + dataOffset++; + + buffer->generateHash(); /* done building the string */ + /* write out the line */ + this->activity->traceOutput(this, buffer); + discard(buffer); +} + + +/** + * Trace a compound variable entry that's of the form 'tag => + * "value"'. + * + * @param prefix The trace prefix tag to use. + * @param stem The stem name of the compound. + * @param tails The array of tail elements (unresolved). + * @param tailCount The count of tail elements. + * @param value The associated trace value. + */ +void RexxActivation::traceCompoundValue(int prefix, RexxString *stem, RexxObject **tails, size_t tailCount, + RexxObject * value) +{ + // the trace settings would normally require us to trace this, but there are conditions + // where we just skip doing this anyway. + if (this->settings.flags&trace_suppress || this->debug_pause || value == OREF_NULL || !source->traceable()) + { + return; + } + + // get the string value from the traced object. + RexxString *stringValue = value->stringValue(); + // protect against negative indent values (belt and braces) + if (this->settings.traceindent < 0) + { + + this->settings.traceindent = 0; + } + + + // now calculate the length of the traced string + stringsize_t outLength = stem->getLength() + stringValue->getLength(); + + // build an unresolved tail name + RexxCompoundTail tail(tails, tailCount, false); + + outLength += tail.getLength(); + + // add in the number of added dots + outLength += tailCount - 1; + + // these are fixed overheads + outLength += TRACE_OVERHEAD + strlen(VALUE_MARKER); + // now the indent spacing + outLength += this->settings.traceindent * INDENT_SPACING; + + // now get a buffer to write this out into + RexxString *buffer = raw_string(outLength); + save(buffer); + + // get a cursor for filling in the formatted data + stringsize_t dataOffset = TRACE_OVERHEAD + this->settings.traceindent * INDENT_SPACING - 2; + /* insert the leading blanks */ + buffer->set(0, ' ', TRACE_OVERHEAD + this->settings.traceindent * INDENT_SPACING); + /* add the trace prefix */ + buffer->put(PREFIX_OFFSET, trace_prefix_table[prefix], PREFIX_LENGTH); + + // add in the stem name + buffer->put(dataOffset, stem); + dataOffset += stem->getLength(); + + // copy the tail portion of the compound name + buffer->put(dataOffset, tail.getTail(), tail.getLength()); + dataOffset += tail.getLength(); + + // now add the data marker + buffer->put(dataOffset, VALUE_MARKER, strlen(VALUE_MARKER)); + dataOffset += strlen(VALUE_MARKER); + + // the leading quote around the value + buffer->putChar(dataOffset, '\"'); + dataOffset++; + + // the traced value + buffer->put(dataOffset, stringValue); + dataOffset += stringValue->getLength(); + + // and finally, the trailing quote + buffer->putChar(dataOffset, '\"'); + dataOffset++; + + buffer->generateHash(); /* done building the string */ + /* write out the line */ + this->activity->traceOutput(this, buffer); + discard(buffer); +} + + void RexxActivation::traceSourceString() /******************************************************************************/ /* Function: Trace the source string at debug mode start */ Modified: interpreter-3.x/trunk/kernel/runtime/RexxActivation.hpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/RexxActivation.hpp 2007-06-29 12:44:32 UTC (rev 527) +++ interpreter-3.x/trunk/kernel/runtime/RexxActivation.hpp 2007-06-29 13:31:47 UTC (rev 528) @@ -242,6 +242,8 @@ LONG currentLine(); void arguments(RexxObject *); void traceValue(RexxObject *, int); + void traceCompoundValue(int prefix, RexxString *stem, RexxObject **tails, size_t tailCount, RexxObject * value); + void traceTaggedValue(int prefix, stringchar_t *tagPrefix, bool quoteTag, RexxString *tag, RexxObject * value); void traceSourceString(); void traceClause(RexxInstruction *, int); void resetElapsed(); @@ -341,19 +343,20 @@ inline LONG getIndent() {return this->settings.traceindent;}; inline void traceIntermediate(RexxObject * v, int p) { if (this->settings.intermediate_trace) this->traceValue(v, p); }; inline void traceVariable(RexxString *n, RexxObject *v) - { if (this->settings.intermediate_trace) { this->traceValue(n, TRACE_PREFIX_VARIABLE_NAME); this->traceValue(v, TRACE_PREFIX_VARIABLE);} }; + { if (this->settings.intermediate_trace) { this->traceTaggedValue(TRACE_PREFIX_VARIABLE, NULL, false, n, v); } }; inline void traceDotVariable(RexxString *n, RexxObject *v) - { if (this->settings.intermediate_trace) { this->traceValue(n->concatToCstring(CHAR_PERIOD), TRACE_PREFIX_DOTVARIABLE_NAME); this->traceValue(v, TRACE_PREFIX_DOTVARIABLE);} }; + { if (this->settings.intermediate_trace) { this->traceTaggedValue(TRACE_PREFIX_DOTVARIABLE, (stringchar_t *)".", false, n, v); } }; inline void traceFunction(RexxString *n, RexxObject *v) - { if (this->settings.intermediate_trace) { this->traceValue(n, TRACE_PREFIX_FUNCTION_NAME); this->traceValue(v, TRACE_PREFIX_FUNCTION);} }; + { if (this->settings.intermediate_trace) { this->traceTaggedValue(TRACE_PREFIX_FUNCTION, NULL, false, n, v); } }; inline void traceMessage(RexxString *n, RexxObject *v) - { if (this->settings.intermediate_trace) { this->traceValue(n, TRACE_PREFIX_MESSAGE_NAME); this->traceValue(v, TRACE_PREFIX_MESSAGE);} }; + { if (this->settings.intermediate_trace) { this->traceTaggedValue(TRACE_PREFIX_MESSAGE, NULL, true, n, v); } }; inline void traceOperator(RexxString *n, RexxObject *v) - { if (this->settings.intermediate_trace) { this->traceValue(n, TRACE_PREFIX_OPERATOR_NAME); this->traceValue(v, TRACE_PREFIX_OPERATOR);} }; + { if (this->settings.intermediate_trace) { this->traceTaggedValue(TRACE_PREFIX_OPERATOR, NULL, true, n, v); } }; inline void tracePrefix(RexxString *n, RexxObject *v) - { if (this->settings.intermediate_trace) { this->traceValue(n, TRACE_PREFIX_PREFIX_NAME); this->traceValue(v, TRACE_PREFIX_PREFIX);} }; - inline void traceCompoundName(RexxString *stem, RexxCompoundTail *tail) { if (this->settings.intermediate_trace) this->traceValue(tail->createCompoundName(stem), TRACE_PREFIX_COMPOUND); }; - inline void traceCompoundName(RexxString *stem, RexxString *tail) { if (this->settings.intermediate_trace) this->traceValue(stem->concat(tail), TRACE_PREFIX_COMPOUND); }; + { if (this->settings.intermediate_trace) { this->traceTaggedValue(TRACE_PREFIX_PREFIX, NULL, true, n, v); } }; + inline void traceCompoundName(RexxString *stem, RexxObject **tails, size_t tailCount, RexxCompoundTail *tail) { if (this->settings.intermediate_trace) this->traceCompoundValue(TRACE_PREFIX_COMPOUND, stem, tails, tailCount, tail->createCompoundName(stem)); }; + inline void traceCompoundName(RexxString *stem, RexxObject **tails, size_t tailCount, RexxString *tail) { if (this->settings.intermediate_trace) this->traceCompoundValue(TRACE_PREFIX_COMPOUND, stem, tails, tailCount, stem->concat(tail)); }; + inline void traceCompound(RexxString *stem, RexxObject **tails, size_t tailCount, RexxObject *value) { if (this->settings.intermediate_trace) this->traceCompoundValue(TRACE_PREFIX_VARIABLE, stem, tails, tailCount, value); }; inline void traceResult(RexxObject * v) { if ((this->settings.flags&trace_results) || (this->settings.dbg_flags&dbg_trace)) this->traceValue(v, TRACE_PREFIX_RESULT); }; inline BOOL tracingInstructions(void) { return this->settings.flags&trace_all || this->settings.dbg_flags&dbg_trace;}; inline void traceInstruction(RexxInstruction * v) { if (this->settings.flags&trace_all) @@ -513,9 +516,9 @@ RexxObject *value = stem_table->evaluateCompoundVariableValue(this, &resolved_tail); /* need to trace? */ if (tracingIntermediates()) { - traceCompoundName(stem, &resolved_tail); + traceCompoundName(stem, tail, tailCount, &resolved_tail); /* trace variable value */ - traceIntermediate(value, TRACE_PREFIX_VARIABLE); + traceCompound(stem, tail, tailCount, value); } return value; } @@ -571,7 +574,7 @@ /* and set the value */ stem_table->setCompoundVariable(&resolved_tail, value); /* trace resolved compound name */ - traceCompoundName(stem, &resolved_tail); + traceCompoundName(stem, tail, tailCount, &resolved_tail); } inline void setLocalCompoundVariable(RexxString *stem, size_t index, RexxObject **tail, size_t tailCount, RexxObject *value) Modified: interpreter-3.x/trunk/kernel/runtime/RexxCompoundTail.cpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/RexxCompoundTail.cpp 2007-06-29 12:44:32 UTC (rev 527) +++ interpreter-3.x/trunk/kernel/runtime/RexxCompoundTail.cpp 2007-06-29 13:31:47 UTC (rev 528) @@ -46,6 +46,7 @@ #include "StringClass.hpp" #include "RexxCompoundTail.hpp" #include "RexxBuffer.hpp" +#include "ExpressionVariable.hpp" void RexxCompoundTail::buildTail( @@ -182,6 +183,40 @@ } +void RexxCompoundTail::buildUnresolvedTail( + RexxObject **tails, /* tail elements */ + size_t count) /* number of tail elements */ +/******************************************************************************/ +/* Function: Build a tail value from a set of tail elements without doing */ +/* variable resolution. */ +/******************************************************************************/ +{ + bool first = true; /* first tail piece indicator */ + + for (size_t i = 0; i < count; i++) { + if (!first) { /* if not the first tail piece */ + addDot(); /* add a dot to the buffer */ + } + first = false; /* we need to add a dot from here on */ + RexxObject *part = tails[i]; + // this could be ommitted + if (part != OREF_NULL) + { + // if this is a variable, just copy the name. Otherwixe, copy the value + if (OTYPE(ParseVariable, part)) + { + ((RexxParseVariable *)part)->getName()->copyIntoTail(this); + } + else + { + part->stringValue()->copyIntoTail(this); + } + } + } + length = current - tail; /* set the final, updated length */ +} + + void RexxCompoundTail::buildTail( RexxString *tail) /* the single string index */ /******************************************************************************/ Modified: interpreter-3.x/trunk/kernel/runtime/RexxCompoundTail.hpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/RexxCompoundTail.hpp 2007-06-29 12:44:32 UTC (rev 527) +++ interpreter-3.x/trunk/kernel/runtime/RexxCompoundTail.hpp 2007-06-29 13:31:47 UTC (rev 528) @@ -67,6 +67,19 @@ init(); /* do the common initialization */ buildTail(tails, count); /* build the full tail up */ } + + inline RexxCompoundTail(RexxObject **tails, size_t count, bool resolve) { + init(); /* do the common initialization */ + if (resolve) + { + buildTail(tails, count); /* build the full tail up */ + } + else + { + buildUnresolvedTail(tails, count); /* build the full tail up */ + } + } + inline RexxCompoundTail(RexxString *tails, size_t count) { init(); /* do the common initialization */ buildTail(tails, count); /* build the full tail up */ @@ -122,6 +135,7 @@ void buildTail(RexxVariableDictionary *dictionary, RexxObject **tails, size_t tailCount); void buildTail(RexxActivation *context, RexxObject **tails, size_t tailCount); void buildTail(RexxObject **tails, size_t count); + void buildUnresolvedTail(RexxObject **tails, size_t count); void buildTail(RexxString *tail); void buildTail(RexxString *tail, size_t index); void buildTail(size_t index); @@ -135,6 +149,9 @@ return rc; } + inline size_t getLength() { return length; } + inline UCHAR *getTail() { return tail; } + size_t length; /* length of the buffer (current) */ size_t remainder; /* remaining length in the buffer */ UCHAR *tail; /* the start of the tail buffer */ Modified: interpreter-3.x/trunk/kernel/runtime/RexxCore.h =================================================================== --- interpreter-3.x/trunk/kernel/runtime/RexxCore.h 2007-06-29 12:44:32 UTC (rev 527) +++ interpreter-3.x/trunk/kernel/runtime/RexxCore.h 2007-06-29 13:31:47 UTC (rev 528) @@ -114,12 +114,6 @@ TRACE_PREFIX_COMPOUND , TRACE_PREFIX_MESSAGE , TRACE_PREFIX_ARGUMENT , - TRACE_PREFIX_VARIABLE_NAME, - TRACE_PREFIX_DOTVARIABLE_NAME, - TRACE_PREFIX_FUNCTION_NAME, - TRACE_PREFIX_OPERATOR_NAME, - TRACE_PREFIX_PREFIX_NAME, - TRACE_PREFIX_MESSAGE_NAME, }; #define MAX_TRACEBACK_LIST 80 /* 40 messages are displayed */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2007-07-03 22:51:16
|
Revision: 553 http://svn.sourceforge.net/oorexx/?rev=553&view=rev Author: bigrixx Date: 2007-07-03 15:51:17 -0700 (Tue, 03 Jul 2007) Log Message: ----------- [ 1747343 ] Please add method "caselessAbbrev" to "String" class [ 1747346 ] Please rename class "DescendingCaselessComparator" to ... Modified Paths: -------------- interpreter-3.x/trunk/kernel/RexxClasses/CoreClasses.orx interpreter-3.x/trunk/kernel/classes/StringClass.hpp interpreter-3.x/trunk/kernel/classes/StringClassMisc.cpp interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp interpreter-3.x/trunk/kernel/runtime/Setup.cpp Modified: interpreter-3.x/trunk/kernel/RexxClasses/CoreClasses.orx =================================================================== --- interpreter-3.x/trunk/kernel/RexxClasses/CoreClasses.orx 2007-07-03 20:39:14 UTC (rev 552) +++ interpreter-3.x/trunk/kernel/RexxClasses/CoreClasses.orx 2007-07-03 22:51:17 UTC (rev 553) @@ -110,7 +110,7 @@ .environment~setentry('COMPARATOR', .comparator) .environment~setentry('DESCENDINGCOMPARATOR', .descendingcomparator) .environment~setentry('CASELESSCOMPARATOR', .caselesscomparator) -.environment~setentry('DESCENDINGCASELESSCOMPARATOR', .descendingcaselesscomparator) +.environment~setentry('CASELESSDESCENDINGCOMPARATOR', .caselessdescendingcomparator) .environment~setentry('COLUMNCOMPARATOR', .columncomparator) .environment~setentry('CASELESSCOLUMNCOMPARATOR', .caselesscolumncomparator) .environment~setentry('INVERTINGCOMPARATOR', .invertingcomparator) @@ -834,7 +834,7 @@ use strict arg left, right return left~caselessCompareTo(right) -::CLASS 'DescendingCaselessComparator' MIXINCLASS Comparator +::CLASS 'CaselessDescendingComparator' MIXINCLASS Comparator ::METHOD compare use strict arg left, right return -left~caselessCompareTo(right) Modified: interpreter-3.x/trunk/kernel/classes/StringClass.hpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/StringClass.hpp 2007-07-03 20:39:14 UTC (rev 552) +++ interpreter-3.x/trunk/kernel/classes/StringClass.hpp 2007-07-03 22:51:17 UTC (rev 553) @@ -187,6 +187,7 @@ RexxString *changeStr(RexxString *, RexxString *); RexxString *caselessChangeStr(RexxString *, RexxString *); RexxInteger *abbrev(RexxString *, RexxInteger *); + RexxInteger *caselessAbbrev(RexxString *, RexxInteger *); RexxInteger *compare(RexxString *, RexxString *); RexxInteger *caselessCompare(RexxString *, RexxString *); RexxString *copies(RexxInteger *); Modified: interpreter-3.x/trunk/kernel/classes/StringClassMisc.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/StringClassMisc.cpp 2007-07-03 20:39:14 UTC (rev 552) +++ interpreter-3.x/trunk/kernel/classes/StringClassMisc.cpp 2007-07-03 22:51:17 UTC (rev 553) @@ -420,6 +420,39 @@ } +RexxInteger *RexxString::caselessAbbrev(RexxString *info, RexxInteger *length) +{ + size_t Len1; /* length of string1 */ + size_t Len2; /* length of string1 */ + size_t ChkLen; /* required check length */ + INT rc; /* compare result */ + + // the info must be a string value + info = get_string(info, ARG_ONE); + stringsize_t len2 = info->getLength(); + // the check length is optional, and defaults to the length of info. + stringsize_t chkLen = optional_length(length, len2, ARG_TWO); + + stringsize_t len1 = this->getLength(); + + // if a null string match is allowed, this is true + if (chkLen == 0 && len2 == 0) + { + return TheTrueObject; + } + + // if the info is a null string, no match is possible + // if the target string is shorter than the check length, also no match + // if the info string is shorter than this string, not a match. + if (len1 == 0 || (len2 < chkLen) || (len1 < len2)) + { + return TheFalseObject; + } + /* do the comparison */ + return(CaselessCompare((PUCHAR)this->getStringData(), (PUCHAR)info->getStringData(), len2) == 0) ? TheTrueObject : TheFalseObject; +} + + RexxInteger *RexxString::compare( RexxString *string2, /* other string to compare against */ RexxString *pad) /* optional padding character */ Modified: interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp 2007-07-03 20:39:14 UTC (rev 552) +++ interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp 2007-07-03 22:51:17 UTC (rev 553) @@ -419,6 +419,7 @@ /*now names for the builtin functions */ CHARCONSTANT(ABBREV, "ABBREV"); +CHARCONSTANT(CASELESSABBREV, "CASELESSABBREV"); CHARCONSTANT(ABS, "ABS"); CHARCONSTANT(ABSTRACT, "ABSTRACT"); CHARCONSTANT(ADDRESS, "ADDRESS"); Modified: interpreter-3.x/trunk/kernel/runtime/Setup.cpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/Setup.cpp 2007-07-03 20:39:14 UTC (rev 552) +++ interpreter-3.x/trunk/kernel/runtime/Setup.cpp 2007-07-03 22:51:17 UTC (rev 553) @@ -423,6 +423,7 @@ CPPMSTR(RexxString::countStrRexx), CPPMSTR(RexxString::caselessCountStrRexx), CPPMSTR(RexxString::abbrev), +CPPMSTR(RexxString::caselessAbbrev), CPPMSTR(RexxString::compare), CPPMSTR(RexxString::caselessCompare), CPPMSTR(RexxString::copies), @@ -1220,6 +1221,7 @@ defineKernelMethod(CHAR_CASELESSWORDPOS ,TheStringBehaviour, CPPMSTR(RexxString::caselessWordPos), 2); defineKernelMethod(CHAR_WORDS ,TheStringBehaviour, CPPMSTR(RexxString::words), 0); defineKernelMethod(CHAR_ABBREV ,TheStringBehaviour, CPPMSTR(RexxString::abbrev), 2); + defineKernelMethod(CHAR_CASELESSABBREV ,TheStringBehaviour, CPPMSTR(RexxString::caselessAbbrev), 2); defineKernelMethod(CHAR_CHANGESTR ,TheStringBehaviour, CPPMSTR(RexxString::changeStr), 2); defineKernelMethod(CHAR_CASELESSCHANGESTR ,TheStringBehaviour, CPPMSTR(RexxString::caselessChangeStr), 2); defineKernelMethod(CHAR_COMPARE ,TheStringBehaviour, CPPMSTR(RexxString::compare), 2); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2007-07-17 11:26:50
|
Revision: 600 http://svn.sourceforge.net/oorexx/?rev=600&view=rev Author: bigrixx Date: 2007-07-17 04:26:52 -0700 (Tue, 17 Jul 2007) Log Message: ----------- [ 1755232 ] 3.1.2 tokenized program crashes on 3.2.0 revsion 590 Modified Paths: -------------- interpreter-3.x/trunk/kernel/classes/StringClass.hpp interpreter-3.x/trunk/kernel/expression/ExpressionOperator.cpp interpreter-3.x/trunk/kernel/expression/ExpressionOperator.hpp interpreter-3.x/trunk/kernel/parser/InstructionParser.cpp interpreter-3.x/trunk/kernel/parser/SourceFile.cpp interpreter-3.x/trunk/kernel/runtime/RexxActivation.cpp interpreter-3.x/trunk/kernel/runtime/RexxActivation.hpp Modified: interpreter-3.x/trunk/kernel/classes/StringClass.hpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/StringClass.hpp 2007-07-16 17:47:38 UTC (rev 599) +++ interpreter-3.x/trunk/kernel/classes/StringClass.hpp 2007-07-17 11:26:52 UTC (rev 600) @@ -303,7 +303,7 @@ inline size_t getLength() { return this->length; }; inline PCHAR getStringData() { return this->stringData; }; - inline void put(size_t s, const void *b, int l) { memcpy((this->stringData+s),b,(size_t)l); }; + inline void put(size_t s, const void *b, size_t l) { memcpy((this->stringData+s), b, l); }; inline void put(size_t s, RexxString *o) { put(s, o->getStringData(), o->getLength()); }; inline void set(size_t s,int c,int l) { memset((this->stringData+s),c,(size_t)l); }; inline char getChar(size_t p) { return *(this->stringData+p); }; Modified: interpreter-3.x/trunk/kernel/expression/ExpressionOperator.cpp =================================================================== --- interpreter-3.x/trunk/kernel/expression/ExpressionOperator.cpp 2007-07-16 17:47:38 UTC (rev 599) +++ interpreter-3.x/trunk/kernel/expression/ExpressionOperator.cpp 2007-07-17 11:26:52 UTC (rev 600) @@ -36,7 +36,7 @@ /* */ /*----------------------------------------------------------------------------*/ /******************************************************************************/ -/* REXX Translator ExpressionOperator.c */ +/* REXX Translator ExpressionOperator.c */ /* */ /* Primitive Operator Parse Class */ /* */ @@ -46,8 +46,45 @@ #include "RexxActivation.hpp" #include "ExpressionOperator.hpp" +const char *RexxExpressionOperator::operatorNames[] = +{ + "+", + "-", + "*", + "/", + "%", + "//", + "**", + "", + "||", + " ", + "=", + "\\=", + ">", + "\\>", + "<", + "\\<", + ">=", + "<=", + "==", + "\\==", + ">>", + "\\>>", + "<<", + "\\<<", + ">>=", + "<<=", + "<>", + "><", + "&", + "|", + "&&", + "\\", +}; + + + RexxExpressionOperator::RexxExpressionOperator( - RexxString *name, /* character name of operator */ INT oper, /* operator index */ RexxObject *left, /* left expression objects */ RexxObject *right) /* right expression objects */ @@ -57,7 +94,6 @@ { ClearObject(this); /* start completely clean */ /* just fill in the three terms */ - this->u_name = name; this->oper = oper; OrefSet(this, this->left_term, left); OrefSet(this, this->right_term, right); @@ -84,14 +120,14 @@ /* replace top two stack elements */ stack->operatorResult(result); /* with this one */ /* trace if necessary */ - context->traceOperator(u_name, result); + context->traceOperator(operatorName(), result); } else { /* prefix operator */ /* process this directly */ result = callOperatorMethod(left_term, this->oper, OREF_NULL); stack->prefixResult(result); /* replace the top element */ /* trace if necessary */ - context->tracePrefix(u_name, result); + context->tracePrefix(operatorName(), result); } return result; /* return the result */ } @@ -116,7 +152,7 @@ /* replace top two stack elements */ stack->operatorResult(result); /* with this one */ /* trace if necessary */ - context->traceOperator(u_name, result); + context->traceOperator(operatorName(), result); return result; /* return the result */ } @@ -136,7 +172,7 @@ result = callOperatorMethod(left_term, this->oper, OREF_NULL); stack->prefixResult(result); /* replace the top element */ /* trace if necessary */ - context->tracePrefix(u_name, result); + context->tracePrefix(operatorName(), result); return result; /* return the result */ } @@ -146,7 +182,6 @@ /******************************************************************************/ { setUpMemoryMark - memory_mark(this->u_name); memory_mark(this->left_term); memory_mark(this->right_term); cleanUpMemoryMark @@ -158,7 +193,6 @@ /******************************************************************************/ { setUpMemoryMarkGeneral - memory_mark_general(this->u_name); memory_mark_general(this->left_term); memory_mark_general(this->right_term); cleanUpMemoryMarkGeneral @@ -171,7 +205,6 @@ { setUpFlatten(RexxExpressionOperator) - flatten_reference(newThis->u_name, envelope); flatten_reference(newThis->left_term, envelope); flatten_reference(newThis->right_term, envelope); Modified: interpreter-3.x/trunk/kernel/expression/ExpressionOperator.hpp =================================================================== --- interpreter-3.x/trunk/kernel/expression/ExpressionOperator.hpp 2007-07-16 17:47:38 UTC (rev 599) +++ interpreter-3.x/trunk/kernel/expression/ExpressionOperator.hpp 2007-07-17 11:26:52 UTC (rev 600) @@ -47,7 +47,7 @@ class RexxExpressionOperator : public RexxInternalObject { public: inline RexxExpressionOperator() { ; } - RexxExpressionOperator(RexxString *name, INT, RexxObject *, RexxObject *); + RexxExpressionOperator(INT, RexxObject *, RexxObject *); inline RexxExpressionOperator(RESTORETYPE restoreType) { ; }; void live(); void liveGeneral(); @@ -56,6 +56,11 @@ inline void *operator new(size_t size, void *ptr) {return ptr;}; RexxObject *evaluate(RexxActivation *, RexxExpressionStack *); + inline const char *operatorName() { return operatorNames[oper - 1]; } + + // table of operator names + static const char *operatorNames[]; + INT oper; /* operator to perform */ RexxObject *right_term; /* right term of the operator */ RexxObject *left_term; /* left term of the operator */ @@ -63,8 +68,8 @@ class RexxBinaryOperator : public RexxExpressionOperator { public: - inline RexxBinaryOperator(RexxString *name, INT oper, RexxObject *left, RexxObject *right) - : RexxExpressionOperator(name, oper, left, right) { ; } + inline RexxBinaryOperator(INT oper, RexxObject *left, RexxObject *right) + : RexxExpressionOperator(oper, left, right) { ; } inline RexxBinaryOperator(RESTORETYPE restoreType) { ; }; void *operator new(size_t); inline void *operator new(size_t size, void *ptr) {return ptr;}; @@ -73,8 +78,8 @@ class RexxUnaryOperator : public RexxExpressionOperator { public: - inline RexxUnaryOperator(RexxString *name, INT oper, RexxObject *left) - : RexxExpressionOperator(name, oper, left, OREF_NULL) { ; } + inline RexxUnaryOperator(INT oper, RexxObject *left) + : RexxExpressionOperator(oper, left, OREF_NULL) { ; } inline RexxUnaryOperator(RESTORETYPE restoreType) { ; }; void *operator new(size_t); inline void *operator new(size_t size, void *ptr) {return ptr;}; Modified: interpreter-3.x/trunk/kernel/parser/InstructionParser.cpp =================================================================== --- interpreter-3.x/trunk/kernel/parser/InstructionParser.cpp 2007-07-16 17:47:38 UTC (rev 599) +++ interpreter-3.x/trunk/kernel/parser/InstructionParser.cpp 2007-07-17 11:26:52 UTC (rev 600) @@ -200,10 +200,8 @@ // we need an evaluator for both the expression and the assignment RexxObject *variable = addText(target); - // we need the operator name from the composite - RexxString *opName = operation->value->extract(0, operation->value->getLength() - 1); // now add a binary operator to this expression tree - expression = (RexxObject *)new RexxBinaryOperator(opName, operation->subclass, variable, expression); + expression = (RexxObject *)new RexxBinaryOperator(operation->subclass, variable, expression); // now everything is the same as an assignment operator RexxObject *newObject = new_instruction(ASSIGNMENT, Assignment); @@ -1214,10 +1212,8 @@ message->makeAssignment(this); // convert into an assignment message (the original message term) - // we need the operator name from the composite - RexxString *opName = operation->value->extract(0, operation->value->getLength() - 1); // now add a binary operator to this expression tree - expression = (RexxObject *)new RexxBinaryOperator(opName, operation->subclass, retriever, expression); + expression = (RexxObject *)new RexxBinaryOperator(operation->subclass, retriever, expression); // allocate a new object. NB: a message instruction gets an extra argument, so we don't subtract one. RexxObject *newObject = new_variable_instruction(MESSAGE, Message, sizeof(RexxInstructionMessage) + (message->argumentCount) * sizeof(OREF)); Modified: interpreter-3.x/trunk/kernel/parser/SourceFile.cpp =================================================================== --- interpreter-3.x/trunk/kernel/parser/SourceFile.cpp 2007-07-16 17:47:38 UTC (rev 599) +++ interpreter-3.x/trunk/kernel/parser/SourceFile.cpp 2007-07-17 11:26:52 UTC (rev 600) @@ -3311,7 +3311,7 @@ report_error_token(Error_Invalid_expression_general, token); /* create a new operation */ RexxToken *op = popOperator(); - subexpression = (RexxObject *)new RexxBinaryOperator(op->value, op->subclass, left, right); + subexpression = (RexxObject *)new RexxBinaryOperator(op->subclass, left, right); /* push this back on the term stack */ this->pushTerm(subexpression); } @@ -3362,7 +3362,7 @@ /* this is an invalid expression */ report_error_token(Error_Invalid_expression_general, token); /* create a new operation */ - subexpression = (RexxObject *)new RexxBinaryOperator (token->value, token->subclass, left, right); + subexpression = (RexxObject *)new RexxBinaryOperator(token->subclass, left, right); this->pushTerm(subexpression); /* push this back on the term stack */ token = this->popOperator(); /* get top operator token */ } @@ -3670,7 +3670,7 @@ /* this is an error */ report_error_token(Error_Invalid_expression_prefix, token); /* create the new operator term */ - term = (RexxObject *)new RexxUnaryOperator(token->value, token->subclass, term); + term = (RexxObject *)new RexxUnaryOperator(token->subclass, term); break; default: /* other operators not allowed here */ Modified: interpreter-3.x/trunk/kernel/runtime/RexxActivation.cpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/RexxActivation.cpp 2007-07-16 17:47:38 UTC (rev 599) +++ interpreter-3.x/trunk/kernel/runtime/RexxActivation.cpp 2007-07-17 11:26:52 UTC (rev 600) @@ -2502,6 +2502,90 @@ /** + * Trace an entry that's of the form 'tag => "value"'. + * + * @param prefix The trace prefix tag to use. + * @param tagPrefix Any prefix string added to the tag. Use mostly for adding + * the "." to traced environment variables. + * @param quoteTag Indicates whether the tag should be quoted or not. Operator + * names are quoted. + * @param tag The tag name. + * @param value The associated trace value. + */ +void RexxActivation::traceOperatorValue(int prefix, const char *tag, RexxObject *value) +{ + // the trace settings would normally require us to trace this, but there are conditions + // where we just skip doing this anyway. + if (this->settings.flags&trace_suppress || this->debug_pause || value == OREF_NULL || !source->traceable()) + { + return; + } + + // get the string value from the traced object. + RexxString *stringValue = value->stringValue(); + // protect against negative indent values (belt and braces) + if (this->settings.traceindent < 0) + { + + this->settings.traceindent = 0; + } + + // now calculate the length of the traced string + stringsize_t outLength = strlen(tag) + stringValue->getLength(); + // these are fixed overheads + outLength += TRACE_OVERHEAD + strlen(VALUE_MARKER); + // now the indent spacing + outLength += this->settings.traceindent * INDENT_SPACING; + // now other conditionals + outLength += QUOTES_OVERHEAD; + + // now get a buffer to write this out into + RexxString *buffer = raw_string(outLength); + save(buffer); + + // get a cursor for filling in the formatted data + stringsize_t dataOffset = TRACE_OVERHEAD + this->settings.traceindent * INDENT_SPACING - 2; + /* insert the leading blanks */ + buffer->set(0, ' ', TRACE_OVERHEAD + this->settings.traceindent * INDENT_SPACING); + /* add the trace prefix */ + buffer->put(PREFIX_OFFSET, trace_prefix_table[prefix], PREFIX_LENGTH); + + // operators are quoted. + buffer->putChar(dataOffset, '\"'); + dataOffset++; + + // add in the tag name + buffer->put(dataOffset, tag, strlen(tag)); + dataOffset += strlen(tag); + + // need a closing quote. + buffer->putChar(dataOffset, '\"'); + dataOffset++; + + // now add the data marker + buffer->put(dataOffset, VALUE_MARKER, strlen(VALUE_MARKER)); + dataOffset += strlen(VALUE_MARKER); + + // the leading quote around the value + buffer->putChar(dataOffset, '\"'); + dataOffset++; + + // the traced value + buffer->put(dataOffset, stringValue); + dataOffset += stringValue->getLength(); + + // and finally, the trailing quote + buffer->putChar(dataOffset, '\"'); + dataOffset++; + + buffer->generateHash(); /* done building the string */ + /* write out the line */ + this->activity->traceOutput(this, buffer); + discard(buffer); +} + + +/** * Trace a compound variable entry that's of the form 'tag => * "value"'. * Modified: interpreter-3.x/trunk/kernel/runtime/RexxActivation.hpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/RexxActivation.hpp 2007-07-16 17:47:38 UTC (rev 599) +++ interpreter-3.x/trunk/kernel/runtime/RexxActivation.hpp 2007-07-17 11:26:52 UTC (rev 600) @@ -244,6 +244,7 @@ void traceValue(RexxObject *, int); void traceCompoundValue(int prefix, RexxString *stem, RexxObject **tails, size_t tailCount, RexxObject * value); void traceTaggedValue(int prefix, stringchar_t *tagPrefix, bool quoteTag, RexxString *tag, RexxObject * value); + void traceOperatorValue(int prefix, const char *tag, RexxObject *value); void traceSourceString(); void traceClause(RexxInstruction *, int); void resetElapsed(); @@ -350,10 +351,10 @@ { if (this->settings.intermediate_trace) { this->traceTaggedValue(TRACE_PREFIX_FUNCTION, NULL, false, n, v); } }; inline void traceMessage(RexxString *n, RexxObject *v) { if (this->settings.intermediate_trace) { this->traceTaggedValue(TRACE_PREFIX_MESSAGE, NULL, true, n, v); } }; - inline void traceOperator(RexxString *n, RexxObject *v) - { if (this->settings.intermediate_trace) { this->traceTaggedValue(TRACE_PREFIX_OPERATOR, NULL, true, n, v); } }; - inline void tracePrefix(RexxString *n, RexxObject *v) - { if (this->settings.intermediate_trace) { this->traceTaggedValue(TRACE_PREFIX_PREFIX, NULL, true, n, v); } }; + inline void traceOperator(const char *n, RexxObject *v) + { if (this->settings.intermediate_trace) { this->traceOperatorValue(TRACE_PREFIX_OPERATOR, n, v); } }; + inline void tracePrefix(const char *n, RexxObject *v) + { if (this->settings.intermediate_trace) { this->traceOperatorValue(TRACE_PREFIX_PREFIX, n, v); } }; inline void traceCompoundName(RexxString *stem, RexxObject **tails, size_t tailCount, RexxCompoundTail *tail) { if (this->settings.intermediate_trace) this->traceCompoundValue(TRACE_PREFIX_COMPOUND, stem, tails, tailCount, tail->createCompoundName(stem)); }; inline void traceCompoundName(RexxString *stem, RexxObject **tails, size_t tailCount, RexxString *tail) { if (this->settings.intermediate_trace) this->traceCompoundValue(TRACE_PREFIX_COMPOUND, stem, tails, tailCount, stem->concat(tail)); }; inline void traceCompound(RexxString *stem, RexxObject **tails, size_t tailCount, RexxObject *value) { if (this->settings.intermediate_trace) this->traceCompoundValue(TRACE_PREFIX_VARIABLE, stem, tails, tailCount, value); }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2007-07-19 13:28:39
|
Revision: 606 http://svn.sourceforge.net/oorexx/?rev=606&view=rev Author: bigrixx Date: 2007-07-19 06:28:41 -0700 (Thu, 19 Jul 2007) Log Message: ----------- [ 1756792 ] Add method to retrieve immediate superclass of a class. Modified Paths: -------------- interpreter-3.x/trunk/kernel/classes/ClassClass.cpp interpreter-3.x/trunk/kernel/runtime/Setup.cpp Modified: interpreter-3.x/trunk/kernel/classes/ClassClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/ClassClass.cpp 2007-07-18 22:50:30 UTC (rev 605) +++ interpreter-3.x/trunk/kernel/classes/ClassClass.cpp 2007-07-19 13:28:41 UTC (rev 606) @@ -285,9 +285,16 @@ /* Function: Return the first superclass in the superclass list */ /*****************************************************************************/ { - /* get the first item from the list */ - return (RexxClass *)this->instanceSuperClasses->get(1); + // object has no superclasses + if (this == TheObjectClass) + { + return (RexxClass *)TheNilObject; + } + // get the first item from the immediate list. + return (RexxClass *)this->instanceSuperClasses->get(1); } + + RexxArray *RexxClass::getSuperClasses() /*****************************************************************************/ /* Function: Return an array of the superclasses */ Modified: interpreter-3.x/trunk/kernel/runtime/Setup.cpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/Setup.cpp 2007-07-18 22:50:30 UTC (rev 605) +++ interpreter-3.x/trunk/kernel/runtime/Setup.cpp 2007-07-19 13:28:41 UTC (rev 606) @@ -122,6 +122,7 @@ CPPMC(RexxClass::getSomClass), CPPMC(RexxClass::setSomClass), CPPMC(RexxClass::getSuperClasses), +CPPMC(RexxClass::getSuperClass), CPPMC(RexxClass::getSubClasses), CPPMC(RexxClass::defmeths), CPPMC(RexxClass::defineMethod), @@ -752,6 +753,7 @@ defineKernelMethod(CHAR_SUBCLASS ,TheClassBehaviour, CPPMC(RexxClass::subclass), 3); defineProtectedKernelMethod(CHAR_SUBCLASSES ,TheClassBehaviour, CPPMC(RexxClass::getSubClasses), 0); defineProtectedKernelMethod(CHAR_SUPERCLASSES ,TheClassBehaviour, CPPMC(RexxClass::getSuperClasses), 0); + defineProtectedKernelMethod(CHAR_SUPERCLASS ,TheClassBehaviour, CPPMC(RexxClass::getSuperClass), 0); defineProtectedKernelMethod(CHAR_UNINHERIT ,TheClassBehaviour, CPPMC(RexxClass::uninherit), 1); /* Class operator methods.... */ defineKernelMethod(CHAR_EQUAL ,TheClassBehaviour, CPPMC(RexxClass::equal), 1); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2007-08-02 11:01:37
|
Revision: 642 http://oorexx.svn.sourceforge.net/oorexx/?rev=642&view=rev Author: bigrixx Date: 2007-08-02 04:01:32 -0700 (Thu, 02 Aug 2007) Log Message: ----------- [ oorexx-Bugs-1765994 ] Bug in comparator implementation causes a crash of ooRexx Modified Paths: -------------- interpreter-3.x/trunk/kernel/classes/ArrayClass.cpp interpreter-3.x/trunk/kernel/classes/ObjectClass.cpp interpreter-3.x/trunk/kernel/messages/DocErrorMessages.sgml interpreter-3.x/trunk/kernel/messages/rexxmsg.xml interpreter-3.x/trunk/kernel/platform/windows/winmsgtb.rc Modified: interpreter-3.x/trunk/kernel/classes/ArrayClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/ArrayClass.cpp 2007-07-28 22:07:35 UTC (rev 641) +++ interpreter-3.x/trunk/kernel/classes/ArrayClass.cpp 2007-08-02 11:01:32 UTC (rev 642) @@ -2193,6 +2193,11 @@ wholenumber_t RexxArray::sortCompare(RexxObject *comparator, RexxObject *left, RexxObject *right) { RexxObject *result = comparator->sendMessage(OREF_COMPARE, left, right); + if (result == OREF_NULL) + { + reportException(Error_No_result_object_message, OREF_COMPARE); + } + wholenumber_t comparison = result->longValue(DEFAULT_DIGITS); if (comparison == NO_LONG) { Modified: interpreter-3.x/trunk/kernel/classes/ObjectClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/ObjectClass.cpp 2007-07-28 22:07:35 UTC (rev 641) +++ interpreter-3.x/trunk/kernel/classes/ObjectClass.cpp 2007-08-02 11:01:32 UTC (rev 642) @@ -157,6 +157,10 @@ wholenumber_t RexxObject::compareTo(RexxObject *other ) { RexxObject *result = sendMessage(OREF_COMPARETO, other); + if (result == OREF_NULL) + { + reportException(Error_No_result_object_message, OREF_COMPARETO); + } wholenumber_t comparison = result->longValue(DEFAULT_DIGITS); if (comparison == NO_LONG) { Modified: interpreter-3.x/trunk/kernel/messages/DocErrorMessages.sgml =================================================================== --- interpreter-3.x/trunk/kernel/messages/DocErrorMessages.sgml 2007-07-28 22:07:35 UTC (rev 641) +++ interpreter-3.x/trunk/kernel/messages/DocErrorMessages.sgml 2007-08-02 11:01:32 UTC (rev 642) @@ -2480,7 +2480,7 @@ <varlistentry> <term>999</term> <listitem> -<para>Message "<emphasis>message</emphasis>" did not return a result object</para> +<para>Message "<emphasis>message</emphasis>" did not return a result</para> </listitem> </varlistentry> </variablelist> Modified: interpreter-3.x/trunk/kernel/messages/rexxmsg.xml =================================================================== --- interpreter-3.x/trunk/kernel/messages/rexxmsg.xml 2007-07-28 22:07:35 UTC (rev 641) +++ interpreter-3.x/trunk/kernel/messages/rexxmsg.xml 2007-08-02 11:01:32 UTC (rev 642) @@ -3342,7 +3342,7 @@ <Component>Rexx</Component> <Severity>Warning</Severity> <SymbolicName>Error_No_result_object_message</SymbolicName> - <Text>Message <q><Sub position="1" name="message"/></q> did not return a result object</Text> + <Text>Message <q><Sub position="1" name="message"/></q> did not return a result</Text> </SubMessage> </Subcodes> </Message> Modified: interpreter-3.x/trunk/kernel/platform/windows/winmsgtb.rc =================================================================== --- interpreter-3.x/trunk/kernel/platform/windows/winmsgtb.rc 2007-07-28 22:07:35 UTC (rev 641) +++ interpreter-3.x/trunk/kernel/platform/windows/winmsgtb.rc 2007-08-02 11:01:32 UTC (rev 642) @@ -364,7 +364,7 @@ Error_External_name_not_found_class "Unable to find external class ""&1""" Error_External_name_not_found_method "Unable to find external method ""&1""" Error_External_name_not_found_routine "Unable to find external routine ""&1""" - Error_No_result_object_message "Message ""&1"" did not return a result object" + Error_No_result_object_message "Message ""&1"" did not return a result" Error_Incorrect_method_minarg "Not enough arguments in method; &1 expected" Error_Incorrect_method_maxarg "Too many arguments in invocation of method; &1 expected" Error_Incorrect_method_noarg "Missing argument in method; argument &1 is required" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2007-08-06 14:53:09
|
Revision: 650 http://oorexx.svn.sourceforge.net/oorexx/?rev=650&view=rev Author: bigrixx Date: 2007-08-06 07:53:12 -0700 (Mon, 06 Aug 2007) Log Message: ----------- Normalize PROTECTED/UNPROTECTED and PUBLIC/PRIVATE keywords on directives. Modified Paths: -------------- interpreter-3.x/trunk/kernel/parser/SourceFile.cpp interpreter-3.x/trunk/kernel/parser/Token.hpp interpreter-3.x/trunk/kernel/runtime/RexxConstants.cpp interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp Modified: interpreter-3.x/trunk/kernel/parser/SourceFile.cpp =================================================================== --- interpreter-3.x/trunk/kernel/parser/SourceFile.cpp 2007-08-06 11:51:26 UTC (rev 649) +++ interpreter-3.x/trunk/kernel/parser/SourceFile.cpp 2007-08-06 14:53:12 UTC (rev 650) @@ -1533,10 +1533,13 @@ #define GUARDED_METHOD 1 /* method is a guarded one */ #define UNGUARDED_METHOD 2 /* method is unguarded */ +#define DEFAULT_PROTECTION 0 /* using defualt protection */ +#define PROTECTED_METHOD 1 /* security manager permission needed*/ +#define UNPROTECTED_METHOD 2 /* no protection. */ -#define DEFAULT_GUARD 0 /* using defualt guarding */ -#define GUARDED_METHOD 1 /* method is a guarded one */ -#define UNGUARDED_METHOD 2 /* method is unguarded */ +#define DEFAULT_SCOPE 0 /* using defualt scope */ +#define PUBLIC_SCOPE 1 /* publicly accessible */ +#define PRIVATE_SCOPE 2 /* private scope */ /** * Process a ::CLASS directive for a source file. @@ -1584,7 +1587,7 @@ this->active_class->put(new_directory(), CLASS_CLASS_METHODS); /* save the ::class location */ this->active_class->put((RexxObject *)new RexxInstruction(this->clause, KEYWORD_CLASS), CLASS_DIRECTIVE); - bool Public = false; /* haven't seen the keyword yet */ + int Public = DEFAULT_SCOPE; /* haven't seen the keyword yet */ bool subclass = false; /* no subclass keyword yet */ RexxString *externalname = OREF_NULL; /* no external name yet */ RexxString *metaclass = OREF_NULL; /* no metaclass yet */ @@ -1621,13 +1624,24 @@ case SUBDIRECTIVE_PUBLIC: /* ::CLASS name PUBLIC */ - if (Public) /* already had one of these? */ + if (Public != DEFAULT_SCOPE) /* already had one of these? */ + { /* duplicates are invalid */ report_error_token(Error_Invalid_subkeyword_class, token); - Public = true; /* turn on the seen flag */ + } + Public = PUBLIC_SCOPE; /* turn on the seen flag */ /* just set this as a public object */ this->active_class->put((RexxObject *)TheTrueObject, CLASS_PUBLIC); break; + + case SUBDIRECTIVE_PRIVATE: /* ::CLASS name PUBLIC */ + if (Public != DEFAULT_SCOPE) /* already had one of these? */ + { + /* duplicates are invalid */ + report_error_token(Error_Invalid_subkeyword_class, token); + } + Public = PRIVATE_SCOPE; /* turn on the seen flag */ + break; /* ::CLASS name SUBCLASS sclass */ case SUBDIRECTIVE_SUBCLASS: if (subclass) /* already had one of these? */ @@ -1698,8 +1712,8 @@ void RexxSource::methodDirective() { this->flags &= ~requires_allowed;/* ::REQUIRES no longer valid */ - bool Private = false; /* this is a public method */ - bool Protected = false; /* and is not protected yet */ + int Private = DEFAULT_SCOPE; /* this is a public method */ + int Protected = DEFAULT_PROTECTION; /* and is not protected yet */ int guard = DEFAULT_GUARD; /* default is guarding */ bool Class = false; /* default is an instance method */ bool Attribute = false; /* init Attribute flag */ @@ -1710,8 +1724,10 @@ /* not a symbol or a string */ if (token->classId != TOKEN_SYMBOL && token->classId != TOKEN_LITERAL) + { /* report an error */ report_error_token(Error_Symbol_or_string_method, token); + } RexxString *name = token->value; /* get the string name */ /* and the name form also */ RexxString *internalname = this->commonString(name->upper()); @@ -1720,11 +1736,15 @@ token = nextReal(); /* get the next token */ /* reached the end? */ if (token->classId == TOKEN_EOC) + { break; /* get out of here */ + } /* not a symbol token? */ else if (token->classId != TOKEN_SYMBOL) + { /* report an error */ report_error_token(Error_Invalid_subkeyword_method, token); + } else { /* have some sort of option keyword */ /* process each sub keyword */ @@ -1733,20 +1753,26 @@ /* ::METHOD name CLASS */ case SUBDIRECTIVE_CLASS: if (Class) /* had one of these already? */ + { /* duplicates are invalid */ report_error_token(Error_Invalid_subkeyword_method, token); + } Class = true; /* flag this for later processing */ break; /* ::METHOD name EXTERNAL extname */ case SUBDIRECTIVE_EXTERNAL: /* already had an external? */ if (externalname != OREF_NULL || abstractMethod || Attribute) + { /* duplicates are invalid */ report_error_token(Error_Invalid_subkeyword_method, token); + } if (Attribute) /* ATTRIBUTE already specified ? */ /* EXTERNAL and ATTRIBUTE are */ /* mutually exclusive */ + { report_error_token(Error_Invalid_subkeyword_method, token); + } token = nextReal(); /* get the next token */ /* not a string? */ if (token->classId != TOKEN_SYMBOL && token->classId != TOKEN_LITERAL) @@ -1758,45 +1784,66 @@ break; /* ::METHOD name PRIVATE */ case SUBDIRECTIVE_PRIVATE: - if (Private) /* already seen one of these? */ + if (Private != DEFAULT_SCOPE) /* already seen one of these? */ + { /* duplicates are invalid */ report_error_token(Error_Invalid_subkeyword_method, token); - Private = true; /* flag for later processing */ + } + Private = PRIVATE_SCOPE; /* flag for later processing */ break; + /* ::METHOD name PUBLIC */ + case SUBDIRECTIVE_PUBLIC: + if (Private != DEFAULT_SCOPE) /* already seen one of these? */ + { + /* duplicates are invalid */ + report_error_token(Error_Invalid_subkeyword_method, token); + } + Private = PUBLIC_SCOPE; /* flag for later processing */ + break; /* ::METHOD name PROTECTED */ case SUBDIRECTIVE_PROTECTED: - if (Protected) /* already seen one of these? */ + if (Protected != DEFAULT_PROTECTION) /* already seen one of these? */ + { /* duplicates are invalid */ report_error_token(Error_Invalid_subkeyword_method, token); - Protected = true; /* flag for later processing */ + } + Protected = PROTECTED_METHOD; /* flag for later processing */ break; /* ::METHOD name UNGUARDED */ case SUBDIRECTIVE_UNGUARDED: /* already seen one of these? */ if (guard != DEFAULT_GUARD) + { /* duplicates are invalid */ report_error_token(Error_Invalid_subkeyword_method, token); + } guard = UNGUARDED_METHOD;/* flag for later processing */ break; /* ::METHOD name GUARDED */ case SUBDIRECTIVE_GUARDED: /* already seen one of these? */ if (guard != DEFAULT_GUARD) + { /* duplicates are invalid */ report_error_token(Error_Invalid_subkeyword_method, token); + } guard = GUARDED_METHOD; /* flag for later processing */ break; /* ::METHOD name ATTRIBUTE */ case SUBDIRECTIVE_ATTRIBUTE: if (Attribute) /* already seen one of these? */ + { /* duplicates are invalid */ report_error_token(Error_Invalid_subkeyword_method, token); + } /* EXTERNAL already specified ? */ if (externalname != OREF_NULL || abstractMethod) + { /* EXTERNAL and ATTRIBUTE are */ /* mutually exclusive */ report_error_token(Error_Invalid_subkeyword_method, token); + } /* get a retriever for it */ retriever = this->getRetriever(internalname); Attribute = true; /* flag for later processing */ @@ -1947,19 +1994,27 @@ } for (;;) { /* process potentially two methods */ - if (Private) /* is this a private method? */ + if (Private == PRIVATE_SCOPE) /* is this a private method? */ + { method->setPrivate(); /* turn on the private attribute */ - if (Protected) /* is this a protected method? */ + } + if (Protected == PROTECTED_METHOD) /* is this a protected method? */ + { method->setProtected(); /* turn on the protected attribute */ + } if (guard == UNGUARDED_METHOD) /* is this unguarded? */ + { method->setUnGuarded(); /* turn on the unguarded attribute */ + } /* set any associated attribute */ method->setAttribute(retriever); /* add the method to the table */ methodsDir->put(method, internalname); if (Attribute == false) /* not an attribute? */ + { break; /* we're finished */ + } else { /* set up the default 'NAME=' method */ internalname = this->commonString(internalname->concatWithCstring("=")); @@ -1991,7 +2046,7 @@ report_error(Error_Translation_duplicate_routine); this->flags |= _install; /* have information to install */ RexxString *externalname = OREF_NULL; /* no external name yet */ - bool Public = false; /* not a public routine yet */ + int Public = DEFAULT_SCOPE; /* not a public routine yet */ for (;;) { /* now loop on the option keywords */ token = nextReal(); /* get the next token */ /* reached the end? */ @@ -2023,12 +2078,25 @@ #endif /* ::ROUTINE name PUBLIC */ case SUBDIRECTIVE_PUBLIC: - if (Public) /* already had one of these? */ + if (Public != DEFAULT_SCOPE) /* already had one of these? */ + { /* duplicates are invalid */ - report_error_token(Error_Invalid_subkeyword_routine, token); - Public = true; /* turn on the seen flag */ + report_error_token(Error_Invalid_subkeyword_routine, token); + + } + Public = PUBLIC_SCOPE; /* turn on the seen flag */ break; + /* ::ROUTINE name PUBLIC */ + case SUBDIRECTIVE_PRIVATE: + if (Public != DEFAULT_SCOPE) /* already had one of these? */ + { + /* duplicates are invalid */ + report_error_token(Error_Invalid_subkeyword_routine, token); + } + Public = PRIVATE_SCOPE; /* turn on the seen flag */ + break; + default: /* invalid keyword */ /* this is an error */ report_error_token(Error_Invalid_subkeyword_routine, token); @@ -2089,9 +2157,12 @@ method = this->translateBlock(OREF_NULL); /* add to the routine directory */ this->routines->setEntry(name, method); - if (Public) /* a public routine? */ + if (Public == PUBLIC_SCOPE) /* a public routine? */ + { /* add to the public directory too */ - this->public_routines->setEntry(name, method); + this->public_routines->setEntry(name, method); + + } } this->toss(name); /* release the "Gary Cole" (GC) lock */ } Modified: interpreter-3.x/trunk/kernel/parser/Token.hpp =================================================================== --- interpreter-3.x/trunk/kernel/parser/Token.hpp 2007-08-06 11:51:26 UTC (rev 649) +++ interpreter-3.x/trunk/kernel/parser/Token.hpp 2007-08-06 14:53:12 UTC (rev 650) @@ -255,19 +255,20 @@ #define DIRECTIVE_ROUTINE 2404 /* directive sub-keywords */ -#define SUBDIRECTIVE_PUBLIC 2501 -#define SUBDIRECTIVE_METACLASS 2502 -#define SUBDIRECTIVE_INHERIT 2503 -#define SUBDIRECTIVE_PRIVATE 2504 -#define SUBDIRECTIVE_GUARDED 2505 -#define SUBDIRECTIVE_CLASS 2506 -#define SUBDIRECTIVE_EXTERNAL 2507 -#define SUBDIRECTIVE_SUBCLASS 2508 -#define SUBDIRECTIVE_UNGUARDED 2509 -#define SUBDIRECTIVE_MIXINCLASS 2510 -#define SUBDIRECTIVE_ATTRIBUTE 2511 -#define SUBDIRECTIVE_PROTECTED 2512 -#define SUBDIRECTIVE_ABSTRACT 2513 +#define SUBDIRECTIVE_PUBLIC 2501 +#define SUBDIRECTIVE_METACLASS 2502 +#define SUBDIRECTIVE_INHERIT 2503 +#define SUBDIRECTIVE_PRIVATE 2504 +#define SUBDIRECTIVE_GUARDED 2505 +#define SUBDIRECTIVE_CLASS 2506 +#define SUBDIRECTIVE_EXTERNAL 2507 +#define SUBDIRECTIVE_SUBCLASS 2508 +#define SUBDIRECTIVE_UNGUARDED 2509 +#define SUBDIRECTIVE_MIXINCLASS 2510 +#define SUBDIRECTIVE_ATTRIBUTE 2511 +#define SUBDIRECTIVE_PROTECTED 2512 +#define SUBDIRECTIVE_ABSTRACT 2513 +#define SUBDIRECTIVE_UNPROTECTED 2514 /* condition keywords */ Modified: interpreter-3.x/trunk/kernel/runtime/RexxConstants.cpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/RexxConstants.cpp 2007-08-06 11:51:26 UTC (rev 649) +++ interpreter-3.x/trunk/kernel/runtime/RexxConstants.cpp 2007-08-06 14:53:12 UTC (rev 650) @@ -322,6 +322,7 @@ KWD(CHAR_PUBLIC, SUBDIRECTIVE_PUBLIC) KWD(CHAR_SUBCLASS, SUBDIRECTIVE_SUBCLASS) KWD(CHAR_UNGUARDED, SUBDIRECTIVE_UNGUARDED) + KWD(CHAR_UNPROTECTED, SUBDIRECTIVE_UNPROTECTED) }; INT SubDirectivescount = /* size of function table */ Modified: interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp 2007-08-06 11:51:26 UTC (rev 649) +++ interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp 2007-08-06 14:53:12 UTC (rev 650) @@ -356,6 +356,7 @@ CHARCONSTANT(UNINIT, "UNINIT"); CHARCONSTANT(UNKNOWN, "UNKNOWN"); CHARCONSTANT(UNPACK, "UNPACK"); +CHARCONSTANT(UNPROTECTED, "UNPROTECTED"); CHARCONSTANT(UNSETMETHOD, "UNSETMETHOD"); CHARCONSTANT(ULONG, "UNSIGNED LONG"); CHARCONSTANT(USHORT, "UNSIGNED SHORT"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2007-08-06 18:53:44
|
Revision: 654 http://oorexx.svn.sourceforge.net/oorexx/?rev=654&view=rev Author: bigrixx Date: 2007-08-06 11:53:45 -0700 (Mon, 06 Aug 2007) Log Message: ----------- [ 1098932 ] Improve syntax for defining attribute methods. Modified Paths: -------------- interpreter-3.x/trunk/kernel/messages/DocErrorMessages.sgml interpreter-3.x/trunk/kernel/messages/RexxErrorCodes.h interpreter-3.x/trunk/kernel/messages/RexxMessageNumbers.h interpreter-3.x/trunk/kernel/messages/RexxMessageTable.h interpreter-3.x/trunk/kernel/messages/rexxmsg.xml interpreter-3.x/trunk/kernel/parser/SourceFile.cpp interpreter-3.x/trunk/kernel/parser/SourceFile.hpp interpreter-3.x/trunk/kernel/parser/Token.hpp interpreter-3.x/trunk/kernel/platform/windows/winmsgtb.rc interpreter-3.x/trunk/kernel/runtime/RexxConstants.cpp Modified: interpreter-3.x/trunk/kernel/messages/DocErrorMessages.sgml =================================================================== --- interpreter-3.x/trunk/kernel/messages/DocErrorMessages.sgml 2007-08-06 18:52:55 UTC (rev 653) +++ interpreter-3.x/trunk/kernel/messages/DocErrorMessages.sgml 2007-08-06 18:53:45 UTC (rev 654) @@ -3498,6 +3498,12 @@ <para>The "..." argument marker can only appear at the end of the argument list</para> </listitem> </varlistentry> +<varlistentry> +<term>931</term> +<listitem> +<para>Duplicate ::ATTRIBUTE directive instruction</para> +</listitem> +</varlistentry> </variablelist> </section> </section> Modified: interpreter-3.x/trunk/kernel/messages/RexxErrorCodes.h =================================================================== --- interpreter-3.x/trunk/kernel/messages/RexxErrorCodes.h 2007-08-06 18:52:55 UTC (rev 653) +++ interpreter-3.x/trunk/kernel/messages/RexxErrorCodes.h 2007-08-06 18:53:45 UTC (rev 654) @@ -561,6 +561,7 @@ #define Error_Translation_class_external_bad_class_name 99928 #define Error_Translation_class_external_bad_class_server 99929 #define Error_Translation_use_strict_ellipsis 99930 +#define Error_Translation_duplicate_attribute 99931 #define Error_at_line 101000 #define Message_Translations_January 101006 #define Message_Translations_February 101007 Modified: interpreter-3.x/trunk/kernel/messages/RexxMessageNumbers.h =================================================================== --- interpreter-3.x/trunk/kernel/messages/RexxMessageNumbers.h 2007-08-06 18:52:55 UTC (rev 653) +++ interpreter-3.x/trunk/kernel/messages/RexxMessageNumbers.h 2007-08-06 18:53:45 UTC (rev 654) @@ -504,6 +504,7 @@ #define Error_Creating_event_msg 569 #define Error_Creating_event_direct_parm_msg 570 #define Error_Accessing_aete_msg 571 +#define Error_Translation_duplicate_attribute_msg 571 #define Error_Launching_app_msg 572 #define Error_Invalid_event_additional_parm_msg 573 #define Error_Creating_event_additional_parm_msg 574 Modified: interpreter-3.x/trunk/kernel/messages/RexxMessageTable.h =================================================================== --- interpreter-3.x/trunk/kernel/messages/RexxMessageTable.h 2007-08-06 18:52:55 UTC (rev 653) +++ interpreter-3.x/trunk/kernel/messages/RexxMessageTable.h 2007-08-06 18:53:45 UTC (rev 654) @@ -563,6 +563,7 @@ MINOR(Error_Translation_class_external_bad_class_name) MINOR(Error_Translation_class_external_bad_class_server) MINOR(Error_Translation_use_strict_ellipsis) + MINOR(Error_Translation_duplicate_attribute) MAJOR(Error_at_line) MINOR(Message_Translations_January) MINOR(Message_Translations_February) Modified: interpreter-3.x/trunk/kernel/messages/rexxmsg.xml =================================================================== --- interpreter-3.x/trunk/kernel/messages/rexxmsg.xml 2007-08-06 18:52:55 UTC (rev 653) +++ interpreter-3.x/trunk/kernel/messages/rexxmsg.xml 2007-08-06 18:53:45 UTC (rev 654) @@ -4828,6 +4828,15 @@ <SymbolicName>Error_Translation_use_strict_ellipsis</SymbolicName> <Text>The <q>...</q> argument marker can only appear at the end of the argument list</Text> </SubMessage> + <SubMessage> + <Code>99</Code> + <Subcode>931</Subcode> + <MessageNumber>571</MessageNumber> + <Component>Rexx</Component> + <Severity>Warning</Severity> + <SymbolicName>Error_Translation_duplicate_attribute</SymbolicName> + <Text>Duplicate ::ATTRIBUTE directive instruction</Text> + </SubMessage> </Subcodes> </Message> <Message> Modified: interpreter-3.x/trunk/kernel/parser/SourceFile.cpp =================================================================== --- interpreter-3.x/trunk/kernel/parser/SourceFile.cpp 2007-08-06 18:52:55 UTC (rev 653) +++ interpreter-3.x/trunk/kernel/parser/SourceFile.cpp 2007-08-06 18:53:45 UTC (rev 654) @@ -991,6 +991,35 @@ } } + +/** + * Test if a directive is followed by a body of Rexx code + * instead of another directive or the end of the source. + * + * @return True if there is a non-directive clause following the current + * clause. + */ +bool RexxSource::hasBody() +{ + // assume there's no body here + bool result = false; + + // if we have anything to look at, see if it is a directive or not. + this->nextClause(); + if (!(this->flags&no_clause)) + { + // we have a clause, now check if this is a directive or not + RexxToken *token = nextReal(); + // not a "::", not a directive, which means we have real code to deal with + result = token->classId != TOKEN_DCOLON; + // reset this clause entirely so we can start parsing for real. + firstToken(); + this->reclaimClause(); + } + return result; +} + + RexxObject *RexxSource::toss( RexxObject *object) /* object to "release" */ /******************************************************************************/ @@ -1720,7 +1749,6 @@ bool abstractMethod = false; // this is an abstract method RexxToken *token = nextReal(); /* get the next token */ RexxString *externalname = OREF_NULL; /* not an external method yet */ - RexxVariableBase *retriever = OREF_NULL; /* no associated retriever yet */ /* not a symbol or a string */ if (token->classId != TOKEN_SYMBOL && token->classId != TOKEN_LITERAL) @@ -1809,6 +1837,15 @@ } Protected = PROTECTED_METHOD; /* flag for later processing */ break; + /* ::METHOD name UNPROTECTED */ + case SUBDIRECTIVE_UNPROTECTED: + if (Protected != DEFAULT_PROTECTION) /* already seen one of these? */ + { + /* duplicates are invalid */ + report_error_token(Error_Invalid_subkeyword_method, token); + } + Protected = UNPROTECTED_METHOD; /* flag for later processing */ + break; /* ::METHOD name UNGUARDED */ case SUBDIRECTIVE_UNGUARDED: /* already seen one of these? */ @@ -1844,8 +1881,6 @@ /* mutually exclusive */ report_error_token(Error_Invalid_subkeyword_method, token); } - /* get a retriever for it */ - retriever = this->getRetriever(internalname); Attribute = true; /* flag for later processing */ break; @@ -1905,20 +1940,18 @@ } RexxMethod *method; + // is this an attribute method? if (Attribute) - { /* this an attribute? */ - /* Attribute option is specified. */ - /* duplicate method "name=" ? */ - if (methodsDir->entry(this->commonString(internalname->concatWithCstring("="))) != OREF_NULL) - { - /* this is an error */ - report_error(Error_Translation_duplicate_method); - } - /* Go check the next clause to make */ - this->checkDirective(); /* sure that no code follows */ - /* create a generic kernel method */ - /* create a generic kernel method */ - method = new_method(getAttributeIndex, CPPM(RexxObject::getAttribute), 0, OREF_NULL); + { + // now get a variable retriever to get the property + RexxVariableBase *retriever = this->getRetriever(name); + + // create the method pair and quit. + createAttributeGetterMethod(methodsDir, internalname, retriever, Private == PRIVATE_SCOPE, + Protected == PROTECTED_METHOD, guard == GUARDED_METHOD, false); + createAttributeSetterMethod(methodsDir, internalname, retriever, Private == PRIVATE_SCOPE, + Protected == PROTECTED_METHOD, guard == GUARDED_METHOD, false); + return; } // abstract method? else if (abstractMethod) @@ -1992,43 +2025,392 @@ report_error1(Error_Translation_bad_external, externalname); } } + if (Private == PRIVATE_SCOPE) /* is this a private method? */ + { + method->setPrivate(); /* turn on the private attribute */ + } + if (Protected == PROTECTED_METHOD) /* is this a protected method? */ + { + method->setProtected(); /* turn on the protected attribute */ + } + if (guard == UNGUARDED_METHOD) /* is this unguarded? */ + { + method->setUnGuarded(); /* turn on the unguarded attribute */ + } + + /* add the method to the table */ + methodsDir->put(method, internalname); +} + +#define ATTRIBUTE_BOTH 0 +#define ATTRIBUTE_GET 1 +#define ATTRIBUTE_SET 2 + + +/** + * Process a ::ATTRIBUTE directive in a source file. + */ +void RexxSource::attributeDirective() +{ + this->flags &= ~requires_allowed;/* ::REQUIRES no longer valid */ + int Private = DEFAULT_SCOPE; /* this is a public method */ + int Protected = DEFAULT_PROTECTION; /* and is not protected yet */ + int guard = DEFAULT_GUARD; /* default is guarding */ + int style = ATTRIBUTE_BOTH; // by default, we create both methods for the attribute. + bool Class = false; /* default is an instance method */ + RexxToken *token = nextReal(); /* get the next token */ + + /* not a symbol or a string */ + if (token->classId != TOKEN_SYMBOL && token->classId != TOKEN_LITERAL) + { + /* report an error */ + report_error_token(Error_Symbol_or_string_method, token); + } + RexxString *name = token->value; /* get the string name */ + /* and the name form also */ + RexxString *internalname = this->commonString(name->upper()); for (;;) - { /* process potentially two methods */ - if (Private == PRIVATE_SCOPE) /* is this a private method? */ + { /* now loop on the option keywords */ + token = nextReal(); /* get the next token */ + /* reached the end? */ + if (token->classId == TOKEN_EOC) { - method->setPrivate(); /* turn on the private attribute */ + break; /* get out of here */ } - if (Protected == PROTECTED_METHOD) /* is this a protected method? */ + /* not a symbol token? */ + else if (token->classId != TOKEN_SYMBOL) { - method->setProtected(); /* turn on the protected attribute */ + /* report an error */ + report_error_token(Error_Invalid_subkeyword_method, token); } - if (guard == UNGUARDED_METHOD) /* is this unguarded? */ + else + { /* have some sort of option keyword */ + /* process each sub keyword */ + switch (this->subDirective(token)) + { + case SUBDIRECTIVE_GET: + // only one of GET/SET allowed + if (style != ATTRIBUTE_BOTH) + { + report_error_token(Error_Invalid_subkeyword_method, token); + } + style = ATTRIBUTE_GET; + break; + + case SUBDIRECTIVE_SET: + // only one of GET/SET allowed + if (style != ATTRIBUTE_BOTH) + { + report_error_token(Error_Invalid_subkeyword_method, token); + } + style = ATTRIBUTE_SET; + break; + + + /* ::ATTRIBUTE name CLASS */ + case SUBDIRECTIVE_CLASS: + if (Class) /* had one of these already? */ + { + /* duplicates are invalid */ + report_error_token(Error_Invalid_subkeyword_method, token); + } + Class = true; /* flag this for later processing */ + break; + case SUBDIRECTIVE_PRIVATE: + if (Private != DEFAULT_SCOPE) /* already seen one of these? */ + { + /* duplicates are invalid */ + report_error_token(Error_Invalid_subkeyword_method, token); + } + Private = PRIVATE_SCOPE; /* flag for later processing */ + break; + /* ::METHOD name PUBLIC */ + case SUBDIRECTIVE_PUBLIC: + if (Private != DEFAULT_SCOPE) /* already seen one of these? */ + { + /* duplicates are invalid */ + report_error_token(Error_Invalid_subkeyword_method, token); + } + Private = PUBLIC_SCOPE; /* flag for later processing */ + break; + /* ::METHOD name PROTECTED */ + case SUBDIRECTIVE_PROTECTED: + if (Protected != DEFAULT_PROTECTION) /* already seen one of these? */ + { + /* duplicates are invalid */ + report_error_token(Error_Invalid_subkeyword_method, token); + } + Protected = PROTECTED_METHOD; /* flag for later processing */ + break; + case SUBDIRECTIVE_UNPROTECTED: + if (Protected != DEFAULT_PROTECTION) /* already seen one of these? */ + { + /* duplicates are invalid */ + report_error_token(Error_Invalid_subkeyword_method, token); + } + Protected = UNPROTECTED_METHOD; /* flag for later processing */ + break; + /* ::METHOD name UNGUARDED */ + case SUBDIRECTIVE_UNGUARDED: + /* already seen one of these? */ + if (guard != DEFAULT_GUARD) + { + /* duplicates are invalid */ + report_error_token(Error_Invalid_subkeyword_method, token); + } + guard = UNGUARDED_METHOD;/* flag for later processing */ + break; + /* ::METHOD name GUARDED */ + case SUBDIRECTIVE_GUARDED: + /* already seen one of these? */ + if (guard != DEFAULT_GUARD) + { + /* duplicates are invalid */ + report_error_token(Error_Invalid_subkeyword_method, token); + } + guard = GUARDED_METHOD; /* flag for later processing */ + break; + /* ::METHOD name ATTRIBUTE */ + + + default: /* invalid keyword */ + /* this is an error */ + report_error_token(Error_Invalid_subkeyword_method, token); + break; + } + } + } + + RexxDirectory *methodsDir; + // now figure out which dictionary we need to add the methods to. + if (this->active_class == OREF_NULL) + { + if (Class) /* supposed to be a class method? */ { - method->setUnGuarded(); /* turn on the unguarded attribute */ + /* this is an error */ + report_error(Error_Translation_missing_class); } - /* set any associated attribute */ - method->setAttribute(retriever); + methodsDir = this->methods; /* adding to the global set */ + } + else + { /* add the method to the active class*/ + if (Class) /* class method? */ + { + /* add to the class method list */ + methodsDir = ((RexxDirectory *)(this->active_class->get(CLASS_CLASS_METHODS))); + } + else + { + /* add to the method list */ + methodsDir = ((RexxDirectory *)(this->active_class->get(CLASS_METHODS))); + } + } - /* add the method to the table */ - methodsDir->put(method, internalname); - if (Attribute == false) /* not an attribute? */ + // both attributes same default properties? + + // now get a variable retriever to get the property (do this before checking the body + // so errors get diagnosed on the correct line), + RexxVariableBase *retriever = this->getRetriever(name); + + switch (style) + { + case ATTRIBUTE_BOTH: + // create the method pair and quit. + createAttributeGetterMethod(methodsDir, internalname, retriever, Private == PRIVATE_SCOPE, + Protected == PROTECTED_METHOD, guard == GUARDED_METHOD, true); + createAttributeSetterMethod(methodsDir, internalname, retriever, Private == PRIVATE_SCOPE, + Protected == PROTECTED_METHOD, guard == GUARDED_METHOD, true); + break; + + case ATTRIBUTE_GET: // just the getter method { - break; /* we're finished */ + if (hasBody()) + { + createMethod(methodsDir, internalname, Private == PRIVATE_SCOPE, + Protected == PROTECTED_METHOD, guard == GUARDED_METHOD); + } + else + { + createAttributeGetterMethod(methodsDir, internalname, retriever, Private == PRIVATE_SCOPE, + Protected == PROTECTED_METHOD, guard == GUARDED_METHOD, true); + } + break; } + + case ATTRIBUTE_SET: + { + if (hasBody()) // just the getter method + { + createMethod(methodsDir, commonString(internalname->concatWithCstring("=")), Private == PRIVATE_SCOPE, + Protected == PROTECTED_METHOD, guard == GUARDED_METHOD); + } + else + { + createAttributeSetterMethod(methodsDir, internalname, retriever, Private == PRIVATE_SCOPE, + Protected == PROTECTED_METHOD, guard == GUARDED_METHOD, true); + } + break; + } + } +} + + +/** + * Create a Rexx method body. + * + * @param target The target method directory. + * @param name The name of the attribute. + * @param privateMethod + * The method's private attribute. + * @param protectedMethod + * The method's protected attribute. + * @param guardedMethod + * The method's guarded attribute. + */ +void RexxSource::createMethod(RexxDirectory *target, RexxString *name, + bool privateMethod, bool protectedMethod, bool guardedMethod) +{ + // make sure we don't have one of these define already. + if (target->entry(name) != OREF_NULL) + { + /* this is an error */ + report_error(Error_Translation_duplicate_attribute); + } + + // translate the method block + RexxMethod *method = translateBlock(OREF_NULL); + + // set the method properties + if (privateMethod) + { + method->setPrivate(); + } + if (protectedMethod) + { + method->setProtected(); + } + if (guardedMethod) + { + method->setUnGuarded(); + } + // and finally add to the target method directory. + target->put(method, name); +} + + +/** + * Create an ATTRIBUTE "get" method. + * + * @param target The target method directory. + * @param name The name of the attribute. + * @param privateMethod + * The method's private attribute. + * @param protectedMethod + * The method's protected attribute. + * @param guardedMethod + * The method's guarded attribute. + */ +void RexxSource::createAttributeGetterMethod(RexxDirectory *target, RexxString *name, RexxVariableBase *retriever, + bool privateMethod, bool protectedMethod, bool guardedMethod, bool isAttribute) +{ + // make sure we don't have one of these define already. + if (target->entry(name) != OREF_NULL) + { + /* this is an error */ + if (isAttribute) + { + report_error(Error_Translation_duplicate_attribute); + } else - { /* set up the default 'NAME=' method */ - internalname = this->commonString(internalname->concatWithCstring("=")); - /* create a generic kernel method */ - method = new_method(setAttributeIndex, CPPM(RexxObject::setAttribute), 1, OREF_NULL); - /* show that we have taken care of */ - /* show that we have taken care of */ - Attribute = false; /* the Attribute option */ + { + report_error(Error_Translation_duplicate_method); } } + + // no code can follow the automatically generated methods + this->checkDirective(); + + // create the kernel method for the accessor + RexxMethod *method = new_method(getAttributeIndex, CPPM(RexxObject::getAttribute), 0, OREF_NULL); + + if (privateMethod) + { + method->setPrivate(); + } + if (protectedMethod) + { + method->setProtected(); + } + if (guardedMethod) + { + method->setUnGuarded(); + } + // set the the retriever as the attribute + method->setAttribute(retriever); + + // and finally add to the target method directory. + target->put(method, name); } /** + * Create an ATTRIBUTE "set" method. + * + * @param target The target method directory. + * @param name The name of the attribute. + * @param privateMethod + * The method's private attribute. + * @param protectedMethod + * The method's protected attribute. + * @param guardedMethod + * The method's guarded attribute. + */ +void RexxSource::createAttributeSetterMethod(RexxDirectory *target, RexxString *name, RexxVariableBase *retriever, + bool privateMethod, bool protectedMethod, bool guardedMethod, bool isAttribute) +{ + // set up the default 'NAME=' method + name = this->commonString(name->concatWithCstring("=")); + // make sure we don't have one of these define already. + if (target->entry(name) != OREF_NULL) + { + /* this is an error */ + if (isAttribute) + { + report_error(Error_Translation_duplicate_attribute); + } + else + { + report_error(Error_Translation_duplicate_method); + } + } + + // no code can follow the automatically generated methods + this->checkDirective(); + + // create the kernel method for the accessor + RexxMethod *method = new_method(setAttributeIndex, CPPM(RexxObject::setAttribute), 1, OREF_NULL); + + if (privateMethod) + { + method->setPrivate(); + } + if (protectedMethod) + { + method->setProtected(); + } + if (guardedMethod) + { + method->setUnGuarded(); + } + // set the the retriever as the attribute + method->setAttribute(retriever); + + // and finally add to the target method directory. + target->put(method, name); +} + + +/** * Process a ::routine directive in a source file. */ void RexxSource::routineDirective() @@ -2240,6 +2622,10 @@ requiresDirective(); break; + case DIRECTIVE_ATTRIBUTE: /* ::ATTRIBUTE directive */ + attributeDirective(); + break; + default: /* unknown directive */ report_error(Error_Translation_bad_directive); break; Modified: interpreter-3.x/trunk/kernel/parser/SourceFile.hpp =================================================================== --- interpreter-3.x/trunk/kernel/parser/SourceFile.hpp 2007-08-06 18:52:55 UTC (rev 653) +++ interpreter-3.x/trunk/kernel/parser/SourceFile.hpp 2007-08-06 18:53:45 UTC (rev 654) @@ -110,6 +110,7 @@ RexxMethod *interpretMethod(RexxDirectory *); RexxMethod *interpret(RexxString *, RexxDirectory *, size_t); void checkDirective(); + bool hasBody(); RexxObject *toss(RexxObject *); void cleanup(); void mergeRequired(RexxSource *); @@ -124,6 +125,10 @@ void requiresDirective(); void methodDirective(); void classDirective(); + void attributeDirective(); + void createMethod(RexxDirectory *target, RexxString *name, bool privateMethod, bool protectedMethod, bool guardedMethod); + void createAttributeGetterMethod(RexxDirectory *target, RexxString *name, RexxVariableBase *retriever, bool privateMethod, bool protectedMethod, bool guardedMethod, bool isAttribute); + void createAttributeSetterMethod(RexxDirectory *target, RexxString *name, RexxVariableBase *retriever, bool privateMethod, bool protectedMethod, bool guardedMethod, bool isAttribute); void flushControl(RexxInstruction *); RexxMethod *translateBlock(RexxDirectory *); RexxInstruction *instruction(); Modified: interpreter-3.x/trunk/kernel/parser/Token.hpp =================================================================== --- interpreter-3.x/trunk/kernel/parser/Token.hpp 2007-08-06 18:52:55 UTC (rev 653) +++ interpreter-3.x/trunk/kernel/parser/Token.hpp 2007-08-06 18:53:45 UTC (rev 654) @@ -249,10 +249,11 @@ #define CLAUSEEND_NULL 2304 /* directive types */ -#define DIRECTIVE_REQUIRES 2401 -#define DIRECTIVE_CLASS 2402 -#define DIRECTIVE_METHOD 2403 -#define DIRECTIVE_ROUTINE 2404 +#define DIRECTIVE_REQUIRES 2401 +#define DIRECTIVE_CLASS 2402 +#define DIRECTIVE_METHOD 2403 +#define DIRECTIVE_ROUTINE 2404 +#define DIRECTIVE_ATTRIBUTE 2405 /* directive sub-keywords */ #define SUBDIRECTIVE_PUBLIC 2501 @@ -269,6 +270,8 @@ #define SUBDIRECTIVE_PROTECTED 2512 #define SUBDIRECTIVE_ABSTRACT 2513 #define SUBDIRECTIVE_UNPROTECTED 2514 +#define SUBDIRECTIVE_GET 2515 +#define SUBDIRECTIVE_SET 2516 /* condition keywords */ Modified: interpreter-3.x/trunk/kernel/platform/windows/winmsgtb.rc =================================================================== --- interpreter-3.x/trunk/kernel/platform/windows/winmsgtb.rc 2007-08-06 18:52:55 UTC (rev 653) +++ interpreter-3.x/trunk/kernel/platform/windows/winmsgtb.rc 2007-08-06 18:53:45 UTC (rev 654) @@ -504,6 +504,7 @@ Error_Creating_event "Error creating OSA event ""&1""" Error_Creating_event_direct_parm "Error creating direct parameter for OSA event ""&1""" Error_Accessing_aete "Error accessing event information in AETE" + Error_Translation_duplicate_attribute "Duplicate ::ATTRIBUTE directive instruction" Error_Launching_app "Error launching application ""&1""" Error_Invalid_event_additional_parm "Invalid additional parameter ""&1"" for OSA event ""&2""" Error_Creating_event_additional_parm "Error creating additional parameter for OSA event ""&1""" Modified: interpreter-3.x/trunk/kernel/runtime/RexxConstants.cpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/RexxConstants.cpp 2007-08-06 18:52:55 UTC (rev 653) +++ interpreter-3.x/trunk/kernel/runtime/RexxConstants.cpp 2007-08-06 18:53:45 UTC (rev 654) @@ -56,6 +56,7 @@ /*********************************************************************/ KWDTABLE Directives[] = { /* language directive table */ + KWD(CHAR_ATTRIBUTE, DIRECTIVE_ATTRIBUTE) KWD(CHAR_CLASS, DIRECTIVE_CLASS) KWD(CHAR_METHOD, DIRECTIVE_METHOD) KWD(CHAR_REQUIRES, DIRECTIVE_REQUIRES) @@ -313,6 +314,7 @@ KWD(CHAR_ATTRIBUTE, SUBDIRECTIVE_ATTRIBUTE) KWD(CHAR_CLASS, SUBDIRECTIVE_CLASS) KWD(CHAR_EXTERNAL, SUBDIRECTIVE_EXTERNAL) + KWD(CHAR_GET, SUBDIRECTIVE_GET) KWD(CHAR_GUARDED, SUBDIRECTIVE_GUARDED) KWD(CHAR_INHERIT, SUBDIRECTIVE_INHERIT) KWD(CHAR_METACLASS, SUBDIRECTIVE_METACLASS) @@ -320,6 +322,7 @@ KWD(CHAR_PRIVATE, SUBDIRECTIVE_PRIVATE) KWD(CHAR_PROTECTED, SUBDIRECTIVE_PROTECTED) KWD(CHAR_PUBLIC, SUBDIRECTIVE_PUBLIC) + KWD(CHAR_SET, SUBDIRECTIVE_SET) KWD(CHAR_SUBCLASS, SUBDIRECTIVE_SUBCLASS) KWD(CHAR_UNGUARDED, SUBDIRECTIVE_UNGUARDED) KWD(CHAR_UNPROTECTED, SUBDIRECTIVE_UNPROTECTED) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2007-09-11 23:12:52
|
Revision: 746 http://oorexx.svn.sourceforge.net/oorexx/?rev=746&view=rev Author: bigrixx Date: 2007-09-11 16:12:37 -0700 (Tue, 11 Sep 2007) Log Message: ----------- [ 1792694 ] Add a max change count to changeStr() Modified Paths: -------------- interpreter-3.x/trunk/kernel/classes/StringClass.hpp interpreter-3.x/trunk/kernel/classes/StringClassMisc.cpp interpreter-3.x/trunk/kernel/expression/BuiltinFunctions.cpp interpreter-3.x/trunk/kernel/runtime/RexxCore.h interpreter-3.x/trunk/kernel/runtime/Setup.cpp Modified: interpreter-3.x/trunk/kernel/classes/StringClass.hpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/StringClass.hpp 2007-09-10 23:54:54 UTC (rev 745) +++ interpreter-3.x/trunk/kernel/classes/StringClass.hpp 2007-09-11 23:12:37 UTC (rev 746) @@ -184,8 +184,8 @@ RexxInteger *words(); /* the following methods are in */ /* OKBMISC */ - RexxString *changeStr(RexxString *, RexxString *); - RexxString *caselessChangeStr(RexxString *, RexxString *); + RexxString *changeStr(RexxString *, RexxString *, RexxInteger *); + RexxString *caselessChangeStr(RexxString *, RexxString *, RexxInteger *); RexxInteger *abbrev(RexxString *, RexxInteger *); RexxInteger *caselessAbbrev(RexxString *, RexxInteger *); RexxInteger *compare(RexxString *, RexxString *); Modified: interpreter-3.x/trunk/kernel/classes/StringClassMisc.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/StringClassMisc.cpp 2007-09-10 23:54:54 UTC (rev 745) +++ interpreter-3.x/trunk/kernel/classes/StringClassMisc.cpp 2007-09-11 23:12:37 UTC (rev 746) @@ -422,11 +422,6 @@ RexxInteger *RexxString::caselessAbbrev(RexxString *info, RexxInteger *length) { - size_t Len1; /* length of string1 */ - size_t Len2; /* length of string1 */ - size_t ChkLen; /* required check length */ - INT rc; /* compare result */ - // the info must be a string value info = get_string(info, ARG_ONE); stringsize_t len2 = info->getLength(); @@ -902,8 +897,7 @@ return new_integer(count); /* return the count as an object */ } -RexxString *RexxString::changeStr(RexxString *needle, - RexxString *newNeedle) +RexxString *RexxString::changeStr(RexxString *needle, RexxString *newNeedle, RexxInteger *countArg) /******************************************************************************/ /* Function: Change strings into another string. */ /******************************************************************************/ @@ -918,11 +912,20 @@ PCHAR copy; /* current copy position */ PCHAR newPtr; /* pointer to replacement data */ RexxString *result; /* returned result string */ + size_t i; + /* force needle to a string */ needle = REQUIRED_STRING(needle, ARG_ONE); /* newneedle must be a string two */ newNeedle = REQUIRED_STRING(newNeedle, ARG_TWO); + + // we'll only change up to a specified count. If not there, we do everything. + size_t count = optional_position(countArg, MAX_WHOLE_NUMBER, ARG_THREE); matches = this->countStr(needle); /* find the number of replacements */ + if (matches > count) // the matches are bounded by the count + { + matches = count; + } needleLength = needle->length; /* get the length of the needle */ newLength = newNeedle->length; /* and the replacement length */ /* get a proper sized string */ @@ -932,7 +935,7 @@ /* and the string to replace */ newPtr = newNeedle->stringData; start = 0; /* set a zero starting point */ - for (;;) { /* loop forever */ + for (i = 0; i < matches; i++) { /* until we hit count or run out */ match = this->pos(needle, start); /* look for the next occurrence */ if (match == 0) /* not found? */ break; /* get out of here */ @@ -955,8 +958,7 @@ return result; /* finished */ } -RexxString *RexxString::caselessChangeStr(RexxString *needle, - RexxString *newNeedle) +RexxString *RexxString::caselessChangeStr(RexxString *needle, RexxString *newNeedle, RexxInteger *countArg) /******************************************************************************/ /* Function: Change strings into another string. */ /******************************************************************************/ @@ -971,11 +973,20 @@ PCHAR copy; /* current copy position */ PCHAR newPtr; /* pointer to replacement data */ RexxString *result; /* returned result string */ + size_t i; + /* force needle to a string */ needle = REQUIRED_STRING(needle, ARG_ONE); /* newneedle must be a string two */ newNeedle = REQUIRED_STRING(newNeedle, ARG_TWO); + // we'll only change up to a specified count. If not there, we do everything. + size_t count = optional_position(countArg, MAX_WHOLE_NUMBER, ARG_THREE); + matches = this->caselessCountStr(needle); /* find the number of replacements */ + if (matches > count) // the matches are bounded by the count + { + matches = count; + } needleLength = needle->length; /* get the length of the needle */ newLength = newNeedle->length; /* and the replacement length */ /* get a proper sized string */ @@ -985,7 +996,7 @@ /* and the string to replace */ newPtr = newNeedle->stringData; start = 0; /* set a zero starting point */ - for (;;) { /* loop forever */ + for (i = 0; i < matches; i++) { /* until we hit count or run out */ match = this->caselessPos(needle, start); /* look for the next occurrence */ if (match == 0) /* not found? */ break; /* get out of here */ Modified: interpreter-3.x/trunk/kernel/expression/BuiltinFunctions.cpp =================================================================== --- interpreter-3.x/trunk/kernel/expression/BuiltinFunctions.cpp 2007-09-10 23:54:54 UTC (rev 745) +++ interpreter-3.x/trunk/kernel/expression/BuiltinFunctions.cpp 2007-09-11 23:12:37 UTC (rev 746) @@ -3010,15 +3010,17 @@ } #define CHANGESTR_MIN 3 -#define CHANGESTR_MAX 3 +#define CHANGESTR_MAX 4 #define CHANGESTR_needle 1 #define CHANGESTR_haystack 2 #define CHANGESTR_newneedle 3 +#define CHANGESTR_count 3 BUILTIN(CHANGESTR) { RexxString *needle; /* needle to change */ RexxString *haystack; /* target haystack */ RexxString *newneedle; /* new, replacement string */ + RexxInteger *count; // max replacement count fix_args(CHANGESTR); /* check on require number of args */ /* get string for new */ @@ -3027,8 +3029,10 @@ haystack = required_string(CHANGESTR, haystack); /* get string to change to */ newneedle = required_string(CHANGESTR, newneedle); + /* length is optional */ + count = optional_integer(CHANGESTR, count); /* go perform the pos function */ - return haystack->changeStr(needle, newneedle); + return haystack->changeStr(needle, newneedle, count); } #define COUNTSTR_MIN 2 Modified: interpreter-3.x/trunk/kernel/runtime/RexxCore.h =================================================================== --- interpreter-3.x/trunk/kernel/runtime/RexxCore.h 2007-09-10 23:54:54 UTC (rev 745) +++ interpreter-3.x/trunk/kernel/runtime/RexxCore.h 2007-09-11 23:12:37 UTC (rev 746) @@ -68,6 +68,8 @@ const int MAX_ERROR_NUMBER = 99999; /* maximum error code number */ const int MAX_SYMBOL_LENGTH = 250; /* length of a symbol name */ +const int MAX_WHOLE_NUMBER = 999999999; // maximum positive whole number +const int MIN_WHOLE_NUMBER = -999999999; // minimum negative whole number /******************************************************************************/ /* Numeric setting constants */ Modified: interpreter-3.x/trunk/kernel/runtime/Setup.cpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/Setup.cpp 2007-09-10 23:54:54 UTC (rev 745) +++ interpreter-3.x/trunk/kernel/runtime/Setup.cpp 2007-09-11 23:12:37 UTC (rev 746) @@ -1224,8 +1224,8 @@ defineKernelMethod(CHAR_WORDS ,TheStringBehaviour, CPPMSTR(RexxString::words), 0); defineKernelMethod(CHAR_ABBREV ,TheStringBehaviour, CPPMSTR(RexxString::abbrev), 2); defineKernelMethod(CHAR_CASELESSABBREV ,TheStringBehaviour, CPPMSTR(RexxString::caselessAbbrev), 2); - defineKernelMethod(CHAR_CHANGESTR ,TheStringBehaviour, CPPMSTR(RexxString::changeStr), 2); - defineKernelMethod(CHAR_CASELESSCHANGESTR ,TheStringBehaviour, CPPMSTR(RexxString::caselessChangeStr), 2); + defineKernelMethod(CHAR_CHANGESTR ,TheStringBehaviour, CPPMSTR(RexxString::changeStr), 3); + defineKernelMethod(CHAR_CASELESSCHANGESTR ,TheStringBehaviour, CPPMSTR(RexxString::caselessChangeStr), 3); defineKernelMethod(CHAR_COMPARE ,TheStringBehaviour, CPPMSTR(RexxString::compare), 2); defineKernelMethod(CHAR_CASELESSCOMPARE ,TheStringBehaviour, CPPMSTR(RexxString::caselessCompare), 2); defineKernelMethod(CHAR_COPIES ,TheStringBehaviour, CPPMSTR(RexxString::copies), 1); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2007-09-12 00:25:05
|
Revision: 748 http://oorexx.svn.sourceforge.net/oorexx/?rev=748&view=rev Author: bigrixx Date: 2007-09-11 17:25:08 -0700 (Tue, 11 Sep 2007) Log Message: ----------- [ 1792831 ] Add dynamic environment symbols. Modified Paths: -------------- interpreter-3.x/trunk/kernel/expression/BuiltinFunctions.cpp interpreter-3.x/trunk/kernel/expression/ExpressionDotVariable.cpp interpreter-3.x/trunk/kernel/expression/ExpressionDotVariable.hpp interpreter-3.x/trunk/kernel/runtime/RexxActivation.cpp Modified: interpreter-3.x/trunk/kernel/expression/BuiltinFunctions.cpp =================================================================== --- interpreter-3.x/trunk/kernel/expression/BuiltinFunctions.cpp 2007-09-11 23:13:32 UTC (rev 747) +++ interpreter-3.x/trunk/kernel/expression/BuiltinFunctions.cpp 2007-09-12 00:25:08 UTC (rev 748) @@ -2222,12 +2222,19 @@ newvalue = optional_argument(VALUE, newValue); /* and the selector */ selector = optional_string(VALUE, selector); + // get the variable type + int variableType = variable->isSymbol(); + bool assignable = variableType == STRING_NAME || variableType == STRING_STEM || variableType == STRING_COMPOUND_NAME; + if (selector == OREF_NULL) { /* have a selector? */ /* get a variable retriever */ retriever = context->getVariableRetriever(variable); - if ((retriever == OREF_NULL) || - ((newvalue != OREF_NULL) && (variable->isSymbol() == STRING_NUMERIC))) /* invalid variable name? */ - report_exception3(Error_Incorrect_call_symbol, new_cstring(CHAR_VALUE), IntegerOne, variable); + // this could an invalid name, or we might be trying to assign a value to a non-variable + // symbol. + if (retriever == OREF_NULL || (newvalue != OREF_NULL && !assignable)) + { + report_exception3(Error_Incorrect_call_symbol, new_cstring(CHAR_VALUE), IntegerOne, variable); + } else { /* need to perform lookup */ /* get the variable value */ result = retriever->getValue(context); Modified: interpreter-3.x/trunk/kernel/expression/ExpressionDotVariable.cpp =================================================================== --- interpreter-3.x/trunk/kernel/expression/ExpressionDotVariable.cpp 2007-09-11 23:13:32 UTC (rev 747) +++ interpreter-3.x/trunk/kernel/expression/ExpressionDotVariable.cpp 2007-09-12 00:25:08 UTC (rev 748) @@ -114,6 +114,27 @@ return result; /* also return the result */ } + +RexxObject * RexxDotVariable::getValue( + RexxActivation *context) +/****************************************************************************/ +/* Function: Evaluate a REXX dot variable */ +/****************************************************************************/ +{ + RexxObject *result; /* dot variable value */ + + /* get this from the source */ + result = context->getSource()->resolveClass(this->variableName, context); + if (result == OREF_NULL) /* not there? */ + /* try for a REXX defined name */ + result = context->rexxVariable(this->variableName); + if (result == OREF_NULL) { /* not there? */ + /* add a period to the name */ + result = this->variableName->concatToCstring(CHAR_PERIOD); + } + return result; /* also return the result */ +} + void * RexxDotVariable::operator new(size_t size) /******************************************************************************/ /* Function: Create a new translator object */ Modified: interpreter-3.x/trunk/kernel/expression/ExpressionDotVariable.hpp =================================================================== --- interpreter-3.x/trunk/kernel/expression/ExpressionDotVariable.hpp 2007-09-11 23:13:32 UTC (rev 747) +++ interpreter-3.x/trunk/kernel/expression/ExpressionDotVariable.hpp 2007-09-12 00:25:08 UTC (rev 748) @@ -36,7 +36,7 @@ /* */ /*----------------------------------------------------------------------------*/ /******************************************************************************/ -/* REXX Kernel ExpressionDotVariable.hpp */ +/* REXX Kernel ExpressionDotVariable.hpp */ /* */ /* Primitive Expression Dot Variable Class Definitions */ /* */ @@ -56,6 +56,7 @@ void liveGeneral(); void flatten(RexxEnvelope *); RexxObject *evaluate(RexxActivation *, RexxExpressionStack *); + RexxObject *getValue(RexxActivation *); /* name of the variable is in hash */ }; Modified: interpreter-3.x/trunk/kernel/runtime/RexxActivation.cpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/RexxActivation.cpp 2007-09-11 23:13:32 UTC (rev 747) +++ interpreter-3.x/trunk/kernel/runtime/RexxActivation.cpp 2007-09-12 00:25:08 UTC (rev 748) @@ -67,6 +67,7 @@ #include "DoBlock.hpp" #include "DoInstruction.hpp" #include "ExpressionBaseVariable.hpp" +#include "ExpressionDotVariable.hpp" #include "ExpressionVariable.hpp" #include "ExpressionStem.hpp" #include "ExpressionCompoundVariable.hpp" @@ -3290,11 +3291,16 @@ break; case STRING_LITERAL_DOT: /* if is is a literal */ - case STRING_LITERAL: case STRING_NUMERIC: /* these are literals */ retriever = (RexxVariableBase *)variable; break; + + // Dot variables retrieve from the environment + case STRING_LITERAL: + retriever = (RexxVariableBase *)new RexxDotVariable(variable->extract(1, variable->getLength() - 1)); + break; + /* if it is a stem */ case STRING_STEM: /* create a new stem retriever */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2007-09-22 23:13:46
|
Revision: 788 http://oorexx.svn.sourceforge.net/oorexx/?rev=788&view=rev Author: bigrixx Date: 2007-09-22 16:13:50 -0700 (Sat, 22 Sep 2007) Log Message: ----------- Yet more compilation fix attempts. Modified Paths: -------------- interpreter-3.x/trunk/kernel/platform/unix/PlatformDefinitions.h interpreter-3.x/trunk/kernel/runtime/Numerics.cpp Modified: interpreter-3.x/trunk/kernel/platform/unix/PlatformDefinitions.h =================================================================== --- interpreter-3.x/trunk/kernel/platform/unix/PlatformDefinitions.h 2007-09-22 22:54:17 UTC (rev 787) +++ interpreter-3.x/trunk/kernel/platform/unix/PlatformDefinitions.h 2007-09-22 23:13:50 UTC (rev 788) @@ -59,6 +59,10 @@ #define TOTAL_STACK_SIZE 1024*512 #define C_STACK_SIZE TOTAL_STACK_SIZE +// The limit values for the portable int types are only included in C++ if the +following is defined before including stdint.h. +#define __STDC_LIMIT_MACROS + #include "stdint.h" Modified: interpreter-3.x/trunk/kernel/runtime/Numerics.cpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/Numerics.cpp 2007-09-22 22:54:17 UTC (rev 787) +++ interpreter-3.x/trunk/kernel/runtime/Numerics.cpp 2007-09-22 23:13:50 UTC (rev 788) @@ -64,8 +64,6 @@ // for the full binary value range stringsize_t Numerics::ARGUMENT_DIGITS = ((stringsize_t)10); #endif -stringsize_t Numerics::MAX_STRINGSIZE = SIZE_MAX; - // max numeric digits value for explicit 64-bit conversions stringsize_t Numerics::DIGITS64 = ((stringsize_t)20); bool Numerics::FORM_SCIENTIFIC = false; @@ -128,7 +126,7 @@ RexxObject *Numerics::toObject(stringsize_t v) { // in the range for an integer object? - if (v <= (uintptr_t)MAX_WHOLENUMBER) + if (v <= (stringsize_t)MAX_WHOLENUMBER) { return new_integer((stringsize_t)v); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2007-09-23 18:07:07
|
Revision: 793 http://oorexx.svn.sourceforge.net/oorexx/?rev=793&view=rev Author: bigrixx Date: 2007-09-23 11:07:09 -0700 (Sun, 23 Sep 2007) Log Message: ----------- [ 1800672 ] Add Time('T') and Date('T') for Regina compatibility. Modified Paths: -------------- interpreter-3.x/trunk/kernel/expression/BuiltinFunctions.cpp interpreter-3.x/trunk/kernel/runtime/RexxDateTime.cpp interpreter-3.x/trunk/kernel/runtime/RexxDateTime.hpp Modified: interpreter-3.x/trunk/kernel/expression/BuiltinFunctions.cpp =================================================================== --- interpreter-3.x/trunk/kernel/expression/BuiltinFunctions.cpp 2007-09-23 16:16:00 UTC (rev 792) +++ interpreter-3.x/trunk/kernel/expression/BuiltinFunctions.cpp 2007-09-23 18:07:09 UTC (rev 793) @@ -1076,7 +1076,7 @@ if (option->length == 0) /* have a null string? */ { /* this is an error */ - report_exception4(Error_Incorrect_call_list, new_cstring(CHAR_DATE), IntegerOne, new_string("BDELMNOSUW", 10), option); + report_exception4(Error_Incorrect_call_list, new_cstring(CHAR_DATE), IntegerOne, new_string("BDEFLMNOSTUW", 10), option); } else /* need to process an option */ { @@ -1097,7 +1097,7 @@ if (option2->length == 0) /* have a null string? */ { /* this is an error */ - report_exception4(Error_Incorrect_call_list, new_cstring(CHAR_DATE), IntegerThree, new_string("BDENOSU", 7), option2); + report_exception4(Error_Incorrect_call_list, new_cstring(CHAR_DATE), IntegerThree, new_string("BDEFNOSTU", 7), option2); } else /* need to process an option */ { @@ -1164,12 +1164,10 @@ /*convert the value */ int basedays = indate->longValue(9); /* bad value? */ - if (basedays == NO_LONG || basedays < 0) + if (basedays == NO_LONG || !timestamp.setBaseDate(basedays)) { report_exception3(Error_Incorrect_call_format_invalid, new_cstring(CHAR_DATE), indate, new_string((PCHAR)&style2, 1)); } - // the timestamp handles the setting directly - timestamp.setBaseDate(basedays); break; } @@ -1177,15 +1175,24 @@ { /*convert the value */ int64_t basetime; - if (!Numerics::objectToInt64(indate, basetime) || basetime < 0) + if (!Numerics::objectToInt64(indate, basetime) || !timestamp.setBaseTime(basetime)) { report_exception3(Error_Incorrect_call_format_invalid, new_cstring(CHAR_DATE), indate, new_string((PCHAR)&style2, 1)); } - // the timestamp handles the setting directly - timestamp.setBaseTime(basetime); break; } + case 'T': /* 'T'icks datetime stamp */ + { + /*convert the value */ + int64_t basetime; + if (!Numerics::objectToInt64(indate, basetime) || !timestamp.setUnixTime(basetime)) + { + report_exception3(Error_Incorrect_call_format_invalid, new_cstring(CHAR_DATE), indate, new_string((PCHAR)&style2, 1)); + } + break; + } + case 'D': /* 'D'ay of year */ { /*convert the value */ @@ -1218,7 +1225,7 @@ break; default: - report_exception4(Error_Incorrect_call_list, new_cstring(CHAR_DATE), IntegerThree, new_string("BDEFNOSU", 7), new_string((PCHAR)&style2, 1)); + report_exception4(Error_Incorrect_call_list, new_cstring(CHAR_DATE), IntegerThree, new_string("BDEFNOTSU", 7), new_string((PCHAR)&style2, 1)); break; } // if there's a formatting error @@ -1257,6 +1264,10 @@ timestamp.formatBaseTime(work); break; + case 'T': /* 'F'asedate */ + timestamp.formatUnixTime(work); + break; + case 'D': /* 'D'ays */ timestamp.formatDays(work); break; @@ -1301,7 +1312,7 @@ default: /* unrecognized */ work[0] = style; /* copy over the character */ - report_exception4(Error_Incorrect_call_list, new_cstring(CHAR_DATE), IntegerOne, new_string("BDEFLMNOSUW", 10), new_string(work, 1)); + report_exception4(Error_Incorrect_call_list, new_cstring(CHAR_DATE), IntegerOne, new_string("BDEFLMNOSTUW", 10), new_string(work, 1)); break; } /* now create a string object */ @@ -1413,15 +1424,24 @@ { /*convert the value */ int64_t basetime; - if (!Numerics::objectToInt64(intime, basetime) || basetime < 0) + if (!Numerics::objectToInt64(intime, basetime) || !timestamp.setBaseTime(basetime)) { report_exception3(Error_Incorrect_call_format_invalid, new_cstring(CHAR_TIME), intime, new_string((PCHAR)&style2, 1)); } - // the timestamp handles the setting directly - timestamp.setBaseTime(basetime); break; } + case 'T': /* 'T'icks datetime stamp */ + { + /*convert the value */ + int64_t basetime; + if (!Numerics::objectToInt64(intime, basetime) || !timestamp.setUnixTime(basetime)) + { + report_exception3(Error_Incorrect_call_format_invalid, new_cstring(CHAR_TIME), intime, new_string((PCHAR)&style2, 1)); + } + break; + } + default: work[0] = style2; /* copy over the character */ report_exception4(Error_Incorrect_call_list, new_cstring(CHAR_TIME), IntegerThree, new_string("CFHLMNS", 6), new_string(work, 1)); @@ -1489,13 +1509,17 @@ timestamp.formatSeconds(work); break; - case 'F': /* 'F'asedate */ + case 'F': /* 'F'ull */ timestamp.formatBaseTime(work); break; + case 'T': /* 'T'icks */ + timestamp.formatUnixTime(work); + break; + default: /* unknown format */ work[0] = style; /* copy over the character */ - report_exception4(Error_Incorrect_call_list, new_cstring(CHAR_TIME), IntegerOne, new_string("CEFHLMNRS", 8), new_string(work, 1)); + report_exception4(Error_Incorrect_call_list, new_cstring(CHAR_TIME), IntegerOne, new_string("CEFHLMNRST", 8), new_string(work, 1)); break; } /* now create a string object */ Modified: interpreter-3.x/trunk/kernel/runtime/RexxDateTime.cpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/RexxDateTime.cpp 2007-09-23 16:16:00 UTC (rev 792) +++ interpreter-3.x/trunk/kernel/runtime/RexxDateTime.cpp 2007-09-23 18:07:09 UTC (rev 793) @@ -39,6 +39,11 @@ #include "RexxDateTime.hpp" #include "Numerics.hpp" +// the base time used for Time('T'); +RexxDateTime RexxDateTime::unixBaseTime(1970, 1, 1); +// the largest possible date we can handle +RexxDateTime RexxDateTime::maxBaseTime(9999, 12, 31, 23, 59, 59, 999999); + // formatting versions of the days const char *RexxDateTime::dayNames[] = { @@ -89,6 +94,83 @@ /** + + * Default constructor for a RexxDateTime instance. This + * initializes the time to all zeros. + */ +RexxDateTime::RexxDateTime() +{ + clear(); +} + + +/** + * Create a RexxDateTime instance from a basetime value. + * + * @param basetime The basetime for this instance. + */ +RexxDateTime::RexxDateTime(int64_t basetime) +{ + clear(); + setBaseTime(basetime); +} + + + + +/** + * Create a RexxDateTime instance from a baseDate value. + * + * @param basetime The basedate for this instance. + */ +RexxDateTime::RexxDateTime(int basedate) +{ + clear(); + setBaseDate(basedate); +} + + +/** + * Create a RexxDateTime instance from a year/month/day value. + * + * @param y The current year. + * @param m The month. + * @param d The day. + */ +RexxDateTime::RexxDateTime(int y, int m, int d) +{ + clear(); + year = y; + month = m; + day = d; +} + + +/** + * Create a RexxDateTime instance from a fully resolved date + * time value. + * + * @param y The date year. + * @param m The date month. + * @param d The date day. + * @param h The time hour. + * @param i The time minues + * @param s The time secons. + * @param u The time microseconds. + */ +RexxDateTime::RexxDateTime(int y, int m, int d, int h, int i, int s, int u) +{ + year = y; + month = m; + day = d; + hours = h; + minutes = i; + seconds = s; + microseconds = y; +} + + +/** * Retrieve the basedate from the timestamp. The basedate * is the number of days since 01 Jan 0001, calculated using * a Gregorian calendar system for the entire date range. @@ -141,13 +223,35 @@ /** + * Calculate the basetime, returned as the number of seconds + * since 00:00:00.000000 on 01 Jan 1970. The basetime is + * calculated using the same Gregorian calendar system used to + * calculate the basedate. Times prior to 01 Jan 1970 are + * returned as a negative number. + * + * @return The unix time as a 64-bit integer value. + */ +int64_t RexxDateTime::getUnixTime() +{ + // subtract the baseline time and convert to seconds. + return (getBaseTime() - unixBaseTime.getBaseTime()) / (int64_t)MICROSECONDS; +} + + +/** * Set the date from a basedate value. The basedate is the * number of days since 01 Jan 0001. * * @param basedays The basedays value (must be a positive integer). */ -void RexxDateTime::setBaseDate(int basedays) +bool RexxDateTime::setBaseDate(int basedays) { + // make sure this is in range. + if (basedays < 0 || basedays > maxBaseTime.getBaseDate()) + { + return false; + } + // reset all of the fields clear(); @@ -222,6 +326,7 @@ break; /* finished */ } } + return true; } @@ -231,8 +336,14 @@ * * @param basetime The input timestamp, in microseconds. */ -void RexxDateTime::setBaseTime(int64_t basetime) +bool RexxDateTime::setBaseTime(int64_t basetime) { + // make sure this is in range + if (basetime < 0 || basetime > maxBaseTime.getBaseTime()) + { + return false; + } + // first subtract out the date portion and process it int64_t basedays = basetime / MICROSECONDS_IN_DAY; basetime -= basedays * MICROSECONDS_IN_DAY; @@ -249,10 +360,28 @@ basetime = basetime % SECONDS_IN_HOUR; minutes = (int)(basetime / SECONDS_IN_MINUTE); seconds = (int)(basetime % SECONDS_IN_MINUTE); + + return true; } /** + * Set the date and time from a unix time value. The unix time + * is the number of seconds from 00:00:00 on 01 Jan 1970. The + * value may be either positive or negative. + * + * @param basetime The input timestamp, in seconds. + */ +bool RexxDateTime::setUnixTime(int64_t basetime) +{ + // calculate this as a base time value. + int64_t adjustedTime = (basetime * (int64_t)MICROSECONDS) + unixBaseTime.getBaseTime(); + // set the value based on the adjustment. + return setBaseTime(adjustedTime); +} + + +/** * Set the time stamp using the number of seconds since midnight. * * @param basetime The basetime, in seconds. @@ -979,8 +1108,6 @@ } - - /** * Format a base time into human readable form. * @@ -993,6 +1120,17 @@ /** + * Format a unix time into human readable form. + * + * @param buffer The target buffer for the output. + */ +void RexxDateTime::formatUnixTime(char *buffer) +{ + Numerics::formatInt64(getUnixTime(), (stringchar_t *)buffer); +} + + +/** * Format a date as the number of days in the current year. * * @param buffer The target buffer for the output. Modified: interpreter-3.x/trunk/kernel/runtime/RexxDateTime.hpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/RexxDateTime.hpp 2007-09-23 16:16:00 UTC (rev 792) +++ interpreter-3.x/trunk/kernel/runtime/RexxDateTime.hpp 2007-09-23 18:07:09 UTC (rev 793) @@ -111,6 +111,12 @@ { public: + RexxDateTime(); + RexxDateTime(int64_t basetime); + RexxDateTime(int basedate); + RexxDateTime(int year, int month, int day); + RexxDateTime(int year, int month, int day, int hour, int minutes, int seconds, int microseconds); + inline bool isLeapYear() { return ((!(year % LEAP_CYCLE)) && ((year % CENTURY) || (!(year % OLYMPIAD)))); } @@ -118,12 +124,14 @@ int getBaseDate(); int getTimeSeconds(); int64_t getBaseTime(); + int64_t getUnixTime(); int getYearDay(); int getWeekDay(); const char *getMonthName(); const char *getDayName(); - void setBaseDate(int basedays); - void setBaseTime(int64_t basetime); + bool setBaseDate(int basedays); + bool setBaseTime(int64_t basetime); + bool setUnixTime(int64_t basetime); void setTimeInSeconds(int basetime); void clear(); void setDate(int newYear, int newDay); @@ -141,6 +149,7 @@ bool setMinutes(int m); void formatBaseDate(char *buffer); void formatBaseTime(char *buffer); + void formatUnixTime(char *buffer); void formatDays(char *buffer); void formatEuropeanDate(char *buffer, const char *sep); void formatMonthName(char *buffer); @@ -177,6 +186,8 @@ static int monthStarts[]; // table of first day of month values for non-leap years static int leapMonthStarts[]; // table of first day of month values for leap years static int monthdays[]; // month number of days mapping table + static RexxDateTime unixBaseTime; // a base time used for Date('T')/Time('T') calculations. + static RexxDateTime maxBaseTime; // the largest possible date we can handle. }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2007-09-26 13:42:22
|
Revision: 809 http://oorexx.svn.sourceforge.net/oorexx/?rev=809&view=rev Author: bigrixx Date: 2007-09-26 06:42:22 -0700 (Wed, 26 Sep 2007) Log Message: ----------- [ 1802711 ] arg() returning unexpected value on prefix operators. Modified Paths: -------------- interpreter-3.x/trunk/kernel/classes/ObjectClass.cpp interpreter-3.x/trunk/kernel/messages/DocErrorMessages.sgml interpreter-3.x/trunk/kernel/messages/rexxmsg.xml Modified: interpreter-3.x/trunk/kernel/classes/ObjectClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/ObjectClass.cpp 2007-09-25 22:05:31 UTC (rev 808) +++ interpreter-3.x/trunk/kernel/classes/ObjectClass.cpp 2007-09-26 13:42:22 UTC (rev 809) @@ -1949,8 +1949,21 @@ }\ -operatorMethod(operator_plus , PLUS) -operatorMethod(operator_minus , SUBTRACT) +#undef prefixOperatorMethod +#define prefixOperatorMethod(name, message) RexxObject * RexxObject::name(RexxObject *operand) \ +{\ + RexxObject *result; /* returned result */\ + /* do a real message send */\ + result = (RexxObject *)this->messageSend(OREF_##message, operand == OREF_NULL ? 0 : 1, &operand); \ + if (result == OREF_NULL) /* in an expression and need a result*/ \ + /* need to raise an exception */ \ + report_exception1(Error_No_result_object_message, OREF_##message); \ + return result; /* return the final result */ \ +}\ + + +prefixOperatorMethod(operator_plus , PLUS) +prefixOperatorMethod(operator_minus , SUBTRACT) operatorMethod(operator_multiply , MULTIPLY) operatorMethod(operator_divide , DIVIDE) operatorMethod(operator_integerDivide , INTDIV) @@ -1980,7 +1993,7 @@ operatorMethod(operator_and , AND) operatorMethod(operator_or , OR) operatorMethod(operator_xor , XOR) -operatorMethod(operator_not , BACKSLASH) +prefixOperatorMethod(operator_not , BACKSLASH) void *RexxObject::operator new(size_t size, RexxClass *classObject) /******************************************************************************/ Modified: interpreter-3.x/trunk/kernel/messages/DocErrorMessages.sgml =================================================================== --- interpreter-3.x/trunk/kernel/messages/DocErrorMessages.sgml 2007-09-25 22:05:31 UTC (rev 808) +++ interpreter-3.x/trunk/kernel/messages/DocErrorMessages.sgml 2007-09-26 13:42:22 UTC (rev 809) @@ -2577,7 +2577,7 @@ <para> <emphasis role="bold">Explanation:</emphasis> </para> -<para>The specified method or built-in or external routine exists, but you used it incorrectly.</para> +<para>The specified method, built-in function, or external routine exists, but you used it incorrectly.</para> <para>The associated subcodes are: </para> <variablelist> <varlistentry> Modified: interpreter-3.x/trunk/kernel/messages/rexxmsg.xml =================================================================== --- interpreter-3.x/trunk/kernel/messages/rexxmsg.xml 2007-09-25 22:05:31 UTC (rev 808) +++ interpreter-3.x/trunk/kernel/messages/rexxmsg.xml 2007-09-26 13:42:22 UTC (rev 809) @@ -3485,7 +3485,7 @@ <Severity>Warning</Severity> <SymbolicName>Error_Incorrect_method</SymbolicName> <Text>Incorrect call to method</Text> - <Explanation><para>The specified method or built-in or external routine exists, but you used it incorrectly.</para></Explanation> + <Explanation><para>The specified method, built-in function, or external routine exists, but you used it incorrectly.</para></Explanation> <Subcodes> <SubMessage> <Code>93</Code> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <bi...@us...> - 2007-09-26 17:27:53
|
Revision: 812 http://oorexx.svn.sourceforge.net/oorexx/?rev=812&view=rev Author: bigrixx Date: 2007-09-26 10:27:50 -0700 (Wed, 26 Sep 2007) Log Message: ----------- [ 1802832 ] Add an explicit hashCode method to object. Modified Paths: -------------- interpreter-3.x/trunk/kernel/classes/ClassClass.cpp interpreter-3.x/trunk/kernel/classes/ClassClass.hpp interpreter-3.x/trunk/kernel/classes/IntegerClass.cpp interpreter-3.x/trunk/kernel/classes/IntegerClass.hpp interpreter-3.x/trunk/kernel/classes/NumberStringClass.cpp interpreter-3.x/trunk/kernel/classes/NumberStringClass.hpp interpreter-3.x/trunk/kernel/classes/ObjectClass.cpp interpreter-3.x/trunk/kernel/classes/ObjectClass.hpp interpreter-3.x/trunk/kernel/runtime/GlobalNames.h interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp interpreter-3.x/trunk/kernel/runtime/Setup.cpp Modified: interpreter-3.x/trunk/kernel/classes/ClassClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/ClassClass.cpp 2007-09-26 17:26:05 UTC (rev 811) +++ interpreter-3.x/trunk/kernel/classes/ClassClass.cpp 2007-09-26 17:27:50 UTC (rev 812) @@ -138,20 +138,27 @@ return new_proxy(this->id->stringData); } + +/** + * Hash a class object. Because behaviors don't always get set + * up properly with this, we'll always use the primitive one for + * class objects. + * + * @return A "hashed hash" that can be used by the map collections. + */ +ULONG RexxClass::hash() +{ + // always, always, always return the hash value + return HASHVALUE(this); +} + + RexxObject *RexxClass::strictEqual( RexxObject *other) /* other comparison object */ /******************************************************************************/ /* Function: Compare two classes */ /******************************************************************************/ { - LONG hash; /* retrieved hash */ - - if (other == OREF_NULL) { /* asking for the hash value? */ - hash = this->hashvalue; /* get the hash value */ - /* create a string value */ - return new_string((PCHAR)&hash, sizeof(LONG)); - } - else return this->equal(other); /* this is direct object equality */ } Modified: interpreter-3.x/trunk/kernel/classes/ClassClass.hpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/ClassClass.hpp 2007-09-26 17:26:05 UTC (rev 811) +++ interpreter-3.x/trunk/kernel/classes/ClassClass.hpp 2007-09-26 17:27:50 UTC (rev 812) @@ -67,6 +67,7 @@ RexxObject *makeProxy(RexxEnvelope*); BOOL isEqual(RexxObject *); + ULONG hash(); RexxObject * equal(RexxObject *); RexxObject * strictEqual(RexxObject *); RexxObject * notEqual(RexxObject *); Modified: interpreter-3.x/trunk/kernel/classes/IntegerClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/IntegerClass.cpp 2007-09-26 17:26:05 UTC (rev 811) +++ interpreter-3.x/trunk/kernel/classes/IntegerClass.cpp 2007-09-26 17:27:50 UTC (rev 812) @@ -551,6 +551,21 @@ return this->stringValue()->strictComp((RexxString *)other); } + +/** + * Exported version of the HASHCODE method for retrieving the + * object's hash. + * + * @return A string version of the hash (generally holds binary characters). + */ +RexxObject *RexxInteger::hashCode() +{ + // get the hash value, which is actually derived from the integer string value + unsigned long hash = this->hash(); + return new_string((char *)&hash, sizeof(unsigned long)); +} + + RexxInteger *RexxInteger::strictEqual( RexxObject *other) /* other comparison value */ /******************************************************************************/ @@ -558,17 +573,10 @@ /* value processing. */ /******************************************************************************/ { - LONG hash; /* retrieved hash */ - - if (other == OREF_NULL) { /* asking for the hash value? */ - hash = this->hash(); /* get the hash value */ - /* create a string value */ - return (RexxInteger *)new_string((PCHAR)&hash, sizeof(LONG)); - } - else return this->strictComp(other) == 0 ? TheTrueObject : TheFalseObject; } + RexxInteger *RexxInteger::strictNotEqual( RexxObject *other) /* other comparison value */ /******************************************************************************/ Modified: interpreter-3.x/trunk/kernel/classes/IntegerClass.hpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/IntegerClass.hpp 2007-09-26 17:26:05 UTC (rev 811) +++ interpreter-3.x/trunk/kernel/classes/IntegerClass.hpp 2007-09-26 17:27:50 UTC (rev 812) @@ -102,6 +102,7 @@ RexxInteger *strictLessThan(RexxObject *); RexxInteger *strictGreaterOrEqual(RexxObject *); RexxInteger *strictLessOrEqual(RexxObject *); + RexxObject *hashCode(); RexxObject *unknown(RexxString *, RexxArray *); RexxObject *plus(RexxInteger *); Modified: interpreter-3.x/trunk/kernel/classes/NumberStringClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/NumberStringClass.cpp 2007-09-26 17:26:05 UTC (rev 811) +++ interpreter-3.x/trunk/kernel/classes/NumberStringClass.cpp 2007-09-26 17:27:50 UTC (rev 812) @@ -2036,20 +2036,26 @@ return (this->comp(other) <= 0) ? TheTrueObject : TheFalseObject; } + +/** + * Exported version of the HASHCODE method for retrieving the + * object's hash. + * + * @return A string version of the hash (generally holds binary characters). + */ +RexxObject *RexxNumberString::hashCode() +{ + // get the hash value, which is actually derived from the integer string value + unsigned long hash = this->hash(); + return new_string((char *)&hash, sizeof(unsigned long)); +} + RexxInteger *RexxNumberString::strictEqual(RexxObject *other) /******************************************************************************/ /* Function: Perform the primitive level "==" compare, including the hash */ /* value processing. */ /******************************************************************************/ { - LONG hash; /* retrieved hash */ - - if (other == OREF_NULL) { /* asking for the hash value? */ - hash = this->hash(); /* get the hash value */ - /* create a string value */ - return (RexxInteger *)new_string((PCHAR)&hash, sizeof(LONG)); - } - else /* do the actual comparison */ return (this->strictComp(other) == 0) ? TheTrueObject : TheFalseObject; } Modified: interpreter-3.x/trunk/kernel/classes/NumberStringClass.hpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/NumberStringClass.hpp 2007-09-26 17:26:05 UTC (rev 811) +++ interpreter-3.x/trunk/kernel/classes/NumberStringClass.hpp 2007-09-26 17:27:50 UTC (rev 812) @@ -135,6 +135,7 @@ RexxInteger *strictLessThan(RexxObject *); RexxInteger *strictGreaterOrEqual(RexxObject *); RexxInteger *strictLessOrEqual(RexxObject *); + RexxObject *hashCode(); int ULong(ULONG *); RexxNumberString *clone(); Modified: interpreter-3.x/trunk/kernel/classes/ObjectClass.cpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/ObjectClass.cpp 2007-09-26 17:26:05 UTC (rev 811) +++ interpreter-3.x/trunk/kernel/classes/ObjectClass.cpp 2007-09-26 17:27:50 UTC (rev 812) @@ -315,20 +315,73 @@ } +/** + * Default implementation of the HASHCODE method. + * + * @return The object's hash code value. + */ +RexxObject *RexxObject::hashCode() +{ + // get the hash value directly, then turn it into a binary string value + unsigned long hash = HASHVALUE(this); + /* create a string value */ + return (RexxObject *)new_string((char *)&hash, sizeof(long)); +} + + +/** + * Hash an exported object. Of we're a non-primitive one, this + * will require us to send the HASHCODE message to request a + * hash value. + * + * @return A "hashed hash" that can be used by the map collections. + */ +ULONG RexxObject::hash() +{ + // if this is a primitive object, we can just return the stored hash code. + if (isPrimitive(this)) + { + return HASHVALUE(this); + } + else + { + ULONG hash; + + // we have some other type of object, so we need to request a hash code + // by sending the HASHCODE() message. + RexxString *hashString = this->sendMessage(OREF_HASHCODE)->stringValue(); + + // ok, we need to pick this string apart and turn this into a numeric code + // a null string is simple. + if (hashString->length == 0) + { + hash = 1; + } + + // if we have at least 4 characters, use them as binary, since that's + // what is normally returned here. + else if (hashString->length >= sizeof(LONG)) + { + hash = *((PULONG)hashString->stringData); + } + + else + { + // either 1 or 2 characters. Just pick up a short value, which will + // also pick up terminating null if only a single character + hash = *((PSHORT)hashString->stringData); + } + return hash; + } +} + + RexxObject * RexxObject::strictEqual( RexxObject * other) /* other object for comparison */ /******************************************************************************/ /* Function: Process the default "==" strict comparison operator */ /******************************************************************************/ { - LONG hash; /* retrieved hash */ - - if (other == OREF_NULL) { /* asking for the hash value? */ - hash = HASHVALUE(this); /* get the hash value */ - /* create a string value */ - return (RexxObject *)new_string((PCHAR)&hash, sizeof(LONG)); - } - else /* this is direct object equality */ return (RexxObject *)((this == other)? TheTrueObject: TheFalseObject); } Modified: interpreter-3.x/trunk/kernel/classes/ObjectClass.hpp =================================================================== --- interpreter-3.x/trunk/kernel/classes/ObjectClass.hpp 2007-09-26 17:26:05 UTC (rev 811) +++ interpreter-3.x/trunk/kernel/classes/ObjectClass.hpp 2007-09-26 17:27:50 UTC (rev 812) @@ -194,11 +194,7 @@ void liveGeneral(); void flatten(RexxEnvelope *); RexxObject *copy(); -// see ObjectClass.c for defect description -#if defined(REXX_DEBUG) -// ULONG hash(); - ULONG hash() { fprintf(stderr,"*** RexxObject::hash called ***\n"); } -#endif + ULONG hash(); BOOL truthValue(LONG); long longValue(size_t); long longValueNoNOSTRING(size_t); @@ -285,6 +281,8 @@ RexxInteger *identityHashRexx(); + RexxObject *hashCode(); + RexxString *stringRexx(); RexxObject *makeStringRexx(); RexxObject *makeArrayRexx(); Modified: interpreter-3.x/trunk/kernel/runtime/GlobalNames.h =================================================================== --- interpreter-3.x/trunk/kernel/runtime/GlobalNames.h 2007-09-26 17:26:05 UTC (rev 811) +++ interpreter-3.x/trunk/kernel/runtime/GlobalNames.h 2007-09-26 17:27:50 UTC (rev 812) @@ -92,6 +92,7 @@ GLOBAL_NAME(GREATERTHAN_LESSTHAN, CHAR_GREATERTHAN_LESSTHAN) GLOBAL_NAME(HALT, CHAR_HALT) GLOBAL_NAME(HASMETHOD, CHAR_HASMETHOD) + GLOBAL_NAME(HASHCODE, CHAR_HASHCODE) GLOBAL_NAME(IMPORT, CHAR_IMPORT) GLOBAL_NAME(INHERIT, CHAR_INHERIT) GLOBAL_NAME(INIT, CHAR_INIT) Modified: interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp 2007-09-26 17:26:05 UTC (rev 811) +++ interpreter-3.x/trunk/kernel/runtime/RexxConstants.hpp 2007-09-26 17:27:50 UTC (rev 812) @@ -464,6 +464,7 @@ CHARCONSTANT(FORM, "FORM"); CHARCONSTANT(FORMAT, "FORMAT"); CHARCONSTANT(FUZZ, "FUZZ"); +CHARCONSTANT(HASHCODE, "HASHCODE"); CHARCONSTANT(IDENTITYHASH, "IDENTITYHASH"); CHARCONSTANT(INSERT, "INSERT"); CHARCONSTANT(LASTPOS, "LASTPOS"); Modified: interpreter-3.x/trunk/kernel/runtime/Setup.cpp =================================================================== --- interpreter-3.x/trunk/kernel/runtime/Setup.cpp 2007-09-26 17:26:05 UTC (rev 811) +++ interpreter-3.x/trunk/kernel/runtime/Setup.cpp 2007-09-26 17:27:50 UTC (rev 812) @@ -97,6 +97,7 @@ CPPM(RexxObject::classObject), CPPM(RexxObject::equal), CPPM(RexxObject::strictEqual), +CPPM(RexxObject::hashCode), CPPM(RexxObject::init), CPPM(RexxObject::strictNotEqual), CPPM(RexxObject::copyRexx), @@ -214,6 +215,7 @@ CPPMI(RexxInteger::equal), CPPMI(RexxInteger::notEqual), CPPMI(RexxInteger::strictEqual), +CPPMI(RexxInteger::hashCode), CPPMI(RexxInteger::strictNotEqual), CPPMI(RexxInteger::isGreaterThan), CPPMI(RexxInteger::isLessThan), @@ -316,6 +318,7 @@ CPPMNM(RexxNumberString::d2x), CPPMNM(RexxNumberString::d2xD2c), CPPMNM(RexxNumberString::strictEqual), +CPPMNM(RexxNumberString::hashCode), CPPMQ(RexxQueue::supplier), /* Queue methods */ CPPMQ(RexxQueue::pushRexx), @@ -765,6 +768,9 @@ defineKernelMethod(CHAR_ISSUBCLASSOF ,TheClassBehaviour, CPPMC(RexxClass::isSubclassOf), 1); defineProtectedKernelMethod(CHAR_SHRIEKREXXDEFINED,TheClassBehaviour, CPPMC(RexxClass::setRexxDefined), 0); defineKernelMethod(CHAR_DEFAULTNAME ,TheClassBehaviour, CPPM(RexxClass::defaultNameRexx), 0); + // this is explicitly inserted into the class behaviour because it gets used + // prior to the instance behavior merges. + defineKernelMethod(CHAR_HASHCODE ,TheClassBehaviour, CPPM(RexxObject::hashCode), 0); /* set the scope of the methods to */ /* the CLASS scope */ @@ -789,6 +795,7 @@ defineKernelMethod(CHAR_INIT ,TheObjectBehaviour, CPPM(RexxObject::init), 0); defineKernelMethod(CHAR_EQUAL ,TheObjectBehaviour, CPPM(RexxObject::equal), 1); defineKernelMethod(CHAR_STRICT_EQUAL ,TheObjectBehaviour, CPPM(RexxObject::strictEqual), 1); + defineKernelMethod(CHAR_HASHCODE ,TheObjectBehaviour, CPPM(RexxObject::hashCode), 0); defineKernelMethod(CHAR_BACKSLASH_EQUAL ,TheObjectBehaviour, CPPM(RexxObject::notEqual), 1); defineKernelMethod(CHAR_LESSTHAN_GREATERTHAN ,TheObjectBehaviour, CPPM(RexxObject::notEqual), 1); defineKernelMethod(CHAR_GREATERTHAN_LESSTHAN ,TheObjectBehaviour, CPPM(RexxObject::notEqual), 1); @@ -1386,6 +1393,7 @@ defineKernelMethod(CHAR_LESSTHAN_EQUAL ,TheIntegerBehaviour, CPPMI(RexxInteger::isLessOrEqual), 1); defineKernelMethod(CHAR_BACKSLASH_GREATERTHAN ,TheIntegerBehaviour, CPPMI(RexxInteger::isLessOrEqual), 1); defineKernelMethod(CHAR_STRICT_EQUAL ,TheIntegerBehaviour, CPPMI(RexxInteger::strictEqual), 1); + defineKernelMethod(CHAR_HASHCODE ,TheIntegerBehaviour, CPPMI(RexxInteger::hashCode), 1); defineKernelMethod(CHAR_STRICT_BACKSLASH_EQUAL ,TheIntegerBehaviour, CPPMI(RexxInteger::strictNotEqual), 1); defineKernelMethod(CHAR_STRICT_GREATERTHAN ,TheIntegerBehaviour, CPPMI(RexxInteger::strictGreaterThan), 1); defineKernelMethod(CHAR_STRICT_LESSTHAN ,TheIntegerBehaviour, CPPMI(RexxInteger::strictLessThan), 1); @@ -1439,6 +1447,7 @@ defineKernelMethod(CHAR_LESSTHAN_EQUAL ,TheNumberStringBehaviour, CPPMNM(RexxNumberString::isLessOrEqual), 1); defineKernelMethod(CHAR_BACKSLASH_GREATERTHAN ,TheNumberStringBehaviour, CPPMNM(RexxNumberString::isLessOrEqual), 1); defineKernelMethod(CHAR_STRICT_EQUAL ,TheNumberStringBehaviour, CPPMNM(RexxNumberString::strictEqual), 1); + defineKernelMethod(CHAR_HASHCODE ,TheNumberStringBehaviour, CPPMNM(RexxNumberString::hashCode), 0); defineKernelMethod(CHAR_STRICT_BACKSLASH_EQUAL ,TheNumberStringBehaviour, CPPMNM(RexxNumberString::strictNotEqual), 1); defineKernelMethod(CHAR_STRICT_GREATERTHAN ,TheNumberStringBehaviour, CPPMNM(RexxNumberString::strictGreaterThan), 1); defineKernelMethod(CHAR_STRICT_LESSTHAN ,TheNumberStringBehaviour, CPPMNM(RexxNumberString::strictLessThan), 1); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |