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

Extending Tiny

  • Upload
    brede

  • View
    43

  • Download
    0

Embed Size (px)

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

Citation preview

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 RPAL

let 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 | false

in

let COMP f g x = let R = f x in

R @EQ 'error' -> 'error' | g R

in

Page 3: Extending Tiny

Tiny’s Denotational Semantics in RPAL

let PIPE x f = x @EQ 'error' -> 'error' | (f x)in

let 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 RPAL

let 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 Expression

Need 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[E2] EE[E3])

Page 17: Extending Tiny

Add prefix auto-increment operator

EE[<++ 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 f, i, o) => CC[<while < ≤ I l> <; 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 Tiny

CC[<case E CC1 ... CCn >] =

EE[E] o (Check Num) oC_CC[CC1] ... C_CC[CCn] o (λ(v,s).s)

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 E

T E G

F G E

User Designer Implementer

Operational

Denotational

Attribute Grammar

E – Excellent, G – Good

F – Fair, T - Terrible

Page 28: Extending Tiny

Programming Language PrinciplesLecture 27

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

Associate ProfessorUniversity of Florida

Extending Tiny