pure-lang-svn Mailing List for Pure (Page 16)
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-14 13:03:13
|
Revision: 495 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=495&view=rev Author: agraef Date: 2008-08-14 13:03:22 +0000 (Thu, 14 Aug 2008) Log Message: ----------- Updated ChangeLog. Modified Paths: -------------- pure/trunk/ChangeLog Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-08-14 12:52:47 UTC (rev 494) +++ pure/trunk/ChangeLog 2008-08-14 13:03:22 UTC (rev 495) @@ -1,5 +1,11 @@ 2008-08-14 Albert Graef <Dr....@t-...> + * lib/math.pure: Bugfixes, overhaul of number predicates, added + missing semantic number predicates. + + * runtime.cc (pure_bigintval, same): Fix up bigint conversions and + syntactic comparisons of doubles for the inf/nan cases. + * lib/primitives.pure, runtime.cc/h: Removed obsolete fun and arg functions, as 'arg' conflicted with math.pure. Also, applp is now implemented directly in Pure, and the corresponding runtime This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-14 12:52:37
|
Revision: 494 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=494&view=rev Author: agraef Date: 2008-08-14 12:52:47 +0000 (Thu, 14 Aug 2008) Log Message: ----------- Add inf/nan cases of double->bigint conversions and syntactic comparisons. Modified Paths: -------------- pure/trunk/runtime.cc Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-08-14 12:30:15 UTC (rev 493) +++ pure/trunk/runtime.cc 2008-08-14 12:52:47 UTC (rev 494) @@ -1820,6 +1820,9 @@ return pointer_to_bigint(x->data.p); else if (x->tag != EXPR::INT && x->tag != EXPR::DBL) return 0; + else if (x->tag == EXPR::DBL && + (is_nan(x->data.d) || is_nan(x->data.d-x->data.d))) + pure_sigfpe(); pure_expr *y = pure_bigint(0, 0); mpz_t& z = y->data.z; if (x->tag == EXPR::INT) @@ -2361,7 +2364,7 @@ case EXPR::BIGINT: return mpz_cmp(x->data.z, y->data.z) == 0; case EXPR::DBL: - return x->data.d == y->data.d; + return x->data.d == y->data.d || is_nan(x->data.d) && is_nan(y->data.d); case EXPR::STR: return strcmp(x->data.s, y->data.s) == 0; case EXPR::PTR: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-14 12:30:06
|
Revision: 493 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=493&view=rev Author: agraef Date: 2008-08-14 12:30:15 +0000 (Thu, 14 Aug 2008) Log Message: ----------- Bugfixes in num/den and number predicates. Modified Paths: -------------- pure/trunk/lib/math.pure Modified: pure/trunk/lib/math.pure =================================================================== --- pure/trunk/lib/math.pure 2008-08-14 12:22:54 UTC (rev 492) +++ pure/trunk/lib/math.pure 2008-08-14 12:30:15 UTC (rev 493) @@ -443,10 +443,12 @@ den (x%y) = y; num x::int | -num x::bigint = x; +num x::bigint = bigint x; +num x::double = if frac x==0.0 then bigint x else num (rational x); den x::int | -den x::bigint = 1; +den x::bigint = 1L; +den x::double = if frac x==0.0 then 1L else den (rational x); /* Absolute value and sign. */ @@ -577,9 +579,9 @@ compvalp x = numberp x; realvalp x = compvalp x && im x==0; -ratvalp x = realvalp x && (y-y!==nan when y = re x end); -bigintvalp x = ratvalp x && den x==1; -intvalp x = bigintvalp && int x==x; +ratvalp x = realvalp x && re (x-x)!==nan; +bigintvalp x = ratvalp x && den (re x)==1; +intvalp x = bigintvalp x && int (re x)==x; /* Check whether a number is exact (i.e., doesn't contain any double components. */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-14 12:22:44
|
Revision: 492 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=492&view=rev Author: agraef Date: 2008-08-14 12:22:54 +0000 (Thu, 14 Aug 2008) Log Message: ----------- Overhaul of number predicates. Modified Paths: -------------- pure/trunk/lib/math.pure Modified: pure/trunk/lib/math.pure =================================================================== --- pure/trunk/lib/math.pure 2008-08-14 07:59:36 UTC (rev 491) +++ pure/trunk/lib/math.pure 2008-08-14 12:22:54 UTC (rev 492) @@ -563,13 +563,33 @@ /* Additional number predicates. */ complexp x = case x of x+:y | x<:y = realp x && realp y; _ = 0 end; -rationalp x = case x of x%y = bigintp x && bigintp y; _ = 0 end; -realp x = intp x || bigintp x || doublep x || rationalp x; +realp x = case x of _::int | _::bigint | _::double | + _::bigint%_::bigint = 1; _ = 0 end; +rationalp x = case x of _::bigint%_::bigint = 1; _ = 0 end; numberp x = realp x || complexp x; -inexactp x = doublep x || doublep (re x) || doublep (im x) if numberp x; -exactp x = not(doublep x || doublep (re x) || doublep (im x)) - if numberp x; +/* Semantic number predicates. In difference to the syntactic predicates in + primitives.pure and above, these check whether the given value can be + represented as an object of the given target type (up to rounding + errors). Note that if x is of syntactic type X, then it is also of semantic + type X. Moreover, intvalp x => bigintvalp x => ratvalp x => realvalp x => + compvalp x <=> numberp x. */ -infp x::double = not nanp x && nanp (x-x); -nanp x::double = x===nan; +compvalp x = numberp x; +realvalp x = compvalp x && im x==0; +ratvalp x = realvalp x && (y-y!==nan when y = re x end); +bigintvalp x = ratvalp x && den x==1; +intvalp x = bigintvalp && int x==x; + +/* Check whether a number is exact (i.e., doesn't contain any double + components. */ + +exactp x = numberp x && + not (doublep x || doublep (re x) || doublep (im x)); +inexactp x = numberp x && + (doublep x || doublep (re x) || doublep (im x)); + +/* Check for inf and nan values. */ + +infp x = case x of x::double = x!==nan && x-x===nan; _ = 0 end; +nanp x = case x of x::double = x===nan; _ = 0 end; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-14 07:59:26
|
Revision: 491 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=491&view=rev Author: agraef Date: 2008-08-14 07:59:36 +0000 (Thu, 14 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-14 07:58:03 UTC (rev 490) +++ pure/trunk/pure.1.in 2008-08-14 07:59:36 UTC (rev 491) @@ -1330,8 +1330,7 @@ symbols). On the other hand, generic rules operating on arbitrary function applications are not all that common, so having to ``escape'' a variable using the anonymous ``as'' pattern trick is a small price to pay for that -convenience. Moreover, the prelude also provides operations to recognize and -decompose function applications. +convenience. .PP .B Constant and variable definitions. Defined constants (symbols bound with \fBdef\fP) are somewhat limited in scope This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-14 07:57:53
|
Revision: 490 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=490&view=rev Author: agraef Date: 2008-08-14 07:58:03 +0000 (Thu, 14 Aug 2008) Log Message: ----------- Removed obsolete fun and arg functions. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/lib/primitives.pure pure/trunk/runtime.cc pure/trunk/runtime.h Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-08-14 07:30:45 UTC (rev 489) +++ pure/trunk/ChangeLog 2008-08-14 07:58:03 UTC (rev 490) @@ -1,3 +1,10 @@ +2008-08-14 Albert Graef <Dr....@t-...> + + * lib/primitives.pure, runtime.cc/h: Removed obsolete fun and arg + functions, as 'arg' conflicted with math.pure. Also, applp is now + implemented directly in Pure, and the corresponding runtime + routine has been removed as well. + 2008-08-13 Albert Graef <Dr....@t-...> * interpreter.cc (declare_extern, named_type, type_name): Add Modified: pure/trunk/lib/primitives.pure =================================================================== --- pure/trunk/lib/primitives.pure 2008-08-14 07:30:45 UTC (rev 489) +++ pure/trunk/lib/primitives.pure 2008-08-14 07:58:03 UTC (rev 490) @@ -45,9 +45,11 @@ /* Predicates to check for function objects, global (unbound) variables, function applications, proper lists, list nodes and tuples. */ -extern bool funp(expr*), bool lambdap(expr*), bool varp(expr*), - bool applp(expr*); +extern bool funp(expr*), bool lambdap(expr*), bool varp(expr*); +applp (_ _) = 1; +applp _ = 0 otherwise; + listp [] = 1; listp (x:xs) = listp xs; listp _ = 0 otherwise; @@ -60,10 +62,6 @@ tuplep (x,xs) = 1; tuplep _ = 0 otherwise; -/* Operations to return the function and the argument in an application. */ - -extern expr* fun(expr*), expr* arg(expr*); - /* Compute a 32 bit hash code of a Pure expression. */ extern int hash(expr*); Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-08-14 07:30:45 UTC (rev 489) +++ pure/trunk/runtime.cc 2008-08-14 07:58:03 UTC (rev 490) @@ -2391,30 +2391,6 @@ } extern "C" -bool applp(const pure_expr *x) -{ - return (x->tag == EXPR::APP); -} - -extern "C" -pure_expr *fun(const pure_expr *x) -{ - if (x->tag == EXPR::APP) - return x->data.x[0]; - else - return 0; -} - -extern "C" -pure_expr *arg(const pure_expr *x) -{ - if (x->tag == EXPR::APP) - return x->data.x[1]; - else - return 0; -} - -extern "C" int32_t pointer_get_byte(void *ptr) { uint8_t *p = (uint8_t*)ptr; Modified: pure/trunk/runtime.h =================================================================== --- pure/trunk/runtime.h 2008-08-14 07:30:45 UTC (rev 489) +++ pure/trunk/runtime.h 2008-08-14 07:58:03 UTC (rev 490) @@ -531,16 +531,6 @@ bool lambdap(const pure_expr *x); bool varp(const pure_expr *x); -/* Check whether an object is a function application, and return the function - and the argument of an application. Note that these operations can't be - defined in Pure because of the "head is function" rule which means that in - a pattern of the form f x, f is always a literal function symbol and not a - variable. */ - -bool applp(const pure_expr *x); -pure_expr *fun(const pure_expr *x); -pure_expr *arg(const pure_expr *x); - /* Direct memory accesses. */ int32_t pointer_get_byte(void *ptr); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-14 07:30:36
|
Revision: 489 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=489&view=rev Author: agraef Date: 2008-08-14 07:30:45 +0000 (Thu, 14 Aug 2008) Log Message: ----------- Add missing complex functions on rationals. Modified Paths: -------------- pure/trunk/lib/math.pure Modified: pure/trunk/lib/math.pure =================================================================== --- pure/trunk/lib/math.pure 2008-08-14 06:56:25 UTC (rev 488) +++ pure/trunk/lib/math.pure 2008-08-14 07:30:45 UTC (rev 489) @@ -453,6 +453,13 @@ abs (x%y) = abs x % y; sgn (x%y) = sgn x; +/* Complex functions. */ + +arg (x%y) = atan2 0 (x/y); +re x@(_%_) = x; +im (_%_) = 0L%1L; +conj x@(_%_) = x; + /* Rounding functions. These return exact results here. */ floor x@(_%_) = if n<=x then n else n-1 when n::bigint = trunc x end; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-14 06:56:14
|
Revision: 488 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=488&view=rev Author: agraef Date: 2008-08-14 06:56:25 +0000 (Thu, 14 Aug 2008) Log Message: ----------- Comment change. Modified Paths: -------------- pure/trunk/lib/math.pure Modified: pure/trunk/lib/math.pure =================================================================== --- pure/trunk/lib/math.pure 2008-08-14 06:39:38 UTC (rev 487) +++ pure/trunk/lib/math.pure 2008-08-14 06:56:25 UTC (rev 488) @@ -368,11 +368,11 @@ /* The '%' operator returns a rational or complex rational for any combination of integer, rational and complex integer/rational arguments, provided that the denominator is nonzero (otherwise it behaves like x div 0, which will - raise an exception on most systems). Machine int operands are always - promoted to bigints. For other numeric operands '%' works just like '/'. - Rational results are normalized so that the sign is always in the numerator - and numerator and denominator are relatively prime. Hence a rational zero - is always represented as 1L%0L. */ + raise an exception). Machine int operands are always promoted to bigints. + For other numeric operands '%' works just like '/'. Rational results are + normalized so that the sign is always in the numerator and numerator and + denominator are relatively prime. Hence a rational zero is always + represented as 0L%1L. */ x::bigint % 0L = x div 0L; x::bigint % y::bigint = (-x)%(-y) if y<0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-14 06:39:28
|
Revision: 487 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=487&view=rev Author: agraef Date: 2008-08-14 06:39:38 +0000 (Thu, 14 Aug 2008) Log Message: ----------- Comment change. Modified Paths: -------------- pure/trunk/lib/math.pure Modified: pure/trunk/lib/math.pure =================================================================== --- pure/trunk/lib/math.pure 2008-08-13 13:51:40 UTC (rev 486) +++ pure/trunk/lib/math.pure 2008-08-14 06:39:38 UTC (rev 487) @@ -154,7 +154,7 @@ rect x::double = x+:0.0; /* Create complex values on the unit circle. Note: To quickly compute - exp (x+:y) in polar form, use exp x*cis y. */ + exp (x+:y) in polar form, use exp x <: y. */ cis t = rect (1<:t); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-13 13:51:32
|
Revision: 486 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=486&view=rev Author: agraef Date: 2008-08-13 13:51:40 +0000 (Wed, 13 Aug 2008) Log Message: ----------- Add remark concerning predefined operators. Modified Paths: -------------- pure/trunk/pure.1.in Modified: pure/trunk/pure.1.in =================================================================== --- pure/trunk/pure.1.in 2008-08-13 13:25:03 UTC (rev 485) +++ pure/trunk/pure.1.in 2008-08-13 13:51:40 UTC (rev 486) @@ -411,6 +411,24 @@ 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 declared at the beginning +of the prelude, see the +.B prelude.pure +script for a list of these. Arithmetic, relational and logical operators +usually follow C conventions. However, out of necessity some of Pure's +operator symbols deviate from C. Most notably, the `!' symbol is Pure's +indexing operator, hence logical negation is denoted +.B not +instead (named for Haskell compatibility, but Pure's +.B not +is a real prefix operator instead of an ordinary function symbol). Moreover, +the bitwise operators are named +.B and +and +.B or +instead of `&' and `|', because the latter is reserved as a special symbol in +rules, see RULE SYNTAX below. +.PP At the toplevel, a Pure program basically consists of equations defining functions, constant and variable definitions, and expressions to be evaluated. .TP This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-13 13:24:53
|
Revision: 485 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=485&view=rev Author: agraef Date: 2008-08-13 13:25:03 +0000 (Wed, 13 Aug 2008) Log Message: ----------- Cosmetic changes. Modified Paths: -------------- pure/trunk/pure.1.in Modified: pure/trunk/pure.1.in =================================================================== --- pure/trunk/pure.1.in 2008-08-13 13:13:21 UTC (rev 484) +++ pure/trunk/pure.1.in 2008-08-13 13:25:03 UTC (rev 485) @@ -33,7 +33,7 @@ Pure is a modern-style functional programming language based on term rewriting. Pure programs are basically collections of equational rules used to evaluate expressions in a symbolic fashion by reducing them to normal form. A -brief overview of the language can be found in the \fBPURE OVERVIEW\fP section +brief overview of the language can be found in the PURE OVERVIEW section below. (In case you're wondering, the name ``Pure'' actually refers to the adjective. But you can also write it as ``PURE'' and take this as a recursive acronym for the ``Pure Universal Rewriting Engine''.) @@ -58,8 +58,7 @@ 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 -.B INTERACTIVE USAGE +(providing completion for all commands listed in section INTERACTIVE USAGE below, as well as for global function and variable symbols) and, when exiting the interpreter, the command history is stored in .BR ~/.pure_history , @@ -170,8 +169,8 @@ .B using clause. As a remedy, you can use the interactive .B list -command (see the \fBINTERACTIVE USAGE\fP section below) to list definitions -along with additional debugging information. +command (see the INTERACTIVE USAGE section below) to list definitions along +with additional debugging information. .SH PURE OVERVIEW .PP Pure is a fairly simple language. Programs are collections of equational rules @@ -615,8 +614,8 @@ programs consisting of several source modules. These are: operator and constant symbol declarations, .B extern -declarations for external C functions (described in the \fBC INTERFACE\fP -section), and +declarations for external C functions (described in the C INTERFACE section), +and .B using clauses which provide a simple include file mechanism. .TP @@ -667,7 +666,7 @@ environment variable. (The .B using clause also has an alternative form which allows dynamic libraries to be -loaded, this will be discussed in the \fBC INTERFACE\fP section.) +loaded, this will be discussed in the C INTERFACE section.) .SH EXCEPTION HANDLING Pure also offers a useful exception handling facility. To raise an exception, you just invoke the built-in function @@ -959,8 +958,8 @@ 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). -See the \fBDEFINITION LEVELS AND OVERRIDE MODE\fP section below for details. +command (or the beginning of the interactive session). See the DEFINITION +LEVELS AND OVERRIDE MODE section below for details. .TP .B "help \fR[\fIargs\fP]\fP" Display the @@ -970,16 +969,16 @@ with the given arguments. .TP .B "list \fR[\fIoption\fP ...]\fP \fR[\fIsymbol\fP ...]\fP" -List defined symbols in various formats. -See the \fBLIST COMMAND\fP section below for details. +List defined symbols in various formats. See the LIST COMMAND section below +for details. .TP .B "ls \fR[\fIargs\fP]\fP" List files (shell \fBls\fP(1) command). .TP .B override Enter ``override'' mode. This allows you to add equations ``above'' existing -definitions in the source script, possibly overriding existing equations. -See the \fBDEFINITION LEVELS AND OVERRIDE MODE\fP section below for details. +definitions in the source script, possibly overriding existing equations. See +the DEFINITION LEVELS AND OVERRIDE MODE section below for details. .TP .B pwd Print the current working dir (shell \fBpwd\fP(1) command). @@ -1004,8 +1003,8 @@ .B clear command (see above) will purge all definitions made after the most recent .B save -(or the beginning of the interactive session). -See the \fBDEFINITION LEVELS AND OVERRIDE MODE\fP section below for details. +(or the beginning of the interactive session). See the DEFINITION LEVELS AND +OVERRIDE MODE section below for details. .TP .B "stats \fR[on|off]\fP" Enables (default) or disables ``stats'' mode, in which various statistics are @@ -1016,7 +1015,7 @@ .B underride Exits ``override'' mode. This returns you to the normal mode of operation, where new equations are added `below'' previous rules of an existing function. -See the \fBDEFINITION LEVELS AND OVERRIDE MODE\fP section below for details. +See the DEFINITION LEVELS AND OVERRIDE MODE section below for details. .PP Note that these special commands are only recognized at the beginning of the interactive command line. (Thus you can escape a symbol looking like a command @@ -1073,9 +1072,9 @@ 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 temporary definitions, whereas 0 indicates \fIall\fP definitions (which is the -default if \fB-t\fP is not specified). See the \fBDEFINITION LEVELS AND -OVERRIDE MODE\fP section below for information about the notion of temporary -definition levels. +default if \fB-t\fP is not specified). See the DEFINITION LEVELS AND OVERRIDE +MODE section below for information about the notion of temporary definition +levels. .TP .B -v Print information about variable symbols. @@ -1506,16 +1505,16 @@ semantics. .PP .B Handling of asynchronous signals. -As described in section \fBEXCEPTION HANDLING\fP, 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, such as entry into a global function. This doesn't include -tail calls, however, so a busy loop like `loop = loop;' will \fInever\fP be +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, +such as entry into a global function. This doesn't include tail calls, +however, so a busy loop like `loop = loop;' will \fInever\fP be interrupted. To work around this, just add a call to another global function to your loop to make it interruptible. For instance: .sp .nf -loop = loop when _ = check end; +loop = loop \fBwhen\fP _ = check \fBend\fP; check = (); .fi .PP @@ -1526,8 +1525,8 @@ exception handler like the following: .sp .nf -loop = loop when _ = catch handle check end -with handle (signal k) = catch handle (...) end; +loop = loop \fBwhen\fP _ = catch handle check \fBend\fP +\fBwith\fP handle (signal k) = catch handle (...) \fBend\fP; .fi .PP By these means the entire loop remains tail-recursive. (Note the `catch This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-13 13:13:13
|
Revision: 484 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=484&view=rev Author: agraef Date: 2008-08-13 13:13:21 +0000 (Wed, 13 Aug 2008) Log Message: ----------- Mask further asynchronous signals in pure_catch while invoking an exception handler. Modified Paths: -------------- pure/trunk/interpreter.cc pure/trunk/interpreter.hh pure/trunk/runtime.cc Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-08-13 12:43:41 UTC (rev 483) +++ pure/trunk/interpreter.cc 2008-08-13 13:13:21 UTC (rev 484) @@ -21,6 +21,7 @@ int interpreter::stackmax = 0; int interpreter::stackdir = 0; int interpreter::brkflag = 0; +int interpreter::brkmask = 0; static void* resolve_external(const std::string& name) { Modified: pure/trunk/interpreter.hh =================================================================== --- pure/trunk/interpreter.hh 2008-08-13 12:43:41 UTC (rev 483) +++ pure/trunk/interpreter.hh 2008-08-13 13:13:21 UTC (rev 484) @@ -583,7 +583,7 @@ static bool g_interactive; static interpreter* g_interp; // not saved - static int brkflag; + static int brkflag, brkmask; static char *baseptr; static int stackmax; static int stackdir; Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-08-13 12:43:41 UTC (rev 483) +++ pure/trunk/runtime.cc 2008-08-13 13:13:21 UTC (rev 484) @@ -38,12 +38,15 @@ interpreter::stackdir*(&test - interpreter::baseptr) \ >= interpreter::stackmax) \ pure_throw(stack_exception()) -#define checkall(test) if (interpreter::brkflag) \ - pure_throw(signal_exception(interpreter::brkflag)); \ - else if (interpreter::stackmax > 0 && \ +#define checkall(test) if (interpreter::stackmax > 0 && \ interpreter::stackdir*(&test - interpreter::baseptr) \ - >= interpreter::stackmax) \ - pure_throw(stack_exception()) + >= interpreter::stackmax) { \ + interpreter::brkmask = 0; \ + pure_throw(stack_exception()); \ + } else if (interpreter::brkmask) \ + interpreter::brkmask = 0; \ + else if (interpreter::brkflag) \ + pure_throw(signal_exception(interpreter::brkflag)) // Debug expression allocations. Warns about expression memory leaks. // NOTE: Bookkeeping starts and ends at each toplevel pure_invoke call. @@ -1389,6 +1392,8 @@ << "): " << e << endl; #endif pure_free_internal(x); + // mask further breaks until the handler starts executing + interp.brkmask = 1; pure_expr *res = pure_apply(h, e); return res; } else { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-13 12:43:33
|
Revision: 483 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=483&view=rev Author: agraef Date: 2008-08-13 12:43:41 +0000 (Wed, 13 Aug 2008) Log Message: ----------- Simplified signal handler. Modified Paths: -------------- pure/trunk/examples/signal.pure Modified: pure/trunk/examples/signal.pure =================================================================== --- pure/trunk/examples/signal.pure 2008-08-13 12:37:02 UTC (rev 482) +++ pure/trunk/examples/signal.pure 2008-08-13 12:43:41 UTC (rev 483) @@ -19,7 +19,7 @@ loop = loop when _ = catch sig check end with - sig (signal k) = loop when _ = printf "Hey, I got signal %d.\n" k end; + sig (signal k) = printf "Hey, I got signal %d.\n" k; end; /* Take a short nap so that the loop doesn't run busily. This also serves the This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-13 12:36:53
|
Revision: 482 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=482&view=rev Author: agraef Date: 2008-08-13 12:37:02 +0000 (Wed, 13 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-13 09:06:17 UTC (rev 481) +++ pure/trunk/pure.1.in 2008-08-13 12:37:02 UTC (rev 482) @@ -177,7 +177,7 @@ Pure is a fairly simple language. Programs are collections of equational rules defining functions, \fBdef\fP and \fBlet\fP commands binding global constant and variable symbols, and expressions to be evaluated. Here's a simple -example, entered interactively in the interpreter (note that the \fB>\fP +example, entered interactively in the interpreter (note that the ``>'' symbol at the beginning of each input line is the interpreter's default command prompt): .sp @@ -606,6 +606,68 @@ = i1==i2 || j1==j2 || i1+j1==i2+j2 || i1-j1==i2-j2; \fBend\fP; .fi +.SH DECLARATIONS +As you probably noticed, Pure is very terse. That's because, in contrast to +hopelessly verbose languages like Java, you don't declare much stuff in Pure, +you just define it and be done with it. Usually, all necessary information +about the defined symbols is inferred automatically. However, there are a few +toplevel constructs which let you declare special symbol attributes and manage +programs consisting of several source modules. These are: operator and +constant symbol declarations, +.B extern +declarations for external C functions (described in the \fBC INTERFACE\fP +section), and +.B using +clauses which provide a simple include file mechanism. +.TP +.B Operator and constant declarations: infix \fIlevel\fP \fIop\fR ...; +Ten different precedence levels are available for user-defined operators, +numbered 0 (lowest) thru 9 (highest). On each precedence level, you can +declare (in order of increasing precedence) +.BR infix " (binary non-associative)," +.BR infixl " (binary left-associative)," +.BR infixr " (binary right-associative)," +.BR prefix " (unary prefix) and" +.BR postfix " (unary postfix)" +operators. For instance: +.sp +.nf +\fBinfixl\fP 6 + - ; +\fBinfixl\fP 7 * / div mod ; +.fi +.sp +Note that to declare multiple symbols in a single declaration, you just list +them all with whitespace in between. +.sp +Similarly, constant symbols are introduced using a declaration of the form: +.sp +.nf +\fBnullary \fIsymbol\fR ...; +.fi +.sp +Examples for all of these can be found in the prelude which declares a bunch +of standard (arithmetic, relational, logical) operator symbols as well as the +list and pair constructors `:' and `,' and the constant symbols `[]' and `()' +denoting the empty list and tuple, respectively. +.TP +.B Using clause: using \fIname\fR ...; +Causes each given script to be included, at the position of the +.B using +clause, but only if the script was not included already. Note that the +constants, variables and functions defined by the included script are then +available anywhere in the program, not just the module that contains the +.B using +clause. The script name can be specified either as a string denoting the +proper filename (possibly including path and/or filename extension), or as an +identifier. In the latter case, the +.B .pure +filename extension is added automatically. In both cases, the script is +searched for in the current directory and the directory named by the +.B PURELIB +environment variable. (The +.B using +clause also has an alternative form which allows dynamic libraries to be +loaded, this will be discussed in the \fBC INTERFACE\fP section.) .SH EXCEPTION HANDLING Pure also offers a useful exception handling facility. To raise an exception, you just invoke the built-in function @@ -657,9 +719,9 @@ <stdin>:2.0-7: unhandled exception 'failed_cond' while evaluating 'fact foo' .fi .PP -Moreover, asynchronous signals can be reported using exceptions, too. Most -standard termination signals (SIGINT, SIGTERM, etc.) are set up during startup -of the interpreter to produce corresponding Pure exceptions of the form +Exceptions also provide a way to handle asynchronous signals. Most standard +termination signals (SIGINT, SIGTERM, etc.) are set up during startup of the +interpreter to produce corresponding Pure exceptions of the form .B signal SIG where .B SIG @@ -675,6 +737,18 @@ > trap SIG_TRAP SIGQUIT; .fi .PP +You can also use +.B trap +to just ignore a signal or revert to the system's default handler (which might +take different actions depending on the type of signal, see +.BR signal (7) +for details): +.sp +.nf +> trap SIG_IGN SIGQUIT; // signal is ignored +> trap SIG_DFL SIGQUIT; // reinstalls the default signal handler +.fi +.PP Last but not least, exceptions can also be used to implement non-local value returns. For instance, here's a variation of our n queens algorithm which only returns the first solution. Note the use of @@ -700,64 +774,6 @@ > queens 8; (1,1):(2,5):(3,8):(4,6):(5,3):(6,7):(7,2):(8,4):[] .fi -.SH DECLARATIONS -As you probably noticed, Pure is very terse. That's because, in contrast to -hopelessly verbose languages like Java, you don't declare much stuff in Pure, -you just define it and be done with it. Usually, all necessary information -about the defined symbols is inferred automatically. However, there are a few -toplevel constructs which let you declare special symbol attributes and manage -programs consisting of several source modules. These are: operator and -constant symbol declarations, -.B extern -declarations for external C functions (described in the next section), and -.B using -clauses which provide a simple include file mechanism. -.TP -.B Operator and constant declarations: infix \fIlevel\fP \fIop\fR ...; -Ten different precedence levels are available for user-defined operators, -numbered 0 (lowest) thru 9 (highest). On each precedence level, you can -declare (in order of increasing precedence) -.BR infix " (binary non-associative)," -.BR infixl " (binary left-associative)," -.BR infixr " (binary right-associative)," -.BR prefix " (unary prefix) and" -.BR postfix " (unary postfix)" -operators. For instance: -.sp -.nf -\fBinfixl\fP 6 + - ; -\fBinfixl\fP 7 * / div mod ; -.fi -.sp -Note that to declare multiple symbols in a single declaration, you just list -them all with whitespace in between. -.sp -Similarly, constant symbols are introduced using a declaration of the form: -.sp -.nf -\fBnullary \fIsymbol\fR ...; -.fi -.sp -Examples for all of these can be found in the prelude which declares a bunch -of standard (arithmetic, relational, logical) operator symbols as well as the -list and pair constructors `:' and `,' and the constant symbols `[]' and `()' -denoting the empty list and tuple, respectively. -.TP -.B Using clause: using \fIname\fR ...; -Causes each given script to be included, at the position of the -.B using -clause, but only if the script was not included already. The script name can -be specified either as a string denoting the proper filename (possibly -including path and/or filename extension), or as an identifier. In the latter -case, the -.B .pure -filename extension is added automatically. In both cases, the script is -searched for in the current directory and the directory named by the -.B PURELIB -environment variable. (The -.B using -clause also has an alternative form which allows dynamic libraries to be -loaded, this will be discussed in the following section.) .SH C INTERFACE Accessing C functions from Pure programs is dead simple. You just need an .B extern @@ -786,11 +802,12 @@ the human reader; they are effectively treated as comments by the compiler. .PP The interpreter makes sure that the parameters in a call match; if not, the -call is treated as a normal form expression. The range of supported C types is -a bit limited right now (void, bool, char, short, int, long, double, as well -as arbitrary pointer types, i.e.: void*, char*, etc.), but in practice these -should cover most kinds of calls that need to be done when interfacing to C -libraries. +call is treated as a normal form expression by default, which enables you to +extend the external function with your own Pure equations. The range of +supported C types is a bit limited right now (void, bool, char, short, int, +long, float, double, as well as arbitrary pointer types, i.e.: void*, char*, +etc.), but in practice these should cover most kinds of calls that need to be +done when interfacing to C libraries. .PP Since Pure only has 32 bit machine integers and GMP bigints, a variety of C integer types are provided which are converted from/to the Pure types in a @@ -805,6 +822,9 @@ Pure bigint (which is truncated to 64 bit if necessary). 64 bit return values are always converted to (signed) Pure bigints. .PP +Similarly, single precision float arguments and return values are converted +from/to Pure's double precision floating point numbers automatically. +.PP Concerning the pointer types, char* is for string arguments and return values which need translation between Pure's internal utf-8 representation and the system encoding, while void* is for any generic kind of pointer (including @@ -820,8 +840,8 @@ Pure). All of this is handled by the runtime system in a transparent way, of course. .PP -It is even possible to augment an external C function with ordinary Pure -equations, but in this case you have to make sure that the +As already mentioned, it is possible to augment an external C function with +ordinary Pure equations, but in this case you have to make sure that the .B extern declaration of the function comes first. For instance, we might want to extend our imported @@ -829,6 +849,9 @@ function with a rule to handle integers: .sp .nf +> \fBextern\fP double sin(double); +> sin 0.3; +0.29552020666134 > sin 0; sin 0 > sin x::int = sin (double x); @@ -887,17 +910,22 @@ error message is printed. .SH STANDARD LIBRARY Pure comes with a collection of Pure library modules, which includes the -standard prelude. Right now the library is pretty rudimentary, but it offers -the necessary functions to work with the built-in types (including arithmetic -and logical operations) and to do most kind of list processing you can find in -ML- and Haskell-like languages. Please refer to the +standard prelude (loaded automatically at startup time) and some other modules +which can be loaded explicitly with a +.B using +clause. The prelude offers the necessary functions to work with the built-in +types (including arithmetic and logical operations) and to do most kind of +list processing you can find in ML- and Haskell-like languages. Please refer +to the .B prelude.pure file for details on the provided operations. Common container data structures -like sets and dictionaries are also available. Moreover, the beginnings of a -system interface can be found in the +like sets and dictionaries are also available, see +.BR set.pure , +.B dict.pure +etc. Moreover, the (beginnings of a) system interface can be found in the .B system.pure -module. In particular, this also includes operations to do basic I/O. More -stuff will likely be provided in future releases. +module. In particular, this module also includes operations to do basic +I/O. More stuff will likely be provided in future releases. .SH INTERACTIVE USAGE In interactive mode, the interpreter reads definitions and expressions and processes them as usual. The input language is just the same as for source @@ -1473,8 +1501,38 @@ (\fBif\fP-\fBthen\fP-\fBelse\fP) are tail-recursive in both branches, just like in Scheme, while the logical operators && and || are .I not -tail-recursive. This is because the logical operators always return a proper -truth value (0 or 1) which wouldn't be possible with tail call semantics. +tail-recursive. This is because in Pure the logical operators always return a +proper truth value (0 or 1) which wouldn't be possible with tail call +semantics. +.PP +.B Handling of asynchronous signals. +As described in section \fBEXCEPTION HANDLING\fP, 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, such as entry into a global function. This doesn't include +tail calls, however, so a busy loop like `loop = loop;' will \fInever\fP be +interrupted. To work around this, just add a call to another global function +to your loop to make it interruptible. For instance: +.sp +.nf +loop = loop when _ = check end; +check = (); +.fi +.PP +(Of course, the `check' function can actually do any processing required by +your application. In that case you'd probably want the `loop' function to +carry around some ``state'' argument which is modified by the `check' +routine.) To handle signals while the above loop is executing, add an +exception handler like the following: +.sp +.nf +loop = loop when _ = catch handle check end +with handle (signal k) = catch handle (...) end; +.fi +.PP +By these means the entire loop remains tail-recursive. (Note the `catch +handle' around the signal processing code which is needed for safety because +another signal may arrive while the signal handler is being executed.) .SH FILES .TP .B ~/.pure_history This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-13 09:06:07
|
Revision: 481 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=481&view=rev Author: agraef Date: 2008-08-13 09:06:17 +0000 (Wed, 13 Aug 2008) Log Message: ----------- Add support for single precision 'float' arguments and return values to the C interface. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/interpreter.cc Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-08-13 01:45:47 UTC (rev 480) +++ pure/trunk/ChangeLog 2008-08-13 09:06:17 UTC (rev 481) @@ -1,5 +1,9 @@ 2008-08-13 Albert Graef <Dr....@t-...> + * interpreter.cc (declare_extern, named_type, type_name): Add + support for single precision 'float' arguments and return values + to the C interface. Reported by Eddie Rucker. + * examples/signal.pure: Add signal processing example. * runtime.cc (pure_catch, pure_invoke): Collecting temporary Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-08-13 01:45:47 UTC (rev 480) +++ pure/trunk/interpreter.cc 2008-08-13 09:06:17 UTC (rev 481) @@ -2567,6 +2567,8 @@ return Type::Int32Ty; else if (name == "long") return Type::Int64Ty; + else if (name == "float") + return Type::FloatTy; else if (name == "double") return Type::DoubleTy; else if (name == "char*") @@ -2606,6 +2608,8 @@ return "int"; else if (type == Type::Int64Ty) return "long"; + else if (type == Type::FloatTy) + return "float"; else if (type == Type::DoubleTy) return "double"; else if (type == CharPtrTy) @@ -2872,6 +2876,18 @@ phi->addIncoming(intv, intbb); phi->addIncoming(mpzv, mpzbb); unboxed[i] = phi; + } else if (argt[i] == Type::FloatTy) { + BasicBlock *okbb = BasicBlock::Create("ok"); + Value *idx[2] = { Zero, Zero }; + Value *tagv = b.CreateLoad(b.CreateGEP(x, idx, idx+2), "tag"); + b.CreateCondBr + (b.CreateICmpEQ(tagv, SInt(EXPR::DBL), "cmp"), okbb, failedbb); + f->getBasicBlockList().push_back(okbb); + b.SetInsertPoint(okbb); + Value *pv = b.CreateBitCast(x, DblExprPtrTy, "dblexpr"); + idx[1] = ValFldIndex; + Value *dv = b.CreateLoad(b.CreateGEP(pv, idx, idx+2), "dblval"); + unboxed[i] = b.CreateFPTrunc(dv, Type::FloatTy); } else if (argt[i] == Type::DoubleTy) { BasicBlock *okbb = BasicBlock::Create("ok"); Value *idx[2] = { Zero, Zero }; @@ -2897,6 +2913,7 @@ } else if (argt[i] == PointerType::get(Type::Int16Ty, 0) || argt[i] == PointerType::get(Type::Int32Ty, 0) || argt[i] == PointerType::get(Type::Int64Ty, 0) || + argt[i] == PointerType::get(Type::FloatTy, 0) || argt[i] == PointerType::get(Type::DoubleTy, 0)) { BasicBlock *okbb = BasicBlock::Create("ok"); Value *idx[2] = { Zero, Zero }; @@ -2977,6 +2994,9 @@ u = b.CreateCall(module->getFunction("pure_int"), u); else if (type == Type::Int64Ty) u = b.CreateCall(module->getFunction("pure_long"), u); + else if (type == Type::FloatTy) + u = b.CreateCall(module->getFunction("pure_double"), + b.CreateFPExt(u, Type::DoubleTy)); else if (type == Type::DoubleTy) u = b.CreateCall(module->getFunction("pure_double"), u); else if (type == CharPtrTy) @@ -2984,6 +3004,7 @@ else if (type == PointerType::get(Type::Int16Ty, 0) || type == PointerType::get(Type::Int32Ty, 0) || type == PointerType::get(Type::Int64Ty, 0) || + type == PointerType::get(Type::FloatTy, 0) || type == PointerType::get(Type::DoubleTy, 0)) u = b.CreateCall(module->getFunction("pure_pointer"), b.CreateBitCast(u, VoidPtrTy)); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-13 01:45:37
|
Revision: 480 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=480&view=rev Author: agraef Date: 2008-08-13 01:45:47 +0000 (Wed, 13 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-13 01:07:48 UTC (rev 479) +++ pure/trunk/pure.1.in 2008-08-13 01:45:47 UTC (rev 480) @@ -586,7 +586,7 @@ expression the comprehension expanded to: .sp .nf -> list primes +> \fBlist\fP primes primes n = sieve (2..n) \fBwith\fP sieve [] = []; sieve (p:qs) = p:sieve (catmap (\eq -> if q mod p then [q] else []) qs) \fBend\fP; .fi @@ -657,9 +657,27 @@ <stdin>:2.0-7: unhandled exception 'failed_cond' while evaluating 'fact foo' .fi .PP -Exceptions can also be used to implement non-local value returns. For -instance, here's a variation of our n queens algorithm which only returns the -first solution. Note the use of +Moreover, asynchronous signals can be reported using exceptions, too. Most +standard termination signals (SIGINT, SIGTERM, etc.) are set up during startup +of the interpreter to produce corresponding Pure exceptions of the form +.B signal SIG +where +.B SIG +is the signal number. Pure's system module provides symbolic constants for +common POSIX signals and also defines the operation +.B trap +which lets you rebind any signal to a +.B signal +exception. For instance, the following lets you handle the SIGQUIT signal: +.sp +.nf +> \fBusing\fP system; +> trap SIG_TRAP SIGQUIT; +.fi +.PP +Last but not least, exceptions can also be used to implement non-local value +returns. For instance, here's a variation of our n queens algorithm which only +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 @@ -874,11 +892,12 @@ and logical operations) and to do most kind of list processing you can find in ML- and Haskell-like languages. Please refer to the .B prelude.pure -file for details on the provided operations. Also, the beginnings of a system -interface can be found in the +file for details on the provided operations. Common container data structures +like sets and dictionaries are also available. Moreover, the beginnings of a +system interface can be found in the .B system.pure module. In particular, this also includes operations to do basic I/O. More -stuff will be provided in future releases. +stuff will likely be provided in future releases. .SH INTERACTIVE USAGE In interactive mode, the interpreter reads definitions and expressions and processes them as usual. The input language is just the same as for source @@ -1288,9 +1307,9 @@ > foo x = c*x; > foo 99; c*99 -> let c = 2; foo 99; +> \fBlet\fP c = 2; foo 99; 198 -> let c = 3; foo 99; +> \fBlet\fP c = 3; foo 99; 297 .fi .PP @@ -1306,14 +1325,14 @@ definitions. E.g., continuing the previous example: .sp .nf -> def d = 2; +> \fBdef\fP d = 2; > bar x = d*x; -> list foo bar +> \fBlist\fP foo bar bar x = 2*x; foo x = c*x; > bar 99; 198 -> def d = 3; +> \fBdef\fP d = 3; <stdin>:9.0-8: symbol 'd' is already defined as a constant .fi .PP @@ -1323,9 +1342,9 @@ definitions: .sp .nf -> clear d -> def d = 3; -> list bar +> \fBclear\fP d +> \fBdef\fP d = 3; +> \fBlist\fP bar bar x = 2*x; .fi .PP @@ -1370,10 +1389,10 @@ using constant folding and similar techniques. Example: .sp .nf -> extern double atan(double); -> def pi = 4*atan 1.0; +> \fBextern\fP double atan(double); +> \fBdef\fP pi = 4*atan 1.0; > foo x = 2*pi*x; -> list foo +> \fBlist\fP foo foo x = 2*3.14159265358979*x; .fi .PP @@ -1385,7 +1404,7 @@ different environments, without any runtime penalties: .sp .nf -> def running_on_windows = index sysinfo "mingw32" >= 0; +> \fBdef\fP running_on_windows = index sysinfo "mingw32" >= 0; > foo x = something x if running_on_windows; > = something_else x otherwise; .fi This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-13 01:07:38
|
Revision: 479 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=479&view=rev Author: agraef Date: 2008-08-13 01:07:48 +0000 (Wed, 13 Aug 2008) Log Message: ----------- Add signal processing example. Modified Paths: -------------- pure/trunk/ChangeLog Added Paths: ----------- pure/trunk/examples/signal.pure Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-08-12 23:58:36 UTC (rev 478) +++ pure/trunk/ChangeLog 2008-08-13 01:07:48 UTC (rev 479) @@ -1,5 +1,7 @@ 2008-08-13 Albert Graef <Dr....@t-...> + * examples/signal.pure: Add signal processing example. + * runtime.cc (pure_catch, pure_invoke): Collecting temporary values after an exception doesn't seem to be safe while an evaluation is still in progress. Moved this to doeval/dodefn in Added: pure/trunk/examples/signal.pure =================================================================== --- pure/trunk/examples/signal.pure (rev 0) +++ pure/trunk/examples/signal.pure 2008-08-13 01:07:48 UTC (rev 479) @@ -0,0 +1,30 @@ + +/* Signal processing example. */ + +using system; +extern int getpid(); + +/* The common POSIX termination signals like SIGHUP, SIGINT, SIGTERM etc. are + already remapped to Pure exceptions by the interpreter when it starts. + Other kinds of signals can be handled as Pure exceptions, too, if we rebind + them with the 'trap' function. (Try 'list -g SIG*' to see which standard + signal values are known on your system.) Example: */ + +trap SIG_TRAP SIGTSTP; + +/* Running this function enters an endless loop reporting all signals + delivered to the process. */ + +test = printf "Running as pid %d, try to kill me!\n" getpid, loop; + +loop = loop when _ = catch sig check end +with + sig (signal k) = loop when _ = printf "Hey, I got signal %d.\n" k end; +end; + +/* Take a short nap so that the loop doesn't run busily. This also serves the + purpose of checking for pending signals. (Note that for performance reasons + the Pure interpreter only processes asynchronous signals at certain points, + such as the entry of a global Pure function.) */ + +check = sleep 1; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-12 23:58:26
|
Revision: 478 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=478&view=rev Author: agraef Date: 2008-08-12 23:58:36 +0000 (Tue, 12 Aug 2008) Log Message: ----------- Separate stack and other kinds of tests for asynchronous exceptions. Modified Paths: -------------- pure/trunk/runtime.cc Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-08-12 23:49:27 UTC (rev 477) +++ pure/trunk/runtime.cc 2008-08-12 23:58:36 UTC (rev 478) @@ -33,8 +33,12 @@ #include "config.h" #include "funcall.h" -// Hook to report stack overflows and other kinds of hard errors. -#define checkstk(test) if (interpreter::brkflag) \ +// Hooks to report stack overflows and other kinds of hard errors. +#define checkstk(test) if (interpreter::stackmax > 0 && \ + interpreter::stackdir*(&test - interpreter::baseptr) \ + >= interpreter::stackmax) \ + pure_throw(stack_exception()) +#define checkall(test) if (interpreter::brkflag) \ pure_throw(signal_exception(interpreter::brkflag)); \ else if (interpreter::stackmax > 0 && \ interpreter::stackdir*(&test - interpreter::baseptr) \ @@ -1158,7 +1162,7 @@ #endif assert(x->tag > 0 && x->refc > 0 && !x->data.clos->local); // parameterless call - checkstk(test); + checkall(test); return ((pure_expr*(*)())fp)(); } else { #if DEBUG>2 @@ -1254,7 +1258,7 @@ for (size_t j = 0; j < m; j++) cerr << "env#" << j << " = " << f0->data.clos->env[j] << " -> " << (void*)f0->data.clos->env[j] << ", refc = " << f0->data.clos->env[j]->refc << endl; #endif - checkstk(test); + checkall(test); if (m>0) xfuncall(ret, fp, n, env, argv) else This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-12 23:49:18
|
Revision: 477 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=477&view=rev Author: agraef Date: 2008-08-12 23:49:27 +0000 (Tue, 12 Aug 2008) Log Message: ----------- Move check for uncollected temporaries after an exception to the toplevel. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/interpreter.cc pure/trunk/runtime.cc Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-08-12 19:20:37 UTC (rev 476) +++ pure/trunk/ChangeLog 2008-08-12 23:49:27 UTC (rev 477) @@ -1,3 +1,11 @@ +2008-08-13 Albert Graef <Dr....@t-...> + + * runtime.cc (pure_catch, pure_invoke): Collecting temporary + values after an exception doesn't seem to be safe while an + evaluation is still in progress. Moved this to doeval/dodefn in + interpreter.cc where we're back at the toplevel and it is safe to + do this. + 2008-08-12 Albert Graef <Dr....@t-...> * runtime.cc/h, lib/system.pure: Add 'trap' operation to configure Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-08-12 19:20:37 UTC (rev 476) +++ pure/trunk/interpreter.cc 2008-08-12 23:49:27 UTC (rev 477) @@ -3201,6 +3201,22 @@ else fptr->refc--; fptr = save_fptr; + if (!res) { + // collect garbage + pure_expr *t = tmps; + while (t) { + pure_expr *next = t->xp; + pure_freenew(t); + t = next; + } + } +#if DEBUG>1 + pure_expr *t = tmps; + while (t) { + if (t != res) std::cerr << "uncollected temporary: " << t << endl; + t = t->xp; + } +#endif // NOTE: Result (if any) is to be freed by the caller. return res; } @@ -3342,7 +3358,21 @@ globalvars.erase(tag); } } + // collect garbage + pure_expr *t = tmps; + while (t) { + pure_expr *next = t->xp; + pure_freenew(t); + t = next; + } } +#if DEBUG>1 + pure_expr *t = tmps; + while (t) { + if (t != res) std::cerr << "uncollected temporary: " << t << endl; + t = t->xp; + } +#endif // NOTE: Result (if any) is to be freed by the caller. return res; } Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-08-12 19:20:37 UTC (rev 476) +++ pure/trunk/runtime.cc 2008-08-12 23:49:27 UTC (rev 477) @@ -1363,6 +1363,8 @@ pure_expr *e = interp.estk.front().e; interp.estk.pop_front(); if (e) pure_new_internal(e); +#if 0 + /* This doesn't seem to be safe here. Defer until later. */ // collect garbage pure_expr *tmps = interp.tmps; while (tmps) { @@ -1370,6 +1372,7 @@ pure_freenew(tmps); tmps = next; } +#endif for (size_t i = interp.sstk_sz; i-- > sz; ) if (interp.sstk[i] && interp.sstk[i]->refc > 0) pure_free_internal(interp.sstk[i]); @@ -1394,7 +1397,7 @@ res = ((pure_expr*(*)())fp)(); // normal return interp.estk.pop_front(); -#if DEBUG>1 +#if DEBUG>2 pure_expr *tmps = interp.tmps; while (tmps) { if (tmps != res) cerr << "uncollected temporary: " << tmps << endl; @@ -1437,6 +1440,8 @@ e = interp.estk.front().e; interp.estk.pop_front(); if (e) pure_new_internal(e); +#if 0 + /* This doesn't seem to be safe here. Defer until later. */ // collect garbage pure_expr *tmps = interp.tmps; while (tmps) { @@ -1444,6 +1449,7 @@ pure_freenew(tmps); tmps = next; } +#endif for (size_t i = interp.sstk_sz; i-- > sz; ) if (interp.sstk[i] && interp.sstk[i]->refc > 0) pure_free_internal(interp.sstk[i]); @@ -1460,7 +1466,7 @@ // normal return interp.estk.pop_front(); MEMDEBUG_SUMMARY(res) -#if DEBUG>1 +#if DEBUG>2 pure_expr *tmps = interp.tmps; while (tmps) { if (tmps != res) cerr << "uncollected temporary: " << tmps << endl; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-12 19:20:27
|
Revision: 476 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=476&view=rev Author: agraef Date: 2008-08-12 19:20:37 +0000 (Tue, 12 Aug 2008) Log Message: ----------- Add 'trap' operation to configure signal handlers. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/lib/system.pure pure/trunk/runtime.cc pure/trunk/runtime.h Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-08-12 19:17:34 UTC (rev 475) +++ pure/trunk/ChangeLog 2008-08-12 19:20:37 UTC (rev 476) @@ -1,5 +1,8 @@ 2008-08-12 Albert Graef <Dr....@t-...> + * runtime.cc/h, lib/system.pure: Add 'trap' operation to configure + signal handlers. + * runtime.cc (pure_sys_vars): Add signal constants. * pure.cc (main): Set up handlers for standard POSIX termination Modified: pure/trunk/lib/system.pure =================================================================== --- pure/trunk/lib/system.pure 2008-08-12 19:17:34 UTC (rev 475) +++ pure/trunk/lib/system.pure 2008-08-12 19:20:37 UTC (rev 476) @@ -47,6 +47,18 @@ errno = pure_errno; set_errno val::int = pure_set_errno val; +/* 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 + form 'signal SIG'. SIG_IGN ignores the signal, SIG_DFL reverts to the + system's default handling. See 'list -g SIG*' for a list of known signal + values on your system. NOTE: Most standard termination signals (SIGINT, + SIGTERM, etc.) are already set up at the start of the interpreter to report + corresponding Pure exceptions; if this is not desired, you can use 'trap' + to either ignore these or revert to the default handlers instead. */ + +extern void pure_trap(int action, int sig) = trap; + /* Time functions. 'time' reports the current time in seconds since the "epoch" a.k.a. 00:00:00 UTC, Jan 1 1970. The result is always a bigint (in fact, the time value is already 64 bit on many OSes nowadays). */ Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-08-12 19:17:34 UTC (rev 475) +++ pure/trunk/runtime.cc 2008-08-12 19:20:37 UTC (rev 476) @@ -1297,7 +1297,23 @@ pure_throw(signal_exception(SIGFPE)); } +static void sig_handler(int sig) +{ + interpreter::brkflag = sig; +} + extern "C" +void pure_trap(int32_t action, int32_t sig) +{ + if (action > 0) + signal(sig, sig_handler); + else if (action < 0) + signal(sig, SIG_IGN); + else + signal(sig, SIG_DFL); +} + +extern "C" pure_expr *pure_catch(pure_expr *h, pure_expr *x) { char test; @@ -2938,6 +2954,10 @@ cdf(interp, "REG_ESPACE", pure_int(REG_ESPACE)); // regexec error codes cdf(interp, "REG_NOMATCH", pure_int(REG_NOMATCH)); + // signal actions + cdf(interp, "SIG_TRAP", pure_int(1)); + cdf(interp, "SIG_IGN", pure_int(-1)); + cdf(interp, "SIG_DFL", pure_int(0)); // signals #ifdef SIGHUP cdf(interp, "SIGHUP", pure_int(SIGHUP)); Modified: pure/trunk/runtime.h =================================================================== --- pure/trunk/runtime.h 2008-08-12 19:17:34 UTC (rev 475) +++ pure/trunk/runtime.h 2008-08-12 19:20:37 UTC (rev 476) @@ -345,6 +345,11 @@ void pure_sigfpe(void); +/* Configure signal handlers. The second argument is the signal number, the + first the action to take (-1 = ignore, 1 = handle, 0 = default). */ + +void pure_trap(int32_t action, int32_t sig); + /* Execute a parameterless fbox x and return its result. If an exception occurs while x is executed, apply h to the value of the exception instead. */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-12 19:17:25
|
Revision: 475 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=475&view=rev Author: agraef Date: 2008-08-12 19:17:34 +0000 (Tue, 12 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-12 13:59:55 UTC (rev 474) +++ pure/trunk/lib/primitives.pure 2008-08-12 19:17:34 UTC (rev 475) @@ -21,8 +21,7 @@ /* Throw an exception. */ -extern void pure_throw(expr*); // IMPURE! -throw x = pure_throw x; +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. */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-12 13:59:49
|
Revision: 474 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=474&view=rev Author: agraef Date: 2008-08-12 13:59:55 +0000 (Tue, 12 Aug 2008) Log Message: ----------- Add signal constants. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/runtime.cc Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-08-12 13:44:56 UTC (rev 473) +++ pure/trunk/ChangeLog 2008-08-12 13:59:55 UTC (rev 474) @@ -1,5 +1,7 @@ 2008-08-12 Albert Graef <Dr....@t-...> + * runtime.cc (pure_sys_vars): Add signal constants. + * pure.cc (main): Set up handlers for standard POSIX termination signals, mapping these to orderly Pure exceptions of the form 'signal SIG'. Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-08-12 13:44:56 UTC (rev 473) +++ pure/trunk/runtime.cc 2008-08-12 13:59:55 UTC (rev 474) @@ -2938,4 +2938,62 @@ cdf(interp, "REG_ESPACE", pure_int(REG_ESPACE)); // regexec error codes cdf(interp, "REG_NOMATCH", pure_int(REG_NOMATCH)); + // signals +#ifdef SIGHUP + cdf(interp, "SIGHUP", pure_int(SIGHUP)); +#endif +#ifdef SIGINT + cdf(interp, "SIGINT", pure_int(SIGINT)); +#endif +#ifdef SIGQUIT + cdf(interp, "SIGQUIT", pure_int(SIGQUIT)); +#endif +#ifdef SIGILL + cdf(interp, "SIGILL", pure_int(SIGILL)); +#endif +#ifdef SIGABRT + cdf(interp, "SIGABRT", pure_int(SIGABRT)); +#endif +#ifdef SIGFPE + cdf(interp, "SIGFPE", pure_int(SIGFPE)); +#endif +#ifdef SIGKILL + cdf(interp, "SIGKILL", pure_int(SIGKILL)); +#endif +#ifdef SIGSEGV + cdf(interp, "SIGSEGV", pure_int(SIGSEGV)); +#endif +#ifdef SIGPIPE + cdf(interp, "SIGPIPE", pure_int(SIGPIPE)); +#endif +#ifdef SIGALRM + cdf(interp, "SIGALRM", pure_int(SIGALRM)); +#endif +#ifdef SIGTERM + cdf(interp, "SIGTERM", pure_int(SIGTERM)); +#endif +#ifdef SIGUSR1 + cdf(interp, "SIGUSR1", pure_int(SIGUSR1)); +#endif +#ifdef SIGUSR2 + cdf(interp, "SIGUSR2", pure_int(SIGUSR2)); +#endif +#ifdef SIGCHLD + cdf(interp, "SIGCHLD", pure_int(SIGCHLD)); +#endif +#ifdef SIGCONT + cdf(interp, "SIGCONT", pure_int(SIGCONT)); +#endif +#ifdef SIGSTOP + cdf(interp, "SIGSTOP", pure_int(SIGSTOP)); +#endif +#ifdef SIGTSTP + cdf(interp, "SIGTSTP", pure_int(SIGTSTP)); +#endif +#ifdef SIGTTIN + cdf(interp, "SIGTTIN", pure_int(SIGTTIN)); +#endif +#ifdef SIGTTOU + cdf(interp, "SIGTTOU", pure_int(SIGTTOU)); +#endif } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-12 13:44:48
|
Revision: 473 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=473&view=rev Author: agraef Date: 2008-08-12 13:44:56 +0000 (Tue, 12 Aug 2008) Log Message: ----------- Add handlers for POSIX termination signals. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/pure.cc Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-08-12 13:28:56 UTC (rev 472) +++ pure/trunk/ChangeLog 2008-08-12 13:44:56 UTC (rev 473) @@ -1,5 +1,9 @@ 2008-08-12 Albert Graef <Dr....@t-...> + * pure.cc (main): Set up handlers for standard POSIX termination + signals, mapping these to orderly Pure exceptions of the form + 'signal SIG'. + * interpreter.cc (builtin_codegen), runtime.cc(bigint_div, bigint_mod): Handle division by zero by throwing a 'signal SIGFPE' exception. Previously, these would just bail out with an unhandled Modified: pure/trunk/pure.cc =================================================================== --- pure/trunk/pure.cc 2008-08-12 13:28:56 UTC (rev 472) +++ pure/trunk/pure.cc 2008-08-12 13:44:56 UTC (rev 473) @@ -162,7 +162,7 @@ return matches; } -static void sigint_handler(int sig) +static void sig_handler(int sig) { interpreter::brkflag = sig; } @@ -185,13 +185,32 @@ // This is used in advisory stack checks. interpreter::baseptr = &base; // make sure that SIGPIPE is ignored -#ifndef _WIN32 + /* Set up handlers for all standard POSIX termination signals (except + SIGKILL which is unmaskable). SIGPIPE is ignored by default, all others + are mapped to Pure exceptions of the form 'signal SIG', so that they can + be caught with 'catch' or safely return us to the interpreter's + interactive command line. */ +#ifdef SIGHUP + signal(SIGHUP, sig_handler); +#endif +#ifdef SIGINT + signal(SIGINT, sig_handler); +#endif +#ifdef SIGPIPE signal(SIGPIPE, SIG_IGN); #endif - /* Set up a SIGINT handler which throws a Pure exception, so that we safely - return to the interpreter's interactive command line when the user - interrupts a computation. */ - signal(SIGINT, sigint_handler); +#ifdef SIGALRM + signal(SIGALRM, sig_handler); +#endif +#ifdef SIGTERM + signal(SIGTERM, sig_handler); +#endif +#ifdef SIGUSR1 + signal(SIGUSR1, sig_handler); +#endif +#ifdef SIGUSR2 + signal(SIGUSR2, sig_handler); +#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: <ye...@us...> - 2008-08-12 13:28:47
|
Revision: 472 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=472&view=rev Author: yes Date: 2008-08-12 13:28:56 +0000 (Tue, 12 Aug 2008) Log Message: ----------- Improved timex in date.pure, now works with the latest Pure fix Modified Paths: -------------- pure/trunk/examples/libor/date.pure Modified: pure/trunk/examples/libor/date.pure =================================================================== --- pure/trunk/examples/libor/date.pure 2008-08-12 12:56:14 UTC (rev 471) +++ pure/trunk/examples/libor/date.pure 2008-08-12 13:28:56 UTC (rev 472) @@ -31,8 +31,9 @@ mstime = 1000.0*gettimeofday; mscpu = 1000.0*clock/CLOCKS_PER_SEC; -// timex returns a list: [ evaluated string argument, cputime, realtime ] -timex s::string = [(eval s), round (mscpu-c0), round (mstime-d0)] +/* timex returns a list: [ evaluated closure, cputime, realtime ] + call with closure argument: (timex (\_ -> sumefunction some arguments)) */ +timex f = (f ()), (round (mscpu-c0)), (round (mstime-d0)) when d0::double = mstime; c0::double = mscpu end; /* extended mod operator to work on doubles, so that int, bigint and double This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-12 12:56:07
|
Revision: 471 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=471&view=rev Author: agraef Date: 2008-08-12 12:56:14 +0000 (Tue, 12 Aug 2008) Log Message: ----------- Handle SIGFPE. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/interpreter.cc pure/trunk/runtime.cc pure/trunk/runtime.h Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-08-12 06:49:56 UTC (rev 470) +++ pure/trunk/ChangeLog 2008-08-12 12:56:14 UTC (rev 471) @@ -1,5 +1,10 @@ 2008-08-12 Albert Graef <Dr....@t-...> + * interpreter.cc (builtin_codegen), runtime.cc(bigint_div, + bigint_mod): Handle division by zero by throwing a 'signal SIGFPE' + exception. Previously, these would just bail out with an unhandled + SIGFPE signal. + * lexer.ll: Fixed a bug in option parsing of the 'list' command which would cause an option string starting with '-a' to be interpreted as an ordinary argument. Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-08-12 06:49:56 UTC (rev 470) +++ pure/trunk/interpreter.cc 2008-08-12 12:56:14 UTC (rev 471) @@ -263,6 +263,8 @@ "pure_catch", "expr*", 2, "expr*", "expr*"); declare_extern((void*)pure_throw, "pure_throw", "void", 1, "expr*"); + declare_extern((void*)pure_sigfpe, + "pure_sigfpe", "void", 0); declare_extern((void*)pure_new, "pure_new", "expr*", 1, "expr*"); @@ -3652,11 +3654,43 @@ return b.CreateSub(u, v); else if (f.ftag() == symtab.mult_sym().f) return b.CreateMul(u, v); - else if (f.ftag() == symtab.div_sym().f) - return b.CreateSDiv(u, v); - else if (f.ftag() == symtab.mod_sym().f) - return b.CreateSRem(u, v); - else { + else if (f.ftag() == symtab.div_sym().f) { + // catch division by zero + if (x.xval2().tag() == EXPR::INT && x.xval2().ival() == 0) { + b.CreateCall(module->getFunction("pure_sigfpe")); + return v; + } else { + BasicBlock *okbb = BasicBlock::Create("ok"); + BasicBlock *errbb = BasicBlock::Create("err"); + Value *cmp = b.CreateICmpEQ(v, Zero); + b.CreateCondBr(cmp, errbb, okbb); + act_env().f->getBasicBlockList().push_back(errbb); + b.SetInsertPoint(errbb); + b.CreateCall(module->getFunction("pure_sigfpe")); + b.CreateRet(NullExprPtr); + act_env().f->getBasicBlockList().push_back(okbb); + b.SetInsertPoint(okbb); + return b.CreateSDiv(u, v); + } + } else if (f.ftag() == symtab.mod_sym().f) { + // catch division by zero + if (x.xval2().tag() == EXPR::INT && x.xval2().ival() == 0) { + b.CreateCall(module->getFunction("pure_sigfpe")); + return v; + } else { + BasicBlock *okbb = BasicBlock::Create("ok"); + BasicBlock *errbb = BasicBlock::Create("err"); + Value *cmp = b.CreateICmpEQ(v, Zero); + b.CreateCondBr(cmp, errbb, okbb); + act_env().f->getBasicBlockList().push_back(errbb); + b.SetInsertPoint(errbb); + b.CreateCall(module->getFunction("pure_sigfpe")); + b.CreateRet(NullExprPtr); + act_env().f->getBasicBlockList().push_back(okbb); + b.SetInsertPoint(okbb); + return b.CreateSRem(u, v); + } + } else { assert(0 && "error in type checker"); return 0; } Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-08-12 06:49:56 UTC (rev 470) +++ pure/trunk/runtime.cc 2008-08-12 12:56:14 UTC (rev 471) @@ -1289,7 +1289,15 @@ } } +#include <signal.h> + extern "C" +void pure_sigfpe(void) +{ + pure_throw(signal_exception(SIGFPE)); +} + +extern "C" pure_expr *pure_catch(pure_expr *h, pure_expr *x) { char test; @@ -1952,9 +1960,12 @@ return u; } +// These raise a SIGFPE signal exception for division by zero. + extern "C" pure_expr *bigint_div(mpz_t x, mpz_t y) { + if (mpz_sgn(y) == 0) pure_sigfpe(); pure_expr *u = pure_bigint(0, 0); mpz_t& z = u->data.z; mpz_tdiv_q(z, x, y); @@ -1964,6 +1975,7 @@ extern "C" pure_expr *bigint_mod(mpz_t x, mpz_t y) { + if (mpz_sgn(y) == 0) pure_sigfpe(); pure_expr *u = pure_bigint(0, 0); mpz_t& z = u->data.z; mpz_tdiv_r(z, x, y); Modified: pure/trunk/runtime.h =================================================================== --- pure/trunk/runtime.h 2008-08-12 06:49:56 UTC (rev 470) +++ pure/trunk/runtime.h 2008-08-12 12:56:14 UTC (rev 471) @@ -340,6 +340,11 @@ void pure_throw(pure_expr* e); +/* Throw a 'signal SIGFPE' exception. This is used to signal division by + zero. */ + +void pure_sigfpe(void); + /* Execute a parameterless fbox x and return its result. If an exception occurs while x is executed, apply h to the value of the exception instead. */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |