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:
parent
581c60048d
commit
dac5b74fa6
30 changed files with 272 additions and 14 deletions
|
|
@ -47,6 +47,9 @@ List = ast.abstract.Runtime {
|
||||||
iter = function(self, state)
|
iter = function(self, state)
|
||||||
return self.branched:get(state):iter()
|
return self.branched:get(state):iter()
|
||||||
end,
|
end,
|
||||||
|
find = function(self, state, value)
|
||||||
|
return self.branched:get(state):find(value)
|
||||||
|
end,
|
||||||
get = function(self, state, index)
|
get = function(self, state, index)
|
||||||
local list = self.branched:get(state)
|
local list = self.branched:get(state)
|
||||||
if index < 0 then index = #list.list + 1 + index end
|
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
|
if index > #list.list+1 or index == 0 then error("list index out of bounds", 0) end
|
||||||
list.list[index] = val
|
list.list[index] = val
|
||||||
end,
|
end,
|
||||||
insert = function(self, state, val)
|
insert = function(self, state, position, val)
|
||||||
local l = self:_prepare_branch(state)
|
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,
|
end,
|
||||||
remove = function(self, state)
|
remove = function(self, state, position)
|
||||||
local l = self:_prepare_branch(state)
|
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,
|
end,
|
||||||
|
|
||||||
to_tuple = function(self, state)
|
to_tuple = function(self, state)
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,14 @@ Tuple = ast.abstract.Node {
|
||||||
iter = function(self)
|
iter = function(self)
|
||||||
return ipairs(self.list)
|
return ipairs(self.list)
|
||||||
end,
|
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
|
return Tuple
|
||||||
|
|
|
||||||
|
|
@ -57,4 +57,12 @@ return {
|
||||||
},
|
},
|
||||||
{ "true", Boolean:new(true) },
|
{ "true", Boolean:new(true) },
|
||||||
{ "false", Boolean:new(false) },
|
{ "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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ return function(main_state)
|
||||||
"number",
|
"number",
|
||||||
"string",
|
"string",
|
||||||
"text",
|
"text",
|
||||||
|
"pair",
|
||||||
"structures",
|
"structures",
|
||||||
"closure",
|
"closure",
|
||||||
"checkpoint",
|
"checkpoint",
|
||||||
|
|
|
||||||
|
|
@ -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", "(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", "(max::number)", function(state, max) return Number:new(math.random(max.number)) end },
|
||||||
{ "rand", "()", function(state) return Number:new(math.random()) 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
14
anselme/stdlib/pair.lua
Normal 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
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,13 @@
|
||||||
|
local utf8 = utf8 or require("lua-utf8")
|
||||||
local ast = require("anselme.ast")
|
local ast = require("anselme.ast")
|
||||||
local String = ast.String
|
local String, Number = ast.String, ast.Number
|
||||||
|
|
||||||
return {
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,17 @@ return {
|
||||||
return Number:new(l:len())
|
return Number:new(l:len())
|
||||||
end
|
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
|
-- list
|
||||||
{
|
{
|
||||||
|
|
@ -36,17 +47,49 @@ return {
|
||||||
return Nil:new()
|
return Nil:new()
|
||||||
end
|
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)",
|
"insert", "(l::list, value)",
|
||||||
function(state, l, v)
|
function(state, l, v)
|
||||||
l:insert(state, v)
|
l:insert(state, v)
|
||||||
return Nil:new()
|
return Nil:new()
|
||||||
end
|
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)
|
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
|
end
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
local ast = require("anselme.ast")
|
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 event_manager = require("anselme.state.event_manager")
|
||||||
local translation_manager = require("anselme.state.translation_manager")
|
local translation_manager = require("anselme.state.translation_manager")
|
||||||
|
|
@ -8,6 +8,19 @@ local resume_manager = require("anselme.state.resume_manager")
|
||||||
|
|
||||||
return {
|
return {
|
||||||
-- text
|
-- 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)",
|
"_!", "(txt::text)",
|
||||||
function(state, text)
|
function(state, text)
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ return {
|
||||||
|
|
||||||
{ "text", "(x)", function(state, x) return Boolean:new(x.type == "text") end },
|
{ "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 },
|
{ "tuple", "(x)", function(state, x) return Boolean:new(x.type == "tuple") end },
|
||||||
{ "list", "(x)", function(state, x) return Boolean:new(x.type == "list") 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 },
|
{ "struct", "(x)", function(state, x) return Boolean:new(x.type == "struct") end },
|
||||||
|
|
|
||||||
5
ideas.md
5
ideas.md
|
|
@ -20,10 +20,9 @@ Do some more fancy scope work to allow the translation to access variables defin
|
||||||
|
|
||||||
Standard library.
|
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.
|
* 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.
|
* And in general, clean up everything.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
|
||||||
7
test/results/error.ans
Normal file
7
test/results/error.ans
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
--# run #--
|
||||||
|
--- error ---
|
||||||
|
[0m[31m[0m[31mnope[0m
|
||||||
|
↳ from [4mtest/tests/error.ans:1:6[0m in call: [2merror("nope")[0m[0m
|
||||||
|
↳ from [4m?[0m in block: [2merror("nope")[0m
|
||||||
|
--# saved #--
|
||||||
|
{}
|
||||||
13
test/results/floor ceil round.ans
Normal file
13
test/results/floor ceil round.ans
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
--# run #--
|
||||||
|
--- text ---
|
||||||
|
| {}"" {}"3" {}"" |
|
||||||
|
--- text ---
|
||||||
|
| {}"" {}"4" {}"" |
|
||||||
|
--- text ---
|
||||||
|
| {}"" {}"3" {}"" |
|
||||||
|
--- text ---
|
||||||
|
| {}"" {}"3.142" {}"" |
|
||||||
|
--- return ---
|
||||||
|
()
|
||||||
|
--# saved #--
|
||||||
|
{}
|
||||||
9
test/results/list find.ans
Normal file
9
test/results/list find.ans
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
--# run #--
|
||||||
|
--- text ---
|
||||||
|
| {}"" {}"3" {}"" |
|
||||||
|
--- text ---
|
||||||
|
| {}"" {}"3" {}"" |
|
||||||
|
--- return ---
|
||||||
|
()
|
||||||
|
--# saved #--
|
||||||
|
{}
|
||||||
11
test/results/list insert.ans
Normal file
11
test/results/list insert.ans
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
--# run #--
|
||||||
|
--- text ---
|
||||||
|
| {}"" {}"*[1, 2, 3]" {}"" |
|
||||||
|
--- text ---
|
||||||
|
| {}"" {}"*[1, 2, 3, 4]" {}"" |
|
||||||
|
--- text ---
|
||||||
|
| {}"" {}"*[1, 5, 2, 3, 4]" {}"" |
|
||||||
|
--- return ---
|
||||||
|
()
|
||||||
|
--# saved #--
|
||||||
|
{}
|
||||||
9
test/results/list len.ans
Normal file
9
test/results/list len.ans
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
--# run #--
|
||||||
|
--- text ---
|
||||||
|
| {}"" {}"4" {}"" |
|
||||||
|
--- text ---
|
||||||
|
| {}"" {}"4" {}"" |
|
||||||
|
--- return ---
|
||||||
|
()
|
||||||
|
--# saved #--
|
||||||
|
{}
|
||||||
11
test/results/list remove.ans
Normal file
11
test/results/list remove.ans
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
--# run #--
|
||||||
|
--- text ---
|
||||||
|
| {}"" {}"*[1, 2, 3, 4, 5]" {}"" |
|
||||||
|
--- text ---
|
||||||
|
| {}"" {}"*[1, 2, 3, 4]" {}"" |
|
||||||
|
--- text ---
|
||||||
|
| {}"" {}"*[1, 3, 4]" {}"" |
|
||||||
|
--- return ---
|
||||||
|
()
|
||||||
|
--# saved #--
|
||||||
|
{}
|
||||||
9
test/results/pair name value.ans
Normal file
9
test/results/pair name value.ans
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
--# run #--
|
||||||
|
--- text ---
|
||||||
|
| {}"" {}"foo" {}"" |
|
||||||
|
--- text ---
|
||||||
|
| {}"" {}"barr" {}"" |
|
||||||
|
--- return ---
|
||||||
|
()
|
||||||
|
--# saved #--
|
||||||
|
{}
|
||||||
7
test/results/string len.ans
Normal file
7
test/results/string len.ans
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
--# run #--
|
||||||
|
--- text ---
|
||||||
|
| {}"" {}"5" {}"" |
|
||||||
|
--- return ---
|
||||||
|
()
|
||||||
|
--# saved #--
|
||||||
|
{}
|
||||||
7
test/results/text concat.ans
Normal file
7
test/results/text concat.ans
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
--# run #--
|
||||||
|
--- text ---
|
||||||
|
| {"a":"b"}"hello" {"b":"c"}"world and " {"b":"c", "x":"y"}"friends" {"b":"c"}"" |
|
||||||
|
--- return ---
|
||||||
|
()
|
||||||
|
--# saved #--
|
||||||
|
{}
|
||||||
|
|
@ -77,7 +77,6 @@ local function run(path, interactive)
|
||||||
local state = anselme:new()
|
local state = anselme:new()
|
||||||
state:load_stdlib()
|
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", "(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("interrupt", "()", function(state) state:interrupt() return ast.Nil:new() end, true)
|
||||||
state:define("wait", "(duration::number)", function(duration) coroutine.yield("wait", duration) end)
|
state:define("wait", "(duration::number)", function(duration) coroutine.yield("wait", duration) end)
|
||||||
|
|
|
||||||
1
test/tests/error.ans
Normal file
1
test/tests/error.ans
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
error("nope")
|
||||||
9
test/tests/floor ceil round.ans
Normal file
9
test/tests/floor ceil round.ans
Normal 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
5
test/tests/list find.ans
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
:l = [5,4,2,1]
|
||||||
|
|
||||||
|
|{l!find(2)}
|
||||||
|
|
||||||
|
|{(*l)!find(2)}
|
||||||
11
test/tests/list insert.ans
Normal file
11
test/tests/list insert.ans
Normal 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
5
test/tests/list len.ans
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
:l = [5,4,2,1]
|
||||||
|
|
||||||
|
|{l!len}
|
||||||
|
|
||||||
|
|{(*l)!len}
|
||||||
11
test/tests/list remove.ans
Normal file
11
test/tests/list remove.ans
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
:l = *[1,2,3,4,5]
|
||||||
|
|
||||||
|
|{l}
|
||||||
|
|
||||||
|
l!remove()
|
||||||
|
|
||||||
|
|{l}
|
||||||
|
|
||||||
|
l!remove(2)
|
||||||
|
|
||||||
|
|{l}
|
||||||
5
test/tests/pair name value.ans
Normal file
5
test/tests/pair name value.ans
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
:a = "foo":"barr"
|
||||||
|
|
||||||
|
|{a!name}
|
||||||
|
|
||||||
|
|{a!value}
|
||||||
3
test/tests/string len.ans
Normal file
3
test/tests/string len.ans
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
:x = "hÉllo"
|
||||||
|
|
||||||
|
|{x!len}
|
||||||
5
test/tests/text concat.ans
Normal file
5
test/tests/text concat.ans
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
:a = ("a":"b" # | hello)
|
||||||
|
|
||||||
|
:b = ("b":"c" # | world and { "x":"y" # |friends })
|
||||||
|
|
||||||
|
a+b
|
||||||
Loading…
Add table
Add a link
Reference in a new issue