controle
1 Motivatie
• In de evaluatoren tot nu toe: volgorde waarin de operands van een functie-applicatie worden
geëvalueerd hangt af van de implementatie van cons
o Cons is primitief dus we zijn afhankelijk van iemand anders zijn implementatie van
cons
• Met deze evaluator wordt de volgorde waarin operands geëvalueerd worden veel explicieter.
o Verder ook duidelijk hoe staartrecursie-optimalisatie werkt
• Geïmplementeerd als registermachine
o Evaluator voor Scheme in registermachinetaal, bovenop simulator voor
registermachinetaal geschreven in Scheme, bovenop DrRacket
2 Definitie van registermachine voor ec-eval
(define eceval
(make-machine
'(exp env val proc argl continue unev)
Lijst van benodigde registers
eceval-operations
Hulpprocedures van de meta-circulaire evaluator zijn beschikbaar als
primitieven
'(
read-eval-print-loop
…
registermachinecode
)))
• exp bevat de te evalueren uitdrukking
• env bevat de omgeving waarbinnen de evaluatie gebeurt
o pointer naar de omgeving
• val bevat de uit evaluatie resulterende waarde
• continue ondersteunt verschillende sprongen naar zelfde subroutine
o enorm belangrijk voor implementatie
• proc bevat het procedure-object waarnaartoe een operator evalueert
• unev bevat een lijst van nog te evalueren expressies (bv. operanden)
• argl bevat de waarden waarnaartoe een lijst van operanden evalueert
1
, 3 Implementatie van read-eval-print lus
(define (get-global-environment)
the-global-environment)
read-eval-print-loop
(perform (op initialize-stack))
Nieuwe aanroep v/d REPL --> stack opnieuw initialiseren waardoor
brol van vorige uitvoeringen weg is.
(perform (op prompt-for-input) (const ";;; EC-Eval input:"))
Vragen naar invoer gebruiker
(assign exp (op read))
Exp = wat de gebruiker ingeeft
(assign env (op get-global-environment))
Env terug op globale omgeving zetten
(assign continue (label print-result))
Cont begint op subroutine print-result
(goto (label eval-dispatch))
Sprong naar subroutine eval-dispatch
print-result
(perform (op announce-output) (const ";;; EC-Eval value:"))
(perform (op user-print) (reg val))
Uitprinten van resultaat = printen inhoud val register
(goto (label read-eval-print-loop))
Nieuwe oproep van REPl nadat resultaat geprint werd
unknown-expression-type
(assign val (const unknown-expression-type-error))
(goto (label signal-error))
unknown-procedure-type
(restore continue)
Zie sprong vanuit apply-dispatch
(assign val (const unknown-procedure-type-error))
(goto (label signal-error))
signal-error
algemene subroutine om fout mee te melden
(perform (op user-print) (reg val))
Print het soort fout --> staat in register val
(goto (label read-eval-print-loop))
Nieuwe oproep REPL
4 Syntactische analyse
eval-dispatch
subroutine die aan de hand van het soort expressie doorverwijst naar
gespecialiseerde subroutines.
(test (op self-evaluating?) (reg exp))
(branch (label ev-self-eval))
(test (op variable?) (reg exp))
(branch (label ev-variable))
(test (op quoted?) (reg exp))
2