1 / 24

CSE 131B – Compiler Construction II

CSE 131B – Compiler Construction II. Discussion 3: Project 1 – Constants, Type Aliases, Procedures 1/24/2007. Overview. Constants Type Aliases Procedures Topics/Questions you may have. Constants. CONST c = 5; (* INTEGER *) CONST d = 5.0; (* REAL *)

nevina
Download Presentation

CSE 131B – Compiler Construction II

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. CSE 131B – Compiler Construction II Discussion 3: Project 1 – Constants, Type Aliases, Procedures 1/24/2007

  2. Overview • Constants • Type Aliases • Procedures • Topics/Questions you may have

  3. Constants • CONST c = 5; (* INTEGER *) • CONST d = 5.0; (* REAL *) • CONST e = FALSE; (* BOOLEAN *) • CONST f = 5 + c; (* folding! *) • CONST g = f – 11; (* folding! *) • VAR v : ARRAY g OF REAL; (* error, since dimension is negative *)

  4. Type Aliases TYPE t1 = REAL; TYPE t2 = t1; TYPE t3 = t2; VAR x : t3; VAR y : REAL;

  5. Type Aliases • Type Aliases provide a way for users to define their own types – like C’s “ typedef ” • So, what needs to be done? • We mainly need to store 2 things: • The name of the alias • The base type it represents

  6. Type Aliases • So, let’s look at this example more closely: TYPE t1 = REAL; TYPE t2 = t1; TYPE t3 = t2; VAR x : t3; VAR y : REAL; • In this case, “x” has a alias name of “t3”, and an underlying type of “REAL”. Notice we don’t need to remember the intermediate aliases!

  7. So, How Do We Implement It? • Since type aliases are referred to by an identifier (their name), they will eventually need to get on the Symbol Table. • So, one way is to have some kind of STO for Type Aliases  TypeAliasSTO • Since it extends your base STO, it will have the Name and Type fields you need to store your information.

  8. Putting it on the Symbol Table • This method (using TypeAliasSTO) fits nicely into the given code, relying on the SymbolTable and STO hierarchy: void DoTypeDecl (String id, Type baseType) { if (m_symtab.access (id) != null) { m_nNumErrors++; m_errors.print (Formatter.toString(ErrorMsg.redeclared_id, id)); } TypeAliasSTO sto = new TypeAliasSTO (id, baseType); m_symtab.insert (sto); }

  9. Type Aliases • There are other ways to handle Type Aliases, such as making an AliasType in your Type hierarchy or overloading the access method of the symbol table to handle Type as well as STO. • Think about what you are most comfortable implementing and what can be done to make your program work before the deadline.

  10. More Type Checking • All basic types use structural equivalence • Arrays and Records use strict name equivalence • Pointers depend on what they point to • Type aliases use loose name equivalence

  11. Alias Equivalence TYPE foo = INTEGER; TYPE bar = foo; TYPE baz = bar; VAR x : INTEGER; VAR y : baz; BEGIN x := 5; (* OK *) x := y; (* OK by loose name equivalence *) RETURN 0; END.

  12. Alias/Record Equivalence TYPE r1 = POINTER TO RECORD a, b : REAL; TYPE r2 = r1; VAR x : POINTER TO RECORD a, b : REAL; VAR y : r1; VAR z : r2; x  y? NO x  z? NO y  z? YES

  13. Now, Procedures! • First, some fundamental differences from 131A: • We are writing a static translator, not an interpreter. • Once we finish the function declaration, including the body, we’re done. We don’t need to remember the code in the body, since we’ll just be spitting out assembly code (Project 2). • A procedure call will basically boil down to an assembly “call foo” type instruction, once all type checking is complete.

  14. Procedures • For Project 1, we will need to: • Check the procedure call against the procedure declaration to ensure argument symmetry. • Check the body of the procedure, type checking the same way we check statements in main. • Check the return logic of the procedure.

  15. ProcSTO • In order to do most of these checks, we will need to store some information about the function. ProcSTO is designed for this! • Things that should be stored: • The Return Type (currently only stores if there is a return type, but not the actual type). • All parameter information: • Total number of parameters • Type of each parameter, including whether VAR or non-VAR

  16. VAR vs. non-VAR • All parameters are VarSTOs, whether or not they have the keyword “VAR” in front of them. • In Oberon, the keyword “VAR” for a procedure parameter means that variable is a reference variable (instead of a value variable). • Think of passing by value versus passing by reference. • If everything was good and well in the world, the keyword “VAR” for parameters would’ve been “REF” instead.

  17. Procedure Declaration ProcDecl ::= T_PROCEDURE OptReceiver:_2 IdentDef:_3 {: ((OParser) parser).SaveLineNum (); ((OParser) parser).DoProcDecl_1 (_3, _2); :} OptFormalParams T_SEMI DeclSeq OptStmts T_END T_ID:_9 {: ((OParser) parser).DoProcDecl (_3, _9); :} ;

  18. Procedure Declaration void DoProcDecl_1 (String id, STO stoReceiverVar) { if (m_symtab.access (id) != null) { m_nNumErrors++; m_errors.print (Formatter.toString(ErrorMsg.redeclared_id, id)); } ProcSTO sto = new ProcSTO (id); if (stoReceiverVar == null) { m_symtab.insert (sto); // Inserted into outer scope } m_symtab.openScope (); // New scope opened m_symtab.setProc (sto); // Current Proc we’re in is set if (stoReceiverVar != null) { m_symtab.insert (stoReceiverVar); } }

  19. Procedure Declaration void DoProcDecl (String strBeginID, String strEndID) { if (!strBeginID.equals (strEndID)) { m_nNumErrors++; m_errors.print (Formatter.toString (ErrorMsg.improper_proc_end, strEndID)); } m_symtab.closeScope (); // Close scope (pops top scope off) m_symtab.setProc (null); // Says we’re back in “main” }

  20. Procedure Declaration PROCEDURE foo (a, b : REAL; VAR c : REAL) : BOOLEAN; VAR x : BOOLEAN; (* Local Variable *) BEGIN x := a > b; x := x & c; RETURN x; END foo; • In this example, we want to create a ProcSTO with the name “foo”, set its return type to BOOLEAN, set its param count to 3, and remember the parameters are: non-VAR REAL, non-VAR REAL, and VAR REAL). • Furthermore, we want to insert the VarSTO for a, b, c, and x into the SymTable so they are available for the body of the procedure.

  21. Procedure Call • Now that we have a ProcSTO in the SymTable, and type-checked the procedure declaration, we are ready to call it. foo(1, 2, 3); • Given the above call, there would be an error since ‘3’ is not addressable and cannot be sent to a VAR (reference) parameter.

  22. Procedure Call • So, when we call a procedure, we want to get the ProcSTO from the SymTable and check its parameters with the arguments. • Consider making a Vector of some new object (you create it how you want) that holds the parameters. When you call the function, compare the two vectors. • Important design choices!!!

  23. What to do Next! • Finish up Phase 2. • Write more test programs. • Start Phase 3. • Come to lab hours and ask questions.

  24. Topics/Questions you may have • Anything else you would like me to go over now? • Anything in particular you would like to see next week?

More Related