diff --git a/lib/Minilisp.pm b/lib/Minilisp.pm index fde6a86..85ca69b 100644 --- a/lib/Minilisp.pm +++ b/lib/Minilisp.pm @@ -743,6 +743,25 @@ sub macro_unless { } $macros{unless} = \¯o_unless; +sub macro_set { + my $ts = shift; + + my $ident = parser_identifier($ts); + + my $expr = parser_expr($ts); + + return sub { + my $ctx = shift; + + my $value = $expr->($ctx); + + ctx_assign($ctx, $ident, $value); + + return $value; + } +} +$macros{set} = \¯o_set; + sub compile { my ($term) = @_; my @tokens = tokenize($term); diff --git a/t/context.t b/t/context.t new file mode 100644 index 0000000..e563538 --- /dev/null +++ b/t/context.t @@ -0,0 +1,12 @@ +(let ((a 2)) + (let ((a 10)) + (expect "Inner variable shadows outer" (= a 10))) + (expect "Outer is not overriden" (= a 2))) + +(let ((pings 0)) + (defun ping () + (set pings (+ pings 1))) + + (ping) (ping) (ping) + + (expect "setting variables in outside context works" (= pings 3)))