diff --git a/doc/md/examples/grammar.txt b/doc/md/examples/grammar.txt index 667c62e326c..4fef313dd49 100644 --- a/doc/md/examples/grammar.txt +++ b/doc/md/examples/grammar.txt @@ -270,10 +270,14 @@ 'flexible' 'stable' + TRANSIENT + PERSISTENT ::= 'flexible' 'stable' + TRANSIENT + PERSISTENT ::= '_' diff --git a/src/mo_frontend/error_reporting.ml b/src/mo_frontend/error_reporting.ml index 6b2122d1dc1..6c3e5442ff2 100644 --- a/src/mo_frontend/error_reporting.ml +++ b/src/mo_frontend/error_reporting.ml @@ -18,6 +18,7 @@ let terminal2token (type a) (symbol : a terminal) : token = | T_UNDERSCORE -> UNDERSCORE | T_COMPOSITE -> COMPOSITE | T_TYPE -> TYPE + | T_TRANSIENT -> TRANSIENT | T_TRY -> TRY | T_THROW -> THROW | T_FINALLY -> FINALLY @@ -45,6 +46,7 @@ let terminal2token (type a) (symbol : a terminal) : token = | T_BANG -> BANG | T_QUERY -> QUERY | T_PUBLIC -> PUBLIC + | T_PERSISTENT -> PERSISTENT | T_PRIVATE -> PRIVATE | T_PRIM -> PRIM | T_POWOP -> POWOP diff --git a/src/mo_frontend/parser.mly b/src/mo_frontend/parser.mly index 73665d323ed..5fd24feecaf 100644 --- a/src/mo_frontend/parser.mly +++ b/src/mo_frontend/parser.mly @@ -242,6 +242,7 @@ and objblock s id ty dec_fields = %token WRAPADDASSIGN WRAPSUBASSIGN WRAPMULASSIGN WRAPPOWASSIGN %token NULL %token FLEXIBLE STABLE +%token TRANSIENT PERSISTENT %token DOT_NUM %token NAT %token FLOAT @@ -805,10 +806,16 @@ stab : | (* empty *) { None } | FLEXIBLE { Some (Flexible @@ at $sloc) } | STABLE { Some (Stable @@ at $sloc) } + | TRANSIENT { Some (Flexible @@ at $sloc) } + | PERSISTENT { Some (Stable @@ at $sloc) } %inline stab_mod : + (* we could also forbid flexible/transient, + defining away flexible/transient actor class? {} ... *) | FLEXIBLE { Some (Flexible @@ at $sloc) } | STABLE { Some (Stable @@ at $sloc) } + | TRANSIENT { Some (Flexible @@ at $sloc) } + | PERSISTENT { Some (Stable @@ at $sloc) } (* Patterns *) diff --git a/src/mo_frontend/printers.ml b/src/mo_frontend/printers.ml index b525da1e1b9..f5885c34438 100644 --- a/src/mo_frontend/printers.ml +++ b/src/mo_frontend/printers.ml @@ -24,6 +24,7 @@ let string_of_symbol = function | X (T T_SHRASSIGN) -> binop ">>=" | X (T T_UNDERSCORE) -> "_" | X (T T_TYPE) -> "type" + | X (T T_TRANSIENT) -> "transient" | X (T T_TRY) -> "try" | X (T T_THROW) -> "throw" | X (T T_FINALLY) -> "finally" @@ -50,6 +51,7 @@ let string_of_symbol = function | X (T T_QUEST) -> "?" | X (T T_BANG) -> "!" | X (T T_QUERY) -> "query" + | X (T T_PERSISTENT) -> "persistent" | X (T T_PUBLIC) -> "public" | X (T T_PRIVATE) -> "private" | X (T T_PRIM) -> "prim" diff --git a/src/mo_frontend/source_lexer.mll b/src/mo_frontend/source_lexer.mll index 2e527822c79..6a00084c802 100644 --- a/src/mo_frontend/source_lexer.mll +++ b/src/mo_frontend/source_lexer.mll @@ -234,6 +234,7 @@ rule token mode = parse | "label" { LABEL } | "let" { LET } | "loop" { LOOP } + | "persistent" { PERSISTENT} | "private" { PRIVATE } | "public" { PUBLIC } | "query" { QUERY } @@ -242,6 +243,7 @@ rule token mode = parse | "stable" { STABLE } | "switch" { SWITCH } | "system" { SYSTEM } + | "transient" { TRANSIENT } | "try" { TRY } | "throw" { THROW } | "to_candid" { TO_CANDID } diff --git a/src/mo_frontend/source_token.ml b/src/mo_frontend/source_token.ml index b49a7071967..8a94dcc121e 100644 --- a/src/mo_frontend/source_token.ml +++ b/src/mo_frontend/source_token.ml @@ -35,6 +35,7 @@ type token = | RETURN | SYSTEM | STABLE + | TRANSIENT | TRY | THROW | WITH @@ -45,6 +46,7 @@ type token = | OBJECT | ACTOR | CLASS + | PERSISTENT | PUBLIC | PRIVATE | SHARED @@ -162,6 +164,7 @@ let to_parser_token : | WHILE -> Ok Parser.WHILE | FOR -> Ok Parser.FOR | RETURN -> Ok Parser.RETURN + | TRANSIENT -> Ok Parser.TRANSIENT | TRY -> Ok Parser.TRY | THROW -> Ok Parser.THROW | FINALLY -> Ok Parser.FINALLY @@ -173,6 +176,7 @@ let to_parser_token : | OBJECT -> Ok Parser.OBJECT | ACTOR -> Ok Parser.ACTOR | CLASS -> Ok Parser.CLASS + | PERSISTENT -> Ok Parser.PERSISTENT | PUBLIC -> Ok Parser.PUBLIC | PRIVATE -> Ok Parser.PRIVATE | SHARED -> Ok Parser.SHARED @@ -302,11 +306,13 @@ let string_of_parser_token = function | Parser.OBJECT -> "OBJECT" | Parser.ACTOR -> "ACTOR" | Parser.CLASS -> "CLASS" + | Parser.PERSISTENT -> "PERSISTENT" | Parser.PUBLIC -> "PUBLIC" | Parser.PRIVATE -> "PRIVATE" | Parser.SHARED -> "SHARED" | Parser.STABLE -> "STABLE" | Parser.SYSTEM -> "SYSTEM" + | Parser.TRANSIENT -> "TRANSIENT" | Parser.QUERY -> "QUERY" | Parser.SEMICOLON -> "SEMICOLON" | Parser.SEMICOLON_EOL -> "SEMICOLON_EOL" diff --git a/test/run-drun/ok/stable-counter-class.drun.ok b/test/run-drun/ok/stable-counter-class.drun.ok index 2440e94163e..a79a8499de5 100644 --- a/test/run-drun/ok/stable-counter-class.drun.ok +++ b/test/run-drun/ok/stable-counter-class.drun.ok @@ -6,3 +6,7 @@ debug.print: {pre = 1} ingress Completed: Reply: 0x4449444c0000 debug.print: 2 ingress Completed: Reply: 0x4449444c00017d02 +debug.print: {pre = 2} +ingress Completed: Reply: 0x4449444c0000 +debug.print: 3 +ingress Completed: Reply: 0x4449444c00017d03 diff --git a/test/run-drun/ok/stable-counter.drun.ok b/test/run-drun/ok/stable-counter.drun.ok index 2440e94163e..a79a8499de5 100644 --- a/test/run-drun/ok/stable-counter.drun.ok +++ b/test/run-drun/ok/stable-counter.drun.ok @@ -6,3 +6,7 @@ debug.print: {pre = 1} ingress Completed: Reply: 0x4449444c0000 debug.print: 2 ingress Completed: Reply: 0x4449444c00017d02 +debug.print: {pre = 2} +ingress Completed: Reply: 0x4449444c0000 +debug.print: 3 +ingress Completed: Reply: 0x4449444c00017d03 diff --git a/test/run-drun/stable-counter-class.drun b/test/run-drun/stable-counter-class.drun index be5d4c62985..bb6c1da5c7a 100644 --- a/test/run-drun/stable-counter-class.drun +++ b/test/run-drun/stable-counter-class.drun @@ -1,4 +1,6 @@ install $ID stable-counter-class/stable-counter-class.mo "" ingress $ID inc "DIDL\x00\x00" -upgrade $ID stable-counter-class/stable-counter-class.mo "" +upgrade $ID stable-counter-class/stable-counter-class-1.mo "" +ingress $ID inc "DIDL\x00\x00" +upgrade $ID stable-counter-class/stable-counter-class-2.mo "" ingress $ID inc "DIDL\x00\x00" diff --git a/test/run-drun/stable-counter-class/stable-counter-class-1.mo b/test/run-drun/stable-counter-class/stable-counter-class-1.mo new file mode 100644 index 00000000000..b94c0bf4107 --- /dev/null +++ b/test/run-drun/stable-counter-class/stable-counter-class-1.mo @@ -0,0 +1,25 @@ +import Prim "mo:⛔"; + +persistent actor class Counter() { + + var count : Nat = 0; + + public func inc() : async Nat { + count += 1; + Prim.debugPrint (debug_show(count)); + count + }; + + system func preupgrade() { + Prim.debugPrint (debug_show({pre=count})); + }; + + transient let f = func(){}; + func g() {}; + class D() {}; + type T = ?T; + ignore 1; + +} + + diff --git a/test/run-drun/stable-counter-class/stable-counter-class-2.mo b/test/run-drun/stable-counter-class/stable-counter-class-2.mo new file mode 100644 index 00000000000..c654a7fbd67 --- /dev/null +++ b/test/run-drun/stable-counter-class/stable-counter-class-2.mo @@ -0,0 +1,25 @@ +import Prim "mo:⛔"; + +actor class Counter() { + + persistent var count : Nat = 0; + + public func inc() : async Nat { + count += 1; + Prim.debugPrint (debug_show(count)); + count + }; + + system func preupgrade() { + Prim.debugPrint (debug_show({pre=count})); + }; + + let f = func(){}; + func g() {}; + class D() {}; + type T = ?T; + ignore 1; + +} + + diff --git a/test/run-drun/stable-counter-class/stable-counter-class.mo b/test/run-drun/stable-counter-class/stable-counter-class.mo index 69d2a2a4f10..581f5d4afda 100644 --- a/test/run-drun/stable-counter-class/stable-counter-class.mo +++ b/test/run-drun/stable-counter-class/stable-counter-class.mo @@ -12,9 +12,13 @@ stable actor class Counter() { system func preupgrade() { Prim.debugPrint (debug_show({pre=count})); - } + }; - // let f = func(){}; // rejected as unstable + flexible let f = func(){}; + func g() {}; + class D() {}; + type T = ?T; + ignore 1; } diff --git a/test/run-drun/stable-counter.drun b/test/run-drun/stable-counter.drun index 953a3361bc9..3c33fdbea0c 100644 --- a/test/run-drun/stable-counter.drun +++ b/test/run-drun/stable-counter.drun @@ -1,4 +1,6 @@ install $ID stable-counter/stable-counter.mo "" ingress $ID inc "DIDL\x00\x00" -upgrade $ID stable-counter/stable-counter.mo "" +upgrade $ID stable-counter/stable-counter-1.mo "" +ingress $ID inc "DIDL\x00\x00" +upgrade $ID stable-counter/stable-counter-2.mo "" ingress $ID inc "DIDL\x00\x00" diff --git a/test/run-drun/stable-counter/stable-counter-1.mo b/test/run-drun/stable-counter/stable-counter-1.mo new file mode 100644 index 00000000000..9769abf1e6d --- /dev/null +++ b/test/run-drun/stable-counter/stable-counter-1.mo @@ -0,0 +1,26 @@ +import Prim "mo:⛔"; + +persistent actor Counter { + + var count : Nat = 0; + + public func inc() : async Nat { + count += 1; + Prim.debugPrint (debug_show(count)); + count + }; + + system func preupgrade() { + Prim.debugPrint (debug_show({pre=count})); + }; + + transient let f = func(){}; + + func g() {}; + class D() {}; + type T = ?T; + ignore 1; + +} + + diff --git a/test/run-drun/stable-counter/stable-counter-2.mo b/test/run-drun/stable-counter/stable-counter-2.mo new file mode 100644 index 00000000000..d29145b5d87 --- /dev/null +++ b/test/run-drun/stable-counter/stable-counter-2.mo @@ -0,0 +1,26 @@ +import Prim "mo:⛔"; + +actor Counter { + + persistent var count : Nat = 0; + + public func inc() : async Nat { + count += 1; + Prim.debugPrint (debug_show(count)); + count + }; + + system func preupgrade() { + Prim.debugPrint (debug_show({pre=count})); + }; + + let f = func(){}; + + func g() {}; + class D() {}; + type T = ?T; + ignore 1; + +} + + diff --git a/test/run-drun/stable-counter/stable-counter.mo b/test/run-drun/stable-counter/stable-counter.mo index 2c9479cf22d..db1983b20da 100644 --- a/test/run-drun/stable-counter/stable-counter.mo +++ b/test/run-drun/stable-counter/stable-counter.mo @@ -12,9 +12,13 @@ stable actor Counter { system func preupgrade() { Prim.debugPrint (debug_show({pre=count})); - } + }; - // let f = func(){}; // rejected as unstable + flexible let f = func(){}; + func g() {}; + class D() {}; + type T = ?T; + ignore 1; }