[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: command line evaluator
- From: Luiz Henrique de Figueiredo <lhf@...>
- Date: Thu, 21 Jan 2010 08:47:17 -0200
In a long recent thread, someone mentioned possible interpretations for
a line such as
print a b 23
This reminded me of an experiment I did with using Lua for evaluating command
lines, for which full Lua syntax is too heavy.
A command line is of the form
word arg1 arg2 ... argn
where the args can be a word or a quoted string. This is converted to
word(arg1,arg2,...,argn)
where the args are converted to strings.
Here are some examples, both of evaluation and conversion to full call syntax.
The code is attached. It can be much simplified I guess. All feedback welcome.
>>> eval print moon jane ball 123
moon jane ball 123
>>> eval print moon 'jane ball' 123
moon jane ball 123
>>> eval print moon "jane's ball" 123
moon jane's ball 123
>>> eval print
>>> eval
>>> eval print 1
1
>>> conv print moon jane ball 123
print( moon , jane , ball , 123 )
>>> conv print moon 'jane ball' 123
print( moon ,'jane ball', 123 )
>>> conv print moon "jane's ball" 123
print( moon ,"jane's ball", 123 )
>>> conv print
print()
>>> conv
>>> conv print 1
print( 1 )
/*
* lcl.c
* command line evaluator and converter for Lua 5.1
* Luiz Henrique de Figueiredo <lhf@tecgraf.puc-rio.br>
* 21 Jan 2010 08:46:56
* This code is hereby placed in the public domain.
*/
#include "lua.h"
#include "lauxlib.h"
static int Lconv(lua_State *L) /** conv(s) */
{
const char *s=luaL_checkstring(L,1);
size_t l;
int n;
const char *b;
lua_settop(L,1);
for (n=0;;n++) {
while (*s==' ' || *s=='\t') s++;
if (*s==0) break;
if (*s=='"' || *s=='\'') {
int q=*s++;
b=s;
for (l=0; *s!=q && *s!=0; s++,l++);
if (*s!=0) s++;
}
else {
b=s;
for (l=0; *s!=' ' && *s!='\t' && *s!=0; s++,l++);
}
if (n>1) lua_pushliteral(L,",");
if (n>0) lua_pushlstring(L,b-1,1);
lua_pushlstring(L,b,l);
if (n>0) lua_pushlstring(L,b-1,1);
if (n==0) lua_pushliteral(L,"(");
}
if (n>0) lua_pushliteral(L,")");
if (n>0) lua_concat(L,lua_gettop(L)-1);
return 1;
}
static int Leval(lua_State *L) /** eval(s) */
{
const char *s=luaL_checkstring(L,1);
size_t l;
int n;
const char *b;
for (n=0;;n++) {
while (*s==' ' || *s=='\t') s++;
if (*s==0) break;
if (*s=='"' || *s=='\'') {
int q=*s++;
b=s;
for (l=0; *s!=q && *s!=0; s++,l++);
if (*s!=0) s++;
}
else {
b=s;
for (l=0; *s!=' ' && *s!='\t' && *s!=0; s++,l++);
}
lua_pushlstring(L,b,l);
if (n==0) lua_gettable(L,LUA_GLOBALSINDEX);
}
if (n>0) lua_call(L,n-1,0);
return 0;
}
static const luaL_Reg R[] =
{
{ "eval", Leval},
{ "conv", Lconv},
{ NULL, NULL }
};
LUALIB_API int luaopen_cl(lua_State *L)
{
luaL_register(L,"cl",R);
return 1;
}
require"cl"
function test(w,s)
print(">>>",w,s)
print(cl[w](s,"extra","more"))
end
function doit(w)
test(w," print moon jane ball 123")
test(w," print moon 'jane ball' 123")
test(w," print moon \"jane's ball\" 123")
test(w," print ")
test(w," ")
test(w," print 1")
end
doit"eval"
doit"conv"