Change table syntax to {key=value}
and {:K,V}
/{K,V}
This commit is contained in:
parent
b025cf269d
commit
645d66e0de
@ -325,7 +325,7 @@ Counts the occurrences of each element in the array.
|
||||
|
||||
**Signature:**
|
||||
```tomo
|
||||
func counts(arr: [T] -> {T: Int})
|
||||
func counts(arr: [T] -> {T,Int})
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
@ -338,7 +338,7 @@ A table mapping each element to its count.
|
||||
**Example:**
|
||||
```tomo
|
||||
>> [10, 20, 30, 30, 30]:counts()
|
||||
= {10: 1, 20: 1, 30: 3}
|
||||
= {10=1, 20=1, 30=3}
|
||||
```
|
||||
|
||||
---
|
||||
|
@ -82,7 +82,7 @@ func _add(x, y:Int -> Int):
|
||||
return x + y
|
||||
|
||||
struct add_args(x,y:Int)
|
||||
add_cache := @{:add_args:Int}
|
||||
add_cache := @{:add_args,Int}
|
||||
|
||||
func add(x, y:Int -> Int):
|
||||
args := add_args(x, y)
|
||||
|
@ -12,11 +12,11 @@ where a different type of string is needed.
|
||||
lang HTML:
|
||||
func escape(t:Text -> HTML):
|
||||
t = t:replace_all({
|
||||
$/&/: "&",
|
||||
$/</: "<",
|
||||
$/>/: ">",
|
||||
$/"/: """,
|
||||
$/'/: "'",
|
||||
$/&/ = "&",
|
||||
$/</ = "<",
|
||||
$/>/ = ">",
|
||||
$/"/ = """,
|
||||
$/'/ = "'",
|
||||
})
|
||||
return HTML.without_escaping(t)
|
||||
|
||||
|
@ -51,7 +51,7 @@ Now, what happens if we want to _use_ the compiled object file?
|
||||
foo := use ./foo.tm
|
||||
|
||||
func say_stuff():
|
||||
say("I got {foo.my_variable} from foo")
|
||||
say("I got $(foo.my_variable) from foo")
|
||||
|
||||
func main():
|
||||
say_stuff()
|
||||
|
@ -17,20 +17,20 @@ table := {"A": 10, "B": 20}
|
||||
Empty tables must specify the key and value types explicitly:
|
||||
|
||||
```tomo
|
||||
empty := {:Text:Int}
|
||||
empty := {:Text,Int}
|
||||
```
|
||||
|
||||
For type annotations, a table that maps keys with type `K` to values of type
|
||||
`V` is written as `{K:V}`.
|
||||
`V` is written as `{K,V}`.
|
||||
|
||||
### Comprehensions
|
||||
|
||||
Similar to arrays, tables can use comprehensions to dynamically construct tables:
|
||||
|
||||
```tomo
|
||||
t := {i: 10*i for i in 10}
|
||||
t := {i: 10*i for i in 10 if i mod 2 == 0}
|
||||
t := {-1:-10, i: 10*i for i in 10}
|
||||
t := {i=10*i for i in 10}
|
||||
t := {i=10*i for i in 10 if i mod 2 == 0}
|
||||
t := {-1=-10, i=10*i for i in 10}
|
||||
```
|
||||
|
||||
## Accessing Values
|
||||
@ -39,7 +39,7 @@ Table values can be accessed with square bracket indexing. The result is an
|
||||
optional value:
|
||||
|
||||
```tomo
|
||||
table := {"A": 1, "B": 2}
|
||||
table := {"A"=1, "B"=2}
|
||||
>> table["A"]
|
||||
= 1 : Int?
|
||||
>> table["missing"]
|
||||
@ -64,8 +64,8 @@ Tables can specify a fallback table that is used when looking up a value if it
|
||||
is not found in the table itself:
|
||||
|
||||
```tomo
|
||||
t := {"A": 10}
|
||||
t2 := {"B": 20; fallback=t}
|
||||
t := {"A"=10}
|
||||
t2 := {"B"=20; fallback=t}
|
||||
>> t2["A"]
|
||||
= 10 : Int?
|
||||
```
|
||||
@ -75,9 +75,9 @@ table value:
|
||||
|
||||
```tomo
|
||||
>> t2.fallback
|
||||
= {"A":10} : {Text:Int}?
|
||||
= {"A"=10} : {Text,Int}?
|
||||
>> t.fallback
|
||||
= none : {Text:Int}?
|
||||
= none : {Text,Int}?
|
||||
```
|
||||
|
||||
## Setting Values
|
||||
@ -86,11 +86,11 @@ You can assign a new key/value mapping or overwrite an existing one using
|
||||
`:set(key, value)` or an `=` assignment statement:
|
||||
|
||||
```tomo
|
||||
t := {"A": 1, "B": 2}
|
||||
t := {"A"=1, "B"=2}
|
||||
t["B"] = 222
|
||||
t["C"] = 333
|
||||
>> t
|
||||
= {"A":1, "B":222, "C":333}
|
||||
= {"A"=1, "B"=222, "C"=333}
|
||||
```
|
||||
|
||||
## Length
|
||||
@ -98,7 +98,7 @@ t["C"] = 333
|
||||
Table length can be accessed by the `.length` field:
|
||||
|
||||
```tomo
|
||||
>> {"A":10, "B":20}.length
|
||||
>> {"A"=10, "B"=20}.length
|
||||
= 2
|
||||
```
|
||||
|
||||
@ -108,7 +108,7 @@ The keys and values of a table can be efficiently accessed as arrays using a
|
||||
constant-time immutable slice of the internal data from the table:
|
||||
|
||||
```tomo
|
||||
t := {"A": 10, "B": 20}
|
||||
t := {"A"=10, "B"=20}
|
||||
>> t.keys
|
||||
= ["A", "B"]
|
||||
>> t.values
|
||||
@ -141,7 +141,7 @@ not already in the table, its value will be assumed to be zero.
|
||||
|
||||
**Signature:**
|
||||
```tomo
|
||||
func bump(t:@{K:V}, key: K, amount: Int = 1 -> Void)
|
||||
func bump(t:@{K,V}, key: K, amount: Int = 1 -> Void)
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
@ -155,11 +155,11 @@ Nothing.
|
||||
|
||||
**Example:**
|
||||
```tomo
|
||||
>> t := {"A":1}
|
||||
>> t := {"A"=1}
|
||||
t:bump("A")
|
||||
t:bump("B", 10)
|
||||
>> t
|
||||
= {"A": 2, "B": 10}
|
||||
= {"A"=2, "B"=10}
|
||||
```
|
||||
|
||||
---
|
||||
@ -171,7 +171,7 @@ Removes all key-value pairs from the table.
|
||||
|
||||
**Signature:**
|
||||
```tomo
|
||||
func clear(t:@{K:V})
|
||||
func clear(t:@{K,V})
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
@ -195,7 +195,7 @@ Retrieves the value associated with a key, or returns null if the key is not pre
|
||||
|
||||
**Signature:**
|
||||
```tomo
|
||||
func get(t:{K:V}, key: K -> V?)
|
||||
func get(t:{K,V}, key: K -> V?)
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
@ -208,7 +208,7 @@ The value associated with the key or null if the key is not found.
|
||||
|
||||
**Example:**
|
||||
```tomo
|
||||
>> t := {"A":1, "B":2}
|
||||
>> t := {"A"=1, "B"=2}
|
||||
>> t:get("A")
|
||||
= 1 : Int?
|
||||
|
||||
@ -231,7 +231,7 @@ Checks if the table contains a specified key.
|
||||
|
||||
**Signature:**
|
||||
```tomo
|
||||
func has(t:{K:V}, key: K -> Bool)
|
||||
func has(t:{K,V}, key: K -> Bool)
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
@ -244,9 +244,9 @@ func has(t:{K:V}, key: K -> Bool)
|
||||
|
||||
**Example:**
|
||||
```tomo
|
||||
>> {"A":1, "B":2}:has("A")
|
||||
>> {"A"=1, "B"=2}:has("A")
|
||||
= yes
|
||||
>> {"A":1, "B":2}:has("xxx")
|
||||
>> {"A"=1, "B"=2}:has("xxx")
|
||||
= no
|
||||
```
|
||||
|
||||
@ -259,7 +259,7 @@ Removes the key-value pair associated with a specified key.
|
||||
|
||||
**Signature:**
|
||||
```tomo
|
||||
func remove(t:{K:V}, key: K -> Void)
|
||||
func remove(t:{K,V}, key: K -> Void)
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
@ -272,10 +272,10 @@ Nothing.
|
||||
|
||||
**Example:**
|
||||
```tomo
|
||||
t := {"A":1, "B":2}
|
||||
t := {"A"=1, "B"=2}
|
||||
t:remove("A")
|
||||
>> t
|
||||
= {"B": 2}
|
||||
= {"B"=2}
|
||||
```
|
||||
|
||||
---
|
||||
@ -287,7 +287,7 @@ Sets or updates the value associated with a specified key.
|
||||
|
||||
**Signature:**
|
||||
```tomo
|
||||
func set(t:{K:V}, key: K, value: V -> Void)
|
||||
func set(t:{K,V}, key: K, value: V -> Void)
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
@ -301,8 +301,8 @@ Nothing.
|
||||
|
||||
**Example:**
|
||||
```tomo
|
||||
t := {"A": 1, "B": 2}
|
||||
t := {"A"=1, "B"=2}
|
||||
t:set("C", 3)
|
||||
>> t
|
||||
= {"A": 1, "B": 2, "C": 3}
|
||||
= {"A"=1, "B"=2, "C"=3}
|
||||
```
|
||||
|
16
docs/text.md
16
docs/text.md
@ -279,7 +279,7 @@ Text.find_all(pattern:Pattern -> [Match])
|
||||
Text.matches(pattern:Pattern -> [Text]?)
|
||||
Text.map(pattern:Pattern, fn:func(m:Match -> Text) -> Text)
|
||||
Text.replace(pattern:Pattern, replacement:Text, placeholder:Pattern=$// -> [Text])
|
||||
Text.replace_all(replacements:{Pattern:Text}, placeholder:Pattern=$// -> [Text])
|
||||
Text.replace_all(replacements:{Pattern,Text}, placeholder:Pattern=$// -> [Text])
|
||||
Text.split(pattern:Pattern -> [Text])
|
||||
Text.trim(pattern=$/{whitespace}/, trim_left=yes, trim_right=yes -> [Text])
|
||||
```
|
||||
@ -1183,7 +1183,7 @@ See [`replace()`](#replace) for more information about replacement behavior.
|
||||
|
||||
**Signature:**
|
||||
```tomo
|
||||
func replace_all(replacements:{Pattern:Text}, backref: Pattern = $/\/ -> Text)
|
||||
func replace_all(replacements:{Pattern,Text}, backref: Pattern = $/\/ -> Text)
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
@ -1206,15 +1206,15 @@ replacement text.
|
||||
**Example:**
|
||||
```tomo
|
||||
>> "A <tag> & an amperand":replace_all({
|
||||
$/&/: "&",
|
||||
$/</: "<",
|
||||
$/>/: ">",
|
||||
$/"/: """,
|
||||
$/'/: "'",
|
||||
$/&/ = "&",
|
||||
$/</ = "<",
|
||||
$/>/ = ">",
|
||||
$/"/ = """,
|
||||
$/'/ = "'",
|
||||
}
|
||||
= "A <tag> & an ampersand"
|
||||
|
||||
>> "Hello":replace_all({$/{lower}/:"[\0]", $/{upper}/:"{\0}"})
|
||||
>> "Hello":replace_all({$/{lower}/="[\0]", $/{upper}/="{\0}"})
|
||||
= "{H}[ello]"
|
||||
```
|
||||
|
||||
|
@ -365,7 +365,7 @@ env_t *new_compilation_unit(CORD libname)
|
||||
{"has", "Text$has", "func(path:Path, pattern:Pattern -> Bool)"},
|
||||
{"matches", "Text$matches", "func(path:Path, pattern:Pattern -> [Text]?)"},
|
||||
{"replace", "Text$replace", "func(path:Path, pattern:Pattern, replacement:Text, backref=$/\\/, recursive=yes -> Path)"},
|
||||
{"replace_all", "Text$replace_all", "func(path:Path, replacements:{Pattern:Text}, backref=$/\\/, recursive=yes -> Path)"},
|
||||
{"replace_all", "Text$replace_all", "func(path:Path, replacements:{Pattern,Text}, backref=$/\\/, recursive=yes -> Path)"},
|
||||
{"starts_with", "Text$starts_with", "func(path:Path, prefix:Text -> Bool)"},
|
||||
)},
|
||||
// RNG must come after Path so we can read bytes from /dev/urandom
|
||||
@ -419,7 +419,7 @@ env_t *new_compilation_unit(CORD libname)
|
||||
{"quoted", "Text$quoted", "func(text:Text, color=no -> Text)"},
|
||||
{"repeat", "Text$repeat", "func(text:Text, count:Int -> Text)"},
|
||||
{"replace", "Text$replace", "func(text:Text, pattern:Pattern, replacement:Text, backref=$/\\/, recursive=yes -> Text)"},
|
||||
{"replace_all", "Text$replace_all", "func(text:Text, replacements:{Pattern:Text}, backref=$/\\/, recursive=yes -> Text)"},
|
||||
{"replace_all", "Text$replace_all", "func(text:Text, replacements:{Pattern,Text}, backref=$/\\/, recursive=yes -> Text)"},
|
||||
{"reversed", "Text$reversed", "func(text:Text -> Text)"},
|
||||
{"slice", "Text$slice", "func(text:Text, from=1, to=-1 -> Text)"},
|
||||
{"split", "Text$split", "func(text:Text, pattern=$Pattern'' -> [Text])"},
|
||||
|
12
parse.c
12
parse.c
@ -571,7 +571,7 @@ type_ast_t *parse_table_type(parse_ctx_t *ctx, const char *pos) {
|
||||
whitespace(&pos);
|
||||
type_ast_t *value_type = NULL;
|
||||
ast_t *default_value = NULL;
|
||||
if (match(&pos, ":")) {
|
||||
if (match(&pos, ",")) {
|
||||
value_type = expect(ctx, start, &pos, parse_type, "I couldn't parse the rest of this table type");
|
||||
} else if (match(&pos, "=")) {
|
||||
default_value = expect(ctx, start, &pos, parse_extended_expr, "I couldn't parse the rest of this table type");
|
||||
@ -591,7 +591,7 @@ type_ast_t *parse_set_type(parse_ctx_t *ctx, const char *pos) {
|
||||
if (!item_type) return NULL;
|
||||
pos = item_type->end;
|
||||
whitespace(&pos);
|
||||
if (match(&pos, ":")) return NULL;
|
||||
if (match(&pos, ",")) return NULL;
|
||||
expect_closing(ctx, &pos, "}", "I wasn't able to parse the rest of this set type");
|
||||
return NewTypeAST(ctx->file, start, pos, SetTypeAST, .item=item_type);
|
||||
}
|
||||
@ -808,7 +808,7 @@ PARSER(parse_table) {
|
||||
whitespace(&pos);
|
||||
key_type = expect(ctx, pos-1, &pos, parse_type, "I couldn't parse a key type for this table");
|
||||
whitespace(&pos);
|
||||
if (match(&pos, ":")) {
|
||||
if (match(&pos, ",")) {
|
||||
value_type = expect(ctx, pos-1, &pos, parse_type, "I couldn't parse the value type for this table");
|
||||
} else if (match(&pos, "=")) {
|
||||
default_value = expect(ctx, pos-1, &pos, parse_extended_expr, "I couldn't parse the default value for this table");
|
||||
@ -824,7 +824,7 @@ PARSER(parse_table) {
|
||||
ast_t *key = optional(ctx, &pos, parse_extended_expr);
|
||||
if (!key) break;
|
||||
whitespace(&pos);
|
||||
if (!match(&pos, ":")) return NULL;
|
||||
if (!match(&pos, "=")) return NULL;
|
||||
ast_t *value = expect(ctx, pos-1, &pos, parse_expr, "I couldn't parse the value for this table entry");
|
||||
ast_t *entry = NewAST(ctx->file, entry_start, pos, TableEntry, .key=key, .value=value);
|
||||
ast_t *suffixed = parse_comprehension_suffix(ctx, entry);
|
||||
@ -883,7 +883,7 @@ PARSER(parse_set) {
|
||||
whitespace(&pos);
|
||||
item_type = expect(ctx, pos-1, &pos, parse_type, "I couldn't parse a key type for this set");
|
||||
whitespace(&pos);
|
||||
if (match(&pos, ":"))
|
||||
if (match(&pos, ","))
|
||||
return NULL;
|
||||
whitespace(&pos);
|
||||
match(&pos, ",");
|
||||
@ -894,7 +894,7 @@ PARSER(parse_set) {
|
||||
ast_t *item = optional(ctx, &pos, parse_extended_expr);
|
||||
if (!item) break;
|
||||
whitespace(&pos);
|
||||
if (match(&pos, ":")) return NULL;
|
||||
if (match(&pos, "=")) return NULL;
|
||||
ast_t *suffixed = parse_comprehension_suffix(ctx, item);
|
||||
while (suffixed) {
|
||||
item = suffixed;
|
||||
|
@ -584,7 +584,7 @@ public Text_t Table$as_text(const void *obj, bool colorize, const TypeInfo_t *ty
|
||||
return Text$concat(
|
||||
Text("{"),
|
||||
generic_as_text(NULL, false, table.key),
|
||||
Text(":"),
|
||||
Text(","),
|
||||
generic_as_text(NULL, false, table.value),
|
||||
Text("}"));
|
||||
else
|
||||
@ -602,7 +602,7 @@ public Text_t Table$as_text(const void *obj, bool colorize, const TypeInfo_t *ty
|
||||
void *entry = GET_ENTRY(*t, i);
|
||||
text = Text$concat(text, generic_as_text(entry, colorize, table.key));
|
||||
if (table.value != &Void$info)
|
||||
text = Text$concat(text, Text(":"), generic_as_text(entry + val_off, colorize, table.value));
|
||||
text = Text$concat(text, Text("="), generic_as_text(entry + val_off, colorize, table.value));
|
||||
}
|
||||
|
||||
if (t->fallback) {
|
||||
|
@ -15,14 +15,14 @@ func labeled_nums(nums:[Int] -> Text):
|
||||
return "EMPTY"
|
||||
return result
|
||||
|
||||
func table_str(t:{Text:Text} -> Text):
|
||||
func table_str(t:{Text,Text} -> Text):
|
||||
str := ""
|
||||
for k,v in t:
|
||||
str ++= "$k:$v,"
|
||||
else: return "EMPTY"
|
||||
return str
|
||||
|
||||
func table_key_str(t:{Text:Text} -> Text):
|
||||
func table_key_str(t:{Text,Text} -> Text):
|
||||
str := ""
|
||||
for k in t:
|
||||
str ++= "$k,"
|
||||
@ -40,10 +40,10 @@ func main():
|
||||
>> labeled_nums([:Int])
|
||||
= "EMPTY"
|
||||
|
||||
>> t := {"key1":"value1", "key2":"value2"}
|
||||
>> t := {"key1"="value1", "key2"="value2"}
|
||||
>> table_str(t)
|
||||
= "key1:value1,key2:value2,"
|
||||
>> table_str({:Text:Text})
|
||||
>> table_str({:Text,Text})
|
||||
= "EMPTY"
|
||||
|
||||
>> table_key_str(t)
|
||||
|
10
test/lang.tm
10
test/lang.tm
@ -2,11 +2,11 @@ lang HTML:
|
||||
HEADER := $HTML"<!DOCTYPE HTML>"
|
||||
func escape(t:Text->HTML):
|
||||
t = t:replace_all({
|
||||
$/&/: "&",
|
||||
$/</: "<",
|
||||
$/>/: ">",
|
||||
$/"/: """,
|
||||
$/'/: "'",
|
||||
$/&/="&",
|
||||
$/</="<",
|
||||
$/>/=">",
|
||||
$/"/=""",
|
||||
$/'/="'",
|
||||
})
|
||||
|
||||
return HTML.without_escaping(t)
|
||||
|
@ -57,9 +57,9 @@ func main():
|
||||
= yes
|
||||
|
||||
do:
|
||||
>> obj := {"A":10, "B":20; fallback={"C":30}}
|
||||
>> obj := {"A"=10, "B"=20; fallback={"C"=30}}
|
||||
>> bytes := obj:serialized()
|
||||
>> deserialize(bytes -> {Text:Int}) == obj
|
||||
>> deserialize(bytes -> {Text,Int}) == obj
|
||||
= yes
|
||||
|
||||
do:
|
||||
|
@ -72,8 +72,8 @@ func main():
|
||||
|
||||
>> my_pass := Password("Swordfish")
|
||||
= Password(...)
|
||||
>> users_by_password := {my_pass:"User1", Password("xxx"):"User2"}
|
||||
= {Password(...):"User1", Password(...):"User2"}
|
||||
>> users_by_password := {my_pass="User1", Password("xxx")="User2"}
|
||||
= {Password(...)="User1", Password(...)="User2"}
|
||||
>> users_by_password[my_pass]!
|
||||
= "User1"
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
func main():
|
||||
>> t := {"one":1, "two":2}
|
||||
= {"one":1, "two":2}
|
||||
>> t := {"one"=1, "two"=2}
|
||||
= {"one"=1, "two"=2}
|
||||
|
||||
>> t["one"]
|
||||
= 1 : Int?
|
||||
@ -15,22 +15,22 @@ func main():
|
||||
|
||||
t_str := ""
|
||||
for k,v in t:
|
||||
t_str ++= "($k:$v)"
|
||||
t_str ++= "($k=$v)"
|
||||
>> t_str
|
||||
= "(one:1)(two:2)"
|
||||
= "(one=1)(two=2)"
|
||||
|
||||
>> t.length
|
||||
= 2
|
||||
>> t.fallback
|
||||
= none : {Text:Int}?
|
||||
= none : {Text,Int}?
|
||||
|
||||
>> t.keys
|
||||
= ["one", "two"]
|
||||
>> t.values
|
||||
= [1, 2]
|
||||
|
||||
>> t2 := {"three":3; fallback=t}
|
||||
= {"three":3; fallback={"one":1, "two":2}}
|
||||
>> t2 := {"three"=3; fallback=t}
|
||||
= {"three"=3; fallback={"one"=1, "two"=2}}
|
||||
|
||||
>> t2["one"]
|
||||
= 1 : Int?
|
||||
@ -42,28 +42,28 @@ func main():
|
||||
>> t2.length
|
||||
= 1
|
||||
>> t2.fallback
|
||||
= {"one":1, "two":2} : {Text:Int}?
|
||||
= {"one"=1, "two"=2} : {Text,Int}?
|
||||
|
||||
t2_str := ""
|
||||
for k,v in t2:
|
||||
t2_str ++= "($k:$v)"
|
||||
t2_str ++= "($k=$v)"
|
||||
>> t2_str
|
||||
= "(three:3)"
|
||||
= "(three=3)"
|
||||
|
||||
>> {i:10*i for i in 5}
|
||||
= {1:10, 2:20, 3:30, 4:40, 5:50}
|
||||
>> {i:10*i for i in 5 if i mod 2 != 0}
|
||||
= {1:10, 3:30, 5:50}
|
||||
>> {x:10*x for x in y if x > 1 for y in [3, 4, 5] if y < 5}
|
||||
= {2:20, 3:30, 4:40}
|
||||
>> {i=10*i for i in 5}
|
||||
= {1=10, 2=20, 3=30, 4=40, 5=50}
|
||||
>> {i=10*i for i in 5 if i mod 2 != 0}
|
||||
= {1=10, 3=30, 5=50}
|
||||
>> {x=10*x for x in y if x > 1 for y in [3, 4, 5] if y < 5}
|
||||
= {2=20, 3=30, 4=40}
|
||||
|
||||
>> t3 := @{1:10, 2:20, 3:30}
|
||||
>> t3 := @{1=10, 2=20, 3=30}
|
||||
>> t3:remove(3)
|
||||
>> t3
|
||||
= @{1:10, 2:20}
|
||||
= @{1=10, 2=20}
|
||||
|
||||
do:
|
||||
>> plain := {1:10, 2:20, 3:30}
|
||||
>> plain := {1=10, 2=20, 3=30}
|
||||
>> plain[2]!
|
||||
= 20
|
||||
>> plain[2]!
|
||||
@ -75,29 +75,29 @@ func main():
|
||||
>> plain:has(456)
|
||||
= no
|
||||
|
||||
>> fallback := {4:40; fallback=plain}
|
||||
>> fallback := {4=40; fallback=plain}
|
||||
>> fallback:has(1)
|
||||
= yes
|
||||
>> fallback[1] or -999
|
||||
= 10
|
||||
|
||||
do:
|
||||
>> t4 := &{"one": 1}
|
||||
>> t4 := &{"one"= 1}
|
||||
>> t4["one"] = 999
|
||||
>> t4["two"] = 222
|
||||
>> t4
|
||||
= &{"one":999, "two":222}
|
||||
= &{"one"=999, "two"=222}
|
||||
|
||||
do:
|
||||
>> {1:1, 2:2} == {2:2, 1:1}
|
||||
>> {1=1, 2=2} == {2=2, 1=1}
|
||||
= yes
|
||||
>> {1:1, 2:2} == {1:1, 2:999}
|
||||
>> {1=1, 2=2} == {1=1, 2=999}
|
||||
= no
|
||||
|
||||
>> {1:1, 2:2} <> {2:2, 1:1}
|
||||
>> {1=1, 2=2} <> {2=2, 1=1}
|
||||
= 0
|
||||
>> [{:Int:Int}, {0:0}, {99:99}, {1:1, 2:2, 3:3}, {1:1, 99:99, 3:3}, {1:1, 2:-99, 3:3}, {1:1, 99:-99, 3:4}]:sorted()
|
||||
= [{}, {0:0}, {1:1, 2:-99, 3:3}, {1:1, 2:2, 3:3}, {1:1, 99:99, 3:3}, {1:1, 99:-99, 3:4}, {99:99}]
|
||||
>> [{:Int,Int}, {0=0}, {99=99}, {1=1, 2=2, 3=3}, {1=1, 99=99, 3=3}, {1=1, 2=-99, 3=3}, {1=1, 99=-99, 3=4}]:sorted()
|
||||
= [{}, {0=0}, {1=1, 2=-99, 3=3}, {1=1, 2=2, 3=3}, {1=1, 99=99, 3=3}, {1=1, 99=-99, 3=4}, {99=99}]
|
||||
|
||||
>> [{:Int}, {1}, {2}, {99}, {0, 3}, {1, 2}, {99}]:sorted()
|
||||
= [{}, {0, 3}, {1}, {1, 2}, {2}, {99}, {99}]
|
||||
|
@ -241,7 +241,7 @@ func main():
|
||||
>> " foo(xyz) foo(yyy) foo(z()) ":replace($/foo(?)/, "baz(\1)")
|
||||
= " baz(xyz) baz(yyy) baz(z()) "
|
||||
|
||||
>> "<tag>":replace_all({$/</:"<", $/>/:">"})
|
||||
>> "<tag>":replace_all({$/</="<", $/>/=">"})
|
||||
= "<tag>"
|
||||
|
||||
>> " BAD(x, fn(y), BAD(z), w) ":replace($/BAD(?)/, "good(\1)", recursive=yes)
|
||||
|
Loading…
Reference in New Issue
Block a user