Thread: [pure-lang-svn] SF.net SVN: pure-lang: [9] pure/trunk
Status: Beta
Brought to you by:
agraef
From: <ag...@us...> - 2008-04-30 16:24:07
|
Revision: 9 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=9&view=rev Author: agraef Date: 2008-04-30 09:24:09 -0700 (Wed, 30 Apr 2008) Log Message: ----------- Various bug and OSX compatibility fixes. Modified Paths: -------------- pure/trunk/interpreter.cc pure/trunk/interpreter.hh pure/trunk/lexer.ll pure/trunk/parser.yy pure/trunk/runtime.cc Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-04-30 16:23:21 UTC (rev 8) +++ pure/trunk/interpreter.cc 2008-04-30 16:24:09 UTC (rev 9) @@ -1321,7 +1321,7 @@ if (r->size() > 0x100) throw err("error in expression (too many nested closures)"); uint8_t idx = 0; - for (rulel::const_reverse_iterator it = r->rbegin(); + for (rulel::reverse_iterator it = r->rbegin(); it != r->rend(); ++it, ++idx) { env vars; expr v = bind(vars, it->lhs), w = it->rhs; @@ -1402,9 +1402,9 @@ #define Dbl(d) ConstantFP::get(Type::DoubleTy, APFloat(d)) #define Bool(i) ConstantInt::get(Type::Int1Ty, i) #define UInt(i) ConstantInt::get(Type::Int32Ty, i) -#define SInt(i) ConstantInt::get(Type::Int32Ty, i, true) +#define SInt(i) ConstantInt::get(Type::Int32Ty, (uint64_t)i, true) #define UInt64(i) ConstantInt::get(Type::Int64Ty, i) -#define SInt64(i) ConstantInt::get(Type::Int64Ty, i, true) +#define SInt64(i) ConstantInt::get(Type::Int64Ty, (uint64_t)i, true) #define False Bool(0) #define True Bool(1) #define Zero UInt(0) Modified: pure/trunk/interpreter.hh =================================================================== --- pure/trunk/interpreter.hh 2008-04-30 16:23:21 UTC (rev 8) +++ pure/trunk/interpreter.hh 2008-04-30 16:24:09 UTC (rev 9) @@ -35,17 +35,13 @@ class interpreter; -// Forward declarations. -union YYSTYPE; -namespace yy -{ - class location; - class parser; -} +#include "parser.hh" // Announce to Flex the prototype we want for lexing function, ... #define YY_DECL \ - int yylex (YYSTYPE* yylval, yy::location* yylloc, interpreter& interp) + yy::parser::token_type \ + yylex (yy::parser::semantic_type* yylval, \ + yy::parser::location_type* yylloc, interpreter& interp) // ... and declare it for the parser's sake. YY_DECL; Modified: pure/trunk/lexer.ll =================================================================== --- pure/trunk/lexer.ll 2008-04-30 16:23:21 UTC (rev 8) +++ pure/trunk/lexer.ll 2008-04-30 16:24:09 UTC (rev 9) @@ -12,6 +12,16 @@ #include "parser.hh" #include "util.hh" +/* Work around an incompatibility in flex (at least versions 2.5.31 through + 2.5.33): it generates code that does not conform to C89. See Debian bug + 333231 <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>. */ +# undef yywrap +# define yywrap() 1 + +/* By default yylex returns int, we use token_type. Unfortunately yyterminate + by default returns 0, which is not of token_type. */ +#define yyterminate() return yy::parser::token_type(0) + using namespace std; static void my_readline(const char *prompt, char *buf, int &result, int max_size); @@ -19,7 +29,7 @@ #define YY_INPUT(buf,result,max_size) \ if (interpreter::g_interp->source_s) { \ size_t l = strlen(interpreter::g_interp->source_s); \ - if (l > max_size) l = max_size; \ + if (l > (size_t)max_size) l = (size_t)max_size; \ memcpy(buf, interpreter::g_interp->source_s, l); \ interpreter::g_interp->source_s += result = l; \ } else if ( interpreter::g_interactive && \ @@ -39,17 +49,19 @@ } \ } -static int optoken[10][5] = { - {NA0, LT0, RT0, PR0, PO0}, - {NA1, LT1, RT1, PR1, PO1}, - {NA2, LT2, RT2, PR2, PO2}, - {NA3, LT3, RT3, PR3, PO3}, - {NA4, LT4, RT4, PR4, PO4}, - {NA5, LT5, RT5, PR5, PO5}, - {NA6, LT6, RT6, PR6, PO6}, - {NA7, LT7, RT7, PR7, PO7}, - {NA8, LT8, RT8, PR8, PO8}, - {NA9, LT9, RT9, PR9, PO9}, +typedef yy::parser::token token; + +static yy::parser::token_type optoken[10][5] = { + {token::NA0, token::LT0, token::RT0, token::PR0, token::PO0}, + {token::NA1, token::LT1, token::RT1, token::PR1, token::PO1}, + {token::NA2, token::LT2, token::RT2, token::PR2, token::PO2}, + {token::NA3, token::LT3, token::RT3, token::PR3, token::PO3}, + {token::NA4, token::LT4, token::RT4, token::PR4, token::PO4}, + {token::NA5, token::LT5, token::RT5, token::PR5, token::PO5}, + {token::NA6, token::LT6, token::RT6, token::PR6, token::PO6}, + {token::NA7, token::LT7, token::RT7, token::PR7, token::PO7}, + {token::NA8, token::LT8, token::RT8, token::PR8, token::PO8}, + {token::NA9, token::LT9, token::RT9, token::PR9, token::PO9}, }; struct argl { @@ -119,11 +131,11 @@ str ([^\"\\\n]|\\(.|\n))* blank [ \t] -inttag ::{blank}*int/[^a-zA-Z_0-9] -binttag ::{blank}*bigint/[^a-zA-Z_0-9] -dbltag ::{blank}*double/[^a-zA-Z_0-9] -strtag ::{blank}*string/[^a-zA-Z_0-9] -ptrtag ::{blank}*pointer/[^a-zA-Z_0-9] +inttag ::{blank}*int +binttag ::{blank}*bigint +dbltag ::{blank}*double +strtag ::{blank}*string +ptrtag ::{blank}*pointer %x comment xdecl xdecl_comment @@ -149,17 +161,17 @@ <comment>[\n]+ yylloc->lines(yyleng); yylloc->step(); <comment>"*"+"/" yylloc->step(); BEGIN(INITIAL); -<xdecl>{id} yylval->sval = new string(yytext); return ID; -<xdecl>[()*,=] return yytext[0]; +<xdecl>{id} yylval->sval = new string(yytext); return token::ID; +<xdecl>[()*,=] return yy::parser::token_type(yytext[0]); <xdecl>"//".* yylloc->step(); <xdecl>"/*" BEGIN(xdecl_comment); -<xdecl>; BEGIN(INITIAL); return yytext[0]; +<xdecl>; BEGIN(INITIAL); return yy::parser::token_type(yytext[0]); <xdecl>{blank}+ yylloc->step(); <xdecl>[\n]+ yylloc->lines(yyleng); yylloc->step(); <xdecl>. { string msg = "invalid character '"+string(yytext)+"'"; interp.error(*yylloc, msg); - BEGIN(INITIAL); return ERRTOK; + BEGIN(INITIAL); return token::ERRTOK; } @@ -586,54 +598,54 @@ long n = mpz_get_si(*z); free(z); yylval->ival = n; - return INT; + return token::INT; } else { yylval->zval = z; - return BIGINT; + return token::BIGINT; } } -{float} yylval->dval = my_strtod(yytext, NULL); return(DBL); +{float} yylval->dval = my_strtod(yytext, NULL); return(token::DBL); \"{str}\" { char *msg; yytext[yyleng-1] = 0; yylval->csval = parsestr(yytext+1, msg); yytext[yyleng-1] = '"'; if (msg) interp.error(*yylloc, msg); - return STR; + return token::STR; } \"{str} { char *msg; interp.error(*yylloc, "unterminated string constant"); yylval->csval = parsestr(yytext+1, msg); - return STR; + return token::STR; } -{inttag} yylval->ival = EXPR::INT; return TAG; -{binttag} yylval->ival = EXPR::BIGINT; return TAG; -{dbltag} yylval->ival = EXPR::DBL; return TAG; -{strtag} yylval->ival = EXPR::STR; return TAG; -{ptrtag} yylval->ival = EXPR::PTR; return TAG; -extern BEGIN(xdecl); return EXTERN; -infix yylval->fix = infix; return FIX; -infixl yylval->fix = infixl; return FIX; -infixr yylval->fix = infixr; return FIX; -prefix yylval->fix = prefix; return FIX; -postfix yylval->fix = postfix; return FIX; -nullary return NULLARY; -let return LET; -case return CASE; -of return OF; -end return END; -if return IF; -then return THEN; -else return ELSE; -otherwise return OTHERWISE; -when return WHEN; -with return WITH; -using return USING; +{inttag}/[^a-zA-Z_0-9] yylval->ival = EXPR::INT; return token::TAG; +{binttag}/[^a-zA-Z_0-9] yylval->ival = EXPR::BIGINT; return token::TAG; +{dbltag}/[^a-zA-Z_0-9] yylval->ival = EXPR::DBL; return token::TAG; +{strtag}/[^a-zA-Z_0-9] yylval->ival = EXPR::STR; return token::TAG; +{ptrtag}/[^a-zA-Z_0-9] yylval->ival = EXPR::PTR; return token::TAG; +extern BEGIN(xdecl); return token::EXTERN; +infix yylval->fix = infix; return token::FIX; +infixl yylval->fix = infixl; return token::FIX; +infixr yylval->fix = infixr; return token::FIX; +prefix yylval->fix = prefix; return token::FIX; +postfix yylval->fix = postfix; return token::FIX; +nullary return token::NULLARY; +let return token::LET; +case return token::CASE; +of return token::OF; +end return token::END; +if return token::IF; +then return token::THEN; +else return token::ELSE; +otherwise return token::OTHERWISE; +when return token::WHEN; +with return token::WITH; +using return token::USING; {id} { if (interp.declare_op) { yylval->sval = new string(yytext); - return ID; + return token::ID; } symbol* sym = interp.symtab.lookup(yytext); if (sym && sym->prec >= 0 && sym->prec < 10) { @@ -641,22 +653,22 @@ return optoken[sym->prec][sym->fix]; } else { yylval->sval = new string(yytext); - return ID; + return token::ID; } } -[=;()\[\]\\] return yytext[0]; -"->" return MAPSTO; +[=;()\[\]\\] return yy::parser::token_type(yytext[0]); +"->" return token::MAPSTO; [[:punct:]]+ { if (yytext[0] == '/' && yytext[1] == '*') REJECT; // comment starter while (yyleng > 1 && yytext[yyleng-1] == ';') yyless(yyleng-1); if (interp.declare_op) { yylval->sval = new string(yytext); - return ID; + return token::ID; } symbol* sym = interp.symtab.lookup(yytext); while (!sym && yyleng > 1) { if (yyleng == 2 && yytext[0] == '-' && yytext[1] == '>') - return MAPSTO; + return token::MAPSTO; yyless(yyleng-1); sym = interp.symtab.lookup(yytext); } @@ -666,7 +678,7 @@ return optoken[sym->prec][sym->fix]; } else { yylval->sval = new string(yytext); - return ID; + return token::ID; } } else REJECT; @@ -674,7 +686,7 @@ . { string msg = "invalid character '"+string(yytext)+"'"; interp.error(*yylloc, msg); - return ERRTOK; + return token::ERRTOK; } %% Modified: pure/trunk/parser.yy =================================================================== --- pure/trunk/parser.yy 2008-04-30 16:23:21 UTC (rev 8) +++ pure/trunk/parser.yy 2008-04-30 16:24:09 UTC (rev 9) @@ -1,13 +1,16 @@ /* The PURE parser. -*- C++ -*- */ // Tell bison that we want a C++ parser. +/* NOTE: We require at least bison 2.1a here, since the C++ parser skeleton + changed several times, and the newer versions are not compatible with bison + 2.1 and earlier. :( */ %skeleton "lalr1.cc" +%require "2.1a" %defines %{ #include <iostream> #include <string> -#include "interpreter.hh" #include "expr.hh" #include "printer.hh" #include "util.hh" @@ -23,6 +26,8 @@ { error(yylloc, e.what()); x = new expr(interp.symtab.void_sym().f); } using namespace std; + +class interpreter; %} // The parsing context. @@ -57,6 +62,8 @@ expr l; env e; }; +typedef pair<expr,expr> comp_clause; +typedef list<comp_clause> comp_clause_list; %} %union @@ -79,6 +86,10 @@ sym_info *info; }; +%{ +#include "interpreter.hh" +%} + %token NULLARY "nullary" %token <fix> FIX "fixity" Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-04-30 16:23:21 UTC (rev 8) +++ pure/trunk/runtime.cc 2008-04-30 16:24:09 UTC (rev 9) @@ -675,7 +675,9 @@ case EXPR::INT: return x; case EXPR::BIGINT: return pure_int(mpz_get_ui(x->data.z)); case EXPR::DBL: return pure_int((int32_t)x->data.d); - case EXPR::PTR: return pure_int((uint32_t)x->data.p); + // Must cast to 64 bit here first, since on 64 bit systems g++ gives an + // error when directly casting a 64 bit pointer to a 32 bit integer. + case EXPR::PTR: return pure_int((uint32_t)(uint64_t)x->data.p); default: return 0; } } @@ -724,13 +726,14 @@ #else // 4 byte limbs. if (sizeof(void*) == 4) { - // 4 byte pointers. - limb_t u[1] = { (uint32_t)p }; + // 4 byte pointers. Note that we still cast to 64 bit first, since + // otherwise the code will give an error on 64 bit systems. + limb_t u[1] = { (uint32_t)(uint64_t)p }; return pure_bigint(1, u); } else { // 8 byte pointers, put least significant word in the first limb. assert(sizeof(void*) == 8); - limb_t u[2] = { (uint32_t)p, (uint32_t)(((uint64_t)p)>>32) }; + limb_t u[2] = { (uint32_t)(uint64_t)p, (uint32_t)(((uint64_t)p)>>32) }; return pure_bigint(2, u); } #endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-05-01 15:27:09
|
Revision: 18 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=18&view=rev Author: agraef Date: 2008-05-01 08:27:14 -0700 (Thu, 01 May 2008) Log Message: ----------- Cosmetic changes in output of -v and list command. Modified Paths: -------------- pure/trunk/interpreter.cc pure/trunk/lexer.ll Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-05-01 09:38:20 UTC (rev 17) +++ pure/trunk/interpreter.cc 2008-05-01 15:27:14 UTC (rev 18) @@ -708,7 +708,7 @@ throw err(msg.str()); } if ((verbose&verbosity::defs) != 0) - cout << "let " << r->lhs << " = " << res << ";\n"; + cout << "let " << r->lhs << " = " << r->rhs << ";\n"; delete r; pure_freenew(res); if (interactive && stats) Modified: pure/trunk/lexer.ll =================================================================== --- pure/trunk/lexer.ll 2008-05-01 09:38:20 UTC (rev 17) +++ pure/trunk/lexer.ll 2008-05-01 15:27:14 UTC (rev 18) @@ -755,6 +755,7 @@ void interpreter::print_defs(ostream& os, const Env& e) { + if (e.h && e.h != e.f) e.h->print(os); e.f->print(os); map<int32_t,Env>::const_iterator f; for (f = e.fmap.begin(); f != e.fmap.end(); f++) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-05-02 03:55:10
|
Revision: 20 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=20&view=rev Author: agraef Date: 2008-05-01 20:55:18 -0700 (Thu, 01 May 2008) Log Message: ----------- Fix premature deallocation of closures bound in variable definitions. Modified Paths: -------------- pure/trunk/interpreter.cc pure/trunk/interpreter.hh pure/trunk/runtime.cc Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-05-01 15:29:39 UTC (rev 19) +++ pure/trunk/interpreter.cc 2008-05-02 03:55:18 UTC (rev 20) @@ -721,6 +721,7 @@ // patch up the global variable table to replace it with a cbox. map<int32_t,GlobalVar>::iterator v = globalvars.find(f); if (v != globalvars.end()) { + v->second.clear(); pure_expr *cv = pure_const(f); if (v->second.x) pure_free(v->second.x); v->second.x = pure_new(cv); @@ -1480,7 +1481,8 @@ v.v = new GlobalVariable (ExprPtrTy, false, GlobalVariable::ExternalLinkage, 0, sym.s, module); JIT->addGlobalMapping(v.v, &v.x); - } + } else + v.clear(); if (v.x) pure_free(v.x); v.x = pure_new(x); environ[tag] = env_info(&v.x, temp); restore_globals(g); @@ -1500,6 +1502,15 @@ return os << ")"; } +void GlobalVar::clear() +{ + if (e) { + assert(e->refc > 0); + if (--e->refc == 0) delete e; + e = 0; + } +} + Env& Env::operator= (const Env& e) { if (f) { @@ -1524,17 +1535,28 @@ interpreter& interp = *interpreter::g_interp; if (local) { // purge local functions +#if DEBUG>2 + llvm::cerr << "clearing local '" << name << "'\n"; +#endif + if (h != f) interp.JIT->freeMachineCodeForFunction(h); + interp.JIT->freeMachineCodeForFunction(f); f->dropAllReferences(); if (h != f) h->dropAllReferences(); + fp = 0; fmap.clear(); - interp.JIT->freeMachineCodeForFunction(f); - if (h != f) interp.JIT->freeMachineCodeForFunction(h); - fp = 0; to_be_deleted.push_back(f); if (h != f) to_be_deleted.push_back(h); } else { - // only delete the body, this keeps existing references intact - f->deleteBody(); - interp.JIT->freeMachineCodeForFunction(f); - if (h != f) interp.JIT->freeMachineCodeForFunction(h); +#if DEBUG>2 + llvm::cerr << "clearing global '" << name << "'\n"; +#endif + // The code of anonymous globals (doeval, dodefn) is taken care of + // elsewhere, we must not collect that here. + if (!name.empty()) { + // named global, get rid of the machine code + if (h != f) interp.JIT->freeMachineCodeForFunction(h); + interp.JIT->freeMachineCodeForFunction(f); + // only delete the body, this keeps existing references intact + f->deleteBody(); + } fp = 0; // delete all nested environments and reinitialize other body-related data fmap.clear(); xmap.clear(); xtab.clear(); prop.clear(); m = 0; argv = 0; @@ -2454,7 +2476,8 @@ (ExprPtrTy, false, GlobalVariable::InternalLinkage, 0, mkvarlabel(sym.f), module); JIT->addGlobalMapping(v.v, &v.x); - } + } else + v.clear(); if (v.x) pure_free(v.x); v.x = pure_new(cv); Value *defaultv = b.CreateLoad(v.v); vector<Value*> myargs(2); @@ -2522,6 +2545,7 @@ pure_expr *res = pure_invoke(f.fp, e); if (interactive && stats) clocks = clock()-t0; // Get rid of our anonymous function. + JIT->freeMachineCodeForFunction(f.f); f.f->eraseFromParent(); // NOTE: Result (if any) is to be freed by the caller. return res; @@ -2536,7 +2560,12 @@ } // Create an anonymous function to call in order to evaluate the rhs // expression, match against the lhs and bind variables in lhs accordingly. - Env f(0, 0, rhs, false); + /* NOTE: Unlike doeval(), we must create a semi-permanent environment here + whose child environments persist for the entire lifetime of the variables + bound in this definition, since some of those bindings may refer to + closures (executable code) that might still be called some time. */ + Env *fptr = new Env(0, 0, rhs, false); + Env &f = *fptr; push("dodefn", &f); fun_prolog(""); #if DEBUG>1 @@ -2573,9 +2602,16 @@ v.v = new GlobalVariable (ExprPtrTy, false, GlobalVariable::ExternalLinkage, 0, sym.s, module); JIT->addGlobalMapping(v.v, &v.x); - } + } else + v.clear(); + v.e = fptr; f.refc++; if (v.x) call("pure_free", f.builder.CreateLoad(v.v)); call("pure_new", x); +#if DEBUG>2 + ostringstream msg; + msg << "dodef: " << sym.s << " := %p"; + debug(msg.str().c_str(), x); +#endif f.builder.CreateStore(x, v.v); } // return the matchee to indicate success @@ -2594,6 +2630,7 @@ pure_expr *res = pure_invoke(f.fp, e); if (interactive && stats) clocks = clock()-t0; // Get rid of our anonymous function. + JIT->freeMachineCodeForFunction(f.f); f.f->eraseFromParent(); if (!res) { // We caught an exception, clean up the mess. @@ -2601,6 +2638,7 @@ int32_t tag = it->first; GlobalVar& v = globalvars[tag]; if (!v.x) { + v.clear(); JIT->updateGlobalMapping(v.v, 0); v.v->eraseFromParent(); globalvars.erase(tag); @@ -3288,7 +3326,8 @@ (ExprPtrTy, false, GlobalVariable::InternalLinkage, 0, mkvarlabel(tag), module); JIT->addGlobalMapping(v.v, &v.x); - } + } else + v.clear(); if (v.x) pure_free(v.x); v.x = pure_new(cv); return act_builder().CreateLoad(v.v); } Modified: pure/trunk/interpreter.hh =================================================================== --- pure/trunk/interpreter.hh 2008-05-01 15:29:39 UTC (rev 19) +++ pure/trunk/interpreter.hh 2008-05-02 03:55:18 UTC (rev 20) @@ -63,15 +63,17 @@ /* Data structures used in code generation. */ +struct Env; + struct GlobalVar { // global variable llvm::GlobalVariable* v; pure_expr *x; - GlobalVar() { v = 0; x = 0; } + Env *e; + GlobalVar() { v = 0; x = 0; e = 0; } + void clear(); }; -struct Env; - struct VarInfo { // info about captured variable uint32_t v; // local proxy (offset into extra parameter block) @@ -85,7 +87,6 @@ //#define Builder llvm::LLVMBuilder #define Builder llvm::LLVMFoldingBuilder -struct Env; typedef list<Env*> EnvStack; typedef pair<int32_t,uint8_t> xmap_key; @@ -126,6 +127,8 @@ Builder builder; // parent environment (if any) Env *parent; + // reference counter (for dodefn) + uint32_t refc; // convenience functions for invoking CreateGEP() and CreateLoad() llvm::Value *CreateGEP (llvm::Value *x, llvm::Value *i, const char* name = "") @@ -158,11 +161,11 @@ // default constructor Env() : tag(0), n(0), m(0), l(0), f(0), h(0), fp(0), args(0), envs(0), argv(0), - b(false), local(false), parent(0) {} + b(false), local(false), parent(0), refc(0) {} // environment for an anonymous closure with given body x Env(int32_t _tag, uint32_t _n, expr x, bool _b, bool _local = false) : tag(_tag), n(_n), m(0), l(0), f(0), h(0), fp(0), args(n), envs(0), - argv(0), b(_b), local(_local), parent(0) + argv(0), b(_b), local(_local), parent(0), refc(0) { if (envstk.empty()) { assert(!local); @@ -176,7 +179,7 @@ // environment for a named closure with given definition info Env(int32_t _tag, const env_info& info, bool _b, bool _local = false) : tag(_tag), n(info.argc), m(0), l(0), f(0), h(0), fp(0), args(n), envs(0), - argv(0), b(_b), local(_local), parent(0) + argv(0), b(_b), local(_local), parent(0), refc(0) { if (envstk.empty()) { assert(!local); Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-05-01 15:29:39 UTC (rev 19) +++ pure/trunk/runtime.cc 2008-05-02 03:55:18 UTC (rev 20) @@ -378,8 +378,16 @@ // parameterless call checkstk(test); return ((pure_expr*(*)())fp)(); - } else + } else { +#if DEBUG>2 + if (x->tag >= 0 && x->data.clos) + cerr << "pure_call: returning " << x << " -> " << x->data.clos->fp + << " (" << x->data.clos->n << " args)" << endl; + else + cerr << "pure_call: returning " << x << endl; +#endif return x; + } } extern "C" @@ -534,6 +542,9 @@ // Cast the function pointer to the right type (takes no arguments, returns // a pure_expr*), so we can call it as a native function. pure_expr *(*fp)() = (pure_expr*(*)())f; +#if DEBUG>1 + cerr << "pure_invoke: calling " << f << endl; +#endif // Push an exception. pure_exception ex; ex.e = 0; interp.estk.push_front(ex); // Call the function now. Catch exceptions generated by the runtime. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-05-02 05:31:22
|
Revision: 24 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=24&view=rev Author: agraef Date: 2008-05-01 22:31:22 -0700 (Thu, 01 May 2008) Log Message: ----------- Catch stack overflow in printer. Modified Paths: -------------- pure/trunk/printer.cc pure/trunk/runtime.cc Modified: pure/trunk/printer.cc =================================================================== --- pure/trunk/printer.cc 2008-05-02 05:00:29 UTC (rev 23) +++ pure/trunk/printer.cc 2008-05-02 05:31:22 UTC (rev 24) @@ -606,6 +606,11 @@ ostream& operator << (ostream& os, const pure_expr *x) { + char test; + if (interpreter::stackmax > 0 && + interpreter::stackdir*(&test - interpreter::baseptr) >= + interpreter::stackmax) + throw err("stack overflow in printer"); char buf[64]; assert(x); //os << "{" << x->refc << "}"; Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-05-02 05:00:29 UTC (rev 23) +++ pure/trunk/runtime.cc 2008-05-02 05:31:22 UTC (rev 24) @@ -1040,8 +1040,12 @@ { assert(x); ostringstream os; - os << x; - return pure_string_dup(os.str().c_str()); + try { + os << x; + return pure_string_dup(os.str().c_str()); + } catch (err &e) { + return 0; + } } extern "C" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-05-02 09:04:10
|
Revision: 30 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=30&view=rev Author: agraef Date: 2008-05-02 02:04:18 -0700 (Fri, 02 May 2008) Log Message: ----------- Added syntactic equality. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/lib/prelude.pure pure/trunk/lib/primitives.pure pure/trunk/runtime.cc pure/trunk/runtime.h Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-05-02 07:09:21 UTC (rev 29) +++ pure/trunk/ChangeLog 2008-05-02 09:04:18 UTC (rev 30) @@ -1,5 +1,8 @@ 2008-05-02 Albert Graef <Dr....@t-...> + * runtime.cc (same): Added a syntactic equality test. Requested by + Eddie Rucker. + * Makefile: Add $(LDFLAGS) and $(LIBS) to the link line, so that the user can easily add his own linker options and local libraries. Modified: pure/trunk/lib/prelude.pure =================================================================== --- pure/trunk/lib/prelude.pure 2008-05-02 07:09:21 UTC (rev 29) +++ pure/trunk/lib/prelude.pure 2008-05-02 09:04:18 UTC (rev 30) @@ -41,6 +41,7 @@ infixr 3 && ; // logical and (short-circuit) prefix 3 not ; // logical negation infix 4 < > <= >= == != ; // relations +infix 4 === !== ; // syntactic equality infixr 4 : ; // list cons infixl 5 << >> ; // bit shifts infixl 6 + - | ; // addition, bitwise or Modified: pure/trunk/lib/primitives.pure =================================================================== --- pure/trunk/lib/primitives.pure 2008-05-02 07:09:21 UTC (rev 29) +++ pure/trunk/lib/primitives.pure 2008-05-02 09:04:18 UTC (rev 30) @@ -24,6 +24,12 @@ extern void pure_throw(expr*); // IMPURE! throw x = pure_throw x; +/* Syntactic equality. */ + +extern bool same(expr* x, expr* y); +x === y = same x y; +x !== y = not same x y; + /* Predicates to check for the built-in types. */ intp x = case x of _::int = 1; _ = 0 end; Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-05-02 07:09:21 UTC (rev 29) +++ pure/trunk/runtime.cc 2008-05-02 09:04:18 UTC (rev 30) @@ -1059,6 +1059,42 @@ } extern "C" +bool same(const pure_expr *x, const pure_expr *y) +{ + char test; + if (x == y) + return 1; + else if (x->tag >= 0 && y->tag >= 0) + if (x->data.clos && y->data.clos) + return x->tag == y->tag && x->data.clos->fp == y->data.clos->fp; + else + return x->tag == y->tag && x->data.clos == y->data.clos; + else if (x->tag != y->tag) + return 0; + else { + switch (x->tag) { + case EXPR::APP: { + checkstk(test); + return same(x->data.x[0], y->data.x[0]) && + same(x->data.x[1], y->data.x[1]); + } + case EXPR::INT: + return x->data.i == y->data.i; + case EXPR::BIGINT: + return mpz_cmp(x->data.z, y->data.z) == 0; + case EXPR::DBL: + return x->data.d == y->data.d; + case EXPR::STR: + return strcmp(x->data.s, y->data.s) == 0; + case EXPR::PTR: + return x->data.p == y->data.p; + default: + return 1; + } + } +} + +extern "C" int32_t pointer_get_byte(void *ptr) { uint8_t *p = (uint8_t*)ptr; Modified: pure/trunk/runtime.h =================================================================== --- pure/trunk/runtime.h 2008-05-02 07:09:21 UTC (rev 29) +++ pure/trunk/runtime.h 2008-05-02 09:04:18 UTC (rev 30) @@ -252,6 +252,10 @@ pure_expr *str(const pure_expr *x); pure_expr *eval(const char *s); +/* Check whether two objects are the "same" (syntactically). */ + +bool same(const pure_expr *x, const pure_expr *y); + /* Direct memory accesses. */ int32_t pointer_get_byte(void *ptr); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-05-02 20:31:35
|
Revision: 32 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=32&view=rev Author: agraef Date: 2008-05-02 13:31:41 -0700 (Fri, 02 May 2008) Log Message: ----------- Overhaul of regression test goals. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/Makefile Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-05-02 20:30:47 UTC (rev 31) +++ pure/trunk/ChangeLog 2008-05-02 20:31:41 UTC (rev 32) @@ -1,5 +1,11 @@ 2008-05-02 Albert Graef <Dr....@t-...> + * Makefile: Overhaul of regression tests so that results of + expressions are recorded. Also, 'make check' doesn't depend on the + log files any more, so that the logs can be stored in svn. You can + now use the explicit goal 'make logs' to regenerate the logs for + changed test files. + * runtime.cc (same): Added a syntactic equality test. Requested by Eddie Rucker. Modified: pure/trunk/Makefile =================================================================== --- pure/trunk/Makefile 2008-05-02 20:30:47 UTC (rev 31) +++ pure/trunk/Makefile 2008-05-02 20:31:41 UTC (rev 32) @@ -168,16 +168,16 @@ logs: $(logs) -check: pure $(logs) +check: pure @ echo Running tests. @ (export PURELIB=./lib; echo -n "prelude.pure: "; if ./pure -n -v$(level) lib/prelude.pure | diff -q - test/prelude.log > /dev/null; then echo passed; else echo FAILED; fi) - @ (cd test; export PURELIB=../lib; for x in $(tests); do f="`basename $$x`"; l="`basename $$x .pure`.log"; echo -n "$$x: "; if ../pure -v$(level) $$f | diff -q - $$l > /dev/null; then echo passed; else echo FAILED; fi; done) + @ (cd test; export PURELIB=../lib; for x in $(tests); do f="`basename $$x`"; l="`basename $$x .pure`.log"; echo -n "$$x: "; if ../pure -v$(level) < $$f | diff -q - $$l > /dev/null; then echo passed; else echo FAILED; fi; done) test/prelude.log: lib/prelude.pure PURELIB=./lib ./pure -n -v$(level) $< > $@ %.log: %.pure - PURELIB=./lib ./pure -v$(level) $< > $@ + PURELIB=./lib ./pure -v$(level) < $< > $@ # DO NOT DELETE This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-05-03 05:35:34
|
Revision: 33 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=33&view=rev Author: agraef Date: 2008-05-02 22:35:42 -0700 (Fri, 02 May 2008) Log Message: ----------- Corrected regression test. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/test/test1.log pure/trunk/test/test1.pure Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-05-02 20:31:41 UTC (rev 32) +++ pure/trunk/ChangeLog 2008-05-03 05:35:42 UTC (rev 33) @@ -1,3 +1,8 @@ +2008-05-03 Albert Graef <Dr....@t-...> + + * test/test1.pure: Corrected fact3 example, added test cases. + Reported by Libor Spacek. + 2008-05-02 Albert Graef <Dr....@t-...> * Makefile: Overhaul of regression tests so that results of Modified: pure/trunk/test/test1.log =================================================================== --- pure/trunk/test/test1.log 2008-05-02 20:31:41 UTC (rev 32) +++ pure/trunk/test/test1.log 2008-05-03 05:35:42 UTC (rev 33) @@ -23,6 +23,8 @@ state 1: #0 } let x = fact1 10; +x; +3628800 fact2 n/*0:1*/ = case n/*0:1*/ of n/*0:*/ = n/*0:*/*fact2 (n/*0:*/-1) if n/*0:*/>0; n/*0:*/ = 1 { rule #0: n = n*fact2 (n-1) if n>0 rule #1: n = 1 @@ -30,9 +32,9 @@ <var> state 1 state 1: #0 #1 } end; -fact3 n/*0:1*/ = case n/*0:1*/ of 0 = 1; n/*0:*/ = n/*0:*/*fact3 (n/*0:*/-1) if n/*0:*/>1 { +fact3 n/*0:1*/ = case n/*0:1*/ of 0 = 1; n/*0:*/ = n/*0:*/*fact3 (n/*0:*/-1) if n/*0:*/>0 { rule #0: 0 = 1 - rule #1: n = n*fact3 (n-1) if n>1 + rule #1: n = n*fact3 (n-1) if n>0 state 0: #0 #1 <var> state 1 0::int state 2 @@ -46,9 +48,51 @@ <var> state 1 state 1: #0 }; +{ + rule #0: fact2 n = case n of n = n*fact2 (n-1) if n>0; n = 1 end + state 0: #0 + <var> state 1 + state 1: #0 +} +{ + rule #0: fact3 n = case n of 0 = 1; n = n*fact3 (n-1) if n>0 end + state 0: #0 + <var> state 1 + state 1: #0 +} +{ + rule #0: fact4 n = if n>0 then n*fact4 (n-1) else 1 + state 0: #0 + <var> state 1 + state 1: #0 +} +{ + rule #0: fact5 = \n -> if n>0 then n*fact5 (n-1) else 1 + state 0: #0 +} +fact2 10; +3628800 +fact3 10; +3628800 +fact4 10; +3628800 +fact5 10; +3628800 fact n/*0:1*/::int = fact (bigint n/*0:1*/); fact n/*0:1*/::bigint = n/*0:1*/*fact (n/*0:1*/-1) if n/*0:1*/>0; fact n/*0:1*/::bigint = 1; +{ + rule #0: fact n::int = fact (bigint n) + rule #1: fact n::bigint = n*fact (n-1) if n>0 + rule #2: fact n::bigint = 1 + state 0: #0 #1 #2 + <var>::int state 1 + <var>::bigint state 2 + state 1: #0 + state 2: #1 #2 +} +fact 50; +30414093201713378043612608166064768844377641568960512000000000000 fib1 0 = 0; fib1 1 = 1; fib1 n/*0:1*/ = fib1 (n/*0:1*/-2)+fib1 (n/*0:1*/-1) if n/*0:1*/>1; @@ -119,38 +163,6 @@ state 1: #0 #1 } end; { - rule #0: fact2 n = case n of n = n*fact2 (n-1) if n>0; n = 1 end - state 0: #0 - <var> state 1 - state 1: #0 -} -{ - rule #0: fact3 n = case n of 0 = 1; n = n*fact3 (n-1) if n>1 end - state 0: #0 - <var> state 1 - state 1: #0 -} -{ - rule #0: fact4 n = if n>0 then n*fact4 (n-1) else 1 - state 0: #0 - <var> state 1 - state 1: #0 -} -{ - rule #0: fact5 = \n -> if n>0 then n*fact5 (n-1) else 1 - state 0: #0 -} -{ - rule #0: fact n::int = fact (bigint n) - rule #1: fact n::bigint = n*fact (n-1) if n>0 - rule #2: fact n::bigint = 1 - state 0: #0 #1 #2 - <var>::int state 1 - <var>::bigint state 2 - state 1: #0 - state 2: #1 #2 -} -{ rule #0: fib1 0 = 0 rule #1: fib1 1 = 1 rule #2: fib1 n = fib1 (n-2)+fib1 (n-1) if n>1 Modified: pure/trunk/test/test1.pure =================================================================== --- pure/trunk/test/test1.pure 2008-05-02 20:31:41 UTC (rev 32) +++ pure/trunk/test/test1.pure 2008-05-03 05:35:42 UTC (rev 33) @@ -14,7 +14,7 @@ fact1 n = n*fact1 (n-1) if n>0; = 1 otherwise; -let x = fact1 10; +let x = fact1 10; x; // Factorial, using case. @@ -27,7 +27,7 @@ fact3 n = case n of 0 = 1; - n = n*fact3 (n-1) if n>1; + n = n*fact3 (n-1) if n>0; end; // Factorial, with if-then-else. @@ -38,12 +38,19 @@ fact5 = \n -> if n>0 then n*fact5 (n-1) else 1; +fact2 10; +fact3 10; +fact4 10; +fact5 10; + // Factorial, using bigints. fact n::int = fact (bigint n); fact n::bigint = n*fact (n-1) if n>0; = 1 otherwise; +fact 50; + // Fibonacci function, naive O(fib n) implementation. fib1 0 = 0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-05-03 06:22:18
|
Revision: 34 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=34&view=rev Author: agraef Date: 2008-05-02 23:22:23 -0700 (Fri, 02 May 2008) Log Message: ----------- Disable tail call checks, as they may fail on some platforms. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/test/test4.log pure/trunk/test/test4.pure Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-05-03 05:35:42 UTC (rev 33) +++ pure/trunk/ChangeLog 2008-05-03 06:22:23 UTC (rev 34) @@ -1,5 +1,8 @@ 2008-05-03 Albert Graef <Dr....@t-...> + * test/test4.pure: Disable tail call checks, as they may fail on + some platforms. Reported by Ryan Schmidt. + * test/test1.pure: Corrected fact3 example, added test cases. Reported by Libor Spacek. Modified: pure/trunk/test/test4.log =================================================================== --- pure/trunk/test/test4.log 2008-05-03 05:35:42 UTC (rev 33) +++ pure/trunk/test/test4.log 2008-05-03 06:22:23 UTC (rev 34) @@ -64,8 +64,6 @@ } count 100; 0 -count 10000000; -0 count2 n/*0:1*/::int = n/*0:1*/ if n/*0:1*/<=0; count2 n/*0:1*/::int = count2 (n/*0:1*/-1); { @@ -77,8 +75,6 @@ } count2 100; 0 -count2 10000000; -0 test x/*0:1*/::int = t/*0*/ x/*0:1*/ with t n/*0:1*/::int = t/*1*/ (-n/*0:1*/) if n/*0:1*/<0; t n/*0:1*/::int = u/*0*/ (n/*0:1*/+2) with u _/*0:1*/ = n/*1:1*/+1 { rule #0: u _ = n+1 state 0: #0 Modified: pure/trunk/test/test4.pure =================================================================== --- pure/trunk/test/test4.pure 2008-05-03 05:35:42 UTC (rev 33) +++ pure/trunk/test/test4.pure 2008-05-03 06:22:23 UTC (rev 34) @@ -28,7 +28,7 @@ count 100; // If proper tail calls are supported, this should work, too, no matter what // your stack size is. -count 10000000; +//count 10000000; // Tail recursion in a global function. @@ -37,8 +37,9 @@ // This should always work. count2 100; -// Again, this should work as well, no matter what your stack size is. -count2 10000000; +// Again, this should work if proper tail calls are supported, no matter what +// your stack size is. +//count2 10000000; // Trivial tail-recursive local function which passes an environment to // another local function. Note that the callee can never be tail-called in This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-05-03 10:05:37
|
Revision: 35 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=35&view=rev Author: agraef Date: 2008-05-03 03:05:43 -0700 (Sat, 03 May 2008) Log Message: ----------- Remove temporary workaround which hopefully isn't needed anymore. Modified Paths: -------------- pure/trunk/interpreter.cc pure/trunk/interpreter.hh Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-05-03 06:22:23 UTC (rev 34) +++ pure/trunk/interpreter.cc 2008-05-03 10:05:43 UTC (rev 35) @@ -735,7 +735,6 @@ f->dropAllReferences(); if (h != f) h->eraseFromParent(); f->eraseFromParent(); - reset(); } } @@ -2495,28 +2494,6 @@ return f; } -void interpreter::reset() -{ - /* XXXFIXME: Compile a trivial function to reprime the JIT. Apparently this - is needed to convince the JIT to pick up changes after clearing a - function definition. Don't ask, I don't understand it either. :( Maybe - it's a subtle bug somewhere in the code generator, but I found no other - way to work around it. If anyone knows why this is needed, or has a - better way to do it, please let me know. */ - expr x(EXPR::INT, 0); - Env e(0, 0, x, false); - push("reset", &e); - fun_prolog(""); - e.CreateRet(codegen(x)); - fun_finish(); - pop(&e); - e.fp = JIT->getPointerToFunction(e.f); - assert(e.fp); - pure_expr *y = 0, *res = pure_invoke(e.fp, y); - assert(res); pure_freenew(res); - e.f->eraseFromParent(); -} - pure_expr *interpreter::doeval(expr x, pure_expr*& e) { char test; Modified: pure/trunk/interpreter.hh =================================================================== --- pure/trunk/interpreter.hh 2008-05-03 06:22:23 UTC (rev 34) +++ pure/trunk/interpreter.hh 2008-05-03 10:05:43 UTC (rev 35) @@ -402,7 +402,6 @@ Env *find_stacked(int32_t tag); Env& act_env() { assert(!envstk.empty()); return *envstk.front(); } Builder& act_builder() { return act_env().builder; } - void reset(); pure_expr *doeval(expr x, pure_expr*& e); pure_expr *dodefn(env vars, expr lhs, expr rhs, pure_expr*& e); llvm::Value *codegen(expr x); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-05-03 10:28:54
|
Revision: 36 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=36&view=rev Author: agraef Date: 2008-05-03 03:29:01 -0700 (Sat, 03 May 2008) Log Message: ----------- Fixed premature garbage collection of arguments in external wrapper code. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/interpreter.cc Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-05-03 10:05:43 UTC (rev 35) +++ pure/trunk/ChangeLog 2008-05-03 10:29:01 UTC (rev 36) @@ -1,6 +1,13 @@ 2008-05-03 Albert Graef <Dr....@t-...> - * test/test4.pure: Disable tail call checks, as they may fail on + * interpreter.cc (declare_extern): Fixed a bug in the generated + wrapper code for external calls, which caused function arguments + to be garbage-collected prematurely, when they were still needed + to create the default value, in the case of external calls + returning a null expression pointer to indicate failure. Reported + by Eddie Rucker. + + * test/test4.pure: Disabled tail call checks, as they may fail on some platforms. Reported by Ryan Schmidt. * test/test1.pure: Corrected fact3 example, added test cases. Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-05-03 10:05:43 UTC (rev 35) +++ pure/trunk/interpreter.cc 2008-05-03 10:29:01 UTC (rev 36) @@ -2405,19 +2405,8 @@ } // call the function Value* u = b.CreateCall(g, unboxed.begin(), unboxed.end()); - // free temporaries and arguments + // free temporaries if (temps) b.CreateCall(module->getFunction("pure_free_cstrings")); - if (n == 1) - b.CreateCall(module->getFunction("pure_free"), args[0]); - else if (n > 0) { - vector<Value*> freeargs(n+2); - freeargs[0] = NullExprPtr; - for (size_t i = 0; i < n; i++) - freeargs[i+1] = args[i]; - freeargs[n+1] = NullExprPtr; - b.CreateCall(module->getFunction("pure_free_args"), - freeargs.begin(), freeargs.end()); - } // box the result if (type == Type::VoidTy) u = b.CreateCall(module->getFunction("pure_const"), @@ -2456,6 +2445,18 @@ u = b.CreateCall(module->getFunction("pure_pointer"), u); else assert(0 && "invalid C type"); + // free arguments (we do that here so that the arguments don't get freed + // before we know that we don't need them anymore) + if (n > 0) { + vector<Value*> freeargs(n+2); + freeargs[0] = u; + for (size_t i = 0; i < n; i++) + freeargs[i+1] = args[i]; + freeargs[n+1] = NullExprPtr; + b.CreateCall(module->getFunction("pure_free_args"), + freeargs.begin(), freeargs.end()); + b.CreateCall(module->getFunction("pure_unref"), u); + } b.CreateRet(u); // The call failed. Provide a default value. f->getBasicBlockList().push_back(failedbb); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-05-03 10:48:09
|
Revision: 37 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=37&view=rev Author: agraef Date: 2008-05-03 03:48:16 -0700 (Sat, 03 May 2008) Log Message: ----------- Fix up iconv() calls for compatibility with OSX. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/util.cc Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-05-03 10:29:01 UTC (rev 36) +++ pure/trunk/ChangeLog 2008-05-03 10:48:16 UTC (rev 37) @@ -1,5 +1,8 @@ 2008-05-03 Albert Graef <Dr....@t-...> + * util.cc (myiconv): Apple's iconv takes const char** as 2nd + parameter. #ifdef that case. Reported by Ryan Schmidt. + * interpreter.cc (declare_extern): Fixed a bug in the generated wrapper code for external calls, which caused function arguments to be garbage-collected prematurely, when they were still needed Modified: pure/trunk/util.cc =================================================================== --- pure/trunk/util.cc 2008-05-03 10:29:01 UTC (rev 36) +++ pure/trunk/util.cc 2008-05-03 10:48:16 UTC (rev 37) @@ -433,6 +433,14 @@ #endif /* HAVE_LANGINFO_CODESET */ } +#ifdef __APPLE__ +#define myiconv(ic, inbuf, inbytes, outbuf, outbytes) \ + iconv(ic, (const char**)inbuf, inbytes, outbuf, outbytes) +#else +#define myiconv(ic, inbuf, inbytes, outbuf, outbytes) \ + iconv(ic, inbuf, inbytes, outbuf, outbytes) +#endif + #define CHUNKSZ 128 char * @@ -455,7 +463,7 @@ char *inbuf = (char*)s, *outbuf = t; // const char* -> char*. Ugh. size_t inbytes = l, outbytes = l; - while (iconv(ic, &inbuf, &inbytes, &outbuf, &outbytes) == + while (myiconv(ic, &inbuf, &inbytes, &outbuf, &outbytes) == (size_t)-1) if (errno == E2BIG) { /* try to enlarge the output buffer */ @@ -508,7 +516,7 @@ char *inbuf = (char*)s, *outbuf = t; // const char* -> char*. Ugh. size_t inbytes = l, outbytes = l; - while (iconv(ic, &inbuf, &inbytes, &outbuf, &outbytes) == + while (myiconv(ic, &inbuf, &inbytes, &outbuf, &outbytes) == (size_t)-1) if (errno == E2BIG) { /* try to enlarge the output buffer */ @@ -532,7 +540,7 @@ /* here we might have to deal with a stateful encoding, so make sure that we emit the closing shift sequence */ - while (iconv(ic, NULL, NULL, &outbuf, &outbytes) == + while (myiconv(ic, NULL, NULL, &outbuf, &outbytes) == (size_t)-1) if (errno == E2BIG) { /* try to enlarge the output buffer */ @@ -580,7 +588,7 @@ char *inbuf = s; wchar_t *outbuf = t; size_t inbytes = l, outbytes = l*sizeof(wchar_t); - if (iconv(myic[1], &inbuf, &inbytes, (char**)&outbuf, &outbytes) == + if (myiconv(myic[1], &inbuf, &inbytes, (char**)&outbuf, &outbytes) == (size_t)-1) return NULL; /* terminate the output string */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-05-03 12:28:39
|
Revision: 38 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=38&view=rev Author: agraef Date: 2008-05-03 05:28:44 -0700 (Sat, 03 May 2008) Log Message: ----------- Updated README, added detailed installation instructions in INSTALL. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/Makefile pure/trunk/README Added Paths: ----------- pure/trunk/INSTALL Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-05-03 10:48:16 UTC (rev 37) +++ pure/trunk/ChangeLog 2008-05-03 12:28:44 UTC (rev 38) @@ -1,5 +1,8 @@ 2008-05-03 Albert Graef <Dr....@t-...> + * README: Moved installation instructions to a separate INSTALL + file, added Eddie Rucker's detailed instructions there. + * util.cc (myiconv): Apple's iconv takes const char** as 2nd parameter. #ifdef that case. Reported by Ryan Schmidt. Added: pure/trunk/INSTALL =================================================================== --- pure/trunk/INSTALL (rev 0) +++ pure/trunk/INSTALL 2008-05-03 12:28:44 UTC (rev 38) @@ -0,0 +1,174 @@ + +INSTALLING PURE (AND LLVM) +========== ==== ==== ===== + +These instructions (by courtesy of Eddie Rucker, thanks Eddie!) explain how to +compile and install LLVM (which is the compiler backend required by Pure) and +the Pure interpreter itself. More information about installing LLVM and the +required LLVM source packages can be found at http://llvm.org. + + +BASIC INSTALLATION +===== ============ + +The basic installation process is as follows. Note that steps 1-3 are only +required once. Steps 2-3 can be avoided if binary LLVM packages are available +for your system. Additional instructions for compiling Pure from SVN sources +can be found in the INSTALLING FROM SVN SOURCES section below. Moreover, you +can refer to the OTHER COMPILATION OPTIONS section at the end of the file for +details about various options available when building and installing Pure. + +STEP 1. Make sure you have all the necessary dependencies installed (-dev +denotes corresponding development packages): + +- GNU make, GNU C++ and the corresponding libraries; + +- flex and bison (these are only required when compiling the Pure SVN sources, + see the INSTALLING FROM SVN SOURCES section below); + +- libgmp, -dev; + +- libreadline, -dev; + +- libltdl, -dev; + +- subversion (only needed to fetch the SVN sources, see below). + +E.g., the required packages for Ubuntu are: make, g++, g++ 4.0 multilib, flex, +bison, libgmp3c2, libgmp3-dev, readline5-dev, libltdl3, libldtl3-dev, +subversion. + +STEP 2. Get and unpack the LLVM 2.2 sources at: +http://llvm.org/releases/download.html#2.2 + +STEP 3. Configure, build and install LLVM as follows: + +$ cd llvm-2.2 +$ ./configure +$ make +$ sudo make install + +STEP 4. Get and unpack the Pure sources at: http://pure-lang.sf.net/ + +The latest release tarballs can always be found on the SourceForge project +page. See "Downloads" on the Pure website for a quick link to the download +section. + +STEP 5. Build and install the release version of Pure as follows: + +$ cd pure-x.y +$ make build=release +$ sudo make install + +Here, x.y denotes the current Pure version number (0.1 at the time of this +writing). If you want to install the debugging-enabled version, run just +'make' instead of 'make build=release'. + +To check that Pure is working correctly on your computer, also run: + +$ make check + +STEP 6. The Pure interpreter should be ready to go now. (On some systems you +might first have to run ldconfig to update the dynamic linker cache.) + +Run Pure interactively as: + +$ pure +Pure 0.1 Copyright (c) 2008 by Albert Graef +This program is free software distributed under the GNU Public License +(GPL V3 or later). Please see the COPYING file for details. +Loaded prelude from /usr/local/lib/pure/prelude.pure. + +Check that it works: + +> 6*7; +42 + +Read the online documentation (this invokes the Pure manual page): + +> help + +Exit the interpreter (you can also just type the end-of-file character at the +beginning of a line, i.e., Ctrl-D on Unix): + +> quit + + +INSTALLING FROM SVN SOURCES +========== ==== === ======= + +The latest development version of Pure is available in its subversion (SVN) +source code repository. You can browse the repository at: + +http://pure-lang.svn.sourceforge.net/viewvc/pure-lang/ + +(See the pure/trunk subdirectory for the latest sources.) + +Note that if you're going with the development sources, you'll also need +fairly recent versions of the flex and bison utilities (flex 2.5.31 and bison +2.3 should be ok). + +To compile from the development sources, replace steps 4 and 5 above with: + +STEP 4': Fetch the SVN sources. + +$ svn co http://pure-lang.svn.sourceforge.net/svnroot/pure-lang pure-lang + +STEP 5': Build and install the debugging-enabled version (of course you can +also build the release version, as described in step 5 above): + +$ cd pure-lang/pure/trunk +$ make +$ sudo make install + + +OTHER COMPILATION OPTIONS +===== =========== ======= + +By default, the pure program is installed under /usr/local/bin, with the +library files going into /usr/local/lib/pure. The installation directory can +be changed by editing the definition of the 'prefix' variable in the Makefile, +or by specifying the desired value on the 'make' command line, e.g.: + +$ make all install prefix=/usr + +Note that you should specify this option *both* at compile and installation +time since certain default paths are hardcoded into the interpreter (but can +be changed at runtime by setting corresponding environment variables, see the +manpage for details). + +There are a number of other variables you can set on the 'make' command line +if you need special compiler (CXXFLAGS) or linker flags (LDFLAGS), or if you +have to add platform-specific libraries (LIBS) like libiconv on OSX. + +After your build is done, you can (and should) also run 'make check' to verify +that your Pure interpreter works correctly. This can be done without +installing the software. In fact, there's no need to install the interpreter +if you just want to take it for a test drive, you can simply run it from the +source directory. Just make sure that you set the PURELIB environment variable +to the lib directory in the sources which holds the prelude and the other +library scripts. The following command, + +$ PURELIB=./lib ./pure + +will run the Pure interpreter with that setting in Bourne-compatible shells. + +For the release version, you should build the interpreter as follows: + +$ make build=release + +This disables all runtime checks and debugging information in the interpreter. +(Don't worry, your Pure programs will still be executed "safely" and shouldn't +segfault unless you run out of memory or there's a bug in the interpreter.) +The 'release' build gives you *much* faster execution times (factor of 2 +compared to the default flags on my Linux system running gcc 4.1, YMMV). It +also takes a *long* time to compile runtime.cc, but it's really worth the +wait, so please be patient. ;-) + +Please also have a look at the Makefile for details on the build and +installation process and other available targets and options. + + +May 2008 +Albert Graef <Dr.Graef at t-online.de> +Eddie Rucker <erucker at bmc.edu> Modified: pure/trunk/Makefile =================================================================== --- pure/trunk/Makefile 2008-05-03 10:48:16 UTC (rev 37) +++ pure/trunk/Makefile 2008-05-03 12:28:44 UTC (rev 38) @@ -80,7 +80,7 @@ logs = test/prelude.log $(tests:.pure=.log) distlogs = $(wildcard test/*.log) -DISTFILES = COPYING ChangeLog NEWS README TODO Makefile \ +DISTFILES = COPYING ChangeLog INSTALL NEWS README TODO Makefile \ $(SOURCE) $(EXTRA_SOURCE) w3centities.c pure.1 pure.xml pure.vim \ $(examples) $(lib) $(tests) $(distlogs) Modified: pure/trunk/README =================================================================== --- pure/trunk/README 2008-05-03 10:48:16 UTC (rev 37) +++ pure/trunk/README 2008-05-03 12:28:44 UTC (rev 38) @@ -23,58 +23,15 @@ INSTALLATION -The usual 'make && make install' should do the trick. (No 'configure' step -necessary.) This requires GNU make and g++. For other setups, you'll probably -have to fiddle with the Makefile and the sources. The sources should be pretty -portable, but the Makefile really needs GNU make right now. +Please see the INSTALL file for detailed instructions. On most Unix-like +systems, the usual 'make && sudo make install' should do the trick. (No +'configure' step necessary.) This requires GNU make and g++. For other setups, +you'll probably have to fiddle with the Makefile and the sources. The sources +should be pretty portable, but the Makefile really needs GNU make right now. +You'll also need LLVM for the compiler backend (version 2.2 has been tested). +For your convenience, instructions for installing LLVM are also included in +the INSTALL file. -You'll also need LLVM (version 2.2 has been tested) for the compiler backend; -install it before compiling Pure. Instructions for installing LLVM can be -found at the LLVM website (http://llvm.org). - -By default, the program is installed under /usr/local/bin, with the library -files going into /usr/local/lib/pure. The installation directory can be -changed by editing the definition of the 'prefix' variable in the Makefile, or -by specifying the desired value on the 'make' command line, e.g.: - - make all install prefix=/usr - -Note that you should specify this option *both* at compile and installation -time since certain default paths are hardcoded into the interpreter (but can -be changed at runtime by setting corresponding environment variables, see the -manpage for details). - -There are a number of other variables you can set on the 'make' command line -if you need special compiler (CXXFLAGS) or linker flags (LDFLAGS), or if you -have to add special libraries (LIBS) like libiconv on OSX. - -After your build is done, you can (and should) also run 'make check' to verify -that your Pure interpreter works correctly. This can be done without -installing the software. In fact, there's no need to install the interpreter -if you just want to take it for a test drive, you can simply run it from the -source directory. Just make sure that you set the PURELIB environment variable -to the lib directory in the sources which holds the prelude and the other -library scripts. The following command, - - PURELIB=./lib ./pure - -will run the Pure interpreter with that setting in Bourne-compatible shells. - -For the release version, you should build the interpreter as follows: - - make build=release - -This disables all runtime checks and debugging information in the interpreter. -(Don't worry, your Pure programs will still be executed "safely" and shouldn't -segfault unless you run out of memory or there's a bug in the interpreter.) -The 'release' build gives you *much* faster execution times (factor of 2 -compared to the default flags on my Linux system running gcc 4.1, YMMV). It -also takes a *long* time to compile runtime.cc, but it's really worth the -wait, so please be patient. ;-) - -Please also have a look at the Makefile for details on the build and -installation process and other available targets and options. - USING PURE Pure scripts are just ordinary text files, which can be created with any text @@ -107,5 +64,5 @@ Johannes Gutenberg University of Mainz Germany -<Dr....@t-...> +<Dr.Graef at t-online.de> http://pure-lang.sf.net This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-05-03 22:02:19
|
Revision: 40 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=40&view=rev Author: agraef Date: 2008-05-03 15:02:26 -0700 (Sat, 03 May 2008) Log Message: ----------- Add operations to check for and deconstruct function applications. Modified Paths: -------------- pure/trunk/lib/primitives.pure pure/trunk/runtime.cc pure/trunk/runtime.h Modified: pure/trunk/lib/primitives.pure =================================================================== --- pure/trunk/lib/primitives.pure 2008-05-03 21:06:12 UTC (rev 39) +++ pure/trunk/lib/primitives.pure 2008-05-03 22:02:26 UTC (rev 40) @@ -38,8 +38,11 @@ stringp x = case x of _::string = 1; _ = 0 end; pointerp x = case x of _::pointer = 1; _ = 0 end; -/* Predicates to check for proper lists and tuples. */ +/* Predicates to check for function applications and proper lists and + tuples. */ +extern bool applp(expr*); + listp [] = 1; listp (x:xs) = listp xs; listp _ = 0 otherwise; @@ -48,6 +51,10 @@ tuplep (x,xs) = 1; tuplep _ = 0 otherwise; +/* Operations to return the function and the argument in an application. */ + +extern expr* fun(expr*), expr* arg(expr*); + /* Conversions between the different numeric and pointer types. */ extern expr* pure_intval(expr*), expr* pure_dblval(expr*), Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-05-03 21:06:12 UTC (rev 39) +++ pure/trunk/runtime.cc 2008-05-03 22:02:26 UTC (rev 40) @@ -1095,6 +1095,30 @@ } extern "C" +bool applp(const pure_expr *x) +{ + return (x->tag == EXPR::APP); +} + +extern "C" +pure_expr *fun(const pure_expr *x) +{ + if (x->tag == EXPR::APP) + return x->data.x[0]; + else + return 0; +} + +extern "C" +pure_expr *arg(const pure_expr *x) +{ + if (x->tag == EXPR::APP) + return x->data.x[1]; + else + return 0; +} + +extern "C" int32_t pointer_get_byte(void *ptr) { uint8_t *p = (uint8_t*)ptr; Modified: pure/trunk/runtime.h =================================================================== --- pure/trunk/runtime.h 2008-05-03 21:06:12 UTC (rev 39) +++ pure/trunk/runtime.h 2008-05-03 22:02:26 UTC (rev 40) @@ -256,6 +256,16 @@ bool same(const pure_expr *x, const pure_expr *y); +/* Check whether an object is a function application, and return the function + and the argument of an application. Note that these operations can't be + defined in Pure because of the "head is function" rule which means that in + a pattern of the form f x, f is always a literal function symbol and not a + variable. */ + +bool applp(const pure_expr *x); +pure_expr *fun(const pure_expr *x); +pure_expr *arg(const pure_expr *x); + /* Direct memory accesses. */ int32_t pointer_get_byte(void *ptr); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-05-03 23:33:33
|
Revision: 43 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=43&view=rev Author: agraef Date: 2008-05-03 16:33:41 -0700 (Sat, 03 May 2008) Log Message: ----------- Add an explicit notation for big integers. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/lexer.ll pure/trunk/printer.cc pure/trunk/test/test1.log Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-05-03 23:01:13 UTC (rev 42) +++ pure/trunk/ChangeLog 2008-05-03 23:33:41 UTC (rev 43) @@ -1,5 +1,13 @@ 2008-05-04 Albert Graef <Dr....@t-...> + * lexer.ll, printer.cc: Add an explicit notation for big + integers. Any integer immediately followed by the uppercase letter + "G" (as in "biG" or "GMP") will now always be interpreted as a + bigint constant, even if it fits into a machine integer. This + notation is also used when printing bigint constants. This change + was necessary to make it possible to write rules matching against + "small bigint" constants. + * lib/primitives.pure: Added operations to recognize function applications and extract the function and argument parts, implemented in runtime.cc. Note that these operations can't be Modified: pure/trunk/lexer.ll =================================================================== --- pure/trunk/lexer.ll 2008-05-03 23:01:13 UTC (rev 42) +++ pure/trunk/lexer.ll 2008-05-03 23:33:41 UTC (rev 43) @@ -604,6 +604,13 @@ return token::BIGINT; } } +{int}G { + mpz_t *z = (mpz_t*)malloc(sizeof(mpz_t)); + mpz_init(*z); + mpz_set_str(*z, yytext, 0); + yylval->zval = z; + return token::BIGINT; +} {float} yylval->dval = my_strtod(yytext, NULL); return(token::DBL); \"{str}\" { char *msg; Modified: pure/trunk/printer.cc =================================================================== --- pure/trunk/printer.cc 2008-05-03 23:01:13 UTC (rev 42) +++ pure/trunk/printer.cc 2008-05-03 23:33:41 UTC (rev 43) @@ -202,7 +202,7 @@ return os << x.ival(); case EXPR::BIGINT: { char *s = mpz_get_str(NULL, 10, x.zval()); - os << s; free(s); + os << s << "G"; free(s); return os; } case EXPR::DBL: { @@ -439,7 +439,7 @@ return os << " state " << tr.st->s << endl; case EXPR::BIGINT: { char *s = mpz_get_str(NULL, 10, tr.z); - os << "\t" << s; + os << "\t" << s << "G"; print_ttag(os, tr.ttag); os << " state " << tr.st->s << endl; free(s); @@ -621,7 +621,7 @@ return os << x->data.i; case EXPR::BIGINT: { char *s = mpz_get_str(NULL, 10, x->data.z); - os << s; free(s); + os << s << "G"; free(s); return os; } case EXPR::DBL: { Modified: pure/trunk/test/test1.log =================================================================== --- pure/trunk/test/test1.log 2008-05-03 23:01:13 UTC (rev 42) +++ pure/trunk/test/test1.log 2008-05-03 23:33:41 UTC (rev 43) @@ -92,7 +92,7 @@ state 2: #1 #2 } fact 50; -30414093201713378043612608166064768844377641568960512000000000000 +30414093201713378043612608166064768844377641568960512000000000000G fib1 0 = 0; fib1 1 = 1; fib1 n/*0:1*/ = fib1 (n/*0:1*/-2)+fib1 (n/*0:1*/-1) if n/*0:1*/>1; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-05-04 09:22:37
|
Revision: 47 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=47&view=rev Author: agraef Date: 2008-05-04 02:22:44 -0700 (Sun, 04 May 2008) Log Message: ----------- Release 0.2. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/Makefile pure/trunk/NEWS Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-05-04 08:55:48 UTC (rev 46) +++ pure/trunk/ChangeLog 2008-05-04 09:22:44 UTC (rev 47) @@ -1,5 +1,7 @@ 2008-05-04 Albert Graef <Dr....@t-...> + * 0.2 release. + * lexer.ll, printer.cc: Add an explicit notation for big integers. Any integer immediately followed by the uppercase letter "G" (as in "biG" or "GMP") will now always be interpreted as a @@ -84,6 +86,10 @@ * lexer.ll, parser.yy: Fixes for compatibility with newer flex and bison versions. Reported by Eddie Rucker. +2008-04-29 Albert Graef <Dr....@t-...> + + * 0.1 release. + 2008-04-28 Albert Graef <Dr....@t-...> * examples/symbolic.pure: Add symbolic evaluation example. This is Modified: pure/trunk/Makefile =================================================================== --- pure/trunk/Makefile 2008-05-04 08:55:48 UTC (rev 46) +++ pure/trunk/Makefile 2008-05-04 09:22:44 UTC (rev 47) @@ -9,7 +9,7 @@ # installation time, you can also specify a DESTDIR path if you want to # install into a staging directory, e.g.: 'make install DESTDIR=$PWD/BUILD'. -version = 0.1 +version = 0.2 dist = pure-$(version) prefix = /usr/local @@ -85,7 +85,7 @@ $(examples) $(lib) $(tests) $(distlogs) .PHONY: all html dvi ps pdf clean realclean depend install uninstall dist \ -logs check +distcheck cleanlogs logs check # compilation @@ -162,6 +162,11 @@ tar cfzh $(dist).tar.gz $(dist) rm -rf $(dist) +distcheck: dist + tar xfz $(dist).tar.gz + cd $(dist) && make && make check && make install DESTDIR=./BUILD + rm -rf $(dist) + # test logs, make check level=7 Modified: pure/trunk/NEWS =================================================================== --- pure/trunk/NEWS 2008-05-04 08:55:48 UTC (rev 46) +++ pure/trunk/NEWS 2008-05-04 09:22:44 UTC (rev 47) @@ -1,4 +1,21 @@ +** Pure 0.2 2008-05-04 + +On the heels of Pure 0.1 comes the first bugfix release which addresses a +couple of bugs, misfeatures and Mac OSX compatibility issues, please refer to +the ChangeLog for details. I also added a more detailed INSTALL guide (thanks +are due to Eddie Rucker who wrote most of the new material in this guide) and +updated the manpage with a few minor corrections and some remarks about issues +raised on the Pure mailing list. + +Please note that there are still some issues with Pure on 64 bit systems (as +well as on Ubuntu running on PowerPC) which are still on my TODO list, these +will hopefully be fixed in the next release. + +Thanks to all who sent in bug reports and patches, in particular: Chris +Double, Tim Haynes, Eddie Rucker, Ryan Schmidt and Libor Spacek. (I hope I +didn't forget anyone.) + ** Pure 0.1 2008-04-29 The much-awaited initial release. ;-) The interpreter is already fully This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-05-04 10:10:29
|
Revision: 50 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=50&view=rev Author: agraef Date: 2008-05-04 03:10:37 -0700 (Sun, 04 May 2008) Log Message: ----------- Add missing dependency of pure.o on Makefile. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/Makefile Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-05-04 09:30:54 UTC (rev 49) +++ pure/trunk/ChangeLog 2008-05-04 10:10:37 UTC (rev 50) @@ -1,5 +1,9 @@ 2008-05-04 Albert Graef <Dr....@t-...> + * Makefile (pure.o): Add missing dependency of pure.o on Makefile, + so that the main module gets recompiled when bumping the version + number. + * 0.2 release. * lexer.ll, printer.cc: Add an explicit notation for big Modified: pure/trunk/Makefile =================================================================== --- pure/trunk/Makefile 2008-05-04 09:30:54 UTC (rev 49) +++ pure/trunk/Makefile 2008-05-04 10:10:37 UTC (rev 50) @@ -94,7 +94,7 @@ pure: $(OBJECT) $(CXX) -o $@ $(LDFLAGS) -rdynamic $(OBJECT) $(ALL_LIBS) -pure.o: pure.cc +pure.o: pure.cc Makefile $(CXX) $(CXXFLAGS) -DVERSION='"$(version)"' -DPURELIB='"$(libdir)"' -c -o $@ $< lexer.cc: lexer.ll This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-05-04 22:17:03
|
Revision: 53 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=53&view=rev Author: agraef Date: 2008-05-04 15:17:09 -0700 (Sun, 04 May 2008) Log Message: ----------- Back out previous change (rev. 51), which causes more trouble than it's worth. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/Makefile Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-05-04 22:15:14 UTC (rev 52) +++ pure/trunk/ChangeLog 2008-05-04 22:17:09 UTC (rev 53) @@ -1,9 +1,5 @@ 2008-05-04 Albert Graef <Dr....@t-...> - * Makefile (pure.o): Add missing dependency of pure.o on Makefile, - so that the main module gets recompiled when bumping the version - number. - * 0.2 release. * lexer.ll, printer.cc: Add an explicit notation for big Modified: pure/trunk/Makefile =================================================================== --- pure/trunk/Makefile 2008-05-04 22:15:14 UTC (rev 52) +++ pure/trunk/Makefile 2008-05-04 22:17:09 UTC (rev 53) @@ -94,7 +94,7 @@ pure: $(OBJECT) $(CXX) -o $@ $(LDFLAGS) -rdynamic $(OBJECT) $(ALL_LIBS) -pure.o: pure.cc Makefile +pure.o: pure.cc $(CXX) $(CXXFLAGS) -DVERSION='"$(version)"' -DPURELIB='"$(libdir)"' -c -o $@ $< lexer.cc: lexer.ll This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-05-05 06:57:14
|
Revision: 54 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=54&view=rev Author: agraef Date: 2008-05-04 23:57:21 -0700 (Sun, 04 May 2008) Log Message: ----------- Fixed wrong mpz_cmp() tests in pattern matching code. Added regression test #8. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/matcher.cc Added Paths: ----------- pure/trunk/test/test8.log pure/trunk/test/test8.pure Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-05-04 22:17:09 UTC (rev 53) +++ pure/trunk/ChangeLog 2008-05-05 06:57:21 UTC (rev 54) @@ -1,3 +1,9 @@ +2008-05-05 Albert Graef <Dr....@t-...> + + * matcher.cc (merge_ctrans): Fixed broken mpz_cmp() test causing + transitions on different (instead of equal) bigint constants to be + merged. Reported by Libor Spacek. + 2008-05-04 Albert Graef <Dr....@t-...> * 0.2 release. Modified: pure/trunk/matcher.cc =================================================================== --- pure/trunk/matcher.cc 2008-05-04 22:17:09 UTC (rev 53) +++ pure/trunk/matcher.cc 2008-05-05 06:57:21 UTC (rev 54) @@ -95,7 +95,7 @@ case EXPR::INT: return (x.ival() == t->i)?t->st:0; case EXPR::BIGINT: - return (mpz_cmp(x.zval(), t->z))?t->st:0; + return (mpz_cmp(x.zval(), t->z) == 0)?t->st:0; case EXPR::DBL: return (x.dval() == t->d)?t->st:0; case EXPR::STR: @@ -377,7 +377,7 @@ transl::iterator t; // look for a matching transition for (t = tr.begin(); t != tr.end(); t++) { - if (t->tag == EXPR::BIGINT && mpz_cmp(t->z, x)) { + if (t->tag == EXPR::BIGINT && mpz_cmp(t->z, x) == 0) { merge_state(t->st, st); return; } else if (t->tag > 0 || t->tag < EXPR::BIGINT) Added: pure/trunk/test/test8.log =================================================================== --- pure/trunk/test/test8.log (rev 0) +++ pure/trunk/test/test8.log 2008-05-05 06:57:21 UTC (rev 54) @@ -0,0 +1,36 @@ +Binomial n/*0:01*/ k/*0:1*/ = Binomial n/*0:01*/ (n/*0:01*/-k/*0:1*/) if n/*0:01*/-k/*0:1*/<k/*0:1*/; +Binomial n/*0:01*/ 0G = 1G; +Binomial n/*0:01*/ 0 = 1; +Binomial n/*0:01*/ 1G = n/*0:01*/; +Binomial n/*0:01*/ 1 = n/*0:01*/; +Binomial n/*0:01*/ k/*0:1*/ = Binomial nm2/*0:*/ (k/*1:1*/-2)+2*Binomial nm2/*0:*/ (k/*1:1*/-1)+Binomial nm2/*0:*/ k/*1:1*/ when nm2/*0:*/ = n/*0:01*/-2 { + rule #0: nm2 = n-2 + state 0: #0 + <var> state 1 + state 1: #0 +} end; +{ + rule #0: Binomial n k = Binomial n (n-k) if n-k<k + rule #1: Binomial n 0G = 1G + rule #2: Binomial n 0 = 1 + rule #3: Binomial n 1G = n + rule #4: Binomial n 1 = n + rule #5: Binomial n k = Binomial nm2 (k-2)+2*Binomial nm2 (k-1)+Binomial nm2 k when nm2 = n-2 end + state 0: #0 #1 #2 #3 #4 #5 + <var> state 1 + state 1: #0 #1 #2 #3 #4 #5 + <var> state 2 + 0::int state 3 + 1::int state 4 + 0G::bigint state 5 + 1G::bigint state 6 + state 2: #0 #5 + state 3: #0 #2 #5 + state 4: #0 #4 #5 + state 5: #0 #1 #5 + state 6: #0 #3 #5 +} +Binomial 5 2; +10 +Binomial 5G 2G; +10G Added: pure/trunk/test/test8.pure =================================================================== --- pure/trunk/test/test8.pure (rev 0) +++ pure/trunk/test/test8.pure 2008-05-05 06:57:21 UTC (rev 54) @@ -0,0 +1,13 @@ +Binomial n k = Binomial n (n-k) if n-k < k; +Binomial n 0G = 1G; +Binomial n 0 = 1; +Binomial n 1G = n; +Binomial n 1 = n; +Binomial n k = + Binomial nm2 (k-2) + + 2 * Binomial nm2 (k-1) + + Binomial nm2 k + when nm2 = n-2 end; + +Binomial 5 2; +Binomial 5G 2G; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-05-05 07:28:39
|
Revision: 55 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=55&view=rev Author: agraef Date: 2008-05-05 00:28:25 -0700 (Mon, 05 May 2008) Log Message: ----------- Remove -s option from install command, which wreaks havoc on OSX (unresolved externals). Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/Makefile Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-05-05 06:57:21 UTC (rev 54) +++ pure/trunk/ChangeLog 2008-05-05 07:28:25 UTC (rev 55) @@ -1,5 +1,10 @@ 2008-05-05 Albert Graef <Dr....@t-...> + * Makefile: Remove -s flag so that the pure executable is + installed without stripping the symbols which are needed to + properly resolve runtime externals on OSX. Reported by Ryan + Schmidt and others. + * matcher.cc (merge_ctrans): Fixed broken mpz_cmp() test causing transitions on different (instead of equal) bigint constants to be merged. Reported by Libor Spacek. Modified: pure/trunk/Makefile =================================================================== --- pure/trunk/Makefile 2008-05-05 06:57:21 UTC (rev 54) +++ pure/trunk/Makefile 2008-05-05 07:28:25 UTC (rev 55) @@ -84,8 +84,8 @@ $(SOURCE) $(EXTRA_SOURCE) w3centities.c pure.1 pure.xml pure.vim \ $(examples) $(lib) $(tests) $(distlogs) -.PHONY: all html dvi ps pdf clean realclean depend install uninstall dist \ -distcheck cleanlogs logs check +.PHONY: all html dvi ps pdf clean realclean depend install uninstall strip \ +dist distcheck cleanlogs logs check # compilation @@ -140,11 +140,19 @@ depend: $(SOURCE) $(EXTRA_SOURCE) makedepend -Y $(SOURCE) $(EXTRA_SOURCE) 2> /dev/null +# Strip symbols from the executable. You might want to run this on Linux +# systems before installation to get a smaller executable. *Never* do this on +# OSX though, as the symbols are needed to properly resolve the runtime +# externals which are linked into the executable. + +strip: pure + strip pure + # installation install: pure $(lib) install -d $(DESTDIR)$(bindir) $(DESTDIR)$(libdir) $(DESTDIR)$(mandir) - install -s pure $(DESTDIR)$(bindir)/pure + install pure $(DESTDIR)$(bindir)/pure install -m 644 $(lib) $(DESTDIR)$(libdir) install -m 644 pure.1 $(DESTDIR)$(mandir)/pure.1 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-05-06 07:59:35
|
Revision: 61 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=61&view=rev Author: agraef Date: 2008-05-06 00:59:41 -0700 (Tue, 06 May 2008) Log Message: ----------- Handle some obscure cases of name collisions between Pure and C functions. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/interpreter.cc Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-05-05 11:25:19 UTC (rev 60) +++ pure/trunk/ChangeLog 2008-05-06 07:59:41 UTC (rev 61) @@ -1,3 +1,8 @@ +2008-05-06 Albert Graef <Dr....@t-...> + + * interpreter.cc (declare_extern, fun_prolog): Handle some obscure + cases of name collisions between Pure and C functions. + 2008-05-05 Albert Graef <Dr....@t-...> * INSTALL: Add system-specific notes. Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-05-05 11:25:19 UTC (rev 60) +++ pure/trunk/interpreter.cc 2008-05-06 07:59:41 UTC (rev 61) @@ -2181,6 +2181,12 @@ const FunctionType *gt = g?g->getFunctionType():0; // Check whether we already have an external declaration for this symbol. map<int32_t,ExternInfo>::const_iterator it = externals.find(sym.f); + // Handle the case that the C function was imported through a dll *after* + // the definition of a Pure function of the same name. In this case the C + // function won't be accessible in the Pure program at all. + if (it == externals.end() && g && !g->isDeclaration()) + throw err("symbol '"+name+ + "' is already defined as a Pure function or variable"); if (it == externals.end() && g) { // Cross-check with a builtin declaration. assert(g->isDeclaration() && gt); @@ -2248,7 +2254,7 @@ vector<const Type*> argt2(n, ExprPtrTy); FunctionType *ft2 = FunctionType::get(ExprPtrTy, argt2, false); Function *f = new Function(ft2, Function::InternalLinkage, - "$$pure."+asname, module); + "$$wrap."+asname, module); vector<Value*> args(n), unboxed(n); Function::arg_iterator a = f->arg_begin(); for (size_t i = 0; a != f->arg_end(); ++a, ++i) { @@ -3820,23 +3826,32 @@ /* Mangle local function names so that they're easier to identify; as a side-effect, this should also ensure that we always get the proper names for external functions. */ + bool have_c_func = false; if (f.local) { EnvStack::iterator e = envstk.begin(); if (++e != envstk.end()) name = (*e)->name + "." + name; - } + } else + /* Check that we do not accidentally override a C function of the same + name. */ + have_c_func = sys::DynamicLibrary::SearchForAddressOfSymbol(name); f.name = name; /* Linkage type and calling convention. For each Pure function (no matter whether global or local) we create a C-callable function in LLVM IR. (This is necessary also for local functions, since these might need to be called from the runtime.) In the case of a global function, this - function is also externally visible. However, in order to enable tail - call elimination (on platforms where LLVM supports this), suitable - functions are internally implemented using the fast calling convention - (if enabled, which it is by default). In this case, the C-callable - function is just a stub calling the internal function. */ + function is also externally visible, *unless* there's already a + callable C function of that name (in which case we also mangle the name + to prevent name collisions). However, in order to enable tail call + elimination (on platforms where LLVM supports this), suitable functions + are internally implemented using the fast calling convention (if + enabled, which it is by default). In this case, the C-callable function + is just a stub calling the internal function. */ Function::LinkageTypes scope = Function::ExternalLinkage; CallingConv::ID cc = CallingConv::C; if (f.local || + // global Pure functions use internal linkage if they would shadow a C + // function: + have_c_func || // anonymous functions and operators use internal linkage, too: f.tag == 0 || symtab.sym(f.tag).prec < 10) scope = Function::InternalLinkage; @@ -3850,16 +3865,20 @@ situations and thus this optimization isn't implemented yet. */ if (!name.empty() && f.m == 0) cc = CallingConv::Fast; #endif + /* Mangle the name of the C-callable wrapper if it would shadow another C + function. */ + string pure_name = name; + if (have_c_func) pure_name = "$$pure."+name; if (cc == CallingConv::Fast) { // create the function f.f = new Function(ft, Function::InternalLinkage, "$$fastcc."+name, module); assert(f.f); f.f->setCallingConv(cc); // create the C-callable stub - f.h = new Function(ft, scope, name, module); assert(f.h); + f.h = new Function(ft, scope, pure_name, module); assert(f.h); } else { // no need for a separate stub - f.f = new Function(ft, scope, name, module); assert(f.f); + f.f = new Function(ft, scope, pure_name, module); assert(f.f); f.h = f.f; } /* Give names to the arguments, and provide direct access to these by This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-05-06 11:29:15
|
Revision: 62 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=62&view=rev Author: agraef Date: 2008-05-06 04:29:22 -0700 (Tue, 06 May 2008) Log Message: ----------- Added funp, lambdap and varp predicates. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/lib/primitives.pure pure/trunk/runtime.cc pure/trunk/runtime.h Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-05-06 07:59:41 UTC (rev 61) +++ pure/trunk/ChangeLog 2008-05-06 11:29:22 UTC (rev 62) @@ -1,5 +1,9 @@ 2008-05-06 Albert Graef <Dr....@t-...> + * runtime.cc, lib/primitives.pure: Added predicates funp, lambdap, + varp checking for named and anonymous closures and unbound global + variables, respectively. Requested by Libor Spacek. + * interpreter.cc (declare_extern, fun_prolog): Handle some obscure cases of name collisions between Pure and C functions. Modified: pure/trunk/lib/primitives.pure =================================================================== --- pure/trunk/lib/primitives.pure 2008-05-06 07:59:41 UTC (rev 61) +++ pure/trunk/lib/primitives.pure 2008-05-06 11:29:22 UTC (rev 62) @@ -38,10 +38,11 @@ stringp x = case x of _::string = 1; _ = 0 end; pointerp x = case x of _::pointer = 1; _ = 0 end; -/* Predicates to check for function applications and proper lists and - tuples. */ +/* Predicates to check for function objects, global (unbound) variables, + function applications and proper lists and tuples. */ -extern bool applp(expr*); +extern bool funp(expr*), bool lambdap(expr*), bool varp(expr*), + bool applp(expr*); listp [] = 1; listp (x:xs) = listp xs; Modified: pure/trunk/runtime.cc =================================================================== --- pure/trunk/runtime.cc 2008-05-06 07:59:41 UTC (rev 61) +++ pure/trunk/runtime.cc 2008-05-06 11:29:22 UTC (rev 62) @@ -1095,6 +1095,24 @@ } extern "C" +bool funp(const pure_expr *x) +{ + return (x->tag > 0 && x->data.clos); +} + +extern "C" +bool lambdap(const pure_expr *x) +{ + return (x->tag == 0 && x->data.clos); +} + +extern "C" +bool varp(const pure_expr *x) +{ + return (x->tag > 0 && !x->data.clos); +} + +extern "C" bool applp(const pure_expr *x) { return (x->tag == EXPR::APP); Modified: pure/trunk/runtime.h =================================================================== --- pure/trunk/runtime.h 2008-05-06 07:59:41 UTC (rev 61) +++ pure/trunk/runtime.h 2008-05-06 11:29:22 UTC (rev 62) @@ -256,6 +256,13 @@ bool same(const pure_expr *x, const pure_expr *y); +/* Check whether an object is a named function (closure), an anonymous + function (lambda), or a global variable, respectively. */ + +bool funp(const pure_expr *x); +bool lambdap(const pure_expr *x); +bool varp(const pure_expr *x); + /* Check whether an object is a function application, and return the function and the argument of an application. Note that these operations can't be defined in Pure because of the "head is function" rule which means that in This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-05-06 17:01:12
|
Revision: 63 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=63&view=rev Author: agraef Date: 2008-05-06 10:01:15 -0700 (Tue, 06 May 2008) Log Message: ----------- Make pow work also with double arguments, add sqrt function. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/lib/primitives.pure Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-05-06 11:29:22 UTC (rev 62) +++ pure/trunk/ChangeLog 2008-05-06 17:01:15 UTC (rev 63) @@ -1,5 +1,9 @@ 2008-05-06 Albert Graef <Dr....@t-...> + * lib/primitives.pure: Made the pow function work with all + combinations of integer and double arguments. Added the sqrt + function. + * runtime.cc, lib/primitives.pure: Added predicates funp, lambdap, varp checking for named and anonymous closures and unbound global variables, respectively. Requested by Libor Spacek. Modified: pure/trunk/lib/primitives.pure =================================================================== --- pure/trunk/lib/primitives.pure 2008-05-06 11:29:22 UTC (rev 62) +++ pure/trunk/lib/primitives.pure 2008-05-06 17:01:15 UTC (rev 63) @@ -254,12 +254,35 @@ x::double==y::bigint = x==double y; x::double!=y::bigint = x!=double y; -extern expr* bigint_pow(void*, int); +/* The sqrt function. Integer arguments get promoted to double and the result + is always a double. The argument must be nonnegative. */ -pow x::bigint y::int = bigint_pow x y if y>=0; +extern double sqrt(double) = c_sqrt; + +sqrt x::int = c_sqrt (double x) if x>=0; +sqrt x::bigint = c_sqrt (double x) if x>=0; +sqrt x::double = c_sqrt x if x>=0; + +/* The pow function. Returns a bigint for integer arguments, double if one of + the arguments is double (in the latter case, x may be negative only if y is + integer). */ + +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; +// mixed int/bigint +pow x::int y::bigint = bigint_pow (bigint x) (int y) if y>=0; +pow x::bigint y::int = bigint_pow x y if y>=0; + +// mixed double/int/bigint +pow x::double y::int = c_pow x (double y); +pow x::double y::bigint = c_pow x (double y); +pow x::int 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 || int y==y; + /* Pointer arithmetic. We do this using bigints, so that the code is portable to 64 bit systems. */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-05-06 17:12:28
|
Revision: 64 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=64&view=rev Author: agraef Date: 2008-05-06 10:12:35 -0700 (Tue, 06 May 2008) Log Message: ----------- Add a definition for the ^ operator. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/lib/prelude.pure pure/trunk/lib/primitives.pure Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-05-06 17:01:15 UTC (rev 63) +++ pure/trunk/ChangeLog 2008-05-06 17:12:35 UTC (rev 64) @@ -1,8 +1,8 @@ 2008-05-06 Albert Graef <Dr....@t-...> * lib/primitives.pure: Made the pow function work with all - combinations of integer and double arguments. Added the sqrt - function. + combinations of integer and double arguments. Also added the sqrt + function and the ^ operator. * runtime.cc, lib/primitives.pure: Added predicates funp, lambdap, varp checking for named and anonymous closures and unbound global Modified: pure/trunk/lib/prelude.pure =================================================================== --- pure/trunk/lib/prelude.pure 2008-05-06 17:01:15 UTC (rev 63) +++ pure/trunk/lib/prelude.pure 2008-05-06 17:12:35 UTC (rev 64) @@ -47,7 +47,7 @@ infixl 6 + - | ; // addition, bitwise or infixl 7 * / div mod & ; // multiplication, bitwise and prefix 7 ~ ; // bitwise not -infixr 8 ^ ; // exponentiation (undefined for now) +infixr 8 ^ ; // exponentiation prefix 8 # ; // size operator infixl 9 ! ; // indexing infixr 9 . ; // function composition Modified: pure/trunk/lib/primitives.pure =================================================================== --- pure/trunk/lib/primitives.pure 2008-05-06 17:01:15 UTC (rev 63) +++ pure/trunk/lib/primitives.pure 2008-05-06 17:12:35 UTC (rev 64) @@ -283,6 +283,19 @@ pow x::int 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 || int y==y; +/* 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::int^y::int = c_pow (double x) (double y); +x::bigint^y::bigint = c_pow (double x) (double y); +x::int^y::bigint = c_pow (double x) (double y); +x::bigint^y::int = c_pow (double x) (double y); +x::double^y::int = c_pow x (double y); +x::double^y::bigint = c_pow x (double y); +x::int^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 || int y==y; + /* Pointer arithmetic. We do this using bigints, so that the code is portable to 64 bit systems. */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-05-08 22:00:39
|
Revision: 67 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=67&view=rev Author: agraef Date: 2008-05-08 15:00:36 -0700 (Thu, 08 May 2008) Log Message: ----------- Changed 'G' bigint suffix to 'L'. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/examples/hello.pure pure/trunk/lexer.ll pure/trunk/printer.cc pure/trunk/pure.1 pure/trunk/test/test1.log pure/trunk/test/test8.log pure/trunk/test/test8.pure Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-05-06 17:49:50 UTC (rev 66) +++ pure/trunk/ChangeLog 2008-05-08 22:00:36 UTC (rev 67) @@ -1,3 +1,10 @@ +2008-05-09 Albert Graef <Dr....@t-...> + + * lexer.ll, printer.cc, etc.: Change the "G" suffix to denote + bigints to "L" ("G" can too easily be mistaken for a digit; also, + Python uses the same "L" notation for bigints). Reported by Eddie + Rucker. + 2008-05-06 Albert Graef <Dr....@t-...> * lib/primitives.pure: Made the pow function work with all Modified: pure/trunk/examples/hello.pure =================================================================== --- pure/trunk/examples/hello.pure 2008-05-06 17:49:50 UTC (rev 66) +++ pure/trunk/examples/hello.pure 2008-05-08 22:00:36 UTC (rev 67) @@ -115,7 +115,7 @@ // constant stack space. It also uses bigints so that the arithmetically // correct values are computed for large n. -fib3 n = a when a, b = fibs (0G, 1G) n end +fib3 n = a when a, b = fibs (0L, 1L) n end with fibs (a, b) n = a, b if n<=0; = fibs (b, a+b) (n-1) otherwise; end; Modified: pure/trunk/lexer.ll =================================================================== --- pure/trunk/lexer.ll 2008-05-06 17:49:50 UTC (rev 66) +++ pure/trunk/lexer.ll 2008-05-08 22:00:36 UTC (rev 67) @@ -604,12 +604,12 @@ return token::BIGINT; } } -{int}G { +{int}L { mpz_t *z = (mpz_t*)malloc(sizeof(mpz_t)); mpz_init(*z); yytext[yyleng-1] = 0; mpz_set_str(*z, yytext, 0); - yytext[yyleng-1] = 'G'; + yytext[yyleng-1] = 'L'; yylval->zval = z; return token::BIGINT; } Modified: pure/trunk/printer.cc =================================================================== --- pure/trunk/printer.cc 2008-05-06 17:49:50 UTC (rev 66) +++ pure/trunk/printer.cc 2008-05-08 22:00:36 UTC (rev 67) @@ -202,7 +202,7 @@ return os << x.ival(); case EXPR::BIGINT: { char *s = mpz_get_str(NULL, 10, x.zval()); - os << s << "G"; free(s); + os << s << "L"; free(s); return os; } case EXPR::DBL: { @@ -439,7 +439,7 @@ return os << " state " << tr.st->s << endl; case EXPR::BIGINT: { char *s = mpz_get_str(NULL, 10, tr.z); - os << "\t" << s << "G"; + os << "\t" << s << "L"; print_ttag(os, tr.ttag); os << " state " << tr.st->s << endl; free(s); @@ -621,7 +621,7 @@ return os << x->data.i; case EXPR::BIGINT: { char *s = mpz_get_str(NULL, 10, x->data.z); - os << s << "G"; free(s); + os << s << "L"; free(s); return os; } case EXPR::DBL: { Modified: pure/trunk/pure.1 =================================================================== --- pure/trunk/pure.1 2008-05-06 17:49:50 UTC (rev 66) +++ pure/trunk/pure.1 2008-05-08 22:00:36 UTC (rev 67) @@ -193,13 +193,12 @@ syntax differs in some minor ways, as discussed in the following. First, there is a special notation for denoting bigints. Note that an integer constant that is too large to fit into a machine integer will be interpreted as a bigint -automatically. Moreover, an integer literal immediately followed by the -uppercase letter ``G'' (mnemonic: ``biG'' or ``GMP'' integer) will always be -interpreted as a bigint constant, even if it fits into a machine integer. This -``big G'' notation is also used when printing bigint constants. Second, -character escapes in Pure strings have a more flexible syntax borrowed from -the author's Q language, which provides notations to specify any Unicode -character. In particular, the notation +automatically. Moreover, as in Python an integer literal immediately followed +by the uppercase letter ``L'' will always be interpreted as a bigint constant, +even if it fits into a machine integer. This notation is also used when +printing bigint constants. Second, character escapes in Pure strings have a +more flexible syntax borrowed from the author's Q language, which provides +notations to specify any Unicode character. In particular, the notation .BR \e\fIn\fP , where \fIn\fP is an integer literal written in decimal (no prefix), hexadecimal (`0x' prefix) or octal (`0' prefix) notation, denotes the Unicode @@ -1052,7 +1051,7 @@ have to provide equations for both. This also applies to equations matching against constant values of these types; in particular, a small integer constant like `0' only matches machine integers, not bigints; for the latter -you'll have to use the ``big G'' notation `0G'. +you'll have to use the ``big L'' notation `0L'. .PP .B External C functions. The interpreter always takes your Modified: pure/trunk/test/test1.log =================================================================== --- pure/trunk/test/test1.log 2008-05-06 17:49:50 UTC (rev 66) +++ pure/trunk/test/test1.log 2008-05-08 22:00:36 UTC (rev 67) @@ -92,7 +92,7 @@ state 2: #1 #2 } fact 50; -30414093201713378043612608166064768844377641568960512000000000000G +30414093201713378043612608166064768844377641568960512000000000000L fib1 0 = 0; fib1 1 = 1; fib1 n/*0:1*/ = fib1 (n/*0:1*/-2)+fib1 (n/*0:1*/-1) if n/*0:1*/>1; Modified: pure/trunk/test/test8.log =================================================================== --- pure/trunk/test/test8.log 2008-05-06 17:49:50 UTC (rev 66) +++ pure/trunk/test/test8.log 2008-05-08 22:00:36 UTC (rev 67) @@ -1,7 +1,7 @@ Binomial n/*0:01*/ k/*0:1*/ = Binomial n/*0:01*/ (n/*0:01*/-k/*0:1*/) if n/*0:01*/-k/*0:1*/<k/*0:1*/; -Binomial n/*0:01*/ 0G = 1G; +Binomial n/*0:01*/ 0L = 1L; Binomial n/*0:01*/ 0 = 1; -Binomial n/*0:01*/ 1G = n/*0:01*/; +Binomial n/*0:01*/ 1L = n/*0:01*/; Binomial n/*0:01*/ 1 = n/*0:01*/; Binomial n/*0:01*/ k/*0:1*/ = Binomial nm2/*0:*/ (k/*1:1*/-2)+2*Binomial nm2/*0:*/ (k/*1:1*/-1)+Binomial nm2/*0:*/ k/*1:1*/ when nm2/*0:*/ = n/*0:01*/-2 { rule #0: nm2 = n-2 @@ -11,9 +11,9 @@ } end; { rule #0: Binomial n k = Binomial n (n-k) if n-k<k - rule #1: Binomial n 0G = 1G + rule #1: Binomial n 0L = 1L rule #2: Binomial n 0 = 1 - rule #3: Binomial n 1G = n + rule #3: Binomial n 1L = n rule #4: Binomial n 1 = n rule #5: Binomial n k = Binomial nm2 (k-2)+2*Binomial nm2 (k-1)+Binomial nm2 k when nm2 = n-2 end state 0: #0 #1 #2 #3 #4 #5 @@ -22,8 +22,8 @@ <var> state 2 0::int state 3 1::int state 4 - 0G::bigint state 5 - 1G::bigint state 6 + 0L::bigint state 5 + 1L::bigint state 6 state 2: #0 #5 state 3: #0 #2 #5 state 4: #0 #4 #5 @@ -32,5 +32,5 @@ } Binomial 5 2; 10 -Binomial 5G 2G; -10G +Binomial 5L 2L; +10L Modified: pure/trunk/test/test8.pure =================================================================== --- pure/trunk/test/test8.pure 2008-05-06 17:49:50 UTC (rev 66) +++ pure/trunk/test/test8.pure 2008-05-08 22:00:36 UTC (rev 67) @@ -1,7 +1,7 @@ Binomial n k = Binomial n (n-k) if n-k < k; -Binomial n 0G = 1G; +Binomial n 0L = 1L; Binomial n 0 = 1; -Binomial n 1G = n; +Binomial n 1L = n; Binomial n 1 = n; Binomial n k = Binomial nm2 (k-2) + @@ -10,4 +10,4 @@ when nm2 = n-2 end; Binomial 5 2; -Binomial 5G 2G; +Binomial 5L 2L; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-05-10 19:42:44
|
Revision: 72 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=72&view=rev Author: agraef Date: 2008-05-10 12:42:51 -0700 (Sat, 10 May 2008) Log Message: ----------- Correctly treat -0x80000000 as a machine int. Modified Paths: -------------- pure/trunk/ChangeLog pure/trunk/interpreter.cc Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-05-10 19:37:36 UTC (rev 71) +++ pure/trunk/ChangeLog 2008-05-10 19:42:51 UTC (rev 72) @@ -1,3 +1,9 @@ +2008-05-10 Albert Graef <Dr....@t-...> + + * interpreter.cc (uminop): Handle the value -0x80000000 at the + border of the int range, so that it is correctly treated as a + machine int. + 2008-05-09 Albert Graef <Dr....@t-...> * lexer.ll, printer.cc, etc.: Change the "G" suffix to denote Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-05-10 19:37:36 UTC (rev 71) +++ pure/trunk/interpreter.cc 2008-05-10 19:42:51 UTC (rev 72) @@ -1222,7 +1222,11 @@ } expr *y; // handle special case of a numeric argument - if (x->tag() == EXPR::INT) + 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. + y = new expr(EXPR::INT, (int32_t)-0x80000000); + else if (x->tag() == EXPR::INT) y = new expr(EXPR::INT, -x->ival()); else if (x->tag() == EXPR::DBL) y = new expr(EXPR::DBL, -x->dval()); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |