[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. |