summaryrefslogblamecommitdiff
path: root/src/user/app/kbasic/lex.c
blob: 5d3487be62f1bc78ecbfab45de7614648f3bccf9 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13












                                                      
                         








































































                                                           

                                     







                                                                        

                                       



                                                       

                                       






                                                              

                                     









                                                                         

                                 







                                                                         

                                    

















                                                                         



                                                       

















































                                                                              
#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;
}