summaryrefslogtreecommitdiff
path: root/Build/source/utils/asymptote/genv.cc
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2009-05-16 00:19:13 +0000
committerKarl Berry <karl@freefriends.org>2009-05-16 00:19:13 +0000
commitbab45528d65eaafe68a705dbb2a57075c7b7cbd8 (patch)
tree10b4ae2b5195c8dede153ab89359ec00f55f325f /Build/source/utils/asymptote/genv.cc
parent8643d90372e9c31e0f461c15c596b60a545bd7d3 (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.cc120
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 &ge;
+ 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