pure-lang-svn Mailing List for Pure (Page 9)
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-08-30 20:58:34
|
Revision: 670 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=670&view=rev Author: agraef Date: 2008-08-30 20:58:44 +0000 (Sat, 30 Aug 2008) Log Message: ----------- Add sizes of complex types (requires gcc or ISO C99). Modified Paths: -------------- pure/trunk/runtime.cc Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-08-30 20:30:19 UTC (rev 669) +++ pure/trunk/runtime.cc 2008-08-30 20:58:44 UTC (rev 670) @@ -3109,6 +3109,8 @@ cdf(interp, "SIZEOF_LONG", pure_int(sizeof(long))); cdf(interp, "SIZEOF_FLOAT", pure_int(sizeof(float))); cdf(interp, "SIZEOF_DOUBLE", pure_int(sizeof(double))); + cdf(interp, "SIZEOF_COMPLEX_FLOAT", pure_int(sizeof(_Complex float))); + cdf(interp, "SIZEOF_COMPLEX_DOUBLE", pure_int(sizeof(_Complex double))); cdf(interp, "SIZEOF_POINTER", pure_int(sizeof(void*))); // clock cdf(interp, "CLOCKS_PER_SEC", pure_int(CLOCKS_PER_SEC)); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-30 20:30:09
|
Revision: 669 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=669&view=rev Author: agraef Date: 2008-08-30 20:30:19 +0000 (Sat, 30 Aug 2008) Log Message: ----------- Add memory sizes to pure_sys_vars. Modified Paths: -------------- pure/trunk/runtime.cc Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-08-30 20:09:05 UTC (rev 668) +++ pure/trunk/runtime.cc 2008-08-30 20:30:19 UTC (rev 669) @@ -3102,6 +3102,14 @@ df(interp, "stdin", pure_pointer(stdin)); df(interp, "stdout", pure_pointer(stdout)); df(interp, "stderr", pure_pointer(stderr)); + // memory sizes + cdf(interp, "SIZEOF_BYTE", pure_int(1)); + cdf(interp, "SIZEOF_SHORT", pure_int(sizeof(short))); + cdf(interp, "SIZEOF_INT", pure_int(sizeof(int))); + cdf(interp, "SIZEOF_LONG", pure_int(sizeof(long))); + cdf(interp, "SIZEOF_FLOAT", pure_int(sizeof(float))); + cdf(interp, "SIZEOF_DOUBLE", pure_int(sizeof(double))); + cdf(interp, "SIZEOF_POINTER", pure_int(sizeof(void*))); // clock cdf(interp, "CLOCKS_PER_SEC", pure_int(CLOCKS_PER_SEC)); // fnmatch, glob This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-30 20:08:55
|
Revision: 668 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=668&view=rev Author: agraef Date: 2008-08-30 20:09:05 +0000 (Sat, 30 Aug 2008) Log Message: ----------- Add expression pointer operations. Modified Paths: -------------- pure/trunk/runtime.cc pure/trunk/runtime.h Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-08-30 19:51:11 UTC (rev 667) +++ pure/trunk/runtime.cc 2008-08-30 20:09:05 UTC (rev 668) @@ -2571,6 +2571,13 @@ } extern "C" +pure_expr *pointer_get_expr(void *ptr) +{ + pure_expr **p = (pure_expr**)ptr; + return *p; +} + +extern "C" void pointer_put_byte(void *ptr, int32_t x) { uint8_t *p = (uint8_t*)ptr; @@ -2605,6 +2612,13 @@ *p = x; } +extern "C" +void pointer_put_expr(void *ptr, pure_expr *x) +{ + pure_expr **p = (pure_expr**)ptr; + *p = x; +} + #include <errno.h> extern "C" Modified: pure/trunk/runtime.h =================================================================== --- pure/trunk/runtime.h 2008-08-30 19:51:11 UTC (rev 667) +++ pure/trunk/runtime.h 2008-08-30 20:09:05 UTC (rev 668) @@ -553,12 +553,14 @@ double pointer_get_double(void *ptr); char *pointer_get_string(void *ptr); void *pointer_get_pointer(void *ptr); +pure_expr *pointer_get_expr(void *ptr); void pointer_put_byte(void *ptr, int32_t x); void pointer_put_int(void *ptr, int32_t x); void pointer_put_double(void *ptr, double x); void pointer_put_string(void *ptr, const char *x); void pointer_put_pointer(void *ptr, void *x); +void pointer_put_expr(void *ptr, pure_expr *x); /* Initialize a bunch of variables with useful system constants. */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-30 19:51:01
|
Revision: 667 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=667&view=rev Author: agraef Date: 2008-08-30 19:51:11 +0000 (Sat, 30 Aug 2008) Log Message: ----------- Cosmetic changes. Modified Paths: -------------- pure/trunk/lib/primitives.pure Modified: pure/trunk/lib/primitives.pure =================================================================== --- pure/trunk/lib/primitives.pure 2008-08-30 19:37:11 UTC (rev 666) +++ pure/trunk/lib/primitives.pure 2008-08-30 19:51:11 UTC (rev 667) @@ -23,17 +23,6 @@ extern void pure_throw(expr*) = throw; // IMPURE! -/* Sentries. These are expression "guards" which are applied to the target - expression when it is garbage-collected. The sentry function places a - sentry at an expression (and returns the modified expression), clear_sentry - removes, get_sentry returns it. NOTE: In the current implementation - sentries can only be placed at applications and pointer objects. The sentry - itself can be any type of object (but usually it's a function). */ - -extern expr* pure_sentry(expr*,expr*) = sentry; // IMPURE! -extern expr* pure_clear_sentry(expr*) = clear_sentry; // IMPURE! -extern expr* pure_get_sentry(expr*) = get_sentry; - /* Syntactic equality. */ extern bool same(expr* x, expr* y); @@ -424,3 +413,14 @@ put_string x::pointer y::string = pointer_put_string x y; put_pointer x::pointer y::string = pointer_put_pointer x y; put_pointer x::pointer y::pointer = pointer_put_pointer x y; + +/* Sentries. These are expression "guards" which are applied to the target + expression when it is garbage-collected. The sentry function places a + sentry at an expression (and returns the modified expression), clear_sentry + removes, get_sentry returns it. NOTE: In the current implementation + sentries can only be placed at applications and pointer objects. The sentry + itself can be any type of object (but usually it's a function). */ + +extern expr* pure_sentry(expr*,expr*) = sentry; // IMPURE! +extern expr* pure_clear_sentry(expr*) = clear_sentry; // IMPURE! +extern expr* pure_get_sentry(expr*) = get_sentry; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-30 19:37:01
|
Revision: 666 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=666&view=rev Author: agraef Date: 2008-08-30 19:37:11 +0000 (Sat, 30 Aug 2008) Log Message: ----------- Bugfixes. Modified Paths: -------------- pure/trunk/lib/system.pure Modified: pure/trunk/lib/system.pure =================================================================== --- pure/trunk/lib/system.pure 2008-08-30 19:16:04 UTC (rev 665) +++ pure/trunk/lib/system.pure 2008-08-30 19:37:11 UTC (rev 666) @@ -252,14 +252,14 @@ "p", x::string | "p", x::pointer = pure_fprintf_pointer fp s x; _ = throw (printf_value_error s arg); end; - count = if res>=0 then count+res else throw printf_error res; + count = if res>=0 then count+res else throw (printf_error res); end; do_fprintf fp (count,args) (printf_format_str s) = count, args when res = pure_fprintf fp s; - count = if res>=0 then count+res else throw printf_error res; + count = if res>=0 then count+res else throw (printf_error res); end; - do_fprintf fp (count,_) _ = throw printf_arg_error; + do_fprintf fp (count,_) _ = throw (this_cant_happen count); end; printf_split_format format = regexg analyze @@ -319,16 +319,16 @@ _ = free buf $$ throw (printf_value_error s arg); end; u = if res>=0 then u + cstring buf - else free buf $$ throw printf_error res; + else free buf $$ throw (printf_error res); end; do_sprintf (u,args) (printf_format_str s) = u, args when size = #s+1000; buf = check_buf (malloc size); res = pure_snprintf buf size s; u = if res>=0 then u + cstring buf - else free buf $$ throw printf_error res; + else free buf $$ throw (printf_error res); end; - do_sprintf (u,_) _ = throw printf_arg_error; + do_sprintf (u,_) _ = throw (this_cant_happen u); check_buf buf = throw malloc_error if null buf; = buf otherwise; end; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-30 19:15:54
|
Revision: 665 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=665&view=rev Author: agraef Date: 2008-08-30 19:16:04 +0000 (Sat, 30 Aug 2008) Log Message: ----------- Add malloc_error symbol. Modified Paths: -------------- pure/trunk/lib/prelude.pure pure/trunk/lib/system.pure Modified: pure/trunk/lib/prelude.pure =================================================================== --- pure/trunk/lib/prelude.pure 2008-08-30 02:20:55 UTC (rev 664) +++ pure/trunk/lib/prelude.pure 2008-08-30 19:16:04 UTC (rev 665) @@ -34,6 +34,7 @@ In particular, the 'bad_list_value' exception is raised by functions which need to work from the end of a list towards its front. */ +nullary malloc_error; // memory allocation error nullary out_of_bounds; // tuple or list index is out of bounds (!) // bad_list_value xs; // not a proper list value (reverse, etc.) // xs denotes the offending tail of the list Modified: pure/trunk/lib/system.pure =================================================================== --- pure/trunk/lib/system.pure 2008-08-30 02:20:55 UTC (rev 664) +++ pure/trunk/lib/system.pure 2008-08-30 19:16:04 UTC (rev 665) @@ -329,7 +329,7 @@ else free buf $$ throw printf_error res; end; do_sprintf (u,_) _ = throw printf_arg_error; - check_buf buf = throw printf_malloc_error if null buf; + check_buf buf = throw malloc_error if null buf; = buf otherwise; end; @@ -400,7 +400,7 @@ ret = if res>=0 then ret else throw (scanf_error ret); end; do_fscanf _ (_,ret) _ = throw (this_cant_happen ret); - check_buf buf = throw scanf_malloc_error if null buf; + check_buf buf = throw malloc_error if null buf; = buf otherwise; // Compute a reasonable size for a string buffer; if necessary, modify the // field width of the format accordingly. @@ -495,7 +495,7 @@ u = drop res u; end; do_sscanf (_,_,ret) _ = throw (this_cant_happen ret); - check_buf buf = throw scanf_malloc_error if null buf; + check_buf buf = throw malloc_error if null buf; = buf otherwise; // Compute a reasonable size for a string buffer; if necessary, modify the // field width of the format accordingly. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-30 02:20:46
|
Revision: 664 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=664&view=rev Author: agraef Date: 2008-08-30 02:20:55 +0000 (Sat, 30 Aug 2008) Log Message: ----------- Update version number. Modified Paths: -------------- pure/trunk/INSTALL Modified: pure/trunk/INSTALL =================================================================== --- pure/trunk/INSTALL 2008-08-30 02:18:01 UTC (rev 663) +++ pure/trunk/INSTALL 2008-08-30 02:20:55 UTC (rev 664) @@ -76,7 +76,7 @@ section. STEP 5. Configure, build and install Pure as follows (x.y denotes the current -Pure version number, 0.5 at the time of this writing): +Pure version number, 0.6 at the time of this writing): $ cd pure-x.y $ ./configure @@ -114,10 +114,10 @@ Run Pure interactively as: $ pure -Pure 0.5 (i686-pc-linux-gnu) Copyright (c) 2008 by Albert Graef +Pure 0.6 (i686-pc-linux-gnu) Copyright (c) 2008 by Albert Graef This program is free software distributed under the GNU Public License (GPL V3 or later). Please see the COPYING file for details. -Loaded prelude from /usr/local/lib/pure-0.5/prelude.pure. +Loaded prelude from /usr/local/lib/pure-0.6/prelude.pure. Check that it works: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-30 02:17:51
|
Revision: 663 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=663&view=rev Author: agraef Date: 2008-08-30 02:18:01 +0000 (Sat, 30 Aug 2008) Log Message: ----------- Cosmetic change in startup message. Modified Paths: -------------- pure/trunk/pure.cc Modified: pure/trunk/pure.cc =================================================================== --- pure/trunk/pure.cc 2008-08-30 02:14:01 UTC (rev 662) +++ pure/trunk/pure.cc 2008-08-30 02:18:01 UTC (rev 663) @@ -406,7 +406,8 @@ cout << "Pure " << PACKAGE_VERSION << " (" << HOST << ") " << COPYRIGHT << endl << LICENSE; if (have_prelude) - cout << "Loaded prelude from " << prelude << ".\n\n"; + cout << "Loaded prelude from " << prelude << ".\n"; + cout << endl; } interp.compile(); interp.ttymode = true; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-30 02:13:51
|
Revision: 662 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=662&view=rev Author: agraef Date: 2008-08-30 02:14:01 +0000 (Sat, 30 Aug 2008) Log Message: ----------- Fix formatting glitch. Modified Paths: -------------- pure/trunk/pure.1.in Modified: pure/trunk/pure.1.in =================================================================== --- pure/trunk/pure.1.in 2008-08-30 01:33:10 UTC (rev 661) +++ pure/trunk/pure.1.in 2008-08-30 02:14:01 UTC (rev 662) @@ -955,8 +955,8 @@ .sp .nf > \fBusing\fP system; -> f = [printf "%g\n" (2^x+1); x=1..5; x mod 2]; -> g = void [printf "%g\n" (2^x+1); x=1..5; x mod 2]; +> f = [printf "%g\en" (2^x+1); x=1..5; x mod 2]; +> g = void [printf "%g\en" (2^x+1); x=1..5; x mod 2]; > \fBlist\fP f g f = catmap (\ex -> if x mod 2 then [printf "%g\n" (2^x+1)] else []) (1..5); g = do (\ex -> if x mod 2 then [printf "%g\n" (2^x+1)] else []) (1..5); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-30 01:32:59
|
Revision: 661 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=661&view=rev Author: agraef Date: 2008-08-30 01:33:10 +0000 (Sat, 30 Aug 2008) Log Message: ----------- Update test logs. Modified Paths: -------------- pure/trunk/test/prelude.log pure/trunk/test/test020.log Modified: pure/trunk/test/prelude.log =================================================================== --- pure/trunk/test/prelude.log 2008-08-30 01:28:49 UTC (rev 660) +++ pure/trunk/test/prelude.log 2008-08-30 01:33:10 UTC (rev 661) @@ -11,6 +11,7 @@ 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*/; 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*/); +def void (catmap f/*0:101*/ x/*0:11*/) = do f/*0:101*/ x/*0:11*/; (x/*0:0101*/=>v/*0:011*/)==(y/*0:101*/=>w/*0:11*/) = if x/*0:0101*/==y/*0:101*/ then v/*0:011*/==w/*0:11*/ else 0; (x/*0:0101*/=>v/*0:011*/)!=(y/*0:101*/=>w/*0:11*/) = if x/*0:0101*/!=y/*0:101*/ then 1 else v/*0:011*/!=w/*0:11*/; x/*0:01*/,() = x/*0:01*/; Modified: pure/trunk/test/test020.log =================================================================== --- pure/trunk/test/test020.log 2008-08-30 01:28:49 UTC (rev 660) +++ pure/trunk/test/test020.log 2008-08-30 01:33:10 UTC (rev 661) @@ -51,7 +51,7 @@ show (x/*0:101*/+:y/*0:11*/) = show x/*0:101*/+"+:"+show y/*0:11*/; show (x/*0:101*/<:y/*0:11*/) = show x/*0:101*/+"<:"+show y/*0:11*/; show x/*0:1*/ = str x/*0:1*/; -tests = puts "*** UNARY ***"$$void (catmap (\f/*0:*/ -> catmap (\x/*0:*/ -> [test (f/*1:*/,x/*0:*/)] { +tests = puts "*** UNARY ***"$$do (\f/*0:*/ -> catmap (\x/*0:*/ -> [test (f/*1:*/,x/*0:*/)] { rule #0: x = [test (f,x)] state 0: #0 <var> state 1 @@ -61,7 +61,7 @@ state 0: #0 <var> state 1 state 1: #0 -}) f)$$puts "*** BINARY ***"$$void (catmap (\f/*0:*/ -> catmap (\x/*0:*/ -> [test (f/*1:*/,x/*0:*/)] { +}) f$$puts "*** BINARY ***"$$do (\f/*0:*/ -> catmap (\x/*0:*/ -> [test (f/*1:*/,x/*0:*/)] { rule #0: x = [test (f,x)] state 0: #0 <var> state 1 @@ -71,7 +71,7 @@ state 0: #0 <var> state 1 state 1: #0 -}) f2); +}) f2; { rule #0: check _ z = z if numberp z rule #1: check (f,x,y) (g@_ u v) = __failed__ if f===g&&x===u&&y===v @@ -285,7 +285,7 @@ state 15: #4 #5 } { - rule #0: tests = puts "*** UNARY ***"$$void (catmap (\f -> catmap (\x -> [test (f,x)]) x) f)$$puts "*** BINARY ***"$$void (catmap (\f -> catmap (\x -> [test (f,x)]) x2) f2) + rule #0: tests = puts "*** UNARY ***"$$do (\f -> catmap (\x -> [test (f,x)]) x) f$$puts "*** BINARY ***"$$do (\f -> catmap (\x -> [test (f,x)]) x2) f2 state 0: #0 } *** UNARY *** This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-30 01:28:39
|
Revision: 660 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=660&view=rev Author: agraef Date: 2008-08-30 01:28:49 +0000 (Sat, 30 Aug 2008) Log Message: ----------- runtime.cc needs to have PURELIB defined. Modified Paths: -------------- pure/trunk/Makefile.in Modified: pure/trunk/Makefile.in =================================================================== --- pure/trunk/Makefile.in 2008-08-29 22:22:12 UTC (rev 659) +++ pure/trunk/Makefile.in 2008-08-30 01:28:49 UTC (rev 660) @@ -138,6 +138,9 @@ pure.o: pure.cc $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LLVM_FLAGS) -DPURELIB='"$(libdir)/pure-$(version)"' -c -o $@ $< +runtime.o: runtime.cc + $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LLVM_FLAGS) -DPURELIB='"$(libdir)/pure-$(version)"' -c -o $@ $< + interpreter.o: interpreter.cc $(CXX) $(CXXFLAGS) $(PIC) $(CPPFLAGS) $(LLVM_FLAGS) $(AUXLIBS) -c -o $@ $< This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-29 22:22:02
|
Revision: 659 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=659&view=rev Author: agraef Date: 2008-08-29 22:22:12 +0000 (Fri, 29 Aug 2008) Log Message: ----------- Update documentation. Modified Paths: -------------- pure/trunk/pure.1.in Modified: pure/trunk/pure.1.in =================================================================== --- pure/trunk/pure.1.in 2008-08-29 21:08:59 UTC (rev 658) +++ pure/trunk/pure.1.in 2008-08-29 22:22:12 UTC (rev 659) @@ -51,6 +51,15 @@ convenient, fully interactive environment for running Pure scripts and evaluating expressions. .PP +Pure programs (a.k.a. +.IR scripts ) +are just ordinary text files containing Pure code. A bunch of syntax +highlighting files and programming modes for various popular text editors are +included in the Pure sources. There's no difference between the Pure +programming language and the input language accepted by the interpreter, +except that the interpreter also understands some special commands when +running in interactive mode; see the INTERACTIVE USAGE section for details. +.PP If any source scripts are specified on the command line, they are loaded and executed, after which the interpreter exits. Otherwise the interpreter enters the interactive read-eval-print loop. You can also use the @@ -64,9 +73,9 @@ 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 in section INTERACTIVE USAGE -below, as well as for symbols defined in the running program) and, when -exiting the interpreter, the command history is stored in +(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 .BR ~/.pure_history , from where it is restored the next time you run the interpreter. .PP This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-29 21:08:52
|
Revision: 658 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=658&view=rev Author: agraef Date: 2008-08-29 21:08:59 +0000 (Fri, 29 Aug 2008) Log Message: ----------- Added Eddie Rucker's syntax highlighting for gedit. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/README pure/trunk/lib/prelude.pure Added Paths: ----------- pure/trunk/etc/gpure.lang Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-08-29 14:55:53 UTC (rev 657) +++ pure/trunk/ChangeLog 2008-08-29 21:08:59 UTC (rev 658) @@ -1,3 +1,8 @@ +2008-08-29 Albert Graef <Dr....@t-...> + + * etc/gpure.lang: Added syntax highlighting for gedit. Contributed + by Eddie Rucker. + 2008-08-28 Albert Graef <Dr....@t-...> * lib/system.pure: New definitions of fopen/popen and Modified: pure/trunk/README =================================================================== --- pure/trunk/README 2008-08-29 14:55:53 UTC (rev 657) +++ pure/trunk/README 2008-08-29 21:08:59 UTC (rev 658) @@ -69,8 +69,8 @@ Pure scripts are just ordinary text files, which can be created with any text editor. The distribution contains some language definition files and programming modes to provide syntax highlighting in various popular text -editors, such as Emacs, Kate and Vim. The Emacs mode also lets you run the -Pure interpreter in an Emacs buffer, this is probably the most convenient +editors, such as Emacs, Gedit, Kate and Vim. The Emacs mode also lets you run +the Pure interpreter in an Emacs buffer, this is probably the most convenient interface to the interpreter if you're friends with Emacs. A syntax file for Andre Simon's highlight program is also included, this lets you pretty-print Pure source in various output formats such as HTML and LaTeX. You can find all Added: pure/trunk/etc/gpure.lang =================================================================== --- pure/trunk/etc/gpure.lang (rev 0) +++ pure/trunk/etc/gpure.lang 2008-08-29 21:08:59 UTC (rev 658) @@ -0,0 +1,181 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Pure syntax highlighting for gedit. Usage: + + - Rename this file to 'pure.lang' and copy it to the + /usr/share/gtksourceview-2.0/language-specs directory. + + - You may also want to add a text/x-pure or text/x-puresrc mime type for + *.pure files so that your file manager can recognize them. + + - Fire up gedit on your Pure script and enjoy the syntax highlighting. + + Author: Eddie Rucker (mostly pilfered from Marco Barision and + Emanuela Aina's Ada and C packages) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + +--> +<language id="pure" _name="Pure" version="2.0" _section="Sources"> + <metadata> + <property name="mimetypes">text/x-pure;text/x-puresrc</property> + <property name="globs">*.pure</property> + <property name="line-comment-start">//</property> + <property name="block-comment-start">/*</property> + <property name="block-comment-end">*/</property> + </metadata> + + <styles> + <style id="comment" _name="Comment" map-to="def:comment"/> + <style id="string" _name="String" map-to="def:string"/> + <style id="keyword" _name="Keyword" map-to="def:keyword"/> + <style id="storage-class" _name="Storage Class" map-to="def:type"/> + <style id="type" _name="Data Type" map-to="def:type"/> + <style id="preprocessor" _name="Preprocessor" map-to="def:preprocessor"/> + <style id="double" _name="Double" map-to="def:floating-point"/> + <style id="hexadecimal" _name="Hexadecimal number" map-to="def:base-n-integer"/> + <style id="octal" _name="Octal" map-to="def:base-n-integer"/> + <style id="int" _name="Integer" map-to="def:decimal"/> + <style id="escaped-character" _name="Escaped Character" map-to="def:special-char"/> + </styles> + + <default-regex-options case-sensitive="true"/> + + <definitions> + + <context id="line-comment" style-ref="comment" end-at-line-end="true"> + <start>//</start> + <include> + <context ref="def:in-line-comment"/> + </include> + </context> + + <context id="comment-multiline" style-ref="comment"> + <start>/\*</start> + <end>\*/</end> + <include> + <context ref="def:in-comment"/> + </include> + </context> + + <context id="string" style-ref="string" end-at-line-end="true"> + <start>"</start> + <end>"</end> + <include> + <context id="string-esc" style-ref="escaped-character" extend-parent="true"> + <match>""</match> + </context> + </include> + </context> + + <context id="preprocessor-keyword" style-ref="preprocessor"> + <keyword>def</keyword> + </context> + + <context id="keyword" style-ref="keyword"> + <keyword>case</keyword> + <keyword>when</keyword> + <keyword>with</keyword> + <keyword>end</keyword> + <keyword>else</keyword> + <keyword>if</keyword> + <keyword>infix</keyword> + <keyword>infixl</keyword> + <keyword>infixr</keyword> + <keyword>let</keyword> + <keyword>nullary</keyword> + <keyword>of</keyword> + <keyword>otherwise</keyword> + <keyword>prefix</keyword> + <keyword>postfix</keyword> + <keyword>then</keyword> + <keyword>catch</keyword> + <keyword>throw</keyword> + </context> + + <context id="storage-class" style-ref="storage-class"> + <keyword>const</keyword> + <keyword>private</keyword> + <keyword>extern</keyword> + <keyword>using</keyword> + </context> + + <context id="type" style-ref="type"> + <keyword>char</keyword> + <keyword>bool</keyword> + <keyword>float</keyword> + <keyword>int</keyword> + <keyword>double</keyword> + <keyword>expr</keyword> + <keyword>short</keyword> + <keyword>long</keyword> + <keyword>void</keyword> + <keyword>string</keyword> + <keyword>pointer</keyword> + </context> + + <!-- http://www.lysator.liu.se/c/ANSI-C-grammar-l.html --> + <context id="double" style-ref="double"> + <match extended="true"> + (?<![\w\.]) + ((\.[0-9]+ | [0-9]+\.[0-9]*) ([Ee][+-]?[0-9]*)?) + (?![\w\.]) + </match> + </context> + + <context id="hexadecimal" style-ref="hexadecimal"> + <match extended="true"> + (?<![\w\.]) + 0[xX][a-fA-F0-9]+L? + (?![\w\.]) + </match> + </context> + + <context id="octal" style-ref="octal"> + <match extended="true"> + (?<![\w\.]) + 0[0-7]+L? + (?![\w\.]) + </match> + </context> + + <context id="int" style-ref="int"> + <match extended="true"> + (?<![\w\.]) + [0-9]+L? + (?![\w\.]) + </match> + </context> + + <context id="pure"> + <include> + <context ref="line-comment"/> + <context ref="comment-multiline"/> + <context ref="string"/> + <context ref="preprocessor-keyword"/> + <context ref="keyword"/> + <context ref="storage-class"/> + <context ref="type"/> + <context ref="double"/> + <context ref="hexadecimal"/> + <context ref="octal"/> + <context ref="int"/> + </include> + </context> + + </definitions> +</language> Modified: pure/trunk/lib/prelude.pure =================================================================== --- pure/trunk/lib/prelude.pure 2008-08-29 14:55:53 UTC (rev 657) +++ pure/trunk/lib/prelude.pure 2008-08-29 21:08:59 UTC (rev 658) @@ -97,9 +97,9 @@ def f $ x = f x; def (f . g) x = f (g x); -/* The following rule is always valid and optimizes the case of list - comprehensions with throwaway results (useful if a list comprehension is - evaluated solely for its side effects). */ +/* The following rule is always valid and optimizes the case of "throwaway" + list comprehensions (useful if a list comprehension is evaluated solely for + its side effects). */ def void (catmap f x) = do f x; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-29 14:55:43
|
Revision: 657 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=657&view=rev Author: agraef Date: 2008-08-29 14:55:53 +0000 (Fri, 29 Aug 2008) Log Message: ----------- Update documentation. Modified Paths: -------------- pure/trunk/pure.1.in Modified: pure/trunk/pure.1.in =================================================================== --- pure/trunk/pure.1.in 2008-08-29 09:31:43 UTC (rev 656) +++ pure/trunk/pure.1.in 2008-08-29 14:55:53 UTC (rev 657) @@ -458,12 +458,14 @@ and .BR case , followed by conditional expressions (\fBif\fP-\fBthen\fP-\fBelse\fP), followed -by the ``simple'' expressions (i.e., all other kinds of expressions involving -operators, function applications, constants, symbols and other primary -expressions). Precedence and associativity of operator symbols are given by -their declarations (in the prelude or the user's program), and function -application binds stronger than all operators. Parentheses can be used to -override default precedences and associativities as usual. +by the +.IR "simple expressions" , +i.e., all other kinds of expressions involving operators, function +applications, constants, symbols and other primary expressions. Precedence and +associativity of operator symbols are given by their declarations (in the +prelude or the user's program), and function application binds stronger than +all operators. Parentheses can be used to override default precedences and +associativities as usual. .PP The common operator symbols like +, -, *, / etc. are all declared at the beginning of the prelude, see the @@ -513,10 +515,13 @@ and expressions to be evaluated: .TP .B Rules: \fIlhs\fR = \fIrhs\fR; -The basic form can also be augmented with a condition \fBif\fP\ \fIguard\fP -tacked on to the end of the rule (which restricts the applicability of the -rule to the case that the guard evaluates to a nonzero integer), or the -keyword +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 +kind of Pure expression described above). In some cases, this basic form can +also be augmented with a condition \fBif\fP\ \fIguard\fP tacked on to the end +of the rule (which restricts the applicability of the rule to the case that +the guard evaluates to a nonzero integer), or the keyword .B otherwise denoting an empty guard which is always true (this is nothing but syntactic sugar to point out the ``default'' case of a definition; the interpreter just @@ -532,7 +537,7 @@ function. No guards or multiple left-hand and right-hand sides are permitted here. Macro rules are used to preprocess expressions on the right-hand side of other definitions at compile time, and are typically employed to implement -user-defined special forms and simple kinds of optimizations rules. See the +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; @@ -759,9 +764,10 @@ is picked. (Again, the \fBwhen\fP construct is treated differently, because each rule is actually a separate definition.) .PP -In any case, the left-hand side pattern must not contain repeated variables -(i.e., rules must be ``left-linear''), except for the anonymous variable `_' -which matches an arbitrary value without binding a variable symbol. +In any case, the left-hand side pattern (which, as already mentioned, is +always a simple expression) must not contain repeated variables (i.e., rules +must be ``left-linear''), except for the anonymous variable `_' which matches +an arbitrary value without binding a variable symbol. .PP A left-hand side variable (including the anonymous variable) may be followed by one of the special type tags \fB::int\fP, \fB::bigint\fP, \fB::double\fP, @@ -855,7 +861,13 @@ .SH MACROS Macros are a special type of functions to be executed as a kind of ``preprocessing stage'' at compile time. In Pure these are typically used to -define custom special forms and to perform inlining of simple function calls. +define custom special forms, and to perform inlining of function calls and +other simple kinds of source-level optimizations. In the following, these are +also referred to as +.I convenience +and +.IR "optimization macros" , +respectively. .PP Whereas the macro facilities of most programming languages simply provide a kind of textual substitution mechanism, Pure macros operate on symbolic @@ -881,6 +893,7 @@ calls in macro arguments are expanded before the macro gets applied to its parameters). .PP +.B 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: @@ -892,50 +905,96 @@ foo x::int = x+1+1; .fi .PP -Rules like these can be useful to help the compiler generate better -code. E.g., try the following interactive command to have a look at the -assembler code for the above `foo' function (\fIwarning:\fP this is not for -the faint at heart): +Rules like these can be useful to help the compiler generate better code. Note +that a macro may have the same name as an ordinary Pure function, which is +essential if you want to optimize calls to an existing function, as in the +previous example. +.PP +A somewhat more practical example is the following rule from the prelude, +which eliminates saturated instances of the right-associative function +application operator: .sp .nf -> \fBlist\fP -d foo +\fBdef\fP f $ x = f x; .fi .PP -You'll see that (ignoring the function header and the boilerplate code for -boxing and unboxing Pure expressions generated by the compiler) it essentially -boils down to just a single integer increment instruction: +Like in Haskell, this low-priority operator is handy to write cascading +function calls. With the above macro rule, these will be ``inlined'' as +ordinary function applications automagically. Example: .sp .nf - ... - %intval = load i32* %1 ; <i32> [#uses=1] - add i32 %intval, 2 ; <i32>:2 [#uses=1] - ... +> foo x = bar $ bar $ 2*x; +> \fBlist\fP foo +foo x = bar (bar (2*x)); .fi .PP -Note that a macro may have the same name as an ordinary Pure function, which -is useful for optimizing calls to an existing function, as shown in the -example above. As a somewhat more practical example, since Pure 0.6 the -following rule has been added to the prelude to eliminate saturated instances -of the right-associative function application operator: +Here is slightly more tricky rule from the prelude, which optimizes the case +of ``throwaway'' list comprehensions. This is useful if a list comprehension +is evaluated solely for its side effects. .sp .nf -\fBdef\fP f $ x = f x; +\fBdef\fP void (catmap f x) = do f x; .fi +.PP +Note that the `void' function simply throws away its argument and returns () +instead. The `do' function applies a function to every member of a list (like +`map'), but throws away all intermediate results and just returns (), which is +much more efficient if you don't need those results anyway. These are both +defined in the prelude. +.PP +Let's see how this rule transforms a list comprehension if we ``voidify'' it: .sp -Like in Haskell, this low-priority operator is handy to write cascading -function calls. With the above macro rule, these will be ``inlined'' as -ordinary function applications automagically. Example: +.nf +> \fBusing\fP system; +> f = [printf "%g\n" (2^x+1); x=1..5; x mod 2]; +> g = void [printf "%g\n" (2^x+1); x=1..5; x mod 2]; +> \fBlist\fP f g +f = catmap (\ex -> if x mod 2 then [printf "%g\n" (2^x+1)] else []) (1..5); +g = do (\ex -> if x mod 2 then [printf "%g\n" (2^x+1)] else []) (1..5); +.fi +.PP +Ok, so the `catmap' got replaced with a `do' which is just what we need to +make this code go essentially as fast as a `for' loop in conventional +programming languages (up to constant factors, of course). Here's how it looks +like when we run the `g' function: .sp .nf -> foo x = bar $ bar $ 2*x; -> \fBlist\fP foo -foo x = bar (bar (2*x)); +> g; +3 +9 +33 +() .fi .PP -Macros can also be recursive, consist of multiple rules and make use of -pattern-matching like ordinary function definitions. Example: +It's not all roses, however, since the above macro rule will only get rid of +the outermost `catmap' if the list comprehension binds multiple variables: .sp .nf +> u = void [puts $ str (x,y); x=1..2; y=1..3]; +> \fBlist\fP u +u = do (\ex -> catmap (\ey -> [puts (str (x,y))]) (1..3)) (1..2); +.fi +.PP +If you're bothered by this, you'll have to apply `void' recursively, creating +a nested list comprehension which expands to a nested `do': +.sp +.nf +> v = void [void [puts $ str (x,y); y=1..3]; x=1..2]; +> \fBlist\fP v +v = do (\ex -> [do (\ey -> [puts (str (x,y))]) (1..3)]) (1..2); +.fi +.PP +(It would be nice to have this handled automatically, but the left-hand side +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. +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: +.sp +.nf > \fBdef\fP foo (bar x) = foo x+1; > \fBdef\fP foo x = x; > baz = foo (bar (bar (bar x))); @@ -943,17 +1002,29 @@ baz = x+1+1+1; .fi .PP -Note that, whereas the right-hand side of a constant definition really gets -evaluated to a normal form at the time the definition is processed, the only -things that get evaluated during macro substitution are other macros. The -right-hand side may be an arbitrary Pure expression involving conditional -expressions, lambdas, binding clauses, etc., but these are +Note that, technically, Pure macros are just as powerful as (unconditional) +term rewriting systems and thus they are Turing-complete. This implies that a +badly written macro may well send the Pure compiler into an infinite +recursion, which results in a stack overflow at compile time. See the CAVEATS +AND NOTES section at the end of this manual for information on how to deal +with these by setting the +.B PURE_STACK +environment variable. +.PP +.B 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 +built-in special forms and other constructs which defer their evaluation. In +fact, the right-hand side of a macro rule may be an arbitrary Pure expression +involving conditional expressions, lambdas, binding clauses, etc. These are .I not evaluated during macro substitution, they just become part of the macro -expansion (after substituting the macro parameters). For instance, here is a -useful little macro `timex', which employs the system function `clock' to -report the cpu time in seconds needed to evaluate a given expression, along -with the computed result: +expansion (after substituting the macro parameters). +.PP +Our definition of `timex' employs the system function `clock' to report the +cpu time in seconds needed to evaluate a given expression, along with the +computed result: .sp .nf > \fBusing\fP system; @@ -963,19 +1034,16 @@ 0.43,5000050000L .fi .PP -The `timex' macro also provides a useful example of how you can use macros to -define your own special forms, since the macro arguments will only be -evaluated at runtime and can thus be passed to built-in special forms and -other constructs which defer their evaluation. (Note that the above definition -of `timex' wouldn't work as an ordinary 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.) +(Note that the above definition of `timex' wouldn't work as an ordinary +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 -Finally, note that 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 as +.B 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 +as .B with and .B when @@ -985,13 +1053,11 @@ macros. They are not susceptible to so-called ``name capture,'' which makes macros in less sophisticated languages bug-ridden and hard to use. .PP -Despite their simplicity and ease of use, Pure's macros are an incredibly -powerful feature. But with power comes responsibility. If over-used, or used -in inappropriate ways, macros can make your code incromprehensible and -bloated, and a buggy macro may well kick the Pure compiler into an endless -loop (usually resulting in a stack overflow at compile time). In other words, -macros are a good way to shoot yourself in the foot. So use them thoughtfully -and with care. +Pure macros also have their limitations. Specifically, the left-hand side of a +macro rule must be a simple expression, just like in ordinary function +definitions. This restricts the kinds of expressions which can be rewritten by +a macro. But Pure macros are certainly powerful enough for most common +preprocessing purposes, while still being robust and easy to use. .SH DECLARATIONS Pure is a very terse language by design; you don't declare much stuff, you just define it and be done with it. Usually, all necessary information about @@ -1899,6 +1965,47 @@ the anonymous ``as'' pattern trick is a small price to pay for that convenience. .PP +Sometimes you may also run into the complementary problem, i.e., to match a +function argument against a given function. Consider this code fragment: +.sp +.nf +foo x = x+1; +foop f = \fBcase\fP f \fBof\fP foo = 1; _ = 0 \fBend\fP; +.fi +.PP +You might expect `foop' to return true for `foo', and false on all other +values. Better think again, because in reality `foop' will +.I always +return true! In fact, the Pure compiler will warn you about the second rule +of the +.B case +expression not being used at all: +.sp +.nf +> foop 99; +warning: rule never reduced: _ = 0; +1 +.fi +.PP +This happens because a non-nullary symbol on the left-hand side of a rule, +which is not the head symbol of a function application, is always considered +to be a variable, even if that symbol is defined as a global function +elsewhere. So `foo' isn't a literal name in the above +.B case +expression, it's a variable! (As a matter of fact, this is rather useful, +since otherwise a rule like `f g = g+1' would suddenly change meaning if you +happen to add a definition like `g x = x-1' somewhere else in your program, +which certainly isn't desirable.) +.PP +Fortunately, the syntactic equality operator `===' defined in the prelude +comes to the rescue here. Just define `foop' as follows: +.sp +.nf +> foop f = f===foo; +> foop foo, foop 99; +1,0 +.fi +.PP .B With or when? A common source of confusion for Haskellers is that Pure provides two different constructs to bind local function and variable symbols, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-29 09:31:33
|
Revision: 656 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=656&view=rev Author: agraef Date: 2008-08-29 09:31:43 +0000 (Fri, 29 Aug 2008) Log Message: ----------- Add a void-catmap macro rule to optimize the case of list comprehensions with throwaway results. Modified Paths: -------------- pure/trunk/lib/prelude.pure Modified: pure/trunk/lib/prelude.pure =================================================================== --- pure/trunk/lib/prelude.pure 2008-08-28 15:24:05 UTC (rev 655) +++ pure/trunk/lib/prelude.pure 2008-08-29 09:31:43 UTC (rev 656) @@ -97,6 +97,12 @@ def f $ x = f x; def (f . g) x = f (g x); +/* The following rule is always valid and optimizes the case of list + comprehensions with throwaway results (useful if a list comprehension is + evaluated solely for its side effects). */ + +def void (catmap f x) = do f x; + /* "Mapsto" operator. This constructor is declared here so that it can be used in other standard library modules to denote special kinds of pairs which map keys to values. Here we only define equality of such pairs. */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-28 15:23:55
|
Revision: 655 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=655&view=rev Author: agraef Date: 2008-08-28 15:24:05 +0000 (Thu, 28 Aug 2008) Log Message: ----------- Simplify definitions of fclose/pclose. Modified Paths: -------------- pure/trunk/lib/system.pure Modified: pure/trunk/lib/system.pure =================================================================== --- pure/trunk/lib/system.pure 2008-08-28 12:03:49 UTC (rev 654) +++ pure/trunk/lib/system.pure 2008-08-28 15:24:05 UTC (rev 655) @@ -174,15 +174,11 @@ /* Pure wrappers for fopen/popen and fclose/pclose which take care of closing a file object automagically when it's garbage-collected. */ -fopen name::string mode::string = check (c_fopen name mode) with - check fp::pointer = sentry c_fclose fp if not null fp; - check fp = fp otherwise; -end; +fopen name::string mode::string = if null fp then fp else sentry c_fclose fp +when fp = c_fopen name mode end; -popen name::string mode::string = check (c_popen name mode) with - check fp::pointer = sentry c_pclose fp if not null fp; - check fp = fp otherwise; -end; +popen name::string mode::string = if null fp then fp else sentry c_pclose fp +when fp = c_popen name mode end; fclose fp::pointer = clear_sentry fp $$ c_fclose fp; pclose fp::pointer = clear_sentry fp $$ c_pclose fp; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-28 12:03:40
|
Revision: 654 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=654&view=rev Author: agraef Date: 2008-08-28 12:03:49 +0000 (Thu, 28 Aug 2008) Log Message: ----------- fopen/popen now take care of closing a file object when it's garbage-collected. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/lib/system.pure Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-08-28 11:38:47 UTC (rev 653) +++ pure/trunk/ChangeLog 2008-08-28 12:03:49 UTC (rev 654) @@ -1,5 +1,9 @@ 2008-08-28 Albert Graef <Dr....@t-...> + * lib/system.pure: New definitions of fopen/popen and + fclose/pclose, using sentries which take care of closing a file + object automagically when it's garbage-collected. + * lib/primitives.pure: Add interface to sentries (see below). * runtime.cc/h: Added sentries -- expression "guards" which are Modified: pure/trunk/lib/system.pure =================================================================== --- pure/trunk/lib/system.pure 2008-08-28 11:38:47 UTC (rev 653) +++ pure/trunk/lib/system.pure 2008-08-28 12:03:49 UTC (rev 654) @@ -157,10 +157,12 @@ routines are actually overridden with more convenient Pure wrappers below. */ +private c_fopen c_popen c_fclose c_pclose; +extern FILE* fopen(char* name, char* mode) = c_fopen; +extern FILE* popen(char* cmd, char* mode) = c_popen; +extern int fclose(FILE* fp) = c_fclose, int pclose(FILE* fp) = c_pclose; +extern int fflush(FILE* fp); private c_fgets c_gets; -extern FILE* fopen(char* name, char* mode); -extern FILE* popen(char* cmd, char* mode); -extern int fflush(FILE* fp), int fclose(FILE* fp), int pclose(FILE* fp); extern char* fgets(void* buf, int size, FILE* fp) = c_fgets; extern char* gets(void* buf) = c_gets; extern int fputs(char* s, FILE* fp), int puts(char* s); @@ -169,6 +171,22 @@ extern void clearerr(FILE* fp); extern int feof(FILE* fp), int ferror(FILE* fp); +/* Pure wrappers for fopen/popen and fclose/pclose which take care of closing + a file object automagically when it's garbage-collected. */ + +fopen name::string mode::string = check (c_fopen name mode) with + check fp::pointer = sentry c_fclose fp if not null fp; + check fp = fp otherwise; +end; + +popen name::string mode::string = check (c_popen name mode) with + check fp::pointer = sentry c_pclose fp if not null fp; + check fp = fp otherwise; +end; + +fclose fp::pointer = clear_sentry fp $$ c_fclose fp; +pclose fp::pointer = clear_sentry fp $$ c_pclose fp; + /* Pure wrappers for fgets and gets which handle the necessary buffering automatically. */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-28 11:38:39
|
Revision: 653 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=653&view=rev Author: agraef Date: 2008-08-28 11:38:47 +0000 (Thu, 28 Aug 2008) Log Message: ----------- Add interface to sentries. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/lib/primitives.pure Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-08-28 11:27:46 UTC (rev 652) +++ pure/trunk/ChangeLog 2008-08-28 11:38:47 UTC (rev 653) @@ -1,5 +1,7 @@ 2008-08-28 Albert Graef <Dr....@t-...> + * lib/primitives.pure: Add interface to sentries (see below). + * runtime.cc/h: Added sentries -- expression "guards" which are applied to the target expression when it is garbage-collected. Only sentries on applications and pointer objects are supported Modified: pure/trunk/lib/primitives.pure =================================================================== --- pure/trunk/lib/primitives.pure 2008-08-28 11:27:46 UTC (rev 652) +++ pure/trunk/lib/primitives.pure 2008-08-28 11:38:47 UTC (rev 653) @@ -23,6 +23,17 @@ extern void pure_throw(expr*) = throw; // IMPURE! +/* Sentries. These are expression "guards" which are applied to the target + expression when it is garbage-collected. The sentry function places a + sentry at an expression (and returns the modified expression), clear_sentry + removes, get_sentry returns it. NOTE: In the current implementation + sentries can only be placed at applications and pointer objects. The sentry + itself can be any type of object (but usually it's a function). */ + +extern expr* pure_sentry(expr*,expr*) = sentry; // IMPURE! +extern expr* pure_clear_sentry(expr*) = clear_sentry; // IMPURE! +extern expr* pure_get_sentry(expr*) = get_sentry; + /* Syntactic equality. */ extern bool same(expr* x, expr* y); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-28 11:27:37
|
Revision: 652 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=652&view=rev Author: agraef Date: 2008-08-28 11:27:46 +0000 (Thu, 28 Aug 2008) Log Message: ----------- Remove assert convenience function, it's not really worth having trivial stuff like that in the prelude. Modified Paths: -------------- pure/trunk/lib/primitives.pure Modified: pure/trunk/lib/primitives.pure =================================================================== --- pure/trunk/lib/primitives.pure 2008-08-28 11:25:58 UTC (rev 651) +++ pure/trunk/lib/primitives.pure 2008-08-28 11:27:46 UTC (rev 652) @@ -23,11 +23,6 @@ extern void pure_throw(expr*) = throw; // IMPURE! -/* Convenience function to ensure a condition p. Returns 1 (true) if p holds, - and throws the given exception e otherwise. */ - -assert p e = if p then 1 else throw e; - /* Syntactic equality. */ extern bool same(expr* x, expr* y); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-28 11:25:49
|
Revision: 651 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=651&view=rev Author: agraef Date: 2008-08-28 11:25:58 +0000 (Thu, 28 Aug 2008) Log Message: ----------- Moved definition of NULL to primitives.pure. Modified Paths: -------------- pure/trunk/interpreter.cc pure/trunk/lib/primitives.pure Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-08-28 11:22:17 UTC (rev 650) +++ pure/trunk/interpreter.cc 2008-08-28 11:25:58 UTC (rev 651) @@ -337,8 +337,6 @@ defn("argv", args); defn("version", pure_cstring_dup(version.c_str())); defn("sysinfo", pure_cstring_dup(host.c_str())); - // null pointer - const_defn("NULL", pure_pointer(0)); } // Errors and warnings. Modified: pure/trunk/lib/primitives.pure =================================================================== --- pure/trunk/lib/primitives.pure 2008-08-28 11:22:17 UTC (rev 650) +++ pure/trunk/lib/primitives.pure 2008-08-28 11:25:58 UTC (rev 651) @@ -373,6 +373,8 @@ /* Pointer arithmetic. We do this using bigints, so that the code is portable to 64 bit systems. */ +const NULL = pointer 0; // the null pointer + null x::pointer = bigint x==0; x::pointer-y::pointer = bigint x-bigint y; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-28 11:22:07
|
Revision: 650 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=650&view=rev Author: agraef Date: 2008-08-28 11:22:17 +0000 (Thu, 28 Aug 2008) Log Message: ----------- Moved definition of NULL to interpreter initialization. Modified Paths: -------------- pure/trunk/interpreter.cc pure/trunk/runtime.cc Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-08-28 11:16:52 UTC (rev 649) +++ pure/trunk/interpreter.cc 2008-08-28 11:22:17 UTC (rev 650) @@ -337,6 +337,8 @@ defn("argv", args); defn("version", pure_cstring_dup(version.c_str())); defn("sysinfo", pure_cstring_dup(host.c_str())); + // null pointer + const_defn("NULL", pure_pointer(0)); } // Errors and warnings. Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-08-28 11:16:52 UTC (rev 649) +++ pure/trunk/runtime.cc 2008-08-28 11:22:17 UTC (rev 650) @@ -3088,8 +3088,6 @@ df(interp, "stdin", pure_pointer(stdin)); df(interp, "stdout", pure_pointer(stdout)); df(interp, "stderr", pure_pointer(stderr)); - // null pointer - cdf(interp, "NULL", pure_pointer(0)); // clock cdf(interp, "CLOCKS_PER_SEC", pure_int(CLOCKS_PER_SEC)); // fnmatch, glob This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-28 11:16:45
|
Revision: 649 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=649&view=rev Author: agraef Date: 2008-08-28 11:16:52 +0000 (Thu, 28 Aug 2008) Log Message: ----------- Added sentries a.k.a. expression guards. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/runtime.cc pure/trunk/runtime.h Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-08-28 08:39:27 UTC (rev 648) +++ pure/trunk/ChangeLog 2008-08-28 11:16:52 UTC (rev 649) @@ -1,5 +1,10 @@ 2008-08-28 Albert Graef <Dr....@t-...> + * runtime.cc/h: Added sentries -- expression "guards" which are + applied to the target expression when it is garbage-collected. + Only sentries on applications and pointer objects are supported + right now. + * Makefile.in: Set LC_ALL=C, to work around failed math tests due to locale-related problems on some systems. Note: This requires a reconfigure. Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-08-28 08:39:27 UTC (rev 648) +++ pure/trunk/runtime.cc 2008-08-28 11:16:52 UTC (rev 649) @@ -102,6 +102,50 @@ #define SSTK_DEBUG 0 #endif +static inline pure_expr* pure_apply2(pure_expr *x, pure_expr *y) +{ + // Count references and construct a function application. + pure_new_args(2, x, y); + return pure_apply(x, y); +} + +static inline pure_expr* signal_exception(int sig) +{ + if (!interpreter::g_interp) return 0; + pure_expr *f = pure_const(interpreter::g_interp->symtab.signal_sym().f); + pure_expr *x = pure_int(sig); + return pure_apply2(f, x); +} + +static inline pure_expr* stack_exception() +{ + if (!interpreter::g_interp) return 0; + return pure_const(interpreter::g_interp->symtab.segfault_sym().f); +} + +static inline pure_expr *get_sentry(pure_expr *x) +{ + if (x==0) + return 0; + else if (x->tag == EXPR::APP || x->tag == EXPR::PTR) + return x->data.x[2]; + else + return 0; +} + +static inline void free_sentry(pure_expr *x) +{ + if (x->tag == EXPR::APP || x->tag == EXPR::PTR) { + pure_expr *s = x->data.x[2]; + if (s) { + ++x->refc; + pure_freenew(pure_apply2(s, x)); + pure_free(s); + --x->refc; + } + } +} + // Expression pointers are allocated in larger chunks for better performance. // NOTE: Only internal fields get initialized by new_expr(), the remaining // fields *must* be initialized as appropriate by the caller. @@ -123,6 +167,7 @@ } x->refc = 0; x->xp = interp.tmps; + x->data.x[2] = 0; // initialize the sentry interp.tmps = x; return x; } @@ -197,6 +242,7 @@ pure_expr *xp = 0, *y; loop: if (--x->refc == 0) { + free_sentry(x); switch (x->tag) { case EXPR::APP: y = x->data.x[0]; @@ -242,6 +288,7 @@ void pure_free_internal(pure_expr *x) { if (--x->refc == 0) { + free_sentry(x); switch (x->tag) { case EXPR::APP: pure_free_internal(x->data.x[0]); @@ -287,27 +334,6 @@ } } -static inline pure_expr* pure_apply2(pure_expr *x, pure_expr *y) -{ - // Count references and construct a function application. - pure_new_args(2, x, y); - return pure_apply(x, y); -} - -static inline pure_expr* signal_exception(int sig) -{ - if (!interpreter::g_interp) return 0; - pure_expr *f = pure_const(interpreter::g_interp->symtab.signal_sym().f); - pure_expr *x = pure_int(sig); - return pure_apply2(f, x); -} - -static inline pure_expr* stack_exception() -{ - if (!interpreter::g_interp) return 0; - return pure_const(interpreter::g_interp->symtab.segfault_sym().f); -} - /* PUBLIC API. **************************************************************/ extern "C" @@ -812,6 +838,32 @@ } extern "C" +pure_expr *pure_sentry(pure_expr *sentry, pure_expr *x) +{ + if (x==0) + return 0; + else if (x->tag == EXPR::APP || x->tag == EXPR::PTR) { + if (x->data.x[2]) + pure_free_internal(x->data.x[2]); + x->data.x[2] = sentry?pure_new_internal(sentry):0; + return x; + } else + return 0; +} + +extern "C" +pure_expr *pure_get_sentry(pure_expr *x) +{ + return get_sentry(x); +} + +extern "C" +pure_expr *pure_clear_sentry(pure_expr *x) +{ + return pure_sentry(0, x); +} + +extern "C" bool pure_let(int32_t sym, pure_expr *x) { if (sym <= 0 || !x) return false; Modified: pure/trunk/runtime.h =================================================================== --- pure/trunk/runtime.h 2008-08-28 08:39:27 UTC (rev 648) +++ pure/trunk/runtime.h 2008-08-28 11:16:52 UTC (rev 649) @@ -38,7 +38,7 @@ int32_t tag; // type tag or symbol, see expr.hh for possible values uint32_t refc; // reference counter union { - struct _pure_expr *x[2]; // application arguments (EXPR::APP) + struct _pure_expr *x[3]; // application arguments (EXPR::APP), sentry int32_t i; // integer (EXPR::INT) mpz_t z; // GMP bigint (EXPR::BIGINT) double d; // double (EXPR::DBL) @@ -217,6 +217,20 @@ void pure_ref(pure_expr *x); void pure_unref(pure_expr *x); +/* Sentries. These are expression "guards" which are applied to the target + expression when it is garbage-collected. pure_sentry places a sentry at an + expression (or removes it if sentry is NULL) and returns the modified + expression, pure_get_sentry returns the current sentry of an expression, if + any (NULL otherwise). pure_clear_sentry(x) is a convenience function for + pure_sentry(NULL, x). NOTE: In the current implementation sentries can only + be placed at applications and pointer objects, pure_sentry will return NULL + if you apply it to other kinds of expressions. The sentry itself can be any + type of object (but usually it's a function). */ + +pure_expr *pure_sentry(pure_expr *sentry, pure_expr *x); +pure_expr *pure_get_sentry(pure_expr *x); +pure_expr *pure_clear_sentry(pure_expr *x); + /* Variable and constant definitions. These allow you to directly bind variable and constant symbols to pure_expr* values, as the 'let' and 'def' constructs do in the Pure language. The functions return true if This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-28 08:39:17
|
Revision: 648 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=648&view=rev Author: agraef Date: 2008-08-28 08:39:27 +0000 (Thu, 28 Aug 2008) Log Message: ----------- Work around failed math tests due to locale-related problems on some systems. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/Makefile.in Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-08-28 08:14:15 UTC (rev 647) +++ pure/trunk/ChangeLog 2008-08-28 08:39:27 UTC (rev 648) @@ -1,5 +1,9 @@ 2008-08-28 Albert Graef <Dr....@t-...> + * Makefile.in: Set LC_ALL=C, to work around failed math tests due + to locale-related problems on some systems. Note: This requires a + reconfigure. + * lib/system.pure: Add setlocale function. * runtime.cc (pure_sys_vars): Add NULL and LC_* constants. Modified: pure/trunk/Makefile.in =================================================================== --- pure/trunk/Makefile.in 2008-08-28 08:14:15 UTC (rev 647) +++ pure/trunk/Makefile.in 2008-08-28 08:39:27 UTC (rev 648) @@ -259,16 +259,21 @@ cleanlogs: rm -f $(srcdir)/test/*.log +# Note: Unfortunately, a few tests may produce varying results with different +# locales, so we have to make sure that we set up a neutral environment +# here. We therefore set LC_ALL=C below, which should do the job on Linux and +# other glibc-based systems. Other systems might require some work. + $(srcdir)/test/prelude.log: lib/prelude.pure lib/primitives.pure lib/strings.pure - @LD_LIB_PATH@=. PURELIB=$(srcdir)/lib ./pure -n -v$(level) $< > $@ 2>&1 + LC_ALL=C @LD_LIB_PATH@=. PURELIB=$(srcdir)/lib ./pure -n -v$(level) $< > $@ 2>&1 %.log: %.pure - @LD_LIB_PATH@=. PURELIB=$(srcdir)/lib ./pure -v$(level) < $< > $@ 2>&1 + LC_ALL=C @LD_LIB_PATH@=. PURELIB=$(srcdir)/lib ./pure -v$(level) < $< > $@ 2>&1 check: pure @ echo Running tests. - @ (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 @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 -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) # 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-08-28 08:14:05
|
Revision: 647 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=647&view=rev Author: agraef Date: 2008-08-28 08:14:15 +0000 (Thu, 28 Aug 2008) Log Message: ----------- Add setlocale function. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/lib/system.pure Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-08-28 06:55:34 UTC (rev 646) +++ pure/trunk/ChangeLog 2008-08-28 08:14:15 UTC (rev 647) @@ -1,5 +1,7 @@ 2008-08-28 Albert Graef <Dr....@t-...> + * lib/system.pure: Add setlocale function. + * runtime.cc (pure_sys_vars): Add NULL and LC_* constants. * lexer.ll: Add option -p to list only private/public symbols to Modified: pure/trunk/lib/system.pure =================================================================== --- pure/trunk/lib/system.pure 2008-08-28 06:55:34 UTC (rev 646) +++ pure/trunk/lib/system.pure 2008-08-28 08:14:15 UTC (rev 647) @@ -45,6 +45,40 @@ extern int pure_errno() = errno, void pure_set_errno(int) = set_errno; extern void perror(char*), char* strerror(int); +/* POSIX locale handling. Details are platform-specific, but you can expect + that at least the categories LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, + LC_NUMERIC and LC_TIME are defined, as well as the following values for the + locale parameter: "C" or "POSIX" (the default POSIX locale), "" (the system + default locale), and NULL, to just query the current locale. + + Other string values which can be passed as the locale argument depend on + the implementation, please check your local setlocale(3) documentation for + details. If locale is not NULL, the current locale is changed accordingly. + The return value is the new locale, or the current locale when passing NULL + for the locale parameter. In either case, the string returned by setlocale + is such that it can be passed to setlocale to restore the same locale + again. In case of an error, setlocale returns a null pointer. + + Please note that calling this function alters the Pure interpreter's idea + of what the current locale is, which will affect the expected encoding of + subsequently loaded scripts, among other things. When the interpreter + starts up, it always sets the default system locale. Unless your scripts + rely on a specific encoding, setting the locale to either "C" or "" should + always be safe. */ + +private c_setlocale; +extern void* setlocale(int category, void* locale) = c_setlocale; + +setlocale category::int locale = +return (check (c_setlocale category buf)) with + check res = cstring_dup res if not null res; + = res otherwise; + return res = free buf $$ res if not null buf; + = res otherwise; +end when + buf = if stringp locale then byte_cstring locale else locale; +end if stringp locale || pointerp locale && null locale; + /* Signal handling. The action parameter of 'trap' can be one of the predefined integer values SIG_TRAP, SIG_IGN and SIG_DFL. SIG_TRAP causes the given signal to be handled by mapping it to a Pure exception of the This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-28 06:55:24
|
Revision: 646 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=646&view=rev Author: agraef Date: 2008-08-28 06:55:34 +0000 (Thu, 28 Aug 2008) Log Message: ----------- Add NULL and LC_* constants. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/runtime.cc Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-08-28 00:03:19 UTC (rev 645) +++ pure/trunk/ChangeLog 2008-08-28 06:55:34 UTC (rev 646) @@ -1,5 +1,7 @@ 2008-08-28 Albert Graef <Dr....@t-...> + * runtime.cc (pure_sys_vars): Add NULL and LC_* constants. + * lexer.ll: Add option -p to list only private/public symbols to the 'list' command. Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-08-28 00:03:19 UTC (rev 645) +++ pure/trunk/runtime.cc 2008-08-28 06:55:34 UTC (rev 646) @@ -27,6 +27,7 @@ #include <stdarg.h> #include <unistd.h> #include <limits.h> +#include <locale.h> #include <iostream> #include <sstream> @@ -3035,6 +3036,8 @@ df(interp, "stdin", pure_pointer(stdin)); df(interp, "stdout", pure_pointer(stdout)); df(interp, "stderr", pure_pointer(stderr)); + // null pointer + cdf(interp, "NULL", pure_pointer(0)); // clock cdf(interp, "CLOCKS_PER_SEC", pure_int(CLOCKS_PER_SEC)); // fnmatch, glob @@ -3140,4 +3143,26 @@ #ifdef SIGTTOU cdf(interp, "SIGTTOU", pure_int(SIGTTOU)); #endif + // setlocale +#ifdef LC_ALL + cdf(interp, "LC_ALL", pure_int(LC_ALL)); +#endif +#ifdef LC_COLLATE + cdf(interp, "LC_COLLATE", pure_int(LC_COLLATE)); +#endif +#ifdef LC_CTYPE + cdf(interp, "LC_CTYPE", pure_int(LC_CTYPE)); +#endif +#ifdef LC_MESSAGES + cdf(interp, "LC_MESSAGES", pure_int(LC_MESSAGES)); +#endif +#ifdef LC_MONETARY + cdf(interp, "LC_MONETARY", pure_int(LC_MONETARY)); +#endif +#ifdef LC_NUMERIC + cdf(interp, "LC_NUMERIC", pure_int(LC_NUMERIC)); +#endif +#ifdef LC_TIME + cdf(interp, "LC_TIME", pure_int(LC_TIME)); +#endif } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |