1
|
1 // builtins.cc -*- C++ -*- |
|
2 /* |
|
3 |
|
4 Copyright (C) 1992, 1993 John W. Eaton |
|
5 |
|
6 This file is part of Octave. |
|
7 |
|
8 Octave is free software; you can redistribute it and/or modify it |
|
9 under the terms of the GNU General Public License as published by the |
|
10 Free Software Foundation; either version 2, or (at your option) any |
|
11 later version. |
|
12 |
|
13 Octave is distributed in the hope that it will be useful, but WITHOUT |
|
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
16 for more details. |
|
17 |
|
18 You should have received a copy of the GNU General Public License |
|
19 along with Octave; see the file COPYING. If not, write to the Free |
|
20 Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
|
21 |
|
22 */ |
|
23 |
|
24 #ifdef __GNUG__ |
|
25 #pragma implementation |
|
26 #endif |
|
27 |
|
28 #include <iostream.h> |
|
29 #include <math.h> |
|
30 #include <float.h> |
|
31 |
|
32 #include "tree-const.h" |
|
33 #include "symtab.h" |
|
34 #include "t-builtins.h" |
|
35 #include "g-builtins.h" |
|
36 #include "builtins.h" |
|
37 #include "octave.h" |
|
38 #include "utils.h" |
|
39 #include "tree.h" |
|
40 #include "mappers.h" |
|
41 #include "user-prefs.h" |
|
42 #include "variables.h" |
|
43 |
|
44 // NOTE: nargin == 1 means that the function takes no arguments (just |
|
45 // like C, the first argument is (or should be, anyway) the function |
|
46 // name). Also, -1 is shorthand for infinity. |
|
47 |
|
48 // The following initializations may eventually need to be reworked |
|
49 // like the builtin functions in bash were around version 1.12... |
|
50 |
|
51 static builtin_mapper_functions mapper_functions[] = |
|
52 { |
|
53 { "abs", 2, 1, 0, fabs, abs, NULL, |
|
54 "compute abs(X) for each element of X\n", }, |
|
55 |
|
56 { "acos", 2, 1, 0, acos, NULL, acos, |
|
57 "compute acos(X) for each element of X\n", }, |
|
58 |
|
59 { "acosh", 2, 1, 0, acosh, NULL, acosh, |
|
60 "compute acosh(X) for each element of X\n", }, |
|
61 |
|
62 { "angle", 2, 1, 0, arg, arg, NULL, |
|
63 "compute arg(X) for each element of X\n", }, |
|
64 |
|
65 { "arg", 2, 1, 0, arg, arg, NULL, |
|
66 "compute arg(X) for each element of X\n", }, |
|
67 |
|
68 { "asin", 2, 1, 0, asin, NULL, asin, |
|
69 "compute asin(X) for each element of X\n", }, |
|
70 |
|
71 { "asinh", 2, 1, 0, asinh, NULL, asinh, |
|
72 "compute asinh(X) for each element of X\n", }, |
|
73 |
|
74 { "atan", 2, 1, 0, atan, NULL, atan, |
|
75 "compute atan(X) for each element of X\n", }, |
|
76 |
|
77 { "atanh", 2, 1, 0, atanh, NULL, atanh, |
|
78 "compute atanh(X) for each element of X\n", }, |
|
79 |
|
80 { "ceil", 2, 1, 0, ceil, NULL, ceil, |
|
81 "ceil(X): round elements of X toward +Inf\n", }, |
|
82 |
|
83 { "conj", 2, 1, 0, conj, NULL, conj, |
|
84 "compute complex conjugate for each element of X\n", }, |
|
85 |
|
86 { "cos", 2, 1, 0, cos, NULL, cos, |
|
87 "compute cos(X) for each element of X\n", }, |
|
88 |
|
89 { "cosh", 2, 1, 0, cosh, NULL, cosh, |
|
90 "compute cosh(X) for each element of X\n", }, |
|
91 |
|
92 { "exp", 2, 1, 0, exp, NULL, exp, |
|
93 "compute exp(X) for each element of X\n", }, |
|
94 |
|
95 { "finite", 2, 1, 0, xfinite, xfinite, NULL, |
|
96 "finite(X): return 1 for finite elements of X\n", }, |
|
97 |
|
98 { "fix", 2, 1, 0, fix, NULL, fix, |
|
99 "fix(X): round elements of X toward zero\n", }, |
|
100 |
|
101 { "floor", 2, 1, 0, floor, NULL, floor, |
|
102 "floor(X): round elements of X toward -Inf\n", }, |
|
103 |
|
104 { "isinf", 2, 1, 0, xisinf, xisinf, NULL, |
|
105 "isinf(X): return 1 for elements of X infinite\n", }, |
|
106 |
|
107 { "imag", 2, 1, 0, imag, imag, NULL, |
|
108 "return imaginary part for each elements of X\n", }, |
|
109 |
|
110 #ifdef HAVE_ISNAN |
|
111 { "isnan", 2, 1, 0, xisnan, xisnan, NULL, |
|
112 "isnan(X): return 1 where elements of X are NaNs\n", }, |
|
113 #endif |
|
114 |
|
115 { "log", 2, 1, 1, log, NULL, log, |
|
116 "compute log(X) for each element of X\n", }, |
|
117 |
|
118 { "log10", 2, 1, 1, log10, NULL, log10, |
|
119 "compute log10(X) for each element of X\n", }, |
|
120 |
|
121 { "real", 2, 1, 0, real, real, NULL, |
|
122 "return real part for each element of X\n", }, |
|
123 |
|
124 { "round", 2, 1, 0, round, NULL, round, |
|
125 "round(X): round elements of X to nearest integer\n", }, |
|
126 |
|
127 { "sign", 2, 1, 0, signum, NULL, signum, |
|
128 "sign(X): apply signum function to elements of X\n", }, |
|
129 |
|
130 { "sin", 2, 1, 0, sin, NULL, sin, |
|
131 "compute sin(X) for each element of X\n", }, |
|
132 |
|
133 { "sinh", 2, 1, 0, sinh, NULL, sinh, |
|
134 "compute sinh(X) for each element of X\n", }, |
|
135 |
|
136 { "sqrt", 2, 1, 1, sqrt, NULL, sqrt, |
|
137 "compute sqrt(X) for each element of X\n", }, |
|
138 |
|
139 { "tan", 2, 1, 0, tan, NULL, tan, |
|
140 "compute tan(X) for each element of X\n", }, |
|
141 |
|
142 { "tanh", 2, 1, 0, tanh, NULL, tanh, |
|
143 "compute tanh(X) for each element of X\n", }, |
|
144 |
|
145 { NULL, -1, -1, -1, NULL, NULL, NULL, NULL, }, |
|
146 }; |
|
147 |
|
148 static builtin_text_functions text_functions[] = |
|
149 { |
|
150 { "casesen", 2, builtin_casesen, |
|
151 "print warning if user tries to change case sensitivity\n", }, |
|
152 |
|
153 { "cd", 2, builtin_cd, |
|
154 "change current working directory\n", }, |
|
155 |
|
156 { "clear", -1, builtin_clear, |
|
157 "clear symbol(s) from symbol table\n", }, |
|
158 |
|
159 { "dir", -1, builtin_ls, |
|
160 "print a directory listing\n", }, |
|
161 |
|
162 { "document", -1, builtin_document, |
|
163 "define help string for symbol\n", }, |
|
164 |
|
165 { "edit_history", -1, builtin_edit_history, |
|
166 "usage: edit_history [first] [last]\n", }, |
|
167 |
|
168 { "format", -1, builtin_format, |
|
169 "set output formatting style\n", }, |
|
170 |
|
171 { "help", -1, builtin_help, |
|
172 "print cryptic yet witty messages\n", }, |
|
173 |
|
174 { "history", -1, builtin_history, |
|
175 "print/save/load command history\n", }, |
|
176 |
|
177 { "load", -1, builtin_load, |
|
178 "load variables from a file\n", }, |
|
179 |
|
180 { "ls", -1, builtin_ls, |
|
181 "print a directory listing\n", }, |
|
182 |
|
183 { "save", -1, builtin_save, |
|
184 "save variables to a file\n", }, |
|
185 |
|
186 { "set", -1, builtin_set, |
|
187 "set plotting options\n", }, |
|
188 |
|
189 { "show", -1, builtin_show, |
|
190 "show plotting options\n", }, |
|
191 |
|
192 { "who", -1, builtin_who, |
|
193 "list symbols\n", }, |
|
194 |
|
195 { NULL, -1, NULL, NULL, }, |
|
196 }; |
|
197 |
|
198 static builtin_general_functions general_functions[] = |
|
199 { |
|
200 { "all", 2, 1, builtin_all, |
|
201 "all(X): are all elements of X nonzero?\n", }, |
|
202 |
|
203 { "any", 2, 1, builtin_any, |
|
204 "any(X): are any elements of X nonzero?\n", }, |
|
205 |
19
|
206 { "balance", 4, 4, builtin_balance, |
|
207 "balancing for algebraic and generalized eigenvalue prblems\n\ |
|
208 Usage: \n\ |
|
209 algebraic eigenvalues problem:\n\ |
|
210 aa = balance(a{,opt}) or [{dd,}aa] = balance(a{,opt})\n\ |
|
211 generalized eigenvalue problem:\n\ |
|
212 [cc, dd, aa, bb] = balance (a, b {,opt})\n\ |
|
213 where 'opt' is an optional single character argument as follows: \n\ |
|
214 'N' or 'n': no balancing; arguments copied, transformation(s) \n\ |
|
215 set to identity\n\ |
|
216 'P' or 'p': permute argument(s) to isolate eigenvalues where possible\n\ |
|
217 'S' or 's': scale to improve accuracy of computed eigenvalues\n\ |
|
218 'B' or 'b': (default) permute and scale, in that order. Rows/columns of a \n\ |
|
219 (and b) that are isolated by permutation are not scaled\n\ |
|
220 [dd, aa] = balance (a, opt) returns aa = dd\a*dd,\n\ |
|
221 [cc, dd, aa, bb] = balance (a, b, opt) returns aa (bb) = cc*a*dd (cc*b*dd)\n", }, |
|
222 |
1
|
223 { "clc", 1, 0, builtin_clc, |
|
224 "clear screen\n", }, |
|
225 |
|
226 { "clock", 1, 0, builtin_clock, |
|
227 "return current date and time in vector\n", }, |
|
228 |
|
229 { "closeplot", 1, 0, builtin_closeplot, |
|
230 "close the stream to plotter\n", }, |
|
231 |
|
232 { "colloc", 7, 4, builtin_colloc, |
|
233 "[r, A, B, q] = colloc (n [, 'left'] [, 'right']): collocation weights\n", }, |
|
234 |
|
235 { "cumprod", 2, 1, builtin_cumprod, |
|
236 "cumprod (X): cumulative products\n", }, |
|
237 |
|
238 { "cumsum", 2, 1, builtin_cumsum, |
|
239 "cumsum (X): cumulative sums\n", }, |
|
240 |
|
241 { "dassl", 5, 1, builtin_dassl, |
|
242 "solve DAEs using Petzold's DASSL. Usage:\n\ |
|
243 \n\ |
|
244 dassl ('function_name', x_0, xdot_0, t_out)\n\ |
|
245 dassl ('function_name', x_0, xdot_0, t_out, t_crit)\n\ |
|
246 \n\ |
|
247 The first argument is the name of the function to call to\n\ |
|
248 compute the vector of residuals. It must have the form\n\ |
|
249 \n\ |
|
250 res = f (x, xdot, t)\n\ |
|
251 \n\ |
|
252 where x, xdot, and res are vectors, and t is a scalar.\n\n", }, |
|
253 |
|
254 { "date", 1, 0, builtin_date, |
|
255 "return current date in a string\n", }, |
|
256 |
|
257 { "det", 2, 1, builtin_det, |
|
258 "det(X): determinant of a square matrix\n", }, |
|
259 |
|
260 { "diag", 3, 1, builtin_diag, |
|
261 "diag(X [,k]): form/extract diagonals\n", }, |
|
262 |
|
263 { "disp", 3, 1, builtin_disp, |
|
264 "disp(X): display value\n", }, |
|
265 |
|
266 { "eig", 2, 1, builtin_eig, |
|
267 "eig (x): compute eigenvalues and eigenvectors of x\n", }, |
|
268 |
|
269 { "error", 2, 1, builtin_error, |
|
270 "print message and jump to top level\n", }, |
|
271 |
|
272 { "eval", 2, 1, builtin_eval, |
|
273 "evaluate text as octave source\n", }, |
|
274 |
|
275 { "exist", 2, 1, builtin_exist, |
|
276 "check if variable or file exists\n", }, |
|
277 |
|
278 { "exit", 1, 0, builtin_quit, |
|
279 "exit Octave gracefully\n", }, |
|
280 |
|
281 { "expm", 2, 1, builtin_expm, |
|
282 "Matrix exponential, e^A\n", }, |
|
283 |
|
284 { "eye", 3, 1, builtin_eye, |
|
285 "create an identity matrix\n", }, |
|
286 |
|
287 { "fclose", 2, 1, builtin_fclose, |
|
288 "fclose('filename' or filenum): close a file\n", }, |
|
289 |
|
290 { "feval", -1, 1, builtin_feval, |
|
291 "evaluate argument as function\n", }, |
|
292 |
|
293 { "fflush", 2, 1, builtin_fflush, |
|
294 "fflush('filename' or filenum): flush buffered data to output file\n", }, |
|
295 |
|
296 { "fft", 2, 1, builtin_fft, |
|
297 "fft(X): fast fourier transform of a vector\n", }, |
|
298 |
|
299 { "fgets",3, 2, builtin_fgets, |
|
300 "[string, length] = fgets('filename' or filenum, length): read a string from a file\n", }, |
|
301 |
|
302 { "find", -1, 1, builtin_find, |
|
303 "find (x): return vector of indices of nonzero elements\n", }, |
|
304 |
|
305 { "flops", 2, 1, builtin_flops, |
|
306 "count floating point operations\n", }, |
|
307 |
|
308 { "fopen", 3, 1, builtin_fopen, |
|
309 "filenum = fopen('filename','mode'): open a file\n", }, |
|
310 |
|
311 { "fprintf", -1, 1, builtin_fprintf, |
|
312 "fprintf ('file', 'fmt', ...)\n", }, |
|
313 |
|
314 { "freport", 1, 1, builtin_freport, |
|
315 "freport: list open files and their status\n", }, |
|
316 |
|
317 { "frewind", 2, 1, builtin_frewind, |
|
318 "frewind('filename' or filenum): set file position at beginning of file\n", }, |
|
319 |
|
320 { "fscanf", 3, -1, builtin_fscanf, |
|
321 "[a,b,c...] = fscanf ('file', 'fmt')\n", }, |
|
322 |
|
323 { "fseek", 4, 1, builtin_fseek, |
|
324 "fseek('filename' or filenum): set file position for reading or writing\n", }, |
|
325 |
|
326 { "fsolve", 5, 1, builtin_fsolve, |
|
327 "Solve nonlinear equations using Minpack. Usage:\n\ |
|
328 \n\ |
|
329 [x, info] = fsolve ('f', x0)\n\ |
|
330 \n\ |
|
331 Where the first argument is the name of the function to call to\n\ |
|
332 compute the vector of function values. It must have the form\n\ |
|
333 \n\ |
|
334 y = f (x) |
|
335 \n\ |
|
336 where y and x are vectors.\n\n", }, |
|
337 |
|
338 { "fsqp", 11, 3, builtin_fsqp, |
|
339 "solve NLPs\n", }, |
|
340 |
|
341 { "ftell", 2, 1, builtin_ftell, |
|
342 "position = ftell ('filename' or filenum): returns the current file position\n", }, |
|
343 |
|
344 { "getenv", 2, 1, builtin_getenv, |
|
345 "get environment variable values\n", }, |
|
346 |
31
|
347 { "givens", 3, 2, builtin_givens, |
|
348 "Givens rotation:\n\ |
|
349 G = givens(x,y) returns an orthogonal matrix G = [c s; -conj(s) c] such\n\ |
|
350 that G[x;y] = [*;0] (x,y scalars)\n\ |
|
351 [c,s] = givens(x,y) returns the (c,s) values themselves.",}, |
|
352 |
|
353 |
1
|
354 { "hess", 2, 2, builtin_hess, |
31
|
355 "Hessenberg decomposition\n",}, |
1
|
356 |
|
357 { "home", 1, 0, builtin_clc, |
|
358 "clear screen\n", }, |
|
359 |
|
360 { "input", 3, 1, builtin_input, |
|
361 "input('prompt' [,'s']): prompt user for [string] input\n", }, |
|
362 |
|
363 { "ifft", 2, 1, builtin_ifft, |
|
364 "ifft(X): inverse fast fourier transform of a vector\n", }, |
|
365 |
|
366 { "inv", 2, 1, builtin_inv, |
|
367 "inv(X): inverse of a square matrix\n", }, |
|
368 |
|
369 { "inverse", 2, 1, builtin_inv, |
|
370 "inverse(X): inverse of a square matrix\n", }, |
|
371 |
|
372 { "isstr", 2, 1, builtin_isstr, |
|
373 "isstr(X): return 1 if X is a string\n", }, |
|
374 |
|
375 { "keyboard", 2, 1, builtin_keyboard, |
|
376 "maybe help in debugging M-files\n", }, |
|
377 |
|
378 { "logm", 2, 1, builtin_logm, |
|
379 "Matrix logarithm, log (A)\n", }, |
|
380 |
|
381 { "lpsolve", 11, 3, builtin_lpsolve, |
|
382 "Solve linear programs using lp_solve.\n", }, |
|
383 |
|
384 { "lsode", 6, 1, builtin_lsode, |
|
385 "solve ODEs using Hindmarsh's LSODE. Usage:\n\ |
|
386 \n\ |
|
387 lsode ('function_name', x0, t_out\n\ |
|
388 lsode ('function_name', x0, t_out, t_crit)\n\ |
|
389 \n\ |
|
390 The first argument is the name of the function to call to\n\ |
|
391 compute the vector of right hand sides. It must have the form\n\ |
|
392 \n\ |
|
393 xdot = f (x, t)\n\ |
|
394 \n\ |
|
395 where xdot and x are vectors and t is a scalar.\n\n", }, |
|
396 |
|
397 { "lu", 2, 3, builtin_lu, |
|
398 "[L, U, P] = lu (A) -- LU factorization\n", }, |
|
399 |
|
400 { "max", 3, 2, builtin_max, |
|
401 "maximum value(s) of a vector (matrix)\n", }, |
|
402 |
|
403 { "min", 3, 2, builtin_min, |
|
404 "minimum value(s) of a vector (matrix)\n", }, |
|
405 |
|
406 { "npsol", 11, 3, builtin_npsol, |
|
407 "Solve nonlinear programs using Gill and Murray's NPSOL. Usage:\n\ |
|
408 \n\ |
|
409 [x, obj, info, lambda] = npsol (x, 'phi' [, lb, ub] [, lb, A, ub] [, lb, 'g', ub])\n\n\ |
|
410 Groups of arguments surrounded in `[]' are optional, but\n\ |
|
411 must appear in the same relative order shown above.\n\ |
|
412 \n\ |
|
413 The second argument is a string containing the name of the objective\n\ |
|
414 function to call. The objective function must be of the form\n\ |
|
415 \n\ |
|
416 y = phi (x)\n\ |
|
417 \n\ |
|
418 where x is a vector and y is a scalar.\n\n", }, |
|
419 |
|
420 { "ones", 3, 1, builtin_ones, |
|
421 "create a matrix of all ones\n", }, |
|
422 |
|
423 { "pause", 1, 0, builtin_pause, |
|
424 "suspend program execution\n", }, |
|
425 |
|
426 { "purge_tmp_files", 5, 1, builtin_purge_tmp_files, |
|
427 "delete temporary data files used for plotting\n", }, |
|
428 |
|
429 { "printf", -1, 1, builtin_printf, |
|
430 "printf ('fmt', ...)\n", }, |
|
431 |
|
432 { "prod", 2, 1, builtin_prod, |
|
433 "prod (X): products\n", }, |
|
434 |
|
435 { "pwd", 1, 0, builtin_pwd, |
|
436 "print current working directory\n", }, |
|
437 |
|
438 { "qpsol", 9, 3, builtin_qpsol, |
|
439 "Solve nonlinear programs using Gill and Murray's QPSOL. Usage:\n\ |
|
440 \n\ |
|
441 [x, obj, info, lambda] = qpsol (x, H, c [, lb, ub] [, lb, A, ub])\n\ |
|
442 \n\ |
|
443 Groups of arguments surrounded in `[]' are optional, but\n\ |
|
444 must appear in the same relative order shown above.", }, |
|
445 |
|
446 { "qr", 2, 2, builtin_qr, |
|
447 "[q, r] = qr (X): form QR factorization of X\n", }, |
|
448 |
|
449 { "quad", 6, 3, builtin_quad, |
|
450 "Integrate a nonlinear function of one variable using Quadpack.\n\ |
|
451 Usage:\n\ |
|
452 \n\ |
|
453 [v, ier, nfun] = quad ('f', a, b [, tol] [, sing])\n\ |
|
454 \n\ |
|
455 Where the first argument is the name of the function to call to\n\ |
|
456 compute the value of the integrand. It must have the form\n\ |
|
457 \n\ |
|
458 y = f (x) |
|
459 \n\ |
|
460 where y and x are scalars.\n\ |
|
461 \n\ |
|
462 The second and third arguments are limits of integration. Either or\n\ |
|
463 both may be infinite. The optional argument tol specifies the desired\n\ |
|
464 accuracy of the result. The optional argument sing is a vector of\n\ |
|
465 at which the integrand is singular.\n\n", }, |
|
466 |
|
467 { "quit", 1, 0, builtin_quit, |
|
468 "exit Octave gracefully\n", }, |
|
469 |
|
470 { "rand", 2, 1, builtin_rand, |
|
471 "matrices with random elements\n", }, |
|
472 |
|
473 { "replot", 1, 0, builtin_replot, |
|
474 "redisplay current plot\n", }, |
|
475 |
|
476 { "scanf", 2, -1, builtin_scanf, |
|
477 "[a,b,c...] = scanf ('fmt')\n", }, |
|
478 |
|
479 { "setstr", 2, 1, builtin_setstr, |
|
480 "setstr (v): convert a vector to a string\n", }, |
|
481 |
|
482 { "shell_cmd", 2, 1, builtin_shell_command, |
|
483 "shell_cmd (string [, return_output]): execute shell commands\n", }, |
|
484 |
|
485 { "schur", 3, 2, builtin_schur, |
|
486 "returns the Schur (straight or ordered) decomposition of matrix\n", }, |
|
487 |
|
488 { "size", 2, 1, builtin_size, |
|
489 "size(X): return rows and columns of X\n", }, |
|
490 |
|
491 { "sort", 2, 2, builtin_sort, |
|
492 "[s,i] = sort(x): sort the columns of x, optionally return sort index\n", }, |
|
493 |
|
494 { "sqrtm", 2, 1, builtin_sqrtm, |
|
495 "Matrix sqrt, sqrt (A)\n", }, |
|
496 |
|
497 { "sprintf", -1, 1, builtin_sprintf, |
|
498 "s = sprintf ('fmt', ...)\n", }, |
|
499 |
|
500 { "sscanf", 3, -1, builtin_sscanf, |
|
501 "[a,b,c...] = sscanf (string, 'fmt')\n", }, |
|
502 |
|
503 { "sum", 2, 1, builtin_sum, |
|
504 "sum (X): sum of elements\n", }, |
|
505 |
|
506 { "sumsq", 2, 1, builtin_sumsq, |
|
507 "sumsq (X): sum of squares of elements\n", }, |
|
508 |
|
509 { "svd", 2, 3, builtin_svd, |
|
510 "[U,S,V] = svd(X): return SVD of X\n", }, |
|
511 |
|
512 { "warranty", 1, 0, builtin_warranty, |
|
513 "describe copying conditions\n", }, |
|
514 |
|
515 { "zeros", 3, 1, builtin_zeros, |
|
516 "create a matrix of all zeros\n", }, |
|
517 |
|
518 { NULL, -1, -1, NULL, NULL, }, |
|
519 }; |
|
520 |
|
521 // This is a lie. Some of these get reassigned to be numeric |
|
522 // variables. See below. |
|
523 |
|
524 static builtin_string_variables string_variables[] = |
|
525 { |
|
526 { "I", "??", NULL, |
|
527 "sqrt (-1)\n", }, |
|
528 |
|
529 { "Inf", "??", NULL, |
|
530 "infinity\n", }, |
|
531 |
|
532 { "J", "??", NULL, |
|
533 "sqrt (-1)\n", }, |
|
534 |
|
535 #if defined (HAVE_ISNAN) |
|
536 { "NaN", "??", NULL, |
|
537 "not a number\n", }, |
|
538 #endif |
|
539 |
|
540 { "LOADPATH", "??", sv_loadpath, |
|
541 "colon separated list of directories to search for scripts\n", }, |
|
542 |
|
543 { "PAGER", "??", sv_pager_binary, |
|
544 "path to pager binary\n", }, |
|
545 |
|
546 { "PS1", "\\s:\\#> ", sv_ps1, |
|
547 "primary prompt string\n", }, |
|
548 |
|
549 { "PS2", "> ", sv_ps2, |
|
550 "secondary prompt string\n", }, |
|
551 |
|
552 { "PWD", "??PWD??", sv_pwd, |
|
553 "current working directory\n", }, |
|
554 |
|
555 { "SEEK_SET", "??", NULL, |
|
556 "used with fseek to position file relative to the beginning\n", }, |
|
557 |
|
558 { "SEEK_CUR", "??", NULL, |
|
559 "used with fseek to position file relative to the current position\n", }, |
|
560 |
|
561 { "SEEK_END", "??", NULL, |
|
562 "used with fseek to position file relative to the end\n", }, |
|
563 |
|
564 { "do_fortran_indexing", "false", do_fortran_indexing, |
|
565 "allow single indices for matrices\n", }, |
|
566 |
|
567 { "empty_list_elements_ok", "warn", empty_list_elements_ok, |
|
568 "ignore the empty element in expressions like `a = [[], 1]'\n", }, |
|
569 |
|
570 { "eps", "??", NULL, |
|
571 "machine precision\n", }, |
|
572 |
|
573 { "gnuplot_binary", "gnuplot", sv_gnuplot_binary, |
|
574 "path to gnuplot binary\n", }, |
|
575 |
|
576 { "i", "??", NULL, |
|
577 "sqrt (-1)\n", }, |
|
578 |
|
579 { "implicit_str_to_num_ok", "false", implicit_str_to_num_ok, |
|
580 "allow implicit string to number conversion\n", }, |
|
581 |
|
582 { "inf", "??", NULL, |
|
583 "infinity\n", }, |
|
584 |
|
585 { "j", "??", NULL, |
|
586 "sqrt (-1)\n", }, |
|
587 |
|
588 #if defined (HAVE_ISNAN) |
|
589 { "nan", "??", NULL, |
|
590 "not a number\n", }, |
|
591 #endif |
|
592 |
|
593 { "ok_to_lose_imaginary_part", "warn", ok_to_lose_imaginary_part, |
|
594 "silently convert from complex to real by dropping imaginary part\n", }, |
|
595 |
|
596 { "output_max_field_width", "??", set_output_max_field_width, |
|
597 "maximum width of an output field for numeric output\n", }, |
|
598 |
|
599 { "output_precision", "??", set_output_precision, |
|
600 "number of significant figures to display for numeric output\n", }, |
|
601 |
|
602 { "page_screen_output", "true", page_screen_output, |
|
603 "if possible, send output intended for the screen through the pager\n", }, |
|
604 |
|
605 { "pi", "??", NULL, |
|
606 "ratio of the circumference of a circle to its diameter\n", }, |
|
607 |
|
608 { "prefer_column_vectors", "true", prefer_column_vectors, |
|
609 "prefer column/row vectors\n", }, |
|
610 |
|
611 { "prefer_zero_one_indexing", "false", prefer_zero_one_indexing, |
|
612 "when there is a conflict, prefer zero-one style indexing\n", }, |
|
613 |
|
614 { "print_answer_id_name", "true", print_answer_id_name, |
|
615 "set output style to print `var_name = ...'\n", }, |
|
616 |
|
617 { "print_empty_dimensions", "true", print_empty_dimensions, |
|
618 "also print dimensions of empty matrices\n", }, |
|
619 |
|
620 { "propagate_empty_matrices", "true", propagate_empty_matrices, |
|
621 "operations on empty matrices return an empty matrix, not an error\n", }, |
|
622 |
|
623 { "resize_on_range_error", "true", resize_on_range_error, |
|
624 "enlarge matrices on assignment\n", }, |
|
625 |
|
626 { "return_last_computed_value", "false", return_last_computed_value, |
|
627 "if a function does not return any values explicitly, return the\n\ |
|
628 last computed value\n", }, |
|
629 |
|
630 { "silent_functions", "false", silent_functions, |
|
631 "suppress printing results in called functions\n", }, |
|
632 |
|
633 { "split_long_rows", "true", split_long_rows, |
|
634 "split long matrix rows instead of wrapping\n", }, |
|
635 |
|
636 { "stdin", "??", NULL, |
|
637 "file number of the standard input stream\n", }, |
|
638 |
|
639 { "stdout", "??", NULL, |
|
640 "file number of the standard output stream\n", }, |
|
641 |
|
642 { "stderr", "??", NULL, |
|
643 "file number of the standard error stream\n", }, |
|
644 |
|
645 { "treat_neg_dim_as_zero", "false", treat_neg_dim_as_zero, |
|
646 "convert negative dimensions to zero\n", }, |
|
647 |
|
648 { "warn_assign_as_truth_value", "true", warn_assign_as_truth_value, |
|
649 "produce warning for assignments used as truth values\n", }, |
|
650 |
|
651 { "warn_comma_in_global_decl", "true", warn_comma_in_global_decl, |
|
652 "produce warning for commas in global declarations\n", }, |
|
653 |
|
654 { "warn_divide_by_zero", "true", warn_divide_by_zero, |
|
655 "on IEEE machines, allow divide by zero errors to be suppressed\n", }, |
|
656 |
|
657 { NULL, NULL, NULL, NULL, }, |
|
658 }; |
|
659 |
|
660 void |
|
661 make_eternal (char *s) |
|
662 { |
|
663 symbol_record *sym_rec = curr_sym_tab->lookup (s, 0, 0); |
|
664 if (sym_rec != (symbol_record *) NULL) |
|
665 sym_rec->make_eternal (); |
|
666 } |
|
667 |
|
668 void |
|
669 install_builtins (void) |
|
670 { |
|
671 symbol_record *sym_rec; |
|
672 |
|
673 tree_builtin *tb_tmp; |
|
674 |
|
675 // So that the clear function can't delete other builtin variables and |
|
676 // functions, they are given eternal life. |
|
677 |
|
678 builtin_mapper_functions *mfptr = mapper_functions; |
|
679 while (mfptr->name != (char *) NULL) |
|
680 { |
|
681 sym_rec = curr_sym_tab->lookup (mfptr->name, 1); |
|
682 sym_rec->unprotect (); |
|
683 |
|
684 Mapper_fcn mfcn; |
|
685 mfcn.neg_arg_complex = mfptr->neg_arg_complex; |
|
686 mfcn.d_d_mapper = mfptr->d_d_mapper; |
|
687 mfcn.d_c_mapper = mfptr->d_c_mapper; |
|
688 mfcn.c_c_mapper = mfptr->c_c_mapper; |
|
689 |
|
690 tb_tmp = new tree_builtin (mfptr->nargin_max, mfptr->nargout_max, |
|
691 mfcn, sym_rec); |
|
692 |
|
693 sym_rec->define (tb_tmp); |
|
694 sym_rec->document (mfptr->help_string); |
|
695 sym_rec->make_eternal (); |
|
696 sym_rec->protect (); |
|
697 mfptr++; |
|
698 } |
|
699 |
|
700 builtin_text_functions *tfptr = text_functions; |
|
701 while (tfptr->name != (char *) NULL) |
|
702 { |
|
703 sym_rec = curr_sym_tab->lookup (tfptr->name, 1); |
|
704 sym_rec->unprotect (); |
|
705 |
|
706 tb_tmp = new tree_builtin (tfptr->nargin_max, 1, |
|
707 tfptr->text_fcn, sym_rec); |
|
708 |
|
709 sym_rec->define (tb_tmp); |
|
710 sym_rec->document (tfptr->help_string); |
|
711 sym_rec->make_eternal (); |
|
712 sym_rec->protect (); |
|
713 tfptr++; |
|
714 } |
|
715 |
|
716 builtin_general_functions *gfptr = general_functions; |
|
717 while (gfptr->name != (char *) NULL) |
|
718 { |
|
719 sym_rec = curr_sym_tab->lookup (gfptr->name, 1); |
|
720 sym_rec->unprotect (); |
|
721 |
|
722 tb_tmp = new tree_builtin (gfptr->nargin_max, gfptr->nargout_max, |
|
723 gfptr->general_fcn, sym_rec); |
|
724 |
|
725 sym_rec->define (tb_tmp); |
|
726 sym_rec->document (gfptr->help_string); |
|
727 sym_rec->make_eternal (); |
|
728 sym_rec->protect (); |
|
729 gfptr++; |
|
730 } |
|
731 |
|
732 // Most built-in variables are not protected because the user should |
|
733 // be able to redefine them. |
|
734 |
|
735 builtin_string_variables *svptr = string_variables; |
|
736 while (svptr->name != (char *) NULL) |
|
737 { |
|
738 sym_rec = curr_sym_tab->lookup (svptr->name, 1); |
|
739 sym_rec->unprotect (); |
|
740 |
|
741 tree_constant *tmp = new tree_constant (svptr->value); |
|
742 |
|
743 sym_rec->set_sv_function (svptr->sv_function); |
|
744 sym_rec->define (tmp); |
|
745 sym_rec->document (svptr->help_string); |
|
746 sym_rec->make_eternal (); |
|
747 svptr++; |
|
748 } |
|
749 |
|
750 // XXX FIXME XXX -- Need a convenient way to document these variables. |
|
751 |
|
752 // IMPORTANT: Always create a new tree_constant for each variable. |
|
753 |
|
754 tree_constant *tmp = NULL_TREE_CONST; |
|
755 bind_variable ("ans", tmp); |
|
756 |
|
757 Complex ctmp (0.0, 1.0); |
|
758 tmp = new tree_constant (ctmp); |
|
759 bind_protected_variable ("I", tmp); |
|
760 make_eternal ("I"); |
|
761 |
|
762 tmp = new tree_constant (ctmp); |
|
763 bind_protected_variable ("J", tmp); |
|
764 make_eternal ("J"); |
|
765 |
|
766 // Let i and j be functions so they can be redefined without being |
|
767 // wiped out. |
|
768 |
|
769 char *tmp_help; |
|
770 |
|
771 tmp = new tree_constant (ctmp); |
|
772 sym_rec = curr_sym_tab->lookup ("i", 1); |
|
773 tmp_help = sym_rec->help (); |
|
774 sym_rec->define_as_fcn (tmp); |
|
775 sym_rec->document (tmp_help); |
|
776 sym_rec->protect (); |
|
777 sym_rec->make_eternal (); |
|
778 |
|
779 tmp = new tree_constant (ctmp); |
|
780 sym_rec = curr_sym_tab->lookup ("j", 1); |
|
781 tmp_help = sym_rec->help (); |
|
782 sym_rec->define_as_fcn (tmp); |
|
783 sym_rec->document (tmp_help); |
|
784 sym_rec->protect (); |
|
785 sym_rec->make_eternal (); |
|
786 |
|
787 tmp = new tree_constant (get_working_directory ("initialize_globals")); |
|
788 bind_protected_variable ("PWD", tmp); |
|
789 make_eternal ("PWD"); |
|
790 |
|
791 tmp = new tree_constant (load_path); |
|
792 bind_variable ("LOADPATH", tmp); |
|
793 make_eternal ("LOADPATH"); |
|
794 |
|
795 tmp = new tree_constant (default_pager ()); |
|
796 bind_variable ("PAGER", tmp); |
|
797 make_eternal ("PAGER"); |
|
798 |
|
799 tmp = new tree_constant (0.0); |
|
800 bind_variable ("SEEK_SET", tmp); |
|
801 make_eternal ("SEEK_SET"); |
|
802 |
|
803 tmp = new tree_constant (1.0); |
|
804 bind_variable ("SEEK_CUR", tmp); |
|
805 make_eternal ("SEEK_CUR"); |
|
806 |
|
807 tmp = new tree_constant (2.0); |
|
808 bind_variable ("SEEK_END", tmp); |
|
809 make_eternal ("SEEK_END"); |
|
810 |
|
811 tmp = new tree_constant (DBL_EPSILON); |
|
812 bind_protected_variable ("eps", tmp); |
|
813 make_eternal ("eps"); |
|
814 |
|
815 tmp = new tree_constant (10.0); |
|
816 bind_variable ("output_max_field_width", tmp); |
|
817 make_eternal ("output_max_field_width"); |
|
818 |
|
819 tmp = new tree_constant (5.0); |
|
820 bind_variable ("output_precision", tmp); |
|
821 make_eternal ("output_precision"); |
|
822 |
|
823 tmp = new tree_constant (4.0 * atan (1.0)); |
|
824 bind_protected_variable ("pi", tmp); |
|
825 make_eternal ("pi"); |
|
826 |
|
827 tmp = new tree_constant (0.0); |
|
828 bind_protected_variable ("stdin", tmp); |
|
829 make_eternal ("stdin"); |
|
830 |
|
831 tmp = new tree_constant (1.0); |
|
832 bind_protected_variable ("stdout", tmp); |
|
833 make_eternal ("stdout"); |
|
834 |
|
835 tmp = new tree_constant (2.0); |
|
836 bind_protected_variable ("stderr", tmp); |
|
837 make_eternal ("stderr"); |
|
838 |
|
839 #if defined (HAVE_ISINF) || defined (HAVE_FINITE) |
|
840 #ifdef linux |
|
841 tmp = new tree_constant (HUGE_VAL); |
|
842 #else |
|
843 tmp = new tree_constant (1.0/0.0); |
|
844 #endif |
|
845 bind_protected_variable ("Inf", tmp); |
|
846 make_eternal ("Inf"); |
|
847 |
|
848 #ifdef linux |
|
849 tmp = new tree_constant (HUGE_VAL); |
|
850 #else |
|
851 tmp = new tree_constant (1.0/0.0); |
|
852 #endif |
|
853 bind_protected_variable ("inf", tmp); |
|
854 make_eternal ("inf"); |
|
855 |
|
856 #else |
|
857 |
|
858 // This is sort of cheesy, but what can we do, other than blowing it |
|
859 // off completely, or writing an entire IEEE emulation package? |
|
860 |
|
861 tmp = new tree_constant (DBL_MAX); |
|
862 bind_protected_variable ("Inf", tmp); |
|
863 make_eternal ("Inf"); |
|
864 |
|
865 tmp = new tree_constant (DBL_MAX); |
|
866 bind_protected_variable ("inf", tmp); |
|
867 make_eternal ("inf"); |
|
868 #endif |
|
869 |
|
870 #if defined (HAVE_ISNAN) |
|
871 #ifdef linux |
|
872 tmp = new tree_constant (NAN); |
|
873 #else |
|
874 tmp = new tree_constant (0.0/0.0); |
|
875 #endif |
|
876 bind_protected_variable ("NaN", tmp); |
|
877 make_eternal ("NaN"); |
|
878 |
|
879 #ifdef linux |
|
880 tmp = new tree_constant (NAN); |
|
881 #else |
|
882 tmp = new tree_constant (0.0/0.0); |
|
883 #endif |
|
884 bind_protected_variable ("nan", tmp); |
|
885 make_eternal ("nan"); |
|
886 #endif |
|
887 } |
|
888 |
|
889 int |
|
890 is_text_function_name (char *s) |
|
891 { |
|
892 int retval = 0; |
|
893 |
|
894 builtin_text_functions *tfptr = text_functions; |
|
895 while (tfptr->name != (char *) NULL) |
|
896 { |
|
897 if (strcmp (tfptr->name, s) == 0) |
|
898 { |
|
899 retval = 1; |
|
900 break; |
|
901 } |
|
902 tfptr++; |
|
903 } |
|
904 |
|
905 return retval; |
|
906 } |
|
907 |
|
908 help_list * |
|
909 builtin_mapper_functions_help (void) |
|
910 { |
|
911 int count = 0; |
|
912 builtin_mapper_functions *mfptr; |
|
913 |
|
914 mfptr = mapper_functions; |
|
915 while (mfptr->name != (char *) NULL) |
|
916 { |
|
917 count++; |
|
918 mfptr++; |
|
919 } |
|
920 |
|
921 if (count == 0) |
|
922 return (help_list *) NULL; |
|
923 |
|
924 help_list *hl = new help_list [count+1]; |
|
925 |
|
926 int i = 0; |
|
927 mfptr = mapper_functions; |
|
928 while (mfptr->name != (char *) NULL) |
|
929 { |
|
930 hl[i].name = mfptr->name; |
|
931 hl[i].help = mfptr->help_string; |
|
932 i++; |
|
933 mfptr++; |
|
934 } |
|
935 |
|
936 hl[count].name = (char *) NULL; |
|
937 hl[count].help = (char *) NULL; |
|
938 |
|
939 return hl; |
|
940 } |
|
941 |
|
942 help_list * |
|
943 builtin_general_functions_help (void) |
|
944 { |
|
945 int count = 0; |
|
946 builtin_general_functions *gfptr; |
|
947 |
|
948 gfptr = general_functions; |
|
949 while (gfptr->name != (char *) NULL) |
|
950 { |
|
951 count++; |
|
952 gfptr++; |
|
953 } |
|
954 |
|
955 if (count == 0) |
|
956 return (help_list *) NULL; |
|
957 |
|
958 help_list *hl = new help_list [count+1]; |
|
959 |
|
960 int i = 0; |
|
961 gfptr = general_functions; |
|
962 while (gfptr->name != (char *) NULL) |
|
963 { |
|
964 hl[i].name = gfptr->name; |
|
965 hl[i].help = gfptr->help_string; |
|
966 i++; |
|
967 gfptr++; |
|
968 } |
|
969 |
|
970 hl[count].name = (char *) NULL; |
|
971 hl[count].help = (char *) NULL; |
|
972 |
|
973 return hl; |
|
974 } |
|
975 |
|
976 help_list * |
|
977 builtin_text_functions_help (void) |
|
978 { |
|
979 int count = 0; |
|
980 builtin_text_functions *tfptr; |
|
981 |
|
982 tfptr = text_functions; |
|
983 while (tfptr->name != (char *) NULL) |
|
984 { |
|
985 count++; |
|
986 tfptr++; |
|
987 } |
|
988 |
|
989 if (count == 0) |
|
990 return (help_list *) NULL; |
|
991 |
|
992 help_list *hl = new help_list [count+1]; |
|
993 |
|
994 int i = 0; |
|
995 tfptr = text_functions; |
|
996 while (tfptr->name != (char *) NULL) |
|
997 { |
|
998 hl[i].name = tfptr->name; |
|
999 hl[i].help = tfptr->help_string; |
|
1000 i++; |
|
1001 tfptr++; |
|
1002 } |
|
1003 |
|
1004 hl[count].name = (char *) NULL; |
|
1005 hl[count].help = (char *) NULL; |
|
1006 |
|
1007 return hl; |
|
1008 } |
|
1009 |
|
1010 help_list * |
|
1011 builtin_variables_help (void) |
|
1012 { |
|
1013 int count = 0; |
|
1014 builtin_string_variables *svptr; |
|
1015 |
|
1016 svptr = string_variables; |
|
1017 while (svptr->name != (char *) NULL) |
|
1018 { |
|
1019 count++; |
|
1020 svptr++; |
|
1021 } |
|
1022 |
|
1023 if (count == 0) |
|
1024 return (help_list *) NULL; |
|
1025 |
|
1026 help_list *hl = new help_list [count+1]; |
|
1027 |
|
1028 int i = 0; |
|
1029 svptr = string_variables; |
|
1030 while (svptr->name != (char *) NULL) |
|
1031 { |
|
1032 hl[i].name = svptr->name; |
|
1033 hl[i].help = svptr->help_string; |
|
1034 i++; |
|
1035 svptr++; |
|
1036 } |
|
1037 |
|
1038 hl[count].name = (char *) NULL; |
|
1039 hl[count].help = (char *) NULL; |
|
1040 |
|
1041 return hl; |
|
1042 } |
|
1043 |
|
1044 /* |
|
1045 ;;; Local Variables: *** |
|
1046 ;;; mode: C++ *** |
|
1047 ;;; page-delimiter: "^/\\*" *** |
|
1048 ;;; End: *** |
|
1049 */ |