1
0
Fork 0
mirror of https://github.com/Reuh/anselme.git synced 2025-10-27 16:49:31 +00:00

Add stdlib functions from anselme v1

This commit is contained in:
Étienne Fildadut 2024-01-04 20:22:18 +01:00
parent 581c60048d
commit dac5b74fa6
30 changed files with 272 additions and 14 deletions

View file

@ -47,6 +47,9 @@ List = ast.abstract.Runtime {
iter = function(self, state)
return self.branched:get(state):iter()
end,
find = function(self, state, value)
return self.branched:get(state):find(value)
end,
get = function(self, state, index)
local list = self.branched:get(state)
if index < 0 then index = #list.list + 1 + index end
@ -59,13 +62,21 @@ List = ast.abstract.Runtime {
if index > #list.list+1 or index == 0 then error("list index out of bounds", 0) end
list.list[index] = val
end,
insert = function(self, state, val)
insert = function(self, state, position, val)
local l = self:_prepare_branch(state)
table.insert(l.list, val)
if val then
table.insert(l.list, position, val)
else
table.insert(l.list, position)
end
end,
remove = function(self, state)
remove = function(self, state, position)
local l = self:_prepare_branch(state)
table.remove(l.list)
if position then
table.remove(l.list, position)
else
table.remove(l.list)
end
end,
to_tuple = function(self, state)

View file

@ -72,6 +72,14 @@ Tuple = ast.abstract.Node {
iter = function(self)
return ipairs(self.list)
end,
find = function(self, value)
for i, v in self:iter() do
if v:hash() == value:hash() then
return i
end
end
return nil
end
}
return Tuple

View file

@ -57,4 +57,12 @@ return {
},
{ "true", Boolean:new(true) },
{ "false", Boolean:new(false) },
{
"error", "(message=\"error\")",
function(state, message)
if message.type == "string" then message = message.string end
error(message:format(state), 0)
end
}
}

View file

@ -26,6 +26,7 @@ return function(main_state)
"number",
"string",
"text",
"pair",
"structures",
"closure",
"checkpoint",

View file

@ -50,4 +50,20 @@ return {
{ "rand", "(min::number, max::number)", function(state, min, max) return Number:new(math.random(min.number, max.number)) end },
{ "rand", "(max::number)", function(state, max) return Number:new(math.random(max.number)) end },
{ "rand", "()", function(state) return Number:new(math.random()) end },
{ "floor", "(x::number)", function(state, x) return Number:new(math.floor(x.number)) end },
{ "ceil", "(x::number)", function(state, x) return Number:new(math.ceil(x.number)) end },
{
"round", "(x::number, increment=1)",
function(state, x, increment)
local n = x.number / increment.number
if n >= 0 then
return Number:new(math.floor(n + 0.5) * increment.number)
else
return Number:new(math.ceil(n - 0.5) * increment.number)
end
end
},
{ "pi", Number:new(math.pi) }
}

14
anselme/stdlib/pair.lua Normal file
View file

@ -0,0 +1,14 @@
return {
{
"name", "(pair::pair)",
function(state, pair)
return pair.name
end
},
{
"value", "(pair::pair)",
function(state, pair)
return pair.value
end
},
}

View file

@ -1,6 +1,13 @@
local utf8 = utf8 or require("lua-utf8")
local ast = require("anselme.ast")
local String = ast.String
local String, Number = ast.String, ast.Number
return {
{ "_+_", "(a::string, b::string)", function(state, a, b) return String:new(a.string .. b.string) end }
{ "_+_", "(a::string, b::string)", function(state, a, b) return String:new(a.string .. b.string) end },
{
"len", "(s::string)",
function(state, s)
return Number:new(utf8.len(s.string))
end
}
}

View file

@ -21,6 +21,17 @@ return {
return Number:new(l:len())
end
},
{
"find", "(l::tuple, value)",
function(state, l, v)
local i = l:find(v)
if i then
return Number:new(i)
else
return Nil:new()
end
end
},
-- list
{
@ -36,17 +47,49 @@ return {
return Nil:new()
end
},
{
"len", "(l::list)",
function(state, l)
return Number:new(l:len(state))
end
},
{
"find", "(l::list, value)",
function(state, l, v)
local i = l:find(state, v)
if i then
return Number:new(i)
else
return Nil:new()
end
end
},
{
"insert", "(l::list, value)",
function(state, l, v)
l:insert(state, v)
l:insert(state, v)
return Nil:new()
end
},
{
"len", "(l::list)",
"insert", "(l::list, position::number, value)",
function(state, l, position, v)
l:insert(state, position.number, v)
return Nil:new()
end
},
{
"remove", "(l::list)",
function(state, l)
return Number:new(l:len(state))
l:remove(state)
return Nil:new()
end
},
{
"remove", "(l::list, position::number)",
function(state, l, position)
l:remove(state, position.number)
return Nil:new()
end
},
{

View file

@ -1,5 +1,5 @@
local ast = require("anselme.ast")
local Nil, Choice, PartialScope, ArgumentTuple, Identifier = ast.Nil, ast.Choice, ast.PartialScope, ast.ArgumentTuple, ast.Identifier
local Nil, Choice, PartialScope, ArgumentTuple, Identifier, Text = ast.Nil, ast.Choice, ast.PartialScope, ast.ArgumentTuple, ast.Identifier, ast.Text
local event_manager = require("anselme.state.event_manager")
local translation_manager = require("anselme.state.translation_manager")
@ -8,6 +8,19 @@ local resume_manager = require("anselme.state.resume_manager")
return {
-- text
{
"_+_", "(a::text, b::text)",
function(state, a, b)
local r = Text:new()
for _, e in ipairs(a.list) do
r:insert(e[1], e[2])
end
for _, e in ipairs(b.list) do
r:insert(e[1], e[2])
end
return r
end
},
{
"_!", "(txt::text)",
function(state, text)

View file

@ -11,6 +11,7 @@ return {
{ "text", "(x)", function(state, x) return Boolean:new(x.type == "text") end },
{ "pair", "(x)", function(state, x) return Boolean:new(x.type == "pair") end },
{ "tuple", "(x)", function(state, x) return Boolean:new(x.type == "tuple") end },
{ "list", "(x)", function(state, x) return Boolean:new(x.type == "list") end },
{ "struct", "(x)", function(state, x) return Boolean:new(x.type == "struct") end },

View file

@ -20,10 +20,9 @@ Do some more fancy scope work to allow the translation to access variables defin
Standard library.
* Text manipulation would make sense, but that would require a full UTF-8/Unicode support library like https://github.com/starwing/luautf8.
* Text and string manipulation would make sense, but that would require a full UTF-8/Unicode support library like https://github.com/starwing/luautf8.
- retag/add tags
* Something to load other files. Maybe not load it by default to let the calling game sandbox Anselme. Probably create an export scope per file to perform some nice module loading.
* Implement the useful functions from Anselme v1.
* Text manipulation: concatenation, retag/add tags
* And in general, clean up everything.
---

7
test/results/error.ans Normal file
View file

@ -0,0 +1,7 @@
--# run #--
--- error ---
nope
↳ from test/tests/error.ans:1:6 in call: error("nope")
↳ from ? in block: error("nope")
--# saved #--
{}

View file

@ -0,0 +1,13 @@
--# run #--
--- text ---
| {}"" {}"3" {}"" |
--- text ---
| {}"" {}"4" {}"" |
--- text ---
| {}"" {}"3" {}"" |
--- text ---
| {}"" {}"3.142" {}"" |
--- return ---
()
--# saved #--
{}

View file

@ -0,0 +1,9 @@
--# run #--
--- text ---
| {}"" {}"3" {}"" |
--- text ---
| {}"" {}"3" {}"" |
--- return ---
()
--# saved #--
{}

View file

@ -0,0 +1,11 @@
--# run #--
--- text ---
| {}"" {}"*[1, 2, 3]" {}"" |
--- text ---
| {}"" {}"*[1, 2, 3, 4]" {}"" |
--- text ---
| {}"" {}"*[1, 5, 2, 3, 4]" {}"" |
--- return ---
()
--# saved #--
{}

View file

@ -0,0 +1,9 @@
--# run #--
--- text ---
| {}"" {}"4" {}"" |
--- text ---
| {}"" {}"4" {}"" |
--- return ---
()
--# saved #--
{}

View file

@ -0,0 +1,11 @@
--# run #--
--- text ---
| {}"" {}"*[1, 2, 3, 4, 5]" {}"" |
--- text ---
| {}"" {}"*[1, 2, 3, 4]" {}"" |
--- text ---
| {}"" {}"*[1, 3, 4]" {}"" |
--- return ---
()
--# saved #--
{}

View file

@ -0,0 +1,9 @@
--# run #--
--- text ---
| {}"" {}"foo" {}"" |
--- text ---
| {}"" {}"barr" {}"" |
--- return ---
()
--# saved #--
{}

View file

@ -0,0 +1,7 @@
--# run #--
--- text ---
| {}"" {}"5" {}"" |
--- return ---
()
--# saved #--
{}

View file

@ -0,0 +1,7 @@
--# run #--
--- text ---
| {"a":"b"}"hello" {"b":"c"}"world and " {"b":"c", "x":"y"}"friends" {"b":"c"}"" |
--- return ---
()
--# saved #--
{}

View file

@ -77,7 +77,6 @@ local function run(path, interactive)
local state = anselme:new()
state:load_stdlib()
state:define("error", "(message=\"error\")", function(message) error(message, 0) end)
state:define("interrupt", "(code::string)", function(state, code) state:interrupt(code:to_lua(state), "interrupt") return ast.Nil:new() end, true)
state:define("interrupt", "()", function(state) state:interrupt() return ast.Nil:new() end, true)
state:define("wait", "(duration::number)", function(duration) coroutine.yield("wait", duration) end)

1
test/tests/error.ans Normal file
View file

@ -0,0 +1 @@
error("nope")

View file

@ -0,0 +1,9 @@
:x = pi
|{floor(x)}
|{ceil(x)}
|{round(x)}
|{round(x, 0.001)}

5
test/tests/list find.ans Normal file
View file

@ -0,0 +1,5 @@
:l = [5,4,2,1]
|{l!find(2)}
|{(*l)!find(2)}

View file

@ -0,0 +1,11 @@
:l = *[1,2,3]
|{l}
l!insert(4)
|{l}
l!insert(2, 5)
|{l}

5
test/tests/list len.ans Normal file
View file

@ -0,0 +1,5 @@
:l = [5,4,2,1]
|{l!len}
|{(*l)!len}

View file

@ -0,0 +1,11 @@
:l = *[1,2,3,4,5]
|{l}
l!remove()
|{l}
l!remove(2)
|{l}

View file

@ -0,0 +1,5 @@
:a = "foo":"barr"
|{a!name}
|{a!value}

View file

@ -0,0 +1,3 @@
:x = "hÉllo"
|{x!len}

View file

@ -0,0 +1,5 @@
:a = ("a":"b" # | hello)
:b = ("b":"c" # | world and { "x":"y" # |friends })
a+b