#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#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;
}