pure-lang-svn Mailing List for Pure (Page 15)
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-17 11:45:59
|
Revision: 520 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=520&view=rev Author: agraef Date: 2008-08-17 11:46:10 +0000 (Sun, 17 Aug 2008) Log Message: ----------- Cosmetic changes. Modified Paths: -------------- pure/trunk/lib/array.pure pure/trunk/lib/system.pure Modified: pure/trunk/lib/array.pure =================================================================== --- pure/trunk/lib/array.pure 2008-08-17 11:40:00 UTC (rev 519) +++ pure/trunk/lib/array.pure 2008-08-17 11:46:10 UTC (rev 520) @@ -40,7 +40,7 @@ a!!is slicing (get a list of values from a list indices a!!ijs slicing of two-dimensional array (from a given - list of pairs (i, j):...:[]) + list of pairs [(i, j), ...]) null a tests whether a is the empty array members a list of values stored in a Modified: pure/trunk/lib/system.pure =================================================================== --- pure/trunk/lib/system.pure 2008-08-17 11:40:00 UTC (rev 519) +++ pure/trunk/lib/system.pure 2008-08-17 11:46:10 UTC (rev 520) @@ -603,7 +603,7 @@ regs info = myregs 0 info with myregs n (p,s,infos) = (n,p,s):myregs (n+1) infos if p>=0; = myregs (n+1) infos otherwise; - myregs n (p,s) = (n,p,s):[] if p>=0; + myregs n (p,s) = [(n,p,s)] if p>=0; = [] 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-17 11:39:51
|
Revision: 519 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=519&view=rev Author: agraef Date: 2008-08-17 11:40:00 +0000 (Sun, 17 Aug 2008) Log Message: ----------- Cosmetic changes. Modified Paths: -------------- pure/trunk/expr.cc pure/trunk/expr.hh pure/trunk/interpreter.cc Modified: pure/trunk/expr.cc =================================================================== --- pure/trunk/expr.cc 2008-08-17 11:25:34 UTC (rev 518) +++ pure/trunk/expr.cc 2008-08-17 11:40:00 UTC (rev 519) @@ -252,11 +252,11 @@ } } -bool expr::is_tuplexxx(exprl &xs) const +bool expr::is_tuplel(exprl &xs) const { expr x, y; if (is_pair(x, y) && !(flags()&EXPR::PAREN)) - return x.is_tuplexxx(xs) && y.is_tuplexxx(xs); + return x.is_tuplel(xs) && y.is_tuplel(xs); else { xs.push_back(*this); return true; Modified: pure/trunk/expr.hh =================================================================== --- pure/trunk/expr.hh 2008-08-17 11:25:34 UTC (rev 518) +++ pure/trunk/expr.hh 2008-08-17 11:40:00 UTC (rev 519) @@ -483,9 +483,10 @@ // Always true (see note above). Use is_pair() && istuple(xs) to test for a // "real" tuple instead. bool is_tuple(exprl &xs) const; + // Check for proper (normalized) tuples. bool is_tuplex(exprl &xs) const; // Special check for tuples used in list construction. - bool is_tuplexxx(exprl &xs) const; + bool is_tuplel(exprl &xs) const; }; /* Rules of the form: lhs -> rhs [if qual]. */ Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-08-17 11:25:34 UTC (rev 518) +++ pure/trunk/interpreter.cc 2008-08-17 11:40:00 UTC (rev 519) @@ -1920,7 +1920,7 @@ { expr *u; exprl xs; - if (x->is_pair() && x->is_tuplexxx(xs)) + if (x->is_pair() && x->is_tuplel(xs)) u = new expr(expr::list(xs)); else u = new expr(expr::cons(*x, expr::nil())); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-17 11:25:25
|
Revision: 518 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=518&view=rev Author: agraef Date: 2008-08-17 11:25:34 +0000 (Sun, 17 Aug 2008) Log Message: ----------- Revised list-of-tuple syntax. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/expr.cc pure/trunk/expr.hh pure/trunk/interpreter.cc pure/trunk/parser.yy pure/trunk/printer.cc pure/trunk/test/test015.log Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-08-17 09:51:09 UTC (rev 517) +++ pure/trunk/ChangeLog 2008-08-17 11:25:34 UTC (rev 518) @@ -1,5 +1,9 @@ 2008-08-17 Albert Graef <Dr....@t-...> + * parser.yy, printer.cc et al: Revised list-of-tuples syntax. In + order to include a tuple in a proper list value you can simply put + the tuple inside parentheses now. + * parser.yy, lexer.ll: Revised 'using' syntax so that script names are now separated with a comma. Updated library and sample scripts accordingly. Modified: pure/trunk/expr.cc =================================================================== --- pure/trunk/expr.cc 2008-08-17 09:51:09 UTC (rev 517) +++ pure/trunk/expr.cc 2008-08-17 11:25:34 UTC (rev 518) @@ -175,15 +175,6 @@ return is_nil(); } -bool expr::is_listx() const -{ - expr x, y; - if (is_cons(x, y)) - return !x.is_pair() && y.is_listx(); - else - return is_nil(); -} - bool expr::is_voidx() const { return tag() == interpreter::g_interp->symtab.void_sym().f; @@ -226,25 +217,6 @@ } } -bool expr::is_listx(exprl &xs) const -{ - expr x, y; - if (is_cons(x, y)) { - if (x.is_pair()) { - xs.clear(); - return false; - } else { - xs.push_back(x); - return y.is_listx(xs); - } - } else if (is_nil()) - return true; - else { - xs.clear(); - return false; - } -} - bool expr::is_pair(expr &x, expr &y) const { expr u, v; @@ -280,6 +252,17 @@ } } +bool expr::is_tuplexxx(exprl &xs) const +{ + expr x, y; + if (is_pair(x, y) && !(flags()&EXPR::PAREN)) + return x.is_tuplexxx(xs) && y.is_tuplexxx(xs); + else { + xs.push_back(*this); + return true; + } +} + env_info::env_info(const env_info& e) : t(e.t), temp(e.temp) { switch (t) { case none: Modified: pure/trunk/expr.hh =================================================================== --- pure/trunk/expr.hh 2008-08-17 09:51:09 UTC (rev 517) +++ pure/trunk/expr.hh 2008-08-17 11:25:34 UTC (rev 518) @@ -117,7 +117,8 @@ // special flag values used during compilation: enum { - OVF = 1, // overflowed int constant -> bigint + OVF = 1, // overflowed int constant -> bigint + PAREN = 1<<1, // parenthesized expression }; uint32_t refc; // reference counter @@ -469,9 +470,6 @@ bool is_nil() const; bool is_cons() const; bool is_list() const; - // Check for lists which don't contain tuple elements, so that they can be - // printed in standard list format. - bool is_listx() const; bool is_voidx() const; bool is_pair() const; // This is always true, as we consider a singleton as a tuple, too. Use @@ -481,12 +479,13 @@ bool is_tuplex() const; bool is_cons(expr &x, expr &y) const; bool is_list(exprl &xs) const; - bool is_listx(exprl &xs) const; bool is_pair(expr &x, expr &y) const; // Always true (see note above). Use is_pair() && istuple(xs) to test for a // "real" tuple instead. bool is_tuple(exprl &xs) const; bool is_tuplex(exprl &xs) const; + // Special check for tuples used in list construction. + bool is_tuplexxx(exprl &xs) const; }; /* Rules of the form: lhs -> rhs [if qual]. */ Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-08-17 09:51:09 UTC (rev 517) +++ pure/trunk/interpreter.cc 2008-08-17 11:25:34 UTC (rev 518) @@ -1920,7 +1920,7 @@ { expr *u; exprl xs; - if (x->is_pair() && x->is_tuple(xs)) + if (x->is_pair() && x->is_tuplexxx(xs)) u = new expr(expr::list(xs)); else u = new expr(expr::cons(*x, expr::nil())); Modified: pure/trunk/parser.yy =================================================================== --- pure/trunk/parser.yy 2008-08-17 09:51:09 UTC (rev 517) +++ pure/trunk/parser.yy 2008-08-17 11:25:34 UTC (rev 518) @@ -515,7 +515,8 @@ | '[' expr ']' { $$ = interp.mklist_expr($2); } | '[' expr ';' comp_clauses ']' { $$ = interp.mklistcomp_expr($2, $4); } -| '(' expr ')' { $$ = $2; } +| '(' expr ')' { $$ = $2; + if ($$->is_pair()) $$->flags() |= EXPR::PAREN; } | '(' op ')' { $$ = $2; } ; Modified: pure/trunk/printer.cc =================================================================== --- pure/trunk/printer.cc 2008-08-17 09:51:09 UTC (rev 517) +++ pure/trunk/printer.cc 2008-08-17 11:25:34 UTC (rev 518) @@ -84,7 +84,7 @@ case EXPR::APP: { expr u, v, w; prec_t p; - if (x.is_listx()) + if (x.is_list()) return 100; else if (x.is_app(u, v)) if (u.tag() > 0 && (p = sym_nprec(u.tag())) < 100 && p%10 >= 3) @@ -248,11 +248,11 @@ expr u, v, w, y; exprl xs; prec_t p; - if (x.is_listx(xs)) { + if (x.is_list(xs)) { // proper list value size_t n = xs.size(); os << "["; - if (n>1) { + if (n>1 || n==1 && xs.front().is_pair()) { // list elements at a precedence not larger than ',' have to be // parenthesized p = sym_nprec(interpreter::g_interp->symtab.pair_sym().f) + 1; @@ -528,8 +528,7 @@ static bool pure_is_cons(const pure_expr *x) { if (x->tag == EXPR::APP && x->data.x[0]->tag == EXPR::APP) - return - x->data.x[0]->data.x[0]->tag == interpreter::g_interp->symtab.cons_sym().f; + return x->data.x[0]->data.x[0]->tag == interpreter::g_interp->symtab.cons_sym().f; else return false; } @@ -537,8 +536,7 @@ static bool pure_is_pair(const pure_expr *x) { if (x->tag == EXPR::APP && x->data.x[0]->tag == EXPR::APP) - return - x->data.x[0]->data.x[0]->tag == interpreter::g_interp->symtab.pair_sym().f; + return x->data.x[0]->data.x[0]->tag == interpreter::g_interp->symtab.pair_sym().f; else return false; } @@ -546,22 +544,16 @@ static bool pure_is_list(const pure_expr *x) { while (pure_is_cons(x)) - if (pure_is_pair(x->data.x[0]->data.x[1])) - return false; - else - x = x->data.x[1]; + x = x->data.x[1]; return pure_is_nil(x); } static bool pure_is_list(const pure_expr *x, list<const pure_expr*>& xs) { - while (pure_is_cons(x)) - if (pure_is_pair(x->data.x[0]->data.x[1])) - return false; - else { - xs.push_back(x->data.x[0]->data.x[1]); - x = x->data.x[1]; - } + while (pure_is_cons(x)) { + xs.push_back(x->data.x[0]->data.x[1]); + x = x->data.x[1]; + } return pure_is_nil(x); } @@ -681,7 +673,7 @@ // proper list value size_t n = xs.size(); os << "["; - if (n>1) { + if (n>1 || n==1 && pure_is_pair(xs.front())) { // list elements at a precedence not larger than ',' have to be // parenthesized p = sym_nprec(interpreter::g_interp->symtab.pair_sym().f) + 1; Modified: pure/trunk/test/test015.log =================================================================== --- pure/trunk/test/test015.log 2008-08-17 09:51:09 UTC (rev 517) +++ pure/trunk/test/test015.log 2008-08-17 11:25:34 UTC (rev 518) @@ -196,25 +196,25 @@ state 1: #0 }) (11..20)); { - rule #0: c = hdict$zipwith (=>) (catmap (\i -> (i,double i,str i):[]) (1..10)) (1..10) + rule #0: c = hdict$zipwith (=>) (catmap (\i -> [(i,double i,str i)]) (1..10)) (1..10) state 0: #0 <var> state 1 state 1: #0 } -let c = hdict$zipwith (=>) (catmap (\i/*0:*/ -> (i/*0:*/,double i/*0:*/,str i/*0:*/):[] { - rule #0: i = (i,double i,str i):[] +let c = hdict$zipwith (=>) (catmap (\i/*0:*/ -> [(i/*0:*/,double i/*0:*/,str i/*0:*/)] { + rule #0: i = [(i,double i,str i)] state 0: #0 <var> state 1 state 1: #0 }) (1..10)) (1..10); { - rule #0: d = hdict$zipwith (=>) (catmap (\i -> (i,double i,str i):[]) (11..20)) (11..20) + rule #0: d = hdict$zipwith (=>) (catmap (\i -> [(i,double i,str i)]) (11..20)) (11..20) state 0: #0 <var> state 1 state 1: #0 } -let d = hdict$zipwith (=>) (catmap (\i/*0:*/ -> (i/*0:*/,double i/*0:*/,str i/*0:*/):[] { - rule #0: i = (i,double i,str i):[] +let d = hdict$zipwith (=>) (catmap (\i/*0:*/ -> [(i/*0:*/,double i/*0:*/,str i/*0:*/)] { + rule #0: i = [(i,double i,str i)] state 0: #0 <var> state 1 state 1: #0 @@ -238,8 +238,8 @@ Dict (bin "4" "4" 0 (bin "2" "2" 1 (bin "1" "1" (-1) nil (bin "10" "10" 0 nil nil)) (bin "3" "3" 0 nil nil)) (bin "6" "6" (-1) (bin "5" "5" 0 nil nil) (bin "8" "8" 0 (bin "7" "7" 0 nil nil) (bin "9" "9" 0 nil nil)))) mkdict 1000 (1..10); Dict (bin 4 1000 (-1) (bin 2 1000 0 (bin 1 1000 0 nil nil) (bin 3 1000 0 nil nil)) (bin 8 1000 0 (bin 6 1000 0 (bin 5 1000 0 nil nil) (bin 7 1000 0 nil nil)) (bin 9 1000 (-1) nil (bin 10 1000 0 nil nil)))) -mkhdict 1000 (catmap (\i/*0:*/ -> (i/*0:*/,double i/*0:*/,str i/*0:*/):[] { - rule #0: i = (i,double i,str i):[] +mkhdict 1000 (catmap (\i/*0:*/ -> [(i/*0:*/,double i/*0:*/,str i/*0:*/)] { + rule #0: i = [(i,double i,str i)] state 0: #0 <var> state 1 state 1: #0 @@ -297,8 +297,8 @@ <stdin>:166.39-59: unhandled exception 'out_of_bounds' while evaluating 'c!(50,50.0,"50")' a!!(5..15); [5.0,6.0,7.0,8.0,9.0,10.0] -c!!catmap (\i/*0:*/ -> (i/*0:*/,double i/*0:*/,str i/*0:*/):[] { - rule #0: i = (i,double i,str i):[] +c!!catmap (\i/*0:*/ -> [(i/*0:*/,double i/*0:*/,str i/*0:*/)] { + rule #0: i = [(i,double i,str i)] state 0: #0 <var> state 1 state 1: #0 @@ -311,7 +311,7 @@ keys a; [1,2,3,4,5,6,7,8,9,10] keys c; -(1,1.0,"1"):(2,2.0,"2"):(3,3.0,"3"):(4,4.0,"4"):(5,5.0,"5"):(6,6.0,"6"):(7,7.0,"7"):(8,8.0,"8"):(9,9.0,"9"):(10,10.0,"10"):[] +[(1,1.0,"1"),(2,2.0,"2"),(3,3.0,"3"),(4,4.0,"4"),(5,5.0,"5"),(6,6.0,"6"),(7,7.0,"7"),(8,8.0,"8"),(9,9.0,"9"),(10,10.0,"10")] vals a; [1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0] vals c; @@ -328,8 +328,8 @@ Dict nil delete a 5000; Dict (bin 4 4.0 (-1) (bin 2 2.0 0 (bin 1 1.0 0 nil nil) (bin 3 3.0 0 nil nil)) (bin 8 8.0 0 (bin 6 6.0 0 (bin 5 5.0 0 nil nil) (bin 7 7.0 0 nil nil)) (bin 9 9.0 (-1) nil (bin 10 10.0 0 nil nil)))) -foldl delete c (catmap (\i/*0:*/ -> (i/*0:*/,double i/*0:*/,str i/*0:*/):[] { - rule #0: i = (i,double i,str i):[] +foldl delete c (catmap (\i/*0:*/ -> [(i/*0:*/,double i/*0:*/,str i/*0:*/)] { + rule #0: i = [(i,double i,str i)] state 0: #0 <var> state 1 state 1: #0 @@ -519,13 +519,13 @@ <stdin>:292.24-36: unhandled exception 'out_of_bounds' while evaluating 'c!(20,30)' a!!(5..15); [6,7,8,9,10] -c!!catmap (\i/*0:*/ -> catmap (\j/*0:*/ -> (i/*1:*/,j/*0:*/):[] { - rule #0: j = (i,j):[] +c!!catmap (\i/*0:*/ -> catmap (\j/*0:*/ -> [(i/*1:*/,j/*0:*/)] { + rule #0: j = [(i,j)] state 0: #0 <var> state 1 state 1: #0 }) (3..15) { - rule #0: i = catmap (\j -> (i,j):[]) (3..15) + rule #0: i = catmap (\j -> [(i,j)]) (3..15) state 0: #0 <var> state 1 state 1: #0 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-17 09:51:05
|
Revision: 517 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=517&view=rev Author: agraef Date: 2008-08-17 09:51:09 +0000 (Sun, 17 Aug 2008) Log Message: ----------- Add compilation flag values to expr data structure. Modified Paths: -------------- pure/trunk/expr.hh pure/trunk/interpreter.cc Modified: pure/trunk/expr.hh =================================================================== --- pure/trunk/expr.hh 2008-08-16 23:34:50 UTC (rev 516) +++ pure/trunk/expr.hh 2008-08-17 09:51:09 UTC (rev 517) @@ -115,6 +115,11 @@ WITH = -12, // with expression }; + // special flag values used during compilation: + enum { + OVF = 1, // overflowed int constant -> bigint + }; + uint32_t refc; // reference counter int32_t tag; // type tag or nullary symbol @@ -143,8 +148,8 @@ // matching automaton (LAMBDA, CASE; vector for WHEN): matcher *m; - // KLUDGE: overflowed int constant, needed to properly handle -0x8000000 - bool c; + // compilation flags: + uint16_t flags; // extra built-in type tag used in code generation: int8_t ttag; @@ -159,54 +164,54 @@ static EXPR *newref(EXPR *x) { return x?x->incref():0; } EXPR(int32_t _tag) : - refc(0), tag(_tag), m(0), c(false), ttag(0), astag(0), aspath(0) { } + refc(0), tag(_tag), m(0), flags(0), ttag(0), astag(0), aspath(0) { } EXPR(int32_t _tag, int32_t _vtag, uint8_t _idx, int8_t _ttag = 0, const path& _p = path()) : - refc(0), tag(_tag), m(0), c(false), ttag(_ttag), astag(0), aspath(0) + refc(0), tag(_tag), m(0), flags(0), ttag(_ttag), astag(0), aspath(0) { assert(_tag == VAR || _tag == FVAR); data.v.vtag = _vtag; data.v.idx = _idx; data.v.p = (_tag == VAR)?new path(_p):0; } EXPR(int32_t _tag, int32_t _i) : - refc(0), tag(_tag), m(0), c(false), ttag(_tag), astag(0), aspath(0) + refc(0), tag(_tag), m(0), flags(0), ttag(_tag), astag(0), aspath(0) { assert(_tag == INT); data.i = _i; } - EXPR(int32_t _tag, mpz_t _z, bool _c = false) : - refc(0), tag(_tag), m(0), c(_c), ttag(_tag), astag(0), aspath(0) + EXPR(int32_t _tag, mpz_t _z, bool c = false) : + refc(0), tag(_tag), m(0), flags(c?OVF:0), ttag(_tag), astag(0), aspath(0) { assert(_tag == BIGINT); mpz_init_set(data.z, _z); mpz_clear(_z); } EXPR(int32_t _tag, double _d) : - refc(0), tag(_tag), m(0), c(false), ttag(_tag), astag(0), aspath(0) + refc(0), tag(_tag), m(0), flags(0), ttag(_tag), astag(0), aspath(0) { assert(_tag == DBL); data.d = _d; } explicit EXPR(int32_t _tag, char *_s) : - refc(0), tag(_tag), m(0), c(false), ttag(_tag), astag(0), aspath(0) + refc(0), tag(_tag), m(0), flags(0), ttag(_tag), astag(0), aspath(0) { assert(_tag == STR); data.s = _s; } explicit EXPR(int32_t _tag, void *_p) : - refc(0), tag(_tag), m(0), c(false), ttag(_tag), astag(0), aspath(0) + refc(0), tag(_tag), m(0), flags(0), ttag(_tag), astag(0), aspath(0) { assert(_tag == PTR); data.p = _p; } EXPR(int32_t _tag, EXPR *_arg1, EXPR *_arg2, EXPR *_arg3) : - refc(0), tag(_tag), m(0), c(false), ttag(0), astag(0), aspath(0) + refc(0), tag(_tag), m(0), flags(0), ttag(0), astag(0), aspath(0) { assert(_tag == COND); data.x[0] = newref(_arg1); data.x[1] = newref(_arg2); data.x[2] = newref(_arg3); } EXPR(int32_t _tag, EXPR *_arg, EXPR *_body) : - refc(0), tag(_tag), m(0), c(false), ttag(0), astag(0), aspath(0) + refc(0), tag(_tag), m(0), flags(0), ttag(0), astag(0), aspath(0) { assert(_tag == LAMBDA); data.x[0] = newref(_arg); data.x[1] = newref(_body); } EXPR(int32_t _tag, EXPR *_arg, rulel *_rules) : - refc(0), tag(_tag), m(0), c(false), ttag(0), astag(0), aspath(0) + refc(0), tag(_tag), m(0), flags(0), ttag(0), astag(0), aspath(0) { assert(_tag == CASE || _tag == WHEN); data.c.x = newref(_arg); data.c.r = _rules; } EXPR(int32_t _tag, EXPR *_arg, env *_e) : - refc(0), tag(_tag), m(0), c(false), ttag(0), astag(0), aspath(0) + refc(0), tag(_tag), m(0), flags(0), ttag(0), astag(0), aspath(0) { assert(_tag == WITH); data.c.x = newref(_arg); data.c.e = _e; } EXPR(EXPR *_fun, EXPR *_arg) : - refc(0), tag(APP), m(0), c(false), ttag(0), astag(0), aspath(0) + refc(0), tag(APP), m(0), flags(0), ttag(0), astag(0), aspath(0) { data.x[0] = newref(_fun); data.x[1] = newref(_arg); } EXPR(EXPR *_fun, EXPR *_arg1, EXPR *_arg2) : - refc(0), tag(APP), m(0), c(false), ttag(0), astag(0), aspath(0) + refc(0), tag(APP), m(0), flags(0), ttag(0), astag(0), aspath(0) { data.x[0] = new EXPR(_fun, _arg1); data.x[0]->incref(); data.x[1] = newref(_arg2); } EXPR(EXPR *_fun, EXPR *_arg1, EXPR *_arg2, EXPR *_arg3) : - refc(0), tag(APP), m(0), c(false), ttag(0), astag(0), aspath(0) + refc(0), tag(APP), m(0), flags(0), ttag(0), astag(0), aspath(0) { data.x[0] = new EXPR(_fun, _arg1, _arg2); data.x[0]->incref(); data.x[1] = newref(_arg3); } @@ -340,7 +345,7 @@ p->tag == EXPR::CASE || p->tag == EXPR::WHEN); return p->m; } - bool cint() const { return p->c; } + uint16_t&flags() const { return p->flags; } int32_t astag() const { return p->astag; } path &aspath() const { assert(p->aspath); return *p->aspath; } Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-08-16 23:34:50 UTC (rev 516) +++ pure/trunk/interpreter.cc 2008-08-17 09:51:09 UTC (rev 517) @@ -1748,7 +1748,7 @@ } expr *y; // handle special case of a numeric argument - if (x->tag() == EXPR::BIGINT && x->cint() && + if (x->tag() == EXPR::BIGINT && (x->flags()&EXPR::OVF) && mpz_cmp_ui(x->zval(), 0x80000000U) == 0) // The negated int 0x80000000 can actually be represented as a machine int // value, we convert it back on the fly here. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-16 23:34:39
|
Revision: 516 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=516&view=rev Author: agraef Date: 2008-08-16 23:34:50 +0000 (Sat, 16 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-16 23:13:37 UTC (rev 515) +++ pure/trunk/pure.1.in 2008-08-16 23:34:50 UTC (rev 516) @@ -677,7 +677,7 @@ list and pair constructors `:' and `,' and the constant symbols `[]' and `()' denoting the empty list and tuple, respectively. .TP -.B Using clause: using \fIname\fR ...; +.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 @@ -728,9 +728,8 @@ .PP Note that the .B using -clause also has an alternative form which works differently and allows dynamic -libraries to be loaded, this will be discussed in the C INTERFACE section -below. +clause also has an alternative form which allows dynamic libraries to be +loaded, this will be discussed in the C INTERFACE section below. .SH EXCEPTION HANDLING Pure also offers a useful exception handling facility. To raise an exception, you just invoke the built-in function @@ -854,6 +853,14 @@ 0.29552020666134 .fi .sp +Multiple prototypes can be given in one +.B extern +declaration, separating them with commas: +.sp +.nf +\fBextern\fP double sin(double), double cos(double), double tan(double); +.fi +.sp For clarity, the parameter types can also be annotated with parameter names, e.g.: .sp @@ -877,12 +884,12 @@ .PP A variety of C integer types (char, short, int, long) are provided which are converted from/to the available Pure integer types in a straightforward -way. One important thing to note here is that the the `long' type +way. One important thing to note here is that the `long' type .I always denotes 64 bit integers, even if the corresponding C type is actually 32 bit -(as it usually is on most contemporary systems). All integer parameter types -take both Pure ints and bigints as arguments; truncation or sign extension is -performed as needed, so that the C interface behaves as if the argument was +(as it usually is on most contemporary systems). All integer parameters take +both Pure ints and bigints as actual arguments; truncation or sign extension +is performed as needed, so that the C interface behaves as if the argument was ``cast'' to the C target type. Returned integers use the smallest Pure type capable of holding the result (i.e., int for the C char, short and int types, bigint for long a.k.a. 64 bit integers). This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-16 23:13:27
|
Revision: 515 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=515&view=rev Author: agraef Date: 2008-08-16 23:13:37 +0000 (Sat, 16 Aug 2008) Log Message: ----------- Revised 'using' syntax so that script names are now separated with a comma. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/lexer.ll pure/trunk/lib/prelude.pure pure/trunk/parser.yy pure/trunk/test/test015.pure Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-08-16 22:46:01 UTC (rev 514) +++ pure/trunk/ChangeLog 2008-08-16 23:13:37 UTC (rev 515) @@ -1,3 +1,9 @@ +2008-08-17 Albert Graef <Dr....@t-...> + + * parser.yy, lexer.ll: Revised 'using' syntax so that script names + are now separated with a comma. Updated library and sample scripts + accordingly. + 2008-08-16 Albert Graef <Dr....@t-...> * pure.cc (main): More robust test for presence of the prelude. Modified: pure/trunk/lexer.ll =================================================================== --- pure/trunk/lexer.ll 2008-08-16 22:46:01 UTC (rev 514) +++ pure/trunk/lexer.ll 2008-08-16 23:13:37 UTC (rev 515) @@ -229,7 +229,7 @@ strtag ::{blank}*string ptrtag ::{blank}*pointer -%x comment xdecl xdecl_comment +%x comment xdecl xdecl_comment xusing xusing_comment %{ # define YY_USER_ACTION yylloc->columns(yyleng); @@ -266,13 +266,42 @@ interp.error(*yylloc, msg); BEGIN(INITIAL); return token::ERRTOK; } - <xdecl_comment>[^*\n]* yylloc->step(); <xdecl_comment>"*"+[^*/\n]* yylloc->step(); <xdecl_comment>[\n]+ yylloc->lines(yyleng); yylloc->step(); <xdecl_comment>"*"+"/" yylloc->step(); BEGIN(xdecl); +<xusing>{id} yylval->sval = new string(yytext); return token::ID; +<xusing>, return yy::parser::token_type(yytext[0]); +<xusing>"//".* yylloc->step(); +<xusing>"/*" BEGIN(xusing_comment); +<xusing>; BEGIN(INITIAL); return yy::parser::token_type(yytext[0]); +<xusing>{blank}+ yylloc->step(); +<xusing>[\n]+ yylloc->lines(yyleng); yylloc->step(); +<xusing>\"{str}\" { + char *msg; + yytext[yyleng-1] = 0; + yylval->csval = parsestr(yytext+1, msg); + yytext[yyleng-1] = '"'; + if (msg) interp.error(*yylloc, msg); + return token::STR; +} +<xusing>\"{str} { + interp.error(*yylloc, "unterminated string constant"); + BEGIN(INITIAL); return token::ERRTOK; +} +<xusing>. { + string msg = "invalid character '"+string(yytext)+"'"; + interp.error(*yylloc, msg); + BEGIN(INITIAL); return token::ERRTOK; +} + +<xusing_comment>[^*\n]* yylloc->step(); +<xusing_comment>"*"+[^*/\n]* yylloc->step(); +<xusing_comment>[\n]+ yylloc->lines(yyleng); yylloc->step(); +<xusing_comment>"*"+"/" yylloc->step(); BEGIN(xusing); + ^!{blank}*.* { // shell escape is only permitted in interactive mode if (!interp.interactive) REJECT; @@ -801,7 +830,7 @@ otherwise return token::OTHERWISE; when return token::WHEN; with return token::WITH; -using return token::USING; +using BEGIN(xusing); return token::USING; {id} { if (interp.declare_op) { yylval->sval = new string(yytext); Modified: pure/trunk/lib/prelude.pure =================================================================== --- pure/trunk/lib/prelude.pure 2008-08-16 22:46:01 UTC (rev 514) +++ pure/trunk/lib/prelude.pure 2008-08-16 23:13:37 UTC (rev 515) @@ -72,7 +72,7 @@ Note that the math and system modules are *not* included here, so you have to do that yourself if your program requires any of those operations. */ -using primitives strings; +using primitives, strings; /* Basic combinators. */ Modified: pure/trunk/parser.yy =================================================================== --- pure/trunk/parser.yy 2008-08-16 22:46:01 UTC (rev 514) +++ pure/trunk/parser.yy 2008-08-16 23:13:37 UTC (rev 515) @@ -313,8 +313,8 @@ names : name { $$ = new list<string>; $$->push_back(*$1); delete $1; } -| names name -{ $$ = $1; $$->push_back(*$2); delete $2; } +| names ',' name +{ $$ = $1; $$->push_back(*$3); delete $3; } ; name Modified: pure/trunk/test/test015.pure =================================================================== --- pure/trunk/test/test015.pure 2008-08-16 22:46:01 UTC (rev 514) +++ pure/trunk/test/test015.pure 2008-08-16 23:13:37 UTC (rev 515) @@ -1,6 +1,6 @@ // Some tests for set and bag data containers -using array dict heap set; +using array, dict, heap, set; // List of 1000 random integers from interval <0; 99> for stress tests let randlist = This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-16 22:45:51
|
Revision: 514 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=514&view=rev Author: agraef Date: 2008-08-16 22:46:01 +0000 (Sat, 16 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-16 21:44:56 UTC (rev 513) +++ pure/trunk/pure.1.in 2008-08-16 22:46:01 UTC (rev 514) @@ -645,7 +645,7 @@ .B using clauses which provide a simple include file mechanism. .TP -.B Operator and constant declarations: infix \fIlevel\fP \fIop\fR ...; +.B Operator and constant declarations: infix \fIlevel\fP \fIop\fP\fR ...;\fP nullary \fIsymbol\fP\fR ...;\fP 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) @@ -664,10 +664,12 @@ 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: +Similarly, constant symbols are introduced using a +.B nullary +declaration, e.g.: .sp .nf -\fBnullary \fIsymbol\fR ...; +\fBnullary\fP [] () nil; .fi .sp Examples for all of these can be found in the prelude which declares a bunch @@ -682,17 +684,53 @@ 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 +clause. +.sp +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 +searched for first in the directory of the script containing the +.B using +clause, then the directory named by the .B PURELIB -environment variable. (The +environment variable, and finally in the current working directory. This is +different from the standard search order used for scripts specified on the +command line, where the current directory is searched prior to the +.B PURELIB +directory. The search order employed here lets you install a script into any +directory, along with any other required non-library scripts, and run the +script from there. (Note that this will only work if the .B using -clause also has an alternative form which allows dynamic libraries to be -loaded, this will be discussed in the C INTERFACE section.) +clause is contained in a script file, but not if the clause is read from +standard input or entered interactively. In the latter case the normal search +order is used.) +.sp +For the purpose of comparing and loading scripts, the interpreter always uses +the canonicalized full pathname of the script, following symbolic links to the +destination file (albeit only one level). Thus different scripts with the same +basename, such as +.B foo/utils.pure +and +.B bar/utils.pure +can both be included in the same program (unless they link to the same +file). The resolution of symbolic links also makes it possible to have an +executable script with a shebang line in its own directory, to be executed via +a symbolic link placed on the system +.BR PATH . +In this case the script search performed in +.B using +clauses will use the real script directory and thus other required scripts can +be located in the script directory as usual. This is the recommended practice +for installing standalone Pure applications in source form which are to be run +directly from the shell. +.PP +Note that the +.B using +clause also has an alternative form which works differently and allows dynamic +libraries to be loaded, this will be discussed in the C INTERFACE section +below. .SH EXCEPTION HANDLING Pure also offers a useful exception handling facility. To raise an exception, you just invoke the built-in function @@ -1024,13 +1062,18 @@ Loads the given script file and adds its definitions to the current environment. This works more or less like a .B using -clause, but loads the script ``anonymously'', as if the contents of the script -had been typed at the command prompt. That is, +clause, but uses the standard search order and loads the script +``anonymously'', as if the contents of the script had been typed at the +command prompt. That is, .B run doesn't check whether the script is being used already and it puts the definitions on the current temporary level (so that .B clear -can be used to remove them again). +can be used to remove them again). In particular, this makes it possible to +quickly reload a script without exiting the interpreter, by issuing the +.B clear +command followed by +.BR run . .TP .B save Begin a new level of temporary definitions. A subsequent @@ -1586,7 +1629,7 @@ .B PURE_MORE Shell command to be used for paging through output of the .B list -command, when the interpreter runs in interactive mode. +command, when the interpreter runs in interactive mode (default: none). .TP .B PURE_PS Command prompt used in the interactive command loop (">\ " by default). This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-16 21:44:46
|
Revision: 513 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=513&view=rev Author: agraef Date: 2008-08-16 21:44:56 +0000 (Sat, 16 Aug 2008) Log Message: ----------- More robust test for presence of the prelude. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/pure.cc Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-08-16 21:27:39 UTC (rev 512) +++ pure/trunk/ChangeLog 2008-08-16 21:44:56 UTC (rev 513) @@ -1,5 +1,7 @@ 2008-08-16 Albert Graef <Dr....@t-...> + * pure.cc (main): More robust test for presence of the prelude. + * interpreter.cc, lexer.ll: Implemented new script search algorithm, as discussed on the mailing list. Modified: pure/trunk/pure.cc =================================================================== --- pure/trunk/pure.cc 2008-08-16 21:27:39 UTC (rev 512) +++ pure/trunk/pure.cc 2008-08-16 21:44:56 UTC (rev 513) @@ -5,6 +5,8 @@ #include <iostream> #include <stdio.h> #include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> #include <unistd.h> #include <locale.h> #include <signal.h> @@ -174,6 +176,12 @@ if (histfile) write_history(histfile); } +static inline bool chkfile(const string& s) +{ + struct stat st; + return !stat(s.c_str(), &st) && !S_ISDIR(st.st_mode); +} + int main(int argc, char *argv[]) { @@ -272,15 +280,12 @@ interp.init_sys_vars(PACKAGE_VERSION, HOST, myargs); if (want_prelude) { // load the prelude if we can find it - FILE *fp = fopen("prelude.pure", "r"); - if (fp) + if (chkfile("prelude.pure")) { prelude = "prelude.pure"; - else - // try again in the PURELIB directory - fp = fopen(prelude.c_str(), "r"); - if (fp) { - fclose(fp); have_prelude = true; + } else if (chkfile(prelude)) // try again in the PURELIB directory + have_prelude = true; + if (have_prelude) { interp.run(prelude); interp.compile(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-16 21:27:32
|
Revision: 512 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=512&view=rev Author: agraef Date: 2008-08-16 21:27:39 +0000 (Sat, 16 Aug 2008) Log Message: ----------- Implement new script search algorithm. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/interpreter.cc pure/trunk/interpreter.hh pure/trunk/lexer.ll Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-08-16 00:54:21 UTC (rev 511) +++ pure/trunk/ChangeLog 2008-08-16 21:27:39 UTC (rev 512) @@ -1,3 +1,24 @@ +2008-08-16 Albert Graef <Dr....@t-...> + + * interpreter.cc, lexer.ll: Implemented new script search + algorithm, as discussed on the mailing list. + + Scripts loaded with a 'using' clause are now first searched in the + directory of the script containing the 'using' clause, then in the + PURELIB directory and finally in the current directory. This + allows scripts to be installed in their own directory, along with + any other non-library modules they need. Scripts specified on the + command line or with the 'run' command are searched for in the + current directory and then in the PURELIB directory, as before. + + Script names are now "canonicalized" by following symbolic links + (albeit only one level) and removing '.' and '..' directory + components in the absolute pathname. Also, checking whether a + script has already been loaded now uses the canonicalized pathname + so that, e.g., two scripts foo/baz.pure and bar/baz.pure are + considered distinct modules and can both be used in the same + program (unless they link to the same script file). + 2008-08-15 Albert Graef <Dr....@t-...> * test/test018.pure: Add test for integer marshalling. Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-08-16 00:54:21 UTC (rev 511) +++ pure/trunk/interpreter.cc 2008-08-16 21:27:39 UTC (rev 512) @@ -387,6 +387,124 @@ } } +/* Search for a source file. Absolute file names (starting with a slash) are + taken as is. Relative pathnames are resolved using the following algorithm: + If srcdir is nonempty, search it first, then libdir (if nonempty), then the + current working directory. If srcdir is empty, first search the current + directory, then libdir (if nonempty). In either case, if the resulting + absolute pathname is a symbolic link, the destination is used instead, and + finally the pathname is canonicalized. */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +static inline string dirname(const string& fname) +{ + size_t pos = fname.rfind('/'); + if (pos == string::npos) + return ""; + else + return fname.substr(0, pos+1); +} + +static inline string basename(const string& fname) +{ + size_t pos = fname.rfind('/'); + if (pos == string::npos) + return fname; + else + return fname.substr(pos+1); +} + +static inline bool chkfile(const string& s) +{ + struct stat st; + return !stat(s.c_str(), &st) && !S_ISDIR(st.st_mode); +} + +#ifndef _WIN32 +static inline bool chklink(const string& s) +{ + struct stat st; + return !lstat(s.c_str(), &st) && S_ISLNK(st.st_mode); +} +#endif + +#define BUFSIZE 1024 + +static string searchdir(const string& srcdir, const string& libdir, + const string& script) +{ + char cwd[BUFSIZE]; + if (script.empty()) + return script; + else if (!getcwd(cwd, BUFSIZE)) { + perror("getcwd"); + return script; + } + string workdir = cwd; + if (!workdir.empty() && workdir[workdir.size()-1] != '/') + workdir += "/"; + string fname; + if (script[0] != '/') { + // resolve relative pathname + if (srcdir.empty()) { + fname = workdir+script; + if (chkfile(fname)) goto found; + if (!libdir.empty()) { + fname = libdir+script; + if (chkfile(fname)) goto found; + } + fname = script; + } else { + fname = srcdir+script; + if (chkfile(fname)) goto found; + if (!libdir.empty()) { + fname = libdir+script; + if (chkfile(fname)) goto found; + } + fname = workdir+script; + if (chkfile(fname)) goto found; + fname = script; + } + } else + fname = script; + found: + if (fname[0] != '/') fname = workdir+fname; + char buf[BUFSIZE]; +#ifndef _WIN32 + if (chklink(fname)) { + // follow symbolic link to its destination + int l = readlink(fname.c_str(), buf, BUFSIZE-1); + if (l >= 0) { + buf[l] = 0; + string basedir = dirname(fname), linkname = buf; + string dir = dirname(linkname), name = basename(linkname); + if (dir.empty()) + dir = basedir; + else if (dir[0] != '/') + dir = basedir+dir; + fname = dir+name; + } else + perror("readlink"); + } +#endif + // canonicalize the pathname + string dir = dirname(fname), name = basename(fname); + if (chdir(dir.c_str())==0 && getcwd(buf, BUFSIZE)) { + string dir = buf; + if (!dir.empty() && dir[dir.size()-1] != '/') + dir += "/"; + fname = dir+name; + } + chdir(cwd); +#if DEBUG>1 + std::cerr << "search '" << script << "', found as '" << fname << "'\n"; +#endif + return fname; +} + // Run the interpreter on a source file, collection of source files, or on // string data. @@ -415,7 +533,8 @@ return 0; } // ordinary source file - if (check && sources.find(s) != sources.end()) + string fname = searchdir(srcdir, lib, s); + if (check && sources.find(fname) != sources.end()) // already loaded, skip return 0; // save local data @@ -424,6 +543,7 @@ int l_nerrs = nerrs; uint8_t l_temp = temp; const char *l_source_s = source_s; + string l_srcdir = srcdir; // save global data uint8_t s_verbose = g_verbose; bool s_interactive = g_interactive; @@ -435,11 +555,12 @@ nerrs = 0; source = s; declare_op = false; source_s = 0; + srcdir = dirname(fname); errmsg.clear(); if (check && !interactive) temp = 0; - bool ok = lex_begin(); + bool ok = lex_begin(fname); if (ok) { - if (temp == 0 && !s.empty()) sources.insert(s); + if (temp == 0 && !s.empty()) sources.insert(fname); yy::parser parser(*this); parser.set_debug_level((verbose&verbosity::parser) != 0); // parse @@ -460,6 +581,7 @@ nerrs = l_nerrs; temp = l_temp; source_s = l_source_s; + srcdir = l_srcdir; // return last computed result, if any return result; } @@ -488,6 +610,7 @@ string l_source = source; int l_nerrs = nerrs; const char *l_source_s = source_s; + string l_srcdir = srcdir; // save global data uint8_t s_verbose = g_verbose; bool s_interactive = g_interactive; @@ -499,6 +622,7 @@ nerrs = 0; source = ""; declare_op = false; source_s = s.c_str(); + srcdir = ""; errmsg.clear(); bool ok = lex_begin(); if (ok) { @@ -519,6 +643,7 @@ source_s = 0; nerrs = l_nerrs; source_s = l_source_s; + srcdir = l_srcdir; // return last computed result, if any return result; } Modified: pure/trunk/interpreter.hh =================================================================== --- pure/trunk/interpreter.hh 2008-08-16 00:54:21 UTC (rev 511) +++ pure/trunk/interpreter.hh 2008-08-16 21:27:39 UTC (rev 512) @@ -618,8 +618,9 @@ // Interface to the lexer. public: bool declare_op; + string srcdir; private: - bool lex_begin(); + bool lex_begin(const string& fname = ""); void lex_end(); }; Modified: pure/trunk/lexer.ll =================================================================== --- pure/trunk/lexer.ll 2008-08-16 00:54:21 UTC (rev 511) +++ pure/trunk/lexer.ll 2008-08-16 21:27:39 UTC (rev 512) @@ -852,19 +852,14 @@ %% bool -interpreter::lex_begin() +interpreter::lex_begin(const string& fname) { yy_flex_debug = (verbose&verbosity::lexer) != 0 && !source_s; if (source_s) yyin = 0; else if (source.empty()) yyin = stdin; - else if (!(yyin = fopen(source.c_str(), "r")) && source[0] != '/') { - string fname = lib+source; - if (!(yyin = fopen(fname.c_str(), "r"))) - perror(source.c_str()); - //error("cannot open '" + source + "'"); - } else if (!yyin) + else if (!(yyin = fopen(fname.c_str(), "r"))) //error("cannot open '" + source + "'"); perror(source.c_str()); if (source_s || yyin) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-16 00:54:12
|
Revision: 511 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=511&view=rev Author: agraef Date: 2008-08-16 00:54:21 +0000 (Sat, 16 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-15 10:41:43 UTC (rev 510) +++ pure/trunk/pure.1.in 2008-08-16 00:54:21 UTC (rev 511) @@ -309,19 +309,18 @@ syntactic sugar for list values in brackets, such as [x,y,z], which is exactly the same as x:y:z:[]. Moreover, the prelude also provides an infix `..' operator to denote arithmetic sequences such as 1..10 or 1.0,1.2..3.0. Pure's -tuples are a bit unusual, however: They are constructed by just ``paring'' -things using the `,' operator, for which the empty tuple acts as a neutral -element (i.e., (),x is just x, as is x,()). The pairing operator is -associative, which implies that tuples are completely flat (i.e., x,(y,z) is -just x,y,z, as is (x,y),z). This means that there are no nested tuples (tuples -of tuples), if you need such constructs then you should use lists -instead. Also note that the parentheses are \fInot\fP part of the tuple syntax -in Pure, although you \fIcan\fP use parentheses, just as with any other -expression, for the usual purpose of grouping expressions and overriding -default precedences and associativity. This means that a list of tuples will -be printed (and must also be entered) using the ``canonical'' representation -(x1,y1):(x2,y2):...:[] rather than [(x1,y1),(x2,y2),...] (which denotes just -[x1,y1,x2,y2,...]). +tuples are a bit unusual: They are constructed by just ``paring'' things using +the `,' operator, for which the empty tuple acts as a neutral element (i.e., +(),x is just x, as is x,()). The pairing operator is associative, which +implies that tuples are completely flat (i.e., x,(y,z) is just x,y,z, as is +(x,y),z). This means that there are no nested tuples (tuples of tuples), if +you need such constructs then you should use lists instead. Also note that the +parentheses are \fInot\fP part of the tuple syntax in Pure, although you +\fIcan\fP use parentheses, just as with any other expression, for the usual +purpose of grouping expressions and overriding default precedences and +associativity. This means that a list of tuples will be printed (and must also +be entered) using the ``canonical'' representation (x1,y1):(x2,y2):...:[] +rather than [(x1,y1),(x2,y2),...] (which denotes just [x1,y1,x2,y2,...]). .TP .B List comprehensions: \fR[x,y; x = 1..n; y = 1..m; x<y] Pure also has list comprehensions which generate lists from an expression and @@ -430,7 +429,8 @@ 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. +functions (also called ``rules''), constant and variable bindings, 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 @@ -462,6 +462,71 @@ A singleton expression at the toplevel, terminated with a semicolon, simply causes the given value to be evaluated (and the result to be printed, when running in interactive mode). +.PP +Here are a few examples showing how the above constructs are used (see the +following section for a closer discussion of the rule syntax). +.PP +The factorial: +.sp +.nf +fact n = n*fact (n-1) \fBif\fP n>0; + = 1 \fBotherwise\fP; +.fi +.PP +The Fibonacci numbers: +.sp +.nf +fib n = a \fBwhen\fP a, b = fibs n \fBend\fP + \fBwith\fP fibs n = 0, 1 \fBif\fP n<=0; + = \fBcase\fP fibs (n-1) \fBof\fP + a, b = b, a+b; + \fBend\fP; + \fBend\fP; + +\fBlet\fP fibs = map fib (1..30); +fibs; +.fi +.PP +A little list comprehension example (Erathosthenes' classical prime sieve): +.sp +.nf +primes n = sieve (2..n) \fBwith\fP + sieve [] = []; + sieve (p:qs) = p : sieve [q; q = qs; q mod p]; +\fBend\fP; +.fi +.sp +For instance: +.sp +.nf +> primes 100; +[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97] +.fi +.PP +If you dare, you can actually have a look at the catmap-lambda-if-then-else +expression the comprehension expanded to: +.sp +.nf +> \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 +.PP +List comprehensions are also a useful device to organize backtracking +searches. For instance, here's an algorithm for the n queens problem, which +returns the list of all placements of n queens on an n x n board (encoded as +lists of n pairs (i,j) with i = 1..n), so that no two queens hold each other +in check. +.sp +.nf +queens n = search n 1 [] \fBwith\fP + search n i p = [reverse p] \fBif\fP i>n; + = cat [search n (i+1) ((i,j):p); j = 1..n; safe (i,j) p]; + safe (i,j) p = not any (check (i,j)) p; + check (i1,j1) (i2,j2) + = i1==i2 || j1==j2 || i1+j1==i2+j2 || i1-j1==i2-j2; +\fBend\fP; +.fi .SH RULE SYNTAX Basically, the same rule syntax is used to define functions at the toplevel and in \fBwith\fP expressions, as well as inside \fBcase\fP, \fBwhen\fP, @@ -566,63 +631,6 @@ .nf \fBcase\fP ans \fBof\fP "y" | "Y" = 1; _ = 0; \fBend\fP; .fi -.PP -Here are a few more examples of rules illustrating some of the constructs -introduced above and in the previous section. The first one is a definition of -a function which generates the Fibonacci numbers: -.sp -.nf -fib n = a \fBwhen\fP a, b = fibs n \fBend\fP - \fBwith\fP fibs n = 0, 1 \fBif\fP n<=0; - = \fBcase\fP fibs (n-1) \fBof\fP - a, b = b, a+b; - \fBend\fP; - \fBend\fP; - -\fBlet\fP fibs = map fib (1..100); -fibs; -.fi -.PP -A little list comprehension example (Erathosthenes' classical prime sieve): -.sp -.nf -primes n = sieve (2..n) \fBwith\fP - sieve [] = []; - sieve (p:qs) = p : sieve [q; q = qs; q mod p]; -\fBend\fP; -.fi -.sp -For instance: -.sp -.nf -> primes 100; -[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97] -.fi -.PP -If you dare, you can actually have a look at the catmap-lambda-if-then-else -expression the comprehension expanded to: -.sp -.nf -> \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 -.PP -We mention in passing that list comprehensions are also a useful device to -organize backtracking searches. For instance, here's an algorithm for the n -queens problem, which returns the list of all placements of n queens on an n x -n board (encoded as lists of n pairs (i,j) with i = 1..n), so that no two -queens hold each other in check. -.sp -.nf -queens n = search n 1 [] \fBwith\fP - search n i p = [reverse p] \fBif\fP i>n; - = cat [search n (i+1) ((i,j):p); j = 1..n; safe (i,j) p]; - safe (i,j) p = not any (check (i,j)) p; - check (i1,j1) (i2,j2) - = 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, @@ -820,28 +828,35 @@ .PP The interpreter makes sure that the parameters in a call match; if not, the 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. +extend the external function with your own Pure equations (see below). 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 -straightfoward way. The short type indicates 16 bit integers which are -converted from/to Pure machine ints using truncation and sign extension, -respectively. The char type, which denotes 8 bit integers, is treated -analogously. The long type +Single precision float arguments and return values are converted from/to +Pure's double precision floating point numbers automatically. +.PP +A variety of C integer types (char, short, int, long) are provided which are +converted from/to the available Pure integer types in a straightforward +way. One important thing to note here is that the the `long' type .I always denotes 64 bit integers, even if the corresponding C type is actually 32 bit -(as it usually is on most contemporary systems). This type is to be used if a -C function takes or returns 64 bit integer values. For a long parameter you -can either pass a Pure machine int (which is sign-extended to 64 bit) or a -Pure bigint (which is truncated to 64 bit if necessary). 64 bit return values -are always converted to (signed) Pure bigints. +(as it usually is on most contemporary systems). All integer parameter types +take both Pure ints and bigints as arguments; truncation or sign extension is +performed as needed, so that the C interface behaves as if the argument was +``cast'' to the C target type. Returned integers use the smallest Pure type +capable of holding the result (i.e., int for the C char, short and int types, +bigint for long a.k.a. 64 bit integers). .PP -Similarly, single precision float arguments and return values are converted -from/to Pure's double precision floating point numbers automatically. +Pure considers all integers as signed quantities, but it is possible to pass +unsigned integers as well (if necessary, you can use a bigint to pass positive +values which are too big to fit into a machine int). Also note that when an +unsigned integer is returned by a C routine which is too big to fit into the +corresponding signed integer type, it will become negative. In this case, +depending on the target type, you can use the ubyte, ushort, uint and ulong +functions provided by the prelude to convert the result back to an unsigned +quantity. .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 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-15 10:41:33
|
Revision: 510 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=510&view=rev Author: agraef Date: 2008-08-15 10:41:43 +0000 (Fri, 15 Aug 2008) Log Message: ----------- Add test for integer marshalling. Modified Paths: -------------- pure/trunk/ChangeLog Added Paths: ----------- pure/trunk/test/test018.log pure/trunk/test/test018.pure Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-08-15 10:31:59 UTC (rev 509) +++ pure/trunk/ChangeLog 2008-08-15 10:41:43 UTC (rev 510) @@ -1,5 +1,7 @@ 2008-08-15 Albert Graef <Dr....@t-...> + * test/test018.pure: Add test for integer marshalling. + * interpreter.cc (declare_extern): All C int parameter types now handle bigint arguments. Added: pure/trunk/test/test018.log =================================================================== --- pure/trunk/test/test018.log (rev 0) +++ pure/trunk/test/test018.log 2008-08-15 10:41:43 UTC (rev 510) @@ -0,0 +1,88 @@ +sprintf "%d" 2147483647; +"2147483647" +sprintf "%d" 2147483648L; +"-2147483648" +sprintf "%d" 4294967295L; +"-1" +sprintf "%d" (-2147483647); +"-2147483647" +sprintf "%d" (-2147483648); +"-2147483648" +sprintf "%d" (-4294967295L); +"1" +sprintf "%d" 2147483647L; +"2147483647" +sprintf "%d" 2147483648L; +"-2147483648" +sprintf "%d" 4294967295L; +"-1" +sprintf "%d" (-2147483647L); +"-2147483647" +sprintf "%d" (-2147483648L); +"-2147483648" +sprintf "%d" (-4294967295L); +"1" +sprintf "%u" 2147483647; +"2147483647" +sprintf "%u" 2147483648L; +"2147483648" +sprintf "%u" 4294967295L; +"4294967295" +sprintf "%u" (-2147483647); +"2147483649" +sprintf "%u" (-2147483648); +"2147483648" +sprintf "%u" (-4294967295L); +"1" +sprintf "%u" 2147483647L; +"2147483647" +sprintf "%u" 2147483648L; +"2147483648" +sprintf "%u" 4294967295L; +"4294967295" +sprintf "%u" (-2147483647L); +"2147483649" +sprintf "%u" (-2147483648L); +"2147483648" +sprintf "%u" (-4294967295L); +"1" +sprintf "%x" 2147483647; +"7fffffff" +sprintf "%x" 2147483648L; +"80000000" +sprintf "%x" 4294967295L; +"ffffffff" +sprintf "%x" (-2147483647); +"80000001" +sprintf "%x" (-2147483648); +"80000000" +sprintf "%x" (-4294967295L); +"1" +sprintf "%x" 2147483647L; +"7fffffff" +sprintf "%x" 2147483648L; +"80000000" +sprintf "%x" 4294967295L; +"ffffffff" +sprintf "%x" (-2147483647L); +"80000001" +sprintf "%x" (-2147483648L); +"80000000" +sprintf "%x" (-4294967295L); +"1" +ord$sprintf "%c" 128; +128 +ord$sprintf "%c" 255; +255 +ord$sprintf "%c" 128L; +128 +ord$sprintf "%c" 255L; +255 +sscanf "ffffffff" "%x"; +-1 +uint$sscanf "ffffffff" "%x"; +4294967295L +sscanf "4294967295" "%u"; +-1 +uint$sscanf "4294967295" "%u"; +4294967295L Added: pure/trunk/test/test018.pure =================================================================== --- pure/trunk/test/test018.pure (rev 0) +++ pure/trunk/test/test018.pure 2008-08-15 10:41:43 UTC (rev 510) @@ -0,0 +1,67 @@ + +// check integer marshalling of the C interface +// (this isn't exhaustive, but should cover the most important cases) + +using system; + +// signed parameters + +sprintf "%d" 0x7fffffff; +sprintf "%d" 0x80000000; +sprintf "%d" 0xffffffff; +sprintf "%d" (-0x7fffffff); +sprintf "%d" (-0x80000000); +sprintf "%d" (-0xffffffff); + +sprintf "%d" 0x7fffffffL; +sprintf "%d" 0x80000000L; +sprintf "%d" 0xffffffffL; +sprintf "%d" (-0x7fffffffL); +sprintf "%d" (-0x80000000L); +sprintf "%d" (-0xffffffffL); + +// unsigned parameters + +sprintf "%u" 0x7fffffff; +sprintf "%u" 0x80000000; +sprintf "%u" 0xffffffff; +sprintf "%u" (-0x7fffffff); +sprintf "%u" (-0x80000000); +sprintf "%u" (-0xffffffff); + +sprintf "%u" 0x7fffffffL; +sprintf "%u" 0x80000000L; +sprintf "%u" 0xffffffffL; +sprintf "%u" (-0x7fffffffL); +sprintf "%u" (-0x80000000L); +sprintf "%u" (-0xffffffffL); + +// unsigned parameters (hex) + +sprintf "%x" 0x7fffffff; +sprintf "%x" 0x80000000; +sprintf "%x" 0xffffffff; +sprintf "%x" (-0x7fffffff); +sprintf "%x" (-0x80000000); +sprintf "%x" (-0xffffffff); + +sprintf "%x" 0x7fffffffL; +sprintf "%x" 0x80000000L; +sprintf "%x" 0xffffffffL; +sprintf "%x" (-0x7fffffffL); +sprintf "%x" (-0x80000000L); +sprintf "%x" (-0xffffffffL); + +// unsigned char + +ord $ sprintf "%c" 0x80; +ord $ sprintf "%c" 0xff; +ord $ sprintf "%c" 0x80L; +ord $ sprintf "%c" 0xffL; + +// unsigned return values + +sscanf "ffffffff" "%x"; +uint $ sscanf "ffffffff" "%x"; +sscanf "4294967295" "%u"; +uint $ sscanf "4294967295" "%u"; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-15 10:31:51
|
Revision: 509 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=509&view=rev Author: agraef Date: 2008-08-15 10:31:59 +0000 (Fri, 15 Aug 2008) Log Message: ----------- Fix treatment of negative bigint constants, so that an explicit bigint -0x80000000L doesn't get converted back to an int. Modified Paths: -------------- pure/trunk/expr.hh pure/trunk/interpreter.cc pure/trunk/lexer.ll pure/trunk/parser.yy Modified: pure/trunk/expr.hh =================================================================== --- pure/trunk/expr.hh 2008-08-15 09:15:37 UTC (rev 508) +++ pure/trunk/expr.hh 2008-08-15 10:31:59 UTC (rev 509) @@ -143,6 +143,9 @@ // matching automaton (LAMBDA, CASE; vector for WHEN): matcher *m; + // KLUDGE: overflowed int constant, needed to properly handle -0x8000000 + bool c; + // extra built-in type tag used in code generation: int8_t ttag; @@ -156,54 +159,54 @@ static EXPR *newref(EXPR *x) { return x?x->incref():0; } EXPR(int32_t _tag) : - refc(0), tag(_tag), m(0), ttag(0), astag(0), aspath(0) { } + refc(0), tag(_tag), m(0), c(false), ttag(0), astag(0), aspath(0) { } EXPR(int32_t _tag, int32_t _vtag, uint8_t _idx, int8_t _ttag = 0, const path& _p = path()) : - refc(0), tag(_tag), m(0), ttag(_ttag), astag(0), aspath(0) + refc(0), tag(_tag), m(0), c(false), ttag(_ttag), astag(0), aspath(0) { assert(_tag == VAR || _tag == FVAR); data.v.vtag = _vtag; data.v.idx = _idx; data.v.p = (_tag == VAR)?new path(_p):0; } EXPR(int32_t _tag, int32_t _i) : - refc(0), tag(_tag), m(0), ttag(_tag), astag(0), aspath(0) + refc(0), tag(_tag), m(0), c(false), ttag(_tag), astag(0), aspath(0) { assert(_tag == INT); data.i = _i; } - EXPR(int32_t _tag, mpz_t _z) : - refc(0), tag(_tag), m(0), ttag(_tag), astag(0), aspath(0) + EXPR(int32_t _tag, mpz_t _z, bool _c = false) : + refc(0), tag(_tag), m(0), c(_c), ttag(_tag), astag(0), aspath(0) { assert(_tag == BIGINT); mpz_init_set(data.z, _z); mpz_clear(_z); } EXPR(int32_t _tag, double _d) : - refc(0), tag(_tag), m(0), ttag(_tag), astag(0), aspath(0) + refc(0), tag(_tag), m(0), c(false), ttag(_tag), astag(0), aspath(0) { assert(_tag == DBL); data.d = _d; } explicit EXPR(int32_t _tag, char *_s) : - refc(0), tag(_tag), m(0), ttag(_tag), astag(0), aspath(0) + refc(0), tag(_tag), m(0), c(false), ttag(_tag), astag(0), aspath(0) { assert(_tag == STR); data.s = _s; } explicit EXPR(int32_t _tag, void *_p) : - refc(0), tag(_tag), m(0), ttag(_tag), astag(0), aspath(0) + refc(0), tag(_tag), m(0), c(false), ttag(_tag), astag(0), aspath(0) { assert(_tag == PTR); data.p = _p; } EXPR(int32_t _tag, EXPR *_arg1, EXPR *_arg2, EXPR *_arg3) : - refc(0), tag(_tag), m(0), ttag(0), astag(0), aspath(0) + refc(0), tag(_tag), m(0), c(false), ttag(0), astag(0), aspath(0) { assert(_tag == COND); data.x[0] = newref(_arg1); data.x[1] = newref(_arg2); data.x[2] = newref(_arg3); } EXPR(int32_t _tag, EXPR *_arg, EXPR *_body) : - refc(0), tag(_tag), m(0), ttag(0), astag(0), aspath(0) + refc(0), tag(_tag), m(0), c(false), ttag(0), astag(0), aspath(0) { assert(_tag == LAMBDA); data.x[0] = newref(_arg); data.x[1] = newref(_body); } EXPR(int32_t _tag, EXPR *_arg, rulel *_rules) : - refc(0), tag(_tag), m(0), ttag(0), astag(0), aspath(0) + refc(0), tag(_tag), m(0), c(false), ttag(0), astag(0), aspath(0) { assert(_tag == CASE || _tag == WHEN); data.c.x = newref(_arg); data.c.r = _rules; } EXPR(int32_t _tag, EXPR *_arg, env *_e) : - refc(0), tag(_tag), m(0), ttag(0), astag(0), aspath(0) + refc(0), tag(_tag), m(0), c(false), ttag(0), astag(0), aspath(0) { assert(_tag == WITH); data.c.x = newref(_arg); data.c.e = _e; } EXPR(EXPR *_fun, EXPR *_arg) : - refc(0), tag(APP), m(0), ttag(0), astag(0), aspath(0) + refc(0), tag(APP), m(0), c(false), ttag(0), astag(0), aspath(0) { data.x[0] = newref(_fun); data.x[1] = newref(_arg); } EXPR(EXPR *_fun, EXPR *_arg1, EXPR *_arg2) : - refc(0), tag(APP), m(0), ttag(0), astag(0), aspath(0) + refc(0), tag(APP), m(0), c(false), ttag(0), astag(0), aspath(0) { data.x[0] = new EXPR(_fun, _arg1); data.x[0]->incref(); data.x[1] = newref(_arg2); } EXPR(EXPR *_fun, EXPR *_arg1, EXPR *_arg2, EXPR *_arg3) : - refc(0), tag(APP), m(0), ttag(0), astag(0), aspath(0) + refc(0), tag(APP), m(0), c(false), ttag(0), astag(0), aspath(0) { data.x[0] = new EXPR(_fun, _arg1, _arg2); data.x[0]->incref(); data.x[1] = newref(_arg3); } @@ -253,8 +256,8 @@ p(new EXPR(tag, vtag, idx, ttag, _p)) { p->incref(); } expr(int32_t tag, int32_t i) : p(new EXPR(tag, i)) { p->incref(); } - expr(int32_t tag, mpz_t z) : - p(new EXPR(tag, z)) { p->incref(); } + expr(int32_t tag, mpz_t z, bool c = false) : + p(new EXPR(tag, z, c)) { p->incref(); } expr(int32_t tag, double d) : p(new EXPR(tag, d)) { p->incref(); } explicit expr(int32_t tag, char *s) : @@ -337,6 +340,7 @@ p->tag == EXPR::CASE || p->tag == EXPR::WHEN); return p->m; } + bool cint() const { return p->c; } int32_t astag() const { return p->astag; } path &aspath() const { assert(p->aspath); return *p->aspath; } Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-08-15 09:15:37 UTC (rev 508) +++ pure/trunk/interpreter.cc 2008-08-15 10:31:59 UTC (rev 509) @@ -1623,9 +1623,10 @@ } expr *y; // handle special case of a numeric argument - if (x->tag() == EXPR::BIGINT && mpz_cmp_ui(x->zval(), 0x80000000U) == 0) - // The negated bigint 0x80000000 can actually be represented as a machine - // int value, we do that conversion on the fly here. + if (x->tag() == EXPR::BIGINT && x->cint() && + mpz_cmp_ui(x->zval(), 0x80000000U) == 0) + // The negated int 0x80000000 can actually be represented as a machine int + // value, we convert it back on the fly here. y = new expr(EXPR::INT, (int32_t)-0x80000000); else if (x->tag() == EXPR::INT) y = new expr(EXPR::INT, -x->ival()); Modified: pure/trunk/lexer.ll =================================================================== --- pure/trunk/lexer.ll 2008-08-15 09:15:37 UTC (rev 508) +++ pure/trunk/lexer.ll 2008-08-15 10:31:59 UTC (rev 509) @@ -751,7 +751,7 @@ return token::INT; } else { yylval->zval = z; - return token::BIGINT; + return token::CBIGINT; } } {int}L { Modified: pure/trunk/parser.yy =================================================================== --- pure/trunk/parser.yy 2008-08-15 09:15:37 UTC (rev 508) +++ pure/trunk/parser.yy 2008-08-15 10:31:59 UTC (rev 509) @@ -224,6 +224,7 @@ %token <csval> STR "string" %token <ival> INT "integer" %token <zval> BIGINT "bigint" +%token <zval> CBIGINT "converted bigint" %token <dval> DBL "floating point number" %token <ival> TAG "type tag" %type <sval> name optalias ctype @@ -242,7 +243,7 @@ comp_clauses comp_clause_list args lhs qual rules rulel rule pat_rules pat_rulel simple_rules simple_rulel simple_rule ids names name optalias opt_ctypes ctypes ctype -%destructor { mpz_clear(*$$); free($$); } BIGINT +%destructor { mpz_clear(*$$); free($$); } BIGINT CBIGINT %destructor { free($$); } STR %printer { debug_stream() << *$$; } ID name optalias ctype expr cond simple app prim op args lhs qual rule simple_rules simple_rulel simple_rule @@ -250,7 +251,7 @@ %printer { debug_stream() << $$->rl; } pat_rules pat_rulel %printer { debug_stream() << $$; } INT DBL STR %printer { char *s = mpz_get_str(NULL, 10, *$$); - debug_stream() << s; free(s); } BIGINT + debug_stream() << s; free(s); } BIGINT CBIGINT %% @@ -507,6 +508,7 @@ $$ = $3; } } | INT { $$ = new expr(EXPR::INT, $1); } +| CBIGINT { $$ = new expr(EXPR::BIGINT, *$1, true); free($1); } | BIGINT { $$ = new expr(EXPR::BIGINT, *$1); free($1); } | DBL { $$ = new expr(EXPR::DBL, $1); } | STR { $$ = new expr(EXPR::STR, $1); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-15 09:15:27
|
Revision: 508 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=508&view=rev Author: agraef Date: 2008-08-15 09:15:37 +0000 (Fri, 15 Aug 2008) Log Message: ----------- Add missing printf %c conversion. Modified Paths: -------------- pure/trunk/lib/system.pure Modified: pure/trunk/lib/system.pure =================================================================== --- pure/trunk/lib/system.pure 2008-08-15 08:49:09 UTC (rev 507) +++ pure/trunk/lib/system.pure 2008-08-15 09:15:37 UTC (rev 508) @@ -194,6 +194,7 @@ do_fprintf fp (count,arg:args) (printf_format_spec t s) = count, args when res = case t, arg of + "c", x::int | "c", x::bigint | "d", x::int | "d", x::bigint = pure_fprintf_int fp s x; "g", x::double = pure_fprintf_double fp s x; "s", x::string = pure_fprintf_string fp s x; @@ -211,7 +212,7 @@ end; printf_split_format format = regexg analyze - "(%[-#0 ]?[0-9]*([.][0-9]*)?[diouxXeEfgGsp])|(%)|([^%]|%%)+" + "(%[-#0 ]?[0-9]*([.][0-9]*)?[cdiouxXeEfgGsp])|(%)|([^%]|%%)+" REG_EXTENDED format 0 with analyze info = @@ -257,6 +258,7 @@ end; buf = check_buf (malloc size); res = case t, arg of + "c", x::int | "c", x::bigint | "d", x::int | "d", x::bigint = pure_snprintf_int buf size s x; "g", x::double = pure_snprintf_double buf size s x; "s", x::string = pure_snprintf_string buf size s x; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-15 08:48:59
|
Revision: 507 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=507&view=rev Author: agraef Date: 2008-08-15 08:49:09 +0000 (Fri, 15 Aug 2008) Log Message: ----------- Fix up scanf %c conversion. Modified Paths: -------------- pure/trunk/lib/system.pure Modified: pure/trunk/lib/system.pure =================================================================== --- pure/trunk/lib/system.pure 2008-08-15 08:12:33 UTC (rev 506) +++ pure/trunk/lib/system.pure 2008-08-15 08:49:09 UTC (rev 507) @@ -345,6 +345,7 @@ = buf otherwise; // Compute a reasonable size for a string buffer; if necessary, modify the // field width of the format accordingly. + guestimate "%c" = 2, "%c"; guestimate format = n, format when 1,0,_,1,s = regex "^%([0-9]*)" REG_EXTENDED format 0; @@ -437,6 +438,7 @@ = buf otherwise; // Compute a reasonable size for a string buffer; if necessary, modify the // field width of the format accordingly. + guestimate "%c" = 2, "%c"; guestimate format = n, format when 1,0,_,1,s = regex "^%([0-9]*)" REG_EXTENDED format 0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-15 08:12:24
|
Revision: 506 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=506&view=rev Author: agraef Date: 2008-08-15 08:12:33 +0000 (Fri, 15 Aug 2008) Log Message: ----------- Cosmetic changes. Modified Paths: -------------- pure/trunk/lib/primitives.pure pure/trunk/lib/system.pure Modified: pure/trunk/lib/primitives.pure =================================================================== --- pure/trunk/lib/primitives.pure 2008-08-15 07:48:07 UTC (rev 505) +++ pure/trunk/lib/primitives.pure 2008-08-15 08:12:33 UTC (rev 506) @@ -332,11 +332,11 @@ extern expr* bigint_pow(void*, int), double pow(double, double) = c_pow; pow x::int y::int = bigint_pow (bigint x) y if y>=0; -pow x::bigint y::bigint = bigint_pow x (int y) if y>=0; +pow x::bigint y::bigint = bigint_pow x y if y>=0; pow x::double y::double = c_pow x y if x>=0 || frac y==0.0; // mixed int/bigint -pow x::int y::bigint = bigint_pow (bigint x) (int y) if y>=0; +pow x::int y::bigint = bigint_pow (bigint x) y if y>=0; pow x::bigint y::int = bigint_pow x y if y>=0; // mixed double/int/bigint Modified: pure/trunk/lib/system.pure =================================================================== --- pure/trunk/lib/system.pure 2008-08-15 07:48:07 UTC (rev 505) +++ pure/trunk/lib/system.pure 2008-08-15 08:12:33 UTC (rev 506) @@ -103,7 +103,6 @@ extern int sleep(int); extern double pure_nanosleep(double) = nanosleep; -sleep t::bigint = sleep (int t); nanosleep t::int | nanosleep t::bigint = nanosleep (double t); /* Basic process operations: system executes a shell command, exit terminates @@ -195,12 +194,10 @@ do_fprintf fp (count,arg:args) (printf_format_spec t s) = count, args when res = case t, arg of - "d", x::int = pure_fprintf_int fp s x; - "d", x::bigint = pure_fprintf_int fp s (int x); + "d", x::int | "d", x::bigint = pure_fprintf_int fp s x; "g", x::double = pure_fprintf_double fp s x; "s", x::string = pure_fprintf_string fp s x; - "p", x::string = pure_fprintf_pointer fp s x; - "p", x::pointer = pure_fprintf_pointer fp s x; + "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; @@ -260,12 +257,10 @@ end; buf = check_buf (malloc size); res = case t, arg of - "d", x::int = pure_snprintf_int buf size s x; - "d", x::bigint = pure_snprintf_int buf size s (int x); + "d", x::int | "d", x::bigint = pure_snprintf_int buf size s x; "g", x::double = pure_snprintf_double buf size s x; "s", x::string = pure_snprintf_string buf size s x; - "p", x::string = pure_snprintf_pointer buf size s x; - "p", x::pointer = pure_snprintf_pointer buf size s x; + "p", x::string | "p", x::pointer = pure_snprintf_pointer buf size s x; _ = throw (printf_value_error s arg) when _ = free buf end; end; u = if res>=0 then u + cstring buf This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-15 07:47:57
|
Revision: 505 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=505&view=rev Author: agraef Date: 2008-08-15 07:48:07 +0000 (Fri, 15 Aug 2008) Log Message: ----------- Allow bigint arguments for all C int parameter types. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/interpreter.cc Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-08-14 23:43:27 UTC (rev 504) +++ pure/trunk/ChangeLog 2008-08-15 07:48:07 UTC (rev 505) @@ -1,5 +1,8 @@ 2008-08-15 Albert Graef <Dr....@t-...> + * interpreter.cc (declare_extern): All C int parameter types now + handle bigint arguments. + * lib/primitives.pure: Moved basic rounding functions from math.pure, and fixed some minor glitches in the pow function. Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-08-14 23:43:27 UTC (rev 504) +++ pure/trunk/interpreter.cc 2008-08-15 07:48:07 UTC (rev 505) @@ -259,6 +259,8 @@ "pure_get_bigint", "void*", 1, "expr*"); declare_extern((void*)pure_get_long, "pure_get_long", "long", 1, "expr*"); + declare_extern((void*)pure_get_int, + "pure_get_int", "int", 1, "expr*"); declare_extern((void*)pure_catch, "pure_catch", "expr*", 2, "expr*", "expr*"); @@ -2814,41 +2816,84 @@ Value *iv = b.CreateLoad(b.CreateGEP(pv, idx, idx+2), "intval"); unboxed[i] = b.CreateICmpNE(iv, Zero); } else if (argt[i] == Type::Int8Ty) { + /* We allow either ints or bigints to be passed for C integers. */ + BasicBlock *intbb = BasicBlock::Create("int"); + BasicBlock *mpzbb = BasicBlock::Create("mpz"); 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::INT), "cmp"), okbb, failedbb); + SwitchInst *sw = b.CreateSwitch(tagv, failedbb, 2); + sw->addCase(SInt(EXPR::INT), intbb); + sw->addCase(SInt(EXPR::BIGINT), mpzbb); + f->getBasicBlockList().push_back(intbb); + b.SetInsertPoint(intbb); + Value *pv = b.CreateBitCast(x, IntExprPtrTy, "intexpr"); + idx[1] = ValFldIndex; + Value *intv = b.CreateLoad(b.CreateGEP(pv, idx, idx+2), "intval"); + b.CreateBr(okbb); + f->getBasicBlockList().push_back(mpzbb); + b.SetInsertPoint(mpzbb); + // Handle the case of a bigint (mpz_t -> int). + Value *mpzv = b.CreateCall(module->getFunction("pure_get_int"), x); + b.CreateBr(okbb); f->getBasicBlockList().push_back(okbb); b.SetInsertPoint(okbb); - Value *pv = b.CreateBitCast(x, IntExprPtrTy, "intexpr"); - idx[1] = ValFldIndex; - Value *iv = b.CreateLoad(b.CreateGEP(pv, idx, idx+2), "intval"); - unboxed[i] = b.CreateTrunc(iv, Type::Int8Ty); + PHINode *phi = b.CreatePHI(Type::Int32Ty); + phi->addIncoming(intv, intbb); + phi->addIncoming(mpzv, mpzbb); + unboxed[i] = b.CreateTrunc(phi, Type::Int8Ty); } else if (argt[i] == Type::Int16Ty) { + BasicBlock *intbb = BasicBlock::Create("int"); + BasicBlock *mpzbb = BasicBlock::Create("mpz"); 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::INT), "cmp"), okbb, failedbb); + SwitchInst *sw = b.CreateSwitch(tagv, failedbb, 2); + sw->addCase(SInt(EXPR::INT), intbb); + sw->addCase(SInt(EXPR::BIGINT), mpzbb); + f->getBasicBlockList().push_back(intbb); + b.SetInsertPoint(intbb); + Value *pv = b.CreateBitCast(x, IntExprPtrTy, "intexpr"); + idx[1] = ValFldIndex; + Value *intv = b.CreateLoad(b.CreateGEP(pv, idx, idx+2), "intval"); + b.CreateBr(okbb); + f->getBasicBlockList().push_back(mpzbb); + b.SetInsertPoint(mpzbb); + // Handle the case of a bigint (mpz_t -> int). + Value *mpzv = b.CreateCall(module->getFunction("pure_get_int"), x); + b.CreateBr(okbb); f->getBasicBlockList().push_back(okbb); b.SetInsertPoint(okbb); - Value *pv = b.CreateBitCast(x, IntExprPtrTy, "intexpr"); - idx[1] = ValFldIndex; - Value *iv = b.CreateLoad(b.CreateGEP(pv, idx, idx+2), "intval"); - unboxed[i] = b.CreateTrunc(iv, Type::Int16Ty); + PHINode *phi = b.CreatePHI(Type::Int32Ty); + phi->addIncoming(intv, intbb); + phi->addIncoming(mpzv, mpzbb); + unboxed[i] = b.CreateTrunc(phi, Type::Int16Ty); } else if (argt[i] == Type::Int32Ty) { + BasicBlock *intbb = BasicBlock::Create("int"); + BasicBlock *mpzbb = BasicBlock::Create("mpz"); 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::INT), "cmp"), okbb, failedbb); + SwitchInst *sw = b.CreateSwitch(tagv, failedbb, 2); + sw->addCase(SInt(EXPR::INT), intbb); + sw->addCase(SInt(EXPR::BIGINT), mpzbb); + f->getBasicBlockList().push_back(intbb); + b.SetInsertPoint(intbb); + Value *pv = b.CreateBitCast(x, IntExprPtrTy, "intexpr"); + idx[1] = ValFldIndex; + Value *intv = b.CreateLoad(b.CreateGEP(pv, idx, idx+2), "intval"); + b.CreateBr(okbb); + f->getBasicBlockList().push_back(mpzbb); + b.SetInsertPoint(mpzbb); + // Handle the case of a bigint (mpz_t -> int). + Value *mpzv = b.CreateCall(module->getFunction("pure_get_int"), x); + b.CreateBr(okbb); f->getBasicBlockList().push_back(okbb); b.SetInsertPoint(okbb); - Value *pv = b.CreateBitCast(x, IntExprPtrTy, "intexpr"); - idx[1] = ValFldIndex; - Value *iv = b.CreateLoad(b.CreateGEP(pv, idx, idx+2), "intval"); - unboxed[i] = iv; + PHINode *phi = b.CreatePHI(Type::Int32Ty); + phi->addIncoming(intv, intbb); + phi->addIncoming(mpzv, mpzbb); + unboxed[i] = phi; } else if (argt[i] == Type::Int64Ty) { BasicBlock *intbb = BasicBlock::Create("int"); BasicBlock *mpzbb = BasicBlock::Create("mpz"); @@ -2856,15 +2901,14 @@ Value *idx[2] = { Zero, Zero }; Value *tagv = b.CreateLoad(b.CreateGEP(x, idx, idx+2), "tag"); SwitchInst *sw = b.CreateSwitch(tagv, failedbb, 2); - /* We allow either ints or bigints to be passed for a long value. */ sw->addCase(SInt(EXPR::INT), intbb); sw->addCase(SInt(EXPR::BIGINT), mpzbb); f->getBasicBlockList().push_back(intbb); b.SetInsertPoint(intbb); Value *pv = b.CreateBitCast(x, IntExprPtrTy, "intexpr"); idx[1] = ValFldIndex; - Value *iv = b.CreateLoad(b.CreateGEP(pv, idx, idx+2), "intval"); - Value *intv = b.CreateSExt(iv, Type::Int64Ty); + Value *intv = b.CreateLoad(b.CreateGEP(pv, idx, idx+2), "intval"); + intv = b.CreateSExt(intv, Type::Int64Ty); b.CreateBr(okbb); f->getBasicBlockList().push_back(mpzbb); b.SetInsertPoint(mpzbb); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-14 23:43:16
|
Revision: 504 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=504&view=rev Author: agraef Date: 2008-08-14 23:43:27 +0000 (Thu, 14 Aug 2008) Log Message: ----------- Fix up some conversion operations, where mpz_get_ui/si don't do the right thing. Modified Paths: -------------- pure/trunk/runtime.cc Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-08-14 23:31:59 UTC (rev 503) +++ pure/trunk/runtime.cc 2008-08-14 23:43:27 UTC (rev 504) @@ -1742,7 +1742,7 @@ assert(x); switch (x->tag) { case EXPR::INT: return x; - case EXPR::BIGINT: return pure_int(mpz_get_si(x->data.z)); + case EXPR::BIGINT: return pure_int(pure_get_int(x)); case EXPR::DBL: return pure_int((int32_t)x->data.d); #if SIZEOF_VOID_P==8 // Must cast to 64 bit here first, since on 64 bit systems g++ gives an @@ -1782,15 +1782,12 @@ #else return pure_pointer((void*)(uint32_t)mpz_getlimbn(x->data.z, 0)); #endif - else { + else #if SIZEOF_VOID_P==8 - uint64_t u = mpz_getlimbn(x->data.z, 0) + - (((uint64_t)mpz_getlimbn(x->data.z, 1))<<32); - return pure_pointer((void*)u); + return pure_pointer((void*)(uint64_t)pure_get_long(x)); #else - return pure_pointer((void*)mpz_get_ui(x->data.z)); + return pure_pointer((void*)(uint32_t)pure_get_int(x)); #endif - } default: return 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 23:31:50
|
Revision: 503 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=503&view=rev Author: agraef Date: 2008-08-14 23:31:59 +0000 (Thu, 14 Aug 2008) Log Message: ----------- Add bigint->int32_t marshalling routine. Modified Paths: -------------- pure/trunk/runtime.cc pure/trunk/runtime.h Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-08-14 23:16:09 UTC (rev 502) +++ pure/trunk/runtime.cc 2008-08-14 23:31:59 UTC (rev 503) @@ -1147,6 +1147,15 @@ } extern "C" +int32_t pure_get_int(pure_expr *x) +{ + uint32_t v = + (sizeof(mp_limb_t) == 8) ? (uint32_t)(uint64_t)mpz_getlimbn(x->data.z, 0) : + mpz_getlimbn(x->data.z, 0); + return (mpz_sgn(x->data.z) < 0) ? -(int32_t)v : (int32_t)v; +} + +extern "C" void *pure_get_bigint(pure_expr *x) { assert(x && x->tag == EXPR::BIGINT); Modified: pure/trunk/runtime.h =================================================================== --- pure/trunk/runtime.h 2008-08-14 23:16:09 UTC (rev 502) +++ pure/trunk/runtime.h 2008-08-14 23:31:59 UTC (rev 503) @@ -318,11 +318,12 @@ char *pure_get_cstring(pure_expr *x); void pure_free_cstrings(); -/* Convert a bigint expression to a pointer (mpz_t) or a long (64 bit) +/* Convert a bigint expression to a pointer (mpz_t) or a 64 or 32 bit integer. This is used to marshall bigint arguments in the C interface. */ void *pure_get_bigint(pure_expr *x); int64_t pure_get_long(pure_expr *x); +int32_t pure_get_int(pure_expr *x); /* Execute a closure. If the given expression x (or x y in the case of pure_apply) is a parameterless closure (or a saturated application of a This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-14 23:15:59
|
Revision: 502 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=502&view=rev Author: agraef Date: 2008-08-14 23:16:09 +0000 (Thu, 14 Aug 2008) Log Message: ----------- Updated ChangeLog. Modified Paths: -------------- pure/trunk/ChangeLog Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-08-14 23:14:26 UTC (rev 501) +++ pure/trunk/ChangeLog 2008-08-14 23:16:09 UTC (rev 502) @@ -1,3 +1,8 @@ +2008-08-15 Albert Graef <Dr....@t-...> + + * lib/primitives.pure: Moved basic rounding functions from + math.pure, and fixed some minor glitches in the pow function. + 2008-08-14 Albert Graef <Dr....@t-...> * lib/primitives.pure: Added routines to convert signed integers This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-14 23:14:16
|
Revision: 501 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=501&view=rev Author: agraef Date: 2008-08-14 23:14:26 +0000 (Thu, 14 Aug 2008) Log Message: ----------- Fix some minor glitches in the pow function. Modified Paths: -------------- pure/trunk/lib/primitives.pure Modified: pure/trunk/lib/primitives.pure =================================================================== --- pure/trunk/lib/primitives.pure 2008-08-14 23:10:55 UTC (rev 500) +++ pure/trunk/lib/primitives.pure 2008-08-14 23:14:26 UTC (rev 501) @@ -332,8 +332,8 @@ extern expr* bigint_pow(void*, int), double pow(double, double) = c_pow; pow x::int y::int = bigint_pow (bigint x) y if y>=0; -pow x::bigint y::bigint = bigint_pow x (int y) if int y>=0; -pow x::double y::double = c_pow x y if x>=0 || int y==y; +pow x::bigint y::bigint = bigint_pow x (int y) if y>=0; +pow x::double y::double = c_pow x y if x>=0 || frac y==0.0; // mixed int/bigint pow x::int y::bigint = bigint_pow (bigint x) (int y) if y>=0; @@ -343,12 +343,12 @@ pow x::double y::int | pow x::double y::bigint = c_pow x (double y); pow x::int y::double | -pow x::bigint y::double = c_pow (double x) y if x>=0 || int y==y; +pow x::bigint y::double = c_pow (double x) y if x>=0 || frac y==0.0; /* The ^ operator. Works like pow, but always promotes its operands to double and returns a double result. */ -x::double^y::double = c_pow x y if x>=0 || int y==y; +x::double^y::double = c_pow x y if x>=0 || frac y==0.0; x::int^y::int | x::bigint^y::bigint | x::int^y::bigint | @@ -356,7 +356,7 @@ x::double^y::int | x::double^y::bigint = c_pow x (double y); x::int^y::double | -x::bigint^y::double = c_pow (double x) y if x>=0 || int y==y; +x::bigint^y::double = c_pow (double x) y if x>=0 || frac y==0.0; = double x^y otherwise; /* Pointer arithmetic. We do this using bigints, so that the code is portable This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-14 23:10:44
|
Revision: 500 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=500&view=rev Author: agraef Date: 2008-08-14 23:10:55 +0000 (Thu, 14 Aug 2008) Log Message: ----------- Move basic rounding functions from math.pure to primitives.pure. Modified Paths: -------------- pure/trunk/lib/math.pure pure/trunk/lib/primitives.pure Modified: pure/trunk/lib/math.pure =================================================================== --- pure/trunk/lib/math.pure 2008-08-14 22:13:28 UTC (rev 499) +++ pure/trunk/lib/math.pure 2008-08-14 23:10:55 UTC (rev 500) @@ -28,19 +28,6 @@ extern int pure_random() = random, void pure_srandom(int) = srandom; -/* Rounding functions. */ - -extern double floor(double), double ceil(double); -extern double round(double), double trunc(double); - -floor x::int | floor x::bigint = x; -ceil x::int | ceil x::bigint = x; -round x::int | round x::bigint = x; -trunc x::int | trunc x::bigint = x; - -// Fractional part of x. -frac x::int | frac x::bigint | frac x::double = x-trunc x; - /* The sqrt function. */ extern double sqrt(double) = c_sqrt; Modified: pure/trunk/lib/primitives.pure =================================================================== --- pure/trunk/lib/primitives.pure 2008-08-14 22:13:28 UTC (rev 499) +++ pure/trunk/lib/primitives.pure 2008-08-14 23:10:55 UTC (rev 500) @@ -105,6 +105,19 @@ uint x::int = if x>=0 then bigint x else x+0x100000000L; ulong x::bigint = if x>=0 then x else x+0x10000000000000000L; +/* Rounding functions. */ + +extern double floor(double), double ceil(double); +extern double round(double), double trunc(double); + +floor x::int | floor x::bigint = x; +ceil x::int | ceil x::bigint = x; +round x::int | round x::bigint = x; +trunc x::int | trunc x::bigint = x; + +// Fractional part of x. +frac x::int | frac x::bigint | frac x::double = x-trunc x; + /* Absolute value and sign of a number. */ abs x::int | abs x::bigint | abs x::double This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-14 22:13:19
|
Revision: 499 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=499&view=rev Author: agraef Date: 2008-08-14 22:13:28 +0000 (Thu, 14 Aug 2008) Log Message: ----------- Add missing description of C char type. Modified Paths: -------------- pure/trunk/pure.1.in Modified: pure/trunk/pure.1.in =================================================================== --- pure/trunk/pure.1.in 2008-08-14 21:31:33 UTC (rev 498) +++ pure/trunk/pure.1.in 2008-08-14 22:13:28 UTC (rev 499) @@ -830,7 +830,8 @@ integer types are provided which are converted from/to the Pure types in a straightfoward way. The short type indicates 16 bit integers which are converted from/to Pure machine ints using truncation and sign extension, -respectively. The long type +respectively. The char type, which denotes 8 bit integers, is treated +analogously. The long type .I always denotes 64 bit integers, even if the corresponding C type is actually 32 bit (as it usually is on most contemporary systems). This type is to be used if a This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-14 21:31:25
|
Revision: 498 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=498&view=rev Author: agraef Date: 2008-08-14 21:31:33 +0000 (Thu, 14 Aug 2008) Log Message: ----------- For compatibility with the other C interface integer types, do sign extension also for char return values (use ubyte from the prelude to convert back to an unsigned quantity if desired). Modified Paths: -------------- pure/trunk/interpreter.cc Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-08-14 13:56:45 UTC (rev 497) +++ pure/trunk/interpreter.cc 2008-08-14 21:31:33 UTC (rev 498) @@ -2985,9 +2985,8 @@ u = b.CreateCall(module->getFunction("pure_int"), b.CreateZExt(u, Type::Int32Ty)); else if (type == Type::Int8Ty) - // char treated as an unsigned integer here u = b.CreateCall(module->getFunction("pure_int"), - b.CreateZExt(u, Type::Int32Ty)); + b.CreateSExt(u, Type::Int32Ty)); else if (type == Type::Int16Ty) u = b.CreateCall(module->getFunction("pure_int"), b.CreateSExt(u, Type::Int32Ty)); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-14 13:56:38
|
Revision: 497 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=497&view=rev Author: agraef Date: 2008-08-14 13:56:45 +0000 (Thu, 14 Aug 2008) Log Message: ----------- Fix typo. Modified Paths: -------------- pure/trunk/lib/primitives.pure Modified: pure/trunk/lib/primitives.pure =================================================================== --- pure/trunk/lib/primitives.pure 2008-08-14 13:37:16 UTC (rev 496) +++ pure/trunk/lib/primitives.pure 2008-08-14 13:56:45 UTC (rev 497) @@ -105,7 +105,6 @@ uint x::int = if x>=0 then bigint x else x+0x100000000L; ulong x::bigint = if x>=0 then x else x+0x10000000000000000L; - /* Absolute value and sign of a number. */ abs x::int | abs x::bigint | abs x::double This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-14 13:37:07
|
Revision: 496 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=496&view=rev Author: agraef Date: 2008-08-14 13:37:16 +0000 (Thu, 14 Aug 2008) Log Message: ----------- Added ubyte, ushort, uint, ulong routines to convert integers to unsigned quantities, as discussed on the mailing list. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/lib/primitives.pure Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-08-14 13:03:22 UTC (rev 495) +++ pure/trunk/ChangeLog 2008-08-14 13:37:16 UTC (rev 496) @@ -1,5 +1,9 @@ 2008-08-14 Albert Graef <Dr....@t-...> + * lib/primitives.pure: Added routines to convert signed integers + to the corresponding unsigned quantities, as discussed on the + mailing list. + * lib/math.pure: Bugfixes, overhaul of number predicates, added missing semantic number predicates. Modified: pure/trunk/lib/primitives.pure =================================================================== --- pure/trunk/lib/primitives.pure 2008-08-14 13:03:22 UTC (rev 495) +++ pure/trunk/lib/primitives.pure 2008-08-14 13:37:16 UTC (rev 496) @@ -91,6 +91,21 @@ pointer x::double | pointer x::string = pure_pointerval x; +/* Convert signed (8/16/32/64) bit integers to the corresponding unsigned + quantities. These functions behave as if the value was "cast" to the + corresponding unsigned C type, and are most useful for dealing with + unsigned integers returned by external C routines. The routines always use + the smallest Pure int type capable of holding the result: int for ubyte and + ushort, bigint for uint and ulong. (Note that in the case of 64 bit values + the C interface returns a bigint, that's why ulong takes a bigint + parameter. The other routines all take an int as input.) */ + +ubyte x::int = if x>=0 then x else x+0x100; +ushort x::int = if x>=0 then x else x+0x10000; +uint x::int = if x>=0 then bigint x else x+0x100000000L; +ulong x::bigint = if x>=0 then x else x+0x10000000000000000L; + + /* Absolute value and sign of a number. */ abs x::int | abs x::bigint | abs x::double This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |