mirror of
https://github.com/Reuh/anselme.git
synced 2025-10-28 00:59: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
|
local global_vars = state.interpreter.global_state.variables
|
||||||
for var, value in pairs(state.variables) do
|
for var, value in pairs(state.variables) do
|
||||||
global_vars[var] = value
|
global_vars[var] = value
|
||||||
|
state.variables[var] = nil
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
-- returns a variable's value, evaluating a pending expression if neccessary
|
-- returns a variable's value, evaluating a pending expression if neccessary
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@ local parse_text
|
||||||
-- * nil, error: in case of error
|
-- * nil, error: in case of error
|
||||||
local function parse(state)
|
local function parse(state)
|
||||||
-- expression parsing
|
-- 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
|
local line, namespace = l.line, l.namespace
|
||||||
-- default arguments and type annotation
|
-- default arguments and type annotation
|
||||||
if line.type == "function" then
|
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
|
if err then return nil, ("%s; at %s"):format(err, line.source) end
|
||||||
line.text = txt
|
line.text = txt
|
||||||
end
|
end
|
||||||
|
state.queued_lines[i] = nil
|
||||||
end
|
end
|
||||||
state.queued_lines = {}
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,9 +57,9 @@ local function parse_line(line, state, namespace)
|
||||||
if r.type == "function" then
|
if r.type == "function" then
|
||||||
r.remove_from_block_ast = true
|
r.remove_from_block_ast = true
|
||||||
-- lua function
|
-- lua function
|
||||||
if state.link_next_function_definition_to_lua_function then
|
if state.global_state.link_next_function_definition_to_lua_function then
|
||||||
r.lua_function = state.link_next_function_definition_to_lua_function
|
r.lua_function = state.global_state.link_next_function_definition_to_lua_function
|
||||||
state.link_next_function_definition_to_lua_function = nil
|
state.global_state.link_next_function_definition_to_lua_function = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- get identifier
|
-- get identifier
|
||||||
|
|
@ -164,10 +164,18 @@ local function parse_line(line, state, namespace)
|
||||||
r.arity = { minarity, maxarity }
|
r.arity = { minarity, maxarity }
|
||||||
r.signature = signature(r)
|
r.signature = signature(r)
|
||||||
r.pretty_signature = pretty_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
|
-- define variables
|
||||||
if not line.children then line.children = {} end
|
if not line.children then line.children = {} end
|
||||||
-- define 👁️ variable
|
-- define 👁️ variable
|
||||||
local seen_alias = state.builtin_aliases["👁️"]
|
local seen_alias = state.global_state.builtin_aliases["👁️"]
|
||||||
if seen_alias then
|
if seen_alias then
|
||||||
table.insert(line.children, 1, { content = (":👁️:%s=0"):format(seen_alias), source = line.source })
|
table.insert(line.children, 1, { content = (":👁️:%s=0"):format(seen_alias), source = line.source })
|
||||||
else
|
else
|
||||||
|
|
@ -175,7 +183,7 @@ local function parse_line(line, state, namespace)
|
||||||
end
|
end
|
||||||
if r.type == "function" then
|
if r.type == "function" then
|
||||||
-- define 🔖 variable
|
-- define 🔖 variable
|
||||||
local checkpoint_alias = state.builtin_aliases["🔖"]
|
local checkpoint_alias = state.global_state.builtin_aliases["🔖"]
|
||||||
if checkpoint_alias then
|
if checkpoint_alias then
|
||||||
table.insert(line.children, 1, { content = (":🔖:%s=\"\""):format(checkpoint_alias), source = line.source })
|
table.insert(line.children, 1, { content = (":🔖:%s=\"\""):format(checkpoint_alias), source = line.source })
|
||||||
else
|
else
|
||||||
|
|
@ -183,7 +191,7 @@ local function parse_line(line, state, namespace)
|
||||||
end
|
end
|
||||||
elseif r.type == "checkpoint" then
|
elseif r.type == "checkpoint" then
|
||||||
-- define 🏁 variable
|
-- define 🏁 variable
|
||||||
local reached_alias = state.builtin_aliases["🏁"]
|
local reached_alias = state.global_state.builtin_aliases["🏁"]
|
||||||
if reached_alias then
|
if reached_alias then
|
||||||
table.insert(line.children, 1, { content = (":🏁:%s=0"):format(reached_alias), source = line.source })
|
table.insert(line.children, 1, { content = (":🏁:%s=0"):format(reached_alias), source = line.source })
|
||||||
else
|
else
|
||||||
|
|
@ -216,13 +224,6 @@ local function parse_line(line, state, namespace)
|
||||||
state.functions[fqm] = { r }
|
state.functions[fqm] = { r }
|
||||||
-- overloading
|
-- overloading
|
||||||
else
|
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)
|
table.insert(state.functions[fqm], r)
|
||||||
end
|
end
|
||||||
-- definition
|
-- definition
|
||||||
|
|
@ -422,9 +423,49 @@ local function parse(state, s, name, source)
|
||||||
end
|
end
|
||||||
-- transform ast
|
-- transform ast
|
||||||
indented = transform_indented(indented)
|
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
|
-- parse
|
||||||
local root, err = parse_block(indented, state, "")
|
local root, err = parse_block(indented, state_proxy, "")
|
||||||
if not root then return nil, err end
|
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
|
return root
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue