17_mar_2004

Upload: alex-solomon-a

Post on 02-Jun-2018

224 views

Category:

Documents


0 download

TRANSCRIPT

  • 8/10/2019 17_MAR_2004

    1/2

    Computer Science 332

    Compiler Construction

    Chapter 8: Intermediate CodeGeneration

    Section 8.2: Procedure Declarations

    8.2 Declarations : Single Procedure

    Each local name has a symbol-table entry

    Entry contains

    Type : .type attribute

    Relative address in procedure's activation record (e.g, Java

    inttakes four bytes, doubletakes eight) : .widthattribute

    Code-generating part of compiler uses a global variable offset

    that is reset to zero as new procedures are declared

    Code-generator proc. enter (name, type, width) creates symbol-

    table entry with this info

    Consider just declarations part of program....

    P D { offset := 0}// initializaion

    D D ;D

    D id: T { enter(id.name, T.type, offset);

    offset := offset + T.width) }

    T integer { T.type := integer; T.width := 4 }

    T double { T.type := double; T.width := 8 }

    Problem : (look at first production)

    offset := 0 code will be performed as last action, instead offirst

    Solution: "dummy" non-terminal:

    P M DM { offset := 0 }

    8.2 Declarations : Nested Procedures

    ML Example:

    let fun f(x) =

    let fun g(x, y) = x + y

    in f(g(3, 4)) end end

    Abstractly:

    P DD D, D | id : T | fun id (D ) =S

    Each procedure gets its own symbol table

    Table for "inner" declaration points to table for "outer" linked list, searched from end to beginning (recalenvironmentsfrom CS312)

  • 8/10/2019 17_MAR_2004

    2/2

    8.2 Declarations : Nested Procedures

    nil

    f:x

    g

    g:x

    y

    8.2 Declarations : Nested Procedures

    Semantic rules are a little more complicated:

    mktable (previous) creates and returns a new s.t., pointing to

    previously created one

    enter (table, name, type, offset) acts like enter, but using a

    specified table

    addwidth (table, width) records cumulative width of all

    entries in table

    enterproc (table, name, newtable) creates new entry for

    procedure namein existing table, and assigns newtable to be

    the s.t. for this new proc.

    Can do it all in one pass, if we use stacks tblptr, offset to keep

    track of symbol tables and offsets:

    8.2 Declarations : Nested ProceduresP M D { addwidth(top(tblptr), top(offset));

    pop(tblptr);pop(offset); } // done afterM's

    // actionsM { t := mktable(nil);

    push(t, tblptr);push(0, offset) }D D,D

    D fun idN (D1) =S { t := top (tblptr);

    addwidth (t, top ( offset)); pop(tblptr);pop(offset);

    enterproc( top( tblptr), id.name, t ) }

    continues ...

    8.2 Declarations : Nested Procedures

    D id: T { enter (top (tblptr), id.name, T.type, top ( offset));

    top(offset) := top( offset) + T.width) }

    N { t := mktable(top( tblptr) );

    push(t, tblptr);push(0, offset) }

    Let's try it with

    let fun f(x:int) =

    let fun g(x:int, y:int) = x + y

    in f(g(3, 4)) end end