Added support for V langauge (#2687)
This commit is contained in:
parent
6e34771fd7
commit
729627012e
File diff suppressed because one or more lines are too long
|
@ -1199,6 +1199,11 @@
|
|||
"alias": ["uscript", "uc"],
|
||||
"owner": "RunDevelopment"
|
||||
},
|
||||
"v": {
|
||||
"title": "V",
|
||||
"require": "clike",
|
||||
"owner": "taggon"
|
||||
},
|
||||
"vala": {
|
||||
"title": "Vala",
|
||||
"require": "clike",
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
(function(Prism) {
|
||||
var interpolationExpr = {
|
||||
pattern: /[\s\S]+/,
|
||||
inside: null
|
||||
};
|
||||
|
||||
Prism.languages.v = Prism.languages.extend('clike', {
|
||||
'string': [
|
||||
{
|
||||
pattern: /`(?:\\\`|\\?[^\`]{1,2})`/, // using {1,2} instead of `u` flag for compatibility
|
||||
alias: 'rune'
|
||||
},
|
||||
{
|
||||
pattern: /r?(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
|
||||
alias: 'quoted-string',
|
||||
greedy: true,
|
||||
inside: {
|
||||
'interpolation': {
|
||||
pattern: /((?:^|[^\\])(?:\\{2})*)\$(?:\{[^{}]*\}|\w+(?:\.\w+(?:\([^\(\)]*\))?|\[[^\[\]]+\])*)/,
|
||||
lookbehind: true,
|
||||
inside: {
|
||||
'interpolation-variable': {
|
||||
pattern: /^\$\w[\s\S]*$/,
|
||||
alias: 'variable'
|
||||
},
|
||||
'interpolation-punctuation': {
|
||||
pattern: /^\${|}$/,
|
||||
alias: 'punctuation'
|
||||
},
|
||||
'interpolation-expression': interpolationExpr
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
'class-name': {
|
||||
pattern: /(\b(?:enum|interface|struct|type)\s+)(?:C\.)?[\w]+/,
|
||||
lookbehind: true
|
||||
},
|
||||
'keyword': /(?:\b(?:as|asm|assert|atomic|break|chan|const|continue|defer|else|embed|enum|fn|for|__global|go(?:to)?|if|import|in|interface|is|lock|match|module|mut|none|or|pub|return|rlock|select|shared|sizeof|static|struct|type(?:of)?|union|unsafe)|\$(?:if|else|for)|#(?:include|flag))\b/,
|
||||
'number': /\b(?:0x[a-f\d]+(?:_[a-f\d]+)*|0b[01]+(?:_[01]+)*|0o[0-7]+(?:_[0-7]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?)\b/i,
|
||||
'operator': /~|\?|[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\.?/,
|
||||
'builtin': /\b(?:any(?:_int|_float)?|bool|byte(?:ptr)?|charptr|f(?:32|64)|i(?:8|16|nt|64|128)|rune|size_t|string|u(?:16|32|64|128)|voidptr)\b/
|
||||
});
|
||||
|
||||
interpolationExpr.inside = Prism.languages.v;
|
||||
|
||||
Prism.languages.insertBefore('v', 'operator', {
|
||||
'attribute': {
|
||||
pattern: /^\s*\[(?:deprecated|unsafe_fn|typedef|live|inline|flag|ref_only|windows_stdcall|direct_array_access)\]/m,
|
||||
alias: 'annotation',
|
||||
inside: {
|
||||
'punctuation': /[\[\]]/,
|
||||
'keyword': /\w+/
|
||||
}
|
||||
},
|
||||
'generic': {
|
||||
pattern: /\<\w+\>(?=\s*[\)\{])/,
|
||||
inside: {
|
||||
'punctuation': /[<>]/,
|
||||
'class-name': /\w+/
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Prism.languages.insertBefore('v', 'function', {
|
||||
'generic-function': {
|
||||
// e.g. foo<T>( ...
|
||||
pattern: /\w+\s*<\w+>(?=\()/,
|
||||
inside: {
|
||||
'function': /^\w+/,
|
||||
'generic': {
|
||||
pattern: /<\w+>/,
|
||||
inside: Prism.languages.v.generic.inside
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
})(Prism);
|
|
@ -0,0 +1 @@
|
|||
!function(e){var n={pattern:/[\s\S]+/,inside:null};e.languages.v=e.languages.extend("clike",{string:[{pattern:/`(?:\\\`|\\?[^\`]{1,2})`/,alias:"rune"},{pattern:/r?(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,alias:"quoted-string",greedy:!0,inside:{interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$(?:\{[^{}]*\}|\w+(?:\.\w+(?:\([^\(\)]*\))?|\[[^\[\]]+\])*)/,lookbehind:!0,inside:{"interpolation-variable":{pattern:/^\$\w[\s\S]*$/,alias:"variable"},"interpolation-punctuation":{pattern:/^\${|}$/,alias:"punctuation"},"interpolation-expression":n}}}}],"class-name":{pattern:/(\b(?:enum|interface|struct|type)\s+)(?:C\.)?[\w]+/,lookbehind:!0},keyword:/(?:\b(?:as|asm|assert|atomic|break|chan|const|continue|defer|else|embed|enum|fn|for|__global|go(?:to)?|if|import|in|interface|is|lock|match|module|mut|none|or|pub|return|rlock|select|shared|sizeof|static|struct|type(?:of)?|union|unsafe)|\$(?:if|else|for)|#(?:include|flag))\b/,number:/\b(?:0x[a-f\d]+(?:_[a-f\d]+)*|0b[01]+(?:_[01]+)*|0o[0-7]+(?:_[0-7]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?)\b/i,operator:/~|\?|[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\.?/,builtin:/\b(?:any(?:_int|_float)?|bool|byte(?:ptr)?|charptr|f(?:32|64)|i(?:8|16|nt|64|128)|rune|size_t|string|u(?:16|32|64|128)|voidptr)\b/}),n.inside=e.languages.v,e.languages.insertBefore("v","operator",{attribute:{pattern:/^\s*\[(?:deprecated|unsafe_fn|typedef|live|inline|flag|ref_only|windows_stdcall|direct_array_access)\]/m,alias:"annotation",inside:{punctuation:/[\[\]]/,keyword:/\w+/}},generic:{pattern:/\<\w+\>(?=\s*[\)\{])/,inside:{punctuation:/[<>]/,"class-name":/\w+/}}}),e.languages.insertBefore("v","function",{"generic-function":{pattern:/\w+\s*<\w+>(?=\()/,inside:{function:/^\w+/,generic:{pattern:/<\w+>/,inside:e.languages.v.generic.inside}}}})}(Prism);
|
|
@ -0,0 +1,91 @@
|
|||
<h2>Comments</h2>
|
||||
<pre><code>// This is a comment
|
||||
/* This is a comment
|
||||
on multiple lines */</code></pre>
|
||||
|
||||
<h2>Numbers</h2>
|
||||
<pre><code>123
|
||||
0x7B
|
||||
0b01111011
|
||||
0o173
|
||||
170141183460469231731687303715884105727
|
||||
1_000_000
|
||||
0b0_11
|
||||
3_122.55
|
||||
0xF_F
|
||||
0o17_3
|
||||
72.40
|
||||
072.40
|
||||
2.71828
|
||||
</code></pre>
|
||||
|
||||
<h2>Runes and strings</h2>
|
||||
<pre><code>'\t'
|
||||
'\000'
|
||||
'\x07'
|
||||
'\u12e4'
|
||||
'\U00101234'
|
||||
`abc`
|
||||
`multi-line
|
||||
string`
|
||||
"Hello, world!"
|
||||
"multi-line
|
||||
string"</code></pre>
|
||||
|
||||
<h2>String interpolation</h2>
|
||||
<pre><code>'Hello, $name!'
|
||||
"age = $user.age"
|
||||
'can register = ${user.age > 13}'
|
||||
'x = ${x:4.2f}'
|
||||
'[${x:10}]'
|
||||
'[${int(x):-10}]'
|
||||
</code></pre>
|
||||
|
||||
<h2>Struct</h2>
|
||||
<pre><code>struct Foo {
|
||||
a int // private immutable (default)
|
||||
mut:
|
||||
b int // private mutable
|
||||
c int // (you can list multiple fields with the same access modifier)
|
||||
pub:
|
||||
d int // public immutable (readonly)
|
||||
pub mut:
|
||||
e int // public, but mutable only in parent module
|
||||
__global:
|
||||
f int // public and mutable both inside and outside parent module
|
||||
} // (not recommended to use, that's why the 'global' keyword
|
||||
// starts with __)
|
||||
</code></pre>
|
||||
|
||||
<h2>Functions</h2>
|
||||
<pre><code>func(a, b int, z float64) bool { return a*b < int(z) }</code></pre>
|
||||
|
||||
<h2>Full example</h2>
|
||||
<pre><code>
|
||||
module mymodule
|
||||
|
||||
import external_module
|
||||
|
||||
fn sqr(n int) int {
|
||||
return n * n
|
||||
}
|
||||
|
||||
fn run(value int, op fn (int) int) int {
|
||||
return op(value)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println(run(5, sqr)) // "25"
|
||||
// Anonymous functions can be declared inside other functions:
|
||||
double_fn := fn (n int) int {
|
||||
return n + n
|
||||
}
|
||||
println(run(5, double_fn)) // "10"
|
||||
// Functions can be passed around without assigning them to variables:
|
||||
res := run(5, fn (n int) int {
|
||||
return n + n
|
||||
})
|
||||
|
||||
external_module.say_hi()
|
||||
}
|
||||
</code></pre>
|
|
@ -141,6 +141,7 @@
|
|||
"textile": "markup",
|
||||
"twig": "markup",
|
||||
"typescript": "javascript",
|
||||
"v": "clike",
|
||||
"vala": "clike",
|
||||
"vbnet": "basic",
|
||||
"velocity": "markup",
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,13 @@
|
|||
true
|
||||
false
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
[
|
||||
["boolean", "true"],
|
||||
["boolean", "false"]
|
||||
]
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
Check for boolean
|
|
@ -0,0 +1,41 @@
|
|||
struct Abc { }
|
||||
type Alphabet = Abc | Xyz
|
||||
enum Token { }
|
||||
interface Speaker { }
|
||||
struct Repo<T> { }
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
[
|
||||
["keyword", "struct"],
|
||||
["class-name", "Abc"],
|
||||
["punctuation", "{"],
|
||||
["punctuation", "}"],
|
||||
|
||||
["keyword", "type"],
|
||||
["class-name", "Alphabet"],
|
||||
["operator", "="],
|
||||
" Abc ",
|
||||
["operator", "|"],
|
||||
" Xyz\r\n",
|
||||
|
||||
["keyword", "enum"],
|
||||
["class-name", "Token"],
|
||||
["punctuation", "{"],
|
||||
["punctuation", "}"],
|
||||
|
||||
["keyword", "interface"],
|
||||
["class-name", "Speaker"],
|
||||
["punctuation", "{"],
|
||||
["punctuation", "}"],
|
||||
|
||||
["keyword", "struct"],
|
||||
["class-name", "Repo"],
|
||||
["generic", [
|
||||
["punctuation", "<"],
|
||||
["class-name", "T"],
|
||||
["punctuation", ">"]
|
||||
]],
|
||||
["punctuation", "{"],
|
||||
["punctuation", "}"]
|
||||
]
|
|
@ -0,0 +1,120 @@
|
|||
fn init() { }
|
||||
fn add(x int, y int) int { }
|
||||
fn sum(a ...int) int { }
|
||||
fn (mut t MyTime) century() int { }
|
||||
fn (d Dog) speak() string { }
|
||||
fn (r Repo) find_user_by_id(id int) ?User { }
|
||||
fn new_repo<T>(db DB) Repo<T> { }
|
||||
fn (r Repo<T>) find_by_id(id int) ?T { }
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
[
|
||||
["keyword", "fn"],
|
||||
["function", "init"],
|
||||
["punctuation", "("],
|
||||
["punctuation", ")"],
|
||||
["punctuation", "{"],
|
||||
["punctuation", "}"],
|
||||
|
||||
["keyword", "fn"],
|
||||
["function", "add"],
|
||||
["punctuation", "("],
|
||||
"x ",
|
||||
["builtin", "int"],
|
||||
["punctuation", ","],
|
||||
" y ",
|
||||
["builtin", "int"],
|
||||
["punctuation", ")"],
|
||||
["builtin", "int"],
|
||||
["punctuation", "{"],
|
||||
["punctuation", "}"],
|
||||
|
||||
["keyword", "fn"],
|
||||
["function", "sum"],
|
||||
["punctuation", "("],
|
||||
"a ",
|
||||
["operator", "..."],
|
||||
["builtin", "int"],
|
||||
["punctuation", ")"],
|
||||
["builtin", "int"],
|
||||
["punctuation", "{"],
|
||||
["punctuation", "}"],
|
||||
|
||||
["keyword", "fn"],
|
||||
["punctuation", "("],
|
||||
["keyword", "mut"],
|
||||
" t MyTime",
|
||||
["punctuation", ")"],
|
||||
["function", "century"],
|
||||
["punctuation", "("],
|
||||
["punctuation", ")"],
|
||||
["builtin", "int"],
|
||||
["punctuation", "{"],
|
||||
["punctuation", "}"],
|
||||
|
||||
["keyword", "fn"],
|
||||
["punctuation", "("],
|
||||
"d Dog",
|
||||
["punctuation", ")"],
|
||||
["function", "speak"],
|
||||
["punctuation", "("],
|
||||
["punctuation", ")"],
|
||||
["builtin", "string"],
|
||||
["punctuation", "{"],
|
||||
["punctuation", "}"],
|
||||
|
||||
["keyword", "fn"],
|
||||
["punctuation", "("],
|
||||
"r Repo",
|
||||
["punctuation", ")"],
|
||||
["function", "find_user_by_id"],
|
||||
["punctuation", "("],
|
||||
"id ",
|
||||
["builtin", "int"],
|
||||
["punctuation", ")"],
|
||||
["operator", "?"],
|
||||
"User ",
|
||||
["punctuation", "{"],
|
||||
["punctuation", "}"],
|
||||
|
||||
["keyword", "fn"],
|
||||
["generic-function", [
|
||||
["function", "new_repo"],
|
||||
["generic", [
|
||||
["punctuation", "<"],
|
||||
["class-name", "T"],
|
||||
["punctuation", ">"]
|
||||
]]
|
||||
]],
|
||||
["punctuation", "("],
|
||||
"db DB",
|
||||
["punctuation", ")"],
|
||||
" Repo",
|
||||
["generic", [
|
||||
["punctuation", "<"],
|
||||
["class-name", "T"],
|
||||
["punctuation", ">"]
|
||||
]],
|
||||
["punctuation", "{"],
|
||||
["punctuation", "}"],
|
||||
|
||||
["keyword", "fn"],
|
||||
["punctuation", "("],
|
||||
"r Repo",
|
||||
["generic", [
|
||||
["punctuation", "<"],
|
||||
["class-name", "T"],
|
||||
["punctuation", ">"]
|
||||
]],
|
||||
["punctuation", ")"],
|
||||
["function", "find_by_id"],
|
||||
["punctuation", "("],
|
||||
"id ",
|
||||
["builtin", "int"],
|
||||
["punctuation", ")"],
|
||||
["operator", "?"],
|
||||
"T ",
|
||||
["punctuation", "{"],
|
||||
["punctuation", "}"]
|
||||
]
|
|
@ -0,0 +1,93 @@
|
|||
as;
|
||||
asm;
|
||||
assert;
|
||||
atomic;
|
||||
break;
|
||||
const;
|
||||
continue;
|
||||
defer;
|
||||
else;
|
||||
embed;
|
||||
enum;;
|
||||
fn;
|
||||
for;
|
||||
__global;
|
||||
go;
|
||||
goto;
|
||||
if;
|
||||
import;
|
||||
in;
|
||||
interface;
|
||||
is;
|
||||
lock;
|
||||
match;
|
||||
module;
|
||||
mut;
|
||||
none;
|
||||
or;
|
||||
pub;
|
||||
return;
|
||||
rlock;
|
||||
select;
|
||||
shared;
|
||||
sizeof;
|
||||
static;
|
||||
struct;
|
||||
type;;
|
||||
typeof;
|
||||
union;
|
||||
unsafe;
|
||||
$if;
|
||||
$else;
|
||||
$for;
|
||||
#include;
|
||||
#flag;
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
[
|
||||
["keyword", "as"], ["punctuation", ";"],
|
||||
["keyword", "asm"], ["punctuation", ";"],
|
||||
["keyword", "assert"], ["punctuation", ";"],
|
||||
["keyword", "atomic"], ["punctuation", ";"],
|
||||
["keyword", "break"], ["punctuation", ";"],
|
||||
["keyword", "const"], ["punctuation", ";"],
|
||||
["keyword", "continue"], ["punctuation", ";"],
|
||||
["keyword", "defer"], ["punctuation", ";"],
|
||||
["keyword", "else"], ["punctuation", ";"],
|
||||
["keyword", "embed"], ["punctuation", ";"],
|
||||
["keyword", "enum"], ["punctuation", ";"], ["punctuation", ";"],
|
||||
["keyword", "fn"], ["punctuation", ";"],
|
||||
["keyword", "for"], ["punctuation", ";"],
|
||||
["keyword", "__global"], ["punctuation", ";"],
|
||||
["keyword", "go"], ["punctuation", ";"],
|
||||
["keyword", "goto"], ["punctuation", ";"],
|
||||
["keyword", "if"], ["punctuation", ";"],
|
||||
["keyword", "import"], ["punctuation", ";"],
|
||||
["keyword", "in"], ["punctuation", ";"],
|
||||
["keyword", "interface"], ["punctuation", ";"],
|
||||
["keyword", "is"], ["punctuation", ";"],
|
||||
["keyword", "lock"], ["punctuation", ";"],
|
||||
["keyword", "match"], ["punctuation", ";"],
|
||||
["keyword", "module"], ["punctuation", ";"],
|
||||
["keyword", "mut"], ["punctuation", ";"],
|
||||
["keyword", "none"], ["punctuation", ";"],
|
||||
["keyword", "or"], ["punctuation", ";"],
|
||||
["keyword", "pub"], ["punctuation", ";"],
|
||||
["keyword", "return"], ["punctuation", ";"],
|
||||
["keyword", "rlock"], ["punctuation", ";"],
|
||||
["keyword", "select"], ["punctuation", ";"],
|
||||
["keyword", "shared"], ["punctuation", ";"],
|
||||
["keyword", "sizeof"], ["punctuation", ";"],
|
||||
["keyword", "static"], ["punctuation", ";"],
|
||||
["keyword", "struct"], ["punctuation", ";"],
|
||||
["keyword", "type"], ["punctuation", ";"], ["punctuation", ";"],
|
||||
["keyword", "typeof"], ["punctuation", ";"],
|
||||
["keyword", "union"], ["punctuation", ";"],
|
||||
["keyword", "unsafe"], ["punctuation", ";"],
|
||||
["keyword", "$if"], ["punctuation", ";"],
|
||||
["keyword", "$else"], ["punctuation", ";"],
|
||||
["keyword", "$for"], ["punctuation", ";"],
|
||||
["keyword", "#include"], ["punctuation", ";"],
|
||||
["keyword", "#flag"], ["punctuation", ";"]
|
||||
]
|
|
@ -0,0 +1,25 @@
|
|||
123
|
||||
0x7B
|
||||
0b01111011
|
||||
0o173
|
||||
1_000_000
|
||||
0xF_F
|
||||
072.40
|
||||
2.71828
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
[
|
||||
["number", "123"],
|
||||
["number", "0x7B"],
|
||||
["number", "0b01111011"],
|
||||
["number", "0o173"],
|
||||
["number", "1_000_000"],
|
||||
["number", "0xF_F"],
|
||||
["number", "072.40"],
|
||||
["number", "2.71828"]
|
||||
]
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
Check for numbers
|
|
@ -0,0 +1,67 @@
|
|||
+
|
||||
-
|
||||
*
|
||||
/
|
||||
%
|
||||
~
|
||||
&
|
||||
|
|
||||
^
|
||||
!
|
||||
&&
|
||||
||
|
||||
!=
|
||||
<<
|
||||
>>
|
||||
==
|
||||
<
|
||||
<=
|
||||
>
|
||||
>=
|
||||
+=
|
||||
-=
|
||||
*=
|
||||
/=
|
||||
%=
|
||||
&=
|
||||
|=
|
||||
^=
|
||||
>>=
|
||||
<<=
|
||||
:=
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
[
|
||||
["operator", "+"],
|
||||
["operator", "-"],
|
||||
["operator", "*"],
|
||||
["operator", "/"],
|
||||
["operator", "%"],
|
||||
["operator", "~"],
|
||||
["operator", "&"],
|
||||
["operator", "|"],
|
||||
["operator", "^"],
|
||||
["operator", "!"],
|
||||
["operator", "&&"],
|
||||
["operator", "||"],
|
||||
["operator", "!="],
|
||||
["operator", "<<"],
|
||||
["operator", ">>"],
|
||||
["operator", "=="],
|
||||
["operator", "<"],
|
||||
["operator", "<="],
|
||||
["operator", ">"],
|
||||
["operator", ">="],
|
||||
["operator", "+="],
|
||||
["operator", "-="],
|
||||
["operator", "*="],
|
||||
["operator", "/="],
|
||||
["operator", "%="],
|
||||
["operator", "&="],
|
||||
["operator", "|="],
|
||||
["operator", "^="],
|
||||
["operator", ">>="],
|
||||
["operator", "<<="],
|
||||
["operator", ":="]
|
||||
]
|
|
@ -0,0 +1,47 @@
|
|||
"https://example.com"
|
||||
'single quote'
|
||||
'age = $user.age'
|
||||
'[${int(x):-10}]'
|
||||
r'hello\nworld'
|
||||
`🚀`
|
||||
`\``
|
||||
`Not a Rune`
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
[
|
||||
["string", ["\"https://example.com\""]],
|
||||
["string", ["'single quote'"]],
|
||||
["string", [
|
||||
"'age = ",
|
||||
["interpolation", [
|
||||
["interpolation-variable", "$user.age"]
|
||||
]],
|
||||
"'"
|
||||
]],
|
||||
["string", [
|
||||
"'[",
|
||||
["interpolation", [
|
||||
["interpolation-punctuation", "${"],
|
||||
["interpolation-expression", [
|
||||
["function", "int"],
|
||||
["punctuation", "("],
|
||||
"x",
|
||||
["punctuation", ")"],
|
||||
["punctuation", ":"],
|
||||
["operator", "-"],
|
||||
["number", "10"]
|
||||
]],
|
||||
["interpolation-punctuation", "}"]
|
||||
]],
|
||||
"]'"
|
||||
]],
|
||||
["string", ["r'hello\\nworld'"]],
|
||||
["string", "`🚀`"],
|
||||
["string", "`\\``"],
|
||||
"\r\n`Not a Rune`"
|
||||
]
|
||||
|
||||
----------------------------------------------------
|
||||
|
||||
Check for strings and string interpolation
|
Loading…
Reference in New Issue