pure-lang-svn Mailing List for Pure (Page 6)
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: <ag...@us...> - 2008-09-08 14:25:25
|
Revision: 745 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=745&view=rev Author: agraef Date: 2008-09-08 14:25:33 +0000 (Mon, 08 Sep 2008) Log Message: ----------- Add checks for signal functions (requires reconfigure). Modified Paths: -------------- pure/trunk/config/aclocal.m4 pure/trunk/config.h.in pure/trunk/configure pure/trunk/configure.ac Modified: pure/trunk/config/aclocal.m4 =================================================================== --- pure/trunk/config/aclocal.m4 2008-09-08 14:24:48 UTC (rev 744) +++ pure/trunk/config/aclocal.m4 2008-09-08 14:25:33 UTC (rev 745) @@ -82,3 +82,105 @@ [Define if you have <langinfo.h> and nl_langinfo(CODESET).]) fi ]) + +dnl Check type of signal routines (posix, 4.2bsd, 4.1bsd or v7). + +AC_DEFUN([AC_SIGNAL_CHECK], +[AC_REQUIRE([AC_TYPE_SIGNAL]) +AC_MSG_CHECKING(for type of signal functions) +AC_CACHE_VAL(q_cv_signal_vintage, +[ + AC_TRY_LINK([#include <signal.h>],[ + sigset_t ss; + struct sigaction sa; + sigemptyset(&ss); sigsuspend(&ss); + sigaction(SIGINT, &sa, (struct sigaction *) 0); + sigprocmask(SIG_BLOCK, &ss, (sigset_t *) 0); + ], q_cv_signal_vintage=posix, + [ + AC_TRY_LINK([#include <signal.h>], [ + int mask = sigmask(SIGINT); + sigsetmask(mask); sigblock(mask); sigpause(mask); + ], q_cv_signal_vintage=4.2bsd, + [ + AC_TRY_LINK([ + #include <signal.h> + RETSIGTYPE foo() { }], [ + int mask = sigmask(SIGINT); + sigset(SIGINT, foo); sigrelse(SIGINT); + sighold(SIGINT); sigpause(SIGINT); + ], q_cv_signal_vintage=svr3, q_cv_signal_vintage=v7 + )] + )] +) +]) +AC_MSG_RESULT($q_cv_signal_vintage) +if test "$q_cv_signal_vintage" = posix; then +AC_DEFINE(HAVE_POSIX_SIGNALS, 1, [Define if POSIX signal functions are available.]) +elif test "$q_cv_signal_vintage" = "4.2bsd"; then +AC_DEFINE(HAVE_BSD_SIGNALS, 1, [Define if BSD signal functions are available.]) +elif test "$q_cv_signal_vintage" = svr3; then +AC_DEFINE(HAVE_USG_SIGHOLD, 1, [Define if SVR3 signal functions are available.]) +fi +]) + +dnl Check whether signal handlers must be reinstalled when invoked. + +AC_DEFUN([AC_REINSTALL_SIGHANDLERS], +[AC_REQUIRE([AC_TYPE_SIGNAL]) +AC_REQUIRE([AC_SIGNAL_CHECK]) +AC_MSG_CHECKING([if signal handlers must be reinstalled when invoked]) +AC_CACHE_VAL(q_cv_must_reinstall_sighandlers, +[AC_TRY_RUN([ +#include <signal.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +typedef RETSIGTYPE sigfunc(); +int nsigint; +#ifdef HAVE_POSIX_SIGNALS +sigfunc * +set_signal_handler(sig, handler) + int sig; + sigfunc *handler; +{ + struct sigaction act, oact; + act.sa_handler = handler; + act.sa_flags = 0; + sigemptyset (&act.sa_mask); + sigemptyset (&oact.sa_mask); + sigaction (sig, &act, &oact); + return (oact.sa_handler); +} +#else +#define set_signal_handler(s, h) signal(s, h) +#endif +RETSIGTYPE +sigint(s) + int s; +{ + nsigint++; +} +main() +{ + nsigint = 0; + set_signal_handler(SIGINT, sigint); + kill((int)getpid(), SIGINT); + kill((int)getpid(), SIGINT); + exit(nsigint != 2); +} +], q_cv_must_reinstall_sighandlers=no, q_cv_must_reinstall_sighandlers=yes, +if test "$q_cv_signal_vintage" = svr3; then + q_cv_must_reinstall_sighandlers=yes +else + q_cv_must_reinstall_sighandlers=no +fi)]) +if test "$cross_compiling" = yes; then + AC_MSG_RESULT([$q_cv_must_reinstall_sighandlers assumed for cross compilation]) +else + AC_MSG_RESULT($q_cv_must_reinstall_sighandlers) +fi +if test "$q_cv_must_reinstall_sighandlers" = yes; then + AC_DEFINE(MUST_REINSTALL_SIGHANDLERS, 1, [Define if signal handlers must be reinstalled by handler.]) +fi +]) Modified: pure/trunk/config.h.in =================================================================== --- pure/trunk/config.h.in 2008-09-08 14:24:48 UTC (rev 744) +++ pure/trunk/config.h.in 2008-09-08 14:25:33 UTC (rev 745) @@ -18,6 +18,9 @@ */ #undef HAVE_ALLOCA_H +/* Define if BSD signal functions are available. */ +#undef HAVE_BSD_SIGNALS + /* Define to 1 if you have the `ftime' function. */ #undef HAVE_FTIME @@ -54,6 +57,9 @@ /* Define to 1 if you have the `nanosleep' function. */ #undef HAVE_NANOSLEEP +/* Define if POSIX signal functions are available. */ +#undef HAVE_POSIX_SIGNALS + /* Define to 1 if you have the <stdint.h> header file. */ #undef HAVE_STDINT_H @@ -75,6 +81,9 @@ /* Define to 1 if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H +/* Define if SVR3 signal functions are available. */ +#undef HAVE_USG_SIGHOLD + /* Define to 1 if you have the `usleep' function. */ #undef HAVE_USLEEP @@ -90,6 +99,9 @@ /* Define as const if the declaration of iconv() needs const. */ #undef ICONV_CONST +/* Define if signal handlers must be reinstalled by handler. */ +#undef MUST_REINSTALL_SIGHANDLERS + /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT @@ -105,6 +117,9 @@ /* Define to the version of this package. */ #undef PACKAGE_VERSION +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + /* The size of `void *', as computed by sizeof. */ #undef SIZEOF_VOID_P Modified: pure/trunk/configure =================================================================== --- pure/trunk/configure 2008-09-08 14:24:48 UTC (rev 744) +++ pure/trunk/configure 2008-09-08 14:25:33 UTC (rev 745) @@ -5472,6 +5472,352 @@ fi done +{ echo "$as_me:$LINENO: checking return type of signal handlers" >&5 +echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6; } +if test "${ac_cv_type_signal+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. */ +#include <sys/types.h> +#include <signal.h> + +int +main () +{ +return *(signal (0, 0)) (0) == 1; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +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_compile") 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_objext; then + ac_cv_type_signal=int +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type_signal=void +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 +echo "${ECHO_T}$ac_cv_type_signal" >&6; } + +cat >>confdefs.h <<_ACEOF +#define RETSIGTYPE $ac_cv_type_signal +_ACEOF + + + +{ echo "$as_me:$LINENO: checking for type of signal functions" >&5 +echo $ECHO_N "checking for type of signal functions... $ECHO_C" >&6; } +if test "${q_cv_signal_vintage+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. */ +#include <signal.h> +int +main () +{ + + sigset_t ss; + struct sigaction sa; + sigemptyset(&ss); sigsuspend(&ss); + sigaction(SIGINT, &sa, (struct sigaction *) 0); + sigprocmask(SIG_BLOCK, &ss, (sigset_t *) 0); + + ; + 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 + q_cv_signal_vintage=posix +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <signal.h> +int +main () +{ + + int mask = sigmask(SIGINT); + sigsetmask(mask); sigblock(mask); sigpause(mask); + + ; + 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 + q_cv_signal_vintage=4.2bsd +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + #include <signal.h> + RETSIGTYPE foo() { } +int +main () +{ + + int mask = sigmask(SIGINT); + sigset(SIGINT, foo); sigrelse(SIGINT); + sighold(SIGINT); sigpause(SIGINT); + + ; + 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 + q_cv_signal_vintage=svr3 +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + q_cv_signal_vintage=v7 + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + +fi + +{ echo "$as_me:$LINENO: result: $q_cv_signal_vintage" >&5 +echo "${ECHO_T}$q_cv_signal_vintage" >&6; } +if test "$q_cv_signal_vintage" = posix; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_POSIX_SIGNALS 1 +_ACEOF + +elif test "$q_cv_signal_vintage" = "4.2bsd"; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_BSD_SIGNALS 1 +_ACEOF + +elif test "$q_cv_signal_vintage" = svr3; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_USG_SIGHOLD 1 +_ACEOF + +fi + + + +{ echo "$as_me:$LINENO: checking if signal handlers must be reinstalled when invoked" >&5 +echo $ECHO_N "checking if signal handlers must be reinstalled when invoked... $ECHO_C" >&6; } +if test "${q_cv_must_reinstall_sighandlers+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + if test "$q_cv_signal_vintage" = svr3; then + q_cv_must_reinstall_sighandlers=yes +else + q_cv_must_reinstall_sighandlers=no +fi +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include <signal.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +typedef RETSIGTYPE sigfunc(); +int nsigint; +#ifdef HAVE_POSIX_SIGNALS +sigfunc * +set_signal_handler(sig, handler) + int sig; + sigfunc *handler; +{ + struct sigaction act, oact; + act.sa_handler = handler; + act.sa_flags = 0; + sigemptyset (&act.sa_mask); + sigemptyset (&oact.sa_mask); + sigaction (sig, &act, &oact); + return (oact.sa_handler); +} +#else +#define set_signal_handler(s, h) signal(s, h) +#endif +RETSIGTYPE +sigint(s) + int s; +{ + nsigint++; +} +main() +{ + nsigint = 0; + set_signal_handler(SIGINT, sigint); + kill((int)getpid(), SIGINT); + kill((int)getpid(), SIGINT); + exit(nsigint != 2); +} + +_ACEOF +rm -f 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>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (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_try") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + q_cv_must_reinstall_sighandlers=no +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +q_cv_must_reinstall_sighandlers=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi + +if test "$cross_compiling" = yes; then + { echo "$as_me:$LINENO: result: $q_cv_must_reinstall_sighandlers assumed for cross compilation" >&5 +echo "${ECHO_T}$q_cv_must_reinstall_sighandlers assumed for cross compilation" >&6; } +else + { echo "$as_me:$LINENO: result: $q_cv_must_reinstall_sighandlers" >&5 +echo "${ECHO_T}$q_cv_must_reinstall_sighandlers" >&6; } +fi +if test "$q_cv_must_reinstall_sighandlers" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define MUST_REINSTALL_SIGHANDLERS 1 +_ACEOF + +fi + { echo "$as_me:$LINENO: checking for _Complex float" >&5 echo $ECHO_N "checking for _Complex float... $ECHO_C" >&6; } if test "${ac_cv_type__Complex_float+set}" = set; then Modified: pure/trunk/configure.ac =================================================================== --- pure/trunk/configure.ac 2008-09-08 14:24:48 UTC (rev 744) +++ pure/trunk/configure.ac 2008-09-08 14:25:33 UTC (rev 745) @@ -91,6 +91,8 @@ AC_FUNC_ALLOCA dnl Platform-dependent time functions. AC_CHECK_FUNCS(ftime gettimeofday nanosleep usleep) +dnl Platform specifics of signal handlers. +AC_REINSTALL_SIGHANDLERS dnl Check to see whether we have POSIX/ISOC99 complex numbers. AC_CHECK_TYPES([_Complex float, _Complex double]) AC_CONFIG_FILES([Makefile]) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-08 14:24:37
|
Revision: 744 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=744&view=rev Author: agraef Date: 2008-09-08 14:24:48 +0000 (Mon, 08 Sep 2008) Log Message: ----------- Windows kludges. Modified Paths: -------------- pure/trunk/pure.cc Modified: pure/trunk/pure.cc =================================================================== --- pure/trunk/pure.cc 2008-09-07 09:41:18 UTC (rev 743) +++ pure/trunk/pure.cc 2008-09-08 14:24:48 UTC (rev 744) @@ -171,6 +171,9 @@ static void sig_handler(int sig) { interpreter::brkflag = sig; +#ifdef MUST_REINSTALL_SIGHANDLERS + signal(sig, sig_handler); +#endif } static const char *histfile = 0; @@ -180,6 +183,51 @@ if (histfile) write_history(histfile); } +#ifdef _WIN32 + +/* Crappy Windoze doesn't have kill, so we need to set up a special kind of + "console" event handler for Ctrl+C. That at least enables PurePad to signal + us. */ + +#include <windows.h> + +static HANDLE hSigInt, hSigTerm, hSignalHandler; + +static DWORD WINAPI SignalHandler(LPVOID dummy) +{ + HANDLE hEvents[2] = { hSigInt, hSigTerm }; + while (1) { + DWORD ev = WaitForMultipleObjects(2, hEvents, FALSE, INFINITE); + switch (ev) { + case WAIT_OBJECT_0: + raise(SIGINT); + break; + case WAIT_OBJECT_0+1: + raise(SIGTERM); + break; + default: + ExitProcess(0); + } + } +} + +int InstallSignalHandler() +{ + TCHAR szSigInt[MAX_PATH], szSigTerm[MAX_PATH]; + DWORD dwSignalHandler; + sprintf(szSigInt, "PURE_SIGINT-%u", GetCurrentProcessId()); + sprintf(szSigTerm, "PURE_SIGTERM-%u", GetCurrentProcessId()); + hSigInt = OpenEvent(EVENT_ALL_ACCESS, FALSE, szSigInt); + hSigTerm = OpenEvent(EVENT_ALL_ACCESS, FALSE, szSigTerm); + if (hSigInt != NULL && hSigTerm != NULL) { + hSignalHandler = CreateThread(NULL, 0, SignalHandler, NULL, + 0, &dwSignalHandler); + return hSignalHandler != NULL; + } else + return hSigInt == hSigTerm; +} +#endif + static inline bool chkfile(const string& s) { struct stat st; @@ -259,6 +307,9 @@ #ifdef SIGUSR2 signal(SIGUSR2, sig_handler); #endif +#ifdef _WIN32 + InstallSignalHandler(); +#endif // set up an exit function which saves the history if needed atexit(exit_handler); // set the system locale This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-07 09:41:08
|
Revision: 743 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=743&view=rev Author: agraef Date: 2008-09-07 09:41:18 +0000 (Sun, 07 Sep 2008) Log Message: ----------- Update NEWS file. Modified Paths: -------------- pure/trunk/NEWS Modified: pure/trunk/NEWS =================================================================== --- pure/trunk/NEWS 2008-09-07 09:34:45 UTC (rev 742) +++ pure/trunk/NEWS 2008-09-07 09:41:18 UTC (rev 743) @@ -4,16 +4,19 @@ New stuff in this release (please see the ChangeLog and the manual for details): -- Macros: rewriting rules applied at compile time, which can be used for -preprocessing purposes, optimizing and inlining function calls at the source -level, and implementing user-defined special forms. +- Macros: These are implemented as rewriting rules which are applied at +compile time, and can be used for all usual preprocessing purposes, including +the optimization and inlining of function calls at the source level, and the +programming of user-defined special forms. -- Thunks a.k.a. "futures": anonymous parameterless closures, which are used to -implement call-by-need and lazy data structures. In particular, the prelude -now implements lazy lists a.k.a. "streams". +- Thunks a.k.a. "futures": These are realized as anonymous parameterless +closures (a la Alice ML), and are used to implement call-by-need and lazy data +structures. In particular, the prelude now implements lazy lists a.k.a. +"streams". - Private namespaces. You can now declare symbols as private in a module, to -keep the global public namespace clean. +hide away internal helper functions and constructor symbols, and to keep the +global public namespace clean. - Sentries (object finalizers) and references (mutable expression pointers). File objects in the system module now employ sentries in order to close @@ -24,13 +27,13 @@ - The 'list' command was renamed to 'show' (to avoid a clash with the prelude function 'list'), and a new 'dump' command was added. The latter is similar to -'show', but allows you to save a snapshot of your current interactive -environment in a file. +'show', but saves a snapshot of your current interactive environment in a +file. - User-defined hook for the expression printer (__show__). This allows you to define your own custom print representations for expressions at runtime. -- Syntax highlighting for gedit (contributed by Eddie Rucker). +- Syntax highlighting for gedit (contributed by Eddie Rucker, thanks!). ** Pure 0.5 2008-08-24 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-07 09:34:34
|
Revision: 742 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=742&view=rev Author: agraef Date: 2008-09-07 09:34:45 +0000 (Sun, 07 Sep 2008) Log Message: ----------- Update NEWS file. Modified Paths: -------------- pure/trunk/NEWS Modified: pure/trunk/NEWS =================================================================== --- pure/trunk/NEWS 2008-09-07 07:22:30 UTC (rev 741) +++ pure/trunk/NEWS 2008-09-07 09:34:45 UTC (rev 742) @@ -1,4 +1,37 @@ +** Pure 0.6 (in progress) + +New stuff in this release (please see the ChangeLog and the manual for +details): + +- Macros: rewriting rules applied at compile time, which can be used for +preprocessing purposes, optimizing and inlining function calls at the source +level, and implementing user-defined special forms. + +- Thunks a.k.a. "futures": anonymous parameterless closures, which are used to +implement call-by-need and lazy data structures. In particular, the prelude +now implements lazy lists a.k.a. "streams". + +- Private namespaces. You can now declare symbols as private in a module, to +keep the global public namespace clean. + +- Sentries (object finalizers) and references (mutable expression pointers). +File objects in the system module now employ sentries in order to close +themselves when they're garbage-collected. + +- New interactive startup files (.purerc). These are just normal Pure scripts +with additional definitions for interactive usage. + +- The 'list' command was renamed to 'show' (to avoid a clash with the prelude +function 'list'), and a new 'dump' command was added. The latter is similar to +'show', but allows you to save a snapshot of your current interactive +environment in a file. + +- User-defined hook for the expression printer (__show__). This allows you to +define your own custom print representations for expressions at runtime. + +- Syntax highlighting for gedit (contributed by Eddie Rucker). + ** Pure 0.5 2008-08-24 This release sports LLVM 2.3 support and a bunch of bug fixes and improvements This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-07 07:22:20
|
Revision: 741 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=741&view=rev Author: agraef Date: 2008-09-07 07:22:30 +0000 (Sun, 07 Sep 2008) Log Message: ----------- Update logs. Modified Paths: -------------- pure/trunk/test/prelude.log Modified: pure/trunk/test/prelude.log =================================================================== --- pure/trunk/test/prelude.log 2008-09-07 07:21:17 UTC (rev 740) +++ pure/trunk/test/prelude.log 2008-09-07 07:22:30 UTC (rev 741) @@ -9,16 +9,11 @@ curry3 f/*0:0001*/ x/*0:001*/ y/*0:01*/ z/*0:1*/ = f/*0:0001*/ (x/*0:001*/,y/*0:01*/,z/*0:1*/); uncurry f/*0:01*/ (x/*0:101*/,y/*0:11*/) = f/*0:01*/ x/*0:101*/ y/*0:11*/; uncurry3 f/*0:01*/ (x/*0:101*/,y/*0:1101*/,z/*0:111*/) = f/*0:01*/ x/*0:101*/ y/*0:1101*/ z/*0:111*/; -fix f/*0:1*/ = y/*0:*/ y/*0:*/ when y/*0:*/ = \x/*0:*/ -> f/*1:1*/ (x/*1:*/ x/*1:*/&) { - rule #0: x = f (x x&) +fix f/*0:1*/ = y/*0*/ y/*0*/ with y x/*0:1*/ = f/*1:1*/ (x/*1:1*/ x/*1:1*/&) { + rule #0: y x = f (x x&) state 0: #0 <var> state 1 state 1: #0 -} { - rule #0: y = \x -> f (x x&) - state 0: #0 - <var> state 1 - state 1: #0 } end; def f/*0:01*/$x/*0:1*/ = f/*0:01*/ x/*0:1*/; def (f/*0:001*/.g/*0:01*/) x/*0:1*/ = f/*0:001*/ (g/*0:01*/ x/*0:1*/); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-07 07:21:06
|
Revision: 740 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=740&view=rev Author: agraef Date: 2008-09-07 07:21:17 +0000 (Sun, 07 Sep 2008) Log Message: ----------- Bugfixes. Modified Paths: -------------- pure/trunk/interpreter.cc pure/trunk/interpreter.hh Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-09-07 06:58:12 UTC (rev 739) +++ pure/trunk/interpreter.cc 2008-09-07 07:21:17 UTC (rev 740) @@ -2663,14 +2663,16 @@ { interpreter& interp = *interpreter::g_interp; assert(info.tag > 0); - os << "extern " << interp.type_name(info.type) << " " - << interp.symtab.sym(info.tag).s << "("; + const symbol& sym = interp.symtab.sym(info.tag); + os << "extern " << interp.type_name(info.type) << " " << info.name << "("; size_t n = info.argtypes.size(); for (size_t i = 0; i < n; i++) { if (i > 0) os << ", "; os << interp.type_name(info.argtypes[i]); } - return os << ")"; + os << ")"; + if (sym.s != info.name) os << " = " << sym.s; + return os; } FMap& FMap::operator= (const FMap& f) @@ -3452,7 +3454,7 @@ externals.find(sym.f) == externals.end()) // There already is a Pure function or global variable for this symbol. // This is an error (unless the symbol is already declared as an external). - throw err("symbol '"+name+"' is already defined as a Pure "+ + throw err("symbol '"+asname+"' is already defined as a Pure "+ ((globenv[sym.f].t == env_info::fun) ? "function" : (globenv[sym.f].t == env_info::fvar) ? "variable" : (globenv[sym.f].t == env_info::cvar) ? "constant" : @@ -3491,7 +3493,7 @@ vector<const Type*> argt(n); for (size_t i = 0; i < n; i++) argt[i] = gt->getParamType(i); - ExternInfo info(sym.f, gt->getReturnType(), argt, g); + ExternInfo info(sym.f, name, gt->getReturnType(), argt, g); ostringstream msg; msg << "declaration of extern function '" << name << "' does not match builtin declaration: " << info; @@ -3884,7 +3886,7 @@ verifyFunction(*f); if (FPM) FPM->run(*f); if (verbose&verbosity::dump) f->print(std::cout); - externals[sym.f] = ExternInfo(sym.f, type, argt, f); + externals[sym.f] = ExternInfo(sym.f, name, type, argt, f); return f; } Modified: pure/trunk/interpreter.hh =================================================================== --- pure/trunk/interpreter.hh 2008-09-07 06:58:12 UTC (rev 739) +++ pure/trunk/interpreter.hh 2008-09-07 07:21:17 UTC (rev 740) @@ -274,15 +274,16 @@ struct ExternInfo { // info about extern (C) functions callable from the Pure script int32_t tag; // function symbol + string name; // real function name const llvm::Type* type; // return type vector<const llvm::Type*> argtypes; // argument types llvm::Function *f; // Pure wrapper for the external ExternInfo() : tag(0), type(0), argtypes(0), f(0) {} - ExternInfo(int32_t _tag, const llvm::Type *_type, + ExternInfo(int32_t _tag, const string&_name, const llvm::Type *_type, vector<const llvm::Type*> _argtypes, llvm::Function *_f) - : tag(_tag), type(_type), argtypes(_argtypes), f(_f) + : tag(_tag), name(_name), type(_type), argtypes(_argtypes), f(_f) {} }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-07 06:58:02
|
Revision: 739 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=739&view=rev Author: agraef Date: 2008-09-07 06:58:12 +0000 (Sun, 07 Sep 2008) Log Message: ----------- Cosmetic changes. Modified Paths: -------------- pure/trunk/lexer.ll Modified: pure/trunk/lexer.ll =================================================================== --- pure/trunk/lexer.ll 2008-09-07 06:55:28 UTC (rev 738) +++ pure/trunk/lexer.ll 2008-09-07 06:58:12 UTC (rev 739) @@ -426,7 +426,8 @@ tflag = interp.temp; break; case 'h': - cout << "show command help: show [options ...] [symbol ...]\n\ + cout << +"show command help: show [options ...] [symbol ...]\n\ Options may be combined, e.g., show -tvl is the same as show -t -v -l.\n\ -a Disassembles pattern matching automata. Useful for debugging purposes.\n\ -c Print information about defined constants.\n\ @@ -787,9 +788,10 @@ tflag = interp.temp; break; case 'h': - cout << "dump command help: dump [options ...] [symbol ...]\n\ -Options may be combined, e.g., dump -tcv is the same as show -t -c -v.\n\ --F Write the dump to the file named in the next arg (default is .pure).\n\ + cout << +"dump command help: dump [-F filename] [options ...] [symbol ...]\n\ +Options may be combined, e.g., dump -fg f* is the same as dump -f -g f*.\n\ +-F Write the dump to the given file (default is .pure).\n\ -c Dump defined constants.\n\ -f Dump defined functions.\n\ -g Indicates that the following symbols are actually shell glob patterns\n\ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-07 06:55:19
|
Revision: 738 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=738&view=rev Author: agraef Date: 2008-09-07 06:55:28 +0000 (Sun, 07 Sep 2008) Log Message: ----------- Cosmetic changes. Modified Paths: -------------- pure/trunk/lib/prelude.pure Modified: pure/trunk/lib/prelude.pure =================================================================== --- pure/trunk/lib/prelude.pure 2008-09-07 06:55:01 UTC (rev 737) +++ pure/trunk/lib/prelude.pure 2008-09-07 06:55:28 UTC (rev 738) @@ -91,7 +91,7 @@ /* The (normal order) fixed point combinator. */ -fix f = y y when y = \x -> f (x x&) end; +fix f = y y with y x = f (x x&) end; /* Some convenient optimization rules which eliminate saturated calls of the function composition combinators. */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-07 06:54:51
|
Revision: 737 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=737&view=rev Author: agraef Date: 2008-09-07 06:55:01 +0000 (Sun, 07 Sep 2008) Log Message: ----------- Update documentation. Modified Paths: -------------- pure/trunk/pure.1.in Modified: pure/trunk/pure.1.in =================================================================== --- pure/trunk/pure.1.in 2008-09-06 19:47:35 UTC (rev 736) +++ pure/trunk/pure.1.in 2008-09-07 06:55:01 UTC (rev 737) @@ -79,33 +79,6 @@ command or the end-of-file character (^D on Unix) at the beginning of the command line. .PP -Unless the -.B --norc -option is specified, in interactive mode the interpreter automatically loads -some additional startup files if they are present; first -.B .purerc -in the user's home directory (provided that the -.B HOME -environment variable is set accordingly), then -.B .purerc -in the current working directory. These are ordinary Pure scripts which can be -used to provide additional definitions for interactive usage. Finally, a -.B .pure -file in the current directory (containing a dump from a previous interactive -session) is loaded if it is present. See the INTERACTIVE USAGE section for -details. -.PP -Unless the -.B --noediting -option is specified, when the interpreter is in interactive mode and reads -from a tty, commands are read using -.BR readline (3) -(providing completion for all commands listed under INTERACTIVE USAGE, as well -as for symbols defined in the running program). When exiting the interpreter, -the command history is stored in -.BR ~/.pure_history , -from where it is restored the next time you run the interpreter. -.PP Options and source files are processed in the order in which they are given on the command line. Processing of options and source files ends when either the .B -- @@ -148,6 +121,8 @@ .B prelude.pure is loaded by the interpreter prior to any other other definitions, unless the .B -n +or +.B --noprelude option is specified. The prelude is searched for in the directory specified with the .B PURELIB @@ -165,6 +140,31 @@ .B -L options; see the sections DECLARATIONS and C INTERFACE below for details. .PP +If the interpreter runs in interactive mode, it may source a few additional +interactive startup files immediately before entering the interactive loop, +unless the +.B --norc +option is specified. First +.B .purerc +in the user's home directory is read, then +.B .purerc +in the current working directory. These are ordinary Pure scripts which can be +used to provide additional definitions for interactive usage. Finally, a +.B .pure +file in the current directory (containing a dump from a previous interactive +session) is loaded if it is present. See the INTERACTIVE USAGE section for +details. +.PP +When the interpreter is in interactive mode and reads from a tty, unless the +.B --noediting +option is specified, commands are read using +.BR readline (3) +(providing completion for all commands listed under INTERACTIVE USAGE, as well +as for symbols defined in the running program). When exiting the interpreter, +the command history is stored in +.BR ~/.pure_history , +from where it is restored the next time you run the interpreter. +.PP The .B -v option is most useful for debugging the interpreter, or if you are interested @@ -286,7 +286,7 @@ 98 .fi .PP -However, due to its term rewriting semantics, Pure goes beyond most other +In fact, due to its term rewriting semantics, Pure goes beyond most other functional languages in that it can do symbolic evaluations just as well as ``normal'' computations: .sp @@ -298,9 +298,11 @@ (a+b)*(a+b) .fi .PP -In fact, all the Pure interpreter does is evaluating expressions in a symbolic -fashion, rewriting expressions using the equations supplied by the programmer, -until no more equations are applicable. The result of this process is called a +Leaving aside the built-in support for some common data structures such as +numbers and strings, all the Pure interpreter really does is evaluating +expressions in a symbolic fashion, rewriting expressions using the equations +supplied by the programmer, until no more equations are applicable. The result +of this process is called a .I "normal form" which represents the ``value'' of the original expression. Keeping with the tradition of term rewriting, there's no distinction between ``defined'' and @@ -844,7 +846,7 @@ 0L:1L:#<thunk 0xb5f87630> .fi .PP -Hmm, not much progress there, but that's just how streams work (or rather +Hmm, not much progress there, but that's just how streams work (or rather they don't, they're lazy bums indeed!). Nevertheless, the stream computed with `take' is in fact finite and we can readily convert it to an ordinary list, forcing its evaluation: @@ -913,13 +915,13 @@ .sp .nf > \fBshow\fP fix -fix f = y y \fBwhen\fP y = \ex -> f (x x&) \fBend\fP; +fix f = y y \fBwith\fP y x = f (x x&) \fBend\fP; .fi .PP -(Functional programming buffs surely notice that this is an implementation of -the normal order fixed point combinator, decorated with `&' in the right place -to make it work with eager evaluation. Aspiring novices may go read Wikipedia -or a good book on the lambda calculus now.) +(Functional programming buffs will quickly recognize this as an implementation +of the normal order fixed point combinator, decorated with `&' in the right +place to make it work with eager evaluation. Aspiring novices may go read +Wikipedia or a good book on the lambda calculus now.) .PP So here's how we can define a ``linear-time'' version of the Fibonacci stream. (Note that we also define the stream as a variable now, to take full @@ -1808,11 +1810,10 @@ processes them as usual. If the .B -i option was used to force interactive mode when invoking the interpreter, the -last script specified on the command line determines the visible namespace -(i.e., all public symbols are visible, along with the private symbols of the -loaded script). Otherwise only the public symbols defined in the prelude are -available, as well as the (public or private) definitions in the startup files -(see below). Additional scripts can be loaded interactively using either a +last script specified on the command line determines the visible namespace, +i.e., the private symbols of that script are available in addition to the +public symbols defined in the prelude and the other scripts specified on the +command line. Additional scripts can be loaded interactively using either a .B using declaration or the interactive .B run @@ -1836,7 +1837,7 @@ > map fact (1..10); [1,2,6,24,120,720,5040,40320,362880,3628800] .fi -.SS Print Syntax +.PP As indicated, in interactive mode the normal forms of toplevel expressions are printed after each expression is entered. We also call this the .I read-eval-print @@ -1845,108 +1846,11 @@ (anonymous and local functions), thunks (``lazy'' values to be evaluated when needed) and pointers which don't have a textual representation in the Pure syntax and will be printed in the format -\fB#<\fP\fIobject description\fP\fB>\fP. -.PP -The interpreter provides a ``hook'' to override the print representations of -expressions at runtime by means of the +\fB#<\fP\fIobject description\fP\fB>\fP by default. It is also possible to +override the print representation of any kind of expression by means of the .B __show__ -function. This is just an ordinary Pure function expected to return a string -with the desired custom representation of a normal form value given as the -function's single argument. __show__ is not defined by default, so you are -free to add any rules that you want. The interpreter prints the strings -returned by __show__ just as they are. It will -.I not -check whether they conform to Pure syntax and/or semantics, or modify them in -any way. +function, see the CAVEATS AND NOTES section for details. .PP -Custom print representations are most useful for interactive purposes, when -you're not happy with the default print syntax of some kinds of objects, or if -you just want to change the format of numeric values. Here are some examples: -.sp -.nf -> \fBusing\fP system; -> __show__ x::double = sprintf "%0.6f" x; -> 1/7; -0.142857 -> __show__ x::int = sprintf "0x%0x" x; -> 1786; -0x6fa -> \fBusing\fP math; -> __show__ (x::double+:y::double) = sprintf "%0.6f+%0.6fi" (x,y); -> cis (-pi); --1.000000+0.000000i -.fi -.PP -The prelude function -.BR str , -which returns the print representation of any Pure expression, uses __show__ -as well: -.sp -.nf -> str (1/7); -"0.142857" -.fi -.PP -However, the str function always returns just the default representation of an -expression if it is invoked through __show__. This prevents __show__ from -going recursive, and allows you to define your custom representation in terms -of the default one. E.g., the following rule removes the `L' suffixes from -bigint values: -.sp -.nf -> __show__ x::bigint = init (str x); -> fact n = foldl (*) 1L (1..n); -> fact 30; -265252859812191058636308480000000 -.fi -.PP -If you have a set of definitions for the __show__ function which should always -be loaded at startup, you can put them into the interpreter's interactive -startup files, see below. -.PP -By just purging the definition of the __show__ function you can easily go back -to the standard print syntax: -.sp -.nf -> \fBclear\fP __show__ -> 1/7; 1786; cis (-pi); -0.142857142857143 -1786 --1.0+:1.22460635382238e-16 -> str (1/7); -"0.142857142857143" -> fact 30; -265252859812191058636308480000000L -.fi -.SS Startup Files -When running the interpreter interactively, it loads some additional scripts -at startup, after loading the prelude. The interpreter first looks for a -.B .purerc -file in the user's home directory (as given by the -.B HOME -environment variable) and then for a -.B .purerc -file in the current working directory. These are just ordinary Pure scripts -which may contain any additional definitions that you need. The -.B .purerc -file in the home directory is for global definitions which should always be -available when running interactively, while the -.B .purerc -file in the current directory can be used for project-specific -definitions. There can be yet another -.B .pure -initialization file in the current directory, which is created by the -.B dump -command (see below) and is loaded after the -.B .purerc -files if it is present. -.PP -The interpreter processes these files in the same way as with the -.B run -command (see below). When invoking the interpreter, you can specify the -.B --norc -option on the command line if you do not wish to load these files. -.SS Interactive Commands When running interactively, the interpreter also accepts a number of special commands useful for interactive purposes. Here is a quick rundown of the currently supported operations: @@ -1962,43 +1866,77 @@ global variables). If no symbols are given, purge \fIall\fP definitions (after confirmation) made after the most recent .B save -command, or the beginning of the interactive session. (It might be a good -idea to first check your current definitions with \fBlist -t\fP before you do -this, though.) See the DEFINITION LEVELS section below for details. +command, or the beginning of the interactive session. (It might be a good idea +to first check your current definitions with \fBshow -t\fP or save them with +\fBdump\fP before you do this, though.) See the DEFINITION LEVELS section +below for details. .TP \fBdump\fP [\fIoption\fP ...] [\fIsymbol\fP ...] -Dump function, macro, variable and constant definitions to a file. This works -similar to the +Dump a snapshot of the current function, macro, constant and variable +definitions in Pure syntax to a text file. This works similar to the .B show command (see below and the SHOW COMMAND section), but writes the definitions -to a file. This command only supports a subset of the +to a file. +.sp +This command only supports a subset of the .B show options, type .B dump -h -for a description of these. +for a description of these. Also note that by default the +.B dump +command only writes interactive definitions to the output file, which is +equivalent to the +.B -t1 +option of the +.B show +command. Presumably this is the most common usage, but using the +.B -t +option, you can select any definitions level just as with +.BR show . +In particular, +.B dump -t +saves only the definitions made after the most recent +.B save +command, and +.B dump -t0 +can be used to dump the +.I entire +program (including the definitions of the prelude), which can be useful for +debugging purposes. .sp -By default, all definitions made interactively are written to a file named +The default output file is .B .pure in the current directory, which is then reloaded automatically the next time the interpreter starts up in interactive mode in the same directory. This provides a quick-and-dirty means to save an interactive session and have it -restored later. (Please note that this isn't perfect yet, because variable -values containing special objects such as thunks and pointers can't be -reconstructed, and +restored later. Please note that this isn't perfect; in order to properly +handle +.B extern +and .B using -or -.B extern -declarations are not recorded at all. For those you'll have to manually create -a +declarations and other special cases such as thunks and pointers stored in +variables, you'll probably have to prepare a corresponding .B .purerc -file instead.) +file yourself, see ``Startup Files'' below. .sp A different filename can be specified with the .B -F option. You can then edit that file and use it as a starting point for an ordinary script or a -.B purerc -file. +.B .purerc +file, or you can just run the file with the +.B run +command (see below) to restore the definitions in a subsequent interpreter +session. +.sp +You can also specify a subset of symbols to be saved. Shell glob patterns can +be used if the +.B -g +option is given. Options may be combined; e.g., +.B "dump -Ffg foo.pure foo*" +is just the same as +.BR "dump -F foo.pure -f -g foo*" , +and dumps all functions whose names start with `foo' to the file `foo.pure'. .TP \fBhelp\fP [\fIargs\fP] Display the @@ -2072,6 +2010,39 @@ .PP Some commands which are especially important for effective operation of the interpreter are discussed in more detail in the following sections. +.SS Startup Files +In interactive mode, the interpreter also runs some additional scripts at +startup, after loading the prelude and the scripts specified on the command +line. +.PP +The interpreter first looks for a +.B .purerc +file in the user's home directory (as given by the +.B HOME +environment variable) and then for a +.B .purerc +file in the current working directory. These are just ordinary Pure scripts +which may contain any additional definitions that you need. The +.B .purerc +file in the home directory is for global definitions which should always be +available when running interactively, while the +.B .purerc +file in the current directory can be used for project-specific +definitions. +.PP +Finally, you can also have a +.B .pure +initialization file in the current directory, which is created by the +.B dump +command (see above) and is loaded after the +.B .purerc +files if it is present. +.PP +The interpreter processes all these files in the same way as with the +.B run +command (see above). When invoking the interpreter, you can specify the +.B --norc +option on the command line if you wish to skip these initializations. .SH SHOW COMMAND In interactive mode, the .B show @@ -2328,6 +2299,97 @@ (available in the .B system standard library module) should be your friend. ;-) +.SS The __show__ Function +As of Pure 0.6, the interpreter provides a ``hook'' to override the print +representations of expressions at runtime by means of the +.B __show__ +function, which works in a fashion similar to Haskell's show function. This +feature is still a bit experimental, but seems to work reasonably well for the +purposes for which it is intended. +.PP +.B __show__ +is just an ordinary Pure function expected to return a string with the desired +custom representation of a normal form value given as the function's single +argument. This function is not defined by default, so you are free to add any +rules that you want. The interpreter prints the strings returned by __show__ +just as they are. It will +.I not +check whether they conform to Pure syntax and/or semantics, or modify them in +any way. +.PP +Custom print representations are most useful for interactive purposes, if +you're not happy with the default print syntax of some kinds of objects. One +particularly useful application of __show__ is to change the format of numeric +values. Here are some examples: +.sp +.nf +> \fBusing\fP system; +> __show__ x::double = sprintf "%0.6f" x; +> 1/7; +0.142857 +> __show__ x::int = sprintf "0x%0x" x; +> 1786; +0x6fa +> \fBusing\fP math; +> __show__ (x::double+:y::double) = sprintf "%0.6f+%0.6fi" (x,y); +> cis (-pi/2); +0.000000+-1.000000i +.fi +.PP +The prelude function +.BR str , +which returns the print representation of any Pure expression, calls __show__ +as well: +.sp +.nf +> str (1/7); +"0.142857" +.fi +.PP +Conversely, you can call the str function from __show__, but in this case it +always returns the default representation of an expression. This prevents the +expression printer from going recursive, and allows you to define your custom +representation in terms of the default one. E.g., the following rule removes +the `L' suffixes from bigint values: +.sp +.nf +> __show__ x::bigint = init (str x); +> fact n = foldl (*) 1L (1..n); +> fact 30; +265252859812191058636308480000000 +.fi +.PP +Of course, your definition of __show__ can also call __show__ itself +recursively to determine the custom representation of an object. +.PP +One case which needs special consideration are thunks (futures). The printer +will never use __show__ for those, to prevent them from being forced +inadvertently. In fact, you +.I can +use __show__ to define custom representations for thunks, but only in the +context of a rule for other kinds of objects, such as lists. For instance: +.sp +.nf +> \fBnullary\fP ...; +> __show__ (x:xs) = str (x:...) \fBif\fP thunkp xs; +> 1:2:(3..inf); +1:2:3:... +.fi +.PP +Finally, by just purging the definition of the __show__ function you can +easily go back to the standard print syntax: +.sp +.nf +> \fBclear\fP __show__ +> 1/7; 1786; cis (-pi/2); +0.142857142857143 +1786 +6.12303176911189e-17+:-1.0 +.fi +.PP +Note that if you have a set of definitions for the __show__ function which +should always be loaded at startup, you can put them into the interpreter's +interactive startup files, see INTERACTIVE USAGE. .SS ``As'' Patterns In the current implementation, ``as'' patterns cannot be placed on the ``spine'' of a function definition. Thus rules like the following, which have This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-06 19:47:24
|
Revision: 736 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=736&view=rev Author: agraef Date: 2008-09-06 19:47:35 +0000 (Sat, 06 Sep 2008) Log Message: ----------- Updated ChangeLog. Modified Paths: -------------- pure/trunk/ChangeLog Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-09-06 19:46:07 UTC (rev 735) +++ pure/trunk/ChangeLog 2008-09-06 19:47:35 UTC (rev 736) @@ -1,10 +1,10 @@ 2008-09-06 Albert Graef <Dr....@t-...> * pure.cc, lexer.ll: Add 'dump' command. This is similar to - 'show', but dumps temporary definitions to a hidden file named - '.pure', which, if present, is loaded after .purerc during - interactive startup. This provides a quick-and-dirty means to save - an interactive session and have it restored later. (This is not + 'show', but dumps definitions to a file (named '.pure' by default, + which, if present, is loaded after .purerc during interactive + startup). This provides a quick-and-dirty means to save an + interactive session and have it restored later. (This is not perfect, though, as variable values containing special objects such as thunks and pointers can't be reconstructed, and 'using' or 'extern' declarations are not recorded. For those you should use This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-06 19:45:56
|
Revision: 735 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=735&view=rev Author: agraef Date: 2008-09-06 19:46:07 +0000 (Sat, 06 Sep 2008) Log Message: ----------- Add -F option to the dump command, cosmetic changes in the output. Modified Paths: -------------- pure/trunk/lexer.ll Modified: pure/trunk/lexer.ll =================================================================== --- pure/trunk/lexer.ll 2008-09-06 19:28:53 UTC (rev 734) +++ pure/trunk/lexer.ll 2008-09-06 19:46:07 UTC (rev 735) @@ -4,6 +4,7 @@ #include <limits.h> #include <string.h> #include <fnmatch.h> +#include <time.h> #include <readline/readline.h> #include <readline/history.h> #include <string> @@ -750,7 +751,8 @@ if (!interp.interactive) REJECT; uint8_t tflag = 1; int pflag = -1; bool cflag = false, fflag = false, mflag = false, vflag = false; - bool gflag = false; + bool gflag = false, Fflag = false; + string fname = ".pure"; const char *s = yytext+4; if (*s && !isspace(*s)) REJECT; yylloc->step(); @@ -759,10 +761,12 @@ if (!args.ok) goto out2; // process option arguments for (arg = args.l.begin(); arg != args.l.end(); arg++) { + if (Fflag) { fname = *arg; Fflag = false; continue; } const char *s = arg->c_str(); - if (s[0] != '-' || !s[1] || !strchr("cfghmptv", s[1])) break; + if (s[0] != '-' || !s[1] || !strchr("Fcfghmptv", s[1])) break; while (*++s) { switch (*s) { + case 'F': Fflag = true; break; case 'c': cflag = true; break; case 'f': fflag = true; break; case 'g': gflag = true; break; @@ -784,7 +788,8 @@ break; case 'h': cout << "dump command help: dump [options ...] [symbol ...]\n\ -Options may be combined, e.g., dump -cv is the same as show -c -v.\n\ +Options may be combined, e.g., dump -tcv is the same as show -t -c -v.\n\ +-F Write the dump to the file named in the next arg (default is .pure).\n\ -c Dump defined constants.\n\ -f Dump defined functions.\n\ -g Indicates that the following symbols are actually shell glob patterns\n\ @@ -919,11 +924,13 @@ } l.sort(env_compare); if (l.empty()) { - unlink(".pure"); + unlink(fname.c_str()); goto out2; } ofstream fout; - fout.open(".pure"); + fout.open(fname.c_str()); + time_t t; time(&t); + fout << "// dump written " << ctime(&t); for (list<env_sym>::const_iterator it = l.begin(); it != l.end(); ++it) { const symbol& sym = *it->sym; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-06 19:28:42
|
Revision: 734 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=734&view=rev Author: agraef Date: 2008-09-06 19:28:53 +0000 (Sat, 06 Sep 2008) Log Message: ----------- Update documentation. Modified Paths: -------------- pure/trunk/pure.1.in Modified: pure/trunk/pure.1.in =================================================================== --- pure/trunk/pure.1.in 2008-09-06 18:19:20 UTC (rev 733) +++ pure/trunk/pure.1.in 2008-09-06 19:28:53 UTC (rev 734) @@ -89,8 +89,11 @@ environment variable is set accordingly), then .B .purerc in the current working directory. These are ordinary Pure scripts which can be -used to provide additional definitions for interactive usage. See the -INTERACTIVE USAGE section for details. +used to provide additional definitions for interactive usage. Finally, a +.B .pure +file in the current directory (containing a dump from a previous interactive +session) is loaded if it is present. See the INTERACTIVE USAGE section for +details. .PP Unless the .B --noediting @@ -1929,7 +1932,14 @@ file in the home directory is for global definitions which should always be available when running interactively, while the .B .purerc -file in the current directory can be used for project-specific definitions. +file in the current directory can be used for project-specific +definitions. There can be yet another +.B .pure +initialization file in the current directory, which is created by the +.B dump +command (see below) and is loaded after the +.B .purerc +files if it is present. .PP The interpreter processes these files in the same way as with the .B run @@ -1956,6 +1966,40 @@ idea to first check your current definitions with \fBlist -t\fP before you do this, though.) See the DEFINITION LEVELS section below for details. .TP +\fBdump\fP [\fIoption\fP ...] [\fIsymbol\fP ...] +Dump function, macro, variable and constant definitions to a file. This works +similar to the +.B show +command (see below and the SHOW COMMAND section), but writes the definitions +to a file. This command only supports a subset of the +.B show +options, type +.B dump -h +for a description of these. +.sp +By default, all definitions made interactively are written to a file named +.B .pure +in the current directory, which is then reloaded automatically the next time +the interpreter starts up in interactive mode in the same directory. This +provides a quick-and-dirty means to save an interactive session and have it +restored later. (Please note that this isn't perfect yet, because variable +values containing special objects such as thunks and pointers can't be +reconstructed, and +.B using +or +.B extern +declarations are not recorded at all. For those you'll have to manually create +a +.B .purerc +file instead.) +.sp +A different filename can be specified with the +.B -F +option. You can then edit that file and use it as a starting point for an +ordinary script or a +.B purerc +file. +.TP \fBhelp\fP [\fIargs\fP] Display the .BR pure (1) @@ -2678,8 +2722,9 @@ .B ~/.pure_history Interactive command history. .TP -\fB~/.purerc\fP, \fB.purerc\fP -Interactive startup files. +\fB~/.purerc\fP, \fB.purerc\fP, \fB.pure\fP +Interactive startup files. The latter is usually a dump from a previous +interactive session. .TP .B prelude.pure Standard prelude. If available, this script is loaded before any other This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-06 18:19:09
|
Revision: 733 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=733&view=rev Author: agraef Date: 2008-09-06 18:19:20 +0000 (Sat, 06 Sep 2008) Log Message: ----------- Cosmetic changes. Modified Paths: -------------- pure/trunk/Makefile.in Modified: pure/trunk/Makefile.in =================================================================== --- pure/trunk/Makefile.in 2008-09-06 18:18:20 UTC (rev 732) +++ pure/trunk/Makefile.in 2008-09-06 18:19:20 UTC (rev 733) @@ -268,15 +268,15 @@ # other glibc-based systems. Other systems might require some work. $(srcdir)/test/prelude.log: lib/prelude.pure lib/primitives.pure lib/strings.pure - LC_ALL=C @LD_LIB_PATH@=. PURELIB=$(srcdir)/lib ./pure -n -v$(level) $< > $@ 2>&1 + LC_ALL=C @LD_LIB_PATH@=. PURELIB=$(srcdir)/lib ./pure --norc -n -v$(level) $< > $@ 2>&1 %.log: %.pure - LC_ALL=C @LD_LIB_PATH@=. PURELIB=$(srcdir)/lib ./pure -v$(level) < $< > $@ 2>&1 + LC_ALL=C @LD_LIB_PATH@=. PURELIB=$(srcdir)/lib ./pure --norc -v$(level) < $< > $@ 2>&1 check: pure @ echo Running tests. - @ (export LC_ALL=C; export @LD_LIB_PATH@=.; export PURELIB=$(srcdir)/lib; echo $(ECHO_N) "prelude.pure: $(ECHO_C)"; if ./pure -n -v$(level) $(srcdir)/lib/prelude.pure 2>&1 | diff -q - $(srcdir)/test/prelude.log > /dev/null; then echo "$(ECHO_T)passed"; else echo "$(ECHO_T)FAILED"; fi) - @ (export LC_ALL=C; export @LD_LIB_PATH@=.; export PURELIB=$(srcdir)/lib; for x in $(notdir $(tests)); do echo $(ECHO_N) "$$x: $(ECHO_C)"; if ./pure -v$(level) < $(srcdir)/test/$$x 2>&1 | diff -q - $(srcdir)/test/"`basename $$x .pure`.log" > /dev/null; then echo "$(ECHO_T)passed"; else echo "$(ECHO_T)FAILED"; fi; done) + @ (export LC_ALL=C; export @LD_LIB_PATH@=.; export PURELIB=$(srcdir)/lib; echo $(ECHO_N) "prelude.pure: $(ECHO_C)"; if ./pure --norc -n -v$(level) $(srcdir)/lib/prelude.pure 2>&1 | diff -q - $(srcdir)/test/prelude.log > /dev/null; then echo "$(ECHO_T)passed"; else echo "$(ECHO_T)FAILED"; fi) + @ (export LC_ALL=C; export @LD_LIB_PATH@=.; export PURELIB=$(srcdir)/lib; for x in $(notdir $(tests)); do echo $(ECHO_N) "$$x: $(ECHO_C)"; if ./pure --norc -v$(level) < $(srcdir)/test/$$x 2>&1 | diff -q - $(srcdir)/test/"`basename $$x .pure`.log" > /dev/null; then echo "$(ECHO_T)passed"; else echo "$(ECHO_T)FAILED"; fi; done) # DO NOT DELETE This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-06 18:18:10
|
Revision: 732 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=732&view=rev Author: agraef Date: 2008-09-06 18:18:20 +0000 (Sat, 06 Sep 2008) Log Message: ----------- Bugfixes. Modified Paths: -------------- pure/trunk/interpreter.cc Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-09-06 18:04:33 UTC (rev 731) +++ pure/trunk/interpreter.cc 2008-09-06 18:18:20 UTC (rev 732) @@ -347,7 +347,7 @@ interpreter::error(const yy::location& l, const string& m) { string m1 = m; - if (m.find("bad token")) + if (m.find("bad token") != string::npos) m1 = "bad anonymous function or pointer value"; nerrs++; if (source_s) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-06 18:04:27
|
Revision: 731 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=731&view=rev Author: agraef Date: 2008-09-06 18:04:33 +0000 (Sat, 06 Sep 2008) Log Message: ----------- Handle external objects in input more gracefully. Modified Paths: -------------- pure/trunk/interpreter.cc pure/trunk/lexer.ll pure/trunk/parser.yy Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-09-06 17:32:03 UTC (rev 730) +++ pure/trunk/interpreter.cc 2008-09-06 18:04:33 UTC (rev 731) @@ -346,14 +346,17 @@ void interpreter::error(const yy::location& l, const string& m) { + string m1 = m; + if (m.find("bad token")) + m1 = "bad anonymous function or pointer value"; nerrs++; if (source_s) { ostringstream msg; - msg << l << ": " << m << endl; + msg << l << ": " << m1 << endl; errmsg += msg.str(); } else { cout.flush(); - cerr << l << ": " << m << endl; + cerr << l << ": " << m1 << endl; } } Modified: pure/trunk/lexer.ll =================================================================== --- pure/trunk/lexer.ll 2008-09-06 17:32:03 UTC (rev 730) +++ pure/trunk/lexer.ll 2008-09-06 18:04:33 UTC (rev 731) @@ -1214,6 +1214,7 @@ } [@=|;()\[\]\\] return yy::parser::token_type(yytext[0]); "->" return token::MAPSTO; +"#<"{id}(" "{int})?">" return token::BADTOK; ([[:punct:]]|[\200-\377])+ { if (yytext[0] == '/' && yytext[1] == '*') REJECT; // comment starter while (yyleng > 1 && yytext[yyleng-1] == ';') yyless(yyleng-1); Modified: pure/trunk/parser.yy =================================================================== --- pure/trunk/parser.yy 2008-09-06 17:32:03 UTC (rev 730) +++ pure/trunk/parser.yy 2008-09-06 18:04:33 UTC (rev 731) @@ -222,6 +222,7 @@ %token EOFTOK 0 "end of file" %token ERRTOK "invalid character" +%token BADTOK "bad token" %token MAPSTO "->" %token <sval> ID "identifier" %token <csval> STR "string" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-06 17:31:53
|
Revision: 730 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=730&view=rev Author: agraef Date: 2008-09-06 17:32:03 +0000 (Sat, 06 Sep 2008) Log Message: ----------- Add dump command. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/lexer.ll pure/trunk/pure.cc Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-09-06 16:59:50 UTC (rev 729) +++ pure/trunk/ChangeLog 2008-09-06 17:32:03 UTC (rev 730) @@ -1,5 +1,15 @@ 2008-09-06 Albert Graef <Dr....@t-...> + * pure.cc, lexer.ll: Add 'dump' command. This is similar to + 'show', but dumps temporary definitions to a hidden file named + '.pure', which, if present, is loaded after .purerc during + interactive startup. This provides a quick-and-dirty means to save + an interactive session and have it restored later. (This is not + perfect, though, as variable values containing special objects + such as thunks and pointers can't be reconstructed, and 'using' or + 'extern' declarations are not recorded. For those you should use + the .purerc file instead.) + * runtime.cc (pure_create_interp): Add new command line options (see below). Modified: pure/trunk/lexer.ll =================================================================== --- pure/trunk/lexer.ll 2008-09-06 16:59:50 UTC (rev 729) +++ pure/trunk/lexer.ll 2008-09-06 17:32:03 UTC (rev 730) @@ -8,6 +8,7 @@ #include <readline/history.h> #include <string> #include <sstream> +#include <fstream> #include "interpreter.hh" #include "parser.hh" #include "util.hh" @@ -132,7 +133,7 @@ now. */ static const char *commands[] = { - "cd", "clear", "const", "def", "extern", "help", "infix", "infixl", + "cd", "clear", "const", "def", "dump", "extern", "help", "infix", "infixl", "infixr", "let", "ls", "nullary", "override", "postfix", "prefix", "private", "pwd", "quit", "run", "save", "show", "stats", "underride", "using", 0 @@ -744,6 +745,252 @@ out: interpreter::g_verbose = s_verbose; } +^dump.* { + // dump command is only permitted in interactive mode + if (!interp.interactive) REJECT; + uint8_t tflag = 1; int pflag = -1; + bool cflag = false, fflag = false, mflag = false, vflag = false; + bool gflag = false; + const char *s = yytext+4; + if (*s && !isspace(*s)) REJECT; + yylloc->step(); + argl args(s, "dump"); + list<string>::iterator arg; + if (!args.ok) goto out2; + // process option arguments + for (arg = args.l.begin(); arg != args.l.end(); arg++) { + const char *s = arg->c_str(); + if (s[0] != '-' || !s[1] || !strchr("cfghmptv", s[1])) break; + while (*++s) { + switch (*s) { + case 'c': cflag = true; break; + case 'f': fflag = true; break; + case 'g': gflag = true; break; + case 'm': mflag = true; break; + case 'p': + if (isdigit(s[1])) { + pflag = strtoul(s+1, 0, 10)>0; + while (isdigit(s[1])) ++s; + } else + pflag = 1; + break; + case 'v': vflag = true; break; + case 't': + if (isdigit(s[1])) { + tflag = strtoul(s+1, 0, 10); + while (isdigit(s[1])) ++s; + } else + tflag = interp.temp; + break; + case 'h': + cout << "dump command help: dump [options ...] [symbol ...]\n\ +Options may be combined, e.g., dump -cv is the same as show -c -v.\n\ +-c Dump defined constants.\n\ +-f Dump defined functions.\n\ +-g Indicates that the following symbols are actually shell glob patterns\n\ + and that all matching symbols should be dumped.\n\ +-h Print this list.\n\ +-m Dump defined macros.\n\ +-p[flag] Dump only private symbols in the current module if flag is\n\ + nonzero (the default), otherwise dump only public symbols of all\n\ + modules. Dump both private and public symbols if -p is omitted.\n\ +-t[level] Dump only symbols and definitions at the given temporary level\n\ + (the current level by default) or above. Level 1 denotes all temporary\n\ + definitions (the default if -t is omitted), level 0 *all* definitions.\n\ +-v Dump defined variables.\n"; + goto out2; + default: + cerr << "show: invalid option character '" << *s << "'\n"; + goto out2; + } + } + } + args.l.erase(args.l.begin(), arg); + if (!cflag && !fflag && !mflag && !vflag) + cflag = fflag = mflag = vflag = true; + { + list<env_sym> l; set<int32_t> syms; + for (env::const_iterator it = interp.globenv.begin(); + it != interp.globenv.end(); ++it) { + int32_t f = it->first; + const env_info& e = it->second; + const symbol& sym = interp.symtab.sym(f); + if (sym.modno >= 0 && sym.modno != interp.modno || + pflag >= 0 && (pflag > 0) != (sym.modno >= 0) || + !((e.t == env_info::fun)?fflag: + (e.t == env_info::cvar)?cflag: + (e.t == env_info::fvar)?vflag:0)) + continue; + bool matches = e.temp >= tflag; + if (!matches && args.l.empty() && + e.t == env_info::fun && fflag) { + // dump temporary rules for a non-temporary symbol + rulel::const_iterator r; + for (r = e.rules->begin(); r != e.rules->end(); r++) + if (r->temp >= tflag) { + matches = true; + break; + } + } + if (!matches) continue; + if (!args.l.empty()) { + // see whether we actually want the defined symbol to be dumped + matches = false; + for (arg = args.l.begin(); arg != args.l.end(); ++arg) { + if (gflag ? (!fnmatch(arg->c_str(), sym.s.c_str(), 0)) : + (*arg == sym.s)) { + matches = true; + break; + } + } + } + if (!matches) continue; + syms.insert(f); + l.push_back(env_sym(sym, it, interp.macenv.find(f), + interp.externals.find(f))); + } + if (fflag && tflag == 0) { + // also process the declared externals which don't have any rules yet + for (extmap::const_iterator it = interp.externals.begin(); + it != interp.externals.end(); ++it) { + int32_t f = it->first; + if (syms.find(f) == syms.end()) { + const symbol& sym = interp.symtab.sym(f); + if (sym.modno >= 0 && sym.modno != interp.modno || + pflag >= 0 && (pflag > 0) != (sym.modno >= 0)) + continue; + bool matches = true; + if (!args.l.empty()) { + matches = false; + for (arg = args.l.begin(); arg != args.l.end(); ++arg) { + if (gflag ? (!fnmatch(arg->c_str(), sym.s.c_str(), 0)) : + (*arg == sym.s)) { + matches = true; + break; + } + } + } + if (!matches) continue; + l.push_back(env_sym(sym, interp.globenv.end(), + interp.macenv.find(f), it)); + } + } + } + if (mflag) { + // also dump any symbols defined as macros, unless they've already been + // considered + for (env::const_iterator it = interp.macenv.begin(); + it != interp.macenv.end(); ++it) { + int32_t f = it->first; + if (syms.find(f) == syms.end()) { + const env_info& e = it->second; + const symbol& sym = interp.symtab.sym(f); + if (sym.modno >= 0 && sym.modno != interp.modno || + pflag >= 0 && (pflag > 0) != (sym.modno >= 0)) + continue; + bool matches = e.temp >= tflag; + if (!matches && args.l.empty()) { + // also dump temporary rules for a non-temporary symbol + rulel::const_iterator r; + for (r = e.rules->begin(); r != e.rules->end(); r++) + if (r->temp >= tflag) { + matches = true; + break; + } + } + if (!matches) continue; + if (!args.l.empty()) { + // see whether we actually want the defined symbol to be dumped + matches = false; + for (arg = args.l.begin(); arg != args.l.end(); ++arg) { + if (gflag ? (!fnmatch(arg->c_str(), sym.s.c_str(), 0)) : + (*arg == sym.s)) { + matches = true; + break; + } + } + } + if (!matches) continue; + syms.insert(f); + l.push_back(env_sym(sym, interp.globenv.end(), it, + interp.externals.end())); + } + } + } + l.sort(env_compare); + if (l.empty()) { + unlink(".pure"); + goto out2; + } + ofstream fout; + fout.open(".pure"); + for (list<env_sym>::const_iterator it = l.begin(); + it != l.end(); ++it) { + const symbol& sym = *it->sym; + int32_t ftag = sym.f; + map<int32_t,Env>::iterator fenv = interp.globalfuns.find(ftag); + const env::const_iterator jt = it->it, kt = it->jt; + const extmap::const_iterator xt = it->xt; + if (jt == interp.globenv.end() && kt == interp.macenv.end()) { + assert(xt != interp.externals.end()); + const ExternInfo& info = xt->second; + fout << info << ";\n"; + } else if (jt != interp.globenv.end() && + jt->second.t == env_info::fvar) { + fout << "let " << sym.s << " = " << *(pure_expr**)jt->second.val + << ";\n"; + } else if (jt != interp.globenv.end() && + jt->second.t == env_info::cvar) { + fout << "const " << sym.s << " = " << *jt->second.cval + << ";\n"; + } else { + if (sym.fix == nullary) + fout << "nullary " << sym.s << ";\n"; + else if (sym.prec < 10) { + switch (sym.fix) { + case infix: + fout << "infix"; break; + case infixl: + fout << "infixl"; break; + case infixr: + fout << "infixr"; break; + case prefix: + fout << "prefix"; break; + case postfix: + fout << "postfix"; break; + case nullary: + assert(0 && "this can't happen"); break; + } + fout << " " << (int)sym.prec << " " << sym.s << ";\n"; + } + if (fflag && xt != interp.externals.end()) { + const ExternInfo& info = xt->second; + fout << info << ";\n"; + } + if (mflag && kt != interp.macenv.end()) { + const rulel& rules = *kt->second.rules; + for (rulel::const_iterator it = rules.begin(); + it != rules.end(); ++it) { + if (it->temp >= tflag) { + fout << "def " << *it << ";\n"; + } + } + } + if (fflag && jt != interp.globenv.end()) { + const rulel& rules = *jt->second.rules; + for (rulel::const_iterator it = rules.begin(); + it != rules.end(); ++it) { + if (it->temp >= tflag) { + fout << *it << ";\n"; + } + } + } + } + } + } + out2: + ; +} ^save.* { // save command is only permitted in interactive mode if (!interp.interactive) REJECT; Modified: pure/trunk/pure.cc =================================================================== --- pure/trunk/pure.cc 2008-09-06 16:59:50 UTC (rev 729) +++ pure/trunk/pure.cc 2008-09-06 17:32:03 UTC (rev 730) @@ -50,7 +50,7 @@ #define LICENSE "This program is free software distributed under the GNU Public License\n(GPL V3 or later). Please see the COPYING file for details.\n" static const char *commands[] = { - "cd", "clear", "const", "def", "extern", "help", "infix", "infixl", + "cd", "clear", "const", "def", "dump", "extern", "help", "infix", "infixl", "infixr", "let", "ls", "nullary", "override", "postfix", "prefix", "private", "pwd", "quit", "run", "save", "show", "stats", "underride", "using", 0 @@ -448,6 +448,10 @@ interp.run(".purerc", false, sticky); sticky = true; } + if (chkfile(".pure")) { + interp.run(".pure", false, sticky); + sticky = true; + } } interp.run("", false, sticky); if (interp.ttymode) cout << endl; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-06 16:59:39
|
Revision: 729 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=729&view=rev Author: agraef Date: 2008-09-06 16:59:50 +0000 (Sat, 06 Sep 2008) Log Message: ----------- Bugfixes. Modified Paths: -------------- pure/trunk/printer.cc Modified: pure/trunk/printer.cc =================================================================== --- pure/trunk/printer.cc 2008-09-06 15:00:35 UTC (rev 728) +++ pure/trunk/printer.cc 2008-09-06 16:59:50 UTC (rev 729) @@ -625,7 +625,12 @@ static inline bool pstr(ostream& os, pure_expr *x) { static bool recursive = false; - if (recursive) return false; + if (recursive || + // We don't want to force a thunk here. Unfortunately, this means that + // currently you can't define a print representation for a thunk, at + // least not directly. :( + x->tag == 0 && x->data.clos && x->data.clos->n == 0) + return false; interpreter& interp = *interpreter::g_interp; int32_t f = interp.symtab.__show__sym; if (f > 0 && interp.globenv.find(f) != interp.globenv.end()) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-06 15:00:25
|
Revision: 728 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=728&view=rev Author: agraef Date: 2008-09-06 15:00:35 +0000 (Sat, 06 Sep 2008) Log Message: ----------- Update documentation. Modified Paths: -------------- pure/trunk/pure.1.in Modified: pure/trunk/pure.1.in =================================================================== --- pure/trunk/pure.1.in 2008-09-06 09:20:39 UTC (rev 727) +++ pure/trunk/pure.1.in 2008-09-06 15:00:35 UTC (rev 728) @@ -1931,7 +1931,7 @@ .B .purerc file in the current directory can be used for project-specific definitions. .PP -The interpreter loads these files in the same way as with the +The interpreter processes these files in the same way as with the .B run command (see below). When invoking the interpreter, you can specify the .B --norc This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-06 09:20:29
|
Revision: 727 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=727&view=rev Author: agraef Date: 2008-09-06 09:20:39 +0000 (Sat, 06 Sep 2008) Log Message: ----------- Update documentation. Modified Paths: -------------- pure/trunk/pure.1.in Modified: pure/trunk/pure.1.in =================================================================== --- pure/trunk/pure.1.in 2008-09-06 08:49:07 UTC (rev 726) +++ pure/trunk/pure.1.in 2008-09-06 09:20:39 UTC (rev 727) @@ -7,7 +7,7 @@ \fBpure\fP [\fIoptions\fP ...] -x \fIscript\fP [\fIargs\fP ...] .SH OPTIONS .TP -.B -h +\fB--help\fP, \fB-h\fP Print help message and exit. .TP .B -i @@ -19,15 +19,24 @@ .BI -L directory Add a directory to be searched for dynamic libraries. .TP -.B -n -Suppress automatic inclusion of the prelude. +.B --noediting +Do not use readline for command-line editing. .TP +\fB--noprelude\fP, \fB-n\fP +Do not load the prelude. +.TP +.B --norc +Do not run the interactive startup files. +.TP .B -q Quiet startup (suppresses sign-on message in interactive mode). .TP .BR -v [\fIlevel\fP] Set verbosity level. See below for details. .TP +.B --version +Print version information and exit. +.TP .B -x Execute script with given command line arguments. .TP @@ -70,12 +79,27 @@ command or the end-of-file character (^D on Unix) at the beginning of the command line. .PP -When the interpreter is in interactive mode and reads from a tty, commands are -read using +Unless the +.B --norc +option is specified, in interactive mode the interpreter automatically loads +some additional startup files if they are present; first +.B .purerc +in the user's home directory (provided that the +.B HOME +environment variable is set accordingly), then +.B .purerc +in the current working directory. These are ordinary Pure scripts which can be +used to provide additional definitions for interactive usage. See the +INTERACTIVE USAGE section for details. +.PP +Unless the +.B --noediting +option is specified, when the interpreter is in interactive mode and reads +from a tty, commands are read using .BR readline (3) (providing completion for all commands listed under INTERACTIVE USAGE, as well -as for symbols defined in the running program) and, when exiting the -interpreter, the command history is stored in +as for symbols defined in the running program). When exiting the interpreter, +the command history is stored in .BR ~/.pure_history , from where it is restored the next time you run the interpreter. .PP @@ -1784,7 +1808,8 @@ last script specified on the command line determines the visible namespace (i.e., all public symbols are visible, along with the private symbols of the loaded script). Otherwise only the public symbols defined in the prelude are -available. Additional scripts can be loaded interactively using either a +available, as well as the (public or private) definitions in the startup files +(see below). Additional scripts can be loaded interactively using either a .B using declaration or the interactive .B run @@ -1872,6 +1897,10 @@ 265252859812191058636308480000000 .fi .PP +If you have a set of definitions for the __show__ function which should always +be loaded at startup, you can put them into the interpreter's interactive +startup files, see below. +.PP By just purging the definition of the __show__ function you can easily go back to the standard print syntax: .sp @@ -1886,6 +1915,27 @@ > fact 30; 265252859812191058636308480000000L .fi +.SS Startup Files +When running the interpreter interactively, it loads some additional scripts +at startup, after loading the prelude. The interpreter first looks for a +.B .purerc +file in the user's home directory (as given by the +.B HOME +environment variable) and then for a +.B .purerc +file in the current working directory. These are just ordinary Pure scripts +which may contain any additional definitions that you need. The +.B .purerc +file in the home directory is for global definitions which should always be +available when running interactively, while the +.B .purerc +file in the current directory can be used for project-specific definitions. +.PP +The interpreter loads these files in the same way as with the +.B run +command (see below). When invoking the interpreter, you can specify the +.B --norc +option on the command line if you do not wish to load these files. .SS Interactive Commands When running interactively, the interpreter also accepts a number of special commands useful for interactive purposes. Here is a quick rundown of the @@ -2628,6 +2678,9 @@ .B ~/.pure_history Interactive command history. .TP +\fB~/.purerc\fP, \fB.purerc\fP +Interactive startup files. +.TP .B prelude.pure Standard prelude. If available, this script is loaded before any other definitions, unless This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-06 08:48:58
|
Revision: 726 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=726&view=rev Author: agraef Date: 2008-09-06 08:49:07 +0000 (Sat, 06 Sep 2008) Log Message: ----------- Overhaul of command line options. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/pure.cc pure/trunk/runtime.cc Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-09-06 07:57:49 UTC (rev 725) +++ pure/trunk/ChangeLog 2008-09-06 08:49:07 UTC (rev 726) @@ -1,8 +1,18 @@ 2008-09-06 Albert Graef <Dr....@t-...> + * runtime.cc (pure_create_interp): Add new command line options + (see below). + * pure.cc (main): Source interactive startup files (first $HOME/.purerc, then $PWD/.purerc). + Add options --norc to not source the rc files and --noediting to + suppress readline editing, as well as --noprelude (long form of + -n), --help (long form of -h) and --version (like --help, but only + print version information). + + Overhaul help message. + 2008-09-05 Albert Graef <Dr....@t-...> * pure.cc (main): In interactive mode, print a warning if -n was Modified: pure/trunk/pure.cc =================================================================== --- pure/trunk/pure.cc 2008-09-06 07:57:49 UTC (rev 725) +++ pure/trunk/pure.cc 2008-09-06 08:49:07 UTC (rev 726) @@ -32,25 +32,21 @@ #define COPYRIGHT "Copyright (c) 2008 by Albert Graef" #define USAGE \ -"Usage: pure [options ...] [script ...] [-- args ...]\n\ - pure [options ...] -x script [args ...]\n\ -Options:\n\ --h Print this message and exit.\n\ --i Force interactive mode (read commands from stdin).\n\ --Idirectory Add directory to search for included source files.\n\ --Ldirectory Add directory to search for dynamic libraries.\n\ --n Suppress automatic inclusion of the prelude.\n\ --q Quiet startup (suppresses sign-on message).\n\ --v[level] Set debugging level (default: 1).\n\ --x Execute script with given command line arguments.\n\ --- Stop option processing, pass remaining args in argv variable.\n\ -Environment:\n\ -PURELIB Directory to search for library scripts and the prelude.\n\ -PURE_INCLUDE Path to search for included source files.\n\ -PURE_LIBRARY Path to search for dynamic libraries.\n\ -PURE_MORE Shell command for paging through output of the 'show' command.\n\ -PURE_PS Command prompt to be used in the interactive command loop.\n\ -PURE_STACK Maximum stack size in kilobytes (default: 0 = unlimited).\n" +"Usage: pure [options ...] [script ...] [-- args ...]\n\ + pure [options ...] -x script [args ...]\n\ +--help, -h Print this message and exit.\n\ +-i Force interactive mode (read commands from stdin).\n\ +-Idirectory Add directory to search for included source files.\n\ +-Ldirectory Add directory to search for dynamic libraries.\n\ +--noediting Do not use readline for command-line editing.\n\ +--noprelude, -n Do not load the prelude.\n\ +--norc Do not run the interactive startup files.\n\ +-q Quiet startup (suppresses sign-on message).\n\ +-v[level] Set debugging level (default: 1).\n\ +--version Print version information and exit.\n\ +-x Execute script with given command line arguments.\n\ +-- Stop option processing.\n\ +Type 'help' in the interpreter for more help.\n" #define LICENSE "This program is free software distributed under the GNU Public License\n(GPL V3 or later). Please see the COPYING file for details.\n" static const char *commands[] = { @@ -232,7 +228,8 @@ interpreter interp; int count = 0; bool quiet = false, force_interactive = false, - want_prelude = true, have_prelude = false; + want_prelude = true, have_prelude = false, + want_rcfile = true, want_editing = true; string rcfile; // This is used in advisory stack checks. interpreter::baseptr = &base; @@ -295,14 +292,22 @@ const string prog = *argv; list<string> myargs; for (char **args = ++argv; *args; ++args) - if (*args == string("-h")) { + if (*args == string("-h") || *args == string("--help")) { cout << "Pure " << PACKAGE_VERSION << " (" << HOST << ") " << COPYRIGHT << endl << USAGE; return 0; + } else if (*args == string("--version")) { + cout << "Pure " << PACKAGE_VERSION << " (" << HOST << ") " + << COPYRIGHT << endl; + return 0; } else if (*args == string("-i")) force_interactive = true; - else if (*args == string("-n")) + else if (*args == string("-n") || *args == string("--noprelude")) want_prelude = false; + else if (*args == string("--norc")) + want_rcfile = false; + else if (*args == string("--noediting")) + want_editing = false; else if (*args == string("-q")) quiet = true; else if (string(*args).substr(0,2) == "-I") { @@ -418,7 +423,7 @@ interp.compile(); interp.ttymode = true; } - if (isatty(fileno(stdin))) { + if (want_editing && isatty(fileno(stdin))) { // initialize readline extern bool using_readline; using_readline = true; @@ -434,14 +439,16 @@ if (force_interactive) interp.modno = last_modno; // source the initialization files, if any bool sticky = force_interactive; - if (!rcfile.empty() && chkfile(rcfile)) { - interp.run(rcfile, false, sticky); - sticky = true; + if (want_rcfile) { + if (!rcfile.empty() && chkfile(rcfile)) { + interp.run(rcfile, false, sticky); + sticky = true; + } + if (chkfile(".purerc")) { + interp.run(".purerc", false, sticky); + sticky = true; + } } - if (chkfile(".purerc")) { - interp.run(".purerc", false, sticky); - sticky = true; - } interp.run("", false, sticky); if (interp.ttymode) cout << endl; return 0; Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-09-06 07:57:49 UTC (rev 725) +++ pure/trunk/runtime.cc 2008-09-06 08:49:07 UTC (rev 726) @@ -1062,12 +1062,18 @@ // scan the command line options list<string> myargs; for (char **args = ++argv; *args; ++args) - if (*args == string("-h")) + if (*args == string("-h") || *args == string("--help")) /* ignored */; + else if (*args == string("--version")) + /* ignored */; else if (*args == string("-i")) /* ignored */; - else if (*args == string("-n")) + else if (*args == string("-n") || *args == string("--noprelude")) want_prelude = false; + else if (*args == string("--norc")) + /* ignored */; + else if (*args == string("--noediting")) + /* ignored */; else if (*args == string("-q")) /* ignored */; else if (string(*args).substr(0,2) == "-I") { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-06 07:57:38
|
Revision: 725 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=725&view=rev Author: agraef Date: 2008-09-06 07:57:49 +0000 (Sat, 06 Sep 2008) Log Message: ----------- Add support for interactive startup files (.purerc). Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/pure.cc Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-09-06 07:39:02 UTC (rev 724) +++ pure/trunk/ChangeLog 2008-09-06 07:57:49 UTC (rev 725) @@ -1,3 +1,8 @@ +2008-09-06 Albert Graef <Dr....@t-...> + + * pure.cc (main): Source interactive startup files (first + $HOME/.purerc, then $PWD/.purerc). + 2008-09-05 Albert Graef <Dr....@t-...> * pure.cc (main): In interactive mode, print a warning if -n was Modified: pure/trunk/pure.cc =================================================================== --- pure/trunk/pure.cc 2008-09-06 07:39:02 UTC (rev 724) +++ pure/trunk/pure.cc 2008-09-06 07:57:49 UTC (rev 725) @@ -233,6 +233,7 @@ int count = 0; bool quiet = false, force_interactive = false, want_prelude = true, have_prelude = false; + string rcfile; // This is used in advisory stack checks. interpreter::baseptr = &base; /* Set up handlers for all standard POSIX termination signals (except @@ -267,8 +268,10 @@ setlocale(LC_ALL, ""); // get some settings from the environment const char *env; - if ((env = getenv("HOME"))) + if ((env = getenv("HOME"))) { interp.histfile = string(env)+"/.pure_history"; + rcfile = string(env)+"/.purerc"; + } if ((env = getenv("PURE_PS"))) interp.ps = string(env); if ((env = getenv("PURE_STACK"))) { @@ -429,7 +432,17 @@ interp.temp = 1; if (last_modno < 0) force_interactive = false; if (force_interactive) interp.modno = last_modno; - interp.run("", false, force_interactive); + // source the initialization files, if any + bool sticky = force_interactive; + if (!rcfile.empty() && chkfile(rcfile)) { + interp.run(rcfile, false, sticky); + sticky = true; + } + if (chkfile(".purerc")) { + interp.run(".purerc", false, sticky); + sticky = true; + } + interp.run("", false, sticky); if (interp.ttymode) cout << endl; return 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-06 07:38:51
|
Revision: 724 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=724&view=rev Author: agraef Date: 2008-09-06 07:39:02 +0000 (Sat, 06 Sep 2008) Log Message: ----------- Fix typos and formatting glitches. Modified Paths: -------------- pure/trunk/pure.1.in Modified: pure/trunk/pure.1.in =================================================================== --- pure/trunk/pure.1.in 2008-09-06 07:15:26 UTC (rev 723) +++ pure/trunk/pure.1.in 2008-09-06 07:39:02 UTC (rev 724) @@ -225,11 +225,8 @@ order to turn it into an executable program. .PP There are a few reserved keywords which cannot be used as identifiers: -.if t .PP -.if t .RS case const def else end extern if infix infixl infixr let nullary of -otherwise postfix prefix private then using when with -.if t .RE +otherwise postfix prefix private then using when with. .PP Pure is a terse language. You won't see many declarations, and often your programs will read more like a collection of algebraic specifications (which @@ -912,7 +909,7 @@ 0L:1L:1L:2L:3L:5L:8L:13L:21L:34L:#<thunk 0xb4ce5d30> .fi .PP -As you can see, the invokation of our `takel' function forced the +As you can see, the invocation of our `takel' function forced the corresponding prefix of the `fibs' stream to be computed. The result of the evaluation is memoized, so that this portion of the stream is now readily available in case we need to have another look at it later. By these means, @@ -1820,7 +1817,7 @@ (anonymous and local functions), thunks (``lazy'' values to be evaluated when needed) and pointers which don't have a textual representation in the Pure syntax and will be printed in the format -.BR "#<\fIobject description\fP>" . +\fB#<\fP\fIobject description\fP\fB>\fP. .PP The interpreter provides a ``hook'' to override the print representations of expressions at runtime by means of the This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-06 07:15:16
|
Revision: 723 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=723&view=rev Author: agraef Date: 2008-09-06 07:15:26 +0000 (Sat, 06 Sep 2008) Log Message: ----------- Reformatting. Modified Paths: -------------- pure/trunk/pure.1.in Modified: pure/trunk/pure.1.in =================================================================== --- pure/trunk/pure.1.in 2008-09-05 22:58:16 UTC (rev 722) +++ pure/trunk/pure.1.in 2008-09-06 07:15:26 UTC (rev 723) @@ -224,9 +224,12 @@ Unix-like systems this allows you to add a ``shebang'' to your main script in order to turn it into an executable program. .PP -There are a few reserved keywords which cannot be used as identifiers. These -are: case const def else end extern if infix infixl infixr let nullary of -otherwise postfix prefix private then using when with. +There are a few reserved keywords which cannot be used as identifiers: +.if t .PP +.if t .RS +case const def else end extern if infix infixl infixr let nullary of +otherwise postfix prefix private then using when with +.if t .RE .PP Pure is a terse language. You won't see many declarations, and often your programs will read more like a collection of algebraic specifications (which @@ -307,11 +310,10 @@ .B false and any non-zero value .BR true ). -.PP -.B Expression syntax. +.SS Expression Syntax Expressions consist of the following elements: .TP -.B Constants: \fR4711, 4711L, 1.2e-3, \(dqHello,\ world!\en\(dq +\fBConstants:\fP 4711, 4711L, 1.2e-3, \(dqHello,\ world!\en\(dq The usual C'ish notations for integers (decimal, hexadecimal, octal), floating point values and double-quoted strings are all provided, although the Pure syntax differs in some minor ways, as discussed in the following. First, there @@ -344,7 +346,7 @@ Thus, e.g., \(dq\e©\(dq denotes the copyright character (code point 0x000A9). .TP -.B Function and variable symbols: \fRfoo, foo_bar, BAR, bar2 +\fBFunction and variable symbols:\fP foo, foo_bar, BAR, bar2 These consist of the usual sequence of ASCII letters (including the underscore) and digits, starting with a letter. The `_' symbol, when occurring on the left-hand side of an equation, is special; it denotes the @@ -360,7 +362,7 @@ .B nullary symbols, see below). .TP -.B Operator and constant symbols: \fRx+y, x==y, \fBnot\fP\ x, [] +\fBOperator and constant symbols:\fP x+y, x==y, \fBnot\fP\ x, [] As indicated, these take the form of an identifier or a sequence of punctuation symbols. As of Pure 0.6, operator and constant symbols may also contain arbitrary extended (non-ASCII) Unicode characters, which makes it @@ -380,7 +382,7 @@ left-hand side of an equation, it is to be interpreted as a constant rather than a variable (see above). .TP -.B Lists and tuples: \fR[x,y,z], x..y, x:xs, x,y,z +\fBLists and tuples:\fP [x,y,z], x..y, x:xs, x,y,z The necessary constructors to build lists and tuples are actually defined in the prelude: `[]' and `()' are the empty list and tuple, `:' produces list ``conses'', and `,' produces ``pairs''. As indicated, Pure provides the usual @@ -402,7 +404,7 @@ tuple 1,2, the integer 3, and another tuple 4,5. Likewise, [(1,2,3)] is list with a single element, the tuple 1,2,3. .TP -.B List comprehensions: \fR[x,y; x = 1..n; y = 1..m; x<y] +\fBList comprehensions:\fP [x,y; x = 1..n; y = 1..m; x<y] Pure also has list comprehensions which generate lists from an expression and one or more ``generator'' and ``filter'' clauses (the former bind a pattern to values drawn from a list, the latter are just predicates determining which @@ -413,26 +415,26 @@ prelude), but they are often much easier to write. Some examples of list comprehensions can be found in the EXAMPLES section below. .TP -.B Function applications: \fRfoo\ x\ y\ z +\fBFunction applications:\fP foo x y z As in other modern FPLs, these are written simply as juxtaposition (i.e., in ``curried'' form) and associate to the left. Operator applications are written using prefix, postfix or infix notation, as the declaration of the operator demands, but are just ordinary function applications in disguise. E.g., x+y is exactly the same as (+) x y. .TP -.B Conditional expressions: if\fR\ x\ \fBthen\fR\ y\ \fBelse\fR\ z +\fBConditional expressions:\fP \fBif\fP x \fBthen\fP y \fBelse\fP z Evaluates to y or z depending on whether x is ``true'' (i.e., a nonzero integer). An exception is generated if the condition is not an integer. .TP -.B Lambdas: \fR\ex\ ->\ y +\fBLambdas:\fP \ex\ ->\ y These work pretty much like in Haskell. More than one variable may be bound (e.g, \ex\ y\ ->\ x*y), which is equivalent to a nested lambda (\ex\ ->\ \ey\ ->\ x*y). Pure also fully supports pattern-matching lambda abstractions which match a pattern against the lambda argument and bind multiple lambda variables in one go, such as \e(x,y)\ ->\ x*y. .TP -.B Case expressions: case\fR\ x\ \fBof\fR\ \fIrule\fR;\ ...\ \fBend +\fBCase expressions:\fP \fBcase\fP x \fBof\fP \fIrule\fP; ... \fBend\fP Matches an expression, discriminating over a number of different cases, similar to the Haskell \fBcase\fP construct. The expression x is matched in turn against each left-hand side pattern in the rule list, and the first @@ -440,7 +442,7 @@ evaluating the corresponding right-hand side with the variables in the pattern bound to their corresponding values. .TP -.B When expressions: \fRx\ \fBwhen\fR\ \fIrule\fR;\ ...\ \fBend +\fBWhen expressions:\fP x \fBwhen\fP \fIrule\fR; ... \fBend\fP An alternative way to bind local variables by matching a collection of subject terms against corresponding patterns. Similar to Aardappel's \fBwhen\fP construct. A single binding such as x \fBwhen\fP u = v \fBend\fP is equivalent @@ -452,14 +454,13 @@ like several nested \fBwhen\fP expressions, with the first binding being the ``outermost'' one. .TP -.B With expressions: \fRx\ \fBwith\fR\ \fIrule\fR;\ ...\ \fBend\fR +\fBWith expressions:\fP x \fBwith\fP \fIrule\fR; ... \fBend\fP Defines local functions. Like Haskell's \fBwhere\fP construct, but it can be used anywhere inside an expression (just like Aardappel's \fBwhere\fP, but Pure uses the keyword \fBwith\fP which better lines up with \fBcase\fP and \fBwhen\fP). Several functions can be defined in a single \fBwith\fP clause, and the definitions may consist of as many equations as you want. -.PP -.B Operators and precedence. +.SS Operators and Precedence Expressions are parsed according to the following precedence rules: Lambda binds most weakly, followed by .BR when , @@ -492,8 +493,7 @@ and .B or instead of `&' and `|', which are used for other purposes in Pure. -.PP -.B Special forms. +.SS Special Forms As already mentioned, some operators are actually implemented as special forms. In particular, the conditional expression \fBif\fP x \fBthen\fP y \fBelse\fP z is a special form with call-by-name arguments y and z; only one @@ -540,13 +540,12 @@ infinite. The Pure prelude defines many functions for creating and manipulating these kinds of objects; further details and examples can be found in the EXAMPLES section below. -.PP -.B Toplevel. +.SS Toplevel At the toplevel, a Pure program basically consists of rewriting rules (which are used to define functions and macros), constant and variable definitions, and expressions to be evaluated: .TP -.B Rules: \fIlhs\fR = \fIrhs\fR; +\fBRules:\fP \fIlhs\fP = \fIrhs\fP; These rules always combine a left-hand side .I pattern (which must be a simple expression) and a right-hand side (which can be any @@ -561,7 +560,7 @@ out common left-hand or right-hand sides in collections of rules; see section RULE SYNTAX below for details. .TP -.B Macro rules: def\fR \fIlhs\fR = \fIrhs\fR; +\fBMacro rules:\fP \fBdef\fP \fIlhs\fP = \fIrhs\fP; A rule starting with the keyword .B def defines a @@ -572,13 +571,13 @@ user-defined special forms and simple kinds of optimization rules. See the MACROS section below for details and examples. .TP -.B Global variable bindings: let\fR \fIlhs\fR = \fIrhs\fR; +\fBGlobal variable bindings:\fP \fBlet\fP \fIlhs\fP = \fIrhs\fP; Binds every variable in the left-hand side pattern to the corresponding subterm of the right-hand side (after evaluating it). This works like a \fBwhen\fP clause, but serves to bind \fIglobal\fP variables occurring free on the right-hand side of other function and variable definitions. .TP -.B Constant bindings: const\fR \fIlhs\fR = \fIrhs\fR; +\fBConstant bindings:\fP \fBconst\fP \fIlhs\fP = \fIrhs\fP; An alternative form of \fBlet\fP which defines constants rather than variables. (These are not to be confused with .B nullary @@ -590,12 +589,11 @@ directly into the right-hand sides of other definitions, rather than being looked up at runtime. .TP -.B Toplevel expressions: \fIexpr\fR; +\fBToplevel expressions:\fP \fIexpr\fP; A singleton expression at the toplevel, terminated with a semicolon, simply causes the given value to be evaluated (and the result to be printed, when running in interactive mode). -.PP -.B Scoping rules. +.SS Scoping Rules A few remarks about the scope of identifiers and other symbols are in order here. Like most modern functional languages, Pure uses .I lexical @@ -743,9 +741,10 @@ > foo 1; 6.28318530717958 .fi -.PP -.B List comprehensions. -Erathosthenes' classical prime sieve: +.SS List Comprehensions +List comprehensions are Pure's main workhorse for generating and processing +all kinds of list values. Here's a well-known example, Erathosthenes' +classical prime sieve: .sp .nf primes n = sieve (2..n) \fBwith\fP @@ -785,8 +784,7 @@ = i1==i2 || j1==j2 || i1+j1==i2+j2 || i1-j1==i2-j2; \fBend\fP; .fi -.PP -.B Lazy evaluation and streams. +.SS Lazy Evaluation and Streams As already mentioned, lists can also be evaluated in a ``lazy'' fashion, by just turning the tail of a list into a .IR future . @@ -832,6 +830,9 @@ [0L,1L,1L,2L,3L,5L,8L,13L,21L,34L] .fi .PP +(Conversely, you can also turn a list into a stream value with the `stream' +function.) +.PP For interactive usage it's often convenient to define an eager variation of `take' which combines `take' and `list'. Let's do this now, so that we can use this operation in the following examples. @@ -1143,8 +1144,7 @@ will be expanded using the leftmost-innermost reduction strategy (i.e., macro calls in macro arguments are expanded before the macro gets applied to its parameters). -.PP -.B Optimization rules. +.SS Optimization Rules Here is a simple example, showing a rule which expands saturated calls of the .B succ function (defined in the prelude) at compile time: @@ -1239,8 +1239,7 @@ of a macro definition must be a simple expression, and thus it's not possible to write a macro which descends recursively into the lambda argument of `catmap'.) -.PP -.B Recursive macros. +.SS Recursive Macros Macros can also be recursive, in which case they usually consist of multiple rules and make use of pattern-matching like ordinary function definitions. Example: @@ -1261,8 +1260,7 @@ with these by setting the .B PURE_STACK environment variable. -.PP -.B Convenience macros. +.SS Convenience Macros The following `timex' macro provides an example of how you can use macros to define your own special forms. This is made possible by the fact that the macro arguments will only be evaluated at runtime and can thus be passed to @@ -1289,8 +1287,7 @@ function definition, since by virtue of Pure's basic eager evaluation strategy the x parameter would have been evaluated already before it is passed to `timex', making `timex' always return a zero time value. Try it.) -.PP -.B Macro hygiene. +.SS Macro Hygiene Pure macros are lexically scoped, i.e., symbols on the right-hand-side of a macro definition can never refer to anything outside the macro definition, and macro parameter substitution also takes into account binding constructs, such @@ -1325,7 +1322,7 @@ .B using clauses which let you include other scripts in a Pure script. .TP -.B Private symbol declarations: private \fIsymbol\fP\fR ...;\fP +\fBPrivate symbol declarations:\fP \fBprivate\fP \fIsymbol\fP ...; Declares the listed symbols as .IR private . Pure programs usually consist of several source scripts (see the description @@ -1346,7 +1343,7 @@ them all with whitespace in between. The same applies to the other types of symbol declarations discussed below. .TP -.B Operator declarations: infix \fIlevel\fP \fIop\fP\fR ...;\fP +\fBOperator declarations:\fP \fBinfix\fP \fIlevel op\fP ...; These may also be prefixed with the keyword .B private to indicate a private operator symbol (see above). @@ -1375,7 +1372,7 @@ minus operator; the unary minus operation can be denoted using the built-in `neg' function. .TP -.B Constant symbol declarations: nullary \fIsymbol\fP\fR ...;\fP +\fBConstant symbol declarations:\fP \fBnullary\fP \fIsymbol\fP ...; Constant symbols are introduced using a .B nullary declaration (again, a @@ -1397,7 +1394,7 @@ symbols as well as the list and pair constructors `:' and `,' and the empty list and tuple constants `[]' and `()'. .TP -.B Using clause: using \fIname\fR, ...; +\fBUsing clause:\fP \fBusing\fP \fIname\fP, ...; Causes each given script to be included in the Pure program. Each included script is loaded only .IR once , @@ -1410,7 +1407,7 @@ .B using clause also has an alternative form which allows dynamic libraries to be loaded, this will be discussed in the C INTERFACE section. -.PP +.SS The `using' Declaration The .B using declaration provides a simple but effective way to assemble a Pure program @@ -1580,9 +1577,11 @@ returns the first solution. Note the use of .B throw in the recursive search routine to bail out with a solution as soon as we -found one. The value thrown there is caught in the main routine. If no value -gets thrown, the function regularly returns with () to indicate that there is -no solution. +found one. The value thrown there is caught in the main routine. Also note the +use of `void' in the second equation of `search'. This effectively turns the +list comprehension into a simple loop which suppresses the normal list result +and just returns () instead. Thus, if no value gets thrown then the function +regularly returns with () to indicate that there is no solution. .sp .nf queens1 n = catch reverse (search n 1 []) \fBwith\fP @@ -1812,8 +1811,7 @@ > map fact (1..10); [1,2,6,24,120,720,5040,40320,362880,3628800] .fi -.PP -.B Print syntax. +.SS Print Syntax As indicated, in interactive mode the normal forms of toplevel expressions are printed after each expression is entered. We also call this the .I read-eval-print @@ -1891,19 +1889,18 @@ > fact 30; 265252859812191058636308480000000L .fi -.PP -.B Interactive commands. +.SS Interactive Commands When running interactively, the interpreter also accepts a number of special commands useful for interactive purposes. Here is a quick rundown of the currently supported operations: .TP -.B "! \fIcommand\fP" +\fB!\fP \fIcommand\fP Shell escape. .TP -.B "cd \fIdir\fP" +\fBcd\fP \fIdir\fP Change the current working dir. .TP -.B "clear \fR[\fIsymbol\fP ...]\fP" +\fBclear\fP [\fIsymbol\fP ...] Purge the definitions of the given symbols (functions, macros, constants or global variables). If no symbols are given, purge \fIall\fP definitions (after confirmation) made after the most recent @@ -1912,14 +1909,14 @@ idea to first check your current definitions with \fBlist -t\fP before you do this, though.) See the DEFINITION LEVELS section below for details. .TP -.B "help \fR[\fIargs\fP]\fP" +\fBhelp\fP [\fIargs\fP] Display the .BR pure (1) manpage, or invoke .BR man (1) with the given arguments. .TP -.B "ls \fR[\fIargs\fP]\fP" +\fBls\fP [\fIargs\fP] List files (shell \fBls\fP(1) command). .TP .B override @@ -1933,17 +1930,16 @@ .B quit Exits the interpreter. .TP -.B "run \fIscript\fP" +\fBrun\fP \fIscript\fP Loads the given script file and adds its definitions to the current environment. This works more or less like a .B using clause, but only searches for the script in the current directory and loads -the script ``anonymously'', as if the contents of the script had been typed at -the command prompt. That is, +the script ``anonymously.'' That is, .B run -will just put the definitions into the current namespace, giving you access to -all private symbols of the script. Also, the definitions are placed at the -current temporary level, so that +puts the definitions into the current namespace, giving you access to all +private symbols of the script. Also, the definitions are placed at the current +temporary level, so that .B clear can be used to remove them again. In particular, this makes it possible to quickly reload a script without exiting the interpreter, by issuing the @@ -1961,11 +1957,11 @@ (or the beginning of the interactive session). See the DEFINITION LEVELS section below for details. .TP -.B "show \fR[\fIoption\fP ...]\fP \fR[\fIsymbol\fP ...]\fP" +\fBshow\fP [\fIoption\fP ...] [\fIsymbol\fP ...] Show the definitions of symbols in various formats. See the SHOW COMMAND section below for details. .TP -.B "stats \fR[on|off]\fP" +\fBstats\fP [on|off] Enables (default) or disables ``stats'' mode, in which various statistics are printed after an expression has been evaluated. Currently, this just prints the cpu time in seconds for each evaluation, but in the future additional @@ -2029,7 +2025,7 @@ .B -m Print information about defined macros. .TP -.B -p[\fIflag\fP] +\fB-p\fP[\fIflag\fP] List only private symbols in the current module if \fIflag\fP is nonzero (the default), otherwise (\fIflag\fP is zero) list only public symbols of all modules. List both private and public symbols if -p is omitted. The @@ -2038,7 +2034,7 @@ .B -s Summary format, print just summary information about listed symbols. .TP -.B -t[\fIlevel\fP] +\fB-t\fP[\fIlevel\fP] List only ``temporary'' symbols and definitions at the given \fIlevel\fP (the current level by default) or above. The \fIlevel\fP parameter, if given, must immediately follow the option character. A \fIlevel\fP of 1 denotes all @@ -2222,8 +2218,7 @@ This section is a grab bag of casual remarks, useful tips and tricks, and information on common pitfalls, quirks and limitations of the current implementation and how to deal with them. -.PP -.B Purity. +.SS Purity People keep asking me what's so ``pure'' about Pure. The long and apologetic answer is that at its core, Pure is in fact purely algebraic and purely functional. Pure doesn't get in your way if you want to call external @@ -2236,15 +2231,13 @@ The short answer is that I simply liked the name, and there wasn't any programming language named ``Pure'' yet (quite a feat nowadays), so there's one now. :) -.PP -.B Debugging. +.SS Debugging There's no symbolic debugger yet. So .BR printf (3) (available in the .B system standard library module) should be your friend. ;-) -.PP -.B ``As'' patterns. +.SS ``As'' Patterns In the current implementation, ``as'' patterns cannot be placed on the ``spine'' of a function definition. Thus rules like the following, which have the pattern somewhere in the head of the left-hand side, will all provoke an @@ -2265,8 +2258,7 @@ > \fBcase\fP bar 99 \fBof\fP y@(bar x) = y,x+1; \fBend\fP; bar 99,100 .fi -.PP -.B Head = function. +.SS Head = Function ``As'' patterns are also a useful device if you need to manipulate function applications in a generic way. Note that the ``head = function'' rule means that the head symbol f of an application f x1 ... xn occurring on (or inside) @@ -2333,8 +2325,7 @@ > foop foo, foop 99; 1,0 .fi -.PP -.B With or when? +.SS With or when? A common source of confusion for Haskellers is that Pure provides two different constructs to bind local function and variable symbols, respectively. This distinction is necessary because Pure does not segregate @@ -2368,8 +2359,7 @@ around this with conditional and .B case expressions, though. -.PP -.B Numeric calculations. +.SS Numeric Calculations If possible, you should decorate numeric variables on the left-hand sides of function definitions with the appropriate type tags, like .B ::int @@ -2402,8 +2392,7 @@ against constant values of these types; in particular, a small integer constant like `0' only matches machine integers, not bigints; for the latter you'll have to use the ``big L'' notation `0L'. -.PP -.B Constant definitions. +.SS Constant Definitions When definining a function in terms of constant values which have to be computed beforehand, it's usually better to use a .B const @@ -2490,8 +2479,7 @@ to redefine it as a constant, or vice versa, since Pure won't let you redefine an existing constant or variable as a different kind of symbol. The same also holds if a symbol is currently defined as a function or a macro.) -.PP -.B External C functions. +.SS External C Functions The interpreter always takes your .B extern declarations of C routines at face value. It will not go and read any C header @@ -2507,16 +2495,14 @@ Therefore it is highly recommended that you wrap your lowlevel code in Pure routines and data structures which do all the checks necessary to ensure that only the right kind of data is passed to C routines. -.PP -.B Special forms. +.SS Special Forms Special forms are recognized at compile time only. Thus the catch function as well as the logical connectives && and ||, the sequencing operator $$ and the lazy evaluation operator & are only treated as special forms in direct (saturated) calls. They can still be used if you pass them around as function values or partial applications, but in this case they lose all their special call-by-name argument processing. -.PP -.B Laziness. +.SS Laziness Pure does lazy evaluation in the same way as Alice ML, providing an explicit operation (&) to defer evaluation and create a ``future'' which is called by need. However, note that like any language with a basically eager evaluation @@ -2552,8 +2538,7 @@ need something like Haskell's irrefutable matches, you'll have to code them explicitly using futures. See the definition of the `unzip' function in the prelude for an example showing how to do this. -.PP -.B Stack size and tail recursion. +.SS Stack Size and Tail Recursion Pure programs may need a considerable amount of stack space to handle recursive function calls, and the interpreter itself also takes its toll. So you may have to configure your system accordingly (8 MB of stack space is @@ -2604,8 +2589,7 @@ can be changed at any time during an interactive session, without having to recompile the entire program.) However, mutual tail recursion does work with \fIlocal\fP functions, so it's easy to work around this limitation. -.PP -.B Handling of asynchronous signals. +.SS Handling of Asynchronous Signals As described in section EXCEPTION HANDLING, signals delivered to the process can be caught and handled with Pure's exception handling facilities. Like stack checks, checks for pending signals are only performed at certain places, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-05 22:58:05
|
Revision: 722 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=722&view=rev Author: agraef Date: 2008-09-05 22:58:16 +0000 (Fri, 05 Sep 2008) Log Message: ----------- Bugfixes. Modified Paths: -------------- pure/trunk/printer.cc Modified: pure/trunk/printer.cc =================================================================== --- pure/trunk/printer.cc 2008-09-05 22:57:51 UTC (rev 721) +++ pure/trunk/printer.cc 2008-09-05 22:58:16 UTC (rev 722) @@ -624,22 +624,42 @@ static inline bool pstr(ostream& os, pure_expr *x) { + static bool recursive = false; + if (recursive) return false; interpreter& interp = *interpreter::g_interp; int32_t f = interp.symtab.__show__sym; if (f > 0 && interp.globenv.find(f) != interp.globenv.end()) { assert(x->refc > 0); - pure_expr *y = pure_app(pure_symbol(f), x); - assert(y); - if (y->tag == EXPR::STR) { - char *s = fromutf8(y->data.s); - pure_freenew(y); - if (s) { - os << s; free(s); - return true; + pure_exception ex; ex.e = 0; ex.sz = interp.sstk_sz; + interp.estk.push_front(ex); + if (setjmp(interp.estk.front().jmp)) { + // caught an exception + size_t sz = interp.estk.front().sz; + pure_expr* e = interp.estk.front().e; + interp.estk.pop_front(); + if (e) pure_freenew(e); + for (size_t i = interp.sstk_sz; i-- > sz; ) + if (interp.sstk[i] && interp.sstk[i]->refc > 0) + pure_free(interp.sstk[i]); + interp.sstk_sz = sz; + return false; + } else { + recursive = true; + pure_expr *y = pure_app(pure_symbol(f), x); + interp.estk.pop_front(); + recursive = false; + assert(y); + if (y->tag == EXPR::STR) { + char *s = fromutf8(y->data.s); + pure_freenew(y); + if (s) { + os << s; free(s); + return true; + } else + return false; } else return false; - } else - return false; + } } else return false; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-09-05 22:57:40
|
Revision: 721 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=721&view=rev Author: agraef Date: 2008-09-05 22:57:51 +0000 (Fri, 05 Sep 2008) Log Message: ----------- Update documentation. Modified Paths: -------------- pure/trunk/pure.1.in Modified: pure/trunk/pure.1.in =================================================================== --- pure/trunk/pure.1.in 2008-09-05 14:12:15 UTC (rev 720) +++ pure/trunk/pure.1.in 2008-09-05 22:57:51 UTC (rev 721) @@ -1813,6 +1813,86 @@ [1,2,6,24,120,720,5040,40320,362880,3628800] .fi .PP +.B Print syntax. +As indicated, in interactive mode the normal forms of toplevel expressions are +printed after each expression is entered. We also call this the +.I read-eval-print +loop. Normal form expressions are usually printed in the same form as you'd +enter them. However, there are a few special kinds of objects like closures +(anonymous and local functions), thunks (``lazy'' values to be evaluated when +needed) and pointers which don't have a textual representation in the Pure +syntax and will be printed in the format +.BR "#<\fIobject description\fP>" . +.PP +The interpreter provides a ``hook'' to override the print representations of +expressions at runtime by means of the +.B __show__ +function. This is just an ordinary Pure function expected to return a string +with the desired custom representation of a normal form value given as the +function's single argument. __show__ is not defined by default, so you are +free to add any rules that you want. The interpreter prints the strings +returned by __show__ just as they are. It will +.I not +check whether they conform to Pure syntax and/or semantics, or modify them in +any way. +.PP +Custom print representations are most useful for interactive purposes, when +you're not happy with the default print syntax of some kinds of objects, or if +you just want to change the format of numeric values. Here are some examples: +.sp +.nf +> \fBusing\fP system; +> __show__ x::double = sprintf "%0.6f" x; +> 1/7; +0.142857 +> __show__ x::int = sprintf "0x%0x" x; +> 1786; +0x6fa +> \fBusing\fP math; +> __show__ (x::double+:y::double) = sprintf "%0.6f+%0.6fi" (x,y); +> cis (-pi); +-1.000000+0.000000i +.fi +.PP +The prelude function +.BR str , +which returns the print representation of any Pure expression, uses __show__ +as well: +.sp +.nf +> str (1/7); +"0.142857" +.fi +.PP +However, the str function always returns just the default representation of an +expression if it is invoked through __show__. This prevents __show__ from +going recursive, and allows you to define your custom representation in terms +of the default one. E.g., the following rule removes the `L' suffixes from +bigint values: +.sp +.nf +> __show__ x::bigint = init (str x); +> fact n = foldl (*) 1L (1..n); +> fact 30; +265252859812191058636308480000000 +.fi +.PP +By just purging the definition of the __show__ function you can easily go back +to the standard print syntax: +.sp +.nf +> \fBclear\fP __show__ +> 1/7; 1786; cis (-pi); +0.142857142857143 +1786 +-1.0+:1.22460635382238e-16 +> str (1/7); +"0.142857142857143" +> fact 30; +265252859812191058636308480000000L +.fi +.PP +.B Interactive commands. When running interactively, the interpreter also accepts a number of special commands useful for interactive purposes. Here is a quick rundown of the currently supported operations: @@ -1899,9 +1979,9 @@ Note that these special commands are only recognized at the beginning of the interactive command line (they are not reserved keywords of the Pure language). Thus it's possible to ``escape'' identifiers looking like commands -by entering a space at the start of the line. However, the compiler also warns -you about identifiers which might be mistaken as command names, so that you -can avoid this kind of problem. +by entering a space at the beginning of the line. However, the compiler also +warns you about identifiers which might be mistaken as command names, so that +you can avoid this kind of problem. .PP Some commands which are especially important for effective operation of the interpreter are discussed in more detail in the following sections. @@ -2273,11 +2353,11 @@ and .B when clauses are tacked on to the end of the expression they belong to, which -mimics mathematical notation but may be unfamilar if you're more accustomed to -languages from the Algol/Pascal/C family. If you want to figure out what is -actually going on there, it's usually best to read nested scopes ``in -reverse'' (proceeding from the rightmost/outermost to the leftmost/innermost -clause). +mimics mathematical language but may be unfamilar if you're more accustomed to +programming languages from the Algol/Pascal/C family. If you want to figure +out what is actually going on there, it's usually best to read nested scopes +``in reverse'' (proceeding from the rightmost/outermost to the +leftmost/innermost clause). .PP Also note that since .B with This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |