lua-users home
lua-l archive

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


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"