evaluator: closures work
This commit is contained in:
9
src/Phsyche.package/PEnv.class/instance/lookupAt.put..st
Normal file
9
src/Phsyche.package/PEnv.class/instance/lookupAt.put..st
Normal file
@@ -0,0 +1,9 @@
|
||||
dictionary access
|
||||
lookupAt: key put: val
|
||||
| found |
|
||||
found := self at: key ifAbsent: nil.
|
||||
found
|
||||
ifNil: [ parent
|
||||
ifNotNil: [ :arg | parent lookupAt: key put: val ]
|
||||
ifNil: [ KeyNotFound signal: key , ' not found in the environment' ] ]
|
||||
ifNotNil: [ :arg | self at: key put: val ]
|
@@ -0,0 +1,9 @@
|
||||
tests
|
||||
testSetAtRightLevel
|
||||
outer at: #dad put: 'donald'.
|
||||
inner at: #son put: 'riri'.
|
||||
self assert: (inner at: #son) = 'riri'.
|
||||
inner lookupAt: #son put: 'fifi'.
|
||||
self assert: (outer at: #dad) = 'donald'.
|
||||
outer lookupAt: #dad put: 'piscou'.
|
||||
self assert: (outer at: #dad) = 'piscou'.
|
@@ -0,0 +1,9 @@
|
||||
tests
|
||||
testSetLookup
|
||||
outer at: #dad put: 'donald'.
|
||||
inner at: #son put: 'riri'.
|
||||
self assert: (inner at: #dad) = 'donald'.
|
||||
inner lookupAt: #dad put: 'picsou'.
|
||||
self assert: (outer at: #dad) = 'picsou'.
|
||||
self assert: (inner at: #dad) = 'picsou'.
|
||||
self deny: (inner keys includes: #dad)
|
3
src/Phsyche.package/PProc.class/instance/env..st
Normal file
3
src/Phsyche.package/PProc.class/instance/env..st
Normal file
@@ -0,0 +1,3 @@
|
||||
accessing
|
||||
env: e
|
||||
env := e
|
3
src/Phsyche.package/PProc.class/instance/env.st
Normal file
3
src/Phsyche.package/PProc.class/instance/env.st
Normal file
@@ -0,0 +1,3 @@
|
||||
accessing
|
||||
env
|
||||
^ env
|
@@ -7,7 +7,8 @@
|
||||
"commentStamp" : "<historical>",
|
||||
"instvars" : [
|
||||
"params",
|
||||
"body" ],
|
||||
"body",
|
||||
"env" ],
|
||||
"name" : "PProc",
|
||||
"pools" : [
|
||||
],
|
||||
|
@@ -1,3 +1,3 @@
|
||||
as yet unclassified
|
||||
divBinding
|
||||
^ #+ -> [ :e :v | e / v asFloat ]
|
||||
^ #/ -> [ :e :v | e / v asFloat ]
|
@@ -12,6 +12,8 @@ eval: expr in: environ
|
||||
fst = #define ifTrue: [ ^ self evalDefine: expr in: environ ]. "defines the value"
|
||||
fst = #if ifTrue: [ ^ self evalIf: expr in: environ]. "evaluates if"
|
||||
fst = #lambda ifTrue: [ ^ self evalLambda: expr in: environ ]. "evaluates lambda"
|
||||
fst = #begin ifTrue: [ ^ self evalBegin: expr in: environ ]. "evaluates begin"
|
||||
fst = #quote ifTrue: [ ^ expr second ]. "returns the value unevaluated"
|
||||
^ self evalApp: expr in: environ
|
||||
fst = #set ifTrue: [ ^ self evalSet: expr in: environ ]. "evaluates set"
|
||||
^ self evalApp: expr in: environ "everything else is treated as fn application"
|
||||
]
|
@@ -3,5 +3,5 @@ evalApp: expr in: environ
|
||||
| proc newEnv |
|
||||
proc := self eval: expr first in: environ.
|
||||
newEnv := proc setParamEnv: (expr allButFirst collect: [ :e | self eval: e in: environ ])
|
||||
in: environ.
|
||||
in: proc env.
|
||||
^ self eval: proc body in: newEnv
|
@@ -0,0 +1,5 @@
|
||||
as yet unclassified
|
||||
evalBegin: expr in: environ
|
||||
| res |
|
||||
expr allButFirst do: [ :each | res := self eval: each in: environ ].
|
||||
^ res
|
@@ -1,3 +1,3 @@
|
||||
as yet unclassified
|
||||
evalLambda: expr in: environ
|
||||
^ PProc new params: expr second; body: expr third
|
||||
^ PProc new params: expr second; body: expr third; env: environ
|
||||
|
@@ -0,0 +1,4 @@
|
||||
as yet unclassified
|
||||
evalSet: expr in: environ
|
||||
environ lookupAt: expr second put: (self eval: expr third in: environ).
|
||||
^ #undefined
|
@@ -1,6 +1,6 @@
|
||||
initialization
|
||||
initialize
|
||||
super initialize.
|
||||
env := Dictionary new.
|
||||
env := PEnv new.
|
||||
prims := OrderedCollection new.
|
||||
self initializeEnvBindings
|
@@ -1,3 +1,3 @@
|
||||
as yet unclassified
|
||||
minusBinding
|
||||
^ #+ -> [ :e :v | e - v ]
|
||||
^ #- -> [ :e :v | e - v ]
|
@@ -0,0 +1,3 @@
|
||||
tests
|
||||
testEvalBegin
|
||||
self assert: (ph parseAndEval: '(begin 1 2 3)') equals: 3
|
@@ -0,0 +1,3 @@
|
||||
tests
|
||||
testEvalBeginSet
|
||||
self assert: (ph parseAndEval: '(begin (define x 1) (set x 2) x)') equals: 2
|
@@ -0,0 +1,13 @@
|
||||
tests
|
||||
testEvalSetAtCorrectLevel
|
||||
| proc |
|
||||
ph parseAndEval: '
|
||||
(define fy3
|
||||
((lambda (x)
|
||||
(lambda (y)
|
||||
(begin
|
||||
(set x (+ x 2))
|
||||
(+ x y))))
|
||||
3))'.
|
||||
proc := ph eval: #fy3.
|
||||
self assert: (ph parseAndEval: '(fy3 5)') equals: 10
|
@@ -0,0 +1,5 @@
|
||||
tests
|
||||
testEvalSimpleSet
|
||||
self assert: (ph parseAndEval: '(define x2 21') equals: #undefined.
|
||||
self assert: (ph parseAndEval: '(set x2 22)') equals: #undefined.
|
||||
self assert: (ph parseAndEval: 'x2') equals: 22.
|
@@ -1,3 +1,3 @@
|
||||
as yet unclassified
|
||||
tests
|
||||
testLambdaProcedureExecution
|
||||
self assert: (ph parseAndEval: '((lambda (x) (* x x)) 3)') equals: 9.
|
@@ -1,4 +1,4 @@
|
||||
as yet unclassified
|
||||
tests
|
||||
testProcedureDefinition
|
||||
| proc |
|
||||
ph parseAndEval: '(define squared (lambda (x) (* x x)))'.
|
||||
|
@@ -1,4 +1,4 @@
|
||||
as yet unclassified
|
||||
tests
|
||||
testProcedureExecution
|
||||
ph parseAndEval: '(define squared (lambda (x) (* x x)))'.
|
||||
self assert: (ph parseAndEval: '(squared 3)') equals: 9
|
@@ -0,0 +1,10 @@
|
||||
tests
|
||||
testSimpleClosure
|
||||
| res |
|
||||
res := ph eval: (ph parse: '(
|
||||
((lambda (x)
|
||||
(lambda (y)
|
||||
(+ x y)))
|
||||
3)
|
||||
7)').
|
||||
self assert: res equals: 10
|
@@ -0,0 +1,11 @@
|
||||
tests
|
||||
testSimpleClosureIntrospection
|
||||
| proc |
|
||||
ph parseAndEval: '(define fy3
|
||||
((lambda (x)
|
||||
(lambda (y)
|
||||
x))
|
||||
3))'.
|
||||
proc := ph parseAndEval: '#fy3'.
|
||||
self assert: proc params equals: #(y).
|
||||
self assert: (proc env at: #x) equals: 3.
|
Reference in New Issue
Block a user