summaryrefslogtreecommitdiff
path: root/src/lex.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lex.c')
-rw-r--r--src/lex.c143
1 files changed, 88 insertions, 55 deletions
diff --git a/src/lex.c b/src/lex.c
index 14f41434..2916084f 100644
--- a/src/lex.c
+++ b/src/lex.c
@@ -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];
}
}
}
}
-