comparison src/variables.cc @ 195:13c6086c325c

[project @ 1993-11-06 10:12:29 by jwe]
author jwe
date Sat, 06 Nov 1993 10:14:11 +0000
parents b6b4d8c513fe
children c8863fc976ee
comparison
equal deleted inserted replaced
194:4f3364dcf450 195:13c6086c325c
33 #include <iostream.h> 33 #include <iostream.h>
34 34
35 #include "statdefs.h" 35 #include "statdefs.h"
36 #include "tree-const.h" 36 #include "tree-const.h"
37 #include "variables.h" 37 #include "variables.h"
38 #include "user-prefs.h"
38 #include "symtab.h" 39 #include "symtab.h"
40 #include "builtins.h"
41 #include "g-builtins.h"
42 #include "t-builtins.h"
39 #include "error.h" 43 #include "error.h"
40 #include "utils.h" 44 #include "utils.h"
41 #include "tree.h" 45 #include "tree.h"
42 #include "help.h" 46 #include "help.h"
43 47
48 symbol_table *curr_sym_tab; 52 symbol_table *curr_sym_tab;
49 53
50 // Symbol table for global symbols. 54 // Symbol table for global symbols.
51 symbol_table *global_sym_tab; 55 symbol_table *global_sym_tab;
52 56
57 void
58 initialize_symbol_tables (void)
59 {
60 global_sym_tab = new symbol_table ();
61
62 top_level_sym_tab = new symbol_table ();
63
64 curr_sym_tab = top_level_sym_tab;
65 }
66
53 /* 67 /*
54 * Is there a corresponding M-file that is newer than the symbol 68 * Is there a corresponding M-file that is newer than the symbol
55 * definition? 69 * definition?
56 */ 70 */
57 int 71 int
58 symbol_out_of_date (symbol_record *sr) 72 symbol_out_of_date (symbol_record *sr)
59 { 73 {
60 int status = 0; 74 int ignore = user_pref.ignore_function_time_stamp;
75
76 if (ignore == 2)
77 return 0;
78
61 if (sr != (symbol_record *) NULL) 79 if (sr != (symbol_record *) NULL)
62 { 80 {
63 tree *ans = sr->def (); 81 tree *ans = sr->def ();
64 if (ans != NULL_TREE) 82 if (ans != NULL_TREE)
65 { 83 {
66 char *mf = ans->m_file_name (); 84 char *mf = ans->m_file_name ();
67 if (mf != (char *) NULL) 85 if (! (mf == (char *) NULL
86 || (ignore && ans->is_system_m_file ())))
68 { 87 {
69 time_t tp = ans->time_parsed (); 88 time_t tp = ans->time_parsed ();
70 status = is_newer (mf, tp); 89 char *fname = m_file_in_path (mf);
90 int status = is_newer (fname, tp);
91 delete [] fname;
92 if (status > 0)
93 return 1;
71 } 94 }
72 } 95 }
73 } 96 }
74 return status; 97 return 0;
75 } 98 }
76 99
77 /* 100 void
78 * Force a symbol into the global symbol table. 101 document_symbol (const char *name, const char *help)
79 */ 102 {
80 symbol_record * 103 if (is_builtin_variable (name))
81 force_global (char *name) 104 {
82 { 105 error ("sorry, can't redefine help for builtin variables");
83 symbol_record *retval = (symbol_record *) NULL; 106 }
84 107 else
85 if (valid_identifier (name)) 108 {
86 { 109 symbol_record *sym_rec = curr_sym_tab->lookup (name, 0);
87 symbol_record *sr; 110 if (sym_rec == (symbol_record *) NULL)
88 sr = curr_sym_tab->lookup (name, 0, 0); 111 {
89 if (sr == (symbol_record *) NULL) 112 error ("document: no such symbol `%s'", name);
90 {
91 retval = global_sym_tab->lookup (name, 1, 0);
92 retval->mark_as_forced_global ();
93 }
94 else if (sr->is_formal_parameter ())
95 {
96 error ("formal parameter `%s' can't be made global", name);
97 } 113 }
98 else 114 else
99 { 115 {
100 retval = global_sym_tab->lookup (name, 1, 0); 116 sym_rec->document (help);
101 retval->mark_as_forced_global (); 117 }
102 retval->alias (sr, 1); 118 }
103 curr_sym_tab->clear (name); 119 }
104 } 120
105 } 121 void
106 else 122 install_builtin_mapper_function (builtin_mapper_functions *mf)
107 warning ("`%s' is invalid as an identifier", name); 123 {
108 124 symbol_record *sym_rec = global_sym_tab->lookup (mf->name, 1);
109 return retval; 125 sym_rec->unprotect ();
110 } 126
111 127 Mapper_fcn mfcn;
112 int 128 mfcn.neg_arg_complex = mf->neg_arg_complex;
113 bind_variable (char *varname, tree_constant *val) 129 mfcn.d_d_mapper = mf->d_d_mapper;
114 { 130 mfcn.d_c_mapper = mf->d_c_mapper;
115 // Look for the symbol in the current symbol table. If it's there, 131 mfcn.c_c_mapper = mf->c_c_mapper;
116 // great. If not, don't insert it, but look for it in the global 132
117 // symbol table. If it's there, great. If not, insert it in the 133 tree_builtin *def = new tree_builtin (mf->nargin_max,
118 // original current symbol table. 134 mf->nargout_max, mfcn,
119 135 mf->name);
136
137 sym_rec->define (def);
138
139 sym_rec->document (mf->help_string);
140 sym_rec->make_eternal ();
141 sym_rec->protect ();
142 }
143
144 void
145 install_builtin_text_function (builtin_text_functions *tf)
146 {
147 symbol_record *sym_rec = global_sym_tab->lookup (tf->name, 1);
148 sym_rec->unprotect ();
149
150 tree_builtin *def = new tree_builtin (tf->nargin_max, 1,
151 tf->text_fcn, tf->name);
152
153 sym_rec->define (def);
154
155 sym_rec->document (tf->help_string);
156 sym_rec->make_eternal ();
157 sym_rec->protect ();
158
159 }
160
161 void
162 install_builtin_general_function (builtin_general_functions *gf)
163 {
164 symbol_record *sym_rec = global_sym_tab->lookup (gf->name, 1);
165 sym_rec->unprotect ();
166
167 tree_builtin *def = new tree_builtin (gf->nargin_max,
168 gf->nargout_max,
169 gf->general_fcn, gf->name);
170
171 sym_rec->define (def);
172
173 sym_rec->document (gf->help_string);
174 sym_rec->make_eternal ();
175 sym_rec->protect ();
176 }
177
178 void
179 install_builtin_variable (builtin_string_variables *sv)
180 {
181 tree_constant *val = new tree_constant (sv->value);
182
183 bind_builtin_variable (sv->name, val, 0, 1, sv->sv_function,
184 sv->help_string);
185 }
186
187 void
188 install_builtin_variable_as_function (const char *name, tree_constant *val,
189 int protect = 0, int eternal = 0)
190 {
191 symbol_record *sym_rec = global_sym_tab->lookup (name, 1);
192 sym_rec->unprotect ();
193
194 char *tmp_help = sym_rec->help ();
195
196 sym_rec->define_as_fcn (val);
197
198 sym_rec->document (tmp_help);
199
200 if (protect)
201 sym_rec->protect ();
202
203 if (eternal)
204 sym_rec->make_eternal ();
205 }
206
207 void
208 bind_nargin_and_nargout (symbol_table *sym_tab, int nargin, int nargout)
209 {
210 tree_constant *tmp;
120 symbol_record *sr; 211 symbol_record *sr;
121 sr = curr_sym_tab->lookup (varname, 0, 0); 212
122 if (sr == (symbol_record *) NULL) 213 sr = sym_tab->lookup ("nargin", 1, 0);
123 { 214 sr->unprotect ();
124 sr = global_sym_tab->lookup (varname, 0, 0); 215 tmp = new tree_constant (nargin-1);
125 if (sr == (symbol_record *) NULL) 216 sr->define (tmp);
126 { 217 sr->protect ();
127 sr = curr_sym_tab->lookup (varname, 1); 218
128 } 219 sr = sym_tab->lookup ("nargout", 1, 0);
129 } 220 sr->unprotect ();
130 221 tmp = new tree_constant (nargout);
131 if (sr != (symbol_record *) NULL) 222 sr->define (tmp);
132 { 223 sr->protect ();
133 sr->define (val); 224 }
134 return 0; 225
135 } 226 /*
136 else 227 * Give a global variable a definition. This will insert the symbol
137 return 1; 228 * in the global table if necessary.
138 } 229 */
139 230 void
140 int 231 bind_builtin_variable (const char *varname, tree_constant *val,
141 bind_protected_variable (char *varname, tree_constant *val) 232 int protect = 0, int eternal = 0,
142 { 233 sv_Function sv_fcn = (sv_Function) 0,
143 // Look for the symbol in the current symbol table. If it's there, 234 const char *help = (char *) 0)
144 // great. If not, don't insert it, but look for it in the global 235 {
145 // symbol table. If it's there, great. If not, insert it in the 236 symbol_record *sr = global_sym_tab->lookup (varname, 1, 0);
146 // original current symbol table. 237
147 238 // It is a programming error for a builtin symbol to be missing.
148 symbol_record *sr; 239 // Besides, we just inserted it, so it must be there.
149 sr = curr_sym_tab->lookup (varname, 0, 0); 240
150 if (sr == (symbol_record *) NULL) 241 assert (sr != (symbol_record *) NULL);
151 { 242
152 sr = global_sym_tab->lookup (varname, 0, 0); 243 sr->unprotect ();
153 if (sr == (symbol_record *) NULL) 244
154 { 245 // Must do this before define, since define will call the special
155 sr = curr_sym_tab->lookup (varname, 1); 246 // variable function only if it knows about it, and it needs to, so
156 } 247 // that user prefs can be properly initialized.
157 } 248
158 249 if (sv_fcn)
159 if (sr != (symbol_record *) NULL) 250 sr->set_sv_function (sv_fcn);
160 { 251
161 sr->unprotect (); 252 sr->define_builtin_var (val);
162 sr->define (val); 253
163 sr->protect (); 254 if (protect)
164 return 0; 255 sr->protect ();
165 } 256
166 else 257 if (eternal)
167 return 1; 258 sr->make_eternal ();
168 } 259
169 260 if (help)
170 /* 261 sr->document (help);
171 * Look for name first in current then in global symbol tables. If 262 }
172 * name is found and it refers to a string, return a new string 263
173 * containing its value. Otherwise, return NULL. 264 /*
265 * Look for the given name in the global symbol table. If it refers
266 * to a string, return a new copy. If not, return NULL.
174 */ 267 */
175 char * 268 char *
176 octave_string_variable (char *name) 269 builtin_string_variable (const char *name)
177 { 270 {
271 symbol_record *sr = global_sym_tab->lookup (name, 0, 0);
272
273 // It is a prorgramming error to look for builtins that aren't.
274
275 assert (sr != (symbol_record *) NULL);
276
178 char *retval = (char *) NULL; 277 char *retval = (char *) NULL;
179 symbol_record *sr;
180 sr = curr_sym_tab->lookup (name, 0, 0);
181 if (sr == (symbol_record *) NULL)
182 {
183 sr = global_sym_tab->lookup (name, 0, 0);
184 if (sr == (symbol_record *) NULL)
185 return retval;
186 }
187 278
188 tree *defn = sr->def (); 279 tree *defn = sr->def ();
280
189 if (defn != NULL_TREE) 281 if (defn != NULL_TREE)
190 { 282 {
191 tree_constant val = defn->eval (0); 283 tree_constant val = defn->eval (0);
192 if (error_state) 284
193 return retval; 285 if (! error_state && val.is_string_type ())
194 else if (val.is_string_type ())
195 { 286 {
196 char *s = val.string_value (); 287 char *s = val.string_value ();
197 if (s != (char *) NULL) 288 if (s != (char *) NULL)
198 retval = strsave (s); 289 retval = strsave (s);
199 } 290 }
201 292
202 return retval; 293 return retval;
203 } 294 }
204 295
205 /* 296 /*
206 * Look for name first in current then in global symbol tables. If 297 * Look for the given name in the global symbol table. If it refers
207 * name is found and it refers to a real scalar, place the value in d 298 * to a real scalar, place the value in d and return 0. Otherwise,
208 * and return 0. Otherwise, return -1. 299 * return -1.
209 */ 300 */
210 int 301 int
211 octave_real_scalar_variable (char *name, double& d) 302 builtin_real_scalar_variable (const char *name, double& d)
212 { 303 {
213 int status = -1; 304 int status = -1;
214 symbol_record *sr; 305 symbol_record *sr = global_sym_tab->lookup (name, 0, 0);
215 sr = curr_sym_tab->lookup (name, 0, 0); 306
216 if (sr == (symbol_record *) NULL) 307 // It is a prorgramming error to look for builtins that aren't.
217 { 308
218 sr = global_sym_tab->lookup (name, 0, 0); 309 assert (sr != (symbol_record *) NULL);
219 if (sr == (symbol_record *) NULL)
220 return status;
221 }
222 310
223 tree *defn = sr->def (); 311 tree *defn = sr->def ();
312
224 if (defn != NULL_TREE) 313 if (defn != NULL_TREE)
225 { 314 {
226 tree_constant val = defn->eval (0); 315 tree_constant val = defn->eval (0);
227 if (error_state) 316
228 return status; 317 if (! error_state
229 else if (val.const_type () == tree_constant_rep::scalar_constant) 318 && val.const_type () == tree_constant_rep::scalar_constant)
230 { 319 {
231 d = val.double_value (); 320 d = val.double_value ();
232 status = 0; 321 status = 0;
233 } 322 }
234 } 323 }
235 324
236 return status; 325 return status;
326 }
327
328 /*
329 * Make the definition of the symbol record sr be the same as the
330 * definition of the global variable of the same name, creating it if
331 * it doesn't already exist.
332 */
333 void
334 link_to_global_variable (symbol_record *sr)
335 {
336 if (sr->is_linked_to_global ())
337 return;
338
339 symbol_record *gsr = global_sym_tab->lookup (sr->name (), 1, 0);
340
341 if (sr->is_formal_parameter ())
342 {
343 error ("can't make function parameter `%s' global", sr->name ());
344 return;
345 }
346
347 // There must be a better way to do this. XXX FIXME XXX
348
349 if (sr->is_variable ())
350 {
351 // Would be nice not to have this cast. XXX FIXME XXX
352 tree_constant *tmp = (tree_constant *) sr->def ();
353 tmp = new tree_constant (*tmp);
354 gsr->define (tmp);
355 }
356 else
357 {
358 sr->clear ();
359 }
360
361 // If the global symbol is currently defined as a function, we need to
362 // hide it with a variable.
363
364 if (gsr->is_function ())
365 gsr->define (NULL_TREE_CONST);
366
367 sr->alias (gsr, 1);
368 sr->mark_as_linked_to_global ();
369 }
370
371 /*
372 * Make the definition of the symbol record sr be the same as the
373 * definition of the builtin variable of the same name.
374 */
375 void
376 link_to_builtin_variable (symbol_record *sr)
377 {
378 symbol_record *tmp_sym = global_sym_tab->lookup (sr->name (), 0, 0);
379
380 if (tmp_sym != (symbol_record *) NULL)
381 {
382 if (tmp_sym->is_builtin_variable ())
383 {
384 sr->alias (tmp_sym);
385 }
386 }
387 }
388
389 /*
390 * Make the definition of the symbol record sr be the same as the
391 * definition of the builtin variable or function, or user function of
392 * the same name, provided that the name has not been used as a formal
393 * parameter.
394 */
395 void
396 link_to_builtin_or_function (symbol_record *sr)
397 {
398 symbol_record *tmp_sym = global_sym_tab->lookup (sr->name (), 0, 0);
399
400 if (tmp_sym != (symbol_record *) NULL)
401 {
402 if ((tmp_sym->is_builtin_variable () || tmp_sym->is_function ())
403 && ! tmp_sym->is_formal_parameter ())
404 {
405 sr->alias (tmp_sym);
406 }
407 }
408 }
409
410 /*
411 * Force a link to a function in the current symbol table. This is
412 * used just after defining a function to avoid different behavior
413 * depending on whether or not the function has been evaluated after
414 * being defined.
415 *
416 * Return without doing anything if there isn't a function with the
417 * given name defined in the global symbol table.
418 */
419 void
420 force_link_to_function (const char *id_name)
421 {
422 symbol_record *gsr = global_sym_tab->lookup (id_name, 1, 0);
423 if (gsr->is_function ())
424 {
425 curr_sym_tab->clear (id_name);
426 symbol_record *csr = curr_sym_tab->lookup (id_name, 1, 0);
427 csr->alias (gsr);
428 }
429 }
430
431 /*
432 * Return 1 if the argument names a globally visible variable.
433 * Otherwise, return 0.
434 */
435 int
436 is_globally_visible (const char *name)
437 {
438 symbol_record *sr = curr_sym_tab->lookup (name, 0, 0);
439 return (sr != (symbol_record *) NULL && sr->is_linked_to_global ());
237 } 440 }
238 441
239 /* 442 /*
240 * Extract a keyword and its value from a file. Input should look 443 * Extract a keyword and its value from a file. Input should look
241 * something like: 444 * something like:
394 { 597 {
395 struct stat buf; 598 struct stat buf;
396 if (stat (name, &buf) == 0 && S_ISREG (buf.st_mode)) 599 if (stat (name, &buf) == 0 && S_ISREG (buf.st_mode))
397 return 2; 600 return 2;
398 } 601 }
399
400 } 602 }
401 return 0; 603 return 0;
604 }
605
606 /*
607 * Is this variable a builtin?
608 */
609 int
610 is_builtin_variable (const char *name)
611 {
612 symbol_record *sr = global_sym_tab->lookup (name, 0, 0);
613 return (sr != (symbol_record *) NULL && sr->is_builtin_variable ());
402 } 614 }
403 615
404 /* 616 /*
405 * Is this tree_constant a valid function? 617 * Is this tree_constant a valid function?
406 */ 618 */
459 e_nargs, s_plural (e_nargs)); 671 e_nargs, s_plural (e_nargs));
460 return 0; 672 return 0;
461 } 673 }
462 return 1; 674 return 1;
463 } 675 }
676
677 // It's not likely that this does the right thing now. XXX FIXME XXX
464 678
465 char ** 679 char **
466 make_name_list (void) 680 make_name_list (void)
467 { 681 {
468 int key_len = 0; 682 int key_len = 0;