#include #include #include #include #include "basic.h" struct commands { /* keyword lookup table */ char command[20]; char tok; } table[] = { /* Commands must be entered lowercase */ {"print", PRINT}, /* in this table. */ {"input", INPUT}, {"color", COLOR}, {"if", IF}, {"then", THEN}, {"goto", GOTO}, {"for", FOR}, {"next", NEXT}, {"to", TO}, {"gosub", GOSUB}, {"return", RETURN}, {"end", END}, {"run", RUN}, {"load", LOAD}, {"list", LIST}, {"exec", EXEC}, {"rnd", RND}, {"", END} /* mark end of table */ }; char token[TOK_LEN]; int token_type, tok; int look_up(char *s); // lookup keyword int iswhite(char c); int isdelim(char c); /* Load a file into a buffer. */ char* load_file(char *fname) { FILE *fp; char *p; int size; if(!(fp=fopen(fname, "rb"))) return 0; // Get file size fseek(fp, 0, SEEK_END); size = ftell(fp); p = (char*)malloc(size + 2); fseek(fp, 0, SEEK_SET); // Read file contents fread(p, size, 1, fp); fclose(fp); /* null terminate the program */ if (p[size-1] != '\n') p[size++] = '\n'; p[size] = 0; return p; } /* Find the start of the next line. */ void find_eol() { while(*prog_ip!='\n' && *prog_ip!='\0') ++prog_ip; if(*prog_ip) prog_ip++; } /* Get a token. */ int get_token() { register char *temp; token_type=0; tok=0; temp=token; if(*prog_ip=='\0') { /* end of file */ *token=0; tok = FINISHED; token_type=DELIMITER; goto get_tok_end; } while(iswhite(*prog_ip)) ++prog_ip; /* skip over white space */ if(*prog_ip=='\r') { /* crlf */ ++prog_ip; ++prog_ip; tok = EOL; *token='\r'; token[1]='\n'; token[2]=0; token_type = DELIMITER; goto get_tok_end; } if (*prog_ip=='\n') { /* lf (unix newline) */ ++prog_ip; tok = EOL; *token='\n'; token[1] = 0; token_type = DELIMITER; goto get_tok_end; } if(strchr("+-*^/%=;(),><", *prog_ip)){ /* delimiter */ *temp=*prog_ip; prog_ip++; /* advance to next position */ temp++; *temp=0; token_type=DELIMITER; goto get_tok_end; } if(*prog_ip=='"') { /* quoted string */ prog_ip++; while(*prog_ip!='"'&& *prog_ip!='\r' && *prog_ip!='\n') { if (temp - token < TOK_LEN - 1) *temp++=*prog_ip; prog_ip++; } if(*prog_ip=='\r' || *prog_ip=='\n') serror(1); prog_ip++;*temp=0; token_type=QUOTE; goto get_tok_end; } if(isdigit(*prog_ip)) { /* number */ while(!isdelim(*prog_ip)) { if (temp - token < TOK_LEN - 1) *temp++=*prog_ip; prog_ip++; } *temp = '\0'; token_type = NUMBER; goto get_tok_end; } if(isalpha(*prog_ip)) { /* var or command */ while(!isdelim(*prog_ip)) { if (temp - token < TOK_LEN - 1) *temp++=*prog_ip; prog_ip++; } token_type=STRING; } *temp = '\0'; /* see if a string is a command or a variable */ if(token_type==STRING) { tok=look_up(token); /* convert to internal rep */ if(!tok) token_type = VARIABLE; else token_type = COMMAND; /* is a command */ } get_tok_end: //printf("[%d.%d.%s]", token_type, tok, token); return token_type; } /* Return a token to input stream. */ void putback() { char *t; t = token; for(; *t; t++) prog_ip--; } /* Look up a a token's internal representation in the token table. */ int look_up(char *s) { register int i; char *p; /* convert to lowercase */ p = s; while(*p){ *p = tolower(*p); p++; } /* see if token is in table */ for(i=0; *table[i].command; i++) if(!strcmp(table[i].command, s)) return table[i].tok; return 0; /* unknown command */ } /* Return true if c is a delimiter. */ int isdelim(char c) { if(strchr(" ;,+-<>/*%^=()", c) || c==9 || c=='\r' || c=='\n' || c==0) return 1; return 0; } /* Return 1 if c is space or tab. */ int iswhite(char c) { if(c==' ' || c=='\t') return 1; else return 0; }