1 / 29

Language definition by interpreter

Language definition by interpreter. Lecture 18. Routes to defining a language. Formal mathematics Context free grammar Mathematical semantics (axioms, theorems, proofs) Rarely used (the downfall of Algol 68) Theoretical interest Informal textual CFG + natural language (Algol 60)

cleo
Download Presentation

Language definition by interpreter

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Language definition by interpreter Lecture 18 Prof. Fateman CS 164 Lecture 18

  2. Routes to defining a language • Formal mathematics • Context free grammar • Mathematical semantics (axioms, theorems, proofs) • Rarely used (the downfall of Algol 68) • Theoretical interest • Informal textual • CFG + natural language (Algol 60) • Just natural language (Tiger?) • Almost universally used • Operational • Here’s a program that does the job • Metacircular evaluator for Scheme, Lisp • Evaluator/ interpreter for Tiger Prof. Fateman CS 164 Lecture 18

  3. Typical compiler structure input Source program Machine output Lex, parse AST Object code Typecheck, cleanup Intermediate form Assembly lang Prof. Fateman CS 164 Lecture 18

  4. “Tigrun” structure Source program input Lex, parse AST Typecheck, cleanup output Intermediate form interpreter What language is interpreter written in? What machine does it run on? Prof. Fateman CS 164 Lecture 18

  5. Interpreter structure: advantages interpreter • Interpreter in a higher level language: source language derives semantics from interpreter code and the semantics of the language of the interpreter (e.g. Lisp). • What does EACH STATEMENT MEAN? • Exhaustive case analysis • What are the boundaries of legal semantics? • What exactly is the model of scope, etc.. Prof. Fateman CS 164 Lecture 18

  6. Interpreter structure: more advantages interpreter • Prototyping / debugging easier • Portable intermediate form • (Byte code ) intermediate form may be compact • Security may be more easily enforced Prof. Fateman CS 164 Lecture 18

  7. Interpreter structure: disadvantages interpreter • Typically unable to reach full machine speed • Difficult to transcend the limits of the underlying language implementation (not full access to machine) • Code depends on presence of infrastructure (all of Lisp??) • (if meta-circular) bootstrapping… Prof. Fateman CS 164 Lecture 18

  8. An interpreter compromise (e.g. Java VM) interpreter • “Compile” to a hypothetical byte-code stack machine appropriate for Java (etc), easily simulated on most real machines • Implement this virtual byte-code stack machine on all real machines • When speed is an issue, try Just In Time compiling; convert sections of code to machine language for a specific machine. Prof. Fateman CS 164 Lecture 18

  9. Interpreter to Compiler is a small step • Modest modification of an interpreter can become a compiler. • For example: • Interpreter: To evaluate a sequence {s1, s2}, evaluate s1 then evaluate s2, returning the last of these. • Compiler: To compile a sequence {s1, s2}, compile s1 then compile s2, returning the concatenation of the code for s1 and the code for s2. • Interpreter: To evaluate a sum (+ A B) evaluate A, evaluate B and add. • Compiler: To compile a sum, (+ A B) compile A, compile B, concatenate results, compile + to “add the results of the two previous sections of code”. • Program structure is a walk over the intermediate code. Prof. Fateman CS 164 Lecture 18

  10. AST for merge.tig ;;; -*- Mode: Lisp; Syntax: Common-Lisp; package: tiger -*- (in-package :tiger) (defparameter merge-ast '(LetExp (1 . 3) (DecList (TypeDec (3 . 9) any (FieldList (FieldDescriptor (3 . 16) any int))) (VarDec (4 . 4) buffer nil (CallExp (4 . 22) (getchar (4 . 22)) (ExpList))) (FunctionDec (6 . 16) readint (ExpList (IdType (6 . 20) any any)) (int (6 . 32)) (LetExp (7 . 4) (DecList (VarDec (7 . 8) i nil (IntExp (7 . 15) 0)) (FunctionDec (8 . 21) isdigit (ExpList (IdType (8 . 23) s string)) ;Explist or FieldList? (int (8 . 39)) (IfExp (9 . 12) (OpExp (9 . 12) (>= (9 . 12)) (CallExp (9 . 7) (ord (9 . 7)) (ExpList (SimpleVar (9 . 9) s))) (CallExp (9 . 15) (ord (9 . 15)) (ExpList (StringExp (9 . 19) "0")))) (OpExp (9 . 31) (<= (9 . 31)) (CallExp (9 . 26) (ord (9 . 26)) (ExpList (SimpleVar (9 . 28) s))); which line/col#? (CallExp (9 . 34) (ord (9 . 34)) (ExpList (StringExp (9 . 38) "9")))) (IntExp (9 . 12) 0)))……. Prof. Fateman CS 164 Lecture 18

  11. Intermediate form (cleanup) for merge.ast ;;; -*- Mode: Lisp; Syntax: Common-Lisp; package: tiger -*- (in-package :tiger) (defparameter merge-cleaned ;; the line numbers removed; other excess fluff removed. '(LetExp (DecList (TypeDec any (FieldList (FieldDescriptor any int))) (VarDec buffer nil (getchar)) (FunctionDec readint (ExpList (IdType any any)) (int);; ? (int) or int? (LetExp (DecList (VarDec i nil 0) (FunctionDec isdigit (ExpList (IdType s string)) (int) (IfExp (>= (ord s) (ord "0")) (<= (ord s) (ord "9")) 0)) (FunctionDec skipto (ExpList) nil (WhileExp (IfExp (= buffer " ") 1 (= buffer " ")) (AssignExp buffer (getchar))))) (ExpList (skipto) (AssignExp (FieldVar any any) (isdigit buffer)) (WhileExp (isdigit buffer) (ExpList (AssignExp i (- (+ (* i 10) (ord buffer)) (ord "0"))) (AssignExp buffer (getchar)))) Prof. Fateman CS 164 Lecture 18

  12. Start of the interpreter (defun tig-interp (x env) ; x= intermediate code, env=environment of bindings ;; first deal with interp of trivial or error cases which might occur. (cond ((null x) nil) ((eq x 'VOID) 'VOID) ;;or (error "attempt to evaluate VOID") ((symbolp x) (get-var x env)) ((atom x) x);; integers and strings are atoms. (t (tig-interp-list x env)))) ;; the real business is in lisp lists Prof. Fateman CS 164 Lecture 18

  13. Start of the interpreter: tig-interp-list (defun tig-interp-list (x env) ; environment of bindings (case (first x) (ExpList;; a sequence of expressions. (last1 (mapcar #'(lambda(r)(tig-interp r env)) (cdr x)))) (AssignExp (set-var (elt x 1)(elt x 2) env)) (IfExp (tig-interp-if (elt x 1)(elt x 2) (elt x 3) env)) ;; see next slide (LetExp (tig-interp-let (elt x 1)(elt x 2) env)) (WhileExp (tig-interp-while (elt x 1)(elt x 2) env)) (ArrayExp (make-array (tig-interp (elt x 2) env) ; size :initial-element (tig-interp (elt x 3) env))) (RecordExp (tig-interp-rec x env)) (FieldVar (cadr (assoc (elt x 2) (tig-interp (elt x 1) env)))) (BreakExp (throw 'tig-break nil)) (SubscriptVar (aref (get-var (elt x 1) env); get the array (tig-interp (elt x 2)env))) (ForExp (tig-interp-for (elt x 1)(elt x 2) (elt x 3)(elt x 4) env)) (t;; a CallExp ;; get the procedure ;; evaluate the arguments (tig-call (get-fun (car x) env) (mapcar #'(lambda(p) (tig-interp p env)) (cdr x)) env )))))) Prof. Fateman CS 164 Lecture 18

  14. if (defun tig-interp-if (a b c env) (if (equal 1 (tig-interp a env)) (tig-interp b env) (tig-interp c env))) What if in interp… we did (tig-interp-if (tig-interp (elt x 1) env) (tig-interp (elt x 2) …) This would be quite wrong (defun tig-interp-if (a b c env) (if (equal 1 a) b c) What if in interp… we did (if (tig-interp (elt x 1) env) (tig-interp (elt x 2) …) ? Prof. Fateman CS 164 Lecture 18

  15. Loops: while (defun tig-interp-while (test body env) (catch 'tig-break ;; watch out for breaks in body ;see interp (loop while (not (equal (tig-interp test env) 0)) do (tig-interp body env) ‘VOID ;;why? )) ;;semantics translates conveniently into the lisp loop while… ;; but we could write this out using block/ if/ goto/ … (block foo label1 (if (equal (tig-interp test env) 0) (return-from ‘foo ‘VOID)) (tig-interp body env) (go label1)) Or anything else with the same semantics Prof. Fateman CS 164 Lecture 18

  16. loops: for (defun tig-interp-for (index low hi body env) ;; put index into the environment; initialize it to low. (let ((start (tig-interp low env))) (setf env (extend-env1 index start env)) ;; key step. Introduce new variable (catch 'tig-break ;catch any break statements here (loop while (<= start (tig-interp hi env));; loop like Lisp loop! do (tig-interp body env) (set-var index (incf start) env)); another key step..increment start and index by 1 ‘VOID)));; note what happens to env on exit Prof. Fateman CS 164 Lecture 18

  17. Revisit the main interpreter (defun tig-interp-list (x env) ; environment of bindings (case (first x) (ExpList;; a sequence of expressions. (last1 (mapcar #'(lambda(r)(tig-interp r env)) (cdr x)))) ;; self explanatory (AssignExp (set-var (elt x 1)(elt x 2) env)) (IfExp (tig-interp-if (elt x 1)(elt x 2) (elt x 3) env)) (LetExp (tig-interp-let (elt x 1)(elt x 2) env)) (WhileExp (tig-interp-while (elt x 1)(elt x 2) env)) (ArrayExp (make-array (tig-interp (elt x 2) env) ; size :initial-element (tig-interp (elt x 3) env))) (RecordExp (tig-interp-rec x env)) (FieldVar (cadr (assoc (elt x 2) (tig-interp (elt x 1) env)))) (BreakExp (throw 'tig-break nil)) (SubscriptVar (aref (get-var (elt x 1) env); get the array (tig-interp (elt x 2)env))) (ForExp (tig-interp-for (elt x 1)(elt x 2) (elt x 3)(elt x 4) env)) (t;; a CallExp ;; get the procedure ;; evaluate the arguments (tig-call (get-fun (car x) env) (mapcar #'(lambda(p) (tig-interp p env)) (cdr x)) env )))))) Prof. Fateman CS 164 Lecture 18

  18. Construct a record (defun tig-interp-rec(x env) ;; This constructs a record. Cheap trick: ;; make an association list with ;; the appropriate name-value pairs. ;; Recall, we've already type-checked this guy.. (let* ((actualnames (mapcar #'(lambda(z)(elt z 1))(cddr x))) (actualvals (mapcar #'(lambda(z)(tig-interp (elt z 2) env)) (cddr x))) (res (mapcar #'list actualnames actualvals))) res)) sometype{a=1,b=2} /*create a record of type “sometype” with two fields in it AST = (RecordExp (1 . 8) (sometype (1 . 8)) (ExpList (FieldId (1 . 10) a (IntExp (1 . 12) 1)) (FieldId (1 . 14) b (IntExp (1 . 16) 2)))) Cleans up to (RecordExp sometype (FieldId a 1) (FieldId b 2)) In lisp, actualsnames is (a b), actualvals is (1 2), result is ((a 1) (b 2)). THIS IS THE RECORD! Prof. Fateman CS 164 Lecture 18

  19. Getting a value from a field (defun tig-interp-list (x env) (case (first x) …. (FieldVar (cadr (assoc (elt x 2) (tig-interp (elt x 1) env)))) ….)) If you see (FieldVar x a) then get the value for x, say ((a 1)(b 2) and then look for the value associated with a with assoc.. (a 1) . Then take cadr of it to get 1. Prof. Fateman CS 164 Lecture 18

  20. Revisit the main interpreter (defun tig-interp-list (x env) ; environment of bindings (case (first x) … (AssignExp (set-var (elt x 1)(elt x 2) env)) ;; what does set-var do … ) Prof. Fateman CS 164 Lecture 18

  21. Set the value of a “variable” set-var (defun set-var (name val env) ;; Change the value associated with the name in the environment. ;; In this case the name may be complex: an l-value. (cond ((symbolp name) (let ((r (assoc name env))) ;; look for a pair ( …. (r . Val) ….) on env (if (null r)(error "can't set unbound tiger var ~s" name) (setf (cdr r) (tig-interp val env))))) ((eq (car name) 'SubscriptVar) (setf (aref (get-var (elt name 1) env); get the array (tig-interp (elt name 2)env)); the index ;;; (setf (aref xxx) (tig-interp val env) (tig-interp val env))) ((eq (car name) 'FieldVar) (let ((therecord (assoc (elt name 2) (get-var (elt name 1) env) ))) (setf (cadr therecord) (tig-interp val env)))) ;; plop something down in the record.. ((a 1)(b 2)) (t;; no other option for set-var (error "unimplemented setting of ~s" name)))) Prof. Fateman CS 164 Lecture 18

  22. Set the value of a “variable” set-var dealing with l-values… …. Works for x.a :=34 x[9]:=34 (AssignExp (Fieldvar x a) 34). (AssignExp (SubscriptVar x 9) 34) What about z.x.a := 34 or x[9].a :=34 (AssignExp (Fieldvar z (Fieldvar x a)) 34). (AssignExp (Fieldvar (SubscriptVar x 9) a )34) Or x.a[9]:=34 ? (AssignExp (SubscriptVar (FieldVar x a) 9) 34) Or x[3][9]:=34 ? (AssignExp (SubscriptVar (SubscriptVar x 3) 9) 34) ;; note: for this last expression to make sense, let type ar1 = array of int type ar2 = array of ar1 var x:ar2:= ar2[10] of (ar1[4] of 0) Prof. Fateman CS 164 Lecture 18

  23. Get the variable’s value (also used by set-var) (defun get-var (name env) ;; find the value associated with the name in the environment (cond ((symbolp name) (let ((r (assoc name env))) (cond ((null r)(error "unbound tiger var ~s" name)) (t (cdr r))))) (t;; could be subscript or fieldvar (tig-interp name env) ))) ;; note that lvalues are used only by AssignExp, and evaluation there stops one level above the call to get-var. Prof. Fateman CS 164 Lecture 18

  24. Get the function associated with a name (defun get-fun (name env) ;; find the function associated with the name in the environment (let ((r (assoc name env))) (cond ((null r)(error "unbound tiger fun ~s" name)) ((Ent-p (cdr r)) (cdr r)) ; (Ent-body (cdr r)) holds the function (t (error "accessing var as function ~s" name))))) (defstruct (Ent (:print-function print-ent)) name params body env kind def tyinit lev readonly pos esc usedret) ;; these guys will live on the environment stack. (defun print-ent (p &optional (stream *standard-output*) depth) (format stream "[[ Ent:~a ]]" (Ent-name p))) Prof. Fateman CS 164 Lecture 18

  25. What is the environment, initially? (defparameter init-env ;; for built-in functions we don't give the :params list because ;; we don't check it and bind vars etc. ;; we have the count of params in (built-in fun count) ;; each Ent has an environment, :env, but it is nil ;; we have bunches of other fields we don't use here. (list (cons 'print (make-Ent :name 'print :body `(built-in ,#'princ 1);one arg :ret 'VOID)) (cons 'flush (make-Ent :name 'flush :body `(built-in ,#'finish-output 0) :ret 'VOID)) (cons 'getchar (make-Ent :name 'getchar :body `(built-in ,#'(lambda()(coerce (vector (read-char))'string )) 0) :ret 'string )) (cons 'ord (make-Ent :name 'ord :body `(built-in ,#'(lambda(s)(if (or (not (stringp s))(string= s "")) -1 (char-code (elt s 0)))) 1) :ret 'int)) Prof. Fateman CS 164 Lecture 18

  26. What is the environment, initially? (defparameter init-env … continued (cons 'not (make-Ent :name 'not :body `(built-in ,#'(lambda(i)(if (= i 0) 1 0)) 1) :ret 'int)) (cons 'exit (make-Ent :name 'exit :body `(built-in ,#'(lambda(i)(error "termination with code ~s" i))1) :ret 'VOID)) (cons '+ (make-Ent :name '+ :body `(built-in ,#'+ 2) :ret 'int)) (cons '* (make-Ent :name '* :body `(built-in ,#'* 2) :ret 'int)) (cons '/ (make-Ent :name '/ :body `(built-in ,#'truncate 2) :ret 'int)) (cons '- (make-Ent :name '- :body `(built-in ,#'- 2) :ret 'int)) (cons '> (make-Ent :name '> :body `(built-in ,#'tig> 2) :ret 'int)) (cons '>= (make-Ent :name '>= :body `(built-in ,#'tig>= 2) :ret 'int)) (cons '< (make-Ent :name '< :body `(built-in ,#'tig< 2) :ret 'int)) (cons '<= (make-Ent :name '<= :body `(built-in ,#'tig<= 2) :ret 'int)) (cons '<> (make-Ent :name '<> :body `(built-in ,#'tig<> 2) :ret 'int)) (cons '= (make-Ent :name '= :body `(built-in ,#'tig= 2) :ret 'int)) (cons nil nil);; hm should be read-only. tig-interp nil should be nil regardless (cons 'VOID 'VOID);; ditto. )) Prof. Fateman CS 164 Lecture 18

  27. What are these little functions like tig<= ? (defun tig>(r s)(tig-truth (typecase r (string (string> r s))(number(> r s))))) (defun tig<(r s)(tig-truth (typecase r (string (string< r s))(number(< r s))))) (defun tig>=(r s)(tig-truth (typecase r (string (string>= r s))(number(>= r s))))) (defun tig<=(r s)(tig-truth (typecase r (string (string<= r s))(number(<= r s))))) (defun tig<>(r s)(tig-truth (not (equal r s)))) (defun tig=(r s)(tig-truth (equal r s))) (defun tig-truth (r)(if (null r) 0 1));convert lisp boolean to tiger boolean )) Prof. Fateman CS 164 Lecture 18

  28. Prof. Fateman CS 164 Lecture 18

  29. What else is in env and how does it get there • This is the meat of the interpreter and requires some real intellectual effort • It also explains completely dynamic and static scope. • ….to be continued…. Prof. Fateman CS 164 Lecture 18

More Related