Browse Source

first implementation of "$if";
new function "findstring" (useful in good places)

Roberto Ierusalimschy 28 years ago
parent
commit
c9e3d32182
6 changed files with 139 additions and 73 deletions
  1. 13 1
      auxlib.c
  2. 8 1
      auxlib.h
  3. 43 48
      fallback.c
  4. 66 21
      lex.c
  5. 7 1
      table.c
  6. 2 1
      table.h

+ 13 - 1
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 <stdio.h>
 #include <stdarg.h>
+#include <string.h>
 
 #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;

+ 8 - 1
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

+ 43 - 48
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 <stdio.h>
 #include <string.h>
@@ -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);

+ 66 - 21
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 <ctype.h>
@@ -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 = "<eof>";
   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 = "<eof>";
-  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:

+ 7 - 1
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
 */

+ 2 - 1
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);