Some simple context-aware operations Description: As in any language, lisp interpreters allow to store information in "variables". A variable is an identifier, which is associated to a lisp expression using the operator "define". To update the value associated with a variable, a specific "set!" operator must be used. The scope of those variables is by default global, i.e. they can be accessed in any lisp expression after being defined. A specific case is the one of function (lambda expression) parameters. Those variables are not defined explicitly. Their scope is limited to the body of the lambda expression. Narrative: In order to reuse information, as a casual lisp user I want to associate expressions to identifiers using the keyword define. Scenario: simple definitions Given a lisp interpreter When the expression entered is (define a 5) Then the result should be 5 When the expression entered is (define b 10) Then the result should be 10 When the expression entered is Then the result should be Examples: |expression |result| |(+ a b) | 15 | |(- a b) | -5 | |(* a b) | 50 | |(* 1 a 2 b) | 100 | |(/ b a) | 2 | |(max a b) | 10 | |(min a b) | 5 | |(cons a (cons b ()))| (5 10) | Scenario: overriding definitions Given a lisp interpreter When the expression entered is (define a 5) Then the result should be 5 When the expression entered is (define b 10) Then the result should be 10 When the expression entered is (+ a b) Then the result should be 15 When the expression entered is (define b 30) Then the result should be 30 When the expression entered is (+ a b) Then the result should be 35 When the expression entered is (define a 20) Then the result should be 20 When the expression entered is (+ a b) Then the result should be 50 Scenario: some students are picky about testing Given a lisp interpreter When the expression entered is Then the result should display the error message Examples: |expression|result| |(define 12 20)|12 is not a valid identifier| |(define + 20)|+ is not a valid identifier| |(define - 20)|- is not a valid identifier| |(define * 20)|* is not a valid identifier| |(define / 20)|/ is not a valid identifier| |(define or 20)|or is not a valid identifier| |(define not 20)|not is not a valid identifier| |(define and 20)|and is not a valid identifier| |(define lambda 20)|lambda is not a valid identifier| |(define define 20)|define is not a valid identifier| |(define set! 20)|set! is not a valid identifier| |(define cons 20)|cons is not a valid identifier| Scenario: modifying the value of an identifier using set! Given a lisp interpreter When the expression entered is (define a 50) Then the result should be 50 When the expression entered is (set! a 30) Then the result should be 30 When the expression entered is (set! b 20) Then the result should display the error message b is undefined Scenario: defining a function (a lambda expression) with one parameter Given a lisp interpreter When the expression entered is (define surprise (lambda (x) (* x x))) Then the result should be lambda (x) (* x x) When the expression entered is (surprise 10) Then the result should be 100 Scenario: defining a function (a lambda expression) with two parameters Given a lisp interpreter When the expression entered is (define surprise (lambda (x y) (* x y))) Then the result should be lambda (x y) (* x y) When the expression entered is (surprise 10 20) Then the result should be 200 Scenario: a function has its own context Given a lisp interpreter When the expression entered is (define x 10) Then the result should be 10 When the expression entered is x Then the result should be 10 When the expression entered is (define surprise (lambda (x) (* x x))) Then the result should be lambda (x) (* x x) When the expression entered is (surprise 15) Then the result should be 225 When the expression entered is x Then the result should be 10 Scenario: identifier is not defined Given a lisp interpreter When the expression entered is x Then the result should display the error message x is undefined When the expression entered is (surprise 15) Then the result should display the error message surprise is undefined Scenario: first group inspiration Given a lisp interpreter When the expression entered is (define n 10) Then the result should be 10 When the expression entered is (define f (lambda (x) (* n x))) Then the result should be lambda (x) (* n x) When the expression entered is (f 4) Then the result should be 40 When the expression entered is (set! n 100) Then the result should be 100 When the expression entered is (f 4) Then the result should be 400