mirror of
https://github.com/Reuh/anselme.git
synced 2025-10-27 08:39:30 +00:00
[internal] clean up format calls in interpolations, add format(val::is string) without quotes
This commit is contained in:
parent
bdc4f8a13a
commit
02fa9d075d
8 changed files with 39 additions and 31 deletions
|
|
@ -36,10 +36,10 @@ local StringInterpolation = ast.abstract.Node {
|
||||||
local t = {}
|
local t = {}
|
||||||
for _, e in ipairs(self.list) do
|
for _, e in ipairs(self.list) do
|
||||||
local r = e:eval(state)
|
local r = e:eval(state)
|
||||||
if String:is(r) then
|
if String:is(e) then -- raw string
|
||||||
r = r.string
|
r = e.string
|
||||||
else
|
else -- interpolation
|
||||||
r = r:format(state)
|
r = e:format_custom(state)
|
||||||
end
|
end
|
||||||
table.insert(t, r)
|
table.insert(t, r)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -39,14 +39,14 @@ local TextInterpolation = ast.abstract.Node {
|
||||||
local tags = tag_manager:get(state)
|
local tags = tag_manager:get(state)
|
||||||
for _, e in ipairs(self.list) do
|
for _, e in ipairs(self.list) do
|
||||||
local r = e:eval(state)
|
local r = e:eval(state)
|
||||||
if String:is(r) then
|
if String:is(e) then -- raw string
|
||||||
t:insert(r, tags)
|
t:insert(r, tags)
|
||||||
elseif Text:is(r) then
|
elseif Text:is(r) then -- interpolation
|
||||||
for _, v in ipairs(r.list) do
|
for _, v in ipairs(r.list) do
|
||||||
t:insert(v[1], v[2])
|
t:insert(v[1], v[2])
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
t:insert(String:new(r:format(state)), tags)
|
t:insert(String:new(r:format_custom(state)), tags)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return t
|
return t
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,6 @@ local ast = require("anselme.ast")
|
||||||
|
|
||||||
local operator_priority = require("anselme.common").operator_priority
|
local operator_priority = require("anselme.common").operator_priority
|
||||||
|
|
||||||
local format_identifier
|
|
||||||
|
|
||||||
local ArgumentTuple
|
|
||||||
|
|
||||||
local Typed
|
local Typed
|
||||||
Typed = ast.abstract.Runtime {
|
Typed = ast.abstract.Runtime {
|
||||||
type = "typed",
|
type = "typed",
|
||||||
|
|
@ -19,15 +15,6 @@ Typed = ast.abstract.Runtime {
|
||||||
end,
|
end,
|
||||||
|
|
||||||
_format = function(self, state, prio, ...)
|
_format = function(self, state, prio, ...)
|
||||||
-- try custom format
|
|
||||||
if state and state.scope:defined(format_identifier) then
|
|
||||||
local custom_format = format_identifier:eval(state)
|
|
||||||
local args = ArgumentTuple:new(self)
|
|
||||||
local fn, d_args = custom_format:dispatch(state, args)
|
|
||||||
if fn then
|
|
||||||
return custom_format:call(state, d_args):format(state, prio, ...)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return ("type(%s, %s)"):format(self.expression:format(state, operator_priority["_,_"], ...), self.type_expression:format_right(state, operator_priority["_,_"], ...))
|
return ("type(%s, %s)"):format(self.expression:format(state, operator_priority["_,_"], ...), self.type_expression:format_right(state, operator_priority["_,_"], ...))
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
|
@ -37,8 +24,4 @@ Typed = ast.abstract.Runtime {
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
|
|
||||||
package.loaded[...] = Typed
|
|
||||||
format_identifier = ast.Identifier:new("format")
|
|
||||||
ArgumentTuple = ast.ArgumentTuple
|
|
||||||
|
|
||||||
return Typed
|
return Typed
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,10 @@ local unpack = table.unpack or unpack
|
||||||
|
|
||||||
local uuid = require("anselme.common").uuid
|
local uuid = require("anselme.common").uuid
|
||||||
|
|
||||||
local Call, Identifier, Struct, Tuple, String, Pair
|
local Call, Identifier, Struct, Tuple, String, Pair, ArgumentTuple
|
||||||
local resume_manager
|
local resume_manager
|
||||||
|
|
||||||
local custom_call_identifier
|
local custom_call_identifier, custom_format_identifier
|
||||||
|
|
||||||
local context_max_length = 50
|
local context_max_length = 50
|
||||||
local function cutoff_text(str)
|
local function cutoff_text(str)
|
||||||
|
|
@ -372,6 +372,18 @@ Node = class {
|
||||||
_format_priority_cache = nil, -- cached priority
|
_format_priority_cache = nil, -- cached priority
|
||||||
from_symbol = nil, -- last symbol this node was retrived from
|
from_symbol = nil, -- last symbol this node was retrived from
|
||||||
|
|
||||||
|
-- return a human-readable, string representation of the node
|
||||||
|
-- this works by calling the `format(node)` anselme method (if the method returns a non-string value, it is converted to a string using :format)
|
||||||
|
format_custom = function(self, state)
|
||||||
|
local custom_format = custom_format_identifier:eval(state)
|
||||||
|
local r = custom_format:call(state, ArgumentTuple:new(self))
|
||||||
|
if String:is(r) then
|
||||||
|
return r.string
|
||||||
|
else
|
||||||
|
return r:format(state)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
-- return Lua value
|
-- return Lua value
|
||||||
-- this should probably be only called on a Node that is already evaluated
|
-- this should probably be only called on a Node that is already evaluated
|
||||||
-- redefine if you want, probably only for nodes that are already evaluated
|
-- redefine if you want, probably only for nodes that are already evaluated
|
||||||
|
|
@ -430,8 +442,9 @@ Node = class {
|
||||||
-- Thus, any require here that may require other Nodes shall be done here. This method is called in anselme.lua after everything else is required.
|
-- Thus, any require here that may require other Nodes shall be done here. This method is called in anselme.lua after everything else is required.
|
||||||
_i_hate_cycles = function(self)
|
_i_hate_cycles = function(self)
|
||||||
local ast = require("anselme.ast")
|
local ast = require("anselme.ast")
|
||||||
Call, Identifier, Struct, Tuple, String, Pair = ast.Call, ast.Identifier, ast.Struct, ast.Tuple, ast.String, ast.Pair
|
Call, Identifier, Struct, Tuple, String, Pair, ArgumentTuple = ast.Call, ast.Identifier, ast.Struct, ast.Tuple, ast.String, ast.Pair, ast.ArgumentTuple
|
||||||
custom_call_identifier = Identifier:new("_!")
|
custom_call_identifier = Identifier:new("_!")
|
||||||
|
custom_format_identifier = Identifier:new("format")
|
||||||
|
|
||||||
resume_manager = require("anselme.state.resume_manager")
|
resume_manager = require("anselme.state.resume_manager")
|
||||||
end,
|
end,
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,18 @@ return {
|
||||||
{
|
{
|
||||||
"print", "(a)",
|
"print", "(a)",
|
||||||
function(state, a)
|
function(state, a)
|
||||||
print(a:format(state))
|
print(a:format_custom(state))
|
||||||
return Nil:new()
|
return Nil:new()
|
||||||
end
|
end
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"hash", "(a)",
|
"hash", "(a)",
|
||||||
|
"format", "(val)",
|
||||||
|
function(state, val)
|
||||||
|
return String:new(val:format(state))
|
||||||
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
function(state, a)
|
function(state, a)
|
||||||
return String:new(a:hash())
|
return String:new(a:hash())
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -9,5 +9,11 @@ return {
|
||||||
function(state, s)
|
function(state, s)
|
||||||
return Number:new(utf8.len(s.string))
|
return Number:new(utf8.len(s.string))
|
||||||
end
|
end
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"format", "(val::is string)",
|
||||||
|
function(state, val)
|
||||||
|
return val
|
||||||
|
end
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -485,7 +485,7 @@ Strings literal starts with a `"` and end with a `"`. Specials characters, inclu
|
||||||
* `\n` is replaced with a newline
|
* `\n` is replaced with a newline
|
||||||
* `\t` is replaced with a tab character
|
* `\t` is replaced with a tab character
|
||||||
|
|
||||||
Non-escaped `{` in the string start an interpolated expression; any expression can then follow, but a closing `}` is expected after it. When the string literal is evaluated, each interpolated expression will be evaluated, the returned value will be formatted to a string and appear in the string where the `{` expression `}` appeared in the literal.
|
Non-escaped `{` in the string start an interpolated expression; any expression can then follow, but a closing `}` is expected after it. When the string literal is evaluated, each interpolated expression will be evaluated, the returned value will be converted to a string using `format` and appear in the string where the `{` expression `}` appeared in the literal.
|
||||||
|
|
||||||
Strings can contain newlines.
|
Strings can contain newlines.
|
||||||
|
|
||||||
|
|
@ -680,7 +680,7 @@ var!type // returns "$"
|
||||||
var!value // returns 10
|
var!value // returns 10
|
||||||
```
|
```
|
||||||
|
|
||||||
When trying to convert the custom type to a string, for example in a string interpolation, the `format(custom type)` function call will be tried. If the function can be called, its return value will be used as the string representation of the value.
|
When trying to convert the custom type to a string, for example in a string interpolation, the `format(custom type)` function will be called. How custom types appear in strings can therefore be changed by overloading the `format` function.
|
||||||
|
|
||||||
```
|
```
|
||||||
:var = type(10, "$")
|
:var = type(10, "$")
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
--# run #--
|
--# run #--
|
||||||
--- text ---
|
--- text ---
|
||||||
| {}"" {}"\"Name: Darmanin\nAge: 38\"" {}"" |
|
| {}"" {}"Name: Darmanin\nAge: 38" {}"" |
|
||||||
--- return ---
|
--- return ---
|
||||||
()
|
()
|
||||||
--# saved #--
|
--# saved #--
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue