From 69613e6c03809bcb82ffdaee7820df5a0ead7a6f Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Fri, 29 Nov 2024 19:57:50 -0500 Subject: Tweak serialization syntax --- docs/serialization.md | 6 +++--- parse.c | 21 +++++++++++---------- test/serialization.tm | 32 ++++++++++++++++---------------- 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 -- cgit v1.2.3