Extending Tiny

28
Programming Language Principles Lecture 27 Prepared by Manuel E. Bermúdez, Ph.D. Associate Professor University of Florida Extending Tiny

description

Extending Tiny. Programming Language Principles Lecture 27. Prepared by Manuel E. Bermúdez, Ph.D. Associate Professor University of Florida. Tiny’s Denotational Semantics in RPAL. let EQ x y = Istruthvalue x & Istruthvalue y -> (x & y) or (not x & not y) - PowerPoint PPT Presentation

Transcript of Extending Tiny

Page 1: Extending Tiny

Programming Language PrinciplesLecture 27

Prepared byManuel E. Bermúdez, Ph.D.

Associate ProfessorUniversity of Florida

Extending Tiny

Page 2: Extending Tiny

Tiny’s Denotational Semantics in RPALlet EQ x y = Istruthvalue x & Istruthvalue y -> (x & y) or (not x & not y) | Isstring x & Isstring y or Isinteger x & Isinteger y

-> x eq y | falseinlet COMP f g x = let R = f x in R @EQ 'error' -> 'error' | g Rin

Page 3: Extending Tiny

Tiny’s Denotational Semantics in RPAL

let PIPE x f = x @EQ 'error' -> 'error' | (f x)inlet Return v s = (v,s)in

let Check Dom (v,s) = Dom eq 'Num' -> Isinteger v -> (v,s) | 'error'

| Dom eq 'Bool' -> Istruthvalue v -> (v,s) | 'error'

| 'error'in

Page 4: Extending Tiny

Tiny’s Denotational Semantics in RPAL

let Dummy s = sinlet Cond F1 F2 (v,s) = s @PIPE (v -> F1 | F2)inlet Replace m i v x = x @EQ i -> v | m xinlet Head i = i 1inlet Tail T = rtail T (Order T)where rec rtail T N =

N eq 1 -> nil | (rtail T (N-1) aug (T N))in

Page 5: Extending Tiny

Tiny’s Denotational Semantics in RPALlet rec EE E (m,i,o) = Isinteger E -> Return E (m,i,o) | Isstring E -> ( E eq 'true' -> Return true (m,i,o) | E eq 'false' -> Return false (m,i,o) | E eq 'read' -> Null i -> 'error' | (Head i,(m,Tail i,o)) | (let R = m E in R @EQ 'undef' -> 'error' | (R,(m,i,o)) ) )

Page 6: Extending Tiny

Tiny’s Denotational Semantics in RPAL

| Istuple E -> ( (E 1) @EQ 'not' -> (m,i,o) @PIPE EE(E 2)

@PIPE (Check 'Bool') @PIPE (fn(v,s).(not v,s))

Page 7: Extending Tiny

Tiny’s Denotational Semantics in RPAL

| (E 1) @EQ '<=' -> (m,i,o) @PIPE EE(E 2) @PIPE (Check 'Num') @PIPE (fn(v1,s1). s1

@PIPE EE(E 3) @PIPE (Check 'Num') @PIPE (fn(v2,s2).(v1 le v2,s2)) )

Page 8: Extending Tiny

Tiny’s Denotational Semantics in RPAL

| (E 1) @EQ '+' -> (m,i,o) @PIPE EE(E 2)

@PIPE (Check 'Num') @PIPE (fn(v1,s1). S1

@PIPE EE(E 3) @PIPE (Check 'Num') @PIPE (fn(v2,s2).(v1 + v2,s2)) ) | 'error' // not 'not', '<=', '+' )| 'error' // not a tuplein

Page 9: Extending Tiny

Tiny’s Denotational Semantics in RPALlet rec CC C s = not (Istuple C) -> 'error' |(C 1) @EQ ':=' -> s @PIPE EE (C 3) @PIPE (fn(v,s).

(Replace (s 1) (C 2) v,s 2,s 3)) |(C 1) @EQ 'print' -> s @PIPE EE (C 2) @PIPE (fn(v,s).

(s 1,s 2,s 3 aug v))

Page 10: Extending Tiny

Tiny’s Denotational Semantics in RPAL

| (C 1) @EQ 'if' -> s @PIPE EE (C 2) @PIPE (Check 'Bool') @PIPE (Cond (CC(C 3)) (CC(C 4)))

| (C 1) @EQ 'while' -> s @PIPE EE (C 2) @PIPE (Check 'Bool')

@PIPE Cond (CC(';',C 3,C)) Dummy

Page 11: Extending Tiny

Tiny’s Denotational Semantics in RPAL |(C 1) @EQ ';' -> s @PIPE CC (C 2) @PIPE CC (C 3)

| 'error' // not ':=', 'if', ...inlet PP P = not (Istuple P) -> (fn i. 'error') | not ((P 1) @EQ 'program') -> (fn i. 'error') | ((fn i. CC (P 2) ((fn i.'undef'),i,nil) //start state! ) @COMP (fn s.(s 3)) )in

Page 12: Extending Tiny

Tiny’s Denotational Semantics in RPAL

Print ( PP ('program', // test program (';', (':=', 'x',3),

('print', 'x') ) ) (nil aug 3) // the input

)

