#include "const.h" #include "scan.h" #include "ctype.h" #include "string.h" #include "utils.h" #include "io.h" void scanner_init( Scanner *s, char *src ) { s->src = src; scanner_reset( s ); } void scanner_reset( Scanner *s ) { s->peek = ' '; s->row = 1; s->col = 1; s->pos = s->src; } void scanner_done( Scanner *s ) { } static char get_char( Scanner *s ) { char c; c = *s->pos; s->pos++; s->peek = c; return c; } static void skip_whitespace( Scanner *s ) { for( ; ; get_char( s ) ) { s->col++; if( s->peek == ' ' || s->peek == '\t' ) { continue; } else if( s->peek == '\n' ) { s->row++; s->col = 1; break; } else if( s->peek == '\0' ) { break; } else { break; } } } void scanner_skip_line( Scanner *s ) { while( s->peek != '\0' && s->peek != '\n' ) { s->col++; get_char( s ); } if( s->peek == '\n' ) { s->col++; } } Symbol get_int( Scanner *s ) { Symbol sym; sym.sym = S_number; sym.data.n = 0; do { sym.data.n = sym.data.n * 10 + ( s->peek - '0' ); get_char( s ); } while( s->peek != '\0' && isdigit( s->peek ) ); return sym; } Symbol get_ident_or_label( Scanner *s ) { Symbol newSym; char *p; newSym.sym = S_ident; newSym.data.s[0] = '\0'; p = newSym.data.s; do { *p++ = s->peek; get_char( s ); } while( ( isalnum( s->peek ) || s->peek == '_' ) && !isspace( s->peek ) && ( s->peek != '\0' ) && ( s->peek != ':' ) && ( p - newSym.data.s < MAX_IDENT_LEN ) ); if( s->peek == ':' ) { newSym.sym = S_label; get_char( s ); } *p = '\0'; return newSym; } Symbol scanner_scan( Scanner *s ) { Symbol sym; if( s->peek == '\0' ) { sym.sym = S_eof; if( s->debug ) { print( "SCANNER(EOF)" ); } return sym; } skip_whitespace( s ); if( s->peek == '\0' ) { sym.sym = S_eof; if( s->debug ) { print( "SCANNER(EOF)" ); } return sym; } if( isdigit( s->peek ) ) { sym = get_int( s ); if( s->debug ) { char buf[MAX_TMP_LEN]; char buf2[MAX_TMP_LEN]; buf[0] = '\0'; strcat( buf, "SCANNER(NUMBER," ); inttohex( sym.data.n, buf2 ); strcat( buf, buf2 ); strcat( buf, ")" ); print( buf ); } return sym; } else if( isalpha( s->peek ) ) { sym = get_ident_or_label( s ); if( s->debug ) { char buf[MAX_TMP_LEN]; buf[0] = '\0'; if( sym.sym == S_ident ) { strcat( buf, "SCANNER(IDENT," ); } else if( sym.sym == S_label ) { strcat( buf, "SCANNER(LABEL," ); } else { strcat( buf, "SCANNER(," ); } strcat( buf, sym.data.s ); strcat( buf, ")" ); print( buf ); } return sym; } else if( s->peek == '\n' ) { sym.sym = S_newline; if( s->debug ) { print( "SCANNER(NEWLINE)" ); } s->peek = ' '; return sym; } else if( s->peek == ';' ) { sym.sym = S_comment; if( s->debug ) { print( "SCANNER(COMMENT)" ); } s->peek = ' '; return sym; } else { sym.sym = S_token; sym.tag = s->peek; s->peek = ' '; if( s->debug ) { char buf[MAX_TMP_LEN]; char buf2[MAX_TMP_LEN]; buf[0] = '\0'; strcat( buf, "SCANNER(TOKEN," ); inttohex( sym.tag, buf2 ); strcat( buf, buf2 ); strcat( buf, ")" ); print( buf ); } return sym; } return sym; } void scanner_debug( Scanner *s, int enable ) { s->debug = enable; if( s->debug ) { print( "SCANNER DEBUGGING ENABLED" ); } }