diff options
author | Alex AUVOLAT <alexis211@gmail.com> | 2013-06-08 23:09:52 +0200 |
---|---|---|
committer | Alex AUVOLAT <alexis211@gmail.com> | 2013-06-08 23:09:52 +0200 |
commit | 4d65fcb9a8b6c7c6fd5a3390c46a96d11b6a80d4 (patch) | |
tree | c193acf64ff2db985f6664f161cf586c3caeb684 /src/user/app/kbasic/lex.c | |
parent | eae9997d3c2dbaef53022ddabe61c1800a619499 (diff) | |
download | TCE-4d65fcb9a8b6c7c6fd5a3390c46a96d11b6a80d4.tar.gz TCE-4d65fcb9a8b6c7c6fd5a3390c46a96d11b6a80d4.zip |
All FWIK is deleted. YOSH is now pure C. Not-working KBASIC included.
Diffstat (limited to 'src/user/app/kbasic/lex.c')
-rw-r--r-- | src/user/app/kbasic/lex.c | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/src/user/app/kbasic/lex.c b/src/user/app/kbasic/lex.c new file mode 100644 index 0000000..055b502 --- /dev/null +++ b/src/user/app/kbasic/lex.c @@ -0,0 +1,197 @@ +#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}, + + {"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; + return(token_type=DELIMITER); + } + + 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; + return (token_type = DELIMITER); + } + if (*prog_ip=='\n') { /* lf (unix newline) */ + ++prog_ip; + tok = EOL; *token='\n'; token[1] = 0; + return (token_type = DELIMITER); + } + + if(strchr("+-*^/%=;(),><", *prog_ip)){ /* delimiter */ + *temp=*prog_ip; + prog_ip++; /* advance to next position */ + temp++; + *temp=0; + return (token_type=DELIMITER); + } + + 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; + return(token_type=QUOTE); + } + + if(isdigit(*prog_ip)) { /* number */ + while(!isdelim(*prog_ip)) { + if (temp - token < TOK_LEN - 1) *temp++=*prog_ip; + prog_ip++; + } + *temp = '\0'; + return(token_type = NUMBER); + } + + 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 */ + } + 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; +} + + + |