evaluator: add user-defined functions
This commit is contained in:
1
src/Phsyche.package/PEnv.class/README.md
Normal file
1
src/Phsyche.package/PEnv.class/README.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
I’m an interpreter environment.
|
@@ -0,0 +1,6 @@
|
|||||||
|
dictionary access
|
||||||
|
newFromKeys: keys andValues: values
|
||||||
|
| dict |
|
||||||
|
dict := self new.
|
||||||
|
keys with: values do: [ :k :v | dict at: k put: v ].
|
||||||
|
^ dict
|
7
src/Phsyche.package/PEnv.class/instance/at..st
Normal file
7
src/Phsyche.package/PEnv.class/instance/at..st
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
dictionary access
|
||||||
|
at: key
|
||||||
|
| value |
|
||||||
|
value := self at: key ifAbsent: [ nil ].
|
||||||
|
^ value
|
||||||
|
ifNil: [ parent ifNil: [ super at: key ] ifNotNil: [ :arg | parent at: key ] ]
|
||||||
|
ifNotNil: [ :v | v ]
|
3
src/Phsyche.package/PEnv.class/instance/parent..st
Normal file
3
src/Phsyche.package/PEnv.class/instance/parent..st
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
accessing
|
||||||
|
parent: env
|
||||||
|
parent := env
|
14
src/Phsyche.package/PEnv.class/properties.json
Normal file
14
src/Phsyche.package/PEnv.class/properties.json
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"category" : "Phsyche",
|
||||||
|
"classinstvars" : [
|
||||||
|
],
|
||||||
|
"classvars" : [
|
||||||
|
],
|
||||||
|
"commentStamp" : "<historical>",
|
||||||
|
"instvars" : [
|
||||||
|
"parent" ],
|
||||||
|
"name" : "PEnv",
|
||||||
|
"pools" : [
|
||||||
|
],
|
||||||
|
"super" : "Dictionary",
|
||||||
|
"type" : "normal" }
|
0
src/Phsyche.package/PEnvTest.class/README.md
Normal file
0
src/Phsyche.package/PEnvTest.class/README.md
Normal file
5
src/Phsyche.package/PEnvTest.class/instance/setUp.st
Normal file
5
src/Phsyche.package/PEnvTest.class/instance/setUp.st
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
tests
|
||||||
|
setUp
|
||||||
|
outer := PEnv new.
|
||||||
|
inner := PEnv new.
|
||||||
|
inner parent: outer
|
@@ -0,0 +1,5 @@
|
|||||||
|
tests
|
||||||
|
testLookingOuterFromInner
|
||||||
|
outer at: #dad put: 'donald'.
|
||||||
|
inner at: #son put: 'riri'.
|
||||||
|
self assert: (inner at: #dad) equals: 'donald'
|
@@ -0,0 +1,7 @@
|
|||||||
|
tests
|
||||||
|
testLookupInFails
|
||||||
|
outer at: #dad put: 'donald'.
|
||||||
|
inner at: #son put: 'riri'.
|
||||||
|
self should: [ outer at: #nodad ] raise: KeyNotFound.
|
||||||
|
self should: [ outer at: #noson ] raise: KeyNotFound.
|
||||||
|
self should: [ inner at: #nodad ] raise: KeyNotFound
|
15
src/Phsyche.package/PEnvTest.class/properties.json
Normal file
15
src/Phsyche.package/PEnvTest.class/properties.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"category" : "Phsyche",
|
||||||
|
"classinstvars" : [
|
||||||
|
],
|
||||||
|
"classvars" : [
|
||||||
|
],
|
||||||
|
"commentStamp" : "",
|
||||||
|
"instvars" : [
|
||||||
|
"outer",
|
||||||
|
"inner" ],
|
||||||
|
"name" : "PEnvTest",
|
||||||
|
"pools" : [
|
||||||
|
],
|
||||||
|
"super" : "TestCase",
|
||||||
|
"type" : "normal" }
|
1
src/Phsyche.package/PProc.class/README.md
Normal file
1
src/Phsyche.package/PProc.class/README.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
I’m a user-defined procedure.
|
3
src/Phsyche.package/PProc.class/instance/body..st
Normal file
3
src/Phsyche.package/PProc.class/instance/body..st
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
accessing
|
||||||
|
body: b
|
||||||
|
body := b
|
3
src/Phsyche.package/PProc.class/instance/body.st
Normal file
3
src/Phsyche.package/PProc.class/instance/body.st
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
accessing
|
||||||
|
body
|
||||||
|
^ body
|
3
src/Phsyche.package/PProc.class/instance/params..st
Normal file
3
src/Phsyche.package/PProc.class/instance/params..st
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
accessing
|
||||||
|
params: p
|
||||||
|
params := p
|
3
src/Phsyche.package/PProc.class/instance/params.st
Normal file
3
src/Phsyche.package/PProc.class/instance/params.st
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
accessing
|
||||||
|
params
|
||||||
|
^ params
|
@@ -0,0 +1,6 @@
|
|||||||
|
accessing
|
||||||
|
setParamEnv: values in: parent
|
||||||
|
| appEnv |
|
||||||
|
appEnv := PEnv newFromKeys: self params andValues: values.
|
||||||
|
appEnv parent: parent.
|
||||||
|
^ appEnv
|
15
src/Phsyche.package/PProc.class/properties.json
Normal file
15
src/Phsyche.package/PProc.class/properties.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"category" : "Phsyche",
|
||||||
|
"classinstvars" : [
|
||||||
|
],
|
||||||
|
"classvars" : [
|
||||||
|
],
|
||||||
|
"commentStamp" : "<historical>",
|
||||||
|
"instvars" : [
|
||||||
|
"params",
|
||||||
|
"body" ],
|
||||||
|
"name" : "PProc",
|
||||||
|
"pools" : [
|
||||||
|
],
|
||||||
|
"super" : "Object",
|
||||||
|
"type" : "normal" }
|
@@ -11,5 +11,7 @@ eval: expr in: environ
|
|||||||
]. "evaluates primitive"
|
]. "evaluates primitive"
|
||||||
fst = #define ifTrue: [ ^ self evalDefine: expr in: environ ]. "defines the value"
|
fst = #define ifTrue: [ ^ self evalDefine: expr in: environ ]. "defines the value"
|
||||||
fst = #if ifTrue: [ ^ self evalIf: expr in: environ]. "evaluates if"
|
fst = #if ifTrue: [ ^ self evalIf: expr in: environ]. "evaluates if"
|
||||||
|
fst = #lambda ifTrue: [ ^ self evalLambda: expr in: environ ]. "evaluates lambda"
|
||||||
fst = #quote ifTrue: [ ^ expr second ]. "returns the value unevaluated"
|
fst = #quote ifTrue: [ ^ expr second ]. "returns the value unevaluated"
|
||||||
|
^ self evalApp: expr in: environ
|
||||||
]
|
]
|
@@ -0,0 +1,7 @@
|
|||||||
|
as yet unclassified
|
||||||
|
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.
|
||||||
|
^ self eval: proc body in: newEnv
|
@@ -0,0 +1,3 @@
|
|||||||
|
as yet unclassified
|
||||||
|
evalLambda: expr in: environ
|
||||||
|
^ PProc new params: expr second; body: expr third
|
@@ -0,0 +1,3 @@
|
|||||||
|
as yet unclassified
|
||||||
|
testLambdaProcedureExecution
|
||||||
|
self assert: (ph parseAndEval: '((lambda (x) (* x x)) 3)') equals: 9.
|
@@ -0,0 +1,7 @@
|
|||||||
|
as yet unclassified
|
||||||
|
testProcedureDefinition
|
||||||
|
| proc |
|
||||||
|
ph parseAndEval: '(define squared (lambda (x) (* x x)))'.
|
||||||
|
proc := ph parseAndEval: #squared.
|
||||||
|
self assert: proc params equals: #(#x).
|
||||||
|
self assert: proc body equals: #(#* #x #x)
|
@@ -0,0 +1,4 @@
|
|||||||
|
as yet unclassified
|
||||||
|
testProcedureExecution
|
||||||
|
ph parseAndEval: '(define squared (lambda (x) (* x x)))'.
|
||||||
|
self assert: (ph parseAndEval: '(squared 3)') equals: 9
|
Reference in New Issue
Block a user