00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <mmxlight/mmxlight_glue.hpp>
00014 #include <mmxlight/base_evaluator.hpp>
00015 #include <mmxlight/shell.hpp>
00016 #include <basix/timer.hpp>
00017 #include <basix/system.hpp>
00018 #include <basix/cpp_syntax.hpp>
00019 #include <basix/mmx_syntax.hpp>
00020 #include <basix/threads.hpp>
00021 namespace mmx {
00022
00023 static table<string,string> include_cache ("");
00024
00025
00026
00027
00028
00029 static string
00030 mmx_relative_name (const string& name) {
00031 static string file_var ("current_file");
00032 if (!current_ev->contains (gen (file_var)))
00033 current_ev->set (file_var, as<generic> (string ("")));
00034 return relative_name (as<string> (current_ev->get (gen (file_var))), name);
00035 }
00036
00037 static string
00038 mmx_resolve_name (const string& name) {
00039 static string file_var ("current_file");
00040 if (!current_ev->contains (gen (file_var)))
00041 current_ev->set (file_var, as<generic> (string ("")));
00042 return resolve_name (as<string> (current_ev->get (gen (file_var))), name);
00043 }
00044
00045 static string
00046 mmx_strip_preamble (const string& s) {
00047 string preamble= "#!/usr/bin/env mmx-light\n";
00048 if (N(s) >= N(preamble) && s (0, N(preamble)) == preamble)
00049 return s (N(preamble)-1, N(s));
00050 return s;
00051 }
00052
00053 generic
00054 mmx_is_readable (const generic& x) {
00055 if (N(x) != 2) return wrong_nr_args (x);
00056 generic name= eval_as<string> (x[1]);
00057 if (is<exception> (name) || !is<string> (name)) return name;
00058 string file_name= mmx_resolve_name (as<string> (name));
00059 return as<generic> (file_name != "" && file_exists (file_name));
00060 }
00061
00062 static generic
00063 mmx_load_file (const generic& x) {
00064 if (N(x) != 2) return wrong_nr_args (x);
00065 generic name= eval_as<string> (x[1]);
00066 if (is<exception> (name) || !is<string> (name)) return name;
00067 string file_name= mmx_resolve_name (as<string> (name));
00068 ASSERT (file_name != "", "file " * as<string> (name) * " not found");
00069 string ucontents;
00070 if (load ("$MMX_LOAD_PATH", file_name, ucontents))
00071 ERROR ("file " * file_name * " could not be loaded");
00072 string contents= mmx_strip_preamble (ucontents);
00073 store_file_source (file_name, contents);
00074 return gen (GEN_TUPLE, as<generic> (file_name), as<generic> (contents));
00075 }
00076
00077 generic
00078 mmx_load_string (const generic& x) {
00079 generic name_contents= mmx_load_file (x);
00080 if (is<exception> (name_contents)) return name_contents;
00081 return name_contents[2];
00082 }
00083
00084 generic
00085 mmx_save_string (const generic& x) {
00086 if (N(x) != 3) return wrong_nr_args (x);
00087 generic name= eval_as<string> (x[1]);
00088 if (is<exception> (name) || !is<string> (name)) return name;
00089 generic contents= eval_as<string> (x[2]);
00090 if (is<exception> (contents) || !is<string> (contents)) return contents;
00091 string file_name= mmx_relative_name (as<string> (name));
00092 if (save (file_name, as<string> (contents)))
00093 ERROR ("file " * file_name * " not writable");
00094 return void_value ();
00095 }
00096
00097 generic
00098 mmx_load_directory (const generic& x) {
00099 if (N(x) != 2) return wrong_nr_args (x);
00100 generic name= eval_as<string> (x[1]);
00101 if (is<exception> (name) || !is<string> (name)) return name;
00102 string dir_name= mmx_relative_name (as<string> (name));
00103 vector<string> dir;
00104 if (load_directory (dir_name, dir))
00105 ERROR ("directory " * dir_name * " not found");
00106 vector<generic> gdir;
00107 for (nat i=0; i<N(dir); i++)
00108 gdir << as<generic> (dir[i]);
00109 return as<generic> (gdir);
00110 }
00111
00112 generic
00113 mmx_update_string (const generic& x) {
00114 if (N(x) != 3) return wrong_nr_args (x);
00115 generic name= eval_as<string> (x[1]);
00116 if (is<exception> (name) || !is<string> (name)) return name;
00117 generic contents= eval_as<string> (x[2]);
00118 if (is<exception> (contents) || !is<string> (contents)) return contents;
00119 string old_contents;
00120 string new_contents= as<string> (contents);
00121 string file_name= mmx_resolve_name (as<string> (name));
00122 ASSERT (file_name != "", "file " * as<string> (name) * " not found");
00123 if (load (file_name, old_contents))
00124 old_contents= (new_contents == ""? string ("x"): string (""));
00125 if (new_contents != old_contents)
00126 if (save (file_name, new_contents))
00127 ERROR ("file " * file_name * " not writable");
00128 return void_value ();
00129 }
00130
00131 generic
00132 mmx_parse (const generic& x) {
00133 generic name_contents= mmx_load_file (x);
00134 if (is<exception> (name_contents)) return name_contents;
00135 string file_name= as<string> (name_contents[1]);
00136 string contents = as<string> (name_contents[2]);
00137 return mmx_parse (file_name, contents);
00138 }
00139
00140 generic
00141 mmx_do_include (const generic& x, bool always) {
00142 static string file_var ("current_file");
00143 generic name_contents= mmx_load_file (x);
00144 if (is<exception> (name_contents)) return name_contents;
00145 string file_name= as<string> (name_contents[1]);
00146 string contents = as<string> (name_contents[2]);
00147 if (always || include_cache[file_name] != contents) {
00148 include_cache[file_name]= contents;
00149 generic y = mmx_parse (file_name, contents);
00150 string cur_file = as<string> (current_ev->get (gen (file_var)));
00151 current_ev->set (gen (file_var), as<generic> (file_name));
00152 generic r= eval (y);
00153 current_ev->set (gen (file_var), as<generic> (cur_file));
00154 if (is<exception> (r)) return r;
00155
00156 }
00157 return void_value ();
00158 }
00159
00160 generic
00161 mmx_include (const generic& x) {
00162 return mmx_do_include (x, false);
00163 }
00164
00165 generic
00166 mmx_reinclude (const generic& x) {
00167 return mmx_do_include (x, true);
00168 }
00169
00170 generic
00171 mmx_supports (const generic& x) {
00172 if (N(x) != 2) return wrong_nr_args (x);
00173 generic r= eval_as<string> (x[1]);
00174 if (is<exception> (r) || !is<string> (r)) return r;
00175 string name= as<string> (r);
00176 return as<generic> (dl_exists (name));
00177 }
00178
00179 generic
00180 mmx_use (const generic& x) {
00181 if (N(x) != 2) return wrong_nr_args (x);
00182 generic r= eval_as<string> (x[1]);
00183 if (is<exception> (r) || !is<string> (r)) return r;
00184 string name= as<string> (r);
00185 dl_link (name);
00186 verify_if_unknown_types (get_environment (current_ev));
00187 return void_value ();
00188 }
00189
00190 int
00191 mmx_system (const string& s) {
00192 return mmx::system (s);
00193 }
00194
00195
00196
00197
00198
00199 vector<generic>
00200 mmx_tokenize (const string& s, const string& sep, const bool& flag) {
00201 return as<vector<generic> > (tokenize (s, sep, flag));
00202 }
00203
00204 string
00205 mmx_recompose (const vector<generic>& v, const string& sep, const bool& flag) {
00206 return recompose (as<vector<string> > (v), sep, flag);
00207 }
00208
00209 int
00210 simple_loop (const int& i, const int& j) {
00211 threads_simple_loop (i, j);
00212 return 0;
00213 }
00214
00215 generic
00216 mmx_foobar () {
00217 return generic ((nat) 1);
00218 }
00219
00220
00221
00222
00223
00224 void
00225 glue_system () {
00226 define ("relative_name", relative_name);
00227 define ("resolve_name", resolve_name);
00228 define ("follow_link", follow_link);
00229 define ("path_name", path_name);
00230 define_primitive ("readable?", mmx_is_readable);
00231 define ("file?", file_is_file);
00232 define ("directory?", file_is_directory);
00233 define ("last_modified", file_last_modified);
00234 define_primitive ("load", mmx_load_string);
00235 define_primitive ("save", mmx_save_string);
00236 define_primitive ("update", mmx_update_string);
00237 define_primitive ("parse", mmx_parse);
00238 define_primitive ("include", mmx_include);
00239 define_primitive ("reinclude", mmx_reinclude);
00240 define_primitive ("load_directory", mmx_load_directory);
00241 define_primitive ("supports?", mmx_supports);
00242 define_primitive ("use", mmx_use);
00243
00244 define ("flatten_as_cpp", flatten_as_cpp);
00245 define ("flatten_as_mmx", flatten_as_mmx);
00246
00247 define ("get_env", get_env);
00248
00249 define ("system", mmx_system);
00250 define ("eval_system", eval_system);
00251 define ("prefix_dir", prefix_dir);
00252 define ("user_dir", user_dir);
00253 define ("sysconf_dir", user_dir);
00254 define ("file_exists?", file_exists);
00255 define ("strip_directory", strip_directory);
00256 define ("get_directory", get_directory);
00257 define ("strip_extension", strip_extension);
00258 define ("get_extension", get_extension);
00259 define ("get_number_threads", threads_get_number);
00260 define ("set_number_threads", threads_set_number);
00261 define ("get_number_cores", get_number_cores);
00262 define ("tokenize", mmx_tokenize);
00263 define ("recompose", mmx_recompose);
00264 define ("simple_loop", simple_loop);
00265 define ("foobar", mmx_foobar);
00266 define ("time", mmx_var_time);
00267 }
00268
00269 }