mirror of
https://github.com/Reuh/anselme.git
synced 2025-10-27 16:49:31 +00:00
Check identifier pattern in more cases while parsing
This commit is contained in:
parent
eb6da84878
commit
b0d7a0bfb5
2 changed files with 26 additions and 7 deletions
|
|
@ -24,9 +24,14 @@ local function parse_line(line, state, namespace)
|
||||||
r.condition = expr
|
r.condition = expr
|
||||||
-- paragraph
|
-- paragraph
|
||||||
elseif l:match("^..+§.-$") then
|
elseif l:match("^..+§.-$") then
|
||||||
|
-- get identifier
|
||||||
local name
|
local name
|
||||||
l, name = l:match("^(.-)%s*§(.-)$")
|
l, name = l:match("^(.-)%s*§(.-)$")
|
||||||
local fqm = ("%s%s"):format(namespace, format_identifier(name, state))
|
local identifier, rem = name:match("^("..identifier_pattern..")(.-)$")
|
||||||
|
if not identifier then return nil, ("no valid identifier in paragraph decorator %q; at %s"):format(identifier, line.source) end
|
||||||
|
if rem:match("[^%s]") then return nil, ("expected end-of-line after identifier in paragraph decorator, but got %q; at %s"):format(rem, line.source) end
|
||||||
|
-- format identifier
|
||||||
|
local fqm = ("%s%s"):format(namespace, format_identifier(identifier, state))
|
||||||
namespace = fqm.."."
|
namespace = fqm.."."
|
||||||
r.paragraph = true
|
r.paragraph = true
|
||||||
r.parent_function = true
|
r.parent_function = true
|
||||||
|
|
@ -78,16 +83,21 @@ local function parse_line(line, state, namespace)
|
||||||
elseif l:match("^%$") or l:match("^§") then -- § is a 2-bytes caracter, DO NOT USE LUA PATTERN OPERATORS as they operate on single bytes
|
elseif l:match("^%$") or l:match("^§") then -- § is a 2-bytes caracter, DO NOT USE LUA PATTERN OPERATORS as they operate on single bytes
|
||||||
r.type = l:match("^%$") and "function" or "paragraph"
|
r.type = l:match("^%$") and "function" or "paragraph"
|
||||||
r.child = true
|
r.child = true
|
||||||
local fqm = ("%s%s"):format(namespace, format_identifier(l:match("^%$(.*)$") or l:match("^§(.*)$"), state))
|
-- get identifier
|
||||||
|
local lc = l:match("^%$(.*)$") or l:match("^§(.*)$")
|
||||||
|
local identifier, rem = lc:match("^("..identifier_pattern..")(.-)$")
|
||||||
|
if not identifier then return nil, ("no valid identifier in paragraph/function definition line %q; at %s"):format(lc, line.source) end
|
||||||
|
-- format identifier
|
||||||
|
local fqm = ("%s%s"):format(namespace, format_identifier(identifier, state))
|
||||||
-- get params
|
-- get params
|
||||||
r.params = {}
|
r.params = {}
|
||||||
if r.type == "function" and fqm:match("%b()$") then
|
if r.type == "function" and rem:match("^%b()$") then
|
||||||
local content
|
local content = rem:gsub("^%(", ""):gsub("%)$", "")
|
||||||
fqm, content = fqm:match("^(.-)(%b())$")
|
|
||||||
content = content:gsub("^%(", ""):gsub("%)$", "")
|
|
||||||
for param in content:gmatch("[^%,]+") do
|
for param in content:gmatch("[^%,]+") do
|
||||||
table.insert(r.params, format_identifier(("%s.%s"):format(fqm, param), state))
|
table.insert(r.params, format_identifier(("%s.%s"):format(fqm, param), state))
|
||||||
end
|
end
|
||||||
|
elseif rem:match("[^%s]") then
|
||||||
|
return nil, ("expected end-of-line at end of paragraph/function definition line, but got %q; at %s"):format(rem, line.source)
|
||||||
end
|
end
|
||||||
local arity, vararg = #r.params, nil
|
local arity, vararg = #r.params, nil
|
||||||
if arity > 0 and r.params[arity]:match("%.%.%.$") then -- varargs
|
if arity > 0 and r.params[arity]:match("%.%.%.$") then -- varargs
|
||||||
|
|
@ -165,9 +175,15 @@ local function parse_line(line, state, namespace)
|
||||||
elseif l:match("^:") then
|
elseif l:match("^:") then
|
||||||
r.type = "definition"
|
r.type = "definition"
|
||||||
r.remove_from_block_ast = true
|
r.remove_from_block_ast = true
|
||||||
|
-- get expression
|
||||||
local exp, rem = expression(l:match("^:(.*)$"), state, namespace) -- expression parsing is done directly to get type information
|
local exp, rem = expression(l:match("^:(.*)$"), state, namespace) -- expression parsing is done directly to get type information
|
||||||
if not exp then return nil, ("%s; at %s"):format(rem, line.source) end
|
if not exp then return nil, ("%s; at %s"):format(rem, line.source) end
|
||||||
local fqm = ("%s%s"):format(namespace, format_identifier(rem, state))
|
-- get identifier
|
||||||
|
local identifier, rem2 = rem:match("^("..identifier_pattern..")(.-)$")
|
||||||
|
if not identifier then return nil, ("no valid identifier after expression in definition line %q; at %s"):format(rem, line.source) end
|
||||||
|
if rem2:match("[^%s]") then return nil, ("expected end-of-line after identifier in definition line, but got %q; at %s"):format(rem2, line.source) end
|
||||||
|
-- format identifier & define
|
||||||
|
local fqm = ("%s%s"):format(namespace, format_identifier(identifier, state))
|
||||||
if state.functions[fqm] then return nil, ("trying to define variable %s, but a function with the same name exists; at %s"):format(fqm, line.source) end
|
if state.functions[fqm] then return nil, ("trying to define variable %s, but a function with the same name exists; at %s"):format(fqm, line.source) end
|
||||||
if not state.variables[fqm] or state.variables[fqm].type == "undefined argument" then
|
if not state.variables[fqm] or state.variables[fqm].type == "undefined argument" then
|
||||||
local v, e = eval(state, exp)
|
local v, e = eval(state, exp)
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,9 @@ if args.script then
|
||||||
end
|
end
|
||||||
until t == "return" or t == "error"
|
until t == "return" or t == "error"
|
||||||
end
|
end
|
||||||
|
if args.save then
|
||||||
|
print(inspect(vm:save()))
|
||||||
|
end
|
||||||
else
|
else
|
||||||
print("error", err)
|
print("error", err)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue