From 778aa4e7dfd616743f3b9e18e10bb53f5d441f5f Mon Sep 17 00:00:00 2001 From: Laurenz Date: Mon, 9 May 2022 00:11:03 +0200 Subject: [PATCH] Mutable field access --- src/eval/mod.rs | 25 +++++++++++++++++++++++-- tests/typ/code/dict.typ | 23 +++++++++++++++++++---- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/eval/mod.rs b/src/eval/mod.rs index 0021b93ca..db50ee82e 100644 --- a/src/eval/mod.rs +++ b/src/eval/mod.rs @@ -1000,8 +1000,9 @@ impl Access for Expr { scp: &'a mut Scopes, ) -> TypResult> { match self { - Expr::Ident(ident) => ident.access(ctx, scp), - Expr::FuncCall(call) => call.access(ctx, scp), + Expr::Ident(v) => v.access(ctx, scp), + Expr::FieldAccess(v) => v.access(ctx, scp), + Expr::FuncCall(v) => v.access(ctx, scp), _ => bail!(self.span(), "cannot mutate a temporary value"), } } @@ -1023,6 +1024,26 @@ impl Access for Ident { } } +impl Access for FieldAccess { + fn access<'a>( + &self, + ctx: &mut Context, + scp: &'a mut Scopes, + ) -> TypResult> { + let guard = self.object().access(ctx, scp)?; + try_map(guard, |value| { + Ok(match value { + Value::Dict(dict) => dict.get_mut(self.field().take()), + v => bail!( + self.object().span(), + "expected dictionary, found {}", + v.type_name(), + ), + }) + }) + } +} + impl Access for FuncCall { fn access<'a>( &self, diff --git a/tests/typ/code/dict.typ b/tests/typ/code/dict.typ index 800977612..182f53d95 100644 --- a/tests/typ/code/dict.typ +++ b/tests/typ/code/dict.typ @@ -17,10 +17,14 @@ --- // Test lvalue and rvalue access. { - let dict = (a: 1, b: 1) - dict("b") += 1 - dict("c") = 3 - test(dict, (a: 1, b: 2, c: 3)) + let dict = (a: 1, "b b": 1) + dict("b b") += 1 + dict.state = (ok: true, err: false) + test(dict, (a: 1, "b b": 2, state: (ok: true, err: false))) + test(dict.state.ok, true) + dict("state").ok = false + test(dict.state.ok, false) + test(dict.state.err, false) } --- @@ -58,3 +62,14 @@ // Error: 12-16 expected identifier or string, found boolean // Error: 17-18 expected expression, found colon {(:1 b:"", true::)} + +--- +// Error: 3-15 cannot mutate a temporary value +{ (key: value).other = "some" } + +--- +{ + let object = none + // Error: 3-9 expected dictionary, found none + object.property = "value" +}