diff options
author | Karl Berry <karl@freefriends.org> | 2009-05-16 00:19:13 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2009-05-16 00:19:13 +0000 |
commit | bab45528d65eaafe68a705dbb2a57075c7b7cbd8 (patch) | |
tree | 10b4ae2b5195c8dede153ab89359ec00f55f325f /Build/source/utils/asymptote/genv.cc | |
parent | 8643d90372e9c31e0f461c15c596b60a545bd7d3 (diff) |
asymptote 1.72 sources (not integrated into build yet)
git-svn-id: svn://tug.org/texlive/trunk@13110 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/utils/asymptote/genv.cc')
-rw-r--r-- | Build/source/utils/asymptote/genv.cc | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/Build/source/utils/asymptote/genv.cc b/Build/source/utils/asymptote/genv.cc new file mode 100644 index 00000000000..bb0a325d6b5 --- /dev/null +++ b/Build/source/utils/asymptote/genv.cc @@ -0,0 +1,120 @@ +/***** + * genv.cc + * Andy Hammerlindl 2002/08/29 + * + * This is the global environment for the translation of programs. In + * actuality, it is basically a module manager. When a module is + * requested, it looks for the corresponding filename, and if found, + * parses and translates the file, returning the resultant module. + * + * genv sets up the basic type bindings and function bindings for + * builtin functions, casts and operators, and imports plain (if set), + * but all other initialization is done by the local environment defined + * in env.h. + *****/ + +#include <sstream> +#include <unistd.h> +#include <bits/stl_algo.h> + +#include "genv.h" +#include "env.h" +#include "dec.h" +#include "stm.h" +#include "types.h" +#include "settings.h" +#include "runtime.h" +#include "parser.h" +#include "locate.h" +#include "interact.h" +#include "builtin.h" + +using namespace types; +using settings::getSetting; +using settings::Setting; + + +namespace trans { + +genv::genv() + : imap() +{ + // Add settings as a module. This is so that the init file ~/.asy/config.asy + // can set settings. + imap["settings"]=settings::getSettingsModule(); + + // Translate plain in advance, if we're using autoplain. + if(getSetting<bool>("autoplain")) { + Setting("autoplain")=false; + + // Translate plain without autoplain. + getModule(symbol::trans("plain"), "plain"); + + Setting("autoplain")=true; + } +#ifdef HAVE_LIBGSL + imap["gsl"]=trans::getGSLModule(); +#endif +} + +record *genv::loadModule(symbol *id, string filename) { + // Get the abstract syntax tree. + absyntax::file *ast = parser::parseFile(filename,"Loading"); + + inTranslation.push_front(filename); + + em.sync(); + + record *r=ast->transAsFile(*this, id); + + inTranslation.remove(filename); + + return r; +} + +void genv::checkRecursion(string filename) { + if (find(inTranslation.begin(), inTranslation.end(), filename) != + inTranslation.end()) { + em.sync(); + em << "error: recursive loading of module '" << filename << "'\n"; + em.sync(); + throw handled_error(); + } +} + +record *genv::getModule(symbol *id, string filename) { + checkRecursion(filename); + + record *r=imap[filename]; + if (r) + return r; + else { + record *r=loadModule(id, filename); + // Don't add an erroneous module to the dictionary in interactive mode, as + // the user may try to load it again. + if (!interact::interactive || !em.errors()) + imap[filename]=r; + + return r; + } + +} + +typedef vm::stack::importInitMap importInitMap; + +importInitMap *genv::getInitMap() +{ + struct initMap : public importInitMap, public gc { + genv ≥ + initMap(genv &ge) + : ge(ge) {} + lambda *operator[](string s) { + record *r=ge.imap[s]; + return r ? r->getInit() : 0; + } + }; + + return new initMap(*this); +} + +} // namespace trans |