pure-lang-svn Mailing List for Pure (Page 17)
Status: Beta
Brought to you by:
agraef
You can subscribe to this list here.
2008 |
Jan
|
Feb
|
Mar
|
Apr
(5) |
May
(141) |
Jun
(184) |
Jul
(97) |
Aug
(232) |
Sep
(196) |
Oct
|
Nov
|
Dec
|
---|
From: <ag...@us...> - 2008-08-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 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:16:00
|
Revision: 468 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=468&view=rev Author: agraef Date: 2008-08-12 06:16:09 +0000 (Tue, 12 Aug 2008) Log Message: ----------- Add extra symbol for memory debugging code. Modified Paths: -------------- pure/trunk/interpreter.hh Modified: pure/trunk/interpreter.hh =================================================================== --- pure/trunk/interpreter.hh 2008-08-11 20:09:26 UTC (rev 467) +++ pure/trunk/interpreter.hh 2008-08-12 06:16:09 UTC (rev 468) @@ -19,11 +19,15 @@ #include "symtable.hh" #include "runtime.h" -// add some debugging output (disable in release version!) +/* Add some debugging output (disable in release version!). */ #ifndef DEBUG #define DEBUG 1 // extra sanity checks //#define DEBUG 2 // debug runtime + code execution etc. #endif +/* Extra memory debugging code (slow!). See runtime.cc for details. */ +#ifndef MEMDEBUG +#define MEMDEBUG 0 +#endif /* Experimental support for the "fast" calling convention which is needed to get tail call elimination. */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-11 20:09:29
|
Revision: 467 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=467&view=rev Author: agraef Date: 2008-08-11 20:09:26 +0000 (Mon, 11 Aug 2008) Log Message: ----------- Fix timex/catch/throw regression test. Modified Paths: -------------- pure/trunk/test/test017.log pure/trunk/test/test017.pure Modified: pure/trunk/test/test017.log =================================================================== --- pure/trunk/test/test017.log 2008-08-11 20:06:18 UTC (rev 466) +++ pure/trunk/test/test017.log 2008-08-11 20:09:26 UTC (rev 467) @@ -34,12 +34,12 @@ state 0: #0 <var> state 1 state 1: #0 -}); -0.14,0 +})!1; +0 timex (\_/*0:*/ -> bar 99 { rule #0: _ = bar 99 state 0: #0 <var> state 1 state 1: #0 -}); -0.0,99 +})!1; +99 Modified: pure/trunk/test/test017.pure =================================================================== --- pure/trunk/test/test017.pure 2008-08-11 20:06:18 UTC (rev 466) +++ pure/trunk/test/test017.pure 2008-08-11 20:09:26 UTC (rev 467) @@ -6,5 +6,5 @@ foo n = if n<=0 then n else foo (n-1); // burn some cycles bar x = catch id (throw x); -timex (\_->foo 100000); -timex (\_->bar 99); +timex (\_->foo 100000)!1; +timex (\_->bar 99)!1; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-11 20:06:20
|
Revision: 466 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=466&view=rev Author: agraef Date: 2008-08-11 20:06:18 +0000 (Mon, 11 Aug 2008) Log Message: ----------- Add timex/catch/throw regression test. Added Paths: ----------- pure/trunk/test/test017.log pure/trunk/test/test017.pure Added: pure/trunk/test/test017.log =================================================================== --- pure/trunk/test/test017.log (rev 0) +++ pure/trunk/test/test017.log 2008-08-11 20:06:18 UTC (rev 466) @@ -0,0 +1,45 @@ +timex f/*0:1*/ = (clock-t0/*1:*/)/1000000,res/*0:*/ when t0/*0:*/ = clock; res/*0:*/ = f/*1:1*/ () { + rule #0: res = f () + state 0: #0 + <var> state 1 + state 1: #0 +} { + rule #0: t0 = clock + state 0: #0 + <var> state 1 + state 1: #0 +} end; +foo n/*0:1*/ = if n/*0:1*/<=0 then n/*0:1*/ else foo (n/*0:1*/-1); +bar x/*0:1*/ = catch id (throw x/*1:1*/); +{ + rule #0: timex f = (clock-t0)/1000000,res when t0 = clock; res = f () end + state 0: #0 + <var> state 1 + state 1: #0 +} +{ + rule #0: foo n = if n<=0 then n else foo (n-1) + state 0: #0 + <var> state 1 + state 1: #0 +} +{ + rule #0: bar x = catch id (throw x) + state 0: #0 + <var> state 1 + state 1: #0 +} +timex (\_/*0:*/ -> foo 100000 { + rule #0: _ = foo 100000 + state 0: #0 + <var> state 1 + state 1: #0 +}); +0.14,0 +timex (\_/*0:*/ -> bar 99 { + rule #0: _ = bar 99 + state 0: #0 + <var> state 1 + state 1: #0 +}); +0.0,99 Added: pure/trunk/test/test017.pure =================================================================== --- pure/trunk/test/test017.pure (rev 0) +++ pure/trunk/test/test017.pure 2008-08-11 20:06:18 UTC (rev 466) @@ -0,0 +1,10 @@ + +using system; + +timex f = (clock-t0)/CLOCKS_PER_SEC, res when t0 = clock; res = f () end; + +foo n = if n<=0 then n else foo (n-1); // burn some cycles +bar x = catch id (throw x); + +timex (\_->foo 100000); +timex (\_->bar 99); 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-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 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-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-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 10:23:16
|
Revision: 460 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=460&view=rev Author: agraef Date: 2008-08-10 10:23:24 +0000 (Sun, 10 Aug 2008) Log Message: ----------- Updated ChangeLog. Modified Paths: -------------- pure/trunk/ChangeLog Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-08-10 08:37:53 UTC (rev 459) +++ pure/trunk/ChangeLog 2008-08-10 10:23:24 UTC (rev 460) @@ -1,3 +1,8 @@ +2008-08-10 Albert Graef <Dr....@t-...> + + * interpreter.cc (codegen): Fixed memory leak caused by the new + list and tuple code. Reported by Jiri Spitz. + 2008-08-09 Albert Graef <Dr....@t-...> * interpreter.cc: Overhaul environment-handling code in the code This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-10 08:37:45
|
Revision: 459 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=459&view=rev Author: agraef Date: 2008-08-10 08:37:53 +0000 (Sun, 10 Aug 2008) Log Message: ----------- Fix typos. Modified Paths: -------------- pure/trunk/interpreter.cc Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-08-10 07:34:54 UTC (rev 458) +++ pure/trunk/interpreter.cc 2008-08-10 08:37:53 UTC (rev 459) @@ -3816,7 +3816,7 @@ 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); - return act_env().CreateCall + v = act_env().CreateCall (module->getFunction(x.is_pair()?"pure_tuplel":"pure_listl"), argv); vector<Value*> argv1; argv1.push_back(NullExprPtr); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-10 07:34:44
|
Revision: 458 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=458&view=rev Author: agraef Date: 2008-08-10 07:34:54 +0000 (Sun, 10 Aug 2008) Log Message: ----------- Fix typos. Modified Paths: -------------- pure/trunk/expr.cc Modified: pure/trunk/expr.cc =================================================================== --- pure/trunk/expr.cc 2008-08-09 10:57:16 UTC (rev 457) +++ pure/trunk/expr.cc 2008-08-10 07:34:54 UTC (rev 458) @@ -170,7 +170,7 @@ { expr x, y; if (is_cons(x, y)) - return y.is_listx(); + return y.is_list(); else return is_nil(); } @@ -208,7 +208,7 @@ expr x, y; if (is_cons(x, y)) { xs.push_back(x); - return y.is_listx(xs); + return y.is_list(xs); } else if (is_nil()) return true; else { 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:57:08
|
Revision: 457 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=457&view=rev Author: agraef Date: 2008-08-09 10:57:16 +0000 (Sat, 09 Aug 2008) Log Message: ----------- Updated ChangeLog. Modified Paths: -------------- pure/trunk/ChangeLog Modified: pure/trunk/ChangeLog =================================================================== --- pure/trunk/ChangeLog 2008-08-09 10:52:33 UTC (rev 456) +++ pure/trunk/ChangeLog 2008-08-09 10:57:16 UTC (rev 457) @@ -1,3 +1,8 @@ +2008-08-09 Albert Graef <Dr....@t-...> + + * interpreter.cc: Overhaul environment-handling code in the code + generator so that it properly handles nested 'with' environments. + 2008-07-30 Albert Graef <Dr....@t-...> * w3centities.c: Updated to latest from W3C. 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:52:23
|
Revision: 456 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=456&view=rev Author: agraef Date: 2008-08-09 10:52:33 +0000 (Sat, 09 Aug 2008) Log Message: ----------- Add regression test for nested 'with' environments. Added Paths: ----------- pure/trunk/test/test016.log pure/trunk/test/test016.pure Added: pure/trunk/test/test016.log =================================================================== --- pure/trunk/test/test016.log (rev 0) +++ pure/trunk/test/test016.log 2008-08-09 10:52:33 UTC (rev 456) @@ -0,0 +1,44 @@ +(foo/*0*/ x with foo x/*0:1*/ = x/*0:1*/^3 { + rule #0: foo x = x^3 + state 0: #0 + <var> state 1 + state 1: #0 +} end)+(foo/*0*/ x with foo x/*0:1*/ = 2*x/*0:1*/ { + rule #0: foo x = 2*x + state 0: #0 + <var> state 1 + state 1: #0 +} end); +x^3+2*x +(foo/*0*/ x with foo x/*0:1*/ = x/*0:1*/^3 { + rule #0: foo x = x^3 + state 0: #0 + <var> state 1 + state 1: #0 +} end)+(foo/*0*/ x with foo = (+) 1 { + rule #0: foo = (+) 1 + state 0: #0 +} end with foo x/*0:1*/ = 2*x/*0:1*/ { + rule #0: foo x = 2*x + state 0: #0 + <var> state 1 + state 1: #0 +} end); +x^3+(1+x) +(foo/*0*/ x with foo x/*0:1*/ = x/*0:1*/^3 { + rule #0: foo x = x^3 + state 0: #0 + <var> state 1 + state 1: #0 +} end)+(foo/*0:*/ x when foo/*0:*/ = (+) 1 { + rule #0: foo = (+) 1 + state 0: #0 + <var> state 1 + state 1: #0 +} end with foo x/*0:1*/ = 2*x/*0:1*/ { + rule #0: foo x = 2*x + state 0: #0 + <var> state 1 + state 1: #0 +} end); +x^3+(1+x) Added: pure/trunk/test/test016.pure =================================================================== --- pure/trunk/test/test016.pure (rev 0) +++ pure/trunk/test/test016.pure 2008-08-09 10:52:33 UTC (rev 456) @@ -0,0 +1,5 @@ +// test handling of nested 'with' environments + +(foo x with foo x = x^3 end) + (foo x with foo x = 2*x end); +(foo x with foo x = x^3 end) + (foo x with foo = (+) 1 end with foo x = 2*x end); +(foo x with foo x = x^3 end) + (foo x when foo = (+) 1 end with foo x = 2*x end); 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:48:26
|
Revision: 455 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=455&view=rev Author: agraef Date: 2008-08-09 10:48:35 +0000 (Sat, 09 Aug 2008) Log Message: ----------- Fix handling of nested 'with' environments. Modified Paths: -------------- pure/trunk/interpreter.cc Modified: pure/trunk/interpreter.cc =================================================================== --- pure/trunk/interpreter.cc 2008-08-09 10:44:26 UTC (rev 454) +++ pure/trunk/interpreter.cc 2008-08-09 10:48:35 UTC (rev 455) @@ -2326,6 +2326,7 @@ break; case EXPR::WITH: { env *fe = x.fenv(); + fmap.push(); push("with"); // First enter all the environments into the fmap. for (env::const_iterator p = fe->begin(); p != fe->end(); p++) { @@ -2342,6 +2343,7 @@ } pop(); build_map(x.xval()); + fmap.pop(); break; } default: @@ -3870,6 +3872,7 @@ Env& act = act_env(); // first create all function entry points, so that we properly handle // mutually recursive definitions + act.fmap.push(); for (p = fe->begin(); p != fe->end(); p++) { int32_t ftag = p->first; assert(act.fmap.act().find(ftag) != act.fmap.act().end()); @@ -3887,6 +3890,7 @@ pop(&e); } Value *v = codegen(x.xval()); + act.fmap.pop(); return v; } default: { 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-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-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-05 05:44:53
|
Revision: 451 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=451&view=rev Author: agraef Date: 2008-08-05 05:45:03 +0000 (Tue, 05 Aug 2008) Log Message: ----------- Fix up FMap assignment operation. Modified Paths: -------------- pure/trunk/interpreter.hh Modified: pure/trunk/interpreter.hh =================================================================== --- pure/trunk/interpreter.hh 2008-08-05 05:30:38 UTC (rev 450) +++ pure/trunk/interpreter.hh 2008-08-05 05:45:03 UTC (rev 451) @@ -103,7 +103,7 @@ 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]); - m = f.m; idx = f.idx; return *this; } + idx = f.idx; return *this; } // set index to first, next and given map void first() { idx = 0; } void next() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ag...@us...> - 2008-08-05 05:30:30
|
Revision: 450 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=450&view=rev Author: agraef Date: 2008-08-05 05:30:38 +0000 (Tue, 05 Aug 2008) Log Message: ----------- Fix up FMap assignment operation. Modified Paths: -------------- pure/trunk/interpreter.hh Modified: pure/trunk/interpreter.hh =================================================================== --- pure/trunk/interpreter.hh 2008-08-05 04:58:46 UTC (rev 449) +++ pure/trunk/interpreter.hh 2008-08-05 05:30:38 UTC (rev 450) @@ -95,13 +95,15 @@ size_t idx; // constructor (create one empty map by default) 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() { 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]); + m = f.m; idx = f.idx; return *this; } // set index to first, next and given map void first() { idx = 0; } void next() 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:58:37
|
Revision: 449 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=449&view=rev Author: agraef Date: 2008-08-05 04:58:46 +0000 (Tue, 05 Aug 2008) Log Message: ----------- Cosmetic changes. Modified Paths: -------------- pure/trunk/lexer.ll Modified: pure/trunk/lexer.ll =================================================================== --- pure/trunk/lexer.ll 2008-08-05 04:37:56 UTC (rev 448) +++ pure/trunk/lexer.ll 2008-08-05 04:58:46 UTC (rev 449) @@ -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 (EnvMap::const_iterator f = fmap.m[i]->begin(), - end = fmap.m[i]->end(); f != end; f++) - f->second.print(os); + for (EnvMap::const_iterator it = fmap.m[i]->begin(), + end = fmap.m[i]->end(); it != end; it++) + it->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:37:48
|
Revision: 448 http://pure-lang.svn.sourceforge.net/pure-lang/?rev=448&view=rev Author: agraef Date: 2008-08-05 04:37:56 +0000 (Tue, 05 Aug 2008) Log Message: ----------- Remove obsolete code. Modified Paths: -------------- pure/trunk/interpreter.hh Modified: pure/trunk/interpreter.hh =================================================================== --- pure/trunk/interpreter.hh 2008-08-05 04:35:06 UTC (rev 447) +++ pure/trunk/interpreter.hh 2008-08-05 04:37:56 UTC (rev 448) @@ -82,7 +82,6 @@ : v(_v), vtag(_vtag), idx(_idx), p(_p) {} }; -//#define Builder llvm::LLVMBuilder #define Builder llvm::IRBuilder typedef list<Env*> EnvStack; 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-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. |