Language definition by interpreter

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

description

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) - PowerPoint PPT Presentation

Transcript of Language definition by interpreter

Page 1: Language definition by interpreter

Prof. Fateman CS 164 Lecture 18 1

Language definition by interpreter

Lecture 18

Page 2: Language definition by interpreter

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

Page 3: Language definition by interpreter

Prof. Fateman CS 164 Lecture 18 3

input

Typical compiler structure

Source program

AST

Intermediate form

outputLex, parse

Typecheck, cleanup

Assembly lang

Object code

Machine

Page 4: Language definition by interpreter

Prof. Fateman CS 164 Lecture 18 4

input

“Tigrun” structure

Source program

AST

Intermediate form

output

interpreter

Lex, parse

Typecheck, cleanup

What language is interpreter written in? What machine does it run on?

Page 5: Language definition by interpreter

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

Page 6: Language definition by interpreter

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

Page 7: Language definition by interpreter

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…

Page 8: Language definition by interpreter

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.

Page 9: Language definition by interpreter

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.

Page 10: Language definition by interpreter

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)))…….

Page 11: Language definition by interpreter

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

Page 12: Language definition by interpreter

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

Page 13: Language definition by interpreter

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

Page 14: Language definition by interpreter

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) …) ?

Page 15: Language definition by interpreter

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

Page 16: Language definition by interpreter

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

Page 17: Language definition by interpreter

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

Page 18: Language definition by interpreter

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!

Page 19: Language definition by interpreter

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) andthen look for the value associated with a with assoc.. (a 1) . Then takecadr of it to get 1.

Page 20: Language definition by interpreter

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 …

)

Page 21: Language definition by interpreter

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

Page 22: Language definition by interpreter

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)

Page 23: Language definition by interpreter

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.

Page 24: Language definition by interpreter

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 ty init lev readonly pos esc used ret) ;; these

guys will live on the environment stack.

(defun print-ent (p &optional (stream *standard-output*) depth) (format stream "[[ Ent:~a ]]" (Ent-name p)))

Page 25: Language definition by interpreter

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

Page 26: Language definition by interpreter

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

Page 27: Language definition by interpreter

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

Page 28: Language definition by interpreter

Prof. Fateman CS 164 Lecture 18 28

Page 29: Language definition by interpreter

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….