Mercurial > hg > octave-jordi
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; |