COP 3402 meeting -*- Outline -*- * HW4, Basics and Demos ** Testing and The Task ------------------------------------------ TESTING FOR HOMEWORK 4 Does the generated code need to work in some particular way? ------------------------------------------ ... No, only the output of the compiled code has to match, and it's not a trace. ------------------------------------------ RUNNING INDIVIDUAL TESTS $ cat simple-print.spl % $Id: simple-print.spl,v 1.1 ... begin print 3402 end. $ make simple-print.myo rm -f simple-print.bof; umask 022; \ ./compiler simple-print.spl rm -f simple-print.myo; umask 022; \ cat char-inputs.txt | \ ./vm/vm simple-print.bof \ > simple-print.myo 2>&1 $ cat simple-print.myo 3402$ ------------------------------------------ Do that note that: - the output is just what is printed, no assembly language, no VM trace - (and there's no newline in the output) ------------------------------------------ THE TASK Write modules: gen_code literal_table So that with the provided files SPL source file test.spl | | compiler | v BOF file test.bof | | VM (provided) | v program output test.myo ------------------------------------------ ... the compiler transforms .spl source files into .bof files that when run on the provided VM produce the expected output (according to the SPL Manual) ** Strategy ------------------------------------------ OVERALL STRATEGY FOR WRITING GEN_CODE Use the shape of the unparser.c code Decide on overall tactics (e.g., expressions put result on stack) and follow those in all cases Build up code from Check your work by: ------------------------------------------ ... becuase it's also a recursive walk over the ASTs ... because that gives you an understanding of the recursion ... simplest to more complex test cases because those are the base cases of the recursion ... writing your own test cases, and checking for expected: - generated code (the .asm files) - and traces (the .myt files) *** Some Basic Decisions These are not required, just decisions that I thought made sense. But you need some decision that is general and always works. **** Literal above the GP ------------------------------------------ LITERALS STORED ABOVE THE GP FROM BOF Literal values stored at positive offsets from the GP - loaded from the BOF file's data section - offsets known to the compiler from Memory of the VM running a program: address 32768 [ ] [ ] [ ] [ ] initial [ ] SP,FP -->[ runtime stack ] [ program's AR ] [ AR for block 1 ] [ ... ] FP --> [ AR for block N ] SP --> [ ... ] [ | ] [ v ] [ ] [ ] [ ] [ ] [ ] [ literals ] [ ... ] [ (data from BOF) ] GP --> [ offset 0 data word ] [ ] [ ] [ ] [ ] [ ] [ VM ] [ instructions ] [ ... ] [ (text of BOF) ] [ ] PC --> [ ] 0 [________________________] ------------------------------------------ ... the literal table So, literals go from the program text to the literal table, so the compiler knows their offsets above the GP and then into the BOF, and then are loaded into the memory ------------------------------------------ OTHER BASIC DECISIONS Epressions: Conditions: Statements: Declarations: ------------------------------------------ - stored at positive offsets from GP loaded there from the BOF file's data section - push result on "top" of runtime stack (i.e., at SP + 0 offset) - push result on top of runtime stack it's 0 for false, 1 for true - leave SP unchanged when done (so they don't allocate or deallocate storage) - allocate and initialize variables and constants on the runtime stack (at positive offsets from the FP, as in layout 2) ------------------------------------------ STACK LAYOUT FOR EACH AR Layout 2: offset [ ... ] [ local variables ] [ ... ] FP -->[ local constants ] 0 [ saved SP ]-1 [ registers FP ]-2 [ static link ]-3 [ RA ]-4 [ temporary storage ] SP -->[ ... ] ------------------------------------------ Q: Is there something in the provided code that makes this layout? Yes, code_utils_save_registers_for_AR() and code_utils_restore_rgisters_from_AR() ** Tactics These are things that work with the provided code (in the code_utils module, for example) but are not required ------------------------------------------ TACTIC: MAKE EVERYTHING LOOK THE SAME Even the program's AR looks like other ARs $ cat empty.spl % $Id: empty.spl,v 1.1 ... begin end. $ $ make empty.asm rm -f empty.asm; umask 022; \ vm/disasm empty.bof > empty.asm 2>&1 $ cat empty.asm .text 0 a0: CPR $r3, $fp a1: SWR $sp, -1, $sp a2: SWR $sp, -2, $fp a3: SWR $sp, -3, $r3 a4: SWR $sp, -4, $ra a5: CPR $fp, $sp a6: SRI $sp, 4 a7: SWR $sp, -1, $sp a8: SWR $sp, -2, $fp a9: SWR $sp, -3, $r3 a10: SWR $sp, -4, $ra a11: CPR $fp, $sp a12: SRI $sp, 4 a13: NOP a14: LWR $ra, $fp, -4 a15: LWR $r3, $fp, -1 a16: LWR $fp, $fp, -2 a17: CPR $sp, $r3 a18: LWR $ra, $fp, -4 a19: LWR $r3, $fp, -1 a20: LWR $fp, $fp, -2 a21: CPR $sp, $r3 a22: EXIT 0 .data 4096 .stack 20480 .end $ ------------------------------------------ Maybe show the running of this program, and its lack of output Emphasize the generation of assembly code to check gen_code Show what comes from code_utils_set_up_program() code_utils_save_registers_for_AR() the stmts (NOP) code_utils_restore_rgisters_from_AR() code_utils_tear_down_program() including the EXIT! **** Other simple tests Do simple-print.spl talk about expression evaluations, literal table, talk about print statement and PINT, and result show the assembly code and what corresponds to what Do an if-then-else