From c9e3d321828dd095d46e295873bc991f0c9ed3d7 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Mon, 7 Apr 1997 11:48:53 -0300 Subject: [PATCH] first implementation of "$if"; new function "findstring" (useful in good places) --- auxlib.c | 14 ++++++++- auxlib.h | 9 +++++- fallback.c | 91 ++++++++++++++++++++++++++---------------------------- lex.c | 87 ++++++++++++++++++++++++++++++++++++++------------- table.c | 8 ++++- table.h | 3 +- 6 files changed, 139 insertions(+), 73 deletions(-) diff --git a/auxlib.c b/auxlib.c index 83087572..1c967c71 100644 --- a/auxlib.c +++ b/auxlib.c @@ -1,13 +1,25 @@ -char *rcs_auxlib="$Id: auxlib.c,v 1.2 1997/03/18 15:30:50 roberto Exp roberto $"; +char *rcs_auxlib="$Id: auxlib.c,v 1.3 1997/04/06 14:08:08 roberto Exp roberto $"; #include #include +#include #include "lua.h" #include "auxlib.h" #include "luadebug.h" + +int luaI_findstring (char *name, char *list[]) +{ + int i; + for (i=0; list[i]; i++) + if (strcmp(list[i], name) == 0) + return i; + return -1; /* name not found */ +} + + void luaL_arg_check(int cond, int numarg, char *extramsg) { char *funcname; diff --git a/auxlib.h b/auxlib.h index c5897b3a..45cbda9d 100644 --- a/auxlib.h +++ b/auxlib.h @@ -1,5 +1,5 @@ /* -** $Id: auxlib.h,v 1.1 1997/03/18 15:30:50 roberto Exp $ +** $Id: auxlib.h,v 1.2 1997/04/06 14:08:08 roberto Exp roberto $ */ #ifndef auxlib_h @@ -20,4 +20,11 @@ double luaL_check_number (int numArg); double luaL_opt_number (int numArg, double def); void luaL_verror (char *fmt, ...); + + +/* -- private part (only for Lua modules */ + +int luaI_findstring (char *name, char *list[]); + + #endif diff --git a/fallback.c b/fallback.c index 25f52773..12c4509d 100644 --- a/fallback.c +++ b/fallback.c @@ -3,7 +3,7 @@ ** TecCGraf - PUC-Rio */ -char *rcs_fallback="$Id: fallback.c,v 2.2 1997/04/04 22:24:51 roberto Exp roberto $"; +char *rcs_fallback="$Id: fallback.c,v 2.3 1997/04/06 14:08:08 roberto Exp roberto $"; #include #include @@ -102,18 +102,9 @@ char *luaI_eventname[] = { /* ORDER IM */ -static int findstring (char *name, char *list[]) -{ - int i; - for (i=0; list[i]; i++) - if (strcmp(list[i], name) == 0) - return i; - return -1; /* name not found */ -} - static int luaI_checkevent (char *name, char *list[]) { - int e = findstring(name, list); + int e = luaI_findstring(name, list); if (e < 0) luaL_verror("`%s' is not a valid event name", name); return e; @@ -197,11 +188,8 @@ void luaI_settag (int tag, TObject *o) case LUA_T_ARRAY: o->value.a->htag = tag; break; - case LUA_T_USERDATA: - o->value.ts->tag = tag; - break; default: - luaL_verror("cannot change tag of a %s", luaI_typenames[-ttype(o)]); + luaL_verror("cannot change the tag of a %s", luaI_typenames[-ttype(o)]); } } @@ -318,45 +306,52 @@ static void fillvalids (IMS e, TObject *func) void luaI_setfallback (void) { - int e; + static char *oldnames [] = {"error", "getglobal", "arith", "order", NULL}; TObject oldfunc; lua_CFunction replace; char *name = luaL_check_string(1); lua_Object func = lua_getparam(2); luaI_initfallbacks(); luaL_arg_check(lua_isfunction(func), 2, "function expected"); - if (strcmp(name, "error") == 0) { /* old error fallback */ - oldfunc = errorim; - errorim = *luaI_Address(func); - replace = errorFB; - } - else if (strcmp(name, "getglobal") == 0) { /* old getglobal fallback */ - oldfunc = luaI_IMtable[-LUA_T_NIL].int_method[IM_GETGLOBAL]; - luaI_IMtable[-LUA_T_NIL].int_method[IM_GETGLOBAL] = *luaI_Address(func); - replace = nilFB; - } - else if ((e = findstring(name, luaI_eventname)) >= 0) { - oldfunc = luaI_IMtable[-LUA_T_USERDATA].int_method[e]; - fillvalids(e, luaI_Address(func)); - replace = (e == IM_GC || e == IM_INDEX) ? nilFB : typeFB; - } - else if (strcmp(name, "arith") == 0) { /* old arith fallback */ - int i; - oldfunc = luaI_IMtable[-LUA_T_USERDATA].int_method[IM_POW]; - for (i=IM_ADD; i<=IM_UNM; i++) /* ORDER IM */ - fillvalids(i, luaI_Address(func)); - replace = typeFB; - } - else if (strcmp(name, "order") == 0) { /* old order fallback */ - int i; - oldfunc = luaI_IMtable[-LUA_T_USERDATA].int_method[IM_LT]; - for (i=IM_LT; i<=IM_GE; i++) /* ORDER IM */ - fillvalids(i, luaI_Address(func)); - replace = typeFB; - } - else { - luaL_verror("`%s' is not a valid fallback name", name); - replace = NULL; /* to avoid warnings */ + switch (luaI_findstring(name, oldnames)) { + case 0: /* old error fallback */ + oldfunc = errorim; + errorim = *luaI_Address(func); + replace = errorFB; + break; + case 1: /* old getglobal fallback */ + oldfunc = luaI_IMtable[-LUA_T_NIL].int_method[IM_GETGLOBAL]; + luaI_IMtable[-LUA_T_NIL].int_method[IM_GETGLOBAL] = *luaI_Address(func); + replace = nilFB; + break; + case 2: { /* old arith fallback */ + int i; + oldfunc = luaI_IMtable[-LUA_T_USERDATA].int_method[IM_POW]; + for (i=IM_ADD; i<=IM_UNM; i++) /* ORDER IM */ + fillvalids(i, luaI_Address(func)); + replace = typeFB; + break; + } + case 3: { /* old order fallback */ + int i; + oldfunc = luaI_IMtable[-LUA_T_USERDATA].int_method[IM_LT]; + for (i=IM_LT; i<=IM_GE; i++) /* ORDER IM */ + fillvalids(i, luaI_Address(func)); + replace = typeFB; + break; + } + default: { + int e; + if ((e = luaI_findstring(name, luaI_eventname)) >= 0) { + oldfunc = luaI_IMtable[-LUA_T_USERDATA].int_method[e]; + fillvalids(e, luaI_Address(func)); + replace = (e == IM_GC || e == IM_INDEX) ? nilFB : typeFB; + } + else { + luaL_verror("`%s' is not a valid fallback name", name); + replace = NULL; /* to avoid warnings */ + } + } } if (oldfunc.ttype != LUA_T_NIL) luaI_pushobject(&oldfunc); diff --git a/lex.c b/lex.c index 0f64c758..3c8da4c2 100644 --- a/lex.c +++ b/lex.c @@ -1,4 +1,4 @@ -char *rcs_lex = "$Id: lex.c,v 2.44 1997/03/31 14:17:09 roberto Exp roberto $"; +char *rcs_lex = "$Id: lex.c,v 2.45 1997/04/01 21:23:20 roberto Exp roberto $"; #include @@ -22,27 +22,31 @@ char *rcs_lex = "$Id: lex.c,v 2.44 1997/03/31 14:17:09 roberto Exp roberto $"; static int current; /* look ahead character */ static Input input; /* input function */ +static int iflevel; /* level of nested $if's */ void lua_setinput (Input fn) { current = '\n'; lua_linenumber = 0; + iflevel = 0; input = fn; } static void luaI_auxsyntaxerror (char *s, char *token) { + if (token == NULL) + luaL_verror("%s;\n> at line %d in file %s", + s, lua_linenumber, lua_parsedfile); + if (token[0] == 0) + token = ""; luaL_verror("%s;\n> last token read: \"%s\" at line %d in file %s", s, token, lua_linenumber, lua_parsedfile); } void luaI_syntaxerror (char *s) { - char *token = luaI_buffer(1); - if (token[0] == 0) - token = ""; - luaI_auxsyntaxerror(s, token); + luaI_auxsyntaxerror(s, luaI_buffer(1)); } @@ -82,24 +86,63 @@ void luaI_addReserved (void) } } -static int inclinenumber (int pragma_allowed) + +static void readname (char *buff) { + int i = 0; + while (current == ' ') next(); + while (isalnum((unsigned char)current)) { + if (i >= MINBUFF) luaI_syntaxerror("pragma too long"); + buff[i++] = current; + next(); + } + buff[i] = 0; + if (!isalpha(buff[0]) || (current != 0 && !isspace(current))) + luaI_auxsyntaxerror("invalid pragma format", NULL); +} + +static int inclinenumber (void) +{ + static char *pragmas [] = {"debug", "nodebug", "endif", "ifnil", "if", NULL}; + int ifnil = 0; ++lua_linenumber; - if (pragma_allowed && current == '$') { /* is a pragma? */ + if (current == '$') { /* is a pragma? */ char buff[MINBUFF+1]; - int i = 0; next(); /* skip $ */ - while (isalnum((unsigned char)current)) { - if (i >= MINBUFF) luaI_syntaxerror("pragma too long"); - buff[i++] = current; - next(); + readname(buff); + switch (luaI_findstring(buff, pragmas)) { + case 0: /* debug */ + lua_debug = 1; + break; + case 1: /* nodebug */ + lua_debug = 0; + break; + case 2: /* endif */ + if (--iflevel < 0) + luaI_auxsyntaxerror("too many $endif's", NULL); + break; + case 3: /* ifnil */ + ifnil = 1; + /* go through */ + case 4: { /* if */ + int thisiflevel = iflevel++; + readname(buff); + if ((ifnil && luaI_globaldefined(buff)) || + (!ifnil && !luaI_globaldefined(buff))) { /* skip the $if? */ + do { + if (current == '\n') { + next(); + inclinenumber(); + } + else if (current == 0) + luaI_auxsyntaxerror("input ends inside a $if", NULL); + else next(); + } while (iflevel > thisiflevel); + } + break; + } + default: luaI_auxsyntaxerror("invalid pragma", buff); } - buff[i] = 0; - if (strcmp(buff, "debug") == 0) - lua_debug = 1; - else if (strcmp(buff, "nodebug") == 0) - lua_debug = 0; - else luaI_auxsyntaxerror("invalid pragma", buff); } return lua_linenumber; } @@ -136,7 +179,7 @@ static int read_long_string (char *yytext, int buffsize) continue; case '\n': save_and_next(); - inclinenumber(0); + inclinenumber(); continue; default: save_and_next(); @@ -167,7 +210,7 @@ int luaY_lex (void) { case '\n': next(); - linelasttoken = inclinenumber(1); + linelasttoken = inclinenumber(); continue; case ' ': case '\t': case '\r': /* CR: to avoid problems with DOS */ @@ -231,7 +274,7 @@ int luaY_lex (void) case 'n': save('\n'); next(); break; case 't': save('\t'); next(); break; case 'r': save('\r'); next(); break; - case '\n': save_and_next(); inclinenumber(0); break; + case '\n': save_and_next(); inclinenumber(); break; default : save_and_next(); break; } break; @@ -339,6 +382,8 @@ int luaY_lex (void) case 0: save(0); + if (iflevel > 0) + luaI_syntaxerror("missing $endif"); return 0; default: diff --git a/table.c b/table.c index a1ab1178..1d6afbfc 100644 --- a/table.c +++ b/table.c @@ -3,7 +3,7 @@ ** Module to control static tables */ -char *rcs_table="$Id: table.c,v 2.66 1997/04/04 15:35:37 roberto Exp roberto $"; +char *rcs_table="$Id: table.c,v 2.67 1997/04/06 14:08:08 roberto Exp roberto $"; #include "luamem.h" #include "auxlib.h" @@ -111,6 +111,12 @@ TaggedString *luaI_createfixedstring (char *name) } +int luaI_globaldefined (char *name) +{ + return ttype(&lua_table[luaI_findsymbolbyname(name)].object) != LUA_T_NIL; +} + + /* ** Traverse symbol table objects */ diff --git a/table.h b/table.h index d03a5607..c2af9621 100644 --- a/table.h +++ b/table.h @@ -1,7 +1,7 @@ /* ** Module to control static tables ** TeCGraf - PUC-Rio -** $Id: table.h,v 2.22 1997/02/26 17:38:41 roberto Unstable roberto $ +** $Id: table.h,v 2.23 1997/03/31 14:02:58 roberto Exp roberto $ */ #ifndef table_h @@ -28,6 +28,7 @@ Word luaI_findsymbolbyname (char *name); Word luaI_findsymbol (TaggedString *t); Word luaI_findconstant (TaggedString *t); Word luaI_findconstantbyname (char *name); +int luaI_globaldefined (char *name); void luaI_nextvar (void); TaggedString *luaI_createfixedstring (char *str); int lua_markobject (TObject *o);