UP | HOME

Code Generation I
Lecture 11

Table of Contents

Review

Questions about the last class?

Quiz

Prove the following conclusion

{x: 10} |- <x + 2 * 3> => 16

using the proof rules below.


-----------------
<n> => parseInt(n)


v = S.get(x)      // S is a dictionary
---------------
S |- <x> => v


S |- <e1> => v1     S |- <e2> => v2     v = eval(v1 op v2)
----------------------------------------------------------
S |- <e1 op e2> => v

Quiz Discussion

Informal semantics of SimpleC

Informal semantics

  • Similar to C
  • Eager evaluation
  • Call-by-value
  • Imperative (statements with side-effects)

Approaches to formalizing semantics

  • Operational
    • Meaning in terms of effect on (usually idealized) machine state
      • Small step: how does each step of the computation combine to form the result?
      • Big step: what is the final result of a computation?
  • Denotational
    • Meaning in terms of another language (translation).
  • Axiomatic
    • Meaning in terms of assertions about program state before and after each instruction (pre- and post-conditions).

Operational semantics

:CUSTOM_ID: operational

// abstract syntax: abstract syntax does not capture all of the concrete syntax's language restrictions.  boolean operators use and, or, and not to remove conflict with the pipe symbol.

program ::= (d | f)+                   // a program 

f       ::= def f(fs) -> t { d* st* }  // function definition
fs      ::= (x : t (, x : t)*)?        // formal arguments

d       ::= x : t;                     // a declaration

t       ::= int                        // integer type
          | bool                       // boolean type
          | string                     // string type
          | (t+) -> t                  // function type

st      ::= x = e;                     // assignment statement
          | while (e) st               // while statement
          | if (e) st else st          // if-then-else statement
          | if (e) st                  // if-then statement
          | return expr ;              // return statement
          | e;                         // expression statement
          | { st* }                    // compound statement

e       ::= f(actuals)                 // function call expression
actuals ::= (e (, e)*)?                // function args
e       ::= e op e | op e | (e)        // arithmetic expressions
op      ::= + | - | * | /              // numeric operators
op      ::= && | "||" | !              // boolean operators
op      ::= == | != | < | <= | > | >=  // relational operators
e       ::= x                          // variable usage
e       ::= n | b | S                  // literals

n       ::= [0-9]+                     // numeric values
b       ::= true | false               // boolean values
s       ::= " characters "             // string values
x       ::= [A-Za-z0-9]+               // identifiers


// environment (symbol table): this holds the type information for the symbols in scope

S
the store is a mapping of names to valuesl

S' = {name: value}S
means S' is identical to S, but has name has a new value.

v = get(name, S)
means get name's value in S.

convert(symbol) means interpret the symbol into the target language's representation, e.g., parseInt for Java for number symbols or the addition operation for the plus symbol.

eval(v1 op v2) means evaluate the resulting value of applying the operator op to values v1 and v2.

// notation

<e>
refers to e's semantic value, e.g., ASCII numbers vs. Java integers.

<e> => v
says that e's semantic value is v.

S |- <e> => v
says that, given the store S, e has value v.

S |- <st> ~> S'
says that given the store S, st produces a new store S'.


hypotheses
----------
conclusion

means that if the hypotheses are true we can conclude that the conclusion is true.


// literals: the symbols mean their equivalent mathmetical values for numbers, boolean true/false, and string.

-----------------
<n> => convert(n)

-----------------
<b> => convert(b)

-----------------
<s> => convert(s)


// operators: the symbols for arithmetic, boolean, and relationship operators each have a function type

S |- <e1> => v1     S |- <e2> => v2     v = eval(v1 op v2)
---------------------------------------------------------------------
S |- <e1 op e2> => v

S |- <e1> => v1     v = eval(op v1)
---------------------------------------------------------------------
S |- <op e1> => v



// variables: variables assignments evaluate their right-hand side at define-time and are stored and looked up in a storage context.

S' = {x: 0}S
-----------------  [declaration]
S |- <x : t;> ~> S'

v = S.get(x)
---------------    [substitution]
S |- <x> => v

S |- <e> => v     S' = {x: v}S
---------------------------------------------  [assignment]
S |- <x = e;> ~> S'


// control-flow: conditionals and iteration are statements that update state but produce no value.

S |- <e> => true     S |- st1 ~> S'
-----------------------------------  [if-true]
S |- <if e st1 else st2> ~> S'

S |- <e> => false     S |- st2 ~> S'
------------------------------------  [if-false]
S |- <if e st1 else st2> ~> S'

S |- <e> => true    S |- <st> ~> S'    S' |- <while e st> ~> S''
----------------------------------------------------------------  [while-true]
S |- <while e st> ~> S''

S |- <e> => false
----------------------  [while-false]
S |- <while e st> ~> S


// functions: functions are call-by-value, have a local storage context, and produce a return value

functions.put(f, (formals, st, e))  // store function in global function store
----------------------------------
S : <f(formals) st return e;> => S

(formals, decls, stmts) = functions.lookup(f)
S |- actual[1] => v[1]   for all actual[i] in actuals
Slocal = {formals[i]: v[i]}S   for all formals[i] in formals
Slocal' |- <stmt[i]> ~> Slocal''   for all stmt[i] in stmts
Slocal'' |- <e> => v, such that return e; is in stmts  //makes some big assumptions here
-------------------------------------------  [call]
S : <f(actuals)> => v

Author: Paul Gazzillo

Created: 2023-04-13 Thu 14:59