pure-lang-svn Mailing List for Pure (Page 20)
Status: Beta
Brought to you by:
agraef
You can subscribe to this list here.
2008 |
Jan
|
Feb
|
Mar
|
Apr
(5) |
May
(141) |
Jun
(184) |
Jul
(97) |
Aug
(232) |
Sep
(196) |
Oct
|
Nov
|
Dec
|
---|
From: <ye...@us...> - 2008-07-06 00:58:41
|
Revision: 395 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=395&view=rev Author: yes Date: 2008-07-05 17:58:50 -0700 (Sat, 05 Jul 2008) Log Message: ----------- more simplifications and addition of Gregorian dates based on Dr Albert Graef's Q code Modified Paths: -------------- pure/trunk/examples/libor/date.pure Modified: pure/trunk/examples/libor/date.pure =================================================================== --- pure/trunk/examples/libor/date.pure 2008-07-06 00:20:07 UTC (rev 394) +++ pure/trunk/examples/libor/date.pure 2008-07-06 00:58:50 UTC (rev 395) @@ -1,5 +1,8 @@ /* New Calendar and Clock Copyright (c) 2008 by Libor Spacek + + Acknowledgement: thanks to Dr Albert Graef for his "Q" code for the + Gregorian date calculation Usage: pure -x date.pure [-h] @@ -8,13 +11,16 @@ (Temps Atomique International) rather than local daylight saving time */ using system; // this is needed just to get C printf -extern int time(int*) = c_time; // makes available the C function time(); +extern long time(long*) = c_time; // makes available the C function time(); puts "****************************************************************"; puts "* New Calendar/Clock, Copyright (c) 2008 by Libor Spacek *"; puts "****************************************************************"; -def posixepoch = (12:17:16:7:5); // Mayan long count date of the posix epoch -def endofcycle = (13:0:0:0:0); // The end of the cycle +// def posixepoch = (12:17:16:7:5); // Mayan long count date of the posix epoch +def mdayposix = 1856305; // Mayan day for the posix epoch Jan 1 1970 +def jdayposix = 2440588; // Julian day for the posix epoch +// def endofcycle = (13:0:0:0:0); // The end of the cycle +def cycledays = 1872000; // Total days in 13 Baktuns def secsinday = 86400; // number of seconds in a day def trueyear = 31556941;// (in seconds) divisible by 13 = current true year def myyear = 31556943;// div by 2277, secsinday compatible, 365.2424 days @@ -25,25 +31,37 @@ // current values in posix time supplied by C time(); posixsecsnow = c_time (pointer 0); // each call refreshes to the current second secsnow = posixsecsnow mod secsinday; // int seconds since midnight + +// either mayan or julian day (and time) as a day number (::double) +mjday epoch::int secs::int |mjday epoch::int secs::bigint= epoch+secs/secsinday; // first some simple conversions +jday2mday day::int | jday2mday day::double = day - jdayposix + mdayposix; +mday2jday day::int | mday2jday day::double = day - mdayposix + jdayposix; + secs2days s::int | secs2days s::bigint | secs2days s::double = (s / secsinday); days2secs d::int | days2secs d::bigint | deys2secs d::double = secsinday * d; days2hours d::int| days2hours d::bigint| days2hours d::double= 24*d; hours2days h::int = h / 24; // conversions from/to days:hours:minutes:seconds format -// seconds can be int or bigint or double. d,h,m are ints +// seconds can be int or double. d,h,m are ints dhms2secs (d::int:h::int:m::int:s::int) | -dhms2secs (d::int:h::int:m::int:s::bigint) | dhms2secs (d::int:h::int:m::int:s::double) = 60*(60*(24*d+h)+m)+s; -secs2dhms secs::int | secs2dhms secs::bigint | secs2dhms secs::double = - d:(h mod 24):(m mod 60):(secs-60*m) +secs2dhms secs::int | secs2dhms secs::bigint = + d:(h mod 24):(m mod 60):(int (secs-60*m)) when m::int = int (secs / 60); h::int = m div 60; d::int = h div 24 + end; + +secs2dhms secs::double = d:(h mod 24):(m mod 60):(secs-60*m) + when + m::int = int (secs / 60); + h::int = m div 60; + d::int = h div 24 end; // an arbitrary binary operator applied to two (days:hours:minutes:seconds) @@ -53,14 +71,17 @@ // conversions from/to hours:minutes:seconds format for displaying time of day. // hours may be more than 24 but use d:h:m:s for longer periods of time hms2secs (h::int:m::int:s::int) | -hms2secs (h::int:m::int:s::bigint) | hms2secs (h::int:m::int:s::double) = 60*(60*h+m)+s; -secs2hms secs::int | secs2hms secs::bigint | secs2hms secs::double = - h:(m mod 60):(secs-60*m) +secs2hms secs::int | secs2hms secs::bigint = h:(m mod 60):(int (secs-60*m)) when m::int = int (secs / 60); h::int = m div 60; + end; +secs2hms secs::double = h:(m mod 60):(secs-60*m) + when + m::int = int (secs / 60); + h::int = m div 60; end; // New Time Format! hours:3mins:10secs:secs = hours:tres:dicis:secs = h:t:d:s @@ -68,16 +89,24 @@ // dicis:secs are easy to read: 6:0 means 60 seconds, 12:5 125 seconds etc. // tres - multiply by three to get traditional babylonian minutes // hours as usual (24 hour clock) -htds2secs (h::int:t::int:d::int:s::int) = 10*(18*(20*h+t)+d)+s; +htds2secs (h::int:t::int:d::int:s::int)| +htds2secs (h::int:t::int:d::int:s::double) = 10*(18*(20*h+t)+d)+s; -secs2htds secs::int | secs2htds secs::bigint | secs2htds secs::double = - h:(t mod 20):(d mod 18):(secs-10*d) +secs2htds secs::int | secs2htds secs::bigint = + h:(t mod 20):(d mod 18):(int (secs-10*d)) when d::int = int (secs / 10); t::int = d div 18; h::int = t div 20 end; +secs2htds secs::double = h:(t mod 20):(d mod 18):(secs-10*d) + when + d::int = int (secs / 10); + t::int = d div 18; + h::int = t div 20 + end; + // not used yet but could be, as in: addmayan posixepoch (days2mayan posixdays) addmayan (baktun1::int:katun1::int:tun1::int:vinal1::int:kin1::int) (baktun2::int:katun2::int:tun2::int:vinal2::int:kin2::int) = @@ -96,29 +125,39 @@ mayan2days (baktun::int:katun::int:tun::int:vinal::int:kin::int) = 20*(18*(20*(20*baktun+katun)+tun)+vinal)+kin; +/* Gregorian date for Julian day number. Please note that these dates are + historically correct only after the introduction of the Gregorian calendar + in 1582 (even much later in some countries). */ + +date N::int = (E-(153*M+2) div 5+1, M+3-12*(M div 10), 100*B+D-4800+M div 10) + when A = N+32044; B = (4*A+3) div 146097; + C = A-146097*B div 4; D = (4*C+3) div 1461; + E = C-1461*D div 4; M = (5*E+2) div 153 end; + + // moon calculations -moonphase psecs::int=((psecs-(dhms2secs newmoondhms))mod lunarmonth)/lunarmonth; +moonphase psecs::int | moonphase psecs::bigint = + ((psecs-(dhms2secs newmoondhms))mod lunarmonth)/lunarmonth; // full moon percentage at psecs posix seconds -fullmoon psecs::int = if mf > 0.5 then 200.0*(1.0-mf) else 200.0*mf - when mf = moonphase psecs end; - +fullmoon psecs::int | fullmoon psecs::bigint = + if mf > 0.5 then 200.0*(1.0-mf) else 200.0*mf when mf = moonphase psecs end; + // for now, let's just do some simple calculations to print -def epochday = mayan2days posixepoch; // (mayan) day of the posix epoch -def cycledays = mayan2days endofcycle; // total days in 13 Baktuns -daytoday = epochday + (secs2days posixsecsnow); // mayan whole day count +daytoday = mjday mdayposix posixsecsnow; // mayan day (double) mayantoday = days2mayan (int daytoday); // as above but in the long count format -daysleft = cycledays-epochday-(secs2days (double posixsecsnow)); // double +daysleft = cycledays - daytoday; mayanleft = days2mayan ((int daysleft)); timeleft = secs2htds (secsinday - secsnow); -percentcomplete = 100.0*(epochday+posixsecsnow/secsinday)/cycledays; +percentcomplete = 100.0*daytoday/cycledays; usage = puts "Usage: pure -x date.pure [anyarg]" $ puts "\tanyarg for help\n"; case argc of - 1 = - printf "%s \tUTC Time in h:m:s\n" (str (secs2hms secsnow)) $ - printf "%s \tUTC Time in h:t:d:s\n" (str (secs2htds (secsnow-1)))$ + 1 = + printf "%s \tToday's Gregorian Date\n"(str(date(mday2jday(int daytoday))))$ + printf "%s \tUTC Time in h:m:s\n" (str (secs2hms secsnow)) $ + printf "%s \tUTC Time in h:t:d:s\n" (str (secs2htds secsnow))$ printf "%7.4f %% \tFullness of the Moon\n" (fullmoon posixsecsnow) $ printf "%d \tMayan day number\n" (int daytoday) $ printf "%s \tMayan long count notation for this day\n" (str mayantoday) $ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-07-06 00:19:58
|
Revision: 394 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=394&view=rev Author: agraef Date: 2008-07-05 17:20:07 -0700 (Sat, 05 Jul 2008) Log Message: ----------- Turn system constants into real constant definitions. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/runtime.cc Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-07-05 23:50:12 UTC (rev 393) +++ pure/trunk/ChangeLog 2008-07-06 00:20:07 UTC (rev 394) @@ -1,5 +1,8 @@ 2008-07-06 Albert Graef <Dr....@t-...> + * runtime.cc (pure_sys_vars): Turn system constants into real + constant definitions. + * runtime.cc/h, lib/system.pure: Added a few time functions to the system interface. Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-07-05 23:50:12 UTC (rev 393) +++ pure/trunk/runtime.cc 2008-07-06 00:20:07 UTC (rev 394) @@ -2722,56 +2722,75 @@ return x; } +static inline void +df(interpreter& interp, const char* s, pure_expr *x) +{ + try { + interp.defn(s, x); + } catch (err &e) { + cerr << "warning: " << e.what() << endl; + } +} + +static inline void +cdf(interpreter& interp, const char* s, pure_expr *x) +{ + try { + interp.const_defn(s, x); + } catch (err &e) { + cerr << "warning: " << e.what() << endl; + } +} + extern "C" void pure_sys_vars(void) { interpreter& interp = *interpreter::g_interp; // standard I/O streams - interp.defn("stdin", pure_pointer(stdin)); - interp.defn("stdout", pure_pointer(stdout)); - interp.defn("stderr", pure_pointer(stderr)); + df(interp, "stdin", pure_pointer(stdin)); + df(interp, "stdout", pure_pointer(stdout)); + df(interp, "stderr", pure_pointer(stderr)); // clock - interp.defn("CLOCKS_PER_SEC", pure_int(CLOCKS_PER_SEC)); + cdf(interp, "CLOCKS_PER_SEC", pure_int(CLOCKS_PER_SEC)); // fnmatch, glob - interp.defn("FNM_NOESCAPE", pure_int(FNM_NOESCAPE)); - interp.defn("FNM_PATHNAME", pure_int(FNM_PATHNAME)); - interp.defn("FNM_PERIOD", pure_int(FNM_PERIOD)); - interp.defn("FNM_CASEFOLD", pure_int(FNM_CASEFOLD)); - interp.defn("GLOB_SIZE", pure_int(sizeof(glob_t))); // not in POSIX - interp.defn("GLOB_ERR", pure_int(GLOB_ERR)); - interp.defn("GLOB_MARK", pure_int(GLOB_MARK)); - interp.defn("GLOB_NOSORT", pure_int(GLOB_NOSORT)); - interp.defn("GLOB_NOCHECK", pure_int(GLOB_NOCHECK)); - interp.defn("GLOB_NOESCAPE", pure_int(GLOB_NOESCAPE)); + cdf(interp, "FNM_NOESCAPE", pure_int(FNM_NOESCAPE)); + cdf(interp, "FNM_PATHNAME", pure_int(FNM_PATHNAME)); + cdf(interp, "FNM_PERIOD", pure_int(FNM_PERIOD)); + cdf(interp, "FNM_CASEFOLD", pure_int(FNM_CASEFOLD)); + cdf(interp, "GLOB_SIZE", pure_int(sizeof(glob_t))); // not in POSIX + cdf(interp, "GLOB_ERR", pure_int(GLOB_ERR)); + cdf(interp, "GLOB_MARK", pure_int(GLOB_MARK)); + cdf(interp, "GLOB_NOSORT", pure_int(GLOB_NOSORT)); + cdf(interp, "GLOB_NOCHECK", pure_int(GLOB_NOCHECK)); + cdf(interp, "GLOB_NOESCAPE", pure_int(GLOB_NOESCAPE)); #ifndef __APPLE__ - interp.defn("GLOB_PERIOD", pure_int(GLOB_PERIOD)); - interp.defn("GLOB_ONLYDIR", pure_int(GLOB_ONLYDIR)); + cdf(interp, "GLOB_PERIOD", pure_int(GLOB_PERIOD)); + cdf(interp, "GLOB_ONLYDIR", pure_int(GLOB_ONLYDIR)); #endif - interp.defn("GLOB_BRACE", pure_int(GLOB_BRACE)); - interp.defn("GLOB_NOMAGIC", pure_int(GLOB_NOMAGIC)); - interp.defn("GLOB_TILDE", pure_int(GLOB_TILDE)); + cdf(interp, "GLOB_BRACE", pure_int(GLOB_BRACE)); + cdf(interp, "GLOB_NOMAGIC", pure_int(GLOB_NOMAGIC)); + cdf(interp, "GLOB_TILDE", pure_int(GLOB_TILDE)); // regex stuff - interp.defn("REG_SIZE", pure_int(sizeof(regex_t))); // not in POSIX - interp.defn("REG_EXTENDED", pure_int(REG_EXTENDED)); - interp.defn("REG_ICASE", pure_int(REG_ICASE)); - interp.defn("REG_NOSUB", pure_int(REG_NOSUB)); - interp.defn("REG_NEWLINE", pure_int(REG_NEWLINE)); - interp.defn("REG_NOTBOL", pure_int(REG_NOTBOL)); - interp.defn("REG_NOTEOL", pure_int(REG_NOTEOL)); + cdf(interp, "REG_SIZE", pure_int(sizeof(regex_t))); // not in POSIX + cdf(interp, "REG_EXTENDED", pure_int(REG_EXTENDED)); + cdf(interp, "REG_ICASE", pure_int(REG_ICASE)); + cdf(interp, "REG_NOSUB", pure_int(REG_NOSUB)); + cdf(interp, "REG_NEWLINE", pure_int(REG_NEWLINE)); + cdf(interp, "REG_NOTBOL", pure_int(REG_NOTBOL)); + cdf(interp, "REG_NOTEOL", pure_int(REG_NOTEOL)); // regcomp error codes - interp.defn("REG_BADBR", pure_int(REG_BADBR)); - interp.defn("REG_BADPAT", pure_int(REG_BADPAT)); - interp.defn("REG_BADRPT", pure_int(REG_BADRPT)); - interp.defn("REG_ECOLLATE", pure_int(REG_ECOLLATE)); - interp.defn("REG_ECTYPE", pure_int(REG_ECTYPE)); - interp.defn("REG_EESCAPE", pure_int(REG_EESCAPE)); - interp.defn("REG_ESUBREG", pure_int(REG_ESUBREG)); - interp.defn("REG_EBRACK", pure_int(REG_EBRACK)); - interp.defn("REG_EPAREN", pure_int(REG_EPAREN)); - interp.defn("REG_EBRACE", pure_int(REG_EBRACE)); - interp.defn("REG_ERANGE", pure_int(REG_ERANGE)); - interp.defn("REG_ESPACE", pure_int(REG_ESPACE)); + cdf(interp, "REG_BADBR", pure_int(REG_BADBR)); + cdf(interp, "REG_BADPAT", pure_int(REG_BADPAT)); + cdf(interp, "REG_BADRPT", pure_int(REG_BADRPT)); + cdf(interp, "REG_ECOLLATE", pure_int(REG_ECOLLATE)); + cdf(interp, "REG_ECTYPE", pure_int(REG_ECTYPE)); + cdf(interp, "REG_EESCAPE", pure_int(REG_EESCAPE)); + cdf(interp, "REG_ESUBREG", pure_int(REG_ESUBREG)); + cdf(interp, "REG_EBRACK", pure_int(REG_EBRACK)); + cdf(interp, "REG_EPAREN", pure_int(REG_EPAREN)); + cdf(interp, "REG_EBRACE", pure_int(REG_EBRACE)); + cdf(interp, "REG_ERANGE", pure_int(REG_ERANGE)); + cdf(interp, "REG_ESPACE", pure_int(REG_ESPACE)); // regexec error codes - interp.defn("REG_NOMATCH", pure_int(REG_NOMATCH)); - interp.defn("REG_ESPACE", pure_int(REG_ESPACE)); + cdf(interp, "REG_NOMATCH", pure_int(REG_NOMATCH)); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-07-05 23:50:03
|
Revision: 393 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=393&view=rev Author: agraef Date: 2008-07-05 16:50:12 -0700 (Sat, 05 Jul 2008) Log Message: ----------- Add time functions to system interface. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/config.h.in pure/trunk/configure pure/trunk/configure.ac pure/trunk/lib/system.pure pure/trunk/runtime.cc pure/trunk/runtime.h Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-07-05 21:49:42 UTC (rev 392) +++ pure/trunk/ChangeLog 2008-07-05 23:50:12 UTC (rev 393) @@ -1,3 +1,8 @@ +2008-07-06 Albert Graef <Dr....@t-...> + + * runtime.cc/h, lib/system.pure: Added a few time functions to the + system interface. + 2008-07-03 Albert Graef <Dr....@t-...> * interpreter.cc (run): Temporarily suppress verbose output for Modified: pure/trunk/config.h.in =================================================================== --- pure/trunk/config.h.in 2008-07-05 21:49:42 UTC (rev 392) +++ pure/trunk/config.h.in 2008-07-05 23:50:12 UTC (rev 393) @@ -15,6 +15,12 @@ */ #undef HAVE_ALLOCA_H +/* Define to 1 if you have the `ftime' function. */ +#undef HAVE_FTIME + +/* Define to 1 if you have the `gettimeofday' function. */ +#undef HAVE_GETTIMEOFDAY + /* Define if you have the iconv() function. */ #undef HAVE_ICONV @@ -42,6 +48,9 @@ /* Define to 1 if you have the <memory.h> header file. */ #undef HAVE_MEMORY_H +/* Define to 1 if you have the `nanosleep' function. */ +#undef HAVE_NANOSLEEP + /* Define to 1 if you have the <stdint.h> header file. */ #undef HAVE_STDINT_H @@ -63,6 +72,9 @@ /* Define to 1 if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H +/* Define to 1 if you have the `usleep' function. */ +#undef HAVE_USLEEP + /* Define to the name of the host system. */ #undef HOST Modified: pure/trunk/configure =================================================================== --- pure/trunk/configure 2008-07-05 21:49:42 UTC (rev 392) +++ pure/trunk/configure 2008-07-05 23:50:12 UTC (rev 393) @@ -5366,6 +5366,103 @@ fi + + + + +for ac_func in ftime gettimeofday nanosleep usleep +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func. + For example, HP-UX 11i <limits.h> declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer <limits.h> to <assert.h> if __STDC__ is defined, since + <limits.h> exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include <limits.h> +#else +# include <assert.h> +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + ac_config_files="$ac_config_files Makefile" cat >confcache <<\_ACEOF Modified: pure/trunk/configure.ac =================================================================== --- pure/trunk/configure.ac 2008-07-05 21:49:42 UTC (rev 392) +++ pure/trunk/configure.ac 2008-07-05 23:50:12 UTC (rev 393) @@ -85,6 +85,8 @@ AM_LANGINFO_CODESET dnl Determine how to get alloca. AC_FUNC_ALLOCA +dnl Platform-dependent time functions. +AC_CHECK_FUNCS(ftime gettimeofday nanosleep usleep) AC_CONFIG_FILES([Makefile]) AC_OUTPUT Modified: pure/trunk/lib/system.pure =================================================================== --- pure/trunk/lib/system.pure 2008-07-05 21:49:42 UTC (rev 392) +++ pure/trunk/lib/system.pure 2008-07-05 23:50:12 UTC (rev 393) @@ -47,6 +47,48 @@ errno = pure_errno; set_errno val::int = pure_set_errno val; +/* Time functions. 'time' reports the current time in seconds since the + "epoch" a.k.a. 00:00:00 UTC, Jan 1 1970. The result is always a bigint (in + fact, the time value is already 64 bit on many OSes nowadays). The ctime + and gmtime functions convert a time value to a string in either local time + or UTC. (Note that the latter is actually a combination of the C gmtime() + and asctime() functions.) */ + +extern long pure_time() = time; +extern char* pure_ctime(long) = ctime; +extern char* pure_gmtime(long) = gmtime; + +/* The gettimeofday function also returns wallclock time as seconds since the + epoch, but theoretically offers resolutions in the microsec range (actual + resolutions vary, but are usually in the msec range for contemporary + systems). The result is returned as a double value (which also limits + precision). This function may actually be implemented through different + system calls, depending on what's available on the host OS. */ + +extern double pure_gettimeofday() = gettimeofday; + +/* The clock function returns the current CPU (not wallclock) time since an + arbitrary point in the past, as a machine int. The number of "ticks" per + second is given by the CLOCKS_PER_SEC constant. Note that this value will + wrap around approximately every 72 minutes. */ + +extern int clock(); + +/* The sleep and nanosleep functions suspend execution for a given time + interval in seconds. 'sleep' takes integer (int/bigint) arguments only and + uses the sleep() system function. 'nanosleep' also accepts double arguments + and theoretically supports resolutions down to 1 nanosecond (again, actual + resolutions vary). This function may actually be implemented through + different system calls, depending on what's available on the host OS. Both + functions usually return zero, unless the sleep was interrupted by a + signal, in which case the time remaining to be slept is returned. */ + +extern int sleep(int); +extern double pure_nanosleep(double) = nanosleep; + +sleep t::bigint = sleep (int t); +nanosleep t::int | nanosleep t::bigint = nanosleep (double t); + /* Basic process operations: system executes a shell command, exit terminates the program with the given status code. */ Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-07-05 21:49:42 UTC (rev 392) +++ pure/trunk/runtime.cc 2008-07-05 23:50:12 UTC (rev 393) @@ -25,6 +25,7 @@ #include <readline/history.h> #include <stdlib.h> #include <stdarg.h> +#include <unistd.h> #include <iostream> #include <sstream> @@ -2340,7 +2341,112 @@ errno = value; } +#include <time.h> + +extern "C" +int64_t pure_time(void) +{ + return (int64_t)time(NULL); +} + +extern "C" +char *pure_ctime(int64_t t) +{ + time_t time = (time_t)t; + return ctime(&time); +} + +extern "C" +char *pure_gmtime(int64_t t) +{ + time_t time = (time_t)t; + return asctime(gmtime(&time)); +} + +#ifdef HAVE_GETTIMEOFDAY +#include <sys/time.h> +extern "C" +double pure_gettimeofday(void) +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return ((double)tv.tv_sec)+((double)tv.tv_usec)*1e-6; +} +#else +#ifdef HAVE_FTIME +#include <sys/timeb.h> +extern "C" +double pure_gettimeofday(void) +{ + struct timeb tb; + ftime(&tb); + return ((double)tb.time)+((double)tb.millitm)*1e-3; +} +#else +extern "C" +double pure_gettimeofday(void) +{ + return (double)time(NULL); +} +#endif +#endif + #ifdef __MINGW32__ +#include <windows.h> +double pure_nanosleep(double t) +{ + if (t > 0.0) { + unsigned long secs; + unsigned short msecs; + double ip, fp; + if (t > LONG_MAX) t = LONG_MAX; + fp = modf(t, &ip); + secs = (unsigned long)ip; + msecs = (unsigned short)(fp*1e3); + Sleep(secs*1000U+msecs); + } + return 0.0; +} +#else +double pure_nanosleep(double t) +{ + if (t > 0.0) { + double ip, fp; + unsigned long secs; +#ifdef HAVE_NANOSLEEP + unsigned long nsecs; + struct timespec req, rem; + fp = modf(t, &ip); + if (ip > LONG_MAX) { ip = (double)LONG_MAX; fp = 0.0; } + secs = (unsigned long)ip; + nsecs = (unsigned long)(fp*1e9); + req.tv_sec = secs; req.tv_nsec = nsecs; + if (nanosleep(&req, &rem)) + return ((double)rem.tv_sec)+((double)rem.tv_nsec)*1e-9; + else + return 0.0; +#else +#ifdef HAVE_USLEEP + unsigned long usecs; + if (t > LONG_MAX) t = LONG_MAX; + fp = modf(t, &ip); + secs = (unsigned long)ip; + usecs = (unsigned long)(fp*1e6); + usleep(secs*1000000U+usecs); + return 0.0; +#else + fp = modf(t, &ip); + if (ip > LONG_MAX) ip = (double)LONG_MAX; + secs = (unsigned long)ip; + return (double)sleep(secs); +#endif +#endif + } else + return 0.0; +} +#endif + +#ifdef __MINGW32__ extern "C" FILE *popen(const char *command, const char *type) { @@ -2621,9 +2727,11 @@ { interpreter& interp = *interpreter::g_interp; // standard I/O streams - interp.defn("stdin", pure_pointer(stdin)); + interp.defn("stdin", pure_pointer(stdin)); interp.defn("stdout", pure_pointer(stdout)); interp.defn("stderr", pure_pointer(stderr)); + // clock + interp.defn("CLOCKS_PER_SEC", pure_int(CLOCKS_PER_SEC)); // fnmatch, glob interp.defn("FNM_NOESCAPE", pure_int(FNM_NOESCAPE)); interp.defn("FNM_PATHNAME", pure_int(FNM_PATHNAME)); Modified: pure/trunk/runtime.h =================================================================== --- pure/trunk/runtime.h 2008-07-05 21:49:42 UTC (rev 392) +++ pure/trunk/runtime.h 2008-07-05 23:50:12 UTC (rev 393) @@ -546,6 +546,26 @@ int pure_errno(void); void pure_set_errno(int value); +/* time() function. We provide an interface to this routine to account for + platform incompatibilities. The result is always int64_t, as time_t + nowadays is a 64 bit type on many OSes. We also provide wrappers for + ctime() and gmtime() which convert a time value to a string, using either + local or UTC time. */ + +int64_t pure_time(void); +char *pure_ctime(int64_t t); +char *pure_gmtime(int64_t t); + +/* gettimeofday() interface. This may actually be implemented using different + system functions, depending on what's available on the host OS. */ + +double pure_gettimeofday(void); + +/* nanosleep() interface. This may actually be implemented using different + system functions, depending on what's available on the host OS. */ + +double pure_nanosleep(double t); + #ifdef __MINGW32__ /* Windows compatibility. */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ye...@us...> - 2008-07-05 21:49:37
|
Revision: 392 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=392&view=rev Author: yes Date: 2008-07-05 14:49:42 -0700 (Sat, 05 Jul 2008) Log Message: ----------- fixed a portability issue with external time declaration Modified Paths: -------------- pure/trunk/examples/libor/date.pure Modified: pure/trunk/examples/libor/date.pure =================================================================== --- pure/trunk/examples/libor/date.pure 2008-07-05 20:01:33 UTC (rev 391) +++ pure/trunk/examples/libor/date.pure 2008-07-05 21:49:42 UTC (rev 392) @@ -8,7 +8,7 @@ (Temps Atomique International) rather than local daylight saving time */ using system; // this is needed just to get C printf -extern int time(); // makes available the C function time(); +extern int time(int*) = c_time; // makes available the C function time(); puts "****************************************************************"; puts "* New Calendar/Clock, Copyright (c) 2008 by Libor Spacek *"; @@ -16,14 +16,14 @@ def posixepoch = (12:17:16:7:5); // Mayan long count date of the posix epoch def endofcycle = (13:0:0:0:0); // The end of the cycle def secsinday = 86400; // number of seconds in a day -def trueyear = 31556941;// (in seconds) divisible by 13 = current true year -def myyear = 31556943;// div by 2277, secsinday compatible, 365.2424 days -def gregyear = 31556952;// div by 40824, mean gregorian year, 365.2425 days +def trueyear = 31556941;// (in seconds) divisible by 13 = current true year +def myyear = 31556943;// div by 2277, secsinday compatible, 365.2424 days +def gregyear = 31556952;// div by 40824, mean gregorian year, 365.2425 days def lunarmonth = 2551443; // lunar (synodic) month to the nearest second -def newmoondhms = (14063:2:19:0); // 3rd July 08 new moon in posix dhms +def newmoondhms= (14063:2:19:0); // 3rd July 08 new moon in posix dhms // current values in posix time supplied by C time(); -posixsecsnow = time; // int - each new call refreshes to the current second +posixsecsnow = c_time (pointer 0); // each call refreshes to the current second secsnow = posixsecsnow mod secsinday; // int seconds since midnight // first some simple conversions @@ -113,7 +113,7 @@ percentcomplete = 100.0*(epochday+posixsecsnow/secsinday)/cycledays; usage = puts "Usage: pure -x date.pure [anyarg]" $ - puts "\tanyarg for help"; + puts "\tanyarg for help\n"; case argc of 1 = @@ -129,13 +129,13 @@ percentcomplete $ puts "****************************************************************"; 2 = - puts "Mayan long count digits (and their range of values):" $ + puts "Mayan long count digits and their ranges of values:" $ puts "Baktun(0-12) : Katun(0-19) : Tun(0-19) : Vinal(0-17) : Kin(0-19)" $ puts "Baktun=144000days Katun=7200days Tun=360days Vinal=20days Kin=day" $ - puts "\nNew clock digits (and their range of values):" $ - puts "Hour(0-23) : Tre(0-19) : Dici(0-17) : Sec(0-9)" $ - puts "Hour=3600secs Tre=180secs Dici=10secs Sec=second\n" $ - puts "Complete time count: Baktun:Katun:Tun:Vinal:Kin,Hour:Tre:Dici:Sec\n" $ + puts "\nNew clock digits and their ranges of values:" $ + puts "hour(0-23) : tre(0-19) : dici(0-17) : second(0-9)" $ + puts "hour=3600s : tre=180s : dici=10s : s=second\n" $ + puts "Full time spec: Baktun:Katun:Tun:Vinal:Kin hour:tre:dici:second\n" $ usage; n = usage end; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ye...@us...> - 2008-07-05 20:01:23
|
Revision: 391 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=391&view=rev Author: yes Date: 2008-07-05 13:01:33 -0700 (Sat, 05 Jul 2008) Log Message: ----------- stylistic improvements and simplification to integral seconds Modified Paths: -------------- pure/trunk/examples/libor/date.pure Modified: pure/trunk/examples/libor/date.pure =================================================================== --- pure/trunk/examples/libor/date.pure 2008-07-05 09:38:36 UTC (rev 390) +++ pure/trunk/examples/libor/date.pure 2008-07-05 20:01:33 UTC (rev 391) @@ -14,26 +14,23 @@ puts "* New Calendar/Clock, Copyright (c) 2008 by Libor Spacek *"; puts "****************************************************************"; def posixepoch = (12:17:16:7:5); // Mayan long count date of the posix epoch -def epochday = mayan2days posixepoch; // (mayan) day of the posix epoch def endofcycle = (13:0:0:0:0); // The end of the cycle -def cycledays = mayan2days endofcycle; // total days in 13 Baktuns -def secsinday = 86400.0; // number of seconds in a day +def secsinday = 86400; // number of seconds in a day def trueyear = 31556941;// (in seconds) divisible by 13 = current true year def myyear = 31556943;// div by 2277, secsinday compatible, 365.2424 days def gregyear = 31556952;// div by 40824, mean gregorian year, 365.2425 days def lunarmonth = 2551443; // lunar (synodic) month to the nearest second -def newmoonsecs = dhms2secs(14063:2:19:0); // 3rd July 08 new moon in posix +def newmoondhms = (14063:2:19:0); // 3rd July 08 new moon in posix dhms // current values in posix time supplied by C time(); posixsecsnow = time; // int - each new call refreshes to the current second -secsnow = posixsecsnow mod (int secsinday); // int seconds since midnight -moonphase = 100.0*((posixsecsnow-newmoonsecs) mod lunarmonth)/lunarmonth; +secsnow = posixsecsnow mod secsinday; // int seconds since midnight // first some simple conversions secs2days s::int | secs2days s::bigint | secs2days s::double = (s / secsinday); -days2secs d::int = secsinday * d; -days2hours d::int = 24*d; -hours2days h::int = h div 24; +days2secs d::int | days2secs d::bigint | deys2secs d::double = secsinday * d; +days2hours d::int| days2hours d::bigint| days2hours d::double= 24*d; +hours2days h::int = h / 24; // conversions from/to days:hours:minutes:seconds format // seconds can be int or bigint or double. d,h,m are ints @@ -98,35 +95,47 @@ mayan2days (baktun::int:katun::int:tun::int:vinal::int:kin::int) = 20*(18*(20*(20*baktun+katun)+tun)+vinal)+kin; + +// moon calculations +moonphase psecs::int=((psecs-(dhms2secs newmoondhms))mod lunarmonth)/lunarmonth; +// full moon percentage at psecs posix seconds +fullmoon psecs::int = if mf > 0.5 then 200.0*(1.0-mf) else 200.0*mf + when mf = moonphase psecs end; // for now, let's just do some simple calculations to print +def epochday = mayan2days posixepoch; // (mayan) day of the posix epoch +def cycledays = mayan2days endofcycle; // total days in 13 Baktuns daytoday = epochday + (secs2days posixsecsnow); // mayan whole day count mayantoday = days2mayan (int daytoday); // as above but in the long count format -daysleft = cycledays - epochday - (secs2days (double posixsecsnow)); // double +daysleft = cycledays-epochday-(secs2days (double posixsecsnow)); // double mayanleft = days2mayan ((int daysleft)); -timeleft = secs2htds ((int secsinday) - secsnow); +timeleft = secs2htds (secsinday - secsnow); percentcomplete = 100.0*(epochday+posixsecsnow/secsinday)/cycledays; usage = puts "Usage: pure -x date.pure [anyarg]" $ puts "\tanyarg for help"; case argc of - 1 = void (printf "\t\tThe moonphase now is: %7.4f%%\n" moonphase) $ - void (printf "Mayan day %d + UTC Time %s = %s,%s\n" ((int daytoday), - (str (secs2hms secsnow)),(str mayantoday),(str (secs2htds secsnow))))$ - void (printf "Long countdown: %f days left = %s,%s\n" - (daysleft, (str mayanleft), (str timeleft))) $ - void (printf "The Mayan cycle of over 5125 years is now %11.8f%% complete\n" - percentcomplete ) $ - void (puts"****************************************************************"); + 1 = + printf "%s \tUTC Time in h:m:s\n" (str (secs2hms secsnow)) $ + printf "%s \tUTC Time in h:t:d:s\n" (str (secs2htds (secsnow-1)))$ + printf "%7.4f %% \tFullness of the Moon\n" (fullmoon posixsecsnow) $ + printf "%d \tMayan day number\n" (int daytoday) $ + printf "%s \tMayan long count notation for this day\n" (str mayantoday) $ + printf "%s \tLong countdown of days to the end of this cycle\n" + (str mayanleft) $ + printf "%s \tTime (h:t:d:s) countdown of today\n" (str timeleft) $ + printf "%11.8f %%\tCompletion of the Mayan cycle of over 5125 years\n" + percentcomplete $ + puts "****************************************************************"; 2 = - void(puts "Mayan long count digits (and their range of values):") $ - void(puts "Baktun(0-12) : Katun(0-19) : Tun(0-19) : Vinal(0-17) : Kin(0-19)")$ - puts "Baktun=144000days Katun=7200days Tun=360days Vinal=20days Kin=day"$ - void (puts "\nNew clock digits (and their range of values):") $ - void (puts "Hour(0-23) : Tre(0-19) : Dici(0-17) : Sec(0-9)")$ - puts "Hour=3600secs Tre=180secs Dici=10secs Sec=second\n"$ - puts "Complete time count: Baktun:Katun:Tun:Vinal:Kin,Hour:Tre:Dici:Sec\n" $ - usage; - n = usage otherwise + puts "Mayan long count digits (and their range of values):" $ + puts "Baktun(0-12) : Katun(0-19) : Tun(0-19) : Vinal(0-17) : Kin(0-19)" $ + puts "Baktun=144000days Katun=7200days Tun=360days Vinal=20days Kin=day" $ + puts "\nNew clock digits (and their range of values):" $ + puts "Hour(0-23) : Tre(0-19) : Dici(0-17) : Sec(0-9)" $ + puts "Hour=3600secs Tre=180secs Dici=10secs Sec=second\n" $ + puts "Complete time count: Baktun:Katun:Tun:Vinal:Kin,Hour:Tre:Dici:Sec\n" $ + usage; + n = usage end; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <js...@us...> - 2008-07-05 09:38:28
|
Revision: 390 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=390&view=rev Author: jspitz Date: 2008-07-05 02:38:36 -0700 (Sat, 05 Jul 2008) Log Message: ----------- Add type annotations to variables. Modified Paths: -------------- pure/trunk/examples/array.pure Modified: pure/trunk/examples/array.pure =================================================================== --- pure/trunk/examples/array.pure 2008-07-05 07:34:02 UTC (rev 389) +++ pure/trunk/examples/array.pure 2008-07-05 09:38:36 UTC (rev 390) @@ -171,7 +171,8 @@ update (Array a) i::int y = Array (update a i y) with update (tip _) 0 y = tip y; - update (bin b a1 a2) i::int y = bin b (update a1 (i div 2) y) a2 + update (bin b::int a1 a2) i::int y + = bin b (update a1 (i div 2) y) a2 if i mod 2 == 0; = bin b a1 (update a2 (i div 2) y) if i mod 2 == 1; @@ -192,7 +193,7 @@ eq (tip _) (bin _ _ _) = 0; eq (bin _ _ _) nil = 0; eq (bin _ _ _) (tip _) = 0; - eq (bin b1 a1 a2) (bin b2 a3 a4) + eq (bin b1::int a1 a2) (bin b2::int a3 a4) = b1 == b2 && eq a1 a3 && eq a2 a4; end; @@ -207,7 +208,7 @@ neq (tip _) (bin _ _ _) = 1; neq (bin _ _ _) nil = 1; neq (bin _ _ _) (tip _) = 1; - neq (bin b1 a1 a2) (bin b2 a3 a4) + neq (bin b1::int a1 a2) (bin b2::int a3 a4) = b1 != b2 || neq a1 a3 || neq a2 a4; end; @@ -216,4 +217,4 @@ // construct a binary array node array_mkbin _ nil a2 = a2; array_mkbin _ a1 nil = a1; -array_mkbin b a1 a2 = bin b a1 a2; +array_mkbin b::int a1 a2 = bin b a1 a2; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <js...@us...> - 2008-07-05 07:33:57
|
Revision: 389 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=389&view=rev Author: jspitz Date: 2008-07-05 00:34:02 -0700 (Sat, 05 Jul 2008) Log Message: ----------- Bugfix of equality and inequality checks (locally hidden == and !=) Modified Paths: -------------- pure/trunk/examples/array.pure Modified: pure/trunk/examples/array.pure =================================================================== --- pure/trunk/examples/array.pure 2008-07-04 23:40:43 UTC (rev 388) +++ pure/trunk/examples/array.pure 2008-07-05 07:34:02 UTC (rev 389) @@ -182,31 +182,33 @@ = update x i (update (x!i) j y); // compare two arrays for equality -Array a == Array b = a == b +Array a == Array b = eq a b with - nil == nil = 1; - nil == tip _ = 0; - nil == bin _ _ _ = 0; - tip _ == nil = 0; - tip x == tip y = x == y; - tip _ == bin _ _ _ = 0; - bin _ _ _ == nil = 0; - bin _ _ _ == tip _ = 0; - bin b1 a1 a2 == bin b2 a3 a4 = b1 == b2 && a1 == a3 && a2 == a4; + eq nil nil = 1; + eq nil (tip _) = 0; + eq nil (bin _ _ _) = 0; + eq (tip _) nil = 0; + eq (tip x) (tip y) = x == y; + eq (tip _) (bin _ _ _) = 0; + eq (bin _ _ _) nil = 0; + eq (bin _ _ _) (tip _) = 0; + eq (bin b1 a1 a2) (bin b2 a3 a4) + = b1 == b2 && eq a1 a3 && eq a2 a4; end; // compare two arrays for inequality -Array a != Array b = a != b +Array a != Array b = neq a b with - nil != nil = 0; - nil != tip _ = 1; - nil != bin _ _ _ = 1; - tip _ != nil = 1; - tip x != tip y = x != y; - tip _ != bin _ _ _ = 1; - bin _ _ _ != nil = 1; - bin _ _ _ != tip _ = 1; - bin b1 a1 a2 != bin b2 a3 a4 = b1 != b2 || a1 != a3 || a2 != a4; + neq nil nil = 0; + neq nil (tip _) = 1; + neq nil (bin _ _ _) = 1; + neq (tip _) nil = 1; + neq (tip x) (tip y) = x != y; + neq (tip _) (bin _ _ _) = 1; + neq (bin _ _ _) nil = 1; + neq (bin _ _ _) (tip _) = 1; + neq (bin b1 a1 a2) (bin b2 a3 a4) + = b1 != b2 || neq a1 a3 || neq a2 a4; end; /* Private functions, don't invoke these directly. */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ye...@us...> - 2008-07-04 23:40:35
|
Revision: 388 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=388&view=rev Author: yes Date: 2008-07-04 16:40:43 -0700 (Fri, 04 Jul 2008) Log Message: ----------- minor fixes Modified Paths: -------------- pure/trunk/examples/libor/date.pure Modified: pure/trunk/examples/libor/date.pure =================================================================== --- pure/trunk/examples/libor/date.pure 2008-07-04 22:40:45 UTC (rev 387) +++ pure/trunk/examples/libor/date.pure 2008-07-04 23:40:43 UTC (rev 388) @@ -22,15 +22,15 @@ def myyear = 31556943;// div by 2277, secsinday compatible, 365.2424 days def gregyear = 31556952;// div by 40824, mean gregorian year, 365.2425 days def lunarmonth = 2551443; // lunar (synodic) month to the nearest second -def newmoonsecs = dhms2secs(14063:2:19:0); // 3/July/08 in posix +def newmoonsecs = dhms2secs(14063:2:19:0); // 3rd July 08 new moon in posix -// current posix time supplied by C time(); +// current values in posix time supplied by C time(); posixsecsnow = time; // int - each new call refreshes to the current second secsnow = posixsecsnow mod (int secsinday); // int seconds since midnight +moonphase = 100.0*((posixsecsnow-newmoonsecs) mod lunarmonth)/lunarmonth; // first some simple conversions -secs2days s::int | secs2days s::bigint = (s div (int secsinday)); -secs2days s::double = ( s / secsinday ); // this returns double days +secs2days s::int | secs2days s::bigint | secs2days s::double = (s / secsinday); days2secs d::int = secsinday * d; days2hours d::int = 24*d; hours2days h::int = h div 24; @@ -39,7 +39,8 @@ // seconds can be int or bigint or double. d,h,m are ints dhms2secs (d::int:h::int:m::int:s::int) | dhms2secs (d::int:h::int:m::int:s::bigint) | -dhms2secs (d::int:h::int:m::int:s::double) = 60.0*(60*(24*d+h)+m)+s; +dhms2secs (d::int:h::int:m::int:s::double) = 60*(60*(24*d+h)+m)+s; + secs2dhms secs::int | secs2dhms secs::bigint | secs2dhms secs::double = d:(h mod 24):(m mod 60):(secs-60*m) when @@ -47,6 +48,7 @@ h::int = m div 60; d::int = h div 24 end; + // an arbitrary binary operator applied to two (days:hours:minutes:seconds) opdhms op (d1::int:h1::int:m1::int:s1)(d2::int:h2::int:m2::int:s2) = secs2dhms (op (dhms2secs (d1:h1:m1:s1)) (dhms2secs (d2:h2:m2:s2))); @@ -55,7 +57,8 @@ // hours may be more than 24 but use d:h:m:s for longer periods of time hms2secs (h::int:m::int:s::int) | hms2secs (h::int:m::int:s::bigint) | -hms2secs (h::int:m::int:s::double) = 60.0*(60*h+m)+s; +hms2secs (h::int:m::int:s::double) = 60*(60*h+m)+s; + secs2hms secs::int | secs2hms secs::bigint | secs2hms secs::double = h:(m mod 60):(secs-60*m) when @@ -68,7 +71,8 @@ // dicis:secs are easy to read: 6:0 means 60 seconds, 12:5 125 seconds etc. // tres - multiply by three to get traditional babylonian minutes // hours as usual (24 hour clock) -htds2secs (h::int:t::int:d::int:s::int) = 10.0*(18*(20*h+t)+d)+s; +htds2secs (h::int:t::int:d::int:s::int) = 10*(18*(20*h+t)+d)+s; + secs2htds secs::int | secs2htds secs::bigint | secs2htds secs::double = h:(t mod 20):(d mod 18):(secs-10*d) when @@ -97,26 +101,23 @@ // for now, let's just do some simple calculations to print daytoday = epochday + (secs2days posixsecsnow); // mayan whole day count -mayantoday = days2mayan daytoday; // as above but in mayan long count format +mayantoday = days2mayan (int daytoday); // as above but in the long count format daysleft = cycledays - epochday - (secs2days (double posixsecsnow)); // double mayanleft = days2mayan ((int daysleft)); timeleft = secs2htds ((int secsinday) - secsnow); percentcomplete = 100.0*(epochday+posixsecsnow/secsinday)/cycledays; - -moonphase = 100.0*((int (posixsecsnow-newmoonsecs)) mod lunarmonth)/lunarmonth; usage = puts "Usage: pure -x date.pure [anyarg]" $ puts "\tanyarg for help"; case argc of - 1 = - void (printf "Mayan day %d + UTC Time %s = %s,%s\n" (daytoday, + 1 = void (printf "\t\tThe moonphase now is: %7.4f%%\n" moonphase) $ + void (printf "Mayan day %d + UTC Time %s = %s,%s\n" ((int daytoday), (str (secs2hms secsnow)),(str mayantoday),(str (secs2htds secsnow))))$ - void (printf "Long countdown %f(days left) = %s,%s\n" + void (printf "Long countdown: %f days left = %s,%s\n" (daysleft, (str mayanleft), (str timeleft))) $ void (printf "The Mayan cycle of over 5125 years is now %11.8f%% complete\n" percentcomplete ) $ - void (printf "Current Moonphase is %f%%\n" moonphase) $ void (puts"****************************************************************"); 2 = void(puts "Mayan long count digits (and their range of values):") $ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ye...@us...> - 2008-07-04 22:40:36
|
Revision: 387 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=387&view=rev Author: yes Date: 2008-07-04 15:40:45 -0700 (Fri, 04 Jul 2008) Log Message: ----------- Added Moonphase to date.pure Modified Paths: -------------- pure/trunk/examples/libor/date.pure Modified: pure/trunk/examples/libor/date.pure =================================================================== --- pure/trunk/examples/libor/date.pure 2008-07-04 21:27:31 UTC (rev 386) +++ pure/trunk/examples/libor/date.pure 2008-07-04 22:40:45 UTC (rev 387) @@ -18,17 +18,19 @@ def endofcycle = (13:0:0:0:0); // The end of the cycle def cycledays = mayan2days endofcycle; // total days in 13 Baktuns def secsinday = 86400.0; // number of seconds in a day -def trueyear = 31556941.0;// (in seconds) divisible by 13 = current true year -def myyear = 31556943.0;// div by 2277, secsinday compatible, 365.2424 days -def gregyear = 31556952.0;// div by 40824, mean gregorian year, 365.2425 days - +def trueyear = 31556941;// (in seconds) divisible by 13 = current true year +def myyear = 31556943;// div by 2277, secsinday compatible, 365.2424 days +def gregyear = 31556952;// div by 40824, mean gregorian year, 365.2425 days +def lunarmonth = 2551443; // lunar (synodic) month to the nearest second +def newmoonsecs = dhms2secs(14063:2:19:0); // 3/July/08 in posix + // current posix time supplied by C time(); posixsecsnow = time; // int - each new call refreshes to the current second secsnow = posixsecsnow mod (int secsinday); // int seconds since midnight // first some simple conversions -secs2days s::int | secs2days s::bigint = s div (int secsinday); -secs2days s::double = s / secsinday; // this returns double days +secs2days s::int | secs2days s::bigint = (s div (int secsinday)); +secs2days s::double = ( s / secsinday ); // this returns double days days2secs d::int = secsinday * d; days2hours d::int = 24*d; hours2days h::int = h div 24; @@ -100,6 +102,8 @@ mayanleft = days2mayan ((int daysleft)); timeleft = secs2htds ((int secsinday) - secsnow); percentcomplete = 100.0*(epochday+posixsecsnow/secsinday)/cycledays; + +moonphase = 100.0*((int (posixsecsnow-newmoonsecs)) mod lunarmonth)/lunarmonth; usage = puts "Usage: pure -x date.pure [anyarg]" $ puts "\tanyarg for help"; @@ -112,6 +116,7 @@ (daysleft, (str mayanleft), (str timeleft))) $ void (printf "The Mayan cycle of over 5125 years is now %11.8f%% complete\n" percentcomplete ) $ + void (printf "Current Moonphase is %f%%\n" moonphase) $ void (puts"****************************************************************"); 2 = void(puts "Mayan long count digits (and their range of values):") $ @@ -120,7 +125,7 @@ void (puts "\nNew clock digits (and their range of values):") $ void (puts "Hour(0-23) : Tre(0-19) : Dici(0-17) : Sec(0-9)")$ puts "Hour=3600secs Tre=180secs Dici=10secs Sec=second\n"$ - puts "Complete time count: Baktun:Katun:Tun:Vinal:Kin,Hour:Tre:Dici:Sec\n" + puts "Complete time count: Baktun:Katun:Tun:Vinal:Kin,Hour:Tre:Dici:Sec\n" $ usage; n = usage otherwise end; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ye...@us...> - 2008-07-04 21:27:22
|
Revision: 386 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=386&view=rev Author: yes Date: 2008-07-04 14:27:31 -0700 (Fri, 04 Jul 2008) Log Message: ----------- improvements to date.pure Modified Paths: -------------- pure/trunk/examples/libor/date.pure Modified: pure/trunk/examples/libor/date.pure =================================================================== --- pure/trunk/examples/libor/date.pure 2008-07-04 20:33:00 UTC (rev 385) +++ pure/trunk/examples/libor/date.pure 2008-07-04 21:27:31 UTC (rev 386) @@ -1,45 +1,79 @@ -/* Mayan Calendar - Copyright (c) 2008 by Libor Spacek +/* New Calendar and Clock + Copyright (c) 2008 by Libor Spacek Usage: pure -x date.pure [-h] Discrepancies with your local clock may occur when C library's time(); - returns Posix time based on UTC (Universel Temps Coordonné) or TAI - (Temps Atomique Internacional) rather than local daylight saving time */ + returns Posix time based on UTC (Universal Temps Coordinat) or TAI + (Temps Atomique International) rather than local daylight saving time */ -using system; -extern int time(); +using system; // this is needed just to get C printf +extern int time(); // makes available the C function time(); -puts "Mayan Calendar, Copyright (c) 2008 by Libor Spacek"; +puts "****************************************************************"; +puts "* New Calendar/Clock, Copyright (c) 2008 by Libor Spacek *"; +puts "****************************************************************"; +def posixepoch = (12:17:16:7:5); // Mayan long count date of the posix epoch +def epochday = mayan2days posixepoch; // (mayan) day of the posix epoch +def endofcycle = (13:0:0:0:0); // The end of the cycle +def cycledays = mayan2days endofcycle; // total days in 13 Baktuns +def secsinday = 86400.0; // number of seconds in a day +def trueyear = 31556941.0;// (in seconds) divisible by 13 = current true year +def myyear = 31556943.0;// div by 2277, secsinday compatible, 365.2424 days +def gregyear = 31556952.0;// div by 40824, mean gregorian year, 365.2425 days -def posixepoch = (12:17:16:7:5); // Mayan long count date of the posix epoch -def epochday = mayan2days posixepoch; // Mayan day of the posix epoch -def endofdays = 15695; // posix days at the end of the cycle (13th baktun) -def secsinday = 86400; // number of seconds in a day -def cycledays = mayan2days (13:0:0:0:0); -def year = 365.242374; -def cycleyears = cycledays / year; - -// time now in posix seconds converted to whole days -posixsecsnow = time; // call posixsecsnow to refresh the current time -posixdays = posixsecsnow div secsinday; -secsnow = posixsecsnow mod secsinday; - -// time calculations on the usual days:hours:minutes:seconds format -dhms2secs (d::int:h::int:m::int:s) = 60.0*(60*(24*d+h)+m)+s; -// secs are usually double and can be int or bigint but d,h,m are always ints -secs2dhms secs = - d:(h mod 24):(m mod 60):(secs-60.0*m) +// current posix time supplied by C time(); +posixsecsnow = time; // int - each new call refreshes to the current second +secsnow = posixsecsnow mod (int secsinday); // int seconds since midnight + +// first some simple conversions +secs2days s::int | secs2days s::bigint = s div (int secsinday); +secs2days s::double = s / secsinday; // this returns double days +days2secs d::int = secsinday * d; +days2hours d::int = 24*d; +hours2days h::int = h div 24; + +// conversions from/to days:hours:minutes:seconds format +// seconds can be int or bigint or double. d,h,m are ints +dhms2secs (d::int:h::int:m::int:s::int) | +dhms2secs (d::int:h::int:m::int:s::bigint) | +dhms2secs (d::int:h::int:m::int:s::double) = 60.0*(60*(24*d+h)+m)+s; +secs2dhms secs::int | secs2dhms secs::bigint | secs2dhms secs::double = + d:(h mod 24):(m mod 60):(secs-60*m) when m::int = int (secs / 60); h::int = m div 60; d::int = h div 24 end; - -// an arbitrary binary operator applied to two (days,hours,minutes,seconds) +// an arbitrary binary operator applied to two (days:hours:minutes:seconds) opdhms op (d1::int:h1::int:m1::int:s1)(d2::int:h2::int:m2::int:s2) = secs2dhms (op (dhms2secs (d1:h1:m1:s1)) (dhms2secs (d2:h2:m2:s2))); + +// conversions from/to hours:minutes:seconds format for displaying time of day. +// hours may be more than 24 but use d:h:m:s for longer periods of time +hms2secs (h::int:m::int:s::int) | +hms2secs (h::int:m::int:s::bigint) | +hms2secs (h::int:m::int:s::double) = 60.0*(60*h+m)+s; +secs2hms secs::int | secs2hms secs::bigint | secs2hms secs::double = + h:(m mod 60):(secs-60*m) + when + m::int = int (secs / 60); + h::int = m div 60; + end; -// Now follows the Mayan Calendar +// New Time Format! hours:3mins:10secs:secs = hours:tres:dicis:secs = h:t:d:s +// the normal seconds are now just a single digit 0-9 +// dicis:secs are easy to read: 6:0 means 60 seconds, 12:5 125 seconds etc. +// tres - multiply by three to get traditional babylonian minutes +// hours as usual (24 hour clock) +htds2secs (h::int:t::int:d::int:s::int) = 10.0*(18*(20*h+t)+d)+s; +secs2htds secs::int | secs2htds secs::bigint | secs2htds secs::double = + h:(t mod 20):(d mod 18):(secs-10*d) + when + d::int = int (secs / 10); + t::int = d div 18; + h::int = t div 20 + end; // not used yet but could be, as in: addmayan posixepoch (days2mayan posixdays) addmayan (baktun1::int:katun1::int:tun1::int:vinal1::int:kin1::int) @@ -59,11 +93,12 @@ mayan2days (baktun::int:katun::int:tun::int:vinal::int:kin::int) = 20*(18*(20*(20*baktun+katun)+tun)+vinal)+kin; -// simple calculations to print -daytoday = epochday + posixdays; -mayantoday = days2mayan daytoday; -daysleft = endofdays - posixdays; -mayanleft = days2mayan daysleft; +// for now, let's just do some simple calculations to print +daytoday = epochday + (secs2days posixsecsnow); // mayan whole day count +mayantoday = days2mayan daytoday; // as above but in mayan long count format +daysleft = cycledays - epochday - (secs2days (double posixsecsnow)); // double +mayanleft = days2mayan ((int daysleft)); +timeleft = secs2htds ((int secsinday) - secsnow); percentcomplete = 100.0*(epochday+posixsecsnow/secsinday)/cycledays; usage = puts "Usage: pure -x date.pure [anyarg]" $ @@ -71,16 +106,21 @@ case argc of 1 = - void (printf "Posix time now: %s\n" (str (secs2dhms posixsecsnow))) $ - void (printf "Mayan long count date: %s = day %d\n" - ((str mayantoday), (mayan2days mayantoday))) $ - void (printf "Mayan countdown today: %s = %d days till the cycle ends\n" - ((str mayanleft), daysleft)) $ - void (printf "The Mayan cycle of over %d years " (int cycleyears)) $ - void (printf "is now %11.8f%% complete!\n" percentcomplete); - 2 = void (puts "Mayan long count digits (and their range of values):") $ - void (puts "Baktun(0-12):Katun(0-19):Tun(0-19):Vinal(0-17):Kin(0-19)")$ - puts "Baktun=144000days:Katun=7200days:Tun=360days:Vinal=20days:Kin=1day"$ - usage; + void (printf "Mayan day %d + UTC Time %s = %s,%s\n" (daytoday, + (str (secs2hms secsnow)),(str mayantoday),(str (secs2htds secsnow))))$ + void (printf "Long countdown %f(days left) = %s,%s\n" + (daysleft, (str mayanleft), (str timeleft))) $ + void (printf "The Mayan cycle of over 5125 years is now %11.8f%% complete\n" + percentcomplete ) $ + void (puts"****************************************************************"); + 2 = + void(puts "Mayan long count digits (and their range of values):") $ + void(puts "Baktun(0-12) : Katun(0-19) : Tun(0-19) : Vinal(0-17) : Kin(0-19)")$ + puts "Baktun=144000days Katun=7200days Tun=360days Vinal=20days Kin=day"$ + void (puts "\nNew clock digits (and their range of values):") $ + void (puts "Hour(0-23) : Tre(0-19) : Dici(0-17) : Sec(0-9)")$ + puts "Hour=3600secs Tre=180secs Dici=10secs Sec=second\n"$ + puts "Complete time count: Baktun:Katun:Tun:Vinal:Kin,Hour:Tre:Dici:Sec\n" + usage; n = usage otherwise end; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <js...@us...> - 2008-07-04 20:33:13
|
Revision: 385 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=385&view=rev Author: jspitz Date: 2008-07-04 13:33:00 -0700 (Fri, 04 Jul 2008) Log Message: ----------- Add annotations of variable types. Modified Paths: -------------- pure/trunk/examples/heap.pure Modified: pure/trunk/examples/heap.pure =================================================================== --- pure/trunk/examples/heap.pure 2008-07-04 20:04:01 UTC (rev 384) +++ pure/trunk/examples/heap.pure 2008-07-04 20:33:00 UTC (rev 385) @@ -86,17 +86,30 @@ rmfirst (bin 0 _ h1 h2 ) = update (bin 1 (last h2) h1 (rmlast h2)); rmfirst (bin 1 _ h1 h2 ) = update (bin 0 (last h1) (rmlast h1) h2); - last (bin 0 x nil nil) = x; + last (bin 0 x::int nil nil) | + last (bin 0 x::string nil nil) | + last (bin 0 x nil nil) + = x; last (bin 0 _ _ h2) = last h2; last (bin 1 _ h1 _) = last h1; - update (bin 0 x nil nil) = bin 0 x nil nil; - update (bin 1 x (bin b1 x1 h1 h2) nil) + update (bin 0 x::int nil nil) | + update (bin 0 x::string nil nil) | + update (bin 0 x nil nil) + = bin 0 x nil nil; + update (bin 1 x::int (bin b1::int x1::int h1 h2) nil) | + update (bin 1 x::string (bin b1::int x1::string h1 h2) nil) | + update (bin 1 x (bin b1::int x1 h1 h2) nil) = bin 1 x (bin b1 x1 h1 h2) nil if x <= x1; = bin 1 x1 (update (bin b1 x h1 h2)) nil otherwise; - update (bin b x (bin b1 x1 h1 h2) (bin b2 x2 h3 h4)) + update (bin b::int x::int (bin b1::int x1::int h1 h2) + (bin b2::int x2::int h3 h4)) | + update (bin b::int x::string (bin b1::int x1::string h1 h2) + (bin b2::int x2::string h3 h4)) | + update (bin b::int x (bin b1::int x1 h1 h2) + (bin b2::int x2 h3 h4)) = bin b x (bin b1 x1 h1 h2) (bin b2 x2 h3 h4) if (x <= x1) && (x <= x2); = bin b x1 (update (bin b1 x h1 h2)) @@ -112,12 +125,23 @@ end; // insert a new member into a heap +insert (Heap h) y::int | +insert (Heap h) y::string | insert (Heap h) y = Heap (insert h y) with + insert nil y::int | + insert nil y::string | insert nil y = bin 0 y nil nil; - insert (bin 0 x h1 h2) y = bin 1 x (insert h1 y) h2 if x <= y; + + insert (bin 0 x::int h1 h2) y::int | + insert (bin 0 x::string h1 h2) y::string | + insert (bin 0 x h1 h2) y + = bin 1 x (insert h1 y) h2 if x <= y; = bin 1 y (insert h1 x) h2 otherwise; - insert (bin 1 x h1 h2) y = bin 0 x h1 (insert h2 y) if x <= y; + insert (bin 1 x::int h1 h2) y::int | + insert (bin 1 x::string h1 h2) y::string | + insert (bin 1 x h1 h2) y + = bin 0 x h1 (insert h2 y) if x <= y; = bin 0 y h1 (insert h2 x) otherwise end; @@ -127,7 +151,9 @@ eq nil nil = 1; eq nil (bin _ _ _ _) = 0; eq (bin _ _ _ _) nil = 0; - eq (bin b1 x1 h1 h2) (bin b2 x2 h3 h4) + eq (bin b1::int x1::int h1 h2) (bin b2::int x2::int h3 h4) | + eq (bin b1::int x1::string h1 h2) (bin b2::int x2::string h3 h4) | + eq (bin b1::int x1 h1 h2) (bin b2::int x2 h3 h4) = if (b1 == b2) then if (x1 == x2) then if eq h1 h3 @@ -143,7 +169,9 @@ neq nil nil = 0; neq nil (bin _ _ _ _) = 1; neq (bin _ _ _ _) nil = 1; - neq (bin b1 x1 h1 h2) (bin b2 x2 h3 h4) + neq (bin b1::int x1::int h1 h2) (bin b2::int x2::int h3 h4) | + neq (bin b1::int x1::string h1 h2) (bin b2::int x2::string h3 h4) | + neq (bin b1::int x1 h1 h2) (bin b2::int x2 h3 h4) = if (b1 != b2) then 1 else if (x1 != x2) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-07-04 20:03:52
|
Revision: 384 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=384&view=rev Author: agraef Date: 2008-07-04 13:04:01 -0700 (Fri, 04 Jul 2008) Log Message: ----------- Optimization: Skip compile for 'using' clause if possible. Modified Paths: -------------- pure/trunk/interpreter.cc Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-07-04 19:54:52 UTC (rev 383) +++ pure/trunk/interpreter.cc 2008-07-04 20:04:01 UTC (rev 384) @@ -443,12 +443,16 @@ { uint8_t s_verbose = verbose; // Temporarily suppress verbose output for using clause. - compile(); - verbose = 0; + if (verbose) { + compile(); + verbose = 0; + } for (list<string>::const_iterator s = sl.begin(); s != sl.end(); s++) run(*s, check); - compile(); - verbose = s_verbose; + if (s_verbose) { + compile(); + verbose = s_verbose; + } return result; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <js...@us...> - 2008-07-04 19:54:44
|
Revision: 383 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=383&view=rev Author: jspitz Date: 2008-07-04 12:54:52 -0700 (Fri, 04 Jul 2008) Log Message: ----------- Add heap data container to examples. Added Paths: ----------- pure/trunk/examples/heap.pure Added: pure/trunk/examples/heap.pure =================================================================== --- pure/trunk/examples/heap.pure (rev 0) +++ pure/trunk/examples/heap.pure 2008-07-04 19:54:52 UTC (rev 383) @@ -0,0 +1,154 @@ +/* Pure's priority queue data structure implemented as binary trees */ + +/* Copyright (c) 2008 by Albert Graef <Dr....@t-...>. + + This file is part of the Pure programming language and system. + + Pure is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or (at your option) any later + version. + + Pure 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 General Public License for more + details. + + You should have received a copy of the GNU General Public License along + with this program. If not, see <http://www.gnu.org/licenses/>. */ + + +/* Heaps allow quick (constant time) access to the smallest member, and to + remove the smallest nember and insert new elements in logarithmic time. + This implementation does not allow quick update of heap members; if + such functionality is required, bags should be used instead + (see bag in set.pure). + + Heap members must be ordered by the <= predicate. Multiple instances + of the same element may be stored in a heap; however, the order in + which equal elements are retrieved is not specified. */ + +/* Public operations: ****************************************************** + +// #h // size of a heap + +// null h // tests whether h is the empty heap +// list h, members h // lists members of h in ascending order + +// first h // first (i.e. smallest) member of h +// rmfirst h // remove smallest member from h +// insert h x // insert h into x + + *************************************************************************/ + +/* Empty tree constant, consider this private. */ +nullary nil; + +// create an empty heap +emptyheap = Heap nil; + +// create a heap from a list +heap xs = foldl insert emptyheap xs if listp xs; + +// check whether h is a heap +heapp (Heap _) = 1; +heapp _ = 0 otherwise; + +// get size of a heap +#(Heap h) = #h +with + #nil = 0; + #bin 0 _ h1 _ = #h1 * 2 + 1; + #bin 1 _ h1 _ = #h1 * 2 +end; + +// test for an empty heap +null (Heap nil) = 1; +null (Heap _) = 0 otherwise; + +// get members of a heap as an ordered list +members h@(Heap _) = [] if null h; + = accum [first h] (rmfirst h) +with + accum ys h = reverse ys if null h; + = accum ((first h):ys) (rmfirst h) +end; + +list h@(Heap _) = members h; + +// get the first (smallest) member of a heap +first (Heap (bin _ x _ _)) = x; + +// remove the first (smallest) member of a heap +rmfirst (Heap h) = Heap (rmfirst h) +with + rmfirst (bin 0 _ nil nil) = nil; + rmfirst (bin 0 _ h1 h2 ) = update (bin 1 (last h2) h1 (rmlast h2)); + rmfirst (bin 1 _ h1 h2 ) = update (bin 0 (last h1) (rmlast h1) h2); + + last (bin 0 x nil nil) = x; + last (bin 0 _ _ h2) = last h2; + last (bin 1 _ h1 _) = last h1; + + update (bin 0 x nil nil) = bin 0 x nil nil; + update (bin 1 x (bin b1 x1 h1 h2) nil) + = bin 1 x (bin b1 x1 h1 h2) nil + if x <= x1; + = bin 1 x1 (update (bin b1 x h1 h2)) + nil otherwise; + update (bin b x (bin b1 x1 h1 h2) (bin b2 x2 h3 h4)) + = bin b x (bin b1 x1 h1 h2) (bin b2 x2 h3 h4) + if (x <= x1) && (x <= x2); + = bin b x1 (update (bin b1 x h1 h2)) + (bin b2 x2 h3 h4) + if x1 <= x2; + = bin b x2 (bin b1 x1 h1 h2) + (update (bin b2 x h3 h4)) + otherwise; + + rmlast (bin 0 _ nil nil) = nil; + rmlast (bin 0 x h1 h2 ) = bin 1 x h1 (rmlast h2); + rmlast (bin 1 x h1 h2 ) = bin 0 x (rmlast h1) h2; +end; + +// insert a new member into a heap +insert (Heap h) y = Heap (insert h y) +with + insert nil y = bin 0 y nil nil; + insert (bin 0 x h1 h2) y = bin 1 x (insert h1 y) h2 if x <= y; + = bin 1 y (insert h1 x) h2 otherwise; + insert (bin 1 x h1 h2) y = bin 0 x h1 (insert h2 y) if x <= y; + = bin 0 y h1 (insert h2 x) otherwise +end; + +// equality test +(Heap h1) == (Heap h2) = eq h1 h2 +with + eq nil nil = 1; + eq nil (bin _ _ _ _) = 0; + eq (bin _ _ _ _) nil = 0; + eq (bin b1 x1 h1 h2) (bin b2 x2 h3 h4) + = if (b1 == b2) + then if (x1 == x2) + then if eq h1 h3 + then eq h2 h4 + else 0 + else 0 + else 0 +end;; + +// inequaliy test +(Heap h1) != (Heap h2) = neq h1 h2 +with + neq nil nil = 0; + neq nil (bin _ _ _ _) = 1; + neq (bin _ _ _ _) nil = 1; + neq (bin b1 x1 h1 h2) (bin b2 x2 h3 h4) + = if (b1 != b2) + then 1 + else if (x1 != x2) + then 1 + else if neq h1 h3 + then 1 + else neq h2 h4 +end; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <js...@us...> - 2008-07-04 05:47:43
|
Revision: 382 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=382&view=rev Author: jspitz Date: 2008-07-03 22:47:17 -0700 (Thu, 03 Jul 2008) Log Message: ----------- Delete outdated cdt.pure. Removed Paths: ------------- pure/trunk/examples/cdt.pure Deleted: pure/trunk/examples/cdt.pure =================================================================== --- pure/trunk/examples/cdt.pure 2008-07-04 05:42:48 UTC (rev 381) +++ pure/trunk/examples/cdt.pure 2008-07-04 05:47:17 UTC (rev 382) @@ -1,1131 +0,0 @@ -/* Pure's data container types (cdt) based on AVL trees. */ - -/* Copyright (c) 2008 by Albert Graef <Dr....@t-...>. - - This file is part of the Pure programming language and system. - - Pure is free software: you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation, either version 3 of the License, or (at your option) any later - version. - - Pure 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 General Public License for more - details. - - You should have received a copy of the GNU General Public License along - with this program. If not, see <http://www.gnu.org/licenses/>. */ - - -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - The used algorithm of AVL trees has its origin in the SWI-Prolog - implementation of association lists. The original file was created by - R. A. O'Keefe and updated for the SWI-Prolog by Jan Wielemaker. For the - original file see http://www.swi-prolog.org. - - The port from SWI-Prolog and the deletion stuff (rmfirst, rmlast, delete) - missing in the original file was provided by Jiri Spitz -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - -/*****************************************************************************/ -/* */ -/* DIFFERENCES VERSUS Q LANGUAGE */ -/* */ -/****************************************************************************** - -1. The "pure man's tuples" are not suitable for holding key - value pairs. - Therefore, the key - value pairs are denoted as lists [Key, Value] in Pure. - -2. Views are not currently available in Pure and so the data structures are - displayed as they really are. To view the data as lists you should call - the function "members". - -******************************************************************************/ - - -/*** some declarations ***/ - -using primitives; - -// tree constructors -nullary nil bin; - -// symbolic constants for better readibility -nullary islt iseq isgt; -nullary left right; -nullary false true; - -// symbolic constants identifying the data structures -nullary tset tbag tdict thdict; -nullary cdt; - - -/*** some stuff from Q's stdlib which is missing in Pure now ***/ - -fst (X:_) = X; -fst (X,_) = X; - -snd (_:X:_) = X; -snd (_,X,_) = X; - - -/******************************************************************************/ -/* */ -/* PUBLIC FUNCTIONS */ -/* */ -/******************************************************************************/ - -/*** The following functions represent the user's interface to the module ***/ - - -// data structure type checks - -isbag (cdt tbag _) = 1; -isbag _ = 0; - -isset (cdt tset _) = 1; -isset _ = 0; - -isdict (cdt tdict _) = 1; -isdict _ = 0; - -ishdict (cdt thdict _) = 1; -ishdict _ = 0; - - -// create an empty data structure - -emptyset = cdt tset nil; -emptybag = cdt tbag nil; -emptydict = cdt tdict nil; -emptyhdict = cdt thdict nil; - - -// create data structure from a list - -set Xs = foldl insert emptyset Xs if listp Xs; -bag Xs = foldl insert emptybag Xs if listp Xs; -dict XYs = foldl insert emptydict XYs if listp XYs; -hdict XYs = foldl insert emptyhdict XYs if listp XYs; - - -// insert a new member into the data structure - -insert (cdt tset M) Y::int | -insert (cdt tset M) Y::string | -insert (cdt tset M) Y - = cdt tset (fst (insert_set_a M Y)); - -insert (cdt tbag M) Y::int | -insert (cdt tbag M) Y::string | -insert (cdt tbag M) Y - = cdt tbag (fst (insert_bag_a M Y)); - -insert (cdt tdict D) [X::int,Y] | -insert (cdt tdict D) [X::string,Y] | -insert (cdt tdict D) [X, Y] - = cdt tdict (fst (insert_dict_a D X Y)); - -insert (cdt thdict D) [X,Y] - = cdt thdict (fst (insert_hdict_a D (hash X) X Y)); - - -// delete a meber by key from the data structure - -delete (cdt tset M) Y::int | -delete (cdt tset M) Y::string | -delete (cdt tset M) Y - = cdt tset (fst (delete_set_bag_a M Y)); - -delete (cdt tbag M) Y::int | -delete (cdt tbag M) Y::string | -delete (cdt tbag M) Y - = cdt tbag (fst (delete_set_bag_a M Y)); - -delete (cdt tdict D) X::int | -delete (cdt tdict D) X::string | -delete (cdt tdict D) X - = cdt tdict (fst (delete_dict_a D X)); - -delete (cdt thdict D) X - = cdt thdict (fst (delete_hdict_a D (hash X) X)); - - -// create dict or hdict from a list of keys and a constant value - -mkdict Y Xs = dict (zip Xs (repeat (#Xs) Y)) if listp Xs; -mkhdict Y Xs = hdict (zip Xs (repeat (#Xs) Y)) if listp Xs; - - -// check for the empty data structure - -null (cdt tset nil) = 1; -null (cdt tset _) = 0; - -null (cdt tbag nil) = 1; -null (cdt tbag _) = 0; - -null (cdt tdict nil) = 1; -null (cdt tdict _) = 0; - -null (cdt thdict nil) = 1; -null (cdt thdict _) = 0; - - -// get a number of members in data structure - -#(cdt tset M) = size_set_bag M; -#(cdt tbag M) = size_set_bag M; -#(cdt tdict D) = size_dict D; -#(cdt thdict D) = size_hdict D; - - -// check whether a key exists in data structure - -member (cdt tset M) K::int | -member (cdt tset M) K::string | -member (cdt tset M) K - = member_set_bag M K; - -member (cdt tbag M) K::int | -member (cdt tbag M) K::string | -member (cdt tbag M) K - = member_set_bag M K; - -member (cdt tdict D) K::int | -member (cdt tdict D) K::string | -member (cdt tdict D) K - = member_dict D K; - -member (cdt thdict D) K::int | -member (cdt thdict D) K::string | -member (cdt thdict D) K - = member_hdict D K; - - -// get all members of data structure as a list - -members (cdt tset M) = members_set_bag M; -members (cdt tbag M) = members_set_bag M; -members (cdt tdict D) = members_dict D; -members (cdt thdict D) = members_hdict D; - - -// get the first member of an ordered data structure - -first (cdt tset M) = first_set_bag M; -first (cdt tbag M) = first_set_bag M; -first (cdt tdict D) = first_dict D; - - -// get the last member of an ordered data structure - -last (cdt tset M) = last_set_bag M; -last (cdt tbag M) = last_set_bag M; -last (cdt tdict D) = last_dict D; - - -// remove the first member from an ordered data structure - -rmfirst (cdt tset M) = cdt tset (fst (rmfirst_set_bag_a M)); -rmfirst (cdt tbag M) = cdt tbag (fst (rmfirst_set_bag_a M)); -rmfirst (cdt tdict D) = cdt tdict (fst (rmfirst_dict_a D)); - - -// remove the last member from an ordered data structure - -rmlast (cdt tset M) = cdt tset (fst (rmlast_set_bag_a M)); -rmlast (cdt tbag M) = cdt tbag (fst (rmlast_set_bag_a M)); -rmlast (cdt tdict D) = cdt tdict (fst (rmlast_dict_a D)); - - -// get a list of all keys from dict or hdict - -keys (cdt tdict D) = keys_dict D; -keys (cdt thdict D) = keys_hdict D; - - -// get a list of all values from dict or hdict - -vals (cdt tdict D) = vals_dict D; -vals (cdt thdict D) = vals_hdict D; - - -// get a value by key from dict or hdict - -(cdt tdict D)!K::int | -(cdt tdict D)!K::string | -(cdt tdict D)!K - = key2val_dict D K; - -(cdt thdict D)!K = lookup_hdict D (hash K) K; - - -// curried version of insert for dict and hdict - -update (cdt tdict D) X::int Y | -update (cdt tdict D) X::string Y | -update (cdt tdict D) X Y - = (cdt tdict (fst (insert_dict D X Y))); - -update (cdt thdict D) X::int Y | -update (cdt thdict D) X::string Y | -update (cdt thdict D) X Y - = (cdt thdict (fst (insert_hdict D (hash X) X Y))); - - -// equality checks for data structures - -(cdt tset M1) == (cdt tset M2) = eq_set_bag_dict M1 M2; -(cdt tbag M1) == (cdt tbag M2) = eq_set_bag_dict M1 M2; -(cdt tdict D1) == (cdt tdict D2) = eq_set_bag_dict D1 D2; -(cdt thdict D1) == (cdt thdict D2) = eq_hdict D1 D2; - - -// inequality checks for data structures - -(cdt tset M1) != (cdt tset M2) = neq_set_bag_dict M1 M2; -(cdt tbag M1) != (cdt tbag M2) = neq_set_bag_dict M1 M2; -(cdt tdict D1) != (cdt tdict D2) = neq_set_bag_dict D1 D2; -(cdt thdict D1) != (cdt thdict D2) = neq_hdict D1 D2; - - -// set and bag relations - -(cdt tset M1) <= (cdt tset M2) = leq_set M1 M2; -(cdt tbag M1) <= (cdt tbag M2) = leq_bag M1 M2; - -(cdt tset M1) >= (cdt tset M2) = geq_set M1 M2; -(cdt tbag M1) >= (cdt tbag M2) = geq_bag M1 M2; - -(cdt tset M1) < (cdt tset M2) = lt_set M1 M2; -(cdt tbag M1) < (cdt tbag M2) = lt_bag M1 M2; - -(cdt tset M1) > (cdt tset M2) = gt_set M1 M2; -(cdt tbag M1) > (cdt tbag M2) = gt_bag M1 M2; - - -// set and bag union - -(cdt tset M1) + (cdt tset M2) = union_set M1 M2; -(cdt tbag M1) + (cdt tbag M2) = union_bag M1 M2; - - -// set and bag difference - -(cdt tset M1) - (cdt tset M2) = diff_set_bag M1 M2; -(cdt tbag M1) - (cdt tbag M2) = diff_set_bag M1 M2; - - -// set and bag intersection - -(cdt tset M1) * (cdt tset M2) = intersect_set_bag M1 M2; -(cdt tbag M1) * (cdt tbag M2) = intersect_set_bag M1 M2; - - -/******************************************************************************/ -/* */ -/* PRIVATE FUNCTIONS */ -/* */ -/******************************************************************************/ - -/*** The following functions shouldn't be directly used by users ***/ - - -/***** -Tree for set and bag is either: -- nil (empty tree) or -- bin Key Balance Left Right (Left, Right: trees) - -Tree for dict and hdict is either: -- nil (empty tree) or -- bin Key Value Balance Left Right (Left, Right: trees) - -Balance: islt, iseq, or isgt denoting |L|-|R| = 1, 0, or -1, respectively -*****/ - -/*** set stuff ***/ - -insert_set_a nil Key::int | -insert_set_a nil Key::string | -insert_set_a nil Key - = [(bin Key iseq nil nil), true]; - -insert_set_a (bin K::int B L R) Key::int | -insert_set_a (bin K::string B L R) Key::string | -insert_set_a (bin K B L R) Key - = [(bin Key B L R), false] if Key == K; - -insert_set_a (bin K::int B L R) Key::int | -insert_set_a (bin K::string B L R) Key::string | -insert_set_a (bin K B L R) Key - = adjusti_set_bag LeftHasChanged (bin K B NewL R) left - when [NewL, LeftHasChanged] = insert_set_a L Key end if Key < K; - -insert_set_a (bin K::int B L R) Key::int | -insert_set_a (bin K::string B L R) Key::string | -insert_set_a (bin K B L R) Key - = adjusti_set_bag RightHasChanged (bin K B L NewR) right - when [NewR, RightHasChanged] = insert_set_a R Key end if Key > K; - - -/*** bag stuff ***/ - -insert_bag_a nil Key::int | -insert_bag_a nil Key::string | -insert_bag_a nil Key - = [(bin Key iseq nil nil), true]; - -insert_bag_a (bin K::int B L R) Key::int | -insert_bag_a (bin K::string B L R) Key::string | -insert_bag_a (bin K B L R) Key - = adjusti_set_bag LeftHasChanged (bin K B NewL R) left - when [NewL, LeftHasChanged] = insert_bag_a L Key end if Key < K; - -insert_bag_a (bin K::int B L R) Key::int | -insert_bag_a (bin K::string B L R) Key::string | -insert_bag_a (bin K B L R) Key - = adjusti_set_bag RightHasChanged (bin K B L NewR) right - when [NewR, RightHasChanged] = insert_bag_a R Key end if Key >= K; - - -/*** set and bag stuff ***/ - -rmfirst_set_bag_a nil - = [nil, false]; - -rmfirst_set_bag_a (bin _ _ nil R) - = [R, true]; - -rmfirst_set_bag_a (bin K B L R) - = adjustd_set_bag LeftHasChanged (bin K B NewL R) left - when [NewL, LeftHasChanged] = rmfirst_set_bag_a L end; - -rmlast_set_bag_a nil - = [nil false]; - -rmlast_set_bag_a (bin _ _ L nil) - = [L, true]; - -rmlast_set_bag_a (bin K B L R) - = adjustd_set_bag RightHasChanged (bin K B L NewR) right - when [NewR, RightHasChanged] = rmlast_set_bag_a R end; - - -delete_set_bag_a nil _ - = [nil, false]; - - -delete_set_bag_a (bin K::int _ nil R ) Key::int | -delete_set_bag_a (bin K::string _ nil R ) Key::string | -delete_set_bag_a (bin K _ nil R ) Key - = [R, true] if Key == K; - -delete_set_bag_a (bin K::int _ L nil) Key::int | -delete_set_bag_a (bin K::string _ L nil) Key::string | -delete_set_bag_a (bin K _ L nil) Key - = [L, true] if Key == K; - -delete_set_bag_a (bin K::int B (bin KL::int BL RL LL) R) Key::int | -delete_set_bag_a (bin K::string B (bin KL::string BL RL LL) R) Key::string | -delete_set_bag_a (bin K B (bin KL BL RL LL) R) Key - = adjustd_set_bag LeftHasChanged (bin LK B NewL R) left - when - LK = last_set_bag (bin KL BL RL LL); - [NewL, LeftHasChanged] - = rmlast_set_bag_a (bin KL BL RL LL) - end - if Key == K; - -delete_set_bag_a (bin K::int B L R) Key::int | -delete_set_bag_a (bin K::string B L R) Key::string | -delete_set_bag_a (bin K B L R) Key - = adjustd_set_bag LeftHasChanged (bin K B NewL R) left - when - [NewL, LeftHasChanged] = delete_set_bag_a L Key - end - if Key < K; - - -delete_set_bag_a (bin K::int B L R) Key::int | -delete_set_bag_a (bin K::string B L R) Key::string | -delete_set_bag_a (bin K B L R) Key - = adjustd_set_bag RightHasChanged (bin K B L NewR) right - when - [NewR, RightHasChanged] = delete_set_bag_a R Key - end - if Key > K; - - -// The insertions and deletions are dealt with separately. - -// Insertions - -adjusti_set_bag false OldTree _ - = [OldTree, false]; - -adjusti_set_bag true (bin Key::int B0 L R) LoR | -adjusti_set_bag true (bin Key::string B0 L R) LoR | -adjusti_set_bag true (bin Key B0 L R) LoR - = [rebali_set_bag ToBeRebalanced (bin Key B0 L R) B1, WhatHasChanged] - when - [B1, WhatHasChanged, ToBeRebalanced] = tablei B0 LoR - end; - -rebali_set_bag false (bin K::int _ L R) B | -rebali_set_bag false (bin K::string _ L R) B | -rebali_set_bag false (bin K _ L R) B - = bin K B L R; - - -rebali_set_bag true OldTree _ - = fst (avl_geq_set_bag OldTree); - - -// Deletions - -adjustd_set_bag false OldTree _ - = [OldTree, false]; - -adjustd_set_bag true (bin Key::int B0 L R) LoR | -adjustd_set_bag true (bin Key::string B0 L R) LoR | -adjustd_set_bag true (bin Key B0 L R) LoR - = rebald_set_bag ToBeRebalanced (bin Key B0 L R) B1 WhatHasChanged - when - [B1, WhatHasChanged, ToBeRebalanced] = tabled B0 LoR - end; - - -/* - Note that rebali and rebald are not symmetrical. With insertions it is - sufficient to know the original balance and insertion side in order to - decide whether the whole tree increases. With deletions it is sometimes not - sufficient and we need to know which kind of tree rotation took place. -*/ -rebald_set_bag false (bin K::int _ L R) B WhatHasChanged | -rebald_set_bag false (bin K::string _ L R) B WhatHasChanged | -rebald_set_bag false (bin K _ L R) B WhatHasChanged - = [bin K B L R, WhatHasChanged]; - - -rebald_set_bag true OldTree _ _ - = avl_geq_set_bag OldTree; - -// Single and double tree rotations - these are common for insert and delete -/* - The patterns isgt-isgt, isgt-islt, islt-islt and islt-isgt on the LHS always - change the tree height and these are the only patterns which can happen - after an insertion. That's the reason why we can use tablei only to decide - the needed changes. - The patterns isgt-iseq and islt-iseq do not change the tree height. After a - deletion any pattern can occur and so we return true or false as a flag of - a height change. -*/ - -avl_geq_set_bag (bin A::int isgt Alpha (bin B::int isgt Beta Gamma)) | -avl_geq_set_bag (bin A::string isgt Alpha (bin B::string isgt Beta Gamma)) | -avl_geq_set_bag (bin A isgt Alpha (bin B isgt Beta Gamma)) - = [bin B iseq (bin A iseq Alpha Beta) Gamma, true]; - -avl_geq_set_bag (bin A::int isgt Alpha (bin B::int iseq Beta Gamma)) | -avl_geq_set_bag (bin A::string isgt Alpha (bin B::string iseq Beta Gamma)) | -avl_geq_set_bag (bin A isgt Alpha (bin B iseq Beta Gamma)) - = [bin B islt (bin A isgt Alpha Beta) Gamma, false]; - // the tree doesn't decrease with this pattern - -avl_geq_set_bag (bin A::int isgt Alpha - (bin B::int islt (bin X::int B1 Beta Gamma) Delta)) | -avl_geq_set_bag (bin A::string isgt Alpha - (bin B::string islt (bin X::string B1 Beta Gamma) Delta)) | -avl_geq_set_bag (bin A isgt Alpha (bin B islt (bin X B1 Beta Gamma) Delta)) - = [bin X iseq (bin A B2 Alpha Beta) - (bin B B3 Gamma Delta), true] - when - [B2, B3] = table2 B1 - end; - -avl_geq_set_bag (bin B::int islt (bin A::int islt Alpha Beta) Gamma) | -avl_geq_set_bag (bin B::string islt (bin A::string islt Alpha Beta) Gamma) | -avl_geq_set_bag (bin B islt (bin A islt Alpha Beta) Gamma) - = [bin A iseq Alpha (bin B iseq Beta Gamma), true]; - -avl_geq_set_bag (bin B::int islt (bin A::int iseq Alpha Beta) Gamma) | -avl_geq_set_bag (bin B::string islt (bin A::string iseq Alpha Beta) Gamma) | -avl_geq_set_bag (bin B islt (bin A iseq Alpha Beta) Gamma) - = [bin A isgt Alpha (bin B islt Beta Gamma), false]; - // the tree doesn't decrease with this pattern - - -avl_geq_set_bag (bin B::int islt - (bin A::int isgt Alpha (bin X::int B1 Beta Gamma)) Delta) | -avl_geq_set_bag (bin B::string islt - (bin A::string isgt Alpha (bin X::string B1 Beta Gamma)) Delta) | -avl_geq_set_bag (bin B islt (bin A isgt Alpha (bin X B1 Beta Gamma)) Delta) - = [bin X iseq (bin A B2 Alpha Beta) - (bin B B3 Gamma Delta), true] - when - [B2, B3] = table2 B1 - end; - - -/*** dict stuff ***/ - -insert_dict_a nil Key::int Val | -insert_dict_a nil Key::string Val | -insert_dict_a nil Key Val - = [(bin Key Val iseq nil nil), true]; - -insert_dict_a (bin K::int _ B L R) Key::int Val | -insert_dict_a (bin K::string _ B L R) Key::string Val | -insert_dict_a (bin K _ B L R) Key Val - = [(bin Key Val B L R), false] if Key == K; - -insert_dict_a (bin K::int V B L R) Key::int Val | -insert_dict_a (bin K::string V B L R) Key::string Val | -insert_dict_a (bin K V B L R) Key Val - = adjusti_dict_hdict LeftHasChanged (bin K V B NewL R) left - when - [NewL, LeftHasChanged] = insert_dict_a L Key Val - end - if Key < K; - -insert_dict_a (bin K::int V B L R) Key::int Val | -insert_dict_a (bin K::string V B L R) Key::string Val | -insert_dict_a (bin K V B L R) Key Val - = adjusti_dict_hdict RightHasChanged (bin K V B L NewR) right - when - [NewR, RightHasChanged] = insert_dict_a R Key Val - end - if Key > K; - -rmfirst_dict_a nil - = [nil, false]; - -rmfirst_dict_a (bin _ _ _ nil R) - = [R, true]; - -rmfirst_dict_a (bin K V B L R) - = adjustd_dict_hdict LeftHasChanged (bin K V B NewL R) left - when - [NewL, LeftHasChanged] = rmfirst_dict_a L - end; - - -rmlast_dict_a nil - = [nil false]; - -rmlast_dict_a (bin _ _ _ L nil) - = [L, true]; - -rmlast_dict_a (bin K V B L R) - = adjustd_dict_hdict RightHasChanged (bin K V B L NewR) right - when - [NewR, RightHasChanged] = rmlast_dict_a R - end; - -delete_dict_a nil _ - = [nil, false]; - -delete_dict_a (bin K::int _ _ nil R ) Key::int | -delete_dict_a (bin K::string _ _ nil R ) Key::string | -delete_dict_a (bin K _ _ nil R ) Key - = [R, true] if Key == K; - -delete_dict_a (bin K::int _ _ L nil) Key::int | -delete_dict_a (bin K::string _ _ L nil) Key::string | -delete_dict_a (bin K _ _ L nil) Key - = [L, true] if Key == K; - - -delete_dict_a (bin K::int _ B (bin KL::int VL BL RL LL) R ) Key::int | -delete_dict_a (bin K::string _ B (bin KL::string VL BL RL LL) R ) Key::string | -delete_dict_a (bin K _ B (bin KL VL BL RL LL) R ) Key - = adjustd_dict_hdict LeftHasChanged (bin LastK LastV B NewL R) left - when - [LastK, LastV] - = last_dict (bin KL VL BL RL LL); - [NewL, LeftHasChanged] - = rmlast_dict_a (bin KL VL BL RL LL) - end - if Key == K; - -delete_dict_a (bin K::int V B L R) Key::int | -delete_dict_a (bin K::string V B L R) Key::string | -delete_dict_a (bin K V B L R) Key - = adjustd_dict_hdict LeftHasChanged (bin K V B NewL R) left - when - [NewL, LeftHasChanged] = delete_dict_a L Key - end - if Key < K; - -delete_dict_a (bin K::int V B L R) Key::int | -delete_dict_a (bin K::string V B L R) Key::string | -delete_dict_a (bin K V B L R) Key - = adjustd_dict_hdict RightHasChanged (bin K V B L NewR) right - when - [NewR, RightHasChanged] = delete_dict_a R Key - end - if Key > K; - - -/*** hdict stuff ***/ - -lookup_hdict nil _ _ - = throw out_of_bounds; -lookup_hdict (bin K::int XYs _ D1 D2) K1::int X1 - = lookup_hdict D1 K1 X1 if K > K1; - = lookup_hdict D2 K1 X1 if K < K1; - = lookup2 XYs X1 - with - lookup2 [] _ = throw out_of_bounds; - lookup2 ([XA,Y]: _) XB = Y if XA === XB; - lookup2 ( _:XYs) X = lookup2 XYs X - end; - - -memberk_hdict nil _ _ - = 0; -memberk_hdict (bin K::int XYs _ D1 D2) K1::int X1 - = memberk_hdict D1 K1 X1 if K > K1; - = memberk_hdict D2 K1 X1 if K < K1; - = memberk2 XYs X1 - with - memberk2 [] _ = 0; - memberk2 ([MXA,MY] :_) MXB = 1 if MXA === MXB; - memberk2 ( _:MXYs) MX = memberk2 MXYs MX - end; - -insert_hdict_a nil K::int X Y - = [(bin K [[X, Y]] iseq nil nil), true]; - -insert_hdict_a (bin K::int V B L R) Key::int X Y - = [(bin K (inserta2 V X Y) B L R), false] - with - inserta2 [] IX IY = [IX, IY]:[]; - inserta2 ([IXA,IY]:IXYs) IXB IY1 - = ([IXA,IY1]:IXYs) if IXA === IXB; - inserta2 ([IX,IY]:IXYs) IX1 IY1 - = ([IX,IY]:(inserta2 IXYs IX1 IY1)); - end - if K == Key; - -insert_hdict_a (bin K::int V B L R) Key::int X Y - = adjusti_dict_hdict LeftHasChanged (bin K V B NewL R) left - when - [NewL, LeftHasChanged] = insert_hdict_a L Key X Y - end - if Key < K; - -insert_hdict_a (bin K::int V B L R) Key::int X Y - = adjusti_dict_hdict RightHasChanged (bin K V B L NewR) right - when - [NewR, RightHasChanged] = insert_hdict_a R Key X Y - end - if Key > K; - - -delete_hdict_a nil _ _ - = [nil, false]; - -delete_hdict_a (bin K::int XYs B nil R ) Key::int X - = (if (NewXYs == []) - then [R, true] - else [bin K NewXYs B nil R, false]) - when - NewXYs = delete_hdict_a2 XYs X - end - if K == Key; - -delete_hdict_a (bin K::int XYs B L nil) Key::int X - = (if (NewXYs == []) - then [L, true] - else [bin K NewXYs B L nil, false]) - when - NewXYs = delete_hdict_a2 XYs X - end - if K == Key; - -delete_hdict_a (bin K::int XYs B (bin KL VL BL RL LL) R) Key::int X - = adjustd_dict_hdict LeftHasChanged (bin LastK LastV B NewL R) left - when - [LastK, LastV] = last_dict (bin KL VL BL RL LL); - [NewL, LeftHasChanged] = rmlast_dict_a (bin KL VL BL RL LL) - end - if (K == Key) && ((delete_hdict_a2 XYs X) == []); - -delete_hdict_a (bin K::int XYs B L R) Key::int X - = [bin Key (delete_hdict_a2 XYs X) B L R, false] - if K == Key; - -delete_hdict_a (bin K::int V B L R) Key::int X - = adjustd_dict_hdict LeftHasChanged (bin K V B NewL R) left - when - [NewL, LeftHasChanged] = delete_hdict_a L Key X - end - if Key < K; - -delete_hdict_a (bin K::int V B L R) Key::int X - = adjustd_dict_hdict RightHasChanged (bin K V B L NewR) right - when - [NewR, RightHasChanged] = delete_hdict_a R Key X - end - if Key > K; - -delete_hdict_a2 [] _ = []; -delete_hdict_a2 ([X1,_]:XYs) X2 = XYs if X1 === X2; -delete_hdict_a2 ([X,Y]:XYs) X1 = [X,Y]:(delete_hdict_a2 XYs X1); - - - - -/*** dict and hdict stuff ***/ - -// The insertions and deletions are dealt with separately. - -// Insertions - -adjusti_dict_hdict false OldTree _ = [OldTree, false]; - -adjusti_dict_hdict true (bin Key::int Val B0 L R) LoR | -adjusti_dict_hdict true (bin Key::string Val B0 L R) LoR | -adjusti_dict_hdict true (bin Key Val B0 L R) LoR - = [rebali_dict_hdict ToBeRebalanced (bin Key Val B0 L R) B1, - WhatHasChanged] - when - [B1, WhatHasChanged, ToBeRebalanced] = tablei B0 LoR - end; - -rebali_dict_hdict false (bin K::int V _ L R) B | -rebali_dict_hdict false (bin K::string V _ L R) B | -rebali_dict_hdict false (bin K V _ L R) B - = bin K V B L R; - -rebali_dict_hdict true OldTree _ - = fst (avl_geq_dict_hdict OldTree); - - -// Deletions -adjustd_dict_hdict false OldTree _ - = [OldTree, false]; - -adjustd_dict_hdict true (bin Key::int Val B0 L R) LoR | -adjustd_dict_hdict true (bin Key::string Val B0 L R) LoR | -adjustd_dict_hdict true (bin Key Val B0 L R) LoR - = rebald_dict_hdict ToBeRebalanced (bin Key Val B0 L R) B1 - WhatHasChanged - when - [B1, WhatHasChanged, ToBeRebalanced] = tabled B0 LoR - end; - - -rebald_dict_hdict false (bin K::int V _ L R) B WhatHasChanged | -rebald_dict_hdict false (bin K::string V _ L R) B WhatHasChanged | -rebald_dict_hdict false (bin K V _ L R) B WhatHasChanged - = [bin K V B L R, WhatHasChanged]; - - -rebald_dict_hdict true OldTree _ _ - = avl_geq_dict_hdict OldTree; - -// Single and double tree rotations - these are common for insert and delete -/* - The patterns isgt-isgt, isgt-islt, islt-islt and islt-isgt on the LHS always - change the tree height and these are the only patterns which can happen - after an insertion. That's the reason why we can use tablei only to decide - the needed changes. - The patterns isgt-iseq and islt-iseq do not change the tree height. After a - deletion any pattern can occur and so we return true or false as a flag of - a height change. -*/ - -avl_geq_dict_hdict (bin A::int VA isgt Alpha (bin B::int VB isgt Beta Gamma)) | -avl_geq_dict_hdict (bin A::string VA isgt Alpha - (bin B::string VB isgt Beta Gamma)) | -avl_geq_dict_hdict (bin A VA isgt Alpha (bin B VB isgt Beta Gamma)) - = [bin B VB iseq (bin A VA iseq Alpha Beta) Gamma, true]; - - -avl_geq_dict_hdict (bin A::int VA isgt Alpha (bin B::int VB iseq Beta Gamma)) | -avl_geq_dict_hdict (bin A::string VA isgt Alpha - (bin B::string VB iseq Beta Gamma)) | -avl_geq_dict_hdict (bin A VA isgt Alpha (bin B VB iseq Beta Gamma)) - = [bin B VB islt (bin A VA isgt Alpha Beta) Gamma, false]; - // the tree doesn't decrease with this pattern - -avl_geq_dict_hdict (bin A::int VA isgt Alpha - (bin B::int VB islt (bin X::int VX B1 Beta Gamma) Delta)) | -avl_geq_dict_hdict (bin A::string VA isgt Alpha - (bin B::string VB islt - (bin X::string VX B1 Beta Gamma) Delta)) | -avl_geq_dict_hdict (bin A VA isgt Alpha - (bin B VB islt (bin X VX B1 Beta Gamma) Delta)) - = [bin X VX iseq (bin A VA B2 Alpha Beta) - (bin B VB B3 Gamma Delta), true] - when - [B2, B3] = table2 B1 - end; - - -avl_geq_dict_hdict (bin B::int VB islt (bin A::int VA islt Alpha Beta) Gamma) | -avl_geq_dict_hdict (bin B::string VB islt - (bin A::string VA islt Alpha Beta) Gamma) | -avl_geq_dict_hdict (bin B VB islt (bin A VA islt Alpha Beta) Gamma) - = [bin A VA iseq Alpha (bin B VB iseq Beta Gamma), true]; - -avl_geq_dict_hdict (bin B::int VB islt (bin A::int VA iseq Alpha Beta) Gamma) | -avl_geq_dict_hdict (bin B::string VB islt - (bin A::string VA iseq Alpha Beta) Gamma) | -avl_geq_dict_hdict (bin B VB islt (bin A VA iseq Alpha Beta) Gamma) - = [bin A VA isgt Alpha (bin B VB islt Beta Gamma), false]; - // the tree doesn't decrease with this pattern - -avl_geq_dict_hdict (bin B::int VB islt - (bin A::int VA isgt Alpha - (bin X::int VX B1 Beta Gamma)) Delta) | -avl_geq_dict_hdict (bin B::string VB islt - (bin A::string VA isgt Alpha - (bin X::string VX B1 Beta Gamma)) Delta) | -avl_geq_dict_hdict (bin B VB islt - (bin A VA isgt Alpha (bin X VX B1 Beta Gamma)) Delta) - = [bin X VX iseq (bin A VA B2 Alpha Beta) - (bin B VB B3 Gamma Delta), true] - when - [B2, B3] = table2 B1 - end; - - -/*** set, bag, dict and hdict stuff ***/ - -// Balance rules for insertions -// balance where balance whole tree to be -// before inserted after increased rebalanced -tablei iseq left = [islt, true, false]; -tablei iseq right = [isgt, true, false]; -tablei islt left = [iseq, false, true]; -tablei islt right = [iseq, false, false]; -tablei isgt left = [iseq, false, false]; -tablei isgt right = [iseq, false, true]; - -// Balance rules for deletions -// balance where balance whole tree to be -// before deleted after decreased rebalanced -tabled iseq right = [islt, false, false]; -tabled iseq left = [isgt, false, false]; -tabled islt right = [iseq, true, true]; -// ^^^^ -// It depends on the tree pattern in avl_geq whether it really decreases - -tabled islt left = [iseq, true, false]; -tabled isgt right = [iseq, true, false]; -tabled isgt left = [iseq, true, true]; -// ^^^^ -// It depends on the tree pattern in avl_geq whether it really decreases - - -table2 islt = [iseq, isgt]; -table2 isgt = [islt, iseq]; -table2 iseq = [iseq, iseq]; - - -/*** auxilliary stuff and interfaces between AVL trees and public functions ***/ - -size_set_bag nil - = 0; -size_set_bag (bin _ _ M1 M2) - = (size_set_bag M1) + (size_set_bag M2) + 1; - - -size_dict nil - = 0; -size_dict (bin _ _ _ D1 D2) - = (size_dict D1) + (size_dict D2) + 1; - - -size_hdict nil - = 0; -size_hdict (bin _ XYs _ D1 D2) - = (size_hdict D1) + (size_hdict D2) + #XYs; - - -member_set_bag nil _ - = 0; - -member_set_bag (bin X _ M1 M2) Y::int | -member_set_bag (bin X _ M1 M2) Y::string | -member_set_bag (bin X _ M1 M2) Y - = member_set_bag M1 Y if X > Y; - = member_set_bag M2 Y if X < Y; - = 1 if X == Y; - - -member_dict nil _ - = 0; - -member_dict (bin X _ _ M1 M2) Y::int | -member_dict (bin X _ _ M1 M2) Y::string | -member_dict (bin X _ _ M1 M2) Y - = member_dict M1 Y if X > Y; - = member_dict M2 Y if X < Y; - = 1 if X == Y; - - -member_hdict D X - = memberk_hdict D (hash X) X; - - -members_set_bag nil - = []; - -members_set_bag (bin X::int _ M1 M2) | -members_set_bag (bin X::string _ M1 M2) | -members_set_bag (bin X _ M1 M2) - = (members_set_bag M1) + (X : (members_set_bag M2)); - - -members_dict nil - = []; - -members_dict (bin X::int Y _ M1 M2) | -members_dict (bin X::string Y _ M1 M2) | -members_dict (bin X Y _ M1 M2) - = (members_dict M1) + ([X, Y] : (members_dict M2)); - - -members_hdict nil - = []; - -members_hdict (bin _ XYs _ D1 D2) - = members_hdict D1 + XYs + members_hdict D2; - - -keys_dict nil - = []; - -keys_dict (bin X::int _ _ M1 M2) | -keys_dict (bin X::string _ _ M1 M2) | -keys_dict (bin X _ _ M1 M2) - = (keys_dict M1) + (X : (keys_dict M2)); - - -keys_hdict nil - = []; - -keys_hdict (bin _ XYs _ D1 D2) - = keys_hdict D1 + map fst XYs + keys_hdict D2; - - -vals_dict nil - = []; - -vals_dict (bin _ Y _ M1 M2) - = (vals_dict M1) + (Y : (vals_dict M2)); - - -vals_hdict nil - = []; - -vals_hdict (bin _ XYs _ D1 D2) - = vals_hdict D1 + map snd XYs + vals_hdict D2; - - -first_set_bag (bin X _ nil _) - = X; - -first_set_bag (bin _ _ M1 _) - = first_set_bag M1; - - -first_dict (bin X Y _ nil _) - = [X, Y]; - -first_dict (bin _ _ _ D1 _) - = first_dict D1; - - -last_set_bag (bin X _ _ nil) - = X; - -last_set_bag (bin _ _ _ M2) - = last_set_bag M2; - - -last_dict (bin X Y _ _ nil) - = [X, Y]; - -last_dict (bin _ _ _ _ D2) - = last_dict D2; - - -key2val_dict nil _ - = throw out_of_bounds; - -key2val_dict (bin X::int Y _ D1 D2) X1::int | -key2val_dict (bin X::string Y _ D1 D2) X1::string | -key2val_dict (bin X Y _ D1 D2) X1 - = key2val_dict D1 X1 if X1 < X; - = key2val_dict D2 X1 if X1 > X; - = Y; - - -eq_set_bag M1 M2 - = members_set_bag M1 == members_set_bag M2; - -eq_dict D1 D2 - = members_dict D1 == members_dict D2; - - -eq_hdict D1 D2 - = if (all (member_hdict D1) (keys_hdict D2)) - then - if (all (member_hdict D2) (keys_hdict D1)) - then (vals_hdict D1) == (map ((!)D2) (keys D1)) - else 0 - else 0; - -neq_set_bag M1 M2 - = members_set_bag M1 != members_set_bag M2; - -neq_dict D1 D2 - = members_dict D1 != members_dict D2; - -neq_hdict D1 D2 - = not (D1 == D2); - - -leq_set M1 M2 - = all (member_set_bag M2) (members_set_bag M1); - -leq_bag M1 M2 - = (diff_set_bag M1 M2) == nil; - -geq_set M1 M2 - = all (member_set_bag M1) (members_set_bag M2); - -geq_bag M1 M2 - = (diff_set_bag M2 M1) == nil; - -lt_set M1 M2 - = if (leq_set M1 M2) then (neq_set_bag M1 M2) else 0; - -lt_bag M1 M2 - = if (leq_bag M1 M2) then (neq_set_bag M1 M2) else 0; - -gt_set M1 M2 - = if (geq_set M1 M2) then (neq_bag_set M1 M2) else 0; - -gt_bag M1 M2 - = if (geq_bag M1 M2) then (neq_bag_set M1 M2) else 0; - - -union_set M1 M2 - = foldl ins_set M1 (members_set_bag M2); - -union_bag M1 M2 - = foldl ins_bag M1 (members_set_bag M2); - -diff_set_bag M1 M2 - = foldl del_set_bag M1 (members_set_bag M2); - -intersect_set_bag M1 M2 - = diff_set_bag M1 (diff_set_bag M1 M2); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <js...@us...> - 2008-07-04 05:42:41
|
Revision: 381 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=381&view=rev Author: jspitz Date: 2008-07-03 22:42:48 -0700 (Thu, 03 Jul 2008) Log Message: ----------- Add dict data container to examples. Added Paths: ----------- pure/trunk/examples/dict.pure Added: pure/trunk/examples/dict.pure =================================================================== --- pure/trunk/examples/dict.pure (rev 0) +++ pure/trunk/examples/dict.pure 2008-07-04 05:42:48 UTC (rev 381) @@ -0,0 +1,578 @@ +/* Pure's dict and hdict data types based on AVL trees. */ + +/* Copyright (c) 2008 by Albert Graef <Dr....@t-...>. + Copyright (c) 2008 by Jiri Spitz <jir...@bl...>. + + This file is part of the Pure programming language and system. + + Pure is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or (at your option) any later + version. + + Pure 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 General Public License for more + details. + + You should have received a copy of the GNU General Public License along + with this program. If not, see <http://www.gnu.org/licenses/>. */ + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + The used algorithm of AVL trees has its origin in the SWI-Prolog + implementation of association lists. The original file was created by + R. A. O'Keefe and updated for the SWI-Prolog by Jan Wielemaker. For the + original file see http://www.swi-prolog.org. + + The port from SWI-Prolog and the deletion stuff (rmfirst, rmlast, delete) + missing in the original file was provided by Jiri Spitz +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + +/* Empty tree constant, consider this private. */ +nullary nil; + +/***** +Tree for dict and hdict is either: +- nil (empty tree) or +- bin Key value Balance Left Right (Left, Right: trees) + +Balance: ( 1), ( 0), or (-1) denoting |L|-|R| = 1, 0, or -1, respectively +*****/ + + +/* Public operations: ****************************************************** + +emptydict, emptyhdict: return the empty dict or bag +dict xs, hdict xs; create a dict or hdict from list xs +dictp x, hdictp x; check whether x is a dict or hdict +mkdict y xs, mkhdixt y xs: create dict or hdict from a list of keys and + a constant value + +#d size of dict or hdict d +d!x: get value from d by key x + +null d tests whether d is the empty dict or hdict +member d x tests whether d contains member with key x +members d, list d list members of d (in ascending order fo dict) +keys d: lists keys of d (in ascending order fo dict) +values d: list values of d + +first m, last m return first and last member of dict +rmfirst m, rmlast m remove first and last member from dict +insert m x insert x into d (replace existing element) +delete m x remove x from d + + *************************************************************************/ + + +// Dict and hdict type checks +dictp (Dict _) = 1; +dictp _ = 0; + +hdictp (Hdict _) = 1; +hdictp _ = 0; + +// create an empty dict or hdict +emptydict = Dict nil; +emptyhdict = Hdict nil; + +// create dict or hdict from a list +dict xys = foldl insert emptydict xys if listp xys; +hdict xys = foldl insert emptyhdict xys if listp xys; + +// insert a new member into the dict or hdict +insert (t@Dict d) [x::int, y] | +insert (t@Dict d) [x::string, y] | +insert (t@Dict d) [x, y] | +insert (t@Hdict d) [x, y] + = if t === Dict + then t ((insertd d x y)!0) + else t ((inserth d (hash x) x y)!0) +with + insertd nil key::int val | + insertd nil key::string val | + insertd nil key val + = [(bin key val ( 0) nil nil), 1]; + + insertd (bin k::int _ b l r) key::int val | + insertd (bin k::string _ b l r) key::string val | + insertd (bin k _ b l r) key val + = [(bin key val b l r), 0] if key == k; + + insertd (bin k::int v b l r) key::int val | + insertd (bin k::string v b l r) key::string val | + insertd (bin k v b l r) key val + = adjust leftHasChanged (bin k v b newl r) (-1) + when + [newl, leftHasChanged] = insertd l key val + end + if key < k; + + insertd (bin k::int v b l r) key::int val | + insertd (bin k::string v b l r) key::string val | + insertd (bin k v b l r) key val + = adjust rightHasChanged (bin k v b l newr) ( 1) + when + [newr, rightHasChanged] = insertd r key val + end + if key > k; + + inserth nil k::int x y = [(bin k [[x, y]] ( 0) nil nil), 1]; + + inserth (bin k::int v b l r) key::int x y + = [(bin k (inserth2 v x y) b l r), 0] if k == key; + + inserth (bin k::int v b l r) key::int x y + = adjust leftHasChanged (bin k v b newl r) (-1) + when + [newl, leftHasChanged] = inserth l key x y + end + if key < k; + + inserth (bin k::int v b l r) key::int x y + = adjust rightHasChanged (bin k v b l newr) ( 1) + when + [newr, rightHasChanged] = inserth r key x y + end + if key > k; + + inserth2 [] x y = [x, y]:[]; + inserth2 ([x1, y] :xys) x2 y1 = ([x1, y1]:xys) if x1 === x2; + inserth2 ([x, y] :xys) x1 y1 = ([x, y]:(inserth2 xys x1 y1)); + + adjust 0 oldTree _ = [oldTree, 0]; + + adjust 1 (bin key::int val b0 l r) LoR | + adjust 1 (bin key::string val b0 l r) LoR | + adjust 1 (bin key val b0 l r) LoR + = [rebal toBeRebalanced (bin key val b0 l r) b1, whatHasChanged] + when + [b1, whatHasChanged, toBeRebalanced] = table b0 LoR + end; + + rebal 0 (bin k::int v _ l r) b | + rebal 0 (bin k::string v _ l r) b | + rebal 0 (bin k v _ l r) b + = bin k v b l r; + + rebal 1 oldTree _ = (Dict_avl_geq oldTree)!0; + +// Balance rules for insertions +// balance where balance whole tree to be +// before inserted after increased rebalanced +table ( 0) (-1) = [( 1), 1, 0]; +table ( 0) ( 1) = [(-1), 1, 0]; +table ( 1) (-1) = [( 0), 0, 1]; +table ( 1) ( 1) = [( 0), 0, 0]; +table (-1) (-1) = [( 0), 0, 0]; +table (-1) ( 1) = [( 0), 0, 1] +end; + +// delete a member by key from the dict or hdict +delete (t@Dict d) x::int | +delete (t@Dict d) x::string | +delete (t@Dict d) x | +delete (t@Hdict d) x + = if t === Dict + then t ((deleted d x)!0) + else t ((deleteh d (hash x) x)!0) +with + deleted nil _ = [nil, 0]; + + deleted (bin k::int _ _ nil r ) key::int | + deleted (bin k::string _ _ nil r ) key::string | + deleted (bin k _ _ nil r ) key + = [r, 1] if key == k; + + deleted (bin k::int _ _ l nil) key::int | + deleted (bin k::string _ _ l nil) key::string | + deleted (bin k _ _ l nil) key + = [l, 1] if key == k; + + deleted (bin k::int _ b (bin kl::int vl bl rl ll) r ) key::int | + deleted (bin k::string _ b (bin kl::string vl bl rl ll) r ) key::string | + deleted (bin k _ b (bin kl vl bl rl ll) r ) key + = Dict_adjustd leftHasChanged (bin lastk lastv b newl r) (-1) + when + [lastk, lastv] = last (bin kl vl bl rl ll); + [newl, leftHasChanged] + = rmlast (bin kl vl bl rl ll) + end + if key == k; + + deleted (bin k::int v b l r) key::int | + deleted (bin k::string v b l r) key::string | + deleted (bin k v b l r) key + = Dict_adjustd leftHasChanged (bin k v b newl r) (-1) + when + [newl, leftHasChanged] = deleted l key + end + if key < k; + + deleted (bin k::int v b l r) key::int | + deleted (bin k::string v b l r) key::string | + deleted (bin k v b l r) key + = Dict_adjustd rightHasChanged (bin k v b l newr) ( 1) + when + [newr, rightHasChanged] = deleted r key + end + if key > k; + + deleteh nil _ _ = [nil, 0]; + + deleteh (bin k::int xys b nil r ) key::int x + = (if (newxys == []) + then [r, 1] + else [bin k newxys b nil r, 0]) + when + newxys = deleteh2 xys x + end + if k == key; + + deleteh (bin k::int xys b l nil) key::int x + = (if (newxys == []) + then [l, 1] + else [bin k newxys b l nil, 0]) + when + newxys = deleteh2 xys x + end + if k == key; + + deleteh (bin k::int xys b (bin kl vl bl rl ll) r) key::int x + = Dict_adjustd leftHasChanged (bin lastk lastv b newl r) (-1) + when + [lastk, lastv] = last (bin kl vl bl rl ll); + [newl, leftHasChanged] = rmlast (bin kl vl bl rl ll) + end + if (k == key) && ((deleteh2 xys x) == []); + + deleteh (bin k::int xys b l r) key::int x + = [bin key (deleteh2 xys x) b l r, 0] + if k == key; + + deleteh (bin k::int v b l r) key::int x + = Dict_adjustd leftHasChanged (bin k v b newl r) (-1) + when + [newl, leftHasChanged] = deleteh l key x + end + if key < k; + + deleteh (bin k::int v b l r) key::int x + = Dict_adjustd rightHasChanged (bin k v b l newr) ( 1) + when + [newr, rightHasChanged] = deleteh r key x + end + if key > k; + + deleteh2 [] _ = []; + deleteh2 ([x1 ,_] : xys) x2 = xys if x1 === x2; + deleteh2 ([x, y] : xys) x1 = [x, y] : (deleteh2 xys x1); + + rmlast nil = [nil, 0]; + rmlast (bin _ _ _ l nil) = [l, 1]; + rmlast (bin k v b::int l r ) + = Dict_adjustd rightHasChanged (bin k v b l newr) ( 1) + when [newr, rightHasChanged] = rmlast r end; + + last (bin x y _ _ nil) = [x, y]; + last (bin _ _ _ _ d2 ) = last d2 +end; + + +// create dict or hdict from a list of keys and a constant value +mkdict y xs = dict (zip xs (repeat (#xs) y)) if listp xs; +mkhdict y xs = hdict (zip xs (repeat (#xs) y)) if listp xs; + +// check for the empty dict or hdict +null (Dict nil) = 1; +null (Dict _) = 0; + +null (Hdict nil) = 1; +null (Hdict _) = 0; + +// get a number of members in dict or hdict +#(Dict d) = #d +with + #nil = 0; + #(bin _ _ _ d1 d2) = #d1 + #d2 + 1 +end; + +#(Hdict d) = size d +with + size nil = 0; + size (bin _ xys _ d1 d2) = size d1 + size d2 + #xys +end; + +// check whether a key in dict or hdict +member (Dict d) k::int | +member (Dict d) k::string | +member (Dict d) k = member d k +with + member nil _ = 0; + + member (bin x _ _ d1 d2) y::int | + member (bin x _ _ d1 d2) y::string | + member (bin x _ _ d1 d2) y + = member d1 y if x > y; + = member d2 y if x < y; + = 1 if x == y +end; + +member (Hdict d) k = member d (hash k) k +with + member nil _ _ = 0; + member (bin k::int xys _ d1 d2) k1::int x1 + = member d1 k1 x1 if k > k1; + = member d2 k1 x1 if k < k1; + = memberk xys x1; + + memberk [] _ = 0; + memberk ([x1, y]:_ ) x2 = 1 if x1 === x2; + memberk ( _:xys) x2 = memberk xys x2 +end;; + +// get all members of dict or hdict +members (Dict d) = members d +with + members nil = []; + + members (bin x::int y _ d1 d2) | + members (bin x::string y _ d1 d2) | + members (bin x y _ d1 d2) + = members d1 + ([x, y] : (members d2)) +end; + +members (Hdict d) = members d +with + members nil = []; + members (bin _ xys _ d1 d2) = members d1 + xys + members d2 +end; + +list d@(Dict _) | +list d@(Hdict _) = members d; + +// get the first member of a dict +first (Dict d) = first d +with + first (bin x y _ nil _) = [x, y]; + first (bin _ _ _ d1 _) = first d1 +end; + +// get the last member of a dict +last (Dict d) = last d +with + last (bin x y _ _ nil) = [x, y]; + last (bin _ _ _ _ d2 ) = last d2 +end; + +// remove the first member from a dict +rmfirst (Dict d) = Dict ((rmfirst d)!0) +with + rmfirst nil = [nil, 0]; + rmfirst (bin _ _ _ nil r) = [r, 1]; + rmfirst (bin k v b l r) + = Dict_adjustd leftHasChanged (bin k v b newl r) (-1) + when + [newl, leftHasChanged] = rmfirst l + end +end; + +// remove the last member from a dict +rmlast (Dict d) = Dict ((rmlast d)!0) +with + rmlast nil = [nil 0]; + rmlast (bin _ _ _ l nil) = [l, 1]; + rmlast (bin k v b l r) + = Dict_adjustd rightHasChanged (bin k v b l newr) ( 1) + when + [newr, rightHasChanged] = rmlast r + end +end; + +// get a list of all keys from dict or hdict +keys (Dict d) = keys d +with + keys nil = []; + + keys (bin x::int _ _ d1 d2) | + keys (bin x::string _ _ d1 d2) | + keys (bin x _ _ d1 d2) + = keys d1 + (x : (keys d2)) +end; + +keys (Hdict d) = keys d +with + keys nil = []; + keys (bin _ xys _ d1 d2) = keys d1 + map (\d -> d!0) xys + keys d2 +end; + +// get a list of all values from dict or hdict +vals (Dict d) = vals d +with + vals nil = []; + vals (bin _ y _ d1 d2) = vals d1 + (y : (vals d2)) +end; + +vals (Hdict d) = vals d +with + vals nil = []; + vals (bin _ xys _ d1 d2) = vals d1 + map (\d -> d!1) xys + vals d2 +end; + +// get a value by key from dict or hdict +(Dict d)!k::int | +(Dict d)!k::string | +(Dict d)!k = d!k +with + nil!_ = throw out_of_bounds; + + (bin x::int y _ d1 d2)!x1::int | + (bin x::string y _ d1 d2)!x1::string | + (bin x y _ d1 d2)!x1 + = d1!x1 if x1 < x; + = d2!x1 if x1 > x; + = y +end; + +(Hdict d)!k = lookup d (hash k) k +with + lookup nil _ _ = throw out_of_bounds; + + lookup (bin k::int xys _ d1 d2) k1::int x1 + = lookup d1 k1 x1 if k > k1; + = lookup d2 k1 x1 if k < k1; + = lookupk xys x1; + + lookupk [] _ = throw out_of_bounds; + lookupk ([xa,y]: _) xb = y if xa === xb; + lookupk ( _ :xys) x = lookupk xys x +end; + +// curried version of insert for dict and hdict +update d@(Dict _) x::int y | +update d@(Dict _) x::string y | +update d@(Dict _) x y | +update d@(Hdict _) x y + = insert d [x, y]; + +// equality checks for dict and hdict +(Dict d1) == (Dict d2) = (members d1) == (members d2); + +(Hdict d1) == (Hdict d2) + = if (all (member d1) (keys d2)) + then + if (all (member d2) (keys d1)) + then (vals d1) == (map ((!)d2) (keys d1)) + else 0 + else 0; + + +// inequality checks for dict and hdict +(Dict d1) != (Dict d2) = (members d1) != (members d2); +(Hdict d1) != (Hdict d2) = not (d1 == d2); + + +/* Private functions, don't invoke these directly. */ + +Dict_adjustd ToF::int tree LoR::int + = adjust ToF tree LoR +with + adjust 0 oldTree _ = [oldTree, 0]; + + adjust 1 (bin key::int val b0 l r) LoR | + adjust 1 (bin key::string val b0 l r) LoR | + adjust 1 (bin key val b0 l r) LoR + = rebal toBeRebalanced (bin key val b0 l r) b1 whatHasChanged + when + [b1, whatHasChanged, toBeRebalanced] = tabled b0 LoR + end; + + rebal 0 (bin k::int v _ l r) b whatHasChanged | + rebal 0 (bin k::string v _ l r) b whatHasChanged | + rebal 0 (bin k v _ l r) b whatHasChanged + = [bin k v b l r, whatHasChanged]; + + rebal 1 oldTree _ _ = Dict_avl_geq oldTree; + +// Balance rules for deletions +// balance where balance whole tree to be +// before deleted after decreased rebalanced +tabled ( 0) ( 1) = [( 1), 0, 0]; +tabled ( 0) (-1) = [(-1), 0, 0]; +tabled ( 1) ( 1) = [( 0), 1, 1]; +// ^^^^ +// It depends on the tree pattern in avl_geq whether it really decreases + +tabled ( 1) (-1) = [( 0), 1, 0]; +tabled (-1) ( 1) = [( 0), 1, 0]; +tabled (-1) (-1) = [( 0), 1, 1]; +// ^^^^ +// It depends on the tree pattern in avl_geq whether it really decreases +end; + +// Single and double tree rotations - these are common for insert and delete +/* + The patterns (-1)-(-1), (-1)-( 1), ( 1)-( 1) and ( 1)-(-1) on the LHS always + change the tree height and these are the only patterns which can happen + after an insertion. That's the reason why we can use tablei only to decide + the needed changes. + The patterns (-1)-( 0) and ( 1)-( 0) do not change the tree height. After a + deletion any pattern can occur and so we return 1 or 0 as a flag of + a height change. +*/ +Dict_avl_geq d = avl_geq d +with + avl_geq (bin a::int va (-1) alpha (bin b::int vb (-1) beta gamma)) | + avl_geq (bin a::string va (-1) alpha (bin b::string vb (-1) beta gamma)) | + avl_geq (bin a va (-1) alpha (bin b vb (-1) beta gamma)) + = [bin b vb ( 0) (bin a va ( 0) alpha beta) gamma, 1]; + + avl_geq (bin a::int va (-1) alpha (bin b::int vb ( 0) beta gamma)) | + avl_geq (bin a::string va (-1) alpha (bin b::string vb ( 0) beta gamma)) | + avl_geq (bin a va (-1) alpha (bin b vb ( 0) beta gamma)) + = [bin b vb ( 1) (bin a va (-1) alpha beta) gamma, 0]; + // the tree doesn't decrease with this pattern + + avl_geq (bin a::int va (-1) alpha + (bin b::int vb ( 1) + (bin x::int vx b1 beta gamma) delta)) | + avl_geq (bin a::string va (-1) alpha + (bin b::string vb ( 1) + (bin x::string vx b1 beta gamma) delta)) | + avl_geq (bin a va (-1) alpha + (bin b vb ( 1) (bin x vx b1 beta gamma) delta)) + = [bin x vx ( 0) (bin a va b2 alpha beta) (bin b vb b3 gamma delta), 1] + when + [b2, b3] = table b1 + end; + + avl_geq (bin b::int vb ( 1) (bin a::int va ( 1) alpha beta) gamma) | + avl_geq (bin b::string vb ( 1) (bin a::string va ( 1) alpha beta) gamma) | + avl_geq (bin b vb ( 1) (bin a va ( 1) alpha beta) gamma) + = [bin a va ( 0) alpha (bin b vb ( 0) beta gamma), 1]; + + avl_geq (bin b::int vb ( 1) (bin a::int va ( 0) alpha beta) gamma) | + avl_geq (bin b::string vb ( 1) (bin a::string va ( 0) alpha beta) gamma) | + avl_geq (bin b vb ( 1) (bin a va ( 0) alpha beta) gamma) + = [bin a va (-1) alpha (bin b vb ( 1) beta gamma), 0]; + // the tree doesn't decrease with this pattern + + avl_geq (bin b::int vb ( 1) + (bin a::int va (-1) alpha + (bin x::int vx b1 beta gamma)) delta) | + avl_geq (bin b::string vb ( 1) + (bin a::string va (-1) alpha + (bin x::string vx b1 beta gamma)) delta) | + avl_geq (bin b vb ( 1) + (bin a va (-1) alpha (bin x vx b1 beta gamma)) delta) + = [bin x vx ( 0) (bin a va b2 alpha beta) (bin b vb b3 gamma delta), 1] + when + [b2, b3] = table b1 + end; + + table ( 1) = [( 0), (-1)]; + table (-1) = [( 1), ( 0)]; + table ( 0) = [( 0), ( 0)] +end; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <js...@us...> - 2008-07-04 05:40:22
|
Revision: 380 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=380&view=rev Author: jspitz Date: 2008-07-03 22:40:30 -0700 (Thu, 03 Jul 2008) Log Message: ----------- Update comments. Modified Paths: -------------- pure/trunk/lib/set.pure Modified: pure/trunk/lib/set.pure =================================================================== --- pure/trunk/lib/set.pure 2008-07-04 00:07:53 UTC (rev 379) +++ pure/trunk/lib/set.pure 2008-07-04 05:40:30 UTC (rev 380) @@ -63,10 +63,10 @@ *****/ // set and bag type checks -bagp (Bag _) = 1; +bagp (Bag _) = 1; bagp _ = 0; -setp (Set _) = 1; +setp (Set _) = 1; setp _ = 0; // create an empty set or bag @@ -197,14 +197,14 @@ last (bin _ _ _ m2 ) = last m2 end; -// check for the empty data structure +// check for the empty set or bag null (Set nil) = 1; null (Set _) = 0; null (Bag nil) = 1; null (Bag _) = 0; -// get a number of members in data structure +// get a number of members in set or bag #(Set m) | #(Bag m) = #m with @@ -212,7 +212,7 @@ #(bin _ _ m1 m2) = #m1 + #m2 + 1 end; -// check whether a key exists in data structure +// check whether a key exists in set or bag member (Set m) k::int | member (Set m) k::string | member (Set m) k | @@ -231,7 +231,7 @@ = 1 if x == y end; -// get all members of data structure as a list +// get all members of set or bag as a list members (Set m) | members (Bag m) = members m @@ -248,7 +248,7 @@ list m@(Bag _) = members m; -// get the first member of an ordered data structure +// get the first member of set or bag first (Set m) | first (Bag m) = first m @@ -257,7 +257,7 @@ first (bin _ _ m1 _) = first m1 end; -// get the last member of an ordered data structure +// get the last member of set or bag last (Set m) | last (Bag m) = last m @@ -266,7 +266,7 @@ last (bin _ _ _ m2 ) = last m2 end; -// remove the first member from an ordered data structure +// remove the first member from set or bag rmfirst (t@Set m) | rmfirst (t@Bag m) = t ((rmfirst m)!0) @@ -278,7 +278,7 @@ when [newL, leftHasChanged] = rmfirst l end end; -// remove the last member from an ordered data structure +// remove the last member from set or bag rmlast (t@Set m) | rmlast (t@Bag m) = t ((rmlast m)!0) @@ -332,7 +332,7 @@ /* Private functions, don't invoke these directly. */ Set_adjustd ToF::int tree LoR::int -= adjust ToF tree LoR + = adjust ToF tree LoR with adjust 0 oldTree _ = [oldTree, 0]; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ye...@us...> - 2008-07-04 00:07:44
|
Revision: 379 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=379&view=rev Author: yes Date: 2008-07-03 17:07:53 -0700 (Thu, 03 Jul 2008) Log Message: ----------- Moved time calculation utilities from myutils.pure to date.pure and added up-to-the-second time functionality to date.pure Modified Paths: -------------- pure/trunk/examples/libor/date.pure pure/trunk/examples/libor/myutils.pure Modified: pure/trunk/examples/libor/date.pure =================================================================== --- pure/trunk/examples/libor/date.pure 2008-07-03 11:04:10 UTC (rev 378) +++ pure/trunk/examples/libor/date.pure 2008-07-04 00:07:53 UTC (rev 379) @@ -1,6 +1,11 @@ -// Mayan Calendar - Copyright (c) 2008 by Libor Spacek -// Usage: pure -x date.pure [-h]] +/* Mayan Calendar - Copyright (c) 2008 by Libor Spacek + Usage: pure -x date.pure [-h] + + Discrepancies with your local clock may occur when C library's time(); + returns Posix time based on UTC (Universel Temps Coordonné) or TAI + (Temps Atomique Internacional) rather than local daylight saving time */ + using system; extern int time(); @@ -11,11 +16,32 @@ def endofdays = 15695; // posix days at the end of the cycle (13th baktun) def secsinday = 86400; // number of seconds in a day def cycledays = mayan2days (13:0:0:0:0); +def year = 365.242374; +def cycleyears = cycledays / year; // time now in posix seconds converted to whole days -posixdays = tm div secsinday when tm = time end; +posixsecsnow = time; // call posixsecsnow to refresh the current time +posixdays = posixsecsnow div secsinday; +secsnow = posixsecsnow mod secsinday; + +// time calculations on the usual days:hours:minutes:seconds format +dhms2secs (d::int:h::int:m::int:s) = 60.0*(60*(24*d+h)+m)+s; +// secs are usually double and can be int or bigint but d,h,m are always ints +secs2dhms secs = + d:(h mod 24):(m mod 60):(secs-60.0*m) + when + m::int = int (secs / 60); + h::int = m div 60; + d::int = h div 24 + end; + +// an arbitrary binary operator applied to two (days,hours,minutes,seconds) +opdhms op (d1::int:h1::int:m1::int:s1)(d2::int:h2::int:m2::int:s2) = + secs2dhms (op (dhms2secs (d1:h1:m1:s1)) (dhms2secs (d2:h2:m2:s2))); + +// Now follows the Mayan Calendar -// not used yet but could be: addmayan posixepoch (days2mayan posixdays) +// not used yet but could be, as in: addmayan posixepoch (days2mayan posixdays) addmayan (baktun1::int:katun1::int:tun1::int:vinal1::int:kin1::int) (baktun2::int:katun2::int:tun2::int:vinal2::int:kin2::int) = baktun:(katun mod 20):(tun mod 20):(vinal mod 18):(kin mod 20) @@ -38,17 +64,20 @@ mayantoday = days2mayan daytoday; daysleft = endofdays - posixdays; mayanleft = days2mayan daysleft; -percentcomplete = 100.0 * daytoday / cycledays; +percentcomplete = 100.0*(epochday+posixsecsnow/secsinday)/cycledays; usage = puts "Usage: pure -x date.pure [anyarg]" $ puts "\tanyarg for help"; case argc of - 1 = void (printf "Mayan long count today: %s = day %d of this cycle\n" - ((str mayantoday), (mayan2days mayantoday))) $ - void (printf "Mayan count down today: %s = %d days left till the end\n" - ((str mayanleft), daysleft)) $ - void (printf "The Cycle is %f%% complete!\n" percentcomplete); + 1 = + void (printf "Posix time now: %s\n" (str (secs2dhms posixsecsnow))) $ + void (printf "Mayan long count date: %s = day %d\n" + ((str mayantoday), (mayan2days mayantoday))) $ + void (printf "Mayan countdown today: %s = %d days till the cycle ends\n" + ((str mayanleft), daysleft)) $ + void (printf "The Mayan cycle of over %d years " (int cycleyears)) $ + void (printf "is now %11.8f%% complete!\n" percentcomplete); 2 = void (puts "Mayan long count digits (and their range of values):") $ void (puts "Baktun(0-12):Katun(0-19):Tun(0-19):Vinal(0-17):Kin(0-19)")$ puts "Baktun=144000days:Katun=7200days:Tun=360days:Vinal=20days:Kin=1day"$ Modified: pure/trunk/examples/libor/myutils.pure =================================================================== --- pure/trunk/examples/libor/myutils.pure 2008-07-03 11:04:10 UTC (rev 378) +++ pure/trunk/examples/libor/myutils.pure 2008-07-04 00:07:53 UTC (rev 379) @@ -36,28 +36,3 @@ // what time is 33 hrs before midnight? Answer: 15 hrs. nrotate n::int l = protate nm l when ll = #l; nm = ll + (n mod ll) end if n<0; = protate nm l when nm = n mod #l end; - -//(3) Time Calculations - seconds can be int or double or bigint. d,h,m are ints -dhms2secs (d::int,h::int,m::int,s::int) | -dhms2secs (d::int,h::int,m::int,s::double) | -dhms2secs (d::int,h::int,m::int,s::bigint) = 60*(60*(24*d+h)+m)+s; - -secs2dhms secs::int | secs2dhms secs::bigint = - (int d),(int (h mod 24)),(int (m mod 60)),(int (secs mod 60)) - when - m = secs div 60; - h = m div 60; - d = h div 24 - end; -secs2dhms secs::double = - (int d),(int (h mod 24)),(int (m mod 60)),(int (isecs mod 60))+(secs-isecs) - when isecs = (bigint secs); - m = isecs div 60; - h = m div 60; - d = h div 24 - end; - -// an arbitrary binary operator applied to two (days,hours,minutes,seconds) -opdhms op (d1::int,h1::int,m1::int,s1)(d2::int,h2::int,m2::int,s2) = - secs2dhms (op (dhms2secs (d1,h1,m1,s1)) (dhms2secs (d2,h2,m2,s2))); - \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ye...@us...> - 2008-07-03 11:04:03
|
Revision: 378 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=378&view=rev Author: yes Date: 2008-07-03 04:04:10 -0700 (Thu, 03 Jul 2008) Log Message: ----------- fixed some minor typos in comments, added Mayan Calendar curiosity, see added file examples/libor/date.pure Modified Paths: -------------- pure/trunk/examples/libor/myutils.pure pure/trunk/examples/libor/queens.pure Added Paths: ----------- pure/trunk/examples/libor/date.pure Added: pure/trunk/examples/libor/date.pure =================================================================== --- pure/trunk/examples/libor/date.pure (rev 0) +++ pure/trunk/examples/libor/date.pure 2008-07-03 11:04:10 UTC (rev 378) @@ -0,0 +1,57 @@ +// Mayan Calendar - Copyright (c) 2008 by Libor Spacek +// Usage: pure -x date.pure [-h]] + +using system; +extern int time(); + +puts "Mayan Calendar, Copyright (c) 2008 by Libor Spacek"; + +def posixepoch = (12:17:16:7:5); // Mayan long count date of the posix epoch +def epochday = mayan2days posixepoch; // Mayan day of the posix epoch +def endofdays = 15695; // posix days at the end of the cycle (13th baktun) +def secsinday = 86400; // number of seconds in a day +def cycledays = mayan2days (13:0:0:0:0); + +// time now in posix seconds converted to whole days +posixdays = tm div secsinday when tm = time end; + +// not used yet but could be: addmayan posixepoch (days2mayan posixdays) +addmayan (baktun1::int:katun1::int:tun1::int:vinal1::int:kin1::int) + (baktun2::int:katun2::int:tun2::int:vinal2::int:kin2::int) = + baktun:(katun mod 20):(tun mod 20):(vinal mod 18):(kin mod 20) + when + kin = kin1+kin2; vinal = vinal1+vinal2+(kin div 20); + tun = tun1+tun2+(vinal div 18); katun = katun1+katun2+(tun div 20); + baktun = baktun1+baktun2+(katun div 20) + end; + +days2mayan d::int = baktun:(katun mod 20):(tun mod 20):(vinal mod 18):(d mod 20) + when + vinal =d div 20; tun =vinal div 18; katun =tun div 20; baktun =katun div 20 + end; + +mayan2days (baktun::int:katun::int:tun::int:vinal::int:kin::int) = + 20*(18*(20*(20*baktun+katun)+tun)+vinal)+kin; + +// simple calculations to print +daytoday = epochday + posixdays; +mayantoday = days2mayan daytoday; +daysleft = endofdays - posixdays; +mayanleft = days2mayan daysleft; +percentcomplete = 100.0 * daytoday / cycledays; + +usage = puts "Usage: pure -x date.pure [anyarg]" $ + puts "\tanyarg for help"; + +case argc of + 1 = void (printf "Mayan long count today: %s = day %d of this cycle\n" + ((str mayantoday), (mayan2days mayantoday))) $ + void (printf "Mayan count down today: %s = %d days left till the end\n" + ((str mayanleft), daysleft)) $ + void (printf "The Cycle is %f%% complete!\n" percentcomplete); + 2 = void (puts "Mayan long count digits (and their range of values):") $ + void (puts "Baktun(0-12):Katun(0-19):Tun(0-19):Vinal(0-17):Kin(0-19)")$ + puts "Baktun=144000days:Katun=7200days:Tun=360days:Vinal=20days:Kin=1day"$ + usage; + n = usage otherwise +end; Modified: pure/trunk/examples/libor/myutils.pure =================================================================== --- pure/trunk/examples/libor/myutils.pure 2008-07-03 05:19:00 UTC (rev 377) +++ pure/trunk/examples/libor/myutils.pure 2008-07-03 11:04:10 UTC (rev 378) @@ -57,6 +57,7 @@ d = h div 24 end; -// an arbitrary binary operator applied to two days:hours:minutes:seconds +// an arbitrary binary operator applied to two (days,hours,minutes,seconds) opdhms op (d1::int,h1::int,m1::int,s1)(d2::int,h2::int,m2::int,s2) = - secs2dhms (op (dhms2secs (d1,h1,m1,s1)) (dhms2secs (d2,h2,m2,s2))); \ No newline at end of file + secs2dhms (op (dhms2secs (d1,h1,m1,s1)) (dhms2secs (d2,h2,m2,s2))); + \ No newline at end of file Modified: pure/trunk/examples/libor/queens.pure =================================================================== --- pure/trunk/examples/libor/queens.pure 2008-07-03 05:19:00 UTC (rev 377) +++ pure/trunk/examples/libor/queens.pure 2008-07-03 11:04:10 UTC (rev 378) @@ -77,8 +77,8 @@ halfn::int = n div 2; // local variable halfn start::int = if (n mod 3) then (halfn-1) else 1;//(n mod 3) is special start2::int = n-((start + 2*(halfn-1)) mod n)-1 // start reflections - end if (n mod 2) == 0; // even sized boards finished - = 0:(map succ (thequeens (n-1))) // corner start 0: solves odd size boards! + end if (n mod 2) == 0; // even sized boards finished + = 0:(map succ (thequeens (n-1))) // corner start 0: solves odd size boards! end; // end of case and thequeens This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <js...@us...> - 2008-07-03 05:18:54
|
Revision: 377 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=377&view=rev Author: jspitz Date: 2008-07-02 22:19:00 -0700 (Wed, 02 Jul 2008) Log Message: ----------- Move set.pure to lib, add test015 Added Paths: ----------- pure/trunk/lib/set.pure pure/trunk/test/test015.log pure/trunk/test/test015.pure Removed Paths: ------------- pure/trunk/examples/set.pure Deleted: pure/trunk/examples/set.pure =================================================================== --- pure/trunk/examples/set.pure 2008-07-03 00:23:57 UTC (rev 376) +++ pure/trunk/examples/set.pure 2008-07-03 05:19:00 UTC (rev 377) @@ -1,438 +0,0 @@ -/* Pure's set and bag data types based on AVL trees. */ - -/* Copyright (c) 2008 by Albert Graef <Dr....@t-...>. - Copyright (c) 2008 by Jiri Spitz <jir...@bl...>. - - This file is part of the Pure programming language and system. - - Pure is free software: you can redistribute it and/or modify it under the - terms of the GNU General Public License as published by the Free Software - Foundation, either version 3 of the License, or (at your option) any later - version. - - Pure 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 General Public License for more - details. - - You should have received a copy of the GNU General Public License along - with this program. If not, see <http://www.gnu.org/licenses/>. */ - - -/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - The used algorithm of AVL trees has its origin in the SWI-Prolog - implementation of association lists. The original file was created by - R. A. O'Keefe and updated for the SWI-Prolog by Jan Wielemaker. For the - original file see http://www.swi-prolog.org. - - The port from SWI-Prolog and the deletion stuff (rmfirst, rmlast, delete) - missing in the original file was provided by Jiri Spitz -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ - - -/* Public operations: ****************************************************** - -emptyset, emptybag: return the empty set or bag -set xs, bag xs; create a set or bag from list xs -setp x, bagp x; check whether x is a set or bag - -#m size of set or bag m - -null m tests whether m is the empty set or bag -member m x tests whether m contains x -members m, list m list members of m in ascending order - -first m, last m return first and last member of m -rmfirst m, rmlast m remove first and last member from m -insert m x insert x into m (replace existing element) -delete m x remove x from m - - *************************************************************************/ - - -/* Empty tree constant, consider this private. */ -nullary nil; - -/***** -Tree for set and bag is either: -- nil (empty tree) or -- bin key Balance Left Right (Left, Right: trees) - - -Balance: ( 1), ( 0), or (-1) denoting |L|-|R| = 1, 0, or -1, respectively -*****/ - -// set and bag type checks -bagp (Bag _) = 1; -bagp _ = 0; - -setp (Set _) = 1; -setp _ = 0; - -// create an empty set or bag -emptyset = Set nil; -emptybag = Bag nil; - -// create set or bag from a list -set xs = foldl insert emptyset xs if listp xs; -bag xs = foldl insert emptybag xs if listp xs; - -// insert a new member into a set or bag -insert (t@Set m) y::int | -insert (t@Set m) y::string | -insert (t@Set m) y | -insert (t@Bag m) y::int | -insert (t@Bag m) y::string | -insert (t@Bag m) y = t ((insert m y)!0) -with - insert nil key::int | - insert nil key::string | - insert nil key - = [(bin key ( 0) nil nil), 1]; - - insert (bin k::int b::int l r) key::int | - insert (bin k::string b::int l r) key::string | - insert (bin k b::int l r) key - = [(bin key b l r), 0] if (key == k) && (t === Set); - - insert (bin k::int b::int l r) key::int | - insert (bin k::string b::int l r) key::string | - insert (bin k b::int l r) key - = adjust leftHasChanged (bin k b newL r) (-1) - when [newL, leftHasChanged] = insert l key end if key < k; - - insert (bin k::int b::int l r) key::int | - insert (bin k::string b::int l r) key::string | - insert (bin k b::int l r) key - = adjust rightHasChanged (bin k b l newR) ( 1) - when [newR, rightHasChanged] = insert r key end - if ((key > k) && (t === Set)) || ((key >= k) && (t === Bag)); - - adjust 0 oldTree _ - = [oldTree, 0]; - - adjust 1 (bin key::int b0::int l r) LoR::int | - adjust 1 (bin key::string b0::int l r) LoR::int | - adjust 1 (bin key b0::int l r) LoR::int - = [rebal toBeRebalanced (bin key b0 l r) b1, whatHasChanged] - when - [b1, whatHasChanged, toBeRebalanced] = table b0 LoR - end; - - rebal 0 (bin k::int _ l r) b | - rebal 0 (bin k::string _ l r) b | - rebal 0 (bin k _ l r) b - = bin k b l r; - - rebal 1 oldTree _ - = (Set_avl_geq oldTree)!0; - -// Balance rules for insertions -// balance where balance whole tree to be -// before inserted after increased rebalanced -table ( 0) (-1) = [( 1), 1, 0]; -table ( 0) ( 1) = [(-1), 1, 0]; -table ( 1) (-1) = [( 0), 0, 1]; -table ( 1) ( 1) = [( 0), 0, 0]; -table (-1) (-1) = [( 0), 0, 0]; -table (-1) ( 1) = [( 0), 0, 1]; -end; - -// delete a member by key from the data structure -delete (t@Set m) y::int | -delete (t@Set m) y::string | -delete (t@Set m) y | -delete (t@Bag m) y::int | -delete (t@Bag m) y::string | -delete (t@Bag m) y -= t ((delete m y)!0) -with - delete nil _ = [nil, 0]; - - delete (bin k::int _ nil r) key::int | - delete (bin k::string _ nil r) key::string | - delete (bin k _ nil r) key - = [r, 1] if key == k; - - delete (bin k::int _ l nil) key::int | - delete (bin k::string _ l nil) key::string | - delete (bin k _ l nil) key - = [l, 1] if key == k; - - delete (bin k::int b::int x@(bin kl::int bl::int rl ll) r) key::int | - delete (bin k::string b::int x@(bin kl::string bl::int rl ll) r) key::string | - delete (bin k b::int x@(bin kl bl::int rl ll) r) key - = Set_adjustd leftHasChanged (bin lk b newL r) (-1) - when - lk = last x; - [newL, leftHasChanged] = rmlast x - end - if key == k; - - delete (bin k::int b::int l r) key::int | - delete (bin k::string b::int l r) key::string | - delete (bin k b::int l r) key - = Set_adjustd leftHasChanged (bin k b newL r) (-1) - when - [newL, leftHasChanged] = delete l key - end - if key < k; - - delete (bin k::int b::int l r) key::int | - delete (bin k::string b::int l r) key::string | - delete (bin k b::int l r) key - = Set_adjustd rightHasChanged (bin k b l newR) ( 1) - when - [newR, rightHasChanged] = delete r key - end - if key > k; - - rmlast nil = [nil, 0]; - rmlast (bin _ _ l nil) = [l, 1]; - rmlast (bin k b::int l r ) - = Set_adjustd rightHasChanged (bin k b l newR) ( 1) - when [newR, rightHasChanged] = rmlast r end; - - last (bin x _ _ nil) = x; - last (bin _ _ _ m2 ) = last m2 -end; - -// check for the empty data structure -null (Set nil) = 1; -null (Set _) = 0; - -null (Bag nil) = 1; -null (Bag _) = 0; - -// get a number of members in data structure -#(Set m) | -#(Bag m) = #m -with - #nil = 0; - #(bin _ _ m1 m2) = #m1 + #m2 + 1 -end; - -// check whether a key exists in data structure -member (Set m) k::int | -member (Set m) k::string | -member (Set m) k | -member (Bag m) k::int | -member (Bag m) k::string | -member (Bag m) k -= member m k -with - member nil _ = 0; - - member (bin x _ m1 m2) y::int | - member (bin x _ m1 m2) y::string | - member (bin x _ m1 m2) y - = member m1 y if x > y; - = member m2 y if x < y; - = 1 if x == y -end; - -// get all members of data structure as a list -members (Set m) | -members (Bag m) -= members m -with - members nil = []; - - members (bin x::int _ m1 m2) | - members (bin x::string _ m1 m2) | - members (bin x _ m1 m2) - = (members m1) + (x : (members m2)) -end; - -list m@(Set _) | -list m@(Bag _) - = members m; - -// get the first member of an ordered data structure -first (Set m) | -first (Bag m) -= first m -with - first (bin x _ nil _) = x; - first (bin _ _ m1 _) = first m1 -end; - -// get the last member of an ordered data structure -last (Set m) | -last (Bag m) -= last m -with - last (bin x _ _ nil) = x; - last (bin _ _ _ m2 ) = last m2 -end; - -// remove the first member from an ordered data structure -rmfirst (t@Set m) | -rmfirst (t@Bag m) -= t ((rmfirst m)!0) -with - rmfirst nil = [nil, 0]; - rmfirst (bin _ _ nil r) = [r, 1]; - rmfirst (bin k b::int l r) - = Set_adjustd leftHasChanged (bin k b newL r) (-1) - when [newL, leftHasChanged] = rmfirst l end -end; - -// remove the last member from an ordered data structure -rmlast (t@Set m) | -rmlast (t@Bag m) -= t ((rmlast m)!0) -with - rmlast nil = [nil, 0]; - rmlast (bin _ _ l nil) = [l, 1]; - rmlast (bin k b::int l r ) - = Set_adjustd rightHasChanged (bin k b l newR) ( 1) - when [newR, rightHasChanged] = rmlast r end -end; - -// set and bag relations -m1@(Set _) == m2@(Set _) | -m1@(Bag _) == m2@(Bag _) - = (members m1 == members m2); - -m1@(Set _) != m2@(Set _) | -m1@(Bag _) != m2@(Bag _) - = (members m1 != members m2); - -m1@(Set _) <= m2@(Set _) = all (member m2) (members m1); -m1@(Bag _) <= m2@(Bag _) = null (m1 - m2); - -m1@(Set _) >= m2@(Set _) = all (member m1) (members m2); -m1@(Bag _) >= m2@(Bag _) = null (m2 - m1); - -m1@(Set _) < m2@(Set _) | -m1@(Bag _) < m2@(Bag _) - = if (m1 <= m2) then (m1 != m2) else 0; - -m1@(Set _) > m2@(Set _) | -m1@(Bag _) > m2@(Bag _) - = if (m1 >= m2) then (m1 != m2) else 0; - -// set and bag union -m1@(Set _) + m2@(Set _) | -m1@(Bag _) + m2@(Bag _) - = foldl insert m1 (members m2); - -// set and bag difference -m1@(Set _) - m2@(Set _) | -m1@(Bag _) - m2@(Bag _) - = foldl delete m1 (members m2); - -// set and bag intersection -m1@(Set _) * m2@(Set _) | -m1@(Bag _) * m2@(Bag _) - = m1 - (m1 - m2); - - -/* Private functions, don't invoke these directly. */ - -Set_adjustd ToF::int tree LoR::int -= adjust ToF tree LoR -with - adjust 0 oldTree _ = [oldTree, 0]; - - adjust 1 (bin key::int b0::int l r) LoR::int | - adjust 1 (bin key::string b0::int l r) LoR::int | - adjust 1 (bin key b0::int l r) LoR::int - = rebal toBeRebalanced (bin key b0 l r) b1 whatHasChanged - when - [b1, whatHasChanged, toBeRebalanced] = table b0 LoR; - end; -/* - Note that rebali and rebald are not symmetrical. With insertions it is - sufficient to know the original balance and insertion side in order to - decide whether the whole tree increases. With deletions it is sometimes not - sufficient and we need to know which kind of tree rotation took place. -*/ - rebal 0 (bin k::int _ l r) b::int whatHasChanged | - rebal 0 (bin k::string _ l r) b::int whatHasChanged | - rebal 0 (bin k _ l r) b::int whatHasChanged - = [bin k b l r, whatHasChanged]; - - rebal 1 oldTree _ _ = Set_avl_geq oldTree; - -// Balance rules for deletions -// balance where balance whole tree to be -// before deleted after decreased rebalanced -table ( 0) ( 1) = [( 1), 0, 0]; -table ( 0) (-1) = [(-1), 0, 0]; -table ( 1) ( 1) = [( 0), 1, 1]; -// ^^^^ -// It depends on the tree pattern in avl_geq whether it really decreases - -table ( 1) (-1) = [( 0), 1, 0]; -table (-1) ( 1) = [( 0), 1, 0]; -table (-1) (-1) = [( 0), 1, 1] -// ^^^^ -// It depends on the tree pattern in avl_geq whether it really decreases -end; - - -// Single and double tree rotations - these are common for insert and delete -/* - The patterns (-1)-(-1), (-1)-( 1), ( 1)-( 1) and ( 1)-(-1) on the LHS always - change the tree height and these are the only patterns which can happen - after an insertion. That's the reason why we can use tablei only to decide - the needed changes. - The patterns (-1)-( 0) and ( 1)-( 0) do not change the tree height. After a - deletion any pattern can occur and so we return 1 or 0 as a flag of - a height change. -*/ - -Set_avl_geq x = avl_geq x -with - avl_geq (bin a::int (-1) alpha (bin b::int (-1) beta gamma)) | - avl_geq (bin a::string (-1) alpha (bin b::string (-1) beta gamma)) | - avl_geq (bin a (-1) alpha (bin b (-1) beta gamma)) - = [bin b ( 0) (bin a ( 0) alpha beta) gamma, 1]; - - avl_geq (bin a::int (-1) alpha (bin b::int ( 0) beta gamma)) | - avl_geq (bin a::string (-1) alpha (bin b::string ( 0) beta gamma)) | - avl_geq (bin a (-1) alpha (bin b ( 0) beta gamma)) - = [bin b ( 1) (bin a (-1) alpha beta) gamma, 0]; - // the tree doesn't decrease with this pattern - - avl_geq (bin a::int (-1) alpha - (bin b::int ( 1) (bin x::int b1 beta gamma) delta)) | - avl_geq (bin a::string (-1) alpha - (bin b::string ( 1) (bin x::string b1 beta gamma) delta)) | - avl_geq (bin a (-1) alpha - (bin b ( 1) (bin x b1 beta gamma) delta)) - = [bin x ( 0) (bin a b2 alpha beta) - (bin b b3 gamma delta), 1] - when - [b2, b3] = table b1 - end; - - avl_geq (bin b::int ( 1) (bin a::int ( 1) alpha beta) gamma) | - avl_geq (bin b::string ( 1) (bin a::string ( 1) alpha beta) gamma) | - avl_geq (bin b ( 1) (bin a ( 1) alpha beta) gamma) - = [bin a ( 0) alpha (bin b ( 0) beta gamma), 1]; - - avl_geq (bin b::int ( 1) (bin a::int ( 0) alpha beta) gamma) | - avl_geq (bin b::string ( 1) (bin a::string ( 0) alpha beta) gamma) | - avl_geq (bin b ( 1) (bin a ( 0) alpha beta) gamma) - = [bin a (-1) alpha (bin b ( 1) beta gamma), 0]; - // the tree doesn't decrease with this pattern - - avl_geq (bin b::int ( 1) - (bin a::int (-1) alpha (bin x::int b1 beta gamma)) delta) | - avl_geq (bin b::string ( 1) - (bin a::string (-1) alpha (bin x::string b1 beta gamma)) delta) | - avl_geq (bin b ( 1) - (bin a (-1) alpha (bin x b1 beta gamma)) delta) - = [bin x ( 0) (bin a b2 alpha beta) - (bin b b3 gamma delta), 1] - when - [b2, b3] = table b1 - end; - - table ( 1) = [( 0), (-1)]; - table (-1) = [( 1), ( 0)]; - table ( 0) = [( 0), ( 0)] -end; Copied: pure/trunk/lib/set.pure (from rev 376, pure/trunk/examples/set.pure) =================================================================== --- pure/trunk/lib/set.pure (rev 0) +++ pure/trunk/lib/set.pure 2008-07-03 05:19:00 UTC (rev 377) @@ -0,0 +1,438 @@ +/* Pure's set and bag data types based on AVL trees. */ + +/* Copyright (c) 2008 by Albert Graef <Dr....@t-...>. + Copyright (c) 2008 by Jiri Spitz <jir...@bl...>. + + This file is part of the Pure programming language and system. + + Pure is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or (at your option) any later + version. + + Pure 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 General Public License for more + details. + + You should have received a copy of the GNU General Public License along + with this program. If not, see <http://www.gnu.org/licenses/>. */ + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + The used algorithm of AVL trees has its origin in the SWI-Prolog + implementation of association lists. The original file was created by + R. A. O'Keefe and updated for the SWI-Prolog by Jan Wielemaker. For the + original file see http://www.swi-prolog.org. + + The port from SWI-Prolog and the deletion stuff (rmfirst, rmlast, delete) + missing in the original file was provided by Jiri Spitz +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + +/* Public operations: ****************************************************** + +emptyset, emptybag: return the empty set or bag +set xs, bag xs; create a set or bag from list xs +setp x, bagp x; check whether x is a set or bag + +#m size of set or bag m + +null m tests whether m is the empty set or bag +member m x tests whether m contains x +members m, list m list members of m in ascending order + +first m, last m return first and last member of m +rmfirst m, rmlast m remove first and last member from m +insert m x insert x into m (replace existing element) +delete m x remove x from m + + *************************************************************************/ + + +/* Empty tree constant, consider this private. */ +nullary nil; + +/***** +Tree for set and bag is either: +- nil (empty tree) or +- bin key Balance Left Right (Left, Right: trees) + + +Balance: ( 1), ( 0), or (-1) denoting |L|-|R| = 1, 0, or -1, respectively +*****/ + +// set and bag type checks +bagp (Bag _) = 1; +bagp _ = 0; + +setp (Set _) = 1; +setp _ = 0; + +// create an empty set or bag +emptyset = Set nil; +emptybag = Bag nil; + +// create set or bag from a list +set xs = foldl insert emptyset xs if listp xs; +bag xs = foldl insert emptybag xs if listp xs; + +// insert a new member into a set or bag +insert (t@Set m) y::int | +insert (t@Set m) y::string | +insert (t@Set m) y | +insert (t@Bag m) y::int | +insert (t@Bag m) y::string | +insert (t@Bag m) y = t ((insert m y)!0) +with + insert nil key::int | + insert nil key::string | + insert nil key + = [(bin key ( 0) nil nil), 1]; + + insert (bin k::int b::int l r) key::int | + insert (bin k::string b::int l r) key::string | + insert (bin k b::int l r) key + = [(bin key b l r), 0] if (key == k) && (t === Set); + + insert (bin k::int b::int l r) key::int | + insert (bin k::string b::int l r) key::string | + insert (bin k b::int l r) key + = adjust leftHasChanged (bin k b newL r) (-1) + when [newL, leftHasChanged] = insert l key end if key < k; + + insert (bin k::int b::int l r) key::int | + insert (bin k::string b::int l r) key::string | + insert (bin k b::int l r) key + = adjust rightHasChanged (bin k b l newR) ( 1) + when [newR, rightHasChanged] = insert r key end + if ((key > k) && (t === Set)) || ((key >= k) && (t === Bag)); + + adjust 0 oldTree _ + = [oldTree, 0]; + + adjust 1 (bin key::int b0::int l r) LoR::int | + adjust 1 (bin key::string b0::int l r) LoR::int | + adjust 1 (bin key b0::int l r) LoR::int + = [rebal toBeRebalanced (bin key b0 l r) b1, whatHasChanged] + when + [b1, whatHasChanged, toBeRebalanced] = table b0 LoR + end; + + rebal 0 (bin k::int _ l r) b | + rebal 0 (bin k::string _ l r) b | + rebal 0 (bin k _ l r) b + = bin k b l r; + + rebal 1 oldTree _ + = (Set_avl_geq oldTree)!0; + +// Balance rules for insertions +// balance where balance whole tree to be +// before inserted after increased rebalanced +table ( 0) (-1) = [( 1), 1, 0]; +table ( 0) ( 1) = [(-1), 1, 0]; +table ( 1) (-1) = [( 0), 0, 1]; +table ( 1) ( 1) = [( 0), 0, 0]; +table (-1) (-1) = [( 0), 0, 0]; +table (-1) ( 1) = [( 0), 0, 1]; +end; + +// delete a member by key from the data structure +delete (t@Set m) y::int | +delete (t@Set m) y::string | +delete (t@Set m) y | +delete (t@Bag m) y::int | +delete (t@Bag m) y::string | +delete (t@Bag m) y += t ((delete m y)!0) +with + delete nil _ = [nil, 0]; + + delete (bin k::int _ nil r) key::int | + delete (bin k::string _ nil r) key::string | + delete (bin k _ nil r) key + = [r, 1] if key == k; + + delete (bin k::int _ l nil) key::int | + delete (bin k::string _ l nil) key::string | + delete (bin k _ l nil) key + = [l, 1] if key == k; + + delete (bin k::int b::int x@(bin kl::int bl::int rl ll) r) key::int | + delete (bin k::string b::int x@(bin kl::string bl::int rl ll) r) key::string | + delete (bin k b::int x@(bin kl bl::int rl ll) r) key + = Set_adjustd leftHasChanged (bin lk b newL r) (-1) + when + lk = last x; + [newL, leftHasChanged] = rmlast x + end + if key == k; + + delete (bin k::int b::int l r) key::int | + delete (bin k::string b::int l r) key::string | + delete (bin k b::int l r) key + = Set_adjustd leftHasChanged (bin k b newL r) (-1) + when + [newL, leftHasChanged] = delete l key + end + if key < k; + + delete (bin k::int b::int l r) key::int | + delete (bin k::string b::int l r) key::string | + delete (bin k b::int l r) key + = Set_adjustd rightHasChanged (bin k b l newR) ( 1) + when + [newR, rightHasChanged] = delete r key + end + if key > k; + + rmlast nil = [nil, 0]; + rmlast (bin _ _ l nil) = [l, 1]; + rmlast (bin k b::int l r ) + = Set_adjustd rightHasChanged (bin k b l newR) ( 1) + when [newR, rightHasChanged] = rmlast r end; + + last (bin x _ _ nil) = x; + last (bin _ _ _ m2 ) = last m2 +end; + +// check for the empty data structure +null (Set nil) = 1; +null (Set _) = 0; + +null (Bag nil) = 1; +null (Bag _) = 0; + +// get a number of members in data structure +#(Set m) | +#(Bag m) = #m +with + #nil = 0; + #(bin _ _ m1 m2) = #m1 + #m2 + 1 +end; + +// check whether a key exists in data structure +member (Set m) k::int | +member (Set m) k::string | +member (Set m) k | +member (Bag m) k::int | +member (Bag m) k::string | +member (Bag m) k += member m k +with + member nil _ = 0; + + member (bin x _ m1 m2) y::int | + member (bin x _ m1 m2) y::string | + member (bin x _ m1 m2) y + = member m1 y if x > y; + = member m2 y if x < y; + = 1 if x == y +end; + +// get all members of data structure as a list +members (Set m) | +members (Bag m) += members m +with + members nil = []; + + members (bin x::int _ m1 m2) | + members (bin x::string _ m1 m2) | + members (bin x _ m1 m2) + = (members m1) + (x : (members m2)) +end; + +list m@(Set _) | +list m@(Bag _) + = members m; + +// get the first member of an ordered data structure +first (Set m) | +first (Bag m) += first m +with + first (bin x _ nil _) = x; + first (bin _ _ m1 _) = first m1 +end; + +// get the last member of an ordered data structure +last (Set m) | +last (Bag m) += last m +with + last (bin x _ _ nil) = x; + last (bin _ _ _ m2 ) = last m2 +end; + +// remove the first member from an ordered data structure +rmfirst (t@Set m) | +rmfirst (t@Bag m) += t ((rmfirst m)!0) +with + rmfirst nil = [nil, 0]; + rmfirst (bin _ _ nil r) = [r, 1]; + rmfirst (bin k b::int l r) + = Set_adjustd leftHasChanged (bin k b newL r) (-1) + when [newL, leftHasChanged] = rmfirst l end +end; + +// remove the last member from an ordered data structure +rmlast (t@Set m) | +rmlast (t@Bag m) += t ((rmlast m)!0) +with + rmlast nil = [nil, 0]; + rmlast (bin _ _ l nil) = [l, 1]; + rmlast (bin k b::int l r ) + = Set_adjustd rightHasChanged (bin k b l newR) ( 1) + when [newR, rightHasChanged] = rmlast r end +end; + +// set and bag relations +m1@(Set _) == m2@(Set _) | +m1@(Bag _) == m2@(Bag _) + = (members m1 == members m2); + +m1@(Set _) != m2@(Set _) | +m1@(Bag _) != m2@(Bag _) + = (members m1 != members m2); + +m1@(Set _) <= m2@(Set _) = all (member m2) (members m1); +m1@(Bag _) <= m2@(Bag _) = null (m1 - m2); + +m1@(Set _) >= m2@(Set _) = all (member m1) (members m2); +m1@(Bag _) >= m2@(Bag _) = null (m2 - m1); + +m1@(Set _) < m2@(Set _) | +m1@(Bag _) < m2@(Bag _) + = if (m1 <= m2) then (m1 != m2) else 0; + +m1@(Set _) > m2@(Set _) | +m1@(Bag _) > m2@(Bag _) + = if (m1 >= m2) then (m1 != m2) else 0; + +// set and bag union +m1@(Set _) + m2@(Set _) | +m1@(Bag _) + m2@(Bag _) + = foldl insert m1 (members m2); + +// set and bag difference +m1@(Set _) - m2@(Set _) | +m1@(Bag _) - m2@(Bag _) + = foldl delete m1 (members m2); + +// set and bag intersection +m1@(Set _) * m2@(Set _) | +m1@(Bag _) * m2@(Bag _) + = m1 - (m1 - m2); + + +/* Private functions, don't invoke these directly. */ + +Set_adjustd ToF::int tree LoR::int += adjust ToF tree LoR +with + adjust 0 oldTree _ = [oldTree, 0]; + + adjust 1 (bin key::int b0::int l r) LoR::int | + adjust 1 (bin key::string b0::int l r) LoR::int | + adjust 1 (bin key b0::int l r) LoR::int + = rebal toBeRebalanced (bin key b0 l r) b1 whatHasChanged + when + [b1, whatHasChanged, toBeRebalanced] = table b0 LoR; + end; +/* + Note that rebali and rebald are not symmetrical. With insertions it is + sufficient to know the original balance and insertion side in order to + decide whether the whole tree increases. With deletions it is sometimes not + sufficient and we need to know which kind of tree rotation took place. +*/ + rebal 0 (bin k::int _ l r) b::int whatHasChanged | + rebal 0 (bin k::string _ l r) b::int whatHasChanged | + rebal 0 (bin k _ l r) b::int whatHasChanged + = [bin k b l r, whatHasChanged]; + + rebal 1 oldTree _ _ = Set_avl_geq oldTree; + +// Balance rules for deletions +// balance where balance whole tree to be +// before deleted after decreased rebalanced +table ( 0) ( 1) = [( 1), 0, 0]; +table ( 0) (-1) = [(-1), 0, 0]; +table ( 1) ( 1) = [( 0), 1, 1]; +// ^^^^ +// It depends on the tree pattern in avl_geq whether it really decreases + +table ( 1) (-1) = [( 0), 1, 0]; +table (-1) ( 1) = [( 0), 1, 0]; +table (-1) (-1) = [( 0), 1, 1] +// ^^^^ +// It depends on the tree pattern in avl_geq whether it really decreases +end; + + +// Single and double tree rotations - these are common for insert and delete +/* + The patterns (-1)-(-1), (-1)-( 1), ( 1)-( 1) and ( 1)-(-1) on the LHS always + change the tree height and these are the only patterns which can happen + after an insertion. That's the reason why we can use tablei only to decide + the needed changes. + The patterns (-1)-( 0) and ( 1)-( 0) do not change the tree height. After a + deletion any pattern can occur and so we return 1 or 0 as a flag of + a height change. +*/ + +Set_avl_geq x = avl_geq x +with + avl_geq (bin a::int (-1) alpha (bin b::int (-1) beta gamma)) | + avl_geq (bin a::string (-1) alpha (bin b::string (-1) beta gamma)) | + avl_geq (bin a (-1) alpha (bin b (-1) beta gamma)) + = [bin b ( 0) (bin a ( 0) alpha beta) gamma, 1]; + + avl_geq (bin a::int (-1) alpha (bin b::int ( 0) beta gamma)) | + avl_geq (bin a::string (-1) alpha (bin b::string ( 0) beta gamma)) | + avl_geq (bin a (-1) alpha (bin b ( 0) beta gamma)) + = [bin b ( 1) (bin a (-1) alpha beta) gamma, 0]; + // the tree doesn't decrease with this pattern + + avl_geq (bin a::int (-1) alpha + (bin b::int ( 1) (bin x::int b1 beta gamma) delta)) | + avl_geq (bin a::string (-1) alpha + (bin b::string ( 1) (bin x::string b1 beta gamma) delta)) | + avl_geq (bin a (-1) alpha + (bin b ( 1) (bin x b1 beta gamma) delta)) + = [bin x ( 0) (bin a b2 alpha beta) + (bin b b3 gamma delta), 1] + when + [b2, b3] = table b1 + end; + + avl_geq (bin b::int ( 1) (bin a::int ( 1) alpha beta) gamma) | + avl_geq (bin b::string ( 1) (bin a::string ( 1) alpha beta) gamma) | + avl_geq (bin b ( 1) (bin a ( 1) alpha beta) gamma) + = [bin a ( 0) alpha (bin b ( 0) beta gamma), 1]; + + avl_geq (bin b::int ( 1) (bin a::int ( 0) alpha beta) gamma) | + avl_geq (bin b::string ( 1) (bin a::string ( 0) alpha beta) gamma) | + avl_geq (bin b ( 1) (bin a ( 0) alpha beta) gamma) + = [bin a (-1) alpha (bin b ( 1) beta gamma), 0]; + // the tree doesn't decrease with this pattern + + avl_geq (bin b::int ( 1) + (bin a::int (-1) alpha (bin x::int b1 beta gamma)) delta) | + avl_geq (bin b::string ( 1) + (bin a::string (-1) alpha (bin x::string b1 beta gamma)) delta) | + avl_geq (bin b ( 1) + (bin a (-1) alpha (bin x b1 beta gamma)) delta) + = [bin x ( 0) (bin a b2 alpha beta) + (bin b b3 gamma delta), 1] + when + [b2, b3] = table b1 + end; + + table ( 1) = [( 0), (-1)]; + table (-1) = [( 1), ( 0)]; + table ( 0) = [( 0), ( 0)] +end; Added: pure/trunk/test/test015.log =================================================================== --- pure/trunk/test/test015.log (rev 0) +++ pure/trunk/test/test015.log 2008-07-03 05:19:00 UTC (rev 377) @@ -0,0 +1,160 @@ +{ + rule #0: a = set (1..10) + state 0: #0 + <var> state 1 + state 1: #0 +} +let a = set (1..10); +{ + rule #0: b = set (6..10) + state 0: #0 + <var> state 1 + state 1: #0 +} +let b = set (6..10); +{ + rule #0: c = bag (1..10) + state 0: #0 + <var> state 1 + state 1: #0 +} +let c = bag (1..10); +{ + rule #0: d = bag (6..10) + state 0: #0 + <var> state 1 + state 1: #0 +} +let d = bag (6..10); +{ + rule #0: e = set (map str (1..10)) + state 0: #0 + <var> state 1 + state 1: #0 +} +let e = set (map str (1..10)); +{ + rule #0: f = bag (map str (1..10)) + state 0: #0 + <var> state 1 + state 1: #0 +} +let f = bag (map str (1..10)); +a; +Set (bin 4 (-1) (bin 2 0 (bin 1 0 nil nil) (bin 3 0 nil nil)) (bin 8 0 (bin 6 0 (bin 5 0 nil nil) (bin 7 0 nil nil)) (bin 9 (-1) nil (bin 10 0 nil nil)))) +b; +Set (bin 7 (-1) (bin 6 0 nil nil) (bin 9 0 (bin 8 0 nil nil) (bin 10 0 nil nil))) +c; +Bag (bin 4 (-1) (bin 2 0 (bin 1 0 nil nil) (bin 3 0 nil nil)) (bin 8 0 (bin 6 0 (bin 5 0 nil nil) (bin 7 0 nil nil)) (bin 9 (-1) nil (bin 10 0 nil nil)))) +d; +Bag (bin 7 (-1) (bin 6 0 nil nil) (bin 9 0 (bin 8 0 nil nil) (bin 10 0 nil nil))) +e; +Set (bin "4" 0 (bin "2" 1 (bin "1" (-1) nil (bin "10" 0 nil nil)) (bin "3" 0 nil nil)) (bin "6" (-1) (bin "5" 0 nil nil) (bin "8" 0 (bin "7" 0 nil nil) (bin "9" 0 nil nil)))) +f; +Bag (bin "4" 0 (bin "2" 1 (bin "1" (-1) nil (bin "10" 0 nil nil)) (bin "3" 0 nil nil)) (bin "6" (-1) (bin "5" 0 nil nil) (bin "8" 0 (bin "7" 0 nil nil) (bin "9" 0 nil nil)))) +setp a; +1 +setp c; +0 +bagp c; +1 +bagp a; +0 +null emptyset; +1 +null emptybag; +1 +null a; +0 +null c; +0 +rmfirst a; +Set (bin 4 (-1) (bin 2 (-1) nil (bin 3 0 nil nil)) (bin 8 0 (bin 6 0 (bin 5 0 nil nil) (bin 7 0 nil nil)) (bin 9 (-1) nil (bin 10 0 nil nil)))) +rmfirst c; +Bag (bin 4 (-1) (bin 2 (-1) nil (bin 3 0 nil nil)) (bin 8 0 (bin 6 0 (bin 5 0 nil nil) (bin 7 0 nil nil)) (bin 9 (-1) nil (bin 10 0 nil nil)))) +rmlast a; +Set (bin 4 (-1) (bin 2 0 (bin 1 0 nil nil) (bin 3 0 nil nil)) (bin 8 1 (bin 6 0 (bin 5 0 nil nil) (bin 7 0 nil nil)) (bin 9 0 nil nil))) +rmlast c; +Bag (bin 4 (-1) (bin 2 0 (bin 1 0 nil nil) (bin 3 0 nil nil)) (bin 8 1 (bin 6 0 (bin 5 0 nil nil) (bin 7 0 nil nil)) (bin 9 0 nil nil))) +first a; +1 +last a; +10 +first c; +1 +last c; +10 +#a; +10 +#c; +10 +member a 5; +1 +member a 50; +0 +member c 5; +1 +member c 50; +0 +a==b; +0 +a!=b; +1 +a<b; +0 +a<=b; +0 +a>b; +1 +a>=b; +1 +a==a; +1 +a!=a; +0 +a<a; +0 +a<=a; +1 +a>a; +0 +a>=a; +1 +c==d; +0 +c!=d; +1 +c<d; +0 +c<=d; +0 +c>d; +1 +c>=d; +1 +c==c; +1 +c!=c; +0 +c<c; +0 +c<=c; +1 +c>c; +0 +c>=c; +1 +a+b; +Set (bin 4 (-1) (bin 2 0 (bin 1 0 nil nil) (bin 3 0 nil nil)) (bin 8 0 (bin 6 0 (bin 5 0 nil nil) (bin 7 0 nil nil)) (bin 9 (-1) nil (bin 10 0 nil nil)))) +a*b; +Set (bin 8 0 (bin 6 (-1) nil (bin 7 0 nil nil)) (bin 9 (-1) nil (bin 10 0 nil nil))) +a-b; +Set (bin 4 1 (bin 2 0 (bin 1 0 nil nil) (bin 3 0 nil nil)) (bin 5 0 nil nil)) +c+d; +Bag (bin 6 (-1) (bin 4 1 (bin 2 0 (bin 1 0 nil nil) (bin 3 0 nil nil)) (bin 5 0 nil nil)) (bin 8 (-1) (bin 7 0 (bin 6 0 nil nil) (bin 7 0 nil nil)) (bin 9 (-1) (bin 8 0 nil nil) (bin 10 0 (bin 9 0 nil nil) (bin 10 0 nil nil))))) +c*d; +Bag (bin 8 0 (bin 6 (-1) nil (bin 7 0 nil nil)) (bin 9 (-1) nil (bin 10 0 nil nil))) +c-d; +Bag (bin 4 1 (bin 2 0 (bin 1 0 nil nil) (bin 3 0 nil nil)) (bin 5 0 nil nil)) +c+d-d; +Bag (bin 5 0 (bin 2 (-1) (bin 1 0 nil nil) (bin 4 1 (bin 3 0 nil nil) nil)) (bin 8 0 (bin 7 1 (bin 6 0 nil nil) nil) (bin 9 (-1) nil (bin 10 0 nil nil)))) Added: pure/trunk/test/test015.pure =================================================================== --- pure/trunk/test/test015.pure (rev 0) +++ pure/trunk/test/test015.pure 2008-07-03 05:19:00 UTC (rev 377) @@ -0,0 +1,56 @@ +// Some tests for set and bag data containers + +using set; + +// Create data structures + +let a = set (1..10); +let b = set (6..10); + +let c = bag (1..10); +let d = bag (6..10); + +let e = set (map str (1..10)); +let f = bag (map str (1..10)); + +a; b; c; d; e; f; + +// Type tests + +setp a; setp c; bagp c; bagp a; + +// Tests for empty data sets + +null emptyset; null emptybag; null a; null c; + +// Remove the first and last member + +rmfirst a; rmfirst c; rmlast a; rmlast c; + +// Find the first and last member + +first a; last a; first c; last c; + +// Size of data set + +#a; #c; + +// Membership tests + +member a 5; member a 50; member c 5; member c 50; + +// Relations + +a == b; a != b; a < b; a <= b; a > b; a >= b; + +a == a; a != a; a < a; a <= a; a > a; a >= a; + +c == d; c != d; c < d; c <= d; c > d; c >= d; + +c == c; c != c; c < c; c <= c; c > c; c >= c; + +// Set operations + +a + b; a * b; a - b; + +c + d; c * d; c - d; (c + d) - d; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ye...@us...> - 2008-07-03 00:23:48
|
Revision: 376 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=376&view=rev Author: yes Date: 2008-07-02 17:23:57 -0700 (Wed, 02 Jul 2008) Log Message: ----------- added time calculations to examples/libor/myutils.pure Modified Paths: -------------- pure/trunk/examples/libor/myutils.pure Modified: pure/trunk/examples/libor/myutils.pure =================================================================== --- pure/trunk/examples/libor/myutils.pure 2008-07-03 00:23:46 UTC (rev 375) +++ pure/trunk/examples/libor/myutils.pure 2008-07-03 00:23:57 UTC (rev 376) @@ -1,31 +1,62 @@ -// Dr Libor Spacek, 21th May 2008 +/* General Utilities + Copyright (c) 2008 by Libor Spacek */ +//(1) Mathematics //General mathematical iterators over one and two indices MathIter1 op i1 i2 f = foldl1 op (map f (i1..i2)); + MathIter2 op i1 i2 j1 j2 f = foldl1 op (map (uncurry f) [x,y; x = i1..i2; y = j1..j2]); + //Examples on how to use the mathematical iterators Sigma i1 i2 f = MathIter1 (+) i1 i2 f; + Pi i1 i2 f = MathIter1 (*) i1 i2 f; + Factorial n = Pi 1L n id; + //Binomial using (k, n-k) symmetry and bignum division Binomial n k = (Pi (k+1L) n id) div (Pi 2L (n-k) id) if n-k < k; = (Pi (n-k+1L) n id) div (Pi 2L k id); - + // Euclid's recursive greatest common factor algorithm for ints and bignums Gcf x 0 | Gcf x 0L = x; Gcf x y = Gcf y (x mod y); +//(2) List Processing // take the head of a list and put it at the end rotate (h:t) = reverse (h:(reverse t)); -// protate = rotate n items from the front: use when n is positive: 0<=n<=#n + +// take n items from the front and put them at the end (n positive 0<=n<=#n) protate 0 l = l; protate n::int l = cat [(drop n l),(take n l)]; -// rotate n items, generalisation of "rotate the bits instruction" -// example: head (nrotate (-33) (0..23)); -// what time is 33 hrs before midnight? 15 hrs. -// The clock was moved -33 mod 24 = -9 hours from midnight (0) + +// rotate n items, cf. "rotate n bits instruction" (n can now also be negative) +// example applied to clocks: >head (nrotate (-33) (0..23)); +// what time is 33 hrs before midnight? Answer: 15 hrs. nrotate n::int l = protate nm l when ll = #l; nm = ll + (n mod ll) end if n<0; = protate nm l when nm = n mod #l end; +//(3) Time Calculations - seconds can be int or double or bigint. d,h,m are ints +dhms2secs (d::int,h::int,m::int,s::int) | +dhms2secs (d::int,h::int,m::int,s::double) | +dhms2secs (d::int,h::int,m::int,s::bigint) = 60*(60*(24*d+h)+m)+s; +secs2dhms secs::int | secs2dhms secs::bigint = + (int d),(int (h mod 24)),(int (m mod 60)),(int (secs mod 60)) + when + m = secs div 60; + h = m div 60; + d = h div 24 + end; +secs2dhms secs::double = + (int d),(int (h mod 24)),(int (m mod 60)),(int (isecs mod 60))+(secs-isecs) + when isecs = (bigint secs); + m = isecs div 60; + h = m div 60; + d = h div 24 + end; + +// an arbitrary binary operator applied to two days:hours:minutes:seconds +opdhms op (d1::int,h1::int,m1::int,s1)(d2::int,h2::int,m2::int,s2) = + secs2dhms (op (dhms2secs (d1,h1,m1,s1)) (dhms2secs (d2,h2,m2,s2))); \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-07-03 00:23:38
|
Revision: 375 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=375&view=rev Author: agraef Date: 2008-07-02 17:23:46 -0700 (Wed, 02 Jul 2008) Log Message: ----------- Update documentation. Modified Paths: -------------- pure/trunk/pure.1.in Modified: pure/trunk/pure.1.in =================================================================== --- pure/trunk/pure.1.in 2008-07-03 00:19:47 UTC (rev 374) +++ pure/trunk/pure.1.in 2008-07-03 00:23:46 UTC (rev 375) @@ -165,8 +165,10 @@ .B -n option and specify the .B prelude.pure -file explicitly on the command line. Alternatively, you can also use the -interactive +file explicitly on the command line. Verbose output is also suppressed for +modules imported through a +.B using +clause. As a remedy, you can use the interactive .B list command (see the \fBINTERACTIVE USAGE\fP section below) to list definitions along with additional debugging information. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-07-03 00:19:38
|
Revision: 374 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=374&view=rev Author: agraef Date: 2008-07-02 17:19:47 -0700 (Wed, 02 Jul 2008) Log Message: ----------- Temporarily suppress verbose output for using clause. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/interpreter.cc pure/trunk/test/prelude.log pure/trunk/test/test011.log pure/trunk/test/test014.log Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-07-02 23:31:57 UTC (rev 373) +++ pure/trunk/ChangeLog 2008-07-03 00:19:47 UTC (rev 374) @@ -1,3 +1,9 @@ +2008-07-03 Albert Graef <Dr....@t-...> + + * interpreter.cc (run): Temporarily suppress verbose output for + using clause. This also makes the some of the test logs much + smaller. Reported by Jiri Spitz. + 2008-07-02 Albert Graef <Dr....@t-...> * lib/math.pure: Added rational numbers. Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-07-02 23:31:57 UTC (rev 373) +++ pure/trunk/interpreter.cc 2008-07-03 00:19:47 UTC (rev 374) @@ -441,8 +441,14 @@ pure_expr* interpreter::run(const list<string> &sl, bool check) { + uint8_t s_verbose = verbose; + // Temporarily suppress verbose output for using clause. + compile(); + verbose = 0; for (list<string>::const_iterator s = sl.begin(); s != sl.end(); s++) run(*s, check); + compile(); + verbose = s_verbose; return result; } Modified: pure/trunk/test/prelude.log =================================================================== --- pure/trunk/test/prelude.log 2008-07-02 23:31:57 UTC (rev 373) +++ pure/trunk/test/prelude.log 2008-07-03 00:19:47 UTC (rev 374) @@ -1,355 +1,5 @@ def false = 0; def true = 1; -throw x/*0:1*/ = pure_throw x/*0:1*/; -assert p/*0:01*/ e/*0:1*/ = if p/*0:01*/ then 1 else throw e/*0:1*/; -x/*0:01*/===y/*0:1*/ = same x/*0:01*/ y/*0:1*/; -x/*0:01*/!==y/*0:1*/ = not same x/*0:01*/ y/*0:1*/; -intp x/*0:1*/ = case x/*0:1*/ of _/*0:*/::int = 1; _/*0:*/ = 0 { - rule #0: _::int = 1 - rule #1: _ = 0 - state 0: #0 #1 - <var> state 1 - <var>::int state 2 - state 1: #1 - state 2: #0 #1 -} end; -bigintp x/*0:1*/ = case x/*0:1*/ of _/*0:*/::bigint = 1; _/*0:*/ = 0 { - rule #0: _::bigint = 1 - rule #1: _ = 0 - state 0: #0 #1 - <var> state 1 - <var>::bigint state 2 - state 1: #1 - state 2: #0 #1 -} end; -doublep x/*0:1*/ = case x/*0:1*/ of _/*0:*/::double = 1; _/*0:*/ = 0 { - rule #0: _::double = 1 - rule #1: _ = 0 - state 0: #0 #1 - <var> state 1 - <var>::double state 2 - state 1: #1 - state 2: #0 #1 -} end; -stringp x/*0:1*/ = case x/*0:1*/ of _/*0:*/::string = 1; _/*0:*/ = 0 { - rule #0: _::string = 1 - rule #1: _ = 0 - state 0: #0 #1 - <var> state 1 - <var>::string state 2 - state 1: #1 - state 2: #0 #1 -} end; -pointerp x/*0:1*/ = case x/*0:1*/ of _/*0:*/ = 1; _/*0:*/ = 0 { - rule #0: _ = 1 - rule #1: _ = 0 - state 0: #0 #1 - <var> state 1 - <var> state 2 - state 1: #1 - state 2: #0 #1 -} end; -listp [] = 1; -listp (x/*0:101*/:xs/*0:11*/) = listp xs/*0:11*/; -listp _/*0:1*/ = 0; -listnp [] = 1; -listnp (x/*0:101*/:xs/*0:11*/) = 1; -listnp _/*0:1*/ = 0; -tuplep () = 1; -tuplep (x/*0:101*/,xs/*0:11*/) = 1; -tuplep _/*0:1*/ = 0; -int x/*0:1*/::int = x/*0:1*/; -int x/*0:1*/::bigint = pure_intval x/*0:1*/; -int x/*0:1*/::double = pure_intval x/*0:1*/; -int x/*0:1*/ = pure_intval x/*0:1*/; -bigint x/*0:1*/::bigint = x/*0:1*/; -bigint x/*0:1*/::int = pure_bigintval x/*0:1*/; -bigint x/*0:1*/::double = pure_bigintval x/*0:1*/; -bigint x/*0:1*/ = pure_bigintval x/*0:1*/; -double x/*0:1*/::double = x/*0:1*/; -double x/*0:1*/::int = pure_dblval x/*0:1*/; -double x/*0:1*/::bigint = pure_dblval x/*0:1*/; -pointer x/*0:1*/ = x/*0:1*/; -pointer x/*0:1*/::int = pure_pointerval x/*0:1*/; -pointer x/*0:1*/::bigint = pure_pointerval x/*0:1*/; -pointer x/*0:1*/::double = pure_pointerval x/*0:1*/; -pointer x/*0:1*/::string = pure_pointerval x/*0:1*/; --x/*0:1*/::int = -x/*0:1*/; -~x/*0:1*/::int = ~x/*0:1*/; -not x/*0:1*/::int = not x/*0:1*/; -x/*0:01*/::int<<y/*0:1*/::int = x/*0:01*/<<y/*0:1*/; -x/*0:01*/::int>>y/*0:1*/::int = x/*0:01*/>>y/*0:1*/; -x/*0:01*/::int+y/*0:1*/::int = x/*0:01*/+y/*0:1*/; -x/*0:01*/::int-y/*0:1*/::int = x/*0:01*/-y/*0:1*/; -x/*0:01*/::int*y/*0:1*/::int = x/*0:01*/*y/*0:1*/; -x/*0:01*/::int/y/*0:1*/::int = x/*0:01*//y/*0:1*/; -x/*0:01*/::int div y/*0:1*/::int = x/*0:01*/ div y/*0:1*/; -x/*0:01*/::int mod y/*0:1*/::int = x/*0:01*/ mod y/*0:1*/; -x/*0:01*/::int or y/*0:1*/::int = x/*0:01*/ or y/*0:1*/; -x/*0:01*/::int and y/*0:1*/::int = x/*0:01*/ and y/*0:1*/; -x/*0:01*/::int<y/*0:1*/::int = x/*0:01*/<y/*0:1*/; -x/*0:01*/::int>y/*0:1*/::int = x/*0:01*/>y/*0:1*/; -x/*0:01*/::int<=y/*0:1*/::int = x/*0:01*/<=y/*0:1*/; -x/*0:01*/::int>=y/*0:1*/::int = x/*0:01*/>=y/*0:1*/; -x/*0:01*/::int==y/*0:1*/::int = x/*0:01*/==y/*0:1*/; -x/*0:01*/::int!=y/*0:1*/::int = x/*0:01*/!=y/*0:1*/; --x/*0:1*/::double = -x/*0:1*/; -x/*0:01*/::double+y/*0:1*/::double = x/*0:01*/+y/*0:1*/; -x/*0:01*/::double-y/*0:1*/::double = x/*0:01*/-y/*0:1*/; -x/*0:01*/::double*y/*0:1*/::double = x/*0:01*/*y/*0:1*/; -x/*0:01*/::double/y/*0:1*/::double = x/*0:01*//y/*0:1*/; -x/*0:01*/::double<y/*0:1*/::double = x/*0:01*/<y/*0:1*/; -x/*0:01*/::double>y/*0:1*/::double = x/*0:01*/>y/*0:1*/; -x/*0:01*/::double<=y/*0:1*/::double = x/*0:01*/<=y/*0:1*/; -x/*0:01*/::double>=y/*0:1*/::double = x/*0:01*/>=y/*0:1*/; -x/*0:01*/::double==y/*0:1*/::double = x/*0:01*/==y/*0:1*/; -x/*0:01*/::double!=y/*0:1*/::double = x/*0:01*/!=y/*0:1*/; -x/*0:01*/::int+y/*0:1*/::double = x/*0:01*/+y/*0:1*/; -x/*0:01*/::int-y/*0:1*/::double = x/*0:01*/-y/*0:1*/; -x/*0:01*/::int*y/*0:1*/::double = x/*0:01*/*y/*0:1*/; -x/*0:01*/::int/y/*0:1*/::double = x/*0:01*//y/*0:1*/; -x/*0:01*/::int<y/*0:1*/::double = x/*0:01*/<y/*0:1*/; -x/*0:01*/::int>y/*0:1*/::double = x/*0:01*/>y/*0:1*/; -x/*0:01*/::int<=y/*0:1*/::double = x/*0:01*/<=y/*0:1*/; -x/*0:01*/::int>=y/*0:1*/::double = x/*0:01*/>=y/*0:1*/; -x/*0:01*/::int==y/*0:1*/::double = x/*0:01*/==y/*0:1*/; -x/*0:01*/::int!=y/*0:1*/::double = x/*0:01*/!=y/*0:1*/; -x/*0:01*/::double+y/*0:1*/::int = x/*0:01*/+y/*0:1*/; -x/*0:01*/::double-y/*0:1*/::int = x/*0:01*/-y/*0:1*/; -x/*0:01*/::double*y/*0:1*/::int = x/*0:01*/*y/*0:1*/; -x/*0:01*/::double/y/*0:1*/::int = x/*0:01*//y/*0:1*/; -x/*0:01*/::double<y/*0:1*/::int = x/*0:01*/<y/*0:1*/; -x/*0:01*/::double>y/*0:1*/::int = x/*0:01*/>y/*0:1*/; -x/*0:01*/::double<=y/*0:1*/::int = x/*0:01*/<=y/*0:1*/; -x/*0:01*/::double>=y/*0:1*/::int = x/*0:01*/>=y/*0:1*/; -x/*0:01*/::double==y/*0:1*/::int = x/*0:01*/==y/*0:1*/; -x/*0:01*/::double!=y/*0:1*/::int = x/*0:01*/!=y/*0:1*/; -x/*0:01*/::int&&y/*0:1*/::int = x/*0:01*/&&y/*0:1*/; -x/*0:01*/::int||y/*0:1*/::int = x/*0:01*/||y/*0:1*/; --x/*0:1*/::bigint = bigint_neg x/*0:1*/; -~x/*0:1*/::bigint = bigint_not x/*0:1*/; -not x/*0:1*/::bigint = not int x/*0:1*/; -x/*0:01*/::bigint<<y/*0:1*/::int = bigint_shl x/*0:01*/ y/*0:1*/ if y/*0:1*/>=0; -x/*0:01*/::bigint<<y/*0:1*/::int = bigint_shr x/*0:01*/ (-y/*0:1*/); -x/*0:01*/::bigint>>y/*0:1*/::int = bigint_shr x/*0:01*/ y/*0:1*/ if y/*0:1*/>=0; -x/*0:01*/::bigint>>y/*0:1*/::int = bigint_shl x/*0:01*/ (-y/*0:1*/); -x/*0:01*/::bigint+y/*0:1*/::bigint = bigint_add x/*0:01*/ y/*0:1*/; -x/*0:01*/::bigint-y/*0:1*/::bigint = bigint_sub x/*0:01*/ y/*0:1*/; -x/*0:01*/::bigint*y/*0:1*/::bigint = bigint_mul x/*0:01*/ y/*0:1*/; -x/*0:01*/::bigint/y/*0:1*/::bigint = double x/*0:01*//double y/*0:1*/; -x/*0:01*/::bigint div y/*0:1*/::bigint = bigint_div x/*0:01*/ y/*0:1*/; -x/*0:01*/::bigint mod y/*0:1*/::bigint = bigint_mod x/*0:01*/ y/*0:1*/; -x/*0:01*/::bigint or y/*0:1*/::bigint = bigint_or x/*0:01*/ y/*0:1*/; -x/*0:01*/::bigint and y/*0:1*/::bigint = bigint_and x/*0:01*/ y/*0:1*/; -x/*0:01*/::bigint<y/*0:1*/::bigint = bigint_cmp x/*0:01*/ y/*0:1*/<0; -x/*0:01*/::bigint>y/*0:1*/::bigint = bigint_cmp x/*0:01*/ y/*0:1*/>0; -x/*0:01*/::bigint<=y/*0:1*/::bigint = bigint_cmp x/*0:01*/ y/*0:1*/<=0; -x/*0:01*/::bigint>=y/*0:1*/::bigint = bigint_cmp x/*0:01*/ y/*0:1*/>=0; -x/*0:01*/::bigint==y/*0:1*/::bigint = bigint_cmp x/*0:01*/ y/*0:1*/==0; -x/*0:01*/::bigint!=y/*0:1*/::bigint = bigint_cmp x/*0:01*/ y/*0:1*/!=0; -x/*0:01*/::int+y/*0:1*/::bigint = bigint x/*0:01*/+y/*0:1*/; -x/*0:01*/::int-y/*0:1*/::bigint = bigint x/*0:01*/-y/*0:1*/; -x/*0:01*/::int*y/*0:1*/::bigint = bigint x/*0:01*/*y/*0:1*/; -x/*0:01*/::int/y/*0:1*/::bigint = double x/*0:01*//y/*0:1*/; -x/*0:01*/::int div y/*0:1*/::bigint = bigint x/*0:01*/ div y/*0:1*/; -x/*0:01*/::int mod y/*0:1*/::bigint = bigint x/*0:01*/ mod y/*0:1*/; -x/*0:01*/::int or y/*0:1*/::bigint = bigint x/*0:01*/ or y/*0:1*/; -x/*0:01*/::int and y/*0:1*/::bigint = bigint x/*0:01*/ and y/*0:1*/; -x/*0:01*/::int<y/*0:1*/::bigint = bigint x/*0:01*/<y/*0:1*/; -x/*0:01*/::int>y/*0:1*/::bigint = bigint x/*0:01*/>y/*0:1*/; -x/*0:01*/::int<=y/*0:1*/::bigint = bigint x/*0:01*/<=y/*0:1*/; -x/*0:01*/::int>=y/*0:1*/::bigint = bigint x/*0:01*/>=y/*0:1*/; -x/*0:01*/::int==y/*0:1*/::bigint = bigint x/*0:01*/==y/*0:1*/; -x/*0:01*/::int!=y/*0:1*/::bigint = bigint x/*0:01*/!=y/*0:1*/; -x/*0:01*/::bigint+y/*0:1*/::int = x/*0:01*/+bigint y/*0:1*/; -x/*0:01*/::bigint-y/*0:1*/::int = x/*0:01*/-bigint y/*0:1*/; -x/*0:01*/::bigint*y/*0:1*/::int = x/*0:01*/*bigint y/*0:1*/; -x/*0:01*/::bigint/y/*0:1*/::int = x/*0:01*//double y/*0:1*/; -x/*0:01*/::bigint div y/*0:1*/::int = x/*0:01*/ div bigint y/*0:1*/; -x/*0:01*/::bigint mod y/*0:1*/::int = x/*0:01*/ mod bigint y/*0:1*/; -x/*0:01*/::bigint or y/*0:1*/::int = x/*0:01*/ or bigint y/*0:1*/; -x/*0:01*/::bigint and y/*0:1*/::int = x/*0:01*/ and bigint y/*0:1*/; -x/*0:01*/::bigint<y/*0:1*/::int = x/*0:01*/<bigint y/*0:1*/; -x/*0:01*/::bigint>y/*0:1*/::int = x/*0:01*/>bigint y/*0:1*/; -x/*0:01*/::bigint<=y/*0:1*/::int = x/*0:01*/<=bigint y/*0:1*/; -x/*0:01*/::bigint>=y/*0:1*/::int = x/*0:01*/>=bigint y/*0:1*/; -x/*0:01*/::bigint==y/*0:1*/::int = x/*0:01*/==bigint y/*0:1*/; -x/*0:01*/::bigint!=y/*0:1*/::int = x/*0:01*/!=bigint y/*0:1*/; -x/*0:01*/::bigint+y/*0:1*/::double = double x/*0:01*/+y/*0:1*/; -x/*0:01*/::bigint-y/*0:1*/::double = double x/*0:01*/-y/*0:1*/; -x/*0:01*/::bigint*y/*0:1*/::double = double x/*0:01*/*y/*0:1*/; -x/*0:01*/::bigint/y/*0:1*/::double = double x/*0:01*//y/*0:1*/; -x/*0:01*/::bigint<y/*0:1*/::double = double x/*0:01*/<y/*0:1*/; -x/*0:01*/::bigint>y/*0:1*/::double = double x/*0:01*/>y/*0:1*/; -x/*0:01*/::bigint<=y/*0:1*/::double = double x/*0:01*/<=y/*0:1*/; -x/*0:01*/::bigint>=y/*0:1*/::double = double x/*0:01*/>=y/*0:1*/; -x/*0:01*/::bigint==y/*0:1*/::double = double x/*0:01*/==y/*0:1*/; -x/*0:01*/::bigint!=y/*0:1*/::double = double x/*0:01*/!=y/*0:1*/; -x/*0:01*/::double+y/*0:1*/::bigint = x/*0:01*/+double y/*0:1*/; -x/*0:01*/::double-y/*0:1*/::bigint = x/*0:01*/-double y/*0:1*/; -x/*0:01*/::double*y/*0:1*/::bigint = x/*0:01*/*double y/*0:1*/; -x/*0:01*/::double/y/*0:1*/::bigint = x/*0:01*//double y/*0:1*/; -x/*0:01*/::double<y/*0:1*/::bigint = x/*0:01*/<double y/*0:1*/; -x/*0:01*/::double>y/*0:1*/::bigint = x/*0:01*/>double y/*0:1*/; -x/*0:01*/::double<=y/*0:1*/::bigint = x/*0:01*/<=double y/*0:1*/; -x/*0:01*/::double>=y/*0:1*/::bigint = x/*0:01*/>=double y/*0:1*/; -x/*0:01*/::double==y/*0:1*/::bigint = x/*0:01*/==double y/*0:1*/; -x/*0:01*/::double!=y/*0:1*/::bigint = x/*0:01*/!=double y/*0:1*/; -gcd x/*0:01*/::bigint y/*0:1*/::bigint = bigint_gcd x/*0:01*/ y/*0:1*/; -lcm x/*0:01*/::bigint y/*0:1*/::bigint = bigint_lcm x/*0:01*/ y/*0:1*/; -gcd x/*0:01*/::int y/*0:1*/::bigint = bigint_gcd (bigint x/*0:01*/) y/*0:1*/; -gcd x/*0:01*/::bigint y/*0:1*/::int = bigint_gcd x/*0:01*/ (bigint y/*0:1*/); -gcd x/*0:01*/::int y/*0:1*/::int = int (bigint_gcd (bigint x/*0:01*/) (bigint y/*0:1*/)); -lcm x/*0:01*/::int y/*0:1*/::bigint = bigint_lcm (bigint x/*0:01*/) y/*0:1*/; -lcm x/*0:01*/::bigint y/*0:1*/::int = bigint_lcm x/*0:01*/ (bigint y/*0:1*/); -lcm x/*0:01*/::int y/*0:1*/::int = int (bigint_lcm (bigint x/*0:01*/) (bigint y/*0:1*/)); -pow x/*0:01*/::int y/*0:1*/::int = bigint_pow (bigint x/*0:01*/) y/*0:1*/ if y/*0:1*/>=0; -pow x/*0:01*/::bigint y/*0:1*/::bigint = bigint_pow x/*0:01*/ (int y/*0:1*/) if int y/*0:1*/>=0; -pow x/*0:01*/::double y/*0:1*/::double = c_pow x/*0:01*/ y/*0:1*/ if x/*0:01*/>=0||int y/*0:1*/==y/*0:1*/; -pow x/*0:01*/::int y/*0:1*/::bigint = bigint_pow (bigint x/*0:01*/) (int y/*0:1*/) if y/*0:1*/>=0; -pow x/*0:01*/::bigint y/*0:1*/::int = bigint_pow x/*0:01*/ y/*0:1*/ if y/*0:1*/>=0; -pow x/*0:01*/::double y/*0:1*/::int = c_pow x/*0:01*/ (double y/*0:1*/); -pow x/*0:01*/::double y/*0:1*/::bigint = c_pow x/*0:01*/ (double y/*0:1*/); -pow x/*0:01*/::int y/*0:1*/::double = c_pow (double x/*0:01*/) y/*0:1*/ if x/*0:01*/>=0||int y/*0:1*/==y/*0:1*/; -pow x/*0:01*/::bigint y/*0:1*/::double = c_pow (double x/*0:01*/) y/*0:1*/ if x/*0:01*/>=0||int y/*0:1*/==y/*0:1*/; -x/*0:01*/::double^y/*0:1*/::double = c_pow x/*0:01*/ y/*0:1*/ if x/*0:01*/>=0||int y/*0:1*/==y/*0:1*/; -x/*0:01*/::int^y/*0:1*/::int = c_pow (double x/*0:01*/) (double y/*0:1*/); -x/*0:01*/::bigint^y/*0:1*/::bigint = c_pow (double x/*0:01*/) (double y/*0:1*/); -x/*0:01*/::int^y/*0:1*/::bigint = c_pow (double x/*0:01*/) (double y/*0:1*/); -x/*0:01*/::bigint^y/*0:1*/::int = c_pow (double x/*0:01*/) (double y/*0:1*/); -x/*0:01*/::double^y/*0:1*/::int = c_pow x/*0:01*/ (double y/*0:1*/); -x/*0:01*/::double^y/*0:1*/::bigint = c_pow x/*0:01*/ (double y/*0:1*/); -x/*0:01*/::int^y/*0:1*/::double = c_pow (double x/*0:01*/) y/*0:1*/ if x/*0:01*/>=0||int y/*0:1*/==y/*0:1*/; -x/*0:01*/::bigint^y/*0:1*/::double = c_pow (double x/*0:01*/) y/*0:1*/ if x/*0:01*/>=0||int y/*0:1*/==y/*0:1*/; -x/*0:01*/::int^y/*0:1*/::double = double x/*0:01*/^y/*0:1*/; -x/*0:01*/::bigint^y/*0:1*/::double = double x/*0:01*/^y/*0:1*/; -null x/*0:1*/ = bigint x/*0:1*/==0; -x/*0:01*/-y/*0:1*/ = bigint x/*0:01*/-bigint y/*0:1*/; -x/*0:01*/+y/*0:1*/::int = pointer (bigint x/*0:01*/+y/*0:1*/); -x/*0:01*/+y/*0:1*/::bigint = pointer (bigint x/*0:01*/+y/*0:1*/); -x/*0:01*/<y/*0:1*/ = bigint x/*0:01*/<bigint y/*0:1*/; -x/*0:01*/>y/*0:1*/ = bigint x/*0:01*/>bigint y/*0:1*/; -x/*0:01*/<=y/*0:1*/ = bigint x/*0:01*/<=bigint y/*0:1*/; -x/*0:01*/>=y/*0:1*/ = bigint x/*0:01*/>=bigint y/*0:1*/; -x/*0:01*/==y/*0:1*/ = bigint x/*0:01*/==bigint y/*0:1*/; -x/*0:01*/!=y/*0:1*/ = bigint x/*0:01*/!=bigint y/*0:1*/; -get_byte x/*0:1*/ = pointer_get_byte x/*0:1*/; -get_int x/*0:1*/ = pointer_get_int x/*0:1*/; -get_double x/*0:1*/ = pointer_get_double x/*0:1*/; -get_string x/*0:1*/ = pointer_get_string x/*0:1*/; -get_pointer x/*0:1*/ = pointer_get_pointer x/*0:1*/; -put_byte x/*0:01*/ y/*0:1*/::int = pointer_put_byte x/*0:01*/ y/*0:1*/; -put_int x/*0:01*/ y/*0:1*/::int = pointer_put_int x/*0:01*/ y/*0:1*/; -put_double x/*0:01*/ y/*0:1*/::double = pointer_put_double x/*0:01*/ y/*0:1*/; -put_string x/*0:01*/ y/*0:1*/::string = pointer_put_string x/*0:01*/ y/*0:1*/; -put_pointer x/*0:01*/ y/*0:1*/::string = pointer_put_pointer x/*0:01*/ y/*0:1*/; -put_pointer x/*0:01*/ y/*0:1*/ = pointer_put_pointer x/*0:01*/ y/*0:1*/; -str x/*0:1*/ = cstring (pure_str x/*0:1*/); -chr n/*0:1*/::int = string_chr n/*0:1*/ if n/*0:1*/>0; -ord s/*0:1*/::string = string_ord s/*0:1*/ if #s/*0:1*/==1; -string s/*0:1*/ = pure_string s/*0:1*/; -cstring s/*0:1*/ = pure_cstring s/*0:1*/; -string_dup s/*0:1*/ = pure_string_dup s/*0:1*/; -cstring_dup s/*0:1*/ = pure_cstring_dup s/*0:1*/; -byte_string s/*0:1*/::string = pure_byte_string s/*0:1*/; -byte_cstring s/*0:1*/::string = pure_byte_cstring s/*0:1*/; -c/*0:01*/::string+n/*0:1*/::int = chr (ord c/*0:01*/+n/*0:1*/) if #c/*0:01*/==1; -c/*0:01*/::string-n/*0:1*/::int = chr (ord c/*0:01*/-n/*0:1*/) if #c/*0:01*/==1&&ord c/*0:01*/>=n/*0:1*/; -c/*0:01*/::string-d/*0:1*/::string = ord c/*0:01*/-ord d/*0:1*/ if #c/*0:01*/==1&&#d/*0:1*/==1; -null s/*0:1*/::string = string_null s/*0:1*/; -#s/*0:1*/::string = string_size s/*0:1*/; -s/*0:01*/::string!n/*0:1*/::int = string_char_at s/*0:01*/ n/*0:1*/ if n/*0:1*/>=0&&n/*0:1*/<#s/*0:01*/; -s/*0:01*/::string+t/*0:1*/::string = string_concat s/*0:01*/ t/*0:1*/; -chars s/*0:1*/::string = string_chars s/*0:1*/; -x/*0:01*/::string<y/*0:1*/::string = strcmp x/*0:01*/ y/*0:1*/<0; -x/*0:01*/::string>y/*0:1*/::string = strcmp x/*0:01*/ y/*0:1*/>0; -x/*0:01*/::string<=y/*0:1*/::string = strcmp x/*0:01*/ y/*0:1*/<=0; -x/*0:01*/::string>=y/*0:1*/::string = strcmp x/*0:01*/ y/*0:1*/>=0; -x/*0:01*/::string==y/*0:1*/::string = strcmp x/*0:01*/ y/*0:1*/==0; -x/*0:01*/::string!=y/*0:1*/::string = strcmp x/*0:01*/ y/*0:1*/!=0; -substr s/*0:001*/::string pos/*0:01*/::int size/*0:1*/::int = string_substr s/*0:001*/ (max/*0*/ 0 pos/*0:01*/) (max/*0*/ 0 size/*0:1*/) with max x/*0:01*/ y/*0:1*/ = if x/*0:01*/>=y/*0:1*/ then x/*0:01*/ else y/*0:1*/ { - rule #0: max x y = if x>=y then x else y - state 0: #0 - <var> state 1 - state 1: #0 - <var> state 2 - state 2: #0 -} end; -index s/*0:01*/::string u/*0:1*/::string = string_index s/*0:01*/ u/*0:1*/; -strcat xs/*0:1*/ = string_concat_list xs/*0:1*/ if listp xs/*0:1*/&&all stringp xs/*0:1*/; -join delim/*0:01*/::string [] = ""; -join delim/*0:01*/::string (x/*0:101*/::string:xs/*0:11*/) = x/*0:101*/+strcat (catmap (\x/*0:*/ -> [delim/*1:01*/+x/*0:*/] { - rule #0: x = [delim+x] - state 0: #0 - <var> state 1 - state 1: #0 -}) xs/*0:11*/) if listp xs/*0:11*/&&all stringp xs/*0:11*/; -split delim/*0:01*/::string s/*0:1*/::string = if null s/*1:1*/ then [] else split1/*0*/ delim/*1:01*/ s/*1:1*/ with split1 delim/*0:01*/ s/*0:1*/ = case index s/*0:1*/ delim/*0:01*/ of n/*0:*/ = take n/*0:*/ s/*1:1*/:split1/*2*/ delim/*1:01*/ (drop (n/*0:*/+m/*2:*/) s/*1:1*/) if n/*0:*/>=0; n/*0:*/ = [s/*1:1*/] { - rule #0: n = take n s:split1 delim (drop (n+m) s) if n>=0 - rule #1: n = [s] - state 0: #0 #1 - <var> state 1 - state 1: #0 #1 -} end { - rule #0: split1 delim s = case index s delim of n = take n s:split1 delim (drop (n+m) s) if n>=0; n = [s] end - state 0: #0 - <var> state 1 - state 1: #0 - <var> state 2 - state 2: #0 -} end when m/*0:*/ = #delim/*0:01*/ { - rule #0: m = #delim - state 0: #0 - <var> state 1 - state 1: #0 -} end if not null delim/*0:01*/; -list s/*0:1*/::string = chars s/*0:1*/; -tuple s/*0:1*/::string = tuple (chars s/*0:1*/); -reverse s/*0:1*/::string = strcat (reverse (chars s/*0:1*/)); -cat (s/*0:101*/::string:xs/*0:11*/) = cat (chars s/*0:101*/:xs/*0:11*/); -cycle n/*0:01*/::int "" = ""; -cycle n/*0:01*/::int s/*0:1*/::string = "" if n/*0:01*/<=0; -cycle n/*0:01*/::int s/*0:1*/::string = accum/*0*/ [] n/*1:01*/ with accum ys/*0:01*/ n/*0:1*/ = strcat ys/*0:01*/+take n/*0:1*/ s/*2:1*/ if n/*0:1*/<=m/*1:*/; accum ys/*0:01*/ n/*0:1*/ = accum/*1*/ (s/*2:1*/:ys/*0:01*/) (n/*0:1*/-m/*1:*/) { - rule #0: accum ys n = strcat ys+take n s if n<=m - rule #1: accum ys n = accum (s:ys) (n-m) - state 0: #0 #1 - <var> state 1 - state 1: #0 #1 - <var> state 2 - state 2: #0 #1 -} end when m/*0:*/::int = #s/*0:1*/ { - rule #0: m::int = #s - state 0: #0 - <var>::int state 1 - state 1: #0 -} end; -all p/*0:01*/ s/*0:1*/::string = all p/*0:01*/ (chars s/*0:1*/); -any p/*0:01*/ s/*0:1*/::string = any p/*0:01*/ (chars s/*0:1*/); -do f/*0:01*/ s/*0:1*/::string = do f/*0:01*/ (chars s/*0:1*/); -drop n/*0:01*/ s/*0:1*/::string = substr s/*0:1*/ n/*0:01*/ (#s/*0:1*/-n/*0:01*/); -dropwhile p/*0:01*/ s/*0:1*/::string = strcat (dropwhile p/*0:01*/ (chars s/*0:1*/)); -filter p/*0:01*/ s/*0:1*/::string = strcat (filter p/*0:01*/ (chars s/*0:1*/)); -foldl f/*0:001*/ a/*0:01*/ s/*0:1*/::string = foldl f/*0:001*/ a/*0:01*/ (chars s/*0:1*/); -foldl1 f/*0:01*/ s/*0:1*/::string = foldl1 f/*0:01*/ (chars s/*0:1*/); -foldr f/*0:001*/ a/*0:01*/ s/*0:1*/::string = foldr f/*0:001*/ a/*0:01*/ (chars s/*0:1*/); -foldr1 f/*0:01*/ s/*0:1*/::string = foldr1 f/*0:01*/ (chars s/*0:1*/); -head s/*0:1*/::string = s/*0:1*/!0 if not null s/*0:1*/; -init s/*0:1*/::string = substr s/*0:1*/ 0 (#s/*0:1*/-1) if not null s/*0:1*/; -last s/*0:1*/::string = s/*0:1*/!(#s/*0:1*/-1) if not null s/*0:1*/; -map f/*0:01*/ s/*0:1*/::string = map f/*0:01*/ (chars s/*0:1*/); -scanl f/*0:001*/ a/*0:01*/ s/*0:1*/::string = scanl f/*0:001*/ a/*0:01*/ (chars s/*0:1*/); -scanl1 f/*0:01*/ s/*0:1*/::string = scanl1 f/*0:01*/ (chars s/*0:1*/); -scanr f/*0:001*/ a/*0:01*/ s/*0:1*/::string = scanr f/*0:001*/ a/*0:01*/ (chars s/*0:1*/); -scanr1 f/*0:01*/ s/*0:1*/::string = scanr1 f/*0:01*/ (chars s/*0:1*/); -take n/*0:01*/ s/*0:1*/::string = substr s/*0:1*/ 0 n/*0:01*/; -takewhile p/*0:01*/ s/*0:1*/::string = strcat (takewhile p/*0:01*/ (chars s/*0:1*/)); -tail s/*0:1*/::string = substr s/*0:1*/ 1 (#s/*0:1*/-1) if not null s/*0:1*/; -zip s/*0:01*/::string t/*0:1*/::string = zip (chars s/*0:01*/) (chars t/*0:1*/); -zip3 s/*0:001*/::string t/*0:01*/::string u/*0:1*/::string = zip3 (chars s/*0:001*/) (chars t/*0:01*/) (chars u/*0:1*/); -zipwith f/*0:001*/ s/*0:01*/::string t/*0:1*/::string = zipwith f/*0:001*/ (chars s/*0:01*/) (chars t/*0:1*/); -zipwith3 f/*0:0001*/ s/*0:001*/::string t/*0:01*/::string u/*0:1*/::string = zipwith3 f/*0:0001*/ (chars s/*0:001*/) (chars t/*0:01*/) (chars u/*0:1*/); -dowith f/*0:001*/ s/*0:01*/::string t/*0:1*/::string = dowith f/*0:001*/ (chars s/*0:01*/) (chars t/*0:1*/); -dowith3 f/*0:0001*/ s/*0:001*/::string t/*0:01*/::string u/*0:1*/::string = dowith3 f/*0:0001*/ (chars s/*0:001*/) (chars t/*0:01*/) (chars u/*0:1*/); f/*0:01*/$x/*0:1*/ = f/*0:01*/ x/*0:1*/; (f/*0:001*/.g/*0:01*/) x/*0:1*/ = f/*0:001*/ (g/*0:01*/ x/*0:1*/); void _/*0:1*/ = (); Modified: pure/trunk/test/test011.log =================================================================== --- pure/trunk/test/test011.log 2008-07-02 23:31:57 UTC (rev 373) +++ pure/trunk/test/test011.log 2008-07-03 00:19:47 UTC (rev 374) @@ -1,2107 +1,3 @@ -pure_sys_vars; -errno = pure_errno; -set_errno val/*0:1*/::int = pure_set_errno val/*0:1*/; -fgets f/*0:1*/ = read_a_line/*1*/ f/*1:1*/ buf/*0:*/ "" when buf/*0:*/ = malloc 1024 { - rule #0: buf = malloc 1024 - state 0: #0 - <var> state 1 - state 1: #0 -} end with read_a_line f/*0:001*/ buf/*0:01*/ t/*0:1*/ = check/*1*/ s/*0:*/ when s/*0:*/ = c_fgets buf/*0:01*/ 1024 f/*0:001*/ { - rule #0: s = c_fgets buf 1024 f - state 0: #0 - <var> state 1 - state 1: #0 -} end with check s/*0:1*/::string = return/*1*/ (t/*1:1*/+s/*0:1*/) if done/*1*/ s/*0:1*/; check s/*0:1*/::string = read_a_line/*2*/ f/*1:001*/ buf/*1:01*/ (t/*1:1*/+s/*0:1*/); check s/*0:1*/ = return/*1*/ s/*0:1*/ if null t/*1:1*/; check s/*0:1*/ = return/*1*/ t/*1:1*/ { - rule #0: check s::string = return (t+s) if done s - rule #1: check s::string = read_a_line f buf (t+s) - rule #2: check s = return s if null t - rule #3: check s = return t - state 0: #0 #1 #2 #3 - <var> state 1 - <var>::string state 2 - state 1: #2 #3 - state 2: #0 #1 #2 #3 -}; return x/*0:1*/ = x/*1:1*/ when _/*0:*/ = free buf/*1:01*/ { - rule #0: _ = free buf - state 0: #0 - <var> state 1 - state 1: #0 -} end { - rule #0: return x = x when _ = free buf end - state 0: #0 - <var> state 1 - state 1: #0 -}; done s/*0:1*/::string = feof f/*1:001*/||ferror f/*1:001*/||not null s/*0:1*/&&last s/*0:1*/=="\n" { - rule #0: done s::string = feof f||ferror f||not null s&&last s=="\n" - state 0: #0 - <var>::string state 1 - state 1: #0 -} end { - rule #0: read_a_line f buf t = check s when s = c_fgets buf 1024 f end with check s::string = return (t+s) if done s; check s::string = read_a_line f buf (t+s); check s = return s if null t; check s = return t; return x = x when _ = free buf end; done s::string = feof f||ferror f||not null s&&last s=="\n" end - state 0: #0 - <var> state 1 - state 1: #0 - <var> state 2 - state 2: #0 - <var> state 3 - state 3: #0 -} end; -gets = if null s/*0:*/ then s/*0:*/ else if last s/*0:*/=="\n" then init s/*0:*/ else s/*0:*/ when s/*0:*/ = fgets stdin { - rule #0: s = fgets stdin - state 0: #0 - <var> state 1 - state 1: #0 -} end; -fget f/*0:1*/ = read_a_file/*1*/ f/*1:1*/ buf/*0:*/ "" when buf/*0:*/ = malloc 65536 { - rule #0: buf = malloc 65536 - state 0: #0 - <var> state 1 - state 1: #0 -} end with read_a_file f/*0:001*/ buf/*0:01*/ t/*0:1*/ = check/*1*/ s/*0:*/ when s/*0:*/ = c_fgets buf/*0:01*/ 65536 f/*0:001*/ { - rule #0: s = c_fgets buf 65536 f - state 0: #0 - <var> state 1 - state 1: #0 -} end with check s/*0:1*/::string = return/*1*/ (t/*1:1*/+s/*0:1*/) if feof f/*1:001*/||ferror f/*1:001*/; check s/*0:1*/::string = read_a_file/*2*/ f/*1:001*/ buf/*1:01*/ (t/*1:1*/+s/*0:1*/); check s/*0:1*/ = return/*1*/ s/*0:1*/ if null t/*1:1*/; check s/*0:1*/ = return/*1*/ t/*1:1*/ { - rule #0: check s::string = return (t+s) if feof f||ferror f - rule #1: check s::string = read_a_file f buf (t+s) - rule #2: check s = return s if null t - rule #3: check s = return t - state 0: #0 #1 #2 #3 - <var> state 1 - <var>::string state 2 - state 1: #2 #3 - state 2: #0 #1 #2 #3 -}; return x/*0:1*/ = x/*1:1*/ when _/*0:*/ = free buf/*1:01*/ { - rule #0: _ = free buf - state 0: #0 - <var> state 1 - state 1: #0 -} end { - rule #0: return x = x when _ = free buf end - state 0: #0 - <var> state 1 - state 1: #0 -} end { - rule #0: read_a_file f buf t = check s when s = c_fgets buf 65536 f end with check s::string = return (t+s) if feof f||ferror f; check s::string = read_a_file f buf (t+s); check s = return s if null t; check s = return t; return x = x when _ = free buf end end - state 0: #0 - <var> state 1 - state 1: #0 - <var> state 2 - state 2: #0 - <var> state 3 - state 3: #0 -} end; -printf format/*0:01*/::string args/*0:1*/ = fprintf stdout format/*0:01*/ args/*0:1*/; -fprintf fp/*0:001*/ format/*0:01*/::string args/*0:1*/ = count/*0:01*/ when args/*0:*/ = if tuplep args/*0:1*/ then list args/*0:1*/ else [args/*0:1*/]; count/*0:01*/,_/*0:1*/ = catch error_handler/*1*/ (foldl (do_fprintf/*2*/ fp/*2:001*/) (0,args/*1:*/)$printf_split_format format/*2:01*/) { - rule #0: count,_ = catch error_handler (foldl (do_fprintf fp) (0,args)$printf_split_format format) - state 0: #0 - <app> state 1 - state 1: #0 - <app> state 2 - state 2: #0 - , state 3 - state 3: #0 - <var> state 4 - state 4: #0 - <var> state 5 - state 5: #0 -} { - rule #0: args = if tuplep args then list args else [args] - state 0: #0 - <var> state 1 - state 1: #0 -} end with error_handler (printf_error res/*0:11*/::int) = res/*0:11*/,[]; error_handler x/*0:1*/ = throw x/*0:1*/ { - rule #0: error_handler (printf_error res::int) = res,[] - rule #1: error_handler x = throw x - state 0: #0 #1 - <var> state 1 - <app> state 2 - state 1: #1 - state 2: #0 #1 - <var> state 3 - printf_error state 5 - state 3: #1 - <var> state 4 - state 4: #1 - state 5: #0 #1 - <var> state 6 - <var>::int state 7 - state 6: #1 - state 7: #0 #1 -}; do_fprintf fp/*0:001*/ (count/*0:0101*/,arg/*0:01101*/:args/*0:0111*/) (printf_format_spec t/*0:101*/ s/*0:11*/) = count/*0:*/,args/*2:0111*/ when res/*0:*/ = case t/*0:101*/,arg/*0:01101*/ of "d",x/*0:1*/::int = pure_fprintf_int fp/*1:001*/ s/*1:11*/ x/*0:1*/; "d",x/*0:1*/::bigint = pure_fprintf_int fp/*1:001*/ s/*1:11*/ (int x/*0:1*/); "g",x/*0:1*/::double = pure_fprintf_double fp/*1:001*/ s/*1:11*/ x/*0:1*/; "s",x/*0:1*/::string = pure_fprintf_string fp/*1:001*/ s/*1:11*/ x/*0:1*/; "p",x/*0:1*/::string = pure_fprintf_pointer fp/*1:001*/ s/*1:11*/ x/*0:1*/; "p",x/*0:1*/ = pure_fprintf_pointer fp/*1:001*/ s/*1:11*/ x/*0:1*/; _/*0:*/ = throw (printf_value_error s/*1:11*/ arg/*1:01101*/) { - rule #0: "d",x::int = pure_fprintf_int fp s x - rule #1: "d",x::bigint = pure_fprintf_int fp s (int x) - rule #2: "g",x::double = pure_fprintf_double fp s x - rule #3: "s",x::string = pure_fprintf_string fp s x - rule #4: "p",x::string = pure_fprintf_pointer fp s x - rule #5: "p",x = pure_fprintf_pointer fp s x - rule #6: _ = throw (printf_value_error s arg) - state 0: #0 #1 #2 #3 #4 #5 #6 - <var> state 1 - <app> state 2 - state 1: #6 - state 2: #0 #1 #2 #3 #4 #5 #6 - <var> state 3 - <app> state 5 - state 3: #6 - <var> state 4 - state 4: #6 - state 5: #0 #1 #2 #3 #4 #5 #6 - <var> state 6 - , state 9 - state 6: #6 - <var> state 7 - state 7: #6 - <var> state 8 - state 8: #6 - state 9: #0 #1 #2 #3 #4 #5 #6 - <var> state 10 - "d"::string state 12 - "g"::string state 16 - "s"::string state 19 - "p"::string state 22 - state 10: #6 - <var> state 11 - state 11: #6 - state 12: #0 #1 #6 - <var> state 13 - <var>::int state 14 - <var>::bigint state 15 - state 13: #6 - state 14: #0 #6 - state 15: #1 #6 - state 16: #2 #6 - <var> state 17 - <var>::double state 18 - state 17: #6 - state 18: #2 #6 - state 19: #3 #6 - <var> state 20 - <var>::string state 21 - state 20: #6 - state 21: #3 #6 - state 22: #4 #5 #6 - <var> state 23 - <var>::string state 24 - <var> state 25 - state 23: #6 - state 24: #4 #6 - state 25: #5 #6 -} end; count/*0:*/ = if res/*0:*/>=0 then count/*1:0101*/+res/*0:*/ else throw printf_error res/*0:*/ { - rule #0: count = if res>=0 then count+res else throw printf_error res - state 0: #0 - <var> state 1 - state 1: #0 -} { - rule #0: res = case t,arg of "d",x::int = pure_fprintf_int fp s x; "d",x::bigint = pure_fprintf_int fp s (int x); "g",x::double = pure_fprintf_double fp s x; "s",x::string = pure_fprintf_string fp s x; "p",x::string = pure_fprintf_pointer fp s x; "p",x = pure_fprintf_pointer fp s x; _ = throw (printf_value_error s arg) end - state 0: #0 - <var> state 1 - state 1: #0 -} end; do_fprintf fp/*0:001*/ (count/*0:0101*/,args/*0:011*/) (printf_format_str s/*0:11*/) = count/*0:*/,args/*2:011*/ when res/*0:*/ = pure_fprintf fp/*0:001*/ s/*0:11*/; count/*0:*/ = if res/*0:*/>=0 then count/*1:0101*/+res/*0:*/ else throw printf_error res/*0:*/ { - rule #0: count = if res>=0 then count+res else throw printf_error res - state 0: #0 - <var> state 1 - state 1: #0 -} { - rule #0: res = pure_fprintf fp s - state 0: #0 - <var> state 1 - state 1: #0 -} end; do_fprintf fp/*0:001*/ (count/*0:0101*/,_/*0:011*/) _/*0:1*/ = throw printf_arg_error { - rule #0: do_fprintf fp (count,arg:args) (printf_format_spec t s) = count,args when res = case t,arg of "d",x::int = pure_fprintf_int fp s x; "d",x::bigint = pure_fprintf_int fp s (int x); "g",x::double = pure_fprintf_double fp s x; "s",x::string = pure_fprintf_string fp s x; "p",x::string = pure_fprintf_pointer fp s x; "p",x = pure_fprintf_pointer fp s x; _ = throw (printf_value_error s arg) end; count = if res>=0 then count+res else throw printf_error res end - rule #1: do_fprintf fp (count,args) (printf_format_str s) = count,args when res = pure_fprintf fp s; count = if res>=0 then count+res else throw printf_error res end - rule #2: do_fprintf fp (count,_) _ = throw printf_arg_error - state 0: #0 #1 #2 - <var> state 1 - state 1: #0 #1 #2 - <app> state 2 - state 2: #0 #1 #2 - <app> state 3 - state 3: #0 #1 #2 - , state 4 - state 4: #0 #1 #2 - <var> state 5 - state 5: #0 #1 #2 - <var> state 6 - <app> state 13 - state 6: #1 #2 - <var> state 7 - <app> state 8 - state 7: #2 - state 8: #1 #2 - <var> state 9 - printf_format_str state 11 - state 9: #2 - <var> state 10 - state 10: #2 - state 11: #1 #2 - <var> state 12 - state 12: #1 #2 - state 13: #0 #1 #2 - <var> state 14 - <app> state 22 - state 14: #1 #2 - <var> state 15 - state 15: #1 #2 - <var> state 16 - <app> state 17 - state 16: #2 - state 17: #1 #2 - <var> state 18 - printf_format_str state 20 - state 18: #2 - <var> state 19 - state 19: #2 - state 20: #1 #2 - <var> state 21 - state 21: #1 #2 - state 22: #0 #1 #2 - <var> state 23 - : state 32 - state 23: #1 #2 - <var> state 24 - state 24: #1 #2 - <var> state 25 - state 25: #1 #2 - <var> state 26 - <app> state 27 - state 26: #2 - state 27: #1 #2 - <var> state 28 - printf_format_str state 30 - state 28: #2 - <var> state 29 - state 29: #2 - state 30: #1 #2 - <var> state 31 - state 31: #1 #2 - state 32: #0 #1 #2 - <var> state 33 - state 33: #0 #1 #2 - <var> state 34 - state 34: #0 #1 #2 - <var> state 35 - <app> state 36 - state 35: #2 - state 36: #0 #1 #2 - <var> state 37 - <app> state 39 - printf_format_str state 46 - state 37: #2 - <var> state 38 - state 38: #2 - state 39: #0 #2 - <var> state 40 - printf_format_spec state 43 - state 40: #2 - <var> state 41 - state 41: #2 - <var> state 42 - state 42: #2 - state 43: #0 #2 - <var> state 44 - state 44: #0 #2 - <var> state 45 - state 45: #0 #2 - state 46: #1 #2 - <var> state 47 - state 47: #1 #2 -} end; -printf_split_format format/*0:1*/ = regexg analyze/*0*/ "(%[-#0 ]?[0-9]*([.][0-9]*)?[diouxXeEfgGsp])|(%)|([^%]|%%)+" REG_EXTENDED format/*0:1*/ 0 with analyze info/*0:1*/ = if p/*1:01*/>=0 then printf_format_spec (format_type/*4*/ (last u/*2:1*/)) u/*2:1*/ else if q/*0:01*/>=0 then throw (printf_format_error q/*0:01*/) else printf_format_str u/*2:1*/ when _/*0:01*/,u/*0:1*/ = reg 0 info/*0:1*/; p/*0:01*/,_/*0:1*/ = reg 1 info/*1:1*/; q/*0:01*/,_/*0:1*/ = reg 3 info/*2:1*/ { - rule #0: q,_ = reg 3 info - state 0: #0 - <app> state 1 - state 1: #0 - <app> state 2 - state 2: #0 - , state 3 - state 3: #0 - <var> state 4 - state 4: #0 - <var> state 5 - state 5: #0 -} { - rule #0: p,_ = reg 1 info - state 0: #0 - <app> state 1 - state 1: #0 - <app> state 2 - state 2: #0 - , state 3 - state 3: #0 - <var> state 4 - state 4: #0 - <var> state 5 - state 5: #0 -} { - rule #0: _,u = reg 0 info - state 0: #0 - <app> state 1 - state 1: #0 - <app> state 2 - state 2: #0 - , state 3 - state 3: #0 - <var> state 4 - state 4: #0 - <var> state 5 - state 5: #0 -} end { - rule #0: analyze info = if p>=0 then printf_format_spec (format_type (last u)) u else if q>=0 then throw (printf_format_error q) else printf_format_str u when _,u = reg 0 info; p,_ = reg 1 info; q,_ = reg 3 info end - state 0: #0 - <var> state 1 - state 1: #0 -}; format_type x/*0:1*/ = if index "diouxX" x/*0:1*/>=0 then "d" else if index "eEfgG" x/*0:1*/>=0 then "g" else x/*0:1*/ { - rule #0: format_type x = if index "diouxX" x>=0 then "d" else if index "eEfgG" x>=0 then "g" else x - state 0: #0 - <var> state 1 - state 1: #0 -} end; -sprintf format/*0:01*/::string args/*0:1*/ = s/*0:01*/ when args/*0:*/ = if tuplep args/*0:1*/ then list args/*0:1*/ else [args/*0:1*/]; s/*0:01*/,_/*0:1*/ = catch error_handler/*1*/ (foldl do_sprintf/*2*/ ("",args/*1:*/)$printf_split_format format/*2:01*/) { - rule #0: s,_ = catch error_handler (foldl do_sprintf ("",args)$printf_split_format format) - state 0: #0 - <app> state 1 - state 1: #0 - <app> state 2 - state 2: #0 - , state 3 - state 3: #0 - <var> state 4 - state 4: #0 - <var> state 5 - state 5: #0 -} { - rule #0: args = if tuplep args then list args else [args] - state 0: #0 - <var> state 1 - state 1: #0 -} end with error_handler (printf_error res/*0:11*/::int) = pointer 0,[]; error_handler x/*0:1*/ = throw x/*0:1*/ { - rule #0: error_handler (printf_error res::int) = pointer 0,[] - rule #1: error_handler x = throw x - state 0: #0 #1 - <var> state 1 - <app> state 2 - state 1: #1 - state 2: #0 #1 - <var> state 3 - printf_error state 5 - state 3: #1 - <var> state 4 - state 4: #1 - state 5: #0 #1 - <var> state 6 - <var>::int state 7 - state 6: #1 - state 7: #0 #1 -}; do_sprintf (u/*0:0101*/,arg/*0:01101*/:args/*0:0111*/) (printf_format_spec t/*0:101*/ s/*0:11*/) = u/*0:*/,args/*4:0111*/ when size/*0:*/ = case t/*0:101*/,arg/*0:01101*/ of "s",x/*0:1*/::string = #s/*1:11*/+#x/*0:1*/+1000; _/*0:*/ = 64 { - rule #0: "s",x::string = #s+#x+1000 - rule #1: _ = 64 - state 0: #0 #1 - <var> state 1 - <app> state 2 - state 1: #1 - state 2: #0 #1 - <var> state 3 - <app> state 5 - state 3: #1 - <var> state 4 - state 4: #1 - state 5: #0 #1 - <var> state 6 - , state 9 - state 6: #1 - <var> state 7 - state 7: #1 - <var> state 8 - state 8: #1 - state 9: #0 #1 - <var> state 10 - "s"::string state 12 - state 10: #1 - <var> state 11 - state 11: #1 - state 12: #0 #1 - <var> state 13 - <var>::string state 14 - state 13: #1 - state 14: #0 #1 -} end; buf/*0:*/ = check_buf/*2*/ (malloc size/*0:*/); res/*0:*/ = case t/*2:101*/,arg/*2:01101*/ of "d",x/*0:1*/::int = pure_snprintf_int buf/*1:*/ size/*2:*/ s/*3:11*/ x/*0:1*/; "d",x/*0:1*/::bigint = pure_snprintf_int buf/*1:*/ size/*2:*/ s/*3:11*/ (int x/*0:1*/); "g",x/*0:1*/::double = pure_snprintf_double buf/*1:*/ size/*2:*/ s/*3:11*/ x/*0:1*/; "s",x/*0:1*/::string = pure_snprintf_string buf/*1:*/ size/*2:*/ s/*3:11*/ x/*0:1*/; "p",x/*0:1*/::string = pure_snprintf_pointer buf/*1:*/ size/*2:*/ s/*3:11*/ x/*0:1*/; "p",x/*0:1*/ = pure_snprintf_pointer buf/*1:*/ size/*2:*/ s/*3:11*/ x/*0:1*/; _/*0:*/ = throw (printf_value_error s/*4:11*/ arg/*4:01101*/) when _/*0:*/ = free buf/*1:*/ { - rule #0: _ = free buf - state 0: #0 - <var> state 1 - state 1: #0 -} end { - rule #0: "d",x::int = pure_snprintf_int buf size s x - rule #1: "d",x::bigint = pure_snprintf_int buf size s (int x) - rule #2: "g",x::double = pure_snprintf_double buf size s x - rule #3: "s",x::string = pure_snprintf_string buf size s x - rule #4: "p",x::string = pure_snprintf_pointer buf size s x - rule #5: "p",x = pure_snprintf_pointer buf size s x - rule #6: _ = throw (printf_value_error s arg) when _ = free buf end - state 0: #0 #1 #2 #3 #4 #5 #6 - <var> state 1 - <app> state 2 - state 1: #6 - state 2: #0 #1 #2 #3 #4 #5 #6 - <var> state 3 - <app> state 5 - state 3: #6 - <var> state 4 - state 4: #6 - state 5: #0 #1 #2 #3 #4 #5 #6 - <var> state 6 - , state 9 - state 6: #6 - <var> state 7 - state 7: #6 - <var> state 8 - state 8: #6 - state 9: #0 #1 #2 #3 #4 #5 #6 - <var> state 10 - "d"::string state 12 - "g"::string state 16 - "s"::string state 19 - "p"::string state 22 - state 10: #6 - <var> state 11 - state 11: #6 - state 12: #0 #1 #6 - <var> state 13 - <var>::int state 14 - <var>::bigint state 15 - state 13: #6 - state 14: #0 #6 - state 15: #1 #6 - state 16: #2 #6 - <var> state 17 - <var>::double state 18 - state 17: #6 - state 18: #2 #6 - state 19: #3 #6 - <var> state 20 - <var>::string state 21 - state 20: #6 - state 21: #3 #6 - state 22: #4 #5 #6 - <var> state 23 - <var>::string state 24 - <var> state 25 - state 23: #6 - state 24: #4 #6 - state 25: #5 #6 -} end; u/*0:*/ = if res/*0:*/>=0 then u/*3:0101*/+cstring buf/*1:*/ else throw printf_error res/*1:*/ when _/*0:*/ = free buf/*1:*/ { - rule #0: _ = free buf - state 0: #0 - <var> state 1 - state 1: #0 -} end { - rule #0: u = if res>=0 then u+cstring buf else throw printf_error res when _ = free buf end - state 0: #0 - <var> state 1 - state 1: #0 -} { - rule #0: res = case t,arg of "d",x::int = pure_snprintf_int buf size s x; "d",x::bigint = pure_snprintf_int buf size s (int x); "g",x::double = pure_snprintf_double buf size s x; "s",x::string = pure_snprintf_string buf size s x; "p",x::string = pure_snprintf_pointer buf size s x; "p",x = pure_snprintf_pointer buf size s x; _ = throw (printf_value_error s arg) when _ = free buf end end - state 0: #0 - <var> state 1 - state 1: #0 -} { - rule #0: buf = check_buf (malloc size) - state 0: #0 - <var> state 1 - state 1: #0 -} { - rule #0: size = case t,arg of "s",x::string = #s+#x+1000; _ = 64 end - state 0: #0 - <var> state 1 - state 1: #0 -} end; do_sprintf (u/*0:0101*/,args/*0:011*/) (printf_format_str s/*0:11*/) = u/*0:*/,args/*4:011*/ when size/*0:*/ = #s/*0:11*/+1000; buf/*0:*/ = check_buf/*2*/ (malloc size/*0:*/); res/*0:*/ = pure_snprintf buf/*0:*/ size/*1:*/ s/*2:11*/; u/*0:*/ = if res/*0:*/>=0 then u/*3:0101*/+cstring buf/*1:*/ else throw printf_error res/*1:*/ when _/*0:*/ = free buf/*1:*/ { - rule #0: _ = free buf - state 0: #0 - <var> state 1 - state 1: #0 -} end { - rule #0: u = if res>=0 then u+cstring buf else throw printf_error res when _ = free buf end - state 0: #0 - <var> state 1 - state 1: #0 -} { - rule #0: res = pure_snprintf buf size s - state 0: #0 - <var> state 1 - state 1: #0 -} { - rule #0: buf = check_buf (malloc size) - state 0: #0 - <var> state 1 - state 1: #0 -} { - rule #0: size = #s+1000 - state 0: #0 - <var> state 1 - state 1: #0 -} end; do_sprintf (u/*0:0101*/,_/*0:011*/) _/*0:1*/ = throw printf_arg_error { - rule #0: do_sprintf (u,arg:args) (printf_format_spec t s) = u,args when size = case t,arg of "s",x::string = #s+#x+1000; _ = 64 end; buf = check_buf (malloc size); res = case t,arg of "d",x::int = pure_snprintf_int buf size s x; "d",x::bigint = pure_snprintf_int buf size s (int x); "g",x::double = pure_snprintf_double buf size s x; "s",x::string = pure_snprintf_string buf size s x; "p",x::string = pure_snprintf_pointer buf size s x; "p",x = pure_snprintf_pointer buf size s x; _ = throw (printf_value_error s arg) when _ = free buf end end; u = if res>=0 then u+cstring buf else throw printf_error res when _ = free buf end end - rule #1: do_sprintf (u,args) (printf_format_str s) = u,args when size = #s+1000; buf = check_buf (malloc size); res = pure_snprintf buf size s; u = if res>=0 then u+cstring buf else throw printf_error res when _ = free buf end end - rule #2: do_sprintf (u,_) _ = throw printf_arg_error - state 0: #0 #1 #2 - <app> state 1 - state 1: #0 #1 #2 - <app> state 2 - state 2: #0 #1 #2 - , state 3 - state 3: #0 #1 #2 - <var> state 4 - state 4: #0 #1 #2 - <var> state 5 - <app> state 12 - state 5: #1 #2 - <var> state 6 - <app> state 7 - state 6: #2 - state 7: #1 #2 - <var> state 8 - printf_format_str state 10 - state 8: #2 - <var> state 9 - state 9: #2 - state 10: #1 #2 - <var> state 11 - state 11: #1 #2 - state 12: #0 #1 #2 - <var> state 13 - <app> state 21 - state 13: #1 #2 - <var> state 14 - state 14: #1 #2 - <var> state 15 - <app> state 16 - state 15: #2 - state 16: #1 #2 - <var> state 17 - printf_format_str state 19 - state 17: #2 - <var> state 18 - state 18: #2 - state 19: #1 #2 - <var> state 20 - state 20: #1 #2 - state 21: #0 #1 #2 - <var> state 22 - : state 31 - state 22: #1 #2 - <var> state 23 - state 23: #1 #2 - <var> state 24 - state 24: #1 #2 - <var> state 25 - <app> state 26 - state 25: #2 - state 26: #1 #2 - <var> state 27 - printf_format_str state 29 - state 27: #2 - <var> state 28 - state 28: #2 - state 29: #1 #2 - <var> state 30 - state 30: #1 #2 - state 31: #0 #1 #2 - <var> state 32 - state 32: #0 #1 #2 - <var> state 33 - state 33: #0 #1 #2 - <var> state 34 - <app> state 35 - state 34: #2 - state 35: #0 #1 #2 - <var> state 36 - <app> state 38 - printf_format_str state 45 - state 36: #2 - <var> state 37 - state 37: #2 - state 38: #0 #2 - <var> state 39 - printf_format_spec state 42 - state 39: #2 - <var> state 40 - state 40: #2 - <var> state 41 - state 41: #2 - state 42: #0 #2 - <var> state 43 - state 43: #0 #2 - <var> state 44 - state 44: #0 #2 - state 45: #1 #2 - <var> state 46 - state 46: #1 #2 -}; check_buf buf/*0:1*/ = throw printf_malloc_error if null buf/*0:1*/; check_buf buf/*0:1*/ = buf/*0:1*/ { - rule #0: check_buf buf = throw printf_malloc_error if null buf - rule #1: check_buf buf = buf - state 0: #0 #1 - <var> state 1 - state 1: #0 #1 -} end; -scanf format/*0:1*/::string = fscanf stdin format/*0:1*/; -fscanf fp/*0:01*/ format/*0:1*/::string = tuple$reverse ret/*0:1*/ when _/*0:01*/,ret/*0:1*/ = catch error_handler/*0*/ (foldl (do_fscanf/*1*/ fp/*1:01*/) (0,[])$scanf_split_format format/*1:1*/) { - rule #0: _,ret = catch error_handler (foldl (do_fscanf fp) (0,[])$scanf_split_format format) - state 0: #0 - <app> state 1 - state 1: #0 - <app> state 2 - state 2: #0 - , state 3 - state 3: #0 - <var> state 4 - state 4: #0 - <var> state 5 - state 5: #0 -} end with error_handler (scanf_error ret/*0:11*/) = throw (scanf_error (tuple$reverse ret/*0:11*/)); error_handler x/*0:1*/ = throw x/*0:1*/ { - rule #0: error_handler (scanf_error ret) = throw (scanf_error (tuple$reverse ret)) - rule #1: error_handler x = throw x - state 0: #0 #1 - <var> state 1 - <app> state 2 - state 1: #1 - state 2: #0 #1 - <var> state 3 - scanf_error state 5 - state 3: #1 - <var> state 4 - state 4: #1 - state 5: #0 #1 - <var> state 6 - state 6: #0 #1 -}; check_buf buf/*0:1*/ = throw scanf_malloc_error if null buf/*0:1*/; check_buf buf/*0:1*/ = buf/*0:1*/ { - rule #0: check_buf buf = throw scanf_malloc_error if null buf - rule #1: check_buf buf = buf - state 0: #0 #1 - <var> state 1 - state 1: #0 #1 -}; do_fscanf fp/*0:001*/ (nread/*0:0101*/,ret/*0:011*/) (scanf_format_spec t/*0:101*/ s/*0:11*/) = nread/*7:0101*/+res/*3:*/,ret/*0:*/ when size/*0:01*/,s/*0:1*/ = if t/*0:101*/=="s" then guestimate/*1*/ s/*0:11*/ else 16,s/*0:11*/; buf/*0:*/ = check_buf/*2*/ (calloc size/*0:01*/ 1); res/*0:*/ = case t/*2:101*/ of "n" = pure_fscanf_int fp/*3:001*/ s/*2:1*/ buf/*1:*/; "d" = pure_fscanf_int fp/*3:001*/ s/*2:1*/ buf/*1:*/; "g" = pure_fscanf_double fp/*3:001*/ s/*2:1*/ buf/*1:*/; "s" = pure_fscanf_string fp/*3:001*/ s/*2:1*/ buf/*1:*/; "p" = pure_fscanf_pointer fp/*3:001*/ s/*2:1*/ buf/*1:*/; _/*0:*/ = throw (this_cant_happen ret/*3:011*/) { - rule #0: "n" = pure_fscanf_int fp s buf - rule #1: "d" = pure_fscanf_int fp s buf - rule #2: "g" = pure_fscanf_double fp s buf - rule #3: "s" = pure_fscanf_string fp s buf - rule #4: "p" = pure_fscanf_pointer fp s buf - rule #5: _ = throw (this_cant_happen ret) - state 0: #0 #1 #2 #3 #4 #5 - <var> state 1 - "n"::string state 2 - "d"::string state 3 - "g"::string state 4 - "s"::string state 5 - "p"::string state 6 - state 1: #5 - state 2: #0 #5 - state 3: #1 #5 - state 4: #2 #5 - state 5: #3 #5 - state 6: #4 #5 -} end; res/*0:*/ = if res/*0:*/>=0 then res/*0:*/ else throw (scanf_error ret/*4:011*/) when _/*0:*/ = free buf/*1:*/ { - rule #0: _ = free buf - state 0: #0 - <var> state 1 - state 1: #0 -} end; val/*0:*/ = case t/*4:101*/ of "n" = nread/*5:0101*/+get_int buf/*3:*/; "d" = get_int buf/*3:*/; "g" = get_double buf/*3:*/; "s" = cstring buf/*3:*/; "p" = get_pointer buf/*3:*/; _/*0:*/ = throw (this_cant_happen ret/*5:011*/) { - rule #0: "n" = nread+get_int buf - rule #1: "d" = get_int buf - rule #2: "g" = get_double buf - rule #3: "s" = cstring buf - rule #4: "p" = get_pointer buf - rule #5: _ = throw (this_cant_happen ret) - state 0: #0 #1 #2 #3 #4 #5 - <var> state 1 - "n"::string state 2 - "d"::string state 3 - "g"::string state 4 - "s"::string state 5 - "p"::string state 6 - state 1: #5 - state 2: #0 #5 - state 3: #1 #5 - state 4: #2 #5 - state 5: #3 #5 - state 6: #4 #5 -} end; _/*0:*/ = if t/*5:101*/=="s" then () else free buf/*3:*/; ret/*0:*/ = val/*1:*/:ret/*6:011*/ { - rule #0: ret = val:ret - state 0: #0 - <var> state 1 - state 1: #0 -} { - rule #0: _ = if t=="s" then () else free buf - state 0: #0 - <var> state 1 - state 1: #0 -} { - rule #0: val = case t of "n" = nread+get_int buf; "d" = get_int buf; "g" = get_double buf; "s" = cstring buf; "p" = get_pointer buf; _ = throw (this_cant_happen ret) end - state 0: #0 - <var> state 1 - state 1: #0 -} { - rule #0: res = if res>=0 then res else throw (scanf_error ret) when _ = free buf end - state 0: #0 - <var> state 1 - state 1: #0 -} { - rule #0: res = case t of "n" = pure_fscanf_int fp s buf; "d" = pure_fscanf_int fp s buf; "g" = pure_fscanf_double fp s buf; "s" = pure_fscanf_string fp s buf; "p" = pure_fscanf_pointer fp s buf; _ = throw (this_cant_happen ret) end - state 0: #0 - <var> state 1 - state 1: #0 -} { - rule #0: buf = check_buf (calloc size 1) - state 0: #0 - <var> state 1 - state 1: #0 -} { - rule #0: size,s = if t=="s" then guestimate s else 16,s - state 0: #0 - <app> state 1 - state 1: #0 - <app> state 2 - state 2: #0 - , state 3 - state 3: #0 - <var> state 4 - state 4: #0 - <var> state 5 - state 5: #0 -} end; do_fscanf fp/*0:001*/ (nread/*0:0101*/,ret/*0:011*/) (scanf_format_str s/*0:11*/) = nread/*2:0101*/+res/*1:*/,ret/*0:*/ when res/*0:*/ = pure_fscanf fp/*0:001*/ s/*0:11*/; ret/*0:*/ = if res/*0:*/>=0 then ret/*1:011*/ else throw (scanf_error ret/*1:011*/) { - rule #0: ret = if res>=0 then ret else throw (scanf_error ret) - state 0: #0 - <var> state 1 - state 1: #0 -} { - rule #0: res = pure_fscanf fp s - state 0: #0 - <var> state 1 - state 1: #0 -} end; do_fscanf _/*0:001*/ (_/*0:0101*/,ret/*0:011*/) _/*0:1*/ = throw (this_cant_happen ret/*0:011*/) { - rule #0: do_fscanf fp (nread,ret) (scanf_format_spec t s) = nread+res,ret when size,s = if t=="s" then guestimate s else 16,s; buf = check_buf (calloc size 1); res = case t of "n" = pure_fscanf_int fp s buf; "d" = pure_fscanf_int fp s buf; "g" = pure_fscanf_double fp s buf; "s" = pure_fscanf_string fp s buf; "p" = pure_fscanf_pointer fp s buf; _ = throw (this_cant_happen ret) end; res = if res>=0 then res else throw (scanf_error ret) when _ = free buf end; val = case t of "n" = nread+get_int buf; "d" = get_int buf; "g" = get_double buf; "s" = cstring buf; "p" = get_pointer buf; _ = throw (this_cant_happen ret) end; _ = if t=="s" then () else free buf; ret = val:ret end - rule #1: do_fscanf fp (nread,ret) (scanf_format_str s) = nread+res,ret when res = pure_fscanf fp s; ret = if res>=0 then ret else throw (scanf_error ret) end - rule #2: do_fscanf _ (_,ret) _ = throw (this_cant_happen ret) - state 0: #0 #1 #2 - <var> state 1 - state 1: #0 #1 #2 - <app> state 2 - state 2: #0 #1 #2 - <app> state 3 - state 3: #0 #1 #2 - , state 4 - state 4: #0 #1 #2 - <var> state 5 - state 5: #0 #1 #2 - <var> state 6 - state 6: #0 #1 #2 - <var> state 7 - <app> state 8 - state 7: #2 - state 8: #0 #1 #2 - <var> state 9 - <app> state 11 - scanf_format_str state 18 - state 9: #2 - <var> state 10 - state 10: #2 - state 11: #0 #2 - <var> state 12 - scanf_format_spec state 15 - state 12: #2 - <var> state 13 - state 13: #2 - <var> state 14 - state 14: #2 - state 15: #0 #2 - <var> state 16 - state 16: #0 #2 - <var> state 17 - state 17: #0 #2 - state 18: #1 #2 - <var> state 19 - state 19: #1 #2 -}; guestimate format/*0:1*/ = n/*0:01*/,format/*0:1*/ when 1,0,_/*0:1101*/,1,s/*0:1111*/ = regex "^%([0-9]*)" REG_EXTENDED format/*0:1*/ 0; n/*0:01*/,format/*0:1*/ = if null s/*0:1111*/ then 1025,"%1024"+tail format/*1:1*/ else eval s/*0:1111*/+1,format/*1:1*/ { - rule #0: n,format = if null s then 1025,"%1024"+tail format else eval s+1,format - state 0: #0 - <app> state 1 - state 1: #0 - <app> state 2 - state 2: #0 - , state 3 - state 3: #0 - <var> state 4 - state 4: #0 - <var> state 5 - state 5: #0 -} { - rule #0: 1,0,_,1,s = regex "^%([0-9]*)" REG_EXTENDED format 0 - state 0: #0 - <app> state 1 - state 1: #0 - <app> state 2 - state 2: #0 - , state 3 - state 3: #0 - 1::int state 4 - state 4: #0 - <app> state 5 - state 5: #0 - <app> state 6 - state 6: #0 - , state 7 - state 7: #0 - 0::int state 8 - state 8: #0 - <app> state 9 - state 9: #0 - <app> state 10 - state 10: #0 - , state 11 - state 11: #0 - <var> state 12 - state 12: #0 - <app> state 13 - state 13: #0 - <app> state 14 - state 14: #0 - , state 15 - state 15: #0 - 1::int state 16 - state 16: #0 - <var> state 17 - state 17: #0 -} end { - rule #0: guestimate format = n,format when 1,0,_,1,s = regex "^%([0-9]*)" REG_EXTENDED format 0; n,format = if null s then 1025,"%1024"+tail format else eval s+1,format end - state 0: #0 - <var> state 1 - state 1: #0 -} end; -scanf_split_format format/*0:1*/ = regexg analyze/*0*/ "(%[*]?[0-9]*([cdiouxXneEfgsp]|\\[\\^?\\]?[^]]+\\]))|(%)|([^%]|%%)+" REG_EXTENDED format/*0:1*/ 0 with analyze info/*0:1*/ = if p/*1:01*/>=0&&u/*2:1*/!1!="*" then scanf_format_spec t/*0:*/ (kludge/*5*/ t/*0:*/ u/*3:1*/) when t/*0:*/ = format_type/*4*/ (last u/*2:1*/) { - rule #0: t = format_type (last u) - state 0: #0 - <var> state 1 - state 1: #0 -} end else if q/*0:01*/>=0 then throw (scanf_format_error q/*0:01*/) else scanf_format_str u/*2:1*/ when _/*0:01*/,u/*0:1*/ = reg 0 info/*0:1*/; p/*0:01*/,_/*0:1*/ = reg 1 info/*1:1*/; q/*0:01*/,_/*0:1*/ = reg 3 info/*2:1*/ { - rule #0: q,_ = reg 3 info - state 0: #0 - <app> state 1 - state 1: #0 - <app> state 2 - state 2: #0 - , state 3 - state 3: #0 - <var> state 4 - state 4: #0 - <var> state 5 - state 5: #0 -} { - rule #0: p,_ = reg 1 info - state 0: #0 - <app> state 1 - state 1: #0 - <app> state 2 - state 2: #0 - , state 3 - state 3: #0 - <var> state 4 - state 4: #0 - <var> state 5 - state 5: #0 -} { - rule #0: _,u = reg 0 info - state 0: #0 - <app> state 1 - state 1: #0 - <app> state 2 - state 2: #0 - , state 3 - state 3: #0 - <var> state 4 - state 4: #0 - <var> state 5 - state 5: #0 -} end { - rule #0: analyze info = if p>=0&&u!1!="*" then scanf_format_spec t (kludge t u) when t = format_type (last u) end else if q>=0 then throw (scanf_format_error q) else scanf_format_str u when _,u = reg 0 info; p,_ = reg 1 info; q,_ = reg 3 info end - state 0: #0 - <var> state 1 - state 1: #0 -}; format_type x/*0:1*/ = if x/*0:1*/=="n" then "n" else if index "diouxX" x/*0:1*/>=0 then "d" else if index "eEfg" x/*0:1*/>=0 then "g" else if x/*0:1*/=="]"||x/*0:1*/=="c" then "s" else x/*0:1*/ { - rule #0: format_type x = if x=="n" then "n" else if index "diouxX" x>=0 then "d" else if index "eEfg" x>=0 then "g" else if x=="]"||x=="c" then "s" else x - state 0: #0 - <var> state 1 - state 1: #0 -}; kludge "g" u/*0:1*/ = init u/*0:1*/+"l"+last u/*0:1*/; kludge _/*0:01*/ u/*0:1*/ = u/*0:1*/ { - rule #0: kludge "g" u = init u+"l"+last u - rule #1: kludge _ u = u - state 0: #0 #1 - <var> state 1 - "g"::string state 3 - state 1: #1 - <var> state 2 - state 2: #1 - state 3: #0 #1 - <var> state 4 - state 4: #0 #1 -} end; -sscanf s/*0:01*/::string format/*0:1*/::string = tuple$reverse ret/*0:11*/ when _/*0:01*/,_/*0:101*/,ret/*0:11*/ = catch error_handler/*0*/ (foldl do_sscanf/*1*/ (s/*1:01*/,0,[])$scanf_split_format format/*1:1*/) { - rule #0: _,_,ret = catch error_handler (foldl do_sscanf (s,0,[])$scanf_split_format format) - state 0: #0 - <app> state 1 - state 1: #0 - <app> state 2 - state 2: #0 - , state 3 - state 3: #0 - <var> state 4 - state 4: #0 - <app> state 5 - state 5: #0 - <app> state 6 - state 6: #0 - , state 7 - state 7: #0 - <var> state 8 - state 8: #0 - <var> state 9 - state 9: #0 -} end with error_handler (scanf_error ret/*0:11*/) = throw (scanf_error (tuple$reverse ret/*0:11*/)); error_handler x/*0:1*/ = throw x/*0:1*/ { - rule #0: error_handler (scanf_error ret) = throw (scanf_error (tuple$reverse ret)) - rule #1: error_handler x = throw x - state 0: #0 #1 - <var> state 1 - <app> state 2 - state 1: #1 - state 2: #0 #1 - <var> state 3 - scanf_error state 5 - state 3: #1 - <var> state 4 - state 4: #1 - state 5: #0 #1 - <var> state 6 - state 6: #0 #1 -}; check_buf buf/*0:1*/ = throw scanf_malloc_error if null buf/*0:1*/; check_buf buf/*0:1*/ = buf/*0:1*/ { - rule #0: check_buf buf = throw scanf_malloc_error if null buf - rule #1: check_buf buf = buf - state 0: #0 #1 - <var> state 1 - state 1: #0 #1 -}; guestimate format/*0:1*/ = n/*0:01*/,format/*0:1*/ when 1,0,_/*0:1101*/,1,s/*0:1111*/ = regex "^%([0-9]*)" REG_EXTENDED format/*0:1*/ 0; n/*0:01*/,format/*0:1*/ = if null s/*0:1111*/ then 1025,"%1024"+tail format/*1:1*/ else eval s/*0:1111*/+1,format/*1:1*/ { - rule #0: n,format = if null s then 1025,"%1024"+tail format else eval s+1,format - state 0: #0 - <app> state 1 - state 1: #0 - <app> state 2 - state 2: #0 - , state 3 - state 3: #0 - <var> state 4 - state 4: #0 - <var> state 5 - state 5: #0 -} { - rule #0: 1,0,_,1,s = regex "^%([0-9]*)" REG_EXTENDED format 0 - state 0: #0 - <app> state 1 - state 1: #0 - <app> state 2 - state 2: #0 - , state 3 - state 3: #0 - 1::int state 4 - state 4: #0 - <app> state 5 - state 5: #0 - <app> state 6 - state 6: #0 - , state 7 - state 7: #0 - 0::int state 8 - state 8: #0 - <app> state 9 - state 9: #0 - <app> state 10 - state 10: #0 - , state 11 - state 11: #0 - <var> state 12 - state 12: #0 - <app> state 13 - state 13: #0 - <app> state 14 - state 14: #0 - , state 15 - state 15: #0 - 1::int state 16 - state 16: #0 - <var> state 17 - state 17: #0 -} end { - rule #0: guestimate format = n,format when 1,0,_,1,s = regex "^%([0-9]*)" REG_EXTENDED format 0; n,format = if null s then 1025,"%1024"+tail format else eval s+1,format end - state 0: #0 - <var> state 1 - state 1: #0 -}; do_sscanf (u/*0:0101*/,nread/*0:01101*/,ret/*0:0111*/) (scanf_format_spec t/*0:101*/ s/*0:11*/) = u/*0:*/,nread/*8:01101*/+res/*4:*/,ret/*1:*/ when size/*0:01*/,s/*0:1*/ = if t/*0:101*/=="s" then guestimate/*1*/ s/*0:11*/ else 16,s/*0:11*/; buf/*0:*/ = check_buf/*2*/ (calloc size/*0:01*/ 1); res/*0:*/ = case t/*2:101*/ of "n" = pure_sscanf_int u/*3:0101*/ s/*2:1*/ buf/*1:*/; "d" = pure_sscanf_int u/*3:0101*/ s/*2:1*/ buf/*1:*/; "g" = pure_sscanf_double u/*3:0101*/ s/*2:1*/ buf/*1:*/; "s" = pure_sscanf_string u/*3:0101*/ s/*2:1*/ buf/*1:*/; "p" = pure_sscanf_pointer u/*3:0101*/ s/*2:1*/ buf/*1:*/; _/*0:*/ = throw (this_cant_happen ret/*3:0111*/) { - rule #0: "n" = pure_sscanf_int u s buf - rule #1: "d" = pure_sscanf_int u s buf - rule #2: "g" = pure_sscanf_double u s buf - rule #3: "s" = pure_sscanf_string u s buf - rule #4: "p" = pure_sscanf_pointer u s buf - rule #5: _ = throw (this_cant_happen ret) - state 0: #0 #1 #2 #3 #4 #5 - <var> state 1 - "n"::string state 2 - "d"::string state 3 - "g"::string state 4 - "s"::string state 5 - "p"::string state 6 - state 1: #5 - state 2: #0 #5 - state 3: #1 #5 - state 4: #2 #5 - state 5: #3 #5 - state 6: #4 #5 -} end; res/*0:*/ = if res/*0:*/>=0 then res/*0:*/ else throw (scanf_error ret/*4:0111*/) when _/*0:*/ = free buf/*1:*/ { - rule #0: _ = free buf - state 0: #0 - <var> state 1 - state 1: #0 -} end; val/*0:*/ = case t/*4:101*/ of "n" = nread/*5:01101*/+get_int buf/*3:*/; "d" = get_int buf/*3:*/; "g" = get_double buf/*3:*/; "s" = cstring buf/*3:*/; "p" = get_pointer buf/*3:*/; _/*0:*/ = throw (this_cant_happen ret/*5:0111*/) { - rule #0: "n" = nread+get_int buf - rule #1: "d" = get_int buf - rule #2: "g" = get_double buf - rule #3: "s" = cstring buf - rule #4: "p" = get_pointer buf - rule #5: _ = throw (this_cant_happen ret) - state 0: #0 #1 #2 #3 #4 #5 - <var> state 1 - "n"::string state 2 - "d"::string state 3 - "g"::string state 4 - "s"::string state 5 - "p"::string state 6 - state 1: #5 - state 2: #0 #5 - state 3: #1 #5 - state 4: #2 #5 - state 5: #3 #5 - state 6: #4 #5 -} end; _/*0:*/ = if t/*5:101*/=="s" then () else free buf/*3:*/; ret/*0:*/ = val/*1:*/:ret/*6:0111*/; u/*0:*/ = drop res/*3:*/ u/*7:0101*/ { - rule #0: u = drop res u - state 0: #0 - <var> state 1 - state 1: #0 -} { - rule #0: ret = val:ret - state 0: #0 - <var> state 1 - state 1: #0 -} { - rule #0: _ = if t=="s" then () else free buf - state 0: #0 - <var> state 1 - state 1: #0 -} { - rule #0: val = case t of "n" = nread+get_int buf; "d" = get_int buf; "g" = get_double buf; "s" = cstring buf; "p" = get_pointer buf; _ = throw (this_cant_happen ret) end - state 0: #0 - <var> state 1 - state 1: #0 -} { - rule #0: res = if res>=0 then res else throw (scanf_error ret) when _ = free buf end - state 0: #0 - <var> state 1 - state 1: #0 -} { - rule #0: res = case t of "n" = pure_sscanf_int u s buf; "d" = pure_sscanf_int u s buf; "g" = pure_sscanf_double u s buf; "s" = pure_sscanf_string u s buf; "p" = pure_sscanf_pointer u s buf; _ = throw (this_cant_happen ret) end - state 0: #0 - <var> state 1 - state 1: #0 -} { - rule #0: buf = check_buf (calloc size 1) - state 0: #0 - <var> state 1 - state 1: #0 -} { - rule #0: size,s = if t=="s" then guestimate s else 16,s - state 0: #0 - <app> state 1 - state 1: #0 - <app> state 2 - state 2: #0 - , state 3 - state 3: #0 - <var> state 4 - state 4: #0 - <var> state 5 - state 5: #0 -} end; do_sscanf (u/*0:0101*/,nread/*0:01101*/,ret/*0:0111*/) (scanf_format_str s/*0:11*/) = u/*0:*/,nread/*3:01101*/+res/*2:*/,ret/*1:*/ when res/*0:*/ = pure_sscanf u/*0:0101*/ s/*0:11*/; ret/*0:*/ = if res/*0:*/>=0 then ret/*1:0111*/ else throw (scanf_error ret/*1:0111*/); u/*0:*/ = drop res/*1:*/ u/*2:0101*/ { - rule #0: u = drop res u - state 0: #0 - <var> state 1 - state 1: #0 -} { - rule #0: ret = if res>=0 then ret else throw (scanf_error ret) - state 0: #0 - <var> state 1 - state 1: #0 -} { - rule #0: res = pure_sscanf u s - state 0: #0 - <var> state 1 - state 1: #0 -} end; do_sscanf (_/*0:0101*/,_/*0:01101*/,ret/*0:0111*/) _/*0:1*/ = throw (this_cant_happen ret/*0:0111*/) { - rule #0: do_sscanf (u,nread,ret) (scanf_format_spec t s) = u,nread+res,ret when size,s = if t=="s" then guestimate s else 16,s; buf = check_buf (calloc size 1); res = case t of "n" = pure_sscanf_int u s buf; "d" = pure_sscanf_int u s buf; "g" = pure_sscanf_double u s buf; "s" = pure_sscanf_string u s buf; "p" = pure_sscanf_pointer u s buf; _ = throw (this_cant_happen ret) end; res = if res>=0 then res else throw (scan... [truncated message content] |
From: <ag...@us...> - 2008-07-02 23:31:53
|
Revision: 373 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=373&view=rev Author: agraef Date: 2008-07-02 16:31:57 -0700 (Wed, 02 Jul 2008) Log Message: ----------- Update logs. Modified Paths: -------------- pure/trunk/test/test014.log Modified: pure/trunk/test/test014.log =================================================================== --- pure/trunk/test/test014.log 2008-07-02 21:59:15 UTC (rev 372) +++ pure/trunk/test/test014.log 2008-07-02 23:31:57 UTC (rev 373) @@ -602,7 +602,20 @@ rational x@(_/*0:101*/%_/*0:11*/) = x/*0:1*/; rational x/*0:1*/::int = x/*0:1*/%1; rational x/*0:1*/::bigint = x/*0:1*/%1; -rational x/*0:1*/::double = x/*0:1*/; +rational x/*0:1*/::double = n/*0:01*/%d/*0:1*/ when n/*0:01*/,d/*0:1*/ = pure_rational x/*0:1*/ { + rule #0: n,d = pure_rational x + state 0: #0 + <app> state 1 + state 1: #0 + <app> state 2 + state 2: #0 + , state 3 + state 3: #0 + <var> state 4 + state 4: #0 + <var> state 5 + state 5: #0 +} end; rational (x/*0:101*/+:y/*0:11*/) = rational x/*0:101*/+:rational y/*0:11*/; rational (x/*0:101*/<:y/*0:11*/) = rational x/*0:101*/<:rational y/*0:11*/; int x@(_/*0:101*/%_/*0:11*/) = int (bigint x/*0:1*/); @@ -6083,7 +6096,7 @@ rule #0: rational x@(_%_) = x rule #1: rational x::int = x%1 rule #2: rational x::bigint = x%1 - rule #3: rational x::double = x + rule #3: rational x::double = n%d when n,d = pure_rational x end rule #4: rational (x+:y) = rational x+:rational y rule #5: rational (x<:y) = rational x<:rational y state 0: #0 #1 #2 #3 #4 #5 @@ -6271,7 +6284,7 @@ frac (-22%7); (-1L)%7L rational (3/8); -0.375 +3L%8L { rule #0: z = 1+(0+:1)*(1%2) state 0: #0 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <js...@us...> - 2008-07-02 21:59:06
|
Revision: 372 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=372&view=rev Author: jspitz Date: 2008-07-02 14:59:15 -0700 (Wed, 02 Jul 2008) Log Message: ----------- Fixed bug in bag <= and >= tests. Modified Paths: -------------- pure/trunk/examples/set.pure Modified: pure/trunk/examples/set.pure =================================================================== --- pure/trunk/examples/set.pure 2008-07-02 21:34:02 UTC (rev 371) +++ pure/trunk/examples/set.pure 2008-07-02 21:59:15 UTC (rev 372) @@ -299,15 +299,11 @@ m1@(Bag _) != m2@(Bag _) = (members m1 != members m2); -m1@(Set _) <= m2@(Set _) - = all (member m2) (members m1); -m1@(Bag _) <= m2@(Bag _) - = (m1 - m2) == nil; +m1@(Set _) <= m2@(Set _) = all (member m2) (members m1); +m1@(Bag _) <= m2@(Bag _) = null (m1 - m2); -m1@(Set _) >= m2@(Set _) - = all (member m1) (members m2); -m1@(Bag _) >= m2@(Bag _) - = (m2 - m1) == nil; +m1@(Set _) >= m2@(Set _) = all (member m1) (members m2); +m1@(Bag _) >= m2@(Bag _) = null (m2 - m1); m1@(Set _) < m2@(Set _) | m1@(Bag _) < m2@(Bag _) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-07-02 21:34:03
|
Revision: 371 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=371&view=rev Author: agraef Date: 2008-07-02 14:34:02 -0700 (Wed, 02 Jul 2008) Log Message: ----------- Fontification fixes for pure-eval mode. Modified Paths: -------------- pure/trunk/etc/pure-mode.el.in Modified: pure/trunk/etc/pure-mode.el.in =================================================================== --- pure/trunk/etc/pure-mode.el.in 2008-07-02 20:46:27 UTC (rev 370) +++ pure/trunk/etc/pure-mode.el.in 2008-07-02 21:34:02 UTC (rev 371) @@ -126,7 +126,7 @@ :group 'pure) (defcustom pure-msg-regexp - "^[ \t]*\\(\\([^:\n]+\\):\\([0-9]+\\)\\(\\.[0-9]+\\)?\\):" + "^[ \t]*\\(\\([^:\n]+\\):\\([0-9]+\\)\\(\\.[0-9]+\\)?\\): " "*Regexp to match error and warning messages with source line references in the Pure eval buffer. Expression 1 denotes the whole source line info, expression 2 the file name and expression 3 the corresponding line number." @@ -161,12 +161,12 @@ ; (list pure-prompt-regexp 0 'font-lock-preprocessor-face t) (list pure-msg-regexp 0 'font-lock-warning-face t) (list "::\\([A-Za-z_][A-Za-z_0-9]*\\)" 1 'font-lock-type-face) - (list "\\<\\(catch\\|throw\\)\\>" 0 'font-lock-builtin-face) +; (list "\\<\\(catch\\|throw\\)\\>" 0 'font-lock-builtin-face) (list (concat "\\<\\(" - "case\\|def\\|e\\(lse\\|nd\\|xtern\\)\\|i\\(f\\|nfix[lr]?\\)\\|" - "let\\|nullary\\|o\\(f\\|therwise\\)\\|p\\(refix\\|ostfix\\)\\|" - "then\\|using\\|w\\(hen\\|ith\\)" + "def\\|extern\\|infix[lr]?\\|" + "let\\|nullary\\|p\\(refix\\|ostfix\\)\\|" + "using" "\\)\\>") 0 'font-lock-keyword-face)) "Rules for fontifying in Pure-Eval mode.") This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |