]> www.ginac.de Git - ginac.git/blob - ginsh/ginsh_parser.cc
- removed strdup() replacement from ginsh
[ginac.git] / ginsh / ginsh_parser.cc
1
2 /*  A Bison parser, made from ginsh_parser.yy
3  by  GNU Bison version 1.25
4   */
5
6 #define YYBISON 1  /* Identify Bison output.  */
7
8 #define T_NUMBER        258
9 #define T_SYMBOL        259
10 #define T_LITERAL       260
11 #define T_DIGITS        261
12 #define T_QUOTE 262
13 #define T_QUOTE2        263
14 #define T_QUOTE3        264
15 #define T_EQUAL 265
16 #define T_NOTEQ 266
17 #define T_LESSEQ        267
18 #define T_GREATEREQ     268
19 #define T_MATRIX_BEGIN  269
20 #define T_MATRIX_END    270
21 #define T_QUIT  271
22 #define T_PRINT 272
23 #define T_TIME  273
24 #define T_XYZZY 274
25 #define T_INVENTORY     275
26 #define T_LOOK  276
27 #define T_SCORE 277
28 #define NEG     278
29
30 #line 28 "ginsh_parser.yy"
31
32 #include "config.h"
33
34 #include <sys/resource.h>
35
36 #if HAVE_UNISTD_H
37 #include <sys/types.h>
38 #include <unistd.h>
39 #endif
40
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44
45 extern "C" {
46 #include <readline/readline.h>
47 #include <readline/history.h>
48 }
49
50 #include <map>
51 #include <string>
52 #include <stdexcept>
53
54 #include <ginac/ginac.h>
55 #include "ginsh.h"
56
57 // Original readline settings
58 static int orig_completion_append_character;
59 static char *orig_basic_word_break_characters;
60
61 // Expression stack for ", "" and """
62 static void push(const ex &e);
63 static ex exstack[3];
64
65 // Start and end time for the time() function
66 static struct rusage start_time, end_time;
67
68 // Table of functions (a multimap, because one function may appear with different
69 // numbers of parameters)
70 typedef ex (*fcnp)(const exprseq &e);
71 typedef ex (*fcnp2)(const exprseq &e, int serial);
72
73 struct fcn_desc {
74         fcn_desc() : p(NULL), num_params(0) {}
75         fcn_desc(fcnp func, int num) : p(func), num_params(num), is_ginac(false) {}
76         fcn_desc(fcnp2 func, int num, int ser) : p((fcnp)func), num_params(num), is_ginac(true), serial(ser) {}
77
78         fcnp p;         // Pointer to function
79         int num_params; // Number of parameters (0 = arbitrary)
80         bool is_ginac;  // Flag: function is GiNaC function
81         int serial;     // GiNaC function serial number (if is_ginac == true)
82 };
83
84 typedef multimap<string, fcn_desc> fcn_tab;
85 static fcn_tab fcns;
86
87 static fcn_tab::const_iterator find_function(const ex &sym, int req_params);
88
89 static ex lst2matrix(const ex &l);
90 #ifndef YYSTYPE
91 #define YYSTYPE int
92 #endif
93 #include <stdio.h>
94
95 #ifndef __cplusplus
96 #ifndef __STDC__
97 #define const
98 #endif
99 #endif
100
101
102
103 #define YYFINAL         96
104 #define YYFLAG          -32768
105 #define YYNTBASE        41
106
107 #define YYTRANSLATE(x) ((unsigned)(x) <= 278 ? yytranslate[x] : 50)
108
109 static const char yytranslate[] = {     0,
110      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
111      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
112      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
113      2,     2,    33,     2,     2,     2,    30,     2,    37,    35,
114     36,    28,    26,    40,    27,     2,    29,     2,     2,     2,
115      2,     2,     2,     2,     2,     2,     2,     2,    34,    24,
116     23,    25,     2,     2,     2,     2,     2,     2,     2,     2,
117      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
118      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
119     38,     2,    39,    32,     2,     2,     2,     2,     2,     2,
120      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
121      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
122      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
123      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
124      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
125      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
126      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
127      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
128      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
129      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
130      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
131      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
132      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
133      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
134      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
135      2,     2,     2,     2,     2,     1,     2,     3,     4,     5,
136      6,     7,     8,     9,    10,    11,    12,    13,    14,    15,
137     16,    17,    18,    19,    20,    21,    22,    31
138 };
139
140 #if YYDEBUG != 0
141 static const short yyprhs[] = {     0,
142      0,     1,     4,     6,     9,    15,    17,    19,    21,    23,
143     25,    28,    30,    32,    36,    38,    40,    42,    44,    46,
144     47,    53,    58,    62,    66,    70,    74,    78,    82,    86,
145     90,    94,    98,   102,   106,   110,   113,   116,   120,   123,
146    127,   131,   135,   137,   141,   142,   144,   146,   150,   154,
147    160,   162
148 };
149
150 static const short yyrhs[] = {    -1,
151     41,    42,     0,    34,     0,    43,    34,     0,    17,    35,
152     43,    36,    34,     0,    16,     0,    19,     0,    20,     0,
153     21,     0,    22,     0,     1,    34,     0,     3,     0,     4,
154      0,    37,     4,    37,     0,     5,     0,     6,     0,     7,
155      0,     8,     0,     9,     0,     0,    18,    44,    35,    43,
156     36,     0,     4,    35,    45,    36,     0,     6,    23,     3,
157      0,     4,    23,    43,     0,    43,    10,    43,     0,    43,
158     11,    43,     0,    43,    24,    43,     0,    43,    12,    43,
159      0,    43,    25,    43,     0,    43,    13,    43,     0,    43,
160     26,    43,     0,    43,    27,    43,     0,    43,    28,    43,
161      0,    43,    29,    43,     0,    43,    30,    43,     0,    27,
162     43,     0,    26,    43,     0,    43,    32,    43,     0,    43,
163     33,     0,    35,    43,    36,     0,    38,    46,    39,     0,
164     14,    48,    15,     0,    43,     0,    45,    40,    43,     0,
165      0,    47,     0,    43,     0,    47,    40,    43,     0,    14,
166     49,    15,     0,    48,    40,    14,    49,    15,     0,    43,
167      0,    49,    40,    43,     0
168 };
169
170 #endif
171
172 #if YYDEBUG != 0
173 static const short yyrline[] = { 0,
174    114,   115,   118,   119,   129,   138,   139,   140,   141,   142,
175    148,   151,   152,   153,   154,   155,   156,   157,   158,   159,
176    159,   167,   176,   178,   180,   181,   182,   183,   184,   185,
177    186,   187,   188,   189,   190,   191,   192,   193,   194,   195,
178    196,   197,   200,   201,   204,   205,   208,   209,   212,   213,
179    216,   217
180 };
181 #endif
182
183
184 #if YYDEBUG != 0 || defined (YYERROR_VERBOSE)
185
186 static const char * const yytname[] = {   "$","error","$undefined.","T_NUMBER",
187 "T_SYMBOL","T_LITERAL","T_DIGITS","T_QUOTE","T_QUOTE2","T_QUOTE3","T_EQUAL",
188 "T_NOTEQ","T_LESSEQ","T_GREATEREQ","T_MATRIX_BEGIN","T_MATRIX_END","T_QUIT",
189 "T_PRINT","T_TIME","T_XYZZY","T_INVENTORY","T_LOOK","T_SCORE","'='","'<'","'>'",
190 "'+'","'-'","'*'","'/'","'%'","NEG","'^'","'!'","';'","'('","')'","'''","'['",
191 "']'","','","input","line","exp","@1","exprseq","list_or_empty","list","matrix",
192 "row", NULL
193 };
194 #endif
195
196 static const short yyr1[] = {     0,
197     41,    41,    42,    42,    42,    42,    42,    42,    42,    42,
198     42,    43,    43,    43,    43,    43,    43,    43,    43,    44,
199     43,    43,    43,    43,    43,    43,    43,    43,    43,    43,
200     43,    43,    43,    43,    43,    43,    43,    43,    43,    43,
201     43,    43,    45,    45,    46,    46,    47,    47,    48,    48,
202     49,    49
203 };
204
205 static const short yyr2[] = {     0,
206      0,     2,     1,     2,     5,     1,     1,     1,     1,     1,
207      2,     1,     1,     3,     1,     1,     1,     1,     1,     0,
208      5,     4,     3,     3,     3,     3,     3,     3,     3,     3,
209      3,     3,     3,     3,     3,     2,     2,     3,     2,     3,
210      3,     3,     1,     3,     0,     1,     1,     3,     3,     5,
211      1,     3
212 };
213
214 static const short yydefact[] = {     1,
215      0,     0,    12,    13,    15,    16,    17,    18,    19,     0,
216      6,     0,    20,     7,     8,     9,    10,     0,     0,     3,
217      0,     0,    45,     2,     0,    11,     0,     0,     0,     0,
218      0,     0,     0,    37,    36,     0,     0,    47,     0,    46,
219      0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
220      0,     0,    39,     4,    24,    43,     0,    23,    51,     0,
221     42,     0,     0,     0,    40,    14,    41,     0,    25,    26,
222     28,    30,    27,    29,    31,    32,    33,    34,    35,    38,
223     22,     0,    49,     0,     0,     0,     0,    48,    44,    52,
224      0,     5,    21,    50,     0,     0
225 };
226
227 static const short yydefgoto[] = {     1,
228     24,    59,    33,    57,    39,    40,    31,    60
229 };
230
231 static const short yypact[] = {-32768,
232     52,   -21,-32768,   -12,-32768,   -15,-32768,-32768,-32768,     1,
233 -32768,   -16,-32768,-32768,-32768,-32768,-32768,    -2,    -2,-32768,
234     -2,    17,    -2,-32768,   162,-32768,    -2,    -2,    25,    -2,
235     -6,    -2,    -5,     6,     6,    81,    27,   187,    -7,    35,
236     -2,    -2,    -2,    -2,    -2,    -2,    -2,    -2,    -2,    -2,
237     -2,    -2,-32768,-32768,   187,   187,   -26,-32768,   187,    14,
238 -32768,    51,   108,    -2,-32768,-32768,-32768,    -2,   197,   197,
239     69,    69,    69,    69,    94,    94,     6,     6,     6,     6,
240 -32768,    -2,-32768,    -2,    -2,    42,   135,   187,   187,   187,
241     22,-32768,-32768,-32768,    77,-32768
242 };
243
244 static const short yypgoto[] = {-32768,
245 -32768,    -1,-32768,-32768,-32768,-32768,-32768,    -3
246 };
247
248
249 #define YYLAST          230
250
251
252 static const short yytable[] = {    25,
253      3,     4,     5,     6,     7,     8,     9,    29,    61,    81,
254     27,    10,    26,    82,    30,    13,    34,    35,    32,    36,
255     37,    38,    28,    18,    19,    55,    56,    58,    83,    64,
256     63,    67,    21,    62,    22,    23,    94,    52,    53,    69,
257     70,    71,    72,    73,    74,    75,    76,    77,    78,    79,
258     80,    95,     2,    84,     3,     4,     5,     6,     7,     8,
259      9,    84,    87,    66,    85,    10,    88,    11,    12,    13,
260     14,    15,    16,    17,    68,    92,    96,    18,    19,     0,
261     89,    91,    90,     0,     0,    20,    21,     0,    22,    23,
262     41,    42,    43,    44,    47,    48,    49,    50,    51,     0,
263     52,    53,     0,     0,    45,    46,    47,    48,    49,    50,
264     51,     0,    52,    53,     0,     0,    65,    41,    42,    43,
265     44,    49,    50,    51,     0,    52,    53,     0,     0,     0,
266      0,    45,    46,    47,    48,    49,    50,    51,     0,    52,
267     53,     0,     0,    86,    41,    42,    43,    44,     0,     0,
268      0,     0,     0,     0,     0,     0,     0,     0,    45,    46,
269     47,    48,    49,    50,    51,     0,    52,    53,     0,     0,
270     93,    41,    42,    43,    44,     0,     0,     0,     0,     0,
271      0,     0,     0,     0,     0,    45,    46,    47,    48,    49,
272     50,    51,     0,    52,    53,    54,    41,    42,    43,    44,
273      0,     0,     0,     0,     0,     0,     0,     0,    43,    44,
274     45,    46,    47,    48,    49,    50,    51,     0,    52,    53,
275     45,    46,    47,    48,    49,    50,    51,     0,    52,    53
276 };
277
278 static const short yycheck[] = {     1,
279      3,     4,     5,     6,     7,     8,     9,    23,    15,    36,
280     23,    14,    34,    40,    14,    18,    18,    19,    35,    21,
281      4,    23,    35,    26,    27,    27,    28,     3,    15,    35,
282     32,    39,    35,    40,    37,    38,    15,    32,    33,    41,
283     42,    43,    44,    45,    46,    47,    48,    49,    50,    51,
284     52,     0,     1,    40,     3,     4,     5,     6,     7,     8,
285      9,    40,    64,    37,    14,    14,    68,    16,    17,    18,
286     19,    20,    21,    22,    40,    34,     0,    26,    27,    -1,
287     82,    85,    84,    -1,    -1,    34,    35,    -1,    37,    38,
288     10,    11,    12,    13,    26,    27,    28,    29,    30,    -1,
289     32,    33,    -1,    -1,    24,    25,    26,    27,    28,    29,
290     30,    -1,    32,    33,    -1,    -1,    36,    10,    11,    12,
291     13,    28,    29,    30,    -1,    32,    33,    -1,    -1,    -1,
292     -1,    24,    25,    26,    27,    28,    29,    30,    -1,    32,
293     33,    -1,    -1,    36,    10,    11,    12,    13,    -1,    -1,
294     -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    24,    25,
295     26,    27,    28,    29,    30,    -1,    32,    33,    -1,    -1,
296     36,    10,    11,    12,    13,    -1,    -1,    -1,    -1,    -1,
297     -1,    -1,    -1,    -1,    -1,    24,    25,    26,    27,    28,
298     29,    30,    -1,    32,    33,    34,    10,    11,    12,    13,
299     -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    12,    13,
300     24,    25,    26,    27,    28,    29,    30,    -1,    32,    33,
301     24,    25,    26,    27,    28,    29,    30,    -1,    32,    33
302 };
303 /* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
304 #line 3 "/usr/share/misc/bison.simple"
305
306 /* Skeleton output parser for bison,
307    Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
308
309    This program is free software; you can redistribute it and/or modify
310    it under the terms of the GNU General Public License as published by
311    the Free Software Foundation; either version 2, or (at your option)
312    any later version.
313
314    This program is distributed in the hope that it will be useful,
315    but WITHOUT ANY WARRANTY; without even the implied warranty of
316    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
317    GNU General Public License for more details.
318
319    You should have received a copy of the GNU General Public License
320    along with this program; if not, write to the Free Software
321    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
322
323 /* As a special exception, when this file is copied by Bison into a
324    Bison output file, you may use that output file without restriction.
325    This special exception was added by the Free Software Foundation
326    in version 1.24 of Bison.  */
327
328 #ifndef alloca
329 #ifdef __GNUC__
330 #define alloca __builtin_alloca
331 #else /* not GNU C.  */
332 #if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi)
333 #include <alloca.h>
334 #else /* not sparc */
335 #if defined (MSDOS) && !defined (__TURBOC__)
336 #include <malloc.h>
337 #else /* not MSDOS, or __TURBOC__ */
338 #if defined(_AIX)
339 #include <malloc.h>
340  #pragma alloca
341 #else /* not MSDOS, __TURBOC__, or _AIX */
342 #ifdef __hpux
343 #ifdef __cplusplus
344 extern "C" {
345 void *alloca (unsigned int);
346 };
347 #else /* not __cplusplus */
348 void *alloca ();
349 #endif /* not __cplusplus */
350 #endif /* __hpux */
351 #endif /* not _AIX */
352 #endif /* not MSDOS, or __TURBOC__ */
353 #endif /* not sparc.  */
354 #endif /* not GNU C.  */
355 #endif /* alloca not defined.  */
356
357 /* This is the parser code that is written into each bison parser
358   when the %semantic_parser declaration is not specified in the grammar.
359   It was written by Richard Stallman by simplifying the hairy parser
360   used when %semantic_parser is specified.  */
361
362 /* Note: there must be only one dollar sign in this file.
363    It is replaced by the list of actions, each action
364    as one case of the switch.  */
365
366 #define yyerrok         (yyerrstatus = 0)
367 #define yyclearin       (yychar = YYEMPTY)
368 #define YYEMPTY         -2
369 #define YYEOF           0
370 #define YYACCEPT        return(0)
371 #define YYABORT         return(1)
372 #define YYERROR         goto yyerrlab1
373 /* Like YYERROR except do call yyerror.
374    This remains here temporarily to ease the
375    transition to the new meaning of YYERROR, for GCC.
376    Once GCC version 2 has supplanted version 1, this can go.  */
377 #define YYFAIL          goto yyerrlab
378 #define YYRECOVERING()  (!!yyerrstatus)
379 #define YYBACKUP(token, value) \
380 do                                                              \
381   if (yychar == YYEMPTY && yylen == 1)                          \
382     { yychar = (token), yylval = (value);                       \
383       yychar1 = YYTRANSLATE (yychar);                           \
384       YYPOPSTACK;                                               \
385       goto yybackup;                                            \
386     }                                                           \
387   else                                                          \
388     { yyerror ("syntax error: cannot back up"); YYERROR; }      \
389 while (0)
390
391 #define YYTERROR        1
392 #define YYERRCODE       256
393
394 #ifndef YYPURE
395 #define YYLEX           yylex()
396 #endif
397
398 #ifdef YYPURE
399 #ifdef YYLSP_NEEDED
400 #ifdef YYLEX_PARAM
401 #define YYLEX           yylex(&yylval, &yylloc, YYLEX_PARAM)
402 #else
403 #define YYLEX           yylex(&yylval, &yylloc)
404 #endif
405 #else /* not YYLSP_NEEDED */
406 #ifdef YYLEX_PARAM
407 #define YYLEX           yylex(&yylval, YYLEX_PARAM)
408 #else
409 #define YYLEX           yylex(&yylval)
410 #endif
411 #endif /* not YYLSP_NEEDED */
412 #endif
413
414 /* If nonreentrant, generate the variables here */
415
416 #ifndef YYPURE
417
418 int     yychar;                 /*  the lookahead symbol                */
419 YYSTYPE yylval;                 /*  the semantic value of the           */
420                                 /*  lookahead symbol                    */
421
422 #ifdef YYLSP_NEEDED
423 YYLTYPE yylloc;                 /*  location data for the lookahead     */
424                                 /*  symbol                              */
425 #endif
426
427 int yynerrs;                    /*  number of parse errors so far       */
428 #endif  /* not YYPURE */
429
430 #if YYDEBUG != 0
431 int yydebug;                    /*  nonzero means print parse trace     */
432 /* Since this is uninitialized, it does not stop multiple parsers
433    from coexisting.  */
434 #endif
435
436 /*  YYINITDEPTH indicates the initial size of the parser's stacks       */
437
438 #ifndef YYINITDEPTH
439 #define YYINITDEPTH 200
440 #endif
441
442 /*  YYMAXDEPTH is the maximum size the stacks can grow to
443     (effective only if the built-in stack extension method is used).  */
444
445 #if YYMAXDEPTH == 0
446 #undef YYMAXDEPTH
447 #endif
448
449 #ifndef YYMAXDEPTH
450 #define YYMAXDEPTH 10000
451 #endif
452
453 /* Prevent warning if -Wstrict-prototypes.  */
454 #ifdef __GNUC__
455 #ifndef YYPARSE_PARAM
456 int yyparse (void);
457 #endif
458 #endif
459 \f
460 #if __GNUC__ > 1                /* GNU C and GNU C++ define this.  */
461 #define __yy_memcpy(TO,FROM,COUNT)      __builtin_memcpy(TO,FROM,COUNT)
462 #else                           /* not GNU C or C++ */
463 #ifndef __cplusplus
464
465 /* This is the most reliable way to avoid incompatibilities
466    in available built-in functions on various systems.  */
467 static void
468 __yy_memcpy (to, from, count)
469      char *to;
470      char *from;
471      int count;
472 {
473   register char *f = from;
474   register char *t = to;
475   register int i = count;
476
477   while (i-- > 0)
478     *t++ = *f++;
479 }
480
481 #else /* __cplusplus */
482
483 /* This is the most reliable way to avoid incompatibilities
484    in available built-in functions on various systems.  */
485 static void
486 __yy_memcpy (char *to, char *from, int count)
487 {
488   register char *f = from;
489   register char *t = to;
490   register int i = count;
491
492   while (i-- > 0)
493     *t++ = *f++;
494 }
495
496 #endif
497 #endif
498 \f
499 #line 196 "/usr/share/misc/bison.simple"
500
501 /* The user can define YYPARSE_PARAM as the name of an argument to be passed
502    into yyparse.  The argument should have type void *.
503    It should actually point to an object.
504    Grammar actions can access the variable by casting it
505    to the proper pointer type.  */
506
507 #ifdef YYPARSE_PARAM
508 #ifdef __cplusplus
509 #define YYPARSE_PARAM_ARG void *YYPARSE_PARAM
510 #define YYPARSE_PARAM_DECL
511 #else /* not __cplusplus */
512 #define YYPARSE_PARAM_ARG YYPARSE_PARAM
513 #define YYPARSE_PARAM_DECL void *YYPARSE_PARAM;
514 #endif /* not __cplusplus */
515 #else /* not YYPARSE_PARAM */
516 #define YYPARSE_PARAM_ARG
517 #define YYPARSE_PARAM_DECL
518 #endif /* not YYPARSE_PARAM */
519
520 int
521 yyparse(YYPARSE_PARAM_ARG)
522      YYPARSE_PARAM_DECL
523 {
524   register int yystate;
525   register int yyn;
526   register short *yyssp;
527   register YYSTYPE *yyvsp;
528   int yyerrstatus;      /*  number of tokens to shift before error messages enabled */
529   int yychar1 = 0;              /*  lookahead token as an internal (translated) token number */
530
531   short yyssa[YYINITDEPTH];     /*  the state stack                     */
532   YYSTYPE yyvsa[YYINITDEPTH];   /*  the semantic value stack            */
533
534   short *yyss = yyssa;          /*  refer to the stacks thru separate pointers */
535   YYSTYPE *yyvs = yyvsa;        /*  to allow yyoverflow to reallocate them elsewhere */
536
537 #ifdef YYLSP_NEEDED
538   YYLTYPE yylsa[YYINITDEPTH];   /*  the location stack                  */
539   YYLTYPE *yyls = yylsa;
540   YYLTYPE *yylsp;
541
542 #define YYPOPSTACK   (yyvsp--, yyssp--, yylsp--)
543 #else
544 #define YYPOPSTACK   (yyvsp--, yyssp--)
545 #endif
546
547   int yystacksize = YYINITDEPTH;
548
549 #ifdef YYPURE
550   int yychar;
551   YYSTYPE yylval;
552   int yynerrs;
553 #ifdef YYLSP_NEEDED
554   YYLTYPE yylloc;
555 #endif
556 #endif
557
558   YYSTYPE yyval;                /*  the variable used to return         */
559                                 /*  semantic values from the action     */
560                                 /*  routines                            */
561
562   int yylen;
563
564 #if YYDEBUG != 0
565   if (yydebug)
566     fprintf(stderr, "Starting parse\n");
567 #endif
568
569   yystate = 0;
570   yyerrstatus = 0;
571   yynerrs = 0;
572   yychar = YYEMPTY;             /* Cause a token to be read.  */
573
574   /* Initialize stack pointers.
575      Waste one element of value and location stack
576      so that they stay on the same level as the state stack.
577      The wasted elements are never initialized.  */
578
579   yyssp = yyss - 1;
580   yyvsp = yyvs;
581 #ifdef YYLSP_NEEDED
582   yylsp = yyls;
583 #endif
584
585 /* Push a new state, which is found in  yystate  .  */
586 /* In all cases, when you get here, the value and location stacks
587    have just been pushed. so pushing a state here evens the stacks.  */
588 yynewstate:
589
590   *++yyssp = yystate;
591
592   if (yyssp >= yyss + yystacksize - 1)
593     {
594       /* Give user a chance to reallocate the stack */
595       /* Use copies of these so that the &'s don't force the real ones into memory. */
596       YYSTYPE *yyvs1 = yyvs;
597       short *yyss1 = yyss;
598 #ifdef YYLSP_NEEDED
599       YYLTYPE *yyls1 = yyls;
600 #endif
601
602       /* Get the current used size of the three stacks, in elements.  */
603       int size = yyssp - yyss + 1;
604
605 #ifdef yyoverflow
606       /* Each stack pointer address is followed by the size of
607          the data in use in that stack, in bytes.  */
608 #ifdef YYLSP_NEEDED
609       /* This used to be a conditional around just the two extra args,
610          but that might be undefined if yyoverflow is a macro.  */
611       yyoverflow("parser stack overflow",
612                  &yyss1, size * sizeof (*yyssp),
613                  &yyvs1, size * sizeof (*yyvsp),
614                  &yyls1, size * sizeof (*yylsp),
615                  &yystacksize);
616 #else
617       yyoverflow("parser stack overflow",
618                  &yyss1, size * sizeof (*yyssp),
619                  &yyvs1, size * sizeof (*yyvsp),
620                  &yystacksize);
621 #endif
622
623       yyss = yyss1; yyvs = yyvs1;
624 #ifdef YYLSP_NEEDED
625       yyls = yyls1;
626 #endif
627 #else /* no yyoverflow */
628       /* Extend the stack our own way.  */
629       if (yystacksize >= YYMAXDEPTH)
630         {
631           yyerror("parser stack overflow");
632           return 2;
633         }
634       yystacksize *= 2;
635       if (yystacksize > YYMAXDEPTH)
636         yystacksize = YYMAXDEPTH;
637       yyss = (short *) alloca (yystacksize * sizeof (*yyssp));
638       __yy_memcpy ((char *)yyss, (char *)yyss1, size * sizeof (*yyssp));
639       yyvs = (YYSTYPE *) alloca (yystacksize * sizeof (*yyvsp));
640       __yy_memcpy ((char *)yyvs, (char *)yyvs1, size * sizeof (*yyvsp));
641 #ifdef YYLSP_NEEDED
642       yyls = (YYLTYPE *) alloca (yystacksize * sizeof (*yylsp));
643       __yy_memcpy ((char *)yyls, (char *)yyls1, size * sizeof (*yylsp));
644 #endif
645 #endif /* no yyoverflow */
646
647       yyssp = yyss + size - 1;
648       yyvsp = yyvs + size - 1;
649 #ifdef YYLSP_NEEDED
650       yylsp = yyls + size - 1;
651 #endif
652
653 #if YYDEBUG != 0
654       if (yydebug)
655         fprintf(stderr, "Stack size increased to %d\n", yystacksize);
656 #endif
657
658       if (yyssp >= yyss + yystacksize - 1)
659         YYABORT;
660     }
661
662 #if YYDEBUG != 0
663   if (yydebug)
664     fprintf(stderr, "Entering state %d\n", yystate);
665 #endif
666
667   goto yybackup;
668  yybackup:
669
670 /* Do appropriate processing given the current state.  */
671 /* Read a lookahead token if we need one and don't already have one.  */
672 /* yyresume: */
673
674   /* First try to decide what to do without reference to lookahead token.  */
675
676   yyn = yypact[yystate];
677   if (yyn == YYFLAG)
678     goto yydefault;
679
680   /* Not known => get a lookahead token if don't already have one.  */
681
682   /* yychar is either YYEMPTY or YYEOF
683      or a valid token in external form.  */
684
685   if (yychar == YYEMPTY)
686     {
687 #if YYDEBUG != 0
688       if (yydebug)
689         fprintf(stderr, "Reading a token: ");
690 #endif
691       yychar = YYLEX;
692     }
693
694   /* Convert token to internal form (in yychar1) for indexing tables with */
695
696   if (yychar <= 0)              /* This means end of input. */
697     {
698       yychar1 = 0;
699       yychar = YYEOF;           /* Don't call YYLEX any more */
700
701 #if YYDEBUG != 0
702       if (yydebug)
703         fprintf(stderr, "Now at end of input.\n");
704 #endif
705     }
706   else
707     {
708       yychar1 = YYTRANSLATE(yychar);
709
710 #if YYDEBUG != 0
711       if (yydebug)
712         {
713           fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]);
714           /* Give the individual parser a way to print the precise meaning
715              of a token, for further debugging info.  */
716 #ifdef YYPRINT
717           YYPRINT (stderr, yychar, yylval);
718 #endif
719           fprintf (stderr, ")\n");
720         }
721 #endif
722     }
723
724   yyn += yychar1;
725   if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1)
726     goto yydefault;
727
728   yyn = yytable[yyn];
729
730   /* yyn is what to do for this token type in this state.
731      Negative => reduce, -yyn is rule number.
732      Positive => shift, yyn is new state.
733        New state is final state => don't bother to shift,
734        just return success.
735      0, or most negative number => error.  */
736
737   if (yyn < 0)
738     {
739       if (yyn == YYFLAG)
740         goto yyerrlab;
741       yyn = -yyn;
742       goto yyreduce;
743     }
744   else if (yyn == 0)
745     goto yyerrlab;
746
747   if (yyn == YYFINAL)
748     YYACCEPT;
749
750   /* Shift the lookahead token.  */
751
752 #if YYDEBUG != 0
753   if (yydebug)
754     fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]);
755 #endif
756
757   /* Discard the token being shifted unless it is eof.  */
758   if (yychar != YYEOF)
759     yychar = YYEMPTY;
760
761   *++yyvsp = yylval;
762 #ifdef YYLSP_NEEDED
763   *++yylsp = yylloc;
764 #endif
765
766   /* count tokens shifted since error; after three, turn off error status.  */
767   if (yyerrstatus) yyerrstatus--;
768
769   yystate = yyn;
770   goto yynewstate;
771
772 /* Do the default action for the current state.  */
773 yydefault:
774
775   yyn = yydefact[yystate];
776   if (yyn == 0)
777     goto yyerrlab;
778
779 /* Do a reduction.  yyn is the number of a rule to reduce with.  */
780 yyreduce:
781   yylen = yyr2[yyn];
782   if (yylen > 0)
783     yyval = yyvsp[1-yylen]; /* implement default value of the action */
784
785 #if YYDEBUG != 0
786   if (yydebug)
787     {
788       int i;
789
790       fprintf (stderr, "Reducing via rule %d (line %d), ",
791                yyn, yyrline[yyn]);
792
793       /* Print the symbols being reduced, and their result.  */
794       for (i = yyprhs[yyn]; yyrhs[i] > 0; i++)
795         fprintf (stderr, "%s ", yytname[yyrhs[i]]);
796       fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]);
797     }
798 #endif
799
800
801   switch (yyn) {
802
803 case 4:
804 #line 120 "ginsh_parser.yy"
805 {
806                         try {
807                                 cout << yyvsp[-1] << endl;
808                                 push(yyvsp[-1]);
809                         } catch (exception &e) {
810                                 cerr << e.what() << endl;
811                                 YYERROR;
812                         }
813                 ;
814     break;}
815 case 5:
816 #line 130 "ginsh_parser.yy"
817 {
818                         try {
819                                 yyvsp[-2].printtree(cout);
820                         } catch (exception &e) {
821                                 cerr << e.what() << endl;
822                                 YYERROR;
823                         }
824                 ;
825     break;}
826 case 6:
827 #line 138 "ginsh_parser.yy"
828 {YYACCEPT;;
829     break;}
830 case 7:
831 #line 139 "ginsh_parser.yy"
832 {cout << "Nothing happens.\n";;
833     break;}
834 case 8:
835 #line 140 "ginsh_parser.yy"
836 {cout << "You're not carrying anything.\n";;
837     break;}
838 case 9:
839 #line 141 "ginsh_parser.yy"
840 {cout << "You're in a twisty little maze of passages, all alike.\n";;
841     break;}
842 case 10:
843 #line 143 "ginsh_parser.yy"
844 {
845                         cout << "If you were to quit now, you would score ";
846                         cout << (syms.size() > 350 ? 350 : syms.size());
847                         cout << " out of a possible 350.\n";
848                 ;
849     break;}
850 case 11:
851 #line 148 "ginsh_parser.yy"
852 {yyclearin; yyerrok;;
853     break;}
854 case 12:
855 #line 151 "ginsh_parser.yy"
856 {yyval = yyvsp[0];;
857     break;}
858 case 13:
859 #line 152 "ginsh_parser.yy"
860 {yyval = yyvsp[0].eval();;
861     break;}
862 case 14:
863 #line 153 "ginsh_parser.yy"
864 {yyval = yyvsp[-1];;
865     break;}
866 case 15:
867 #line 154 "ginsh_parser.yy"
868 {yyval = yyvsp[0];;
869     break;}
870 case 16:
871 #line 155 "ginsh_parser.yy"
872 {yyval = yyvsp[0];;
873     break;}
874 case 17:
875 #line 156 "ginsh_parser.yy"
876 {yyval = exstack[0];;
877     break;}
878 case 18:
879 #line 157 "ginsh_parser.yy"
880 {yyval = exstack[1];;
881     break;}
882 case 19:
883 #line 158 "ginsh_parser.yy"
884 {yyval = exstack[2];;
885     break;}
886 case 20:
887 #line 159 "ginsh_parser.yy"
888 {getrusage(RUSAGE_SELF, &start_time);;
889     break;}
890 case 21:
891 #line 160 "ginsh_parser.yy"
892 {
893                         getrusage(RUSAGE_SELF, &end_time);
894                         yyval = (end_time.ru_utime.tv_sec - start_time.ru_utime.tv_sec) +
895                              (end_time.ru_stime.tv_sec - start_time.ru_stime.tv_sec) +
896                              double(end_time.ru_utime.tv_usec - start_time.ru_utime.tv_usec) / 1e6 +
897                              double(end_time.ru_stime.tv_usec - start_time.ru_stime.tv_usec) / 1e6;
898                 ;
899     break;}
900 case 22:
901 #line 168 "ginsh_parser.yy"
902 {
903                         fcn_tab::const_iterator i = find_function(yyvsp[-3], yyvsp[-1].nops());
904                         if (i->second.is_ginac) {
905                                 yyval = ((fcnp2)(i->second.p))(static_cast<const exprseq &>(*(yyvsp[-1].bp)), i->second.serial);
906                         } else {
907                                 yyval = (i->second.p)(static_cast<const exprseq &>(*(yyvsp[-1].bp)));
908                         }
909                 ;
910     break;}
911 case 23:
912 #line 177 "ginsh_parser.yy"
913 {yyval = yyvsp[0]; Digits = ex_to_numeric(yyvsp[0]).to_int();;
914     break;}
915 case 24:
916 #line 179 "ginsh_parser.yy"
917 {yyval = yyvsp[0]; const_cast<symbol *>(&ex_to_symbol(yyvsp[-2]))->assign(yyvsp[0]);;
918     break;}
919 case 25:
920 #line 180 "ginsh_parser.yy"
921 {yyval = yyvsp[-2] == yyvsp[0];;
922     break;}
923 case 26:
924 #line 181 "ginsh_parser.yy"
925 {yyval = yyvsp[-2] != yyvsp[0];;
926     break;}
927 case 27:
928 #line 182 "ginsh_parser.yy"
929 {yyval = yyvsp[-2] < yyvsp[0];;
930     break;}
931 case 28:
932 #line 183 "ginsh_parser.yy"
933 {yyval = yyvsp[-2] <= yyvsp[0];;
934     break;}
935 case 29:
936 #line 184 "ginsh_parser.yy"
937 {yyval = yyvsp[-2] > yyvsp[0];;
938     break;}
939 case 30:
940 #line 185 "ginsh_parser.yy"
941 {yyval = yyvsp[-2] >= yyvsp[0];;
942     break;}
943 case 31:
944 #line 186 "ginsh_parser.yy"
945 {yyval = yyvsp[-2] + yyvsp[0];;
946     break;}
947 case 32:
948 #line 187 "ginsh_parser.yy"
949 {yyval = yyvsp[-2] - yyvsp[0];;
950     break;}
951 case 33:
952 #line 188 "ginsh_parser.yy"
953 {yyval = yyvsp[-2] * yyvsp[0];;
954     break;}
955 case 34:
956 #line 189 "ginsh_parser.yy"
957 {yyval = yyvsp[-2] / yyvsp[0];;
958     break;}
959 case 35:
960 #line 190 "ginsh_parser.yy"
961 {yyval = yyvsp[-2] % yyvsp[0];;
962     break;}
963 case 36:
964 #line 191 "ginsh_parser.yy"
965 {yyval = -yyvsp[0];;
966     break;}
967 case 37:
968 #line 192 "ginsh_parser.yy"
969 {yyval = yyvsp[0];;
970     break;}
971 case 38:
972 #line 193 "ginsh_parser.yy"
973 {yyval = power(yyvsp[-2], yyvsp[0]);;
974     break;}
975 case 39:
976 #line 194 "ginsh_parser.yy"
977 {yyval = factorial(yyvsp[-1]);;
978     break;}
979 case 40:
980 #line 195 "ginsh_parser.yy"
981 {yyval = yyvsp[-1];;
982     break;}
983 case 41:
984 #line 196 "ginsh_parser.yy"
985 {yyval = yyvsp[-1];;
986     break;}
987 case 42:
988 #line 197 "ginsh_parser.yy"
989 {yyval = lst2matrix(yyvsp[-1]);;
990     break;}
991 case 43:
992 #line 200 "ginsh_parser.yy"
993 {yyval = exprseq(yyvsp[0]);;
994     break;}
995 case 44:
996 #line 201 "ginsh_parser.yy"
997 {exprseq es(static_cast<exprseq &>(*(yyvsp[-2].bp))); yyval = es.append(yyvsp[0]);;
998     break;}
999 case 45:
1000 #line 204 "ginsh_parser.yy"
1001 {yyval = *new lst;;
1002     break;}
1003 case 46:
1004 #line 205 "ginsh_parser.yy"
1005 {yyval = yyvsp[0];;
1006     break;}
1007 case 47:
1008 #line 208 "ginsh_parser.yy"
1009 {yyval = lst(yyvsp[0]);;
1010     break;}
1011 case 48:
1012 #line 209 "ginsh_parser.yy"
1013 {lst l(static_cast<lst &>(*(yyvsp[-2].bp))); yyval = l.append(yyvsp[0]);;
1014     break;}
1015 case 49:
1016 #line 212 "ginsh_parser.yy"
1017 {yyval = lst(yyvsp[-1]);;
1018     break;}
1019 case 50:
1020 #line 213 "ginsh_parser.yy"
1021 {lst l(static_cast<lst &>(*(yyvsp[-4].bp))); yyval = l.append(yyvsp[-1]);;
1022     break;}
1023 case 51:
1024 #line 216 "ginsh_parser.yy"
1025 {yyval = lst(yyvsp[0]);;
1026     break;}
1027 case 52:
1028 #line 217 "ginsh_parser.yy"
1029 {lst l(static_cast<lst &>(*(yyvsp[-2].bp))); yyval = l.append(yyvsp[0]);;
1030     break;}
1031 }
1032    /* the action file gets copied in in place of this dollarsign */
1033 #line 498 "/usr/share/misc/bison.simple"
1034 \f
1035   yyvsp -= yylen;
1036   yyssp -= yylen;
1037 #ifdef YYLSP_NEEDED
1038   yylsp -= yylen;
1039 #endif
1040
1041 #if YYDEBUG != 0
1042   if (yydebug)
1043     {
1044       short *ssp1 = yyss - 1;
1045       fprintf (stderr, "state stack now");
1046       while (ssp1 != yyssp)
1047         fprintf (stderr, " %d", *++ssp1);
1048       fprintf (stderr, "\n");
1049     }
1050 #endif
1051
1052   *++yyvsp = yyval;
1053
1054 #ifdef YYLSP_NEEDED
1055   yylsp++;
1056   if (yylen == 0)
1057     {
1058       yylsp->first_line = yylloc.first_line;
1059       yylsp->first_column = yylloc.first_column;
1060       yylsp->last_line = (yylsp-1)->last_line;
1061       yylsp->last_column = (yylsp-1)->last_column;
1062       yylsp->text = 0;
1063     }
1064   else
1065     {
1066       yylsp->last_line = (yylsp+yylen-1)->last_line;
1067       yylsp->last_column = (yylsp+yylen-1)->last_column;
1068     }
1069 #endif
1070
1071   /* Now "shift" the result of the reduction.
1072      Determine what state that goes to,
1073      based on the state we popped back to
1074      and the rule number reduced by.  */
1075
1076   yyn = yyr1[yyn];
1077
1078   yystate = yypgoto[yyn - YYNTBASE] + *yyssp;
1079   if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp)
1080     yystate = yytable[yystate];
1081   else
1082     yystate = yydefgoto[yyn - YYNTBASE];
1083
1084   goto yynewstate;
1085
1086 yyerrlab:   /* here on detecting error */
1087
1088   if (! yyerrstatus)
1089     /* If not already recovering from an error, report this error.  */
1090     {
1091       ++yynerrs;
1092
1093 #ifdef YYERROR_VERBOSE
1094       yyn = yypact[yystate];
1095
1096       if (yyn > YYFLAG && yyn < YYLAST)
1097         {
1098           int size = 0;
1099           char *msg;
1100           int x, count;
1101
1102           count = 0;
1103           /* Start X at -yyn if nec to avoid negative indexes in yycheck.  */
1104           for (x = (yyn < 0 ? -yyn : 0);
1105                x < (sizeof(yytname) / sizeof(char *)); x++)
1106             if (yycheck[x + yyn] == x)
1107               size += strlen(yytname[x]) + 15, count++;
1108           msg = (char *) malloc(size + 15);
1109           if (msg != 0)
1110             {
1111               strcpy(msg, "parse error");
1112
1113               if (count < 5)
1114                 {
1115                   count = 0;
1116                   for (x = (yyn < 0 ? -yyn : 0);
1117                        x < (sizeof(yytname) / sizeof(char *)); x++)
1118                     if (yycheck[x + yyn] == x)
1119                       {
1120                         strcat(msg, count == 0 ? ", expecting `" : " or `");
1121                         strcat(msg, yytname[x]);
1122                         strcat(msg, "'");
1123                         count++;
1124                       }
1125                 }
1126               yyerror(msg);
1127               free(msg);
1128             }
1129           else
1130             yyerror ("parse error; also virtual memory exceeded");
1131         }
1132       else
1133 #endif /* YYERROR_VERBOSE */
1134         yyerror("parse error");
1135     }
1136
1137   goto yyerrlab1;
1138 yyerrlab1:   /* here on error raised explicitly by an action */
1139
1140   if (yyerrstatus == 3)
1141     {
1142       /* if just tried and failed to reuse lookahead token after an error, discard it.  */
1143
1144       /* return failure if at end of input */
1145       if (yychar == YYEOF)
1146         YYABORT;
1147
1148 #if YYDEBUG != 0
1149       if (yydebug)
1150         fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]);
1151 #endif
1152
1153       yychar = YYEMPTY;
1154     }
1155
1156   /* Else will try to reuse lookahead token
1157      after shifting the error token.  */
1158
1159   yyerrstatus = 3;              /* Each real token shifted decrements this */
1160
1161   goto yyerrhandle;
1162
1163 yyerrdefault:  /* current state does not do anything special for the error token. */
1164
1165 #if 0
1166   /* This is wrong; only states that explicitly want error tokens
1167      should shift them.  */
1168   yyn = yydefact[yystate];  /* If its default is to accept any token, ok.  Otherwise pop it.*/
1169   if (yyn) goto yydefault;
1170 #endif
1171
1172 yyerrpop:   /* pop the current state because it cannot handle the error token */
1173
1174   if (yyssp == yyss) YYABORT;
1175   yyvsp--;
1176   yystate = *--yyssp;
1177 #ifdef YYLSP_NEEDED
1178   yylsp--;
1179 #endif
1180
1181 #if YYDEBUG != 0
1182   if (yydebug)
1183     {
1184       short *ssp1 = yyss - 1;
1185       fprintf (stderr, "Error: state stack now");
1186       while (ssp1 != yyssp)
1187         fprintf (stderr, " %d", *++ssp1);
1188       fprintf (stderr, "\n");
1189     }
1190 #endif
1191
1192 yyerrhandle:
1193
1194   yyn = yypact[yystate];
1195   if (yyn == YYFLAG)
1196     goto yyerrdefault;
1197
1198   yyn += YYTERROR;
1199   if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR)
1200     goto yyerrdefault;
1201
1202   yyn = yytable[yyn];
1203   if (yyn < 0)
1204     {
1205       if (yyn == YYFLAG)
1206         goto yyerrpop;
1207       yyn = -yyn;
1208       goto yyreduce;
1209     }
1210   else if (yyn == 0)
1211     goto yyerrpop;
1212
1213   if (yyn == YYFINAL)
1214     YYACCEPT;
1215
1216 #if YYDEBUG != 0
1217   if (yydebug)
1218     fprintf(stderr, "Shifting error token, ");
1219 #endif
1220
1221   *++yyvsp = yylval;
1222 #ifdef YYLSP_NEEDED
1223   *++yylsp = yylloc;
1224 #endif
1225
1226   yystate = yyn;
1227   goto yynewstate;
1228 }
1229 #line 225 "ginsh_parser.yy"
1230
1231 // Error print routine
1232 int yyerror(char *s)
1233 {
1234         cerr << s << " at " << yytext << endl;
1235         return 0;
1236 }
1237
1238 // Push expression "e" onto the expression stack (for ", "" and """)
1239 static void push(const ex &e)
1240 {
1241         exstack[2] = exstack[1];
1242         exstack[1] = exstack[0];
1243         exstack[0] = e;
1244 }
1245
1246
1247 /*
1248  *  Built-in functions
1249  */
1250
1251 static ex f_beta(const exprseq &e) {return gamma(e[0])*gamma(e[1])/gamma(e[0]+e[1]);}
1252 static ex f_denom(const exprseq &e) {return e[0].denom();}
1253 static ex f_eval1(const exprseq &e) {return e[0].eval();}
1254 static ex f_evalf1(const exprseq &e) {return e[0].evalf();}
1255 static ex f_expand(const exprseq &e) {return e[0].expand();}
1256 static ex f_gcd(const exprseq &e) {return gcd(e[0], e[1]);}
1257 static ex f_lcm(const exprseq &e) {return lcm(e[0], e[1]);}
1258 static ex f_lsolve(const exprseq &e) {return lsolve(e[0], e[1]);}
1259 static ex f_nops(const exprseq &e) {return e[0].nops();}
1260 static ex f_normal1(const exprseq &e) {return e[0].normal();}
1261 static ex f_numer(const exprseq &e) {return e[0].numer();}
1262 static ex f_power(const exprseq &e) {return power(e[0], e[1]);}
1263 static ex f_sqrt(const exprseq &e) {return sqrt(e[0]);}
1264 static ex f_subs2(const exprseq &e) {return e[0].subs(e[1]);}
1265
1266 #define CHECK_ARG(num, type, fcn) if (!is_ex_of_type(e[num], type)) throw(std::invalid_argument("argument " #num " to " #fcn " must be a " #type))
1267
1268 static ex f_charpoly(const exprseq &e)
1269 {
1270         CHECK_ARG(0, matrix, charpoly);
1271         CHECK_ARG(1, symbol, charpoly);
1272         return ex_to_matrix(e[0]).charpoly(ex_to_symbol(e[1]));
1273 }
1274
1275 static ex f_coeff(const exprseq &e)
1276 {
1277         CHECK_ARG(1, symbol, coeff);
1278         CHECK_ARG(2, numeric, coeff);
1279         return e[0].coeff(ex_to_symbol(e[1]), ex_to_numeric(e[2]).to_int());
1280 }
1281
1282 static ex f_collect(const exprseq &e)
1283 {
1284         CHECK_ARG(1, symbol, collect);
1285         return e[0].collect(ex_to_symbol(e[1]));
1286 }
1287
1288 static ex f_content(const exprseq &e)
1289 {
1290         CHECK_ARG(1, symbol, content);
1291         return e[0].content(ex_to_symbol(e[1]));
1292 }
1293
1294 static ex f_degree(const exprseq &e)
1295 {
1296         CHECK_ARG(1, symbol, degree);
1297         return e[0].degree(ex_to_symbol(e[1]));
1298 }
1299
1300 static ex f_determinant(const exprseq &e)
1301 {
1302         CHECK_ARG(0, matrix, determinant);
1303         return ex_to_matrix(e[0]).determinant();
1304 }
1305
1306 static ex f_diag(const exprseq &e)
1307 {
1308         int dim = e.nops();
1309         matrix &m = *new matrix(dim, dim);
1310         for (int i=0; i<dim; i++)
1311                 m.set(i, i, e.op(i));
1312         return m;
1313 }
1314
1315 static ex f_diff2(const exprseq &e)
1316 {
1317         CHECK_ARG(1, symbol, diff);
1318         return e[0].diff(ex_to_symbol(e[1]));
1319 }
1320
1321 static ex f_diff3(const exprseq &e)
1322 {
1323         CHECK_ARG(1, symbol, diff);
1324         CHECK_ARG(2, numeric, diff);
1325         return e[0].diff(ex_to_symbol(e[1]), ex_to_numeric(e[2]).to_int());
1326 }
1327
1328 static ex f_divide(const exprseq &e)
1329 {
1330         ex q;
1331         if (divide(e[0], e[1], q))
1332                 return q;
1333         else
1334                 return *new fail();
1335 }
1336
1337 static ex f_eval2(const exprseq &e)
1338 {
1339         CHECK_ARG(1, numeric, eval);
1340         return e[0].eval(ex_to_numeric(e[1]).to_int());
1341 }
1342
1343 static ex f_evalf2(const exprseq &e)
1344 {
1345         CHECK_ARG(1, numeric, evalf);
1346         return e[0].evalf(ex_to_numeric(e[1]).to_int());
1347 }
1348
1349 static ex f_has(const exprseq &e)
1350 {
1351         return e[0].has(e[1]) ? exONE() : exZERO();
1352 }
1353
1354 static ex f_inverse(const exprseq &e)
1355 {
1356         CHECK_ARG(0, matrix, inverse);
1357         return ex_to_matrix(e[0]).inverse();
1358 }
1359
1360 static ex f_is(const exprseq &e)
1361 {
1362         CHECK_ARG(0, relational, is);
1363         return (bool)ex_to_relational(e[0]) ? exONE() : exZERO();
1364 }
1365
1366 static ex f_lcoeff(const exprseq &e)
1367 {
1368         CHECK_ARG(1, symbol, lcoeff);
1369         return e[0].lcoeff(ex_to_symbol(e[1]));
1370 }
1371
1372 static ex f_ldegree(const exprseq &e)
1373 {
1374         CHECK_ARG(1, symbol, ldegree);
1375         return e[0].ldegree(ex_to_symbol(e[1]));
1376 }
1377
1378 static ex f_normal2(const exprseq &e)
1379 {
1380         CHECK_ARG(1, numeric, normal);
1381         return e[0].normal(ex_to_numeric(e[1]).to_int());
1382 }
1383
1384 static ex f_op(const exprseq &e)
1385 {
1386         CHECK_ARG(1, numeric, op);
1387         int n = ex_to_numeric(e[1]).to_int();
1388         if (n < 0 || n >= e[0].nops())
1389                 throw(std::out_of_range("second argument to op() is out of range"));
1390         return e[0].op(n);
1391 }
1392
1393 static ex f_prem(const exprseq &e)
1394 {
1395         CHECK_ARG(2, symbol, prem);
1396         return prem(e[0], e[1], ex_to_symbol(e[2]));
1397 }
1398
1399 static ex f_primpart(const exprseq &e)
1400 {
1401         CHECK_ARG(1, symbol, primpart);
1402         return e[0].primpart(ex_to_symbol(e[1]));
1403 }
1404
1405 static ex f_quo(const exprseq &e)
1406 {
1407         CHECK_ARG(2, symbol, quo);
1408         return quo(e[0], e[1], ex_to_symbol(e[2]));
1409 }
1410
1411 static ex f_rem(const exprseq &e)
1412 {
1413         CHECK_ARG(2, symbol, rem);
1414         return rem(e[0], e[1], ex_to_symbol(e[2]));
1415 }
1416
1417 static ex f_series2(const exprseq &e)
1418 {
1419         CHECK_ARG(1, symbol, series);
1420         return e[0].series(ex_to_symbol(e[1]), exZERO());
1421 }
1422
1423 static ex f_series3(const exprseq &e)
1424 {
1425         CHECK_ARG(1, symbol, series);
1426         return e[0].series(ex_to_symbol(e[1]), e[2]);
1427 }
1428
1429 static ex f_series4(const exprseq &e)
1430 {
1431         CHECK_ARG(1, symbol, series);
1432         CHECK_ARG(3, numeric, series);
1433         return e[0].series(ex_to_symbol(e[1]), e[2], ex_to_numeric(e[3]).to_int());
1434 }
1435
1436 static ex f_sqrfree(const exprseq &e)
1437 {
1438         CHECK_ARG(1, symbol, sqrfree);
1439         return sqrfree(e[0], ex_to_symbol(e[1]));
1440 }
1441
1442 static ex f_subs3(const exprseq &e)
1443 {
1444         CHECK_ARG(1, lst, subs);
1445         CHECK_ARG(2, lst, subs);
1446         return e[0].subs(ex_to_lst(e[1]), ex_to_lst(e[2]));
1447 }
1448
1449 static ex f_tcoeff(const exprseq &e)
1450 {
1451         CHECK_ARG(1, symbol, tcoeff);
1452         return e[0].tcoeff(ex_to_symbol(e[1]));
1453 }
1454
1455 static ex f_trace(const exprseq &e)
1456 {
1457         CHECK_ARG(0, matrix, trace);
1458         return ex_to_matrix(e[0]).trace();
1459 }
1460
1461 static ex f_transpose(const exprseq &e)
1462 {
1463         CHECK_ARG(0, matrix, transpose);
1464         return ex_to_matrix(e[0]).transpose();
1465 }
1466
1467 static ex f_unassign(const exprseq &e)
1468 {
1469         CHECK_ARG(0, symbol, unassign);
1470         (const_cast<symbol *>(&ex_to_symbol(e[0])))->unassign();
1471         return e[0];
1472 }
1473
1474 static ex f_unit(const exprseq &e)
1475 {
1476         CHECK_ARG(1, symbol, unit);
1477         return e[0].unit(ex_to_symbol(e[1]));
1478 }
1479
1480 static ex f_dummy(const exprseq &e)
1481 {
1482         throw(std::logic_error("dummy function called (shouldn't happen)"));
1483 }
1484
1485
1486 /*
1487  *  Add all registered GiNaC functions to ginsh
1488  */
1489
1490 static ex f_ginac_function(const exprseq &es, int serial)
1491 {
1492         return function(serial, es).eval(1);
1493 }
1494
1495 void ginsh_get_ginac_functions(void)
1496 {
1497         vector<registered_function_info>::const_iterator i = function::registered_functions().begin(), end = function::registered_functions().end();
1498         unsigned serial = 0;
1499         while (i != end) {
1500                 fcns.insert(make_pair(i->name, fcn_desc(f_ginac_function, i->nparams, serial)));
1501                 i++;
1502                 serial++;
1503         }
1504 }
1505
1506
1507 /*
1508  *  Find a function given a name and number of parameters. Throw exceptions on error.
1509  */
1510
1511 static fcn_tab::const_iterator find_function(const ex &sym, int req_params)
1512 {
1513         const string &name = ex_to_symbol(sym).getname();
1514         typedef fcn_tab::const_iterator I;
1515         pair<I, I> b = fcns.equal_range(name);
1516         if (b.first == b.second)
1517                 throw(std::logic_error("unknown function '" + name + "'"));
1518         else {
1519                 for (I i=b.first; i!=b.second; i++)
1520                         if ((i->second.num_params == 0) || (i->second.num_params == req_params))
1521                                 return i;
1522         }
1523         throw(std::logic_error("invalid number of arguments to " + name + "()"));
1524 }
1525
1526
1527 /*
1528  *  Convert list of lists to matrix
1529  */
1530
1531 static ex lst2matrix(const ex &l)
1532 {
1533         if (!is_ex_of_type(l, lst))
1534                 throw(std::logic_error("internal error: argument to lst2matrix() is not a list"));
1535
1536         // Find number of rows and columns
1537         int rows = l.nops(), cols = 0, i, j;
1538         for (i=0; i<rows; i++)
1539                 if (l.op(i).nops() > cols)
1540                         cols = l.op(i).nops();
1541
1542         // Allocate and fill matrix
1543         matrix &m = *new matrix(rows, cols);
1544         for (i=0; i<rows; i++)
1545                 for (j=0; j<cols; j++)
1546                         if (l.op(i).nops() > j)
1547                                 m.set(i, j, l.op(i).op(j));
1548                         else
1549                                 m.set(i, j, exZERO());
1550         return m;
1551 }
1552
1553
1554 /*
1555  *  Function name completion functions for readline
1556  */
1557
1558 static char *fcn_generator(char *text, int state)
1559 {
1560         static int len;                         // Length of word to complete
1561         static fcn_tab::const_iterator index;   // Iterator to function being currently considered
1562
1563         // If this is a new word to complete, initialize now
1564         if (state == 0) {
1565                 index = fcns.begin();
1566                 len = strlen(text);
1567         }
1568
1569         // Return the next function which partially matches
1570         while (index != fcns.end()) {
1571                 const char *fcn_name = index->first.c_str();
1572                 index++;
1573                 if (strncmp(fcn_name, text, len) == 0)
1574                         return strdup(fcn_name);
1575         }
1576         return NULL;
1577 }
1578
1579 static char **fcn_completion(char *text, int start, int end)
1580 {
1581         if (rl_line_buffer[0] == '!') {
1582                 // For shell commands, revert back to filename completion
1583                 rl_completion_append_character = orig_completion_append_character;
1584                 rl_basic_word_break_characters = orig_basic_word_break_characters;
1585                 return completion_matches(text, filename_completion_function);
1586         } else {
1587                 // Otherwise, complete function names
1588                 rl_completion_append_character = '(';
1589                 rl_basic_word_break_characters = " \t\n\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~";
1590                 return completion_matches(text, fcn_generator);
1591         }
1592 }
1593
1594
1595 /*
1596  *  Main program
1597  */
1598
1599 int main(int argc, char **argv)
1600 {
1601         // Print banner in interactive mode
1602         if (isatty(0)) {
1603                 cout << "ginsh - GiNaC Interactive Shell (" << PACKAGE << " " << VERSION << ")\n";
1604                 cout << "Copyright (C) 1999 Johannes Gutenberg Universitaet Mainz, Germany\n";
1605                 cout << "This is free software, and you are welcome to redistribute it\n";
1606                 cout << "under certain conditions; see the file COPYING for details.\n"; 
1607         }
1608
1609         // Init table of built-in functions
1610         fcns.insert(make_pair(string("beta"), fcn_desc(f_beta, 2)));
1611         fcns.insert(make_pair(string("charpoly"), fcn_desc(f_charpoly, 2)));
1612         fcns.insert(make_pair(string("coeff"), fcn_desc(f_coeff, 3)));
1613         fcns.insert(make_pair(string("collect"), fcn_desc(f_collect, 2)));
1614         fcns.insert(make_pair(string("content"), fcn_desc(f_content, 2)));
1615         fcns.insert(make_pair(string("degree"), fcn_desc(f_degree, 2)));
1616         fcns.insert(make_pair(string("denom"), fcn_desc(f_denom, 1)));
1617         fcns.insert(make_pair(string("determinant"), fcn_desc(f_determinant, 1)));
1618         fcns.insert(make_pair(string("diag"), fcn_desc(f_diag, 0)));
1619         fcns.insert(make_pair(string("diff"), fcn_desc(f_diff2, 2)));
1620         fcns.insert(make_pair(string("diff"), fcn_desc(f_diff3, 3)));
1621         fcns.insert(make_pair(string("divide"), fcn_desc(f_divide, 2)));
1622         fcns.insert(make_pair(string("eval"), fcn_desc(f_eval1, 1)));
1623         fcns.insert(make_pair(string("eval"), fcn_desc(f_eval2, 2)));
1624         fcns.insert(make_pair(string("evalf"), fcn_desc(f_evalf1, 1)));
1625         fcns.insert(make_pair(string("evalf"), fcn_desc(f_evalf2, 2)));
1626         fcns.insert(make_pair(string("expand"), fcn_desc(f_expand, 1)));
1627         fcns.insert(make_pair(string("gcd"), fcn_desc(f_gcd, 2)));
1628         fcns.insert(make_pair(string("has"), fcn_desc(f_has, 2)));
1629         fcns.insert(make_pair(string("inverse"), fcn_desc(f_inverse, 1)));
1630         fcns.insert(make_pair(string("is"), fcn_desc(f_is, 1)));
1631         fcns.insert(make_pair(string("lcm"), fcn_desc(f_lcm, 2)));
1632         fcns.insert(make_pair(string("lcoeff"), fcn_desc(f_lcoeff, 2)));
1633         fcns.insert(make_pair(string("ldegree"), fcn_desc(f_ldegree, 2)));
1634         fcns.insert(make_pair(string("lsolve"), fcn_desc(f_lsolve, 2)));
1635         fcns.insert(make_pair(string("nops"), fcn_desc(f_nops, 1)));
1636         fcns.insert(make_pair(string("normal"), fcn_desc(f_normal1, 1)));
1637         fcns.insert(make_pair(string("normal"), fcn_desc(f_normal2, 2)));
1638         fcns.insert(make_pair(string("numer"), fcn_desc(f_numer, 1)));
1639         fcns.insert(make_pair(string("op"), fcn_desc(f_op, 2)));
1640         fcns.insert(make_pair(string("power"), fcn_desc(f_power, 2)));
1641         fcns.insert(make_pair(string("prem"), fcn_desc(f_prem, 3)));
1642         fcns.insert(make_pair(string("primpart"), fcn_desc(f_primpart, 2)));
1643         fcns.insert(make_pair(string("quo"), fcn_desc(f_quo, 3)));
1644         fcns.insert(make_pair(string("rem"), fcn_desc(f_rem, 3)));
1645         fcns.insert(make_pair(string("series"), fcn_desc(f_series2, 2)));
1646         fcns.insert(make_pair(string("series"), fcn_desc(f_series3, 3)));
1647         fcns.insert(make_pair(string("series"), fcn_desc(f_series4, 4)));
1648         fcns.insert(make_pair(string("sqrfree"), fcn_desc(f_sqrfree, 2)));
1649         fcns.insert(make_pair(string("sqrt"), fcn_desc(f_sqrt, 1)));
1650         fcns.insert(make_pair(string("subs"), fcn_desc(f_subs2, 2)));
1651         fcns.insert(make_pair(string("subs"), fcn_desc(f_subs3, 3)));
1652         fcns.insert(make_pair(string("tcoeff"), fcn_desc(f_tcoeff, 2)));
1653         fcns.insert(make_pair(string("time"), fcn_desc(f_dummy, 0)));
1654         fcns.insert(make_pair(string("trace"), fcn_desc(f_trace, 1)));
1655         fcns.insert(make_pair(string("transpose"), fcn_desc(f_transpose, 1)));
1656         fcns.insert(make_pair(string("unassign"), fcn_desc(f_unassign, 1)));
1657         fcns.insert(make_pair(string("unit"), fcn_desc(f_unit, 2)));
1658         ginsh_get_ginac_functions();
1659
1660         // Init readline completer
1661         rl_readline_name = argv[0];
1662         rl_attempted_completion_function = (CPPFunction *)fcn_completion;
1663         orig_completion_append_character = rl_completion_append_character;
1664         orig_basic_word_break_characters = rl_basic_word_break_characters;
1665
1666         // Parse input, catch all remaining exceptions
1667         int result;
1668 again:  try {
1669                 result = yyparse();
1670         } catch (exception &e) {
1671                 cerr << e.what() << endl;
1672                 goto again;
1673         }
1674         return result;
1675 }