mirror of
https://github.com/Reuh/anselme.git
synced 2025-10-27 16:49:31 +00:00
Parser only change state on success
This commit is contained in:
parent
0e755ea841
commit
c847fefd39
3 changed files with 59 additions and 16 deletions
|
|
@ -8,6 +8,7 @@ common = {
|
|||
local global_vars = state.interpreter.global_state.variables
|
||||
for var, value in pairs(state.variables) do
|
||||
global_vars[var] = value
|
||||
state.variables[var] = nil
|
||||
end
|
||||
end,
|
||||
-- returns a variable's value, evaluating a pending expression if neccessary
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@ local parse_text
|
|||
-- * nil, error: in case of error
|
||||
local function parse(state)
|
||||
-- expression parsing
|
||||
for _, l in ipairs(state.queued_lines) do
|
||||
for i=#state.queued_lines, 1, -1 do
|
||||
local l = state.queued_lines[i]
|
||||
local line, namespace = l.line, l.namespace
|
||||
-- default arguments and type annotation
|
||||
if line.type == "function" then
|
||||
|
|
@ -60,8 +61,8 @@ local function parse(state)
|
|||
if err then return nil, ("%s; at %s"):format(err, line.source) end
|
||||
line.text = txt
|
||||
end
|
||||
state.queued_lines[i] = nil
|
||||
end
|
||||
state.queued_lines = {}
|
||||
return true
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -57,9 +57,9 @@ local function parse_line(line, state, namespace)
|
|||
if r.type == "function" then
|
||||
r.remove_from_block_ast = true
|
||||
-- lua function
|
||||
if state.link_next_function_definition_to_lua_function then
|
||||
r.lua_function = state.link_next_function_definition_to_lua_function
|
||||
state.link_next_function_definition_to_lua_function = nil
|
||||
if state.global_state.link_next_function_definition_to_lua_function then
|
||||
r.lua_function = state.global_state.link_next_function_definition_to_lua_function
|
||||
state.global_state.link_next_function_definition_to_lua_function = nil
|
||||
end
|
||||
end
|
||||
-- get identifier
|
||||
|
|
@ -164,10 +164,18 @@ local function parse_line(line, state, namespace)
|
|||
r.arity = { minarity, maxarity }
|
||||
r.signature = signature(r)
|
||||
r.pretty_signature = pretty_signature(r)
|
||||
-- check for signature conflict with functions with the same fqm
|
||||
if state.functions[fqm] then
|
||||
for _, variant in ipairs(state.functions[fqm]) do
|
||||
if r.signature == variant.signature then
|
||||
return nil, ("trying to define %s %s, but another function with same signature %s exists; at %s"):format(r.type, r.pretty_signature, variant.pretty_signature, line.source)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- define variables
|
||||
if not line.children then line.children = {} end
|
||||
-- define 👁️ variable
|
||||
local seen_alias = state.builtin_aliases["👁️"]
|
||||
local seen_alias = state.global_state.builtin_aliases["👁️"]
|
||||
if seen_alias then
|
||||
table.insert(line.children, 1, { content = (":👁️:%s=0"):format(seen_alias), source = line.source })
|
||||
else
|
||||
|
|
@ -175,7 +183,7 @@ local function parse_line(line, state, namespace)
|
|||
end
|
||||
if r.type == "function" then
|
||||
-- define 🔖 variable
|
||||
local checkpoint_alias = state.builtin_aliases["🔖"]
|
||||
local checkpoint_alias = state.global_state.builtin_aliases["🔖"]
|
||||
if checkpoint_alias then
|
||||
table.insert(line.children, 1, { content = (":🔖:%s=\"\""):format(checkpoint_alias), source = line.source })
|
||||
else
|
||||
|
|
@ -183,7 +191,7 @@ local function parse_line(line, state, namespace)
|
|||
end
|
||||
elseif r.type == "checkpoint" then
|
||||
-- define 🏁 variable
|
||||
local reached_alias = state.builtin_aliases["🏁"]
|
||||
local reached_alias = state.global_state.builtin_aliases["🏁"]
|
||||
if reached_alias then
|
||||
table.insert(line.children, 1, { content = (":🏁:%s=0"):format(reached_alias), source = line.source })
|
||||
else
|
||||
|
|
@ -216,13 +224,6 @@ local function parse_line(line, state, namespace)
|
|||
state.functions[fqm] = { r }
|
||||
-- overloading
|
||||
else
|
||||
-- check for signature conflict with functions with the same fqm
|
||||
for _, variant in ipairs(state.functions[fqm]) do
|
||||
if r.signature == variant.signature then
|
||||
return nil, ("trying to define %s %s, but another function with same signature %s exists; at %s"):format(r.type, r.pretty_signature, variant.pretty_signature, line.source)
|
||||
end
|
||||
end
|
||||
-- add
|
||||
table.insert(state.functions[fqm], r)
|
||||
end
|
||||
-- definition
|
||||
|
|
@ -422,9 +423,49 @@ local function parse(state, s, name, source)
|
|||
end
|
||||
-- transform ast
|
||||
indented = transform_indented(indented)
|
||||
-- build state proxy
|
||||
local state_proxy = {
|
||||
aliases = setmetatable({}, { __index = state.aliases }),
|
||||
variables = setmetatable({}, { __index = state.aliases }),
|
||||
functions = setmetatable({}, {
|
||||
__index = function(self, key)
|
||||
if state.functions[key] then
|
||||
local t = {} -- need to copy to allow ipairs over variants
|
||||
for k, v in ipairs(state.functions[key]) do
|
||||
t[k] = v
|
||||
end
|
||||
self[key] = t
|
||||
return t
|
||||
end
|
||||
return nil
|
||||
end
|
||||
}),
|
||||
queued_lines = {},
|
||||
global_state = state
|
||||
}
|
||||
-- parse
|
||||
local root, err = parse_block(indented, state, "")
|
||||
local root, err = parse_block(indented, state_proxy, "")
|
||||
if not root then return nil, err end
|
||||
-- merge back state proxy into global state
|
||||
for k,v in pairs(state_proxy.aliases) do
|
||||
state.aliases[k] = v
|
||||
end
|
||||
for k,v in pairs(state_proxy.variables) do
|
||||
state.variables[k] = v
|
||||
end
|
||||
for k,v in pairs(state_proxy.functions) do
|
||||
if not state.functions[k] then
|
||||
state.functions[k] = v
|
||||
else
|
||||
for i,w in ipairs(v) do
|
||||
state.functions[k][i] = w
|
||||
end
|
||||
end
|
||||
end
|
||||
for _,l in ipairs(state_proxy.queued_lines) do
|
||||
table.insert(state.queued_lines, l)
|
||||
end
|
||||
-- return block
|
||||
return root
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue