1
0
Fork 0
mirror of https://github.com/Reuh/anselme.git synced 2025-10-27 08:39:30 +00:00

Add rounding functions

This commit is contained in:
Étienne Fildadut 2022-09-16 22:04:30 +09:00
parent e017a391ec
commit ccaa40a99d
3 changed files with 44 additions and 61 deletions

View file

@ -1077,6 +1077,12 @@ This only works on strings:
`rand([m[, n]])`: when called whitout arguments, returns a random float in [0,1). Otherwise, returns a random number in [m,n]; m=1 if not given.
`floor(x)`: returns the largest integral value less than or equal x
`ceil(x)`: returns the smallest integral value more than or equal x
`round(x, increment=1)`: returns the number, rounder to the nearest increment
`error(str)`: throw an error with the specified message
`annotation(v::annotated)`: returns v's annotation

View file

@ -24,6 +24,27 @@ local function maybe_alias(rem, fqm, namespace, line, state)
return true, rem, alias
end
--- inject lines defined for the injection that match parent_function type and inject_type in inject_in starting from index inject_at
local function inject(state, parent_function, inject_type, inject_in, inject_at)
inject_at = inject_at or #inject_in+1
local prefix
if parent_function.subtype == "checkpoint" then
prefix = "checkpoint"
elseif parent_function.subtype == "class" then
prefix = "class"
elseif parent_function.scoped then
prefix = "scoped_function"
else
prefix = "function"
end
local ninject = ("%s_%s"):format(prefix, inject_type)
if state.inject[ninject] then
for i, ll in ipairs(state.inject[ninject]) do
table.insert(inject_in, inject_at+i-1, copy(ll))
end
end
end
--- parse a single line into AST
-- * ast: if success
-- * nil, error: in case of error
@ -225,42 +246,8 @@ local function parse_line(line, state, namespace, parent_function)
table.insert(line.children, 1, { content = ":🔖=()", source = line.source })
end
-- custom code injection
if r.subtype == "class" then
if state.inject.class_start then
for i, ll in ipairs(state.inject.class_start) do
table.insert(line.children, 1+i, copy(ll))
end
end
if state.inject.class_end then
for _, ll in ipairs(state.inject.class_end) do
table.insert(line.children, copy(ll))
end
end
else
if r.scoped then
if state.inject.scoped_function_start then
for i, ll in ipairs(state.inject.scoped_function_start) do
table.insert(line.children, 1+i, copy(ll))
end
end
if state.inject.scoped_function_end then
for _, ll in ipairs(state.inject.scoped_function_end) do
table.insert(line.children, copy(ll))
end
end
else
if state.inject.function_start then
for i, ll in ipairs(state.inject.function_start) do
table.insert(line.children, 1+i, copy(ll))
end
end
if state.inject.function_end then
for _, ll in ipairs(state.inject.function_end) do
table.insert(line.children, copy(ll))
end
end
end
end
inject(state, r, "start", line.children, 2)
inject(state, r, "end", line.children)
elseif r.subtype == "checkpoint" then
-- define 🏁 variable
local reached_alias = state.global_state.builtin_aliases["🏁"]
@ -270,16 +257,8 @@ local function parse_line(line, state, namespace, parent_function)
table.insert(line.children, 1, { content = ":🏁=0", source = line.source })
end
-- custom code injection
if state.inject.checkpoint_start then
for i, ll in ipairs(state.inject.checkpoint_start) do
table.insert(line.children, 1+i, copy(ll))
end
end
if state.inject.checkpoint_end then
for _, ll in ipairs(state.inject.checkpoint_end) do
table.insert(line.children, copy(ll))
end
end
inject(state, r, "start", line.children, 2)
inject(state, r, "end", line.children)
end
-- define args
for _, param in ipairs(r.params) do
@ -373,19 +352,7 @@ local function parse_line(line, state, namespace, parent_function)
end
-- custom code injection
if not line.children then line.children = {} end
if parent_function.scoped then
if state.inject.scoped_function_return then
for _, ll in ipairs(state.inject.scoped_function_return) do
table.insert(line.children, copy(ll))
end
end
else
if state.inject.function_return then
for _, ll in ipairs(state.inject.function_return) do
table.insert(line.children, copy(ll))
end
end
end
inject(state, parent_function, "return", line.children)
-- text
elseif l:match("[^%s]") then
r.type = "text"
@ -559,9 +526,9 @@ local function parse(state, s, name, source)
global_state = state
}
-- parse injects
for inject, ninject in pairs(injections) do
for tinject, ninject in pairs(injections) do
if state.inject[ninject] then
local inject_indented, err = parse_indented(state.inject[ninject], nil, "injected "..inject)
local inject_indented, err = parse_indented(state.inject[ninject], nil, "injected "..tinject)
if not inject_indented then return nil, err end
state_proxy.inject[ninject] = inject_indented
end

View file

@ -386,6 +386,16 @@ lua_functions = {
["rand()"] = function() return math.random() end,
["rand(a::number)"] = function(a) return math.random(a) end,
["rand(a::number, b::number)"] = function(a, b) return math.random(a, b) end,
["floor(a::number)"] = function(a) return math.floor(a) end,
["ceil(a::number)"] = function(a) return math.ceil(a) end,
["round(a::number, increment=1::number)"] = function(a, increment)
local n = a / increment
if n >= 0 then
return math.floor(n + 0.5) * increment
else
return math.ceil(n - 0.5) * increment
end
end,
["unannotated(v)"] = {
mode = "raw",
value = function(v)