Whew ! Now, RUN IT !!

Page 13: Extending Tiny

Tiny’s Denotational Semantics in RPAL

• Executable semantic specification of Tiny.• Add a parser, and voilà ... Tiny is

implemented !• Could even write the parser in RPAL ... • Inefficient, but who cares ...• 'error' (and others) should probably be '<error>', so we allow those as variable names in Tiny.

• Subject to change:– Alter order of evaluation of operands.– Allow comparison of booleans.

Page 14: Extending Tiny

Extending Tiny• First, add more comparison operators, and lots of

arithmetic operators (easy). Example:

EE[<- E1 E2>] = EE[E1]o (Check Num)o (λ(v1,s1). s1 => EE[E2]

=> (Check Num)=> (λ(v2,s2).(v1 - v2,s2)

)

Page 15: Extending Tiny

Extending Tiny• Let’s add the '=' comparison operator.

Allow for Num and Bool. This allows type mixing !

EE[<= E1 E2>] = EE[E1]o (Check Num)o (λ(v1,s1). s1 => EE[E2]

=> (Check Num)=> (λ(v2,s2).(v1 eq v2,s2)

)

Page 16: Extending Tiny

Add Conditional ExpressionNeed a new auxiliary function: Econd.ECond: (State → Val x State) → (State → Val x State) → (Val x State) → (Val x State) Econd = λEF1. λEF2. λ(v,s). s => (v → EF1 | EF2)

EE[<cond E1 E2 E3>] = EE[E1] o (Check Bool)

o (Econd EE[E1] EE[E2])

Page 17: Extending Tiny

Add prefix auto-increment operatorEE[<++ I>] = | EE[I] o (Check Num) (λ(v,(m,i,o)). v eq → error | (v+1, (Replace m I (v+1)), i, o) )

For postfix (n++), change this to v !

Page 18: Extending Tiny

Adding the one-armed ‘if’ to Tiny

CC[<if E C>] = EE[E] o (Check Bool)

o (Cond CC[C] Dummy)

Of course, for most of these, the syntactic domains need to be updated.

Page 19: Extending Tiny

Adding a ‘repeat’ statement to Tiny

CC[<repeat C E>] = CC[C] o EE[E] o (Check Bool) o

(Cond Dummy (CC[<repeat C E>]))

or better yet,

CC[<repeat C E>] =CC[C] o CC[<while <not E> C>]

Page 20: Extending Tiny

Adding a read statement to Tiny

CC[<read I>] = | λ(m,i,o). Null i → error

| (Replace m I (Head i), Tail i, o)

Would need to remove the ‘read’ expression.

Page 21: Extending Tiny

Adding the Pascal ‘for’ loop to Tiny

CC[<for I F L C>] = EE[L] o (Check Num) o(λ(l,s). S => EE[F] => (Check Num)

=> (λ(f,(m,i,o)). (Replace m I l, i, o) => CC[<while < ≤ I f> <; C <:= I <+ I 1>>> ] ) ) o (λ(m,i,o). (Replace m I , i, o))

Yuck. Can’t enforce lots of rules.

Page 22: Extending Tiny

Adding the C ‘for’ loop to Tiny

CC[<for F E I C>] =CC[F] o CC[<while E <; C I>>]

or CC[<; F <while E <; C I>>]

Remarkably simple, eh ? Of course, Tiny has no continue statement

to get in the way.We assume default values have been added

for any missing parts, e.g. true for E.

Page 23: Extending Tiny

Adding a ‘case’ statement to TinyCC[<case E CC1 ... CCn >] =

EE[E] o (Check Num) oC_CC[CC1] ... C_CC[CCn]

Need a new syntactic domain, for case-clauses:C_C = <c_c n C>

Also, a new semantic function to process them:C_CC: C_C → (Val x State) → (Val x State)

Page 24: Extending Tiny

Adding a ‘case’ statement to Tiny

To process one case clause:

C_CC[<c_c n C>] = λ(v,s). v eq → (v,s)

| v ne n → (v,s) | ( , s => CC[C])

Aborts all subsequent case clauses.To process them all, change this to v !

Page 25: Extending Tiny

Remarks on Denotational Semantics

• Exercise: implement these in RPAL ! (see ‘medium’ on website)

• Can this be done for “real” programming languages ? Yes, but ...

• We now have three formalisms for specifying the semantics of programming languages:– Operational (RPAL)– Attribute grammars (Tiny)– Denotational (Tiny)

Page 26: Extending Tiny

Remarks on Semantic Specifications

• Remember, parsing was *easy*

• Reason: one formalism (CFG’s) good for everyone:– Language user.– Language implementer.– Language designer.

• Not so in the world of semantics.

Page 27: Extending Tiny

Remarks on Semantic Specifications

F F ET E GF G E

User Designer ImplementerOperational

DenotationalAttribute Grammar

E – Excellent, G – GoodF – Fair, T - Terrible

Page 28: Extending Tiny

Programming Language PrinciplesLecture 27

Prepared byManuel E. Bermúdez, Ph.D.

Associate ProfessorUniversity of Florida

Extending Tiny