Screenshot instructions:
Windows
Mac
Red Hat Linux
Ubuntu
Click URL instructions:
Right-click on ad, choose "Copy Link", then paste here →
(This may not be possible with some types of ads)
You can subscribe to this list here.
2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(43) |
Aug
(25) |
Sep
(34) |
Oct
(136) |
Nov
(81) |
Dec
(33) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2010 |
Jan
(69) |
Feb
(123) |
Mar
(176) |
Apr
(110) |
May
(128) |
Jun
(119) |
Jul
(57) |
Aug
(96) |
Sep
(69) |
Oct
(28) |
Nov
(39) |
Dec
(102) |
2011 |
Jan
(12) |
Feb
(39) |
Mar
(24) |
Apr
(20) |
May
(9) |
Jun
(29) |
Jul
(48) |
Aug
(37) |
Sep
(38) |
Oct
(35) |
Nov
(37) |
Dec
(85) |
2012 |
Jan
(54) |
Feb
(75) |
Mar
(45) |
Apr
(110) |
May
(111) |
Jun
(56) |
Jul
(14) |
Aug
(35) |
Sep
(45) |
Oct
(4) |
Nov
|
Dec
|
From: <subik@us...> - 2012-10-11 11:34:46
|
Revision: 5047 http://qore.svn.sourceforge.net/qore/?rev=5047&view=rev Author: subik Date: 2012-10-11 11:34:40 +0000 (Thu, 11 Oct 2012) Log Message: ----------- disabled old repository Added Paths: ----------- README Removed Paths: ------------- module-asn1/ module-db2/ module-dummy/ module-glut/ module-gnu-java/ module-json/ module-magic/ module-mysql/ module-ncurses/ module-opengl/ module-oracle/ module-pgsql/ module-qt/ module-qt4/ module-sqlite3/ module-ssh2/ module-sybase/ module-sysconf/ module-tibae/ module-tibrv/ module-tuxedo/ module-uuid/ module-xml/ module-xmlsec/ module-yaml/ qore/ qore-eclipse-ide/ Added: README =================================================================== --- README (rev 0) +++ README 2012-10-11 11:34:40 UTC (rev 5047) @@ -0,0 +1,6 @@ +Qore SVN repository has been moved to the new URL + +Please visit this website to get new information: + +https://sourceforge.net/projects/qore/ + This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <subik@us...> - 2012-10-08 13:27:49
|
Revision: 5046 http://qore.svn.sourceforge.net/qore/?rev=5046&view=rev Author: subik Date: 2012-10-08 13:27:40 +0000 (Mon, 08 Oct 2012) Log Message: ----------- typo fix Modified Paths: -------------- qore/trunk/lib/ql_list.qpp Modified: qore/trunk/lib/ql_list.qpp =================================================================== --- qore/trunk/lib/ql_list.qpp 2012-10-08 13:23:47 UTC (rev 5045) +++ qore/trunk/lib/ql_list.qpp 2012-10-08 13:27:40 UTC (rev 5046) @@ -48,7 +48,7 @@ QoreListNode *range_intern(int64 start, int64 stop, int64 step, ExceptionSink *xsink) { if (step < 1) { - xsink->raiseException("RANGE-ERROR", "Value of the 'step' argument has to be greater than 1"); + xsink->raiseException("RANGE-ERROR", "Value of the 'step' argument has to be greater than 0"); return 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <subik@us...> - 2012-10-08 13:23:57
|
Revision: 5045 http://qore.svn.sourceforge.net/qore/?rev=5045&view=rev Author: subik Date: 2012-10-08 13:23:47 +0000 (Mon, 08 Oct 2012) Log Message: ----------- range() implemented - test Modified Paths: -------------- qore/trunk/include/qore/intern/qore_thread_intern.h qore/trunk/test/test.q Modified: qore/trunk/include/qore/intern/qore_thread_intern.h =================================================================== --- qore/trunk/include/qore/intern/qore_thread_intern.h 2012-10-08 13:14:10 UTC (rev 5044) +++ qore/trunk/include/qore/intern/qore_thread_intern.h 2012-10-08 13:23:47 UTC (rev 5045) @@ -109,7 +109,7 @@ } DLLLOCAL ~ModuleContextNamespaceList() { - assert(empty()); + //assert(empty()); } DLLLOCAL void clear(); @@ -136,7 +136,7 @@ } DLLLOCAL ~ModuleContextFunctionList() { - assert(empty()); + //assert(empty()); } DLLLOCAL void clear(); Modified: qore/trunk/test/test.q =================================================================== --- qore/trunk/test/test.q 2012-10-08 13:14:10 UTC (rev 5044) +++ qore/trunk/test/test.q 2012-10-08 13:23:47 UTC (rev 5045) @@ -272,6 +272,15 @@ my binary $bin = binary($astr); test_value($bin[4], ord("o"), "binary byte dereference"); + # range tests + test_value(range(1), (0, 1,), "range - basic test"); + test_value(range(2, 5), (2, 3, 4, 5), "range - boundaries test"); + test_value(range(2, -2), (2, 1, 0, -1, -2), "range - descending test"); + test_value(range(1, 10, 5), (1, 6), "range - step test"); + test_value(range(0, 10, 5), (0, 5, 10), "range - step from 0"); + test_value(range(-10, 10, 5), (-10, -5, 0, 5, 10), "range - asc test"); + test_value(range(10, -10, 5), (10, 5, 0, -5, -10), "range - descending step test"); + # pseudomethods my list $pseudoList = (1, 2, 3, 4, 'a'); test_value($pseudoList.typeCode(), NT_LIST, "<list>::typeCode"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <subik@us...> - 2012-10-08 13:14:21
|
Revision: 5044 http://qore.svn.sourceforge.net/qore/?rev=5044&view=rev Author: subik Date: 2012-10-08 13:14:10 +0000 (Mon, 08 Oct 2012) Log Message: ----------- range() implemented Modified Paths: -------------- qore/trunk/lib/ql_list.qpp Modified: qore/trunk/lib/ql_list.qpp =================================================================== --- qore/trunk/lib/ql_list.qpp 2012-09-15 20:55:56 UTC (rev 5043) +++ qore/trunk/lib/ql_list.qpp 2012-10-08 13:14:10 UTC (rev 5044) @@ -45,7 +45,28 @@ return false; } +QoreListNode *range_intern(int64 start, int64 stop, int64 step, ExceptionSink *xsink) +{ + if (step < 1) { + xsink->raiseException("RANGE-ERROR", "Value of the 'step' argument has to be greater than 1"); + return 0; + } + QoreListNode *l = new QoreListNode(); + if (start < stop) { + for (int64 i = start; i <= stop; i += step) { + l->push(new QoreBigIntNode(i)); + } + } + else { + for (int64 i = start; i >= stop; i -= step) { + l->push(new QoreBigIntNode(i)); + } + } + return l; +} + + /** @defgroup list_functions List Functions List functions */ @@ -596,4 +617,42 @@ } return false; } + + +//! Returns a list containing an arithmetic progression of integers. +/** + @param start the initial value + @param stop the final value + @param step the step. Default is 1. It throws \c RANGE-ERROR exception of is the \c step < 1 + + @return Returns a list containing an arithmetic progression of integers. + + @par Example: + @code +range(1); # (0, 1,) +range(2, 5); # (2, 3, 4, 5) +range(2, -2); # (2, 1, 0, -1, -2) +range(1, 10, 5); # (1, 6) +range(0, 10, 5); # (0, 5, 10) +range(-10, 10, 5); # (-10, -5, 0, 5, 10) +range(10, -10, 5); # (10, 5, 0, -5, -10) + @endcode +*/ +list range(int start, int stop, int step=1) [flags=RET_VALUE_ONLY] { + return range_intern(start, stop, step, xsink); +} + +//! Returns a list containing an arithmetic progression of integers with start = 0 and step = 1. +/** + This is an overloaded version of \c range(start, stop, step). With meaning \c range(0, stop, 1). + + @param stop the final value + + @return Returns a list containing an arithmetic progression of integers with start = 0 and step = 1. + */ +list range(int stop) [flags=RET_VALUE_ONLY] { + return range_intern(0, stop, 1, xsink); +} + + //@} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <david_nichols@us...> - 2012-09-15 20:56:04
|
Revision: 5043 http://qore.svn.sourceforge.net/qore/?rev=5043&view=rev Author: david_nichols Date: 2012-09-15 20:55:56 +0000 (Sat, 15 Sep 2012) Log Message: ----------- * added docs for number type * added <number> pseudo-class * added constants for number type * added docs for unreferenced-variable warning Modified Paths: -------------- qore/trunk/Makefile.am qore/trunk/RELEASE-NOTES qore/trunk/doxygen/lang/145_basic_data_types.dox.tmpl qore/trunk/doxygen/lang/155_data_type_declarations.dox.tmpl qore/trunk/doxygen/lang/180_operators.dox.tmpl qore/trunk/doxygen/lang/215_classes.dox.tmpl qore/trunk/doxygen/lang/250_warnings.dox.tmpl qore/trunk/doxygen/lang/mainpage.dox.tmpl qore/trunk/include/qore/intern/QorePseudoMethods.h qore/trunk/include/qore/intern/qore_number_private.h qore/trunk/lib/Makefile.am qore/trunk/lib/Pseudo_QC_All.qpp qore/trunk/lib/Pseudo_QC_Binary.qpp qore/trunk/lib/Pseudo_QC_Bool.qpp qore/trunk/lib/Pseudo_QC_Callref.qpp qore/trunk/lib/Pseudo_QC_Closure.qpp qore/trunk/lib/Pseudo_QC_Date.qpp qore/trunk/lib/Pseudo_QC_Float.qpp qore/trunk/lib/Pseudo_QC_Hash.qpp qore/trunk/lib/Pseudo_QC_Int.qpp qore/trunk/lib/Pseudo_QC_List.qpp qore/trunk/lib/Pseudo_QC_Nothing.qpp qore/trunk/lib/Pseudo_QC_String.qpp qore/trunk/lib/QorePseudoMethods.cpp qore/trunk/lib/qc_qore.qpp qore/trunk/lib/ql_math.qpp qore/trunk/lib/ql_type.qpp Added Paths: ----------- qore/trunk/lib/Pseudo_QC_Number.qpp Modified: qore/trunk/Makefile.am =================================================================== --- qore/trunk/Makefile.am 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/Makefile.am 2012-09-15 20:55:56 UTC (rev 5043) @@ -87,6 +87,7 @@ lib/Pseudo_QC_Bool.qpp \ lib/Pseudo_QC_Int.qpp \ lib/Pseudo_QC_Float.qpp \ + lib/Pseudo_QC_Number.qpp \ lib/Pseudo_QC_Closure.qpp \ lib/Pseudo_QC_Callref.qpp \ lib/ql_misc.qpp \ Modified: qore/trunk/RELEASE-NOTES =================================================================== --- qore/trunk/RELEASE-NOTES 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/RELEASE-NOTES 2012-09-15 20:55:56 UTC (rev 5043) @@ -19,7 +19,7 @@ includes threading primitives needed by the Qore language itself. This was apparently a conscious design decision in Darwin development and is not likely to change. - (tested with Darwin 11.3.0 = OSX 10.7.3) + (tested with Darwin 11.3.0/OSX 10.7.3 - 12.1.0/OSX 10.8.1) * Darwin does not seem to have complete support for signaling in threads; for example, sigprocmask() has to be called after pthread_sigmask() in order to effect changes in the thread signal mask (this is only necessary @@ -27,9 +27,9 @@ Additionally, SIGINFO and SIGWINCH are never delivered to Qore's signal handling thread even though the signal mask is set up appropriately (other signals are delivered correctly though) - this only happens on Darwin - (tested with Darwin 11.3.0 = OSX 10.7.3) + (tested with Darwin 11.3.0/OSX 10.7.3 - 12.1.0/OSX 10.8.1) * pthread_create() on Darwin (on <= Darwin 10 - however this problem is - fixed on Darwin 11.3.0+ = OSX 10.7.3+) returns 0 (= success) even though + fixed on Darwin 11.3.0+/OSX 10.7.3+) returns 0 (= success) even though thread creation fails - the background thread is never started. Therefore on Darwin < 11 the maximum number of threads is set to 2560 which is the empirically tested maximum number of threads where pthread_create() still Modified: qore/trunk/doxygen/lang/145_basic_data_types.dox.tmpl =================================================================== --- qore/trunk/doxygen/lang/145_basic_data_types.dox.tmpl 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/doxygen/lang/145_basic_data_types.dox.tmpl 2012-09-15 20:55:56 UTC (rev 5043) @@ -10,6 +10,7 @@ |@ref string|A sequence of characters with an encoding|\c "string"|Empty string (i.e. \c "") |@ref integer|A 64-bit signed integer|\c 1|\c 0 |@ref float|A double-precision floating-point number|\c 1.00023|\c 0.0 + |@ref number|An arbitrary-precision number|\c 5.23928173726123e50n|\c 0.0n |@ref date|@ref absolute_dates "absolute" or @ref relative_dates "relative" date/time values with resolution to the microsecond|\c 2010-05-10T18:35:21.001456-07:00|\c 1970-01-01Z |@ref binary|An opaque binary object|<tt><23deadbeef></tt>|an empty object of size 0 |@ref null|Corresponds to a \c NULL value in a database query (not equivalent to @ref nothing|@ref Qore::NULL|@ref Qore::NULL @@ -92,8 +93,9 @@ @par Description: %Qore floats are double precision floating-point numbers (C/C++ type double), normally a 64-bit value. - @par Immediate Value Example: - \c -500.494 + @par Immediate Value Examples: + - \c -500.494 + - \c 2.35e10 @par Pseudo Class for Type Float: @ref Qore::zzz8floatzzz9 @@ -109,13 +111,40 @@ - @ref math_functions <hr> + @section number Number + + @par Description: + %Qore "number" values are arbitrary-precision numbers as provided by the <a href="http://gmplib.org">GMP</a> and <a href="http://www.mpfr.org">MPFR</a> libraries.\n\n + Operations with number values are generally slower than those with @ref float "floats" but support far greater accuracy. To give an immediate number value; write an integer or floating-point value and append an \c "n" to it, designating a "number" value.\n\n + In numeric operations where at least one argument is a number type, the other operands will generally be automatically converted to a number type and the result of the operation will also be a number type. When an operator acts on two values of type number, the result of the operation has the precision of the operand with the greatest precision. + + @par Immediate Value Example: + - \c -500.494n + - \c 2.35e10n + + @par Pseudo Class for Type Float: + @ref Qore::zzz8numberzzz9 + + @par Type Code: + @ref Qore::NT_NUMBER + + @par Type Name: + \c "number" + + @see + - @ref number_type, @ref softnumber_type + - @ref math_functions + + @since %Qore 0.8.6 introduced the number type and integration with the <a href="http://gmplib.org">GMP</a> and <a href="http://www.mpfr.org">MPFR</a> libraries + + <hr> @section date Date @par Description: %Qore date/time values have date and time components supporting a resolution to the microsecond and can be either @ref absolute_dates "absolute" or @ref relative_dates "relative". @par Immediate Value Examples: - - \c 2012-02-17T19:05:54+01:00 + - <tt>2012-02-17T19:05:54+01:00</tt> @par Pseudo Class for Type Date: @ref Qore::zzz8datezzz9 Modified: qore/trunk/doxygen/lang/155_data_type_declarations.dox.tmpl =================================================================== --- qore/trunk/doxygen/lang/155_data_type_declarations.dox.tmpl 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/doxygen/lang/155_data_type_declarations.dox.tmpl 2012-09-15 20:55:56 UTC (rev 5043) @@ -12,6 +12,7 @@ |!Name|!Accepts %Qore Type(s)|!Returns %Qore Type(s)|!Description |@ref int_type "int"|@ref integer|@ref integer|Restricts values @ref integer values |@ref float_type "float"|@ref float|@ref float|Restricts values to @ref float values + |@ref number_type "number"|@ref number|@ref number|Restricts values to @ref number values |@ref bool_type "bool"|@ref boolean|@ref boolean|Restricts values to @ref boolean values |@ref string_type "string"|@ref string|@ref string|Restricts values to @ref string values |@ref date_type "date"|@ref date|@ref date|Restricts values to @ref date values; values may be either @ref absolute_dates "absolute" or @ref relative_dates "relative" @@ -23,11 +24,12 @@ |@ref null_type "null"|@ref null|@ref null|Restricts values to %Qore's @ref null type; this type has few (if any) practical applications and has been included for completeness' sake |@ref nothing_type "nothing"|@ref nothing|@ref nothing|Restricts values to %Qore's @ref nothing type; this type is mostly useful for declaring that a function or method returns no value |@ref timeout_type "timeout"|@ref integer, @ref date|@ref integer|Accepts @ref integer, @ref date and converts dates to an integer value representing milliseconds and returns the integer; incoming integers are assumed to represent milliseconds - |@ref softint_type "softint"|@ref integer, @ref float, @ref boolean, @ref string, @ref null|@ref integer|Accepts @ref integer, @ref float, @ref boolean, @ref string, @ref null and converts non-integer values to an integer and returns the integer - |@ref softfloat_type "softfloat"|@ref integer, @ref float, @ref boolean, @ref string, @ref null|@ref float|Accepts @ref integer, @ref float, @ref boolean, @ref string, @ref null and converts non-float values to a float and returns the new value - |@ref softbool_type "softbool"|@ref integer, @ref float, @ref boolean, @ref string, @ref null|@ref boolean|Accepts @ref integer, @ref float, @ref boolean, @ref string, @ref null and converts non-boolean values to a boolean and returns the new value - |@ref softstring_type "softstring"|@ref integer, @ref float, @ref boolean, @ref string, @ref null|@ref string|Accepts @ref integer, @ref float, @ref boolean, @ref string, @ref null and converts non-string values to a string and returns the new value - |@ref softdate_type "softdate"|@ref integer, @ref float, @ref boolean, @ref string, @ref date, @ref null|@ref date|Accepts @ref integer, @ref float, @ref boolean, @ref string, @ref date, and @ref null and converts non-date values to a date and returns the new value + |@ref softint_type "softint"|@ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref null|@ref integer|Accepts @ref integer, @ref float, @ref boolean, @ref string, @ref null and converts non-integer values to an integer and returns the integer + |@ref softfloat_type "softfloat"|@ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref null|@ref float|Accepts @ref integer, @ref float, @ref boolean, @ref string, @ref null and converts non-float values to a float and returns the new value + |@ref softnumber_type "softnumber"|@ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref null|@ref float|Accepts @ref integer, @ref float, @ref boolean, @ref string, @ref null and converts non-float values to a float and returns the new value + |@ref softbool_type "softbool"|@ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref null|@ref boolean|Accepts @ref integer, @ref float, @ref boolean, @ref string, @ref null and converts non-boolean values to a boolean and returns the new value + |@ref softstring_type "softstring"|@ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref null|@ref string|Accepts @ref integer, @ref float, @ref boolean, @ref string, @ref null and converts non-string values to a string and returns the new value + |@ref softdate_type "softdate"|@ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref date, @ref null|@ref date|Accepts @ref integer, @ref float, @ref boolean, @ref string, @ref date, and @ref null and converts non-date values to a date and returns the new value |@ref softlist_type "softlist"|all types|@ref list|Accepts all types; @ref nothing is returned as an empty list; a list is returned unchanged, and any other type is returned as the first element of a new list |@ref data_type "data"|@ref string or @ref binary|same as received|Restricts input to @ref string and @ref binary and returns the same type |@ref code_type "code"|@ref closure, @ref call_reference|same as received|Restricts values to @ref closure "closures" and @ref call_reference "call references" @@ -45,11 +47,12 @@ |@ref data_or_nothing_type "*data"|@ref string, @ref binary, or @ref nothing|same as received|Restricts input to @ref string, @ref binary, or @ref nothing and returns the same type |@ref code_or_nothing_type "*code"|@ref closure, @ref call_reference, @ref nothing|same as received|Restricts values to @ref closure "closures", @ref call_reference "call references" and @ref nothing |@ref timeout_or_nothing_type "*timeout"|@ref integer, @ref date or @ref nothing|@ref integer or @ref nothing|Accepts @ref integer, @ref date and converts dates to an integer value representing milliseconds and returns the integer; incoming integers are assumed to represent milliseconds. If no value is passed, then @ref nothing is returned - |@ref softint_or_nothing_type "*softint"|@ref integer, @ref float, @ref boolean, @ref string, @ref null or @ref nothing|@ref integer or @ref nothing|Accepts @ref integer, @ref float, @ref boolean, @ref string, @ref null and converts non-integer values to an integer and returns the integer. If no value is passed, then @ref nothing is returned - |@ref softfloat_or_nothing_type "*softfloat"|@ref integer, @ref float, @ref boolean, @ref string, @ref null or @ref nothing|@ref float or @ref nothing|Accepts @ref integer, @ref float, @ref boolean, @ref string, @ref null and converts non-float values to a float and returns the new value. If no value is passed, then @ref nothing is returned - |@ref softbool_or_nothing_type "*softbool"|@ref integer, @ref float, @ref boolean, @ref string, @ref null or @ref nothing|@ref boolean or @ref nothing|Accepts @ref integer, @ref float, @ref boolean, @ref string, @ref null and converts non-boolean values to a boolean and returns the new value. If no value is passed, then @ref nothing is returned - |@ref softstring_or_nothing_type "*softstring"|@ref integer, @ref float, @ref boolean, @ref string, @ref null or @ref nothing|@ref string or @ref nothing|Accepts @ref integer, @ref float, @ref boolean, @ref string, @ref null and converts non-string values to a string and returns the new value. If no value is passed, then @ref nothing is returned - |@ref softdate_or_nothing_type "*softdate"|@ref integer, @ref float, @ref boolean, @ref string, @ref date, @ref null or @ref nothing|@ref date or @ref nothing|Accepts @ref integer, @ref float, @ref boolean, @ref string, @ref date, and @ref null and converts non-date values to a date and returns the new value. If no value is passed, then @ref nothing is returned + |@ref softint_or_nothing_type "*softint"|@ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref null or @ref nothing|@ref integer or @ref nothing|Accepts @ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref null and converts non-integer values to an integer and returns the integer. If no value is passed, then @ref nothing is returned + |@ref softfloat_or_nothing_type "*softfloat"|@ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref null or @ref nothing|@ref float or @ref nothing|Accepts @ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref null and converts non-float values to a float and returns the new value. If no value is passed, then @ref nothing is returned + |@ref softnumber_or_nothing_type "*softnumber"|@ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref null or @ref nothing|@ref number or @ref nothing|Accepts @ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref null and converts non-number values to a number and returns the new value. If no value is passed, then @ref nothing is returned + |@ref softbool_or_nothing_type "*softbool"|@ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref null or @ref nothing|@ref boolean or @ref nothing|Accepts @ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref null and converts non-boolean values to a boolean and returns the new value. If no value is passed, then @ref nothing is returned + |@ref softstring_or_nothing_type "*softstring"|@ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref null or @ref nothing|@ref string or @ref nothing|Accepts @ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref null and converts non-string values to a string and returns the new value. If no value is passed, then @ref nothing is returned + |@ref softdate_or_nothing_type "*softdate"|@ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref date, @ref null or @ref nothing|@ref date or @ref nothing|Accepts @ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref date, and @ref null and converts non-date values to a date and returns the new value. If no value is passed, then @ref nothing is returned |@ref softlist_or_nothing_type "*softlist"|all types|@ref list or @ref nothing|Accepts all types; @ref nothing and list values are returned as the same value; any other type is returned as the first element of a new list |@ref any_type "any"|any|same as received|Provides no restrictions on the type of value it receives and returns the same value @@ -82,6 +85,22 @@ @endcode <hr> + @section number_type number + + <b>number Type Restriction</b> + |!Name|!Accepts %Qore Type(s)|!Returns %Qore Type(s)|!Description + |\c number|@ref number|@ref number|Restricts values to %Qore's @ref number type + + @par Example + @code +number sub foo(number $n = 2.35e40) { + return $n; +} + @endcode + + @since %Qore 0.8.6 introduced the number type + + <hr> @section bool_type bool <b>bool Type Restriction</b> @@ -239,7 +258,7 @@ <b>softint Type Restriction</b> |!Name|!Accepts %Qore Type(s)|!Returns %Qore Type(s)|!Description - |\c softint|@ref integer, @ref float, @ref boolean, @ref string, @ref null|@ref integer|Accepts @ref integer, @ref float, @ref boolean, @ref string, and @ref null values and converts non-integer values to an integer and returns the integer + |\c softint|@ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref null|@ref integer|Accepts @ref integer, @ref float, @ref number, @ref boolean, @ref string, and @ref null values and converts non-integer values to an integer and returns the integer @par Example @code @@ -254,7 +273,7 @@ <b>softfloat Type Restriction</b> |!Name|!Accepts %Qore Type(s)|!Returns %Qore Type(s)|!Description - |\c softfloat|@ref integer, @ref float, @ref boolean, @ref string, @ref null|@ref float|Accepts @ref integer, @ref float, @ref boolean, @ref string, and @ref null values and converts non-float values to a float and returns the float + |\c softfloat|@ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref null|@ref float|Accepts @ref integer, @ref float, @ref number, @ref boolean, @ref string, and @ref null values and converts non-float values to a float and returns the float @par Example @code @@ -265,11 +284,28 @@ @endcode <hr> + @section softnumber_type softnumber + + <b>softnumber Type Restriction</b> + |!Name|!Accepts %Qore Type(s)|!Returns %Qore Type(s)|!Description + |\c softnumber|@ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref null|@ref float|Accepts @ref integer, @ref float, @ref number, @ref boolean, @ref string, and @ref null values and converts non-number values to a number and returns the number + + @par Example + @code +softnumber sub foo(softnumber $n = "1000") { + # note that "200" will be converted to a number on return + return $n > 500.0n ? "200" : $n; +} + @endcode + + @since %Qore 0.8.6 introduced the softnumber type + + <hr> @section softbool_type softbool <b>softbool Type Restriction</b> |!Name|!Accepts %Qore Type(s)|!Returns %Qore Type(s)|!Description - |\c softbool|@ref integer, @ref float, @ref boolean, @ref string, @ref null|@ref boolean|Accepts @ref integer, @ref float, @ref boolean, @ref string, and @ref null values and converts non-boolean values to a boolean and returns the boolean + |\c softbool|@ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref null|@ref boolean|Accepts @ref integer, @ref float, @ref number, @ref boolean, @ref string, and @ref null values and converts non-boolean values to a boolean and returns the boolean @par Example @code @@ -281,7 +317,7 @@ <b>softstring Type Restriction</b> |!Name|!Accepts %Qore Type(s)|!Returns %Qore Type(s)|!Description - |\c softstring|@ref integer, @ref float, @ref boolean, @ref string, @ref null|@ref string|Accepts @ref integer, @ref float, @ref boolean, @ref string, and @ref null values and converts non-string values to a string and returns the string + |\c softstring|@ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref null|@ref string|Accepts @ref integer, @ref float, @ref number, @ref boolean, @ref string, and @ref null values and converts non-string values to a string and returns the string @par Example @code @@ -293,7 +329,7 @@ <b>softdate Type Restriction</b> |!Name|!Accepts %Qore Type(s)|!Returns %Qore Type(s)|!Description - |\c softdate|@ref integer, @ref float, @ref boolean, @ref string, @ref date, @ref null|@ref date|Accepts @ref integer, @ref float, @ref boolean, @ref string, @ref date, and @ref null values and converts non-date values to a date and returns the date + |\c softdate|@ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref date, @ref null|@ref date|Accepts @ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref date, and @ref null values and converts non-date values to a date and returns the date @par Example @code @@ -316,6 +352,8 @@ } @endcode + @since %Qore 0.8.3 introduced the softlist type + <hr> @section data_type data @@ -392,11 +430,27 @@ @endcode <hr> + @section number_or_nothing_type *number + + <b>*number Type Restriction</b> + |!Name|!Accepts %Qore Type(s)|!Returns %Qore Type(s)|!Description + |\c *number|@ref number or @ref nothing|same as received|Restricts values to @ref number and @ref nothing + + @par Example + @code +*number sub foo(*number $n) { + return $n; +} + @endcode + + @since %Qore 0.8.6 introduced the *number type + + <hr> @section bool_or_nothing_type *bool <b>*bool Type Restriction</b> |!Name|!Accepts %Qore Type(s)|!Returns %Qore Type(s)|!Description - |\c *bool|@ref float or @ref nothing|same as received|Restricts values to @ref boolean and @ref nothing + |\c *bool|@ref boolean or @ref nothing|same as received|Restricts values to @ref boolean and @ref nothing @par Example @code @@ -545,7 +599,7 @@ <b>*softint Type Restriction</b> |!Name|!Accepts %Qore Type(s)|!Returns %Qore Type(s)|!Description - |\c *softint|@ref integer, @ref float, @ref boolean, @ref string, @ref null, @ref nothing|@ref integer or @ref nothing|Accepts @ref integer, @ref float, @ref boolean, @ref string, and @ref null values and converts non-integer values to an integer and returns the integer; also accepts @ref nothing and returns @ref nothing + |\c *softint|@ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref null, @ref nothing|@ref integer or @ref nothing|Accepts @ref integer, @ref float, @ref number, @ref boolean, @ref string, and @ref null values and converts non-integer values to an integer and returns the integer; also accepts @ref nothing and returns @ref nothing @par Example @code @@ -558,7 +612,7 @@ <b>*softfloat Type Restriction</b> |!Name|!Accepts %Qore Type(s)|!Returns %Qore Type(s)|!Description - |\c *softfloat|@ref integer, @ref float, @ref boolean, @ref string, @ref null, @ref nothing|@ref float or @ref nothing|Accepts @ref integer, @ref float, @ref boolean, @ref string, and @ref null values and converts non-float values to a float and returns the float; also accepts @ref nothing and returns @ref nothing + |\c *softfloat|@ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref null, @ref nothing|@ref float or @ref nothing|Accepts @ref integer, @ref float, @ref number, @ref boolean, @ref string, and @ref null values and converts non-float values to a float and returns the float; also accepts @ref nothing and returns @ref nothing @par Example @code @@ -567,11 +621,26 @@ @endcode <hr> + @section softnumber_or_nothing_type *softnumber + + <b>*softnumber Type Restriction</b> + |!Name|!Accepts %Qore Type(s)|!Returns %Qore Type(s)|!Description + |\c *softnumber|@ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref null, @ref nothing|@ref number or @ref nothing|Accepts @ref integer, @ref float, @ref number, @ref boolean, @ref string, and @ref null values and converts non-number values to a number and returns the number; also accepts @ref nothing and returns @ref nothing + + @par Example + @code +sub foo(*softnumber $n) { +} + @endcode + + @since %Qore 0.8.6 introduced the *softnumber type + + <hr> @section softbool_or_nothing_type *softbool <b>*softbool Type Restriction</b> |!Name|!Accepts %Qore Type(s)|!Returns %Qore Type(s)|!Description - |\c *softbool|@ref integer, @ref float, @ref boolean, @ref string, @ref null, @ref nothing|@ref boolean or @ref nothing|Accepts @ref integer, @ref float, @ref boolean, @ref string, and @ref null values and converts non-boolean values to a boolean and returns the boolean; also accepts @ref nothing and returns @ref nothing + |\c *softbool|@ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref null, @ref nothing|@ref boolean or @ref nothing|Accepts @ref integer, @ref float, @ref number, @ref boolean, @ref string, and @ref null values and converts non-boolean values to a boolean and returns the boolean; also accepts @ref nothing and returns @ref nothing @par Example @code @@ -584,7 +653,7 @@ <b>*softstring Type Restriction</b> |!Name|!Accepts %Qore Type(s)|!Returns %Qore Type(s)|!Description - |\c *softstring|@ref integer, @ref float, @ref boolean, @ref string, @ref null, @ref nothing|@ref string or @ref nothing|Accepts @ref integer, @ref float, @ref boolean, @ref string, and @ref null values and converts non-string values to a string and returns the string; also accepts @ref nothing and returns @ref nothing + |\c *softstring|@ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref null, @ref nothing|@ref string or @ref nothing|Accepts @ref integer, @ref float, @ref number, @ref boolean, @ref string, and @ref null values and converts non-string values to a string and returns the string; also accepts @ref nothing and returns @ref nothing @par Example @code @@ -597,7 +666,7 @@ <b>*softdate Type Restriction</b> |!Name|!Accepts %Qore Type(s)|!Returns %Qore Type(s)|!Description - |\c *softdate|@ref integer, @ref float, @ref boolean, @ref string, @ref date, @ref null, @ref nothing|@ref string or @ref nothing|Accepts @ref integer, @ref float, @ref boolean, @ref string, @ref date, and @ref null values and converts non-date values to a date and returns the date; also accepts @ref nothing and returns @ref nothing + |\c *softdate|@ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref date, @ref null, @ref nothing|@ref string or @ref nothing|Accepts @ref integer, @ref float, @ref number, @ref boolean, @ref string, @ref date, and @ref null values and converts non-date values to a date and returns the date; also accepts @ref nothing and returns @ref nothing @par Example @code @@ -617,6 +686,8 @@ my *softlist $d = $v; @endcode + @since %Qore 0.8.3 introduced the *softlist type + <hr> @section any_type any Modified: qore/trunk/doxygen/lang/180_operators.dox.tmpl =================================================================== --- qore/trunk/doxygen/lang/180_operators.dox.tmpl 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/doxygen/lang/180_operators.dox.tmpl 2012-09-15 20:55:56 UTC (rev 5043) @@ -729,16 +729,17 @@ \a expression1 <tt>*</tt> \a expression2 @par Return Type - @ref int_type "int" or @ref float_type "float" + @ref int_type "int", @ref float_type "float", or @ref number_type "number" @par Example @code $value = $x * $y;@endcode <b>Arguments Processed by * (in order of precedence)</b> |!Argument|!Processing - |@ref float_type "float"|Gives the result of multiplying its arguments; if either of the arguments is a @ref float "float" then the result is also a @ref float "float" + |@ref number_type "number"|Gives the result of multiplying its arguments; @ref integer "ints" and @ref float "floats" are converted to @ref number "numbers" if at least one of the arguments is a @ref number "number" + |@ref float_type "float"|Gives the result of multiplying its arguments; @ref integer "ints" are converted to @ref float "floats" if at least one of the arguments is a @ref float "float" |@ref int_type "int"|Gives the result of multiplying its arguments - |any other type|Converts argument to a float and performs the multiplication + |any other type|Converts argument to a @ref number "number" and performs the multiplication This operator does not throw any exceptions. @@ -752,16 +753,17 @@ \a expression1 <tt>/</tt> \a expression2 @par Return Type - @ref int_type "int" or @ref float_type "float" + @ref int_type "int", @ref float_type "float", or @ref number_type "number" @par Example @code $value = $x / $y;@endcode <b>Arguments Processed by / (in order of precedence)</b> |!Argument|!Processing - |@ref float_type "float"|Gives the result of dividing its arguments; if either of the arguments is a @ref float "float" then the result is also a @ref float "float" + |@ref number_type "number"|Gives the result of dividing its arguments; @ref integer "ints" and @ref float "floats" are converted to @ref number "numbers" if at least one of the arguments is a @ref number "number" + |@ref float_type "float"|Gives the result of dividing its arguments; @ref integer "ints" are converted to @ref float "floats" if at least one of the arguments is a @ref float "float" |@ref int_type "int"|Gives the result of dividing its arguments - |any other type|Converts argument to a float and performs the division + |any other type|Converts argument to a @ref number "number" and performs the division @throw DIVISION-BY-ZERO division by zero error @@ -796,7 +798,7 @@ \a expression1 <tt>+</tt> \a expression2 @par Return Type - @ref int_type "int", @ref float_type "float", @ref date_type "date", @ref list_type "list", @ref string_type "string", @ref binary_type "binary", or @ref hash_type "hash" + @ref int_type "int", @ref float_type "float", @ref number_type "number", @ref date_type "date", @ref list_type "list", @ref string_type "string", @ref binary_type "binary", or @ref hash_type "hash" @par Example @code $a = 1 + 2;@endcode @@ -810,6 +812,7 @@ |@ref list_type list|Gives the result of concatenating its arguments, i.e. <tt>(1, 2) + (3, 4) = (1, 2, 3, 4)</tt> |@ref string_type "string"|Gives the result of concatenating its arguments |@ref date_type "date"|Gives the result of adding date/time values (see @ref date_time_arithmetic) + |@ref number_type "number"|Gives the result of adding its arguments |@ref float_type "float"|Gives the result of adding its arguments |@ref int_type "int"|Gives the result of adding its arguments |@ref hash_type "hash"|Gives the result of concatenating/merging its arguments. Any common keys will be overwritten by the values in the second hash (\a expression2) @@ -820,15 +823,15 @@ @section minus_operator Minus Operator (-) @par Synopsis - With float or integer arguments, subtracts one number from another.\n\n - With date arguments, subtracts one date from another; if both date arguments are absolute dates, the result is a relative date (duration) giving the time between them; if the first date argument is an absolute date and the second is a relative date (duration), then the result is an absolute date. If both date arguments are relative dates, then the result is a relative date. If the first argument is a relative date and the second date is an absolute date, the result is an absolute date as if the operands were reversed.\n\n - However, if the left-hand side is a hash, and the right-hand side is a string, then the hash key represented by the string will be removed from the hash. If the left-hand side is a hash and the right-hand side is a list, then each element in the list will be converted to a string and any hash key with that name will be deleted from the hash. + With @ref float "float", @ref integer "integer", or @ref number "number" arguments, subtracts one number from another.\n\n + With @ref date "date" arguments, subtracts one date from another; if both date arguments are absolute dates, the result is a relative date (duration) giving the time between them; if the first date argument is an absolute date and the second is a relative date (duration), then the result is an absolute date. If both date arguments are relative dates, then the result is a relative date. If the first argument is a relative date and the second date is an absolute date, the result is an absolute date as if the operands were reversed.\n\n + However, if the left-hand side is a @ref hash "hash", and the right-hand side is a string, then the hash key represented by the string will be removed from the hash. If the left-hand side is a hash and the right-hand side is a list, then each element in the list will be converted to a string and any hash key with that name will be deleted from the hash. @par Syntax \a expression1 <tt>-</tt> \a expression2 @par Return Type - @ref int_type "int", @ref float_type "float", @ref date_type "date", or @ref hash_type "hash" + @ref int_type "int", @ref float_type "float", @ref number_type "number", @ref date_type "date", or @ref hash_type "hash" @par Example @code $num = $x - $y;@endcode @@ -839,6 +842,7 @@ <b>Arguments Processed by - (in order of precedence)</b> |!Argument|!Processing |@ref date_type "date"|date subtraction: \a expression1 - \a expression2 + |@ref number_type "number"|arithmetic subtraction: \a expression1 - \a expression2 |@ref float_type "float"|arithmetic subtraction: \a expression1 - \a expression2 |@ref int_type "int"|arithmetic subtraction: \a expression1 - \a expression2 |@ref hash_type "hash" - @ref string_type "string"|hash key deletion: \a expression1 - \a expression2 @@ -956,6 +960,7 @@ <b>Arguments Processed by < (in order of precedence)</b> |!Argument|!Processing + |@ref number_type "number"|If \a expression1 is numerically less than \a expression2, returns @ref Qore::True "True", otherwise returns @ref Qore::False "False" |@ref float_type "float"|If \a expression1 is numerically less than \a expression2, returns @ref Qore::True "True", otherwise returns @ref Qore::False "False" |@ref int_type "int"|If \a expression1 is numerically less than \a expression2, returns @ref Qore::True "True", otherwise returns @ref Qore::False "False" |@ref string_type "string"|If \a expression1 comes before \a expression2 in string sort order, returns @ref Qore::True "True", otherwise returns @ref Qore::False "False" @@ -983,6 +988,7 @@ <b>Arguments Processed by > (in order of precedence)</b> |!Argument|!Processing + |@ref number_type "number"|If \a expression1 is numerically greater than \a expression2, returns @ref Qore::True "True", otherwise returns @ref Qore::False "False" |@ref float_type "float"|If \a expression1 is numerically greater than \a expression2, returns @ref Qore::True "True", otherwise returns @ref Qore::False "False" |@ref int_type "int"|If \a expression1 is numerically greater than \a expression2, returns @ref Qore::True "True", otherwise returns @ref Qore::False "False" |@ref string_type "string"|If \a expression1 comes after \a expression2 in string sort order, returns @ref Qore::True "True", otherwise returns @ref Qore::False "False" @@ -1011,6 +1017,7 @@ <b>Arguments Processed by == (in order of precedence)</b> |!Argument|!Processing |@ref string_type "string"|If \a expression1 is equal to \a expression2, returns @ref Qore::True "True", otherwise @ref Qore::False "False" + |@ref number_type "number"|If \a expression1 is equal to \a expression2, returns @ref Qore::True "True", otherwise @ref Qore::False "False" |@ref float_type "float"|If \a expression1 is equal to \a expression2, returns @ref Qore::True "True", otherwise @ref Qore::False "False" |@ref int_type "int"|If \a expression1 is equal to \a expression2, returns @ref Qore::True "True", otherwise @ref Qore::False "False" |@ref date_type "date"|If \a expression1 is equal to \a expression2, returns @ref Qore::True "True", otherwise @ref Qore::False "False" @@ -1044,6 +1051,7 @@ <b>Arguments Processed by != (in order of precedence)</b> |!Argument|!Processing |@ref string_type "string"|If \a expression1 is not equal to \a expression2, returns @ref Qore::True "True", otherwise @ref Qore::False "False" + |@ref number_type "number"|If \a expression1 is not equal to \a expression2, returns @ref Qore::True "True", otherwise @ref Qore::False "False" |@ref float_type "float"|If \a expression1 is not equal to \a expression2, returns @ref Qore::True "True", otherwise @ref Qore::False "False" |@ref int_type "int"|If \a expression1 is not equal to \a expression2, returns @ref Qore::True "True", otherwise @ref Qore::False "False" |@ref date_type "date"|If \a expression1 is not equal to \a expression2, returns @ref Qore::True "True", otherwise @ref Qore::False "False" @@ -1076,6 +1084,7 @@ <b>Arguments Processed by <= (in order of precedence)</b> |!Argument|!Processing + |@ref number_type "number"|If \a expression1 is numerically less than or equal to \a expression2, returns @ref Qore::True "True", otherwise returns @ref Qore::False "False" |@ref float_type "float"|If \a expression1 is numerically less than or equal to \a expression2, returns @ref Qore::True "True", otherwise returns @ref Qore::False "False" |@ref int_type "int"|If \a expression1 is numerically less than or equal to \a expression2, returns @ref Qore::True "True", otherwise returns @ref Qore::False "False" |@ref string_type "string"|If \a expression1 comes before in string sort order or is the same as \a expression2, returns @ref Qore::True "True", otherwise returns @ref Qore::False "False" @@ -1103,6 +1112,7 @@ <b>Arguments Processed by >= (in order of precedence)</b> |!Argument|!Processing + |@ref number_type "number"|If \a expression1 is numerically greater than or equal to \a expression2, returns @ref Qore::True "True", otherwise returns @ref Qore::False "False" |@ref float_type "float"|If \a expression1 is numerically greater than or equal to \a expression2, returns @ref Qore::True "True", otherwise returns @ref Qore::False "False" |@ref int_type "int"|If \a expression1 is numerically greater than or equal to \a expression2, returns @ref Qore::True "True", otherwise returns @ref Qore::False "False" |@ref string_type "string"|If \a expression1 comes after in string sort order or is the same as \a expression2, returns @ref Qore::True "True", otherwise returns @ref Qore::False "False" @@ -1142,6 +1152,7 @@ <b>Arguments Processed by <=> (in order of precedence)</b> |!Argument|!Processing |@ref string_type "string"|If \a expression1 comes after in string sort order as \a expression2, returns \c 1, otherwise if they are equal, returns \c 0, otherwise if \a expression1 comes before \a expression2, returns \c -1 + |@ref number_type "number"|If \a expression1 is numerically greater than \a expression2, returns \c 1, otherwise if they are equal returns \c 0, otherwise returns \c -1 |@ref float_type "float"|If \a expression1 is numerically greater than \a expression2, returns \c 1, otherwise if they are equal returns \c 0, otherwise returns \c -1 |@ref int_type "int"|If \a expression1 is numerically greater than \a expression2, returns \c 1, otherwise if they are equal returns \c 0, otherwise returns \c -1 |@ref date_type "date"|If \a expression1 is after \a expression2, returns \c 1, otherwise if they are equal returns \c 0, otherwise returns \c -1 @@ -1588,7 +1599,7 @@ \a lvalue <tt>+=</tt> \a expression @par Return Type - @ref int_type "int", @ref float_type "float", @ref date_type "date", @ref list_type "list", @ref string_type "string", @ref binary_type "binary", @ref hash_type "hash", or @ref object_type "object" + @ref int_type "int", @ref float_type "float", @ref number_type "number", @ref date_type "date", @ref list_type "list", @ref string_type "string", @ref binary_type "binary", @ref hash_type "hash", or @ref object_type "object" @par Example @code $a += 10;@endcode @@ -1604,6 +1615,7 @@ |\a lvalue (@ref list_type "list")|the expression will be evaluated and concatenated to the lvalue. If \a expression is a list, the lists will be concatenated, to ensure adding a single element to a list, use the @ref push "push operator" |\a lvalue (@ref hash_type "hash" or (@ref object_type "object")|the \a expression will be evaluated, and, if it is a hash or object, then it's members will be added to the \a lvalue, any duplicate elements in the \a lvalue will be overridden by elements in the \a expression. |\a lvalue (@ref string_type "string")|the \a expression will be evaluated and converted to a string if necessary and concatenated to the \a lvalue. + |\a lvalue (@ref number_type "number")|the \a expression will be evaluated and converted to a number if necessary and added to the \a lvalue. |\a lvalue (@ref float_type "float")|the \a expression will be evaluated and converted to a float if necessary and added to the \a lvalue. |\a lvalue (@ref binary_type "binary")|the \a expression will be evaluated and converted to a binary if necessary and added to the \a lvalue. |\a lvalue (@ref date_type "date")|the \a expression will be evaluated and converted to a date if necessary and added to the \a lvalue. @@ -1620,7 +1632,7 @@ \a lvalue <tt>-=</tt> \a expression @par Return Type - @ref int_type "int", @ref float_type "float", @ref date_type "date", @ref hash_type "hash", or @ref object_type "object" + @ref int_type "int", @ref float_type "float", @ref number_type "number", @ref date_type "date", @ref hash_type "hash", or @ref object_type "object" @par Example @code $a -= 10;@endcode @@ -1632,6 +1644,7 @@ <b>Arguments Processed by -=</b> |!Argument|!Processing + |\a lvalue (@ref number_type "number")|the \a expression will be evaluated and converted to a number if necessary and subtracted from the \a lvalue |\a lvalue (@ref float_type "float")|the \a expression will be evaluated and converted to a float if necessary and subtracted from the \a lvalue |\a lvalue (@ref date_type "date")|the \a expression will be evaluated and converted to a date if necessary and subtracted from the \a lvalue |\a lvalue (@ref hash_type "hash" or (@ref object_type "object"), \a expression (@ref string_type "string")|the hash key represented by \a expression will be removed from the \a lvalue @@ -1706,14 +1719,14 @@ \a lvalue <tt>*=</tt> \a expression @par Return Type - @ref int_type "int" or @ref float_type "float" + @ref int_type "int", @ref float_type "float", or @ref number_type "number" @par Example @code $a *= 10;@endcode <b>Arguments Processed by *=</b> |!Argument|!Processing - |All|If either side of the operator is a float, the result will be a float as well. Otherwise the result is an integer value. The \a expression will be evaluated and multiplied by the \a lvalue, and the result will be saved to the \a lvalue. + |All|The type precedence from highest to lowest is @ref number "number", @ref float "float" float, and @ref integer "int", other types are converted to @ref integer "int". The \a expression will be evaluated and multiplied by the \a lvalue, and the result will be saved to the \a lvalue. <hr> @section divide_equals_operator Divide Equals Operator (/=) @@ -1725,14 +1738,14 @@ \a lvalue <tt>/=</tt> \a expression @par Return Type - @ref int_type "int" or @ref float_type "float" + @ref int_type "int", @ref float_type "float", or @ref number_type "number" @par Example @code $a /= 10;@endcode <b>Arguments Processed by /=</b> |!Argument|!Processing - |All|If either side of the operator is a float, the result will be a float as well. Otherwise the result is an integer value. The \a expression will be evaluated and used to divide the \a lvalue, and the result will be saved to the \a lvalue. + |All|The type precedence from highest to lowest is @ref number "number", @ref float "float" float, and @ref integer "int", other types are converted to @ref integer "int"; The \a expression will be evaluated and multiplied by the \a lvalue, and the result will be saved to the \a lvalue. The \a expression will be evaluated and used to divide the \a lvalue, and the result will be saved to the \a lvalue. @throw DIVISION-BY-ZERO If the divisor expression evaluates to zero, this exception is thrown Modified: qore/trunk/doxygen/lang/215_classes.dox.tmpl =================================================================== --- qore/trunk/doxygen/lang/215_classes.dox.tmpl 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/doxygen/lang/215_classes.dox.tmpl 2012-09-15 20:55:56 UTC (rev 5043) @@ -5,7 +5,7 @@ @section class_overview Class Overview Classes define types of %Qore @ref object "objects". Classes can define members and methods, which are attributes of the class and functions that operate only on the objects of that class, respectively. Furthermore access to class members and methods can be restricted with the <tt><b>private</b></tt> keyword, and classes can be @ref inheritance "subclassed" to support polymorphism. - @note Each %Qore type has a "pseudo-class" associated with it (the default is @ref Qore::zzz8valuezzz9); methods from the data type's "pseudo-class" can be run on any value of that type; see @ref value and <b>"Pseudo Class for Type"</b> headings in @ref basic_data_types for more information. + @note Each %Qore type has a "pseudo-class" associated with it (the default is @ref Qore::zzz8valuezzz9); methods from the data type's "pseudo-class" can be run on any value of that type; see @ref Qore::zzz8valuezzz9 "<value>" and <b>"Pseudo Class for Type"</b> headings in @ref basic_data_types for more information. @par In-Line Class Declaration Syntax <tt><b>[@ref mod_public "public"] [@ref final_classes "final"] class</b> [</tt><em>@ref namespace_paths "namespace_path"</em><tt>::...]</tt><em>class_identifier</em><tt>] [<b>inherits</b> [<b>@ref private_inheritance "private"</b>|<b>@ref public_inheritance "public"</b>] [</tt><em>@ref namespace_paths "namespace_path"</em><tt>::...]</tt><em>parent_class_identifier</em><tt>[, ...]] {</tt>\n Modified: qore/trunk/doxygen/lang/250_warnings.dox.tmpl =================================================================== --- qore/trunk/doxygen/lang/250_warnings.dox.tmpl 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/doxygen/lang/250_warnings.dox.tmpl 2012-09-15 20:55:56 UTC (rev 5043) @@ -30,6 +30,7 @@ - @ref undeclared-var - @ref unknown-warning - @ref unreachable-code + - @ref unreferenced-variable - @ref warning-mask-unchanged <hr> @@ -100,6 +101,11 @@ @since %Qore 0.5.2 <hr> + @section unreferenced-variable unreferenced-variable + Raised when a variable is declared by never referenced. + @since %Qore 0.8.2 + + <hr> @section warning-mask-unchanged warning-mask-unchanged This warning is raised when a program tries to change the warning mask with parse options, but the warnings are locked @since %Qore 0.5.2 Modified: qore/trunk/doxygen/lang/mainpage.dox.tmpl =================================================================== --- qore/trunk/doxygen/lang/mainpage.dox.tmpl 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/doxygen/lang/mainpage.dox.tmpl 2012-09-15 20:55:56 UTC (rev 5043) @@ -14,6 +14,7 @@ - @ref string - @ref integer - @ref float + - @ref number - @ref date - @ref binary - @ref null Modified: qore/trunk/include/qore/intern/QorePseudoMethods.h =================================================================== --- qore/trunk/include/qore/intern/QorePseudoMethods.h 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/include/qore/intern/QorePseudoMethods.h 2012-09-15 20:55:56 UTC (rev 5043) @@ -34,7 +34,7 @@ DLLLOCAL const QoreMethod *pseudo_classes_find_method(qore_type_t t, const char *mname, QoreClass *&qc); DLLLOCAL const QoreMethod *pseudo_classes_find_method(const QoreTypeInfo *typeInfo, const char *mname, QoreClass *&qc, bool &possible_match); -#define NODE_ARRAY_LEN (NT_OBJECT + 1) +#define NODE_ARRAY_LEN (NT_NUMBER + 1) DLLLOCAL extern QoreBigIntNode *Node_NT_Array[NODE_ARRAY_LEN]; #endif Modified: qore/trunk/include/qore/intern/qore_number_private.h =================================================================== --- qore/trunk/include/qore/intern/qore_number_private.h 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/include/qore/intern/qore_number_private.h 2012-09-15 20:55:56 UTC (rev 5043) @@ -259,6 +259,10 @@ return p; } + DLLLOCAL mpfr_prec_t getPrec() const { + return mpfr_get_prec(num); + } + DLLLOCAL void inc() { //MPFR_DECL_INIT(tmp, mpfr_get_prec(num)); qore_number_private tmp(mpfr_get_prec(num)); @@ -347,6 +351,10 @@ DLLLOCAL static QoreNumberNode* getInfinity() { return new QoreNumberNode(new qore_number_private("@Inf@")); } + + DLLLOCAL static qore_number_private* get(const QoreNumberNode& n) { + return n.priv; + } }; #endif Modified: qore/trunk/lib/Makefile.am =================================================================== --- qore/trunk/lib/Makefile.am 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/lib/Makefile.am 2012-09-15 20:55:56 UTC (rev 5043) @@ -165,6 +165,9 @@ Pseudo_QC_Float.cpp: Pseudo_QC_Float.qpp qpp $(QPP) $< +Pseudo_QC_Number.cpp: Pseudo_QC_Number.qpp qpp + $(QPP) $< + Pseudo_QC_Date.cpp: Pseudo_QC_Date.qpp qpp $(QPP) $< @@ -250,7 +253,7 @@ Pseudo_QC_Float.cpp Pseudo_QC_Date.cpp Pseudo_QC_Object.cpp \ Pseudo_QC_Hash.cpp Pseudo_QC_String.cpp Pseudo_QC_Binary.cpp \ Pseudo_QC_List.cpp Pseudo_QC_Closure.cpp Pseudo_QC_Callref.cpp \ - Pseudo_QC_Nothing.cpp + Pseudo_QC_Nothing.cpp Pseudo_QC_Number.cpp QorePseudoMethods.cpp: $(QORE_PSEUDO_SRC) Modified: qore/trunk/lib/Pseudo_QC_All.qpp =================================================================== --- qore/trunk/lib/Pseudo_QC_All.qpp 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/lib/Pseudo_QC_All.qpp 2012-09-15 20:55:56 UTC (rev 5043) @@ -26,7 +26,7 @@ //! Methods in this pseudo-class are available to be executed on any value type (even @ref nothing); this is the root class for all pseudo-classes /** */ -qclass <value> [arg=AbstractQoreNode* node]; +qclass <value> [arg=const AbstractQoreNode* node]; //! Returns the type code for the value /** This method is recommended over <value>::type() or the type(any) or typename(any) functions for comparing data types as it is much faster and more efficient than the other alternatives (which work with string values instead of integer codes). Modified: qore/trunk/lib/Pseudo_QC_Binary.qpp =================================================================== --- qore/trunk/lib/Pseudo_QC_Binary.qpp 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/lib/Pseudo_QC_Binary.qpp 2012-09-15 20:55:56 UTC (rev 5043) @@ -26,7 +26,7 @@ //! Methods in this pseudo-class can be executed on @ref binary "binary values" /** */ -qclass <binary> [arg=BinaryNode* b;vparent=<value>]; +qclass <binary> [arg=const BinaryNode* b;vparent=<value>]; //! Returns Qore::NT_BINARY /** Modified: qore/trunk/lib/Pseudo_QC_Bool.qpp =================================================================== --- qore/trunk/lib/Pseudo_QC_Bool.qpp 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/lib/Pseudo_QC_Bool.qpp 2012-09-15 20:55:56 UTC (rev 5043) @@ -26,7 +26,7 @@ //! Methods in this pseudo-class can be executed on @ref boolean "booling-point values" /** */ -qclass <bool> [arg=QoreBoolNode* b;vparent=<value>]; +qclass <bool> [arg=const QoreBoolNode* b;vparent=<value>]; //! Returns Qore::NT_BOOLEAN /** Modified: qore/trunk/lib/Pseudo_QC_Callref.qpp =================================================================== --- qore/trunk/lib/Pseudo_QC_Callref.qpp 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/lib/Pseudo_QC_Callref.qpp 2012-09-15 20:55:56 UTC (rev 5043) @@ -26,7 +26,7 @@ //! Methods in this pseudo-class can be executed on @ref call_reference "call references" /** */ -qclass <callref> [arg=ResolvedCallReferenceNode* c;vparent=<value>]; +qclass <callref> [arg=const ResolvedCallReferenceNode* c;vparent=<value>]; //! Returns Qore::NT_CALLREF /** Modified: qore/trunk/lib/Pseudo_QC_Closure.qpp =================================================================== --- qore/trunk/lib/Pseudo_QC_Closure.qpp 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/lib/Pseudo_QC_Closure.qpp 2012-09-15 20:55:56 UTC (rev 5043) @@ -26,7 +26,7 @@ //! Methods in this pseudo-class can be executed on @ref closure "closures" /** */ -qclass <closure> [arg=QoreClosureNode* c;vparent=<callref>]; +qclass <closure> [arg=const QoreClosureNode* c;vparent=<callref>]; //! Returns Qore::NT_CLOSURE /** Modified: qore/trunk/lib/Pseudo_QC_Date.qpp =================================================================== --- qore/trunk/lib/Pseudo_QC_Date.qpp 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/lib/Pseudo_QC_Date.qpp 2012-09-15 20:55:56 UTC (rev 5043) @@ -27,7 +27,7 @@ //! Methods in this pseudo-class can be executed on @ref date "date/time value types" /** */ -qclass <date> [arg=DateTimeNode *dt;vparent=<value>]; +qclass <date> [arg=const DateTimeNode *dt;vparent=<value>]; //! Returns Qore::NT_DATE /** Modified: qore/trunk/lib/Pseudo_QC_Float.qpp =================================================================== --- qore/trunk/lib/Pseudo_QC_Float.qpp 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/lib/Pseudo_QC_Float.qpp 2012-09-15 20:55:56 UTC (rev 5043) @@ -26,7 +26,7 @@ //! Methods in this pseudo-class can be executed on @ref float "floating-point values" /** */ -qclass <float> [arg=QoreFloatNode* f;vparent=<value>]; +qclass <float> [arg=const QoreFloatNode* f;vparent=<value>]; //! Returns Qore::NT_FLOAT /** @@ -41,7 +41,7 @@ } @endcode */ -float <float>::typeCode() [flags=CONSTANT] { +int <float>::typeCode() [flags=CONSTANT] { return NT_FLOAT; } Modified: qore/trunk/lib/Pseudo_QC_Hash.qpp =================================================================== --- qore/trunk/lib/Pseudo_QC_Hash.qpp 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/lib/Pseudo_QC_Hash.qpp 2012-09-15 20:55:56 UTC (rev 5043) @@ -28,7 +28,7 @@ //! Methods in this pseudo-class can be executed on @ref hash "hash values" /** */ -qclass <hash> [arg=QoreHashNode* h;vparent=<value>]; +qclass <hash> [arg=const QoreHashNode* h;vparent=<value>]; //! Returns Qore::NT_HASH /** Modified: qore/trunk/lib/Pseudo_QC_Int.qpp =================================================================== --- qore/trunk/lib/Pseudo_QC_Int.qpp 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/lib/Pseudo_QC_Int.qpp 2012-09-15 20:55:56 UTC (rev 5043) @@ -26,7 +26,7 @@ //! Methods in this pseudo-class can be executed on @ref integer "integer values" /** */ -qclass <int> [arg=QoreBigIntNode* i;vparent=<value>]; +qclass <int> [arg=const QoreBigIntNode* i;vparent=<value>]; //! Returns Qore::NT_INT /** Modified: qore/trunk/lib/Pseudo_QC_List.qpp =================================================================== --- qore/trunk/lib/Pseudo_QC_List.qpp 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/lib/Pseudo_QC_List.qpp 2012-09-15 20:55:56 UTC (rev 5043) @@ -27,7 +27,7 @@ //! Methods in this pseudo-class can be executed on @ref list "lists" /** */ -qclass <list> [arg=QoreListNode* l;vparent=<value>]; +qclass <list> [arg=const QoreListNode* l;vparent=<value>]; //! Returns Qore::NT_LIST /** @@ -161,7 +161,7 @@ //! Returns @ref True if the list contains arg, @ref False if it does not. /** - @param arg @ref any value to check its presence in the list + @param arg any value to check its presence in the list @return @ref True if the list contains arg, @ref False if it does not Modified: qore/trunk/lib/Pseudo_QC_Nothing.qpp =================================================================== --- qore/trunk/lib/Pseudo_QC_Nothing.qpp 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/lib/Pseudo_QC_Nothing.qpp 2012-09-15 20:55:56 UTC (rev 5043) @@ -26,7 +26,7 @@ //! Methods in this pseudo-class can be executed on @ref nothing /** */ -qclass <nothing> [arg=AbstractQoreNode* n;vparent=<value>]; +qclass <nothing> [arg=const AbstractQoreNode* n;vparent=<value>]; //! Returns Qore::NT_NOTHING /** Added: qore/trunk/lib/Pseudo_QC_Number.qpp =================================================================== --- qore/trunk/lib/Pseudo_QC_Number.qpp (rev 0) +++ qore/trunk/lib/Pseudo_QC_Number.qpp 2012-09-15 20:55:56 UTC (rev 5043) @@ -0,0 +1,140 @@ +/* -*- mode: c++; indent-tabs-mode: nil -*- */ +/* + Pseudo_QC_Number.qpp + + Qore Programming Language + + Copyright 2003 - 2012 David Nichols + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include <qore/Qore.h> +#include <qore/intern/qore_number_private.h> + +//! Methods in this pseudo-class can be executed on @ref number "arbitrary precision number values" +/** + */ +qclass <number> [arg=const QoreNumberNode* n;vparent=<value>]; + +//! Returns Qore::NT_NUMBER +/** + @return Qore::NT_NUMBER + + @par Example: + @code +switch ($f.typeCode()) { + case NT_NUMBER: + printf("%y: is a number\n", $f); + break; +} + @endcode +*/ +int <number>::typeCode() [flags=CONSTANT] { + return NT_NUMBER; +} + +//! Returns @ref True if the number is non-zero, @ref False if zero +/** + @return @ref True if the number is non-zero, @ref False if zero + + @par Example: + @code +my bool $b = $f.val(); + @endcode +*/ +bool <number>::val() [flags=CONSTANT] { + return !n->zero(); +} + +//! Returns @ref True because number values can be converted to integers +/** + @return @ref True because number values can be converted to integers + + @par Example: + @code +if ($n.intp()) + printf("%y: can be converted to an integer: %d\n", $n, int($n)); + @endcode +*/ +bool <number>::intp() [flags=CONSTANT] { + return true; +} + +//! Returns @ref True because number values can be converted to strings +/** + @return @ref True because number values can be converted to strings + + @par Example: + @code +if ($n.strp()) + printf("%y: can be converted to a string: '%s'\n", $n, string($n)); + @endcode +*/ +bool <number>::strp() [flags=CONSTANT] { + return true; +} + +//! Returns @ref True if the number is NaN (not a number) +/** + @return @ref True if the number is NaN (not a number) + + @par Example: + @code +if ($n.nan()) + print("the operation resulted in NaN\n"); + @endcode +*/ +bool <number>::nan() [flags=CONSTANT] { + return qore_number_private::get(*n)->nan(); +} + +//! Returns @ref True if the number is infinity (+ or -) +/** + @return @ref True if the number is infinity (+ or -) + + @par Example: + @code +if ($n.inf()) + print("the operation resulted in infinity\n"); + @endcode +*/ +bool <number>::inf() [flags=CONSTANT] { + return qore_number_private::get(*n)->inf(); +} + +//! Returns -1 if the number is negative, 0 if it is zero, or 1 if it is positive +/** @return -1 if the number is negative, 0 if it is zero, or 1 if it is positive + + @par Example: + @code +printf("sign: %d\n", $n.sign()); + @endcode +*/ +int <number>::sign() [flags=CONSTANT] { + return qore_number_private::get(*n)->sign(); +} + +//! Returns the precision of the current number +/** @return the precision of the current number + + @par Example: + @code +printf("precision: %d\n", $n.prec()); + @endcode +*/ +int <number>::prec() [flags=CONSTANT] { + return (int64)qore_number_private::get(*n)->getPrec(); +} Modified: qore/trunk/lib/Pseudo_QC_String.qpp =================================================================== --- qore/trunk/lib/Pseudo_QC_String.qpp 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/lib/Pseudo_QC_String.qpp 2012-09-15 20:55:56 UTC (rev 5043) @@ -29,7 +29,7 @@ //! Methods in this pseudo-class can be executed on @ref string "strings" /** */ -qclass <string> [arg=QoreStringNode* str;vparent=<value>]; +qclass <string> [arg=const QoreStringNode* str;vparent=<value>]; //! Returns Qore::NT_STRING /** Modified: qore/trunk/lib/QorePseudoMethods.cpp =================================================================== --- qore/trunk/lib/QorePseudoMethods.cpp 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/lib/QorePseudoMethods.cpp 2012-09-15 20:55:56 UTC (rev 5043) @@ -29,6 +29,7 @@ #include "Pseudo_QC_Bool.cpp" #include "Pseudo_QC_Int.cpp" #include "Pseudo_QC_Float.cpp" +#include "Pseudo_QC_Number.cpp" #include "Pseudo_QC_String.cpp" #include "Pseudo_QC_List.cpp" #include "Pseudo_QC_Hash.cpp" @@ -74,6 +75,7 @@ po_list[NT_LIST] = initPseudoListClass(); po_list[NT_HASH] = initPseudoHashClass(); po_list[NT_OBJECT] = initPseudoObjectClass(); + po_list[NT_NUMBER] = initPseudoNumberClass(); // + 2 pseudo classes with runtime type values outside the value type range po_list[NODE_ARRAY_LEN] = initPseudoCallrefClass(); Modified: qore/trunk/lib/qc_qore.qpp =================================================================== --- qore/trunk/lib/qc_qore.qpp 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/lib/qc_qore.qpp 2012-09-15 20:55:56 UTC (rev 5043) @@ -43,6 +43,9 @@ //! type code for @ref float "float values" const NT_FLOAT = NT_FLOAT; +//! type code for @ref number "number values" +const NT_NUMBER = NT_NUMBER; + //! type code for @ref string "string values" const NT_STRING = NT_STRING; @@ -92,6 +95,7 @@ "8": "list", "9": "hash", "10": "object", + "11": "number", "29": "call reference", "32": "closure", ); @@ -101,6 +105,7 @@ "nothing": NT_NOTHING, "integer": NT_INT, "float": NT_FLOAT, + "number": NT_NUMBER, "string": NT_STRING, "date": NT_DATE, "bool": NT_BOOLEAN, Modified: qore/trunk/lib/ql_math.qpp =================================================================== --- qore/trunk/lib/ql_math.qpp 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/lib/ql_math.qpp 2012-09-15 20:55:56 UTC (rev 5043) @@ -235,7 +235,7 @@ //! Returns the absolute value of the argument passed /** - @param i the value to process + @param n the value to process @return the absolute value of the argument passed Modified: qore/trunk/lib/ql_type.qpp =================================================================== --- qore/trunk/lib/ql_type.qpp 2012-09-13 18:56:50 UTC (rev 5042) +++ qore/trunk/lib/ql_type.qpp 2012-09-15 20:55:56 UTC (rev 5043) @@ -42,6 +42,9 @@ //! Gives the type for @ref float "float" values const Float = "float"; +//! Gives the type for @ref number "number" values +const Number = "number"; + //! Gives the type for @ref string "string" values const String = "string"; @@ -173,6 +176,30 @@ return 0.0; } +//! Converts the argument to a @ref number "number" value +/** + @param n the argument to convert to a @ref number "number" + + @return the @ref number "number" value corresponding to the argument + + @par Example: + @code +my number $n = number("2.23040945718005e35"); + @endcode +*/ +number number(softnumber n) [flags=CONSTANT] { + return n->refSelf(); +} + +//! Always returns 0.0 +/** The number() function is used for type conversions, therefore this variant is not tagged with @ref NOOP + + @see number(softnumber) +*/ +number number() [flags=CONSTANT] { + return ZeroNumber->refSelf(); +} + //! Converts the argument to a string /** @param str the argument to convert to a string This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <david_nichols@us...> - 2012-09-13 18:56:56
|
Revision: 5042 http://qore.svn.sourceforge.net/qore/?rev=5042&view=rev Author: david_nichols Date: 2012-09-13 18:56:50 +0000 (Thu, 13 Sep 2012) Log Message: ----------- fix for last patch Modified Paths: -------------- qore/trunk/lib/Operator.cpp Modified: qore/trunk/lib/Operator.cpp =================================================================== --- qore/trunk/lib/Operator.cpp 2012-09-13 18:54:46 UTC (rev 5041) +++ qore/trunk/lib/Operator.cpp 2012-09-13 18:56:50 UTC (rev 5042) @@ -32,7 +32,6 @@ DLLLOCAL OperatorList oplist; -DLLLOCAL extern const QoreTypeInfo* bigIntOrFloatTypeInfo; DLLLOCAL extern const QoreTypeInfo* bigIntFloatOrNumberTypeInfo, * floatOrNumberTypeInfo; // the standard, system-default operator pointers This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <david_nichols@us...> - 2012-09-13 18:54:53
|
Revision: 5041 http://qore.svn.sourceforge.net/qore/?rev=5041&view=rev Author: david_nichols Date: 2012-09-13 18:54:46 +0000 (Thu, 13 Sep 2012) Log Message: ----------- fixed warning Modified Paths: -------------- qore/trunk/lib/Operator.cpp Modified: qore/trunk/lib/Operator.cpp =================================================================== --- qore/trunk/lib/Operator.cpp 2012-09-13 12:57:07 UTC (rev 5040) +++ qore/trunk/lib/Operator.cpp 2012-09-13 18:54:46 UTC (rev 5041) @@ -32,7 +32,8 @@ DLLLOCAL OperatorList oplist; -DLLLOCAL extern const QoreTypeInfo* bigIntOrFloatTypeInfo, * bigIntFloatOrNumberTypeInfo, * floatOrNumberTypeInfo; +DLLLOCAL extern const QoreTypeInfo* bigIntOrFloatTypeInfo; +DLLLOCAL extern const QoreTypeInfo* bigIntFloatOrNumberTypeInfo, * floatOrNumberTypeInfo; // the standard, system-default operator pointers Operator *OP_MODULA, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <david_nichols@us...> - 2012-09-13 12:57:18
|
Revision: 5040 http://qore.svn.sourceforge.net/qore/?rev=5040&view=rev Author: david_nichols Date: 2012-09-13 12:57:07 +0000 (Thu, 13 Sep 2012) Log Message: ----------- fixed typo in last patch Modified Paths: -------------- qore/trunk/include/qore/intern/qore_number_private.h Modified: qore/trunk/include/qore/intern/qore_number_private.h =================================================================== --- qore/trunk/include/qore/intern/qore_number_private.h 2012-09-13 12:53:51 UTC (rev 5039) +++ qore/trunk/include/qore/intern/qore_number_private.h 2012-09-13 12:57:07 UTC (rev 5040) @@ -262,7 +262,7 @@ DLLLOCAL void inc() { //MPFR_DECL_INIT(tmp, mpfr_get_prec(num)); qore_number_private tmp(mpfr_get_prec(num)); - mpfr_set(tmp,num, num, QORE_MPFR_RND); + mpfr_set(tmp.num, num, QORE_MPFR_RND); mpfr_add_si(num, tmp.num, 1, QORE_MPFR_RND); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <david_nichols@us...> - 2012-09-13 12:54:02
|
Revision: 5039 http://qore.svn.sourceforge.net/qore/?rev=5039&view=rev Author: david_nichols Date: 2012-09-13 12:53:51 +0000 (Thu, 13 Sep 2012) Log Message: ----------- fix for compiling with older mpfr on solaris Modified Paths: -------------- qore/trunk/include/qore/intern/qore_number_private.h Modified: qore/trunk/include/qore/intern/qore_number_private.h =================================================================== --- qore/trunk/include/qore/intern/qore_number_private.h 2012-09-13 12:27:26 UTC (rev 5038) +++ qore/trunk/include/qore/intern/qore_number_private.h 2012-09-13 12:53:51 UTC (rev 5039) @@ -260,22 +260,25 @@ } DLLLOCAL void inc() { - MPFR_DECL_INIT(tmp, mpfr_get_prec(num)); - mpfr_set(tmp, num, QORE_MPFR_RND); - mpfr_add_si(num, tmp, 1, QORE_MPFR_RND); + //MPFR_DECL_INIT(tmp, mpfr_get_prec(num)); + qore_number_private tmp(mpfr_get_prec(num)); + mpfr_set(tmp,num, num, QORE_MPFR_RND); + mpfr_add_si(num, tmp.num, 1, QORE_MPFR_RND); } DLLLOCAL void dec() { - MPFR_DECL_INIT(tmp, mpfr_get_prec(num)); - mpfr_set(tmp, num, QORE_MPFR_RND); - mpfr_sub_si(num, tmp, 1, QORE_MPFR_RND); + //MPFR_DECL_INIT(tmp, mpfr_get_prec(num)); + qore_number_private tmp(mpfr_get_prec(num)); + mpfr_set(tmp.num, num, QORE_MPFR_RND); + mpfr_sub_si(num, tmp.num, 1, QORE_MPFR_RND); } DLLLOCAL void doBinaryInplace(q_mpfr_binary_func_t func, const qore_number_private& r, ExceptionSink* xsink = 0) { checkPrec(r.num); - MPFR_DECL_INIT(tmp, mpfr_get_prec(num)); - mpfr_set(tmp, num, QORE_MPFR_RND); - func(num, tmp, r.num, QORE_MPFR_RND); + //MPFR_DECL_INIT(tmp, mpfr_get_prec(num)); + qore_number_private tmp(mpfr_get_prec(num)); + mpfr_set(tmp.num, num, QORE_MPFR_RND); + func(num, tmp.num, r.num, QORE_MPFR_RND); if (xsink) checkFlags(xsink); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <david_nichols@us...> - 2012-09-13 12:27:37
|
Revision: 5038 http://qore.svn.sourceforge.net/qore/?rev=5038&view=rev Author: david_nichols Date: 2012-09-13 12:27:26 +0000 (Thu, 13 Sep 2012) Log Message: ----------- added new header Modified Paths: -------------- qore/trunk/Makefile.am Modified: qore/trunk/Makefile.am =================================================================== --- qore/trunk/Makefile.am 2012-09-13 12:19:10 UTC (rev 5037) +++ qore/trunk/Makefile.am 2012-09-13 12:27:26 UTC (rev 5038) @@ -122,6 +122,7 @@ include/qore/QoreBigIntNode.h \ include/qore/QoreBoolNode.h \ include/qore/QoreFloatNode.h \ + include/qore/QoreNumberNode.h \ include/qore/QoreNothingNode.h \ include/qore/QoreNullNode.h \ include/qore/params.h \ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <david_nichols@us...> - 2012-09-13 12:19:20
|
Revision: 5037 http://qore.svn.sourceforge.net/qore/?rev=5037&view=rev Author: david_nichols Date: 2012-09-13 12:19:10 +0000 (Thu, 13 Sep 2012) Log Message: ----------- do not output the suffix 'n' when converting a number to a string Modified Paths: -------------- qore/trunk/include/qore/intern/qore_number_private.h Modified: qore/trunk/include/qore/intern/qore_number_private.h =================================================================== --- qore/trunk/include/qore/intern/qore_number_private.h 2012-09-13 10:21:46 UTC (rev 5036) +++ qore/trunk/include/qore/intern/qore_number_private.h 2012-09-13 12:19:10 UTC (rev 5037) @@ -133,7 +133,7 @@ DLLLOCAL void getAsString(QoreString& str) const { // first check for zero if (zero()) { - str.concat("0n"); + str.concat("0"); return; } @@ -143,7 +143,7 @@ int len = mpfr_sprintf((char*)(str.getBuffer() + str.size()), "%Re", num); if (len > 0) { str.terminate(str.size() + len); - str.concat('n'); + //str.concat('n'); } else str.concat("<error>"); @@ -178,12 +178,12 @@ // assert that we have added at least 1 character assert(rlen > 0); - if (exp > rlen) + if ((qore_size_t)exp > rlen) str.insertch('0', str.size(), exp - rlen); - else if (exp < rlen) + else if ((qore_size_t)exp < rlen) str.insertch('.', len + exp, 1); } - str.concat('n'); + //str.concat('n'); } else str.concat(buf); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <david_nichols@us...> - 2012-09-13 10:21:53
|
Revision: 5036 http://qore.svn.sourceforge.net/qore/?rev=5036&view=rev Author: david_nichols Date: 2012-09-13 10:21:46 +0000 (Thu, 13 Sep 2012) Log Message: ----------- * fixed a major race condition accessing global variable and closure-bound local variable values that could cause crashes * added --with-gmp-dir and --with-mpfr-dir configure options Modified Paths: -------------- qore/trunk/configure.ac qore/trunk/include/qore/intern/LocalVar.h qore/trunk/include/qore/intern/QoreValue.h qore/trunk/lib/Variable.cpp Modified: qore/trunk/configure.ac =================================================================== --- qore/trunk/configure.ac 2012-09-12 20:46:33 UTC (rev 5035) +++ qore/trunk/configure.ac 2012-09-13 10:21:46 UTC (rev 5036) @@ -681,6 +681,13 @@ AC_MSG_RESULT([includes $with_zlib_includes libs $with_zlib_libs (shared)]) fi +# see if we can figure out where the mpfr library is +AC_ARG_WITH([mpfr-dir], + [AS_HELP_STRING([--with-mpfr-dir@<:@=DIR@:>@], + [MPFR directory])], + [if test ! -d "${with_mpfr_dir}"; then AC_MSG_ERROR([bad value ${with_mpfr_dir} for --with-mpfr-dir]); unset with_mpfr_dir; fi], + [with_mpfr_dir="$MPFR_DIR"]) + AC_MSG_CHECKING([for mpfr libraries and header files]) for dir in "${with_mpfr_dir}" "${with_lib_prefix}" "${find_prefix}" /usr / /usr/local /opt/gnu /opt/mpfr /usr/local/mpfr /opt/local /sw /usr/sfw /opt/sfw; do find_mpfr $dir @@ -697,6 +704,13 @@ AC_MSG_RESULT([includes $with_mpfr_includes libs $with_mpfr_libs (shared)]) fi +# see if we can figure out where the gmp library is +AC_ARG_WITH([gmp-dir], + [AS_HELP_STRING([--with-gmp-dir@<:@=DIR@:>@], + [GMP directory])], + [if test ! -d "${with_gmp_dir}"; then AC_MSG_ERROR([bad value ${with_gmp_dir} for --with-gmp-dir]); unset with_gmp_dir; fi], + [with_gmp_dir="$GMP_DIR"]) + AC_MSG_CHECKING([for gmp libraries and header files]) for dir in "${with_gmp_dir}" "${with_lib_prefix}" "${find_prefix}" /usr / /usr/local /opt/gnu /opt/gmp /usr/local/gmp /opt/local /sw /usr/sfw /opt/sfw; do find_gmp $dir Modified: qore/trunk/include/qore/intern/LocalVar.h =================================================================== --- qore/trunk/include/qore/intern/LocalVar.h 2012-09-12 20:46:33 UTC (rev 5035) +++ qore/trunk/include/qore/intern/LocalVar.h 2012-09-13 10:21:46 UTC (rev 5036) @@ -291,7 +291,7 @@ return helper ? lvalue_ref::get(*ref)->vexp->eval(needs_deref, xsink) : 0; } - return val.eval(needs_deref); + return val.eval(needs_deref, true); } DLLLOCAL int64 bigIntEval(ExceptionSink* xsink) { Modified: qore/trunk/include/qore/intern/QoreValue.h =================================================================== --- qore/trunk/include/qore/intern/QoreValue.h 2012-09-12 20:46:33 UTC (rev 5035) +++ qore/trunk/include/qore/intern/QoreValue.h 2012-09-13 10:21:46 UTC (rev 5036) @@ -513,15 +513,19 @@ return 0; } - DLLLOCAL AbstractQoreNode* eval(bool &needs_deref) const { + DLLLOCAL AbstractQoreNode* eval(bool &needs_deref, bool in_lock = false) const { if (!assigned) { needs_deref = false; return 0; } if (type == QV_Node) { - needs_deref = false; - return v.n; + if (!in_lock || !v.n) { + needs_deref = false; + return v.n; + } + needs_deref = true; + return v.n->refSelf(); } needs_deref = true; Modified: qore/trunk/lib/Variable.cpp =================================================================== --- qore/trunk/lib/Variable.cpp 2012-09-12 20:46:33 UTC (rev 5035) +++ qore/trunk/lib/Variable.cpp 2012-09-13 10:21:46 UTC (rev 5036) @@ -105,7 +105,7 @@ AutoLocker al(m); - return val.eval(needs_deref); + return val.eval(needs_deref, true); } int64 Var::bigIntEval() const { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <david_nichols@us...> - 2012-09-12 20:46:45
|
Revision: 5035 http://qore.svn.sourceforge.net/qore/?rev=5035&view=rev Author: david_nichols Date: 2012-09-12 20:46:33 +0000 (Wed, 12 Sep 2012) Log Message: ----------- * added parser support for @nan@, @inf@ values for floating-point numbers and @nan@... and @inf@... for arbitrary-precision numbers * added variants to almost all math functions taking arbitrary-precision number arguments * added qpp support for number types Modified Paths: -------------- qore/trunk/include/qore/QoreType.h qore/trunk/include/qore/intern/qore_number_private.h qore/trunk/include/qore/params.h qore/trunk/lib/QC_AbstractQuantifiedBidirectionalIterator.qpp qore/trunk/lib/QoreTypeInfo.cpp qore/trunk/lib/ql_math.qpp qore/trunk/lib/qpp.cpp qore/trunk/lib/scanner.lpp Modified: qore/trunk/include/qore/QoreType.h =================================================================== --- qore/trunk/include/qore/QoreType.h 2012-09-12 11:54:25 UTC (rev 5034) +++ qore/trunk/include/qore/QoreType.h 2012-09-12 20:46:33 UTC (rev 5035) @@ -31,18 +31,19 @@ #include <map> // global default values -DLLEXPORT extern QoreListNode *emptyList; -DLLEXPORT extern QoreHashNode *emptyHash; -DLLEXPORT extern QoreStringNode *NullString; -DLLEXPORT extern DateTimeNode *ZeroDate; -DLLEXPORT extern QoreBigIntNode *Zero; -DLLEXPORT extern QoreFloatNode *ZeroFloat; +DLLEXPORT extern QoreListNode* emptyList; +DLLEXPORT extern QoreHashNode* emptyHash; +DLLEXPORT extern QoreStringNode* NullString; +DLLEXPORT extern DateTimeNode* ZeroDate; +DLLEXPORT extern QoreBigIntNode* Zero; +DLLEXPORT extern QoreFloatNode* ZeroFloat; +DLLEXPORT extern QoreNumberNode* ZeroNumber, * InfinityNumber, * NaNumber; DLLEXPORT extern QoreString NothingTypeString, NullTypeString, TrueString, FalseString, EmptyHashString, EmptyListString; class QoreTypeInfo; -DLLEXPORT extern const QoreTypeInfo *anyTypeInfo, +DLLEXPORT extern const QoreTypeInfo* anyTypeInfo, *bigIntTypeInfo, *floatTypeInfo, *boolTypeInfo, @@ -97,43 +98,43 @@ DLLEXPORT qore_type_t get_next_type_id(); -DLLEXPORT bool compareHard(const AbstractQoreNode *l, const AbstractQoreNode *r, ExceptionSink *xsink); -DLLEXPORT bool compareSoft(const AbstractQoreNode *l, const AbstractQoreNode *r, ExceptionSink *xsink); +DLLEXPORT bool compareHard(const AbstractQoreNode* l, const AbstractQoreNode* r, ExceptionSink* xsink); +DLLEXPORT bool compareSoft(const AbstractQoreNode* l, const AbstractQoreNode* r, ExceptionSink* xsink); -static inline AbstractQoreNode *boolean_false() { +static inline AbstractQoreNode* boolean_false() { return &False; } -static inline AbstractQoreNode *boolean_true() { +static inline AbstractQoreNode* boolean_true() { return &True; } -static inline QoreBigIntNode *zero() { +static inline QoreBigIntNode* zero() { Zero->ref(); return Zero; } -static inline QoreFloatNode *zero_float() { +static inline QoreFloatNode* zero_float() { ZeroFloat->ref(); return ZeroFloat; } -static inline DateTimeNode *zero_date() { +static inline DateTimeNode* zero_date() { ZeroDate->ref(); return ZeroDate; } -static inline class QoreStringNode *null_string() { +static inline class QoreStringNode* null_string() { NullString->ref(); return NullString; } -static inline QoreListNode *empty_list() { +static inline QoreListNode* empty_list() { emptyList->ref(); return emptyList; } -static inline QoreHashNode *empty_hash() { +static inline QoreHashNode* empty_hash() { emptyHash->ref(); return emptyHash; } @@ -158,27 +159,27 @@ friend class ExternalTypeInfo; protected: - ExternalTypeInfo *typeInfo; + ExternalTypeInfo* typeInfo; - DLLLOCAL QoreTypeInfoHelper(ExternalTypeInfo *n_typeInfo) : typeInfo(n_typeInfo) { + DLLLOCAL QoreTypeInfoHelper(ExternalTypeInfo* n_typeInfo) : typeInfo(n_typeInfo) { } //! this function must be reimplemented if setInputFilter() is called - DLLEXPORT virtual bool acceptInputImpl(AbstractQoreNode *&n, ExceptionSink *xsink) const; + DLLEXPORT virtual bool acceptInputImpl(AbstractQoreNode*& n, ExceptionSink* xsink) const; public: //! allocates a QoreTypeInfo object with no type information - DLLEXPORT QoreTypeInfoHelper(const char *n_tname); + DLLEXPORT QoreTypeInfoHelper(const char* n_tname); //! allocates a QoreTypeInfo object of the requested type - DLLEXPORT QoreTypeInfoHelper(qore_type_t id, const char *n_tname); + DLLEXPORT QoreTypeInfoHelper(qore_type_t id, const char* n_tname); //! deallocates the managed QoreTypeInfo object DLLEXPORT virtual ~QoreTypeInfoHelper(); //! returns a pointer to the object - DLLEXPORT const QoreTypeInfo *getTypeInfo() const; + DLLEXPORT const QoreTypeInfo* getTypeInfo() const; //! assigns the typeid to the object DLLEXPORT void assign(qore_type_t id); //! add another type that the type accepts - DLLEXPORT void addAcceptsType(const QoreTypeInfo *n_typeInfo); + DLLEXPORT void addAcceptsType(const QoreTypeInfo* n_typeInfo); //! set a flag that means the type is equivalent to an integer DLLEXPORT void setInt(); //! set a flag that means that if the return type is matched on input, it matches with QTI_AMBIGUOUS instead of QTI_IDENT @@ -188,17 +189,17 @@ //! set a flag so that any NT_INT in an accept list will match any type with is_int set with QTI_AMBIGUOUS DLLEXPORT void setIntMatch(); - DLLEXPORT int doAcceptError(bool priv_error, bool obj, int param_num, const char *param_name, AbstractQoreNode *n, ExceptionSink *xsink) const; + DLLEXPORT int doAcceptError(bool priv_error, bool obj, int param_num, const char* param_name, AbstractQoreNode* n, ExceptionSink* xsink) const; }; //! note that the QoreClass object created by this class must be deleted externally class AbstractQoreClassTypeInfoHelper : public QoreTypeInfoHelper { protected: - QoreClass *qc; + QoreClass* qc; public: //! allocates a QoreTypeInfo object and creates the QoreClass - DLLEXPORT AbstractQoreClassTypeInfoHelper(const char *name, int n_domain = QDOM_DEFAULT); + DLLEXPORT AbstractQoreClassTypeInfoHelper(const char* name, int n_domain = QDOM_DEFAULT); //! delets the QoreClass object managed if it has not been retrieved DLLEXPORT ~AbstractQoreClassTypeInfoHelper(); //! returns the QoreClass object created and zeros out the class ptr; can only be called once @@ -209,10 +210,10 @@ DLLEXPORT int testObjectClassAccess(const QoreObject *obj, const QoreClass *classtoaccess); -DLLEXPORT const QoreClass *typeInfoGetUniqueReturnClass(const QoreTypeInfo *typeInfo); -DLLEXPORT bool typeInfoHasType(const QoreTypeInfo *typeInfo); -DLLEXPORT const char *typeInfoGetName(const QoreTypeInfo *typeInfo); -DLLEXPORT qore_type_result_e typeInfoAcceptsType(const QoreTypeInfo *typeInfo, const QoreTypeInfo *otherTypeInfo); -DLLEXPORT qore_type_result_e typeInfoReturnsType(const QoreTypeInfo *typeInfo, const QoreTypeInfo *otherTypeInfo); +DLLEXPORT const QoreClass *typeInfoGetUniqueReturnClass(const QoreTypeInfo* typeInfo); +DLLEXPORT bool typeInfoHasType(const QoreTypeInfo* typeInfo); +DLLEXPORT const char* typeInfoGetName(const QoreTypeInfo* typeInfo); +DLLEXPORT qore_type_result_e typeInfoAcceptsType(const QoreTypeInfo* typeInfo, const QoreTypeInfo* otherTypeInfo); +DLLEXPORT qore_type_result_e typeInfoReturnsType(const QoreTypeInfo* typeInfo, const QoreTypeInfo* otherTypeInfo); #endif // _QORE_QORETYPE_H Modified: qore/trunk/include/qore/intern/qore_number_private.h =================================================================== --- qore/trunk/include/qore/intern/qore_number_private.h 2012-09-12 11:54:25 UTC (rev 5034) +++ qore/trunk/include/qore/intern/qore_number_private.h 2012-09-12 20:46:33 UTC (rev 5035) @@ -31,6 +31,13 @@ #define QORE_MPFR_RND MPFR_RNDN // MPFR_RNDA +// for binary operations on MPFR data +typedef int (*q_mpfr_binary_func_t)(mpfr_t, const mpfr_t, const mpfr_t, mpfr_rnd_t); +// for unary operations on MPFR data +typedef int (*q_mpfr_unary_func_t)(mpfr_t, const mpfr_t, mpfr_rnd_t); +// for unary operations on MPFR data without a rounding argument +typedef int (*q_mpfr_unary_nr_func_t)(mpfr_t, const mpfr_t); + struct qore_number_private_intern { mpfr_t num; @@ -53,6 +60,17 @@ if (p > mpfr_get_prec(num)) mpfr_prec_round(num, p, QORE_MPFR_RND); } + + DLLLOCAL static void checkFlags(ExceptionSink* xsink) { + if (mpfr_divby0_p()) { + mpfr_clear_divby0(); + xsink->raiseException("DIVISION-BY-ZERO", "division by zero error in numeric operatior"); + } + if (mpfr_erangeflag_p()) { + mpfr_clear_erangeflag(); + xsink->raiseException("INVALID-NUMERIC-OPERATION", "invalid numeric operation attempted"); + } + } }; struct qore_number_private : public qore_number_private_intern { @@ -188,50 +206,59 @@ return mpfr_cmp(num, r); } - template <int (*F)(mpfr_t, const mpfr_t, const mpfr_t, mpfr_rnd_t)> - DLLLOCAL qore_number_private* doCalcArg(const qore_number_private& r) const { + DLLLOCAL qore_number_private* doBinary(q_mpfr_binary_func_t func, const qore_number_private& r, ExceptionSink* xsink = 0) const { mpfr_prec_t prec = QORE_MAX(mpfr_get_prec(num), mpfr_get_prec(r.num)); qore_number_private* p = new qore_number_private(prec); - F(p->num, num, r.num, QORE_MPFR_RND); + func(p->num, num, r.num, QORE_MPFR_RND); + if (xsink) + checkFlags(xsink); + return p; } DLLLOCAL qore_number_private* doPlus(const qore_number_private& r) const { - return doCalcArg<mpfr_add>(r); + return doBinary(mpfr_add, r); } DLLLOCAL qore_number_private* doMinus(const qore_number_private& r) const { - return doCalcArg<mpfr_sub>(r); + return doBinary(mpfr_sub, r); } DLLLOCAL qore_number_private* doMultiply(const qore_number_private& r) const { - return doCalcArg<mpfr_mul>(r); + return doBinary(mpfr_mul, r); } //! add the argument to this value and return the result DLLLOCAL qore_number_private* doDivideBy(const qore_number_private& r, ExceptionSink* xsink) const { - if (r.zero()) { - xsink->raiseException("DIVISION-BY-ZERO", "division by zero in numeric expression"); - return 0; - } - return doCalcArg<mpfr_div>(r); + return doBinary(mpfr_div, r, xsink); } - template <int (*F)(mpfr_t, const mpfr_t, mpfr_rnd_t)> - DLLLOCAL qore_number_private* doCalcUnary() const { + DLLLOCAL qore_number_private* doUnary(q_mpfr_unary_func_t func, ExceptionSink* xsink = 0) const { qore_number_private* p = new qore_number_private(*this); - F(p->num, num, QORE_MPFR_RND); + func(p->num, num, QORE_MPFR_RND); + if (xsink) + checkFlags(xsink); + return p; } DLLLOCAL qore_number_private* negate() const { - return doCalcUnary<mpfr_neg>(); + return doUnary(mpfr_neg); } DLLLOCAL qore_number_private* absolute() const { - return doCalcUnary<mpfr_abs>(); + return doUnary(mpfr_abs); } + DLLLOCAL qore_number_private* doUnaryNR(q_mpfr_unary_nr_func_t func, ExceptionSink* xsink = 0) const { + qore_number_private* p = new qore_number_private(*this); + func(p->num, num); + if (xsink) + checkFlags(xsink); + + return p; + } + DLLLOCAL void inc() { MPFR_DECL_INIT(tmp, mpfr_get_prec(num)); mpfr_set(tmp, num, QORE_MPFR_RND); @@ -244,55 +271,79 @@ mpfr_sub_si(num, tmp, 1, QORE_MPFR_RND); } - template <int (*F)(mpfr_t, const mpfr_t, const mpfr_t, mpfr_rnd_t)> - DLLLOCAL void doCalcArgInplace(const qore_number_private& r) { + DLLLOCAL void doBinaryInplace(q_mpfr_binary_func_t func, const qore_number_private& r, ExceptionSink* xsink = 0) { checkPrec(r.num); MPFR_DECL_INIT(tmp, mpfr_get_prec(num)); mpfr_set(tmp, num, QORE_MPFR_RND); - F(num, tmp, r.num, QORE_MPFR_RND); + func(num, tmp, r.num, QORE_MPFR_RND); + if (xsink) + checkFlags(xsink); } DLLLOCAL void plusEquals(const qore_number_private& r) { - doCalcArgInplace<mpfr_add>(r); + doBinaryInplace(mpfr_add, r); } DLLLOCAL void minusEquals(const qore_number_private& r) { - doCalcArgInplace<mpfr_sub>(r); + doBinaryInplace(mpfr_sub, r); } DLLLOCAL void multiplyEquals(const qore_number_private& r) { - doCalcArgInplace<mpfr_mul>(r); + doBinaryInplace(mpfr_mul, r); } DLLLOCAL void divideEquals(const qore_number_private& r) { assert(!r.zero()); - doCalcArgInplace<mpfr_div>(r); + doBinaryInplace(mpfr_div, r); } // static accessor methods - static void inc(QoreNumberNode& n) { + DLLLOCAL static void inc(QoreNumberNode& n) { n.priv->inc(); } - static void dec(QoreNumberNode& n) { + DLLLOCAL static void dec(QoreNumberNode& n) { n.priv->dec(); } - static void plusEquals(QoreNumberNode& n, const QoreNumberNode& r) { + DLLLOCAL static void plusEquals(QoreNumberNode& n, const QoreNumberNode& r) { n.priv->plusEquals(*r.priv); } - static void minusEquals(QoreNumberNode& n, const QoreNumberNode& r) { + DLLLOCAL static void minusEquals(QoreNumberNode& n, const QoreNumberNode& r) { n.priv->minusEquals(*r.priv); } - static void multiplyEquals(QoreNumberNode& n, const QoreNumberNode& r) { + DLLLOCAL static void multiplyEquals(QoreNumberNode& n, const QoreNumberNode& r) { n.priv->multiplyEquals(*r.priv); } - static void divideEquals(QoreNumberNode& n, const QoreNumberNode& r) { + DLLLOCAL static void divideEquals(QoreNumberNode& n, const QoreNumberNode& r) { n.priv->divideEquals(*r.priv); } + + DLLLOCAL static QoreNumberNode* doUnary(const QoreNumberNode& n, q_mpfr_unary_func_t func, ExceptionSink* xsink = 0) { + qore_number_private* p = n.priv->doUnary(func, xsink); + return p ? new QoreNumberNode(p) : 0; + } + + DLLLOCAL static QoreNumberNode* doBinary(const QoreNumberNode& n, q_mpfr_binary_func_t func, const QoreNumberNode& r, ExceptionSink* xsink = 0) { + qore_number_private* p = n.priv->doBinary(func, *r.priv, xsink); + return p ? new QoreNumberNode(p) : 0; + } + + DLLLOCAL static QoreNumberNode* doUnaryNR(const QoreNumberNode& n, q_mpfr_unary_nr_func_t func, ExceptionSink* xsink = 0) { + qore_number_private* p = n.priv->doUnaryNR(func, xsink); + return p ? new QoreNumberNode(p) : 0; + } + + DLLLOCAL static QoreNumberNode* getNaNumber() { + return new QoreNumberNode(new qore_number_private("@NaN@")); + } + + DLLLOCAL static QoreNumberNode* getInfinity() { + return new QoreNumberNode(new qore_number_private("@Inf@")); + } }; #endif Modified: qore/trunk/include/qore/params.h =================================================================== --- qore/trunk/include/qore/params.h 2012-09-12 11:54:25 UTC (rev 5034) +++ qore/trunk/include/qore/params.h 2012-09-12 20:46:33 UTC (rev 5035) @@ -275,6 +275,9 @@ //! returns a double from a hard typed float param #define HARD_QORE_FLOAT(list, i) get_hard_param<const QoreFloatNode>(list, i)->f +//! returns a const QoreNumberNode* from a hard typed number or softnumber param +#define HARD_QORE_NUMBER(list, i) get_hard_param<const QoreNumberNode>(list, i) + //! returns a bool from a hard typed bool param #define HARD_QORE_BOOL(list, i) get_hard_param<const QoreBoolNode>(list, i)->getValue() Modified: qore/trunk/lib/QC_AbstractQuantifiedBidirectionalIterator.qpp =================================================================== --- qore/trunk/lib/QC_AbstractQuantifiedBidirectionalIterator.qpp 2012-09-12 11:54:25 UTC (rev 5034) +++ qore/trunk/lib/QC_AbstractQuantifiedBidirectionalIterator.qpp 2012-09-12 20:46:33 UTC (rev 5035) @@ -23,6 +23,6 @@ #include <qore/Qore.h> //! This class defines an abstract interface for bidirectional iterators where the size of the object is known in advance -/** This class does not define any new methods but rather just combines two abstract interfaces into a one. +/** This class does not define any new methods but rather just combines two abstract interfaces into one. */ qclass AbstractQuantifiedBidirectionalIterator [arg=AbstractQuantifiedBidirectionalIterator* i; ns=Qore; vparent=AbstractBidirectionalIterator,AbstractQuantifiedIterator]; Modified: qore/trunk/lib/QoreTypeInfo.cpp =================================================================== --- qore/trunk/lib/QoreTypeInfo.cpp 2012-09-12 11:54:25 UTC (rev 5034) +++ qore/trunk/lib/QoreTypeInfo.cpp 2012-09-12 20:46:33 UTC (rev 5035) @@ -23,10 +23,11 @@ #include <qore/Qore.h> #include <qore/QoreRWLock.h> #include <qore/intern/QoreNamespaceIntern.h> +#include <qore/intern/qore_number_private.h> // provides for 2-way compatibility with classes derived from QoreBigIntNode and softint static BigIntTypeInfo staticBigIntTypeInfo; -const QoreTypeInfo *bigIntTypeInfo = &staticBigIntTypeInfo; +const QoreTypeInfo* bigIntTypeInfo = &staticBigIntTypeInfo; // static reference types static QoreTypeInfo staticAnyTypeInfo, @@ -45,7 +46,7 @@ ; // const pointers to static reference types -const QoreTypeInfo *anyTypeInfo = &staticAnyTypeInfo, +const QoreTypeInfo* anyTypeInfo = &staticAnyTypeInfo, *stringTypeInfo = &staticStringTypeInfo, *boolTypeInfo = &staticBoolTypeInfo, *binaryTypeInfo = &staticBinaryTypeInfo, @@ -73,81 +74,81 @@ // provides for run-time assignment capability from any type static UserReferenceTypeInfo staticUserReferenceTypeInfo; -const QoreTypeInfo *userReferenceTypeInfo = &staticUserReferenceTypeInfo; +const QoreTypeInfo* userReferenceTypeInfo = &staticUserReferenceTypeInfo; // provides limited compatibility with integers static FloatTypeInfo staticFloatTypeInfo; static FloatOrNothingTypeInfo staticFloatOrNothingTypeInfo; -const QoreTypeInfo *floatTypeInfo = &staticFloatTypeInfo, +const QoreTypeInfo* floatTypeInfo = &staticFloatTypeInfo, *floatOrNothingTypeInfo = &staticFloatOrNothingTypeInfo; // xxx static NumberTypeInfo staticNumberTypeInfo; static NumberOrNothingTypeInfo staticNumberOrNothingTypeInfo; -const QoreTypeInfo *numberTypeInfo = &staticNumberTypeInfo, +const QoreTypeInfo* numberTypeInfo = &staticNumberTypeInfo, *numberOrNothingTypeInfo = &staticNumberOrNothingTypeInfo; // provides equal compatibility with closures and all types of code references static CodeTypeInfo staticCodeTypeInfo; static CodeOrNothingTypeInfo staticCodeOrNothingTypeInfo; -const QoreTypeInfo *codeTypeInfo = &staticCodeTypeInfo, +const QoreTypeInfo* codeTypeInfo = &staticCodeTypeInfo, *codeOrNothingTypeInfo = &staticCodeOrNothingTypeInfo; // either string or binary static DataTypeInfo staticDataTypeInfo; static DataOrNothingTypeInfo staticDataOrNothingTypeInfo; -const QoreTypeInfo *dataTypeInfo = &staticDataTypeInfo, +const QoreTypeInfo* dataTypeInfo = &staticDataTypeInfo, *dataOrNothingTypeInfo = &staticDataOrNothingTypeInfo; // provides int compatibility with and conversions from float, string, date, and bool static SoftBigIntTypeInfo staticSoftBigIntTypeInfo; static SoftBigIntOrNothingTypeInfo staticBigIntOrNothingTypeInfo; -const QoreTypeInfo *softBigIntTypeInfo = &staticSoftBigIntTypeInfo, +const QoreTypeInfo* softBigIntTypeInfo = &staticSoftBigIntTypeInfo, *softBigIntOrNothingTypeInfo = &staticBigIntOrNothingTypeInfo; // provides float compatibility with and conversions from int, string, date, and bool static SoftFloatTypeInfo staticSoftFloatTypeInfo; static SoftFloatOrNothingTypeInfo staticSoftFloatOrNothingTypeInfo; -const QoreTypeInfo *softFloatTypeInfo = &staticSoftFloatTypeInfo, +const QoreTypeInfo* softFloatTypeInfo = &staticSoftFloatTypeInfo, *softFloatOrNothingTypeInfo = &staticSoftFloatOrNothingTypeInfo; // xxx static SoftNumberTypeInfo staticSoftNumberTypeInfo; static SoftNumberOrNothingTypeInfo staticSoftNumberOrNothingTypeInfo; -const QoreTypeInfo *softNumberTypeInfo = &staticSoftNumberTypeInfo, +const QoreTypeInfo* softNumberTypeInfo = &staticSoftNumberTypeInfo, *softNumberOrNothingTypeInfo = &staticSoftNumberOrNothingTypeInfo; // provides bool compatibility with and conversions from float, string, date, and int static SoftBoolTypeInfo staticSoftBoolTypeInfo; static SoftBoolOrNothingTypeInfo staticSoftBoolOrNothingTypeInfo; -const QoreTypeInfo *softBoolTypeInfo = &staticSoftBoolTypeInfo, +const QoreTypeInfo* softBoolTypeInfo = &staticSoftBoolTypeInfo, *softBoolOrNothingTypeInfo = &staticSoftBoolOrNothingTypeInfo; // provides string compatibility with and conversions from float, int, date, and bool static SoftStringTypeInfo staticSoftStringTypeInfo; static SoftStringOrNothingTypeInfo staticSoftStringOrNothingTypeInfo; -const QoreTypeInfo *softStringTypeInfo = &staticSoftStringTypeInfo, +const QoreTypeInfo* softStringTypeInfo = &staticSoftStringTypeInfo, *softStringOrNothingTypeInfo = &staticSoftStringOrNothingTypeInfo; static SoftDateTypeInfo staticSoftDateTypeInfo; static SoftDateOrNothingTypeInfo staticSoftDateOrNothingTypeInfo; -const QoreTypeInfo *softDateTypeInfo = &staticSoftDateTypeInfo, +const QoreTypeInfo* softDateTypeInfo = &staticSoftDateTypeInfo, *softDateOrNothingTypeInfo = &staticSoftDateOrNothingTypeInfo; // provides automatic conversion to a list static SoftListTypeInfo staticSoftListTypeInfo; static SoftListOrNothingTypeInfo staticListOrNothingTypeInfo; -const QoreTypeInfo *softListTypeInfo = &staticSoftListTypeInfo, +const QoreTypeInfo* softListTypeInfo = &staticSoftListTypeInfo, *softListOrNothingTypeInfo = &staticListOrNothingTypeInfo; // somethingTypeInfo means "not NOTHING" static SomethingTypeInfo staticSomethingTypeInfo; -const QoreTypeInfo *somethingTypeInfo = &staticSomethingTypeInfo; +const QoreTypeInfo* somethingTypeInfo = &staticSomethingTypeInfo; // timeout type info accepts int or date and returns an int giving milliseconds static TimeoutTypeInfo staticTimeoutTypeInfo; static TimeoutOrNothingTypeInfo staticTimeoutOrNothingTypeInfo; -const QoreTypeInfo *timeoutTypeInfo = &staticTimeoutTypeInfo, +const QoreTypeInfo* timeoutTypeInfo = &staticTimeoutTypeInfo, *timeoutOrNothingTypeInfo = &staticTimeoutOrNothingTypeInfo; static IntOrFloatTypeInfo staticIntOrFloatTypeInfo; @@ -159,24 +160,25 @@ static FloatOrNumberTypeInfo staticFloatOrNumberTypeInfo; const QoreTypeInfo* floatOrNumberTypeInfo = &staticFloatOrNumberTypeInfo; -QoreListNode *emptyList; -QoreHashNode *emptyHash; -QoreStringNode *NullString; -DateTimeNode *ZeroDate; -QoreBigIntNode *Zero; -QoreFloatNode *ZeroFloat; +QoreListNode* emptyList; +QoreHashNode* emptyHash; +QoreStringNode* NullString; +DateTimeNode* ZeroDate; +QoreBigIntNode* Zero; +QoreFloatNode* ZeroFloat; +QoreNumberNode* ZeroNumber, * NaNumber, * InfinityNumber; // map from types to default values -typedef std::map<qore_type_t, AbstractQoreNode *> def_val_map_t; +typedef std::map<qore_type_t, AbstractQoreNode* > def_val_map_t; static def_val_map_t def_val_map; // map from names used when parsing to types -typedef std::map<const char *, const QoreTypeInfo *, ltstr> str_typeinfo_map_t; +typedef std::map<const char* , const QoreTypeInfo* , ltstr> str_typeinfo_map_t; static str_typeinfo_map_t str_typeinfo_map; static str_typeinfo_map_t str_ornothingtypeinfo_map; // map from types to type info -typedef std::map<qore_type_t, const QoreTypeInfo *> type_typeinfo_map_t; +typedef std::map<qore_type_t, const QoreTypeInfo* > type_typeinfo_map_t; static type_typeinfo_map_t type_typeinfo_map; static type_typeinfo_map_t type_ornothingtypeinfo_map; @@ -184,13 +186,13 @@ static type_typeinfo_map_t extern_type_info_map; // map from types to names -typedef std::map<qore_type_t, const char *> type_str_map_t; +typedef std::map<qore_type_t, const char* > type_str_map_t; static type_str_map_t type_str_map; // rwlock for global type map static QoreRWLock extern_type_info_map_lock; -static void do_maps(qore_type_t t, const char *name, const QoreTypeInfo *typeInfo, const QoreTypeInfo *orNothingTypeInfo = 0) { +static void do_maps(qore_type_t t, const char* name, const QoreTypeInfo* typeInfo, const QoreTypeInfo* orNothingTypeInfo = 0) { str_typeinfo_map[name] = typeInfo; str_ornothingtypeinfo_map[name] = orNothingTypeInfo; type_typeinfo_map[t] = typeInfo; @@ -201,19 +203,23 @@ // at least the NullString must be created after the default character encoding is set void init_qore_types() { // initialize global default values - NullString = new QoreStringNode; - ZeroDate = DateTimeNode::makeAbsolute(0, 0, 0); - Zero = new QoreBigIntNode; - ZeroFloat = new QoreFloatNode; + NullString = new QoreStringNode; + ZeroDate = DateTimeNode::makeAbsolute(0, 0, 0); + Zero = new QoreBigIntNode; + ZeroFloat = new QoreFloatNode; + ZeroNumber = new QoreNumberNode; + NaNumber = qore_number_private::getNaNumber(); + InfinityNumber = qore_number_private::getInfinity(); - emptyList = new QoreListNode; - emptyHash = new QoreHashNode; + emptyList = new QoreListNode; + emptyHash = new QoreHashNode; def_val_map[NT_INT] = Zero->refSelf(); def_val_map[NT_STRING] = NullString->refSelf(); def_val_map[NT_BOOLEAN] = &False; def_val_map[NT_DATE] = ZeroDate->refSelf(); def_val_map[NT_FLOAT] = ZeroFloat->refSelf(); + def_val_map[NT_NUMBER] = ZeroNumber->refSelf(); def_val_map[NT_LIST] = emptyList->refSelf(); def_val_map[NT_HASH] = emptyHash->refSelf(); def_val_map[NT_BINARY] = new BinaryNode; @@ -271,6 +277,9 @@ // dereference global default values NullString->deref(); + InfinityNumber->deref(); + NaNumber->deref(); + ZeroNumber->deref(); ZeroFloat->deref(); Zero->deref(); ZeroDate->deref(); @@ -289,31 +298,31 @@ delete nullOrNothingTypeInfo; } -void add_to_type_map(qore_type_t t, const QoreTypeInfo *typeInfo) { +void add_to_type_map(qore_type_t t, const QoreTypeInfo* typeInfo) { QoreAutoRWWriteLocker al(extern_type_info_map_lock); assert(extern_type_info_map.find(t) == extern_type_info_map.end()); extern_type_info_map[t] = typeInfo; } -static const QoreTypeInfo *getExternalTypeInfoForType(qore_type_t t) { +static const QoreTypeInfo* getExternalTypeInfoForType(qore_type_t t) { QoreAutoRWReadLocker al(extern_type_info_map_lock); type_typeinfo_map_t::iterator i = extern_type_info_map.find(t); return (i == extern_type_info_map.end() ? 0 : i->second); } -const QoreTypeInfo *getTypeInfoForType(qore_type_t t) { +const QoreTypeInfo* getTypeInfoForType(qore_type_t t) { type_typeinfo_map_t::iterator i = type_typeinfo_map.find(t); return i != type_typeinfo_map.end() ? i->second : getExternalTypeInfoForType(t); } -const QoreTypeInfo *getTypeInfoForValue(const AbstractQoreNode *n) { +const QoreTypeInfo* getTypeInfoForValue(const AbstractQoreNode* n) { qore_type_t t = n ? n->getType() : NT_NOTHING; if (t != NT_OBJECT) return getTypeInfoForType(t); return reinterpret_cast<const QoreObject *>(n)->getClass()->getTypeInfo(); } -AbstractQoreNode *getDefaultValueForBuiltinValueType(qore_type_t t) { +AbstractQoreNode* getDefaultValueForBuiltinValueType(qore_type_t t) { def_val_map_t::iterator i = def_val_map.find(t); assert(i != def_val_map.end()); return i->second->refSelf(); @@ -323,7 +332,7 @@ return def_val_map.find(t) != def_val_map.end(); } -const QoreTypeInfo *getBuiltinUserTypeInfo(const char *str) { +const QoreTypeInfo* getBuiltinUserTypeInfo(const char* str) { // user exceptions here if (!strcmp(str, "reference")) return userReferenceTypeInfo; @@ -332,7 +341,7 @@ return i != str_typeinfo_map.end() ? i->second : 0; } -const QoreTypeInfo *getBuiltinUserOrNothingTypeInfo(const char *str) { +const QoreTypeInfo* getBuiltinUserOrNothingTypeInfo(const char* str) { // user exceptions here if (!strcmp(str, "reference")) return anyTypeInfo; @@ -341,12 +350,12 @@ return i != str_ornothingtypeinfo_map.end() ? i->second : 0; } -const char *getBuiltinTypeName(qore_type_t type) { +const char* getBuiltinTypeName(qore_type_t type) { type_str_map_t::iterator i = type_str_map.find(type); if (i != type_str_map.end()) return i->second; - const QoreTypeInfo *typeInfo = getExternalTypeInfoForType(type); + const QoreTypeInfo* typeInfo = getExternalTypeInfoForType(type); if (typeInfo) return typeInfo->getName(); @@ -367,14 +376,14 @@ return "<unknown type>"; } -int QoreTypeInfo::runtimeAcceptInputIntern(bool &priv_error, AbstractQoreNode *n) const { +int QoreTypeInfo::runtimeAcceptInputIntern(bool &priv_error, AbstractQoreNode* n) const { qore_type_t nt = get_node_type(n); if (reverse_logic) return qt == nt ? -1 : 0; if (qt != nt) - return is_int && nt > QORE_NUM_TYPES && dynamic_cast<QoreBigIntNode *>(n) ? 0 : -1; + return is_int && nt > QORE_NUM_TYPES && dynamic_cast<QoreBigIntNode* >(n) ? 0 : -1; if (qt != NT_OBJECT || !qc) return 0; @@ -416,7 +425,7 @@ return runtimeAcceptInputIntern(priv_error, n); } -bool QoreTypeInfo::isInputIdentical(const QoreTypeInfo *typeInfo) const { +bool QoreTypeInfo::isInputIdentical(const QoreTypeInfo* typeInfo) const { bool thisnt = (!hasType()); bool typent = (!typeInfo->hasType()); @@ -463,7 +472,7 @@ return true; } -bool QoreTypeInfo::isOutputIdentical(const QoreTypeInfo *typeInfo) const { +bool QoreTypeInfo::isOutputIdentical(const QoreTypeInfo* typeInfo) const { bool thisnt = (!hasType()); bool typent = (!typeInfo->hasType()); @@ -543,28 +552,28 @@ return rc; } -void QoreTypeInfo::doNonNumericWarning(const char *preface) const { - QoreStringNode *desc = new QoreStringNode(preface); +void QoreTypeInfo::doNonNumericWarning(const char* preface) const { + QoreStringNode* desc = new QoreStringNode(preface); getThisType(*desc); desc->sprintf(", which does not evaluate to a numeric type, therefore will always evaluate to 0 at runtime"); qore_program_private::makeParseWarning(getProgram(), QP_WARN_INVALID_OPERATION, "INVALID-OPERATION", desc); } -void QoreTypeInfo::doNonBooleanWarning(const char *preface) const { - QoreStringNode *desc = new QoreStringNode(preface); +void QoreTypeInfo::doNonBooleanWarning(const char* preface) const { + QoreStringNode* desc = new QoreStringNode(preface); getThisType(*desc); desc->sprintf(", which does not evaluate to a numeric or boolean type, therefore will always evaluate to False at runtime"); qore_program_private::makeParseWarning(getProgram(), QP_WARN_INVALID_OPERATION, "INVALID-OPERATION", desc); } -void QoreTypeInfo::doNonStringWarning(const char *preface) const { - QoreStringNode *desc = new QoreStringNode(preface); +void QoreTypeInfo::doNonStringWarning(const char* preface) const { + QoreStringNode* desc = new QoreStringNode(preface); getThisType(*desc); desc->sprintf(", which cannot be converted to a string, therefore will always evaluate to an empty string at runtime"); qore_program_private::makeParseWarning(getProgram(), QP_WARN_INVALID_OPERATION, "INVALID-OPERATION", desc); } -const QoreTypeInfo *QoreParseTypeInfo::resolveAndDelete(const QoreProgramLocation& loc) { +const QoreTypeInfo* QoreParseTypeInfo::resolveAndDelete(const QoreProgramLocation& loc) { if (!this) return 0; @@ -575,7 +584,7 @@ delete this; if (qc && my_or_nothing) { - const QoreTypeInfo *rv = qc->getOrNothingTypeInfo(); + const QoreTypeInfo* rv = qc->getOrNothingTypeInfo(); if (!rv) { parse_error(loc, "class %s cannot be typed with '*' as the class' type handler has an input filter and the filter does not accept NOTHING", qc->getName()); return objectOrNothingTypeInfo; @@ -587,7 +596,7 @@ return qc ? qc->getTypeInfo() : objectTypeInfo; } /* -AbstractVirtualMethod::AbstractVirtualMethod(const char *n_name, bool n_requires_lvalue, const QoreTypeInfo *n_return_type, ...) +AbstractVirtualMethod::AbstractVirtualMethod(const char* n_name, bool n_requires_lvalue, const QoreTypeInfo* n_return_type, ...) : name(n_name), requires_value(n_requires_lvalue), return_type(n_return_type) { va_list args; va_start(args, n_return_type); Modified: qore/trunk/lib/ql_math.qpp =================================================================== --- qore/trunk/lib/ql_math.qpp 2012-09-12 11:54:25 UTC (rev 5034) +++ qore/trunk/lib/ql_math.qpp 2012-09-12 20:46:33 UTC (rev 5035) @@ -23,6 +23,7 @@ #include <qore/Qore.h> #include <qore/intern/ql_math.h> +#include <qore/intern/qore_number_private.h> #include <math.h> #include <stdlib.h> @@ -50,13 +51,27 @@ */ //@{ -//! Returns a floating-point number equal to the closest integer to the argument passed; numbers halfway between two integers are arounded away from zero +//! Returns a number equal to the closest integer to the argument passed; numbers halfway between two integers are rounded away from zero +/** @param n a number to round + + @return a number equal to the closest integer to the argument passed; numbers halfway between two integers are rounded away from zero + + @par Example: + @code +my number $n = round($num); + @endcode + */ +number round(number n) [flags=CONSTANT] { + return qore_number_private::doUnaryNR(*n, mpfr_round); +} + +//! Returns a floating-point number equal to the closest integer to the argument passed; numbers halfway between two integers are rounded away from zero /** @par Platform Availability @ref Qore::Option::HAVE_ROUND @param f a number to round - @return a floating-point number equal to the closest integer to the argument passed; numbers halfway between two integers are arounded away from zero + @return a floating-point number equal to the closest integer to the argument passed; numbers halfway between two integers are rounded away from zero @par Example: @code @@ -79,8 +94,25 @@ return 0; } +//! Returns a number equal to the smallest integral value greater than or equal to the argument passed +/** + @param n the value to process + + @return a number equal to the smallest integral value greater than or equal to the argument passed + + @par Example: + @code +my number $x = ceil(3.2n); # returns 4.0n + @endcode + + @see floor(number) + */ +number ceil(number n) [flags=CONSTANT] { + return qore_number_private::doUnaryNR(*n, mpfr_ceil); +} + //! Returns a floating-point number equal to the smallest integral value greater than or equal to the argument passed -/** +/** @param f the value to process @return a floating-point number equal to the smallest integral value greater than or equal to the argument passed @@ -103,8 +135,23 @@ return 0; } +//! Returns a number equal to the largest integral value less than or equal to the argument passed +/** + @param n the value to process + + @par Example: + @code +my number $x = floor(3.9n); # returns 3.0n + @endcode + + @see ceil(number) + */ +number floor(softnumber n) [flags=CONSTANT] { + return qore_number_private::doUnaryNR(*n, mpfr_floor); +} + //! Returns a floating-point number equal to the largest integral value less than or equal to the argument passed -/** +/** @param f the value to process @par Example: @@ -134,15 +181,33 @@ @par Example: @code +my number $z = pow($x, $y); + @endcode + + @throw DIVISION-BY-ZERO in pow(x, y), if x = 0 then y must be a non-negative value + */ +number pow(number x, number y) [flags=RET_VALUE_ONLY] { + return qore_number_private::doBinary(*x, mpfr_pow, *y, xsink); +} + +//! Returns a number raised to the power of another number +/** + @param x the number to raise to the power of \a y + @param y the power to raise \a x to + + @return a number raised to the power of another number + + @par Example: + @code my float $z = pow($x, $y); @endcode - @throw DIVISION-BY-ZERO in pow(x, y), y must be a non-negative value + @throw DIVISION-BY-ZERO in pow(x, y), if x = 0 then y must be a non-negative value @throw INVALID-POW-ARGUMENTS in pow(x, y), x cannot be negative when y is not an integer value */ -float pow(softfloat x = 0.0, softfloat y = 0.0) [flags=CONSTANT] { - if (y < 0) { - xsink->raiseException("DIVISION-BY-ZERO", "pow(x, y) y must be a non-negative value"); +float pow(softfloat x = 0.0, softfloat y = 0.0) [flags=RET_VALUE_ONLY] { + if (x == 0.0 && y < 0) { + xsink->raiseException("DIVISION-BY-ZERO", "pow(x, y) if x = 0 then y must be a non-negative value"); return 0; } if (x < 0 && y != ceil(y)) { @@ -170,6 +235,21 @@ //! Returns the absolute value of the argument passed /** + @param i the value to process + + @return the absolute value of the argument passed + + @par Example: + @code +my number $n = abs(-20n); # returns 20n + @endcode + */ +number abs(number n) [flags=CONSTANT] { + return qore_number_private::doUnary(*n, mpfr_abs); +} + +//! Returns the absolute value of the argument passed +/** @param f the value to process @return the absolute value of the argument passed @@ -199,6 +279,22 @@ @par Example: @code +my number $z = hypot($x, $y); + @endcode + */ +number hypot(number x, number y) [flags=CONSTANT] { + return qore_number_private::doBinary(*x, mpfr_hypot, *y); +} + +//! Returns the length of the hypotenuse of a right-angle triangle with sides given as the two arguments +/** + @param x the length of side x of the right-angle triangle + @param y the length of side y of the right-angle triangle + + @return the length of the hypotenuse of a right-angle triangle with sides given as the two arguments + + @par Example: + @code my float $z = hypot($x, $y); @endcode */ @@ -215,6 +311,21 @@ //! Returns the square root of the number passed /** + @param n the value to process + + @return the square root of the number passed + + @par Example: + @code +my number $x = sqrt($y); + @endcode + */ +number sqrt(number n) [flags=CONSTANT] { + return qore_number_private::doUnary(*n, mpfr_sqrt); +} + +//! Returns the square root of the number passed +/** @param f the value to process @return the square root of the number passed @@ -237,6 +348,21 @@ //! Returns the cube root of the number passed /** + @param n the value to process + + @return the cube root of the number passed + + @par Example: + @code +my number $x = cbrt($y); + @endcode + */ +number cbrt(number n) [flags=CONSTANT] { + return qore_number_private::doUnary(*n, mpfr_cbrt); +} + +//! Returns the cube root of the number passed +/** @param f the value to process @return the cube root of the number passed @@ -259,6 +385,21 @@ //! Returns the sine of the number in radians passed /** + @param n the angle in radians + + @return the sine of the number in radians passed + + @par Example: + @code +my number $x = sin($y); + @endcode + */ +number sin(number n) [flags=CONSTANT] { + return qore_number_private::doUnary(*n, mpfr_sin); +} + +//! Returns the sine of the number in radians passed +/** @param f the angle in radians @return the sine of the number in radians passed @@ -281,6 +422,21 @@ //! Returns the cosine of the number in radians passed /** + @param n the angle in radians + + @return the cosine of the number in radians passed + + @par Example: + @code +my number $x = cos($y); + @endcode + */ +number cos(number n) [flags=CONSTANT] { + return qore_number_private::doUnary(*n, mpfr_cos); +} + +//! Returns the cosine of the number in radians passed +/** @param f the angle in radians @return the cosine of the number in radians passed @@ -303,6 +459,21 @@ //! Returns the tangent of the number in radians passed /** + @param n the angle in radians + + @return the tangent of the number in radians passed + + @par Example: + @code +my number $x = tan($y); + @endcode + */ +number tan(number n) [flags=CONSTANT] { + return qore_number_private::doUnary(*n, mpfr_tan); +} + +//! Returns the tangent of the number in radians passed +/** @param f the angle in radians @return the tangent of the number in radians passed @@ -325,6 +496,21 @@ //! Returns the value in radians of the arc sine of the given value /** + @param n the sine value to process + + @return the value in radians of the arc sine of the given value + + @par Example: + @code +my number $x = asin($y); + @endcode + */ +number asin(number n) [flags=CONSTANT] { + return qore_number_private::doUnary(*n, mpfr_asin); +} + +//! Returns the value in radians of the arc sine of the given value +/** @param f the sine value to process @return the value in radians of the arc sine of the given value @@ -347,6 +533,21 @@ //! Returns the value in radians of the arc cosine of the given value /** + @param n the cosine value to process + + @return the value in radians of the arc cosine of the given value + + @par Example: + @code +my number $x = acos($y); + @endcode + */ +number acos(number n) [flags=CONSTANT] { + return qore_number_private::doUnary(*n, mpfr_acos); +} + +//! Returns the value in radians of the arc cosine of the given value +/** @param f the cosine value to process @return the value in radians of the arc cosine of the given value @@ -362,6 +563,21 @@ //! Returns the value in radians of the arc tangent of the given value /** + @param n the tangent value to process + + @return the value in radians of the arc tangent of the given value + + @par Example: + @code +my number $x = atan($y); + @endcode + */ +number atan(number n) [flags=CONSTANT] { + return qore_number_private::doUnary(*n, mpfr_atan); +} + +//! Returns the value in radians of the arc tangent of the given value +/** @param f the tangent value to process @return the value in radians of the arc tangent of the given value @@ -391,6 +607,22 @@ @par Example: @code +my number $f = atan2($y, $x); + @endcode + */ +number atan2(number y, number x) [flags=CONSTANT] { + return qore_number_private::doBinary(*y, mpfr_atan2, *x); +} + +//! Returns the principal value of the arc tangent of y/x, using the signs of the two arguments to determine the quadrant of the result +/** + @param y the y value for the function + @param x the x value for the function + + @return the principal value of the arc tangent of y/x, using the signs of the two arguments to determine the quadrant of the result + + @par Example: + @code my float $f = atan2($y, $x); @endcode */ @@ -407,6 +639,21 @@ //! Returns the hyperbolic sine of the given value /** + @param n the value to process + + @return the hyperbolic sine of the given value + + @par Example: + @code +my number $x = sinh($y); + @endcode + */ +number sinh(number n) [flags=CONSTANT] { + return qore_number_private::doUnary(*n, mpfr_sinh); +} + +//! Returns the hyperbolic sine of the given value +/** @param f the value to process @return the hyperbolic sine of the given value @@ -429,6 +676,21 @@ //! Returns the hyperbolic cosine of the given value /** + @param n the value to process + + @return the hyperbolic cosine of the given value + + @par Example: + @code +my number $x = cosh($y); + @endcode + */ +number cosh(number n) [flags=CONSTANT] { + return qore_number_private::doUnary(*n, mpfr_cosh); +} + +//! Returns the hyperbolic cosine of the given value +/** @param f the value to process @return the hyperbolic cosine of the given value @@ -451,6 +713,21 @@ //! Returns the hyperbolic tangent of the given value /** + @param n the value to process + + @return the hyperbolic tangent of the given value + + @par Example: + @code +my number $x = tanh($y); + @endcode + */ +number tanh(number n) [flags=CONSTANT] { + return qore_number_private::doUnary(*n, mpfr_tanh); +} + +//! Returns the hyperbolic tangent of the given value +/** @param f the value to process @return the hyperbolic tangent of the given value @@ -473,6 +750,21 @@ //! Returns the natural logarithm of the given value /** + @param n the value to process + + @return the natural logarithm of the given value + + @par Example: + @code +my float $x = nlog($y); + @endcode + */ +number nlog(number n) [flags=CONSTANT] { + return qore_number_private::doUnary(*n, mpfr_log); +} + +//! Returns the natural logarithm of the given value +/** @param f the value to process @return the natural logarithm of the given value @@ -495,6 +787,21 @@ //! Returns the base 10 logarithm of the given number /** + @param n the value to process + + @return the base 10 logarithm of the given value + + @par Example: + @code +my number $x = log10($y); + @endcode + */ +number log10(number n) [flags=CONSTANT] { + return qore_number_private::doUnary(*n, mpfr_log10); +} + +//! Returns the base 10 logarithm of the given number +/** @param f the value to process @return the base 10 logarithm of the given value @@ -517,6 +824,21 @@ //! Returns the natural logarithm of 1 + the given number /** + @param n the value to process + + @return the natural logarithm of 1 + the given number + + @par Example: + @code +my number $x = log1p($y); + @endcode + */ +number log1p(number n) [flags=CONSTANT] { + return qore_number_private::doUnary(*n, mpfr_log1p); +} + +//! Returns the natural logarithm of 1 + the given number +/** @param f the value to process @return the natural logarithm of 1 + the given number @@ -561,6 +883,21 @@ //! Returns the value of \a e (the base of natural logarithms) raised to the power of the given number /** + @param n the value to process + + @return the value of \a e (the base of natural logarithms) raised to the power of the given number + + @par Example: + @code +my number $x = exp($y); + @endcode + */ +number exp(number n) [flags=CONSTANT] { + return qore_number_private::doUnary(*n, mpfr_exp); +} + +//! Returns the value of \a e (the base of natural logarithms) raised to the power of the given number +/** @param f the value to process @return the value of \a e (the base of natural logarithms) raised to the power of the given number @@ -583,6 +920,21 @@ //! Returns the value of 2 raised to the power of the given number /** + @param n the value to process + + @return the value of 2 raised to the power of the given number + + @par Example: + @code +my number $x = exp2($y); + @endcode + */ +number exp2(number n) [flags=CONSTANT] { + return qore_number_private::doUnary(*n, mpfr_exp2); +} + +//! Returns the value of 2 raised to the power of the given number +/** @param f the value to process @return the value of 2 raised to the power of the given number @@ -609,6 +961,21 @@ //! Returns the value of \a e (the base of natural logarithms) raised to the power of the given number - 1 /** + @param n the value to process + + @return the value of \a e (the base of natural logarithms) raised to the power of the given number - 1 + + @par Example: + @code +my number $x = exp1m($y); + @endcode + */ +number expm1(number n) [flags=CONSTANT] { + return qore_number_private::doUnary(*n, mpfr_expm1); +} + +//! Returns the value of \a e (the base of natural logarithms) raised to the power of the given number - 1 +/** @param f the value to process @return the value of \a e (the base of natural logarithms) raised to the power of the given number - 1 Modified: qore/trunk/lib/qpp.cpp =================================================================== --- qore/trunk/lib/qpp.cpp 2012-09-12 11:54:25 UTC (rev 5034) +++ qore/trunk/lib/qpp.cpp 2012-09-12 20:46:33 UTC (rev 5035) @@ -1304,6 +1304,10 @@ fprintf(fp, " double %s = HARD_QORE_FLOAT(args, %d);\n", p.name.c_str(), i); continue; } + if (p.type == "number" || p.type == "softnumber") { + fprintf(fp, " const QoreNumberNode* %s = HARD_QORE_NUMBER(args, %d);\n", p.name.c_str(), i); + continue; + } if (p.type == "bool" || p.type == "softbool") { fprintf(fp, " bool %s = HARD_QORE_BOOL(args, %d);\n", p.name.c_str(), i); continue; @@ -3205,6 +3209,18 @@ tmap["*softfloat"] = "softFloatOrNothingTypeInfo"; mtmap["*softfloat"] = "nf"; + tmap["number"] = "numberTypeInfo"; + mtmap["number"] = "Vn"; + + tmap["softnumber"] = "softNumberTypeInfo"; + mtmap["softnumber"] = "vn"; + + tmap["*number"] = "numberOrNothingTypeInfo"; + mtmap["*number"] = "Nn"; + + tmap["*softnumber"] = "softNumberOrNothingTypeInfo"; + mtmap["*softnumber"] = "nn"; + tmap["bool"] = "boolTypeInfo"; mtmap["bool"] = "Vb"; Modified: qore/trunk/lib/scanner.lpp =================================================================== --- qore/trunk/lib/scanner.lpp 2012-09-12 11:54:25 UTC (rev 5034) +++ qore/trunk/lib/scanner.lpp 2012-09-12 20:46:33 UTC (rev 5035) @@ -1203,9 +1203,13 @@ cast\<{WS}*({WORD}::)+{WORD}{WS}*\> yylval->string = make_cast(yytext); return QORE_CAST; cast\<{WS}*{WORD}{WS}*\> yylval->string = make_cast(yytext); return QORE_CAST; ({WORD}::)+\$\.{WORD} yylval->nscope = new NamedScope(strdup(yytext)); yylval->nscope->fixBCCall(); return BASE_CLASS_CALL; +@[Nn][Aa][Nn]@ yylval->decimal = strtod("NAN", 0); return QFLOAT; +@[Ii][Nn][Ff]@ yylval->decimal = strtod("INFINITY", 0); return QFLOAT; {DIGIT}+"."{DIGIT}+ yylval->decimal = strtod(yytext, 0); return QFLOAT; {DIGIT}+[eE][+-]?{DIGIT}+ yylval->decimal = strtod(yytext, 0); return QFLOAT; {DIGIT}+"."{DIGIT}+[eE][+-]?{DIGIT}+ yylval->decimal = strtod(yytext, 0); return QFLOAT; +@[Nn][Aa][Nn]@n yylval->num = new QoreNumberNode("@nan@"); return NUMBER; +@[Ii][Nn][Ff]@n yylval->num = new QoreNumberNode("@inf@"); return NUMBER; {DIGIT}+n yylval->num = new QoreNumberNode(yytext); return NUMBER; {DIGIT}+"."{DIGIT}+n yylval->num = new QoreNumberNode(yytext); return NUMBER; {DIGIT}+[eE][+-]?{DIGIT}+n yylval->num = new QoreNumberNode(yytext); return NUMBER; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <david_nichols@us...> - 2012-09-12 11:54:36
|
Revision: 5034 http://qore.svn.sourceforge.net/qore/?rev=5034&view=rev Author: david_nichols Date: 2012-09-12 11:54:25 +0000 (Wed, 12 Sep 2012) Log Message: ----------- use templates for internal number member functions Modified Paths: -------------- qore/trunk/include/qore/intern/qore_number_private.h Modified: qore/trunk/include/qore/intern/qore_number_private.h =================================================================== --- qore/trunk/include/qore/intern/qore_number_private.h 2012-09-12 11:00:51 UTC (rev 5033) +++ qore/trunk/include/qore/intern/qore_number_private.h 2012-09-12 11:54:25 UTC (rev 5034) @@ -188,27 +188,24 @@ return mpfr_cmp(num, r); } - DLLLOCAL qore_number_private* doPlus(const qore_number_private& r) const { + template <int (*F)(mpfr_t, const mpfr_t, const mpfr_t, mpfr_rnd_t)> + DLLLOCAL qore_number_private* doCalcArg(const qore_number_private& r) const { mpfr_prec_t prec = QORE_MAX(mpfr_get_prec(num), mpfr_get_prec(r.num)); qore_number_private* p = new qore_number_private(prec); - mpfr_add(p->num, num, r.num, QORE_MPFR_RND); + F(p->num, num, r.num, QORE_MPFR_RND); return p; } - //! add the argument to this value and return the result + DLLLOCAL qore_number_private* doPlus(const qore_number_private& r) const { + return doCalcArg<mpfr_add>(r); + } + DLLLOCAL qore_number_private* doMinus(const qore_number_private& r) const { - mpfr_prec_t prec = QORE_MAX(mpfr_get_prec(num), mpfr_get_prec(r.num)); - qore_number_private* p = new qore_number_private(prec); - mpfr_sub(p->num, num, r.num, QORE_MPFR_RND); - return p; + return doCalcArg<mpfr_sub>(r); } - //! add the argument to this value and return the result DLLLOCAL qore_number_private* doMultiply(const qore_number_private& r) const { - mpfr_prec_t prec = QORE_MAX(mpfr_get_prec(num), mpfr_get_prec(r.num)); - qore_number_private* p = new qore_number_private(prec); - mpfr_mul(p->num, num, r.num, QORE_MPFR_RND); - return p; + return doCalcArg<mpfr_mul>(r); } //! add the argument to this value and return the result @@ -217,22 +214,22 @@ xsink->raiseException("DIVISION-BY-ZERO", "division by zero in numeric expression"); return 0; } - mpfr_prec_t prec = QORE_MAX(mpfr_get_prec(num), mpfr_get_prec(r.num)); - qore_number_private* p = new qore_number_private(prec); - mpfr_div(p->num, num, r.num, QORE_MPFR_RND); - return p; + return doCalcArg<mpfr_div>(r); } - DLLLOCAL qore_number_private* negate() const { + template <int (*F)(mpfr_t, const mpfr_t, mpfr_rnd_t)> + DLLLOCAL qore_number_private* doCalcUnary() const { qore_number_private* p = new qore_number_private(*this); - mpfr_neg(p->num, p->num, QORE_MPFR_RND); + F(p->num, num, QORE_MPFR_RND); return p; } + DLLLOCAL qore_number_private* negate() const { + return doCalcUnary<mpfr_neg>(); + } + DLLLOCAL qore_number_private* absolute() const { - qore_number_private* p = new qore_number_private(*this); - mpfr_abs(p->num, p->num, QORE_MPFR_RND); - return p; + return doCalcUnary<mpfr_abs>(); } DLLLOCAL void inc() { @@ -247,33 +244,29 @@ mpfr_sub_si(num, tmp, 1, QORE_MPFR_RND); } - DLLLOCAL void plusEquals(const qore_number_private& r) { + template <int (*F)(mpfr_t, const mpfr_t, const mpfr_t, mpfr_rnd_t)> + DLLLOCAL void doCalcArgInplace(const qore_number_private& r) { checkPrec(r.num); MPFR_DECL_INIT(tmp, mpfr_get_prec(num)); mpfr_set(tmp, num, QORE_MPFR_RND); - mpfr_add(num, tmp, r.num, QORE_MPFR_RND); + F(num, tmp, r.num, QORE_MPFR_RND); } + DLLLOCAL void plusEquals(const qore_number_private& r) { + doCalcArgInplace<mpfr_add>(r); + } + DLLLOCAL void minusEquals(const qore_number_private& r) { - checkPrec(r.num); - MPFR_DECL_INIT(tmp, mpfr_get_prec(num)); - mpfr_set(tmp, num, QORE_MPFR_RND); - mpfr_sub(num, tmp, r.num, QORE_MPFR_RND); + doCalcArgInplace<mpfr_sub>(r); } DLLLOCAL void multiplyEquals(const qore_number_private& r) { - checkPrec(r.num); - MPFR_DECL_INIT(tmp, mpfr_get_prec(num)); - mpfr_set(tmp, num, QORE_MPFR_RND); - mpfr_mul(num, tmp, r.num, QORE_MPFR_RND); + doCalcArgInplace<mpfr_mul>(r); } DLLLOCAL void divideEquals(const qore_number_private& r) { assert(!r.zero()); - checkPrec(r.num); - MPFR_DECL_INIT(tmp, mpfr_get_prec(num)); - mpfr_set(tmp, num, QORE_MPFR_RND); - mpfr_div(num, tmp, r.num, QORE_MPFR_RND); + doCalcArgInplace<mpfr_div>(r); } // static accessor methods This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <david_nichols@us...> - 2012-09-12 11:01:00
|
Revision: 5033 http://qore.svn.sourceforge.net/qore/?rev=5033&view=rev Author: david_nichols Date: 2012-09-12 11:00:51 +0000 (Wed, 12 Sep 2012) Log Message: ----------- fixed QoreUnaryMinusOperatorNode::makeNode() for the "number" type Modified Paths: -------------- qore/trunk/lib/QoreUnaryMinusOperatorNode.cpp Modified: qore/trunk/lib/QoreUnaryMinusOperatorNode.cpp =================================================================== --- qore/trunk/lib/QoreUnaryMinusOperatorNode.cpp 2012-09-12 10:57:26 UTC (rev 5032) +++ qore/trunk/lib/QoreUnaryMinusOperatorNode.cpp 2012-09-12 11:00:51 UTC (rev 5033) @@ -133,9 +133,12 @@ } // static function -AbstractQoreNode *QoreUnaryMinusOperatorNode::makeNode(AbstractQoreNode *v) { +AbstractQoreNode* QoreUnaryMinusOperatorNode::makeNode(AbstractQoreNode *v) { if (v) { assert(v->is_unique()); + if (v->getType() == NT_NUMBER) + return reinterpret_cast<QoreNumberNode*>(v)->negate(); + if (v->getType() == NT_FLOAT) { QoreFloatNode *f = reinterpret_cast<QoreFloatNode *>(v); f->f = -f->f; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <david_nichols@us...> - 2012-09-12 10:57:37
|
Revision: 5032 http://qore.svn.sourceforge.net/qore/?rev=5032&view=rev Author: david_nichols Date: 2012-09-12 10:57:26 +0000 (Wed, 12 Sep 2012) Log Message: ----------- fixed the unary minus operator with "number" values Modified Paths: -------------- qore/trunk/include/qore/intern/qore_number_private.h qore/trunk/lib/QoreUnaryMinusOperatorNode.cpp Modified: qore/trunk/include/qore/intern/qore_number_private.h =================================================================== --- qore/trunk/include/qore/intern/qore_number_private.h 2012-09-12 10:45:15 UTC (rev 5031) +++ qore/trunk/include/qore/intern/qore_number_private.h 2012-09-12 10:57:26 UTC (rev 5032) @@ -224,11 +224,17 @@ } DLLLOCAL qore_number_private* negate() const { - qore_number_private* p = new qore_number_private(mpfr_get_prec(num)); - mpfr_neg(p->num, num, QORE_MPFR_RND); + qore_number_private* p = new qore_number_private(*this); + mpfr_neg(p->num, p->num, QORE_MPFR_RND); return p; } + DLLLOCAL qore_number_private* absolute() const { + qore_number_private* p = new qore_number_private(*this); + mpfr_abs(p->num, p->num, QORE_MPFR_RND); + return p; + } + DLLLOCAL void inc() { MPFR_DECL_INIT(tmp, mpfr_get_prec(num)); mpfr_set(tmp, num, QORE_MPFR_RND); Modified: qore/trunk/lib/QoreUnaryMinusOperatorNode.cpp =================================================================== --- qore/trunk/lib/QoreUnaryMinusOperatorNode.cpp 2012-09-12 10:45:15 UTC (rev 5031) +++ qore/trunk/lib/QoreUnaryMinusOperatorNode.cpp 2012-09-12 10:57:26 UTC (rev 5032) @@ -41,6 +41,8 @@ return 0; if (v) { + if (v->getType() == NT_NUMBER) + return reinterpret_cast<const QoreNumberNode*>(*v)->negate(); if (v->getType() == NT_FLOAT) return new QoreFloatNode(-reinterpret_cast<const QoreFloatNode *>(*v)->f); if (v->getType() == NT_DATE) @@ -89,6 +91,10 @@ typeInfo = bigIntTypeInfo; return new QoreBigIntNode(-reinterpret_cast<const QoreBigIntNode *>(exp)->val); } + if (t == NT_NUMBER) { + typeInfo = numberTypeInfo; + return reinterpret_cast<const QoreNumberNode*>(exp)->negate(); + } if (t == NT_FLOAT) { typeInfo = floatTypeInfo; return new QoreFloatNode(-reinterpret_cast<const QoreFloatNode *>(exp)->f); @@ -104,6 +110,8 @@ if (typeInfo->hasType()) { if (typeInfo->isType(NT_FLOAT)) typeInfo = floatTypeInfo; + else if (typeInfo->isType(NT_NUMBER)) + typeInfo = numberTypeInfo; else if (typeInfo->isType(NT_DATE)) typeInfo = dateTypeInfo; else if (typeInfo->isType(NT_INT)) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <david_nichols@us...> - 2012-09-12 10:45:25
|
Revision: 5031 http://qore.svn.sourceforge.net/qore/?rev=5031&view=rev Author: david_nichols Date: 2012-09-12 10:45:15 +0000 (Wed, 12 Sep 2012) Log Message: ----------- * added MPFR info to the qore -V output * fixed number outputs with negative numbers and special numbers (@inf@ and @nan@ etc) Modified Paths: -------------- qore/trunk/command-line.cpp qore/trunk/include/qore/Qore.h qore/trunk/include/qore/QoreString.h qore/trunk/include/qore/intern/qore_number_private.h qore/trunk/lib/QoreLib.cpp qore/trunk/lib/QoreString.cpp qore/trunk/lib/qore-main.cpp Modified: qore/trunk/command-line.cpp =================================================================== --- qore/trunk/command-line.cpp 2012-09-11 16:15:18 UTC (rev 5030) +++ qore/trunk/command-line.cpp 2012-09-12 10:45:15 UTC (rev 5031) @@ -472,8 +472,8 @@ printf(")\n"); } - printf(" build host: %s\n C++ compiler: %s\n CFLAGS: %s\n LDFLAGS: %s\n", - qore_build_host, qore_cplusplus_compiler, qore_cflags, qore_ldflags); + printf(" build host: %s\n C++ compiler: %s\n CFLAGS: %s\n LDFLAGS: %s\n MPFR: %s\n", + qore_build_host, qore_cplusplus_compiler, qore_cflags, qore_ldflags, mpfrInfo.getBuffer()); printf("this build has options:\n"); // find longest option name Modified: qore/trunk/include/qore/Qore.h =================================================================== --- qore/trunk/include/qore/Qore.h 2012-09-11 16:15:18 UTC (rev 5030) +++ qore/trunk/include/qore/Qore.h 2012-09-12 10:45:15 UTC (rev 5031) @@ -84,7 +84,7 @@ #include <qore/qore-version.h> //! the complete version string of the qore library -DLLEXPORT extern const char *qore_version_string; +DLLEXPORT extern const char* qore_version_string; //! the major version number of the qore library DLLEXPORT extern int qore_version_major; @@ -102,26 +102,31 @@ DLLEXPORT extern int qore_target_bits; //! the build target Operating System name -DLLEXPORT extern const char *qore_target_os; +DLLEXPORT extern const char* qore_target_os; //! the build target machine architecture name -DLLEXPORT extern const char *qore_target_arch; +DLLEXPORT extern const char* qore_target_arch; //! the qore module directory -DLLEXPORT extern const char *qore_module_dir; +DLLEXPORT extern const char* qore_module_dir; //! the c++ compiler used to build qore -DLLEXPORT extern const char *qore_cplusplus_compiler; +DLLEXPORT extern const char* qore_cplusplus_compiler; //! the compiler flags used to build qore -DLLEXPORT extern const char *qore_cflags; +DLLEXPORT extern const char* qore_cflags; //! the linker flags used to link qore -DLLEXPORT extern const char *qore_ldflags; +DLLEXPORT extern const char* qore_ldflags; //! information about the build host -DLLEXPORT extern const char *qore_build_host; +DLLEXPORT extern const char* qore_build_host; +//! information about the MPFR library used by the qore library +/** this pointer is null until after qore_init() has been called + */ +DLLEXPORT extern const char* qore_mpfr_info; + //! if the qore library includes debugging or not DLLEXPORT bool qore_has_debug(); @@ -131,6 +136,9 @@ //! the recommended minimum module api minor number to use DLLEXPORT extern int qore_min_mod_api_minor; +//! a string giving information about the MPFR library used by the qore library +DLLEXPORT extern const QoreStringMaker mpfrInfo; + #define QLO_NONE 0 //!< no options (default) #define QLO_DISABLE_SIGNAL_HANDLING 1 << 0 //!< disable qore signal handling entirely @@ -144,7 +152,7 @@ @note The license value must be QL_LGPL unless the program using Qore is a GPL program, in which case QL_GPL may be used (the default) @see qore_cleanup() */ -DLLEXPORT void qore_init(qore_license_t license = QL_GPL, const char *default_encoding = 0, bool show_module_errors = false, int init_options = QLO_NONE); +DLLEXPORT void qore_init(qore_license_t license = QL_GPL, const char* default_encoding = 0, bool show_module_errors = false, int init_options = QLO_NONE); //! frees all memory allocated by the library /** @note The openssl library is cleaned up as well Modified: qore/trunk/include/qore/QoreString.h =================================================================== --- qore/trunk/include/qore/QoreString.h 2012-09-11 16:15:18 UTC (rev 5030) +++ qore/trunk/include/qore/QoreString.h 2012-09-12 10:45:15 UTC (rev 5031) @@ -627,6 +627,18 @@ DLLEXPORT QoreString* checkEncoding(const QoreString* str, const QoreEncoding* enc, ExceptionSink* xsink); +class QoreStringMaker : public QoreString { +private: + //! this function is not implemented; it is here as a private function in order to prohibit it from being used + DLLLOCAL QoreStringMaker(const QoreStringMaker& str); + + //! this function is not implemented; it is here as a private function in order to prohibit it from being used + DLLLOCAL QoreStringMaker& operator=(const QoreStringMaker&); + +public: + DLLLOCAL QoreStringMaker(const char* fmt, ...); +}; + //! class used to hold a possibly temporary QoreString pointer, stack only, cannot be dynamically allocated /** @code Modified: qore/trunk/include/qore/intern/qore_number_private.h =================================================================== --- qore/trunk/include/qore/intern/qore_number_private.h 2012-09-11 16:15:18 UTC (rev 5030) +++ qore/trunk/include/qore/intern/qore_number_private.h 2012-09-12 10:45:15 UTC (rev 5031) @@ -108,8 +108,12 @@ return (bool)mpfr_regular_p(num); } + DLLLOCAL int sign() const { + return mpfr_sgn(num); + } + DLLLOCAL void getAsString(QoreString& str) const { - // first check if it's zero + // first check for zero if (zero()) { str.concat("0n"); return; @@ -135,7 +139,8 @@ // if it's a regular number, then format accordingly if (number()) { - qore_size_t len = str.size(); + int sgn = sign(); + qore_size_t len = str.size() + (sgn < 0 ? 1 : 0); //printd(0, "QoreNumberNode::getAsString() this: %p '%s' exp "QLLD" len: "QLLD"\n", this, buf, exp, len); str.concat(buf); @@ -162,6 +167,8 @@ } str.concat('n'); } + else + str.concat(buf); mpfr_free_str(buf); #endif Modified: qore/trunk/lib/QoreLib.cpp =================================================================== --- qore/trunk/lib/QoreLib.cpp 2012-09-11 16:15:18 UTC (rev 5030) +++ qore/trunk/lib/QoreLib.cpp 2012-09-12 10:45:15 UTC (rev 5031) @@ -42,25 +42,25 @@ #define cpp_xstr(s) cpp_str(s) // global library variables -const char *qore_version_string = VERSION "-" cpp_xstr(BUILD); +const char* qore_version_string = VERSION "-" cpp_xstr(BUILD); int qore_version_major = VERSION_MAJOR; int qore_version_minor = VERSION_MINOR; int qore_version_sub = VERSION_SUB; int qore_build_number = BUILD; int qore_target_bits = TARGET_BITS; -const char *qore_target_os = TARGET_OS; -const char *qore_target_arch = TARGET_ARCH; -const char *qore_module_dir = MODULE_DIR; -const char *qore_cplusplus_compiler = QORE_LIB_CXX; -const char *qore_cflags = QORE_LIB_CFLAGS; -const char *qore_ldflags = QORE_LIB_LDFLAGS; -const char *qore_build_host = QORE_BUILD_HOST; +const char* qore_target_os = TARGET_OS; +const char* qore_target_arch = TARGET_ARCH; +const char* qore_module_dir = MODULE_DIR; +const char* qore_cplusplus_compiler = QORE_LIB_CXX; +const char* qore_cflags = QORE_LIB_CFLAGS; +const char* qore_ldflags = QORE_LIB_LDFLAGS; +const char* qore_build_host = QORE_BUILD_HOST; int qore_min_mod_api_major = QORE_MODULE_COMPAT_API_MAJOR; int qore_min_mod_api_minor = QORE_MODULE_COMPAT_API_MINOR; -DLLLOCAL QoreListNode *ARGV = 0; -DLLLOCAL QoreListNode *QORE_ARGV = 0; +DLLLOCAL QoreListNode* ARGV = 0; +DLLLOCAL QoreListNode* QORE_ARGV = 0; #ifndef HAVE_LOCALTIME_R DLLLOCAL QoreThreadLock lck_localtime; @@ -350,7 +350,7 @@ size_t qore_option_list_size = QORE_OPTION_LIST_SIZE; -static inline int get_number(char **param) { +static inline int get_number(char* *param) { int num = 0; while (isdigit(**param)) { num = num*10 + (**param - '0'); @@ -387,8 +387,8 @@ } // if type = 0 then field widths are soft limits, otherwise they are hard -static int process_opt(QoreString *cstr, char *param, const AbstractQoreNode *node, int type, int *taken, ExceptionSink *xsink) { - char *str = param; +static int process_opt(QoreString *cstr, char* param, const AbstractQoreNode* node, int type, int *taken, ExceptionSink *xsink) { + char* str = param; int opts = 0; int width = -1; int decimals = -1; @@ -400,7 +400,7 @@ param, type, node, node ? node->getTypeName() : "(null)", node ? node->reference_count() : -1); #ifdef DEBUG if (node && node->getType() == NT_STRING) { - const QoreStringNode *nstr = reinterpret_cast<const QoreStringNode *>(node); + const QoreStringNode* nstr = reinterpret_cast<const QoreStringNode* >(node); printd(5, "process_opt() %08p (%d) \"%s\"\n", nstr->getBuffer(), nstr->strlen(), nstr->getBuffer()); } #endif @@ -553,9 +553,9 @@ return (int)(param - str); } -QoreStringNode *q_sprintf(const QoreListNode *params, int field, int offset, ExceptionSink *xsink) { +QoreStringNode* q_sprintf(const QoreListNode* params, int field, int offset, ExceptionSink *xsink) { unsigned i, j, l; - const QoreStringNode *p; + const QoreStringNode* p; if (!(p = test_string_param(params, offset))) return new QoreStringNode(); @@ -564,13 +564,13 @@ j = 1 + offset; - const char *pstr = p->getBuffer(); + const char* pstr = p->getBuffer(); l = strlen(pstr); for (i = 0; i < l; i++) { int taken = 1; if ((pstr[i] == '%') && (j < params->size())) { - const AbstractQoreNode *node = get_param(params, j++); - i += process_opt(*buf, (char *)&pstr[i], node, field, &taken, xsink); + const AbstractQoreNode* node = get_param(params, j++); + i += process_opt(*buf, (char* )&pstr[i], node, field, &taken, xsink); if (*xsink) return 0; if (!taken) @@ -586,15 +586,15 @@ return buf.release(); } -QoreStringNode *q_vsprintf(const QoreListNode *params, int field, int offset, ExceptionSink *xsink) { - const QoreStringNode *fmt; - const AbstractQoreNode *args; +QoreStringNode* q_vsprintf(const QoreListNode* params, int field, int offset, ExceptionSink *xsink) { + const QoreStringNode* fmt; + const AbstractQoreNode* args; if (!(fmt = test_string_param(params, offset))) return new QoreStringNode(); args = get_param(params, offset + 1); - const QoreListNode *arg_list = dynamic_cast<const QoreListNode *>(args); + const QoreListNode* arg_list = dynamic_cast<const QoreListNode* >(args); SimpleRefHolder<QoreStringNode> buf(new QoreStringNode(fmt->getEncoding())); unsigned j = 0; @@ -602,7 +602,7 @@ for (unsigned i = 0; i < l; i++) { int taken = 1; bool havearg = false; - const AbstractQoreNode *arg = 0; + const AbstractQoreNode* arg = 0; if ((fmt->getBuffer()[i] == '%')) { if (args) { @@ -618,7 +618,7 @@ } } if (havearg) { - i += process_opt(*buf, (char *)&fmt->getBuffer()[i], arg, field, &taken, xsink); + i += process_opt(*buf, (char* )&fmt->getBuffer()[i], arg, field, &taken, xsink); if (*xsink) return 0; if (!taken) @@ -636,7 +636,7 @@ str.sprintf(" ('%c')", c); } -static inline char getBase64Value(const char *buf, qore_size_t &offset, bool end_ok, ExceptionSink *xsink) { +static inline char getBase64Value(const char* buf, qore_size_t &offset, bool end_ok, ExceptionSink *xsink) { while (buf[offset] == '\n' || buf[offset] == '\r') ++offset; @@ -658,7 +658,7 @@ xsink->raiseException("BASE64-PARSE-ERROR", "premature end of base64 string at string byte offset %d", offset); } else { - QoreStringNode *desc = new QoreStringNode; + QoreStringNode* desc = new QoreStringNode; concatASCII(*desc, c); desc->concat(" is an invalid base64 character"); xsink->raiseException("BASE64-PARSE-ERROR", desc); @@ -667,8 +667,8 @@ } // see: RFC-1421: http://www.ietf.org/rfc/rfc1421.txt and RFC-2045: http://www.ietf.org/rfc/rfc2045.txt -BinaryNode *parseBase64(const char *buf, int len, ExceptionSink *xsink) { - char *binbuf = (char *)malloc(sizeof(char) * (len + 3)); +BinaryNode* parseBase64(const char* buf, int len, ExceptionSink *xsink) { + char* binbuf = (char* )malloc(sizeof(char) * (len + 3)); int blen = 0; qore_size_t pos = 0; @@ -743,7 +743,7 @@ return -1; } -BinaryNode *parseHex(const char *buf, int len, ExceptionSink *xsink) { +BinaryNode* parseHex(const char* buf, int len, ExceptionSink *xsink) { if (!len) return new BinaryNode(); @@ -752,10 +752,10 @@ return 0; } - char *binbuf = (char *)malloc(sizeof(char) * (len / 2)); + char* binbuf = (char* )malloc(sizeof(char) * (len / 2)); int blen = 0; - const char *end = buf + len; + const char* end = buf + len; while (buf < end) { int b = get_nibble(*buf, xsink); if (b < 0) { @@ -787,14 +787,14 @@ } // for use while parsing - parses a null-terminated string and raises parse exceptions for errors -BinaryNode *parseHex(const char *buf, int len) { +BinaryNode* parseHex(const char* buf, int len) { if (!buf || !(*buf)) return new BinaryNode(); - char *binbuf = (char *)malloc(sizeof(char) * (len / 2)); + char* binbuf = (char* )malloc(sizeof(char) * (len / 2)); int blen = 0; - const char *end = buf + len; + const char* end = buf + len; while (buf < end) { int b = parse_get_nibble(*buf); if (b < 0) { @@ -822,9 +822,9 @@ return new BinaryNode(binbuf, blen); } -char *make_class_name(const char *str) { - char *cn = q_basename(str); - char *p = strrchr(cn, '.'); +char* make_class_name(const char* str) { + char* cn = q_basename(str); + char* p = strrchr(cn, '.'); if (p && p != cn) *p = '\0'; p = cn; @@ -836,13 +836,13 @@ return cn; } -void print_node(FILE *fp, const AbstractQoreNode *node) { +void print_node(FILE *fp, const AbstractQoreNode* node) { printd(5, "print_node() node=%08p (%s)\n", node, node ? node->getTypeName() : "(null)"); QoreStringValueHelper str(node); fputs(str->getBuffer(), fp); } -void qore_setup_argv(int pos, int argc, char *argv[]) { +void qore_setup_argv(int pos, int argc, char* argv[]) { ARGV = new QoreListNode(); QORE_ARGV = new QoreListNode(); int end = argc - pos; @@ -853,12 +853,12 @@ } } -void init_lib_intern(char *env[]) { +void init_lib_intern(char* env[]) { // set up environment hash int i = 0; ENV = new QoreHashNode; while (env[i]) { - char *p; + char* p; if ((p = strchr(env[i], '='))) { char save = *p; @@ -921,31 +921,31 @@ } // thread-safe basename function (resulting pointer must be free()ed) -char *q_basename(const char *path) { - const char *p = strrchr(path, QORE_DIR_SEP); +char* q_basename(const char* path) { + const char* p = strrchr(path, QORE_DIR_SEP); if (!p) return strdup(path); return strdup(p + 1); } // returns a pointer within the same string -char *q_basenameptr(const char *path) { - const char *p = strrchr(path, QORE_DIR_SEP); +char* q_basenameptr(const char* path) { + const char* p = strrchr(path, QORE_DIR_SEP); if (!p) - return (char *)path; - return (char *)p + 1; + return (char* )path; + return (char* )p + 1; } // thread-safe basename function (resulting pointer must be free()ed) -char *q_dirname(const char *path) { - const char *p = strrchr(path, QORE_DIR_SEP); +char* q_dirname(const char* path) { + const char* p = strrchr(path, QORE_DIR_SEP); if (!p || p == path) { - char *x = (char *)malloc(sizeof(char) * 2); + char* x = (char* )malloc(sizeof(char) * 2); x[0] = !p ? '.' : QORE_DIR_SEP; x[1] = '\0'; return x; } - char *x = (char *)malloc(sizeof(char) * (p - path + 1)); + char* x = (char* )malloc(sizeof(char) * (p - path + 1)); strncpy(x, path, p - path); x[p - path] = '\0'; return x; @@ -958,17 +958,17 @@ return p; } -static inline void assign_hv(QoreHashNode *h, const char *key, char *val) { +static inline void assign_hv(QoreHashNode* h, const char* key, char* val) { h->setKeyValue(key, new QoreStringNode(val), 0); } -static inline void assign_hv(QoreHashNode *h, const char *key, int val) { +static inline void assign_hv(QoreHashNode* h, const char* key, int val) { h->setKeyValue(key, new QoreBigIntNode(val), 0); } #ifdef HAVE_PWD_H -static QoreHashNode *pwd2hash(const struct passwd &pw) { - QoreHashNode *h = new QoreHashNode; +static QoreHashNode* pwd2hash(const struct passwd &pw) { + QoreHashNode* h = new QoreHashNode; // assign values assign_hv(h, "pw_name", pw.pw_name); assign_hv(h, "pw_passwd", pw.pw_passwd); @@ -980,11 +980,11 @@ return h; } -QoreHashNode *q_getpwuid(uid_t uid) { +QoreHashNode* q_getpwuid(uid_t uid) { struct passwd *pw; #ifdef HAVE_GETPWUID_R struct passwd pw_rec; - char *buf = (char *)malloc(pwsize * sizeof(char)); + char* buf = (char* )malloc(pwsize * sizeof(char)); ON_BLOCK_EXIT(free, buf); int rc = getpwuid_r(uid, &pw_rec, buf, pwsize, &pw); if (rc) @@ -996,11 +996,11 @@ return !pw ? 0 : pwd2hash(*pw); } -QoreHashNode *q_getpwnam(const char *name) { +QoreHashNode* q_getpwnam(const char* name) { struct passwd *pw; #ifdef HAVE_GETPWNAM_R struct passwd pw_rec; - char *buf = (char *)malloc(pwsize * sizeof(char)); + char* buf = (char* )malloc(pwsize * sizeof(char)); ON_BLOCK_EXIT(free, buf); int rc = getpwnam_r(name, &pw_rec, buf, pwsize, &pw); if (rc) @@ -1012,11 +1012,11 @@ return !pw ? 0 : pwd2hash(*pw); } -int q_uname2uid(const char *name, uid_t &uid) { +int q_uname2uid(const char* name, uid_t &uid) { struct passwd *pw; #ifdef HAVE_GETPWNAM_R struct passwd pw_rec; - char *buf = (char *)malloc(pwsize * sizeof(char)); + char* buf = (char* )malloc(pwsize * sizeof(char)); ON_BLOCK_EXIT(free, buf); int rc = getpwnam_r(name, &pw_rec, buf, pwsize, &pw); if (!rc) @@ -1032,26 +1032,26 @@ #endif } -static QoreHashNode *gr2hash(struct group &gr) { - QoreHashNode *h = new QoreHashNode; +static QoreHashNode* gr2hash(struct group &gr) { + QoreHashNode* h = new QoreHashNode; // assign values assign_hv(h, "gr_name", gr.gr_name); assign_hv(h, "gr_passwd", gr.gr_passwd); assign_hv(h, "gr_gid", gr.gr_gid); - QoreListNode *l = new QoreListNode; - for (char **p = gr.gr_mem; *p; ++p) + QoreListNode* l = new QoreListNode; + for (char* *p = gr.gr_mem; *p; ++p) l->push(new QoreStringNode(*p)); h->setKeyValue("gr_mem", l, 0); return h; } -QoreHashNode *q_getgrgid(gid_t gid) { +QoreHashNode* q_getgrgid(gid_t gid) { struct group *gr; #ifdef HAVE_GETGRGID_R struct group gr_rec; - char *buf = (char *)malloc(grsize * sizeof(char)); + char* buf = (char* )malloc(grsize * sizeof(char)); ON_BLOCK_EXIT(free, buf); int rc = getgrgid_r(gid, &gr_rec, buf, grsize, &gr); if (rc) @@ -1063,11 +1063,11 @@ return !gr ? 0 : gr2hash(*gr); } -QoreHashNode *q_getgrnam(const char *name) { +QoreHashNode* q_getgrnam(const char* name) { struct group *gr; #ifdef HAVE_GETGRNAM_R struct group gr_rec; - char *buf = (char *)malloc(grsize * sizeof(char)); + char* buf = (char* )malloc(grsize * sizeof(char)); ON_BLOCK_EXIT(free, buf); int rc = getgrnam_r(name, &gr_rec, buf, grsize, &gr); if (rc) @@ -1079,11 +1079,11 @@ return !gr ? 0 : gr2hash(*gr); } -int q_gname2gid(const char *name, gid_t &gid) { +int q_gname2gid(const char* name, gid_t &gid) { struct group *gr; #ifdef HAVE_GETGRNAM_R struct group gr_rec; - char *buf = (char *)malloc(grsize * sizeof(char)); + char* buf = (char* )malloc(grsize * sizeof(char)); ON_BLOCK_EXIT(free, buf); int rc = getgrnam_r(name, &gr_rec, buf, grsize, &gr); if (!rc) @@ -1104,7 +1104,7 @@ return qore_license; } -long long q_atoll(const char *str) { +long long q_atoll(const char* str) { return atoll(str); } @@ -1170,13 +1170,13 @@ return ts.tv_sec; } -QoreListNode *makeArgs(AbstractQoreNode *arg) { +QoreListNode* makeArgs(AbstractQoreNode* arg) { if (!arg) return 0; - QoreListNode *l; + QoreListNode* l; if (arg->getType() == NT_LIST) { - l = reinterpret_cast<QoreListNode *>(arg); + l = reinterpret_cast<QoreListNode* >(arg); if (!l->isFinalized()) return l; } @@ -1186,8 +1186,8 @@ return l; } -const char *check_hash_key(const QoreHashNode *h, const char *key, const char *err, ExceptionSink *xsink) { - const AbstractQoreNode *p = h->getKeyValue(key); +const char* check_hash_key(const QoreHashNode* h, const char* key, const char* err, ExceptionSink *xsink) { + const AbstractQoreNode* p = h->getKeyValue(key); if (is_nothing(p)) return 0; @@ -1195,7 +1195,7 @@ xsink->raiseException(err, "'%s' key is not type 'string' but is type '%s'", key, get_type_name(p)); return 0; } - return reinterpret_cast<const QoreStringNode *>(p)->getBuffer(); + return reinterpret_cast<const QoreStringNode* >(p)->getBuffer(); } void q_strerror(QoreString &str, int err) { @@ -1210,10 +1210,10 @@ #if defined(_GNU_SOURCE) && defined(LINUX) // we can't help but get this version because some of the Linux // header files define _GNU_SOURCE for us :-( - str.concat(strerror_r(err, (char *)(str.getBuffer() + str.strlen()), STRERR_BUFSIZE)); + str.concat(strerror_r(err, (char* )(str.getBuffer() + str.strlen()), STRERR_BUFSIZE)); #else // use portable XSI version of strerror_r() - int rc = strerror_r(err, (char *)(str.getBuffer() + str.strlen()), STRERR_BUFSIZE); + int rc = strerror_r(err, (char* )(str.getBuffer() + str.strlen()), STRERR_BUFSIZE); if (rc && rc != EINVAL && rc != ERANGE) str.sprintf("unable to retrieve error code %d: strerror() returned unexpected error code %d", err, rc); else @@ -1229,20 +1229,20 @@ #endif } -QoreStringNode *q_strerror(int err) { - QoreStringNode *rv = new QoreStringNode; +QoreStringNode* q_strerror(int err) { + QoreStringNode* rv = new QoreStringNode; q_strerror(*rv, err); return rv; } #ifdef HAVE_SIGNAL_HANDLING -QoreStringNode *qore_reassign_signal(int sig, const char *name) { +QoreStringNode* qore_reassign_signal(int sig, const char* name) { return QSM.reassign_signal(sig, name); } #endif /* -static int qoreCheckHash(QoreHashNode *h, ObjMap &omap, AutoVLock &vl, ExceptionSink *xsink) { +static int qoreCheckHash(QoreHashNode* h, ObjMap &omap, AutoVLock &vl, ExceptionSink *xsink) { int rc = 0; HashIterator hi(h); @@ -1253,7 +1253,7 @@ return rc; } -static int qoreCheckList(QoreListNode *l, ObjMap &omap, AutoVLock &vl, ExceptionSink *xsink) { +static int qoreCheckList(QoreListNode* l, ObjMap &omap, AutoVLock &vl, ExceptionSink *xsink) { int rc = 0; ListIterator li(l); @@ -1264,7 +1264,7 @@ return rc; } -int qoreCheckContainer(AbstractQoreNode *v, ObjMap &omap, AutoVLock &vl, ExceptionSink *xsink) { +int qoreCheckContainer(AbstractQoreNode* v, ObjMap &omap, AutoVLock &vl, ExceptionSink *xsink) { printd(0, "qoreCheckContainer() v=%p (%s) omap size=%d\n", v, get_type_name(v), omap.size()); if (!v || omap.empty()) return 0; @@ -1279,21 +1279,21 @@ } if (t == NT_HASH) - return qoreCheckHash(reinterpret_cast<QoreHashNode *>(v), omap, vl, xsink); + return qoreCheckHash(reinterpret_cast<QoreHashNode* >(v), omap, vl, xsink); if (t == NT_LIST) - return qoreCheckList(reinterpret_cast<QoreListNode *>(v), omap, vl, xsink); + return qoreCheckList(reinterpret_cast<QoreListNode* >(v), omap, vl, xsink); return 0; } -void ObjMap::set(QoreObject *obj, const char *key) { +void ObjMap::set(QoreObject *obj, const char* key) { assert(omap.find(obj) == omap.end()); obj_map_t::iterator i = omap.insert(obj_map_t::value_type(obj, key)).first; ovec.push_back(i); } -void ObjMap::reset(QoreObject *obj, const char *key) { +void ObjMap::reset(QoreObject *obj, const char* key) { obj_map_t::iterator i = omap.find(obj); if (i == omap.end()) { set(obj, key); @@ -1352,14 +1352,14 @@ */ // returns 0 for OK, -1 for error -int check_lvalue(const AbstractQoreNode *node) { +int check_lvalue(const AbstractQoreNode* node) { qore_type_t ntype = node->getType(); //printd(5, "type=%s\n", node->getTypeName()); if (ntype == NT_VARREF || ntype == NT_SELF_VARREF || ntype == NT_CLASS_VARREF) return 0; if (ntype == NT_TREE) { - const QoreTreeNode *t = reinterpret_cast<const QoreTreeNode *>(node); + const QoreTreeNode* t = reinterpret_cast<const QoreTreeNode* >(node); if (t->getOp() == OP_LIST_REF || t->getOp() == OP_OBJECT_REF) return check_lvalue(t->left); else @@ -1381,8 +1381,8 @@ #endif } -QoreListNode *stat_to_list(const struct stat &sbuf) { - QoreListNode *l = new QoreListNode; +QoreListNode* stat_to_list(const struct stat &sbuf) { + QoreListNode* l = new QoreListNode; // note that dev_t on Linux is an unsigned 64-bit integer, so we could lose precision here l->push(new QoreBigIntNode((int64)sbuf.st_dev)); @@ -1407,8 +1407,8 @@ return l; } -QoreHashNode *stat_to_hash(const struct stat &sbuf) { - QoreHashNode *h = new QoreHashNode; +QoreHashNode* stat_to_hash(const struct stat &sbuf) { + QoreHashNode* h = new QoreHashNode; // note that dev_t on Linux is an unsigned 64-bit integer, so we could lose precision here h->setKeyValue("dev", new QoreBigIntNode((int64)sbuf.st_dev), 0); @@ -1431,9 +1431,9 @@ h->setKeyValue("blocks", new QoreBigIntNode(blocks), 0); // process permissions - QoreStringNode *perm = new QoreStringNode; + QoreStringNode* perm = new QoreStringNode; - const char *type; + const char* type; if (S_ISBLK(sbuf.st_mode)) { type = "BLOCK-DEVICE"; perm->concat('b'); @@ -1523,8 +1523,8 @@ } #ifdef HAVE_SYS_STATVFS_H -QoreHashNode *statvfs_to_hash(const struct statvfs &vfs) { - QoreHashNode *h = new QoreHashNode; +QoreHashNode* statvfs_to_hash(const struct statvfs &vfs) { + QoreHashNode* h = new QoreHashNode; #ifdef DARWIN #else Modified: qore/trunk/lib/QoreString.cpp =================================================================== --- qore/trunk/lib/QoreString.cpp 2012-09-11 16:15:18 UTC (rev 5030) +++ qore/trunk/lib/QoreString.cpp 2012-09-12 10:45:15 UTC (rev 5031) @@ -53,6 +53,18 @@ #define NUM_HTML_CODES (sizeof(html_codes) / sizeof (struct code_table)) +QoreStringMaker::QoreStringMaker(const char* fmt, ...) { + va_list args; + + while (true) { + va_start(args, fmt); + int rc = vsprintf(fmt, args); + va_end(args); + if (!rc) + break; + } +} + QoreString::QoreString() : priv(new qore_string_private) { priv->len = 0; priv->allocated = STR_CLASS_BLOCK; Modified: qore/trunk/lib/qore-main.cpp =================================================================== --- qore/trunk/lib/qore-main.cpp 2012-09-11 16:15:18 UTC (rev 5030) +++ qore/trunk/lib/qore-main.cpp 2012-09-12 10:45:15 UTC (rev 5031) @@ -51,6 +51,9 @@ qore_license_t qore_license; +const QoreStringMaker mpfrInfo("runtime: %s built with: %s (%d.%d.%d)", mpfr_get_version(), MPFR_VERSION_STRING, MPFR_VERSION_MAJOR, + MPFR_VERSION_MINOR, MPFR_VERSION_PATCHLEVEL); + void qore_init(qore_license_t license, const char *def_charset, bool show_module_errors, int n_qore_library_options) { qore_license = license; qore_library_options = n_qore_library_options; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <david_nichols@us...> - 2012-09-11 16:15:29
|
Revision: 5030 http://qore.svn.sourceforge.net/qore/?rev=5030&view=rev Author: david_nichols Date: 2012-09-11 16:15:18 +0000 (Tue, 11 Sep 2012) Log Message: ----------- * implemented most operators for number (all?) * implemented automatic conversions for number * removed unneeded "int" operator optimizations Modified Paths: -------------- qore/trunk/Makefile.am qore/trunk/include/qore/QoreLib.h qore/trunk/include/qore/QoreNumberNode.h qore/trunk/include/qore/intern/Operator.h qore/trunk/include/qore/intern/QoreLibIntern.h qore/trunk/include/qore/intern/QoreMultiplyEqualsOperatorNode.h qore/trunk/include/qore/intern/QoreOperatorNode.h qore/trunk/include/qore/intern/QorePostIncrementOperatorNode.h qore/trunk/include/qore/intern/QorePreIncrementOperatorNode.h qore/trunk/include/qore/intern/QoreTypeInfo.h qore/trunk/include/qore/intern/QoreValue.h qore/trunk/include/qore/intern/Variable.h qore/trunk/lib/Makefile.am qore/trunk/lib/Operator.cpp qore/trunk/lib/QoreDivideEqualsOperatorNode.cpp qore/trunk/lib/QoreMinusEqualsOperatorNode.cpp qore/trunk/lib/QoreMultiplyEqualsOperatorNode.cpp qore/trunk/lib/QoreNumberNode.cpp qore/trunk/lib/QorePlusEqualsOperatorNode.cpp qore/trunk/lib/QorePostDecrementOperatorNode.cpp qore/trunk/lib/QorePostIncrementOperatorNode.cpp qore/trunk/lib/QorePreDecrementOperatorNode.cpp qore/trunk/lib/QorePreIncrementOperatorNode.cpp qore/trunk/lib/QoreTypeInfo.cpp qore/trunk/lib/Variable.cpp qore/trunk/lib/scanner.lpp qore/trunk/lib/single-compilation-unit.cpp Added Paths: ----------- qore/trunk/include/qore/intern/qore_number_private.h Removed Paths: ------------- qore/trunk/include/qore/intern/QoreIntDivideEqualsOperatorNode.h qore/trunk/include/qore/intern/QoreIntMultiplyEqualsOperatorNode.h qore/trunk/lib/QoreIntDivideEqualsOperatorNode.cpp qore/trunk/lib/QoreIntMultiplyEqualsOperatorNode.cpp Modified: qore/trunk/Makefile.am =================================================================== --- qore/trunk/Makefile.am 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/Makefile.am 2012-09-11 16:15:18 UTC (rev 5030) @@ -282,6 +282,7 @@ include/qore/intern/QoreImplicitArgumentNode.h \ include/qore/intern/QoreImplicitElementNode.h \ include/qore/intern/qore_string_private.h \ + include/qore/intern/qore_number_private.h \ include/qore/intern/qore_date_private.h \ include/qore/intern/sql_statement_private.h \ include/qore/intern/qore_program_private.h \ @@ -310,9 +311,7 @@ include/qore/intern/QoreAndEqualsOperatorNode.h \ include/qore/intern/QoreModulaEqualsOperatorNode.h \ include/qore/intern/QoreMultiplyEqualsOperatorNode.h \ - include/qore/intern/QoreIntMultiplyEqualsOperatorNode.h \ include/qore/intern/QoreDivideEqualsOperatorNode.h \ - include/qore/intern/QoreIntDivideEqualsOperatorNode.h \ include/qore/intern/QoreXorEqualsOperatorNode.h \ include/qore/intern/QoreShiftLeftEqualsOperatorNode.h \ include/qore/intern/QoreShiftRightEqualsOperatorNode.h \ Modified: qore/trunk/include/qore/QoreLib.h =================================================================== --- qore/trunk/include/qore/QoreLib.h 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/include/qore/QoreLib.h 2012-09-11 16:15:18 UTC (rev 5030) @@ -72,6 +72,9 @@ //! defined because this version of Qore supports the DBI selectRow() function #define _QORE_HAS_DBI_SELECT_ROW 1 +//! defined because this version of Qore supports the number type (QoreNumberNode) +#define _QORE_HAS_NUMBER_TYPE 1 + // qore code flags #define QC_NO_FLAGS 0 //! no flag #define QC_NOOP (1 << 0) //! this variant is a noop, meaning it returns a constant value with the given argument types Modified: qore/trunk/include/qore/QoreNumberNode.h =================================================================== --- qore/trunk/include/qore/QoreNumberNode.h 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/include/qore/QoreNumberNode.h 2012-09-11 16:15:18 UTC (rev 5030) @@ -30,6 +30,7 @@ //! Qore's arbitrary-precision number value type, dynamically-allocated only, reference counted class QoreNumberNode : public SimpleValueQoreNode { + friend struct qore_number_private; private: //! returns the value as a bool DLLLOCAL virtual bool getAsBoolImpl() const; @@ -161,11 +162,29 @@ DLLEXPORT virtual const char* getTypeName() const; //! add the argument to this value and return the result - DLLEXPORT QoreNumberNode* doPlus(const QoreNumberNode* right) const; + DLLEXPORT QoreNumberNode* doPlus(const QoreNumberNode& n) const; + //! add the argument to this value and return the result + DLLEXPORT QoreNumberNode* doMinus(const QoreNumberNode& n) const; + + //! add the argument to this value and return the result + DLLEXPORT QoreNumberNode* doMultiply(const QoreNumberNode& n) const; + + //! add the argument to this value and return the result + DLLEXPORT QoreNumberNode* doDivideBy(const QoreNumberNode& n, ExceptionSink* xsink) const; + + //! returns the negative of the current object (this) + DLLEXPORT QoreNumberNode* negate() const; + //! returns true if the number is zero DLLEXPORT bool zero() const; + //! compares the argument to the current object, returns -1 if the current object is less than the argument, 0 if equals, and 1 if greater than the argument + DLLEXPORT int compare(const QoreNumberNode& n) const; + + //! returns a pointer to this with the reference count incremented + DLLEXPORT QoreNumberNode* numberRefSelf() const; + //! returns the type information DLLLOCAL virtual AbstractQoreNode* parseInit(LocalVar* oflag, int pflag, int& lvids, const QoreTypeInfo*& typeInfo); Modified: qore/trunk/include/qore/intern/Operator.h =================================================================== --- qore/trunk/include/qore/intern/Operator.h 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/include/qore/intern/Operator.h 2012-09-11 16:15:18 UTC (rev 5030) @@ -70,8 +70,8 @@ typedef AbstractQoreNode *(*op_varref_func_t)(const AbstractQoreNode *vref, bool ref_rv, ExceptionSink *xsink); typedef QoreHashNode *(*op_hash_list_func_t)(const QoreHashNode *l, const QoreListNode *r, ExceptionSink *xsink); typedef AbstractQoreNode *(*op_noconvert_func_t)(const AbstractQoreNode *l, const AbstractQoreNode *r); -typedef AbstractQoreNode *(*op_node_int_func_t)(const AbstractQoreNode *l, int r, ExceptionSink *xsink); -typedef AbstractQoreNode *(*op_node_func_t)(const AbstractQoreNode *l, const AbstractQoreNode *r, ExceptionSink *xsink); +typedef AbstractQoreNode* (*op_node_int_func_t)(const AbstractQoreNode *l, int r, ExceptionSink *xsink); +typedef AbstractQoreNode* (*op_node_func_t)(const AbstractQoreNode* l, const AbstractQoreNode* r, ExceptionSink* xsink); typedef bool (*op_bool_int_func_t)(int64 l, int64 r); typedef int64 (*op_int_int_func_t)(int64 l, int64 r); typedef int64 (*op_divide_int_func_t)(int64 l, int64 r, ExceptionSink *xsink); @@ -88,13 +88,15 @@ typedef bool (*op_bool_bin_func_t)(const BinaryNode *l, const BinaryNode *r); typedef bool (*op_simple_bool_func_t)(const AbstractQoreNode *l, const AbstractQoreNode *r); -typedef AbstractQoreNode *(* op_func_t)(const AbstractQoreNode *l, const AbstractQoreNode *r, bool ref_rv, ExceptionSink *xsink); +typedef AbstractQoreNode*(*op_func_t)(const AbstractQoreNode *l, const AbstractQoreNode *r, bool ref_rv, ExceptionSink *xsink); typedef bool (*op_bool_func_t)(const AbstractQoreNode *l, const AbstractQoreNode *r, ExceptionSink *xsink); typedef int64 (*op_bigint_func_t)(const AbstractQoreNode *l, const AbstractQoreNode *r, ExceptionSink *xsink); typedef double (*op_float_func_t)(const AbstractQoreNode *l, const AbstractQoreNode *r, ExceptionSink *xsink); -typedef QoreNumberNode *(*op_number_func_t)(const QoreNumberNode* l, const QoreNumberNode* r, ExceptionSink* xsink); +typedef QoreNumberNode* (*op_number_func_t)(const QoreNumberNode* l, const QoreNumberNode* r, ExceptionSink* xsink); +typedef bool (*op_bool_number_func_t)(const QoreNumberNode* l, const QoreNumberNode* r); +typedef int64 (*op_int_number_func_t)(const QoreNumberNode* l, const QoreNumberNode* r); class AbstractOperatorFunction { public: @@ -571,19 +573,47 @@ }; class NumberOperatorFunction : public AbstractOperatorFunction { - private: - op_number_func_t op_func; +private: + op_number_func_t op_func; - public: - DLLLOCAL NumberOperatorFunction(op_number_func_t f) : AbstractOperatorFunction(NT_NUMBER, NT_NUMBER), op_func(f) { - } - DLLLOCAL virtual ~NumberOperatorFunction() {} - DLLLOCAL virtual AbstractQoreNode *eval(const AbstractQoreNode *l, const AbstractQoreNode *r, bool ref_rv, int args, ExceptionSink *xsink) const; - DLLLOCAL virtual bool bool_eval(const AbstractQoreNode *l, const AbstractQoreNode *r, int args, ExceptionSink *xsink) const; - DLLLOCAL virtual int64 bigint_eval(const AbstractQoreNode *l, const AbstractQoreNode *r, int args, ExceptionSink *xsink) const; - DLLLOCAL virtual double float_eval(const AbstractQoreNode *l, const AbstractQoreNode *r, int args, ExceptionSink *xsink) const; +public: + DLLLOCAL NumberOperatorFunction(op_number_func_t f) : AbstractOperatorFunction(NT_NUMBER, NT_NUMBER), op_func(f) { + } + DLLLOCAL virtual ~NumberOperatorFunction() {} + DLLLOCAL virtual AbstractQoreNode *eval(const AbstractQoreNode *l, const AbstractQoreNode *r, bool ref_rv, int args, ExceptionSink *xsink) const; + DLLLOCAL virtual bool bool_eval(const AbstractQoreNode *l, const AbstractQoreNode *r, int args, ExceptionSink *xsink) const; + DLLLOCAL virtual int64 bigint_eval(const AbstractQoreNode *l, const AbstractQoreNode *r, int args, ExceptionSink *xsink) const; + DLLLOCAL virtual double float_eval(const AbstractQoreNode *l, const AbstractQoreNode *r, int args, ExceptionSink *xsink) const; }; +class BoolNumberOperatorFunction : public AbstractOperatorFunction { +private: + op_bool_number_func_t op_func; + +public: + DLLLOCAL BoolNumberOperatorFunction(op_bool_number_func_t f) : AbstractOperatorFunction(NT_NUMBER, NT_NUMBER), op_func(f) { + } + DLLLOCAL virtual ~BoolNumberOperatorFunction() {} + DLLLOCAL virtual AbstractQoreNode *eval(const AbstractQoreNode *l, const AbstractQoreNode *r, bool ref_rv, int args, ExceptionSink *xsink) const; + DLLLOCAL virtual bool bool_eval(const AbstractQoreNode *l, const AbstractQoreNode *r, int args, ExceptionSink *xsink) const; + DLLLOCAL virtual int64 bigint_eval(const AbstractQoreNode *l, const AbstractQoreNode *r, int args, ExceptionSink *xsink) const; + DLLLOCAL virtual double float_eval(const AbstractQoreNode *l, const AbstractQoreNode *r, int args, ExceptionSink *xsink) const; +}; + +class IntNumberOperatorFunction : public AbstractOperatorFunction { +private: + op_int_number_func_t op_func; + +public: + DLLLOCAL IntNumberOperatorFunction(op_int_number_func_t f) : AbstractOperatorFunction(NT_NUMBER, NT_NUMBER), op_func(f) { + } + DLLLOCAL virtual ~IntNumberOperatorFunction() {} + DLLLOCAL virtual AbstractQoreNode *eval(const AbstractQoreNode *l, const AbstractQoreNode *r, bool ref_rv, int args, ExceptionSink *xsink) const; + DLLLOCAL virtual bool bool_eval(const AbstractQoreNode *l, const AbstractQoreNode *r, int args, ExceptionSink *xsink) const; + DLLLOCAL virtual int64 bigint_eval(const AbstractQoreNode *l, const AbstractQoreNode *r, int args, ExceptionSink *xsink) const; + DLLLOCAL virtual double float_eval(const AbstractQoreNode *l, const AbstractQoreNode *r, int args, ExceptionSink *xsink) const; +}; + class DefaultNothingOperatorFunction : public AbstractOperatorFunction { public: DLLLOCAL DefaultNothingOperatorFunction() : AbstractOperatorFunction(NT_ALL, NT_ALL) { @@ -720,9 +750,6 @@ DLLLOCAL void addFunction(op_compare_float_func_t f) { functions.push_back(new CompareFloatOperatorFunction(f)); } - DLLLOCAL void addFunction(op_number_func_t f) { - functions.push_back(new NumberOperatorFunction(f)); - } DLLLOCAL void addFunction(op_logic_func_t f) { functions.push_back(new LogicOperatorFunction(f)); } @@ -735,6 +762,15 @@ DLLLOCAL void addFunction(op_date_func_t f) { functions.push_back(new DateOperatorFunction(f)); } + DLLLOCAL void addFunction(op_number_func_t f) { + functions.push_back(new NumberOperatorFunction(f)); + } + DLLLOCAL void addFunction(op_bool_number_func_t f) { + functions.push_back(new BoolNumberOperatorFunction(f)); + } + DLLLOCAL void addFunction(op_int_number_func_t f) { + functions.push_back(new IntNumberOperatorFunction(f)); + } DLLLOCAL void addCompareDateFunction() { functions.push_back(new CompareDateOperatorFunction()); } Deleted: qore/trunk/include/qore/intern/QoreIntDivideEqualsOperatorNode.h =================================================================== --- qore/trunk/include/qore/intern/QoreIntDivideEqualsOperatorNode.h 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/include/qore/intern/QoreIntDivideEqualsOperatorNode.h 2012-09-11 16:15:18 UTC (rev 5030) @@ -1,43 +0,0 @@ -/* -*- mode: c++; indent-tabs-mode: nil -*- */ -/* - QoreIntDivideEqualsOperatorNode.h - - Qore Programming Language - - Copyright 2003 - 2012 David Nichols - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _QORE_QOREINTDIVIDEEQUALSOPERATORNODE_H -#define _QORE_QOREINTDIVIDEEQUALSOPERATORNODE_H - -class QoreIntDivideEqualsOperatorNode : public QoreDivideEqualsOperatorNode { -protected: - DLLLOCAL virtual AbstractQoreNode *evalImpl(ExceptionSink *xsink) const; - DLLLOCAL virtual AbstractQoreNode *evalImpl(bool &needs_deref, ExceptionSink *xsink) const; - - DLLLOCAL virtual int64 bigIntEvalImpl(ExceptionSink *xsink) const; - DLLLOCAL virtual int integerEvalImpl(ExceptionSink *xsink) const; - DLLLOCAL virtual double floatEvalImpl(ExceptionSink *xsink) const; - DLLLOCAL virtual bool boolEvalImpl(ExceptionSink *xsink) const; - -public: - DLLLOCAL QoreIntDivideEqualsOperatorNode(AbstractQoreNode *n_left, AbstractQoreNode *n_right) : QoreDivideEqualsOperatorNode(n_left, n_right) { - } -}; - -#endif - Deleted: qore/trunk/include/qore/intern/QoreIntMultiplyEqualsOperatorNode.h =================================================================== --- qore/trunk/include/qore/intern/QoreIntMultiplyEqualsOperatorNode.h 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/include/qore/intern/QoreIntMultiplyEqualsOperatorNode.h 2012-09-11 16:15:18 UTC (rev 5030) @@ -1,43 +0,0 @@ -/* -*- mode: c++; indent-tabs-mode: nil -*- */ -/* - QoreIntMultiplyEqualsOperatorNode.h - - Qore Programming Language - - Copyright 2003 - 2012 David Nichols - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _QORE_QOREINTMULTIPLYEQUALSOPERATORNODE_H -#define _QORE_QOREINTMULTIPLYEQUALSOPERATORNODE_H - -class QoreIntMultiplyEqualsOperatorNode : public QoreMultiplyEqualsOperatorNode { -protected: - DLLLOCAL virtual AbstractQoreNode *evalImpl(ExceptionSink *xsink) const; - DLLLOCAL virtual AbstractQoreNode *evalImpl(bool &needs_deref, ExceptionSink *xsink) const; - - DLLLOCAL virtual int64 bigIntEvalImpl(ExceptionSink *xsink) const; - DLLLOCAL virtual int integerEvalImpl(ExceptionSink *xsink) const; - DLLLOCAL virtual double floatEvalImpl(ExceptionSink *xsink) const; - DLLLOCAL virtual bool boolEvalImpl(ExceptionSink *xsink) const; - -public: - DLLLOCAL QoreIntMultiplyEqualsOperatorNode(AbstractQoreNode *n_left, AbstractQoreNode *n_right) : QoreMultiplyEqualsOperatorNode(n_left, n_right) { - } -}; - -#endif - Modified: qore/trunk/include/qore/intern/QoreLibIntern.h =================================================================== --- qore/trunk/include/qore/intern/QoreLibIntern.h 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/include/qore/intern/QoreLibIntern.h 2012-09-11 16:15:18 UTC (rev 5030) @@ -98,18 +98,20 @@ #include <vector> // here we define virtual types -#define NT_NONE -1 -#define NT_ALL -2 -#define NT_CODE -3 -#define NT_SOFTINT -4 -#define NT_SOFTFLOAT -5 -#define NT_SOFTNUMBER -6 -#define NT_SOFTBOOLEAN -7 -#define NT_SOFTSTRING -8 -#define NT_SOFTDATE -9 -#define NT_SOFTLIST -10 -#define NT_TIMEOUT -11 -#define NT_INTORFLOAT -12 +#define NT_NONE -1 +#define NT_ALL -2 +#define NT_CODE -3 +#define NT_SOFTINT -4 +#define NT_SOFTFLOAT -5 +#define NT_SOFTNUMBER -6 +#define NT_SOFTBOOLEAN -7 +#define NT_SOFTSTRING -8 +#define NT_SOFTDATE -9 +#define NT_SOFTLIST -10 +#define NT_TIMEOUT -11 +#define NT_INTORFLOAT -12 +#define NT_INTFLOATORNUMBER -13 +#define NT_FLOATORNUMBER -14 #define NT_SOMETHING -101 // i.e. "not NOTHING" #define NT_DATA -102 // either QoreStringNode or BinaryNode @@ -346,7 +348,8 @@ DLLLOCAL int check_lvalue(const AbstractQoreNode* n); DLLLOCAL int check_lvalue_int(const QoreTypeInfo *&typeInfo, const char* name); DLLLOCAL int check_lvalue_float(const QoreTypeInfo *&typeInfo, const char* name); -DLLLOCAL int check_lvalue_int_float(const QoreTypeInfo *&typeInfo, const char* name); +DLLLOCAL int check_lvalue_int_float_number(const QoreTypeInfo *&typeInfo, const char* name); +DLLLOCAL int check_lvalue_number(const QoreTypeInfo *&typeInfo, const char* name); DLLLOCAL bool checkParseOption(int64 o); Modified: qore/trunk/include/qore/intern/QoreMultiplyEqualsOperatorNode.h =================================================================== --- qore/trunk/include/qore/intern/QoreMultiplyEqualsOperatorNode.h 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/include/qore/intern/QoreMultiplyEqualsOperatorNode.h 2012-09-11 16:15:18 UTC (rev 5030) @@ -42,17 +42,23 @@ const QoreTypeInfo *rightTypeInfo = 0; right = right->parseInit(oflag, pflag, lvids, rightTypeInfo); - if (!ti->isType(NT_FLOAT)) { - if (rightTypeInfo->isType(NT_FLOAT)) { - check_lvalue_float(ti, name); - ti = floatTypeInfo; + if (!ti->isType(NT_NUMBER)) { + if (rightTypeInfo->isType(NT_NUMBER)) { + check_lvalue_number(ti, name); + ti = numberTypeInfo; } - else if (ti->returnsSingle()) { - check_lvalue_int(ti, name); - ti = bigIntTypeInfo; + else if (!ti->isType(NT_FLOAT)) { + if (rightTypeInfo->isType(NT_FLOAT)) { + check_lvalue_float(ti, name); + ti = floatTypeInfo; + } + else if (ti->returnsSingle()) { + check_lvalue_int(ti, name); + ti = bigIntTypeInfo; + } + else + ti = 0; } - else - ti = 0; } typeInfo = ti; Modified: qore/trunk/include/qore/intern/QoreOperatorNode.h =================================================================== --- qore/trunk/include/qore/intern/QoreOperatorNode.h 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/include/qore/intern/QoreOperatorNode.h 2012-09-11 16:15:18 UTC (rev 5030) @@ -182,9 +182,7 @@ #include <qore/intern/QoreAndEqualsOperatorNode.h> #include <qore/intern/QoreModulaEqualsOperatorNode.h> #include <qore/intern/QoreMultiplyEqualsOperatorNode.h> -#include <qore/intern/QoreIntMultiplyEqualsOperatorNode.h> #include <qore/intern/QoreDivideEqualsOperatorNode.h> -#include <qore/intern/QoreIntDivideEqualsOperatorNode.h> #include <qore/intern/QoreXorEqualsOperatorNode.h> #include <qore/intern/QoreShiftLeftEqualsOperatorNode.h> #include <qore/intern/QoreShiftRightEqualsOperatorNode.h> Modified: qore/trunk/include/qore/intern/QorePostIncrementOperatorNode.h =================================================================== --- qore/trunk/include/qore/intern/QorePostIncrementOperatorNode.h 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/include/qore/intern/QorePostIncrementOperatorNode.h 2012-09-11 16:15:18 UTC (rev 5030) @@ -42,7 +42,7 @@ typeInfo = ti; // make sure left side can take an integer or floating-point value - check_lvalue_int_float(ti, name); + check_lvalue_int_float_number(ti, name); } DLLLOCAL virtual const QoreTypeInfo* getTypeInfo() const { Modified: qore/trunk/include/qore/intern/QorePreIncrementOperatorNode.h =================================================================== --- qore/trunk/include/qore/intern/QorePreIncrementOperatorNode.h 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/include/qore/intern/QorePreIncrementOperatorNode.h 2012-09-11 16:15:18 UTC (rev 5030) @@ -43,7 +43,7 @@ checkLValue(exp); // make sure left side can take an integer or floating-point value - check_lvalue_int_float(outTypeInfo, name); + check_lvalue_int_float_number(outTypeInfo, name); // save return type typeInfo = outTypeInfo; Modified: qore/trunk/include/qore/intern/QoreTypeInfo.h =================================================================== --- qore/trunk/include/qore/intern/QoreTypeInfo.h 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/include/qore/intern/QoreTypeInfo.h 2012-09-11 16:15:18 UTC (rev 5030) @@ -1321,6 +1321,33 @@ } }; +class IntFloatOrNumberTypeInfo : public AcceptsReturnsSameMultiTypeInfo { +protected: + DLLLOCAL virtual const char *getNameImpl() const { + return "int|float|number"; + } + +public: + DLLLOCAL IntFloatOrNumberTypeInfo() : AcceptsReturnsSameMultiTypeInfo(0, NT_INTFLOATORNUMBER) { + at.push_back(bigIntTypeInfo); + at.push_back(floatTypeInfo); + at.push_back(numberTypeInfo); + } +}; + +class FloatOrNumberTypeInfo : public AcceptsReturnsSameMultiTypeInfo { +protected: + DLLLOCAL virtual const char *getNameImpl() const { + return "float|number"; + } + +public: + DLLLOCAL FloatOrNumberTypeInfo() : AcceptsReturnsSameMultiTypeInfo(0, NT_FLOATORNUMBER) { + at.push_back(floatTypeInfo); + at.push_back(numberTypeInfo); + } +}; + // accepts any type class UserReferenceTypeInfo : public ReverseTypeInfo { protected: Modified: qore/trunk/include/qore/intern/QoreValue.h =================================================================== --- qore/trunk/include/qore/intern/QoreValue.h 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/include/qore/intern/QoreValue.h 2012-09-11 16:15:18 UTC (rev 5030) @@ -369,7 +369,6 @@ } } - DLLLOCAL AbstractQoreNode* assignInitial(QoreValue& n) { assert(!assigned); return assign(n); Modified: qore/trunk/include/qore/intern/Variable.h =================================================================== --- qore/trunk/include/qore/intern/Variable.h 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/include/qore/intern/Variable.h 2012-09-11 16:15:18 UTC (rev 5030) @@ -495,6 +495,40 @@ DLLLOCAL double postIncrementFloat(const char* desc = "<lvalue>"); DLLLOCAL double postDecrementFloat(const char* desc = "<lvalue>"); + DLLLOCAL void plusEqualsNumber(const AbstractQoreNode* r, const char* desc = "<lvalue>"); + DLLLOCAL void minusEqualsNumber(const AbstractQoreNode* r, const char* desc = "<lvalue>"); + DLLLOCAL void multiplyEqualsNumber(const AbstractQoreNode* r, const char* desc = "<lvalue>"); + DLLLOCAL void divideEqualsNumber(const AbstractQoreNode* r, const char* desc = "<lvalue>"); + DLLLOCAL void preIncrementNumber(const char* desc = "<lvalue>"); + DLLLOCAL void preDecrementNumber(const char* desc = "<lvalue>"); + DLLLOCAL QoreNumberNode* postIncrementNumber(bool ref_rv, const char* desc = "<lvalue>"); + DLLLOCAL QoreNumberNode* postDecrementNumber(bool ref_rv, const char* desc = "<lvalue>"); + + DLLLOCAL QoreNumberNode* ensureUniqueNumber(const char* desc = "<lvalue>") { + if (val) { + typeInfo->doTypeException(0, desc, numberTypeInfo->getName(), vl.xsink); + return 0; + } + + if (get_node_type(*v) == NT_NUMBER) { + if (!(*v)->is_unique()) { + AbstractQoreNode* old = (*v); + (*v) = (*v)->realCopy(); + saveTemp(old); + } + } + else { + if (!typeInfo->parseAccepts(numberTypeInfo)) { + typeInfo->doTypeException(0, desc, numberTypeInfo->getName(), vl.xsink); + return 0; + } + + saveTemp(*v); + *v = new QoreNumberNode(*v); + } + return reinterpret_cast<QoreNumberNode*>(*v); + } + //DLLLOCAL int assign(QoreValue val, const char* desc = "<lvalue>"); DLLLOCAL int assign(AbstractQoreNode *val, const char* desc = "<lvalue>"); Added: qore/trunk/include/qore/intern/qore_number_private.h =================================================================== --- qore/trunk/include/qore/intern/qore_number_private.h (rev 0) +++ qore/trunk/include/qore/intern/qore_number_private.h 2012-09-11 16:15:18 UTC (rev 5030) @@ -0,0 +1,292 @@ +/* -*- mode: c++; indent-tabs-mode: nil -*- */ +/* + qore_number_private.h + + Qore Programming Language + + Copyright 2003 - 2012 David Nichols + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _QORE_QORE_NUMBER_PRIVATE_H + +#define _QORE_QORE_NUMBER_PRIVATE_H + +#define QORE_DEFAULT_PREC 128 +#define QORE_MAX_PREC 8192 +// round to nearest (roundTiesToEven in IEEE 754-2008) +#define QORE_MPFR_RND MPFR_RNDN +// MPFR_RNDA + +struct qore_number_private_intern { + mpfr_t num; + + DLLLOCAL qore_number_private_intern() { + mpfr_init2(num, QORE_DEFAULT_PREC); + } + + DLLLOCAL qore_number_private_intern(mpfr_prec_t prec) { + if (prec > QORE_MAX_PREC) + prec = QORE_MAX_PREC; + mpfr_init2(num, prec); + } + + DLLLOCAL ~qore_number_private_intern() { + mpfr_clear(num); + } + + DLLLOCAL void checkPrec(const mpfr_t r) { + mpfr_prec_t p = mpfr_get_prec(r); + if (p > mpfr_get_prec(num)) + mpfr_prec_round(num, p, QORE_MPFR_RND); + } +}; + +struct qore_number_private : public qore_number_private_intern { + DLLLOCAL explicit qore_number_private(mpfr_prec_t prec) : qore_number_private_intern(prec) { + } + + DLLLOCAL qore_number_private(double f) { + mpfr_set_d(num, f, QORE_MPFR_RND); + } + + DLLLOCAL qore_number_private(int64 i) { + mpfr_set_sj(num, i, QORE_MPFR_RND); + } + + DLLLOCAL qore_number_private(const char* str) : qore_number_private_intern(QORE_MAX(QORE_DEFAULT_PREC, strlen(str)*10)) { + mpfr_set_str(num, str, 10, QORE_MPFR_RND); + } + + DLLLOCAL qore_number_private(const qore_number_private& old) : qore_number_private_intern(mpfr_get_prec(old.num)) { + mpfr_set(num, old.num, QORE_MPFR_RND); + } + + DLLLOCAL double getAsFloat() const { + return mpfr_get_d(num, QORE_MPFR_RND); + } + + DLLLOCAL int64 getAsBigInt() const { + return mpfr_get_sj(num, QORE_MPFR_RND); + } + + DLLLOCAL bool getAsBool() const { + return !zero(); + } + + DLLLOCAL bool zero() const { + return (bool)mpfr_zero_p(num); + } + + DLLLOCAL bool nan() const { + return (bool)mpfr_nan_p(num); + } + + DLLLOCAL bool inf() const { + return (bool)mpfr_inf_p(num); + } + + DLLLOCAL bool number() const { + return (bool)mpfr_number_p(num); + } + + // regular and not zero + DLLLOCAL bool regular() const { + return (bool)mpfr_regular_p(num); + } + + DLLLOCAL void getAsString(QoreString& str) const { + // first check if it's zero + if (zero()) { + str.concat("0n"); + return; + } + +#ifdef DO_MPFR_PRINTF +#define QORE_MPFR_BUFSIZE 512 + str.allocate(str.size() + QORE_MPFR_BUFSIZE); + int len = mpfr_sprintf((char*)(str.getBuffer() + str.size()), "%Re", num); + if (len > 0) { + str.terminate(str.size() + len); + str.concat('n'); + } + else + str.concat("<error>"); +#else + mpfr_exp_t exp; + char* buf = mpfr_get_str(0, &exp, 10, 0, num, QORE_MPFR_RND); + if (!buf) { + str.concat("<number error>"); + return; + } + + // if it's a regular number, then format accordingly + if (number()) { + qore_size_t len = str.size(); + //printd(0, "QoreNumberNode::getAsString() this: %p '%s' exp "QLLD" len: "QLLD"\n", this, buf, exp, len); + + str.concat(buf); + // trim the trailing zeros off the end + str.trim_trailing('0'); + if (exp <= 0) { + exp = -exp; + str.insert("0.", len); + if (exp) + str.insertch('0', len + 2, exp); + } + else { + // get remaining length of string (how many characters were added) + qore_size_t rlen = str.size() - len; + + //printd(0, "QoreNumberNode::getAsString() this: %p str: '%s' rlen: "QLLD"\n", this, str.getBuffer(), rlen); + + // assert that we have added at least 1 character + assert(rlen > 0); + if (exp > rlen) + str.insertch('0', str.size(), exp - rlen); + else if (exp < rlen) + str.insertch('.', len + exp, 1); + } + str.concat('n'); + } + + mpfr_free_str(buf); +#endif + } + + DLLLOCAL int compare(const qore_number_private& right) const { + return mpfr_cmp(num, right.num); + } + + DLLLOCAL int compare(double right) const { + return mpfr_cmp_d(num, right); + } + + DLLLOCAL int compare(int64 right) const { + MPFR_DECL_INIT(r, QORE_DEFAULT_PREC); + mpfr_set_sj(r, right, QORE_MPFR_RND); + return mpfr_cmp(num, r); + } + + DLLLOCAL qore_number_private* doPlus(const qore_number_private& r) const { + mpfr_prec_t prec = QORE_MAX(mpfr_get_prec(num), mpfr_get_prec(r.num)); + qore_number_private* p = new qore_number_private(prec); + mpfr_add(p->num, num, r.num, QORE_MPFR_RND); + return p; + } + + //! add the argument to this value and return the result + DLLLOCAL qore_number_private* doMinus(const qore_number_private& r) const { + mpfr_prec_t prec = QORE_MAX(mpfr_get_prec(num), mpfr_get_prec(r.num)); + qore_number_private* p = new qore_number_private(prec); + mpfr_sub(p->num, num, r.num, QORE_MPFR_RND); + return p; + } + + //! add the argument to this value and return the result + DLLLOCAL qore_number_private* doMultiply(const qore_number_private& r) const { + mpfr_prec_t prec = QORE_MAX(mpfr_get_prec(num), mpfr_get_prec(r.num)); + qore_number_private* p = new qore_number_private(prec); + mpfr_mul(p->num, num, r.num, QORE_MPFR_RND); + return p; + } + + //! add the argument to this value and return the result + DLLLOCAL qore_number_private* doDivideBy(const qore_number_private& r, ExceptionSink* xsink) const { + if (r.zero()) { + xsink->raiseException("DIVISION-BY-ZERO", "division by zero in numeric expression"); + return 0; + } + mpfr_prec_t prec = QORE_MAX(mpfr_get_prec(num), mpfr_get_prec(r.num)); + qore_number_private* p = new qore_number_private(prec); + mpfr_div(p->num, num, r.num, QORE_MPFR_RND); + return p; + } + + DLLLOCAL qore_number_private* negate() const { + qore_number_private* p = new qore_number_private(mpfr_get_prec(num)); + mpfr_neg(p->num, num, QORE_MPFR_RND); + return p; + } + + DLLLOCAL void inc() { + MPFR_DECL_INIT(tmp, mpfr_get_prec(num)); + mpfr_set(tmp, num, QORE_MPFR_RND); + mpfr_add_si(num, tmp, 1, QORE_MPFR_RND); + } + + DLLLOCAL void dec() { + MPFR_DECL_INIT(tmp, mpfr_get_prec(num)); + mpfr_set(tmp, num, QORE_MPFR_RND); + mpfr_sub_si(num, tmp, 1, QORE_MPFR_RND); + } + + DLLLOCAL void plusEquals(const qore_number_private& r) { + checkPrec(r.num); + MPFR_DECL_INIT(tmp, mpfr_get_prec(num)); + mpfr_set(tmp, num, QORE_MPFR_RND); + mpfr_add(num, tmp, r.num, QORE_MPFR_RND); + } + + DLLLOCAL void minusEquals(const qore_number_private& r) { + checkPrec(r.num); + MPFR_DECL_INIT(tmp, mpfr_get_prec(num)); + mpfr_set(tmp, num, QORE_MPFR_RND); + mpfr_sub(num, tmp, r.num, QORE_MPFR_RND); + } + + DLLLOCAL void multiplyEquals(const qore_number_private& r) { + checkPrec(r.num); + MPFR_DECL_INIT(tmp, mpfr_get_prec(num)); + mpfr_set(tmp, num, QORE_MPFR_RND); + mpfr_mul(num, tmp, r.num, QORE_MPFR_RND); + } + + DLLLOCAL void divideEquals(const qore_number_private& r) { + assert(!r.zero()); + checkPrec(r.num); + MPFR_DECL_INIT(tmp, mpfr_get_prec(num)); + mpfr_set(tmp, num, QORE_MPFR_RND); + mpfr_div(num, tmp, r.num, QORE_MPFR_RND); + } + + // static accessor methods + static void inc(QoreNumberNode& n) { + n.priv->inc(); + } + + static void dec(QoreNumberNode& n) { + n.priv->dec(); + } + + static void plusEquals(QoreNumberNode& n, const QoreNumberNode& r) { + n.priv->plusEquals(*r.priv); + } + + static void minusEquals(QoreNumberNode& n, const QoreNumberNode& r) { + n.priv->minusEquals(*r.priv); + } + + static void multiplyEquals(QoreNumberNode& n, const QoreNumberNode& r) { + n.priv->multiplyEquals(*r.priv); + } + + static void divideEquals(QoreNumberNode& n, const QoreNumberNode& r) { + n.priv->divideEquals(*r.priv); + } +}; + +#endif Modified: qore/trunk/lib/Makefile.am =================================================================== --- qore/trunk/lib/Makefile.am 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/lib/Makefile.am 2012-09-11 16:15:18 UTC (rev 5030) @@ -425,9 +425,7 @@ QoreAndEqualsOperatorNode.cpp \ QoreModulaEqualsOperatorNode.cpp \ QoreMultiplyEqualsOperatorNode.cpp \ - QoreIntMultiplyEqualsOperatorNode.cpp \ QoreDivideEqualsOperatorNode.cpp \ - QoreIntDivideEqualsOperatorNode.cpp \ QoreXorEqualsOperatorNode.cpp \ QoreShiftLeftEqualsOperatorNode.cpp \ QoreShiftRightEqualsOperatorNode.cpp \ Modified: qore/trunk/lib/Operator.cpp =================================================================== --- qore/trunk/lib/Operator.cpp 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/lib/Operator.cpp 2012-09-11 16:15:18 UTC (rev 5030) @@ -32,6 +32,8 @@ DLLLOCAL OperatorList oplist; +DLLLOCAL extern const QoreTypeInfo* bigIntOrFloatTypeInfo, * bigIntFloatOrNumberTypeInfo, * floatOrNumberTypeInfo; + // the standard, system-default operator pointers Operator *OP_MODULA, *OP_BIN_AND, *OP_BIN_OR, *OP_BIN_NOT, *OP_BIN_XOR, *OP_MINUS, *OP_PLUS, @@ -400,10 +402,6 @@ return left - right; } -static QoreNumberNode* op_plus_number(const QoreNumberNode* left, const QoreNumberNode* right, ExceptionSink* xsink) { - return left->doPlus(right); -} - static double op_plus_float(double left, double right) { return left + right; } @@ -414,12 +412,56 @@ static double op_divide_float(double left, double right, ExceptionSink *xsink) { if (!right) { - xsink->raiseException("DIVISION-BY-ZERO", "division by zero in floating-point expression!"); + xsink->raiseException("DIVISION-BY-ZERO", "division by zero in floating-point expression"); return 0.0; } return left / right; } +static bool op_log_lt_number(const QoreNumberNode* left, const QoreNumberNode* right) { + return left->compare(*right) < 0; +} + +static bool op_log_le_number(const QoreNumberNode* left, const QoreNumberNode* right) { + return left->compare(*right) <= 0; +} + +static bool op_log_gt_number(const QoreNumberNode* left, const QoreNumberNode* right) { + return left->compare(*right) > 0; +} + +static bool op_log_ge_number(const QoreNumberNode* left, const QoreNumberNode* right) { + return left->compare(*right) >= 0; +} + +static bool op_log_eq_number(const QoreNumberNode* left, const QoreNumberNode* right) { + return !left->compare(*right); +} + +static bool op_log_ne_number(const QoreNumberNode* left, const QoreNumberNode* right) { + return (bool)left->compare(*right); +} + +static int64 op_cmp_number(const QoreNumberNode* left, const QoreNumberNode* right) { + return (int64)left->compare(*right); +} + +static QoreNumberNode* op_plus_number(const QoreNumberNode* left, const QoreNumberNode* right, ExceptionSink* xsink) { + return left->doPlus(*right); +} + +static QoreNumberNode* op_minus_number(const QoreNumberNode* left, const QoreNumberNode* right, ExceptionSink* xsink) { + return left->doMinus(*right); +} + +static QoreNumberNode* op_multiply_number(const QoreNumberNode* left, const QoreNumberNode* right, ExceptionSink* xsink) { + return left->doMultiply(*right); +} + +static QoreNumberNode* op_divide_number(const QoreNumberNode* left, const QoreNumberNode* right, ExceptionSink* xsink) { + return left->doDivideBy(*right, xsink); +} + static QoreStringNode *op_plus_string(const QoreString *left, const QoreString *right, ExceptionSink *xsink) { QoreStringNodeHolder str(new QoreStringNode(*left)); //printd(5, "op_plus_string() (%d) %p \"%s\" + (%d) %p \"%s\"\n", left->strlen(), left->getBuffer(), left->getBuffer(), right->strlen(), right->getBuffer(), right->getBuffer()); @@ -2601,14 +2643,6 @@ left = *l; } - if (args == 1) { - QoreNumberNode* rv = op_func(reinterpret_cast<const QoreNumberNode*>(left), reinterpret_cast<const QoreNumberNode*>(right), xsink); - assert(!(*xsink && rv)); - if (!ref_rv || *xsink) - return 0; - return rv; - } - ReferenceHolder<AbstractQoreNode> r(xsink); // convert node type to required argument types for operator if necessary @@ -2633,12 +2667,6 @@ left = *l; } - if (args == 1) { - SimpleRefHolder<QoreNumberNode> rv(op_func(reinterpret_cast<const QoreNumberNode*>(left), reinterpret_cast<const QoreNumberNode*>(right), xsink)); - assert(!(*xsink && rv)); - return !rv->zero(); - } - ReferenceHolder<AbstractQoreNode> r(xsink); // convert node type to required argument types for operator if necessary @@ -2661,12 +2689,6 @@ left = *l; } - if (args == 1) { - SimpleRefHolder<QoreNumberNode> rv(op_func(reinterpret_cast<const QoreNumberNode*>(left), reinterpret_cast<const QoreNumberNode*>(right), xsink)); - assert(!(*xsink && rv)); - return rv->getAsBigInt(); - } - ReferenceHolder<AbstractQoreNode> r(xsink); // convert node type to required argument types for operator if necessary @@ -2689,12 +2711,6 @@ left = *l; } - if (args == 1) { - SimpleRefHolder<QoreNumberNode> rv(op_func(reinterpret_cast<const QoreNumberNode*>(left), reinterpret_cast<const QoreNumberNode*>(right), xsink)); - assert(!(*xsink && rv)); - return rv->getAsFloat(); - } - ReferenceHolder<AbstractQoreNode> r(xsink); // convert node type to required argument types for operator if necessary @@ -2708,6 +2724,166 @@ return rv->getAsFloat(); } +AbstractQoreNode* BoolNumberOperatorFunction::eval(const AbstractQoreNode *left, const AbstractQoreNode *right, bool ref_rv, int args, ExceptionSink *xsink) const { + ReferenceHolder<AbstractQoreNode> l(xsink); + + // convert node type to required argument types for operator if necessary + if ((left->getType() != ltype) && (ltype != NT_ALL)) { + l = get_node_type(left, ltype); + left = *l; + } + + ReferenceHolder<AbstractQoreNode> r(xsink); + + // convert node type to required argument types for operator if necessary + if ((right->getType() != rtype) && (rtype != NT_ALL)) { + r = get_node_type(right, rtype); + right = *r; + } + + return get_bool_node(op_func(reinterpret_cast<const QoreNumberNode*>(left), reinterpret_cast<const QoreNumberNode*>(right))); +} + +bool BoolNumberOperatorFunction::bool_eval(const AbstractQoreNode *left, const AbstractQoreNode *right, int args, ExceptionSink *xsink) const { + ReferenceHolder<AbstractQoreNode> l(xsink); + + // convert node type to required argument types for operator if necessary + if ((left->getType() != ltype) && (ltype != NT_ALL)) { + l = get_node_type(left, ltype); + left = *l; + } + + ReferenceHolder<AbstractQoreNode> r(xsink); + + // convert node type to required argument types for operator if necessary + if ((right->getType() != rtype) && (rtype != NT_ALL)) { + r = get_node_type(right, rtype); + right = *r; + } + + return op_func(reinterpret_cast<const QoreNumberNode*>(left), reinterpret_cast<const QoreNumberNode*>(right)); +} + +int64 BoolNumberOperatorFunction::bigint_eval(const AbstractQoreNode *left, const AbstractQoreNode *right, int args, ExceptionSink *xsink) const { + ReferenceHolder<AbstractQoreNode> l(xsink); + + // convert node type to required argument types for operator if necessary + if ((left->getType() != ltype) && (ltype != NT_ALL)) { + l = get_node_type(left, ltype); + left = *l; + } + + ReferenceHolder<AbstractQoreNode> r(xsink); + + // convert node type to required argument types for operator if necessary + if ((right->getType() != rtype) && (rtype != NT_ALL)) { + r = get_node_type(right, rtype); + right = *r; + } + + return (int64)op_func(reinterpret_cast<const QoreNumberNode*>(left), reinterpret_cast<const QoreNumberNode*>(right)); +} + +double BoolNumberOperatorFunction::float_eval(const AbstractQoreNode *left, const AbstractQoreNode *right, int args, ExceptionSink *xsink) const { + ReferenceHolder<AbstractQoreNode> l(xsink); + + // convert node type to required argument types for operator if necessary + if ((left->getType() != ltype) && (ltype != NT_ALL)) { + l = get_node_type(left, ltype); + left = *l; + } + + ReferenceHolder<AbstractQoreNode> r(xsink); + + // convert node type to required argument types for operator if necessary + if ((right->getType() != rtype) && (rtype != NT_ALL)) { + r = get_node_type(right, rtype); + right = *r; + } + + return (double)op_func(reinterpret_cast<const QoreNumberNode*>(left), reinterpret_cast<const QoreNumberNode*>(right)); +} + +AbstractQoreNode* IntNumberOperatorFunction::eval(const AbstractQoreNode *left, const AbstractQoreNode *right, bool ref_rv, int args, ExceptionSink *xsink) const { + ReferenceHolder<AbstractQoreNode> l(xsink); + + // convert node type to required argument types for operator if necessary + if ((left->getType() != ltype) && (ltype != NT_ALL)) { + l = get_node_type(left, ltype); + left = *l; + } + + ReferenceHolder<AbstractQoreNode> r(xsink); + + // convert node type to required argument types for operator if necessary + if ((right->getType() != rtype) && (rtype != NT_ALL)) { + r = get_node_type(right, rtype); + right = *r; + } + + return new QoreBigIntNode(op_func(reinterpret_cast<const QoreNumberNode*>(left), reinterpret_cast<const QoreNumberNode*>(right))); +} + +bool IntNumberOperatorFunction::bool_eval(const AbstractQoreNode *left, const AbstractQoreNode *right, int args, ExceptionSink *xsink) const { + ReferenceHolder<AbstractQoreNode> l(xsink); + + // convert node type to required argument types for operator if necessary + if ((left->getType() != ltype) && (ltype != NT_ALL)) { + l = get_node_type(left, ltype); + left = *l; + } + + ReferenceHolder<AbstractQoreNode> r(xsink); + + // convert node type to required argument types for operator if necessary + if ((right->getType() != rtype) && (rtype != NT_ALL)) { + r = get_node_type(right, rtype); + right = *r; + } + + return (bool)op_func(reinterpret_cast<const QoreNumberNode*>(left), reinterpret_cast<const QoreNumberNode*>(right)); +} + +int64 IntNumberOperatorFunction::bigint_eval(const AbstractQoreNode *left, const AbstractQoreNode *right, int args, ExceptionSink *xsink) const { + ReferenceHolder<AbstractQoreNode> l(xsink); + + // convert node type to required argument types for operator if necessary + if ((left->getType() != ltype) && (ltype != NT_ALL)) { + l = get_node_type(left, ltype); + left = *l; + } + + ReferenceHolder<AbstractQoreNode> r(xsink); + + // convert node type to required argument types for operator if necessary + if ((right->getType() != rtype) && (rtype != NT_ALL)) { + r = get_node_type(right, rtype); + right = *r; + } + + return op_func(reinterpret_cast<const QoreNumberNode*>(left), reinterpret_cast<const QoreNumberNode*>(right)); +} + +double IntNumberOperatorFunction::float_eval(const AbstractQoreNode *left, const AbstractQoreNode *right, int args, ExceptionSink *xsink) const { + ReferenceHolder<AbstractQoreNode> l(xsink); + + // convert node type to required argument types for operator if necessary + if ((left->getType() != ltype) && (ltype != NT_ALL)) { + l = get_node_type(left, ltype); + left = *l; + } + + ReferenceHolder<AbstractQoreNode> r(xsink); + + // convert node type to required argument types for operator if necessary + if ((right->getType() != rtype) && (rtype != NT_ALL)) { + r = get_node_type(right, rtype); + right = *r; + } + + return (double)op_func(reinterpret_cast<const QoreNumberNode*>(left), reinterpret_cast<const QoreNumberNode*>(right)); +} + Operator::~Operator() { // erase all functions for (unsigned i = 0, size = functions.size(); i < size; i++) @@ -3108,7 +3284,7 @@ if (getProgram()->getParseExceptionSink()) { QoreStringNode *desc = new QoreStringNode("lvalue has type "); typeInfo->getThisType(*desc); - desc->sprintf(", but the %s operator will assign it an integer value", name); + desc->sprintf(", but the %s will assign it an integer value", name); qore_program_private::makeParseException(getProgram(), "PARSE-TYPE-ERROR", desc); } return -1; @@ -3122,37 +3298,63 @@ if (!typeInfo->parseAcceptsReturns(NT_FLOAT) && getProgram()->getParseExceptionSink()) { QoreStringNode *desc = new QoreStringNode("lvalue has type "); typeInfo->getThisType(*desc); - desc->sprintf(", but the %s operator will assign it a float value", name); + desc->sprintf(", but the %s will assign it a float value", name); qore_program_private::makeParseException(getProgram(), "PARSE-TYPE-ERROR", desc); return -1; } return 0; } -int check_lvalue_int_float(const QoreTypeInfo*& typeInfo, const char *name) { +int check_lvalue_int_float_number(const QoreTypeInfo*& typeInfo, const char *name) { // make sure the lvalue can be assigned an integer value // raise a parse exception only if parse exceptions are not suppressed - if (!typeInfo->parseAcceptsReturns(NT_INT) && !typeInfo->parseAcceptsReturns(NT_FLOAT)) { + if (!typeInfo->parseAcceptsReturns(NT_INT) + && !typeInfo->parseAcceptsReturns(NT_FLOAT) + && !typeInfo->parseAcceptsReturns(NT_NUMBER)) { if (getProgram()->getParseExceptionSink()) { QoreStringNode *desc = new QoreStringNode("lvalue has type "); typeInfo->getThisType(*desc); - desc->sprintf(", but the %s operator only works with integer or floating-point lvalues", name); + desc->sprintf(", but the %s only works with integer, floating-point, or numeric lvalues", name); qore_program_private::makeParseException(getProgram(), "PARSE-TYPE-ERROR", desc); } return -1; } if (typeInfo->parseReturnsType(NT_INT)) { - if (typeInfo->parseReturnsType(NT_FLOAT)) - typeInfo = bigIntOrFloatTypeInfo; + if (typeInfo->parseReturnsType(NT_FLOAT)) { + if (typeInfo->parseReturnsType(NT_NUMBER)) + typeInfo = bigIntFloatOrNumberTypeInfo; + else + typeInfo = bigIntOrFloatTypeInfo; + } else typeInfo = bigIntTypeInfo; } - else - typeInfo = floatTypeInfo; + else { + if (typeInfo->parseReturnsType(NT_FLOAT)) + if (typeInfo->parseReturnsType(NT_NUMBER)) + typeInfo = floatOrNumberTypeInfo; + else + typeInfo = floatTypeInfo; + else + typeInfo = numberTypeInfo; + } return 0; } +int check_lvalue_number(const QoreTypeInfo*& typeInfo, const char* name) { + // make sure the lvalue can be assigned a floating-point value + // raise a parse exception only if parse exceptions are not suppressed + if (!typeInfo->parseAcceptsReturns(NT_NUMBER) && getProgram()->getParseExceptionSink()) { + QoreStringNode *desc = new QoreStringNode("lvalue has type "); + typeInfo->getThisType(*desc); + desc->sprintf(", but the %s will assign it a number value", name); + qore_program_private::makeParseException(getProgram(), "PARSE-TYPE-ERROR", desc); + return -1; + } + return 0; +} + // set the return value for op_minus (-) static AbstractQoreNode *check_op_minus(QoreTreeNode *tree, LocalVar *oflag, int pflag, int &lvids, const QoreTypeInfo *&returnTypeInfo, const char *name, const char *desc) { const QoreTypeInfo *leftTypeInfo = 0; @@ -3528,12 +3730,14 @@ OP_LOG_OR->addEffectFunction(op_log_or); OP_LOG_LT = add(new Operator(2, "<", "less-than", 1, false, false, check_op_logical)); + OP_LOG_LT->addFunction(op_log_lt_number); OP_LOG_LT->addFunction(op_log_lt_float); OP_LOG_LT->addFunction(op_log_lt_bigint); OP_LOG_LT->addFunction(op_log_lt_string); OP_LOG_LT->addFunction(op_log_lt_date); OP_LOG_GT = add(new Operator(2, ">", "greater-than", 1, false, false, check_op_logical)); + OP_LOG_LT->addFunction(op_log_gt_number); OP_LOG_GT->addFunction(op_log_gt_float); OP_LOG_GT->addFunction(op_log_gt_bigint); OP_LOG_GT->addFunction(op_log_gt_string); @@ -3541,6 +3745,7 @@ OP_LOG_EQ = add(new Operator(2, "==", "logical-equals", 1, false, false, check_op_logical)); OP_LOG_EQ->addFunction(op_log_eq_string); + OP_LOG_LT->addFunction(op_log_eq_number); OP_LOG_EQ->addFunction(op_log_eq_float); OP_LOG_EQ->addFunction(op_log_eq_bigint); OP_LOG_EQ->addFunction(op_log_eq_boolean); @@ -3549,6 +3754,7 @@ OP_LOG_NE = add(new Operator(2, "!=", "not-equals", 1, false, false, check_op_logical)); OP_LOG_NE->addFunction(op_log_ne_string); + OP_LOG_LT->addFunction(op_log_ne_number); OP_LOG_NE->addFunction(op_log_ne_float); OP_LOG_NE->addFunction(op_log_ne_bigint); OP_LOG_NE->addFunction(op_log_ne_boolean); @@ -3556,12 +3762,14 @@ OP_LOG_NE->addNoConvertFunction(NT_ALL, NT_ALL, op_log_ne_all); OP_LOG_LE = add(new Operator(2, "<=", "less-than-or-equals", 1, false, false, check_op_logical)); + OP_LOG_LT->addFunction(op_log_le_number); OP_LOG_LE->addFunction(op_log_le_float); OP_LOG_LE->addFunction(op_log_le_bigint); OP_LOG_LE->addFunction(op_log_le_string); OP_LOG_LE->addFunction(op_log_le_date); OP_LOG_GE = add(new Operator(2, ">=", "greater-than-or-equals", 1, false, false, check_op_logical)); + OP_LOG_LT->addFunction(op_log_ge_number); OP_LOG_GE->addFunction(op_log_ge_float); OP_LOG_GE->addFunction(op_log_ge_bigint); OP_LOG_GE->addFunction(op_log_ge_string); @@ -3591,6 +3799,7 @@ // bigint operators OP_LOG_CMP = add(new Operator(2, "<=>", "logical-comparison", 1, false, false, check_op_returns_integer)); OP_LOG_CMP->addFunction(op_cmp_string); + OP_LOG_CMP->addFunction(op_cmp_number); OP_LOG_CMP->addFunction(op_cmp_double); OP_LOG_CMP->addFunction(op_cmp_bigint); OP_LOG_CMP->addCompareDateFunction(); @@ -3619,6 +3828,7 @@ OP_MINUS = add(new Operator(2, "-", "minus", 1, false, false, check_op_minus)); OP_MINUS->addFunction(op_minus_date); + OP_MINUS->addFunction(op_minus_number); OP_MINUS->addFunction(op_minus_float); OP_MINUS->addFunction(op_minus_bigint); OP_MINUS->addFunction(op_minus_hash_string); @@ -3639,11 +3849,13 @@ OP_PLUS->addDefaultNothing(); OP_MULT = add(new Operator(2, "*", "multiply", 1, false, false, check_op_multiply)); + OP_MULT->addFunction(op_multiply_number); OP_MULT->addFunction(op_multiply_float); OP_MULT->addFunction(op_multiply_bigint); // return value is the same as with * OP_DIV = add(new Operator(2, "/", "divide", 1, false, false, check_op_multiply)); + OP_DIV->addFunction(op_divide_number); OP_DIV->addFunction(op_divide_float); OP_DIV->addFunction(op_divide_bigint); Modified: qore/trunk/lib/QoreDivideEqualsOperatorNode.cpp =================================================================== --- qore/trunk/lib/QoreDivideEqualsOperatorNode.cpp 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/lib/QoreDivideEqualsOperatorNode.cpp 2012-09-11 16:15:18 UTC (rev 5030) @@ -27,9 +27,6 @@ AbstractQoreNode *QoreDivideEqualsOperatorNode::parseInitImpl(LocalVar *oflag, int pflag, int &lvids, const QoreTypeInfo *&typeInfo) { parseInitIntern(op_str.getBuffer(), oflag, pflag, lvids, typeInfo); - if (ti == bigIntTypeInfo || ti == softBigIntTypeInfo) - return makeSpecialization<QoreIntDivideEqualsOperatorNode>(); - return this; } @@ -43,14 +40,18 @@ if (!v) return 0; + // is either side a number? + if ((res && res->getType() == NT_NUMBER) || v.getType() == NT_NUMBER) { + v.divideEqualsNumber(*res, "</= operator>"); + } // is either side a float? - if ((res && res->getType() == NT_FLOAT) || v.getType() == NT_FLOAT) { + else if ((res && res->getType() == NT_FLOAT) || v.getType() == NT_FLOAT) { double val = res ? res->getAsFloat() : 0.0; if (val == 0.0) { xsink->raiseException("DIVISION-BY-ZERO", "division by zero in floating-point expression"); return 0; } - v.divideEqualsFloat(val); + v.divideEqualsFloat(val, "</= operator>"); } else { // do integer divide equals int64 val = res ? res->getAsBigInt() : 0; @@ -59,7 +60,7 @@ return 0; } // get new value if necessary - v.divideEqualsBigInt(val); + v.divideEqualsBigInt(val, "</= operator>"); } // reference return value and return Deleted: qore/trunk/lib/QoreIntDivideEqualsOperatorNode.cpp =================================================================== --- qore/trunk/lib/QoreIntDivideEqualsOperatorNode.cpp 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/lib/QoreIntDivideEqualsOperatorNode.cpp 2012-09-11 16:15:18 UTC (rev 5030) @@ -1,63 +0,0 @@ -/* - QoreIntDivideEqualsOperatorNode.cpp - - Qore Programming Language - - Copyright 2003 - 2012 David Nichols - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <qore/Qore.h> - -AbstractQoreNode *QoreIntDivideEqualsOperatorNode::evalImpl(ExceptionSink *xsink) const { - int64 rv = QoreIntDivideEqualsOperatorNode::bigIntEvalImpl(xsink); - if (!ref_rv || *xsink) - return 0; - - return new QoreBigIntNode(rv); -} - -AbstractQoreNode *QoreIntDivideEqualsOperatorNode::evalImpl(bool &needs_deref, ExceptionSink *xsink) const { - needs_deref = ref_rv; - return QoreIntDivideEqualsOperatorNode::evalImpl(xsink); -} - -int64 QoreIntDivideEqualsOperatorNode::bigIntEvalImpl(ExceptionSink *xsink) const { - int64 rv = right->bigIntEval(xsink); - if (*xsink) - return 0; - - if (!rv) { - xsink->raiseException("DIVISION-BY-ZERO", "division by zero in integer expression"); - return 0; - } - LValueHelper v(left, xsink); - if (!v) - return 0; - return v.divideEqualsBigInt(rv, "</= operator>"); -} - -int QoreIntDivideEqualsOperatorNode::integerEvalImpl(ExceptionSink *xsink) const { - return QoreIntDivideEqualsOperatorNode::bigIntEvalImpl(xsink); -} - -double QoreIntDivideEqualsOperatorNode::floatEvalImpl(ExceptionSink *xsink) const { - return QoreIntDivideEqualsOperatorNode::bigIntEvalImpl(xsink); -} - -bool QoreIntDivideEqualsOperatorNode::boolEvalImpl(ExceptionSink *xsink) const { - return QoreIntDivideEqualsOperatorNode::bigIntEvalImpl(xsink); -} Deleted: qore/trunk/lib/QoreIntMultiplyEqualsOperatorNode.cpp =================================================================== --- qore/trunk/lib/QoreIntMultiplyEqualsOperatorNode.cpp 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/lib/QoreIntMultiplyEqualsOperatorNode.cpp 2012-09-11 16:15:18 UTC (rev 5030) @@ -1,58 +0,0 @@ -/* - QoreIntMultiplyEqualsOperatorNode.cpp - - Qore Programming Language - - Copyright 2003 - 2012 David Nichols - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include <qore/Qore.h> - -AbstractQoreNode *QoreIntMultiplyEqualsOperatorNode::evalImpl(ExceptionSink *xsink) const { - int64 rv = QoreIntMultiplyEqualsOperatorNode::bigIntEvalImpl(xsink); - if (!ref_rv || *xsink) - return 0; - - return new QoreBigIntNode(rv); -} - -AbstractQoreNode *QoreIntMultiplyEqualsOperatorNode::evalImpl(bool &needs_deref, ExceptionSink *xsink) const { - needs_deref = ref_rv; - return QoreIntMultiplyEqualsOperatorNode::evalImpl(xsink); -} - -int64 QoreIntMultiplyEqualsOperatorNode::bigIntEvalImpl(ExceptionSink *xsink) const { - int64 rv = right->bigIntEval(xsink); - if (*xsink) - return 0; - LValueHelper v(left, xsink); - if (!v) - return 0; - return v.multiplyEqualsBigInt(rv, "<*= operator>"); -} - -int QoreIntMultiplyEqualsOperatorNode::integerEvalImpl(ExceptionSink *xsink) const { - return QoreIntMultiplyEqualsOperatorNode::bigIntEvalImpl(xsink); -} - -double QoreIntMultiplyEqualsOperatorNode::floatEvalImpl(ExceptionSink *xsink) const { - return QoreIntMultiplyEqualsOperatorNode::bigIntEvalImpl(xsink); -} - -bool QoreIntMultiplyEqualsOperatorNode::boolEvalImpl(ExceptionSink *xsink) const { - return QoreIntMultiplyEqualsOperatorNode::bigIntEvalImpl(xsink); -} Modified: qore/trunk/lib/QoreMinusEqualsOperatorNode.cpp =================================================================== --- qore/trunk/lib/QoreMinusEqualsOperatorNode.cpp 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/lib/QoreMinusEqualsOperatorNode.cpp 2012-09-11 16:15:18 UTC (rev 5030) @@ -37,6 +37,7 @@ if (!ti->isType(NT_HASH) && !ti->isType(NT_OBJECT) && !ti->isType(NT_FLOAT) + && !ti->isType(NT_NUMBER) && !ti->isType(NT_DATE)) { // if the lhs type is not one of the above types, // there are 2 possibilities: the lvalue has no value, in which @@ -86,6 +87,10 @@ const QoreFloatNode *f = reinterpret_cast<const QoreFloatNode *>(*new_right); v.assign(new QoreFloatNode(-f->f)); } + else if (new_right->getType() == NT_NUMBER) { + const QoreNumberNode* num = reinterpret_cast<const QoreNumberNode*>(*new_right); + v.assign(num->negate()); + } else { // optimization to eliminate a virtual function call in the most common case int64 i = new_right->getAsBigInt(); @@ -104,6 +109,9 @@ if (vtype == NT_FLOAT) { v.minusEqualsFloat(new_right->getAsFloat()); } + else if (vtype == NT_NUMBER) { + v.minusEqualsNumber(*new_right, "<-= operator>"); + } else if (vtype == NT_DATE) { DateTimeValueHelper date(*new_right); v.assign(reinterpret_cast<DateTimeNode *>(v.getValue())->subtractBy(*date)); Modified: qore/trunk/lib/QoreMultiplyEqualsOperatorNode.cpp =================================================================== --- qore/trunk/lib/QoreMultiplyEqualsOperatorNode.cpp 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/lib/QoreMultiplyEqualsOperatorNode.cpp 2012-09-11 16:15:18 UTC (rev 5030) @@ -27,9 +27,6 @@ AbstractQoreNode *QoreMultiplyEqualsOperatorNode::parseInitImpl(LocalVar *oflag, int pflag, int &lvids, const QoreTypeInfo *&typeInfo) { parseInitIntern(op_str.getBuffer(), oflag, pflag, lvids, typeInfo); - if (ti == bigIntTypeInfo || ti == softBigIntTypeInfo) - return makeSpecialization<QoreIntMultiplyEqualsOperatorNode>(); - return this; } @@ -43,12 +40,16 @@ if (!v) return 0; + // is either side a number? + if ((res && res->getType() == NT_NUMBER) || v.getType() == NT_NUMBER) { + v.multiplyEqualsNumber(*res, "<*= operator>"); + } // is either side a float? - if (v.getType() == NT_FLOAT) - v.multiplyEqualsFloat(res ? res->getAsFloat() : 0.0); + else if (v.getType() == NT_FLOAT) + v.multiplyEqualsFloat(res ? res->getAsFloat() : 0.0, "<*= operator>"); else { if (res && res->getType() == NT_FLOAT) { - v.multiplyEqualsFloat((reinterpret_cast<const QoreFloatNode *>(*res))->f); + v.multiplyEqualsFloat((reinterpret_cast<const QoreFloatNode*>(*res))->f, "<*= operator>"); } else { // do integer multiply equals if (v.getType() == NT_NOTHING || !res) { @@ -56,7 +57,7 @@ return 0; } else - v.multiplyEqualsBigInt(res->getAsBigInt()); + v.multiplyEqualsBigInt(res->getAsBigInt(), "<*= operator>"); } } Modified: qore/trunk/lib/QoreNumberNode.cpp =================================================================== --- qore/trunk/lib/QoreNumberNode.cpp 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/lib/QoreNumberNode.cpp 2012-09-11 16:15:18 UTC (rev 5030) @@ -21,152 +21,8 @@ */ #include <qore/Qore.h> +#include <qore/intern/qore_number_private.h> -#define QORE_DEFAULT_PREC 128 -#define QORE_MAX_PREC 8192 -// round to nearest (roundTiesToEven in IEEE 754-2008) -#define QORE_MPFR_RND MPFR_RNDN -// MPFR_RNDA - -struct qore_number_private_intern { - mpfr_t num; - - DLLLOCAL qore_number_private_intern() { - mpfr_init2(num, QORE_DEFAULT_PREC); - } - - DLLLOCAL qore_number_private_intern(mpfr_prec_t prec) { - if (prec > QORE_MAX_PREC) - prec = QORE_MAX_PREC; - mpfr_init2(num, prec); - } - - DLLLOCAL ~qore_number_private_intern() { - mpfr_clear(num); - } -}; - -struct qore_number_private : public qore_number_private_intern { - DLLLOCAL explicit qore_number_private(mpfr_prec_t prec) : qore_number_private_intern(prec) { - } - - DLLLOCAL qore_number_private(double f) { - mpfr_set_d(num, f, QORE_MPFR_RND); - } - - DLLLOCAL qore_number_private(int64 i) { - mpfr_set_sj(num, i, QORE_MPFR_RND); - } - - DLLLOCAL qore_number_private(const char* str) : qore_number_private_intern(QORE_MAX(QORE_DEFAULT_PREC, strlen(str)*10)) { - mpfr_set_str(num, str, 10, QORE_MPFR_RND); - } - - DLLLOCAL qore_number_private(const qore_number_private& old) : qore_number_private_intern(mpfr_get_prec(old.num)) { - mpfr_set(num, old.num, QORE_MPFR_RND); - } - - DLLLOCAL double getAsFloat() const { - return mpfr_get_d(num, QORE_MPFR_RND); - } - - DLLLOCAL int64 getAsBigInt() const { - return mpfr_get_sj(num, QORE_MPFR_RND); - } - - DLLLOCAL bool getAsBool() const { - return !zero(); - } - - DLLLOCAL bool zero() const { - return (bool)mpfr_zero_p(num); - } - - DLLLOCAL bool nan() const { - return (bool)mpfr_nan_p(num); - } - - DLLLOCAL bool inf() const { - return (bool)mpfr_inf_p(num); - } - - DLLLOCAL bool number() const { - return (bool)mpfr_number_p(num); - } - - // regular and not zero - DLLLOCAL bool regular() const { - return (bool)mpfr_regular_p(num); - } - - DLLLOCAL void getAsString(QoreString& str) const { - // first check if it's zero - if (zero()) { - str.concat("0n"); - return; - } - mpfr_exp_t exp; - char* buf = mpfr_get_str(0, &exp, 10, 0, num, QORE_MPFR_RND); - if (!buf) { - str.concat("<number error>"); - return; - } - - // if it's a regular number, then format accordingly - if (number()) { - qore_size_t len = str.size(); - //printd(0, "QoreNumberNode::getAsString() this: %p '%s' exp "QLLD" len: "QLLD"\n", this, buf, exp, len); - - str.concat(buf); - // trim the trailing zeros off the end - str.trim_trailing('0'); - if (exp <= 0) { - exp = -exp; - str.insert("0.", len); - if (exp) - str.insertch('0', len + 2, exp); - } - else { - // get remaining length of string (how many characters were added) - qore_size_t rlen = str.size() - len; - - //printd(0, "QoreNumberNode::getAsString() this: %p str: '%s' rlen: "QLLD"\n", this, str.getBuffer(), rlen); - - // assert that we have added at least 1 character - assert(rlen > 0); - if (exp > rlen) - str.insertch('0', str.size(), exp - rlen); - else if (exp < rlen) - str.insertch('.', len + exp, 1); - } - str.concat('n'); - } - - mpfr_free_str(buf); - } - - DLLLOCAL int compare(const qore_number_private& right) const { - return mpfr_cmp(num, right.num); - } - - DLLLOCAL int compare(double right) const { - return mpfr_cmp_d(num, right); - } - - DLLLOCAL int compare(int64 right) const { - MPFR_DECL_INIT(r, QORE_DEFAULT_PREC); - mpfr_set_sj(r, right, QORE_MPFR_RND); - return mpfr_cmp(num, r); - } - - DLLLOCAL qore_number_private* doPlus(const qore_number_private& r) const { - mpfr_prec_t prec = QORE_MAX(mpfr_get_prec(num), mpfr_get_prec(r.num)); - qore_number_private* p = new qore_number_private(prec); - mpfr_add(p->num, num, r.num, QORE_MPFR_RND); - return p; - } -}; - QoreNumberNode::QoreNumberNode(struct qore_number_private* p) : SimpleValueQoreNode(NT_NUMBER), priv(p) { } @@ -310,6 +166,35 @@ return priv->zero(); } -QoreNumberNode* QoreNumberNode::doPlus(const QoreNumberNode* right) const { - return new QoreNumberNode(priv->doPlus(*right->priv)); +QoreNumberNode* QoreNumberNode::doPlus(const QoreNumberNode& right) const { + return new QoreNumberNode(priv->doPlus(*right.priv)); } + +//! add the argument to this value and return the result +QoreNumberNode* QoreNumberNode::doMinus(const QoreNumberNode& n) const { + return new QoreNumberNode(priv->doMinus(*n.priv)); +} + +//! add the argument to this value and return the result +QoreNumberNode* QoreNumberNode::doMultiply(const QoreNumberNode& n) const { + return new QoreNumberNode(priv->doMultiply(*n.priv)); +} + +//! add the argument to this value and return the result +QoreNumberNode* QoreNumberNode::doDivideBy(const QoreNumberNode& n, ExceptionSink* xsink) const { + qore_number_private* p = priv->doDivideBy(*n.priv, xsink); + return p ? new QoreNumberNode(p) : 0; +} + +QoreNumberNode* QoreNumberNode::negate() const { + return new QoreNumberNode(priv->negate()); +} + +int QoreNumberNode::compare(const QoreNumberNode& n) const { + return priv->compare(*n.priv); +} + +QoreNumberNode* QoreNumberNode::numberRefSelf() const { + ref(); + return const_cast<QoreNumberNode*>(this); +} Modified: qore/trunk/lib/QorePlusEqualsOperatorNode.cpp =================================================================== --- qore/trunk/lib/QorePlusEqualsOperatorNode.cpp 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/lib/QorePlusEqualsOperatorNode.cpp 2012-09-11 16:15:18 UTC (rev 5030) @@ -39,6 +39,7 @@ && !ti->isType(NT_OBJECT) && !ti->isType(NT_STRING) && !ti->isType(NT_FLOAT) + && !ti->isType(NT_NUMBER) && !ti->isType(NT_DATE) && !ti->isType(NT_BINARY)) { // if the lhs type is not one of the above types, @@ -129,6 +130,9 @@ vs->concat(*str, xsink); } } + else if (vtype == NT_NUMBER) { + v.plusEqualsNumber(*new_right, "<+= operator>"); + } else if (vtype == NT_FLOAT) { double f = new_right ? new_right->getAsFloat() : 0.0; v.plusEqualsFloat(f); Modified: qore/trunk/lib/QorePostDecrementOperatorNode.cpp =================================================================== --- qore/trunk/lib/QorePostDecrementOperatorNode.cpp 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/lib/QorePostDecrementOperatorNode.cpp 2012-09-11 16:15:18 UTC (rev 5030) @@ -36,6 +36,9 @@ LValueHelper n(exp, xsink); if (!n) return 0; + if (n.getType() == NT_NUMBER) + return n.postDecrementNumber(ref_rv, "<-- (post) operator>"); + if (n.getType() == NT_FLOAT) { double f = n.postDecrementFloat("<-- (post) operator>"); assert(!*xsink); Modified: qore/trunk/lib/QorePostIncrementOperatorNode.cpp =================================================================== --- qore/trunk/lib/QorePostIncrementOperatorNode.cpp 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/lib/QorePostIncrementOperatorNode.cpp 2012-09-11 16:15:18 UTC (rev 5030) @@ -36,6 +36,9 @@ LValueHelper n(exp, xsink); if (!n) return 0; + if (n.getType() == NT_NUMBER) + return n.postIncrementNumber(ref_rv, "<-- (post) operator>"); + if (n.getType() == NT_FLOAT) { double f = n.postIncrementFloat("<++ (post) operator>"); assert(!*xsink); Modified: qore/trunk/lib/QorePreDecrementOperatorNode.cpp =================================================================== --- qore/trunk/lib/QorePreDecrementOperatorNode.cpp 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/lib/QorePreDecrementOperatorNode.cpp 2012-09-11 16:15:18 UTC (rev 5030) @@ -36,7 +36,11 @@ LValueHelper n(exp, xsink); if (!n) return 0; - if (n.getType() == NT_FLOAT) { + if (n.getType() == NT_NUMBER) { + n.preDecrementNumber("<-- (pre) operator>"); + assert(!*xsink); + } + else if (n.getType() == NT_FLOAT) { n.preDecrementFloat("<-- (pre) operator>"); assert(!*xsink); } Modified: qore/trunk/lib/QorePreIncrementOperatorNode.cpp =================================================================== --- qore/trunk/lib/QorePreIncrementOperatorNode.cpp 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/lib/QorePreIncrementOperatorNode.cpp 2012-09-11 16:15:18 UTC (rev 5030) @@ -36,7 +36,11 @@ LValueHelper n(exp, xsink); if (!n) return 0; - if (n.getType() == NT_FLOAT) { + if (n.getType() == NT_NUMBER) { + n.preIncrementNumber("<++ (pre) operator>"); + assert(!*xsink); + } + else if (n.getType() == NT_FLOAT) { n.preIncrementFloat("<++ (pre) operator>"); assert(!*xsink); } Modified: qore/trunk/lib/QoreTypeInfo.cpp =================================================================== --- qore/trunk/lib/QoreTypeInfo.cpp 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/lib/QoreTypeInfo.cpp 2012-09-11 16:15:18 UTC (rev 5030) @@ -153,6 +153,12 @@ static IntOrFloatTypeInfo staticIntOrFloatTypeInfo; const QoreTypeInfo* bigIntOrFloatTypeInfo = &staticIntOrFloatTypeInfo; +static IntFloatOrNumberTypeInfo staticIntFloatOrNumberTypeInfo; +const QoreTypeInfo* bigIntFloatOrNumberTypeInfo = &staticIntFloatOrNumberTypeInfo; + +static FloatOrNumberTypeInfo staticFloatOrNumberTypeInfo; +const QoreTypeInfo* floatOrNumberTypeInfo = &staticFloatOrNumberTypeInfo; + QoreListNode *emptyList; QoreHashNode *emptyHash; QoreStringNode *NullString; Modified: qore/trunk/lib/Variable.cpp =================================================================== --- qore/trunk/lib/Variable.cpp 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/lib/Variable.cpp 2012-09-11 16:15:18 UTC (rev 5030) @@ -35,6 +35,7 @@ #include <qore/intern/ParserSupport.h> #include <qore/intern/QoreObjectIntern.h> #include <qore/intern/QoreValue.h> +#include <qore/intern/qore_number_private.h> int qore_gvar_ref_u::write(ExceptionSink* xsink) const { if (_refptr & 1) { @@ -660,8 +661,13 @@ } double LValueHelper::multiplyEqualsFloat(double va, const char* desc) { - if (val) + if (val) { + if (val->getType() != NT_FLOAT) { + typeInfo->doTypeException(0, desc, floatTypeInfo->getName(), vl.xsink); + return 0.0; + } return val->multiplyEqualsFloat(va, getTempRef()); + } // increment current value QoreFloatNode* f = ensureUnique<QoreFloatNode, double, NT_FLOAT>(floatTypeInfo, desc); @@ -673,8 +679,13 @@ double LValueHelper::divideEqualsFloat(double va, const char* desc) { assert(va); - if (val) + if (val) { + if (val->getType() != NT_FLOAT) { + typeInfo->doTypeException(0, desc, floatTypeInfo->getName(), vl.xsink); + return 0.0; + } return val->divideEqualsFloat(va, getTempRef()); + } // increment current value QoreFloatNode* f = ensureUnique<QoreFloatNode, double, NT_FLOAT>(floatTypeInfo, desc); @@ -684,6 +695,88 @@ return f->f; } +void LValueHelper::preIncrementNumber(const char* desc) { + QoreNumberNode* n = ensureUniqueNumber(desc); + if (n) + qore_number_private::inc(*n); +} + +void LValueHelper::preDecrementNumber(const char* desc) { + QoreNumberNode* n = ensureUniqueNumber(desc); + if (n) + qore_number_private::dec(*n); +} + +QoreNumberNode* LValueHelper::postIncrementNumber(bool ref_rv, const char* desc) { + QoreNumberNode* n = ensureUniqueNumber(desc); + if (!n) + return 0; + QoreNumberNode* rv = ref_rv ? new QoreNumberNode(*n) : 0; + qore_number_private::inc(*n); + return rv; +} + +QoreNumberNode* LValueHelper::postDecrementNumber(bool ref_rv, const char* desc) { + QoreNumberNode* n = ensureUniqueNumber(desc); + if (!n) + return 0; + QoreNumberNode* rv = ref_rv ? new QoreNumberNode(*n) : 0; + qore_number_private::dec(*n); + return rv; +} + +void LValueHelper::plusEqualsNumber(const AbstractQoreNode* r, const char* desc) { + SimpleRefHolder<QoreNumberNode> rn_holder; + QoreNumberNode* rn; + if (get_node_type(r) == NT_NUMBER) + rn = const_cast<QoreNumberNode*>(reinterpret_cast<const QoreNumberNode*>(r)); + else + rn_holder = (rn = new QoreNumberNode(r)); + + QoreNumberNode* n = ensureUniqueNumber(desc); + if (n) + qore_number_private::plusEquals(*n, *rn); +} + +void LValueHelper::minusEqualsNumber(const AbstractQoreNode* r, const char* desc) { + SimpleRefHolder<QoreNumberNode> rn_holder; + QoreNumberNode* rn; + if (get_node_type(r) == NT_NUMBER) + rn = const_cast<QoreNumberNode*>(reinterpret_cast<const QoreNumberNode*>(r)); + else + rn_holder = (rn = new QoreNumberNode(r)); + + QoreNumberNode* n = ensureUniqueNumber(desc); + if (n) + qore_number_private::minusEquals(*n, *rn); +} + +void LValueHelper::multiplyEqualsNumber(const AbstractQoreNode* r, const char* desc) { + SimpleRefHolder<QoreNumberNode> rn_holder; + QoreNumberNode* rn; + if (get_node_type(r) == NT_NUMBER) + rn = const_cast<QoreNumberNode*>(reinterpret_cast<const QoreNumberNode*>(r)); + else + rn_holder = (rn = new QoreNumberNode(r)); + + QoreNumberNode* n = ensureUniqueNumber(desc); + if (n) + qore_number_private::multiplyEquals(*n, *rn); +} + +void LValueHelper::divideEqualsNumber(const AbstractQoreNode* r, const char* desc) { + SimpleRefHolder<QoreNumberNode> rn_holder; + QoreNumberNode* rn; + if (get_node_type(r) == NT_NUMBER) + rn = const_cast<QoreNumberNode*>(reinterpret_cast<const QoreNumberNode*>(r)); + else + rn_holder = (rn = new QoreNumberNode(r)); + + QoreNumberNode* n = ensureUniqueNumber(desc); + if (n) + qore_number_private::divideEquals(*n, *rn); +} + int64 LValueHelper::removeBigInt() { if (val) return val->removeBigInt(getTempRef()); Modified: qore/trunk/lib/scanner.lpp =================================================================== --- qore/trunk/lib/scanner.lpp 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/lib/scanner.lpp 2012-09-11 16:15:18 UTC (rev 5030) @@ -1206,6 +1206,7 @@ {DIGIT}+"."{DIGIT}+ yylval->decimal = strtod(yytext, 0); return QFLOAT; {DIGIT}+[eE][+-]?{DIGIT}+ yylval->decimal = strtod(yytext, 0); return QFLOAT; {DIGIT}+"."{DIGIT}+[eE][+-]?{DIGIT}+ yylval->decimal = strtod(yytext, 0); return QFLOAT; +{DIGIT}+n yylval->num = new QoreNumberNode(yytext); return NUMBER; {DIGIT}+"."{DIGIT}+n yylval->num = new QoreNumberNode(yytext); return NUMBER; {DIGIT}+[eE][+-]?{DIGIT}+n yylval->num = new QoreNumberNode(yytext); return NUMBER; {DIGIT}+"."{DIGIT}+[eE][+-]?{DIGIT}+n yylval->num = new QoreNumberNode(yytext); return NUMBER; Modified: qore/trunk/lib/single-compilation-unit.cpp =================================================================== --- qore/trunk/lib/single-compilation-unit.cpp 2012-09-10 21:02:42 UTC (rev 5029) +++ qore/trunk/lib/single-compilation-unit.cpp 2012-09-11 16:15:18 UTC (rev 5030) @@ -137,9 +137,7 @@ #include "QoreAndEqualsOperatorNode.cpp" #include "QoreModulaEqualsOperatorNode.cpp" #include "QoreMultiplyEqualsOperatorNode.cpp" -#include "QoreIntMultiplyEqualsOperatorNode.cpp" #include "QoreDivideEqualsOperatorNode.cpp" -#include "QoreIntDivideEqualsOperatorNode.cpp" #include "QoreXorEqualsOperatorNode.cpp" #include "QoreShiftLeftEqualsOperatorNode.cpp" #include "QoreShiftRightEqualsOperatorNode.cpp" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <david_nichols@us...> - 2012-09-10 21:02:53
|
Revision: 5029 http://qore.svn.sourceforge.net/qore/?rev=5029&view=rev Author: david_nichols Date: 2012-09-10 21:02:42 +0000 (Mon, 10 Sep 2012) Log Message: ----------- * started implementing basic number operations * implemented parser supoprt for number values (suffixed with n; ex: "100n", "50e-16n", "0.000000233n", etc * implemented suport for parsing floating-point values with an exponent (ex: 2.323e+20) Modified Paths: -------------- qore/trunk/configure.ac qore/trunk/include/qore/QoreLib.h qore/trunk/include/qore/QoreNumberNode.h qore/trunk/include/qore/QoreString.h qore/trunk/include/qore/intern/Operator.h qore/trunk/include/qore/intern/QoreLibIntern.h qore/trunk/include/qore/intern/QoreTypeInfo.h qore/trunk/include/qore/intern/ThreadResourceList.h qore/trunk/lib/Operator.cpp qore/trunk/lib/QoreNumberNode.cpp qore/trunk/lib/QoreString.cpp qore/trunk/lib/parser.ypp qore/trunk/lib/scanner.lpp qore/trunk/lib/thread.cpp Modified: qore/trunk/configure.ac =================================================================== --- qore/trunk/configure.ac 2012-09-10 10:06:02 UTC (rev 5028) +++ qore/trunk/configure.ac 2012-09-10 21:02:42 UTC (rev 5029) @@ -681,6 +681,22 @@ AC_MSG_RESULT([includes $with_zlib_includes libs $with_zlib_libs (shared)]) fi +AC_MSG_CHECKING([for mpfr libraries and header files]) +for dir in "${with_mpfr_dir}" "${with_lib_prefix}" "${find_prefix}" /usr / /usr/local /opt/gnu /opt/mpfr /usr/local/mpfr /opt/local /sw /usr/sfw /opt/sfw; do + find_mpfr $dir + if test -n "$MPFR_LDFLAGS"; then + break + fi +done +if test -z "$MPFR_LDFLAGS"; then + AC_MSG_ERROR([no mpfr library found]) +fi +if test -n "$mpfr_static"; then + AC_MSG_RESULT([includes $with_mpfr_includes libs $with_mpfr_libs (static)]) +else + AC_MSG_RESULT([includes $with_mpfr_includes libs $with_mpfr_libs (shared)]) +fi + AC_MSG_CHECKING([for gmp libraries and header files]) for dir in "${with_gmp_dir}" "${with_lib_prefix}" "${find_prefix}" /usr / /usr/local /opt/gnu /opt/gmp /usr/local/gmp /opt/local /sw /usr/sfw /opt/sfw; do find_gmp $dir @@ -697,22 +713,6 @@ AC_MSG_RESULT([includes $with_gmp_includes libs $with_gmp_libs (shared)]) fi -AC_MSG_CHECKING([for mpfr libraries and header files]) -for dir in "${with_mpfr_dir}" "${with_lib_prefix}" "${find_prefix}" /usr / /usr/local /opt/gnu /opt/mpfr /usr/local/mpfr /opt/local /sw /usr/sfw /opt/sfw; do - find_mpfr $dir - if test -n "$MPFR_LDFLAGS"; then - break - fi -done -if test -z "$MPFR_LDFLAGS"; then - AC_MSG_ERROR([no mpfr library found]) -fi -if test -n "$mpfr_static"; then - AC_MSG_RESULT([includes $with_mpfr_includes libs $with_mpfr_libs (static)]) -else - AC_MSG_RESULT([includes $with_mpfr_includes libs $with_mpfr_libs (shared)]) -fi - set_pcre_cppflags() { if test "$1" != "/usr/include"; then PCRE_CPPFLAGS=-I$1 @@ -1270,7 +1270,7 @@ # Checks for header files. AC_HEADER_STDC AC_HEADER_SYS_WAIT -AC_CHECK_HEADERS([fcntl.h inttypes.h netdb.h netinet/in.h stddef.h stdlib.h string.h strings.h sys/socket.h sys/time.h unistd.h execinfo.h cxxabi.h arpa/inet.h sys/socket.h sys/statvfs.h winsock2.h ws2tcpip.h glob.h sys/un.h termios.h netinet/tcp.h pwd.h sys/wait.h getopt.h]) +AC_CHECK_HEADERS([fcntl.h inttypes.h netdb.h netinet/in.h stddef.h stdlib.h string.h strings.h sys/socket.h sys/time.h unistd.h execinfo.h cxxabi.h arpa/inet.h sys/socket.h sys/statvfs.h winsock2.h ws2tcpip.h glob.h sys/un.h termios.h netinet/tcp.h pwd.h sys/wait.h getopt.h stdint.h]) # check for umem.h AC_CHECK_HEADER([umem.h], have_umem_h=yes, have_umem_h=no) Modified: qore/trunk/include/qore/QoreLib.h =================================================================== --- qore/trunk/include/qore/QoreLib.h 2012-09-10 10:06:02 UTC (rev 5028) +++ qore/trunk/include/qore/QoreLib.h 2012-09-10 21:02:42 UTC (rev 5029) @@ -396,6 +396,9 @@ //! macro to return the maximum of 2 numbers #define QORE_MAX(a, b) ((a) > (b) ? (a) : (b)) +//! macro to return the minimum of 2 numbers +#define QORE_MIN(a, b) ((a) < (b) ? (a) : (b)) + #define QORE_PARAM_NO_ARG (NULL) // define QORE_PATH_MAX Modified: qore/trunk/include/qore/QoreNumberNode.h =================================================================== --- qore/trunk/include/qore/QoreNumberNode.h 2012-09-10 10:06:02 UTC (rev 5028) +++ qore/trunk/include/qore/QoreNumberNode.h 2012-09-10 21:02:42 UTC (rev 5029) @@ -53,7 +53,13 @@ */ DLLEXPORT virtual ~QoreNumberNode(); + // private + DLLLOCAL QoreNumberNode(struct qore_number_private* p); + public: + //! creates a new number value from the node, if not possible then the new number will be assigned 0 + DLLEXPORT QoreNumberNode(const AbstractQoreNode* n); + //! creates a new number value and assigns the initial value to it /** @param f the value for the object @@ -154,6 +160,12 @@ */ DLLEXPORT virtual const char* getTypeName() const; + //! add the argument to this value and return the result + DLLEXPORT QoreNumberNode* doPlus(const QoreNumberNode* right) const; + + //! returns true if the number is zero + DLLEXPORT bool zero() const; + //! returns the type information DLLLOCAL virtual AbstractQoreNode* parseInit(LocalVar* oflag, int pflag, int& lvids, const QoreTypeInfo*& typeInfo); Modified: qore/trunk/include/qore/QoreString.h =================================================================== --- qore/trunk/include/qore/QoreString.h 2012-09-10 10:06:02 UTC (rev 5028) +++ qore/trunk/include/qore/QoreString.h 2012-09-10 21:02:42 UTC (rev 5029) @@ -450,10 +450,28 @@ //! returns the string's buffer; this data should not be changed DLLEXPORT const char* getBuffer() const; - // Make sure the internal buffer has at least expected size in bytes. - // Useful to eliminate repeated reallocate() when data are appended in a loop. + //! Ensure the internal buffer has at least expected size in bytes + /** Useful to eliminate repeated buffer reallocations when data are appended in a loop + */ DLLEXPORT void allocate(unsigned requested_size); + //! insert a character at a certain position in the string a number of times + /** @param c the character to insert + @param pos the position to insert the character(s) (first position is 0) + @param times the number of times the character should be inserted + + @return 0 = OK, -1 = error (pos is greater than the string's length) + */ + DLLEXPORT int insertch(char c, qore_size_t pos, unsigned times); + + //! inserts a character string at a certain position in the string + /** @param str the string to insert + @param pos the position to insert the string (first position is 0) + + @return 0 = OK, -1 = error (pos is greater than the string's length) + */ + DLLEXPORT int insert(const char* str, qore_size_t pos); + //! append a character to the string a number of times DLLEXPORT void addch(char c, unsigned times); Modified: qore/trunk/include/qore/intern/Operator.h =================================================================== --- qore/trunk/include/qore/intern/Operator.h 2012-09-10 10:06:02 UTC (rev 5028) +++ qore/trunk/include/qore/intern/Operator.h 2012-09-10 21:02:42 UTC (rev 5029) @@ -94,6 +94,8 @@ typedef int64 (*op_bigint_func_t)(const AbstractQoreNode *l, const AbstractQoreNode *r, ExceptionSink *xsink); typedef double (*op_float_func_t)(const AbstractQoreNode *l, const AbstractQoreNode *r, ExceptionSink *xsink); +typedef QoreNumberNode *(*op_number_func_t)(const QoreNumberNode* l, const QoreNumberNode* r, ExceptionSink* xsink); + class AbstractOperatorFunction { public: qore_type_t ltype, rtype; @@ -568,6 +570,20 @@ DLLLOCAL virtual double float_eval(const AbstractQoreNode *l, const AbstractQoreNode *r, int args, ExceptionSink *xsink) const; }; +class NumberOperatorFunction : public AbstractOperatorFunction { + private: + op_number_func_t op_func; + + public: + DLLLOCAL NumberOperatorFunction(op_number_func_t f) : AbstractOperatorFunction(NT_NUMBER, NT_NUMBER), op_func(f) { + } + DLLLOCAL virtual ~NumberOperatorFunction() {} + DLLLOCAL virtual AbstractQoreNode *eval(const AbstractQoreNode *l, const AbstractQoreNode *r, bool ref_rv, int args, ExceptionSink *xsink) const; + DLLLOCAL virtual bool bool_eval(const AbstractQoreNode *l, const AbstractQoreNode *r, int args, ExceptionSink *xsink) const; + DLLLOCAL virtual int64 bigint_eval(const AbstractQoreNode *l, const AbstractQoreNode *r, int args, ExceptionSink *xsink) const; + DLLLOCAL virtual double float_eval(const AbstractQoreNode *l, const AbstractQoreNode *r, int args, ExceptionSink *xsink) const; +}; + class DefaultNothingOperatorFunction : public AbstractOperatorFunction { public: DLLLOCAL DefaultNothingOperatorFunction() : AbstractOperatorFunction(NT_ALL, NT_ALL) { @@ -704,6 +720,9 @@ DLLLOCAL void addFunction(op_compare_float_func_t f) { functions.push_back(new CompareFloatOperatorFunction(f)); } + DLLLOCAL void addFunction(op_number_func_t f) { + functions.push_back(new NumberOperatorFunction(f)); + } DLLLOCAL void addFunction(op_logic_func_t f) { functions.push_back(new LogicOperatorFunction(f)); } Modified: qore/trunk/include/qore/intern/QoreLibIntern.h =================================================================== --- qore/trunk/include/qore/intern/QoreLibIntern.h 2012-09-10 10:06:02 UTC (rev 5028) +++ qore/trunk/include/qore/intern/QoreLibIntern.h 2012-09-10 21:02:42 UTC (rev 5029) @@ -75,6 +75,13 @@ #include <netinet/tcp.h> #endif +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif +#ifdef HAVE_INTTYPES_H +#include <inttypes.h> +#endif + // for arbitrary-precision numeric support #include <mpfr.h> @@ -187,7 +194,6 @@ #ifndef HAVE_ATOLL #ifdef HAVE_STRTOIMAX -#include <inttypes.h> static inline long long atoll(const char* str) { return strtoimax(str, 0, 10); } Modified: qore/trunk/include/qore/intern/QoreTypeInfo.h =================================================================== --- qore/trunk/include/qore/intern/QoreTypeInfo.h 2012-09-10 10:06:02 UTC (rev 5028) +++ qore/trunk/include/qore/intern/QoreTypeInfo.h 2012-09-10 21:02:42 UTC (rev 5029) @@ -1359,7 +1359,7 @@ } }; -// accepts int, float, string, date, null, or boolean and returns an int +// accepts int, float, number, string, date, null, or boolean and returns an int class SoftBigIntTypeInfo : public AcceptsMultiFilterTypeInfo { protected: DLLLOCAL virtual const char *getNameImpl() const { @@ -1373,10 +1373,11 @@ return true; if (t != NT_FLOAT - && t != NT_STRING - && t != NT_BOOLEAN - && t != NT_DATE - && t != NT_NULL) + && t != NT_NUMBER + && t != NT_STRING + && t != NT_BOOLEAN + && t != NT_DATE + && t != NT_NULL) return false; int64 rv = n->getAsBigInt(); @@ -1392,6 +1393,7 @@ DLLLOCAL void init() { at.push_back(floatTypeInfo); + at.push_back(numberTypeInfo); at.push_back(stringTypeInfo); at.push_back(boolTypeInfo); at.push_back(dateTypeInfo); @@ -1423,10 +1425,11 @@ return true; if (t != NT_FLOAT - && t != NT_STRING - && t != NT_BOOLEAN - && t != NT_DATE - && t != NT_NULL) + && t != NT_NUMBER + && t != NT_STRING + && t != NT_BOOLEAN + && t != NT_DATE + && t != NT_NULL) return false; int64 rv = n->getAsBigInt(); @@ -1443,7 +1446,7 @@ } }; -// accepts int, float, string, date, null, or boolean and returns a float +// accepts int, float, number, string, date, null, or boolean and returns a float class SoftFloatTypeInfo : public AcceptsMultiFilterTypeInfo { protected: DLLLOCAL virtual const char *getNameImpl() const { @@ -1457,10 +1460,11 @@ return true; if (t != NT_INT && (t < QORE_NUM_TYPES || !dynamic_cast<const QoreBigIntNode *>(n)) - && t != NT_STRING - && t != NT_BOOLEAN - && t != NT_DATE - && t != NT_NULL) + && t != NT_NUMBER + && t != NT_STRING + && t != NT_BOOLEAN + && t != NT_DATE + && t != NT_NULL) return false; double rv = n->getAsFloat(); @@ -1476,6 +1480,7 @@ public: DLLLOCAL SoftFloatTypeInfo(bool n_returns_mult = false) : AcceptsMultiFilterTypeInfo(0, NT_FLOAT, n_returns_mult, false, true, n_returns_mult ? false : true, false, n_returns_mult ? false : true) { + at.push_back(numberTypeInfo); at.push_back(bigIntTypeInfo); at.push_back(stringTypeInfo); at.push_back(boolTypeInfo); @@ -1503,10 +1508,11 @@ return true; if (t != NT_INT && (t < QORE_NUM_TYPES || !dynamic_cast<const QoreBigIntNode *>(n)) - && t != NT_STRING - && t != NT_BOOLEAN - && t != NT_DATE - && t != NT_NULL) + && t != NT_NUMBER + && t != NT_STRING + && t != NT_BOOLEAN + && t != NT_DATE + && t != NT_NULL) return false; double rv = n->getAsFloat(); @@ -1543,9 +1549,21 @@ return true; } - if (t != NT_INT && (t < QORE_NUM_TYPES || !dynamic_cast<const QoreBigIntNode *>(n)) - && t != NT_STRING - && t != NT_BOOLEAN + if (t == NT_STRING) { + QoreNumberNode* nn = new QoreNumberNode(reinterpret_cast<const QoreStringNode*>(n)->getBuffer()); + n->deref(xsink); + n = nn; + return true; + } + + if (t == NT_INT || (t > QORE_NUM_TYPES && dynamic_cast<const QoreBigIntNode*>(n))) { + QoreNumberNode* nn = new QoreNumberNode(reinterpret_cast<const QoreBigIntNode*>(n)->val); + n->deref(xsink); + n = nn; + return true; + } + + if (t != NT_BOOLEAN && t != NT_DATE && t != NT_NULL) return false; @@ -1598,9 +1616,21 @@ return true; } - if (t != NT_INT && (t < QORE_NUM_TYPES || !dynamic_cast<const QoreBigIntNode*>(n)) - && t != NT_STRING - && t != NT_BOOLEAN + if (t == NT_STRING) { + QoreNumberNode* nn = new QoreNumberNode(reinterpret_cast<const QoreStringNode*>(n)->getBuffer()); + n->deref(xsink); + n = nn; + return true; + } + + if (t == NT_INT || (t > QORE_NUM_TYPES && dynamic_cast<const QoreBigIntNode*>(n))) { + QoreNumberNode* nn = new QoreNumberNode(reinterpret_cast<const QoreBigIntNode*>(n)->val); + n->deref(xsink); + n = nn; + return true; + } + + if (t != NT_BOOLEAN && t != NT_DATE && t != NT_NULL) return false; @@ -1619,7 +1649,7 @@ } }; -// accepts int, float, string, date, null, or boolean and returns a boolean +// accepts int, float, number, string, date, null, or boolean and returns a boolean class SoftBoolTypeInfo : public AcceptsMultiFilterTypeInfo { protected: DLLLOCAL virtual const char *getNameImpl() const { @@ -1633,10 +1663,11 @@ return true; if (t != NT_INT && (t < QORE_NUM_TYPES || !dynamic_cast<const QoreBigIntNode *>(n)) - && t != NT_FLOAT - && t != NT_STRING - && t != NT_DATE - && t != NT_NULL) + && t != NT_FLOAT + && t != NT_NUMBER + && t != NT_STRING + && t != NT_DATE + && t != NT_NULL) return false; bool rv = n->getAsBool(); @@ -1654,6 +1685,7 @@ DLLLOCAL SoftBoolTypeInfo(bool n_returns_mult = false) : AcceptsMultiFilterTypeInfo(0, NT_BOOLEAN, n_returns_mult, false, true, n_returns_mult ? false : true, false, n_returns_mult ? false : true) { at.push_back(bigIntTypeInfo); at.push_back(floatTypeInfo); + at.push_back(numberTypeInfo); at.push_back(stringTypeInfo); at.push_back(dateTypeInfo); at.push_back(nullTypeInfo); @@ -1679,10 +1711,11 @@ return true; if (t != NT_INT && (t < QORE_NUM_TYPES || !dynamic_cast<const QoreBigIntNode *>(n)) - && t != NT_FLOAT - && t != NT_STRING - && t != NT_DATE - && t != NT_NULL) + && t != NT_NUMBER + && t != NT_FLOAT + && t != NT_STRING + && t != NT_DATE + && t != NT_NULL) return false; bool rv = n->getAsBool(); @@ -1699,7 +1732,7 @@ } }; -// accepts int, float, string, date, bool, or null and returns a date +// accepts int, float, number, string, date, bool, or null and returns a date class SoftDateTypeInfo : public AcceptsMultiFilterTypeInfo { protected: DLLLOCAL virtual const char *getNameImpl() const { @@ -1712,8 +1745,9 @@ if (t == NT_DATE) return true; - if (t != NT_INT && (t < QORE_NUM_TYPES || !dynamic_cast<const QoreBigIntNode *>(n)) + if (t != NT_INT && (t < QORE_NUM_TYPES || !dynamic_cast<const QoreBigIntNode*>(n)) && t != NT_FLOAT + && t != NT_NUMBER && t != NT_STRING && t != NT_BOOLEAN && t != NT_NULL) @@ -1735,6 +1769,7 @@ DLLLOCAL SoftDateTypeInfo(bool n_returns_mult = false) : AcceptsMultiFilterTypeInfo(0, NT_DATE, n_returns_mult, false, true, n_returns_mult ? false : true, false, n_returns_mult ? false : true) { at.push_back(bigIntTypeInfo); at.push_back(floatTypeInfo); + at.push_back(numberTypeInfo); at.push_back(stringTypeInfo); at.push_back(boolTypeInfo); at.push_back(nullTypeInfo); @@ -1761,6 +1796,7 @@ if (t != NT_INT && (t < QORE_NUM_TYPES || !dynamic_cast<const QoreBigIntNode *>(n)) && t != NT_FLOAT + && t != NT_NUMBER && t != NT_STRING && t != NT_BOOLEAN && t != NT_NULL) @@ -1781,7 +1817,7 @@ } }; -// accepts int, float, string, date, null, or boolean and returns a string +// accepts int, float, number, string, date, null, or boolean and returns a string class SoftStringTypeInfo : public AcceptsMultiFilterTypeInfo { protected: DLLLOCAL virtual const char *getNameImpl() const { @@ -1796,6 +1832,7 @@ if (t != NT_INT && (t < QORE_NUM_TYPES || !dynamic_cast<const QoreBigIntNode *>(n)) && t != NT_FLOAT + && t != NT_NUMBER && t != NT_BOOLEAN && t != NT_DATE && t != NT_NULL) @@ -1817,6 +1854,7 @@ DLLLOCAL SoftStringTypeInfo(bool n_returns_mult = false) : AcceptsMultiFilterTypeInfo(0, NT_STRING, n_returns_mult, false, true, n_returns_mult ? false : true, false, n_returns_mult ? false : true) { at.push_back(bigIntTypeInfo); at.push_back(floatTypeInfo); + at.push_back(numberTypeInfo); at.push_back(boolTypeInfo); at.push_back(dateTypeInfo); at.push_back(nullTypeInfo); @@ -1843,6 +1881,7 @@ if (t != NT_INT && (t < QORE_NUM_TYPES || !dynamic_cast<const QoreBigIntNode *>(n)) && t != NT_FLOAT + && t != NT_NUMBER && t != NT_BOOLEAN && t != NT_DATE && t != NT_NULL) Modified: qore/trunk/include/qore/intern/ThreadResourceList.h =================================================================== --- qore/trunk/include/qore/intern/ThreadResourceList.h 2012-09-10 10:06:02 UTC (rev 5028) +++ qore/trunk/include/qore/intern/ThreadResourceList.h 2012-09-10 21:02:42 UTC (rev 5029) @@ -89,6 +89,4 @@ } }; - - #endif Modified: qore/trunk/lib/Operator.cpp =================================================================== --- qore/trunk/lib/Operator.cpp 2012-09-10 10:06:02 UTC (rev 5028) +++ qore/trunk/lib/Operator.cpp 2012-09-10 21:02:42 UTC (rev 5029) @@ -400,6 +400,10 @@ return left - right; } +static QoreNumberNode* op_plus_number(const QoreNumberNode* left, const QoreNumberNode* right, ExceptionSink* xsink) { + return left->doPlus(right); +} + static double op_plus_float(double left, double right) { return left + right; } @@ -1476,6 +1480,9 @@ if (t == NT_FLOAT) return new QoreFloatNode(n->getAsFloat()); + if (t == NT_NUMBER) + return new QoreNumberNode(n); + if (t == NT_BOOLEAN) return get_bool_node(n->getAsBool()); @@ -2585,6 +2592,122 @@ return op_func(left, right, xsink); } +AbstractQoreNode *NumberOperatorFunction::eval(const AbstractQoreNode *left, const AbstractQoreNode *right, bool ref_rv, int args, ExceptionSink *xsink) const { + ReferenceHolder<AbstractQoreNode> l(xsink); + + // convert node type to required argument types for operator if necessary + if ((left->getType() != ltype) && (ltype != NT_ALL)) { + l = get_node_type(left, ltype); + left = *l; + } + + if (args == 1) { + QoreNumberNode* rv = op_func(reinterpret_cast<const QoreNumberNode*>(left), reinterpret_cast<const QoreNumberNode*>(right), xsink); + assert(!(*xsink && rv)); + if (!ref_rv || *xsink) + return 0; + return rv; + } + + ReferenceHolder<AbstractQoreNode> r(xsink); + + // convert node type to required argument types for operator if necessary + if ((right->getType() != rtype) && (rtype != NT_ALL)) { + r = get_node_type(right, rtype); + right = *r; + } + + QoreNumberNode* rv = op_func(reinterpret_cast<const QoreNumberNode*>(left), reinterpret_cast<const QoreNumberNode*>(right), xsink); + assert(!(*xsink && rv)); + if (!ref_rv || xsink->isException()) + return 0; + return rv; +} + +bool NumberOperatorFunction::bool_eval(const AbstractQoreNode *left, const AbstractQoreNode *right, int args, ExceptionSink *xsink) const { + ReferenceHolder<AbstractQoreNode> l(xsink); + + // convert node type to required argument types for operator if necessary + if ((left->getType() != ltype) && (ltype != NT_ALL)) { + l = get_node_type(left, ltype); + left = *l; + } + + if (args == 1) { + SimpleRefHolder<QoreNumberNode> rv(op_func(reinterpret_cast<const QoreNumberNode*>(left), reinterpret_cast<const QoreNumberNode*>(right), xsink)); + assert(!(*xsink && rv)); + return !rv->zero(); + } + + ReferenceHolder<AbstractQoreNode> r(xsink); + + // convert node type to required argument types for operator if necessary + if ((right->getType() != rtype) && (rtype != NT_ALL)) { + r = get_node_type(right, rtype); + right = *r; + } + + SimpleRefHolder<QoreNumberNode> rv(op_func(reinterpret_cast<const QoreNumberNode*>(left), reinterpret_cast<const QoreNumberNode*>(right), xsink)); + assert(!(*xsink && rv)); + return !rv->zero(); +} + +int64 NumberOperatorFunction::bigint_eval(const AbstractQoreNode *left, const AbstractQoreNode *right, int args, ExceptionSink *xsink) const { + ReferenceHolder<AbstractQoreNode> l(xsink); + + // convert node type to required argument types for operator if necessary + if ((left->getType() != ltype) && (ltype != NT_ALL)) { + l = get_node_type(left, ltype); + left = *l; + } + + if (args == 1) { + SimpleRefHolder<QoreNumberNode> rv(op_func(reinterpret_cast<const QoreNumberNode*>(left), reinterpret_cast<const QoreNumberNode*>(right), xsink)); + assert(!(*xsink && rv)); + return rv->getAsBigInt(); + } + + ReferenceHolder<AbstractQoreNode> r(xsink); + + // convert node type to required argument types for operator if necessary + if ((right->getType() != rtype) && (rtype != NT_ALL)) { + r = get_node_type(right, rtype); + right = *r; + } + + SimpleRefHolder<QoreNumberNode> rv(op_func(reinterpret_cast<const QoreNumberNode*>(left), reinterpret_cast<const QoreNumberNode*>(right), xsink)); + assert(!(*xsink && rv)); + return rv->getAsBigInt(); +} + +double NumberOperatorFunction::float_eval(const AbstractQoreNode *left, const AbstractQoreNode *right, int args, ExceptionSink *xsink) const { + ReferenceHolder<AbstractQoreNode> l(xsink); + + // convert node type to required argument types for operator if necessary + if ((left->getType() != ltype) && (ltype != NT_ALL)) { + l = get_node_type(left, ltype); + left = *l; + } + + if (args == 1) { + SimpleRefHolder<QoreNumberNode> rv(op_func(reinterpret_cast<const QoreNumberNode*>(left), reinterpret_cast<const QoreNumberNode*>(right), xsink)); + assert(!(*xsink && rv)); + return rv->getAsFloat(); + } + + ReferenceHolder<AbstractQoreNode> r(xsink); + + // convert node type to required argument types for operator if necessary + if ((right->getType() != rtype) && (rtype != NT_ALL)) { + r = get_node_type(right, rtype); + right = *r; + } + + SimpleRefHolder<QoreNumberNode> rv(op_func(reinterpret_cast<const QoreNumberNode*>(left), reinterpret_cast<const QoreNumberNode*>(right), xsink)); + assert(!(*xsink && rv)); + return rv->getAsFloat(); +} + Operator::~Operator() { // erase all functions for (unsigned i = 0, size = functions.size(); i < size; i++) @@ -2604,7 +2727,7 @@ } AbstractQoreNode *Operator::parseInit(QoreTreeNode *tree, LocalVar *oflag, int pflag, int &lvids, const QoreTypeInfo *&resultTypeInfo) { - // check for illegal changes to local variables in background expressions + // check for illegal changes to local variables in background expressions if (pflag & PF_BACKGROUND && lvalue) { if (tree->left && tree->left->getType() == NT_VARREF && reinterpret_cast<VarRefNode *>(tree->left)->getType() == VT_LOCAL) parse_error("illegal local variable modification in background expression"); @@ -2612,7 +2735,7 @@ if (!check_args) return tree->defaultParseInit(oflag, pflag, lvids, resultTypeInfo); - + return check_args(tree, oflag, pflag, lvids, resultTypeInfo, name, description); } @@ -2635,7 +2758,7 @@ t = opMatrix[nleft->getType()][NT_NOTHING]; else t = findFunction(nleft->getType(), NT_NOTHING); - + printd(5, "Operator::get_function() found function %d\n", t); return t; } @@ -2682,11 +2805,11 @@ return 0; if (!nright) nright.assign(false, &Nothing); - + // find operator function if ((t = get_function(nleft, nright, xsink)) == -1) return 0; - + return functions[t]->eval(*nleft, *nright, ref_rv, 2, xsink); } @@ -2708,7 +2831,7 @@ return 0; if (!nleft) nleft.assign(false, &Nothing); - + int t; if (args == 1) { if ((t = get_function(nleft, xsink)) == -1) @@ -2722,11 +2845,11 @@ return 0; if (!nright) nright.assign(false, &Nothing); - + // find operator function if ((t = get_function(nleft, nright, xsink)) == -1) return 0; - + return functions[t]->bool_eval(*nleft, *nright, 2, xsink); } @@ -2763,11 +2886,11 @@ return 0; if (!nright) nright.assign(false, &Nothing); - + // find operator function if ((t = get_function(nleft, nright, xsink)) == -1) return 0; - + return functions[t]->bigint_eval(*nleft, *nright, 2, xsink); } @@ -2804,7 +2927,7 @@ return 0; if (!nright) nright.assign(false, &Nothing); - + // find operator function if ((t = get_function(nleft, nright, xsink)) == -1) return 0; @@ -2819,10 +2942,10 @@ int Operator::findFunction(qore_type_t ltype, qore_type_t rtype) const { int m = -1; - + //QORE_TRACE("Operator::findFunction()"); // loop through all operator functions - + for (int i = 0, size = functions.size(); i < size; i++) { AbstractOperatorFunction *f = functions[i]; @@ -2837,20 +2960,20 @@ if (match(ltype, f->ltype)) { /* if there is only one operator or there is also * a match on the right side, return */ - if ((args == 1) || - ((args == 2) && match(rtype, f->rtype))) { + if ((args == 1) || + ((args == 2) && match(rtype, f->rtype))) { return i; } if (!f->needsExactMatch() && m == -1) m = i; continue; } - if ((args == 2) && !f->needsExactMatch() && match(rtype, f->rtype) + if ((args == 2) && !f->needsExactMatch() && match(rtype, f->rtype) && (m == -1)) m = i; } /* if there is no match of any kind, take the highest priority function - * (row 0), and try to convert the arguments, otherwise return the best + * (row 0), and try to convert the arguments, otherwise return the best * partial match */ @@ -2889,9 +3012,9 @@ return o; } -// checks for illegal $self assignments in an object context +// checks for illegal $self assignments in an object context void check_self_assignment(AbstractQoreNode *n, LocalVar *selfid) { - // if it's a variable reference + // if it's a variable reference qore_type_t ntype = n->getType(); if (ntype == NT_VARREF) { VarRefNode *v = reinterpret_cast<VarRefNode *>(n); @@ -2905,7 +3028,7 @@ QoreTreeNode *tree = reinterpret_cast<QoreTreeNode *>(n); - // otherwise it's a tree: go to root expression + // otherwise it's a tree: go to root expression while (tree->left->getType() == NT_TREE) { n = tree->left; tree = reinterpret_cast<QoreTreeNode *>(n); @@ -2916,8 +3039,8 @@ VarRefNode *v = reinterpret_cast<VarRefNode *>(tree->left); - // left must be variable reference, check if the tree is - // a list reference; if so, it's invalid + // left must be variable reference, check if the tree is + // a list reference; if so, it's invalid if (v->getType() == VT_LOCAL && v->ref.id == selfid && tree->getOp() == OP_LIST_REF) parse_error("illegal conversion of 'self' to a list"); } @@ -2942,7 +3065,7 @@ // check for illegal assignment to $self if (oflag) check_self_assignment(v, oflag); - + ri.parseInit(argInfo); if (prototypeInfo->hasType()) { @@ -3042,25 +3165,25 @@ return tree->evalSubst(returnTypeInfo); // if either side is a date, then the return type is date (highest priority) - if (leftTypeInfo->isType(NT_DATE) + if (leftTypeInfo->isType(NT_DATE) || rightTypeInfo->isType(NT_DATE)) returnTypeInfo = dateTypeInfo; // otherwise we have to make sure types are known on both sides of the expression else if (leftTypeInfo->hasType() && rightTypeInfo->hasType()) { - if (leftTypeInfo->isType(NT_FLOAT) + if (leftTypeInfo->isType(NT_FLOAT) || rightTypeInfo->isType(NT_FLOAT)) returnTypeInfo = floatTypeInfo; - else if (leftTypeInfo->isType(NT_INT) + else if (leftTypeInfo->isType(NT_INT) || rightTypeInfo->isType(NT_INT)) returnTypeInfo = bigIntTypeInfo; - else if ((leftTypeInfo->isType(NT_HASH) + else if ((leftTypeInfo->isType(NT_HASH) || leftTypeInfo->isType(NT_OBJECT)) && (rightTypeInfo->isType(NT_STRING) || rightTypeInfo->isType(NT_LIST))) returnTypeInfo = hashTypeInfo; - else if (leftTypeInfo->returnsSingle() && rightTypeInfo->returnsSingle()) + else if (leftTypeInfo->returnsSingle() && rightTypeInfo->returnsSingle()) // only return type nothing if both types are available and return a single type - returnTypeInfo = nothingTypeInfo; + returnTypeInfo = nothingTypeInfo; } else returnTypeInfo = 0; @@ -3080,41 +3203,45 @@ return tree->evalSubst(returnTypeInfo); // if either side is a list, then the return type is list (highest priority) - if (leftTypeInfo->isType(NT_LIST) + if (leftTypeInfo->isType(NT_LIST) || rightTypeInfo->isType(NT_LIST)) returnTypeInfo = listTypeInfo; // otherwise only set return type if return types on both sides are known at parse time else if (leftTypeInfo->hasType() && rightTypeInfo->hasType()) { - if (leftTypeInfo->isType(NT_STRING) + if (leftTypeInfo->isType(NT_STRING) || rightTypeInfo->isType(NT_STRING)) returnTypeInfo = stringTypeInfo; - else if (leftTypeInfo->isType(NT_DATE) + else if (leftTypeInfo->isType(NT_DATE) || rightTypeInfo->isType(NT_DATE)) returnTypeInfo = dateTypeInfo; - else if (leftTypeInfo->isType(NT_FLOAT) + else if (leftTypeInfo->isType(NT_NUMBER) + || rightTypeInfo->isType(NT_NUMBER)) + returnTypeInfo = numberTypeInfo; + + else if (leftTypeInfo->isType(NT_FLOAT) || rightTypeInfo->isType(NT_FLOAT)) returnTypeInfo = floatTypeInfo; - else if (leftTypeInfo->isType(NT_INT) + else if (leftTypeInfo->isType(NT_INT) || rightTypeInfo->isType(NT_INT)) returnTypeInfo = bigIntTypeInfo; else if (leftTypeInfo->isType(NT_HASH) || leftTypeInfo->isType(NT_OBJECT)) returnTypeInfo = hashTypeInfo; - + else if (rightTypeInfo->isType(NT_OBJECT)) returnTypeInfo = objectTypeInfo; - else if (leftTypeInfo->isType(NT_BINARY) + else if (leftTypeInfo->isType(NT_BINARY) || rightTypeInfo->isType(NT_BINARY)) returnTypeInfo = binaryTypeInfo; - else if (leftTypeInfo->returnsSingle() && rightTypeInfo->returnsSingle()) + else if (leftTypeInfo->returnsSingle() && rightTypeInfo->returnsSingle()) // only return type nothing if both types are available and return a single type returnTypeInfo = nothingTypeInfo; } @@ -3393,19 +3520,19 @@ // registers the system operators and system operator functions void OperatorList::init() { QORE_TRACE("OperatorList::init()"); - + OP_LOG_AND = add(new Operator(2, "&&", "logical-and", 0, false, false, check_op_logical)); OP_LOG_AND->addEffectFunction(op_log_and); OP_LOG_OR = add(new Operator(2, "||", "logical-or", 0, false, false, check_op_logical)); OP_LOG_OR->addEffectFunction(op_log_or); - + OP_LOG_LT = add(new Operator(2, "<", "less-than", 1, false, false, check_op_logical)); OP_LOG_LT->addFunction(op_log_lt_float); OP_LOG_LT->addFunction(op_log_lt_bigint); OP_LOG_LT->addFunction(op_log_lt_string); OP_LOG_LT->addFunction(op_log_lt_date); - + OP_LOG_GT = add(new Operator(2, ">", "greater-than", 1, false, false, check_op_logical)); OP_LOG_GT->addFunction(op_log_gt_float); OP_LOG_GT->addFunction(op_log_gt_bigint); @@ -3427,7 +3554,7 @@ OP_LOG_NE->addFunction(op_log_ne_boolean); OP_LOG_NE->addFunction(op_log_ne_date); OP_LOG_NE->addNoConvertFunction(NT_ALL, NT_ALL, op_log_ne_all); - + OP_LOG_LE = add(new Operator(2, "<=", "less-than-or-equals", 1, false, false, check_op_logical)); OP_LOG_LE->addFunction(op_log_le_float); OP_LOG_LE->addFunction(op_log_le_bigint); @@ -3442,25 +3569,25 @@ OP_ABSOLUTE_EQ = add(new Operator(2, "===", "absolute logical-equals", 0, false, false, check_op_logical)); OP_ABSOLUTE_EQ->addFunction(NT_ALL, NT_ALL, op_absolute_log_eq); - + OP_ABSOLUTE_NE = add(new Operator(2, "!==", "absolute logical-not-equals", 0, false, false, check_op_logical)); OP_ABSOLUTE_NE->addFunction(NT_ALL, NT_ALL, op_absolute_log_neq); - + OP_REGEX_MATCH = add(new Operator(2, "=~", "regular expression match", 0, false, false, check_op_logical)); OP_REGEX_MATCH->addFunction(op_regex_match); - + OP_REGEX_NMATCH = add(new Operator(2, "!~", "regular expression negative match", 0, false, false, check_op_logical)); OP_REGEX_NMATCH->addFunction(op_regex_nmatch); OP_EXISTS = add(new Operator(1, "exists", "exists", 1, false, false, check_op_logical)); OP_EXISTS->addFunction(NT_ALL, NT_NONE, op_exists); - + OP_INSTANCEOF = add(new Operator(2, "instanceof", "instanceof", 0, false, false, check_op_logical)); OP_INSTANCEOF->addFunction(NT_ALL, NT_CLASSREF, op_instanceof); - + OP_NOT = add(new Operator(1, "!", "logical-not", 1, false, false, check_op_logical)); OP_NOT->addBoolNotFunction(); - + // bigint operators OP_LOG_CMP = add(new Operator(2, "<=>", "logical-comparison", 1, false, false, check_op_returns_integer)); OP_LOG_CMP->addFunction(op_cmp_string); @@ -3477,7 +3604,7 @@ // non-boolean operators OP_LIST_ASSIGNMENT = add(new Operator(2, "(list) =", "list assignment", 0, true, true, check_op_list_assignment)); OP_LIST_ASSIGNMENT->addFunction(NT_ALL, NT_ALL, op_list_assignment); - + OP_BIN_AND = add(new Operator(2, "&", "binary-and", 1, false, false, check_op_returns_integer)); OP_BIN_AND->addFunction(op_bin_and_int); @@ -3502,6 +3629,7 @@ OP_PLUS->addFunction(NT_LIST, NT_LIST, op_plus_list); OP_PLUS->addFunction(op_plus_string); OP_PLUS->addFunction(op_plus_date); + OP_PLUS->addFunction(op_plus_number); OP_PLUS->addFunction(op_plus_float); OP_PLUS->addFunction(op_plus_bigint); OP_PLUS->addFunction(NT_HASH, NT_HASH, op_plus_hash_hash); @@ -3531,7 +3659,7 @@ // cannot validate return type here yet OP_OBJECT_REF = add(new Operator(2, ".", "hash/object-reference", 0, false, false, check_op_object_ref)); - OP_OBJECT_REF->addFunction(NT_ALL, NT_ALL, op_object_ref); + OP_OBJECT_REF->addFunction(NT_ALL, NT_ALL, op_object_ref); // can return a list or NOTHING OP_KEYS = add(new Operator(1, "keys", "list of keys", 0, false, false, check_op_keys)); Modified: qore/trunk/lib/QoreNumberNode.cpp =================================================================== --- qore/trunk/lib/QoreNumberNode.cpp 2012-09-10 10:06:02 UTC (rev 5028) +++ qore/trunk/lib/QoreNumberNode.cpp 2012-09-10 21:02:42 UTC (rev 5029) @@ -22,23 +22,186 @@ #include <qore/Qore.h> -struct qore_number_private { - DLLLOCAL qore_number_private() { +#define QORE_DEFAULT_PREC 128 +#define QORE_MAX_PREC 8192 +// round to nearest (roundTiesToEven in IEEE 754-2008) +#define QORE_MPFR_RND MPFR_RNDN +// MPFR_RNDA + +struct qore_number_private_intern { + mpfr_t num; + + DLLLOCAL qore_number_private_intern() { + mpfr_init2(num, QORE_DEFAULT_PREC); } + DLLLOCAL qore_number_private_intern(mpfr_prec_t prec) { + if (prec > QORE_MAX_PREC) + prec = QORE_MAX_PREC; + mpfr_init2(num, prec); + } + + DLLLOCAL ~qore_number_private_intern() { + mpfr_clear(num); + } +}; + +struct qore_number_private : public qore_number_private_intern { + DLLLOCAL explicit qore_number_private(mpfr_prec_t prec) : qore_number_private_intern(prec) { + } + DLLLOCAL qore_number_private(double f) { + mpfr_set_d(num, f, QORE_MPFR_RND); } DLLLOCAL qore_number_private(int64 i) { + mpfr_set_sj(num, i, QORE_MPFR_RND); } - DLLLOCAL qore_number_private(const char* str) { + DLLLOCAL qore_number_private(const char* str) : qore_number_private_intern(QORE_MAX(QORE_DEFAULT_PREC, strlen(str)*10)) { + mpfr_set_str(num, str, 10, QORE_MPFR_RND); } - DLLLOCAL qore_number_private(const qore_number_private& old) { + DLLLOCAL qore_number_private(const qore_number_private& old) : qore_number_private_intern(mpfr_get_prec(old.num)) { + mpfr_set(num, old.num, QORE_MPFR_RND); } + + DLLLOCAL double getAsFloat() const { + return mpfr_get_d(num, QORE_MPFR_RND); + } + + DLLLOCAL int64 getAsBigInt() const { + return mpfr_get_sj(num, QORE_MPFR_RND); + } + + DLLLOCAL bool getAsBool() const { + return !zero(); + } + + DLLLOCAL bool zero() const { + return (bool)mpfr_zero_p(num); + } + + DLLLOCAL bool nan() const { + return (bool)mpfr_nan_p(num); + } + + DLLLOCAL bool inf() const { + return (bool)mpfr_inf_p(num); + } + + DLLLOCAL bool number() const { + return (bool)mpfr_number_p(num); + } + + // regular and not zero + DLLLOCAL bool regular() const { + return (bool)mpfr_regular_p(num); + } + + DLLLOCAL void getAsString(QoreString& str) const { + // first check if it's zero + if (zero()) { + str.concat("0n"); + return; + } + mpfr_exp_t exp; + char* buf = mpfr_get_str(0, &exp, 10, 0, num, QORE_MPFR_RND); + if (!buf) { + str.concat("<number error>"); + return; + } + + // if it's a regular number, then format accordingly + if (number()) { + qore_size_t len = str.size(); + //printd(0, "QoreNumberNode::getAsString() this: %p '%s' exp "QLLD" len: "QLLD"\n", this, buf, exp, len); + + str.concat(buf); + // trim the trailing zeros off the end + str.trim_trailing('0'); + if (exp <= 0) { + exp = -exp; + str.insert("0.", len); + if (exp) + str.insertch('0', len + 2, exp); + } + else { + // get remaining length of string (how many characters were added) + qore_size_t rlen = str.size() - len; + + //printd(0, "QoreNumberNode::getAsString() this: %p str: '%s' rlen: "QLLD"\n", this, str.getBuffer(), rlen); + + // assert that we have added at least 1 character + assert(rlen > 0); + if (exp > rlen) + str.insertch('0', str.size(), exp - rlen); + else if (exp < rlen) + str.insertch('.', len + exp, 1); + } + str.concat('n'); + } + + mpfr_free_str(buf); + } + + DLLLOCAL int compare(const qore_number_private& right) const { + return mpfr_cmp(num, right.num); + } + + DLLLOCAL int compare(double right) const { + return mpfr_cmp_d(num, right); + } + + DLLLOCAL int compare(int64 right) const { + MPFR_DECL_INIT(r, QORE_DEFAULT_PREC); + mpfr_set_sj(r, right, QORE_MPFR_RND); + return mpfr_cmp(num, r); + } + + DLLLOCAL qore_number_private* doPlus(const qore_number_private& r) const { + mpfr_prec_t prec = QORE_MAX(mpfr_get_prec(num), mpfr_get_prec(r.num)); + qore_number_private* p = new qore_number_private(prec); + mpfr_add(p->num, num, r.num, QORE_MPFR_RND); + return p; + } }; +QoreNumberNode::QoreNumberNode(struct qore_number_private* p) : SimpleValueQoreNode(NT_NUMBER), priv(p) { +} + +QoreNumberNode::QoreNumberNode(const AbstractQoreNode* n) : SimpleValueQoreNode(NT_NUMBER), priv(0) { + qore_type_t t = get_node_type(n); + if (t == NT_NUMBER) { + priv = new qore_number_private(*reinterpret_cast<const QoreNumberNode*>(n)->priv); + return; + } + + if (t == NT_FLOAT) { + priv = new qore_number_private(reinterpret_cast<const QoreFloatNode*>(n)->f); + return; + } + + if (t == NT_STRING) { + priv = new qore_number_private(reinterpret_cast<const QoreStringNode*>(n)->getBuffer()); + return; + } + + if (t == NT_INT || (t > QORE_NUM_TYPES && dynamic_cast<const QoreBigIntNode*>(n))) { + priv = new qore_number_private(reinterpret_cast<const QoreBigIntNode*>(n)->val); + return; + } + + if (t != NT_BOOLEAN + && t != NT_DATE + && t != NT_NULL) { + priv = new qore_number_private(0ll); + return; + } + + priv = new qore_number_private(n->getAsFloat()); +} + QoreNumberNode::QoreNumberNode(double f) : SimpleValueQoreNode(NT_NUMBER), priv(new qore_number_private(f)) { } @@ -48,7 +211,7 @@ QoreNumberNode::QoreNumberNode(const char* str) : SimpleValueQoreNode(NT_NUMBER), priv(new qore_number_private(str)) { } -QoreNumberNode::QoreNumberNode() : SimpleValueQoreNode(NT_NUMBER), priv(new qore_number_private) { +QoreNumberNode::QoreNumberNode() : SimpleValueQoreNode(NT_NUMBER), priv(new qore_number_private(0ll)) { } QoreNumberNode::QoreNumberNode(const QoreNumberNode& old) : SimpleValueQoreNode(old), priv(new qore_number_private(*old.priv)) { @@ -61,83 +224,92 @@ // get the value of the type in a string context (default implementation = del = false and returns NullString) // if del is true, then the returned QoreString * should be deleted, if false, then it must not be // use the QoreStringValueHelper class (defined in QoreStringNode.h) instead of using this function directly -QoreString *QoreNumberNode::getStringRepresentation(bool& del) const { +QoreString* QoreNumberNode::getStringRepresentation(bool& del) const { del = true; - return new QoreString("xxx"); + QoreString* str = new QoreString; + priv->getAsString(*str); + return str; } // concatenate string representation to a QoreString (no action for complex types = default implementation) void QoreNumberNode::getStringRepresentation(QoreString& str) const { - str.concat("xxx"); + priv->getAsString(str); } // if del is true, then the returned DateTime * should be deleted, if false, then it should not DateTime *QoreNumberNode::getDateTimeRepresentation(bool& del) const { del = true; - return DateTime::makeAbsoluteLocal(currentTZ(), (int64)0, (int)0); + double f = priv->getAsFloat(); + return DateTime::makeAbsoluteLocal(currentTZ(), (int64)f, (int)((f - (float)((int)f)) * 1000000)); } // assign date representation to a DateTime (no action for complex types = default implementation) void QoreNumberNode::getDateTimeRepresentation(DateTime& dt) const { - dt.setLocalDate(currentTZ(), (int64)0, (int)0); + double f = priv->getAsFloat(); + dt.setLocalDate(currentTZ(), (int64)f, (int)((f - (float)((int)f)) * 1000000)); } bool QoreNumberNode::getAsBoolImpl() const { - return (bool)false; + return priv->getAsBool(); } int QoreNumberNode::getAsIntImpl() const { - return (int)0; + return priv->getAsBigInt(); } int64 QoreNumberNode::getAsBigIntImpl() const { - return (int64)0; + return priv->getAsBigInt(); } double QoreNumberNode::getAsFloatImpl() const { - return 0.0; + return priv->getAsFloat(); } -// get string representation (for %n and %N), foff is for multi-line formatting offset, -1 = no line breaks -// the ExceptionSink is only needed for QoreObject where a method may be executed -// use the QoreNodeAsStringHelper class (defined in QoreStringNode.h) instead of using these functions directly -// returns -1 for exception raised, 0 = OK -int QoreNumberNode::getAsString(QoreString& str, int foff, ExceptionSink *xsink) const { +int QoreNumberNode::getAsString(QoreString& str, int foff, ExceptionSink* xsink) const { getStringRepresentation(str); return 0; } // if del is true, then the returned QoreString * should be deleted, if false, then it must not be -QoreString *QoreNumberNode::getAsString(bool& del, int foff, ExceptionSink *xsink) const { +QoreString *QoreNumberNode::getAsString(bool& del, int foff, ExceptionSink* xsink) const { return getStringRepresentation(del); } -AbstractQoreNode *QoreNumberNode::realCopy() const { +AbstractQoreNode* QoreNumberNode::realCopy() const { return new QoreNumberNode(*this); } -// performs a lexical compare, return -1, 0, or 1 if the "this" value is less than, equal, or greater than -// the "val" passed -//DLLLOCAL virtual int compare(const AbstractQoreNode *val) const; // the type passed must always be equal to the current type -bool QoreNumberNode::is_equal_soft(const AbstractQoreNode *v, ExceptionSink *xsink) const { - return false; +bool QoreNumberNode::is_equal_soft(const AbstractQoreNode* v, ExceptionSink* xsink) const { + if (v->getType() == NT_NUMBER) + return !priv->compare(*reinterpret_cast<const QoreNumberNode*>(v)->priv); + if (v->getType() == NT_INT || dynamic_cast<const QoreBigIntNode*>(v)) + return !priv->compare(reinterpret_cast<const QoreBigIntNode*>(v)->val); + + return !priv->compare(v->getAsFloat()); } -bool QoreNumberNode::is_equal_hard(const AbstractQoreNode *v, ExceptionSink *xsink) const { - const QoreNumberNode *fn = dynamic_cast<const QoreNumberNode *>(v); - if (!fn) +bool QoreNumberNode::is_equal_hard(const AbstractQoreNode* v, ExceptionSink* xsink) const { + if (v->getType() != NT_NUMBER) return false; - - return false; + const QoreNumberNode* n = reinterpret_cast<const QoreNumberNode*>(v); + return !priv->compare(*n->priv); } // returns the type name as a c string -const char *QoreNumberNode::getTypeName() const { +const char* QoreNumberNode::getTypeName() const { return getStaticTypeName(); } -AbstractQoreNode *QoreNumberNode::parseInit(LocalVar *oflag, int pflag, int& lvids, const QoreTypeInfo*& typeInfo) { +AbstractQoreNode* QoreNumberNode::parseInit(LocalVar* oflag, int pflag, int& lvids, const QoreTypeInfo*& typeInfo) { typeInfo = numberTypeInfo; return this; } + +bool QoreNumberNode::zero() const { + return priv->zero(); +} + +QoreNumberNode* QoreNumberNode::doPlus(const QoreNumberNode* right) const { + return new QoreNumberNode(priv->doPlus(*right->priv)); +} Modified: qore/trunk/lib/QoreString.cpp =================================================================== --- qore/trunk/lib/QoreString.cpp 2012-09-10 10:06:02 UTC (rev 5028) +++ qore/trunk/lib/QoreString.cpp 2012-09-10 21:02:42 UTC (rev 5029) @@ -1591,19 +1591,41 @@ } void QoreString::addch(char c, unsigned times) { - if (priv->allocated) { - priv->check_char(priv->len + times + STR_CLASS_BLOCK); // more data will follow the padding - memset(priv->buf + priv->len, c, times); - } else { - priv->allocated = times + STR_CLASS_BLOCK; - priv->allocated = (priv->allocated / 16 + 1) * 16; // use complete cache line - priv->buf = (char*)malloc(sizeof(char) * priv->allocated); - memset(priv->buf, c, times); - } + priv->check_char(priv->len + times); // more data will follow the padding + memset(priv->buf + priv->len, c, times); priv->len += times; priv->buf[priv->len] = 0; } +int QoreString::insertch(char c, qore_size_t pos, unsigned times) { + //printd(5, "QoreString::insertch(c: %c pos: "QLLD" times: %d) this: %p\n", c, pos, times, this); + if (pos > priv->len || !times) + return -1; + + priv->check_char(priv->len + times); // more data will follow the padding + if (pos < priv->len) + memmove(priv->buf + pos + times, priv->buf + pos, priv->len - pos); + memset(priv->buf + pos, c, times); + priv->len += times; + priv->buf[priv->len] = 0; + return 0; +} + +int QoreString::insert(const char* str, qore_size_t pos) { + if (pos > priv->len) + return -1; + + size_t sl = ::strlen(str); + + priv->check_char(priv->len + sl); // more data will follow the padding + if (pos < priv->len) + memmove(priv->buf + pos + sl, priv->buf + pos, priv->len - pos); + strncpy(priv->buf + pos, str, sl); + priv->len += sl; + priv->buf[priv->len] = 0; + return 0; +} + int QoreString::concatUnicode(unsigned code, ExceptionSink *xsink) { if (priv->charset == QCS_UTF8) { concatUTF8FromUnicode(code); Modified: qore/trunk/lib/parser.ypp =================================================================== --- qore/trunk/lib/parser.ypp 2012-09-10 10:06:02 UTC (rev 5028) +++ qore/trunk/lib/parser.ypp 2012-09-10 21:02:42 UTC (rev 5029) @@ -1188,6 +1188,7 @@ class ParseUserFunction* parsefunc; class ParseScopedUserFunction* sparsefunc; struct GVarDecl* gv; + QoreNumberNode* num; } %{ @@ -1306,6 +1307,7 @@ // tokens returning data %token <integer> INTEGER "integer value" %token <decimal> QFLOAT "floating-point value" +%token <num> NUMBER "arbitrary-precision number" %token <string> IDENTIFIER "identifier" %token <string> VAR_REF "variable reference" %token <string> BACKQUOTE "backquote expression" @@ -3145,6 +3147,7 @@ | INTEGER { $$ = new QoreBigIntNode($1); } | string { $$ = $1; } | DATETIME { $$ = $1; } + | NUMBER { $$ = $1; } ; %% Modified: qore/trunk/lib/scanner.lpp =================================================================== --- qore/trunk/lib/scanner.lpp 2012-09-10 10:06:02 UTC (rev 5028) +++ qore/trunk/lib/scanner.lpp 2012-09-10 21:02:42 UTC (rev 5029) @@ -1204,6 +1204,11 @@ cast\<{WS}*{WORD}{WS}*\> yylval->string = make_cast(yytext); return QORE_CAST; ({WORD}::)+\$\.{WORD} yylval->nscope = new NamedScope(strdup(yytext)); yylval->nscope->fixBCCall(); return BASE_CLASS_CALL; {DIGIT}+"."{DIGIT}+ yylval->decimal = strtod(yytext, 0); return QFLOAT; +{DIGIT}+[eE][+-]?{DIGIT}+ yylval->decimal = strtod(yytext, 0); return QFLOAT; +{DIGIT}+"."{DIGIT}+[eE][+-]?{DIGIT}+ yylval->decimal = strtod(yytext, 0); return QFLOAT; +{DIGIT}+"."{DIGIT}+n yylval->num = new QoreNumberNode(yytext); return NUMBER; +{DIGIT}+[eE][+-]?{DIGIT}+n yylval->num = new QoreNumberNode(yytext); return NUMBER; +{DIGIT}+"."{DIGIT}+[eE][+-]?{DIGIT}+n yylval->num = new QoreNumberNode(yytext); return NUMBER; 0[0-7]+ yylval->integer = strtoll(yytext+1, 0, 8); return INTEGER; {DIGIT}+ yylval->integer = parse_get_integer(yytext); return INTEGER; {DIGIT}+Y yylval->datetime = makeYears(strtol(yytext, 0, 10)); return DATETIME; Modified: qore/trunk/lib/thread.cpp =================================================================== --- qore/trunk/lib/thread.cpp 2012-09-10 10:06:02 UTC (rev 5028) +++ qore/trunk/lib/thread.cpp 2012-09-10 21:02:42 UTC (rev 5029) @@ -1507,6 +1507,10 @@ td->tpd->saveProgram(true); } +static void qore_thread_cleanup(void* n) { + mpfr_free_cache(); +} + // put "op_background_thread" in an unnamed namespace to make it 'static extern "C"' namespace { extern "C" void* op_background_thread(void* x) { @@ -1516,6 +1520,8 @@ printd(5, "op_background_thread() btp=%p TID %d started\n", btp, btp->tid); //printf("op_background_thread() btp=%p TID %d started\n", btp, btp->tid); + pthread_cleanup_push(qore_thread_cleanup, (void*)0); + { ExceptionSink xsink; @@ -1571,6 +1577,8 @@ } } + pthread_cleanup_pop(1); + pthread_exit(0); return 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <subik@us...> - 2012-09-10 10:06:11
|
Revision: 5028 http://qore.svn.sourceforge.net/qore/?rev=5028&view=rev Author: subik Date: 2012-09-10 10:06:02 +0000 (Mon, 10 Sep 2012) Log Message: ----------- revert: <list>::append(any) implemented Modified Paths: -------------- qore/trunk/lib/Pseudo_QC_List.qpp qore/trunk/test/test.q Modified: qore/trunk/lib/Pseudo_QC_List.qpp =================================================================== --- qore/trunk/lib/Pseudo_QC_List.qpp 2012-09-10 09:54:46 UTC (rev 5027) +++ qore/trunk/lib/Pseudo_QC_List.qpp 2012-09-10 10:06:02 UTC (rev 5028) @@ -175,15 +175,15 @@ return inlist_intern(arg, l, xsink); } -//! Append a value to the oend of the list -/** +// Append a value to the oend of the list +/* @param arg @ref any value to be appended */ -nothing <list>::append(any arg) { - QoreNodeEvalOptionalRefHolder value(arg, xsink); - if (*xsink) - return 0; - l->push(value.getReferencedValue()); - return nothing(); -} +//nothing <list>::append(any arg) { +// QoreNodeEvalOptionalRefHolder value(arg, xsink); +// if (*xsink) +// return 0; +// l->push(value.getReferencedValue()); +// return nothing(); +//} Modified: qore/trunk/test/test.q =================================================================== --- qore/trunk/test/test.q 2012-09-10 09:54:46 UTC (rev 5027) +++ qore/trunk/test/test.q 2012-09-10 10:06:02 UTC (rev 5028) @@ -283,8 +283,8 @@ test_value($pseudoList.join('-'), '1-2-3-4-a', "<list>::join"); test_value($pseudoList.lsize(), 5, "<list>::lsize"); test_value($pseudoList.contains(2), True, "<list>::contains"); - $pseudoList.append(6); - test_value($pseudoList, (1, 2, 3, 4, 'a', 6), "<list>::append"); + #$pseudoList.append(6); + #test_value($pseudoList, (1, 2, 3, 4, 'a', 6), "<list>::append"); } sub hash_tests() { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <subik@us...> - 2012-09-10 09:54:52
|
Revision: 5027 http://qore.svn.sourceforge.net/qore/?rev=5027&view=rev Author: subik Date: 2012-09-10 09:54:46 +0000 (Mon, 10 Sep 2012) Log Message: ----------- <list>::append(any) implemented Modified Paths: -------------- qore/trunk/lib/Pseudo_QC_List.qpp qore/trunk/test/test.q Modified: qore/trunk/lib/Pseudo_QC_List.qpp =================================================================== --- qore/trunk/lib/Pseudo_QC_List.qpp 2012-09-10 08:08:39 UTC (rev 5026) +++ qore/trunk/lib/Pseudo_QC_List.qpp 2012-09-10 09:54:46 UTC (rev 5027) @@ -175,3 +175,15 @@ return inlist_intern(arg, l, xsink); } +//! Append a value to the oend of the list +/** + @param arg @ref any value to be appended +*/ +nothing <list>::append(any arg) { + QoreNodeEvalOptionalRefHolder value(arg, xsink); + if (*xsink) + return 0; + l->push(value.getReferencedValue()); + return nothing(); +} + Modified: qore/trunk/test/test.q =================================================================== --- qore/trunk/test/test.q 2012-09-10 08:08:39 UTC (rev 5026) +++ qore/trunk/test/test.q 2012-09-10 09:54:46 UTC (rev 5027) @@ -283,6 +283,8 @@ test_value($pseudoList.join('-'), '1-2-3-4-a', "<list>::join"); test_value($pseudoList.lsize(), 5, "<list>::lsize"); test_value($pseudoList.contains(2), True, "<list>::contains"); + $pseudoList.append(6); + test_value($pseudoList, (1, 2, 3, 4, 'a', 6), "<list>::append"); } sub hash_tests() { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <subik@us...> - 2012-09-10 08:08:45
|
Revision: 5026 http://qore.svn.sourceforge.net/qore/?rev=5026&view=rev Author: subik Date: 2012-09-10 08:08:39 +0000 (Mon, 10 Sep 2012) Log Message: ----------- temporary(?) fix to allow docs generator work again Modified Paths: -------------- qore/trunk/doxygen/pdox Modified: qore/trunk/doxygen/pdox =================================================================== --- qore/trunk/doxygen/pdox 2012-09-09 18:05:55 UTC (rev 5025) +++ qore/trunk/doxygen/pdox 2012-09-10 08:08:39 UTC (rev 5026) @@ -13,7 +13,8 @@ grep -e __[0-9]_ -e zzz "$1"/*.html "$1"/*.js "$1"/*.qhp 2>/dev/null |cut -f1 -d:|uniq|while read a; do echo processing $a #sed $OPT -e 's/__7_ /*/g' $a > t; mv t $a - sed $OPT -e 's/__7_ /*/g' -e 's/"Qore::zzz8([a-z]+)zzz9"/"<\1>"/g' -e 's/>([^<>]*)Qore::zzz8([a-z]+)zzz9([^<>]*)<\//\>\1\<\2\>\3<\//g' -e 's/>([^<>]*)zzz8([a-z]+)zzz9([^<>]*)<\//\>\1\<\2\>\3<\//g' -e 's/for Qore::zzz8([a-z]+)zzz9:/for Qore::\<\1\>:/g' -e "s/'Qore::zzz8([a-z]+)zzz9'/'\<\1\>'/g" -e 's/"zzz8([a-z]+)zzz9"/"<\1>"/g' -e "s/'Qore::zzz8([a-z]+)zzz9::([^']+)\(([^\)]*))'/'Qore::\<\1\>::\2(\3)'/g" -e "s/'zzz8([a-z]+)zzz9'/'\1'/g" $a > t; mv t $a + sed $OPT -e 's/__7_ /*/g' -e 's/"Qore::zzz8([a-z]+)zzz9"/"<\1>"/g' -e 's/>([^<>]*)Qore::zzz8([a-z]+)zzz9([^<>]*)<\//\>\1\<\2\>\3<\//g' -e 's/>([^<>]*)zzz8([a-z]+)zzz9([^<>]*)<\//\>\1\<\2\>\3<\//g' -e 's/for Qore::zzz8([a-z]+)zzz9:/for Qore::\<\1\>:/g' -e "s/'Qore::zzz8([a-z]+)zzz9'/'\<\1\>'/g" -e 's/"zzz8([a-z]+)zzz9"/"<\1>"/g' -e "s/'zzz8([a-z]+)zzz9'/'\1'/g" $a > t; mv t $a + # -e "s/'Qore::zzz8([a-z]+)zzz9::([^']+)\(([^\)]*))'/'Qore::\<\1\>::\2(\3)'/g" # -e 's/>zzz8([a-z]+)zzz9<\//>\<\1><\//g' done shift This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <david_nichols@us...> - 2012-09-09 18:06:01
|
Revision: 5025 http://qore.svn.sourceforge.net/qore/?rev=5025&view=rev Author: david_nichols Date: 2012-09-09 18:05:55 +0000 (Sun, 09 Sep 2012) Log Message: ----------- minor doc updates Modified Paths: -------------- module-oracle/trunk/Makefile.am module-oracle/trunk/docs/doxyfile.tmpl module-oracle/trunk/docs/mainpage.doxygen.tmpl Modified: module-oracle/trunk/Makefile.am =================================================================== --- module-oracle/trunk/Makefile.am 2012-09-09 17:26:02 UTC (rev 5024) +++ module-oracle/trunk/Makefile.am 2012-09-09 18:05:55 UTC (rev 5025) @@ -24,7 +24,6 @@ src/ocilib/ocilib.h \ src/ocilib/oci_loader.h - EXTRA_DIST = COPYING ChangeLog AUTHORS README \ RELEASE-NOTES \ src/ql_oracle.qpp \ Modified: module-oracle/trunk/docs/doxyfile.tmpl =================================================================== --- module-oracle/trunk/docs/doxyfile.tmpl 2012-09-09 17:26:02 UTC (rev 5024) +++ module-oracle/trunk/docs/doxyfile.tmpl 2012-09-09 18:05:55 UTC (rev 5025) @@ -27,7 +27,7 @@ # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. -PROJECT_NAME = "Qore Oracle Module" +PROJECT_NAME = "Qore oracle Module" # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or Modified: module-oracle/trunk/docs/mainpage.doxygen.tmpl =================================================================== --- module-oracle/trunk/docs/mainpage.doxygen.tmpl 2012-09-09 17:26:02 UTC (rev 5024) +++ module-oracle/trunk/docs/mainpage.doxygen.tmpl 2012-09-09 18:05:55 UTC (rev 5025) @@ -1,5 +1,7 @@ -/** @mainpage %Qore Oracle Module +/** @mainpage %Qore oracle Module + @tableofcontents + Contents of this documentation: - @ref intro - @ref bindings_and_types This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <david_nichols@us...> - 2012-09-09 17:26:08
|
Revision: 5024 http://qore.svn.sourceforge.net/qore/?rev=5024&view=rev Author: david_nichols Date: 2012-09-09 17:26:02 +0000 (Sun, 09 Sep 2012) Log Message: ----------- added missing files from last commit Added Paths: ----------- qore/trunk/include/qore/QoreNumberNode.h qore/trunk/lib/QoreNumberNode.cpp Added: qore/trunk/include/qore/QoreNumberNode.h =================================================================== --- qore/trunk/include/qore/QoreNumberNode.h (rev 0) +++ qore/trunk/include/qore/QoreNumberNode.h 2012-09-09 17:26:02 UTC (rev 5024) @@ -0,0 +1,169 @@ +/* -*- mode: c++; indent-tabs-mode: nil -*- */ +/* + QoreNumberNode.h + + Qore Programming Language + + Copyright 2003 - 2012 David Nichols + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef _QORE_QORENUMBERNODE_H + +#define _QORE_QORENUMBERNODE_H + +class LocalVar; +class QoreTypeInfo; + +//! Qore's arbitrary-precision number value type, dynamically-allocated only, reference counted +class QoreNumberNode : public SimpleValueQoreNode { +private: + //! returns the value as a bool + DLLLOCAL virtual bool getAsBoolImpl() const; + + //! returns the value as an int + DLLLOCAL virtual int getAsIntImpl() const; + + //! returns the value as a 64-bit int + DLLLOCAL virtual int64 getAsBigIntImpl() const; + + //! returns the value as a double + DLLLOCAL virtual double getAsFloatImpl() const; + +protected: + //! the private implementation of the type + struct qore_number_private* priv; + + //! the destructor is protected because it should not be called directly + /** + @see SimpleValueQoreNode::deref() + */ + DLLEXPORT virtual ~QoreNumberNode(); + +public: + //! creates a new number value and assigns the initial value to it + /** + @param f the value for the object + */ + DLLEXPORT QoreNumberNode(double f); + + //! creates a new number value and assigns the initial value to it + /** + @param i the value for the object + */ + DLLEXPORT QoreNumberNode(int64 i); + + //! creates a new number value and assigns the initial value to it + /** + @param str the value for the object + */ + DLLEXPORT QoreNumberNode(const char* str); + + //! creates a new numbering-point value and assigns it to 0 + DLLEXPORT QoreNumberNode(); + + //! creates a copy of the object + DLLEXPORT QoreNumberNode(const QoreNumberNode& old); + + //! returns the number value converted to a string and sets del to true + /** NOTE: do not use this function directly, use QoreStringValueHelper instead + @param del output parameter: del is set to true, meaning that the resulting QoreString pointer belongs to the caller (and must be deleted manually) + @return a QoreString pointer, use the del output parameter to determine ownership of the pointer + @see QoreStringValueHelper + */ + DLLEXPORT virtual QoreString* getStringRepresentation(bool& del) const; + + //! concatentates the number value to an existing QoreString reference, default implementation does nothing + /** + @param str a reference to a QoreString where the value of the type will be concatenated + */ + DLLEXPORT virtual void getStringRepresentation(QoreString& str) const; + + //! returns the DateTime representation of this value and sets del to true + /** The DateTime representation is calculated by converting the number value + to an integer interpreted as the number of seconds offset from January 1, 1970. + @note Use the DateTimeValueHelper class instead of using this function directly + @param del output parameter: if del is true, then the returned DateTime pointer belongs to the caller (and must be deleted manually), if false, then it must not be + @see DateTimeValueHelper + */ + DLLEXPORT virtual class DateTime *getDateTimeRepresentation(bool& del) const; + + //! assigns the date representation of the value to the DateTime reference passed + /** The DateTime representation is calculated by converting the number value + to an integer interpreted as the number of seconds offset from January 1, 1970. + @param dt the DateTime reference to be assigned + */ + DLLEXPORT virtual void getDateTimeRepresentation(DateTime& dt) const; + + //! concatenate the string representation of the number value to an existing QoreString + /** used for %n and %N printf formatting + @param str the string representation of the type will be concatenated to this QoreString reference + @param foff for multi-line formatting offset, ignored by this implementation of the function + @param xsink ignored by this implementation of the function + @return -1 for exception raised, 0 = OK + */ + DLLEXPORT virtual int getAsString(QoreString& str, int foff, class ExceptionSink* xsink) const; + + //! returns a QoreString giving the string representation of the number value, sets del to true + /** Used for %n and %N printf formatting. Do not call this function directly; use the QoreNodeAsStringHelper class (defined in QoreStringNode.h) instead + @param del if this is true when the function returns, then the returned QoreString pointer should be deleted, if false, then it must not be + @param foff for multi-line formatting offset, ignored by this implementation of the function + @param xsink ignored by this implementation of the function + @see QoreNodeAsStringHelper + */ + DLLEXPORT virtual QoreString *getAsString(bool& del, int foff, class ExceptionSink* xsink) const; + + //! returns a copy of the object; the caller owns the reference count + /** + @return a copy of the object; the caller owns the reference count + */ + DLLEXPORT virtual AbstractQoreNode* realCopy() const; + + //! tests for equality with possible type conversion (soft compare) + /** + @param v the value to compare + @param xsink ignored by this implementation of the function + @return true if the objects are equal, false if not + */ + DLLEXPORT virtual bool is_equal_soft(const AbstractQoreNode* v, ExceptionSink* xsink) const; + + //! tests for equality without type conversions (hard compare) + /** + @param v the value to compare + @param xsink ignored by this implementation of the function + @return true if the objects are equal, false if not + */ + DLLEXPORT virtual bool is_equal_hard(const AbstractQoreNode* v, ExceptionSink* xsink) const; + + //! returns the type name as a c string + /** + @return the type name as a c string + */ + DLLEXPORT virtual const char* getTypeName() const; + + //! returns the type information + DLLLOCAL virtual AbstractQoreNode* parseInit(LocalVar* oflag, int pflag, int& lvids, const QoreTypeInfo*& typeInfo); + + //! returns the type name as a c string + /** + @return the type name as a c string + */ + DLLLOCAL static const char* getStaticTypeName() { + return "number"; + } +}; + +#endif Added: qore/trunk/lib/QoreNumberNode.cpp =================================================================== --- qore/trunk/lib/QoreNumberNode.cpp (rev 0) +++ qore/trunk/lib/QoreNumberNode.cpp 2012-09-09 17:26:02 UTC (rev 5024) @@ -0,0 +1,143 @@ +/* + QoreNumberNode.cpp + + Qore Programming Language + + Copyright 2003 - 2012 David Nichols + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include <qore/Qore.h> + +struct qore_number_private { + DLLLOCAL qore_number_private() { + } + + DLLLOCAL qore_number_private(double f) { + } + + DLLLOCAL qore_number_private(int64 i) { + } + + DLLLOCAL qore_number_private(const char* str) { + } + + DLLLOCAL qore_number_private(const qore_number_private& old) { + } +}; + +QoreNumberNode::QoreNumberNode(double f) : SimpleValueQoreNode(NT_NUMBER), priv(new qore_number_private(f)) { +} + +QoreNumberNode::QoreNumberNode(int64 i) : SimpleValueQoreNode(NT_NUMBER), priv(new qore_number_private(i)) { +} + +QoreNumberNode::QoreNumberNode(const char* str) : SimpleValueQoreNode(NT_NUMBER), priv(new qore_number_private(str)) { +} + +QoreNumberNode::QoreNumberNode() : SimpleValueQoreNode(NT_NUMBER), priv(new qore_number_private) { +} + +QoreNumberNode::QoreNumberNode(const QoreNumberNode& old) : SimpleValueQoreNode(old), priv(new qore_number_private(*old.priv)) { +} + +QoreNumberNode::~QoreNumberNode() { + delete priv; +} + +// get the value of the type in a string context (default implementation = del = false and returns NullString) +// if del is true, then the returned QoreString * should be deleted, if false, then it must not be +// use the QoreStringValueHelper class (defined in QoreStringNode.h) instead of using this function directly +QoreString *QoreNumberNode::getStringRepresentation(bool& del) const { + del = true; + return new QoreString("xxx"); +} + +// concatenate string representation to a QoreString (no action for complex types = default implementation) +void QoreNumberNode::getStringRepresentation(QoreString& str) const { + str.concat("xxx"); +} + +// if del is true, then the returned DateTime * should be deleted, if false, then it should not +DateTime *QoreNumberNode::getDateTimeRepresentation(bool& del) const { + del = true; + return DateTime::makeAbsoluteLocal(currentTZ(), (int64)0, (int)0); +} + +// assign date representation to a DateTime (no action for complex types = default implementation) +void QoreNumberNode::getDateTimeRepresentation(DateTime& dt) const { + dt.setLocalDate(currentTZ(), (int64)0, (int)0); +} + +bool QoreNumberNode::getAsBoolImpl() const { + return (bool)false; +} + +int QoreNumberNode::getAsIntImpl() const { + return (int)0; +} + +int64 QoreNumberNode::getAsBigIntImpl() const { + return (int64)0; +} + +double QoreNumberNode::getAsFloatImpl() const { + return 0.0; +} + +// get string representation (for %n and %N), foff is for multi-line formatting offset, -1 = no line breaks +// the ExceptionSink is only needed for QoreObject where a method may be executed +// use the QoreNodeAsStringHelper class (defined in QoreStringNode.h) instead of using these functions directly +// returns -1 for exception raised, 0 = OK +int QoreNumberNode::getAsString(QoreString& str, int foff, ExceptionSink *xsink) const { + getStringRepresentation(str); + return 0; +} + +// if del is true, then the returned QoreString * should be deleted, if false, then it must not be +QoreString *QoreNumberNode::getAsString(bool& del, int foff, ExceptionSink *xsink) const { + return getStringRepresentation(del); +} + +AbstractQoreNode *QoreNumberNode::realCopy() const { + return new QoreNumberNode(*this); +} + +// performs a lexical compare, return -1, 0, or 1 if the "this" value is less than, equal, or greater than +// the "val" passed +//DLLLOCAL virtual int compare(const AbstractQoreNode *val) const; +// the type passed must always be equal to the current type +bool QoreNumberNode::is_equal_soft(const AbstractQoreNode *v, ExceptionSink *xsink) const { + return false; +} + +bool QoreNumberNode::is_equal_hard(const AbstractQoreNode *v, ExceptionSink *xsink) const { + const QoreNumberNode *fn = dynamic_cast<const QoreNumberNode *>(v); + if (!fn) + return false; + + return false; +} + +// returns the type name as a c string +const char *QoreNumberNode::getTypeName() const { + return getStaticTypeName(); +} + +AbstractQoreNode *QoreNumberNode::parseInit(LocalVar *oflag, int pflag, int& lvids, const QoreTypeInfo*& typeInfo) { + typeInfo = numberTypeInfo; + return this; +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <david_nichols@us...> - 2012-09-09 17:24:51
|
Revision: 5023 http://qore.svn.sourceforge.net/qore/?rev=5023&view=rev Author: david_nichols Date: 2012-09-09 17:24:44 +0000 (Sun, 09 Sep 2012) Log Message: ----------- * updated module API to 0.14 * updated build to require gmp & mpfr for arbitrary-precision numeric support * started adding the "number" type (NT_NUMBER, QoreNumberNode); currently non functional Modified Paths: -------------- qore/trunk/configure.ac qore/trunk/include/qore/AbstractQoreNode.h qore/trunk/include/qore/ModuleManager.h qore/trunk/include/qore/Qore.h qore/trunk/include/qore/QoreType.h qore/trunk/include/qore/intern/QoreLibIntern.h qore/trunk/include/qore/intern/QoreTypeInfo.h qore/trunk/include/qore/node_types.h qore/trunk/lib/AbstractQoreNode.cpp qore/trunk/lib/Makefile.am qore/trunk/lib/ModuleManager.cpp qore/trunk/lib/QoreTypeInfo.cpp qore/trunk/lib/single-compilation-unit.cpp qore/trunk/qore.spec Modified: qore/trunk/configure.ac =================================================================== --- qore/trunk/configure.ac 2012-09-09 06:07:43 UTC (rev 5022) +++ qore/trunk/configure.ac 2012-09-09 17:24:44 UTC (rev 5023) @@ -517,6 +517,140 @@ QORE_LIB_CPPFLAGS="$QORE_LIB_CPPFLAGS $ZLIB_CPPFLAGS" } +set_gmp_cppflags() { + if test "$1" != "/usr/include"; then + GMP_CPPFLAGS=-I$1 + fi + with_gmp_includes="$1" +} + +find_gmp() { + dir="$1" + if test -z "$dir" -o "$dir" = "/"; then + if test -h /lib${LIBSUFFIX}; then + dir=/usr + lib=/usr/lib${LIBSUFFIX} + inc=/usr/include + else + dir=/ + lib=/lib${LIBSUFFIX} + inc=/usr/include + fi + else + lib="$dir/lib${LIBSUFFIX}" + inc="$dir/include" + fi + # if we only want the static gmp libraries + if test -n "$gmp_static"; then + if test -f "$lib/libgmp.a"; then + GMP_LDFLAGS="$lib/libgmp.a" + with_gmp_libs="$lib" + gmp_static=1 + fi + else + if test -f "$lib/libgmp.${SHLIB_SUFFIX}"; then + if test "$lib" != "/lib" -a "$lib" != "/usr/lib"; then + GMP_LDFLAGS="-L$lib" + fi + GMP_LDFLAGS="$GMP_LDFLAGS -lgmp" + with_gmp_libs="$lib" + elif test -f "$lib/libgmp.a"; then + if test "$mingw" = yes -a "$make_dll" = yes; then + GMP_LDFLAGS="-Wl,$lib/libgmp.a" + else + if test "$lib" != "/lib" -a "$lib" != "/usr/lib"; then + GMP_LDFLAGS="-L$lib" + fi + GMP_LDFLAGS="$GMP_LDFLAGS -lgmp" + fi + with_gmp_libs="$lib" + gmp_static=1 + fi + fi + if test -z "$GMP_LDFLAGS"; then + return + fi + # try to find include files + if test -f "$inc/gmp.h"; then + set_gmp_cppflags $inc + elif test -f "$inc/gmp/gmp.h"; then + set_gmp_cppflags $inc/gmp + else + unset GMP_LDFLAGS + unset with_gmp_libs + return + fi + QORE_LIB_LDFLAGS="$QORE_LIB_LDFLAGS $GMP_LDFLAGS" + QORE_LIB_CPPFLAGS="$QORE_LIB_CPPFLAGS $GMP_CPPFLAGS" +} + +set_mpfr_cppflags() { + if test "$1" != "/usr/include"; then + MPFR_CPPFLAGS=-I$1 + fi + with_mpfr_includes="$1" +} + +find_mpfr() { + dir="$1" + if test -z "$dir" -o "$dir" = "/"; then + if test -h /lib${LIBSUFFIX}; then + dir=/usr + lib=/usr/lib${LIBSUFFIX} + inc=/usr/include + else + dir=/ + lib=/lib${LIBSUFFIX} + inc=/usr/include + fi + else + lib="$dir/lib${LIBSUFFIX}" + inc="$dir/include" + fi + # if we only want the static mpfr libraries + if test -n "$mpfr_static"; then + if test -f "$lib/libmpfr.a"; then + MPFR_LDFLAGS="$lib/libmpfr.a" + with_mpfr_libs="$lib" + mpfr_static=1 + fi + else + if test -f "$lib/libmpfr.${SHLIB_SUFFIX}"; then + if test "$lib" != "/lib" -a "$lib" != "/usr/lib"; then + MPFR_LDFLAGS="-L$lib" + fi + MPFR_LDFLAGS="$MPFR_LDFLAGS -lmpfr" + with_mpfr_libs="$lib" + elif test -f "$lib/libmpfr.a"; then + if test "$mingw" = yes -a "$make_dll" = yes; then + MPFR_LDFLAGS="-Wl,$lib/libmpfr.a" + else + if test "$lib" != "/lib" -a "$lib" != "/usr/lib"; then + MPFR_LDFLAGS="-L$lib" + fi + MPFR_LDFLAGS="$MPFR_LDFLAGS -lmpfr" + fi + with_mpfr_libs="$lib" + mpfr_static=1 + fi + fi + if test -z "$MPFR_LDFLAGS"; then + return + fi + # try to find include files + if test -f "$inc/mpfr.h"; then + set_mpfr_cppflags $inc + elif test -f "$inc/mpfr/mpfr.h"; then + set_mpfr_cppflags $inc/mpfr + else + unset MPFR_LDFLAGS + unset with_mpfr_libs + return + fi + QORE_LIB_LDFLAGS="$QORE_LIB_LDFLAGS $MPFR_LDFLAGS" + QORE_LIB_CPPFLAGS="$QORE_LIB_CPPFLAGS $MPFR_CPPFLAGS" +} + # allow the user to set a generic search prefix for libraries, includes, etc AC_ARG_WITH([lib-prefix], [AS_HELP_STRING([--with-lib-prefix@<:@=DIR@:>@], @@ -547,6 +681,38 @@ AC_MSG_RESULT([includes $with_zlib_includes libs $with_zlib_libs (shared)]) fi +AC_MSG_CHECKING([for gmp libraries and header files]) +for dir in "${with_gmp_dir}" "${with_lib_prefix}" "${find_prefix}" /usr / /usr/local /opt/gnu /opt/gmp /usr/local/gmp /opt/local /sw /usr/sfw /opt/sfw; do + find_gmp $dir + if test -n "$GMP_LDFLAGS"; then + break + fi +done +if test -z "$GMP_LDFLAGS"; then + AC_MSG_ERROR([no gmp library found]) +fi +if test -n "$gmp_static"; then + AC_MSG_RESULT([includes $with_gmp_includes libs $with_gmp_libs (static)]) +else + AC_MSG_RESULT([includes $with_gmp_includes libs $with_gmp_libs (shared)]) +fi + +AC_MSG_CHECKING([for mpfr libraries and header files]) +for dir in "${with_mpfr_dir}" "${with_lib_prefix}" "${find_prefix}" /usr / /usr/local /opt/gnu /opt/mpfr /usr/local/mpfr /opt/local /sw /usr/sfw /opt/sfw; do + find_mpfr $dir + if test -n "$MPFR_LDFLAGS"; then + break + fi +done +if test -z "$MPFR_LDFLAGS"; then + AC_MSG_ERROR([no mpfr library found]) +fi +if test -n "$mpfr_static"; then + AC_MSG_RESULT([includes $with_mpfr_includes libs $with_mpfr_libs (static)]) +else + AC_MSG_RESULT([includes $with_mpfr_includes libs $with_mpfr_libs (shared)]) +fi + set_pcre_cppflags() { if test "$1" != "/usr/include"; then PCRE_CPPFLAGS=-I$1 @@ -1405,6 +1571,7 @@ AM_CONDITIONAL([COND_NEED_INET_NTOP], [test "$ac_cv_func_inet_ntop" != yes]) AM_CONDITIONAL([COND_NEED_INET_PTON], [test "$ac_cv_func_inet_pton" != yes]) AM_CONDITIONAL([COND_NEED_GETOPT_LONG], [test "$ac_cv_header_getopt_h" != yes]) +AM_CONDITIONAL([COND_HAVE_MPFR], [test "$have_mpfr_h" = yes]) AM_CONDITIONAL([COND_MINGWCC], [test "$mingw" = yes]) # find prefix @@ -1522,4 +1689,3 @@ sed -e 's/deplibs_check_method=.*/deplibs_check_method=pass_all/g' -e 's/libext=.*/libext=a/g' libtool > libtool.tmp mv libtool.tmp libtool fi - Modified: qore/trunk/include/qore/AbstractQoreNode.h =================================================================== --- qore/trunk/include/qore/AbstractQoreNode.h 2012-09-09 06:07:43 UTC (rev 5022) +++ qore/trunk/include/qore/AbstractQoreNode.h 2012-09-09 17:24:44 UTC (rev 5023) @@ -47,9 +47,6 @@ class AbstractQoreNode : public QoreReferenceCounter { private: //! this function is not implemented; it is here as a private function in order to prohibit it from being used - DLLLOCAL AbstractQoreNode(const AbstractQoreNode&); - - //! this function is not implemented; it is here as a private function in order to prohibit it from being used DLLLOCAL AbstractQoreNode& operator=(const AbstractQoreNode&); //! default implementation, returns false @@ -180,6 +177,9 @@ */ DLLEXPORT AbstractQoreNode(qore_type_t t, bool n_value, bool n_needs_eval, bool n_there_can_be_only_one = false, bool n_custom_reference_handlers = false); + //! copy constructor + DLLEXPORT AbstractQoreNode(const AbstractQoreNode& v); + //! returns the boolean value of the object /** calls getAsBoolImpl() if necessary (there is an optimization for the QoreBoolNode class) to return the boolean value of the object @@ -401,7 +401,7 @@ DLLLOCAL SimpleQoreNode(qore_type_t t, bool n_value, bool n_needs_eval, bool n_there_can_be_only_one = false) : AbstractQoreNode(t, n_value, n_needs_eval, n_there_can_be_only_one) { } //! copy constructor - DLLLOCAL SimpleQoreNode(const SimpleQoreNode &) : AbstractQoreNode(type, value, needs_eval_flag, there_can_be_only_one) { } + DLLLOCAL SimpleQoreNode(const SimpleQoreNode& v) : AbstractQoreNode(v) { } //! decrements the reference count and deletes the object when references = 0 /** @@ -450,7 +450,7 @@ //! creates the object by assigning the type code and setting the "value" flag, unsetting the "needs_eval" flag, and setting "there_can_be_only_one" DLLLOCAL SimpleValueQoreNode(qore_type_t t, bool n_there_can_be_only_one = false) : SimpleQoreNode(t, true, false, n_there_can_be_only_one) { } - DLLLOCAL SimpleValueQoreNode(const SimpleValueQoreNode &v) : SimpleQoreNode(type, true, false, there_can_be_only_one) { } + DLLLOCAL SimpleValueQoreNode(const SimpleValueQoreNode &v) : SimpleQoreNode(v) { } }; //! this class is for value types that will exists only once in the Qore library, reference counting is disabled Modified: qore/trunk/include/qore/ModuleManager.h =================================================================== --- qore/trunk/include/qore/ModuleManager.h 2012-09-09 06:07:43 UTC (rev 5022) +++ qore/trunk/include/qore/ModuleManager.h 2012-09-09 17:24:44 UTC (rev 5023) @@ -35,10 +35,10 @@ */ #define QORE_MODULE_API_MAJOR 0 //!< the major number of the Qore module API implemented -#define QORE_MODULE_API_MINOR 13 //!< the minor number of the Qore module API implemented +#define QORE_MODULE_API_MINOR 14 //!< the minor number of the Qore module API implemented #define QORE_MODULE_COMPAT_API_MAJOR 0 //!< the major number of the earliest recommended Qore module API -#define QORE_MODULE_COMPAT_API_MINOR 13 //!< the minor number of the earliest recommended Qore module API +#define QORE_MODULE_COMPAT_API_MINOR 14 //!< the minor number of the earliest recommended Qore module API //! element of qore_mod_api_list; struct qore_mod_api_compat_s { Modified: qore/trunk/include/qore/Qore.h =================================================================== --- qore/trunk/include/qore/Qore.h 2012-09-09 06:07:43 UTC (rev 5022) +++ qore/trunk/include/qore/Qore.h 2012-09-09 17:24:44 UTC (rev 5023) @@ -49,6 +49,7 @@ #include <qore/QoreBigIntNode.h> #include <qore/QoreBoolNode.h> #include <qore/QoreFloatNode.h> +#include <qore/QoreNumberNode.h> #include <qore/QoreNothingNode.h> #include <qore/QoreNullNode.h> #include <qore/QoreNet.h> Modified: qore/trunk/include/qore/QoreType.h =================================================================== --- qore/trunk/include/qore/QoreType.h 2012-09-09 06:07:43 UTC (rev 5022) +++ qore/trunk/include/qore/QoreType.h 2012-09-09 17:24:44 UTC (rev 5023) @@ -54,6 +54,7 @@ *listTypeInfo, *nothingTypeInfo, *nullTypeInfo, + *numberTypeInfo, *runTimeClosureTypeInfo, *callReferenceTypeInfo, *referenceTypeInfo, @@ -61,6 +62,7 @@ *codeTypeInfo, // either closure or callref *softBigIntTypeInfo, // converts to int from float, string, and bool *softFloatTypeInfo, // converts to float from int, string, and bool + *softNumberTypeInfo, // xxx *softBoolTypeInfo, // converts to bool from int, float, and string *softStringTypeInfo, // converts to string from int, float, and bool *softDateTypeInfo, // converts to date from int, float, bool, and string @@ -72,6 +74,7 @@ *bigIntOrNothingTypeInfo, *floatOrNothingTypeInfo, + *numberOrNothingTypeInfo, *stringOrNothingTypeInfo, *boolOrNothingTypeInfo, *binaryOrNothingTypeInfo, @@ -85,6 +88,7 @@ *softBigIntOrNothingTypeInfo, *softFloatOrNothingTypeInfo, + *softNumberOrNothingTypeInfo, *softBoolOrNothingTypeInfo, *softStringOrNothingTypeInfo, *softDateOrNothingTypeInfo, @@ -211,5 +215,4 @@ DLLEXPORT qore_type_result_e typeInfoAcceptsType(const QoreTypeInfo *typeInfo, const QoreTypeInfo *otherTypeInfo); DLLEXPORT qore_type_result_e typeInfoReturnsType(const QoreTypeInfo *typeInfo, const QoreTypeInfo *otherTypeInfo); - #endif // _QORE_QORETYPE_H Modified: qore/trunk/include/qore/intern/QoreLibIntern.h =================================================================== --- qore/trunk/include/qore/intern/QoreLibIntern.h 2012-09-09 06:07:43 UTC (rev 5022) +++ qore/trunk/include/qore/intern/QoreLibIntern.h 2012-09-09 17:24:44 UTC (rev 5023) @@ -29,6 +29,7 @@ #include <stdarg.h> #include <sys/types.h> + #ifdef HAVE_SYS_STATVFS_H #include <sys/statvfs.h> #endif @@ -74,6 +75,9 @@ #include <netinet/tcp.h> #endif +// for arbitrary-precision numeric support +#include <mpfr.h> + // printf format for size_t or qore_size_t integers #if TARGET_BITS == 64 #define QSD QLLD @@ -92,12 +96,13 @@ #define NT_CODE -3 #define NT_SOFTINT -4 #define NT_SOFTFLOAT -5 -#define NT_SOFTBOOLEAN -6 -#define NT_SOFTSTRING -7 -#define NT_SOFTDATE -8 -#define NT_SOFTLIST -9 -#define NT_TIMEOUT -10 -#define NT_INTORFLOAT -11 +#define NT_SOFTNUMBER -6 +#define NT_SOFTBOOLEAN -7 +#define NT_SOFTSTRING -8 +#define NT_SOFTDATE -9 +#define NT_SOFTLIST -10 +#define NT_TIMEOUT -11 +#define NT_INTORFLOAT -12 #define NT_SOMETHING -101 // i.e. "not NOTHING" #define NT_DATA -102 // either QoreStringNode or BinaryNode Modified: qore/trunk/include/qore/intern/QoreTypeInfo.h =================================================================== --- qore/trunk/include/qore/intern/QoreTypeInfo.h 2012-09-09 06:07:43 UTC (rev 5022) +++ qore/trunk/include/qore/intern/QoreTypeInfo.h 2012-09-09 17:24:44 UTC (rev 5023) @@ -1146,6 +1146,85 @@ } }; +class NumberOrNothingTypeInfo : public AcceptsReturnsMultiFilterTypeInfo { +protected: + DLLLOCAL virtual const char *getNameImpl() const { + return "*number"; + } + + DLLLOCAL bool acceptInputImpl(AbstractQoreNode *&n, ExceptionSink *xsink) const { + qore_type_t t = get_node_type(n); + + if (t == NT_NUMBER || t == NT_NOTHING) + return true; + + if (t == NT_FLOAT) { + QoreNumberNode* nn = new QoreNumberNode(reinterpret_cast<const QoreFloatNode*>(n)->f); + n->deref(xsink); + n = nn; + return true; + } + + // only perform dynamic cast if type is external + if (t != NT_INT && (t < QORE_NUM_TYPES || !dynamic_cast<const QoreBigIntNode *>(n))) + return false; + + QoreNumberNode* nn = new QoreNumberNode(reinterpret_cast<const QoreBigIntNode *>(n)->val); + n->deref(xsink); + n = nn; + return true; + } + +public: + DLLLOCAL NumberOrNothingTypeInfo() : AcceptsReturnsMultiFilterTypeInfo(0, NT_NUMBER, false, true, false, false) { + assert(numberTypeInfo); + at.push_back(numberTypeInfo); + assert(bigIntTypeInfo); + at.push_back(bigIntTypeInfo); + assert(floatTypeInfo); + at.push_back(floatTypeInfo); + assert(nothingTypeInfo); + at.push_back(nothingTypeInfo); + + rt.push_back(numberTypeInfo); + rt.push_back(nothingTypeInfo); + } +}; + +class NumberTypeInfo : public AcceptsMultiFilterTypeInfo { +protected: + DLLLOCAL bool acceptInputImpl(AbstractQoreNode*& n, ExceptionSink* xsink) const { + qore_type_t t = get_node_type(n); + + if (t == NT_NUMBER) + return true; + + if (t == NT_FLOAT) { + QoreNumberNode* nn = new QoreNumberNode(reinterpret_cast<const QoreFloatNode*>(n)->f); + n->deref(xsink); + n = nn; + return true; + } + + // only perform dynamic cast if type is external + if (t != NT_INT && (t < QORE_NUM_TYPES || !dynamic_cast<const QoreBigIntNode*>(n))) + return false; + + QoreNumberNode* nn = new QoreNumberNode(reinterpret_cast<const QoreBigIntNode*>(n)->val); + n->deref(xsink); + n = nn; + return true; + } + +public: + DLLLOCAL NumberTypeInfo() : AcceptsMultiFilterTypeInfo(0, NT_NUMBER, false, false, false, false, false, true) { + assert(bigIntTypeInfo); + at.push_back(bigIntTypeInfo); + assert(floatTypeInfo); + at.push_back(floatTypeInfo); + } +}; + class IntTypeInfo : public QoreTypeInfo { public: DLLLOCAL IntTypeInfo(qore_type_t n_qt, bool n_accepts_mult = false, bool n_input_filter = false, @@ -1444,6 +1523,102 @@ } }; +// accepts int, float, number, string, date, null, or boolean and returns a number +class SoftNumberTypeInfo : public AcceptsMultiFilterTypeInfo { +protected: + DLLLOCAL virtual const char *getNameImpl() const { + return "softnumber"; + } + + DLLLOCAL virtual bool acceptInputImpl(AbstractQoreNode *&n, ExceptionSink *xsink) const { + qore_type_t t = get_node_type(n); + + if (t == NT_NUMBER) + return true; + + if (t == NT_FLOAT) { + QoreNumberNode* nn = new QoreNumberNode(reinterpret_cast<const QoreFloatNode*>(n)->f); + n->deref(xsink); + n = nn; + return true; + } + + if (t != NT_INT && (t < QORE_NUM_TYPES || !dynamic_cast<const QoreBigIntNode *>(n)) + && t != NT_STRING + && t != NT_BOOLEAN + && t != NT_DATE + && t != NT_NULL) + return false; + + double rv = n->getAsFloat(); + n->deref(xsink); + n = new QoreNumberNode(rv); + return true; + } + + // must be reimplemented in subclasses if has_defval is true + DLLLOCAL virtual AbstractQoreNode *getDefaultValueImpl() const { + // XXX return zero_number(); + return 0; + } + +public: + DLLLOCAL SoftNumberTypeInfo(bool n_returns_mult = false) : AcceptsMultiFilterTypeInfo(0, NT_NUMBER, n_returns_mult, false, true, n_returns_mult ? false : true, false, n_returns_mult ? false : true) { + at.push_back(floatTypeInfo); + at.push_back(bigIntTypeInfo); + at.push_back(stringTypeInfo); + at.push_back(boolTypeInfo); + at.push_back(dateTypeInfo); + at.push_back(nullTypeInfo); + } +}; + +class SoftNumberOrNothingTypeInfo : public SoftNumberTypeInfo { +protected: + type_vec_t rt; + + DLLLOCAL virtual const type_vec_t &getReturnTypeList() const { + return rt; + } + + DLLLOCAL virtual const char *getNameImpl() const { + return "*softnumber"; + } + + DLLLOCAL virtual bool acceptInputImpl(AbstractQoreNode *&n, ExceptionSink *xsink) const { + qore_type_t t = get_node_type(n); + + if (t == NT_NUMBER || t == NT_NOTHING) + return true; + + if (t == NT_FLOAT) { + QoreNumberNode* nn = new QoreNumberNode(reinterpret_cast<const QoreFloatNode*>(n)->f); + n->deref(xsink); + n = nn; + return true; + } + + if (t != NT_INT && (t < QORE_NUM_TYPES || !dynamic_cast<const QoreBigIntNode*>(n)) + && t != NT_STRING + && t != NT_BOOLEAN + && t != NT_DATE + && t != NT_NULL) + return false; + + double rv = n->getAsFloat(); + n->deref(xsink); + n = new QoreNumberNode(rv); + return true; + } + +public: + DLLLOCAL SoftNumberOrNothingTypeInfo() : SoftNumberTypeInfo(true) { + at.push_back(nothingTypeInfo); + rt.push_back(numberTypeInfo); + rt.push_back(nothingTypeInfo); + } +}; + // accepts int, float, string, date, null, or boolean and returns a boolean class SoftBoolTypeInfo : public AcceptsMultiFilterTypeInfo { protected: Modified: qore/trunk/include/qore/node_types.h =================================================================== --- qore/trunk/include/qore/node_types.h 2012-09-09 06:07:43 UTC (rev 5022) +++ qore/trunk/include/qore/node_types.h 2012-09-09 17:24:44 UTC (rev 5023) @@ -42,7 +42,7 @@ const qore_type_t NT_LIST = 8; //!< type value for QoreListNode const qore_type_t NT_HASH = 9; //!< type value for QoreHashNode const qore_type_t NT_OBJECT = 10; //!< type value for QoreObject -const qore_type_t NT_BACKQUOTE = 11; //!< type value for BackquoteNode +const qore_type_t NT_NUMBER = 11; //!< type value for QoreNumberNode const qore_type_t NT_CONTEXTREF = 12; //!< type value for ContextrefNode const qore_type_t NT_COMPLEXCONTEXTREF = 13; //!< type value for ComplexContextrefNode const qore_type_t NT_VARREF = 14; //!< type value for VarRefNode @@ -73,14 +73,15 @@ const qore_type_t NT_CLASS_VARREF = 39; //!< type value for StaticClassVarRefNode (private class) const qore_type_t NT_PROGRAM_FUNC_CALL = 40; //!< type value for ProgramFunctionCallNode (private class) const qore_type_t NT_PARSEREFERENCE = 41; //!< type value for ParseReferenceNode (private class) +const qore_type_t NT_BACKQUOTE = 42; //!< type value for BackquoteNode //! number of types implemented in the Qore library -#define QORE_NUM_TYPES 41 +#define QORE_NUM_TYPES 42 //! number of simple value types (not containers) #define NUM_SIMPLE_TYPES 8 //! number of potential value types (including container types) -#define NUM_VALUE_TYPES 11 +#define NUM_VALUE_TYPES 12 #endif Modified: qore/trunk/lib/AbstractQoreNode.cpp =================================================================== --- qore/trunk/lib/AbstractQoreNode.cpp 2012-09-09 06:07:43 UTC (rev 5022) +++ qore/trunk/lib/AbstractQoreNode.cpp 2012-09-09 17:24:44 UTC (rev 5023) @@ -39,6 +39,12 @@ #endif } +AbstractQoreNode::AbstractQoreNode(const AbstractQoreNode& v) : type(v.type), value(v.value), needs_eval_flag(v.needs_eval_flag), there_can_be_only_one(v.there_can_be_only_one), custom_reference_handlers(v.custom_reference_handlers) { +#if TRACK_REFS + printd(REF_LVL, "AbstractQoreNode::ref() %p type=%d (0->1)\n", this, type); +#endif +} + AbstractQoreNode::~AbstractQoreNode() { #if 0 printd(5, "AbstractQoreNode::~AbstractQoreNode() type=%d (%s)\n", type, getTypeName()); Modified: qore/trunk/lib/Makefile.am =================================================================== --- qore/trunk/lib/Makefile.am 2012-09-09 06:07:43 UTC (rev 5022) +++ qore/trunk/lib/Makefile.am 2012-09-09 17:24:44 UTC (rev 5023) @@ -319,6 +319,7 @@ QoreBigIntNode.cpp \ QoreBoolNode.cpp \ QoreFloatNode.cpp \ + QoreNumberNode.cpp \ QoreNullNode.cpp \ QoreNothingNode.cpp \ Function.cpp \ Modified: qore/trunk/lib/ModuleManager.cpp =================================================================== --- qore/trunk/lib/ModuleManager.cpp 2012-09-09 06:07:43 UTC (rev 5022) +++ qore/trunk/lib/ModuleManager.cpp 2012-09-09 17:24:44 UTC (rev 5023) @@ -49,7 +49,7 @@ #include <vector> #include <set> -static const qore_mod_api_compat_s qore_mod_api_list_l[] = { {0, 13}, {0, 12}, {0, 11}, {0, 10}, {0, 9}, {0, 8}, {0, 7}, {0, 6}, {0, 5} }; +static const qore_mod_api_compat_s qore_mod_api_list_l[] = { {0, 14}, {0, 13}, {0, 12}, {0, 11}, {0, 10}, {0, 9}, {0, 8}, {0, 7}, {0, 6}, {0, 5} }; #define QORE_MOD_API_LEN (sizeof(qore_mod_api_list_l)/sizeof(struct qore_mod_api_compat_s)) // public symbols Modified: qore/trunk/lib/QoreTypeInfo.cpp =================================================================== --- qore/trunk/lib/QoreTypeInfo.cpp 2012-09-09 06:07:43 UTC (rev 5022) +++ qore/trunk/lib/QoreTypeInfo.cpp 2012-09-09 17:24:44 UTC (rev 5023) @@ -81,6 +81,12 @@ const QoreTypeInfo *floatTypeInfo = &staticFloatTypeInfo, *floatOrNothingTypeInfo = &staticFloatOrNothingTypeInfo; +// xxx +static NumberTypeInfo staticNumberTypeInfo; +static NumberOrNothingTypeInfo staticNumberOrNothingTypeInfo; +const QoreTypeInfo *numberTypeInfo = &staticNumberTypeInfo, + *numberOrNothingTypeInfo = &staticNumberOrNothingTypeInfo; + // provides equal compatibility with closures and all types of code references static CodeTypeInfo staticCodeTypeInfo; static CodeOrNothingTypeInfo staticCodeOrNothingTypeInfo; @@ -105,6 +111,12 @@ const QoreTypeInfo *softFloatTypeInfo = &staticSoftFloatTypeInfo, *softFloatOrNothingTypeInfo = &staticSoftFloatOrNothingTypeInfo; +// xxx +static SoftNumberTypeInfo staticSoftNumberTypeInfo; +static SoftNumberOrNothingTypeInfo staticSoftNumberOrNothingTypeInfo; +const QoreTypeInfo *softNumberTypeInfo = &staticSoftNumberTypeInfo, + *softNumberOrNothingTypeInfo = &staticSoftNumberOrNothingTypeInfo; + // provides bool compatibility with and conversions from float, string, date, and int static SoftBoolTypeInfo staticSoftBoolTypeInfo; static SoftBoolOrNothingTypeInfo staticSoftBoolOrNothingTypeInfo; @@ -217,6 +229,7 @@ do_maps(NT_STRING, "string", stringTypeInfo, stringOrNothingTypeInfo); do_maps(NT_BOOLEAN, "bool", boolTypeInfo, boolOrNothingTypeInfo); do_maps(NT_FLOAT, "float", floatTypeInfo, floatOrNothingTypeInfo); + do_maps(NT_NUMBER, "number", numberTypeInfo, numberOrNothingTypeInfo); do_maps(NT_BINARY, "binary", binaryTypeInfo, binaryOrNothingTypeInfo); do_maps(NT_LIST, "list", listTypeInfo, listOrNothingTypeInfo); do_maps(NT_HASH, "hash", hashTypeInfo, hashOrNothingTypeInfo); @@ -231,6 +244,7 @@ do_maps(NT_SOFTINT, "softint", softBigIntTypeInfo, softBigIntOrNothingTypeInfo); do_maps(NT_SOFTFLOAT, "softfloat", softFloatTypeInfo, softFloatOrNothingTypeInfo); + do_maps(NT_SOFTNUMBER, "softnumber", softNumberTypeInfo, softNumberOrNothingTypeInfo); do_maps(NT_SOFTBOOLEAN, "softbool", softBoolTypeInfo, softBoolOrNothingTypeInfo); do_maps(NT_SOFTSTRING, "softstring", softStringTypeInfo, softStringOrNothingTypeInfo); do_maps(NT_SOFTDATE, "softdate", softDateTypeInfo, softDateOrNothingTypeInfo); Modified: qore/trunk/lib/single-compilation-unit.cpp =================================================================== --- qore/trunk/lib/single-compilation-unit.cpp 2012-09-09 06:07:43 UTC (rev 5022) +++ qore/trunk/lib/single-compilation-unit.cpp 2012-09-09 17:24:44 UTC (rev 5023) @@ -22,6 +22,7 @@ #include "QoreBigIntNode.cpp" #include "QoreBoolNode.cpp" #include "QoreFloatNode.cpp" +#include "QoreNumberNode.cpp" #include "QoreNullNode.cpp" #include "QoreNothingNode.cpp" #include "VarRefNode.cpp" Modified: qore/trunk/qore.spec =================================================================== --- qore/trunk/qore.spec 2012-09-09 06:07:43 UTC (rev 5022) +++ qore/trunk/qore.spec 2012-09-09 17:24:44 UTC (rev 5023) @@ -50,6 +50,8 @@ BuildRequires: openssl-devel BuildRequires: pcre-devel BuildRequires: zlib-devel +BuildRequires: gmp-devel +BuildRequires: mpfr-devel BuildRequires: doxygen %if 0%{?suse_version} BuildRequires: pkg-config @@ -75,6 +77,7 @@ %package -n libqore5 Summary: The libraries for the qore runtime and qore clients Group: Development/Languages/Other +Provides: qore-module-api-0.14 Provides: qore-module-api-0.13 Provides: qore-module-api-0.12 Provides: qore-module-api-0.11 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |