Thread: [pure-lang-svn] SF.net SVN: pure-lang:[441] pure/trunk
Status: Beta
Brought to you by:
agraef
|
From: <ag...@us...> - 2008-07-30 20:39:56
|
Revision: 441
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=441&view=rev
Author: agraef
Date: 2008-07-30 20:40:04 +0000 (Wed, 30 Jul 2008)
Log Message:
-----------
Update entity definitions to latest from W3C.
Modified Paths:
--------------
pure/trunk/ChangeLog
pure/trunk/w3centities.c
Modified: pure/trunk/ChangeLog
===================================================================
--- pure/trunk/ChangeLog 2008-07-30 20:16:55 UTC (rev 440)
+++ pure/trunk/ChangeLog 2008-07-30 20:40:04 UTC (rev 441)
@@ -1,3 +1,7 @@
+2008-07-30 Albert Graef <Dr....@t-...>
+
+ * w3centities.c: Updated to latest from W3C.
+
2008-07-13 Albert Graef <Dr....@t-...>
* interpreter.cc (codegen): Streamline code for list and tuple
Modified: pure/trunk/w3centities.c
===================================================================
--- pure/trunk/w3centities.c 2008-07-30 20:16:55 UTC (rev 440)
+++ pure/trunk/w3centities.c 2008-07-30 20:40:04 UTC (rev 441)
@@ -1,4 +1,4 @@
-/* generated from w3centities.ent Fri Jan 18 03:24:08 2008 */
+/* generated from w3centities.ent Wed Jul 30 22:28:13 2008 */
typedef struct ENTITY { const char *name; long c; } Entity;
@@ -239,7 +239,7 @@
{ "Lcaron", 0x0013D },
{ "Lcedil", 0x0013B },
{ "Lcy", 0x0041B },
- { "LeftAngleBracket", 0x02329 },
+ { "LeftAngleBracket", 0x027E8 },
{ "LeftArrowBar", 0x021E4 },
{ "LeftArrowRightArrow", 0x021C6 },
{ "LeftCeiling", 0x02308 },
@@ -370,9 +370,9 @@
{ "Otimes", 0x02A37 },
{ "Ouml", 0x000D6 },
{ "OverBar", 0x000AF },
- { "OverBrace", 0x0FE37 },
+ { "OverBrace", 0x023DE },
{ "OverBracket", 0x023B4 },
- { "OverParenthesis", 0x0FE35 },
+ { "OverParenthesis", 0x023DC },
{ "PHgr", 0x003A6 },
{ "PSgr", 0x003A8 },
{ "PartialD", 0x02202 },
@@ -413,7 +413,7 @@
{ "Rfr", 0x0211C },
{ "Rgr", 0x003A1 },
{ "Rho", 0x003A1 },
- { "RightAngleBracket", 0x0232A },
+ { "RightAngleBracket", 0x027E9 },
{ "RightArrowBar", 0x021E5 },
{ "RightArrowLeftArrow", 0x021C4 },
{ "RightCeiling", 0x02309 },
@@ -513,9 +513,9 @@
{ "Ugr", 0x003A5 },
{ "Ugrave", 0x000D9 },
{ "Umacr", 0x0016A },
- { "UnderBrace", 0x0FE38 },
+ { "UnderBrace", 0x023DF },
{ "UnderBracket", 0x023B5 },
- { "UnderParenthesis", 0x0FE36 },
+ { "UnderParenthesis", 0x023DD },
{ "Union", 0x022C3 },
{ "UnionPlus", 0x0228E },
{ "Uogon", 0x00172 },
@@ -1228,9 +1228,9 @@
{ "laemptyv", 0x029B4 },
{ "lagran", 0x02112 },
{ "lambda", 0x003BB },
- { "lang", 0x02329 },
+ { "lang", 0x027E8 },
{ "langd", 0x02991 },
- { "langle", 0x02329 },
+ { "langle", 0x027E8 },
{ "lap", 0x02A85 },
{ "laquo", 0x000AB },
{ "larr", 0x02190 },
@@ -1246,7 +1246,7 @@
{ "latail", 0x02919 },
{ "late", 0x02AAD },
{ "lbarr", 0x0290C },
- { "lbbrk", 0x02997 },
+ { "lbbrk", 0x02772 },
{ "lbrace", 0x0007B },
{ "lbrack", 0x0005B },
{ "lbrke", 0x0298B },
@@ -1596,7 +1596,7 @@
{ "pfr", 0x1D52D },
{ "pgr", 0x003C0 },
{ "phgr", 0x003C6 },
- { "phi", 0x003D5 },
+ { "phi", 0x003C6 },
{ "phiv", 0x003C6 },
{ "phmmat", 0x02133 },
{ "phone", 0x0260E },
@@ -1669,10 +1669,10 @@
{ "racute", 0x00155 },
{ "radic", 0x0221A },
{ "raemptyv", 0x029B3 },
- { "rang", 0x0232A },
+ { "rang", 0x027E9 },
{ "rangd", 0x02992 },
{ "range", 0x029A5 },
- { "rangle", 0x0232A },
+ { "rangle", 0x027E9 },
{ "raquo", 0x000BB },
{ "rarr", 0x02192 },
{ "rarrap", 0x02975 },
@@ -1690,7 +1690,7 @@
{ "ratio", 0x02236 },
{ "rationals", 0x0211A },
{ "rbarr", 0x0290D },
- { "rbbrk", 0x02998 },
+ { "rbbrk", 0x02773 },
{ "rbrace", 0x0007D },
{ "rbrack", 0x0005D },
{ "rbrke", 0x0298C },
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ag...@us...> - 2008-08-02 07:07:35
|
Revision: 443
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=443&view=rev
Author: agraef
Date: 2008-08-02 07:07:44 +0000 (Sat, 02 Aug 2008)
Log Message:
-----------
Move map of local function environments to separate class.
Modified Paths:
--------------
pure/trunk/interpreter.cc
pure/trunk/interpreter.hh
pure/trunk/lexer.ll
Modified: pure/trunk/interpreter.cc
===================================================================
--- pure/trunk/interpreter.cc 2008-07-31 12:16:17 UTC (rev 442)
+++ pure/trunk/interpreter.cc 2008-08-02 07:07:44 UTC (rev 443)
@@ -1942,8 +1942,7 @@
args = e.args; envs = e.envs;
b = e.b; local = e.local; parent = e.parent;
}
- fmap = e.fmap; fmap_idx = e.fmap_idx;
- xmap = e.xmap; xtab = e.xtab; prop = e.prop; m = e.m;
+ fmap = e.fmap; xmap = e.xmap; xtab = e.xtab; prop = e.prop; m = e.m;
return *this;
}
@@ -1961,7 +1960,7 @@
interp.JIT->freeMachineCodeForFunction(f);
f->dropAllReferences(); if (h != f) h->dropAllReferences();
fp = 0;
- fmap.clear(); fmap_idx = 0;
+ fmap.clear();
to_be_deleted.push_back(f); if (h != f) to_be_deleted.push_back(h);
} else {
#if DEBUG>2
@@ -1978,8 +1977,7 @@
}
fp = 0;
// delete all nested environments and reinitialize other body-related data
- fmap.clear(); fmap_idx = 0;
- xmap.clear(); xtab.clear(); prop.clear(); m = 0;
+ fmap.clear(); xmap.clear(); xtab.clear(); prop.clear(); m = 0;
// now that all references have been removed, delete the function pointers
for (list<Function*>::iterator fi = to_be_deleted.begin();
fi != to_be_deleted.end(); fi++) {
@@ -2130,7 +2128,7 @@
fenv = *ei++;
}
assert(fenv->act_fmap().find(x.vtag()) != fenv->act_fmap().end());
- fenv = &fenv->act_fmap()[x.vtag()];
+ fenv = &fenv->fmap.act()[x.vtag()];
if (!fenv->local) break;
// fenv now points to the environment of the (local) function
assert(fenv != this && fenv->tag == x.vtag());
@@ -2190,7 +2188,7 @@
if (n == 2 && f.tag() == interp.symtab.catch_sym().f) {
expr h = x.xval1().xval2(), y = x.xval2();
push("catch");
- Env& e = act_fmap()[-x.hash()] = Env(0, 0, y, true, true);
+ Env& e = fmap.act()[-x.hash()] = Env(0, 0, y, true, true);
e.build_map(y); e.promote_map();
pop();
build_map(h);
@@ -2207,14 +2205,14 @@
break;
case EXPR::LAMBDA: {
push("lambda");
- Env& e = act_fmap()[-x.hash()] = Env(0, 1, x.xval2(), true, true);
+ Env& e = fmap.act()[-x.hash()] = Env(0, 1, x.xval2(), true, true);
e.build_map(x.xval2()); e.promote_map();
pop();
break;
}
case EXPR::CASE: {
push("case");
- Env& e = act_fmap()[-x.hash()] = Env(0, 1, x.xval(), true, true);
+ Env& e = fmap.act()[-x.hash()] = Env(0, 1, x.xval(), true, true);
e.build_map(*x.rules()); e.promote_map();
pop();
build_map(x.xval());
@@ -2231,13 +2229,13 @@
for (env::const_iterator p = fe->begin(); p != fe->end(); p++) {
int32_t ftag = p->first;
const env_info& info = p->second;
- act_fmap()[ftag] = Env(ftag, info, false, true);
+ fmap.act()[ftag] = Env(ftag, info, false, true);
}
// Now recursively build the maps for the child environments.
for (env::const_iterator p = fe->begin(); p != fe->end(); p++) {
int32_t ftag = p->first;
const env_info& info = p->second;
- Env& e = act_fmap()[ftag];
+ Env& e = fmap.act()[ftag];
e.build_map(info); e.promote_map();
}
pop();
@@ -2261,7 +2259,7 @@
rulel::const_iterator s = r;
expr y = (++s == end)?x:s->rhs;
push("when");
- Env& e = act_fmap()[-y.hash()] = Env(0, 1, y, true, true);
+ Env& e = fmap.act()[-y.hash()] = Env(0, 1, y, true, true);
e.build_map(x, s, end); e.promote_map();
pop();
build_map(r->rhs);
@@ -2288,9 +2286,9 @@
while (r != info.rules->end()) {
build_map(r->rhs);
if (!r->qual.is_null()) build_map(r->qual);
- r++; fmap_idx++;
+ r++; fmap.next();
}
- fmap_idx = 0;
+ fmap.first();
#if DEBUG>1
if (!local) print_map(std::cerr, this);
#endif
@@ -3120,8 +3118,8 @@
Env& act = act_env();
rulel::const_iterator s = r;
expr y = (++s == end)?x:s->rhs;
- assert(act.act_fmap().find(-y.hash()) != act.act_fmap().end());
- Env& e = act.act_fmap()[-y.hash()];
+ assert(act.fmap.act().find(-y.hash()) != act.fmap.act().end());
+ Env& e = act.fmap.act()[-y.hash()];
push("when", &e);
fun_prolog("anonymous");
BasicBlock *bodybb = BasicBlock::Create("body");
@@ -3548,7 +3546,7 @@
int offs = idx-1;
if (idx == 0) {
// function in current environment ('with'-bound)
- f = &act_env().act_fmap()[tag];
+ f = &act_env().fmap.act()[tag];
} else {
// function in an outer environment, the de Bruijn index idx tells us
// where on the current environment stack it's at
@@ -3556,7 +3554,7 @@
size_t i = idx;
for (; i > 0; e++, i--) assert(e != envstk.end());
// look up the function in the environment
- f = &(*e)->act_fmap()[tag];
+ f = &(*e)->fmap.act()[tag];
}
if (f->n == n) {
// bingo! saturated call
@@ -3694,8 +3692,8 @@
// through pure_catch()
expr h = x.xval1().xval2(), y = x.xval2();
Env& act = act_env();
- assert(act.act_fmap().find(-x.hash()) != act.act_fmap().end());
- Env& e = act.act_fmap()[-x.hash()];
+ assert(act.fmap.act().find(-x.hash()) != act.fmap.act().end());
+ Env& e = act.fmap.act()[-x.hash()];
push("catch", &e);
fun_prolog("anonymous");
e.CreateRet(codegen(y));
@@ -3735,8 +3733,8 @@
// anonymous closure:
case EXPR::LAMBDA: {
Env& act = act_env();
- assert(act.act_fmap().find(-x.hash()) != act.act_fmap().end());
- Env& e = act.act_fmap()[-x.hash()];
+ assert(act.fmap.act().find(-x.hash()) != act.fmap.act().end());
+ Env& e = act.fmap.act()[-x.hash()];
push("lambda", &e);
fun("anonymous", x.pm(), true);
pop(&e);
@@ -3747,8 +3745,8 @@
// case expression: treated like an anonymous closure (see the lambda case
// above) which gets applied to the subject term to be matched
Env& act = act_env();
- assert(act.act_fmap().find(-x.hash()) != act.act_fmap().end());
- Env& e = act.act_fmap()[-x.hash()];
+ assert(act.fmap.act().find(-x.hash()) != act.fmap.act().end());
+ Env& e = act.fmap.act()[-x.hash()];
push("case", &e);
fun("anonymous", x.pm(), true);
pop(&e);
@@ -3774,16 +3772,16 @@
// mutually recursive definitions
for (p = fe->begin(); p != fe->end(); p++) {
int32_t ftag = p->first;
- assert(act.act_fmap().find(ftag) != act.act_fmap().end());
- Env& e = act.act_fmap()[ftag];
+ assert(act.fmap.act().find(ftag) != act.fmap.act().end());
+ Env& e = act.fmap.act()[ftag];
push("with", &e);
- act.act_fmap()[ftag].f = fun_prolog(symtab.sym(ftag).s);
+ act.fmap.act()[ftag].f = fun_prolog(symtab.sym(ftag).s);
pop(&e);
}
for (p = fe->begin(); p != fe->end(); p++) {
int32_t ftag = p->first;
const env_info& info = p->second;
- Env& e = act.act_fmap()[ftag];
+ Env& e = act.fmap.act()[ftag];
push("with", &e);
fun_body(info.m);
pop(&e);
@@ -4078,7 +4076,7 @@
assert(!envstk.empty());
if (idx == 0) {
// function in current environment ('with'-bound)
- Env& f = act_env().act_fmap()[tag];
+ Env& f = act_env().fmap.act()[tag];
return fbox(f, thunked);
}
// If we come here, the function is defined in an outer environment. Locate
@@ -4088,7 +4086,7 @@
size_t i = idx;
for (; i > 0; e++, i--) assert(e != envstk.end());
// look up the function in the environment
- Env& f = (*e)->act_fmap()[tag];
+ Env& f = (*e)->fmap.act()[tag];
assert(f.f);
// Now create the closure. This is essentially just like fbox(), but we are
// called inside a nested environment here, and hence the de Bruijn indices
@@ -5062,7 +5060,7 @@
while (r != rl.end()) {
const rule& rr = rules[*r];
reduced.insert(*r);
- if (f.fmap.size() > 1) f.fmap_idx = *r;
+ if (f.fmap.size() > 1) f.fmap.set(*r);
f.f->getBasicBlockList().push_back(rulebb);
f.builder.SetInsertPoint(rulebb);
#if DEBUG>1
@@ -5120,5 +5118,5 @@
toplevel_codegen(rr.rhs);
rulebb = nextbb;
}
- if (f.fmap.size() > 1) f.fmap_idx = 0;
+ if (f.fmap.size() > 1) f.fmap.first();
}
Modified: pure/trunk/interpreter.hh
===================================================================
--- pure/trunk/interpreter.hh 2008-07-31 12:16:17 UTC (rev 442)
+++ pure/trunk/interpreter.hh 2008-08-02 07:07:44 UTC (rev 443)
@@ -88,6 +88,33 @@
typedef list<Env*> EnvStack;
typedef pair<int32_t,uint8_t> xmap_key;
+class FMap {
+ // manage local function environments
+ vector< map<int32_t,Env> > fmap;
+ // current map index
+ size_t idx;
+public:
+ // constructor (create one empty map by default)
+ FMap() : fmap(1), idx(0) {}
+ // assignment
+ FMap& operator= (const FMap& f)
+ { fmap = f.fmap; idx = f.idx; return *this; }
+ // clear local environments
+ void clear() { fmap.clear(); idx = 0; }
+ // resize (set number of maps)
+ void resize(size_t n) { fmap.resize(n); }
+ // current size (number of maps)
+ size_t size() const { return fmap.size(); }
+ // set index to first, next and given map
+ void first() { idx = 0; }
+ void next() { idx++; }
+ void set(size_t n) { idx = n; }
+ // access the current map
+ map<int32_t,Env>& act() { return fmap[idx]; }
+ // access the given map (read-only)
+ const map<int32_t,Env>& act(size_t n) const { return fmap[n]; }
+};
+
struct Env {
// function environment
int32_t tag; // function id, zero for anonymous functions
@@ -106,14 +133,8 @@
map<xmap_key,uint32_t > xmap;
// info about captured variables
list<VarInfo> xtab;
- // local function environments; note that there's actually a separate child
- // environment for each rule of the parent function (this gets initialized
- // to a single empty environment)
- vector< map<int32_t,Env> > fmap;
- // the current fmap index; this gets updated each time a new rule is added
- size_t fmap_idx;
- // convenience function to access the current fmap
- map<int32_t,Env>& act_fmap() { return fmap[fmap_idx]; }
+ // local function environments
+ FMap fmap;
// propagation links for environment variables (pointers to call sites)
// e in prop means that there's a call with de Bruijn index prop[e] at e
map<Env*,uint8_t> prop;
@@ -162,11 +183,11 @@
// default constructor
Env()
: tag(0), n(0), m(0), f(0), h(0), fp(0), args(0), envs(0),
- fmap(1), fmap_idx(0), b(false), local(false), parent(0), refc(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), f(0), h(0), fp(0), args(n), envs(0),
- fmap(1), fmap_idx(0), b(_b), local(_local), parent(0), refc(0)
+ b(_b), local(_local), parent(0), refc(0)
{
if (envstk.empty()) {
assert(!local);
@@ -180,7 +201,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), f(0), h(0), fp(0), args(n), envs(0),
- fmap(1), fmap_idx(0), b(_b), local(_local), parent(0), refc(0)
+ b(_b), local(_local), parent(0), refc(0)
{
if (envstk.empty()) {
assert(!local);
Modified: pure/trunk/lexer.ll
===================================================================
--- pure/trunk/lexer.ll 2008-07-31 12:16:17 UTC (rev 442)
+++ pure/trunk/lexer.ll 2008-08-02 07:07:44 UTC (rev 443)
@@ -942,8 +942,8 @@
if (e.h && e.h != e.f) e.h->print(os);
e.f->print(os);
for (size_t i = 0, n = e.fmap.size(); i < n; i++) {
- map<int32_t,Env>::const_iterator f;
- for (f = e.fmap[i].begin(); f != e.fmap[i].end(); f++)
+ for (map<int32_t,Env>::const_iterator f = e.fmap.act(i).begin(),
+ end = e.fmap.act(i).end(); f != end; f++)
print_defs(os, f->second);
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ag...@us...> - 2008-08-04 06:36:03
|
Revision: 444
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=444&view=rev
Author: agraef
Date: 2008-08-04 06:36:13 +0000 (Mon, 04 Aug 2008)
Log Message:
-----------
Refactoring of FMap/Env printing code.
Modified Paths:
--------------
pure/trunk/interpreter.hh
pure/trunk/lexer.ll
Modified: pure/trunk/interpreter.hh
===================================================================
--- pure/trunk/interpreter.hh 2008-08-02 07:07:44 UTC (rev 443)
+++ pure/trunk/interpreter.hh 2008-08-04 06:36:13 UTC (rev 444)
@@ -88,31 +88,28 @@
typedef list<Env*> EnvStack;
typedef pair<int32_t,uint8_t> xmap_key;
-class FMap {
+struct FMap {
// manage local function environments
- vector< map<int32_t,Env> > fmap;
+ vector< map<int32_t,Env> > m;
// current map index
size_t idx;
-public:
// constructor (create one empty map by default)
- FMap() : fmap(1), idx(0) {}
+ FMap() : m(1), idx(0) {}
// assignment
FMap& operator= (const FMap& f)
- { fmap = f.fmap; idx = f.idx; return *this; }
+ { m = f.m; idx = f.idx; return *this; }
// clear local environments
- void clear() { fmap.clear(); idx = 0; }
+ void clear() { m.clear(); idx = 0; }
// resize (set number of maps)
- void resize(size_t n) { fmap.resize(n); }
+ void resize(size_t n) { m.resize(n); }
// current size (number of maps)
- size_t size() const { return fmap.size(); }
+ size_t size() const { return m.size(); }
// set index to first, next and given map
void first() { idx = 0; }
void next() { idx++; }
void set(size_t n) { idx = n; }
// access the current map
- map<int32_t,Env>& act() { return fmap[idx]; }
- // access the given map (read-only)
- const map<int32_t,Env>& act(size_t n) const { return fmap[n]; }
+ map<int32_t,Env>& act() { return m[idx]; }
};
struct Env {
@@ -180,6 +177,8 @@
// interface to CreateRet() which also takes care of collecting temporaries
// and patching up tail calls
llvm::ReturnInst *CreateRet(llvm::Value *v);
+ // print the code of all functions in an environment, recursively
+ void print_defs(ostream& os) const;
// default constructor
Env()
: tag(0), n(0), m(0), f(0), h(0), fp(0), args(0), envs(0),
@@ -580,7 +579,6 @@
// Interface to the lexer.
public:
bool declare_op;
- void print_defs(ostream& os, const Env& e);
private:
bool lex_begin();
void lex_end();
Modified: pure/trunk/lexer.ll
===================================================================
--- pure/trunk/lexer.ll 2008-08-02 07:07:44 UTC (rev 443)
+++ pure/trunk/lexer.ll 2008-08-04 06:36:13 UTC (rev 444)
@@ -543,7 +543,7 @@
sout << " " << rules << ";";
if (aflag && m) sout << endl << *m;
if (dflag && fenv != interp.globalfuns.end() && fenv->second.f)
- interp.print_defs(sout, fenv->second);
+ fenv->second.print_defs(sout);
} else {
sout << " " << argc << " args, " << rules.size() << " rules";
}
@@ -560,7 +560,7 @@
if (n > 0) {
if (aflag && m) sout << *m << endl;
if (dflag && fenv != interp.globalfuns.end() && fenv->second.f)
- interp.print_defs(sout, fenv->second);
+ fenv->second.print_defs(sout);
nrules += n;
++nfuns;
}
@@ -936,14 +936,14 @@
result = k;
}
-void interpreter::print_defs(ostream& os, const Env& e)
+void Env::print_defs(ostream& os) const
{
- if (!e.f) return; // not used, probably a shadowed rule
- if (e.h && e.h != e.f) e.h->print(os);
- e.f->print(os);
- for (size_t i = 0, n = e.fmap.size(); i < n; i++) {
- for (map<int32_t,Env>::const_iterator f = e.fmap.act(i).begin(),
- end = e.fmap.act(i).end(); f != end; f++)
- print_defs(os, f->second);
+ if (!f) return; // not used, probably a shadowed rule
+ if (h && h != f) h->print(os);
+ f->print(os);
+ for (size_t i = 0, n = fmap.m.size(); i < n; i++) {
+ for (map<int32_t,Env>::const_iterator f = fmap.m[i].begin(),
+ end = fmap.m[i].end(); f != end; f++)
+ f->second.print_defs(os);
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ag...@us...> - 2008-08-04 06:50:13
|
Revision: 445
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=445&view=rev
Author: agraef
Date: 2008-08-04 06:50:23 +0000 (Mon, 04 Aug 2008)
Log Message:
-----------
Move fmap size check into FMap class.
Modified Paths:
--------------
pure/trunk/interpreter.cc
pure/trunk/interpreter.hh
Modified: pure/trunk/interpreter.cc
===================================================================
--- pure/trunk/interpreter.cc 2008-08-04 06:36:13 UTC (rev 444)
+++ pure/trunk/interpreter.cc 2008-08-04 06:50:23 UTC (rev 445)
@@ -5060,7 +5060,7 @@
while (r != rl.end()) {
const rule& rr = rules[*r];
reduced.insert(*r);
- if (f.fmap.size() > 1) f.fmap.set(*r);
+ f.fmap.set(*r);
f.f->getBasicBlockList().push_back(rulebb);
f.builder.SetInsertPoint(rulebb);
#if DEBUG>1
@@ -5118,5 +5118,5 @@
toplevel_codegen(rr.rhs);
rulebb = nextbb;
}
- if (f.fmap.size() > 1) f.fmap.first();
+ f.fmap.first();
}
Modified: pure/trunk/interpreter.hh
===================================================================
--- pure/trunk/interpreter.hh 2008-08-04 06:36:13 UTC (rev 444)
+++ pure/trunk/interpreter.hh 2008-08-04 06:50:23 UTC (rev 445)
@@ -102,12 +102,10 @@
void clear() { m.clear(); idx = 0; }
// resize (set number of maps)
void resize(size_t n) { m.resize(n); }
- // current size (number of maps)
- size_t size() const { return m.size(); }
// set index to first, next and given map
void first() { idx = 0; }
void next() { idx++; }
- void set(size_t n) { idx = n; }
+ void set(size_t n) { if (m.size() > 1) idx = n; }
// access the current map
map<int32_t,Env>& act() { return m[idx]; }
};
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ag...@us...> - 2008-08-04 06:59:33
|
Revision: 446
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=446&view=rev
Author: agraef
Date: 2008-08-04 06:59:40 +0000 (Mon, 04 Aug 2008)
Log Message:
-----------
Rename Env::print_defs -> print.
Modified Paths:
--------------
pure/trunk/interpreter.hh
pure/trunk/lexer.ll
Modified: pure/trunk/interpreter.hh
===================================================================
--- pure/trunk/interpreter.hh 2008-08-04 06:50:23 UTC (rev 445)
+++ pure/trunk/interpreter.hh 2008-08-04 06:59:40 UTC (rev 446)
@@ -176,7 +176,7 @@
// and patching up tail calls
llvm::ReturnInst *CreateRet(llvm::Value *v);
// print the code of all functions in an environment, recursively
- void print_defs(ostream& os) const;
+ void print(ostream& os) const;
// default constructor
Env()
: tag(0), n(0), m(0), f(0), h(0), fp(0), args(0), envs(0),
Modified: pure/trunk/lexer.ll
===================================================================
--- pure/trunk/lexer.ll 2008-08-04 06:50:23 UTC (rev 445)
+++ pure/trunk/lexer.ll 2008-08-04 06:59:40 UTC (rev 446)
@@ -543,7 +543,7 @@
sout << " " << rules << ";";
if (aflag && m) sout << endl << *m;
if (dflag && fenv != interp.globalfuns.end() && fenv->second.f)
- fenv->second.print_defs(sout);
+ fenv->second.print(sout);
} else {
sout << " " << argc << " args, " << rules.size() << " rules";
}
@@ -560,7 +560,7 @@
if (n > 0) {
if (aflag && m) sout << *m << endl;
if (dflag && fenv != interp.globalfuns.end() && fenv->second.f)
- fenv->second.print_defs(sout);
+ fenv->second.print(sout);
nrules += n;
++nfuns;
}
@@ -936,7 +936,7 @@
result = k;
}
-void Env::print_defs(ostream& os) const
+void Env::print(ostream& os) const
{
if (!f) return; // not used, probably a shadowed rule
if (h && h != f) h->print(os);
@@ -944,6 +944,6 @@
for (size_t i = 0, n = fmap.m.size(); i < n; i++) {
for (map<int32_t,Env>::const_iterator f = fmap.m[i].begin(),
end = fmap.m[i].end(); f != end; f++)
- f->second.print_defs(os);
+ f->second.print(os);
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ag...@us...> - 2008-08-05 04:34:57
|
Revision: 447
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=447&view=rev
Author: agraef
Date: 2008-08-05 04:35:06 +0000 (Tue, 05 Aug 2008)
Log Message:
-----------
Automatic resizing of FMap structure.
Modified Paths:
--------------
pure/trunk/interpreter.cc
pure/trunk/interpreter.hh
pure/trunk/lexer.ll
Modified: pure/trunk/interpreter.cc
===================================================================
--- pure/trunk/interpreter.cc 2008-08-04 06:59:40 UTC (rev 446)
+++ pure/trunk/interpreter.cc 2008-08-05 04:35:06 UTC (rev 447)
@@ -2280,8 +2280,6 @@
// build the maps for a global function definition
assert(info.t == env_info::fun);
// we need a separate submap for each rule
- size_t n = info.rules->size();
- fmap.resize(n);
rulel::const_iterator r = info.rules->begin();
while (r != info.rules->end()) {
build_map(r->rhs);
Modified: pure/trunk/interpreter.hh
===================================================================
--- pure/trunk/interpreter.hh 2008-08-04 06:59:40 UTC (rev 446)
+++ pure/trunk/interpreter.hh 2008-08-05 04:35:06 UTC (rev 447)
@@ -86,28 +86,30 @@
#define Builder llvm::IRBuilder
typedef list<Env*> EnvStack;
+typedef map<int32_t,Env> EnvMap;
typedef pair<int32_t,uint8_t> xmap_key;
struct FMap {
// manage local function environments
- vector< map<int32_t,Env> > m;
+ vector<EnvMap*> m;
// current map index
size_t idx;
// constructor (create one empty map by default)
- FMap() : m(1), idx(0) {}
+ FMap() : m(1), idx(0) { m[0] = new EnvMap; }
// assignment
FMap& operator= (const FMap& f)
{ m = f.m; idx = f.idx; return *this; }
// clear local environments
- void clear() { m.clear(); idx = 0; }
- // resize (set number of maps)
- void resize(size_t n) { m.resize(n); }
+ void clear()
+ { for (size_t i = 0, n = m.size(); i < n; i++) delete m[i];
+ m.clear(); idx = 0; }
// set index to first, next and given map
void first() { idx = 0; }
- void next() { idx++; }
+ void next()
+ { if (++idx >= m.size()) { m.resize(idx+1); m[idx] = new EnvMap; } }
void set(size_t n) { if (m.size() > 1) idx = n; }
// access the current map
- map<int32_t,Env>& act() { return m[idx]; }
+ EnvMap& act() { return *m[idx]; }
};
struct Env {
Modified: pure/trunk/lexer.ll
===================================================================
--- pure/trunk/lexer.ll 2008-08-04 06:59:40 UTC (rev 446)
+++ pure/trunk/lexer.ll 2008-08-05 04:35:06 UTC (rev 447)
@@ -942,8 +942,8 @@
if (h && h != f) h->print(os);
f->print(os);
for (size_t i = 0, n = fmap.m.size(); i < n; i++) {
- for (map<int32_t,Env>::const_iterator f = fmap.m[i].begin(),
- end = fmap.m[i].end(); f != end; f++)
+ for (EnvMap::const_iterator f = fmap.m[i]->begin(),
+ end = fmap.m[i]->end(); f != end; f++)
f->second.print(os);
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ag...@us...> - 2008-08-07 08:07:14
|
Revision: 452
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=452&view=rev
Author: agraef
Date: 2008-08-07 08:07:20 +0000 (Thu, 07 Aug 2008)
Log Message:
-----------
Allocate environments in FMap dynamically.
Modified Paths:
--------------
pure/trunk/interpreter.cc
pure/trunk/interpreter.hh
pure/trunk/lexer.ll
Modified: pure/trunk/interpreter.cc
===================================================================
--- pure/trunk/interpreter.cc 2008-08-05 05:45:03 UTC (rev 451)
+++ pure/trunk/interpreter.cc 2008-08-07 08:07:20 UTC (rev 452)
@@ -1929,6 +1929,28 @@
return os << ")";
}
+FMap& FMap::operator= (const FMap& f)
+{
+ clear(); m.resize(f.m.size());
+ for (size_t i = 0, n = f.m.size(); i < n; i++) m[i] = new EnvMap(*f.m[i]);
+ idx = f.idx; return *this;
+}
+
+void FMap::clear()
+{
+ set<Env*> e;
+ for (size_t i = 0, n = m.size(); i < n; i++) {
+ for (EnvMap::iterator it = m[i]->begin(), end = m[i]->end();
+ it != end; it++)
+ e.insert(it->second);
+ delete m[i];
+ }
+ for (set<Env*>::iterator it = e.begin(), end = e.end();
+ it != end; it++)
+ delete *it;
+ m.clear(); idx = 0;
+}
+
Env& Env::operator= (const Env& e)
{
if (f) {
@@ -2128,7 +2150,7 @@
fenv = *ei++;
}
assert(fenv->act_fmap().find(x.vtag()) != fenv->act_fmap().end());
- fenv = &fenv->fmap.act()[x.vtag()];
+ fenv = fenv->fmap.act()[x.vtag()];
if (!fenv->local) break;
// fenv now points to the environment of the (local) function
assert(fenv != this && fenv->tag == x.vtag());
@@ -2188,7 +2210,8 @@
if (n == 2 && f.tag() == interp.symtab.catch_sym().f) {
expr h = x.xval1().xval2(), y = x.xval2();
push("catch");
- Env& e = fmap.act()[-x.hash()] = Env(0, 0, y, true, true);
+ Env* eptr = fmap.act()[-x.hash()] = new Env(0, 0, y, true, true);
+ Env& e = *eptr;
e.build_map(y); e.promote_map();
pop();
build_map(h);
@@ -2205,14 +2228,16 @@
break;
case EXPR::LAMBDA: {
push("lambda");
- Env& e = fmap.act()[-x.hash()] = Env(0, 1, x.xval2(), true, true);
+ Env* eptr = fmap.act()[-x.hash()] = new Env(0, 1, x.xval2(), true, true);
+ Env& e = *eptr;
e.build_map(x.xval2()); e.promote_map();
pop();
break;
}
case EXPR::CASE: {
push("case");
- Env& e = fmap.act()[-x.hash()] = Env(0, 1, x.xval(), true, true);
+ Env* eptr = fmap.act()[-x.hash()] = new Env(0, 1, x.xval(), true, true);
+ Env& e = *eptr;
e.build_map(*x.rules()); e.promote_map();
pop();
build_map(x.xval());
@@ -2229,13 +2254,13 @@
for (env::const_iterator p = fe->begin(); p != fe->end(); p++) {
int32_t ftag = p->first;
const env_info& info = p->second;
- fmap.act()[ftag] = Env(ftag, info, false, true);
+ fmap.act()[ftag] = new Env(ftag, info, false, true);
}
// Now recursively build the maps for the child environments.
for (env::const_iterator p = fe->begin(); p != fe->end(); p++) {
int32_t ftag = p->first;
const env_info& info = p->second;
- Env& e = fmap.act()[ftag];
+ Env& e = *fmap.act()[ftag];
e.build_map(info); e.promote_map();
}
pop();
@@ -2259,7 +2284,8 @@
rulel::const_iterator s = r;
expr y = (++s == end)?x:s->rhs;
push("when");
- Env& e = fmap.act()[-y.hash()] = Env(0, 1, y, true, true);
+ Env* eptr = fmap.act()[-y.hash()] = new Env(0, 1, y, true, true);
+ Env& e = *eptr;
e.build_map(x, s, end); e.promote_map();
pop();
build_map(r->rhs);
@@ -3117,7 +3143,7 @@
rulel::const_iterator s = r;
expr y = (++s == end)?x:s->rhs;
assert(act.fmap.act().find(-y.hash()) != act.fmap.act().end());
- Env& e = act.fmap.act()[-y.hash()];
+ Env& e = *act.fmap.act()[-y.hash()];
push("when", &e);
fun_prolog("anonymous");
BasicBlock *bodybb = BasicBlock::Create("body");
@@ -3544,7 +3570,7 @@
int offs = idx-1;
if (idx == 0) {
// function in current environment ('with'-bound)
- f = &act_env().fmap.act()[tag];
+ f = act_env().fmap.act()[tag];
} else {
// function in an outer environment, the de Bruijn index idx tells us
// where on the current environment stack it's at
@@ -3552,7 +3578,7 @@
size_t i = idx;
for (; i > 0; e++, i--) assert(e != envstk.end());
// look up the function in the environment
- f = &(*e)->fmap.act()[tag];
+ f = (*e)->fmap.act()[tag];
}
if (f->n == n) {
// bingo! saturated call
@@ -3691,7 +3717,7 @@
expr h = x.xval1().xval2(), y = x.xval2();
Env& act = act_env();
assert(act.fmap.act().find(-x.hash()) != act.fmap.act().end());
- Env& e = act.fmap.act()[-x.hash()];
+ Env& e = *act.fmap.act()[-x.hash()];
push("catch", &e);
fun_prolog("anonymous");
e.CreateRet(codegen(y));
@@ -3732,7 +3758,7 @@
case EXPR::LAMBDA: {
Env& act = act_env();
assert(act.fmap.act().find(-x.hash()) != act.fmap.act().end());
- Env& e = act.fmap.act()[-x.hash()];
+ Env& e = *act.fmap.act()[-x.hash()];
push("lambda", &e);
fun("anonymous", x.pm(), true);
pop(&e);
@@ -3744,7 +3770,7 @@
// above) which gets applied to the subject term to be matched
Env& act = act_env();
assert(act.fmap.act().find(-x.hash()) != act.fmap.act().end());
- Env& e = act.fmap.act()[-x.hash()];
+ Env& e = *act.fmap.act()[-x.hash()];
push("case", &e);
fun("anonymous", x.pm(), true);
pop(&e);
@@ -3771,15 +3797,15 @@
for (p = fe->begin(); p != fe->end(); p++) {
int32_t ftag = p->first;
assert(act.fmap.act().find(ftag) != act.fmap.act().end());
- Env& e = act.fmap.act()[ftag];
+ Env& e = *act.fmap.act()[ftag];
push("with", &e);
- act.fmap.act()[ftag].f = fun_prolog(symtab.sym(ftag).s);
+ act.fmap.act()[ftag]->f = fun_prolog(symtab.sym(ftag).s);
pop(&e);
}
for (p = fe->begin(); p != fe->end(); p++) {
int32_t ftag = p->first;
const env_info& info = p->second;
- Env& e = act.fmap.act()[ftag];
+ Env& e = *act.fmap.act()[ftag];
push("with", &e);
fun_body(info.m);
pop(&e);
@@ -4074,7 +4100,7 @@
assert(!envstk.empty());
if (idx == 0) {
// function in current environment ('with'-bound)
- Env& f = act_env().fmap.act()[tag];
+ Env& f = *act_env().fmap.act()[tag];
return fbox(f, thunked);
}
// If we come here, the function is defined in an outer environment. Locate
@@ -4084,7 +4110,7 @@
size_t i = idx;
for (; i > 0; e++, i--) assert(e != envstk.end());
// look up the function in the environment
- Env& f = (*e)->fmap.act()[tag];
+ Env& f = *(*e)->fmap.act()[tag];
assert(f.f);
// Now create the closure. This is essentially just like fbox(), but we are
// called inside a nested environment here, and hence the de Bruijn indices
@@ -5058,7 +5084,7 @@
while (r != rl.end()) {
const rule& rr = rules[*r];
reduced.insert(*r);
- f.fmap.set(*r);
+ f.fmap.select(*r);
f.f->getBasicBlockList().push_back(rulebb);
f.builder.SetInsertPoint(rulebb);
#if DEBUG>1
Modified: pure/trunk/interpreter.hh
===================================================================
--- pure/trunk/interpreter.hh 2008-08-05 05:45:03 UTC (rev 451)
+++ pure/trunk/interpreter.hh 2008-08-07 08:07:20 UTC (rev 452)
@@ -85,7 +85,7 @@
#define Builder llvm::IRBuilder
typedef list<Env*> EnvStack;
-typedef map<int32_t,Env> EnvMap;
+typedef map<int32_t,Env*> EnvMap;
typedef pair<int32_t,uint8_t> xmap_key;
struct FMap {
@@ -95,20 +95,15 @@
size_t idx;
// constructor (create one empty map by default)
FMap() : m(1), idx(0) { m[0] = new EnvMap; }
- // clear local environments
- void clear()
- { for (size_t i = 0, n = m.size(); i < n; i++) delete m[i];
- m.clear(); idx = 0; }
// assignment
- FMap& operator= (const FMap& f)
- { clear(); m.resize(f.m.size());
- for (size_t i = 0, n = f.m.size(); i < n; i++) m[i] = new EnvMap(*f.m[i]);
- idx = f.idx; return *this; }
+ FMap& operator= (const FMap& f);
+ // clear local environments
+ void clear();
// set index to first, next and given map
void first() { idx = 0; }
void next()
{ if (++idx >= m.size()) { m.resize(idx+1); m[idx] = new EnvMap; } }
- void set(size_t n) { if (m.size() > 1) idx = n; }
+ void select(size_t n) { if (m.size() > 1) idx = n; }
// access the current map
EnvMap& act() { return *m[idx]; }
};
Modified: pure/trunk/lexer.ll
===================================================================
--- pure/trunk/lexer.ll 2008-08-05 05:45:03 UTC (rev 451)
+++ pure/trunk/lexer.ll 2008-08-07 08:07:20 UTC (rev 452)
@@ -941,9 +941,13 @@
if (!f) return; // not used, probably a shadowed rule
if (h && h != f) h->print(os);
f->print(os);
+ set<Env*> e;
for (size_t i = 0, n = fmap.m.size(); i < n; i++) {
for (EnvMap::const_iterator it = fmap.m[i]->begin(),
end = fmap.m[i]->end(); it != end; it++)
- it->second.print(os);
+ if (e.find(it->second) == e.end()) {
+ it->second->print(os);
+ e.insert(it->second);
+ }
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ag...@us...> - 2008-08-08 08:53:24
|
Revision: 453
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=453&view=rev
Author: agraef
Date: 2008-08-08 08:53:33 +0000 (Fri, 08 Aug 2008)
Log Message:
-----------
Rework FMap structure so that it can accommodate a forest of local environments.
Modified Paths:
--------------
pure/trunk/interpreter.cc
pure/trunk/interpreter.hh
Modified: pure/trunk/interpreter.cc
===================================================================
--- pure/trunk/interpreter.cc 2008-08-07 08:07:20 UTC (rev 452)
+++ pure/trunk/interpreter.cc 2008-08-08 08:53:33 UTC (rev 453)
@@ -1932,8 +1932,11 @@
FMap& FMap::operator= (const FMap& f)
{
clear(); m.resize(f.m.size());
- for (size_t i = 0, n = f.m.size(); i < n; i++) m[i] = new EnvMap(*f.m[i]);
- idx = f.idx; return *this;
+ for (size_t i = 0, n = f.m.size(); i < n; i++)
+ m[i] = new EnvMap(*f.m[i]);
+ root = f.root; pred = f.pred; succ = f.succ;
+ idx = f.idx; lastidx = f.lastidx;
+ return *this;
}
void FMap::clear()
@@ -1948,9 +1951,69 @@
for (set<Env*>::iterator it = e.begin(), end = e.end();
it != end; it++)
delete *it;
- m.clear(); idx = 0;
+ m.clear(); root.clear(); pred.clear(); succ.clear();
+ idx = 0; lastidx = -1;
}
+void FMap::next()
+{
+ assert(pred[idx] < 0);
+ if (succ[idx] >= 0)
+ idx = succ[idx];
+ else {
+ // create a new root
+ size_t n = root.size(), k = m.size();
+ root.resize(n+1);
+ m.resize(k+1); pred.resize(k+1); succ.resize(k+1);
+ root[n] = succ[idx] = k;
+ pred[k] = succ[k] = -1;
+ m[k] = new EnvMap;
+ idx = k;
+ }
+ lastidx = -1;
+}
+
+void FMap::select(size_t n)
+{
+ if (root.size() > 1) {
+ assert(n < root.size());
+ idx = root[n];
+ } else
+ idx = 0;
+ lastidx = -1;
+}
+
+void FMap::push()
+{
+ if (lastidx >= 0) {
+ assert(pred[lastidx] == idx);
+ if (succ[lastidx] >= 0)
+ idx = succ[lastidx];
+ else {
+ // create a new child, link from the previous one
+ size_t k = m.size();
+ m.resize(k+1); pred.resize(k+1); succ.resize(k+1);
+ pred[k] = idx; succ[k] = -1;
+ m[k] = new EnvMap(*m[idx]);
+ succ[lastidx] = k;
+ idx = k;
+ }
+ } else if (++idx >= (int32_t)m.size()) {
+ // the first child always immediately follows its parent
+ assert(idx == m.size());
+ m.resize(idx+1); pred.resize(idx+1); succ.resize(idx+1);
+ pred[idx] = idx-1; succ[idx] = -1;
+ m[idx] = new EnvMap(*m[idx-1]);
+ }
+ lastidx = -1;
+}
+
+void FMap::pop()
+{
+ assert(pred[idx] >= 0);
+ lastidx = idx; idx = pred[idx];
+}
+
Env& Env::operator= (const Env& e)
{
if (f) {
Modified: pure/trunk/interpreter.hh
===================================================================
--- pure/trunk/interpreter.hh 2008-08-07 08:07:20 UTC (rev 452)
+++ pure/trunk/interpreter.hh 2008-08-08 08:53:33 UTC (rev 453)
@@ -88,22 +88,49 @@
typedef map<int32_t,Env*> EnvMap;
typedef pair<int32_t,uint8_t> xmap_key;
+/* Manage local function environments. The FMap structure is organized as a
+ forest with one root per rule and one child per 'with' clause. Each node of
+ the forest holds a map mapping function symbols to the corresponding
+ environments. Initially, there is just one root holding an empty map. New
+ roots can be added with 'next', new children with 'push'; 'pop' backs out
+ to the parent level.
+
+ Child nodes are initialized to a copy of its parent map, to which you can
+ then add any local bindings. After the structure has been built, you can
+ use 'first' to reposition the "cursor" so that it points to the first root
+ and then traverse the forest using the same sequence of calls to 'next',
+ 'push' and 'pop'. The 'select' method can be used to position the cursor at
+ the given root. The 'act' method returns the current map.
+
+ Implementation: The forest is encoded as a collection of vectors: 'm' holds
+ the map for each node, 'root' the node number of each root, 'pred' the
+ parent link for each node, and 'succ' the link to the next sibling of each
+ node. A 'pred' value of -1 denotes a root node, in which case 'succ' points
+ to the next root (or contains -1 to indicate the last root). The 'idx'
+ member points to the current node, 'lastidx' to the most recently visited
+ child after a 'pop' operation (-1 otherwise). */
+
struct FMap {
- // manage local function environments
+ // map of each node
vector<EnvMap*> m;
- // current map index
- size_t idx;
+ // vectors encoding the forest structure (see explanation above)
+ vector<int32_t> root, pred, succ;
+ // index of current node and most previously visited child
+ int32_t idx, lastidx;
// constructor (create one empty map by default)
- FMap() : m(1), idx(0) { m[0] = new EnvMap; }
+ FMap() : m(1), root(1, 0), pred(1, -1), succ(1, -1), idx(0), lastidx(-1)
+ { m[0] = new EnvMap; }
// assignment
FMap& operator= (const FMap& f);
- // clear local environments
+ // clear
void clear();
- // set index to first, next and given map
- void first() { idx = 0; }
- void next()
- { if (++idx >= m.size()) { m.resize(idx+1); m[idx] = new EnvMap; } }
- void select(size_t n) { if (m.size() > 1) idx = n; }
+ // set index to first, next and given root node
+ void first() { idx = 0; lastidx = -1; }
+ void next();
+ void select(size_t n);
+ // set index to the parent or next child of the current node
+ void push();
+ void pop();
// access the current map
EnvMap& act() { return *m[idx]; }
};
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ag...@us...> - 2008-08-09 10:44:16
|
Revision: 454
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=454&view=rev
Author: agraef
Date: 2008-08-09 10:44:26 +0000 (Sat, 09 Aug 2008)
Log Message:
-----------
Bugfixes in FMap code.
Modified Paths:
--------------
pure/trunk/interpreter.cc
pure/trunk/interpreter.hh
Modified: pure/trunk/interpreter.cc
===================================================================
--- pure/trunk/interpreter.cc 2008-08-08 08:53:33 UTC (rev 453)
+++ pure/trunk/interpreter.cc 2008-08-09 10:44:26 UTC (rev 454)
@@ -1955,6 +1955,20 @@
idx = 0; lastidx = -1;
}
+void FMap::first()
+{
+ idx = 0; lastidx = -1;
+ // reset child environments
+ set<Env*> e;
+ for (size_t i = 0, n = m.size(); i < n; i++)
+ for (EnvMap::iterator it = m[i]->begin(), end = m[i]->end();
+ it != end; it++)
+ e.insert(it->second);
+ for (set<Env*>::iterator it = e.begin(), end = e.end();
+ it != end; it++)
+ (*it)->fmap.first();
+}
+
void FMap::next()
{
assert(pred[idx] < 0);
@@ -2000,7 +2014,7 @@
}
} else if (++idx >= (int32_t)m.size()) {
// the first child always immediately follows its parent
- assert(idx == m.size());
+ assert(idx == (int32_t)m.size());
m.resize(idx+1); pred.resize(idx+1); succ.resize(idx+1);
pred[idx] = idx-1; succ[idx] = -1;
m[idx] = new EnvMap(*m[idx-1]);
@@ -2212,7 +2226,7 @@
assert(ei != envstk.end());
fenv = *ei++;
}
- assert(fenv->act_fmap().find(x.vtag()) != fenv->act_fmap().end());
+ assert(fenv->fmap.act().find(x.vtag()) != fenv->fmap.act().end());
fenv = fenv->fmap.act()[x.vtag()];
if (!fenv->local) break;
// fenv now points to the environment of the (local) function
@@ -2369,13 +2383,12 @@
// build the maps for a global function definition
assert(info.t == env_info::fun);
// we need a separate submap for each rule
- rulel::const_iterator r = info.rules->begin();
- while (r != info.rules->end()) {
+ rulel::const_iterator r = info.rules->begin(), end = info.rules->end();
+ while (r != end) {
build_map(r->rhs);
if (!r->qual.is_null()) build_map(r->qual);
- r++; fmap.next();
+ if (++r != end) fmap.next();
}
- fmap.first();
#if DEBUG>1
if (!local) print_map(std::cerr, this);
#endif
@@ -5137,11 +5150,11 @@
Env& f = act_env();
assert(s->tr.empty()); // we're in a final state here
const rulev& rules = pm->r;
- assert(f.fmap.size() == 1 || f.fmap.size() == rules.size());
+ assert(f.fmap.root.size() == 1 || f.fmap.root.size() == rules.size());
const ruleml& rl = s->r;
ruleml::const_iterator r = rl.begin();
assert(r != rl.end());
- assert(f.fmap_idx == 0);
+ assert(f.fmap.idx == 0);
BasicBlock* rulebb = BasicBlock::Create(mklabel("rule.state", s->s, rl.front()));
f.builder.CreateBr(rulebb);
while (r != rl.end()) {
Modified: pure/trunk/interpreter.hh
===================================================================
--- pure/trunk/interpreter.hh 2008-08-08 08:53:33 UTC (rev 453)
+++ pure/trunk/interpreter.hh 2008-08-09 10:44:26 UTC (rev 454)
@@ -125,7 +125,7 @@
// clear
void clear();
// set index to first, next and given root node
- void first() { idx = 0; lastidx = -1; }
+ void first();
void next();
void select(size_t n);
// set index to the parent or next child of the current node
@@ -219,6 +219,7 @@
assert(local);
parent = envstk.front();
}
+ fmap.first();
}
// environment for a named closure with given definition info
Env(int32_t _tag, const env_info& info, bool _b, bool _local = false)
@@ -233,6 +234,7 @@
assert(local);
parent = envstk.front();
}
+ fmap.first();
}
// assignment -- this is only allowed if the lvalue is an uninitialized
// environment for which no LLVM function has been created yet, or if it is
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ag...@us...> - 2008-08-10 20:21:17
|
Revision: 461
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=461&view=rev
Author: agraef
Date: 2008-08-10 20:21:23 +0000 (Sun, 10 Aug 2008)
Log Message:
-----------
Optimize toplevel expressions to avoid unnecessary evaluations of constants.
Modified Paths:
--------------
pure/trunk/ChangeLog
pure/trunk/expr.cc
pure/trunk/expr.hh
pure/trunk/interpreter.cc
pure/trunk/interpreter.hh
pure/trunk/test/test015.log
Modified: pure/trunk/ChangeLog
===================================================================
--- pure/trunk/ChangeLog 2008-08-10 10:23:24 UTC (rev 460)
+++ pure/trunk/ChangeLog 2008-08-10 20:21:23 UTC (rev 461)
@@ -1,5 +1,8 @@
2008-08-10 Albert Graef <Dr....@t-...>
+ * interpreter.cc (doeval, dodefn): Optimize the case of toplevel
+ evaluations and variable definitions of constant expressions.
+
* interpreter.cc (codegen): Fixed memory leak caused by the new
list and tuple code. Reported by Jiri Spitz.
Modified: pure/trunk/expr.cc
===================================================================
--- pure/trunk/expr.cc 2008-08-10 10:23:24 UTC (rev 460)
+++ pure/trunk/expr.cc 2008-08-10 20:21:23 UTC (rev 461)
@@ -196,6 +196,15 @@
u.tag() == interpreter::g_interp->symtab.pair_sym().f;
}
+bool expr::is_tuplex() const
+{
+ expr x, y;
+ if (is_pair(x, y))
+ return !x.is_pair() && y.is_tuplex();
+ else
+ return true;
+}
+
bool expr::is_cons(expr &x, expr &y) const
{
expr u, v;
@@ -254,6 +263,23 @@
}
}
+bool expr::is_tuplex(exprl &xs) const
+{
+ expr x, y;
+ if (is_pair(x, y))
+ if (x.is_pair()) {
+ xs.clear();
+ return false;
+ } else {
+ xs.push_back(x);
+ return y.is_tuplex(xs);
+ }
+ else {
+ xs.push_back(*this);
+ return true;
+ }
+}
+
env_info::env_info(const env_info& e) : t(e.t), temp(e.temp) {
switch (t) {
case none:
Modified: pure/trunk/expr.hh
===================================================================
--- pure/trunk/expr.hh 2008-08-10 10:23:24 UTC (rev 460)
+++ pure/trunk/expr.hh 2008-08-10 20:21:23 UTC (rev 461)
@@ -468,6 +468,8 @@
// This is always true, as we consider a singleton as a tuple, too. Use
// is_pair() to test for a "real" tuple instead.
bool is_tuple() const { return true; }
+ // Check for proper (normalized) tuples.
+ bool is_tuplex() const;
bool is_cons(expr &x, expr &y) const;
bool is_list(exprl &xs) const;
bool is_listx(exprl &xs) const;
@@ -475,6 +477,7 @@
// Always true (see note above). Use is_pair() && istuple(xs) to test for a
// "real" tuple instead.
bool is_tuple(exprl &xs) const;
+ bool is_tuplex(exprl &xs) const;
};
/* Rules of the form: lhs -> rhs [if qual]. */
Modified: pure/trunk/interpreter.cc
===================================================================
--- pure/trunk/interpreter.cc 2008-08-10 10:23:24 UTC (rev 460)
+++ pure/trunk/interpreter.cc 2008-08-10 20:21:23 UTC (rev 461)
@@ -3062,6 +3062,58 @@
return act_builder().CreateLoad(fptrvar);
}
+pure_expr *interpreter::const_value(expr x)
+{
+ switch (x.tag()) {
+ // constants:
+ case EXPR::INT:
+ return pure_int(x.ival());
+ case EXPR::BIGINT:
+ return pure_mpz(x.zval());
+ case EXPR::DBL:
+ return pure_double(x.dval());
+ case EXPR::STR:
+ return pure_string_dup(x.sval());
+ case EXPR::PTR:
+ return pure_pointer(x.pval());
+ default: {
+ exprl xs;
+ if (x.tag() > 0) {
+ env::const_iterator it = globenv.find(x.tag());
+ map<int32_t,GlobalVar>::iterator v;
+ if (externals.find(x.tag()) != externals.end())
+ return 0;
+ else if (it == globenv.end())
+ // unbound symbol
+ return pure_const(x.tag());
+ else if (it->second.t == env_info::fvar &&
+ (v = globalvars.find(x.tag())) != globalvars.end())
+ // variable
+ return v->second.x;
+ else
+ return 0;
+ } else if (x.is_list(xs) || x.is_pair() && x.is_tuplex(xs)) {
+ // proper lists and tuples
+ size_t i, n = xs.size();
+ pure_expr **xv = (pure_expr**)malloc(n*sizeof(pure_expr*));
+ if (!xv) return 0;
+ exprl::iterator it = xs.begin(), end = xs.end();
+ for (i = 0; it != end; i++, it++)
+ if ((xv[i] = const_value(*it)) == 0) {
+ for (size_t j = 0; j < i; j++)
+ pure_freenew(xv[j]);
+ free(xv);
+ return 0;
+ }
+ pure_expr *res = (x.is_pair()?pure_tuplev:pure_listv)(n, xv);
+ free(xv);
+ return res;
+ } else
+ return 0;
+ }
+ }
+}
+
pure_expr *interpreter::doeval(expr x, pure_expr*& e)
{
char test;
@@ -3069,8 +3121,15 @@
e = pure_const(symtab.segfault_sym().f);
return 0;
}
- // Create an anonymous function to call in order to evaluate the target
- // expression.
+ e = 0;
+ // First check whether the value is actually a constant, then we can skip
+ // the compilation step.
+ clock_t t0 = clock();
+ pure_expr *res = const_value(x);
+ if (interactive && stats) clocks = clock()-t0;
+ if (res) return res;
+ // Not a constant value. Create an anonymous function to call in order to
+ // evaluate the target expression.
/* NOTE: The environment is allocated dynamically, so that its child
environments survive for the entire lifetime of any embedded closures,
which might still be called at a later time. */
@@ -3090,9 +3149,8 @@
// JIT the function.
f.fp = JIT->getPointerToFunction(f.f);
assert(f.fp);
- e = 0;
- clock_t t0 = clock();
- pure_expr *res = pure_invoke(f.fp, &e);
+ t0 = clock();
+ res = pure_invoke(f.fp, &e);
if (interactive && stats) clocks = clock()-t0;
// Get rid of our anonymous function.
JIT->freeMachineCodeForFunction(f.f);
@@ -3107,6 +3165,15 @@
return res;
}
+static pure_expr *pure_subterm(pure_expr *x, const path& p)
+{
+ for (size_t i = 0, n = p.len(); i < n; i++) {
+ assert(x->tag == EXPR::APP);
+ x = x->data.x[p[i]?1:0];
+ }
+ return x;
+}
+
pure_expr *interpreter::dodefn(env vars, expr lhs, expr rhs, pure_expr*& e)
{
char test;
@@ -3114,8 +3181,44 @@
e = pure_const(symtab.segfault_sym().f);
return 0;
}
- // Create an anonymous function to call in order to evaluate the rhs
- // expression, match against the lhs and bind variables in lhs accordingly.
+ e = 0;
+ // First check whether the value is actually a constant, then we can skip
+ // the compilation step.
+ clock_t t0 = clock();
+ pure_expr *res = const_value(rhs);
+ if (res) {
+ matcher m(rule(lhs, rhs));
+ if (m.match(rhs)) {
+ // Bind the variables.
+ for (env::const_iterator it = vars.begin(); it != vars.end(); ++it) {
+ int32_t tag = it->first;
+ const env_info& info = it->second;
+ assert(info.t == env_info::lvar && info.p);
+ // find the subterm at info.p
+ pure_expr *x = pure_subterm(res, *info.p);
+ // store the value in a global variable of the same name
+ const symbol& sym = symtab.sym(tag);
+ GlobalVar& v = globalvars[tag];
+ if (!v.v) {
+ v.v = new GlobalVariable
+ (ExprPtrTy, false, GlobalVariable::ExternalLinkage, 0, sym.s,
+ module);
+ JIT->addGlobalMapping(v.v, &v.x);
+ }
+ if (v.x) pure_free(v.x);
+ v.x = pure_new(x);
+ }
+ } else {
+ // Failed match, bail out.
+ pure_freenew(res);
+ res = e = 0;
+ }
+ if (interactive && stats) clocks = clock()-t0;
+ return res;
+ }
+ // Not a constant value. Create an anonymous function to call in order to
+ // evaluate the rhs expression, match against the lhs and bind variables in
+ // lhs accordingly.
Env *save_fptr = fptr;
fptr = new Env(0, 0, rhs, false); fptr->refc = 1;
Env &f = *fptr;
@@ -3176,9 +3279,8 @@
// JIT the function.
f.fp = JIT->getPointerToFunction(f.f);
assert(f.fp);
- e = 0;
- clock_t t0 = clock();
- pure_expr *res = pure_invoke(f.fp, &e);
+ t0 = clock();
+ res = pure_invoke(f.fp, &e);
if (interactive && stats) clocks = clock()-t0;
// Get rid of our anonymous function.
JIT->freeMachineCodeForFunction(f.f);
Modified: pure/trunk/interpreter.hh
===================================================================
--- pure/trunk/interpreter.hh 2008-08-10 10:23:24 UTC (rev 460)
+++ pure/trunk/interpreter.hh 2008-08-10 20:21:23 UTC (rev 461)
@@ -485,6 +485,7 @@
Env *find_stacked(int32_t tag);
Env& act_env() { assert(!envstk.empty()); return *envstk.front(); }
Builder& act_builder() { return act_env().builder; }
+ pure_expr *const_value(expr x);
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);
Modified: pure/trunk/test/test015.log
===================================================================
--- pure/trunk/test/test015.log 2008-08-10 10:23:24 UTC (rev 460)
+++ pure/trunk/test/test015.log 2008-08-10 20:21:23 UTC (rev 461)
@@ -1,9 +1,3 @@
-{
- rule #0: randlist = [52,72,26,78,46,19,44,72,96,75,46,86,13,84,1,94,67,79,14,61,90,77,36,94,88,44,16,42,47,3,60,79,18,52,89,30,94,38,93,91,33,53,70,97,76,75,9,85,17,1,41,29,37,41,13,38,29,2,23,3,22,52,49,88,77,5,11,54,34,45,58,58,6,81,40,58,19,89,17,20,11,15,99,68,81,64,32,73,82,72,65,35,61,41,81,77,27,4,60,51,63,18,27,45,64,74,41,61,61,85,18,30,2,0,95,99,20,60,93,55,54,43,44,30,20,21,4,20,57,91,41,65,35,58,39,3,28,9,44,92,92,60,86,1,68,84,12,5,1,39,86,1,92,88,66,65,7,9,0,52,78,65,54,79,72,25,25,13,48,46,10,50,85,1,82,96,1,92,6,3,19,27,44,64,15,48,64,53,35,39,72,72,30,10,91,74,23,65,36,2,84,4,5,42,47,50,98,60,91,75,71,97,2,26,1,8,15,11,75,93,12,59,12,59,6,25,41,94,35,1,97,76,86,40,86,3,20,42,98,56,57,46,46,76,30,41,9,13,69,18,89,73,30,14,82,44,59,97,50,89,72,26,45,26,96,1,94,90,9,52,8,79,86,9,88,0,20,47,64,93,9,57,50,65,89,73,68,80,24,76,76,54,48,41,7,52,50,75,13,0,76,10,96,8,11,89,74,21,58,24,88,39,5,92,45,87,23,48,57,85,21,92,3,40,5,10,52,57,11,4,50,72,49,34,3,36,91,50,86,92,1,28,23,71,10,77,24,43,59,51,76,72,80,74,50,81,5,57,86,55,82,12,71,0,3,29,67,30,43,27,12,13,10,41,82,26,14,1,22,35,76,42,68,52,32,14,37,74,72,73,17,55,68,87,55,34,53,96,92,75,68,33,36,70,66,39,1,40,66,21,8,61,1,21,20,37,39,29,52,79,39,72,69,63,12,73,16,2,21,17,17,52,31,90,44,7,13,53,64,84,96,34,36,71,4,12,25,96,83,68,68,80,52,58,68,46,75,27,31,6,14,47,23,94,33,26,17,87,86,47,21,77,10,20,23,16,26,80,10,25,87,21,66,62,79,34,63,25,3,80,40,43,75,78,48,71,38,2,41,90,61,83,75,60,86,40,23,58,10,49,84,70,10,69,3,42,73,27,33,31,21,60,57,7,47,16,29,65,99,9,5,2,93,6,71,55,41,98,46,69,68,53,57,54,60,37,89,24,41,57,29,83,26,26,49,6,10,23,61,70,25,80,12,40,80,16,44,69,2,54,50,91,43,86,83,66,87,91,15,9,67,13,89,31,7,58,21,69,30,80,87,74,57,86,84,64,9,62,80,93,44,10,94,85,13,84,68,55,98,34,75,20,42,85,2,25,53,62,77,62,79,11,88,77,85,47,77,28,29,19,29,47,31,40,59,41,86,4,4,76,43,49,53,95,45,96,38,46,3,33,86,94,70,24,19,86,69,16,85,18,6,91,31,19,28,99,24,84,42,45,71,50,30,34,0,82,36,87,27,60,76,21,19,37,65,20,42,43,5,87,66,30,11,92,93,41,21,69,28,29,63,54,58,74,6,95,72,8,96,10,9,44,38,71,93,29,94,17,2,38,94,71,46,33,82,58,89,70,91,89,63,35,6,79,62,45,74,29,62,52,79,69,23,20,57,55,90,98,43,40,1,47,54,4,47,72,23,35,96,7,15,17,67,19,74,8,97,31,70,51,89,91,14,69,82,74,99,83,77,66,66,24,13,58,37,17,99,59,75,99,61,9,8,86,55,56,22,55,81,58,73,29,91,47,15,16,73,82,97,4,7,72,53,92,7,23,92,30,72,99,25,48,12,51,99,85,31,42,59,32,45,46,86,55,63,5,46,21,45,9,72,86,17,76,28,35,96,0,25,26,87,9,89,32,80,72,47,26,48,50,95,63,6,61,43,21,1,43,90,57,35,25,30,89,3,84,5,72,1,15,9,36,55,67,31,51,81,79,84,52,56,40,77,91,66,9,83,39,1,22,72,23,64,0,97,9,6,54,66,18,51,18,99,6,94,59,54,92,8,32,9,24,87,67,67,23,80,56,57,60,53,90,89,57,82,2,45,28,57,21,7,20,76,57,85,80,69,59,31,34,74,83,1,45,31,39,19,69,43,84,6,35,91,52,99,52,86,75,50,21,46,2,0,7,55,50,49,58,13,88,6,91,72,1,89,69,50,83,88,21,54,72,54,82,48,47,2,31,70,39]
- state 0: #0
- <var> state 1
- state 1: #0
-}
let randlist = [52,72,26,78,46,19,44,72,96,75,46,86,13,84,1,94,67,79,14,61,90,77,36,94,88,44,16,42,47,3,60,79,18,52,89,30,94,38,93,91,33,53,70,97,76,75,9,85,17,1,41,29,37,41,13,38,29,2,23,3,22,52,49,88,77,5,11,54,34,45,58,58,6,81,40,58,19,89,17,20,11,15,99,68,81,64,32,73,82,72,65,35,61,41,81,77,27,4,60,51,63,18,27,45,64,74,41,61,61,85,18,30,2,0,95,99,20,60,93,55,54,43,44,30,20,21,4,20,57,91,41,65,35,58,39,3,28,9,44,92,92,60,86,1,68,84,12,5,1,39,86,1,92,88,66,65,7,9,0,52,78,65,54,79,72,25,25,13,48,46,10,50,85,1,82,96,1,92,6,3,19,27,44,64,15,48,64,53,35,39,72,72,30,10,91,74,23,65,36,2,84,4,5,42,47,50,98,60,91,75,71,97,2,26,1,8,15,11,75,93,12,59,12,59,6,25,41,94,35,1,97,76,86,40,86,3,20,42,98,56,57,46,46,76,30,41,9,13,69,18,89,73,30,14,82,44,59,97,50,89,72,26,45,26,96,1,94,90,9,52,8,79,86,9,88,0,20,47,64,93,9,57,50,65,89,73,68,80,24,76,76,54,48,41,7,52,50,75,13,0,76,10,96,8,11,89,74,21,58,24,88,39,5,92,45,87,23,48,57,85,21,92,3,40,5,10,52,57,11,4,50,72,49,34,3,36,91,50,86,92,1,28,23,71,10,77,24,43,59,51,76,72,80,74,50,81,5,57,86,55,82,12,71,0,3,29,67,30,43,27,12,13,10,41,82,26,14,1,22,35,76,42,68,52,32,14,37,74,72,73,17,55,68,87,55,34,53,96,92,75,68,33,36,70,66,39,1,40,66,21,8,61,1,21,20,37,39,29,52,79,39,72,69,63,12,73,16,2,21,17,17,52,31,90,44,7,13,53,64,84,96,34,36,71,4,12,25,96,83,68,68,80,52,58,68,46,75,27,31,6,14,47,23,94,33,26,17,87,86,47,21,77,10,20,23,16,26,80,10,25,87,21,66,62,79,34,63,25,3,80,40,43,75,78,48,71,38,2,41,90,61,83,75,60,86,40,23,58,10,49,84,70,10,69,3,42,73,27,33,31,21,60,57,7,47,16,29,65,99,9,5,2,93,6,71,55,41,98,46,69,68,53,57,54,60,37,89,24,41,57,29,83,26,26,49,6,10,23,61,70,25,80,12,40,80,16,44,69,2,54,50,91,43,86,83,66,87,91,15,9,67,13,89,31,7,58,21,69,30,80,87,74,57,86,84,64,9,62,80,93,44,10,94,85,13,84,68,55,98,34,75,20,42,85,2,25,53,62,77,62,79,11,88,77,85,47,77,28,29,19,29,47,31,40,59,41,86,4,4,76,43,49,53,95,45,96,38,46,3,33,86,94,70,24,19,86,69,16,85,18,6,91,31,19,28,99,24,84,42,45,71,50,30,34,0,82,36,87,27,60,76,21,19,37,65,20,42,43,5,87,66,30,11,92,93,41,21,69,28,29,63,54,58,74,6,95,72,8,96,10,9,44,38,71,93,29,94,17,2,38,94,71,46,33,82,58,89,70,91,89,63,35,6,79,62,45,74,29,62,52,79,69,23,20,57,55,90,98,43,40,1,47,54,4,47,72,23,35,96,7,15,17,67,19,74,8,97,31,70,51,89,91,14,69,82,74,99,83,77,66,66,24,13,58,37,17,99,59,75,99,61,9,8,86,55,56,22,55,81,58,73,29,91,47,15,16,73,82,97,4,7,72,53,92,7,23,92,30,72,99,25,48,12,51,99,85,31,42,59,32,45,46,86,55,63,5,46,21,45,9,72,86,17,76,28,35,96,0,25,26,87,9,89,32,80,72,47,26,48,50,95,63,6,61,43,21,1,43,90,57,35,25,30,89,3,84,5,72,1,15,9,36,55,67,31,51,81,79,84,52,56,40,77,91,66,9,83,39,1,22,72,23,64,0,97,9,6,54,66,18,51,18,99,6,94,59,54,92,8,32,9,24,87,67,67,23,80,56,57,60,53,90,89,57,82,2,45,28,57,21,7,20,76,57,85,80,69,59,31,34,74,83,1,45,31,39,19,69,43,84,6,35,91,52,99,52,86,75,50,21,46,2,0,7,55,50,49,58,13,88,6,91,72,1,89,69,50,83,88,21,54,72,54,82,48,47,2,31,70,39];
{
rule #0: a = set (1..10)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ag...@us...> - 2008-08-10 21:33:33
|
Revision: 462
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=462&view=rev
Author: agraef
Date: 2008-08-10 21:33:41 +0000 (Sun, 10 Aug 2008)
Log Message:
-----------
Overhaul of list/tuple generation code.
Modified Paths:
--------------
pure/trunk/ChangeLog
pure/trunk/interpreter.cc
pure/trunk/interpreter.hh
Modified: pure/trunk/ChangeLog
===================================================================
--- pure/trunk/ChangeLog 2008-08-10 20:21:23 UTC (rev 461)
+++ pure/trunk/ChangeLog 2008-08-10 21:33:41 UTC (rev 462)
@@ -4,7 +4,9 @@
evaluations and variable definitions of constant expressions.
* interpreter.cc (codegen): Fixed memory leak caused by the new
- list and tuple code. Reported by Jiri Spitz.
+ list and tuple code. Reported by Jiri Spitz. We now also impose a
+ minimum size for speeding up the generated code for smaller list
+ and tuple sizes.
2008-08-09 Albert Graef <Dr....@t-...>
Modified: pure/trunk/interpreter.cc
===================================================================
--- pure/trunk/interpreter.cc 2008-08-10 20:21:23 UTC (rev 461)
+++ pure/trunk/interpreter.cc 2008-08-10 21:33:41 UTC (rev 462)
@@ -3880,7 +3880,6 @@
interactive session. */
expr f; uint32_t n = count_args(x, f);
Value *v; Env *e;
- exprl xs;
if (f.tag() == EXPR::FVAR && (v = funcall(f.vtag(), f.vidx(), n, x)))
// local function call
return v;
@@ -3910,22 +3909,32 @@
argv.push_back(body);
act_env().CreateCall(module->getFunction("pure_new_args"), argv);
return call("pure_catch", handler, body);
- } else if (x.is_list(xs) || x.is_pair() && x.is_tuple(xs)) {
- // optimize the case of proper lists and tuples
- size_t i = 0, n = xs.size();
- vector<Value*> argv(n+1);
- argv[0] = UInt(n);
- for (exprl::iterator it = xs.begin(), end = xs.end(); it != end; it++)
- argv[++i] = codegen(*it);
- act_env().CreateCall(module->getFunction("pure_new_args"), argv);
- v = act_env().CreateCall
- (module->getFunction(x.is_pair()?"pure_tuplel":"pure_listl"), argv);
- vector<Value*> argv1;
- argv1.push_back(NullExprPtr);
- argv1.insert(argv1.end(), argv.begin(), argv.end());
- act_env().CreateCall(module->getFunction("pure_free_args"), argv1);
- return v;
} else {
+#if LIST_KLUDGE>0
+ /* Alternative code for proper lists and tuples, which considerably
+ speeds up compilation for larger sequences. See the comments at the
+ beginning of interpreter.hh for details. */
+ exprl xs;
+ if ((x.is_list(xs) || x.is_pair() && x.is_tuple(xs)) &&
+ xs.size() >= LIST_KLUDGE) {
+ size_t i = 0, n = xs.size();
+ vector<Value*> argv(n+1);
+ argv[0] = UInt(n);
+ for (exprl::iterator it = xs.begin(), end = xs.end(); it != end;
+ it++)
+ argv[++i] = codegen(*it);
+ act_env().CreateCall(module->getFunction("pure_new_args"), argv);
+ v = act_env().CreateCall
+ (module->getFunction(x.is_pair()?"pure_tuplel":"pure_listl"),
+ argv);
+ vector<Value*> argv1;
+ argv1.push_back(NullExprPtr);
+ argv1.insert(argv1.end(), argv.begin(), argv.end());
+ act_env().CreateCall(module->getFunction("pure_free_args"), argv1);
+ return v;
+ }
+ xs.clear();
+#endif
// ordinary function application
Value *u = codegen(x.xval1()), *v = codegen(x.xval2());
return apply(u, v);
Modified: pure/trunk/interpreter.hh
===================================================================
--- pure/trunk/interpreter.hh 2008-08-10 20:21:23 UTC (rev 461)
+++ pure/trunk/interpreter.hh 2008-08-10 21:33:41 UTC (rev 462)
@@ -29,6 +29,14 @@
get tail call elimination. */
#define USE_FASTCC 1
+/* Alternative code generation for the case of proper lists and tuples. This
+ is a kludge to work around performance issues with the JIT which (as of
+ LLVM 2.3) gets very slow with deeply nested call graphs. The code enabled
+ with this option here is actually less efficient for small list/tuple
+ values, which is why we impose a lower bound on the list/tuple size (10 by
+ default, use 0 to disable this option). */
+#define LIST_KLUDGE 10
+
using namespace std;
/* The Pure interpreter. */
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ag...@us...> - 2008-08-11 10:01:48
|
Revision: 463
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=463&view=rev
Author: agraef
Date: 2008-08-11 10:01:55 +0000 (Mon, 11 Aug 2008)
Log Message:
-----------
More optimizations of toplevel expressions to avoid unnecessary evaluations of constants.
Modified Paths:
--------------
pure/trunk/interpreter.cc
pure/trunk/interpreter.hh
Modified: pure/trunk/interpreter.cc
===================================================================
--- pure/trunk/interpreter.cc 2008-08-10 21:33:41 UTC (rev 462)
+++ pure/trunk/interpreter.cc 2008-08-11 10:01:55 UTC (rev 463)
@@ -3076,6 +3076,8 @@
return pure_string_dup(x.sval());
case EXPR::PTR:
return pure_pointer(x.pval());
+ case EXPR::APP:
+ return const_app_value(x);
default: {
exprl xs;
if (x.tag() > 0) {
@@ -3114,6 +3116,42 @@
}
}
+pure_expr *interpreter::const_app_value(expr x)
+{
+ if (x.tag() == EXPR::APP) {
+ pure_expr *f = 0, *y = 0;
+ if ((f = const_app_value(x.xval1())) && (y = const_value(x.xval2())))
+ return pure_app(f, y);
+ else {
+ if (f) pure_freenew(f);
+ return 0;
+ }
+ } else if (x.tag() > 0) {
+ env::const_iterator it = globenv.find(x.tag());
+ map<int32_t,GlobalVar>::iterator v;
+ if (externals.find(x.tag()) != externals.end())
+ return 0;
+ else if (it == globenv.end())
+ // unbound symbol
+ return pure_const(x.tag());
+ else if (it->second.t == env_info::fvar &&
+ (v = globalvars.find(x.tag())) != globalvars.end()) {
+ // variable value
+ pure_expr *y = v->second.x;
+ // walk down the spine, if any
+ while (y->tag == EXPR::APP) y = y->data.x[0];
+ // check if we got a closure subject to evaluation
+ if (y->tag >= 0 && y->data.clos)
+ return 0;
+ else
+ // not a callable closure, so it must be a constructor term
+ return v->second.x;
+ } else
+ return 0;
+ } else
+ return 0;
+}
+
pure_expr *interpreter::doeval(expr x, pure_expr*& e)
{
char test;
Modified: pure/trunk/interpreter.hh
===================================================================
--- pure/trunk/interpreter.hh 2008-08-10 21:33:41 UTC (rev 462)
+++ pure/trunk/interpreter.hh 2008-08-11 10:01:55 UTC (rev 463)
@@ -494,6 +494,7 @@
Env& act_env() { assert(!envstk.empty()); return *envstk.front(); }
Builder& act_builder() { return act_env().builder; }
pure_expr *const_value(expr x);
+ pure_expr *const_app_value(expr x);
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-08-11 10:26:37
|
Revision: 464
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=464&view=rev
Author: agraef
Date: 2008-08-11 10:26:44 +0000 (Mon, 11 Aug 2008)
Log Message:
-----------
OSX compatibility fixes.
Modified Paths:
--------------
pure/trunk/ChangeLog
pure/trunk/Makefile.in
pure/trunk/configure
pure/trunk/configure.ac
Modified: pure/trunk/ChangeLog
===================================================================
--- pure/trunk/ChangeLog 2008-08-11 10:01:55 UTC (rev 463)
+++ pure/trunk/ChangeLog 2008-08-11 10:26:44 UTC (rev 464)
@@ -1,3 +1,10 @@
+2008-08-11 Albert Graef <Dr....@t-...>
+
+ * configure.ac, Makefile.in: Additional configury for proper
+ handling of dynamic linking on OSX (-install_name option,
+ DYLD_LIBRARY_PATH). Reported by Ryan Schmidt. NOTE: This change
+ requires a reconfigure.
+
2008-08-10 Albert Graef <Dr....@t-...>
* interpreter.cc (doeval, dodefn): Optimize the case of toplevel
Modified: pure/trunk/Makefile.in
===================================================================
--- pure/trunk/Makefile.in 2008-08-11 10:01:55 UTC (rev 463)
+++ pure/trunk/Makefile.in 2008-08-11 10:26:44 UTC (rev 464)
@@ -257,15 +257,15 @@
rm -f $(srcdir)/test/*.log
$(srcdir)/test/prelude.log: lib/prelude.pure lib/primitives.pure lib/strings.pure
- LD_LIBRARY_PATH=. PURELIB=$(srcdir)/lib ./pure -n -v$(level) $< > $@ 2>&1
+ @LD_LIB_PATH@=. PURELIB=$(srcdir)/lib ./pure -n -v$(level) $< > $@ 2>&1
%.log: %.pure
- LD_LIBRARY_PATH=. PURELIB=$(srcdir)/lib ./pure -v$(level) < $< > $@ 2>&1
+ @LD_LIB_PATH@=. PURELIB=$(srcdir)/lib ./pure -v$(level) < $< > $@ 2>&1
check: pure
@ echo Running tests.
- @ (export LD_LIBRARY_PATH=.; export PURELIB=$(srcdir)/lib; echo $(ECHO_N) "prelude.pure: "; if ./pure $(ECHO_N) -v$(level) $(srcdir)/lib/prelude.pure 2>&1 | diff -q - $(srcdir)/test/prelude.log > /dev/null; then echo passed; else echo FAILED; fi)
- @ (export LD_LIBRARY_PATH=.; export PURELIB=$(srcdir)/lib; for x in $(notdir $(tests)); do echo $(ECHO_N) "$$x: "; if ./pure -v$(level) < $(srcdir)/test/$$x 2>&1 | diff -q - $(srcdir)/test/"`basename $$x .pure`.log" > /dev/null; then echo passed; else echo FAILED; fi; done)
+ @ (export @LD_LIB_PATH@=.; export PURELIB=$(srcdir)/lib; echo $(ECHO_N) "prelude.pure: "; if ./pure $(ECHO_N) -v$(level) $(srcdir)/lib/prelude.pure 2>&1 | diff -q - $(srcdir)/test/prelude.log > /dev/null; then echo passed; else echo FAILED; fi)
+ @ (export @LD_LIB_PATH@=.; export PURELIB=$(srcdir)/lib; for x in $(notdir $(tests)); do echo $(ECHO_N) "$$x: "; if ./pure -v$(level) < $(srcdir)/test/$$x 2>&1 | diff -q - $(srcdir)/test/"`basename $$x .pure`.log" > /dev/null; then echo passed; else echo FAILED; fi; done)
# DO NOT DELETE
Modified: pure/trunk/configure
===================================================================
--- pure/trunk/configure 2008-08-11 10:01:55 UTC (rev 463)
+++ pure/trunk/configure 2008-08-11 10:26:44 UTC (rev 464)
@@ -662,6 +662,7 @@
PIC
DLLEXT
AUXLIBS
+LD_LIB_PATH
INSTALL_PROGRAM
INSTALL_SCRIPT
INSTALL_DATA
@@ -1853,12 +1854,14 @@
PIC=
DLLEXT=".so"
AUXLIBS=
+LD_LIB_PATH="LD_LIBRARY_PATH"
case "$host" in
*-*-mingw*) AUXLIBS="-DLIBGLOB='\"libglob.dll\"' -DLIBREGEX='\"libgnurx-0.dll\"'";
LIBS="$LIBS -limagehlp -lpsapi";
LDFLAGS="-Wl,--enable-auto-import"; DLLEXT=".dll";;
x86_64-*-linux*) PIC="-fPIC";;
- *-*-darwin*) rdynamic=""; shared="-dynamiclib"; DLLEXT=".dylib";;
+ *-*-darwin*) LD_LIB_PATH="DYLD_LIBRARY_PATH";
+ rdynamic=""; shared="-dynamiclib -install_name \$(libdir)/\$(libpure)"; DLLEXT=".dylib";;
hppa*-hp-hpux*) rdynamic=""; DLLEXT=".sl";;
esac
@@ -1867,6 +1870,7 @@
+
cat >>confdefs.h <<_ACEOF
#define DLLEXT "${DLLEXT}"
_ACEOF
@@ -6136,6 +6140,7 @@
PIC!$PIC$ac_delim
DLLEXT!$DLLEXT$ac_delim
AUXLIBS!$AUXLIBS$ac_delim
+LD_LIB_PATH!$LD_LIB_PATH$ac_delim
INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim
INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim
INSTALL_DATA!$INSTALL_DATA$ac_delim
@@ -6159,7 +6164,7 @@
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 71; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 72; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
Modified: pure/trunk/configure.ac
===================================================================
--- pure/trunk/configure.ac 2008-08-11 10:01:55 UTC (rev 463)
+++ pure/trunk/configure.ac 2008-08-11 10:26:44 UTC (rev 464)
@@ -21,12 +21,14 @@
PIC=
DLLEXT=".so"
AUXLIBS=
+LD_LIB_PATH="LD_LIBRARY_PATH"
case "$host" in
*-*-mingw*) AUXLIBS="-DLIBGLOB='\"libglob.dll\"' -DLIBREGEX='\"libgnurx-0.dll\"'";
LIBS="$LIBS -limagehlp -lpsapi";
LDFLAGS="-Wl,--enable-auto-import"; DLLEXT=".dll";;
x86_64-*-linux*) PIC="-fPIC";;
- *-*-darwin*) rdynamic=""; shared="-dynamiclib"; DLLEXT=".dylib";;
+ *-*-darwin*) LD_LIB_PATH="DYLD_LIBRARY_PATH";
+ rdynamic=""; shared="-dynamiclib -install_name \$(libdir)/\$(libpure)"; DLLEXT=".dylib";;
hppa*-hp-hpux*) rdynamic=""; DLLEXT=".sl";;
esac
AC_SUBST(shared)
@@ -34,6 +36,7 @@
AC_SUBST(PIC)
AC_SUBST(DLLEXT)
AC_SUBST(AUXLIBS)
+AC_SUBST(LD_LIB_PATH)
AC_DEFINE_UNQUOTED(DLLEXT, "${DLLEXT}", [Define to the filename extension for shared libraries.])
dnl Check for programs.
AC_PROG_INSTALL
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ag...@us...> - 2008-08-11 19:07:46
|
Revision: 465
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=465&view=rev
Author: agraef
Date: 2008-08-11 19:07:48 +0000 (Mon, 11 Aug 2008)
Log Message:
-----------
Fix segfault in catch/throw.
Modified Paths:
--------------
pure/trunk/ChangeLog
pure/trunk/runtime.cc
Modified: pure/trunk/ChangeLog
===================================================================
--- pure/trunk/ChangeLog 2008-08-11 10:26:44 UTC (rev 464)
+++ pure/trunk/ChangeLog 2008-08-11 19:07:48 UTC (rev 465)
@@ -1,5 +1,8 @@
2008-08-11 Albert Graef <Dr....@t-...>
+ * runtime.cc (pure_catch): Fix wrong stack cleanup, causing
+ segfaults with catch/throw. Reported by Libor Spacek.
+
* configure.ac, Makefile.in: Additional configury for proper
handling of dynamic linking on OSX (-install_name option,
DYLD_LIBRARY_PATH). Reported by Ryan Schmidt. NOTE: This change
Modified: pure/trunk/runtime.cc
===================================================================
--- pure/trunk/runtime.cc 2008-08-11 10:26:44 UTC (rev 464)
+++ pure/trunk/runtime.cc 2008-08-11 19:07:48 UTC (rev 465)
@@ -1299,9 +1299,10 @@
size_t m = x->data.clos->m;
assert(x->data.clos->local || m == 0);
pure_expr **env = 0;
+ size_t oldsz = interp.sstk_sz;;
if (m>0) {
// construct a stack frame
- size_t sz = interp.sstk_sz;;
+ size_t sz = oldsz;
resize_sstk(interp.sstk, interp.sstk_cap, sz, m+1);
pure_expr **sstk = interp.sstk; env = sstk+sz+1;
sstk[sz++] = 0;
@@ -1324,7 +1325,7 @@
}
checkstk(test);
// Push an exception.
- pure_exception ex; ex.e = 0; ex.sz = interp.sstk_sz;
+ pure_exception ex; ex.e = 0; ex.sz = oldsz;
interp.estk.push_front(ex);
// Call the function now. Catch exceptions generated by the runtime.
if (setjmp(interp.estk.front().jmp)) {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ag...@us...> - 2008-08-12 06:23:07
|
Revision: 469
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=469&view=rev
Author: agraef
Date: 2008-08-12 06:23:16 +0000 (Tue, 12 Aug 2008)
Log Message:
-----------
Fix memory leaks.
Modified Paths:
--------------
pure/trunk/ChangeLog
pure/trunk/runtime.cc
Modified: pure/trunk/ChangeLog
===================================================================
--- pure/trunk/ChangeLog 2008-08-12 06:16:09 UTC (rev 468)
+++ pure/trunk/ChangeLog 2008-08-12 06:23:16 UTC (rev 469)
@@ -1,3 +1,7 @@
+2008-08-12 Albert Graef <Dr....@t-...>
+
+ * runtime.cc (pure_catch, pure_sys_vars): Fixed memory leaks.
+
2008-08-11 Albert Graef <Dr....@t-...>
* runtime.cc (pure_catch): Fix wrong stack cleanup, causing
Modified: pure/trunk/runtime.cc
===================================================================
--- pure/trunk/runtime.cc 2008-08-12 06:16:09 UTC (rev 468)
+++ pure/trunk/runtime.cc 2008-08-12 06:23:16 UTC (rev 469)
@@ -44,8 +44,8 @@
// Debug expression allocations. Warns about expression memory leaks.
// NOTE: Bookkeeping starts and ends at each toplevel pure_invoke call.
// Enabling this code will make the interpreter *much* slower.
-#if DEBUG>2
-#if DEBUG>9 // enable this to print each and every expression (de)allocation
+#if MEMDEBUG
+#if MEMDEBUG>1 // enable this to print each and every expression (de)allocation
#define MEMDEBUG_NEW(x) interpreter::g_interp->mem_allocations.insert(x); \
cerr << "NEW: " << (void*)x << ": " << x << endl;
#define MEMDEBUG_FREE(x) interpreter::g_interp->mem_allocations.erase(x); \
@@ -1216,7 +1216,11 @@
argv[n-1] = y;
// make sure that we do not gc the function before calling it
f0->refc++; pure_free_internal(x);
- // construct a stack frame
+ // first push the function object on the shadow stack so that it's
+ // garbage-collected in case of an exception
+ resize_sstk(interp.sstk, interp.sstk_cap, interp.sstk_sz, n+m+2);
+ interp.sstk[interp.sstk_sz++] = f0;
+ // construct a stack frame for the function call
{
size_t sz = interp.sstk_sz;
resize_sstk(interp.sstk, interp.sstk_cap, sz, n+m+1);
@@ -1258,7 +1262,8 @@
#if DEBUG>1
cerr << "pure_apply: result " << f0 << " = " << ret << " -> " << (void*)ret << ", refc = " << ret->refc << endl;
#endif
- pure_free_internal(f0);
+ // pop the function object from the shadow stack
+ pure_free_internal(interp.sstk[--interp.sstk_sz]);
return ret;
} else {
// construct a literal application node
@@ -1352,11 +1357,8 @@
cerr << "pure_catch: exception " << (void*)e << " (refc = " << e->refc
<< "): " << e << endl;
#endif
+ pure_free_internal(x);
pure_expr *res = pure_apply(h, e);
- assert(res);
- res->refc++;
- pure_free_internal(x);
- pure_unref_internal(res);
return res;
} else {
pure_expr *res;
@@ -2859,6 +2861,7 @@
} catch (err &e) {
cerr << "warning: " << e.what() << endl;
}
+ MEMDEBUG_FREE(x)
}
static inline void
@@ -2869,6 +2872,7 @@
} catch (err &e) {
cerr << "warning: " << e.what() << endl;
}
+ pure_freenew(x);
}
extern "C"
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ag...@us...> - 2008-08-12 06:49:46
|
Revision: 470
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=470&view=rev
Author: agraef
Date: 2008-08-12 06:49:56 +0000 (Tue, 12 Aug 2008)
Log Message:
-----------
Bugfix in parsing the option string of the 'list' command.
Modified Paths:
--------------
pure/trunk/ChangeLog
pure/trunk/lexer.ll
Modified: pure/trunk/ChangeLog
===================================================================
--- pure/trunk/ChangeLog 2008-08-12 06:23:16 UTC (rev 469)
+++ pure/trunk/ChangeLog 2008-08-12 06:49:56 UTC (rev 470)
@@ -1,5 +1,9 @@
2008-08-12 Albert Graef <Dr....@t-...>
+ * lexer.ll: Fixed a bug in option parsing of the 'list' command
+ which would cause an option string starting with '-a' to be
+ interpreted as an ordinary argument.
+
* runtime.cc (pure_catch, pure_sys_vars): Fixed memory leaks.
2008-08-11 Albert Graef <Dr....@t-...>
Modified: pure/trunk/lexer.ll
===================================================================
--- pure/trunk/lexer.ll 2008-08-12 06:23:16 UTC (rev 469)
+++ pure/trunk/lexer.ll 2008-08-12 06:49:56 UTC (rev 470)
@@ -343,7 +343,7 @@
// process option arguments
for (arg = args.l.begin(); arg != args.l.end(); arg++) {
const char *s = arg->c_str();
- if (s[0] != '-' || !s[1] || !strchr("cdefghlstv", s[1])) break;
+ if (s[0] != '-' || !s[1] || !strchr("acdefghlstv", s[1])) break;
while (*++s) {
switch (*s) {
case 'a': aflag = true; break;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ag...@us...> - 2008-08-12 12:56:07
|
Revision: 471
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=471&view=rev
Author: agraef
Date: 2008-08-12 12:56:14 +0000 (Tue, 12 Aug 2008)
Log Message:
-----------
Handle SIGFPE.
Modified Paths:
--------------
pure/trunk/ChangeLog
pure/trunk/interpreter.cc
pure/trunk/runtime.cc
pure/trunk/runtime.h
Modified: pure/trunk/ChangeLog
===================================================================
--- pure/trunk/ChangeLog 2008-08-12 06:49:56 UTC (rev 470)
+++ pure/trunk/ChangeLog 2008-08-12 12:56:14 UTC (rev 471)
@@ -1,5 +1,10 @@
2008-08-12 Albert Graef <Dr....@t-...>
+ * interpreter.cc (builtin_codegen), runtime.cc(bigint_div,
+ bigint_mod): Handle division by zero by throwing a 'signal SIGFPE'
+ exception. Previously, these would just bail out with an unhandled
+ SIGFPE signal.
+
* lexer.ll: Fixed a bug in option parsing of the 'list' command
which would cause an option string starting with '-a' to be
interpreted as an ordinary argument.
Modified: pure/trunk/interpreter.cc
===================================================================
--- pure/trunk/interpreter.cc 2008-08-12 06:49:56 UTC (rev 470)
+++ pure/trunk/interpreter.cc 2008-08-12 12:56:14 UTC (rev 471)
@@ -263,6 +263,8 @@
"pure_catch", "expr*", 2, "expr*", "expr*");
declare_extern((void*)pure_throw,
"pure_throw", "void", 1, "expr*");
+ declare_extern((void*)pure_sigfpe,
+ "pure_sigfpe", "void", 0);
declare_extern((void*)pure_new,
"pure_new", "expr*", 1, "expr*");
@@ -3652,11 +3654,43 @@
return b.CreateSub(u, v);
else if (f.ftag() == symtab.mult_sym().f)
return b.CreateMul(u, v);
- else if (f.ftag() == symtab.div_sym().f)
- return b.CreateSDiv(u, v);
- else if (f.ftag() == symtab.mod_sym().f)
- return b.CreateSRem(u, v);
- else {
+ else if (f.ftag() == symtab.div_sym().f) {
+ // catch division by zero
+ if (x.xval2().tag() == EXPR::INT && x.xval2().ival() == 0) {
+ b.CreateCall(module->getFunction("pure_sigfpe"));
+ return v;
+ } else {
+ BasicBlock *okbb = BasicBlock::Create("ok");
+ BasicBlock *errbb = BasicBlock::Create("err");
+ Value *cmp = b.CreateICmpEQ(v, Zero);
+ b.CreateCondBr(cmp, errbb, okbb);
+ act_env().f->getBasicBlockList().push_back(errbb);
+ b.SetInsertPoint(errbb);
+ b.CreateCall(module->getFunction("pure_sigfpe"));
+ b.CreateRet(NullExprPtr);
+ act_env().f->getBasicBlockList().push_back(okbb);
+ b.SetInsertPoint(okbb);
+ return b.CreateSDiv(u, v);
+ }
+ } else if (f.ftag() == symtab.mod_sym().f) {
+ // catch division by zero
+ if (x.xval2().tag() == EXPR::INT && x.xval2().ival() == 0) {
+ b.CreateCall(module->getFunction("pure_sigfpe"));
+ return v;
+ } else {
+ BasicBlock *okbb = BasicBlock::Create("ok");
+ BasicBlock *errbb = BasicBlock::Create("err");
+ Value *cmp = b.CreateICmpEQ(v, Zero);
+ b.CreateCondBr(cmp, errbb, okbb);
+ act_env().f->getBasicBlockList().push_back(errbb);
+ b.SetInsertPoint(errbb);
+ b.CreateCall(module->getFunction("pure_sigfpe"));
+ b.CreateRet(NullExprPtr);
+ act_env().f->getBasicBlockList().push_back(okbb);
+ b.SetInsertPoint(okbb);
+ return b.CreateSRem(u, v);
+ }
+ } else {
assert(0 && "error in type checker");
return 0;
}
Modified: pure/trunk/runtime.cc
===================================================================
--- pure/trunk/runtime.cc 2008-08-12 06:49:56 UTC (rev 470)
+++ pure/trunk/runtime.cc 2008-08-12 12:56:14 UTC (rev 471)
@@ -1289,7 +1289,15 @@
}
}
+#include <signal.h>
+
extern "C"
+void pure_sigfpe(void)
+{
+ pure_throw(signal_exception(SIGFPE));
+}
+
+extern "C"
pure_expr *pure_catch(pure_expr *h, pure_expr *x)
{
char test;
@@ -1952,9 +1960,12 @@
return u;
}
+// These raise a SIGFPE signal exception for division by zero.
+
extern "C"
pure_expr *bigint_div(mpz_t x, mpz_t y)
{
+ if (mpz_sgn(y) == 0) pure_sigfpe();
pure_expr *u = pure_bigint(0, 0);
mpz_t& z = u->data.z;
mpz_tdiv_q(z, x, y);
@@ -1964,6 +1975,7 @@
extern "C"
pure_expr *bigint_mod(mpz_t x, mpz_t y)
{
+ if (mpz_sgn(y) == 0) pure_sigfpe();
pure_expr *u = pure_bigint(0, 0);
mpz_t& z = u->data.z;
mpz_tdiv_r(z, x, y);
Modified: pure/trunk/runtime.h
===================================================================
--- pure/trunk/runtime.h 2008-08-12 06:49:56 UTC (rev 470)
+++ pure/trunk/runtime.h 2008-08-12 12:56:14 UTC (rev 471)
@@ -340,6 +340,11 @@
void pure_throw(pure_expr* e);
+/* Throw a 'signal SIGFPE' exception. This is used to signal division by
+ zero. */
+
+void pure_sigfpe(void);
+
/* Execute a parameterless fbox x and return its result. If an exception
occurs while x is executed, apply h to the value of the exception
instead. */
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ag...@us...> - 2008-08-12 13:44:48
|
Revision: 473
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=473&view=rev
Author: agraef
Date: 2008-08-12 13:44:56 +0000 (Tue, 12 Aug 2008)
Log Message:
-----------
Add handlers for POSIX termination signals.
Modified Paths:
--------------
pure/trunk/ChangeLog
pure/trunk/pure.cc
Modified: pure/trunk/ChangeLog
===================================================================
--- pure/trunk/ChangeLog 2008-08-12 13:28:56 UTC (rev 472)
+++ pure/trunk/ChangeLog 2008-08-12 13:44:56 UTC (rev 473)
@@ -1,5 +1,9 @@
2008-08-12 Albert Graef <Dr....@t-...>
+ * pure.cc (main): Set up handlers for standard POSIX termination
+ signals, mapping these to orderly Pure exceptions of the form
+ 'signal SIG'.
+
* interpreter.cc (builtin_codegen), runtime.cc(bigint_div,
bigint_mod): Handle division by zero by throwing a 'signal SIGFPE'
exception. Previously, these would just bail out with an unhandled
Modified: pure/trunk/pure.cc
===================================================================
--- pure/trunk/pure.cc 2008-08-12 13:28:56 UTC (rev 472)
+++ pure/trunk/pure.cc 2008-08-12 13:44:56 UTC (rev 473)
@@ -162,7 +162,7 @@
return matches;
}
-static void sigint_handler(int sig)
+static void sig_handler(int sig)
{
interpreter::brkflag = sig;
}
@@ -185,13 +185,32 @@
// This is used in advisory stack checks.
interpreter::baseptr = &base;
// make sure that SIGPIPE is ignored
-#ifndef _WIN32
+ /* Set up handlers for all standard POSIX termination signals (except
+ SIGKILL which is unmaskable). SIGPIPE is ignored by default, all others
+ are mapped to Pure exceptions of the form 'signal SIG', so that they can
+ be caught with 'catch' or safely return us to the interpreter's
+ interactive command line. */
+#ifdef SIGHUP
+ signal(SIGHUP, sig_handler);
+#endif
+#ifdef SIGINT
+ signal(SIGINT, sig_handler);
+#endif
+#ifdef SIGPIPE
signal(SIGPIPE, SIG_IGN);
#endif
- /* Set up a SIGINT handler which throws a Pure exception, so that we safely
- return to the interpreter's interactive command line when the user
- interrupts a computation. */
- signal(SIGINT, sigint_handler);
+#ifdef SIGALRM
+ signal(SIGALRM, sig_handler);
+#endif
+#ifdef SIGTERM
+ signal(SIGTERM, sig_handler);
+#endif
+#ifdef SIGUSR1
+ signal(SIGUSR1, sig_handler);
+#endif
+#ifdef SIGUSR2
+ signal(SIGUSR2, sig_handler);
+#endif
// set up an exit function which saves the history if needed
atexit(exit_handler);
// set the system locale
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ag...@us...> - 2008-08-12 13:59:49
|
Revision: 474
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=474&view=rev
Author: agraef
Date: 2008-08-12 13:59:55 +0000 (Tue, 12 Aug 2008)
Log Message:
-----------
Add signal constants.
Modified Paths:
--------------
pure/trunk/ChangeLog
pure/trunk/runtime.cc
Modified: pure/trunk/ChangeLog
===================================================================
--- pure/trunk/ChangeLog 2008-08-12 13:44:56 UTC (rev 473)
+++ pure/trunk/ChangeLog 2008-08-12 13:59:55 UTC (rev 474)
@@ -1,5 +1,7 @@
2008-08-12 Albert Graef <Dr....@t-...>
+ * runtime.cc (pure_sys_vars): Add signal constants.
+
* pure.cc (main): Set up handlers for standard POSIX termination
signals, mapping these to orderly Pure exceptions of the form
'signal SIG'.
Modified: pure/trunk/runtime.cc
===================================================================
--- pure/trunk/runtime.cc 2008-08-12 13:44:56 UTC (rev 473)
+++ pure/trunk/runtime.cc 2008-08-12 13:59:55 UTC (rev 474)
@@ -2938,4 +2938,62 @@
cdf(interp, "REG_ESPACE", pure_int(REG_ESPACE));
// regexec error codes
cdf(interp, "REG_NOMATCH", pure_int(REG_NOMATCH));
+ // signals
+#ifdef SIGHUP
+ cdf(interp, "SIGHUP", pure_int(SIGHUP));
+#endif
+#ifdef SIGINT
+ cdf(interp, "SIGINT", pure_int(SIGINT));
+#endif
+#ifdef SIGQUIT
+ cdf(interp, "SIGQUIT", pure_int(SIGQUIT));
+#endif
+#ifdef SIGILL
+ cdf(interp, "SIGILL", pure_int(SIGILL));
+#endif
+#ifdef SIGABRT
+ cdf(interp, "SIGABRT", pure_int(SIGABRT));
+#endif
+#ifdef SIGFPE
+ cdf(interp, "SIGFPE", pure_int(SIGFPE));
+#endif
+#ifdef SIGKILL
+ cdf(interp, "SIGKILL", pure_int(SIGKILL));
+#endif
+#ifdef SIGSEGV
+ cdf(interp, "SIGSEGV", pure_int(SIGSEGV));
+#endif
+#ifdef SIGPIPE
+ cdf(interp, "SIGPIPE", pure_int(SIGPIPE));
+#endif
+#ifdef SIGALRM
+ cdf(interp, "SIGALRM", pure_int(SIGALRM));
+#endif
+#ifdef SIGTERM
+ cdf(interp, "SIGTERM", pure_int(SIGTERM));
+#endif
+#ifdef SIGUSR1
+ cdf(interp, "SIGUSR1", pure_int(SIGUSR1));
+#endif
+#ifdef SIGUSR2
+ cdf(interp, "SIGUSR2", pure_int(SIGUSR2));
+#endif
+#ifdef SIGCHLD
+ cdf(interp, "SIGCHLD", pure_int(SIGCHLD));
+#endif
+#ifdef SIGCONT
+ cdf(interp, "SIGCONT", pure_int(SIGCONT));
+#endif
+#ifdef SIGSTOP
+ cdf(interp, "SIGSTOP", pure_int(SIGSTOP));
+#endif
+#ifdef SIGTSTP
+ cdf(interp, "SIGTSTP", pure_int(SIGTSTP));
+#endif
+#ifdef SIGTTIN
+ cdf(interp, "SIGTTIN", pure_int(SIGTTIN));
+#endif
+#ifdef SIGTTOU
+ cdf(interp, "SIGTTOU", pure_int(SIGTTOU));
+#endif
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ag...@us...> - 2008-08-12 19:20:27
|
Revision: 476
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=476&view=rev
Author: agraef
Date: 2008-08-12 19:20:37 +0000 (Tue, 12 Aug 2008)
Log Message:
-----------
Add 'trap' operation to configure signal handlers.
Modified Paths:
--------------
pure/trunk/ChangeLog
pure/trunk/lib/system.pure
pure/trunk/runtime.cc
pure/trunk/runtime.h
Modified: pure/trunk/ChangeLog
===================================================================
--- pure/trunk/ChangeLog 2008-08-12 19:17:34 UTC (rev 475)
+++ pure/trunk/ChangeLog 2008-08-12 19:20:37 UTC (rev 476)
@@ -1,5 +1,8 @@
2008-08-12 Albert Graef <Dr....@t-...>
+ * runtime.cc/h, lib/system.pure: Add 'trap' operation to configure
+ signal handlers.
+
* runtime.cc (pure_sys_vars): Add signal constants.
* pure.cc (main): Set up handlers for standard POSIX termination
Modified: pure/trunk/lib/system.pure
===================================================================
--- pure/trunk/lib/system.pure 2008-08-12 19:17:34 UTC (rev 475)
+++ pure/trunk/lib/system.pure 2008-08-12 19:20:37 UTC (rev 476)
@@ -47,6 +47,18 @@
errno = pure_errno;
set_errno val::int = pure_set_errno val;
+/* Signal handling. The action parameter of 'trap' can be one of the
+ predefined integer values SIG_TRAP, SIG_IGN and SIG_DFL. SIG_TRAP causes
+ the given signal to be handled by mapping it to a Pure exception of the
+ form 'signal SIG'. SIG_IGN ignores the signal, SIG_DFL reverts to the
+ system's default handling. See 'list -g SIG*' for a list of known signal
+ values on your system. NOTE: Most standard termination signals (SIGINT,
+ SIGTERM, etc.) are already set up at the start of the interpreter to report
+ corresponding Pure exceptions; if this is not desired, you can use 'trap'
+ to either ignore these or revert to the default handlers instead. */
+
+extern void pure_trap(int action, int sig) = trap;
+
/* Time functions. 'time' reports the current time in seconds since the
"epoch" a.k.a. 00:00:00 UTC, Jan 1 1970. The result is always a bigint (in
fact, the time value is already 64 bit on many OSes nowadays). */
Modified: pure/trunk/runtime.cc
===================================================================
--- pure/trunk/runtime.cc 2008-08-12 19:17:34 UTC (rev 475)
+++ pure/trunk/runtime.cc 2008-08-12 19:20:37 UTC (rev 476)
@@ -1297,7 +1297,23 @@
pure_throw(signal_exception(SIGFPE));
}
+static void sig_handler(int sig)
+{
+ interpreter::brkflag = sig;
+}
+
extern "C"
+void pure_trap(int32_t action, int32_t sig)
+{
+ if (action > 0)
+ signal(sig, sig_handler);
+ else if (action < 0)
+ signal(sig, SIG_IGN);
+ else
+ signal(sig, SIG_DFL);
+}
+
+extern "C"
pure_expr *pure_catch(pure_expr *h, pure_expr *x)
{
char test;
@@ -2938,6 +2954,10 @@
cdf(interp, "REG_ESPACE", pure_int(REG_ESPACE));
// regexec error codes
cdf(interp, "REG_NOMATCH", pure_int(REG_NOMATCH));
+ // signal actions
+ cdf(interp, "SIG_TRAP", pure_int(1));
+ cdf(interp, "SIG_IGN", pure_int(-1));
+ cdf(interp, "SIG_DFL", pure_int(0));
// signals
#ifdef SIGHUP
cdf(interp, "SIGHUP", pure_int(SIGHUP));
Modified: pure/trunk/runtime.h
===================================================================
--- pure/trunk/runtime.h 2008-08-12 19:17:34 UTC (rev 475)
+++ pure/trunk/runtime.h 2008-08-12 19:20:37 UTC (rev 476)
@@ -345,6 +345,11 @@
void pure_sigfpe(void);
+/* Configure signal handlers. The second argument is the signal number, the
+ first the action to take (-1 = ignore, 1 = handle, 0 = default). */
+
+void pure_trap(int32_t action, int32_t sig);
+
/* Execute a parameterless fbox x and return its result. If an exception
occurs while x is executed, apply h to the value of the exception
instead. */
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ag...@us...> - 2008-08-12 23:49:18
|
Revision: 477
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=477&view=rev
Author: agraef
Date: 2008-08-12 23:49:27 +0000 (Tue, 12 Aug 2008)
Log Message:
-----------
Move check for uncollected temporaries after an exception to the toplevel.
Modified Paths:
--------------
pure/trunk/ChangeLog
pure/trunk/interpreter.cc
pure/trunk/runtime.cc
Modified: pure/trunk/ChangeLog
===================================================================
--- pure/trunk/ChangeLog 2008-08-12 19:20:37 UTC (rev 476)
+++ pure/trunk/ChangeLog 2008-08-12 23:49:27 UTC (rev 477)
@@ -1,3 +1,11 @@
+2008-08-13 Albert Graef <Dr....@t-...>
+
+ * runtime.cc (pure_catch, pure_invoke): Collecting temporary
+ values after an exception doesn't seem to be safe while an
+ evaluation is still in progress. Moved this to doeval/dodefn in
+ interpreter.cc where we're back at the toplevel and it is safe to
+ do this.
+
2008-08-12 Albert Graef <Dr....@t-...>
* runtime.cc/h, lib/system.pure: Add 'trap' operation to configure
Modified: pure/trunk/interpreter.cc
===================================================================
--- pure/trunk/interpreter.cc 2008-08-12 19:20:37 UTC (rev 476)
+++ pure/trunk/interpreter.cc 2008-08-12 23:49:27 UTC (rev 477)
@@ -3201,6 +3201,22 @@
else
fptr->refc--;
fptr = save_fptr;
+ if (!res) {
+ // collect garbage
+ pure_expr *t = tmps;
+ while (t) {
+ pure_expr *next = t->xp;
+ pure_freenew(t);
+ t = next;
+ }
+ }
+#if DEBUG>1
+ pure_expr *t = tmps;
+ while (t) {
+ if (t != res) std::cerr << "uncollected temporary: " << t << endl;
+ t = t->xp;
+ }
+#endif
// NOTE: Result (if any) is to be freed by the caller.
return res;
}
@@ -3342,7 +3358,21 @@
globalvars.erase(tag);
}
}
+ // collect garbage
+ pure_expr *t = tmps;
+ while (t) {
+ pure_expr *next = t->xp;
+ pure_freenew(t);
+ t = next;
+ }
}
+#if DEBUG>1
+ pure_expr *t = tmps;
+ while (t) {
+ if (t != res) std::cerr << "uncollected temporary: " << t << endl;
+ t = t->xp;
+ }
+#endif
// NOTE: Result (if any) is to be freed by the caller.
return res;
}
Modified: pure/trunk/runtime.cc
===================================================================
--- pure/trunk/runtime.cc 2008-08-12 19:20:37 UTC (rev 476)
+++ pure/trunk/runtime.cc 2008-08-12 23:49:27 UTC (rev 477)
@@ -1363,6 +1363,8 @@
pure_expr *e = interp.estk.front().e;
interp.estk.pop_front();
if (e) pure_new_internal(e);
+#if 0
+ /* This doesn't seem to be safe here. Defer until later. */
// collect garbage
pure_expr *tmps = interp.tmps;
while (tmps) {
@@ -1370,6 +1372,7 @@
pure_freenew(tmps);
tmps = next;
}
+#endif
for (size_t i = interp.sstk_sz; i-- > sz; )
if (interp.sstk[i] && interp.sstk[i]->refc > 0)
pure_free_internal(interp.sstk[i]);
@@ -1394,7 +1397,7 @@
res = ((pure_expr*(*)())fp)();
// normal return
interp.estk.pop_front();
-#if DEBUG>1
+#if DEBUG>2
pure_expr *tmps = interp.tmps;
while (tmps) {
if (tmps != res) cerr << "uncollected temporary: " << tmps << endl;
@@ -1437,6 +1440,8 @@
e = interp.estk.front().e;
interp.estk.pop_front();
if (e) pure_new_internal(e);
+#if 0
+ /* This doesn't seem to be safe here. Defer until later. */
// collect garbage
pure_expr *tmps = interp.tmps;
while (tmps) {
@@ -1444,6 +1449,7 @@
pure_freenew(tmps);
tmps = next;
}
+#endif
for (size_t i = interp.sstk_sz; i-- > sz; )
if (interp.sstk[i] && interp.sstk[i]->refc > 0)
pure_free_internal(interp.sstk[i]);
@@ -1460,7 +1466,7 @@
// normal return
interp.estk.pop_front();
MEMDEBUG_SUMMARY(res)
-#if DEBUG>1
+#if DEBUG>2
pure_expr *tmps = interp.tmps;
while (tmps) {
if (tmps != res) cerr << "uncollected temporary: " << tmps << endl;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ag...@us...> - 2008-08-13 01:07:38
|
Revision: 479
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=479&view=rev
Author: agraef
Date: 2008-08-13 01:07:48 +0000 (Wed, 13 Aug 2008)
Log Message:
-----------
Add signal processing example.
Modified Paths:
--------------
pure/trunk/ChangeLog
Added Paths:
-----------
pure/trunk/examples/signal.pure
Modified: pure/trunk/ChangeLog
===================================================================
--- pure/trunk/ChangeLog 2008-08-12 23:58:36 UTC (rev 478)
+++ pure/trunk/ChangeLog 2008-08-13 01:07:48 UTC (rev 479)
@@ -1,5 +1,7 @@
2008-08-13 Albert Graef <Dr....@t-...>
+ * examples/signal.pure: Add signal processing example.
+
* runtime.cc (pure_catch, pure_invoke): Collecting temporary
values after an exception doesn't seem to be safe while an
evaluation is still in progress. Moved this to doeval/dodefn in
Added: pure/trunk/examples/signal.pure
===================================================================
--- pure/trunk/examples/signal.pure (rev 0)
+++ pure/trunk/examples/signal.pure 2008-08-13 01:07:48 UTC (rev 479)
@@ -0,0 +1,30 @@
+
+/* Signal processing example. */
+
+using system;
+extern int getpid();
+
+/* The common POSIX termination signals like SIGHUP, SIGINT, SIGTERM etc. are
+ already remapped to Pure exceptions by the interpreter when it starts.
+ Other kinds of signals can be handled as Pure exceptions, too, if we rebind
+ them with the 'trap' function. (Try 'list -g SIG*' to see which standard
+ signal values are known on your system.) Example: */
+
+trap SIG_TRAP SIGTSTP;
+
+/* Running this function enters an endless loop reporting all signals
+ delivered to the process. */
+
+test = printf "Running as pid %d, try to kill me!\n" getpid, loop;
+
+loop = loop when _ = catch sig check end
+with
+ sig (signal k) = loop when _ = printf "Hey, I got signal %d.\n" k end;
+end;
+
+/* Take a short nap so that the loop doesn't run busily. This also serves the
+ purpose of checking for pending signals. (Note that for performance reasons
+ the Pure interpreter only processes asynchronous signals at certain points,
+ such as the entry of a global Pure function.) */
+
+check = sleep 1;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ag...@us...> - 2008-08-13 09:06:07
|
Revision: 481
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=481&view=rev
Author: agraef
Date: 2008-08-13 09:06:17 +0000 (Wed, 13 Aug 2008)
Log Message:
-----------
Add support for single precision 'float' arguments and return values to the C interface.
Modified Paths:
--------------
pure/trunk/ChangeLog
pure/trunk/interpreter.cc
Modified: pure/trunk/ChangeLog
===================================================================
--- pure/trunk/ChangeLog 2008-08-13 01:45:47 UTC (rev 480)
+++ pure/trunk/ChangeLog 2008-08-13 09:06:17 UTC (rev 481)
@@ -1,5 +1,9 @@
2008-08-13 Albert Graef <Dr....@t-...>
+ * interpreter.cc (declare_extern, named_type, type_name): Add
+ support for single precision 'float' arguments and return values
+ to the C interface. Reported by Eddie Rucker.
+
* examples/signal.pure: Add signal processing example.
* runtime.cc (pure_catch, pure_invoke): Collecting temporary
Modified: pure/trunk/interpreter.cc
===================================================================
--- pure/trunk/interpreter.cc 2008-08-13 01:45:47 UTC (rev 480)
+++ pure/trunk/interpreter.cc 2008-08-13 09:06:17 UTC (rev 481)
@@ -2567,6 +2567,8 @@
return Type::Int32Ty;
else if (name == "long")
return Type::Int64Ty;
+ else if (name == "float")
+ return Type::FloatTy;
else if (name == "double")
return Type::DoubleTy;
else if (name == "char*")
@@ -2606,6 +2608,8 @@
return "int";
else if (type == Type::Int64Ty)
return "long";
+ else if (type == Type::FloatTy)
+ return "float";
else if (type == Type::DoubleTy)
return "double";
else if (type == CharPtrTy)
@@ -2872,6 +2876,18 @@
phi->addIncoming(intv, intbb);
phi->addIncoming(mpzv, mpzbb);
unboxed[i] = phi;
+ } else if (argt[i] == Type::FloatTy) {
+ BasicBlock *okbb = BasicBlock::Create("ok");
+ Value *idx[2] = { Zero, Zero };
+ Value *tagv = b.CreateLoad(b.CreateGEP(x, idx, idx+2), "tag");
+ b.CreateCondBr
+ (b.CreateICmpEQ(tagv, SInt(EXPR::DBL), "cmp"), okbb, failedbb);
+ f->getBasicBlockList().push_back(okbb);
+ b.SetInsertPoint(okbb);
+ Value *pv = b.CreateBitCast(x, DblExprPtrTy, "dblexpr");
+ idx[1] = ValFldIndex;
+ Value *dv = b.CreateLoad(b.CreateGEP(pv, idx, idx+2), "dblval");
+ unboxed[i] = b.CreateFPTrunc(dv, Type::FloatTy);
} else if (argt[i] == Type::DoubleTy) {
BasicBlock *okbb = BasicBlock::Create("ok");
Value *idx[2] = { Zero, Zero };
@@ -2897,6 +2913,7 @@
} else if (argt[i] == PointerType::get(Type::Int16Ty, 0) ||
argt[i] == PointerType::get(Type::Int32Ty, 0) ||
argt[i] == PointerType::get(Type::Int64Ty, 0) ||
+ argt[i] == PointerType::get(Type::FloatTy, 0) ||
argt[i] == PointerType::get(Type::DoubleTy, 0)) {
BasicBlock *okbb = BasicBlock::Create("ok");
Value *idx[2] = { Zero, Zero };
@@ -2977,6 +2994,9 @@
u = b.CreateCall(module->getFunction("pure_int"), u);
else if (type == Type::Int64Ty)
u = b.CreateCall(module->getFunction("pure_long"), u);
+ else if (type == Type::FloatTy)
+ u = b.CreateCall(module->getFunction("pure_double"),
+ b.CreateFPExt(u, Type::DoubleTy));
else if (type == Type::DoubleTy)
u = b.CreateCall(module->getFunction("pure_double"), u);
else if (type == CharPtrTy)
@@ -2984,6 +3004,7 @@
else if (type == PointerType::get(Type::Int16Ty, 0) ||
type == PointerType::get(Type::Int32Ty, 0) ||
type == PointerType::get(Type::Int64Ty, 0) ||
+ type == PointerType::get(Type::FloatTy, 0) ||
type == PointerType::get(Type::DoubleTy, 0))
u = b.CreateCall(module->getFunction("pure_pointer"),
b.CreateBitCast(u, VoidPtrTy));
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ag...@us...> - 2008-08-13 13:13:13
|
Revision: 484
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=484&view=rev
Author: agraef
Date: 2008-08-13 13:13:21 +0000 (Wed, 13 Aug 2008)
Log Message:
-----------
Mask further asynchronous signals in pure_catch while invoking an exception handler.
Modified Paths:
--------------
pure/trunk/interpreter.cc
pure/trunk/interpreter.hh
pure/trunk/runtime.cc
Modified: pure/trunk/interpreter.cc
===================================================================
--- pure/trunk/interpreter.cc 2008-08-13 12:43:41 UTC (rev 483)
+++ pure/trunk/interpreter.cc 2008-08-13 13:13:21 UTC (rev 484)
@@ -21,6 +21,7 @@
int interpreter::stackmax = 0;
int interpreter::stackdir = 0;
int interpreter::brkflag = 0;
+int interpreter::brkmask = 0;
static void* resolve_external(const std::string& name)
{
Modified: pure/trunk/interpreter.hh
===================================================================
--- pure/trunk/interpreter.hh 2008-08-13 12:43:41 UTC (rev 483)
+++ pure/trunk/interpreter.hh 2008-08-13 13:13:21 UTC (rev 484)
@@ -583,7 +583,7 @@
static bool g_interactive;
static interpreter* g_interp;
// not saved
- static int brkflag;
+ static int brkflag, brkmask;
static char *baseptr;
static int stackmax;
static int stackdir;
Modified: pure/trunk/runtime.cc
===================================================================
--- pure/trunk/runtime.cc 2008-08-13 12:43:41 UTC (rev 483)
+++ pure/trunk/runtime.cc 2008-08-13 13:13:21 UTC (rev 484)
@@ -38,12 +38,15 @@
interpreter::stackdir*(&test - interpreter::baseptr) \
>= interpreter::stackmax) \
pure_throw(stack_exception())
-#define checkall(test) if (interpreter::brkflag) \
- pure_throw(signal_exception(interpreter::brkflag)); \
- else if (interpreter::stackmax > 0 && \
+#define checkall(test) if (interpreter::stackmax > 0 && \
interpreter::stackdir*(&test - interpreter::baseptr) \
- >= interpreter::stackmax) \
- pure_throw(stack_exception())
+ >= interpreter::stackmax) { \
+ interpreter::brkmask = 0; \
+ pure_throw(stack_exception()); \
+ } else if (interpreter::brkmask) \
+ interpreter::brkmask = 0; \
+ else if (interpreter::brkflag) \
+ pure_throw(signal_exception(interpreter::brkflag))
// Debug expression allocations. Warns about expression memory leaks.
// NOTE: Bookkeeping starts and ends at each toplevel pure_invoke call.
@@ -1389,6 +1392,8 @@
<< "): " << e << endl;
#endif
pure_free_internal(x);
+ // mask further breaks until the handler starts executing
+ interp.brkmask = 1;
pure_expr *res = pure_apply(h, e);
return res;
} else {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ag...@us...> - 2008-08-14 07:57:53
|
Revision: 490
http://pure-lang.svn.sourceforge.net/pure-lang/?rev=490&view=rev
Author: agraef
Date: 2008-08-14 07:58:03 +0000 (Thu, 14 Aug 2008)
Log Message:
-----------
Removed obsolete fun and arg functions.
Modified Paths:
--------------
pure/trunk/ChangeLog
pure/trunk/lib/primitives.pure
pure/trunk/runtime.cc
pure/trunk/runtime.h
Modified: pure/trunk/ChangeLog
===================================================================
--- pure/trunk/ChangeLog 2008-08-14 07:30:45 UTC (rev 489)
+++ pure/trunk/ChangeLog 2008-08-14 07:58:03 UTC (rev 490)
@@ -1,3 +1,10 @@
+2008-08-14 Albert Graef <Dr....@t-...>
+
+ * lib/primitives.pure, runtime.cc/h: Removed obsolete fun and arg
+ functions, as 'arg' conflicted with math.pure. Also, applp is now
+ implemented directly in Pure, and the corresponding runtime
+ routine has been removed as well.
+
2008-08-13 Albert Graef <Dr....@t-...>
* interpreter.cc (declare_extern, named_type, type_name): Add
Modified: pure/trunk/lib/primitives.pure
===================================================================
--- pure/trunk/lib/primitives.pure 2008-08-14 07:30:45 UTC (rev 489)
+++ pure/trunk/lib/primitives.pure 2008-08-14 07:58:03 UTC (rev 490)
@@ -45,9 +45,11 @@
/* Predicates to check for function objects, global (unbound) variables,
function applications, proper lists, list nodes and tuples. */
-extern bool funp(expr*), bool lambdap(expr*), bool varp(expr*),
- bool applp(expr*);
+extern bool funp(expr*), bool lambdap(expr*), bool varp(expr*);
+applp (_ _) = 1;
+applp _ = 0 otherwise;
+
listp [] = 1;
listp (x:xs) = listp xs;
listp _ = 0 otherwise;
@@ -60,10 +62,6 @@
tuplep (x,xs) = 1;
tuplep _ = 0 otherwise;
-/* Operations to return the function and the argument in an application. */
-
-extern expr* fun(expr*), expr* arg(expr*);
-
/* Compute a 32 bit hash code of a Pure expression. */
extern int hash(expr*);
Modified: pure/trunk/runtime.cc
===================================================================
--- pure/trunk/runtime.cc 2008-08-14 07:30:45 UTC (rev 489)
+++ pure/trunk/runtime.cc 2008-08-14 07:58:03 UTC (rev 490)
@@ -2391,30 +2391,6 @@
}
extern "C"
-bool applp(const pure_expr *x)
-{
- return (x->tag == EXPR::APP);
-}
-
-extern "C"
-pure_expr *fun(const pure_expr *x)
-{
- if (x->tag == EXPR::APP)
- return x->data.x[0];
- else
- return 0;
-}
-
-extern "C"
-pure_expr *arg(const pure_expr *x)
-{
- if (x->tag == EXPR::APP)
- return x->data.x[1];
- else
- return 0;
-}
-
-extern "C"
int32_t pointer_get_byte(void *ptr)
{
uint8_t *p = (uint8_t*)ptr;
Modified: pure/trunk/runtime.h
===================================================================
--- pure/trunk/runtime.h 2008-08-14 07:30:45 UTC (rev 489)
+++ pure/trunk/runtime.h 2008-08-14 07:58:03 UTC (rev 490)
@@ -531,16 +531,6 @@
bool lambdap(const pure_expr *x);
bool varp(const pure_expr *x);
-/* Check whether an object is a function application, and return the function
- and the argument of an application. Note that these operations can't be
- defined in Pure because of the "head is function" rule which means that in
- a pattern of the form f x, f is always a literal function symbol and not a
- variable. */
-
-bool applp(const pure_expr *x);
-pure_expr *fun(const pure_expr *x);
-pure_expr *arg(const pure_expr *x);
-
/* Direct memory accesses. */
int32_t pointer_get_byte(void *ptr);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|