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"
|
||||
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 = #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