home *** CD-ROM | disk | FTP | other *** search
- /*
- * parser.c - grasp language file parser.
- *
- * Copyright (c) 1991 by Patrick J. Naughton
- */
-
- #pragma segment Parser
-
- #include "grasp.h"
-
- char *tokens[] = {
- "notoken",
- "box",
- "break",
- "call",
- "cfade",
- "cfree",
- "cgetbuf",
- "chgcolor",
- "circle",
- "clearscr",
- "cload",
- "closegl",
- "color",
- "cycle",
- "data",
- "databegin",
- "dataend",
- "dataskip",
- "dfree",
- "dload",
- "edge",
- "else",
- "endlfloat",
- "endif",
- "exec",
- "exit",
- "ffree",
- "fgaps",
- "fload",
- "float",
- "fly",
- "font",
- "fstyle",
- "getcolor",
- "getkey",
- "gosub",
- "goto",
- "if",
- "ifkey",
- "ifmem",
- "ifmouse",
- "ifvideo",
- "int",
- "line",
- "link",
- "local",
- "loop",
- "mark",
- "merge",
- "mode",
- "mouse",
- "move",
- "noise",
- "note",
- "offset",
- "opengl",
- "out",
- "palette",
- "pan",
- "pfade",
- "pfree",
- "pgetbuf",
- "pload",
- "pnewbuf",
- "point",
- "poke",
- "pokel",
- "pokew",
- "pop",
- "position",
- "psave",
- "psetbuf",
- "putoff",
- "putup",
- "rect",
- "resetgl",
- "resetscr",
- "return",
- "revpage",
- "send",
- "set",
- "setcolor",
- "setpage",
- "setrgb",
- "setupscr",
- "split",
- "spread",
- "text",
- "tile",
- "timer",
- "tran",
- "video",
- "waitkey",
- "when",
- "window",
- "fade",
- "wait",
- };
-
- static char *
- sows(ptr)
- char *ptr;
- {
- int incomment = 0;
-
- while (incomment || *ptr == ' ' || *ptr == '\t' || *ptr == '\r' ||
- *ptr == ',' || *ptr == ';') {
- if (*ptr == ';')
- incomment = 1;
- else if (*ptr == '\n')
- break;
- ptr++;
- }
- return ptr;
- }
-
- static char *
- sowsanl(ptr)
- char *ptr;
- {
- int incomment = 0;
-
- while (incomment || *ptr == ' ' || *ptr == '\t' || *ptr == '\r' ||
- *ptr == ',' || *ptr == ';' || *ptr == '\n') {
- if (*ptr == ';')
- incomment = 1;
- else if (*ptr == '\n')
- incomment = 0;
- ptr++;
- }
- return ptr;
- }
-
- static char *
- copytoken(src, dst)
- char *src;
- char *dst;
- {
- src = sowsanl(src);
- if (*src == '"') {
- src++;
- while (*src != '"' && *src != '\n' && *src != '\r')
- *dst++ = *src++;
- if (*src != '\n')
- src++;
- } else
- while (*src != ' ' && *src != '\t' && *src != '\r' &&
- *src != ',' && *src != '\n' && *src != 26) {
- if (*src >= 'A' && *src <= 'Z')
- *dst++ = *src++ + 'a' - 'A'; /* tolower */
- else
- *dst++ = *src++;
- }
- *dst = 0;
- src = sows(src);
- return src;
- }
-
- static int
- lookuptoken(ptr)
- char *ptr;
- {
- int i;
-
- if (ptr[strlen(ptr) - 1] != ':')
- for (i = 1; i < NTOKENS; i++)
- if (!strcmp(ptr, tokens[i]))
- return i;
-
- return NOTOKEN;
- }
-
- static int
- tokentoint(s, ret)
- char *s;
- int *ret;
- {
- int i;
- for (i = 0; i < strlen(s); i++)
- if (!isdigit(s[i]) && s[i] != '-')
- return 0;
- sscanf(s, "%d", ret);
- return 1;
- }
-
- static void
- addlabel(ex, s)
- ExecStruct *ex;
- char *s;
- {
- ex->label[ex->numlabels].string = strdup(s);
- ex->label[ex->numlabels].ipaddr = ex->numcodes;
- if (++(ex->numlabels) >= MAXLABELS)
- error("%s: too many labels!");
- }
-
- static void
- addargcount(ex, tokenaddr)
- ExecStruct *ex;
- int tokenaddr;
- {
- ex->Code[tokenaddr].val.i = ex->numcodes - tokenaddr - 1;
- }
-
- static void
- addtoken(ex, t)
- ExecStruct *ex;
- int t;
- {
- ex->Code[ex->numcodes].token = t;
- if (++(ex->numcodes) >= MAXCODES)
- error("%s: text file too large. can only have %d tokens\n", MAXCODES);
- }
-
- static void
- addstring(ex, string)
- ExecStruct *ex;
- char *string;
- {
- ex->Code[ex->numcodes].val.s = strdup(string);
- addtoken(ex, STRING);
- }
-
- static void
- addint(token, arg, ex, string, integer)
- int token;
- int arg;
- ExecStruct *ex;
- char *string;
- int integer;
- {
- /*
- * make sure we don't convert a string that happens to parse as a number
- * such as a filename, or keyname, or video mode, into an integer
- */
- if (((token == CLOAD || token == PLOAD || token == FLOAD)
- && (arg == 1))
- || (token == TEXT && arg == 3)
- || (token == VIDEO || token == IFKEY))
- addstring(ex, string);
- else {
- ex->Code[ex->numcodes].val.i = integer;
- addtoken(ex, INTEGER);
- }
- }
-
- void
- parsefile(ex, ptr)
- ExecStruct *ex;
- char *ptr;
- {
- char buffer[100];
- int tokenaddr;
-
- ex->numcodes = 0;
- ex->numlabels = 0;
- do {
- int i;
- int token;
-
- ptr = copytoken(ptr, buffer);
- if (buffer[0] == 0)
- break;
- if (buffer[strlen(buffer) - 1] == ':') {
- buffer[strlen(buffer) - 1] = 0;
- addlabel(ex, buffer);
- while (*ptr != '\n' && *ptr != 26)
- ptr++;
- } else {
- int range;
- int start;
-
- token = lookuptoken(buffer);
- if (token == NOTOKEN) {
- if (tokentoint(buffer, &i))
- addint(token, 0, ex, buffer, i);
- else
- addstring(ex, buffer);
- tokenaddr = -1;
- } else {
- tokenaddr = ex->numcodes;
- addtoken(ex, token);
- }
-
- range = 0;
- while (*ptr != '\n' && *ptr != 26) {
- int arg = ex->numcodes - tokenaddr;
- ptr = copytoken(ptr, buffer);
- if (range) {
- if (tokentoint(buffer, &i)) {
- int val;
- if (i >= start)
- for (val = start; val <= i; val++)
- addint(token, arg, ex, buffer, val);
- else
- for (val = start; val >= i; val--)
- addint(token, arg, ex, buffer, val);
- range = 0;
- } else
- error("%s: parse error on int range\n");
-
- } else {
- if (buffer[0] == '-' && buffer[1] == 0) {
- range = 1;
- } else {
- if (tokentoint(buffer, &i)) {
- addint(token, arg, ex, buffer, i);
- start = i;
- } else
- addstring(ex, buffer);
- }
- }
- }
- if (tokenaddr != -1)
- addargcount(ex, tokenaddr);
- }
-
- if (*ptr == 26)
- break;
- ptr++;
- } while (*ptr != 26);
- }
-