// Precondition: sr is a valid streamreader which has been initialized // Postcondition: cch, cpos, and prevch are updated for sr accordingly. void inc_char ( ) { sr.prevch = sr.cch; sr.cch = getc(sr.fp); //get next character //update cpos if (sr.prevch == '\n') { inc_line(sr.cpos); } else { inc_col(sr.cpos); } }
static int lex(lexer_state *ls, token_info *info) { buffer_reset(ls->buf); if(setjmp(ls->error.buf)) return TK_ERROR; for(;;) { switch(ls->current) { case '\n': case '\r': { // newline inc_line(ls); break; } case ' ': case '\t': { // whitespace next(ls); break; } case '-': { // comment or minus // minus if(next(ls) != '-') return '-'; // comment, skip line while(next(ls) != EOS && !isnewline(ls)); break; } case '=': { // EQ next(ls); return '='; } case '<': { // LT, LTE, ASSIGN next(ls); if(ls->current == '=') { next(ls); return TK_LTE; } else if(ls->current == '-'){ next(ls); return TK_ASSIGN; } else return '<'; } case '>': { // GT, GTE next(ls); if(ls->current == '=') { next(ls); return TK_GTE; } else return '>'; } case '/': { // NEQ, DIV next(ls); if(ls->current == '=') { next(ls); return TK_NEQ; } else return '/'; } case '"': { // STRING read_string(ls, info); return TK_STRING; } case EOS: { // EOS return TK_EOS; } default: { if(lisdigit(ls->current)) { // NUMERIC read_numeric(ls, info); return TK_REAL; } if(lisalpha(ls->current)) { // ID or RESERVED return read_id_or_reserved(ls, info); } int c = ls->current; // valid operators, single character tokens, etc. switch(ls->current) { case '+': case '-': case '*': case '/': case '!': case '>': case '<': case '=': case '(': case ')': case '[': case ']': case '{': case '}': case ':': case '.': case ',': next(ls); return c; default: lexer_error(ls, "unrecognized symbol %c", c); next(ls); } } } } }