diff --git a/src/Phsyche.package/PEnv.class/instance/lookupAt.put..st b/src/Phsyche.package/PEnv.class/instance/lookupAt.put..st new file mode 100644 index 0000000..ac8782b --- /dev/null +++ b/src/Phsyche.package/PEnv.class/instance/lookupAt.put..st @@ -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 ] \ No newline at end of file diff --git a/src/Phsyche.package/PEnvTest.class/instance/testSetAtRightLevel.st b/src/Phsyche.package/PEnvTest.class/instance/testSetAtRightLevel.st new file mode 100644 index 0000000..18aba52 --- /dev/null +++ b/src/Phsyche.package/PEnvTest.class/instance/testSetAtRightLevel.st @@ -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'. \ No newline at end of file diff --git a/src/Phsyche.package/PEnvTest.class/instance/testSetLookup.st b/src/Phsyche.package/PEnvTest.class/instance/testSetLookup.st new file mode 100644 index 0000000..f6750d1 --- /dev/null +++ b/src/Phsyche.package/PEnvTest.class/instance/testSetLookup.st @@ -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) \ No newline at end of file diff --git a/src/Phsyche.package/PProc.class/instance/env..st b/src/Phsyche.package/PProc.class/instance/env..st new file mode 100644 index 0000000..e0f1181 --- /dev/null +++ b/src/Phsyche.package/PProc.class/instance/env..st @@ -0,0 +1,3 @@ +accessing +env: e + env := e \ No newline at end of file diff --git a/src/Phsyche.package/PProc.class/instance/env.st b/src/Phsyche.package/PProc.class/instance/env.st new file mode 100644 index 0000000..cf85606 --- /dev/null +++ b/src/Phsyche.package/PProc.class/instance/env.st @@ -0,0 +1,3 @@ +accessing +env + ^ env \ No newline at end of file diff --git a/src/Phsyche.package/PProc.class/properties.json b/src/Phsyche.package/PProc.class/properties.json index 57582f2..738b8f1 100644 --- a/src/Phsyche.package/PProc.class/properties.json +++ b/src/Phsyche.package/PProc.class/properties.json @@ -7,7 +7,8 @@ "commentStamp" : "", "instvars" : [ "params", - "body" ], + "body", + "env" ], "name" : "PProc", "pools" : [ ], diff --git a/src/Phsyche.package/Phsyche.class/instance/divBinding.st b/src/Phsyche.package/Phsyche.class/instance/divBinding.st index 4bcc678..cc58235 100644 --- a/src/Phsyche.package/Phsyche.class/instance/divBinding.st +++ b/src/Phsyche.package/Phsyche.class/instance/divBinding.st @@ -1,3 +1,3 @@ as yet unclassified divBinding - ^ #+ -> [ :e :v | e / v asFloat ] \ No newline at end of file + ^ #/ -> [ :e :v | e / v asFloat ] \ No newline at end of file diff --git a/src/Phsyche.package/Phsyche.class/instance/eval.in..st b/src/Phsyche.package/Phsyche.class/instance/eval.in..st index fbfa18a..b1d0b64 100644 --- a/src/Phsyche.package/Phsyche.class/instance/eval.in..st +++ b/src/Phsyche.package/Phsyche.class/instance/eval.in..st @@ -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" ] \ No newline at end of file diff --git a/src/Phsyche.package/Phsyche.class/instance/evalApp.in..st b/src/Phsyche.package/Phsyche.class/instance/evalApp.in..st index 8da53a8..7c47c39 100644 --- a/src/Phsyche.package/Phsyche.class/instance/evalApp.in..st +++ b/src/Phsyche.package/Phsyche.class/instance/evalApp.in..st @@ -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 \ No newline at end of file diff --git a/src/Phsyche.package/Phsyche.class/instance/evalBegin.in..st b/src/Phsyche.package/Phsyche.class/instance/evalBegin.in..st new file mode 100644 index 0000000..706423a --- /dev/null +++ b/src/Phsyche.package/Phsyche.class/instance/evalBegin.in..st @@ -0,0 +1,5 @@ +as yet unclassified +evalBegin: expr in: environ + | res | + expr allButFirst do: [ :each | res := self eval: each in: environ ]. + ^ res \ No newline at end of file diff --git a/src/Phsyche.package/Phsyche.class/instance/evalLambda.in..st b/src/Phsyche.package/Phsyche.class/instance/evalLambda.in..st index 6fc30e9..043dfd7 100644 --- a/src/Phsyche.package/Phsyche.class/instance/evalLambda.in..st +++ b/src/Phsyche.package/Phsyche.class/instance/evalLambda.in..st @@ -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 diff --git a/src/Phsyche.package/Phsyche.class/instance/evalSet.in..st b/src/Phsyche.package/Phsyche.class/instance/evalSet.in..st new file mode 100644 index 0000000..059cfc8 --- /dev/null +++ b/src/Phsyche.package/Phsyche.class/instance/evalSet.in..st @@ -0,0 +1,4 @@ +as yet unclassified +evalSet: expr in: environ + environ lookupAt: expr second put: (self eval: expr third in: environ). + ^ #undefined \ No newline at end of file diff --git a/src/Phsyche.package/Phsyche.class/instance/initialize.st b/src/Phsyche.package/Phsyche.class/instance/initialize.st index 87d0528..d5b9a66 100644 --- a/src/Phsyche.package/Phsyche.class/instance/initialize.st +++ b/src/Phsyche.package/Phsyche.class/instance/initialize.st @@ -1,6 +1,6 @@ initialization initialize super initialize. - env := Dictionary new. + env := PEnv new. prims := OrderedCollection new. self initializeEnvBindings \ No newline at end of file diff --git a/src/Phsyche.package/Phsyche.class/instance/minusBinding.st b/src/Phsyche.package/Phsyche.class/instance/minusBinding.st index ac392b3..db12a38 100644 --- a/src/Phsyche.package/Phsyche.class/instance/minusBinding.st +++ b/src/Phsyche.package/Phsyche.class/instance/minusBinding.st @@ -1,3 +1,3 @@ as yet unclassified minusBinding - ^ #+ -> [ :e :v | e - v ] \ No newline at end of file + ^ #- -> [ :e :v | e - v ] \ No newline at end of file diff --git a/src/Phsyche.package/PhsycheTest.class/instance/testEvalBegin.st b/src/Phsyche.package/PhsycheTest.class/instance/testEvalBegin.st new file mode 100644 index 0000000..0176219 --- /dev/null +++ b/src/Phsyche.package/PhsycheTest.class/instance/testEvalBegin.st @@ -0,0 +1,3 @@ +tests +testEvalBegin + self assert: (ph parseAndEval: '(begin 1 2 3)') equals: 3 \ No newline at end of file diff --git a/src/Phsyche.package/PhsycheTest.class/instance/testEvalBeginSet.st b/src/Phsyche.package/PhsycheTest.class/instance/testEvalBeginSet.st new file mode 100644 index 0000000..8497623 --- /dev/null +++ b/src/Phsyche.package/PhsycheTest.class/instance/testEvalBeginSet.st @@ -0,0 +1,3 @@ +tests +testEvalBeginSet + self assert: (ph parseAndEval: '(begin (define x 1) (set x 2) x)') equals: 2 \ No newline at end of file diff --git a/src/Phsyche.package/PhsycheTest.class/instance/testEvalSetAtCorrectLevel.st b/src/Phsyche.package/PhsycheTest.class/instance/testEvalSetAtCorrectLevel.st new file mode 100644 index 0000000..6f0c000 --- /dev/null +++ b/src/Phsyche.package/PhsycheTest.class/instance/testEvalSetAtCorrectLevel.st @@ -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 \ No newline at end of file diff --git a/src/Phsyche.package/PhsycheTest.class/instance/testEvalSimpleSet.st b/src/Phsyche.package/PhsycheTest.class/instance/testEvalSimpleSet.st new file mode 100644 index 0000000..c6eb3be --- /dev/null +++ b/src/Phsyche.package/PhsycheTest.class/instance/testEvalSimpleSet.st @@ -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. \ No newline at end of file diff --git a/src/Phsyche.package/PhsycheTest.class/instance/testLambdaProcedureExecution.st b/src/Phsyche.package/PhsycheTest.class/instance/testLambdaProcedureExecution.st index 7da50e0..eb4c981 100644 --- a/src/Phsyche.package/PhsycheTest.class/instance/testLambdaProcedureExecution.st +++ b/src/Phsyche.package/PhsycheTest.class/instance/testLambdaProcedureExecution.st @@ -1,3 +1,3 @@ -as yet unclassified +tests testLambdaProcedureExecution self assert: (ph parseAndEval: '((lambda (x) (* x x)) 3)') equals: 9. \ No newline at end of file diff --git a/src/Phsyche.package/PhsycheTest.class/instance/testProcedureDefinition.st b/src/Phsyche.package/PhsycheTest.class/instance/testProcedureDefinition.st index ed52490..263dfd5 100644 --- a/src/Phsyche.package/PhsycheTest.class/instance/testProcedureDefinition.st +++ b/src/Phsyche.package/PhsycheTest.class/instance/testProcedureDefinition.st @@ -1,4 +1,4 @@ -as yet unclassified +tests testProcedureDefinition | proc | ph parseAndEval: '(define squared (lambda (x) (* x x)))'. diff --git a/src/Phsyche.package/PhsycheTest.class/instance/testProcedureExecution.st b/src/Phsyche.package/PhsycheTest.class/instance/testProcedureExecution.st index dd50c94..503c375 100644 --- a/src/Phsyche.package/PhsycheTest.class/instance/testProcedureExecution.st +++ b/src/Phsyche.package/PhsycheTest.class/instance/testProcedureExecution.st @@ -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 \ No newline at end of file diff --git a/src/Phsyche.package/PhsycheTest.class/instance/testSimpleClosure.st b/src/Phsyche.package/PhsycheTest.class/instance/testSimpleClosure.st new file mode 100644 index 0000000..5d052a6 --- /dev/null +++ b/src/Phsyche.package/PhsycheTest.class/instance/testSimpleClosure.st @@ -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 \ No newline at end of file diff --git a/src/Phsyche.package/PhsycheTest.class/instance/testSimpleClosureIntrospection.st b/src/Phsyche.package/PhsycheTest.class/instance/testSimpleClosureIntrospection.st new file mode 100644 index 0000000..f49435c --- /dev/null +++ b/src/Phsyche.package/PhsycheTest.class/instance/testSimpleClosureIntrospection.st @@ -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. \ No newline at end of file