COP 3402 meeting -*- Outline -*- * Code Generation Demo ** context ------------------------------------------ CONTEXT VM changes (from the SRM) // machine_types.h // type of 32 bit integers typedef int int_type; // type of 32 bit floats typedef float float_type; typedef float word_type; Instruction changes: Floating point versions of instructions: FADD, FSUB, FMUL, FDIV BFEQ, BFGEZ, BFGTZ, BFLEZ, BFLTZ, FLW, FSW, PFLT, RFLT FMUL and FDIV are 3 register operations FDIV does not do a modulo calculation Conversion instructions: CVT -- converts int to a float RND =- rounds float to an int FLOAT Language differences from PL/0: - no constant declarations, only vars - no procedures - { ... } is a scope ::= ::= { } ::= float ; | bool ; ::= '{' { } '}' | = ; | if ( ) | read ; | write ; ------------------------------------------ Q: If the FLOAT language only has floats and bools, does it make sense to have a round expression? No, need to also have integer data for that (that would be future work for FLOAT) ** Lexical grammar changes ------------------------------------------ LEXICAL GRAMMAR FOR FLOAT LITERALS DIGIT [0-9] SIGN (-|\+) EXPONENTMARKER [eE] NUMBER {NUMBERPART}{EXPONENTPART}? MANTISSA [.]({DIGIT})* NUMBERPART {SIGN}?{DIGIT}+{MANTISSA}? EXPONENTPART {EXPONENTMARKER}{SIGN}?{DIGIT}+ ------------------------------------------ here NUMBER is the token recognized ** Enhanced ASTs as an IR Recall that IR = Intermediate Representation Q: What changes to the ASTs are needed for new syntax and for code generation? - for new syntax: VDs in begin ASTs - for code generation: need lexical address info. for id uses ------------------------------------------ ENHANCED ASTS AS AN IR // changes in // file ast.h #include "type_exp.h" // (possibly signed) floats typedef struct { file_location *file_loc; const char *text; type_exp_e type; word_type value; } number_t; // expr ::= expr op expr // op ::= == | != | < | <= | + | - | * | / typedef struct { file_location *file_loc; type_exp_e type; struct expr_s *expr1; token_t op; struct expr_s *expr2; } binary_op_expr_t; // ... ------------------------------------------ And also changing the ASTs to have ident ASTs with identifier use information. *** identifier uses ------------------------------------------ IDENTIFIER USES IN ASTs // E ::= x typedef struct { // name of a constant or variable const char *name; // set during static analysis, // includes info for lexical addr id_use *idu; } ident_t; // S ::= read x typedef struct { AST *ident; } read_t; // S ::= assign x E typedef struct { AST *ident; AST *exp; } assign_t; ------------------------------------------ Note that an in the AST is now an full AST, with the id_use information ------------------------------------------ ID_USE STRUCTURES typedef struct { id_attrs *attrs; unsigned int levelsOutward; } id_use; ------------------------------------------ Q: Why track attributes in the AST? As an IR, these are needed for: type checking (variable type), and generating code (type and lexical address) (Also: the symbol table isn't around in later passes) *** id attributes (id_attrs) ------------------------------------------ ID ATTRIBUTES // attributes of idents typedef struct { file_location file_loc; var_type vt; // type // offset from beginning of scope unsigned int loc_offset; } id_attrs; // where: typedef enum {float_t, bool_t} var_type; ------------------------------------------ these are both in the file id_attrs.h ** scopes and symbol tables Q: Where do nested scopes happen in this language? In begin statements *** scope checking begin statements ------------------------------------------ void scope_check_beginStmt(AST *stmt) { symtab_enter_scope(); // <******* scope_check_varDecls( stmt->data.begin_stmt.vds); AST_list stmts = stmt->data.begin_stmt.stmts; while (!ast_list_is_empty(stmts)) { scope_check_stmt( ast_list_first(stmts)); stmts = ast_list_rest(stmts); } symtab_leave_scope(); // <******** } ------------------------------------------ ** Writing a Code Generator ------------------------------------------ GENERATING CODE Done in the file gen_code.c - Functions arranged to walk the ASTs - All return a code_seq Useful files: ast.h id_attrs.h id_use.h code.h ------------------------------------------ These are all provided files Q: What does a function in gen_code get as an argument? The AST (IR tree structure) for that nonterminal ------------------------------------------ STEPS FOR CODE GENERATION 1. start with the base cases 2. Write simplest tests possible 3. Design code sequences for the nonterminals involved 4. Write code for each node of the AST 5. Test it: a. check the output machine code b. check the VM's execution ------------------------------------------ ... i.e., cases with no recursive occurrences of the nodes ... and check the source programs parse ... record code sequence designs in comments ** Examples of generating code *** expressions **** design ------------------------------------------ EXPRESSIONS What are the base cases? A very simple test: What code sequence do we want? ------------------------------------------ ... numbers, identifiers Q: And what are the inductive cases? looking at the ASTs: - binary expressions, and - logical negation (not) ... use a file vmtest0.flt: # $Id$ float x; x = 1; ... [allocate space for x] [get fp for x on top of stack] [get value of 1 on top of stack] STO 0 Q: What instruction can we use to allocate space for x? INC 1 Q: How should we get the fp for x on top of the stack? PBP Q: How should we get the value of 1 on top of the stack LIT 1 So, that is our code sequence: INC 1 PBP 0 LIT 1 STO 0 Q: Anything else we are missing in this code? Need a HLT instruction! **** coding it ------------------------------------------ GENERATING CODE Where does execution start? What is the AST for our program? Where do we generate those code sequences? Let's write it! ------------------------------------------ ... in gen_code_program ... [program] / \ [var_decl] [assign] / \ [ident] [number] ... following the grammar we need to write code for: gen_code_program (for the HLT) gen_code_varDecls and gen_code_varDecl (for INC) gen_code_assignStmt (for the fp, LIT, STO) Write the code for gen_code_program, then gen_code_varDecls (a loop calling gen_code_varDecl), then gen_code_varDecl Then test it, get an error as assignment is not yet implemented So comment out the call to gen_code_stmt (or make a simpler test case that just declares a variable). Test again, should get output of 8 1 ; INC 1 for the var decl 13 0 ; HLT Now code gen_code_stmt (to dispatch to) gen_code_assignStmt Test that, then do gen_code_expr (to dispatch to) gen_code_number_expr Test by running make vmtest0.myvo **** more expression cases Try variable uses, like: # vmtest1.flt float x, y; x = y; **** binary expressions E.g., # vmtest2.flt float x; x = 2 + 3; vary this with different operators ** statements Q: Any more base cases for statments in FLOAT? No, but skip in PL/0 is a base case Q: What are the inductive cases? see below: ***** begin-statements without var decls (actually just concatenation) ***** read and write statements careful testing read! (input is an issue in testing) ***** if statements ** nested scopes ------------------------------------------ NESTED SCOPES Example in FLOAT: # $Id$ float x; { float y; { float z; z = 0; y = 1; x = 2; } } What kind of code sequence for this? ------------------------------------------ ... [code to make program look like a scope] INC 1 [code to enter a scope] INC 1 [code to enter a scope] INC 1 [code for z = 0;...] [code to exit a scope] [code to exit a scope] Q: What should be done to enter a scope? save address of surrounding block's AR base, save old BP -- but those are the same here (due to textual nesting) so just need a PBP instruction to push the BP on the stack Q: What should be done to exit a scope? trim off any added variables, then restore the old break pointer so just need an RBP instruction Also need to adjust addresses for LOD and STO instructions, use BLOCK_LINKS_SIZE (defined in code.h) for this. Review code for code_compute_fp (in code.c) to get the FP for the right scope on the stack (draw pictures) test it!