[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re[2]: python like syntax for lua
- From: Serge Semashko <serge@...>
- Date: Sat, 14 Jun 2003 01:00:31 +0300
Friday, June 13, 2003, 9:39:43 PM, Eli wrote:
E> This could very easily be done as a pre-processor written in Lua...
You are right, though it has to handle string literals, comments and
may have other problems.
Here is a pre-alpha pre-processor that converts lua-scripts to
python-like syntax (just removes extra 'end' keywords for now) and
back. It is just a concept test and works only for very simple scripts
(at least it works for its own source).
-------------------------------------------------------------------
-- gets indentation level
-- does not allow mixed tabs and spaces in the same source file
local ws = nil
function get_indent(l)
local _, len, prefix = string.find(l, "^(%s*)")
if not ws and len > 0 then
ws = string.sub(l, 1, 1)
end
assert(not ws or prefix == string.rep(ws, len))
return len
end
local indent_tbl = {}
function get_prev_indent()
if table.getn(indent_tbl) > 0 then
return indent_tbl[table.getn(indent_tbl)]
else
return 0
end
end
-- returns the change in indentation level
function get_indent_change(l)
local indent = get_indent(l)
local prev_indent = get_prev_indent(l)
if indent > prev_indent then
table.insert(indent_tbl, indent)
return 1
elseif indent == prev_indent then
return 0;
else
local res = 0
while get_prev_indent() > indent do
res = res - 1
table.remove(indent_tbl)
end
return res
end
end
function has_end_of_block_keyword(l)
local _, _, keyword = string.find(l, "^%s*(%w+)")
return keyword == "end" or keyword == "else" or keyword == "elseif"
end
function has_end_keyword(l)
local _, _, keyword = string.find(l, "^%s*(%w+)")
return keyword == "end"
end
-- removes the first keyword in the string (returns nil if there is nothing
-- left in this string)
function remove_first_keyword(l)
local res = string.gsub(l, "^(%s*)(%w+)", "%1")
if string.find(res, "%S") then
return res
else
return nil
end
end
if string.find(arg[1], "%.lua$") then
-- process lua sources to produce python-like syntax
for l in io.lines(arg[1]) do
local indent_change = get_indent_change(l)
if indent_change < 0 then
assert(has_end_of_block_keyword(l))
if has_end_keyword(l) then
assert(indent_change == -1)
l = remove_first_keyword(l)
end
end
if l then
print(l)
end
end
else
-- restore lua source from preprocessed file
for l in io.lines(arg[1]) do
local indent_change = get_indent_change(l)
if has_end_of_block_keyword(l) then
indent_change = indent_change + 1
end
while indent_change < 0 do
print("end")
indent_change = indent_change + 1
end
print(l)
end
local indent_change = get_indent_change("")
while indent_change < 0 do
print("end")
indent_change = indent_change + 1
end
end
-------------------------------------------------------------------
E> I personally like the Python syntax .. Python tends to be very legible. But I
E> really don't like the way they mix tabs and spaces. It seems to me that the
E> parser doesn't know until it's read a few lines of the file wether to use
E> spaces or tabs or both.
IMHO the source must use either tabs or spaces, the mixture of tabs
and spaces must be detected as a syntax error.
E> In Lua, it also leads to somewhat unattractive things like:
E> for i in obj:iterator():
E> do_stuff(i)
E> Two colons on the same line? That mean completely different things? Ugh. Maybe
E> you could make "do" the beginning of a block.
This is not so easy question. Just replacing 'then' and 'do' with ':'
adds ambiguety (as you have pointed). In addition, probably this will
require some changes in the parser as we replace two different tokens
with colon.
For now, I want to try to make 'end' keyword optional and see what
happens. Maybe this idea is not good at all.