lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hello list,

I'm not sure if this wasnt implemented before, but couldn't find it
anywhere so here it is:

print("Hello from \$_LUA_VERSION\ ..")

equals to:

print("Hello from ".._LUA_VERSION.." ..")

the use of escape character was chosen to avoid clashes with existing
scripts, this can be fairly simply modified though. the terminating
(\ again) character is necessary since this is only a syntactic
sugar and we have no idea about parser state in llex.c, i wanted to
keep it simple. not to mention this allows us some cool things to do,
like:

print("blah \$func("foo\$var\bar")\ baz")

thats right the \$ and \ technically equals to ".. and ..", so there
can be any expression allowed between concats, but always only one,
so print("blah \$func() func2()\ baz") is incorrect.

Note that all of this only works with "string" constants, not 'string'
nor [[string]] (again, to keep it simple :)

This patch is part of larger collection of useful patches available at
http://blua.leet.cz/ - sort of netfilter-like patch-o-matic for lua,
have a peek.

diff -ruN lua-5.1.1/src/llex.c tmp/src/llex.c
--- lua-5.1.1/src/llex.c	2006-03-09 13:14:31.000000000 -0500
+++ tmp/src/llex.c	2006-10-22 20:51:17.000000000 -0400
@@ -144,6 +144,7 @@
   ls->linenumber = 1;
   ls->lastline = 1;
   ls->source = source;
+  ls->refstr = 0;
   luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER);  /* initialize buffer */
   next(ls);  /* read first char */
 }
@@ -298,6 +299,16 @@
           case '\n':  /* go through */
           case '\r': save(ls, '\n'); inclinenumber(ls); continue;
           case EOZ: continue;  /* will raise an error next loop */
+          case '$':
+            if (del == '"') {
+              save_and_next(ls); /* skip $ */
+              seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1,
+                            luaZ_bufflen(ls->buff) - 2);
+	      ls->refstr++; /* expect '\' anytime soon */
+              lua_assert(ls->lookahead.token == TK_EOS);
+	      ls->lookahead.token = TK_CONCAT;
+	      return;
+	    }
           default: {
             if (!isdigit(ls->current))
               save_and_next(ls);  /* handles \\, \", \', and \? */
@@ -407,6 +418,11 @@
       case EOZ: {
         return TK_EOS;
       }
+      case '\\': if (ls->refstr) {
+        ls->refstr--;
+	ls->current = '"'; /* whacky! */
+	return TK_CONCAT;
+      }
       default: {
         if (isspace(ls->current)) {
           lua_assert(!currIsNewline(ls));
diff -ruN lua-5.1.1/src/llex.h tmp/src/llex.h
--- lua-5.1.1/src/llex.h	2006-03-23 13:23:32.000000000 -0500
+++ tmp/src/llex.h	2006-10-22 20:51:17.000000000 -0400
@@ -64,6 +64,7 @@
   Mbuffer *buff;  /* buffer for tokens */
   TString *source;  /* current source name */
   char decpoint;  /* locale decimal point */
+  int refstr;
 } LexState;