Lua相关问题整理(4) – 让Lua的eval函数支持赋值语句

上一篇文章提到了在Lua中实现类似于JavaScript中的eval函数,遗憾是该eval函数不支持赋值语句,原因是Lua的赋值运算符是不支持返回值。所以如果要让该eval函数也支持赋值语句,就需要一个额外的工作,让它鉴别一个语句是不是赋值语句,如果是,则return的是被赋值后变量的值。为此,我写了一个isAssignmentExpression函数,比较粗糙,不过够用了,基本思想是检测语句中第一个出现的”=“操作符,且该”=“不能在一对引号当中。

-- Lua code
function isAssignmentExpression( str )
	local i = 1;
	local curChar;
	local quotesType = "none" -- none, single or double
	local isEscaping = false

	curChar = string.sub( str, 1, 1 )
	while ( curChar ~= "" ) do
		if ( curChar == "'" and
			 isEscaping == false and
			 quotesType ~= "double" )
		then
			if ( quotesType == "single" )
			then quotesType = "none"
			elseif ( quotesType == "none" )
			then quotesType = "single"
			end
		end

		if ( curChar == "\"" and
			 isEscaping == false and
			 quotesType ~= "single" )
		then
			if ( quotesType == "double" )
			then quotesType = "none"
			elseif ( quotesType == "none" )
			then quotesType = "double"
			end
		end

		if ( curChar == "\\" and isEscaping == false )
		then isEscaping = true
		else isEscaping = false
		end

		if ( curChar == "=" and quotesType == "none" )
		then
			if ( string.sub( str, i+1, i+1 ) ~= "=" )
			then
				return true, string.sub( str, 1, i - 1 )
			else
				return false
			end
		end

		i = i + 1
		curChar = string.sub( str, i, i )
	end

	return false
end

function eval( str )
	local bAssign
	local var
	bAssign, var = isAssignmentExpression( str )
	if ( bAssign )
	then
		print( "Assignment, var=" .. var )
		loadstring( str )()
		return loadstring( "return " .. var )()
	else
		return loadstring( "return " .. str )()
	end
end

-- 以下是一组测试
print( eval( "3+4" ) )
-- 7
function Multiply( a, b )
	return a*b
end
print( eval( "Multiply( 3, 4 )" ) )
-- 12
print( eval( "i" ) )
-- nil
print( eval( "i = 1" ) )
-- Assignment, var=i
-- 1
print( eval( "i = i + 1" ) )
-- Assignment, var=i
-- 2
print( eval( "i" ) )
-- 2
print( eval( "i+1" ) )
-- 3
print( eval( "i, j = 4, 5" ) )
-- Assignment, var=i, j
-- 4	   5
print( eval( "i = {}" ) )
-- Assignment, var=i
-- table: 003CD818
print( eval( "i[ \"0\" ] = 0" ) )
-- Assignment, var=i[ "0" ]
-- 0
print( eval( "i[ \"\\\"0=\" ] = 1" ) )
-- Assignment, var=i[ "\"0=" ]
-- 1
print( eval( "i.name=\"hello\"" ) )
-- Assignment, var=i.name
-- hello
print( eval( "i[0], i.name = 4" ) )
-- Assignment, var=i[0], i.name
-- 4	  nil
print( eval( "i == 10" ) )
-- false
This entry was written by Benny Chen , posted on Sunday November 28 2010at 10:11 pm , filed under Lua and tagged , , . Bookmark the permalink . Post a comment below or leave a trackback: Trackback URL.

9 Responses to “Lua相关问题整理(4) – 让Lua的eval函数支持赋值语句”

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>