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
- 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?
- Meaning in terms of effect on (usually idealized) machine state
- 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