diff options
Diffstat (limited to 'src/lex.c')
-rw-r--r-- | src/lex.c | 143 |
1 files changed, 88 insertions, 55 deletions
@@ -1,30 +1,20 @@ -char *rcs_lex = "$Id: lex.c,v 2.1 1994/04/15 19:00:28 celes Exp $"; -/*$Log: lex.c,v $ - * Revision 2.1 1994/04/15 19:00:28 celes - * Retirar chamada da funcao lua_findsymbol associada a cada - * token NAME. A decisao de chamar lua_findsymbol ou lua_findconstant - * fica a cargo do modulo "lua.stx". - * - * Revision 1.3 1993/12/28 16:42:29 roberto - * "include"s de string.h e stdlib.h para evitar warnings - * - * Revision 1.2 1993/12/22 21:39:15 celes - * Tratamento do token $debug e $nodebug - * - * Revision 1.1 1993/12/22 21:15:16 roberto - * Initial revision - **/ +char *rcs_lex = "$Id: lex.c,v 2.14 1994/12/27 20:50:38 celes Exp $"; + #include <ctype.h> #include <math.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> +#include "tree.h" +#include "table.h" #include "opcode.h" -#include "hash.h" #include "inout.h" -#include "table.h" -#include "y.tab.h" +#include "parser.h" +#include "ugly.h" + +#define lua_strcmp(a,b) (a[0]<b[0]?(-1):(a[0]>b[0]?(1):strcmp(a,b))) #define next() { current = input(); } #define save(x) { *yytextLast++ = (x); } @@ -49,7 +39,8 @@ char *lua_lasttext (void) } -static struct +/* The reserved words must be listed in lexicographic order */ +static struct { char *name; int token; @@ -71,17 +62,18 @@ static struct {"until", UNTIL}, {"while", WHILE} }; + #define RESERVEDSIZE (sizeof(reserved)/sizeof(reserved[0])) -int findReserved (char *name) +static int findReserved (char *name) { int l = 0; int h = RESERVEDSIZE - 1; while (l <= h) { int m = (l+h)/2; - int comp = strcmp(name, reserved[m].name); + int comp = lua_strcmp(name, reserved[m].name); if (comp < 0) h = m-1; else if (comp == 0) @@ -93,13 +85,20 @@ int findReserved (char *name) } -int yylex () +int yylex (void) { + float a; while (1) { yytextLast = yytext; +#if 0 + fprintf(stderr,"'%c' %d\n",current,current); +#endif switch (current) { + case EOF: + case 0: + return 0; case '\n': lua_linenumber++; case ' ': case '\t': @@ -111,34 +110,39 @@ int yylex () while (isalnum(current) || current == '_') save_and_next(); *yytextLast = 0; - if (strcmp(yytext, "debug") == 0) + if (lua_strcmp(yytext, "debug") == 0) { yylval.vInt = 1; return DEBUG; } - else if (strcmp(yytext, "nodebug") == 0) + else if (lua_strcmp(yytext, "nodebug") == 0) { yylval.vInt = 0; return DEBUG; } return WRONGTOKEN; - + case '-': save_and_next(); if (current != '-') return '-'; do { next(); } while (current != '\n' && current != 0); continue; - + + case '=': + save_and_next(); + if (current != '=') return '='; + else { save_and_next(); return EQ; } + case '<': save_and_next(); if (current != '=') return '<'; else { save_and_next(); return LE; } - + case '>': save_and_next(); if (current != '=') return '>'; else { save_and_next(); return GE; } - + case '~': save_and_next(); if (current != '=') return '~'; @@ -149,12 +153,13 @@ int yylex () { int del = current; next(); /* skip the delimiter */ - while (current != del) + while (current != del) { switch (current) { - case 0: - case '\n': + case EOF: + case 0: + case '\n': return WRONGTOKEN; case '\\': next(); /* do not save the '\' */ @@ -163,16 +168,16 @@ int yylex () case 'n': save('\n'); next(); break; case 't': save('\t'); next(); break; case 'r': save('\r'); next(); break; - default : save('\\'); break; + default : save(current); next(); break; } break; - default: + default: save_and_next(); } } next(); /* skip the delimiter */ *yytextLast = 0; - yylval.vWord = lua_findconstant (yytext); + yylval.vWord = luaI_findconstant(lua_constcreate(yytext)); return STRING; } @@ -190,49 +195,77 @@ int yylex () case 'Z': case '_': { - int res; + Word res; do { save_and_next(); } while (isalnum(current) || current == '_'); *yytextLast = 0; res = findReserved(yytext); if (res) return res; - yylval.pChar = yytext; + yylval.pNode = lua_constcreate(yytext); return NAME; } - + case '.': save_and_next(); - if (current == '.') - { - save_and_next(); + if (current == '.') + { + save_and_next(); return CONC; } else if (!isdigit(current)) return '.'; /* current is a digit: goes through to number */ + a=0.0; goto fraction; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - - do { save_and_next(); } while (isdigit(current)); + a=0.0; + do { a=10*a+current-'0'; save_and_next(); } while (isdigit(current)); if (current == '.') save_and_next(); -fraction: while (isdigit(current)) save_and_next(); - if (current == 'e' || current == 'E') - { - save_and_next(); - if (current == '+' || current == '-') save_and_next(); - if (!isdigit(current)) return WRONGTOKEN; - do { save_and_next(); } while (isdigit(current)); +fraction: + { float da=0.1; + while (isdigit(current)) + {a+=(current-'0')*da; da/=10.0; save_and_next()}; + if (current == 'e' || current == 'E') + { + int e=0; + int neg; + float ea; + save_and_next(); + neg=(current=='-'); + if (current == '+' || current == '-') save_and_next(); + if (!isdigit(current)) return WRONGTOKEN; + do { e=10*e+current-'0'; save_and_next(); } while (isdigit(current)); + for (ea=neg?0.1:10.0; e>0; e>>=1) + { + if (e & 1) a*=ea; + ea*=ea; + } + } + yylval.vFloat = a; + return NUMBER; } - *yytextLast = 0; - yylval.vFloat = atof(yytext); - return NUMBER; + + case U_and: case U_do: case U_else: case U_elseif: case U_end: + case U_function: case U_if: case U_local: case U_nil: case U_not: + case U_or: case U_repeat: case U_return: case U_then: + case U_until: case U_while: + { + int old = current; + next(); + return reserved[old-U_and].token; + } + + case U_eq: next(); return EQ; + case U_le: next(); return LE; + case U_ge: next(); return GE; + case U_ne: next(); return NE; + case U_sc: next(); return CONC; default: /* also end of file */ { save_and_next(); - return *yytext; + return yytext[0]; } } } } - |