[pure-lang-svn] SF.net SVN: pure-lang:[509] pure/trunk
Status: Beta
Brought to you by:
agraef
|
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.
|