home *** CD-ROM | disk | FTP | other *** search
- /*
- * parse.c logo parser module dvb
- *
- * Copyright (C) 1993 by the Regents of the University of California
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- */
-
- #ifdef WIN32
- #include <windows.h>
- #endif
-
- #include "logo.h"
- #include "globals.h"
-
- #ifdef HAVE_TERMIO_H
- #include <termio.h>
- #else
- #ifdef HAVE_SGTTY_H
- #include <sgtty.h>
- #endif
- #endif
-
- #include <ctype.h>
-
- #ifdef ibm
- #ifndef _MSC_VER
- #include <bios.h>
- extern int getch(void);
- #endif /* _MSC_VER */
- #endif
- #ifdef __ZTC__
- #include <disp.h>
- #endif
-
- #if defined(__PPC__) && defined(AMIGA)
-
- #define __USE_SYSBASE
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <powerup/ppclib/interface.h>
- #include <powerup/gcclib/powerup_protos.h>
-
- #define AllocVec(n, f) PPCAllocVec(n, f)
- #define FreeVec(b) PPCFreeVec(b)
-
- #endif
-
- FILE *readstream = stdin;
- FILE *writestream = stdout;
- FILE *loadstream = stdin;
- FILE *dribblestream = NULL;
- int input_blocking = 0;
- NODE *deepend_proc_name = NIL;
-
- #ifdef AMIGA
- int rd_getc(FILE *strm)
- {
- int c;
-
- /*
- CTRL-C and CTRL-D are only used to stop and pause,
- so they shouldn't ever reach the reader functions.
- */
- if (strm==stdin && console!=NULL)
- do
- c = FGetC(console);
- while (c=='\003' || c=='\004');
- else
- c = getc(strm);
- if (strm == stdin && c != EOF)
- update_coords(c);
- return(c);
- }
- #else
-
- int rd_getc(FILE *strm) {
- int c;
- #ifdef WIN32
- MSG msg;
- #endif
-
- #ifndef WIN32 /* skip this section ... */
- #ifdef __ZTC__
- if (strm == stdin) zflush();
- c = ztc_getc(strm);
- #else
- c = getc(strm);
- #endif
- if (strm == stdin && c != EOF) update_coords(c);
- #ifdef ibm
- if (c == 17 && interactive && strm==stdin) { /* control-q */
- to_pending = 0;
- err_logo(STOP_ERROR,NIL);
- }
- if (c == 23 && interactive && strm==stdin) { /* control-w */
- #ifndef __ZTC__
- getc(strm); /* eat up the return */
- #endif
-
- #if defined(__ZTC__) || defined(WIN32)
- logo_pause(0);
- #else
- logo_pause();
- #endif
-
- return(rd_getc(strm));
- }
- #endif
- #else /* WIN32 */
- if (strm == stdin) {
- if (!line_avail) {
- win32_text_cursor();
- while (GetMessage(&msg, NULL, 0, 0)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- if (line_avail)
- break;
- }
- }
- c = read_line[read_index++];
- if (c == 17 && interactive && strm==stdin) { /* control-q */
- to_pending = 0;
- err_logo(STOP_ERROR,NIL);
- line_avail = 0;
- return('\n');
- }
- if (c == 23 && interactive && strm==stdin) { /* control-w */
- line_avail = 0;
- logo_pause(0);
- return(rd_getc(strm));
- }
- if (c == '\n')
- line_avail = 0;
- }
- else /* reading from a file */
- c = getc(strm);
- #endif /* WIN32 */
-
- #ifdef ecma
- return(ecma_clear(c));
- #else
- return(c);
- #endif
- }
-
- #endif /* AMIGA */
-
-
- void rd_print_prompt(char *str) {
- #ifdef ibm
- #if defined(__ZTC__) || defined(WIN32)
- if (in_graphics_mode && !in_splitscreen)
- #else
- #ifndef _MSC_VER
- if (in_graphics_mode && ibm_screen_top == 0)
- #endif /* _MSC_VER */
- #endif
- lsplitscreen(NIL);
- #endif
- ndprintf(stdout,"%t",str);
- #if defined(__ZTC__) && !defined(WIN32) /* sowings */
- zflush();
- #endif
- #ifdef AMIGA
- if (console)
- Flush(console);
- #endif
- }
-
- #if defined(__ZTC__) && !defined(WIN32) /* sowings */
- void zrd_print_prompt(char *str) {
- newline_bugfix();
- rd_print_prompt(str);
- }
- #else
- #define zrd_print_prompt rd_print_prompt
- #endif
-
- #define into_line(chr) {if (phys_line >= p_end) { \
- p_len += MAX_PHYS_LINE; \
- p_pos = phys_line - p_line; \
- p_line = realloc(p_line, p_len); \
- p_end = &p_line[p_len-1]; \
- phys_line = &p_line[p_pos]; \
- } \
- *phys_line++ = (chr);}
-
- char *p_line = 0, *p_end;
- int p_len = MAX_PHYS_LINE;
-
- NODE *reader(FILE *strm, char *prompt) {
- int c = 0, dribbling, vbar = 0, paren = 0;
- int bracket = 0, brace = 0, p_pos, contin=1;
- static char ender[] = "\nEND\n";
- char *phys_line, *lookfor = ender;
- NODETYPES this_type = STRING;
- NODE *ret;
-
- #ifdef AMIGA
- if (strm==stdin)
- SetMode(console,0); /* turn buffering on */
- #endif
- if (!strcmp(prompt, "RW")) { /* called by readword */
- prompt = "";
- contin = 0;
- }
- charmode_off();
- #ifdef WIN32
- dribbling = 0;
- #else
- dribbling = (dribblestream != NULL && strm == stdin);
- #endif
- if (p_line == 0) {
- p_line = malloc(MAX_PHYS_LINE);
- if (p_line == NULL) {
- err_logo(OUT_OF_MEM, NIL);
- return UNBOUND;
- }
- p_end = &p_line[MAX_PHYS_LINE-1];
- }
- phys_line = p_line;
- if (strm == stdin && *prompt) {
- if (interactive) {
- rd_print_prompt(prompt);
- #ifdef WIN32
- win32_update_text();
- #endif
- }
- }
- if (strm == stdin) {
- input_blocking++;
- erract_errtype = FATAL;
- }
-
- #ifndef TIOCSTI
- if (!setjmp(iblk_buf)) {
- #endif
- c = rd_getc(strm);
- while (c != EOF && (vbar || paren || bracket || brace || c != '\n')) {
- if (dribbling) rd_putc(c, dribblestream);
- if (c == '\\' && (c = rd_getc(strm)) != EOF) {
- if (dribbling) rd_putc(c, dribblestream);
- c = setparity(c);
- this_type = BACKSLASH_STRING;
- if (c == setparity('\n') && strm == stdin) {
- if (interactive) zrd_print_prompt("\\ ");
- }
- }
- if (c != EOF) into_line(c);
- if (*prompt && (c&0137) == *lookfor) {
- lookfor++;
- if (*lookfor == 0) {
- err_logo(DEEPEND, deepend_proc_name);
- break;
- }
- } else lookfor = ender;
- if (c == '|') {
- vbar = !vbar;
- this_type = VBAR_STRING;
- } else if (contin && !vbar) {
- if (c == '(') paren++;
- else if (paren && c == ')') paren--;
- else if (c == '[') bracket++;
- else if (bracket && c == ']') bracket--;
- else if (c == '{') brace++;
- else if (brace && c == '}') brace--;
- }
-
- if (this_type == STRING && strchr(special_chars, c))
- this_type = VBAR_STRING;
- if (/* (vbar || paren ...) && */ c == '\n') {
- if (strm == stdin) {
- if (interactive) zrd_print_prompt(vbar ? "| " : "~ ");
- }
- }
- while (!vbar && c == '~' && (c = rd_getc(strm)) != EOF) {
- while (c == ' ' || c == '\t')
- c = rd_getc(strm);
- if (dribbling) rd_putc(c, dribblestream);
- into_line(c);
- if (c == '\n' && strm == stdin) {
- if (interactive) zrd_print_prompt("~ ");
- }
- }
- if (c != EOF) c = rd_getc(strm);
- }
- #ifndef TIOCSTI
- }
- #endif
- *phys_line = '\0';
- input_blocking = 0;
- #if defined(__ZTC__) && !defined(WIN32) /* sowings */
- fix_cursor();
- if (interactive && strm == stdin) newline_bugfix();
- #endif
- if (dribbling)
- rd_putc('\n', dribblestream);
- if (c == EOF && strm == stdin) {
- if (interactive) clearerr(stdin);
- rd_print_prompt("\n");
- }
- #ifdef AMIGA
- if (strm==stdin)
- SetMode(console,1); /* turn buffering off */
- #endif
- if (phys_line == p_line) return(Null_Word); /* so emptyp works */
- ret = make_strnode(p_line, (struct string_block *)NULL, (int)strlen(p_line),
- this_type, strnzcpy);
- return(ret);
- }
-
- NODE *list_to_array(NODE *list) {
- NODE *np = list, *result;
- int len = 0, i;
-
- for (; np; np = cdr(np)) len++;
-
- result = make_array(len);
- setarrorg(result,1);
-
- for (i = 0, np = list; np; np = cdr(np))
- (getarrptr(result))[i++] = car(np);
-
- return(result);
- }
-
- #define parens(ch) (ch == '(' || ch == ')' || ch == ';')
- #define infixs(ch) (ch == '*' || ch == '/' || ch == '+' || ch == '-' || ch == '=' || ch == '<' || ch == '>')
- #define white_space(ch) (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\0')
-
- NODE *parser_iterate(char **inln, char *inlimit, struct string_block *inhead,
- BOOLEAN semi, int endchar) {
- char ch, *wptr = NULL;
- static char terminate = '\0'; /* KLUDGE */
- NODE *outline = NIL, *lastnode = NIL, *tnode = NIL;
- int windex = 0, vbar = 0;
- NODETYPES this_type = STRING;
- BOOLEAN broken = FALSE;
-
- do {
- /* get the current character and increase pointer */
- ch = **inln;
- if (!vbar && windex == 0) wptr = *inln;
- if (++(*inln) >= inlimit) *inln = &terminate;
-
- /* skip through comments and line continuations */
- while (!vbar && ((semi && ch == ';') ||
- #ifdef WIN32
- (ch == '~' && (**inln == 012 || **inln == 015)))) {
- while (ch == '~' && (**inln == 012 || **inln == 015)) {
- #else
- (ch == '~' && **inln == '\n'))) {
- while (ch == '~' && **inln == '\n') {
- #endif
- if (++(*inln) >= inlimit) *inln = &terminate;
- ch = **inln;
- if (windex == 0) wptr = *inln;
- else {
- if (**inln == ']' || **inln == '[' ||
- **inln == '{' || **inln == '}') {
- ch = ' ';
- break;
- } else {
- broken = TRUE;
- }
- }
- if (++(*inln) >= inlimit) *inln = &terminate;
- }
-
- if (semi && ch == ';') {
- #ifdef WIN32
- if (**inln != 012 && **inln != 015)
- #else
- if (**inln != '\n')
- #endif
- do {
- ch = **inln;
- if (windex == 0) wptr = *inln;
- else broken = TRUE;
- if (++(*inln) >= inlimit) *inln = &terminate;
- }
- #ifdef WIN32
- while (ch != '\0' && ch != '~' && **inln != 012 && **inln != 015);
- #else /* !Win32 */
- while (ch != '\0' && ch != '~' && **inln != '\n');
- #endif
- if (ch != '\0' && ch != '~') ch = '\n';
- }
- }
-
- /* flag that this word will be of BACKSLASH_STRING type */
- if (getparity(ch)) this_type = BACKSLASH_STRING;
-
- if (ch == '|') {
- vbar = !vbar;
- this_type = VBAR_STRING;
- broken = TRUE; /* so we'll copy the chars */
- }
-
- else if (vbar || (!white_space(ch) && ch != ']' &&
- ch != '{' && ch != '}' && ch != '['))
- windex++;
-
- if (vbar) continue;
-
- else if (ch == endchar) break;
-
- else if (ch == ']') err_logo(UNEXPECTED_BRACKET, NIL);
- else if (ch == '}') err_logo(UNEXPECTED_BRACE, NIL);
-
- /* if this is a '[', parse a new list */
- else if (ch == '[') {
- tnode = cons(parser_iterate(inln,inlimit,inhead,semi,']'), NIL);
- if (**inln == '\0') ch = '\0';
- }
-
- else if (ch == '{') {
- tnode = cons(list_to_array
- (parser_iterate(inln,inlimit,inhead,semi,'}')), NIL);
- if (**inln == '@') {
- int i = 0, sign = 1;
-
- (*inln)++;
- if (**inln == '-') {
- sign = -1;
- (*inln)++;
- }
- while ((ch = **inln) >= '0' && ch <= '9') {
- i = (i*10) + ch - '0';
- (*inln)++;
- }
- setarrorg(car(tnode),sign*i);
- }
- if (**inln == '\0') ch = '\0';
- }
-
- /* if this character or the next one will terminate string, make the word */
- else if (white_space(ch) || **inln == ']' || **inln == '[' ||
- **inln == '{' || **inln == '}') {
- if (windex > 0) {
- if (broken == FALSE)
- tnode = cons(make_strnode(wptr, inhead, windex,
- this_type, strnzcpy),
- NIL);
- else {
- tnode = cons(make_strnode(wptr,
- (struct string_block *)NULL, windex,
- this_type, (semi ? mend_strnzcpy : mend_nosemi)),
- NIL);
- broken = FALSE;
- }
- this_type = STRING;
- windex = 0;
- }
- }
-
- /* put the word onto the end of the return list */
- if (tnode != NIL) {
- if (outline == NIL) outline = tnode;
- else setcdr(lastnode, tnode);
- lastnode = tnode;
- tnode = NIL;
- }
- } while (ch);
- return(outline);
- }
-
- NODE *parser(NODE *nd, BOOLEAN semi) {
- NODE *rtn;
- int slen;
- char *lnsav;
-
- rtn = cnv_node_to_strnode(nd);
- slen = getstrlen(rtn);
- lnsav = getstrptr(rtn);
- rtn = parser_iterate(&lnsav,lnsav + slen,getstrhead(rtn),semi,-1);
- return(rtn);
- }
-
- NODE *lparse(NODE *args) {
- NODE *arg, *val = UNBOUND;
-
- arg = string_arg(args);
- if (NOT_THROWING) {
- val = parser(arg, FALSE);
- }
- return(val);
- }
-
- NODE *runparse_node(NODE *nd, NODE **ndsptr) {
- NODE *outline = NIL, *tnode = NIL, *lastnode = NIL, *snd;
- char *wptr, *tptr;
- struct string_block *whead;
- int wlen, wcnt, tcnt, isnumb, gotdot;
- NODETYPES wtyp;
- BOOLEAN monadic_minus = FALSE;
-
- if (nd == Minus_Tight) return cons(nd, NIL);
- snd = cnv_node_to_strnode(nd);
- wptr = getstrptr(snd);
- wlen = getstrlen(snd);
- wtyp = nodetype(snd);
- wcnt = 0;
- whead = getstrhead(snd);
-
- while (wcnt < wlen) {
- if (*wptr == ';') {
- *ndsptr = NIL;
- break;
- }
- if (*wptr == '"') {
- tcnt = 0;
- tptr = ++wptr;
- wcnt++;
- while (wcnt < wlen && !parens(*wptr)) {
- if (wtyp == BACKSLASH_STRING && getparity(*wptr))
- wtyp = PUNBOUND; /* flag for "\( case */
- wptr++, wcnt++, tcnt++;
- }
- if (wtyp == PUNBOUND) {
- wtyp = BACKSLASH_STRING;
- tnode = cons(make_quote(intern(make_strnode(tptr, NULL,
- tcnt, wtyp, noparity_strnzcpy))), NIL);
- } else
- tnode = cons(make_quote(intern(make_strnode(tptr, whead, tcnt,
- wtyp, strnzcpy))), NIL);
- } else if (*wptr == ':') {
- tcnt = 0;
- tptr = ++wptr;
- wcnt++;
- while (wcnt < wlen && !parens(*wptr) && !infixs(*wptr))
- wptr++, wcnt++, tcnt++;
- tnode = cons(make_colon(intern(make_strnode(tptr, whead, tcnt,
- wtyp, strnzcpy))), NIL);
- } else if (wcnt == 0 && *wptr == '-' && monadic_minus == FALSE &&
- wcnt+1 < wlen && !white_space(*(wptr+1))) {
- /* minus sign with space before and no space after is unary */
- tnode = cons(make_intnode((FIXNUM)0), NIL);
- monadic_minus = TRUE;
- } else if (parens(*wptr) || infixs(*wptr)) {
- if (monadic_minus)
- tnode = cons(Minus_Tight, NIL);
- else
- tnode = cons(intern(make_strnode(wptr, whead, 1,
- STRING, strnzcpy)), NIL);
- monadic_minus = FALSE;
- wptr++, wcnt++;
- } else {
- tcnt = 0;
- tptr = wptr;
- /* isnumb 4 means nothing yet;
- * 0 means digits so far, 1 means just saw
- * 'e' so minus can be next, 2 means no longer
- * eligible even if an 'e' comes along */
- isnumb = 4;
- gotdot = 0;
- if (*wptr == '?') {
- isnumb = 3; /* turn ?5 to (? 5) */
- wptr++, wcnt++, tcnt++;
- }
- while (wcnt < wlen && !parens(*wptr) &&
- (!infixs(*wptr) || (isnumb == 1 && (*wptr == '-' || *wptr == '+')))) {
- if (isnumb == 4 && isdigit(*wptr)) isnumb = 0;
- if (isnumb == 0 && tcnt > 0 && (*wptr == 'e' || *wptr == 'E'))
- isnumb = 1;
- else if (!(isdigit(*wptr) || (!gotdot && *wptr == '.')) || isnumb == 1)
- isnumb = 2;
- if (*wptr == '.') gotdot++;
- wptr++, wcnt++, tcnt++;
- }
- if (isnumb == 3 && tcnt > 1) { /* ?5 syntax */
- NODE *qmtnode;
-
- qmtnode = cons_list(0, Left_Paren, Query,
- cnv_node_to_numnode
- (make_strnode(tptr+1, whead,
- tcnt-1, wtyp, strnzcpy)),
- END_OF_LIST);
- if (outline == NIL) {
- outline = qmtnode;
- } else {
- setcdr(lastnode, qmtnode);
- }
- lastnode = cddr(qmtnode);
- tnode = cons(Right_Paren, NIL);
- } else if (isnumb < 2 && tcnt > 0) {
- tnode = cons(cnv_node_to_numnode(make_strnode(tptr, whead, tcnt,
- wtyp, strnzcpy)),
- NIL);
- } else
- tnode = cons(intern(make_strnode(tptr, whead, tcnt,
- wtyp, strnzcpy)),
- NIL);
- }
-
- if (outline == NIL) outline = tnode;
- else setcdr(lastnode, tnode);
- lastnode = tnode;
- }
- return(outline);
- }
-
- NODE *runparse(NODE *ndlist) {
- NODE *curnd = NIL, *outline = NIL, *tnode = NIL, *lastnode = NIL;
-
- if (nodetype(ndlist) == RUN_PARSE)
- return parsed__runparse(ndlist);
- if (!is_list(ndlist)) {
- err_logo(BAD_DATA_UNREC, ndlist);
- return(NIL);
- }
- while (ndlist != NIL) {
- curnd = car(ndlist);
- ndlist = cdr(ndlist);
- if (!is_word(curnd))
- tnode = cons(curnd, NIL);
- else {
- if (!numberp(curnd))
- tnode = runparse_node(curnd, &ndlist);
- else
- tnode = cons(cnv_node_to_numnode(curnd), NIL);
- }
- if (tnode != NIL) {
- if (outline == NIL) outline = tnode;
- else setcdr(lastnode, tnode);
- lastnode = tnode;
- while (cdr(lastnode) != NIL) {
- lastnode = cdr(lastnode);
- if (check_throwing) break;
- }
- }
- if (check_throwing) break;
- }
- return(outline);
- }
-
- NODE *lrunparse(NODE *args) {
- NODE *arg;
-
- arg = car(args);
- while (nodetype(arg) == ARRAY && NOT_THROWING) {
- setcar(args, err_logo(BAD_DATA, arg));
- arg = car(args);
- }
- if (NOT_THROWING && !aggregate(arg))
- arg = parser(arg, TRUE);
- if (NOT_THROWING)
- return runparse(arg);
- return UNBOUND;
- }
-