From 127d2e4ad8aa0333ec9019f2ab911723883fa968 Mon Sep 17 00:00:00 2001 From: hellerve Date: Mon, 30 Apr 2018 18:08:01 +0200 Subject: [PATCH] evaluator: add user-defined functions --- src/Phsyche.package/PEnv.class/README.md | 1 + .../PEnv.class/class/newFromKeys.andValues..st | 6 ++++++ src/Phsyche.package/PEnv.class/instance/at..st | 7 +++++++ .../PEnv.class/instance/parent..st | 3 +++ src/Phsyche.package/PEnv.class/properties.json | 14 ++++++++++++++ src/Phsyche.package/PEnvTest.class/README.md | 0 .../PEnvTest.class/instance/setUp.st | 5 +++++ .../instance/testLookingOuterFromInner.st | 5 +++++ .../PEnvTest.class/instance/testLookupInFails.st | 7 +++++++ .../PEnvTest.class/properties.json | 15 +++++++++++++++ src/Phsyche.package/PProc.class/README.md | 1 + src/Phsyche.package/PProc.class/instance/body..st | 3 +++ src/Phsyche.package/PProc.class/instance/body.st | 3 +++ .../PProc.class/instance/params..st | 3 +++ .../PProc.class/instance/params.st | 3 +++ .../PProc.class/instance/setParamEnv.in..st | 6 ++++++ src/Phsyche.package/PProc.class/properties.json | 15 +++++++++++++++ .../Phsyche.class/instance/eval.in..st | 2 ++ .../Phsyche.class/instance/evalApp.in..st | 7 +++++++ .../Phsyche.class/instance/evalLambda.in..st | 3 +++ .../instance/testLambdaProcedureExecution.st | 3 +++ .../instance/testProcedureDefinition.st | 7 +++++++ .../instance/testProcedureExecution.st | 4 ++++ 23 files changed, 123 insertions(+) create mode 100644 src/Phsyche.package/PEnv.class/README.md create mode 100644 src/Phsyche.package/PEnv.class/class/newFromKeys.andValues..st create mode 100644 src/Phsyche.package/PEnv.class/instance/at..st create mode 100644 src/Phsyche.package/PEnv.class/instance/parent..st create mode 100644 src/Phsyche.package/PEnv.class/properties.json create mode 100644 src/Phsyche.package/PEnvTest.class/README.md create mode 100644 src/Phsyche.package/PEnvTest.class/instance/setUp.st create mode 100644 src/Phsyche.package/PEnvTest.class/instance/testLookingOuterFromInner.st create mode 100644 src/Phsyche.package/PEnvTest.class/instance/testLookupInFails.st create mode 100644 src/Phsyche.package/PEnvTest.class/properties.json create mode 100644 src/Phsyche.package/PProc.class/README.md create mode 100644 src/Phsyche.package/PProc.class/instance/body..st create mode 100644 src/Phsyche.package/PProc.class/instance/body.st create mode 100644 src/Phsyche.package/PProc.class/instance/params..st create mode 100644 src/Phsyche.package/PProc.class/instance/params.st create mode 100644 src/Phsyche.package/PProc.class/instance/setParamEnv.in..st create mode 100644 src/Phsyche.package/PProc.class/properties.json create mode 100644 src/Phsyche.package/Phsyche.class/instance/evalApp.in..st create mode 100644 src/Phsyche.package/Phsyche.class/instance/evalLambda.in..st create mode 100644 src/Phsyche.package/PhsycheTest.class/instance/testLambdaProcedureExecution.st create mode 100644 src/Phsyche.package/PhsycheTest.class/instance/testProcedureDefinition.st create mode 100644 src/Phsyche.package/PhsycheTest.class/instance/testProcedureExecution.st diff --git a/src/Phsyche.package/PEnv.class/README.md b/src/Phsyche.package/PEnv.class/README.md new file mode 100644 index 0000000..8c63f69 --- /dev/null +++ b/src/Phsyche.package/PEnv.class/README.md @@ -0,0 +1 @@ +I’m an interpreter environment. \ No newline at end of file diff --git a/src/Phsyche.package/PEnv.class/class/newFromKeys.andValues..st b/src/Phsyche.package/PEnv.class/class/newFromKeys.andValues..st new file mode 100644 index 0000000..0a4affc --- /dev/null +++ b/src/Phsyche.package/PEnv.class/class/newFromKeys.andValues..st @@ -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 \ No newline at end of file diff --git a/src/Phsyche.package/PEnv.class/instance/at..st b/src/Phsyche.package/PEnv.class/instance/at..st new file mode 100644 index 0000000..f3e0496 --- /dev/null +++ b/src/Phsyche.package/PEnv.class/instance/at..st @@ -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 ] \ No newline at end of file diff --git a/src/Phsyche.package/PEnv.class/instance/parent..st b/src/Phsyche.package/PEnv.class/instance/parent..st new file mode 100644 index 0000000..be8ee98 --- /dev/null +++ b/src/Phsyche.package/PEnv.class/instance/parent..st @@ -0,0 +1,3 @@ +accessing +parent: env + parent := env \ No newline at end of file diff --git a/src/Phsyche.package/PEnv.class/properties.json b/src/Phsyche.package/PEnv.class/properties.json new file mode 100644 index 0000000..4b364dd --- /dev/null +++ b/src/Phsyche.package/PEnv.class/properties.json @@ -0,0 +1,14 @@ +{ + "category" : "Phsyche", + "classinstvars" : [ + ], + "classvars" : [ + ], + "commentStamp" : "", + "instvars" : [ + "parent" ], + "name" : "PEnv", + "pools" : [ + ], + "super" : "Dictionary", + "type" : "normal" } diff --git a/src/Phsyche.package/PEnvTest.class/README.md b/src/Phsyche.package/PEnvTest.class/README.md new file mode 100644 index 0000000..e69de29 diff --git a/src/Phsyche.package/PEnvTest.class/instance/setUp.st b/src/Phsyche.package/PEnvTest.class/instance/setUp.st new file mode 100644 index 0000000..974685f --- /dev/null +++ b/src/Phsyche.package/PEnvTest.class/instance/setUp.st @@ -0,0 +1,5 @@ +tests +setUp + outer := PEnv new. + inner := PEnv new. + inner parent: outer \ No newline at end of file diff --git a/src/Phsyche.package/PEnvTest.class/instance/testLookingOuterFromInner.st b/src/Phsyche.package/PEnvTest.class/instance/testLookingOuterFromInner.st new file mode 100644 index 0000000..7d1f5de --- /dev/null +++ b/src/Phsyche.package/PEnvTest.class/instance/testLookingOuterFromInner.st @@ -0,0 +1,5 @@ +tests +testLookingOuterFromInner + outer at: #dad put: 'donald'. + inner at: #son put: 'riri'. + self assert: (inner at: #dad) equals: 'donald' \ No newline at end of file diff --git a/src/Phsyche.package/PEnvTest.class/instance/testLookupInFails.st b/src/Phsyche.package/PEnvTest.class/instance/testLookupInFails.st new file mode 100644 index 0000000..eef6812 --- /dev/null +++ b/src/Phsyche.package/PEnvTest.class/instance/testLookupInFails.st @@ -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 \ No newline at end of file diff --git a/src/Phsyche.package/PEnvTest.class/properties.json b/src/Phsyche.package/PEnvTest.class/properties.json new file mode 100644 index 0000000..5676d0a --- /dev/null +++ b/src/Phsyche.package/PEnvTest.class/properties.json @@ -0,0 +1,15 @@ +{ + "category" : "Phsyche", + "classinstvars" : [ + ], + "classvars" : [ + ], + "commentStamp" : "", + "instvars" : [ + "outer", + "inner" ], + "name" : "PEnvTest", + "pools" : [ + ], + "super" : "TestCase", + "type" : "normal" } diff --git a/src/Phsyche.package/PProc.class/README.md b/src/Phsyche.package/PProc.class/README.md new file mode 100644 index 0000000..5ab6662 --- /dev/null +++ b/src/Phsyche.package/PProc.class/README.md @@ -0,0 +1 @@ +I’m a user-defined procedure. \ No newline at end of file diff --git a/src/Phsyche.package/PProc.class/instance/body..st b/src/Phsyche.package/PProc.class/instance/body..st new file mode 100644 index 0000000..7eacdb7 --- /dev/null +++ b/src/Phsyche.package/PProc.class/instance/body..st @@ -0,0 +1,3 @@ +accessing +body: b + body := b \ No newline at end of file diff --git a/src/Phsyche.package/PProc.class/instance/body.st b/src/Phsyche.package/PProc.class/instance/body.st new file mode 100644 index 0000000..38c9578 --- /dev/null +++ b/src/Phsyche.package/PProc.class/instance/body.st @@ -0,0 +1,3 @@ +accessing +body + ^ body \ No newline at end of file diff --git a/src/Phsyche.package/PProc.class/instance/params..st b/src/Phsyche.package/PProc.class/instance/params..st new file mode 100644 index 0000000..8214625 --- /dev/null +++ b/src/Phsyche.package/PProc.class/instance/params..st @@ -0,0 +1,3 @@ +accessing +params: p + params := p \ No newline at end of file diff --git a/src/Phsyche.package/PProc.class/instance/params.st b/src/Phsyche.package/PProc.class/instance/params.st new file mode 100644 index 0000000..1e8bd2f --- /dev/null +++ b/src/Phsyche.package/PProc.class/instance/params.st @@ -0,0 +1,3 @@ +accessing +params + ^ params \ No newline at end of file diff --git a/src/Phsyche.package/PProc.class/instance/setParamEnv.in..st b/src/Phsyche.package/PProc.class/instance/setParamEnv.in..st new file mode 100644 index 0000000..efbfe4b --- /dev/null +++ b/src/Phsyche.package/PProc.class/instance/setParamEnv.in..st @@ -0,0 +1,6 @@ +accessing +setParamEnv: values in: parent + | appEnv | + appEnv := PEnv newFromKeys: self params andValues: values. + appEnv parent: parent. + ^ appEnv \ No newline at end of file diff --git a/src/Phsyche.package/PProc.class/properties.json b/src/Phsyche.package/PProc.class/properties.json new file mode 100644 index 0000000..57582f2 --- /dev/null +++ b/src/Phsyche.package/PProc.class/properties.json @@ -0,0 +1,15 @@ +{ + "category" : "Phsyche", + "classinstvars" : [ + ], + "classvars" : [ + ], + "commentStamp" : "", + "instvars" : [ + "params", + "body" ], + "name" : "PProc", + "pools" : [ + ], + "super" : "Object", + "type" : "normal" } diff --git a/src/Phsyche.package/Phsyche.class/instance/eval.in..st b/src/Phsyche.package/Phsyche.class/instance/eval.in..st index 7bbebe9..fbfa18a 100644 --- a/src/Phsyche.package/Phsyche.class/instance/eval.in..st +++ b/src/Phsyche.package/Phsyche.class/instance/eval.in..st @@ -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 ] \ 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 new file mode 100644 index 0000000..8da53a8 --- /dev/null +++ b/src/Phsyche.package/Phsyche.class/instance/evalApp.in..st @@ -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 \ 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 new file mode 100644 index 0000000..6fc30e9 --- /dev/null +++ b/src/Phsyche.package/Phsyche.class/instance/evalLambda.in..st @@ -0,0 +1,3 @@ +as yet unclassified +evalLambda: expr in: environ + ^ PProc new params: expr second; body: expr third diff --git a/src/Phsyche.package/PhsycheTest.class/instance/testLambdaProcedureExecution.st b/src/Phsyche.package/PhsycheTest.class/instance/testLambdaProcedureExecution.st new file mode 100644 index 0000000..7da50e0 --- /dev/null +++ b/src/Phsyche.package/PhsycheTest.class/instance/testLambdaProcedureExecution.st @@ -0,0 +1,3 @@ +as yet unclassified +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 new file mode 100644 index 0000000..ed52490 --- /dev/null +++ b/src/Phsyche.package/PhsycheTest.class/instance/testProcedureDefinition.st @@ -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) \ No newline at end of file diff --git a/src/Phsyche.package/PhsycheTest.class/instance/testProcedureExecution.st b/src/Phsyche.package/PhsycheTest.class/instance/testProcedureExecution.st new file mode 100644 index 0000000..dd50c94 --- /dev/null +++ b/src/Phsyche.package/PhsycheTest.class/instance/testProcedureExecution.st @@ -0,0 +1,4 @@ +as yet unclassified +testProcedureExecution + ph parseAndEval: '(define squared (lambda (x) (* x x)))'. + self assert: (ph parseAndEval: '(squared 3)') equals: 9 \ No newline at end of file