ginsh \- GiNaC Interactive Shell
.SH SYNPOSIS
.B ginsh
+.RI [ file\&... ]
.SH DESCRIPTION
.B ginsh
is an interactive frontend for the GiNaC symbolic computation framework.
.BR + " and " * ,
and functions (e.g.
.BR sin " or " normal ).
-ginsh will evaluate the expression and print the result to stdout. Every
-input expression must be terminated by a semicolon
-.RB ( ; ),
-and it is possible to enter multiple expressions on one line. Whitespace
-(spaces, tabs, newlines) can be applied freely between tokens. To quit ginsh,
-enter
+Every input expression must be terminated with either a semicolon
+.RB ( ; )
+or a colon
+.RB ( : ).
+If terminated with a semicolon, ginsh will evaluate the expression and print
+the result to stdout. If terminated with a colon, ginsh will only evaluate the
+expression but not print the result. It is possible to enter multiple
+expressions on one line. Whitespace (spaces, tabs, newlines) can be applied
+freely between tokens. To quit ginsh, enter
.BR quit " or " exit ,
or type an EOF (Ctrl-D) at the prompt.
.SS NUMBERS
#ifndef GINSH_H
#define GINSH_H
-// yacc semantic type
+// yacc stack type
#define YYSTYPE ex
// lex functions/variables
#else
extern char yytext[];
#endif
+extern FILE *yyin;
+
+// List of input files to be processed
+extern int num_files;
+extern char **file_list;
// Table of all used symbols
typedef map<string, symbol> sym_tab;
extern sym_tab syms;
-// Prototypes for missing functions
-#ifndef HAVE_STRDUP
-extern char *strdup(const char *s);
-#endif
-
#endif
return result;
}
-// Scanner terminates on EOF
+// List of input files to be processed
+int num_files = 0;
+char **file_list = NULL;
+
+// EOF encountered, connect to next file. If this was the last file,
+// connect to stdin. If this was stdin, terminate the scanner.
int yywrap()
{
- return 1;
+ if (yyin == stdin)
+ return 1;
+
+ fclose(yyin);
+ if (num_files) {
+ yyin = fopen(*file_list, "r");
+ if (yyin == NULL) {
+ cerr << "Can't open " << *file_list << endl;
+ return 1;
+ }
+ num_files--;
+ file_list++;
+ } else
+ yyin = stdin;
+ return 0;
}
YYERROR;
}
}
+ | exp ':'
+ {
+ try {
+ push($1);
+ } catch (exception &e) {
+ cerr << e.what() << endl;
+ YYERROR;
+ }
+ }
| T_PRINT '(' exp ')' ';'
{
try {
cout << " out of a possible 350.\n";
}
| error ';' {yyclearin; yyerrok;}
+ | error ':' {yyclearin; yyerrok;}
;
exp : T_NUMBER {$$ = $1;}
orig_completion_append_character = rl_completion_append_character;
orig_basic_word_break_characters = rl_basic_word_break_characters;
+ // Init input file list, open first file
+ num_files = argc - 1;
+ file_list = argv + 1;
+ if (num_files) {
+ yyin = fopen(*file_list, "r");
+ if (yyin == NULL) {
+ cerr << "Can't open " << *file_list << endl;
+ exit(1);
+ }
+ num_files--;
+ file_list++;
+ }
+
// Parse input, catch all remaining exceptions
int result;
again: try {