aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-11-29 19:57:50 -0500
committerBruce Hill <bruce@bruce-hill.com>2024-11-29 19:57:50 -0500
commit69613e6c03809bcb82ffdaee7820df5a0ead7a6f (patch)
tree7f23683a2c92a54fea8601cee4ae01fe5f39c120
parente2fa11b7fe35c6d7033e15725d08a09bd0f3c73a (diff)
Tweak serialization syntax
-rw-r--r--docs/serialization.md6
-rw-r--r--parse.c21
-rw-r--r--test/serialization.tm32
3 files changed, 30 insertions, 29 deletions
diff --git a/docs/serialization.md b/docs/serialization.md
index 9ffb6050..ac3c0bfe 100644
--- a/docs/serialization.md
+++ b/docs/serialization.md
@@ -25,14 +25,14 @@ because it's a small number.
## Deserializing
-To deserialize data, you must provide its type explicitly. The current syntax
-is a placeholder, but it looks like this:
+To deserialize data, you must provide its type explicitly using the syntax
+`deserialize(bytes -> Type)`:
```tomo
i := 123
bytes := i:serialized()
-roundtripped := DESERIALIZE(bytes):Int
+roundtripped := deserialize(bytes -> Int)
>> roundtripped
= 123 :Int
```
diff --git a/parse.c b/parse.c
index 152a7706..5e062359 100644
--- a/parse.c
+++ b/parse.c
@@ -53,9 +53,8 @@ int op_tightness[] = {
static const char *keywords[] = {
"yes", "xor", "while", "when", "use", "unless", "struct", "stop", "skip", "return",
"or", "not", "no", "mod1", "mod", "pass", "lang", "inline", "in", "if",
- "func", "for", "extern", "enum", "else", "do", "defer", "and", "NONE", "_min_", "_max_",
- "DESERIALIZE",
- NULL,
+ "func", "for", "extern", "enum", "else", "do", "deserialize", "defer", "and", "NONE",
+ "_min_", "_max_", NULL,
};
enum {NORMAL_FUNCTION=0, EXTERN_FUNCTION=1};
@@ -1551,17 +1550,19 @@ PARSER(parse_none) {
PARSER(parse_deserialize) {
const char *start = pos;
- if (!match_word(&pos, "DESERIALIZE"))
+ if (!match_word(&pos, "deserialize"))
return NULL;
spaces(&pos);
- ast_t *value = expect(ctx, start, &pos, parse_parens, "I expected an expression here");
-
- spaces(&pos);
- if (!match(&pos, ":"))
- parser_err(ctx, pos, pos, "I expected a ':' and a type here");
-
+ expect_str(ctx, start, &pos, "(", "I expected arguments for this `deserialize` call");
+ whitespace(&pos);
+ ast_t *value = expect(ctx, start, &pos, parse_extended_expr, "I expected an expression here");
+ whitespace(&pos);
+ expect_str(ctx, start, &pos, "->", "I expected a `-> Type` for this `deserialize` call so I know what it deserializes to");
+ whitespace(&pos);
type_ast_t *type = expect(ctx, start, &pos, parse_type, "I couldn't parse the type for this deserialization");
+ whitespace(&pos);
+ expect_closing(ctx, &pos, ")", "I expected a closing ')' for this `deserialize` call");
return NewAST(ctx->file, start, pos, Deserialize, .value=value, .type=type);
}
diff --git a/test/serialization.tm b/test/serialization.tm
index 33dd2a71..da79f1b7 100644
--- a/test/serialization.tm
+++ b/test/serialization.tm
@@ -7,50 +7,50 @@ func main():
do:
>> obj := now()
>> bytes := obj:serialized()
- >> DESERIALIZE(bytes):Moment == obj
+ >> deserialize(bytes -> Moment) == obj
= yes
do:
>> obj := Int64(123)
>> bytes := obj:serialized()
- >> DESERIALIZE(bytes):Int64 == obj
+ >> deserialize(bytes -> Int64) == obj
= yes
do:
>> obj := 5
>> bytes := obj:serialized()
- >> DESERIALIZE(bytes):Int == obj
+ >> deserialize(bytes -> Int) == obj
= yes
do:
>> obj := 9999999999999999999999999999999999999999999999999999
>> bytes := obj:serialized()
- >> DESERIALIZE(bytes):Int == obj
+ >> deserialize(bytes -> Int) == obj
= yes
do:
>> obj := "Héllo"
>> bytes := obj:serialized()
- >> DESERIALIZE(bytes):Text
- >> DESERIALIZE(bytes):Text == obj
+ >> deserialize(bytes -> Text)
+ >> deserialize(bytes -> Text) == obj
= yes
do:
>> obj := [Int64(10), Int64(20), Int64(30)]:reversed()
>> bytes := obj:serialized()
- >> DESERIALIZE(bytes):[Int64] == obj
+ >> deserialize(bytes -> [Int64]) == obj
= yes
do:
>> obj := yes
>> bytes := obj:serialized()
- >> DESERIALIZE(bytes):Bool == obj
+ >> deserialize(bytes -> Bool) == obj
= yes
do:
>> obj := @[10, 20]
>> bytes := obj:serialized()
- >> roundtrip := DESERIALIZE(bytes):@[Int]
+ >> roundtrip := deserialize(bytes -> @[Int])
>> roundtrip == obj
= no
>> roundtrip[] == obj[]
@@ -59,43 +59,43 @@ func main():
do:
>> obj := {"A":10, "B":20; fallback={"C":30}}
>> bytes := obj:serialized()
- >> DESERIALIZE(bytes):{Text:Int} == obj
+ >> deserialize(bytes -> {Text:Int}) == obj
= yes
do:
>> obj := @Foo("root")
>> obj.next = @Foo("abcdef", next=obj)
>> bytes := obj:serialized()
- >> DESERIALIZE(bytes):@Foo
+ >> deserialize(bytes -> @Foo)
= @Foo(name="root", next=@Foo(name="abcdef", next=@~1))
do:
>> obj := MyEnum.Two(123, "OKAY")
>> bytes := obj:serialized()
- >> DESERIALIZE(bytes):MyEnum == obj
+ >> deserialize(bytes -> MyEnum) == obj
= yes
do:
>> obj := "Hello"?
>> bytes := obj:serialized()
- >> DESERIALIZE(bytes):Text? == obj
+ >> deserialize(bytes -> Text?) == obj
= yes
do:
>> obj := {10, 20, 30}
>> bytes := obj:serialized()
- >> DESERIALIZE(bytes):{Int} == obj
+ >> deserialize(bytes -> {Int}) == obj
= yes
do:
>> obj := NONE:Num
>> bytes := obj:serialized()
- >> DESERIALIZE(bytes):Num? == obj
+ >> deserialize(bytes -> Num?) == obj
= yes
do:
cases := [0, -1, 1, 10, 100000, 999999999999999999999999999]
for i in cases:
>> bytes := i:serialized()
- >> DESERIALIZE(bytes):Int == i
+ >> deserialize(bytes -> Int) == i
= yes