lua-users home
lua-l archive

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


In Lua, many special characters are idle, e.g. !, ?, @ etc.
Lua 5.2 makes it easy to bring these characters into the syntax
as alphabetic or space characters via the table in lctype.c.

Things become really interesting if one does not merely patch
that table, but adds functions to change it on the fly.  That is
done by the attached patch, documented tersely in a README file.

This is NOT a suggestion to change official Lua!

Dirk

diff -r lua-5.2.0-alpha/src/lbaselib.c lua-5.2.0-patch/src/lbaselib.c
21c21
< 
---
> #include "lctype.h"
437a438,470
> const char* codes = "ADPSXU";
> 
> static int luaB_getcatcode (lua_State *L) {
>   const lu_byte* s = (lu_byte*) luaL_checkstring(L,1);
>   luaL_argcheck(L,s[1]==0,1,"must be a one-byte string");
>   char b[7];
>   int k, j=0, n=s[0];
>   lu_byte c=getcatcode(n+1);
>   for (k=0; k<6; k++, c>>=1) if (c&1) b[j++]=codes[k];
>   b[j]=0;
>   lua_pushstring(L,b);
>   return 1;
>   }
>      
> static int luaB_setcatcode (lua_State *L) {
>   const lu_byte* s = (lu_byte*) luaL_checkstring(L,1);
>   luaL_argcheck(L,s[1]==0,1,"must be a one-byte string");
>   int n=s[0];
>   lu_byte c=getcatcode(n+1), p=MASK(PRINTBIT);
>   luaL_argcheck(L,c&p,1,"must be a printable character");
>   const char* a = luaL_checkstring(L,2);
>   for (c=p; *a; a++) {
>     switch (*a) {
>       case 'A': c |= MASK(ALPHABIT); break;
>       case 'S': c |= MASK(SPACEBIT); break;
>       case 'U': c |= MASK(UPPERBIT); break;
>       luaL_argcheck(L,0,2,"may contain only A,S,U");
>     }
>   }  
>   setcatcode(n+1,c);
>   return 0;
> }
> 
471a505,506
>   {"getcatcode", luaB_getcatcode}, 
>   {"setcatcode", luaB_setcatcode}, 
diff -r lua-5.2.0-alpha/src/lctype.c lua-5.2.0-patch/src/lctype.c
11c11
< LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = {
---
> LUAI_DDEF lu_byte luai_ctype_[UCHAR_MAX + 2] = {
diff -r lua-5.2.0-alpha/src/lctype.h lua-5.2.0-patch/src/lctype.h
47c47,49
< LUAI_DDEC const lu_byte luai_ctype_[UCHAR_MAX + 2];
---
> LUAI_DDEC lu_byte luai_ctype_[UCHAR_MAX + 2];
> #define setcatcode(c,v) luai_ctype_[c]=v 
> #define getcatcode(c) luai_ctype_[c]
This patch to Lua 5.2 allows you to redefine character category
codes, à la TeX.

There are two new functions in the base library:
    getcatcode(c) returns a string describing the category code of the 
	character c (specified as a one-character string), as follows:
	    A: alphabetic
	    D: digit
	    P: printable
	    S: space
	    U: upper case
	    X: hex digit
    setcatcode(c,a) sets the category code of the character c, where a
	is a string containing any combination of the letters ADU.  
	The category code of c must already contain P; this attribute
	will be automatically set.