evaluator: add user-defined functions

This commit is contained in:
2018-04-30 18:08:01 +02:00
parent 013c0844c7
commit 127d2e4ad8
23 changed files with 123 additions and 0 deletions

View File

@@ -0,0 +1 @@
Im an interpreter environment.

View File

@@ -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

View 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 ]

View File

@@ -0,0 +1,3 @@
accessing
parent: env
parent := env

View File

@@ -0,0 +1,14 @@
{
"category" : "Phsyche",
"classinstvars" : [
],
"classvars" : [
],
"commentStamp" : "<historical>",
"instvars" : [
"parent" ],
"name" : "PEnv",
"pools" : [
],
"super" : "Dictionary",
"type" : "normal" }

View File

@@ -0,0 +1,5 @@
tests
setUp
outer := PEnv new.
inner := PEnv new.
inner parent: outer

View File

@@ -0,0 +1,5 @@
tests
testLookingOuterFromInner
outer at: #dad put: 'donald'.
inner at: #son put: 'riri'.
self assert: (inner at: #dad) equals: 'donald'

View File

@@ -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

View File

@@ -0,0 +1,15 @@
{
"category" : "Phsyche",
"classinstvars" : [
],
"classvars" : [
],
"commentStamp" : "",
"instvars" : [
"outer",
"inner" ],
"name" : "PEnvTest",
"pools" : [
],
"super" : "TestCase",
"type" : "normal" }

View File

@@ -0,0 +1 @@
Im a user-defined procedure.

View File

@@ -0,0 +1,3 @@
accessing
body: b
body := b

View File

@@ -0,0 +1,3 @@
accessing
body
^ body

View File

@@ -0,0 +1,3 @@
accessing
params: p
params := p

View File

@@ -0,0 +1,3 @@
accessing
params
^ params

View File

@@ -0,0 +1,6 @@
accessing
setParamEnv: values in: parent
| appEnv |
appEnv := PEnv newFromKeys: self params andValues: values.
appEnv parent: parent.
^ appEnv

View File

@@ -0,0 +1,15 @@
{
"category" : "Phsyche",
"classinstvars" : [
],
"classvars" : [
],
"commentStamp" : "<historical>",
"instvars" : [
"params",
"body" ],
"name" : "PProc",
"pools" : [
],
"super" : "Object",
"type" : "normal" }

View File

@@ -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
]

View File

@@ -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

View File

@@ -0,0 +1,3 @@
as yet unclassified
evalLambda: expr in: environ
^ PProc new params: expr second; body: expr third

View File

@@ -0,0 +1,3 @@
as yet unclassified
testLambdaProcedureExecution
self assert: (ph parseAndEval: '((lambda (x) (* x x)) 3)') equals: 9.

View File

@@ -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)

View File

@@ -0,0 +1,4 @@
as yet unclassified
testProcedureExecution
ph parseAndEval: '(define squared (lambda (x) (* x x)))'.
self assert: (ph parseAndEval: '(squared 3)') equals: 9