From abd9efb1f056af9a163b765fb4aefef51f63fcea Mon Sep 17 00:00:00 2001 From: MarkMango21 Date: Wed, 20 Nov 2024 19:49:19 -0800 Subject: [PATCH 1/6] Many changes in the gen_code --- code.c | 32 ++++++++++++++ code.h | 9 ++++ code_seq.c | 2 + code_seq.h | 5 ++- gen_code.c | 120 ++++++++++++++++++++++++++++++++++++++++------------- gen_code.h | 10 ++++- 6 files changed, 148 insertions(+), 30 deletions(-) diff --git a/code.c b/code.c index 1e460ab..b76f5ee 100755 --- a/code.c +++ b/code.c @@ -460,3 +460,35 @@ code *code_notr() return create_syscall_instr(stop_tracing_sc,0,0); } +#define MINIMAL_STACK_ALLOC_IN_WORDS 12 +#define MINIMAL_STACK_ALLOC_BYTES (BYTES_PER_WORD*MINIMAL_STACK_ALLOC_IN_WORDS) + +// Set up the runtime stack for a procedure, +// where the static link is found in register $a0. +// Modifies when executed, the SP register, the FP register, +// and memory from SP to SP - MINIMAL_STACK_ALLOC_BYTES +// (inclusive) +code_seq code_save_registers_for_AR() +{ + // assume that SP is pointing to the lowest local storage already allocated + code_seq ret; + // push stack_pointer at word index 0 - 1 from current SP + ret = code_seq_singleton(code_swr(SP, SP, -1)); + // push the frame pointer (dynamic link) at word index -2 + code_seq_add_to_end(&ret, code_swr(SP, FP, -2)); + // save SP into FP register so FP points to the base of the AR + code_seq_add_to_end(&ret, code_add(0, SP, FP,ADD_F)); + // allocate the space on the stack, by subtracting from SP + code_seq_add_to_end(&ret, code_addi(SP, SP, - MINIMAL_STACK_ALLOC_BYTES)); + // push the static link at word index -3 + code_seq_add_to_end(&ret, code_swr(FP, GP, -3)); + // push the return address at word index 3 + code_seq_add_to_end(&ret, code_swr(FP, RA, -4)); + // save the registers $s0 to $s7 (inclusive) + int idx = -5; + for (int rn = GP; rn <= RA; rn++) { + code_seq_add_to_end(&ret, code_swr(FP, rn, idx--)); + } + return ret; +} + diff --git a/code.h b/code.h index 5bb188d..8fd4f2f 100755 --- a/code.h +++ b/code.h @@ -4,6 +4,7 @@ #include #include "machine_types.h" #include "instruction.h" +#include "code_seq.h" // SSM assembly language instructions (that can be in linked lists) typedef struct code_s { @@ -218,4 +219,12 @@ extern code *code_stra(); // with the named mnemonic and parameters extern code *code_notr(); +// Set up the runtime stack for a procedure, +// where the static link is found in register $a0. +// Modifies when executed, the SP register, the FP register, +// and memory from SP to SP - MINIMAL_STACK_ALLOC_BYTES +// (inclusive) +extern code_seq code_save_registers_for_AR(); + + #endif diff --git a/code_seq.c b/code_seq.c index 5c8fc2a..b433c4b 100755 --- a/code_seq.c +++ b/code_seq.c @@ -4,8 +4,10 @@ #include #include "utilities.h" #include "regname.h" +#include "code.h" #include "code_seq.h" + static void code_seq_okay(code_seq seq) { // seq.first and seq.last are either both null or both not null diff --git a/code_seq.h b/code_seq.h index 830cffe..661715c 100755 --- a/code_seq.h +++ b/code_seq.h @@ -2,7 +2,10 @@ #ifndef _CODE_SEQ_H #define _CODE_SEQ_H #include -#include "code.h" + +// Forward declare 'code' type to avoid circular dependency +struct code_s; +typedef struct code_s code; // Declare code as a type // code sequences are linked lists // with an additional last pointer to the last node diff --git a/gen_code.c b/gen_code.c index ea359d7..60b5162 100644 --- a/gen_code.c +++ b/gen_code.c @@ -90,34 +90,35 @@ void gen_code_program(BOFFILE bf, block_t prog) code_seq main_cs; // We want to make the main program's AR look like all blocks... so: // allocate space and initialize any variables - main_cs = gen_code_var_decls(prog.var_decls); - int vars_len_in_bytes = (code_seq_size(main_cs) / 2) * BYTES_PER_WORD; + main_cs = gen_code_seq_var_decls(prog.var_decls);//gen_code_seq_var_decls’ + //int vars_len_in_bytes = (code_seq_size(main_cs) / 2) * BYTES_PER_WORD; variable that has been muted based on line 101-104 // there is no static link for the program as a whole, // so nothing to do for saving FP into A0 as would be done for a block - code_seq_concat(main_cs, code_save_registers_for_AR()); - code_seq_concat(main_cs, - gen_code_stmt(prog.stmt)); - code_seq_concat(main_cs, + code_seq_concat(&main_cs, code_save_registers_for_AR()); + code_seq_concat(&main_cs, + gen_code_seq_stmts(prog.stmts));// Big difference from the Float calculator. Use of gen_code_stmts rather than gen_code_seq_stmt + /*code_seq_concat(&main_cs, code_restore_registers_from_AR()); - code_seq_concat(main_cs, - code_deallocate_stack_space(vars_len_in_bytes)); - code_seq_add_to_end(main_cs, code_exit()); + code_seq_concat(&main_cs, + code_deallocate_stack_space(vars_len_in_bytes));*/ // this section has been muted + code_seq_add_to_end(&main_cs, code_exit(0));// Over here I added a 0 into the code_ exit because of the instruction exit offset should be 0 gen_code_output_program(bf, main_cs); } // Generate code for the var_decls_t vds to out // There are 2 instructions generated for each identifier declared // (one to allocate space and another to initialize that space) -code_seq gen_code_var_decls(var_decls_t vds) +code_seq gen_code_seq_var_decls(var_decls_t vds)// the name was modified { code_seq ret = code_seq_empty(); var_decl_t *vdp = vds.var_decls; while (vdp != NULL) { - // generate these in reverse order, + // generate these in reverse order, // so the addressing offsets work properly - ret = code_seq_concat(gen_code_var_decl(*vdp), ret); + code_seq temp = gen_code_seq_var_decl(*vdp); // Store the result in a variable + code_seq_concat(&temp, ret); // Just call code_seq_concat without assigning to ret vdp = vdp->next; } return ret; @@ -126,24 +127,24 @@ code_seq gen_code_var_decls(var_decls_t vds) // Generate code for a single , vd, // There are 2 instructions generated for each identifier declared // (one to allocate space and another to initialize that space) -code_seq gen_code_var_decl(var_decl_t vd) +code_seq gen_code_seq_var_decl(var_decl_t vd) { - return gen_code_idents(vd.idents, vd.type); + return /*gen_code_idents(vd.idents, vd.type);*/ gen_code_seq_idents(vd.ident_list ); } // Generate code for the identififers in idents with type vt // in reverse order (so the first declared are allocated last). // There are 2 instructions generated for each identifier declared // (one to allocate space and another to initialize that space) -code_seq gen_code_idents(idents_t idents, - type_exp_e vt) +code_seq gen_code_seq_idents(ident_list_t idl) // this was changed+ modified compared to float calculato + { - code_seq ret = code_seq_empty(); - ident_t *idp = idents.idents; + /* code_seq ret = code_seq_empty(); + //ident_t *idp = idents.idents; + ident_t *idp = idl.start; while (idp != NULL) { - code_seq alloc_and_init = code_seq_singleton(code_addi(SP, SP, - -BYTES_PER_WORD)); + code_seq alloc_and_init = code_seq_singleton(code_addi(SP, SP, -BYTES_PER_WORD)); switch (vt) { case float_te: @@ -164,7 +165,27 @@ code_seq gen_code_idents(idents_t idents, ret = code_seq_concat(alloc_and_init, ret); idp = idp->next; } - return ret; + return ret;*/ + code_seq gen_code_seq_idents(ident_list_t idl) + { + code_seq ret = code_seq_empty(); // Start with an empty code sequence + ident_t *idp = idl.start; // Start from the first identifier in the list + + while (idp != NULL) + { + // Generate the code to allocate space for this identifier + // We assume you have a function gen_code_seq_alloc_ident that generates allocation code + code_seq alloc_and_init = gen_code_seq_alloc_ident(idp); + + // Add the allocation and initialization code in reverse order + code_seq_concat(&alloc_and_init, ret); // Concatenate the allocation code with the result + + // Move to the next identifier in the list + idp = idp->next; + } + + return ret; + } } // Generate code for stmt @@ -173,16 +194,22 @@ code_seq gen_code_stmt(stmt_t stmt) switch (stmt.stmt_kind) { case assign_stmt: - return gen_code_assign_stmt(stmt.data.assign_stmt); + return /*gen_code_assign_stmt(stmt.data.assign_stmt);*/ gen_code_seq_assign_stmt(stmt.data.assign_stmt); break; - case begin_stmt: + /*case begin_stmt: return gen_code_begin_stmt(stmt.data.begin_stmt); + break;*/ + case call_stmt: + return gen_code_seq_call_stmt(stmt.data.call_stmt); break; case if_stmt: - return gen_code_if_stmt(stmt.data.if_stmt); + return gen_code_seq_if_stmt(stmt.data.if_stmt); + break; + case while_stmt: + return gen_code_seq_while_stmt(stmt.data.while_stmt); break; case read_stmt: - return gen_code_read_stmt(stmt.data.read_stmt); + return gen_code_seq_read_stmt(stmt.data.read_stmt); break; case write_stmt: return gen_code_write_stmt(stmt.data.write_stmt); @@ -196,7 +223,7 @@ code_seq gen_code_stmt(stmt_t stmt) } // Generate code for stmt -code_seq gen_code_assign_stmt(assign_stmt_t stmt) +code_seq gen_code_seq_assign_stmt(assign_stmt_t stmt) { // can't call gen_code_ident, // since stmt.name is not an ident_t @@ -230,6 +257,15 @@ code_seq gen_code_assign_stmt(assign_stmt_t stmt) } return ret; } +// Generate code for stmt +code_seq gen_code_seq_call_stmt(call_stmt_t stmt) +{ + // can't call gen_code_ident, + // since stmt.name is not an ident_t + code_seq ret; + ret = gen_code_expr(*(stmt.expr)); + return ret; +} // Generate code for stmt code_seq gen_code_begin_stmt(begin_stmt_t stmt) @@ -241,14 +277,14 @@ code_seq gen_code_begin_stmt(begin_stmt_t stmt) // in FLOAT, surrounding scope's base is FP, so that is the static link ret = code_seq_add_to_end(ret, code_add(0, FP, A0)); ret = code_seq_concat(ret, code_save_registers_for_AR()); - ret = code_seq_concat(ret, gen_code_stmts(stmt.stmts)); + ret = code_seq_concat(ret, gen_code_seq_stmts(stmt.stmts)); ret = code_seq_concat(ret, code_restore_registers_from_AR()); ret = code_seq_concat(ret, code_deallocate_stack_space(vars_len_in_bytes)); return ret; } // Generate code for the list of statments given by stmts -code_seq gen_code_stmts(stmts_t stmts) +code_seq gen_code_seq_stmts(stmts_t stmts) { code_seq ret = code_seq_empty(); stmt_t *sp = stmts.stmts; @@ -260,6 +296,16 @@ code_seq gen_code_stmts(stmts_t stmts) return ret; } +// Generate code for stmt +code_seq gen_code_seq_while_stmt(while_stmt_t stmt) +{ + // can't call gen_code_ident, + // since stmt.name is not an ident_t + code_seq ret; + ret = gen_code_expr(*(stmt.expr)); + return ret; +} + // Generate code for the if-statment given by stmt code_seq gen_code_if_stmt(if_stmt_t stmt) { @@ -567,4 +613,22 @@ code_seq gen_code_logical_not_expr(expr_t exp) // push the result on the stack ret = code_seq_concat(ret, code_push_reg_on_stack(AT, bool_te)); return ret; +} +/*Brand new function responsible for generating the code sequence that allocates space for a variable (identifier) on the stack and initializes it with a default value, typically 0 */ +code_seq gen_code_seq_alloc_ident(ident_t *idp) +{ + code_seq ret = code_seq_empty(); // Start with an empty code sequence + + // Assuming that each identifier requires 4 bytes of space + // (adjust this based on your VM's size for each variable) + int size_of_ident = 4; // Adjust the size if necessary + + // 1. Allocate space by subtracting from the stack pointer (SP) + ret = code_seq_add_to_end(ret, code_addi(SP, SP, -size_of_ident)); + + // 2. Initialize the identifier (e.g., set it to 0) + // Assuming that a register 'zero' holds the value 0 + ret = code_seq_add_to_end(ret, code_swr(SP, zero, 0)); // Store 0 into the allocated space + + return ret; // Return the code sequence } \ No newline at end of file diff --git a/gen_code.h b/gen_code.h index 1ce7c92..04b3301 100644 --- a/gen_code.h +++ b/gen_code.h @@ -36,12 +36,18 @@ extern code_seq gen_code_seq_idents(ident_list_t idents); // Generate code_seq for stmt extern code_seq gen_code_seq_stmt(stmt_t stmt); -// Generate code_seq for stmt +// Generate code_seq for assign stmt extern code_seq gen_code_seq_assign_stmt(assign_stmt_t stmt); +//Generate code_seq for call stmt +extern code_seq gen_code_seq_call_stmt(call_stmt_t stmt); + // Generate code_seq for the list of statements given by stmts to out extern code_seq gen_code_seq_stmts(stmts_t stmts); +//Generate code_seq for while stmt +extern code_seq gen_code_seq_while_stmt(while_stmt_t stmt); + // Generate code_seq for the if-statement given by stmt extern code_seq gen_code_seq_if_stmt(if_stmt_t stmt); @@ -92,4 +98,6 @@ extern code_seq gen_code_seq_number(number_t num); // May also modify SP, HI,LO when executed extern code_seq gen_code_seq_logical_not_expr(expr_t exp); +extern code_seq gen_code_seq_alloc_ident(ident_t *idp); + #endif \ No newline at end of file From 5c15f80abbc38f324bb5fb93455c9a7e9d55c150 Mon Sep 17 00:00:00 2001 From: MarkMango21 Date: Wed, 20 Nov 2024 19:49:54 -0800 Subject: [PATCH 2/6] ok --- .gitignore | 55 - .vscode/c_cpp_properties.json | 18 - .vscode/launch.json | 24 - .vscode/settings.json | 62 - COP3402_Group_Member_Responsibilities.docx | Bin 17285 -> 0 bytes CollaborationFormulas.pdf | Bin 98428 -> 0 bytes ...p_Member_Responsibility_Certification.docx | Bin 16918 -> 0 bytes Makefile | 189 -- README.md | 1 - ast.c | 780 ----- ast.h | 537 ---- bof.c | 193 -- bof.h | 88 - char-inputs.txt | 6 - code.c | 494 ---- code.h | 230 -- code_seq.c | 137 - code_seq.h | 56 - code_utils.c | 158 - code_utils.h | 59 - compiler_main.c | 120 - file_location.c | 34 - file_location.h | 21 - gen_code.c | 634 ----- gen_code.h | 103 - hw4-code-generation.pdf | Bin 105010 -> 0 bytes hw4-gtest0.spl | 3 - hw4-gtest1.spl | 4 - hw4-gtest2.spl | 7 - hw4-gtest3.spl | 5 - hw4-gtest5.spl | 5 - hw4-gtest6.spl | 8 - hw4-gtest7.spl | 10 - hw4-gtest8.spl | 10 - hw4-gtest9.spl | 7 - hw4-gtestA.spl | 8 - hw4-gtestB.spl | 16 - hw4-gtestC.spl | 12 - hw4-gtestD.spl | 9 - hw4-gtestE.spl | 9 - hw4-gtestF.spl | 9 - hw4-gtestG.spl | 9 - hw4-gtestH.spl | 9 - hw4-gtestI.spl | 31 - hw4-gtestJ.spl | 26 - hw4-gtestK.spl | 8 - hw4-gtestL.spl | 22 - hw4-gtestM.spl | 18 - hw4-gtestN.spl | 25 - hw4-gtestO.spl | 15 - hw4-gtestP.spl | 29 - hw4-gtestQ.spl | 9 - hw4-gtestR.spl | 9 - hw4-gtestS.spl | 11 - hw4-gtestT.spl | 16 - hw4-read-test0.spl | 8 - hw4-read-test1.spl | 12 - hw4-tests.zip | Bin 631641 -> 0 bytes hw4-vmtest0.spl | 3 - hw4-vmtest1.spl | 4 - hw4-vmtest2.spl | 8 - hw4-vmtest3.spl | 9 - hw4-vmtest4.spl | 5 - hw4-vmtest5.spl | 10 - hw4-vmtest6.spl | 13 - hw4-vmtest7.spl | 13 - hw4-vmtest8.spl | 14 - hw4-vmtest9.spl | 22 - hw4-vmtestA.spl | 16 - hw4-vmtestB.spl | 7 - hw4-vmtestC.spl | 22 - id_attrs.c | 50 - id_attrs.h | 39 - id_use.c | 47 - id_use.h | 32 - instruction.c | 575 ---- instruction.h | 178 -- lexer.c | 6 - lexer.h | 39 - lexer_utilities.c | 8 - lexer_utilities.h | 15 - lexical_address.c | 28 - lexical_address.h | 23 - literal_table.c | 168 -- literal_table.h | 46 - machine_types.c | 100 - machine_types.h | 94 - parser.c | 22 - parser.h | 13 - parser_types.h | 11 - regname.c | 12 - regname.h | 18 - scope.c | 121 - scope.h | 55 - scope_check.c | 411 --- scope_check.h | 166 -- spl-manual.pdf | Bin 139829 -> 0 bytes spl.tab.c | 2319 --------------- spl.tab.h | 133 - spl.y | 235 -- spl_lexer.c | 2236 --------------- spl_lexer.h | 492 ---- spl_lexer.l | 252 -- symtab.c | 169 -- symtab.h | 66 - unparser.c | 427 --- unparser.h | 138 - utilities.c | 113 - utilities.h | 37 - vm/BOF_layout.png | Bin 55499 -> 0 bytes vm/Makefile | 165 -- vm/Makefile-for-Instructor | 113 - vm/asm.output | 2091 -------------- vm/asm.tab.c | 2533 ----------------- vm/asm.tab.h | 166 -- vm/asm.y | 489 ---- vm/asm_lexer.l | 379 --- vm/asm_main.c | 148 - vm/asm_unparser.c | 268 -- vm/asm_unparser.h | 58 - vm/assemble.c | 236 -- vm/assemble.h | 41 - vm/ast.c | 547 ---- vm/ast.h | 422 --- vm/bof.c | 193 -- vm/bof.h | 88 - vm/bof_bin_dump.c | 70 - vm/char_utilities.c | 158 - vm/char_utilities.h | 23 - vm/check-tests.sh | 6 - vm/disasm.c | 91 - vm/disasm.h | 37 - vm/disasm_main.c | 32 - vm/error_vm_test1.asm | 9 - vm/file_location.c | 31 - vm/file_location.h | 21 - vm/hexdump.sh | 3 - vm/id_attrs.h | 19 - vm/id_attrs_assoc.h | 19 - vm/instruction.c | 610 ---- vm/instruction.h | 181 -- vm/lexer.c | 230 -- vm/lexer.h | 63 - vm/lexer_error1.asm | 8 - vm/lexer_main.c | 26 - vm/lexer_test1.asm | 61 - vm/lexer_test1.lst | 50 - vm/lexer_test2.asm | 33 - vm/lexer_test2.lst | 12 - vm/lexer_test3.asm | 11 - vm/lexer_test3.lst | 6 - vm/lexer_test4.asm | 9 - vm/lexer_test4.lst | 6 - vm/lexer_test5.asm | 10 - vm/lexer_test5.lst | 7 - vm/lexer_test6.asm | 10 - vm/lexer_test6.lst | 6 - vm/lexer_utilities.c | 21 - vm/lexer_utilities.h | 15 - vm/machine.c | 649 ----- vm/machine.h | 50 - vm/machine_main.c | 62 - vm/machine_types.c | 100 - vm/machine_types.h | 94 - vm/parser_test0.asm | 6 - vm/parser_test0.lst | 3 - vm/parser_test1.asm | 12 - vm/parser_test1.lst | 5 - vm/parser_test2.asm | 14 - vm/parser_test2.lst | 10 - vm/parser_test3.asm | 13 - vm/parser_test3.lst | 8 - vm/parser_test4.asm | 10 - vm/parser_test4.lst | 5 - vm/parser_test5.asm | 58 - vm/parser_test5.lst | 47 - vm/parser_test6.asm | 36 - vm/parser_test6.lst | 30 - vm/parser_types.h | 11 - vm/pass1.c | 143 - vm/pass1.h | 40 - vm/regname.c | 12 - vm/regname.h | 18 - vm/run-tests.sh | 10 - vm/show_magic.c | 12 - vm/srm-asm.aux | 36 - vm/srm-asm.bbl | 8 - vm/srm-asm.tex | 322 --- vm/srm-isa.tex | 45 - vm/srm-lexertest1.asm | 14 - vm/srm-vm.aux | 91 - vm/srm-vm.bbl | 13 - vm/srm-vm.bib | 15 - vm/srm-vm.tex | 1017 ------- vm/ssm-asm.pdf | Bin 116407 -> 0 bytes vm/ssm-vm.pdf | Bin 267779 -> 0 bytes vm/symtab.c | 131 - vm/symtab.h | 49 - vm/symtab_test4.asm | 46 - vm/test.asm | 13 - vm/test.c | 46 - vm/test0.asm | 6 - vm/test_add.asm | 9 - vm/token.c | 38 - vm/token.h | 39 - vm/type_distinction_demo.c | 50 - vm/unparser_test1.asm | 12 - vm/unparser_test2.asm | 20 - vm/utilities.c | 94 - vm/utilities.h | 31 - vm/vm.c | 12 - vm/vm_test0.asm | 9 - vm/vm_test0.lst | 5 - vm/vm_test1.asm | 22 - vm/vm_test1.lst | 15 - vm/vm_test2.asm | 19 - vm/vm_test2.lst | 12 - vm/vm_test3.asm | 30 - vm/vm_test3.lst | 23 - vm/vm_test4.asm | 51 - vm/vm_test4.lst | 43 - vm/vm_test5.asm | 49 - vm/vm_test5.lst | 38 - vm/vm_test6.asm | 32 - vm/vm_test6.lst | 26 - vm/vm_test7.asm | 63 - vm/vm_test7.lst | 40 - vm/vm_test8.asm | 14 - vm/vm_test8.lst | 11 - vm/vm_test9.asm | 24 - vm/vm_test9.lst | 19 - vm/vm_testA.asm | 21 - vm/vm_testA.lst | 16 - vm/vm_testB.asm | 22 - vm/vm_testB.lst | 17 - vm/vm_testC.asm | 29 - vm/vm_testC.lst | 23 - vm/vm_testD.asm | 37 - vm/vm_testD.lst | 31 - vm/vm_testE.asm | 12 - vm/vm_testE.lst | 9 - 241 files changed, 27626 deletions(-) delete mode 100644 .gitignore delete mode 100644 .vscode/c_cpp_properties.json delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json delete mode 100644 COP3402_Group_Member_Responsibilities.docx delete mode 100644 CollaborationFormulas.pdf delete mode 100644 Group_Member_Responsibility_Certification.docx delete mode 100755 Makefile delete mode 100644 README.md delete mode 100755 ast.c delete mode 100755 ast.h delete mode 100755 bof.c delete mode 100755 bof.h delete mode 100755 char-inputs.txt delete mode 100755 code.c delete mode 100755 code.h delete mode 100755 code_seq.c delete mode 100755 code_seq.h delete mode 100755 code_utils.c delete mode 100755 code_utils.h delete mode 100755 compiler_main.c delete mode 100755 file_location.c delete mode 100755 file_location.h delete mode 100644 gen_code.c delete mode 100644 gen_code.h delete mode 100644 hw4-code-generation.pdf delete mode 100644 hw4-gtest0.spl delete mode 100644 hw4-gtest1.spl delete mode 100644 hw4-gtest2.spl delete mode 100644 hw4-gtest3.spl delete mode 100644 hw4-gtest5.spl delete mode 100644 hw4-gtest6.spl delete mode 100644 hw4-gtest7.spl delete mode 100644 hw4-gtest8.spl delete mode 100644 hw4-gtest9.spl delete mode 100644 hw4-gtestA.spl delete mode 100644 hw4-gtestB.spl delete mode 100644 hw4-gtestC.spl delete mode 100644 hw4-gtestD.spl delete mode 100644 hw4-gtestE.spl delete mode 100644 hw4-gtestF.spl delete mode 100644 hw4-gtestG.spl delete mode 100644 hw4-gtestH.spl delete mode 100644 hw4-gtestI.spl delete mode 100644 hw4-gtestJ.spl delete mode 100644 hw4-gtestK.spl delete mode 100644 hw4-gtestL.spl delete mode 100644 hw4-gtestM.spl delete mode 100644 hw4-gtestN.spl delete mode 100644 hw4-gtestO.spl delete mode 100644 hw4-gtestP.spl delete mode 100644 hw4-gtestQ.spl delete mode 100644 hw4-gtestR.spl delete mode 100644 hw4-gtestS.spl delete mode 100644 hw4-gtestT.spl delete mode 100644 hw4-read-test0.spl delete mode 100644 hw4-read-test1.spl delete mode 100644 hw4-tests.zip delete mode 100644 hw4-vmtest0.spl delete mode 100644 hw4-vmtest1.spl delete mode 100644 hw4-vmtest2.spl delete mode 100644 hw4-vmtest3.spl delete mode 100644 hw4-vmtest4.spl delete mode 100644 hw4-vmtest5.spl delete mode 100644 hw4-vmtest6.spl delete mode 100644 hw4-vmtest7.spl delete mode 100644 hw4-vmtest8.spl delete mode 100644 hw4-vmtest9.spl delete mode 100644 hw4-vmtestA.spl delete mode 100644 hw4-vmtestB.spl delete mode 100644 hw4-vmtestC.spl delete mode 100755 id_attrs.c delete mode 100755 id_attrs.h delete mode 100755 id_use.c delete mode 100755 id_use.h delete mode 100755 instruction.c delete mode 100755 instruction.h delete mode 100755 lexer.c delete mode 100755 lexer.h delete mode 100755 lexer_utilities.c delete mode 100755 lexer_utilities.h delete mode 100755 lexical_address.c delete mode 100755 lexical_address.h delete mode 100644 literal_table.c delete mode 100644 literal_table.h delete mode 100755 machine_types.c delete mode 100755 machine_types.h delete mode 100755 parser.c delete mode 100755 parser.h delete mode 100755 parser_types.h delete mode 100755 regname.c delete mode 100755 regname.h delete mode 100755 scope.c delete mode 100755 scope.h delete mode 100755 scope_check.c delete mode 100755 scope_check.h delete mode 100644 spl-manual.pdf delete mode 100755 spl.tab.c delete mode 100755 spl.tab.h delete mode 100755 spl.y delete mode 100755 spl_lexer.c delete mode 100755 spl_lexer.h delete mode 100755 spl_lexer.l delete mode 100755 symtab.c delete mode 100755 symtab.h delete mode 100755 unparser.c delete mode 100755 unparser.h delete mode 100755 utilities.c delete mode 100755 utilities.h delete mode 100755 vm/BOF_layout.png delete mode 100755 vm/Makefile delete mode 100755 vm/Makefile-for-Instructor delete mode 100644 vm/asm.output delete mode 100755 vm/asm.tab.c delete mode 100755 vm/asm.tab.h delete mode 100755 vm/asm.y delete mode 100755 vm/asm_lexer.l delete mode 100755 vm/asm_main.c delete mode 100755 vm/asm_unparser.c delete mode 100755 vm/asm_unparser.h delete mode 100755 vm/assemble.c delete mode 100755 vm/assemble.h delete mode 100755 vm/ast.c delete mode 100755 vm/ast.h delete mode 100755 vm/bof.c delete mode 100755 vm/bof.h delete mode 100755 vm/bof_bin_dump.c delete mode 100755 vm/char_utilities.c delete mode 100755 vm/char_utilities.h delete mode 100755 vm/check-tests.sh delete mode 100755 vm/disasm.c delete mode 100755 vm/disasm.h delete mode 100755 vm/disasm_main.c delete mode 100755 vm/error_vm_test1.asm delete mode 100755 vm/file_location.c delete mode 100755 vm/file_location.h delete mode 100755 vm/hexdump.sh delete mode 100755 vm/id_attrs.h delete mode 100755 vm/id_attrs_assoc.h delete mode 100755 vm/instruction.c delete mode 100755 vm/instruction.h delete mode 100755 vm/lexer.c delete mode 100755 vm/lexer.h delete mode 100755 vm/lexer_error1.asm delete mode 100755 vm/lexer_main.c delete mode 100755 vm/lexer_test1.asm delete mode 100755 vm/lexer_test1.lst delete mode 100755 vm/lexer_test2.asm delete mode 100755 vm/lexer_test2.lst delete mode 100755 vm/lexer_test3.asm delete mode 100755 vm/lexer_test3.lst delete mode 100755 vm/lexer_test4.asm delete mode 100755 vm/lexer_test4.lst delete mode 100755 vm/lexer_test5.asm delete mode 100755 vm/lexer_test5.lst delete mode 100755 vm/lexer_test6.asm delete mode 100755 vm/lexer_test6.lst delete mode 100755 vm/lexer_utilities.c delete mode 100755 vm/lexer_utilities.h delete mode 100755 vm/machine.c delete mode 100755 vm/machine.h delete mode 100755 vm/machine_main.c delete mode 100755 vm/machine_types.c delete mode 100755 vm/machine_types.h delete mode 100755 vm/parser_test0.asm delete mode 100755 vm/parser_test0.lst delete mode 100755 vm/parser_test1.asm delete mode 100755 vm/parser_test1.lst delete mode 100755 vm/parser_test2.asm delete mode 100755 vm/parser_test2.lst delete mode 100755 vm/parser_test3.asm delete mode 100755 vm/parser_test3.lst delete mode 100755 vm/parser_test4.asm delete mode 100755 vm/parser_test4.lst delete mode 100755 vm/parser_test5.asm delete mode 100755 vm/parser_test5.lst delete mode 100755 vm/parser_test6.asm delete mode 100755 vm/parser_test6.lst delete mode 100755 vm/parser_types.h delete mode 100755 vm/pass1.c delete mode 100755 vm/pass1.h delete mode 100755 vm/regname.c delete mode 100755 vm/regname.h delete mode 100755 vm/run-tests.sh delete mode 100755 vm/show_magic.c delete mode 100755 vm/srm-asm.aux delete mode 100755 vm/srm-asm.bbl delete mode 100755 vm/srm-asm.tex delete mode 100755 vm/srm-isa.tex delete mode 100755 vm/srm-lexertest1.asm delete mode 100755 vm/srm-vm.aux delete mode 100755 vm/srm-vm.bbl delete mode 100755 vm/srm-vm.bib delete mode 100755 vm/srm-vm.tex delete mode 100755 vm/ssm-asm.pdf delete mode 100755 vm/ssm-vm.pdf delete mode 100755 vm/symtab.c delete mode 100755 vm/symtab.h delete mode 100755 vm/symtab_test4.asm delete mode 100755 vm/test.asm delete mode 100755 vm/test.c delete mode 100755 vm/test0.asm delete mode 100755 vm/test_add.asm delete mode 100755 vm/token.c delete mode 100755 vm/token.h delete mode 100755 vm/type_distinction_demo.c delete mode 100755 vm/unparser_test1.asm delete mode 100755 vm/unparser_test2.asm delete mode 100755 vm/utilities.c delete mode 100755 vm/utilities.h delete mode 100755 vm/vm.c delete mode 100755 vm/vm_test0.asm delete mode 100755 vm/vm_test0.lst delete mode 100755 vm/vm_test1.asm delete mode 100755 vm/vm_test1.lst delete mode 100755 vm/vm_test2.asm delete mode 100755 vm/vm_test2.lst delete mode 100755 vm/vm_test3.asm delete mode 100755 vm/vm_test3.lst delete mode 100755 vm/vm_test4.asm delete mode 100755 vm/vm_test4.lst delete mode 100755 vm/vm_test5.asm delete mode 100755 vm/vm_test5.lst delete mode 100755 vm/vm_test6.asm delete mode 100755 vm/vm_test6.lst delete mode 100755 vm/vm_test7.asm delete mode 100755 vm/vm_test7.lst delete mode 100755 vm/vm_test8.asm delete mode 100755 vm/vm_test8.lst delete mode 100755 vm/vm_test9.asm delete mode 100755 vm/vm_test9.lst delete mode 100755 vm/vm_testA.asm delete mode 100755 vm/vm_testA.lst delete mode 100755 vm/vm_testB.asm delete mode 100755 vm/vm_testB.lst delete mode 100755 vm/vm_testC.asm delete mode 100755 vm/vm_testC.lst delete mode 100755 vm/vm_testD.asm delete mode 100755 vm/vm_testD.lst delete mode 100755 vm/vm_testE.asm delete mode 100755 vm/vm_testE.lst diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 2617e10..0000000 --- a/.gitignore +++ /dev/null @@ -1,55 +0,0 @@ -# Prerequisites -*.d - -# Object files -*.o -*.ko -*.obj -*.elf - -# Linker output -*.ilk -*.map -*.exp - -# Precompiled Headers -*.gch -*.pch - -# Libraries -*.lib -*.a -*.la -*.lo - -# Shared objects (inc. Windows DLLs) -*.dll -*.so -*.so.* -*.dylib - -# Executables -*.exe -*.out -*.app -*.i*86 -*.x86_64 -*.hex - -# Debug files -*.dSYM/ -*.su -*.idb -*.pdb - -# Kernel Module Compile Results -*.mod* -*.cmd -.tmp_versions/ -modules.order -Module.symvers -Mkfile.old -dkms.conf - -# vscode -.vscode/ \ No newline at end of file diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json deleted file mode 100644 index c2098a2..0000000 --- a/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "configurations": [ - { - "name": "linux-gcc-x64", - "includePath": [ - "${workspaceFolder}/**" - ], - "compilerPath": "/usr/bin/gcc", - "cStandard": "${default}", - "cppStandard": "${default}", - "intelliSenseMode": "linux-gcc-x64", - "compilerArgs": [ - "" - ] - } - ], - "version": 4 -} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index bb41346..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "name": "C/C++ Runner: Debug Session", - "type": "cppdbg", - "request": "launch", - "args": [], - "stopAtEntry": false, - "externalConsole": false, - "cwd": "/home/eugene-chevski/Desktop/CodeGeneratorSPL", - "program": "/home/eugene-chevski/Desktop/CodeGeneratorSPL/build/Debug/outDebug", - "MIMode": "gdb", - "miDebuggerPath": "gdb", - "setupCommands": [ - { - "description": "Enable pretty-printing for gdb", - "text": "-enable-pretty-printing", - "ignoreFailures": true - } - ] - } - ] -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index a8aadc4..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "C_Cpp_Runner.cCompilerPath": "gcc", - "C_Cpp_Runner.cppCompilerPath": "g++", - "C_Cpp_Runner.debuggerPath": "gdb", - "C_Cpp_Runner.cStandard": "", - "C_Cpp_Runner.cppStandard": "", - "C_Cpp_Runner.msvcBatchPath": "", - "C_Cpp_Runner.useMsvc": false, - "C_Cpp_Runner.warnings": [ - "-Wall", - "-Wextra", - "-Wpedantic", - "-Wshadow", - "-Wformat=2", - "-Wcast-align", - "-Wconversion", - "-Wsign-conversion", - "-Wnull-dereference" - ], - "C_Cpp_Runner.msvcWarnings": [ - "/W4", - "/permissive-", - "/w14242", - "/w14287", - "/w14296", - "/w14311", - "/w14826", - "/w44062", - "/w44242", - "/w14905", - "/w14906", - "/w14263", - "/w44265", - "/w14928" - ], - "C_Cpp_Runner.enableWarnings": true, - "C_Cpp_Runner.warningsAsError": false, - "C_Cpp_Runner.compilerArgs": [], - "C_Cpp_Runner.linkerArgs": [], - "C_Cpp_Runner.includePaths": [], - "C_Cpp_Runner.includeSearch": [ - "*", - "**/*" - ], - "C_Cpp_Runner.excludeSearch": [ - "**/build", - "**/build/**", - "**/.*", - "**/.*/**", - "**/.vscode", - "**/.vscode/**" - ], - "C_Cpp_Runner.useAddressSanitizer": false, - "C_Cpp_Runner.useUndefinedSanitizer": false, - "C_Cpp_Runner.useLeakSanitizer": false, - "C_Cpp_Runner.showCompilationTime": false, - "C_Cpp_Runner.useLinkTimeOptimization": false, - "C_Cpp_Runner.msvcSecureNoWarnings": false, - "files.associations": { - "gen_code.h": "c" - } -} \ No newline at end of file diff --git a/COP3402_Group_Member_Responsibilities.docx b/COP3402_Group_Member_Responsibilities.docx deleted file mode 100644 index 1d2de48b4e7ef53da6a7788236008f179bd19880..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17285 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%0AVgf3~Rh9owG1P&iNJ4VNJGWl(*c7jV-@7)OZK&N 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 z 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 MWmUMNNKE+u0AN&)*#H0l diff --git a/Group_Member_Responsibility_Certification.docx b/Group_Member_Responsibility_Certification.docx deleted file mode 100644 index 3d12bba9ac4c93a50a6d88a3ed627c9fbaf189e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16918 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 $@ 2>&1 - -# A .myt file is the output of running the VM with the -t option -# This can be useful for debugging. -.PRECIOUS: %.myt -%.myt: %.bof $(RUNVM) - $(RM) $@; umask 022; \ - cat char-inputs.txt | ./$(RUNVM) -t $< > $@ 2>&1 - -.PHONY: asm disasm -asm: $(ASM) -disasm: $(DISASM) - -$(ASM): - (cd $(VM); $(MAKE) asm) - -$(DISASM): - (cd $(VM); $(MAKE) disasm) - -# The .bof files are the compiled binary object files. -.PRECIOUS: %.bof -%.bof: %.$(SUF) $(COMPILER) - $(RM) $@; umask 022; \ - ./$(COMPILER) $< - -# The .upo files are unparsed programs; -# these are useful for debugging the parser and understanding the parse. -%.upo: %.$(SUF) $(COMPILER) - $(RM) $@; umask 022; \ - ./$(UNPARSER) $< > $@ 2>&1 - -# The .asm files are disassembled binary object files. -# These are useful for debugging the code the compiler creates. -%.asm: %.bof $(COMPILER) $(DISASM) - $(RM) $@; umask 022; \ - $(DISASM) $< > $@ 2>&1 - -# main target for testing -.PHONY: check-outputs -check-outputs: $(COMPILER) $(RUNVM) - @DIFFS=0; \ - for f in `echo $(ALLTESTS) | sed -e 's/\\.$(SUF)//g'`; \ - do \ - echo running ./$(COMPILER) on "$$f.$(SUF)"; \ - $(RM) "$$f.bof"; \ - ./$(COMPILER) "$$f.$(SUF)" ; \ - echo running $(RUNVM) on "$$f.bof"; \ - $(RM) "$$f.myo"; \ - cat char-inputs.txt | $(RUNVM) "$$f.bof" > "$$f.myo" 2>&1; \ - diff -w -B "$$f.out" "$$f.myo" && echo 'passed!' || DIFFS=1; \ - done; \ - if test 0 = $$DIFFS; \ - then \ - echo 'All output tests passed!'; \ - else \ - echo 'Some output test(s) failed!'; \ - fi - -$(SUBMISSIONZIPFILE): *.c *.h $(STUDENTTESTOUTPUTS) - $(ZIP) $(SUBMISSIONZIPFILE) $(SPL).y $(SPL)_lexer.l *.c *.h Makefile - $(ZIP) $(SUBMISSIONZIPFILE) $(STUDENTTESTOUTPUTS) $(ALLTESTS) $(EXPECTEDOUTPUTS) - $(ZIP) -r -9 $(SUBMISSIONZIPFILE) $(VM) -x 'vm/*.o' 'vm/*.exe' 'vm/RCS/' 'vm/RCS/*,v' - -.PHONY: compile-separately check-separately -compile-separately check-separately: $(COMPILER_OBJECTS) diff --git a/README.md b/README.md deleted file mode 100644 index e83f438..0000000 --- a/README.md +++ /dev/null @@ -1 +0,0 @@ -# CodeGeneratorSPL \ No newline at end of file diff --git a/ast.c b/ast.c deleted file mode 100755 index 6b15584..0000000 --- a/ast.c +++ /dev/null @@ -1,780 +0,0 @@ -/* $Id: ast.c,v 1.15 2024/11/03 22:49:33 leavens Exp $ */ -#include -#include -#include -#include "utilities.h" -#include "ast.h" -#include "spl.tab.h" - -// Return the file location from an AST -file_location *ast_file_loc(AST t) { - return t.generic.file_loc; -} - -// Return the filename from the AST t -const char *ast_filename(AST t) { - return ast_file_loc(t)->filename; -} - -// Return the line number from the AST t -unsigned int ast_line(AST t) { - return ast_file_loc(t)->line; -} - -// Return the type tag of the AST t -AST_type ast_type_tag(AST t) { - return t.generic.type_tag; -} - -// Return a pointer to a fresh copy of t -// that has been allocated on the heap -AST *ast_heap_copy(AST t) { - AST *ret = (AST *)malloc(sizeof(AST)); - if (ret == NULL) { - bail_with_error("Cannot allocate an AST heap copy!"); - } - *ret = t; - return ret; -} - -// Return an AST for a block which contains the given ASTs. -block_t ast_block(token_t begin_tok, const_decls_t const_decls, - var_decls_t var_decls, proc_decls_t proc_decls, - stmts_t stmts) -{ - block_t ret; - ret.file_loc = file_location_copy(begin_tok.file_loc); - ret.type_tag = block_ast; - ret.const_decls = const_decls; - ret.var_decls = var_decls; - ret.proc_decls = proc_decls; - ret.stmts = stmts; - return ret; -} - -// Return an AST for an empty const decls -extern const_decls_t ast_const_decls_empty(empty_t empty) -{ - const_decls_t ret; - ret.file_loc = empty.file_loc; - ret.type_tag = const_decls_ast; - ret.start = NULL; - return ret; -} - -// Return an AST for the const decls -const_decls_t ast_const_decls(const_decls_t const_decls, - const_decl_t const_decl) -{ - const_decls_t ret = const_decls; - // make a copy of const_decl on the heap - const_decl_t *p = (const_decl_t *) malloc(sizeof(const_decl_t)); - if (p == NULL) { - bail_with_error("Cannot allocate space for %s!", "const_decl_t"); - } - *p = const_decl; - p->next = NULL; - const_decl_t *last = ast_last_list_elem(ret.start); - if (last == NULL) { - ret.start = p; - } else { - last->next = p; - } - return ret; -} - - - -// Return an AST for a const_decl -const_decl_t ast_const_decl(const_def_list_t const_def_list) -{ - const_decl_t ret; - ret.file_loc = const_def_list.file_loc; - ret.type_tag = const_decl_ast; - ret.const_def_list = const_def_list; - ret.next = NULL; - return ret; -} - -// Return an AST for const-def-list that is a singleton -extern const_def_list_t ast_const_def_list_singleton(const_def_t const_def) -{ - const_def_list_t ret; - ret.file_loc = const_def.file_loc; - ret.type_tag = const_def_list_ast; - const_def_t *p = (const_def_t *) malloc(sizeof(const_def_t)); - if (p == NULL) { - bail_with_error("Unable to allocate space for a %s!", "const_def_t"); - } - *p = const_def; - p->next = NULL; - ret.start = p; - return ret; -} - -// Return an AST for const_defs -extern const_def_list_t ast_const_def_list(const_def_list_t const_def_list, - const_def_t const_def) -{ - const_def_list_t ret = const_def_list; - // make a copy of const_def on the heap - const_def_t *p = (const_def_t *) malloc(sizeof(const_def_t)); - if (p == NULL) { - bail_with_error("Cannot allocate space for %s!", "const_def_t"); - } - *p = const_def; - p->next = NULL; - const_def_t *last = ast_last_list_elem(ret.start); - if (last == NULL) { - ret.start = p; - } else { - last->next = p; - } - return ret; -} - -// Return an AST for a const-def -const_def_t ast_const_def(ident_t ident, number_t number) -{ - const_def_t ret; - ret.file_loc = file_location_copy(ident.file_loc); - assert((ret.file_loc)->filename != NULL); - ret.type_tag = const_def_ast; - ret.next = NULL; - ret.ident = ident; - ret.number = number; - return ret; -} - - -// Return an AST for varDecls that are empty -var_decls_t ast_var_decls_empty(empty_t empty) -{ - var_decls_t ret; - ret.file_loc = empty.file_loc; - ret.type_tag = var_decls_ast; - ret.var_decls = NULL; - return ret; -} - -// Return an AST varDecls that have some var_decls -var_decls_t ast_var_decls(var_decls_t var_decls, var_decl_t var_decl) -{ - var_decls_t ret = var_decls; - // make a copy of var_decl on the heap - var_decl_t *p = (var_decl_t *) malloc(sizeof(var_decl_t)); - if (p == NULL) { - bail_with_error("Cannot allocate space for %s!", "var_decl_t"); - } - *p = var_decl; - p->next = NULL; - var_decl_t *last = ast_last_list_elem(ret.var_decls); - if (last == NULL) { - ret.var_decls = p; - } else { - last->next = p; - } - return ret; -} - -// Return an AST for a var_decl -var_decl_t ast_var_decl(ident_list_t ident_list) -{ - var_decl_t ret; - ret.file_loc = ident_list.file_loc; - ret.type_tag = var_decl_ast; - ret.next = NULL; - ret.ident_list = ident_list; - return ret; -} - -// Return an AST made for one ident -extern ident_list_t ast_ident_list_singleton(ident_t ident) -{ - ident_list_t ret; - ret.file_loc = ident.file_loc; - ret.type_tag = ident_list_ast; - // make a copy of ident on the heap - ident_t *p = (ident_t *) malloc(sizeof(ident_t)); - if (p == NULL) { - bail_with_error("Unable to allocate space for a %s!", "ident_t"); - } - *p = ident; - p->next = NULL; - ret.start = p; - return ret; -} - -// Return an AST made for idents -extern ident_list_t ast_ident_list(ident_list_t ident_list, ident_t ident) -{ - ident_list_t ret = ident_list; - // make a copy of ident on the heap - ident_t *p = (ident_t *) malloc(sizeof(ident_t)); - if (p == NULL) { - bail_with_error("Cannot allocate space for %s!", "ident_t"); - } - *p = ident; - p->next = NULL; - ident_t *last = ast_last_list_elem(ret.start); - if (last == NULL) { - ret.start = p; - } else { - last->next = p; - } - return ret; -} - -// Return an AST for proc_decls -proc_decls_t ast_proc_decls_empty(empty_t empty) -{ - proc_decls_t ret; - ret.file_loc = empty.file_loc; - ret.type_tag = proc_decls_ast; - ret.proc_decls = NULL; - return ret; -} - -// Return an AST for proc_decls -proc_decls_t ast_proc_decls(proc_decls_t proc_decls, - proc_decl_t proc_decl) -{ - proc_decls_t ret = proc_decls; - // make a copy of proc_decl on the heap - proc_decl_t *p = (proc_decl_t *) malloc(sizeof(proc_decl_t)); - if (p == NULL) { - bail_with_error("Unable to allocate space for a %s!", "proc_decl_t"); - } - *p = proc_decl; - p->next = NULL; - proc_decl_t *last = ast_last_list_elem(ret.proc_decls); - if (last == NULL) { - ret.proc_decls = p; - } else { - last->next = p; - } - return ret; -} - -// Return an AST for a proc_decl -proc_decl_t ast_proc_decl(ident_t ident, block_t block) -{ - proc_decl_t ret; - ret.file_loc = file_location_copy(ident.file_loc); - ret.type_tag = proc_decl_ast; - ret.next = NULL; - ret.name = ident.name; - block_t *p = (block_t *) malloc(sizeof(block_t)); - if (p == NULL) { - bail_with_error("Unable to allocate space for a %s!", "block_t"); - } - *p = block; - ret.block = p; - return ret; -} - -// Return an AST for a print statement -print_stmt_t ast_print_stmt(expr_t expr) { - print_stmt_t ret; - ret.file_loc = expr.file_loc; - ret.type_tag = print_stmt_ast; - ret.expr = expr; - return ret; -} - -// Return an AST for a read statement -read_stmt_t ast_read_stmt(ident_t ident) { - read_stmt_t ret; - ret.file_loc = file_location_copy(ident.file_loc); - ret.type_tag = read_stmt_ast; - ret.name = ident.name; - return ret; -} - -// Return an immediate data holding an address -while_stmt_t ast_while_stmt(condition_t condition, stmts_t body) { - while_stmt_t ret; - ret.file_loc = condition.file_loc; - ret.type_tag = while_stmt_ast; - ret.condition = condition; - stmts_t *p = (stmts_t *) malloc(sizeof(stmts_t)); - if (p == NULL) { - bail_with_error("Unable to allocate space for a %s!", "stmts_t"); - } - *p = body; - ret.body = p; - return ret; -} - -// Return an AST for an if-then-else statement -if_stmt_t ast_if_then_else_stmt(condition_t condition, - stmts_t then_stmts, stmts_t else_stmts) -{ - if_stmt_t ret; - ret.file_loc = condition.file_loc; - ret.type_tag = if_stmt_ast; - ret.condition = condition; - // copy then_stmt to the heap - stmts_t *p = (stmts_t *) malloc(sizeof(stmts_t)); - if (p == NULL) { - bail_with_error("Unable to allocate space for a %s!", "stmts_t"); - } - *p = then_stmts; - ret.then_stmts = p; - // copy else_stmts to the heap - p = (stmts_t *) malloc(sizeof(stmts_t)); - if (p == NULL) { - bail_with_error("Unable to allocate space for a %s!", "stmts_t"); - } - *p = else_stmts; - ret.else_stmts = p; - return ret; -} - -// Return an AST for a (short) if-then statement -// Note that the else part is a NULL pointer -extern if_stmt_t ast_if_then_stmt(condition_t condition, - stmts_t then_stmts) -{ - if_stmt_t ret; - ret.file_loc = condition.file_loc; - ret.type_tag = if_stmt_ast; - ret.condition = condition; - // copy then_stmt to the heap - stmts_t *p = (stmts_t *) malloc(sizeof(stmts_t)); - if (p == NULL) { - bail_with_error("Unable to allocate space for a %s!", "stmts_t"); - } - *p = then_stmts; - ret.then_stmts = p; - ret.else_stmts = NULL; - return ret; -} - -// Return an AST for a begin statement -// containing the given list of statements -block_stmt_t ast_block_stmt(block_t block) -{ - block_stmt_t ret; - ret.file_loc = block.file_loc; - ret.type_tag = block_stmt_ast; - // copy the block to the heap - block_t *p = (block_t *) malloc(sizeof(block_t)); - if (p == NULL) { - bail_with_error("Unable to allocate space for a %s!", "block_t"); - } - *p = block; - ret.block = p; - return ret; -} - -// Return an AST for a call statment - call_stmt_t ast_call_stmt(ident_t ident) -{ - call_stmt_t ret; - ret.file_loc = file_location_copy(ident.file_loc); - ret.type_tag = call_stmt_ast; - ret.name = ident.name; - return ret; -} - -// Return an AST for an assignment statement -assign_stmt_t ast_assign_stmt(ident_t ident, expr_t expr) -{ - assign_stmt_t ret; - ret.file_loc = file_location_copy(ident.file_loc); - ret.type_tag = assign_stmt_ast; - ret.name = ident.name; - assert(ret.name != NULL); - expr_t *p = (expr_t *) malloc(sizeof(expr_t)); - if (p == NULL) { - bail_with_error("Unable to allocate space for a %s!", "expr_t"); - } - *p = expr; - ret.expr = p; - assert(ret.expr != NULL); - return ret; -} - -// Return an AST for the list of statements -stmts_t ast_stmts_empty(empty_t empty) -{ - stmts_t ret; - ret.file_loc = file_location_copy(empty.file_loc); - ret.type_tag = stmts_ast; - ret.stmts_kind = empty_stmts_e; - return ret; -} - -// Return an AST for empty found in the given file location -empty_t ast_empty(file_location *file_loc) -{ - empty_t ret; - ret.file_loc = file_loc; - ret.type_tag = empty_ast; - return ret; -} - -// Return an AST for the list of statements -stmts_t ast_stmts(stmt_list_t stmt_list) -{ - stmts_t ret; - ret.file_loc = stmt_list.file_loc; - ret.type_tag = stmts_ast; - ret.stmts_kind = stmt_list_e; - ret.stmt_list = stmt_list; - return ret; -} - - -// Return an AST for the list of statements -stmt_list_t ast_stmt_list_singleton(stmt_t stmt) { - // debug_print("Entering ast_stmts_singleton\n"); - stmt_list_t ret; - ret.file_loc = stmt.file_loc; - ret.type_tag = stmt_list_ast; - stmt.next = NULL; - // copy stmt to the heap - stmt_t *p = (stmt_t *) malloc(sizeof(stmt_t)); - if (p == NULL) { - bail_with_error("Unable to allocate space for a %s!", "stmt_t"); - } - *p = stmt; - p->next = NULL; - // there will be no statments after stmt in the list - ret.start = p; - return ret; -} - -// Return an AST for the list of statements -extern stmt_list_t ast_stmt_list(stmt_list_t stmt_list, stmt_t stmt) { - // debug_print("Entering ast_stmt_list...\n"); - stmt_list_t ret = stmt_list; - // copy stmt to the heap - stmt_t *s = (stmt_t *) malloc(sizeof(stmt_t)); - if (s == NULL) { - bail_with_error("Cannot allocate space for %s!", "stmt_t"); - } - *s = stmt; - s->next = NULL; - stmt_t *last = ast_last_list_elem(ret.start); - assert(last != NULL); // because there are no empty lists of stmts - last->next = s; - return ret; -} - -// Return an AST for the given statment -stmt_t ast_stmt_assign(assign_stmt_t s) -{ - stmt_t ret; - ret.file_loc = s.file_loc; - ret.type_tag = stmt_ast; - ret.next = NULL; - ret.stmt_kind = assign_stmt; - ret.data.assign_stmt = s; - return ret; -} - -// Return an AST for the given statment -stmt_t ast_stmt_call(call_stmt_t s) -{ - stmt_t ret; - ret.file_loc = s.file_loc; - ret.type_tag = stmt_ast; - ret.next = NULL; - ret.stmt_kind = call_stmt; - ret.data.call_stmt = s; - return ret; -} - -// Return an AST for the given statment -stmt_t ast_stmt_block(block_stmt_t s) -{ - stmt_t ret; - ret.file_loc = s.file_loc; - ret.type_tag = stmt_ast; - ret.next = NULL; - ret.stmt_kind = block_stmt; - ret.data.block_stmt = s; - return ret; -} - -// Return an AST for the given statment -stmt_t ast_stmt_if(if_stmt_t s) -{ - stmt_t ret; - ret.file_loc = s.file_loc; - ret.type_tag = stmt_ast; - ret.next = NULL; - ret.stmt_kind = if_stmt; - ret.data.if_stmt = s; - return ret; -} - -// Return an AST for the given statment -stmt_t ast_stmt_while(while_stmt_t s) -{ - stmt_t ret; - ret.file_loc = s.file_loc; - ret.type_tag = stmt_ast; - ret.next = NULL; - ret.stmt_kind = while_stmt; - ret.data.while_stmt = s; - return ret; -} - -// Return an AST for the given statment -stmt_t ast_stmt_read(read_stmt_t s) -{ - stmt_t ret; - ret.file_loc = s.file_loc; - ret.type_tag = stmt_ast; - ret.next = NULL; - ret.stmt_kind = read_stmt; - ret.data.read_stmt = s; - return ret; -} - -// Return an AST for the given statment -stmt_t ast_stmt_print(print_stmt_t s) -{ - // debug_print("Entering ast_stmt_print...\n"); - stmt_t ret; - ret.file_loc = s.file_loc; - ret.type_tag = stmt_ast; - ret.next = NULL; - ret.stmt_kind = print_stmt; - ret.data.print_stmt = s; - return ret; -} - -// Return an AST for an odd condition -db_condition_t ast_db_condition(expr_t dividend, expr_t divisor) -{ - db_condition_t ret; - ret.file_loc = dividend.file_loc; - ret.type_tag = db_condition_ast; - ret.dividend = dividend; - ret.divisor = divisor; - return ret; -} - -// Return an AST for an initializer with the given value -rel_op_condition_t ast_rel_op_condition(expr_t expr1, token_t rel_op, - expr_t expr2) -{ - rel_op_condition_t ret; - ret.file_loc = expr1.file_loc; - ret.type_tag = rel_op_condition_ast; - ret.expr1 = expr1; - ret.rel_op = rel_op; - ret.expr2 = expr2; - return ret; -} - -// Return an AST for an odd condition -condition_t ast_condition_db(db_condition_t db_cond) -{ - condition_t ret; - ret.file_loc = db_cond.file_loc; - ret.type_tag = db_condition_ast; - ret.cond_kind = ck_db; - ret.data.db_cond = db_cond; - return ret; -} - -// Return an AST for a relational condition -condition_t ast_condition_rel_op(rel_op_condition_t rel_op_cond) -{ - condition_t ret; - ret.file_loc = rel_op_cond.file_loc; - ret.type_tag = condition_ast; - ret.cond_kind = ck_rel; - ret.data.rel_op_cond = rel_op_cond; - return ret; -} - -// Return an AST for an odd condition -binary_op_expr_t ast_binary_op_expr(expr_t expr1, token_t arith_op, - expr_t expr2) -{ - binary_op_expr_t ret; - ret.file_loc = expr1.file_loc; - ret.type_tag = binary_op_expr_ast; - - expr_t *p = (expr_t *) malloc(sizeof(expr_t)); - if (p == NULL) { - bail_with_error("Unable to allocate space for a %s!", "expr_t"); - } - *p = expr1; - ret.expr1 = p; - - ret.arith_op = arith_op; - - p = (expr_t *) malloc(sizeof(expr_t)); - if (p == NULL) { - bail_with_error("Unable to allocate space for a %s!", "expr_t"); - } - *p = expr2; - ret.expr2 = p; - - return ret; -} - -// Return an expression AST for a binary operation expresion -expr_t ast_expr_binary_op(binary_op_expr_t e) -{ - expr_t ret; - ret.file_loc = e.file_loc; - ret.type_tag = expr_ast; - ret.expr_kind = expr_bin; - ret.data.binary = e; - return ret; -} - -// Return an expression AST for a signed expression -expr_t ast_expr_signed_expr(token_t sign, expr_t e) -{ - expr_t ret; - ret.file_loc = file_location_copy(sign.file_loc); - ret.type_tag = expr_ast; - switch (sign.code) { - case minussym: - ret.expr_kind = expr_negated; - negated_expr_t ne; - ne.file_loc = ret.file_loc; - ne.type_tag = negated_expr_ast; - ne.expr = (expr_t *)ast_heap_copy((AST)e); - ret.data.negated = ne; - break; - case plussym: - // don't make any changes, use e as the result - return e; - break; - default: - bail_with_error("Unexpected sign token in ast_expr_signed_expr: %d", - sign.code); - break; - } - return ret; -} - -// Return an expression AST for an signed number -expr_t ast_expr_pos_number(token_t sign, number_t number) -{ - expr_t ret; - ret.file_loc = file_location_copy(sign.file_loc); - ret.type_tag = expr_ast; - ret.expr_kind = expr_number; - ret.data.number = number; - return ret; -} - -// Return an AST for the given token -token_t ast_token(file_location *file_loc, const char *text, int code) -{ - token_t ret; - ret.file_loc = file_loc; - ret.type_tag = token_ast; - ret.text = text; - ret.code = code; - return ret; -} - -// Return an AST for a (signed) number with the given value -number_t ast_number(token_t sgn, word_type value) -{ - number_t ret; - ret.file_loc = file_location_copy(sgn.file_loc); - ret.type_tag = number_ast; - ret.value = value; - return ret; -} - -// Return an AST for an identifier -ident_t ast_ident(file_location *file_loc, const char *name) -{ - ident_t ret; - ret.file_loc = file_loc; - ret.type_tag = ident_ast; - ret.name = name; - return ret; -} - -// Return an AST for an expression that's a binary expression -expr_t ast_expr_binary_op_expr(binary_op_expr_t e) -{ - expr_t ret; - ret.file_loc = e.file_loc; - ret.type_tag = binary_op_expr_ast; - ret.expr_kind = expr_bin; - ret.data.binary = e; - return ret; -} - -// Return an AST for an expression that's an identifier -expr_t ast_expr_ident(ident_t e) -{ - expr_t ret; - ret.file_loc = e.file_loc; - ret.type_tag = expr_ast; - ret.expr_kind = expr_ident; - ret.data.ident = e; - return ret; -} - -// Return an AST for an expression that's a number -expr_t ast_expr_number(number_t e) -{ - expr_t ret; - ret.file_loc = e.file_loc; - ret.type_tag = expr_ast; - ret.expr_kind = expr_number; - ret.data.number = e; - return ret; -} - -// Requires: lst is a pointer to a non-circular -// linked list with next pointers -// as in generic_t -// Return a pointer to the last element in lst. -// This only returns NULL if lst == NULL. -void *ast_last_list_elem(void *lst) -{ - // debug_print("Entering ast_last_list_elem\n"); - if (lst == NULL) { - return lst; - } - // assert(lst != NULL); - void *prev = NULL; - while (lst != NULL) { - prev = lst; - lst = ((generic_t *)lst)->next; - } - // here lst == NULL; - return prev; -} - -// Requires: lst is a pointer to a non-circular -// linked list with next pointers -// as in generic_t -// Return the number of elements in the linked list lst -int ast_list_length(void *lst) -{ - int ret = 0; - generic_t *p = (generic_t *) lst; - while (p != NULL) { - p = p->next; - ret++; - } - return ret; -} - -// Requires: lst is a pointer to a non-circular -// linked list with next pointers -// as in generic_t -// Is lst empty? -bool ast_list_is_empty(void *lst) -{ - return lst == NULL; -} diff --git a/ast.h b/ast.h deleted file mode 100755 index ab3f532..0000000 --- a/ast.h +++ /dev/null @@ -1,537 +0,0 @@ -/* $Id: ast.h,v 1.18 2024/11/03 22:49:33 leavens Exp $ */ -#ifndef _AST_H -#define _AST_H -#include -#include "machine_types.h" -#include "file_location.h" -#include "id_use.h" - -// types of ASTs (type tags) -typedef enum { - block_ast, const_decls_ast, const_decl_ast, - const_def_list_ast, const_def_ast, - var_decls_ast, var_decl_ast, ident_list_ast, - proc_decls_ast, proc_decl_ast, - stmts_ast, empty_ast, stmt_list_ast, stmt_ast, - assign_stmt_ast, call_stmt_ast, if_stmt_ast, while_stmt_ast, - read_stmt_ast, print_stmt_ast, block_stmt_ast, - condition_ast, db_condition_ast, rel_op_condition_ast, - expr_ast, binary_op_expr_ast, negated_expr_ast, ident_ast, number_ast, - token_ast -} AST_type; - -// The following types for structs named N_t -// are returned by the parser. -// The struct N_t is the type of information kept in the AST -// that is related to the nonterminal N in the abstract syntax. - -// The generic struct type (generic_t) has the fields that -// should be in all alternatives for ASTs. -typedef struct { - file_location *file_loc; - AST_type type_tag; // says what field of the union is active - void *next; // for lists -} generic_t; - -// empty ::= -typedef struct { - file_location *file_loc; - AST_type type_tag; -} empty_t; - -// identifiers -typedef struct ident_s { - file_location *file_loc; - AST_type type_tag; - struct ident_s *next; // for lists this is a part of - const char *name; - id_use *idu; -} ident_t; - -// (possibly signed) numbers -typedef struct { - file_location *file_loc; - AST_type type_tag; - const char *text; - word_type value; -} number_t; - -// tokens as ASTs -typedef struct { - file_location *file_loc; - AST_type type_tag; - const char *text; - int code; -} token_t; - -// kinds of expressions -typedef enum { expr_bin, expr_negated, expr_ident, expr_number } expr_kind_e; - -// forward declaration for the expr type -struct expr_s; - -// expr ::= expr arithOp expr -// arithOp ::= + | - | * | / -typedef struct { - file_location *file_loc; - AST_type type_tag; - struct expr_s *expr1; - token_t arith_op; - struct expr_s *expr2; -} binary_op_expr_t; - -// expr ::= - expr -typedef struct { - file_location *file_loc; - AST_type type_tag; - struct expr_s *expr; -} negated_expr_t; - -// expr ::= expr arithOp expr | ident | number -typedef struct expr_s { - file_location *file_loc; - AST_type type_tag; - expr_kind_e expr_kind; - union { - binary_op_expr_t binary; - negated_expr_t negated; - ident_t ident; - number_t number; - } data; -} expr_t; - -// kinds of conditions -typedef enum { ck_db, ck_rel } condition_kind_e; - -typedef struct { - file_location *file_loc; - AST_type type_tag; - expr_t dividend; - expr_t divisor; -} db_condition_t; - -typedef struct { - file_location *file_loc; - AST_type type_tag; - expr_t expr1; - token_t rel_op; - expr_t expr2; -} rel_op_condition_t; - -// condition ::= divisible expr expr | expr relOp expr -typedef struct { - file_location *file_loc; - AST_type type_tag; - condition_kind_e cond_kind; - union cond_u { - db_condition_t db_cond; - rel_op_condition_t rel_op_cond; - } data; -} condition_t; - -// kinds of statements -typedef enum { assign_stmt, call_stmt, if_stmt, while_stmt, - read_stmt, print_stmt, block_stmt } stmt_kind_e; - -// forward declaration of statement type -struct stmt_s; - -// stmt-list ::= stmt | stmt-list stmt -typedef struct { - file_location *file_loc; - AST_type type_tag; - struct stmt_s *start; -} stmt_list_t; - -typedef enum { empty_stmts_e, stmt_list_e } stmts_kind_e; - -// stmts ::= { stmts } -typedef struct { - file_location *file_loc; - AST_type type_tag; - stmts_kind_e stmts_kind; - stmt_list_t stmt_list; // when stmts_kind != empty_stmts_e -} stmts_t; - -// stmt ::= ident := expr -typedef struct { - file_location *file_loc; - AST_type type_tag; - const char *name; - struct expr_s *expr; - id_use *idu; -} assign_stmt_t; - -// stmt ::= call ident -typedef struct { - file_location *file_loc; - AST_type type_tag; - const char *name; - id_use *idu; -} call_stmt_t; - -// forward declaration for block type -struct block_s; - -// block-stmt ::= block -typedef struct block_stmt_s { - file_location *file_loc; - AST_type type_tag; - struct block_s *block; -} block_stmt_t; - -// if-stmt ::= if condition stmts stmts | if condition stmts -typedef struct { - file_location *file_loc; - AST_type type_tag; - condition_t condition; - stmts_t *then_stmts; - stmts_t *else_stmts; -} if_stmt_t; - -// stmt ::= while condition stmt -typedef struct { - file_location *file_loc; - AST_type type_tag; - condition_t condition; - stmts_t *body; -} while_stmt_t; - -// stmt ::= read ident -typedef struct { - file_location *file_loc; - AST_type type_tag; - const char *name; - id_use *idu; -} read_stmt_t; - -// stmt ::= print expr -typedef struct { - file_location *file_loc; - AST_type type_tag; - expr_t expr; -} print_stmt_t; - -// stmt ::= assign-stmt | call-stmt | if-stmt -// | while-stmt | read-stmt | print-stmt | block-stmt -typedef struct stmt_s { - file_location *file_loc; - AST_type type_tag; - struct stmt_s *next; // for lists this is a part of - stmt_kind_e stmt_kind; - union { - assign_stmt_t assign_stmt; - call_stmt_t call_stmt; - if_stmt_t if_stmt; - while_stmt_t while_stmt; - read_stmt_t read_stmt; - print_stmt_t print_stmt; - block_stmt_t block_stmt; - } data; -} stmt_t; - -// procDecl ::= proc ident block -typedef struct proc_decl_s { - file_location *file_loc; - AST_type type_tag; - struct proc_decl_s *next; // for lists - const char *name; - struct block_s *block; -} proc_decl_t; - -// proc-decls ::= { proc-decl } -typedef struct { - file_location *file_loc; - AST_type type_tag; - proc_decl_t *proc_decls; -} proc_decls_t; - -// ident-list ::= ident | ident-list ident -typedef struct { - file_location *file_loc; - AST_type type_tag; - ident_t *start; -} ident_list_t; - -// var-decl ::= var ident-list -typedef struct var_decl_s { - file_location *file_loc; - AST_type type_tag; - struct var_decl_s *next; // for lists this is a part of - ident_list_t ident_list; -} var_decl_t; - -// var-decls ::= { var-decl } -typedef struct { - file_location *file_loc; - AST_type type_tag; - var_decl_t *var_decls; -} var_decls_t; - -// const-def ::= ident number -typedef struct const_def_s { - file_location *file_loc; - AST_type type_tag; - struct const_def_s *next; // for lists this is a part of - ident_t ident; - number_t number; -} const_def_t; - -// const-def-list ::= { const-def } -typedef struct { - file_location *file_loc; - AST_type type_tag; - const_def_t *start; -} const_def_list_t; - -// const-decl ::= const const-def-list -typedef struct const_decl_s { - file_location *file_loc; - AST_type type_tag; - struct const_decl_s *next; // for lists this is a part of - const_def_list_t const_def_list; -} const_decl_t; - -// const-decls ::= { const-decl } -typedef struct { - file_location *file_loc; - AST_type type_tag; - const_decl_t *start; -} const_decls_t; - -// block ::= begin const-decls var-decls proc-decls stmts -typedef struct block_s { - file_location *file_loc; - AST_type type_tag; - const_decls_t const_decls; - var_decls_t var_decls; - proc_decls_t proc_decls; - stmts_t stmts; -} block_t; - -// program ::= block - -// The AST definition used by bison -typedef union AST_u { - generic_t generic; - block_t block; - const_decls_t const_decls; - const_decl_t const_decl; - const_def_list_t const_def_list; - const_def_t const_def; - var_decls_t var_decls; - var_decl_t var_decl; - ident_list_t ident_list; - proc_decls_t proc_decls; - proc_decl_t proc_decl; - stmts_t stmts; - stmt_list_t stmt_list; - stmt_t stmt; - assign_stmt_t assign_stmt; - call_stmt_t call_stmt; - if_stmt_t if_stmt; - while_stmt_t while_stmt; - read_stmt_t read_stmt; - print_stmt_t print_stmt; - block_stmt_t block_stmt; - condition_t condition; - rel_op_condition_t rel_op_condition; - db_condition_t db_condition; - expr_t expr; - binary_op_expr_t binary_op_expr; - token_t token; - number_t number; - ident_t ident; - empty_t empty; -} AST; - -// Return the file location from an AST -extern file_location *ast_file_loc(AST t); - -// Return the filename from the AST t -extern const char *ast_filename(AST t); - -// Return the line number from the AST t -extern unsigned int ast_line(AST t); - -// Return the type tag of the AST t -extern AST_type ast_type_tag(AST t); - -// Return a pointer to a fresh copy of t -// that has been allocated on the heap -extern AST *ast_heap_copy(AST t); - -// Return an AST for a block which contains the given ASTs. -extern block_t ast_block(token_t begin_tok, const_decls_t const_decls, var_decls_t var_decls, proc_decls_t proc_decls, stmts_t stmts); - -// Return an AST for an empty const decls -extern const_decls_t ast_const_decls_empty(empty_t empty); - -// Return an AST for the const decls -extern const_decls_t ast_const_decls(const_decls_t const_decls, - const_decl_t const_decl); - -// Return an AST for a const_decl -extern const_decl_t ast_const_decl(const_def_list_t const_def_list); - -// Return an AST for const_def_list -extern const_def_list_t ast_const_def_list_singleton(const_def_t const_def); - -// Return an AST for adding to a const_def_list -extern const_def_list_t ast_const_def_list(const_def_list_t const_def_list, - const_def_t const_def); - -// Return an AST for a const-def -extern const_def_t ast_const_def(ident_t ident, number_t number); - -// Return an AST for varDecls that are empty -extern var_decls_t ast_var_decls_empty(empty_t empty); - -// Return an AST varDecls that have some var_decls -extern var_decls_t ast_var_decls(var_decls_t var_decls, var_decl_t var_decl); - -// Return an AST for a var_decl -extern var_decl_t ast_var_decl(ident_list_t ident_list); - -// Return an AST made for one ident -extern ident_list_t ast_ident_list_singleton(ident_t ident); - -// Return an AST made for ident lists -extern ident_list_t ast_ident_list(ident_list_t ident_list, ident_t ident); - -// Return an AST for proc_decls -extern proc_decls_t ast_proc_decls_empty(empty_t empty); - -// Return an AST for proc_decls -extern proc_decls_t ast_proc_decls(proc_decls_t proc_decls, - proc_decl_t proc_decl); - -// Return an AST for a proc_decl -extern proc_decl_t ast_proc_decl(ident_t ident, block_t block); - - -// Return an AST for the list of statements -extern stmts_t ast_stmts_empty(empty_t empty); - -// Return an AST for empty found in the given file location -extern empty_t ast_empty(file_location *file_loc); - -// Return an AST for the list of statements -extern stmts_t ast_stmts(stmt_list_t stmt_list); - -// Return an AST for a list of statements that has stmt as a member -extern stmt_list_t ast_stmt_list_singleton(stmt_t stmt); - -// Return an AST for the list of statements -extern stmt_list_t ast_stmt_list(stmt_list_t stmt_list, stmt_t stmt); - -// Return an AST for the given statement as a more general stmt AST -extern stmt_t ast_stmt_assign(assign_stmt_t s); - -// Return an AST for the given statement as a more general stmt AST -extern stmt_t ast_stmt_call(call_stmt_t s); - -// Return an AST for the given statement as a more general stmt AST -extern stmt_t ast_stmt_block(block_stmt_t s); - -// Return an AST for the given statement as a more general stmt AST -extern stmt_t ast_stmt_if(if_stmt_t s); - -// Return an AST for the given statement as a more general stmt AST -extern stmt_t ast_stmt_while(while_stmt_t s); - -// Return an AST for the given statement as a more general stmt AST -extern stmt_t ast_stmt_read(read_stmt_t s); - -// Return an AST for the given statement as a more general stmt AST -extern stmt_t ast_stmt_print(print_stmt_t s); - -// Return an AST for an assignment statement -extern assign_stmt_t ast_assign_stmt(ident_t ident, expr_t expr); - -// Return an AST for a call statement -extern call_stmt_t ast_call_stmt(ident_t ident); - -// Return an AST for an if-then-else statement -extern if_stmt_t ast_if_then_else_stmt(condition_t condition, - stmts_t then_stmts, stmts_t else_stmts); - -// Return an AST for a (short) if-then statement -// Note that the else part is a NULL pointer -extern if_stmt_t ast_if_then_stmt(condition_t condition, - stmts_t then_stmts); - -// Return an AST for a while statement -extern while_stmt_t ast_while_stmt(condition_t condition, stmts_t body); - -// Return an AST for a read statement -extern read_stmt_t ast_read_stmt(ident_t ident); - -// Return an AST for a print statement -extern print_stmt_t ast_print_stmt(expr_t expr); - -// Return an AST for a block statement -extern block_stmt_t ast_block_stmt(block_t block); - - -// Return an AST for an odd condition -extern db_condition_t ast_db_condition(expr_t dividend, expr_t divisor); - -// Return an AST for an initializer with the given value -extern rel_op_condition_t ast_rel_op_condition(expr_t expr1, token_t rel_op, - expr_t expr2); - -// Return an AST for an odd condition -extern condition_t ast_condition_db(db_condition_t db_cond); - -// Return an AST for a relational condition -extern condition_t ast_condition_rel_op(rel_op_condition_t rel_op_cond); - - -// Return an expression AST for a binary operation expresion -extern expr_t ast_expr_binary_op(binary_op_expr_t e1); - -// Return an expression AST for an identifier -extern expr_t ast_expr_ident(ident_t e); - -// Return an AST for an expression that's a number -extern expr_t ast_expr_number(number_t e); - -// Return an AST for a binary op expression -extern binary_op_expr_t ast_binary_op_expr(expr_t expr1, token_t arith_op, - expr_t expr2); - -// Return an expression AST for a signed expression -extern expr_t ast_expr_signed_expr(token_t sign, expr_t expr); - -// The following are made by the lexer... - -// Return an AST for the given token -extern token_t ast_token(file_location *file_loc, const char *text, int code); - -// Return an AST for an identifier -// found in the file named fn, on line ln, with the given name. -extern ident_t ast_ident(file_location *file_loc, const char *name); - -// Some operations on AST lists - -// Requires: lst is a pointer to a non-circular -// linked list with next pointers -// as in generic_t -// Return a pointer to the last element in lst. -// This only returns NULL if lst == NULL. -extern void *ast_last_list_elem(void *lst); - -// Requires: lst is a pointer to a non-circular -// linked list with next pointers -// as in generic_t -// Return the number of elements in the linked list lst -extern int ast_list_length(void *lst); - -// Requires: lst is a pointer to a non-circular -// linked list with next pointers -// as in generic_t -// Is lst empty? -extern bool ast_list_is_empty(void *lst); - -#endif diff --git a/bof.c b/bof.c deleted file mode 100755 index 82b2b6a..0000000 --- a/bof.c +++ /dev/null @@ -1,193 +0,0 @@ -/* $Id: bof.c,v 1.2 2024/10/23 13:38:20 leavens Exp $ */ -// #include -#include -// #include -#include -#include -#include -#include "bof.h" -#include "utilities.h" - -#define MAGIC "BO32" - -// a type for treating bytes as a word -typedef union { - unsigned char buf[BYTES_PER_WORD]; - word_type w; -} word_pun_t; - -// Open filename for reading as a binary file -// Exit the program with an error if this fails, -// otherwise return the BOFFILE struct for the file -BOFFILE bof_read_open(const char *filename) { - BOFFILE bf; - bf.fileptr = fopen(filename, "rb"); - bf.filename = filename; - - if (bf.fileptr == NULL) { - bail_with_error("Error opening file for reading: %s", filename); - } - - return bf; -} - -// Return the size (in bytes) of bf -size_t bof_file_bytes(BOFFILE bf) -{ - struct stat st; - if (stat(bf.filename, &st) < 0) { - bail_with_error("Cannot stat %s to get its size!", bf.filename); - } - ; - return st.st_size; -} - -// Return true just when bf is at its end, false otherwise -bool bof_at_eof(BOFFILE bf) { - return feof(bf.fileptr); -} - -// Requires: bf is open for reading in binary and has -// at least BYTES_PER_WORD bytes in it -// Return the next word from bf -word_type bof_read_word(BOFFILE bf) -{ - word_pun_t b; - assert(!bof_at_eof(bf)); - size_t bytes_read = bof_read_bytes(bf, BYTES_PER_WORD, b.buf); - if (bytes_read == 0) { - bail_with_error( - "Cannot read a word from %s (got %d bytes), at EOF: %d", - bf.filename, bytes_read, bof_at_eof(bf)); - } - return b.w; -} - -// Requires: bf.fileptr is open for reading in binary -// and buf is of size at least bytes -// Read the given number of bytes into buf and return the number of bytes read -size_t bof_read_bytes(BOFFILE bf, size_t bytes, void *buf) { - int elems_read = fread(buf, bytes, 1, bf.fileptr); - return elems_read; -} - -// Requires: bf is open for reading in binary -// Read the header of bf as a BOFHeader and return that header -// If any errors are encountered, exit with an error message. -BOFHeader bof_read_header(BOFFILE bf) { - BOFHeader ret; - size_t rd = fread(&ret, sizeof(ret), 1, bf.fileptr); - if (rd != 1) { - bail_with_error("Cannot read header from %s", bf.filename); - } - if (!bof_has_correct_magic_number(ret)) { - bail_with_error("Wrong magic number code in file '%s'!", - bf.filename); - } - return ret; - /* - bof_read_bytes(bf, MAGIC_BUFFER_SIZE, &ret.magic); - if (strncmp(ret.magic, MAGIC, MAGIC_BUFFER_SIZE) != 0) { - bail_with_error("File %s is not a BOF format file, bad magic number!", - bf.filename); - } - bof_read_bytes(bf, BYTES_PER_WORD, &ret.text_start_address); - bof_read_bytes(bf, BYTES_PER_WORD, &ret.text_length); - bof_read_bytes(bf, BYTES_PER_WORD, &ret.data_start_address); - bof_read_bytes(bf, BYTES_PER_WORD, &ret.data_length); - bof_read_bytes(bf, BYTES_PER_WORD, &ret.stack_bottom_addr); - return ret; - */ -} - -// Requires: f is open for writing -// Write the magic number in hexadecimal notation on f, followed by a newline; -// Note: this is just for help in writing the documentation -/* -void bof_write_magic(FILE *f) { - fprintf(f, "%s", "0x"); - for (int i = 0; i < MAGIC_BUFFER_SIZE; i++) { - fprintf(f, "%x", MAGIC[i]); - } - fprintf(f, "\n"); -} -*/ - -// Open filename for writing as a binary file -// Exit the program with an error if this fails, -// otherwise return the BOFFILE for it. -BOFFILE bof_write_open(const char *filename) { - BOFFILE bf; - bf.fileptr = fopen(filename, "wb"); - bf.filename = filename; - - if (bf.fileptr == NULL) { - bail_with_error("Error opening file for writing: %s", filename); - } - - return bf; -} - -// Requres: bf is open -// Close the given binary file -// Exit the program with an error if this fails. -void bof_close(BOFFILE bf) -{ - if (fclose(bf.fileptr) != 0) { - bail_with_error("Could not close %s", bf.filename); - } -} - - -// Requires: bf is open for writing in binary. -// Write the given word into bf -// Exit the program with an error if this fails. -extern void bof_write_word(BOFFILE bf, word_type w) -{ - word_pun_t b; - b.w = w; - bof_write_bytes(bf, BYTES_PER_WORD, b.buf); -} - -// Requires: bf is open for writing in binary -// and the size of buf is at least bytes -// Write the given number of bytes from buf into f. -// Exit the program with an error if this fails. -void bof_write_bytes(BOFFILE bf, size_t bytes, - const void *buf) { - size_t wr = fwrite(buf, bytes, 1, bf.fileptr); - if (wr != 1) { - bail_with_error("Cannot write %u bytes to %s", bytes, bf.filename); - } -} - -// Requires: bf is open for writing in binary -// Write the given header to f -// Exit the program with an error if this fails. -void bof_write_header(BOFFILE bf, const BOFHeader hdr) { - size_t wr = fwrite(&hdr, sizeof(BOFHeader), 1, bf.fileptr); - if (wr != 1) { - bail_with_error("Canot write header to %s", bf.filename); - } -} - -// Write the (bits of the) magic number into the header bh. -void bof_write_magic_to_header(BOFHeader *bh) -{ - const char *magic = MAGIC; - for (int i = 0; i < MAGIC_BUFFER_SIZE; i++) { - bh->magic[i] = magic[i]; - } - assert(bof_has_correct_magic_number(*bh)); -} - -// Does the given header have the appropriate magic number? -bool bof_has_correct_magic_number(BOFHeader bh) -{ - char buf[MAGIC_BUFFER_SIZE+1]; - for (int i = 0; i < MAGIC_BUFFER_SIZE; i++) { - buf[i] = bh.magic[i]; - } - buf[MAGIC_BUFFER_SIZE] = '\0'; - return (0 == strncmp(buf, MAGIC, MAGIC_BUFFER_SIZE)); -} diff --git a/bof.h b/bof.h deleted file mode 100755 index 0201806..0000000 --- a/bof.h +++ /dev/null @@ -1,88 +0,0 @@ -/* $Id: bof.h,v 1.2 2024/10/23 13:38:20 leavens Exp $ */ -// Binary Object File Format (for the SSM) -#ifndef _BOF_H -#define _BOF_H -#include -#include -#include -#include "machine_types.h" - -#define MAGIC_BUFFER_SIZE 4 - -typedef struct { // Field magic should hold value of MAGIC (with no null char) - char magic[MAGIC_BUFFER_SIZE]; - word_type text_start_address; // word address to start running (PC) - word_type text_length; // size of the text section in words - word_type data_start_address; // word address of static data (GP) - word_type data_length; // size of data section in words - word_type stack_bottom_addr; // word address of stack "bottom" (FP) -} BOFHeader; - -// a type for Binary Output Files -typedef struct { - FILE *fileptr; - const char *filename; -} BOFFILE; - -// Open filename for reading as a binary file -// Exit the program with an error if this fails, -// otherwise return the FILE pointer to the open file. -extern BOFFILE bof_read_open(const char *filename); - -// Return the size (in bytes) of bf -extern size_t bof_file_bytes(BOFFILE bf); - -// Return true just when bf is at its end, false otherwise -extern bool bof_at_eof(BOFFILE bf); - -// Requires: bf is open for reading in binary and has -// at least 1 word (2 bytes) available to read -// Return the next word from bf -extern word_type bof_read_word(BOFFILE bf); - -// Requires: bf is open for reading in binary and -// buf is of size at least bytes -// Read the given number of bytes into buf and return the number of bytes read -size_t bof_read_bytes(BOFFILE bf, size_t bytes, void *buf); - -// Requires: bf is open for reading in binary -// Read the header of bf as a BOFHeader and return that header -// If any errors are encountered, exit with an error message. -extern BOFHeader bof_read_header(BOFFILE); - -// Open filename for writing as a binary file -// Exit the program with an error if this fails, -// otherwise return the BOFFILE for it. -extern BOFFILE bof_write_open(const char *filename); - -// Requres: bf is open -// Close the given binary file -// Exit the program with an error if this fails. -extern void bof_close(BOFFILE bf); - -// Requires: bf is open for writing in binary -// Write the given word into bf. -// Exit the program with an error if this fails. -extern void bof_write_word(BOFFILE bf, word_type w); - -// Requires: bf is open for writing in binary -// and the size of buf is at least bytes -// Write the given number of bytes from buf into f. -// Exit the program with an error if this fails. -extern void bof_write_bytes(BOFFILE bf, size_t bytes, - const void *buf); - -// Requires: bf is open for writing in binary -// Write the given header to f -// Exit the program with an error if this fails. -extern void bof_write_header(BOFFILE bf, const BOFHeader hdr); - -// Write the (bits of the) magic number into the header *bh. -extern void bof_write_magic_to_header(BOFHeader *bh); - -// Does the given header have the appropriate magic number? -bool bof_has_correct_magic_number(BOFHeader bh); - -// The following line is for the manual (i.e., the document itself)y -// ... -#endif diff --git a/char-inputs.txt b/char-inputs.txt deleted file mode 100755 index 28eebd9..0000000 --- a/char-inputs.txt +++ /dev/null @@ -1,6 +0,0 @@ -$Id: char-inputs.txt,v 1.2 2024/11/13 19:48:06 leavens Exp leavens $ -"8N[3456789abcdefghijklmnopqrstuvwzyz -ABCDEFGHIJKLMNOPQRSTUVWXYZ -ljk;.!@$%`~<>,?/\[{}]dfafjk -skfj8u32820t-0i[pkrojgivrmolk;u -slkdfj;sdfkjalskj diff --git a/code.c b/code.c deleted file mode 100755 index b76f5ee..0000000 --- a/code.c +++ /dev/null @@ -1,494 +0,0 @@ -/* $Id: code.c,v 1.29 2024/11/11 23:01:08 leavens Exp $ */ -#include -#include -#include -#include "utilities.h" -#include "code.h" -#include "regname.h" - -// Return a fresh code struct, with next pointer NULL -// containing the given instruction instr. -// If there is not enough space, bail with an error, -// so this will never return NULL. -static code *code_create(bin_instr_t instr) -{ - code *ret = (code *)malloc(sizeof(code)); - if (ret == NULL) { - bail_with_error("Not enough space to allocate a code struct!"); - } - ret->next = NULL; - ret->instr = instr; - return ret; -} - -// --- computational format instructions as in the SSM Manual's table 3 --- - -// return a freshly allocated computational-format instruction -static code *create_comp_instr(reg_num_type t, offset_type ot, reg_num_type s, - offset_type os, func0_code fc) -{ - comp_instr_t ci; - ci.op = COMP_O; - ci.rt = t; - ci.ot = ot; - ci.rs = s; - ci.os = os; - ci.func = fc; - bin_instr_t bi; - bi.comp = ci; - return code_create(bi); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_nop() -{ - return create_comp_instr(0,0,0,0,NOP_F); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_add(reg_num_type t, offset_type ot, - reg_num_type s, offset_type os) -{ - return create_comp_instr(t, ot, s, os, ADD_F); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_sub(reg_num_type t, offset_type ot, - reg_num_type s, offset_type os) -{ - return create_comp_instr(t, ot, s, os, SUB_F); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_cpw(reg_num_type t, offset_type ot, - reg_num_type s, offset_type os) -{ - return create_comp_instr(t, ot, s, os, CPW_F); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_cpr(reg_num_type t, reg_num_type s) -{ - return create_comp_instr(t, 0, s, 0, CPR_F); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_and(reg_num_type t, offset_type ot, - reg_num_type s, offset_type os) -{ - return create_comp_instr(t, ot, s, os, AND_F); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_bor(reg_num_type t, offset_type ot, - reg_num_type s, offset_type os) -{ - return create_comp_instr(t, ot, s, os, BOR_F); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_nor(reg_num_type t, offset_type ot, - reg_num_type s, offset_type os) -{ - return create_comp_instr(t, ot, s, os, NOR_F); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_xor(reg_num_type t, offset_type ot, - reg_num_type s, offset_type os) -{ - return create_comp_instr(t, ot, s, os, XOR_F); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_lwr(reg_num_type t, reg_num_type s, offset_type os) -{ - return create_comp_instr(t, 0, s, os, LWR_F); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_swr(reg_num_type t, offset_type ot, reg_num_type s) -{ - return create_comp_instr(t, ot, s, 0, SWR_F); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_sca(reg_num_type t, offset_type ot, - reg_num_type s, offset_type os) -{ - return create_comp_instr(t, ot, s, os, SCA_F); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_lwi(reg_num_type t, offset_type ot, - reg_num_type s, offset_type os) -{ - return create_comp_instr(t, ot, s, os, LWI_F); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_neg(reg_num_type t, offset_type ot, - reg_num_type s, offset_type os) -{ - return create_comp_instr(t, ot, s, os, NEG_F); -} - - -// --- other computational format instructions, in SSM Manual's table 4 --- - -// return a freshly allocated computational-format instruction -static code *create_other_comp_instr(reg_num_type t, offset_type o, - arg_type a, func1_code fc) -{ - other_comp_instr_t oci; - oci.op = OTHC_O; - oci.reg = t; - oci.offset = o; - oci.arg = a; - oci.func = fc; - bin_instr_t bi; - bi.othc = oci; - return code_create(bi); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_lit(reg_num_type t, offset_type ot, immediate_type i) -{ - return create_other_comp_instr(t, ot, i, LIT_F); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_ari(reg_num_type r, immediate_type i) -{ - return create_other_comp_instr(r, 0, i, ARI_F); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_sri(reg_num_type r, immediate_type i) -{ - return create_other_comp_instr(r, 0, i, SRI_F); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_mul(reg_num_type s, offset_type o) -{ - return create_other_comp_instr(s, o, 0, MUL_F); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_div(reg_num_type s, offset_type o) -{ - return create_other_comp_instr(s, o, 0, DIV_F); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_cfhi(reg_num_type t, offset_type o) -{ - return create_other_comp_instr(t, o, 0, CFHI_F); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_cflo(reg_num_type t, offset_type o) -{ - return create_other_comp_instr(t, o, 0, CFLO_F); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_sll(reg_num_type t, offset_type o, shift_type h) -{ - return create_other_comp_instr(t, o, h, SLL_F); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_srl(reg_num_type t, offset_type o, shift_type h) -{ - return create_other_comp_instr(t, o, h, SLL_F); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_jmp(reg_num_type s, offset_type o) -{ - return create_other_comp_instr(s, o, 0, JMP_F); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_csi(reg_num_type s, offset_type o) -{ - return create_other_comp_instr(s, o, 0, CSI_F); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_jrel(offset_type o) -{ - return create_other_comp_instr(0, 0, o, JREL_F); -} - - -// --- immediate format instructions, in SSM Manual's table 5 --- - -// return a fresh immediate-type instruction -// (with a signed immediate operand) -static code *create_immed_instr(op_code op, reg_num_type r, - offset_type o, immediate_type i) -{ - immed_instr_t ii; - ii.op = op; - ii.reg = r; - ii.offset = o; - ii.immed = i; // this is sign extended by the VM, not here! - bin_instr_t bi; - bi.immed = ii; - return code_create(bi); -} - -// return a fresh immediate-type instruction -// (with an unsigned immediate operand) -static code *create_uimmed_instr(op_code op, reg_num_type r, - offset_type o, uimmed_type u) -{ - uimmed_instr_t ui; - ui.op = op; - ui.reg = r; - ui.offset = o; - ui.uimmed = u; - bin_instr_t bi; - bi.uimmed = ui; - return code_create(bi); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_addi(reg_num_type r, offset_type o, immediate_type i) -{ - return create_immed_instr(ADDI_O, r, o, i); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_andi(reg_num_type r, offset_type o, uimmed_type u) -{ - return create_uimmed_instr(ANDI_O, r, o, u); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_bori(reg_num_type r, offset_type o, uimmed_type u) -{ - return create_uimmed_instr(BORI_O, r, o, u); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_nori(reg_num_type r, offset_type o, uimmed_type u) -{ - return create_uimmed_instr(NORI_O, r, o, u); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_xori(reg_num_type r, offset_type o, uimmed_type u) -{ - return create_uimmed_instr(XORI_O, r, o, u); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_beq(reg_num_type r, offset_type o, immediate_type i) -{ - return create_immed_instr(BEQ_O, r, o, i); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_bgez(reg_num_type r, offset_type o, immediate_type i) -{ - return create_immed_instr(BGEZ_O, r, o, i); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_bgtz(reg_num_type r, offset_type o, immediate_type i) -{ - return create_immed_instr(BGTZ_O, r, o, i); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_blez(reg_num_type r, offset_type o, immediate_type i) -{ - return create_immed_instr(BLEZ_O, r, o, i); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_bltz(reg_num_type r, offset_type o, immediate_type i) -{ - return create_immed_instr(BLTZ_O, r, o, i); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_bne(reg_num_type r, offset_type o, immediate_type i) -{ - return create_immed_instr(BNE_O, r, o, i); -} - -// --- jump format instructions, in SSM Manual's table 6 --- - -// return a fresh jump-type instruction -static code *create_jump_instr(op_code op, address_type a) -{ - jump_instr_t ji; - ji.op = op; - ji.addr = a; - bin_instr_t bi; - bi.jump = ji; - return code_create(bi); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_jmpa(address_type a) -{ - return create_jump_instr(JMPA_O, a); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_call(address_type a) -{ - code *ret = create_jump_instr(CALL_O, a); - return ret; -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_rtn() -{ - code *ret = create_jump_instr(RTN_O, 0); - return ret; -} - -// --- system call instructions, in SSM Manual's table 7 --- - -// return a fresh syscall-type instruction -static code *create_syscall_instr(syscall_type t, reg_num_type r, offset_type o) -{ - syscall_instr_t si; - si.op = OTHC_O; - si.reg = r; - si.offset = o; - si.code = t; - si.func = SYS_F; - bin_instr_t bi; - bi.syscall = si; - return code_create(bi); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_exit(offset_type o) -{ - return create_syscall_instr(exit_sc, 0, o); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_pstr(reg_num_type s, offset_type o) -{ - return create_syscall_instr(print_str_sc, s, o); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_pint(reg_num_type s, offset_type o) -{ - return create_syscall_instr(print_int_sc, s, o); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_pch(reg_num_type s, offset_type o) -{ - return create_syscall_instr(print_char_sc, s, o); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_rch(reg_num_type t, offset_type o) -{ - return create_syscall_instr(read_char_sc, t, o); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_stra() -{ - return create_syscall_instr(start_tracing_sc,0,0); -} - -// Create and return a fresh instruction -// with the named mnemonic and parameters -code *code_notr() -{ - return create_syscall_instr(stop_tracing_sc,0,0); -} - -#define MINIMAL_STACK_ALLOC_IN_WORDS 12 -#define MINIMAL_STACK_ALLOC_BYTES (BYTES_PER_WORD*MINIMAL_STACK_ALLOC_IN_WORDS) - -// Set up the runtime stack for a procedure, -// where the static link is found in register $a0. -// Modifies when executed, the SP register, the FP register, -// and memory from SP to SP - MINIMAL_STACK_ALLOC_BYTES -// (inclusive) -code_seq code_save_registers_for_AR() -{ - // assume that SP is pointing to the lowest local storage already allocated - code_seq ret; - // push stack_pointer at word index 0 - 1 from current SP - ret = code_seq_singleton(code_swr(SP, SP, -1)); - // push the frame pointer (dynamic link) at word index -2 - code_seq_add_to_end(&ret, code_swr(SP, FP, -2)); - // save SP into FP register so FP points to the base of the AR - code_seq_add_to_end(&ret, code_add(0, SP, FP,ADD_F)); - // allocate the space on the stack, by subtracting from SP - code_seq_add_to_end(&ret, code_addi(SP, SP, - MINIMAL_STACK_ALLOC_BYTES)); - // push the static link at word index -3 - code_seq_add_to_end(&ret, code_swr(FP, GP, -3)); - // push the return address at word index 3 - code_seq_add_to_end(&ret, code_swr(FP, RA, -4)); - // save the registers $s0 to $s7 (inclusive) - int idx = -5; - for (int rn = GP; rn <= RA; rn++) { - code_seq_add_to_end(&ret, code_swr(FP, rn, idx--)); - } - return ret; -} - diff --git a/code.h b/code.h deleted file mode 100755 index 8fd4f2f..0000000 --- a/code.h +++ /dev/null @@ -1,230 +0,0 @@ -/* $Id: code.h,v 1.23 2024/11/10 21:09:43 leavens Exp $ */ -#ifndef _CODE_H -#define _CODE_H -#include -#include "machine_types.h" -#include "instruction.h" -#include "code_seq.h" - -// SSM assembly language instructions (that can be in linked lists) -typedef struct code_s { - struct code_s *next; - bin_instr_t instr; -} code; - -// Code creation functions below - -// --- computational format instructions from table 3 of the SSM Manual --- - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_nop(); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_add(reg_num_type t, offset_type ot, - reg_num_type s, offset_type os); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_sub(reg_num_type t, offset_type ot, - reg_num_type s, offset_type os); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_cpw(reg_num_type t, offset_type ot, - reg_num_type s, offset_type os); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_cpr(reg_num_type t, reg_num_type s); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_and(reg_num_type t, offset_type ot, - reg_num_type s, offset_type os); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_bor(reg_num_type t, offset_type ot, - reg_num_type s, offset_type os); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_nor(reg_num_type t, offset_type ot, - reg_num_type s, offset_type os); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_xor(reg_num_type t, offset_type ot, - reg_num_type s, offset_type os); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_lwr(reg_num_type t, reg_num_type s, offset_type os); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_swr(reg_num_type t, offset_type ot, reg_num_type s); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_sca(reg_num_type t, offset_type ot, - reg_num_type s, offset_type os); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_lwi(reg_num_type t, offset_type ot, - reg_num_type s, offset_type os); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_neg(reg_num_type t, offset_type ot, - reg_num_type s, offset_type os); - -// --- other computational format instructions from table 4 --- - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_lit(reg_num_type t, offset_type o, - immediate_type i); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_ari(reg_num_type r, immediate_type i); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_sri(reg_num_type r, immediate_type i); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_mul(reg_num_type s, offset_type o); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_div(reg_num_type s, offset_type o); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_cfhi(reg_num_type t, offset_type o); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_cflo(reg_num_type t, offset_type o); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_sll(reg_num_type t, offset_type o, shift_type h); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_srl(reg_num_type t, offset_type o, shift_type h); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_jmp(reg_num_type s, offset_type o); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_csi(reg_num_type s, offset_type o); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_jrel(offset_type o); - -// --- immediate format instructions from table 5 of the SSM Manual --- - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_addi(reg_num_type r, offset_type o, immediate_type i); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_andi(reg_num_type r, offset_type o, uimmed_type i); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_bori(reg_num_type r, offset_type o, uimmed_type i); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_nori(reg_num_type r, offset_type o, uimmed_type i); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_beq(reg_num_type r, offset_type o, immediate_type i); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_bgez(reg_num_type r, offset_type o, immediate_type i); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_bgtz(reg_num_type r, offset_type o, immediate_type i); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_blez(reg_num_type r, offset_type o, immediate_type i); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_bltz(reg_num_type r, offset_type o, immediate_type i); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_bne(reg_num_type r, offset_type o, immediate_type i); - -// --- jump format instructions from table 6 of the SSM Manual --- - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_jmpa(address_type a); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_call(address_type a); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_rtn(); - -// --- system calls from table 7 of the SSM Manual --- - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_exit(offset_type o); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_pstr(reg_num_type s, offset_type o); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_pint(reg_num_type s, offset_type o); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_pch(reg_num_type s, offset_type o); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_rch(reg_num_type t, offset_type o); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_stra(); - -// Create and return a fresh instruction -// with the named mnemonic and parameters -extern code *code_notr(); - -// Set up the runtime stack for a procedure, -// where the static link is found in register $a0. -// Modifies when executed, the SP register, the FP register, -// and memory from SP to SP - MINIMAL_STACK_ALLOC_BYTES -// (inclusive) -extern code_seq code_save_registers_for_AR(); - - -#endif diff --git a/code_seq.c b/code_seq.c deleted file mode 100755 index b433c4b..0000000 --- a/code_seq.c +++ /dev/null @@ -1,137 +0,0 @@ -/* $Id: code_seq.c,v 1.4 2024/11/08 21:01:43 leavens Exp $ */ -#include -#include -#include -#include "utilities.h" -#include "regname.h" -#include "code.h" -#include "code_seq.h" - - -static void code_seq_okay(code_seq seq) -{ - // seq.first and seq.last are either both null or both not null - assert((seq.first == NULL) == (seq.last == NULL)); -} - -// Return an empty code_seq -code_seq code_seq_empty() -{ - code_seq ret; - ret.first = NULL; - ret.last = NULL; - code_seq_okay(ret); - return ret; -} - -// Requires: c != NULL -// Return a code_seq containing just the given code -code_seq code_seq_singleton(code *c) -{ - code_seq ret; - ret.first = c; - ret.last = c; - code_seq_okay(ret); - return ret; -} - -// Is seq empty? -bool code_seq_is_empty(code_seq seq) -{ - code_seq_okay(seq); - return seq.first == NULL; -} - -// Requires: !code_seq_is_empty(seq) -// Return the first element of the given code sequence, seq -code *code_seq_first(code_seq seq) -{ - assert(!code_seq_is_empty(seq)); - return seq.first; -} - -// Requires: !code_seq_is_empty(seq) -// Return a new code_seq containing -// the rest of the given sequence, seq -// Note that seq is not modified -code_seq code_seq_rest(code_seq seq) -{ - assert(!code_seq_is_empty(seq)); - code *first = seq.first; - code_seq ret; - ret.first = first->next; - if (ret.first == NULL) { - ret.last = NULL; - } else { - ret.last = seq.last; - } - code_seq_okay(ret); - return ret; -} - -// Return the size (number of instructions/words) in seq -unsigned int code_seq_size(code_seq seq) -{ - unsigned int ret = 0; - while (!code_seq_is_empty(seq)) { - ret++; - seq = code_seq_rest(seq); - } - return ret; -} - -// Requires: !code_seq_is_empty(seq) -// Return the last element in the given sequence -code *code_seq_last_elem(code_seq seq) -{ - assert(!code_seq_is_empty(seq)); - return seq.last; -} - -// Requires: c != NULL && seq != NULL -// Modify seq to add the given code *c added to its end -void code_seq_add_to_end(code_seq *seq, code *c) -{ - assert(c != NULL); - if (code_seq_is_empty(*seq)) { - seq->first = c; - seq->last = c; - } else { - // assert(!code_seq_is_empty(seq)); - code *last = code_seq_last_elem(*seq); - last->next = c; - c->next = NULL; - seq->last = c; - } - code_seq_okay(*seq); -} - -// Requires: s1 != NULL && s2 != NULL -// Modifies s1 to be the concatenation of s1 followed by s2 -void code_seq_concat(code_seq *s1, code_seq s2) -{ - if (code_seq_is_empty(*s1)) { - s1->first = s2.first; - s1->last = s2.last; - } else if (code_seq_is_empty(s2)) { - ; // s1 is already their concatenation - } else { - code *last = code_seq_last_elem(*s1); - // assert(last != NULL); - last->next = s2.first; - s1->last = s2.last; - } - code_seq_okay(*s1); -} - -// Requires: out is open for writing. -// Print the instructions in the code_seq to out -// in assembly language format -void code_seq_debug_print(FILE *out, code_seq seq) -{ - while(!code_seq_is_empty(seq)) { - fprintf(out, "%s\n", - instruction_assembly_form(0, code_seq_first(seq)->instr)); - seq = code_seq_rest(seq); - } -} diff --git a/code_seq.h b/code_seq.h deleted file mode 100755 index 661715c..0000000 --- a/code_seq.h +++ /dev/null @@ -1,56 +0,0 @@ -/* $Id: code_seq.h,v 1.3 2024/11/08 21:01:43 leavens Exp $ */ -#ifndef _CODE_SEQ_H -#define _CODE_SEQ_H -#include - -// Forward declare 'code' type to avoid circular dependency -struct code_s; -typedef struct code_s code; // Declare code as a type - -// code sequences are linked lists -// with an additional last pointer to the last node -typedef struct { - code *first; - code *last; -} code_seq; - -// Return an empty code_seq -extern code_seq code_seq_empty(); - -// Return a code_seq containing just the given code -extern code_seq code_seq_singleton(code *c); - -// Is seq empty? -extern bool code_seq_is_empty(code_seq seq); - -// Requires: !code_seq_is_empty(seq) -// Return the first element of the given code sequence, seq -extern code *code_seq_first(code_seq seq); - -// Requires: !code_seq_is_empty(seq) -// Return a new code_seq containing -// the rest of the given sequence, seq -// Note that seq is not modified -extern code_seq code_seq_rest(code_seq seq); - -// Return the size (number of instructions/words) in seq -extern unsigned int code_seq_size(code_seq seq); - -// Requires: !code_seq_is_empty(seq) -// Return the last element in the given sequence -extern code *code_seq_last_elem(code_seq seq); - -// Requires: c != NULL && seq != NULL -// Modify seq to add the given code *c added to its end -extern void code_seq_add_to_end(code_seq *seq, code *c); - -// Requires: s1 != NULL && s2 != NULL -// Modifies s1 to be the concatenation of s1 followed by s2 -extern void code_seq_concat(code_seq *s1, code_seq s2); - -// Requires: out is open for writing. -// Print the instructions in the code_seq to out -// in assembly language format -extern void code_seq_debug_print(FILE *out, code_seq seq); - -#endif diff --git a/code_utils.c b/code_utils.c deleted file mode 100755 index d5c0eed..0000000 --- a/code_utils.c +++ /dev/null @@ -1,158 +0,0 @@ -// $Id: code_utils.c,v 1.8 2024/11/11 23:01:08 leavens Exp $ -#include -#include "regname.h" -#include "code.h" -#include "code_seq.h" -#include "code_utils.h" - -#define MINIMAL_STACK_ALLOC_IN_WORDS 4 -#define SAVED_SP_OFFSET (-1) -#define SAVED_FP_OFFSET (-2) -#define SAVED_STATIC_LINK_OFFSET (-3) -#define SAVED_RA_OFFSET (-4) - -// Requires: t != SP && s != SP -// Return a code sequence that copies the value from register s -// into register t, using the top of the stack as a temporary. -// Modifies: t (and temporarily, SP) -code_seq code_utils_copy_regs(reg_num_type t, reg_num_type s) -{ - assert(t != SP); - assert(s != SP); - code_seq ret = code_seq_singleton(code_cpr(t, s)); - // If the SSM didn't have the cpr instruction - // one could use the top of the stack as a temporary, as follows - /* - code_seq ret = code_utils_allocate_stack_space(1); - code_seq_add_to_end(&ret, code_swr(SP, 0, s)); - code_seq_add_to_end(&ret, code_lwr(t, SP, 0)); - code_seq_concat(&ret, code_utils_deallocate_stack_space(1)); - */ - return ret; -} - -// Return a code sequence that loads the static link -// (which is SAVEDSTATIC_LINK_OFFSET from the address contained in register b, -// and place it in register rt. -// Modifies only register rt. -code_seq code_utils_load_static_link_into_reg(reg_num_type t, - reg_num_type b) -{ - code_seq ret = code_seq_singleton(code_lwr(t, b, SAVED_STATIC_LINK_OFFSET)); - return ret; -} - -// Requires: reg != FP && reg != RA -// Modifies only: register reg -// Return a code sequence that will put the address that corresponds to the -// frame pointer for the given number of scopes outward in register reg -code_seq code_utils_compute_fp(reg_num_type reg, unsigned int levelsOut) -{ - assert(reg != FP && reg != RA); - code_seq ret - = code_utils_copy_regs(reg, FP); - while (levelsOut > 0) { - code_seq_concat(&ret, - code_utils_load_static_link_into_reg(reg, reg)); - levelsOut--; - } - return ret; -} - -// Requires: words >= 0 -// Allocate the given number of words on the runtime stack -// Modifies when executed: SP register -// At the end of exeuction, SP holds the address of the last allocated word. -// (So, if the call allocates only one word, then SP addresses that word.) -code_seq code_utils_allocate_stack_space(immediate_type words) -{ - assert(words >= 0); - code_seq ret = code_seq_singleton(code_sri(SP, words)); - return ret; -} - -// Requires: words >= 0 -// Deallocate the given number of words from the runtime stack -// Modifies when executed: SP register -code_seq code_utils_deallocate_stack_space(immediate_type words) -{ - assert(words >= 0); - code_seq ret = code_seq_singleton(code_ari(SP, words)); - return ret; -} - -// Requires: $r3 holds the static link (from the current AR) -// Set up the runtime stack for a procedure, -// where the static link is found in register $r3. -// Modifies when executed, the SP register, the FP register, -// and memory from SP to SP - MINIMAL_STACK_ALLOC_IN_WORDS -// (inclusive) -code_seq code_utils_save_registers_for_AR() -{ - // assume that SP is pointing to the lowest local storage already allocated - code_seq ret; - // save SP onto the top of the stack - ret = code_seq_singleton(code_swr(SP, SAVED_SP_OFFSET, SP)); - // save FP (dynamic link) onto top of the stack - code_seq_add_to_end(&ret, code_swr(SP, SAVED_FP_OFFSET, FP)); - // save the static link from $r3 onto top of stack - code_seq_add_to_end(&ret, code_swr(SP, SAVED_STATIC_LINK_OFFSET, 3)); - // save the RA register on the stack - code_seq_add_to_end(&ret, code_swr(SP, SAVED_RA_OFFSET, RA)); - // save SP into the FP register so FP points to the base of the AR - // can't use code_utils_copy_regs for this because SP is involved - code_seq_add_to_end(&ret, code_cpr(FP, SP)); - /* the following can be used if there is no cpr instruction: - code_seq_add_to_end(&ret, SAVED_RA_OFFSET-1, SP)); - code_seq_add_to_end(&ret, code_lwr(FP, SP, SAVED_RA_OFFSET-1)); - */ - - // allocate the space on the stack for the saved registers - code_seq_concat(&ret, - code_utils_allocate_stack_space(MINIMAL_STACK_ALLOC_IN_WORDS)); - - return ret; -} - -// Restore the callee's registers from the places they are saved on the stack. -// This restores the SP, FP, and RA registers only. -// (It is assumed that the stack already holds the static link address) -// Modifies when executed, the SP register, the FP register, the RA register. -// restoring their saved contents from memory -// (as saved by code_utils_save_registers_for_AR) -code_seq code_utils_restore_registers_from_AR() -{ - code_seq ret = code_seq_empty(); - // restore the RA register - code_seq_add_to_end(&ret, - code_lwr(RA, FP, SAVED_RA_OFFSET)); - // save the SP register in $r3 temporarily, to not violate VM's invariant - code_seq_add_to_end(&ret, code_lwr(3, FP, SAVED_SP_OFFSET)); - // restore the FP (dynamic link) register - code_seq_add_to_end(&ret, code_lwr(FP, FP, SAVED_FP_OFFSET)); - // deallocate the space for variables and constants by restoring old SP - code_seq_add_to_end(&ret, code_cpr(SP, 3)); - return ret; -} - -// Set up the program's stack as if it were in a call (from the OS) -code_seq code_utils_set_up_program() -{ - code_seq ret; - // set up the saved registers - ret = code_utils_copy_regs(3, FP); // save FP into $r3 - code_seq_concat(&ret, code_utils_save_registers_for_AR()); - // use what will be the new FP as the saved static link - code_seq_add_to_end(&ret, code_swr(FP, SAVED_STATIC_LINK_OFFSET, FP)); - return ret; -} - -// Tear down the program's stack and exit (with exit code 0). -code_seq code_utils_tear_down_program() -{ - code_seq ret; - // restore the saved registers to their initial state - ret = code_utils_restore_registers_from_AR(); - code_seq_add_to_end(&ret, code_exit(0)); - return ret; -} diff --git a/code_utils.h b/code_utils.h deleted file mode 100755 index d81da30..0000000 --- a/code_utils.h +++ /dev/null @@ -1,59 +0,0 @@ -// $Id: code_utils.h,v 1.4 2024/11/10 22:06:54 leavens Exp $ -// Some convenience functions that may help with code generation -#ifndef _CODE_UTILS_H -#define _CODE_UTILS_H -#include "code_seq.h" - -// Requires: t != SP && s != SP -// Return a code sequence that copies the value from register s -// into register t, using the top of the stack as a temporary. -// Modifies: t (and temporarily, SP) -extern code_seq code_utils_copy_regs(reg_num_type t, reg_num_type s); - -// Return a code sequence that loads the static link -// (which is SAVEDSTATIC_LINK_OFFSET from the address contained in register b, -// and place it in register rt. -// Modifies only register rt. -extern code_seq code_utils_load_static_link_into_reg(reg_num_type t, - reg_num_type b); - -// Requires: reg != FP && reg != RA -// Modifies only: register reg -// Return a code sequence that will put the address that corresponds to the -// frame pointer for the given number of scopes outward in register reg -extern code_seq code_utils_compute_fp(reg_num_type reg, unsigned int levelsOut); - -// Requires: words >= 0 -// Allocate the given number of words on the runtime stack -// Modifies when executed: SP register -// At the end of exeuction, SP holds the address of the last allocated word. -// (So, if the call allocates only one word, then SP addresses that word.) -extern code_seq code_utils_allocate_stack_space(immediate_type words); - -// Requires: words >= 0 -// Deallocate the given number of words from the runtime stack -// Modifies when executed: SP register -extern code_seq code_utils_deallocate_stack_space(immediate_type words); - -// Set up the runtime stack for a procedure, -// where the static link is found in register $r3. -// Modifies when executed, the SP register, the FP register, -// and memory from SP to SP - MINIMAL_STACK_ALLOC_IN_WORDS -// (inclusive) -extern code_seq code_utils_save_registers_for_AR(); - -// Restore the callee's registers from the places they are saved on the stack. -// This restores the SP, FP, and RA registers only. -// (It is assumed that the stack already holds the static link address) -// Modifies when executed, the SP register, the FP register, the RA register. -// restoring their saved contents from memory -// (as saved by code_utils_save_registers_for_AR) -extern code_seq code_utils_restore_registers_from_AR(); - -// Set up the program's stack as if it were in a call (from the OS) -extern code_seq code_utils_set_up_program(); - -// Tear down the program's stack and exit (with exit code 0). -extern code_seq code_utils_tear_down_program(); - -#endif diff --git a/compiler_main.c b/compiler_main.c deleted file mode 100755 index bb1c25a..0000000 --- a/compiler_main.c +++ /dev/null @@ -1,120 +0,0 @@ -/* $Id: compiler_main.c,v 1.18 2024/11/13 20:33:01 leavens Exp $ */ -#include -#include -#include -#include "bof.h" -#include "lexer.h" -#include "parser.h" -#include "unparser.h" -#include "ast.h" -#include "utilities.h" -#include "symtab.h" -#include "scope_check.h" -#include "gen_code.h" - -/* Print a usage message on stderr - and exit with failure. */ -static void usage(const char *cmdname) -{ - fprintf(stderr, "Usage: %s %s\n %s %s\n %s %s\n", - cmdname, "-l codeFilename.spl", - cmdname, "-u codeFilename.spl", - cmdname, " codeFilename.spl"); - exit(EXIT_FAILURE); -} - -// If the -l option is used, then output the tokens -// in the give file name to stdout, -// otherwise unparse the program given in the file name argument to stdout -int main(int argc, char *argv[]) -{ - // should the lexer's tokens be shown? - bool lexer_print_output = false; - // should the unparse of the AST be shown? - bool parser_unparse = false; - const char *cmdname = argv[0]; - argc--; - argv++; - // possible options: -l, and -u - while (argc > 0 && strlen(argv[0]) >= 2 && argv[0][0] == '-') - { - if (strcmp(argv[0], "-l") == 0) - { - lexer_print_output = true; - argc--; - argv++; - } - else if (strcmp(argv[0], "-u") == 0) - { - parser_unparse = true; - argc--; - argv++; - } - else - { - // bad option! - usage(cmdname); - } - } - - // give usage message if -l and other options are used - if (lexer_print_output && parser_unparse) - { - usage(cmdname); - } - - // must have a file name - if (argc <= 0 || (strlen(argv[0]) >= 2 && argv[0][0] == '-')) - { - usage(cmdname); - } - - // the name of the file - char *filename = argv[0]; - char *lastdot = strrchr(filename, '.'); - if (lastdot == NULL || strcmp(lastdot, ".spl") != 0) - { - bail_with_error("filename argument must end in .spl not %s", - filename); - } - char boffilename[BUFSIZ]; - strncpy(boffilename, filename, BUFSIZ); - int len = strlen(boffilename); - assert(len < BUFSIZ); // it has to fit! - strncpy(boffilename + (len - 4), ".bof", 5); - // debug_print("Output going to %s\n", boffilename); - - if (lexer_print_output) - { - // with the lexer_print_output option, nothing else is done - lexer_init(filename); - lexer_output(); - return EXIT_SUCCESS; - } - - // otherwise (if not lexer_print_outout) continue to parse etc. - block_t progast = parseProgram(filename); - - if (parser_unparse) - { - unparseProgram(stdout, progast); - } - - // build symbol table and... - symtab_initialize(); - // check for duplicate declarations - // and record id-use information in the AST - scope_check_program(&progast); - - if (parser_unparse) - { - return EXIT_SUCCESS; - } - - // generate code from the ASTs - gen_code_initialize(); - BOFFILE bf = bof_write_open(boffilename); - gen_code_program(bf, progast); - - return EXIT_SUCCESS; -} diff --git a/file_location.c b/file_location.c deleted file mode 100755 index c7ceae7..0000000 --- a/file_location.c +++ /dev/null @@ -1,34 +0,0 @@ -/* $Id: file_location.c,v 1.2 2023/11/13 05:13:47 leavens Exp $ */ -#include -#include -#include -#include "file_location.h" -#include "utilities.h" - -// Requires: filename != NULL -// Return a (pointer to a) fresh file_location with the given -// information -file_location *file_location_make(const char *filename, - unsigned int line) -{ - file_location *ret = (file_location *) malloc(sizeof(file_location)); - if (ret == NULL) { - bail_with_error("Could not allocate space for a file_location!"); - } - ret->filename = filename; - ret->line = line; - return ret; -} - -// Requires: fl != NULL -// Return a (pointer to a) fresh copy of fl -file_location *file_location_copy(file_location *fl) -{ - file_location *ret = (file_location *) malloc(sizeof(file_location)); - if (ret == NULL) { - bail_with_error("Could not allocate space for a file_location!"); - } - ret->filename = fl->filename; - ret->line = fl->line; - return ret; -} diff --git a/file_location.h b/file_location.h deleted file mode 100755 index 19d1931..0000000 --- a/file_location.h +++ /dev/null @@ -1,21 +0,0 @@ -/* $Id: file_location.h,v 1.2 2023/11/13 05:13:48 leavens Exp $ */ -#ifndef _FILE_LOCATION_H -#define _FILE_LOCATION_H - -// location in a source file (useful for error messages) -typedef struct { - const char *filename; - unsigned int line; // of first token -} file_location; - -// Requires: filename != NULL -// Return a (pointer to a) fresh file_location with the given -// information -extern file_location *file_location_make(const char *filename, - unsigned int line); - -// Requires: fl != NULL -// Return a (pointer to a) fresh copy of fl -extern file_location *file_location_copy(file_location *fl); - -#endif diff --git a/gen_code.c b/gen_code.c deleted file mode 100644 index 60b5162..0000000 --- a/gen_code.c +++ /dev/null @@ -1,634 +0,0 @@ -#include "gen_code.h" - -#include -#include -#include "spl.tab.h" -#include "ast.h" -#include "code.h" -#include "id_use.h" -#include "literal_table.h" -#include "gen_code.h" -#include "utilities.h" -#include "regname.h" - -#define STACK_SPACE 4096 - -// Initialize the code generator -void gen_code_initialize() -{ - literal_table_initialize(); -} - -// Requires: bf if open for writing in binary -// and prior to this scope checking and type checking have been done. -// Write all the instructions in cs to bf in order -static void gen_code_output_seq(BOFFILE bf, code_seq cs) -{ - while (!code_seq_is_empty(cs)) - { - bin_instr_t inst = code_seq_first(cs)->instr; - instruction_write_bin_instr(bf, inst); - cs = code_seq_rest(cs); - } -} - -// Return a header appropriate for the give code -static BOFHeader gen_code_program_header(code_seq main_cs) -{ - BOFHeader ret; - - // magic - strncpy(ret.magic, "MAGIC", 4); - - // text start address - ret.text_start_address = 0; - - // text length - ret.text_length = code_seq_size(main_cs) * BYTES_PER_WORD; - - // data start address - int dsa = MAX(ret.text_length, 1024) + BYTES_PER_WORD; - ret.data_start_address = dsa; - - // data length - ret.data_length = literal_table_size() * BYTES_PER_WORD; - - // stack bottom address - int sba = dsa + ret.data_length + STACK_SPACE; - ret.stack_bottom_addr = sba; - - return ret; -} - -static void gen_code_output_literals(BOFFILE bf) -{ - literal_table_start_iteration(); - while (literal_table_iteration_has_next()) - { - word_type w = literal_table_iteration_next(); - // debug_print("Writing literal %f to BOF file\n", w); - bof_write_word(bf, w); - } - literal_table_end_iteration(); -} - -// Requires: bf is open for writing in binary -// Write the program's BOFFILE to bf -static void gen_code_output_program(BOFFILE bf, code_seq main_cs) -{ - BOFHeader bfh = gen_code_program_header(main_cs); - bof_write_header(bf, bfh); - gen_code_output_seq(bf, main_cs); - gen_code_output_literals(bf); - bof_close(bf); -} - -// Requires: bf if open for writing in binary -// Generate code for prog into bf -void gen_code_program(BOFFILE bf, block_t prog) -{ - code_seq main_cs; - // We want to make the main program's AR look like all blocks... so: - // allocate space and initialize any variables - main_cs = gen_code_seq_var_decls(prog.var_decls);//gen_code_seq_var_decls’ - //int vars_len_in_bytes = (code_seq_size(main_cs) / 2) * BYTES_PER_WORD; variable that has been muted based on line 101-104 - - // there is no static link for the program as a whole, - // so nothing to do for saving FP into A0 as would be done for a block - code_seq_concat(&main_cs, code_save_registers_for_AR()); - code_seq_concat(&main_cs, - gen_code_seq_stmts(prog.stmts));// Big difference from the Float calculator. Use of gen_code_stmts rather than gen_code_seq_stmt - /*code_seq_concat(&main_cs, - code_restore_registers_from_AR()); - code_seq_concat(&main_cs, - code_deallocate_stack_space(vars_len_in_bytes));*/ // this section has been muted - code_seq_add_to_end(&main_cs, code_exit(0));// Over here I added a 0 into the code_ exit because of the instruction exit offset should be 0 - gen_code_output_program(bf, main_cs); -} - -// Generate code for the var_decls_t vds to out -// There are 2 instructions generated for each identifier declared -// (one to allocate space and another to initialize that space) -code_seq gen_code_seq_var_decls(var_decls_t vds)// the name was modified -{ - code_seq ret = code_seq_empty(); - var_decl_t *vdp = vds.var_decls; - while (vdp != NULL) - { - // generate these in reverse order, - // so the addressing offsets work properly - code_seq temp = gen_code_seq_var_decl(*vdp); // Store the result in a variable - code_seq_concat(&temp, ret); // Just call code_seq_concat without assigning to ret - vdp = vdp->next; - } - return ret; -} - -// Generate code for a single , vd, -// There are 2 instructions generated for each identifier declared -// (one to allocate space and another to initialize that space) -code_seq gen_code_seq_var_decl(var_decl_t vd) -{ - return /*gen_code_idents(vd.idents, vd.type);*/ gen_code_seq_idents(vd.ident_list ); -} - -// Generate code for the identififers in idents with type vt -// in reverse order (so the first declared are allocated last). -// There are 2 instructions generated for each identifier declared -// (one to allocate space and another to initialize that space) -code_seq gen_code_seq_idents(ident_list_t idl) // this was changed+ modified compared to float calculato - -{ - /* code_seq ret = code_seq_empty(); - //ident_t *idp = idents.idents; - ident_t *idp = idl.start; - while (idp != NULL) - { - code_seq alloc_and_init = code_seq_singleton(code_addi(SP, SP, -BYTES_PER_WORD)); - switch (vt) - { - case float_te: - alloc_and_init = code_seq_add_to_end(alloc_and_init, - code_fsw(SP, 0, 0)); - break; - case bool_te: - alloc_and_init = code_seq_add_to_end(alloc_and_init, - code_sw(SP, 0, 0)); - break; - default: - bail_with_error("Bad type_exp_e (%d) passed to gen_code_idents!", - vt); - break; - } - // Generate these in revese order, - // so addressing works propertly - ret = code_seq_concat(alloc_and_init, ret); - idp = idp->next; - } - return ret;*/ - code_seq gen_code_seq_idents(ident_list_t idl) - { - code_seq ret = code_seq_empty(); // Start with an empty code sequence - ident_t *idp = idl.start; // Start from the first identifier in the list - - while (idp != NULL) - { - // Generate the code to allocate space for this identifier - // We assume you have a function gen_code_seq_alloc_ident that generates allocation code - code_seq alloc_and_init = gen_code_seq_alloc_ident(idp); - - // Add the allocation and initialization code in reverse order - code_seq_concat(&alloc_and_init, ret); // Concatenate the allocation code with the result - - // Move to the next identifier in the list - idp = idp->next; - } - - return ret; - } -} - -// Generate code for stmt -code_seq gen_code_stmt(stmt_t stmt) -{ - switch (stmt.stmt_kind) - { - case assign_stmt: - return /*gen_code_assign_stmt(stmt.data.assign_stmt);*/ gen_code_seq_assign_stmt(stmt.data.assign_stmt); - break; - /*case begin_stmt: - return gen_code_begin_stmt(stmt.data.begin_stmt); - break;*/ - case call_stmt: - return gen_code_seq_call_stmt(stmt.data.call_stmt); - break; - case if_stmt: - return gen_code_seq_if_stmt(stmt.data.if_stmt); - break; - case while_stmt: - return gen_code_seq_while_stmt(stmt.data.while_stmt); - break; - case read_stmt: - return gen_code_seq_read_stmt(stmt.data.read_stmt); - break; - case write_stmt: - return gen_code_write_stmt(stmt.data.write_stmt); - break; - default: - bail_with_error("Call to gen_code_stmt with an AST that is not a statement!"); - break; - } - // The following can never execute, but this quiets gcc's warning - return code_seq_empty(); -} - -// Generate code for stmt -code_seq gen_code_seq_assign_stmt(assign_stmt_t stmt) -{ - // can't call gen_code_ident, - // since stmt.name is not an ident_t - code_seq ret; - // put value of expression in $v0 - ret = gen_code_expr(*(stmt.expr)); - assert(stmt.idu != NULL); - assert(id_use_get_attrs(stmt.idu) != NULL); - type_exp_e typ = id_use_get_attrs(stmt.idu)->type; - ret = code_seq_concat(ret, code_pop_stack_into_reg(V0, typ)); - // put frame pointer from the lexical address of the name - // (using stmt.idu) into $t9 - ret = code_seq_concat(ret, - code_compute_fp(T9, stmt.idu->levelsOutward)); - unsigned int offset_count = id_use_get_attrs(stmt.idu)->offset_count; - assert(offset_count <= USHRT_MAX); // it has to fit! - switch (id_use_get_attrs(stmt.idu)->type) - { - case float_te: - ret = code_seq_add_to_end(ret, - code_fsw(T9, V0, offset_count)); - break; - case bool_te: - ret = code_seq_add_to_end(ret, - code_sw(T9, V0, offset_count)); - break; - default: - bail_with_error("Bad var_type (%d) for ident in assignment stmt!", - id_use_get_attrs(stmt.idu)->type); - break; - } - return ret; -} -// Generate code for stmt -code_seq gen_code_seq_call_stmt(call_stmt_t stmt) -{ - // can't call gen_code_ident, - // since stmt.name is not an ident_t - code_seq ret; - ret = gen_code_expr(*(stmt.expr)); - return ret; -} - -// Generate code for stmt -code_seq gen_code_begin_stmt(begin_stmt_t stmt) -{ - code_seq ret; - // allocate space and initialize any variables in block - ret = gen_code_var_decls(stmt.var_decls); - int vars_len_in_bytes = (code_seq_size(ret) / 2) * BYTES_PER_WORD; - // in FLOAT, surrounding scope's base is FP, so that is the static link - ret = code_seq_add_to_end(ret, code_add(0, FP, A0)); - ret = code_seq_concat(ret, code_save_registers_for_AR()); - ret = code_seq_concat(ret, gen_code_seq_stmts(stmt.stmts)); - ret = code_seq_concat(ret, code_restore_registers_from_AR()); - ret = code_seq_concat(ret, code_deallocate_stack_space(vars_len_in_bytes)); - return ret; -} - -// Generate code for the list of statments given by stmts -code_seq gen_code_seq_stmts(stmts_t stmts) -{ - code_seq ret = code_seq_empty(); - stmt_t *sp = stmts.stmts; - while (sp != NULL) - { - ret = code_seq_concat(ret, gen_code_stmt(*sp)); - sp = sp->next; - } - return ret; -} - -// Generate code for stmt -code_seq gen_code_seq_while_stmt(while_stmt_t stmt) -{ - // can't call gen_code_ident, - // since stmt.name is not an ident_t - code_seq ret; - ret = gen_code_expr(*(stmt.expr)); - return ret; -} - -// Generate code for the if-statment given by stmt -code_seq gen_code_if_stmt(if_stmt_t stmt) -{ - // put truth value of stmt.expr in $v0 - code_seq ret = gen_code_expr(stmt.expr); - ret = code_seq_concat(ret, code_pop_stack_into_reg(V0, bool_te)); - code_seq cbody = gen_code_stmt(*(stmt.body)); - int cbody_len = code_seq_size(cbody); - // skip over body if $v0 contains false - ret = code_seq_add_to_end(ret, - code_beq(V0, 0, cbody_len)); - return code_seq_concat(ret, cbody); -} - -// Generate code for the read statment given by stmt -code_seq gen_code_read_stmt(read_stmt_t stmt) -{ - // put number read into $v0 - code_seq ret = code_seq_singleton(code_rch()); - // put frame pointer from the lexical address of the name - // (using stmt.idu) into $t9 - assert(stmt.idu != NULL); - ret = code_seq_concat(ret, - code_compute_fp(T9, stmt.idu->levelsOutward)); - assert(id_use_get_attrs(stmt.idu) != NULL); - unsigned int offset_count = id_use_get_attrs(stmt.idu)->offset_count; - assert(offset_count <= USHRT_MAX); // it has to fit! - ret = code_seq_add_to_end(ret, - code_seq_singleton(code_fsw(T9, V0, offset_count))); - return ret; -} - -// Generate code for the write statment given by stmt. -code_seq gen_code_write_stmt(write_stmt_t stmt) -{ - // put the result into $a0 to get ready for PCH - code_seq ret = gen_code_expr(stmt.expr); - ret = code_seq_concat(ret, code_pop_stack_into_reg(A0, float_te)); - ret = code_seq_add_to_end(ret, code_pflt()); - return ret; -} - -// Generate code for the expression exp -// putting the result on top of the stack, -// and using V0 and AT as temporary registers -// May also modify SP, HI,LO when executed -code_seq gen_code_expr(expr_t exp) -{ - switch (exp.expr_kind) - { - case expr_bin_op: - return gen_code_binary_op_expr(exp.data.binary); - break; - case expr_ident: - return gen_code_ident(exp.data.ident); - break; - case expr_number: - return gen_code_number(exp.data.number); - break; - case expr_logical_not: - return gen_code_logical_not_expr(*(exp.data.logical_not)); - break; - default: - bail_with_error("Unexpected expr_kind_e (%d) in gen_code_expr", - exp.expr_kind); - break; - } - // never happens, but suppresses a warning from gcc - return code_seq_empty(); -} - -// Generate code for the expression exp -// putting the result on top of the stack, -// and using V0 and AT as temporary registers -// May also modify SP, HI,LO when executed -code_seq gen_code_binary_op_expr(binary_op_expr_t exp) -{ - // put the values of the two subexpressions on the stack - code_seq ret = gen_code_expr(*(exp.expr1)); - ret = code_seq_concat(ret, gen_code_expr(*(exp.expr2))); - // check the types match - type_exp_e t1 = ast_expr_type(*(exp.expr1)); - assert(ast_expr_type(*(exp.expr2)) == t1); - // do the operation, putting the result on the stack - ret = code_seq_concat(ret, gen_code_op(exp.op, t1)); - return ret; -} - -// Generate code to apply op to the -// 2nd from top and top of the stack, -// putting the result on top of the stack in their place, -// and using V0 and AT as temporary registers -// Modifies SP when executed -code_seq gen_code_op(token_t op, type_exp_e typ) -{ - switch (op.code) - { - case eqsym: - case neqsym: - case ltsym: - case leqsym: - case gtsym: - case geqsym: - return gen_code_rel_op(op, typ); - break; - case plussym: - case minussym: - case multsym: - case divsym: - assert(typ == float_te); - return gen_code_arith_op(op); - break; - default: - bail_with_error("Unknown token code (%d) in gen_code_op", - op.code); - break; - } - return code_seq_empty(); -} - -// Generate code to apply the floating-point arith_op to the -// 2nd from top and top of the stack, -// putting the result on top of the stack in their place, -// and using V0 and AT as temporary registers -// Also modifies SP when executed -code_seq gen_code_arith_op(token_t arith_op) -{ - // load top of the stack (the second operand) into AT - code_seq ret = code_pop_stack_into_reg(AT, float_te); - // load next element of the stack into V0 - ret = code_seq_concat(ret, code_pop_stack_into_reg(V0, float_te)); - - code_seq do_op = code_seq_empty(); - switch (arith_op.code) - { - case plussym: - do_op = code_seq_add_to_end(do_op, code_fadd(V0, AT, V0)); - break; - case minussym: - do_op = code_seq_add_to_end(do_op, code_fsub(V0, AT, V0)); - break; - case multsym: - do_op = code_seq_add_to_end(do_op, code_fmul(V0, AT, V0)); - break; - case divsym: - do_op = code_seq_add_to_end(do_op, code_fdiv(V0, AT, V0)); - break; - default: - bail_with_error("Unexpected arithOp (%d) in gen_code_arith_op", - arith_op.code); - break; - } - do_op = code_seq_concat(do_op, code_push_reg_on_stack(V0, float_te)); - return code_seq_concat(ret, do_op); -} - -// Generate code for the rel_op -// applied to 2nd from top and top of the stack, -// putting the result on top of the stack in their place, -// and using V0 and AT as temporary registers -// Also modifies SP when executed -code_seq gen_code_rel_op(token_t rel_op, type_exp_e typ) -{ - // load top of the stack (the second operand) into AT - code_seq ret = code_pop_stack_into_reg(AT, typ); - // load next element of the stack into V0 - ret = code_seq_concat(ret, code_pop_stack_into_reg(V0, typ)); - - // start out by doing the comparison - // and skipping the next 2 instructions if it's true - code_seq do_op = code_seq_empty(); - switch (rel_op.code) - { - case eqsym: - if (typ == float_te) - { - do_op = code_seq_singleton(code_bfeq(V0, AT, 2)); - } - else - { - do_op = code_seq_singleton(code_beq(V0, AT, 2)); - } - break; - case neqsym: - if (typ == float_te) - { - do_op = code_seq_singleton(code_bfne(V0, AT, 2)); - } - else - { - do_op = code_seq_singleton(code_bne(V0, AT, 2)); - } - break; - case ltsym: - if (typ == float_te) - { - do_op = code_seq_singleton(code_fsub(V0, AT, V0)); - do_op = code_seq_add_to_end(do_op, code_bfltz(V0, 2)); - } - else - { - do_op = code_seq_singleton(code_sub(V0, AT, V0)); - do_op = code_seq_add_to_end(do_op, code_bltz(V0, 2)); - } - break; - case leqsym: - if (typ == float_te) - { - do_op = code_seq_singleton(code_fsub(V0, AT, V0)); - do_op = code_seq_add_to_end(do_op, code_bflez(V0, 2)); - } - else - { - do_op = code_seq_singleton(code_sub(V0, AT, V0)); - do_op = code_seq_add_to_end(do_op, code_blez(V0, 2)); - } - break; - case gtsym: - if (typ == float_te) - { - do_op = code_seq_singleton(code_fsub(V0, AT, V0)); - do_op = code_seq_add_to_end(do_op, code_bfgtz(V0, 2)); - } - else - { - do_op = code_seq_singleton(code_sub(V0, AT, V0)); - do_op = code_seq_add_to_end(do_op, code_bgtz(V0, 2)); - } - break; - case geqsym: - if (typ == float_te) - { - do_op = code_seq_singleton(code_fsub(V0, AT, V0)); - do_op = code_seq_add_to_end(do_op, code_bfgez(V0, 2)); - } - else - { - do_op = code_seq_singleton(code_sub(V0, AT, V0)); - do_op = code_seq_add_to_end(do_op, code_bgez(V0, 2)); - } - break; - default: - bail_with_error("Unknown token code (%d) in gen_code_rel_op", - rel_op.code); - break; - } - ret = code_seq_concat(ret, do_op); - // rest of the code for the comparisons - ret = code_seq_add_to_end(ret, code_add(0, 0, AT)); // put false in AT - ret = code_seq_add_to_end(ret, code_beq(0, 0, 1)); // skip next instr - ret = code_seq_add_to_end(ret, code_addi(0, AT, 1)); // put true in AT - ret = code_seq_concat(ret, code_push_reg_on_stack(AT, bool_te)); - return ret; -} - -// Generate code to put the value of the given identifier -// on top of the stack -// Modifies T9, V0, and SP when executed -code_seq gen_code_ident(ident_t id) -{ - assert(id.idu != NULL); - code_seq ret = code_compute_fp(T9, id.idu->levelsOutward); - assert(id_use_get_attrs(id.idu) != NULL); - unsigned int offset_count = id_use_get_attrs(id.idu)->offset_count; - assert(offset_count <= USHRT_MAX); // it has to fit! - type_exp_e typ = id_use_get_attrs(id.idu)->type; - if (typ == float_te) - { - ret = code_seq_add_to_end(ret, - code_flw(T9, V0, offset_count)); - } - else - { - ret = code_seq_add_to_end(ret, - code_lw(T9, V0, offset_count)); - } - return code_seq_concat(ret, code_push_reg_on_stack(V0, typ)); -} - -// Generate code to put the given number on top of the stack -// Modifies V0 when executed -code_seq gen_code_number(number_t num) -{ - unsigned int global_offset = literal_table_lookup(num.text, num.value); - return code_seq_concat(code_seq_singleton(code_flw(GP, V0, global_offset)), - code_push_reg_on_stack(V0, float_te)); -} - -// Generate code for the expression exp -// putting the result on top of the stack, -// and using V0 and AT as temporary registers -// May also modify SP, HI,LO when executed -code_seq gen_code_logical_not_expr(expr_t exp) -{ - code_seq ret = gen_code_expr(exp); - ret = code_seq_concat(ret, code_pop_stack_into_reg(AT, bool_te)); - // if 0 skip next 2 instructions - ret = code_seq_add_to_end(ret, code_beq(0, AT, 2)); - // it was 1, so put 0 in AT - ret = code_seq_add_to_end(ret, code_add(0, 0, AT)); - // and skip the next instruction - ret = code_seq_add_to_end(ret, code_beq(0, 0, 1)); - // put 1 in AT - ret = code_seq_add_to_end(ret, code_addi(0, AT, 1)); - // push the result on the stack - ret = code_seq_concat(ret, code_push_reg_on_stack(AT, bool_te)); - return ret; -} -/*Brand new function responsible for generating the code sequence that allocates space for a variable (identifier) on the stack and initializes it with a default value, typically 0 */ -code_seq gen_code_seq_alloc_ident(ident_t *idp) -{ - code_seq ret = code_seq_empty(); // Start with an empty code sequence - - // Assuming that each identifier requires 4 bytes of space - // (adjust this based on your VM's size for each variable) - int size_of_ident = 4; // Adjust the size if necessary - - // 1. Allocate space by subtracting from the stack pointer (SP) - ret = code_seq_add_to_end(ret, code_addi(SP, SP, -size_of_ident)); - - // 2. Initialize the identifier (e.g., set it to 0) - // Assuming that a register 'zero' holds the value 0 - ret = code_seq_add_to_end(ret, code_swr(SP, zero, 0)); // Store 0 into the allocated space - - return ret; // Return the code sequence -} \ No newline at end of file diff --git a/gen_code.h b/gen_code.h deleted file mode 100644 index 04b3301..0000000 --- a/gen_code.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef _GEN_code_seq_H -#define _GEN_code_seq_H -#include -#include "ast.h" -#include "bof.h" -#include "instruction.h" -#include "code_seq.h" - -// Initialize the code_seq generator -extern void gen_code_seq_initialize(); - -// Requires: bf if open for writing in binary -// Generate code_seq for the given AST -extern void gen_code_seq_program(BOFFILE bf, block_t prog); - -// Requires: bf if open for writing in binary -// Generate code_seq for prog into bf -extern void gen_code_seq_program(BOFFILE bf, block_t prog); - -// Generate code_seq for the var_decls_t vds to out -// There are 2 instructions generated for each identifier declared -// (one to allocate space and another to initialize that space) -extern code_seq gen_code_seq_var_decls(var_decls_t vds); - -// Generate code_seq for a single , vd, -// There are 2 instructions generated for each identifier declared -// (one to allocate space and another to initialize that space) -extern code_seq gen_code_seq_var_decl(var_decl_t vd); - -// Generate code_seq for the identifiers in idents with type t -// in reverse order (so the first declared are allocated last). -// There are 2 instructions generated for each identifier declared -// (one to allocate space and another to initialize that space) -extern code_seq gen_code_seq_idents(ident_list_t idents); - -// Generate code_seq for stmt -extern code_seq gen_code_seq_stmt(stmt_t stmt); - -// Generate code_seq for assign stmt -extern code_seq gen_code_seq_assign_stmt(assign_stmt_t stmt); - -//Generate code_seq for call stmt -extern code_seq gen_code_seq_call_stmt(call_stmt_t stmt); - -// Generate code_seq for the list of statements given by stmts to out -extern code_seq gen_code_seq_stmts(stmts_t stmts); - -//Generate code_seq for while stmt -extern code_seq gen_code_seq_while_stmt(while_stmt_t stmt); - -// Generate code_seq for the if-statement given by stmt -extern code_seq gen_code_seq_if_stmt(if_stmt_t stmt); - -// Generate code_seq for the read statement given by stmt -extern code_seq gen_code_seq_read_stmt(read_stmt_t stmt); - -// Generate code_seq for the write statement given by stmt. -extern code_seq gen_code_seq_print_stmt(print_stmt_t stmt); - -// Generate code_seq for the expression exp -// putting the result on top of the stack, -// and using V0 and AT as temporary registers -// May also modify SP, HI,LO when executed -extern code_seq gen_code_seq_expr(expr_t exp); - -// Generate code_seq for the expression exp -// putting the result on top of the stack, -// and using V0 and AT as temporary registers -// May also modify SP, HI,LO when executed -extern code_seq gen_code_seq_binary_op_expr(binary_op_expr_t exp); - -// Generate code_seq to apply the floating-point arith_op to the -// 2nd from top and top of the stack, -// putting the result on top of the stack in their place, -// and using V0 and AT as temporary registers -// Also modifies SP when executed -extern code_seq gen_code_seq_arith_op(token_t arith_op); - -// Generate code_seq for the rel_op -// applied to 2nd from top and top of the stack, -// putting the result on top of the stack in their place, -// and using V0 and AT as temporary registers -// Also modifies SP when executed -extern code_seq gen_code_seq_rel_op(token_t rel_op); - -// Generate code_seq to put the value of the given identifier -// on top of the stack -// Modifies T9, V0, and SP when executed -extern code_seq gen_code_seq_ident(ident_t id); - -// Generate code_seq to put the given number on top of the stack -// Modifies V0 when executed -extern code_seq gen_code_seq_number(number_t num); - -// Generate code_seq for the expression exp -// putting the result on top of the stack, -// and using V0 and AT as temporary registers -// May also modify SP, HI,LO when executed -extern code_seq gen_code_seq_logical_not_expr(expr_t exp); - -extern code_seq gen_code_seq_alloc_ident(ident_t *idp); - -#endif \ No newline at end of file diff --git a/hw4-code-generation.pdf b/hw4-code-generation.pdf deleted file mode 100644 index 45d99631b271a8e59b144090cd0e27178987782d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 105010 zcmdqJXIK4dh7JsM!j@hdi#)ipPO>u zK%|36IERDk`!|*-A$(eS-klWNI6BOGq28*UsuA_IZ<{l^`l|>_tWJVlnu_Ij#vBU0 z>rTJD6KpDWIj$I~N`7HgI)2vRxAqk7pAdx-w_SgJ z^rCnRE4`5FIVz-ot6-biVDd1O!)$E#+g)5KXsEq-G9=ouX7e$-F6~243n7V{AN@Eb z)oy(`mal;Jda~+dSkd{JP%;&*BP|g7GRxDFS~H2dlXj>QOG7Oz)+|elo=OcH6s>;? z5S_zSMZm)yjV!VVU(_61Sk@TcFdIvEBwJMXv}%0x#6uJLP#bEZ;l5vJr_%GPSdvfb zY3Wg7HHNAK|FeYG3pkwD2biN3PKoa&cgJ77kM^uMk_s17-dnxqg>s_Q15X_)8(aiw zW~In!goAonVrQp90Tr!U-JLR2);E(BkF9-Sdo%laHKQeam~AcP0jUqaYv^Qh2>U^C zs9%0KHS@M%-Kig(TfJ>OA9?KqU&oatr8p#lJF7}n#JlpH%~pKRy-zEiOlck!z9f)0 z;8P0K=N|BybS`~UvzoM)fJR5IjI;mB`+k{cAHfVZzHS}uv{sfkQ{mgk-71a#)UcMv zN&Ev{WF|;Rk0O#@+gw!~nM5H^-d$hOl35LMU~;{JtW&??>Nb{n-_hm%Zj%4UwlpsD zq4iHfXWMTg@rDq0t;bG$%mbg4PL;)r#%J8&#eY$(HN1!|9Q=V`=63xvOezX%f=4`@ zR@kaiga;ap%`9f$L;4Rp7)%*6#a60|zmi9w z+_5Hayk4j8uvg0DiyJ}UA-hsX|E`lVp5RD~bS$y*d*o?vA``)fGA0MzXDpN{eRR_3 zaz*aOjh~E5t2RQXt_QfWDxEF+th45S&Lr`S&Aby`E^TQofi-Q-N+88(8KB|u$_JVB zb8ZN+zIKXdmF7cxa9Ev1#6#tb*L7W1sAM~#+2I{dDUHhyY)$e{7evW#tBz*RPwK;T zMlw;}K3at>A6GnIZ#m;{A3Z(x=H!wYVPyW=`nh9RsSH{3fl&AdrCooVq&6!vryzD5 zLK~-^@+QgIl9Co3Bfq=_H0^>A5q+`v@jWM9pQQ=15xrNz8_T*PDAbdYuJLmC)Ra=} zZCHm#ok|fmH$L)$v1;dwF|lumv9(|OgiwFX^0mGD`P0#ml$$v3iR5X;IS$5W{04ic z(i6w+^e5QUZ6;aX=oqX~SE%1WzgLPvMm~GgVqIt}I`XkWC}JFE{$41xNT|Qz-CcS6 zv->NMq~jXCTZYMx(y$GjC0dnmb=#I<*Ib1=c(bCotMk4)J;v+6-ab(3c{$VT?(J;$ z!p4eBr|fa!Tl1ukHtywB{qNHXn4;pK4ZK=;>p^8)j0;YJ!o1^8!W&#iGotocHFkyl zTND`7WoVxdK~B~gMJL|yk(>G-zU4R6;=zw8P~QJ4sF}U{a#SRUlr|ev{I$7b&t@?) z!bXySs$ts4$LM5Xw_j&UG$HquzJ2!uv04tlFUr!*oe6^r3&(xbjrCUggcAqXi6)F}8CxF?X@#gfPQr!=D<$b^gE6 zkc$__&JE=TLAW67P%bEli;s()laC7ofr8n2A#m&c7Y!AG-Y~XwFo%FI=*IVpZa-&q zZJj$H9x%`$Tp$N`JG)=a4Tks2kJem}0J;$9wo4Mfw*Qg@l#iR8iw|;H3ihXZpb((J zKo?!Ai~CPfTs#nV2$=V>6x=2MYn!+@x!A$K)9??rgMc7lE_PmC?n`z3T9q`=E9V|1 z&CLS>!%-F-O>y&rfWh$BH4osSe>pyfG!F~}=nlURxE6n?tEXRhUCm_QcgGb=M%mvmQ}AB zr_kinSyTXrS4nZUaU_i zt#^G)KK77vynUDcM!vH7V;YH6wsj%*8V8uBk|MtpjaNb{Gj`GG6_##zPvpDoS!~){ z$H$H8V>;Jg==Y4TGAkTTM;yPLi8(+KiTY}%`SqD??3!)$bf-~K>yCqmhNp=ZG&lfJ zsF_TL=+H#hT-QOfraDh8x>Tq|SW!Z7@aL$d3C2Q=98KtcQ zh1ZKa-|=>>5)X>JkYWa^Ty2)8~e2HPrrsC?N8GR}Np5?dSBeX20=j!(k2 zWe>(EcQ=YA*s3AQ(?^jz=N-iZ3hA$dp?0Wx`Pm!TgbM5y2TcNfrsMO(PvedxcwWiN zVRUzm%Rdo*{<+bm0*Z}R7Lz{K`(D7)Pjv96l-%drx@HunZEgD2VO5xc_4ee?D@hpl z#d-TbC?Iq>eJM&??0K5G$+ulJiy>6O!e9Q1);c)K9uhW+6wM+-0Xr(+cT7cEm$av> z#Qk2LN|7Yr5dWYpSXVCy6IEVL*!3+#$Rt5!)-9KPSDUweE1wjo1nHRH*Yf0Y_e#*F zBgLWIZugFIB0s~Sto86*SSc47Oo^&`KDMZ*$+(;mHG<9j33p>cFyyAPbg=VPi{LLV z+v1`jLQdwQAtuq=DRmK$7@X7_d^)oBgYPjH(0V^;j42JhP~?sp3hp2l?X{Ze4W3mN z6GH1zQK-=@cRduB7)*NVc#5}cI2IFwfP`_Jqm6Yp^h8-r(#3P~YTa&I`ll}Is1NF9 zr8xGrbo53Qa-ydns%BamcwEY(-kH4m#*WK1|9PNG0W(Keml|K4`qY^KG?S6OBHb=~ z1LKuQ+0d@)9gwbv!0uBmX66>-4YsQ%*oo-vOr($OwoV^6;A(iPz9yc~LK@n(wPi88 zs*=##HJ6k+RJC~E8|y6TGsNa{i$!1267wZ z^B+C^%J$}ZDv`O?OLXe~SC7Ogk8gl&)Tr&=<0ZP@%r>x#sglBDXXyH78I^kRtW16315?Zew0EL5Ma58Xr& zpCdoAP*WeNxq>pNkSLeiWO#klL-79B&=IZ`8Z{;w$h{qLT~>jBgyF5M?;5%<1t#}d z-q0yaAk7*isjKokDzF!-)W5Yw+u?BXJPY*noMGu%>GYTp+>*8`?iPCe$^3V>zQtMxLU zJbW5ysjsgnnezL28M7yiUbp>BO>BK|-}Qxjl}d|DXVL0t!79~pO;+#8PIy1bMhx$X z({q*Vd*8BO6mmv1~ z;FPEBp3iyLN@Z6y(^ziT9&xKMCUf>9i+EvZcH9F+F09&R%jXNAI0S~;soo+o-0a<#UDV2Nutp_yL`yCkt=4MAO}ww=H(7wtGsUk& zC8cxEXq7005+-qdi`SSKg(Pti6rGlNdnjb^#d?MVzUQ<#HeGYmstfEeGAZ{dU+WiN z*IGRzS^Z4}D#Ak#J4ZZBZ2^;vTCbhg2F3cjmHjsl`nJMrX$D(R>ld?-M2oLT*aXdQ zb~~1pskH2klmrm_me{N8c7?f~mWAWH5wk_Ol3RF$8*6N$<9&pWXi3&+E1P_gxuiKkbeT2|SNdI+G7d&xs2`?u zX|UQ%aOOL!D>+*!8U!l-OK(lK{ASTV?JxmPi$hjkyierxQP-(%^4?-D) z(%Ex;G*(39m4c_bB$LuLi7P{@?P9Q&Td1#TQnT#7d_vBw3Bbq*`p|+u7_oSlT@Std z^QgB~O)1gA{$p~in}W9+pG-iL!U+=?`$C^<2{uiggk#WF%B|EGU~b>i8R>Y&cMTJx zY@O)c9jyq~FFAq47UUhW$h=JhW%^pD*iM-Xrh1LCo0S`F;QRAb_d< z<{V4RmIuyRfC?ydPP=)kQ(JL(P{Tdo+c(?ll3CAqlCCa~Js*Aduo8NiIu*&mvTUl; zT*D+JJ9XJU?;@2(MU|9SLGx@h)`I>!$X_0q_qBQX&%1+p(=QU zQfx2d@l{!?NicY#}lxeiV}S2-waJf|5mT-#EHN z&=Y>cJ$^-&za<~%Am|_L19A?hFgX6F^aGBj)Ie}}srC<;^()HyOND<=Kj4V(C;fo% z!PudkU=TMCm>mKEgSfz8c1|u3H!p;pkLUN;-qqd26`(HGjt=Zx>=$XruTc1Zrx_GL zz)&7;5H}Rc4h9Se<>X`MgF!&tFdhJf^Zk}~$XYl$x&hS9oc$u@fc&Z$oDclP={WvC zIsj7kPk{cb$nRMPl?L9#{1pAeGv>N!M zy)-+^c`5SI(WBKTa?8;F`9Vi#>(Q6SEu52*%@tmSMePHMv+kF|+ZCLPhE5s@QHJ-0 z&YGw`I}msZ)W4G57jto^2|2lXRwk=cTQ_UCd6e5V4?7b_$Lq~Tf4;NVc=P?i^)BHz zgJ=plwXVLtFR5DFr%kqD-*oSEmv}!NjnIY@Fh}(cHie)w%{yOiL)S5AGYO48-02b} zt-?tvRbIzQ*{=16!9r=gw2Y3%S&c&8zq^J^u-MNzSL3jD1*dObSg}0Rlk?1LXI}Xv zFJtD^32fSuxbKLhvVQ=}eKqlIDP3;;&|yV4;G-u-*h6y|1^s(EX6NN+%^RI9?x}l0 zbD*3Og>TLhzEi$6jNGqDB>AF(*#m|Q6ZWKPpJ|4wI= zNbM2F{6f~bOyH)@DAn1uf`t((KM}jzZnLT;GLJ0^xNFR3rbCV&nwGPP_ZtPi+VG#p z%wu9vQ7J|f66u_N>_O*-IqTRmUDAfFV(U) zJXz^!R>A$ba0-iB^5LuA7(Hseh!s=TAPm(T7SVlv?!iZ#?)p<%H%+&WidL7sR1Z!+ ze#{}9W*bm(cud*laKE_;Khv~5LjvQbf>l7vp-B#%mdTb|=!wR1O}bif>lQ z@tp0f?Fm_Qob+$6wLW~J7EnGINSw!%=y-#97o@KctcgLgYDQRkOEUr5Ngw^ZsK`?8 zLnLXZGc{=u69!=(+o`M`XBb~&vNF0)Pg8y6)-A>s>Vd{>WH_%3qN z@y6}s1!7TA4;k*nq}Pu>;OB}UT!lEg)x%^}D4A;a527{vEywJ?H9awZ=Es|~`2UiGXE7fbxWd{*GVA^r=zieU59lGaS#(MElP8gZWz!c$x7n$5>zziWO|~ zlb_-g*75XB6_Q5>LzO&Zc-Eivzx$kVg~?!r%|3v%st^%zN;k33F4rgVRIU~k9KoxY zq;G~iQ>!+qk~@egHs5t!v?}PEzeqXVXc#rKYz*k|`mXbKJz;qO+ zSnJ{scZEsuV7XPhlpKBzzvJQIMe1u6wubK`M9t94H4Nc|B{gDJo=Pr7U0qazriaJk zBR@4HzrtZkNVHTbj^C|$c1_8qq)!NQ0W#MGRuK+FAN|1Y;6oCsB&`T47Jngt_oOy1 zMu|1W`pZkZ<&AY(jj_JLMX?*X&}!Zyv04+&yH#{hK``S+6?L6ybBpPk_mwZn6Ay6~ zPC+qS52I#HEJwRfOSq`n0!{P}6!AjiFw`F?f5@LX-BxnMNRdN^b_z!y(ger$@q?n$ z3chq8NjY~uy|2=AfJEhS^fEK`iEX~HZHOwKq~`4AXl1d^V|ND1Ne4qw?bq+oKh*^! z9+RhZ&__CdMtA=h8%<`PvXkn7E#QrNtg>6Rti9Ee!lz z(1s9^(BMB3%zq=`sf;gO$2W@L|0v$%cIF{`8$Sz^jbKpK zC(1HmNi~a5;lrSLN4fbs6Z`ezhCbtuw(T?_(HwOp#ok_f`!h54l=nU!sSJggPHHJ=1tch%d@njEHy~Rgy>%QPBA4nbr@`@XC88h!uI}g zGo!Ho=m4Tr&>+)`S1X@p>I*!Uj%PkHE)E#^ZW?-;b7^ESa;LOQMGa08D|7iWA2qkk z@P5A)FU6C8v+h}Aj>QpF-jWWF3X_kYr~?r5ei0o_F9_i8KTZ~e}8WoI|qPFtmn(T+d8q#2z)_0=DOKh8?ztJ5bilvrCsJZ0K)o-z<$ef&Y{phcn;U! zahLxo&*A!u=y3hTbhzNa`=5m8{DB{s?tjNCxS%}jP;MBAixUcjHGnfWJe&c9HNfzg z0QYZs#UClpxz_(jx&c8S9sp>Axd2^wc|lw}+(0l0fV$9g$opH}EUYcvT`m)zb0hvA zX$5dX2oO~Ol;eg%07Jo*0`}tilTH`OA@lLd~C}qNvZ+UWpH)Hp$_B$`&0=^W6=}fAx8OS-bB%*}OZ5~2OfmXXVv__{4kn2UTR602 z)+42C7Vr#WdCEi77~R7?g|2!Vz1mkJD46W9_g>ev8#7q3n<7ftXng14iBH6@AP}(s zc;1Up^Hd?G2>f;GHosc~&N{7cpVY2i)3Jp;Lwf8${FEI=jqwIhV=fPn;N^h5~Kl2jYtmdgsEpD)dfqI_A^j(SAr)=d~fCa z*;ywsN@JPB4bsK+PKg-6Dg84}6FTa}FUS@Xg*e;x)x&d#J^bkqx!t+1Cv5gI*izlA zIBun;y7S!}(}d88N3&lzP|Fu`|5#sD3UpD^chnVm`iVdxM_@O{~9v`7MZQ9`cq#t}5w2sj1@ zFJ&d#-bGPlD`eyML?Ex4w-AYOIk_~Rr7Y9)ZuV|gH;tRYZbZkweETW5`o%*6L=aPU zqDe$&Gzg2bvpsv^poPRik_jb3k-g%XjJ67XK{TZW3?_%Tj3?_p=Oq}cCMk1Towonr z?J~V}U6>s!Khgl}k=_!48k1i?ot4Zgd#YPj8~Gclg17Df&L$V|@%wayR-0IUmyS!T zC5=yXHr*?j6qnVW<#0+j`}u=F>7dyCBjkBb-Tn4Zx)o(6rS5ErqfHy_NeHxf7kl9K zXV-g<7Q$A=v$E*o$*&@_d#tr|IA>FFL=4tz@SsT_%(}Lk}L+B$b$WF$H)oYgR?X4oOY;EBP4O zCi>fyk?qu^B1=|umeUsP#`2}+l z8mV)VoNmdJ&YDqMJPV7N;xT%D(~VP2k-00K?VFIQEW#~Z=X<-_cWH=6jCnpcnB4KD zNBQb2+WYz2HF~U+p{>xWB_E%pWN~Gw%hCtPWxDxoNL97Nhrysm~P+ zEw3EcBunw|pmFm?Vue^?SHCN1Z};L~YK$DSXn{6b#An}#k0 zfjc@Vtn1Ctd-dh}Rl3XLxVbU!UU3}KTa=K1>K#fxi2Bnvj2Z<$5i7nzKQ2}cGgwZ# zi^lpn)<)yG@ja8KVu@kWC7F;TM2fVNz7IFzcdXmq!@&2bO)On}%&aZI&e%3aC2tyy z8x8s@tIrY>J=s=smyjB^%&=vjP8U|~6yN^%a6vNU3#OY)$HaX!(}o=i(oKa^j7f8I zn3|r05{AM~&E%~$Up;4-kzXr#Lq$}CV3%@)J`@{0YkmH~&A0Uo2K+U=Yi40$%mp&v z$0QR?o)jihFzRJJru>=|cm!!pTGADK-DVPT*97l{rO?}U=2<7YHz)qLBvX+cazDhm zaTrR(1ySr^_EdH~>==-ER#9A-wj*qN^p@B29vCA@PA2?L)oniu!XSK0UuGg!GU}2& zPJfGKd-og(X@uCMt)POe{>C`b2UmqOJ~e%#M9#Rr;LGLFqN^&l6JGp`#ikd@f5YMw z&xx5e>TY%F%(XD=eJFN!Si+)LA2OI`8y9PDDM|?1-()$Kg^9LP@gnznG2-kKJTY@y zFzcteC{^PFvnmee4C9+@H)!*7)%XoNt%k@I@6uT7;z9PSd!QwbuP~B`W0VwYo+PDn zkUqKj-Nts1zv1;HCezO9(g2SilU}%U?p5T>^!+EX%Z;y1$+-YWt7W(0cKqk;{?*geiJv~z5vB9h;akiWZb{O)UZE@L0~}O z3E-OC+%R_D-$VeoFTnVVRRSq?e3yYWzzKhL_QehWs0J5|9R^_bi@+La@_!YBhbTA! z{>IG-k8*%7$pY~Hzsm9e@gf*6I|NYcVwC_y{gW6JFb^;9Z)*FKhe1G4AbE@vAWoNR z`?Hrp&%-d6xfBp@`IC}dfH}E;m#TJw16=4k2*8N>0KdPeBw(#S)dq%evUC2%Q_ctL z50?Cs1Hj2HT#rkcasSDN1Ngu%*>gW*OaF=w08!1K%KnHU!DDX!GKTb2$2JbglKb8Q zEWeSG5p((6atKD40FhO%ANia?>3<9&%l2R|H&rjS;?Y#!@Mxn|_AG%s1-Jgv|`(;k*`-HE> zQyphCQ|0mUM+Ba2++6o^xcVg+tBls0!{LY(kBWahn?>zb#>1MaQ$k{SrcF6&hx)!Z zebWKeLI;w<{`4B2lq~hPS)YPBb;!7+KdbNE++>;5yW&UP0TvMp=X^#XP+P6(+w8zF zz9BI)LFq|ya>}Ymyw&0$z_`Sh@(e^TDAlzbjJ_o}!O^_ll636uKgR93f4Zxx$M@Nx zvd&FXM{T4o!9rtk2%APUqfS^x14!DyMe{M_cQ&PbkWMt$vF zpiym2R&+a7QwGeIumW%qceK^-Wwyj~O#361;gH zs%Nqbmi^aQG(M0YcbA$_vVN(pO6&{?Z+Yr$xKyY1OvT;SL*MK(?xQRgt5&_Ma$zSo zInCQ*lbgJ5#NTgQWQyKMbVNhMd9TfVqNUyty*0pVsOLRq_^iNiczA*R+TMsqou2RV z1X(V3oV8JL#4!E5RlGnG6L3o_2y6}OIZ->U0* zQKo0k$gw^ff5DRR7`;wc3Ob18sUv;L70`NCf4+e+wuWHY^_&0Ew?1}-T9-qr0LDYk zR5FoqjAdW!G1Q~^D{Wa+)3aq@s|}U!or>sH5tqxN zI0RNQ&0jKaaje~|jmX^`e@^n!t$0jy#b)38x?FtfijKP#zXC~aDZ-8Jh`_|S=~ZH3 z&SHb?MSB^_d!jn1vrHHR)b7M}4$--4Y@f;)h=cBEDJ_PFHHb1_VN)_#VEV{s^@NU5 zQ&40{$BGJj-#Yq9!7#ov<(Xm@UDMg(Yt43%uSf(LU_}anvX}>cUM2EU#Vuo9&ul<< zlI427mVOy-L)(6J1mw}(&ZFJ%V%2Dt*~L97_%ec5g3_#nKElMgOYB^c$PGme7-yH@Z3xySM2~GiHtkiHBL6_Zb~D@}&%pj$%R@1%q80jx(QEN)`US&B z+xJL4%&T2YgzcVa77!h7#|3V7cpX#vJj9W-$VwEP)Y_}HeS)qV>7I>Dz1xeCQTM(k zn*{rXv6$VBoAVQ~nf#UJ357zb*%EU7K#a17t@~r=Ar3vqG9iu3dok5yhTV4q2=*8aWJQYH(a8XnSnKpN&MHS-$|OOmA3aqDZlKY0^7$J zS^u7_+>ncPZ;fqyC%bnbu-AdPK?fr=n@wq;!ih|QG-2~bW&hx3y{fdHPm`MWXohs! zBTjm?6>SXk0~Z-17wA6mp^r72R5i$t6;ty9{B*P+T}y&msl;uc2N%D*wn_VQS-%+W zMC&(uD&LME`YB{nF?_|VrClp#>ayq|v2|Yc2WwpD>M)P|u&(Pf=^F#?JrQUu`;TJV z`tr(%aa7A*d@X!YFr9^S_que0NzJJ1I`YRWBOM&F$g=4YE|t#y9X`_z8NMaM5gPlC z?#m~Wc=6dh63g$*jtI7z2IUN2`I>M*oZ@^)RU=i8ALfI9fhh-t{U)J!5j8_qg_p+hTY*GnKB=8n}axJ-zE1<{|#<+p_B9NYYZ z5CNN603`Kq3DM8JH#~3#@Xs*N`K=#t?H^&F|F+QvzJcbijW%E&7_jEg3xe?QvcrG{ zaxN}_9RWKmAbgzcz&+r(zxVENz_;#jhzSawZ!O{wJ5P1vQ0LH4lY<{jR&H)iuKXMv zo}QlUrmpPnrWWkxX6_sTcIL(&<_@kL63QxEP)-PkxtFoMlbtyme6uNswS$?t7rT|4 zy&W?E5r48io(oX^+`xZkeLNRn{69nho&v;*;5%P0A><1%{-PKRK*+yYljpqv<1dPV zf!s7;CHrD+0R8ysC;*wdBnB|J-@tevl=CMsc$5MjiMmwV1+sXdHYfxLrTm7v@m`>A z7sUXc$ord=Hr`(c!R5Ab0ZIbpwL9Dy+BMX~eI^TXwTGL&E0$M5&< z{3|BH`>Rv@U?QCVo{4nn=(++-Bw)rcxAsmJ+U)nQX-ZWB8wvssJClUX1Slgy>D`#s zP}|&hw_HW_Wbei+PRJk8rC$kl{r=7q`);4{bvt2yw9J{-sladhrYVjc2oJb9!k)Z+0*t6U1L;(c`@=#ug~#H7^~QM7{?42+$Q6^ zX*E*P6+&Ds6l2lhLsp^%?2;XmUY#1^#@yuJmuikJB>1fQxr~x@S_hAxw@a4p{y5gm zcfShM$8#%O1a(Lcq|9y??n(6bu#nO3=ex@2iV=@+0M0s=O!MH6{oo$K6D>kFcc#R zvS^50OHbce`D1U46BS%X*H0-WrmMhQ$X#Zq?7T ztBn>HF=^?F=>HG$llf znL;k2vI@!mn3OaU4xpgFEQX zkXcY`(~ZHO(E?g|huiSATI7p6tJ{6A(<{pivLpqasSpr7uO2|Nen9bT=Y5{VF(&C} z(QjIe5v&aRnj1_vRrRJBD9a0jahC0Es=rA>8GLhTuNC?|uS8^~ciGW!DdLjZpG+Ud zF?=)ZuZuOi99_mFE|uQTw(kU*BZS;*$NZLnY_E!5j|5#V8r_$Vo+9}4rnVPP34Qi0 z-z3&HUj=DIg28*|Io5C28Xx1Sj7m;4Hw90TeIS#S51whsAZhgSz#x9 zD#9ID@gbxz{7s^0M)LCNBwk?lA(%+m;%Xa-@8=7A2Mp44YRoZCUQ1qg%^nDq< zk&fe4fydGkR=qS)8B25959q`Z2L|dC^>sE_^2*Ei zV^vv{hds=Z$wX9yuQXTRHw-4Pnk*W5Oy%DZ^03?HB(}Ej?){H82VagDW}_RmO;4L_ zh{#lgmoiZ*O|$#PqjOq(y>$)CFbA?GIkkPn$XJ+Wg}sBmS~~AXbOD9#* ze79qN$9@-785AJ-j-qIc5yzjgW0e;x@0D#c9cogHYmw^?0%k1dhq4SVF%i|2?7D}; zOpM80gaUsF(js& zhbTS}i;|O5laWrAE^@Jhnf{n zzC|$2>~Pu~tIwEH)sq|Me72`W*`(f0{UyT-`NlZL=|;EU=<9Y{3}X&Hv9#jjDE-?s z0-;hp9z<7gcXEi!eN9icA}yYOYAF)P3Ho?!BiUSuC=H!QoiE}t_GL>| z+$q{>zwr0BbL!m;h4~M~dj>nzu#g2S$>Uu~X0erG!QDM)K7*PIHn;L8dsD(o{U|$@ zwmb&J>Xq3(#v5eHR=>9yd+ICUQ!`s5Y_>Zh#geE2~12}VW5wszFFQCMuc-l&Su`f)(a3ZR4k0y?Ui!bMy!&YW<2%sq#21W8&|{~T8L$7G@E_MN)69H*|xw?yO7{zmH=cf{X}uUWeMlF;~y-67Y>B~HB0yjp!qJ~)APFj450ZgVAFqy zz&BAt07!c|Y;vyQ|7S=H$UysPvmZGkFaYcR%QfLC?OSocFW9s!Yt`}ftVB^WMK5FzDG2HYS82# z#<=@&<2jL|b`yxWke5DsqK~F4n)oqVI48>u&uJO?{Kdx;w%yO`c4%Xodwo`i(0u)7 z+~SU0^&?LV0s}hn0!E#C_O?}bk7)Zbb$j~;m2O%u2(5_Kay?%wV{`pJCj0Ec*!0_L z&Vj9TPB$Ij_>?m8h?A}+T4rUu!@Q+qIcUW+9Jt-2zI0Pfa^7e*2|>!(MxiTBQ#$yn zdqn&Jo3{ACC}PWOA%Rrr_r?r|cAB(+FAT=r21V%dI%s59m!wnNdFE=|NV7oV#tYxZ z+1I{hBUfF7?*@sBEJ3MP@TUOVRTyLWr{pUqE6(ciSv_QVaVU4IdYp8VbjG>lLJfYn1h8(mP4lVIf8R<%f9(*joTH6T2&Ja z;20NM(4wbqELemg-QLyF5E?gA8~JKUXkrj)fwZMZuw>h7Tl|vZ!xpY?XUZ$%!rq|! zR1otaE$Q?$GaPNgYW-G+Sz2-#j1S41R>fYfgc=!dR7fkG<&(+QR!u)yuJ=)u1!FrJW_!VTJ+8@D4T~LnR@GznnG{Z;#^)B{ z&77(|u|Qs&)mx{7bG3#!vaz|&Rb#+XZ0%4{#ZJgmZkmc%l#o>YqLM*NPZA1#K2^c{ z*K&19uThcUH~2M3*RWM( zrizWH#V^0oH1&Rv8(8kKfBlsEV~6nAVipSS(t6SdyB{CTzj@;n5Lr^;#sh!h?z2(j%BAnPNYybVC_FwSbJA3Y6!>kb?EC=bAMH-#kTrB18K`u1Icq7++qfjvT!x#EsnR z9_165bar-T$BiyZ>1m||r%{q{gM721qepH=2#K~GFlOkgj6l7n!BcQ^l64DlNhPIu z`s??_L%Q-p_~{?g-%e);OCjz~(&`m^Ropp!+#f>sxBG?Vd z^~GX^aUw(#->u;Vr+tGjSl&8u&y?oSL+l)uc$Ygzv!-(KcfHA-H0!D zMZ0iFVB?_!{6)bQM-Lo7ZHVE=jqo|j;1_8{+h|E7ho*nI@0WfSa$7dwLz5miRt1C5 z7g%lV*j4wDj(Llx?xT72diQ*ykd{uqVxQ31x6wTuz`mtYnA#WT>Frx8`=U|6st%h{o6^wxUqiZqId?!ly2@ z09l$xOZ{eor`k)a#5FOZQyrTe$GI@owd*BsDI4bz%==9W^M3azccd7x)<=1 zAU`VuRzuD!|9_dbFD#(^Lj(w41N%jJf0IZ6EKdFRn&4tUSRV+{UtD+L`xV1nR1ipl z=7YfZ$zGEBbv@-bQo!0Huu<}o7?|?{in-7>E?{wp57@VPu{toY@9 z2F!V3o$X?Mz^+VQAjSJ~eZTt1Z`uce0_$^^a{<7dzoMJp$N{T}Jil4|0(1V!P2g*{ zJnUd#IqtHafA$p!FOYNsI_^z`1Oxxf1JIbz;%Sn0LL$8{xSG;3=80N=r{;r({rXMp_q`G*YL#=m?AuNSD}7u)`LLH=Kl zlK;yQ_y5k0gh;eUqKk6{6C1H8@W!w2wA zxUTTG!ubdRzT^G-`rLE>ehw}RmpLDjfDHV*{|rIk8h#&M&JVjmx&Ioj@O$SY3TXGQ zXZZae_V|zPz%%e`_>lhb-H-DR9nahNw;j**`}-PRHWY4ecs;-wcD~^a-ZMXHfFI5A?c}xLqCylDR56nkhxlY^ab~$yV~e0*V~aGB1_`;8~~ek-T%#%5l$?yP0*%r}>NcDYvgKJ^vC5qMrM+)6`ijO-l~WcuwMYG?uC zxC$c~QS}X^(_}+*L}X-#%(>3>^*2mtxX4m%8bQPn&^BVEE5)Ls2zYowmC4BjU;$B* z;9XI%jdd^r`%BALlTA&2f!+ay2zG*}c=dddVdL$HGMO1;dVWWncI#>jWAv|)z zeT#Y$-4;7@<4XoE{=K>$r-sO>pjDayVkjD_lnDZlhPwvkSU0J$vJmPlx`TBNX!&RCD&bXP!c&*P*dk~|aMT1Fy5d7!d+ z@LBfjGt|g4R-`knh3~*mJT*$6E#sd(J~-SOh|@RXw0|_zhjen-hTvd8jPi;3(+Jtl znM<&eN?Ld8>r>x6@PcyK8HOY>auZ1i&E%#u1~p=?NS4a3X|VuG*|n~qb;KIc(Y}~~ zW2{*tG>j|vBpj+wgrpH#E8_=dOs?#!#M7RP40N4gihcUj%GH{%%;P8~WNNC;W;)&4 zTGaa7&GB|Ou@}fO;=3c&9kgwcSVLlYc{I-;qSiE~AVW!U{B0FAVh}U+`VL3Q_b|NE z-eDvY6&25*F~wf-j#jd>nJtdqIY-VCCtRcx+grO}QQmJB&rVmr5nic(q{8EK+Oo!j zb@uYKc@8&107X*pI|*VUx`(Wsa#vGf&nAT?c+HO^X5tu0N6%Cxe);Um`^{ARBmK`W z_M{fC1&`ycmP*Gduf6W2SInmRzV*a7b3-nEL(hjwbMt%ipHxnB_2yke3QMq1C76AOUMo^+n|-EVV@mgsgQ=eX$l#h3+l|GE zlRd2a-##XpzS|6Lnah9?+xbHY{8(cwliCmm5}@PhqHjwy!m>pU}6)|4q0j{qY*xQzVz{hWvI$ zF$%k2e{RodD47D|V&nTr6V&2i;mMFS z$yP+p9{O9pdg@9i5RW-XH&1@@Me5DiQqX&^-9uW-s+UCID<(GlebeDDAk~9MEn2lk zzZh%Bsw$hswwr;~!tRehtY|W~_VB_8c9}8!IGI5vC2W zn{;gKDHkLZpm`Dwn`1@0MwSBcw%ABWw`@jdBoq?ELGoh2XIH_8m3?uG_XS2kxQh(n zTI6j;K?wTYV_telsp;zimC6ahSrwu}z<^-QIQA$3%B|s+mKR7zHYI)|`p7Y(#Kpfe zkWH8R1b_I#{A~KrK&9xqmZ!Y=DdBbiwuKO0d%gPSIkoa49$pN&|28pG1y= z>Wew4cmTcSuE^)~Cnf`_O$wiaPC55-3W^DE8O#qM4tP#H?<56<*JZX_ig{f) zrNq+)tzvfvSdc2W=O46~6*EL-cVaU`1|TZV$K10Z_l)YIqWIiSeX-u`e5i;cWgjdV z>(y9lOSpu6<@BV4$pFpy7_bS5VYF4%;p@s7SEX85`E^{Es_qu))@dGwd2D{nRxLuc zwaDxp-VFo&B5X<}@`b_1Ih=IaRh`SB>dHX$hXTeRVOc>p%98|x9v?z<`5ghT&+aS~ zJDta?Mhyy~6G%S_ly2c~Mb^7WGy-XCAbM$4Nc!0XtKNzJ-?SwI*IwG>kK;<|cZTa; zPg@83YlXJ<%Iqw zaTP`DzcIE>L};(oI0Y_f^EFqPZIfvzHeW7Tr3lLq@7~CqWhi z^jg?BgRRGFpAM!)btpQD9nT^gc8v@`*MG!o51@7_(XU}1bPezf0p-=^Z=92qz4 zv*FSZbo#Dh)WqelfOnf8gr2`@z(b%H#zWpHt$sqYrDEZvI;KD;E*99$ny#4b?arBW z`lJ4^FB`iDtCt=(>|y}pa^fdlMu`j?e?~ZUt7Q)&lD~Icq=^Tf^52qag%SNo8ZGBs zay=p5>YMB56CTLrrlbyOq{BmoQ&b*ptR`(cv5R!QQ14z%#6k-_R*{2aC=?|72a6#u zwhPH&Lp+(iG7sK3j04bIT(_^v#GA{v-6B8jNz0`JHrt&-@1#F823SSP%OE(`@Eeal z*I8iQ+9w8Lr$>OFbyT->9Cu!Jy;;gPi}T-a$7!9FE?G=lG={aOCTMhp_sXDZ zMU5FjbQZdXaB*9f#1yU%vE)e}r>V0I|FL)OSbLB>4O%%t7YIArw{$Zwno8dJs<)Wf zy|*g>`c%(YNPOA=?svBnxo>^xwMCcm7wJp`lX+#%c6S`9U|pU>^~pgq*X70Nm`nj% zgKp;ZbCl9lYmQ{O0-LQiuBKEpJw_UbbgM61C>@!SOWwnuaok2)Lt2-+Ee5>xo~+26 zd+5~S2S=w7BgM;4m#$CvzJ?B1ET~oHbZ1>ho--lQO?v;@oEFvpKuzzmVcTLRuPf{8 zfjM?lX^nDSN|Ld`?G}~)EsH+A8@h=I14po2QdfRI3@Rb|xr=DL2hHA@h+>PN+{2R4 zDh|ns4l@vxlO0vF149q*)3w5(N8q*XRLIDDy__2Ey;@QPF6PIn%1Xs_Z0+=~m zhK%rim!-HEWEDQ?TpVr<7TV<8qhE&3U1H|6r3aVjf_^uTe)Fw&PHWvc9>lu+z1?tApB~m+!y%K*`$;j+l)MfC$B`)`; zXpr2tgJT^OKU){Io^@+AqNnkZe6GB|6OtoI1C_kL-wK(}vDb)mtoE!+NSy{|e& zk&;Y)&xLBu+!uQv_p93#>2oTH}o;Ad#WE* zDv4u=-%l#%Zi9Ii#$G;i$JfMHT%LCt@1#emo0ya`v2;My<6lo(!v(F~70X25sLLm$ z&fjtrGXFE0AZKAhut4N}nUx86by&;3PeWj^D|+jEjF($N>H6|Q&pA@0RKD$;NswA& zF^nrhGvOySwb81nIY)u9SyG zo3dsoA3AO37iP8vbKoEXb$Y9id7fm1Fpc-us#At^QY1WMvW@pG*;ate@=%5Mn`H74ev+ZQJNFy zeMO=KA2WLDNVtitsYI;!KAUc9jC$IQ27E)%P{DO_h}X9pErU3DSAryiSe89hIn>D~ zOlN5&dR4I^rs`-73-cyr;^rn=gTw8cC-+hqForTRvZCFYHCbE0gKCWEep{;_{H|T$ zUoFR41@EG51qzgMI1X@o97xNVrYX zLhxZJ@9yx&$A59d)DUEnf2=y$CEc+O@vezvN-xjuWa8z z7Tv;esfyZ=MzuUXIj(W3bC#DOc*g3~zM_JwzDM|jg?54BQosJkx)Tr=Hh9*ObNw>L zhy5bx-UpZkkclMd=6#PMfwusp=`9=Mv~*V5e0gfEr%jkB<`EP`FCw>uhZVA0YPxwK z$X;?<8IY8^+r6vfU0|s>8VF~`<8c8d0KQfSpRt7~jwK3*k1Fg$8KmR(0X>v`!%>Ao zH4XZK{>7$y&k2|rc&DdeHk}F@b3*I0kprz3QEQZCZ|H(1t{D#**&7CnHUNYMj-8?C?}oWeKkaDn z=aR>#qV_xli{NQecEUML8(S#N*mKd`9cdiIA?G&1-q+N5CXR1EzdgOll_B=~o9BDK zlnr94D3|~!wcFqvk4$L+T#j~;r&{e~0heX>aLwzB6H11%UIK-}D=yXIu9`Rku;cBX z&$OiGVT|lB2N);ceWU;bG$pm=YZzMalNDYQF(5}Y0f}@u(m&EJoSaP*c6TQd;He}@ zLGGrQ=APS>_6d*k))C!l>Su&i5kQgp}DM=Bd zKbPz@fErL^9c0#nw~4y@0x-+#fJKeT$MOFlp`EvpW~uI`l||Db7e^kz)t2yG+of`J zZ(BvZ^Yq%2W{fEkyL4g?MYtru-CSN=NOY~KYl>dW@-DyP#g&kyL#_+|K^lXed}WoP zshnSsu#%pX9aDkbjJ3sgi|M%|%U9qeZ~^F!Yl;Iem*-9W6aKWaP&N&z$O(~T;h9YF zs`ez~i@1)nZMuS@wXh*!#vPILy|w&gYXDO{Q@F=Y%De9;w)woFmMvd;3mHW0CPjcx z%XHob10hpokFkTRM!&0I5WRYT%re_H!BMJ74>{|1u?H&ne5_~+yNrN&Sgd?>37>oS zukY%HlaGY$NLs+GnX|Ej6W(E-z?NstRv)=r>Eh6mEOSm1R3yY=dK)9T#@x7|EQ{#C z&z_WLecpNFt?ybt;C@f8Ukx~#wfkfICxsG!dB^2>QD6_a z%AI^wQVdgcHI;-G8~a({tRq-vPA6y}>#~khmbtEGHJKVi(a4p&iLNU_P^cj@Ua+J= z=05)t%VOuocIcXp+`0snA)>r(8;640sH-C<4r%V2t}5^FS|Pb|ki}xbkZGiCwyE`f2}h&E4?6YS0G}y|{(Cx0@^D-(ReOB83ab!J+qF1&a=i z{x-4Bs)6o|X}yV;4#Rb^K0Qj`Py~gc%0z9R2$C1iTq-C>ey^DCHa;bTRT30HQ+3P5 zXBn!*IX!qQQ&sM&a(Mw38zS=@Ua*r{QjVr#s#STY4Mfs@xT25B(+MjvXN~@RVZiCR zXgM(EvUFh=t5UE;8;K9KFjAa5VTgG_q9jKu5w#T_*H9CL^ep?(sH+#O4im-|G)TRs zhE96|=P@BF^a#Z3O2jDKyR;5_EvL@Tbr+^A>QJ0mf7fja38#@%^}hp5)?4aMKXxWm zrl^e}>{?BAl6Nr$V$z%O@B42gJSmC+?M~e@xZtBBi}Lc)6bX}H=_68I97K-rD;4wd zN26}TD)u$h>C?VkAN+r{UbsA@`PO7BqWd4S+JfV`>u*feiFgC=4D5h|`P}B(C(FX- z@RI6iqZ78$nRFp%PE!*@f@U$_FaZ>$d zY4kH+W>HBRza--Zi2&Plr!cW*>vhJRoXlgW&Eo>Xy znM)v#A$g+M^0voD{FT)9Xq)GV_zQ#fr%a zH82_a6?#;xzITu)h;teJ9+c0Y*0zV0=r00rm8a&SzDj(@ss8z@BXrw4*M5(@6#eonx1?e5}+m zx@V(v4RIfDOxDFrB%L*r73+cP^-UCx6ZRpoFLMvF^5jz_Mcl(CDb81ag$1NTTH1IB zv@zUngSYit&fVu{CBgSa!aW5PN+9@Awk=2tKnYFAyGH%%Z3UK6z*37IP5HRcC?eoE+~@?l(Yb@la9 zJU8oVz2%t((w!&HCg7^$DqHs8Mx&;7v^}NDBeS5qNT4&TvSrNj2|b2UNWAqJ9c$ki zZR;GN2}@V>YGXm+o;j>zB3#Y$wldXS9C-83B@A2A7@t9w>Oh9(iOa;yw-|m7{H{YJ^xG(22ZimvC))K>L+m_v zFR$ zoHN{PGz-Q0IDvjX-F+U}ph|=JUn8hPHF~1KJX}U4kHT(_YTjub?|<#St?!+uvW^v-DGVVcRIdf=rkU;? z+QgsyEL|UMJ4QLLr{?%dtjnQqT;L`pa3b@5w0A)coVXtPLrutu4^~eC5Lo`uxDhhi zn6j>Z6reE=AM)1u7ZtL1UVMDXLkXiG%Kp7-)gN$f4^bFA1rZ8Tsv*7zuuSMt%=Fje zhnn&p)xF17_3ohSG96K+kx9Cbq$^VV7)wZx5?>t$M+4T=!Y{bs8*zI)+>SDlR3$VX zhNBuj#Qb%GIz{dJN2slT>|KRCZ7=Akn>f4DKo12zXATg!~N$PH9fAshWbe@ND5LpKxc1!|0qQ?@q44D5~O1kPq_S1Z@b=%qUA z62pyVS>BtDm+$ANZ13;OhcC62CKKf;`2vf@Ov^Y#%JNyLv{lTs@QsbOSw==Wd!R#V z>nN?PqsuF!vn1&$Z2;e>OS{8E0-0hyR7p=x`P>L{R=$BnU_1*8Xgz%ZI^Umf>}V`J zgPYwmBXgTQz+45z<=o<;q7T{$Ui?3VGe2i<9Sdvoo3MO$FGEv{!`pq!i_=H6gFjCq z$cl=75kcg=lk>w!c=@@d#Kg1!x$&{8Kw_!uX&eC7f5NLpSdxeTs7o3ua+)ey_@#9r z_8#v*`PFr0g&px0u`_-SAvpYsj?=Kk!^yraX&z`99G?gIKy0ZTYZ@G!Ki*(!96*y< zel9e=p1THcwT+C;_RMb~y}BJ~Up?ULY->MJwOP{n39m-|+iMrXT#uNlhnN}oGi z+EjitKZh>OpBJF38DCLMb*wI5C566k-~FFY?SH7RG686caejL+Fo2}0ad58w;r==P zhC1FgdZWdto=$c-{u%Ov-8Hg+bz-QacXs)PdO-cix&Bnm^82as$PEmPI_YuQ_@O-a zwXb!uXKA80^fNSh%UD=FvbAxP$e6;Nds~GrsY)j+#s^C}pnS_4Q zMc_m9k?H$Surs0Z5kwo&H0wsa{am1RYBCG|t`USk4ynwFOO zJy2qyZ*FD%B73p+bH&ia_$GVrEBub?EJDvt%udg~{?n=WgIx5g>WQi>8`3lQElTe2 zO!8xS2Nzsh+XdE}@qGhPXsUk%Z1*WWIy8Ct;XC?Fi+22@F#({RNyYt#!&lP8;9GU? z=isd-Y1_9qbPatYFh!u6c^I@^+~g-6fbwZdxMwT>%%i>&r_OAZ~*DWwBn?{ zY+$6DX{t|bh81)CT4`az%S%_`d>e2P=2wqe55yDs(hWs7#hBYx^)+h2Yh+JdgmWQD zOnj2u&I2!ASI^R`&MpNK+kyn78^ytn{ft~VKcM53!{D2>fRdddi;vF1AqNu)2?6b} z#q)f*GjrV68*}$l^C2%89HYq&mU-!k;>Fk9V%u_cOAL^w=tG~5*Ua}8)e5a{1P#LI z!v7cCAIJukURgWFXp;2l2&y%%gB0jXC_0O2pw36fqta{26z%F-{D_F{h(>X!Y>* zr7~c-w-qzY6tov*E2$2AYkQ2Nstz!Q&r_;RA{AGXl;|9z#jD+MzwC!jWo(f5pk`s5 zXSOexJoWvxmJ`(Oyg%cQ6#Yw9aI)RmV=ovz8=nb_5W~D;<$_`l$9l$>XT~H9cu?R0 zy-_Lq=kchFBXr{M+giP8U68qIL1nW`-Mtuqw#*q|L`|Vn7(CdbMIs#yOTCRI0@VE8flU+x=baFWik^}}IQgoHdTRNsH?vq)vzP#$@Yd2E}(-mj~@~u zi_gLfskE>6A2S?oJ5tIX+56E2GFQuV;S?BIGO~zNx1SDGW_o;yQmcPG7eKT$DWai0 z$cVSm;hj=jbR`t=8TTCxrq$y0FgQ3;8dTP&ZM#T=C$2Ea4QpP%q z%75n<4qULl|NSF*KfWKCX(XEH6|y0Q|2Dy;GAEYJoB+&vT;=m9StiXdGWj6HxClXd zchO>bg@;7@Cc!Q9_c)}^iF@c~a(2qK-tqQ!n86g>uIWBEvU*5i0 zkYzEx+yhbm`#5dn+l~jzc^8dUXQS+;bymQ3(>OF-WV-r~3K<2^!|d|?n0o{WjyhKV zcKiymrA^?vcJ2%!3%C3gp65TxPyUiJF;&Z+*jn1mzmLJ$TZHx+5eBW2G`7<4naEIQ zIc2=$5k&HpXSP|P2*rjCIK;G_<7!!l2-n`=TUnLIog71Tje4m75uG+$Y{L-#?Xip! z8qU!LyZ4riBfWiqp6_qCSO(t-T6kLg#47bOlFl6foeNzBH%wXXiLaGr2w1n@PATci z>Z)#3pdywX+AP-Eg&=;SgbX{R;N{yTRI*TGZqM)(?VnQ19~rn~7~ptVzO$qt1#%o1 zns4|zlBc1>hHL#%y*rTG%p-kbWxF*ojemxX z;LV+o7}a0FEWmJ5$J`7d#e&++W;mXxnKe!hSo2;5_tjCy!N>-|6cjISymSRD@-ypf zW;M?<#uaK>GZYk1iY(nv5ua1EKCu%F^*lMn#D{M51x>tIWV{&%L?h2N^tCSm?m(uF zQM*`s=?d=4-Xu83rx-#=D<3KktUz~GLT^26^N($K+KI$vRV?B^vuWIDZR6tY7R2_t znP1M7HB-mV4QU5%3jgHb;x>)Q!5zz5%A5uRZnHd_&*v5{$ZF}QqM8#4Fj-0EJ=Ag;UVX@qPVVC0yS~zA|_xR5N zYJsVyn;rCT_d-4EXK!rEe2i!o&BoSahpI%WB;f=-H9pD_QH-2|Aj72vJ=E`3JP9nk z!PN(EPt$8l=0hczPZu&LSDX|In`lcaiYS3<+}PS(lA7dsu94b#s#|L4LR{{H z2PrJ)!NfAv0jK3i(NR2%w1jNXMvdhmIq)GPGB$rgHSb$tyRGoe<(!$BxUK_VdlY3Q z(>!2R>=g}u+JRqrGj(RrooDF>I9561-^(c;JkEn#;c>w+W#>4-XEZHGawr!P?-t4Ht%peop!}4&;)qHQiY@yr}L~N!oTNb`sgl@;w*!**m(u(mtv1H(YK7V|CN4 zcxF3axQ3Vp>2x0^&bwRK%TQ4hK$6z)ehEQIV-9qRXD0YGMgUgm86(xH{%+uR$t^mK zG>bvi3RgO~wRd;^ZGMH;*=MPa)%hTq?TFf+fU}|l%@xgRw)*&}vQIX%*+r4XrwYK+ z7MG5SsRd&5X|J#PxqN z%`SEekZLwFPm=zi=!-S|X#PBYUUTNleL*iIw4xdw8wIa&J)U5UF817&F{VwjC}RZD z>E8iqcbe?;oBiN4`~zZ9MZwbl3u>)gHe|s!o(+(9jw1|g#P|0+Fnr{HIcb;^x>rj5 zc?IkOWv?esSYl-=+x;)X(NptjW5OstkAi}yAgh}B>u@NfTEz!KMeNA~XOX=$brZW(HmWd3_0ThOUH_m%wE z70Q9a(;L+m_4Jts!UDz4@u;8=SmZdLMr&U%&v3sttXZ4{@?Q0&r>_(l8AI!At$}S! ztyB3;1N9^q3VRpKe6e}@v5Vs;9hXCYmk34uNMGh2cwz543~NmDFm8RGXo$e7o7Y1) z?Cyy55+G3WgU{pPQypL-g=`cJ!kcEsbiEm{DS^ujK6Q%$Z;?qUJos(ow@yGR5&LW= z;n&n+R}M7<50%MLR-i(jg@D9KDA3Ru9|XC8#Ys#c!Q_PfD%P?NZw^tkAj$=K#E&z( zov9^7kjyq-W7gQ{omBr5kO13C8|BWE{1*THtcgM$P7ZRhuz3&MjaQ}1mm;+$B&U+R#+-T zRbk+5A#hR#M291089LRgjG>szQ>?%z3gcvGNB5MZdb_2ikf0nm=plkM4vL}w{jsqX z%fYb^nZ5)J{L!U4`VFwug_X!5>~2{tnK}0tgdXa8`!l{9ZFJfcV(NQeeVIflF8SlP z;YpX9L@_z{`T$}&kuAhkL9w}gv8PE(6taAB7~&=Jn30j)k%0;DjM!0JV)SUJX|j}X zfzMn%g>e?b>NSU9M8u!DPtl&MV4bSzRl2)@xfy-+$$oy9zDNj++mi?^#BAZW11ZlkEqTZ40{g#>|f0XabJUPz; zr^!Sv)FpqZ3HW1495W&U3>AD(6_I@Wi>!+Ipb0#ow&DHg+hv(|1EXs#GvN}uEHypo zip|q_)M0W*^;sTd)zpuM(XKGf>94K9`R`eBn=M6E7>HrL)H|ai=70FaZ=^8e@81z6865+bWx*qgXyb-)wuLNE+@~S6 z#|X0{`TUS9LcG$lw@YvMjwvp!R*ddO<}`g&*ws)r`{hwF>)3$w$v>=&%?VTTZj zz2{$Ks_V>%>0#AgNuMA{6kI^5patwtMJ1`^ikg1}c zOq*c3+p>C2xK1s~zPVfzout$+y${4NuKJMe|Jp~(;t?4mO1>zNJI+m_Myg*E`$}PR zL{jk^2t|P_4;_`Jqdj_$wlEU;HBCq~!Q)VeuZ>G>Ls_>?K6{ajvo`m!_^$JRV#5zh zZ(i^|76ivN{4>+K@DGYZ9C{+eetf*#Fj-D6q*_lRUiMb}(JiPo*-B-|RxuuxmD{f| z_962R(VmHW7oDmX5e?@in)}%~VTK~DmS0oV_%PJw%Fi8oP^SS~3bwRFSpys3uejGl zdCZMtg3CH0oPwUmw)DB78&yO?S3Auv|aS7{~4e=w>6$YhrqKBeR;>WL%F*tEC>bK>sFn9 z8na?)^ti6&2BA{XK)K}2EbU*_qYy`iu*sR5TXK=l?h+o|dMwB%9+~}8&LK``Nf#T) z=xk~yO&poQYY0Bz0ppi>RCVZe@=npHG^gQt%Nx?qmT$~K7CHmGzMhTGVpu1dL0#cD z^nP^4sG3>jL4+O_q(!dMs_e~s-KE89+w3KSYkz-$J!9Dnk`lH`)V{nNu0naKW&^Cc-(3t<& z*}+l5A`=ad`EHmzR6aUM;}Rj1lPIMpIRzVgs-XNM2=$QC>!6DN(Qb0l?~i6Gzbd+A zR3M{F3O1E+5icu1M*2Qn=?PBeq|Wvy!*UVw10;+z$3KX?Z}0PB_SF;f&@-%O+i`o% zrA(>}J(ZCZ@CedUf|>GE`Kri&4MzcNL5`FS<3mh0%wz291-8gAp{21+NGu{!ikkb= z98_o@=ULDqIHMyUQ0nj-UHn_$O#_>!)pWgqr;^DF7HM5==q$1UIGaFltNuv#-4 z+}5w$+85%fWGe>R8I|~$Z=Cs6=DpNsG@O%J#V>um_>QzYT3hsij`^7PT$$xW3u{h@ zm0InqDKK&Zek4B(TX7q}WgZzl#ZTcWDeBD{^VM7Zy$XNXBf9rrY8XXQ7lqt!L1S-B zm#BP1*YB&RE7zh-Cw}^=`pQ|w*%g5GJyn5b%#>7=dZMs_{XIV$CEK||+!g~VXuMdE zrZ(yrlH%k8l~l#z%@P123wp4QCRrXk_^kMh0KA+U0Vt)M*7D%&@t^ zT(vN}f$oTiZCA~w4U-5hjESY_4*XmgY*xNI4!jt^pHlF+a-&x|)&75j%f!<3kg=|7 zrE3nq`=xFtgoj)A!HzeQo_qHrI0&ZhVm4NGN@ZiyZSI(+D$aZ;w^}iFmOtyNC!eY( za&p_kV~gqz2x;XSMu=T4(G*TuyDHbcNbm%heJ`K9<~cw z^~BU^q$&QQfXECThL2`*%G_p^KcWws&68AI8sQ92X9fh?82~GzbGy5_`G08<*(f{5 zql%~-$}FXpFgoj-04@LB3xxW1Q@%u<=bt@qZRmUjh6yrdMHpvmG{AibiAKctPj!Z0QI{-^(ugpFy@O#A|RHt(src$88xG?exH{IK#gE;!jyRP zk~)=&HM)Q0Gtubz3ZWL(l{NZ;Ey2r$_*d)%M$igful zjm%|axgDouN1QQ7>rm)gEbqZaMcz~nl7ux91Q9E(@pY_@hKPaR-yl6`LNy}jh4aNG zK;$?%kEhig5}(ngGFO@9*?3!+H>8;;`Ys$B_-fMzhy2dI+NS5HN$hANn@1%!0QNb} zzTkO7E0L^AI3AN*5%^B?hoHWnjcFQz@m_z(Ej>wE_>Tq-iMf+}Ud-DaXS*gg z)fT3f-1$$s*r{ovv*ZtKlah?(sPHzO5>rt7YBf9-!<6-na0x!Mr%Q{-2@&30x=xgw z`jSml&T(9LM1lg?b88aT+Z2EAwpWIQeET|^WJhVQ-i1IiaQ7BMV`wB;faqZ&MNn2L zWFC_$-JvSh2X>azHbQDAOamn=Bk@*?Q5T1v??tQNL?BF>tF1P{eC)u53g%uL1GjlmW^uxt`1h=sm`C)|O4 zdmV@gtna={DH=wFWv{L5dpeYFe9GmTSQ7O3WEdeh4R%KnD&Kuw)AYc)R`|5${OLfv zg%yGIfhZ10og;@=Y)atz)1@nGqEJ&&kYJ#&jn-? ~1V9k5gPh^{Ac0r9881bjDc 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℘yZ=?R)W+^tNvsTZnJwZv}%@4H)T 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 diff --git a/hw4-gtest0.spl b/hw4-gtest0.spl deleted file mode 100644 index 9e8844f..0000000 --- a/hw4-gtest0.spl +++ /dev/null @@ -1,3 +0,0 @@ -% $Id: hw4-gtest0.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ -begin % no output -end. diff --git a/hw4-gtest1.spl b/hw4-gtest1.spl deleted file mode 100644 index 6bf944c..0000000 --- a/hw4-gtest1.spl +++ /dev/null @@ -1,4 +0,0 @@ -% $Id: hw4-gtest1.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ -begin - print 8 % prints 8 -end. diff --git a/hw4-gtest2.spl b/hw4-gtest2.spl deleted file mode 100644 index 79083c9..0000000 --- a/hw4-gtest2.spl +++ /dev/null @@ -1,7 +0,0 @@ -% $Id: hw4-gtest2.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ -begin - if 3 < 4 - then print 10 % prints 10 - else print 11 - end -end. diff --git a/hw4-gtest3.spl b/hw4-gtest3.spl deleted file mode 100644 index c62a9fe..0000000 --- a/hw4-gtest3.spl +++ /dev/null @@ -1,5 +0,0 @@ -% $Id: hw4-gtest3.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ -begin - const first = 33; - print first % prints 33 -end. diff --git a/hw4-gtest5.spl b/hw4-gtest5.spl deleted file mode 100644 index e7a8c4b..0000000 --- a/hw4-gtest5.spl +++ /dev/null @@ -1,5 +0,0 @@ -% $Id: hw4-gtest5.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ -begin - print 340; % prints 340 - print 2 % prints 2 -end. diff --git a/hw4-gtest6.spl b/hw4-gtest6.spl deleted file mode 100644 index 6a205d4..0000000 --- a/hw4-gtest6.spl +++ /dev/null @@ -1,8 +0,0 @@ -% $Id: hw4-gtest6.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ -begin - const three = 3; - var four; - four := 4; - print three; % prints 3 - print four % prints 4 -end. diff --git a/hw4-gtest7.spl b/hw4-gtest7.spl deleted file mode 100644 index c3cc02f..0000000 --- a/hw4-gtest7.spl +++ /dev/null @@ -1,10 +0,0 @@ -% $Id: hw4-gtest7.spl,v 1.3 2024/11/11 21:31:41 leavens Exp $ -begin - var x; - var y; - x := -3; - y := 4; - print y; % prints 4 - y := x; - print y % prints -3 -end. diff --git a/hw4-gtest8.spl b/hw4-gtest8.spl deleted file mode 100644 index f85d4be..0000000 --- a/hw4-gtest8.spl +++ /dev/null @@ -1,10 +0,0 @@ -% $Id: hw4-gtest8.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ -begin - const aConst = 77; - var aVar, anotherVar; - print aConst; % prints 77 - aVar := aConst; - print aVar; % prints 77 - anotherVar := aConst + 1; - print anotherVar % prints 78 -end. diff --git a/hw4-gtest9.spl b/hw4-gtest9.spl deleted file mode 100644 index 067a867..0000000 --- a/hw4-gtest9.spl +++ /dev/null @@ -1,7 +0,0 @@ -% $Id: hw4-gtest9.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ -begin - if 0 == 0 - then print 111 % prints 111 - else print 0 - end -end. diff --git a/hw4-gtestA.spl b/hw4-gtestA.spl deleted file mode 100644 index 04166fc..0000000 --- a/hw4-gtestA.spl +++ /dev/null @@ -1,8 +0,0 @@ -% $Id: hw4-gtestA.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ -begin - const false = 0, true = 1; - if false < true - then print true % prints 1 - else print false - end -end. diff --git a/hw4-gtestB.spl b/hw4-gtestB.spl deleted file mode 100644 index 0429323..0000000 --- a/hw4-gtestB.spl +++ /dev/null @@ -1,16 +0,0 @@ -% $Id: hw4-gtestB.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ -begin - const zero = 0, one = 1, two = 2; - const three = 3; - var v1, v2; - var v3, v4; - print zero; % prints 0 - print one; % prints 1 - print two; % prints 2 - v1 := one; - print v1; % prints 1 - v2 := two / one; - print v2; % prints 2 - v3 := (two + 1 + 0) / one; - print v3 % prints 3 -end. diff --git a/hw4-gtestC.spl b/hw4-gtestC.spl deleted file mode 100644 index 9c51507..0000000 --- a/hw4-gtestC.spl +++ /dev/null @@ -1,12 +0,0 @@ -% $Id: hw4-gtestC.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ -begin - const t = 3, f = 4; - const z = 0; - const two = 2; - var a; - var b; - if t <= f - then print t + z % prints 3 - else print two - end -end. diff --git a/hw4-gtestD.spl b/hw4-gtestD.spl deleted file mode 100644 index f7516ca..0000000 --- a/hw4-gtestD.spl +++ /dev/null @@ -1,9 +0,0 @@ -% $Id: hw4-gtestD.spl,v 1.2 2024/09/17 21:48:53 leavens Exp $ -begin - const t = 3, f = 4; - const z = 0; - const two = 2; - var a; - var b; - if t >= f then print t else print two end % prints 2 -end. diff --git a/hw4-gtestE.spl b/hw4-gtestE.spl deleted file mode 100644 index 473cea6..0000000 --- a/hw4-gtestE.spl +++ /dev/null @@ -1,9 +0,0 @@ -% $Id: hw4-gtestE.spl,v 1.2 2024/09/17 21:48:53 leavens Exp $ -begin - const t = 3, f = 4; - const z = 0; - const two = 2; - var a; - var b; - if t > f then print t else print f end % prints 4 -end. diff --git a/hw4-gtestF.spl b/hw4-gtestF.spl deleted file mode 100644 index 6ec3903..0000000 --- a/hw4-gtestF.spl +++ /dev/null @@ -1,9 +0,0 @@ -% $Id: hw4-gtestF.spl,v 1.2 2024/09/17 21:48:53 leavens Exp $ -begin - const t = 3, f = 4; - const z = 0; - const two = 2; - var a; - var b; - if t < f then print t else print z end % prints 3 -end. diff --git a/hw4-gtestG.spl b/hw4-gtestG.spl deleted file mode 100644 index 66bca40..0000000 --- a/hw4-gtestG.spl +++ /dev/null @@ -1,9 +0,0 @@ -% $Id: hw4-gtestG.spl,v 1.2 2024/09/17 21:48:53 leavens Exp $ -begin - const t = 3, f = 4; - const z = 0; - const two = 2; - var a; - var b; - if t != f then print t else print z end % prints 3 -end. diff --git a/hw4-gtestH.spl b/hw4-gtestH.spl deleted file mode 100644 index 873314b..0000000 --- a/hw4-gtestH.spl +++ /dev/null @@ -1,9 +0,0 @@ -% $Id: hw4-gtestH.spl,v 1.3 2024/11/10 12:54:14 leavens Exp $ -begin - const t = 3, f = 4; - const z = 0; - const two = 2; - var a; - var b; - if t == f then print t else print z end % prints 0 -end. diff --git a/hw4-gtestI.spl b/hw4-gtestI.spl deleted file mode 100644 index 693b36d..0000000 --- a/hw4-gtestI.spl +++ /dev/null @@ -1,31 +0,0 @@ -% $Id: hw4-gtestI.spl,v 1.4 2024/11/10 12:54:14 leavens Exp $ -begin - const z = 0; - const two = 2; - var t; - var a, b, c; - var d, e, f; - t := 3; f := 4; - print a; % prints 0 - a := t + d; - print a; % prints 3 - print d; % prints 0 - if t == f then print t else print z end; % prints 0 - if t != f then print f else print two end; % prints 4 - if t < f then print two * two * two + 100 % prints 108 - else print t * t end; - if t >= f then print f / f - else print two * t + f end; % prints 10 (i.e., 6+4) - if divisible z by 2 then print f - t else print z end; % prints 1 - if t > f then b := two; c := f * f + b; print c; print b - else print two / two % prints 1 - end; - if t <= f - then - d := t; e := f; - f := d; t := e; - print t; % prints 4 - print f % prints 3 - else print z + (t-t)/t - end -end. diff --git a/hw4-gtestJ.spl b/hw4-gtestJ.spl deleted file mode 100644 index dcdb9e5..0000000 --- a/hw4-gtestJ.spl +++ /dev/null @@ -1,26 +0,0 @@ -% $Id: hw4-gtestJ.spl,v 1.3 2024/11/11 21:36:18 leavens Exp $ -begin - const ten = 10; - const fifty = 50; - var x, y, z, w; - var a, b, c; - print z; % prints 0 - if ten <= fifty - then - x := 10 + 25; - print x; % prints 35 - y := x + 10; - print y; % prints 45 - z := y + (y-x); - print z; % prints 55 - if (z + 0*9999) > fifty % should be true - then - w := ten * x + y + z / 11; - print w % prints 400 - else - print z / 5 + ten - end - else - print a - end -end. diff --git a/hw4-gtestK.spl b/hw4-gtestK.spl deleted file mode 100644 index 51db706..0000000 --- a/hw4-gtestK.spl +++ /dev/null @@ -1,8 +0,0 @@ -% $Id: hw4-gtestK.spl,v 1.3 2024/11/10 13:11:33 leavens Exp $ -begin - while 0 < 0 - do - print 0 - end; - print 1 % prints 1 -end. diff --git a/hw4-gtestL.spl b/hw4-gtestL.spl deleted file mode 100644 index 09a6e7f..0000000 --- a/hw4-gtestL.spl +++ /dev/null @@ -1,22 +0,0 @@ -% $Id: hw4-gtestL.spl,v 1.2 2024/09/17 21:48:53 leavens Exp $ -begin - const two = 2; - const three = 3; - var i; - print three; % prints 3 - i := two * three - (two * three - three * two); - while i > (two - two) - do - print i; % prints 6, then 5, 4, 3, 2, 1 - i := i - (three - two + 0 * 5021 * 6414) - end; - if i < 0 - then if i > 0 - then print 0 - else print 0 - end - else if i == 0 - then print (three - two) % prints 1 - end - end -end. diff --git a/hw4-gtestM.spl b/hw4-gtestM.spl deleted file mode 100644 index 6734650..0000000 --- a/hw4-gtestM.spl +++ /dev/null @@ -1,18 +0,0 @@ -% $Id: hw4-gtestM.spl,v 1.2 2024/09/17 21:48:53 leavens Exp $ -begin - const seven = 7; - var x; - begin - print seven; % prints 7 - x := seven / ((100 * 100) / (100 * 100)); - while x > 1 - do - print x; % prints 7, 11, 17, 26, 13, 20, 10, 5, 8, 4, 2 - if divisible x by 2 - then x := x / 2 - else x := (3 * x + 1) / 2 - end - end; - print x + (seven - seven + (6 - (5+1)) * 3402) % prints 1 - end -end. diff --git a/hw4-gtestN.spl b/hw4-gtestN.spl deleted file mode 100644 index 4caf4c5..0000000 --- a/hw4-gtestN.spl +++ /dev/null @@ -1,25 +0,0 @@ -% $Id: hw4-gtestN.spl,v 1.4 2024/11/11 18:56:53 leavens Exp $ -% various statments -begin - const pi = 31, e = 3; - var x, y, z; - begin - x := 3*4-2/5; % x is 12 = 12-0 - if x > 0 - then x := y+1 % x is 1 - else - x := 1; - y := z - end; - while x <= 10 - do - x := x+1 - end; - print x; % prints 11 - print y+2; % prints 2 - if divisible y by 2 - then y := y / 2 + 3 % y is 3 - end; - print y % prints 3 - end -end. diff --git a/hw4-gtestO.spl b/hw4-gtestO.spl deleted file mode 100644 index bdaa427..0000000 --- a/hw4-gtestO.spl +++ /dev/null @@ -1,15 +0,0 @@ -% $Id: hw4-gtestO.spl,v 1.2 2024/09/17 21:48:53 leavens Exp $ -begin -var x; - begin - x := 2-1; - if x >= 1 - then print x % prints 1 - end; - while x <= 10 - do - x := x+1 - end; - print x % prints 11 - end -end. diff --git a/hw4-gtestP.spl b/hw4-gtestP.spl deleted file mode 100644 index 7b0e307..0000000 --- a/hw4-gtestP.spl +++ /dev/null @@ -1,29 +0,0 @@ -% $Id: hw4-gtestP.spl,v 1.4 2024/11/10 12:54:14 leavens Exp $ -begin - const a = 1, b = 3; - const c = 4, d = 6; - var aVar, anotherVar; - var x; - begin - aVar := -1; - anotherVar := aVar - 2 - 3/1 - 6*aVar; - if anotherVar >= aVar - then - print 32; % prints 32 - print 10; % prints 10 - anotherVar := anotherVar / 12 + 2; - while (anotherVar*2) < 3 - do - begin end; - anotherVar := 0 - end - else - if 3 < 2 - then - if 7 > 5 then x := 3 end - else x := 2 * 3 - 5/4; - print x - end - end - end -end. diff --git a/hw4-gtestQ.spl b/hw4-gtestQ.spl deleted file mode 100644 index 6a62aae..0000000 --- a/hw4-gtestQ.spl +++ /dev/null @@ -1,9 +0,0 @@ -% $Id: hw4-gtestQ.spl,v 1.1 2024/11/12 02:04:20 leavens Exp $ -begin - if divisible 33 by 3 - then - print 86 % prints 86 - else - print 55 - end -end. diff --git a/hw4-gtestR.spl b/hw4-gtestR.spl deleted file mode 100644 index f76436c..0000000 --- a/hw4-gtestR.spl +++ /dev/null @@ -1,9 +0,0 @@ -% $Id: hw4-gtestR.spl,v 1.1 2024/11/12 02:04:20 leavens Exp $ -begin - if divisible 8 by 3 - then - print 1 - else - print 99 % prints 99 - end -end. diff --git a/hw4-gtestS.spl b/hw4-gtestS.spl deleted file mode 100644 index b0a92af..0000000 --- a/hw4-gtestS.spl +++ /dev/null @@ -1,11 +0,0 @@ -% $Id: hw4-gtestS.spl,v 1.1 2024/11/12 02:04:20 leavens Exp $ -begin - var ff; - ff := 44; - if divisible ff by 11 - then - print 23 % prints 23 - else - print 97 - end -end. diff --git a/hw4-gtestT.spl b/hw4-gtestT.spl deleted file mode 100644 index a54ef2f..0000000 --- a/hw4-gtestT.spl +++ /dev/null @@ -1,16 +0,0 @@ -% $Id: hw4-gtestT.spl,v 1.1 2024/11/12 02:04:20 leavens Exp $ -begin - const seventeen = 17; - begin - var seventeen2; - begin - seventeen2 := seventeen * seventeen; - if divisible seventeen2 by 11 - then - print 86 - else - print 42 % prints 42 - end - end - end -end. diff --git a/hw4-read-test0.spl b/hw4-read-test0.spl deleted file mode 100644 index 945b59a..0000000 --- a/hw4-read-test0.spl +++ /dev/null @@ -1,8 +0,0 @@ -% $Id: hw4-read-test0.spl,v 1.2 2024/09/17 21:48:53 leavens Exp $ -begin - var c; - begin - read c; - print c - end -end. diff --git a/hw4-read-test1.spl b/hw4-read-test1.spl deleted file mode 100644 index 57fe061..0000000 --- a/hw4-read-test1.spl +++ /dev/null @@ -1,12 +0,0 @@ -% $Id: hw4-read-test1.spl,v 1.2 2024/09/17 21:48:53 leavens Exp $ -begin - var rd; - begin - read rd; - while rd > 0 - do - print rd; - read rd - end - end -end. diff --git a/hw4-tests.zip b/hw4-tests.zip deleted file mode 100644 index fc1bbcb8f693138643a7e3660a153f023d81aae0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 631641 zcmbTeby$_#`UOgN3Q_{nCEeW}(%s$NDc#-ODIne5Ad-R-(ka~_c^7-1bKJ1?=e>75 z&qV)WFveT+{pLHrB_ja}h6)4%1O+teYpGfsqz0}61O%iCSO`GaKqk(NRK^a5_71ev z_BIxZ3eZ5HaTrX-Cs<6zjxMl3z+m4&L4p4I0p3LigdIX$%lEX={t+}SI*qUb~iC2riIROYpKPO55Cz4Dd!!X^nsDhV1w>^||8HKK5OpT5!#$;{vK1jYS z3Oq{+wrD-+Y+TK|sFkg^ULSg=DX2{wy2&6*%U_?F(h`|zKM8N@HmN=1Sq)4p>OH&MbYB+>RT2+<#vY1?R>TIt-1j+qhCi{F zSCl!HtdbifW0{bm5u>7}`|^f*aDrT(c8WoXmY$Y=f~9hbg;AN7zLvhKlAcLvP)v$a zV&sjIO*xs2%*uwixYXFEwGBBL(b2It)Uu+(lpwM7F#Y{s@Vb0+KXE4Gffe)jhWb#r zG|8RHow+mtJq?YHy6(4Tzv9jGC*DFsRWN?EsKP5;(au+p3v`sifLCr0OOkHmS+AFW2w+#1YcTI@Jp#{ zL}OqM@arSR?#X~GA3N|Da-!;`S=PlQ%^dbdb_PkKIxahwuLpxXSCULo@L|AJ#Wapd&{AEY@F%O)qLzoJWr{fs3jt z^#uuy#bAr@`o*|+O{r{H*q|{z-#pL>0gtNP(9mo#pDH^Tv^sb3mb{=Y@AnGZFo)rhSuU5+9mU#8!Bd zAS%!t;v6ZKtuJounRFoQ>&gZZCHO)VqM~D;IV&<38rTIOH0HUp*#0DxYMAe_KKZYB z;yEV^wR~ozi7)}xY(Bye&$7hx*WuqkHlG^lgnXzqv5MU`6J3Muyn}qzZuhCt3OWK6G1D_1Cb$GkxjddwSVU=B*EsqA7{bn08U_>~yOgz-?X z_FC4kp>OtM`JxAw5i5DlZKPWj-BKj#*@7YbXzWP?8j55J<%s9){y9eYyEZp(MOoct zc+^I{w}#oHKF~$l_$8khpbNCoVb?KBweWXg8>15hq7vIP`_cJ z>09&qsiw6cgybQBo}lN!$NwiyhLPH^fLhSE1m4l(N=rt+@H&s)4ccv6Uj^Z%LFlVD z*JqYkl)Ji>_G5?X?&!fE3?r{&EGeksxk=w!>w~7+&~{hHW6L#z=DF67HDH&Mg-63A z8Ap-9S>>7;U;tgdrHDwvU{B}ObC8=sjL3Oy)g6gDd5)JpG>}3LfiaA^N!&pH%8-ZA z?mZVsm>30;^(@zyW3=48r4(ao!=PdM!kw^&o$ z)z^r2pL{vt{3+vTT|l221eyLlT?W7)OV6Dw@F#;vh5uC?1s|PU
=S1v27)E|%q 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 z z|3j%bUcR%9M-UH)gNGM<1{*+J;4}2j#l!nwNf7=N=zo_j?B!qC;^O6iZ~^FfupktN zL;&0%4($B!V6iMOH~5!a>6zFWa7gP|8n8bzFtM~X(KCkd{Eb84|Cr#oK|l@=A2&S@ z5X1q*LU(R34_07&^gJM3+T+)Pv(wQvH{js@8(05x`~5r+ZVp`H;!m!4AbcDk+&=q% zgR6hSdfb0*z5XV*`p+2nA8D`)l!xo@;1J05dm=CvRr37`IRm->1tH)+$zT9^{skd7 zgai1iOc@aHF9@+}3j+KCI0J#dCj?_|3D7Tc5&$0Ty81VB z5=iRS@ae+!m7I?1mtidTC@=g_cKKfPeW$n&)rT5$aQ$?@?HyR0<$l5R{-IscZ5MxP zWbu>~$LGtyw{D3Ep@Dur8b@m%W-z;SRR?H`WQw;p(`CHs8xO@Z$#Z3VfNO>7E^4ON zFBhm0$hXXnc3N&`s${)<7`-aD%@W$G*Q-Lk_lj;KwZJ~_V0&8bTP6($D}~ubtGB5y zS6AFpL%x4bpBoo8d;N}f*CC~5_Fe_BHqNZ zDuVF?>Cd%AUY`EQb(pEh=edWrxIw}!=@S5IRhXF}$@&MA#SKx-Si6#Tx*ech z+d@=B=*5z6=XLZd1Qlha>19uzqZ3jThcopDWXHgDj29lECLVGoczgz?c|JDbdE8su zj{q}3%)c))(|C8>u#S1x)ph5Xp|v$`cD;N{8ZR*r6j4Y5v}Sv7-VtKD6*Fx6EJsMf?9>#(M0XjS++cFKjX>PUbf)R(3 z(lJXKHhP>dqL5DnQb9ycg>cA8NqVE^^4qX3+4PE!52oe4ssEy%^g*7BobPoq;o7P z=U=>6fEBduO-rcX%rq#sNqcWq>Abt*+b}jVI(Ch><~il9_a8bezTU_?`WEoR{KS)U zvV-fBIEa3i$eierxO0>SU;oo5kJI4A(<7q(&)%G9cZ^fgyZ|aLb{I||FcprtGqnfV?ph%8oEdaE(l<%)v8;t_M zD8DPshf_h;M)jLRhlJK-2E%&><&(k#VlPFqK3g+?eEVj>p*n_jQ~-uV9my))blQK^ zT7K^9`#NMbMPx8xf81*ftf)4na8y1~J3vDLVk4_b913_T5O}F!r6Jp-c0yRtc%wG= zW6cE{3;zfK) zE!vYo9Q0}3@+*El)LDJgTI)MU`*UfQx_Ei70-L8#2^2Q0gY$1O(ZS9uKp*X~WsO1( z3GxPo2A^pJ(>}vf0p-6)H0&nuKv~q-!EBYTKP^<%D;qUG<<6qu+UAq$`UV`SCUFvF zQn^vV5GKu7!l&97CtG;z`sVA9D@8BV6DiHIDcw7DqO+iS^WgcplX8YA-y&G;k|UEg zyjEih*XQSG-sjrXhG~kof7gu)x)o*J7|m2;mT5E7slcxLP5YjuLUCzS5#?sb8}FB)p1z99@jFyWr)?pYjUmuTMVtb7|5?DT9@80N?K z;)HZd!2OGZ^sXTS=Q{&|+)0{0+EY!Kx^gtTqL5Q$0S}4&bT5`AziKZ#3Z+oh>!#;P3r_9RglSX@p92fP4^VpMhyXtb12+|juW?#gJBv;+HZlTTO{PFRvLjqjLq$tL;h{1>P zrT^q3y>Na(X%3Qb&88d!kC(I*o6lGlC%S#?X&JN;p^8-BryjSph;V(fN_UF8)V830 zH(ACv{D(@Zr5f?VdD-(ZkMTyVuSw)|dsCQAz;0(ed6<53<<`t60+o>Fi&BBL!u~JI zoyI2ab)MuAS7TL9DJeuo0FSR9Xg8e7&X9<-ghwu>(F&WW0tMAZB$?6R(JL0XdE; znQ?MMY$f8lzIA*F$wzQXLLEy^dp9(*Bn%F2AcN|=GNRfo~bY{ zcotQOeY(=fv9~R{mpb#UDJwE0;$~Xbo}VmpWt()QM|{K=5^p864--e_4duCdJky6S z>h$KwJ|vfBzFDCZwNBnXEm-Rz@@8tv97Ej}d?uy4nd#&wBV#{jm4QF=rf~fn7`@Z2 z#*WtJZtOB9(zosG*U=x2jf!@r81X0%l)9I_FhTi5q!(<)UbPN%Ofc@K=UX$+xF=g? z%{u!Pcw+LyFF!IqS!1<9#4Y+VjSTE-)@jR!s)N;gsV?spo^Q%?6s2&)SesvoZ@!oW>OWc zp^&j(b&L2cOZ|(cucS@IYwvTLax-TP=XKU#Pq*LABv!nAf{|G0wpk15)Ovr*fid1h z3sypW?Ytb1|3>j$0`zpKPP%Mr>v8c7f_uS2m&FF3mYVwt=x*L&T8(SdFp@G!J@=OR z={%mXwNXgnNQrHfdNJb1jTqoNU2FTXJ4jb0DP@U05U?tDBxftvv8%v%M&@}&{)+Uu zm8(LT?9WMtf*fEG-)?($yYcZ1wX2?l3eX;_U9Et$o|lU)*{SG@cq*`jDe;Uz#*=dh zu?dM}-&i}k-9PNXdGmev&Ry=8)t3iVzq$sRbO7J9IWD`I*FAq+HGAXbOVZd=)p4bH zw)?hq!%y1FAJ;Z)nK|4Z+N5^kGoiTU)Ez9l;iR5vmbz>nJ1Y+B6Kh#4i6x42Y7Ul& z?L~gvTMdTZIh`nSN}sFq_TA4XdAsCT7?;6h+Qh&w0Xv+m zxf7Bvhp!1}w>Ba;4cf=UUkTm1_GYDz$kV=Fsa7++gd9eF`9rdD>ze;UrVGizTb+7@UmsCFHP46;kbP<|IH;>&ZDiIuZBg$p05<5EduWkLU_U~;)5x;P zo3Ri#J@JWK=;2*4>jyM?jlA**+qxuHW>Y0z4vm`~*2apqA9nFq=aDT8!-F=Ydn&UA z0<>@Ducn!B^#{wU=y7Hp9$92SJl`t#^PBO?dR}SMO?teN7zvlFp-HAH(rdWEbK?dG zk2c_$_Kg>i(#ptSDsg2w!;t5pqA26+FNN11CscH%e6)L$W=_Dw5`KM9)Ny{{nVgI_ z{mw%P$J}cQRULd^7dbtVV+-dB6gGxlM2e=wnO=FvvjKr8 z92;L#Rekmz)gBV#+i{s1&E+}xHaIjaSx{YMd|DCCF_u*KFoR)6r7Df#O54%a=Hbh0 z7o;0%qx%UGXx?DbMp7O?wY(Jln`At{%{$pD^J!9Y_j9(U6^UJ%8x30R_z`9y;O>~% zneq*tS)0+v6wuZBz99aBySU$rc-lHH2UkO4s&H?sxcYk^-QA8BL^N~fnSYV|1O4md zAL#GNKhVFI{No1m{Zsaj8}vuo4+QvIn(t@X|4^Qf7k63)mvQ0Y;N^qR1Nnd)T)Yr^ z9x#xD8}OS1%-@n#Ai)3NF+jlC(Iy^TmXD8{9>~MP!3P0j;V~}<7l7xNTvN- z&GGnejQulI2mR~J5I30XcSQe5Y6#5zdm<2!n*;cZ^9EqR@96;CKn@7_7nvb2@b`o~ z+*}-dT))T+fkD3~# z{rGE^156JF{c#Nh;!>f1ON;z_*^httFDU*zk-^Q!`|oBy3e*;@hMTURu2gwGB8of@ zjdc|X+7WvrO9G8;1%cJ_C8^h*wA`f+V3CaD-0gSVd90eutQIxEIrPAh4>$W zba+`pL}T*abi!)3R>cRtyOdPs&+LkV9^QLqd!1QE$6MKCi@7q^goa5ZCvOmOg{FIP z5OJMme5`Vp(-Lg2uuLwiWqA}>1h_l(oh3Xq-nGPe_lY%-X{7a>?R~CYTVVwj{;kfm zk{^60m28D&j7~G-F2k2JH!9~+$PVM&UpK{mNcb=;9^-4ZRzS9aURkJ8zA)o)?ylao zmu%qy3}0pQA7%@?R=>Dnwt6?{V`ryV65CzI2cc3QbCQNLsz}$aT_O~2IRB0+^y3em zA6LCEKY2vTOck#3dNXp^>_icEmrEs7=AP1xCy{djS#UEjy%MW;`*neHfr-T_6Sul} zRbUqJrcjVLLL+&9kj)p!`$Kvgn6tnT3-}yXBD0yNN^Fes7WLeSM=mnN!fLK3QJA=a z1J5BLpMtrCVmTdS>z{ktFw+zf*@-;5bm`NB~=B-q>*1w|~bhbU&5$$@H<0&QNGf?E=rcZ&z9vwPC;WFC!Z#SKYKSw?ZYC>IV zcqAq56t+QNV#F|aG5wHOO6T0$^oAD;JL;qQ7bmXht>0D6IVOH?@^p&)qiNt%nR?QU z?}gXuj31>x(m3Q^ujK@*MX<<$b?!{{yW+p5)ViRbf0r(doA5h6xQ0N}+&hK*whmnw z?~vd?&+__ZwF8F1WStw<A?`){rE^b{>WRRKl;sS46Fj~N^d4NtG#adDnwgRPELH8oQHz|FXw=gf^tT) zgcjakW`1G#!nsX<%#xmS%=E-1@h?24cdfnD)TQ6tD3-ljbg@XRB+X+u&_}LXk9dUN zSK#VMYH0g~i~B@V9@aBdYSkQ;f=8rtgbO) z;{?3E@22y?ylAjN^R)5}5evR+-=9L= z51va~^`pFw2g*%TePBP(UD^`972AJ=VIvY?3C{;9%#WM5(x_clUu>tUeP*k@OpwRV z5^I+c3cGF9ihg!UEpS$cmd$9jCu{b3NBrZxd-pCB3{4wD8J^fRxf!n-!aOY+BTvci zpRjXoq|y$R9#h6Ydq}jB865P`##VMtq&B&-QC?~7=~fc;7&qt4Z&T4OM*jy;O-KFOK=Guf&~u{2o6C4 z1cwkDz9C!A-urNN_IdBQ&;93n=Be(U?pj@|s#dRBzmiq8HR`6)I^IX&exA{#!;v3R zSlaG4*j)5JtBnQ*M$~rG6h)!b1mX2fB38WpTIozuyIPMjhVcmX@#vDh=;aq=cFA)Mi5gllD5MIOuNtHrp5lNcRmRqK)@1vzsc8-n^XT& z@!>D3rKb;p%J@7a35*Cl*Mwi*bzy6=4@@Z+VoZG+vU{w&CG+0s35us-sHY7oaoPf2 zyJ8KahtuAntaW)zL7wZ%1>c^i*X5^Av+2I=XHSn-KKc5bo+j&kKnzGxVLV=13_bS* zVsorV(BGF&$D}ju95U~*Gm>}MIFmi{r&@*AAoF@6OK3rkk|eEp(eR*oPLWtK71{Gb zD0n}T%iBnG`)f~pd7SIY;`6cTSVVsfv)pm-mCIhkrNVWB>eXZQ&A0)U0HiqTcZ>dscC#|bC zlEtbv_o zOXtk<*vEfMWiK|-6@!WEJ+irvS*Jx$B107illT5!x~P&_;?rlV7zF2UG*EJsf%}F; zpcnc|s-`T4f^MlG!=z3!@qAQ^bCq#JFd9%Z=46j zJ>TQ5j8TV6DH;rj#UR%DQVw^0`tDL~=8<;uHS+L$DhI`L?7E>hQpnNc+4(_XA$8gG z4U*%hgZeL4ajtECx*W&h>3RFiEGIi1_Em=uzt9ud>L<2TsO0gzQLMS( zL^zF>3Ws64va+@$gvRp~UP|1qcnQ^HD9$xW%Qb&6r)Gzx^d!TPx2NIj3Ehd~$H3C+ z{AR8iE=5s^?9W^t)g>~@)mCJSZ;s|&4clB2mGNBBKLrx4VDr#Eq9pEjyje$BN(o6$ zudXU=^OZBtW6aVER5s6SLp1;!S^4U$Q;(0?A+q=-`)V*mwx83t(SGAq*7KZ|4~1>m ztt|;`33=uS|E5N*b00 z-o?!B-=`1o{tt)2fl#moweP{;TkypXwIR6y5U3>zzMX6V;{VS~{Tm45`zs*e1N{T6 zBk(sww{sXkKz=AO1i*a<1mWZTyA*FHt_$2fX3Gcpd&1kP9{hJL{^8^MIiUdWT`BVa zgb)G&2;8w4o|{kLCxkrQ03QB3Mv3`=e^1B_1_Ho5ccsYv^Ofd5U0n{11C=4*9b>+K z80Y;@(CD8bpg;Ku_-$>v0JOUQAp+_q=_{Xw>}OT%zlM<2%+=-;Lgd1b9^f;`aLHpm zh1iuQGD<2w9evof+~xOP#%&+a3!&q`L}!+qU(;97vOV%VA-y} zn+j`BB%PBJJRqeY%s4s@KX=;Md}Hwqjj=3UabfhPLSvTqib_Sd*XR{BR_*79EU#K? z8rG~^vtyBzVe=ryltnsA-lLgTiCW)YS6rMg6@8RlE{@}Vh}y91h}6RQu#G{h%Z0!* zVqNUP`{S#|sb}VqD-LBBUzgT8D<17ZSX1CRBn{V;vX3HHx46i0U(aKu)LT-dwpBO0 zYX6Q_f6>(lMoz#~XFv?kLwd$Sv>B1tbkQ`;Rtd+3I1y}=D- z`I_h1Q=$`%)V5O8V!x_&4sIunjenze#{cZC$_oq>|9FG@THEuYPbmQX=jz+e;fVo@ zfdY?AKd?%o`%%-5_wEd%tYxU!pgbg@73TQsh3!Pi~SAbB$zm zA2D9y@%I8mg9s^GZg-18+&B8#pVX?3IQ_g%_k%fdXh<0aX}hJm3Z8fmZ|(BI2_H2- zAb3rQawKB~=ot`-^y=UpXYPV2Tj-8^kX&&p&N9#v5s$)xO1i(^RpiaMx& zHUpXLk6T;DU{LJMs&|nd%G0btSK1V7DeMc4&>n+BSdl`VJU81yk--lLAeS3zd zw;uFY&{`c4ACM*Wx+n%tuJHAZ}6&luo(DKB_viq93G)$cZ5^M>PCJeTSu7uTxd<96j6gm!nfr>T(qfKe>M*!gXtxg z4>IZ#Zdeb2e?JTO#70zjaG!6yRMLXjzD?)^l4@2SB~g6jN+b|dw_I3;h>Nz9oRMnN z?`T`zYn}a(BT}NkCRrbg!q$93=c70cLbGps3J0PheB`WA87(5F##%8jiLcWm1G8&g zHi&#JFwj4=N(V9-=o+BdgP$BEy6wSK)UjE_JODzOwpC3FptqKfDoPZ>f@yiZzGO}R zN?@_(O*E-mS6K140`6l>lY+omVe>(cji)!VHULzq5{!&%^o?}m^q=N=je0y8vly|o}Fx*z^ ztq>qe=u(<&K_H+)ni_NIj{_JS=B(a(o9 z!rL8LPgyZHroiXJm{@ZRQ!X50IprbT?o=}OTez<=t~i%coOmxxU);~;kXhNf357G! z(&y(64yQ4|e(rNFhI7FnhI8Bk)3~bPxT9zxI>#o1{nTsPyl)?)1AnKH-|e-{g;bo_ zn7qZrq)19{bit=53unoyG;RFROGolSF7craVx_cX=#npPz(H~^;rL7XIz6RcQCrfv zVyjMBkARDdH!8hh;5>v${S0;|R`Ee&XwOhvq(2m`yd<7Os)(8Q`_fm~BAp-2qx zTldXI;0&1-E;zxiA=>%X%8S7Hr?s34YDrAA&s_#~GzzL|L$sf2GVTw(_`G!3kA$io zal6S)-o^_%YykmuU&V2L|08RMJ%8>Xc46ml9FK!dgZhy_Srg?)jXQe#?pE4Zi~=%t z2gF`{6a}4%78K7vTc7%voJySVWvVe*9>LBaV{o1D{R6QrJso76R3|JNFQJH+q89_M zvm}G8B=ifjxX7g+w@$cxb9Yf8aiY}o#8 zA^$UDR^X2Ad>%gFKX#YAqp$Bg*MsZzsp3tDa7^OZQ_)KFx1MpPI%Zl5PPX|OY+E zuC4c`vnl`&7aDGk*QyR=OOLzz>aVU!2Zr3dy=N$@t!@st&c3gIFPxaz{K_Hzb%n2@ zeYfZM@;LWK1a#2LUn^}zoKvQ;Q_{WJolCv2(XDfN@d^F)BYjSvc}mwRmH@4Kdyylb zgZW(FZEq0-vy!w6FX1s(gO8gl@D@y2DNSX|+O^efmJbI9;=|YMSEoZCTqaD42Tzhz zeC=OrDJ_N7w9wE%i*3>suyY#Qfw53226@n`8WdGmKI8FzW_vX{JLDAF8usatZGW9g zPPy~dV83bu9bqS=1-)=Z{=}KRXtAgWucB~#$+7&pnp;G=Iuu*Qkk%|#YY`|f6;P*0=dF7$OHzv8 z1Z(sG)~2(Fxl<^Ll{2iXw-9SS7Vg+gPwKgzeDgGc3%DL& zIwn6Vr8%FK!EE5wk%x~u3CR3rmFfbD9uE=D?2-d~FX&HXpv&thc{i2e(w#_0S5`$( zmGfSwQB^A7V~>q)N+sU}X1po`U9lpow`OM^0j{b7YpV6|u!x0Ix9P&8t$J3wtFmbK zeraGF4lc?VVSqRrEU@XNERZD#7bEO_AIT%B8Ghh6(rWjiaou$*YTrnki`k7Ov71rp z?23;ib{}l!*zgBjuC_A>Wi9iW%rln{ZX`@SUV=+QACv>eaCs;XKGBALmla&yvGzV- zJL0+I5J&L2?SUwz-$d<@yOtLt>fY{YYv6vQI zj5t2O(LVAH8c%u>hP^(Lotd=fuU@0Axxt4qvnWduJyquN9-5cMDheB=*iRmsSc*|t zD}DO~wlJV(8kb%I9w1MUR-s6UcHa_5h8>JThl=@5PC^nW2mOmj78DxqYE~5HhKOKTi2~wt!@SbwwoH=uEsUF z;j`R+UV<{gnl1S*d&Aa+!jywSqRMP}=DGWgm!N&8w02*xMePd2i)pmk!W?Lazd+R3BY6C55BhdEN%KjjcBM@ODjHRE_2<^IF+w5{y=t@v@ymF~j$^?+z+ zU<#ouO&k#{f+`V=I4Bi+6!9L6I4*{mvar(grFT^kr5UVPOqV$i_;HXU%e<9ea;HSc zNZq6M1K*?eXShe6qxQ`U0S_9+j-(KJoG)H#pj@j#=8r05b4%%z`pEC=pva67!HIvB z0LmG_$P@w*0>QzCG5t&?7@HhA_67-~^=?C)uVn{~o=}oGuTD2P0avl@-}`@<18bHddG zt$J$?$0)|Q1q-LMS-fYYE9QaT=_PT(Rdo_ewbseV1#cIcAYu-(TM3GiBl``Yp=KVqhciTQ78y~=p8h5FeLil=t&3$ zQIHVVO)&t1k~sknMm_KCCWmRKFP1sy`fMs~6{ohe_(u3xNsO-sK3AWv7SixFQH86pBzGSckbms*dG8EJPsNXy!Ll;%(w`z@oByR`m@%xxDS>k}HjiHmS zn{q?-SX@GX!Hh2`5q~9TK%j|oSyHH^<-lF1+5dwgYBv(!;$HewK4sj_Co7I-O|QRy zBm9JsXt+b+o1Nr%dBiWv;hP;_b4i!CdUlalwoYusIKF7HcE26LYW=*X*s0urE>3WE z(E>AKhnSYpBC)t&@511FhuzhGxBFCEk=nEWi$wueq>z<4qXs%|nN26x1Q!_g2MORF1+cB)FuSi)f zF3hy!cSf{HXSpO4>P55JOfID9UfBBf=tj-@kdB#_fyM^Ew?DF@u9@^b=Xct9hQB3P zMg&U}#{r9gM+zez2Gu~_qA=nePz_`W)j)LPvfNFbudk!Wj^L}tHmx|~DX6j&OP1Xv~$hotsVw~6-go2jIU(RIlKJCjz!?Y#Bso1iP$B{WD= z#7Z4wJtxdNxh5$ZxnvZiO}w`oE-wsY0Js=qYo-w$*J8EL9;AQ`&QyF%cl@o;FMB7b z_Q$FGD4t-aV9&tka>7+87|fd$BfsKWBhVjSBwbogp%1cW{Nm3iq2pBauG}YaPmYo^7~TP@*n^w`RFCjrdF*N_DXlC)^9Uuh3hQVOF@I zF>$zC@#dTX>+P9s?F$)vn>)#0Qj6C(F$4Q@`$7J%1KAX9D`0{~`w0T%N&CGOe)A5Xd#Ck86>gI=1%=-Ymqdzv`!6&x* zO_h&^{&jCNEGVx}f2~O;Gh^+EhOMtq`&_w*S1Q^#S&B%PFgJl_Dq5)qOlY1KjQ>Yu zv6!SUk}mx)G%UlgC}A_jIFCLM(E?Js@3l}neo6PTKZm^(T6`xt|J@6XFS_UZY&4TcToiQt_iNj#26WZ>4f4T-pcjAdu>=QZNR4 zA^=*2F0pS4cE}e&3ST0hfD+W-e3QpKI^F`6)uNcDO_xs&r^MV?UR?$ds z71#{zS*8!AgW~&>$(71IVqfOjkz84U(t%RTg{6<}`6G?2iE)+sukYo|sRKqdiM2k> znw30K8Xle;7z$?BV8UiqYb);G$f|6vfLb*VQ0T0nR?Un!P!0n}2F)IY9&yVBgGt-{ z>}|Sa@!^L>8-FQ@+`a0?hKTvY=fJo&sHJz?4k7^se>95-f#2?t22Sf686Rs}HyaS` z9j~3gY98lYlthka81`+X#KV?f8;ZPWJZ?X5t)&L>89i_)`8NGvs-j2V4~3`EFXHJO zGPG&@4ok|sf?z5akN;jyfQzOxtwpS-{|zj(NryjECl#f^lV3#!X?A+8wP3Il>ZH2J z>~{LNdb+het~QVs^;Y(Tuq-=NRy0Y{#L2-T#8JSApF`D5F|6Oq4@fjDN`(>*MqlX* zz9Vz(FFiK&p#WD$y*uRn9t43JaZpRK8fqy*{6?*ymZBpxQ@ed68HAzlFhwqD7adRJ zef1XZ-Q(_OB%t}OD&u(B>p5%0Mu?WW_YpEF1D}3g%$414$Pt2IVrewD$AdxIOAX9p9I7b(VIMvo&u6;DeNsPc@^rS%4>h`Nr-h0M{P ztxS|8=z<4jgIP?Q4C^5~8} z8-bsX+Y0>qxUIl{H*Wh!(EQgCM}dDZ;`mn|%zq*RaYF#$TL*Und;s8G1AqcQ9~}E* z|G+;O`1*(a1AKS%5Abk<{+s@R**ApVBNZPcg-jlPLTQsX&7J}G39i_UP3VQ*S7{z<=VDnNLy&%)-XaI7IgU5Q^u|KTa^6D}i}7;e{T$CX;xV$mIGlCQ*X~Tp z;maHR_?m$i?8(!veH=aV5JWw+9*umOc*vzS z&}_%eNmM$!`QUi`V5dO)30HqML{we$s-C61^hs%R_yot>7o8&(Pqvs^1)qH%;Q8Es zuK578IZK=3Z0%I#_5FY+d+>7a33CQ(@!0q25g* z1fHK>D6*z%6c?Edw|qAKI+(qy>S!$5;lqHf{0L(uFPh!@kZvj2gjtSZIj&P_`DX>Knf*bqBrTh2gHteO(%RC5bd0-&nKz zO%nGr0@R&+HJ*pb6Nh@MJyNUOll)Zs-5zgjX%8RVJl!zK53vJe$RJ@ ze3t)_4wp1`v(UDQs}x32O1t`JKfXQDAQN4x?~i2Osz~!i995&rdhJ?=Mc-ozq`w|} zuHyY%5}>uU)?D<_lKyMPnGHs7@|UmHEhll&o-MdLGyDs#o(q1sIaf?JbxQN@6U^nF z>jF}gRgF#F$BV=DrFeGQv&5PFKDIb@l&I_om?4$ME+TDGz@#-RGz4l2r_xgA>#Y!z zJh7L~lWXGf1nk&7%Jt#!JNE!4{k*Ca4E%})WUD%Z9zp6z-{Q-*0+<*zi9bB7E=NmC zz$-?>QT5tldF-VA5(wiT<07*w452cKe@d?4X6eFQ3Dru#$?hP^IydsRT3aI>^ zBW60Gll@AZAJK*~IK5Vzgi3Y>KQuj0n?}j0fR=zyph`JoS!&C0j-fliF%188r(?W2 z?Pq>eR)kf#w%H@&d#x;3(LwRAi#ReuUsVrE`>I1S9M_R#-^8k%wGDT@J6tJwW}NPg zv3l6X+fu_Tz|$iP0;E5oPDUQE;i}h_Od&e4cMu+`eWMa5KyHrhd;JL&FI}y2vZ_%& zy!(q|-UW|kh6VQ~(u*N^IU}Uk@?k?S^EVds9fo!1p9LYTGvwi9r00>L4$I5Y^2?sj zFA#(`r*nlmBRlsF;|H^vSRR=XU{oR^!mBHFz>MMntudkUqY9NDdDL|w7O5A;PY<%K zTQtgcOSskzN=B}W!Rr;Za>9xAo5S@I8we&e+zw1TDy&+OY4SE^tV}h6t~Y+CX*93K zKFt|$+gr6282VMPk}TPvA)TiAsa&K5z_w9E_@AYbi|V3q?R4-vi$Op+^_UouBc{3R?~)a>J)K<;;s44R@PN2}h&^op_r z&wGj>*n+a794?N5R;?i4<7d8+K_YiMalWL=;CSIDNc6+dBkLk$;gpuHVfe) zH^F?yl}7&rea!Bss%~(Tf+l=cRT1~XYM70n`Yk9k0RPZ69)I8y>Uq7=rw2+L`h`nD zw)3llF}Bc0?<^VSvrN4Yu@omI_3)cNglJ}>>Xt*lds!Bem!4=ymQYq~psbKVS$Q#t z-qM17!K&pu(%8gqH^Ia#$M&XW4gwO?x{x6+9%I;YO6A5LU@l~Sf8Ebe=2~q(X59Cb z!s=nYeVp;MAS!F#787eyxmt{Zed+{&sa59CHOxkrd7H^9ieVe7>h9BDJ>~**wo)-4 zozH%?cI0mDaQeQ4B<+^4MmT6$s>l$rM2II7BZ5lLk{ST}j==~a6SMcNOV9I>dLvh> z+3Y&k#yVBs+}ccIo3&4UGuVqGsXJyn_Rgva%4s}WLPqg}@*ObFs=&7y&_Y;E z9j05n)8$xf?XcFQRZ^6xCKdDNDkV9q^dLfo*-#=@JLs30T#w7DI#WQ4nQtc*mQXJ* zms1-l7dr;&<9$8`p>w^;w<8-R*3$yCBZH8@neKuDtew;vNIoyOXK6+97|c0axWCd;a*0~_D>a%H@@ ze}*SGq*xqu0~Y2GZn@e=(-BaVK$o`d3MZ(tlJmw*-<<5DIwpo*mlD4cevcY!PqBWD zt|E0IrFF$?8;Ad#4APeO9=!ybPhccMi+&Qe%*p5F&P#J$^${92gK$uV52xnDx(h^a zgfD&A6Gern+G|y+OY(`(=Ci3HYW&5Ks_)844+)7cxY(`k?Pji>JTxkOOzFgsw-r^V zdRmoviDgc3PDO_6imvL4srB)(Sfcf%ZN{k2pXa#~%q8;}#Ke}! zu~kB<5Hhu7tBQ_dED9NEpVLe-+`Fn~{bF<@FTjGm_mO?4J~f2)Y}#m7R(hT9^9aTw zz0$_=OZ!cvd-Smn%P&v(jxBnN*&nwh*LVp|?iN2BdVzh)!-6F? zD$bV6v$BX*KoV>H(2=0(>7y4D*`g>u*9V_FsdquGaUj6B`fIB1rH@`asr1mrmWDh% zZrEU&+=?WSkjj3@tj0HCIZ2)vwqcaXJbIM6DALe5W#DEqUe|fPhiw3_R~1JGkYRpN^az)GX6uQPt}nCL z+0q#R4HFd2mRDKz=6Cw-VCgQZF}waj53)@_9Q`6*TWjs zryjOXd?{C40sFk38os`p%DeF$27=u_nV~4rtn9DuS!$~P9i@oL_1SpwV zIeY+UmU zDwqdE$`|e@=^lH-o>lgXJx^D+99b}=Lak6*&+Wh;ry~QbJM)nU?t+h^_43U!Eboza z$H}i&ag13ZG&`grYtk=2y8p;0I7Tej1y~XqpBk%+m)IjO7`ZfY1iLg@(#uPsKYlnX zR#Ln%amG@Qormz$imULo(b|VY+NA`LW@;Y1{It#9u6;Wlb%^AW-@$W&wl|p^L~o5} zT-cJp8C`5DTIZN&8~hIyqaz=UVN5;Ld>Ud%jQo`7%~zn{;g`~x?KHJ++NvFyElPq~ zh%{a}$eYo+I8L9OTn{CtIk2ij!NX;-RDny|`;ltEU_3wjB7|qkC=EeKigm~G-1&(N zhO=DJ8+dqUd6hjYPTIJWI*rVo?eA~Wt_)?KE}qP9TI)S_I=d2lKyQ8#K<)WNr^_lw z(pAHCKHUf=TwV$_f(s(DJ~}DpSMA6h2%<;F#TkE`!KZ1p^Z z{kZ$llkrUg$3XH6c<|G6A3=3AFI^j(!&8O_#_-CpGJPa)Cb}|MIl4%DZd) zW3X0)B#~?PK8#aRDD9MMb5KwWRU)rX1v?85)HD-)c1w2z_TKBEO%bLlqi5;Aeu<*Y z81#0XG5tMH=;~go6j^Dl#|T6J8=S)j;qO;oDf?Hv8w0>IKG5*vtre0)@Ac+-4T&_E z*+XZ6+ghd#3CmaST~K%EI_7D85{Wr6rKW}hH_F?$Ai|~F5d&(`}Dj zt}Ki$%}$5*lw9@0S*nvmTt>*yis?6ORaBQ~{fKEcch;R%td;&x?^{18-b+r5rJvNd z355$bWo<5>7w@-WCx+x5*(gZAK!m*^ybGP3R%b8Z@&ei!UK zSE*CCZ-_gRr5Jlp5H5>Pl#lBuRi<4^aQfhj?xiNZ#NcrhLf;uZ%#Df{aJ}NG+d+Nn zY}uBQfAvHa#x)YqrfcOE%M47mbg+9vVb<4Uru) z2cG}}-MJFl$N)Y-!N03KVs8ne&nS-}23{{an@{&YUeOUf5JNpPZJ!tmpn)GoeMi|h zG{3Wx{f(2e(9wM!1TP)*{SePDc@5z$E}lH9PRV0IYE*ZZGkc;DnCi_%2MJx%C+3ZG z!)8#QzS zVU3vk`hCzF#!`kBXXAWZP}$8sQG>dA+ zdt1TsYJqK|igYR1(nf^waI3gx7bDHNBbkHY>dmm!w|&aiptnO# zn+w-;arTWdVn39?B2shl24VyE7=TYy0tD_mZn(ETa1H;=9a%$DtBCj6KFzJq)`Tt6 z)luW=tcnqsmBh4hM%%c-JNW*LZMq4M2tKB>DR5)XJ=z=brO-;^;*;>;j?;Y*u09=5u(fnj-+6<0=c$R4} z9hq=c;HIyYTaRwphb&+f&3&1|{)0J@ac3u7zYG^f7&;>*yq!`}*D6Bc)+Lx+C%sOF zxci$g>_^F#jM<%lK{(Uu7Tru8ox)^T2*`R&N8`;=OGOlvaG%Xy37oTnhi3Twz2G~l zx*829jKe?BzZaCum>1&_7jNPuKF+)M-AkfV}P!iZ-d)VGkewjF>R3e7u-M z2z#hj-LdsrD^v=W2wS&2^=dE>OtQzXa}mI7yn)%N;Bhat|1nJrY+|r^7TKOBeg7jt z%hJ-b3pi~dsa?9KElb@&EZ-jFYqUg0_fK9l%vTRXwbfPC6JM86pk)x^bznF|?R6*stf| z;;@#sM}(o3gMY4w7}olLoZZ|xa8k@kOD{z3CAUsKS6F{TRwWoGNgvf_#zyCXqM#1{ z&;@Qy;#w!OKW37e)D9xAr99FA3L!nc-9uzi1r-q+i>KX#WIi|FVzcxHeQGNyl$PK$ zo2NyhIV`^me;I2g)DF!?#ybFr_m zWXPr36Ngx2_GuwL)4)c^MF{na)#61WB{eMoA<5R(%u-70z{p#Of#gzp$)0YYaAgF1?*&e8=Kv-!s<&oOUwsH}p-tlra1p5Z5yx39y-@zvc z_*3xt3k3NS_yhs}uiz5|{ADsb2*~~G8T9M<-yQmZfd9M6?NERV0D*7!P6Gq@pg4_R z007~K!axBCfEUF5H<!kQatrkTq*sHR_pV+I;6I-;kZIsd z-ay#Bc+7elgKQ-zu}_W8+ZVC@p6c17X~*La#anJ9;Z9)sFf3_Cdr|KyhDtcOZNe(z z*qs#YDscZH1&8Bq_mkx2M}kj9U*#4)t6g8ut!aIdZ7FD+plv<9v2EOy%6K0_KW|C* zhBPxXdSN@8671r8c{H)Q6vN(B5ru_?n0ql&Fy42z=JEN)i#z>cZ}`Ms@+ZFVvz_Md zwe9mS8%sOWN5e;}wtJuMeerRvr|-;+rAs&(ZQfi+Z*Xzhy}tI6dQmyFak8d49{VxC zfsaVAiR{XIudwbDxy+l`4_os|0W4Nm13b^{FsgcXYE`6AnrAl04_vA#JVC}i{IT}& zZ1oYmQlQN9VG+|u&u9I@6w1e5ltZSz+`MU) zjpl;z*2TfB7HK5Skk`p#loKiA!pf6%ztcR*xSuXaTJMog9>%1eTG?&jL{@6h$;4^edS7$UReBo7yt(y) zSOd)GA^&FkyF=2rqsf!|44n&buFp{<^t1v5Q<1c^NFtSg4=9o4a=826|+ZPZrLG=KeN6-}fN?hId|WK>TMSO^+^pJXc0) zDGZW;2pvVqk+5{3Wu5d>m6#3ss-a+iL9E^<*STsh z&Z)2L|4u@xLnFzW!w6GWgGixM>-Qi-uddmM1k>6t_$a1H@Y`~D?O5#Qm2}A-r>drQ zZppB}71C2J-M6ckLJinSma}!QZXSH85utHYo%;xD+)RmMf@VBzKxUl&nYxT+C7AZB zSLLe+*WT#s!IRwN3Rt>wWAYgOgTyO2;Sb=Et{1FtyIk+zBVaCoA<*K+RL@9(Q-5Tp z1izoB6IOM)=JkvXK&`4vVUJZuj$wV!V;Qt$43@xx3XCR7B!ID-Oj)7!qS#ISa!EZx zUP4cMC*^q$Av6aBzXyq2_A+D4&@e(~uih?SJf`cB%a@*)LB8V2(SAR|4C$ZEl~Xg^~x&pXn^;K;Lj+cGyT z5N7e%@$~(o6aP2b3Hrjg*YIhB`~BMANgj|1r9|Zu2FX8u9+l7Ts&sXQd;_!jCd}^T zN|)Bj_<`8CFeS8LDL-)^yFd%p1)7r&j>c#o91{gF2jf$iT)Yks<|lTB%w~gpY@Ya~ z5L7vx(TqEBC$X?AD+(&mOOfW{#=RIt5tp=dX@ts=(>Thj#ObQTz#0$}nw^=|2}JHi zDMy4%(eEKhMoXug42D}#64m)t^Z0v%VXM_TSf=Oyz%0(5Ri9}Y z0;|>ii}k!^te&koQRYOZaz>9}fiu*%pUKK8v3l!~-hPHw0Y9_~_@Rt1IoP6ocEB9R z3NcYb34vBY2(Ns?mz6E|_OcXrx1HkCPqPPvU9H`@@&oUVm2LJKbwV3@s~+5ZjTl8q z?Y0a;fy&J*95Q_|=tm8UyZQD0i_!88M&`8V>W^0+K1XR@(-)SsueC9~NxK*t3fT@= zT^K}q>_$0+?%2?M$S{B6tt)fo*nHwj|D5^}-n~!m-<+y(Y;}{6m6ZoSNv3#KbzwiL5Jh$q!`it}`+QU1ht={^ zM@LZiBXUhwm~hs2+HYpRZ1#!5zAIUpfz`B~h4JHkUlUSc{4lh_+5@R2>>h1P$g4bG4el4Mvd*~ zNL!uaKntL#pO=O%H-hE02yN_+2ypJv;U=h-oVTTZwK=uo1|i*8n*D)3~lw)zDQ|b&X~CoPYa`pkzaNZ zz`SHD@b|-0^Ybeiv=Vy>R^*1;^g%d>?G;@Uib;xF9ajGggOZDD95sqk46PI#I&jl{ zLK_$u2C(Zu(LC%2W+a+`~d7q3g$TNaN6laOVagLCYN7~#Czp3>N?Fhl0s09-85~N-hy$GT6WJw^}^!5NPDJ__SKsFvp}D3p?wyk^h_Ph z_d#ZlXcq%h>|N%*;Ks|#lXQE3Vpr&_C}hE$2TkEbQZ$k&f!$x(RbF+Ru1vcKHV%sn z#BeR@4sOiKJEW?h$y;K&dOGX%t?f5>^ji>qf;oS|^(|pUu)MU;i>YAc=!j$c!dATs zb2`*}Hp%_)pmXB%>0FYH!PcQTD^-t-auBGqbpAC-nsEiY!_GJ?l}-C0yO;UN<&%n; z_^-WUGuGPfR^hFr`}{8j%SG&}Hc3Kt2}f}1R`qu$!@F&dkG#Jf1Fn%i)nhU7@yQAl z7^>S!6Y7Lcx5z&3NpWa799m9MQ#Xs)|N2%ub$$f<17ZxZ>ce4WTu;7|c0oxy&7-u@ zvHSDL%x&+&Eqrq&80$LOGn(csHP;ewZL-@suOdmKqYYYMN}8e8)O-~ee3q?p?}V1S zEt-Zq;fV5lpOA1{lWyYv(9X!w^v?3((`E6hy`@P=&?05L7mujJY*fueNvP&wR;SkM zZu5x>-k3LEB`>Cgn_{=i%c?^lk+pScF_nz^a=s;<5JL4QYm>tYLd>s$8Lo9!LMJpY>k=|6(NKSH*i^D{ZE~8wcR=|)aBWtW;cEJ zI-V2AtJMOwMNH3)18^Kf9<@1(zyuv^*ayijW-f7#XeBd`ETRb0k+7D%-#B!WYLwzf zk%29c1HMm-EN>a8>Uw-?g&WD7V8Z3Wopp-vj2PP!m(y;c;j?jUbOo1hQAB&2@Yy=5 zKf@F?q6H%oq%6<-8>67uiq(yU1l=f-W87obJmTE&c+rNhicwzKCleuY zBFpz1zf#Vl!{x!D))N@lKaqbEale^-htV(;&zD45f`BfjEXRB_#bFQ2m4+uEhy*Pa z(VWQU{pL=J(;g%`3~O7Aj_yosY9^Fh)9B&2POr9_M9i`iiMoPeu(yh=x7{;}2k43u z?IuwxT?OGRdS4)@@FuCY)SlduNngTG)ricol_Q1ih1KSi-EMkB>G=H3skbR${X3F6 z`DNeYuC$T2w70cxJ4VwQqOQp)&va#e^XM^p`3NlL>1SD5VHGWlF{%>Ay{rxvmyedD zKv58+e1%2k{Q`XliL7~EA^VjdlHqj1;9lG(12ny1Y_heNj48=$kjb=_K^!w59hRMH z_-lCYxfI%Rl{~v(2-*XLo`s`z{d+G}nFq#>96nRrhycC}@2o5J?;2B*i)Z(->qe%iYy8Qqd3=lbRo{0ma@o=rq?ih^;B>5%Y&BdS7Cl)5#a1X@;ke8}Fx z87(k#;1lh|BOkwx*TQX4^3Q~QPzJ|7Z>0=arkZ1C+H>F#xV1S=kmBH!3!gS)ua{$# zt$uw8%*;s0_sOhi!VvF#Q%2Y0YGD(zZ#cive~&=4&D`g-NdIF*igZ zjmjwZ)%*ga>=|!Cl&U|Mb<``TPcT9m>wtXh)=wz(3Ksrr=fqI zng_9n^D#qCpNR}#?sFrT`~ZD(!)_UEu5`qAEvjRS?o9~giW7EeoQr&u>vrK7O!_bM zrIL4w85q@yaW$RXs6XMZit0Gyf&6| zC+MW--j1j z5eL@r-{6v~JIdEzT>?~F!{9P2Wufptt65Qbi-Khkf0ii5R%!fn+S*_rD=z(mIsBRO=lI2Rdg{ie@!p zC+hG=#tXSi8tK0^E(+Oy)=<{19l`J&+d>$fh6eLUAkG;Moz>m)aQ7<3sA4aEmF5HC z*4C7F88t$!>6O|`#w}!6P8|be#7X3PWz=vD#@>{C@FmCWEV~A;R%Uhs=uEF&>!aDkVx;>x5%9ne{-%=8zB5ica~wJd^bD&*?4=jMLW4O z5bn8`9XkhI3Nlh=)FELlOwYHDYx4^P)COhnCNOn6sCk}vT{>aSQrMqm?+VN$H9nz% zuAlkro?ebs@?O&xU%H;G4Wu%vb$CbntGSD-9nt3K!(}>1XRr4Y+#A~z>oRFQ^+qH2oJU$i~j$J(Jwy2*pjV_qP09?1C4q?SdOhhRFKXG+HCgA@qZG z_+A(10#UVrbIr?XtwbW$kNCZ>Wx^nyg#78`{s!HBE>-0o3)&_UI13cQqI$t4l>KXbG zVyEQ^JibJ#?9K}HckyjWu|PSP2qas5eHD1rZJ?E95e(HOES36ZF`<9`%EdzVH?EQj zy8Kseyk)%j1k3DpLtPwA&q=p4P*?yZ_-QqtEcQlxn;JbX8b0woS)9K-y}pbl{w~*9 z=pQrB^Mvz03rl$1#MtZ5!ul_Qqau^AcIChiGgcErGn1zc2U7rr`NHYJ{SQPRE6y~u zaw`lbTNiN6=S$ia>U>adSe5KCw4R{ZbhLcaP1(p5nNEwonVOkAGk~oZ;y=!BP&g80dlho4=@)*7#d0wyq4&#fCD5Lyu}NS7-uaBFyaC2#CotP0eOxT=ou zQjQ;e;vi^pPbvA}^1NB6`ZJ?!B zE%!USG;~&rIZ+j0-eq0dF4}rO`U+nk`SIZ*5m4Jx=RHcah*U<1j=Fi1)U=2yR!$Tg zS5wA7@++Sw6T=*!pv4zYz66#`W!Sih-6z?e{Px)*a2Cs|RY?7aZM-;LR$JJ`P}Liw zOSiT9u?I|2^XRn<*Fy!k>5KB5$HSTRNzWPA9-+@KfHQ_bicdXMcGGM(>_>c@G+vt| z%wZl8KOj?*d)bbHVn{EYkqlKxC%`5%#>5*wAAczp$X2a2F&d3S4r!;V=1oGcpdMN zFd1)rP-d(QkCNGb{c$14M8Ub<2z1h0wNso(RM*M`|HI^hxo><3_`s;X@Q~C#c zjXIC>C|P;R1zAdz9nR&l6JxB7GAe1x$E=1jTEiBPeiHzz(>~S)r3z&zu?TqO7_vqySg?%cWuM3!wQHZ@P6R5M;KBpt-k-} zd7*rL{j(S~gT{@MnR<+c!FGX^gy{e>bo*Y+&1a>fF>DRS=bZb-$$Iw2ncTTIWy1J= zQgxTyn2w3Bl${j{HLWt<4DwH_?`TJBhF}>9;P$gIbCeZXnb)5AV!eJcwhKD0823z> zlP)hZ!W7>5Dp?4*SE|*Y`#$mVn_>3%N8Rd?w$rtKbt5f7rI6B>br|S-Ty7@zB{O*T zX=y{D=}scAJ_?F%yTm5gm!R6*gsl0(2H7#|-G!P2eu|oY80vpPP5l2AYWm}_E%=V% z+5e&cVIVgE0>v<39s$7Z_8lM~^bBPS%zL}x2KetbF#flpP|&|&HGzLHX;|QIh(H1m z0FY|gAn}pgtr^RfIxhA5c2+v5CQ-R z+%d2Sg8YP#8wB73-<3zczbE8@VrK3;Ht7X{_uoxU*ImnpGXc55DehC zW3y!t&)-Q7H}u2c0fT5je7Bwh@94td|F60*{^+^xA8g6{m#&RJ_;&tpyEb_4+P0UQ z2l&tD+AGGd)Z?~YXx&%JDbd6b^Q$;yRod<m&VfLW(^=wxc7uC92Zc}Y4rruP!XJqUi-_ipO0pd)Te2i# ziy~DBu?8&LHAKgOS=?e#e7dvi**GT|JE|(ZCt4gr3K*7^kEJrg3z{%oN44zmcfYgY zc8Ja{e3-gccWAga4LwEoj@mg>oe&~T8P)>VvpukI7ZtsRPf2nvNbG;dpjFA-do-Of zyUXci*F5G*eX`ZQ^}qu3(Q!NEgp<>Ad8ePBXYT)0MZLRerj>s*L2wwqQ}ScKt=DFRwnp5hm(`BW*;1_tOvJ8( zQ<_Zkjzzt>i7l^oA}wG!viaiv(Q3UoIwo4l z_}7og)bMt;f`hF+uihz*cYvR$vkBH17gQegX~%b~D)#3%@9Ml5tVu?;pSgMCO^xg_ z^l^6>q0M3DYSZ@otK57h61MENrHY>pMnB)wMBXqR(NSfZ*sQ{XmyuwC(7<)n$)Fz0 z_%V_grgReT0sZf_C%MF`R(!;9Dk_8 zqp)E~P%lZVV#Z}wOHeX(#EK6qTEOC#2(c1*n#uFN)jDEjKDe-XYNSTl+^I)2P2ttI z!uyEdmX1xy4po%VG-?l3@^XT(4=ExkMORh7b|@b-+KfoW@-WXl|7=75h9^Cu_p_U?_*|G<&BL{d4z{l;F|n zCR*DjFiduQ+Mqr|a4_A>&@Wy8VL$4mYgBvH4{*3)0;9-p7U2LScu9Ie1la< zNt0VgUwUTU8W=j={Wkg0{RqF$GhwnR_3#&Byzyilm14OF>#i&{CZ{k@w^9>J9w^*@tL18h}wS=w#y+} zMw*R4zU3p!hj{IxrP*L2q_f=iIp+`W9W(P6S5}OesTt3cTzlZQt%g_d`%j8nQ!c)V zDt0~^Fq=VsOAsQ|FX%)B%s94dsEasD(ivuF~8pf?kWh{$?Ii9&0 z5=HujLln8uj$xe5_yVw@x(=p;borCL$p8@_ypSHWLBRbHYD(yrM`RDCf%Y1DgJ z(D7VB~E`;6lxSy#n*=4^1pm~B*D!4**L>1RyJ(w<++bv$nt9G} zITj)Aa%)LapRMDos{MC}{e_}QSMoLekbzegi>8r_V}nAGSEnQbc7r%^C@V!U*@SQ)2^_LHUjZR%Tl?jnz zMc}K0T7v@M+}6fezR8gEJLz$-&i>W2VAi*7?+^1Wm17^nR@A{SC~RIP-3QJ{Wp}cB zP*=yH23kjiiY~E|>ULvsarHzgHnDSyAt=ddAES|sDeH^#;=5>L>GXA}J`<0$jOFEO zti>EM#C?|O_s(!7FQFe8b(rtWL<|pj#U2G*5o%(8c28rKoshxJ)$Rqyd$r-IZhx=M z!TfxKH zV@<9f_^#Wqvxemm)A#(V#k)>70pzgqrj6q3ry*D`)N)1b%F=eaU@uG2+wMn=hjlyQ zjgObCdSVs$@)jJx588G4TG8$aeawJxbiz-*%vTB3W+HKpi97H5a55Ffq!7$D*-j3_ zoTL5}Rf|M>2%jY+acSTasTd`?jqt=-5c)h)H(}^Qn8*rT;jU#ca3qu=8+Ac^S|4k} z^lPQEaGAp=@qNz7du|gQjrSv!hRmJ-zZJ5mQY(A2NwKtDNg7ay;+jo9$u)L5#!fsw6sbeVtnMUd=w`-AQ`?1TP^ z6x|LUof@1YpYV5$z9i8Ig!h)}w9jZeSR{CMBQIZ^eAX-?%MJNJ#YiJhE@3@~L*yYj z7YN8dBbsE6cvqM!#u15WGo_62FiPn%$pC3J_2DFv=Y{vC34$Ov3J&RU)AD^kN+(%l zqbM5)?C7Xw`gvq}STu_pwlTrN*ZxGl?~U~}D8qHJRL(n%oEk%B8#_BR*YNX6@87R4 zTMJ{BY=x#N!K3YhDX6}bvKFl<-Y3~x0xop%_C954Y_x=!VV-3U_cSk7+#K($B=z~R z_KYLWfO_6MPnu)vrK#y3oN8-To~>o(XHZ%@7<{f>aOmN)a&K!R(tHogHzla)xaqlx zh?mD+w268WtSA2@z5 z3_3OE36<~>YSqzxwy=WvIp1pm&kuD z%ta&D7GaK0QrS)-0-_EKsmNb|F$VNGrFJ7oAF=~Sw9AGGAEz`vcFBDmXm6QTg>0hu zsBR1Sq#C_$9hFexvS`jGvCWgQ$RzSx;rK%9UY(bn^X6Xiw-fB(*Rh9KS!kEWug`|G z5s|yHB{fdezimq7UD{N)RX^t2j%-V;>pVt*%TM^=O`QyG1iG&bm6R z?=;fM5@Kc7sqc8~M6wETqQ*xQxL$lyc$(LI8jaqFHx?{M%6i6*agq?q+XZYZCctQz zYbT~K>S4!!Dnd$63nP9m`r)xzjuPqp_a390TfJP@$eHm(U3c{F@ceXN-CxkkpZj-s zAph4^zK?;TJZ%>DO-ATSRA%*}lVA?Rm>ya2wt`dYv| ze@}Qj6`z;;4niKt&%Lq#2fX?(So+W4C-_cBYP|n=*PtD;+47b8gL?*!3)b*9G6d54 zF@*(k0Z3B?VtlA!3@E00BAS{>81f78M<9_8MFkN`oqwJ`_*^)Y%r>*@f`gFmTd$XCpY|FH zLfvoTIJYZ7ZrcVZeKmW1xT_~dAiN=FCSHK6vR{e*S)RP-Xa#}^>2|Xyn|`GC))*BX z{;*_O+?Po1)7(s8gfCVA4qr})UWm~6Oz_RgEO2VB|LYsESa*HLX)S5?=wqjjs_h=$ zN&Am(#9OvUkc!wQi^m@`f*S-q_h8UH*5R}BTPwHN> zHML3BBeP}{Z+pq2#H%x^oNroegqP4oU^lb$tC#FNGLob1oU(5_>pc<1aq?Er%c-{d zqHN%YLJdo^L_<1t6@UHw;LF9A$)kPkN8#t%A4B3i&||zuMG2*cumgvlJ0c)_X^kez zB#S9I0~^2fGn0&?j&-7W=(kc>llyX{Z&8@2Rau3&Ocz@SUxsb?6(TXY=4C5MfHV3% z(vH9=4fEwQ_L~Lk58uB8PiELPIXlxc;{_s8C@L3cQFj@cq92{2pGQPlL?M(a);1!lI)9%6lLC;_Tf` zm+wk0zpVCUj_rlsWA4*9>R~fXDm!8wP9NmS{ZxmJI>ZpI0r*CJx}2qscQvEUg$2i% z3wc#&b)K0KZYnTHq%VwheDbAU1G!mv`g&0)Q3T&^vP8jDZXMw_)!;ugGJO{4B>$Z8 zaF>Ubh2u>^^!j5>njHj=4?EXcxfzQX63FxO@HIrw44h2S1C$!h{Yu#0XAQ4?=3t;t zK8#8}IP?g_J3tU*w$0A6A%x>Y>J_WLAVgJ0rY5hEW9+EBF5dRf08YH?0AlhzM3gLF zeQPL27mP~84P!2Dvs?JqK>IcE>M83BT0(_tm25j@Vlgap-1rBU76d%8;7D%-+KFI7 z8o{?ODLXJG4KufU#9UuVb8OJO!@uSyJqd8kG`RHVl~*Uj%D8Yi$YzU3R6<7bo9dL} zM|mTC$uGQ`X)C8ITcdXvYnrt`Mf8bH^gW$Qgpf~fYPI7Ap>GYH&#GTp@BVfqWJxet zaIF_v;(n(?ffAk%tZXF;#Rz*L3MPZR+AxH@V+cbeZC+`~#fg;Ip`V&qwRF&P-SH$G3giu{Kr$Np_`pfUv$=ESkXlf-ijMH;-|Ge3^KyaqmsVp=QMBkSGc6bswIhZC|h5o zruK(*;w&eS`33WiA2^ew>2bD&_1g%p7F*_suoyz{-jRDgi7>E=8B83_Ct~53Y>K)O zxPGpjOGqG?SKf1Dvap^fXR66tf!|?5{<0}@ie>4YuLh{5#KPyxN9r$IlCHT5#$maf zG@)^oOU#8BxF^JW_*j@oAtnb+qMH^VZT4i(*u`#}PzCryix6r zJaaX^d+^hl^r2nII4t&0gXIcyMb!*o*ICvS_2Us>E(-SK9br9&OYtSi&yvj)0sdn2 z_ZWzR8uXT=Glht9aW#hOET1>KJTmB*B+Sz*ij|BG!jrP~CkR|Xgl8_ISFOp4$frGt zK{;&M2LnWz833Z~6*M~^u3z>e6%Eh7Os6Qx|JtoO6_@m(x)KqlG{aSD>cY6YX(O

Dc>bCi!8=L0><| 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

r>RQd&+_-=!2JAK`4ejD z5A=`JARKt;+D{TNHV|}UORy$apng4hI{6jf;=5U%|L;n7NmNwP>h9urxk6*ikpDNMcYvf^oK`8E0Kk56@d0eh=|ya!qH z01E*E5!?bI6u4>o6>90F-}-GpPvK4PXGko~N{KX>9TX$&+Z=__e#VXdw(c{#sXkD52trP#Q)GyPS&dH)f1 zPNQSL^`~TE7@~D|fdo_e^T~&a?CPh-_yYU%>}$m*a=le-JRK`ghS5Uelh*vph;(BD z++F^MH-D!c=HI?`eRBxsC-TO045z3OrNQns3wuG7#^$INqGsU2M)G{DWJR5dk&UD= ziI3a1@iLQPYy0=injIN_EC=i2?zgBh+wJ?I< zEG|L9i%g-SVP-;H2jOXV>tt`%%Q@x*?7%-$SSM&CP^k_9{E5uSc1Xv8F3`y34RtBY z2XG-gF4DZq!|i5FQR+v?cJeiOZFET97chOl9b=(1~E&c<;9R@K5o?m2+N*4o>QJ`--O9 zf&A3*8T^zR?FBu5lFu>DQmnDk0kQu$m{KW`lKzU%ecPl7V0nXJ<4Z55&4kei0Z^J zb+VkKjwih>6f(>U;{IGW9%Y$k-gKOgSzT3BF`XYRsyv91-LwBiC|Fow#}N#gg3UmC z4p3T*Er598D(PdeJ=^2bRpDrPQY~1>uNFD9A#+*vDSjVI+JOZTAo|EGCHfx2A z6=D~;!eV$^JkfTLjg1Z)G2O5(^!xbR`VjIP%KMbYerK34iY9?oLVs2-q-cVQs%MsG zzq;zV*pt~ypjv^SeOT|hnjsIPF*qa_S0B?iHI2Xh)qv$$7QJwar*Vz|czb`HSW|I~txIXYSffVFS2(3uF%i3uZxPZISz z(!h3l^W0u6+8kH9>(cxr#FJECV>lEPge|I;`A95$h~36k7fXgUpAWMBYjzC|0_<|m zgk_(*+s)Hnhh`V+5sqCai-XaASor7S)~4FA6~ne4GUawVf{@c20~)g+CfHjFF+?ie zWUiknYADlN2}n-0`+5H|NRw+5zW%G8%vSy`UU(rp;$cnt-ezRR&+@sp5zTU;_cD;5V#l_W?O=-Zn#4=KS{&bY7G zvE6ln<(IS)9U2Q2TEg!&WtDif+^rGMwjiUkvy>&?DO6Z^s*YU8(Yto4hD$_LcLf*Y z6QltXC~a`pT?+f^BulJMOMlf$2$^)1e&49v41IkCG1vT!+UNlD%~pfX|2qE53v=^q zR_FnNX`*o=5@boZn2)KI|7)I%$CT#cGQV8j_rQK-ImX)42JGV1n*mjvTx^Srki{}C z&``sqT#CE++ZUepa9{?!8{(|lEHcK?s{7Kxv+99D8zYT1Gyr$+kT~0ivM6_|FLV;K z{5*x<3{VE}w6);>y-6N;I_%t1h$Z>na_8{rWxn+!;q>!#<@xF|{?@y_e{~K3^iUYq zAf(mhK9EG>obM3pAZ|I`H%<6;xC}_&bEwsAnGwG^!zd6x<=z2Wwq0tZ$pc*QVH9JcI}n{YCa`8c_qMKVC|^8fm^fTIC_1z)xAney zx$M;|jRJe*>BWGQBm3OP!l>O2;oFqq2BO3Tk`V}Z6Re1GL&V%$gPiKb>s;n_2>e_H{MyPlDezR}zh1ZLaY&Vzo#$n!RC8WUXviGpj> znd&8i>X8|$hT`MFdBPxq+V=OvgB$CuP%!C3=9lSE(jX#Blrz6}b;hlxZh(bj_xyQf za6PUU5_vv0S|9+DY>`f5nQB7;*+B90*~yQec&6;Eo7`@)$Zdy0!-cr+!TVkcZG%W!6Pcs>Q*v{d@W9ymV{kq z1O&|GqS%TX%m>_)IRbLNrL0W{qj{d@b?5Po#H5N4A{y>9W4q@7XX8v*NZ~a4yI55d z6$O*VOhr3qyzQHb+uaU7OE!!YD)4p*yl`eavg{{8DLgX*2^rs6f3SD!VJ`yk_(pNT zTe>`ekn(FkwmqEKXWQ77m#0qmfd2Tc&93XY3ZE1vgq_gMT*?tQ@c6I%N(^gIH*36a zno3}TZV0Ji-H0fS$mMuufn=5&3(?Sug1lD-A@two+Br==uL-pH{%THU)0p`LciX;A zj%D7ByDbrceNKi472=({w(u{ZlYOo3D=e7$aM$`B8Xu^6{B0fuCEK%F49|&ntIDJq zZ?8OG1Y#~4vKfhX9n_4x&T0C0X$;bi-VSG1Z0HLnuN2VW_$XI__i6QvX}z&;!ta4| zYb84~%vveMuZo@)>!U{*AdJs?mHC#vGeM3JBIHY5tVv?cCI0NmxJ`alXv30L@bHX{ z+{)&A!ou6w$s87)z|EaWCQD?Se_HCp#n;>EwgYI&tDeLgg5(7!0o=I_o%Oe!(zq*GAEi`ItZ~jCItR#r0;b0JI&fQ~iB%kw&jftt`XZ zjX=3{ecuW5so$%R(>n*PgnbR6GEeuy;jrNFpx2wdOYfdel4MhT`l_o62p*Z|h6Y0j zMaoZEmmE^I5dA-(auOGC<(`8T<`LG)tvt?((D0bRrDL@56lvJ;m6zw}N-Y)OffW}@ z1xM{+Ei0I5xsL>GDjZHoqcuCo&On1ae6eg>Ccj>;`;_jkHD+ws%agO+_mPmIdw$Sn z9J7Z^xLXx090kk;{g*5Zep#NRM05+=u4gf+5!pV1H7-O@S--SxaZ!(Kbu$EPAEA+0 zvss$OZ_htcnfjQ!Zi_Q9Z4kGEBSl`x4NA`*u~4Ss{`&rclC3?){GMr8(ajGFkTp^% zcRTKmc~}14#nDa+cPJ|mz<91*lmsKn7Y@PVjQ(JQzGwfe*2!Y74SQ4xwmb<+m4lFb zsxwunZYOXA$AZ9;-*8t5_-3IW8Am^5r3PRgvKCun|3G{jwhr5BJhC4&S9s?jDHgGkM#3J)}L z46VQaAzCqml7hot$&Acfh~-AC=Rx2U zp|OOwYG$h)To@drcb<@{3{XFe{LVl0vl?nPeyv9#BGlOsib=)|mR95hH77t+s=S0z$CB>shY8Wg>@N}oDh&9oO7-%~pn za*0N5ws~`EF6RpE);4sDVMU7lD0$@&ZS{dh2YSeD8 z!Agv!!Ss?&A{b_{!11eM_p&krWj4{{k;!fy@QuE5Fd@MoWV3$4v=i~@t&<2*aP3l4 zP5vl{QH@#W=tP72O@5WhQ3@hLz>3zdiQG>jz51)$dR_Gj`Hop3MfXtjVo!)5i2bSK zn_UaXHuNDT46pim0b!IR2M&wYj69(-CT6g7yo)m33f<8G${kFMT$eDSU@KOXG!!2X zpGL0l6E<7w8}~N|2LB(tsIPhzLxdAj@+yWZi8uw$>QeJvR}HU&u6WuT7H>UN=}Rpg z#TNR|0hx~Gw`KD9mEP|j&xYv&2}V-Z(oUWaQ|IMhNj;V+TMdoXjLM}XlWFXJg;xp0 zy$7vxx;>!}vqX_>$#k`#qS&-x)zW_erQvW?vb^0(mG!>BDNb(gywp~<6Xb+boxk(q zL}6AF4rXtFN~uaAr%IfcM^z`8==UCIbiibk|H|?!Pbk@f`Kl2gn>16)GqxJX`_8z4 z^u`_TKQ&LEv6m;^SP5lob$DpYU|`9NCMlj!hn{V5?-;a(tQT^;D^CJ1Re30BrK%|=KQ8wXr*X_e4Cie6OsAtkuO`$p`ZnuA!ePSKlP2nQ)8!nM%@!~!o zmTTX=awi_qJr0IyRWPhW*S3y%y&mJToVxEFmQh@8?h?ymsCHPwrvFZZET19CmPQLh zfx$tr`et6n@f%$`oOAeWF?NqeMfneQYpZ!mO?zB!g}<>US5s;00_r?a6{?nAKS;+L zE|?|7@VY2n6GNI(#(1JnF#{;bcgbF|O+c%3iKreB(G*8g!&|JRfhK$pFfb;mc5{V- z5W!eSB);P@QfKbUQ4W#>`@i}wX=*P`hQvM+X;NM8%y5k^iZ5??fX1{w>8gD$6`kM> zhMC3cN#!lWS}ClsaA*IBU7@0l<&uf7MN&%K%^z*ttv|FO8?@Odtm==BG7o|_k0r59 z#$sZU>1j(-PM&9?)`kOoI2V1Te!v74wQWnL681X6#Nhq%OVj`)kU zK9uIF9$iniGOlIlK~D1D1#FZ*9ah&%6m$qsX6nFaj=d9`l7_d789*NNUg=TI!$S;+il60YyQVs)RUBV zHkT629J_rYwPc;o#Jws6ni=F5Q3{Ucfk*5qqvgac!vvr!n5D$V{6Noa*17}>R8PW4H{&#++W(R^WSu7 zc@PZBv5`EpBRuo)B8$&h9Yl!L9q$lS0rvs2Z-N zP&1f>;n5Tg5%qBd9_L>xzEW?Nokg(zxq4q%Tfc+#P1kjyGZ~uoAk-J*w0fSUIk@DK zBX}k^Nlfa4U7v4-F;G}>^!mfY8;Th6#BbirLjb9udEl?*SxM3;@`q8IQrX|~^mY9} zG<6WpH64q3L8)9WVQ|S__Z9Tp3&2R8>M1Stejrtg-)oa z9t?ZbY>!la(l(Awq@(b>By3Y5HEf0g^tg~Ej5Xn(0Df#oPd0%V0|dW< znMrw3_I`@x0lClQEH^^W@=9ZO&f}uiO8(QUckQw$R!Wqlb3h8p-*gqcDFr zhX%$iamzDK?VO;ctVZl8MN{J3pE(z81z?kEkB1vgJJV!Xgc|dQuRqQIk)u0x$UXki_ZuS)*1X z&GWX@eDR)F3vbG-+`Sp>)+6}Wi`c-$gD3qh%R-SC#xc2+OB-{e%Su0q+^e1B>BVnN zS88vli>=CN+P#iuy>Y60Ul7+WlB7CkIZq!}tuL6fQS+30hlyi0O_0;C9BeFVm3o(q zcp=YdD4VadD%EamICB4i5}SELemD&w4w4_1BZ-D@(?B8uN)D>Sc>#B#9`?@%xOcbN zR)29Ob5jeCR8FLkjM;=Ze#JZvgRs)Whc@{2NS)n+ zhUzJB)FLYwv37T%8d_m?#JT*o0@l^+k=Gskl-ajY6{)jmTG=P#(kgojVwY##yhOn? zSppC>Tu=kfn>sVUq4S8h^dXt{c4Xyo6y2+HS?0~qToc~r8R=5VStz^ zX2ftyqKd2Nw#VQ88re_C*FB{W{x!grYq2Y?SU*C_bLP>?Jc2i%H0sYxWkk4%8&^6F zA<3N~?5HYu*N0jQ)#5zAwszohpgv}=Se;#dbt;Z5+A}$5@>9JZzz$)=LdYXMMJ*pOU9*5*cNR(C2@8@rHdup*!8euOv zJ*K?w$E$b!9cx99&ff+Pm*^rM?1~ESx^wVsq?0N%IZj8GM^o2S!6ak2#kWrEEdG;9 zbK0#16wOnwE#{V%cS@yaW0?<^6EK^#M;TISF!I3gB~|Oh{Hjk{YSz zkiV!B@?#Ml-fZ$%DH5x%lc=_9H*YoKZ_7k#xV<@(pOPD6Ynxe->~V^#k|2GzutDaB z&apyueNDwGix2}zw%ekiX=_96FYP#!LLRw3b&rMR>0??5s{4;W z????Wxtmp}>R3OqJ7lhwFMlfz)#x7e?v`F(o$jUn))B70xnX9D0z8iM`9_C$=Dd4S zVBqGv5`6>clN^5vUw%O5*ZWKNbcX66Ah1IgiG}MwTA{QWL{hUYdDj@<=6UGa6qlA3$fQ*);VrtrKcS9tm^RqH8AHx z@;U;c9e$$hZMU83*1t6{j8;#`h|BGJogP+e;RNKF+>BeoV#XVCIQx1{lFLZt7||TH z>_c~dkc6(6xZe9bT1!hAgtNh_Hg`s0!6Ztu)j6Z$hL^~GEj=9;d0gm#o}Vz-cBQ{I zMYoM=88z?FZqzF}F00(4t>e>yRtu&t)j!Wen_-4O|T!FfPl~&=PDK z4P*QbS*IKY8!pkDD?QqWPI>Xzt-Md<kTIf?{J*M+@ zb%DHW=@{PYvQP(GNSaAe9r==?*x=_wa859FSZ!)>hlyaj^`}wwq`esu#k<(Y$qJ z2jHVsh(Q&Oes+v`m$jDG6sA7qX1Ty4 z)XXA8I)e|PJ#XJ?L${>Bl+!ypjGEiL0)(n6`vX~j$~U}*4p!W%i0aW?+`bgU>0uG5 zCs{eY;LUJZKDCg%B5n&$tpwaWON2e?U<09fi$eEq>e%&VM}1d>HQV)9ah5%?SIQt3LC*gM6T&A{qI^!KJhFBzUy6S&Jd%?Z8PXm47jv#6- zJ)Jb?oVt>!y7sxt_Ss!|g*C)D?4Mltdsv(Txu}UV_>$X) zGTj5^1QM|YKwU>r$(L(vBdY8oZIxmENJd4*Bn3Bic*L$UtoqLXpe~KKsKKayfc$z% zvT7o9@N~>wHAi-WnP56-i+!Z-n&q1+8HtOEN$$2{uD)@>5BIKR0CskgWua{U6vQ^n zC&82Mqs@)gwZZ_I9v3ipQQe@pdid!5mUvqb{5#7Z_U; zerDJ`SfaQJj02_pyZj|gyya}JE)Qx z7?OfXV%1mv2qibg8=(&`ZnXzo7jsYIHBmTKYPU#9YY~@-In1(sZ_Z0T&glro6Ju?2 zf9P^^7sHVP=!(DH+Hl7Z@~DNBdDTj%Uqpf3MIQU_=9*88R%T`1EUX_E;-{p>lN^(S z;>t--)!of^au_>wA0c5xh!VnyyP9`tDeY3RO#snW;;b4 z!m&NabTZv%8ci+ly`G3=%svDm?(i(vrZ;VgiApWdi=%56G^p&BZc$i@h)zl+IJUY# zx3j%>B|yW%Yv}w76lW~&IFGypL8JFqQIBfUXOS6rhdX+Ao^pLKX?*=2zX*{MK$1jA z+7PAalj6>fIX=2p4UlUp`5PsA0)l|3r&{`9y)FtZv^d z_6{&hQcE?%Pi55l4X1tU`)s}sR;-qWEE;GtMpwQlRGd4##d(z;9G>Mp-3VyDY4*wi zNxyauAD)MXYDLX8LlMyMM{#_O?X~W%g>;sDc-m0{xbDZWV-j9lPDOXz9zas1r$&ey z*T94DHz0TMNL06gaIx*gOgX*G86463} z(KZ*oDTa=QJQeu#Z#e-f&1!M?H?GvZ{>^@RGdGAVZ|SQl_VDtOHZL|SGZ(A#3HSh+ zb;g$G-wV}llwAJ9DnEkO&1O`fT%otC#-k3)RW8s}Jjc#gEp{zyYJ(N{`@Sq@)0j2O zpU*V+{h9tpUCuAZ?n2_<+H*G0OK7mWAH($vEY2-KN;6*-Gm%>`-N;D=#AP8UTlN-8?FzckKu1oX}0m-7x=H?4Hvqk3v{;$g+XQYrj&I>gn}Sc z+QlCCSm~?AulsHJ@lK)AmnPP{oxJU+2-j#q=j&SB7)eP~k`8fi8E9=-QQ28HQ-vHxl- zy{3%UMOe$$=Eo3*Vc4$R9>O>6s>0}=50vD9XKOS?2FFbry`_G^?!)jnB-mC-84%C(nl$zv@joEt8c~q~!kqr9UatcCm z^fWBaRPQYj*SU^Ywz0R9jV>(Br$XHv9xb^9rGapBfzwH%&w&gBiAd|>T7&b~C03dN zy1xkLHO2G{^>0k$qSh9-_q7G|~pyZ_4W0oa>3TG$x_905)MXMhX9#n$*gE-
    =Af5s0%wfhi2Z@8=$Lb8Ax@@CN5^$XoADIV>1R_H+P{5{wlAzq+n~lAUji`Q=v|#EdHtjFyoVMv@=oS4-B$cT{|L(e^H6 zR&P(QKD4XsjO<7(`pb-euLhd%(9iVZ`qtcg-j*!7-!>4}Vs8SO>j>R%@)KZJFTGdS zObAAc+@EP~`#n!vl;1xhB&oZlV03rOum1{{_D5uJczj^xiVt%R1Sh~WG?r|IpS-M> z-ml^Je8z7D>TS1@t+}o37 zSK#0mJ>XaC=-UtFwb$~g7x&~%-({~?;^%iyoD=)UCN#fhT~FZeIp(iTvpsT?JwzsjIy-h2s5D&7 zuj_@LtBMv%eo;#Z?Ok2ruO*p(Y(&C+@0;=zZFG(GuLaL$uMWRf(y!!Co%nCzOg>Q& zU1^2%qu%Y3p9tmG@{Y#v;18hTS0l1IXZ%<5D~OQ9_!R!G@Y4(AJY9nw=*kbpk&)s3 z3%~IjCiI+dwJ~%i7X1e3x|fuR@w@8o_x*D=<;E`nsfDGL>D^2rr*XX-W00Lw?V5FWp%5{XhKlNM#bEYNTLkNXv!-q#&Ux@I<1deJr z?_c~J24|nJ_b>DRp?=McE;Ij8~)-2yZ~`X zW#CPc4_#)qc6B-(R-9n^N{sRy)+~;3&kY1mfOdDU<9u;A?@0skKlzLnkm6|S)c4%DQ;L`ebPn&*#2@2frmQ<|y{Kn^=Tu{gU>Q843BNuAKG;VDSPmu#V zbCf;;dJ^ZzL~-OR6#2QdCfjYt^$=D+UC>DoDAP;)U%OWOvhK*N5-|0`K*dZ$uo;t`xC+M@XLn6FoYLvyls%YI5u zgord9&Ih8U283~!%MM8hsM<65>iNEfp6u!E=X*L}oEz;srI5T5_(>I5mXGV{$*eX2 z`6R0?psAWEWI+$-#zOX5 zuo`pw4s}4W>e9k*eg%NQBt!5$oV!C(h@sBSzD-w#ctlr5GSVmDDctYY9`jebe#!_l z=1hSp!p~^sM5--$1IK)bS&UsM#U8oWw{rzp@JBI!?GVz|^{>>X(u1#bDcSqAC0VK~ zIkyXJJ?W1bbzoz6GKaj1`$>bba`b&XTFH}Icf?p+YR2e~J+C#(AcO7Ji&C9Kf5=Yz zq`t}XmX7ZfBC2O;LCtZ}qpFkk0{dGx=`3|>m*{dQ&@DL)=fH+QDSYfkji2W(|PNt!{lxgC7#e1^I0Y&Ol+b-lmUxUW$0){T>)UNS?t362A&qx5xEbOtUd+9C3CuFkPuDNy7WP3+M5z?KR=-C6L?8;~2g+49Z zEVapzzNW3*$u?TjEyMhXCfvDDa&N~-|CHPaiG58JoZ%YSd!)N9{~Cf!Vx>0 zRx>;uLPqOn6sa7jo_w!O3eXn52trFUW%ZV4Ok!-8hZx~ZV4eyNio}Z#p%eAn>N^*% zFw;<+!`+>NopgHxKBDV^kgk5rzao1n0UD=LJThU!^(uzAReDX&GEXLi#cA{#*9UPnH{>EGc+}AMo|+V&6>Fh!uB1Lq?GwRLX<6wNdCD=Oah9-w zHpX>0IQh4ui%0jbX|jGB{~Mnn*ba%q8)|iiH}U7;P&iKG*8p0dVmP-sCA`h+z=f5x zs3*WQtpc3qjiX+bhfCuJFkz6;F!~z#+#E%;I#N4n{H+e>!|Z)Brf!xgs>YbF$En5w ztaEqyBt_#gzd!V{+F*Io6)x2AFdo<)hJ8o=0;H`#`T~fjgm>y|b|$db)%7eO!Y+RH z8IH0zB(JkTDa3wgnm20-jL(gC*pIU{EUVb&9oJ zQllF=f`ua}Y^&_cr*aBAn$O^bZO$2Lc82G%a0wLux`&7=5(3+$CO%_n7D?P-$5y6u zE_>YUE5$xSsl2RAm2;_Nx^&XqIu@l<9;^L*qUKRu(b6}bFR**QW94h-idI;D zRUVI|(03pv)E(~*0x%1uBuW$pC`fm@>vEw?po^lST5@@$@0y7dkGp8}#q z+*^rNK->*8yxN7Tf|?{7;?v4LwVoFgKC6ZF8No&%H#TD99ByOCD`|710u3y-8M%!a z+y{iPi-!r8-oc8uRyDhoxTp7c20S?Ozx=Q(It$5algY3VLv@#J2`qc?y@wtB!#Dam2nc(nN%oElMn6BKR^*?lz3f% z53SNxCDm8#9ACq$vfR8vAmGVK!(2FBKMDu&%jK+E#{iQInC>9nrg=)&Pf|*RKQB8k zYljZ(4V(-8`$Kd8y9fWP~yT#05{GQ|&q`_8ugUKCL@Zv)AI<5T@_C znM3e^EosQnb%!{++;*PFjc2H z+s;9`JkR|oChOfqr{mB~Cz=~S$n&zmq1VWzn4FXFS6=cf?Lv6rbtu^W|-P*W#l_wJ6y@w zsi;_7Jrw7ZkUmUXbTzmL?Hd%o^>YZW%JPRstso_NV-xpQ*JG_2k$gN=KCA)Roqvwc zYNv#h2u)tZxud)3Ulm#9b95g>@0#~t>~Q5E`}4Lc7aXf6c|1&vY2cA9W>G-*($7e~ z_dVvA%vQtc73|r_b1sPxqx-PP91J)9dR&B}@Y9o$@i>V+`8R|?H%kN<>>#$eGmab@W&bgEx@?&UkH40bsw1z3q1uCvW`{YnM!_}uheZyX#DCceX~FmUtRi=^Av>m z49M$Y#anfr9#-z+H-UyW!AAp|je9bDL4Fg6{sKre;-!&<%;UT5{4M*}b`NrdF!4O< zrlq9QcZyNxVUmXC0LPVq7jqStO93Kl(#a^*$&^?rs=1Q?Q_wEQVj42l z1XOV=o+C(tl^Ln;x5%}l`lo?PR9mX|oF|6HtXI7)u_U~*qaJL7w^}-KGgT!vxZOA` z;ic@U$Ay)&l7N`kg=0E_qmC=J{wpCw**>wdB4`6sMqQxOPg#0r63yD4?R(-<{vHputgWsxPT~b-u z$b6kuiyP>(Y0DhS;ND+up)TXp{1wMzu@O0TF@K=`OmZimkK1Z@<0k0=lBmSkqI(+) zO*$Xc>7Iev5yui?hzfQIkV=Dkk_!nqUzG5^Ge>mTr7(zJym1xB13|znwd5FZB-Zn- zZkk&mMC#Hcv$#mWg85o+660bNZE*DKw&@8E=%7@$TC6lq-oAv zW_O%!1fPPT6X<}d+Yz_mKKor@WkuXTxW14S--wc_=aWN)n30t@qup@g0xyx?qLbF< z{`?<{hXXGamw$MHW1ftS_6cRdA_#IM*xFQ(AEa~-R;LZV2`W-^e%Kg#9HX|VNc9fE zXfkaZ&=x}j&umaeKzJ&5)`foWdAQ}a!nV&M8muAlDXH_$l+t*SNY-HA(hFC>W&RvT zzZ40I6qGz5=FFvSuq3N#xF3GEBSt78IBOIIPWGJ2;3)2<&laVS@0eD4Kl=G}Bo@&_ z`14gBVQsVXnzrAIa#_{~ML#-sJQNClb0_4bx5NVSr7bkixi7DG%u_?7BIO%5G86@G zxBR4{=<#71fs@Ttgtu0s39ixw4qF2DaXTXz!87}=+uH5VE}8&WyO)v&$In8C3=uv+}#Lo;!RCR3UAvhJ81pmoZ_C^ zD?qtRODxfNNyQI-qVqSdjD5+7E%?N`>uAU?G6x&;s1153%yyI3)zN2D@Ghoet;dl2 zt-dwy)qwHkA|sjQin1Ovt}=A>K%j&^5|t(DZ5|O$n(DTW#P4k-=v0zyy!-_7M0eJ% z|1Pz2)IXU!!AaQ1lP}Q2G>hxR;IdL;AKC?j9k5`sAp!o{_IYM`?>JrYw z92U~Q;7)fKjsZ*kwBge?KYPywsMiG#4}>HPwlqMkJri)Pm@6u9Bu)>T~pjmGvIBUQ_h0AyL} zw!iz1*7J|U5Epopimw%4Zd_pCbQw|?NnMrs^qmkNJe@A7Hwh@^gcTh4hR!sLs?tn63M=NpvR+QmM_+7f(6 zQgoGqg&ywgyzgadCoI{JLlxCs@GpmAT3UD`=A@Nu)&^W$STL}NyLhIBO2S+V`#6x- z$_0cr`x6z|`lN9BUI@`3zmYJX1WgdJLT~4f4(Y*zwO(zVu8V$-Y%%c4Onv3ZUR6%=m zdDc*7Bold_>=D74off!0Wd zs9o)4N`p|Ily#bs_lwNFFrVW~0(7Rl061Gnx^GXx0;_;-#@_=dC+JwK!B)D@9>d%m zZc}k3;;V((Jn|<};(ErQ`I+Ffv08rdfDVO{qk%!&x>8Ng%W)P0vD9KukYQ-(>swt2 zuM;g1p^xQ>8=4Iqxk?OqxJiqCgiw`8(B+mdr9Lz65r$;C>JLifipj|)M0mW@R%Rnd zkbJn~X?`oi(nz+UWVta0(?57LhY;QNb4QLQIR~c-`84Ws71b~A1WH&)o@xmF;_mWq z1Z0zn3{U^j)>i3(gEidbVZWlYU#jO+Mdf_(l3`5w>B*zWi_In*#e8~NIGV9y=Ly! zWXLgX)bv}iMRu%+HY08Zxe~Amif11v)*i#_+TYp8Wk0L6a6F$(u&1^eae?Ec==P{J zipS&>P{exk#X=#0KEq{qbq#!}jPdaFFLsD|YwI1G&@T6y>E#l4)j;EoJ!letXdG=sHvT zQDowL>e|ULxj8&)J@L|Ipc(w;wKo!Mh1ybc-I6rmiyz_k!IYU196BQ4 zcr#;rh8#PVvm$Kfud% zRKA&l5u)V9)3~0K_A_a10##)5fro0b!9zE+|ij;Up~0GW_+ zvYPI9oszldfU1+7Y5HuDxe;@{tVN~)F;_2-Aygw>E&Yl>G5N!7B+YHD#&||xlbKA} z$i-5KgW-3^mJ4Y`RZDX*P!qCp-|#adAPCqGHr{5C`>nR;xK?B_5|oOQw@jJGOC;l9 zf(Kz9;~AZftjQ$d8d%7KmweJy!|Q$@l!Q_FcxXHl-ASeFE6sj48kg*etK0Yr&qDo+ z%y~gRb+kRw%;lhRHe8Ks^O`JgIHtQl2*-puJ7oBUz6No!YBcgQft!m`Z?du@kAm2+7AGHdC908YdhV#}}0 zpO=MTYl#f~F-H#Jk4#_^3f>}@z=4XRDnGQG1I#itODfYfHrdjq-wr$%|IBgXG44Rs zgcgcCanYT+Bh8|1!AK~QxXs-dO4HHwLB$9+V4cQiq5&w8z+Y|Bz=eD0&CtX9<&G1| zW>(HwkgeWc4qJj9tDzn<3qi8kE%Se}yX!ckc#*`^Jl>Pc|YwgF}?XnYNRxfsq)ozc8d`HYNaut zJ|BR1v?GSM|Hr4FN=G)#945Z3D~;Gtsf0o=;>6&KBjoO8)7)Cx-bb`)0C|Ri9~ET5 zCkD7{R?`WLSY-RG*ISEUPFnIGq0=NoQejjWdfx3_Awp0wgS&RR1OyW@}m7PS4yspjm*t*Vb zu7_&HD5hNLNvhL6gnKu=ph1LDIaxFx!GZGlN{G$XM&KMbx=3S|;As)D%vuwHKcPjq{rc zNPj!CXe6%9;)uG zo#88Zgg{v%zhFAx?vC&S#A&l0QSvoMsefV*(lXdSART`=bm#T;D5d#iV|Q%pa=7wX z8(C7SbU6U_48tEo`eH2JCc=xnSNOXmpUSO>X&1>Q+hN_|(o4Q`7m1N%d8R@3XNqlj ze&P7Xc_lWyUxly%jbFkB2#H=xi!l&NJr@8ibMkVpzIA9y)XBKcEIxSt+uG;4T?1iX zQ>@G01i;2No0Lz{?b&z%>p<Sw3hgs zrT<5JE*$GIWh-=wMYRzA`~`L*y9@TQGk<|P%a)W&O$+h_UG-TL_0HooV%;Lrd*&+V zeh}n4+whqbXyDL45}AK%mgA@zAXKJXfn^k)f77ufRHjVp1__7TzD3uRN`{XJshF?d zqrG?+4g)7v*V+B4BUa;q(Zy-WXz!X5omDf3VO0D=d$yVa9A_*l3q&8o>&{~luT}o8 z!VIr|w>W)1m+F*JBR9|+!mLYY3VMr2VVv2q1VZ0a*mQcMA15Dw2hz8Gnk>rhc9et( zA}$e=#5^E%>_}7)z2aQxi=`mN=XmTan-(i2FH6ko&Qw)#$6(WZIzb3e@*7f)SJtHF@D~ut^PGPtl zc;>86I}LvXl3N)eTCJ*GjVme#5rZzqe~Ye`H%;NME&^4e{Qx^)lySz`=3JxlksHDc zp!#wD8M63(o&sCZQY`*E+U42!e)HvsF)@vmSU(?(X(hlX3|1-{GUYjP(Lg((rAqlD zi^}M?moJ^5pux)oI*A57#8;^3i1u5g$x!XwoKBc@;+TxN!hcOtX-2ffU`TlaBv{RP zXZdrk{ZBkntW%TW6~`CF+iR+ia?CmonTbGquHg{oF+?WoHYgcy1+qzk2qTEZSeW+- zGQdpR4*Fkb)6-q$%X?b?LZXf>l4ZaTe|E1FSZ5|+Cp!b=wz%WfQ<$yr`LQMl5(WOO ztL*2K0=R^vBLi8t?A$^{&t+K90M`^nNv@UQoZ<$=|3;Y5>3lXUqylERWf+C1dP2q- z@-VP-S?;op8V&emn8_Ytoptqwez&ziiVq_RyyTb)$N=%X%{?XJZmc=yCy2zAQ|6c6 z9b_E1w?&4kpX{R#_*fQJ1eU?PRC@wSB!zBTk;ul~X@b_T9(o%DKG1S^n$aAtA_L<< zJK~h(&}&GAA~GGh0lE4l1V;oenhO#Uhut-E!CXXD_lu=n{n1XvH8f;ibE;9==5(k0 z#n2D0$@oG-0RXbpPZ-)-)Jw)5v{-j6(E~Y~w(P?AA_@b5Q|`_4dry#Lu+yD|h;8TW z@ArgsH-xfQRdx;X5>JTDiG3{@ZBSJYtpDnLqEI&D!90 z(nAsJ`eKHQ>l7_dXQ&Y*+0bD819x83%5N~YI$)6wCU3)*@ObOirB3Rytv&Nd)3Ujr z=R^96Ck?wh^Jtr%PH-G2ldL1F3SmVl}-qULJFn2sTfdaboS&4{HkSzB{| zwA`0b>D1X?F1HpD>xyt0^OlFO{#H`PYTS@PD955x(%+{|Yq7UOOz;;N%-HG=gc%~_ zM!rU+d`cx(vl82qd!9v!;&dj03HbzB8pE8HDw1@HybezMni4S9Q>IKBXYUzE zgnhT962gKa7@#U%c_Szh>0O67WxQl_zM3U=tsm%r(9eCMZKoL(#QLa-06R@Cpli1- z-M&kGg1g}*St;XhPg7HBdbq!DO1?7G1V-9oR4-64QjDJN-&3B2XU- znE8q0fSJcyBBSJc!IAEWLclylhaALhYS@y;um@^<=%e>o^WU5d?Xj0{nIB$T8&+j2K@;bcvY)QR+L^e=w!A- z&O-iO$MY0x$gJE_T92klq=~Gqovcm?E9fdH72Njj40D(~HkZNYIkrp(hsp66yuTxK ztIVW-)?t5RQSfQGQ-wHZ|0ePZ9*Uwkp6L;?OH*%SqmpQGL|Z6=7(Au7@*tAn#P1Sw zTh8?rUW=ZafR1d7LmLOW+8-%GL5UH=&b+e^TIYH{Q!}<>?stH^Z5uIUAi-;--k;Hv zuEvPufZ9A$1Cf5TWtf)zTeiV*Y}n@FPI)=}es41cyuuDh5%m_n*I>$X!UV*MGzZZK=G zUTbq-98`}^t4GIww+xiD+7mx1MZNkx0PIYpv>TKJJPT3;TU~!DQV1>P^|EOa2Cc6aIxZRNXO>l^I0Y5;pW3_mBI@p+CEwIU+{qV_8@#+I5a$V^=EWhIzS2G&T(Zh+NO-@-r{uu|j496|O| zd<(a-wbw%qv90g514CN4fR^C?f*(3&8YV?}0>%TOS>wM~`0Mxi-jq=yKf^rYD}fMF zdz-9071>v@j#mUGNCYv{=pA-${l!*pOs?YPz^$&5h>IT79o&GHK_q1Wd?hUDJ;^P5 zc?@Y5en!)v0aL_h0*<$4L)?TrKzKrCUo=-ft`26AAs6U6`5FrgmQY_143zO#?Iyz( zPfcq=N)Y!vP7?v?<7| zI6OsD!H%8jpA-#G@x3(kU64VBoR5nOoYX6rRk zJseUxQZ>C;yWtDnh50Cmjhc|4Da>AQh({1eDlr6R<$tO_$`SM#G=LARhZ?E+0eD%WlI|$t4?g}_v7+)9LuH1=Jl1gBV+Bj zv1$w8v0dCIvEC>yh)tF(OsMM{3z#|^J2+Ox4iL6jCfXe&r?px4E@cf!-{+GH51<8E z6Q?Me_$J;F{=0=EQZ{ZA&%gk(98L;}ia0WUh)$B_(zc47-EfBiKR23?;fFfqSIYSz zHr(~`rw=FPrA_gAQT+((v?ym;r6y#`~<)0oCK;N9*nBD{^CAIk2uE`>^kdZBrO@jO`bjUs#O8Nx@vUCcl+svk|O2-UPbYL0b#~;L0$|h}`t41@oEdgxC7JnqK&z7uglm z{|>Z$bV(G>Jd4%Ae}SO~ISS?;GZ}$#PX-zQj%Pq9y^&@XAC8086ul{{AuCz1CaE$f z@?=uXt^u#5?V$A?D0@3LAgPkU6F+BGkKN_;TY7+X5um!c3w?96+?B{}$jhkybU8p< z8Ej1&)7~|Vz43PHL0>X*Euivt@v~>CEYHZ0W1q1mfd&^bY**{oNa(-$5;`UC{SP(L ziYR9!2;vUI?R@2)0DqHr_WOY3mQeW>%ui4F^)Dl>jBtWTiGBu_!IY~s)glAKmUU8C z;@b0u=#|A{871Z*oVqZ!dMqKzBLQ_CX_R*i^CqtbdYoF@pYUd~LKech2gag;_Ivrg zQ2{2&2b*jh7alz|=&-7BstO3dYwj>e@Yn^cY{t>fr&U325SAC-lu2HN;hy7^|z~3@({+VsVySh=oMPmBd0+|j_>XnHS2TazV%*F{S0xG{A!)ETZiB`S)6i#g%m=FHxLp8Ah&zS_y# z;R+*{$=q2LC)TCO?ZV$x0MLnEi=xbLKsS)u6LFQ*j|+StBVu-W)liH|17}ELF2gm)%9y9WONDNk1g+(8Ibmz8!<=Sy z<2=J2?20guFFCLF8T1*Hjw8&!QQKpkDK)P(&mhsb=xK6XUXQSN zZY@i3)$>bDiq>-&&MQKV4NbuN4bjz$=0UXG7(5$!B_q@3IOVlS5D@IKqQ>{3jJ!4y zaoX$r;0^2}=2>}-*zKUBkwZ!{ zEz1=R=JZLc{Y|cf3ZF{!IoZg_o?0Mn`n!$Q>h`Ok3#Q8MVkO+DUTbBVBQKx4;WQlN zvzWLyEL~V050y;GW#@>`LoAFo&-AP0^V!`a{fZ(0P3k?Cr|*=O><_LA=^;l&_qznq zSeO}DZQ%70rN@;fteP2B0390f73_KLs1^3SsevZ<2((w*)()~i<((@-t|u%CQc)Lz zdHS@Ms?x(&$;cGTfR6I;F*i&Ndeoh??Pr47t7zX&VVB@gcq5(?St%9JhQ|R!>|L^d z&uN5@Pgc!t0gOn93|le7wY3*>f1}BQd1jVMPUw$Tw?4kSP6nwMNF?jGR2o*tZfqJs zB(`5tSdBR6CF8%c%%oJ%j)8@z3u??9^ua^&*#Z}1J^pEXe!l<&U#GvE!yr3bhsp80 zXm`hwvo?r;vRp@VF>29R=|DKF?Y$dRF%hl5cwL`N7~^(PlWl8^XEeEU%SUN+Qime6 ztTUTKl_T;aE|B8c*?$+fb{Z7_MgUXviItT2VzQo1qp^c+W=0_Su!Iv#<2KR@Q=4-{ zCsf~}H%S~^C}^$s{8jchzB=s>8dzE=2eJpV(tcq#2}yBRba@p=lxhQ>qc)GCoz77i zl~*5~*vzL^#d|cS1hk)cz?=mZ^KI7UlR?_Ff1P|0M;H8u;-QaaZI37w#W~x3+S#Eg zj)n}}hey!VaFO#-b)n96b5>*L)~l9;beX}-B1T9`Ihrnh#8);M$MP!u91WC)g}L*a zdPTZYt3LUvkejNzM1=GG{M*upoDt)3~35~`%z|nU2NsU z<*g_4`9t?9E564_rKZ%ejwECE8>}ox48|5VAw|?^^+$LcikgRB|N2g@BrX^BM?P1> zf-io&+^B>(;7#rrVHn0x@3PEo8tZ7y#A3#B|0Vd4q~=c|qVeiw4Fh}nL*i3ISA0-ZWLN%H%2A4l%ueu?i zTWx$D7I}_Fc0_uq)f3&dTLamPTK(-%DW(M>1WwDGOFgc%k)K4XI+u2+jcz9f2}Ela zp)yCq!J*J2F|$lwv#V?@GUF`>&-$vL%;i&$Tcp*MG=~Mf5>s4SCsEjU4$%5b$&$WX z=ciZZiIH(+m*xlZCGf(Ua^_8D#xEQ0j#^K0Q?;9VqrqNR6UkHC&sqnJ{4U=!=Jo0h z6G-BLozlRMOsx zNt|5e4>@OfDNee%rI{DEv4h>Y;Y2-;GW~?OdW~1tpfar=Dyw+%)ia&+R9;XpgA?b-li4rqtfy)K3W6F7g6vp2H;vC1{wgvJxSWb6CiS9hp?*2u1-D z?B1|baK!{*S2n)wW3Jle+3|$h24Ro{^uX%->NErC$0F0oM_VycOe_zlCqkSO3Cf0d zrA^z-ifV6tiqbyty`Px(EMryqP7ZX{a7gt0gsAZ`OvNR98Vg%Pq7ThT1Z$F z8`8eGlhhOv*UJ=yxFY{l5hP*i5EDn%Gj)CZj<1v67LOe%ye@(-TgloEoQlJQ zW{4&9Vb>+aO_b0U>^g{mr)n@}!j&J~z!lgp20d8vx)2N3nUIwX2I>X^uFONN(LPW? zMV&ol!pz=QJZcNDX%tkiz`@qaz0*a!Na@Al`?-SB_1$j#fDp)(Y^KoV^F*W-T$F?X z%l`WsU8Bu+rf7+Dy6MY{TQlbsb}&Arepi0_LE0%av=s$J->klVDlD_hui^1kp9J0` zz1*J6@gh7s$>M}2debt&Bo~95exRcnf~5m6Jtjncd<{g~+B0TiuJ!cIe#!V1tC-;R z&5JTY{L{u0Hp$g8UL$TJBv1i})5nBLF5s9m)!34`gVhgf`Ht2Op--W&Y+aqumL3YB zy%oO%_?Rk8Nq68go<88XB$2_85-EnVLSAcX5hO`=Z3JJEnsjvjTkz(%0_oj;Mm0uU z!4^q7;7{$Rc`!{e2_#MLEhqaOHoH@cRvbRTM@NTJG*smlHk{KI_g?;6@!>{b4H?2@WvaBUnU5HoD0%2qnhMn1T{FF zYh-cvIv_At&ITLEa2lK49OmT{<&#p`K>J}u+$!p}f9Go>vdb`-(7w<;-?c429q zPmh-;H&gX<%ef19-u*J+CE&r)6V-2U;F0aL7T4h9qfL4NLAp(@aeBUVrgVeKvRjY0 ztMKJlTx36B#G!E5R|u-M6*$X+d3w?0Q&SR5OEhse*vLB364d-rN_QJL75q8_Qt}8E zw2n!|*|H1g@N4xQ{SL>HulH6aj{Ji%P1(`0KJW8m0>H}fHT(shW^yK0qh+$~YjYtz z+Zz97@0+e;gGl^hQMN5~8x4>^uVwt%N&l$0;kCB}yjbF@8kgIDyWO5G+?r?&w)5CD zYvJs(OABtiMV1!QS`CI&QjK$5nX2DR=Y4&;F)qg zDIw^VeCf8y1IxrsVwP4@&UFduM!3Z0e_Jk@YMWN{{|JiDY6R+3e%dE z*|>fgXhLTt-aWA3(9~QlE}OItn-$fiz9{)#CaJAC`pvSJGjBVO;g5}1c{`_}h}O?G zd{zd+0^22cJf8`)ZROtF6%;A;PiZV~v5-ZS!*5hAU!Lp!8`ZF{BkI)TnqA~m!pYAk89B{zyJP6;H_%NS_&G7YI4Iq&CHv>f>)|COnGAoTR}idkM|JqxF^xeS$&`pG^yiWK&Wxpj48HNLf`i_Yg0S zXQ$v3s5Zfc>dql~B=wyey4o^$db$M(6X6?9ezmyih5$c6z`tQ(9O+RwqzNOxE$^6Q z`3JWI5h3KXotW91R8Qmc5(+lpP^xf$k5C7+0e|VG zI_t_0r)L;*IY~pwXdG3M`=3}A__`Ug`Z&d#Lw$r0OE7ezu+Y{B? zzM$`;7S8V~!klX)F-K?o2Jem!PG!;j5WJ#ab7~<@0Y)s;BG-clmi}BPOTl*XtrV{Y z*OU4R7>oid%t;g}^P&b$=%Qt@;m0U?%5B`?`3cJANk#1VQsVb{*&7y(M9#_LAZBtz z3jRpSK|RXqBI|_S0#2*M*;&hinL?v#a7)TDrZ??w_iaAGmlc*6Y5qUb23+lahZDRU3oZ9MkC~^RydNrQ$BbX)zAk% zy78ZO1rLn#$K_p$luPWh3C$HZVMB6Ytxh1SZ{fUHwTX6vq(;z zpMTy%oYFTAbse~ed&CYBkK!2hT7+0P>JMon>S_I_XbG4gDA!1kAjiE6D_?k6q zJECW@Hd3KPG!W;w2!r)?^nj3U7^Os-fJ$SSN5zSI7NC|y* z$MS`O;iSa%;V^}MXcG38oba#BMmYqn1Wq_{BlogKapV2H*Pw;B^frPCk*O`Ds7YfG zr7bAmPT03k;=15L7?gtvhIFO(B#}40sHd?B`c#SwwDbIJ-6xo6{_13bT4%L(5u|IK zmlcQT_5&i>nqv=NoY}HBbm>>1=83`5LaI^V;_Ra6 zmoq-8ROHTiMK&EmIk=juqe1bx5@BClECfGC*o2tAUHc)pjOSYGgI z<(6avClaRl;YHpLq-6Hv7>T)vs&PA;=oJHC3-~i_HuKLkSry{EXfSmyI>5`Jc!l-tiY527PSTg8PU5RUKbPhds77v^U zuKJV8a0YZF><0Qp77f1!QTyY^uDGz0>nWHOJ z;S*!Y3c`Pn+DFq-Q$<(Ce6zlqfK{(H&F<%lxBIv?fz@1RHs&`b_{N15t!+}v z*tUiKENW`FT9*lxXyVw#Gs*l47-3~JyZFI(z@i0p$><4DQXfFtv#y8Gn=yqe{%HhHVji<4hbH>2XoTg zZbB%}R_b#q*q~kV)O6iYM|s%82;D!es^=U(y{u}gv?2EPVS(4P* zRTFEaQt@311i8Q>5*gVMe+-}7X|HD4at<*{W$2gy2?F4LHO_dOaYEh+) z8|cB7y3Lkjr8;N>YKF4PLQW@y^HgE2|0NmmG`?jRZWOX*d7z?fdU(JIJvuwv;*LD3 zPMqyUrgb_BB1{eGbck5A%!;nqDJTbF&RxT<;YiVi9V2}qVc;H$SREwj1of-s- zKGuk9HmsO7Nd0!P4xTm9XA@dfoPhz%bI}>1MA}k$YCE>BR2_X%kr{Hn%ixo2}frExYt55eRj41 z>+-ElH6}JybFlug6mJz19=T$>R_d~t$|QvzI=D-Dxw^PXxUFI!F;brvhP8TFS%6su zjOsWC-FWR!K9FrlqStoWdLQtO;|8_;2i{hzuWw13_`3f7e^U6|!OpCjFYUV%)3C!WT^lZ!>9V!!e(TL+b^48FO0;N-9S`k*`+w@%ibwHKYk{90Wen}j zks0n*`9At=ZH%@u9vtILyfTLs_h&ujUN2ICRJu654QPkYW!S60z4b!9;~K1j`IN*t zE*P$}QQO3%@m}Co9WhgPcYP?Pr#_dAmcG)$ijLt>+%sr+b6fe6TgM+OBnAj3iXnW& zmE+C5nyyP+sik*1E1_5xyAO}h_j#;#lmB?@HlVtFvC``}Z(1?5N$S8gI^h*_91anu zbf$=eY^7T7bYzLBr^T`@hKk^QRA=|%Em@9Vnb*P3?W(9i)H=U#Klu^(7jvCLk zM~6z7Q!Zj>pg>XxQ2-1qk^Lw@E0WL6mv_XwOA;aVXUtTE5VV(fK6=Uy2lWexUsyvY z-e5gg(ESiAR9RaKd#B^Q7H)MgW|G_^vBc-jyk@$hq#Sn8J(Y3SeQ(e?N-RK5FRh5H z8H{TRVN@S{MOtfp_NXy}8)!km-2|ee5`70g4aFQ6Pz;ahGl33;YEM*t0ITq8cXQwn zHn15sDeY+VY|%)(v9 zNgQ043qn(fSm5e(vB~WRl0nytX{-{lkGq3Gn|2;xC%_dYm^c~>&(cgtrsZDK+H%<0 zq0q+4xl(5%rx#1~d@)fm_s1sQjmZfLN(-)@{LJ{9J%)a?s?U1cx;W@L(T<{UrA4Jy zeF=9cZe*ULzCU$#ZNDo9^}b#EsRzyS5Cuc ze~$U*$ofVL&xYP;9loeQ;^pCyDwTdrkN0+(BT^Pui~@aU$R+X{N(U^RIH8o=@gw5M z5^NF7eF~Q|pWQEw(oXnT%!%xcW_#J!cXQ{b^oLxk22QOiike@tE`ObO z)tw#Y^-=O~fZ*UALYP}hw3|u^GgezJkjza2b@7H$wHMIPWTwTUohh+1?A#VJ+Uy=& zBV!r?c~~&=pOSt=pl7okly3sBFf6xUSe9%J0K;N^K|g3oA2)kMT{BYvAfxg1tbV zBvOBiFLLpgR&xa!;Xb)*IunNhxm`n)b9yO%fQ%)f6uwW4!|-tel)nY00*c=fgVOy) z3&=7CU9~Fg^R?0(QYb#IIK>GmAo!AWbbDIOq}-rgOHEO@MEL~KFaKEkAByq`8_p$Y z)#4o-8L>hK7rfotXRDl3JmD;f7|KpJtw`(7nx;QO%|G8GY4GRHgr1>Vv1VqSg;qMn zAbAM!Kzv~x6n%Z{KyszO>FviE6<$=_=2gP}& z6 zMMLg1=3BHroEG)U|K$ZXotV{ShU@5xt?(|j5e7cc9`r_d2UW`Zykb1BTA8{%00cSn z;v%4lm3bE8gSF#P=18M@fCVh%#L@MD9X?R;e@pP}s(^n~&tA|99P0TbK7Fz>jut1} zMYI%M-+&;%WpL$YR4Q0EwfZDp<9l6O`B`a#Z&+uXY)A7AwnmqR&?Fo_Ar?;u?+GLwX3 z$Uj(asIImyXV$95vzCh9&C09HMhS6EPu(D*G4c9CZ6B!asDwfMWANfiHJ0AHSCn%fQ9qo~qW!Mf zzw&Jz=vV56llGFN!xHs=SZz?ICAoj80-H2)H&wFvNky!=-I(xC{N`EzZaQHFFz3QK z|64N`^Zx@gm$I~)sD{%2Z01rlF?0Fv&0GwO1hkAyYy_+<^aSh-|BIQ6<$pDEvHj0x zE@rm>jhT!2e-?B74}aJHCFT+U2m*uv!T=F~C_oG#4v+vy0;B;l09k+>Kpvn7Py#3e zQ~;^~HGn!m1E2{o02tWVn>afCkL*zcCub8!3nwdpA;8eU5n$+OU}W;2v8Df6IsT8~ z{;5SX-Oe*!@@6|M%X1_5HuO#r{WV>VFBwENo5wTg#Y%qlxW*Hu}%% zznc8V9sZAJ`hP0O99-<2O^gk#|Ik!C%j{4D3fC)ZbQ_VaVgZ|hWh^;LWKSX=DEKZHdaLCg^}E+Jf*T@k4ODj#ac zmN}9o)Ev4EWZMD=MS0L(N@5+cTz9Y6oXmh9oIx2R!aTfy(E}R+OFxtlbOI76VouoH zypk}(DtJOKfTWR3Ux3U#2?Q7>9y+lbQkcv{d|;tVfM_}M**?TpnstsJPJH$5*V*c53<|+QyZ}VIpN9=r8 zm+uS0=Q4ZWRW?XE2%qQcK>ROS>^+(L{O@Q0ALweM{{eT|^Ippqe8pOUB>j7bAB*_1nBoGyP(T9&RKKzsTSb-=t zm>6*z*otb=?=Rzx-5x|tNy7Nl{Z|*k$$IaLJ4h2hA}mnDR?s)e)qXfr36jg@uqV;a z9RekA+kDV{ieDkL&Fqb@bLo&2F&L|FJJjL(z-2(4XV%-rpLMx&nooS55WNOJ9?yWn# zX_q1OLMVsBq6Az8bF!hC6|egOG-cwFdMimEY4xXwF>3Zag_qG<3B5xl^L<-Suo4v0 z$%ALtYjd6|S&o6^;5SaqM+u6ei}WLgcmMFyxzSU&FtM9lQpzCq1nwl z>gB8P2FbM|yeDL}91(cMEXU%rvpGb&tB#&M1}P|nF-d7>Rv5U)ORMO=x?$nX2U7RQ zX$_+yIvsP->Fpx5G^gdaF^3zniN5#zC#qApvQTsLMyGEGB4AW4&$lso&iqYc@ffW_@UF{Aa=VR2qjArY(u1(SdX4Q~U6w>9 zeLL%@sjfce*NvS#`F~OJPqCs!(Sj|yZ0u#*wr$(CZQHhO+qP}nw)M`bsuXfhz1*A3 zpYhkf#vHvRt@))=aieRUG~GL1^Y~d8_2if?9|XN@#vS=Thef&A=*Vusd$MhDJ_3(CYsm|c1$Hz_lQV_8GJL$UQ;g4yqeyb@=@IW9vYAi zvG2qhQg|;Vq$aH!U2Jih6l7QeGPEz>)lYNI^vuG}Yxq{COlmg*M3Tbx?fA21B%o+~RNzRou zzy#n7BEhZ>HSC6sMb97B!C0YS*E{p%@v!F1XC(rdC0NW7`8~thn#kR0 zQsZ{kQIdFGSn9HQ*${*=I^OQ?^gkF(M1C2@jes#U7!fQ20ml-)g^%lOmf>z?DBswh zdA(7}2vWFZ|y8C^o%OtE#J;_V{V9jG8_!t1mB z#~RLy%%{i1O8v9*?4b&#l+1Q!yQh&P!7Y?8y~3_isU-%~bl-7EcZB)v^BzpU(H#_nwp&|v1}r)Eh>`++($(Ptckjn& zm@{yI7o)4e^?F(nJ`GaFwKJVM~S#$zFC#*JdDzhtvPoZYtNi=qaX&{J#fBWbsG z=G06sGMK2G#+p#eglSMt9pN0DF<{~y6_%5Zg#%@P__nk|W z!9<6n&W%%y&8EiA|E117Z`MQY(52qpckXr6lNH#aqm2<0mDuyct82sc+!t9(x3ZcT zP07O;MQ@2%@pOt>KC0CjVk*1SHgJwm+kl%sXC@lqNW|v z*~F^KC~`ShrrdMSN(luyD^jd>Q8<+SgsE+~Nb5!^6SMZIx1q*M*+_XmIeWNd!r;>E z=(B9)_{_TLkhg_19&3~P89q8(WdZ7r_9ca=N@B)Zs8Mo8rV4S0Tv0X@s8z%&netp7 zEM=!;-$ZL!u$8Kta)NJnJuZENa9I$5&i(Cq3)vP}oxFp)itXN4_XYM(QNuBA*Dv4f zv3!$8hPq2vZhBCI!4%%+%lgx2oPxRYqoiX%p@v&!ts`41zD(DO<{mR^zZ+TS4q73M zH>0}&7umPq=#;ZlHrRtY!?zr|VtAP9`T6k3r))y-m-Skf7%hw}=UH$GoW}YNf-czO zL~mS*4Q3WAMD<2uOP#Zzxy#;~M6#t*NUN%f(r>gMAG~_$sVhx2(>I{3Lnz-w!8dp? zzQMoSo9S=MoX@zP7^9T*~>qVBU&I z-SG0pinO;hF`!#%_M;<i@*>z)i(?I^P{94OmRjKJpZ?$3 z=ULHLinq0fl7s?h98wJ1BoOKq4u9#V;nnNxDY(#n1mMBM;FeZJJItEl7h3A!ww?V- z{nXpb?D>t~7EyK&fLS#RTSjww1uk5r$+PO*3M8N3>#wDg@b=+k8gi}ML|`bOmP>zf z&4^fn_5@4f>G1CF&TF@%iCsXKgbWSMY_6*mv;_@xWVY=?6w$}k1g%!cVuhZ*H&`8b zq(?M&Zsct%!KaACOyO!f6Qk!hA%^R6UCYxifvcS!phWf_JcOL6kYi)eM;oDzd_qYG zmXYZ1THf2(4iE2zxAK1QA4&=p#o6b!-kTf*XXU#A=wjp`N8$Q=o?>ek3Z^)(OiUh* zj*bD0js}UcaPuRU?G|k_HRna<$A$1nj08MMydJrOn$1gpFZACq3 zemN2~>J6O{h?{j_%0Vuc%6Hx|OA>`_GYgzP)|d)kdA-KV)>7!9Vwd5ltw~~bGA&rP zb@tUSKKmFYU!TYx@fH3t*9E#u47OUDA7Q(|bmeW$FKlJ{3ELK6;L zQ4~1ETfs{4ZRxczY+ze%s;5b0H;Ne+US+LYcmAyI3YbbG#&$Hu$(inV9eLy%m6Ch*h|xX*Ht4s)1SDUd!m zWhQY!8|994;xr>Eo(+kf(w{aj5qjU|BW>gg1gYQGkrQ0fI?r48hhiGq@#Mk~p6eO6 zExKXIi%MQE&RzQQwm$L)wjE^|>ai$vL`3YSA-dI$heJ1ZBNh5*tYYc)tL1%mRs8Nx zJBG;k4_%(%KAYZ6at9^)#g@EBq2}LdXJ_k)Giar!jZ z_2L$p7jiILdyiCWgWU}on21`ID++TJdAU4@>JNq zMPgYHcY?Q9PAX ziw7d5ZaE3PqvG5~biEq_=X~?aG38v8ARyLzEEZeRoTiT7C*CI%8uxz%!C3!4KrmSi zDFr2!{{g|24F3N^Fg9j<8b)>&d?t9493X7^nbx% z>@5EagRw9&{hxjM|G}UBGf!{--#L$k`+w&-|0l0u`G4>lw*N9T|DTxce}?9n*jbqV z%g{VCD+kN}OJGyuYUFHsm1;X3c|%tbX|vTzh2q;_!&R}~YSU%7RlZ)S&gPYO%gZx+ z^Hp~D(J-ohcg%FgwAX=3(GbX3lb;X+C_g>AnUI(4n4fe*wCLeBt*&cVTPAPzXl+G_i1N?IBV0Hs3W zB57%v=_mQi2#DVPQ+B$vG%!7k$^ZIs2-Do$&;q2%-@iVM2=Omf zZ9X{}30yvWssd;@V3ps?N6J4iDWD{SfPZxQpZN_yF$ntBIxzL00|5G_I#$MyN+$4* z8MOeoKX3m4s=4{=1(-7n$mVZJA>caDP0chmHt!ywDI5Tjmygxh94`ANz;rb%O-}SL z&^-lP>jzeRP0vhO$V%BQQ+i-bP*G4pPeu*VK2ud-_&T3GXXYi>Z_3udwGwPS!*4Tl zBZKp2RdJt7o&j%5?5F7}9DrDU)sbEYj6VPo6S$U?Putvf-hlPZ%x~zyvA(IzqZ|k` zfLDG*Z%+cr{J;UzwApoE=hGY~;9rfWkCv8HTVIdOZ|f%=jA<+!zmyRtyJ+cLc4%x~ zhs<>K!TDb%iiDLB768!@-?6A{>tBTv*yi63eq^6%=p#~aZ$eB<306OZIgA*c+0lCj zBL735QO50_*kfP7p&#_XAFAiy-}sMO?C%!I?_bZ{AExH?#G<0?-lY@3Z-Ws)o|Nbw z=6#150Hc2&YE06~-$|jJiRs1bpW~;RmCHWgJk*9d=1-OEqQYMjN#H7JUNikX!?%$6 zDZc3`6tg0|6Eia?`jwXN>y=$cWedXm?&37&`^42A4d^^0BmH-j?8x%;{NN`YkosQ% zkS5j-)wf*bFPL0iJ_QjSq2Lc6^;#b+3U64y!pO`k(w1K`p_S3IURd8C1ms3L5VtwT z20K9WG<9^I+a1zBGOVDrzxc;H{^&pMsY|ZStPY@NzAIDx@2<~3_g|02k2Lzi)lgPZ zznGZDqTZH;v*Mq$eY%!{q@EwL0YAOpxyrw%@3(2-fLeZ`_7o8;pZ!&rWC9Ysp=Md}tnkZxt%7|`O8 z`}A?1eH8k2wTV2lO4mk>p7YxR2-HmQagapudA5_`p<`fvulT@jbcKoKpukE^*2JCU zxC>_QpO>2bmF?c+JZ@y{pbEPTPpC>+ilo!7mN(GIthPG_O_JsG=5;Ct*_st}UjD91 zvMS8zktvQ}_KFKHRD7DZs&2y-dg$v102K3*#-YKbl6BM{tB$QU2Qc%64Dmy!Ras z;XFj%l$x<&9p4y0Fb>YaQJ-_RgKBbbc!P-lF)OEkau&FJ4mg_yS7a|8SWQbu8jdPL zPg6p=r%TZPv4{OMAS4-b{4f*|9jtQ8BlY7L@w(BO5(iHGB-LumD5~9kRp(e9;w(S; z*!5%Lh~YLHNtX^ubUmQ0^IqLL^rm=R6{Xd9{mXHyDd%g5$;Dt;(Hgxzyze#II(a4p z?R&pkjH@G(t_XDAi|Goxut}m4tyzrxUEZT$)wR>6U!XkVjc!fY=&nas^*o#bMXb9N zz*r{glJBywJbN~fF>3B095JPN1HTxPzeFI;Nu%!?&NzB_R9ac*t3LEaGQU7o)Ggt2 z9dD$0y&&vGI(1$$=>=B^eb@<=0c&a49lu{oCWl@$^ zn0i?mE{?zqDqU;tWdQ>^{)cEEkbbiNl~rLEB&NFix@{jl`_F5{?UeExcnf@FP(ZWd zSAoeEe&oW(BO-?Qdj*Sts8D&lyoR+=)D^i@#{eKyo~sT02l3eqe3p`Q)aO2Z%TCvZ z?MWGRb{YnUQKSo7cM{Bbj{~;pD%Y!f`yC7R>Cx4gk8$3<$?0mQPH~a#-=v7ZNAiH~ zztd~pP7(4rt}KNR2hYQ9ExoC~<3=}TF0{e$nQ1uEDEpLofz}db@Fo9_g;Hl5*Tg2g zKFAFj^8I^D3HU@$8bqVeQG~Sk96-uoxoox^w#FU@stnwc3qR#2;~rH*>m2K>wD6&L z1Bx9>>zdiA&uLu|T}Q)e$hEQk@EqhC!~Gd(PE{FhnpbY)nEBnwxU`AVz~e4iP$-CG zwcSk*KaWcV$!xvPoqe$*w$TW3#!q3M`%efb#B1_))00Eu-GzhT1I);mLr=Bz1A|j_ z)YhUf-1yb(M6iyM&7V~AS%_4hk-J+kn7c5m8r=vhVn@xEV7R^;=D5Q!YEOk*n2 zKPu4Wh3SK+-}APqqRVsimPil{w5JS5&8kzr|(=Ojz%WrVGTZUhI(Z=7L1 zSvLU}aP*2)@|>YXDzf4|Y;uh)Zgv?4(lMu>VNq%QGF;eLR@|Y`{VxAvxZ4RH~S>WMY+#a1j1$71%0*y=rLRXk#Qf|6`cmd^qdS8g6r?70NUoN zK;P*PpB)6R82kgv8F1`4@$(0LSpOb6opohWJ3Q(sZ$h(^jRkWsS253>&G0tX(myzo z+|HlOvvT%EmZ)$P>M@1ENU80>;0zKFzCWgnp=rkRlMpZp75hz`>!aHQH#mYk^9j(dA@+W*J zQNGmpF?DV2YQdjO2Ut?pl769SotGN9&7ksLBHI_%51_7l|Dw|Sx2QajK!|LX{o5;S zsS-}SI&+9YNyzs46HRu_Eg=b|*ZZ0h3ac~q^CYS1la@qYx%X+>RlSAQTmoH~y1Gsp zTN-$bcz*NQ0SnNk8QO|DVt@>Bt)5)6 z$}!(i=hGQptSKujOn0FcQ}$`->h1s)D~ZQ;Wpm27Z_|S@RBCn2h+V(XcGomW?y$bG z5rq}~F~<2JIoqrNsXxV2Exl2#$l~bIEC=V(U6S@v9766yW3u4Ep>3kDw@2lM^>zaY za1@;giV=hOuxpRtc*r0cI$3wKV(QJsf_g4i8E@t%f0N5nlQy`)o`NG7-78at*>Iub zBY;ucE>%b(X7EtSVo>*GKIDr!SP1!FMxZ4RW0?2O;tw-HBz0UT1XbzWRSkroNfZM| zc~CU58f}kR(}w*-N0oR^^b~J)o?d0;4x|mHYkeNDO;z_XZS0Ub%l7FyUzIDPBWe4_`Hxj2$r<*MJ=v!YW~ALXh=PXqXL zu!m#}Vl|E77>JbSDQn)RDETpk4oP_EkZN@D^_L{&0s!F8)M-^|oE$7O%ho0qsi)N` zOKmTJD*~F1Y_zn_V7$aHs9&1`Ql%XW68Fc4)D%)OXXPJFKi7r z>63-q3EeS4nK&d0jV$OI$iTyE^0$aDdXIEGg62U7#+zsH-kubFA3rmP5M9LBiWmh5 zt~f{x2V>ndNWE9Mml8lgVCKxSwN35Mgo;<{d%`JMCTqq4iAhIJO!K&X6W&A0tPyN)h zmNxRSu*)`reXC-X@JVT{u>uuiAnx3lqX%-?=cTXY!`C;ZTZ!T%-HvBNGr3Q$Sw1D=5;6>$;?t5Uj_yF{WMDl>sl0lt(} z1^CpaWk>=qpC$;qunLiNj_1)mt&tBL#Qa+=d%SzdrOGtWQt2eUruFHoozDTLs6-iU z{uLK7k0~CbY*Y~iZXTqJ>TYap{?u2TE?0~za$1dA$oscx4~JSB{5`~$1_xyW2}c&^ z+xesXq4%ux(5Ve>e{hZ)a&NE4=Z@iy=Nui3qoR*qW@y?53Q*x^fkt~`I2qfwI3P^t zAE5k@*XEDjnk0Z=GNHyUf4h2TC>$$Dn7H9?QiQD2R_X3}Gcqb(M~<*El|5QKVI=xW zhLSpFj54M8qra$9elCE{X1^SL0rR#l?_~SgK7+=RyOmm4d(fr55gP^wy*A$@3aVv1 z6jJPNuH~S2)FhyZPxlNo?PkzKHD5V(CRVbwo87D;oUNcGr(TWq|7dnN z`r@?}u1jSDG=FG~W6KSx&eK4!iplT2VGVS*JuWrac@3BO4%Ndum9=`N%xGMU`Wi zvXUXT{LgM*1h=-1kqU{&U9Z|v1)**ahlBiY?<&otqNe-UYI0#JI#&_+$!v4K4=Y41 z;!&7KnO<(nm0?k>Ps(sEZpfG&ulJ?o1VGq zS}M%-JqLha84HnoT%*z$P6=uEqRezoe0lxmbTX!4jyYKAude_T%O;*6S+d2Lu(Z@K z-t+(o8^w+X7@3x0?srj&xpxw0ET5h^7FlHGlwNa}G^EP`sMp=UMLo0m+vvlaIX4^K z&DWf+2-_XwHVgh)ZeDVixC=~xqb>YPYk_6?j+>8StU9$(bRSXIa0H*C{$ar@b|BZ} zC|%X~_MB5zxI5+lq8UI>{0c4E+#APkW|0P=M8+&!8q)_k^PS?YkQP=9?E{^Rc7N z>b>WJ#A>ewN$g^Zz^1u5&afUG7b$y1L*PKi&SVgXq6xBNK>wSt{u3F8@}7XbU~AVsw8&R*GD2l zNLi|;)U2t_YYi*9$#4V zBS032h=C$HI(naEc<6NE3O%=UPgliOo8x?4;%y?4%6`Aq|Dad5S0+4{rVTHYSVL8X zEqxZ{j|zm7dswqy$RJLHQXg;BBvi!;!qqYB%9FJ!)a2All{o|$$PJ>YhHbD=`sbqW zpbo+R!H$cm9JDZV(7gCPGA?T3IPOin-l8y@37sJVaEn~)Ny(MeyzQW?WUY_O%BANL zhKv^of+*-S*aSo;g>%6>vyEeyU%<39AJMlh`Z=fA19xs~3kAkjMU1=5@zd|GUh?J5 zbnn#Al$*HybYes7Jf7NGUjaBTgxi znmfk_dNK>}yGVtE@0kJYZf+~9&(UZ8gL81I?$8Ki5US?&=p`ajE3M%^)l2$|j?YY+ zYKX0w04cm)&cjD<*x!P)oJRAxsN%r>fx80R(Iwl6L;i@1I*@pGs}`dDFNBRz+KgOhim&;e>MT}6yFl6R_u+EaN8oM=y+o$5jx7N$Wf)f+Zy}ddu@jq5`a6opky3X7o@r z9(ET5S_H?iQ$cY=Nl-W}_E;_f4o97~LCq7{|X zF1@)hJRtI*Wi_x3S^vHFWz!1Y)RcF!epA|P?dGH*j*#baDPciL@s%vr+fs+!j_B{) z5;b}}V)+RN!&(!Bl)gpliW}WZ>}~J>ux)etz#jY?{nMEY2lHhx znJTHMPdff#kdo%gffC{PL-Z5mqr`$cm(DIyN()z)PTMqW7B8WTxVczcXd}0TLU@B+ z3M}6DxI7}N8@!V6ttQ3VLc!T&`-xarc_8q>AjVAF4HTrI`PcV!=E#ePGjD2Ja7s0F zS%EqL0`|x#*dj8sZQaZ7Ub#8fnT>-K^4?=Y?Kko<<7x|k+J0kS@8s8EL%AL(WtgA= z=im5hD#+BHNRw0>Eq_Cx`s8n;<>>7zN}vubBN`YZt{viYIbr0oM0jv+6vn}A08Z5sZN}6Ekfbx{Z%J?EgIN(d z)S~Sd`a;Nbsy7K6@w64okrN-J7+wljKsNb>E*6nFPj<2;)++YQ0{vVoW-gpubRj%+ z?QNnm6M#zr3N{}0jjpC$LBRK=AKZ_2sXhiq0msDegJWl{j?MfKL82YdJrARhe&+?3 z%RGTf+gK$pSOs9Brt)z&2lr9qGE%4 ztC+S zsQ^Miy}!5g(sMw!tOMuv88t?zU2E7pCIA)dD zFd8o#X~YC)sSN1#L95$~=uxeCnG^|*BWW^~_8OeA9Y_C=QTN-zd*v=!8GJ4I}M)KLSUg)A7 zF&!Lsx{tuYp@@^SEOniFAhL(NBH@w3;g|-j!KG2HEvjS8#QzDTTE|o>$nbesTQkJ9 z+X+6W`zA$~oD8mOV3O#A4}stYrtRFlRcAn{dcrB_KpKi;DdASLacX8XpaC%k8NW6D zgthk&J(5rt=(I_IvPw&@HOqEU^w1TM0X3-1iEo7Grlt>AjBe!=La>>cv0AAqjfJZg z+S#mzu&KuD3$28(&(*h6_Lfj-9@#^zNn4!6pPm^Z1z`istQ@wKV zW&m>1YNTK|py*Bsb7!*UvS9;00LO~j2`AgnjLAs9pm60oi8_9svd3{S+Fv@6>W5>( zq!fnji~|_YfRF?gQq0n+j8B&9{8*UP6PEq9pr}K@i;CBAV)L*8Vs0k}3jG=s;aoq; zogRwuP-tLR=s-EHRT$$W#_bss?c0aEu%2&T;m=;DIC96RVp7sYjCG@;t%lfdMvdv| zj-Uau3x*{T`r@^bc`B%lnxi}tOEt8!o@ssM)ngrcFmsl>V&T7dzg%;EsP>rPPCq6r z={1KDH4p9^P@K(!bs(X5S4X)~Tz^ne=vCo4wO&pXCzFG?AQq^gWEsRAEl?qyVP%J- zbQC{!n(E{b8-Qz>MA*bRFTSrcXTACCDml5O)U5^mIeJozEJ+cG&Tf0wv%iK;194q9 zu#*Gr1pY-M{;cILsg{%tj$2mDk@EP%i>KVFiNI}yK#EQ49cSrs{eCHp2gm8XE#k~%l6*yyiQgM!DkIn` zaqK^CupVN45#baI$Wgq8Fgmw;2Of?WzFjR-Fq2`)s{SHXU)Wzqpk`jK^5|+ZDVr{$ zGLaB#hDz>pWJ?TsvDrA{Agz&PsQCG_HsW@FZ)XyjYIVpzvgMmja)(5n=_FU2Bp!A- z%YY2hcL^8DAdl6o7Lb$s2$tL+$OCLmxHib~Sf^@LFUWK?z*lu!VfVc>&>&6Swo*~E zt}Y26(luLi*EoDPo`rkKH0Y&=PsKqzA8-$OeJ2R}l~RCR08qwA5*^PtY84&xy3 zNrZis6n|JiBsF>oiwvoSb~YB)_)2f6?Kah9a*T_nguiDN>3pAs%I%D;+>2#mF%xe( zA^`Gg2C}>78Fq|zz|+iJ!|wG(Duu9G{KQB8wV!5`))GK(8m(g!ZObks+*T$A;-!74 ze~EYAej<_ja47SZ2D34~wO*F5{^4LpbuRSpU2uXq5Wv3-qtYs-PZMfLlZQGI z_~;a)1ct=?J+Vi&VzxG|14b*FySmuIY>bmoh3q=ZY@1hK|Dtk6t|Wasw>-IgFADGj zN>BA&b)~?;nVUM;uO+=)<4YatGtb+~+Q1iro7SuVEV+t;w7iboo15-apQ=EE+4R~( z+3R%zJqzl4X#?_ypJ>$rB=DAFn_*ApG^2IdkOX}wAcB}X;@ZK(#I&T|J5=XRnN0#r z1!zsEV{hc@qB;BvP&L-i3A8DeX2C6jQT_YAbMMK6PR!fmAme_bj?dsPXMz zN>=%%F_UaoD2&71Rdl791j>Kv)|AN}|%Sp0yt+@meD)vSY zq^Z|Tzyn^Emy-1u4W9Oi<3&{hTtxMiX8 zh94JtjogLT#X0X`?UN4EQUFk5NUgJsoEsDwro zrgRaI?$|S@x|F(FcrM4>-= zJ2;6nPt4lN?{G|##!!N@Hm^K}=k{jOu7&#Y#%hOV3B%iIiJ&#i^|;$jzc^sv`a$hs z?nW$>qe7D;ZT=r)^m`1nKxVHkc)3CoxL~`YHHDaR!*JJy5$_d2s{d@ZsVb={z4Tgb zUkK^A^9|X_D$OP`(ci$J$?}&Kf-0DVzT2Bh^X_7rc$XCqZ;hA{*m=&k>MRV`C9G*g z#TUQdY+T=MYIbHU8Up-qjYaQ85PaSmJ>pm5hN2RQDi8|R(}8$bVcaa-fk)? z`39dtJo`7D$cgcBVicj_Js-3|r!p8+n`vBxw`~LNGf|*QfwYNt^@x-G$eAfqvMSA> z1Ehze&$J|1r$V@V6qp&Hy?$uet6R`NiOV_4eKzpkh){-LGlagT{38aQ3I;2>3%0M!SQBk9vF_eU{j*ox9 zudng`j~B6`@RK=%mnt5ofkeqdm}DaeTU%J^y|Al4!V9E=(@=!s^2%L@&s&iU{n^Ts zAHok>t71vui84@l!9O3;p zbS~^VcUmPARwLWLPtO1k8x#%Zksa`{vm1MWc=i`F=c@iryO2nIO9N9w`ezK)5>y87G z0vW4b4}<3TyD?Nt-Hl>zis>D{#||^b`|Xj+JG}U<{D{|vkd#OFA|yM+*z?!9Yz#?9 zC}-eA{9aiG_?#|>g%m-MAVaH|H=AM08;77S9A6N5rh&t@&?{2inAb|73?0+p<~f?t zJp(#o{gd|AXrib|DpePqp(|q@7h@xZ*@FSA833@pq&yGe2he^@W6yI~mJ&iAC)$7+ z$$qTS?SJAGG2w}y^;Q(w7!+pu+>-8apaNY%dD~4L-kIoOi~M}wvcc{I2Y;E`vH(P> zfO-SgV4!W$ypx&Akc=z^jTdv%W2v@P(IRTUEMv69Og>JPLB$o4C`!A54%WTD?pgOA zEBlnub2`qygM>(8{W9Q?MoLr%GmBX%H`{>{J5GIbYJ3?&sMJNB46=aN1L1HNv2N{N(*UHPLH~9zSa>_g8&rYu;%jW z$w7yaWagCm$JldNngJmMV=vbE4SAGa}t9OJ0r=wF=)PC1yC{hDVAE|klFYjvi>&}j0}cc=XjBd_2l zS)K0+aa9NUZ=NS!I=zGl>x7l_Ken}Fy{Xx z;i`wDAgOqt;JFS1@_g|`>N-_6tD8kW+hB+nu4F~U(o++`wV`E*$5({q!+)*N3vO@h z9l|nK6k0GH#`e%-NR=4H)cwTr$_H75mrE6}^|0?D{uLT}z36b>v&2Bcv52dPyIDcT zE0bQE46r+;m|tP|>OJQ9HH+J_C>i|mGt|?}pY!i{n*toNwgR^T(*%&#Rv3BnUBOn31YNa=lkYcfC={=qGotY-h}!aB8?ua`$h}pE zQ#JE7geeI$R>9+U+{?huQpY>_(zGc?wZ&jCu-&qz*h%x|z%>c1vx-#yhfgCYx6s=Z zg;&R){;&njsL%Z6&DmrEmF8lwE1eP_?e8O zr}L>8+*a}Hdna4NM_E#&(t0lWkE`99(DUc}9Tbe>2^gDQIB1+N+jwWGwY&;HohzUD7RoqN)gx~G5Fg)4BZi0G+3_Ms$*Yfpem`q>lKWt52fuah)R-LPX9_$>-(oYTnn#(Burj?m0>!E6(;l4 zzy*rQLUI6E(n(W}`DcsLfVsMe)J zStVzSFRKGnV9au_Z7m;Jg4Zhrr-*Xus0uIdus2q%X}lQ(c-q$hk{#@5Rr)uT_K}K5 z6P!850y{cTF(+$Y53E9ms`jBLHElK(^0;nY1hsD?nSG&#&%hTyJ2gl#SmmKbK#9G|nhaOVBx zW=}Akv7!2k5RPANq07#Vf7`)$rFzF-0$G(hM=d-}K-%|{kX!jvg27BKzuqv>wB=Pa zAQJ5E7~S24Nv5UL6Bp*t?)wL+MH+DiA*PD7kOvuk8zV%Xb z5$Q2S;2#0Wa{Illx!ZXrZlC}WNc9Go==w|K{0!NY#n7=%1&Ljg`ZpYMJ$_)eRGnDT z^DaY6z-(*Zy)p<;)T97vVSMA4SWC_qsL4uwVOZUte$-+?Df{EY!)0~}A6p2O%`{st zuONm&;i@Xy*eGUu7l!UvceUJyS}ddR?#al#i7P^?BK8cA3kqT{yC=;gq?{M|noy=$ zYzTuIcmaHwjH2T>_J*psFP;l<3nM}u_4Y%F5U6(SbQOea%NB-0%H~_iMy^ZaWCFRJ z$?;JrF$ABOjlA2`id{|SS4XJ?Y+-eFSo+aSAB>*r9)yt&1IfV4cjVGA$+>>Xp0yp> zSh23$QDSZ7mj3ULaZ;W5Srihqe-Gql_kcY`=>t=fHqfu;$y`=iAFNv>P!u#2-AFkb zE8K_^jPT9h`eh1nYZJ65;an9D!AfUN*U+x^6rtvJcCP;PyD;W8r2h9mhgbU-uv209WFiU{kljH+v3uX2kqZw7%?M2 z6T9sX7QtR%qZCjwvgxM{TqSQZljZ~_TZ27#>GqmN)BaYSa_N1FCuqqO9cH){6}yen z0F~klfm}J=H!f^H?fr3mLs(i9Giij@hxw`0Em8+IG|)lnE1>gF)!}^mSBpiSqh=~D zaZy)FP9npj{y z;N@^TY|MunsSJSyKaP1}BT|1I0+l8tZk9TNVm#a*!}P%`To0)9Z}kAHW-A!vw_X2e z>fnoaqkElZG^0_iom%L@FpiXk#DN-G(H7Rk*%2fAB?ttrZ=RsT#ZKKrFD<}};zpf? zwz&HI)sq5d@&V0nv-kCV>%3rsiAK8-g{^hT6*_>G;~m>#>(P>QVJgSQXJY9)Q!`ZP zbK4RpC11WiF~dr_kF!uZ9vC(w=-+vsgQBxfhVl?wD9$EbYseJa`Ucy|_PNpD7%-Ne zw}`5LnB(R*p1SmB{wX^;Eu9(#*08`QOJ;Zhub-}0AuW4DZtuC(B^l4q^vpp^#(dRkwzc157yvSkUdQb~x0{@2h zDKL|>^Er;AW2mPwa>Ri|p2EGwNF+&!2}x1Z26&BDp8)L!aD5&IL`nrDYz(@;ep5e3 zF-m&!1=uh;lgE{{zN~!3PAj)?C0HClP{6ijXdyi2X>uP86I_tr5gEcKtVY!OJPQ5D zZS;!p&Oz6;PIQ5IHwnVYTd_y_xjJ6>%SQkCPNAguLsKd+7-vz8mYT*xN)9WEcn|01 z^95PtRRoKZ)z$(Q*|^0W$lOmMjaGz+Bq9W{f*5N)!b^&x;XHk<<&9T@#6=~5G%D&M z?|h9K8s0LgFXG}Zos{x-U()OPsJhz@5Rh9X?pL>!x;4v}%V;DdvR)0V{yPrcfN;OF zeRV1*>fp#(J=dn-TIb_S0hNXtf2}tIZr79eGrTdE?Qq` zE95XuAW#82L7vg7%5QM;vA>RZY4J=GFH6ZT{0A5y@*=h_OJX~ zH8F~Rdg`K3rj(B}wM?o+2+w(#D2bKd^1EOwbZVx#nq}c}4iX3q# zXeQhbLi1+X(C=vmCe%z@hW%`W~}fmLx5YD&MnNx@ZPlPONFO}xfSnh zU48(4uTNd_CUjM5#+b}RVwjjda&Ku)l;mv1O}F(1e%f*o${Ni_E{W<|QjVx-QQIlT zL2)_no-DOHCZe77F=sJ45OyX6rmxQk!O__a1BUf`$evgP|L}^LJoqz5sl+9SAKtpx z>YbDEk~OcTCXb;tdqg0);9plfSme4Gj2Rh!J((X^F+=NHaE(0ALp>*#`NcSQD?Rk% zGB|n*eSB{d|HcB^;ocX37bGZN@nTx3BV}!siPUy13z(i|y$Bh9D|MR1BH~`X`7*7+ zkI0$8{BuMzMtIGG&@^ULGV_mhbk6ye-F%_$1za+DUV&*uw7pD<@=Hus3$eoYq%`G^ z`^>5^r^bjhu6wkL#$-yu%Buy=f*9kWk8|r6=&3Mz#Z(Z5@oR8zvs6}t(IB3_a$J|T zKEu|&4BkX_VG&^8F&rLre8y*G_+FA*l$v)*));I=z%6kij}LD)2AuiJ{pRhU)_W;*vUo+X{DW*wj8%`f!YBoz z@n$I?U5?np>n-`zJ3)`_a1=K*b^A}{;6$lgzj2`WKk7gwOCmrM{ug9cgS*`~)4*Y?qlQL@1XDVhNXj6F@hq{IXQXx15kzBDd zypf1)*Xh=`wPgSqLjidhAk zTD0X%8NyH%;>SA7;RsXEbvL2_IDr8_HTEwyi^^@SG_0Obd=}dsPnTHE6=~c-N|*v1 z2iT(v5S%#^F@tfs(RiMI5FM&WX7T(6nQ)sSK3^Rzc;u9~ILJ>dXxZolO!n4l98)DN6mfxz)i4$Frff50r=K*ax* z;L860L2#AVkd_k`{vU#?qMePb9fvfHjES+u|HW}-WyhysVrKYH$CVzRgO&b&OTBT> z|L>0Le>?s!$CaMr|KhkZFw_5Utv6PN|F5mL|17;}&>7Gf{?9<0F`dbO>#+SFDK>LD z3p&gH7Fheww%Y$}sr_%cwErGb`)?xce-TIfpGCC)Q?6zEf5^2Q|D{~ZME}3Zwd~9s ztpBB4%fZC_|5mQ8ZZon!@o6K)=DKJm>8x?XQ}OU#M2*=qfdZ{=dWbqS~2hi@*M zL+LE%gVBliy7F(a#lB{*aub<2lJa@5v~`rd`X(0u^&c&O^!3g3z+a1* zgaf+NdZK=aeRFVTz#mxP&J2K?Uj`rGbwHeIf!J8TK0tgi|Bj%9n58`o_6;C@R#Mg3 z(m&*TH9OOpxHRzm^|RrDhjrM`j0r4GzFxQx#;SKerrNR8iT#V^@$L7GUd{ zU(d|VO!mK}#Xf64gI~>@XnxjM0J8k7CBBa6005=R{}{#K*YJ-i=kFTnzR%gt*v#zYx6XXa&*NtflV3KLpNa_##5A>! zLniz8lofmfpZ>RrN|DvH6~MIA?@A`;=6C26$oYNEzx;0lBePEgJ!5lIy#rV}z!W0- zu~pVj38?(_3+2jD(fFj322wQzIzndY}z}KgX}S2B7ndjP&0qnH3=8$Dva^ z#PvTLpw0B(HMrl!m%2}kKC4LyOUs2HJGkpUY?MFRz@*BqoxROpF*e86(m$nla8cpm zRoH!rx#=_a)Zv-I)1N+x4?6tQzvPqXY;1m8fSf)bCWgPNufK;cIf=Wz ze(yGh29_T)7v=0|Yw17Rtv}^&BUT4j`**3wKDhq9+CQP+wO!xBaF9D^pG{hXu$rU(=c9a#f!y%cq#U;2Cd{Yyuab)5TIshb!<+FC(gcfS$?3#T` z6Il?kec;uaEH?GLU)l-2!FV7Ncr)I|m=F4MW5mS8CK!TVxGx}IS{>OmqV{p{@PsB! zkXprtn~jzR$7sye`kGGCY??Jy(<{87S9aU-%o8$Kq=vcV721(rbzjCmtGYS2xy^Ui zfa6htp-p4JGK?f$_O~%anu$DV`X-F`Kn#x_yw($&XLsaMqb)-+GJDR1a?Wm)4^5oH zii}=F?5~OLkW7GbYu4*t$+Ur%9~4OA1hxo#@~B3kSMw!f19-6LGa1#gC05J_SODEQ zn+fckrm%D$2zxaIhB0bxJ|=smZ2BU9{N-PQ#44S($1PhTii+zuLtY*2#Ou zsaJ=kpGH>_tWp+>sN_-w2qRQSB5PVS29l~39M@DE^3+*0sx!7RmN$5crvI*0@5*C8 zj}KAJ!zRAf^T#P+N+HY-eCLHxz8vYiHHse;Wg-D_2B3i0R7M#fCO4E20|V%1lJuSe zEUS9FCFS$ys(ewn+6|iwT$t+}fDM{%L?OHOMryO5pS2bTptZ?SFbWubZfRf6{Mr!8 zLr1~!($=OpQeanm#_YI|xuANssOEHF7jzTt$`C{}rq898(pFCl`)l*tFpf`Jd00$H z_vW8>0`;_6_F*f*H}gB3_YVB?jVUM!iE)=$Ai;9 z=oe!i2w5m!9K4SW=c@<6kZ5*2sZ#hU3Zk|Oz7-$TZx8Y{(d43z7=)BeI&_jxY^Hd1 zGSp`ZN2ezSwCtM}9%!GrUfZgMJxrMnnAu@{^N6TWpFT%3+=8sZh=<+VNe0?Dw7XZt zS35XeIbExUne+5Sv;8$Xe>|5G3I*YY!2`9GUnR7u!GIO0!RwT!xg|uaA*LT}!*SI8 zW~Df1cRe#vBXf@ok2l;pB0znwggAomu+h6a`femsOC?4@=-}_Xs4co9(qk;1T^@>D z99b;1>`^>)b>n}O3g(LIapT8@TJC^9NqEGj&|&m4S0F9RJ%&XGu0nr03B-w8{*F`Q z&kA<*Cn-je8ab+ZmZ5OsG^NOT+8{uGJIZx)*Wa1!ok+!wkYoBuoFAray$RhB5#feG z37BIt60>iBAv2u<91z$z(st3z%ktBJcvNkj@^Q{r24lV?O7Z=0n=#*6Az#p!@rFK2Z1QTz2gi z=`2}yrq2E@l{A~Zj;hINxs>)4OQyCgj(_D!7A z5u`gn#`RYk6~qM$wbc-(YGn?_m>A0+Y3K)dwgRezbj3%vFvU#Q&KDbM+&3uA+oXtL zz)Zl`+|VQU0(5XvVc8+>=3!pA>mH5nK!_D=N zV@yFg(v{RoXc1eVH~%7ndxsm1s9?yS9?3?h(7iq?(@uV1lSvuCJ&Qmykur1q#>D=y zm)J7`s|hT8EgO61MLU!qf68dynplsZx2YZ0#PJnBq;GuTzS}>KO_9*Zt~q}UvDwcM zhvzQTx(~;Y*;nq$jqEC8^+X;xIur-=~Aa<9^UOYjvp@oee1w0GfJyRhnlC zfXN~TSqO+S#EDf2Pt%!4nj?^7)B7&DCmVc_a3l*?d<0IRShae}52B&?$;thV>#xT~ z#OC)nh1J5YVSsx`Nd{%;#QbpAWkBS zo;Mc?*TvSHY@ecr*@by-m2{8I1evm>sKQ!{#2Ug{=Eh zGB^uhJ~Va%utnq>*+`0hK`)1oie)&@?7QhOh0Q6Ld%vJoC3eBHv+hk>$czCM zBkUNn*+95Vo;s7?tD|O?@B=NR;Er+*q7Z{FwvH2hvTjFiiWh}05TSyyt-c2`EZ%UF z2;F&g=K;71wyCuF!9)>dDHjt;pDlud{>|&PV@n*<3=Xq^oJ(~6~D?Uk; zjA4;I%H_4yybNkIm)a@fFiA5N9fqyiA%Ua0CZ}I?tyYXXJuK}rMTz9y+gp=FTs*i! zO#Du<;ynd%{g-H0;X*k57xO2g#U^_YVx|?2nVrF_8#$e;dU{WSf0?G!^Thv<2}UZB zwK0m$m^}iTw>@d3($yzUcy0)vQuvuW#~_fvtkjhQ=E(9?N(LWGkX5a}8%Xi;+|-U% zp;2K7Tfetbyhv9Flt#!xvkbODXYXSmC@v=5aVo+kJ@jzmp2B{h-O`eu5onp)q>=C^ zEn3Xwl(m2K-i9EIp>({)pciNn3LgkAW*P=*M0`X^E{wywH^UuMQH%?wY_)d*QK<7Z z`5oc0V9}i&<54EO4ZiKH3Lk?g7H;9@+Z$B9LPLo^#prpYwhYj>VpIAbw>>;3Iq{bn z;GnB{Lg!PLBfA6ZSW_%P;+JiSP)6d$1$9EZJR;cHT720Sat=dkBfcqv*18p(GfFSe z)UQYc-KD!oG<<$e2SLwsg_{b73#FX>vvI`CT_BkP`p4-gq1SZSri^(-Y{Gk%(QT-m4M9J&1*F%zWPdWISklx;v z!+DR0pfWG+{IhPK*d|T#3HNpD`A8S*-TUFL-aq!xy*Q?PFdCf3HbXtw@NN-t^!f#F z8(1EzW6^HSkJhAwxk{7(ebbkoY!UJL@^k?nT`$y&rtWh7^0!ih%$vc~!|%s^_9=h_ zBaTs)qd5}4CUp;UvEMb9IUp`$!=@B|EtZ%td`(=SummuUS#u%WysPyB1*3qqa87mz z0xpO)`zXcKsd$3s-JKFzQ}>X!)?iBHORFn45&*xU5RY##{ zWD)wfOCS3N`Wmc}w7aEM`Dl#t4L=l{U4V~J(S`!}7}Ghy$9RhG>fG*ZGUQ1d24NgU z1mT&4Wq4(MGm|}Ya%AL<{)2pPJz}OdWz{BvCq{r|J#<9TpYH5%spwILh#Q)9Xcc)( z>)tTqpv$a-4^D&3YV1eI>E#c+O12BLAcu~Ospbtj3OHzKCZYzMurDv`N4EEy_p$iy zlu$_A)q_Z?(V=T^v>K{-A7Z`LEPH)eg{Q$Cp|Gj?nu~mG!)%NJZtsR9`a&`yb05t) z*F{$CunX|PlF2hK(xT=`JZ%t)X~`%C$ixGs!N2$swHu0W8Y!9PZ zQ;#RrQAJWVv`?wg@p_WpVy(ohRI6}Z1A`M zD@y&4wqQk9O&xD`qxVLnuu^RBe)_b5t5s=!clJ;;_(FExV_{~RQmmKaZgZ(RkO788 z;*`Df2r|BsGfD)e>4hV6xnZ9VCio>DJb!c|B-xs*04_*3L#0GBu)VPj|D_7 zD4Je5Z7^7Z2PMEODF0;io++`7rAOP6M!ORPvI)j*QQIdx==ZBaoew0)dRjrI9vp=% z__Ls!1>2(*l1{7`escLFPraBnTl!w?O4ACL3+o?YtlU-v-m9j$Ug}-gcywkw7{WYZ zd!5|+Nd+NcH4j&~Ut#AKo7keygRLe&wU#4broGb5jI>sFt!m_enfP0vOiy!J^$={{ zbyoe!*xc4)+3A!gzEh|EQuCe*b_vDcM{HoZfRcGV+(&T9EbC$H-)TiqvF`pfmheM?$-4Ggq5*(Z8)V$tJ+ z#0*56vcsXTETO1~90P?zMR*3-h(s8(9Bj7j=jP{s9(JO)E!G`P<1-2$h9_Q3avyEI zffK0LLH8{RoJ=4tq@-uqV!(zmkoMq-P=^zGsyWdT-A=pXQ--0*&_VgsRZL3M4oE1W ze5?gizLbO*)E$jV$yf&7&gxjY^q&54-VOw9izq49yF8|c2qG~pwiwRx9kw4}UEi95 zj~vLTa`q_Ysc0)#K{5OSxub6wJQ_ae{+V7+n|GPI_(_6XW56q9Mg%}PZf}k7crQY7 zQai+)a33P2=(BtdIqcmIm2gZ}XG6*PX3Z}3%)eJdPvv*|vCxB85DBUBUBhZfb*?m+ zsaxAn>&;i%Is?>&)|Qa@M=NN{&C_O3N=OPMiWZF5q%he>nQsHk5)YgtDibI59Jt6YMIb690KFmZ_2X*U-;VXL!ashF&X5MwRrGGir z<0Z!Ay1hNm67`SdZUcC^{mG8gJM;r zAcS&Z1t_CsmE`MiUV8r2aWgFZ9BWphPELSJG{{|yVt=3c(<#5k2e{r*ByM(dDtT+E zPZ1vUWy&$r4<-iHf(+zTB<4jSNaw>znHj17)Y?quhb!n><1RjA{!o>VW-(I|w?>Uh zS&i~(hxHBVJS1Ni3z;N3DI->Fs}_N$-nCSQs4woN?}p(y4cXEbvlj5`N^Wp6f^$9% z!eZM71JrXe?cu5#*>Z>yn->*fu7n&qbLrT1=%b3%n+IgUsZ;kGXj;!$R6vFzuKs0N zgM}FPj}&u%T|)fg+rwp-!d40Y&N>V_f#IWe+jCk6zp0oG)C-fCV3sX*-Yb00sdbIW z#ePJa%ClhG&rzaDH{zmPKi&fTu>@Ac`j4zUlh>-xv|S{ZRd91LlbJsx5+LT2Mpp?Z ziM{8a13S?<*yWJFsOZ8!3>Y_3=m{bpTS!tOEG01Pi79kf0by?J&~5rVF8Ox=T-&5bq5m03V9IRNP8z0%Nl3F2{N^?_ z-_Zvio~-Fjl|Z$%!W1~295wx%i{bW8z*Sz4hge~iec!(;co)li6wi2s!wd>Qmv{x+ zrT+-Zvi>6*oAwD(ZV|NA0>ZjA$X)qU@A}Iz1Az89i%Yu*K7AjvmeX@l=+0~Ek+n>i zsP@;O`8m`!s~)*@!0ndLY3P2$f$Po*US6U^u;XWC^#i+2I&AV_kn6vqBwHR+-eeCp z6ttGs0QdO}ou{|kk&#$VI(M^|Fp!T8d^?`%A;2zKJwse{1zB%*{r(a~;V;(gBUTAJ z0&OE8hh;JjhX8=TsQ&)eao4sp0A5Qg77UiEjX<%@B(EEAym8(UvuoGeY$YE?v0hCS znHurSY~Y{(9qSdEXw9A{4!|WicmW#EbqbusJff&*A`QR6FDI--%-+D?+SCf;v`;dJ8a&m&i3c3pf_!Wc8hWaJn2`{t#p&fD~ z>FXkD=A-rqZ>~riJ>rxMoi6-zXVHr@`DZ1$^{VQ#<`peA_9^HE#%LGn&IUVUnLY^f zR9;|JmMO-l&SS3I*hAwnd*?sTl#j^>=C43y4z|`+VFOsBqXf z^?vU~EfC?qUl$G+%PnUxwufbY z<9sXm3r!)IJNAFC$n{aNPxAV7IB53vZV5v`VMR!vPY z*Ui4I>L_Y{%2pt6k6gwOt;IZvLM7X2ppS?>$IBbXra+WRM%RRsFR)M$QtMy(VigjXfdcG za-=a!#pxJ6_zyJDPD#RO-Ox)JVd(pNfbbewwWQ5T9K$V&If?qY#cpQ&PC8*C{{+y~ zZ@{!NixtPg)o^mGz1PS{hwWnq2yAXY3=&Dbso|Xos#m-&JC8i7TwERJED;6knq?DR zXr2N5CctfaBt#t+mVU2vwosdN%DdC*kD;4@bW!5dXgNh|SxBSdbaKN=FkUjz-n9vU zHGD^pe^JWs@AzKa1x!23F*(ubG6ZXU7sGd(hsVP>L#%Eu7iV`f8CbtEP6>JsjtmaD`IQYpU)> z(((^#G?Y`DNC-U@)x00P^f+9^kSsIWck;Dnj#wDHOvGR5>%(o6I(^9Gr!8(xmGV1| z;l1Nhl&0TU_bGeg8KXN2Ym@;~py5Dba_;b4eHfsK)%Nd{whV`5^UT(>EPW>R(u@0j8KrH-I*P!k$eXh*mJbDP|$BKV0e7U0%t z6KE)y0`&1^r3l#$G1!pn0i+DDnIoHxAk-mMncDXioMTy^rb-p_roraX?3tY{Q&+5* zhrANn?0tECvVd~AuDENda=4I1VYwZ42dn}1K>UFTte$?KjPZtf(hI;Ng4IkrOTgXX zy~))G@e=x;NusFU@yBpv1htpuu_yi1EwKL(-xx;Apj#&q)WziG8FOHq?zmi%h(v@1 z5pYuQgnWa*z?0Ac3n_KdiR38z_4sR%avAt8Hvg6bj9({DnR(~3ceqwlH!M7*pE{7) z3&7nDZX7#6o3ZsQ2IA_n7bhFVZb{)1Hzv+Ues!oFw}{{<9;dIgVaFM_St)YPL^Eex z-#~8tt*|q;lN<{qZ>0zx)NY*;1I@(ZVm>EAU1zyDwv&sRVVAMMWlK9{?{6a2i7m16 zY-GV=k1|O{Y|8|-8cw{X{eTXqP;W%=$_&At??xS;Pk@=G+U{)rgmCPt71^+ zvxhl`V)hqnEPyMr-wKKTK^nZU^mazIXiVclZQu^HadZZGnRvI&*kQva_bBPpgF~TB z*G#EV5D=5&IQpU#U_vBdBQdc+U`3r4Ja{kuVK#*7{$0&Z4mL%z0r6oc!J(7D{re4k z{xzfo`m(84Ky>qRlP1p5N2Z?;DsQshTwQZ{v>;oj%VM}>{_s4g)&mcuusJ-NFbjGO zkc1!sal`mjp%!F){nhp_IHX&EN*9Uf@l&SH?cZ-(m(X=L$4Fx zuam;?Qu9A7F{|KvEfyUhh20h`8UR_BJAR5aiKSaJZ8(CBz>?!2Ox1s1UA<&Gns&xsHk_7JMZLCfcDjp<~ zjk zhvYJ>b;H0<{%@(IZL-)L!X46PQl*kQSQxCxcnO)JEd$>1Tkwx~pB5#ux4hzy%Lmsn zNB=F9&mPN-JP#u2gdq0Z6D#!8$&z`^;&z-r{Eu%kuwzTqVV`8a{0Q#qwljCG1e~LL@IJ3s$x?CG8Rqt)mr!rb@A(cC?^&Xb`_P4T zHgE@`Hs0kLS_j=_Z*tEW*n^`CxVu{h;xt3zwe_y3vBOH*?>=7y%<|qmi1wDp>d)NQ zrMkPDceMq~K6Ve_D``nU8o4-9q5$K6z@Y%~mvKFA?ARF|G^AP2o5=btKgUX{z zu6Jp9R`m@JV}rQ$5^m$ghCoMs>Y{KY5nA7ikWtY(#D5zx^}%fkgKr#st=X&8PEx@q z#65`SrQL!n-%AXI+rL^hbV%I6x2&|1sUT?Le~QLuTN#Szx7n0gyEW-V2S8LiXnH^S z1XE;kyqdrvFgF|4(!->kHk>c~GIQ$SOz!5rzOBN;@#lJW*d@isy&>(R50t-8qOFdW z+4%swJL#wEmYMw1t(@hYwJOoEP*9I&BELNYT;Z-$od+=WHVl`}5IR?*T0Llh_xlpj z%~JwCtOOw#+qtByYw1HyI$9G-%^x5sgWJxyw`SCn!ckS+%n{BTni zi%%pkMbjr%0aX&P7WZ{_wXL#@6=MIMh>_wSJhrwo*&E%k>txx+ON2>67|P>@OIgi$ zAac5x18pyqR>WG4;EE7fm+@j;aPV?=I12G5wZJiiDJs^UQNonIA)AiYz-FxoGOO6I z%0+A0+`d1;WphITw+@=9_DdG349LLZ>9r#LLK7)A^KV^K>d>fP=dmB~xs#f5hV8P% zr_IlcJQXPVHwg5rT&+suMvE-a7R-(lA^T#I9`%owuOEZhJ-Hi*>742c> zo5KOK_R-jg`iZrTCNyTyd=*Nn>1z$e`)^;oKM$iIi(FDZ6=|5^8Q0OZU%9Pw9G4L^ z#9-jq^-`u)8`z=D9nv+$8YyaTRXZi6Ny_xP&-euO8noFTa zY{tXIzfUfw&E`bdGcO$sU*;Ja7Qc!ehx5uEH+{M96Z1c33uUnWNj1}5NcjE(8Mt%p ztd*htg&a@KzmOak=Z)EGk6PGv+sGObpy|=Zhv`G}-W4i9@ayiRCA_NM2&<*}76O9W zW-XlHSUt}F-qzP|l#!K&>6Cc;6~f^w6gHs(&3w zf$y)hpa}gnHko!Iww4AOh+-C1CZaAx-fos&@nz>me04xx`E36Ks-u;3Oth=#3?zQF zH{qU2gz?B-!(0?7Yt`PfV;bo$al?22d};boyoLUGMqU3ns(zPkA`od^hiR{v1%a)@ z1`e8-ezOrPnvb3@b0EB!hJ=lA&Bn}kE@kv(P(CaA{<_C!WI`|Iyn!EVHMr&T#{w5T z&9fg&aR~nMN93m;z?u0u)@4FjaXRx%1x`rrr8ChyMUsNBoS8EZZa_52@-BGBb^TYv z;N=`Q8G`LtAFl%Jj3XC{#Rs5D=0yoOkZ%X7@3S>;DF(nUfCT})HVf5_A11K=WdT~~ zoaNm-r^)Hj*d%Up(w-#%&H3sa_9r9Eo|SzOSL#sHm!)%~O2f*T`x7tF#q5*+Z z;@af!xB33zu?Kq*N=SGR;L>vM-svF0s8k;3@JnDxms*7V!th5wO6M{KK{48s{VZL$ z^X!9aWSQatNmbYqWiZ++Tyu-vu;bPrT(pGTe#)i{Kslm48~3 z_^7jvl8uH78men!OUACdW>R^M%0)hq?K^=?xLIgJjpqn1h5X%>**QiZLT&{0aLzBb z;O=+9 zd#LTn4e6!^0`49)>HXcLgcn7vX7@peOt+1{?r2rZ91oH~{3Sw8*o3&|BIYNSFd8*+hFLqWL6H%!V{}WvM#XRe_q)OpPuk+d9h5){gbaH$ zu^G{DR@Pe7{a*v5p^U8k1MERU0`cucj|P^}pT)@0(wue`us}Wk&U{4av+g+4yH%d! z`x+AJUTdl+L>YTsI?N@p&R9h3*N(F2*&c7`UBIHwIawIg_j7W(o;4P}|6wo-E9T5m z<_Ke9T51XZ`*4bn4IdPtE|xi1_3|l2N=n(?j9#fjZt_R2);d*rkcbh;?k%r8Q@Uzi z`&IG2DZ49(tf>OP*b_(r$Xh|v_vbk=&NGCx!6XS>{Ple15v_~ke!ziS+taBZr>f*eS-GYlyYiZCcU~YD5t2dQ}KewrnqNC zx2*Hqu%E1D?&X34yskTN0lfD2%UW}Ot5&=9sZy>8A4_d_8M>QdD2mi=7NHu{*Q_;} z0eX-F5b~BB1$M!GS5(>M)SBhO%T8KV4^=^u6ThG!4Yem7?FQ?SQ-8xboYH2<`TSOW z6Q~k|OaqK9Se-+|pghd|oU~PxiUx)<$#bt8QnB-2?s(K1WQm!qrvNUa=aiTvA-0;= z<9RM9)Eq#ts8q)+uwED(NMG%u5npI$3L{ek?OYMRFQi_K;=L)Hbr_wE!m?VWd~|l? zQ`;_6N$=Q_PLcxJVN=+!BI8@bPpZKX>%nvXHjW?B@b@s^6(llyV{rBNOw&vzX#Z!^3cp^_lfyYK=4;c~)HO#y( zB~j@Dq#lG_2v7(q(KGb(*|syAtPx<58zI&bR@Z~Uqnx&Rw4tfv>MUqvC>->QD)CfI zcbu_SV8wD7&#QxCbp}aAQgqjbzCX7`|F8u$J!|r~UIq)tCsL+nvN{8D@t}vvVF0UrcbtT-3&L{J?L;>79$=r)aBQ3({Oy9fs8Y$w9Sg!h7AC~6px1_X1 ziln0sdf-twXq;HmS`*R6Jy>l6;7SS})?cw70cS63EbTd!f--UO(p&%SSnzxp?iDB- zimzUdsgP!QFMH5nGL0$pcG0V##7k7mJN!Bw)std+^9v9tWST|8n$75oEg5Fd7jIKp`hhNqJTASomYMW>Ola%uKoJW?%jZ|E0$87%wx3KEwHC06)(6oRwbhj{xg1 zNZZ$Rp4NBlUe=@rKOJ08l(<1;rTY8NWy@k97E%? ztX#XHf@#^xcv>4Vixf=N15EYLHB#m1_`q~G`gE+%VD%>8ebj;U6bp%BkqGW!5R%$q zJocuTX;;$?!Z)(#t?nhK+RIy>Zs+qOJCTs?3z`X+k~s;Od^I?${4e1Woe1edXFLIS zppS^#T%+@~LQb|>WQ0Mu&&7Di)(Ov>rBn9#gY!_VRK-}6yM=<^hTj*eymsq%!1%o9 zeoCEkyHaW>y&Y1g-)GqzoQnjUGemc8E*a^3QKLVnzvxA znP}g88~-*9Mu>*T1k!ZK$6^GA@D_fnoY#PZFi^oKe*(|j+-7?rg0?LTkbYi)QqV!o z8V!OR2CCdk5y#x{SFZK;vj~fKE`jh$9^$KFK!VQ?Bp7pRm{TL(Jtr@(f@(h;FZ$F* z#tH)J%pi%)q6dXm6n*xb<02`zT7#`k#e>?xpf7v}=N)L*Ia{Ck%*j!!Ol=DSgN>RU6fH^* zdQ%m1QcrPbT>uc|O4fk&zZt|~eZO5`_P11=^RKVnc_(iGqrWS%lja+-Q}ylvkJ3@s zWQNVp^yJBlW)|gwNwvi%SWvHvQ_QhVuqr*MdB>SCN(#m{b;UhHf&!Nb3L>>+u-F3+ zOX_oSH*Y01L9E3V7RQ@K`QDhl!`0^B`weBI+3joj{e2CsLM_K0{g|O^%41XLLjP_O z8NsU*%07?FWI;8eT}PNO(?eMLsw2@}^cq9h^~6uoK4S6kYcgU{y^vobxuFArrN{xa z$-)AgFzFOnIT*ruPffz~s%V-7=JZk^6V1V5lS zP3vOI$~a7b;HM*W7-CQeZ+BarQK~#Vi*%sxF}6|J)7la}2uk4o)%d**mE;jc?A@mgO;e1{$M0A8!Ht6^Y zF@}2MWOE*4QKdYfhn>*)aX(^m8m-ZTa>()ycf;H260Z`oe#tu>az2DP<*k6poGaTO z$xyck+t6gW=g`)+U8!P%5m=x52CO2Z!0dh1$qU#2l(G?$AcCZ&&sHPita^E;EG>44xy2i+Vm~Y(h*J#8#e&&#v12Ywh*JPUN z$*GAeokjBIoM@yb3g8;;Fr%9*b2f`2%%*$Y8$cq$tc7W-V+ko5!>6k#`N}WQ-qR0v zDLxtnTfVpPrpKxxH5>^*S?5kP^nmpvk15gCAZXJuxRe|rB@f<|Kk_&LUGF}Tz;>|K z>MHx37`1a~^(Ovz{V5Y_aB-Js38TpA9m0$U)*Gqf4LzIg5@;AOtp71U8@4+nwJ!e$z2Y zDW+4*CZW~FB$&&#+zNZ*woL=BGWP2{bG}&pk^+_|-5W6QGd{KOc%%!j=ZO9>9Sl+6 zdLLvR(CIvw0j1)jce4C`P5B6-^kFEV__Z8f_Hq`c9QkMY0`b1t^u!y-gr5?hrFrnhSpO?n)!*kt7940w!>h0zZ0h+2iS?Y(Lq9|qB4ddQ zLo!FxU0u~-;JCsp&A9`VcNLT&TM>mTblk7D3}Q_P0Hp3s(?IK=fZ04;bqHPL@sQX} z@y`Bbmo4hcchACTO=aC`wSKBp#F# zQbyXWOLsq#zv=toq3>aR9WIGHYYgALe~z9kbk=Ky0PdNgkKBE_Iis>!BptqRmIt#+ z5h@#5?~W&oSB2Dd$Ht{GD{Q1B&R@gR^}lEpmRyfDY)3~MqL{4P(}I9lp^)aaE<4RK zX3Vvdq4;WzN25c#R@=d#m1(g1#(g@4v2U z8VmN&AKFaI{2eB|jX#uZ53QmvRF?qMOOr8+(|#7nPSE|;uoB9s9Xu12PPal;Bh%`EQn}^iRkV@-_S%G zjRK(%tfPcY$RBA7Z_qVC)nyXe<4ICdvjyxHY(ZU9_L@T}Q)tVqpKhm~8Ci9zANZ=D zL^NnK9iwRY;O}q|4w_NV#-LRUP#W}o+ROxcv zT#4iSTVKVF&6S2^z*Ej|lLaZG(!8N zT+-OWCiv&M(!^Ooq#fGx$C2pX(ji-Zf3>l_Ojh;XxkCpd>9>APjSws0uZO*{__7|( z%iV(21=oB-k*6AxKVMB0YH3Zeo}lC8Z(Mv;o0X<*`V^4NFLv!%uZu-#$@Qbp#fFy z{s~{}gdq}LC()s{?fy}QrjPR3h+R&JF|xZyQaV^jKpcT>UrX|Pv@CXC_zNWXaIkIK)du@+7*RRSJ^oaNqE_EiFe_MK!8M?| zEg4OoV~X4xph}NElhJ6Y_56BA@=kp~^hFz<_V0Yh(%rtiHRF+_s|D@R`nQb_NVXU$ z0C>#&ow^L}>V}a}e*wMHgQ|%TqCp7+R9jpylJNs#xo8AC80m6ATrsrECiJ6?N|37O z&EdU$MZKJdF}8~!`J{4jB2EwYRYj9w1%`?o+s)TUUL8rBTuLk&qHud4JR^>(X4c!i zbMasX4N-1#KF;`;NzPSUyRs1d14_PF?lZt=ZkB_SdmX(L`u}V1y~D9?`^WK=vPVRS zND5ik9%i;O5*dl?y|-*Cl9jzl*(+p(tca) zIqu`WuIqK4=lgu^ah~t{bz5ft7|Fexz~oq)V)|#pSNUW4|v*^eXfYF>R8Y-S*y_a=(Qe zY;Ka{%gOhA7pE)gMTHmrQZGe1+=%OS9Ya8l-AA1(sQSh{C)Av!nchgg%Q-YBmKfLH3xD?w~j1_-}30`L#ee_ih&R55k zY9Tab`1$$D3b?)*zb=|2s;2!TcW>Z?l6bjp%g5zl6%l1dA`?ZW3Eaj4Hb_qdT=|?6 zwV6>6-CoOF1)<2&0;P-L?RY=qF{;!sNy8ZO-StmaT0@Td zHus`wuw|wWo_-|JBFb7YpqgA+j$^BrR3|vg@xAuawzM}5J7=R&Xzlw?Z2H&SuUra{ znv*s*xmahGcyYDwmN-PvRohakgOQO>d>gw6`O! zI!+|xnnUjPbaM)yyHUGu$K9Sms z>ulq6yU#1^J?Gpb+-VC(UC8iG#WvdWZ!|D}-%z1R>@wpwSkvV9x{44D$>#j_FS3BPzJ9Agi-?t~5DInW7t&an~f^Qvoz%PqejZ^wL%_xUpWyrM3BT1aq z=sGh?^xR@hy2v|OPC}3zzx+=A7pt72C*Hna^c=aNQ_sR1k_cqPaqM+nuA%RXs@~t$ z_1JbzBFDc#zpE4A@PW5FZGb4qFFADT6_F=SXRpthde#>eCi!zur^<^H?TXf^b1By} z@6A7fpw7>|_DlQ1)|H0)1+Mw@6|O=bZcsS1JPQxLRd46Q*ey3hqv3B#T_G*Tou_Z2 ztre0iQQH?#zMj~~iM&OAmYaO|E?@d&^Xzyjd*vqeiR~A?UxR&dKVEnkDdsA>(KGp3 z0WERAim!KmKrw{YUJvCf5kMew!h$zFk-9`@F68TzTUQ>cJG#nN9N^qH?9lc@c{EtJ z+e92NznGnjy23ZVO82NgG7cOt*jLQRe_HdJw-miYw40pMA{kF)#QS~quf6@Vgxj7IN=1b zioGdP_fSv$*;vda&o{OBPKdKz37UN<0M`rfK>FYF6x)?P%Luury?WN#c6rgIZBbaH z>rM*ElgU$Q)aS=(+8a=@>*NjG(PX*@QtTh%eymcsKGXSNwBif0gG5phaelI2MtxhP zyRv5@gnPdG;Cwit={j69rba{jL^iJf>8MMokI_qM-CIR{I3h$;gZ19k_6a?w;;$7; z(BKGYjm>zgiM8hikdwvuicvWbB4ve&t!+M8u8Y3wF>K~#y(>R&odXUD7G;daxh{I; z)Roc;(FC?JCaSO{^5D%6Qr~$>r(IQ@NLQ`ejz`e z7j(a2+V>14n>)}jp+)0$tXK5f3KYmo5gMJH52&=Voyqa2Xh7Yw7{1@qwB0MgZk~Cj z{^^^xDTG(REy=jAg)>TpLkAs9Ei1Wx5}VhUA+L+PCT>2lvfZ)1aM?N!w~Uwl^>?|` zTE^+o1w`DBm6O_~%mW!8x$2*xNjxdGPoQtT+^yj&mb9I+D4}=$F&A|`xYJa1Dx6^{ zL!Ir^lz&<8pj4WFq#M$$OTOwyk<`{kC;sZxh1zuv##2U5iBF@hw2mA+VTjkhLXj7_ z@LrxlE{TeylYc-nYHhvMWX5hIRpiWwT|~+Gu*VcA@*L5Vs2hdnjqZLg_@e$ePQa5{+jO&`;IB1fR@+qV`s@zJvvk@`$7 z8n{IgE_ZM0l-#!U#mR)`ZYG7Jug%h5uqTu)^k>)mWYZgSaZj6EmWF9Tp`WQAX`$h6 zwY|$)ad64|Lb70{;f1Z|xtk%#k1Gz%y!mZQ{(OR^BovogP@~rqEd;z*K0GZ|7hy5) zLAO@K6+;-8zWGE4-h3m;wSI~5TGYvyOJOOMYtXMUckxX33~%eCkm-yKoIa?YwtM8l zsIj_wptW?u6FfdwE-27uf#2Th!Fs@#OSV3IAot9Ways>vK_LH1R#MiDP#0WBVThp7 zUPWZ6*|UPOorFr>Z6WmJ)BTwszH3!Zsvo=fhNojUo=!zPArvz9S_f)M$!*=B(RE;G4t)-S$6|b^^oSgCze*9Z2G0yU1Cf~xWvo% zh(^!K-fl3x%OCr}(L{M^Hnx7okMp9m6kQzuc@qM{q(Xtk6y$ksJEMmc{&%h4*;&0@ zvS%=Y%>3YarlzM^zr=UG^!d9riMSUn;Wl8y6W3bkMfTp&Jv?Wgav}GHIeGe>^Notl z9beqM^9o*H+9H0+6U*uN?R!u%&iVbgwx?uovQuji)xuL zye6*bMbr0-o>wYy`&xEo8zSZ2i58u<4a;KhrsZKUQ}5}t4xsgU+W&CRUXZBPcM;#q zuI?3qMQ)xmoemzjEuhfmO~NK^I{8Qc{#1AWj{Y^zcTy;Y$;%02FV6SEPpUB0*dJIY z_P~~kyJU?}%HTK>mfg$i{ND{IxP6Tx9n_YYx@H^KQ?+R2o4>{6$g+GJW7e}DFiyIz zZbNv*u3^4InhO4PB`*x!2B z@HCRgAs}pSxb4c546aOXB8RsrUj<&X)!!{w!WxT0^U2&H#TR-3-Qb)t`(Q+Py0D#CSkOuqFF zO>pAU`gA_eDe>&e*SN2^p1CX2yqt-DAhB+L+0z-{_6qr&m1l`ryt{tz>rV$NGINRT zXBnf88$qslofmZ&8v7En>%zu+CQ9B-iy6eCy-NiU{O|<(!Q!C z{TiS1x>`~mou^RTStkfrDTUmVI2^mDjI^)l7#U+9GmkELt*5A|5S{3t6k|GY;uE~1g#pjY8IA4le+w$i- zWs&cbkwb+Sh$umiG#-5Q-G0wsd?kPx@4^?>49&0Ff*GY{spCH?`gcCGq*=^U zw+(oj7100L!QBhbDAwL55o-TNFd)6nt!d=TUTjmev8ic8qy9Cg(WiwM)$rOl!lqEM z0^=WU>c1kG1KuDA7QljX~hu^EIpI%kVA*SK%*uBi;KJv^CAwx!uD z!q1p|dxXj7#p|v)ZCvwVYQ~;jpE@R5jThAXdFl0N7M2ikiDbB3^1V(f=Fj;jnll(! z&fHJ8u$fox&R{9teWW#f$MSAa(i;5L7O#scDD*!X(2)W=f?{!Z>JbpbEk#p+{g5q5x($apkEti9e zKWR*J$nZ%a1>L+AE+sf7#%X(mrYmi@rHV9Ox^P!uyA%J;kqWe zM>pa>?77`-DdA-Mde7JH6)g9G?NILGIoIn$Z!F+>GTZTDo=G-?AL$-fP!|{~dItF= zG)<#P9uC)dy@|C;pWbpP@0m%4-hGp19CUf;j#parrm-9BV~|+o!y1E&qE2-WX~iO4 z((l_z?7hgWoweD!^#U!nMK&X_ar)z%z_FWZc>(L4msv$qrfE;Im8yU8V3g$%`QD$Q zY3%@dW=Hm@dEy1>Xwppk-s8m;cJSK?5795OT<{=!bYih>@&j^pe|?4_(e4n*I%VU1W!ucAD;l}NZvEqOnf&V)!974z8cfKNCQfj15AG(x86y)iv` zxjErc^JYny#2o7GZV2i6F>Tmjp#P!`o4Bg1l- zNYo!~*x=yb+pvKV|Dg>V3jSLcHaO^?y0A(A)`#u(uTE@AhrQTTdG7M4@o4jC+wth| z=-6oMn(Et`=^NPn_5Ej?H6431Gkv>%wQSS1G&k2iY}|H;0gt|uu9>#^?_J!?{@uvU z=z*1yzQrH?+$@YO^#9$|P1{D_;&98uZ$CHutJB-hUT=CjW``60`tftl(Kc}U=EgtK zv(7S0 zeu1}GS@9WLW;aosmy9O`lgs&^J>tA068y4X6E?}=)N@I`I$2~D;Q%f<{iEU2I6IqI zf@dSQGLs8f_dFBXbxNZ%PB!={IjPehw<&x{3881Rhio97o z)f9vom)1!B+{ z6yFKi+bR2(`(CprNUyWB0(fQxk&6n(YxWK5wRPxspWHi4*Th z-6&^Javg&T%%kj}>}Q`id&`9}t*SFKK*+&8=``{3EY0q+mdE6gW% zNS9w2PLG}Gd~F5Ua|`fDx{M@>+dQ~6=y4W&Fmw0wr-tTvzUxtbUVeVG%bUAGf(H+} z4|re`8);0hJ*K5THhlWLur#~JQzw+4nH|=n*>F%yvhT3ZIO8F3l4+T*^PIaqfnLi6 zqlD1Jd4-1w0aUca&8VE7-;gC38RteiXOrp}MNe!St*i3eJB>yq z3((Bf7N*Y2oxDFq;S|=jHl1vtP-5%Ohpz==lej6+6R=#a{%pvndt9p<^(jGK8O-Lq zD}wsiK9B3NEj1}Q9XaDGyg%l-pc|`xK5$^A7>79b>cLt7WPfYL%S6l0$tZu9uH2FF z;GQy!{`4zw$*l?Y8{YoDAw3$Eb9ih17t%Sr`9jY-&sT87R0|jrN)`3lev4@cF0b6$ zmRq2}37I!e zuuyZ~T<5qUCB#CLdAFxMwR)6h#)!_e;4WhIX3p*G9LluI8G=vVTthPKPH5MEG2pI{ zA^y^CCrP2w-@MUxe$ZdB;bL{8Tl0mHMjN5XYde>Oau5WqPfadJc}>&C?b(RzSbbx8 zp^$3Q&Ss@nk@)`39g9jj>&b0p!)Ep`&{XfP$BF)eGv**B4V-=5t=N@wfK#% zL^L@^4CrM_%$>|%-FP=Md!@h;=i(dwA9V2+ij0(c#*bfL7nB_#k+h-=7?ELdmwL3E zlNBo8?LQS!(jg~7<(yb`&p3;PIo?i;Q;_tbgLZx=CBq0hzs}M>@I6I>W96N(ag&DX zv<07rGtSx0T9r%mk+dxMKlt;4iMsfwMnc}KFi~fWHnyC@OT*<(@1j#u`CL@&-f;Uw z>#DQBJS07hkbNrZbeVf`%hoydA?6u*@x*Bg55D|tvy8Kg`*Ooi{8(>Y97-syA!#LF ziGJCCw&{anixj?!te(C3=@S`&e>qfrWR{RBp)6BgEOxe|AjgrmQ<)3k9W?jV-s)iV= zlopLv`=`9U_+qpZ8ShxSmc8B$i{u)q5E0zd~5)oN1QQPl{($9|f8LnAp$rmj} z4hS3|cIpbdW6Y)SCl~QYWUN{(31u8&AD#4{CQ~m-`4shVv-Nu-zZcl$_J#cmrJ=9vE93&(5pPh6I}i(6+vy? zrgo=rTtTy3EQ^SO1-5eBJ5dZ<|)58>rsKW1x@Lv?pS@eA81JRMh22A zmU!w}|AX18xZv`8Vn!4)dL9nMYlSN`PVThgO0vUR0erIjD4{05!Fss}_Z7=#Hrm?0 z=L(=(?ksxSUwA_wX0Xo8rBF$5S-vZ^$v20}Z$FaLD5Sv)0nMa+zsZoLZx`|CrEuv* zErlydQ!=<=6E|PW8kjP!oh8;**LquZ;1@!AsW!3q#&*I%#{y(`aJH(9Hvh*&cj=f7 zGh@ge&U95&o;oeUpU(2Fml%P{tA)u2*0mqf$PPFQ^la`q41b*YzS@v`W0u7E8-t5R z2=eg@)#xTp&M&#&@vogH+<(;AJb{zIF&`;tQM9z&aPVAjfyAgiR?tmOQd_bg=Vgz3 zZn`X`kB*u}^(Ku2!-mPp32U@|+M>B!s5Aqrw(+t4yN)s0+c_NDeYuSS!UIwn%7H5t zE@gc#p|w*K?pda_3otkN;M&XL12=9ug-L66jeiN;TIlq{HF<1~v*$DsFORrI4xdXj z8ILX~d>85Oqt4-1!_ex@#&ZTO6v(IwIbEFHAhOy+YOEh{VTA$O6ZOQ~^!^+{_^l6J z+vypG>?s8c*BtLnOZyskB+%^R)r%`$kGkowI(6TootI7I`RD#oH??dg{Kdq_eQkY& zw!tWFn(eK)xAl$=LyNUuC+^C+qB*9DobG=Lk48|>3P=RML&Rr+AgU>?>ixXk)5Ccb z%F3&SYk1YqEpviymKyu?eMPM-i^LC0;%~}TL>XM};ZApW(JxM9Fr-MRB2%skPIf8K^@z0^y(go?g|QoZNvbX=4_(~_qBO==T%{q`04pdOt@dv-eTR3>Q)_?3B)-$ z0(zZR*xCQ6r@YWjXVz!u)zxR^xeu%gzFC=*tq+j zUpR8)!mSrEwof-md>%TnI2TiW-AAS_?7xRu-873yi&@(9RaDC!{yZ$aZ0$Rx&51sB zfon*Wa{5Ed$@5i4MQJ|jq}?~CUJu;8PH^fA>YMIhi6uWHM2VGYp>KGNgGFU|5A%Ud(j#IKPf5G~j&<;M?{@pT1C;||D^ zwJ#H{TC&AVah|<{T560lQnE*O245@uD&OE#;k;@-osLWX^s@Z4;j6D~@+9q6_YqU~ zsD|5b`fYEGxb~fTGGo3976gqo!F|ssu`s^OozU1WaL$StFMrRum!H=#dVXn5c`Xos z9Wr#eTVeGQE>T|m+!Fqp_%=%1nk=w-d1d?oMfA%~)m`c*eOJA@`cv-I5+s)jo>VRp ze4x_4|BUrP*wuWONjD-RiNXEy$;%==1Tp37mtVa8k@4MSj_H-UWi?shxP>aeK{zEP zzlQkfR;zCWwFX^z**92v<8J%ica<*0@k^^r$f3UUqMqjBSa6kel7?D{zVmq!JmuK; zBbUMx(eb+1C`Em9-&A29psW1!kmCnOceag*oV1<}*!)qp0%|=w zjIvTjLJ-EN_e$xzR>NAPCPB$Kes@z^!TISDD){)-OkNKv6_)b)hxjjtzT-Qh2Sm%> zHDB>_JAa$^WW4ksZ#jI3hAIn3u~GL0;aj0h4%X(!pL_;~42u?0Vh6tMg1K+HPOp8W zCl*=rbF`gnX{v-vkzBLVA1q#R4$^Y&^%^n|O~&0aq<_Dklec18=+n$rn?PkRcZY$Q ze%E}bi@I0*>5XZPJ~i?AMq#22Nv>~G;$@0aJ|kvKn~5z3FdiPSFJuWdS7wL|OiGtu zNkHRyk&$%F2xoT&C7b}t81@O4Q|A~$b|p~+l-;ALE~;C^wveYGNHkt*CjQ_nhYQLI z-x5wSUC{ViX{cgKZIgcK)m6SPt`5XkO77|1`{>ga>qs&`PAvauzR*R$_8A>Gho6%4 zikRc4GLyjZF&#gPmHUAg=Qc@&a%tzZpWYJVG9sX62o{61K9f{$BjC(Yibsu0nWMeF zoE;QX9^B;R(U5GLHd0PS)03Gzi*IGqK>OH zHOijiByC>B2WfGH-e*dr&#=NY}6_GQ1Wxa4)L69IVCupQZd^en* zq4o(kx^U_^ywnUFMSu1{zT}ef^G&)>Qe3DaI=5oDe;2DV51Fh?~ zNlPt!uRW`at*m(w#Y$ldYLl8L(3Y*va@a_AqCce~cv5Y;HPGan|(N@U0~(N@978s3_*4IaZJA(vw4PA(~t zy|H_3;#Em8)=|?>5=%=dt(qEy!x8TMR)zc14{uFFrU~e!)6FzyUpO{h!JnOia68+7 z=$zV6iHhZYJEG~b!mg9~Zam5NoIyc!Cw}l=a+fteWm|1G)xkGW9Qc5s&x`k}&OdcMHO`^;=rcUm=CN)t=388jTy#<*xvPkD4*wEHx!l!Tc2e?-<7NZ$wovm~tIEpT zOmPR-H|QI7?|eLM^5(%kk=3*UIV6Zd*lpxM>Y)$U<{jC0P9sTnSD&_-(((2A?EHuz zIcXam0Un?+PRh9F<}bJr+8nmNN4xMYPW%nu6RDc>q31PpdR-6hkSB&H@B|NQ;=fk9 zbv|&OQLqvZN8}m9LrJb5g9?i{*1ZFQ1WM#_2tEGx13Kr|uZ2{cXrivk_qZC#E=c9v zx@PuhgYWr>MxFM(T$Hw=@%7?*VJ8y-n~$C`MNJ`JbKb?#v{Flc;+5LKQ=c@o;;dxC!FrJHYY!uo|=#L zT6sn-L-ASNA^KI}MljKQ$rhyexz=<|H>Js|M9|ajVS^_;VtHy>rre*A^j}{z@66o3 z$}t{G_dIB-L$iw5|tAH&?5JVIwc%=`hRKL$Lz=3;PYF;U>iQZdA1A zS)P>kY0bYp8W@q7B~DOMf7^j`_SE_tzbE%ah!cq-kuM3XFEpOnxARHAG#lj6JU^w4 z9*mM)Zm#<3d@a41ZdOQ#&X|oyH2;0Mz5Yx1i;kFtwu-gSZ%lHwF3l~wC`WIgiBELJ zwTsw@%Nj4l_R^$ClV}yi@LqQ6lD^`5rXbPM%Lru$Yp9(Qsn(fz)v4OoJ5N(}?VPng z$-1r0TXmvECJnsGl#&<;N+L6@#94r7vo7L+{KWthZop&q=YRG=JI1Uc3CqQoHw|fVikf) zpJgQLEh-qn3R+GO+>#1=QZPgYRhu(Q%gb2Ea{9U}7fcw@1mD9$ggH+#h`bix#rK1$ z`$ZIhMN@7(HoutO?X6%e7kBniu!XYoL!Y(LH{WPVlI3P1zT>3ki1$DyGzi{_sw$24 zZmc%?akY?H$|tpwL*kS$NAr7aMAOM zzN`pReQ{ux(5#_p8$kRd&wGh?Kin|I-^E`$m#W9&;?u=5YE4}#nmmd1TUH6e^3MXx zIq2AL$6xDn%#wLKkGqsNor)Lqqh@Zu8PD=!G5tC2s+TJEpB6VL?*Cw;+tBt3CN8!N zFWkTC?6UeOW#2$e6xNqVpJieDk~Cp0XeYO!;j7QUseyyEpjY=co`0Wpvrg|%zsj9T zv64x|z!O1twUtsm`A!9`u7_vFQktIxxsJK-C!H5h@C}&?glfT-@pB_#urD}-byn)C z(C->yUn^V4Esd1t)dJ26v;<`_EJ73bUYDqq6m<$SOnkm>v4i)nv_-_p1Tknyy0RVI z_VnrXUA?XvGW~}Ja%+YUhOd9`c=CiJY>f(c*SXaMcZyBH5gD%7DgN%1!Dz-RA8X5& z0Au^*n5M^|tLf>KFYdcN2cP4VcJno;b<4LVD5j>NSz!gq0|nA0Kr! zs(#e^LX?E^w&09o8?PQInQPcqrI9FjYdc%*ZR4uOTq*#&iDR0axk!QVCJ;rjz zUg#hU&TMo^{+x8_XkI}rnV(bJ!(EI^XQPBd9OAmqy(_=J;-fvizL)ZuF?)m7b#N`-@zFyiLczQg zUgpBk%m?&BCAJGc+OJPWeArRZn#O;Utm2kdIh?!1o@h%j(DfRhCA6LBIo`#!eFlHk zpyh_pWzE=!vvK(|N$}V8e&XJ~`UI`2JhATEf2a5i;q4qz)5~-FVAiB^C%MsgbbAhY+3qZey~|cL zl7$npcje)Zto)Db1#j6_YZDoTNXTlhd0RUzAd#FtVnQu$rgz;;+bj5JZYL&xUyr40 zW4>^DYK`jym!`VaZN$v=!7~K$Fz++(6F&Fvq4RVrRG3XRoSkiNXLMy)md1OtR&KK6 zO$sck-yE)d=cBz87G52p{M0)a)a?kmv&6c}6`~9eKJ%jfqpe(fGZDde%f0zIi1C-P<<0WSrn)+^HUyly>s6cJcUNy!Y}IZ_xx<9G5dMlGwhA z903=m3OM$CeE+8<~Y|b2F_`iXTux@-Qwh^-^kr(Y`s>MVngTb;T+{T<&6Jj zG~?OA!1a4Vo{C;&;7VJk(8bZ1NAE(3TswYTy)fnhijFm#Yl4T!7Wuin6AZ(j`(FQ@ zNVuzh#xq+>(TU{o*FFXHdGFB&O&9pc@t(?Ydau2W?%mz=u0pw88#&<>FEeXiWj0&m z`7&Z9T|}-rWky(YrS8Qk4}Q~V0Sl}1WiLi>16KvJ+{4}5p51pC;SWEXEyz3!msrh8 zt$5iuTuYeHnmSwKBi8slPtl)7Yp(`W(aIPW{xpH_;T05HvC{yqr|7Hgr*&HPL1E`a zJ-mHlV$R__$k;S@RQ(dasJa~~9WYa3rpMhKlocr!6vy1J#rcTmNu}5MOm7Ix?s4CO zxlLklgGOOdu+pRP7L9D9{j(=86z~AKqo@GWy-3neFu}IrGwz-}%IBGbSHwbb~ZPu0Sv*OGrGv!iAk(&`@8WykRd3jqt z&c>*XUJz2K^(~6K+07q%Q~wq63k%`n;hWrDkcGCn7$<`b!nYiGsjkCh=4A0I%M}mZ z2Ju|PYMyEhevYxS+DlD&&|#Fo@S!< zuiBEUv|HBLHV$&J%+3MDy0qh~50(>}d~1%6y6jHe@1(vqsC1dYw z$pM#FT{A^eaL?w2H14yh@65UQ~v*z+!BtsLQhnI?x!8q7=6pnIi^es51RCGNAo6)C*s#`%HGMS zPFDH8%0Bt5#V9n~SWPL!G1=xrQ23jneh_i&xy833G36e%p1r#<>L=2h&(NY7+7-sb z4Qz9iI_T*e-JQh92B(<%q70i!r;JMKLK+w7!U(iImRJK(E8`;X6;ZsxI!2wPXV_D< zUP)fz;V0j6mk;;cKLuyeC4_Ew^j9EGrX>=Fk?(P;}#ZBSLh8*@! z6mpiO=|bsGH}wghK2184xrjKs<@oqTq&}}W8ET5ALDto2?Z@)nYcciayz|aUs|^Br z2SKs(I6}HDNn+c|2PO)10ZS6KIecd+2nawrpv?+n>NAY0P-h7MJjt+8mez~Ik(PT1&-=C$(+B;6OdE|?a(bE?;xiTvB^x0Tr&e@*sKZ<+X?((gs6K<9r&)1Qjfn6|#7CP{{qj{b18q*LiMn z+(@jsCiz9E%QGFxaGQ6-KNY=_{zLrQxF+v(h>Ahl3Db zTm=OMt8s`{M*PIPmncg$6qj_z&fb0~L*)w39wBN|Hst*Rn)V8R89muQI#aUPo&X_P zHNNem$+VnOK+AjawfI{7G_#04K5IAZ1@d09yZ8J#j`V0Tjku%`x9AOInJfO_U2bSB zWQce>9?#CrlqY&s_SUA!H;O8~WhZFo(8SG^N73+iHg{^@U1>KCaZfcqqgmnFEKAx8 z5p$mWzCa>hWCX1@96VXH(i1Vrg49rJXr&x$du7Ah7H|sj%wHt=mBKU4loexYuzrJD z^AEOE*};)JN;x%ooA|pNU|BHysZStbD8FDLN+6lH*+3$a?#Ifv7hc?yko9OQ2hEwNWf<@W8U)k}{qBW0``(cBpXH?sJg)=QXi7vzWu%dQgOTUa(5MP1wXi{HPnYT~mE!Rdf9^{20Be6twqy{t z_*Sy@^j6Lz8wAyhPbVMNyKWh*!QvljnwUVQI#oJw%j35&XI`Po)lIA|F6T3LcpI12btCD# zhAiLtn=QJVTfTjkJ^w5?pAzpE1@%J!qe6PJOVo!03nGJgp~O zecC;o+1p}Uy^UJ^!G!ey-}sp*vPF;m=`ms`GX+oGP+`fz8~!<;oOa^j6!VDCw_nCH z9oN%{UTV0amq$Z1zNklyP;Rpf`877RC4S-|(PbvkpZw^wDt6MplzDz`29#Xntkn!8Hbyce%!sM2MX z7@=Ze-iD=0NxYFzu z&lnEbN|JD-&jplyYxg)M|4yJXG}8D&X3Tb*`)pQ(R4eV7<&3ApUx=01*t81gn#?&* zo+n=-;%m${9dcv2Tm|8>LsH2Mb6kX9>@ZRpM!-iI= z3MKD@guwym$Dm^3`s9T+p9_YoCFbi;4#=Dw4}X$-?=qf2H>LfJJ9ACn_u4m&4<=50 zu~Av(B%d0~b8A_~=PXQ}gx5H~GU9T_PpxWu5YDw?53|q+jBe_iyYHBj&*ms?vOMPb z6fH@2MuCRWpcymz=<++`o+Q)hxI#3WeaJ4--Z1_w0 z86)MDCk=Nyze9>$s>MHlig4Y}GEfnj2`?5)*Y7S0TYAL1NO|F&vjuLR9E@x;7Fu@E zXNvjtebjuG?%iG{y@rUbu}+VJ4I;~F%9mdqwJKOVR;X8KyPlSF*Q*ICFq$A|7$Xzy#GcD~#8N z^7Z+T6{*p7fk`6c7R2~@k!>f=wMqs-eDzwd-4DCHJKB0r6M@9d>fvS{lV0D*x$<%v z-$1sy-nHSg{=FplG@eqH)Re6olUa+nGDTZu$R0uUvr3dmp@$RJF?dK6~ zE(^tyirT5VF%g@1ECdPGU7xd_)wdED_TOmiSM5e_*KU}g=UVf1U{cXpW_4SNAKgOt zA4fCa$ksy=l4hAAgFi1B%CO zlsj8|-0g0tvo4CnTid-FCc*h=;U1?8Pl(>r78A~|OW~Sk8?DQZ{IV@x%iI(G(i2n; zr{xoA9`A^!k2{>ba-J-t?2Amd%B%GzN7~CCs%^J=#v=wJ%HOtM`gDf!BOTT2>)};6 zar-*9;S}lAAM`5Y$wy!BXfM&cE43?qMyVUY#T?y8LOzf0LFKH8td{D6;+_lm!P}DH zM>Xh!F0?*4JB3JP@)Yj!eM>ALFYt}M@cOuTf^)|Xr{Lw%+);A+f!j(^=ekuwS*PNs z$Gkn%w)4%brlh|ag_E70udDJ@wf`|LGJQpTJ#IRb`3t;4C*M56Xq*sh-OBLnHjlJaHeEmZ1Wxnkhi-n^B^)V zMwHuNj&A+kiZU{ymqC3ADjJM($rr$nC;gb^`cBO1$ITCStp!-@&6tXXiISIhR)@Ar zRAUrkEXtYXE<;)ea%#@n_@=Y<5-4_3XSi~nE_9cguTjh^RAML!*zI|+S4iM`&3Wjl zeOhEeb@Pxc4Ae8jn#eV1=GK`q8c=Zd)0T69{p$C++u~>{wa=eDSs0P3Bi4#tM%B?z zu0eQuPD+TM_o-7qea7vFeCPg4d0SjL zxn{U9ckhokXA#=(hHgHY4ZEVR(i6W@kd>xV-qA6$=gwe3dX-TvZ(uU^jkvTkYo3*# z{9P77XP-|U43Q$e8lt zN?+p(KZ>#HJ({IRD5p!Do_gZMdTEUR=1sPT&lSoxmb8mvK6nJ0$Puw;6o2qCWbeL< zbJOaY@%Ja16V!v7Ar^V6s`I@9i{yCKA91^0kG6_rrj~`Tjc`;G;eik?B?;gQL7`uG zcDKOIW>Z`!;=H7+KxD%evD?)2msIH@Qtg%4b9(N(HAyRdG-y0oKKy)^T-VIm)uP(6 zD8}mic>P&=nv5?RG8*4)`TWkDWxcZ)lH+YY{G~qa&71kN%$M&(_w>+;bGYmZBWCoj zOzRajatx07xKM<~w|Gtk66J2@T?&5!ihK~ekg}Z;ITeTa(gShp3yaoJavXZL&SSo* zWMP70ocrs^b<|T<6bX%5Ws`>dEBS$>0 z#rMWiIx{YoXYU%V?XLzt3A<-_`&?5W#Uix3_-`M4Ls$@q=-_|~^?-M^EhtLj# zEq7dKU(A9?R|g+hB&-P%eIj!O$}(x8{jofF|PhK3WA!8`C|6B!i1Vx3Qw0ypO^s6 z`klFb)psKk!K|B9Y5AdN{)Mr7;&eDy1#wh?&|ATmXISM&6D==YD~hA@R0OT|-Ya5# z%VDR!G-9q_AQ9-*yR_@bk`B9!6smfA|5cdjE0*Y#j@X+ zs$1r-9%SX2S9G7NZyJqxc#pI}SGNlh#x7lOLFv=2VPo*^wFj?5f9QT%lkYoNmXniQ zx!&@=U_r1t_sR2DA@>P764z45pySeKBBV3QTM6C2i0ca?^Wx)O*bHwHhOA$^Mv#C% zFX?$lYJKu@W|c_{Pan%RokMRYV`_5D=O=puQnZ=0yD*c_O&kZ=?$^tFnur@675s}v z;OdOV6O$LJql*pB)qmbC4)MD1w4!e|>+7cYtt;VARhswUmn&mx7kqFkacn`oePhi%u?1fEh)tH}{5?~5R@nw~*4`8MURTg?MRXE%cYkBTDCGonApc}tfhh<4<044yAgA5B2MJYkoV>9H7h$g%bikaGcH6Dt)yGxF1t>oWP*^%$) z$n{?-SA*kTCcVkhneFGFD9g*kmEoac*te8Lvzg_RniCbm6v&G zgZ5xrccud96T$U;6Za;c|ioK7y7WoGUikNLK=p1QeovDxeh z*Z0k$bE%1^@_ohikZ)&L?}pPx!P(Kei;Xf2eOdQcagATY)|Tf#mbgT|GR=%&l_YNX zqMo)&)iMyMU=15ennKaDce@S~KLE=ZIX085!$MR}$!!R$*4YgO`wp%|kUa)NI$536 zZcdW0WOqD>RQ?puX2e*qAGkuBw`jiccvjE%^`?O29bY`lZP5sviPTBePbPhX;X&d7R8Tg{$4mP3aTuG4mbgNfR< zH;_xcqZiAaambezrloDIo_q$VS85dOlKZL)QAyY|I|Ei=T%b2q;?YTw?lv+*#R z)kpG|NXvC<7lZgp72FM-sEG7&p|rk=o85#Clb87;O^6gL>uTi&cZ-iXfXNeD_bW5Ot38 zoRcpR&pRpORAW5X{;}05n~x&(##sUR>|Gz3=S?<``4{|tL^siIMxmTza-z&Ft@dm+ zCeKJfGsjjtE5Kp_W)bQQ!EoJFJdSg@2^}^#E~h@+ze?h^qguyx-+rWJ;mxYsm2=PG ze4TY0v`f_6A$OCb+DU`)sh+&s98vswt}Cp9JgSH;(}s7SuQ^h(&>TcbdXtLUPX_#9 z5wrkKFIW4>Z1X|uyxa5nf?>mNNiGVbh*?BXYD$w(GY5T6SkOJv)aH8QGLqB+dX=6& z1*ynwTfuAaf$CY}ZbF>7mn-29PLnQAWVDMI!zC#pdf?YW`H$H;gNK^>pt~i9T)XJ0;q5 zF-hE^pZ8Msw+RR1sSDm+Me#pY-`+(%z7w=_$)WDDg+aICe4~Fdx1{b@c;MA*Co=;; zyq!-y2A(5*Bd51K$mWbH`-yHGG?(o_=UZINFu%7cH z&C{mRdT>?et7&Z8H!poUC#fVE(hBmfW-`5~IoY;%Er8$E;EHj#O5B9-=8o{d)=H)< zkfn`)`@H%(x&~9fuXS7=yys9)SH7F)v>dmS|i|iw-ymP3Pa=2xQgtqn`BmO@S8V< zDU}JI?Pavrs7gq65jTIq<6C_~QG;_kHGNptJR~FslI($7hkE9N(;^wKu;s#X%2M_b#wD)We04AxebPPKB-Ix$YUK z6XX{ZXV0jMiG9{Jvb<^b$-WU*79? zt<6RYxP%Cb)r{$SW926GYj3-+A3eHX01#)zbRYV1r+{$cub9RlHqm09Kc`foh zU9P))Wo?{FIdL7^iSw}Y#zl(b=z?4kKg574_rv=sxwdyyE>=iz+@oW-F$Ry*8+c#- zS)0K@r@dT_G`Dei)lU3lPI(5Zh0VWda&W<@@dFblM|vf!2p*I0QlN|A^qo zrTZk&C3db`_fOHZX}zQsUxNgQRG(D)3}#ob7ugT!YDD7R5p;~2n6f;%!v2}>7HAu~ zKwUgCwfU?;{%JOuC$XZBfbKY2P*9f3pfggfLd2TbfxzYUxPQK65uPvTt)XaNt*weO zWtr=X%ci!@j-zhGC-9@TM526CA(|It4HSRexzJWzx_{?odQ7@h{49LP`n=AqgR|e* zSc4UNaPTCp>iyjL`>p(l6kXPe#?RKD)HP9glMpr-r}r+<&Yaid09?wqY-7Bok>Fz| zk^tWCt(m`H%I{7L@zCnm`Qjt}*)No}YI&{-9Ag9bXW68^$V`=(m7SXt`1rDRqF0N5 zW-g1=ZO!k?>5C6>o(ha>kQ!CLUAXsZ6x5p#6q~|AwYqKzGqq5x^C6dHiKfE|DDE0u zSM^#E;mwAJkyqzNvR?E^&NWZ5)TYR3RJVU`>GhtlQarhjj_a;lGfj!xnH?ok$*h%H z3ep*MVVr8oqGE%YLAQIY(7P6vGpL~P5r~J__{TT?-)nAbKOTC4QhEKcsb&sRPRCRY zqrBrw4|ZF;FYwJMMz2ni*ZzkXhq8ZGudq52OcPpzGVzHgG)O7PgVbFJa><=z{i*&MzUM}L7V011|P~R2L zvOCEsASUIU&X0?}8%-%Vd)F+Gmb#YWEPaFK>z2@uC%9`!!Wq<)rOUmSwwdWT*?Wou zLP)8NT05kLELJ&3Q_-&F7B(HH?Zl1sH5}p+1l@4`Ur%qV2D*NTl*=%<&YRpR{^?D- z1484O^$O?pw>2b+RJ@-!66MSr)$kXyg8oCHJzSM1+v6aT7?jW0@l&$hG)Q$n{a8^tU>0%8!C7S=dQ!B_p3T z&3>Y~#3yGyG4|c{lL@Z2n6<&>^-%YbNs?5=vWku?sX=W&MS6i)5}j2%O={e9mxXDI zEaJu07$FkQ^2p~%8ls^&1JEFacj}YmQqrf?{^YeV~QYnjN@$z^j3 zp&Z=F$j4_<1@A?!vU)6a76tTtOH_T;6~&#W8Qw>B>h)KzuX@+?g`FGTkGNaa`3#=$ zNDgKv@2f2jWej!>xO0_Cjq74bpKX&#Nc)flpC8DO*;E0)t|CmXg7{|e(50xI@ofRo z7OwhFevu>$L*_;7H%TboDn>_zlDA%#wODPtI7(uYN82{rvj&q1m*yK7r6wPxQC8qc z?z0uI)3Si%_7e5IaH`4hO?FdNF%%oB=*(52>kU2o?Q24);OZm1^*HcZDB;A?=xg+w z@(%$fxo!5*DnT_)lJ8zEf*8Lmy3-4DHNcyCrDB+^)}5meiwnc;tzv>@>M zg*SEhZ2>r8RtfBhnFb-37z4g*bDGX6!|ygw1!W;W3kta}k)~R2Dwwpmkght_zg9SV z?oE@PJo|MBMZe;!yaotpbjy1-pX?8BuN-*G>V99aQzm1W zyQ7icD$A{%*A;Sxq*j$_3NG#xdDpMQB1+nqYc<0|;D(iE>-PF2P5YU0ie?tQZJTsM zajMjEni@Vq`b&9M=P2NzZMTwCs?>}P;4x_**=IVe!f$gH$q$9Ccj-jx+uiI{6lqJ| zymZPN|3$)ZmW2CD3PTqzqK5>#&K1O7bPQ25TMZ3i=F~2FvxdGG1-*r~r4Ah4n!O#3 zi_^jR6fpW;zHAk*_x<`C$FuJym^HpDrIYJbMd}c4-?jL@+);j&;ZpuE`o8~mdwoI zTiKaL@qI1FD+SM%eC-~}#YM|7E7j0T4wTlFeAh7=3NU#{z5!Zkw0#~l7N(`|YQIgI z>QqdpdM}fJ{#4Xh<(C>;-0|m+{K*tu)^$80WEuHxK+8O4&pki+v8m6E=BO#cLIvxEQCLjldi1wn$Cz##C^9tsHbA3YSXKmXN3 z0gQ(J*+YQ~4F9W(0=DQqS1J5W`?&0|R{wI=cF{O!pv%ogd7YpwPd1LHr9b z3wv`N%ao}-hc_efKWky6-TLq*5<&~(W3R` zv8K2Z{`=SX3f-^L?%po-@)lg!AK6a`msKPZ9MGJflrN7O%A49fw}+E0viGxm7n8XuLY3^%>Z7xF5#I!#z1`y{ zD;X&A{VNK5+v#@qp?N&PA6a2F672Z1_GK)Ll!L~yDooFe51O=qw#=~AhJ5zlnazT zw)6DQe8-7R^!SORZk(7$#8<4ZI2*36l(%|R?9UUc5T#f*Jqvxw5p^-?@15d^1l!C}KTe4~J$`zcx_-t-XURNBb*Ji)^eFOuvD7G1l3{L_`q6Hc zh0ghO!KZ50%*qiab}q zF6vt}P9pS|Jkxun*^HzzqwaJ@PA5LBxS2`X;nnfV;bi~t*IEJ7vp>2aTd7LR(jDHK zyrk}PEL*8PV^MvzJPCN!0mSYx;>#SA$m-eF7d!+9W(&zf-E2H=OB)1S9BP!RPu&%}k)9!*X+3`w8e!?Rv|SPzVO2>7uf4-;MNb?gp*Vu6^jBBE`pj~&4PRFu?| z#5hD{Wp98%ghwJI6BGhF^uZVlvaz+p1|udoCYH%)|M~&O_5)He*0VFRWrBi#&Anr( zWMPc8F{Yn}`Dgzc7|>LaQ1t)YRF$x%dhYFCrs^PdQt6T2jOawZxl-20`}xBN#oX?5%Ui$u2Tyi;>&F{V{UBN+7f^J_C1f6QHGEI zf?}L=ynq14RI~dGFs6DCWzPzcyu%NBAvawe|N%H#sTQm(~uYD}y`~Cx%OnCv5l9EbXkF{cqdyjiG(-+s~?n3o5 zX}Je+(nbvqNCisiFSf3auc@8MB<6|)6AtU#tI^BI1eHF{FG9WWZV;v;@~8YlNR4Og z-OM6-nY&Xo*;h^7v7lVybhGQ7J9`6b=NI|awP+=E*&h&dW|E%fXUXw0d_*+%#9^!k ztld9T`1&4Ef`U|km`pubkjBvcZ4GL3l6Z20aleV((sYbqM)(nm2#0Kgg;MK=`YdJp zseY)|jIcq_B!3gV+G&l4?=Ja2nkRIUGi7-HV6tqoli}Plb3F2FZ8ei->SS1Yn>FEt zl-Bq0jR;p)JgMqe9ms`S+=7?cwGV| z-;(Pn`-`S`E;3eJRxS&6X?kBx5^%p|jAvyvLmp_=V8nlI)uL*5r6g1_R;_TXQ6r8T zH4OBdQDgJdf7vt|Xwxu&O~e0B+4NA>o$N{xo$?SS;Y;*8OZ}6QR)5&^-GABiN1#pr zfTSVTQ7+CpJZ>tvA8Nk6R;n_I8?OyjF)tSCH_&st)jeHlEO2@^e;2uGsKBtZt>8&bGsJ2X|lj9BL00Wzxd z>7qr-)yS5aEkdOtVg*_?PTg~F8cIBy=gicbbr#kS@*PLCf@zQ;l*P(A% zO3j=4ERQwjiLNWC{fCp6^|$x5jSZ~-zfJ#U(;UujYgn7!>=Y>e%ckjm*>vN358{Bt z)-lG~6X_3+vuVhGZPdz&w{FT}L$w0x7@I}`Z2I>=jqT$1FPnw{Z5j@+X#~)w(IC)& zWz$2vO3^!oUOOebyqp(QKSl6FU$lg5do%d8X`Fe8XuwCS zGCn?fAIBtj!FJbbk09u(_*2c5H$t~G;^Ctuz7yZ_MjU4}=x>ecF6eq_2)I)TrMqp? z+?uF*V8qxszJ|Uc6fiPW7Tli`946w*&=~J6II+*Z&-c~gz2gRKr_{|v4^-suMhDH?iDiIa9I@E=>(Y<{6Y=@Q#8`n-U zpGMVe>ChE{{Oy%Jr>7OZEBcz8Q9An^To-Tk@LB&*Z}X6Gi}zVk8a}we#U+qP=39zS zCqkVaF*_-p6+L}WH6ji^uxh;5-m`m&PG5& zT;uom5;gP6>{}vace@y{96ZT}a|ibmh3Dz96He7QV>q~HIT6r@&e3hYI-!iAoaS3l9>wX$)(}!+>um}YwevG+LsGQgGNNPF%xfaJ6lM|hF+$Y|^PvFV57hIp6$e-<0mgb@y!*NQwvKBoIC5yfC zTsZ%3kEe5Td+eEBd_hw>`O7)4({R@5V&LW=m6w*WX?0bJCb@a(!+WI(+&-OZ$w7Bm zR8R0^vRklEUsgF6^~jQKI?S?0LG3dUEsOLED_CfdS_zlVgnBMGZ8-nt6v4DSv*b#M zYVYkFZ)0*E6kfS$^L@{EYSsa~YPJEDvFLEU=drmW+eAU^qqZ{JTuY~smD5gM(H%Fv z;*zVnwO(l_HdnG6q&Bno6o=w~W8M(zbv@P15>=xW-R6IZi>!m*Y%yGQZnN0hm!fIP zU!)puyX)oA97{8GC;pZ8Li||+JjT8<^Iac!MeFH)SJ*H+_zJoRP44jKJd!BYXy%7(61Ck z+NcFtb6b1>YrH3UKc;vvP0N!>Iw~Krw`9LjjT|_rYTMsb+NdraIQXo8u*kYR00Y*>URFf zB;db!9VpQ2AOKzmd0Zj?Ut|(@YAs%33i(y4&!VXt&l-KM%TS3klc&&^Wj?CZn0xEI;n zlKqK{3E3I~-x4qOu68Qjb5t(fPWx2!VLK=kX}<2BITF2okP_iyI@ob;Ib%p=)1_Ob z?lURnj`36_V#aaspeofUH_x;ovwGOdqUzpz4U2i9w0G>Ei!Q4*is z=-yl+B@8Exlvb)Z1%G*$(NQuzZPd5iqS}2;?(tj1i?n$Y$9czy3l58MMAT|LA75}r zd6|B-bh#QCx~JVH%cjz?0)oC~(F%N{r*)rPi?iWsswB--=t+?xvNAbEnG=u+g%i@( zb=VSZFDE?D6fZd~&346D%$irXX6nSVkefb!_)VRcTgxPUF4FE$+2Zu!o_nq#ErBy= z?^P!LiLP5(FN)&~+tm{TsrWBx&IHQUJKLr0yuQ$cxBN9hT8Gq^i4dO0dLql2oZ1^NPg>D*oRsz|^C=uW>E|;I^cGt!2>i+qM z5@Agj9_<=%$6Iyj(VI?d612y^@RvK;08*Aj_wV$#6nM;ZQtde6?TbkVZ0FR|!c^-7 zM7Oj>o4pt#4I%6>RS&l39~y0RKPB;Q$)z ze`x>vceZ*%ROPO?)UQKqSxXBUE)h#JyVO8wjm`uKTZ}8O%wo24ncH>5JAD(cH8pF*E4C{q zc=x4Z&yuJ{sUu^h;-y!C8JXpS2|I3IeB5@Yy&v~U7qhkMj}7h&CHkdKt%IhohG)+> zMaSHw$d^!ufOzmhkvd`Bmx;q@aV`z|s;9GGJwa>D?sD8Z^Dz^k}7KsI%1%U(5QnI-%-#m*}4j=JdENMQpj$@dC)?&eqSUy{4hPX3C; z$0*_T>#L7G#;(vSkgUexzq~L_cDb?IidD6vDyLGA^1xsC<&7zlcW%)0a&L?vLGaaA zxQ23F;;ddeG}$lXP4`T{e5$scCETkxwF{F(*yVC=}Sy=p%aA-=gXcY?QAyU zK_k=}1 z$#A;z0gdLK)397&xr=q!ta3K1<3hXWm#fkl}BQvo~!Q8*>g=bB9fP+|xWIHH0cg!}b?Dep+&3To2!($EZS)a#Zm| zucieGq2ZF=mfIKWX@75K1gAW>w%0a$F2i87XnpK-#`#|%c^eawPaTHjl_}CVhf!=u z7VMf{fnh>&oYoEq8R8yMWEp|ftTdCOFz`c(F2Fi6G#_mL5!O+s4q3BCH%6Oo?v^87Oryuyn9W<-(l zH@lxq*fn}K<1k&0Af`O~ELk$rHkeodvc@reGKYZedPQWw$)c|(ZT<7%DN#+_D#Y?K zCkmy{N`Q&!5}vHj%B+|CzZH_z@jgEIJtTAg5t2nQAz4%3CgZp(<^S4}-R86=V2O|y8F zg+G$GyFViA)m>|oY2x_Y0QPnA+idUJu6+MufAHtbXZ;ercQh8|_VR4%^4x4|MZTu0 zg@1uqneUl*)GHJUsoPMte6;0nYvUwPz06G;eIA!ay5Pp#S)b+rPx3|4ydF#}4R~{| zhT<8`)0tr@RwI)T^ID3VH|TE1x6^>oC-hQ;eRWvd%eHoc1_*8`MT>hVF2&tlin~kE z;skeh_d@aF6xX&;tSw&Lp*Y3i%f9D)ckgr0zW4kwdGbK=WY*04zH7}|^P3TG&QcMd z$#&=tqfxkR4x-3I~*pX7OgPj`R1X#0?Q967H$SnjjB(rlPjZ}p%NO8 z%paGN7s*&(W!y~(6E~B4h$*)iCw~2{b*fd9)QuXS(9IY;6QPvr{FG&g+QI8SrjX}- z)MT&3YxdKv!JtaCd*_}q(1eU!23c)^bxNv$i+4z!uuO)C%n5ZR-?-o#(?^Xldh9sE z*5CD<^KVA4J5GO#XMMl59NfPW3NJ)nb7ptV!1c?L zG3J6s4u0i-F0~}>{*v-i;|obZUjE=E{qv05I1V0$BIODxN~t9i`y_ERW+$ep7qXUU z7Ac%G@#P{wH5-(?p(2kN31>4q%PBjuqio%Y6shvBnQdd3OhY~N`-iP2-{4nLXH>4| z{%-Hsc}zvts(2!9w13=aJeV=IbVVss+T$p{UnwYg`uW7X6UjIr8fgDzj{0|C*2~R6 zvoAq9*{g|912>n>qcS9BK)3a(g%pYq1*HU`p> z`gW~Gy<}avBy(wM1*%i6InrJZ)D9C<#QnU1?~9`u8Mr5jQ`9DYYdkwcw2xK*y7Zwu z)N^5DyD#>1e=Z!5u}VZTw{3e zPh4NADeVWco#JkmM~?V^W_a7hShM_0Mo{^#Az%ybeUu>nATzH={zcJ^qLikatst8} zlGYvUOY@bOfCvLw*DSFQN{_gXX5^kl*3Aj8NJYu8F;~g$!h6Q`sr4Ovmjb&Tr1{Mn z>}G;kGsm083{~Q=TFQvaXUW1znk@85Sn@|pN7&}=f18U+)0OYQ9_;jb@F zuBPC7SXC67xxzC?ELL=4Ous%o>@&wp)F1-&B@Lj&e!#-t-$A`~d4YeOD1zS8a})mX z^!DMn1#uurgd+OBodbe=cN6t^`P^SO2`VNUS&}2(`{{`_PQ)13Eco89CJ5~;A#$qs|x3WhJ=raNfxxVGm(dtm-->A?5wxEs-bykXEA~f9m5a<+O1TJ zW~ECG6TWNS`lgmJ;f&PohOoGXT3nKl5z=zv+!%xV4XU{HCkrX&VkEozoX<%}^U5|Q<_TIo~QdC$&6 z6#JRTM$DiP-f2vgRg0(9aEm9ztM6-=CH5`^3K~^8;Xs^24n#Y<0)lT;`EX*jxaI;2 zkwU&DwFf4L2!!XZ?3iapi33^(p#=V52rO-w!-XdOX`~(yrZsN9UD9xiM!5$vlF`1G zBffpx5zu`eXUd^Hm>78eXzVh%1^^?F-n4JBUkbhqCZxslKE&}PJiFG?4G}L+pgPCq zf>k|I5&~~g)j1TPBnV=#_#t388GMs6(g+sW1X}fFVc`gtY0at*m|q~YAFJ;vez~9x zVfI0e?eGhceK&{JI9G|vc6eB^#ECu=vtJt83+!7?Yz(y*WPtd!f z?@J7%fdr>f-|F&<*SktmFw20n<9E%sKz(0u{i{i-boqd>g1_!U%kX?4?Uz}I@2<68spB| zXKgMoo{*XVMkb>4ia!tIHv-Hdkam1d=k3i07uL&Zl~cGU5|-nJ>8Le@ZfffMNz3 z)I(tn5+m}s;c-cY=4GG(d0fA00#jYa;Dl!K>eGA0xF^moT}|NVV=3`z!iAX@+FBz};iJ3IayN*XQ!*>8K`2o5Pq zc-|X{i6!6!pyuMcZUe@SttM`uK#_Wj0wp$7?g256rMQ;~TxLip5oE0*(nc=VZxA7G z`VvymwQ~|ShIXo{brBpoJ0DCk)oK1q<$vsQnTfxkMu z760RXJ9#VewixteMLlxpXg6B~BpLh|B??xr-$?AY!2$b#Ne49M-nBbP*mrZ&~MDJ_Iw#WIz@zFdc(L9)jl$rX3g9`7BZUY5A3@2h74=hc}8*GU9 zC@6w1vM-GdAE8YV3z0|(XEc9TIH`{!6v=f7l%AK^ z<5n)xfK+{(qCO|09-W4@sk>L$Kz(8^T|WjS8zHS;M3RV4c|PMDOf~ZP_9PVeaOGY+ z2aI{7!GBb-FtbDyR_4*23QEAo)PA|TK@&m5)c`j-NZpFaYq(JMmPbK-N$R|}#iHn6; zX#C~VG8E*bq$L%*1v@CJa~#xjW}6TxDT?%0BfE^ZP>zUu!%Y#%6ZkC1-A8;!@z2DR zm>f9_c$}Wo4DyPY-R!-_R$|`J((RP9txbUok4<<2X&Q!crz54Ld%G8*e1*pX|pA7=oYhqvyVfUOQut zbd>j~w@LtJX!`>Tyx*3 zW~~Muo_}+CLL%$P?=kr;@RaS{M(P13y#rrxxK#H8gbtkBNb?@(sYbSdJ*+{G?(aqY z3Pp~I3P-@CMtHsP&wAl|QS3g8pwuf9qLnIL)3XDVFBt-4X7A;w4v!fLglUk%1gyMR zti?u(!kRzzi0@G#>T)CZO9gaT?{XkU5R(`7P@Uj(mDoSh;5=R-MUzeg1)aQD$m&-> z_Yyy`*kw$fY;i&e(QgY-8fK9zp19s-QWrmkZ%TwF7+%x=jC>NkDyXXOKt?8u084uX z*zw+q#F4+h4m9ws*je3>=E!|Tz)yNnAl=}KN;EZM7I?TX!VkNbQ8v*b6Nol$TChFH zd;t3fu3h81%AQiV)oT_%2ALp7KAIEqki+@{Rlc%=ADh=z(Bl;_0>%f2%X^Y13vjBd zWDp5Yjm2kQNtpdNcVda(gAo?12ce3II#I}q8eyQAA>Z;%Mgdn@s@2O>Jf z_TVBxSh~{*20VD6qdgE77WEV(T+DjEAhiKkMSvYA-%rj}+ z3je+ihsf!Df`I?MXOEx(hrj;V`vQjh)AVN~*TdlzEqN_jWmIbutqhM3<-;lxPd5f( z1tlNSeQt&1TW(#`iEcxMTB|QuL$T+3k>2KDK71TaY;E}7IQyg3)GUQNy}P9Di$$4r z(9LQ;Ieeqi6UaOC*RNO>$GJK0BMAIv40B<^Uml83mSI2qp_Y&Rv7c?sbp%KjpK&}h zJ!xr};x*Yxnh9LBu`RJ44fh^ilLWssTkyP9bTI40!9fbI%oW1{fq`OGrdB4CPZJ?t z4)xA5yBw#oHaYWV6)8Q`wO?3Govq4C98FxErxJB?i0dN|VFL9wQoMOrX{J zd1foz;f%tGxda;2a zWYpMPGwt_i62YcH-ZnH~(dQ&s--)?E47^CBD3ipyYnQW0{@BNXPn(=)ZQcn%&*vdqyEBv}MIpA_{j z6s2UqK|viyMEphUac#GNJ7>!1N`P{K%D_OtcMR1fgY^aZ1O>xCyy~(lgaqQl2BxB- zqy4iXBkz(x(8UmT$RtonJl)AjgF}O0Py*42Nhpp9_Qe`(FsT_t0|JB~IuIft@1u|c z1@?KNP|$A0@_-r$YC?`41*nxmut16^0s4hYr~-cW>Vgw_kiaJ2AaiOI;jlhBBP`gkEArC15Z1#v`DumlEJF-HXkR zl^}$Ta$*mH!iN;)l@&HbwL6m%+W;`5dgQJ3f>_~C?yzq2@x|g4#Wpa z#5Xf>*_>+gP&A4VrGnj1pxba}a^d2%LX*HYoHh_r(dXz`lbEriD1#PA!*wtiw6MFd z&jjG83Mw?}9Yb6|B|+E(k|0E8fVc=gS;y8P0$pYJkUlXp^b%83_4*+qA`UW)u@EGp zf`YnCe*<on;XH1&KVr^TNbb;am#| z0qiiT;uIQ*nyY)maeh%@WC};exe0XD8*6n5HC8DX;7hsc0sx~SuLlQ_rm;hEqWb~o zlQ;x8;Rr{-V1zd)KwAmQgnVjK0#alFlyJagOrb7#}tf@JV&g1WnwCNKdDMt zz;PRl(vJfIfK}mtVxSBFG2nqD5Z@+9BUnaN`Ubfd23h+<%mLFd;nyLsKFZ0dx1nKV zaTE{;1S=62}`f}xv)~c>+1#ZV-ke})?<+nXI~`s zHZw4|827egL#jY7K}W&yGv&Gv(q3OEBo@#Q5Wqq~JkwP!=zd(}WxaMh$>o zPx)b{a8UsRh@Y#+PlpF1T=iNs07RlblK~&GQ-;X5D3E-gV0`Ey2>Wgzq+o&f67X2~ z9EwYTQi01s^~@y!5oPlV2XYdRo}xNn0)T)6G`DdebXUM-3gEZ}6d51vf(?}DOAKnZ znVS;AO({SaH{yT>VTnPr=BKjp5kp9S5Q7ghJBVWW_D49N-_`WQS8;l~fN6 z3WY~{gKi_xJEyUr3EsXMo#7 zD|Y<^R8>GkA^;!&K!CeAJ3Y6?Z|h%?0Dw$P0009(3h;Dfck_01H#K83*V04-AU@;c zu&#Z^ZSCISjQ{v**!(&TgEA3c3J}7ZWrsx8j~FJcPRWf!^$8^zIs3=G zDU?gOR1?`b9odISk|-!k9-UC12z{I2iAie6hRc0wHjg-yf+P`c%1B zg7A7edIp_9rYhN5awZzkjzTNpewxuf|=?~KfSF1 z4FpVvrP7J#P^v_!iW^4i={h$pxb32!C9X<(Uiw|DLOJG*evRp5Zsj8$ z9cQm9cPrRY&oMG$w=8Oi8F>S-%WBfktio-QI@){;*A$~FCEUkMlmk=|R z=$YPTNerpEo65%~L(T0rkd&q;UOO=yjB^>~VbyND_V|*gUdQG&0wGj3{p=DJY???# zJn%DV08s;3wiY|d%VC*;Nf6Dg!-OvjNe9s>rkWBV-Xk;p8`%tbUGqh?+vgkqM)}w- z^Mop2OjP|2;k|QKUtwNFRc|a*u@PV4n+3(&q^d8v+TWpdzdC9R2bANIu4?2rwR}&Xq)yc)i}iC~Qt&H* zqmK(;@uvbB8tyd-#+2i33n)B0{39%YauX&&CtZ2{DWYED85$mPm#X6%r z(TqtVSm(94$xs8H5{oc25vj?Q*n^pCBYNohb=D0N={3iBTYbg{&;D6a9hHXk?vVEb z3=lB}Ac~k9IRK{lu zF>CG!&SA^kTSeuwj4x9QHROUNeW)u+!rECcX32g?@nY#!*wn1m`2EV)kF5L}!5p#+ zL=m4M#J<{FId@l3D^^%DmBWai_=@@}%Kv&KBivI-spcuK4ohf6k56EMNhHAWTEUdJ zIbp^-bvL8QcEcFK5hmW?W!r+5OUlsAY4=F_=0szp2@;?>P=KoT}G|f?`MJP@u>L(G06jFzQG_zS*U~5GZ0?>|f zuSgEoLJa$$O{5m3Da#afcWIdHBcMz{3@rAvwz7^ur*~;lPA~KdGkue&L}5bI3A?%R z!_Du(+#!bMuoK5@ts}TvU^8$Tyh?LHNjbURO?~&GkDz$*nAaC;S< zk`XQFxLMAO@tpE*Qt;K9++eJlfZ6L&rNq3sa%kxD--9vl0cwOCOo@yj?LsU^js)fq z62)P#LuL>}?0F>=$QCs3ZI<;-mfy43iLHmb!)aEe)e;@SYN03CDq4llK=U&jQ*)hz9EcFdy|1{C47q1*avgE`^i*uAs2-hw7- z*+0>x4*(&IG|AvKl$Q(mAluhRKiX(N9PuL6-m!yi({@;4msuyQ?sVr!=x4s7;tbSB z@~@P6QC9tjK$=JFYnKk40u|#gkE0~!T%!vWfNj+-R-c+=oL){&lec{41Mi0<#`37! zd{G)EP-J=S9C1acQ;~7<{@q5H3T8Hj^Qz1K7lfaWf}guS&0r;Ed<7Yx%cijuBD(Tz zrb{JWsH(oSY*I>PCh19(kNXlEepTr-r@$DZu0B^SJ29;xOC!-}SfY7yb8yM+a+SuT zB1q)Q7pnOvy-;45*7nX?z3OY(y(_qd z36QQ#MN^db5YA^zRWAq25Ord#m-YMjWdvMF1Pg#7XaEXdDbdtdzfk?0AKh-YmDQ`A zdVgMG^Nxov({%JX|M$SC)ARCjm*WH}#r%7bh*NS6m*4)s**NTz53?@m2WmjaS4E$d z)o6rX3EyJ=32HS(J3W?!W!6z30AK)j_4t2v^TzI$Zth%crf!b^1#X`~=-;{fuoN|w z5>bM%0;)BUrBWKh6ckgW=(xMd1ty0%ZF`T|uXH(;g*@sVrqVi356jO&v53-8t;WYj z_&M7RY7nhb!9iWs{DzNfj2pF5^Bq@6@lru^gFjnC{P6&9PzImR@mMhW%e$eZ?DUwB zbXc8UWFc-et%kEjzw*(fTdV{$`&)6L~1gW;xUq zJ^wJ5qVWcDa8KA%p~;eJT&Y@-J;s?D&-XFRFz_5u>(8Ld{1xB!k>XEWBxrEyC3A-l zYR;lHf@Cj2vu??Vq3C6Jm$e;iPH{bf~>ZISjxQgjFC{m?2n zo+f^d`SxBqx`HRcmwl(#4N{3pb!PCcVjpkR6D+R3F7Y~KF>z~X<-z41aU3Qmh9G26 znD;x($620qtN=p%18Mo`k5MAgu zCbtc%v~MPpk#Nq?D{QCq>FWDV`RWSoPYW;N$@Ch&sAgZmk?#tZbF_aT|GzB!M|f*+ zH2HV-)o3o-Es7HO)rvm3sDhe%8InP?HH*SpNFscUuIx>fxY14VMAd2Y3g)e!d%Sd7 z(;RQaqu}T3S?!GF>fM1;EU46xj-RQ#S+k%}+NiG7^Uk%%ER3wnh~&@u@yoQIj}UDH znNjdVMsd6308QpnxJdEdwKYzhbMbNO+B-&r4(An{PhV%{2vBA>_A)4Q`_nr7-vEUq zP8`p&#p2I`Ya?8YPry*vNN_n$3c(Ra)ER%Fv5e1QOEd-t38U- z3<9x^d3bo3^`L8sBbi`_ZxuCcl`P|^=^wL4v7sU77sL(Ws)UEHTVJ?ap8%ISRBhdu zMzmTTGFqi`mb!FbRo49+%bO)Vt04@=?i1*dU*RTZJ~R!M9-xqnF&RRYFFaV-x=!<9 zeD)fXwn(6yq0hThb*cPRKI^c1+a_k6K+(%Te<4AK*d@P2vj=G@wL!y^=8W<O@NCOPEo+5D=C z;Jk2#H}Idxf&Mo+{ui+%i)ug*h2kLJi9W8u((!nw&Y@jlU17gm=l6w@MqdPU_t}MK zp~LV@33G^c}pPRPey%U;66o0l)1JzK*l)*0B5=B5NfH zV)R1^!ghY^EcLaQV%HGuzj)y!MT+zWL?GzS*wweVTQy!;o(sfsu`N*EfXiRe_B>r zx4dy#UHX`x#e4jE>-YI}Q<&u695l$&tqan65Ccq`s*W#y1WcHx(tPd@(`&DtFkAGj z7N7rg=@BS@kNPL2|CpH6tJ&EixUt*thW+Qn7@JyH{HM858h?cy425SGpW!_YmD_7!frwe%G&r%`ZVrQfi~aq>m@I z7w({;w-k~y04>s&j$~0n$HFi-yV_)V2&Ln1a>Op8L7K(m4kF!%nLQL3T<-WS6B~Mi z+lbqk^|R-8T9^Ep@iHbo%GwoPsLz@6^jsvkxAMf?v%BJ;B`A4{(}#!wt1Jxh|S&pSK)B z!BT~~?#0^a>QTzs$PZWQ$+({{#kQ#}&!YTh+F#a?(}+v_#{IfgURl*4kTJ&?;&Qcf z=X$!a`1Pmj>DA6x=j#i8$+}vTwb0Yoi62k|tbIi}FY57qM6oUUQZ%f79elxewkv8L z#&3GQwu*==^U%ZFer#%_(>u|ihKG40u`*V;*2L^iotO?PV5DZ0wFs4#PCVnP`C-5< zb!v;#0Y+#1`7zCdev#n!`DgN!%MfAYvW2ZdfxE6z&lN{aU{hYX@7t98 z_V>w!OwZmYr!(EWw@oJ$-a4MS?g3~53=u-Uk@^%&qWXOsn-?^|KdJ#sTSsu z<~iswA0y*epeW#g`!-973!-pdIX-RzHLAgsAD1rFyKJnCAw0DCY)0af(w!NZb;%df zTKDD<# zQR#ieC=XiZdkiEg=Y9AvNp1vT28Lt-YOi9Q8@Ar2JS4x=eUOmYmQuvUM;(= zuc46|@8Cnv$cJqCbq8+tAkx+)R|AbPYd6Tbftj%*DPGp9RQe^8&_x~>F#P}*|9aS` zhM=KeS9Ogy>(MOkn+SJAY#+XCgCe*`<uBZ~O zbj*yMs1z(!0;r>I^KT{@AZGmz8 z+fI$M^8n_hbaLdh%sqJ5uHYAW%Ivow))=CNiriAMFeuFX@Y>5`;I+)KXCni(kbH^= zj6vnRX)7^C{C)N_Hst!UCX~cM90Wn}W;GtpK9ZD1-?z{#7V*WYP1Lg@lvB8;)_Pt(7MyBo&*5>i+&hFGjA>I?`+c+} z_oV#P$l5H6N^d&pS;hRTV8@R8*=#n)YBUcX^)1s)?kbksmpREKbclwUBw&;hrVP*7%x#3*6m`Bqug1{cQZNP+foTzL5-vDi9v9 zk^EEhyj?7fEo|M~ZJo^BZJnKrEi4_K|L+84n&vSax;PI;l}`f=6zb?ywhFYWqlv@2 zsKT&e9C7jYxz`=K3ct(*zrMG9610XtALf8CgK) zQ&=)aJagLSDT?%G(D1-14OzF+$g#n&i{us7_6%+7e22_)&nY>Hlyw%tn;;b4yo*&&G& zOSxV;cCBoxp=s20GG8e*8BVJJBTQAe+6TE-WI-E7EHZV*+GY%j=4rLE(^#3lFO}#% zD@HjH9%=q*8If7nB8AZ(u0H>}*@8J#_I+AnHK~wBgJBR?Zt{xd5bpBx(J=XF>^xn@ z56X#2evbZ=oH%&3>&ow5YBp8P&P6@B50`cl}-?`^3_NeE8`>cg@`59)<2 zfaDj;;BKmg%T(Dl-hQc*I_cLSZy^`@;qP|n&(^}sTi?qw=i-;Hwi%o`w>#P4s8H^P6Q+{4Mm)YZ+>^}m+n9RDejk&0Eq2o}W& zpFn?%AYLfhJIqcNj}XPq4+iZM>9gUbMSqME>EVt+u|mne8qf<$(+b!5_SvZF(IJ&b zDDid=dsPfc>;*a_rZ+;q#fvX|Yek!dBynbky+X5Su_T!LGj0bw16+$jsQPy%m4?bQ z=5lD#oY7%B>w#l}*u*LuEhnBbKa+Bl@RTpK3-qu=}&j$HEGbAHzeMv@Luk?#_D z&U{+;?Ua$0;EMaMMlTE3>~d|K)!&|5bvD{Qwj^G=a7$2--H6 zW8G5OSmK$M_~K)m^I;Jhqp~O-)is@9%s9p`yM1-yo19Fn`Y_kO;@;Tkb#CnuHs(E_uUAUM!v+eILW)qE41nU0^n<(i!e;Y<=pH7+=8H#n z@?}v%Fs;r||C_g{TAYWFjz{$OrciJUF>zyClD5)415mdnTXI$THU3CpQW2ggg!_dU zTH#COck=a7Y8H=IhG{R1DDBCVd!vz#L~di2UM-jaFYz+Z*Nj(G?KCjjZO5ir{1N^f zt3Q1AjfG6fH6j48iw*!_{Szwgwhp%Lww7*x5y4+1|5l~x(sqnll*V~n3c16^H%9n? z+p@8owAvJwej82IRMsV0#AwC(>ovx7?Y!aqPWs((-n`-GWVVcube@9ssm@muLY%&h zXq^T-3Ke-QWhqO_jTeBrcf9qP?6ubCyp2N{C$~QBZF)v4qMzqs%otU7uR23NAD*qt zzpt)#!!p*(;B3qxS^>wZi?pP<-hHwuC6RVB{|?R88;v`7F0*qKGqp9eHROPz98wjB zz>2i#r+@63N#W47V!uI&W?L!^Rov<`ZyX_Cnv2*mkR9qHBt5KL*vAXF54ijpK|wj6 zziLwtv8vK4uZm`V3NZ*{Q}7=&ruwWkh9_Rxz|1%~LqZavd}9HYbDexiF~RYfke&6a zooky{#?~7(uBlK<07-N^kr&mK_<-+9x^Scg3oRdWzN`^(6Jgvy5IEO#Dt?$@=4J96^tR&@I5Ff0s!)!2zcf z6iE;D)KQ(_vroo=D1Z1cCm@iqh2}5BUQmYoS%xyu&K|#rqb3~oaCfv~R7niIPAu@u zM$U!Xg#7!l)cA1&mT4~n!s+*LiE_6k>Z+;KBBF<{)D7F&5lCXyagqh)YZ@=f#`cAr ztBGaeXR$Fj*4kjyhN%e0N`1e5kDOJafA{mwK<$x9 zMYmZEkZ#bJSZ*O&zZ$x~{Y9bl#PdF*+fV!>-yx0S?a(ZrWiN>_lI3;e@Gs!*{axLF z2c+u*#SezC{5$L4QJX2%0s1SBPCbS_PbZ`A6*eb~Mi@rA2k&k#OJ1P);@)G~Bb1Mj4~-j7Y3y^s&T8bNGOpit^#tklW4NQ@ItPU<=M8M+oXptRH&8&O6X zVjMgE)A{Jq?O@%9_+j30{&|c3`Cg?Zed#_CA$qw+lILD?QHK`mMF&mm!4-2RPK>oH zwfIwOFNoOegl|v>Md9f$i^xCpgLPnQixnPF1;7`P|E3>*#{Yk#A8{K0sA)Vu5n;(C zr3p#IpS1rsqU{g~mrkdoK3ETwGi_^&O0+3;Np zp547$`5gaCLpIqWW10Sr>p?c6UF5psGtwDJfS;aUz$1FUxI-00lO)x%MimqBR;rPZ zh-$v2qQd3}FQ#D`tT4UH5r$O4(W|wU(BTEnWjA_Wlq(`0F>{7egquoY<6&b8D{UPl zjNFTLy-+f-?ajc3Zlx zJ)4Cyj=UiiBK*1zIeI>&X5oN1qfS8x)lHk54FM7{^FEu92Ch}-(WcI%T=F<;=OB4> z^#<4Cvy%#uclx!%jyJUM)fomX%%n&Ne7Ht%<$flQR?3kwLb6 zXpUO?Qf~(#=F4^|z2)2iR(DqE1+h;h8(rCzlAS^_OVs)Ds1WQ!m~THfQjT;!5b5zPAt7HpLAx74wulBmHM` z3kAB^so|>^wW%#O2H>i0-r=5mJ?XgxhQX1q`Lq!X(J6yuZD)U>+#lf$&(Dt^!r<0t z!P`GGRGyCi71#ae>|tyJdI%H}x&!i#2(fC)F72Ck2*%RWk8q;p%Bp_xHR1YNNq}sH zY^4D|6ocsQtTxV&M8Ba}TOGn7`48&f*uXtr68%q8hsZLkol#=Gmc>RY6 zi?8C9u*w6JFS6+eUloY}@5VQ!#3A&2AHr`jbJ%Jkr3^A? zVp6_uYG_D9tgKB`Mr>A9rVsSO$)aqPWbIk831FLq1d^r82ytN&h2`gyXKo_^{zTay zJqy&I_?-gpl`CA{{%6nrf98|*?|Y`93V;EunUN9Mu7V0}(k_B^nUN(BsqvAOp*@g6 zUXFUMkh5=-*HXix-M~*c3@b>(5t%v`(R9w?!z!UwsJN6lFh6BvhRJW=G=da@tC8hg z-^?#8h;3q469h{HlTw}GBtWp_5+JV``8wL(G68;8mK54ol$eBW(w2z*qOC|!gdJ@T zZoQ&rMxF&t;FvHW{>8RGFhsH>A}tGNkLkbJ_8->`fwldC*i|n%6rtGVH`XgWk zFN*Y>jjU6+148Ic=y#Cl{R^+f$FD{)Wba;Szx%>W=*$O9&J zegRXcY$Xl5xvptsK&=6I_0u`@#M%lJ%(B@nFQgt#9hxIY$+~NILLQ^Lwd`Dkf8jbg z+EuC1*iwI>d1L=ZUy~eMQRDjX)+@?Bl|IRKQaT_CW86FSySY@-&yw!V_Qc~0Bk2>W zplMHviyq;(^CQOsM>;u^EZB{f9#qpG%Jr&oqIvuuBDAMZVs=ar2On!9sd^suA59swp@-w5VvOqlI}AK_HS9qjJR(j6^Dt?EVa6h{vv6A zfX(*Z_*fMjY)0@&`B$)Uu>A)bD5)sH)6U>mqjkG5YN~@1M6VpP7sT9=XkHw{7$o6O zEAiU8jTXMg&Hm0Uj&~7ms-8}}Jy&a&M=wswzy=3j5U6Q1({MhjAY?N-_7a7;$VTir zlu`xUj!SB$r@!!)r=9Mfj{d#kd9F!WBSAqTF?3HCNrTc3`_^7db3W5+8MtXE6v9;a zvV7M%qP+SYmJ*}dhBywggl3?mUODg0g!mD1OPTyP_s){P)Cd2t`F{4eiWqM10ouRY z{2vImmDb=C0>ufpejEM#<%`Y6IJrc;C>r(ev~jWmTF*L~?4`;({f{CsbxI{!$S8@# zA3c6Mue{p;tiG8eC|v(pbesEdpN}D0#wr=tUEgB2*7xD80n}g5vJz-bTmk$3FE#lj zV}$`I!BBzzt{2~Azma@Kxs+aCL<5#KM7aZo9vsTOU$3BmZ};$#ea9)|J=9 zS0z#kF*VEGtAuC;DQdba(*!8jszFAZeJB8Xr+0!iy3!J5?? z`M$DQoL|ooU=9+AI2`WRs!B22pMw^44r$DOR<+|>oj*%_ePTSY$v&`3?_Koy()H%& z$r9n$T@UZv+;xbst|6~}IUi&>yH=dK(5TJvJF9T5PL4W-lNAQi#IK!D3FpOMq5Zo7 z7tP9nKPWYR?^Cz4)jiPiJ); z86!_W@$eVn{0+zKU?OsQ1e~YO|7J}8KTp~J-YNXA?h09km{HDRG4f8(6NlCu|UH8P_OP1 zcLIiGJK2~Zajnc{;(q~>*qfql05G|@g5Cs4i_K9MzI%sS-rn{Xd;Z{{pr}y`0B#G% zzj5#-+kfET&(v4&@*bRn=gdwnsmXQa+=Y}{nl23cg^?jKwdzkIZ!^ldi9}quo@IA` z-OAqSvIp9vh9Qq{Z{1Gz7$guOWsvwNugKa9a~Tx~cBogtFGzXK+cBK#u$ z+l3W|{AH&s>*jzoL_m-F<|@bks>YK+of#T~f??!Q%R(z^?v z1-9J8vOZzxcfarAYb**-kEMCiLI~Y4C3zmGi&TP5%qoJd*TP`bBZV3T*oW`C!5}HuCJUrBT=n zgC_Nf(~@x{jnh(5maQ!q{XJejeV}3gz40ve9Yt$LFkglcz+nWtE z`BT?)M+zTSXfht_vj;^-Yv^ut@#?RoIC0aoMo|>_Lp4_m?1@qav;u{Oc@Af?FhI{aJFx)UC_ehAs1wFz=FoA8@csdrhNy)~p-us8!virGm+pBT0H?D@h^ByDTjKPa|C^H_GeJVD+ z%I}b4myRKWkkpfQn)mAv|578>&o*bt)H{_hIev5GEL4fzmS3hTeN%mxOFZ>kf_8zF zoF|SuZg`zCA@`%b6K0mcOVso(fwv+Cz%=XgC*P!OmJE-r97#J@siFSelL~O<(0jIL zsw!`%N6IFqh4U|;@TafFd8Eh&Z*4hul=`lcX>{y*5%nz7H%)1r%hQxoa1viHtvEBs zZ`^T4KmHGaknv?dXMp3{{@(dGv&(=I1M%;>3$}6^ zKliRg^p~0+B}q!-_b0C?6ZEWKc9?}O+7>{fBWW}7i;{+ zwqmyC5uIUb;{0Jzo+xG~f%gpCj|D4UlbmOth++r}tI#IVK>NVe4J68Okc;1mH)@dg z_K@ZIzDTx?{{=hF3kKw)j9^lFOyO7w6u!&^i8%ZS$S`bbS6v65+)4Mp2uTgRF0}x!OM&s825O*DPB?h< zwv5xllYKL?u`de`N}aOR&7?K!O9r<_0(%;jD8-+h!C&JCCS+@`3&j}?4t(ZySPVRWpXZrgHI=!?KlCR}xi z2>BHv`V?m6DlKGz;8mYJl^L9=HU^>V7>kd2T|=5>F>Jg86w+vuKFNqMLSM+(|7oqN zMZDa1N$UsDkA{>jeE>fCjnj7*t`0@bta z*1O%L@t>A_tc|TFZPZjWeKL-a59}5R8R>KhzTVX;6h=#Fzj2Q^db`5)g|TALYZ>;v z_4Rv04K~O`xParX##N-BYizmh8!0aS0oW^S9oR9JzbG`%g{YTnJ0=9@4!pCerNWorWVh-2=+ZEi4=zk zt9cpSSG2-;+nEXE5qD4If_mG+BnDb^YY_^)!aETHt{uM)Lq8#CSU=U?rfS}Weh=bY zU~=#AHSfhRW?El!BFFlFrJZ*?m){q_KUVe%B^8koB6}4=_Ff^$&d6R_(I*+%S(!;G ztFk4O6|$9NL^3K3gfc>Y_X+tt^v%cXr`O}g+&NFjmdsw%d(ZY<;^2G@ZZ`wXmmlKdY01QImy~{t zvqooFnMl2PA1|mg9aeCXX$fUggHonku4lD62>wZMLa^Bvw@I0?n$>pT2ubvdj*>=1 zT;B15qy1_&3X)w6ug@v-*M|t4>>QkY9`43kl<%eYVZ6m_@qCYEIft7$eq;Xq;D|?` z9Ykh_D*DOJ&z!)bxJDM|vB!~7Dri^;DX}1ieG%^_@{Sb$9;0(9Ugnt> z#Wd(oJb1ZlGs0x(X@=|01m_uAO1LYfa zk}Ie!%?_E9JH!p9Y3}#5A;96V{p2=#E-C@^iSo*4T*U3V*E7i`6!Xo4tt4+qUXhQ= zB3C^T)3fp;L*WRM&eHYfy+s+VWc=oj+nz3hTh8Tv)DjN1R1PQ_v3(b>z<%T;HTC- zGz>TB9`$Ca);H;Hd^~u6b~J?|zMia90Mpv{DRFAR#Jx^~ut%DK6it|A3(R&1!Ct0n z<%%d~6=fxXC%N!AptY`vjz4uh3d_t((z+?YM| zpMv7Z zGIVmB?AM6ZN`Lxd{>z#6AiwGrJ8xetY{N&IDHag#r1B z`ewVPvyB>NOxcYCwO!6{z*TtK_qDnneH~JWk^HgbdCOBw|K=iMQs19_sz&vWf&i@^ z9ZmvsMd?!1LzBK%5sPo7L9`QeL!gQFS9n~WF6W)aE&@s?-xCWu!>SF$xW;%##;2cm z5Cx2vGTG~a{+ zm%c=@dxguu-BSB`y%lEp^`9pR`!w!i_{-T8OUL%c@4il`Oho8A=%~bbG?PQJKvdZI zL-Ia-D+#Z!`gsvPPH~Q!clBQNVyP2%@DG%BP1ybL>ObSz{*n)G-$0>|-wR{H@$*vZ z!p9w+3n_aPUOyJcLrv1q(N=P>DS9z2h325;%I-2otX+rnS;{;1CX{84 z5GlTQ67BTCtZa2B3z$5mp(0jjd!$pT@zV9HMk6Z6ox{f-rX}nhmuQPtjHjw69K^e4 zY!`{)e}nM{Mp&G!duwiU%y{_7X+-|10=9ff4~+5Du`guwvVvZipZY$g=W5S|D*PyR zT$U;pomKFWWa}!ej5LV3F2&!h-sN;f*IVLk!!<8qbr09iVvZsv0)-yLDT%(?X+n1b zSJEeTYiJq>)p-pHvS*aac9DlfeV+$+J+g$b6F)HUmoz&rbB~gMWzWp@qwU@KB&O`e0pOLOvsthk;3)TNVPZ6<|(CS1m6=D%aShR!K(a#ROe#92i{Jt z=lP|-C93m?cwAPdR;;e@J<8KDg=N#C%TXq?9KrupHA$sgti!xBF)GFG2vOP@*4|1x zspMRRcfn5jN3+V7F4bgoWX9rOnP$_$*(>93=0~6KK8&QX9@{K${Mc=;X_Y&S{8?e; zyB>^3J-l@{CGcfare_M?0~?B0nFkU{uAd{*=%}AoX}9DnOJ4qU3_cxBQn@*+f!q;5 zzcqJkHyw5x+9yHN;m2>Rc73$b&n;|bWIr>$KBb*;G|V#HEpe8NRj)WhSK1@2;4(s0NN>9SLvsAgU?vNjH2uu)IX$Cxg$$I#Ll78`Q%6>vb@1s)@Rb zQ>gYqon`Yf*TJG;gU+W12t-A82@9WF;g1TwvMIW@jDYPA|v|ADIJ5^s`feFvXA5?jb5F7Ze%ZSofc&6$WcL7j2%B8 z`uP}7lTNFgsod+3^UU|#lr)YvBBNYpJd3Rv7oJ%jxb2@Q`QonS8O0eTe9nDB@`^lT zO0u69%g&k16Hv?&W=HSV`Z18fS9|)50yB-Ux}p}z?y#?)UiMufWU&sh=6yyfJ=K~^ ztE_R#!a9M5KZvs2?eqMp;*nI!%y#CNL#2Ems7o4kio7p%8gKc@>+t|^2?oTSl8i%Xs^`94ttCRFN1s1(8 zektTqBU(e6`J{&a%>%upYd7w{__g0)f45f&=Z~MpPi&^UQ!D%z4cso422Khu{k%SI z{Akc3@C0t7A}Q;EUzXnT#RDFaIE8$oUjqu0e4lep#pdm0AL$annVg~bt#v(|@#fBP zq8lR0k1o8sKc*{NXhK9MZo4}&+ag=-tby>47oT4_cqqO(KD4}R!!e;rjro&Ed_71e z+TeT~KB)<8KdDu#jBt^OKGIk*PM<|E5SQQ&+|?irDqzqc%fu;TIel)}KZx&Bz1_Q+ z1jpThC5QL}pP5#A%)AZl{8W1=v_Xw?h5Bym^BbO@Vyl+v4#nez_qLll1~lhWhwbyz zYSb{N;T+WA8go7VRDE(+(RKe%uHzQ{!l^1!)MK%@QWF@Hi0}06loju#iKgw(v2iUB zO#8;neJ5ydvV14!=2)IN9p61VGI1jKj6k)~F_Ebw)bHD@nGSr;Af3^V@3>%j;dW2S z2i{BM1=TmSY-E@AizVD!h~^_mkG-0Cq{2B_BJ9iq;)gRfeo1*D`-p;X37mag8=t*P zU+Y9>W=Ypn)l{4 zkLn2Tj~`~jm>4g7JVwhcBIo_S^C=!lWv0_5y5ht4bH-LK=-IS2NQrx<(8%!!l@esh z2DZ8LGj~6nRkil+?0s+lU1}wWPVw*qTB1FIg;`JbQha$9@apk3|GthN<$W{kGZ@GB zt6#-^GJ*1T0W`N9h;-7N0(($0AXja6hiw*A=GRs2!Q4{UKB76_VVY%1APl)8*cxdnY^ykbE9*jyQd~E}LxiWnM zO(hI}Q~c%#nLK$ZJ!`F+*N>+_17v%PV4uR>g$^GZ=jrm8VA&t{u`Mq8em*;vY*mO% zZ|w>c(CyDre}7EkTz}*BXgg8ThmTV!g{-MUmE@_VO(x4Zt~x*Kqcs7q8{fDv$JzVc zbEr3m>Rwr|)Vbsp#X~OSqPZELQ=OlT8yvW%L`|W`LgaJ%*x}%SobWsM#XLOSX@?KZ zr(2L11r!?U#St%#Zd&j(j2ykl1gthqv(<9jW%&3;Fe{UtY#(L!9wU!z$S;)FlI)0+ z%L=~55t~ix$=V(KtMV0hzOf|UaZD`X%d%~=H(A=Ag?@T4C{I0i^QT{X`P8IN&1J$y z>&|)AhNuSQHQznM*CM#PS-A6y9DSZ%J2OVQXLz#r*H2l)eYu9bw*HqoOWr1e7Z=Af z?IkXHp38AfotwE@Ts{ypB-*Wq^_l2|KrNQVH=>l6i`r?DH6qLEDotPF;@=T;J0gdJ zuM!v9h~-_O&>EE1;yg^XE4E4ulT?Yh(>OLquWLax9lPX;whG-F56*}m;>M>ZcmlOs zvQ51Gy6#Ue>E0dh586L+^ioP#G2>WT$e5G!cd{3fEGJl@GZ!}aj=t}3v}oEmT5Zy!7D$Ga5J-knf+hw%QJKDW2_c-h9v z)y!?jh_MqEF7fQQ$vPGJy(4$!+U+ymdy8A9=DuACbnBdRx@Oc?t$VDFXRxU7MzQNR zoSd40;}N}z=S240WP6{^Zgcpy{hJ|;z`(f7qG#t46^}BWeHVYqQRJG0v;pam9Z5BP z;K{e3EA;+6S%5>DL%PbH90vm2i!|4}D94M`!t1-~soI?#a&Xb zc=Wtmm|pdGd6t$SVd>+6c8;Fmtcrl6oC6QkYnllQ8VWe%kZR9OeM!63zpBv6aUqQz@c6IhV;jtLw!99O4|r>WyxaTZC+b8;RLr!+y2@H7v6yLal5pYp(|K# z4msPhOau-}vffvljoef6h`zz;@cCw$sFc~k$#e25ugdbsFv~>dW|DJ~rSse~38>$Q z2V8JI$UDF(D>rhWfKlI&S@4Dx$tUIfGL8aDnl>3u{{G6@yiy_YkXz;&-=%6p#~5As z<3(}#B}21JXIG^Npp(8!%?LY2XVrd&M0k>=`3>bR0rv<(T=#YR%9=whmT3_ z=QE0F2(*~Yzj{GrrLRUZ|E^#_P=6}NaMR&wviw<#kmsT%2N_QPvLU|^q3a*ilFDK7 zo?I_TZa^3_?+}mh;w#W=kHhnM&$z=_z`ZN#EGsqI4X;-V!gvqI-Pi${r`#SR-4yCjBd1@#lOT`OmPP zF=S>hE1=iT8gOw5ln_yx6uQaA@!0j@tvw2dpJZ53W)L?Hl`^;wjLRJm-lY-i)6L{4 z))*?6qkwzg&C^8ykMR=w#C$!yJ1eNFi{A5+5{FDt1ofAnU%n3WaV zenixPzct;PuxpCn=0}oikELi)kwl?vpwlADDPD_bY4q&4ADr@OI{Utj`YM>}nG?Ts zJsNYxX!7ARl1cvW!6R`bG%~M=`sF`ZSa^qwa#<4jlJ$(7Dvpp9Nt1Q1im^|PF}dqT zbLNCq4QcV^6%IRv$u_z|9@{aA()y%z5>zuQK-z<4SkjG32g2 zR3}a@B6Rw7Bgd0w?i*co3*s9^3p7hnywcM^a|X& zJ#{wI@m{&StzOtO!ZZPjE^Cd$ImC_$8ttz#Y)F~Z>*$X3O-qoP8~EiXu~4f{jPTUh zUd|2t^6uFWnu5#+mf93ijmwSgp@pvMOOLz_@MjE%683(He-;*D$eBXjDxtPQhpqQz z(cNRNWPxv#X|gGvPhrHgq#Bo0sBHEbZ?&Ja>NnYO}7)mo<2ge>KZwZrOj%`&6W{Lt;=Xvj@r9&Om-f9!#zsWsLTqx|&DTOX9& zS7?u~>8sr9A0P=4aBiOR1h+eS8ShgL8RnwK{pLKwidiTdTaiI^UcyWdTW=SYn{lt- zyB4mDgP*H>mX-NFM_U$~r%zpUCV5i?cl=W)UOH3$Ezn^eEIRMr1R!$H-_)? z^R5G`Kix(48P9MZ*9Gsq2hipQ@ZF(t%5&B^I6g9E`62s@5ix<;)SlA)3dG=cAQNAe zJYi`Iuti1O+*KUYT-~EksY`w-zaTw;Nim`R5brvn{*7;W`YI|f!v2^@w`=S}bgxrMkI+4#t(;?0cW zxD2mGjmft#rLst$82f%BD5^DP$gYVC&qW?@bR2O7KWf*BqnxxeeOk3q*_JIB_iC#X z14=(h-6D;sYY^*}G<(Z;AhaR=+9-x^%S`u2(xsATE5AMvo-jN*{qgk*Hl3zxR7}Oa;`PRk3D|>wxJ?Hga3?tMjDe znIMiD2h6#&1rA>lEBX?bo@0}^zj6X{j=RP75HL!VO0@nU_WgCD^KsBV{^xp=B9wJ22|HTi)tN-yr3K~^H#MP}_fN`?-AH;S$7XP=JT*C=Go$IPJgy2a9&Xd!`Nvlnc^YLm1>(Uy88_o7v@vE8sm`k*5|h{gI=6C=pLYW z@PJ|Ao6}D?eDIsEA6mh0zIh1C_{rz-eRN+;bmuI?#Jd&<<}7a&*@YF;efT!46lp&) zdFcHM)!n~N6+00~wn@G1EHzXpO*o@^XVb}d&CN?bNMMR(@N724Hmi>RZd##hC)?;* zaRyB*YC2gCZ=b}~&=*R1SMidnl(?k%t0^t76dpb$*G;C~ zMwE_gUH0%gi4ys#mj^nn387ZSTLWAT37EuO@3bysii(PIwc?=c%|R(Kj8mx+7YwK@ z-d0VvSp{^(R1;p|qO5QKsZ${(8~fx_G6?|#!&MR!2?>`mjqc19y1xEUdQC1imq!uy z6>~nR?HHMw53$L7HBV>sj{EF6sYmdx>t`0%^jh1cfr^T5C$;DGuB|UxzcoDl1P6l_GYqH4bA6-{tILH=x39Hte z`^7OH`j!0@RCzfBVNx8)rF4PeSb=3NoUclYuRr!rQo`Bm+#Xc=_>+lpqPBUswz>G# zx}}vorHOCWS;A5-h>SbC1avbkrUGU%KAR@_3Z+X>T%|&!N+O=^`gMZ%?bL1a<$aNk zHcxo3R_`;zd@Z~1ntTOkW2T4d+%y6%dZ_HUXc@LTz=KOO$tTNiF z_iiMQU5XL-R`a?D8S=WX1K(7{jvRN;B|yw=DRLyw?aFB#2;3-IZwKVavKha~hKsCN@el_?dPe@c9?C`~HHMtx7P zHO0jjbE1b23et}-$2lHk_`D)gFIjxS`kjsWkh5y<@YftMzVGbTpRf2HvbFHK^%-Rp5s6-iVSPP2i_wCg+ z+Q3pqgqtH;_)n4ZAN}9saf6^qk*py#sdD%vUGb=F^m!z{N+41Cepgb8sk9E)`Sc>J z<(VhnZ{!zh(2eg=cw>L;@dvT~gBW?HuBMlx%C(nVo_cu+R2?C$Vs|xmJ;{>&T2J;P zCV#Pt^+CR}=^M@A2CgnI+a3unT40^Up~#JUdHJQ}g)VP3H{UQkN5=)bz{$n;(J>Fd zGCzoo{PaCL@g(tyXP^w>yi9IsYEjw1xnlZt+Tud9F+y_O!vxo|GTd&UKE^zuR_-9~odPy5GS)}R zQ+@(e;SrJZB%`@il8x6Q zb(?Iya#4u?vWs-f3m|M<7>HhMps7`E#v7P2Xg=L=(=wuyq<`dF0$p3rK+9aU-x0jq z4#+dXD%pGFeXo4!iOVq0tsX0G(<~jgB2Y0Y6k(Tnq2m%HmQjbWpFeqx<5(N7*}Xm< z#b09wOtps9M${zuX{HxtUxh!hr=dCU{Is-+;knn+Bp2;H6CHz3++*)mQ+-KyJM=#L z;S~$MK6d{-?}`>9l?oeleg$w$aQ98T8k026vnJAMjdXVpcFs)fFw0=Rr<+svaj#@a zDZfJY%Y0vycN?Hg;LvwUu^w2@R_9-Nm z<~xM`TzdPxewv%>?Zpo@j{4e{Y>5imh?ZwWisst<4yHM_@y>t9zdRcIs`NlZ%B`8F zFSs;m7VjGs#Smt4ndQCgSyqVai6bNG#wPug>R%`vP+n2sjB3KvMjVbh zIRx{mSSa|IhPgkYpJEs++nX=rNzaWNZDkN_mEx<>WM#mnb5ZRG&*>K;36JGO)GLBV zEYC(>r!+l8^{a#eyLxW6VpEU%xM<+gL12np+|8jbv2Ccwv_t*K4egDFQ#hh+QTHz8 z6SvfwJwI8Zelb2MQ1a1`ygcsDk4fEzal>XhIcY`9-?@aZfocX6Y=9;cJjhf3dzq~4L}ClZwRIX`_AW%_|awtk5+WdS(d)h$jZxoyZsszX-x2VLL3LN@+SS~&4jO0SUS zP;$tz7|;nM%N2d1cKei`|NWzvRPQNbWd97f9@uU;bST68>cqUY)`j7dB@I@%v<`U8 zHT%jF@G)p*OvqbtteKAA)n{DBfBI1bss04xj%7;5w>O=X$xc9|R{W+yr6kYoC#awPztJ z+)PR^$|u@#u}LqY(YjlH;OfYP$FLH@osOPSC~)yC_>0 zbW*&z&p*A4MX!HW|E|lY$AcS54+`6OMpc0}V8O7zSa3aTx&Gec4Z@ZLG>V>TpQef) zQUrKjx%fsyKC%PeD&zH}7Oe8LHTxK_S zXyH}*YD%#C8j;H4IZf}kI-JIRMoCmx&hz<)n_|2mv&5B7-GAS=Hn~<=Q^Bak;n6~& zJD-eB$&b5Irc-5)s1)duE10-@#zPLgLp=vgw~+L36FAu+HYRC)hK5d&`eF;a$k`L zm;`G}C#dB1;j64z3w=+Zywc=kgl*4&*=w^jS~h8dmvKdb!R~nJ95-XqZ;1~kct767 zUYGQOp3#Fhy0L<^9OIqtfRNg>Tddew+H+495Q&bg3Bo$gP6p`P=_ z2WNJ=B%|=*P1PlH+~gOzP=M~nQ%3;ff@+}~)rtF>^Y={_T?yM|+Opubg+KRTZl zDe*n%Di*^_#58s@3!}eGwA>flUM#|~Jp?yDWE*lk{z1s0Yn(oMfRDtK?0)~or zPS(&5)|iY=ch^AoGEh@W@jU%?ABxM};%!Bx{$z0!J)=c{ZX zEh9~tcGlYzf0n&BhAL0)=L&qy*S*W7pfM`YjDr_z?%Ioz2PrRA^))BW=T9Gt4zZlo zD4#g^dqo7#^J3@1D=M8++e^dua-X*iam$ zw*$@Yp&uV7mstAyXyQd3tIO$n8x5xqi07K*+;|aE9m^Y-939ga#rO_+OR9dr(ok^3 z+s#r@khh4(_sIN7qFu4UE0)S)=33Y$&o7bpu*bal5K4CZn5wyB&H_rHLHVal0Z$(a zv`=8~558QN`m_D|ANeQty0R+xaz#M??BJd9#Zb>^@5_(FN z3BS1@LxJn`)r*C+5fKATvLb=KOR?9JE-Ovk8t872BFxzJl+zVwu_N|9c69BG2|rFz zr6RYbElG%hP2lzBp`od)`RW1*(%x2DF0=VcLFDZmUCux%a$KtA@!(+IQE|4Yfn&|% zG(rr4I{Skk*75Q3IR26u+}oEgh40H$c4$bAP?bTc<|YX@?@JF^&8ud2iknPx8E%}a z`E=y@uJ28rVNK19C#NwU%$=qlKOAjvx~Ef7P3S$}d5s@BFTfs45l>%yX8PU%#aAj8 zP1bv}!Y;ZVR_^>FLURcv(4ZVwI4InAADBLS_g2%d?=Sq$1;Mv`q=$t)$Wx`hREIZJtWM|oUFKG?BgRZ49_5(TV=?}RvZO< zpY(b^kv1n|)bqP)B|3d)KYX5Btm_o?2)@hqc?Q?7+zC-1vViSi>vi%{ zCjJ;VW_Ga~b|nLsV)t?hbM@!p#sWtAa<-PNWVO4Q#TTNDs6vDuN()&`pQ` zP*A;lPmZyzAKARkJl@Bdy<$s|q&_z8D;i~)v|N)kCGsVD_CtpQC)00mYDHq?6)0Lm_+Le0}JN@PMmut}t-mQ>tIXHEf%#^sj^ZkJ(y{M00 zzBi$MrXI?!u~DYn!(h-qZpp5vw#}~52B4P~yy74+ES^lodGc;nO1!GoUiP~e?on#o zGI?2|5|ADm_l#ViBX!U;5WA1ZPROwRi*tC2z7xE6zNEo6Ce=!shfEUa~S_s;ikp zmF=-@wnR&%GnLhL9K-%M>u09l9*9bzn7T2S%~jh-dysdfR$E1D&(D?0Q`(1%2?wOx zQ$HA_yQpZt5YH$ktun@o^7>iyI-j~XM4h9g{sPq()i+!-`=?(mT_ipCwtYw-=aJpO z{?|sVX^B6yyk0p>et5l%7lUD{OM_oQ_4w?w=8X5r4Fu;EnOxa>de7et_p(a;eD~rA zG3nut#VMM_enVzjY|Lky?5gQhWvp0hl~!294pMT(HpnM36&vH6bu>!vJY^wrz+mJ! z(NIn!{Se916{lZSS{IDIw@@4UG+0c&6r-ivC6an(5%X|{TMa#VS5*4@B5K<=;d1UtDFI(l9ov73xB`+CId3noTyi;zC2XGZwaWHiA{$IydvsGn{NjZNtj_ z0@rHNf_{>{No{zWpe?g_$>#`xT$^-)uWwvN^JCmDHSYU5_}@cvF(MCz(klyGd4*6r z;(DY+t09spWEUYXcW8$FgQzPkM=mZ*snuj%PE~vwXfR&i z&$iWysfYV*xPHI*>B0lj+)4#=ufyd=pI;mxl`Hy(GiihrZwOLd%D7#re?472oiz8|VVyOOpySW#$~!&uow2WQYR@p}-#Kv+-_Nskft#Swqak&dliG#ihSPPd z+K0N;9TDIAJpKAK)uh~lUwh?9j_jA|df?eArY<~AB$NIoqldHi`B=wQ<2z>M?N{p) z&=&~hbMIh5*M_6h z;-O)$XlWj>@4le>(mK#8P)(QL5c%=o%>SX+mwoq2LT@ngnhq8JZ$m*>+OnzUS$n5)tqi)F)NeSB|%Gi=}O5@9CnBumcXTW1S1bJBHLi{lu{`(AT*X0tn2sA$|I$fmxS zb!wLqTQ$XX#@RMTKhn@(ts|V$))(%!nv2aWR0uaPtIlL6{;IoiLuZ_rI#);dU3m&d zNHuwf6t>m{D!gAIRTX7ZIpNq|I-_$O_z7vx&iUiSQe^X8;x}L3OaB4?#Zxj;NsHaq z&4)EJz3XxGBm`b-&HHE+W5XSIBfu5|KV{ zy8>=bq5cnc*^Z*hibGRRk&iqWFecI+Rxo9*;qYo2i;(OoDW|}^^R`ItyxYM^D}UQ> z-#^iO8Z~^uv_H(h4N_*Z7`E`d=?r?1uIAB>tpcBP5RGFg8cg%*P`Lj z$`Mp5y^`>%((s`wqZc6)cv^0pvv|M$y>8uwhWKc+eQYGtvnC~VJ3g2QR{58sO9 zX1Xc&VQFBul|CoqHM=ay=|9TuerDj!Ya~sXa5Q6h<|98`fqSNU2uA|~p&C2GUzhvK zJC3V9f2p?efjeQc<@CYxwb7+7Wn?~UB-cFEc`!)fuldR{w?R;vw#wsD4!uQ^>!CM^ zjHoXKLTS+7Zud>-E$E)V=($ZA{Lcd=|96MhUV@eiicE{W;(U_qlpNCo1cN2E)?N}S zz7DYdbu`U%7tuO!@9i^%>PCJtPP=DW_tm0wV{V?g9jSL;?WSSO?MOV=sC}pWvSP1X zxN3pdLVjNDAx8WKGb0n@yGB)62pmsOPoqS_O~*=UPei=>fiB!zUOkZBE=>%?sDfi9 z>cIA&tUhWDkqb8t^w3`)JHLnW6s|KCk|+ zoqQmpZv2@sw*|?A4^i%I-l|iN8*1WO#&*}WMJFv@ebfAeHe=i)am>7t<`owamaSa7 zM&=iZJWHqgeC5}X=50owEp1yS1tz#``Xh##+eYz5((|K>-IngFyER7*^s&=mJWAoASM#OE z%h%-CquaHfEaHt|S%QH{i?w>6Pumq+z0ANfIJ&@0df*{JP=nv#OPb&xBNF<{@**FH z1@!rIE>33$8*MEd1XeWlme0m*X1?XQIcxy_w;6cg%v-2T?wv51hBN!!!2gci!juMc z_a8ZVcEZFH=aO{*yenInSYUqn!{prwv$D8G#rm(za#SY&PM9ieT^@dbS-3?`TTrw7 zkyBtNOoO6%D{sIn*uoS7ZOwm}f;(Y)x{lhV0Uk3L5%{<-p)!Sb!VJHSkKqoO*SE;| z9t8FuIfZw^b913`kw=nO5-oQUhiJdS<0!iW<0WWZi?jB%k{0~!dCromlZ0;1m z9NZ#jFgPp!!<5+p5@Vt|b8TjazfLSf48h)K^b1^MPy=37*z+)kL&3%|g3 z^ALz65Z!QlJ_5I{{n1_i4>M-_ocu+T)QuJ}p||niOiNM}rov8`M`gS(IRV`xw%D_c z427w<6Q;XXhwx9po8A&fLF6b*rJXQ++65+{KADCs%qFlW^v9mcJ7HRVymA2#@V;(g zl2W2DRd&MEI7jD{2IR!p!Zf5pVXE$gS$C|&oEq?;kGaFgU2YEwQ*9^ASe;x+B#<*5 zJaA^_UKFPKPME@xk>C@N2t@K0rXwgy{)~~vPMA*R&T-*@_hbuGU>^!ob0vR{(^(04`}O47yP^{-^pIP#>jcR>=MDZh?l-qDs0^H=+TJIS~5&3;QOYHMkCzC2>>{;1zO2~3f(A3(SRn5e)EC~vcfIuryWLx zZd9b(K-)n?g`eiGE(1``Ezm|rROm)Y8vE}lAA**9pK$U8P$;FM4iq-Bg$Wh9QInzp zopqtl9{|AoO_E|GW0+B)8%61VLP2c^e#o!dLTk@IKkE|;vCp#;OJq32c z%*gGP0yQoIdf;-pqB7TBjR3lT-+qh&dyQ4WDh>fXaAp-MQ|OPJXfQ?9FDUxzWY|+rP{C4V5Xi6MGUr z?V|ZRQlukAKm{iCgo8S z-DP*eq#u0q{qMRPpfcrl!aQiK{DkCp3~i31d#FtLoiMGAlyMLMCiK8#a|xBHuoLEg z$B_yLiaizoFlVBj>=Ts39~RfAN%ie_M$S?cEU_KzLfCy`H1Nlitg$=VJh#{CHp(m z9+jzqE|U`Eka!jkioY`-qcS!BFz5d5pAa)BkCEr^Oe`)G-L-bYJUxu(xz2;~t0hR*v&{a_KLMY|2XHtyX)|}D7W+>wlsOOxi2M7GwO{Mi?P|@~ z!M$pO^+o8m!mbvL5EQk*TZgU|c>8!zp=e18SrdXjWY32hcYjx+aHts!x=}X%L;dZc z4`I-ax^e!${R%SUzim1XgYx}xtbah)B_-{0C0`GIxcU;js5afGM$v#izNBZnUg^N0 z;V|e%If@2U^TYeWze_p*gKpHLXg~!RCE6iVKo49}Ha=AKHwscTpb7pZSfsy!o1v~S z=tf2QpU~Avr2>A+@OcE<7Xp`WY=*YNpc^IW!oOV#f&$i`pLO+D!<3sJRsD^c^dC^j zh7h#Y$7*ah_#1lGp{rr)34?AFrT+TM@41!=71SL2JB(t{n^z5S6w5!094ud zg86wX8}r|1ps)T*?^RkWSbU!q_dLS`PN)otQALDkHDU;aslBZOfH@i38e9FooE7BK z>;GQSPn_1#(-@h+9>xdafz2yIn24gM5D0KWYiMKcZtldndQxjhvd_ZRoe+V6{Rs;T z@%tC*Ni8JhNW56x17JiZke|q5KrV= z6ba~v;{Zc*45$wG@&tWgjNcaut{D-Hfxf~0BY7E&2J|)*oQ7xchlaLn?)E{uzX6&t zpy9*DSN0ruU(MXY&e+x*ec@hAc-IpHRO}XCloKpvd8L-{PY6VJPUiRw)yXMbm8L$Nyur7K2qdrK7DIi$k;srT?L3egp z8`{W!Cm0A7h13X`Cqy8!j&DXW_^hHAsg|1tV@M~wF^fVzX>g+r-AH$zt?MI*_S1Wv2wfdcp~C`Jfi!|lycquj~(`Q8h>0#?)Y=XXkR7p%HS%3k{KuH5n%{b+M zXlToJB55c-4mdM4D7xV^yQg5DH#2l~ULRaEJXxM{#sM49f`I|yG@0r@v{l*ApmjF2 zV3+}#A&?F3$Dy^qX~r%tPV4h78axLBS1#zvk9sf`a2{Vh3J-1h_8F4ht_71uHAq%) zS9$du@a&vjoLqljQ;mLpnMj-`Oa$s$gEMD1@@*F!iI$X5N`0a}<{t@=ZXg@LvvXxX z0%2l*eoeY1&86tcdSRCpC&Tuo^=v-~F3SZG-bVjUr8_^>iHwlOp|GjlR`UKbRNnlwd2f(+`OdJfD9$7bPd z#jZ-b4HnzYR*(M_{m({F5xoKrd`dR}MUttdu@i@tor9~3GpCC?xZ)6$_!lw%*(pl| z)|`hVwL>SsFyVrgEWF~i2hBxbLB|Q@{8br0{(I30;YghJ9@GOXEK~4-BslIC=>~3f ziG&6&b1pAGTnxOlIJ~()Jz@A8x3=6w8+h<>|1)wBF|n+hfuuK4f!ip&x(P@M6b57Q z=Lc)e%@GJP#JGfcHU`4Y_So-%nE1ElbY*SzY|knQMT15o%tUxXO-J5d1sOZrLYrP- zfPW)zLL(BHW;vg8Ap28{+10wZcOQD5Lr9MR~*4~o&f|!4Z(3F z`2kEw+jZiq{k9=4fUADRduDGsfI8X=q*v65cntZR@egrz(XdB|`(GOW1T;(~PUbfx z2*e`+_@ZG9>B+TDgY8i4-JUscaYcy_OvLvA7j>o^N2Y*Q##NnBcTvzl+K273qXuPV z9Vp#U6T~=@TKW%iQ#p+W);1$P1?o7s2u28w^-|i3T^%Acus0I*xp{!J5}T&_ab%Us z8rIp|*2HFgB18jOrn5+$2qaYonFnrD;nQ#=+EO;YHIn597&_QhFo9X zp&{Tt9je{jAWvX|jW;;W$NUcsZP`>q4unMkRWE|d22PuD{7u^^ZqSg8@{@`#RNN#2 z`QWrVu-XF-3DMA!t?bT{t_#LCdp3L#N|aSdZ{%;Rq^gXejj;#FXq*mq7Qa&(%@rc^e_){ikMyNt z_XN5dgJ7gUsVc^il@wTz?$9*2Wy25+qY8MRe&Y>1@-Q$392@`^fm^|7**DIUQg77e z=)f7EcqDjGgR%;#O0xzA%f8>OmCl^btJu)5;43Eoy>AK`V!v2kt`3lO5iBZEw{FIf z-&e6_R?bi|UY!}yFo2i%$g|hL0Hz?-!GV#qzvWy5qNO+_;a4fOkLCbq3#uS8*ihvh zLILg|b*h1v;iB4~OoswfW`Tzag<6F?!|Ezl zzzk=>15ctZ%)hyo=I+0PcFn6~bM9>CRZ~2n_J@I}Q{aIkiNQ)9m;kJ^SJ$#=NeQ_@ z=o8+r(03q;DvDk0w>Z!?Uu%f|x-Z|Pj z2n?DHre!!UN(zOCmV8iD$t(4z<^VVP3Lf|%70Yb!41dSgj$(?H@CwseF!}~SSkyJk zIP!rk3K-=OY8&mLd&bS(zj}Zqhd2Yq2{oXqkQ(wRP^bZXLs*Z0Cx8t|%L|6SsVp%=Y*9Ke#My*#2z_QQ-=k8YB!d>qbsQxeR>IolY zhj*I#t>y|>tM}^|XXR%gEAb}oD3V@%le|2u-;M!X zy@S~QO0c?V2lV6*=ZVY%E~ubj@{S^PG`4Wp?GRMa{;#YB*+Jv8L)J~eeZ9%PRmddG zP29C>bJ4Q{y@2I$Ex?T1#2rQYYi;4K`vV$wcBtgw1a3&k5By8a*l{7iy~ ze6SQSFK@9!&Q|Wa9d!QfXOKVewtdA-2i%TL@{S{ObvMbob_pDMcDTpKtalYK>o;*n zk*RuHxM=zVWQVQ<`QRqN6ag~?+`jf_ws6<&pu4>te%^X>5tQHvu-gvfRw4cMH*weQ z4MNWj4liAi(8fp5ChjQGE!^ zfJzX`JJ+=?gFKlJ@(v|R%{Y!+M&)ikK;330g2?@8HzlA?fkSNuaB{ODio_dav}R<8 zd^1lbhn^g4_9<-MX*q5Do4j_UzgFO*AuD(NLv=b}Sp`rt!1r#RIKhZ$%Q*GzS{T$> zLBxP# zAQv14)h!K*zg8jbgJ3|8^Y%_0@@r+Tz0>bS^fm%R`O)by=5BC?j_?8xYPDB|bPD^; zUv0uLTz!KMtRjDd(I^}gYh4+60QBT0@F?@qd-cdQpVEe5&7=S0Y znBryBR`3o?al0$@J~*2~Sb^X}m3S1H6}=U_15>;&FR*_Mz`r(0T!s7+vl+ZmQF{J+ zg&_pILdR6g1KPb9+5{d&PQ`8oubV>u-%}?PAPz|%4ZZ-VCRn<_P0lbl5)D%{S+j!=5g`!#o4}*U{FJR=G)(~&maU)O?MVa@ zpP=7tini3P;B`}=QCWJ(V%7-)iM6-bxcK&F@J4BghAA%IDVUcBU}#AIA3Wjot>7J) z;z+x7-6#N)gOe*bxc%-{Fq)=-ChPsrk|*kbyFq$?i5fP>Xd|6 zlN@=!dGKaQG$g$0)5}HzXi&2xoM@I0BcdfEzSkZ-`IV$Ge;{Kacu+T=s*t4xt3+2j z_{O_&WW&EI2FQ>{#=jfn10ZPFfI-KR0foPz&X)EULB(rfWs2VD1jpLyWQtZjD+Qw+ z1uA~jX2)^l<)T%nlPw3dop0>w{<|1^RiyE+qY{Y8OaG1WIuNo3Je!!0VN4T~)o$(1 ze>2Ztu+`}|y2$!kJ@8y)qcn#e7vxU+aI$2{GTDCX1j4d1M%PCaRoO$oZB( zOmLXNi6#@Oa3iOhouK{9PVk_f5{w~@+y5|s?^?h&3Af2m{I2#oU6;w8l!JnUpLz2Z zxqinVwA;o={h-zU*GTaJq}+Ui;t-JZ4DfvTuDd}GDsp|GX8w(2s1VVaCa$#j36Ri{ z7Ag`f{d-|ZE0f>;WPh9DUsAFIDZS_(#QxwyAi5La$T4JnA1ZQvn1=r?rI3uZo@2D_ z-LV7=#3OK-@%qpMp}~m@CJ{DNBs)8=y1j$h`QKtLJ^qi)*40hXb`YPD$`5SWc(4#y zd$9j#zRKjehqKNE<#~WE z61aR3aCtbecmNfMR;Gje{b@ICcblR>~zlW;c3nQG$eY?qNJz{3FJjJk&b4pYZh zd7vIL1ZT=FR(8KzPYun?ZSB#UF(IQ$Tj&dcHfO{*cu+HZ6>|T#-~9FVncqIYv2@?Y z10eK*%x&BOfHeYc3P;mSZAEV^g||UNR#`BUy)zF=+c5(8TsMxCnO;S2desSyWWrJV z{yhh>!wwkuFB=imDp4#vvbpV8dA2p~(kqtlL(Dg+E^o9L@ zbO1n5U;XykXaIBq=7d9y7va$L@aOn96jGn2UtC5G*wJ_sv?$6c1i&$1;I1`SHA}r6}nNBprO88u4lD6kaQAcQdHS#n`9PF97wMwy3X1 z4u|eQ{Yfe}XEh*c06kpNQ6w=19J&MbnLmldgVG+M4W=fz`uC_%p&MI7XsCZ6(n)g) zIKK>#78N>*EZz%;?m+#9k)s!x0B{<#{lKA<)Ntqy)JKpjOBMsD*Cyv5LmKQyg$n*D z{LoMzevLZV%>qBb#Ncf~eOfql2kOHw1xJMr)4`!TP#=C*@&>dDdFU`IbnWJ3uzo;8 zefX`z8_-cCJ0l#r1NGq-0HZ>GY=Z7UefTZ78_;p2G&8ECYj@(Jr#=0_!VXw&{1R`FC4l9_2HLup+dF!;m{qZ55N2g z6{;YJ3SGMj3O)7V*94(LU4`M$9jFh#%LWz7bQ}&vQ~j+smTW-BkujpE(6#$Zfcnt= zCI9f#t=EHWKu3|@VsPjV)Q8{EfeKX;heQ9VJ`R}S!HbC)M=@TSAP|lxK?#lcAF;4K A>i_@% diff --git a/hw4-vmtest0.spl b/hw4-vmtest0.spl deleted file mode 100644 index 2c7e635..0000000 --- a/hw4-vmtest0.spl +++ /dev/null @@ -1,3 +0,0 @@ -% $Id: hw4-vmtest0.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ -begin -end. diff --git a/hw4-vmtest1.spl b/hw4-vmtest1.spl deleted file mode 100644 index f7f3524..0000000 --- a/hw4-vmtest1.spl +++ /dev/null @@ -1,4 +0,0 @@ -% $Id: hw4-vmtest1.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ -begin - print 10 % prints 10 -end. diff --git a/hw4-vmtest2.spl b/hw4-vmtest2.spl deleted file mode 100644 index 111f9da..0000000 --- a/hw4-vmtest2.spl +++ /dev/null @@ -1,8 +0,0 @@ -% $Id: hw4-vmtest2.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ -begin - var x; - begin - x := 5; - print x % prints 5 - end -end. diff --git a/hw4-vmtest3.spl b/hw4-vmtest3.spl deleted file mode 100644 index 4deb444..0000000 --- a/hw4-vmtest3.spl +++ /dev/null @@ -1,9 +0,0 @@ -% $Id: hw4-vmtest3.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ -begin - const five = 5; - var x; - begin - x := five; - print x % prints 5 - end -end. diff --git a/hw4-vmtest4.spl b/hw4-vmtest4.spl deleted file mode 100644 index 98a82dc..0000000 --- a/hw4-vmtest4.spl +++ /dev/null @@ -1,5 +0,0 @@ -% $Id: hw4-vmtest4.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ -begin - begin end; - begin end -end. diff --git a/hw4-vmtest5.spl b/hw4-vmtest5.spl deleted file mode 100644 index 38b0005..0000000 --- a/hw4-vmtest5.spl +++ /dev/null @@ -1,10 +0,0 @@ -% $Id: hw4-vmtest5.spl,v 1.6 2024/09/17 21:48:53 leavens Exp $ -begin - var x, y; - begin - y := 33; - print y; % prints 33 - x := y + 22; - print x % prints 55 - end -end. diff --git a/hw4-vmtest6.spl b/hw4-vmtest6.spl deleted file mode 100644 index 7f06f1f..0000000 --- a/hw4-vmtest6.spl +++ /dev/null @@ -1,13 +0,0 @@ -% $Id: hw4-vmtest6.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ -begin - const nl = 10, y = 121; - var x, z, q; - begin - x := nl+1+0-0*10/10; - print x; % prints 11 - z := x - x + y - (1 - 2 + 1); - print z + q; % prints 121 - q := x / z; - print q-0-0 % prints 0 - end -end. diff --git a/hw4-vmtest7.spl b/hw4-vmtest7.spl deleted file mode 100644 index dee869e..0000000 --- a/hw4-vmtest7.spl +++ /dev/null @@ -1,13 +0,0 @@ -% $Id: hw4-vmtest7.spl,v 1.4 2024/09/17 21:48:53 leavens Exp $ -begin - const Y = 89, N = 78, nl =10; - begin - if 99 > 86 - then - print Y % prints 89 - else - print N - end; - print nl % prints 10 - end -end. diff --git a/hw4-vmtest8.spl b/hw4-vmtest8.spl deleted file mode 100644 index eee2d9c..0000000 --- a/hw4-vmtest8.spl +++ /dev/null @@ -1,14 +0,0 @@ -% $Id: hw4-vmtest8.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ -begin - var x, y; - begin - if 99 < 86 - then - x := +72 - else - y := 1 - end; - print x; % prints 0 - print y % prints 1 - end -end. diff --git a/hw4-vmtest9.spl b/hw4-vmtest9.spl deleted file mode 100644 index dafb28d..0000000 --- a/hw4-vmtest9.spl +++ /dev/null @@ -1,22 +0,0 @@ -% $Id: hw4-vmtest9.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ -begin - const q = 7; - var x, y, z; - begin - x := 86; - print x; % prints 86 - y := 99; - print y; % prints 99 - z := 1001; - print z; % prints 1001 - print (x-y); % prints -13 - if divisible (x-y) by 2 - then - y := y-1*z; - print y - else - x := z+1+q; - print x % prints 1009 - end - end -end. diff --git a/hw4-vmtestA.spl b/hw4-vmtestA.spl deleted file mode 100644 index 31ec85f..0000000 --- a/hw4-vmtestA.spl +++ /dev/null @@ -1,16 +0,0 @@ -% $Id: hw4-vmtestA.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ -begin - const achar = 97; - var c; - var i; - begin - i := 0; - while i < 10 - do - c := achar + i; - % prints 98, 99, 100, 101, 102, 103, 104, 105, 106, 107 - print c+1; - i := i+1 - end - end -end. diff --git a/hw4-vmtestB.spl b/hw4-vmtestB.spl deleted file mode 100644 index 863152e..0000000 --- a/hw4-vmtestB.spl +++ /dev/null @@ -1,7 +0,0 @@ -% $Id: hw4-vmtestB.spl,v 1.2 2024/09/17 21:48:53 leavens Exp $ -begin - const c = 32; - const five = 5, three = 3; - var x, y, z; - var i, j, k; -end. diff --git a/hw4-vmtestC.spl b/hw4-vmtestC.spl deleted file mode 100644 index df68d49..0000000 --- a/hw4-vmtestC.spl +++ /dev/null @@ -1,22 +0,0 @@ -% $Id: hw4-vmtestC.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ -begin - const c = 48; - var i, j; - begin - i := 0; - print i; % prints 0 - j := c; - print j; % prints 48 - while i <= 1 - do - print c+i+4; % prints 52, 53 - while j < c+i+4 - do - print j; % prints 48, 49, 50, 51, 52 - j := j+1 - end; - i := i+1 - end; - print i % prints 2 - end -end. diff --git a/id_attrs.c b/id_attrs.c deleted file mode 100755 index cd4eca6..0000000 --- a/id_attrs.c +++ /dev/null @@ -1,50 +0,0 @@ -/* $Id: id_attrs.c,v 1.10 2023/11/17 21:56:45 leavens Exp $ */ -// Attributes of identifiers in the symbol table -#include -#include -#include "utilities.h" -#include "id_attrs.h" - -// Return a freshly allocated id_attrs struct -// with its field file_loc set to floc, kind set to k, -// and its offset_count set to ofst_cnt. -// If there is no space, bail with an error message, -// so this should never return NULL. -id_attrs *id_attrs_create(file_location floc, id_kind k, - unsigned int ofst_cnt) -{ - id_attrs *ret = (id_attrs *)malloc(sizeof(id_attrs)); - if (ret == NULL) { - bail_with_error("No space to allocate id_attrs!"); - } - ret->file_loc = floc; - ret->kind = k; - ret->offset_count = ofst_cnt; - return ret; -} - -// Return a freshly allocated id_attrs struct for a procedure -// declared at floc. -// If there is no space, bail with an error message, -// so this should never return NULL. -extern id_attrs *id_attrs_proc_create(file_location floc) -{ - id_attrs *ret = (id_attrs *)malloc(sizeof(id_attrs)); - if (ret == NULL) { - bail_with_error("No space to allocate id_attrs!"); - } - ret->file_loc = floc; - ret->kind = procedure_idk; - return ret; -} - - -// Return a lowercase version of the kind's name as a string -// (i.e. if k == variable_idk, return "variable" -// else if k == constant_idk, return "constant", -// else if k == procedure_idk, return "procedure") -const char *id_attrs_id_kind_string(id_kind k) -{ - static const char *kind_names[3] = {"constant", "variable", "procedure"}; - return kind_names[k]; -} diff --git a/id_attrs.h b/id_attrs.h deleted file mode 100755 index 73070c1..0000000 --- a/id_attrs.h +++ /dev/null @@ -1,39 +0,0 @@ -/* $Id: id_attrs.h,v 1.11 2024/10/23 13:06:37 leavens Exp $ */ -#ifndef _ID_ATTRS_H -#define _ID_ATTRS_H -#include "file_location.h" - -// kinds of entries in the symbol table -typedef enum {constant_idk, variable_idk, procedure_idk} id_kind; - -// attributes of identifiers in the symbol table -typedef struct { - // file_loc is the source file location of the identifier's declaration - file_location file_loc; - id_kind kind; // kind of identifier - // offset_count is the number of constant or variable decls before this one - // in this scope - unsigned int offset_count; -} id_attrs; - -// Return a freshly allocated id_attrs struct -// with its field file_loc set to floc, kind set to k, -// and its offset_count set to ofst_cnt. -// If there is no space, bail with an error message, -// so this should never return NULL. -extern id_attrs *id_attrs_create(file_location floc, id_kind k, - unsigned int ofst_cnt); - -// Return a freshly allocated id_attrs struct for a procedure -// declared at floc. -// If there is no space, bail with an error message, -// so this should never return NULL. -extern id_attrs *id_attrs_proc_create(file_location floc); - -// Return a lowercase version of the kind's name as a string -// (i.e. if k == variable_idk, return "variable" -// else if k == constant_idk, return "constant", -// else if k == procedure_idk, return "procedure") -extern const char *id_attrs_id_kind_string(id_kind k); - -#endif diff --git a/id_use.c b/id_use.c deleted file mode 100755 index b4fc528..0000000 --- a/id_use.c +++ /dev/null @@ -1,47 +0,0 @@ -/* $Id: id_use.c,v 1.10 2024/10/23 13:13:07 leavens Exp $ */ -#include -#include "machine_types.h" -#include "id_use.h" -#include "utilities.h" - -// Requires: attrs != NULL -// Return a (pointer to a fresh) id_use struct containing the attributes -// given by attrs and the information about the number of lexical levels -// outward from the current scope where the declaration was found. -// If there is no space, bail with an error message, -// so this should never return NULL. -extern id_use *id_use_create(id_attrs *attrs, unsigned int levelsOut) -{ - id_use *ret = (id_use *)malloc(sizeof(id_use)); - if (ret == NULL) { - bail_with_error("No space to allocate id_use!"); - } - ret->attrs = attrs; - ret->levelsOutward = levelsOut; - // Shouldn't create a label for procedures here! - // A label should only be created when creating the proc_decl's AST! - return ret; -} - -// Requires: idu != NULL -// Return a pointer to the attributes of this id_use -// and the result will never be NULL -id_attrs *id_use_get_attrs(id_use *idu) -{ - assert(idu != NULL); - return idu->attrs; -} - - -// Requires: idu != NULL -// Return (a pointer to) the lexical address for idu. -lexical_address *id_use_2_lexical_address(id_use *idu) -{ - lexical_address *ret = (lexical_address *)malloc(sizeof(lexical_address)); - if (ret == NULL) { - bail_with_error("No space to allocate lexical_address!"); - } - ret->levelsOutward = idu->levelsOutward; - ret->offsetInAR = idu->attrs->offset_count; - return ret; -} diff --git a/id_use.h b/id_use.h deleted file mode 100755 index 9f00847..0000000 --- a/id_use.h +++ /dev/null @@ -1,32 +0,0 @@ -/* $Id: id_use.h,v 1.7 2024/10/23 13:13:07 leavens Exp $ */ -#ifndef _ID_USE_H -#define _ID_USE_H -#include "id_attrs.h" -// we'll use lexical_address in HW4 -#include "lexical_address.h" - -// An id_use struct gives all the information from -// a lookup in the symbol table for a name: -// the (pointer to the) id_attrs (attributes) -// and the number of lexical levels out -// from the current scope where the name was declared. -typedef struct { - id_attrs *attrs; - unsigned int levelsOutward; -} id_use; - -// Requires: attrs != NULL -// Return a (pointer to a fresh) id_use struct containing the attributes -// given by attrs and the information about the number of lexical levels -// outward from the current scope where the declaration was found. -extern id_use *id_use_create(id_attrs *attrs, unsigned int levelsOut); - -// Requires: idu != NULL -// Return a pointer to the attributes of this id_use -// and the result will never be NULL -extern id_attrs *id_use_get_attrs(id_use *idu); - -// Requires: idu != NULL -// Return (a pointer to) the lexical address for idu. -extern lexical_address *id_use_2_lexical_address(id_use *idu); -#endif diff --git a/instruction.c b/instruction.c deleted file mode 100755 index ef37eeb..0000000 --- a/instruction.c +++ /dev/null @@ -1,575 +0,0 @@ -// $Id: instruction.c,v 1.7 2024/11/10 21:09:43 leavens Exp $ -#include -#include -#include "bof.h" -#include "instruction.h" -#include "regname.h" -#include "utilities.h" -#include "machine_types.h" - -#define INSTR_BUF_SIZE 512 - -// the following declaration isn't in everywhere ... -extern char *strdup(const char *s); - -// space to hold one instruction's assembly language form -static char instr_buf[INSTR_BUF_SIZE]; - -// Return the instruction type of the given opcode -instr_type instruction_type(bin_instr_t i) { - switch (i.comp.op) { // need to pretend a type to read the op field - case COMP_O: - return comp_instr_type; - break; - case OTHC_O: - if (i.othc.func == SYS_F) { - return syscall_instr_type; - } else { - assert(i.othc.op != COMP_O); - assert(i.othc.func != NOP_F); - return other_comp_instr_type; - } - break; - case ADDI_O: case ANDI_O: case BORI_O: case NORI_O: case XORI_O: - case BEQ_O: case BGEZ_O: case BGTZ_O: case BLEZ_O: case BLTZ_O: - case BNE_O: - return immed_instr_type; - break; - case JMPA_O: case CALL_O: case RTN_O: - return jump_instr_type; - break; - default: - return error_instr_type; - break; - } -} - -// Requires: bof is open for reading in binary -// Read a single instruction (in binary) from bf and return it, -// but exit with an error if there is a problem. -bin_instr_t instruction_read(BOFFILE bf) -{ - bin_instr_t bi; - size_t rd = fread(&bi, sizeof(bi), 1, bf.fileptr); - if (rd != 1) { - bail_with_error("Cannot read instruction from %s (read %d instrs)", - bf.filename, rd); - } - return bi; -} - -// Requires: bf is open for writing in binary -// Write the given binary instruction to bf, -// but exit with an error if there is a problem. -static void write_bin_instr(BOFFILE bf, bin_instr_t i) -{ - size_t wr = fwrite(&i, sizeof(i), 1, bf.fileptr); - if (wr != 1) { - bail_with_error("Cannot write binary instr to %s", bf.filename); - } -} - -// Requires: bof is open for writing in binary -// Write the binary instruction bi to bf in binary, -// but exit with an error if there is a problem. -void instruction_write_bin_instr(BOFFILE bf, bin_instr_t bi) -{ - switch (instruction_type(bi)) { - case comp_instr_type: - instruction_write_compInstr(bf, bi.comp); - break; - case other_comp_instr_type: - instruction_write_otherCompInstr(bf, bi.othc); - break; - case immed_instr_type: - instruction_write_immedInstr(bf, bi.immed); - break; - case jump_instr_type: - instruction_write_jumpInstr(bf, bi.jump); - break; - case syscall_instr_type: - instruction_write_syscallInstr(bf, bi.syscall); - break; - default: - bail_with_error("Unknown instruction type in instruction_write_bin_instr (%d)", - instruction_type(bi)); - break; - } -} - - -// Requires: bof is open for writing in binary -// Write the computational instruction ci to bf in binary, -// but exit with an error if there is a problem. -void instruction_write_compInstr(BOFFILE bf, comp_instr_t ci) -{ - bin_instr_t bi; - bi.comp = ci; - assert(bi.comp.op == ci.op); - assert(bi.comp.rt == ci.rt); - assert(bi.comp.ot == ci.ot); - assert(bi.comp.rs == ci.rs); - assert(bi.comp.os == ci.os); - assert(bi.comp.func == ci.func); - assert(bi.comp.func != NOP_F || bi.comp.op == COMP_O); - write_bin_instr(bf, bi); -} - -// Requires: bof is open for writing in binary -// Write the other computational instruction oci to bf in binary, -// but exit with an error if there is a problem. -void instruction_write_otherCompInstr(BOFFILE bf, other_comp_instr_t oci) -{ - bin_instr_t bi; - bi.othc = oci; - - assert(bi.othc.op == oci.op); - assert(bi.othc.reg == oci.reg); - assert(bi.othc.offset == oci.offset); - assert(bi.othc.arg == oci.arg); - assert(bi.othc.func == oci.func); - - write_bin_instr(bf, bi); -} - -// Requires: bof is open for writing in binary -// Write the system instruction si to bf in binary, -// but exit with an error if there is a problem. -void instruction_write_syscallInstr(BOFFILE bf, syscall_instr_t si) -{ - bin_instr_t bi; - bi.syscall = si; - /* - assert(bi.syscall.op == OTHC_O); - assert(bi.syscall.reg == si.reg); - assert(bi.syscall.offset == si.offset); - assert(bi.syscall.code == si.code); - assert(bi.syscall.func == SYS_F); - */ - write_bin_instr(bf, bi); -} - -// Requires: bof is open for writing in binary -// Write the immediate instruction ii to bf in binary, -// but exit with an error if there is a problem. -void instruction_write_uimmedInstr(BOFFILE bf, uimmed_instr_t ui) -{ - bin_instr_t bi; - bi.uimmed = ui; - /* - assert(bi.uimmed.op == op); - assert(bi.uimmed.reg == ui.reg); - assert(bi.uimmed.offset == ui.offset); - assert(bi.uimmed.uimmed == ui.uimmed); - */ - write_bin_instr(bf, bi); -} - -// Requires: bof is open for writing in binary -// Write the immediate instruction ii to bf in binary, -// but exit with an error if there is a problem. -void instruction_write_immedInstr(BOFFILE bf, immed_instr_t ii) -{ - bin_instr_t bi; - bi.immed = ii; - /* - assert(bi.immed.op == op); - assert(bi.immed.reg == ii.reg); - assert(bi.immed.offset == ii.offset); - assert(bi.immed.immed == ii.immed); - */ - write_bin_instr(bf, bi); -} - -// Requires: bof is open for writing in binary -// Write the jump instruction ji with opcode op to bf in binary, -// but exit with an error if there is a problem. -void instruction_write_jumpInstr(BOFFILE bf, jump_instr_t ji) -{ - bin_instr_t bi; - bi.jump = ji; - /* - assert(bi.jump.op == op); - assert(bi.jump.addr == ji.addr); - */ - write_bin_instr(bf, bi); -} - -// Return the assembly language name (mnemonic) for bi -const char *instruction_mnemonic(bin_instr_t bi) { - switch (bi.comp.op) { // pretending a type is needed to get the op field - case COMP_O: - return instruction_compFunc2name(bi); - break; - case OTHC_O: - return instruction_otherCompFunc2name(bi); - break; - case ADDI_O: - return "ADDI"; - break; - case ANDI_O: - return "ANDI"; - break; - case BORI_O: - return "BORI"; - break; - case NORI_O: - return "NORI"; - break; - case XORI_O: - return "XORI"; - break; - case BEQ_O: - return "BEQ"; - break; - case BGEZ_O: - return "BGEZ"; - break; - case BGTZ_O: - return "BGTZ"; - break; - case BLEZ_O: - return "BLEZ"; - break; - case BLTZ_O: - return "BLTZ"; - break; - case BNE_O: - return "BNE"; - break; - case JMPA_O: - return "JMPA"; - break; - case CALL_O: - return "CALL"; - break; - case RTN_O: - return "RTN"; - break; - default: - bail_with_error("Unknown op code (%d) in instruction_mnemonic!", - bi.immed.op); - return NULL; // should never happen - } - return NULL; // should never happen -} - -static char address_comment_buf[512]; - -// return a comment string of the form -// "# target is word address %u" -// that uses the formAddress function to get the proper address -static const char *instruction_formAddress_comment(address_type addr, - address_type a) -{ - address_type actual = machine_types_formAddress(addr, a); - sprintf(address_comment_buf, "# target is word address %u", - actual); - return strdup(address_comment_buf); -} - - -// Return a string containing the assembly language form of instr, -// which is found at address addr -const char *instruction_assembly_form(address_type addr, - bin_instr_t instr) -{ - char *buf = instr_buf; - - // put in the mnemonic for the instruction - int cwr = sprintf(buf, "%s ", instruction_mnemonic(instr)); - // point buf to the null char that was printed into instr_buf - buf += cwr; - - instr_type it = instruction_type(instr); - switch (it) { - case comp_instr_type: - switch (instr.comp.func) { - case NOP_F: - // no arguments for NOP! - break; - case ADD_F: case SUB_F: case CPW_F: - case AND_F: case BOR_F: case NOR_F: case XOR_F: - case SCA_F: case LWI_F: case NEG_F: - sprintf(buf, "%s, %hd, %s, %hd", - regname_get(instr.comp.rt), - instr.comp.ot, - regname_get(instr.comp.rs), - instr.comp.os); - break; - case CPR_F: - sprintf(buf, "%s, %s", - regname_get(instr.comp.rt), - regname_get(instr.comp.rs)); - break; - case LWR_F: - sprintf(buf, "%s, %s, %hd", - regname_get(instr.comp.rt), - regname_get(instr.comp.rs), - instr.comp.os); - break; - case SWR_F: - sprintf(buf, "%s, %hd, %s", - regname_get(instr.comp.rt), - instr.comp.ot, - regname_get(instr.comp.rs)); - break; - default: - bail_with_error("Unknown computational instruction function (%d) for mnemonic %s!", - instr.comp.func, buf); - break; - } - break; - case other_comp_instr_type: - assert(instr.othc.op == OTHC_O); - switch (instr.othc.func) { - case LIT_F: - sprintf(buf, "%s, %hd, %hd", regname_get(instr.othc.reg), - instr.othc.offset, instr.othc.arg); - break; - case ARI_F: case SRI_F: - sprintf(buf, "%s, %hd", regname_get(instr.othc.reg), - instr.othc.arg); - break; - case MUL_F: case DIV_F: case CFHI_F: case CFLO_F: case JMP_F: - case CSI_F: - sprintf(buf, "%s, %hd", regname_get(instr.othc.reg), - instr.othc.offset); - break; - case SLL_F: case SRL_F: - sprintf(buf, "%s, %hd, %hu", regname_get(instr.othc.reg), - instr.othc.offset, instr.othc.arg); - break; - case JREL_F: - sprintf(buf, "%hd\t%s", instr.othc.arg, - instruction_formAddress_comment(addr, - addr+instr.othc.arg)); - break; - default: - bail_with_error("Unknown other computational instruction function (%d)!", - instr.comp.func); - break; - } - break; - case immed_instr_type: - switch (instr.immed.op) { - case ADDI_O: - sprintf(buf, "%s, %hd, %hd", regname_get(instr.immed.reg), - instr.immed.offset, instr.immed.immed); - break; - case ANDI_O: case BORI_O: case NORI_O: case XORI_O: - sprintf(buf, "%s, %hd, 0x%hx", regname_get(instr.immed.reg), - instr.immed.offset, instr.immed.immed); - break; - case BEQ_O: case BGEZ_O: case BGTZ_O: - case BLEZ_O: case BLTZ_O: case BNE_O: - sprintf(buf, "%s, %hd, %hd\t%s", regname_get(instr.immed.reg), - instr.immed.offset, instr.immed.immed, - instruction_formAddress_comment(addr, - addr+instr.immed.immed)); - break; - default: - bail_with_error("Unknown immediate type instruction opcode (%d)!", - instr.immed.op); - break; - } - break; - case jump_instr_type: - switch (instr.jump.op) { - case JMPA_O: case CALL_O: - sprintf(buf, "%u\t%s", instr.jump.addr, - instruction_formAddress_comment(addr, instr.jump.addr)); - break; - case RTN_O: - // no arguments in this case - break; - default: - bail_with_error("Unknown jump type instruction opcode (%d)!", - instr.jump.op); - break; - } - break; - case syscall_instr_type: - switch (instr.syscall.code) { - case exit_sc: - sprintf(buf, "%hd", instr.syscall.offset); - break; - case print_str_sc: case print_int_sc: - case print_char_sc: case read_char_sc: - sprintf(buf, "%s, %hd", regname_get(instr.syscall.reg), - instr.syscall.offset); - break; - case start_tracing_sc: case stop_tracing_sc: - // no arguments, so nothing to do! - break; - } - break; - default: - bail_with_error("Unknown instruction type (%d) in instruction_assembly_form!", - it); - break; - } - - return instr_buf; -} - -// Requires: out is open and writable FILE -// print the header of the instruction output table on out -void instruction_print_table_heading(FILE *out) { - fprintf(out, "%s %s\n", "Address", "Instruction"); -} - -// Requires: out is an open FILE, and instr is found at address addr. -// Print addr on out, ": ", then the instruction's symbolic -// (assembly language) form, and finally a newline character (all on one line) -void instruction_print(FILE *out, address_type addr, bin_instr_t instr) { - fprintf(out, "%8u: %s\n", addr, instruction_assembly_form(addr, instr)); -} - -// Return the mnemonic for the given system call code -const char *instruction_syscall_mnemonic(syscall_type code) -{ - switch (code) { - case exit_sc: - return "EXIT"; - break; - case print_str_sc: - return "PSTR"; - break; - case print_int_sc: - return "PINT"; - break; - case print_char_sc: - return "PCH"; - break; - case read_char_sc: - return "RCH"; - break; - case start_tracing_sc: - return "STRA"; - break; - case stop_tracing_sc: - return "NOTR"; - break; - default: - bail_with_error("Unknown code (%u) in instruction_syscall_mnemonic", - code); - return "NEVERHAPPENS"; - break; - } -} - -// Requires: instr is a SYSCALL instruction -// (i.e., instr.syscall.op == OTHC_O and instr.syscall.func == SYS_F). -// Return the code field that tells what kind of system call is being made -syscall_type instruction_syscall_number(bin_instr_t instr) { - assert(instr.syscall.op == OTHC_O && instr.syscall.func == SYS_F); - return instr.syscall.code; -} - -// Requires: bi is a computational instruction (bi.comp.op == COMP_O). -// Return a string giving the assembly language mnemonic for bi's operation -const char *instruction_compFunc2name(bin_instr_t bi) { - assert(bi.comp.op == COMP_O); - switch (bi.comp.func) { - case NOP_F: - return "NOP"; - break; - case ADD_F: - return "ADD"; - break; - case SUB_F: - return "SUB"; - break; - case CPW_F: - return "CPW"; - break; - case CPR_F: - return "CPR"; - break; - case AND_F: - return "AND"; - break; - case BOR_F: - return "BOR"; - break; - case NOR_F: - return "NOR"; - break; - case XOR_F: - return "XOR"; - break; - case LWR_F: - return "LWR"; - break; - case SWR_F: - return "SWR"; - break; - case SCA_F: - return "SCA"; - break; - case LWI_F: - return "LWI"; - break; - case NEG_F: - return "NEG"; - break; - default: - bail_with_error("Unknown function code (%d) in instruction_compFunc2name", - bi.comp.func); - break; - } - return NULL; // should never happen -} - -// Requires: bi is an other computational instruction (bi.othc.op == OTHC_O). -// Return a string giving the assembly language mnemonic for bi's operation -const char *instruction_otherCompFunc2name(bin_instr_t bi) { - assert(bi.othc.op == OTHC_O); - switch (bi.othc.func) { - case LIT_F: - return "LIT"; - break; - case ARI_F: - return "ARI"; - break; - case SRI_F: - return "SRI"; - break; - case MUL_F: - return "MUL"; - break; - case DIV_F: - return "DIV"; - break; - case CFHI_F: - return "CFHI"; - break; - case CFLO_F: - return "CFLO"; - break; - case SLL_F: - return "SLL"; - break; - case SRL_F: - return "SRL"; - break; - case JMP_F: - return "JMP"; - break; - case CSI_F: - return "CSI"; - break; - case JREL_F: - return "JREL"; - break; - case SYS_F: - return instruction_syscall_mnemonic(instruction_syscall_number(bi)); - break; - default: - bail_with_error("Unknown function code (%d) in instruction_otherCompFunc2name", - bi.comp.func); - break; - } - return NULL; // should never happen -} diff --git a/instruction.h b/instruction.h deleted file mode 100755 index 0cc03c6..0000000 --- a/instruction.h +++ /dev/null @@ -1,178 +0,0 @@ -// $Id: instruction.h,v 1.5 2024/11/10 21:09:43 leavens Exp $ -#ifndef _INSTRUCTION_H -#define _INSTRUCTION_H -#include -#include -#include "machine_types.h" -#include "bof.h" - -// op codes in binary instructions for the SSM -typedef enum {COMP_O = 0, OTHC_O = 1, ADDI_O = 2, ANDI_O = 3, BORI_O = 4, - NORI_O = 5, XORI_O = 6, - BEQ_O = 7, BGEZ_O = 8, BGTZ_O = 9, BLEZ_O = 10, BLTZ_O = 11, - BNE_O = 12, JMPA_O = 13, CALL_O = 14, RTN_O = 15 - } op_code; - -// function codes in binary instructions for the SSM (when opcode is 0) -typedef enum {NOP_F = 0, ADD_F = 1, SUB_F = 2, CPW_F = 3, CPR_F = 4, - AND_F = 5, BOR_F = 6, NOR_F = 7, XOR_F = 8, - LWR_F = 9, SWR_F = 10, SCA_F = 11, LWI_F = 12, NEG_F = 13 - } func0_code; - -// function codes in binary instructions for the SSM (when opcode is 1) -typedef enum {LIT_F = 1, ARI_F = 2, SRI_F = 3, MUL_F = 4, DIV_F = 5, - CFHI_F = 6, CFLO_F = 7, SLL_F = 8, SRL_F = 9, JMP_F = 10, - CSI_F = 11, JREL_F = 12, SYS_F = 15 - } func1_code; - -// instruction types (each is a binary instruction format) -typedef enum {comp_instr_type, other_comp_instr_type, - immed_instr_type, jump_instr_type, syscall_instr_type, - error_instr_type - } instr_type; - -// system calls -typedef enum {exit_sc = 1, print_str_sc = 2, print_int_sc = 3, - print_char_sc = 4, read_char_sc = 5, - start_tracing_sc = 2046, stop_tracing_sc = 2047 -} syscall_type; - -// computational type instructions, with opcode 0 -typedef struct { - opcode_type op : 4; - reg_num_type rt : 3; // target register - offset_type ot : 9; // offset from target register - reg_num_type rs : 3; // source register - offset_type os : 9; // offset from source register - func_type func : 4; -} comp_instr_t; - -// other computational type instructions, with opcode 1, except system calls -typedef struct { - opcode_type op : 4; - reg_num_type reg : 3; - offset_type offset : 9; - arg_type arg : 12; - func_type func : 4; -} other_comp_instr_t; - -// system call instructions, with op field 1 and func field 15 -typedef struct { - opcode_type op : 4; - reg_num_type reg : 3; - offset_type offset : 9; - syscall_type code : 12; - func_type func : 4; -} syscall_instr_t; - -// immediate operand type instructions -// with signed immediate operands -typedef struct { - opcode_type op : 4; - reg_num_type reg : 3; - offset_type offset : 9; - immediate_type immed : 16; -} immed_instr_t; - -// immediate operand type instructions -// with unsigned immediate operands -typedef struct { - opcode_type op : 4; - reg_num_type reg : 3; - offset_type offset : 9; - uimmed_type uimmed : 16; -} uimmed_instr_t; - -// jump type instructions -typedef struct { - opcode_type op : 4; - address_type addr : 28; -} jump_instr_t; - -// binary instructions of any type -typedef union { - comp_instr_t comp; - other_comp_instr_t othc; - syscall_instr_t syscall; - immed_instr_t immed; - uimmed_instr_t uimmed; - jump_instr_t jump; -} bin_instr_t; - -// Return the type of the binary instruction given -extern instr_type instruction_type(bin_instr_t i); - -// Requires: bof is open for reading in binary -// Read a single instruction (in binary) from bf and return it, -// but exit with an error if there is a problem. -extern bin_instr_t instruction_read(BOFFILE bf); - -// Requires: bof is open for writing in binary -// Write the binary instruction bi to bf in binary, -// but exit with an error if there is a problem. -extern void instruction_write_bin_instr(BOFFILE bf, bin_instr_t bi); - -// Requires: bof is open for writing in binary -// Write the computational instruction oci to bf in binary, -// but exit with an error if there is a problem. -extern void instruction_write_compInstr(BOFFILE bf, comp_instr_t oci); - -// Requires: bof is open for writing in binary -// Write the other computational instruction oci to bf in binary, -// but exit with an error if there is a problem. -extern void instruction_write_otherCompInstr(BOFFILE bf, other_comp_instr_t oci); - -// Requires: bof is open for writing in binary -// Write the system instruction si to bf in binary, -// but exit with an error if there is a problem. -extern void instruction_write_syscallInstr(BOFFILE bf, syscall_instr_t si); - -// Requires: bof is open for writing in binary -// Write the immediate instruction ii with opcode op to bf in binary, -// but exit with an error if there is a problem. -extern void instruction_write_immedInstr(BOFFILE bf, immed_instr_t ii); - -// Requires: bof is open for writing in binary -// Write the immediate instruction ii with opcode op to bf in binary, -// but exit with an error if there is a problem. -extern void instruction_write_uimmedInstr(BOFFILE bf, uimmed_instr_t ii); - -// Requires: bof is open for writing in binary -// Write the jump instruction ji with opcode op to bf in binary, -// but exit with an error if there is a problem. -extern void instruction_write_jumpInstr(BOFFILE bf, jump_instr_t ji); - -// Return the assembly language name (mnemonic) for bi -extern const char *instruction_mnemonic(bin_instr_t bi); - -// Return a string containing the assembly language form of instr, -// which is found at address addr -extern const char *instruction_assembly_form(address_type addr, - bin_instr_t instr); - -// Requires: out is open and writable FILE -// print the header of the instruction output table on out -extern void instruction_print_table_heading(FILE *out); - -// Requires: out is an open FILE, and instr is found at address addr. -// Print addr on out, ": ", then the instruction's symbolic -// (assembly language) form, and finally a newline character (all on one line) -extern void instruction_print(FILE *out, address_type addr, bin_instr_t instr); - -// Return the mnemonic for the given system call code -extern const char *instruction_syscall_mnemonic(unsigned int code); - -// Requires: instr is a SYSCALL instruction -// (i.e., instr.syscall.op == OTHC_O and instr.syscall.func == SYS_F). -// Return the code field that tells what kind of system call is being made -extern syscall_type instruction_syscall_number(bin_instr_t instr); - -// Requires: bi is a computational instruction (bi.comp.op == COMP_O). -// Return a string giving the assembly language mnemonic for bi's operation -extern const char *instruction_compFunc2name(bin_instr_t bi); - -// Requires: bi is an other computational instruction (bi.othc.op == OTHC_O). -// Return a string giving the assembly language mnemonic for bi's operation -extern const char *instruction_otherCompFunc2name(bin_instr_t bi); - -#endif diff --git a/lexer.c b/lexer.c deleted file mode 100755 index 0763360..0000000 --- a/lexer.c +++ /dev/null @@ -1,6 +0,0 @@ -/* $Id: lexer.c,v 1.6 2024/10/23 13:38:20 leavens Exp $ */ - -#include "lexer.h" - -// All the functions declared in lexer.h are -// defined in the user code section of spl_lexer.l diff --git a/lexer.h b/lexer.h deleted file mode 100755 index 006536b..0000000 --- a/lexer.h +++ /dev/null @@ -1,39 +0,0 @@ -/* $Id: lexer.h,v 1.3 2024/10/23 13:38:20 leavens Exp $ */ -#ifndef _LEXER_H -#define _LEXER_H -#include - -// Requires: fname != NULL -// Requires: fname is the name of a readable file -// Initialize the lexer and start it reading -// from the given file name -extern void lexer_init(char *fname); - -// Return the next token in the input -extern int yylex(); - -// Return the name of the current file -extern const char *lexer_filename(); - -// Return the line number of the next token -extern unsigned int lexer_line(); - -// On standard output: -// Print a message about the file name of the lexer's input -// and then print a heading for the lexer's output. -extern void lexer_print_output_header(); - -// Have any errors been noted by the lexer? -extern bool lexer_has_errors(); - -// Print information about the token t to stdout -// followed by a newline -extern void lexer_print_token(int t, unsigned int tline, - const char *txt); - -/* Read all the tokens from the input file - * and print each token on standard output - * using the format in lexer_print_token */ -extern void lexer_output(); - -#endif diff --git a/lexer_utilities.c b/lexer_utilities.c deleted file mode 100755 index b0f9ed6..0000000 --- a/lexer_utilities.c +++ /dev/null @@ -1,8 +0,0 @@ -/* $Id: lexer_utilities.c,v 1.3 2024/11/13 14:08:23 leavens Exp $ */ -#include -#include -#include -#include "lexer_utilities.h" - -/* yyerror() is defined in spl_lexer.c (which is made from spl_lexer.l) */ -/* formatted_yyerror() is defined in utilities.c */ diff --git a/lexer_utilities.h b/lexer_utilities.h deleted file mode 100755 index 530dca4..0000000 --- a/lexer_utilities.h +++ /dev/null @@ -1,15 +0,0 @@ -/* $Id: lexer_utilities.h,v 1.1 2023/11/13 05:13:55 leavens Exp $ */ -#ifndef _LEXER_UTILITIES_H -#define _LEXER_UTILITIES_H - -// Report a syntax error on the current line on stderr. -// The output looks like: the filename, ":", the lexer's current line number, -// ": ", and then msg. -extern void yyerror(const char *filename, const char *msg); - -// Call yyerror to print an error message on stderr -// starting with the filename, ":", the lexer's current line number, ": ", -// and then the formatted message (as in sprintf) -extern void formatted_yyerror(const char *filename, const char *fmt, ...); - -#endif diff --git a/lexical_address.c b/lexical_address.c deleted file mode 100755 index 4215fec..0000000 --- a/lexical_address.c +++ /dev/null @@ -1,28 +0,0 @@ -/* $Id: lexical_address.c,v 1.3 2023/11/13 05:13:56 leavens Exp $ */ -#include "lexical_address.h" -#include "utilities.h" - -// Allocate and return a (fresh) lexical address -// where the levelsOutwards field is levelsOut -// and the offsetInAR field is the byte offset in the AR -lexical_address *lexical_address_create(unsigned int levelsOut, - unsigned int offset) -{ - lexical_address *ret = (lexical_address *) malloc(sizeof(lexical_address)); - if (ret == NULL) { - bail_with_error("No space to create a lexical_address!"); - } - ret->levelsOutward = levelsOut; - ret->offsetInAR = offset; - return ret; -} - -// Requires: out is not NULL and is open for writing -// Requires: la is not NULL -// Print the lexical address la in the form "(l,o)", -// where l is la->levelsOutwards and o is la->offsetInAR. -// Note: no newline or other spacing is added. -extern void lexical_address_print(FILE *out, lexical_address *la) -{ - fprintf(out, "(%d,%d)", la->levelsOutward, la->offsetInAR); -} diff --git a/lexical_address.h b/lexical_address.h deleted file mode 100755 index 973cd96..0000000 --- a/lexical_address.h +++ /dev/null @@ -1,23 +0,0 @@ -/* $Id: lexical_address.h,v 1.3 2023/11/13 05:13:56 leavens Exp $ */ -#ifndef _LEXICAL_ADDRESS_H -#define _LEXICAL_ADDRESS_H - -#include -#include - -typedef struct { - unsigned int levelsOutward; - unsigned int offsetInAR; // in bytes -} lexical_address; - -// Allocate and return a (fresh) lexical address -// where the levelsOutwards field is levelsOut -// and the offsetInAR field is the byte offset in the AR -extern lexical_address *lexical_address_create(unsigned int levelsOut, - unsigned int offset); - -// Requires: out is not NULL and is open for writing -// Requires: la is not NULL -extern void lexical_address_print(FILE *out, lexical_address *la); - -#endif diff --git a/literal_table.c b/literal_table.c deleted file mode 100644 index 264dd38..0000000 --- a/literal_table.c +++ /dev/null @@ -1,168 +0,0 @@ -#include -#include -#include -#include "literal_table.h" -#include "utilities.h" - -// constant table entries -typedef struct literal_table_entry_s -{ - struct literal_table_entry_s *next; - const char *text; - word_type value; - unsigned int offset; -} literal_table_entry_t; - -// the table of constants is a linked list of literal_table_entry_t's -// with first pointing to the first entry and last to the last one -static literal_table_entry_t *first; -static literal_table_entry_t *last; -static unsigned int next_word_offset; - -// Iteration state follows -static bool iterating; -static literal_table_entry_t *iteration_next; - -// Check the invariant -static void literal_table_okay() -{ - bool emp = literal_table_empty(); - assert(emp == (next_word_offset == 0)); - assert(emp == (first == NULL)); - assert(emp == (last == NULL)); -} - -// Return the size (in words/entries) in the literal table -unsigned int literal_table_size() -{ - return next_word_offset; -} - -// is the literal_table empty? -bool literal_table_empty() -{ - return next_word_offset == 0; -} - -// is the literal_table full? -bool literal_table_full() -{ - return false; -} - -// initialize the literal_table -void literal_table_initialize() -{ - first = NULL; - last = NULL; - next_word_offset = 0; - literal_table_okay(); - iterating = false; - iteration_next = NULL; - literal_table_okay(); -} - -// Requires: sought is the print form of value -// return the offset of sought/value if it is in the table -// otherwise return -1. -int literal_table_find_offset(const char *sought, word_type value) -{ - literal_table_okay(); - literal_table_entry_t *entry = first; - while (entry != NULL) - { - if (strcmp(entry->text, sought) == 0) - { - return entry->offset; - } - entry = entry->next; - } - return -1; -} - -// Requires: sought is the print form of value -// Return true just when sought is in the table -bool literal_table_present(const char *sought, word_type value) -{ - literal_table_okay(); - return literal_table_find_offset(sought, value) >= 0; -} - -// Return the word offset for val_string/value -// entering it in the table if it's not already present -unsigned int literal_table_lookup(const char *val_string, - word_type value) -{ - int ret = literal_table_find_offset(val_string, value); - if (ret >= 0) - { - // don't insert if it's already present - return ret; - } - // it's not already present, so insert it - literal_table_entry_t *new_entry = (literal_table_entry_t *)malloc(sizeof(literal_table_entry_t)); - new_entry->text = val_string; - new_entry->value = value; - new_entry->next = NULL; - ret = next_word_offset; - new_entry->offset = next_word_offset++; - if (new_entry == NULL) - { - bail_with_error("No space to allocate new literal table entry!"); - } - if (first == NULL) - { - first = new_entry; - last = new_entry; - } - else - { - last->next = new_entry; - last = new_entry; - } - literal_table_okay(); - return ret; -} - -// === iteration helpers === - -// Start an iteration over the literal table -// which can extract the elements -void literal_table_start_iteration() -{ - if (iterating) - { - bail_with_error("Attempt to start literal_table iterating when already iterating!"); - } - literal_table_okay(); - iterating = true; - iteration_next = first; -} - -// End the current iteration over the literal table. -void literal_table_end_iteration() -{ - iterating = false; -} - -// Is there another float in the literal table? -bool literal_table_iteration_has_next() -{ - literal_table_okay(); - bool ret = (iteration_next != NULL); - if (!ret) - { - iterating = false; - } - return ret; -} - -// Return the next float in the literal table -// and advance the iteration -word_type literal_table_iteration_next() -{ - assert(iteration_next != NULL); - float ret = iteration_next->value; - iteration_next = iteration_next->next; - return ret; -} \ No newline at end of file diff --git a/literal_table.h b/literal_table.h deleted file mode 100644 index d8f3360..0000000 --- a/literal_table.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef _LITERAL_TABLE_H -#define _LITERAL_TABLE_H -#include -#include "machine_types.h" - -// Return the size (in words/entries) in the literal table -extern unsigned int literal_table_size(); - -// is the literal_table empty? -extern bool literal_table_empty(); - -// is the literal_table full? -extern bool literal_table_full(); - -// initialize the literal_table -extern void literal_table_initialize(); - -// Return the offset of sought if it is in the table, -// otherwise return -1. -extern int literal_table_find_offset(const char *sought, word_type value); - -// Return true just when sought is in the table -extern bool literal_table_present(const char *sought, word_type value); - -// Return the word offset for val_string/value -// entering it in the table if it's not already present -extern unsigned int literal_table_lookup(const char *val_string, - word_type value); - -// === iteration helpers === - -// Start an iteration over the literal table -// which can extract the elements -extern void literal_table_start_iteration(); - -// End the current iteration over the literal table. -extern void literal_table_end_iteration(); - -// Is there another float in the literal table? -extern bool literal_table_iteration_has_next(); - -// Return the next word_type in the literal table -// and advance the iteration -extern word_type literal_table_iteration_next(); - -#endif \ No newline at end of file diff --git a/machine_types.c b/machine_types.c deleted file mode 100755 index 5466e82..0000000 --- a/machine_types.c +++ /dev/null @@ -1,100 +0,0 @@ -// $Id: machine_types.c,v 1.2 2024/10/23 13:38:20 leavens Exp $ -#include "machine_types.h" -#include "utilities.h" - -// Return the sign-extended equivalent of i -word_type machine_types_sgnExt(immediate_type i) { - return i; // preserves the value -} - -// Return the zero-extended equivalent of i -uword_type machine_types_zeroExt(immediate_type i) { - return (uword_type) i; -} - -// Return the offset given by o, -// which is the sign extension of o -word_type machine_types_formOffset(immediate_type o) { - return machine_types_sgnExt(o); -} - -// Return an address formed by concatenating the instruction address, a, -// with the high-order (4) bits of the PC. -address_type machine_types_formAddress(address_type PC, address_type a) { - return ((0xF0000000 & PC) | (0x0FFFFFF & a)); -} - -// Check that o can be represented as an offset field in an instruction -// bail with an error message if not (so doesn't return if wrong) -void machine_types_check_fits_in_offset(word_type o) -{ - if (o > NINEBITSMAXSIGNED) { - bail_with_error("Offset is too large: %d", o); - } else if (o < NINEBITSMINSIGNED) { - bail_with_error("Offset is too small: %d", o); - } -} - -// Check that arg can be represented as an arg field in an instruction, -// bail with an error message if not (so doesn't return if wrong) -void machine_types_check_fits_in_arg(word_type arg) -{ - if (arg > TWELVEBITSMAXSIGNED) { - bail_with_error("12 bit argument is too large: %d", arg); - } else if (arg < TWELVEBITSMINSIGNED) { - bail_with_error("12 bit argument is too small: %d", arg); - } -} - -// Check that s can be represented as a shift field in an instruction, -// bail with an error message if not (so doesn't return if wrong) -void machine_types_check_fits_in_shift(word_type s) -{ - if (s > TWELVEBITSMAXUNSIGNED) { - bail_with_error("Shift is too large: %u", s); - } -} - -// Check that immed can be represented as a signed immediate field, -// bail with an error message if not (so doesn't return if wrong) -void machine_types_check_fits_in_immed(word_type immed) -{ - if (immed > SIXTEENBITSMAXSIGNED) { - bail_with_error("Immediate argument is too large: %d", - immed); - } else if (immed < SIXTEENBITSMINSIGNED) { - bail_with_error("Immediate argument is too small: %d", - immed); - } -} - -// Check that arg can be represented as unsigned immediate field, -// bail with an error message if not (so doesn't return if wrong) -void machine_types_check_fits_in_uimmed(word_type arg) -{ - if (arg > SIXTEENBITSMAXUNSIGNED) { - bail_with_error("Unsigned immediate argument is too large: %u", arg); - } -} - -// Check that addr can be represented as an address field in an instruction, -// bail with an error message if not (so doesn't return if wrong) -void machine_types_check_fits_in_addr(address_type addr) -{ - if (addr > TWENTYEIGHTBITSMAXUNSIGNED) { - bail_with_error("Address is too large: %u", addr); - } -} - -// Return the nearest multiple of BYTES_PER_WORD -// that is greater than or equal to n -int machine_types_round_up_to_wordsize(unsigned int n) -{ - int rem = n % BYTES_PER_WORD; - if (rem == 0) { - return n; - } else { - // assert(((n + (BYTES_PER_WORD - rem)) % BYTES_PER_WORD) == 0); - return n + (BYTES_PER_WORD - rem); - } -} diff --git a/machine_types.h b/machine_types.h deleted file mode 100755 index 01bcd1c..0000000 --- a/machine_types.h +++ /dev/null @@ -1,94 +0,0 @@ -// $Id: machine_types.h,v 1.3 2024/10/23 13:38:20 leavens Exp $ -// Machine Types for the Simplified Stack Machine (SSM) -#ifndef _MACHINE_TYPES_H -#define _MACHINE_TYPES_H - -#define BYTES_PER_WORD 4 - -// operation codes -typedef unsigned short opcode_type; - -// registers encoded in instructions -typedef unsigned short reg_num_type; - -// offset values (which are signed) encoded in instructions -typedef short offset_type; - -// function codes in computational instructions -typedef unsigned short func_type; - -// argument values (signed) encoded in instructions -typedef short arg_type; - -// shift values encoded in other computational instructions -typedef unsigned short shift_type; - -// immediate operands encoded in instructions -typedef int immediate_type; - -// unsigned immediate operands in instructions -typedef unsigned int uimmed_type; - -// addresses, assuming ints are 32 bits -typedef unsigned int address_type; - -// machine words, assuming ints are 32 bits -typedef int word_type; - -// machine words, unsigned -typedef unsigned int uword_type; - -// bytes, assuming chars are 8 bits -typedef unsigned char byte_type; - -#define NINEBITSMAXSIGNED 0xff -#define NINEBITSMINSIGNED -512 -#define TWELVEBITSMAXSIGNED 0x7ff -#define TWELVEBITSMINSIGNED -0x800 -#define TWELVEBITSMAXUNSIGNED 0xfff -#define SIXTEENBITSMAXSIGNED 0777 -#define SIXTEENBITSMINSIGNED -01000 -#define SIXTEENBITSMAXUNSIGNED 0xffff -#define TWENTYEIGHTBITSMAXUNSIGNED 0xfffffff - -// Return the sign-extended equivalent of i -extern word_type machine_types_sgnExt(immediate_type i); - -// Return the zero-extended equivalent of i -extern uword_type machine_types_zeroExt(immediate_type i); - -// Return the offset given by o, -// which is the sign extension of o -extern word_type machine_types_formOffset(immediate_type o); - -// Return an address formed by concatenating the instruction address, a, -// with the high-order (4) bits of the PC. -extern address_type machine_types_formAddress(address_type PC, address_type a); - -// Check that o can be represented as an offset field in an instruction -// bail with an error message if not (so doesn't return if wrong) -extern void machine_types_check_fits_in_offset(word_type o); - -// Check that arg can be represented as an arg field in an instruction, -// bail with an error message if not (so doesn't return if wrong) -extern void machine_types_check_fits_in_arg(word_type arg); - -// Check that arg can be represented as a shift field in an instruction, -// bail with an error message if not (so doesn't return if wrong) -extern void machine_types_check_fits_in_shift(word_type arg); - -// Check that immed can be represented as a signed immediate field, -// bail with an error message if not (so doesn't return if wrong) -extern void machine_types_check_fits_in_immed(word_type immed); - -// Check that arg can be represented as unsigned immediate field, -// bail with an error message if not (so doesn't return if wrong) -extern void machine_types_check_fits_in_uimmed(word_type arg); - -// Check that addr can be represented as an address field in an instruction, -// bail with an error message if not (so doesn't return if wrong) -extern void machine_types_check_fits_in_addr(address_type addr); - -// the following line is for the documentation -// ... -#endif diff --git a/parser.c b/parser.c deleted file mode 100755 index 69bbb84..0000000 --- a/parser.c +++ /dev/null @@ -1,22 +0,0 @@ -/* $Id: parser.c,v 1.6 2023/11/13 14:08:44 leavens Exp $ */ -#include -#include -#include "lexer.h" -#include "parser.h" -#include "utilities.h" - -// Parse a PL/0 program from the given file, -// putting the AST into progast -extern int yyparse (char const *file_name); - -// Parse a PL/0 program using the tokens from the lexer, -// returning the program's AST -extern block_t parseProgram(char *file_name) -{ - lexer_init(file_name); - int rc = yyparse(file_name); - if (rc != 0) { - exit(rc); - } - return progast; -} diff --git a/parser.h b/parser.h deleted file mode 100755 index 02bd7ce..0000000 --- a/parser.h +++ /dev/null @@ -1,13 +0,0 @@ -/* $Id: parser.h,v 1.3 2023/11/13 14:08:44 leavens Exp $ */ -// This header file defines the externally-visible entry points to the parser -#ifndef _PARSER_H -#define _PARSER_H -#include "ast.h" - -extern block_t progast; - -// Parse a PL/0 program using the tokens from the lexer, -// returning the program's AST -extern block_t parseProgram(char *file_name); - -#endif diff --git a/parser_types.h b/parser_types.h deleted file mode 100755 index b98bc78..0000000 --- a/parser_types.h +++ /dev/null @@ -1,11 +0,0 @@ -/* $Id: parser_types.h,v 1.1 2023/11/13 05:13:59 leavens Exp $ */ -#ifndef _PARSER_TYPES_H -#define _PARSER_TYPES_H - -#include "ast.h" - -// The type of Bison's parser stack elements (parse values) -typedef AST YYSTYPE; -#define YYSTYPE_IS_DECLARED 1 - -#endif diff --git a/regname.c b/regname.c deleted file mode 100755 index 545fdf4..0000000 --- a/regname.c +++ /dev/null @@ -1,12 +0,0 @@ -// $Id: regname.c,v 1.2 2024/10/23 13:38:20 leavens Exp $ -#include "regname.h" - -static const char *regnames[NUM_REGISTERS] = { - "$gp", "$sp", "$fp", "$r3", "$r4", "$r5", "$r6", "$ra" }; - -// requires 0 <= n && n < NUM_REGISTERS -// Return the standard symbolic name for n -const char *regname_get(reg_num_type n) -{ - return regnames[n]; -} diff --git a/regname.h b/regname.h deleted file mode 100755 index 56fe926..0000000 --- a/regname.h +++ /dev/null @@ -1,18 +0,0 @@ -// $Id: regname.h,v 1.2 2024/10/23 13:38:20 leavens Exp $ -#ifndef _REGNAME_H -#define _REGNAME_H -#include "machine_types.h" - -#define NUM_REGISTERS 8 - -// some important register numbers in the ISA -#define GP 0 -#define SP 1 -#define FP 2 -#define RA 7 - -// requires 0 <= n && n < NUM_REGISTERS -// Return the standard symbolic name for n -extern const char *regname_get(reg_num_type n); -#endif - diff --git a/scope.c b/scope.c deleted file mode 100755 index 5127d41..0000000 --- a/scope.c +++ /dev/null @@ -1,121 +0,0 @@ -/* $Id: scope.c,v 1.5 2023/11/13 12:51:58 leavens Exp $ */ -#include -#include -#include -#include -#include "scope.h" -#include "utilities.h" - -// Allocate a fresh scope symbol table and return (a pointer to) it. -// Issues an error message (on stderr) if there is no space -// and exits with a failure error code in that case. -scope_t *scope_create() -{ - scope_t *new_s - = (scope_t *) malloc(sizeof(scope_t)); - if (new_s == NULL) { - bail_with_error("No space for new scope_t!"); - } - new_s->size = 0; - new_s->loc_count = 0; - for (int j = 0; j < MAX_SCOPE_SIZE; j++) { - new_s->entries[j] = NULL; - } - return new_s; -} - -// Return the number of constant and variables declarations -// that have been added to this scope. -extern unsigned int scope_loc_count(scope_t *s) -{ - return s->loc_count; -} - -// Return the current scope's size (number of declared ids). -unsigned int scope_size(scope_t *s) -{ - return s->size; -} - -// Is the current scope full? -bool scope_full(scope_t *s) -{ - return scope_size(s) >= MAX_SCOPE_SIZE; -} - -// Requires: assoc != NULL && !scope_full() && !scope_defined(assoc->id); -// Add an association from the given name to the given id attributes -// in the current scope. -// If assoc->attrs->kind != procedure_idk, -// then this stores the scope_count value into assoc->attrs->offset_count -// and then increases loc_count by 1. -static void scope_add(scope_t *s, scope_assoc_t *assoc) -{ - // assert(assoc != NULL); - // assert(!scope_full()); - // assert(!scope_defined(assoc->id)); - if (assoc->attrs->kind != procedure_idk) { - (assoc->attrs->offset_count) = (s->loc_count)++; - } - s->entries[(s->size)++] = assoc; - // fprintf(stderr, "assoc->attrs->offset_count is %d\n", - // assoc->attrs->offset_count); -} - -// Requires: !scope_defined(name) && attrs != NULL; -// Modify the current scope symbol table to -// add an association from the given name to the given id_attrs attrs, -// and if attrs->kind != procedure, -// then this stores the loc_count value into attrs->offset_count -// and then increases the loc_count for this scope by 1. -void scope_insert(scope_t *s, const char *name, id_attrs *attrs) -{ - // assert(!scope_defined(name)); - // assert(attrs != NULL); - // debug_print("Running scope_insert for name "%s\"\n", name); - scope_assoc_t *new_assoc = malloc(sizeof(scope_assoc_t)); - if (new_assoc == NULL) { - bail_with_error("No space for association!"); - } - new_assoc->id = name; - new_assoc->attrs = attrs; - scope_add(s, new_assoc); -} - -// Requires: name != NULL; -// Is the given name associated with some attributes in the current scope? -bool scope_defined(scope_t *s, const char *name) -{ - // assert(s != NULL); - // assert(name != NULL); - // debug_print("entering scope_defined for \"%s\"\n", name); - return scope_lookup(s, name) != NULL; -} - -// Requires: name != NULL and scope_initialize() has been called previously. -// Return (a pointer to) the attributes of the given name in the current scope -// or NULL if there is no association for name. -id_attrs *scope_lookup(scope_t *s, const char *name) -{ - int i; - // assert(name != NULL); - // assert(s != NULL); - // debug_print("Entering scope_lookup for \"%s\"\n", name); - for (i = 0; i < s->size; i++) { - // assert(s != NULL); - // assert(s->entries != NULL); - // assert(0 <= i && i < s->size); - // assert(s->entries[i] != NULL); - // assert(s->entries[i]->id != NULL); - // debug_print("Past asserts in scope_lookup loop\n"); - // debug_print("Length of name is %d\n", strlen(name)); - if (strcmp(s->entries[i]->id, name) == 0) { - // debug_print("scope_lookup(\"%s\") returning attributes\n", - // name); - return s->entries[i]->attrs; - } - } - // assert(i == s->size); - // debug_print("The scope_lookup call on \"%s\" returns NULL\n", name); - return NULL; -} diff --git a/scope.h b/scope.h deleted file mode 100755 index b488344..0000000 --- a/scope.h +++ /dev/null @@ -1,55 +0,0 @@ -/* $Id: scope.h,v 1.3 2023/11/13 12:51:59 leavens Exp $ */ -#ifndef _SCOPE_H -#define _SCOPE_H - -#include -#include "ast.h" -#include "machine_types.h" -#include "id_attrs.h" - -// Maximum number of declarations that can be stored in a scope -#define MAX_SCOPE_SIZE 4096 - -typedef struct { - const char *id; - id_attrs *attrs; -} scope_assoc_t; - -// Invariant: 0 <= size < MAX_SCOPE_SIZE; -typedef struct scope_s { - unsigned int size; - unsigned int loc_count; // number of consts and vars in this scope - scope_assoc_t *entries[MAX_SCOPE_SIZE]; -} scope_t; - -// Allocate a fresh scope symbol table and return (a pointer to) it. -// Issues an error message (on stderr) if there is no space -// and exits with a failure error code in that case. -extern scope_t *scope_create(); - -// Return the number of constant and variables declarations -// that have been added to this scope. -extern address_type scope_loc_count(scope_t *s); - -// Return the number of declared identifier associations in s -extern unsigned int scope_size(scope_t *s); - -// Is the current scope full? -extern bool scope_full(scope_t *s); - -// Is the given name associated with some attributes in the current scope? -extern bool scope_defined(scope_t *s, const char *name); - -// Requires: !scope_defined(name) && attrs != NULL; -// Modify the current scope symbol table to -// add an association from the given name to the given id_attrs attrs, -// and if attrs->id_kind != procedure, -// then this stores the next_loc_offset value into attrs->loc_offset -// and then increases the next_loc_offset for this scope by 1. -extern void scope_insert(scope_t *s, const char *name, id_attrs *attrs); - -// Return (a pointer to) the attributes of the given name in the current scope -// or NULL if there is no association for name. -extern id_attrs *scope_lookup(scope_t *s, const char *name); - -#endif diff --git a/scope_check.c b/scope_check.c deleted file mode 100755 index fe712e7..0000000 --- a/scope_check.c +++ /dev/null @@ -1,411 +0,0 @@ -/* $Id: scope_check.c,v 1.21 2024/11/13 15:23:58 leavens Exp $ */ -#include -#include -#include -#include "scope_check.h" -#include "id_attrs.h" -#include "file_location.h" -#include "ast.h" -#include "utilities.h" -#include "symtab.h" -#include "scope_check.h" - -// Requires: prog != NULL. -// The pointer passed to this function should point to the AST -// used by the compiler to generate code, so that the changes -// made (to the id_use fields) are communicated to the code generator. -// Build the symbol table for the given program AST -// and Check the given program AST for duplicate declarations -// or uses of identifiers that were not declared. -// Modifies the given AST to have appropriate id_use pointers. -void scope_check_program(block_t *prog) -{ - scope_check_block(prog); -} - -// build the symbol table and check the declarations in blk -// Modifies the given AST to have appropriate id_use pointers. -void scope_check_block(block_t *blk) -{ - symtab_enter_scope(); - scope_check_constDecls(blk->const_decls); - scope_check_varDecls(blk->var_decls); - scope_check_procDecls(&(blk->proc_decls)); - scope_check_stmts(&(blk->stmts)); - symtab_leave_scope(); -} - -// build the symbol table and check the declarations in cds -// Modifies the given AST to have appropriate id_use pointers. -void scope_check_constDecls(const_decls_t cds) -{ - const_decl_t *dcl = cds.start; - while (dcl != NULL) { - scope_check_constDecl(*(dcl)); - dcl = dcl->next; - } -} - -// build the symbol table and check the const declaration cd -// and add its const-defs to the current scope's symbol table -// or produce an error if these names have already been declared -// Modifies the given AST to have appropriate id_use pointers. -void scope_check_constDecl(const_decl_t cd) -{ - scope_check_const_def_list(cd.const_def_list); -} - -// build the symbol table and check the const definitions cdfs -// and add the declared names to the current scope's symbol table -// or produce an error if these names have already been declared -// Modifies the given AST to have appropriate id_use pointers. -void scope_check_const_def_list(const_def_list_t cdl) -{ - const_def_t *cdf = cdl.start; - while (cdf != NULL) { - scope_check_constDef(*(cdf)); - cdf = cdf->next; - } -} - -// Put the given name, which is to be declared with kind k, -// and has its declaration at the given file location (floc), -// into the current scope's symbol table at the offset scope_size(). -// Modifies the given AST to have appropriate id_use pointers. -static void add_ident_to_scope(const char *name, id_kind k, file_location floc) -{ - id_use *idu = symtab_lookup(name); - if (idu != NULL && idu->levelsOutward == 0) { - bail_with_prog_error(floc, - "%s \"%s\" is already declared as a %s", - id_attrs_id_kind_string(k), - name, - id_attrs_id_kind_string( - id_use_get_attrs(idu)->kind)); - } else { - symtab_insert(name, - id_attrs_create(floc, k, symtab_scope_loc_count())); - } -} - -// build the symbol table and check the const definition cdf -// and add the declared name to the current scope's symbol table -// or produce an error if this name has already been declared -void scope_check_constDef(const_def_t cdf) -{ - add_ident_to_scope(cdf.ident.name, constant_idk, *(cdf.file_loc)); -} - -// build the symbol table and check the declarations in vds -void scope_check_varDecls(var_decls_t vds) -{ - var_decl_t *vdp = vds.var_decls; - while (vdp != NULL) { - scope_check_varDecl(*vdp); - vdp = vdp->next; - } -} - -// check the var declaration vd -// and add the declared names to the current scope's symbol table -// or produce an error if the names have already been declared -void scope_check_varDecl(var_decl_t vd) -{ - scope_check_varIdentList(vd.ident_list); -} - -// check the identifiers from a var declaration, as given in ids -// and add the declared names to the current scope's symbol table -// or produce an error if the names have already been declared -void scope_check_varIdentList(ident_list_t idl) -{ - ident_t *idp = idl.start; - while (idp != NULL) { - add_ident_to_scope(idp->name, variable_idk, *(idp->file_loc)); - idp = idp->next; - } -} - -// build the symbol table and check the declarations in pds -// Modifies the given AST to have appropriate id_use pointers. -void scope_check_procDecls(proc_decls_t *pds) -{ - proc_decl_t *pdp = pds->proc_decls; - while (pdp != NULL) { - scope_check_procDecl(pdp); - pdp = pdp->next; - } -} - -// check the procedure declaration pd -// and add it to the current scope's symbol table -// or produce an error if its name has already been declared -// Modifies the given AST to have appropriate id_use pointers. -void scope_check_procDecl(proc_decl_t *pd) -{ - // add name to scope first, so that the procedure can be recursive - add_ident_to_scope(pd->name, procedure_idk, *(pd->file_loc)); - scope_check_block(pd->block); -} - -// check all the statement in stmts to make sure that -// all idenfifiers referenced in them have been declared -// (if not, then produce an error) -// Modifies the given AST to have appropriate id_use pointers. -void scope_check_stmts(stmts_t *stmts) -{ - if (stmts->stmts_kind != empty_stmts_e) { - scope_check_stmtList(&(stmts->stmt_list)); - } -} - -// check all the statement in stmt_list to make sure that -// all idenfifiers referenced in them have been declared -// (if not, then produce an error) -// Modifies the given AST to have appropriate id_use pointers. -void scope_check_stmtList(stmt_list_t *stmt_list) -{ - stmt_t *s = stmt_list->start; - while (s != NULL) { - scope_check_stmt(s); - s = s->next; - } -} - -// check the statement to make sure that -// all idenfifiers referenced in it have been declared -// (if not, then produce an error). -// Modifies the given AST to have appropriate id_use pointers. -void scope_check_stmt(stmt_t *stmt) -{ - switch (stmt->stmt_kind) { - case assign_stmt: - scope_check_assignStmt(&(stmt->data.assign_stmt)); - break; - case call_stmt: - scope_check_callStmt(&(stmt->data.call_stmt)); - break; - case if_stmt: - scope_check_ifStmt(&(stmt->data.if_stmt)); - break; - case while_stmt: - scope_check_whileStmt(&(stmt->data.while_stmt)); - break; - case read_stmt: - scope_check_readStmt(&(stmt->data.read_stmt)); - break; - case print_stmt: - scope_check_printStmt(&(stmt->data.print_stmt)); - print_stmt_t ps = stmt->data.print_stmt; - if (ps.expr.expr_kind == expr_ident) { - assert(ps.expr.data.ident.idu != NULL); - } - break; - case block_stmt: - scope_check_blockStmt(&(stmt->data.block_stmt)); - break; - default: - bail_with_error("Unknown stmt_kind (%d) in scope_check_stmt!", - stmt->stmt_kind); - break; - } -} - -// check the statement to make sure that -// all idenfifiers referenced in it have been declared -// (if not, then produce an error). -// Modifies the given AST to have appropriate id_use pointers. -void scope_check_assignStmt(assign_stmt_t *stmt) -{ - stmt->idu = scope_check_ident_declared(*(stmt->file_loc), stmt->name); - id_attrs attrs = *(stmt->idu->attrs); - if (attrs.kind != variable_idk) { - bail_with_prog_error(attrs.file_loc, - "Must be a variable on the left-hand side of an assignment statement, not the %s \"%s\"", - id_attrs_id_kind_string(attrs.kind), - stmt->name); - } - scope_check_expr(stmt->expr); -} - -// check the statement to make sure that -// the procedure being called has been declared -// (if not, then produce an error). -// Modifies the given AST to have appropriate id_use pointers. -void scope_check_callStmt(call_stmt_t *stmt) -{ - stmt->idu = scope_check_ident_declared(*(stmt->file_loc), stmt->name); -} - -// check the statement to make sure that -// all idenfifiers referenced in it have been declared -// (if not, then produce an error). -// Modifies the given AST to have appropriate id_use pointers. -void scope_check_blockStmt(block_stmt_t *stmt) -{ - scope_check_block(stmt->block); -} - - -// check the statement to make sure that -// all idenfifiers referenced in it have been declared -// (if not, then produce an error). -// Modifies the given AST to have appropriate id_use pointers. -void scope_check_ifStmt(if_stmt_t *stmt) -{ - scope_check_condition(&(stmt->condition)); - scope_check_stmts(stmt->then_stmts); - if (stmt->else_stmts != NULL) { - scope_check_stmts(stmt->else_stmts); - } -} - -// check the statement to make sure that -// all idenfifiers referenced in it have been declared -// (if not, then produce an error). -// Modifies the given AST to have appropriate id_use pointers. -void scope_check_whileStmt(while_stmt_t *stmt) -{ - scope_check_condition(&(stmt->condition)); - scope_check_stmts(stmt->body); -} - -// Check the statement to make sure that -// all idenfifiers referenced in it have been declared -// (if not, then produce an error). -// Modifies the given AST to have appropriate id_use pointers. -void scope_check_readStmt(read_stmt_t *stmt) -{ - stmt->idu = scope_check_ident_declared(*(stmt->file_loc), stmt->name); - id_attrs attrs = *(stmt->idu->attrs); - if (attrs.kind != variable_idk) { - bail_with_prog_error(attrs.file_loc, - "The name (%s) in a read statement must be a variable, not a %s", - stmt->name, - id_attrs_id_kind_string(attrs.kind)); - } -} - -// check the statement to make sure that -// all idenfifiers referenced in it have been declared -// (if not, then produce an error). -// Modifies the given AST to have appropriate id_use pointers. -void scope_check_printStmt(print_stmt_t *stmt) -{ - scope_check_expr(&(stmt->expr)); - if (stmt->expr.expr_kind == expr_ident) { - assert(stmt->expr.data.ident.idu != NULL); - } -} - -// check the condition to make sure that -// all idenfifiers referenced in it have been declared -// (if not, then produce an error). -// Modifies the given AST to have appropriate id_use pointers. -void scope_check_condition(condition_t *cond) -{ - switch (cond->cond_kind){ - case ck_db: - scope_check_db_condition(&(cond->data.db_cond)); - break; - case ck_rel: - scope_check_rel_op_condition(&(cond->data.rel_op_cond)); - break; - default: - bail_with_error("Unexpected type_tag (%d) in scope_check_cond!", - cond->cond_kind); - break; - } -} - -// check the condition to make sure that -// all idenfifiers referenced in it have been declared -// (if not, then produce an error). -// Modifies the given AST to have appropriate id_use pointers. -void scope_check_db_condition(db_condition_t *cond) -{ - scope_check_expr(&(cond->dividend)); - scope_check_expr(&(cond->divisor)); -} - -// check the condition to make sure that -// all idenfifiers referenced in it have been declared -// (if not, then produce an error). -// Modifies the given AST to have appropriate id_use pointers. -void scope_check_rel_op_condition(rel_op_condition_t *cond) -{ - scope_check_expr(&(cond->expr1)); - scope_check_expr(&(cond->expr2)); -} - -// check the expresion to make sure that -// all idenfifiers referenced in it have been declared -// (if not, then produce an error). -// Modifies the given AST to have appropriate id_use pointers. -void scope_check_expr(expr_t *exp) -{ - switch (exp->expr_kind) { - case expr_ident: - scope_check_ident(&(exp->data.ident)); - assert(exp->data.ident.idu != NULL); - break; - case expr_negated: - scope_check_expr(exp->data.negated.expr); - break; - case expr_bin: - scope_check_binary_op_expr(&(exp->data.binary)); - break; - case expr_number: - // no identifiers are possible in this case, so just return - break; - default: - bail_with_error("Unexpected expr_kind_e (%d) in scope_check_expr!", - exp->expr_kind); - break; - } -} - -// check that the given name has been declared, -// if not, then produce an error using the file_location (floc) given. -// Modifies the given AST to have appropriate id_use pointers. -void scope_check_ident(ident_t *id) -{ - file_location floc = *(id->file_loc); - const char *name = id->name; - id_use *idu = scope_check_ident_declared(floc, name); - if (idu == NULL) { - bail_with_prog_error(floc, - "identifier \"%s\" has not been declared!", - name); - } - id->idu = idu; -} - -// check the expression (exp) to make sure that -// all idenfifiers referenced in it have been declared -// (if not, then produce an error) -void scope_check_binary_op_expr(binary_op_expr_t *exp) -{ - scope_check_expr(exp->expr1); - scope_check_expr(exp->expr2); -} - -// Check that the given name has been declared, -// if so, then return an id_use -// (containing the attributes) for that name, -// otherwise, produce an error -// using the file_location (floc) given. -id_use *scope_check_ident_declared( - file_location floc, - const char *name) -{ - id_use *ret = symtab_lookup(name); - if (ret == NULL) { - bail_with_prog_error(floc, - "identifier \"%s\" is not declared!", - name); - } - id_attrs *ret_attrs = id_use_get_attrs(ret); - assert(ret_attrs != NULL); - return ret; -} diff --git a/scope_check.h b/scope_check.h deleted file mode 100755 index cf678dd..0000000 --- a/scope_check.h +++ /dev/null @@ -1,166 +0,0 @@ -/* $Id: scope_check.h,v 1.9 2024/11/10 12:54:14 leavens Exp $ */ -#ifndef _SCOPE_CHECK_H -#define _SCOPE_CHECK_H -#include "ast.h" - -// Requires: prog != NULL. -// The pointer passed to this function should point to the AST -// used by the compiler to generate code, so that the changes -// made (to the id_use fields) are communicated to the code generator. -// Build the symbol table for the given program AST -// and Check the given program AST for duplicate declarations -// or uses of identifiers that were not declared. -// Modifies the given AST to have appropriate id_use pointers. -extern void scope_check_program(block_t *prog); - -// build the symbol table and check the declarations in blk -// Modifies the given AST to have appropriate id_use pointers. -extern void scope_check_block(block_t *blk); - -// build the symbol table and check the declarations in cds -extern void scope_check_constDecls(const_decls_t cds); - -// build the symbol table and check the const declaration cd -// and add its const-defs to the current scope's symbol table -// or produce an error if these names have already been declared -extern void scope_check_constDecl(const_decl_t cd); - -// build the symbol table and check the const definitions cdfs -// and add the declared names to the current scope's symbol table -// or produce an error if these names have already been declared -// Modifies the given AST to have appropriate id_use pointers. -extern void scope_check_const_def_list(const_def_list_t cdl); - -// build the symbol table and check the const definition cdf -// and add the declared name to the current scope's symbol table -// or produce an error if its name has already been declared -extern void scope_check_constDef(const_def_t cdf); - -// build the symbol table and check the declarations in vds -extern void scope_check_varDecls(var_decls_t vds); - -// check the var declaration vd -// and add the declared names to the current scope's symbol table -// or produce an error if the names have already been declared -extern void scope_check_varDecl(var_decl_t vd); - -// check the identifiers from a var declaration, as given in ids -// and add the declared names to the current scope's symbol table -// or produce an error if the names have already been declared -// Modifies the given AST to have appropriate id_use pointers. -extern void scope_check_varIdentList(ident_list_t ident_list); - -// build the symbol table and check the declarations in pds -extern void scope_check_procDecls(proc_decls_t *pds); - -// check the procedure declaration pd -// and add it to the current scope's symbol table -// or produce an error if its name has already been declared -// Modifies the given AST to have appropriate id_use pointers. -extern void scope_check_procDecl(proc_decl_t *pd); - -// check all the statement in stmts to make sure that -// all idenfifiers referenced in them have been declared -// (if not, then produce an error) -// Modifies the given AST to have appropriate id_use pointers. -extern void scope_check_stmts(stmts_t *stmts); - -// check all the statement in stmt_list to make sure that -// all idenfifiers referenced in them have been declared -// (if not, then produce an error) -// Modifies the given AST to have appropriate id_use pointers. -extern void scope_check_stmtList(stmt_list_t *stmt_list); - -// check the statement to make sure that -// all idenfifiers referenced in it have been declared -// (if not, then produce an error). -// Modifies the given AST to have appropriate id_use pointers. -extern void scope_check_stmt(stmt_t *stmt); - -// check the statement to make sure that -// all idenfifiers referenced in it have been declared -// (if not, then produce an error). -// Modifies the given AST to have appropriate id_use pointers. -extern void scope_check_assignStmt(assign_stmt_t *stmt); - -// check the statement to make sure that -// the procedure being called has been declared -// (if not, then produce an error) -// Modifies the given AST to have appropriate id_use pointers. -extern void scope_check_callStmt(call_stmt_t *stmt); - -// check the statement to make sure that -// all idenfifiers referenced in it have been declared -// (if not, then produce an error) -// Modifies the given AST to have appropriate id_use pointers. -extern void scope_check_blockStmt(block_stmt_t *block); - -// check the statement to make sure that -// all idenfifiers referenced in it have been declared -// (if not, then produce an error) -// Modifies the given AST to have appropriate id_use pointers. -extern void scope_check_ifStmt(if_stmt_t *stmt); - -// check the statement to make sure that -// all idenfifiers referenced in it have been declared -// (if not, then produce an error) -// Modifies the given AST to have appropriate id_use pointers. -extern void scope_check_whileStmt(while_stmt_t *stmt); - -// check the statement to make sure that -// all idenfifiers referenced in it have been declared -// (if not, then produce an error) -// Modifies the given AST to have appropriate id_use pointers. -extern void scope_check_readStmt(read_stmt_t *stmt); - -// check the statement to make sure that -// all idenfifiers referenced in it have been declared -// (if not, then produce an error). -// Modifies the given AST to have appropriate id_use pointers. -extern void scope_check_printStmt(print_stmt_t *stmt); - -// check the condition to make sure that -// all idenfifiers referenced in it have been declared -// (if not, then produce an error). -// Modifies the given AST to have appropriate id_use pointers. -extern void scope_check_condition(condition_t *cond); - -// check the condition to make sure that -// all idenfifiers referenced in it have been declared -// (if not, then produce an error). -// Modifies the given AST to have appropriate id_use pointers. -extern void scope_check_db_condition(db_condition_t *cond); - -// check the condition to make sure that -// all idenfifiers referenced in it have been declared -// (if not, then produce an error). -// Modifies the given AST to have appropriate id_use pointers. -extern void scope_check_rel_op_condition(rel_op_condition_t *cond); - -// check the expresion to make sure that -// all idenfifiers referenced in it have been declared -// (if not, then produce an error). -// Modifies the given AST to have appropriate id_use pointers. -extern void scope_check_expr(expr_t *exp); - -// check that the given name has been declared, -// if not, then produce an error using the file_location (floc) given. -// Modifies the AST to have appropriate id_use pointers. -extern void scope_check_ident(ident_t *id); - -// check the expression (exp) to make sure that -// all idenfifiers referenced in it have been declared -// (if not, then produce an error) -// Modifies the given AST to have appropriate id_use pointers. -extern void scope_check_binary_op_expr(binary_op_expr_t *exp); - -// Check that the given name has been declared, -// if so, then return an id_use -// (containing the attributes) for that name, -// otherwise, produce an error -// using the file_location (floc) given. -extern id_use *scope_check_ident_declared( - file_location floc, - const char *name); - -#endif diff --git a/spl-manual.pdf b/spl-manual.pdf deleted file mode 100644 index 0cd7ee528d9c82b4fdf41dc7ef932bb8d990ee33..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 139829 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�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

    VD<_`Y0i%8Bg`3Gmv~ z_uv!R zs)`^vgD29qZp+mUTc;}|oD^}0nH6cL;J0PgOK0cHnmIeRi{y8{`|z8l>A-+UYU{Q6_Y?2`b)SxO z?+*F>q+2CAyW_;v(ga4A)kCAc-1hscl1_M+jtVs?-Lp8Q`Hw7vG3{fmsJ;cf=5Iz) zR_kWwwkyiZ^fk8_%~)(@r8c8m%U@}9_HWk{Q75?JK2?~SX7EoA%UmQLVdt8S155z#Q z8lD(eFh2qU4WNphQoz+I7;E{!ZVT50nQ20C$robNJF|>7uXRB0}dD^R*`q}#U zQ7HoADo(D>{yvU0gi1m15R^(m`HWEpaTrtzOQ4xS2$M?T@FOloWwWo}W>;T7aGr~% z3MOOn5y8u~R=K*n`VmMIknxgZ%fdmnv6BP7SOTHpG~nCf>>PanNhksHCoezY0H4W! z9>eGHCmcw_6f7xz9v~BwZ*&BF7J&1MN~}->#_%(-sCdb+k99GU{bY#^NDL<$2f&4k zgAe6z-hfI=0q$nyX=ok{`kMdKUc&jrIx30T7l#~*{24(f8yVuz6q zi~!`>!;%L}1P(Jo&m+(PYs48=5NLQpQ^c@|(!fmY;bsC8vH24b7H?4Z0`BnC8HDA- zZl(__AYh6;98t-XCOKY`x%G~-n~aKv_V3G zDcA(oAo*cg18U+4je|b}P!B>E>fhJV-p|$3<2OG4LfsF+fDl}v5JNB^2v?}{As7&b z%hxy7X!xW6X%!3_-VvaQ6B!;t1`6R3c?3$~5qX5d5qSgxfJ zJ-DP;I9$Tv=Hc5Zf4y;XVTS_N@WOEk!a;h2!U+ojLB<7(BrqjJnDh`~l0$?^4V(ss zs>YJW6a~Y&APde&q$XH+M3|QlVID#Rc?UcDPlv%uNE8Sz1c8LG)K~jH9K!^42*TnoIrg+O3ohy)mY~+swgqSJJ;BLzV^}r*ED{A_9}$#-g1;JoqZ(>! zd>swJ>2WDFBQHk}Eq>^s@Iw=h4pjUg9b+F)2Y-8TX6EX**%AB(hfX(vum=984G)-uzpb)`BLiIhTqrK!II542qZ3t4 z-*Ibzr;mfL3YdeB2;$%}aH@o&vP>PNqf8JZ*>o0yve@(K$UHiI9>4=a{1b|qkFA%N zqXRgiV!PQFNNQ}RV?omeZ!ER5_3(gln7O$6QouifJgNeDC`=l{q0uQSgK|+Z8VLma zN`XrZ;0P>z=m(@e7O1$LC_^w9OW+U1V-SY0;4?P@j18+o0*p%sIw!z*aJ}&`pcK+r zIvo}a1U!TetcM7L_KAgoQ@RY8^zbk`6Cu+D>p{dr7%&fE$I|I2SS%8Z0gnJ+@eq{D zg6$F(2F5aAje&(B3cGP2bS4Ue8y?1HzHk5tIYFa{?Y0CC|s@lJR&XKLSn&Yghby3_2_<2rz^chY$t=8#4kPN{a0W ziwz&g;PKdWSm@(nEGEhRfHRPF&*H#diZGT-ip3xa!A_Ha$AdROh%nf|;9+b!F(v}l zGe|K9;UOe{L%3|%KoRCc$#%tsw>k)TTn>+CsIi?cp%E+ z=L2d6!4nUoqu{y_TP;9DGGEd^o3SO;J{5-$u;#**kVnZz0xVKCY7h9^!A29ry) z7lgs0lgF|UGA}F!(eA-m7Hp#NG*}#BJqhqYfFa_s>16$pa{$6%gN#HPi;JCpKDMr# z9euzBK8l*DYY@0X2k+aNczS}Je}3Nw9z(3~aPkD7!0NyQJu8+`)-M8uG@YRf$|Hu3 xwl?T#c|6XtrA%OVY$h97#^Nrf{4. */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, - especially those whose name start with YY_ or yy_. They are - private implementation details that can be changed or removed. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output, and Bison version. */ -#define YYBISON 30802 - -/* Bison version string. */ -#define YYBISON_VERSION "3.8.2" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 0 - -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - -/* "%code top" blocks. */ -#line 3 "spl.y" - -#include - -#line 72 "spl.tab.c" - - - - -# ifndef YY_CAST -# ifdef __cplusplus -# define YY_CAST(Type, Val) static_cast (Val) -# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) -# else -# define YY_CAST(Type, Val) ((Type) (Val)) -# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) -# endif -# endif -# ifndef YY_NULLPTR -# if defined __cplusplus -# if 201103L <= __cplusplus -# define YY_NULLPTR nullptr -# else -# define YY_NULLPTR 0 -# endif -# else -# define YY_NULLPTR ((void*)0) -# endif -# endif - -#include "spl.tab.h" -/* Symbol kind. */ -enum yysymbol_kind_t -{ - YYSYMBOL_YYEMPTY = -2, - YYSYMBOL_YYEOF = 0, /* "end of file" */ - YYSYMBOL_YYerror = 1, /* error */ - YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ - YYSYMBOL_identsym = 3, /* identsym */ - YYSYMBOL_numbersym = 4, /* numbersym */ - YYSYMBOL_plussym = 5, /* "+" */ - YYSYMBOL_minussym = 6, /* "-" */ - YYSYMBOL_multsym = 7, /* "*" */ - YYSYMBOL_divsym = 8, /* "/" */ - YYSYMBOL_periodsym = 9, /* "." */ - YYSYMBOL_semisym = 10, /* ";" */ - YYSYMBOL_eqsym = 11, /* "=" */ - YYSYMBOL_commasym = 12, /* "," */ - YYSYMBOL_becomessym = 13, /* ":=" */ - YYSYMBOL_lparensym = 14, /* "(" */ - YYSYMBOL_rparensym = 15, /* ")" */ - YYSYMBOL_constsym = 16, /* "const" */ - YYSYMBOL_varsym = 17, /* "var" */ - YYSYMBOL_procsym = 18, /* "proc" */ - YYSYMBOL_callsym = 19, /* "call" */ - YYSYMBOL_beginsym = 20, /* "begin" */ - YYSYMBOL_endsym = 21, /* "end" */ - YYSYMBOL_ifsym = 22, /* "if" */ - YYSYMBOL_thensym = 23, /* "then" */ - YYSYMBOL_elsesym = 24, /* "else" */ - YYSYMBOL_whilesym = 25, /* "while" */ - YYSYMBOL_dosym = 26, /* "do" */ - YYSYMBOL_readsym = 27, /* "read" */ - YYSYMBOL_printsym = 28, /* "print" */ - YYSYMBOL_divisiblesym = 29, /* "divisible" */ - YYSYMBOL_bysym = 30, /* "by" */ - YYSYMBOL_eqeqsym = 31, /* "==" */ - YYSYMBOL_neqsym = 32, /* "!=" */ - YYSYMBOL_ltsym = 33, /* "<" */ - YYSYMBOL_leqsym = 34, /* "<=" */ - YYSYMBOL_gtsym = 35, /* ">" */ - YYSYMBOL_geqsym = 36, /* ">=" */ - YYSYMBOL_YYACCEPT = 37, /* $accept */ - YYSYMBOL_program = 38, /* program */ - YYSYMBOL_block = 39, /* block */ - YYSYMBOL_constDecls = 40, /* constDecls */ - YYSYMBOL_empty = 41, /* empty */ - YYSYMBOL_constDecl = 42, /* constDecl */ - YYSYMBOL_constDefList = 43, /* constDefList */ - YYSYMBOL_constDef = 44, /* constDef */ - YYSYMBOL_varDecls = 45, /* varDecls */ - YYSYMBOL_varDecl = 46, /* varDecl */ - YYSYMBOL_identList = 47, /* identList */ - YYSYMBOL_procDecls = 48, /* procDecls */ - YYSYMBOL_procDecl = 49, /* procDecl */ - YYSYMBOL_stmts = 50, /* stmts */ - YYSYMBOL_stmtList = 51, /* stmtList */ - YYSYMBOL_stmt = 52, /* stmt */ - YYSYMBOL_assignStmt = 53, /* assignStmt */ - YYSYMBOL_callStmt = 54, /* callStmt */ - YYSYMBOL_ifStmt = 55, /* ifStmt */ - YYSYMBOL_whileStmt = 56, /* whileStmt */ - YYSYMBOL_readStmt = 57, /* readStmt */ - YYSYMBOL_printStmt = 58, /* printStmt */ - YYSYMBOL_blockStmt = 59, /* blockStmt */ - YYSYMBOL_condition = 60, /* condition */ - YYSYMBOL_dbCondition = 61, /* dbCondition */ - YYSYMBOL_relOpCondition = 62, /* relOpCondition */ - YYSYMBOL_relOp = 63, /* relOp */ - YYSYMBOL_expr = 64, /* expr */ - YYSYMBOL_term = 65, /* term */ - YYSYMBOL_factor = 66 /* factor */ -}; -typedef enum yysymbol_kind_t yysymbol_kind_t; - - - -/* Unqualified %code blocks. */ -#line 106 "spl.y" - - /* extern declarations provided by the lexer */ -extern int yylex(void); - - /* The AST for the program, set by the semantic action - for the nonterminal program. */ -block_t progast; - - /* Set the program's ast to be t */ -extern void setProgAST(block_t t); - -#line 188 "spl.tab.c" - -#ifdef short -# undef short -#endif - -/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure - and (if available) are included - so that the code can choose integer types of a good width. */ - -#ifndef __PTRDIFF_MAX__ -# include /* INFRINGES ON USER NAME SPACE */ -# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_STDINT_H -# endif -#endif - -/* Narrow types that promote to a signed type and that can represent a - signed or unsigned integer of at least N bits. In tables they can - save space and decrease cache pressure. Promoting to a signed type - helps avoid bugs in integer arithmetic. */ - -#ifdef __INT_LEAST8_MAX__ -typedef __INT_LEAST8_TYPE__ yytype_int8; -#elif defined YY_STDINT_H -typedef int_least8_t yytype_int8; -#else -typedef signed char yytype_int8; -#endif - -#ifdef __INT_LEAST16_MAX__ -typedef __INT_LEAST16_TYPE__ yytype_int16; -#elif defined YY_STDINT_H -typedef int_least16_t yytype_int16; -#else -typedef short yytype_int16; -#endif - -/* Work around bug in HP-UX 11.23, which defines these macros - incorrectly for preprocessor constants. This workaround can likely - be removed in 2023, as HPE has promised support for HP-UX 11.23 - (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of - . */ -#ifdef __hpux -# undef UINT_LEAST8_MAX -# undef UINT_LEAST16_MAX -# define UINT_LEAST8_MAX 255 -# define UINT_LEAST16_MAX 65535 -#endif - -#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ -typedef __UINT_LEAST8_TYPE__ yytype_uint8; -#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ - && UINT_LEAST8_MAX <= INT_MAX) -typedef uint_least8_t yytype_uint8; -#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX -typedef unsigned char yytype_uint8; -#else -typedef short yytype_uint8; -#endif - -#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ -typedef __UINT_LEAST16_TYPE__ yytype_uint16; -#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ - && UINT_LEAST16_MAX <= INT_MAX) -typedef uint_least16_t yytype_uint16; -#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX -typedef unsigned short yytype_uint16; -#else -typedef int yytype_uint16; -#endif - -#ifndef YYPTRDIFF_T -# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ -# define YYPTRDIFF_T __PTRDIFF_TYPE__ -# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ -# elif defined PTRDIFF_MAX -# ifndef ptrdiff_t -# include /* INFRINGES ON USER NAME SPACE */ -# endif -# define YYPTRDIFF_T ptrdiff_t -# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX -# else -# define YYPTRDIFF_T long -# define YYPTRDIFF_MAXIMUM LONG_MAX -# endif -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned -# endif -#endif - -#define YYSIZE_MAXIMUM \ - YY_CAST (YYPTRDIFF_T, \ - (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ - ? YYPTRDIFF_MAXIMUM \ - : YY_CAST (YYSIZE_T, -1))) - -#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) - - -/* Stored state numbers (used for stacks). */ -typedef yytype_int8 yy_state_t; - -/* State numbers in computations. */ -typedef int yy_state_fast_t; - -#ifndef YY_ -# if defined YYENABLE_NLS && YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(Msgid) dgettext ("bison-runtime", Msgid) -# endif -# endif -# ifndef YY_ -# define YY_(Msgid) Msgid -# endif -#endif - - -#ifndef YY_ATTRIBUTE_PURE -# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) -# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) -# else -# define YY_ATTRIBUTE_PURE -# endif -#endif - -#ifndef YY_ATTRIBUTE_UNUSED -# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) -# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) -# else -# define YY_ATTRIBUTE_UNUSED -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YY_USE(E) ((void) (E)) -#else -# define YY_USE(E) /* empty */ -#endif - -/* Suppress an incorrect diagnostic about yylval being uninitialized. */ -#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__ -# if __GNUC__ * 100 + __GNUC_MINOR__ < 407 -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") -# else -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ - _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -# endif -# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ - _Pragma ("GCC diagnostic pop") -#else -# define YY_INITIAL_VALUE(Value) Value -#endif -#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_END -#endif -#ifndef YY_INITIAL_VALUE -# define YY_INITIAL_VALUE(Value) /* Nothing. */ -#endif - -#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ -# define YY_IGNORE_USELESS_CAST_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") -# define YY_IGNORE_USELESS_CAST_END \ - _Pragma ("GCC diagnostic pop") -#endif -#ifndef YY_IGNORE_USELESS_CAST_BEGIN -# define YY_IGNORE_USELESS_CAST_BEGIN -# define YY_IGNORE_USELESS_CAST_END -#endif - - -#define YY_ASSERT(E) ((void) (0 && (E))) - -#if 1 - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's 'empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined EXIT_SUCCESS \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined EXIT_SUCCESS -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined EXIT_SUCCESS -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -# define YYCOPY_NEEDED 1 -#endif /* 1 */ - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ - && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yy_state_t yyss_alloc; - YYSTYPE yyvs_alloc; - YYLTYPE yyls_alloc; -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE) \ - + YYSIZEOF (YYLTYPE)) \ - + 2 * YYSTACK_GAP_MAXIMUM) - -# define YYCOPY_NEEDED 1 - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYPTRDIFF_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / YYSIZEOF (*yyptr); \ - } \ - while (0) - -#endif - -#if defined YYCOPY_NEEDED && YYCOPY_NEEDED -/* Copy COUNT objects from SRC to DST. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(Dst, Src, Count) \ - __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) -# else -# define YYCOPY(Dst, Src, Count) \ - do \ - { \ - YYPTRDIFF_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (Dst)[yyi] = (Src)[yyi]; \ - } \ - while (0) -# endif -# endif -#endif /* !YYCOPY_NEEDED */ - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 6 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 94 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 37 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 30 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 58 -/* YYNSTATES -- Number of states. */ -#define YYNSTATES 105 - -/* YYMAXUTOK -- Last valid token kind. */ -#define YYMAXUTOK 291 - - -/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM - as returned by yylex, with out-of-bounds checking. */ -#define YYTRANSLATE(YYX) \ - (0 <= (YYX) && (YYX) <= YYMAXUTOK \ - ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \ - : YYSYMBOL_YYUNDEF) - -/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM - as returned by yylex. */ -static const yytype_int8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36 -}; - -#if YYDEBUG -/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ -static const yytype_uint8 yyrline[] = -{ - 0, 121, 121, 124, 128, 129, 133, 140, 142, 143, - 147, 149, 150, 153, 155, 156, 159, 160, 163, 165, - 166, 169, 170, 173, 174, 175, 176, 177, 178, 179, - 182, 184, 186, 188, 192, 195, 197, 199, 201, 202, - 205, 207, 209, 209, 209, 209, 209, 209, 211, 212, - 214, 218, 219, 221, 225, 226, 227, 228, 229 -}; -#endif - -/** Accessing symbol of state STATE. */ -#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State]) - -#if 1 -/* The user-facing name of the symbol whose (internal) number is - YYSYMBOL. No bounds checking. */ -static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; - -static const char * -yysymbol_name (yysymbol_kind_t yysymbol) -{ - static const char *const yy_sname[] = - { - "end of file", "error", "invalid token", "identsym", "numbersym", "+", - "-", "*", "/", ".", ";", "=", ",", ":=", "(", ")", "const", "var", - "proc", "call", "begin", "end", "if", "then", "else", "while", "do", - "read", "print", "divisible", "by", "==", "!=", "<", "<=", ">", ">=", - "$accept", "program", "block", "constDecls", "empty", "constDecl", - "constDefList", "constDef", "varDecls", "varDecl", "identList", - "procDecls", "procDecl", "stmts", "stmtList", "stmt", "assignStmt", - "callStmt", "ifStmt", "whileStmt", "readStmt", "printStmt", "blockStmt", - "condition", "dbCondition", "relOpCondition", "relOp", "expr", "term", - "factor", YY_NULLPTR - }; - return yy_sname[yysymbol]; -} -#endif - -#define YYPACT_NINF (-59) - -#define yypact_value_is_default(Yyn) \ - ((Yyn) == YYPACT_NINF) - -#define YYTABLE_NINF (-1) - -#define yytable_value_is_error(Yyn) \ - 0 - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -static const yytype_int8 yypact[] = -{ - -16, -59, 22, 36, -7, -59, -59, -59, 24, -59, - -59, 31, 41, 18, -59, 62, -59, -59, 44, 70, - -59, 24, -59, 43, 64, 75, 78, 2, 2, 79, - 9, -59, -59, -59, 63, 73, -59, -59, -59, -59, - -59, -59, -59, -59, -59, -59, -59, 82, 9, -16, - -59, -59, -59, 9, 9, 9, 9, 65, -59, -59, - 5, 50, -59, 60, -59, 54, -59, 48, -59, 54, - 77, -59, -59, 27, 14, 48, 9, 9, -59, -59, - -59, -59, -59, -59, 9, 9, 9, 48, -59, -59, - -59, 9, 0, 50, 50, 54, -59, -59, 68, 54, - -59, 48, -59, 69, -59 -}; - -/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE does not specify something else to do. Zero - means the default is an error. */ -static const yytype_int8 yydefact[] = -{ - 0, 6, 0, 0, 6, 4, 1, 2, 0, 11, - 5, 6, 0, 0, 8, 0, 16, 12, 6, 0, - 7, 0, 14, 0, 0, 0, 0, 0, 0, 0, - 0, 37, 19, 17, 0, 20, 21, 23, 24, 25, - 26, 27, 28, 29, 10, 9, 13, 0, 0, 0, - 31, 54, 55, 0, 0, 0, 0, 0, 38, 39, - 0, 48, 51, 0, 35, 36, 3, 0, 15, 30, - 0, 57, 56, 0, 0, 6, 0, 0, 42, 43, - 44, 45, 46, 47, 0, 0, 0, 6, 22, 18, - 58, 0, 0, 49, 50, 41, 52, 53, 0, 40, - 33, 6, 34, 0, 32 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int8 yypgoto[] = -{ - -59, -59, 1, -59, 45, -59, -59, 71, -59, -59, - -59, -59, -59, -58, -59, 26, -59, -59, -59, -59, - -59, -59, -59, 66, -59, -59, -59, -30, 3, -51 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int8 yydefgoto[] = -{ - 0, 2, 31, 4, 32, 10, 13, 14, 11, 17, - 23, 18, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 57, 58, 59, 84, 60, 61, 62 -}; - -/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule whose - number is the opposite. If YYTABLE_NINF, syntax error. */ -static const yytype_int8 yytable[] = -{ - 65, 3, 71, 72, 1, 51, 52, 53, 54, 8, - 76, 77, 51, 52, 53, 54, 55, 92, 69, 76, - 77, 100, 6, 55, 101, 73, 74, 12, 20, 98, - 21, 56, 76, 77, 96, 97, 78, 79, 80, 81, - 82, 83, 90, 103, 91, 7, 5, 24, 15, 9, - 70, 24, 19, 46, 95, 47, 16, 85, 86, 76, - 77, 99, 25, 26, 1, 22, 27, 26, 1, 28, - 27, 29, 30, 28, 44, 29, 30, 48, 49, 93, - 94, 50, 64, 67, 66, 68, 87, 89, 75, 102, - 104, 0, 45, 88, 63 -}; - -static const yytype_int8 yycheck[] = -{ - 30, 0, 53, 54, 20, 3, 4, 5, 6, 16, - 5, 6, 3, 4, 5, 6, 14, 75, 48, 5, - 6, 21, 0, 14, 24, 55, 56, 3, 10, 87, - 12, 29, 5, 6, 85, 86, 31, 32, 33, 34, - 35, 36, 15, 101, 30, 9, 1, 3, 17, 4, - 49, 3, 11, 10, 84, 12, 11, 7, 8, 5, - 6, 91, 18, 19, 20, 3, 22, 19, 20, 25, - 22, 27, 28, 25, 4, 27, 28, 13, 3, 76, - 77, 3, 3, 10, 21, 3, 26, 10, 23, 21, - 21, -1, 21, 67, 28 -}; - -/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of - state STATE-NUM. */ -static const yytype_int8 yystos[] = -{ - 0, 20, 38, 39, 40, 41, 0, 9, 16, 41, - 42, 45, 3, 43, 44, 17, 41, 46, 48, 11, - 10, 12, 3, 47, 3, 18, 19, 22, 25, 27, - 28, 39, 41, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 4, 44, 10, 12, 13, 3, - 3, 3, 4, 5, 6, 14, 29, 60, 61, 62, - 64, 65, 66, 60, 3, 64, 21, 10, 3, 64, - 39, 66, 66, 64, 64, 23, 5, 6, 31, 32, - 33, 34, 35, 36, 63, 7, 8, 26, 52, 10, - 15, 30, 50, 65, 65, 64, 66, 66, 50, 64, - 21, 24, 21, 50, 21 -}; - -/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ -static const yytype_int8 yyr1[] = -{ - 0, 37, 38, 39, 40, 40, 41, 42, 43, 43, - 44, 45, 45, 46, 47, 47, 48, 48, 49, 50, - 50, 51, 51, 52, 52, 52, 52, 52, 52, 52, - 53, 54, 55, 55, 56, 57, 58, 59, 60, 60, - 61, 62, 63, 63, 63, 63, 63, 63, 64, 64, - 64, 65, 65, 65, 66, 66, 66, 66, 66 -}; - -/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ -static const yytype_int8 yyr2[] = -{ - 0, 2, 2, 6, 1, 2, 0, 3, 1, 3, - 3, 1, 2, 3, 1, 3, 1, 2, 4, 1, - 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, - 3, 2, 7, 5, 5, 2, 2, 1, 1, 1, - 4, 3, 1, 1, 1, 1, 1, 1, 1, 3, - 3, 1, 3, 3, 1, 1, 2, 2, 3 -}; - - -enum { YYENOMEM = -2 }; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab -#define YYNOMEM goto yyexhaustedlab - - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ - do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - YY_LAC_DISCARD ("YYBACKUP"); \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (file_name, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ - while (0) - -/* Backward compatibility with an undocumented macro. - Use YYerror or YYUNDEF. */ -#define YYERRCODE YYUNDEF - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (N) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (0) -#endif - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) - - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) - - -/* YYLOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -# ifndef YYLOCATION_PRINT - -# if defined YY_LOCATION_PRINT - - /* Temporary convenience wrapper in case some people defined the - undocumented and private YY_LOCATION_PRINT macros. */ -# define YYLOCATION_PRINT(File, Loc) YY_LOCATION_PRINT(File, *(Loc)) - -# elif defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL - -/* Print *YYLOCP on YYO. Private, do not rely on its existence. */ - -YY_ATTRIBUTE_UNUSED -static int -yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) -{ - int res = 0; - int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; - if (0 <= yylocp->first_line) - { - res += YYFPRINTF (yyo, "%d", yylocp->first_line); - if (0 <= yylocp->first_column) - res += YYFPRINTF (yyo, ".%d", yylocp->first_column); - } - if (0 <= yylocp->last_line) - { - if (yylocp->first_line < yylocp->last_line) - { - res += YYFPRINTF (yyo, "-%d", yylocp->last_line); - if (0 <= end_col) - res += YYFPRINTF (yyo, ".%d", end_col); - } - else if (0 <= end_col && yylocp->first_column < end_col) - res += YYFPRINTF (yyo, "-%d", end_col); - } - return res; -} - -# define YYLOCATION_PRINT yy_location_print_ - - /* Temporary convenience wrapper in case some people defined the - undocumented and private YY_LOCATION_PRINT macros. */ -# define YY_LOCATION_PRINT(File, Loc) YYLOCATION_PRINT(File, &(Loc)) - -# else - -# define YYLOCATION_PRINT(File, Loc) ((void) 0) - /* Temporary convenience wrapper in case some people defined the - undocumented and private YY_LOCATION_PRINT macros. */ -# define YY_LOCATION_PRINT YYLOCATION_PRINT - -# endif -# endif /* !defined YYLOCATION_PRINT */ - - -# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Kind, Value, Location, file_name); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (0) - - -/*-----------------------------------. -| Print this symbol's value on YYO. | -`-----------------------------------*/ - -static void -yy_symbol_value_print (FILE *yyo, - yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, char const *file_name) -{ - FILE *yyoutput = yyo; - YY_USE (yyoutput); - YY_USE (yylocationp); - YY_USE (file_name); - if (!yyvaluep) - return; - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YY_USE (yykind); - YY_IGNORE_MAYBE_UNINITIALIZED_END -} - - -/*---------------------------. -| Print this symbol on YYO. | -`---------------------------*/ - -static void -yy_symbol_print (FILE *yyo, - yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, char const *file_name) -{ - YYFPRINTF (yyo, "%s %s (", - yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind)); - - YYLOCATION_PRINT (yyo, yylocationp); - YYFPRINTF (yyo, ": "); - yy_symbol_value_print (yyo, yykind, yyvaluep, yylocationp, file_name); - YYFPRINTF (yyo, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -static void -yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (0) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -static void -yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, - int yyrule, char const *file_name) -{ - int yylno = yyrline[yyrule]; - int yynrhs = yyr2[yyrule]; - int yyi; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, - YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]), - &yyvsp[(yyi + 1) - (yynrhs)], - &(yylsp[(yyi + 1) - (yynrhs)]), file_name); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyssp, yyvsp, yylsp, Rule, file_name); \ -} while (0) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) ((void) 0) -# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - -/* Given a state stack such that *YYBOTTOM is its bottom, such that - *YYTOP is either its top or is YYTOP_EMPTY to indicate an empty - stack, and such that *YYCAPACITY is the maximum number of elements it - can hold without a reallocation, make sure there is enough room to - store YYADD more elements. If not, allocate a new stack using - YYSTACK_ALLOC, copy the existing elements, and adjust *YYBOTTOM, - *YYTOP, and *YYCAPACITY to reflect the new capacity and memory - location. If *YYBOTTOM != YYBOTTOM_NO_FREE, then free the old stack - using YYSTACK_FREE. Return 0 if successful or if no reallocation is - required. Return YYENOMEM if memory is exhausted. */ -static int -yy_lac_stack_realloc (YYPTRDIFF_T *yycapacity, YYPTRDIFF_T yyadd, -#if YYDEBUG - char const *yydebug_prefix, - char const *yydebug_suffix, -#endif - yy_state_t **yybottom, - yy_state_t *yybottom_no_free, - yy_state_t **yytop, yy_state_t *yytop_empty) -{ - YYPTRDIFF_T yysize_old = - *yytop == yytop_empty ? 0 : *yytop - *yybottom + 1; - YYPTRDIFF_T yysize_new = yysize_old + yyadd; - if (*yycapacity < yysize_new) - { - YYPTRDIFF_T yyalloc = 2 * yysize_new; - yy_state_t *yybottom_new; - /* Use YYMAXDEPTH for maximum stack size given that the stack - should never need to grow larger than the main state stack - needs to grow without LAC. */ - if (YYMAXDEPTH < yysize_new) - { - YYDPRINTF ((stderr, "%smax size exceeded%s", yydebug_prefix, - yydebug_suffix)); - return YYENOMEM; - } - if (YYMAXDEPTH < yyalloc) - yyalloc = YYMAXDEPTH; - yybottom_new = - YY_CAST (yy_state_t *, - YYSTACK_ALLOC (YY_CAST (YYSIZE_T, - yyalloc * YYSIZEOF (*yybottom_new)))); - if (!yybottom_new) - { - YYDPRINTF ((stderr, "%srealloc failed%s", yydebug_prefix, - yydebug_suffix)); - return YYENOMEM; - } - if (*yytop != yytop_empty) - { - YYCOPY (yybottom_new, *yybottom, yysize_old); - *yytop = yybottom_new + (yysize_old - 1); - } - if (*yybottom != yybottom_no_free) - YYSTACK_FREE (*yybottom); - *yybottom = yybottom_new; - *yycapacity = yyalloc; - } - return 0; -} - -/* Establish the initial context for the current lookahead if no initial - context is currently established. - - We define a context as a snapshot of the parser stacks. We define - the initial context for a lookahead as the context in which the - parser initially examines that lookahead in order to select a - syntactic action. Thus, if the lookahead eventually proves - syntactically unacceptable (possibly in a later context reached via a - series of reductions), the initial context can be used to determine - the exact set of tokens that would be syntactically acceptable in the - lookahead's place. Moreover, it is the context after which any - further semantic actions would be erroneous because they would be - determined by a syntactically unacceptable token. - - YY_LAC_ESTABLISH should be invoked when a reduction is about to be - performed in an inconsistent state (which, for the purposes of LAC, - includes consistent states that don't know they're consistent because - their default reductions have been disabled). Iff there is a - lookahead token, it should also be invoked before reporting a syntax - error. This latter case is for the sake of the debugging output. - - For parse.lac=full, the implementation of YY_LAC_ESTABLISH is as - follows. If no initial context is currently established for the - current lookahead, then check if that lookahead can eventually be - shifted if syntactic actions continue from the current context. - Report a syntax error if it cannot. */ -#define YY_LAC_ESTABLISH \ -do { \ - if (!yy_lac_established) \ - { \ - YYDPRINTF ((stderr, \ - "LAC: initial context established for %s\n", \ - yysymbol_name (yytoken))); \ - yy_lac_established = 1; \ - switch (yy_lac (yyesa, &yyes, &yyes_capacity, yyssp, yytoken)) \ - { \ - case YYENOMEM: \ - YYNOMEM; \ - case 1: \ - goto yyerrlab; \ - } \ - } \ -} while (0) - -/* Discard any previous initial lookahead context because of Event, - which may be a lookahead change or an invalidation of the currently - established initial context for the current lookahead. - - The most common example of a lookahead change is a shift. An example - of both cases is syntax error recovery. That is, a syntax error - occurs when the lookahead is syntactically erroneous for the - currently established initial context, so error recovery manipulates - the parser stacks to try to find a new initial context in which the - current lookahead is syntactically acceptable. If it fails to find - such a context, it discards the lookahead. */ -#if YYDEBUG -# define YY_LAC_DISCARD(Event) \ -do { \ - if (yy_lac_established) \ - { \ - YYDPRINTF ((stderr, "LAC: initial context discarded due to " \ - Event "\n")); \ - yy_lac_established = 0; \ - } \ -} while (0) -#else -# define YY_LAC_DISCARD(Event) yy_lac_established = 0 -#endif - -/* Given the stack whose top is *YYSSP, return 0 iff YYTOKEN can - eventually (after perhaps some reductions) be shifted, return 1 if - not, or return YYENOMEM if memory is exhausted. As preconditions and - postconditions: *YYES_CAPACITY is the allocated size of the array to - which *YYES points, and either *YYES = YYESA or *YYES points to an - array allocated with YYSTACK_ALLOC. yy_lac may overwrite the - contents of either array, alter *YYES and *YYES_CAPACITY, and free - any old *YYES other than YYESA. */ -static int -yy_lac (yy_state_t *yyesa, yy_state_t **yyes, - YYPTRDIFF_T *yyes_capacity, yy_state_t *yyssp, yysymbol_kind_t yytoken) -{ - yy_state_t *yyes_prev = yyssp; - yy_state_t *yyesp = yyes_prev; - /* Reduce until we encounter a shift and thereby accept the token. */ - YYDPRINTF ((stderr, "LAC: checking lookahead %s:", yysymbol_name (yytoken))); - if (yytoken == YYSYMBOL_YYUNDEF) - { - YYDPRINTF ((stderr, " Always Err\n")); - return 1; - } - while (1) - { - int yyrule = yypact[+*yyesp]; - if (yypact_value_is_default (yyrule) - || (yyrule += yytoken) < 0 || YYLAST < yyrule - || yycheck[yyrule] != yytoken) - { - /* Use the default action. */ - yyrule = yydefact[+*yyesp]; - if (yyrule == 0) - { - YYDPRINTF ((stderr, " Err\n")); - return 1; - } - } - else - { - /* Use the action from yytable. */ - yyrule = yytable[yyrule]; - if (yytable_value_is_error (yyrule)) - { - YYDPRINTF ((stderr, " Err\n")); - return 1; - } - if (0 < yyrule) - { - YYDPRINTF ((stderr, " S%d\n", yyrule)); - return 0; - } - yyrule = -yyrule; - } - /* By now we know we have to simulate a reduce. */ - YYDPRINTF ((stderr, " R%d", yyrule - 1)); - { - /* Pop the corresponding number of values from the stack. */ - YYPTRDIFF_T yylen = yyr2[yyrule]; - /* First pop from the LAC stack as many tokens as possible. */ - if (yyesp != yyes_prev) - { - YYPTRDIFF_T yysize = yyesp - *yyes + 1; - if (yylen < yysize) - { - yyesp -= yylen; - yylen = 0; - } - else - { - yyesp = yyes_prev; - yylen -= yysize; - } - } - /* Only afterwards look at the main stack. */ - if (yylen) - yyesp = yyes_prev -= yylen; - } - /* Push the resulting state of the reduction. */ - { - yy_state_fast_t yystate; - { - const int yylhs = yyr1[yyrule] - YYNTOKENS; - const int yyi = yypgoto[yylhs] + *yyesp; - yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyesp - ? yytable[yyi] - : yydefgoto[yylhs]); - } - if (yyesp == yyes_prev) - { - yyesp = *yyes; - YY_IGNORE_USELESS_CAST_BEGIN - *yyesp = YY_CAST (yy_state_t, yystate); - YY_IGNORE_USELESS_CAST_END - } - else - { - if (yy_lac_stack_realloc (yyes_capacity, 1, -#if YYDEBUG - " (", ")", -#endif - yyes, yyesa, &yyesp, yyes_prev)) - { - YYDPRINTF ((stderr, "\n")); - return YYENOMEM; - } - YY_IGNORE_USELESS_CAST_BEGIN - *++yyesp = YY_CAST (yy_state_t, yystate); - YY_IGNORE_USELESS_CAST_END - } - YYDPRINTF ((stderr, " G%d", yystate)); - } - } -} - -/* Context of a parse error. */ -typedef struct -{ - yy_state_t *yyssp; - yy_state_t *yyesa; - yy_state_t **yyes; - YYPTRDIFF_T *yyes_capacity; - yysymbol_kind_t yytoken; - YYLTYPE *yylloc; -} yypcontext_t; - -/* Put in YYARG at most YYARGN of the expected tokens given the - current YYCTX, and return the number of tokens stored in YYARG. If - YYARG is null, return the number of expected tokens (guaranteed to - be less than YYNTOKENS). Return YYENOMEM on memory exhaustion. - Return 0 if there are more than YYARGN expected tokens, yet fill - YYARG up to YYARGN. */ -static int -yypcontext_expected_tokens (const yypcontext_t *yyctx, - yysymbol_kind_t yyarg[], int yyargn) -{ - /* Actual size of YYARG. */ - int yycount = 0; - - int yyx; - for (yyx = 0; yyx < YYNTOKENS; ++yyx) - { - yysymbol_kind_t yysym = YY_CAST (yysymbol_kind_t, yyx); - if (yysym != YYSYMBOL_YYerror && yysym != YYSYMBOL_YYUNDEF) - switch (yy_lac (yyctx->yyesa, yyctx->yyes, yyctx->yyes_capacity, yyctx->yyssp, yysym)) - { - case YYENOMEM: - return YYENOMEM; - case 1: - continue; - default: - if (!yyarg) - ++yycount; - else if (yycount == yyargn) - return 0; - else - yyarg[yycount++] = yysym; - } - } - if (yyarg && yycount == 0 && 0 < yyargn) - yyarg[0] = YYSYMBOL_YYEMPTY; - return yycount; -} - - - - -#ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S))) -# else -/* Return the length of YYSTR. */ -static YYPTRDIFF_T -yystrlen (const char *yystr) -{ - YYPTRDIFF_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -#endif - -#ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -static char * -yystpcpy (char *yydest, const char *yysrc) -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -#endif - - - -static int -yy_syntax_error_arguments (const yypcontext_t *yyctx, - yysymbol_kind_t yyarg[], int yyargn) -{ - /* Actual size of YYARG. */ - int yycount = 0; - /* There are many possibilities here to consider: - - If this state is a consistent state with a default action, then - the only way this function was invoked is if the default action - is an error action. In that case, don't check for expected - tokens because there are none. - - The only way there can be no lookahead present (in yychar) is if - this state is a consistent state with a default action. Thus, - detecting the absence of a lookahead is sufficient to determine - that there is no unexpected or expected token to report. In that - case, just report a simple "syntax error". - - Don't assume there isn't a lookahead just because this state is a - consistent state with a default action. There might have been a - previous inconsistent state, consistent state with a non-default - action, or user semantic action that manipulated yychar. - In the first two cases, it might appear that the current syntax - error should have been detected in the previous state when yy_lac - was invoked. However, at that time, there might have been a - different syntax error that discarded a different initial context - during error recovery, leaving behind the current lookahead. - */ - if (yyctx->yytoken != YYSYMBOL_YYEMPTY) - { - int yyn; - YYDPRINTF ((stderr, "Constructing syntax error message\n")); - if (yyarg) - yyarg[yycount] = yyctx->yytoken; - ++yycount; - yyn = yypcontext_expected_tokens (yyctx, - yyarg ? yyarg + 1 : yyarg, yyargn - 1); - if (yyn == YYENOMEM) - return YYENOMEM; - else if (yyn == 0) - YYDPRINTF ((stderr, "No expected tokens.\n")); - else - yycount += yyn; - } - return yycount; -} - -/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message - about the unexpected token YYTOKEN for the state stack whose top is - YYSSP. In order to see if a particular token T is a - valid looakhead, invoke yy_lac (YYESA, YYES, YYES_CAPACITY, YYSSP, T). - - Return 0 if *YYMSG was successfully written. Return -1 if *YYMSG is - not large enough to hold the message. In that case, also set - *YYMSG_ALLOC to the required number of bytes. Return YYENOMEM if the - required number of bytes is too large to store or if - yy_lac returned YYENOMEM. */ -static int -yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, - const yypcontext_t *yyctx) -{ - enum { YYARGS_MAX = 5 }; - /* Internationalized format string. */ - const char *yyformat = YY_NULLPTR; - /* Arguments of yyformat: reported tokens (one for the "unexpected", - one per "expected"). */ - yysymbol_kind_t yyarg[YYARGS_MAX]; - /* Cumulated lengths of YYARG. */ - YYPTRDIFF_T yysize = 0; - - /* Actual size of YYARG. */ - int yycount = yy_syntax_error_arguments (yyctx, yyarg, YYARGS_MAX); - if (yycount == YYENOMEM) - return YYENOMEM; - - switch (yycount) - { -#define YYCASE_(N, S) \ - case N: \ - yyformat = S; \ - break - default: /* Avoid compiler warnings. */ - YYCASE_(0, YY_("syntax error")); - YYCASE_(1, YY_("syntax error, unexpected %s")); - YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); - YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); - YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); - YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); -#undef YYCASE_ - } - - /* Compute error message size. Don't count the "%s"s, but reserve - room for the terminator. */ - yysize = yystrlen (yyformat) - 2 * yycount + 1; - { - int yyi; - for (yyi = 0; yyi < yycount; ++yyi) - { - YYPTRDIFF_T yysize1 - = yysize + yystrlen (yysymbol_name (yyarg[yyi])); - if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) - yysize = yysize1; - else - return YYENOMEM; - } - } - - if (*yymsg_alloc < yysize) - { - *yymsg_alloc = 2 * yysize; - if (! (yysize <= *yymsg_alloc - && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) - *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; - return -1; - } - - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - { - char *yyp = *yymsg; - int yyi = 0; - while ((*yyp = *yyformat) != '\0') - if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) - { - yyp = yystpcpy (yyp, yysymbol_name (yyarg[yyi++])); - yyformat += 2; - } - else - { - ++yyp; - ++yyformat; - } - } - return 0; -} - - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -static void -yydestruct (const char *yymsg, - yysymbol_kind_t yykind, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, char const *file_name) -{ - YY_USE (yyvaluep); - YY_USE (yylocationp); - YY_USE (file_name); - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YY_USE (yykind); - YY_IGNORE_MAYBE_UNINITIALIZED_END -} - - -/* Lookahead token kind. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; -/* Location data for the lookahead symbol. */ -YYLTYPE yylloc -# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL - = { 1, 1, 1, 1 } -# endif -; -/* Number of syntax errors so far. */ -int yynerrs; - - - - -/*----------. -| yyparse. | -`----------*/ - -int -yyparse (char const *file_name) -{ - yy_state_fast_t yystate = 0; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus = 0; - - /* Refer to the stacks through separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* Their size. */ - YYPTRDIFF_T yystacksize = YYINITDEPTH; - - /* The state stack: array, bottom, top. */ - yy_state_t yyssa[YYINITDEPTH]; - yy_state_t *yyss = yyssa; - yy_state_t *yyssp = yyss; - - /* The semantic value stack: array, bottom, top. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp = yyvs; - - /* The location stack: array, bottom, top. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp = yyls; - - yy_state_t yyesa[20]; - yy_state_t *yyes = yyesa; - YYPTRDIFF_T yyes_capacity = 20 < YYMAXDEPTH ? 20 : YYMAXDEPTH; - - /* Whether LAC context is established. A Boolean. */ - int yy_lac_established = 0; - int yyn; - /* The return value of yyparse. */ - int yyresult; - /* Lookahead symbol kind. */ - yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - YYLTYPE yyloc; - - /* The locations where the error started and ended. */ - YYLTYPE yyerror_range[3]; - - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf; - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yychar = YYEMPTY; /* Cause a token to be read. */ - - yylsp[0] = yylloc; - goto yysetstate; - - -/*------------------------------------------------------------. -| yynewstate -- push a new state, which is found in yystate. | -`------------------------------------------------------------*/ -yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - -/*--------------------------------------------------------------------. -| yysetstate -- set current state (the top of the stack) to yystate. | -`--------------------------------------------------------------------*/ -yysetstate: - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - YY_ASSERT (0 <= yystate && yystate < YYNSTATES); - YY_IGNORE_USELESS_CAST_BEGIN - *yyssp = YY_CAST (yy_state_t, yystate); - YY_IGNORE_USELESS_CAST_END - YY_STACK_PRINT (yyss, yyssp); - - if (yyss + yystacksize - 1 <= yyssp) -#if !defined yyoverflow && !defined YYSTACK_RELOCATE - YYNOMEM; -#else - { - /* Get the current used size of the three stacks, in elements. */ - YYPTRDIFF_T yysize = yyssp - yyss + 1; - -# if defined yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - yy_state_t *yyss1 = yyss; - YYSTYPE *yyvs1 = yyvs; - YYLTYPE *yyls1 = yyls; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * YYSIZEOF (*yyssp), - &yyvs1, yysize * YYSIZEOF (*yyvsp), - &yyls1, yysize * YYSIZEOF (*yylsp), - &yystacksize); - yyss = yyss1; - yyvs = yyvs1; - yyls = yyls1; - } -# else /* defined YYSTACK_RELOCATE */ - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - YYNOMEM; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yy_state_t *yyss1 = yyss; - union yyalloc *yyptr = - YY_CAST (union yyalloc *, - YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); - if (! yyptr) - YYNOMEM; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); - YYSTACK_RELOCATE (yyls_alloc, yyls); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - yylsp = yyls + yysize - 1; - - YY_IGNORE_USELESS_CAST_BEGIN - YYDPRINTF ((stderr, "Stack size increased to %ld\n", - YY_CAST (long, yystacksize))); - YY_IGNORE_USELESS_CAST_END - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } -#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ - - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yypact_value_is_default (yyn)) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token\n")); - yychar = yylex (); - } - - if (yychar <= YYEOF) - { - yychar = YYEOF; - yytoken = YYSYMBOL_YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else if (yychar == YYerror) - { - /* The scanner already issued an error message, process directly - to error recovery. But do not keep the error token as - lookahead, it is too special and may lead us to an endless - loop in error recovery. */ - yychar = YYUNDEF; - yytoken = YYSYMBOL_YYerror; - yyerror_range[1] = yylloc; - goto yyerrlab1; - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - { - YY_LAC_ESTABLISH; - goto yydefault; - } - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yytable_value_is_error (yyn)) - goto yyerrlab; - yyn = -yyn; - YY_LAC_ESTABLISH; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - yystate = yyn; - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - *++yylsp = yylloc; - - /* Discard the shifted token. */ - yychar = YYEMPTY; - YY_LAC_DISCARD ("shift"); - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - '$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - /* Default location. */ - YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); - yyerror_range[1] = yyloc; - YY_REDUCE_PRINT (yyn); - { - int yychar_backup = yychar; - switch (yyn) - { - case 2: /* program: block "." */ -#line 121 "spl.y" - { setProgAST((yyvsp[-1].block)); } -#line 1781 "spl.tab.c" - break; - - case 3: /* block: "begin" constDecls varDecls procDecls stmts "end" */ -#line 125 "spl.y" - { (yyval.block) = ast_block((yyvsp[-5].token),(yyvsp[-4].const_decls),(yyvsp[-3].var_decls),(yyvsp[-2].proc_decls),(yyvsp[-1].stmts)); } -#line 1787 "spl.tab.c" - break; - - case 4: /* constDecls: empty */ -#line 128 "spl.y" - { (yyval.const_decls) = ast_const_decls_empty((yyvsp[0].empty)); } -#line 1793 "spl.tab.c" - break; - - case 5: /* constDecls: constDecls constDecl */ -#line 130 "spl.y" - { (yyval.const_decls) = ast_const_decls((yyvsp[-1].const_decls), (yyvsp[0].const_decl)); } -#line 1799 "spl.tab.c" - break; - - case 6: /* empty: %empty */ -#line 134 "spl.y" - { file_location *file_loc - = file_location_make(lexer_filename(), lexer_line()); - (yyval.empty) = ast_empty(file_loc); - } -#line 1808 "spl.tab.c" - break; - - case 7: /* constDecl: "const" constDefList ";" */ -#line 140 "spl.y" - { (yyval.const_decl) = ast_const_decl((yyvsp[-1].const_def_list)); } -#line 1814 "spl.tab.c" - break; - - case 8: /* constDefList: constDef */ -#line 142 "spl.y" - { (yyval.const_def_list) = ast_const_def_list_singleton((yyvsp[0].const_def)); } -#line 1820 "spl.tab.c" - break; - - case 9: /* constDefList: constDefList "," constDef */ -#line 144 "spl.y" - { (yyval.const_def_list) = ast_const_def_list((yyvsp[-2].const_def_list), (yyvsp[0].const_def)); } -#line 1826 "spl.tab.c" - break; - - case 10: /* constDef: identsym "=" numbersym */ -#line 147 "spl.y" - { (yyval.const_def) = ast_const_def((yyvsp[-2].ident), (yyvsp[0].number)); } -#line 1832 "spl.tab.c" - break; - - case 11: /* varDecls: empty */ -#line 149 "spl.y" - { (yyval.var_decls) = ast_var_decls_empty((yyvsp[0].empty)); } -#line 1838 "spl.tab.c" - break; - - case 12: /* varDecls: varDecls varDecl */ -#line 150 "spl.y" - { (yyval.var_decls) = ast_var_decls((yyvsp[-1].var_decls), (yyvsp[0].var_decl)); } -#line 1844 "spl.tab.c" - break; - - case 13: /* varDecl: "var" identList ";" */ -#line 153 "spl.y" - { (yyval.var_decl) = ast_var_decl((yyvsp[-1].ident_list)); } -#line 1850 "spl.tab.c" - break; - - case 14: /* identList: identsym */ -#line 155 "spl.y" - { (yyval.ident_list) = ast_ident_list_singleton((yyvsp[0].ident)); } -#line 1856 "spl.tab.c" - break; - - case 15: /* identList: identList "," identsym */ -#line 156 "spl.y" - { (yyval.ident_list) = ast_ident_list((yyvsp[-2].ident_list), (yyvsp[0].ident)); } -#line 1862 "spl.tab.c" - break; - - case 16: /* procDecls: empty */ -#line 159 "spl.y" - { (yyval.proc_decls) = ast_proc_decls_empty((yyvsp[0].empty)); } -#line 1868 "spl.tab.c" - break; - - case 17: /* procDecls: procDecls procDecl */ -#line 160 "spl.y" - { (yyval.proc_decls) = ast_proc_decls((yyvsp[-1].proc_decls), (yyvsp[0].proc_decl)); } -#line 1874 "spl.tab.c" - break; - - case 18: /* procDecl: "proc" identsym block ";" */ -#line 163 "spl.y" - { (yyval.proc_decl) = ast_proc_decl((yyvsp[-2].ident), (yyvsp[-1].block)); } -#line 1880 "spl.tab.c" - break; - - case 19: /* stmts: empty */ -#line 165 "spl.y" - { (yyval.stmts) = ast_stmts_empty((yyvsp[0].empty)); } -#line 1886 "spl.tab.c" - break; - - case 20: /* stmts: stmtList */ -#line 166 "spl.y" - { (yyval.stmts) = ast_stmts((yyvsp[0].stmt_list)); } -#line 1892 "spl.tab.c" - break; - - case 21: /* stmtList: stmt */ -#line 169 "spl.y" - { (yyval.stmt_list) = ast_stmt_list_singleton((yyvsp[0].stmt)); } -#line 1898 "spl.tab.c" - break; - - case 22: /* stmtList: stmtList ";" stmt */ -#line 170 "spl.y" - { (yyval.stmt_list) = ast_stmt_list((yyvsp[-2].stmt_list),(yyvsp[0].stmt)); } -#line 1904 "spl.tab.c" - break; - - case 23: /* stmt: assignStmt */ -#line 173 "spl.y" - { (yyval.stmt) = ast_stmt_assign((yyvsp[0].assign_stmt)); } -#line 1910 "spl.tab.c" - break; - - case 24: /* stmt: callStmt */ -#line 174 "spl.y" - { (yyval.stmt) = ast_stmt_call((yyvsp[0].call_stmt)); } -#line 1916 "spl.tab.c" - break; - - case 25: /* stmt: ifStmt */ -#line 175 "spl.y" - { (yyval.stmt) = ast_stmt_if((yyvsp[0].if_stmt)); } -#line 1922 "spl.tab.c" - break; - - case 26: /* stmt: whileStmt */ -#line 176 "spl.y" - { (yyval.stmt) = ast_stmt_while((yyvsp[0].while_stmt)); } -#line 1928 "spl.tab.c" - break; - - case 27: /* stmt: readStmt */ -#line 177 "spl.y" - { (yyval.stmt) = ast_stmt_read((yyvsp[0].read_stmt)); } -#line 1934 "spl.tab.c" - break; - - case 28: /* stmt: printStmt */ -#line 178 "spl.y" - { (yyval.stmt) = ast_stmt_print((yyvsp[0].print_stmt)); } -#line 1940 "spl.tab.c" - break; - - case 29: /* stmt: blockStmt */ -#line 179 "spl.y" - { (yyval.stmt) = ast_stmt_block((yyvsp[0].block_stmt)); } -#line 1946 "spl.tab.c" - break; - - case 30: /* assignStmt: identsym ":=" expr */ -#line 182 "spl.y" - { (yyval.assign_stmt) = ast_assign_stmt((yyvsp[-2].ident),(yyvsp[0].expr)); } -#line 1952 "spl.tab.c" - break; - - case 31: /* callStmt: "call" identsym */ -#line 184 "spl.y" - { (yyval.call_stmt) = ast_call_stmt((yyvsp[0].ident)); } -#line 1958 "spl.tab.c" - break; - - case 32: /* ifStmt: "if" condition "then" stmts "else" stmts "end" */ -#line 187 "spl.y" - { (yyval.if_stmt) = ast_if_then_else_stmt((yyvsp[-5].condition), (yyvsp[-3].stmts), (yyvsp[-1].stmts)); } -#line 1964 "spl.tab.c" - break; - - case 33: /* ifStmt: "if" condition "then" stmts "end" */ -#line 189 "spl.y" - { (yyval.if_stmt) = ast_if_then_stmt((yyvsp[-3].condition), (yyvsp[-1].stmts)); } -#line 1970 "spl.tab.c" - break; - - case 34: /* whileStmt: "while" condition "do" stmts "end" */ -#line 193 "spl.y" - { (yyval.while_stmt) = ast_while_stmt((yyvsp[-3].condition),(yyvsp[-1].stmts)); } -#line 1976 "spl.tab.c" - break; - - case 35: /* readStmt: "read" identsym */ -#line 195 "spl.y" - { (yyval.read_stmt) = ast_read_stmt((yyvsp[0].ident)); } -#line 1982 "spl.tab.c" - break; - - case 36: /* printStmt: "print" expr */ -#line 197 "spl.y" - { (yyval.print_stmt) = ast_print_stmt((yyvsp[0].expr)); } -#line 1988 "spl.tab.c" - break; - - case 37: /* blockStmt: block */ -#line 199 "spl.y" - { (yyval.block_stmt) = ast_block_stmt((yyvsp[0].block)); } -#line 1994 "spl.tab.c" - break; - - case 38: /* condition: dbCondition */ -#line 201 "spl.y" - { (yyval.condition) = ast_condition_db((yyvsp[0].db_condition)); } -#line 2000 "spl.tab.c" - break; - - case 39: /* condition: relOpCondition */ -#line 202 "spl.y" - { (yyval.condition) = ast_condition_rel_op((yyvsp[0].rel_op_condition)); } -#line 2006 "spl.tab.c" - break; - - case 40: /* dbCondition: "divisible" expr "by" expr */ -#line 205 "spl.y" - { (yyval.db_condition) = ast_db_condition((yyvsp[-2].expr),(yyvsp[0].expr)); } -#line 2012 "spl.tab.c" - break; - - case 41: /* relOpCondition: expr relOp expr */ -#line 207 "spl.y" - { (yyval.rel_op_condition) = ast_rel_op_condition((yyvsp[-2].expr), (yyvsp[-1].token), (yyvsp[0].expr)); } -#line 2018 "spl.tab.c" - break; - - case 49: /* expr: expr "+" term */ -#line 213 "spl.y" - { (yyval.expr) = ast_expr_binary_op(ast_binary_op_expr((yyvsp[-2].expr), (yyvsp[-1].token), (yyvsp[0].expr))); } -#line 2024 "spl.tab.c" - break; - - case 50: /* expr: expr "-" term */ -#line 215 "spl.y" - { (yyval.expr) = ast_expr_binary_op(ast_binary_op_expr((yyvsp[-2].expr), (yyvsp[-1].token), (yyvsp[0].expr))); } -#line 2030 "spl.tab.c" - break; - - case 52: /* term: term "*" factor */ -#line 220 "spl.y" - { (yyval.expr) = ast_expr_binary_op(ast_binary_op_expr((yyvsp[-2].expr), (yyvsp[-1].token), (yyvsp[0].expr))); } -#line 2036 "spl.tab.c" - break; - - case 53: /* term: term "/" factor */ -#line 222 "spl.y" - { (yyval.expr) = ast_expr_binary_op(ast_binary_op_expr((yyvsp[-2].expr), (yyvsp[-1].token), (yyvsp[0].expr))); } -#line 2042 "spl.tab.c" - break; - - case 54: /* factor: identsym */ -#line 225 "spl.y" - { (yyval.expr) = ast_expr_ident((yyvsp[0].ident)); } -#line 2048 "spl.tab.c" - break; - - case 55: /* factor: numbersym */ -#line 226 "spl.y" - { (yyval.expr) = ast_expr_number((yyvsp[0].number)); } -#line 2054 "spl.tab.c" - break; - - case 56: /* factor: "-" factor */ -#line 227 "spl.y" - { (yyval.expr) = ast_expr_signed_expr((yyvsp[-1].token), (yyvsp[0].expr)); } -#line 2060 "spl.tab.c" - break; - - case 57: /* factor: "+" factor */ -#line 228 "spl.y" - { (yyval.expr) = ast_expr_signed_expr((yyvsp[-1].token), (yyvsp[0].expr)); } -#line 2066 "spl.tab.c" - break; - - case 58: /* factor: "(" expr ")" */ -#line 229 "spl.y" - { (yyval.expr) = (yyvsp[-1].expr); } -#line 2072 "spl.tab.c" - break; - - -#line 2076 "spl.tab.c" - - default: break; - } - if (yychar_backup != yychar) - YY_LAC_DISCARD ("yychar change"); - } - /* User semantic actions sometimes alter yychar, and that requires - that yytoken be updated with the new translation. We take the - approach of translating immediately before every use of yytoken. - One alternative is translating here after every semantic action, - but that translation would be missed if the semantic action invokes - YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or - if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an - incorrect destructor might then be invoked immediately. In the - case of YYERROR or YYBACKUP, subsequent parser actions might lead - to an incorrect destructor call or verbose syntax error message - before the lookahead is translated. */ - YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - - *++yyvsp = yyval; - *++yylsp = yyloc; - - /* Now 'shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - { - const int yylhs = yyr1[yyn] - YYNTOKENS; - const int yyi = yypgoto[yylhs] + *yyssp; - yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp - ? yytable[yyi] - : yydefgoto[yylhs]); - } - - goto yynewstate; - - -/*--------------------------------------. -| yyerrlab -- here on detecting error. | -`--------------------------------------*/ -yyerrlab: - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; - { - yypcontext_t yyctx - = {yyssp, yyesa, &yyes, &yyes_capacity, yytoken, &yylloc}; - char const *yymsgp = YY_("syntax error"); - int yysyntax_error_status; - if (yychar != YYEMPTY) - YY_LAC_ESTABLISH; - yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); - if (yysyntax_error_status == 0) - yymsgp = yymsg; - else if (yysyntax_error_status == -1) - { - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = YY_CAST (char *, - YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc))); - if (yymsg) - { - yysyntax_error_status - = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); - yymsgp = yymsg; - } - else - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - yysyntax_error_status = YYENOMEM; - } - } - yyerror (file_name, yymsgp); - if (yysyntax_error_status == YYENOMEM) - YYNOMEM; - } - } - - yyerror_range[1] = yylloc; - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval, &yylloc, file_name); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - /* Pacify compilers when the user code never invokes YYERROR and the - label yyerrorlab therefore never appears in user code. */ - if (0) - YYERROR; - ++yynerrs; - - /* Do not reclaim the symbols of the rule whose action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - /* Pop stack until we find a state that shifts the error token. */ - for (;;) - { - yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) - { - yyn += YYSYMBOL_YYerror; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - yyerror_range[1] = *yylsp; - yydestruct ("Error: popping", - YY_ACCESSING_SYMBOL (yystate), yyvsp, yylsp, file_name); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - /* If the stack popping above didn't lose the initial context for the - current lookahead token, the shift below will for sure. */ - YY_LAC_DISCARD ("error recovery"); - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - yyerror_range[2] = yylloc; - ++yylsp; - YYLLOC_DEFAULT (*yylsp, yyerror_range, 2); - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturnlab; - - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturnlab; - - -/*-----------------------------------------------------------. -| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. | -`-----------------------------------------------------------*/ -yyexhaustedlab: - yyerror (file_name, YY_("memory exhausted")); - yyresult = 2; - goto yyreturnlab; - - -/*----------------------------------------------------------. -| yyreturnlab -- parsing is finished, clean up and return. | -`----------------------------------------------------------*/ -yyreturnlab: - if (yychar != YYEMPTY) - { - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = YYTRANSLATE (yychar); - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval, &yylloc, file_name); - } - /* Do not reclaim the symbols of the rule whose action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - YY_ACCESSING_SYMBOL (+*yyssp), yyvsp, yylsp, file_name); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif - if (yyes != yyesa) - YYSTACK_FREE (yyes); - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - return yyresult; -} - -#line 232 "spl.y" - - -// Set the program's ast to be ast -void setProgAST(block_t ast) { progast = ast; } diff --git a/spl.tab.h b/spl.tab.h deleted file mode 100755 index e147159..0000000 --- a/spl.tab.h +++ /dev/null @@ -1,133 +0,0 @@ -/* A Bison parser, made by GNU Bison 3.8.2. */ - -/* Bison interface for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, - Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, - especially those whose name start with YY_ or yy_. They are - private implementation details that can be changed or removed. */ - -#ifndef YY_YY_SPL_TAB_H_INCLUDED -# define YY_YY_SPL_TAB_H_INCLUDED -/* Debug traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int yydebug; -#endif -/* "%code requires" blocks. */ -#line 7 "spl.y" - - - /* Including "ast.h" must be at the top, to define the AST type */ -#include "ast.h" -#include "machine_types.h" -#include "parser_types.h" -#include "lexer.h" - - /* Report an error to the user on stderr */ -extern void yyerror(const char *filename, const char *msg); - - -#line 62 "spl.tab.h" - -/* Token kinds. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - enum yytokentype - { - YYEMPTY = -2, - YYEOF = 0, /* "end of file" */ - YYerror = 256, /* error */ - YYUNDEF = 257, /* "invalid token" */ - identsym = 258, /* identsym */ - numbersym = 259, /* numbersym */ - plussym = 260, /* "+" */ - minussym = 261, /* "-" */ - multsym = 262, /* "*" */ - divsym = 263, /* "/" */ - periodsym = 264, /* "." */ - semisym = 265, /* ";" */ - eqsym = 266, /* "=" */ - commasym = 267, /* "," */ - becomessym = 268, /* ":=" */ - lparensym = 269, /* "(" */ - rparensym = 270, /* ")" */ - constsym = 271, /* "const" */ - varsym = 272, /* "var" */ - procsym = 273, /* "proc" */ - callsym = 274, /* "call" */ - beginsym = 275, /* "begin" */ - endsym = 276, /* "end" */ - ifsym = 277, /* "if" */ - thensym = 278, /* "then" */ - elsesym = 279, /* "else" */ - whilesym = 280, /* "while" */ - dosym = 281, /* "do" */ - readsym = 282, /* "read" */ - printsym = 283, /* "print" */ - divisiblesym = 284, /* "divisible" */ - bysym = 285, /* "by" */ - eqeqsym = 286, /* "==" */ - neqsym = 287, /* "!=" */ - ltsym = 288, /* "<" */ - leqsym = 289, /* "<=" */ - gtsym = 290, /* ">" */ - geqsym = 291 /* ">=" */ - }; - typedef enum yytokentype yytoken_kind_t; -#endif - -/* Value type. */ - -/* Location type. */ -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE YYLTYPE; -struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -}; -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - - -extern YYSTYPE yylval; -extern YYLTYPE yylloc; - -int yyparse (char const *file_name); - - -#endif /* !YY_YY_SPL_TAB_H_INCLUDED */ diff --git a/spl.y b/spl.y deleted file mode 100755 index 4549683..0000000 --- a/spl.y +++ /dev/null @@ -1,235 +0,0 @@ - /* $Id: spl.y,v 1.1 2024/10/23 12:17:38 leavens Exp $ */ - -%code top { -#include -} - -%code requires { - - /* Including "ast.h" must be at the top, to define the AST type */ -#include "ast.h" -#include "machine_types.h" -#include "parser_types.h" -#include "lexer.h" - - /* Report an error to the user on stderr */ -extern void yyerror(const char *filename, const char *msg); - -} /* end of %code requires */ - -%verbose -%define parse.lac full -%define parse.error detailed - - /* the following passes file_name to yyerror, - and declares it as an formal parameter of yyparse. */ -%parse-param { char const *file_name } - -%token identsym -%token numbersym -%token plussym "+" -%token minussym "-" -%token multsym "*" -%token divsym "/" - -%token periodsym "." -%token semisym ";" -%token eqsym "=" -%token commasym "," -%token becomessym ":=" -%token lparensym "(" -%token rparensym ")" - -%token constsym "const" -%token varsym "var" -%token procsym "proc" -%token callsym "call" -%token beginsym "begin" -%token endsym "end" -%token ifsym "if" -%token thensym "then" -%token elsesym "else" -%token whilesym "while" -%token dosym "do" -%token readsym "read" -%token printsym "print" -%token divisiblesym "divisible" -%token bysym "by" - -%token eqeqsym "==" -%token neqsym "!=" -%token ltsym "<" -%token leqsym "<=" -%token gtsym ">" -%token geqsym ">=" - -%type program - -%type block - -%type constDecls -%type constDecl -%type constDefList -%type constDef - -%type varDecls -%type varDecl -%type identList - -%type procDecls -%type procDecl - - -%type stmts -%type empty -%type stmtList -%type stmt -%type assignStmt -%type callStmt -%type ifStmt -%type whileStmt -%type readStmt -%type printStmt -%type blockStmt - -%type condition -%type dbCondition -%type relOpCondition -%type relOp - -%type expr -%type term -%type factor - -%start program - -%code { - /* extern declarations provided by the lexer */ -extern int yylex(void); - - /* The AST for the program, set by the semantic action - for the nonterminal program. */ -block_t progast; - - /* Set the program's ast to be t */ -extern void setProgAST(block_t t); -} - -%% - /* Write your grammar rules below and before the next %% */ - -program : block "." { setProgAST($1); } ; - - -block : "begin" constDecls varDecls procDecls stmts "end" - { $$ = ast_block($1,$2,$3,$4,$5); } - ; - -constDecls : empty { $$ = ast_const_decls_empty($1); } - | constDecls constDecl - { $$ = ast_const_decls($1, $2); } - ; - -empty : %empty - { file_location *file_loc - = file_location_make(lexer_filename(), lexer_line()); - $$ = ast_empty(file_loc); - } - ; - -constDecl : "const" constDefList ";" { $$ = ast_const_decl($2); } ; - -constDefList : constDef { $$ = ast_const_def_list_singleton($1); } - | constDefList "," constDef - { $$ = ast_const_def_list($1, $3); } - ; - -constDef : identsym "=" numbersym { $$ = ast_const_def($1, $3); } ; - -varDecls : empty { $$ = ast_var_decls_empty($1); } - | varDecls varDecl { $$ = ast_var_decls($1, $2); } - ; - -varDecl : "var" identList ";" { $$ = ast_var_decl($2); } ; - -identList : identsym { $$ = ast_ident_list_singleton($1); } - | identList "," identsym { $$ = ast_ident_list($1, $3); } - ; - -procDecls : empty { $$ = ast_proc_decls_empty($1); } - | procDecls procDecl { $$ = ast_proc_decls($1, $2); } - ; - -procDecl : "proc" identsym block ";" { $$ = ast_proc_decl($2, $3); } ; - -stmts : empty { $$ = ast_stmts_empty($1); } - | stmtList { $$ = ast_stmts($1); } - ; - -stmtList : stmt { $$ = ast_stmt_list_singleton($1); } - | stmtList ";" stmt { $$ = ast_stmt_list($1,$3); } - ; - -stmt : assignStmt { $$ = ast_stmt_assign($1); } - | callStmt { $$ = ast_stmt_call($1); } - | ifStmt { $$ = ast_stmt_if($1); } - | whileStmt { $$ = ast_stmt_while($1); } - | readStmt { $$ = ast_stmt_read($1); } - | printStmt { $$ = ast_stmt_print($1); } - | blockStmt { $$ = ast_stmt_block($1); } - ; - -assignStmt : identsym ":=" expr { $$ = ast_assign_stmt($1,$3); } ; - -callStmt : "call" identsym { $$ = ast_call_stmt($2); } ; - -ifStmt : "if" condition "then" stmts "else" stmts "end" - { $$ = ast_if_then_else_stmt($2, $4, $6); } - | "if" condition "then" stmts "end" - { $$ = ast_if_then_stmt($2, $4); } - ; - -whileStmt : "while" condition "do" stmts "end" - { $$ = ast_while_stmt($2,$4); } ; - -readStmt : "read" identsym { $$ = ast_read_stmt($2); } ; - -printStmt : "print" expr { $$ = ast_print_stmt($2); } ; - -blockStmt : block { $$ = ast_block_stmt($1); } ; - -condition : dbCondition { $$ = ast_condition_db($1); } - | relOpCondition { $$ = ast_condition_rel_op($1); } - ; - -dbCondition : "divisible" expr "by" expr { $$ = ast_db_condition($2,$4); } ; - -relOpCondition : expr relOp expr { $$ = ast_rel_op_condition($1, $2, $3); } ; - -relOp : "==" | "!=" | "<" | "<=" | ">" | ">=" ; - -expr : term - | expr "+" term - { $$ = ast_expr_binary_op(ast_binary_op_expr($1, $2, $3)); } - | expr "-" term - { $$ = ast_expr_binary_op(ast_binary_op_expr($1, $2, $3)); } - ; - -term : factor - | term "*" factor - { $$ = ast_expr_binary_op(ast_binary_op_expr($1, $2, $3)); } - | term "/" factor - { $$ = ast_expr_binary_op(ast_binary_op_expr($1, $2, $3)); } - ; - -factor : identsym { $$ = ast_expr_ident($1); } - | numbersym { $$ = ast_expr_number($1); } - | "-" factor { $$ = ast_expr_signed_expr($1, $2); } - | "+" factor { $$ = ast_expr_signed_expr($1, $2); } - | "(" expr ")" { $$ = $2; } - ; - -%% - -// Set the program's ast to be ast -void setProgAST(block_t ast) { progast = ast; } diff --git a/spl_lexer.c b/spl_lexer.c deleted file mode 100755 index cbf6aa4..0000000 --- a/spl_lexer.c +++ /dev/null @@ -1,2236 +0,0 @@ -#line 1 "spl_lexer.c" - -#line 3 "spl_lexer.c" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 6 -#define YY_FLEX_SUBMINOR_VERSION 4 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -#ifdef yyget_lval -#define yyget_lval_ALREADY_DEFINED -#else -#define yyget_lval yyget_lval -#endif - -#ifdef yyset_lval -#define yyset_lval_ALREADY_DEFINED -#else -#define yyset_lval yyset_lval -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include -#include -#include -#include - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have . Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#ifndef SIZE_MAX -#define SIZE_MAX (~(size_t)0) -#endif - -#endif /* ! C99 */ - -#endif /* ! FLEXINT_H */ - -/* begin standard C++ headers. */ - -/* TODO: this is always defined, so inline it */ -#define yyconst const - -#if defined(__GNUC__) && __GNUC__ >= 3 -#define yynoreturn __attribute__((__noreturn__)) -#else -#define yynoreturn -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an - * integer in range [0..255] for use as an array index. - */ -#define YY_SC_TO_UI(c) ((YY_CHAR) (c)) - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN (yy_start) = 1 + 2 * -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START (((yy_start) - 1) / 2) -#define YYSTATE YY_START -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE yyrestart( yyin ) -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k. - * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. - * Ditto for the __ia64__ case accordingly. - */ -#define YY_BUF_SIZE 32768 -#else -#define YY_BUF_SIZE 16384 -#endif /* __ia64__ */ -#endif - -/* The state buf must be large enough to hold one state per character in the main buffer. - */ -#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -extern int yyleng; - -extern FILE *yyin, *yyout; - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - - /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires - * access to the local variable yy_act. Since yyless() is a macro, it would break - * existing scanners that call yyless() from OUTSIDE yylex. - * One obvious solution it to make yy_act a global. I tried that, and saw - * a 5% performance hit in a non-yylineno scanner, because yy_act is - * normally declared as a register variable-- so it is not worth it. - */ - #define YY_LESS_LINENO(n) \ - do { \ - int yyl;\ - for ( yyl = n; yyl < yyleng; ++yyl )\ - if ( yytext[yyl] == '\n' )\ - --yylineno;\ - }while(0) - #define YY_LINENO_REWIND_TO(dst) \ - do {\ - const char *p;\ - for ( p = yy_cp-1; p >= (dst); --p)\ - if ( *p == '\n' )\ - --yylineno;\ - }while(0) - -/* Return all but the first "n" matched characters back to the input stream. */ -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - *yy_cp = (yy_hold_char); \ - YY_RESTORE_YY_MORE_OFFSET \ - (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) -#define unput(c) yyunput( c, (yytext_ptr) ) - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - int yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via yyrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -/* Stack of input buffers. */ -static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ -static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ -static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - * - * Returns the top of the stack, or NULL. - */ -#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ - ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ - : NULL) -/* Same as previous macro, but useful when we know that the buffer stack is not - * NULL or when we need an lvalue. For internal use only. - */ -#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] - -/* yy_hold_char holds the character lost when yytext is formed. */ -static char yy_hold_char; -static int yy_n_chars; /* number of characters read into yy_ch_buf */ -int yyleng; - -/* Points to current character in buffer. */ -static char *yy_c_buf_p = NULL; -static int yy_init = 0; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ - -/* Flag which is used to allow yywrap()'s to do buffer switches - * instead of setting up a fresh yyin. A bit of a hack ... - */ -static int yy_did_buffer_switch_on_eof; - -void yyrestart ( FILE *input_file ); -void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); -YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); -void yy_delete_buffer ( YY_BUFFER_STATE b ); -void yy_flush_buffer ( YY_BUFFER_STATE b ); -void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); -void yypop_buffer_state ( void ); - -static void yyensure_buffer_stack ( void ); -static void yy_load_buffer_state ( void ); -static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file ); -#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER ) - -YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); -YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); -YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len ); - -void *yyalloc ( yy_size_t ); -void *yyrealloc ( void *, yy_size_t ); -void yyfree ( void * ); - -#define yy_new_buffer yy_create_buffer -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! YY_CURRENT_BUFFER ){ \ - yyensure_buffer_stack (); \ - YY_CURRENT_BUFFER_LVALUE = \ - yy_create_buffer( yyin, YY_BUF_SIZE ); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ - } -#define yy_set_bol(at_bol) \ - { \ - if ( ! YY_CURRENT_BUFFER ){\ - yyensure_buffer_stack (); \ - YY_CURRENT_BUFFER_LVALUE = \ - yy_create_buffer( yyin, YY_BUF_SIZE ); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ - } -#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) - -/* Begin user sect3 */ -typedef flex_uint8_t YY_CHAR; - -FILE *yyin = NULL, *yyout = NULL; - -typedef int yy_state_type; - -extern int yylineno; -int yylineno = 1; - -extern char *yytext; -#ifdef yytext_ptr -#undef yytext_ptr -#endif -#define yytext_ptr yytext - -static yy_state_type yy_get_previous_state ( void ); -static yy_state_type yy_try_NUL_trans ( yy_state_type current_state ); -static int yy_get_next_buffer ( void ); -static void yynoreturn yy_fatal_error ( const char* msg ); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - (yytext_ptr) = yy_bp; \ - yyleng = (int) (yy_cp - yy_bp); \ - (yy_hold_char) = *yy_cp; \ - *yy_cp = '\0'; \ - (yy_c_buf_p) = yy_cp; -#define YY_NUM_RULES 39 -#define YY_END_OF_BUFFER 40 -/* This struct is not used in this scanner, - but its presence is necessary. */ -struct yy_trans_info - { - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; -static const flex_int16_t yy_accept[90] = - { 0, - 0, 0, 40, 38, 1, 3, 1, 38, 2, 20, - 21, 7, 5, 11, 6, 9, 8, 4, 38, 10, - 19, 14, 18, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 3, 15, 2, 4, 12, 16, - 13, 17, 37, 37, 36, 37, 37, 37, 32, 37, - 37, 28, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 27, 37, 37, 37, 37, 23, 37, 37, - 25, 37, 37, 30, 37, 24, 33, 29, 37, 26, - 22, 37, 34, 31, 37, 37, 37, 35, 0 - } ; - -static const YY_CHAR yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 2, 2, 4, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 5, 1, 1, 1, 6, 1, 1, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 16, 17, 18, - 19, 20, 1, 1, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 1, 1, 1, 1, 1, 1, 22, 23, 24, 25, - - 26, 27, 28, 29, 30, 21, 21, 31, 21, 32, - 33, 34, 21, 35, 36, 37, 21, 38, 39, 21, - 40, 21, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static const YY_CHAR yy_meta[41] = - { 0, - 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 - } ; - -static const flex_int16_t yy_base[92] = - { 0, - 0, 0, 97, 98, 98, 98, 93, 76, 0, 98, - 98, 98, 98, 98, 98, 98, 98, 79, 74, 98, - 73, 72, 71, 0, 15, 20, 13, 13, 62, 53, - 61, 57, 63, 55, 98, 98, 0, 68, 98, 98, - 98, 98, 0, 54, 0, 50, 48, 41, 0, 42, - 52, 0, 17, 54, 49, 39, 43, 42, 40, 34, - 39, 42, 0, 35, 42, 40, 32, 0, 32, 30, - 0, 24, 24, 0, 22, 0, 0, 0, 31, 0, - 0, 24, 0, 0, 29, 20, 23, 0, 98, 55, - 45 - - } ; - -static const flex_int16_t yy_def[92] = - { 0, - 89, 1, 89, 89, 89, 89, 89, 89, 90, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 89, 89, 90, 89, 89, 89, - 89, 89, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 91, 91, 91, 0, 89, - 89 - - } ; - -static const flex_int16_t yy_nxt[139] = - { 0, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 24, 25, 26, 27, 28, 24, 24, 24, 29, - 24, 24, 24, 30, 31, 24, 32, 33, 34, 24, - 44, 46, 48, 50, 51, 49, 64, 43, 88, 65, - 87, 86, 47, 85, 45, 37, 84, 37, 83, 82, - 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, - 71, 70, 69, 68, 67, 66, 63, 62, 61, 60, - 59, 58, 38, 57, 56, 55, 54, 53, 52, 42, - 41, 40, 39, 38, 36, 35, 89, 3, 89, 89, - - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89 - } ; - -static const flex_int16_t yy_chk[139] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 25, 26, 27, 28, 28, 27, 53, 91, 87, 53, - 86, 85, 26, 82, 25, 90, 79, 90, 75, 73, - 72, 70, 69, 67, 66, 65, 64, 62, 61, 60, - 59, 58, 57, 56, 55, 54, 51, 50, 48, 47, - 46, 44, 38, 34, 33, 32, 31, 30, 29, 23, - 22, 21, 19, 18, 8, 7, 3, 89, 89, 89, - - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, - 89, 89, 89, 89, 89, 89, 89, 89 - } ; - -/* Table of booleans, true if rule could match eol. */ -static const flex_int32_t yy_rule_can_match_eol[40] = - { 0, -0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - }; - -static yy_state_type yy_last_accepting_state; -static char *yy_last_accepting_cpos; - -extern int yy_flex_debug; -int yy_flex_debug = 0; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -char *yytext; -#line 1 "spl_lexer.l" -/* $Id: spl_lexer.l,v 1.1 2024/10/23 12:17:38 leavens Exp $ */ -/* Lexical Analyzer for SPL */ -#line 10 "spl_lexer.l" -#include -#include -#include -#include -#include -#include "ast.h" -#include "parser_types.h" -#include "utilities.h" -#include "lexer.h" - - /* Tokens generated by Bison */ -#include "spl.tab.h" - - /* need declaration of fileno, part of the C standard library. - (Putting an extern declaration here shuts off a gcc warning.) */ -extern int fileno(FILE *stream); - -/* The filename of the file being read */ -static char *input_filename; - -/* Have any errors been noted? */ -static bool errors_noted; - -/* The value of a token */ -extern YYSTYPE yylval; - -/* The FILE used by the generated lexer */ -extern FILE *yyin; - -// We are not using yyunput or input -#define YY_NO_UNPUT -#define YY_NO_INPUT - -#undef yywrap /* sometimes a macro by default */ - -// apparently strdup is not declared in -extern char *strdup(const char *s); - -// set the lexer's value for a token in yylval as an AST -static void tok2ast(int code) { - AST t; - t.token.file_loc = file_location_make(input_filename, yylineno); - t.token.type_tag = token_ast; - t.token.code = code; - t.token.text = strdup(yytext); - yylval = t; -} - -static void ident2ast(const char *name) { - AST t; - assert(input_filename != NULL); - t.ident.file_loc = file_location_make(input_filename, yylineno); - t.ident.type_tag = ident_ast; - t.ident.name = strdup(name); - yylval = t; -} - -static void number2ast(unsigned int val) -{ - AST t; - t.number.file_loc = file_location_make(input_filename, yylineno); - t.number.type_tag = number_ast; - t.number.text = strdup(yytext); - t.number.value = val; - yylval = t; -} - -#line 608 "spl_lexer.c" -#line 80 "spl_lexer.l" - /* you can add actual definitions below, before the %% */ -#line 611 "spl_lexer.c" - -#define INITIAL 0 - -#ifndef YY_NO_UNISTD_H -/* Special case for "unistd.h", since it is non-ANSI. We include it way - * down here because we want the user's section 1 to have been scanned first. - * The user has a chance to override it with an option. - */ -#include -#endif - -#ifndef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#endif - -static int yy_init_globals ( void ); - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int yylex_destroy ( void ); - -int yyget_debug ( void ); - -void yyset_debug ( int debug_flag ); - -YY_EXTRA_TYPE yyget_extra ( void ); - -void yyset_extra ( YY_EXTRA_TYPE user_defined ); - -FILE *yyget_in ( void ); - -void yyset_in ( FILE * _in_str ); - -FILE *yyget_out ( void ); - -void yyset_out ( FILE * _out_str ); - - int yyget_leng ( void ); - -char *yyget_text ( void ); - -int yyget_lineno ( void ); - -void yyset_lineno ( int _line_number ); - -YYSTYPE * yyget_lval ( void ); - -void yyset_lval ( YYSTYPE * yylval_param ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int yywrap ( void ); -#else -extern int yywrap ( void ); -#endif -#endif - -#ifndef YY_NO_UNPUT - - static void yyunput ( int c, char *buf_ptr ); - -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy ( char *, const char *, int ); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen ( const char * ); -#endif - -#ifndef YY_NO_INPUT -#ifdef __cplusplus -static int yyinput ( void ); -#else -static int input ( void ); -#endif - -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k */ -#define YY_READ_BUF_SIZE 16384 -#else -#define YY_READ_BUF_SIZE 8192 -#endif /* __ia64__ */ -#endif - -/* Copy whatever the last rule matched to the standard output. */ -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ - { \ - int c = '*'; \ - int n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else \ - { \ - errno=0; \ - while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ - { \ - if( errno != EINTR) \ - { \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - break; \ - } \ - errno=0; \ - clearerr(yyin); \ - } \ - }\ -\ - -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) -#endif - -/* end tables serialization structures and prototypes */ - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int yylex \ - (YYSTYPE * yylval_param ); - -#define YY_DECL int yylex \ - (YYSTYPE * yylval_param ) -#endif /* !YY_DECL */ - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK /*LINTED*/break; -#endif - -#define YY_RULE_SETUP \ - YY_USER_ACTION - -/** The main scanner function which does all the work. - */ -YY_DECL -{ - yy_state_type yy_current_state; - char *yy_cp, *yy_bp; - int yy_act; - - YYSTYPE * yylval; - - yylval = yylval_param; - - if ( !(yy_init) ) - { - (yy_init) = 1; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! (yy_start) ) - (yy_start) = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! YY_CURRENT_BUFFER ) { - yyensure_buffer_stack (); - YY_CURRENT_BUFFER_LVALUE = - yy_create_buffer( yyin, YY_BUF_SIZE ); - } - - yy_load_buffer_state( ); - } - - { -#line 94 "spl_lexer.l" - - - /* fill in the rules for your lexer here! */ - -#line 843 "spl_lexer.c" - - while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ - { - yy_cp = (yy_c_buf_p); - - /* Support of yytext. */ - *yy_cp = (yy_hold_char); - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = (yy_start); -yy_match: - do - { - YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 90 ) - yy_c = yy_meta[yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - ++yy_cp; - } - while ( yy_base[yy_current_state] != 98 ); - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - yy_act = yy_accept[yy_current_state]; - } - - YY_DO_BEFORE_ACTION; - - if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) - { - int yyl; - for ( yyl = 0; yyl < yyleng; ++yyl ) - if ( yytext[yyl] == '\n' ) - - yylineno++; -; - } - -do_action: /* This label is used only to access EOF actions. */ - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = (yy_hold_char); - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - goto yy_find_action; - -case 1: -YY_RULE_SETUP -#line 98 "spl_lexer.l" -{ ; } /* do nothing */ - YY_BREAK -case 2: -YY_RULE_SETUP -#line 99 "spl_lexer.l" -{ ; } /* ignore comments */ - YY_BREAK -case 3: -/* rule 3 can match eol */ -YY_RULE_SETUP -#line 100 "spl_lexer.l" -{ ; } /* ignore EOL */ - YY_BREAK -case 4: -YY_RULE_SETUP -#line 102 "spl_lexer.l" -{ unsigned long lval; - int ssf_ret; - ssf_ret = sscanf(yytext, "%lu", &lval); - if (ssf_ret != 1) { - bail_with_error("Number (%s) couldn't be read by lexer!", - yytext); - } - if (INT_MAX < lval ) { - char msgbuf[512]; - if (strlen(yytext) >= 300) { - snprintf(msgbuf, 327, "Number (%s...) is too large!", - yytext); - } else { - sprintf(msgbuf, "Number (%s) is too large!", yytext); - } - yyerror(lexer_filename(), msgbuf); - } - number2ast((int) lval); - return numbersym; - } - YY_BREAK -case 5: -YY_RULE_SETUP -#line 123 "spl_lexer.l" -{ tok2ast(plussym); return plussym; } - YY_BREAK -case 6: -YY_RULE_SETUP -#line 124 "spl_lexer.l" -{ tok2ast(minussym); return minussym; } - YY_BREAK -case 7: -YY_RULE_SETUP -#line 125 "spl_lexer.l" -{ tok2ast(multsym); return multsym; } - YY_BREAK -case 8: -YY_RULE_SETUP -#line 126 "spl_lexer.l" -{ tok2ast(divsym); return divsym; } - YY_BREAK -case 9: -YY_RULE_SETUP -#line 128 "spl_lexer.l" -{ return periodsym; } - YY_BREAK -case 10: -YY_RULE_SETUP -#line 129 "spl_lexer.l" -{ return semisym; } - YY_BREAK -case 11: -YY_RULE_SETUP -#line 130 "spl_lexer.l" -{ return commasym; } - YY_BREAK -case 12: -YY_RULE_SETUP -#line 131 "spl_lexer.l" -{ return becomessym; } - YY_BREAK -case 13: -YY_RULE_SETUP -#line 132 "spl_lexer.l" -{ tok2ast(eqsym); return eqeqsym; } - YY_BREAK -case 14: -YY_RULE_SETUP -#line 133 "spl_lexer.l" -{ tok2ast(eqsym); return eqsym; } - YY_BREAK -case 15: -YY_RULE_SETUP -#line 134 "spl_lexer.l" -{ tok2ast(neqsym); return neqsym; } - YY_BREAK -case 16: -YY_RULE_SETUP -#line 135 "spl_lexer.l" -{ tok2ast(leqsym); return leqsym; } - YY_BREAK -case 17: -YY_RULE_SETUP -#line 136 "spl_lexer.l" -{ tok2ast(geqsym); return geqsym; } - YY_BREAK -case 18: -YY_RULE_SETUP -#line 137 "spl_lexer.l" -{ tok2ast(gtsym); return gtsym; } - YY_BREAK -case 19: -YY_RULE_SETUP -#line 138 "spl_lexer.l" -{ tok2ast(ltsym); return ltsym; } - YY_BREAK -case 20: -YY_RULE_SETUP -#line 139 "spl_lexer.l" -{ tok2ast(lparensym); return lparensym; } - YY_BREAK -case 21: -YY_RULE_SETUP -#line 140 "spl_lexer.l" -{ tok2ast(rparensym); return rparensym; } - YY_BREAK -case 22: -YY_RULE_SETUP -#line 142 "spl_lexer.l" -{ tok2ast(constsym); return constsym; } - YY_BREAK -case 23: -YY_RULE_SETUP -#line 143 "spl_lexer.l" -{ tok2ast(varsym); return varsym; } - YY_BREAK -case 24: -YY_RULE_SETUP -#line 144 "spl_lexer.l" -{ tok2ast(procsym); return procsym; } - YY_BREAK -case 25: -YY_RULE_SETUP -#line 145 "spl_lexer.l" -{ tok2ast(callsym); return callsym; } - YY_BREAK -case 26: -YY_RULE_SETUP -#line 146 "spl_lexer.l" -{ tok2ast(beginsym); return beginsym; } - YY_BREAK -case 27: -YY_RULE_SETUP -#line 147 "spl_lexer.l" -{ tok2ast(endsym); return endsym; } - YY_BREAK -case 28: -YY_RULE_SETUP -#line 148 "spl_lexer.l" -{ tok2ast(ifsym); return ifsym; } - YY_BREAK -case 29: -YY_RULE_SETUP -#line 149 "spl_lexer.l" -{ tok2ast(thensym); return thensym; } - YY_BREAK -case 30: -YY_RULE_SETUP -#line 150 "spl_lexer.l" -{ tok2ast(elsesym); return elsesym; } - YY_BREAK -case 31: -YY_RULE_SETUP -#line 151 "spl_lexer.l" -{ tok2ast(whilesym); return whilesym; } - YY_BREAK -case 32: -YY_RULE_SETUP -#line 152 "spl_lexer.l" -{ tok2ast(dosym); return dosym; } - YY_BREAK -case 33: -YY_RULE_SETUP -#line 153 "spl_lexer.l" -{ tok2ast(readsym); return readsym; } - YY_BREAK -case 34: -YY_RULE_SETUP -#line 154 "spl_lexer.l" -{ tok2ast(printsym); return printsym; } - YY_BREAK -case 35: -YY_RULE_SETUP -#line 155 "spl_lexer.l" -{ tok2ast(divisiblesym); return divisiblesym; } - YY_BREAK -case 36: -YY_RULE_SETUP -#line 156 "spl_lexer.l" -{ tok2ast(bysym); return bysym; } - YY_BREAK -case 37: -YY_RULE_SETUP -#line 158 "spl_lexer.l" -{ ident2ast(yytext); return identsym; } - YY_BREAK -case 38: -YY_RULE_SETUP -#line 160 "spl_lexer.l" -{ char msgbuf[512]; - sprintf(msgbuf, "invalid character: '%c' ('\\0%o')", *yytext, *yytext); - yyerror(lexer_filename(), msgbuf); - } - YY_BREAK -case 39: -YY_RULE_SETUP -#line 164 "spl_lexer.l" -ECHO; - YY_BREAK -#line 1128 "spl_lexer.c" -case YY_STATE_EOF(INITIAL): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = (yy_hold_char); - YY_RESTORE_YY_MORE_OFFSET - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * yylex(). If so, then we have to assure - * consistency between YY_CURRENT_BUFFER and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( ); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++(yy_c_buf_p); - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = (yy_c_buf_p); - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer( ) ) - { - case EOB_ACT_END_OF_FILE: - { - (yy_did_buffer_switch_on_eof) = 0; - - if ( yywrap( ) ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - (yy_c_buf_p) = - (yytext_ptr) + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( ); - - yy_cp = (yy_c_buf_p); - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - (yy_c_buf_p) = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; - - yy_current_state = yy_get_previous_state( ); - - yy_cp = (yy_c_buf_p); - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ - } /* end of user's declarations */ -} /* end of yylex */ - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ -static int yy_get_next_buffer (void) -{ - char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - char *source = (yytext_ptr); - int number_to_move, i; - int ret_val; - - if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; - - else - { - int num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; - - int yy_c_buf_p_offset = - (int) ((yy_c_buf_p) - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - yyrealloc( (void *) b->yy_ch_buf, - (yy_size_t) (b->yy_buf_size + 2) ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = NULL; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; - - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - (yy_n_chars), num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - if ( (yy_n_chars) == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - yyrestart( yyin ); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ - int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( - (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); - /* "- 2" to take care of EOB's */ - YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); - } - - (yy_n_chars) += number_to_move; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; - - (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; - - return ret_val; -} - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - - static yy_state_type yy_get_previous_state (void) -{ - yy_state_type yy_current_state; - char *yy_cp; - - yy_current_state = (yy_start); - - for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) - { - YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 90 ) - yy_c = yy_meta[yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - } - - return yy_current_state; -} - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) -{ - int yy_is_jam; - char *yy_cp = (yy_c_buf_p); - - YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 90 ) - yy_c = yy_meta[yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - yy_is_jam = (yy_current_state == 89); - - return yy_is_jam ? 0 : yy_current_state; -} - -#ifndef YY_NO_UNPUT - - static void yyunput (int c, char * yy_bp ) -{ - char *yy_cp; - - yy_cp = (yy_c_buf_p); - - /* undo effects of setting up yytext */ - *yy_cp = (yy_hold_char); - - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - int number_to_move = (yy_n_chars) + 2; - char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ - YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; - char *source = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; - - while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - *--dest = *--source; - - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = - (yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size; - - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } - - *--yy_cp = (char) c; - - if ( c == '\n' ){ - --yylineno; - } - - (yytext_ptr) = yy_bp; - (yy_hold_char) = *yy_cp; - (yy_c_buf_p) = yy_cp; -} - -#endif - -#ifndef YY_NO_INPUT -#ifdef __cplusplus - static int yyinput (void) -#else - static int input (void) -#endif - -{ - int c; - - *(yy_c_buf_p) = (yy_hold_char); - - if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) - /* This was really a NUL. */ - *(yy_c_buf_p) = '\0'; - - else - { /* need more input */ - int offset = (int) ((yy_c_buf_p) - (yytext_ptr)); - ++(yy_c_buf_p); - - switch ( yy_get_next_buffer( ) ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - yyrestart( yyin ); - - /*FALLTHROUGH*/ - - case EOB_ACT_END_OF_FILE: - { - if ( yywrap( ) ) - return 0; - - if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(); -#else - return input(); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - (yy_c_buf_p) = (yytext_ptr) + offset; - break; - } - } - } - - c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ - *(yy_c_buf_p) = '\0'; /* preserve yytext */ - (yy_hold_char) = *++(yy_c_buf_p); - - if ( c == '\n' ) - - yylineno++; -; - - return c; -} -#endif /* ifndef YY_NO_INPUT */ - -/** Immediately switch to a different input stream. - * @param input_file A readable stream. - * - * @note This function does not reset the start condition to @c INITIAL . - */ - void yyrestart (FILE * input_file ) -{ - - if ( ! YY_CURRENT_BUFFER ){ - yyensure_buffer_stack (); - YY_CURRENT_BUFFER_LVALUE = - yy_create_buffer( yyin, YY_BUF_SIZE ); - } - - yy_init_buffer( YY_CURRENT_BUFFER, input_file ); - yy_load_buffer_state( ); -} - -/** Switch to a different input buffer. - * @param new_buffer The new input buffer. - * - */ - void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) -{ - - /* TODO. We should be able to replace this entire function body - * with - * yypop_buffer_state(); - * yypush_buffer_state(new_buffer); - */ - yyensure_buffer_stack (); - if ( YY_CURRENT_BUFFER == new_buffer ) - return; - - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *(yy_c_buf_p) = (yy_hold_char); - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - YY_CURRENT_BUFFER_LVALUE = new_buffer; - yy_load_buffer_state( ); - - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - (yy_did_buffer_switch_on_eof) = 1; -} - -static void yy_load_buffer_state (void) -{ - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; - yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; - (yy_hold_char) = *(yy_c_buf_p); -} - -/** Allocate and initialize an input buffer state. - * @param file A readable stream. - * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * - * @return the allocated buffer state. - */ - YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) -{ - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - yy_init_buffer( b, file ); - - return b; -} - -/** Destroy the buffer. - * @param b a buffer created with yy_create_buffer() - * - */ - void yy_delete_buffer (YY_BUFFER_STATE b ) -{ - - if ( ! b ) - return; - - if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ - YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - yyfree( (void *) b->yy_ch_buf ); - - yyfree( (void *) b ); -} - -/* Initializes or reinitializes a buffer. - * This function is sometimes called more than once on the same buffer, - * such as during a yyrestart() or at EOF. - */ - static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) - -{ - int oerrno = errno; - - yy_flush_buffer( b ); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - - /* If b is the current buffer, then yy_init_buffer was _probably_ - * called from yyrestart() or through yy_get_next_buffer. - * In that case, we don't want to reset the lineno or column. - */ - if (b != YY_CURRENT_BUFFER){ - b->yy_bs_lineno = 1; - b->yy_bs_column = 0; - } - - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; - - errno = oerrno; -} - -/** Discard all buffered characters. On the next scan, YY_INPUT will be called. - * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. - * - */ - void yy_flush_buffer (YY_BUFFER_STATE b ) -{ - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == YY_CURRENT_BUFFER ) - yy_load_buffer_state( ); -} - -/** Pushes the new state onto the stack. The new state becomes - * the current state. This function will allocate the stack - * if necessary. - * @param new_buffer The new state. - * - */ -void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) -{ - if (new_buffer == NULL) - return; - - yyensure_buffer_stack(); - - /* This block is copied from yy_switch_to_buffer. */ - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *(yy_c_buf_p) = (yy_hold_char); - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - /* Only push if top exists. Otherwise, replace top. */ - if (YY_CURRENT_BUFFER) - (yy_buffer_stack_top)++; - YY_CURRENT_BUFFER_LVALUE = new_buffer; - - /* copied from yy_switch_to_buffer. */ - yy_load_buffer_state( ); - (yy_did_buffer_switch_on_eof) = 1; -} - -/** Removes and deletes the top of the stack, if present. - * The next element becomes the new top. - * - */ -void yypop_buffer_state (void) -{ - if (!YY_CURRENT_BUFFER) - return; - - yy_delete_buffer(YY_CURRENT_BUFFER ); - YY_CURRENT_BUFFER_LVALUE = NULL; - if ((yy_buffer_stack_top) > 0) - --(yy_buffer_stack_top); - - if (YY_CURRENT_BUFFER) { - yy_load_buffer_state( ); - (yy_did_buffer_switch_on_eof) = 1; - } -} - -/* Allocates the stack if it does not exist. - * Guarantees space for at least one push. - */ -static void yyensure_buffer_stack (void) -{ - yy_size_t num_to_alloc; - - if (!(yy_buffer_stack)) { - - /* First allocation is just for 2 elements, since we don't know if this - * scanner will even need a stack. We use 2 instead of 1 to avoid an - * immediate realloc on the next call. - */ - num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ - (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); - - memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - - (yy_buffer_stack_max) = num_to_alloc; - (yy_buffer_stack_top) = 0; - return; - } - - if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ - - /* Increase the buffer to prepare for a possible push. */ - yy_size_t grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = (yy_buffer_stack_max) + grow_size; - (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc - ((yy_buffer_stack), - num_to_alloc * sizeof(struct yy_buffer_state*) - ); - if ( ! (yy_buffer_stack) ) - YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); - - /* zero only the new slots.*/ - memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); - (yy_buffer_stack_max) = num_to_alloc; - } -} - -/** Setup the input buffer state to scan directly from a user-specified character buffer. - * @param base the character buffer - * @param size the size in bytes of the character buffer - * - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) -{ - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return NULL; - - b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - - b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = NULL; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - yy_switch_to_buffer( b ); - - return b; -} - -/** Setup the input buffer state to scan a string. The next call to yylex() will - * scan from a @e copy of @a str. - * @param yystr a NUL-terminated string to scan - * - * @return the newly allocated buffer state object. - * @note If you want to scan bytes that may contain NUL values, then use - * yy_scan_bytes() instead. - */ -YY_BUFFER_STATE yy_scan_string (const char * yystr ) -{ - - return yy_scan_bytes( yystr, (int) strlen(yystr) ); -} - -/** Setup the input buffer state to scan the given bytes. The next call to yylex() will - * scan from a @e copy of @a bytes. - * @param yybytes the byte buffer to scan - * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. - * - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len ) -{ - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = (yy_size_t) (_yybytes_len + 2); - buf = (char *) yyalloc( n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); - - for ( i = 0; i < _yybytes_len; ++i ) - buf[i] = yybytes[i]; - - buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; - - b = yy_scan_buffer( buf, n ); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; -} - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -static void yynoreturn yy_fatal_error (const char* msg ) -{ - fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); -} - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - yytext[yyleng] = (yy_hold_char); \ - (yy_c_buf_p) = yytext + yyless_macro_arg; \ - (yy_hold_char) = *(yy_c_buf_p); \ - *(yy_c_buf_p) = '\0'; \ - yyleng = yyless_macro_arg; \ - } \ - while ( 0 ) - -/* Accessor methods (get/set functions) to struct members. */ - -/** Get the current line number. - * - */ -int yyget_lineno (void) -{ - - return yylineno; -} - -/** Get the input stream. - * - */ -FILE *yyget_in (void) -{ - return yyin; -} - -/** Get the output stream. - * - */ -FILE *yyget_out (void) -{ - return yyout; -} - -/** Get the length of the current token. - * - */ -int yyget_leng (void) -{ - return yyleng; -} - -/** Get the current token. - * - */ - -char *yyget_text (void) -{ - return yytext; -} - -/** Set the current line number. - * @param _line_number line number - * - */ -void yyset_lineno (int _line_number ) -{ - - yylineno = _line_number; -} - -/** Set the input stream. This does not discard the current - * input buffer. - * @param _in_str A readable stream. - * - * @see yy_switch_to_buffer - */ -void yyset_in (FILE * _in_str ) -{ - yyin = _in_str ; -} - -void yyset_out (FILE * _out_str ) -{ - yyout = _out_str ; -} - -int yyget_debug (void) -{ - return yy_flex_debug; -} - -void yyset_debug (int _bdebug ) -{ - yy_flex_debug = _bdebug ; -} - -static int yy_init_globals (void) -{ - /* Initialization is the same as for the non-reentrant scanner. - * This function is called from yylex_destroy(), so don't allocate here. - */ - - /* We do not touch yylineno unless the option is enabled. */ - yylineno = 1; - - (yy_buffer_stack) = NULL; - (yy_buffer_stack_top) = 0; - (yy_buffer_stack_max) = 0; - (yy_c_buf_p) = NULL; - (yy_init) = 0; - (yy_start) = 0; - -/* Defined in main.c */ -#ifdef YY_STDINIT - yyin = stdin; - yyout = stdout; -#else - yyin = NULL; - yyout = NULL; -#endif - - /* For future reference: Set errno on error, since we are called by - * yylex_init() - */ - return 0; -} - -/* yylex_destroy is for both reentrant and non-reentrant scanners. */ -int yylex_destroy (void) -{ - - /* Pop the buffer stack, destroying each element. */ - while(YY_CURRENT_BUFFER){ - yy_delete_buffer( YY_CURRENT_BUFFER ); - YY_CURRENT_BUFFER_LVALUE = NULL; - yypop_buffer_state(); - } - - /* Destroy the stack itself. */ - yyfree((yy_buffer_stack) ); - (yy_buffer_stack) = NULL; - - /* Reset the globals. This is important in a non-reentrant scanner so the next time - * yylex() is called, initialization will occur. */ - yy_init_globals( ); - - return 0; -} - -/* - * Internal utility routines. - */ - -#ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, const char * s2, int n ) -{ - - int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; -} -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (const char * s ) -{ - int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; -} -#endif - -void *yyalloc (yy_size_t size ) -{ - return malloc(size); -} - -void *yyrealloc (void * ptr, yy_size_t size ) -{ - - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return realloc(ptr, size); -} - -void yyfree (void * ptr ) -{ - free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ -} - -#define YYTABLES_NAME "yytables" - -#line 164 "spl_lexer.l" - - - /* This code goes in the user code section of the spl_lexer.l file, - following the last %% above. */ - -// Requires: fname != NULL -// Requires: fname is the name of a readable file -// Initialize the lexer and start it reading -// from the given file name -void lexer_init(char *fname) -{ - errors_noted = false; - yyin = fopen(fname, "r"); - if (yyin == NULL) { - bail_with_error("Cannot open %s", fname); - } - input_filename = fname; -} - -// Close the file yyin -// and return 0 to indicate that there are no more files -int yywrap() { - if (yyin != NULL) { - int rc = fclose(yyin); - if (rc == EOF) { - bail_with_error("Cannot close %s!", input_filename); - } - } - input_filename = NULL; - return 1; /* no more input */ -} - -// Return the name of the current input file -const char *lexer_filename() { - return input_filename; -} - -// Return the line number of the next token -unsigned int lexer_line() { - return yylineno; -} - -/* Report an error to the user on stderr */ -void yyerror(const char *filename, const char *msg) -{ - fflush(stdout); - fprintf(stderr, "%s:%d: %s\n", input_filename, lexer_line(), msg); - errors_noted = true; -} - -// On standard output: -// Print a message about the file name of the lexer's input -// and then print a heading for the lexer's output. -void lexer_print_output_header() -{ - printf("Tokens from file %s\n", lexer_filename()); - printf("%-6s %-4s %s\n", "Number", "Line", "Text"); -} - -// Have any errors been noted by the lexer? -bool lexer_has_errors() -{ - return errors_noted; -} - -// Print information about the token t to stdout -// followed by a newline -void lexer_print_token(enum yytokentype t, unsigned int tline, - const char *txt) -{ - printf("%-6d %-4d \"%s\"\n", t, tline, txt); -} - - -/* Read all the tokens from the input file - * and print each token on standard output - * using the format in lexer_print_token */ -void lexer_output() -{ - lexer_print_output_header(); - AST dummy; - yytoken_kind_t t; - do { - t = yylex(&dummy); - if (t == YYEOF) { - break; - } - lexer_print_token(t, yylineno, yytext); - } while (t != YYEOF); -} - diff --git a/spl_lexer.h b/spl_lexer.h deleted file mode 100755 index c3c120d..0000000 --- a/spl_lexer.h +++ /dev/null @@ -1,492 +0,0 @@ -#ifndef yyHEADER_H -#define yyHEADER_H 1 -#define yyIN_HEADER 1 - -#line 5 "spl_lexer.h" - -#line 7 "spl_lexer.h" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 6 -#define YY_FLEX_SUBMINOR_VERSION 4 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -#ifdef yyget_lval -#define yyget_lval_ALREADY_DEFINED -#else -#define yyget_lval yyget_lval -#endif - -#ifdef yyset_lval -#define yyset_lval_ALREADY_DEFINED -#else -#define yyset_lval yyset_lval -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include -#include -#include -#include - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have . Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#ifndef SIZE_MAX -#define SIZE_MAX (~(size_t)0) -#endif - -#endif /* ! C99 */ - -#endif /* ! FLEXINT_H */ - -/* begin standard C++ headers. */ - -/* TODO: this is always defined, so inline it */ -#define yyconst const - -#if defined(__GNUC__) && __GNUC__ >= 3 -#define yynoreturn __attribute__((__noreturn__)) -#else -#define yynoreturn -#endif - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k. - * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. - * Ditto for the __ia64__ case accordingly. - */ -#define YY_BUF_SIZE 32768 -#else -#define YY_BUF_SIZE 16384 -#endif /* __ia64__ */ -#endif - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -extern int yyleng; - -extern FILE *yyin, *yyout; - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - int yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -void yyrestart ( FILE *input_file ); -void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); -YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); -void yy_delete_buffer ( YY_BUFFER_STATE b ); -void yy_flush_buffer ( YY_BUFFER_STATE b ); -void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); -void yypop_buffer_state ( void ); - -YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); -YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); -YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len ); - -void *yyalloc ( yy_size_t ); -void *yyrealloc ( void *, yy_size_t ); -void yyfree ( void * ); - -/* Begin user sect3 */ - -extern int yylineno; - -extern char *yytext; -#ifdef yytext_ptr -#undef yytext_ptr -#endif -#define yytext_ptr yytext - -#ifdef YY_HEADER_EXPORT_START_CONDITIONS -#define INITIAL 0 - -#endif - -#ifndef YY_NO_UNISTD_H -/* Special case for "unistd.h", since it is non-ANSI. We include it way - * down here because we want the user's section 1 to have been scanned first. - * The user has a chance to override it with an option. - */ -#include -#endif - -#ifndef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#endif - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int yylex_destroy ( void ); - -int yyget_debug ( void ); - -void yyset_debug ( int debug_flag ); - -YY_EXTRA_TYPE yyget_extra ( void ); - -void yyset_extra ( YY_EXTRA_TYPE user_defined ); - -FILE *yyget_in ( void ); - -void yyset_in ( FILE * _in_str ); - -FILE *yyget_out ( void ); - -void yyset_out ( FILE * _out_str ); - - int yyget_leng ( void ); - -char *yyget_text ( void ); - -int yyget_lineno ( void ); - -void yyset_lineno ( int _line_number ); - -YYSTYPE * yyget_lval ( void ); - -void yyset_lval ( YYSTYPE * yylval_param ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int yywrap ( void ); -#else -extern int yywrap ( void ); -#endif -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy ( char *, const char *, int ); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen ( const char * ); -#endif - -#ifndef YY_NO_INPUT - -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k */ -#define YY_READ_BUF_SIZE 16384 -#else -#define YY_READ_BUF_SIZE 8192 -#endif /* __ia64__ */ -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int yylex \ - (YYSTYPE * yylval_param ); - -#define YY_DECL int yylex \ - (YYSTYPE * yylval_param ) -#endif /* !YY_DECL */ - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - -#undef YY_NEW_FILE -#undef YY_FLUSH_BUFFER -#undef yy_set_bol -#undef yy_new_buffer -#undef yy_set_interactive -#undef YY_DO_BEFORE_ACTION - -#ifdef YY_DECL_IS_OURS -#undef YY_DECL_IS_OURS -#undef YY_DECL -#endif - -#ifndef yy_create_buffer_ALREADY_DEFINED -#undef yy_create_buffer -#endif -#ifndef yy_delete_buffer_ALREADY_DEFINED -#undef yy_delete_buffer -#endif -#ifndef yy_scan_buffer_ALREADY_DEFINED -#undef yy_scan_buffer -#endif -#ifndef yy_scan_string_ALREADY_DEFINED -#undef yy_scan_string -#endif -#ifndef yy_scan_bytes_ALREADY_DEFINED -#undef yy_scan_bytes -#endif -#ifndef yy_init_buffer_ALREADY_DEFINED -#undef yy_init_buffer -#endif -#ifndef yy_flush_buffer_ALREADY_DEFINED -#undef yy_flush_buffer -#endif -#ifndef yy_load_buffer_state_ALREADY_DEFINED -#undef yy_load_buffer_state -#endif -#ifndef yy_switch_to_buffer_ALREADY_DEFINED -#undef yy_switch_to_buffer -#endif -#ifndef yypush_buffer_state_ALREADY_DEFINED -#undef yypush_buffer_state -#endif -#ifndef yypop_buffer_state_ALREADY_DEFINED -#undef yypop_buffer_state -#endif -#ifndef yyensure_buffer_stack_ALREADY_DEFINED -#undef yyensure_buffer_stack -#endif -#ifndef yylex_ALREADY_DEFINED -#undef yylex -#endif -#ifndef yyrestart_ALREADY_DEFINED -#undef yyrestart -#endif -#ifndef yylex_init_ALREADY_DEFINED -#undef yylex_init -#endif -#ifndef yylex_init_extra_ALREADY_DEFINED -#undef yylex_init_extra -#endif -#ifndef yylex_destroy_ALREADY_DEFINED -#undef yylex_destroy -#endif -#ifndef yyget_debug_ALREADY_DEFINED -#undef yyget_debug -#endif -#ifndef yyset_debug_ALREADY_DEFINED -#undef yyset_debug -#endif -#ifndef yyget_extra_ALREADY_DEFINED -#undef yyget_extra -#endif -#ifndef yyset_extra_ALREADY_DEFINED -#undef yyset_extra -#endif -#ifndef yyget_in_ALREADY_DEFINED -#undef yyget_in -#endif -#ifndef yyset_in_ALREADY_DEFINED -#undef yyset_in -#endif -#ifndef yyget_out_ALREADY_DEFINED -#undef yyget_out -#endif -#ifndef yyset_out_ALREADY_DEFINED -#undef yyset_out -#endif -#ifndef yyget_leng_ALREADY_DEFINED -#undef yyget_leng -#endif -#ifndef yyget_text_ALREADY_DEFINED -#undef yyget_text -#endif -#ifndef yyget_lineno_ALREADY_DEFINED -#undef yyget_lineno -#endif -#ifndef yyset_lineno_ALREADY_DEFINED -#undef yyset_lineno -#endif -#ifndef yyget_column_ALREADY_DEFINED -#undef yyget_column -#endif -#ifndef yyset_column_ALREADY_DEFINED -#undef yyset_column -#endif -#ifndef yywrap_ALREADY_DEFINED -#undef yywrap -#endif -#ifndef yyget_lval_ALREADY_DEFINED -#undef yyget_lval -#endif -#ifndef yyset_lval_ALREADY_DEFINED -#undef yyset_lval -#endif -#ifndef yyget_lloc_ALREADY_DEFINED -#undef yyget_lloc -#endif -#ifndef yyset_lloc_ALREADY_DEFINED -#undef yyset_lloc -#endif -#ifndef yyalloc_ALREADY_DEFINED -#undef yyalloc -#endif -#ifndef yyrealloc_ALREADY_DEFINED -#undef yyrealloc -#endif -#ifndef yyfree_ALREADY_DEFINED -#undef yyfree -#endif -#ifndef yytext_ALREADY_DEFINED -#undef yytext -#endif -#ifndef yyleng_ALREADY_DEFINED -#undef yyleng -#endif -#ifndef yyin_ALREADY_DEFINED -#undef yyin -#endif -#ifndef yyout_ALREADY_DEFINED -#undef yyout -#endif -#ifndef yy_flex_debug_ALREADY_DEFINED -#undef yy_flex_debug -#endif -#ifndef yylineno_ALREADY_DEFINED -#undef yylineno -#endif -#ifndef yytables_fload_ALREADY_DEFINED -#undef yytables_fload -#endif -#ifndef yytables_destroy_ALREADY_DEFINED -#undef yytables_destroy -#endif -#ifndef yyTABLES_NAME_ALREADY_DEFINED -#undef yyTABLES_NAME -#endif - -#line 164 "spl_lexer.l" - - -#line 490 "spl_lexer.h" -#undef yyIN_HEADER -#endif /* yyHEADER_H */ diff --git a/spl_lexer.l b/spl_lexer.l deleted file mode 100755 index 55ca4a3..0000000 --- a/spl_lexer.l +++ /dev/null @@ -1,252 +0,0 @@ -/* $Id: spl_lexer.l,v 1.1 2024/10/23 12:17:38 leavens Exp $ */ -/* Lexical Analyzer for SPL */ - -%option header-file = "spl_lexer.h" -%option outfile = "spl_lexer.c" -%option yylineno -%option bison-bridge - -%{ -#include -#include -#include -#include -#include -#include "ast.h" -#include "parser_types.h" -#include "utilities.h" -#include "lexer.h" - - /* Tokens generated by Bison */ -#include "spl.tab.h" - - /* need declaration of fileno, part of the C standard library. - (Putting an extern declaration here shuts off a gcc warning.) */ -extern int fileno(FILE *stream); - -/* The filename of the file being read */ -static char *input_filename; - -/* Have any errors been noted? */ -static bool errors_noted; - -/* The value of a token */ -extern YYSTYPE yylval; - -/* The FILE used by the generated lexer */ -extern FILE *yyin; - -// We are not using yyunput or input -#define YY_NO_UNPUT -#define YY_NO_INPUT - -#undef yywrap /* sometimes a macro by default */ - -// apparently strdup is not declared in -extern char *strdup(const char *s); - -// set the lexer's value for a token in yylval as an AST -static void tok2ast(int code) { - AST t; - t.token.file_loc = file_location_make(input_filename, yylineno); - t.token.type_tag = token_ast; - t.token.code = code; - t.token.text = strdup(yytext); - yylval = t; -} - -static void ident2ast(const char *name) { - AST t; - assert(input_filename != NULL); - t.ident.file_loc = file_location_make(input_filename, yylineno); - t.ident.type_tag = ident_ast; - t.ident.name = strdup(name); - yylval = t; -} - -static void number2ast(unsigned int val) -{ - AST t; - t.number.file_loc = file_location_make(input_filename, yylineno); - t.number.type_tag = number_ast; - t.number.text = strdup(yytext); - t.number.value = val; - yylval = t; -} - -%} - - /* you can add actual definitions below, before the %% */ - -DIGIT [0-9] -NUMBER {DIGIT}+ -LETTER [a-zA-Z] -LETTERORDIGIT ({LETTER}|{DIGIT}) -IDENT {LETTER}({LETTERORDIGIT}*) -NEWLINE \n -CR \r -EOL ({NEWLINE}|({CR}{NEWLINE})) -COMMENTSTART % -COMMENT {COMMENTSTART}.* -IGNORED [ \t\v\f\r] - -%% - - /* fill in the rules for your lexer here! */ - -{IGNORED} { ; } /* do nothing */ -{COMMENT} { ; } /* ignore comments */ -{EOL} { ; } /* ignore EOL */ - -{NUMBER} { unsigned long lval; - int ssf_ret; - ssf_ret = sscanf(yytext, "%lu", &lval); - if (ssf_ret != 1) { - bail_with_error("Number (%s) couldn't be read by lexer!", - yytext); - } - if (INT_MAX < lval ) { - char msgbuf[512]; - if (strlen(yytext) >= 300) { - snprintf(msgbuf, 327, "Number (%s...) is too large!", - yytext); - } else { - sprintf(msgbuf, "Number (%s) is too large!", yytext); - } - yyerror(lexer_filename(), msgbuf); - } - number2ast((int) lval); - return numbersym; - } - -\+ { tok2ast(plussym); return plussym; } -- { tok2ast(minussym); return minussym; } -\* { tok2ast(multsym); return multsym; } -\/ { tok2ast(divsym); return divsym; } - -\. { return periodsym; } -\; { return semisym; } -, { return commasym; } -:= { return becomessym; } -== { tok2ast(eqsym); return eqeqsym; } -= { tok2ast(eqsym); return eqsym; } -!= { tok2ast(neqsym); return neqsym; } -\<= { tok2ast(leqsym); return leqsym; } -\>= { tok2ast(geqsym); return geqsym; } -\> { tok2ast(gtsym); return gtsym; } -\< { tok2ast(ltsym); return ltsym; } -\( { tok2ast(lparensym); return lparensym; } -\) { tok2ast(rparensym); return rparensym; } - -const { tok2ast(constsym); return constsym; } -var { tok2ast(varsym); return varsym; } -proc { tok2ast(procsym); return procsym; } -call { tok2ast(callsym); return callsym; } -begin { tok2ast(beginsym); return beginsym; } -end { tok2ast(endsym); return endsym; } -if { tok2ast(ifsym); return ifsym; } -then { tok2ast(thensym); return thensym; } -else { tok2ast(elsesym); return elsesym; } -while { tok2ast(whilesym); return whilesym; } -do { tok2ast(dosym); return dosym; } -read { tok2ast(readsym); return readsym; } -print { tok2ast(printsym); return printsym; } -divisible { tok2ast(divisiblesym); return divisiblesym; } -by { tok2ast(bysym); return bysym; } - -{IDENT} { ident2ast(yytext); return identsym; } - -. { char msgbuf[512]; - sprintf(msgbuf, "invalid character: '%c' ('\\0%o')", *yytext, *yytext); - yyerror(lexer_filename(), msgbuf); - } -%% - - /* This code goes in the user code section of the spl_lexer.l file, - following the last %% above. */ - -// Requires: fname != NULL -// Requires: fname is the name of a readable file -// Initialize the lexer and start it reading -// from the given file name -void lexer_init(char *fname) -{ - errors_noted = false; - yyin = fopen(fname, "r"); - if (yyin == NULL) { - bail_with_error("Cannot open %s", fname); - } - input_filename = fname; -} - -// Close the file yyin -// and return 0 to indicate that there are no more files -int yywrap() { - if (yyin != NULL) { - int rc = fclose(yyin); - if (rc == EOF) { - bail_with_error("Cannot close %s!", input_filename); - } - } - input_filename = NULL; - return 1; /* no more input */ -} - -// Return the name of the current input file -const char *lexer_filename() { - return input_filename; -} - -// Return the line number of the next token -unsigned int lexer_line() { - return yylineno; -} - -/* Report an error to the user on stderr */ -void yyerror(const char *filename, const char *msg) -{ - fflush(stdout); - fprintf(stderr, "%s:%d: %s\n", input_filename, lexer_line(), msg); - errors_noted = true; -} - -// On standard output: -// Print a message about the file name of the lexer's input -// and then print a heading for the lexer's output. -void lexer_print_output_header() -{ - printf("Tokens from file %s\n", lexer_filename()); - printf("%-6s %-4s %s\n", "Number", "Line", "Text"); -} - -// Have any errors been noted by the lexer? -bool lexer_has_errors() -{ - return errors_noted; -} - -// Print information about the token t to stdout -// followed by a newline -void lexer_print_token(enum yytokentype t, unsigned int tline, - const char *txt) -{ - printf("%-6d %-4d \"%s\"\n", t, tline, txt); -} - - -/* Read all the tokens from the input file - * and print each token on standard output - * using the format in lexer_print_token */ -void lexer_output() -{ - lexer_print_output_header(); - AST dummy; - yytoken_kind_t t; - do { - t = yylex(&dummy); - if (t == YYEOF) { - break; - } - lexer_print_token(t, yylineno, yytext); - } while (t != YYEOF); -} diff --git a/symtab.c b/symtab.c deleted file mode 100755 index 4e2cd57..0000000 --- a/symtab.c +++ /dev/null @@ -1,169 +0,0 @@ -/* $Id: symtab.c,v 1.9 2024/11/10 22:48:40 leavens Exp $ */ -#include -#include "symtab.h" -#include "scope.h" -#include "utilities.h" - -// The symbol table is a stack of scope (see the scope module). - -// index of the top of the stack of scopes -static int symtab_top_idx = -1; - -// the symbol table itself -static scope_t *symtab[MAX_NESTING]; - -// initialize the symbol table -void symtab_initialize() -{ - // initialize the internal state - symtab_top_idx = -1; - for (int i = 0; i < MAX_NESTING; i++) { - symtab[i] = NULL; - } -} - -// Return the number of scopes currently in the symbol table. -unsigned int symtab_size() -{ - return symtab_top_idx + 1; -} - -// Does this symbol table have any scopes in it? -bool symtab_empty() -{ - return symtab_size() == 0; -} - -// Return the current scope's next location count -// (of constants and variables). -unsigned int symtab_scope_loc_count() -{ - return scope_loc_count(symtab[symtab_top_idx]); -} - -// Return the current scope's size (the number of declared ids). -unsigned int symtab_scope_size() -{ - return scope_size(symtab[symtab_top_idx]); -} - -// Is the current scope full? -bool symtab_scope_full() -{ - return scope_full(symtab[symtab_top_idx]); -} - -// Return the current nesting level of the symbol table -// (this is the number of (client made) symtab_enter_scope() calls -// minus the number of symtab_leave_scope() calls -unsigned int symtab_current_nesting_level() -{ - // assert(symtab_top_idx >= 0); - return symtab_top_idx; -} - -// Is the symbol table itself full -// (i.e., is symtab_current_nesting_level() equal to MAX_NESTING-1)? -bool symtab_full() -{ - return symtab_current_nesting_level() == MAX_NESTING - 1; -} - -// Is the given name associated with some attributes? -// (this looks back through all scopes). -bool symtab_defined(const char *name) -{ - return symtab_lookup(name) != NULL; -} - -// Is the given name associated with some attributes in the current scope? -// (this only looks in the current scope). -bool symtab_defined_in_current_scope(const char *name) -{ - id_attrs *attrs = scope_lookup(symtab[symtab_top_idx], name); - return attrs != NULL; -} - - -// Put the given name, which is to be declared with kind k, -// and has its declaration at the given file location (floc), -// into the current scope's symbol table at the offset scope_next_offset(). -static void add_ident(scope_t *s, const char*name, id_attrs *attrs) -{ - id_attrs *old_attrs = scope_lookup(s, name); - if (old_attrs != NULL) { - bail_with_prog_error(attrs->file_loc, - "%s \"%s\" is already declared as a %s", - id_attrs_id_kind_string(attrs->kind), name, - id_attrs_id_kind_string(old_attrs->kind)); - } else { - scope_insert(s, name, attrs); - } -} - -// Requires: !symtab_defined(name) && attrs != NULL -// Modify the current scope (as recorded in the symbol table) to -// add an association from the given name to attributes appropriate -// for k and floc. -void symtab_insert(const char *name, id_attrs *attrs) -{ - add_ident(symtab[symtab_top_idx], name, attrs); -} - -// Requires: !symtab_full() -// Start a new scope (for a procedure) -void symtab_enter_scope() -{ - symtab_top_idx++; - symtab[symtab_top_idx] = scope_create(); -} - -// Requires: !symtab_empty() -void symtab_leave_scope() -{ - if (symtab_top_idx < 0) { - bail_with_error("Cannot leave scope, no scope on symtab's stack!"); - } - symtab_top_idx--; -} - -// Return (a pointer to) the attributes of the given name -// or NULL if there is no association for name in the symbol table. -// (this looks back through all scopes). -id_use *symtab_lookup(const char *name) -{ - unsigned int levelsOut = 0; - for (int level = symtab_top_idx; 0 <= level; level--) { - id_attrs *attrs = scope_lookup(symtab[level], name); - if (attrs != NULL) { - // debug_print("symtab_lookup returning with levelsOut == %d for %s\n", - // levelsOut, name); - return id_use_create(attrs, levelsOut); - } - levelsOut++; - } - return NULL; -} - -// We'll use lexical addresses in HW4... -// Requires: symtab_defined(name) -// Return (a pointer to) the lexical address of the given name -// or NULL if there is no association for name. -/* -lexical_address *symtab_lexical_address(const char *name) -{ - // maintaining: -1 <= level <= symtab_top_idx; - // maintaining: (for all int j: - // level < j <= symtab_top_idx - // ==> !scope_defined(symtab[j], name)) - for (int level = symtab_top_idx; 0 <= level; level--) { - id_attrs *attrs = scope_lookup(symtab[level], name); - if (attrs != NULL) { - return lexical_address_create(symtab_top_idx - level, - attrs->loc_offset); - } - } - bail_with_error("Couldn't find %s for symtab_lexical_address!", name); - return NULL; -} -*/ diff --git a/symtab.h b/symtab.h deleted file mode 100755 index e9a992c..0000000 --- a/symtab.h +++ /dev/null @@ -1,66 +0,0 @@ -/* $Id: symtab.h,v 1.5 2023/11/13 12:52:01 leavens Exp $ */ -#ifndef _SYMTAB_H -#define _SYMTAB_H - -#include "scope.h" -#include "id_use.h" - -// Maximum number of declarations that can be stored in a scope -#define MAX_NESTING 100 - -// initialize the symbol table -extern void symtab_initialize(); - -// Return the number of scopes currently in the symbol table. -extern unsigned int symtab_size(); - -// Does this symbol table have any scopes in it? -extern bool symtab_empty(); - -// Return the current scope's next location count -// (of constants and variables). -extern unsigned int symtab_scope_loc_count(); - -// Return the current scope's size (the number of declared ids). -extern unsigned int symtab_scope_size(); - -// Is the current scope full? -extern bool symtab_scope_full(); - -// Return the current nesting level of the symbol table -// (this is the number of symtab_enter_scope() calls -// minus the number of symtab_leave_scope() calls -extern unsigned int symtab_current_nesting_level(); - -// Is the symbol table itself full -// (i.e., is symtab_current_nesting_level() equal to MAX_NESTING-1)? -extern bool symtab_full(); - -// Is the given name associated with some attributes? -// (this looks back through all scopes). -extern bool symtab_defined(const char *name); - -// Is the given name associated with some attributes in the current scope? -// (this only looks in the current scope). -extern bool symtab_defined_in_current_scope(const char *name); - -// Requires: !symtab_defined_in_current_scope(name) && attrs != NULL -// Modify the current scope (as recorded in the symbol table) to -// add an association from the given name to the given attributes attrs. -extern void symtab_insert(const char *name, id_attrs *attrs); - -// Requires: !symtab_full() -// Start a new scope (for a procedure) -extern void symtab_enter_scope(); - -// Requires: !symtab_empty() -extern void symtab_leave_scope(); - -// Return (a pointer to) a struct containing: -// the attributes of the given name (attrs) -// and the number of lexical levels outward -// from the current scope at which the name was declared, -// or NULL if there is no association for name. -extern id_use *symtab_lookup(const char *name); - -#endif diff --git a/unparser.c b/unparser.c deleted file mode 100755 index 2db36db..0000000 --- a/unparser.c +++ /dev/null @@ -1,427 +0,0 @@ -/* $Id: unparser.c,v 1.11 2024/10/23 13:38:20 leavens Exp $ */ -#include -#include -#include "unparser.h" -#include "utilities.h" - -// Amount of spaces to indent per nesting level -#define SPACES_PER_LEVEL 2 - -// Print SPACES_PER_LEVEL * level spaces to out -static void indent(FILE *out, int level) -{ - int num = SPACES_PER_LEVEL * level; - for (int i = 0; i < num; i++) { - fprintf(out, " "); - } -} - -// Print (to out) a semicolon, but only if addSemiToEnd is true, -// and then print a newline. -static void newlineAndOptionalSemi(FILE *out, bool addSemiToEnd) -{ - fprintf(out, "%s\n", (addSemiToEnd ? ";" : "")); -} - -// Unparse the given program AST and then print a period and an newline -void unparseProgram(FILE *out, block_t prog) -{ - unparseBlock(out, prog, 0, false); - fprintf(out, ".\n"); -} - -// Unparse the given block, indented by the given level, to out -// adding a semicolon to the end if addSemiToEnd is true. -extern void unparseBlock(FILE *out, block_t blk, int level, - bool addSemiToEnd) -{ - indent(out, level); - fprintf(out, "begin\n"); - unparseConstDecls(out, blk.const_decls, level+1); - unparseVarDecls(out, blk.var_decls, level+1); - unparseProcDecls(out, blk.proc_decls, level+1); - unparseStmts(out, blk.stmts, level+1); - indent(out, level); - fprintf(out, "end"); - newlineAndOptionalSemi(out, addSemiToEnd); -} - -// Unparse the list of const-decls given by the AST cds to out -// with the given nesting level -// (note that if cds == NULL, then nothing is printed) -void unparseConstDecls(FILE *out, const_decls_t cds, int level) -{ - // debug_print("unparseConstDecls entry ...\n"); - assert(cds.type_tag == const_decls_ast); - const_decl_t *cd_listp = cds.start; - while (cd_listp != NULL) { - unparseConstDecl(out, *cd_listp, level); - cd_listp = cd_listp->next; - } -} - -// Unparse a single const-def given by the AST cd to out, -// indented for the given nesting level -void unparseConstDecl(FILE *out, const_decl_t cd, int level) -{ - // debug_print("unparseConstDecl entry ...\n"); - indent(out, level); - fprintf(out, "const "); - unparseConstDefList(out, cd.const_def_list, level); -} - -// Unparse the list of const-defs given by the AST cdl to out -// with the given nesting level, followed by a semicolon and a newline. -void unparseConstDefList(FILE *out, const_def_list_t cdl, int level) -{ - // debug_print("unparseConstDefList entry ...\n"); - assert(cdl.type_tag == const_def_list_ast); - bool printed_already = false; - const_def_t *cdp = cdl.start; - while (cdp != NULL) { - if (printed_already) { - fprintf(out, ", "); - } - unparseConstDef(out, *cdp, level); - printed_already = true; - cdp = cdp->next; - } - fprintf(out, ";\n"); -} - -// Unparse the const-def given by the AST cdf to out -// with the given nesting level -extern void unparseConstDef(FILE *out, const_def_t cdf, int level) -{ - fprintf(out, "%s = %d", cdf.ident.name, cdf.number.value); -} - -// Unparse the list of vart-decls given by the AST vds to out -// with the given nesting level -// (note that if vds.var_decls == NULL, then nothing is printed) -void unparseVarDecls(FILE *out, var_decls_t vds, int level) -{ - // debug_print("Entering unparseVarDecls ...\n"); - assert(vds.type_tag == var_decls_ast); - var_decl_t *vdp = vds.var_decls; - while (vdp != NULL) { - unparseVarDecl(out, *vdp, level); - vdp = vdp->next; - } -} - -// Unparse a single var-decl given by the AST vd to out, -// indented for the given nesting level -void unparseVarDecl(FILE *out, var_decl_t vd, int level) -{ - // debug_print("Entering unparseVarDecl ...\n"); - indent(out, level); - fprintf(out, "var"); - unparseIdentList(out, vd.ident_list); - fprintf(out, ";\n"); -} - -// Unparse the identifiers in idents to out, with a space before each, -// and a comma as a separator -void unparseIdentList(FILE *out, ident_list_t ident_list) -{ - // debug_print("Entering unparseIdentList ...\n"); - ident_t *ip = ident_list.start; - bool already_printed =false; - while (ip != NULL) { - // debug_print("in unparseIdents ip is %x\n", ip); - // debug_print("in unparseIdents ip->name is %s\n", ip->name); - if (already_printed) { - fprintf(out, ", %s", ip->name); - } else { - fprintf(out, " %s", ip->name); - } - already_printed = true; - ip = ip->next; - } -} - -// Unparse the list of proc-decls given by the AST pds to out -// with the given nesting level -// (note that if pds.proc_decls is NULL, then nothing is printed) -void unparseProcDecls(FILE *out, proc_decls_t pds, int level) -{ - // debug_print("unparseProcDecls entry ...\n"); - assert(pds.type_tag == proc_decls_ast); - proc_decl_t *pdp = pds.proc_decls; - while (pdp != NULL) { - unparseProcDecl(out, *pdp, level); - pdp = pdp ->next; - } -} - -// Unparse the given proc-decl given by the AST pd to out -// with the given nesting level followed by a semicolon -void unparseProcDecl(FILE *out, proc_decl_t pd, int level) -{ - // debug_print("unparseProcDecl entry ...\n"); - indent(out, level); - fprintf(out, "proc %s\n", pd.name); - unparseBlock(out, *(pd.block), level, true); -} - - -// Unparse the stmts given by stmt to out -// with indentation level given by level. -// (The statements always occur before an end, so a semicolon is never added.) -void unparseStmts(FILE *out, stmts_t stmts, int level) -{ - // indent(out, level); - // fprintf(out, "%% stmts at level %d\n", level); - if (stmts.stmts_kind != empty_stmts_e) { - stmt_list_t sl = stmts.stmt_list; - unparseStmtList(out, sl, level, false); - } -} - -// Unparse the stmts given by stmt to out -// with indentation level given by level, -// and add a semicolon at the end if addSemiToEnd is true. -void unparseStmtList(FILE *out, stmt_list_t stmt_list, int level, - bool addSemiToEnd) -{ - // indent(out, level); - // fprintf(out, "%% stmtList at level %d\n", level); - stmt_t *s = stmt_list.start; - while (s != NULL) { - unparseStmt(out, *s, level, addSemiToEnd || (s->next != NULL)); - s = s->next; - } -} - -// Unparse the statement given by the AST stmt to out, -// indented for the given level, -// adding a semicolon to the end if addSemiToENd is true. -void unparseStmt(FILE *out, stmt_t stmt, int level, bool addSemiToEnd) -{ - // debug_print("In unparseStmt stmt.type_tag is %d\n", stmt.type_tag); - assert(stmt.type_tag == stmt_ast); - switch (stmt.stmt_kind) { - case assign_stmt: - assert(stmt.data.assign_stmt.type_tag == assign_stmt_ast); - unparseAssignStmt(out, stmt.data.assign_stmt, level, addSemiToEnd); - break; - case call_stmt: - unparseCallStmt(out, stmt.data.call_stmt, level, addSemiToEnd); - break; - case if_stmt: - unparseIfStmt(out, stmt.data.if_stmt, level, addSemiToEnd); - break; - case while_stmt: - unparseWhileStmt(out, stmt.data.while_stmt, level, addSemiToEnd); - break; - case read_stmt: - unparseReadStmt(out, stmt.data.read_stmt, level, addSemiToEnd); - break; - case print_stmt: - unparsePrintStmt(out, stmt.data.print_stmt, level, addSemiToEnd); - break; - case block_stmt: - unparseBlockStmt(out, stmt.data.block_stmt, level, addSemiToEnd); - break; - default: - bail_with_error("Unknown stmt_kind (%d) in unparseStmt!", - stmt.stmt_kind); - break; - } -} - -// Unparse the assignment statment given by stmt to out -// with indentation level given by level, -// and add a semicolon at the end if addSemiToEnd is true. -void unparseAssignStmt(FILE *out, assign_stmt_t stmt, int level, - bool addSemiToEnd) -{ - indent(out, level); - fprintf(out, "%s := ", stmt.name); - if (stmt.expr == NULL) { - bail_with_error("Found null expression in assignment statment!"); - } - unparseExpr(out, *(stmt.expr)); - newlineAndOptionalSemi(out, addSemiToEnd); -} - -// Unparse the call statment given by stmt to out -// with indentation level given by level, -// and add a semicolon at the end if addSemiToEnd is true. -void unparseCallStmt(FILE *out, call_stmt_t stmt, int level, - bool addSemiToEnd) -{ - indent(out, level); - fprintf(out, "call %s", stmt.name); - newlineAndOptionalSemi(out, addSemiToEnd); -} - -// Unparse the sequential statment given by stmt to out -// with indentation level given by level (indenting the body one more level) -// and add a semicolon at the end if addSemiToEnd is true. -void unparseBlockStmt(FILE *out, block_stmt_t stmt, int level, - bool addSemiToEnd) -{ - unparseBlock(out, *(stmt.block), level, addSemiToEnd); -} - -// Unparse the if-statment given by stmt to out -// with indentation level given by level (and each body indented one more), -// and add a semicolon at the end if addSemiToEnd is true. -void unparseIfStmt(FILE *out, if_stmt_t stmt, int level, bool addSemiToEnd) -{ - indent(out, level); - fprintf(out, "if "); - unparseCondition(out, stmt.condition); - fprintf(out, "\n"); - indent(out, level); - fprintf(out, "then\n"); - unparseStmts(out, *(stmt.then_stmts), level+1); - if (stmt.else_stmts != NULL) { - indent(out, level); - fprintf(out, "else\n"); - unparseStmts(out, *(stmt.else_stmts), level+1); - } - indent(out, level); - fprintf(out, "end"); - newlineAndOptionalSemi(out, addSemiToEnd); -} - -// Unparse the while-statment given by stmt to out -// with indentation level given by level (and the body indented one more), -// and add a semicolon at the end if addSemiToEnd is true. -void unparseWhileStmt(FILE *out, while_stmt_t stmt, int level, - bool addSemiToEnd) -{ - indent(out, level); - fprintf(out, "while "); - unparseCondition(out, stmt.condition); - fprintf(out, "\n"); - indent(out, level); - fprintf(out, "do\n"); - unparseStmts(out, *(stmt.body), level+1); - indent(out, level); - fprintf(out, "end"); - newlineAndOptionalSemi(out, addSemiToEnd); -} - -// Unparse the read statment given by stmt to out -// and add a semicolon at the end if addSemiToEnd is true. -void unparseReadStmt(FILE *out, read_stmt_t stmt, int level, bool addSemiToEnd) -{ - indent(out, level); - fprintf(out, "read %s", stmt.name); - newlineAndOptionalSemi(out, addSemiToEnd); -} - -// Unparse the write statment given by stmt to out -// and add a semicolon at the end if addSemiToEnd is true. -void unparsePrintStmt(FILE *out, print_stmt_t stmt, int level, - bool addSemiToEnd) -{ - indent(out, level); - fprintf(out, "print "); - unparseExpr(out, stmt.expr); - newlineAndOptionalSemi(out, addSemiToEnd); -} - -// Unparse the condition given by cond to out -void unparseCondition(FILE *out, condition_t cond) -{ - switch (cond.cond_kind) { - case ck_db: - unparseDbCond(out, cond.data.db_cond); - break; - case ck_rel: - unparseRelOpCond(out, cond.data.rel_op_cond); - break; - default: - bail_with_error("Unexpected condition_kind_e (%d) in unparseCondition!", - cond.cond_kind); - break; - } -} - -// Unparse the odd condition given by cond to out -void unparseDbCond(FILE *out, db_condition_t dbcond) -{ - fprintf(out, "divisible "); - unparseExpr(out, dbcond.dividend); - fprintf(out, " by "); - unparseExpr(out, dbcond.divisor); -} - -// Unparse the binary relation condition given by cond to out -void unparseRelOpCond(FILE *out, rel_op_condition_t cond) -{ - unparseExpr(out, cond.expr1); - fprintf(out, " "); - unparseToken(out, cond.rel_op); - fprintf(out, " "); - unparseExpr(out, cond.expr2); -} - -// Unparse the given token, t, to out -void unparseToken(FILE *out, token_t t) -{ - fprintf(out, "%s", t.text); -} - -// Unparse the expression given by the AST exp to out -// adding parentheses to indicate the nesting relationships -void unparseExpr(FILE *out, expr_t exp) -{ - switch (exp.expr_kind) { - case expr_bin: - unparseBinOpExpr(out, exp.data.binary); - break; - case expr_negated: - unparseNegatedExpr(out, exp.data.negated); - break; - case expr_ident: - unparseIdent(out, exp.data.ident); - break; - case expr_number: - unparseNumber(out, exp.data.number); - break; - default: - bail_with_error("Unexpected expr_kind_e (%d) in unparseExpr!", - exp.expr_kind); - break; - } -} - -// Unparse the expression given by the AST exp to out -// adding parentheses (whether needed or not) -void unparseBinOpExpr(FILE *out, binary_op_expr_t exp) -{ - fprintf(out, "("); - unparseExpr(out, *(exp.expr1)); - fprintf(out, " "); - unparseToken(out, exp.arith_op); - fprintf(out, " "); - unparseExpr(out, *(exp.expr2)); - fprintf(out, ")"); -} - -// Unparse the expression given by the AST exp to out -// adding parentheses (whether needed or not) -void unparseNegatedExpr(FILE *out, negated_expr_t exp) -{ - fprintf(out, "-("); - unparseExpr(out, *(exp.expr)); - fprintf(out, ")"); -} - -// Unparse the given identifier reference (i.e., identifier use), id, to out -void unparseIdent(FILE *out, ident_t id) -{ - fprintf(out, "%s", id.name); -} - -// Unparse the given number AST, num, to out in decimal format -void unparseNumber(FILE *out, number_t num) -{ - fprintf(out, "%d", num.value); -} diff --git a/unparser.h b/unparser.h deleted file mode 100755 index 04ec623..0000000 --- a/unparser.h +++ /dev/null @@ -1,138 +0,0 @@ -/* $Id: unparser.h,v 1.6 2024/10/23 14:55:24 leavens Exp $ */ -#ifndef _UNPARSER_H -#define _UNPARSER_H -#include -#include "ast.h" - -// Unparse the given program AST and then print a period and an newline -extern void unparseProgram(FILE *out, block_t prog); - -// Unparse the given block, indented by the given level, to out -// adding a semicolon to the end if addSemiToEnd is true. -extern void unparseBlock(FILE *out, block_t blk, int indentLevel, - bool addSemiToEnd); - -// Unparse the list of const-decls given by the AST cds to out -// with the given nesting level -// (note that if cds is empty, then nothing is printed) -extern void unparseConstDecls(FILE *out, const_decls_t cds, int level); - -// Unparse the const-decl given by the AST cd to out -// with the given nesting level -extern void unparseConstDecl(FILE *out, const_decl_t cd, int level); - -// Unparse the list of const-defs given by the AST cdl to out -// with the given nesting level -extern void unparseConstDefList(FILE *out, const_def_list_t cdl, int level); - -// Unparse the const-def given by the AST cdf to out -// with the given nesting level -extern void unparseConstDef(FILE *out, const_def_t cdf, int level); - -// Unparse the list of var-decls given by the AST vds to out -// with the given nesting level -// (note that if vds.var_decls == NULL, then nothing is printed) -extern void unparseVarDecls(FILE *out, var_decls_t vds, int level); - -// Unparse the var-decl given by the AST vd to out -// with the given nesting level -extern void unparseVarDecl(FILE *out, var_decl_t vd, int level); - -// Unparse the identifiers in idents to out, with a space before each, -// and a comma as a separator -extern void unparseIdentList(FILE *out, ident_list_t ident_list); - -// Unparse the list of proc-decls given by the AST pds to out -// with the given nesting level -// (note that if pds.proc_decls is NULL, then nothing is printed) -extern void unparseProcDecls(FILE *out, proc_decls_t pds, int level); - -// Unparse the given proc-decl given by the AST pd to out -// with the given nesting level -extern void unparseProcDecl(FILE *out, proc_decl_t pd, int level); - -// Unparse the statement given by the AST stmt to out, -// indented for the given level, -// adding a semicolon to the end if addSemiToEnd is true. -extern void unparseStmt(FILE *out, stmt_t stmt, int indentLevel, - bool addSemiToEnd); - -// Unparse the statement given by the AST stmt to out, -// indented for the given level, -// adding a semicolon to the end if addSemiToEnd is true. -extern void unparseAssignStmt(FILE *out, assign_stmt_t stmt, int level, bool addSemiToEnd); - -// Unparse the statement given by the AST stmt to out, -// indented for the given level, -// adding a semicolon to the end if addSemiToEnd is true. -extern void unparseCallStmt(FILE *out, call_stmt_t stmt, int level, bool addSemiToEnd); - -// Unparse the statement given by the AST stmt to out, -// indented for the given level, -// adding a semicolon to the end if addSemiToEnd is true. -extern void unparseBlockStmt(FILE *out, block_stmt_t stmt, int level, bool addSemiToEnd); - -// Unparse the statements given by the AST stmts to out, -// indented for the given level. -// (The statements always occur before an end, so a semicolon is never added.) -extern void unparseStmts(FILE *out, stmts_t stmts, int level); - -// Unparse the stmts given by stmt to out -// with indentation level given by level, -// and add a semicolon at the end if addSemiToEnd is true. -void unparseStmtList(FILE *out, stmt_list_t stmt_list, int level, - bool addSemiToEnd); - -// Unparse the statement given by the AST stmt to out, -// indented for the given level, -// adding a semicolon to the end if addSemiToEnd is true. -extern void unparseIfStmt(FILE *out, if_stmt_t stmt, int level, - bool addSemiToEnd); - -// Unparse the statement given by the AST stmt to out, -// indented for the given level, -// adding a semicolon to the end if addSemiToEnd is true. -extern void unparseWhileStmt(FILE *out, while_stmt_t stmt, int level, - bool addSemiToEnd); - -// Unparse the statement given by the AST stmt to out, -// indented for the given level, -// adding a semicolon to the end if addSemiToEnd is true. -extern void unparseReadStmt(FILE *out, read_stmt_t stmt, int level, - bool addSemiToEnd); - -// Unparse the statement given by the AST stmt to out, -// indented for the given level, -// adding a semicolon to the end if addSemiToEnd is true. -extern void unparsePrintStmt(FILE *out, print_stmt_t stmt, int level, bool addSemiToEnd); - -// Unparse the condition given by cond to out -extern void unparseCondition(FILE *out, condition_t cond); - -extern void unparseDbCond(FILE *out, db_condition_t cond); - -extern void unparseRelOpCond(FILE *out, rel_op_condition_t cond); - -// Unparse the given token, t, to out -extern void unparseToken(FILE *out, token_t t); - -// Unparse the expression given by the AST exp to out -// adding parentheses to indicate the nesting relationships -extern void unparseExpr(FILE *out, expr_t exp); - -extern void unparseBinOpExpr(FILE *out, binary_op_expr_t exp); - -// Unparse the given bin_arith_opo to out -extern void unparseArithOp(FILE *out, token_t arith_op); - -// Unparse the expression given by the AST exp to out -// adding parentheses (whether needed or not) -extern void unparseNegatedExpr(FILE *out, negated_expr_t exp); - -// Unparse the given identifer reference (use) to out -extern void unparseIdent(FILE *out, ident_t id); - -// Unparse the given number to out in decimal format -extern void unparseNumber(FILE *out, number_t num); - -#endif diff --git a/utilities.c b/utilities.c deleted file mode 100755 index dc62a04..0000000 --- a/utilities.c +++ /dev/null @@ -1,113 +0,0 @@ -/* $Id: utilities.c,v 1.4 2024/10/23 12:17:39 leavens Exp $ */ -#include -#include -#include -#include -#include -#include -#include "utilities.h" - -// to turn off debugging support (assertions and debug_print) -// define the symbol NDEBUG (by writing uncommenting the following) -// #define NDEBUG - -#ifdef NDEBUG -#define debug_print() ((void)0) -#else -// otherwise debugging is on, and debug_print is defined as follows... -// (note that assert is a macro defined in -static void vdebug_print(const char *fmt, va_list args); - -// If debugging is false, do nothing, otherwise (when debugging) -// flush stderr and stdout, then print the message given on stderr, -// using printf formatting from the format string fmt. -// This function returns normally. -void debug_print(const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - vdebug_print(fmt, args); - va_end(args); -} - -// The variadic version of debug_print -static void vdebug_print(const char *fmt, va_list args) -{ - // flush output streams to synchronize outputs - fflush(stdout); - fflush(stderr); - vfprintf(stderr, fmt, args); - fflush(stderr); -} -#endif - -static void vbail_with_error(const char* fmt, va_list args); - -// Format a string error message and print it followed by a newline on stderr -// using perror (for an OS error, if the errno is not 0) -// then exit with a failure code, so a call to this does not return. -void bail_with_error(const char *fmt, ...) -{ - fflush(stdout); // flush so output comes after what has happened already - va_list(args); - va_start(args, fmt); - vbail_with_error(fmt, args); -} - -// The variadic version of bail_with_error -static void vbail_with_error(const char* fmt, va_list args) -{ - extern int errno; - char buff[2048]; - vsprintf(buff, fmt, args); - if (errno != 0) { - perror(buff); - } else { - fprintf(stderr, "%s\n", buff); - } - fflush(stderr); - exit(EXIT_FAILURE); -} - -// Print an error message on stderr -// starting with the file name and line number from the floc argument -// (prints: filename, a colon, " line ", the line number, and a space) -// and then the message. -// Then exit with a failure code, so this function does not return. -void bail_with_prog_error(file_location floc, const char *fmt, ...) -{ - fflush(stdout); // flush so output comes after what has happened already - // print file, line, column information - fprintf(stderr, "%s: line %d ", floc.filename, floc.line); - - va_list(args); - va_start(args, fmt); - vbail_with_error(fmt, args); -} - -#define BUF_SIZE 1024 - -// Call yyerror to print an error message on stderr -// starting with the filename, ":", the lexer's current line number, ": ", -// and then the formatted message (as in sprintf) -extern void formatted_yyerror(const char *filename, const char *fmt, ...) -{ - fflush(stdout); // flush so output comes after what has happened already - - char buf[BUF_SIZE]; - va_list(args); - va_start(args, fmt); - vsnprintf(buf, BUF_SIZE, fmt, args); - yyerror(filename, buf); - va_end(args); -} - - - -// print a newline on out and flush out -void newline(FILE *out) -{ - fprintf(out, "\n"); - fflush(out); -} - diff --git a/utilities.h b/utilities.h deleted file mode 100755 index 5549807..0000000 --- a/utilities.h +++ /dev/null @@ -1,37 +0,0 @@ -/* $Id: utilities.h,v 1.5 2024/11/13 14:08:23 leavens Exp $ */ -#ifndef _UTILITIES_H -#define _UTILITIES_H -#include -#include -#include -#include "file_location.h" -#include "lexer_utilities.h" - -#define MAX(x,y) (((x)>(y))?(x):(y)) - -// If NDEBUG is defined, do nothing, otherwise (when debugging) -// flush stderr and stdout, then print the message given on stderr, -// using printf formatting from the format string fmt. -// This function returns normally. -void debug_print(const char *fmt, ...); - -// Format a string error message and print it using perror (for an OS error) -// then exit with a failure code, so a call to this does not return. -extern void bail_with_error(const char *fmt, ...); - -// Print an error message on stderr -// starting with the file name and line number from the floc argument -// (prints: filename, a colon, " line ", the line number, and a space) -// and then the message. -// Then exit with a failure code, so this function does not return. -extern void bail_with_prog_error(file_location floc, const char *fmt, ...); - -// Call yyerror to print an error message on stderr -// starting with the filename, ":", the lexer's current line number, ": ", -// and then the formatted message (as in sprintf) -extern void formatted_yyerror(const char *filename, const char *fmt, ...); - -// print a newline on out and flush out -extern void newline(FILE *out); - -#endif diff --git a/vm/BOF_layout.png b/vm/BOF_layout.png deleted file mode 100755 index b8ef9b2a245c70daa352a355cb30a554e1de761b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55499 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 $@ 2>&1 - -%.myp: %.bof $(VM) - ./$(VM) -p $< > $@ 2>&1 - -# main target for testing -.PHONY: check-outputs -check-outputs: $(VM) $(ASM) $(TESTS) check-lst-outputs check-vm-outputs - @echo 'Be sure to look for two test summaries above (listings and execution)' - -check-lst-outputs check-asm-outputs: - @DIFFS=0; \ - for f in `echo $(TESTS) | sed -e 's/\\.bof//g'`; \ - do \ - echo listing "$$f.bof" using ./$(VM) -p ...; \ - ./$(VM) -p "$$f.bof" > "$$f.myp" 2>&1; \ - diff -w -B "$$f.lst" "$$f.myp" && echo 'passed!' \ - || { echo 'failed!'; DIFFS=1; }; \ - done; \ - if test 0 = $$DIFFS; \ - then \ - echo 'All listing tests passed!'; \ - else \ - echo 'Some listing test(s) failed!'; \ - fi - -check-vm-outputs: - @DIFFS=0; \ - for f in `echo $(TESTS) | sed -e 's/\\.bof//g'`; \ - do \ - echo running "$$f.bof" in the VM using ./$(VM) -t ...; \ - ./$(VM) -t "$$f.bof" > "$$f.myo" 2>&1; \ - diff -w -B "$$f.out" "$$f.myo" && echo 'passed!' \ - || { echo 'failed!'; DIFFS=1; }; \ - done; \ - if test 0 = $$DIFFS; \ - then \ - echo 'All VM execution tests passed!'; \ - else \ - echo 'Some VM execution test(s) failed!'; \ - fi - -# Automatically generate the submission zip file -$(SUBMISSIONZIPFILE): *.c *.h $(STUDENTTESTOUTPUTS) $(STUDENTTESTLISTINGS) \ - Makefile - $(ZIP) $@ $^ asm.y asm_lexer.l $(EXPECTEDOUTPUTS) $(EXPECTEDLISTINGS) $(TESTS) $(TESTSOURCES) - -# instructor's section below... - -ASM = asm -DISASM = disasm -BOF_BIN_DUMP = bof_bin_dump -LEX = flex -LEXFLAGS = -# the following line is just to jog the memory, it is not used -FLEX = $(LEX) -YACC = bison -YACCFLAGS = -Wall --locations -d -v -LEXER = lexer - -.DEFAULT: $(VM) - -$(ASM)_lexer.c: $(ASM)_lexer.l $(ASM).tab.h - $(LEX) $(LEXFLAGS) $< - -$(ASM)_lexer.o: $(ASM)_lexer.c ast.h $(ASM).tab.h utilities.h char_utilities.h file_location.h - $(CC) $(CFLAGS) -Wno-unused-but-set-variable -Wno-unused-function -c $< - -$(ASM).tab.o: $(ASM).tab.c $(ASM).tab.h - $(CC) $(CFLAGS) -Wno-unused-const-variable -c $< - -instruction.o: $(ASM).tab.h - -$(ASM).tab.c $(ASM).tab.h: $(ASM).y ast.h parser_types.h machine_types.h - $(RM) $(ASM).tab.h $(ASM).tab.c - $(YACC) $(YACCFLAGS) $(ASM).y - -lexer.o: lexer.c lexer.h $(ASM).tab.h - $(CC) $(CFLAGS) -c $< - -$(LEXER) : $(LEXER)_main.o $(LEXER).o $(ASM)_lexer.o ast.o $(ASM).tab.o file_location.o lexer.o utilities.o char_utilities.o - $(CC) $(CFLAGS) $^ -o $@ - -$(ASM)_main.o: $(ASM)_main.c $(ASM).tab.h ast.h parser_types.h machine_types.h - -ASM_OBJECTS = $(ASM)_main.o $(ASM).tab.o $(ASM)_lexer.o $(ASM)_unparser.o ast.o bof.o file_location.o lexer.o pass1.o assemble.o instruction.o machine_types.o regname.o symtab.o utilities.o char_utilities.o - -$(ASM): $(ASM).tab.h $(ASM_OBJECTS) - $(CC) $(CFLAGS) $^ -o $@ - -$(DISASM): disasm_main.o disasm.o instruction.o bof.o machine_types.o regname.o utilities.o - $(CC) $(CFLAGS) -o $(DISASM) $^ - -.PHONY: all -all: $(VM) $(ASM) $(DISASM) - -.PHONY: check-separately -check-separately: - $(CC) $(CFLAGS) -c *.c diff --git a/vm/Makefile-for-Instructor b/vm/Makefile-for-Instructor deleted file mode 100755 index 3009c95..0000000 --- a/vm/Makefile-for-Instructor +++ /dev/null @@ -1,113 +0,0 @@ -# $Id: Makefile-for-Instructor,v 1.3 2024/11/10 14:42:04 leavens Exp $ - -include Makefile - -$(BOF_BIN_DUMP): bof_bin_dump.o bof.o utilities.o - $(CC) $(CFLAGS) -o $(BOF_BIN_DUMP) $^ - -.PHONY: all -all: $(ASM).tab.h vm asm disasm bof_bin_dump - -.PRECIOUS: %.out %.lst -%.out: %.bof $(VM) - $(RM) $@ - - ./$(VM) -t $< > $@ 2>&1 - -%.lst: %.bof $(VM) - rm -f $@ - - ./$(VM) -p $< > $@ 2>&1 - -.PHONY: create-outputs -create-outputs: $(VM) $(ASM) $(TESTS) - $(MAKE) -f Makefile-for-Instructor create-vm-outputs - $(MAKE) -f Makefile-for-Instructor create-asm-outputs - -create-vm-outputs: $(VM) $(ASM) $(TESTS) - for f in `echo $(TESTS) | sed -e 's/\\.bof//g'`; \ - do \ - $(RM) "$$f.out"; \ - echo running "$$f.bof" " ... in the VM, with -t option"; \ - ./$(VM) -t "$$f.bof" > "$$f.out" 2>&1 || true ; \ - done - echo 'done creating VM test tracing outputs!' - -create-asm-outputs: $(VM) $(ASM) $(TESTS) - for f in `echo $(TESTS) | sed -e 's/\\.bof//g'`; \ - do \ - $(RM) "$$f.lst"; \ - echo running "$$f.bof" " ... in the VM, with -p option"; \ - ./$(VM) -p "$$f.bof" > "$$f.lst" 2>&1; \ - done - echo 'done creating listing outputs!' - -.PHONY: digest -digest digest.txt: $(EXPECTEDOUTPUTS) $(EXPECTEDLISTINGS) - for f in $(EXPECTEDLISTINGS) ; \ - do cat $$f; echo " "; \ - cat `echo $$f | sed -e 's/\\.lst/.out/'`; \ - echo " "; echo " "; \ - done >digest.txt - -# don't use develop-clean unless you want to regenerate the expected outputs -.PHONY: develop-clean bof-clean asm-clean -develop-clean: cleanall asm-clean - $(RM) digest.txt - $(RM) y.tab.h - -asm-clean: - $(RM) $(ASM)_lexer.[ch] $(ASM).tab.[ch] asm.output - $(RM) $(ASM).exe $(ASM) $(DISASM).exe $(DISASM) $(LEXER) $(LEXER).exe - $(RM) $(BOF_BIN_DUMP).exe $(BOF_BIN_DUMP) - -outputs-clean: clean asm-clean bof-clean - $(RM) $(EXPECTEDOUTPUTS) $(EXPECTEDLISTINGS) - -bof-clean: - $(RM) *.bof - -ZIPFILE = hw1-tests.zip -TESTSZIPFILE = ../$(ZIPFILE) -PROVIDEDFILES = Makefile asm_main.c asm.y asm_lexer.l \ - asm_lexer.c asm.tab.[ch] parser_types.h \ - asm_unparser.[ch] ast.[ch] bof.[ch] machine_types.[ch] \ - utilities.[ch] file_location.[ch] lexer.[ch] \ - pass1.[ch] assemble.[ch] instruction.[ch] regname.[ch] \ - symtab.[ch] utilities.[ch] char_utilities.[ch] \ - id_attrs_assoc.h disasm_main.c disasm.[ch] \ - vm_test*.asm vm_test*.out vm_test*.bof vm_test*.lst \ - bof_bin_dump.c - -PDFFILES = ../../ssm-vm.pdf ../../ssm-asm.pdf - -.PHONY: zip $(ZIPFILE) - -zip $(ZIPFILE): $(TESTSZIPFILE) - -$(TESTSZIPFILE): $(PDFFILES) Makefile $(TESTS) $(PROVIDEDFILES) $(VM) create-vm-outputs - $(RM) $(TESTSZIPFILE) - $(CHMOD) a-w *.lst *.asm *.bof *.lst *.[ch] \ - $(EXPECTEDOUTPUTS) $(EXPECTEDLISTINGS) - $(CHMOD) a+r Makefile $(TESTS) $(PROVIDEDFILES) - $(CHMOD) u+w Makefile asm.tab.h asm.tab.c - $(ZIP) $(TESTSZIPFILE) $(PDFFILES) Makefile $(TESTS) $(PROVIDEDFILES) - $(CHMOD) u+rw Makefile $(TESTS) $(PROVIDEDFILES) *.[ch] - -%.bof: %.$(ASM) - $(RM) -f $@ - ./$(ASM) $< - -SOLUTIONZIP = hw1-solution.zip - -.PHONY: $(SOLUTIONZIP) solution -$(SOLUTIONZIP) ~/temp/$(SOLUTIONZIP) solution: Makefile $(ASM) $(TESTS) \ - $(PROVIDEDFILES) *.out *.lst *.c *.h - $(MAKE) clean - $(ZIP) ~/temp/hw1-solution.zip $^ - -show_magic.o: bof.h - -show_magic: show_magic.o bof.o utilities.o - $(CC) $^ -o $@ - -test: test.o machine_types.o utilities.o - $(CC) $^ -o $@ diff --git a/vm/asm.output b/vm/asm.output deleted file mode 100644 index dd85311..0000000 --- a/vm/asm.output +++ /dev/null @@ -1,2091 +0,0 @@ -Grammar - - 0 $accept: program $end - - 1 program: textSection dataSection stackSection ".end" - - 2 textSection: ".text" entryPoint asmInstrs - - 3 entryPoint: addr - - 4 addr: label - 5 | unsignednumsym - - 6 label: identsym - - 7 asmInstrs: asmInstr - 8 | asmInstrs asmInstr - - 9 asmInstr: labelOpt instr eolsym - - 10 labelOpt: label ":" - 11 | empty - - 12 empty: ε - - 13 instr: noArgInstr - 14 | twoRegCompInstr - 15 | twoRegNoOffsetsInstr - 16 | noTargetOffsetInstr - 17 | noSourceOffsetInstr - 18 | oneRegOffsetArgInstr - 19 | oneRegArgInstr - 20 | oneRegOffsetInstr - 21 | shiftInstr - 22 | argOnlyInstr - 23 | immedArithInstr - 24 | immedBoolInstr - 25 | branchTestInstr - 26 | jumpInstr - 27 | syscallInstr - - 28 noArgInstr: noArgOp - - 29 noArgOp: "NOP" - 30 | "RTN" - - 31 twoRegCompInstr: twoRegCompOp regsym "," offset "," regsym "," offset - - 32 twoRegCompOp: "ADD" - 33 | "SUB" - 34 | "CPW" - 35 | "AND" - 36 | "BOR" - 37 | "NOR" - 38 | "XOR" - 39 | "SCA" - 40 | "LWI" - 41 | "NEG" - - 42 offset: number - - 43 number: sign unsignednumsym - - 44 sign: "+" - 45 | "-" - 46 | empty - - 47 twoRegNoOffsetsInstr: twoRegNoOffsetsOp regsym "," regsym - - 48 twoRegNoOffsetsOp: "CPR" - - 49 noTargetOffsetInstr: noTargetOffsetOp regsym "," regsym "," offset - - 50 noTargetOffsetOp: "LWR" - - 51 noSourceOffsetInstr: noSourceOffsetOp regsym "," offset "," regsym - - 52 noSourceOffsetOp: "SWR" - - 53 oneRegOffsetArgInstr: oneRegOffsetArgOp regsym "," offset "," arg - - 54 oneRegOffsetArgOp: "LIT" - - 55 arg: number - - 56 oneRegArgInstr: oneRegArgOp regsym "," arg - - 57 oneRegArgOp: "ARI" - 58 | "SRI" - - 59 oneRegOffsetInstr: oneRegOffsetOp regsym "," offset - - 60 oneRegOffsetOp: "MUL" - 61 | "DIV" - 62 | "CFHI" - 63 | "CFLO" - 64 | "JMP" - 65 | "CSI" - - 66 shiftInstr: shiftOp regsym "," offset "," shift - - 67 shiftOp: "SLL" - 68 | "SRL" - - 69 shift: unsignednumsym - - 70 argOnlyInstr: argOnlyOp arg - - 71 argOnlyOp: "JREL" - - 72 immedArithInstr: immedArithOp regsym "," offset "," immed - - 73 immedArithOp: "ADDI" - - 74 immed: number - - 75 immedBoolInstr: immedBoolOp regsym "," offset "," uimmed - - 76 immedBoolOp: "ANDI" - 77 | "BORI" - 78 | "XORI" - 79 | "NORI" - - 80 uimmed: unsignednumsym - - 81 branchTestInstr: branchTestOp regsym "," offset "," immed - - 82 branchTestOp: "BEQ" - 83 | "BGEZ" - 84 | "BGTZ" - 85 | "BLEZ" - 86 | "BLTZ" - 87 | "BNE" - - 88 jumpInstr: jumpOp addr - - 89 jumpOp: "JMPA" - 90 | "CALL" - - 91 syscallInstr: offsetOnlySyscall - 92 | regOffsetSyscall - 93 | noArgSyscall - - 94 offsetOnlySyscall: offsetOnlySyscallOp offset - - 95 offsetOnlySyscallOp: "EXIT" - - 96 regOffsetSyscall: regOffsetSyscallOp regsym "," offset - - 97 regOffsetSyscallOp: "PSTR" - 98 | "PINT" - 99 | "PCH" - 100 | "RCH" - - 101 noArgSyscall: noArgSyscallOp - - 102 noArgSyscallOp: "STRA" - 103 | "NOTR" - - 104 dataSection: ".data" staticStartAddr staticDecls - - 105 staticStartAddr: unsignednumsym - - 106 staticDecls: empty - 107 | staticDecls staticDecl - - 108 staticDecl: dataSize identsym initializerOpt eolsym - - 109 dataSize: "WORD" - 110 | "CHAR" - 111 | "STRING" "[" unsignednumsym "]" - - 112 initializerOpt: "=" number - 113 | "=" charliteralsym - 114 | "=" stringliteralsym - 115 | empty - - 116 stackSection: ".stack" stackBottomAddr - - 117 stackBottomAddr: unsignednumsym - - -Terminals, with rules where they appear - - $end (0) 0 - error (256) - eolsym (258) 9 108 - identsym (259) 6 108 - unsignednumsym (260) 5 43 69 80 105 111 117 - "+" (261) 44 - "-" (262) 45 - "," (263) 31 47 49 51 53 56 59 66 72 75 81 96 - ".text" (264) 2 - ".data" (265) 104 - ".stack" (266) 116 - ".end" (267) 1 - ":" (268) 10 - "[" (269) 111 - "]" (270) 111 - "=" (271) 112 113 114 - "NOP" (272) 29 - "ADD" (273) 32 - "SUB" (274) 33 - "CPW" (275) 34 - "CPR" (276) 48 - "AND" (277) 35 - "BOR" (278) 36 - "NOR" (279) 37 - "XOR" (280) 38 - "LWR" (281) 50 - "SWR" (282) 52 - "SCA" (283) 39 - "LWI" (284) 40 - "NEG" (285) 41 - "LIT" (286) 54 - "ARI" (287) 57 - "SRI" (288) 58 - "MUL" (289) 60 - "DIV" (290) 61 - "CFHI" (291) 62 - "CFLO" (292) 63 - "SLL" (293) 67 - "SRL" (294) 68 - "JMP" (295) 64 - "JREL" (296) 71 - "ADDI" (297) 73 - "ANDI" (298) 76 - "BORI" (299) 77 - "NORI" (300) 79 - "XORI" (301) 78 - "BEQ" (302) 82 - "BGEZ" (303) 83 - "BLEZ" (304) 85 - "BGTZ" (305) 84 - "BLTZ" (306) 86 - "BNE" (307) 87 - "CSI" (308) 65 - "JMPA" (309) 89 - "CALL" (310) 90 - "RTN" (311) 30 - "EXIT" (312) 95 - "PSTR" (313) 97 - "PINT" (314) 98 - "PCH" (315) 99 - "RCH" (316) 100 - "STRA" (317) 102 - "NOTR" (318) 103 - regsym (319) 31 47 49 51 53 56 59 66 72 75 81 96 - "WORD" (320) 109 - "CHAR" (321) 110 - "STRING" (322) 111 - charliteralsym (323) 113 - stringliteralsym (324) 114 - - -Nonterminals, with rules where they appear - - $accept (70) - on left: 0 - program (71) - on left: 1 - on right: 0 - textSection (72) - on left: 2 - on right: 1 - entryPoint (73) - on left: 3 - on right: 2 - addr (74) - on left: 4 5 - on right: 3 88 - label (75) - on left: 6 - on right: 4 10 - asmInstrs (76) - on left: 7 8 - on right: 2 8 - asmInstr (77) - on left: 9 - on right: 7 8 - labelOpt (78) - on left: 10 11 - on right: 9 - empty (79) - on left: 12 - on right: 11 46 106 115 - instr (80) - on left: 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 - on right: 9 - noArgInstr (81) - on left: 28 - on right: 13 - noArgOp (82) - on left: 29 30 - on right: 28 - twoRegCompInstr (83) - on left: 31 - on right: 14 - twoRegCompOp (84) - on left: 32 33 34 35 36 37 38 39 40 41 - on right: 31 - offset (85) - on left: 42 - on right: 31 49 51 53 59 66 72 75 81 94 96 - number (86) - on left: 43 - on right: 42 55 74 112 - sign (87) - on left: 44 45 46 - on right: 43 - twoRegNoOffsetsInstr (88) - on left: 47 - on right: 15 - twoRegNoOffsetsOp (89) - on left: 48 - on right: 47 - noTargetOffsetInstr (90) - on left: 49 - on right: 16 - noTargetOffsetOp (91) - on left: 50 - on right: 49 - noSourceOffsetInstr (92) - on left: 51 - on right: 17 - noSourceOffsetOp (93) - on left: 52 - on right: 51 - oneRegOffsetArgInstr (94) - on left: 53 - on right: 18 - oneRegOffsetArgOp (95) - on left: 54 - on right: 53 - arg (96) - on left: 55 - on right: 53 56 70 - oneRegArgInstr (97) - on left: 56 - on right: 19 - oneRegArgOp (98) - on left: 57 58 - on right: 56 - oneRegOffsetInstr (99) - on left: 59 - on right: 20 - oneRegOffsetOp (100) - on left: 60 61 62 63 64 65 - on right: 59 - shiftInstr (101) - on left: 66 - on right: 21 - shiftOp (102) - on left: 67 68 - on right: 66 - shift (103) - on left: 69 - on right: 66 - argOnlyInstr (104) - on left: 70 - on right: 22 - argOnlyOp (105) - on left: 71 - on right: 70 - immedArithInstr (106) - on left: 72 - on right: 23 - immedArithOp (107) - on left: 73 - on right: 72 - immed (108) - on left: 74 - on right: 72 81 - immedBoolInstr (109) - on left: 75 - on right: 24 - immedBoolOp (110) - on left: 76 77 78 79 - on right: 75 - uimmed (111) - on left: 80 - on right: 75 - branchTestInstr (112) - on left: 81 - on right: 25 - branchTestOp (113) - on left: 82 83 84 85 86 87 - on right: 81 - jumpInstr (114) - on left: 88 - on right: 26 - jumpOp (115) - on left: 89 90 - on right: 88 - syscallInstr (116) - on left: 91 92 93 - on right: 27 - offsetOnlySyscall (117) - on left: 94 - on right: 91 - offsetOnlySyscallOp (118) - on left: 95 - on right: 94 - regOffsetSyscall (119) - on left: 96 - on right: 92 - regOffsetSyscallOp (120) - on left: 97 98 99 100 - on right: 96 - noArgSyscall (121) - on left: 101 - on right: 93 - noArgSyscallOp (122) - on left: 102 103 - on right: 101 - dataSection (123) - on left: 104 - on right: 1 - staticStartAddr (124) - on left: 105 - on right: 104 - staticDecls (125) - on left: 106 107 - on right: 104 107 - staticDecl (126) - on left: 108 - on right: 107 - dataSize (127) - on left: 109 110 111 - on right: 108 - initializerOpt (128) - on left: 112 113 114 115 - on right: 108 - stackSection (129) - on left: 116 - on right: 1 - stackBottomAddr (130) - on left: 117 - on right: 116 - - -State 0 - - 0 $accept: • program $end - - ".text" shift, and go to state 1 - - program go to state 2 - textSection go to state 3 - - -State 1 - - 2 textSection: ".text" • entryPoint asmInstrs - - identsym shift, and go to state 4 - unsignednumsym shift, and go to state 5 - - entryPoint go to state 6 - addr go to state 7 - label go to state 8 - - -State 2 - - 0 $accept: program • $end - - $end shift, and go to state 9 - - -State 3 - - 1 program: textSection • dataSection stackSection ".end" - - ".data" shift, and go to state 10 - - dataSection go to state 11 - - -State 4 - - 6 label: identsym • - - $default reduce using rule 6 (label) - - -State 5 - - 5 addr: unsignednumsym • - - $default reduce using rule 5 (addr) - - -State 6 - - 2 textSection: ".text" entryPoint • asmInstrs - - identsym shift, and go to state 4 - - $default reduce using rule 12 (empty) - - label go to state 12 - asmInstrs go to state 13 - asmInstr go to state 14 - labelOpt go to state 15 - empty go to state 16 - - -State 7 - - 3 entryPoint: addr • - - $default reduce using rule 3 (entryPoint) - - -State 8 - - 4 addr: label • - - $default reduce using rule 4 (addr) - - -State 9 - - 0 $accept: program $end • - - $default accept - - -State 10 - - 104 dataSection: ".data" • staticStartAddr staticDecls - - unsignednumsym shift, and go to state 17 - - staticStartAddr go to state 18 - - -State 11 - - 1 program: textSection dataSection • stackSection ".end" - - ".stack" shift, and go to state 19 - - stackSection go to state 20 - - -State 12 - - 10 labelOpt: label • ":" - - ":" shift, and go to state 21 - - -State 13 - - 2 textSection: ".text" entryPoint asmInstrs • - 8 asmInstrs: asmInstrs • asmInstr - - identsym shift, and go to state 4 - - ".data" reduce using rule 2 (textSection) - $default reduce using rule 12 (empty) - - label go to state 12 - asmInstr go to state 22 - labelOpt go to state 15 - empty go to state 16 - - -State 14 - - 7 asmInstrs: asmInstr • - - $default reduce using rule 7 (asmInstrs) - - -State 15 - - 9 asmInstr: labelOpt • instr eolsym - - "NOP" shift, and go to state 23 - "ADD" shift, and go to state 24 - "SUB" shift, and go to state 25 - "CPW" shift, and go to state 26 - "CPR" shift, and go to state 27 - "AND" shift, and go to state 28 - "BOR" shift, and go to state 29 - "NOR" shift, and go to state 30 - "XOR" shift, and go to state 31 - "LWR" shift, and go to state 32 - "SWR" shift, and go to state 33 - "SCA" shift, and go to state 34 - "LWI" shift, and go to state 35 - "NEG" shift, and go to state 36 - "LIT" shift, and go to state 37 - "ARI" shift, and go to state 38 - "SRI" shift, and go to state 39 - "MUL" shift, and go to state 40 - "DIV" shift, and go to state 41 - "CFHI" shift, and go to state 42 - "CFLO" shift, and go to state 43 - "SLL" shift, and go to state 44 - "SRL" shift, and go to state 45 - "JMP" shift, and go to state 46 - "JREL" shift, and go to state 47 - "ADDI" shift, and go to state 48 - "ANDI" shift, and go to state 49 - "BORI" shift, and go to state 50 - "NORI" shift, and go to state 51 - "XORI" shift, and go to state 52 - "BEQ" shift, and go to state 53 - "BGEZ" shift, and go to state 54 - "BLEZ" shift, and go to state 55 - "BGTZ" shift, and go to state 56 - "BLTZ" shift, and go to state 57 - "BNE" shift, and go to state 58 - "CSI" shift, and go to state 59 - "JMPA" shift, and go to state 60 - "CALL" shift, and go to state 61 - "RTN" shift, and go to state 62 - "EXIT" shift, and go to state 63 - "PSTR" shift, and go to state 64 - "PINT" shift, and go to state 65 - "PCH" shift, and go to state 66 - "RCH" shift, and go to state 67 - "STRA" shift, and go to state 68 - "NOTR" shift, and go to state 69 - - instr go to state 70 - noArgInstr go to state 71 - noArgOp go to state 72 - twoRegCompInstr go to state 73 - twoRegCompOp go to state 74 - twoRegNoOffsetsInstr go to state 75 - twoRegNoOffsetsOp go to state 76 - noTargetOffsetInstr go to state 77 - noTargetOffsetOp go to state 78 - noSourceOffsetInstr go to state 79 - noSourceOffsetOp go to state 80 - oneRegOffsetArgInstr go to state 81 - oneRegOffsetArgOp go to state 82 - oneRegArgInstr go to state 83 - oneRegArgOp go to state 84 - oneRegOffsetInstr go to state 85 - oneRegOffsetOp go to state 86 - shiftInstr go to state 87 - shiftOp go to state 88 - argOnlyInstr go to state 89 - argOnlyOp go to state 90 - immedArithInstr go to state 91 - immedArithOp go to state 92 - immedBoolInstr go to state 93 - immedBoolOp go to state 94 - branchTestInstr go to state 95 - branchTestOp go to state 96 - jumpInstr go to state 97 - jumpOp go to state 98 - syscallInstr go to state 99 - offsetOnlySyscall go to state 100 - offsetOnlySyscallOp go to state 101 - regOffsetSyscall go to state 102 - regOffsetSyscallOp go to state 103 - noArgSyscall go to state 104 - noArgSyscallOp go to state 105 - - -State 16 - - 11 labelOpt: empty • - - $default reduce using rule 11 (labelOpt) - - -State 17 - - 105 staticStartAddr: unsignednumsym • - - $default reduce using rule 105 (staticStartAddr) - - -State 18 - - 104 dataSection: ".data" staticStartAddr • staticDecls - - $default reduce using rule 12 (empty) - - empty go to state 106 - staticDecls go to state 107 - - -State 19 - - 116 stackSection: ".stack" • stackBottomAddr - - unsignednumsym shift, and go to state 108 - - stackBottomAddr go to state 109 - - -State 20 - - 1 program: textSection dataSection stackSection • ".end" - - ".end" shift, and go to state 110 - - -State 21 - - 10 labelOpt: label ":" • - - $default reduce using rule 10 (labelOpt) - - -State 22 - - 8 asmInstrs: asmInstrs asmInstr • - - $default reduce using rule 8 (asmInstrs) - - -State 23 - - 29 noArgOp: "NOP" • - - $default reduce using rule 29 (noArgOp) - - -State 24 - - 32 twoRegCompOp: "ADD" • - - $default reduce using rule 32 (twoRegCompOp) - - -State 25 - - 33 twoRegCompOp: "SUB" • - - $default reduce using rule 33 (twoRegCompOp) - - -State 26 - - 34 twoRegCompOp: "CPW" • - - $default reduce using rule 34 (twoRegCompOp) - - -State 27 - - 48 twoRegNoOffsetsOp: "CPR" • - - $default reduce using rule 48 (twoRegNoOffsetsOp) - - -State 28 - - 35 twoRegCompOp: "AND" • - - $default reduce using rule 35 (twoRegCompOp) - - -State 29 - - 36 twoRegCompOp: "BOR" • - - $default reduce using rule 36 (twoRegCompOp) - - -State 30 - - 37 twoRegCompOp: "NOR" • - - $default reduce using rule 37 (twoRegCompOp) - - -State 31 - - 38 twoRegCompOp: "XOR" • - - $default reduce using rule 38 (twoRegCompOp) - - -State 32 - - 50 noTargetOffsetOp: "LWR" • - - $default reduce using rule 50 (noTargetOffsetOp) - - -State 33 - - 52 noSourceOffsetOp: "SWR" • - - $default reduce using rule 52 (noSourceOffsetOp) - - -State 34 - - 39 twoRegCompOp: "SCA" • - - $default reduce using rule 39 (twoRegCompOp) - - -State 35 - - 40 twoRegCompOp: "LWI" • - - $default reduce using rule 40 (twoRegCompOp) - - -State 36 - - 41 twoRegCompOp: "NEG" • - - $default reduce using rule 41 (twoRegCompOp) - - -State 37 - - 54 oneRegOffsetArgOp: "LIT" • - - $default reduce using rule 54 (oneRegOffsetArgOp) - - -State 38 - - 57 oneRegArgOp: "ARI" • - - $default reduce using rule 57 (oneRegArgOp) - - -State 39 - - 58 oneRegArgOp: "SRI" • - - $default reduce using rule 58 (oneRegArgOp) - - -State 40 - - 60 oneRegOffsetOp: "MUL" • - - $default reduce using rule 60 (oneRegOffsetOp) - - -State 41 - - 61 oneRegOffsetOp: "DIV" • - - $default reduce using rule 61 (oneRegOffsetOp) - - -State 42 - - 62 oneRegOffsetOp: "CFHI" • - - $default reduce using rule 62 (oneRegOffsetOp) - - -State 43 - - 63 oneRegOffsetOp: "CFLO" • - - $default reduce using rule 63 (oneRegOffsetOp) - - -State 44 - - 67 shiftOp: "SLL" • - - $default reduce using rule 67 (shiftOp) - - -State 45 - - 68 shiftOp: "SRL" • - - $default reduce using rule 68 (shiftOp) - - -State 46 - - 64 oneRegOffsetOp: "JMP" • - - $default reduce using rule 64 (oneRegOffsetOp) - - -State 47 - - 71 argOnlyOp: "JREL" • - - $default reduce using rule 71 (argOnlyOp) - - -State 48 - - 73 immedArithOp: "ADDI" • - - $default reduce using rule 73 (immedArithOp) - - -State 49 - - 76 immedBoolOp: "ANDI" • - - $default reduce using rule 76 (immedBoolOp) - - -State 50 - - 77 immedBoolOp: "BORI" • - - $default reduce using rule 77 (immedBoolOp) - - -State 51 - - 79 immedBoolOp: "NORI" • - - $default reduce using rule 79 (immedBoolOp) - - -State 52 - - 78 immedBoolOp: "XORI" • - - $default reduce using rule 78 (immedBoolOp) - - -State 53 - - 82 branchTestOp: "BEQ" • - - $default reduce using rule 82 (branchTestOp) - - -State 54 - - 83 branchTestOp: "BGEZ" • - - $default reduce using rule 83 (branchTestOp) - - -State 55 - - 85 branchTestOp: "BLEZ" • - - $default reduce using rule 85 (branchTestOp) - - -State 56 - - 84 branchTestOp: "BGTZ" • - - $default reduce using rule 84 (branchTestOp) - - -State 57 - - 86 branchTestOp: "BLTZ" • - - $default reduce using rule 86 (branchTestOp) - - -State 58 - - 87 branchTestOp: "BNE" • - - $default reduce using rule 87 (branchTestOp) - - -State 59 - - 65 oneRegOffsetOp: "CSI" • - - $default reduce using rule 65 (oneRegOffsetOp) - - -State 60 - - 89 jumpOp: "JMPA" • - - $default reduce using rule 89 (jumpOp) - - -State 61 - - 90 jumpOp: "CALL" • - - $default reduce using rule 90 (jumpOp) - - -State 62 - - 30 noArgOp: "RTN" • - - $default reduce using rule 30 (noArgOp) - - -State 63 - - 95 offsetOnlySyscallOp: "EXIT" • - - $default reduce using rule 95 (offsetOnlySyscallOp) - - -State 64 - - 97 regOffsetSyscallOp: "PSTR" • - - $default reduce using rule 97 (regOffsetSyscallOp) - - -State 65 - - 98 regOffsetSyscallOp: "PINT" • - - $default reduce using rule 98 (regOffsetSyscallOp) - - -State 66 - - 99 regOffsetSyscallOp: "PCH" • - - $default reduce using rule 99 (regOffsetSyscallOp) - - -State 67 - - 100 regOffsetSyscallOp: "RCH" • - - $default reduce using rule 100 (regOffsetSyscallOp) - - -State 68 - - 102 noArgSyscallOp: "STRA" • - - $default reduce using rule 102 (noArgSyscallOp) - - -State 69 - - 103 noArgSyscallOp: "NOTR" • - - $default reduce using rule 103 (noArgSyscallOp) - - -State 70 - - 9 asmInstr: labelOpt instr • eolsym - - eolsym shift, and go to state 111 - - -State 71 - - 13 instr: noArgInstr • - - $default reduce using rule 13 (instr) - - -State 72 - - 28 noArgInstr: noArgOp • - - $default reduce using rule 28 (noArgInstr) - - -State 73 - - 14 instr: twoRegCompInstr • - - $default reduce using rule 14 (instr) - - -State 74 - - 31 twoRegCompInstr: twoRegCompOp • regsym "," offset "," regsym "," offset - - regsym shift, and go to state 112 - - -State 75 - - 15 instr: twoRegNoOffsetsInstr • - - $default reduce using rule 15 (instr) - - -State 76 - - 47 twoRegNoOffsetsInstr: twoRegNoOffsetsOp • regsym "," regsym - - regsym shift, and go to state 113 - - -State 77 - - 16 instr: noTargetOffsetInstr • - - $default reduce using rule 16 (instr) - - -State 78 - - 49 noTargetOffsetInstr: noTargetOffsetOp • regsym "," regsym "," offset - - regsym shift, and go to state 114 - - -State 79 - - 17 instr: noSourceOffsetInstr • - - $default reduce using rule 17 (instr) - - -State 80 - - 51 noSourceOffsetInstr: noSourceOffsetOp • regsym "," offset "," regsym - - regsym shift, and go to state 115 - - -State 81 - - 18 instr: oneRegOffsetArgInstr • - - $default reduce using rule 18 (instr) - - -State 82 - - 53 oneRegOffsetArgInstr: oneRegOffsetArgOp • regsym "," offset "," arg - - regsym shift, and go to state 116 - - -State 83 - - 19 instr: oneRegArgInstr • - - $default reduce using rule 19 (instr) - - -State 84 - - 56 oneRegArgInstr: oneRegArgOp • regsym "," arg - - regsym shift, and go to state 117 - - -State 85 - - 20 instr: oneRegOffsetInstr • - - $default reduce using rule 20 (instr) - - -State 86 - - 59 oneRegOffsetInstr: oneRegOffsetOp • regsym "," offset - - regsym shift, and go to state 118 - - -State 87 - - 21 instr: shiftInstr • - - $default reduce using rule 21 (instr) - - -State 88 - - 66 shiftInstr: shiftOp • regsym "," offset "," shift - - regsym shift, and go to state 119 - - -State 89 - - 22 instr: argOnlyInstr • - - $default reduce using rule 22 (instr) - - -State 90 - - 70 argOnlyInstr: argOnlyOp • arg - - "+" shift, and go to state 120 - "-" shift, and go to state 121 - - $default reduce using rule 12 (empty) - - empty go to state 122 - number go to state 123 - sign go to state 124 - arg go to state 125 - - -State 91 - - 23 instr: immedArithInstr • - - $default reduce using rule 23 (instr) - - -State 92 - - 72 immedArithInstr: immedArithOp • regsym "," offset "," immed - - regsym shift, and go to state 126 - - -State 93 - - 24 instr: immedBoolInstr • - - $default reduce using rule 24 (instr) - - -State 94 - - 75 immedBoolInstr: immedBoolOp • regsym "," offset "," uimmed - - regsym shift, and go to state 127 - - -State 95 - - 25 instr: branchTestInstr • - - $default reduce using rule 25 (instr) - - -State 96 - - 81 branchTestInstr: branchTestOp • regsym "," offset "," immed - - regsym shift, and go to state 128 - - -State 97 - - 26 instr: jumpInstr • - - $default reduce using rule 26 (instr) - - -State 98 - - 88 jumpInstr: jumpOp • addr - - identsym shift, and go to state 4 - unsignednumsym shift, and go to state 5 - - addr go to state 129 - label go to state 8 - - -State 99 - - 27 instr: syscallInstr • - - $default reduce using rule 27 (instr) - - -State 100 - - 91 syscallInstr: offsetOnlySyscall • - - $default reduce using rule 91 (syscallInstr) - - -State 101 - - 94 offsetOnlySyscall: offsetOnlySyscallOp • offset - - "+" shift, and go to state 120 - "-" shift, and go to state 121 - - $default reduce using rule 12 (empty) - - empty go to state 122 - offset go to state 130 - number go to state 131 - sign go to state 124 - - -State 102 - - 92 syscallInstr: regOffsetSyscall • - - $default reduce using rule 92 (syscallInstr) - - -State 103 - - 96 regOffsetSyscall: regOffsetSyscallOp • regsym "," offset - - regsym shift, and go to state 132 - - -State 104 - - 93 syscallInstr: noArgSyscall • - - $default reduce using rule 93 (syscallInstr) - - -State 105 - - 101 noArgSyscall: noArgSyscallOp • - - $default reduce using rule 101 (noArgSyscall) - - -State 106 - - 106 staticDecls: empty • - - $default reduce using rule 106 (staticDecls) - - -State 107 - - 104 dataSection: ".data" staticStartAddr staticDecls • - 107 staticDecls: staticDecls • staticDecl - - "WORD" shift, and go to state 133 - "CHAR" shift, and go to state 134 - "STRING" shift, and go to state 135 - - $default reduce using rule 104 (dataSection) - - staticDecl go to state 136 - dataSize go to state 137 - - -State 108 - - 117 stackBottomAddr: unsignednumsym • - - $default reduce using rule 117 (stackBottomAddr) - - -State 109 - - 116 stackSection: ".stack" stackBottomAddr • - - $default reduce using rule 116 (stackSection) - - -State 110 - - 1 program: textSection dataSection stackSection ".end" • - - $default reduce using rule 1 (program) - - -State 111 - - 9 asmInstr: labelOpt instr eolsym • - - $default reduce using rule 9 (asmInstr) - - -State 112 - - 31 twoRegCompInstr: twoRegCompOp regsym • "," offset "," regsym "," offset - - "," shift, and go to state 138 - - -State 113 - - 47 twoRegNoOffsetsInstr: twoRegNoOffsetsOp regsym • "," regsym - - "," shift, and go to state 139 - - -State 114 - - 49 noTargetOffsetInstr: noTargetOffsetOp regsym • "," regsym "," offset - - "," shift, and go to state 140 - - -State 115 - - 51 noSourceOffsetInstr: noSourceOffsetOp regsym • "," offset "," regsym - - "," shift, and go to state 141 - - -State 116 - - 53 oneRegOffsetArgInstr: oneRegOffsetArgOp regsym • "," offset "," arg - - "," shift, and go to state 142 - - -State 117 - - 56 oneRegArgInstr: oneRegArgOp regsym • "," arg - - "," shift, and go to state 143 - - -State 118 - - 59 oneRegOffsetInstr: oneRegOffsetOp regsym • "," offset - - "," shift, and go to state 144 - - -State 119 - - 66 shiftInstr: shiftOp regsym • "," offset "," shift - - "," shift, and go to state 145 - - -State 120 - - 44 sign: "+" • - - $default reduce using rule 44 (sign) - - -State 121 - - 45 sign: "-" • - - $default reduce using rule 45 (sign) - - -State 122 - - 46 sign: empty • - - $default reduce using rule 46 (sign) - - -State 123 - - 55 arg: number • - - $default reduce using rule 55 (arg) - - -State 124 - - 43 number: sign • unsignednumsym - - unsignednumsym shift, and go to state 146 - - -State 125 - - 70 argOnlyInstr: argOnlyOp arg • - - $default reduce using rule 70 (argOnlyInstr) - - -State 126 - - 72 immedArithInstr: immedArithOp regsym • "," offset "," immed - - "," shift, and go to state 147 - - -State 127 - - 75 immedBoolInstr: immedBoolOp regsym • "," offset "," uimmed - - "," shift, and go to state 148 - - -State 128 - - 81 branchTestInstr: branchTestOp regsym • "," offset "," immed - - "," shift, and go to state 149 - - -State 129 - - 88 jumpInstr: jumpOp addr • - - $default reduce using rule 88 (jumpInstr) - - -State 130 - - 94 offsetOnlySyscall: offsetOnlySyscallOp offset • - - $default reduce using rule 94 (offsetOnlySyscall) - - -State 131 - - 42 offset: number • - - $default reduce using rule 42 (offset) - - -State 132 - - 96 regOffsetSyscall: regOffsetSyscallOp regsym • "," offset - - "," shift, and go to state 150 - - -State 133 - - 109 dataSize: "WORD" • - - $default reduce using rule 109 (dataSize) - - -State 134 - - 110 dataSize: "CHAR" • - - $default reduce using rule 110 (dataSize) - - -State 135 - - 111 dataSize: "STRING" • "[" unsignednumsym "]" - - "[" shift, and go to state 151 - - -State 136 - - 107 staticDecls: staticDecls staticDecl • - - $default reduce using rule 107 (staticDecls) - - -State 137 - - 108 staticDecl: dataSize • identsym initializerOpt eolsym - - identsym shift, and go to state 152 - - -State 138 - - 31 twoRegCompInstr: twoRegCompOp regsym "," • offset "," regsym "," offset - - "+" shift, and go to state 120 - "-" shift, and go to state 121 - - $default reduce using rule 12 (empty) - - empty go to state 122 - offset go to state 153 - number go to state 131 - sign go to state 124 - - -State 139 - - 47 twoRegNoOffsetsInstr: twoRegNoOffsetsOp regsym "," • regsym - - regsym shift, and go to state 154 - - -State 140 - - 49 noTargetOffsetInstr: noTargetOffsetOp regsym "," • regsym "," offset - - regsym shift, and go to state 155 - - -State 141 - - 51 noSourceOffsetInstr: noSourceOffsetOp regsym "," • offset "," regsym - - "+" shift, and go to state 120 - "-" shift, and go to state 121 - - $default reduce using rule 12 (empty) - - empty go to state 122 - offset go to state 156 - number go to state 131 - sign go to state 124 - - -State 142 - - 53 oneRegOffsetArgInstr: oneRegOffsetArgOp regsym "," • offset "," arg - - "+" shift, and go to state 120 - "-" shift, and go to state 121 - - $default reduce using rule 12 (empty) - - empty go to state 122 - offset go to state 157 - number go to state 131 - sign go to state 124 - - -State 143 - - 56 oneRegArgInstr: oneRegArgOp regsym "," • arg - - "+" shift, and go to state 120 - "-" shift, and go to state 121 - - $default reduce using rule 12 (empty) - - empty go to state 122 - number go to state 123 - sign go to state 124 - arg go to state 158 - - -State 144 - - 59 oneRegOffsetInstr: oneRegOffsetOp regsym "," • offset - - "+" shift, and go to state 120 - "-" shift, and go to state 121 - - $default reduce using rule 12 (empty) - - empty go to state 122 - offset go to state 159 - number go to state 131 - sign go to state 124 - - -State 145 - - 66 shiftInstr: shiftOp regsym "," • offset "," shift - - "+" shift, and go to state 120 - "-" shift, and go to state 121 - - $default reduce using rule 12 (empty) - - empty go to state 122 - offset go to state 160 - number go to state 131 - sign go to state 124 - - -State 146 - - 43 number: sign unsignednumsym • - - $default reduce using rule 43 (number) - - -State 147 - - 72 immedArithInstr: immedArithOp regsym "," • offset "," immed - - "+" shift, and go to state 120 - "-" shift, and go to state 121 - - $default reduce using rule 12 (empty) - - empty go to state 122 - offset go to state 161 - number go to state 131 - sign go to state 124 - - -State 148 - - 75 immedBoolInstr: immedBoolOp regsym "," • offset "," uimmed - - "+" shift, and go to state 120 - "-" shift, and go to state 121 - - $default reduce using rule 12 (empty) - - empty go to state 122 - offset go to state 162 - number go to state 131 - sign go to state 124 - - -State 149 - - 81 branchTestInstr: branchTestOp regsym "," • offset "," immed - - "+" shift, and go to state 120 - "-" shift, and go to state 121 - - $default reduce using rule 12 (empty) - - empty go to state 122 - offset go to state 163 - number go to state 131 - sign go to state 124 - - -State 150 - - 96 regOffsetSyscall: regOffsetSyscallOp regsym "," • offset - - "+" shift, and go to state 120 - "-" shift, and go to state 121 - - $default reduce using rule 12 (empty) - - empty go to state 122 - offset go to state 164 - number go to state 131 - sign go to state 124 - - -State 151 - - 111 dataSize: "STRING" "[" • unsignednumsym "]" - - unsignednumsym shift, and go to state 165 - - -State 152 - - 108 staticDecl: dataSize identsym • initializerOpt eolsym - - "=" shift, and go to state 166 - - $default reduce using rule 12 (empty) - - empty go to state 167 - initializerOpt go to state 168 - - -State 153 - - 31 twoRegCompInstr: twoRegCompOp regsym "," offset • "," regsym "," offset - - "," shift, and go to state 169 - - -State 154 - - 47 twoRegNoOffsetsInstr: twoRegNoOffsetsOp regsym "," regsym • - - $default reduce using rule 47 (twoRegNoOffsetsInstr) - - -State 155 - - 49 noTargetOffsetInstr: noTargetOffsetOp regsym "," regsym • "," offset - - "," shift, and go to state 170 - - -State 156 - - 51 noSourceOffsetInstr: noSourceOffsetOp regsym "," offset • "," regsym - - "," shift, and go to state 171 - - -State 157 - - 53 oneRegOffsetArgInstr: oneRegOffsetArgOp regsym "," offset • "," arg - - "," shift, and go to state 172 - - -State 158 - - 56 oneRegArgInstr: oneRegArgOp regsym "," arg • - - $default reduce using rule 56 (oneRegArgInstr) - - -State 159 - - 59 oneRegOffsetInstr: oneRegOffsetOp regsym "," offset • - - $default reduce using rule 59 (oneRegOffsetInstr) - - -State 160 - - 66 shiftInstr: shiftOp regsym "," offset • "," shift - - "," shift, and go to state 173 - - -State 161 - - 72 immedArithInstr: immedArithOp regsym "," offset • "," immed - - "," shift, and go to state 174 - - -State 162 - - 75 immedBoolInstr: immedBoolOp regsym "," offset • "," uimmed - - "," shift, and go to state 175 - - -State 163 - - 81 branchTestInstr: branchTestOp regsym "," offset • "," immed - - "," shift, and go to state 176 - - -State 164 - - 96 regOffsetSyscall: regOffsetSyscallOp regsym "," offset • - - $default reduce using rule 96 (regOffsetSyscall) - - -State 165 - - 111 dataSize: "STRING" "[" unsignednumsym • "]" - - "]" shift, and go to state 177 - - -State 166 - - 112 initializerOpt: "=" • number - 113 | "=" • charliteralsym - 114 | "=" • stringliteralsym - - "+" shift, and go to state 120 - "-" shift, and go to state 121 - charliteralsym shift, and go to state 178 - stringliteralsym shift, and go to state 179 - - $default reduce using rule 12 (empty) - - empty go to state 122 - number go to state 180 - sign go to state 124 - - -State 167 - - 115 initializerOpt: empty • - - $default reduce using rule 115 (initializerOpt) - - -State 168 - - 108 staticDecl: dataSize identsym initializerOpt • eolsym - - eolsym shift, and go to state 181 - - -State 169 - - 31 twoRegCompInstr: twoRegCompOp regsym "," offset "," • regsym "," offset - - regsym shift, and go to state 182 - - -State 170 - - 49 noTargetOffsetInstr: noTargetOffsetOp regsym "," regsym "," • offset - - "+" shift, and go to state 120 - "-" shift, and go to state 121 - - $default reduce using rule 12 (empty) - - empty go to state 122 - offset go to state 183 - number go to state 131 - sign go to state 124 - - -State 171 - - 51 noSourceOffsetInstr: noSourceOffsetOp regsym "," offset "," • regsym - - regsym shift, and go to state 184 - - -State 172 - - 53 oneRegOffsetArgInstr: oneRegOffsetArgOp regsym "," offset "," • arg - - "+" shift, and go to state 120 - "-" shift, and go to state 121 - - $default reduce using rule 12 (empty) - - empty go to state 122 - number go to state 123 - sign go to state 124 - arg go to state 185 - - -State 173 - - 66 shiftInstr: shiftOp regsym "," offset "," • shift - - unsignednumsym shift, and go to state 186 - - shift go to state 187 - - -State 174 - - 72 immedArithInstr: immedArithOp regsym "," offset "," • immed - - "+" shift, and go to state 120 - "-" shift, and go to state 121 - - $default reduce using rule 12 (empty) - - empty go to state 122 - number go to state 188 - sign go to state 124 - immed go to state 189 - - -State 175 - - 75 immedBoolInstr: immedBoolOp regsym "," offset "," • uimmed - - unsignednumsym shift, and go to state 190 - - uimmed go to state 191 - - -State 176 - - 81 branchTestInstr: branchTestOp regsym "," offset "," • immed - - "+" shift, and go to state 120 - "-" shift, and go to state 121 - - $default reduce using rule 12 (empty) - - empty go to state 122 - number go to state 188 - sign go to state 124 - immed go to state 192 - - -State 177 - - 111 dataSize: "STRING" "[" unsignednumsym "]" • - - $default reduce using rule 111 (dataSize) - - -State 178 - - 113 initializerOpt: "=" charliteralsym • - - $default reduce using rule 113 (initializerOpt) - - -State 179 - - 114 initializerOpt: "=" stringliteralsym • - - $default reduce using rule 114 (initializerOpt) - - -State 180 - - 112 initializerOpt: "=" number • - - $default reduce using rule 112 (initializerOpt) - - -State 181 - - 108 staticDecl: dataSize identsym initializerOpt eolsym • - - $default reduce using rule 108 (staticDecl) - - -State 182 - - 31 twoRegCompInstr: twoRegCompOp regsym "," offset "," regsym • "," offset - - "," shift, and go to state 193 - - -State 183 - - 49 noTargetOffsetInstr: noTargetOffsetOp regsym "," regsym "," offset • - - $default reduce using rule 49 (noTargetOffsetInstr) - - -State 184 - - 51 noSourceOffsetInstr: noSourceOffsetOp regsym "," offset "," regsym • - - $default reduce using rule 51 (noSourceOffsetInstr) - - -State 185 - - 53 oneRegOffsetArgInstr: oneRegOffsetArgOp regsym "," offset "," arg • - - $default reduce using rule 53 (oneRegOffsetArgInstr) - - -State 186 - - 69 shift: unsignednumsym • - - $default reduce using rule 69 (shift) - - -State 187 - - 66 shiftInstr: shiftOp regsym "," offset "," shift • - - $default reduce using rule 66 (shiftInstr) - - -State 188 - - 74 immed: number • - - $default reduce using rule 74 (immed) - - -State 189 - - 72 immedArithInstr: immedArithOp regsym "," offset "," immed • - - $default reduce using rule 72 (immedArithInstr) - - -State 190 - - 80 uimmed: unsignednumsym • - - $default reduce using rule 80 (uimmed) - - -State 191 - - 75 immedBoolInstr: immedBoolOp regsym "," offset "," uimmed • - - $default reduce using rule 75 (immedBoolInstr) - - -State 192 - - 81 branchTestInstr: branchTestOp regsym "," offset "," immed • - - $default reduce using rule 81 (branchTestInstr) - - -State 193 - - 31 twoRegCompInstr: twoRegCompOp regsym "," offset "," regsym "," • offset - - "+" shift, and go to state 120 - "-" shift, and go to state 121 - - $default reduce using rule 12 (empty) - - empty go to state 122 - offset go to state 194 - number go to state 131 - sign go to state 124 - - -State 194 - - 31 twoRegCompInstr: twoRegCompOp regsym "," offset "," regsym "," offset • - - $default reduce using rule 31 (twoRegCompInstr) diff --git a/vm/asm.tab.c b/vm/asm.tab.c deleted file mode 100755 index 11784b9..0000000 --- a/vm/asm.tab.c +++ /dev/null @@ -1,2533 +0,0 @@ -/* A Bison parser, made by GNU Bison 3.8.2. */ - -/* Bison implementation for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, - Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, - especially those whose name start with YY_ or yy_. They are - private implementation details that can be changed or removed. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output, and Bison version. */ -#define YYBISON 30802 - -/* Bison version string. */ -#define YYBISON_VERSION "3.8.2" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 0 - -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - -/* "%code top" blocks. */ -#line 3 "asm.y" - -#include - -#line 72 "asm.tab.c" - - - - -# ifndef YY_CAST -# ifdef __cplusplus -# define YY_CAST(Type, Val) static_cast (Val) -# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) -# else -# define YY_CAST(Type, Val) ((Type) (Val)) -# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) -# endif -# endif -# ifndef YY_NULLPTR -# if defined __cplusplus -# if 201103L <= __cplusplus -# define YY_NULLPTR nullptr -# else -# define YY_NULLPTR 0 -# endif -# else -# define YY_NULLPTR ((void*)0) -# endif -# endif - -#include "asm.tab.h" -/* Symbol kind. */ -enum yysymbol_kind_t -{ - YYSYMBOL_YYEMPTY = -2, - YYSYMBOL_YYEOF = 0, /* "end of file" */ - YYSYMBOL_YYerror = 1, /* error */ - YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ - YYSYMBOL_eolsym = 3, /* eolsym */ - YYSYMBOL_identsym = 4, /* identsym */ - YYSYMBOL_unsignednumsym = 5, /* unsignednumsym */ - YYSYMBOL_plussym = 6, /* "+" */ - YYSYMBOL_minussym = 7, /* "-" */ - YYSYMBOL_commasym = 8, /* "," */ - YYSYMBOL_dottextsym = 9, /* ".text" */ - YYSYMBOL_dotdatasym = 10, /* ".data" */ - YYSYMBOL_dotstacksym = 11, /* ".stack" */ - YYSYMBOL_dotendsym = 12, /* ".end" */ - YYSYMBOL_colonsym = 13, /* ":" */ - YYSYMBOL_lbracketsym = 14, /* "[" */ - YYSYMBOL_rbracketsym = 15, /* "]" */ - YYSYMBOL_equalsym = 16, /* "=" */ - YYSYMBOL_noopsym = 17, /* "NOP" */ - YYSYMBOL_addopsym = 18, /* "ADD" */ - YYSYMBOL_subopsym = 19, /* "SUB" */ - YYSYMBOL_cpwopsym = 20, /* "CPW" */ - YYSYMBOL_cpropsym = 21, /* "CPR" */ - YYSYMBOL_andopsym = 22, /* "AND" */ - YYSYMBOL_boropsym = 23, /* "BOR" */ - YYSYMBOL_noropsym = 24, /* "NOR" */ - YYSYMBOL_xoropsym = 25, /* "XOR" */ - YYSYMBOL_lwropsym = 26, /* "LWR" */ - YYSYMBOL_swropsym = 27, /* "SWR" */ - YYSYMBOL_scaopsym = 28, /* "SCA" */ - YYSYMBOL_lwiopsym = 29, /* "LWI" */ - YYSYMBOL_negopsym = 30, /* "NEG" */ - YYSYMBOL_litopsym = 31, /* "LIT" */ - YYSYMBOL_ariopsym = 32, /* "ARI" */ - YYSYMBOL_sriopsym = 33, /* "SRI" */ - YYSYMBOL_mulopsym = 34, /* "MUL" */ - YYSYMBOL_divopsym = 35, /* "DIV" */ - YYSYMBOL_cfhiopsym = 36, /* "CFHI" */ - YYSYMBOL_cfloopsym = 37, /* "CFLO" */ - YYSYMBOL_sllopsym = 38, /* "SLL" */ - YYSYMBOL_srlopsym = 39, /* "SRL" */ - YYSYMBOL_jmpopsym = 40, /* "JMP" */ - YYSYMBOL_jrelopsym = 41, /* "JREL" */ - YYSYMBOL_addiopsym = 42, /* "ADDI" */ - YYSYMBOL_andiopsym = 43, /* "ANDI" */ - YYSYMBOL_boriopsym = 44, /* "BORI" */ - YYSYMBOL_noriopsym = 45, /* "NORI" */ - YYSYMBOL_xoriopsym = 46, /* "XORI" */ - YYSYMBOL_beqopsym = 47, /* "BEQ" */ - YYSYMBOL_bgezopsym = 48, /* "BGEZ" */ - YYSYMBOL_blezopsym = 49, /* "BLEZ" */ - YYSYMBOL_bgtzopsym = 50, /* "BGTZ" */ - YYSYMBOL_bltzopsym = 51, /* "BLTZ" */ - YYSYMBOL_bneopsym = 52, /* "BNE" */ - YYSYMBOL_csiopsym = 53, /* "CSI" */ - YYSYMBOL_jmpaopsym = 54, /* "JMPA" */ - YYSYMBOL_callopsym = 55, /* "CALL" */ - YYSYMBOL_rtnopsym = 56, /* "RTN" */ - YYSYMBOL_exitopsym = 57, /* "EXIT" */ - YYSYMBOL_pstropsym = 58, /* "PSTR" */ - YYSYMBOL_pintopsym = 59, /* "PINT" */ - YYSYMBOL_pchopsym = 60, /* "PCH" */ - YYSYMBOL_rchopsym = 61, /* "RCH" */ - YYSYMBOL_straopsym = 62, /* "STRA" */ - YYSYMBOL_notropsym = 63, /* "NOTR" */ - YYSYMBOL_regsym = 64, /* regsym */ - YYSYMBOL_wordsym = 65, /* "WORD" */ - YYSYMBOL_charsym = 66, /* "CHAR" */ - YYSYMBOL_stringsym = 67, /* "STRING" */ - YYSYMBOL_charliteralsym = 68, /* charliteralsym */ - YYSYMBOL_stringliteralsym = 69, /* stringliteralsym */ - YYSYMBOL_YYACCEPT = 70, /* $accept */ - YYSYMBOL_program = 71, /* program */ - YYSYMBOL_textSection = 72, /* textSection */ - YYSYMBOL_entryPoint = 73, /* entryPoint */ - YYSYMBOL_addr = 74, /* addr */ - YYSYMBOL_label = 75, /* label */ - YYSYMBOL_asmInstrs = 76, /* asmInstrs */ - YYSYMBOL_asmInstr = 77, /* asmInstr */ - YYSYMBOL_labelOpt = 78, /* labelOpt */ - YYSYMBOL_empty = 79, /* empty */ - YYSYMBOL_instr = 80, /* instr */ - YYSYMBOL_noArgInstr = 81, /* noArgInstr */ - YYSYMBOL_noArgOp = 82, /* noArgOp */ - YYSYMBOL_twoRegCompInstr = 83, /* twoRegCompInstr */ - YYSYMBOL_twoRegCompOp = 84, /* twoRegCompOp */ - YYSYMBOL_offset = 85, /* offset */ - YYSYMBOL_number = 86, /* number */ - YYSYMBOL_sign = 87, /* sign */ - YYSYMBOL_twoRegNoOffsetsInstr = 88, /* twoRegNoOffsetsInstr */ - YYSYMBOL_twoRegNoOffsetsOp = 89, /* twoRegNoOffsetsOp */ - YYSYMBOL_noTargetOffsetInstr = 90, /* noTargetOffsetInstr */ - YYSYMBOL_noTargetOffsetOp = 91, /* noTargetOffsetOp */ - YYSYMBOL_noSourceOffsetInstr = 92, /* noSourceOffsetInstr */ - YYSYMBOL_noSourceOffsetOp = 93, /* noSourceOffsetOp */ - YYSYMBOL_oneRegOffsetArgInstr = 94, /* oneRegOffsetArgInstr */ - YYSYMBOL_oneRegOffsetArgOp = 95, /* oneRegOffsetArgOp */ - YYSYMBOL_arg = 96, /* arg */ - YYSYMBOL_oneRegArgInstr = 97, /* oneRegArgInstr */ - YYSYMBOL_oneRegArgOp = 98, /* oneRegArgOp */ - YYSYMBOL_oneRegOffsetInstr = 99, /* oneRegOffsetInstr */ - YYSYMBOL_oneRegOffsetOp = 100, /* oneRegOffsetOp */ - YYSYMBOL_shiftInstr = 101, /* shiftInstr */ - YYSYMBOL_shiftOp = 102, /* shiftOp */ - YYSYMBOL_shift = 103, /* shift */ - YYSYMBOL_argOnlyInstr = 104, /* argOnlyInstr */ - YYSYMBOL_argOnlyOp = 105, /* argOnlyOp */ - YYSYMBOL_immedArithInstr = 106, /* immedArithInstr */ - YYSYMBOL_immedArithOp = 107, /* immedArithOp */ - YYSYMBOL_immed = 108, /* immed */ - YYSYMBOL_immedBoolInstr = 109, /* immedBoolInstr */ - YYSYMBOL_immedBoolOp = 110, /* immedBoolOp */ - YYSYMBOL_uimmed = 111, /* uimmed */ - YYSYMBOL_branchTestInstr = 112, /* branchTestInstr */ - YYSYMBOL_branchTestOp = 113, /* branchTestOp */ - YYSYMBOL_jumpInstr = 114, /* jumpInstr */ - YYSYMBOL_jumpOp = 115, /* jumpOp */ - YYSYMBOL_syscallInstr = 116, /* syscallInstr */ - YYSYMBOL_offsetOnlySyscall = 117, /* offsetOnlySyscall */ - YYSYMBOL_offsetOnlySyscallOp = 118, /* offsetOnlySyscallOp */ - YYSYMBOL_regOffsetSyscall = 119, /* regOffsetSyscall */ - YYSYMBOL_regOffsetSyscallOp = 120, /* regOffsetSyscallOp */ - YYSYMBOL_noArgSyscall = 121, /* noArgSyscall */ - YYSYMBOL_noArgSyscallOp = 122, /* noArgSyscallOp */ - YYSYMBOL_dataSection = 123, /* dataSection */ - YYSYMBOL_staticStartAddr = 124, /* staticStartAddr */ - YYSYMBOL_staticDecls = 125, /* staticDecls */ - YYSYMBOL_staticDecl = 126, /* staticDecl */ - YYSYMBOL_dataSize = 127, /* dataSize */ - YYSYMBOL_initializerOpt = 128, /* initializerOpt */ - YYSYMBOL_stackSection = 129, /* stackSection */ - YYSYMBOL_stackBottomAddr = 130 /* stackBottomAddr */ -}; -typedef enum yysymbol_kind_t yysymbol_kind_t; - - - -/* Unqualified %code blocks. */ -#line 160 "asm.y" - - /* extern declarations provided by the lexer */ -extern int yylex(void); - - /* extern void yyerror(char const *msg); */ - - /* The AST for the program, set by the semantic action for program. */ -ast_program_t progast; - - /* Set the program's ast to be t */ -extern void setProgAST(ast_program_t t); - -#line 253 "asm.tab.c" - -#ifdef short -# undef short -#endif - -/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure - and (if available) are included - so that the code can choose integer types of a good width. */ - -#ifndef __PTRDIFF_MAX__ -# include /* INFRINGES ON USER NAME SPACE */ -# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_STDINT_H -# endif -#endif - -/* Narrow types that promote to a signed type and that can represent a - signed or unsigned integer of at least N bits. In tables they can - save space and decrease cache pressure. Promoting to a signed type - helps avoid bugs in integer arithmetic. */ - -#ifdef __INT_LEAST8_MAX__ -typedef __INT_LEAST8_TYPE__ yytype_int8; -#elif defined YY_STDINT_H -typedef int_least8_t yytype_int8; -#else -typedef signed char yytype_int8; -#endif - -#ifdef __INT_LEAST16_MAX__ -typedef __INT_LEAST16_TYPE__ yytype_int16; -#elif defined YY_STDINT_H -typedef int_least16_t yytype_int16; -#else -typedef short yytype_int16; -#endif - -/* Work around bug in HP-UX 11.23, which defines these macros - incorrectly for preprocessor constants. This workaround can likely - be removed in 2023, as HPE has promised support for HP-UX 11.23 - (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of - . */ -#ifdef __hpux -# undef UINT_LEAST8_MAX -# undef UINT_LEAST16_MAX -# define UINT_LEAST8_MAX 255 -# define UINT_LEAST16_MAX 65535 -#endif - -#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ -typedef __UINT_LEAST8_TYPE__ yytype_uint8; -#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ - && UINT_LEAST8_MAX <= INT_MAX) -typedef uint_least8_t yytype_uint8; -#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX -typedef unsigned char yytype_uint8; -#else -typedef short yytype_uint8; -#endif - -#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ -typedef __UINT_LEAST16_TYPE__ yytype_uint16; -#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ - && UINT_LEAST16_MAX <= INT_MAX) -typedef uint_least16_t yytype_uint16; -#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX -typedef unsigned short yytype_uint16; -#else -typedef int yytype_uint16; -#endif - -#ifndef YYPTRDIFF_T -# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ -# define YYPTRDIFF_T __PTRDIFF_TYPE__ -# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ -# elif defined PTRDIFF_MAX -# ifndef ptrdiff_t -# include /* INFRINGES ON USER NAME SPACE */ -# endif -# define YYPTRDIFF_T ptrdiff_t -# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX -# else -# define YYPTRDIFF_T long -# define YYPTRDIFF_MAXIMUM LONG_MAX -# endif -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ -# include /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned -# endif -#endif - -#define YYSIZE_MAXIMUM \ - YY_CAST (YYPTRDIFF_T, \ - (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ - ? YYPTRDIFF_MAXIMUM \ - : YY_CAST (YYSIZE_T, -1))) - -#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) - - -/* Stored state numbers (used for stacks). */ -typedef yytype_uint8 yy_state_t; - -/* State numbers in computations. */ -typedef int yy_state_fast_t; - -#ifndef YY_ -# if defined YYENABLE_NLS && YYENABLE_NLS -# if ENABLE_NLS -# include /* INFRINGES ON USER NAME SPACE */ -# define YY_(Msgid) dgettext ("bison-runtime", Msgid) -# endif -# endif -# ifndef YY_ -# define YY_(Msgid) Msgid -# endif -#endif - - -#ifndef YY_ATTRIBUTE_PURE -# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) -# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) -# else -# define YY_ATTRIBUTE_PURE -# endif -#endif - -#ifndef YY_ATTRIBUTE_UNUSED -# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) -# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) -# else -# define YY_ATTRIBUTE_UNUSED -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YY_USE(E) ((void) (E)) -#else -# define YY_USE(E) /* empty */ -#endif - -/* Suppress an incorrect diagnostic about yylval being uninitialized. */ -#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__ -# if __GNUC__ * 100 + __GNUC_MINOR__ < 407 -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") -# else -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ - _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") -# endif -# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ - _Pragma ("GCC diagnostic pop") -#else -# define YY_INITIAL_VALUE(Value) Value -#endif -#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_END -#endif -#ifndef YY_INITIAL_VALUE -# define YY_INITIAL_VALUE(Value) /* Nothing. */ -#endif - -#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ -# define YY_IGNORE_USELESS_CAST_BEGIN \ - _Pragma ("GCC diagnostic push") \ - _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") -# define YY_IGNORE_USELESS_CAST_END \ - _Pragma ("GCC diagnostic pop") -#endif -#ifndef YY_IGNORE_USELESS_CAST_BEGIN -# define YY_IGNORE_USELESS_CAST_BEGIN -# define YY_IGNORE_USELESS_CAST_END -#endif - - -#define YY_ASSERT(E) ((void) (0 && (E))) - -#if 1 - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's 'empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined EXIT_SUCCESS \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include /* INFRINGES ON USER NAME SPACE */ -# ifndef EXIT_SUCCESS -# define EXIT_SUCCESS 0 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined EXIT_SUCCESS -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined EXIT_SUCCESS -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -# define YYCOPY_NEEDED 1 -#endif /* 1 */ - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ - && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yy_state_t yyss_alloc; - YYSTYPE yyvs_alloc; - YYLTYPE yyls_alloc; -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE) \ - + YYSIZEOF (YYLTYPE)) \ - + 2 * YYSTACK_GAP_MAXIMUM) - -# define YYCOPY_NEEDED 1 - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYPTRDIFF_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / YYSIZEOF (*yyptr); \ - } \ - while (0) - -#endif - -#if defined YYCOPY_NEEDED && YYCOPY_NEEDED -/* Copy COUNT objects from SRC to DST. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(Dst, Src, Count) \ - __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) -# else -# define YYCOPY(Dst, Src, Count) \ - do \ - { \ - YYPTRDIFF_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (Dst)[yyi] = (Src)[yyi]; \ - } \ - while (0) -# endif -# endif -#endif /* !YYCOPY_NEEDED */ - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 9 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 146 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 70 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 61 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 118 -/* YYNSTATES -- Number of states. */ -#define YYNSTATES 195 - -/* YYMAXUTOK -- Last valid token kind. */ -#define YYMAXUTOK 324 - - -/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM - as returned by yylex, with out-of-bounds checking. */ -#define YYTRANSLATE(YYX) \ - (0 <= (YYX) && (YYX) <= YYMAXUTOK \ - ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \ - : YYSYMBOL_YYUNDEF) - -/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM - as returned by yylex. */ -static const yytype_int8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69 -}; - -#if YYDEBUG -/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ -static const yytype_int16 yyrline[] = -{ - 0, 175, 175, 178, 182, 184, 185, 188, 191, 192, - 195, 197, 198, 201, 204, 204, 204, 205, 205, 205, - 206, 206, 206, 206, 207, 207, 207, 207, 208, 212, - 214, 214, 217, 225, 225, 225, 226, 226, 226, 226, - 226, 226, 226, 229, 236, 246, 246, 247, 251, 258, - 261, 268, 271, 278, 281, 290, 292, 300, 309, 309, - 312, 321, 321, 321, 321, 321, 321, 324, 333, 333, - 335, 343, 351, 354, 362, 364, 372, 380, 380, 380, - 380, 382, 390, 398, 398, 398, 398, 398, 398, 401, - 412, 412, 415, 415, 415, 417, 425, 428, 436, 436, - 436, 436, 439, 447, 447, 451, 455, 458, 459, 462, - 465, 466, 467, 472, 473, 475, 477, 481, 484 -}; -#endif - -/** Accessing symbol of state STATE. */ -#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State]) - -#if 1 -/* The user-facing name of the symbol whose (internal) number is - YYSYMBOL. No bounds checking. */ -static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; - -static const char * -yysymbol_name (yysymbol_kind_t yysymbol) -{ - static const char *const yy_sname[] = - { - "end of file", "error", "invalid token", "eolsym", "identsym", - "unsignednumsym", "+", "-", ",", ".text", ".data", ".stack", ".end", ":", - "[", "]", "=", "NOP", "ADD", "SUB", "CPW", "CPR", "AND", "BOR", "NOR", - "XOR", "LWR", "SWR", "SCA", "LWI", "NEG", "LIT", "ARI", "SRI", "MUL", - "DIV", "CFHI", "CFLO", "SLL", "SRL", "JMP", "JREL", "ADDI", "ANDI", - "BORI", "NORI", "XORI", "BEQ", "BGEZ", "BLEZ", "BGTZ", "BLTZ", "BNE", - "CSI", "JMPA", "CALL", "RTN", "EXIT", "PSTR", "PINT", "PCH", "RCH", - "STRA", "NOTR", "regsym", "WORD", "CHAR", "STRING", "charliteralsym", - "stringliteralsym", "$accept", "program", "textSection", "entryPoint", - "addr", "label", "asmInstrs", "asmInstr", "labelOpt", "empty", "instr", - "noArgInstr", "noArgOp", "twoRegCompInstr", "twoRegCompOp", "offset", - "number", "sign", "twoRegNoOffsetsInstr", "twoRegNoOffsetsOp", - "noTargetOffsetInstr", "noTargetOffsetOp", "noSourceOffsetInstr", - "noSourceOffsetOp", "oneRegOffsetArgInstr", "oneRegOffsetArgOp", "arg", - "oneRegArgInstr", "oneRegArgOp", "oneRegOffsetInstr", "oneRegOffsetOp", - "shiftInstr", "shiftOp", "shift", "argOnlyInstr", "argOnlyOp", - "immedArithInstr", "immedArithOp", "immed", "immedBoolInstr", - "immedBoolOp", "uimmed", "branchTestInstr", "branchTestOp", "jumpInstr", - "jumpOp", "syscallInstr", "offsetOnlySyscall", "offsetOnlySyscallOp", - "regOffsetSyscall", "regOffsetSyscallOp", "noArgSyscall", - "noArgSyscallOp", "dataSection", "staticStartAddr", "staticDecls", - "staticDecl", "dataSize", "initializerOpt", "stackSection", - "stackBottomAddr", YY_NULLPTR - }; - return yy_sname[yysymbol]; -} -#endif - -#define YYPACT_NINF (-140) - -#define yypact_value_is_default(Yyn) \ - ((Yyn) == YYPACT_NINF) - -#define YYTABLE_NINF (-4) - -#define yytable_value_is_error(Yyn) \ - 0 - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -static const yytype_int16 yypact[] = -{ - 10, 4, 5, 19, -140, -140, 26, -140, -140, -140, - 27, 20, 22, 6, -140, 71, -140, -140, -140, 29, - 24, -140, -140, -140, -140, -140, -140, -140, -140, -140, - -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, - -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, - -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, - -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, - 34, -140, -140, -140, -26, -140, -25, -140, -24, -140, - -23, -140, -22, -140, -20, -140, -19, -140, -18, -140, - 21, -140, -17, -140, -16, -140, -15, -140, 4, -140, - -140, 21, -140, -14, -140, -140, -140, -41, -140, -140, - -140, -140, 43, 44, 45, 47, 48, 49, 50, 51, - -140, -140, -140, -140, 55, -140, 53, 54, 59, -140, - -140, -140, 60, -140, -140, 56, -140, 65, 21, -1, - 7, 21, 21, 21, 21, 21, -140, 21, 21, 21, - 21, 67, 57, 66, -140, 68, 70, 72, -140, -140, - 73, 74, 76, 78, -140, 64, -4, -140, 132, 11, - 21, 75, 21, 131, 21, 133, 21, -140, -140, -140, - -140, -140, 129, -140, -140, -140, -140, -140, -140, -140, - -140, -140, -140, 21, -140 -}; - -/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE does not specify something else to do. Zero - means the default is an error. */ -static const yytype_int8 yydefact[] = -{ - 0, 0, 0, 0, 7, 6, 13, 4, 5, 1, - 0, 0, 0, 13, 8, 0, 12, 106, 13, 0, - 0, 11, 9, 30, 33, 34, 35, 49, 36, 37, - 38, 39, 51, 53, 40, 41, 42, 55, 58, 59, - 61, 62, 63, 64, 68, 69, 65, 72, 74, 77, - 78, 80, 79, 83, 84, 86, 85, 87, 88, 66, - 90, 91, 31, 96, 98, 99, 100, 101, 103, 104, - 0, 14, 29, 15, 0, 16, 0, 17, 0, 18, - 0, 19, 0, 20, 0, 21, 0, 22, 0, 23, - 13, 24, 0, 25, 0, 26, 0, 27, 0, 28, - 92, 13, 93, 0, 94, 102, 107, 105, 118, 117, - 2, 10, 0, 0, 0, 0, 0, 0, 0, 0, - 45, 46, 47, 56, 0, 71, 0, 0, 0, 89, - 95, 43, 0, 110, 111, 0, 108, 0, 13, 0, - 0, 13, 13, 13, 13, 13, 44, 13, 13, 13, - 13, 0, 13, 0, 48, 0, 0, 0, 57, 60, - 0, 0, 0, 0, 97, 0, 13, 116, 0, 0, - 13, 0, 13, 0, 13, 0, 13, 112, 114, 115, - 113, 109, 0, 50, 52, 54, 70, 67, 75, 73, - 81, 76, 82, 13, 32 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int16 yypgoto[] = -{ - -140, -140, -140, -140, 42, 0, -140, 128, -140, -6, - -140, -140, -140, -140, -140, -127, -89, -140, -140, -140, - -140, -140, -140, -140, -140, -140, -139, -140, -140, -140, - -140, -140, -140, -140, -140, -140, -140, -140, -34, -140, - -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, - -140, -140, -140, -140, -140, -140, -140, -140, -140, -140, - -140 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_uint8 yydefgoto[] = -{ - 0, 2, 3, 6, 7, 8, 13, 14, 15, 122, - 70, 71, 72, 73, 74, 130, 131, 124, 75, 76, - 77, 78, 79, 80, 81, 82, 125, 83, 84, 85, - 86, 87, 88, 187, 89, 90, 91, 92, 189, 93, - 94, 191, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 11, 18, 107, 136, 137, 168, 20, - 109 -}; - -/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule whose - number is the opposite. If YYTABLE_NINF, syntax error. */ -static const yytype_int16 yytable[] = -{ - 16, 123, 120, 121, 158, 9, 12, 16, 4, 5, - 4, 153, 106, 12, 156, 157, -3, 159, 160, 1, - 161, 162, 163, 164, 133, 134, 135, 120, 121, 10, - 4, 19, 17, 185, 108, 21, 110, 111, 112, 113, - 114, 115, 116, 183, 117, 118, 119, 126, 127, 128, - 132, 138, 139, 140, 123, 141, 142, 143, 144, 145, - 146, 147, 148, 154, 178, 179, 194, 149, 150, 152, - 151, 155, 165, 166, 169, 182, 170, 180, 171, 177, - 172, 173, 174, 123, 175, 188, 176, 188, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 181, 186, 193, 190, 184, - 129, 22, 192, 0, 0, 0, 167 -}; - -static const yytype_int16 yycheck[] = -{ - 6, 90, 6, 7, 143, 0, 6, 13, 4, 5, - 4, 138, 18, 13, 141, 142, 10, 144, 145, 9, - 147, 148, 149, 150, 65, 66, 67, 6, 7, 10, - 4, 11, 5, 172, 5, 13, 12, 3, 64, 64, - 64, 64, 64, 170, 64, 64, 64, 64, 64, 64, - 64, 8, 8, 8, 143, 8, 8, 8, 8, 8, - 5, 8, 8, 64, 68, 69, 193, 8, 8, 4, - 14, 64, 5, 16, 8, 64, 8, 166, 8, 15, - 8, 8, 8, 172, 8, 174, 8, 176, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 63, 3, 5, 8, 5, 64, - 98, 13, 176, -1, -1, -1, 152 -}; - -/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of - state STATE-NUM. */ -static const yytype_uint8 yystos[] = -{ - 0, 9, 71, 72, 4, 5, 73, 74, 75, 0, - 10, 123, 75, 76, 77, 78, 79, 5, 124, 11, - 129, 13, 77, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, - 80, 81, 82, 83, 84, 88, 89, 90, 91, 92, - 93, 94, 95, 97, 98, 99, 100, 101, 102, 104, - 105, 106, 107, 109, 110, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 122, 79, 125, 5, 130, - 12, 3, 64, 64, 64, 64, 64, 64, 64, 64, - 6, 7, 79, 86, 87, 96, 64, 64, 64, 74, - 85, 86, 64, 65, 66, 67, 126, 127, 8, 8, - 8, 8, 8, 8, 8, 8, 5, 8, 8, 8, - 8, 14, 4, 85, 64, 64, 85, 85, 96, 85, - 85, 85, 85, 85, 85, 5, 16, 79, 128, 8, - 8, 8, 8, 8, 8, 8, 8, 15, 68, 69, - 86, 3, 64, 85, 64, 96, 5, 103, 86, 108, - 5, 111, 108, 8, 85 -}; - -/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ -static const yytype_uint8 yyr1[] = -{ - 0, 70, 71, 72, 73, 74, 74, 75, 76, 76, - 77, 78, 78, 79, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, - 82, 82, 83, 84, 84, 84, 84, 84, 84, 84, - 84, 84, 84, 85, 86, 87, 87, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 98, - 99, 100, 100, 100, 100, 100, 100, 101, 102, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 110, 110, - 110, 111, 112, 113, 113, 113, 113, 113, 113, 114, - 115, 115, 116, 116, 116, 117, 118, 119, 120, 120, - 120, 120, 121, 122, 122, 123, 124, 125, 125, 126, - 127, 127, 127, 128, 128, 128, 128, 129, 130 -}; - -/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ -static const yytype_int8 yyr2[] = -{ - 0, 2, 4, 3, 1, 1, 1, 1, 1, 2, - 3, 2, 1, 0, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 1, 1, 1, 4, 1, - 6, 1, 6, 1, 6, 1, 1, 4, 1, 1, - 4, 1, 1, 1, 1, 1, 1, 6, 1, 1, - 1, 2, 1, 6, 1, 1, 6, 1, 1, 1, - 1, 1, 6, 1, 1, 1, 1, 1, 1, 2, - 1, 1, 1, 1, 1, 2, 1, 4, 1, 1, - 1, 1, 1, 1, 1, 3, 1, 1, 2, 4, - 1, 1, 4, 2, 2, 2, 1, 2, 1 -}; - - -enum { YYENOMEM = -2 }; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab -#define YYNOMEM goto yyexhaustedlab - - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ - do \ - if (yychar == YYEMPTY) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - YYPOPSTACK (yylen); \ - yystate = *yyssp; \ - YY_LAC_DISCARD ("YYBACKUP"); \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (file_name, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ - while (0) - -/* Backward compatibility with an undocumented macro. - Use YYerror or YYUNDEF. */ -#define YYERRCODE YYUNDEF - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (N) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (0) -#endif - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) - - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) - - -/* YYLOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -# ifndef YYLOCATION_PRINT - -# if defined YY_LOCATION_PRINT - - /* Temporary convenience wrapper in case some people defined the - undocumented and private YY_LOCATION_PRINT macros. */ -# define YYLOCATION_PRINT(File, Loc) YY_LOCATION_PRINT(File, *(Loc)) - -# elif defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL - -/* Print *YYLOCP on YYO. Private, do not rely on its existence. */ - -YY_ATTRIBUTE_UNUSED -static int -yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) -{ - int res = 0; - int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; - if (0 <= yylocp->first_line) - { - res += YYFPRINTF (yyo, "%d", yylocp->first_line); - if (0 <= yylocp->first_column) - res += YYFPRINTF (yyo, ".%d", yylocp->first_column); - } - if (0 <= yylocp->last_line) - { - if (yylocp->first_line < yylocp->last_line) - { - res += YYFPRINTF (yyo, "-%d", yylocp->last_line); - if (0 <= end_col) - res += YYFPRINTF (yyo, ".%d", end_col); - } - else if (0 <= end_col && yylocp->first_column < end_col) - res += YYFPRINTF (yyo, "-%d", end_col); - } - return res; -} - -# define YYLOCATION_PRINT yy_location_print_ - - /* Temporary convenience wrapper in case some people defined the - undocumented and private YY_LOCATION_PRINT macros. */ -# define YY_LOCATION_PRINT(File, Loc) YYLOCATION_PRINT(File, &(Loc)) - -# else - -# define YYLOCATION_PRINT(File, Loc) ((void) 0) - /* Temporary convenience wrapper in case some people defined the - undocumented and private YY_LOCATION_PRINT macros. */ -# define YY_LOCATION_PRINT YYLOCATION_PRINT - -# endif -# endif /* !defined YYLOCATION_PRINT */ - - -# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Kind, Value, Location, file_name); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (0) - - -/*-----------------------------------. -| Print this symbol's value on YYO. | -`-----------------------------------*/ - -static void -yy_symbol_value_print (FILE *yyo, - yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, char const *file_name) -{ - FILE *yyoutput = yyo; - YY_USE (yyoutput); - YY_USE (yylocationp); - YY_USE (file_name); - if (!yyvaluep) - return; - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YY_USE (yykind); - YY_IGNORE_MAYBE_UNINITIALIZED_END -} - - -/*---------------------------. -| Print this symbol on YYO. | -`---------------------------*/ - -static void -yy_symbol_print (FILE *yyo, - yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, char const *file_name) -{ - YYFPRINTF (yyo, "%s %s (", - yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind)); - - YYLOCATION_PRINT (yyo, yylocationp); - YYFPRINTF (yyo, ": "); - yy_symbol_value_print (yyo, yykind, yyvaluep, yylocationp, file_name); - YYFPRINTF (yyo, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -static void -yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (0) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -static void -yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, - int yyrule, char const *file_name) -{ - int yylno = yyrline[yyrule]; - int yynrhs = yyr2[yyrule]; - int yyi; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, - YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]), - &yyvsp[(yyi + 1) - (yynrhs)], - &(yylsp[(yyi + 1) - (yynrhs)]), file_name); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyssp, yyvsp, yylsp, Rule, file_name); \ -} while (0) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) ((void) 0) -# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - -/* Given a state stack such that *YYBOTTOM is its bottom, such that - *YYTOP is either its top or is YYTOP_EMPTY to indicate an empty - stack, and such that *YYCAPACITY is the maximum number of elements it - can hold without a reallocation, make sure there is enough room to - store YYADD more elements. If not, allocate a new stack using - YYSTACK_ALLOC, copy the existing elements, and adjust *YYBOTTOM, - *YYTOP, and *YYCAPACITY to reflect the new capacity and memory - location. If *YYBOTTOM != YYBOTTOM_NO_FREE, then free the old stack - using YYSTACK_FREE. Return 0 if successful or if no reallocation is - required. Return YYENOMEM if memory is exhausted. */ -static int -yy_lac_stack_realloc (YYPTRDIFF_T *yycapacity, YYPTRDIFF_T yyadd, -#if YYDEBUG - char const *yydebug_prefix, - char const *yydebug_suffix, -#endif - yy_state_t **yybottom, - yy_state_t *yybottom_no_free, - yy_state_t **yytop, yy_state_t *yytop_empty) -{ - YYPTRDIFF_T yysize_old = - *yytop == yytop_empty ? 0 : *yytop - *yybottom + 1; - YYPTRDIFF_T yysize_new = yysize_old + yyadd; - if (*yycapacity < yysize_new) - { - YYPTRDIFF_T yyalloc = 2 * yysize_new; - yy_state_t *yybottom_new; - /* Use YYMAXDEPTH for maximum stack size given that the stack - should never need to grow larger than the main state stack - needs to grow without LAC. */ - if (YYMAXDEPTH < yysize_new) - { - YYDPRINTF ((stderr, "%smax size exceeded%s", yydebug_prefix, - yydebug_suffix)); - return YYENOMEM; - } - if (YYMAXDEPTH < yyalloc) - yyalloc = YYMAXDEPTH; - yybottom_new = - YY_CAST (yy_state_t *, - YYSTACK_ALLOC (YY_CAST (YYSIZE_T, - yyalloc * YYSIZEOF (*yybottom_new)))); - if (!yybottom_new) - { - YYDPRINTF ((stderr, "%srealloc failed%s", yydebug_prefix, - yydebug_suffix)); - return YYENOMEM; - } - if (*yytop != yytop_empty) - { - YYCOPY (yybottom_new, *yybottom, yysize_old); - *yytop = yybottom_new + (yysize_old - 1); - } - if (*yybottom != yybottom_no_free) - YYSTACK_FREE (*yybottom); - *yybottom = yybottom_new; - *yycapacity = yyalloc; - } - return 0; -} - -/* Establish the initial context for the current lookahead if no initial - context is currently established. - - We define a context as a snapshot of the parser stacks. We define - the initial context for a lookahead as the context in which the - parser initially examines that lookahead in order to select a - syntactic action. Thus, if the lookahead eventually proves - syntactically unacceptable (possibly in a later context reached via a - series of reductions), the initial context can be used to determine - the exact set of tokens that would be syntactically acceptable in the - lookahead's place. Moreover, it is the context after which any - further semantic actions would be erroneous because they would be - determined by a syntactically unacceptable token. - - YY_LAC_ESTABLISH should be invoked when a reduction is about to be - performed in an inconsistent state (which, for the purposes of LAC, - includes consistent states that don't know they're consistent because - their default reductions have been disabled). Iff there is a - lookahead token, it should also be invoked before reporting a syntax - error. This latter case is for the sake of the debugging output. - - For parse.lac=full, the implementation of YY_LAC_ESTABLISH is as - follows. If no initial context is currently established for the - current lookahead, then check if that lookahead can eventually be - shifted if syntactic actions continue from the current context. - Report a syntax error if it cannot. */ -#define YY_LAC_ESTABLISH \ -do { \ - if (!yy_lac_established) \ - { \ - YYDPRINTF ((stderr, \ - "LAC: initial context established for %s\n", \ - yysymbol_name (yytoken))); \ - yy_lac_established = 1; \ - switch (yy_lac (yyesa, &yyes, &yyes_capacity, yyssp, yytoken)) \ - { \ - case YYENOMEM: \ - YYNOMEM; \ - case 1: \ - goto yyerrlab; \ - } \ - } \ -} while (0) - -/* Discard any previous initial lookahead context because of Event, - which may be a lookahead change or an invalidation of the currently - established initial context for the current lookahead. - - The most common example of a lookahead change is a shift. An example - of both cases is syntax error recovery. That is, a syntax error - occurs when the lookahead is syntactically erroneous for the - currently established initial context, so error recovery manipulates - the parser stacks to try to find a new initial context in which the - current lookahead is syntactically acceptable. If it fails to find - such a context, it discards the lookahead. */ -#if YYDEBUG -# define YY_LAC_DISCARD(Event) \ -do { \ - if (yy_lac_established) \ - { \ - YYDPRINTF ((stderr, "LAC: initial context discarded due to " \ - Event "\n")); \ - yy_lac_established = 0; \ - } \ -} while (0) -#else -# define YY_LAC_DISCARD(Event) yy_lac_established = 0 -#endif - -/* Given the stack whose top is *YYSSP, return 0 iff YYTOKEN can - eventually (after perhaps some reductions) be shifted, return 1 if - not, or return YYENOMEM if memory is exhausted. As preconditions and - postconditions: *YYES_CAPACITY is the allocated size of the array to - which *YYES points, and either *YYES = YYESA or *YYES points to an - array allocated with YYSTACK_ALLOC. yy_lac may overwrite the - contents of either array, alter *YYES and *YYES_CAPACITY, and free - any old *YYES other than YYESA. */ -static int -yy_lac (yy_state_t *yyesa, yy_state_t **yyes, - YYPTRDIFF_T *yyes_capacity, yy_state_t *yyssp, yysymbol_kind_t yytoken) -{ - yy_state_t *yyes_prev = yyssp; - yy_state_t *yyesp = yyes_prev; - /* Reduce until we encounter a shift and thereby accept the token. */ - YYDPRINTF ((stderr, "LAC: checking lookahead %s:", yysymbol_name (yytoken))); - if (yytoken == YYSYMBOL_YYUNDEF) - { - YYDPRINTF ((stderr, " Always Err\n")); - return 1; - } - while (1) - { - int yyrule = yypact[+*yyesp]; - if (yypact_value_is_default (yyrule) - || (yyrule += yytoken) < 0 || YYLAST < yyrule - || yycheck[yyrule] != yytoken) - { - /* Use the default action. */ - yyrule = yydefact[+*yyesp]; - if (yyrule == 0) - { - YYDPRINTF ((stderr, " Err\n")); - return 1; - } - } - else - { - /* Use the action from yytable. */ - yyrule = yytable[yyrule]; - if (yytable_value_is_error (yyrule)) - { - YYDPRINTF ((stderr, " Err\n")); - return 1; - } - if (0 < yyrule) - { - YYDPRINTF ((stderr, " S%d\n", yyrule)); - return 0; - } - yyrule = -yyrule; - } - /* By now we know we have to simulate a reduce. */ - YYDPRINTF ((stderr, " R%d", yyrule - 1)); - { - /* Pop the corresponding number of values from the stack. */ - YYPTRDIFF_T yylen = yyr2[yyrule]; - /* First pop from the LAC stack as many tokens as possible. */ - if (yyesp != yyes_prev) - { - YYPTRDIFF_T yysize = yyesp - *yyes + 1; - if (yylen < yysize) - { - yyesp -= yylen; - yylen = 0; - } - else - { - yyesp = yyes_prev; - yylen -= yysize; - } - } - /* Only afterwards look at the main stack. */ - if (yylen) - yyesp = yyes_prev -= yylen; - } - /* Push the resulting state of the reduction. */ - { - yy_state_fast_t yystate; - { - const int yylhs = yyr1[yyrule] - YYNTOKENS; - const int yyi = yypgoto[yylhs] + *yyesp; - yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyesp - ? yytable[yyi] - : yydefgoto[yylhs]); - } - if (yyesp == yyes_prev) - { - yyesp = *yyes; - YY_IGNORE_USELESS_CAST_BEGIN - *yyesp = YY_CAST (yy_state_t, yystate); - YY_IGNORE_USELESS_CAST_END - } - else - { - if (yy_lac_stack_realloc (yyes_capacity, 1, -#if YYDEBUG - " (", ")", -#endif - yyes, yyesa, &yyesp, yyes_prev)) - { - YYDPRINTF ((stderr, "\n")); - return YYENOMEM; - } - YY_IGNORE_USELESS_CAST_BEGIN - *++yyesp = YY_CAST (yy_state_t, yystate); - YY_IGNORE_USELESS_CAST_END - } - YYDPRINTF ((stderr, " G%d", yystate)); - } - } -} - -/* Context of a parse error. */ -typedef struct -{ - yy_state_t *yyssp; - yy_state_t *yyesa; - yy_state_t **yyes; - YYPTRDIFF_T *yyes_capacity; - yysymbol_kind_t yytoken; - YYLTYPE *yylloc; -} yypcontext_t; - -/* Put in YYARG at most YYARGN of the expected tokens given the - current YYCTX, and return the number of tokens stored in YYARG. If - YYARG is null, return the number of expected tokens (guaranteed to - be less than YYNTOKENS). Return YYENOMEM on memory exhaustion. - Return 0 if there are more than YYARGN expected tokens, yet fill - YYARG up to YYARGN. */ -static int -yypcontext_expected_tokens (const yypcontext_t *yyctx, - yysymbol_kind_t yyarg[], int yyargn) -{ - /* Actual size of YYARG. */ - int yycount = 0; - - int yyx; - for (yyx = 0; yyx < YYNTOKENS; ++yyx) - { - yysymbol_kind_t yysym = YY_CAST (yysymbol_kind_t, yyx); - if (yysym != YYSYMBOL_YYerror && yysym != YYSYMBOL_YYUNDEF) - switch (yy_lac (yyctx->yyesa, yyctx->yyes, yyctx->yyes_capacity, yyctx->yyssp, yysym)) - { - case YYENOMEM: - return YYENOMEM; - case 1: - continue; - default: - if (!yyarg) - ++yycount; - else if (yycount == yyargn) - return 0; - else - yyarg[yycount++] = yysym; - } - } - if (yyarg && yycount == 0 && 0 < yyargn) - yyarg[0] = YYSYMBOL_YYEMPTY; - return yycount; -} - - - - -#ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S))) -# else -/* Return the length of YYSTR. */ -static YYPTRDIFF_T -yystrlen (const char *yystr) -{ - YYPTRDIFF_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -#endif - -#ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -static char * -yystpcpy (char *yydest, const char *yysrc) -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -#endif - - - -static int -yy_syntax_error_arguments (const yypcontext_t *yyctx, - yysymbol_kind_t yyarg[], int yyargn) -{ - /* Actual size of YYARG. */ - int yycount = 0; - /* There are many possibilities here to consider: - - If this state is a consistent state with a default action, then - the only way this function was invoked is if the default action - is an error action. In that case, don't check for expected - tokens because there are none. - - The only way there can be no lookahead present (in yychar) is if - this state is a consistent state with a default action. Thus, - detecting the absence of a lookahead is sufficient to determine - that there is no unexpected or expected token to report. In that - case, just report a simple "syntax error". - - Don't assume there isn't a lookahead just because this state is a - consistent state with a default action. There might have been a - previous inconsistent state, consistent state with a non-default - action, or user semantic action that manipulated yychar. - In the first two cases, it might appear that the current syntax - error should have been detected in the previous state when yy_lac - was invoked. However, at that time, there might have been a - different syntax error that discarded a different initial context - during error recovery, leaving behind the current lookahead. - */ - if (yyctx->yytoken != YYSYMBOL_YYEMPTY) - { - int yyn; - YYDPRINTF ((stderr, "Constructing syntax error message\n")); - if (yyarg) - yyarg[yycount] = yyctx->yytoken; - ++yycount; - yyn = yypcontext_expected_tokens (yyctx, - yyarg ? yyarg + 1 : yyarg, yyargn - 1); - if (yyn == YYENOMEM) - return YYENOMEM; - else if (yyn == 0) - YYDPRINTF ((stderr, "No expected tokens.\n")); - else - yycount += yyn; - } - return yycount; -} - -/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message - about the unexpected token YYTOKEN for the state stack whose top is - YYSSP. In order to see if a particular token T is a - valid looakhead, invoke yy_lac (YYESA, YYES, YYES_CAPACITY, YYSSP, T). - - Return 0 if *YYMSG was successfully written. Return -1 if *YYMSG is - not large enough to hold the message. In that case, also set - *YYMSG_ALLOC to the required number of bytes. Return YYENOMEM if the - required number of bytes is too large to store or if - yy_lac returned YYENOMEM. */ -static int -yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, - const yypcontext_t *yyctx) -{ - enum { YYARGS_MAX = 5 }; - /* Internationalized format string. */ - const char *yyformat = YY_NULLPTR; - /* Arguments of yyformat: reported tokens (one for the "unexpected", - one per "expected"). */ - yysymbol_kind_t yyarg[YYARGS_MAX]; - /* Cumulated lengths of YYARG. */ - YYPTRDIFF_T yysize = 0; - - /* Actual size of YYARG. */ - int yycount = yy_syntax_error_arguments (yyctx, yyarg, YYARGS_MAX); - if (yycount == YYENOMEM) - return YYENOMEM; - - switch (yycount) - { -#define YYCASE_(N, S) \ - case N: \ - yyformat = S; \ - break - default: /* Avoid compiler warnings. */ - YYCASE_(0, YY_("syntax error")); - YYCASE_(1, YY_("syntax error, unexpected %s")); - YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); - YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); - YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); - YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); -#undef YYCASE_ - } - - /* Compute error message size. Don't count the "%s"s, but reserve - room for the terminator. */ - yysize = yystrlen (yyformat) - 2 * yycount + 1; - { - int yyi; - for (yyi = 0; yyi < yycount; ++yyi) - { - YYPTRDIFF_T yysize1 - = yysize + yystrlen (yysymbol_name (yyarg[yyi])); - if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) - yysize = yysize1; - else - return YYENOMEM; - } - } - - if (*yymsg_alloc < yysize) - { - *yymsg_alloc = 2 * yysize; - if (! (yysize <= *yymsg_alloc - && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) - *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; - return -1; - } - - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - { - char *yyp = *yymsg; - int yyi = 0; - while ((*yyp = *yyformat) != '\0') - if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) - { - yyp = yystpcpy (yyp, yysymbol_name (yyarg[yyi++])); - yyformat += 2; - } - else - { - ++yyp; - ++yyformat; - } - } - return 0; -} - - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -static void -yydestruct (const char *yymsg, - yysymbol_kind_t yykind, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, char const *file_name) -{ - YY_USE (yyvaluep); - YY_USE (yylocationp); - YY_USE (file_name); - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YY_USE (yykind); - YY_IGNORE_MAYBE_UNINITIALIZED_END -} - - -/* Lookahead token kind. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; -/* Location data for the lookahead symbol. */ -YYLTYPE yylloc -# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL - = { 1, 1, 1, 1 } -# endif -; -/* Number of syntax errors so far. */ -int yynerrs; - - - - -/*----------. -| yyparse. | -`----------*/ - -int -yyparse (char const *file_name) -{ - yy_state_fast_t yystate = 0; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus = 0; - - /* Refer to the stacks through separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* Their size. */ - YYPTRDIFF_T yystacksize = YYINITDEPTH; - - /* The state stack: array, bottom, top. */ - yy_state_t yyssa[YYINITDEPTH]; - yy_state_t *yyss = yyssa; - yy_state_t *yyssp = yyss; - - /* The semantic value stack: array, bottom, top. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp = yyvs; - - /* The location stack: array, bottom, top. */ - YYLTYPE yylsa[YYINITDEPTH]; - YYLTYPE *yyls = yylsa; - YYLTYPE *yylsp = yyls; - - yy_state_t yyesa[20]; - yy_state_t *yyes = yyesa; - YYPTRDIFF_T yyes_capacity = 20 < YYMAXDEPTH ? 20 : YYMAXDEPTH; - - /* Whether LAC context is established. A Boolean. */ - int yy_lac_established = 0; - int yyn; - /* The return value of yyparse. */ - int yyresult; - /* Lookahead symbol kind. */ - yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - YYLTYPE yyloc; - - /* The locations where the error started and ended. */ - YYLTYPE yyerror_range[3]; - - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf; - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yychar = YYEMPTY; /* Cause a token to be read. */ - - yylsp[0] = yylloc; - goto yysetstate; - - -/*------------------------------------------------------------. -| yynewstate -- push a new state, which is found in yystate. | -`------------------------------------------------------------*/ -yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - -/*--------------------------------------------------------------------. -| yysetstate -- set current state (the top of the stack) to yystate. | -`--------------------------------------------------------------------*/ -yysetstate: - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - YY_ASSERT (0 <= yystate && yystate < YYNSTATES); - YY_IGNORE_USELESS_CAST_BEGIN - *yyssp = YY_CAST (yy_state_t, yystate); - YY_IGNORE_USELESS_CAST_END - YY_STACK_PRINT (yyss, yyssp); - - if (yyss + yystacksize - 1 <= yyssp) -#if !defined yyoverflow && !defined YYSTACK_RELOCATE - YYNOMEM; -#else - { - /* Get the current used size of the three stacks, in elements. */ - YYPTRDIFF_T yysize = yyssp - yyss + 1; - -# if defined yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - yy_state_t *yyss1 = yyss; - YYSTYPE *yyvs1 = yyvs; - YYLTYPE *yyls1 = yyls; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * YYSIZEOF (*yyssp), - &yyvs1, yysize * YYSIZEOF (*yyvsp), - &yyls1, yysize * YYSIZEOF (*yylsp), - &yystacksize); - yyss = yyss1; - yyvs = yyvs1; - yyls = yyls1; - } -# else /* defined YYSTACK_RELOCATE */ - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - YYNOMEM; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yy_state_t *yyss1 = yyss; - union yyalloc *yyptr = - YY_CAST (union yyalloc *, - YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); - if (! yyptr) - YYNOMEM; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); - YYSTACK_RELOCATE (yyls_alloc, yyls); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - yylsp = yyls + yysize - 1; - - YY_IGNORE_USELESS_CAST_BEGIN - YYDPRINTF ((stderr, "Stack size increased to %ld\n", - YY_CAST (long, yystacksize))); - YY_IGNORE_USELESS_CAST_END - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } -#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ - - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yypact_value_is_default (yyn)) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token\n")); - yychar = yylex (); - } - - if (yychar <= YYEOF) - { - yychar = YYEOF; - yytoken = YYSYMBOL_YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else if (yychar == YYerror) - { - /* The scanner already issued an error message, process directly - to error recovery. But do not keep the error token as - lookahead, it is too special and may lead us to an endless - loop in error recovery. */ - yychar = YYUNDEF; - yytoken = YYSYMBOL_YYerror; - yyerror_range[1] = yylloc; - goto yyerrlab1; - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - { - YY_LAC_ESTABLISH; - goto yydefault; - } - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yytable_value_is_error (yyn)) - goto yyerrlab; - yyn = -yyn; - YY_LAC_ESTABLISH; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - yystate = yyn; - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - *++yylsp = yylloc; - - /* Discard the shifted token. */ - yychar = YYEMPTY; - YY_LAC_DISCARD ("shift"); - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - '$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - /* Default location. */ - YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); - yyerror_range[1] = yyloc; - YY_REDUCE_PRINT (yyn); - { - int yychar_backup = yychar; - switch (yyn) - { - case 2: /* program: textSection dataSection stackSection ".end" */ -#line 176 "asm.y" - { setProgAST(ast_program((yyvsp[-3].text_section), (yyvsp[-2].data_section), (yyvsp[-1].stack_section))); } -#line 1925 "asm.tab.c" - break; - - case 3: /* textSection: ".text" entryPoint asmInstrs */ -#line 179 "asm.y" - { (yyval.text_section) = ast_text_section((yyvsp[-2].token),(yyvsp[-1].addr),(yyvsp[0].asm_instrs)); } -#line 1931 "asm.tab.c" - break; - - case 5: /* addr: label */ -#line 184 "asm.y" - { (yyval.addr) = ast_addr_label((yyvsp[0].ident)); } -#line 1937 "asm.tab.c" - break; - - case 6: /* addr: unsignednumsym */ -#line 185 "asm.y" - { (yyval.addr) = ast_entry_addr((yyvsp[0].unsignednum)); } -#line 1943 "asm.tab.c" - break; - - case 8: /* asmInstrs: asmInstr */ -#line 191 "asm.y" - { (yyval.asm_instrs) = ast_asm_instrs_singleton((yyvsp[0].asm_instr)); } -#line 1949 "asm.tab.c" - break; - - case 9: /* asmInstrs: asmInstrs asmInstr */ -#line 192 "asm.y" - { (yyval.asm_instrs) = ast_asm_instrs_add((yyvsp[-1].asm_instrs),(yyvsp[0].asm_instr)); } -#line 1955 "asm.tab.c" - break; - - case 10: /* asmInstr: labelOpt instr eolsym */ -#line 195 "asm.y" - { (yyval.asm_instr) = ast_asm_instr((yyvsp[-2].label_opt),(yyvsp[-1].instr)); } -#line 1961 "asm.tab.c" - break; - - case 11: /* labelOpt: label ":" */ -#line 197 "asm.y" - { (yyval.label_opt) = ast_label_opt_label((yyvsp[-1].ident)); } -#line 1967 "asm.tab.c" - break; - - case 12: /* labelOpt: empty */ -#line 198 "asm.y" - { (yyval.label_opt) = ast_label_opt_empty((yyvsp[0].empty)); } -#line 1973 "asm.tab.c" - break; - - case 13: /* empty: %empty */ -#line 201 "asm.y" - { (yyval.empty) = ast_empty(lexer_filename(), lexer_line()); } -#line 1979 "asm.tab.c" - break; - - case 29: /* noArgInstr: noArgOp */ -#line 212 "asm.y" - { (yyval.instr) = ast_0arg_instr((yyvsp[0].token)); } -#line 1985 "asm.tab.c" - break; - - case 32: /* twoRegCompInstr: twoRegCompOp regsym "," offset "," regsym "," offset */ -#line 218 "asm.y" - { - (yyval.instr) = ast_2reg_instr((yyvsp[-7].token), (yyvsp[-6].reg).number, (yyvsp[-4].number).value, - (yyvsp[-2].reg).number, (yyvsp[0].number).value, - lexer_token2func((yyvsp[-7].token).toknum)); - } -#line 1995 "asm.tab.c" - break; - - case 43: /* offset: number */ -#line 230 "asm.y" - { - machine_types_check_fits_in_offset((yyvsp[0].number).value); - (yyval.number) = (yyvsp[0].number); - } -#line 2004 "asm.tab.c" - break; - - case 44: /* number: sign unsignednumsym */ -#line 237 "asm.y" - { - word_type val = (yyvsp[0].unsignednum).value; - if ((yyvsp[-1].token).toknum == minussym) { - val = - val; - } - (yyval.number) = ast_number((yyvsp[-1].token), val); - } -#line 2016 "asm.tab.c" - break; - - case 47: /* sign: empty */ -#line 247 "asm.y" - { (yyval.token) = ast_token(lexer_filename(), lexer_line(), plussym); } -#line 2022 "asm.tab.c" - break; - - case 48: /* twoRegNoOffsetsInstr: twoRegNoOffsetsOp regsym "," regsym */ -#line 252 "asm.y" - { - (yyval.instr) = ast_2reg_instr((yyvsp[-3].token), (yyvsp[-2].reg).number, 0, (yyvsp[0].reg).number, 0, - lexer_token2func((yyvsp[-3].token).toknum)); - } -#line 2031 "asm.tab.c" - break; - - case 50: /* noTargetOffsetInstr: noTargetOffsetOp regsym "," regsym "," offset */ -#line 262 "asm.y" - { - (yyval.instr) = ast_2reg_instr((yyvsp[-5].token), (yyvsp[-4].reg).number, 0, (yyvsp[-2].reg).number, (yyvsp[0].number).value, - lexer_token2func((yyvsp[-5].token).toknum)); - } -#line 2040 "asm.tab.c" - break; - - case 52: /* noSourceOffsetInstr: noSourceOffsetOp regsym "," offset "," regsym */ -#line 272 "asm.y" - { - (yyval.instr) = ast_2reg_instr((yyvsp[-5].token), (yyvsp[-4].reg).number, (yyvsp[-2].number).value, (yyvsp[0].reg).number, 0, - lexer_token2func((yyvsp[-5].token).toknum)); - } -#line 2049 "asm.tab.c" - break; - - case 54: /* oneRegOffsetArgInstr: oneRegOffsetArgOp regsym "," offset "," arg */ -#line 282 "asm.y" - { - (yyval.instr) = ast_1reg_instr((yyvsp[-5].token), other_comp_instr_type, - 1, (yyvsp[-4].reg).number, (yyvsp[-2].number).value, - lexer_token2func((yyvsp[-5].token).toknum), - ast_immed_number((yyvsp[0].number).value)); - } -#line 2060 "asm.tab.c" - break; - - case 56: /* arg: number */ -#line 293 "asm.y" - { /* the number is signed */ - machine_types_check_fits_in_arg((yyvsp[0].number).value); - (yyval.number) = (yyvsp[0].number); - } -#line 2069 "asm.tab.c" - break; - - case 57: /* oneRegArgInstr: oneRegArgOp regsym "," arg */ -#line 301 "asm.y" - { - (yyval.instr) = ast_1reg_instr((yyvsp[-3].token), other_comp_instr_type, - 1, (yyvsp[-2].reg).number, 0, - lexer_token2func((yyvsp[-3].token).toknum), - ast_immed_number((yyvsp[0].number).value)); - } -#line 2080 "asm.tab.c" - break; - - case 60: /* oneRegOffsetInstr: oneRegOffsetOp regsym "," offset */ -#line 313 "asm.y" - { - (yyval.instr) = ast_1reg_instr((yyvsp[-3].token), other_comp_instr_type, - 1, (yyvsp[-2].reg).number, (yyvsp[0].number).value, - lexer_token2func((yyvsp[-3].token).toknum), - ast_immed_none()); - } -#line 2091 "asm.tab.c" - break; - - case 67: /* shiftInstr: shiftOp regsym "," offset "," shift */ -#line 325 "asm.y" - { - (yyval.instr) = ast_1reg_instr((yyvsp[-5].token), other_comp_instr_type, - 1, (yyvsp[-4].reg).number, (yyvsp[-2].number).value, - lexer_token2func((yyvsp[-5].token).toknum), - (yyvsp[0].immed)); - } -#line 2102 "asm.tab.c" - break; - - case 70: /* shift: unsignednumsym */ -#line 336 "asm.y" - { - machine_types_check_fits_in_shift((yyvsp[0].unsignednum).value); - (yyval.immed) = ast_immed_unsigned((yyvsp[0].unsignednum).value); - } -#line 2111 "asm.tab.c" - break; - - case 71: /* argOnlyInstr: argOnlyOp arg */ -#line 344 "asm.y" - { - (yyval.instr) = ast_1reg_instr((yyvsp[-1].token), other_comp_instr_type, - 0, 0, 0, lexer_token2func((yyvsp[-1].token).toknum), - ast_immed_number((yyvsp[0].number).value)); - } -#line 2121 "asm.tab.c" - break; - - case 73: /* immedArithInstr: immedArithOp regsym "," offset "," immed */ -#line 355 "asm.y" - { - (yyval.instr) = ast_1reg_instr((yyvsp[-5].token), immed_instr_type, - 1, (yyvsp[-4].reg).number, (yyvsp[-2].number).value, - 0, (yyvsp[0].immed)); - } -#line 2131 "asm.tab.c" - break; - - case 75: /* immed: number */ -#line 365 "asm.y" - { - machine_types_check_fits_in_immed((yyvsp[0].number).value); - (yyval.immed) = ast_immed_number((yyvsp[0].number).value); - } -#line 2140 "asm.tab.c" - break; - - case 76: /* immedBoolInstr: immedBoolOp regsym "," offset "," uimmed */ -#line 373 "asm.y" - { - (yyval.instr) = ast_1reg_instr((yyvsp[-5].token), immed_instr_type, - 1, (yyvsp[-4].reg).number, (yyvsp[-2].number).value, - 0, (yyvsp[0].immed)); - } -#line 2150 "asm.tab.c" - break; - - case 81: /* uimmed: unsignednumsym */ -#line 383 "asm.y" - { - machine_types_check_fits_in_uimmed((yyvsp[0].unsignednum).value); - (yyval.immed) = ast_immed_unsigned((yyvsp[0].unsignednum).value); - } -#line 2159 "asm.tab.c" - break; - - case 82: /* branchTestInstr: branchTestOp regsym "," offset "," immed */ -#line 391 "asm.y" - { - (yyval.instr) = ast_1reg_instr((yyvsp[-5].token), immed_instr_type, - 1, (yyvsp[-4].reg).number, (yyvsp[-2].number).value, - 0, (yyvsp[0].immed)); - } -#line 2169 "asm.tab.c" - break; - - case 89: /* jumpInstr: jumpOp addr */ -#line 402 "asm.y" - { - if ((yyvsp[0].addr).address_defined) { - machine_types_check_fits_in_addr((yyvsp[0].addr).addr); - } - (yyval.instr) = ast_1reg_instr((yyvsp[-1].token), jump_instr_type, - 0, 0, 0, - 0, ast_immed_addr((yyvsp[0].addr))); - } -#line 2182 "asm.tab.c" - break; - - case 95: /* offsetOnlySyscall: offsetOnlySyscallOp offset */ -#line 418 "asm.y" - { - (yyval.instr) = ast_1reg_instr((yyvsp[-1].token), syscall_instr_type, - 1, 0, (yyvsp[0].number).value, - SYS_F, ast_syscall_code_for((yyvsp[-1].token).toknum)); - } -#line 2192 "asm.tab.c" - break; - - case 97: /* regOffsetSyscall: regOffsetSyscallOp regsym "," offset */ -#line 429 "asm.y" - { - (yyval.instr) = ast_1reg_instr((yyvsp[-3].token), syscall_instr_type, - 1, (yyvsp[-2].reg).number, (yyvsp[0].number).value, - SYS_F, ast_syscall_code_for((yyvsp[-3].token).toknum)); - } -#line 2202 "asm.tab.c" - break; - - case 102: /* noArgSyscall: noArgSyscallOp */ -#line 440 "asm.y" - { - (yyval.instr) = ast_1reg_instr((yyvsp[0].token), syscall_instr_type, - 0, 0, 0, - SYS_F, ast_syscall_code_for((yyvsp[0].token).toknum)); - } -#line 2212 "asm.tab.c" - break; - - case 105: /* dataSection: ".data" staticStartAddr staticDecls */ -#line 452 "asm.y" - { (yyval.data_section) = ast_data_section((yyvsp[-2].token), (yyvsp[-1].unsignednum).value, (yyvsp[0].static_decls)); } -#line 2218 "asm.tab.c" - break; - - case 107: /* staticDecls: empty */ -#line 458 "asm.y" - { (yyval.static_decls) = ast_static_decls_empty((yyvsp[0].empty)); } -#line 2224 "asm.tab.c" - break; - - case 108: /* staticDecls: staticDecls staticDecl */ -#line 459 "asm.y" - { (yyval.static_decls) = ast_static_decls_add((yyvsp[-1].static_decls),(yyvsp[0].static_decl)); } -#line 2230 "asm.tab.c" - break; - - case 109: /* staticDecl: dataSize identsym initializerOpt eolsym */ -#line 463 "asm.y" - { (yyval.static_decl) = ast_static_decl((yyvsp[-3].data_size), (yyvsp[-2].ident), (yyvsp[-1].initializer)); } -#line 2236 "asm.tab.c" - break; - - case 110: /* dataSize: "WORD" */ -#line 465 "asm.y" - { (yyval.data_size) = ast_data_size((yyvsp[0].token), ds_word, 1); } -#line 2242 "asm.tab.c" - break; - - case 111: /* dataSize: "CHAR" */ -#line 466 "asm.y" - { (yyval.data_size) = ast_data_size((yyvsp[0].token), ds_char, 1); } -#line 2248 "asm.tab.c" - break; - - case 112: /* dataSize: "STRING" "[" unsignednumsym "]" */ -#line 468 "asm.y" - { (yyval.data_size) = ast_data_size((yyvsp[-3].token), ds_string, - /* declared size is in words! */ - (yyvsp[-1].unsignednum).value); } -#line 2256 "asm.tab.c" - break; - - case 113: /* initializerOpt: "=" number */ -#line 472 "asm.y" - { (yyval.initializer) = ast_initializer_number((yyvsp[-1].token), (yyvsp[0].number).value); } -#line 2262 "asm.tab.c" - break; - - case 114: /* initializerOpt: "=" charliteralsym */ -#line 474 "asm.y" - { (yyval.initializer) = ast_initializer_char((yyvsp[-1].token), (yyvsp[0].charlit).value); } -#line 2268 "asm.tab.c" - break; - - case 115: /* initializerOpt: "=" stringliteralsym */ -#line 476 "asm.y" - { (yyval.initializer) = ast_initializer_string((yyvsp[-1].token), (yyvsp[0].stringlit).pointer); } -#line 2274 "asm.tab.c" - break; - - case 116: /* initializerOpt: empty */ -#line 477 "asm.y" - { (yyval.initializer) = ast_initializer_empty((yyvsp[0].empty)); } -#line 2280 "asm.tab.c" - break; - - case 117: /* stackSection: ".stack" stackBottomAddr */ -#line 482 "asm.y" - { (yyval.stack_section) = ast_stack_section((yyvsp[-1].token), (yyvsp[0].unsignednum).value); } -#line 2286 "asm.tab.c" - break; - - -#line 2290 "asm.tab.c" - - default: break; - } - if (yychar_backup != yychar) - YY_LAC_DISCARD ("yychar change"); - } - /* User semantic actions sometimes alter yychar, and that requires - that yytoken be updated with the new translation. We take the - approach of translating immediately before every use of yytoken. - One alternative is translating here after every semantic action, - but that translation would be missed if the semantic action invokes - YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or - if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an - incorrect destructor might then be invoked immediately. In the - case of YYERROR or YYBACKUP, subsequent parser actions might lead - to an incorrect destructor call or verbose syntax error message - before the lookahead is translated. */ - YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - - *++yyvsp = yyval; - *++yylsp = yyloc; - - /* Now 'shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - { - const int yylhs = yyr1[yyn] - YYNTOKENS; - const int yyi = yypgoto[yylhs] + *yyssp; - yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp - ? yytable[yyi] - : yydefgoto[yylhs]); - } - - goto yynewstate; - - -/*--------------------------------------. -| yyerrlab -- here on detecting error. | -`--------------------------------------*/ -yyerrlab: - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; - { - yypcontext_t yyctx - = {yyssp, yyesa, &yyes, &yyes_capacity, yytoken, &yylloc}; - char const *yymsgp = YY_("syntax error"); - int yysyntax_error_status; - if (yychar != YYEMPTY) - YY_LAC_ESTABLISH; - yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); - if (yysyntax_error_status == 0) - yymsgp = yymsg; - else if (yysyntax_error_status == -1) - { - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = YY_CAST (char *, - YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc))); - if (yymsg) - { - yysyntax_error_status - = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); - yymsgp = yymsg; - } - else - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - yysyntax_error_status = YYENOMEM; - } - } - yyerror (file_name, yymsgp); - if (yysyntax_error_status == YYENOMEM) - YYNOMEM; - } - } - - yyerror_range[1] = yylloc; - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval, &yylloc, file_name); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - /* Pacify compilers when the user code never invokes YYERROR and the - label yyerrorlab therefore never appears in user code. */ - if (0) - YYERROR; - ++yynerrs; - - /* Do not reclaim the symbols of the rule whose action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - /* Pop stack until we find a state that shifts the error token. */ - for (;;) - { - yyn = yypact[yystate]; - if (!yypact_value_is_default (yyn)) - { - yyn += YYSYMBOL_YYerror; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - yyerror_range[1] = *yylsp; - yydestruct ("Error: popping", - YY_ACCESSING_SYMBOL (yystate), yyvsp, yylsp, file_name); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - /* If the stack popping above didn't lose the initial context for the - current lookahead token, the shift below will for sure. */ - YY_LAC_DISCARD ("error recovery"); - - YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - *++yyvsp = yylval; - YY_IGNORE_MAYBE_UNINITIALIZED_END - - yyerror_range[2] = yylloc; - ++yylsp; - YYLLOC_DEFAULT (*yylsp, yyerror_range, 2); - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturnlab; - - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturnlab; - - -/*-----------------------------------------------------------. -| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. | -`-----------------------------------------------------------*/ -yyexhaustedlab: - yyerror (file_name, YY_("memory exhausted")); - yyresult = 2; - goto yyreturnlab; - - -/*----------------------------------------------------------. -| yyreturnlab -- parsing is finished, clean up and return. | -`----------------------------------------------------------*/ -yyreturnlab: - if (yychar != YYEMPTY) - { - /* Make sure we have latest lookahead translation. See comments at - user semantic actions for why this is necessary. */ - yytoken = YYTRANSLATE (yychar); - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval, &yylloc, file_name); - } - /* Do not reclaim the symbols of the rule whose action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - YY_ACCESSING_SYMBOL (+*yyssp), yyvsp, yylsp, file_name); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif - if (yyes != yyesa) - YYSTACK_FREE (yyes); - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - return yyresult; -} - -#line 486 "asm.y" - - -// Set the program's ast to be t -void setProgAST(ast_program_t t) { progast = t; } diff --git a/vm/asm.tab.h b/vm/asm.tab.h deleted file mode 100755 index 7c23c48..0000000 --- a/vm/asm.tab.h +++ /dev/null @@ -1,166 +0,0 @@ -/* A Bison parser, made by GNU Bison 3.8.2. */ - -/* Bison interface for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, - Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, - especially those whose name start with YY_ or yy_. They are - private implementation details that can be changed or removed. */ - -#ifndef YY_YY_ASM_TAB_H_INCLUDED -# define YY_YY_ASM_TAB_H_INCLUDED -/* Debug traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif -#if YYDEBUG -extern int yydebug; -#endif -/* "%code requires" blocks. */ -#line 7 "asm.y" - - - /* Including "ast.h" must be at the top, to define the AST type */ -#include "ast.h" -#include "machine_types.h" -#include "parser_types.h" -#include "lexer.h" -// #include "utilities.h" // only needed for debugging - - /* Report an error to the user on stderr */ -extern void yyerror(const char *filename, const char *msg); - -#line 62 "asm.tab.h" - -/* Token kinds. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - enum yytokentype - { - YYEMPTY = -2, - YYEOF = 0, /* "end of file" */ - YYerror = 256, /* error */ - YYUNDEF = 257, /* "invalid token" */ - eolsym = 258, /* eolsym */ - identsym = 259, /* identsym */ - unsignednumsym = 260, /* unsignednumsym */ - plussym = 261, /* "+" */ - minussym = 262, /* "-" */ - commasym = 263, /* "," */ - dottextsym = 264, /* ".text" */ - dotdatasym = 265, /* ".data" */ - dotstacksym = 266, /* ".stack" */ - dotendsym = 267, /* ".end" */ - colonsym = 268, /* ":" */ - lbracketsym = 269, /* "[" */ - rbracketsym = 270, /* "]" */ - equalsym = 271, /* "=" */ - noopsym = 272, /* "NOP" */ - addopsym = 273, /* "ADD" */ - subopsym = 274, /* "SUB" */ - cpwopsym = 275, /* "CPW" */ - cpropsym = 276, /* "CPR" */ - andopsym = 277, /* "AND" */ - boropsym = 278, /* "BOR" */ - noropsym = 279, /* "NOR" */ - xoropsym = 280, /* "XOR" */ - lwropsym = 281, /* "LWR" */ - swropsym = 282, /* "SWR" */ - scaopsym = 283, /* "SCA" */ - lwiopsym = 284, /* "LWI" */ - negopsym = 285, /* "NEG" */ - litopsym = 286, /* "LIT" */ - ariopsym = 287, /* "ARI" */ - sriopsym = 288, /* "SRI" */ - mulopsym = 289, /* "MUL" */ - divopsym = 290, /* "DIV" */ - cfhiopsym = 291, /* "CFHI" */ - cfloopsym = 292, /* "CFLO" */ - sllopsym = 293, /* "SLL" */ - srlopsym = 294, /* "SRL" */ - jmpopsym = 295, /* "JMP" */ - jrelopsym = 296, /* "JREL" */ - addiopsym = 297, /* "ADDI" */ - andiopsym = 298, /* "ANDI" */ - boriopsym = 299, /* "BORI" */ - noriopsym = 300, /* "NORI" */ - xoriopsym = 301, /* "XORI" */ - beqopsym = 302, /* "BEQ" */ - bgezopsym = 303, /* "BGEZ" */ - blezopsym = 304, /* "BLEZ" */ - bgtzopsym = 305, /* "BGTZ" */ - bltzopsym = 306, /* "BLTZ" */ - bneopsym = 307, /* "BNE" */ - csiopsym = 308, /* "CSI" */ - jmpaopsym = 309, /* "JMPA" */ - callopsym = 310, /* "CALL" */ - rtnopsym = 311, /* "RTN" */ - exitopsym = 312, /* "EXIT" */ - pstropsym = 313, /* "PSTR" */ - pintopsym = 314, /* "PINT" */ - pchopsym = 315, /* "PCH" */ - rchopsym = 316, /* "RCH" */ - straopsym = 317, /* "STRA" */ - notropsym = 318, /* "NOTR" */ - regsym = 319, /* regsym */ - wordsym = 320, /* "WORD" */ - charsym = 321, /* "CHAR" */ - stringsym = 322, /* "STRING" */ - charliteralsym = 323, /* charliteralsym */ - stringliteralsym = 324 /* stringliteralsym */ - }; - typedef enum yytokentype yytoken_kind_t; -#endif - -/* Value type. */ - -/* Location type. */ -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED -typedef struct YYLTYPE YYLTYPE; -struct YYLTYPE -{ - int first_line; - int first_column; - int last_line; - int last_column; -}; -# define YYLTYPE_IS_DECLARED 1 -# define YYLTYPE_IS_TRIVIAL 1 -#endif - - -extern YYSTYPE yylval; -extern YYLTYPE yylloc; - -int yyparse (char const *file_name); - - -#endif /* !YY_YY_ASM_TAB_H_INCLUDED */ diff --git a/vm/asm.y b/vm/asm.y deleted file mode 100755 index f086d1d..0000000 --- a/vm/asm.y +++ /dev/null @@ -1,489 +0,0 @@ - /* $Id: asm.y,v 1.64 2024/11/10 14:34:25 leavens Exp $ */ - -%code top { -#include -} - -%code requires { - - /* Including "ast.h" must be at the top, to define the AST type */ -#include "ast.h" -#include "machine_types.h" -#include "parser_types.h" -#include "lexer.h" -// #include "utilities.h" // only needed for debugging - - /* Report an error to the user on stderr */ -extern void yyerror(const char *filename, const char *msg); -} - -%verbose -%define parse.lac full -%define parse.error detailed - -%parse-param { char const *file_name } - -%token eolsym -%token identsym -%token unsignednumsym -%token plussym "+" -%token minussym "-" -%token commasym "," -%token dottextsym ".text" -%token dotdatasym ".data" -%token dotstacksym ".stack" -%token dotendsym ".end" -%token colonsym ":" -%token lbracketsym "[" -%token rbracketsym "]" -%token equalsym "=" -%token noopsym "NOP" -%token addopsym "ADD" -%token subopsym "SUB" -%token cpwopsym "CPW" -%token cpropsym "CPR" -%token andopsym "AND" -%token boropsym "BOR" -%token noropsym "NOR" -%token xoropsym "XOR" -%token lwropsym "LWR" -%token swropsym "SWR" -%token scaopsym "SCA" -%token lwiopsym "LWI" -%token negopsym "NEG" -%token litopsym "LIT" -%token ariopsym "ARI" -%token sriopsym "SRI" -%token mulopsym "MUL" -%token divopsym "DIV" -%token cfhiopsym "CFHI" -%token cfloopsym "CFLO" -%token sllopsym "SLL" -%token srlopsym "SRL" -%token jmpopsym "JMP" -%token jrelopsym "JREL" -%token addiopsym "ADDI" -%token andiopsym "ANDI" -%token boriopsym "BORI" -%token noriopsym "NORI" -%token xoriopsym "XORI" -%token beqopsym "BEQ" -%token bgezopsym "BGEZ" -%token blezopsym "BLEZ" -%token bgtzopsym "BGTZ" -%token bltzopsym "BLTZ" -%token bneopsym "BNE" -%token csiopsym "CSI" -%token jmpaopsym "JMPA" -%token callopsym "CALL" -%token rtnopsym "RTN" -%token exitopsym "EXIT" -%token pstropsym "PSTR" -%token pintopsym "PINT" -%token pchopsym "PCH" -%token rchopsym "RCH" -%token straopsym "STRA" -%token notropsym "NOTR" - -%token regsym - -%token wordsym "WORD" -%token charsym "CHAR" -%token stringsym "STRING" -%token charliteralsym -%token stringliteralsym - - -%type program -%type textSection -%type entryPoint -%type addr -%type label -%type asmInstr -%type labelOpt -%type empty -%type asmInstrs -%type instr -%type noArgInstr -%type noArgOp -%type twoRegCompInstr -%type twoRegCompOp -%type offset -%type number -%type sign -%type twoRegNoOffsetsInstr -%type twoRegNoOffsetsOp -%type noTargetOffsetInstr -%type noTargetOffsetOp -%type noSourceOffsetInstr -%type noSourceOffsetOp -%type oneRegOffsetArgInstr -%type oneRegOffsetArgOp -%type oneRegArgInstr -%type oneRegArgOp -%type arg -%type oneRegOffsetInstr -%type oneRegOffsetOp -%type shiftInstr -%type shiftOp -%type shift -%type argOnlyInstr -%type argOnlyOp -%type immedArithInstr -%type immedArithOp -%type immed -%type immedBoolInstr -%type immedBoolOp -%type uimmed -%type branchTestInstr -%type branchTestOp -%type jumpInstr -%type jumpOp -%type syscallInstr -%type offsetOnlySyscall -%type offsetOnlySyscallOp -%type regOffsetSyscall -%type regOffsetSyscallOp -%type noArgSyscall -%type noArgSyscallOp -%type dataSection -%type staticStartAddr -%type staticDecls -%type staticDecl -%type dataSize -%type initializerOpt -%type stackSection -%type stackBottomAddr - -%start program - -%code { - /* extern declarations provided by the lexer */ -extern int yylex(void); - - /* extern void yyerror(char const *msg); */ - - /* The AST for the program, set by the semantic action for program. */ -ast_program_t progast; - - /* Set the program's ast to be t */ -extern void setProgAST(ast_program_t t); -} - -%% - -program : textSection dataSection stackSection ".end" - { setProgAST(ast_program($1, $2, $3)); } ; - -textSection : ".text" entryPoint asmInstrs - { $$ = ast_text_section($1,$2,$3); } ; - - -entryPoint : addr ; - -addr : label { $$ = ast_addr_label($1); } - | unsignednumsym { $$ = ast_entry_addr($1); } - ; - -label : identsym ; - - -asmInstrs : asmInstr { $$ = ast_asm_instrs_singleton($1); } - | asmInstrs asmInstr { $$ = ast_asm_instrs_add($1,$2); } - ; - -asmInstr : labelOpt instr eolsym { $$ = ast_asm_instr($1,$2); } ; - -labelOpt : label ":" { $$ = ast_label_opt_label($1); } - | empty { $$ = ast_label_opt_empty($1); } - ; - -empty : %empty { $$ = ast_empty(lexer_filename(), lexer_line()); } ; - - -instr : noArgInstr | twoRegCompInstr | twoRegNoOffsetsInstr - | noTargetOffsetInstr | noSourceOffsetInstr | oneRegOffsetArgInstr - | oneRegArgInstr | oneRegOffsetInstr | shiftInstr | argOnlyInstr - | immedArithInstr | immedBoolInstr | branchTestInstr | jumpInstr - | syscallInstr - ; - - -noArgInstr : noArgOp { $$ = ast_0arg_instr($1); } ; - -noArgOp : "NOP" | "RTN" ; - - -twoRegCompInstr : twoRegCompOp regsym "," offset "," regsym "," offset - { - $$ = ast_2reg_instr($1, $2.number, $4.value, - $6.number, $8.value, - lexer_token2func($1.toknum)); - } - ; - -twoRegCompOp : "ADD" | "SUB" | "CPW" - | "AND" | "BOR" | "NOR" | "XOR" | "SCA" | "LWI" | "NEG" ; - - -offset : number - { - machine_types_check_fits_in_offset($1.value); - $$ = $1; - } - ; - -number : sign unsignednumsym - { - word_type val = $2.value; - if ($1.toknum == minussym) { - val = - val; - } - $$ = ast_number($1, val); - } - ; - -sign : "+" | "-" - | empty { $$ = ast_token(lexer_filename(), lexer_line(), plussym); } - ; - - -twoRegNoOffsetsInstr : twoRegNoOffsetsOp regsym "," regsym - { - $$ = ast_2reg_instr($1, $2.number, 0, $4.number, 0, - lexer_token2func($1.toknum)); - } - ; - -twoRegNoOffsetsOp : "CPR" ; - - -noTargetOffsetInstr : noTargetOffsetOp regsym "," regsym "," offset - { - $$ = ast_2reg_instr($1, $2.number, 0, $4.number, $6.value, - lexer_token2func($1.toknum)); - } - ; - -noTargetOffsetOp : "LWR" ; - - -noSourceOffsetInstr : noSourceOffsetOp regsym "," offset "," regsym - { - $$ = ast_2reg_instr($1, $2.number, $4.value, $6.number, 0, - lexer_token2func($1.toknum)); - } - ; - -noSourceOffsetOp : "SWR" ; - - -oneRegOffsetArgInstr : oneRegOffsetArgOp regsym "," offset "," arg - { - $$ = ast_1reg_instr($1, other_comp_instr_type, - 1, $2.number, $4.value, - lexer_token2func($1.toknum), - ast_immed_number($6.value)); - } - ; - -oneRegOffsetArgOp : "LIT" ; - -arg : number - { /* the number is signed */ - machine_types_check_fits_in_arg($1.value); - $$ = $1; - } - ; - - -oneRegArgInstr : oneRegArgOp regsym "," arg - { - $$ = ast_1reg_instr($1, other_comp_instr_type, - 1, $2.number, 0, - lexer_token2func($1.toknum), - ast_immed_number($4.value)); - } - ; - -oneRegArgOp : "ARI" | "SRI" ; - - -oneRegOffsetInstr : oneRegOffsetOp regsym "," offset - { - $$ = ast_1reg_instr($1, other_comp_instr_type, - 1, $2.number, $4.value, - lexer_token2func($1.toknum), - ast_immed_none()); - } - ; - -oneRegOffsetOp : "MUL" | "DIV" | "CFHI" | "CFLO" | "JMP" | "CSI" ; - - -shiftInstr : shiftOp regsym "," offset "," shift - { - $$ = ast_1reg_instr($1, other_comp_instr_type, - 1, $2.number, $4.value, - lexer_token2func($1.toknum), - $6); - } - ; - -shiftOp : "SLL" | "SRL" ; - -shift : unsignednumsym - { - machine_types_check_fits_in_shift($1.value); - $$ = ast_immed_unsigned($1.value); - } - ; - - -argOnlyInstr : argOnlyOp arg - { - $$ = ast_1reg_instr($1, other_comp_instr_type, - 0, 0, 0, lexer_token2func($1.toknum), - ast_immed_number($2.value)); - } - ; - -argOnlyOp : "JREL" ; - - -immedArithInstr : immedArithOp regsym "," offset "," immed - { - $$ = ast_1reg_instr($1, immed_instr_type, - 1, $2.number, $4.value, - 0, $6); - } - ; - -immedArithOp : "ADDI" ; - -immed : number - { - machine_types_check_fits_in_immed($1.value); - $$ = ast_immed_number($1.value); - } - ; - - -immedBoolInstr : immedBoolOp regsym "," offset "," uimmed - { - $$ = ast_1reg_instr($1, immed_instr_type, - 1, $2.number, $4.value, - 0, $6); - } - ; - -immedBoolOp : "ANDI" | "BORI" | "XORI" | "NORI" ; - -uimmed : unsignednumsym - { - machine_types_check_fits_in_uimmed($1.value); - $$ = ast_immed_unsigned($1.value); - } - ; - - -branchTestInstr : branchTestOp regsym "," offset "," immed - { - $$ = ast_1reg_instr($1, immed_instr_type, - 1, $2.number, $4.value, - 0, $6); - } - ; - -branchTestOp : "BEQ" | "BGEZ" | "BGTZ" | "BLEZ" | "BLTZ" | "BNE" ; - - -jumpInstr : jumpOp addr - { - if ($2.address_defined) { - machine_types_check_fits_in_addr($2.addr); - } - $$ = ast_1reg_instr($1, jump_instr_type, - 0, 0, 0, - 0, ast_immed_addr($2)); - } - ; - -jumpOp : "JMPA" | "CALL" ; - - -syscallInstr : offsetOnlySyscall | regOffsetSyscall | noArgSyscall - -offsetOnlySyscall : offsetOnlySyscallOp offset - { - $$ = ast_1reg_instr($1, syscall_instr_type, - 1, 0, $2.value, - SYS_F, ast_syscall_code_for($1.toknum)); - } - ; - -offsetOnlySyscallOp : "EXIT" ; - - -regOffsetSyscall : regOffsetSyscallOp regsym "," offset - { - $$ = ast_1reg_instr($1, syscall_instr_type, - 1, $2.number, $4.value, - SYS_F, ast_syscall_code_for($1.toknum)); - } - ; - -regOffsetSyscallOp : "PSTR" | "PINT" | "PCH" | "RCH" ; - - -noArgSyscall : noArgSyscallOp - { - $$ = ast_1reg_instr($1, syscall_instr_type, - 0, 0, 0, - SYS_F, ast_syscall_code_for($1.toknum)); - } - ; - -noArgSyscallOp : "STRA" | "NOTR" ; - - - -dataSection : ".data" staticStartAddr staticDecls - { $$ = ast_data_section($1, $2.value, $3); } - ; - -staticStartAddr : unsignednumsym ; - - -staticDecls : empty { $$ = ast_static_decls_empty($1); } - | staticDecls staticDecl { $$ = ast_static_decls_add($1,$2); } - ; - -staticDecl : dataSize identsym initializerOpt eolsym - { $$ = ast_static_decl($1, $2, $3); } ; - -dataSize : "WORD" { $$ = ast_data_size($1, ds_word, 1); } - | "CHAR" { $$ = ast_data_size($1, ds_char, 1); } - | "STRING" "[" unsignednumsym "]" - { $$ = ast_data_size($1, ds_string, - /* declared size is in words! */ - $3.value); } ; - -initializerOpt : "=" number { $$ = ast_initializer_number($1, $2.value); } - | "=" charliteralsym - { $$ = ast_initializer_char($1, $2.value); } - | "=" stringliteralsym - { $$ = ast_initializer_string($1, $2.pointer); } - | empty { $$ = ast_initializer_empty($1); } - ; - - -stackSection : ".stack" stackBottomAddr - { $$ = ast_stack_section($1, $2.value); } ; - -stackBottomAddr : unsignednumsym ; - -%% - -// Set the program's ast to be t -void setProgAST(ast_program_t t) { progast = t; } diff --git a/vm/asm_lexer.l b/vm/asm_lexer.l deleted file mode 100755 index 94f0051..0000000 --- a/vm/asm_lexer.l +++ /dev/null @@ -1,379 +0,0 @@ -/* $Id: asm_lexer.l,v 1.59 2024/11/10 14:34:25 leavens Exp $ */ -/* Scanner for the SSM Assembly Language */ - -%option header-file = "asm_lexer.h" -%option outfile = "asm_lexer.c" -%option yylineno -%option bison-bridge - -%{ -#include -#include -#include -#include "ast.h" -#include "parser_types.h" -#include "utilities.h" -#include "char_utilities.h" -#include "lexer.h" - - /* Tokens generated by Bison */ -#include "asm.tab.h" - - /* need declaration of fileno, part of the C standard library. - (Putting an extern declaration here shuts off a gcc warning.) */ -extern int fileno(FILE *stream); - -/* The filename of the file being read */ -char *filename; - -/* Have any errors been noted? */ -bool errors_noted; - -/* The value of a token */ -extern YYSTYPE yylval; - -/* The FILE used by the generated lexer */ -extern FILE *yyin; - -#undef yywrap /* sometimes a macro by default */ - -// apparently strdup is not declared in -extern char *strdup(const char *s); - -// set the lexer's value for a token in yylval as an AST -static void tok2ast(int toknum) { - AST t; - t.token.file_loc = file_location_make(filename, yylineno); - t.token.type_tag = token_ast; - t.token.toknum = toknum; - t.token.text = strdup(yytext); - yylval = t; -} - -static void reg2ast(const char *txt) { - AST t; - t.reg.file_loc = file_location_make(filename, yylineno); - t.reg.type_tag = reg_ast; - t.reg.text = strdup(yytext); - reg_num_type n; - sscanf(txt, "%hu", &n); - t.reg.number = n; - yylval = t; -} - -static void namedreg2ast(unsigned short num, const char *txt) { - AST t; - t.reg.file_loc = file_location_make(filename, yylineno); - t.reg.type_tag = reg_ast; - t.reg.text = strdup(yytext); - t.reg.number = num; - yylval = t; -} - - -static void ident2ast(const char *name) { - AST t; - t.ident.file_loc = file_location_make(filename, yylineno); - t.ident.type_tag = ident_ast; - t.ident.name = strdup(name); - yylval = t; -} - -static void unsignednum2ast(unsigned int val) -{ - AST t; - t.unsignednum.file_loc = file_location_make(filename, yylineno); - t.unsignednum.type_tag = unsignednum_ast; - t.unsignednum.text = strdup(yytext); - t.unsignednum.value = val; - yylval = t; -} - -static void charliteral2ast() -{ - AST t; - int charlit_len; // number of characters in the literal - t.charlit.file_loc = file_location_make(filename, yylineno); - assert(t.charlit.file_loc != NULL); - t.charlit.type_tag = char_literal_ast; - const char *start_of_literal = yytext+1; - t.charlit.value = char_utilities_char_value(start_of_literal, - &charlit_len); - yylval = t; -} - -#define STRINGLITERALMAXSIZE 1024 - -static void stringliteral2ast() -{ - AST t; - t.stringlit.file_loc = file_location_make(filename, yylineno); - assert(t.stringlit.file_loc != NULL); - t.stringlit.type_tag = string_literal_ast; - int len = strlen(yytext); - if (len < 2) { - bail_with_error("String literal is too short in stringLiteral2ast!"); - } - assert(len >= 2); - // take off length for the quotation marks, - len = len - 2; - - char strval[STRINGLITERALMAXSIZE]; - int ri = 0; // result index (into strval) - int yi = 1; // index into yytext - int charlit_len = 0; // length read for a char literal - while (yi <= len && yytext[yi] != '\"' && ri < (STRINGLITERALMAXSIZE-1)) { - strval[ri] = char_utilities_char_value(yytext+yi, &charlit_len); - ri++; - yi = yi+charlit_len; - } - if (ri >= STRINGLITERALMAXSIZE) { - bail_with_prog_error(*(t.stringlit.file_loc), - "String literal is too long (missing double quote?)"); - } - strval[ri] = '\0'; - assert(ri == strlen(strval)); - t.stringlit.pointer = strdup(strval); - yylval = t; -} - -%} - - /* you can add actual definitions below */ - -DECDIGIT [0-9] -OCTDIGIT [0-7] -HEXDIGIT [0-9A-Fa-f] -UNSIGNEDNUMBER (((0x){HEXDIGIT}+)|{DECDIGIT}+) -LETTER [_a-zA-Z] -LETTERORDIGIT ({LETTER}|{DECDIGIT}) -IDENT {LETTER}({LETTERORDIGIT}*) -NEWLINE \n -CR \r -EOL ({NEWLINE}|({CR}{NEWLINE})) -COMMENTSTART # -COMMENT {COMMENTSTART}.* -IGNORED [ \t\v\f\r] -BACKSLASH \\ -CHARAFTERBACKSLASH ([nrftvab'\"\\]|x{HEXDIGIT}+|0{OCTDIGIT}*) -CHARESCAPE {BACKSLASH}{CHARAFTERBACKSLASH} - /* char codes for char-literals */ -CHARCODE ({CHARESCAPE}|[^\'\\\n]) - /* string chars for string-literals */ -STRINGCHAR ({CHARESCAPE}|[^\"\\\n]) - - /* states of the lexer */ - -%s INSTRUCTION -%s DATADECL - -%% - -{IGNORED} { ; } /* do nothing */ -{COMMENT} { ; } /* ignore comments */ -{EOL} { BEGIN INITIAL; return eolsym; } -{EOL} { BEGIN INITIAL; return eolsym; } -{EOL} { ; } /* ignore EOL outside of the above states */ - -NOP { BEGIN INSTRUCTION; tok2ast(noopsym); return noopsym; } -ADD { BEGIN INSTRUCTION; tok2ast(addopsym); return addopsym; } -SUB { BEGIN INSTRUCTION; tok2ast(subopsym); return subopsym; } -CPW { BEGIN INSTRUCTION; tok2ast(cpwopsym); return cpwopsym; } -CPR { BEGIN INSTRUCTION; tok2ast(cpropsym); return cpropsym; } -AND { BEGIN INSTRUCTION; tok2ast(andopsym); return andopsym; } -BOR { BEGIN INSTRUCTION; tok2ast(boropsym); return boropsym; } -NOR { BEGIN INSTRUCTION; tok2ast(noropsym); return noropsym; } -XOR { BEGIN INSTRUCTION; tok2ast(xoropsym); return xoropsym; } -LWR { BEGIN INSTRUCTION; tok2ast(lwropsym); return lwropsym; } -SWR { BEGIN INSTRUCTION; tok2ast(swropsym); return swropsym; } -SCA { BEGIN INSTRUCTION; tok2ast(scaopsym); return scaopsym; } -LWI { BEGIN INSTRUCTION; tok2ast(lwiopsym); return lwiopsym; } -NEG { BEGIN INSTRUCTION; tok2ast(negopsym); return negopsym; } -LIT { BEGIN INSTRUCTION; tok2ast(litopsym); return litopsym; } -ARI { BEGIN INSTRUCTION; tok2ast(ariopsym); return ariopsym; } -SRI { BEGIN INSTRUCTION; tok2ast(sriopsym); return sriopsym; } -MUL { BEGIN INSTRUCTION; tok2ast(mulopsym); return mulopsym; } -DIV { BEGIN INSTRUCTION; tok2ast(divopsym); return divopsym; } -CFHI { BEGIN INSTRUCTION; tok2ast(cfhiopsym); return cfhiopsym; } -CFLO { BEGIN INSTRUCTION; tok2ast(cfloopsym); return cfloopsym; } -SLL { BEGIN INSTRUCTION; tok2ast(sllopsym); return sllopsym; } -SRL { BEGIN INSTRUCTION; tok2ast(srlopsym); return srlopsym; } -JMP { BEGIN INSTRUCTION; tok2ast(jmpopsym); return jmpopsym; } -CSI { BEGIN INSTRUCTION; tok2ast(csiopsym); return csiopsym; } -JREL { BEGIN INSTRUCTION; tok2ast(jrelopsym); return jrelopsym; } -ADDI { BEGIN INSTRUCTION; tok2ast(addiopsym); return addiopsym; } -ANDI { BEGIN INSTRUCTION; tok2ast(andiopsym); return andiopsym; } -BORI { BEGIN INSTRUCTION; tok2ast(boriopsym); return boriopsym; } -NORI { BEGIN INSTRUCTION; tok2ast(xoriopsym); return noriopsym; } -XORI { BEGIN INSTRUCTION; tok2ast(xoriopsym); return xoriopsym; } -BEQ { BEGIN INSTRUCTION; tok2ast(beqopsym); return beqopsym; } -BGEZ { BEGIN INSTRUCTION; tok2ast(bgezopsym); return bgezopsym; } -BGTZ { BEGIN INSTRUCTION; tok2ast(bgtzopsym); return bgtzopsym; } -BLEZ { BEGIN INSTRUCTION; tok2ast(blezopsym); return blezopsym; } -BLTZ { BEGIN INSTRUCTION; tok2ast(bltzopsym); return bltzopsym; } -BNE { BEGIN INSTRUCTION; tok2ast(bneopsym); return bneopsym; } -JMPA { BEGIN INSTRUCTION; tok2ast(jmpaopsym); return jmpaopsym; } -CALL { BEGIN INSTRUCTION; tok2ast(callopsym); return callopsym; } -RTN { BEGIN INSTRUCTION; tok2ast(rtnopsym); return rtnopsym; } -EXIT { BEGIN INSTRUCTION; tok2ast(exitopsym); return exitopsym; } -PSTR { BEGIN INSTRUCTION; tok2ast(pstropsym); return pstropsym; } -PINT { BEGIN INSTRUCTION; tok2ast(pintopsym); return pintopsym; } -PCH { BEGIN INSTRUCTION; tok2ast(pchopsym); return pchopsym; } -RCH { BEGIN INSTRUCTION; tok2ast(rchopsym); return rchopsym; } -STRA { BEGIN INSTRUCTION; tok2ast(straopsym); return straopsym; } -NOTR { BEGIN INSTRUCTION; tok2ast(notropsym); return notropsym; } - -WORD { BEGIN DATADECL; tok2ast(wordsym); return wordsym; } -CHAR { BEGIN DATADECL; tok2ast(charsym); return charsym; } -STRING { BEGIN DATADECL; tok2ast(stringsym); return stringsym; } - -\+ { tok2ast(plussym); return plussym; } -- { tok2ast(minussym); return minussym; } -, { return commasym; } - -\.text { tok2ast(dottextsym); return dottextsym; } -\.data { tok2ast(dotdatasym); return dotdatasym; } -\.stack { tok2ast(dotstacksym); return dotstacksym; } -\.end { return dotendsym; } -\= { tok2ast(equalsym); return equalsym; } -: { return colonsym; } -\[ { tok2ast(lbracketsym); return lbracketsym; } -\] { tok2ast(rbracketsym); return rbracketsym; } - -'{CHARCODE}' { charliteral2ast(); return charliteralsym; } -\"{STRINGCHAR}*\" { stringliteral2ast(); return stringliteralsym; } - -{UNSIGNEDNUMBER} { unsigned int val; - int ssf_ret; - size_t len = strlen(yytext); - if (yyleng >= 2 && (strncmp(yytext, "0x", 2) == 0)) { - // hex literal - if (len > 8+2) { - bail_with_error( - "Unsigned literal has too many digits \"%s\"", - yytext); - } - ssf_ret = sscanf(yytext+2, "%x", &val); - if (ssf_ret != 1) { - bail_with_error("Unsigned hex literal (%s) could not be read by lexer!", - yytext); - } - } else { - if (len > 10) { // 2^32 has 10 digits - bail_with_error( - "Unsigned decimal literal has too many digits \"%s\"", - yytext); - } - ssf_ret = sscanf(yytext, "%du", &val); - if (ssf_ret != 1) { - bail_with_error("Unsigned decimal literal (%s) could not be read by lexer!", - yytext); - } - } - unsignednum2ast(val); - return unsignednumsym; - } - -${OCTDIGIT} { reg2ast(yytext+1); return regsym; } -${UNSIGNEDNUMBER} { char msgbuf[512]; - sprintf(msgbuf, "Register numbers must be between 0 and 7 (inclusive, (not like \"%s\")", - yytext); - yyerror(lexer_filename(), msgbuf); - } -$gp { namedreg2ast(0,yytext); return regsym; } -$sp { namedreg2ast(1,yytext); return regsym; } -$fp { namedreg2ast(2,yytext); return regsym; } -$r3 { namedreg2ast(3,yytext); return regsym; } -$r4 { namedreg2ast(4,yytext); return regsym; } -$r5 { namedreg2ast(5,yytext); return regsym; } -$r6 { namedreg2ast(6,yytext); return regsym; } -$ra { namedreg2ast(7,yytext); return regsym; } -{IDENT} { ident2ast(yytext); return identsym; } - - -. { char msgbuf[512]; - sprintf(msgbuf, "invalid character: '%c' ('\\0%o')", *yytext, *yytext); - yyerror(lexer_filename(), msgbuf); - } -%% - -/* Requires: fname != NULL - * Requires: fname is the name of a readable file - * Initialize the lexer and start it reading from the given file. */ -void lexer_init(char *fname) { - errors_noted = false; - filename = fname; - yyin = fopen(fname, "r"); - if (yyin == NULL) { - bail_with_error("Lexer cannot open %s", fname); - } -} - -// Close the file yyin -// and return 1 to indicate that there are no more files -int yywrap() { - if (yyin != NULL) { - int rc = fclose(yyin); - if (rc == EOF) { - bail_with_error("Cannot close %s!", filename); - } - } - filename = NULL; - return 1; /* no more input */ -} - -// Return the name of the current input file -const char *lexer_filename() { - return filename; -} - -// Return the line number of the next token -unsigned int lexer_line() { - return yylineno; -} - -/* Report an error to the user on stderr */ -void yyerror(const char *filename, const char *msg) -{ - fflush(stdout); - fprintf(stderr, "%s:%d: %s\n", filename, lexer_line(), msg); - errors_noted = true; -} - -// On standard output: -// Print a message about the file name of the lexer's input -// and then print a heading for the lexer's output. -void lexer_print_output_header() -{ - printf("Tokens from file %s\n", lexer_filename()); - printf("%-6s %-4s %s\n", "Number", "Line", "Text"); -} - -// Print information about the token t to stdout -// followed by a newline -void lexer_print_token(enum yytokentype t, unsigned int tline, - const char *txt) -{ - printf("%-6d %-4d \"%s\"\n", t, tline, txt); -} - -/* Read all the tokens from the input file - * and print each token on standard output - * using the format in lexer_print_token */ -void lexer_output() -{ - lexer_print_output_header(); - AST dummy; - yytoken_kind_t t; - do { - t = yylex(&dummy); - if (t == YYEOF) { - break; - } - if (t != eolsym) { - lexer_print_token(t, yylineno, yytext); - } else { - lexer_print_token(t, yylineno, "\\n"); - } - } while (t != YYEOF); -} diff --git a/vm/asm_main.c b/vm/asm_main.c deleted file mode 100755 index be189f2..0000000 --- a/vm/asm_main.c +++ /dev/null @@ -1,148 +0,0 @@ -/* $Id: asm_main.c,v 1.20 2024/07/16 14:11:23 leavens Exp $ */ -#include -#include -#include -#include "ast.h" -#include "parser_types.h" -#include "bof.h" -#include "lexer.h" -#include "asm.tab.h" -#include "instruction.h" -#include "utilities.h" -#include "asm_unparser.h" -#include "pass1.h" -#include "assemble.h" - -// strdup seems to be in the string library but not in the header... -extern char *strdup(const char *s); - -/* The program's AST, set by the parser */ -extern ast_program_t progast; - -// Requires: fn is a name that ends in .asm -// Modify fn to have the extension .bof -static void change_to_bof_ext(char *fn) { - int len = strlen(fn); - if (len <= 3) { - bail_with_error("Not enough chars in file name passed to chage_to_bof_ext (\"%s\")", - fn); - } - // assert(len > 3); - char *endstr = strrchr(fn, '.'); - // assert(*endstr == '.'); - if (strcmp(endstr, ".asm") != 0) { - bail_with_error("Name passed to change_to_bof_ext does not end in .asm (\"%s\")", - fn); - } - strcpy(endstr, ".bof"); -} - -char * cmdname; -static const char *typicalFile = "file.asm"; - -void usage() { - bail_with_error("Usage: %s %s\n %s %s %s\n %s %s %s\n %s %s %s", - cmdname, typicalFile, - cmdname, "-l", typicalFile, - cmdname, "-u", typicalFile, - cmdname, "-s", typicalFile); - exit(EXIT_FAILURE); -} - -extern int yydebug; - -int main(int argc, char *argv[]) { - // should the tokens seen by the lexer be printed? - bool lexer_print_output = false; - // should the unparse be printed? - bool parser_unparse = false; - // should the symbol table be printed after pass 1? - bool symbol_table_print = false; - - cmdname = argv[0]; - argc--; - argv++; - - // possible options: -l, -u, and -s - while (argc > 0 && strlen(argv[0]) >= 2 && argv[0][0] == '-') { - if (strcmp(argv[0],"-l") == 0) { - lexer_print_output = true; - argc--; - argv++; - } else if (strcmp(argv[0],"-u") == 0) { - parser_unparse = true; - argc--; - argv++; - } else if (strcmp(argv[0],"-s") == 0) { - symbol_table_print = true; - argc--; - argv++; - } else { - // bad option! - usage(); - } - } - - // give usage message if -l and other options are used - if ( lexer_print_output && (symbol_table_print || parser_unparse) ) { - usage(); - } - - // give usage message if -u and other options are used - if ( parser_unparse && symbol_table_print ) { - usage(); - } - - // must have a file name - if (argc <= 0 || (strlen(argv[0]) >= 2 && argv[0][0] == '-')) { - usage(); - } - - // the name of the file - char *file_name = argv[0]; - - if (lexer_print_output) { - // with the lexer_print_output option, nothing else is done - lexer_init(file_name); - lexer_output(); - if (errors_noted) { - return EXIT_FAILURE; - } else { - return EXIT_SUCCESS; - } - } - - // otherwise (if not lexer_print_outout) continue to parse etc. - lexer_init(file_name); - int parser_ret = yyparse(file_name); - if (parser_ret != 0) { - exit(EXIT_FAILURE); - } - - if (parser_unparse) { - unparseProgram(stdout, progast); - } - - if (parser_unparse) { - return EXIT_SUCCESS; - } - - // check for duplicate declarations of labels/names and build symbol table - pass1(progast); - - // print debugging information about the symbol table - if (symbol_table_print) { - pass1_print(stdout); - } - - char *bfn = strdup(file_name); - change_to_bof_ext(bfn); - - BOFFILE bf = bof_write_open(bfn); - - // generate code from the ASTs - assembleProgram(bf, progast); - bof_close(bf); - - return EXIT_SUCCESS; -} diff --git a/vm/asm_unparser.c b/vm/asm_unparser.c deleted file mode 100755 index 3af6c51..0000000 --- a/vm/asm_unparser.c +++ /dev/null @@ -1,268 +0,0 @@ -/* $Id: asm_unparser.c,v 1.30 2024/08/28 21:25:00 leavens Exp $ */ -#include -#include -#include -#include "ast.h" -#include "utilities.h" -#include "char_utilities.h" -#include "regname.h" -#include "asm_unparser.h" - -// Note: newlines and indentation are only printed -// by a function which deals with a grammar that sensibly needs one printed, -// as this makes them those functions more reusable. - -// Unparse prog, with output going to the file out -void unparseProgram(FILE *out, ast_program_t prog) -{ - unparseTextSection(out, prog.textSection); - unparseDataSection(out, prog.dataSection); - unparseStackSection(out, prog.stackSection); - fprintf(out, ".end"); - newline(out); -} - -// Unparse the given AST, with output going to out -void unparseTextSection(FILE *out, ast_text_section_t ts) -{ - fprintf(out, ".text "); - unparseEntryPoint(out, ts.entryPoint); - newline(out); - unparseAsmInstrs(out, ts.instrs); -} - -// Unparse the given AST, with output going to out -void unparseEntryPoint(FILE *out, ast_addr_t ep) -{ - unparseAddr(out, ep); -} - -// Unparse the given AST, with output going to out -void unparseAddr(FILE *out, ast_addr_t addr) -{ - if (addr.label != NULL) { - fprintf(out, "%s", addr.label); - } else { - fprintf(out, "%u", addr.addr); - } -} - -// Unparse the given AST, with output going to out -void unparseAsmInstrs(FILE *out, ast_asm_instrs_t instrs) -{ - ast_asm_instr_t *ip = instrs.instrs; - while (ip != NULL) { - unparseAsmInstr(out, *ip); - ip = ip->next; - } -} - -// Unparse the given AST, with output going to out -void unparseAsmInstr(FILE *out, ast_asm_instr_t instr) -{ - unparseLabelOpt(out, instr.label_opt); - unparseInstr(out, instr.instr); - newline(out); -} - -// Unparse the given AST, with output going to out -void unparseLabelOpt(FILE *out, ast_label_opt_t lopt) -{ - if (lopt.name == NULL) { - fprintf(out, "\t"); - } else { - fprintf(out, "%s:\t", lopt.name); - } -} - -// Unparse the given AST, with output going to out -void unparseInstr(FILE *out, ast_instr_t instr) -{ - fprintf(out, "%s ", instr.opname); - - // print any registers used - switch (instr.opcode) { - case COMP_O: - switch (instr.func) { - case NOP_F: - // no arguments, so nothing to print! - break; - case LWR_F: - fprintf(out, "%s, %s, %hd", - unparseReg(instr.reg), unparseReg(instr.reg2), - instr.offset2); - break; - case SWR_F: - fprintf(out, "%s, %hd, %s", - unparseReg(instr.reg), instr.offset, - unparseReg(instr.reg2)); - break; - default: // all the rest of these instructions - fprintf(out, "%s, %hd, %s, %hd", - unparseReg(instr.reg), instr.offset, - unparseReg(instr.reg2), instr.offset2); - break; - } - break; - case OTHC_O: - switch (instr.func) { - case LIT_F: - fprintf(out, "%s, %hd, %hd", - unparseReg(instr.reg), instr.offset, - instr.immed_data.data.immed); - break; - case ARI_F: case SRI_F: case MUL_F: case DIV_F: - case CFHI_F: case CFLO_F: case JMP_F: case CSI_F: - fprintf(out, "%s, %hd", - unparseReg(instr.reg), instr.offset); - break; - case SLL_F: case SRL_F: - fprintf(out, "%s, %hd, %hu", - unparseReg(instr.reg), instr.offset, - instr.immed_data.data.uimmed); - break; - case JREL_F: - fprintf(out, "%hd", instr.immed_data.data.immed); - break; - case SYS_F: - switch (instr.immed_data.data.syscall_code) { - case exit_sc: - fprintf(out, "%hd", instr.offset); - break; - case print_str_sc: case print_char_sc: case read_char_sc: - fprintf(out, "%s, %hd", unparseReg(instr.reg), instr.offset); - break; - case start_tracing_sc: case stop_tracing_sc: - // no arguments! - break; - default: - bail_with_error("Unknown syscall_code in SYS_F case of unparseInstr!"); - break; - } - break; - default: - bail_with_error("Unknown other computational opcode in unparseInstr %d", instr.opcode); - break; - } - break; - case ADDI_O: - fprintf(out, "%s, %hd, %hd", - unparseReg(instr.reg), instr.offset, instr.immed_data.data.immed); - break; - case ANDI_O: case BORI_O: case NORI_O: case XORI_O: - fprintf(out, "%s, %hd, %hx", - unparseReg(instr.reg), instr.offset, instr.immed_data.data.uimmed); - break; - case BEQ_O: case BGEZ_O: case BGTZ_O: case BLEZ_O: case BLTZ_O: case BNE_O: - fprintf(out, "%s, %hd, %hd", - unparseReg(instr.reg), instr.offset, instr.immed_data.data.immed); - break; - case JMPA_O: case CALL_O: - unparseImmediateAddress(out, instr.immed_data.data.addr); - break; - case RTN_O: - // no arguments, so nothing to print! - break; - default: - bail_with_error("Unknown opcode (%d) in unparseInstr!", instr.opcode); - break; - } -} - -// Unparse the given AST, with output going to out -void unparseImmediateAddress(FILE *out, ast_addr_t addr) -{ - if (addr.address_defined) { - fprintf(out, "%u", addr.addr); - } else { - fprintf(out, "%s", addr.label); - } -} - -// Unparse a register, returning a string for the register's name -const char *unparseReg(reg_num_type n) -{ - if (0 <= n && n < NUM_REGISTERS) { - return regname_get(n); - } else { - bail_with_error("Bad register number (%d)!", n); - return NULL; // never happens - } -} - -// Unparse the given AST, with output going to out -void unparseDataSection(FILE *out, ast_data_section_t ds) -{ - fprintf(out, ".data %u", ds.static_start_addr); - newline(out); - unparseStaticDecls(out, ds.staticDecls); -} - -// Unparse the given AST, with output going to out -void unparseStaticDecls(FILE *out, ast_static_decls_t sds) -{ - ast_static_decl_t *dcl = sds.decls; - while (dcl != NULL) { - unparseStaticDecl(out, *dcl); - dcl = dcl->next; - } -} - -// Unparse the given AST, with output going to out -void unparseStaticDecl(FILE *out, ast_static_decl_t dcl) -{ - unparseDataSize(out, dcl); - fprintf(out, "\t"); - unparseIdent(out, dcl.ident); - fprintf(out, " "); - unparseInitializer(out, dcl.initializer); - newline(out); -} - -// Unparse the data size declaration, with output going to out -void unparseDataSize(FILE *out, ast_static_decl_t dcl) -{ - fprintf(out, "%s ", dcl.size_name); - if (dcl.dse == ds_string) { - fprintf(out, "[%u]", dcl.size_in_words); - } -} - -// Unparse the given AST, with output going to out -void unparseIdent(FILE *out, ast_ident_t id) -{ - fprintf(out, "%s", id.name); -} - - -// Unparse the given AST, with output going to out -void unparseInitializer(FILE *out, ast_initializer_opt_t init) -{ - switch (init.kind) { - case initzlr_k_number: - fprintf(out, "= %d", init.num_value); - break; - case initzlr_k_char: - fprintf(out, "= '%s'", char_utilities_unescape_char(init.num_value)); - break; - case initzlr_k_string: - fprintf(out, "= \""); - fprintf(out, "%s", char_utilities_unescape_string(init.str_value)); - fprintf(out, "\""); - break; - case initzlr_k_none: - // don't print anything! - break; - default: - bail_with_error("Unknown initializer kind in unparseInitializer!"); - break; - } -} - - -// Unparse the given AST, with output going to out -void unparseStackSection(FILE *out, ast_stack_section_t ss) -{ - fprintf(out, ".stack %u", ss.stack_bottom_addr); - newline(out); -} diff --git a/vm/asm_unparser.h b/vm/asm_unparser.h deleted file mode 100755 index 931b096..0000000 --- a/vm/asm_unparser.h +++ /dev/null @@ -1,58 +0,0 @@ -/* $Id: asm_unparser.h,v 1.9 2024/07/29 16:17:19 leavens Exp $ */ -#ifndef _ASM_UNPARSER_H -#define _ASM_UNPARSER_H -#include -#include "ast.h" - -// Unparse prog, with output going to the file out -extern void unparseProgram(FILE *out, ast_program_t prog); - -// Unparse the given AST, with output going to out -extern void unparseTextSection(FILE *out, ast_text_section_t ts); - -// Unparse the given AST, with output going to out -extern void unparseEntryPoint(FILE *out, ast_addr_t ep); - -// Unparse the given AST, with output going to out -extern void unparseAddr(FILE *out, ast_addr_t l); - -// Unparse the given AST, with output going to out -extern void unparseAsmInstrs(FILE *out, ast_asm_instrs_t instrs); - -// Unparse the given AST, with output going to out -extern void unparseAsmInstr(FILE *out, ast_asm_instr_t instr); - -// Unparse the given AST, with output going to out -extern void unparseLabelOpt(FILE *out, ast_label_opt_t lopt); - -// Unparse the given AST, with output going to out -extern void unparseInstr(FILE *out, ast_instr_t instr); - -// Unparse the given AST, with output going to out -extern void unparseImmediateAddress(FILE *out, ast_addr_t addr); - -// Unparse a register, returning a string for the register's name -extern const char *unparseReg(reg_num_type n); - -// Unparse the given AST, with output going to out -extern void unparseDataSection(FILE *out, ast_data_section_t ds); - -// Unparse the given AST, with output going to out -extern void unparseStaticDecls(FILE *out, ast_static_decls_t sds); - -// Unparse the given AST, with output going to out -extern void unparseStaticDecl(FILE *out, ast_static_decl_t dcl); - -// Unparse the data size declartion, with output going to out -void unparseDataSize(FILE *out, ast_static_decl_t dcl); - -// Unparse the given AST, with output going to out -extern void unparseIdent(FILE *out, ast_ident_t id); - -// Unparse the given AST, with output going to out -extern void unparseInitializer(FILE *out, ast_initializer_opt_t init); - -// Unparse the given AST, with output going to out -extern void unparseStackSection(FILE *out, ast_stack_section_t ss); - -#endif diff --git a/vm/assemble.c b/vm/assemble.c deleted file mode 100755 index d99ec94..0000000 --- a/vm/assemble.c +++ /dev/null @@ -1,236 +0,0 @@ -/* $Id: assemble.c,v 1.36 2024/08/29 21:58:39 leavens Exp $ */ -#include -#include -#include -#include "ast.h" -#include "utilities.h" -#include "assemble.h" -#include "bof.h" -#include "symtab.h" -#include "id_attrs_assoc.h" -#include "regname.h" - -// Return the address associated with the addr l -static address_type addr2address(ast_addr_t addr) -{ - address_type ret = addr.addr; - if (addr.address_defined) { - return ret; - } else { - // the address is not defined yet - id_attrs_assoc *ida = symtab_lookup(addr.label); - if (ida == NULL) { - bail_with_prog_error(*(addr.file_loc), - "Label \"%s\" was never defined!", - addr.label); - } - return ida->addr; - } -} - -// Assemble the code for prog, with output going to bf -void assembleProgram(BOFFILE bf, ast_program_t prog) -{ - BOFHeader bh; - bof_write_magic_to_header(&bh); - bh.text_start_address = addr2address(prog.textSection.entryPoint); - bh.text_length = ast_list_length(prog.textSection.instrs.instrs); - bh.data_start_address = prog.dataSection.static_start_addr; - // have to write the header first, so need to know the true size - // of the data section before writing the header - bh.data_length = assemble_dataSection_words(prog.dataSection); - bh.stack_bottom_addr = prog.stackSection.stack_bottom_addr; - bof_write_header(bf, bh); - assembleTextSection(bf, prog.textSection); - assembleDataSection(bf, prog.dataSection); - // nothing to do for the stack section, as it's all in the header -} - -// Assemble the code for the given AST, with output going to bf -void assembleTextSection(BOFFILE bf, ast_text_section_t ts) -{ - assembleAsmInstrs(bf, ts.instrs); -} - -// Assemble the code for the given AST, with output going to bf -void assembleAsmInstrs(BOFFILE bf, ast_asm_instrs_t instrs) -{ - ast_asm_instr_t *ip = instrs.instrs; - while (ip != NULL) { - assembleAsmInstr(bf, *ip); - ip = ip->next; - } -} - -// Assemble the code for the given AST, with output going to bf -void assembleAsmInstr(BOFFILE bf, ast_asm_instr_t instr) -{ - assembleInstr(bf, instr.instr); -} - -// Return the value of the immedidate data AST immed -static unsigned int immedData_value(ast_immedData_t immed) -{ - int ret = 0; - switch (immed.id_data_kind) { - case id_number: - ret = immed.data.immed; - break; - case id_syscall_code: - ret = immed.data.syscall_code; - break; - case id_unsigned: - ret = immed.data.uimmed; - break; - case id_addr: - return addr2address(immed.data.addr); - break; - case id_empty: - ret = 0; - break; - default: - bail_with_error("Unknown immed_data_kind_t (%d) in immedData_value", - immed.id_data_kind); - break; - } - return ret; -} - -// Assemble the code for the given AST, with output going to bf -void assembleInstr(BOFFILE bf, ast_instr_t instr) -{ - switch (instr.itype) { - case comp_instr_type: - comp_instr_t ci; - ci.op = instr.opcode; - assert(ci.op == COMP_O); - ci.rt = instr.reg; - ci.ot = instr.offset; - ci.rs = instr.reg2; - ci.os = instr.offset2; - ci.func = instr.func; - instruction_write_compInstr(bf, ci); - break; - case other_comp_instr_type: - other_comp_instr_t oci; - oci.op = instr.opcode; - assert(oci.op == OTHC_O); - oci.reg = instr.reg; - oci.offset = instr.offset; - oci.arg = instr.immed_data.data.uimmed; - oci.func = instr.func; - instruction_write_otherCompInstr(bf, oci); - break; - case syscall_instr_type: - syscall_instr_t si; - si.op = OTHC_O; - si.reg = instr.reg; - si.offset = instr.offset; - si.code = (syscall_type) immedData_value(instr.immed_data); - si.func = SYS_F; - instruction_write_syscallInstr(bf, si); - break; - case immed_instr_type: - switch (instr.opcode) { - case ANDI_O: case BORI_O: case NORI_O: case XORI_O: - uimmed_instr_t ui; - ui.op = instr.opcode; - ui.reg = instr.reg; - ui.offset = instr.offset; - ui.uimmed = immedData_value(instr.immed_data); - instruction_write_uimmedInstr(bf, ui); - break; - default: - immed_instr_t ii; - ii.op = instr.opcode; - ii.reg = instr.reg; - ii.offset = instr.offset; - ii.immed = (immediate_type) immedData_value(instr.immed_data); - instruction_write_immedInstr(bf, ii); - break; - } - break; - case jump_instr_type: - jump_instr_t ji; - ji.op = instr.opcode; - ji.addr = (address_type) immedData_value(instr.immed_data); - instruction_write_jumpInstr(bf, ji); - break; - default: - bail_with_error("Bad instr_type in assembleInstr (%d)!", instr.itype); - break; - } -} - -// return the size (in words) of the data section's declarations -unsigned int assemble_dataSection_words(ast_data_section_t ds) -{ - return assemble_staticDecls_words(ds.staticDecls); -} - -// return the size (in words) of the given static declarations -unsigned int assemble_staticDecls_words(ast_static_decls_t sds) -{ - int ret = 0; - ast_static_decl_t *dcl = sds.decls; - while (dcl != NULL) { - ret += assemble_staticDecl_words(*dcl); - dcl = dcl->next; - } - return ret; -} - -// return the size (in words) of the given static declarations -unsigned int assemble_staticDecl_words(ast_static_decl_t sd) -{ - return sd.size_in_words; -} - -// Assemble the code for the given AST, with output going to bf -void assembleDataSection(BOFFILE bf, ast_data_section_t ds) -{ - assembleStaticDecls(bf, ds.staticDecls); -} - -// Assemble the code for the given AST, with output going to bf -void assembleStaticDecls(BOFFILE bf, ast_static_decls_t sds) -{ - ast_static_decl_t *dcl = sds.decls; - while (dcl != NULL) { - assembleStaticDecl(bf, *dcl); - dcl = dcl->next; - } -} - -// Assemble the code for the given AST, with output going to bf -void assembleStaticDecl(BOFFILE bf, ast_static_decl_t dcl) -{ - switch (dcl.initializer.kind) { - case initzlr_k_number: case initzlr_k_char: - bof_write_word(bf, dcl.initializer.num_value); - break; - case initzlr_k_string: - bof_write_bytes(bf, dcl.initializer.byte_size, - dcl.initializer.str_value); - // pad to word-align the space for the string - int padding_needed = ((dcl.size_in_words * BYTES_PER_WORD) - - dcl.initializer.byte_size); - assert(padding_needed >= 0); - assert(((dcl.initializer.byte_size + padding_needed) - % BYTES_PER_WORD) == 0); - int zeros[2] = {0, 0}; - for (int i = 0; i < padding_needed; i++) { - bof_write_bytes(bf, 1, zeros); - } - break; - case initzlr_k_none: - for (int i = 0; i < (dcl.size_in_words); i++) { - bof_write_word(bf, 0); - } - break; - default: - bail_with_error("Unknown declaration kind (%d) in assembleStaticDecl!", - dcl.initializer.kind); - break; - } -} diff --git a/vm/assemble.h b/vm/assemble.h deleted file mode 100755 index dd3c67d..0000000 --- a/vm/assemble.h +++ /dev/null @@ -1,41 +0,0 @@ -/* $Id: assemble.h,v 1.10 2024/07/28 22:01:51 leavens Exp $ */ -#ifndef _ASSEMBLE_H -#define _ASSEMBLE_H -#include -#include "ast.h" -#include "bof.h" - -// Generate code for prog, with output going to bf -extern void assembleProgram(BOFFILE bf, ast_program_t prog); - -// Generate code for the given AST, with output going to bf -extern void assembleTextSection(BOFFILE bf, ast_text_section_t ts); - -// Generate code for the given AST, with output going to bf -extern void assembleAsmInstrs(BOFFILE bf, ast_asm_instrs_t instrs); - -// Generate code for the given AST, with output going to bf -extern void assembleAsmInstr(BOFFILE bf, ast_asm_instr_t instr); - -// Generate code for the given AST, with output going to bf -extern void assembleInstr(BOFFILE bf, ast_instr_t instr); - -// return the size (in words) of the data section's declarations -extern unsigned int assemble_dataSection_words(ast_data_section_t ds); - -// return the size (in words) of the given static declarations -extern unsigned int assemble_staticDecls_words(ast_static_decls_t sds); - -// return the size (in words) of the given static declaration -extern unsigned int assemble_staticDecl_words(ast_static_decl_t sd); - -// Generate code for the given AST, with output going to bf -extern void assembleDataSection(BOFFILE bf, ast_data_section_t ds); - -// Generate code for the given AST, with output going to bf -extern void assembleStaticDecls(BOFFILE bf, ast_static_decls_t sds); - -// Generate code for the given AST, with output going to bf -extern void assembleStaticDecl(BOFFILE bf, ast_static_decl_t dcl); - -#endif diff --git a/vm/ast.c b/vm/ast.c deleted file mode 100755 index 34d482d..0000000 --- a/vm/ast.c +++ /dev/null @@ -1,547 +0,0 @@ -/* $Id: ast.c,v 1.44 2024/08/29 00:06:21 leavens Exp $ */ -#include -#include -#include "utilities.h" -#include "ast.h" -#include "lexer.h" - -// Return (a pointer to) the file location from an AST -const file_location *ast_file_loc(AST t) { - return t.generic.file_loc; -} - -// Return the filename from the AST t -const char *ast_filename(AST t) { - return ast_file_loc(t)->filename; -} - -// Return the line number from the AST t -unsigned int ast_line(AST t) { - return ast_file_loc(t)->line; -} - -// Return the type tag of the AST t -AST_type ast_type_tag(AST t) { - return t.generic.type_tag; -} - -// Return an AST for a program, -// which contains the given ASTs. -ast_program_t ast_program(ast_text_section_t textSec, - ast_data_section_t dataSec, - ast_stack_section_t stackSec) -{ - ast_program_t ret; - ret.file_loc = textSec.file_loc; - ret.type_tag = program_ast; - ret.textSection = textSec; - ret.dataSection = dataSec; - ret.stackSection = stackSec; - return ret; -} - -// Return an AST for the text section -// with the given entry point and instructions. -ast_text_section_t ast_text_section(ast_token_t tok, ast_addr_t entryPoint, - ast_asm_instrs_t instrs) -{ - ast_text_section_t ret; - ret.file_loc = file_location_copy(tok.file_loc); - ret.type_tag = text_section_ast; - ret.entryPoint = entryPoint; - ret.instrs = instrs; - return ret; -} - -// Return an AST for an entry point -// that represents the label given -ast_addr_t ast_addr_label(ast_ident_t label) -{ - ast_addr_t ret; - ret.file_loc = file_location_copy(label.file_loc); - ret.type_tag = addr_ast; - ret.address_defined = false; - ret.label = label.name; - ret.addr = 0; - return ret; -} - -// Return an AST for an entry point -// that represents the address given -ast_addr_t ast_entry_addr(ast_unsignednum_t addr) -{ - ast_addr_t ret; - ret.file_loc = file_location_copy(addr.file_loc); - ret.type_tag = addr_ast; - ret.address_defined = true; - ret.label = NULL; - ret.addr = addr.value; - return ret; -} - -// Return an AST for an asm instr AST -// with the given label-opt and instruction -ast_asm_instr_t ast_asm_instr(ast_label_opt_t labelOpt, ast_instr_t instr) -{ - ast_asm_instr_t ret; - ret.file_loc = labelOpt.file_loc; - ret.type_tag = asm_instr_ast; - ret.next = NULL; - ret.label_opt = labelOpt; - ret.instr = instr; - return ret; -} - -// Return an AST for a singleton asm instrs AST -// with the given instruction -ast_asm_instrs_t ast_asm_instrs_singleton(ast_asm_instr_t asminstr) -{ - ast_asm_instrs_t ret; - ret.file_loc = asminstr.file_loc; - ret.type_tag = asm_instrs_ast; - ast_asm_instr_t *p = (ast_asm_instr_t *)malloc(sizeof(ast_asm_instr_t)); - if (p == NULL) { - bail_with_error("Cannot allocate space for an asm_instr!"); - } - *p = asminstr; - p->next = NULL; - ret.instrs = p; - return ret; -} - -// Return an AST made from adding instr to the end of lst -ast_asm_instrs_t ast_asm_instrs_add(ast_asm_instrs_t lst, ast_asm_instr_t asminstr) -{ - ast_asm_instrs_t ret = lst; - ast_asm_instr_t *p = (ast_asm_instr_t *)malloc(sizeof(ast_asm_instr_t)); - if (p == NULL) { - bail_with_error("Cannot allocate space for an asm_instr!"); - } - *p = asminstr; - p->next = NULL; - // splice p onto the end of lst.instrs - ast_asm_instr_t *last = ast_last_list_elem(lst.instrs); - if (last == NULL) { - ret.instrs = p; - } else { - last->next = p; - } - return ret; -} - -// Requires: id.name != NULL. -// Return an AST for a label_opt AST -// with the given identifier -ast_label_opt_t ast_label_opt_label(ast_ident_t id) -{ - ast_label_opt_t ret; - ret.file_loc = file_location_copy(id.file_loc); - ret.type_tag = label_opt_ast; - ret.name = id.name; - return ret; -} - -// Return an AST for a label_opt AST -// with the empty AST (t) -ast_label_opt_t ast_label_opt_empty(ast_empty_t t) -{ - ast_label_opt_t ret; - ret.file_loc = file_location_copy(t.file_loc); - ret.type_tag = label_opt_ast; - ret.name = NULL; - return ret; -} - -// Return an immediate data holding a number -ast_immedData_t ast_immed_number(word_type n) { - ast_immedData_t ret; - ret.id_data_kind = id_number; - ret.data.immed = n; - return ret; -} - -// Return an immediate data holding an unsigned int -ast_immedData_t ast_immed_unsigned(unsigned int u) { - ast_immedData_t ret; - ret.id_data_kind = id_unsigned; - ret.data.uimmed = u; - return ret; -} - -// Requires: toknum is the token number of a system call operation. -// Return an immedidate data holding a system call code for t -extern ast_immedData_t ast_syscall_code_for(int toknum) -{ - ast_immedData_t ret; - ret.id_data_kind = id_syscall_code; - ret.data.syscall_code - = (syscall_type) instruction_token2SyscallCode(toknum); - return ret; -} - -// Return an immediate data holding an address -ast_immedData_t ast_immed_addr(ast_addr_t a) { - ast_immedData_t ret; - ret.id_data_kind = id_addr; - ret.data.addr = a; - return ret; -} - -// Return an immediate data that is nothing -ast_immedData_t ast_immed_none() { - ast_immedData_t ret; - ret.id_data_kind = id_empty; - return ret; -} - -// Return an instruction AST for a (no-argument) instruction -ast_instr_t ast_0arg_instr(ast_token_t op) -{ - ast_instr_t ret; - ret.file_loc = file_location_copy(op.file_loc); - ret.type_tag = instr_ast; - ret.next = NULL; - ret.opname = op.text; - ret.opcode = lexer_token2opcode(op.toknum); - assert(op.toknum != noopsym || ret.opcode == COMP_O); - if (ret.opcode == COMP_O) { - ret.itype = comp_instr_type; - ret.func = lexer_token2func(op.toknum); - } else if (ret.opcode == OTHC_O) { - ret.itype = other_comp_instr_type; - ret.func = lexer_token2func(op.toknum); - } else { - // the func code is not used with other instruction types - ret.itype = jump_instr_type; - ret.func = 0; - } - ret.regs_used = 0; - ret.reg = 0; // not really needed - ret.offset = 0; // not really needed - ret.reg2 = 0; // not really needed - ret.offset2 = 0; // not really needed - ret.immed_data = ast_immed_none(); - return ret; -} - -// Return an instruction AST -// for a (2-register) computational instruction -ast_instr_t ast_2reg_instr(ast_token_t op, - unsigned short rt, offset_type ot, - unsigned short rs, offset_type os, - func_type func) -{ - ast_instr_t ret; - ret.file_loc = file_location_copy(op.file_loc); - ret.type_tag = instr_ast; - ret.next = NULL; - ret.itype = comp_instr_type; // only this type has 2 registers & 2 offsets - ret.opname = op.text; - ret.opcode = lexer_token2opcode(op.toknum); - ret.func = func; - ret.regs_used = 2; - ret.reg = rt; - ret.offset = ot; - ret.reg2 = rs; - ret.offset2 = os; - ret.immed_data = ast_immed_none(); - return ret; -} - -// Return an AST for an instruction -// with the given information -ast_instr_t ast_1reg_instr(ast_token_t op, instr_type itype, - unsigned short num_regs_used, - unsigned short reg, offset_type offset, - func_type func, ast_immedData_t im) -{ - ast_instr_t ret; - ret.file_loc = file_location_copy(op.file_loc); - ret.type_tag = instr_ast; - ret.next = NULL; - ret.itype = itype; - ret.opname = op.text; - ret.opcode = lexer_token2opcode(op.toknum); - ret.func = func; - ret.regs_used = num_regs_used; - switch (num_regs_used) { - case 0: - ret.reg = 0; - ret.offset = 0; - break; - case 1: - ret.reg = reg; - ret.offset = offset; - break; - default: - bail_with_error("ast_1reg_instr called with unknown number of registers!"); - break; - } - ret.immed_data = im; - ret.reg2 = 0; // reg2 is not used - ret.offset2 = 0; // offset2 is not used - return ret; -} - -// Return an AST for the data section AST -// with the given list of static declarations. -ast_data_section_t ast_data_section(ast_token_t kw, unsigned int static_start, - ast_static_decls_t staticDecls) -{ - ast_data_section_t ret; - ret.file_loc = file_location_copy(kw.file_loc); - ret.type_tag = data_section_ast; - ret.static_start_addr = static_start; - ret.staticDecls = staticDecls; - return ret; -} - -// Return an AST for an empty list of static decls -ast_static_decls_t ast_static_decls_empty(ast_empty_t e) -{ - ast_static_decls_t ret; - ret.file_loc = file_location_copy(e.file_loc); - ret.type_tag = static_decls_ast; - ret.decls = NULL; - return ret; -} - -// Return an AST for a list of static declarations -// with sd added to the end of sds -ast_static_decls_t ast_static_decls_add(ast_static_decls_t sds, - ast_static_decl_t sd) -{ - ast_static_decls_t ret = sds; - ast_static_decl_t *p = (ast_static_decl_t *)malloc(sizeof(ast_static_decl_t)); - if (p == NULL) { - bail_with_error("Cannot allocate space for a static_decl!"); - } - *p = sd; - p->next = NULL; - // splice p onto the end of sds.decls - ast_static_decl_t *last = ast_last_list_elem(sds.decls); - if (last == NULL) { - ret.decls = p; - } else { - last->next = p; - } - return ret; -} - -// Return an AST for a data size delclarator -// for the given number of words -ast_data_size_t ast_data_size(ast_token_t kw, data_size_e dse, - unsigned short words) -{ - extern char *strdup(const char *s); - ast_data_size_t ret; - ret.file_loc = file_location_copy(kw.file_loc); - ret.type_tag = data_size_ast; - ret.dse = dse; - ret.size_name = strdup(kw.text); - ret.size_in_words = words; - return ret; -} - -// Requires: init.byte_size <= (ds.size_in_words * BYTES_PER_WORD). -// Return an AST for a static declaration -// with the given data size, identifier, and initializer. -// Note that the size is taken from the ds argument, not the initializer. -ast_static_decl_t ast_static_decl(ast_data_size_t ds, - ast_ident_t ident, - ast_initializer_opt_t init) -{ - ast_static_decl_t ret; - ret.file_loc = file_location_copy(ds.file_loc); - ret.type_tag = static_decl_ast; - ret.next = NULL; - ret.size_in_words = ds.size_in_words; - if (init.kind != initzlr_k_none) { - // give an error if the declared size and initializer don't match - // TODO: move these checks to a static checking pass - if (init.byte_size > (ds.size_in_words * BYTES_PER_WORD)) { - // assert(init.file_loc != NULL); - fprintf(stderr, "Initializer size (%u bytes) is too big for declared data size (%u bytes)!\n", - init.byte_size, (ds.size_in_words * BYTES_PER_WORD)); - if (init.str_value != NULL) { - fprintf(stderr, "Note: initializer string is %s\n", init.str_value); - } - } - } - ret.dse = ds.dse; - switch (ds.dse) { - case ds_word: - if (init.kind == initzlr_k_string) { - bail_with_prog_error(*(init.file_loc), - "Using a string initializer for word data!"); - } - break; - case ds_char: - if (init.kind == initzlr_k_string) { - bail_with_prog_error(*(init.file_loc), - "Using a string initializer for char data!"); - } else if (init.kind == initzlr_k_number) { - bail_with_prog_error(*(init.file_loc), - "Using a word initializer for char data!"); - } - break; - case ds_string: - if (init.kind != initzlr_k_string) { - bail_with_prog_error(*(init.file_loc), - "String data requires a string initializer!"); - } - break; - } - ret.size_name = ds.size_name; - ret.ident = ident; - ret.initializer = init; - return ret; -} - -// Return an AST for an initializer with the given number -ast_initializer_opt_t ast_initializer_number(ast_token_t eqs, - word_type value) -{ - ast_initializer_opt_t ret; - ret.file_loc = file_location_copy(eqs.file_loc); - ret.type_tag = initializer_opt_ast; - ret.kind = initzlr_k_number; - ret.byte_size = BYTES_PER_WORD; - ret.num_value = value; - return ret; -} - -// Return an AST for an initializer with the given char literal -ast_initializer_opt_t ast_initializer_char(ast_token_t eqs, - char c) -{ - ast_initializer_opt_t ret; - ret.file_loc = file_location_copy(eqs.file_loc); - ret.type_tag = initializer_opt_ast; - ret.kind = initzlr_k_char; - ret.byte_size = BYTES_PER_WORD; // make it word aligned - ret.num_value = c; - return ret; -} - -// Return an AST for an initializer with the given string literal -ast_initializer_opt_t ast_initializer_string(ast_token_t eqs, - const char *s) -{ - ast_initializer_opt_t ret; - ret.file_loc = file_location_copy(eqs.file_loc); - ret.type_tag = initializer_opt_ast; - ret.kind = initzlr_k_string; - ret.byte_size = strlen(s) + 1; // add 1 for null char at end - ret.str_value = s; - return ret; -} - - -// Return an AST for an empty initializer -ast_initializer_opt_t ast_initializer_empty(ast_empty_t e) -{ - ast_initializer_opt_t ret; - ret.file_loc = file_location_copy(e.file_loc); - ret.type_tag = initializer_opt_ast; - ret.kind = initzlr_k_none; - // the other fields should not be used when the kind is as above - return ret; -} - -// Return an AST for empty found in the file named fn, on line ln -ast_empty_t ast_empty(const char *fn, unsigned int ln) -{ - ast_empty_t ret; - ret.file_loc = file_location_make(fn, ln); - ret.type_tag = empty_ast; - return ret; -} - -// Return an AST for a stack section AST -// with the given keyword and stack bottom address. -ast_stack_section_t ast_stack_section(ast_token_t kw, - unsigned int stack_bottom) -{ - ast_stack_section_t ret; - ret.file_loc = file_location_copy(kw.file_loc); - ret.type_tag = stack_section_ast; - ret.stack_bottom_addr = stack_bottom; - return ret; -} - -// Return an AST for an identifier -// found in the file named fn, on line ln, with the given name. -ast_ident_t ast_ident(const char *fn, unsigned int ln, const char *name) -{ - ast_ident_t ret; - ret.file_loc = file_location_make(fn, ln); - ret.type_tag = ident_ast; - ret.name = name; - return ret; -} - -// Return an AST for a (signed) number with the given value -ast_number_t ast_number(ast_token_t sgn, word_type value) -{ - ast_number_t ret; - ret.file_loc = file_location_copy(sgn.file_loc); - ret.type_tag = number_ast; - ret.value = value; - return ret; -} - -// Return an AST for an (unsigned) number -// with the given value -ast_unsignednum_t ast_unsignednum(const char *fn, unsigned int ln, - unsigned int value) -{ - ast_unsignednum_t ret; - ret.file_loc = file_location_make(fn, ln); - ret.type_tag = unsignednum_ast; - ret.value = value; - return ret; -} - -// Return an AST for a token -ast_token_t ast_token(const char *fn, unsigned int ln, int token_code) -{ - ast_token_t ret; - ret.file_loc = file_location_make(fn, ln); - ret.type_tag = token_ast; - ret.toknum = token_code; - return ret; -} - -// Requires: lst is a pointer to a non-circular linked list with next pointers -// in the same relative position as ast_generic_t -// Return a pointer to the last element in lst. -// This only returns NULL if lst == NULL. -void *ast_last_list_elem(void *lst) -{ - if (lst == NULL) { - return lst; - } - // assert lst is not NULL - void *prev = NULL; - while (lst != NULL) { - prev = lst; - lst = ((ast_generic_t *)lst)->next; - } - // here lst == NULL; - return prev; -} - -// Requires: lst is a pointer to a non-circular linked list with next pointers -// in the same relative position as ast_generic_t -// Return the number of elements in the linked list lst -extern int ast_list_length(void *lst) -{ - int ret = 0; - ast_generic_t *p = (ast_generic_t *) lst; - while (p != NULL) { - p = p->next; - ret++; - } - return ret; -} diff --git a/vm/ast.h b/vm/ast.h deleted file mode 100755 index 8826ea1..0000000 --- a/vm/ast.h +++ /dev/null @@ -1,422 +0,0 @@ -/* $Id: ast.h,v 1.35 2024/09/25 15:45:15 leavens Exp $ */ -#ifndef _AST_H -#define _AST_H -#include -#include "machine_types.h" -#include "file_location.h" -#include "instruction.h" - -// types of ASTs (type tags) -typedef enum { - program_ast, text_section_ast, addr_ast, asm_instr_ast, - asm_instrs_ast, label_opt_ast, empty_ast, instr_ast, - data_section_ast, data_size_ast, - static_decls_ast, static_decl_ast, initializer_opt_ast, - stack_section_ast, ident_ast, number_ast, unsignednum_ast, - reg_ast, token_ast, char_literal_ast, string_literal_ast -} AST_type; - -// forward declaration, so can use the type AST* below -typedef union AST_u AST; - -// The following types for structs named N_t -// are used in the declaration of the AST_u union below. -// The struct N_t is the type of information kept in the AST -// that is related to the nonterminal N in the abstract syntax. - -// The generic struct type (ast_generic_t) has the fields that -// should be in all alternatives of the AST union type (AST_u) -// (although the next field is only needed for those that can be in lists). -typedef struct { - file_location *file_loc; - AST_type type_tag; // says what field of the union is active - void *next; // for lists -} ast_generic_t; - -// empty ::= -typedef struct { - file_location *file_loc; - AST_type type_tag; -} ast_empty_t; - -// label ::= ident -typedef struct { - file_location *file_loc; - AST_type type_tag; - const char *name; -} ast_ident_t; - -// (signed) numbers (and offsets) -typedef struct { - file_location *file_loc; - AST_type type_tag; - word_type value; -} ast_number_t; - -// unsigned numbers -typedef struct { - file_location *file_loc; - AST_type type_tag; - const char *text; - uword_type value; -} ast_unsignednum_t; - -// registers -typedef struct { - file_location *file_loc; - AST_type type_tag; - const char *text; - unsigned short number; -} ast_reg_t; - -typedef enum { ds_word, ds_char, ds_string } data_size_e; - -// dataSize ::= WORD | CHAR | STRING [ ] -typedef struct { - file_location *file_loc; - AST_type type_tag; - data_size_e dse; - const char *size_name; - unsigned short size_in_words; -} ast_data_size_t; - -// tokens as ASTs -typedef struct { - file_location *file_loc; - AST_type type_tag; - const char *text; - int toknum; -} ast_token_t; - -// char literals as ASTs -typedef struct { - file_location *file_loc; - AST_type type_tag; - char value; -} ast_charliteral_t; - -// string literals as ASTs -typedef struct { - file_location *file_loc; - AST_type type_tag; - const char *pointer; -} ast_stringliteral_t; - - -// label-opt ::= label | empty -typedef struct { - file_location *file_loc; - AST_type type_tag; - const char *name; // NULL if there was no label -} ast_label_opt_t; - -// addr ::= label | unsigned-number -typedef struct { - file_location *file_loc; - AST_type type_tag; - bool address_defined; // has this address gotten a value? - const char *label; // NULL if address_defined (is true) - address_type addr; // 0 if !address_defined -} ast_addr_t; - -// kinds of immediate data -typedef enum { id_number, id_unsigned, id_addr, id_syscall_code, id_empty -} immed_data_kind_t; - -// immed-data ::= number | unsignednum | syscall-code | addr | empty -typedef struct { - immed_data_kind_t id_data_kind; - union { - immediate_type immed; // immediate arguments (not offsets!) - shift_type uimmed; // shifts - syscall_type syscall_code; - ast_addr_t addr; - } data; -} ast_immedData_t; - -// instr ::= no-arg-instr | two-reg-comp-instr | no-target-offset-instr -// | no-source-offset-instr | one-reg-arg-instr | one-reg-offset-instr -// | shift-instr | arg-only-instr | immed-arith-instr -// | immed-bool-astr | branch-test-instr | jump-instr | syscall-instr -typedef struct ast_instr_s { - file_location *file_loc; - AST_type type_tag; - struct ast_instr_s * next; - instr_type itype; - const char *opname; - op_code opcode; - func_type func; // function code for computational instructions - unsigned short regs_used; - reg_num_type reg; - offset_type offset; - reg_num_type reg2; // if there are two of registers - offset_type offset2; - ast_immedData_t immed_data; // includes arg (the number alternative) -} ast_instr_t; - -// asmInstr ::= label-opt instr -typedef struct asm_instr_s { - file_location *file_loc; - AST_type type_tag; - struct asm_instr_s *next; // for lists - ast_label_opt_t label_opt; - ast_instr_t instr; -} ast_asm_instr_t; - -// asmInstrs ::= asmInstr | asmInstrs asmInstr -typedef struct { - file_location *file_loc; - AST_type type_tag; - ast_asm_instr_t *instrs; -} ast_asm_instrs_t; - -// initializer kinds -typedef enum {initzlr_k_number, initzlr_k_char, initzlr_k_string, - initzlr_k_none - } initzlr_k; - -// initializer-opt ::= initializer | empty -typedef struct { - file_location *file_loc; - AST_type type_tag; - initzlr_k kind; - word_type num_value; // for numbers and char-literals - word_type byte_size; // for strings - const char *str_value; // for strings -} ast_initializer_opt_t; - -// staticDecl ::= dataSize ident initializer-opt -typedef struct static_decl_s { - file_location *file_loc; - AST_type type_tag; - struct static_decl_s *next; // for lists - unsigned short size_in_words; - data_size_e dse; - const char *size_name; - ast_ident_t ident; - ast_initializer_opt_t initializer; -} ast_static_decl_t; - -// staticDecls ::= staticDecl* -typedef struct { - file_location *file_loc; - AST_type type_tag; - ast_static_decl_t *decls; -} ast_static_decls_t; - -// text-section ::= entry-point asmInstr* -typedef struct { - file_location *file_loc; - AST_type type_tag; - ast_addr_t entryPoint; - ast_asm_instrs_t instrs; -} ast_text_section_t; - -// data-section ::= static-decl* -typedef struct { - file_location *file_loc; - AST_type type_tag; - address_type static_start_addr; - ast_static_decls_t staticDecls; -} ast_data_section_t; - -// stack-section ::= .stack stack-bottom-addr -typedef struct { - file_location *file_loc; - AST_type type_tag; - address_type stack_bottom_addr; -} ast_stack_section_t; - -// program ::= text-section data-section -typedef struct { - file_location *file_loc; - AST_type type_tag; - ast_text_section_t textSection; - ast_data_section_t dataSection; - ast_stack_section_t stackSection; -} ast_program_t; - -// The actual AST definition: -typedef union AST_u { - ast_generic_t generic; - ast_program_t program; - ast_text_section_t text_section; - ast_addr_t addr; - ast_asm_instrs_t asm_instrs; - ast_asm_instr_t asm_instr; - ast_label_opt_t label_opt; - ast_empty_t empty; - ast_instr_t instr; - ast_data_section_t data_section; - ast_static_decls_t static_decls; - ast_static_decl_t static_decl; - ast_data_size_t data_size; - ast_initializer_opt_t initializer; - ast_stack_section_t stack_section; - ast_ident_t ident; - ast_number_t number; - ast_unsignednum_t unsignednum; - ast_immedData_t immed; - ast_reg_t reg; - ast_token_t token; - ast_charliteral_t charlit; - ast_stringliteral_t stringlit; -} AST; - -// Return (a pointer to) the file location from an AST -extern const file_location *ast_file_loc(AST t); - -// Return the filename from the AST t -extern const char *ast_filename(AST t); - -// Return the line number from the AST t -extern unsigned int ast_line(AST t); - -// Return the type tag of the AST t -extern AST_type ast_type_tag(AST t); - -// Return an AST for a program, -// which contains the given ASTs. -extern ast_program_t ast_program(ast_text_section_t textSec, - ast_data_section_t dataSec, - ast_stack_section_t stackSec); - -// Return an AST for the text section -// with the given entry point and instructions. -extern ast_text_section_t ast_text_section(ast_token_t tok, ast_addr_t entryPoint, - ast_asm_instrs_t instrs); - -// Return an AST for an entry point -// that represents the label given -extern ast_addr_t ast_addr_label(ast_ident_t label); - -// Return an AST for an entry point -// that represents the address given -extern ast_addr_t ast_entry_addr(ast_unsignednum_t addr); - -// Return an AST for an asm instr AST -// with the given label and instruction -extern ast_asm_instr_t ast_asm_instr(ast_label_opt_t label, ast_instr_t instr); - -// Return an AST for a singleton asm instrs AST -// with the given instruction -extern ast_asm_instrs_t ast_asm_instrs_singleton(ast_asm_instr_t asminstr); - -// Return an AST made from adding the given asm instr to the end of lst -extern ast_asm_instrs_t ast_asm_instrs_add(ast_asm_instrs_t lst, ast_asm_instr_t asminstr); - -// Requires: id.name != NULL. -// Return an AST for a label_opt AST -// with the given identifier -extern ast_label_opt_t ast_label_opt_label(ast_ident_t id); - -// Return an AST for a label_opt AST -// with the empty AST (t) -extern ast_label_opt_t ast_label_opt_empty(ast_empty_t t); - -// Return an immediate data holding a number -extern ast_immedData_t ast_immed_number(word_type n); - -// Return an immediate data holding an unsigned int -extern ast_immedData_t ast_immed_unsigned(unsigned int u); - -// Requires: toknum is the token number of a system call operation. -// Return an immedidate data holding a system call code for t -extern ast_immedData_t ast_syscall_code_for(int toknum); - -// Return an immediate data holding an address -extern ast_immedData_t ast_immed_addr(ast_addr_t a); - -// Return an immediate data that is nothing -extern ast_immedData_t ast_immed_none(); - -// Return an instruction AST for a (no-argument) instruction -extern ast_instr_t ast_0arg_instr(ast_token_t op); - -// Return an instruction AST -// for a (2-register) computational instruction -extern ast_instr_t ast_2reg_instr(ast_token_t op, - unsigned short rt, offset_type ot, - unsigned short rs, offset_type os, - func_type func); - -// Return an AST for an instruction -// with the given information -extern ast_instr_t ast_1reg_instr(ast_token_t op, instr_type itype, - unsigned short num_regs_used, - unsigned short reg, offset_type offset, - func_type func, ast_immedData_t im); - -// Return an AST for the data section AST -// with the given list of static declarations. -extern ast_data_section_t ast_data_section(ast_token_t kw, unsigned int static_start, ast_static_decls_t staticDecls); - -// Return an AST for an empty list of static declarations -extern ast_static_decls_t ast_static_decls_empty(ast_empty_t e); - -// Return an AST for a list of static declarations -// with sd added to the end of sds -extern ast_static_decls_t ast_static_decls_add(ast_static_decls_t sds, - ast_static_decl_t sd); - -// Return an AST for a data size delclarator -// for the given number of words -extern ast_data_size_t ast_data_size(ast_token_t kw, data_size_e dse, - unsigned short words); - -// Requires: init.byte_size <= (ds.size_in_words * BYTES_PER_WORD). -// Return an AST for a static declaration -// with the given data size, identifier, and initializer. -// Note that the size is taken from the ds argument, not the initializer. -extern ast_static_decl_t ast_static_decl(ast_data_size_t ds, - ast_ident_t ident, - ast_initializer_opt_t init); - -// Return an AST for an initializer with the given number -extern ast_initializer_opt_t ast_initializer_number(ast_token_t eqs, - word_type value); - -// Return an AST for an initializer with the given char literal -extern ast_initializer_opt_t ast_initializer_char(ast_token_t eqs, - char c); - -// Return an AST for an initializer with the given string literal -extern ast_initializer_opt_t ast_initializer_string(ast_token_t eqs, - const char *s); - -// Return an AST for an empty initializer -extern ast_initializer_opt_t ast_initializer_empty(ast_empty_t e); - -// Return an AST for empty found in the file named fn, on line ln -extern ast_empty_t ast_empty(const char *fn, unsigned int ln); - -// Return an AST for a stack section AST -// with the given keyword and stack bottom address. -extern ast_stack_section_t ast_stack_section(ast_token_t kw, - unsigned int stack_bottom); - -// found in the file named fn, on line ln, with the given name. -extern ast_ident_t ast_ident(const char *fn, unsigned int ln, const char *name); - -// Return an AST for a (signed) number with the given value -extern ast_number_t ast_number(ast_token_t sgn, word_type value); - -// Return an AST for a (signed) number with the given value -extern ast_unsignednum_t ast_unsigned_number(const char *fn, unsigned int ln, - unsigned int value); - -// Return an AST for a token -extern ast_token_t ast_token(const char *fn, unsigned int ln, int token_code); - -// Requires: lst is a pointer to a non-circular linked list with next pointers -// in the same relative position as ast_generic_t -// Return a pointer to the last element in lst. -// This only returns NULL if lst == NULL. -extern void *ast_last_list_elem(void *lst); - -// Requires: lst is a pointer to a non-circular linked list with next pointers -// in the same relative position as ast_generic_t -// Return the number of elements in the linked list lst -extern int ast_list_length(void *lst); - -#endif diff --git a/vm/bof.c b/vm/bof.c deleted file mode 100755 index 8597cff..0000000 --- a/vm/bof.c +++ /dev/null @@ -1,193 +0,0 @@ -/* $Id: bof.c,v 1.19 2024/07/28 22:01:51 leavens Exp $ */ -// #include -#include -// #include -#include -#include -#include -#include "bof.h" -#include "utilities.h" - -#define MAGIC "BO32" - -// a type for treating bytes as a word -typedef union { - unsigned char buf[BYTES_PER_WORD]; - word_type w; -} word_pun_t; - -// Open filename for reading as a binary file -// Exit the program with an error if this fails, -// otherwise return the BOFFILE struct for the file -BOFFILE bof_read_open(const char *filename) { - BOFFILE bf; - bf.fileptr = fopen(filename, "rb"); - bf.filename = filename; - - if (bf.fileptr == NULL) { - bail_with_error("Error opening file for reading: %s", filename); - } - - return bf; -} - -// Return the size (in bytes) of bf -size_t bof_file_bytes(BOFFILE bf) -{ - struct stat st; - if (stat(bf.filename, &st) < 0) { - bail_with_error("Cannot stat %s to get its size!", bf.filename); - } - ; - return st.st_size; -} - -// Return true just when bf is at its end, false otherwise -bool bof_at_eof(BOFFILE bf) { - return feof(bf.fileptr); -} - -// Requires: bf is open for reading in binary and has -// at least BYTES_PER_WORD bytes in it -// Return the next word from bf -word_type bof_read_word(BOFFILE bf) -{ - word_pun_t b; - assert(!bof_at_eof(bf)); - size_t bytes_read = bof_read_bytes(bf, BYTES_PER_WORD, b.buf); - if (bytes_read == 0) { - bail_with_error( - "Cannot read a word from %s (got %d bytes), at EOF: %d", - bf.filename, bytes_read, bof_at_eof(bf)); - } - return b.w; -} - -// Requires: bf.fileptr is open for reading in binary -// and buf is of size at least bytes -// Read the given number of bytes into buf and return the number of bytes read -size_t bof_read_bytes(BOFFILE bf, size_t bytes, void *buf) { - int elems_read = fread(buf, bytes, 1, bf.fileptr); - return elems_read; -} - -// Requires: bf is open for reading in binary -// Read the header of bf as a BOFHeader and return that header -// If any errors are encountered, exit with an error message. -BOFHeader bof_read_header(BOFFILE bf) { - BOFHeader ret; - size_t rd = fread(&ret, sizeof(ret), 1, bf.fileptr); - if (rd != 1) { - bail_with_error("Cannot read header from %s", bf.filename); - } - if (!bof_has_correct_magic_number(ret)) { - bail_with_error("Wrong magic number code in file '%s'!", - bf.filename); - } - return ret; - /* - bof_read_bytes(bf, MAGIC_BUFFER_SIZE, &ret.magic); - if (strncmp(ret.magic, MAGIC, MAGIC_BUFFER_SIZE) != 0) { - bail_with_error("File %s is not a BOF format file, bad magic number!", - bf.filename); - } - bof_read_bytes(bf, BYTES_PER_WORD, &ret.text_start_address); - bof_read_bytes(bf, BYTES_PER_WORD, &ret.text_length); - bof_read_bytes(bf, BYTES_PER_WORD, &ret.data_start_address); - bof_read_bytes(bf, BYTES_PER_WORD, &ret.data_length); - bof_read_bytes(bf, BYTES_PER_WORD, &ret.stack_bottom_addr); - return ret; - */ -} - -// Requires: f is open for writing -// Write the magic number in hexadecimal notation on f, followed by a newline; -// Note: this is just for help in writing the documentation -/* -void bof_write_magic(FILE *f) { - fprintf(f, "%s", "0x"); - for (int i = 0; i < MAGIC_BUFFER_SIZE; i++) { - fprintf(f, "%x", MAGIC[i]); - } - fprintf(f, "\n"); -} -*/ - -// Open filename for writing as a binary file -// Exit the program with an error if this fails, -// otherwise return the BOFFILE for it. -BOFFILE bof_write_open(const char *filename) { - BOFFILE bf; - bf.fileptr = fopen(filename, "wb"); - bf.filename = filename; - - if (bf.fileptr == NULL) { - bail_with_error("Error opening file for writing: %s", filename); - } - - return bf; -} - -// Requres: bf is open -// Close the given binary file -// Exit the program with an error if this fails. -void bof_close(BOFFILE bf) -{ - if (fclose(bf.fileptr) != 0) { - bail_with_error("Could not close %s", bf.filename); - } -} - - -// Requires: bf is open for writing in binary. -// Write the given word into bf -// Exit the program with an error if this fails. -extern void bof_write_word(BOFFILE bf, word_type w) -{ - word_pun_t b; - b.w = w; - bof_write_bytes(bf, BYTES_PER_WORD, b.buf); -} - -// Requires: bf is open for writing in binary -// and the size of buf is at least bytes -// Write the given number of bytes from buf into f. -// Exit the program with an error if this fails. -void bof_write_bytes(BOFFILE bf, size_t bytes, - const void *buf) { - size_t wr = fwrite(buf, bytes, 1, bf.fileptr); - if (wr != 1) { - bail_with_error("Cannot write %u bytes to %s", bytes, bf.filename); - } -} - -// Requires: bf is open for writing in binary -// Write the given header to f -// Exit the program with an error if this fails. -void bof_write_header(BOFFILE bf, const BOFHeader hdr) { - size_t wr = fwrite(&hdr, sizeof(BOFHeader), 1, bf.fileptr); - if (wr != 1) { - bail_with_error("Canot write header to %s", bf.filename); - } -} - -// Write the (bits of the) magic number into the header bh. -void bof_write_magic_to_header(BOFHeader *bh) -{ - const char *magic = MAGIC; - for (int i = 0; i < MAGIC_BUFFER_SIZE; i++) { - bh->magic[i] = magic[i]; - } - assert(bof_has_correct_magic_number(*bh)); -} - -// Does the given header have the appropriate magic number? -bool bof_has_correct_magic_number(BOFHeader bh) -{ - char buf[MAGIC_BUFFER_SIZE+1]; - for (int i = 0; i < MAGIC_BUFFER_SIZE; i++) { - buf[i] = bh.magic[i]; - } - buf[MAGIC_BUFFER_SIZE] = '\0'; - return (0 == strncmp(buf, MAGIC, MAGIC_BUFFER_SIZE)); -} diff --git a/vm/bof.h b/vm/bof.h deleted file mode 100755 index 70d603c..0000000 --- a/vm/bof.h +++ /dev/null @@ -1,88 +0,0 @@ -/* $Id: bof.h,v 1.22 2024/08/20 00:46:41 leavens Exp $ */ -// Binary Object File Format (for the SSM) -#ifndef _BOF_H -#define _BOF_H -#include -#include -#include -#include "machine_types.h" - -#define MAGIC_BUFFER_SIZE 4 - -typedef struct { // Field magic should hold value of MAGIC (with no null char) - char magic[MAGIC_BUFFER_SIZE]; - word_type text_start_address; // word address to start running (PC) - word_type text_length; // size of the text section in words - word_type data_start_address; // word address of static data (GP) - word_type data_length; // size of data section in words - word_type stack_bottom_addr; // word address of stack "bottom" (FP) -} BOFHeader; - -// a type for Binary Output Files -typedef struct { - FILE *fileptr; - const char *filename; -} BOFFILE; - -// Open filename for reading as a binary file -// Exit the program with an error if this fails, -// otherwise return the FILE pointer to the open file. -extern BOFFILE bof_read_open(const char *filename); - -// Return the size (in bytes) of bf -extern size_t bof_file_bytes(BOFFILE bf); - -// Return true just when bf is at its end, false otherwise -extern bool bof_at_eof(BOFFILE bf); - -// Requires: bf is open for reading in binary and has -// at least 1 word (2 bytes) available to read -// Return the next word from bf -extern word_type bof_read_word(BOFFILE bf); - -// Requires: bf is open for reading in binary and -// buf is of size at least bytes -// Read the given number of bytes into buf and return the number of bytes read -size_t bof_read_bytes(BOFFILE bf, size_t bytes, void *buf); - -// Requires: bf is open for reading in binary -// Read the header of bf as a BOFHeader and return that header -// If any errors are encountered, exit with an error message. -extern BOFHeader bof_read_header(BOFFILE); - -// Open filename for writing as a binary file -// Exit the program with an error if this fails, -// otherwise return the BOFFILE for it. -extern BOFFILE bof_write_open(const char *filename); - -// Requres: bf is open -// Close the given binary file -// Exit the program with an error if this fails. -extern void bof_close(BOFFILE bf); - -// Requires: bf is open for writing in binary -// Write the given word into bf. -// Exit the program with an error if this fails. -extern void bof_write_word(BOFFILE bf, word_type w); - -// Requires: bf is open for writing in binary -// and the size of buf is at least bytes -// Write the given number of bytes from buf into f. -// Exit the program with an error if this fails. -extern void bof_write_bytes(BOFFILE bf, size_t bytes, - const void *buf); - -// Requires: bf is open for writing in binary -// Write the given header to f -// Exit the program with an error if this fails. -extern void bof_write_header(BOFFILE bf, const BOFHeader hdr); - -// Write the (bits of the) magic number into the header *bh. -extern void bof_write_magic_to_header(BOFHeader *bh); - -// Does the given header have the appropriate magic number? -bool bof_has_correct_magic_number(BOFHeader bh); - -// The following line is for the manual (i.e., the document itself)y -// ... -#endif diff --git a/vm/bof_bin_dump.c b/vm/bof_bin_dump.c deleted file mode 100755 index 1da4be4..0000000 --- a/vm/bof_bin_dump.c +++ /dev/null @@ -1,70 +0,0 @@ -#include -#include -#include -#include "bof.h" -#include "machine_types.h" -#include "utilities.h" - -#define BITS_PER_BYTE 8 -#define BUFF_SIZE (BITS_PER_BYTE*sizeof(word_type) + 1) - -/* Requires: buff has size at least (BITS_PER_BYTE*sizeof(word_type)+1). - Put binary digit characters corresponding to val into buff - Modified from https://stackoverflow.com/questions/699968/display-the-binary-representation-of-a-number-in-c -*/ -static const char *binrep (unsigned int val, char *buff) { - char *pbuff = buff; - int bit_sz = BITS_PER_BYTE * sizeof(word_type); // bit size - - /* Work from the end of the buffer back. */ - pbuff += bit_sz; - *pbuff-- = '\0'; - - /* For each bit (going backwards) store character. */ - while (1) { - if (bit_sz-- < 0) { // when previous bit size was 0, so did 0th bit - return buff; - } - *pbuff-- = ((val & 1) ? '1' : '0'); - /* Get next bit. */ - val >>= 1; - } -} - - -// Print a usage message on stderr and exit with exit code 1. -static void usage(const char *cmdname) -{ - bail_with_error("Usage: %s file.bof", cmdname); -} - - -int main(int argc, char *argv[]) { - if (argc >= 2) { - BOFFILE bf = bof_read_open(argv[1]); - size_t siz = bof_file_bytes(bf); // size in bytes - char *suffix = strchr(argv[1], '.'); - if (suffix == NULL || strncmp(suffix, ".bof", 4) != 0) { - usage(argv[0]); - } - - char bits_buff[BUFF_SIZE]; - printf("Addr\t= Binary\t\t\t\t= Unsigned\t= Signed\t= Hexadecimal\n"); - for (address_type a = 0; - a*BYTES_PER_WORD < siz && !bof_at_eof(bf); a++) { - if (a == sizeof(BOFHeader) / BYTES_PER_WORD) { - printf("---- end of header ----\n"); - } - word_type w = bof_read_word(bf); - printf("%hu:", a / BYTES_PER_WORD); - printf("\t= %s", binrep((unsigned int) w, - bits_buff)); - printf("\t= %10u", w); - printf("\t= %10d", w); - printf("\t= 0x%x\n", w); - } - } else { - bail_with_error("Cannot read %s!", argv[1]); - } - return EXIT_SUCCESS; -} diff --git a/vm/char_utilities.c b/vm/char_utilities.c deleted file mode 100755 index b0b17db..0000000 --- a/vm/char_utilities.c +++ /dev/null @@ -1,158 +0,0 @@ -// $Id: char_utilities.c,v 1.4 2024/07/26 02:31:21 leavens Exp $ -#include -#include -#include "char_utilities.h" -#include "utilities.h" - -// strdup seems to be in the string library but not in the header... -extern char *strdup(const char *s); - -// return the value of the given character literal -// and set *charlit_len to the number of characters in the literal read -unsigned char char_utilities_char_value(const char *lit, - int *charlit_len) -{ - int len = strlen(lit); - assert(len > 0); - if (len < 2 || lit[0] != '\\') { - *charlit_len = 1; - return lit[0]; - } - // now we know that lit[0] is a backslash - *charlit_len = 2; // adjusted below for octal and hex literals - // lit is an escape sequence, with lit[0] == '\\' - switch (lit[1]) { - case 'n': - return '\n'; - break; - case 'r': - return '\r'; - break; - case 'f': - return '\f'; - break; - case 't': - return '\t'; - break; - case 'v': - return '\v'; - break; - case '0': - if (len == 2 || (len > 2 && !is_octal_digit(lit[3]))) { - return '\0'; - } else { - // octal escape sequence - unsigned int val; - sscanf(lit+2, "%o", &val); - int digits_after_0 = 0; - while (is_octal_digit(lit[2+digits_after_0])) { - digits_after_0++; - } - *charlit_len = 2 + digits_after_0; - return (unsigned char)val; - } - break; - case 'a': - return '\a'; - break; - case 'b': - return '\b'; - break; - case '\\': - return '\\'; - break; - case '\'': - return '\''; - break; - case '\"': - return '\"'; - break; - case 'x': - // hex escape sequence - unsigned int val; - sscanf(lit+2, "%x", &val); - int digits_after_x = 0; - while (isxdigit((int)lit[2+digits_after_x])) { - digits_after_x++; - } - *charlit_len = 2 + digits_after_x; - return (unsigned char)val; - break; - default: - return (unsigned char)lit[1]; - break; - } -} - -// Return the given char as a string -// or, if it's not printable, then return a literal string for it -const char *char_utilities_unescape_char(unsigned char c) -{ - char unescape_buf[20]; // allow for longer octal escapes (for errors) - if (isprint(c) && c != '\\' && c != '\n' && c != '\'' && c != '\"') { - sprintf(unescape_buf, "%c", c); - } else { - switch (c) { - case '\n': - sprintf(unescape_buf, "\\n"); - break; - case '\r': - sprintf(unescape_buf, "\\r"); - break; - case '\f': - sprintf(unescape_buf, "\\f"); - break; - case '\t': - sprintf(unescape_buf, "\\t"); - break; - case '\v': - sprintf(unescape_buf, "\\v"); - break; - case '\0': - sprintf(unescape_buf, "\\0"); - break; - case '\a': - sprintf(unescape_buf, "\\a"); - break; - case '\b': - sprintf(unescape_buf, "\\b"); - break; - case '\\': - sprintf(unescape_buf, "\\\\"); - break; - case '\'': - sprintf(unescape_buf, "\\'"); - break; - case '\"': - sprintf(unescape_buf, "\\\""); - break; - default: - sprintf(unescape_buf, "\\0%o", c); - break; - } - } - return strdup(unescape_buf); -} - -#define UNESTRBUFSIZE 4096 - -// Return the given string as a string with only -// printable characters and escape sequences -const char *char_utilities_unescape_string(const char *s) -{ - char buf[UNESTRBUFSIZE]; - int len = strlen(s); - int buff_index = 0; - for (int i = 0; i < len; i++) { - buff_index - += sprintf(buf+buff_index, "%s", - char_utilities_unescape_char((unsigned char) s[i])); - } - return strdup(buf); -} - -// Is the given character an octal digit (0-7)? -bool is_octal_digit(char c) -{ - return ('0' <= c && c <= '7'); -} diff --git a/vm/char_utilities.h b/vm/char_utilities.h deleted file mode 100755 index b7bfb8d..0000000 --- a/vm/char_utilities.h +++ /dev/null @@ -1,23 +0,0 @@ -// $Id: char_utilities.h,v 1.3 2024/07/26 02:31:21 leavens Exp $ -#ifndef CHAR_UTILTIES_H -#define CHAR_UTILTIES_H - -#include - -// return the value of the given character literal -// and set *charlit_len to the number of characters in the literal read -extern unsigned char char_utilities_char_value(const char *lit, - int *charlit_len); - -// Return a the given char as a string -// or, if it's not printable, then return a literal string for it -extern const char *char_utilities_unescape_char(unsigned char c); - -// Return the given string as a string with only -// printable characters and escape sequences -extern const char *char_utilities_unescape_string(const char *s); - -// Is the given character an octal digit (0-7)? -extern bool is_octal_digit(char c); - -#endif diff --git a/vm/check-tests.sh b/vm/check-tests.sh deleted file mode 100755 index b2a0a83..0000000 --- a/vm/check-tests.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -: ${PREFIX=lexer_test} -for i in $@ -do - emacs ${PREFIX}${i}.lst ${PREFIX}${i}.asm && emacs ${PREFIX}${i}.asm ${PREFIX}${i}.out -done diff --git a/vm/disasm.c b/vm/disasm.c deleted file mode 100755 index 3857ab7..0000000 --- a/vm/disasm.c +++ /dev/null @@ -1,91 +0,0 @@ -/* $Id: disasm.c,v 1.14 2024/07/28 22:01:51 leavens Exp $ */ -#include -#include "disasm.h" -#include "bof.h" -#include "regname.h" -#include "utilities.h" -#include "instruction.h" - -// Disassemble code from bf, -// with output going to the file out -void disasmProgram(FILE *out, BOFFILE bf) -{ - BOFHeader bh = bof_read_header(bf); - disasmTextSection(out, bf, bh); - disasmDataSection(out, bf, bh); - disasmStackSection(out, bh); - fprintf(out, ".end"); - newline(out); -} - -// Disassemble the text section -// with output going to the file out -void disasmTextSection(FILE *out, BOFFILE bf, BOFHeader bh) -{ - fprintf(out, ".text\t%u", bh.text_start_address); - newline(out); - disasmInstrs(out, bf, bh.text_length); -} - -// Disassemble length instructions from bf -// with output going to the file out -void disasmInstrs(FILE *out, BOFFILE bf, int length) -{ - for (int i = 0; i < length; i++) { - disasmInstr(out, instruction_read(bf), i); - } -} - -// Disassemble the binary instruction bi, which would go at address i -// each instruction has a label of the form a%d:, where %d is the value of i -void disasmInstr(FILE *out, bin_instr_t bi, address_type i) -{ - fprintf(out, "a%d:\t%s", i, instruction_assembly_form(i, bi)); - newline(out); -} - -// Disassemble the data section from bf, based on the information in bh, -// with output going to out -void disasmDataSection(FILE *out, BOFFILE bf, BOFHeader bh) -{ - fprintf(out, ".data\t%u", bh.data_start_address); - newline(out); - disasmStaticDecls(out, bf, bh.data_length); -} - -// Disassemble words_to_read static data words from bf, -// with output going to out -void disasmStaticDecls(FILE *out, BOFFILE bf, int words_to_read) -{ - while (words_to_read >= 1) { - disasmStaticDecl(out, bof_read_word(bf)); - words_to_read--; - } -} - -// count of number of words generated, to get unique names -static int word_count = 0; -// buffer for generated ids -static char id_buf[16]; - -static const char*new_word_id() -{ - sprintf(id_buf, "w%x", word_count); - word_count++; - return id_buf; -} - -// Disassemble the the given word as a static data declaration, -// with output going to out -void disasmStaticDecl(FILE *out, word_type w) -{ - fprintf(out, "WORD %s = %d", new_word_id(), w); - newline(out); -} - -// Disassemble the stack section based on the given header information -void disasmStackSection(FILE *out, BOFHeader bh) -{ - fprintf(out, ".stack\t%u", bh.stack_bottom_addr); - newline(out); -} diff --git a/vm/disasm.h b/vm/disasm.h deleted file mode 100755 index b542d22..0000000 --- a/vm/disasm.h +++ /dev/null @@ -1,37 +0,0 @@ -// $Id: disasm.h,v 1.6 2024/07/25 20:33:43 leavens Exp $ -#ifndef _DISASM_H -#define _DISASM_H -#include "instruction.h" - -// Disassemble code from bf, -// with output going to the file out -extern void disasmProgram(FILE *out, BOFFILE bf); - -// Disassemble the text section -// with output going to the file out -extern void disasmTextSection(FILE *out, BOFFILE bf, BOFHeader bh); - -// Disassemble length instructions from bf -// with output going to the file out -extern void disasmInstrs(FILE *out, BOFFILE bf, int length); - -// Disassemble the binary instruction bi, which would go at address i -// each instruction has a label of the form a%d, where %d is the value of i -extern void disasmInstr(FILE *out, bin_instr_t bi, address_type i); - -// Disassemble the data section from bf, based on the information in bh, -// with output going to out -extern void disasmDataSection(FILE *out, BOFFILE bf, BOFHeader bh); - -// Disassemble words_to_read static data words from bf, -// with output going to out -extern void disasmStaticDecls(FILE *out, BOFFILE bf, int words_to_read); - -// Disassemble the the given word as a static data declaration, -// with output going to out -extern void disasmStaticDecl(FILE *out, word_type w); - -// Disassemble the stack section based on the given header information -extern void disasmStackSection(FILE *out, BOFHeader bh); - -#endif diff --git a/vm/disasm_main.c b/vm/disasm_main.c deleted file mode 100755 index beaa5a0..0000000 --- a/vm/disasm_main.c +++ /dev/null @@ -1,32 +0,0 @@ -/* $Id: disasm_main.c,v 1.3 2023/09/16 12:32:30 leavens Exp $ */ -#include -#include -#include "bof.h" -#include "disasm.h" -#include "utilities.h" - -static char *progname; - -void usage() { - bail_with_error("Usage: %s file.bof", progname); -} - -int main(int argc, char *argv[]) { - // set the program's name - progname = argv[0]; - argc--; - argv++; - - if (argc != 1) { - usage(); - } - - // name of the file to read - const char *bofname = argv[0]; - - BOFFILE bf = bof_read_open(bofname); - - disasmProgram(stdout, bf); - - return EXIT_SUCCESS; -} diff --git a/vm/error_vm_test1.asm b/vm/error_vm_test1.asm deleted file mode 100755 index 8fe88b4..0000000 --- a/vm/error_vm_test1.asm +++ /dev/null @@ -1,9 +0,0 @@ - # $Id: error_vm_test1.asm,v 1.1 2023/09/18 03:32:18 leavens Exp $ - .text start -start: ADDI $0, $t0, 1 - ADD $0, $t0, $fp - EXIT - .data 1024 - .stack 4096 - .end - diff --git a/vm/file_location.c b/vm/file_location.c deleted file mode 100755 index 9cc66e2..0000000 --- a/vm/file_location.c +++ /dev/null @@ -1,31 +0,0 @@ -/* $Id: file_location.c,v 1.3 2023/09/10 13:28:44 leavens Exp $ */ -#include -#include -#include "file_location.h" -#include "utilities.h" - -// Requires: filename != NULL -// Return a (pointer to a) fresh file_location with the given -// information -file_location *file_location_make(const char *filename, - unsigned int line) -{ - file_location *ret = (file_location *) malloc(sizeof(file_location)); - if (ret == NULL) { - bail_with_error("Could not allocate space for a file_location!"); - } - return ret; -} - -// Requires: fl != NULL -// Return a (pointer to a) fresh copy of fl -file_location *file_location_copy(file_location *fl) -{ - file_location *ret = (file_location *) malloc(sizeof(file_location)); - if (ret == NULL) { - bail_with_error("Could not allocate space for a file_location!"); - } - ret->filename = fl->filename; - ret->line = fl->line; - return ret; -} diff --git a/vm/file_location.h b/vm/file_location.h deleted file mode 100755 index 748867d..0000000 --- a/vm/file_location.h +++ /dev/null @@ -1,21 +0,0 @@ -/* $Id: file_location.h,v 1.2 2023/09/09 20:45:49 leavens Exp $ */ -#ifndef _FILE_LOCATION_H -#define _FILE_LOCATION_H - -// location in a source file (useful for error messages) -typedef struct { - const char *filename; - unsigned int line; // of first token -} file_location; - -// Requires: filename != NULL -// Return a (pointer to a) fresh file_location with the given -// information -extern file_location *file_location_make(const char *filename, - unsigned int line); - -// Requires: fl != NULL -// Return a (pointer to a) fresh copy of fl -extern file_location *file_location_copy(file_location *fl); - -#endif diff --git a/vm/hexdump.sh b/vm/hexdump.sh deleted file mode 100755 index e2b1e34..0000000 --- a/vm/hexdump.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -# dump the given file in hex, with a big-endian format -od --endian=big -t x4 "$@" diff --git a/vm/id_attrs.h b/vm/id_attrs.h deleted file mode 100755 index 7995510..0000000 --- a/vm/id_attrs.h +++ /dev/null @@ -1,19 +0,0 @@ -/* $Id: id_attrs.h,v 1.1 2023/09/11 04:19:57 leavens Exp $ */ -#ifndef _ID_ATTRS_H -#define _ID_ATTRS_H - -#include "machine_types.h" -#include "file_location.h" - -// Kinds of names in the assembly language -typedef enum {id_label, id_data} id_attr_kind; - -// attributes of a name in the assembly language -typedef struct { - const char *name; - id_attr_kind kind; - file_location *file_loc; - address_type addr; // offset from start of text or data section -} id_attrs; - -#endif diff --git a/vm/id_attrs_assoc.h b/vm/id_attrs_assoc.h deleted file mode 100755 index e422a43..0000000 --- a/vm/id_attrs_assoc.h +++ /dev/null @@ -1,19 +0,0 @@ -/* $Id: id_attrs_assoc.h,v 1.3 2024/07/29 02:01:32 leavens Exp $ */ -#ifndef _ID_ATTRS_ASSOC_H -#define _ID_ATTRS_ASSOC_H - -#include "machine_types.h" -#include "file_location.h" - -// Kinds of names in the assembly language -typedef enum {id_label, id_data} id_attr_kind; - -// attributes of a name in the assembly language -typedef struct { - const char *name; - id_attr_kind kind; - file_location *file_loc; - address_type addr; // word offset from start of text or data section -} id_attrs_assoc; - -#endif diff --git a/vm/instruction.c b/vm/instruction.c deleted file mode 100755 index 27513c9..0000000 --- a/vm/instruction.c +++ /dev/null @@ -1,610 +0,0 @@ -// $Id: instruction.c,v 1.61 2024/11/10 14:34:25 leavens Exp $ -#include -#include -#include "bof.h" -#include "instruction.h" -#include "regname.h" -#include "utilities.h" -#include "machine_types.h" -#include "asm.tab.h" - -#define INSTR_BUF_SIZE 512 - -// the following declaration isn't in everywhere ... -extern char *strdup(const char *s); - -// space to hold one instruction's assembly language form -static char instr_buf[INSTR_BUF_SIZE]; - -// Return the instruction type of the given opcode -instr_type instruction_type(bin_instr_t i) { - switch (i.comp.op) { // need to pretend a type to read the op field - case COMP_O: - return comp_instr_type; - break; - case OTHC_O: - if (i.othc.func == SYS_F) { - return syscall_instr_type; - } else { - assert(i.othc.op != COMP_O); - assert(i.othc.func != NOP_F); - return other_comp_instr_type; - } - break; - case ADDI_O: case ANDI_O: case BORI_O: case NORI_O: case XORI_O: - case BEQ_O: case BGEZ_O: case BGTZ_O: case BLEZ_O: case BLTZ_O: - case BNE_O: - return immed_instr_type; - break; - case JMPA_O: case CALL_O: case RTN_O: - return jump_instr_type; - break; - default: - return error_instr_type; - break; - } -} - -// Requires: bof is open for reading in binary -// Read a single instruction (in binary) from bf and return it, -// but exit with an error if there is a problem. -bin_instr_t instruction_read(BOFFILE bf) -{ - bin_instr_t bi; - size_t rd = fread(&bi, sizeof(bi), 1, bf.fileptr); - if (rd != 1) { - bail_with_error("Cannot read instruction from %s (read %d instrs)", - bf.filename, rd); - } - return bi; -} - -// Requires: bf is open for writing in binary -// Write the given binary instruction to bf, -// but exit with an error if there is a problem. -static void write_bin_instr(BOFFILE bf, bin_instr_t i) -{ - size_t wr = fwrite(&i, sizeof(i), 1, bf.fileptr); - if (wr != 1) { - bail_with_error("Cannot write binary instr to %s", bf.filename); - } -} - -// Requires: bof is open for writing in binary -// Write the binary instruction bi to bf in binary, -// but exit with an error if there is a problem. -void instruction_write_bin_instr(BOFFILE bf, bin_instr_t bi) -{ - switch (instruction_type(bi)) { - case comp_instr_type: - instruction_write_compInstr(bf, bi.comp); - break; - case other_comp_instr_type: - instruction_write_otherCompInstr(bf, bi.othc); - break; - case immed_instr_type: - instruction_write_immedInstr(bf, bi.immed); - break; - case jump_instr_type: - instruction_write_jumpInstr(bf, bi.jump); - break; - case syscall_instr_type: - instruction_write_syscallInstr(bf, bi.syscall); - break; - default: - bail_with_error("Unknown instruction type in instruction_write_bin_instr (%d)", - instruction_type(bi)); - break; - } -} - - -// Requires: bof is open for writing in binary -// Write the computational instruction ci to bf in binary, -// but exit with an error if there is a problem. -void instruction_write_compInstr(BOFFILE bf, comp_instr_t ci) -{ - bin_instr_t bi; - bi.comp = ci; - assert(bi.comp.op == ci.op); - assert(bi.comp.rt == ci.rt); - assert(bi.comp.ot == ci.ot); - assert(bi.comp.rs == ci.rs); - assert(bi.comp.os == ci.os); - assert(bi.comp.func == ci.func); - assert(bi.comp.func != NOP_F || bi.comp.op == COMP_O); - write_bin_instr(bf, bi); -} - -// Requires: bof is open for writing in binary -// Write the other computational instruction oci to bf in binary, -// but exit with an error if there is a problem. -void instruction_write_otherCompInstr(BOFFILE bf, other_comp_instr_t oci) -{ - bin_instr_t bi; - bi.othc = oci; - - assert(bi.othc.op == oci.op); - assert(bi.othc.reg == oci.reg); - assert(bi.othc.offset == oci.offset); - assert(bi.othc.arg == oci.arg); - assert(bi.othc.func == oci.func); - - write_bin_instr(bf, bi); -} - -// Requires: bof is open for writing in binary -// Write the system instruction si to bf in binary, -// but exit with an error if there is a problem. -void instruction_write_syscallInstr(BOFFILE bf, syscall_instr_t si) -{ - bin_instr_t bi; - bi.syscall = si; - /* - assert(bi.syscall.op == OTHC_O); - assert(bi.syscall.reg == si.reg); - assert(bi.syscall.offset == si.offset); - assert(bi.syscall.code == si.code); - assert(bi.syscall.func == SYS_F); - */ - write_bin_instr(bf, bi); -} - -// Requires: bof is open for writing in binary -// Write the immediate instruction ii to bf in binary, -// but exit with an error if there is a problem. -void instruction_write_uimmedInstr(BOFFILE bf, uimmed_instr_t ui) -{ - bin_instr_t bi; - bi.uimmed = ui; - /* - assert(bi.uimmed.op == op); - assert(bi.uimmed.reg == ui.reg); - assert(bi.uimmed.offset == ui.offset); - assert(bi.uimmed.uimmed == ui.uimmed); - */ - write_bin_instr(bf, bi); -} - -// Requires: bof is open for writing in binary -// Write the immediate instruction ii to bf in binary, -// but exit with an error if there is a problem. -void instruction_write_immedInstr(BOFFILE bf, immed_instr_t ii) -{ - bin_instr_t bi; - bi.immed = ii; - /* - assert(bi.immed.op == op); - assert(bi.immed.reg == ii.reg); - assert(bi.immed.offset == ii.offset); - assert(bi.immed.immed == ii.immed); - */ - write_bin_instr(bf, bi); -} - -// Requires: bof is open for writing in binary -// Write the jump instruction ji with opcode op to bf in binary, -// but exit with an error if there is a problem. -void instruction_write_jumpInstr(BOFFILE bf, jump_instr_t ji) -{ - bin_instr_t bi; - bi.jump = ji; - /* - assert(bi.jump.op == op); - assert(bi.jump.addr == ji.addr); - */ - write_bin_instr(bf, bi); -} - -// Return the assembly language name (mnemonic) for bi -const char *instruction_mnemonic(bin_instr_t bi) { - switch (bi.comp.op) { // pretending a type is needed to get the op field - case COMP_O: - return instruction_compFunc2name(bi); - break; - case OTHC_O: - return instruction_otherCompFunc2name(bi); - break; - case ADDI_O: - return "ADDI"; - break; - case ANDI_O: - return "ANDI"; - break; - case BORI_O: - return "BORI"; - break; - case NORI_O: - return "NORI"; - break; - case XORI_O: - return "XORI"; - break; - case BEQ_O: - return "BEQ"; - break; - case BGEZ_O: - return "BGEZ"; - break; - case BGTZ_O: - return "BGTZ"; - break; - case BLEZ_O: - return "BLEZ"; - break; - case BLTZ_O: - return "BLTZ"; - break; - case BNE_O: - return "BNE"; - break; - case JMPA_O: - return "JMPA"; - break; - case CALL_O: - return "CALL"; - break; - case RTN_O: - return "RTN"; - break; - default: - bail_with_error("Unknown op code (%d) in instruction_mnemonic!", - bi.immed.op); - return NULL; // should never happen - } - return NULL; // should never happen -} - -static char address_comment_buf[512]; - -// return a comment string of the form -// "# target is word address %u" -// that uses the formAddress function to get the proper address -static const char *instruction_formAddress_comment(address_type addr, - address_type a) -{ - address_type actual = machine_types_formAddress(addr, a); - sprintf(address_comment_buf, "# target is word address %u", - actual); - return strdup(address_comment_buf); -} - - -// Return a string containing the assembly language form of instr, -// which is found at address addr -const char *instruction_assembly_form(address_type addr, - bin_instr_t instr) -{ - char *buf = instr_buf; - - // put in the mnemonic for the instruction - int cwr = sprintf(buf, "%s ", instruction_mnemonic(instr)); - // point buf to the null char that was printed into instr_buf - buf += cwr; - - instr_type it = instruction_type(instr); - switch (it) { - case comp_instr_type: - switch (instr.comp.func) { - case NOP_F: - // no arguments for NOP! - break; - case ADD_F: case SUB_F: case CPW_F: - case AND_F: case BOR_F: case NOR_F: case XOR_F: - case SCA_F: case LWI_F: case NEG_F: - sprintf(buf, "%s, %hd, %s, %hd", - regname_get(instr.comp.rt), - instr.comp.ot, - regname_get(instr.comp.rs), - instr.comp.os); - break; - case CPR_F: - sprintf(buf, "%s, %s", - regname_get(instr.comp.rt), - regname_get(instr.comp.rs)); - break; - case LWR_F: - sprintf(buf, "%s, %s, %hd", - regname_get(instr.comp.rt), - regname_get(instr.comp.rs), - instr.comp.os); - break; - case SWR_F: - sprintf(buf, "%s, %hd, %s", - regname_get(instr.comp.rt), - instr.comp.ot, - regname_get(instr.comp.rs)); - break; - default: - bail_with_error("Unknown computational instruction function (%d) for mnemonic %s!", - instr.comp.func, buf); - break; - } - break; - case other_comp_instr_type: - assert(instr.othc.op == OTHC_O); - switch (instr.othc.func) { - case LIT_F: - sprintf(buf, "%s, %hd, %hd", regname_get(instr.othc.reg), - instr.othc.offset, instr.othc.arg); - break; - case ARI_F: case SRI_F: - sprintf(buf, "%s, %hd", regname_get(instr.othc.reg), - instr.othc.arg); - break; - case MUL_F: case DIV_F: case CFHI_F: case CFLO_F: case JMP_F: - case CSI_F: - sprintf(buf, "%s, %hd", regname_get(instr.othc.reg), - instr.othc.offset); - break; - case SLL_F: case SRL_F: - sprintf(buf, "%s, %hd, %hu", regname_get(instr.othc.reg), - instr.othc.offset, instr.othc.arg); - break; - case JREL_F: - sprintf(buf, "%hd\t%s", instr.othc.arg, - instruction_formAddress_comment(addr, - addr+instr.othc.arg)); - break; - default: - bail_with_error("Unknown other computational instruction function (%d)!", - instr.comp.func); - break; - } - break; - case immed_instr_type: - switch (instr.immed.op) { - case ADDI_O: - sprintf(buf, "%s, %hd, %hd", regname_get(instr.immed.reg), - instr.immed.offset, instr.immed.immed); - break; - case ANDI_O: case BORI_O: case NORI_O: case XORI_O: - sprintf(buf, "%s, %hd, 0x%hx", regname_get(instr.immed.reg), - instr.immed.offset, instr.immed.immed); - break; - case BEQ_O: case BGEZ_O: case BGTZ_O: - case BLEZ_O: case BLTZ_O: case BNE_O: - sprintf(buf, "%s, %hd, %hd\t%s", regname_get(instr.immed.reg), - instr.immed.offset, instr.immed.immed, - instruction_formAddress_comment(addr, - addr+instr.immed.immed)); - break; - default: - bail_with_error("Unknown immediate type instruction opcode (%d)!", - instr.immed.op); - break; - } - break; - case jump_instr_type: - switch (instr.jump.op) { - case JMPA_O: case CALL_O: - sprintf(buf, "%u\t%s", instr.jump.addr, - instruction_formAddress_comment(addr, instr.jump.addr)); - break; - case RTN_O: - // no arguments in this case - break; - default: - bail_with_error("Unknown jump type instruction opcode (%d)!", - instr.jump.op); - break; - } - break; - case syscall_instr_type: - switch (instr.syscall.code) { - case exit_sc: - sprintf(buf, "%hd", instr.syscall.offset); - break; - case print_str_sc: case print_int_sc: - case print_char_sc: case read_char_sc: - sprintf(buf, "%s, %hd", regname_get(instr.syscall.reg), - instr.syscall.offset); - break; - case start_tracing_sc: case stop_tracing_sc: - // no arguments, so nothing to do! - break; - } - break; - default: - bail_with_error("Unknown instruction type (%d) in instruction_assembly_form!", - it); - break; - } - - return instr_buf; -} - -// Requires: out is open and writable FILE -// print the header of the instruction output table on out -void instruction_print_table_heading(FILE *out) { - fprintf(out, "%s %s\n", "Address", "Instruction"); -} - -// Requires: out is an open FILE, and instr is found at address addr. -// Print addr on out, ": ", then the instruction's symbolic -// (assembly language) form, and finally a newline character (all on one line) -void instruction_print(FILE *out, address_type addr, bin_instr_t instr) { - fprintf(out, "%8u: %s\n", addr, instruction_assembly_form(addr, instr)); -} - -// Return the mnemonic for the given system call code -const char *instruction_syscall_mnemonic(syscall_type code) -{ - switch (code) { - case exit_sc: - return "EXIT"; - break; - case print_str_sc: - return "PSTR"; - break; - case print_int_sc: - return "PINT"; - break; - case print_char_sc: - return "PCH"; - break; - case read_char_sc: - return "RCH"; - break; - case start_tracing_sc: - return "STRA"; - break; - case stop_tracing_sc: - return "NOTR"; - break; - default: - bail_with_error("Unknown code (%u) in instruction_syscall_mnemonic", - code); - return "NEVERHAPPENS"; - break; - } -} - -// Requires: instr is a SYSCALL instruction -// (i.e., instr.syscall.op == OTHC_O and instr.syscall.func == SYS_F). -// Return the code field that tells what kind of system call is being made -syscall_type instruction_syscall_number(bin_instr_t instr) { - assert(instr.syscall.op == OTHC_O && instr.syscall.func == SYS_F); - return instr.syscall.code; -} - -// Requires: bi is a computational instruction (bi.comp.op == COMP_O). -// Return a string giving the assembly language mnemonic for bi's operation -const char *instruction_compFunc2name(bin_instr_t bi) { - assert(bi.comp.op == COMP_O); - switch (bi.comp.func) { - case NOP_F: - return "NOP"; - break; - case ADD_F: - return "ADD"; - break; - case SUB_F: - return "SUB"; - break; - case CPW_F: - return "CPW"; - break; - case CPR_F: - return "CPR"; - break; - case AND_F: - return "AND"; - break; - case BOR_F: - return "BOR"; - break; - case NOR_F: - return "NOR"; - break; - case XOR_F: - return "XOR"; - break; - case LWR_F: - return "LWR"; - break; - case SWR_F: - return "SWR"; - break; - case SCA_F: - return "SCA"; - break; - case LWI_F: - return "LWI"; - break; - case NEG_F: - return "NEG"; - break; - default: - bail_with_error("Unknown function code (%d) in instruction_compFunc2name", - bi.comp.func); - break; - } - return NULL; // should never happen -} - -// Requires: bi is an other computational instruction (bi.othc.op == OTHC_O). -// Return a string giving the assembly language mnemonic for bi's operation -const char *instruction_otherCompFunc2name(bin_instr_t bi) { - assert(bi.othc.op == OTHC_O); - switch (bi.othc.func) { - case LIT_F: - return "LIT"; - break; - case ARI_F: - return "ARI"; - break; - case SRI_F: - return "SRI"; - break; - case MUL_F: - return "MUL"; - break; - case DIV_F: - return "DIV"; - break; - case CFHI_F: - return "CFHI"; - break; - case CFLO_F: - return "CFLO"; - break; - case SLL_F: - return "SLL"; - break; - case SRL_F: - return "SRL"; - break; - case JMP_F: - return "JMP"; - break; - case CSI_F: - return "CSI"; - break; - case JREL_F: - return "JREL"; - break; - case SYS_F: - return instruction_syscall_mnemonic(instruction_syscall_number(bi)); - break; - default: - bail_with_error("Unknown function code (%d) in instruction_otherCompFunc2name", - bi.comp.func); - break; - } - return NULL; // should never happen -} - -// Requires: toknum is the token number of a system call operation -// Return the system call type corresponding to the given token number -syscall_type instruction_token2SyscallCode(int toknum) -{ - switch (toknum) { - case exitopsym: - return exit_sc; - break; - case pstropsym: - return print_str_sc; - break; - case pintopsym: - return print_int_sc; - break; - case pchopsym: - return print_char_sc; - break; - case rchopsym: - return read_char_sc; - break; - case straopsym: - return start_tracing_sc; - break; - case notropsym: - return stop_tracing_sc; - break; - default: - bail_with_error("Unknown token type in instruction_token2SyscallCode: %d", - toknum); - return 0; // should never happen - break; - } -} diff --git a/vm/instruction.h b/vm/instruction.h deleted file mode 100755 index 5993fa3..0000000 --- a/vm/instruction.h +++ /dev/null @@ -1,181 +0,0 @@ -// $Id: instruction.h,v 1.40 2024/11/10 14:34:25 leavens Exp $ -#ifndef _INSTRUCTION_H -#define _INSTRUCTION_H -#include -#include -#include "machine_types.h" -#include "bof.h" - -// op codes in binary instructions for the SSM -typedef enum {COMP_O = 0, OTHC_O = 1, ADDI_O = 2, ANDI_O = 3, BORI_O = 4, - NORI_O = 5, XORI_O = 6, - BEQ_O = 7, BGEZ_O = 8, BGTZ_O = 9, BLEZ_O = 10, BLTZ_O = 11, - BNE_O = 12, JMPA_O = 13, CALL_O = 14, RTN_O = 15 - } op_code; - -// function codes in binary instructions for the SSM (when opcode is 0) -typedef enum {NOP_F = 0, ADD_F = 1, SUB_F = 2, CPW_F = 3, CPR_F = 4, - AND_F = 5, BOR_F = 6, NOR_F = 7, XOR_F = 8, - LWR_F = 9, SWR_F = 10, SCA_F = 11, LWI_F = 12, NEG_F = 13 - } func0_code; - -// function codes in binary instructions for the SSM (when opcode is 1) -typedef enum {LIT_F = 1, ARI_F = 2, SRI_F = 3, MUL_F = 4, DIV_F = 5, - CFHI_F = 6, CFLO_F = 7, SLL_F = 8, SRL_F = 9, JMP_F = 10, - CSI_F = 11, JREL_F = 12, SYS_F = 15 - } func1_code; - -// instruction types (each is a binary instruction format) -typedef enum {comp_instr_type, other_comp_instr_type, - immed_instr_type, jump_instr_type, syscall_instr_type, - error_instr_type - } instr_type; - -// system calls -typedef enum {exit_sc = 1, print_str_sc = 2, print_int_sc = 3, - print_char_sc = 4, read_char_sc = 5, - start_tracing_sc = 2046, stop_tracing_sc = 2047 -} syscall_type; - -// computational type instructions, with opcode 0 -typedef struct { - opcode_type op : 4; - reg_num_type rt : 3; // target register - offset_type ot : 9; // offset from target register - reg_num_type rs : 3; // source register - offset_type os : 9; // offset from source register - func_type func : 4; -} comp_instr_t; - -// other computational type instructions, with opcode 1, except system calls -typedef struct { - opcode_type op : 4; - reg_num_type reg : 3; - offset_type offset : 9; - arg_type arg : 12; - func_type func : 4; -} other_comp_instr_t; - -// system call instructions, with op field 1 and func field 15 -typedef struct { - opcode_type op : 4; - reg_num_type reg : 3; - offset_type offset : 9; - syscall_type code : 12; - func_type func : 4; -} syscall_instr_t; - -// immediate operand type instructions -// with signed immediate operands -typedef struct { - opcode_type op : 4; - reg_num_type reg : 3; - offset_type offset : 9; - immediate_type immed : 16; -} immed_instr_t; - -// immediate operand type instructions -// with unsigned immediate operands -typedef struct { - opcode_type op : 4; - reg_num_type reg : 3; - offset_type offset : 9; - uimmed_type uimmed : 16; -} uimmed_instr_t; - -// jump type instructions -typedef struct { - opcode_type op : 4; - address_type addr : 28; -} jump_instr_t; - -// binary instructions of any type -typedef union { - comp_instr_t comp; - other_comp_instr_t othc; - syscall_instr_t syscall; - immed_instr_t immed; - uimmed_instr_t uimmed; - jump_instr_t jump; -} bin_instr_t; - -// Return the type of the binary instruction given -extern instr_type instruction_type(bin_instr_t i); - -// Requires: bof is open for reading in binary -// Read a single instruction (in binary) from bf and return it, -// but exit with an error if there is a problem. -extern bin_instr_t instruction_read(BOFFILE bf); - -// Requires: bof is open for writing in binary -// Write the binary instruction bi to bf in binary, -// but exit with an error if there is a problem. -extern void instruction_write_bin_instr(BOFFILE bf, bin_instr_t bi); - -// Requires: bof is open for writing in binary -// Write the computational instruction oci to bf in binary, -// but exit with an error if there is a problem. -extern void instruction_write_compInstr(BOFFILE bf, comp_instr_t oci); - -// Requires: bof is open for writing in binary -// Write the other computational instruction oci to bf in binary, -// but exit with an error if there is a problem. -extern void instruction_write_otherCompInstr(BOFFILE bf, other_comp_instr_t oci); - -// Requires: bof is open for writing in binary -// Write the system instruction si to bf in binary, -// but exit with an error if there is a problem. -extern void instruction_write_syscallInstr(BOFFILE bf, syscall_instr_t si); - -// Requires: bof is open for writing in binary -// Write the immediate instruction ii with opcode op to bf in binary, -// but exit with an error if there is a problem. -extern void instruction_write_immedInstr(BOFFILE bf, immed_instr_t ii); - -// Requires: bof is open for writing in binary -// Write the immediate instruction ii with opcode op to bf in binary, -// but exit with an error if there is a problem. -extern void instruction_write_uimmedInstr(BOFFILE bf, uimmed_instr_t ii); - -// Requires: bof is open for writing in binary -// Write the jump instruction ji with opcode op to bf in binary, -// but exit with an error if there is a problem. -extern void instruction_write_jumpInstr(BOFFILE bf, jump_instr_t ji); - -// Return the assembly language name (mnemonic) for bi -extern const char *instruction_mnemonic(bin_instr_t bi); - -// Return a string containing the assembly language form of instr, -// which is found at address addr -extern const char *instruction_assembly_form(address_type addr, - bin_instr_t instr); - -// Requires: out is open and writable FILE -// print the header of the instruction output table on out -extern void instruction_print_table_heading(FILE *out); - -// Requires: out is an open FILE, and instr is found at address addr. -// Print addr on out, ": ", then the instruction's symbolic -// (assembly language) form, and finally a newline character (all on one line) -extern void instruction_print(FILE *out, address_type addr, bin_instr_t instr); - -// Return the mnemonic for the given system call code -extern const char *instruction_syscall_mnemonic(unsigned int code); - -// Requires: instr is a SYSCALL instruction -// (i.e., instr.syscall.op == OTHC_O and instr.syscall.func == SYS_F). -// Return the code field that tells what kind of system call is being made -extern syscall_type instruction_syscall_number(bin_instr_t instr); - -// Requires: bi is a computational instruction (bi.comp.op == COMP_O). -// Return a string giving the assembly language mnemonic for bi's operation -extern const char *instruction_compFunc2name(bin_instr_t bi); - -// Requires: bi is an other computational instruction (bi.othc.op == OTHC_O). -// Return a string giving the assembly language mnemonic for bi's operation -extern const char *instruction_otherCompFunc2name(bin_instr_t bi); - -// Return the system call type corresponding to the given token number -extern syscall_type instruction_token2SyscallCode(int toknum); - -#endif diff --git a/vm/lexer.c b/vm/lexer.c deleted file mode 100755 index 7525c07..0000000 --- a/vm/lexer.c +++ /dev/null @@ -1,230 +0,0 @@ -/* $Id: lexer.c,v 1.27 2024/11/10 14:34:25 leavens Exp $ */ -#include -#include -#include -#include -#include -#include -#include "ast.h" -#include "parser_types.h" -#include "lexer.h" -#include "machine_types.h" -#include "utilities.h" - - -// All of the other lexer_* functions declared in lexer.h -// that are not defined here -// are defined in asm_lexer.l's user code section. - - -// Requires: toknum is a token number (from asm.tab.h) -// of an instruction -// Return the opcode corresponding to the given opcode token number -op_code lexer_token2opcode(int toknum) -{ - op_code ret; - - switch (toknum) { - // register type op codes - case noopsym: case addopsym: case subopsym: case cpwopsym: case cpropsym: - case andopsym: case boropsym: case noropsym: case xoropsym: - case lwropsym: case swropsym: case scaopsym: case lwiopsym: - case negopsym: - ret = COMP_O; - break; - case litopsym: case ariopsym: case sriopsym: - case mulopsym: case divopsym: case cfhiopsym: case cfloopsym: - case sllopsym: case srlopsym: case jmpopsym: case csiopsym: - case jrelopsym: - ret = OTHC_O; - break; - // system call op codes - case exitopsym: case pstropsym: case pintopsym: - case pchopsym: case rchopsym: case straopsym: case notropsym: - ret = OTHC_O; // opcode is OTHC_O for these - break; - // immedidate format op codes - case addiopsym: - ret = ADDI_O; - break; - case andiopsym: - ret = ANDI_O; - break; - case boriopsym: - ret = BORI_O; - break; - case noriopsym: - ret = NORI_O; - break; - case xoriopsym: - ret = XORI_O; - break; - case beqopsym: - ret = BEQ_O; - break; - case bgezopsym: - ret = BGEZ_O; - break; - case bgtzopsym: - ret = BGTZ_O; - break; - case blezopsym: - ret = BLEZ_O; - break; - case bltzopsym: - ret = BLTZ_O; - break; - case bneopsym: - ret = BNE_O; - break; - // jump format instructions - case jmpaopsym: - ret = JMPA_O; - break; - case callopsym: - ret = CALL_O; - break; - case rtnopsym: - ret = RTN_O; - break; - default: - bail_with_error("Token number not of an op code (%d) in lexer_token2opcode!", - toknum); - break; - } - return ret; -} - -// Requires: toknum is a token number (from asm.tab.h) -// that corresponds to a computational instruction -// or an other computational instruction -// Return the function code corresponding to the given opcode token number -func_type lexer_token2func(int toknum) -{ - func_type ret; - - switch (toknum) { - case noopsym: - ret = NOP_F; - break; - case addopsym: - ret = ADD_F; - break; - case subopsym: - ret = SUB_F; - break; - case cpwopsym: - ret = CPW_F; - break; - case cpropsym: - ret = CPR_F; - break; - case andopsym: - ret = AND_F; - break; - case boropsym: - ret = BOR_F; - break; - case noropsym: - ret = NOR_F; - break; - case xoropsym: - ret = XOR_F; - break; - case lwropsym: - ret = LWR_F; - break; - case swropsym: - ret = SWR_F; - break; - case scaopsym: - ret = SCA_F; - break; - case lwiopsym: - ret = LWI_F; - break; - case negopsym: - ret = NEG_F; - break; - case litopsym: - ret = LIT_F; - break; - case ariopsym: - ret = ARI_F; - break; - case sriopsym: - ret = SRI_F; - break; - case mulopsym: - ret = MUL_F; - break; - case divopsym: - ret = DIV_F; - break; - case cfhiopsym: - ret = CFHI_F; - break; - case cfloopsym: - ret = CFLO_F; - break; - case sllopsym: - ret = SLL_F; - break; - case srlopsym: - ret = SRL_F; - break; - case jmpopsym: - ret = JMP_F; - break; - case csiopsym: - ret = CSI_F; - break; - case jrelopsym: - ret = JREL_F; - break; - case exitopsym: case pstropsym: case pintopsym: case pchopsym: - case rchopsym: case straopsym: case notropsym: - ret = SYS_F; - break; - default: - bail_with_error("Unhandled token (%d) in lexer_token2func", toknum); - break; - } - return ret; -} - -// Requires: toknum is a token number (from asm.tab.h) -// that corresponds to a system call instruction -// Return the system call code that corresponds to that token -syscall_type lexer_token2syscall_code(int toknum) -{ - syscall_type ret; - switch (toknum) { - case exitopsym: - ret = exit_sc; - break; - case pstropsym: - ret = print_str_sc; - break; - case pintopsym: - ret = print_int_sc; - break; - case pchopsym: - ret = print_char_sc; - break; - case rchopsym: - ret = read_char_sc; - break; - case straopsym: - ret = start_tracing_sc; - break; - case notropsym: - ret = stop_tracing_sc; - break; - default: - bail_with_error("Unknown token (%d) given to lexer_token2syscall_code!", - toknum); - ret = 0; - } - return ret; -} diff --git a/vm/lexer.h b/vm/lexer.h deleted file mode 100755 index bf4b3f5..0000000 --- a/vm/lexer.h +++ /dev/null @@ -1,63 +0,0 @@ -/* $Id: lexer.h,v 1.9 2024/07/15 20:31:49 leavens Exp $ */ -#ifndef _LEXER_H -#define _LEXER_H -#include -#include -#include "ast.h" -#include "parser_types.h" -#include "asm.tab.h" -#include "instruction.h" - -// Have any error messages been printed? -extern bool errors_noted; - -// The current input file -// extern FILE *yyin; -// The input line number of the current or next input line -// extern int yylineno; -// The value of the current token -// extern YYSTYPE yylval; - -// Requires: fname != NULL -// Requires: fname is the name of a readable file -// Initialize the lexer and start it reading -// from the given file name -extern void lexer_init(char *fname); - -// Return the next token in the input -extern int yylex(); - -// Return the name of the current file -extern const char *lexer_filename(); - -// Return the line number of the next token -extern unsigned int lexer_line(); - -// On standard output: -// Print a message about the file name of the lexer's input -// and then print a heading for the lexer's output. -extern void lexer_print_output_header(); - -// Print information about the token t to stdout -// followed by a newline -extern void lexer_print_token(int t, unsigned int tline, - const char *txt); - -// On standard output, print each token -// using the format in lexer_print_token -extern void lexer_output(); - -// Requires: toknum is a token number (from asm.tab.h) -// of an instruction -// Return the opcode corresponding to the given opcode token number -extern op_code lexer_token2opcode(int toknum); - -// Return the function code corresponding to the given opcode token number -extern func_type lexer_token2func(int toknum); - -// Requires: toknum is a token number (from asm.tab.h) -// that corresponds to a system call instruction -// Return the system call code that corresponds to that token -extern syscall_type lexer_token2syscall_code(int toknum); - -#endif diff --git a/vm/lexer_error1.asm b/vm/lexer_error1.asm deleted file mode 100755 index 1a5d750..0000000 --- a/vm/lexer_error1.asm +++ /dev/null @@ -1,8 +0,0 @@ - # $Id: lexer_error1.asm,v 1.2 2024/08/28 21:25:00 leavens Exp $ -.text 0 - CFHI $8, 2 # error, register number can't be 8 or higher - CFLO $13, 0 # error, again, register number can't be 13 -.data 2048 -.stack 4096 -.end - diff --git a/vm/lexer_main.c b/vm/lexer_main.c deleted file mode 100755 index fbaadfe..0000000 --- a/vm/lexer_main.c +++ /dev/null @@ -1,26 +0,0 @@ -// $Id: lexer_main.c,v 1.2 2023/09/06 22:43:06 leavens Exp $ -#include -#include -#include "ast.h" -#include "parser_types.h" -#include "lexer.h" -#include "utilities.h" - -void usage(const char *cmdname) { - bail_with_error("Usage: %s file.asm", cmdname); - exit(EXIT_FAILURE); -} - -int main(int argc, char *argv[]) { - const char *cmdname = argv[0]; - argc--; - argv++; - if (argc != 1 || argv[0][0] == '-') { - // must be a file name and no options allowed! - usage(cmdname); - } - - lexer_init(argv[0]); - lexer_output(); - return EXIT_SUCCESS; -} diff --git a/vm/lexer_test1.asm b/vm/lexer_test1.asm deleted file mode 100755 index cf0e993..0000000 --- a/vm/lexer_test1.asm +++ /dev/null @@ -1,61 +0,0 @@ - # $Id: lexer_test1.asm,v 1.22 2024/11/10 14:34:25 leavens Exp leavens $ - -.text 0 - - NOP - SRI $sp, 1 - ADD $sp, 0, $0, +1 - SUB $gp, 1, $sp, 0 # put 0 in memory[GP+1] - CPW $gp, 3, $sp, 0 # put 99 in top of stack - CPR $gp, $gp - AND $sp, -1, $r4, 0 # anding memory[SP] and location 1, result in memory[SP-1]! - BOR $sp, -1, $r4, 0 # or location zero, which is 0, so no change - NOR $sp, -1, $sp, -1 # bitwise negate memory[SP-1] - XOR $gp, 2, $gp, 15 # xor c and memory[GP+15] - LWR $r4, $gp, 2 - SWR $gp, 4, $r4 - SCA $sp, -1, $sp, 0 # store stack top address one below stack top - NEG $gp, 0, $gp, 0 - LIT $sp, -1, 122 # put 122 below top of the stack - SRI $sp, 1 # stack top is 122 - MUL $sp, 0 - CFLO $sp, -1 - CFHI $sp, -2 - DIV $sp, 0 # will cause a division by 0 error, eventually! - CFLO $sp, -3 - CFHI $sp, -4 - SLL $sp, 0, 2 - SRL $sp, -1, 3 - JREL +2 # skip next instruction - JMP $r5, 0 # causes a segmentation fault! - ANDI $sp, 0, 0x0123 - BORI $sp, -1, 0x003f - NORI $sp, -2, 0x1ff - XORI $sp, -3, 0 - BEQ $sp, 0, +2 # skip next instruction - BGEZ $sp, -2, +2 - BGTZ $sp, -3, -0xf # jump -15 backwards, if memory[GPR[$sp]-3] > 0 - BLTZ $sp, -4, +2 - BLEZ $sp, -5, +2 - SCA $sp, -6, $gp, 0 - LWI $sp, -7, $sp, -6 # should load memory[GPR[$gp]] - BNE $sp, -1, -4 - JMPA here - CALL here - JREL +2 -here: RTN - PSTR $gp, 4 - PCH $gp, 15 - RCH $gp, 5 - NOTR - EXIT 1 - -.data 2048 - WORD b = 10 - STRING[2] str = "1234" - CHAR c = 'c' - STRING[1] three = "3\n" - WORD sixteen = 0x10 - -.stack 8096 -.end diff --git a/vm/lexer_test1.lst b/vm/lexer_test1.lst deleted file mode 100755 index 08776ef..0000000 --- a/vm/lexer_test1.lst +++ /dev/null @@ -1,50 +0,0 @@ -Address Instruction - 0: NOP - 1: SRI $sp, 1 - 2: ADD $sp, 0, $gp, 1 - 3: SUB $gp, 1, $sp, 0 - 4: CPW $gp, 3, $sp, 0 - 5: CPR $gp, $gp - 6: AND $sp, -1, $r4, 0 - 7: BOR $sp, -1, $r4, 0 - 8: NOR $sp, -1, $sp, -1 - 9: XOR $gp, 2, $gp, 15 - 10: LWR $r4, $gp, 2 - 11: SWR $gp, 4, $r4 - 12: SCA $sp, -1, $sp, 0 - 13: NEG $gp, 0, $gp, 0 - 14: LIT $sp, -1, 122 - 15: SRI $sp, 1 - 16: MUL $sp, 0 - 17: CFLO $sp, -1 - 18: CFHI $sp, -2 - 19: DIV $sp, 0 - 20: CFLO $sp, -3 - 21: CFHI $sp, -4 - 22: SLL $sp, 0, 2 - 23: SRL $sp, -1, 3 - 24: JREL 2 # target is word address 26 - 25: JMP $r5, 0 - 26: ANDI $sp, 0, 0x123 - 27: BORI $sp, -1, 0x3f - 28: XORI $sp, -2, 0x1ff - 29: XORI $sp, -3, 0x0 - 30: BEQ $sp, 0, 2 # target is word address 32 - 31: BGEZ $sp, -2, 2 # target is word address 33 - 32: BGTZ $sp, -3, -15 # target is word address 17 - 33: BLTZ $sp, -4, 2 # target is word address 35 - 34: BLEZ $sp, -5, 2 # target is word address 36 - 35: SCA $sp, -6, $gp, 0 - 36: LWI $sp, -7, $sp, -6 - 37: BNE $sp, -1, -4 # target is word address 33 - 38: JMPA 41 # target is word address 41 - 39: CALL 41 # target is word address 41 - 40: JREL 2 # target is word address 42 - 41: RTN - 42: PSTR $gp, 4 - 43: PCH $gp, 15 - 44: RCH $gp, 5 - 45: NOTR - 46: EXIT 1 - 2048: 10 2049: 875770417 2050: 0 2051: 99 2052: 2611 - 2053: 16 2054: 0 ... diff --git a/vm/lexer_test2.asm b/vm/lexer_test2.asm deleted file mode 100755 index 286a37c..0000000 --- a/vm/lexer_test2.asm +++ /dev/null @@ -1,33 +0,0 @@ - # $Id: lexer_test2.asm,v 1.8 2024/08/20 19:25:40 leavens Exp $ - .text go - NOTR - PSTR $gp, 18 - EXIT 1 -go: EXIT 0 - .data 100 - WORD sixteen = 0x10 - CHAR c = 'a' - CHAR tab = '\t' - CHAR nl = '\n' - CHAR SQ = '\'' - CHAR DQ = '\"' - CHAR BS = '\\' - CHAR R = '\r' - CHAR FF = '\f' - CHAR VT = '\v' - CHAR BELL = '\a' - CHAR HE2 = '\x0F' - CHAR h = '\x1' - CHAR h12 = '\x12' - CHAR he = '\xf' - CHAR sb = '\b' - CHAR null = '\0' - CHAR oe = '\0135' - STRING [1] ot3 = "no\n" - STRING [3] others = "\r\f\v\a\b\'\"\n" - STRING [2] wnl = "abc12\n" - STRING [1] he2 = "a\x12\x0f" - STRING [12] othersE = "\r\f\v\a\b\'\"\x0F\0127\n" - .stack 0x4000 - .end - diff --git a/vm/lexer_test2.lst b/vm/lexer_test2.lst deleted file mode 100755 index 234fed9..0000000 --- a/vm/lexer_test2.lst +++ /dev/null @@ -1,12 +0,0 @@ -Address Instruction - 0: NOTR - 1: PSTR $gp, 18 - 2: EXIT 1 - 3: EXIT 0 - 100: 16 101: 97 102: 9 103: 10 104: 39 - 105: 34 106: 92 107: 13 108: 12 109: 11 - 110: 7 111: 15 112: 1 113: 18 114: 15 - 115: 8 116: 0 117: 93 118: 683886 119: 118164493 - 120: 170010376 121: 0 122: 828596833 123: 2610 - 124: 987745 125: 118164493 126: 253896456 127: 2647 - 128: 0 ... diff --git a/vm/lexer_test3.asm b/vm/lexer_test3.asm deleted file mode 100755 index 90dccae..0000000 --- a/vm/lexer_test3.asm +++ /dev/null @@ -1,11 +0,0 @@ - # $Id: lexer_test3.asm,v 1.4 2024/07/26 16:19:50 leavens Exp $ - .text go -go: ADDI $sp, 0, 93 - ADDI $sp, 0, 093 - ADDI $sp, 0, -093 - EXIT 0 - .data 512 - WORD sixteen = 0x10 - .stack 4512 - .end - diff --git a/vm/lexer_test3.lst b/vm/lexer_test3.lst deleted file mode 100755 index 2f942a3..0000000 --- a/vm/lexer_test3.lst +++ /dev/null @@ -1,6 +0,0 @@ -Address Instruction - 0: ADDI $sp, 0, 93 - 1: ADDI $sp, 0, 93 - 2: ADDI $sp, 0, -93 - 3: EXIT 0 - 512: 16 513: 0 ... diff --git a/vm/lexer_test4.asm b/vm/lexer_test4.asm deleted file mode 100755 index 161d179..0000000 --- a/vm/lexer_test4.asm +++ /dev/null @@ -1,9 +0,0 @@ - # $Id: lexer_test4.asm,v 1.1 2024/08/20 02:21:19 leavens Exp $ - .text 0 - LIT $sp, -1, 122 # put 122 below top of the stack - SRI $sp, 1 # stack top is 122 - MUL $sp, 0 - EXIT 0 -.data 1024 -.stack 2048 -.end diff --git a/vm/lexer_test4.lst b/vm/lexer_test4.lst deleted file mode 100755 index 728c82c..0000000 --- a/vm/lexer_test4.lst +++ /dev/null @@ -1,6 +0,0 @@ -Address Instruction - 0: LIT $sp, -1, 122 - 1: SRI $sp, 1 - 2: MUL $sp, 0 - 3: EXIT 0 - 1024: 0 ... diff --git a/vm/lexer_test5.asm b/vm/lexer_test5.asm deleted file mode 100755 index 4b82e91..0000000 --- a/vm/lexer_test5.asm +++ /dev/null @@ -1,10 +0,0 @@ - # $Id: lexer_test5.asm,v 1.1 2024/08/22 00:44:21 leavens Exp $ - .text 0 - LIT $sp, 0, -1 - ANDI $sp, 0, 0xff - ADDI $sp, 0, 0x100 - EXIT 0 - .data 512 - STRING [3] ls = "a long str\n" - .stack 1024 - .end diff --git a/vm/lexer_test5.lst b/vm/lexer_test5.lst deleted file mode 100755 index 635ce13..0000000 --- a/vm/lexer_test5.lst +++ /dev/null @@ -1,7 +0,0 @@ -Address Instruction - 0: LIT $sp, 0, -1 - 1: ANDI $sp, 0, 0xff - 2: ADDI $sp, 0, 256 - 3: EXIT 0 - 512: 1869357153 513: 1931503470 514: 684660 515: 0 - ... diff --git a/vm/lexer_test6.asm b/vm/lexer_test6.asm deleted file mode 100755 index 5f16db2..0000000 --- a/vm/lexer_test6.asm +++ /dev/null @@ -1,10 +0,0 @@ - # $Id: lexer_test6.asm,v 1.4 2024/07/26 16:19:50 leavens Exp $ - .text st_art -st_art: SWR $sp, 0, $sp - ADDI $sp, 0, -1 - LWR $sp, $sp, 0 - EXIT 0 - .data 1024 - .stack 4096 - .end - diff --git a/vm/lexer_test6.lst b/vm/lexer_test6.lst deleted file mode 100755 index 058104b..0000000 --- a/vm/lexer_test6.lst +++ /dev/null @@ -1,6 +0,0 @@ -Address Instruction - 0: SWR $sp, 0, $sp - 1: ADDI $sp, 0, -1 - 2: LWR $sp, $sp, 0 - 3: EXIT 0 - 1024: 0 ... diff --git a/vm/lexer_utilities.c b/vm/lexer_utilities.c deleted file mode 100755 index 6979f86..0000000 --- a/vm/lexer_utilities.c +++ /dev/null @@ -1,21 +0,0 @@ -/* $Id: lexer_utilities.c,v 1.1 2023/11/13 18:26:52 leavens Exp $ */ -#include -#include -#include -#include "lexer_utilities.h" - -#define BUF_SIZE 1024 - -// Call yyerror to print an error message on stderr -// starting with the filename, ":", the lexer's current line number, ": ", -// and then the formatted message (as in sprintf) -extern void formatted_yyerror(const char *filename, const char *fmt, ...) -{ - fflush(stdout); // flush so output comes after what has happened already - char buf[BUF_SIZE]; - va_list(args); - va_start(args, fmt); - vsnprintf(buf, BUF_SIZE, fmt, args); - yyerror(filename, buf); - va_end(args); -} diff --git a/vm/lexer_utilities.h b/vm/lexer_utilities.h deleted file mode 100755 index ecc4be0..0000000 --- a/vm/lexer_utilities.h +++ /dev/null @@ -1,15 +0,0 @@ -/* $Id: lexer_utilities.h,v 1.1 2023/11/13 18:26:52 leavens Exp $ */ -#ifndef _LEXER_UTILITIES_H -#define _LEXER_UTILITIES_H - -// Report a syntax error on the current line on stderr. -// The output looks like: the filename, ":", the lexer's current line number, -// ": ", and then msg. -extern void yyerror(const char *filename, const char *msg); - -// Call yyerror to print an error message on stderr -// starting with the filename, ":", the lexer's current line number, ": ", -// and then the formatted message (as in sprintf) -extern void formatted_yyerror(const char *filename, const char *fmt, ...); - -#endif diff --git a/vm/machine.c b/vm/machine.c deleted file mode 100755 index a6d3866..0000000 --- a/vm/machine.c +++ /dev/null @@ -1,649 +0,0 @@ -/* $Id: machine.c,v 1.49 2024/11/10 22:47:50 leavens Exp leavens $ */ -#include -#include -#include -#include -#include "machine_types.h" -#include "machine.h" -#include "regname.h" -#include "utilities.h" - -#define MAX_PRINT_WIDTH 59 - -// the VM's memory, in signed and unsigned word and binary instruction views. -static union mem_u { - word_type words[MEMORY_SIZE_IN_WORDS]; - uword_type uwords[MEMORY_SIZE_IN_WORDS]; - bin_instr_t instrs[MEMORY_SIZE_IN_WORDS]; -} memory; - -// general purpose registers -static word_type GPR[NUM_REGISTERS]; -// hi and lo registers used in multiplication and division. -// A view as a (signed) long int (result, 64 bits) -// and as an array (hilo) of 2 32-bit ints. -static union longAs2words_u { - long result; - word_type hilo[2]; -} hilo_regs; - -// LO is index 0, HI is index 1, for an x86 architecture -// (because the x86 is little-endian) -#define LO 0 -#define HI 1 - -// the program counter -static address_type PC; - -// should the machine be printing tracing output? -static bool tracing; - -// initial_stack_bottom is used for tracing -static address_type initial_stack_bottom; - -// words of instructions (based on the header) -static unsigned short instruction_words; -// words of global data (based on the header) -static unsigned short global_data_words; - - -// should the machine be running? (default true) -static bool running; - -// set up the state of the machine -static void initialize() -{ - tracing = true; // default for tracing - instruction_words = 0; - global_data_words = 0; - running = true; - - // zero the registers - for (int j = 0; j < NUM_REGISTERS; j++) { - GPR[j] = 0; - } - hilo_regs.result = 0; - // zero out the memory - for (int i = 0; i < MEMORY_SIZE_IN_WORDS; i++) { - memory.words[i] = 0; - } -} - -// Requires: bf is a binary object file that is open for reading -// Load count instructions from bf into the memory starting at address 0. -// If any errors are encountered, exit with an error message. -static void load_instructions(BOFFILE bf, int count) -{ - for (int wa = 0; wa < count; wa++) { - memory.instrs[wa] = instruction_read(bf); - } -} - -// Requires: bf is a binary object file that is open for reading -// Load count words from bf into the memory -// starting at word address global_base. -// If any errors are encountered, exit with an error message. -static void load_data(BOFFILE bf, int count, unsigned int global_base) -{ - for (int wo = 0; wo < count; wo++) { - memory.words[global_base+wo] = bof_read_word(bf); - } -} - -// Requires: bf is open for reading in binary -// Load the binary object file bf, and get ready to run it -void machine_load(BOFFILE bf) -{ - initialize(); - - // read and check the header - BOFHeader bh = bof_read_header(bf); - if (bh.text_length >= bh.data_start_address) { - bail_with_error("%s (%u) %s (%u)!", - "Text, i.e., program length", bh.text_length, - "is not less than the start address of the global data", - bh.data_start_address); - } - if (bh.data_start_address + bh.data_length >= bh.stack_bottom_addr) { - bail_with_error("%s (%u) + %s (%u) %s (%u)!", - "Global data start address", bh.data_start_address, - "global data length", bh.data_length, - "is not less than the stack bottom address", - bh.stack_bottom_addr); - } - if (bh.stack_bottom_addr >= MEMORY_SIZE_IN_WORDS) { - bail_with_error("%s (%u) %s (%u)!", - "stack_bottom_addr", bh.stack_bottom_addr, - "is not less than the memory size", - MEMORY_SIZE_IN_WORDS); - } - - // load the program - instruction_words = bh.text_length; - load_instructions(bf, instruction_words); - - global_data_words = bh.data_length; - - load_data(bf, global_data_words, bh.data_start_address); - - // initialize the registers - PC = bh.text_start_address; - - GPR[GP] = bh.data_start_address; - GPR[SP] = bh.stack_bottom_addr; - GPR[FP] = bh.stack_bottom_addr; - initial_stack_bottom = bh.stack_bottom_addr; -} - -// Requires: fmt == 'x' or fmt == 'd' -// print the memory location at word address wa to out -// with a format determined by fmt and no newline, -// returns the number of characters written -static int print_loc(FILE *out, address_type wa, char fmt) -{ - int count; - if (fmt == 'x') { - count = fprintf(out, "%8d: 0x%x\t", wa, - memory.words[wa]); - } else { // fmt == 'd' - count = fprintf(out, "%8d: %d\t", wa, - memory.words[wa]); - } - return count; -} - -// print the word address given and the instruction's assembly form -static void print_instruction(FILE *out, address_type wa, bin_instr_t bi) -{ - fprintf(out, "%6d: %s\n", wa, instruction_assembly_form(wa, bi)); -} - -// Print the word memory in hex or decimal based on the fmt argument -// between the word addresses start (inclusive) and end (inclusive) to out, -// without a newline and eliding all repeated zeros in the range -// Returns true if printed a newline at the end, false otherwise -static bool print_memory_nonzero(FILE *out, int start, int end, char fmt) -{ - bool printed_trailing_newline = false; - bool previously_zero = false; // was previous word printed a 0? - bool printed_dots = false; // have we already printed dots? - int lc = 0; // count of chars on a line - for (int wa = start; wa <= end; wa++) { - if (lc > MAX_PRINT_WIDTH) { - newline(out); - printed_trailing_newline = true; - lc = 0; - } - if (memory.words[wa] != 0) { - lc += print_loc(out, wa, fmt); - printed_trailing_newline = false; - previously_zero = false; - printed_dots = false; - } else { - // memory.words[wa] == 0 - if (!previously_zero) { - // print the first zero - lc += print_loc(out, wa, fmt); - previously_zero = true; - printed_dots = false; - } else { - // previously printed a zero - if (!printed_dots) { - // not already printed the dots, so print them now - lc += fprintf(out, "%s", " ... "); - printed_dots = true; - } - } - printed_trailing_newline = false; - } - } - return printed_trailing_newline; -} - -// print the nonzero memory locations between the word addresses -// start and end (both inclusive) on out, in decimal notation -// a trailing newline was printed if the result is true -static bool print_memory_words_d(FILE *out, int start, int end) -{ - return print_memory_nonzero(out, start, end, 'd'); -} - -// Print the global area, eliding repeated zeros, -// starting at GPR[GP] -static void print_global_data(FILE *out) -{ - int global_wa = GPR[GP]; - bool printed_nl; - printed_nl = print_memory_words_d(out, global_wa, GPR[SP]-1); - if (!printed_nl) { - newline(out); - } -} - -// Requires: a program has been loaded into the computer's memory -// print a heading and the program and any global data -// that were previously loaded into the VM's memory to out -void machine_print_loaded_program(FILE *out) -{ - // heading - instruction_print_table_heading(out); - // instructions - for (int wa = 0; wa < instruction_words; wa++) { - print_instruction(out, wa, memory.instrs[wa]); - } - - print_global_data(out); -} - -// Run the VM on the already loaded program, -// producing any trace output called for by the program -void machine_run(bool trace_execution) -{ - tracing = trace_execution; - if (tracing) { - machine_print_state(stdout); - } - // execute the program - while (running) { - machine_okay(); // check the invariant - machine_trace_execute_instr(stdout, PC, memory.instrs[PC]); - } -} - -// Load the given binary object file and run it -void machine_load_and_run(BOFFILE bf, bool trace_execution) -{ - machine_load(bf); - machine_run(trace_execution); -} - -// Requires: addr == PC. -// If tracing then print the given word address and the assembly form of bi, -// then execute bi (always), -// then if tracing print out the machine's state. -// All tracing output goes to the FILE out -void machine_trace_execute_instr(FILE *out, address_type addr, - bin_instr_t bi) -{ - assert(addr == PC); - if (tracing) { - fprintf(out, "\n==> "); - print_instruction(out, PC, bi); - } - machine_execute_instr(addr, bi); - if (tracing) { - machine_print_state(out); - } -} - -// Requires: The instruction at memory.instrs[PC] is bi. -// Execute the given instruction, which is found at word address addr, -// in the machine's current state -void machine_execute_instr(address_type addr, bin_instr_t bi) -{ - // increment the PC (advance address by 1 word) - PC = PC + 1; - - // execute the actual instruction - instr_type it = instruction_type(bi); - switch (it) { - case comp_instr_type: - { - comp_instr_t ci = bi.comp; - switch (ci.func) { - case NOP_F: - // do nothing - break; - case ADD_F: - memory.words[GPR[ci.rt] + machine_types_formOffset(ci.ot)] - = memory.words[GPR[SP]] - + memory.words[GPR[ci.rs] + machine_types_formOffset(ci.os)]; - break; - case SUB_F: - memory.words[GPR[ci.rt] + machine_types_formOffset(ci.ot)] - = memory.words[GPR[SP]] - - memory.words[GPR[ci.rs] - + machine_types_formOffset(ci.os)]; - break; - case CPW_F: - memory.words[GPR[ci.rt] + machine_types_formOffset(ci.ot)] - = memory.words[GPR[ci.rs] - + machine_types_formOffset(ci.os)]; - break; - case CPR_F: - GPR[ci.rt] = GPR[ci.rs]; - break; - case AND_F: - memory.uwords[GPR[ci.rt] + machine_types_formOffset(ci.ot)] - = memory.uwords[GPR[SP]] - & memory.uwords[GPR[ci.rs] - + machine_types_formOffset(ci.os)]; - break; - case BOR_F: - memory.uwords[GPR[ci.rt] + machine_types_formOffset(ci.ot)] - = memory.uwords[GPR[SP]] - | memory.uwords[GPR[ci.rs] - + machine_types_formOffset(ci.os)]; - break; - case NOR_F: - memory.uwords[GPR[ci.rt] + machine_types_formOffset(ci.ot)] - = ~(memory.uwords[GPR[SP]] - | memory.uwords[GPR[ci.rs] - + machine_types_formOffset(ci.os)]); - break; - case XOR_F: - memory.uwords[GPR[ci.rt] + machine_types_formOffset(ci.ot)] - = memory.uwords[GPR[SP]] - ^ memory.uwords[GPR[ci.rs] - + machine_types_formOffset(ci.os)]; - break; - case LWR_F: - GPR[ci.rt] - = memory.words[GPR[ci.rs] - + machine_types_formOffset(ci.os)]; - break; - case SWR_F: - memory.words[GPR[ci.rt] - + machine_types_formOffset(ci.ot)] - = GPR[ci.rs]; - break; - case SCA_F: - memory.words[GPR[ci.rt] + machine_types_formOffset(ci.ot)] - = (GPR[ci.rs] + machine_types_formOffset(ci.os)); - break; - case LWI_F: - memory.words[GPR[ci.rt] + machine_types_formOffset(ci.ot)] - = memory.words[memory.words - [GPR[ci.rs] + machine_types_formOffset(ci.os)]]; - break; - case NEG_F: - memory.words[GPR[ci.rt] + machine_types_formOffset(ci.ot)] - = - (memory.words[GPR[ci.rs] - + machine_types_formOffset(ci.os)]); - break; - default: - bail_with_error("Invalid function code (%d) in machine_execute's COMP_O computational instruction case!", - ci.func); - break; - } - } - break; - case other_comp_instr_type: - { - other_comp_instr_t oci = bi.othc; - switch (oci.func) { - case LIT_F: - memory.words[GPR[oci.reg] + machine_types_sgnExt(oci.offset)] - = machine_types_sgnExt(oci.arg); - break; - case ARI_F: - GPR[oci.reg] = GPR[oci.reg] + machine_types_sgnExt(oci.arg); - break; - case SRI_F: - GPR[oci.reg] = GPR[oci.reg] - machine_types_sgnExt(oci.arg); - break; - case MUL_F: - hilo_regs.result - = (long) memory.words[GPR[SP]] - * (long) memory.words[GPR[oci.reg] - + machine_types_formOffset(oci.offset)]; - break; - case DIV_F: - int divisor = memory.words[GPR[oci.reg] - + machine_types_formOffset(oci.offset)]; - if (divisor == 0) { - bail_with_error("Error: Attempt to divide by zero!"); - } - hilo_regs.hilo[HI] = memory.words[GPR[SP]] % divisor; - hilo_regs.hilo[LO] = memory.words[GPR[SP]] / divisor; - break; - case CFHI_F: - memory.words[GPR[oci.reg] - + machine_types_formOffset(oci.offset)] - = hilo_regs.hilo[HI]; - break; - case CFLO_F: - memory.words[GPR[oci.reg] - + machine_types_formOffset(oci.offset)] - = hilo_regs.hilo[LO]; - break; - case SLL_F: - memory.uwords[GPR[oci.reg] - + machine_types_formOffset(oci.offset)] - = memory.uwords[GPR[SP]] << oci.arg; - break; - case SRL_F: - memory.uwords[GPR[oci.reg] - + machine_types_formOffset(oci.offset)] - = memory.uwords[GPR[SP]] >> oci.arg; - break; - case JMP_F: - PC = memory.uwords[GPR[oci.reg] - + machine_types_formOffset(oci.offset)]; - break; - case CSI_F: - GPR[RA] = PC; - PC = memory.words[GPR[oci.reg] - + machine_types_formOffset(oci.offset)]; - break; - case JREL_F: - PC = (PC - 1) + machine_types_formOffset(oci.arg); - break; - default: - bail_with_error("Invalid function code (%d) in machine_execute's OTHC_O computational instruction case!", - oci.func); - break; - } - } - break; - case syscall_instr_type: - { - syscall_instr_t si = bi.syscall; - switch (si.code) { - case exit_sc: - running = false; - exit(machine_types_sgnExt(si.offset)); - break; - case print_str_sc: - memory.words[GPR[SP]] - = printf("%s", - (char *) &(memory.words[GPR[si.reg] - + machine_types_formOffset(si.offset)])); - break; - case print_int_sc: - memory.words[GPR[SP]] - = printf("%d", - memory.words[GPR[si.reg] - + machine_types_formOffset(si.offset)]); - break; - case print_char_sc: - memory.words[GPR[SP]] - = fputc(memory.words[GPR[si.reg] - + machine_types_formOffset(si.offset)], - stdout); - break; - case read_char_sc: - memory.words[GPR[si.reg] + machine_types_formOffset(si.offset)] - = getc(stdin); - break; - case start_tracing_sc: - tracing = true; - break; - case stop_tracing_sc: - tracing = false; - break; - default: - bail_with_error("Invalid system call type (%d) in machine_execute's syscall instruction case!", - instruction_syscall_number(bi)); - break; - } - } - break; - case immed_instr_type: - { - immed_instr_t ii = bi.immed; - uimmed_instr_t ui = bi.uimmed; - switch (ii.op) { - case ADDI_O: - memory.words[GPR[ii.reg] + machine_types_formOffset(ii.offset)] - = memory.words[GPR[ii.reg] + machine_types_formOffset(ii.offset)] - + machine_types_sgnExt(ii.immed); - break; - case ANDI_O: - memory.uwords[GPR[ui.reg] + machine_types_formOffset(ui.offset)] - = memory.uwords[GPR[ui.reg] - + machine_types_formOffset(ui.offset)] - & machine_types_zeroExt(ui.uimmed); - break; - case BORI_O: - memory.uwords[GPR[ui.reg] + machine_types_formOffset(ui.offset)] - = memory.uwords[GPR[ui.reg] - + machine_types_formOffset(ui.offset)] - | machine_types_zeroExt(ui.uimmed); - break; - case NORI_O: - memory.uwords[GPR[ui.reg] + machine_types_formOffset(ui.offset)] - = ~(memory.uwords[GPR[ui.reg] - + machine_types_formOffset(ui.offset)] - | machine_types_zeroExt(ui.uimmed)); - break; - case XORI_O: - memory.uwords[GPR[ui.reg] + machine_types_formOffset(ui.offset)] - = memory.uwords[GPR[ui.reg] - + machine_types_formOffset(ui.offset)] - ^ machine_types_zeroExt(ui.uimmed); - break; - case BEQ_O: - if (memory.words[GPR[SP]] - == memory.words[GPR[ii.reg] - + machine_types_formOffset(ii.offset)]) { - PC = (PC - 1) + machine_types_formOffset(ii.immed); - } - break; - case BGEZ_O: - if (memory.words[GPR[ii.reg] - + machine_types_formOffset(ii.offset)] - >= 0) { - PC = (PC - 1) + machine_types_formOffset(ii.immed); - } - break; - case BGTZ_O: - if (memory.words[GPR[ii.reg] - + machine_types_formOffset(ii.offset)] - > 0) { - PC = (PC - 1) + machine_types_formOffset(ii.immed); - } - break; - case BLEZ_O: - if (memory.words[GPR[ii.reg] - + machine_types_formOffset(ii.offset)] - <= 0) { - PC = (PC - 1) + machine_types_formOffset(ii.immed); - } - break; - case BLTZ_O: - if (memory.words[GPR[ii.reg] - + machine_types_formOffset(ii.offset)] - < 0) { - PC = (PC - 1) + machine_types_formOffset(ii.immed); - } - break; - case BNE_O: - if (memory.words[GPR[SP]] - != memory.words[GPR[ii.reg] - + machine_types_formOffset(ii.offset)]) { - PC = (PC - 1) + machine_types_formOffset(ii.immed); - } - break; - default: - bail_with_error("Invalid opcode (%d) in machine_execute's immediate instruction case!", - ii.op); - break; - } - } - break; - case jump_instr_type: - { - jump_instr_t ji = bi.jump; - switch (ji.op) { - case JMPA_O: - PC = machine_types_formAddress(PC-1, ji.addr); - break; - case CALL_O: - GPR[RA] = PC; - PC = machine_types_formAddress(PC-1, ji.addr); - break; - case RTN_O: - PC = GPR[RA]; - break; - default: - bail_with_error("Invalid opcode (%d) in machine_execute's jump instruction case!", - ji.op); - break; - } - } - break; - default: - bail_with_error("Invalid instruction type (%d) in machine_execute!", - it); - break; - } -} - -#define REGFORMAT1 "GPR[%-3s]: %-5d" -#define REGFORMAT2 "\tGPR[%-3s]: %-5d" - -// Requires: out != NULL and is writable -// Print the current values in the registers to out -static void print_registers(FILE *out) -{ - // print the registers - fprintf(out, "%8s: %u", "PC", PC); - if (hilo_regs.result != 0L) { - fprintf(out, "\t%8s: %d\t%8s: %d", - "HI", hilo_regs.hilo[HI], - "LO", hilo_regs.hilo[LO]); - } - newline(out); - - for (int j = 0; j < (NUM_REGISTERS); /* nothing */) { - fprintf(out, REGFORMAT1, regname_get(j), GPR[j]); - j++; - for (int lc = 0; lc < 4 && j < (NUM_REGISTERS); lc++) { - fprintf(out, REGFORMAT2, regname_get(j), GPR[j]); - j++; - } - newline(out); - } -} - -// Print non-zero global data between the (word) addresses -// GPR[SP] and initial_stack_bottom inclusive -static void print_runtime_stack(FILE *out) -{ - // print the memory between sp and fp, inclusive - bool printed_nl = print_memory_words_d(out, GPR[SP], initial_stack_bottom); - if (!printed_nl) { - newline(out); - } -} - -// Requires: out != NULL and out can be written on -// print the state of the machine (registers, globals, and -// the memory between GPR[$sp] and GPR[$fp], inclusive) to out -void machine_print_state(FILE *out) -{ - print_registers(out); - print_global_data(out); - print_runtime_stack(out); -} - -// Invariant test for the VM (for debugging purposes) -// This exits with an assertion error if the invariant does not pass -void machine_okay() -{ - assert(0 <= GPR[GP]); - assert(GPR[GP] < GPR[SP]); - assert(GPR[SP] <= GPR[FP]); - assert(GPR[FP] < MEMORY_SIZE_IN_WORDS); -} diff --git a/vm/machine.h b/vm/machine.h deleted file mode 100755 index 35db2d7..0000000 --- a/vm/machine.h +++ /dev/null @@ -1,50 +0,0 @@ -/* $Id: machine.h,v 1.16 2024/11/10 13:22:31 leavens Exp $ */ -#ifndef _MACHINE_H -#define _MACHINE_H -#include -#include "machine_types.h" -#include "bof.h" -#include "instruction.h" - -// a size for the memory (2^16 = 32K words) -#define MEMORY_SIZE_IN_WORDS 32768 - -// Requires: bf is open for reading in binary -// Load the binary object file bf, and get ready to run it -extern void machine_load(BOFFILE bf); - -// Requires: a program has been loaded into the computer's memory -// print a heading and the program in the VM's memory to out -extern void machine_print_loaded_program(FILE *out); - -// Run the VM on the already loaded program, -// producing any trace output called for by the program -// if trace_execution is true -extern void machine_run(bool trace_execution); - -// Load the given binary object file and run it -extern void machine_load_and_run(BOFFILE bf, bool trace_execution); - -// If tracing then print bi, execute bi (always), -// then if tracing print out the machine's state. -// All tracing output goes to the FILE out -extern void machine_trace_execute_instr(FILE *out, address_type addr, - bin_instr_t bi); - -// Execute the given instruction, which is found at address addr, -// in the machine's current state -extern void machine_execute_instr(address_type addr, bin_instr_t bi); - -// Print instr, execute instr, then print out the machine's state (to out) -extern void machine_trace_execute(FILE *out, bin_instr_t instr); - -// Requires: out != NULL and out can be written on -// print the state of the machine (registers, globals, and -// the memory between GPR[$sp] and GPR[$fp], inclusive) to out -extern void machine_print_state(FILE *out); - -// Invariant test for the VM (for debugging purposes) -// This exits with an assertion error if the invariant does not pass -extern void machine_okay(); - -#endif diff --git a/vm/machine_main.c b/vm/machine_main.c deleted file mode 100755 index 7472c00..0000000 --- a/vm/machine_main.c +++ /dev/null @@ -1,62 +0,0 @@ -/* $Id: machine_main.c,v 1.6 2024/11/10 13:22:31 leavens Exp $ */ -#include -#include -#include -#include "bof.h" -#include "machine.h" -#include "utilities.h" - -/* Print a usage message on stderr and exit with exit code 1. */ -static void usage(const char *cmdname) -{ - bail_with_error( - "Usage: %s [-p] file.bof\n %s [-t] file.bof", - cmdname, cmdname); -} - -// Run the VM on the .bof file name given in argv[1] -int main(int argc, char *argv[]) -{ - const char *cmdname = argv[0]; - argc--; - argv++; - - bool print_program = false; - bool trace_execution = false; - if (argc == 2 && strcmp(argv[0], "-p") == 0) { - print_program = true; - argc--; - argv++; - } else if (argc == 2 && strcmp(argv[0], "-t") == 0) { - trace_execution = true; - argc--; - argv++; - } - - // now there should be exactly 1 file argument - if (argc != 1 || argv[0][0] == '-') { - usage(cmdname); - } - - char *suffix = strchr(argv[0], '.'); - if (suffix == NULL || strncmp(suffix, ".bof", 4) != 0) { - usage(cmdname); - } - - BOFFILE bf = bof_read_open(argv[0]); - - machine_load(bf); - - // if printing, don't run the program - if (print_program) { - machine_print_loaded_program(stdout); - return EXIT_SUCCESS; - } - - machine_run(trace_execution); - - // the following should never execute, - // as the exit system call will call exit(0), - // and if the machine goes into an infinite loop it never gets here! - return EXIT_SUCCESS; -} diff --git a/vm/machine_types.c b/vm/machine_types.c deleted file mode 100755 index e5609db..0000000 --- a/vm/machine_types.c +++ /dev/null @@ -1,100 +0,0 @@ -// $Id: machine_types.c,v 1.12 2024/08/22 11:36:02 leavens Exp $ -#include "machine_types.h" -#include "utilities.h" - -// Return the sign-extended equivalent of i -word_type machine_types_sgnExt(immediate_type i) { - return i; // preserves the value -} - -// Return the zero-extended equivalent of i -uword_type machine_types_zeroExt(immediate_type i) { - return (uword_type) i; -} - -// Return the offset given by o, -// which is the sign extension of o -word_type machine_types_formOffset(immediate_type o) { - return machine_types_sgnExt(o); -} - -// Return an address formed by concatenating the instruction address, a, -// with the high-order (4) bits of the PC. -address_type machine_types_formAddress(address_type PC, address_type a) { - return ((0xF0000000 & PC) | (0x0FFFFFF & a)); -} - -// Check that o can be represented as an offset field in an instruction -// bail with an error message if not (so doesn't return if wrong) -void machine_types_check_fits_in_offset(word_type o) -{ - if (o > NINEBITSMAXSIGNED) { - bail_with_error("Offset is too large: %d", o); - } else if (o < NINEBITSMINSIGNED) { - bail_with_error("Offset is too small: %d", o); - } -} - -// Check that arg can be represented as an arg field in an instruction, -// bail with an error message if not (so doesn't return if wrong) -void machine_types_check_fits_in_arg(word_type arg) -{ - if (arg > TWELVEBITSMAXSIGNED) { - bail_with_error("12 bit argument is too large: %d", arg); - } else if (arg < TWELVEBITSMINSIGNED) { - bail_with_error("12 bit argument is too small: %d", arg); - } -} - -// Check that s can be represented as a shift field in an instruction, -// bail with an error message if not (so doesn't return if wrong) -void machine_types_check_fits_in_shift(word_type s) -{ - if (s > TWELVEBITSMAXUNSIGNED) { - bail_with_error("Shift is too large: %u", s); - } -} - -// Check that immed can be represented as a signed immediate field, -// bail with an error message if not (so doesn't return if wrong) -void machine_types_check_fits_in_immed(word_type immed) -{ - if (immed > SIXTEENBITSMAXSIGNED) { - bail_with_error("Immediate argument is too large: %d", - immed); - } else if (immed < SIXTEENBITSMINSIGNED) { - bail_with_error("Immediate argument is too small: %d", - immed); - } -} - -// Check that arg can be represented as unsigned immediate field, -// bail with an error message if not (so doesn't return if wrong) -void machine_types_check_fits_in_uimmed(word_type arg) -{ - if (arg > SIXTEENBITSMAXUNSIGNED) { - bail_with_error("Unsigned immediate argument is too large: %u", arg); - } -} - -// Check that addr can be represented as an address field in an instruction, -// bail with an error message if not (so doesn't return if wrong) -void machine_types_check_fits_in_addr(address_type addr) -{ - if (addr > TWENTYEIGHTBITSMAXUNSIGNED) { - bail_with_error("Address is too large: %u", addr); - } -} - -// Return the nearest multiple of BYTES_PER_WORD -// that is greater than or equal to n -int machine_types_round_up_to_wordsize(unsigned int n) -{ - int rem = n % BYTES_PER_WORD; - if (rem == 0) { - return n; - } else { - // assert(((n + (BYTES_PER_WORD - rem)) % BYTES_PER_WORD) == 0); - return n + (BYTES_PER_WORD - rem); - } -} diff --git a/vm/machine_types.h b/vm/machine_types.h deleted file mode 100755 index 6931cab..0000000 --- a/vm/machine_types.h +++ /dev/null @@ -1,94 +0,0 @@ -// $Id: machine_types.h,v 1.29 2024/08/29 21:58:39 leavens Exp $ -// Machine Types for the Simplified Stack Machine (SSM) -#ifndef _MACHINE_TYPES_H -#define _MACHINE_TYPES_H - -#define BYTES_PER_WORD 4 - -// operation codes -typedef unsigned short opcode_type; - -// registers encoded in instructions -typedef unsigned short reg_num_type; - -// offset values (which are signed) encoded in instructions -typedef short offset_type; - -// function codes in computational instructions -typedef unsigned short func_type; - -// argument values (signed) encoded in instructions -typedef short arg_type; - -// shift values encoded in other computational instructions -typedef unsigned short shift_type; - -// immediate operands encoded in instructions -typedef int immediate_type; - -// unsigned immediate operands in instructions -typedef unsigned int uimmed_type; - -// addresses, assuming ints are 32 bits -typedef unsigned int address_type; - -// machine words, assuming ints are 32 bits -typedef int word_type; - -// machine words, unsigned -typedef unsigned int uword_type; - -// bytes, assuming chars are 8 bits -typedef unsigned char byte_type; - -#define NINEBITSMAXSIGNED 0xff -#define NINEBITSMINSIGNED -512 -#define TWELVEBITSMAXSIGNED 0x7ff -#define TWELVEBITSMINSIGNED -0x800 -#define TWELVEBITSMAXUNSIGNED 0xfff -#define SIXTEENBITSMAXSIGNED 0777 -#define SIXTEENBITSMINSIGNED -01000 -#define SIXTEENBITSMAXUNSIGNED 0xffff -#define TWENTYEIGHTBITSMAXUNSIGNED 0xfffffff - -// Return the sign-extended equivalent of i -extern word_type machine_types_sgnExt(immediate_type i); - -// Return the zero-extended equivalent of i -extern uword_type machine_types_zeroExt(immediate_type i); - -// Return the offset given by o, -// which is the sign extension of o -extern word_type machine_types_formOffset(immediate_type o); - -// Return an address formed by concatenating the instruction address, a, -// with the high-order (4) bits of the PC. -extern address_type machine_types_formAddress(address_type PC, address_type a); - -// Check that o can be represented as an offset field in an instruction -// bail with an error message if not (so doesn't return if wrong) -extern void machine_types_check_fits_in_offset(word_type o); - -// Check that arg can be represented as an arg field in an instruction, -// bail with an error message if not (so doesn't return if wrong) -extern void machine_types_check_fits_in_arg(word_type arg); - -// Check that arg can be represented as a shift field in an instruction, -// bail with an error message if not (so doesn't return if wrong) -extern void machine_types_check_fits_in_shift(word_type arg); - -// Check that immed can be represented as a signed immediate field, -// bail with an error message if not (so doesn't return if wrong) -extern void machine_types_check_fits_in_immed(word_type immed); - -// Check that arg can be represented as unsigned immediate field, -// bail with an error message if not (so doesn't return if wrong) -extern void machine_types_check_fits_in_uimmed(word_type arg); - -// Check that addr can be represented as an address field in an instruction, -// bail with an error message if not (so doesn't return if wrong) -extern void machine_types_check_fits_in_addr(address_type addr); - -// the following line is for the documentation -// ... -#endif diff --git a/vm/parser_test0.asm b/vm/parser_test0.asm deleted file mode 100755 index 4c3bf05..0000000 --- a/vm/parser_test0.asm +++ /dev/null @@ -1,6 +0,0 @@ - # $Id: parser_test0.asm,v 1.3 2024/07/30 12:00:15 leavens Exp $ -.text start -start: EXIT 0 -.data 16 -.stack 4096 -.end diff --git a/vm/parser_test0.lst b/vm/parser_test0.lst deleted file mode 100755 index dcf57f6..0000000 --- a/vm/parser_test0.lst +++ /dev/null @@ -1,3 +0,0 @@ -Address Instruction - 0: EXIT 0 - 16: 0 ... diff --git a/vm/parser_test1.asm b/vm/parser_test1.asm deleted file mode 100755 index ad34249..0000000 --- a/vm/parser_test1.asm +++ /dev/null @@ -1,12 +0,0 @@ - # $Id: parser_test1.asm,v 1.5 2024/07/30 12:00:15 leavens Exp $ - -.text begin -begin: SUB $sp, 0, $sp, 0 - EXIT 0 -.data 0x40 - WORD b = 10 - WORD w - WORD c - WORD sixteen = 16 -.stack 0x4040 -.end diff --git a/vm/parser_test1.lst b/vm/parser_test1.lst deleted file mode 100755 index be56d75..0000000 --- a/vm/parser_test1.lst +++ /dev/null @@ -1,5 +0,0 @@ -Address Instruction - 0: SUB $sp, 0, $sp, 0 - 1: EXIT 0 - 64: 10 65: 0 ... 67: 16 68: 0 - ... diff --git a/vm/parser_test2.asm b/vm/parser_test2.asm deleted file mode 100755 index 90da209..0000000 --- a/vm/parser_test2.asm +++ /dev/null @@ -1,14 +0,0 @@ - # $Id: parser_test2.asm,v 1.4 2024/08/20 00:05:26 leavens Exp $ - .text start -start: NOP - ADDI $sp, 0, 1 - SCA $sp, -1, $sp, 0 - SRI $sp, 1 - SWR $sp, -1, $fp - ADDI $sp, -1, 104 - LWI $sp, -2, $gp, 0 - EXIT 0 - .data 104 - WORD fourtytwo = 42 - .stack 4200 - .end diff --git a/vm/parser_test2.lst b/vm/parser_test2.lst deleted file mode 100755 index 42a6e69..0000000 --- a/vm/parser_test2.lst +++ /dev/null @@ -1,10 +0,0 @@ -Address Instruction - 0: NOP - 1: ADDI $sp, 0, 1 - 2: SCA $sp, -1, $sp, 0 - 3: SRI $sp, 1 - 4: SWR $sp, -1, $fp - 5: ADDI $sp, -1, 104 - 6: LWI $sp, -2, $gp, 0 - 7: EXIT 0 - 104: 42 105: 0 ... diff --git a/vm/parser_test3.asm b/vm/parser_test3.asm deleted file mode 100755 index a626e73..0000000 --- a/vm/parser_test3.asm +++ /dev/null @@ -1,13 +0,0 @@ - # $Id: parser_test3.asm,v 1.5 2024/07/30 12:00:15 leavens Exp $ - .text start -start: ARI $sp, -2 - BNE $sp, 1, +4 - ADDI $sp, 0, 100 - ADD $sp, 0, $gp, 0 - EXIT 0 - .data 1024 - WORD hundred = 100 - WORD forty = 40 - WORD six = 6 - .stack 4096 - .end diff --git a/vm/parser_test3.lst b/vm/parser_test3.lst deleted file mode 100755 index 7be8ad7..0000000 --- a/vm/parser_test3.lst +++ /dev/null @@ -1,8 +0,0 @@ -Address Instruction - 0: ARI $sp, -2 - 1: BNE $sp, 1, 4 # target is word address 5 - 2: ADDI $sp, 0, 100 - 3: ADD $sp, 0, $gp, 0 - 4: EXIT 0 - 1024: 100 1025: 40 1026: 6 1027: 0 ... - diff --git a/vm/parser_test4.asm b/vm/parser_test4.asm deleted file mode 100755 index f7b37b5..0000000 --- a/vm/parser_test4.asm +++ /dev/null @@ -1,10 +0,0 @@ - # $Id: parser_test4.asm,v 1.5 2024/07/30 12:00:15 leavens Exp $ - .text start -start: ARI $sp, -2 - BNE $sp, -1, +1 # shouldn't be effective, as both what $sp and $sp-1 - # point to should contain 0 - EXIT 0 - .data 2048 - WORD five = +5 - .stack 6144 - .end diff --git a/vm/parser_test4.lst b/vm/parser_test4.lst deleted file mode 100755 index 7fbe86b..0000000 --- a/vm/parser_test4.lst +++ /dev/null @@ -1,5 +0,0 @@ -Address Instruction - 0: ARI $sp, -2 - 1: BNE $sp, -1, 1 # target is word address 2 - 2: EXIT 0 - 2048: 5 2049: 0 ... diff --git a/vm/parser_test5.asm b/vm/parser_test5.asm deleted file mode 100755 index 34a64be..0000000 --- a/vm/parser_test5.asm +++ /dev/null @@ -1,58 +0,0 @@ - # $Id: parser_test5.asm,v 1.13 2024/08/29 02:05:03 leavens Exp $ - -.text here - -here: LIT $sp, 0, 0 - SUB $sp, -1, $sp, 0 - AND $sp, -2, $sp, -3 - SRI $sp, 3 - BORI $sp, 0, 0x8 - JREL 3 # skip next 2 instructions - NOR $ra, -1, $sp, 0 # causes an error - XOR $sp, -2, $sp, -1 # why not? - MUL $r5, 0 - CFHI $1, 0 - CFLO $2, 0 - LIT $sp, -1, 1 - LWR $r5, $sp, -1 # put 1 in $r5 - SRI $sp, 1 - DIV $sp, 0 - ADDI $sp, 0, 13 - ADD $gp, 0, $gp, 0 - CALL fun - EXIT 0 -fun: ANDI $sp, 0, 0xff - XORI $sp, 0, 0x00 - BEQ $sp, 0, 2 - BNE $sp, 0, 333 - BGEZ $sp, 0, 3 - ADDI $sp, 0, 11 - BGTZ $sp, 1, -2 - BLTZ $sp, 1, 2 - BLEZ $sp, 0, 2 - CPW $sp, 0, $gp, 1 # put 1025 in stack top - LWR $fp, $sp, 0 # put 1025 in $fp register, violates invariant! - ARI $sp, -1 # allocate a word on the stack - CPW $sp, 0, $gp, 1 # put 1025 in stack top - ADDI $sp, 0, -1 # make $sp be 1024 - SUB $sp, 0, $sp, 0 # zero out the top of the stack - ARI $sp, -1 # allocate a word on the stack - CPW $gp, 2, $sp, 0 # put 'Y' on top of stack - SLL $sp, 0, 8 # shift it 8 bits to the left - BOR $sp, 0, $gp, 0 # put '\n' on top of stack - PCH $sp, 1 # print the 'Y' - PCH $sp, 0 # print '\n' - RTN - SUB $sp, 0, $sp, 0 # zero out the top of the stack - DIV $sp, 0 # cause a division by 0 error - EXIT 1 - -.data 2048 - CHAR nl = '\n' - WORD newsp = 1025 - CHAR ychar = 'Y' - WORD c - WORD sixteen = 0x10 - -.stack 6144 -.end diff --git a/vm/parser_test5.lst b/vm/parser_test5.lst deleted file mode 100755 index 72103e3..0000000 --- a/vm/parser_test5.lst +++ /dev/null @@ -1,47 +0,0 @@ -Address Instruction - 0: LIT $sp, 0, 0 - 1: SUB $sp, -1, $sp, 0 - 2: AND $sp, -2, $sp, -3 - 3: SRI $sp, 3 - 4: BORI $sp, 0, 0x8 - 5: JREL 3 # target is word address 8 - 6: NOR $ra, -1, $sp, 0 - 7: XOR $sp, -2, $sp, -1 - 8: MUL $r5, 0 - 9: CFHI $sp, 0 - 10: CFLO $fp, 0 - 11: LIT $sp, -1, 1 - 12: LWR $r5, $sp, -1 - 13: SRI $sp, 1 - 14: DIV $sp, 0 - 15: ADDI $sp, 0, 13 - 16: ADD $gp, 0, $gp, 0 - 17: CALL 19 # target is word address 19 - 18: EXIT 0 - 19: ANDI $sp, 0, 0xff - 20: XORI $sp, 0, 0x0 - 21: BEQ $sp, 0, 2 # target is word address 23 - 22: BNE $sp, 0, 333 # target is word address 355 - 23: BGEZ $sp, 0, 3 # target is word address 26 - 24: ADDI $sp, 0, 11 - 25: BGTZ $sp, 1, -2 # target is word address 23 - 26: BLTZ $sp, 1, 2 # target is word address 28 - 27: BLEZ $sp, 0, 2 # target is word address 29 - 28: CPW $sp, 0, $gp, 1 - 29: LWR $fp, $sp, 0 - 30: ARI $sp, -1 - 31: CPW $sp, 0, $gp, 1 - 32: ADDI $sp, 0, -1 - 33: SUB $sp, 0, $sp, 0 - 34: ARI $sp, -1 - 35: CPW $gp, 2, $sp, 0 - 36: SLL $sp, 0, 8 - 37: BOR $sp, 0, $gp, 0 - 38: PCH $sp, 1 - 39: PCH $sp, 0 - 40: RTN - 41: SUB $sp, 0, $sp, 0 - 42: DIV $sp, 0 - 43: EXIT 1 - 2048: 10 2049: 1025 2050: 89 2051: 0 2052: 16 - 2053: 0 ... diff --git a/vm/parser_test6.asm b/vm/parser_test6.asm deleted file mode 100755 index f3db38e..0000000 --- a/vm/parser_test6.asm +++ /dev/null @@ -1,36 +0,0 @@ -# $Id: parser_test6.asm,v 1.5 2024/08/28 21:25:00 leavens Exp $ -.text start -zero: SUB $sp, 0, $sp, 0 - AND $sp, 0, $sp, 0 - BOR $sp, 0, $sp, 0 - NOR $sp, 0, $sp, 0 # why? - XOR $sp, 0, $sp, 0 # & why not? - MUL $sp, 0 - CFHI $sp, 0 - CFLO $sp, -1 - RTN -start: ADDI $sp, 0, 13 - ADD $sp, 0, $ra, 0 - CALL zero - ANDI $sp, 0, 0x8 - XORI $sp, -1, 0x567a - BEQ $sp, -1, 2 - BNE $sp, -1, 4 - BGEZ $sp, 0, 3 - BGTZ $sp, 0, 2 - BLTZ $sp, 0, 1 - BLEZ $sp, 1, 2 - SRI $sp, 1 - LIT $sp, 0, 100 - LIT $sp, -1, 10 - MUL $sp, -1 - STRA - NOTR - EXIT 0 -.data 2048 -WORD w0 = 10 -WORD w1 = 0 -WORD w2 = -52345 -WORD w3 = 16 -.stack 6144 -.end diff --git a/vm/parser_test6.lst b/vm/parser_test6.lst deleted file mode 100755 index 1bb1a9b..0000000 --- a/vm/parser_test6.lst +++ /dev/null @@ -1,30 +0,0 @@ -Address Instruction - 0: SUB $sp, 0, $sp, 0 - 1: AND $sp, 0, $sp, 0 - 2: BOR $sp, 0, $sp, 0 - 3: NOR $sp, 0, $sp, 0 - 4: XOR $sp, 0, $sp, 0 - 5: MUL $sp, 0 - 6: CFHI $sp, 0 - 7: CFLO $sp, -1 - 8: RTN - 9: ADDI $sp, 0, 13 - 10: ADD $sp, 0, $ra, 0 - 11: CALL 0 # target is word address 0 - 12: ANDI $sp, 0, 0x8 - 13: XORI $sp, -1, 0x567a - 14: BEQ $sp, -1, 2 # target is word address 16 - 15: BNE $sp, -1, 4 # target is word address 19 - 16: BGEZ $sp, 0, 3 # target is word address 19 - 17: BGTZ $sp, 0, 2 # target is word address 19 - 18: BLTZ $sp, 0, 1 # target is word address 19 - 19: BLEZ $sp, 1, 2 # target is word address 21 - 20: SRI $sp, 1 - 21: LIT $sp, 0, 100 - 22: LIT $sp, -1, 10 - 23: MUL $sp, -1 - 24: STRA - 25: NOTR - 26: EXIT 0 - 2048: 10 2049: 0 2050: -52345 2051: 16 2052: 0 - ... diff --git a/vm/parser_types.h b/vm/parser_types.h deleted file mode 100755 index 05192cb..0000000 --- a/vm/parser_types.h +++ /dev/null @@ -1,11 +0,0 @@ -/* $Id: parser_types.h,v 1.5 2023/09/09 20:45:49 leavens Exp $ */ -#ifndef _PARSER_TYPES_H -#define _PARSER_TYPES_H - -#include "ast.h" - -// The type of Bison's parser stack elements (parse values) -typedef AST YYSTYPE; -#define YYSTYPE_IS_DECLARED 1 - -#endif diff --git a/vm/pass1.c b/vm/pass1.c deleted file mode 100755 index 8ca306c..0000000 --- a/vm/pass1.c +++ /dev/null @@ -1,143 +0,0 @@ -// $Id: pass1.c,v 1.6 2024/07/29 02:01:32 leavens Exp $ -#include -#include "pass1.h" -#include "symtab.h" -#include "utilities.h" - -// Build the symbol table and check for duplicate declarations in the given AST -void pass1(ast_program_t progast) -{ - symtab_initialize(); - pass1TextSection(progast.textSection); - pass1DataSection(progast.dataSection); -} - -// Check the given AST and put its declarations in the symbol table -void pass1TextSection(ast_text_section_t ts) -{ - pass1AsmInstrs(ts.instrs); -} - -// Check the given AST and put its declarations in the symbol table -void pass1AsmInstrs(ast_asm_instrs_t instrs) -{ - ast_asm_instr_t *ip = instrs.instrs; - address_type count = 0; - while (ip != NULL) { - pass1AsmInstr(*ip, count); - ip = ip->next; - count++; - } -} - -// Check the given AST and put its declarations in the symbol table -void pass1AsmInstr(ast_asm_instr_t instr, address_type count) -{ - pass1LabelOpt(instr.label_opt, count); -} - -// Check the given AST and put its declarations in the symbol table -void pass1LabelOpt(ast_label_opt_t lopt, address_type count) -{ - if (lopt.name != NULL) { - id_attrs_assoc attrs; - if (symtab_defined(lopt.name)) { - bail_with_error("Duplicate declaration of label \"%s\"", - lopt.name); - } - attrs.name = lopt.name; - attrs.kind = id_label; - attrs.addr = count; - symtab_insert(attrs); - } -} - -// Check the given AST and put its declarations in the symbol table -void pass1DataSection(ast_data_section_t ds) -{ - pass1StaticDecls(ds.staticDecls); -} - -// Check the given AST and put its declarations in the symbol table -void pass1StaticDecls(ast_static_decls_t sds) -{ - address_type offset = 0; - ast_static_decl_t *dcl = sds.decls; - while (dcl != NULL) { - pass1StaticDecl(*dcl, offset); - offset += dcl->size_in_words; - dcl = dcl->next; - } -} - -// Check the given AST and put its declarations in the symbol table -void pass1StaticDecl(ast_static_decl_t dcl, address_type offset) -{ - pass1DeclareIdent(dcl.ident, offset); -} - -// Check the given AST and put its declarations in the symbol table -void pass1DeclareIdent(ast_ident_t id, address_type offset) -{ - if (symtab_defined(id.name)) { - bail_with_error("Duplicate declaration of data name \"%s\"", - id.name); - } - id_attrs_assoc assoc; - assoc.name = id.name; - assoc.kind = id_data; - assoc.addr = offset; - symtab_insert(assoc); -} - -// Print, on out, the header line for the printed output -// followed by a newline -static void pass1_print_header(FILE *out) -{ - fprintf(out, "%-5s %s\t%s\n", "Kind", "Name", "Address"); -} - -static const char *id_attr_kind_2_string(id_attr_kind k) { - switch (k) { - case id_label: - return "Label"; - break; - case id_data: - return "Data"; - break; - default: - bail_with_error("Unknown id_attr_kind in id_attr_kind_2_string (%d)", - k); - break; - } - return NULL; -} - -// Requires: symtab_defined(name); -// Print, on out, a line with the symbol table's information about name -// followed by a newline -static void pass1_print_name_info(FILE *out, const char *name) -{ - id_attrs_assoc na, *assoc; - assoc = symtab_lookup(name); - if (assoc == NULL) { - bail_with_error("pass1_print_name_info given NULL pointer!"); - } else { - na = *assoc; - } - fprintf(out, "%-5s %s\t%u\n", id_attr_kind_2_string(na.kind), - na.name, na.addr); -} - -// Requires: out is a character file (like stdout) -// that is open for writing -// Print debugging information about the symbol table on out -void pass1_print(FILE *out) -{ - pass1_print_header(out); - const char *name = name = symtab_first_name(); - while (symtab_more_after(name)) { - pass1_print_name_info(out, name); - name = symtab_next_name(name); - } -} diff --git a/vm/pass1.h b/vm/pass1.h deleted file mode 100755 index 85e283c..0000000 --- a/vm/pass1.h +++ /dev/null @@ -1,40 +0,0 @@ -// $Id: pass1.h,v 1.4 2024/07/26 12:44:46 leavens Exp $ -#ifndef _PASS1_H -#define _PASS1_H -#include -#include "ast.h" -#include "machine_types.h" - -// Build the symbol table and check for duplicate declarations in the given AST -extern void pass1(ast_program_t progast); - -// Check the given AST and put its declarations in the symbol table -extern void pass1TextSection(ast_text_section_t ts); - -// Check the given AST and put its declarations in the symbol table -extern void pass1AsmInstrs(ast_asm_instrs_t instrs); - -// Check the given AST and put its declarations in the symbol table -extern void pass1AsmInstr(ast_asm_instr_t instr, address_type count); - -// Check the given AST and put its declarations in the symbol table -extern void pass1LabelOpt(ast_label_opt_t lopt, address_type count); - -// Check the given AST and put its declarations in the symbol table -extern void pass1DataSection(ast_data_section_t ds); - -// Check the given AST and put its declarations in the symbol table -extern void pass1StaticDecls(ast_static_decls_t sds); - -// Check the given AST and put its declarations in the symbol table -extern void pass1StaticDecl(ast_static_decl_t dcl, address_type offset); - -// Check the given AST and put its declarations in the symbol table -extern void pass1DeclareIdent(ast_ident_t id, address_type offset); - -// Requires: out is a character file (like stdout) -// that is open for writing -// Print debugging information about the symbol table on out -void pass1_print(FILE *out); - -#endif diff --git a/vm/regname.c b/vm/regname.c deleted file mode 100755 index 158869b..0000000 --- a/vm/regname.c +++ /dev/null @@ -1,12 +0,0 @@ -// $Id: regname.c,v 1.3 2024/07/29 12:38:50 leavens Exp $ -#include "regname.h" - -static const char *regnames[NUM_REGISTERS] = { - "$gp", "$sp", "$fp", "$r3", "$r4", "$r5", "$r6", "$ra" }; - -// requires 0 <= n && n < NUM_REGISTERS -// Return the standard symbolic name for n -const char *regname_get(reg_num_type n) -{ - return regnames[n]; -} diff --git a/vm/regname.h b/vm/regname.h deleted file mode 100755 index 33208df..0000000 --- a/vm/regname.h +++ /dev/null @@ -1,18 +0,0 @@ -// $Id: regname.h,v 1.5 2024/07/29 12:38:50 leavens Exp $ -#ifndef _REGNAME_H -#define _REGNAME_H -#include "machine_types.h" - -#define NUM_REGISTERS 8 - -// some important register numbers in the ISA -#define GP 0 -#define SP 1 -#define FP 2 -#define RA 7 - -// requires 0 <= n && n < NUM_REGISTERS -// Return the standard symbolic name for n -extern const char *regname_get(reg_num_type n); -#endif - diff --git a/vm/run-tests.sh b/vm/run-tests.sh deleted file mode 100755 index 3066907..0000000 --- a/vm/run-tests.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -: ${PREFIX=lexer_test} -for suf in bof lst out -do - for i in $@ - do - rm -f ${PREFIX}${i}.${suf} - make IMTHEINSTRUCTOR=true ${PREFIX}${i}.${suf} - done -done diff --git a/vm/show_magic.c b/vm/show_magic.c deleted file mode 100755 index b048fd7..0000000 --- a/vm/show_magic.c +++ /dev/null @@ -1,12 +0,0 @@ -// $Id: show_magic.c,v 1.1 2024/07/09 17:48:37 leavens Exp $ - -#include -#include -#include "bof.h" - -extern void bof_write_magic(FILE *f); - -int main() { - bof_write_magic(stdout); - exit(EXIT_SUCCESS); -} diff --git a/vm/srm-asm.aux b/vm/srm-asm.aux deleted file mode 100755 index 4cadcd4..0000000 --- a/vm/srm-asm.aux +++ /dev/null @@ -1,36 +0,0 @@ -\relax -\providecommand\hyper@newdestlabel[2]{} -\providecommand\HyperFirstAtBeginDocument{\AtBeginDocument} -\HyperFirstAtBeginDocument{\ifx\hyper@anchor\@undefined -\global\let\oldnewlabel\newlabel -\gdef\newlabel#1#2{\newlabelxx{#1}#2} -\gdef\newlabelxx#1#2#3#4#5#6{\oldnewlabel{#1}{{#2}{#3}}} -\AtEndDocument{\ifx\hyper@anchor\@undefined -\let\newlabel\oldnewlabel -\fi} -\fi} -\global\let\hyper@last\relax -\gdef\HyperFirstAtBeginDocument#1{#1} -\providecommand\HyField@AuxAddToFields[1]{} -\providecommand\HyField@AuxAddToCoFields[2]{} -\bibstyle{plain} -\citation{Kane-Heinrich92} -\@writefile{toc}{\contentsline {section}{\numberline {1}Overview}{1}{section.1}\protected@file@percent } -\@writefile{toc}{\contentsline {subsection}{\numberline {1.1}Inputs and Outputs}{1}{subsection.1.1}\protected@file@percent } -\@writefile{toc}{\contentsline {subsubsection}{\numberline {1.1.1}Assembler}{1}{subsubsection.1.1.1}\protected@file@percent } -\@writefile{toc}{\contentsline {subsubsection}{\numberline {1.1.2}Disassembler}{1}{subsubsection.1.1.2}\protected@file@percent } -\@writefile{toc}{\contentsline {subsection}{\numberline {1.2}Error Outputs}{2}{subsection.1.2}\protected@file@percent } -\@writefile{toc}{\contentsline {subsection}{\numberline {1.3}Exit Code}{2}{subsection.1.3}\protected@file@percent } -\@writefile{toc}{\contentsline {section}{\numberline {2}Assembly Language Syntax}{2}{section.2}\protected@file@percent } -\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}Lexical Grammar}{2}{subsection.2.1}\protected@file@percent } -\@writefile{toc}{\contentsline {subsection}{\numberline {2.2}Context-Free Grammar}{2}{subsection.2.2}\protected@file@percent } -\@writefile{toc}{\contentsline {section}{\numberline {3}Initial Values}{2}{section.3}\protected@file@percent } -\newlabel{sec:initialvalues}{{3}{2}{Initial Values}{section.3}{}} -\@writefile{toc}{\contentsline {section}{\numberline {4}Constraints on Assembly Code}{2}{section.4}\protected@file@percent } -\@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces Lexical grammar of the SRM assembler. This grammar uses a \texttt {terminal font} for terminal symbols. Note that an underbar (\texttt {\_}) and all ASCII letters (a-z and A-Z) are included in the production for \mbox {$\langle $\textrm {letter}$\rangle $}. Curly brackets, such as $\{x\}$, mean an arbitrary number of (i.e., 0 or more) repetitions of $x$. Note that curly braces are not terminal symbols in this grammar. Some character classes are described in English, these are described in a Roman font between double quotation marks (`` and ''). Note that all characters matched by the nonterminal \mbox {$\langle $\textrm {ignored}$\rangle $} are ignored by the lexer. However, the characters that are part of an \mbox {$\langle $\textrm {eol}$\rangle $} token (i.e., carriage returns and newlines) are not ignored immediately following a semicolon, \mbox {$\langle $\textrm {reserved-opcode}$\rangle $} or \mbox {$\langle $\textrm {reserved-data-size}$\rangle $}, although they are ignored in all other contexts. }}{3}{figure.1}\protected@file@percent } -\newlabel{fig:lexical-grammar}{{1}{3}{Lexical grammar of the SRM assembler. This grammar uses a \texttt {terminal font} for terminal symbols. Note that an underbar (\texttt {\_}) and all ASCII letters (a-z and A-Z) are included in the production for \nonterm {letter}. Curly brackets, such as $\arbno {x}$, mean an arbitrary number of (i.e., 0 or more) repetitions of $x$. Note that curly braces are not terminal symbols in this grammar. Some character classes are described in English, these are described in a Roman font between double quotation marks (`` and ''). Note that all characters matched by the nonterminal \nonterm {ignored} are ignored by the lexer. However, the characters that are part of an \nonterm {eol} token (i.e., carriage returns and newlines) are not ignored immediately following a semicolon, \nonterm {reserved-opcode} or \nonterm {reserved-data-size}, although they are ignored in all other contexts}{figure.1}{}} -\@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces The (context free) grammar of the SRM assembler, which uses a \texttt {typewriter font} for terminal symbols. }}{4}{figure.2}\protected@file@percent } -\newlabel{fig:cfg}{{2}{4}{The (context free) grammar of the SRM assembler, which uses a \texttt {typewriter font} for terminal symbols}{figure.2}{}} -\bibdata{srm-vm.bib} -\bibcite{Kane-Heinrich92}{1} -\gdef \@abspage@last{5} diff --git a/vm/srm-asm.bbl b/vm/srm-asm.bbl deleted file mode 100755 index 125f80e..0000000 --- a/vm/srm-asm.bbl +++ /dev/null @@ -1,8 +0,0 @@ -\begin{thebibliography}{1} - -\bibitem{Kane-Heinrich92} -Gerry Kane and Joe Heinrich. -\newblock {\em {MIPS RISC} architectures}. -\newblock Prentice-Hall, Inc., 1992. - -\end{thebibliography} diff --git a/vm/srm-asm.tex b/vm/srm-asm.tex deleted file mode 100755 index 9b71985..0000000 --- a/vm/srm-asm.tex +++ /dev/null @@ -1,322 +0,0 @@ -% $Id: srm-asm.tex,v 1.29 2023/09/20 19:43:09 leavens Exp $ -\documentclass[11pt,letterpaper]{article} -\usepackage[T1]{fontenc} -\usepackage{times} -\usepackage{textcomp} %required to set upquote flag and for luximono -%\usepackage[scaled=0.81]{luximono} -\usepackage{enumitem} -\usepackage{listings} -\usepackage{color} -\usepackage{ragged2e} -\lstset{language=C,basicstyle=\ttfamily,commentstyle=\rmfamily\itshape} -\lstset{morecomment=[l]{//}, %use comment-line-style! - morecomment=[s]{/*}{*/}} %for multiline comments -\lstset{upquote=true} %FH -% The following is needed for C programs -\lstset{showspaces=false,showstringspaces=false} -%\lstset{mathescape=true} -\input{boxed-figure-new} -% getting files for figures -\newcommand{\LSTFILE}[1]{ -\lstinputlisting[basicstyle=\small\ttfamily]{#1} -} -\newcommand{\LSTFILESLICE}[2]{ -\lstinputlisting[basicstyle=\small\ttfamily,linerange={#1}]{#2} -} -% -\newcommand{\LSTCFILE}[1]{ -\lstinputlisting[language=C,basicstyle=\small\ttfamily]{#1} -} -\usepackage[bookmarks=false]{hyperref} -%\usepackage{varioref} % doesn't work with hyperref, it seems, sigh -%\renewcommand{\reftextfacebefore}{on the previous page} -%\renewcommand{\reftextfaceafter}{on the next page} -\newcommand{\tabref}[1]{Table~\ref{#1}} % vref from varioref -\newcommand{\tabnref}[1]{Table~\ref{#1}} % doesn't use varioref -\newcommand{\figref}[1]{Figure~\ref{#1}} % vref from varioref -\newcommand{\fignref}[1]{Figure~\ref{#1}} % doesn't use varioref -\newcommand{\secref}[1]{Section~\ref{#1}} % vref from varioref -\newcommand{\secnref}[1]{Section~\ref{#1}} % doesn't use varioref - -\input{obey} -\input{grammar} -\renewcommand{\nonterm}[1]{\mbox{$\langle$\textrm{#1}$\rangle$}} -\renewcommand{\arbno}[1]{\{#1\}} -\newcommand{\gramquote}[1]{\textrm{`}#1\textrm{'}} -\input{use-full-height} -\input{use-full-width} -\input{continuedenum} - -\setlength\RaggedRightParindent{\parindent} -\input{srm-isa.tex} -\newcommand{\IFO}[2]{\textrm{\textbf{if} \ensuremath{#1} \textbf{then} \ensuremath{#2} }} -\newcommand{\IF}[3]{\textrm{\textbf{if} #1 \textbf{then} #2 \textbf{else} #3}} -\newcommand{\EQUALS}{\ensuremath{=}} % or {\ensuremath{\:\texttt{==}\:}} -% -\bibliographystyle{plain} -% -\title{Simplified RISC Machine Assembler Manual \\ - (\lstinline!$Revision: 1.29 $!)} -\author{Gary T. Leavens \\ - Leavens@ucf.edu} -\begin{document} - -\maketitle -\begin{abstract} -This document defines the assembly language for the -Simplified RISC Machine VM, which is used in the Systems Software -class (COP 3402) at UCF. -It also defines the interface of the assembler and disassembler. -\end{abstract} - -\section{Overview} - -The assembler for the Simplified RISC Machine (SRM) is simple and has -no macro facilities. However, it does let one assemble the -instructions that make up a program, resolving symbolic names for jump targets, -and it can define the starting -address of a program and the program's (static) data section. -The opcodes generally follow those for the MIPS processor's ISA -\cite{Kane-Heinrich92} albeit in simplified form. - -The assembler assumes that the SRM has $\WS$-bit ($\WSinBytes$-byte) -words and is byte-addressable. - -\subsection{Inputs and Outputs} - -\subsubsection{Assembler} - -The assembler is passed a single file name as its only command line argument; -this file should be the name of a (readable) assembler program; -its output (sent to standard output) is a binary object file. - -For example, if the program is contained in the file -\texttt{myProg.srm}, assuming that the assembler is named \texttt{asm}, -(and both these files are in the current directory), then the assembler -can be invoked as follows in the Unix shell to produce a binary object file on standard output. -\begin{lstlisting} - ./asm myProg.srm -\end{lstlisting} - -Thus, to put the assembled version of \texttt{myProg.srm} into the file \texttt{myProg.bof}, -one would use a Unix command that redirects the output of the assembler into \texttt{myProg.bof}, as follows. - -\begin{lstlisting} - ./asm myProg.srm > myProg.bof -\end{lstlisting} - -\subsubsection{Disassembler} - -The disassembler is the opposite of the assembler. -It is passed a single file name, but that file names a (readable) binary object -file, and it produces, on standard output, -an assembly language source program. - -For example, if the binary object file is found in \texttt{prog.bof}, -assuming that the disassembler is named \texttt{disasm}, -(and both these files are in the current directory), then the disassembler -can be invoked as follows in the Unix shell to produce (on standard -output) an assembly language program that would compile to \texttt{prog.bof}. - -\begin{lstlisting} - ./disasm prog.bof -\end{lstlisting} - -The assembly language program can be redirected into the file \texttt{prog.srm} as follows. - -\begin{lstlisting} - ./disasm prog.bof > prog.srm -\end{lstlisting} - -\subsection{Error Outputs} - -All error messages (e.g., for file permission errors or syntax errors) -are sent to standard error output (\texttt{stderr}). - -\subsection{Exit Code} - -When the either program halts normally, it exits with a zero error code -(which indicates success on Unix). However, when \texttt{asm} or -\texttt{disasm} encounters an error, -it halts and exits with a non-zero exit code -(which indicates failure on Unix). - -\section{Assembly Language Syntax} - -\subsection{Lexical Grammar} - -Tokens in the assembler are described by the (regular) -grammar of \figref{fig:lexical-grammar}. -Note that line endings are significant in the context-free grammar of -the assembler, as each instruction must be specified on a single line. -Lines may be ended either by a newline character (\nonterm{newline} in -\figref{fig:lexical-grammar}) -or by a combination of a carriage-return (\nonterm{cr}) followed by a newline. -Comments (\nonterm{comment}) start with a \nonterm{comment-start} (i.e., \texttt{\#}) -and continue to the end of a line. -White space is needed to separate tokens, but is otherwise ignored. - -\begin{figure} -\begin{grammar} -\nonterm{section-mark} \: .text \| .data \| .end -\nonterm{reserved-opcode} \: ADD \| SUB \| AND \| BOR \| NOR \| XOR \| MUL \| DIV -\> \| \> SLL \| SRL \| MFHI \| MFLO \| JR \| ADDI \| ANDI \| BORI \| XORI \| BEQ -\> \| \> BGEZ \| BGTZ \| BLTZ \| LBU \| LW \| SB \| SW \| JMP \| JAL -\nonterm{reserved-data-size} \: WORD -\nonterm{ident} \: \nonterm{letter} \arbno{\nonterm{letter-or-digit}} \textrm{``but not a \nonterm{reserved-opcode} or \nonterm{reserved-data-size}''} -\nonterm{letter} \: \_ \| a \| b \| $\ldots$ \| y \| z \| A \| B \| $\ldots$ \| Y \| Z -\nonterm{letter-or-digit} \: \nonterm{letter} \| \nonterm{dec-digit} - -\nonterm{unsigned-number} \: \nonterm{dec-digit} \arbno{\nonterm{dec-digit}} - \> \| \> 0x \nonterm{hex-digit} \arbno{\nonterm{hex-digit}} -\nonterm{dec-digit} \: 0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6 \| 7 \| 8 \| 9 -\nonterm{hex-digit} \: \nonterm{dec-digit} \| a \| A \| b \| B \| c \| C \| d \| D \| e \| E \| f \| F - -\nonterm{reg} \: \nonterm{dollar-sign} \nonterm{unsigned-number} \| \$at \| \$v0 \| \$v1 -\> \| \> \$a0 \| \$a1 \| \$a2 \| \$a3 \| \$t0 \| \$t1 \| \$t2 \| \$t3 \| \$t4 \| \$t5 \| \$t6 \| \$t7 -\> \| \> \$s0 \| \$s1 \| \$s2 \| \$s3 \| \$s4 \| \$s5 \| \$s6 \| \$s7 \| \$t8 \| \$t9 -\> \| \> \$gp \| \$sp \| \$fp \| \$ra -\nonterm{dollar-sign} \: \$ - -\nonterm{eol} \: \nonterm{newline} \| \nonterm{cr} \nonterm{newline} -\nonterm{newline} \: \textrm{``A newline character (ASCII 10)''} -\nonterm{cr} \: \textrm{``A carriage return character (ASCII 13)''} - -\nonterm{ignored} \: \nonterm{blank} \| \nonterm{tab} \| \nonterm{vt} \| \nonterm{formfeed} \| \nonterm{comment} -\nonterm{blank} \: \textrm{``A space character (ASCII 32)''} -\nonterm{tab} \: \textrm{``A horizontal tab character (ASCII 9)''} -\nonterm{vt} \: \textrm{``A vertical tab character (ASCII 11)''} -\nonterm{formfeed} \: \textrm{``A formfeed character (ASCII 12)''} -\nonterm{comment} \: \nonterm{comment-start} \arbno{\nonterm{non-nl}} -\nonterm{comment-start} \: \# -\nonterm{non-nl} \: \textrm{``Any character except a newline''} -\end{grammar} -\caption{ - Lexical grammar of the SRM assembler. - This grammar uses a \texttt{terminal font} - for terminal symbols. Note that an underbar (\texttt{\_}) and - all ASCII letters (a-z and A-Z) are included in the production - for \nonterm{letter}. - Curly brackets, such as $\arbno{x}$, mean an arbitrary number of - (i.e., 0 or more) repetitions of $x$. - Note that curly braces are not terminal symbols in this grammar. - Some character classes are described in English, these are described - in a Roman font between double quotation marks (`` and ''). - Note that all characters matched by the nonterminal - \nonterm{ignored} are ignored by the lexer. - However, the characters that are part of an \nonterm{eol} token - (i.e., carriage returns and newlines) are - not ignored immediately following a semicolon, - \nonterm{reserved-opcode} or \nonterm{reserved-data-size}, although - they are ignored in all other contexts. - } -\label{fig:lexical-grammar} -\end{figure} - -\subsection{Context-Free Grammar} - -The syntax of the SRM's assembly language is defined by the -(context-free) grammar in \figref{fig:cfg}. - -\begin{figure} -\begin{grammar}% -\nonterm{program} \: \nonterm{text-section} \nonterm{data-section} \nonterm{stack-section} .end -\nonterm{text-section} \: .text \nonterm{entry-point} \nonterm{asm-instr} \arbno{\nonterm{asm-instr}} -\nonterm{entry-point} \: \nonterm{addr} -\nonterm{addr} \: \nonterm{label} \| \nonterm{unsigned-number} -\nonterm{label} \: \nonterm{ident} -\nonterm{asm-instr} \: \nonterm{label-opt} \nonterm{instr} \nonterm{eol} -\nonterm{label-opt} \: \nonterm{label}~:~\| \nonterm{empty} -\nonterm{empty} \: -\nonterm{instr} \: \nonterm{three-reg-instr} \| \nonterm{two-reg-instr} \| \nonterm{shift-instr} \| \nonterm{one-reg-instr} -\> \| \> \nonterm{immed-arith-instr} \| \nonterm{immed-bool-instr} \| \nonterm{branch-test-instr} \| \nonterm{load-store-instr} -\> \| \> \nonterm{jump-instr} -\nonterm{three-reg-instr} \: \nonterm{three-reg-op} \nonterm{reg} , \nonterm{reg} , \nonterm{reg} -\nonterm{three-reg-op} \: ADD \| SUB \| AND \| BOR \| NOR \| XOR -\nonterm{two-reg-instr} \: \nonterm{two-reg-op} \nonterm{reg} , \nonterm{reg} -\nonterm{two-reg-op} \: MUL \| DIV -\nonterm{shift-instr} \: \nonterm{shift-op} \nonterm{reg} , \nonterm{reg} , \nonterm{shift} -\nonterm{shift-op} \: SLL \| SRL -\nonterm{shift} \: \nonterm{unsigned-number} -\nonterm{one-reg-instr} \: \nonterm{one-reg-op} \nonterm{reg} -\nonterm{one-reg-op} \: MFHI \| MFLO \| JR -\nonterm{immed-arith-instr} \: \nonterm{immed-arith-op} \nonterm{reg} , \nonterm{reg} , \nonterm{immed} -\nonterm{immed-arith-op} \: ADDI -\nonterm{immed} \: \nonterm{number} -\nonterm{number} \: \nonterm{sign} \nonterm{unsigned-number} -\nonterm{sign} \: + \| - \| \nonterm{empty} -\nonterm{immed-bool-instr} \: \nonterm{immed-bool-op} \nonterm{reg} , \nonterm{reg} , \nonterm{uimmed} -\nonterm{immed-bool-op} \: ANDI \| BORI \| XORI -\nonterm{uimmed} \: \nonterm{unsigned-number} -\nonterm{branch-test-instr} \: \nonterm{branch-test-2-op} \nonterm{reg} , \nonterm{reg} , \nonterm{offset} -\> \| \> \nonterm{branch-test-1-op} \nonterm{reg} , \nonterm{offset} -\nonterm{branch-test-2-op} \: BEQ \| BNE -\nonterm{branch-test-1-op} \: BGEZ \| BGTZ \| BLEZ \| BLTZ -\nonterm{offset} \: \nonterm{number} -\nonterm{load-store-instr} \: \nonterm{load-store-op} \nonterm{reg} , \nonterm{reg} , \nonterm{offset} -\nonterm{load-store-op} \: LBU \| LW \| SB \| SW -\nonterm{jump-instr} \: \nonterm{jump-op} \nonterm{addr} -\nonterm{jump-op} \: JMP \| JAL -\nonterm{syscall-instr} \: \nonterm{syscall-op} -\nonterm{syscall-op} \: EXIT | PSTR | PCH | RCH | RSTR | STRA | NOTR -\nonterm{data-section} \: .data \nonterm{static-start-addr} \arbno{\nonterm{static-decl}} -\nonterm{static-start-addr} \: \nonterm{unsigned-number} -\nonterm{static-decl} \: \nonterm{data-size} \nonterm{ident} \nonterm{initializer-opt} \nonterm{eol} -\nonterm{data-size} \: WORD -\nonterm{initializer-opt} \: = \nonterm{number} \| \nonterm{empty} -\nonterm{stack-section} \: .stack \nonterm{stack-bottom-addr} -\nonterm{stack-bottom-addr} \: \nonterm{unsigned-number}% -\end{grammar} -\caption{ - The (context free) grammar of the SRM assembler, which uses - a \texttt{typewriter font} for terminal symbols. -} -\label{fig:cfg} -\end{figure} - -\section{Initial Values} -\label{sec:initialvalues} - -The initial value of the program counter ($\PC$) is set to the address of the -program's entry point (i.e., the value of \nonterm{entry-point}), -which is declared at the beginning of the \nonterm{text-section}. - -The start of the global data in memory is at the address given by the -data section's static data start address -(i.e., the value of \nonterm{static-start-addr}), declared at the -beginning of the \nonterm{data-section}; -this value is used as the initial value of the $\GP$ register. -The data declared in the data section all have offsets from this -address that are computed in declaration order, with \texttt{WORD} sized data -taking $\WSinBytes$ bytes. -(\texttt{WORD} is the only data size allowed at present.) - -The ``bottom'' of the runtime stack is given in a declaration in -the stack section (\nonterm{stack-section}); -it is the value of \nonterm{stack-bottom-addr} that follows the -\texttt{.stack} keyword. -This must be divisible by $\WSinBytes$ and strictly greater than the -static data start address; it is also the initial value put in -the $\FP$ and $\SP$ registers at the start of a program's execution. - -\section{Constraints on Assembly Code} - -There are some constraints on programs that the assembler checks; -the assembler considers violations of these constraints to be an error. - -The program's entry point (\nonterm{entry-point} value), -static data start address (\nonterm{static-start-addr} value), -and stack bottom address (\nonterm{stack-bottom-addr} value) -must all be divisible by $\WSinBytes$. -Furthermore, the entry point must be strictly less than the static -data start address and the static data strart address must be strictly -less than the stack bottom address. - -% Word-sized data declared in the data section must be aligned; -% that is, the offset of every word declared in the data section -% (the number of bytes past the start of the data section) -% must be divisible by $\WSinBytes$. - -\bibliography{srm-vm.bib} - -\end{document} diff --git a/vm/srm-isa.tex b/vm/srm-isa.tex deleted file mode 100755 index e5f8626..0000000 --- a/vm/srm-isa.tex +++ /dev/null @@ -1,45 +0,0 @@ -% $Id: srm-isa.tex,v 1.3 2023/09/16 12:41:27 leavens Exp $ -% Macros for the ISA follow -\newcommand{\WS}{32} -\newcommand{\WSP}{31} -\newcommand{\WSinBytes}{4} -\newcommand{\LOGofRegs}{5} -\newcommand{\WSminusOP}{26} -\newcommand{\INITIALSTACKBOTTOM}{4096} -\newcommand{\NAMEDREG}[1]{\textsf{\$#1}} -\newcommand{\BP}{\FP} -\newcommand{\GP}{\NAMEDREG{gp}} -\newcommand{\FP}{\NAMEDREG{fp}} -\newcommand{\SP}{\NAMEDREG{sp}} -\newcommand{\RA}{\NAMEDREG{ra}} -\newcommand{\RS}{\NAMEDREG{rs}} -\newcommand{\RT}{\NAMEDREG{rt}} -\newcommand{\RD}{\NAMEDREG{rd}} -\newcommand{\VZERO}{\NAMEDREG{v0}} -\newcommand{\AZERO}{\NAMEDREG{a0}} -\newcommand{\AONE}{\NAMEDREG{a1}} -\newcommand{\ATWO}{\NAMEDREG{a2}} -\newcommand{\GPR}[1]{\textrm{GPR[}#1\textrm{]}} -\newcommand{\IMMED}{\textit{i}} -\newcommand{\OFFSET}{\textit{o}} -\newcommand{\PC}{\textit{PC}} -\newcommand{\HI}{\textit{HI}} -\newcommand{\LO}{\textit{LO}} -\newcommand{\IR}{\textit{IR}} -\newcommand{\SIGNEXTENDNAME}{\textrm{sgnExt}} -\newcommand{\SIGNEXTEND}[1]{\SIGNEXTENDNAME(#1)} -\newcommand{\ZEROEXTENDNAME}{\textrm{zeroExt}} -\newcommand{\ZEROEXTEND}[1]{\ZEROEXTENDNAME(#1)} -\newcommand{\FORMOFFSETNAME}{\textrm{formOffset}} -\newcommand{\FORMOFFSET}[1]{\FORMOFFSETNAME(#1)} -\newcommand{\FORMADDRESSNAME}{\textrm{formAddress}} -\newcommand{\FORMADDRESS}[2]{\FORMADDRESSNAME(#1,#2)} -\newcommand{\MEMORYNAME}{\textrm{memory}} -\newcommand{\MEMORY}[1]{\ensuremath{\MEMORYNAME[#1]}} -\newcommand{\MOD}{\ensuremath{\:\hbox{\%}\:}} -\newcommand{\AND}{\ensuremath{\wedge}} -\newcommand{\OR}{\ensuremath{\vee}} -\newcommand{\XOR}{\ensuremath{\:\textrm{xor}\:}} -\newcommand{\LSHIFT}{\ensuremath{\:\texttt{<<}\:}} -\newcommand{\RSHIFT}{\ensuremath{\:\texttt{>>}\:}} -\newcommand{\GETS}{\ensuremath{\leftarrow}} diff --git a/vm/srm-lexertest1.asm b/vm/srm-lexertest1.asm deleted file mode 100755 index 0355bf4..0000000 --- a/vm/srm-lexertest1.asm +++ /dev/null @@ -1,14 +0,0 @@ -# $Id: srm-lexertest1.asm,v 1.4 2023/09/16 16:23:10 leavens Exp $ - -.text foo -foo: EXIT #some text$a.sa# - ADD $1, $2 , $3 - -.data 1024 -WORD x c -WORD y 42 -.stack 5120 -.end -asdflkasjf -_asb 0x42 - diff --git a/vm/srm-vm.aux b/vm/srm-vm.aux deleted file mode 100755 index 91345f4..0000000 --- a/vm/srm-vm.aux +++ /dev/null @@ -1,91 +0,0 @@ -\relax -\providecommand\hyper@newdestlabel[2]{} -\providecommand\HyperFirstAtBeginDocument{\AtBeginDocument} -\HyperFirstAtBeginDocument{\ifx\hyper@anchor\@undefined -\global\let\oldnewlabel\newlabel -\gdef\newlabel#1#2{\newlabelxx{#1}#2} -\gdef\newlabelxx#1#2#3#4#5#6{\oldnewlabel{#1}{{#2}{#3}}} -\AtEndDocument{\ifx\hyper@anchor\@undefined -\let\newlabel\oldnewlabel -\fi} -\fi} -\global\let\hyper@last\relax -\gdef\HyperFirstAtBeginDocument#1{#1} -\providecommand\HyField@AuxAddToFields[1]{} -\providecommand\HyField@AuxAddToCoFields[2]{} -\bibstyle{plain} -\citation{Kane-Heinrich92} -\@writefile{toc}{\contentsline {section}{\numberline {1}Overview}{1}{section.1}\protected@file@percent } -\@writefile{toc}{\contentsline {subsection}{\numberline {1.1}Inputs and Outputs}{1}{subsection.1.1}\protected@file@percent } -\@writefile{toc}{\contentsline {subsubsection}{\numberline {1.1.1}Binary Object Files}{1}{subsubsection.1.1.1}\protected@file@percent } -\@writefile{lol}{\contentsline {lstlisting}{bof.h}{2}{lstlisting.-2}\protected@file@percent } -\@writefile{lof}{\contentsline {figure}{\numberline {1}{\ignorespaces The \texttt {bof.h} header file that defines the format and operations for binary object files.}}{2}{figure.1}\protected@file@percent } -\newlabel{fig:bofh}{{1}{2}{The \texttt {bof.h} header file that defines the format and operations for binary object files}{figure.1}{}} -\@writefile{toc}{\contentsline {subsubsection}{\numberline {1.1.2}Initial/Default Values}{2}{subsubsection.1.1.2}\protected@file@percent } -\newlabel{sec:initial}{{1.1.2}{2}{Initial/Default Values}{subsubsection.1.1.2}{}} -\@writefile{lof}{\contentsline {figure}{\numberline {2}{\ignorespaces The layout of a binary object file.}}{3}{figure.2}\protected@file@percent } -\newlabel{fig:boffilelayout}{{2}{3}{The layout of a binary object file}{figure.2}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {1.2}The Running Program's Input and Output}{4}{subsection.1.2}\protected@file@percent } -\@writefile{toc}{\contentsline {subsection}{\numberline {1.3}Tracing Output}{4}{subsection.1.3}\protected@file@percent } -\@writefile{toc}{\contentsline {subsection}{\numberline {1.4}Printing the Program}{4}{subsection.1.4}\protected@file@percent } -\newlabel{sec:printing}{{1.4}{4}{Printing the Program}{subsection.1.4}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {1.5}Error Outputs}{4}{subsection.1.5}\protected@file@percent } -\@writefile{lol}{\contentsline {lstlisting}{vm\textunderscore test0.asm}{5}{lstlisting.-5}\protected@file@percent } -\@writefile{lof}{\contentsline {figure}{\numberline {3}{\ignorespaces The SRM assembly language file \texttt {vm\_test0.asm}.}}{5}{figure.3}\protected@file@percent } -\newlabel{fig:test0asm}{{3}{5}{The SRM assembly language file \texttt {vm\_test0.asm}}{figure.3}{}} -\@writefile{lol}{\contentsline {lstlisting}{vm\textunderscore test0.out}{5}{lstlisting.-6}\protected@file@percent } -\@writefile{lof}{\contentsline {figure}{\numberline {4}{\ignorespaces The tracing output of running the VM (with the \texttt {-t} option) on the file \texttt {vm\_test0.bof} (which is the result of using the assembler on \texttt {vm\_test0.asm}), with the command \texttt {./vm vm\_test0.bof}, as would be printed on standard output.}}{5}{figure.4}\protected@file@percent } -\newlabel{fig:test0output}{{4}{5}{The tracing output of running the VM (with the \texttt {-t} option) on the file \texttt {vm\_test0.bof} (which is the result of using the assembler on \texttt {vm\_test0.asm}), with the command \texttt {./vm vm\_test0.bof}, as would be printed on standard output}{figure.4}{}} -\@writefile{lol}{\contentsline {lstlisting}{vm\textunderscore test0.lst}{5}{lstlisting.-7}\protected@file@percent } -\@writefile{lof}{\contentsline {figure}{\numberline {5}{\ignorespaces The output of running \texttt {./vm -p vm\_test0.bof}. (where the file \texttt {vm\_test0.bof} is the result of assembling the file \texttt {vm\_test0.asm} that is shown in Figure\nobreakspace {}\ref {fig:test0asm}).}}{5}{figure.5}\protected@file@percent } -\newlabel{fig:test0listing}{{5}{5}{The output of running \texttt {./vm -p vm\_test0.bof}. (where the file \texttt {vm\_test0.bof} is the result of assembling the file \texttt {vm\_test0.asm} that is shown in \figref {fig:test0asm})}{figure.5}{}} -\citation{Kane-Heinrich92} -\@writefile{toc}{\contentsline {subsection}{\numberline {1.6}Exit Code}{6}{subsection.1.6}\protected@file@percent } -\@writefile{toc}{\contentsline {section}{\numberline {2}Architecture}{6}{section.2}\protected@file@percent } -\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}Registers}{6}{subsection.2.1}\protected@file@percent } -\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.1.1}General Purpose Registers and Their Names}{6}{subsubsection.2.1.1}\protected@file@percent } -\@writefile{lot}{\contentsline {table}{\numberline {1}{\ignorespaces SRM Register Numbers, Use, and Names}}{6}{table.1}\protected@file@percent } -\newlabel{tab:registers}{{1}{6}{SRM Register Numbers, Use, and Names}{table.1}{}} -\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.1.2}Special Purpose Registers}{6}{subsubsection.2.1.2}\protected@file@percent } -\@writefile{toc}{\contentsline {subsubsection}{\numberline {2.1.3}Calling Convention}{7}{subsubsection.2.1.3}\protected@file@percent } -\@writefile{toc}{\contentsline {subsection}{\numberline {2.2}Binary Instruction Format}{7}{subsection.2.2}\protected@file@percent } -\@writefile{lot}{\contentsline {table}{\numberline {2}{\ignorespaces SRM Instruction Formats}}{7}{table.2}\protected@file@percent } -\newlabel{tab:instrfmts}{{2}{7}{SRM Instruction Formats}{table.2}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {2.3}Machine Cycles}{7}{subsection.2.3}\protected@file@percent } -\@writefile{toc}{\contentsline {subsection}{\numberline {2.4}Size Limits}{8}{subsection.2.4}\protected@file@percent } -\@writefile{lol}{\contentsline {lstlisting}{machine.h}{8}{lstlisting.-8}\protected@file@percent } -\@writefile{toc}{\contentsline {subsection}{\numberline {2.5}Invariants}{8}{subsection.2.5}\protected@file@percent } -\@writefile{toc}{\contentsline {section}{\numberline {A}Appendix A}{8}{appendix.A}\protected@file@percent } -\newlabel{appsec:A}{{A}{8}{Appendix A}{appendix.A}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {A.1}Register/Computational Instructions}{9}{subsection.A.1}\protected@file@percent } -\@writefile{lot}{\contentsline {table}{\numberline {3}{\ignorespaces Register Format Instructions}}{9}{table.3}\protected@file@percent } -\newlabel{tab:rformatinstrs}{{3}{9}{Register Format Instructions}{table.3}{}} -\citation{Kane-Heinrich92} -\@writefile{toc}{\contentsline {subsection}{\numberline {A.2}Immediate Type Instructions}{10}{subsection.A.2}\protected@file@percent } -\@writefile{lot}{\contentsline {table}{\numberline {4}{\ignorespaces Immediate format instructions:}}{10}{table.4}\protected@file@percent } -\newlabel{tab:immedinstrs}{{4}{10}{Immediate format instructions:}{table.4}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {A.3}Jump Type Instructions}{10}{subsection.A.3}\protected@file@percent } -\@writefile{lot}{\contentsline {table}{\numberline {5}{\ignorespaces Jump Type Instructions}}{11}{table.5}\protected@file@percent } -\newlabel{tab:jumpinstrs}{{5}{11}{Jump Type Instructions}{table.5}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {A.4}System Calls}{11}{subsection.A.4}\protected@file@percent } -\newlabel{sec:syscall}{{A.4}{11}{System Calls}{subsection.A.4}{}} -\@writefile{lot}{\contentsline {table}{\numberline {6}{\ignorespaces System Calls}}{11}{table.6}\protected@file@percent } -\newlabel{tab:syscalls}{{6}{11}{System Calls}{table.6}{}} -\@writefile{toc}{\contentsline {section}{\numberline {B}Appendix B: Hints}{11}{appendix.B}\protected@file@percent } -\@writefile{toc}{\contentsline {subsection}{\numberline {B.1}Overall Structure of the Code}{11}{subsection.B.1}\protected@file@percent } -\@writefile{lof}{\contentsline {figure}{\numberline {6}{\ignorespaces A possible way to represent the memory of the VM, which allows access to the same storage as bytes, words, or binary instructions.}}{12}{figure.6}\protected@file@percent } -\newlabel{fig:memoryrep}{{6}{12}{A possible way to represent the memory of the VM, which allows access to the same storage as bytes, words, or binary instructions}{figure.6}{}} -\@writefile{toc}{\contentsline {subsection}{\numberline {B.2}Writing Your Own Tests}{12}{subsection.B.2}\protected@file@percent } -\citation{GNUMake} -\@writefile{toc}{\contentsline {subsection}{\numberline {B.3}Disassembler}{13}{subsection.B.3}\protected@file@percent } -\@writefile{toc}{\contentsline {subsection}{\numberline {B.4}Provided Files}{13}{subsection.B.4}\protected@file@percent } -\@writefile{toc}{\contentsline {subsubsection}{\numberline {B.4.1}Makefile}{13}{subsubsection.B.4.1}\protected@file@percent } -\bibdata{srm-vm.bib} -\bibcite{GNUMake}{1} -\@writefile{toc}{\contentsline {subsubsection}{\numberline {B.4.2}C Typedefs for SRM Machine Types}{14}{subsubsection.B.4.2}\protected@file@percent } -\@writefile{toc}{\contentsline {subsubsection}{\numberline {B.4.3}Other modules provided}{14}{subsubsection.B.4.3}\protected@file@percent } -\@writefile{lol}{\contentsline {lstlisting}{machine\textunderscore types.h}{15}{lstlisting.-11}\protected@file@percent } -\@writefile{lof}{\contentsline {figure}{\numberline {7}{\ignorespaces The header file of the \texttt {machine\_types} module, which provides some basic definitions for the VM.}}{15}{figure.7}\protected@file@percent } -\newlabel{fig:machinetypes}{{7}{15}{The header file of the \texttt {machine\_types} module, which provides some basic definitions for the VM}{figure.7}{}} -\bibcite{Kane-Heinrich92}{2} -\gdef \@abspage@last{16} diff --git a/vm/srm-vm.bbl b/vm/srm-vm.bbl deleted file mode 100755 index 07fcfa5..0000000 --- a/vm/srm-vm.bbl +++ /dev/null @@ -1,13 +0,0 @@ -\begin{thebibliography}{1} - -\bibitem{GNUMake} -Free Software Foundation. -\newblock {\em GNU Make Manual}, Feb 2023. -\newblock \url{https://www.gnu.org/software/make/manual/}. - -\bibitem{Kane-Heinrich92} -Gerry Kane and Joe Heinrich. -\newblock {\em {MIPS RISC} architectures}. -\newblock Prentice-Hall, Inc., 1992. - -\end{thebibliography} diff --git a/vm/srm-vm.bib b/vm/srm-vm.bib deleted file mode 100755 index 9b02cf6..0000000 --- a/vm/srm-vm.bib +++ /dev/null @@ -1,15 +0,0 @@ -@book{Kane-Heinrich92, - author={Gerry Kane and Joe Heinrich}, - title={{MIPS RISC} architectures}, - year={1992}, - publisher={Prentice-Hall, Inc.} -} - -@Manual{GNUMake, - title = {GNU Make Manual}, - key = {GNUMake}, - organization = {Free Software Foundation}, - month = {Feb}, - year = 2023, - note = {\url{https://www.gnu.org/software/make/manual/}} -} diff --git a/vm/srm-vm.tex b/vm/srm-vm.tex deleted file mode 100755 index 74d3833..0000000 --- a/vm/srm-vm.tex +++ /dev/null @@ -1,1017 +0,0 @@ -% $Id: srm-vm.tex,v 1.62 2023/11/15 19:41:22 leavens Exp leavens $ -\documentclass[11pt,letterpaper]{article} -\usepackage[T1]{fontenc} -\usepackage{times} -\usepackage{textcomp} %required to set upquote flag and for luximono -%\usepackage[scaled=0.81]{luximono} -\usepackage{enumitem} -\usepackage{listings} -\usepackage{graphics} -\usepackage{color} -\usepackage{ragged2e} -\lstset{language=C,basicstyle=\ttfamily,commentstyle=\rmfamily\itshape} -\lstset{morecomment=[l]{//}, %use comment-line-style! - morecomment=[s]{/*}{*/}} %for multiline comments -\lstset{upquote=true} %FH -% The following is needed for C programs -\lstset{showspaces=false,showstringspaces=false} -%\lstset{mathescape=true} -\input{boxed-figure-new} -% getting files for figures -\newcommand{\LSTFILE}[1]{ -\lstinputlisting[basicstyle=\small\ttfamily]{#1} -} -\newcommand{\LSTFILESLICE}[2]{ -\lstinputlisting[basicstyle=\small\ttfamily,linerange={#1}]{#2} -} -% -\newcommand{\LSTCFILE}[1]{ -\lstinputlisting[language=C,basicstyle=\small\ttfamily]{#1} -} -\newcommand{\LSTCFILESLICE}[2]{ -\lstinputlisting[language=C,basicstyle=\small\ttfamily,linerange={#1}]{#2} -} -\usepackage[bookmarks=false]{hyperref} -%\usepackage{varioref} % doesn't work with hyperref, it seems, sigh -%\renewcommand{\reftextfacebefore}{on the previous page} -%\renewcommand{\reftextfaceafter}{on the next page} -\newcommand{\tabref}[1]{Table~\ref{#1}} % vref from varioref -\newcommand{\tabnref}[1]{Table~\ref{#1}} % doesn't use varioref -\newcommand{\figref}[1]{Figure~\ref{#1}} % vref from varioref -\newcommand{\fignref}[1]{Figure~\ref{#1}} % doesn't use varioref -\newcommand{\secref}[1]{Section~\ref{#1}} % vref from varioref -\newcommand{\secnref}[1]{Section~\ref{#1}} % doesn't use varioref - -\input{obey} -\input{grammar} -\renewcommand{\nonterm}[1]{\mbox{$\langle$\textrm{#1}$\rangle$}} -\renewcommand{\arbno}[1]{\{#1\}} -\newcommand{\gramquote}[1]{\textrm{`}#1\textrm{'}} -\input{use-full-height} -\input{use-full-width} -\input{continuedenum} - -\setlength\RaggedRightParindent{\parindent} -\input{srm-isa.tex} -\newcommand{\IFO}[2]{\textrm{\textbf{if} \ensuremath{#1} \textbf{then} \ensuremath{#2} }} -\newcommand{\IF}[3]{\textrm{\textbf{if} #1 \textbf{then} #2 \textbf{else} #3}} -\newcommand{\EQUALS}{\ensuremath{=}} % or {\ensuremath{\:\texttt{==}\:}} -% -\bibliographystyle{plain} -% -\title{Simplified RISC Machine Manual \\ - (\lstinline!$Revision: 1.62 $!)} -\author{Gary T. Leavens \\ - Leavens@ucf.edu} -\begin{document} - -\maketitle -\begin{abstract} -This document defines the machine code of the Simplified RISC Machine VM for -use in the Systems Software class (COP 3402) at UCF. -\end{abstract} - -\section{Overview} - -The Simplified RISC Machine (SRM) processor's instruction set architecture -(ISA) is simplified from the MIPS processor's ISA \cite{Kane-Heinrich92}. -In particular, SRM is a little-endian machine with $\WS$-bit ($\WSinBytes$-byte) words. -All instructions are also $\WS$-bits wide and there is no floating-point support, kernel mode support, or other advanced features. - -\subsection{Inputs and Outputs} - -\subsubsection{Binary Object Files} - -The VM is passed a single file name on its command line as an -argument. -Optionally the VM be passed a single command line option, either -\texttt{-p} or \texttt{-t}. - -When given a \texttt{-p} argument followed by a binary object file -name, the VM loads the binary object file and prints the assembly -language form of the program, see \secref{sec:printing} details. - -When given a \texttt{-t} argument followed by a binary object file -name, the VM runs the binary object file with tracing output enabled. -By default, no tracing happens, but users can turn on tracing under -program control by executing the \texttt{STRA} system call. - -The remainder of this section is concerned -with what the VM does when it only is given a binary object file name -on its command line as an argument. - -The file name given to the VM must be the name of a (readable) -binary object file containing the program that the VM should execute. -For example, if the VM's executable is named \texttt{vm} and the program it -should run is contained in the file named \texttt{test.bof} -(and both these files are in the current directory), then the VM should -execute the program in the file \texttt{test.bof} by executing -the following command in the Unix shell. - -\begin{lstlisting} - ./vm test.bof -\end{lstlisting} - -The format of a binary object file (BOF) is given in the header file -\texttt{bof.h}, which is shown in part in \figref{fig:bofh}. -A BOF starts the header, then the instructions (also in -binary form) follow, followed by the initial values of data. -This layout of binary object files is shown in \figref{fig:boffilelayout}. - -The header of a binary object file starts with a 4-character field -that contains the characters ``\lstinline!BOF!'' -(and a null character); this kind of ``magic number'' is commonly used -to identify files in Unix. -The magic number is followed (in the BOF header) by the starting address of -the program's code and the length of the program's code (in bytes), which -constitutes the ``text'' section of the binary object file. -These are followed by the starting address of the data section and its -length (in bytes). -The data section contains the global/static variables that the program uses. -Finally, the header contains the initial value for the stack and frame -pointers, which is the address (in bytes) of the bottom of the runtime -stack. - -\begin{figure}[htbp] -\LSTCFILESLICE{1-24,75-76}{bof.h} -\caption{The \texttt{bof.h} header file that defines the format and - operations for binary object files.} -\label{fig:bofh} -\end{figure} - -\begin{figure}[htbp] -\includegraphics*{BOF_layout.png} -\caption{The layout of a binary object file.} -\label{fig:boffilelayout} -\end{figure} - -\subsubsection{Initial/Default Values} -\label{sec:initial} - -The memory of the machine starts at all zero ($0$) values. -Then the instructions specified by the given binary object file -(as named on the command line) are loaded into memory, -starting at address $0$, making the contents of the first $N$ bytes -(where $N$ is divisible by $\WSinBytes$) -of memory be the same as the $N$ bytes following the header itself in -the binary object file; here $N$ is the same as the header's value of -the \lstinline!text_length! field. -Following those $N$ bytes are the bytes of the data section. -These are loaded into the memory starting at the data start address -given in the header; thus any initial values are copied from the -data section of the binary object file into VM's memory. - -When the program starts executing: -\begin{itemize} -\item -the register {\GP} is set to the start address of the data section -given in the header, -which must be divisible by $\WSinBytes$, - -\item -the registers {\FP} and {\SP} are both is set to the stack bottom -address given in the header, which must be divisible by $\WSinBytes$ -and strictly greater than the start address of the data section, - -\item -to simulate a call of the program (by the OS) the {\AZERO} register is -set to the same value as {\FP}, and - -\item -the program counter {\PC} is set to the text section's start address, -which must be divisible by $\WSinBytes$ and strictly less than the -data section's start address. -\end{itemize} - -% \clearpage - -\subsection{The Running Program's Input and Output} - -When the program executes instructions to read or write characters, -these are read from standard input (\texttt{stdin}) and written to -standard output (\texttt{stdout}). - -However, note that if you want the program to read a character, typing a single -character (say \texttt{x}) into the terminal (i.e., to the shell) -while the program is running will not send that character immediately -to the program, as standard input is buffered by default. To send -characters to the program it is best to use a pipe or file redirection -in the Unix shell; for example, to send the two characters \texttt{x} -and \texttt{y} (followed by a newline character) -to the VM running the program \texttt{progfile.bof} one -could use the following command at the Unix shell: - -\begin{lstlisting} - echo xy | ./vm progfile.bof -\end{lstlisting} - -Another command that would accomplish the same thing is to put the -characters to be input into a file (using a text editor), say -\texttt{xy-input.txt} and then to use the following Unix command. - -\begin{lstlisting} - ./vm progfile.bof < xy-input.txt -\end{lstlisting} - -\subsection{Tracing Output} - -When used with the \texttt{-t} option or after the \texttt{STRA} -system call is executed, -the VM produces output that traces the its execution on \texttt{stdout}. -(This tracing output can be turned off under program control -by executing a \texttt{NOTR} system call instruction.) -(See \secref{sec:syscall} for more information about the \texttt{STRA} -and \texttt{NOTR} system call instructions.) - -The tracing output shows the initial state of the VM, then for each -instruction executed, it shows the address (in bytes) of that -instruction and then the assembly language form of that instruction. - -The state of the machine shown in tracing output shows: -the values in the PC, the values of the HI and LO registers (if those -are not zero) and the values in all the general purpose registers, -then the memory starting at the address in $\GPR{\GP}$ -with locations containing zeros only indicated with ``\texttt{...}''. -and then the data between the addresses between $\GPR{\SP}$ and -the stack bottom address specified in the binary object file. -The idea is that those addresses should include the runtime stack. -When showing the memory, locations containing zeros are only -indicated with ``\texttt{...}''. -For example, when the binary object file that is assembled from the -assembly code shown in \figref{fig:test0asm} is executed, -which is found in the file \texttt{vm\_test0.bof}, -it produces the output shown in \figref{fig:test0output}. - -\begin{figure} -\LSTFILE{vm_test0.asm} -\caption{The SRM assembly language file \texttt{vm\_test0.asm}.} -\label{fig:test0asm} -\end{figure} - -\begin{figure} -\lstinputlisting[basicstyle=\ttfamily\scriptsize]{vm_test0.out} -\caption{The tracing output of running the VM (with the \texttt{-t} option) - on the file \texttt{vm\_test0.bof} - (which is the result of using the assembler on \texttt{vm\_test0.asm}), - with the command \texttt{./vm vm\_test0.bof}, - as would be printed on standard output.} -\label{fig:test0output} -\end{figure} - -\subsection{Printing the Program} -\label{sec:printing} - -When the VM is given the argument \texttt{-p} option followed by a -binary object file name, it first loads the instructions and data from the -given binary object file, then it prints what was loaded in assembly -language format, and then the VM exits (without running the program). This -can be helpful for understanding what a program is doing. This output -is shown in \figref{fig:test0listing}. - -\begin{figure} -\LSTFILE{vm_test0.lst} -\caption{The output of running \texttt{./vm -p vm\_test0.bof}. - (where the file \texttt{vm\_test0.bof} is the result of assembling the file - \texttt{vm\_test0.asm} that is shown in \figref{fig:test0asm}).} -\label{fig:test0listing} -\end{figure} - -\subsection{Error Outputs} - -All error messages (e.g., for division by zero) are sent to -standard error output (\texttt{stderr}). - -\subsection{Exit Code} - -When the machine halts normally, it exits with a zero error code -(which indicates success on Unix). However, when the machine -encounters an error it halts and exits with a non-zero exit code -(which indicates failure on Unix). - -\section{Architecture} - -In SRM, words are $\WS$ bits ($\WSinBytes$ bytes). -These bits can be interpreted as an integer or as an address. -The machine is byte addressed but instructions must always be at an -address that is on a word boundary (i.e., whose address is evenly -divisible by $\WSinBytes$). - -\subsection{Registers} - -\subsubsection{General Purpose Registers and Their Names} - -The SRM is a register machine with 32 -general purpose registers\footnote{What we call -``registers'' in this document are simply important concepts that -simulate what would be registers in a hardware implementation of the -virtual machine. For the VM program, these registers would be implemented -as variables.}, -numbered 0 to 31 (inclusive). -These are all $\WS$-bit registers. -Since there are 32 registers, -instructions use $\LOGofRegs$ bits to specify them. - -Register 0 cannot be written to, and when read its value is always 0. - -Conventions (from the MIPS architecture \cite{Kane-Heinrich92}) are -followed for these registers and their names, -as shown in \tabref{tab:registers}. -The names shown in \tabnref{tab:registers} are conventional ones. - -\begin{table}[htb] - \caption{SRM Register Numbers, Use, and Names} - \label{tab:registers} -\begin{center} -\begin{tabular}{| l | l | l |} - \hline - Number & Use & Name\\ - \hline - $0$ & always 0 (can't write to this register!) & \\ - $1$ & assembler temporary & \NAMEDREG{at} \\ - $2-3$ & function results & \NAMEDREG{v0}, \NAMEDREG{v1} \\ - $4-7$ & function arguments & \NAMEDREG{a0}$-$\NAMEDREG{a3} \\ - $8-15$ & temporaries & \NAMEDREG{t0}$-$\NAMEDREG{t7} \\ - $16-23$ & temporaries & \NAMEDREG{s0}$-$\NAMEDREG{s7} \\ - $24-25$ & temporaries & \NAMEDREG{t8}, \NAMEDREG{t9} \\ - $26-27$ & reserved for use by OS (don't use!) & \\ - $28$ & globals pointer & $\GP$ \\ - $29$ & stack pointer & $\SP$ \\ - $30$ & frame pointer & $\FP$ \\ - $31$ & return address & $\RA$ \\ - \hline -\end{tabular} -\end{center} -\end{table} - -\subsubsection{Special Purpose Registers} - -SRM also has a few special registers. The registers are named: - -\begin{itemize} -\item - {\PC}, the program counter which holds the address of the next - instruction to execute, - -\item - {\HI}, the high part (i.e., most significant bits) of the result of a multiplication or the - remainder in a division, - -\item - {\LO}, the low part (i.e., least significant bits) of the result of - a multiplication or the quotient in a division. -\end{itemize} - -The $\PC$ register is manipulated by jump instructions. -The $\HI$ and $\LO$ registers are read by instructions that move their contents into another register. - -\subsubsection{Calling Convention} - -The calling convention on the SRM follows the calling convention on -the MIPS processor. - -That is, the caller must save registers $1-15$, and $24-25$ -if they will be needed after a call (and then restores them when -needed). - -The callee saves (and restores before it returns) registers $16-23$ -and $29-31$, if it uses (writes) them. - -(Furthermore, register $0$ cannot be changed and registers $1$ and -$28$ should not be changed by a hand-written routine. -Registers $26-27$ should not be changed by user code.) - -Note that the jump-and-link (\texttt{JAL}) instruction -does not save any registers except the $\PC$, -and it will save that in register $31$. - -\subsection{Binary Instruction Format} - -In object code, -all instructions are one word long and start with a 6-bit opcode. -However, instructions may have one of several formats, with the format -depending on the opcode (called ``op'' below). -The fields of each instruction format shown in \tabref{tab:instrfmts} -are followed by their width in bits; -for example the op field is 6 bits wide. - -\begin{table}[htb] - \caption{SRM Instruction Formats} - \label{tab:instrfmts} -\begin{itemize} -\item Register/computational type instruction format: \\ -\begin{tabular}{|c|p{6ex}{c}|p{6ex}{c}|p{6ex}{c}|p{10ex}|p{9ex}|} - \hline - op:6 & \multicolumn{1}{|c|}{rs:5} & \multicolumn{1}{|c|}{rt:5} & \multicolumn{1}{|c|}{rd:5} & \multicolumn{1}{|c|}{shift:5} & \multicolumn{1}{|c|}{func:6} \\ - \hline -\end{tabular} - -\item System call instructions, whose format is a variant of the register type -instruction format, but with a func field value of 12: \\ -\begin{tabular}{|c|p{6ex}{c}|p{6ex}{c}|p{6ex}{c}|p{10ex}|p{9ex}|} - \hline - op:6 & \multicolumn{4}{|c|}{~~~~~~~~~~~~~code:20~~~~~~~~~~~~~~~~} & \multicolumn{1}{|c|}{func:6} \\ - \hline -\end{tabular} - -\item -Immediate operand type instruction format: \\ -\begin{tabular}{| c | p{6ex}{c} | p{6ex}{c} | p{16ex} |} - \hline - op:6 & \multicolumn{1}{|c|}{rs:5} & \multicolumn{1}{|c|}{rt:5} & \multicolumn{1}{c|}{~~~~~~~~~immed:16~~~~~~~~~~~} \\ - \hline -\end{tabular} - -\item -Jump type instruction format: \\ -\begin{tabular}{| c | p{26ex}|} - \hline - op:6 & \multicolumn{1}{c|}{~~~~~~~~~~~~~~~~~~~~~addr:26~~~~~~~~~~~~~~~~~~~~~~~} \\ - \hline -\end{tabular} -\end{itemize} -\end{table} - -The list of instructions and details on their execution appears in -Appendix \ref{appsec:A}. - -\subsection{Machine Cycles} - -The SRM instruction cycle conceptually does the following for each -instruction: - -\begin{enumerate} -\item - Let $\IR$ be the instruction at the location that {\PC} indicates. - (Note that $\IR$ could be considered to be the contents of a register.) - -\item - The {\PC} is made to point to the next instruction - (i.e., it is set to the address $\PC + \WSinBytes$). - -\item - Then the instruction in $\IR$ is executed. - The op component of this instruction ($\IR$.op) indicates the operation - to be executed. - For example, if $\IR$.op encodes the instruction JR, - then the machine jumps to the specified address by - setting the $\PC$ register (to the contents of the given register). -\end{enumerate} - -\subsection{Size Limits} - -The following constant defines the size of the memory for the VM. - -\LSTCFILESLICE{10-10}{machine.h} - -You might need to copy this definition into your program. - -Note that \lstinline!BYTES_PER_WORD! is defined to be 4 in -\lstinline!machine_types.h!, see \figref{fig:machinetypes}. - -\subsection{Invariants} - -The VM enforces the following invariants and will halt with an error -message (written to stderr) if one of them is violated: - -\newcommand{\BPW}{\mbox{\texttt{BYTES\_PER\_WORD}}} -\begin{itemize} -\item - $\PC \MOD \BPW = 0$, - -\item - $\GPR{\GP} \MOD \BPW = 0$, - -\item - $\GPR{\SP} \MOD \BPW = 0$, - -\item - $\GPR{\FP} \MOD \BPW = 0$, - -\item - $0 \leq \GPR{\GP}$, - -\item - $\GPR{\GP} < \GPR{\SP}$, - -\item - $\GPR{\SP} \leq \GPR{\FP}$, - -\item - $\GPR{\FP} < \mbox{\texttt{MEMORY\_SIZE\_IN\_BYTES}}$, - -\item - $0 \leq \PC$, - -\item - $\PC < \mbox{\texttt{MEMORY\_SIZE\_IN\_BYTES}}$, and - -\item - $\GPR{0} = 0$. -\end{itemize} - -\appendix -\section{Appendix A} -\label{appsec:A} - -In the following tables, italicized names (such as $s$) are -meta-variables that refer to integers. -If an instruction's field is -notated as $-$, then its value does not matter (we use $0$ as a -placeholder for such values in examples). - -All numbers appearing in the following table are in decimal (base 10) notation. - -\subsection{Register/Computational Instructions} - -Note that all of the instructions in table \tabref{tab:rformatinstrs} -have an opcode of $0$, -and a function specified by the func field. They each also have 3 register -arguments: rs, rt, and rd. -The contents of the general purpose register $r$ is -notated as $\GPR{r}$ in the table. -All numbers in the table are in decimal notation. - -All arithmetic and logical operations are performed as for C -\textbf{int} values. -However, the right shift works on the contents of the register -$\GPR{t}$ in a logical manner, as if it were an \textbf{unsigned int}, -so it should shift in zeros from the left. - - -\begin{table}[htbp] -\caption{Register Format Instructions} -\label{tab:rformatinstrs} -\begin{tabular}{|l|l|c|c|c|c|l|p{9cm}|} -\hline -~ & ~ & ~ & ~ & ~ & ~ & & Comment \\ -Name & op & rs & rt & rd & shift & func & (Explanation) \\ -\hline -ADD & 0 &$s$ &$t$ &$d$ & - & 33 & Add: $\GPR{d} \GETS \GPR{s} + \GPR{t}$ \\ -\hline -SUB & 0 &$s$ &$t$ &$d$ & - & 35 & Subtract: $\GPR{d} \GETS \GPR{s} - \GPR{t}$ \\ -\hline -MUL & 0 &$s$ &$t$ & - & - & 25 & Multiply: Multiply -$\GPR{s}$ and $\GPR{t}$, \\ -& & & & & & & putting the least significant bits in $\LO$ \\ -& & & & & & & and the most significant bits in $\HI$. \\ -& & & & & & & $(\HI,\LO) \GETS \GPR{s} \times \GPR{t}$ \\ -\hline -DIV & 0 &$s$ &$t$ & - & - & 27 & Divide (remainder in $\HI$, quotient in $\LO$): \\ - & & & & & & & $\HI \GETS \GPR{s} \MOD \GPR{t}$ \\ - & & & & & & & $\LO \GETS \GPR{s} / \GPR{t})$ \\ -\hline -MFHI & 0 & - & - & $d$ & - & 16 & Move from HI: $\GPR{d} \GETS \HI$ \\ -\hline -MFLO & 0 & - & - & $d$ & - & 18 & Move from LO: $\GPR{d} \GETS \LO$ \\ -\hline -AND & 0 &$s$ &$t$ & $d$ & - & 36 & Bitwise And: $\GPR{d} \GETS \GPR{s} \AND \GPR{t}$ \\ -\hline -BOR & 0 &$s$ &$t$ & $d$ & - & 37 & Bitwise Or: $\GPR{d} \GETS \GPR{s} \OR \GPR{t}$ \\ -\hline -NOR & 0 &$s$ &$t$ & $d$ & - & 39 & Bitwise Not-Or: $\GPR{d} \GETS \neg(\GPR{s} \OR \GPR{t})$ \\ -\hline -XOR & 0 &$s$ &$t$ & $d$ & - & 38 & Bitwise Exclusive-Or: $\GPR{d} \GETS \GPR{s} \XOR \GPR{t}$ \\ -\hline -SLL & 0 & - &$t$ & $d$ & $h$ & 0 & Shift Left Logical: $\GPR{d} \GETS \GPR{t} \LSHIFT h$ \\ -\hline -SRL & 0 & - &$t$ & $d$ & $h$ & 3 & Shift Right Logical: $\GPR{d} \GETS \GPR{t} \RSHIFT h$ \\ -\hline -JR & 0 &$s$ & 0 & 0 & 0 & 8 & Jump Register: $\PC \GETS \GPR{s}$ \\ -\hline -SYSCALL & 0 & - & - & - & - & 12 & System Call: (see \tabref{tab:syscalls}) \\ -\hline -\end{tabular} -\end{table} - -\newpage - -\subsection{Immediate Type Instructions} - -The instructions in \tabref{tab:immedinstrs} may have up to 2 register -arguments, and all have an immediate operand, which is a 16 bit value. - -For arithmetic operations, the immediate value is sign-extended (to an -\textbf{int} value), -which is written in the explanations using the function ``{\SIGNEXTENDNAME}.'' -For example, suppose $i$ is $-1$, which is FFFF in hexadecimal -notation; -then $\SIGNEXTEND{i}$ is FFFFFFFF in hexadecimal, which still -represents $-1$. - -However, for logical operations, the immediate value is zero-extended, -which is written in the explanations using the function ``{\ZEROEXTENDNAME}.'' -For example, suppose $i$ is $-1$, which is FFFF in hexadecimal -notation; -then $\ZEROEXTEND{i}$ is 0000FFFF in hexadecimal notation. - -For the branches, the immediate value, $o$ is first shifted left 2 -bits (multiplied by 4) and then sign-extended, which is written as -``{\FORMOFFSETNAME}'' in the table. -(Thus $\FORMOFFSET{o} = \SIGNEXTEND{4 \times o}$.) -Note that the resulting address is added to the address of the -instruction following the currently executing instruction, not the -address of the instruction itself, since the $\PC$ has already been advanced. -(As a simplification, the opcode for the BLTZ instruction is different -from that found in the MIPS architecture \cite{Kane-Heinrich92}.) - -For loads and stores, $\MEMORY{a}$ denotes the contents of the -machine's memory at the byte address $a$. - -\begin{table}[htbp] -\caption{Immediate format instructions:} -\label{tab:immedinstrs} -\begin{tabular}{|l|r|c|c|c|p{11cm}|} -\hline -~ & & ~ & ~ & ~ & Comment \\ -Name & op & rs & rt & immed & (Explanation) \\ -\hline -ADDI & 9 &$s$ &$t$ & $i$ & Add immediate: $\GPR{t} \GETS \GPR{s} + \SIGNEXTEND{i}$ \\ -\hline -ANDI & 12 &$s$ &$t$ & $i$ & Bitwise And immediate: $\GPR{t} \GETS \GPR{s} \AND \ZEROEXTEND{i}$ \\ -\hline -BORI & 13 &$s$ &$t$ & $i$ & Bitwise Or immediate: $\GPR{t} \GETS \GPR{s} \OR \ZEROEXTEND{i}$ \\ -\hline -XORI & 14 &$s$ &$t$ & $i$ & Bitwise Xor immediate: $\GPR{t} \GETS \GPR{s} \XOR \ZEROEXTEND{i}$ \\ -\hline -BEQ & 4 &$s$ &$t$ & $o$ & Branch on Equal: $\IFO{\GPR{s} = \GPR{t}}{\PC \GETS \PC + \FORMOFFSET{o}}$ \\ -\hline -BGEZ & 1 &$s$ & 1 & $o$ & Branch $\geq$ 0: $\IFO{\GPR{s} \geq 0}{\PC \GETS \PC + \FORMOFFSET{o}}$ \\ -\hline -BGTZ & 7 &$s$ & 0 & $o$ & Branch $>$ 0: $\IFO{\GPR{s} > 0}{\PC \GETS \PC + \FORMOFFSET{o}}$ \\ -\hline -BLEZ & 6 &$s$ & 0 & $o$ & Branch $\leq$ 0: $\IFO{\GPR{s} \leq 0}{\PC \GETS \PC + \FORMOFFSET{o}}$ \\ -\hline -BLTZ & 8 &$s$ & 0 & $o$ & Branch $<$ 0: $\IFO{\GPR{s} < 0}{\PC \GETS \PC + \FORMOFFSET{o}}$ \\ -\hline -BNE & 5 &$s$ &$t$ & $o$ & Branch Not Equal: $\IFO{\GPR{s} \neq \GPR{t}}{\PC \GETS \PC + \FORMOFFSET{o}}$ \\ -\hline -LBU & 36 &$b$ &$t$ & $o$ & Load Byte Unsigned: \\ - & & & & & $\GPR{t} \GETS \ZEROEXTEND{\MEMORY{\GPR{b} + \FORMOFFSET{o}}}$ \\ -\hline -LW & 35 &$b$ &$t$ & $o$ & Load Word ($\WSinBytes$ bytes): \\ - & & & & & $\GPR{t} \GETS \MEMORY{\GPR{b} + \FORMOFFSET{o}}$ \\ -\hline -SB & 40 &$b$ &$t$ & $o$ & Store Byte (least significant byte of $\GPR{t}$): \\ - & & & & & $\MEMORY{\GPR{b} + \FORMOFFSET{o}} \GETS \GPR{t}$ \\ -\hline -SW & 43 &$b$ &$t$ & $o$ & Store Word ($\WSinBytes$ bytes): \\ - & & & & & $\MEMORY{\GPR{b} + \FORMOFFSET{o}} \GETS \GPR{t}$ \\ -\hline -\end{tabular} -\end{table} - -\subsection{Jump Type Instructions} - -The instructions in \tabref{tab:jumpinstrs} have a $\WSminusOP$-bit field ``addr'' -which is used to form the address to jump to. -Forming this address is done by left-shifting the given ``addr'' -field, $a$, by 2 bits, -and then concatenating the (4) high bits of the $\PC$ with those -$\WSminusOP+2$ bits to form a $\WS$-bit address. -This is written ``$\FORMADDRESS{\PC,a}$'' in the table. -For example if $a$ is DECADE in hexadecimal notation, and $\PC$ is -FFFACADE in hexadecimal notation, then $\FORMADDRESS{\PC}{a}$ is F37B2B78 -in hexadecimal notation. (Note: if the high-order 4 bits of $\PC$ -are 0, then $\FORMADDRESS{PC}{a}$ is equivalent to left-shifting $a$ -by 2 bits.) - -\begin{table}[htbp] -\caption{Jump Type Instructions} -\label{tab:jumpinstrs} -\begin{tabular}{|r|l|l|p{11cm}|} -\hline -~ & ~ & ~ & Comment \\ -Name & op & addr & (Explanation) \\ -\hline -JMP & 2 & a & Jump: $\PC \GETS \FORMADDRESS{PC}{a}$ \\ -\hline -JAL & 3 & a & Jump and Link: $\GPR{\RA} \GETS \PC; \PC \GETS \FORMADDRESS{\PC}{a}$ \\ -\hline -\end{tabular} -\end{table} - -The Jump and Link (JAL) instruction does a subroutine call. It does -not explicitly manipulate the runtime stack. -% [[[Put more in about calling conventions here.]]] - -\subsection{System Calls} -\label{sec:syscall} - -System calls are used to provide operating system services. -System calls are made by instructions with op 0 and func 12 having the -following format (with code field made of the 20 bits of what would -be the rs, rt, rd, and shift fields of a register type instruction, -all combined). -The code field is used to specify the service requested. - -System calls include exiting a program and various kinds of printing -and reading of character data (bytes). -These are described in \tabref{tab:syscalls}, -using C library equivalents. -In the table, an entry of $-$ means that the contents of argument registers -is not specified. -Otherwise, the contents of particular argument registers are used to -pass actual arguments to the system calls (the program must load the -actual argument values into those registers before making the call). -(Recall that the correspondence between named registers and register -numbers is given in \tabref{tab:registers}.) -All printing done by these instructions -is to the VM's standard output (stdout) and -reading is from the VM's standard input (stdin). - -\begin{table}[htbp] -\caption{System Calls} -\label{tab:syscalls} -\begin{tabular}{|l|l|l|l|} -\hline -code & name & arg. reg. & Effect (in terms of C std. library) \\ -\hline -10 & EXIT & - & \texttt{exit(0) // halt} \\ -\hline - 4 & PSTR & \AZERO & $\GPR{\VZERO} \GETS $ \texttt{printf("\%s",\&$\MEMORY{\GPR{\AZERO}}$)} \\ -\hline - 5 & PINT & \AZERO & $\GPR{\VZERO} \GETS $ \texttt{printf("\%d",\GPR{\AZERO})} \\ -\hline -11 & PCH & \AZERO & $\GPR{\VZERO} \GETS $\texttt{fputc($\GPR{\AZERO}$,stdout)} \\ -\hline -12 & RCH & - & $\GPR{\VZERO} \GETS $ \texttt{getc(stdin)} \\ -\hline -256 & STRA & - & \textrm{start VM tracing; start tracing output} \\ -\hline -257 & NOTR & - & \textrm{no VM tracing; stop the tracing output} \\ -\hline -\end{tabular} -\end{table} - -In the PSTR instruction, the C standard library function -\texttt{printf} will expect a C pointer to characters as its -argument; this should be the address of those character's -representations in the memory starting at the VM address given by the -contents of $\GPR{\AZERO}$. - -\section{Appendix B: Hints} - -\subsection{Overall Structure of the Code} - -To implement the SRM VM, the first thing to do is to decide on some -data structures to represent the VM's state: especially the memory and -registers. You may want to represent the VM's memory using a -definition like that in \figref{fig:memoryrep}. -\begin{figure}[hbtp] -\begin{lstlisting} -#include "machine_types.h" -#include "instruction.h" -// a size for the memory (2^16 bytes = 64K) -#define MEMORY_SIZE_IN_BYTES (65536 - BYTES_PER_WORD) -#define MEMORY_SIZE_IN_WORDS (MEMORY_SIZE_IN_BYTES / BYTES_PER_WORD) - -static union mem_u { - byte_type bytes[MEMORY_SIZE_IN_BYTES]; - word_type words[MEMORY_SIZE_IN_WORDS]; - bin_instr_t instrs[MEMORY_SIZE_IN_WORDS]; -} memory; -\end{lstlisting} -\caption{A possible way to represent the memory of the VM, which - allows access to the same storage as bytes, words, or binary instructions.} -\label{fig:memoryrep} -\end{figure} -With this definition, -the VM's memory is represented as 3 arrays that share the same -storage: \lstinline!memory.bytes!, \lstinline!memory.words!, and -\lstinline!memory.instrs!. For example, -the 4 bytes at byte address 36 can be accessed as -\lstinline!memory.bytes[36]! -or as \lstinline!memory.words[9]! or as \lstinline!memory.instrs[9]!. -This union definition allows VM's code to decide what view it wants -of the storage at each point in the implementation, -and whatever is changed in that view is -seen by all the other views. -Using a union in this way avoids lots of casting and bit manipulation. -Note that the C compiler considers \lstinline!memory.bytes! to have -the type \lstinline!byte_type[]!, -and \lstinline!memory.words! to have the type \lstinline!word_type[]!, -and \lstinline!memory.instrs! to have the type \lstinline!bin_instr_t[]!. - -The registers can be \lstinline!word_type! variables -(where \lstinline!word_type! is defined in -\lstinline!machine_types.h!), -or an array of them. - -Once the representation for memory and the registers is settled, -implement the loading process and get the \texttt{-p} option to work. -There is code in the disassembler that can be used as a model of what -to do. - -To read from the binary object files (BOFs) you should use the -functions in the bof module. -In particular, use \lstinline!bof_read_open! to open such a file, -use \lstinline!bof_read_header! to read and return the header from a -BOF, then read each of the instructions using -\lstinline!instruction_read! (from the instruction module), -and \lstinline!bof_read_word! to read words in the data section of -the BOF. - -You will find the function \lstinline!instruction_assembly_form! -from the instruction module -helpful in doing the printing of instructions. See the code in the -disassembler (\texttt{disasm.c} in particular) for a model of how to -use it. - -After getting the \texttt{-p} option to work, -you need to implement the basic fetch-execute cycle for the VM -(without the \texttt{-p} option): -make a function that executes a single instruction and handles the tracing -and call the function to execute each instruction in a loop. - -To implement the function that executes a single instruction, -have that function decide between the possible instructions -(using the functions from the instruction module) and -in each case carry out the effect of the instruction as described in -the ``Simplified RISC Machine Manual'', which is available on -Webcourses. -You can see the provided code in the -\lstinline!instruction_assembly_form! -function in the instruction module as an example of how to -decide what an instruction is. - -\subsection{Writing Your Own Tests} - -It is often helpful to write your own tests to execute just one or two -instructions during testing of the VM. -However, be sure to include an \texttt{EXIT} instruction in your test to -stop your program's execution! - -To write your own tests you can use the provided assembler, -since the VM only takes binary object files as inputs. - -The SRM assembler can be compiled using the provided Makefile and the -following command. -\begin{lstlisting} -make asm -\end{lstlisting} - -We also provide documentation for the -assembly language in the course files on webcourses; see the file -named ``\texttt{srm-asm.pdf}''. - -\subsection{Disassembler} - -We also provide a disassembler, that does something similar to running the -virtual machine with the \texttt{-p} option; this program can be built -using the Makefile by issuing the command \texttt{make disasm}. -The way that the disassembler does its output, using the -\texttt{instruction} module, can be helpful in writing the code for -the \texttt{-p} option of the VM. - -\subsection{Provided Files} - -We provide all the source files used to build the assembler and the -disassembler. Many of these can be helpful in writing your VM -implementation. The following describes some of these. - -\subsubsection{Makefile} - -The provided \texttt{Makefile} describes how to compile and link programs -and run tests. This \texttt{Makefile} tells the GNU program -\texttt{make} \cite{GNUMake} -about dependencies between files that \texttt{make} uses -to decide when targets need to be built. - -You should edit the Makefile's definition of \texttt{VM\_OBJECTS}; -change that to be a complete list of the \texttt{.o} files -that are needed to build your virtual machine. -The list present in the Makefile for \texttt{VM\_OBJECTS} -is what the course staff used, -but you might, for example, combine the main function, -which was in our files \texttt{machine\_main.c} and -\texttt{machine.c} (none of these are provided to you) -into a single file named \texttt{vm.c}, in which case would replace -our \texttt{machine\_main.o} and \texttt{machine.o} with your \texttt{vm.o} -On the other hand, you will need to leave the object file names in the -list that your code uses, such as \texttt{bof.o} and \texttt{utilities.o}. -If you receive an error message from the Unix linker/loader -(\texttt{ld}) about an ``undefined reference'' to a function or a -piece of data, then the solution is likely to include the relevant -object file in the list of \texttt{VM\_OBJECTS}. - -You should not need to edit anything in the bottom half of the -Makefile, which is the ``developer's section'' used by the course staff. - -There are several useful targets in the Makefile that can be used with -the \texttt{make} command. A \emph{target} is a name given on the -command line to \texttt{make}; for example \texttt{vm} is a target, -and running the command \texttt{make vm} should compile and link the -code needed to build your VM and create an executable program in the -file \texttt{vm} (or \texttt{vm.exe} on Windows). The following is a -list of the targets in the Makefile that may be useful. - -\newcommand{\bft}[1]{\textbf{\texttt{#1}}} -\begin{description} -\item{\bft{file.o}} compiles \texttt{file.c} if it (or \texttt{file.h}) is - newer than \texttt{file.o}, producing a new copy of \texttt{file.o}. - This works for any file name not just ``\texttt{file}'', as the - Makefile has a general rule to compile \texttt{.c} files into - \texttt{.o} files. - -\item{\bft{vm}} compiles (if necessary) all the .o files named in the macro - \texttt{VM\_OBJECTS} and links them together into an executable - named \texttt{vm} (or \texttt{vm.exe} on Windows). - -\item{\bft{vm\_test1.myo}} runs your virtual machine program (\texttt{./vm}) - on the input \texttt{vm\_test1.bof} and sends the (standard) output - (and standard error output) to \texttt{vm\_test1.myo}. - This works for any test file, not just ``\texttt{vm\_test1.bof}'' as - the Makefile has a general rule for this. - -\item{\bft{vm\_test1.myp}} runs your virtual machine program (\texttt{./vm}) - with the \texttt{-p} option on the input \texttt{vm\_test1.bof} - and sends the (standard) output - (and standard error output) to \texttt{vm\_test1.myp}. - This works for any test file, not just ``\texttt{vm\_test1.bof}'' as - the Makefile has a general rule for this. - -\item{\bft{check-vm-outputs}} runs all of the provided tests in the - \texttt{.bof} files and produces the corresponding \texttt{.myo} - files using your VM (in \texttt{./vm}), and compares each one to the - expected output in the corresponding \texttt{.out} file using the - \texttt{diff} command. Each such test passes if no differences are detected. - -\item{\bft{check-lst-outputs}} runs all of the provided tests in the - \texttt{.bof} files and produces the corresponding \texttt{.myp} - files using your VM (as \texttt{./vm -p}), and compares each one to the - expected output in the corresponding \texttt{.lst} file using the - \texttt{diff} command. Each such test passes if no differences are detected. - -\item{\bft{check-outputs}} runs all of the provided tracing and listing - tests (using the targets - \texttt{check-lst-outputs} and \texttt{check-vm-outputs}). - -\item{\bft{submission.zip}} runs all of the provided tests (using the - \texttt{check-outputs} target) and creates a zip file that can be - submitted for the assignment including your code and outputs from - the tests. - -\item{\bft{clean}} removes all the compiled object files (\texttt{*.o}) and testing - output files (\texttt{*.myo} and \texttt{*.myp}) as well as the - executable VM (files named \texttt{vm} and \texttt{vm.exe}) and the - submission zip file (\texttt{submission.zip}). This allows you to - start over from scratch, forcing \texttt{make} to build the do the - work specified for the targets given, instead of thinking that they - are up to date. (This is especially useful if some dependencies are - not captured in the Makefile.) -\end{description} - -\subsubsection{C Typedefs for SRM Machine Types} - -We provide a module, \lstinline!machine_types! (the header -\lstinline!machine_types.h! is shown in \figref{fig:machinetypes}), -which defines some C equivalents for important types of data in the SRM. - -\begin{figure} -\LSTCFILE{machine_types.h} -\caption{The header file of the \texttt{machine\_types} module, which - provides some basic definitions for the VM.} -\label{fig:machinetypes} -\end{figure} - -\subsubsection{Other modules provided} - -The following gives a brief summary of the other provided code -modules, each of which consists of a \texttt{.c} file and a -\texttt{.h} file. - -\begin{itemize} -\item - \lstinline!bof!, which describes binary object files, - -\item - \lstinline!file_location!, which groups file names and line numbers, - -\item - \lstinline!instruction!, which describes machine instructions and - provides several useful utilities for creating and printing - instructions, - -\item - \lstinline!regname!, which provides access to the symbolic names of - the SRM's general purpose registers, - -\item - \lstinline!utilities!, which describes several functions for error - output, including \lstinline!bail_with_error!. -\end{itemize} - -In addition, we provide code to build the assembler (including many of -the above and also the files -\lstinline!asm_main.c!, \lstinline!asm.y!, \lstinline!asm_lexer.l!, -\lstinline!asm_unparser.[ch]!, \lstinline!ast.[ch]!, -\lstinline!lexer.[ch]!, \lstinline!pass1.[ch]!, -\lstinline!assemble.[ch]!, and \lstinline!id_attrs!) -and the disassembler (including many mentioned above and also -\lstinline!disasm_main.c!, \lstinline!disasm.[ch]!). - -You can use any of these provided files in your solution. - -\bibliography{srm-vm.bib} - -\end{document} diff --git a/vm/ssm-asm.pdf b/vm/ssm-asm.pdf deleted file mode 100755 index 7701239124186319dcb2d9b338fd78f870a85de5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 116407 zcmeGEWmsKFvj7UCfdIiFKpnG|{PP>YME=Te<|b3|b2LW_`d=jQMl(*0()kL1-_B;WTLcnz!Gs}YUA zeZCmPAgK0CDy+ssS0}=8`l89CfBU-B`Sz6{Q<7A1pnOnUTv``rgv%y(9%mCLIr!IdT@k69>!S(^*472X%o) z>xzpX!d;oe8J)tgG^yA@4X?)ih|AGKIZ2s~*$)akTg{~Bi3h1*2?OAgn9==sEcSYK z)6Sn;Ig5MX83Zq3!rP*=zWA}x@c>qCgH8~~nR$Au!`xKcxb?xko75mFzrtx!k(l9J z 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�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 OM1rJ}(uU1?lK%&yhV$|O diff --git a/vm/ssm-vm.pdf b/vm/ssm-vm.pdf deleted file mode 100755 index a991ab3b9a94f5f37dfa2fe29d963eb184e34cc5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 267779 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
    $C^j$_@yJm3P0>^G=Y&;SgnL@;*e${t~hd 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 diff --git a/vm/symtab.c b/vm/symtab.c deleted file mode 100755 index 1868a3c..0000000 --- a/vm/symtab.c +++ /dev/null @@ -1,131 +0,0 @@ -/* $Id: symtab.c,v 1.4 2024/07/26 12:44:46 leavens Exp $ */ -#include -#include -#include -#include "symtab.h" -#include "utilities.h" - -// For a data structure, we use an array (for now), -// although a hash table might be better... - -// size is also the index of the next element to allocate -static int size; -// The data structure is such that the first size entries contain actual data -static id_attrs_assoc entries[MAX_SYMTAB_SIZE]; - -// The symbol table's invariant -void symtab_okay() -{ - assert(0 <= size); - assert(size < MAX_SYMTAB_SIZE); - for (int i = size; i < MAX_SYMTAB_SIZE; i++) { - assert(entries[i].name == NULL); - } -} - -// initialize the symbol table -void symtab_initialize() -{ - size = 0; // no data yet - id_attrs_assoc none; - none.name = NULL; - none.file_loc = NULL; - none.addr = 0; - for (int i = 0; i < MAX_SYMTAB_SIZE; i++) { - entries[i] = none; - } - symtab_okay(); -} - -// Return the number of mappings in this symbol table -unsigned int symtab_size() { return size; } - -// Is this symbol table empty? (I.e., does it have not mappings?) -bool symtab_empty() { return size == 0; } - -// Is this symbol table full? (I.e., can it not hold more mappings?) -// (i.e., is symtab_size() equal to MAX_SYMTAB_SIZE-1)? -bool symtab_full() { return size >= MAX_SYMTAB_SIZE; } - -// Is the given name associated with some attributes? -bool symtab_defined(const char *name) -{ - id_attrs_assoc *v = symtab_lookup(name); - return v != NULL; -} - -// Requires: !symtab_full -// Requires: !symtab_defined(attrs.name) -// Remember the given attributes (i.e., an association from attrs.name -// to the other parts of attrs) -void symtab_insert(id_attrs_assoc attrs) -{ - if (symtab_full()) { - bail_with_error("The symtab is full!"); - } - entries[size++] = attrs; -} - -// if name == NULL or if name is not defined, return -1 -// if name is defined in the table, return its index -static int find_index(const char *name) -{ - if (name == NULL) { - return -1; - } - for (int i = 0; i < size; i++) { - if (strcmp(entries[i].name, name) == 0) { - return i; - } - } - return -1; -} - - -// Return (a pointer to) the attributes of the given name -// or NULL if there is no association for that name. -id_attrs_assoc *symtab_lookup(const char *name) -{ - int i = find_index(name); - if (0 <= i) { - return &entries[i]; - } else { - return NULL; - } -} - -// iteration helpers -// iterations use an external key which is a name - -// Start an iteration by returning the first name in the symbol table, -// return NULL if symtab_empty() -const char *symtab_first_name() -{ - if (symtab_empty()) { - return NULL; - } - assert(0 < size); - return entries[0].name; -} - -// Are there more names defined in the symbol table after the given one? -// This returns false if name is NULL, if name is not defined, -// or if there are no more names following name in the symbol table -bool symtab_more_after(const char *name) -{ - int i = find_index(name); - return (0 <= i && i < size); -} - -// Requires: symtab_more_after(name); -// Return the next name defined in the symbol table after the given one, -// but return NULL if there are no more names -const char *symtab_next_name(const char *name) -{ - int i = find_index(name); - if (i < 0 || i >= size) { - return NULL; - } else { - return entries[i+1].name; - } -} diff --git a/vm/symtab.h b/vm/symtab.h deleted file mode 100755 index 63a95fb..0000000 --- a/vm/symtab.h +++ /dev/null @@ -1,49 +0,0 @@ -/* $Id: symtab.h,v 1.3 2024/07/26 12:44:46 leavens Exp $ */ -#ifndef _SYMTAB_H -#define _SYMTAB_H - -#include -#include "id_attrs_assoc.h" - -// Maximum number of names/attributes that can be stored in a symboltable -#define MAX_SYMTAB_SIZE 1024 - -// initialize the symbol table -extern void symtab_initialize(); - -// Return the number of mappings in this symbol table -extern unsigned int symtab_size(); - -// Is this symbol table empty? (I.e., does it have not mappings?) -extern bool symtab_empty(); - -// Is this symbol table full? (I.e., can it not hold more mappings?) -// (i.e., is symtab_size() equal to MAX_SYMTAB_SIZE-1)? -extern bool symtab_full(); - -// Is the given name associated with some attributes? -extern bool symtab_defined(const char *name); - -// Requires: !symtab_full -// Requires: !symtab_defined(attrs.name) -// Remember the given attributes (i.e., an association from attrs.name -// to the other parts of attrs) -extern void symtab_insert(id_attrs_assoc attrs); - -// Return a pointer to the attributes of the given name -// or NULL if there is no association for that name. -extern id_attrs_assoc *symtab_lookup(const char *name); - -// Start an iteration by returning the first name in the symbol table, -// return NULL if symtab_empty() -extern const char *symtab_first_name(); - -// Are there more names defined in the symbol table after the given one? -// This returns false if name is NULL. -extern bool symtab_more_after(const char *name); - -// Requires: symtab_more_after(name); -// Return the next name defined in the symbol table after the given one, -// but return NULL if there are no more names -extern const char *symtab_next_name(const char *name); -#endif diff --git a/vm/symtab_test4.asm b/vm/symtab_test4.asm deleted file mode 100755 index 2d8978a..0000000 --- a/vm/symtab_test4.asm +++ /dev/null @@ -1,46 +0,0 @@ - # $Id: symtab_test4.asm,v 1.2 2024/08/28 21:25:00 leavens Exp $ - .text start -start: NOTR - STRA - ADDI $0, $t0, 5 # $t0 is 5 - ADDI $t0, $t1, 2 # $t1 should be 7 - ADD $t0, $t1, $t2 # $t2 should be 12 - MUL $t0, $t2 # LO should be 60 - CFLO $t3 # $t3 should be 60 - SUB $t1, $t0, $t4 # $t4 should be 2 - MUL $t3, $t4 # LO should be 120 - CFLO $t5 # $t5 should be 120 - DIV $t5, $t4 # HI should be 0, LO s.b. 60 - CFLO $t6 # $t6 should be 60 - CFHI $s7 # $s7 should be 0 - BEQ $0, $s7, 8 # write N if $s7 is not 0 - ADDI $0, $a0, 78 # 'N' - JAL outch - BLTZ $s7, 8 # write L if $s7 < 0 - ADDI $0, $a0, 76 # 'L' - JAL outch - BGTZ $s7, 8 # write H if $s7 < 0 - ADDI $0, $a0, 72 # 'H' - JAL outch - ADDI $0, $a0, 89 # 'Y' - JAL outch - EXIT - -outch: NOTR - PCH # arg already in $a0 - ADDI $0, $a0, 10 # \n - PCH - STRA -nl: NOTR - ADDI $0, $a0, 78 # $a0 is 78 ('N') - PCH - JR $ra - - .data 512 - WORD N = 78 - WORD L = 76 - WORD H = 72 - WORD nl = 10 - .stack 4096 - .end - diff --git a/vm/test.asm b/vm/test.asm deleted file mode 100755 index 82c70a9..0000000 --- a/vm/test.asm +++ /dev/null @@ -1,13 +0,0 @@ - .text 5 - PSTR $gp,0 - EXIT 1 - NOP - NOP - NOP - PSTR $gp,10 - EXIT 0 - .data 1024 - STRING[10] ERRMSG = "Should have started at location 5!\n" - STRING[10] GOOD = "OK, that started at the right spot!\n" - .stack 5024 - .end diff --git a/vm/test.c b/vm/test.c deleted file mode 100755 index f11b4b4..0000000 --- a/vm/test.c +++ /dev/null @@ -1,46 +0,0 @@ -#include -#include "machine_types.h" -#include "instruction.h" - -#define MEMORY_SIZE_IN_WORDS 4096 -#define NUM_REGISTERS 8 - -// the VM's memory, both in word and binary instruction views. -static union mem_u { - word_type words[MEMORY_SIZE_IN_WORDS]; - uword_type uwords[MEMORY_SIZE_IN_WORDS]; - bin_instr_t instrs[MEMORY_SIZE_IN_WORDS]; -} memory; - -// general purpose registers -static word_type GPR[NUM_REGISTERS]; - -int main() -{ - printf("0xffff is %d\n", 0xffff); - GPR[0] = 0; - memory.words[GPR[0]] = 0xffff; - printf("memory.words[GPR[0]] is %d\n", memory.words[GPR[0]]); - fprintf(stdout, "%8d: %d\n", GPR[0], memory.words[GPR[0]]); - printf("zeroExt(0xff00) is %x in hex, %d in decimal\n", - machine_types_zeroExt(0xff00), - machine_types_zeroExt(0xff00)); - GPR[1] = 1; - immed_instr_t ii; - ii.immed = machine_types_zeroExt(0xff00); - printf("ii.immed is %x in hex, %d in decimal\n", ii.immed, ii.immed); - memory.words[GPR[1]] = 0 | ii.immed; - fprintf(stdout, "%8d: %d\n", GPR[1], memory.words[GPR[1]]); - memory.words[GPR[1]] = ii.immed | machine_types_zeroExt(0xff); - fprintf(stdout, "%8d: %d\n", GPR[1], memory.words[GPR[1]]); - - GPR[2] = 2; - uimmed_instr_t ui; - ui.uimmed = machine_types_zeroExt(0xff00); - printf("ui.uimmed is %x in hex, %d in decimal\n", ui.uimmed, ui.uimmed); - memory.uwords[GPR[2]] = 0 | ui.uimmed; - fprintf(stdout, "%8d: %d\n", GPR[2], memory.words[GPR[2]]); - memory.uwords[GPR[2]] = memory.uwords[GPR[2]] | machine_types_zeroExt(0xff); - fprintf(stdout, "%8d: %d\n", GPR[2], memory.uwords[GPR[2]]); - -} diff --git a/vm/test0.asm b/vm/test0.asm deleted file mode 100755 index caad989..0000000 --- a/vm/test0.asm +++ /dev/null @@ -1,6 +0,0 @@ -# $Id: test0.asm,v 1.2 2023/09/16 13:45:07 leavens Exp $ -.text start -start: EXIT -.data 12 -.stack 40 -.end diff --git a/vm/test_add.asm b/vm/test_add.asm deleted file mode 100755 index 32b1240..0000000 --- a/vm/test_add.asm +++ /dev/null @@ -1,9 +0,0 @@ - # $Id: test_add.asm,v 1.1 2023/09/22 01:29:49 leavens Exp $ - .text start -start: ADDI $0, $t7, 7 # put 7 in $t7 - ADDI $0, $t5, 5 # put 5 in $t5 - ADD $t5, $t7, $t2 # put 12 in $t2 - EXIT - .data 1024 - .stack 4096 - .end diff --git a/vm/token.c b/vm/token.c deleted file mode 100755 index 276654d..0000000 --- a/vm/token.c +++ /dev/null @@ -1,38 +0,0 @@ -#include "token.h" - -#define NUM_TOKEN_TYPES 35 - -// Translation from enum values to strings -static const char *ttstrs[NUM_TOKEN_TYPES] = - {"identsym", "numbersym", "dottextsym", "dotdatasym", "dotendsym", - "colonsym", "equalsym", - "addopsym", "subopsym", "andopsym", "boropsym", "noropsym", "xoropsym", - "mulopsym", "divopsym", "sllopsym", "srlopsym", "mfhiopsym", "mfloopsym", - "jropsym", - "addiopsym", "andiopsym", "boriopsym", "xoriopsym", "noriopsym", - "beqopsym", "bgezopsym", "bgtzopsym", "bltzopsym", "bneopsym", - "lwopsym", "swopsym", "jmpaopsym", "callopsym", "rtnopsym" -}; - -// Requires: fname != NULL -// Create and return a fresh token with the given information -token token_make(token_type typ, const char *fname, - unsigned int line, unsigned int start_column, - const char *text, word_type value) { - token ret; - ret.typ = typ; - ret.filename = fname; - ret.line = line; - ret.start_column = start_column; - ret.text = text; - ret.value = value; - return ret; -} - - -// Return the name of the token_type enum -// corresponding to the given token_type value -const char *ttyp2str(token_type ttyp) -{ - return ttstrs[ttyp]; -} diff --git a/vm/token.h b/vm/token.h deleted file mode 100755 index ea88f45..0000000 --- a/vm/token.h +++ /dev/null @@ -1,39 +0,0 @@ -/* $Id: token.h,v 1.5 2024/07/17 19:55:30 leavens Exp $ */ -#ifndef _TOKEN_H -#define _TOKEN_H -#include "machine_types.h" - -#define MAX_IDENT_LENGTH 255 - -// types of tokens -typedef enum { - identsym, numbersym, dottextsym, dotdatasym, dotendsym, - colonsym, equalsym, - addopsym, subopsym, andopsym, boropsym, noropsym, xoropsym, - mulopsym, divopsym, sllopsym, srlopsym, mfhiopsym, mfloopsym, jropsym, - addiopsym, andiopsym, boriopsym, xoriopsym, noriopsym, - beqopsym, bgezopsym, bgtzopsym, bltzopsym, bneopsym, lwopsym, swopsym, - jmpaopsym, callopsym, rtnopsym -} token_type; - -// information about each token -typedef struct token { - token_type typ; - const char *filename; - unsigned int line; // the line the token occurs on - unsigned int start_column; // starting column for the token - const char *text; // the characters that make up the token's input - word_type value; // when typ==numbersym, its value -} token; - -// Requires: fname != NULL -// Create and return a fresh token with the given information -extern token token_make(token_type typ, const char *fname, - unsigned int line, unsigned int start_column, - const char *text, word_type value); - -// Return the name of the token_type enum -// corresponding to the given token_type value -extern const char *ttyp2str(token_type ttyp); - -#endif diff --git a/vm/type_distinction_demo.c b/vm/type_distinction_demo.c deleted file mode 100755 index d1ac50b..0000000 --- a/vm/type_distinction_demo.c +++ /dev/null @@ -1,50 +0,0 @@ -// $Id: type_distinction_demo.c,v 1.1 2024/07/28 13:02:44 leavens Exp $ -// This demonstration shows how one could leverage the C type checker -// to distinguish word and byte addresses. -// Unfortunately, one has to use structs for this, -// becuase C does structural type checking for all types except struct types -// yet it does by-name (nominal) type checking for struct types. -#include -#include -#include - -// in C, type checking will distinguish these types -typedef struct w_s { unsigned int w; } word_addr; -typedef struct b_s { unsigned int b; } byte_addr; - -// An example conversion factor -#define BYTES_PER_WORD 4 - -// Return the equivalent of the word address w as a byte address -byte_addr word2byte_address(word_addr w) -{ - byte_addr ret; - ret.b = BYTES_PER_WORD * w.w; - return ret; -} - -// Requires: b.b is a multiple of BYTES_PER_WORD. -// Return the equivalent of the byte address b as a word address -word_addr byte2word_address(byte_addr b) -{ - assert((b.b % BYTES_PER_WORD) == 0); - word_addr ret; - ret.w = b.b / BYTES_PER_WORD; - return ret; -} - -// A little demonstration -int main() -{ - word_addr worda; - byte_addr bytea; - worda.w = 1; - bytea = word2byte_address(worda); // okay, checked conversion - // bytea = worda; // type error! - worda.w += 1; - bytea = word2byte_address(worda); - bytea.b += 4; - worda = byte2word_address(bytea); - printf("worda: %d, bytea: %d\n", worda.w, bytea.b); - exit(0); -} diff --git a/vm/unparser_test1.asm b/vm/unparser_test1.asm deleted file mode 100755 index cdc0dab..0000000 --- a/vm/unparser_test1.asm +++ /dev/null @@ -1,12 +0,0 @@ - # $Id: unparser_test1.asm,v 1.3 2023/09/16 16:23:10 leavens Exp $ - .text go -go: ADD $8, $9, $10 - ADDI $0, $9, 52 - ADDI $0, $10, -0934 - EXIT - .data 0x1000 - WORD sixteen = 0x10 - WORD b25 = 25 - .stack 0x4000 - .end - diff --git a/vm/unparser_test2.asm b/vm/unparser_test2.asm deleted file mode 100755 index 72a7623..0000000 --- a/vm/unparser_test2.asm +++ /dev/null @@ -1,20 +0,0 @@ - # $Id: unparser_test2.asm,v 1.2 2023/09/16 13:29:58 leavens Exp $ - .text start -start: ADD $0, $1, $2 - SUB $3, $4, $5 - MUL $6, $7 - DIV $8, $9 - ADD $10, $11, $12 - ADD $13, $14, $15 - ADD $16, $17, $18 - SUB $19, $20, $21 - SUB $22, $23, $24 - MUL $25, $28 - ADD $29, $1, $8 - ADD $30, $1, $9 - JR $31 - EXIT - .data 1024 - .stack 4096 - .end - diff --git a/vm/utilities.c b/vm/utilities.c deleted file mode 100755 index e40eb93..0000000 --- a/vm/utilities.c +++ /dev/null @@ -1,94 +0,0 @@ -/* $Id: utilities.c,v 1.5 2024/07/23 14:25:45 leavens Exp $ */ -#include -#include -#include -#include -#include -#include -#include "utilities.h" - -// to turn off debugging support (assertions and debug_print) -// define the symbol NDEBUG (by writing uncommenting the following) -// #define NDEBUG - -#ifdef NDEBUG -#define debug_print() ((void)0) -#else -// otherwise debugging is on, and debug_print is defined as follows... -// (note that assert is a macro defined in -static void vdebug_print(const char *fmt, va_list args); - -// If debugging is false, do nothing, otherwise (when debugging) -// flush stderr and stdout, then print the message given on stderr, -// using printf formatting from the format string fmt. -// This function returns normally. -void debug_print(const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - vdebug_print(fmt, args); - va_end(args); -} - -// The variadic version of debug_print -static void vdebug_print(const char *fmt, va_list args) -{ - // flush output streams to synchronize outputs - fflush(stdout); - fflush(stderr); - vfprintf(stderr, fmt, args); - fflush(stderr); -} -#endif - -static void vbail_with_error(const char* fmt, va_list args); - -// Format a string error message and print it followed by a newline on stderr -// using perror (for an OS error, if the errno is not 0) -// then exit with a failure code, so a call to this does not return. -void bail_with_error(const char *fmt, ...) -{ - fflush(stdout); // flush so output comes after what has happened already - va_list(args); - va_start(args, fmt); - vbail_with_error(fmt, args); -} - -// The variadic version of bail_with_error -static void vbail_with_error(const char* fmt, va_list args) -{ - extern int errno; - char buff[2048]; - vsprintf(buff, fmt, args); - if (errno != 0) { - perror(buff); - } else { - fprintf(stderr, "%s\n", buff); - } - fflush(stderr); - exit(EXIT_FAILURE); -} - -// Print an error message on stderr -// starting with the file name and line number from the floc argument -// (prints: filename, a colon, " line ", the line number, and a space) -// and then the message. -// Then exit with a failure code, so this function does not return. -void bail_with_prog_error(file_location floc, const char *fmt, ...) -{ - fflush(stdout); // flush so output comes after what has happened already - // print file, line, column information - fprintf(stderr, "%s: line %d ", floc.filename, floc.line); - - va_list(args); - va_start(args, fmt); - vbail_with_error(fmt, args); -} - - -// print a newline on out and flush out -void newline(FILE *out) -{ - fprintf(out, "\n"); - fflush(out); -} diff --git a/vm/utilities.h b/vm/utilities.h deleted file mode 100755 index 646e411..0000000 --- a/vm/utilities.h +++ /dev/null @@ -1,31 +0,0 @@ -/* $Id: utilities.h,v 1.6 2024/07/23 14:25:45 leavens Exp $ */ -#ifndef _UTILITIES_H -#define _UTILITIES_H -#include -#include -#include -#include "file_location.h" - -#define MAX(x,y) (((x)>(y))?(x):(y)) - -// If NDEBUG is defined, do nothing, otherwise (when debugging) -// flush stderr and stdout, then print the message given on stderr, -// using printf formatting from the format string fmt. -// This function returns normally. -void debug_print(const char *fmt, ...); - -// Format a string error message and print it using perror (for an OS error) -// then exit with a failure code, so a call to this does not return. -extern void bail_with_error(const char *fmt, ...); - -// Print an error message on stderr -// starting with the file name and line number from the floc argument -// (prints: filename, a colon, " line ", the line number, and a space) -// and then the message. -// Then exit with a failure code, so this function does not return. -extern void bail_with_prog_error(file_location floc, const char *fmt, ...); - -// print a newline on out and flush out -extern void newline(FILE *out); - -#endif diff --git a/vm/vm.c b/vm/vm.c deleted file mode 100755 index 9e2af74..0000000 --- a/vm/vm.c +++ /dev/null @@ -1,12 +0,0 @@ -#include -#include -#include "bof.h" -#include "utilities.h" -int main(int argc, char *argv[]) { - if (argc >= 2) { - BOFFILE bf = bof_read_open(argv[1]); - } else { - bail_with_error("Cannot read %s!", argv[1]); - } - return EXIT_SUCCESS; -} diff --git a/vm/vm_test0.asm b/vm/vm_test0.asm deleted file mode 100755 index 228752e..0000000 --- a/vm/vm_test0.asm +++ /dev/null @@ -1,9 +0,0 @@ - # $Id: vm_test0.asm,v 1.3 2024/07/26 12:44:46 leavens Exp $ - .text start -start: STRA - ADDI $sp, -1, 2 - EXIT 0 - .data 1024 - .stack 4096 - .end - diff --git a/vm/vm_test0.lst b/vm/vm_test0.lst deleted file mode 100755 index 2f5f311..0000000 --- a/vm/vm_test0.lst +++ /dev/null @@ -1,5 +0,0 @@ -Address Instruction - 0: STRA - 1: ADDI $sp, -1, 2 - 2: EXIT 0 - 1024: 0 ... diff --git a/vm/vm_test1.asm b/vm/vm_test1.asm deleted file mode 100755 index a1b026f..0000000 --- a/vm/vm_test1.asm +++ /dev/null @@ -1,22 +0,0 @@ - # $Id: vm_test1.asm,v 1.6 2024/07/29 02:01:32 leavens Exp $ - .text start -start: STRA - SRI $sp, 2 # allocate 2 words on the stack - ADDI $sp, 1, 1 # put 1 in memory[$sp+1] - ADD $gp, 2, $sp, 1 # put 1 in temp - ADD $sp, 0, $gp, 2 # put 1 in stack top - SUB $gp, 2, $gp, 2 # zero out temp - ADDI $sp, 0, 10 # add 10 to stack top, should be 11 - SRI $sp, 1 # allocate a word on the stack - NOTR - PCH $gp, 0 # print y - PCH $gp, 3 # print nl - EXIT 0 - .data 1024 - CHAR y = 'y' - CHAR n = 'n' - WORD temp # not initialized - CHAR nl = '\n' - .stack 4096 - .end - diff --git a/vm/vm_test1.lst b/vm/vm_test1.lst deleted file mode 100755 index 21811d8..0000000 --- a/vm/vm_test1.lst +++ /dev/null @@ -1,15 +0,0 @@ -Address Instruction - 0: STRA - 1: SRI $sp, 2 - 2: ADDI $sp, 1, 1 - 3: ADD $gp, 2, $sp, 1 - 4: ADD $sp, 0, $gp, 2 - 5: SUB $gp, 2, $gp, 2 - 6: ADDI $sp, 0, 10 - 7: SRI $sp, 1 - 8: NOTR - 9: PCH $gp, 0 - 10: PCH $gp, 3 - 11: EXIT 0 - 1024: 121 1025: 110 1026: 0 1027: 10 1028: 0 - ... diff --git a/vm/vm_test2.asm b/vm/vm_test2.asm deleted file mode 100755 index ae29738..0000000 --- a/vm/vm_test2.asm +++ /dev/null @@ -1,19 +0,0 @@ - # $Id: vm_test2.asm,v 1.3 2024/07/29 02:01:32 leavens Exp $ - .text start -start: ADDI $sp, 0, 1 # top of stack is 1 - ADD $sp, 0, $sp, 0 # top of stack is 2 - ADDI $sp, 0, 1 # top of stack is 3 - ADD $sp, 0, $sp, 0 # $top of stack is 6 - SLL $sp, 0, 1 # top of stack is 12 - SRI $sp, 4 # allocate a word on the stack - # NOTR - PCH $gp, 1 # print 'Y' - PCH $gp, 2 # print '\n' - EXIT 0 - .data 1024 - WORD x = 33 - CHAR y = 'Y' - CHAR nl = '\n' - .stack 4096 - .end - diff --git a/vm/vm_test2.lst b/vm/vm_test2.lst deleted file mode 100755 index 5c98036..0000000 --- a/vm/vm_test2.lst +++ /dev/null @@ -1,12 +0,0 @@ -Address Instruction - 0: ADDI $sp, 0, 1 - 1: ADD $sp, 0, $sp, 0 - 2: ADDI $sp, 0, 1 - 3: ADD $sp, 0, $sp, 0 - 4: SLL $sp, 0, 1 - 5: SRI $sp, 4 - 6: PCH $gp, 1 - 7: PCH $gp, 2 - 8: EXIT 0 - 1024: 33 1025: 89 1026: 10 1027: 0 ... - diff --git a/vm/vm_test3.asm b/vm/vm_test3.asm deleted file mode 100755 index cbc4354..0000000 --- a/vm/vm_test3.asm +++ /dev/null @@ -1,30 +0,0 @@ - # $Id: vm_test3.asm,v 1.5 2024/08/29 20:26:00 leavens Exp $ - .text start -start: STRA - ADDI $sp, 0, 30 # stack top is 30 - SRI $sp, 1 # subtract 1 from SP (allocate a word) - ADDI $sp, 0, 20 # top of stack is 20 - ADDI $sp, 0, 10 # stack top is 30 - BNE $sp, 1, +3 # skip if stack top and stack+1 are not equal - CALL yes - JMPA done - CALL no - JMPA done -yes: NOTR - PSTR $gp, 1 # print yes - RTN -no: NOTR - PSTR $gp, 2 # print no - RTN - STRA - EXIT 1 -done: STRA - EXIT 0 - - .data 1024 - WORD x = 33 - STRING[1] yeah = "Y\n" - STRING[1] nay = "No\n" - .stack 4096 - .end - diff --git a/vm/vm_test3.lst b/vm/vm_test3.lst deleted file mode 100755 index 30d709b..0000000 --- a/vm/vm_test3.lst +++ /dev/null @@ -1,23 +0,0 @@ -Address Instruction - 0: STRA - 1: ADDI $sp, 0, 30 - 2: SRI $sp, 1 - 3: ADDI $sp, 0, 20 - 4: ADDI $sp, 0, 10 - 5: BNE $sp, 1, 3 # target is word address 8 - 6: CALL 10 # target is word address 10 - 7: JMPA 18 # target is word address 18 - 8: CALL 13 # target is word address 13 - 9: JMPA 18 # target is word address 18 - 10: NOTR - 11: PSTR $gp, 1 - 12: RTN - 13: NOTR - 14: PSTR $gp, 2 - 15: RTN - 16: STRA - 17: EXIT 1 - 18: STRA - 19: EXIT 0 - 1024: 33 1025: 2649 1026: 683854 1027: 0 ... - diff --git a/vm/vm_test4.asm b/vm/vm_test4.asm deleted file mode 100755 index f8e1437..0000000 --- a/vm/vm_test4.asm +++ /dev/null @@ -1,51 +0,0 @@ -# $Id: vm_test4.asm,v 1.5 2024/08/29 20:26:00 leavens Exp $ - .text start -start: NOTR - STRA - ADDI $sp, 0, 5 # stack top is 5 - ADDI $sp, -1, 2 # memory[SP-1] is 2 - ARI $sp, -1 # make stack top point to where the 2 is - ADD $sp, 0, $sp, 1 # stack top should be 7 - MUL $sp, 1 # LO should be (5 * 7) = 35 - SRI $sp, 1 # allocate a word on stack - CFLO $sp, 0 # stack top is 35 - SUB $sp, 0, $sp, 1 # stack top should be (35-7) = 28 - MUL $sp, 2 # LO should be (28 * 5) = 140 - SRI $sp, 1 # allocate a word on stack - CFLO $sp, 0 # stack top is 140 - SRI $sp, 1 # allocate a word on stack - CPW $sp, 0, $sp, 2 # put 28 on top of stack - DIV $sp, 4 # HI should be (28 % 5) = 3, LO s.b. (28 / 5) = 5 - SRI $sp, 2 # allocate two words on stack - CFLO $sp, 0 # stack top should be 5 - CFHI $sp, 1 # second from top should be 3 - SRI $sp, 1 # allocate a word on the stack - ADDI $sp, 0, 5 # store 5! on top of stack - BEQ $sp, 1, 2 # write no and exit 1 if memory[$sp+1] is not 5 - CALL no - CALL yes - ARI $sp, 1 # pop a word off the stack - SWR $sp, 0, $r4 # store a 0 (from $r4) into top of stack - ADDI $sp, 0, 3 # make top of stack be 3 - BEQ $sp, 1, 2 # write no if memory[$sp+1] is not 3 - CALL no - CALL yes -done: EXIT 0 - -yes: NOTR - PSTR $gp, 0 # print "y\n" - STRA - RTN - -no: NOTR - PSTR $gp, 1 # print "no\n" - STRA - EXIT 1 - RTN - - .data 512 - STRING[1] y = "y\n" - STRING[1] n = "no\n" - .stack 4096 - .end - diff --git a/vm/vm_test4.lst b/vm/vm_test4.lst deleted file mode 100755 index 48c4f84..0000000 --- a/vm/vm_test4.lst +++ /dev/null @@ -1,43 +0,0 @@ -Address Instruction - 0: NOTR - 1: STRA - 2: ADDI $sp, 0, 5 - 3: ADDI $sp, -1, 2 - 4: ARI $sp, -1 - 5: ADD $sp, 0, $sp, 1 - 6: MUL $sp, 1 - 7: SRI $sp, 1 - 8: CFLO $sp, 0 - 9: SUB $sp, 0, $sp, 1 - 10: MUL $sp, 2 - 11: SRI $sp, 1 - 12: CFLO $sp, 0 - 13: SRI $sp, 1 - 14: CPW $sp, 0, $sp, 2 - 15: DIV $sp, 4 - 16: SRI $sp, 2 - 17: CFLO $sp, 0 - 18: CFHI $sp, 1 - 19: SRI $sp, 1 - 20: ADDI $sp, 0, 5 - 21: BEQ $sp, 1, 2 # target is word address 23 - 22: CALL 35 # target is word address 35 - 23: CALL 31 # target is word address 31 - 24: ARI $sp, 1 - 25: SWR $sp, 0, $r4 - 26: ADDI $sp, 0, 3 - 27: BEQ $sp, 1, 2 # target is word address 29 - 28: CALL 35 # target is word address 35 - 29: CALL 31 # target is word address 31 - 30: EXIT 0 - 31: NOTR - 32: PSTR $gp, 0 - 33: STRA - 34: RTN - 35: NOTR - 36: PSTR $gp, 1 - 37: STRA - 38: EXIT 1 - 39: RTN - 512: 2681 513: 683886 514: 0 ... - diff --git a/vm/vm_test5.asm b/vm/vm_test5.asm deleted file mode 100755 index 6b4fa20..0000000 --- a/vm/vm_test5.asm +++ /dev/null @@ -1,49 +0,0 @@ - # $Id: vm_test5.asm,v 1.4 2024/08/29 20:26:00 leavens Exp $ - .text start -start: ADDI $sp, 0, 0x7 # stack top is 7 - ADDI $sp, -1, 0xf # 1 above stack top is 15 - ARI $sp, -1 # make the stack top be the location with 15 - LWR $r4, $gp, 0 # $r4 should be 2 - AND $sp, 0, $sp, 0 # stack top should (still) be 15 - SLL $sp, 0, 5 # stack top should be 480 - ADDI $sp, 0, -405 # stack top is 75 - SRI $sp, 1 # allocate a word on the stack - ADDI $sp, 0, 2 # put 2 on top of stack - SLL $sp, 0, 7 # top of stack is 256 - SRL $sp, 0, 2 # stack top is 64 - ARI $sp, -1 # allocate a word on the stack - LIT $sp, 0, 11 # put 11 on top of stack - LWR $r5, $sp, 0 # put 11 in $r5 - XOR $sp, 0, $sp, 0 # make top of stack be 0 - SWR $sp, 0, $r5 # put 11 on top of stack - NEG $sp, 0, $sp, 0 # make top of stack be -11 - LIT $sp, 1, 75 # put 75 in memory[SP+1] - ARI $sp, 1 # pop the stack - BNE $sp, 1, 3 # skip if top 2 stack elements are not equal - CALL y - JMPA done - CALL n - JMPA bad -done: EXIT 0 -bad: EXIT 1 - -y: NOTR - PSTR $gp, 5 - STRA - RTN - -n: NOTR - PSTR $gp, 1 - STRA - RTN - - .data 512 - WORD TWO = 2 - STRING[1] No = "No\n" - WORD L = 76 - WORD H = 72 - WORD nl = 10 - STRING[2] Yes = "Yes!\n" - .stack 4096 - .end - diff --git a/vm/vm_test5.lst b/vm/vm_test5.lst deleted file mode 100755 index 1e1032e..0000000 --- a/vm/vm_test5.lst +++ /dev/null @@ -1,38 +0,0 @@ -Address Instruction - 0: ADDI $sp, 0, 7 - 1: ADDI $sp, -1, 15 - 2: ARI $sp, -1 - 3: LWR $r4, $gp, 0 - 4: AND $sp, 0, $sp, 0 - 5: SLL $sp, 0, 5 - 6: ADDI $sp, 0, -405 - 7: SRI $sp, 1 - 8: ADDI $sp, 0, 2 - 9: SLL $sp, 0, 7 - 10: SRL $sp, 0, 2 - 11: ARI $sp, -1 - 12: LIT $sp, 0, 11 - 13: LWR $r5, $sp, 0 - 14: XOR $sp, 0, $sp, 0 - 15: SWR $sp, 0, $r5 - 16: NEG $sp, 0, $sp, 0 - 17: LIT $sp, 1, 75 - 18: ARI $sp, 1 - 19: BNE $sp, 1, 3 # target is word address 22 - 20: CALL 26 # target is word address 26 - 21: JMPA 24 # target is word address 24 - 22: CALL 30 # target is word address 30 - 23: JMPA 25 # target is word address 25 - 24: EXIT 0 - 25: EXIT 1 - 26: NOTR - 27: PSTR $gp, 5 - 28: STRA - 29: RTN - 30: NOTR - 31: PSTR $gp, 1 - 32: STRA - 33: RTN - 512: 2 513: 683854 514: 76 515: 72 516: 10 - 517: 561210713 518: 10 519: 0 ... - diff --git a/vm/vm_test6.asm b/vm/vm_test6.asm deleted file mode 100755 index 2885829..0000000 --- a/vm/vm_test6.asm +++ /dev/null @@ -1,32 +0,0 @@ - # $Id: vm_test6.asm,v 1.7 2024/08/29 20:26:00 leavens Exp $ - .text start -start: ADDI $sp, -1, 1 # one word above top of stack gets 1 - CPW $sp, 0, $sp, -1 - SLL $sp, -1, 20 # one word above top of stack gets 2^20 - SRI $sp, 1 # SP = SP - 1 - ADD $sp, 0, $gp, 0 # top of stack is 2^20+1 - SRI $sp, 1 # allocate a word - LIT $sp, 0, 4 # put 4 on top of stack - LWR $r4, $sp, 0 # $r4 is 4 - LIT $sp, 0, 14 # top of stack is 14 - LWR $r5, $sp, 0 # $r5 is 14 - SWR $sp, -1, $r4 # one word above top of stack gets 4 - ARI $sp, -2 # allocate 2 words on the stack - SWR $sp, 0, $r5 # top of stack gets 14 - DIV $sp, 1 # HI is 2, LO is 3 - CFLO $gp, 2 # dividend holds 3 - CFHI $gp, 1 # rem is 2 - SRI $sp, 1 # allocate a word on top of stack - LIT $sp, 0, 1 # top of stack gets 1 - SLL $sp, 0, 10 # put 2^10 (i.e., 1024) on top of stack - MUL $sp, 0 # square top of stack, result in (HI, LO) - CFHI $sp, -2 - CFLO $sp, -1 - SRI $sp, 2 - EXIT 0 - .data 1024 - WORD one = 1 - WORD rem = 0 - WORD dividend = 0 - .stack 4096 - .end diff --git a/vm/vm_test6.lst b/vm/vm_test6.lst deleted file mode 100755 index bf109ae..0000000 --- a/vm/vm_test6.lst +++ /dev/null @@ -1,26 +0,0 @@ -Address Instruction - 0: ADDI $sp, -1, 1 - 1: CPW $sp, 0, $sp, -1 - 2: SLL $sp, -1, 20 - 3: SRI $sp, 1 - 4: ADD $sp, 0, $gp, 0 - 5: SRI $sp, 1 - 6: LIT $sp, 0, 4 - 7: LWR $r4, $sp, 0 - 8: LIT $sp, 0, 14 - 9: LWR $r5, $sp, 0 - 10: SWR $sp, -1, $r4 - 11: ARI $sp, -2 - 12: SWR $sp, 0, $r5 - 13: DIV $sp, 1 - 14: CFLO $gp, 2 - 15: CFHI $gp, 1 - 16: SRI $sp, 1 - 17: LIT $sp, 0, 1 - 18: SLL $sp, 0, 10 - 19: MUL $sp, 0 - 20: CFHI $sp, -2 - 21: CFLO $sp, -1 - 22: SRI $sp, 2 - 23: EXIT 0 - 1024: 1 1025: 0 ... diff --git a/vm/vm_test7.asm b/vm/vm_test7.asm deleted file mode 100755 index 4c56b98..0000000 --- a/vm/vm_test7.asm +++ /dev/null @@ -1,63 +0,0 @@ - # $Id: vm_test7.asm,v 1.5 2024/08/15 18:39:21 leavens Exp $ - # manipulation of the runtime stack - .text main -main: SRI $sp, 6 # put numbers in the registers - LIT $sp, 6, 7 - LWR $ra, $sp, 6 - LIT $sp, 5, 6 - LWR $r6, $sp, 5 - LIT $sp, 4, 5 - LWR $r5, $sp, 4 - LIT $sp, 3, 4 - LWR $r4, $sp, 3 - LIT $sp, 2, 3 - LWR $r3, $sp, 2 - LIT $sp, 1, 2 - # LWR $sp, $sp, 1 # putting 2 in $sp would violate a machine invariant - SCA $sp, 0, $sp, 0 - - CALL callerSave - SRI $sp, 1 - LIT $sp, 0, -1 - LWR $r6, $sp, 0 - LWR $r5, $sp, 0 - LWR $r4, $sp, 0 - LWR $r3, $sp, 0 - ARI $sp, 1 - CALL callerRestore - - EXIT 0 -bad: EXIT 1 - - # callerSave is a subroutine that saves the registers - # that a caller might need to save on the stack. - # These registers are left undistubed... - # However, since this is a subroutine, it can't save $ra, - # and it disturbs $sp, so those would need to be saved first -callerSave: SRI $sp, 5 # allocate 5 words on the stack - SWR $sp, 4, $fp # save $fp... - SWR $sp, 3, $r3 - SWR $sp, 2, $r4 - SWR $sp, 1, $r5 - SWR $sp, 0, $r6 - RTN - - - # callerRestore is a subroutine that restores all registers - # that were saved by callerSave (on the stack) - # Assuming the runtime stack is in the same state it was - # after calling callerSave, it also restores the $sp - # to its previous value. - # Note that the user will need to restore $ra manually - # after calling this subroutine. -callerRestore: LWR $r6, $sp, 0 - LWR $r5, $sp, 1 # restore $r5 ... - LWR $r4, $sp, 2 - LWR $r3, $sp, 3 - LWR $fp, $sp, 4 - ARI $sp, 5 # deallocate the 5 words - RTN - - .data 1024 - .stack 4096 - .end diff --git a/vm/vm_test7.lst b/vm/vm_test7.lst deleted file mode 100755 index 6f183f6..0000000 --- a/vm/vm_test7.lst +++ /dev/null @@ -1,40 +0,0 @@ -Address Instruction - 0: SRI $sp, 6 - 1: LIT $sp, 6, 7 - 2: LWR $ra, $sp, 6 - 3: LIT $sp, 5, 6 - 4: LWR $r6, $sp, 5 - 5: LIT $sp, 4, 5 - 6: LWR $r5, $sp, 4 - 7: LIT $sp, 3, 4 - 8: LWR $r4, $sp, 3 - 9: LIT $sp, 2, 3 - 10: LWR $r3, $sp, 2 - 11: LIT $sp, 1, 2 - 12: SCA $sp, 0, $sp, 0 - 13: CALL 24 # target is word address 24 - 14: SRI $sp, 1 - 15: LIT $sp, 0, -1 - 16: LWR $r6, $sp, 0 - 17: LWR $r5, $sp, 0 - 18: LWR $r4, $sp, 0 - 19: LWR $r3, $sp, 0 - 20: ARI $sp, 1 - 21: CALL 31 # target is word address 31 - 22: EXIT 0 - 23: EXIT 1 - 24: SRI $sp, 5 - 25: SWR $sp, 4, $fp - 26: SWR $sp, 3, $r3 - 27: SWR $sp, 2, $r4 - 28: SWR $sp, 1, $r5 - 29: SWR $sp, 0, $r6 - 30: RTN - 31: LWR $r6, $sp, 0 - 32: LWR $r5, $sp, 1 - 33: LWR $r4, $sp, 2 - 34: LWR $r3, $sp, 3 - 35: LWR $fp, $sp, 4 - 36: ARI $sp, 5 - 37: RTN - 1024: 0 ... diff --git a/vm/vm_test8.asm b/vm/vm_test8.asm deleted file mode 100755 index 936dd30..0000000 --- a/vm/vm_test8.asm +++ /dev/null @@ -1,14 +0,0 @@ - # $Id: vm_test8.asm,v 1.4 2024/08/15 18:58:50 leavens Exp $ - .text 0 - LIT $sp, 0, 17 - LWR $r4, $sp, 0 # put 14 in $r4 - SRI $sp, 2 - LIT $sp, 0, 19 - LWR $r5, $sp, 0 # put 19 in $r5 - SCA $sp, -1, $sp, 0 # store stack top address - LWI $sp, -2, $sp, -1 - SRI $sp, 2 - EXIT 0 - .data 256 - .stack 1024 - .end diff --git a/vm/vm_test8.lst b/vm/vm_test8.lst deleted file mode 100755 index 7baf6da..0000000 --- a/vm/vm_test8.lst +++ /dev/null @@ -1,11 +0,0 @@ -Address Instruction - 0: LIT $sp, 0, 17 - 1: LWR $r4, $sp, 0 - 2: SRI $sp, 2 - 3: LIT $sp, 0, 19 - 4: LWR $r5, $sp, 0 - 5: SCA $sp, -1, $sp, 0 - 6: LWI $sp, -2, $sp, -1 - 7: SRI $sp, 2 - 8: EXIT 0 - 256: 0 ... diff --git a/vm/vm_test9.asm b/vm/vm_test9.asm deleted file mode 100755 index bf5c48d..0000000 --- a/vm/vm_test9.asm +++ /dev/null @@ -1,24 +0,0 @@ - # $Id: vm_test9.asm,v 1.2 2024/08/22 03:03:33 leavens Exp $ - .text 0 - SRI $sp, 1 - XORI $sp, 0, 0x567a - LIT $sp, -1, 0x67a - BORI $sp, -1, 0x5000 - BNE $sp, -1, 8 # fail if not equal - ANDI $sp, 0, 0xFFF - LIT $sp, -2, 0x67a - BNE $sp, -2, 5 # fail if not equal -good: NOTR - PSTR $gp, 0 - STRA - EXIT 0 -bad: NOTR - PSTR $gp, 1 - STRA - EXIT 1 - .data 1024 - STRING[1] Y = "Y\n" - STRING [1] no = "no\n" - CHAR nl = '\n' - .stack 4096 - .end diff --git a/vm/vm_test9.lst b/vm/vm_test9.lst deleted file mode 100755 index a29cd61..0000000 --- a/vm/vm_test9.lst +++ /dev/null @@ -1,19 +0,0 @@ -Address Instruction - 0: SRI $sp, 1 - 1: XORI $sp, 0, 0x567a - 2: LIT $sp, -1, 1658 - 3: BORI $sp, -1, 0x5000 - 4: BNE $sp, -1, 8 # target is word address 12 - 5: ANDI $sp, 0, 0xfff - 6: LIT $sp, -2, 1658 - 7: BNE $sp, -2, 5 # target is word address 12 - 8: NOTR - 9: PSTR $gp, 0 - 10: STRA - 11: EXIT 0 - 12: NOTR - 13: PSTR $gp, 1 - 14: STRA - 15: EXIT 1 - 1024: 2649 1025: 683886 1026: 10 1027: 0 ... - diff --git a/vm/vm_testA.asm b/vm/vm_testA.asm deleted file mode 100755 index ec25988..0000000 --- a/vm/vm_testA.asm +++ /dev/null @@ -1,21 +0,0 @@ - # $Id: vm_testA.asm,v 1.1 2024/08/22 13:33:49 leavens Exp $ - .text 0 - SRI $sp, 1 - XORI $sp, 0, 0xffff - LIT $sp, -1, 0xff - BORI $sp, -1, 0xff00 - BNE $sp, -1, 5 # fail if not equal -good: NOTR - PSTR $gp, 0 - STRA - EXIT 0 -bad: NOTR - PSTR $gp, 1 - STRA - EXIT 1 - .data 1024 - STRING[1] Y = "Y\n" - STRING [1] no = "no\n" - CHAR nl = '\n' - .stack 4096 - .end diff --git a/vm/vm_testA.lst b/vm/vm_testA.lst deleted file mode 100755 index 138e707..0000000 --- a/vm/vm_testA.lst +++ /dev/null @@ -1,16 +0,0 @@ -Address Instruction - 0: SRI $sp, 1 - 1: XORI $sp, 0, 0xffff - 2: LIT $sp, -1, 255 - 3: BORI $sp, -1, 0xff00 - 4: BNE $sp, -1, 5 # target is word address 9 - 5: NOTR - 6: PSTR $gp, 0 - 7: STRA - 8: EXIT 0 - 9: NOTR - 10: PSTR $gp, 1 - 11: STRA - 12: EXIT 1 - 1024: 2649 1025: 683886 1026: 10 1027: 0 ... - diff --git a/vm/vm_testB.asm b/vm/vm_testB.asm deleted file mode 100755 index 856db8f..0000000 --- a/vm/vm_testB.asm +++ /dev/null @@ -1,22 +0,0 @@ - # $Id: vm_testB.asm,v 1.1 2024/08/22 14:29:52 leavens Exp $ - .text 0 - SRI $sp, 1 - XORI $sp, 0, 0xffff - LIT $sp, -1, 0xff - LIT $sp, -2, -1 - BORI $sp, -1, 0xff00 - BNE $sp, -1, 5 # fail if not equal -good: NOTR - PSTR $gp, 0 - STRA - EXIT 0 -bad: NOTR - PSTR $gp, 1 - STRA - EXIT 1 - .data 1024 - STRING[1] Y = "Y\n" - STRING [1] no = "no\n" - CHAR nl = '\n' - .stack 4096 - .end diff --git a/vm/vm_testB.lst b/vm/vm_testB.lst deleted file mode 100755 index acfa67b..0000000 --- a/vm/vm_testB.lst +++ /dev/null @@ -1,17 +0,0 @@ -Address Instruction - 0: SRI $sp, 1 - 1: XORI $sp, 0, 0xffff - 2: LIT $sp, -1, 255 - 3: LIT $sp, -2, -1 - 4: BORI $sp, -1, 0xff00 - 5: BNE $sp, -1, 5 # target is word address 10 - 6: NOTR - 7: PSTR $gp, 0 - 8: STRA - 9: EXIT 0 - 10: NOTR - 11: PSTR $gp, 1 - 12: STRA - 13: EXIT 1 - 1024: 2649 1025: 683886 1026: 10 1027: 0 ... - diff --git a/vm/vm_testC.asm b/vm/vm_testC.asm deleted file mode 100755 index bae0e32..0000000 --- a/vm/vm_testC.asm +++ /dev/null @@ -1,29 +0,0 @@ - # $Id: vm_testC.asm,v 1.1 2024/09/25 14:16:06 leavens Exp $ - .text 0 - SRI $sp, 1 # allocate a word on stack - LIT $sp, 0, 1 # put a 1 on top of the stack - SLL $sp, 0, 30 # make top of stack be 2^30 - SUB $sp, 0, $gp, 0 # make top of stack be (2^30)-1 - BEQ $gp, 7, +2 - JMPA wrong - MUL $sp, 0 # (HI,LO) is ((2^30)-1)^2 - CFHI $sp, 0 # HI is most significant bits of result - BEQ $gp, 8, +2 - JMPA wrong - CFLO $sp, 0 - BEQ $gp, 9, +2 - JMPA wrong - NOTR -pass: PSTR $gp, 4 - EXIT 0 -wrong: PSTR $gp, 1 - EXIT 1 - .data 4096 - WORD one = 1 - STRING[3] Wrong = "Wrong!\n" - STRING[3] Passed = "Passed!\n" - WORD two30m1 = 1073741823 # (2^30)-1 - WORD mostSignif = 268435455 - WORD leastSignif = -2147483647 - .stack 32000 - .end diff --git a/vm/vm_testC.lst b/vm/vm_testC.lst deleted file mode 100755 index 9a912c3..0000000 --- a/vm/vm_testC.lst +++ /dev/null @@ -1,23 +0,0 @@ -Address Instruction - 0: SRI $sp, 1 - 1: LIT $sp, 0, 1 - 2: SLL $sp, 0, 30 - 3: SUB $sp, 0, $gp, 0 - 4: BEQ $gp, 7, 2 # target is word address 6 - 5: JMPA 16 # target is word address 16 - 6: MUL $sp, 0 - 7: CFHI $sp, 0 - 8: BEQ $gp, 8, 2 # target is word address 10 - 9: JMPA 16 # target is word address 16 - 10: CFLO $sp, 0 - 11: BEQ $gp, 9, 2 # target is word address 13 - 12: JMPA 16 # target is word address 16 - 13: NOTR - 14: PSTR $gp, 4 - 15: EXIT 0 - 16: PSTR $gp, 1 - 17: EXIT 1 - 4096: 1 4097: 1852797527 4098: 663911 4099: 0 - 4100: 1936941392 4101: 169960549 4102: 0 4103: 1073741823 - 4104: 268435455 4105: -2147483647 4106: 0 ... - diff --git a/vm/vm_testD.asm b/vm/vm_testD.asm deleted file mode 100755 index 35210df..0000000 --- a/vm/vm_testD.asm +++ /dev/null @@ -1,37 +0,0 @@ - # $Id: vm_testD.asm,v 1.1 2024/09/25 19:46:40 leavens Exp $ - .text 0 - SRI $sp, 2 # allocate 2 words on stack - LIT $sp, 0, 1 # put a 1 on top of the stack - LIT $sp, 1, 1 # put a 1 just above the top of stack - PINT $sp, 1 - BEQ $sp, 1, +2 - JMPA wrong - SLL $sp, 0, 30 # make top of stack be 2^30 - SUB $sp, 0, $gp, 0 # make top of stack be (2^30)-1 - CPW $sp, 1, $sp, 0 # make ($sp+1) be (2^30)-1 - PINT $sp, 0 - PINT $gp, 7 - CPW $sp, 0, $sp, 1 # restore top of stack - BEQ $gp, 7, +2 - JMPA wrong - MUL $sp, 0 # (HI,LO) is ((2^30)-1)^2 - CFHI $sp, 0 # HI is most significant bits of result - BEQ $gp, 8, +2 - JMPA wrong - CFLO $sp, 0 - BEQ $gp, 9, +2 - JMPA wrong - NOTR -pass: PSTR $gp, 4 - EXIT 0 -wrong: PSTR $gp, 1 - EXIT 1 - .data 4096 - WORD one = 1 - STRING[3] Wrong = "Wrong!\n" - STRING[3] Passed = "Passed!\n" - WORD two30m1 = 1073741823 # (2^30)-1 - WORD mostSignif = 268435455 - WORD leastSignif = -2147483647 - .stack 32000 - .end diff --git a/vm/vm_testD.lst b/vm/vm_testD.lst deleted file mode 100755 index 835f89d..0000000 --- a/vm/vm_testD.lst +++ /dev/null @@ -1,31 +0,0 @@ -Address Instruction - 0: SRI $sp, 2 - 1: LIT $sp, 0, 1 - 2: LIT $sp, 1, 1 - 3: PINT $sp, 1 - 4: BEQ $sp, 1, 2 # target is word address 6 - 5: JMPA 24 # target is word address 24 - 6: SLL $sp, 0, 30 - 7: SUB $sp, 0, $gp, 0 - 8: CPW $sp, 1, $sp, 0 - 9: PINT $sp, 0 - 10: PINT $gp, 7 - 11: CPW $sp, 0, $sp, 1 - 12: BEQ $gp, 7, 2 # target is word address 14 - 13: JMPA 24 # target is word address 24 - 14: MUL $sp, 0 - 15: CFHI $sp, 0 - 16: BEQ $gp, 8, 2 # target is word address 18 - 17: JMPA 24 # target is word address 24 - 18: CFLO $sp, 0 - 19: BEQ $gp, 9, 2 # target is word address 21 - 20: JMPA 24 # target is word address 24 - 21: NOTR - 22: PSTR $gp, 4 - 23: EXIT 0 - 24: PSTR $gp, 1 - 25: EXIT 1 - 4096: 1 4097: 1852797527 4098: 663911 4099: 0 - 4100: 1936941392 4101: 169960549 4102: 0 4103: 1073741823 - 4104: 268435455 4105: -2147483647 4106: 0 ... - diff --git a/vm/vm_testE.asm b/vm/vm_testE.asm deleted file mode 100755 index 9f79085..0000000 --- a/vm/vm_testE.asm +++ /dev/null @@ -1,12 +0,0 @@ - # $Id: vm_testE.asm,v 1.1 2024/11/10 14:34:25 leavens Exp leavens $ - .text 0 - SRI $sp, 1 - CPR $sp, $fp - SWR $sp, 0, $sp - SWR $gp, 0, $fp - BEQ $gp, 0, 2 -bad: EXIT 1 -okay: EXIT 0 - .data 2048 - .stack 8096 - .end diff --git a/vm/vm_testE.lst b/vm/vm_testE.lst deleted file mode 100755 index 2a7a7ca..0000000 --- a/vm/vm_testE.lst +++ /dev/null @@ -1,9 +0,0 @@ -Address Instruction - 0: SRI $sp, 1 - 1: CPR $sp, $fp - 2: SWR $sp, 0, $sp - 3: SWR $gp, 0, $fp - 4: BEQ $gp, 0, 2 # target is word address 6 - 5: EXIT 1 - 6: EXIT 0 - 2048: 0 ... From b3db080701a2e23ef32f185bdaee32f3a6d190e1 Mon Sep 17 00:00:00 2001 From: MarkMango21 Date: Wed, 20 Nov 2024 19:55:13 -0800 Subject: [PATCH 3/6] debugg --- FromGithub/Makefile | 189 +++ FromGithub/README.md | 1 + FromGithub/ast.c | 780 +++++++++++ FromGithub/ast.h | 537 ++++++++ FromGithub/ast.o | Bin 0 -> 53040 bytes FromGithub/bof.c | 193 +++ FromGithub/bof.h | 88 ++ FromGithub/bof.o | Bin 0 -> 16544 bytes FromGithub/char-inputs.txt | 6 + FromGithub/code.c | 494 +++++++ FromGithub/code.h | 230 ++++ FromGithub/code.o | Bin 0 -> 26000 bytes FromGithub/code_seq.c | 137 ++ FromGithub/code_seq.h | 56 + FromGithub/code_seq.o | Bin 0 -> 14888 bytes FromGithub/code_utils.c | 158 +++ FromGithub/code_utils.h | 59 + FromGithub/code_utils.o | Bin 0 -> 13664 bytes FromGithub/compiler_main.c | 120 ++ FromGithub/compiler_main.o | Bin 0 -> 22312 bytes FromGithub/file_location.c | 34 + FromGithub/file_location.h | 21 + FromGithub/file_location.o | Bin 0 -> 5160 bytes FromGithub/gen_code.c | 634 +++++++++ FromGithub/gen_code.h | 103 ++ FromGithub/hw4-gtest0.spl | 3 + FromGithub/hw4-gtest1.spl | 4 + FromGithub/hw4-gtest2.spl | 7 + FromGithub/hw4-gtest3.spl | 5 + FromGithub/hw4-gtest5.spl | 5 + FromGithub/hw4-gtest6.spl | 8 + FromGithub/hw4-gtest7.spl | 10 + FromGithub/hw4-gtest8.spl | 10 + FromGithub/hw4-gtest9.spl | 7 + FromGithub/hw4-gtestA.spl | 8 + FromGithub/hw4-gtestB.spl | 16 + FromGithub/hw4-gtestC.spl | 12 + FromGithub/hw4-gtestD.spl | 9 + FromGithub/hw4-gtestE.spl | 9 + FromGithub/hw4-gtestF.spl | 9 + FromGithub/hw4-gtestG.spl | 9 + FromGithub/hw4-gtestH.spl | 9 + FromGithub/hw4-gtestI.spl | 31 + FromGithub/hw4-gtestJ.spl | 26 + FromGithub/hw4-gtestK.spl | 8 + FromGithub/hw4-gtestL.spl | 22 + FromGithub/hw4-gtestM.spl | 18 + FromGithub/hw4-gtestN.spl | 25 + FromGithub/hw4-gtestO.spl | 15 + FromGithub/hw4-gtestP.spl | 29 + FromGithub/hw4-gtestQ.spl | 9 + FromGithub/hw4-gtestR.spl | 9 + FromGithub/hw4-gtestS.spl | 11 + FromGithub/hw4-gtestT.spl | 16 + FromGithub/hw4-read-test0.spl | 8 + FromGithub/hw4-read-test1.spl | 12 + FromGithub/hw4-vmtest0.spl | 3 + FromGithub/hw4-vmtest1.spl | 4 + FromGithub/hw4-vmtest2.spl | 8 + FromGithub/hw4-vmtest3.spl | 9 + FromGithub/hw4-vmtest4.spl | 5 + FromGithub/hw4-vmtest5.spl | 10 + FromGithub/hw4-vmtest6.spl | 13 + FromGithub/hw4-vmtest7.spl | 13 + FromGithub/hw4-vmtest8.spl | 14 + FromGithub/hw4-vmtest9.spl | 22 + FromGithub/hw4-vmtestA.spl | 16 + FromGithub/hw4-vmtestB.spl | 7 + FromGithub/hw4-vmtestC.spl | 22 + FromGithub/id_attrs.c | 50 + FromGithub/id_attrs.h | 39 + FromGithub/id_attrs.o | Bin 0 -> 6464 bytes FromGithub/id_use.c | 47 + FromGithub/id_use.h | 32 + FromGithub/id_use.o | Bin 0 -> 6760 bytes FromGithub/instruction.c | 575 ++++++++ FromGithub/instruction.h | 178 +++ FromGithub/instruction.o | Bin 0 -> 33760 bytes FromGithub/lexer.c | 6 + FromGithub/lexer.h | 39 + FromGithub/lexer_utilities.c | 8 + FromGithub/lexer_utilities.h | 15 + FromGithub/lexer_utilities.o | Bin 0 -> 2704 bytes FromGithub/lexical_address.c | 28 + FromGithub/lexical_address.h | 23 + FromGithub/literal_table.c | 168 +++ FromGithub/literal_table.h | 46 + FromGithub/machine_types.c | 100 ++ FromGithub/machine_types.h | 94 ++ FromGithub/machine_types.o | Bin 0 -> 7952 bytes FromGithub/parser.c | 22 + FromGithub/parser.h | 13 + FromGithub/parser.o | Bin 0 -> 15312 bytes FromGithub/parser_types.h | 11 + FromGithub/regname.c | 12 + FromGithub/regname.h | 18 + FromGithub/regname.o | Bin 0 -> 4208 bytes FromGithub/scope.c | 121 ++ FromGithub/scope.h | 55 + FromGithub/scope.o | Bin 0 -> 8312 bytes FromGithub/scope_check.c | 411 ++++++ FromGithub/scope_check.h | 166 +++ FromGithub/scope_check.o | Bin 0 -> 30024 bytes FromGithub/spl.output | 1265 ++++++++++++++++++ FromGithub/spl.tab.c | 2319 +++++++++++++++++++++++++++++++++ FromGithub/spl.tab.h | 133 ++ FromGithub/spl.tab.o | Bin 0 -> 68272 bytes FromGithub/spl.y | 235 ++++ FromGithub/spl_lexer.c | 2236 +++++++++++++++++++++++++++++++ FromGithub/spl_lexer.h | 492 +++++++ FromGithub/spl_lexer.l | 252 ++++ FromGithub/spl_lexer.o | Bin 0 -> 67688 bytes FromGithub/symtab.c | 169 +++ FromGithub/symtab.h | 66 + FromGithub/symtab.o | Bin 0 -> 12184 bytes FromGithub/unparser.c | 427 ++++++ FromGithub/unparser.h | 138 ++ FromGithub/unparser.o | Bin 0 -> 37816 bytes FromGithub/utilities.c | 113 ++ FromGithub/utilities.h | 37 + FromGithub/utilities.o | Bin 0 -> 11960 bytes 121 files changed, 14524 insertions(+) create mode 100644 FromGithub/Makefile create mode 100644 FromGithub/README.md create mode 100644 FromGithub/ast.c create mode 100644 FromGithub/ast.h create mode 100644 FromGithub/ast.o create mode 100644 FromGithub/bof.c create mode 100644 FromGithub/bof.h create mode 100644 FromGithub/bof.o create mode 100644 FromGithub/char-inputs.txt create mode 100644 FromGithub/code.c create mode 100644 FromGithub/code.h create mode 100644 FromGithub/code.o create mode 100644 FromGithub/code_seq.c create mode 100644 FromGithub/code_seq.h create mode 100644 FromGithub/code_seq.o create mode 100644 FromGithub/code_utils.c create mode 100644 FromGithub/code_utils.h create mode 100644 FromGithub/code_utils.o create mode 100644 FromGithub/compiler_main.c create mode 100644 FromGithub/compiler_main.o create mode 100644 FromGithub/file_location.c create mode 100644 FromGithub/file_location.h create mode 100644 FromGithub/file_location.o create mode 100644 FromGithub/gen_code.c create mode 100644 FromGithub/gen_code.h create mode 100644 FromGithub/hw4-gtest0.spl create mode 100644 FromGithub/hw4-gtest1.spl create mode 100644 FromGithub/hw4-gtest2.spl create mode 100644 FromGithub/hw4-gtest3.spl create mode 100644 FromGithub/hw4-gtest5.spl create mode 100644 FromGithub/hw4-gtest6.spl create mode 100644 FromGithub/hw4-gtest7.spl create mode 100644 FromGithub/hw4-gtest8.spl create mode 100644 FromGithub/hw4-gtest9.spl create mode 100644 FromGithub/hw4-gtestA.spl create mode 100644 FromGithub/hw4-gtestB.spl create mode 100644 FromGithub/hw4-gtestC.spl create mode 100644 FromGithub/hw4-gtestD.spl create mode 100644 FromGithub/hw4-gtestE.spl create mode 100644 FromGithub/hw4-gtestF.spl create mode 100644 FromGithub/hw4-gtestG.spl create mode 100644 FromGithub/hw4-gtestH.spl create mode 100644 FromGithub/hw4-gtestI.spl create mode 100644 FromGithub/hw4-gtestJ.spl create mode 100644 FromGithub/hw4-gtestK.spl create mode 100644 FromGithub/hw4-gtestL.spl create mode 100644 FromGithub/hw4-gtestM.spl create mode 100644 FromGithub/hw4-gtestN.spl create mode 100644 FromGithub/hw4-gtestO.spl create mode 100644 FromGithub/hw4-gtestP.spl create mode 100644 FromGithub/hw4-gtestQ.spl create mode 100644 FromGithub/hw4-gtestR.spl create mode 100644 FromGithub/hw4-gtestS.spl create mode 100644 FromGithub/hw4-gtestT.spl create mode 100644 FromGithub/hw4-read-test0.spl create mode 100644 FromGithub/hw4-read-test1.spl create mode 100644 FromGithub/hw4-vmtest0.spl create mode 100644 FromGithub/hw4-vmtest1.spl create mode 100644 FromGithub/hw4-vmtest2.spl create mode 100644 FromGithub/hw4-vmtest3.spl create mode 100644 FromGithub/hw4-vmtest4.spl create mode 100644 FromGithub/hw4-vmtest5.spl create mode 100644 FromGithub/hw4-vmtest6.spl create mode 100644 FromGithub/hw4-vmtest7.spl create mode 100644 FromGithub/hw4-vmtest8.spl create mode 100644 FromGithub/hw4-vmtest9.spl create mode 100644 FromGithub/hw4-vmtestA.spl create mode 100644 FromGithub/hw4-vmtestB.spl create mode 100644 FromGithub/hw4-vmtestC.spl create mode 100644 FromGithub/id_attrs.c create mode 100644 FromGithub/id_attrs.h create mode 100644 FromGithub/id_attrs.o create mode 100644 FromGithub/id_use.c create mode 100644 FromGithub/id_use.h create mode 100644 FromGithub/id_use.o create mode 100644 FromGithub/instruction.c create mode 100644 FromGithub/instruction.h create mode 100644 FromGithub/instruction.o create mode 100644 FromGithub/lexer.c create mode 100644 FromGithub/lexer.h create mode 100644 FromGithub/lexer_utilities.c create mode 100644 FromGithub/lexer_utilities.h create mode 100644 FromGithub/lexer_utilities.o create mode 100644 FromGithub/lexical_address.c create mode 100644 FromGithub/lexical_address.h create mode 100644 FromGithub/literal_table.c create mode 100644 FromGithub/literal_table.h create mode 100644 FromGithub/machine_types.c create mode 100644 FromGithub/machine_types.h create mode 100644 FromGithub/machine_types.o create mode 100644 FromGithub/parser.c create mode 100644 FromGithub/parser.h create mode 100644 FromGithub/parser.o create mode 100644 FromGithub/parser_types.h create mode 100644 FromGithub/regname.c create mode 100644 FromGithub/regname.h create mode 100644 FromGithub/regname.o create mode 100644 FromGithub/scope.c create mode 100644 FromGithub/scope.h create mode 100644 FromGithub/scope.o create mode 100644 FromGithub/scope_check.c create mode 100644 FromGithub/scope_check.h create mode 100644 FromGithub/scope_check.o create mode 100644 FromGithub/spl.output create mode 100644 FromGithub/spl.tab.c create mode 100644 FromGithub/spl.tab.h create mode 100644 FromGithub/spl.tab.o create mode 100644 FromGithub/spl.y create mode 100644 FromGithub/spl_lexer.c create mode 100644 FromGithub/spl_lexer.h create mode 100644 FromGithub/spl_lexer.l create mode 100644 FromGithub/spl_lexer.o create mode 100644 FromGithub/symtab.c create mode 100644 FromGithub/symtab.h create mode 100644 FromGithub/symtab.o create mode 100644 FromGithub/unparser.c create mode 100644 FromGithub/unparser.h create mode 100644 FromGithub/unparser.o create mode 100644 FromGithub/utilities.c create mode 100644 FromGithub/utilities.h create mode 100644 FromGithub/utilities.o diff --git a/FromGithub/Makefile b/FromGithub/Makefile new file mode 100644 index 0000000..3df0e37 --- /dev/null +++ b/FromGithub/Makefile @@ -0,0 +1,189 @@ +# $Id: Makefile,v 1.64 2024/11/13 21:32:03 leavens Exp leavens $ +# Makefile for SPL compiler and code generation in COP 3402 + +# Add .exe to the end of target to get that suffix in the rules +COMPILER = compiler +LEXER = ./compiler -l +UNPARSER = ./compiler -u +VM = vm +DISASM = $(VM)/disasm +RUNVM = $(VM)/$(VM) + +# Tools used +CC = gcc +# on Linux, the following can be used with gcc: +# CFLAGS = -fsanitize=address -static-libasan -g -std=c17 -Wall +CFLAGS = -g -std=c17 -Wall +YACC = bison +YACCFLAGS = -Wall --locations -d -v +LEX = flex +LEXFLAGS = +# Unix command names +MV = mv +RM = rm -f +SUBMISSIONZIPFILE = submission.zip +ZIP = zip -9 +SPL = spl +SUF = spl +# The GTESTS are a graduated series of tests, good to start with +GTESTS = hw4-gtest0.spl hw4-gtest1.spl hw4-gtest2.spl hw4-gtest3.spl \ + hw4-gtest5.spl hw4-gtest6.spl hw4-gtest7.spl hw4-gtest8.spl \ + hw4-gtest9.spl hw4-gtestA.spl hw4-gtestB.spl hw4-gtestC.spl \ + hw4-gtestD.spl hw4-gtestE.spl hw4-gtestF.spl hw4-gtestG.spl \ + hw4-gtestH.spl hw4-gtestI.spl hw4-gtestJ.spl hw4-gtestK.spl \ + hw4-gtestL.spl hw4-gtestM.spl hw4-gtestN.spl hw4-gtestO.spl \ + hw4-gtestP.spl hw4-gtestQ.spl hw4-gtestR.spl hw4-gtestS.spl \ + hw4-gtestT.spl +# The READTESTS need input from stdin +READTESTS = hw4-read-test0.spl hw4-read-test1.spl +# the VM tests are another set of tests that (somehwhat) increas in comlexity +VMTESTS = hw4-vmtest0.spl hw4-vmtest1.spl hw4-vmtest2.spl hw4-vmtest3.spl \ + hw4-vmtest4.spl hw4-vmtest5.spl hw4-vmtest6.spl hw4-vmtest7.spl \ + hw4-vmtest8.spl hw4-vmtest9.spl hw4-vmtestA.spl hw4-vmtestB.spl \ + hw4-vmtestC.spl +# you can add your own tests to alltests +ALLTESTS = $(GTESTS) $(READTESTS) $(VMTESTS) +EXPECTEDOUTPUTS = $(ALLTESTS:.spl=.out) +STUDENTTESTOUTPUTS = $(ALLTESTS:.spl=.myo) + +# The macro PROCEDURE_OBJECTS would be used for modules that +# implement procedures, which is not part of the homework +PROCEDURE_OBJECTS = +# Add the names of your own files with a .o suffix to link them in the program +# Feel free to edit the following definition of COMPILER_OBJECTS +COMPILER_OBJECTS = $(COMPILER)_main.o $(SPL)_lexer.o lexer_utilities.o \ + machine_types.o parser.o regname.o utilities.o \ + $(SPL).tab.o ast.o file_location.o unparser.o \ + scope.o scope_check.o symtab.o id_use.o id_attrs.o \ + instruction.o bof.o code.o code_seq.o code_utils.o \ + gen_code.o literal_table.o $(PROCEDURE_OBJECTS) +# Note that you will need to write gen_code.o and literal_table.o, +# but you can change those names if you wish. + +# create the VM executable +.PRECIOUS: $(VM)/$(VM) +$(VM): $(VM)/$(VM) + +$(SPL).tab.o: $(SPL).tab.c $(SPL).tab.h + $(CC) $(CFLAGS) -c $< + +$(SPL).tab.c $(SPL).tab.h: $(SPL).y ast.h parser_types.h machine_types.h + $(YACC) $(YACCFLAGS) $(SPL).y + +.PRECIOUS: $(SPL)_lexer.c +$(SPL)_lexer.c: $(SPL)_lexer.l $(SPL).tab.h + $(LEX) $(LEXFLAGS) $< + +$(SPL)_lexer.o: $(SPL)_lexer.c ast.h utilities.h file_location.h + $(CC) $(CFLAGS) -Wno-unused-function -Wno-unused-but-set-variable -c $(SPL)_lexer.c + +$(SPL)_lexer.l: $(SPL).tab.h + +ast.o: spl.tab.h + +# create the compiler executable +$(COMPILER): $(COMPILER_OBJECTS) + $(CC) $(CFLAGS) -o $(COMPILER) $(COMPILER_OBJECTS) + +$(COMPILER)_main.o: $(COMPILER)_main.c lexer.h parser.h unparser.h ast.h \ + utilities.h symtab.h scope_check.h + $(CC) $(CFLAGS) -c $< + +gen_code.o: gen_code.c spl.tab.h gen_code.h id_use.h literal_table.h \ + utilities.h regname.h + $(CC) $(CFLAGS) -c $< + +# rule for compiling individual .c files +%.o: %.c %.h + $(CC) $(CFLAGS) -c $< + +.PHONY: clean +clean: + $(RM) *~ *.o '#'* + $(RM) $(SPL)_lexer.c $(SPL)_lexer.h + $(RM) $(SPL).tab.c $(SPL).tab.h $(SPL).output + $(RM) $(COMPILER).exe $(COMPILER) + $(RM) *.stackdump core + $(RM) $(SUBMISSIONZIPFILE) + cd $(VM); $(MAKE) clean + +cleanall: clean + $(RM) *.myo *.myt *.bof *.asm + (cd $(VM); $(MAKE) cleanall) + +$(RUNVM): + (cd $(VM); $(MAKE) $(VM)) + +# The .myo files are outputs of VM when run on compiled programs. +# There is no tracing output by default for the .myo files, +# use .myt if you want tracing output. +# The pipe starting with "cat char-inputs.txt |" +# allows read statments to not hang +.PRECIOUS: %.myo +%.myo: %.bof $(RUNVM) + $(RM) $@; umask 022; \ + cat char-inputs.txt | ./$(RUNVM) $< > $@ 2>&1 + +# A .myt file is the output of running the VM with the -t option +# This can be useful for debugging. +.PRECIOUS: %.myt +%.myt: %.bof $(RUNVM) + $(RM) $@; umask 022; \ + cat char-inputs.txt | ./$(RUNVM) -t $< > $@ 2>&1 + +.PHONY: asm disasm +asm: $(ASM) +disasm: $(DISASM) + +$(ASM): + (cd $(VM); $(MAKE) asm) + +$(DISASM): + (cd $(VM); $(MAKE) disasm) + +# The .bof files are the compiled binary object files. +.PRECIOUS: %.bof +%.bof: %.$(SUF) $(COMPILER) + $(RM) $@; umask 022; \ + ./$(COMPILER) $< + +# The .upo files are unparsed programs; +# these are useful for debugging the parser and understanding the parse. +%.upo: %.$(SUF) $(COMPILER) + $(RM) $@; umask 022; \ + ./$(UNPARSER) $< > $@ 2>&1 + +# The .asm files are disassembled binary object files. +# These are useful for debugging the code the compiler creates. +%.asm: %.bof $(COMPILER) $(DISASM) + $(RM) $@; umask 022; \ + $(DISASM) $< > $@ 2>&1 + +# main target for testing +.PHONY: check-outputs +check-outputs: $(COMPILER) $(RUNVM) + @DIFFS=0; \ + for f in `echo $(ALLTESTS) | sed -e 's/\\.$(SUF)//g'`; \ + do \ + echo running ./$(COMPILER) on "$$f.$(SUF)"; \ + $(RM) "$$f.bof"; \ + ./$(COMPILER) "$$f.$(SUF)" ; \ + echo running $(RUNVM) on "$$f.bof"; \ + $(RM) "$$f.myo"; \ + cat char-inputs.txt | $(RUNVM) "$$f.bof" > "$$f.myo" 2>&1; \ + diff -w -B "$$f.out" "$$f.myo" && echo 'passed!' || DIFFS=1; \ + done; \ + if test 0 = $$DIFFS; \ + then \ + echo 'All output tests passed!'; \ + else \ + echo 'Some output test(s) failed!'; \ + fi + +$(SUBMISSIONZIPFILE): *.c *.h $(STUDENTTESTOUTPUTS) + $(ZIP) $(SUBMISSIONZIPFILE) $(SPL).y $(SPL)_lexer.l *.c *.h Makefile + $(ZIP) $(SUBMISSIONZIPFILE) $(STUDENTTESTOUTPUTS) $(ALLTESTS) $(EXPECTEDOUTPUTS) + $(ZIP) -r -9 $(SUBMISSIONZIPFILE) $(VM) -x 'vm/*.o' 'vm/*.exe' 'vm/RCS/' 'vm/RCS/*,v' + +.PHONY: compile-separately check-separately +compile-separately check-separately: $(COMPILER_OBJECTS) diff --git a/FromGithub/README.md b/FromGithub/README.md new file mode 100644 index 0000000..e83f438 --- /dev/null +++ b/FromGithub/README.md @@ -0,0 +1 @@ +# CodeGeneratorSPL \ No newline at end of file diff --git a/FromGithub/ast.c b/FromGithub/ast.c new file mode 100644 index 0000000..257077a --- /dev/null +++ b/FromGithub/ast.c @@ -0,0 +1,780 @@ +/* $Id: ast.c,v 1.15 2024/11/03 22:49:33 leavens Exp $ */ +#include +#include +#include +#include "utilities.h" +#include "ast.h" +#include "spl.tab.h" + +// Return the file location from an AST +file_location *ast_file_loc(AST t) { + return t.generic.file_loc; +} + +// Return the filename from the AST t +const char *ast_filename(AST t) { + return ast_file_loc(t)->filename; +} + +// Return the line number from the AST t +unsigned int ast_line(AST t) { + return ast_file_loc(t)->line; +} + +// Return the type tag of the AST t +AST_type ast_type_tag(AST t) { + return t.generic.type_tag; +} + +// Return a pointer to a fresh copy of t +// that has been allocated on the heap +AST *ast_heap_copy(AST t) { + AST *ret = (AST *)malloc(sizeof(AST)); + if (ret == NULL) { + bail_with_error("Cannot allocate an AST heap copy!"); + } + *ret = t; + return ret; +} + +// Return an AST for a block which contains the given ASTs. +block_t ast_block(token_t begin_tok, const_decls_t const_decls, + var_decls_t var_decls, proc_decls_t proc_decls, + stmts_t stmts) +{ + block_t ret; + ret.file_loc = file_location_copy(begin_tok.file_loc); + ret.type_tag = block_ast; + ret.const_decls = const_decls; + ret.var_decls = var_decls; + ret.proc_decls = proc_decls; + ret.stmts = stmts; + return ret; +} + +// Return an AST for an empty const decls +extern const_decls_t ast_const_decls_empty(empty_t empty) +{ + const_decls_t ret; + ret.file_loc = empty.file_loc; + ret.type_tag = const_decls_ast; + ret.start = NULL; + return ret; +} + +// Return an AST for the const decls +const_decls_t ast_const_decls(const_decls_t const_decls, + const_decl_t const_decl) +{ + const_decls_t ret = const_decls; + // make a copy of const_decl on the heap + const_decl_t *p = (const_decl_t *) malloc(sizeof(const_decl_t)); + if (p == NULL) { + bail_with_error("Cannot allocate space for %s!", "const_decl_t"); + } + *p = const_decl; + p->next = NULL; + const_decl_t *last = ast_last_list_elem(ret.start); + if (last == NULL) { + ret.start = p; + } else { + last->next = p; + } + return ret; +} + + + +// Return an AST for a const_decl +const_decl_t ast_const_decl(const_def_list_t const_def_list) +{ + const_decl_t ret; + ret.file_loc = const_def_list.file_loc; + ret.type_tag = const_decl_ast; + ret.const_def_list = const_def_list; + ret.next = NULL; + return ret; +} + +// Return an AST for const-def-list that is a singleton +extern const_def_list_t ast_const_def_list_singleton(const_def_t const_def) +{ + const_def_list_t ret; + ret.file_loc = const_def.file_loc; + ret.type_tag = const_def_list_ast; + const_def_t *p = (const_def_t *) malloc(sizeof(const_def_t)); + if (p == NULL) { + bail_with_error("Unable to allocate space for a %s!", "const_def_t"); + } + *p = const_def; + p->next = NULL; + ret.start = p; + return ret; +} + +// Return an AST for const_defs +extern const_def_list_t ast_const_def_list(const_def_list_t const_def_list, + const_def_t const_def) +{ + const_def_list_t ret = const_def_list; + // make a copy of const_def on the heap + const_def_t *p = (const_def_t *) malloc(sizeof(const_def_t)); + if (p == NULL) { + bail_with_error("Cannot allocate space for %s!", "const_def_t"); + } + *p = const_def; + p->next = NULL; + const_def_t *last = ast_last_list_elem(ret.start); + if (last == NULL) { + ret.start = p; + } else { + last->next = p; + } + return ret; +} + +// Return an AST for a const-def +const_def_t ast_const_def(ident_t ident, number_t number) +{ + const_def_t ret; + ret.file_loc = file_location_copy(ident.file_loc); + assert((ret.file_loc)->filename != NULL); + ret.type_tag = const_def_ast; + ret.next = NULL; + ret.ident = ident; + ret.number = number; + return ret; +} + + +// Return an AST for varDecls that are empty +var_decls_t ast_var_decls_empty(empty_t empty) +{ + var_decls_t ret; + ret.file_loc = empty.file_loc; + ret.type_tag = var_decls_ast; + ret.var_decls = NULL; + return ret; +} + +// Return an AST varDecls that have some var_decls +var_decls_t ast_var_decls(var_decls_t var_decls, var_decl_t var_decl) +{ + var_decls_t ret = var_decls; + // make a copy of var_decl on the heap + var_decl_t *p = (var_decl_t *) malloc(sizeof(var_decl_t)); + if (p == NULL) { + bail_with_error("Cannot allocate space for %s!", "var_decl_t"); + } + *p = var_decl; + p->next = NULL; + var_decl_t *last = ast_last_list_elem(ret.var_decls); + if (last == NULL) { + ret.var_decls = p; + } else { + last->next = p; + } + return ret; +} + +// Return an AST for a var_decl +var_decl_t ast_var_decl(ident_list_t ident_list) +{ + var_decl_t ret; + ret.file_loc = ident_list.file_loc; + ret.type_tag = var_decl_ast; + ret.next = NULL; + ret.ident_list = ident_list; + return ret; +} + +// Return an AST made for one ident +extern ident_list_t ast_ident_list_singleton(ident_t ident) +{ + ident_list_t ret; + ret.file_loc = ident.file_loc; + ret.type_tag = ident_list_ast; + // make a copy of ident on the heap + ident_t *p = (ident_t *) malloc(sizeof(ident_t)); + if (p == NULL) { + bail_with_error("Unable to allocate space for a %s!", "ident_t"); + } + *p = ident; + p->next = NULL; + ret.start = p; + return ret; +} + +// Return an AST made for idents +extern ident_list_t ast_ident_list(ident_list_t ident_list, ident_t ident) +{ + ident_list_t ret = ident_list; + // make a copy of ident on the heap + ident_t *p = (ident_t *) malloc(sizeof(ident_t)); + if (p == NULL) { + bail_with_error("Cannot allocate space for %s!", "ident_t"); + } + *p = ident; + p->next = NULL; + ident_t *last = ast_last_list_elem(ret.start); + if (last == NULL) { + ret.start = p; + } else { + last->next = p; + } + return ret; +} + +// Return an AST for proc_decls +proc_decls_t ast_proc_decls_empty(empty_t empty) +{ + proc_decls_t ret; + ret.file_loc = empty.file_loc; + ret.type_tag = proc_decls_ast; + ret.proc_decls = NULL; + return ret; +} + +// Return an AST for proc_decls +proc_decls_t ast_proc_decls(proc_decls_t proc_decls, + proc_decl_t proc_decl) +{ + proc_decls_t ret = proc_decls; + // make a copy of proc_decl on the heap + proc_decl_t *p = (proc_decl_t *) malloc(sizeof(proc_decl_t)); + if (p == NULL) { + bail_with_error("Unable to allocate space for a %s!", "proc_decl_t"); + } + *p = proc_decl; + p->next = NULL; + proc_decl_t *last = ast_last_list_elem(ret.proc_decls); + if (last == NULL) { + ret.proc_decls = p; + } else { + last->next = p; + } + return ret; +} + +// Return an AST for a proc_decl +proc_decl_t ast_proc_decl(ident_t ident, block_t block) +{ + proc_decl_t ret; + ret.file_loc = file_location_copy(ident.file_loc); + ret.type_tag = proc_decl_ast; + ret.next = NULL; + ret.name = ident.name; + block_t *p = (block_t *) malloc(sizeof(block_t)); + if (p == NULL) { + bail_with_error("Unable to allocate space for a %s!", "block_t"); + } + *p = block; + ret.block = p; + return ret; +} + +// Return an AST for a print statement +print_stmt_t ast_print_stmt(expr_t expr) { + print_stmt_t ret; + ret.file_loc = expr.file_loc; + ret.type_tag = print_stmt_ast; + ret.expr = expr; + return ret; +} + +// Return an AST for a read statement +read_stmt_t ast_read_stmt(ident_t ident) { + read_stmt_t ret; + ret.file_loc = file_location_copy(ident.file_loc); + ret.type_tag = read_stmt_ast; + ret.name = ident.name; + return ret; +} + +// Return an immediate data holding an address +while_stmt_t ast_while_stmt(condition_t condition, stmts_t body) { + while_stmt_t ret; + ret.file_loc = condition.file_loc; + ret.type_tag = while_stmt_ast; + ret.condition = condition; + stmts_t *p = (stmts_t *) malloc(sizeof(stmts_t)); + if (p == NULL) { + bail_with_error("Unable to allocate space for a %s!", "stmts_t"); + } + *p = body; + ret.body = p; + return ret; +} + +// Return an AST for an if-then-else statement +if_stmt_t ast_if_then_else_stmt(condition_t condition, + stmts_t then_stmts, stmts_t else_stmts) +{ + if_stmt_t ret; + ret.file_loc = condition.file_loc; + ret.type_tag = if_stmt_ast; + ret.condition = condition; + // copy then_stmt to the heap + stmts_t *p = (stmts_t *) malloc(sizeof(stmts_t)); + if (p == NULL) { + bail_with_error("Unable to allocate space for a %s!", "stmts_t"); + } + *p = then_stmts; + ret.then_stmts = p; + // copy else_stmts to the heap + p = (stmts_t *) malloc(sizeof(stmts_t)); + if (p == NULL) { + bail_with_error("Unable to allocate space for a %s!", "stmts_t"); + } + *p = else_stmts; + ret.else_stmts = p; + return ret; +} + +// Return an AST for a (short) if-then statement +// Note that the else part is a NULL pointer +extern if_stmt_t ast_if_then_stmt(condition_t condition, + stmts_t then_stmts) +{ + if_stmt_t ret; + ret.file_loc = condition.file_loc; + ret.type_tag = if_stmt_ast; + ret.condition = condition; + // copy then_stmt to the heap + stmts_t *p = (stmts_t *) malloc(sizeof(stmts_t)); + if (p == NULL) { + bail_with_error("Unable to allocate space for a %s!", "stmts_t"); + } + *p = then_stmts; + ret.then_stmts = p; + ret.else_stmts = NULL; + return ret; +} + +// Return an AST for a begin statement +// containing the given list of statements +block_stmt_t ast_block_stmt(block_t block) +{ + block_stmt_t ret; + ret.file_loc = block.file_loc; + ret.type_tag = block_stmt_ast; + // copy the block to the heap + block_t *p = (block_t *) malloc(sizeof(block_t)); + if (p == NULL) { + bail_with_error("Unable to allocate space for a %s!", "block_t"); + } + *p = block; + ret.block = p; + return ret; +} + +// Return an AST for a call statment + call_stmt_t ast_call_stmt(ident_t ident) +{ + call_stmt_t ret; + ret.file_loc = file_location_copy(ident.file_loc); + ret.type_tag = call_stmt_ast; + ret.name = ident.name; + return ret; +} + +// Return an AST for an assignment statement +assign_stmt_t ast_assign_stmt(ident_t ident, expr_t expr) +{ + assign_stmt_t ret; + ret.file_loc = file_location_copy(ident.file_loc); + ret.type_tag = assign_stmt_ast; + ret.name = ident.name; + assert(ret.name != NULL); + expr_t *p = (expr_t *) malloc(sizeof(expr_t)); + if (p == NULL) { + bail_with_error("Unable to allocate space for a %s!", "expr_t"); + } + *p = expr; + ret.expr = p; + assert(ret.expr != NULL); + return ret; +} + +// Return an AST for the list of statements +stmts_t ast_stmts_empty(empty_t empty) +{ + stmts_t ret; + ret.file_loc = file_location_copy(empty.file_loc); + ret.type_tag = stmts_ast; + ret.stmts_kind = empty_stmts_e; + return ret; +} + +// Return an AST for empty found in the given file location +empty_t ast_empty(file_location *file_loc) +{ + empty_t ret; + ret.file_loc = file_loc; + ret.type_tag = empty_ast; + return ret; +} + +// Return an AST for the list of statements +stmts_t ast_stmts(stmt_list_t stmt_list) +{ + stmts_t ret; + ret.file_loc = stmt_list.file_loc; + ret.type_tag = stmts_ast; + ret.stmts_kind = stmt_list_e; + ret.stmt_list = stmt_list; + return ret; +} + + +// Return an AST for the list of statements +stmt_list_t ast_stmt_list_singleton(stmt_t stmt) { + // debug_print("Entering ast_stmts_singleton\n"); + stmt_list_t ret; + ret.file_loc = stmt.file_loc; + ret.type_tag = stmt_list_ast; + stmt.next = NULL; + // copy stmt to the heap + stmt_t *p = (stmt_t *) malloc(sizeof(stmt_t)); + if (p == NULL) { + bail_with_error("Unable to allocate space for a %s!", "stmt_t"); + } + *p = stmt; + p->next = NULL; + // there will be no statments after stmt in the list + ret.start = p; + return ret; +} + +// Return an AST for the list of statements +extern stmt_list_t ast_stmt_list(stmt_list_t stmt_list, stmt_t stmt) { + // debug_print("Entering ast_stmt_list...\n"); + stmt_list_t ret = stmt_list; + // copy stmt to the heap + stmt_t *s = (stmt_t *) malloc(sizeof(stmt_t)); + if (s == NULL) { + bail_with_error("Cannot allocate space for %s!", "stmt_t"); + } + *s = stmt; + s->next = NULL; + stmt_t *last = ast_last_list_elem(ret.start); + assert(last != NULL); // because there are no empty lists of stmts + last->next = s; + return ret; +} + +// Return an AST for the given statment +stmt_t ast_stmt_assign(assign_stmt_t s) +{ + stmt_t ret; + ret.file_loc = s.file_loc; + ret.type_tag = stmt_ast; + ret.next = NULL; + ret.stmt_kind = assign_stmt; + ret.data.assign_stmt = s; + return ret; +} + +// Return an AST for the given statment +stmt_t ast_stmt_call(call_stmt_t s) +{ + stmt_t ret; + ret.file_loc = s.file_loc; + ret.type_tag = stmt_ast; + ret.next = NULL; + ret.stmt_kind = call_stmt; + ret.data.call_stmt = s; + return ret; +} + +// Return an AST for the given statment +stmt_t ast_stmt_block(block_stmt_t s) +{ + stmt_t ret; + ret.file_loc = s.file_loc; + ret.type_tag = stmt_ast; + ret.next = NULL; + ret.stmt_kind = block_stmt; + ret.data.block_stmt = s; + return ret; +} + +// Return an AST for the given statment +stmt_t ast_stmt_if(if_stmt_t s) +{ + stmt_t ret; + ret.file_loc = s.file_loc; + ret.type_tag = stmt_ast; + ret.next = NULL; + ret.stmt_kind = if_stmt; + ret.data.if_stmt = s; + return ret; +} + +// Return an AST for the given statment +stmt_t ast_stmt_while(while_stmt_t s) +{ + stmt_t ret; + ret.file_loc = s.file_loc; + ret.type_tag = stmt_ast; + ret.next = NULL; + ret.stmt_kind = while_stmt; + ret.data.while_stmt = s; + return ret; +} + +// Return an AST for the given statment +stmt_t ast_stmt_read(read_stmt_t s) +{ + stmt_t ret; + ret.file_loc = s.file_loc; + ret.type_tag = stmt_ast; + ret.next = NULL; + ret.stmt_kind = read_stmt; + ret.data.read_stmt = s; + return ret; +} + +// Return an AST for the given statment +stmt_t ast_stmt_print(print_stmt_t s) +{ + // debug_print("Entering ast_stmt_print...\n"); + stmt_t ret; + ret.file_loc = s.file_loc; + ret.type_tag = stmt_ast; + ret.next = NULL; + ret.stmt_kind = print_stmt; + ret.data.print_stmt = s; + return ret; +} + +// Return an AST for an odd condition +db_condition_t ast_db_condition(expr_t dividend, expr_t divisor) +{ + db_condition_t ret; + ret.file_loc = dividend.file_loc; + ret.type_tag = db_condition_ast; + ret.dividend = dividend; + ret.divisor = divisor; + return ret; +} + +// Return an AST for an initializer with the given value +rel_op_condition_t ast_rel_op_condition(expr_t expr1, token_t rel_op, + expr_t expr2) +{ + rel_op_condition_t ret; + ret.file_loc = expr1.file_loc; + ret.type_tag = rel_op_condition_ast; + ret.expr1 = expr1; + ret.rel_op = rel_op; + ret.expr2 = expr2; + return ret; +} + +// Return an AST for an odd condition +condition_t ast_condition_db(db_condition_t db_cond) +{ + condition_t ret; + ret.file_loc = db_cond.file_loc; + ret.type_tag = db_condition_ast; + ret.cond_kind = ck_db; + ret.data.db_cond = db_cond; + return ret; +} + +// Return an AST for a relational condition +condition_t ast_condition_rel_op(rel_op_condition_t rel_op_cond) +{ + condition_t ret; + ret.file_loc = rel_op_cond.file_loc; + ret.type_tag = condition_ast; + ret.cond_kind = ck_rel; + ret.data.rel_op_cond = rel_op_cond; + return ret; +} + +// Return an AST for an odd condition +binary_op_expr_t ast_binary_op_expr(expr_t expr1, token_t arith_op, + expr_t expr2) +{ + binary_op_expr_t ret; + ret.file_loc = expr1.file_loc; + ret.type_tag = binary_op_expr_ast; + + expr_t *p = (expr_t *) malloc(sizeof(expr_t)); + if (p == NULL) { + bail_with_error("Unable to allocate space for a %s!", "expr_t"); + } + *p = expr1; + ret.expr1 = p; + + ret.arith_op = arith_op; + + p = (expr_t *) malloc(sizeof(expr_t)); + if (p == NULL) { + bail_with_error("Unable to allocate space for a %s!", "expr_t"); + } + *p = expr2; + ret.expr2 = p; + + return ret; +} + +// Return an expression AST for a binary operation expresion +expr_t ast_expr_binary_op(binary_op_expr_t e) +{ + expr_t ret; + ret.file_loc = e.file_loc; + ret.type_tag = expr_ast; + ret.expr_kind = expr_bin; + ret.data.binary = e; + return ret; +} + +// Return an expression AST for a signed expression +expr_t ast_expr_signed_expr(token_t sign, expr_t e) +{ + expr_t ret; + ret.file_loc = file_location_copy(sign.file_loc); + ret.type_tag = expr_ast; + switch (sign.code) { + case minussym: + ret.expr_kind = expr_negated; + negated_expr_t ne; + ne.file_loc = ret.file_loc; + ne.type_tag = negated_expr_ast; + ne.expr = (expr_t *)ast_heap_copy((AST)e); + ret.data.negated = ne; + break; + case plussym: + // don't make any changes, use e as the result + return e; + break; + default: + bail_with_error("Unexpected sign token in ast_expr_signed_expr: %d", + sign.code); + break; + } + return ret; +} + +// Return an expression AST for an signed number +expr_t ast_expr_pos_number(token_t sign, number_t number) +{ + expr_t ret; + ret.file_loc = file_location_copy(sign.file_loc); + ret.type_tag = expr_ast; + ret.expr_kind = expr_number; + ret.data.number = number; + return ret; +} + +// Return an AST for the given token +token_t ast_token(file_location *file_loc, const char *text, int code) +{ + token_t ret; + ret.file_loc = file_loc; + ret.type_tag = token_ast; + ret.text = text; + ret.code = code; + return ret; +} + +// Return an AST for a (signed) number with the given value +number_t ast_number(token_t sgn, word_type value) +{ + number_t ret; + ret.file_loc = file_location_copy(sgn.file_loc); + ret.type_tag = number_ast; + ret.value = value; + return ret; +} + +// Return an AST for an identifier +ident_t ast_ident(file_location *file_loc, const char *name) +{ + ident_t ret; + ret.file_loc = file_loc; + ret.type_tag = ident_ast; + ret.name = name; + return ret; +} + +// Return an AST for an expression that's a binary expression +expr_t ast_expr_binary_op_expr(binary_op_expr_t e) +{ + expr_t ret; + ret.file_loc = e.file_loc; + ret.type_tag = binary_op_expr_ast; + ret.expr_kind = expr_bin; + ret.data.binary = e; + return ret; +} + +// Return an AST for an expression that's an identifier +expr_t ast_expr_ident(ident_t e) +{ + expr_t ret; + ret.file_loc = e.file_loc; + ret.type_tag = expr_ast; + ret.expr_kind = expr_ident; + ret.data.ident = e; + return ret; +} + +// Return an AST for an expression that's a number +expr_t ast_expr_number(number_t e) +{ + expr_t ret; + ret.file_loc = e.file_loc; + ret.type_tag = expr_ast; + ret.expr_kind = expr_number; + ret.data.number = e; + return ret; +} + +// Requires: lst is a pointer to a non-circular +// linked list with next pointers +// as in generic_t +// Return a pointer to the last element in lst. +// This only returns NULL if lst == NULL. +void *ast_last_list_elem(void *lst) +{ + // debug_print("Entering ast_last_list_elem\n"); + if (lst == NULL) { + return lst; + } + // assert(lst != NULL); + void *prev = NULL; + while (lst != NULL) { + prev = lst; + lst = ((generic_t *)lst)->next; + } + // here lst == NULL; + return prev; +} + +// Requires: lst is a pointer to a non-circular +// linked list with next pointers +// as in generic_t +// Return the number of elements in the linked list lst +int ast_list_length(void *lst) +{ + int ret = 0; + generic_t *p = (generic_t *) lst; + while (p != NULL) { + p = p->next; + ret++; + } + return ret; +} + +// Requires: lst is a pointer to a non-circular +// linked list with next pointers +// as in generic_t +// Is lst empty? +bool ast_list_is_empty(void *lst) +{ + return lst == NULL; +} diff --git a/FromGithub/ast.h b/FromGithub/ast.h new file mode 100644 index 0000000..ac0deba --- /dev/null +++ b/FromGithub/ast.h @@ -0,0 +1,537 @@ +/* $Id: ast.h,v 1.18 2024/11/03 22:49:33 leavens Exp $ */ +#ifndef _AST_H +#define _AST_H +#include +#include "machine_types.h" +#include "file_location.h" +#include "id_use.h" + +// types of ASTs (type tags) +typedef enum { + block_ast, const_decls_ast, const_decl_ast, + const_def_list_ast, const_def_ast, + var_decls_ast, var_decl_ast, ident_list_ast, + proc_decls_ast, proc_decl_ast, + stmts_ast, empty_ast, stmt_list_ast, stmt_ast, + assign_stmt_ast, call_stmt_ast, if_stmt_ast, while_stmt_ast, + read_stmt_ast, print_stmt_ast, block_stmt_ast, + condition_ast, db_condition_ast, rel_op_condition_ast, + expr_ast, binary_op_expr_ast, negated_expr_ast, ident_ast, number_ast, + token_ast +} AST_type; + +// The following types for structs named N_t +// are returned by the parser. +// The struct N_t is the type of information kept in the AST +// that is related to the nonterminal N in the abstract syntax. + +// The generic struct type (generic_t) has the fields that +// should be in all alternatives for ASTs. +typedef struct { + file_location *file_loc; + AST_type type_tag; // says what field of the union is active + void *next; // for lists +} generic_t; + +// empty ::= +typedef struct { + file_location *file_loc; + AST_type type_tag; +} empty_t; + +// identifiers +typedef struct ident_s { + file_location *file_loc; + AST_type type_tag; + struct ident_s *next; // for lists this is a part of + const char *name; + id_use *idu; +} ident_t; + +// (possibly signed) numbers +typedef struct { + file_location *file_loc; + AST_type type_tag; + const char *text; + word_type value; +} number_t; + +// tokens as ASTs +typedef struct { + file_location *file_loc; + AST_type type_tag; + const char *text; + int code; +} token_t; + +// kinds of expressions +typedef enum { expr_bin, expr_negated, expr_ident, expr_number } expr_kind_e; + +// forward declaration for the expr type +struct expr_s; + +// expr ::= expr arithOp expr +// arithOp ::= + | - | * | / +typedef struct { + file_location *file_loc; + AST_type type_tag; + struct expr_s *expr1; + token_t arith_op; + struct expr_s *expr2; +} binary_op_expr_t; + +// expr ::= - expr +typedef struct { + file_location *file_loc; + AST_type type_tag; + struct expr_s *expr; +} negated_expr_t; + +// expr ::= expr arithOp expr | ident | number +typedef struct expr_s { + file_location *file_loc; + AST_type type_tag; + expr_kind_e expr_kind; + union { + binary_op_expr_t binary; + negated_expr_t negated; + ident_t ident; + number_t number; + } data; +} expr_t; + +// kinds of conditions +typedef enum { ck_db, ck_rel } condition_kind_e; + +typedef struct { + file_location *file_loc; + AST_type type_tag; + expr_t dividend; + expr_t divisor; +} db_condition_t; + +typedef struct { + file_location *file_loc; + AST_type type_tag; + expr_t expr1; + token_t rel_op; + expr_t expr2; +} rel_op_condition_t; + +// condition ::= divisible expr expr | expr relOp expr +typedef struct { + file_location *file_loc; + AST_type type_tag; + condition_kind_e cond_kind; + union cond_u { + db_condition_t db_cond; + rel_op_condition_t rel_op_cond; + } data; +} condition_t; + +// kinds of statements +typedef enum { assign_stmt, call_stmt, if_stmt, while_stmt, + read_stmt, print_stmt, block_stmt } stmt_kind_e; + +// forward declaration of statement type +struct stmt_s; + +// stmt-list ::= stmt | stmt-list stmt +typedef struct { + file_location *file_loc; + AST_type type_tag; + struct stmt_s *start; +} stmt_list_t; + +typedef enum { empty_stmts_e, stmt_list_e } stmts_kind_e; + +// stmts ::= { stmts } +typedef struct { + file_location *file_loc; + AST_type type_tag; + stmts_kind_e stmts_kind; + stmt_list_t stmt_list; // when stmts_kind != empty_stmts_e +} stmts_t; + +// stmt ::= ident := expr +typedef struct { + file_location *file_loc; + AST_type type_tag; + const char *name; + struct expr_s *expr; + id_use *idu; +} assign_stmt_t; + +// stmt ::= call ident +typedef struct { + file_location *file_loc; + AST_type type_tag; + const char *name; + id_use *idu; +} call_stmt_t; + +// forward declaration for block type +struct block_s; + +// block-stmt ::= block +typedef struct block_stmt_s { + file_location *file_loc; + AST_type type_tag; + struct block_s *block; +} block_stmt_t; + +// if-stmt ::= if condition stmts stmts | if condition stmts +typedef struct { + file_location *file_loc; + AST_type type_tag; + condition_t condition; + stmts_t *then_stmts; + stmts_t *else_stmts; +} if_stmt_t; + +// stmt ::= while condition stmt +typedef struct { + file_location *file_loc; + AST_type type_tag; + condition_t condition; + stmts_t *body; +} while_stmt_t; + +// stmt ::= read ident +typedef struct { + file_location *file_loc; + AST_type type_tag; + const char *name; + id_use *idu; +} read_stmt_t; + +// stmt ::= print expr +typedef struct { + file_location *file_loc; + AST_type type_tag; + expr_t expr; +} print_stmt_t; + +// stmt ::= assign-stmt | call-stmt | if-stmt +// | while-stmt | read-stmt | print-stmt | block-stmt +typedef struct stmt_s { + file_location *file_loc; + AST_type type_tag; + struct stmt_s *next; // for lists this is a part of + stmt_kind_e stmt_kind; + union { + assign_stmt_t assign_stmt; + call_stmt_t call_stmt; + if_stmt_t if_stmt; + while_stmt_t while_stmt; + read_stmt_t read_stmt; + print_stmt_t print_stmt; + block_stmt_t block_stmt; + } data; +} stmt_t; + +// procDecl ::= proc ident block +typedef struct proc_decl_s { + file_location *file_loc; + AST_type type_tag; + struct proc_decl_s *next; // for lists + const char *name; + struct block_s *block; +} proc_decl_t; + +// proc-decls ::= { proc-decl } +typedef struct { + file_location *file_loc; + AST_type type_tag; + proc_decl_t *proc_decls; +} proc_decls_t; + +// ident-list ::= ident | ident-list ident +typedef struct { + file_location *file_loc; + AST_type type_tag; + ident_t *start; +} ident_list_t; + +// var-decl ::= var ident-list +typedef struct var_decl_s { + file_location *file_loc; + AST_type type_tag; + struct var_decl_s *next; // for lists this is a part of + ident_list_t ident_list; +} var_decl_t; + +// var-decls ::= { var-decl } +typedef struct { + file_location *file_loc; + AST_type type_tag; + var_decl_t *var_decls; +} var_decls_t; + +// const-def ::= ident number +typedef struct const_def_s { + file_location *file_loc; + AST_type type_tag; + struct const_def_s *next; // for lists this is a part of + ident_t ident; + number_t number; +} const_def_t; + +// const-def-list ::= { const-def } +typedef struct { + file_location *file_loc; + AST_type type_tag; + const_def_t *start; +} const_def_list_t; + +// const-decl ::= const const-def-list +typedef struct const_decl_s { + file_location *file_loc; + AST_type type_tag; + struct const_decl_s *next; // for lists this is a part of + const_def_list_t const_def_list; +} const_decl_t; + +// const-decls ::= { const-decl } +typedef struct { + file_location *file_loc; + AST_type type_tag; + const_decl_t *start; +} const_decls_t; + +// block ::= begin const-decls var-decls proc-decls stmts +typedef struct block_s { + file_location *file_loc; + AST_type type_tag; + const_decls_t const_decls; + var_decls_t var_decls; + proc_decls_t proc_decls; + stmts_t stmts; +} block_t; + +// program ::= block + +// The AST definition used by bison +typedef union AST_u { + generic_t generic; + block_t block; + const_decls_t const_decls; + const_decl_t const_decl; + const_def_list_t const_def_list; + const_def_t const_def; + var_decls_t var_decls; + var_decl_t var_decl; + ident_list_t ident_list; + proc_decls_t proc_decls; + proc_decl_t proc_decl; + stmts_t stmts; + stmt_list_t stmt_list; + stmt_t stmt; + assign_stmt_t assign_stmt; + call_stmt_t call_stmt; + if_stmt_t if_stmt; + while_stmt_t while_stmt; + read_stmt_t read_stmt; + print_stmt_t print_stmt; + block_stmt_t block_stmt; + condition_t condition; + rel_op_condition_t rel_op_condition; + db_condition_t db_condition; + expr_t expr; + binary_op_expr_t binary_op_expr; + token_t token; + number_t number; + ident_t ident; + empty_t empty; +} AST; + +// Return the file location from an AST +extern file_location *ast_file_loc(AST t); + +// Return the filename from the AST t +extern const char *ast_filename(AST t); + +// Return the line number from the AST t +extern unsigned int ast_line(AST t); + +// Return the type tag of the AST t +extern AST_type ast_type_tag(AST t); + +// Return a pointer to a fresh copy of t +// that has been allocated on the heap +extern AST *ast_heap_copy(AST t); + +// Return an AST for a block which contains the given ASTs. +extern block_t ast_block(token_t begin_tok, const_decls_t const_decls, var_decls_t var_decls, proc_decls_t proc_decls, stmts_t stmts); + +// Return an AST for an empty const decls +extern const_decls_t ast_const_decls_empty(empty_t empty); + +// Return an AST for the const decls +extern const_decls_t ast_const_decls(const_decls_t const_decls, + const_decl_t const_decl); + +// Return an AST for a const_decl +extern const_decl_t ast_const_decl(const_def_list_t const_def_list); + +// Return an AST for const_def_list +extern const_def_list_t ast_const_def_list_singleton(const_def_t const_def); + +// Return an AST for adding to a const_def_list +extern const_def_list_t ast_const_def_list(const_def_list_t const_def_list, + const_def_t const_def); + +// Return an AST for a const-def +extern const_def_t ast_const_def(ident_t ident, number_t number); + +// Return an AST for varDecls that are empty +extern var_decls_t ast_var_decls_empty(empty_t empty); + +// Return an AST varDecls that have some var_decls +extern var_decls_t ast_var_decls(var_decls_t var_decls, var_decl_t var_decl); + +// Return an AST for a var_decl +extern var_decl_t ast_var_decl(ident_list_t ident_list); + +// Return an AST made for one ident +extern ident_list_t ast_ident_list_singleton(ident_t ident); + +// Return an AST made for ident lists +extern ident_list_t ast_ident_list(ident_list_t ident_list, ident_t ident); + +// Return an AST for proc_decls +extern proc_decls_t ast_proc_decls_empty(empty_t empty); + +// Return an AST for proc_decls +extern proc_decls_t ast_proc_decls(proc_decls_t proc_decls, + proc_decl_t proc_decl); + +// Return an AST for a proc_decl +extern proc_decl_t ast_proc_decl(ident_t ident, block_t block); + + +// Return an AST for the list of statements +extern stmts_t ast_stmts_empty(empty_t empty); + +// Return an AST for empty found in the given file location +extern empty_t ast_empty(file_location *file_loc); + +// Return an AST for the list of statements +extern stmts_t ast_stmts(stmt_list_t stmt_list); + +// Return an AST for a list of statements that has stmt as a member +extern stmt_list_t ast_stmt_list_singleton(stmt_t stmt); + +// Return an AST for the list of statements +extern stmt_list_t ast_stmt_list(stmt_list_t stmt_list, stmt_t stmt); + +// Return an AST for the given statement as a more general stmt AST +extern stmt_t ast_stmt_assign(assign_stmt_t s); + +// Return an AST for the given statement as a more general stmt AST +extern stmt_t ast_stmt_call(call_stmt_t s); + +// Return an AST for the given statement as a more general stmt AST +extern stmt_t ast_stmt_block(block_stmt_t s); + +// Return an AST for the given statement as a more general stmt AST +extern stmt_t ast_stmt_if(if_stmt_t s); + +// Return an AST for the given statement as a more general stmt AST +extern stmt_t ast_stmt_while(while_stmt_t s); + +// Return an AST for the given statement as a more general stmt AST +extern stmt_t ast_stmt_read(read_stmt_t s); + +// Return an AST for the given statement as a more general stmt AST +extern stmt_t ast_stmt_print(print_stmt_t s); + +// Return an AST for an assignment statement +extern assign_stmt_t ast_assign_stmt(ident_t ident, expr_t expr); + +// Return an AST for a call statement +extern call_stmt_t ast_call_stmt(ident_t ident); + +// Return an AST for an if-then-else statement +extern if_stmt_t ast_if_then_else_stmt(condition_t condition, + stmts_t then_stmts, stmts_t else_stmts); + +// Return an AST for a (short) if-then statement +// Note that the else part is a NULL pointer +extern if_stmt_t ast_if_then_stmt(condition_t condition, + stmts_t then_stmts); + +// Return an AST for a while statement +extern while_stmt_t ast_while_stmt(condition_t condition, stmts_t body); + +// Return an AST for a read statement +extern read_stmt_t ast_read_stmt(ident_t ident); + +// Return an AST for a print statement +extern print_stmt_t ast_print_stmt(expr_t expr); + +// Return an AST for a block statement +extern block_stmt_t ast_block_stmt(block_t block); + + +// Return an AST for an odd condition +extern db_condition_t ast_db_condition(expr_t dividend, expr_t divisor); + +// Return an AST for an initializer with the given value +extern rel_op_condition_t ast_rel_op_condition(expr_t expr1, token_t rel_op, + expr_t expr2); + +// Return an AST for an odd condition +extern condition_t ast_condition_db(db_condition_t db_cond); + +// Return an AST for a relational condition +extern condition_t ast_condition_rel_op(rel_op_condition_t rel_op_cond); + + +// Return an expression AST for a binary operation expresion +extern expr_t ast_expr_binary_op(binary_op_expr_t e1); + +// Return an expression AST for an identifier +extern expr_t ast_expr_ident(ident_t e); + +// Return an AST for an expression that's a number +extern expr_t ast_expr_number(number_t e); + +// Return an AST for a binary op expression +extern binary_op_expr_t ast_binary_op_expr(expr_t expr1, token_t arith_op, + expr_t expr2); + +// Return an expression AST for a signed expression +extern expr_t ast_expr_signed_expr(token_t sign, expr_t expr); + +// The following are made by the lexer... + +// Return an AST for the given token +extern token_t ast_token(file_location *file_loc, const char *text, int code); + +// Return an AST for an identifier +// found in the file named fn, on line ln, with the given name. +extern ident_t ast_ident(file_location *file_loc, const char *name); + +// Some operations on AST lists + +// Requires: lst is a pointer to a non-circular +// linked list with next pointers +// as in generic_t +// Return a pointer to the last element in lst. +// This only returns NULL if lst == NULL. +extern void *ast_last_list_elem(void *lst); + +// Requires: lst is a pointer to a non-circular +// linked list with next pointers +// as in generic_t +// Return the number of elements in the linked list lst +extern int ast_list_length(void *lst); + +// Requires: lst is a pointer to a non-circular +// linked list with next pointers +// as in generic_t +// Is lst empty? +extern bool ast_list_is_empty(void *lst); + +#endif diff --git a/FromGithub/ast.o b/FromGithub/ast.o new file mode 100644 index 0000000000000000000000000000000000000000..ea5da78446368e0d7da89124980f699e568a6413 GIT binary patch literal 53040 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 literal 0 HcmV?d00001 diff --git a/FromGithub/bof.c b/FromGithub/bof.c new file mode 100644 index 0000000..598aaac --- /dev/null +++ b/FromGithub/bof.c @@ -0,0 +1,193 @@ +/* $Id: bof.c,v 1.2 2024/10/23 13:38:20 leavens Exp $ */ +// #include +#include +// #include +#include +#include +#include +#include "bof.h" +#include "utilities.h" + +#define MAGIC "BO32" + +// a type for treating bytes as a word +typedef union { + unsigned char buf[BYTES_PER_WORD]; + word_type w; +} word_pun_t; + +// Open filename for reading as a binary file +// Exit the program with an error if this fails, +// otherwise return the BOFFILE struct for the file +BOFFILE bof_read_open(const char *filename) { + BOFFILE bf; + bf.fileptr = fopen(filename, "rb"); + bf.filename = filename; + + if (bf.fileptr == NULL) { + bail_with_error("Error opening file for reading: %s", filename); + } + + return bf; +} + +// Return the size (in bytes) of bf +size_t bof_file_bytes(BOFFILE bf) +{ + struct stat st; + if (stat(bf.filename, &st) < 0) { + bail_with_error("Cannot stat %s to get its size!", bf.filename); + } + ; + return st.st_size; +} + +// Return true just when bf is at its end, false otherwise +bool bof_at_eof(BOFFILE bf) { + return feof(bf.fileptr); +} + +// Requires: bf is open for reading in binary and has +// at least BYTES_PER_WORD bytes in it +// Return the next word from bf +word_type bof_read_word(BOFFILE bf) +{ + word_pun_t b; + assert(!bof_at_eof(bf)); + size_t bytes_read = bof_read_bytes(bf, BYTES_PER_WORD, b.buf); + if (bytes_read == 0) { + bail_with_error( + "Cannot read a word from %s (got %d bytes), at EOF: %d", + bf.filename, bytes_read, bof_at_eof(bf)); + } + return b.w; +} + +// Requires: bf.fileptr is open for reading in binary +// and buf is of size at least bytes +// Read the given number of bytes into buf and return the number of bytes read +size_t bof_read_bytes(BOFFILE bf, size_t bytes, void *buf) { + int elems_read = fread(buf, bytes, 1, bf.fileptr); + return elems_read; +} + +// Requires: bf is open for reading in binary +// Read the header of bf as a BOFHeader and return that header +// If any errors are encountered, exit with an error message. +BOFHeader bof_read_header(BOFFILE bf) { + BOFHeader ret; + size_t rd = fread(&ret, sizeof(ret), 1, bf.fileptr); + if (rd != 1) { + bail_with_error("Cannot read header from %s", bf.filename); + } + if (!bof_has_correct_magic_number(ret)) { + bail_with_error("Wrong magic number code in file '%s'!", + bf.filename); + } + return ret; + /* + bof_read_bytes(bf, MAGIC_BUFFER_SIZE, &ret.magic); + if (strncmp(ret.magic, MAGIC, MAGIC_BUFFER_SIZE) != 0) { + bail_with_error("File %s is not a BOF format file, bad magic number!", + bf.filename); + } + bof_read_bytes(bf, BYTES_PER_WORD, &ret.text_start_address); + bof_read_bytes(bf, BYTES_PER_WORD, &ret.text_length); + bof_read_bytes(bf, BYTES_PER_WORD, &ret.data_start_address); + bof_read_bytes(bf, BYTES_PER_WORD, &ret.data_length); + bof_read_bytes(bf, BYTES_PER_WORD, &ret.stack_bottom_addr); + return ret; + */ +} + +// Requires: f is open for writing +// Write the magic number in hexadecimal notation on f, followed by a newline; +// Note: this is just for help in writing the documentation +/* +void bof_write_magic(FILE *f) { + fprintf(f, "%s", "0x"); + for (int i = 0; i < MAGIC_BUFFER_SIZE; i++) { + fprintf(f, "%x", MAGIC[i]); + } + fprintf(f, "\n"); +} +*/ + +// Open filename for writing as a binary file +// Exit the program with an error if this fails, +// otherwise return the BOFFILE for it. +BOFFILE bof_write_open(const char *filename) { + BOFFILE bf; + bf.fileptr = fopen(filename, "wb"); + bf.filename = filename; + + if (bf.fileptr == NULL) { + bail_with_error("Error opening file for writing: %s", filename); + } + + return bf; +} + +// Requres: bf is open +// Close the given binary file +// Exit the program with an error if this fails. +void bof_close(BOFFILE bf) +{ + if (fclose(bf.fileptr) != 0) { + bail_with_error("Could not close %s", bf.filename); + } +} + + +// Requires: bf is open for writing in binary. +// Write the given word into bf +// Exit the program with an error if this fails. +extern void bof_write_word(BOFFILE bf, word_type w) +{ + word_pun_t b; + b.w = w; + bof_write_bytes(bf, BYTES_PER_WORD, b.buf); +} + +// Requires: bf is open for writing in binary +// and the size of buf is at least bytes +// Write the given number of bytes from buf into f. +// Exit the program with an error if this fails. +void bof_write_bytes(BOFFILE bf, size_t bytes, + const void *buf) { + size_t wr = fwrite(buf, bytes, 1, bf.fileptr); + if (wr != 1) { + bail_with_error("Cannot write %u bytes to %s", bytes, bf.filename); + } +} + +// Requires: bf is open for writing in binary +// Write the given header to f +// Exit the program with an error if this fails. +void bof_write_header(BOFFILE bf, const BOFHeader hdr) { + size_t wr = fwrite(&hdr, sizeof(BOFHeader), 1, bf.fileptr); + if (wr != 1) { + bail_with_error("Canot write header to %s", bf.filename); + } +} + +// Write the (bits of the) magic number into the header bh. +void bof_write_magic_to_header(BOFHeader *bh) +{ + const char *magic = MAGIC; + for (int i = 0; i < MAGIC_BUFFER_SIZE; i++) { + bh->magic[i] = magic[i]; + } + assert(bof_has_correct_magic_number(*bh)); +} + +// Does the given header have the appropriate magic number? +bool bof_has_correct_magic_number(BOFHeader bh) +{ + char buf[MAGIC_BUFFER_SIZE+1]; + for (int i = 0; i < MAGIC_BUFFER_SIZE; i++) { + buf[i] = bh.magic[i]; + } + buf[MAGIC_BUFFER_SIZE] = '\0'; + return (0 == strncmp(buf, MAGIC, MAGIC_BUFFER_SIZE)); +} diff --git a/FromGithub/bof.h b/FromGithub/bof.h new file mode 100644 index 0000000..7041917 --- /dev/null +++ b/FromGithub/bof.h @@ -0,0 +1,88 @@ +/* $Id: bof.h,v 1.2 2024/10/23 13:38:20 leavens Exp $ */ +// Binary Object File Format (for the SSM) +#ifndef _BOF_H +#define _BOF_H +#include +#include +#include +#include "machine_types.h" + +#define MAGIC_BUFFER_SIZE 4 + +typedef struct { // Field magic should hold value of MAGIC (with no null char) + char magic[MAGIC_BUFFER_SIZE]; + word_type text_start_address; // word address to start running (PC) + word_type text_length; // size of the text section in words + word_type data_start_address; // word address of static data (GP) + word_type data_length; // size of data section in words + word_type stack_bottom_addr; // word address of stack "bottom" (FP) +} BOFHeader; + +// a type for Binary Output Files +typedef struct { + FILE *fileptr; + const char *filename; +} BOFFILE; + +// Open filename for reading as a binary file +// Exit the program with an error if this fails, +// otherwise return the FILE pointer to the open file. +extern BOFFILE bof_read_open(const char *filename); + +// Return the size (in bytes) of bf +extern size_t bof_file_bytes(BOFFILE bf); + +// Return true just when bf is at its end, false otherwise +extern bool bof_at_eof(BOFFILE bf); + +// Requires: bf is open for reading in binary and has +// at least 1 word (2 bytes) available to read +// Return the next word from bf +extern word_type bof_read_word(BOFFILE bf); + +// Requires: bf is open for reading in binary and +// buf is of size at least bytes +// Read the given number of bytes into buf and return the number of bytes read +size_t bof_read_bytes(BOFFILE bf, size_t bytes, void *buf); + +// Requires: bf is open for reading in binary +// Read the header of bf as a BOFHeader and return that header +// If any errors are encountered, exit with an error message. +extern BOFHeader bof_read_header(BOFFILE); + +// Open filename for writing as a binary file +// Exit the program with an error if this fails, +// otherwise return the BOFFILE for it. +extern BOFFILE bof_write_open(const char *filename); + +// Requres: bf is open +// Close the given binary file +// Exit the program with an error if this fails. +extern void bof_close(BOFFILE bf); + +// Requires: bf is open for writing in binary +// Write the given word into bf. +// Exit the program with an error if this fails. +extern void bof_write_word(BOFFILE bf, word_type w); + +// Requires: bf is open for writing in binary +// and the size of buf is at least bytes +// Write the given number of bytes from buf into f. +// Exit the program with an error if this fails. +extern void bof_write_bytes(BOFFILE bf, size_t bytes, + const void *buf); + +// Requires: bf is open for writing in binary +// Write the given header to f +// Exit the program with an error if this fails. +extern void bof_write_header(BOFFILE bf, const BOFHeader hdr); + +// Write the (bits of the) magic number into the header *bh. +extern void bof_write_magic_to_header(BOFHeader *bh); + +// Does the given header have the appropriate magic number? +bool bof_has_correct_magic_number(BOFHeader bh); + +// The following line is for the manual (i.e., the document itself)y +// ... +#endif diff --git a/FromGithub/bof.o b/FromGithub/bof.o new file mode 100644 index 0000000000000000000000000000000000000000..4e2c35910803ef934b48e454057a807abfcf8f02 GIT binary patch literal 16544 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 literal 0 HcmV?d00001 diff --git a/FromGithub/char-inputs.txt b/FromGithub/char-inputs.txt new file mode 100644 index 0000000..28eebd9 --- /dev/null +++ b/FromGithub/char-inputs.txt @@ -0,0 +1,6 @@ +$Id: char-inputs.txt,v 1.2 2024/11/13 19:48:06 leavens Exp leavens $ +"8N[3456789abcdefghijklmnopqrstuvwzyz +ABCDEFGHIJKLMNOPQRSTUVWXYZ +ljk;.!@$%`~<>,?/\[{}]dfafjk +skfj8u32820t-0i[pkrojgivrmolk;u +slkdfj;sdfkjalskj diff --git a/FromGithub/code.c b/FromGithub/code.c new file mode 100644 index 0000000..f5f181f --- /dev/null +++ b/FromGithub/code.c @@ -0,0 +1,494 @@ +/* $Id: code.c,v 1.29 2024/11/11 23:01:08 leavens Exp $ */ +#include +#include +#include +#include "utilities.h" +#include "code.h" +#include "regname.h" + +// Return a fresh code struct, with next pointer NULL +// containing the given instruction instr. +// If there is not enough space, bail with an error, +// so this will never return NULL. +static code *code_create(bin_instr_t instr) +{ + code *ret = (code *)malloc(sizeof(code)); + if (ret == NULL) { + bail_with_error("Not enough space to allocate a code struct!"); + } + ret->next = NULL; + ret->instr = instr; + return ret; +} + +// --- computational format instructions as in the SSM Manual's table 3 --- + +// return a freshly allocated computational-format instruction +static code *create_comp_instr(reg_num_type t, offset_type ot, reg_num_type s, + offset_type os, func0_code fc) +{ + comp_instr_t ci; + ci.op = COMP_O; + ci.rt = t; + ci.ot = ot; + ci.rs = s; + ci.os = os; + ci.func = fc; + bin_instr_t bi; + bi.comp = ci; + return code_create(bi); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_nop() +{ + return create_comp_instr(0,0,0,0,NOP_F); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_add(reg_num_type t, offset_type ot, + reg_num_type s, offset_type os) +{ + return create_comp_instr(t, ot, s, os, ADD_F); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_sub(reg_num_type t, offset_type ot, + reg_num_type s, offset_type os) +{ + return create_comp_instr(t, ot, s, os, SUB_F); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_cpw(reg_num_type t, offset_type ot, + reg_num_type s, offset_type os) +{ + return create_comp_instr(t, ot, s, os, CPW_F); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_cpr(reg_num_type t, reg_num_type s) +{ + return create_comp_instr(t, 0, s, 0, CPR_F); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_and(reg_num_type t, offset_type ot, + reg_num_type s, offset_type os) +{ + return create_comp_instr(t, ot, s, os, AND_F); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_bor(reg_num_type t, offset_type ot, + reg_num_type s, offset_type os) +{ + return create_comp_instr(t, ot, s, os, BOR_F); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_nor(reg_num_type t, offset_type ot, + reg_num_type s, offset_type os) +{ + return create_comp_instr(t, ot, s, os, NOR_F); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_xor(reg_num_type t, offset_type ot, + reg_num_type s, offset_type os) +{ + return create_comp_instr(t, ot, s, os, XOR_F); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_lwr(reg_num_type t, reg_num_type s, offset_type os) +{ + return create_comp_instr(t, 0, s, os, LWR_F); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_swr(reg_num_type t, offset_type ot, reg_num_type s) +{ + return create_comp_instr(t, ot, s, 0, SWR_F); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_sca(reg_num_type t, offset_type ot, + reg_num_type s, offset_type os) +{ + return create_comp_instr(t, ot, s, os, SCA_F); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_lwi(reg_num_type t, offset_type ot, + reg_num_type s, offset_type os) +{ + return create_comp_instr(t, ot, s, os, LWI_F); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_neg(reg_num_type t, offset_type ot, + reg_num_type s, offset_type os) +{ + return create_comp_instr(t, ot, s, os, NEG_F); +} + + +// --- other computational format instructions, in SSM Manual's table 4 --- + +// return a freshly allocated computational-format instruction +static code *create_other_comp_instr(reg_num_type t, offset_type o, + arg_type a, func1_code fc) +{ + other_comp_instr_t oci; + oci.op = OTHC_O; + oci.reg = t; + oci.offset = o; + oci.arg = a; + oci.func = fc; + bin_instr_t bi; + bi.othc = oci; + return code_create(bi); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_lit(reg_num_type t, offset_type ot, immediate_type i) +{ + return create_other_comp_instr(t, ot, i, LIT_F); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_ari(reg_num_type r, immediate_type i) +{ + return create_other_comp_instr(r, 0, i, ARI_F); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_sri(reg_num_type r, immediate_type i) +{ + return create_other_comp_instr(r, 0, i, SRI_F); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_mul(reg_num_type s, offset_type o) +{ + return create_other_comp_instr(s, o, 0, MUL_F); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_div(reg_num_type s, offset_type o) +{ + return create_other_comp_instr(s, o, 0, DIV_F); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_cfhi(reg_num_type t, offset_type o) +{ + return create_other_comp_instr(t, o, 0, CFHI_F); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_cflo(reg_num_type t, offset_type o) +{ + return create_other_comp_instr(t, o, 0, CFLO_F); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_sll(reg_num_type t, offset_type o, shift_type h) +{ + return create_other_comp_instr(t, o, h, SLL_F); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_srl(reg_num_type t, offset_type o, shift_type h) +{ + return create_other_comp_instr(t, o, h, SLL_F); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_jmp(reg_num_type s, offset_type o) +{ + return create_other_comp_instr(s, o, 0, JMP_F); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_csi(reg_num_type s, offset_type o) +{ + return create_other_comp_instr(s, o, 0, CSI_F); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_jrel(offset_type o) +{ + return create_other_comp_instr(0, 0, o, JREL_F); +} + + +// --- immediate format instructions, in SSM Manual's table 5 --- + +// return a fresh immediate-type instruction +// (with a signed immediate operand) +static code *create_immed_instr(op_code op, reg_num_type r, + offset_type o, immediate_type i) +{ + immed_instr_t ii; + ii.op = op; + ii.reg = r; + ii.offset = o; + ii.immed = i; // this is sign extended by the VM, not here! + bin_instr_t bi; + bi.immed = ii; + return code_create(bi); +} + +// return a fresh immediate-type instruction +// (with an unsigned immediate operand) +static code *create_uimmed_instr(op_code op, reg_num_type r, + offset_type o, uimmed_type u) +{ + uimmed_instr_t ui; + ui.op = op; + ui.reg = r; + ui.offset = o; + ui.uimmed = u; + bin_instr_t bi; + bi.uimmed = ui; + return code_create(bi); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_addi(reg_num_type r, offset_type o, immediate_type i) +{ + return create_immed_instr(ADDI_O, r, o, i); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_andi(reg_num_type r, offset_type o, uimmed_type u) +{ + return create_uimmed_instr(ANDI_O, r, o, u); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_bori(reg_num_type r, offset_type o, uimmed_type u) +{ + return create_uimmed_instr(BORI_O, r, o, u); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_nori(reg_num_type r, offset_type o, uimmed_type u) +{ + return create_uimmed_instr(NORI_O, r, o, u); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_xori(reg_num_type r, offset_type o, uimmed_type u) +{ + return create_uimmed_instr(XORI_O, r, o, u); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_beq(reg_num_type r, offset_type o, immediate_type i) +{ + return create_immed_instr(BEQ_O, r, o, i); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_bgez(reg_num_type r, offset_type o, immediate_type i) +{ + return create_immed_instr(BGEZ_O, r, o, i); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_bgtz(reg_num_type r, offset_type o, immediate_type i) +{ + return create_immed_instr(BGTZ_O, r, o, i); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_blez(reg_num_type r, offset_type o, immediate_type i) +{ + return create_immed_instr(BLEZ_O, r, o, i); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_bltz(reg_num_type r, offset_type o, immediate_type i) +{ + return create_immed_instr(BLTZ_O, r, o, i); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_bne(reg_num_type r, offset_type o, immediate_type i) +{ + return create_immed_instr(BNE_O, r, o, i); +} + +// --- jump format instructions, in SSM Manual's table 6 --- + +// return a fresh jump-type instruction +static code *create_jump_instr(op_code op, address_type a) +{ + jump_instr_t ji; + ji.op = op; + ji.addr = a; + bin_instr_t bi; + bi.jump = ji; + return code_create(bi); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_jmpa(address_type a) +{ + return create_jump_instr(JMPA_O, a); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_call(address_type a) +{ + code *ret = create_jump_instr(CALL_O, a); + return ret; +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_rtn() +{ + code *ret = create_jump_instr(RTN_O, 0); + return ret; +} + +// --- system call instructions, in SSM Manual's table 7 --- + +// return a fresh syscall-type instruction +static code *create_syscall_instr(syscall_type t, reg_num_type r, offset_type o) +{ + syscall_instr_t si; + si.op = OTHC_O; + si.reg = r; + si.offset = o; + si.code = t; + si.func = SYS_F; + bin_instr_t bi; + bi.syscall = si; + return code_create(bi); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_exit(offset_type o) +{ + return create_syscall_instr(exit_sc, 0, o); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_pstr(reg_num_type s, offset_type o) +{ + return create_syscall_instr(print_str_sc, s, o); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_pint(reg_num_type s, offset_type o) +{ + return create_syscall_instr(print_int_sc, s, o); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_pch(reg_num_type s, offset_type o) +{ + return create_syscall_instr(print_char_sc, s, o); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_rch(reg_num_type t, offset_type o) +{ + return create_syscall_instr(read_char_sc, t, o); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_stra() +{ + return create_syscall_instr(start_tracing_sc,0,0); +} + +// Create and return a fresh instruction +// with the named mnemonic and parameters +code *code_notr() +{ + return create_syscall_instr(stop_tracing_sc,0,0); +} + +#define MINIMAL_STACK_ALLOC_IN_WORDS 12 +#define MINIMAL_STACK_ALLOC_BYTES (BYTES_PER_WORD*MINIMAL_STACK_ALLOC_IN_WORDS) + +// Set up the runtime stack for a procedure, +// where the static link is found in register $a0. +// Modifies when executed, the SP register, the FP register, +// and memory from SP to SP - MINIMAL_STACK_ALLOC_BYTES +// (inclusive) +code_seq code_save_registers_for_AR() +{ + // assume that SP is pointing to the lowest local storage already allocated + code_seq ret; + // push stack_pointer at word index 0 - 1 from current SP + ret = code_seq_singleton(code_swr(SP, SP, -1)); + // push the frame pointer (dynamic link) at word index -2 + code_seq_add_to_end(&ret, code_swr(SP, FP, -2)); + // save SP into FP register so FP points to the base of the AR + code_seq_add_to_end(&ret, code_add(0, SP, FP,ADD_F)); + // allocate the space on the stack, by subtracting from SP + code_seq_add_to_end(&ret, code_addi(SP, SP, - MINIMAL_STACK_ALLOC_BYTES)); + // push the static link at word index -3 + code_seq_add_to_end(&ret, code_swr(FP, GP, -3)); + // push the return address at word index 3 + code_seq_add_to_end(&ret, code_swr(FP, RA, -4)); + // save the registers $s0 to $s7 (inclusive) + int idx = -5; + for (int rn = GP; rn <= RA; rn++) { + code_seq_add_to_end(&ret, code_swr(FP, rn, idx--)); + } + return ret; +} + diff --git a/FromGithub/code.h b/FromGithub/code.h new file mode 100644 index 0000000..5df0a9d --- /dev/null +++ b/FromGithub/code.h @@ -0,0 +1,230 @@ +/* $Id: code.h,v 1.23 2024/11/10 21:09:43 leavens Exp $ */ +#ifndef _CODE_H +#define _CODE_H +#include +#include "machine_types.h" +#include "instruction.h" +#include "code_seq.h" + +// SSM assembly language instructions (that can be in linked lists) +typedef struct code_s { + struct code_s *next; + bin_instr_t instr; +} code; + +// Code creation functions below + +// --- computational format instructions from table 3 of the SSM Manual --- + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_nop(); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_add(reg_num_type t, offset_type ot, + reg_num_type s, offset_type os); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_sub(reg_num_type t, offset_type ot, + reg_num_type s, offset_type os); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_cpw(reg_num_type t, offset_type ot, + reg_num_type s, offset_type os); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_cpr(reg_num_type t, reg_num_type s); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_and(reg_num_type t, offset_type ot, + reg_num_type s, offset_type os); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_bor(reg_num_type t, offset_type ot, + reg_num_type s, offset_type os); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_nor(reg_num_type t, offset_type ot, + reg_num_type s, offset_type os); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_xor(reg_num_type t, offset_type ot, + reg_num_type s, offset_type os); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_lwr(reg_num_type t, reg_num_type s, offset_type os); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_swr(reg_num_type t, offset_type ot, reg_num_type s); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_sca(reg_num_type t, offset_type ot, + reg_num_type s, offset_type os); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_lwi(reg_num_type t, offset_type ot, + reg_num_type s, offset_type os); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_neg(reg_num_type t, offset_type ot, + reg_num_type s, offset_type os); + +// --- other computational format instructions from table 4 --- + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_lit(reg_num_type t, offset_type o, + immediate_type i); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_ari(reg_num_type r, immediate_type i); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_sri(reg_num_type r, immediate_type i); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_mul(reg_num_type s, offset_type o); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_div(reg_num_type s, offset_type o); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_cfhi(reg_num_type t, offset_type o); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_cflo(reg_num_type t, offset_type o); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_sll(reg_num_type t, offset_type o, shift_type h); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_srl(reg_num_type t, offset_type o, shift_type h); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_jmp(reg_num_type s, offset_type o); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_csi(reg_num_type s, offset_type o); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_jrel(offset_type o); + +// --- immediate format instructions from table 5 of the SSM Manual --- + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_addi(reg_num_type r, offset_type o, immediate_type i); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_andi(reg_num_type r, offset_type o, uimmed_type i); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_bori(reg_num_type r, offset_type o, uimmed_type i); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_nori(reg_num_type r, offset_type o, uimmed_type i); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_beq(reg_num_type r, offset_type o, immediate_type i); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_bgez(reg_num_type r, offset_type o, immediate_type i); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_bgtz(reg_num_type r, offset_type o, immediate_type i); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_blez(reg_num_type r, offset_type o, immediate_type i); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_bltz(reg_num_type r, offset_type o, immediate_type i); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_bne(reg_num_type r, offset_type o, immediate_type i); + +// --- jump format instructions from table 6 of the SSM Manual --- + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_jmpa(address_type a); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_call(address_type a); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_rtn(); + +// --- system calls from table 7 of the SSM Manual --- + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_exit(offset_type o); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_pstr(reg_num_type s, offset_type o); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_pint(reg_num_type s, offset_type o); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_pch(reg_num_type s, offset_type o); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_rch(reg_num_type t, offset_type o); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_stra(); + +// Create and return a fresh instruction +// with the named mnemonic and parameters +extern code *code_notr(); + +// Set up the runtime stack for a procedure, +// where the static link is found in register $a0. +// Modifies when executed, the SP register, the FP register, +// and memory from SP to SP - MINIMAL_STACK_ALLOC_BYTES +// (inclusive) +extern code_seq code_save_registers_for_AR(); + + +#endif diff --git a/FromGithub/code.o b/FromGithub/code.o new file mode 100644 index 0000000000000000000000000000000000000000..c79c02832f695a0491e3b3f3224f244b9b5174d9 GIT binary patch literal 26000 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 +#include +#include +#include "utilities.h" +#include "regname.h" +#include "code.h" +#include "code_seq.h" + + +static void code_seq_okay(code_seq seq) +{ + // seq.first and seq.last are either both null or both not null + assert((seq.first == NULL) == (seq.last == NULL)); +} + +// Return an empty code_seq +code_seq code_seq_empty() +{ + code_seq ret; + ret.first = NULL; + ret.last = NULL; + code_seq_okay(ret); + return ret; +} + +// Requires: c != NULL +// Return a code_seq containing just the given code +code_seq code_seq_singleton(code *c) +{ + code_seq ret; + ret.first = c; + ret.last = c; + code_seq_okay(ret); + return ret; +} + +// Is seq empty? +bool code_seq_is_empty(code_seq seq) +{ + code_seq_okay(seq); + return seq.first == NULL; +} + +// Requires: !code_seq_is_empty(seq) +// Return the first element of the given code sequence, seq +code *code_seq_first(code_seq seq) +{ + assert(!code_seq_is_empty(seq)); + return seq.first; +} + +// Requires: !code_seq_is_empty(seq) +// Return a new code_seq containing +// the rest of the given sequence, seq +// Note that seq is not modified +code_seq code_seq_rest(code_seq seq) +{ + assert(!code_seq_is_empty(seq)); + code *first = seq.first; + code_seq ret; + ret.first = first->next; + if (ret.first == NULL) { + ret.last = NULL; + } else { + ret.last = seq.last; + } + code_seq_okay(ret); + return ret; +} + +// Return the size (number of instructions/words) in seq +unsigned int code_seq_size(code_seq seq) +{ + unsigned int ret = 0; + while (!code_seq_is_empty(seq)) { + ret++; + seq = code_seq_rest(seq); + } + return ret; +} + +// Requires: !code_seq_is_empty(seq) +// Return the last element in the given sequence +code *code_seq_last_elem(code_seq seq) +{ + assert(!code_seq_is_empty(seq)); + return seq.last; +} + +// Requires: c != NULL && seq != NULL +// Modify seq to add the given code *c added to its end +void code_seq_add_to_end(code_seq *seq, code *c) +{ + assert(c != NULL); + if (code_seq_is_empty(*seq)) { + seq->first = c; + seq->last = c; + } else { + // assert(!code_seq_is_empty(seq)); + code *last = code_seq_last_elem(*seq); + last->next = c; + c->next = NULL; + seq->last = c; + } + code_seq_okay(*seq); +} + +// Requires: s1 != NULL && s2 != NULL +// Modifies s1 to be the concatenation of s1 followed by s2 +void code_seq_concat(code_seq *s1, code_seq s2) +{ + if (code_seq_is_empty(*s1)) { + s1->first = s2.first; + s1->last = s2.last; + } else if (code_seq_is_empty(s2)) { + ; // s1 is already their concatenation + } else { + code *last = code_seq_last_elem(*s1); + // assert(last != NULL); + last->next = s2.first; + s1->last = s2.last; + } + code_seq_okay(*s1); +} + +// Requires: out is open for writing. +// Print the instructions in the code_seq to out +// in assembly language format +void code_seq_debug_print(FILE *out, code_seq seq) +{ + while(!code_seq_is_empty(seq)) { + fprintf(out, "%s\n", + instruction_assembly_form(0, code_seq_first(seq)->instr)); + seq = code_seq_rest(seq); + } +} diff --git a/FromGithub/code_seq.h b/FromGithub/code_seq.h new file mode 100644 index 0000000..0232eb9 --- /dev/null +++ b/FromGithub/code_seq.h @@ -0,0 +1,56 @@ +/* $Id: code_seq.h,v 1.3 2024/11/08 21:01:43 leavens Exp $ */ +#ifndef _CODE_SEQ_H +#define _CODE_SEQ_H +#include + +// Forward declare 'code' type to avoid circular dependency +struct code_s; +typedef struct code_s code; // Declare code as a type + +// code sequences are linked lists +// with an additional last pointer to the last node +typedef struct { + code *first; + code *last; +} code_seq; + +// Return an empty code_seq +extern code_seq code_seq_empty(); + +// Return a code_seq containing just the given code +extern code_seq code_seq_singleton(code *c); + +// Is seq empty? +extern bool code_seq_is_empty(code_seq seq); + +// Requires: !code_seq_is_empty(seq) +// Return the first element of the given code sequence, seq +extern code *code_seq_first(code_seq seq); + +// Requires: !code_seq_is_empty(seq) +// Return a new code_seq containing +// the rest of the given sequence, seq +// Note that seq is not modified +extern code_seq code_seq_rest(code_seq seq); + +// Return the size (number of instructions/words) in seq +extern unsigned int code_seq_size(code_seq seq); + +// Requires: !code_seq_is_empty(seq) +// Return the last element in the given sequence +extern code *code_seq_last_elem(code_seq seq); + +// Requires: c != NULL && seq != NULL +// Modify seq to add the given code *c added to its end +extern void code_seq_add_to_end(code_seq *seq, code *c); + +// Requires: s1 != NULL && s2 != NULL +// Modifies s1 to be the concatenation of s1 followed by s2 +extern void code_seq_concat(code_seq *s1, code_seq s2); + +// Requires: out is open for writing. +// Print the instructions in the code_seq to out +// in assembly language format +extern void code_seq_debug_print(FILE *out, code_seq seq); + +#endif diff --git a/FromGithub/code_seq.o b/FromGithub/code_seq.o new file mode 100644 index 0000000000000000000000000000000000000000..59cb0cc15811d9c18f72b46bd7127028a37e5431 GIT binary patch literal 14888 zcmbtb4RBo5b-qu#&%4rE(poaIh5uIA#x_`5OBVjYmXYnqtZZW&f&z|ho>r?TY2($d z*dMScP8dvMs}55;A%qTQAX6A94bwDa0;RMVlEEb~V5Ussq_pG7Pvb(`IHZ|6!Nfi1 z+;iT(y_QQ$@1TA6eD|F1oO|wl_uY4&`9jauO;whqq*!X5DocVYHPTtGcT=@n%}`D1 zH}!LW-7(nk|ZWxexVMpBEIU?PMkr7Bd>k8!o!K4vj`_n^qiyX;l8s(J@LcD#H(j=7cN{N zpNIR-RT#z+6Z_9V%NdGHUm>~*&tW1IjJBn*>v7zPSPQjcb-Mza5YSo?sXtxV-F zKDzWcl&8pPi1f^fp7R*p`|}R;oVS4HG&wAX4US1~k|v$D6Nh`wS7hT8ru>$V$;M<8 zYNB*HabW*xRWYBPk0F9|MiYm-!@jY(?|89UCmQ-c0j-#GtnLWEzgA183FHNDFU&lf zoKBp;Oe(+i#kO0|U${_tQ^D+kdt>75#KhUe#P9Xp3qy~S2*WTP>sV=effcl}BF35k z=_Hu>=N-)K_Q{!a7svo6MFrEv1`m8_#vOyW!LA~1NJZb7_jgfJ=q{&a0kZ-LpLq2p ztkJrXn9xho{j~@sCf-a;oOr(6`U&RY;Ukb%rBb;;*D1KSx22Fxsl`|yO6Lp3SXWnU zTi@2LORz$4Ch0>}ik6~|F&iAu#-jVX+q0kg!Y(Ye`t8g)S1h zwa`sMLJR9j*rA0DB;2ZnPc?lC;_TPLrs=&PjA$W2QIBb%mxQ7gHb?#ly0A|RH#7`^ zaE}(Y)#E7MtA*|1ZNPRw3pdu^2ErjN?5sTqYDcuNYsLt)Jfwx)&3OPriOJCQslIxBJx+OzH~8?& zeE6)|^`6e$rq6iw7OKw)1rZ9(uUipNsvfG!qTed|4bX3pe(f39`iBr*E`+q((3OD? z!GCoywB!LG2;|1pRnr~@B&Y)UqPn`_NvH>cfm~57o%Sqhh64G5YSnl&kSnM*jW^P5 z5wCv7J($#^-H0j!P zK^=0JpLCs{^g1Rbp6&)r5|gg4B;64BttQ>{MJB!8Pnz(P_WDUTPyZoA8jW&~w*)qW zJ@k0{o6NJr&vT=n=O#bTr>FhY&vSF&%bMqw^UQNA^H5iIHv9^-X9wBqX9GV5t+~O_ zp6Z)nU7Cs`eOm*LC{>-An0~7EUxrDeYO)c#O4Whs7%f#(4d{@02Lreyf+tv-!ZR{Z zr*$k^T@!r(1iH7XBh&u@>MTs1h5>|Cbu>KnIZ+AMMzF3`!gVBsmE8}R=B^JQosACW zp|hIXtf@Hd-vc20CC~{!2tP5^f{mdEr{k?jJG5a=tHbKT73)1kg)=(IG76^Gt z?TKsS9Z}S~22`qHSatE-t!04Rxn*}X*kiPzWvx-wp$png^o3|}*v{pvb!@-H&^KTA zsh|AbU*T5~FJi>opz6?!czf$G`BDbCVjVjvyuAxK#nbX`QEh3U#qDTDTd%IcMk!Bw z)^T{uQ)X7TXzOl@>NQltEstzeB;`k*paZr55=P?QS z{91)i&5IcE)~Px)Bi=<*-hiqU86oQ!qSTi~+?RgXGr$~VvpE$h=wf^8SUv1_f+;m; zzMc-cfAhTl%|}J6p~85zXWR|Ol#uD3!2&XfP^efP@RTXI$O3<-D-#WlYE_`_+Q^#7 z>PTCT1kFqkYAYZGb0u`GwXm)+5|}q@9s*H#YG2M-fJrk8(gjh@E~gqc zy+LbTBm#q=2LsvX&X6pTvw0kBWR1N#f*Dv#eUIVV(c-niK$hFCsDuw%&Dv(ZAFoX1 zf;Q-*j-i|m@URsAXl}#P!C(A)b3gv~@N}_3Hv^z$Ss&Kb;sro_j6h|cZ+R%&Rax_@ z>ghpN#?VH)rsdLGGs_yfhR;2io0h89ae@?xShgL0QB?)4Dd8iwHKl5CW4B%ZqFr~u zwh!1-!*Sa>u-vZy&kCReZ2s1+hsLJOwl%yQMWLui3ftOpjUS8<*mR#=U$m!gvBR6~ z$WA-@m>t<{+gsU7hur|Ak&`H-t>rk>Vo=uJ9bJ<*}&|1pgna&Qj z7Lx-Rw*ZZWVluV2bu6DNx~XC=4`!eU=G>5i_s|h(PUo`FkQ(yI3f@EW%H5YPI)#+_ zTxoR7p*}(1vhF_UJHD`{?kK9EQZ}VKl0km@!I#cLdN}J2#vm(@8)wH&JvZOH)7jLw zZR5?o+qXH6Dy2t9U3k^S)Z~gIsqz~%y>lyPD4lV$xpI>6jo5oj#xyI>7udUbh{zYD zGn7dV7swh?POsBWs)S0J(rA`&>A_eY;&mWD*i$E$8N}f&z>{09;#KL8B@a0KFgknP zJaIZ70;P;nr0FEE>bVC_3duWMXCPUCnV89?_CkD^p$_GY!bqw@F*oKE z^T|{?J4|`-!os{`SJ8+k{ifcnJv58GIUy->2Hk;5O2CPPvJWS)2{IT&A35np-+AlyD3=4aYu%$zqbGY}q`O%chbrCU?;N zAp=YO(8G^h*l)U@Meus14|U{rmV|56Q=*d|Pb#1DXh>1Cc(>54MopYbK3;%bD~dl=Co}4tmZ~5IVB*Ov4+F8uIS2lP!(vmiS0+)QxA|Vth2Y zvZKAD;# zv!b&#lg^g*wGL-X@%Hw3I-AOrV6KxQ3l}R6q>F|Bg-RT6tV%_H+>$it0xZ~r?oiu^ zA`7^}QUkZRgR>7LzKkYQBk8QZUkd>HRsxVbI$b4_!E_F;xJu-UP*K-!+<0wlao<2G zTP*R@q_w?7V*BSiI@*?XE@2qA1Mr8NecWuo69~5v#}SiF1ifj1Y~6K}vi3!-SyMw{ zJi)@lB|2b&EA6Ly>Y`t)+E_cKYA0yuHhB@C&AGIXQ8U@@23st&^OyEwx&3b4tcXY2 z3+47>-0tF4+N*YZ{$J#Fdb#r2zwWia%k6^|_Pf0H^W1(Z{@JwgQtI^z`&T^swcP%E zMf+cQ?Yp_1-qpSM9;9}5ebEI?g6h{7E@}WEpbsD}Y6{TkR>HW2tn%s87y@=V{8^yi z4_7SsH4w`(_(Ob*BtD9R`XVhpJIG1U%$`z zbRKJ(OMv}|@o~oG0N@vl&xack3(ZZq{ucg_ACGXb2u~R75&tFQG#8;A=O*IM@r_J# z5b&jp=kO+nBIiWw0iP@nyDov3S0dkzO+TD3-sH7)PPX-HTRtfYJCR8k+9ySq0jd{1 zV+W!4j1qmGklY{XXHt{eGV{cUNApjA}ys(8o2QP*uW*upD=EYOAV4j5&myzQ8gR5@Xt5!ZLEJa z<0k)lAMVe8(T6tyhw%Tq5BKZOL1HLo-d6f>KhNVn9G?lo|Ev$kXOQ48GcI|!6`etO z+owMZWYPbb5BHDn1t0E@U(RZ3fW!YZk;6j7u`c;UTP%pZwx{7|azTBe-#eF#Xoz1d5XC$6AOt!_)*Pj}dy2-$2@cppUz?+$8z`(!2suY#{&9G|~f1pkQR`Id$~{Be%wB?Fi7 ze#5{=Ss$OvScHE+`~6o9d$?t5;5P<-1II%H?&J9x#R@;e58oc(^+z|XLJ(!hf(|FeP1dhwot|A6!MUj}|9`wj9{^7#QwF|-=jXQ#Jj%F?gXBTx z_Zxt)tfAk{d6Va(=)cGOQSP7MZ!u4kfxpH)vkm-Bmaj1I zcUfL+;3CHj{2h*arGYQuI1d{58jk0y20n%5R}B0P)|a@XzrypLp?{R~FhlYOap3bs zcorD=Q!KX|xbR9`0qH*ZyUJq$bLZh8#vEz8TyA9|CNFN zob&&Yfq%ew1J7&W?`C|Cf#1k+E;jHK=V7^lOMllHxWwOU;7>45pMgKaaVHI2#%t8T z(vDYp^Ub z@J7a$GLG($Lf&ip4gIHC-!=5*{rEuxU&#G>(%_N)zG&b#u>Q*ikGz+EVCc7Ve$M;! zF+@2RvEdsj7U|aj$KS-b=Ja%lh)9PapZ^9Ox}Wf1Kla$G~?m{x1fP?1Q85&l<2ue?PMCvMOCAb7eWd7T1D>`N55^=V$`y%6@GH22y7=BC`?@O) zJjwD^2L2~3w;A{|EO!|A4_IDn;6G(~y@CG+%bN`RcP#tgvoQWD>>!jK`a*d?yoT{U z1E0zGXAOKFUao?tv{;M*B582BxW?`IrEoVQY9TtUo_cN_Qs%l!r} z^Y$JCm;2%|1DE^pxPi<1aN59Sosst}iBs0M823+bS%Ou(O15ynr{stvw!kGk-Axh)G{_S@jo4Sd;$PkJoFm##MW=066XgvOcI z9f2=<$x)XR`TxAcz#da3>wwU8bH)5uFPvUcQ+Q^BkA!Xy(UoXSU;BBz!ZRGSL?zTLRn&T%+%cjIwpp8FHFN< z{k=%n^slLl=XjIF|I{+A&lidxQ(?w`J76X!TE55r<-8a%ET(P-u*v+NV#oSl-0S?| zxuEGE*G=S@}z$r)htL?e+g=A=>5q3xfC8 zWaD>;Hv(Y}80UWj{E2^AKPK~y++jX&eT)Oc^Dw+6OnaP@=Gp;}dTK8I!vFVUB+L*M UPSeTkk1Qv1^^f}E{hIdw4fI;j#sB~S literal 0 HcmV?d00001 diff --git a/FromGithub/code_utils.c b/FromGithub/code_utils.c new file mode 100644 index 0000000..8b54474 --- /dev/null +++ b/FromGithub/code_utils.c @@ -0,0 +1,158 @@ +// $Id: code_utils.c,v 1.8 2024/11/11 23:01:08 leavens Exp $ +#include +#include "regname.h" +#include "code.h" +#include "code_seq.h" +#include "code_utils.h" + +#define MINIMAL_STACK_ALLOC_IN_WORDS 4 +#define SAVED_SP_OFFSET (-1) +#define SAVED_FP_OFFSET (-2) +#define SAVED_STATIC_LINK_OFFSET (-3) +#define SAVED_RA_OFFSET (-4) + +// Requires: t != SP && s != SP +// Return a code sequence that copies the value from register s +// into register t, using the top of the stack as a temporary. +// Modifies: t (and temporarily, SP) +code_seq code_utils_copy_regs(reg_num_type t, reg_num_type s) +{ + assert(t != SP); + assert(s != SP); + code_seq ret = code_seq_singleton(code_cpr(t, s)); + // If the SSM didn't have the cpr instruction + // one could use the top of the stack as a temporary, as follows + /* + code_seq ret = code_utils_allocate_stack_space(1); + code_seq_add_to_end(&ret, code_swr(SP, 0, s)); + code_seq_add_to_end(&ret, code_lwr(t, SP, 0)); + code_seq_concat(&ret, code_utils_deallocate_stack_space(1)); + */ + return ret; +} + +// Return a code sequence that loads the static link +// (which is SAVEDSTATIC_LINK_OFFSET from the address contained in register b, +// and place it in register rt. +// Modifies only register rt. +code_seq code_utils_load_static_link_into_reg(reg_num_type t, + reg_num_type b) +{ + code_seq ret = code_seq_singleton(code_lwr(t, b, SAVED_STATIC_LINK_OFFSET)); + return ret; +} + +// Requires: reg != FP && reg != RA +// Modifies only: register reg +// Return a code sequence that will put the address that corresponds to the +// frame pointer for the given number of scopes outward in register reg +code_seq code_utils_compute_fp(reg_num_type reg, unsigned int levelsOut) +{ + assert(reg != FP && reg != RA); + code_seq ret + = code_utils_copy_regs(reg, FP); + while (levelsOut > 0) { + code_seq_concat(&ret, + code_utils_load_static_link_into_reg(reg, reg)); + levelsOut--; + } + return ret; +} + +// Requires: words >= 0 +// Allocate the given number of words on the runtime stack +// Modifies when executed: SP register +// At the end of exeuction, SP holds the address of the last allocated word. +// (So, if the call allocates only one word, then SP addresses that word.) +code_seq code_utils_allocate_stack_space(immediate_type words) +{ + assert(words >= 0); + code_seq ret = code_seq_singleton(code_sri(SP, words)); + return ret; +} + +// Requires: words >= 0 +// Deallocate the given number of words from the runtime stack +// Modifies when executed: SP register +code_seq code_utils_deallocate_stack_space(immediate_type words) +{ + assert(words >= 0); + code_seq ret = code_seq_singleton(code_ari(SP, words)); + return ret; +} + +// Requires: $r3 holds the static link (from the current AR) +// Set up the runtime stack for a procedure, +// where the static link is found in register $r3. +// Modifies when executed, the SP register, the FP register, +// and memory from SP to SP - MINIMAL_STACK_ALLOC_IN_WORDS +// (inclusive) +code_seq code_utils_save_registers_for_AR() +{ + // assume that SP is pointing to the lowest local storage already allocated + code_seq ret; + // save SP onto the top of the stack + ret = code_seq_singleton(code_swr(SP, SAVED_SP_OFFSET, SP)); + // save FP (dynamic link) onto top of the stack + code_seq_add_to_end(&ret, code_swr(SP, SAVED_FP_OFFSET, FP)); + // save the static link from $r3 onto top of stack + code_seq_add_to_end(&ret, code_swr(SP, SAVED_STATIC_LINK_OFFSET, 3)); + // save the RA register on the stack + code_seq_add_to_end(&ret, code_swr(SP, SAVED_RA_OFFSET, RA)); + // save SP into the FP register so FP points to the base of the AR + // can't use code_utils_copy_regs for this because SP is involved + code_seq_add_to_end(&ret, code_cpr(FP, SP)); + /* the following can be used if there is no cpr instruction: + code_seq_add_to_end(&ret, SAVED_RA_OFFSET-1, SP)); + code_seq_add_to_end(&ret, code_lwr(FP, SP, SAVED_RA_OFFSET-1)); + */ + + // allocate the space on the stack for the saved registers + code_seq_concat(&ret, + code_utils_allocate_stack_space(MINIMAL_STACK_ALLOC_IN_WORDS)); + + return ret; +} + +// Restore the callee's registers from the places they are saved on the stack. +// This restores the SP, FP, and RA registers only. +// (It is assumed that the stack already holds the static link address) +// Modifies when executed, the SP register, the FP register, the RA register. +// restoring their saved contents from memory +// (as saved by code_utils_save_registers_for_AR) +code_seq code_utils_restore_registers_from_AR() +{ + code_seq ret = code_seq_empty(); + // restore the RA register + code_seq_add_to_end(&ret, + code_lwr(RA, FP, SAVED_RA_OFFSET)); + // save the SP register in $r3 temporarily, to not violate VM's invariant + code_seq_add_to_end(&ret, code_lwr(3, FP, SAVED_SP_OFFSET)); + // restore the FP (dynamic link) register + code_seq_add_to_end(&ret, code_lwr(FP, FP, SAVED_FP_OFFSET)); + // deallocate the space for variables and constants by restoring old SP + code_seq_add_to_end(&ret, code_cpr(SP, 3)); + return ret; +} + +// Set up the program's stack as if it were in a call (from the OS) +code_seq code_utils_set_up_program() +{ + code_seq ret; + // set up the saved registers + ret = code_utils_copy_regs(3, FP); // save FP into $r3 + code_seq_concat(&ret, code_utils_save_registers_for_AR()); + // use what will be the new FP as the saved static link + code_seq_add_to_end(&ret, code_swr(FP, SAVED_STATIC_LINK_OFFSET, FP)); + return ret; +} + +// Tear down the program's stack and exit (with exit code 0). +code_seq code_utils_tear_down_program() +{ + code_seq ret; + // restore the saved registers to their initial state + ret = code_utils_restore_registers_from_AR(); + code_seq_add_to_end(&ret, code_exit(0)); + return ret; +} diff --git a/FromGithub/code_utils.h b/FromGithub/code_utils.h new file mode 100644 index 0000000..6bf4259 --- /dev/null +++ b/FromGithub/code_utils.h @@ -0,0 +1,59 @@ +// $Id: code_utils.h,v 1.4 2024/11/10 22:06:54 leavens Exp $ +// Some convenience functions that may help with code generation +#ifndef _CODE_UTILS_H +#define _CODE_UTILS_H +#include "code_seq.h" + +// Requires: t != SP && s != SP +// Return a code sequence that copies the value from register s +// into register t, using the top of the stack as a temporary. +// Modifies: t (and temporarily, SP) +extern code_seq code_utils_copy_regs(reg_num_type t, reg_num_type s); + +// Return a code sequence that loads the static link +// (which is SAVEDSTATIC_LINK_OFFSET from the address contained in register b, +// and place it in register rt. +// Modifies only register rt. +extern code_seq code_utils_load_static_link_into_reg(reg_num_type t, + reg_num_type b); + +// Requires: reg != FP && reg != RA +// Modifies only: register reg +// Return a code sequence that will put the address that corresponds to the +// frame pointer for the given number of scopes outward in register reg +extern code_seq code_utils_compute_fp(reg_num_type reg, unsigned int levelsOut); + +// Requires: words >= 0 +// Allocate the given number of words on the runtime stack +// Modifies when executed: SP register +// At the end of exeuction, SP holds the address of the last allocated word. +// (So, if the call allocates only one word, then SP addresses that word.) +extern code_seq code_utils_allocate_stack_space(immediate_type words); + +// Requires: words >= 0 +// Deallocate the given number of words from the runtime stack +// Modifies when executed: SP register +extern code_seq code_utils_deallocate_stack_space(immediate_type words); + +// Set up the runtime stack for a procedure, +// where the static link is found in register $r3. +// Modifies when executed, the SP register, the FP register, +// and memory from SP to SP - MINIMAL_STACK_ALLOC_IN_WORDS +// (inclusive) +extern code_seq code_utils_save_registers_for_AR(); + +// Restore the callee's registers from the places they are saved on the stack. +// This restores the SP, FP, and RA registers only. +// (It is assumed that the stack already holds the static link address) +// Modifies when executed, the SP register, the FP register, the RA register. +// restoring their saved contents from memory +// (as saved by code_utils_save_registers_for_AR) +extern code_seq code_utils_restore_registers_from_AR(); + +// Set up the program's stack as if it were in a call (from the OS) +extern code_seq code_utils_set_up_program(); + +// Tear down the program's stack and exit (with exit code 0). +extern code_seq code_utils_tear_down_program(); + +#endif diff --git a/FromGithub/code_utils.o b/FromGithub/code_utils.o new file mode 100644 index 0000000000000000000000000000000000000000..aea3243ba0be0d75d1699836a6160c8421e25c2a GIT binary patch literal 13664 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[EQN?`ECR9^9kQWxZJ!!9^dC6{}AC}I`_jF@sm`(oz8f&1uVf! zBwOw7ZmO}>YnT#v^-UN8w!mH#C%mo=S{zPM^=IHLcYwuoF);=HCsW{G103~PSB_P{ z{$UFK4~YK`oH5C<3ui2s^5^|2@JhJwX!mIx0FdPPh4T_9m(p2I{OPpHWB$Mt{N2QV zg!sH8Jvasb^Hbm_Naq+$2)qw|aSHw=;-~$xTk4*H?7tAM-rh~_)yu)ZQvEHS3rnm| zBFjsyS|ZCzqMaqt4$X-6HnzkQ8kasi<7$uU$@w}q^NG-_HQ#?kma}y(b zwIzajZcY6-bc>f#Q@r|>wv1I*=_jZ1il4E#*3%y9vQl~UA#1kDMWWWG)DrHN&t8mZ9p-<6aMoe{JqFJF2Mt`lBLFN% zxT$|w!|^>K>m1Q=ydN0gIL9M=+ze_g}zS;hDT!rA{vpbpa;2G0DS8hD4Ii+41A{rXwHhc_515B4cGm-rr|n2fPsNz#-~}sb^aY1uIsPXa6LXB*KnObqTzaf zzo_B*eTr|{+0R*!;W)gY;d(qTX}ErUf2QHOKObng?$2UcvSKxUaAdn{G`vN_H*2`A zpVDw$AGRDaRltn_h3arHpz@H?Y_YC~oq;uWC1B8EI;EjayUXkPTW$IUm>@e;U-e}-B)-fdv+$H^o4E!kR zeAU38BK~s*&N}A}{81`jGjP`7LC^lbK>F2WpK;coZQxwLw)>!|#f2Hr>I?;7}PD*WP21GgzIzcld0#DCwwQ^e=zCdY@L$F&p>#<{<<44nO6 zVBk-Xey4%INab|~&eyBYz=x@Pzkx3x{e*$@{5Wpl{G8_JFZb&&i1&oSf1mWfY2b$` zj^_+KP5jpl{Ew)7)xfWkP8H3g?9Vf#v(Uit8#ktV4E#Sx=aUBhZ)9(ufj>|DqXxc* z>^^1SJT6}~@cC4JozB=CrFsASp9cRe(&tx0%;$ah0(x$89OUoyKrcc#^Ld|tpTYkX z^>?Si=l2VLVDNtm+L*pz@cI44DTB}ZnQt37??ax~bkLQPC=TgugU{=^Uut}e8^31> zl*wj==NH>;G;p?i8{rrqw0lT37kvhwV6jc(quqC?V!y%X`{8p2&UTM$I%szf>HM9+ z@4!k(=QTdsJta}_nZ6$Kb+5yYK&m1fi^%7+#^AF*y&4})c2ff~E91#)Fs#Bo2qshi zb_Gj5uDe!Jxz)fERObB?`j7l9;dj!R@dH%G_nMd(|AH!tyXnk0uVX%H;7?Jx&%pnR z%KCZ?{W(qe4mz9t4HJ$r*5ll5;HRj($G~~~eAd8uJU?mRe1E-c;C!E6F>t=$gXlOU z_LJw0r3TLPkBGSAWAMcj&R$NPM>v;rM&l6=zcxmaaW5_+gD(6yE|*aSS(|hQ^TY7P zXD9<4nU4<+=A4IthK&iz#nZzMHl4)a6P3eFz#eB2#&3%v09507J(21?zQF#{5kHg_mjaS7m-E zF`p~C=~tRFNf`HN*p}}({DA@{ypIs4X#pXbcwXf)pH2Hqp#nAkukG<0FzT_E)Gg#t$XU_}vSbsfjJF z(MFQrHz9_}+mSV zHlxxgic#Q{vM<_XbMdY^$zPD+KGL+0^Dt_%pF|h;(~Hr2QCv%GpUD^=;$|Px zchsqHC7Q`Ejdpv)ih!q=!^y9_@A862YK_&-MN!%U) knsWz0ViCSPf>dvG%;=85VN$C71$tq@>oq9`2ebYE0w +#include +#include +#include "bof.h" +#include "lexer.h" +#include "parser.h" +#include "unparser.h" +#include "ast.h" +#include "utilities.h" +#include "symtab.h" +#include "scope_check.h" + +// The functions gen_code_initialize and gen_code_program +// would normally be declared in gen_code.h, +// but part of the homework is to write that gen_code module, +// so they are declared below to make this file self-contained. + +// Initialize the code generator +extern void gen_code_initialize(); + +// Requires: bf is open for writing +// Generate code for prog into bf +extern void gen_code_program(BOFFILE bf, block_t prog); + +/* Print a usage message on stderr + and exit with failure. */ +static void usage(const char *cmdname) +{ + fprintf(stderr, "Usage: %s %s\n %s %s\n %s %s\n", + cmdname, "-l codeFilename.spl", + cmdname, "-u codeFilename.spl", + cmdname, " codeFilename.spl" + ); + exit(EXIT_FAILURE); +} + +// If the -l option is used, then output the tokens +// in the give file name to stdout, +// otherwise unparse the program given in the file name argument to stdout +int main(int argc, char *argv[]) +{ + // should the lexer's tokens be shown? + bool lexer_print_output = false; + // should the unparse of the AST be shown? + bool parser_unparse = false; + const char *cmdname = argv[0]; + argc--; + argv++; + // possible options: -l, and -u + while (argc > 0 && strlen(argv[0]) >= 2 && argv[0][0] == '-') { + if (strcmp(argv[0],"-l") == 0) { + lexer_print_output = true; + argc--; + argv++; + } else if (strcmp(argv[0],"-u") == 0) { + parser_unparse = true; + argc--; + argv++; + } else { + // bad option! + usage(cmdname); + } + } + + // give usage message if -l and other options are used + if (lexer_print_output && parser_unparse) { + usage(cmdname); + } + + // must have a file name + if (argc <= 0 || (strlen(argv[0]) >= 2 && argv[0][0] == '-')) { + usage(cmdname); + } + + // the name of the file + char *filename = argv[0]; + char *lastdot = strrchr(filename, '.'); + if (lastdot == NULL || strcmp(lastdot, ".spl") != 0) { + bail_with_error("filename argument must end in .spl not %s", + filename); + } + char boffilename[BUFSIZ]; + strncpy(boffilename, filename, BUFSIZ); + int len = strlen(boffilename); + assert(len < BUFSIZ); // it has to fit! + strncpy(boffilename+(len-4), ".bof", 5); + // debug_print("Output going to %s\n", boffilename); + + if (lexer_print_output) { + // with the lexer_print_output option, nothing else is done + lexer_init(filename); + lexer_output(); + return EXIT_SUCCESS; + } + + // otherwise (if not lexer_print_outout) continue to parse etc. + block_t progast = parseProgram(filename); + + if (parser_unparse) { + unparseProgram(stdout, progast); + } + + // build symbol table and... + symtab_initialize(); + // check for duplicate declarations + // and record id-use information in the AST + scope_check_program(&progast); + + if (parser_unparse) { + return EXIT_SUCCESS; + } + + // generate code from the ASTs + gen_code_initialize(); + BOFFILE bf = bof_write_open(boffilename); + gen_code_program(bf, progast); + + return EXIT_SUCCESS; +} diff --git a/FromGithub/compiler_main.o b/FromGithub/compiler_main.o new file mode 100644 index 0000000000000000000000000000000000000000..b165041be282f928e2dd7ab902fb116b02e60ab3 GIT binary patch literal 22312 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 +#include +#include +#include "file_location.h" +#include "utilities.h" + +// Requires: filename != NULL +// Return a (pointer to a) fresh file_location with the given +// information +file_location *file_location_make(const char *filename, + unsigned int line) +{ + file_location *ret = (file_location *) malloc(sizeof(file_location)); + if (ret == NULL) { + bail_with_error("Could not allocate space for a file_location!"); + } + ret->filename = filename; + ret->line = line; + return ret; +} + +// Requires: fl != NULL +// Return a (pointer to a) fresh copy of fl +file_location *file_location_copy(file_location *fl) +{ + file_location *ret = (file_location *) malloc(sizeof(file_location)); + if (ret == NULL) { + bail_with_error("Could not allocate space for a file_location!"); + } + ret->filename = fl->filename; + ret->line = fl->line; + return ret; +} diff --git a/FromGithub/file_location.h b/FromGithub/file_location.h new file mode 100644 index 0000000..603b398 --- /dev/null +++ b/FromGithub/file_location.h @@ -0,0 +1,21 @@ +/* $Id: file_location.h,v 1.2 2023/11/13 05:13:48 leavens Exp $ */ +#ifndef _FILE_LOCATION_H +#define _FILE_LOCATION_H + +// location in a source file (useful for error messages) +typedef struct { + const char *filename; + unsigned int line; // of first token +} file_location; + +// Requires: filename != NULL +// Return a (pointer to a) fresh file_location with the given +// information +extern file_location *file_location_make(const char *filename, + unsigned int line); + +// Requires: fl != NULL +// Return a (pointer to a) fresh copy of fl +extern file_location *file_location_copy(file_location *fl); + +#endif diff --git a/FromGithub/file_location.o b/FromGithub/file_location.o new file mode 100644 index 0000000000000000000000000000000000000000..e39fffd2e5becf5d558497d63af30b0c737b6ff8 GIT binary patch literal 5160 zcmb_fU2Ggz6}~g;an@OTz5ZzulS0N&Qd+XRUe~0F+oYyek`1M46k!omp=EY<_D9{F zF|#uysYv@!1hq^>Dui03Ac}b50fayT@c^P~D^->Hg7|yl0V$OX^a02NQ9&x_yL0Y( ze7&hu#F2LHIp6u6d(WMF_vurgK5ZI?P-KXcVp~$E5bgXnzarTcv0v;HHzz;z&RTWj zt?Dyx+trP$TO09>Ul&Nf1)J)|saw@&uHF*yZ1p)SL0dm#S>PDeT?B?2y zjq_P>Z@j99eLpd`s+%%i5_W4di8%<3^g^r#akpXnL1a7KZs0nRXZP0~*Rz{JXghYZ z)Aec+?*#t5=+l%~!pOo?K0XL8O+QTuCiu*6_Ak?5WcNTC8?icmM3S5ZH55jm+gmV4 z$DSr818L6`*o4ncUn4dvMmA|Mj8Q0ZUjaWNqsm0)SmyHtjc1LdKEsqcHaAR}aRRO* zvlG9g!9s$(m;_|qY39FAAwihvrmGch5aI2a`O- z6q5subv$?X+}W8#R~W#Q9xyVl9Qd+yoTAdQ>itmJ^zE!E!4b?B{kRz=hex^z2Ou%u zqMt>5becxPF#esNz<>p&A2Eky=aDGMG!B`Qvey*CBODSkEkleY6%ddaH>@MsvX%X# zWyaP__M|oWBWwJ-mhs4a){&bG?y~K^YDbrfw7~J@V#|-ql}fqe zyWP0q32CT=9n(Vz-&<}ATG58rEVV@(b-JCXeeP)5k(WS1sGr;1Kf1Wc#uROi55gv+BwbNKje@CP`K@>fUFdv{3k;o!d4 zch-*Hs>!V=#2nXyHQ!6W|Gb+J>H^`Thh9+lF@Qv{$80IQ2argQBM*1N^*CRb*1O}V zl|e1(RaGkh9B1f5>@Uw=;(^0g)xD4P3TIJ#fEo1J;Db*5y^O;?-8JPDj=Xf{NjkwJ z?12|qeni9n!twcFpQ_zjl7so@UCc~QgZfRpqC4gUkn zKi2S%u>H?9{3zqU((rSPzoOwYjQ?K4ea7F`@PD%WFCJlrbyWML%zkQJ)Os&7uI$-e zJgV8Nd462O)jX@-Kz#JNBDJ^m_#b8i*rPwOuR({CVbHftmhaW@Z?L?i;n!I{uHipq z`J{&blI2wmf0N~^hO6~>RKx$wvYK!GeQnlbP4H8+!i>U|zbN&u^ynr+V-zN1TXCV+ zbxM(UITEFY6FH((@ApM13=%LabSxN`}Ex)vo~bzg`n`hZ(%2DK$}GUk#hTmw5hO;=(Y0SR<8R z&EKa8(_<1OzQcY8G^HjA{KeHV`2UP2bOAz&blZ!h8&?0yc;ck|Q9oWuum6jL=`rE? z7U%yqgcRwvUD6H9zs~vp&c4WxdxW0LgauQwT~FYYCO8#%IZ9nEy?_RQy#& z*?uTLHNJQo|3C4DM1QAA`Kj@Hq*Q#`ZVZ=&A*9>>glu4{_kV%?Z7qhHKLx)*3}Wj3 z3+#{nNR#gW8YzdZ-xv5Irq%`PH%&j~ulj#jZsdEG^B?0EzJst~{Rd3{cEJB-PIL}J WiuC!zJ$#t|HLm}+DPOR<|9=5kg;-wz literal 0 HcmV?d00001 diff --git a/FromGithub/gen_code.c b/FromGithub/gen_code.c new file mode 100644 index 0000000..60b5162 --- /dev/null +++ b/FromGithub/gen_code.c @@ -0,0 +1,634 @@ +#include "gen_code.h" + +#include +#include +#include "spl.tab.h" +#include "ast.h" +#include "code.h" +#include "id_use.h" +#include "literal_table.h" +#include "gen_code.h" +#include "utilities.h" +#include "regname.h" + +#define STACK_SPACE 4096 + +// Initialize the code generator +void gen_code_initialize() +{ + literal_table_initialize(); +} + +// Requires: bf if open for writing in binary +// and prior to this scope checking and type checking have been done. +// Write all the instructions in cs to bf in order +static void gen_code_output_seq(BOFFILE bf, code_seq cs) +{ + while (!code_seq_is_empty(cs)) + { + bin_instr_t inst = code_seq_first(cs)->instr; + instruction_write_bin_instr(bf, inst); + cs = code_seq_rest(cs); + } +} + +// Return a header appropriate for the give code +static BOFHeader gen_code_program_header(code_seq main_cs) +{ + BOFHeader ret; + + // magic + strncpy(ret.magic, "MAGIC", 4); + + // text start address + ret.text_start_address = 0; + + // text length + ret.text_length = code_seq_size(main_cs) * BYTES_PER_WORD; + + // data start address + int dsa = MAX(ret.text_length, 1024) + BYTES_PER_WORD; + ret.data_start_address = dsa; + + // data length + ret.data_length = literal_table_size() * BYTES_PER_WORD; + + // stack bottom address + int sba = dsa + ret.data_length + STACK_SPACE; + ret.stack_bottom_addr = sba; + + return ret; +} + +static void gen_code_output_literals(BOFFILE bf) +{ + literal_table_start_iteration(); + while (literal_table_iteration_has_next()) + { + word_type w = literal_table_iteration_next(); + // debug_print("Writing literal %f to BOF file\n", w); + bof_write_word(bf, w); + } + literal_table_end_iteration(); +} + +// Requires: bf is open for writing in binary +// Write the program's BOFFILE to bf +static void gen_code_output_program(BOFFILE bf, code_seq main_cs) +{ + BOFHeader bfh = gen_code_program_header(main_cs); + bof_write_header(bf, bfh); + gen_code_output_seq(bf, main_cs); + gen_code_output_literals(bf); + bof_close(bf); +} + +// Requires: bf if open for writing in binary +// Generate code for prog into bf +void gen_code_program(BOFFILE bf, block_t prog) +{ + code_seq main_cs; + // We want to make the main program's AR look like all blocks... so: + // allocate space and initialize any variables + main_cs = gen_code_seq_var_decls(prog.var_decls);//gen_code_seq_var_decls’ + //int vars_len_in_bytes = (code_seq_size(main_cs) / 2) * BYTES_PER_WORD; variable that has been muted based on line 101-104 + + // there is no static link for the program as a whole, + // so nothing to do for saving FP into A0 as would be done for a block + code_seq_concat(&main_cs, code_save_registers_for_AR()); + code_seq_concat(&main_cs, + gen_code_seq_stmts(prog.stmts));// Big difference from the Float calculator. Use of gen_code_stmts rather than gen_code_seq_stmt + /*code_seq_concat(&main_cs, + code_restore_registers_from_AR()); + code_seq_concat(&main_cs, + code_deallocate_stack_space(vars_len_in_bytes));*/ // this section has been muted + code_seq_add_to_end(&main_cs, code_exit(0));// Over here I added a 0 into the code_ exit because of the instruction exit offset should be 0 + gen_code_output_program(bf, main_cs); +} + +// Generate code for the var_decls_t vds to out +// There are 2 instructions generated for each identifier declared +// (one to allocate space and another to initialize that space) +code_seq gen_code_seq_var_decls(var_decls_t vds)// the name was modified +{ + code_seq ret = code_seq_empty(); + var_decl_t *vdp = vds.var_decls; + while (vdp != NULL) + { + // generate these in reverse order, + // so the addressing offsets work properly + code_seq temp = gen_code_seq_var_decl(*vdp); // Store the result in a variable + code_seq_concat(&temp, ret); // Just call code_seq_concat without assigning to ret + vdp = vdp->next; + } + return ret; +} + +// Generate code for a single , vd, +// There are 2 instructions generated for each identifier declared +// (one to allocate space and another to initialize that space) +code_seq gen_code_seq_var_decl(var_decl_t vd) +{ + return /*gen_code_idents(vd.idents, vd.type);*/ gen_code_seq_idents(vd.ident_list ); +} + +// Generate code for the identififers in idents with type vt +// in reverse order (so the first declared are allocated last). +// There are 2 instructions generated for each identifier declared +// (one to allocate space and another to initialize that space) +code_seq gen_code_seq_idents(ident_list_t idl) // this was changed+ modified compared to float calculato + +{ + /* code_seq ret = code_seq_empty(); + //ident_t *idp = idents.idents; + ident_t *idp = idl.start; + while (idp != NULL) + { + code_seq alloc_and_init = code_seq_singleton(code_addi(SP, SP, -BYTES_PER_WORD)); + switch (vt) + { + case float_te: + alloc_and_init = code_seq_add_to_end(alloc_and_init, + code_fsw(SP, 0, 0)); + break; + case bool_te: + alloc_and_init = code_seq_add_to_end(alloc_and_init, + code_sw(SP, 0, 0)); + break; + default: + bail_with_error("Bad type_exp_e (%d) passed to gen_code_idents!", + vt); + break; + } + // Generate these in revese order, + // so addressing works propertly + ret = code_seq_concat(alloc_and_init, ret); + idp = idp->next; + } + return ret;*/ + code_seq gen_code_seq_idents(ident_list_t idl) + { + code_seq ret = code_seq_empty(); // Start with an empty code sequence + ident_t *idp = idl.start; // Start from the first identifier in the list + + while (idp != NULL) + { + // Generate the code to allocate space for this identifier + // We assume you have a function gen_code_seq_alloc_ident that generates allocation code + code_seq alloc_and_init = gen_code_seq_alloc_ident(idp); + + // Add the allocation and initialization code in reverse order + code_seq_concat(&alloc_and_init, ret); // Concatenate the allocation code with the result + + // Move to the next identifier in the list + idp = idp->next; + } + + return ret; + } +} + +// Generate code for stmt +code_seq gen_code_stmt(stmt_t stmt) +{ + switch (stmt.stmt_kind) + { + case assign_stmt: + return /*gen_code_assign_stmt(stmt.data.assign_stmt);*/ gen_code_seq_assign_stmt(stmt.data.assign_stmt); + break; + /*case begin_stmt: + return gen_code_begin_stmt(stmt.data.begin_stmt); + break;*/ + case call_stmt: + return gen_code_seq_call_stmt(stmt.data.call_stmt); + break; + case if_stmt: + return gen_code_seq_if_stmt(stmt.data.if_stmt); + break; + case while_stmt: + return gen_code_seq_while_stmt(stmt.data.while_stmt); + break; + case read_stmt: + return gen_code_seq_read_stmt(stmt.data.read_stmt); + break; + case write_stmt: + return gen_code_write_stmt(stmt.data.write_stmt); + break; + default: + bail_with_error("Call to gen_code_stmt with an AST that is not a statement!"); + break; + } + // The following can never execute, but this quiets gcc's warning + return code_seq_empty(); +} + +// Generate code for stmt +code_seq gen_code_seq_assign_stmt(assign_stmt_t stmt) +{ + // can't call gen_code_ident, + // since stmt.name is not an ident_t + code_seq ret; + // put value of expression in $v0 + ret = gen_code_expr(*(stmt.expr)); + assert(stmt.idu != NULL); + assert(id_use_get_attrs(stmt.idu) != NULL); + type_exp_e typ = id_use_get_attrs(stmt.idu)->type; + ret = code_seq_concat(ret, code_pop_stack_into_reg(V0, typ)); + // put frame pointer from the lexical address of the name + // (using stmt.idu) into $t9 + ret = code_seq_concat(ret, + code_compute_fp(T9, stmt.idu->levelsOutward)); + unsigned int offset_count = id_use_get_attrs(stmt.idu)->offset_count; + assert(offset_count <= USHRT_MAX); // it has to fit! + switch (id_use_get_attrs(stmt.idu)->type) + { + case float_te: + ret = code_seq_add_to_end(ret, + code_fsw(T9, V0, offset_count)); + break; + case bool_te: + ret = code_seq_add_to_end(ret, + code_sw(T9, V0, offset_count)); + break; + default: + bail_with_error("Bad var_type (%d) for ident in assignment stmt!", + id_use_get_attrs(stmt.idu)->type); + break; + } + return ret; +} +// Generate code for stmt +code_seq gen_code_seq_call_stmt(call_stmt_t stmt) +{ + // can't call gen_code_ident, + // since stmt.name is not an ident_t + code_seq ret; + ret = gen_code_expr(*(stmt.expr)); + return ret; +} + +// Generate code for stmt +code_seq gen_code_begin_stmt(begin_stmt_t stmt) +{ + code_seq ret; + // allocate space and initialize any variables in block + ret = gen_code_var_decls(stmt.var_decls); + int vars_len_in_bytes = (code_seq_size(ret) / 2) * BYTES_PER_WORD; + // in FLOAT, surrounding scope's base is FP, so that is the static link + ret = code_seq_add_to_end(ret, code_add(0, FP, A0)); + ret = code_seq_concat(ret, code_save_registers_for_AR()); + ret = code_seq_concat(ret, gen_code_seq_stmts(stmt.stmts)); + ret = code_seq_concat(ret, code_restore_registers_from_AR()); + ret = code_seq_concat(ret, code_deallocate_stack_space(vars_len_in_bytes)); + return ret; +} + +// Generate code for the list of statments given by stmts +code_seq gen_code_seq_stmts(stmts_t stmts) +{ + code_seq ret = code_seq_empty(); + stmt_t *sp = stmts.stmts; + while (sp != NULL) + { + ret = code_seq_concat(ret, gen_code_stmt(*sp)); + sp = sp->next; + } + return ret; +} + +// Generate code for stmt +code_seq gen_code_seq_while_stmt(while_stmt_t stmt) +{ + // can't call gen_code_ident, + // since stmt.name is not an ident_t + code_seq ret; + ret = gen_code_expr(*(stmt.expr)); + return ret; +} + +// Generate code for the if-statment given by stmt +code_seq gen_code_if_stmt(if_stmt_t stmt) +{ + // put truth value of stmt.expr in $v0 + code_seq ret = gen_code_expr(stmt.expr); + ret = code_seq_concat(ret, code_pop_stack_into_reg(V0, bool_te)); + code_seq cbody = gen_code_stmt(*(stmt.body)); + int cbody_len = code_seq_size(cbody); + // skip over body if $v0 contains false + ret = code_seq_add_to_end(ret, + code_beq(V0, 0, cbody_len)); + return code_seq_concat(ret, cbody); +} + +// Generate code for the read statment given by stmt +code_seq gen_code_read_stmt(read_stmt_t stmt) +{ + // put number read into $v0 + code_seq ret = code_seq_singleton(code_rch()); + // put frame pointer from the lexical address of the name + // (using stmt.idu) into $t9 + assert(stmt.idu != NULL); + ret = code_seq_concat(ret, + code_compute_fp(T9, stmt.idu->levelsOutward)); + assert(id_use_get_attrs(stmt.idu) != NULL); + unsigned int offset_count = id_use_get_attrs(stmt.idu)->offset_count; + assert(offset_count <= USHRT_MAX); // it has to fit! + ret = code_seq_add_to_end(ret, + code_seq_singleton(code_fsw(T9, V0, offset_count))); + return ret; +} + +// Generate code for the write statment given by stmt. +code_seq gen_code_write_stmt(write_stmt_t stmt) +{ + // put the result into $a0 to get ready for PCH + code_seq ret = gen_code_expr(stmt.expr); + ret = code_seq_concat(ret, code_pop_stack_into_reg(A0, float_te)); + ret = code_seq_add_to_end(ret, code_pflt()); + return ret; +} + +// Generate code for the expression exp +// putting the result on top of the stack, +// and using V0 and AT as temporary registers +// May also modify SP, HI,LO when executed +code_seq gen_code_expr(expr_t exp) +{ + switch (exp.expr_kind) + { + case expr_bin_op: + return gen_code_binary_op_expr(exp.data.binary); + break; + case expr_ident: + return gen_code_ident(exp.data.ident); + break; + case expr_number: + return gen_code_number(exp.data.number); + break; + case expr_logical_not: + return gen_code_logical_not_expr(*(exp.data.logical_not)); + break; + default: + bail_with_error("Unexpected expr_kind_e (%d) in gen_code_expr", + exp.expr_kind); + break; + } + // never happens, but suppresses a warning from gcc + return code_seq_empty(); +} + +// Generate code for the expression exp +// putting the result on top of the stack, +// and using V0 and AT as temporary registers +// May also modify SP, HI,LO when executed +code_seq gen_code_binary_op_expr(binary_op_expr_t exp) +{ + // put the values of the two subexpressions on the stack + code_seq ret = gen_code_expr(*(exp.expr1)); + ret = code_seq_concat(ret, gen_code_expr(*(exp.expr2))); + // check the types match + type_exp_e t1 = ast_expr_type(*(exp.expr1)); + assert(ast_expr_type(*(exp.expr2)) == t1); + // do the operation, putting the result on the stack + ret = code_seq_concat(ret, gen_code_op(exp.op, t1)); + return ret; +} + +// Generate code to apply op to the +// 2nd from top and top of the stack, +// putting the result on top of the stack in their place, +// and using V0 and AT as temporary registers +// Modifies SP when executed +code_seq gen_code_op(token_t op, type_exp_e typ) +{ + switch (op.code) + { + case eqsym: + case neqsym: + case ltsym: + case leqsym: + case gtsym: + case geqsym: + return gen_code_rel_op(op, typ); + break; + case plussym: + case minussym: + case multsym: + case divsym: + assert(typ == float_te); + return gen_code_arith_op(op); + break; + default: + bail_with_error("Unknown token code (%d) in gen_code_op", + op.code); + break; + } + return code_seq_empty(); +} + +// Generate code to apply the floating-point arith_op to the +// 2nd from top and top of the stack, +// putting the result on top of the stack in their place, +// and using V0 and AT as temporary registers +// Also modifies SP when executed +code_seq gen_code_arith_op(token_t arith_op) +{ + // load top of the stack (the second operand) into AT + code_seq ret = code_pop_stack_into_reg(AT, float_te); + // load next element of the stack into V0 + ret = code_seq_concat(ret, code_pop_stack_into_reg(V0, float_te)); + + code_seq do_op = code_seq_empty(); + switch (arith_op.code) + { + case plussym: + do_op = code_seq_add_to_end(do_op, code_fadd(V0, AT, V0)); + break; + case minussym: + do_op = code_seq_add_to_end(do_op, code_fsub(V0, AT, V0)); + break; + case multsym: + do_op = code_seq_add_to_end(do_op, code_fmul(V0, AT, V0)); + break; + case divsym: + do_op = code_seq_add_to_end(do_op, code_fdiv(V0, AT, V0)); + break; + default: + bail_with_error("Unexpected arithOp (%d) in gen_code_arith_op", + arith_op.code); + break; + } + do_op = code_seq_concat(do_op, code_push_reg_on_stack(V0, float_te)); + return code_seq_concat(ret, do_op); +} + +// Generate code for the rel_op +// applied to 2nd from top and top of the stack, +// putting the result on top of the stack in their place, +// and using V0 and AT as temporary registers +// Also modifies SP when executed +code_seq gen_code_rel_op(token_t rel_op, type_exp_e typ) +{ + // load top of the stack (the second operand) into AT + code_seq ret = code_pop_stack_into_reg(AT, typ); + // load next element of the stack into V0 + ret = code_seq_concat(ret, code_pop_stack_into_reg(V0, typ)); + + // start out by doing the comparison + // and skipping the next 2 instructions if it's true + code_seq do_op = code_seq_empty(); + switch (rel_op.code) + { + case eqsym: + if (typ == float_te) + { + do_op = code_seq_singleton(code_bfeq(V0, AT, 2)); + } + else + { + do_op = code_seq_singleton(code_beq(V0, AT, 2)); + } + break; + case neqsym: + if (typ == float_te) + { + do_op = code_seq_singleton(code_bfne(V0, AT, 2)); + } + else + { + do_op = code_seq_singleton(code_bne(V0, AT, 2)); + } + break; + case ltsym: + if (typ == float_te) + { + do_op = code_seq_singleton(code_fsub(V0, AT, V0)); + do_op = code_seq_add_to_end(do_op, code_bfltz(V0, 2)); + } + else + { + do_op = code_seq_singleton(code_sub(V0, AT, V0)); + do_op = code_seq_add_to_end(do_op, code_bltz(V0, 2)); + } + break; + case leqsym: + if (typ == float_te) + { + do_op = code_seq_singleton(code_fsub(V0, AT, V0)); + do_op = code_seq_add_to_end(do_op, code_bflez(V0, 2)); + } + else + { + do_op = code_seq_singleton(code_sub(V0, AT, V0)); + do_op = code_seq_add_to_end(do_op, code_blez(V0, 2)); + } + break; + case gtsym: + if (typ == float_te) + { + do_op = code_seq_singleton(code_fsub(V0, AT, V0)); + do_op = code_seq_add_to_end(do_op, code_bfgtz(V0, 2)); + } + else + { + do_op = code_seq_singleton(code_sub(V0, AT, V0)); + do_op = code_seq_add_to_end(do_op, code_bgtz(V0, 2)); + } + break; + case geqsym: + if (typ == float_te) + { + do_op = code_seq_singleton(code_fsub(V0, AT, V0)); + do_op = code_seq_add_to_end(do_op, code_bfgez(V0, 2)); + } + else + { + do_op = code_seq_singleton(code_sub(V0, AT, V0)); + do_op = code_seq_add_to_end(do_op, code_bgez(V0, 2)); + } + break; + default: + bail_with_error("Unknown token code (%d) in gen_code_rel_op", + rel_op.code); + break; + } + ret = code_seq_concat(ret, do_op); + // rest of the code for the comparisons + ret = code_seq_add_to_end(ret, code_add(0, 0, AT)); // put false in AT + ret = code_seq_add_to_end(ret, code_beq(0, 0, 1)); // skip next instr + ret = code_seq_add_to_end(ret, code_addi(0, AT, 1)); // put true in AT + ret = code_seq_concat(ret, code_push_reg_on_stack(AT, bool_te)); + return ret; +} + +// Generate code to put the value of the given identifier +// on top of the stack +// Modifies T9, V0, and SP when executed +code_seq gen_code_ident(ident_t id) +{ + assert(id.idu != NULL); + code_seq ret = code_compute_fp(T9, id.idu->levelsOutward); + assert(id_use_get_attrs(id.idu) != NULL); + unsigned int offset_count = id_use_get_attrs(id.idu)->offset_count; + assert(offset_count <= USHRT_MAX); // it has to fit! + type_exp_e typ = id_use_get_attrs(id.idu)->type; + if (typ == float_te) + { + ret = code_seq_add_to_end(ret, + code_flw(T9, V0, offset_count)); + } + else + { + ret = code_seq_add_to_end(ret, + code_lw(T9, V0, offset_count)); + } + return code_seq_concat(ret, code_push_reg_on_stack(V0, typ)); +} + +// Generate code to put the given number on top of the stack +// Modifies V0 when executed +code_seq gen_code_number(number_t num) +{ + unsigned int global_offset = literal_table_lookup(num.text, num.value); + return code_seq_concat(code_seq_singleton(code_flw(GP, V0, global_offset)), + code_push_reg_on_stack(V0, float_te)); +} + +// Generate code for the expression exp +// putting the result on top of the stack, +// and using V0 and AT as temporary registers +// May also modify SP, HI,LO when executed +code_seq gen_code_logical_not_expr(expr_t exp) +{ + code_seq ret = gen_code_expr(exp); + ret = code_seq_concat(ret, code_pop_stack_into_reg(AT, bool_te)); + // if 0 skip next 2 instructions + ret = code_seq_add_to_end(ret, code_beq(0, AT, 2)); + // it was 1, so put 0 in AT + ret = code_seq_add_to_end(ret, code_add(0, 0, AT)); + // and skip the next instruction + ret = code_seq_add_to_end(ret, code_beq(0, 0, 1)); + // put 1 in AT + ret = code_seq_add_to_end(ret, code_addi(0, AT, 1)); + // push the result on the stack + ret = code_seq_concat(ret, code_push_reg_on_stack(AT, bool_te)); + return ret; +} +/*Brand new function responsible for generating the code sequence that allocates space for a variable (identifier) on the stack and initializes it with a default value, typically 0 */ +code_seq gen_code_seq_alloc_ident(ident_t *idp) +{ + code_seq ret = code_seq_empty(); // Start with an empty code sequence + + // Assuming that each identifier requires 4 bytes of space + // (adjust this based on your VM's size for each variable) + int size_of_ident = 4; // Adjust the size if necessary + + // 1. Allocate space by subtracting from the stack pointer (SP) + ret = code_seq_add_to_end(ret, code_addi(SP, SP, -size_of_ident)); + + // 2. Initialize the identifier (e.g., set it to 0) + // Assuming that a register 'zero' holds the value 0 + ret = code_seq_add_to_end(ret, code_swr(SP, zero, 0)); // Store 0 into the allocated space + + return ret; // Return the code sequence +} \ No newline at end of file diff --git a/FromGithub/gen_code.h b/FromGithub/gen_code.h new file mode 100644 index 0000000..04b3301 --- /dev/null +++ b/FromGithub/gen_code.h @@ -0,0 +1,103 @@ +#ifndef _GEN_code_seq_H +#define _GEN_code_seq_H +#include +#include "ast.h" +#include "bof.h" +#include "instruction.h" +#include "code_seq.h" + +// Initialize the code_seq generator +extern void gen_code_seq_initialize(); + +// Requires: bf if open for writing in binary +// Generate code_seq for the given AST +extern void gen_code_seq_program(BOFFILE bf, block_t prog); + +// Requires: bf if open for writing in binary +// Generate code_seq for prog into bf +extern void gen_code_seq_program(BOFFILE bf, block_t prog); + +// Generate code_seq for the var_decls_t vds to out +// There are 2 instructions generated for each identifier declared +// (one to allocate space and another to initialize that space) +extern code_seq gen_code_seq_var_decls(var_decls_t vds); + +// Generate code_seq for a single , vd, +// There are 2 instructions generated for each identifier declared +// (one to allocate space and another to initialize that space) +extern code_seq gen_code_seq_var_decl(var_decl_t vd); + +// Generate code_seq for the identifiers in idents with type t +// in reverse order (so the first declared are allocated last). +// There are 2 instructions generated for each identifier declared +// (one to allocate space and another to initialize that space) +extern code_seq gen_code_seq_idents(ident_list_t idents); + +// Generate code_seq for stmt +extern code_seq gen_code_seq_stmt(stmt_t stmt); + +// Generate code_seq for assign stmt +extern code_seq gen_code_seq_assign_stmt(assign_stmt_t stmt); + +//Generate code_seq for call stmt +extern code_seq gen_code_seq_call_stmt(call_stmt_t stmt); + +// Generate code_seq for the list of statements given by stmts to out +extern code_seq gen_code_seq_stmts(stmts_t stmts); + +//Generate code_seq for while stmt +extern code_seq gen_code_seq_while_stmt(while_stmt_t stmt); + +// Generate code_seq for the if-statement given by stmt +extern code_seq gen_code_seq_if_stmt(if_stmt_t stmt); + +// Generate code_seq for the read statement given by stmt +extern code_seq gen_code_seq_read_stmt(read_stmt_t stmt); + +// Generate code_seq for the write statement given by stmt. +extern code_seq gen_code_seq_print_stmt(print_stmt_t stmt); + +// Generate code_seq for the expression exp +// putting the result on top of the stack, +// and using V0 and AT as temporary registers +// May also modify SP, HI,LO when executed +extern code_seq gen_code_seq_expr(expr_t exp); + +// Generate code_seq for the expression exp +// putting the result on top of the stack, +// and using V0 and AT as temporary registers +// May also modify SP, HI,LO when executed +extern code_seq gen_code_seq_binary_op_expr(binary_op_expr_t exp); + +// Generate code_seq to apply the floating-point arith_op to the +// 2nd from top and top of the stack, +// putting the result on top of the stack in their place, +// and using V0 and AT as temporary registers +// Also modifies SP when executed +extern code_seq gen_code_seq_arith_op(token_t arith_op); + +// Generate code_seq for the rel_op +// applied to 2nd from top and top of the stack, +// putting the result on top of the stack in their place, +// and using V0 and AT as temporary registers +// Also modifies SP when executed +extern code_seq gen_code_seq_rel_op(token_t rel_op); + +// Generate code_seq to put the value of the given identifier +// on top of the stack +// Modifies T9, V0, and SP when executed +extern code_seq gen_code_seq_ident(ident_t id); + +// Generate code_seq to put the given number on top of the stack +// Modifies V0 when executed +extern code_seq gen_code_seq_number(number_t num); + +// Generate code_seq for the expression exp +// putting the result on top of the stack, +// and using V0 and AT as temporary registers +// May also modify SP, HI,LO when executed +extern code_seq gen_code_seq_logical_not_expr(expr_t exp); + +extern code_seq gen_code_seq_alloc_ident(ident_t *idp); + +#endif \ No newline at end of file diff --git a/FromGithub/hw4-gtest0.spl b/FromGithub/hw4-gtest0.spl new file mode 100644 index 0000000..6b4ea60 --- /dev/null +++ b/FromGithub/hw4-gtest0.spl @@ -0,0 +1,3 @@ +% $Id: hw4-gtest0.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ +begin % no output +end. diff --git a/FromGithub/hw4-gtest1.spl b/FromGithub/hw4-gtest1.spl new file mode 100644 index 0000000..d3bcf55 --- /dev/null +++ b/FromGithub/hw4-gtest1.spl @@ -0,0 +1,4 @@ +% $Id: hw4-gtest1.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ +begin + print 8 % prints 8 +end. diff --git a/FromGithub/hw4-gtest2.spl b/FromGithub/hw4-gtest2.spl new file mode 100644 index 0000000..0983b7c --- /dev/null +++ b/FromGithub/hw4-gtest2.spl @@ -0,0 +1,7 @@ +% $Id: hw4-gtest2.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ +begin + if 3 < 4 + then print 10 % prints 10 + else print 11 + end +end. diff --git a/FromGithub/hw4-gtest3.spl b/FromGithub/hw4-gtest3.spl new file mode 100644 index 0000000..9286896 --- /dev/null +++ b/FromGithub/hw4-gtest3.spl @@ -0,0 +1,5 @@ +% $Id: hw4-gtest3.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ +begin + const first = 33; + print first % prints 33 +end. diff --git a/FromGithub/hw4-gtest5.spl b/FromGithub/hw4-gtest5.spl new file mode 100644 index 0000000..29d190a --- /dev/null +++ b/FromGithub/hw4-gtest5.spl @@ -0,0 +1,5 @@ +% $Id: hw4-gtest5.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ +begin + print 340; % prints 340 + print 2 % prints 2 +end. diff --git a/FromGithub/hw4-gtest6.spl b/FromGithub/hw4-gtest6.spl new file mode 100644 index 0000000..4ccd48d --- /dev/null +++ b/FromGithub/hw4-gtest6.spl @@ -0,0 +1,8 @@ +% $Id: hw4-gtest6.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ +begin + const three = 3; + var four; + four := 4; + print three; % prints 3 + print four % prints 4 +end. diff --git a/FromGithub/hw4-gtest7.spl b/FromGithub/hw4-gtest7.spl new file mode 100644 index 0000000..c146bd8 --- /dev/null +++ b/FromGithub/hw4-gtest7.spl @@ -0,0 +1,10 @@ +% $Id: hw4-gtest7.spl,v 1.3 2024/11/11 21:31:41 leavens Exp $ +begin + var x; + var y; + x := -3; + y := 4; + print y; % prints 4 + y := x; + print y % prints -3 +end. diff --git a/FromGithub/hw4-gtest8.spl b/FromGithub/hw4-gtest8.spl new file mode 100644 index 0000000..c859aad --- /dev/null +++ b/FromGithub/hw4-gtest8.spl @@ -0,0 +1,10 @@ +% $Id: hw4-gtest8.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ +begin + const aConst = 77; + var aVar, anotherVar; + print aConst; % prints 77 + aVar := aConst; + print aVar; % prints 77 + anotherVar := aConst + 1; + print anotherVar % prints 78 +end. diff --git a/FromGithub/hw4-gtest9.spl b/FromGithub/hw4-gtest9.spl new file mode 100644 index 0000000..984d6e8 --- /dev/null +++ b/FromGithub/hw4-gtest9.spl @@ -0,0 +1,7 @@ +% $Id: hw4-gtest9.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ +begin + if 0 == 0 + then print 111 % prints 111 + else print 0 + end +end. diff --git a/FromGithub/hw4-gtestA.spl b/FromGithub/hw4-gtestA.spl new file mode 100644 index 0000000..d8ef0fe --- /dev/null +++ b/FromGithub/hw4-gtestA.spl @@ -0,0 +1,8 @@ +% $Id: hw4-gtestA.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ +begin + const false = 0, true = 1; + if false < true + then print true % prints 1 + else print false + end +end. diff --git a/FromGithub/hw4-gtestB.spl b/FromGithub/hw4-gtestB.spl new file mode 100644 index 0000000..6d8619e --- /dev/null +++ b/FromGithub/hw4-gtestB.spl @@ -0,0 +1,16 @@ +% $Id: hw4-gtestB.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ +begin + const zero = 0, one = 1, two = 2; + const three = 3; + var v1, v2; + var v3, v4; + print zero; % prints 0 + print one; % prints 1 + print two; % prints 2 + v1 := one; + print v1; % prints 1 + v2 := two / one; + print v2; % prints 2 + v3 := (two + 1 + 0) / one; + print v3 % prints 3 +end. diff --git a/FromGithub/hw4-gtestC.spl b/FromGithub/hw4-gtestC.spl new file mode 100644 index 0000000..f3855f4 --- /dev/null +++ b/FromGithub/hw4-gtestC.spl @@ -0,0 +1,12 @@ +% $Id: hw4-gtestC.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ +begin + const t = 3, f = 4; + const z = 0; + const two = 2; + var a; + var b; + if t <= f + then print t + z % prints 3 + else print two + end +end. diff --git a/FromGithub/hw4-gtestD.spl b/FromGithub/hw4-gtestD.spl new file mode 100644 index 0000000..19ad9c2 --- /dev/null +++ b/FromGithub/hw4-gtestD.spl @@ -0,0 +1,9 @@ +% $Id: hw4-gtestD.spl,v 1.2 2024/09/17 21:48:53 leavens Exp $ +begin + const t = 3, f = 4; + const z = 0; + const two = 2; + var a; + var b; + if t >= f then print t else print two end % prints 2 +end. diff --git a/FromGithub/hw4-gtestE.spl b/FromGithub/hw4-gtestE.spl new file mode 100644 index 0000000..9e6315b --- /dev/null +++ b/FromGithub/hw4-gtestE.spl @@ -0,0 +1,9 @@ +% $Id: hw4-gtestE.spl,v 1.2 2024/09/17 21:48:53 leavens Exp $ +begin + const t = 3, f = 4; + const z = 0; + const two = 2; + var a; + var b; + if t > f then print t else print f end % prints 4 +end. diff --git a/FromGithub/hw4-gtestF.spl b/FromGithub/hw4-gtestF.spl new file mode 100644 index 0000000..0f5918d --- /dev/null +++ b/FromGithub/hw4-gtestF.spl @@ -0,0 +1,9 @@ +% $Id: hw4-gtestF.spl,v 1.2 2024/09/17 21:48:53 leavens Exp $ +begin + const t = 3, f = 4; + const z = 0; + const two = 2; + var a; + var b; + if t < f then print t else print z end % prints 3 +end. diff --git a/FromGithub/hw4-gtestG.spl b/FromGithub/hw4-gtestG.spl new file mode 100644 index 0000000..7281190 --- /dev/null +++ b/FromGithub/hw4-gtestG.spl @@ -0,0 +1,9 @@ +% $Id: hw4-gtestG.spl,v 1.2 2024/09/17 21:48:53 leavens Exp $ +begin + const t = 3, f = 4; + const z = 0; + const two = 2; + var a; + var b; + if t != f then print t else print z end % prints 3 +end. diff --git a/FromGithub/hw4-gtestH.spl b/FromGithub/hw4-gtestH.spl new file mode 100644 index 0000000..f934733 --- /dev/null +++ b/FromGithub/hw4-gtestH.spl @@ -0,0 +1,9 @@ +% $Id: hw4-gtestH.spl,v 1.3 2024/11/10 12:54:14 leavens Exp $ +begin + const t = 3, f = 4; + const z = 0; + const two = 2; + var a; + var b; + if t == f then print t else print z end % prints 0 +end. diff --git a/FromGithub/hw4-gtestI.spl b/FromGithub/hw4-gtestI.spl new file mode 100644 index 0000000..dc9c7e3 --- /dev/null +++ b/FromGithub/hw4-gtestI.spl @@ -0,0 +1,31 @@ +% $Id: hw4-gtestI.spl,v 1.4 2024/11/10 12:54:14 leavens Exp $ +begin + const z = 0; + const two = 2; + var t; + var a, b, c; + var d, e, f; + t := 3; f := 4; + print a; % prints 0 + a := t + d; + print a; % prints 3 + print d; % prints 0 + if t == f then print t else print z end; % prints 0 + if t != f then print f else print two end; % prints 4 + if t < f then print two * two * two + 100 % prints 108 + else print t * t end; + if t >= f then print f / f + else print two * t + f end; % prints 10 (i.e., 6+4) + if divisible z by 2 then print f - t else print z end; % prints 1 + if t > f then b := two; c := f * f + b; print c; print b + else print two / two % prints 1 + end; + if t <= f + then + d := t; e := f; + f := d; t := e; + print t; % prints 4 + print f % prints 3 + else print z + (t-t)/t + end +end. diff --git a/FromGithub/hw4-gtestJ.spl b/FromGithub/hw4-gtestJ.spl new file mode 100644 index 0000000..bd34d85 --- /dev/null +++ b/FromGithub/hw4-gtestJ.spl @@ -0,0 +1,26 @@ +% $Id: hw4-gtestJ.spl,v 1.3 2024/11/11 21:36:18 leavens Exp $ +begin + const ten = 10; + const fifty = 50; + var x, y, z, w; + var a, b, c; + print z; % prints 0 + if ten <= fifty + then + x := 10 + 25; + print x; % prints 35 + y := x + 10; + print y; % prints 45 + z := y + (y-x); + print z; % prints 55 + if (z + 0*9999) > fifty % should be true + then + w := ten * x + y + z / 11; + print w % prints 400 + else + print z / 5 + ten + end + else + print a + end +end. diff --git a/FromGithub/hw4-gtestK.spl b/FromGithub/hw4-gtestK.spl new file mode 100644 index 0000000..fe14aa9 --- /dev/null +++ b/FromGithub/hw4-gtestK.spl @@ -0,0 +1,8 @@ +% $Id: hw4-gtestK.spl,v 1.3 2024/11/10 13:11:33 leavens Exp $ +begin + while 0 < 0 + do + print 0 + end; + print 1 % prints 1 +end. diff --git a/FromGithub/hw4-gtestL.spl b/FromGithub/hw4-gtestL.spl new file mode 100644 index 0000000..3acdd06 --- /dev/null +++ b/FromGithub/hw4-gtestL.spl @@ -0,0 +1,22 @@ +% $Id: hw4-gtestL.spl,v 1.2 2024/09/17 21:48:53 leavens Exp $ +begin + const two = 2; + const three = 3; + var i; + print three; % prints 3 + i := two * three - (two * three - three * two); + while i > (two - two) + do + print i; % prints 6, then 5, 4, 3, 2, 1 + i := i - (three - two + 0 * 5021 * 6414) + end; + if i < 0 + then if i > 0 + then print 0 + else print 0 + end + else if i == 0 + then print (three - two) % prints 1 + end + end +end. diff --git a/FromGithub/hw4-gtestM.spl b/FromGithub/hw4-gtestM.spl new file mode 100644 index 0000000..269503f --- /dev/null +++ b/FromGithub/hw4-gtestM.spl @@ -0,0 +1,18 @@ +% $Id: hw4-gtestM.spl,v 1.2 2024/09/17 21:48:53 leavens Exp $ +begin + const seven = 7; + var x; + begin + print seven; % prints 7 + x := seven / ((100 * 100) / (100 * 100)); + while x > 1 + do + print x; % prints 7, 11, 17, 26, 13, 20, 10, 5, 8, 4, 2 + if divisible x by 2 + then x := x / 2 + else x := (3 * x + 1) / 2 + end + end; + print x + (seven - seven + (6 - (5+1)) * 3402) % prints 1 + end +end. diff --git a/FromGithub/hw4-gtestN.spl b/FromGithub/hw4-gtestN.spl new file mode 100644 index 0000000..f2eb3e2 --- /dev/null +++ b/FromGithub/hw4-gtestN.spl @@ -0,0 +1,25 @@ +% $Id: hw4-gtestN.spl,v 1.4 2024/11/11 18:56:53 leavens Exp $ +% various statments +begin + const pi = 31, e = 3; + var x, y, z; + begin + x := 3*4-2/5; % x is 12 = 12-0 + if x > 0 + then x := y+1 % x is 1 + else + x := 1; + y := z + end; + while x <= 10 + do + x := x+1 + end; + print x; % prints 11 + print y+2; % prints 2 + if divisible y by 2 + then y := y / 2 + 3 % y is 3 + end; + print y % prints 3 + end +end. diff --git a/FromGithub/hw4-gtestO.spl b/FromGithub/hw4-gtestO.spl new file mode 100644 index 0000000..89de84c --- /dev/null +++ b/FromGithub/hw4-gtestO.spl @@ -0,0 +1,15 @@ +% $Id: hw4-gtestO.spl,v 1.2 2024/09/17 21:48:53 leavens Exp $ +begin +var x; + begin + x := 2-1; + if x >= 1 + then print x % prints 1 + end; + while x <= 10 + do + x := x+1 + end; + print x % prints 11 + end +end. diff --git a/FromGithub/hw4-gtestP.spl b/FromGithub/hw4-gtestP.spl new file mode 100644 index 0000000..0551727 --- /dev/null +++ b/FromGithub/hw4-gtestP.spl @@ -0,0 +1,29 @@ +% $Id: hw4-gtestP.spl,v 1.4 2024/11/10 12:54:14 leavens Exp $ +begin + const a = 1, b = 3; + const c = 4, d = 6; + var aVar, anotherVar; + var x; + begin + aVar := -1; + anotherVar := aVar - 2 - 3/1 - 6*aVar; + if anotherVar >= aVar + then + print 32; % prints 32 + print 10; % prints 10 + anotherVar := anotherVar / 12 + 2; + while (anotherVar*2) < 3 + do + begin end; + anotherVar := 0 + end + else + if 3 < 2 + then + if 7 > 5 then x := 3 end + else x := 2 * 3 - 5/4; + print x + end + end + end +end. diff --git a/FromGithub/hw4-gtestQ.spl b/FromGithub/hw4-gtestQ.spl new file mode 100644 index 0000000..0c0d1ba --- /dev/null +++ b/FromGithub/hw4-gtestQ.spl @@ -0,0 +1,9 @@ +% $Id: hw4-gtestQ.spl,v 1.1 2024/11/12 02:04:20 leavens Exp $ +begin + if divisible 33 by 3 + then + print 86 % prints 86 + else + print 55 + end +end. diff --git a/FromGithub/hw4-gtestR.spl b/FromGithub/hw4-gtestR.spl new file mode 100644 index 0000000..509dbd3 --- /dev/null +++ b/FromGithub/hw4-gtestR.spl @@ -0,0 +1,9 @@ +% $Id: hw4-gtestR.spl,v 1.1 2024/11/12 02:04:20 leavens Exp $ +begin + if divisible 8 by 3 + then + print 1 + else + print 99 % prints 99 + end +end. diff --git a/FromGithub/hw4-gtestS.spl b/FromGithub/hw4-gtestS.spl new file mode 100644 index 0000000..0c92456 --- /dev/null +++ b/FromGithub/hw4-gtestS.spl @@ -0,0 +1,11 @@ +% $Id: hw4-gtestS.spl,v 1.1 2024/11/12 02:04:20 leavens Exp $ +begin + var ff; + ff := 44; + if divisible ff by 11 + then + print 23 % prints 23 + else + print 97 + end +end. diff --git a/FromGithub/hw4-gtestT.spl b/FromGithub/hw4-gtestT.spl new file mode 100644 index 0000000..3d44f3b --- /dev/null +++ b/FromGithub/hw4-gtestT.spl @@ -0,0 +1,16 @@ +% $Id: hw4-gtestT.spl,v 1.1 2024/11/12 02:04:20 leavens Exp $ +begin + const seventeen = 17; + begin + var seventeen2; + begin + seventeen2 := seventeen * seventeen; + if divisible seventeen2 by 11 + then + print 86 + else + print 42 % prints 42 + end + end + end +end. diff --git a/FromGithub/hw4-read-test0.spl b/FromGithub/hw4-read-test0.spl new file mode 100644 index 0000000..65fc010 --- /dev/null +++ b/FromGithub/hw4-read-test0.spl @@ -0,0 +1,8 @@ +% $Id: hw4-read-test0.spl,v 1.2 2024/09/17 21:48:53 leavens Exp $ +begin + var c; + begin + read c; + print c + end +end. diff --git a/FromGithub/hw4-read-test1.spl b/FromGithub/hw4-read-test1.spl new file mode 100644 index 0000000..6f5c77c --- /dev/null +++ b/FromGithub/hw4-read-test1.spl @@ -0,0 +1,12 @@ +% $Id: hw4-read-test1.spl,v 1.2 2024/09/17 21:48:53 leavens Exp $ +begin + var rd; + begin + read rd; + while rd > 0 + do + print rd; + read rd + end + end +end. diff --git a/FromGithub/hw4-vmtest0.spl b/FromGithub/hw4-vmtest0.spl new file mode 100644 index 0000000..593a2fe --- /dev/null +++ b/FromGithub/hw4-vmtest0.spl @@ -0,0 +1,3 @@ +% $Id: hw4-vmtest0.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ +begin +end. diff --git a/FromGithub/hw4-vmtest1.spl b/FromGithub/hw4-vmtest1.spl new file mode 100644 index 0000000..441be3d --- /dev/null +++ b/FromGithub/hw4-vmtest1.spl @@ -0,0 +1,4 @@ +% $Id: hw4-vmtest1.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ +begin + print 10 % prints 10 +end. diff --git a/FromGithub/hw4-vmtest2.spl b/FromGithub/hw4-vmtest2.spl new file mode 100644 index 0000000..c565076 --- /dev/null +++ b/FromGithub/hw4-vmtest2.spl @@ -0,0 +1,8 @@ +% $Id: hw4-vmtest2.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ +begin + var x; + begin + x := 5; + print x % prints 5 + end +end. diff --git a/FromGithub/hw4-vmtest3.spl b/FromGithub/hw4-vmtest3.spl new file mode 100644 index 0000000..e4d53e4 --- /dev/null +++ b/FromGithub/hw4-vmtest3.spl @@ -0,0 +1,9 @@ +% $Id: hw4-vmtest3.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ +begin + const five = 5; + var x; + begin + x := five; + print x % prints 5 + end +end. diff --git a/FromGithub/hw4-vmtest4.spl b/FromGithub/hw4-vmtest4.spl new file mode 100644 index 0000000..ba0010c --- /dev/null +++ b/FromGithub/hw4-vmtest4.spl @@ -0,0 +1,5 @@ +% $Id: hw4-vmtest4.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ +begin + begin end; + begin end +end. diff --git a/FromGithub/hw4-vmtest5.spl b/FromGithub/hw4-vmtest5.spl new file mode 100644 index 0000000..e1b38a8 --- /dev/null +++ b/FromGithub/hw4-vmtest5.spl @@ -0,0 +1,10 @@ +% $Id: hw4-vmtest5.spl,v 1.6 2024/09/17 21:48:53 leavens Exp $ +begin + var x, y; + begin + y := 33; + print y; % prints 33 + x := y + 22; + print x % prints 55 + end +end. diff --git a/FromGithub/hw4-vmtest6.spl b/FromGithub/hw4-vmtest6.spl new file mode 100644 index 0000000..e301d66 --- /dev/null +++ b/FromGithub/hw4-vmtest6.spl @@ -0,0 +1,13 @@ +% $Id: hw4-vmtest6.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ +begin + const nl = 10, y = 121; + var x, z, q; + begin + x := nl+1+0-0*10/10; + print x; % prints 11 + z := x - x + y - (1 - 2 + 1); + print z + q; % prints 121 + q := x / z; + print q-0-0 % prints 0 + end +end. diff --git a/FromGithub/hw4-vmtest7.spl b/FromGithub/hw4-vmtest7.spl new file mode 100644 index 0000000..70ef3b2 --- /dev/null +++ b/FromGithub/hw4-vmtest7.spl @@ -0,0 +1,13 @@ +% $Id: hw4-vmtest7.spl,v 1.4 2024/09/17 21:48:53 leavens Exp $ +begin + const Y = 89, N = 78, nl =10; + begin + if 99 > 86 + then + print Y % prints 89 + else + print N + end; + print nl % prints 10 + end +end. diff --git a/FromGithub/hw4-vmtest8.spl b/FromGithub/hw4-vmtest8.spl new file mode 100644 index 0000000..cb29722 --- /dev/null +++ b/FromGithub/hw4-vmtest8.spl @@ -0,0 +1,14 @@ +% $Id: hw4-vmtest8.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ +begin + var x, y; + begin + if 99 < 86 + then + x := +72 + else + y := 1 + end; + print x; % prints 0 + print y % prints 1 + end +end. diff --git a/FromGithub/hw4-vmtest9.spl b/FromGithub/hw4-vmtest9.spl new file mode 100644 index 0000000..4a2bda4 --- /dev/null +++ b/FromGithub/hw4-vmtest9.spl @@ -0,0 +1,22 @@ +% $Id: hw4-vmtest9.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ +begin + const q = 7; + var x, y, z; + begin + x := 86; + print x; % prints 86 + y := 99; + print y; % prints 99 + z := 1001; + print z; % prints 1001 + print (x-y); % prints -13 + if divisible (x-y) by 2 + then + y := y-1*z; + print y + else + x := z+1+q; + print x % prints 1009 + end + end +end. diff --git a/FromGithub/hw4-vmtestA.spl b/FromGithub/hw4-vmtestA.spl new file mode 100644 index 0000000..951a479 --- /dev/null +++ b/FromGithub/hw4-vmtestA.spl @@ -0,0 +1,16 @@ +% $Id: hw4-vmtestA.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ +begin + const achar = 97; + var c; + var i; + begin + i := 0; + while i < 10 + do + c := achar + i; + % prints 98, 99, 100, 101, 102, 103, 104, 105, 106, 107 + print c+1; + i := i+1 + end + end +end. diff --git a/FromGithub/hw4-vmtestB.spl b/FromGithub/hw4-vmtestB.spl new file mode 100644 index 0000000..aa1930b --- /dev/null +++ b/FromGithub/hw4-vmtestB.spl @@ -0,0 +1,7 @@ +% $Id: hw4-vmtestB.spl,v 1.2 2024/09/17 21:48:53 leavens Exp $ +begin + const c = 32; + const five = 5, three = 3; + var x, y, z; + var i, j, k; +end. diff --git a/FromGithub/hw4-vmtestC.spl b/FromGithub/hw4-vmtestC.spl new file mode 100644 index 0000000..cb97c57 --- /dev/null +++ b/FromGithub/hw4-vmtestC.spl @@ -0,0 +1,22 @@ +% $Id: hw4-vmtestC.spl,v 1.3 2024/09/17 21:48:53 leavens Exp $ +begin + const c = 48; + var i, j; + begin + i := 0; + print i; % prints 0 + j := c; + print j; % prints 48 + while i <= 1 + do + print c+i+4; % prints 52, 53 + while j < c+i+4 + do + print j; % prints 48, 49, 50, 51, 52 + j := j+1 + end; + i := i+1 + end; + print i % prints 2 + end +end. diff --git a/FromGithub/id_attrs.c b/FromGithub/id_attrs.c new file mode 100644 index 0000000..3224a36 --- /dev/null +++ b/FromGithub/id_attrs.c @@ -0,0 +1,50 @@ +/* $Id: id_attrs.c,v 1.10 2023/11/17 21:56:45 leavens Exp $ */ +// Attributes of identifiers in the symbol table +#include +#include +#include "utilities.h" +#include "id_attrs.h" + +// Return a freshly allocated id_attrs struct +// with its field file_loc set to floc, kind set to k, +// and its offset_count set to ofst_cnt. +// If there is no space, bail with an error message, +// so this should never return NULL. +id_attrs *id_attrs_create(file_location floc, id_kind k, + unsigned int ofst_cnt) +{ + id_attrs *ret = (id_attrs *)malloc(sizeof(id_attrs)); + if (ret == NULL) { + bail_with_error("No space to allocate id_attrs!"); + } + ret->file_loc = floc; + ret->kind = k; + ret->offset_count = ofst_cnt; + return ret; +} + +// Return a freshly allocated id_attrs struct for a procedure +// declared at floc. +// If there is no space, bail with an error message, +// so this should never return NULL. +extern id_attrs *id_attrs_proc_create(file_location floc) +{ + id_attrs *ret = (id_attrs *)malloc(sizeof(id_attrs)); + if (ret == NULL) { + bail_with_error("No space to allocate id_attrs!"); + } + ret->file_loc = floc; + ret->kind = procedure_idk; + return ret; +} + + +// Return a lowercase version of the kind's name as a string +// (i.e. if k == variable_idk, return "variable" +// else if k == constant_idk, return "constant", +// else if k == procedure_idk, return "procedure") +const char *id_attrs_id_kind_string(id_kind k) +{ + static const char *kind_names[3] = {"constant", "variable", "procedure"}; + return kind_names[k]; +} diff --git a/FromGithub/id_attrs.h b/FromGithub/id_attrs.h new file mode 100644 index 0000000..74779aa --- /dev/null +++ b/FromGithub/id_attrs.h @@ -0,0 +1,39 @@ +/* $Id: id_attrs.h,v 1.11 2024/10/23 13:06:37 leavens Exp $ */ +#ifndef _ID_ATTRS_H +#define _ID_ATTRS_H +#include "file_location.h" + +// kinds of entries in the symbol table +typedef enum {constant_idk, variable_idk, procedure_idk} id_kind; + +// attributes of identifiers in the symbol table +typedef struct { + // file_loc is the source file location of the identifier's declaration + file_location file_loc; + id_kind kind; // kind of identifier + // offset_count is the number of constant or variable decls before this one + // in this scope + unsigned int offset_count; +} id_attrs; + +// Return a freshly allocated id_attrs struct +// with its field file_loc set to floc, kind set to k, +// and its offset_count set to ofst_cnt. +// If there is no space, bail with an error message, +// so this should never return NULL. +extern id_attrs *id_attrs_create(file_location floc, id_kind k, + unsigned int ofst_cnt); + +// Return a freshly allocated id_attrs struct for a procedure +// declared at floc. +// If there is no space, bail with an error message, +// so this should never return NULL. +extern id_attrs *id_attrs_proc_create(file_location floc); + +// Return a lowercase version of the kind's name as a string +// (i.e. if k == variable_idk, return "variable" +// else if k == constant_idk, return "constant", +// else if k == procedure_idk, return "procedure") +extern const char *id_attrs_id_kind_string(id_kind k); + +#endif diff --git a/FromGithub/id_attrs.o b/FromGithub/id_attrs.o new file mode 100644 index 0000000000000000000000000000000000000000..b064c73a2dbd44bc67f7a076d023fbdc06dc2084 GIT binary patch literal 6464 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 KM4h3n`u`WgHvwn> literal 0 HcmV?d00001 diff --git a/FromGithub/id_use.c b/FromGithub/id_use.c new file mode 100644 index 0000000..b322bee --- /dev/null +++ b/FromGithub/id_use.c @@ -0,0 +1,47 @@ +/* $Id: id_use.c,v 1.10 2024/10/23 13:13:07 leavens Exp $ */ +#include +#include "machine_types.h" +#include "id_use.h" +#include "utilities.h" + +// Requires: attrs != NULL +// Return a (pointer to a fresh) id_use struct containing the attributes +// given by attrs and the information about the number of lexical levels +// outward from the current scope where the declaration was found. +// If there is no space, bail with an error message, +// so this should never return NULL. +extern id_use *id_use_create(id_attrs *attrs, unsigned int levelsOut) +{ + id_use *ret = (id_use *)malloc(sizeof(id_use)); + if (ret == NULL) { + bail_with_error("No space to allocate id_use!"); + } + ret->attrs = attrs; + ret->levelsOutward = levelsOut; + // Shouldn't create a label for procedures here! + // A label should only be created when creating the proc_decl's AST! + return ret; +} + +// Requires: idu != NULL +// Return a pointer to the attributes of this id_use +// and the result will never be NULL +id_attrs *id_use_get_attrs(id_use *idu) +{ + assert(idu != NULL); + return idu->attrs; +} + + +// Requires: idu != NULL +// Return (a pointer to) the lexical address for idu. +lexical_address *id_use_2_lexical_address(id_use *idu) +{ + lexical_address *ret = (lexical_address *)malloc(sizeof(lexical_address)); + if (ret == NULL) { + bail_with_error("No space to allocate lexical_address!"); + } + ret->levelsOutward = idu->levelsOutward; + ret->offsetInAR = idu->attrs->offset_count; + return ret; +} diff --git a/FromGithub/id_use.h b/FromGithub/id_use.h new file mode 100644 index 0000000..03d570e --- /dev/null +++ b/FromGithub/id_use.h @@ -0,0 +1,32 @@ +/* $Id: id_use.h,v 1.7 2024/10/23 13:13:07 leavens Exp $ */ +#ifndef _ID_USE_H +#define _ID_USE_H +#include "id_attrs.h" +// we'll use lexical_address in HW4 +#include "lexical_address.h" + +// An id_use struct gives all the information from +// a lookup in the symbol table for a name: +// the (pointer to the) id_attrs (attributes) +// and the number of lexical levels out +// from the current scope where the name was declared. +typedef struct { + id_attrs *attrs; + unsigned int levelsOutward; +} id_use; + +// Requires: attrs != NULL +// Return a (pointer to a fresh) id_use struct containing the attributes +// given by attrs and the information about the number of lexical levels +// outward from the current scope where the declaration was found. +extern id_use *id_use_create(id_attrs *attrs, unsigned int levelsOut); + +// Requires: idu != NULL +// Return a pointer to the attributes of this id_use +// and the result will never be NULL +extern id_attrs *id_use_get_attrs(id_use *idu); + +// Requires: idu != NULL +// Return (a pointer to) the lexical address for idu. +extern lexical_address *id_use_2_lexical_address(id_use *idu); +#endif diff --git a/FromGithub/id_use.o b/FromGithub/id_use.o new file mode 100644 index 0000000000000000000000000000000000000000..25c3320ef9d5978841c9b969abe7cdd93ee4638d GIT binary patch literal 6760 zcmb_geQaA-6~FJ<&vEKFapE*>)|NU`*JT6SNtSh8X-lRkt+SOhlmt51L0)m;*TK#)dt!sKDud|1QZGQW8$BIB7p>`np8o>IOpDT zoR?cy2*i>6?m55nanJoa?>;|0b>xs~7=prawZf`c zo$bf$R%W9rNgT*bGvl4IOHRgbX6#z6S+ad6Q!N(*&lwV`&6R)&GD8P4GxJA|pc7DA zznZgLE!nlAT`s$h=M90K3Q=5g{G#pqt|xwI3SkKY$03sV*ny8Q-3$p4<=(ZJAMlywdOrIvkc(Dt)VL5#lk4s@cPJ(%HPA1xu zr0yWZE|EwaOhmdtn-r1meTk1I9!yN9_aLZf7_aaVUb5!tzICq_$cfx|;%faBK_H4Y{cV5-J}{iGm2$f=i-k>k62@QcRa zewjw!MqGhuoZkMH#!}fU-Db$LdpbQnh}jGn#&jBc*)jw}&O<+2TVC3jA>v1H4d92T zGfd&)5XP^7V1eytpfwERpWR7pU{~SW0GOTYn*=b^*lG4`0!Alv&`GADas zq+#ud=dJi}Ei$ zzO{M3)fIq?X+oB_6w8yx3=~bGppTWxKRnIv^U({u}7RBQ1v8lPaM~jE%XC~*S zkIoc}VzF9t8g|_gT0!P&JXX{d3wE_uJX7^6MaOlUuBcTTjyUBuOHMg(onp0oQq-D_ zrHp)F5-L>%qI`H}J~KJ`KxT9_H=Y~GWb1y=a1Jav4acpPK(yUb<-qdZJ=s0une0*~ z>-psaC9uyf+TPhlsp2*p&A`hBjWaOhtZy&W91oP9Z0!}ANUI05ay z>}Vjx(Wl17awFsS5DX_f3O~Hx;XMKNEY_Ge5aaT|*F@voF<~sHjBQ;V@vlHt*bX-M zLy|9#sqWMl%*kZToB<1^+ppB3fGz8vmTKwy80qEPk@e=BG9aDaU_pwCzki_PC`a1f zbP<=gpbaiq>i>TM6}w=nuvhn-G(CSLU)TMBH)#&Q3m9`Q2zWv z#v28$k52ak&<>vh9OJORoO{4NbsKwpx1;?xphe=F3LQ5%N^J^iZbUncRD1QRsWyD* zvU|&^g$-T2wfaIHgEAYnKXG<%exT^XgyUNW_bB6g3CF#Qw-&}fM>yN_o_j{axxeQ$ z{7#a;N-f66)#La-2;t#8uM*Dvj+6YGkbO8$I5LuOUxs&|{3HMjakP02en|2<3N7OD zqKF{SfNEMe>+T>N&kyFrbT2U&M_uI=kPqS5?{1P0X!!5xhVY1nm|B=g;S!@gmvXtJ(9pVn4Qjp6njf>|Y}Jpoa5#o7C_hkzCO5H%R`t zhQCd6xc=a{-X)yZjr05y;rxDJ{I7)D)G~g9DxlJWVZP{4}mWtKJViRm6Z!avk&S@}1 zXM$Y2vE-oZIwn7ONDuw7H^N0Jmzwpu1K0mt1HMIaaCL-l5%@MC8ScY5_)0kiH}ta< z*Qpd2UHl09zfcCE;GFY5=b#hB++=`Sv<=fX5b#|-5e9*OQ~u>4#NP<-hZcSDoq&X2 z_egjy5XUneru}+Hq|{;jp2wK~tN$qYV$AT~0#Qs*M||%=42jRZk_7xKto&K#_7(Df zRST@=kLS7F{9UFC%PcB^aQ<+O^!a-jFg+$f;w1UiHKiuXd#aA1|L>^Sji3-B-S#-> z+T|aoixvB0{#ZBk{BeHum;i}5ZOEUa5F*{S2D*0r@1_1{$pQOMz)$c0JYZ*ix z9qNDdHtWZETmb8K{{NzmqHIWUS>*PG+xVMUAc1gyhl%~Ty#z|;!*)6H4`aydwyyxz z0Y7b+VubuNpbHbvA7gI;gE4jgS@K_ILuz&Zp8?)({Vu>CdPoJ;$o-E?%KltG+Vzbt tZ&Lry(114shLG-$ds43*0Eq(CFWett(&w)ilz3I|Hx#{~HWaBU}Ig literal 0 HcmV?d00001 diff --git a/FromGithub/instruction.c b/FromGithub/instruction.c new file mode 100644 index 0000000..73c9f02 --- /dev/null +++ b/FromGithub/instruction.c @@ -0,0 +1,575 @@ +// $Id: instruction.c,v 1.7 2024/11/10 21:09:43 leavens Exp $ +#include +#include +#include "bof.h" +#include "instruction.h" +#include "regname.h" +#include "utilities.h" +#include "machine_types.h" + +#define INSTR_BUF_SIZE 512 + +// the following declaration isn't in everywhere ... +extern char *strdup(const char *s); + +// space to hold one instruction's assembly language form +static char instr_buf[INSTR_BUF_SIZE]; + +// Return the instruction type of the given opcode +instr_type instruction_type(bin_instr_t i) { + switch (i.comp.op) { // need to pretend a type to read the op field + case COMP_O: + return comp_instr_type; + break; + case OTHC_O: + if (i.othc.func == SYS_F) { + return syscall_instr_type; + } else { + assert(i.othc.op != COMP_O); + assert(i.othc.func != NOP_F); + return other_comp_instr_type; + } + break; + case ADDI_O: case ANDI_O: case BORI_O: case NORI_O: case XORI_O: + case BEQ_O: case BGEZ_O: case BGTZ_O: case BLEZ_O: case BLTZ_O: + case BNE_O: + return immed_instr_type; + break; + case JMPA_O: case CALL_O: case RTN_O: + return jump_instr_type; + break; + default: + return error_instr_type; + break; + } +} + +// Requires: bof is open for reading in binary +// Read a single instruction (in binary) from bf and return it, +// but exit with an error if there is a problem. +bin_instr_t instruction_read(BOFFILE bf) +{ + bin_instr_t bi; + size_t rd = fread(&bi, sizeof(bi), 1, bf.fileptr); + if (rd != 1) { + bail_with_error("Cannot read instruction from %s (read %d instrs)", + bf.filename, rd); + } + return bi; +} + +// Requires: bf is open for writing in binary +// Write the given binary instruction to bf, +// but exit with an error if there is a problem. +static void write_bin_instr(BOFFILE bf, bin_instr_t i) +{ + size_t wr = fwrite(&i, sizeof(i), 1, bf.fileptr); + if (wr != 1) { + bail_with_error("Cannot write binary instr to %s", bf.filename); + } +} + +// Requires: bof is open for writing in binary +// Write the binary instruction bi to bf in binary, +// but exit with an error if there is a problem. +void instruction_write_bin_instr(BOFFILE bf, bin_instr_t bi) +{ + switch (instruction_type(bi)) { + case comp_instr_type: + instruction_write_compInstr(bf, bi.comp); + break; + case other_comp_instr_type: + instruction_write_otherCompInstr(bf, bi.othc); + break; + case immed_instr_type: + instruction_write_immedInstr(bf, bi.immed); + break; + case jump_instr_type: + instruction_write_jumpInstr(bf, bi.jump); + break; + case syscall_instr_type: + instruction_write_syscallInstr(bf, bi.syscall); + break; + default: + bail_with_error("Unknown instruction type in instruction_write_bin_instr (%d)", + instruction_type(bi)); + break; + } +} + + +// Requires: bof is open for writing in binary +// Write the computational instruction ci to bf in binary, +// but exit with an error if there is a problem. +void instruction_write_compInstr(BOFFILE bf, comp_instr_t ci) +{ + bin_instr_t bi; + bi.comp = ci; + assert(bi.comp.op == ci.op); + assert(bi.comp.rt == ci.rt); + assert(bi.comp.ot == ci.ot); + assert(bi.comp.rs == ci.rs); + assert(bi.comp.os == ci.os); + assert(bi.comp.func == ci.func); + assert(bi.comp.func != NOP_F || bi.comp.op == COMP_O); + write_bin_instr(bf, bi); +} + +// Requires: bof is open for writing in binary +// Write the other computational instruction oci to bf in binary, +// but exit with an error if there is a problem. +void instruction_write_otherCompInstr(BOFFILE bf, other_comp_instr_t oci) +{ + bin_instr_t bi; + bi.othc = oci; + + assert(bi.othc.op == oci.op); + assert(bi.othc.reg == oci.reg); + assert(bi.othc.offset == oci.offset); + assert(bi.othc.arg == oci.arg); + assert(bi.othc.func == oci.func); + + write_bin_instr(bf, bi); +} + +// Requires: bof is open for writing in binary +// Write the system instruction si to bf in binary, +// but exit with an error if there is a problem. +void instruction_write_syscallInstr(BOFFILE bf, syscall_instr_t si) +{ + bin_instr_t bi; + bi.syscall = si; + /* + assert(bi.syscall.op == OTHC_O); + assert(bi.syscall.reg == si.reg); + assert(bi.syscall.offset == si.offset); + assert(bi.syscall.code == si.code); + assert(bi.syscall.func == SYS_F); + */ + write_bin_instr(bf, bi); +} + +// Requires: bof is open for writing in binary +// Write the immediate instruction ii to bf in binary, +// but exit with an error if there is a problem. +void instruction_write_uimmedInstr(BOFFILE bf, uimmed_instr_t ui) +{ + bin_instr_t bi; + bi.uimmed = ui; + /* + assert(bi.uimmed.op == op); + assert(bi.uimmed.reg == ui.reg); + assert(bi.uimmed.offset == ui.offset); + assert(bi.uimmed.uimmed == ui.uimmed); + */ + write_bin_instr(bf, bi); +} + +// Requires: bof is open for writing in binary +// Write the immediate instruction ii to bf in binary, +// but exit with an error if there is a problem. +void instruction_write_immedInstr(BOFFILE bf, immed_instr_t ii) +{ + bin_instr_t bi; + bi.immed = ii; + /* + assert(bi.immed.op == op); + assert(bi.immed.reg == ii.reg); + assert(bi.immed.offset == ii.offset); + assert(bi.immed.immed == ii.immed); + */ + write_bin_instr(bf, bi); +} + +// Requires: bof is open for writing in binary +// Write the jump instruction ji with opcode op to bf in binary, +// but exit with an error if there is a problem. +void instruction_write_jumpInstr(BOFFILE bf, jump_instr_t ji) +{ + bin_instr_t bi; + bi.jump = ji; + /* + assert(bi.jump.op == op); + assert(bi.jump.addr == ji.addr); + */ + write_bin_instr(bf, bi); +} + +// Return the assembly language name (mnemonic) for bi +const char *instruction_mnemonic(bin_instr_t bi) { + switch (bi.comp.op) { // pretending a type is needed to get the op field + case COMP_O: + return instruction_compFunc2name(bi); + break; + case OTHC_O: + return instruction_otherCompFunc2name(bi); + break; + case ADDI_O: + return "ADDI"; + break; + case ANDI_O: + return "ANDI"; + break; + case BORI_O: + return "BORI"; + break; + case NORI_O: + return "NORI"; + break; + case XORI_O: + return "XORI"; + break; + case BEQ_O: + return "BEQ"; + break; + case BGEZ_O: + return "BGEZ"; + break; + case BGTZ_O: + return "BGTZ"; + break; + case BLEZ_O: + return "BLEZ"; + break; + case BLTZ_O: + return "BLTZ"; + break; + case BNE_O: + return "BNE"; + break; + case JMPA_O: + return "JMPA"; + break; + case CALL_O: + return "CALL"; + break; + case RTN_O: + return "RTN"; + break; + default: + bail_with_error("Unknown op code (%d) in instruction_mnemonic!", + bi.immed.op); + return NULL; // should never happen + } + return NULL; // should never happen +} + +static char address_comment_buf[512]; + +// return a comment string of the form +// "# target is word address %u" +// that uses the formAddress function to get the proper address +static const char *instruction_formAddress_comment(address_type addr, + address_type a) +{ + address_type actual = machine_types_formAddress(addr, a); + sprintf(address_comment_buf, "# target is word address %u", + actual); + return strdup(address_comment_buf); +} + + +// Return a string containing the assembly language form of instr, +// which is found at address addr +const char *instruction_assembly_form(address_type addr, + bin_instr_t instr) +{ + char *buf = instr_buf; + + // put in the mnemonic for the instruction + int cwr = sprintf(buf, "%s ", instruction_mnemonic(instr)); + // point buf to the null char that was printed into instr_buf + buf += cwr; + + instr_type it = instruction_type(instr); + switch (it) { + case comp_instr_type: + switch (instr.comp.func) { + case NOP_F: + // no arguments for NOP! + break; + case ADD_F: case SUB_F: case CPW_F: + case AND_F: case BOR_F: case NOR_F: case XOR_F: + case SCA_F: case LWI_F: case NEG_F: + sprintf(buf, "%s, %hd, %s, %hd", + regname_get(instr.comp.rt), + instr.comp.ot, + regname_get(instr.comp.rs), + instr.comp.os); + break; + case CPR_F: + sprintf(buf, "%s, %s", + regname_get(instr.comp.rt), + regname_get(instr.comp.rs)); + break; + case LWR_F: + sprintf(buf, "%s, %s, %hd", + regname_get(instr.comp.rt), + regname_get(instr.comp.rs), + instr.comp.os); + break; + case SWR_F: + sprintf(buf, "%s, %hd, %s", + regname_get(instr.comp.rt), + instr.comp.ot, + regname_get(instr.comp.rs)); + break; + default: + bail_with_error("Unknown computational instruction function (%d) for mnemonic %s!", + instr.comp.func, buf); + break; + } + break; + case other_comp_instr_type: + assert(instr.othc.op == OTHC_O); + switch (instr.othc.func) { + case LIT_F: + sprintf(buf, "%s, %hd, %hd", regname_get(instr.othc.reg), + instr.othc.offset, instr.othc.arg); + break; + case ARI_F: case SRI_F: + sprintf(buf, "%s, %hd", regname_get(instr.othc.reg), + instr.othc.arg); + break; + case MUL_F: case DIV_F: case CFHI_F: case CFLO_F: case JMP_F: + case CSI_F: + sprintf(buf, "%s, %hd", regname_get(instr.othc.reg), + instr.othc.offset); + break; + case SLL_F: case SRL_F: + sprintf(buf, "%s, %hd, %hu", regname_get(instr.othc.reg), + instr.othc.offset, instr.othc.arg); + break; + case JREL_F: + sprintf(buf, "%hd\t%s", instr.othc.arg, + instruction_formAddress_comment(addr, + addr+instr.othc.arg)); + break; + default: + bail_with_error("Unknown other computational instruction function (%d)!", + instr.comp.func); + break; + } + break; + case immed_instr_type: + switch (instr.immed.op) { + case ADDI_O: + sprintf(buf, "%s, %hd, %hd", regname_get(instr.immed.reg), + instr.immed.offset, instr.immed.immed); + break; + case ANDI_O: case BORI_O: case NORI_O: case XORI_O: + sprintf(buf, "%s, %hd, 0x%hx", regname_get(instr.immed.reg), + instr.immed.offset, instr.immed.immed); + break; + case BEQ_O: case BGEZ_O: case BGTZ_O: + case BLEZ_O: case BLTZ_O: case BNE_O: + sprintf(buf, "%s, %hd, %hd\t%s", regname_get(instr.immed.reg), + instr.immed.offset, instr.immed.immed, + instruction_formAddress_comment(addr, + addr+instr.immed.immed)); + break; + default: + bail_with_error("Unknown immediate type instruction opcode (%d)!", + instr.immed.op); + break; + } + break; + case jump_instr_type: + switch (instr.jump.op) { + case JMPA_O: case CALL_O: + sprintf(buf, "%u\t%s", instr.jump.addr, + instruction_formAddress_comment(addr, instr.jump.addr)); + break; + case RTN_O: + // no arguments in this case + break; + default: + bail_with_error("Unknown jump type instruction opcode (%d)!", + instr.jump.op); + break; + } + break; + case syscall_instr_type: + switch (instr.syscall.code) { + case exit_sc: + sprintf(buf, "%hd", instr.syscall.offset); + break; + case print_str_sc: case print_int_sc: + case print_char_sc: case read_char_sc: + sprintf(buf, "%s, %hd", regname_get(instr.syscall.reg), + instr.syscall.offset); + break; + case start_tracing_sc: case stop_tracing_sc: + // no arguments, so nothing to do! + break; + } + break; + default: + bail_with_error("Unknown instruction type (%d) in instruction_assembly_form!", + it); + break; + } + + return instr_buf; +} + +// Requires: out is open and writable FILE +// print the header of the instruction output table on out +void instruction_print_table_heading(FILE *out) { + fprintf(out, "%s %s\n", "Address", "Instruction"); +} + +// Requires: out is an open FILE, and instr is found at address addr. +// Print addr on out, ": ", then the instruction's symbolic +// (assembly language) form, and finally a newline character (all on one line) +void instruction_print(FILE *out, address_type addr, bin_instr_t instr) { + fprintf(out, "%8u: %s\n", addr, instruction_assembly_form(addr, instr)); +} + +// Return the mnemonic for the given system call code +const char *instruction_syscall_mnemonic(syscall_type code) +{ + switch (code) { + case exit_sc: + return "EXIT"; + break; + case print_str_sc: + return "PSTR"; + break; + case print_int_sc: + return "PINT"; + break; + case print_char_sc: + return "PCH"; + break; + case read_char_sc: + return "RCH"; + break; + case start_tracing_sc: + return "STRA"; + break; + case stop_tracing_sc: + return "NOTR"; + break; + default: + bail_with_error("Unknown code (%u) in instruction_syscall_mnemonic", + code); + return "NEVERHAPPENS"; + break; + } +} + +// Requires: instr is a SYSCALL instruction +// (i.e., instr.syscall.op == OTHC_O and instr.syscall.func == SYS_F). +// Return the code field that tells what kind of system call is being made +syscall_type instruction_syscall_number(bin_instr_t instr) { + assert(instr.syscall.op == OTHC_O && instr.syscall.func == SYS_F); + return instr.syscall.code; +} + +// Requires: bi is a computational instruction (bi.comp.op == COMP_O). +// Return a string giving the assembly language mnemonic for bi's operation +const char *instruction_compFunc2name(bin_instr_t bi) { + assert(bi.comp.op == COMP_O); + switch (bi.comp.func) { + case NOP_F: + return "NOP"; + break; + case ADD_F: + return "ADD"; + break; + case SUB_F: + return "SUB"; + break; + case CPW_F: + return "CPW"; + break; + case CPR_F: + return "CPR"; + break; + case AND_F: + return "AND"; + break; + case BOR_F: + return "BOR"; + break; + case NOR_F: + return "NOR"; + break; + case XOR_F: + return "XOR"; + break; + case LWR_F: + return "LWR"; + break; + case SWR_F: + return "SWR"; + break; + case SCA_F: + return "SCA"; + break; + case LWI_F: + return "LWI"; + break; + case NEG_F: + return "NEG"; + break; + default: + bail_with_error("Unknown function code (%d) in instruction_compFunc2name", + bi.comp.func); + break; + } + return NULL; // should never happen +} + +// Requires: bi is an other computational instruction (bi.othc.op == OTHC_O). +// Return a string giving the assembly language mnemonic for bi's operation +const char *instruction_otherCompFunc2name(bin_instr_t bi) { + assert(bi.othc.op == OTHC_O); + switch (bi.othc.func) { + case LIT_F: + return "LIT"; + break; + case ARI_F: + return "ARI"; + break; + case SRI_F: + return "SRI"; + break; + case MUL_F: + return "MUL"; + break; + case DIV_F: + return "DIV"; + break; + case CFHI_F: + return "CFHI"; + break; + case CFLO_F: + return "CFLO"; + break; + case SLL_F: + return "SLL"; + break; + case SRL_F: + return "SRL"; + break; + case JMP_F: + return "JMP"; + break; + case CSI_F: + return "CSI"; + break; + case JREL_F: + return "JREL"; + break; + case SYS_F: + return instruction_syscall_mnemonic(instruction_syscall_number(bi)); + break; + default: + bail_with_error("Unknown function code (%d) in instruction_otherCompFunc2name", + bi.comp.func); + break; + } + return NULL; // should never happen +} diff --git a/FromGithub/instruction.h b/FromGithub/instruction.h new file mode 100644 index 0000000..14c0ce7 --- /dev/null +++ b/FromGithub/instruction.h @@ -0,0 +1,178 @@ +// $Id: instruction.h,v 1.5 2024/11/10 21:09:43 leavens Exp $ +#ifndef _INSTRUCTION_H +#define _INSTRUCTION_H +#include +#include +#include "machine_types.h" +#include "bof.h" + +// op codes in binary instructions for the SSM +typedef enum {COMP_O = 0, OTHC_O = 1, ADDI_O = 2, ANDI_O = 3, BORI_O = 4, + NORI_O = 5, XORI_O = 6, + BEQ_O = 7, BGEZ_O = 8, BGTZ_O = 9, BLEZ_O = 10, BLTZ_O = 11, + BNE_O = 12, JMPA_O = 13, CALL_O = 14, RTN_O = 15 + } op_code; + +// function codes in binary instructions for the SSM (when opcode is 0) +typedef enum {NOP_F = 0, ADD_F = 1, SUB_F = 2, CPW_F = 3, CPR_F = 4, + AND_F = 5, BOR_F = 6, NOR_F = 7, XOR_F = 8, + LWR_F = 9, SWR_F = 10, SCA_F = 11, LWI_F = 12, NEG_F = 13 + } func0_code; + +// function codes in binary instructions for the SSM (when opcode is 1) +typedef enum {LIT_F = 1, ARI_F = 2, SRI_F = 3, MUL_F = 4, DIV_F = 5, + CFHI_F = 6, CFLO_F = 7, SLL_F = 8, SRL_F = 9, JMP_F = 10, + CSI_F = 11, JREL_F = 12, SYS_F = 15 + } func1_code; + +// instruction types (each is a binary instruction format) +typedef enum {comp_instr_type, other_comp_instr_type, + immed_instr_type, jump_instr_type, syscall_instr_type, + error_instr_type + } instr_type; + +// system calls +typedef enum {exit_sc = 1, print_str_sc = 2, print_int_sc = 3, + print_char_sc = 4, read_char_sc = 5, + start_tracing_sc = 2046, stop_tracing_sc = 2047 +} syscall_type; + +// computational type instructions, with opcode 0 +typedef struct { + opcode_type op : 4; + reg_num_type rt : 3; // target register + offset_type ot : 9; // offset from target register + reg_num_type rs : 3; // source register + offset_type os : 9; // offset from source register + func_type func : 4; +} comp_instr_t; + +// other computational type instructions, with opcode 1, except system calls +typedef struct { + opcode_type op : 4; + reg_num_type reg : 3; + offset_type offset : 9; + arg_type arg : 12; + func_type func : 4; +} other_comp_instr_t; + +// system call instructions, with op field 1 and func field 15 +typedef struct { + opcode_type op : 4; + reg_num_type reg : 3; + offset_type offset : 9; + syscall_type code : 12; + func_type func : 4; +} syscall_instr_t; + +// immediate operand type instructions +// with signed immediate operands +typedef struct { + opcode_type op : 4; + reg_num_type reg : 3; + offset_type offset : 9; + immediate_type immed : 16; +} immed_instr_t; + +// immediate operand type instructions +// with unsigned immediate operands +typedef struct { + opcode_type op : 4; + reg_num_type reg : 3; + offset_type offset : 9; + uimmed_type uimmed : 16; +} uimmed_instr_t; + +// jump type instructions +typedef struct { + opcode_type op : 4; + address_type addr : 28; +} jump_instr_t; + +// binary instructions of any type +typedef union { + comp_instr_t comp; + other_comp_instr_t othc; + syscall_instr_t syscall; + immed_instr_t immed; + uimmed_instr_t uimmed; + jump_instr_t jump; +} bin_instr_t; + +// Return the type of the binary instruction given +extern instr_type instruction_type(bin_instr_t i); + +// Requires: bof is open for reading in binary +// Read a single instruction (in binary) from bf and return it, +// but exit with an error if there is a problem. +extern bin_instr_t instruction_read(BOFFILE bf); + +// Requires: bof is open for writing in binary +// Write the binary instruction bi to bf in binary, +// but exit with an error if there is a problem. +extern void instruction_write_bin_instr(BOFFILE bf, bin_instr_t bi); + +// Requires: bof is open for writing in binary +// Write the computational instruction oci to bf in binary, +// but exit with an error if there is a problem. +extern void instruction_write_compInstr(BOFFILE bf, comp_instr_t oci); + +// Requires: bof is open for writing in binary +// Write the other computational instruction oci to bf in binary, +// but exit with an error if there is a problem. +extern void instruction_write_otherCompInstr(BOFFILE bf, other_comp_instr_t oci); + +// Requires: bof is open for writing in binary +// Write the system instruction si to bf in binary, +// but exit with an error if there is a problem. +extern void instruction_write_syscallInstr(BOFFILE bf, syscall_instr_t si); + +// Requires: bof is open for writing in binary +// Write the immediate instruction ii with opcode op to bf in binary, +// but exit with an error if there is a problem. +extern void instruction_write_immedInstr(BOFFILE bf, immed_instr_t ii); + +// Requires: bof is open for writing in binary +// Write the immediate instruction ii with opcode op to bf in binary, +// but exit with an error if there is a problem. +extern void instruction_write_uimmedInstr(BOFFILE bf, uimmed_instr_t ii); + +// Requires: bof is open for writing in binary +// Write the jump instruction ji with opcode op to bf in binary, +// but exit with an error if there is a problem. +extern void instruction_write_jumpInstr(BOFFILE bf, jump_instr_t ji); + +// Return the assembly language name (mnemonic) for bi +extern const char *instruction_mnemonic(bin_instr_t bi); + +// Return a string containing the assembly language form of instr, +// which is found at address addr +extern const char *instruction_assembly_form(address_type addr, + bin_instr_t instr); + +// Requires: out is open and writable FILE +// print the header of the instruction output table on out +extern void instruction_print_table_heading(FILE *out); + +// Requires: out is an open FILE, and instr is found at address addr. +// Print addr on out, ": ", then the instruction's symbolic +// (assembly language) form, and finally a newline character (all on one line) +extern void instruction_print(FILE *out, address_type addr, bin_instr_t instr); + +// Return the mnemonic for the given system call code +extern const char *instruction_syscall_mnemonic(unsigned int code); + +// Requires: instr is a SYSCALL instruction +// (i.e., instr.syscall.op == OTHC_O and instr.syscall.func == SYS_F). +// Return the code field that tells what kind of system call is being made +extern syscall_type instruction_syscall_number(bin_instr_t instr); + +// Requires: bi is a computational instruction (bi.comp.op == COMP_O). +// Return a string giving the assembly language mnemonic for bi's operation +extern const char *instruction_compFunc2name(bin_instr_t bi); + +// Requires: bi is an other computational instruction (bi.othc.op == OTHC_O). +// Return a string giving the assembly language mnemonic for bi's operation +extern const char *instruction_otherCompFunc2name(bin_instr_t bi); + +#endif diff --git a/FromGithub/instruction.o b/FromGithub/instruction.o new file mode 100644 index 0000000000000000000000000000000000000000..e8710a2d6c9a96113f612ecf9eb457cae7d7351e GIT binary patch literal 33760 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 EA1ZI|_5c6? literal 0 HcmV?d00001 diff --git a/FromGithub/lexer.c b/FromGithub/lexer.c new file mode 100644 index 0000000..7a09526 --- /dev/null +++ b/FromGithub/lexer.c @@ -0,0 +1,6 @@ +/* $Id: lexer.c,v 1.6 2024/10/23 13:38:20 leavens Exp $ */ + +#include "lexer.h" + +// All the functions declared in lexer.h are +// defined in the user code section of spl_lexer.l diff --git a/FromGithub/lexer.h b/FromGithub/lexer.h new file mode 100644 index 0000000..6b8ed5f --- /dev/null +++ b/FromGithub/lexer.h @@ -0,0 +1,39 @@ +/* $Id: lexer.h,v 1.3 2024/10/23 13:38:20 leavens Exp $ */ +#ifndef _LEXER_H +#define _LEXER_H +#include + +// Requires: fname != NULL +// Requires: fname is the name of a readable file +// Initialize the lexer and start it reading +// from the given file name +extern void lexer_init(char *fname); + +// Return the next token in the input +extern int yylex(); + +// Return the name of the current file +extern const char *lexer_filename(); + +// Return the line number of the next token +extern unsigned int lexer_line(); + +// On standard output: +// Print a message about the file name of the lexer's input +// and then print a heading for the lexer's output. +extern void lexer_print_output_header(); + +// Have any errors been noted by the lexer? +extern bool lexer_has_errors(); + +// Print information about the token t to stdout +// followed by a newline +extern void lexer_print_token(int t, unsigned int tline, + const char *txt); + +/* Read all the tokens from the input file + * and print each token on standard output + * using the format in lexer_print_token */ +extern void lexer_output(); + +#endif diff --git a/FromGithub/lexer_utilities.c b/FromGithub/lexer_utilities.c new file mode 100644 index 0000000..c79e2d6 --- /dev/null +++ b/FromGithub/lexer_utilities.c @@ -0,0 +1,8 @@ +/* $Id: lexer_utilities.c,v 1.3 2024/11/13 14:08:23 leavens Exp $ */ +#include +#include +#include +#include "lexer_utilities.h" + +/* yyerror() is defined in spl_lexer.c (which is made from spl_lexer.l) */ +/* formatted_yyerror() is defined in utilities.c */ diff --git a/FromGithub/lexer_utilities.h b/FromGithub/lexer_utilities.h new file mode 100644 index 0000000..64e10c3 --- /dev/null +++ b/FromGithub/lexer_utilities.h @@ -0,0 +1,15 @@ +/* $Id: lexer_utilities.h,v 1.1 2023/11/13 05:13:55 leavens Exp $ */ +#ifndef _LEXER_UTILITIES_H +#define _LEXER_UTILITIES_H + +// Report a syntax error on the current line on stderr. +// The output looks like: the filename, ":", the lexer's current line number, +// ": ", and then msg. +extern void yyerror(const char *filename, const char *msg); + +// Call yyerror to print an error message on stderr +// starting with the filename, ":", the lexer's current line number, ": ", +// and then the formatted message (as in sprintf) +extern void formatted_yyerror(const char *filename, const char *fmt, ...); + +#endif diff --git a/FromGithub/lexer_utilities.o b/FromGithub/lexer_utilities.o new file mode 100644 index 0000000000000000000000000000000000000000..09864d74430a024e46d8aa5c2da8350b5d070422 GIT binary patch literal 2704 zcmbtWy>Ap(5Py4X6X1d|SP%q3w;)J}VD~<9F({I)iyUwy5LieQp}^YPd%j(9_tx5d z3pSA;b!bzhN|hpiL6R~>{s2lk8j3U&G&B@s=IxBVem+1VPue##znR~>d7pQWE?>J+ za~#3V5sPBmVpNDH)7yH_s68 z?$mUmG$b;X;~1ZC&WL(_vF^@5@L zI}6froYyl4P~a@#1EpamTyq+=gXPoFY3Xb4+^v40bU{nzw+myoA9gxHtNR7Puya%J&BBMr1(q52|8K-x_}nu56wc4%owIO`Z(8^>vga+F>shey2HD?Q_#)XiE&K)9-&^=AvU#Vl z{_;&I9j7bt7{hg3u<)2{5#*a=xN#tLR?3()EjP3X2B8i`(9d%bWO5V+1KBTztBG1m z!DsZa-_PW|9qup-)llxFj1nc80zHy&O9vWKb&;4N5} zncn2$KU|&wD&7%ZN6yq^#ggTNxeem^L9BXa(c8mrLbLgwLkyn%59POkYv;sad)Ps{ zQ;MzLj>YqU_o25HQ7XSsL6?YtZx6;{t=Nv0!kjBRC%S$m|7Rpw*s&|%urZANhX@`? z7Iy4aa7?QI34+kLPOKk)hVA+XfY~_#63?-NhU;5xcI+xRCyoCvjo%_Nj*qXWJ^ngi zn3Ll`HSGuu^qK*ZJU+`G0H4I4t(Ala@8Lgw3;!qL^LxQ*cwCl06QBJo{~$iwESbml zZ=m45*x`Q>;Bg>HUO$F0pUp+zQv!ddz(XJ>?LY2`efN;^BY|^hRGM8s=AFbpX8zX+ L@n?mLs?Glo5DEMy literal 0 HcmV?d00001 diff --git a/FromGithub/lexical_address.c b/FromGithub/lexical_address.c new file mode 100644 index 0000000..e71fe4f --- /dev/null +++ b/FromGithub/lexical_address.c @@ -0,0 +1,28 @@ +/* $Id: lexical_address.c,v 1.3 2023/11/13 05:13:56 leavens Exp $ */ +#include "lexical_address.h" +#include "utilities.h" + +// Allocate and return a (fresh) lexical address +// where the levelsOutwards field is levelsOut +// and the offsetInAR field is the byte offset in the AR +lexical_address *lexical_address_create(unsigned int levelsOut, + unsigned int offset) +{ + lexical_address *ret = (lexical_address *) malloc(sizeof(lexical_address)); + if (ret == NULL) { + bail_with_error("No space to create a lexical_address!"); + } + ret->levelsOutward = levelsOut; + ret->offsetInAR = offset; + return ret; +} + +// Requires: out is not NULL and is open for writing +// Requires: la is not NULL +// Print the lexical address la in the form "(l,o)", +// where l is la->levelsOutwards and o is la->offsetInAR. +// Note: no newline or other spacing is added. +extern void lexical_address_print(FILE *out, lexical_address *la) +{ + fprintf(out, "(%d,%d)", la->levelsOutward, la->offsetInAR); +} diff --git a/FromGithub/lexical_address.h b/FromGithub/lexical_address.h new file mode 100644 index 0000000..3ff456f --- /dev/null +++ b/FromGithub/lexical_address.h @@ -0,0 +1,23 @@ +/* $Id: lexical_address.h,v 1.3 2023/11/13 05:13:56 leavens Exp $ */ +#ifndef _LEXICAL_ADDRESS_H +#define _LEXICAL_ADDRESS_H + +#include +#include + +typedef struct { + unsigned int levelsOutward; + unsigned int offsetInAR; // in bytes +} lexical_address; + +// Allocate and return a (fresh) lexical address +// where the levelsOutwards field is levelsOut +// and the offsetInAR field is the byte offset in the AR +extern lexical_address *lexical_address_create(unsigned int levelsOut, + unsigned int offset); + +// Requires: out is not NULL and is open for writing +// Requires: la is not NULL +extern void lexical_address_print(FILE *out, lexical_address *la); + +#endif diff --git a/FromGithub/literal_table.c b/FromGithub/literal_table.c new file mode 100644 index 0000000..264dd38 --- /dev/null +++ b/FromGithub/literal_table.c @@ -0,0 +1,168 @@ +#include +#include +#include +#include "literal_table.h" +#include "utilities.h" + +// constant table entries +typedef struct literal_table_entry_s +{ + struct literal_table_entry_s *next; + const char *text; + word_type value; + unsigned int offset; +} literal_table_entry_t; + +// the table of constants is a linked list of literal_table_entry_t's +// with first pointing to the first entry and last to the last one +static literal_table_entry_t *first; +static literal_table_entry_t *last; +static unsigned int next_word_offset; + +// Iteration state follows +static bool iterating; +static literal_table_entry_t *iteration_next; + +// Check the invariant +static void literal_table_okay() +{ + bool emp = literal_table_empty(); + assert(emp == (next_word_offset == 0)); + assert(emp == (first == NULL)); + assert(emp == (last == NULL)); +} + +// Return the size (in words/entries) in the literal table +unsigned int literal_table_size() +{ + return next_word_offset; +} + +// is the literal_table empty? +bool literal_table_empty() +{ + return next_word_offset == 0; +} + +// is the literal_table full? +bool literal_table_full() +{ + return false; +} + +// initialize the literal_table +void literal_table_initialize() +{ + first = NULL; + last = NULL; + next_word_offset = 0; + literal_table_okay(); + iterating = false; + iteration_next = NULL; + literal_table_okay(); +} + +// Requires: sought is the print form of value +// return the offset of sought/value if it is in the table +// otherwise return -1. +int literal_table_find_offset(const char *sought, word_type value) +{ + literal_table_okay(); + literal_table_entry_t *entry = first; + while (entry != NULL) + { + if (strcmp(entry->text, sought) == 0) + { + return entry->offset; + } + entry = entry->next; + } + return -1; +} + +// Requires: sought is the print form of value +// Return true just when sought is in the table +bool literal_table_present(const char *sought, word_type value) +{ + literal_table_okay(); + return literal_table_find_offset(sought, value) >= 0; +} + +// Return the word offset for val_string/value +// entering it in the table if it's not already present +unsigned int literal_table_lookup(const char *val_string, + word_type value) +{ + int ret = literal_table_find_offset(val_string, value); + if (ret >= 0) + { + // don't insert if it's already present + return ret; + } + // it's not already present, so insert it + literal_table_entry_t *new_entry = (literal_table_entry_t *)malloc(sizeof(literal_table_entry_t)); + new_entry->text = val_string; + new_entry->value = value; + new_entry->next = NULL; + ret = next_word_offset; + new_entry->offset = next_word_offset++; + if (new_entry == NULL) + { + bail_with_error("No space to allocate new literal table entry!"); + } + if (first == NULL) + { + first = new_entry; + last = new_entry; + } + else + { + last->next = new_entry; + last = new_entry; + } + literal_table_okay(); + return ret; +} + +// === iteration helpers === + +// Start an iteration over the literal table +// which can extract the elements +void literal_table_start_iteration() +{ + if (iterating) + { + bail_with_error("Attempt to start literal_table iterating when already iterating!"); + } + literal_table_okay(); + iterating = true; + iteration_next = first; +} + +// End the current iteration over the literal table. +void literal_table_end_iteration() +{ + iterating = false; +} + +// Is there another float in the literal table? +bool literal_table_iteration_has_next() +{ + literal_table_okay(); + bool ret = (iteration_next != NULL); + if (!ret) + { + iterating = false; + } + return ret; +} + +// Return the next float in the literal table +// and advance the iteration +word_type literal_table_iteration_next() +{ + assert(iteration_next != NULL); + float ret = iteration_next->value; + iteration_next = iteration_next->next; + return ret; +} \ No newline at end of file diff --git a/FromGithub/literal_table.h b/FromGithub/literal_table.h new file mode 100644 index 0000000..d8f3360 --- /dev/null +++ b/FromGithub/literal_table.h @@ -0,0 +1,46 @@ +#ifndef _LITERAL_TABLE_H +#define _LITERAL_TABLE_H +#include +#include "machine_types.h" + +// Return the size (in words/entries) in the literal table +extern unsigned int literal_table_size(); + +// is the literal_table empty? +extern bool literal_table_empty(); + +// is the literal_table full? +extern bool literal_table_full(); + +// initialize the literal_table +extern void literal_table_initialize(); + +// Return the offset of sought if it is in the table, +// otherwise return -1. +extern int literal_table_find_offset(const char *sought, word_type value); + +// Return true just when sought is in the table +extern bool literal_table_present(const char *sought, word_type value); + +// Return the word offset for val_string/value +// entering it in the table if it's not already present +extern unsigned int literal_table_lookup(const char *val_string, + word_type value); + +// === iteration helpers === + +// Start an iteration over the literal table +// which can extract the elements +extern void literal_table_start_iteration(); + +// End the current iteration over the literal table. +extern void literal_table_end_iteration(); + +// Is there another float in the literal table? +extern bool literal_table_iteration_has_next(); + +// Return the next word_type in the literal table +// and advance the iteration +extern word_type literal_table_iteration_next(); + +#endif \ No newline at end of file diff --git a/FromGithub/machine_types.c b/FromGithub/machine_types.c new file mode 100644 index 0000000..c370460 --- /dev/null +++ b/FromGithub/machine_types.c @@ -0,0 +1,100 @@ +// $Id: machine_types.c,v 1.2 2024/10/23 13:38:20 leavens Exp $ +#include "machine_types.h" +#include "utilities.h" + +// Return the sign-extended equivalent of i +word_type machine_types_sgnExt(immediate_type i) { + return i; // preserves the value +} + +// Return the zero-extended equivalent of i +uword_type machine_types_zeroExt(immediate_type i) { + return (uword_type) i; +} + +// Return the offset given by o, +// which is the sign extension of o +word_type machine_types_formOffset(immediate_type o) { + return machine_types_sgnExt(o); +} + +// Return an address formed by concatenating the instruction address, a, +// with the high-order (4) bits of the PC. +address_type machine_types_formAddress(address_type PC, address_type a) { + return ((0xF0000000 & PC) | (0x0FFFFFF & a)); +} + +// Check that o can be represented as an offset field in an instruction +// bail with an error message if not (so doesn't return if wrong) +void machine_types_check_fits_in_offset(word_type o) +{ + if (o > NINEBITSMAXSIGNED) { + bail_with_error("Offset is too large: %d", o); + } else if (o < NINEBITSMINSIGNED) { + bail_with_error("Offset is too small: %d", o); + } +} + +// Check that arg can be represented as an arg field in an instruction, +// bail with an error message if not (so doesn't return if wrong) +void machine_types_check_fits_in_arg(word_type arg) +{ + if (arg > TWELVEBITSMAXSIGNED) { + bail_with_error("12 bit argument is too large: %d", arg); + } else if (arg < TWELVEBITSMINSIGNED) { + bail_with_error("12 bit argument is too small: %d", arg); + } +} + +// Check that s can be represented as a shift field in an instruction, +// bail with an error message if not (so doesn't return if wrong) +void machine_types_check_fits_in_shift(word_type s) +{ + if (s > TWELVEBITSMAXUNSIGNED) { + bail_with_error("Shift is too large: %u", s); + } +} + +// Check that immed can be represented as a signed immediate field, +// bail with an error message if not (so doesn't return if wrong) +void machine_types_check_fits_in_immed(word_type immed) +{ + if (immed > SIXTEENBITSMAXSIGNED) { + bail_with_error("Immediate argument is too large: %d", + immed); + } else if (immed < SIXTEENBITSMINSIGNED) { + bail_with_error("Immediate argument is too small: %d", + immed); + } +} + +// Check that arg can be represented as unsigned immediate field, +// bail with an error message if not (so doesn't return if wrong) +void machine_types_check_fits_in_uimmed(word_type arg) +{ + if (arg > SIXTEENBITSMAXUNSIGNED) { + bail_with_error("Unsigned immediate argument is too large: %u", arg); + } +} + +// Check that addr can be represented as an address field in an instruction, +// bail with an error message if not (so doesn't return if wrong) +void machine_types_check_fits_in_addr(address_type addr) +{ + if (addr > TWENTYEIGHTBITSMAXUNSIGNED) { + bail_with_error("Address is too large: %u", addr); + } +} + +// Return the nearest multiple of BYTES_PER_WORD +// that is greater than or equal to n +int machine_types_round_up_to_wordsize(unsigned int n) +{ + int rem = n % BYTES_PER_WORD; + if (rem == 0) { + return n; + } else { + // assert(((n + (BYTES_PER_WORD - rem)) % BYTES_PER_WORD) == 0); + return n + (BYTES_PER_WORD - rem); + } +} diff --git a/FromGithub/machine_types.h b/FromGithub/machine_types.h new file mode 100644 index 0000000..3827a13 --- /dev/null +++ b/FromGithub/machine_types.h @@ -0,0 +1,94 @@ +// $Id: machine_types.h,v 1.3 2024/10/23 13:38:20 leavens Exp $ +// Machine Types for the Simplified Stack Machine (SSM) +#ifndef _MACHINE_TYPES_H +#define _MACHINE_TYPES_H + +#define BYTES_PER_WORD 4 + +// operation codes +typedef unsigned short opcode_type; + +// registers encoded in instructions +typedef unsigned short reg_num_type; + +// offset values (which are signed) encoded in instructions +typedef short offset_type; + +// function codes in computational instructions +typedef unsigned short func_type; + +// argument values (signed) encoded in instructions +typedef short arg_type; + +// shift values encoded in other computational instructions +typedef unsigned short shift_type; + +// immediate operands encoded in instructions +typedef int immediate_type; + +// unsigned immediate operands in instructions +typedef unsigned int uimmed_type; + +// addresses, assuming ints are 32 bits +typedef unsigned int address_type; + +// machine words, assuming ints are 32 bits +typedef int word_type; + +// machine words, unsigned +typedef unsigned int uword_type; + +// bytes, assuming chars are 8 bits +typedef unsigned char byte_type; + +#define NINEBITSMAXSIGNED 0xff +#define NINEBITSMINSIGNED -512 +#define TWELVEBITSMAXSIGNED 0x7ff +#define TWELVEBITSMINSIGNED -0x800 +#define TWELVEBITSMAXUNSIGNED 0xfff +#define SIXTEENBITSMAXSIGNED 0777 +#define SIXTEENBITSMINSIGNED -01000 +#define SIXTEENBITSMAXUNSIGNED 0xffff +#define TWENTYEIGHTBITSMAXUNSIGNED 0xfffffff + +// Return the sign-extended equivalent of i +extern word_type machine_types_sgnExt(immediate_type i); + +// Return the zero-extended equivalent of i +extern uword_type machine_types_zeroExt(immediate_type i); + +// Return the offset given by o, +// which is the sign extension of o +extern word_type machine_types_formOffset(immediate_type o); + +// Return an address formed by concatenating the instruction address, a, +// with the high-order (4) bits of the PC. +extern address_type machine_types_formAddress(address_type PC, address_type a); + +// Check that o can be represented as an offset field in an instruction +// bail with an error message if not (so doesn't return if wrong) +extern void machine_types_check_fits_in_offset(word_type o); + +// Check that arg can be represented as an arg field in an instruction, +// bail with an error message if not (so doesn't return if wrong) +extern void machine_types_check_fits_in_arg(word_type arg); + +// Check that arg can be represented as a shift field in an instruction, +// bail with an error message if not (so doesn't return if wrong) +extern void machine_types_check_fits_in_shift(word_type arg); + +// Check that immed can be represented as a signed immediate field, +// bail with an error message if not (so doesn't return if wrong) +extern void machine_types_check_fits_in_immed(word_type immed); + +// Check that arg can be represented as unsigned immediate field, +// bail with an error message if not (so doesn't return if wrong) +extern void machine_types_check_fits_in_uimmed(word_type arg); + +// Check that addr can be represented as an address field in an instruction, +// bail with an error message if not (so doesn't return if wrong) +extern void machine_types_check_fits_in_addr(address_type addr); + +// the following line is for the documentation +// ... +#endif diff --git a/FromGithub/machine_types.o b/FromGithub/machine_types.o new file mode 100644 index 0000000000000000000000000000000000000000..cd81590bcd9406de48dd1c8c7d1a2b37f12f7b3c GIT binary patch literal 7952 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 N>frCunNL*v{{h?%x^n;k literal 0 HcmV?d00001 diff --git a/FromGithub/parser.c b/FromGithub/parser.c new file mode 100644 index 0000000..c63d114 --- /dev/null +++ b/FromGithub/parser.c @@ -0,0 +1,22 @@ +/* $Id: parser.c,v 1.6 2023/11/13 14:08:44 leavens Exp $ */ +#include +#include +#include "lexer.h" +#include "parser.h" +#include "utilities.h" + +// Parse a PL/0 program from the given file, +// putting the AST into progast +extern int yyparse (char const *file_name); + +// Parse a PL/0 program using the tokens from the lexer, +// returning the program's AST +extern block_t parseProgram(char *file_name) +{ + lexer_init(file_name); + int rc = yyparse(file_name); + if (rc != 0) { + exit(rc); + } + return progast; +} diff --git a/FromGithub/parser.h b/FromGithub/parser.h new file mode 100644 index 0000000..c20d3d7 --- /dev/null +++ b/FromGithub/parser.h @@ -0,0 +1,13 @@ +/* $Id: parser.h,v 1.3 2023/11/13 14:08:44 leavens Exp $ */ +// This header file defines the externally-visible entry points to the parser +#ifndef _PARSER_H +#define _PARSER_H +#include "ast.h" + +extern block_t progast; + +// Parse a PL/0 program using the tokens from the lexer, +// returning the program's AST +extern block_t parseProgram(char *file_name); + +#endif diff --git a/FromGithub/parser.o b/FromGithub/parser.o new file mode 100644 index 0000000000000000000000000000000000000000..b97fd6735e43103bc306f222ec7f47c957ab1993 GIT binary patch literal 15312 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 XF~~6K_@PhZwco-1KSixZGTr{K!+TMb literal 0 HcmV?d00001 diff --git a/FromGithub/parser_types.h b/FromGithub/parser_types.h new file mode 100644 index 0000000..0e73bc6 --- /dev/null +++ b/FromGithub/parser_types.h @@ -0,0 +1,11 @@ +/* $Id: parser_types.h,v 1.1 2023/11/13 05:13:59 leavens Exp $ */ +#ifndef _PARSER_TYPES_H +#define _PARSER_TYPES_H + +#include "ast.h" + +// The type of Bison's parser stack elements (parse values) +typedef AST YYSTYPE; +#define YYSTYPE_IS_DECLARED 1 + +#endif diff --git a/FromGithub/regname.c b/FromGithub/regname.c new file mode 100644 index 0000000..a1ef0cc --- /dev/null +++ b/FromGithub/regname.c @@ -0,0 +1,12 @@ +// $Id: regname.c,v 1.2 2024/10/23 13:38:20 leavens Exp $ +#include "regname.h" + +static const char *regnames[NUM_REGISTERS] = { + "$gp", "$sp", "$fp", "$r3", "$r4", "$r5", "$r6", "$ra" }; + +// requires 0 <= n && n < NUM_REGISTERS +// Return the standard symbolic name for n +const char *regname_get(reg_num_type n) +{ + return regnames[n]; +} diff --git a/FromGithub/regname.h b/FromGithub/regname.h new file mode 100644 index 0000000..fb7b5ab --- /dev/null +++ b/FromGithub/regname.h @@ -0,0 +1,18 @@ +// $Id: regname.h,v 1.2 2024/10/23 13:38:20 leavens Exp $ +#ifndef _REGNAME_H +#define _REGNAME_H +#include "machine_types.h" + +#define NUM_REGISTERS 8 + +// some important register numbers in the ISA +#define GP 0 +#define SP 1 +#define FP 2 +#define RA 7 + +// requires 0 <= n && n < NUM_REGISTERS +// Return the standard symbolic name for n +extern const char *regname_get(reg_num_type n); +#endif + diff --git a/FromGithub/regname.o b/FromGithub/regname.o new file mode 100644 index 0000000000000000000000000000000000000000..90acec317789dcc4757fc9402f4f006610afccaa GIT binary patch literal 4208 zcmcInO>7%Q6rS-qWdfZ8%Oe=oHuYWt{7Q*)w_|3im~WR=b#bPC-A=;E{| zrsz~Zv^2WZmNA={PDP8zWU@^!R5}wG=w85VNCs_cedzirO*Gn{I}bc9HL0D%IzYACNvfEO^wmK zZ2i=@gnM*+egs*nW9P<|Dr8kUCwXA2p1=g7*+(^wBy_Tnb%2HEh-Xz!m56Jt{~a6v z!;zy#!URN>(i5qn^+Ew5%4(JGr6MJr*V)k@vpV;7Dn))>FKE_1cgeyo`EK2F+U`Q# z4OOe-)vZmVL8Ie`Nf2C*pEzyJRQ6kyialkQtztXudhX%6>$!fjMyli28i!X8Oc$r8 ztYY0N2I11-8rc_@onXzYHT;g(=?2BF_gd3iDu&Kt%MEBS2%Xx?#TCC3y0x(5lN%Y5 zI}g-aPSB9yX2+v}+Hy>n6$NU2CAEg*177gD?S*h{#Z?hfYINFe$#cU}+u1)^nVj5L zntAr*-l_6r>EzM!ROy)CX&-Nfjqakvv}@|FoVdv3-gat@rsqbp2<(PZ$7f~^S-Vd! zcD=C6l`K}eky?3Ua?&nO?O|ADXe)=Yx74WiI7-)m$=;8W4ASRLDZM(ZcWmj;eLzR# ze!|c|(NUWn9KMj68R$Dp20b{j$LY$bKW`-srW0R2%q4mPZgWYi=!S2?>3&g^4ZIo~ zP1CVYqIB;ixNRt{25!Ruq}9+Ja8zsr5-8{5ZHAO|A4HWM5M_YM1T^Hz@- zjv~q)0h5)XzQExFk{Jmuc6d5Kf^X@m%3?0K`0qAwITvLEm$(NET+WK*$J-k{)@&!0 z2A-!j$M`npz|kIOeY=6Ps_tU}^Iw0fNPdiQ#E>}vs>E>QmH5*J{x|DS8~72{PZ>C? z>O}*;&iaah)7u`=>js|2LWth&v8V=^=dY}P%p7L2=YT$89P5R>)b~@y&HBiVfxXBu zmHjvEALcl)N5gj#gwGL3@UxM&xy~4SiSc-yfrpG&nVWen#<92Y{Z)3b)~4s4cWijHVckFEExjnfWNaL%f6kmNBADEA-t6TWiS1mDGY z{Oux0HPI!InIGp1G4IwN_Z=}eogLC8zeRGK%>20Tz|8zt*{RB0m?Z-9gT#~SSLXU% zV>{FjkXb+cd^6_+m*3D4ecxm2y=i-bMw0UX!TB$<1M(xcnSX&WGbTamGX^h1iIHjR z)0m0D{3vgTd`~2VX^S8FN%Mb?Co2A!KYk0C^S?lt8IvIO3g>?TN{md~^E8%}|0_K+XNGPgsyz5E+Kk$KkhvNwoKjEL>!T)(Iib&q?p0-gd z@&AGbL>3$Hx7a_9K{jo_B@Ewv^ZtpyMPqT2`U&<635aR>U*-G<#E`k^|1;q*t@60A za=s_YJB9tjZyfO#JSjIkf8zWWFPQ!lCZ0c}G2agO-{7CP7L*v7_1j8gN&a&@|LZYd Hh^GI4y%k~_ literal 0 HcmV?d00001 diff --git a/FromGithub/scope.c b/FromGithub/scope.c new file mode 100644 index 0000000..1eca6ac --- /dev/null +++ b/FromGithub/scope.c @@ -0,0 +1,121 @@ +/* $Id: scope.c,v 1.5 2023/11/13 12:51:58 leavens Exp $ */ +#include +#include +#include +#include +#include "scope.h" +#include "utilities.h" + +// Allocate a fresh scope symbol table and return (a pointer to) it. +// Issues an error message (on stderr) if there is no space +// and exits with a failure error code in that case. +scope_t *scope_create() +{ + scope_t *new_s + = (scope_t *) malloc(sizeof(scope_t)); + if (new_s == NULL) { + bail_with_error("No space for new scope_t!"); + } + new_s->size = 0; + new_s->loc_count = 0; + for (int j = 0; j < MAX_SCOPE_SIZE; j++) { + new_s->entries[j] = NULL; + } + return new_s; +} + +// Return the number of constant and variables declarations +// that have been added to this scope. +extern unsigned int scope_loc_count(scope_t *s) +{ + return s->loc_count; +} + +// Return the current scope's size (number of declared ids). +unsigned int scope_size(scope_t *s) +{ + return s->size; +} + +// Is the current scope full? +bool scope_full(scope_t *s) +{ + return scope_size(s) >= MAX_SCOPE_SIZE; +} + +// Requires: assoc != NULL && !scope_full() && !scope_defined(assoc->id); +// Add an association from the given name to the given id attributes +// in the current scope. +// If assoc->attrs->kind != procedure_idk, +// then this stores the scope_count value into assoc->attrs->offset_count +// and then increases loc_count by 1. +static void scope_add(scope_t *s, scope_assoc_t *assoc) +{ + // assert(assoc != NULL); + // assert(!scope_full()); + // assert(!scope_defined(assoc->id)); + if (assoc->attrs->kind != procedure_idk) { + (assoc->attrs->offset_count) = (s->loc_count)++; + } + s->entries[(s->size)++] = assoc; + // fprintf(stderr, "assoc->attrs->offset_count is %d\n", + // assoc->attrs->offset_count); +} + +// Requires: !scope_defined(name) && attrs != NULL; +// Modify the current scope symbol table to +// add an association from the given name to the given id_attrs attrs, +// and if attrs->kind != procedure, +// then this stores the loc_count value into attrs->offset_count +// and then increases the loc_count for this scope by 1. +void scope_insert(scope_t *s, const char *name, id_attrs *attrs) +{ + // assert(!scope_defined(name)); + // assert(attrs != NULL); + // debug_print("Running scope_insert for name "%s\"\n", name); + scope_assoc_t *new_assoc = malloc(sizeof(scope_assoc_t)); + if (new_assoc == NULL) { + bail_with_error("No space for association!"); + } + new_assoc->id = name; + new_assoc->attrs = attrs; + scope_add(s, new_assoc); +} + +// Requires: name != NULL; +// Is the given name associated with some attributes in the current scope? +bool scope_defined(scope_t *s, const char *name) +{ + // assert(s != NULL); + // assert(name != NULL); + // debug_print("entering scope_defined for \"%s\"\n", name); + return scope_lookup(s, name) != NULL; +} + +// Requires: name != NULL and scope_initialize() has been called previously. +// Return (a pointer to) the attributes of the given name in the current scope +// or NULL if there is no association for name. +id_attrs *scope_lookup(scope_t *s, const char *name) +{ + int i; + // assert(name != NULL); + // assert(s != NULL); + // debug_print("Entering scope_lookup for \"%s\"\n", name); + for (i = 0; i < s->size; i++) { + // assert(s != NULL); + // assert(s->entries != NULL); + // assert(0 <= i && i < s->size); + // assert(s->entries[i] != NULL); + // assert(s->entries[i]->id != NULL); + // debug_print("Past asserts in scope_lookup loop\n"); + // debug_print("Length of name is %d\n", strlen(name)); + if (strcmp(s->entries[i]->id, name) == 0) { + // debug_print("scope_lookup(\"%s\") returning attributes\n", + // name); + return s->entries[i]->attrs; + } + } + // assert(i == s->size); + // debug_print("The scope_lookup call on \"%s\" returns NULL\n", name); + return NULL; +} diff --git a/FromGithub/scope.h b/FromGithub/scope.h new file mode 100644 index 0000000..b8d4361 --- /dev/null +++ b/FromGithub/scope.h @@ -0,0 +1,55 @@ +/* $Id: scope.h,v 1.3 2023/11/13 12:51:59 leavens Exp $ */ +#ifndef _SCOPE_H +#define _SCOPE_H + +#include +#include "ast.h" +#include "machine_types.h" +#include "id_attrs.h" + +// Maximum number of declarations that can be stored in a scope +#define MAX_SCOPE_SIZE 4096 + +typedef struct { + const char *id; + id_attrs *attrs; +} scope_assoc_t; + +// Invariant: 0 <= size < MAX_SCOPE_SIZE; +typedef struct scope_s { + unsigned int size; + unsigned int loc_count; // number of consts and vars in this scope + scope_assoc_t *entries[MAX_SCOPE_SIZE]; +} scope_t; + +// Allocate a fresh scope symbol table and return (a pointer to) it. +// Issues an error message (on stderr) if there is no space +// and exits with a failure error code in that case. +extern scope_t *scope_create(); + +// Return the number of constant and variables declarations +// that have been added to this scope. +extern address_type scope_loc_count(scope_t *s); + +// Return the number of declared identifier associations in s +extern unsigned int scope_size(scope_t *s); + +// Is the current scope full? +extern bool scope_full(scope_t *s); + +// Is the given name associated with some attributes in the current scope? +extern bool scope_defined(scope_t *s, const char *name); + +// Requires: !scope_defined(name) && attrs != NULL; +// Modify the current scope symbol table to +// add an association from the given name to the given id_attrs attrs, +// and if attrs->id_kind != procedure, +// then this stores the next_loc_offset value into attrs->loc_offset +// and then increases the next_loc_offset for this scope by 1. +extern void scope_insert(scope_t *s, const char *name, id_attrs *attrs); + +// Return (a pointer to) the attributes of the given name in the current scope +// or NULL if there is no association for name. +extern id_attrs *scope_lookup(scope_t *s, const char *name); + +#endif diff --git a/FromGithub/scope.o b/FromGithub/scope.o new file mode 100644 index 0000000000000000000000000000000000000000..9d32280c2fa6b005066c8aea7af58470f953fcd0 GIT binary patch literal 8312 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 +#include +#include +#include "scope_check.h" +#include "id_attrs.h" +#include "file_location.h" +#include "ast.h" +#include "utilities.h" +#include "symtab.h" +#include "scope_check.h" + +// Requires: prog != NULL. +// The pointer passed to this function should point to the AST +// used by the compiler to generate code, so that the changes +// made (to the id_use fields) are communicated to the code generator. +// Build the symbol table for the given program AST +// and Check the given program AST for duplicate declarations +// or uses of identifiers that were not declared. +// Modifies the given AST to have appropriate id_use pointers. +void scope_check_program(block_t *prog) +{ + scope_check_block(prog); +} + +// build the symbol table and check the declarations in blk +// Modifies the given AST to have appropriate id_use pointers. +void scope_check_block(block_t *blk) +{ + symtab_enter_scope(); + scope_check_constDecls(blk->const_decls); + scope_check_varDecls(blk->var_decls); + scope_check_procDecls(&(blk->proc_decls)); + scope_check_stmts(&(blk->stmts)); + symtab_leave_scope(); +} + +// build the symbol table and check the declarations in cds +// Modifies the given AST to have appropriate id_use pointers. +void scope_check_constDecls(const_decls_t cds) +{ + const_decl_t *dcl = cds.start; + while (dcl != NULL) { + scope_check_constDecl(*(dcl)); + dcl = dcl->next; + } +} + +// build the symbol table and check the const declaration cd +// and add its const-defs to the current scope's symbol table +// or produce an error if these names have already been declared +// Modifies the given AST to have appropriate id_use pointers. +void scope_check_constDecl(const_decl_t cd) +{ + scope_check_const_def_list(cd.const_def_list); +} + +// build the symbol table and check the const definitions cdfs +// and add the declared names to the current scope's symbol table +// or produce an error if these names have already been declared +// Modifies the given AST to have appropriate id_use pointers. +void scope_check_const_def_list(const_def_list_t cdl) +{ + const_def_t *cdf = cdl.start; + while (cdf != NULL) { + scope_check_constDef(*(cdf)); + cdf = cdf->next; + } +} + +// Put the given name, which is to be declared with kind k, +// and has its declaration at the given file location (floc), +// into the current scope's symbol table at the offset scope_size(). +// Modifies the given AST to have appropriate id_use pointers. +static void add_ident_to_scope(const char *name, id_kind k, file_location floc) +{ + id_use *idu = symtab_lookup(name); + if (idu != NULL && idu->levelsOutward == 0) { + bail_with_prog_error(floc, + "%s \"%s\" is already declared as a %s", + id_attrs_id_kind_string(k), + name, + id_attrs_id_kind_string( + id_use_get_attrs(idu)->kind)); + } else { + symtab_insert(name, + id_attrs_create(floc, k, symtab_scope_loc_count())); + } +} + +// build the symbol table and check the const definition cdf +// and add the declared name to the current scope's symbol table +// or produce an error if this name has already been declared +void scope_check_constDef(const_def_t cdf) +{ + add_ident_to_scope(cdf.ident.name, constant_idk, *(cdf.file_loc)); +} + +// build the symbol table and check the declarations in vds +void scope_check_varDecls(var_decls_t vds) +{ + var_decl_t *vdp = vds.var_decls; + while (vdp != NULL) { + scope_check_varDecl(*vdp); + vdp = vdp->next; + } +} + +// check the var declaration vd +// and add the declared names to the current scope's symbol table +// or produce an error if the names have already been declared +void scope_check_varDecl(var_decl_t vd) +{ + scope_check_varIdentList(vd.ident_list); +} + +// check the identifiers from a var declaration, as given in ids +// and add the declared names to the current scope's symbol table +// or produce an error if the names have already been declared +void scope_check_varIdentList(ident_list_t idl) +{ + ident_t *idp = idl.start; + while (idp != NULL) { + add_ident_to_scope(idp->name, variable_idk, *(idp->file_loc)); + idp = idp->next; + } +} + +// build the symbol table and check the declarations in pds +// Modifies the given AST to have appropriate id_use pointers. +void scope_check_procDecls(proc_decls_t *pds) +{ + proc_decl_t *pdp = pds->proc_decls; + while (pdp != NULL) { + scope_check_procDecl(pdp); + pdp = pdp->next; + } +} + +// check the procedure declaration pd +// and add it to the current scope's symbol table +// or produce an error if its name has already been declared +// Modifies the given AST to have appropriate id_use pointers. +void scope_check_procDecl(proc_decl_t *pd) +{ + // add name to scope first, so that the procedure can be recursive + add_ident_to_scope(pd->name, procedure_idk, *(pd->file_loc)); + scope_check_block(pd->block); +} + +// check all the statement in stmts to make sure that +// all idenfifiers referenced in them have been declared +// (if not, then produce an error) +// Modifies the given AST to have appropriate id_use pointers. +void scope_check_stmts(stmts_t *stmts) +{ + if (stmts->stmts_kind != empty_stmts_e) { + scope_check_stmtList(&(stmts->stmt_list)); + } +} + +// check all the statement in stmt_list to make sure that +// all idenfifiers referenced in them have been declared +// (if not, then produce an error) +// Modifies the given AST to have appropriate id_use pointers. +void scope_check_stmtList(stmt_list_t *stmt_list) +{ + stmt_t *s = stmt_list->start; + while (s != NULL) { + scope_check_stmt(s); + s = s->next; + } +} + +// check the statement to make sure that +// all idenfifiers referenced in it have been declared +// (if not, then produce an error). +// Modifies the given AST to have appropriate id_use pointers. +void scope_check_stmt(stmt_t *stmt) +{ + switch (stmt->stmt_kind) { + case assign_stmt: + scope_check_assignStmt(&(stmt->data.assign_stmt)); + break; + case call_stmt: + scope_check_callStmt(&(stmt->data.call_stmt)); + break; + case if_stmt: + scope_check_ifStmt(&(stmt->data.if_stmt)); + break; + case while_stmt: + scope_check_whileStmt(&(stmt->data.while_stmt)); + break; + case read_stmt: + scope_check_readStmt(&(stmt->data.read_stmt)); + break; + case print_stmt: + scope_check_printStmt(&(stmt->data.print_stmt)); + print_stmt_t ps = stmt->data.print_stmt; + if (ps.expr.expr_kind == expr_ident) { + assert(ps.expr.data.ident.idu != NULL); + } + break; + case block_stmt: + scope_check_blockStmt(&(stmt->data.block_stmt)); + break; + default: + bail_with_error("Unknown stmt_kind (%d) in scope_check_stmt!", + stmt->stmt_kind); + break; + } +} + +// check the statement to make sure that +// all idenfifiers referenced in it have been declared +// (if not, then produce an error). +// Modifies the given AST to have appropriate id_use pointers. +void scope_check_assignStmt(assign_stmt_t *stmt) +{ + stmt->idu = scope_check_ident_declared(*(stmt->file_loc), stmt->name); + id_attrs attrs = *(stmt->idu->attrs); + if (attrs.kind != variable_idk) { + bail_with_prog_error(attrs.file_loc, + "Must be a variable on the left-hand side of an assignment statement, not the %s \"%s\"", + id_attrs_id_kind_string(attrs.kind), + stmt->name); + } + scope_check_expr(stmt->expr); +} + +// check the statement to make sure that +// the procedure being called has been declared +// (if not, then produce an error). +// Modifies the given AST to have appropriate id_use pointers. +void scope_check_callStmt(call_stmt_t *stmt) +{ + stmt->idu = scope_check_ident_declared(*(stmt->file_loc), stmt->name); +} + +// check the statement to make sure that +// all idenfifiers referenced in it have been declared +// (if not, then produce an error). +// Modifies the given AST to have appropriate id_use pointers. +void scope_check_blockStmt(block_stmt_t *stmt) +{ + scope_check_block(stmt->block); +} + + +// check the statement to make sure that +// all idenfifiers referenced in it have been declared +// (if not, then produce an error). +// Modifies the given AST to have appropriate id_use pointers. +void scope_check_ifStmt(if_stmt_t *stmt) +{ + scope_check_condition(&(stmt->condition)); + scope_check_stmts(stmt->then_stmts); + if (stmt->else_stmts != NULL) { + scope_check_stmts(stmt->else_stmts); + } +} + +// check the statement to make sure that +// all idenfifiers referenced in it have been declared +// (if not, then produce an error). +// Modifies the given AST to have appropriate id_use pointers. +void scope_check_whileStmt(while_stmt_t *stmt) +{ + scope_check_condition(&(stmt->condition)); + scope_check_stmts(stmt->body); +} + +// Check the statement to make sure that +// all idenfifiers referenced in it have been declared +// (if not, then produce an error). +// Modifies the given AST to have appropriate id_use pointers. +void scope_check_readStmt(read_stmt_t *stmt) +{ + stmt->idu = scope_check_ident_declared(*(stmt->file_loc), stmt->name); + id_attrs attrs = *(stmt->idu->attrs); + if (attrs.kind != variable_idk) { + bail_with_prog_error(attrs.file_loc, + "The name (%s) in a read statement must be a variable, not a %s", + stmt->name, + id_attrs_id_kind_string(attrs.kind)); + } +} + +// check the statement to make sure that +// all idenfifiers referenced in it have been declared +// (if not, then produce an error). +// Modifies the given AST to have appropriate id_use pointers. +void scope_check_printStmt(print_stmt_t *stmt) +{ + scope_check_expr(&(stmt->expr)); + if (stmt->expr.expr_kind == expr_ident) { + assert(stmt->expr.data.ident.idu != NULL); + } +} + +// check the condition to make sure that +// all idenfifiers referenced in it have been declared +// (if not, then produce an error). +// Modifies the given AST to have appropriate id_use pointers. +void scope_check_condition(condition_t *cond) +{ + switch (cond->cond_kind){ + case ck_db: + scope_check_db_condition(&(cond->data.db_cond)); + break; + case ck_rel: + scope_check_rel_op_condition(&(cond->data.rel_op_cond)); + break; + default: + bail_with_error("Unexpected type_tag (%d) in scope_check_cond!", + cond->cond_kind); + break; + } +} + +// check the condition to make sure that +// all idenfifiers referenced in it have been declared +// (if not, then produce an error). +// Modifies the given AST to have appropriate id_use pointers. +void scope_check_db_condition(db_condition_t *cond) +{ + scope_check_expr(&(cond->dividend)); + scope_check_expr(&(cond->divisor)); +} + +// check the condition to make sure that +// all idenfifiers referenced in it have been declared +// (if not, then produce an error). +// Modifies the given AST to have appropriate id_use pointers. +void scope_check_rel_op_condition(rel_op_condition_t *cond) +{ + scope_check_expr(&(cond->expr1)); + scope_check_expr(&(cond->expr2)); +} + +// check the expresion to make sure that +// all idenfifiers referenced in it have been declared +// (if not, then produce an error). +// Modifies the given AST to have appropriate id_use pointers. +void scope_check_expr(expr_t *exp) +{ + switch (exp->expr_kind) { + case expr_ident: + scope_check_ident(&(exp->data.ident)); + assert(exp->data.ident.idu != NULL); + break; + case expr_negated: + scope_check_expr(exp->data.negated.expr); + break; + case expr_bin: + scope_check_binary_op_expr(&(exp->data.binary)); + break; + case expr_number: + // no identifiers are possible in this case, so just return + break; + default: + bail_with_error("Unexpected expr_kind_e (%d) in scope_check_expr!", + exp->expr_kind); + break; + } +} + +// check that the given name has been declared, +// if not, then produce an error using the file_location (floc) given. +// Modifies the given AST to have appropriate id_use pointers. +void scope_check_ident(ident_t *id) +{ + file_location floc = *(id->file_loc); + const char *name = id->name; + id_use *idu = scope_check_ident_declared(floc, name); + if (idu == NULL) { + bail_with_prog_error(floc, + "identifier \"%s\" has not been declared!", + name); + } + id->idu = idu; +} + +// check the expression (exp) to make sure that +// all idenfifiers referenced in it have been declared +// (if not, then produce an error) +void scope_check_binary_op_expr(binary_op_expr_t *exp) +{ + scope_check_expr(exp->expr1); + scope_check_expr(exp->expr2); +} + +// Check that the given name has been declared, +// if so, then return an id_use +// (containing the attributes) for that name, +// otherwise, produce an error +// using the file_location (floc) given. +id_use *scope_check_ident_declared( + file_location floc, + const char *name) +{ + id_use *ret = symtab_lookup(name); + if (ret == NULL) { + bail_with_prog_error(floc, + "identifier \"%s\" is not declared!", + name); + } + id_attrs *ret_attrs = id_use_get_attrs(ret); + assert(ret_attrs != NULL); + return ret; +} diff --git a/FromGithub/scope_check.h b/FromGithub/scope_check.h new file mode 100644 index 0000000..1d72b76 --- /dev/null +++ b/FromGithub/scope_check.h @@ -0,0 +1,166 @@ +/* $Id: scope_check.h,v 1.9 2024/11/10 12:54:14 leavens Exp $ */ +#ifndef _SCOPE_CHECK_H +#define _SCOPE_CHECK_H +#include "ast.h" + +// Requires: prog != NULL. +// The pointer passed to this function should point to the AST +// used by the compiler to generate code, so that the changes +// made (to the id_use fields) are communicated to the code generator. +// Build the symbol table for the given program AST +// and Check the given program AST for duplicate declarations +// or uses of identifiers that were not declared. +// Modifies the given AST to have appropriate id_use pointers. +extern void scope_check_program(block_t *prog); + +// build the symbol table and check the declarations in blk +// Modifies the given AST to have appropriate id_use pointers. +extern void scope_check_block(block_t *blk); + +// build the symbol table and check the declarations in cds +extern void scope_check_constDecls(const_decls_t cds); + +// build the symbol table and check the const declaration cd +// and add its const-defs to the current scope's symbol table +// or produce an error if these names have already been declared +extern void scope_check_constDecl(const_decl_t cd); + +// build the symbol table and check the const definitions cdfs +// and add the declared names to the current scope's symbol table +// or produce an error if these names have already been declared +// Modifies the given AST to have appropriate id_use pointers. +extern void scope_check_const_def_list(const_def_list_t cdl); + +// build the symbol table and check the const definition cdf +// and add the declared name to the current scope's symbol table +// or produce an error if its name has already been declared +extern void scope_check_constDef(const_def_t cdf); + +// build the symbol table and check the declarations in vds +extern void scope_check_varDecls(var_decls_t vds); + +// check the var declaration vd +// and add the declared names to the current scope's symbol table +// or produce an error if the names have already been declared +extern void scope_check_varDecl(var_decl_t vd); + +// check the identifiers from a var declaration, as given in ids +// and add the declared names to the current scope's symbol table +// or produce an error if the names have already been declared +// Modifies the given AST to have appropriate id_use pointers. +extern void scope_check_varIdentList(ident_list_t ident_list); + +// build the symbol table and check the declarations in pds +extern void scope_check_procDecls(proc_decls_t *pds); + +// check the procedure declaration pd +// and add it to the current scope's symbol table +// or produce an error if its name has already been declared +// Modifies the given AST to have appropriate id_use pointers. +extern void scope_check_procDecl(proc_decl_t *pd); + +// check all the statement in stmts to make sure that +// all idenfifiers referenced in them have been declared +// (if not, then produce an error) +// Modifies the given AST to have appropriate id_use pointers. +extern void scope_check_stmts(stmts_t *stmts); + +// check all the statement in stmt_list to make sure that +// all idenfifiers referenced in them have been declared +// (if not, then produce an error) +// Modifies the given AST to have appropriate id_use pointers. +extern void scope_check_stmtList(stmt_list_t *stmt_list); + +// check the statement to make sure that +// all idenfifiers referenced in it have been declared +// (if not, then produce an error). +// Modifies the given AST to have appropriate id_use pointers. +extern void scope_check_stmt(stmt_t *stmt); + +// check the statement to make sure that +// all idenfifiers referenced in it have been declared +// (if not, then produce an error). +// Modifies the given AST to have appropriate id_use pointers. +extern void scope_check_assignStmt(assign_stmt_t *stmt); + +// check the statement to make sure that +// the procedure being called has been declared +// (if not, then produce an error) +// Modifies the given AST to have appropriate id_use pointers. +extern void scope_check_callStmt(call_stmt_t *stmt); + +// check the statement to make sure that +// all idenfifiers referenced in it have been declared +// (if not, then produce an error) +// Modifies the given AST to have appropriate id_use pointers. +extern void scope_check_blockStmt(block_stmt_t *block); + +// check the statement to make sure that +// all idenfifiers referenced in it have been declared +// (if not, then produce an error) +// Modifies the given AST to have appropriate id_use pointers. +extern void scope_check_ifStmt(if_stmt_t *stmt); + +// check the statement to make sure that +// all idenfifiers referenced in it have been declared +// (if not, then produce an error) +// Modifies the given AST to have appropriate id_use pointers. +extern void scope_check_whileStmt(while_stmt_t *stmt); + +// check the statement to make sure that +// all idenfifiers referenced in it have been declared +// (if not, then produce an error) +// Modifies the given AST to have appropriate id_use pointers. +extern void scope_check_readStmt(read_stmt_t *stmt); + +// check the statement to make sure that +// all idenfifiers referenced in it have been declared +// (if not, then produce an error). +// Modifies the given AST to have appropriate id_use pointers. +extern void scope_check_printStmt(print_stmt_t *stmt); + +// check the condition to make sure that +// all idenfifiers referenced in it have been declared +// (if not, then produce an error). +// Modifies the given AST to have appropriate id_use pointers. +extern void scope_check_condition(condition_t *cond); + +// check the condition to make sure that +// all idenfifiers referenced in it have been declared +// (if not, then produce an error). +// Modifies the given AST to have appropriate id_use pointers. +extern void scope_check_db_condition(db_condition_t *cond); + +// check the condition to make sure that +// all idenfifiers referenced in it have been declared +// (if not, then produce an error). +// Modifies the given AST to have appropriate id_use pointers. +extern void scope_check_rel_op_condition(rel_op_condition_t *cond); + +// check the expresion to make sure that +// all idenfifiers referenced in it have been declared +// (if not, then produce an error). +// Modifies the given AST to have appropriate id_use pointers. +extern void scope_check_expr(expr_t *exp); + +// check that the given name has been declared, +// if not, then produce an error using the file_location (floc) given. +// Modifies the AST to have appropriate id_use pointers. +extern void scope_check_ident(ident_t *id); + +// check the expression (exp) to make sure that +// all idenfifiers referenced in it have been declared +// (if not, then produce an error) +// Modifies the given AST to have appropriate id_use pointers. +extern void scope_check_binary_op_expr(binary_op_expr_t *exp); + +// Check that the given name has been declared, +// if so, then return an id_use +// (containing the attributes) for that name, +// otherwise, produce an error +// using the file_location (floc) given. +extern id_use *scope_check_ident_declared( + file_location floc, + const char *name); + +#endif diff --git a/FromGithub/scope_check.o b/FromGithub/scope_check.o new file mode 100644 index 0000000000000000000000000000000000000000..c21dff31d91a5111ac113d65e484706e0d7a0be6 GIT binary patch literal 30024 zcmchA37k~bmG^s9{fdHK=oOkpsb-O8>5WBE5gQSy7LiT>1yOsgrdxVTR~3tj^4SvU zw3^0@BT=HpL?wy(Gf^XP8{8o}2^z<3#*xGg1DP>{CL~6C&N=s-SGNz{=9_PRzwajf z-o5{O_Pf4!U*Xk@&pRjJx{f5*S>U8ff;vvLBbBeDY^77^jCPKWJn^rqqCFo(yN_f? zd$t^l_AWja?RoJKlJxC=R#)#qoGO7KjKuw&k^auY{?2ShpNphw=Jj`$_jeYjYEXFh z-bztG%DVTimU2qER^7We675-h?C^A>ve?(!-x=;N7X{@cu(uLCK}B1RImuu54HOmb zPtNO4miH%9Rt+S`1{p@ze4}f1e`j@nXSBbwvcHoZ8eDtr@!FrXwXcA{%!3%e*^_)N z+OukJv}f5qV0lx#2cr*x(TAKw4Zw$bE5qCNCRbusD8MsrnrP3ny^CM-3(rJ*m%SP7 zP3{HieN{bgRrTzP_Pi3kp#YmJ+VkgV&kL#89-f=Z_dMOZ>NR0BgeI6hAQDY`U3B;L zMSCwfX7z~P#Sp43mC@d6=m((Wm1xg1Pf_lFV|2w;}zitB0w}X=Hy_JRC$3i2oTMA+8*&Dqf ze;YP+^ac-ay=j5yPU&s#fd%~skp=AXz4&-G@Er%9I2bs5Fz{1Ure(f62uMV|(MYs+ zbukREzG%-SJEOhPawyM(@|{rL4dqHGN1^;6l=ncn8p^Aoycf#*pj->(W+)$k@|)0a zHbKjG!T>!81NTtx;`_Rf1(Nlk>p&F7=o$_~wCCx^_M=TEDlq8$oM|2H!C^3yLTgi| z2IpZ{4?3Abz{JJySB>otcPH8#1_Q&oL|}E# zD)4GyHhR>%_+a-jH*uPwT%8SN>DN6l2_z3d#hX<CuCWcXz&fz&%qB~xvZf8R)LzWpJ0QCLk2pA5R9HYCZY161L*%&@IZ^pagxWV zaSOqH@D_rYo>gcFE8%Xn5cM-|p-*}je?lz;cX6cW>6HBBLC7Ea$|--KeM5THTR9#( z_FRy63_49EcJ5-o4?q3bG#r{kb?zZ_n2Bl_I*@;OGD)@?>2UdR$ccym*WhDf$cfbw z$|7r}*@v*qo;MB4p{;+11I&50Sa`W&cq!}_&htv9S0rc!*Fv;Nr=MM|8y?e_+hYW-&GkJaG%mpKjCuiR~yUTy~@3axb33o-% zA55AOk4&5rpBQP0N9tO;Vs(w1BaN|!*1E1(W26qS$dtGfZ|LZZ)igB68rGLKFkff9 zG`6X;tF*B$QCHg17;8_!H5n;7BXa(#^UiaeRqgBBJ2tjQ;)%9I&H9%1#z^s$#%Ylj zKvL3bu(n7{8T7s^8Bav&V_?XJx~`VG`qo&aqdk&njzwByO^K4`I*=R({gIBQNL@Ra z9B*0I-UjA?=DI`-b2B6D9SLG#XHn5gkkDS&76Y^5WL8}Sy-#sP+K$s~1W`yFw7g`& zSB8N6S=A0Sv4#YMGqD+>n5bJfXe1gs+8c`;peXID#m zVg&@!BC_kz0jr9#c0JizBc?eS`Htf`ZW!sv?-MlhlJpdk5gvwxj5KpIY#9MAg{Uq- zyTyrV9@yz*gsGI_Qe9pXG8-rjiG!0fSHmro9SH4)yNg(0SPtg75YC+o`LGjggB$S# zh6iz5nuB=Sus7g}+iJeLln)rnv|*?H0xCjLDzJ;X3#a0u32;)N!M(;=Fl~luBh5^^66SY*HLsGP1i!Yj-l&Vx{jmkc)Ffo zdI_|$0?rC0rlv<6PlSn0clO4Bn#DrO`)^^sZ2maWz>*`1u(}s4*vf{JP8Vy9D%FxmszT)$2#mj8P z=jXoyRP4d>OtiJocwJ33^GvX-*CLszxY!nUi7o8X9JDXPkTniF5ki{n1knr=+^+?f zKt5C$TA2%gAzNijyTF!qp)rklR|kIwypt+JHQq{K9*!}n&3hd%%GTweNXpia*bD)o zY(qM>B1?#oB_@!~n}C|a#(`v-=1476gdPlC_B7m$h3jn#TWt&5GSCzbUON?PSx`st zS`>63^o`Ll;TS<(wxGBzC}9gqQY+LNo()v9m8EVB{xe9OjJ_WTU6sBBM3bLa=b*Wi z-CBSOozTJ1<=6U}udp>=X=~mx3M0Wy_J4*=0+wu6c1;lFn|N(|0kU?yC?BBfAd?46 z_-08Tut9rYAAsrBICO(;%8j-u-_HL!P-Qz)(7lKodMg{thU;yc>tAiIe=}T$?42C6 zlRNN-!)8N7V2Gn~a1t!(3%&~V#-*FC0N8ekX>KZMfQnFY=;r5q_5WzAzr|L+GZ)2h z{JxuWArvHjw+62>g1%P>>ya_=c3aRLwxB!h8Q}ZW_02?emzk)H13w5JK$(%yJvF|} zdu^G!ZJ9qZGHJg1F^Z8n;ZJY(CH>5n^pGv-;ex*aRkkwQ^3c&ISj&H391n6s%c$IYD%g-R;Sbu%%}tDPX)VZ3}KxE}H+ zIc{jr@C#rkU}EmJX+uFm7|i7aIK#PB>xg=0<-br|7K1xG-A=ve6KANr!7 zu|+>?i+;`){k##)f?f!&LqUeYU)q9RvIV_twZ%W%ZSkw%gD9pp^vYD|uEy+F zZ85*G#k^)_3O30^0%KkQEEs#?7cO%hr%D$I{ zwo~@~k*J@tAB_AG*jUF$G=9vI`}_By-k5mUHt~pU;vdE!6}QHJklQ>W|C4$VjL2Jn zz_i9El!qze=oIJ@M)aq)=+A7?f67HFSW`as1^hYq8RS90Uz>aZpW6cdW()Wt3#mW= zE)m9pFM}roL>;@_b@xD?`enfG*g?Bvr@4hlWjeO!=B|fAp%dJQ7!HY$i`lWm-9N*P zWR0+8rQ5PH+#I9=gPs)jOm`n-$)4J5cNJ`QNk)z>BiELZ=Z--tV^6-DiLMnAPl20- z>tCf49EJpF+$a~bW5>AvAcDu*g2&l{$Gf>m1;$+@>?gP}$eLh9+z&)Xku77QEn|{9 z7O9MJlig9@g#rZYhlrs)Q(VlBEp{ivTtP-pvt>=UWzBH&kP7Viy|B-8Ka=dqE>0lh zQ0TDyuK`_nH)M02Vnl{7&g>G1@G$M-k;1TqXKnZEX-_>GtI`T{v9KGfaN`-q-8r#3 z)381~ssQCY2KBkDdfY2MvC(e?P07d7M_7k4;0z3sH;%-AfhbN11`StcV<9gSP%>}= z(w;g2%DE2ZPo6>f>4>{Gy2FVV3y_Ed?(VMJfhY^1Z@Y!}!!59*l8SxqC?pE**mE^J zEhn6tT;vbzs4hg}oi0671a_<*gT)6x$Z*(XaT?#o*a@YO8SCVs68Jy7n4+V|}XMlw#wlq3%w+IJnU`LdUO1kur6xdNq z#SJdaDqwO1xAGg=fz?Lt8ei^yU+xx^iAyyadH_jBYUR*;X`PTn<; zCyST+l2blD2bJ)D$64;4f_d^0w_wDvco2?13CCi$4D-Z+`#0jK@Hy7`))$Xt9To00 z%o7JLdBicr=Vqs@Fm~rOMVtA$=?FE z81vFZg)mZq9NNSQ;+jGN(tQCZ`vN`_0qO2^%#$;?AmNhZe93gq8lPbbOcXH4p>8r} zi5}N7qW@IrC;9ZNg#Od%m?e5#&xro8(9iejw+a2>V$2dfE}KOEw$MM~(?2itZ_mUm zj-we^>Au4efcX|zVB&vB_`k!UaCc41VSgT)fZ5=VV^~M#+?^OVS@#C zY`q$;xZsnHdxUf$XWU&e(Q!{PW??jsj61tCQ6Kq-`&8n+O?XRv-kXK@wj$g~Aw7}y z32Bv2`cFVQqO;NIE5>!%r|cHWltIS~W!&kWj#)IQv$50JMhiNbgj+(=vq`vD_%eYKs!SmZO-BIAZer*jIfufS(i$Ut$H`jp=_lyRqV zD(+NK#RgE(MC-G!;!;sD-Di9b85{csKLc<^fQG3hMJG_&(+WBCFk!E}kafy@;k6AWl| z7RABK)uZ^fL>@4Eo+cNa#fn}9gibAJ*!V}7K)6+>v(Qp?ShLyT!jsdYn zF32qkO&yct<_@bYymAay!s|d3I$WfXW^luEf?>k}mIPoSN(Y2xFp@FZNl#yp9)t-p zGo`{iPDPe*l7%R1A?x(CSaRo!#-*v2OZ|BNu#Bm(^22#(Iy_`76Mbqb;dfskau18^Q=s~xmY5A-kl<$6L2R4M#Aj(KTNLYI_C8- zG6oA=&pYb5k1vGV9pN3}9Y>*b$3idfaWB2w3zT`G@P03QkLPasn&)+UZg|ZiFW0XN zl;=rhUif}5eAFA~1k&7uS72_#s=dG?f#?{|4a_On?w#K4dFO(RJ1V^#Uxvu9X8C7% zSyVT>%nKwy{ToKZaxeF&m;N}J^tdRU`>E$8yfHxIUE{gki@dC(UO3?emU`}|i@Z!> zNPFDNGA`tV^N=GDn3;d{BKe;;>Zq3)XoQ;iUT6(k9_sS~p+GU<;R-Jh4__4ATncf6 zn&9xr6&^~Nb&Z#k@J5Cs-uP~>=o&9;et4Z1p6>e9sMzjGX122nrKk&Ii~z!r?o-KoY`s z(kSRXXL)1Dtufukx!{QTUS42g9`*>J8i!P#QIha7KuMnGE`?Wpt{ZFXOl+>Hizl3x zCOVv?ynW^b=XCJ|oH;esw6*|QXIDo9oj?&`qGNrmopNwkY2diyXA=VszwiLjS#tiW z$fAl;FG;ptvCNiuH4&G9CfhE`Auf+g*-b#PMLScBq7M15ULYt6=%L~{*h{R)vYLWvysc-FQSno8pY(N<{eZpyiDu?RH8>b0l z3RoQm8NB)bmU16#-@Y-w77 zO`U39aIiHwux-piJkhl$+v;Oo5Ojm38pS_KcFe#rfyLfO2h5(Br=IBt4Z4iPrKLR{>l#Q;F((Han(H7MqMcd*KOJz` zF=K|b15OLzYXZjxp5!}?^$=?r6iB;p#mXA|7J$r-H72`a6k!+-(BnEfO;5wtgT84y zfSs|cu5ADYZB~UJUz~@NQ7aB|y5Q)PuF(KNvkL>;0cJW0cLNNWL<~uJ1e0UyYZ~i) z_9p6Cwo%l}C5o*b9qW_efc1q3SwY<@H6RnI!8w2yDJb9r1VG#gY>jP*wZ@kx6C3Ng z8fC`7p*)zjIDSfDzK-x6w1zNx))i}oXj9u*{!#N`H97`?v!&AjHx)G^G&>UmR1DT3&_Nnw z1N=h{>PXUcc#)$}kY)8P?R8z7F>DlGf6n2#C)Md-^)#4cSor31q5&yi%(Tqo$)T|Y zOPCsusjo%M@>H`BcOMA>HGu^SHsVNSD zIDR^po-?oy^CTa)yT9qT*d!Y}x*E;ggfWQo*G1fA%`%zt51JTtn0=0P1(cFnKh4rf z>oh1%ZIq;g;i3(lW_=9=*MX0^+9@1yYiYp&Zgw0dFx0*MVBtK+gX?&QaB738ky@dq zruyrPSFT)BbIz*s7p<&Xetu1jBj01$>k_$ILDyNvZ63}8HVFw+g}$0NVU9)w&pV>p zpH0AFUVL~V2E$-Yq;|HuC4663*4)t+D{GG>%G&BqnN=}s*4(m1%d2P4DW6qVy|8>v z**RSuZA)OONY?+4NR#odvX=IS)+DT#R`&vh152`Fp#4Q@v(r}B&6ix(c3_u`Ppx|qlLG}hRfMv8`PUtHQ?@%UV_3Kk9!l{|lDti#S3`@lvcDNv zlo`4J2)IsO;L^(`sSk7!0rFl9f0&ly#jiihufGy;Nc28T>Q|@a?=scqMVr(IRuVx3 z>Ym_wdbua{i@Sq?y(t+7nTFmL3Qb+A-W+%iZDRx<(jg6HV)-wr@*}{ro9lPm{MgrTH8vtVSi!U<`{SY3dck+ceqXi zv(T6WY$E)*Kwr)Ag_8wJ^BC`BoDQr3JD>4BMUU-n;79Sb<>{ebz4_+HL<2=18V5CebTh4d9{ zkDRX50zR1h_95`Ahrn+c0>5tv{MjM!-wc8O7I3ux9=5;8xaWMv_=}9wJPmdDwJg%F z<#@`8+9bwbRq>z4cpfgEkmNA2it&4JfrTW8l(izC4_Ij4g!&}ok1;NXtT_LnJ$ZBh z=Qwg&dpqM*jNge$AU(wR$Bfgw2l#%#2Wzi4nEn>lJBg$?&L4)L|AOi7;CIn9?*LCB z#0BjfJKPAM`3|zv7+;2)14uN_!u?FfA7-59SHM>@{*l6yjK9b7dr%mp>lklkdqj@f zbq(^WZICT%>1<~(bk?9~#h_@pt(e|#=~oKoUDQ`^Q}L-ep1|kQA)YR*JtZokN7#X+ zv~l)d91QV>&sQ_RYI%B)$J66q05ti6%^Qh9o)`yz$CP?>!3Rcp^=Do~8lO_{&SWQC z!!J%aWP`j)k~eF1R0h1cu`48816;;v(WALdiQoV#>!q7bhp(1qS}LmiF4bx=^NiNWzd0J<4m~&860N5wOTvJ+D>nIYPwaLjzs#}Z zs0VE`e&N845>B7E+WrlGD~?GH#SzDOOK@2a5yw4+;4#Q!LL83$eS9;5kPy#KH0(-qF_j<9!a*sAEsqP;0=u9 zZ3_H}J@^eiCcK>le}dm&;ZrUAE(KSEZny9 zXBKY9=T*ifKA&=YerM6!@$q<{gm&8TnZmfpY32SiN8u5czd+%0cwRWil5h8)D=fSM zWJtT;VBxbY{0=4mVwQiOMQ``30~T)kb#Mqg$ooPahrA*1S_{WLqu8HdT;g^;$E{o8 z5#YgegTlYXe%)-zx8ruVh1-5TYTwe59x?1r zg~Cgi{!~l;44{=bU(0+*hJP1g03mHRH^LC_Wc+%C_b}e4a9I!jLE(=x{Z56y#`rFU zZ{vBEyT60s;}8;MCetH^Z#g=-jC&zWhzkvt<-LpGSqMVHm}A23!6Bpabh;Wj96~~H z>|+wWpYl9~?|Co@Uc~+FOauG)Bu--grHubV(LclZKPjBeah_NB`CNWU;ZlA@;aj=< zhQgoZIKQLtH1_K~h2zgYFnz3W{2>D-d9D$Er?CV0eh-u27xBC#&pUz(o%y|XivHK! z?&f#)DZG^JF~6-(;WDq~vwtE##`N;sB=}owU%8@}ae9Wr|G@T~tMF2mBmGz8Z)1Ni zSM>Nk6w{3g7rnPBT=dF0i^xBh{dz>v&*Ogetio3@j_(^Wi5$`UzQRTC9~CZozf}0o zSbhfIMgAr(Pg3~l+<)->q;1b=j&qs9cQgH5g*Wp2Ghg9ZXaJ;Yg^RzJC|vx#OyL2R zvr*w!a{RAVc$n#LQuutv<@p+mxK9v!eyr%lo<|k_5|7j86uzA8c|+k5?uUmJE_&tp zUF;FP9?KK_0&W+1&o1~_%s?tu^eb5JY=y7pc3hzFO-x^<@T(YKrSL_pw^iY}9G@Kk`07{F3@!GBMO*}t8pzsoI$A=Z(%;m=v-p2iQuflh-UoR?r z8{6}*3YWMYQnsy!Y|?YClxOHk1G{Eg4?%G;o{f#6fS=KSmEb!yF9A!Q5?_b75*}p-%_~f z{ZQee_o%{UpCCu+5@(rj$FP3EKjeN=qHxiBn!-iz5`~N2T7}E{)T;1WZr_ax7roai zT=ecx_%bfvq3{YW|3u*;e~-dN{__g|kjJUK$CJ3t=6?0AqL=mch{A8C9oTzZIvrOUg-ezH7c~l(_2M#x%X*PixU3gj6)x+=^$MTN_V3gG_3ss4&gCx^F7~8jLqU@E5_<|2F5`5D!XMx`oT+e;f1biczVvsj#`RIwP5F*N z@JD(4Z&Grq&}c~4DqQsLP`K#5UEvbvpC}yv?IcW3DO}#W9Zl2Pavavbs%E_#a;E_zE9F8-dbaM}My6)yY#wF>_!uh(q~7ke&OxY%=@ z!lm7BRrsmA&fcwXIWPRF!bR^>3KzXEDO}?4roxADoDVDfEw<+ig^S)1*r<@Cy+rS5 zg^Rz_72eF_bFRWqWqT?Weh$-rUEw7>kH;1MU%W2&DEw3Q>qiQIo7?wsg`0nU(Q#f? z_%@b*Na6Re{a-449M0-v%j}n^ysgA*Y=2_-^y|RrNWnT z91bWs^4;7=ieBXWP2mSveqbaR0ZIIo@AAelF7XsOr3&xk{yay?k?#$cD*7`x&KD_M z;@N1)K@&To&bm&~zs~kFDSG+N z{Z>UU&&hWvdRgzDSM*tEFr=3ieFNj~DSBBKzEHTVBjfO6K}h1SoR>!!m-xuJ=}JX^ z4!8RnMgM^j>s+Pi<-K0FqQ8~tA64|N9RDX2J${pi=_5tIgWLB%6uqH_aguLx;_ur$ zA9A;&IPj8Bggos0bwuP$fjGw0HZ{V_=zX|>K z7(ZLl-_PYLh410=`3irU%PSQAB9~Vy{5M>d-%p4=|Hk+_zDxh%q7&f^HY+zRA(aZ3 z_N`U8^pmX$m;QFA!lmEtRk)0o_Z2SVE)5NbBzDU9ovd(~2jn|gp_lojQPIo1bgjZ= ze*2-qW&V6l;W9tJuW(sM!W>+&N7k>I3YYa!-pdNTtiLk;1ef*wdL>8p5BDit_AM_f zT=r2%6fXNTIp4%;{F8m)OxfQtF8j>$6fXPQR)x#H`g(=S{`@|L%kza(YCg+{d!h^e zF%h^oOAfvduPdd0sDb`77EWn>Jnobd+SNh-c7rK2#_E&nYFgTxI-F9IudA=`ifv$8 zhPvw7*Tsb2VDwvUW&x$bjWGPs8OjYEZTMfPa7y97u@EbT-?_p+)dK%?3zyfmCrjbi z0G;py+Rdyh)?CvBKiG&t6#sWA0_@lYW&RXtm7H0^&(VT&ca+Qyu7^9x8_KR^DW}sYzR@3_YYE*yVgGwDp2PCD?k2D31xCOhMY-#?DtEmLe>+Z ztANa4{?Frydp8rJ|G3m@{}%zKeL|MC{9KgH>m6d4G%fyXeuL>h$oe}Y$Yp*bfJ>#; zzZ@_v6Y1Aa#4G$3K?PRR)&q^kkngG~c!lQzbMvp77T2G_?61Deun0fK57#Jd{|3Oc zOyqok^?#z;Pt)Q$KA8TktbZOepniNcqV-<`7?Oyckfn5cvAJ(Rqpc+R<&OJ;!T9rM z8>SB|Ud#%g+;RUf82?|GAIFECgir4GK&9kux+!z)QYx=$e-2gHuT+?wV&;#eSScs* z6Zlt+q2$i*u#Rc{qo>X_zO+-pt`Xtd!8XUhQcA?z8Z(5 l<{u82G7%7" + 46 | ">=" + + 47 expr: term + 48 | expr "+" term + 49 | expr "-" term + + 50 term: factor + 51 | term "*" factor + 52 | term "/" factor + + 53 factor: identsym + 54 | numbersym + 55 | "-" factor + 56 | "+" factor + 57 | "(" expr ")" + + +Terminals, with rules where they appear + + $end (0) 0 + error (256) + identsym (258) 9 13 14 17 29 30 34 53 + numbersym (259) 9 54 + "+" (260) 48 56 + "-" (261) 49 55 + "*" (262) 51 + "/" (263) 52 + "." (264) 1 + ";" (265) 6 12 17 21 + "=" (266) 9 + "," (267) 8 14 + ":=" (268) 29 + "(" (269) 57 + ")" (270) 57 + "const" (271) 6 + "var" (272) 12 + "proc" (273) 17 + "call" (274) 30 + "begin" (275) 2 + "end" (276) 2 31 32 33 + "if" (277) 31 32 + "then" (278) 31 32 + "else" (279) 31 + "while" (280) 33 + "do" (281) 33 + "read" (282) 34 + "print" (283) 35 + "divisible" (284) 39 + "by" (285) 39 + "==" (286) 41 + "!=" (287) 42 + "<" (288) 43 + "<=" (289) 44 + ">" (290) 45 + ">=" (291) 46 + + +Nonterminals, with rules where they appear + + $accept (37) + on left: 0 + program (38) + on left: 1 + on right: 0 + block (39) + on left: 2 + on right: 1 17 36 + constDecls (40) + on left: 3 4 + on right: 2 4 + empty (41) + on left: 5 + on right: 3 10 15 18 + constDecl (42) + on left: 6 + on right: 4 + constDefList (43) + on left: 7 8 + on right: 6 8 + constDef (44) + on left: 9 + on right: 7 8 + varDecls (45) + on left: 10 11 + on right: 2 11 + varDecl (46) + on left: 12 + on right: 11 + identList (47) + on left: 13 14 + on right: 12 14 + procDecls (48) + on left: 15 16 + on right: 2 16 + procDecl (49) + on left: 17 + on right: 16 + stmts (50) + on left: 18 19 + on right: 2 31 32 33 + stmtList (51) + on left: 20 21 + on right: 19 21 + stmt (52) + on left: 22 23 24 25 26 27 28 + on right: 20 21 + assignStmt (53) + on left: 29 + on right: 22 + callStmt (54) + on left: 30 + on right: 23 + ifStmt (55) + on left: 31 32 + on right: 24 + whileStmt (56) + on left: 33 + on right: 25 + readStmt (57) + on left: 34 + on right: 26 + printStmt (58) + on left: 35 + on right: 27 + blockStmt (59) + on left: 36 + on right: 28 + condition (60) + on left: 37 38 + on right: 31 32 33 + dbCondition (61) + on left: 39 + on right: 37 + relOpCondition (62) + on left: 40 + on right: 38 + relOp (63) + on left: 41 42 43 44 45 46 + on right: 40 + expr (64) + on left: 47 48 49 + on right: 29 35 39 40 48 49 57 + term (65) + on left: 50 51 52 + on right: 47 48 49 51 52 + factor (66) + on left: 53 54 55 56 57 + on right: 50 51 52 55 56 + + +State 0 + + 0 $accept: • program $end + + "begin" shift, and go to state 1 + + program go to state 2 + block go to state 3 + + +State 1 + + 2 block: "begin" • constDecls varDecls procDecls stmts "end" + + $default reduce using rule 5 (empty) + + constDecls go to state 4 + empty go to state 5 + + +State 2 + + 0 $accept: program • $end + + $end shift, and go to state 6 + + +State 3 + + 1 program: block • "." + + "." shift, and go to state 7 + + +State 4 + + 2 block: "begin" constDecls • varDecls procDecls stmts "end" + 4 constDecls: constDecls • constDecl + + "const" shift, and go to state 8 + + $default reduce using rule 5 (empty) + + empty go to state 9 + constDecl go to state 10 + varDecls go to state 11 + + +State 5 + + 3 constDecls: empty • + + $default reduce using rule 3 (constDecls) + + +State 6 + + 0 $accept: program $end • + + $default accept + + +State 7 + + 1 program: block "." • + + $default reduce using rule 1 (program) + + +State 8 + + 6 constDecl: "const" • constDefList ";" + + identsym shift, and go to state 12 + + constDefList go to state 13 + constDef go to state 14 + + +State 9 + + 10 varDecls: empty • + + $default reduce using rule 10 (varDecls) + + +State 10 + + 4 constDecls: constDecls constDecl • + + $default reduce using rule 4 (constDecls) + + +State 11 + + 2 block: "begin" constDecls varDecls • procDecls stmts "end" + 11 varDecls: varDecls • varDecl + + "var" shift, and go to state 15 + + $default reduce using rule 5 (empty) + + empty go to state 16 + varDecl go to state 17 + procDecls go to state 18 + + +State 12 + + 9 constDef: identsym • "=" numbersym + + "=" shift, and go to state 19 + + +State 13 + + 6 constDecl: "const" constDefList • ";" + 8 constDefList: constDefList • "," constDef + + ";" shift, and go to state 20 + "," shift, and go to state 21 + + +State 14 + + 7 constDefList: constDef • + + $default reduce using rule 7 (constDefList) + + +State 15 + + 12 varDecl: "var" • identList ";" + + identsym shift, and go to state 22 + + identList go to state 23 + + +State 16 + + 15 procDecls: empty • + + $default reduce using rule 15 (procDecls) + + +State 17 + + 11 varDecls: varDecls varDecl • + + $default reduce using rule 11 (varDecls) + + +State 18 + + 2 block: "begin" constDecls varDecls procDecls • stmts "end" + 16 procDecls: procDecls • procDecl + + identsym shift, and go to state 24 + "proc" shift, and go to state 25 + "call" shift, and go to state 26 + "begin" shift, and go to state 1 + "if" shift, and go to state 27 + "while" shift, and go to state 28 + "read" shift, and go to state 29 + "print" shift, and go to state 30 + + $default reduce using rule 5 (empty) + + block go to state 31 + empty go to state 32 + procDecl go to state 33 + stmts go to state 34 + stmtList go to state 35 + stmt go to state 36 + assignStmt go to state 37 + callStmt go to state 38 + ifStmt go to state 39 + whileStmt go to state 40 + readStmt go to state 41 + printStmt go to state 42 + blockStmt go to state 43 + + +State 19 + + 9 constDef: identsym "=" • numbersym + + numbersym shift, and go to state 44 + + +State 20 + + 6 constDecl: "const" constDefList ";" • + + $default reduce using rule 6 (constDecl) + + +State 21 + + 8 constDefList: constDefList "," • constDef + + identsym shift, and go to state 12 + + constDef go to state 45 + + +State 22 + + 13 identList: identsym • + + $default reduce using rule 13 (identList) + + +State 23 + + 12 varDecl: "var" identList • ";" + 14 identList: identList • "," identsym + + ";" shift, and go to state 46 + "," shift, and go to state 47 + + +State 24 + + 29 assignStmt: identsym • ":=" expr + + ":=" shift, and go to state 48 + + +State 25 + + 17 procDecl: "proc" • identsym block ";" + + identsym shift, and go to state 49 + + +State 26 + + 30 callStmt: "call" • identsym + + identsym shift, and go to state 50 + + +State 27 + + 31 ifStmt: "if" • condition "then" stmts "else" stmts "end" + 32 | "if" • condition "then" stmts "end" + + identsym shift, and go to state 51 + numbersym shift, and go to state 52 + "+" shift, and go to state 53 + "-" shift, and go to state 54 + "(" shift, and go to state 55 + "divisible" shift, and go to state 56 + + condition go to state 57 + dbCondition go to state 58 + relOpCondition go to state 59 + expr go to state 60 + term go to state 61 + factor go to state 62 + + +State 28 + + 33 whileStmt: "while" • condition "do" stmts "end" + + identsym shift, and go to state 51 + numbersym shift, and go to state 52 + "+" shift, and go to state 53 + "-" shift, and go to state 54 + "(" shift, and go to state 55 + "divisible" shift, and go to state 56 + + condition go to state 63 + dbCondition go to state 58 + relOpCondition go to state 59 + expr go to state 60 + term go to state 61 + factor go to state 62 + + +State 29 + + 34 readStmt: "read" • identsym + + identsym shift, and go to state 64 + + +State 30 + + 35 printStmt: "print" • expr + + identsym shift, and go to state 51 + numbersym shift, and go to state 52 + "+" shift, and go to state 53 + "-" shift, and go to state 54 + "(" shift, and go to state 55 + + expr go to state 65 + term go to state 61 + factor go to state 62 + + +State 31 + + 36 blockStmt: block • + + $default reduce using rule 36 (blockStmt) + + +State 32 + + 18 stmts: empty • + + $default reduce using rule 18 (stmts) + + +State 33 + + 16 procDecls: procDecls procDecl • + + $default reduce using rule 16 (procDecls) + + +State 34 + + 2 block: "begin" constDecls varDecls procDecls stmts • "end" + + "end" shift, and go to state 66 + + +State 35 + + 19 stmts: stmtList • + 21 stmtList: stmtList • ";" stmt + + ";" shift, and go to state 67 + + $default reduce using rule 19 (stmts) + + +State 36 + + 20 stmtList: stmt • + + $default reduce using rule 20 (stmtList) + + +State 37 + + 22 stmt: assignStmt • + + $default reduce using rule 22 (stmt) + + +State 38 + + 23 stmt: callStmt • + + $default reduce using rule 23 (stmt) + + +State 39 + + 24 stmt: ifStmt • + + $default reduce using rule 24 (stmt) + + +State 40 + + 25 stmt: whileStmt • + + $default reduce using rule 25 (stmt) + + +State 41 + + 26 stmt: readStmt • + + $default reduce using rule 26 (stmt) + + +State 42 + + 27 stmt: printStmt • + + $default reduce using rule 27 (stmt) + + +State 43 + + 28 stmt: blockStmt • + + $default reduce using rule 28 (stmt) + + +State 44 + + 9 constDef: identsym "=" numbersym • + + $default reduce using rule 9 (constDef) + + +State 45 + + 8 constDefList: constDefList "," constDef • + + $default reduce using rule 8 (constDefList) + + +State 46 + + 12 varDecl: "var" identList ";" • + + $default reduce using rule 12 (varDecl) + + +State 47 + + 14 identList: identList "," • identsym + + identsym shift, and go to state 68 + + +State 48 + + 29 assignStmt: identsym ":=" • expr + + identsym shift, and go to state 51 + numbersym shift, and go to state 52 + "+" shift, and go to state 53 + "-" shift, and go to state 54 + "(" shift, and go to state 55 + + expr go to state 69 + term go to state 61 + factor go to state 62 + + +State 49 + + 17 procDecl: "proc" identsym • block ";" + + "begin" shift, and go to state 1 + + block go to state 70 + + +State 50 + + 30 callStmt: "call" identsym • + + $default reduce using rule 30 (callStmt) + + +State 51 + + 53 factor: identsym • + + $default reduce using rule 53 (factor) + + +State 52 + + 54 factor: numbersym • + + $default reduce using rule 54 (factor) + + +State 53 + + 56 factor: "+" • factor + + identsym shift, and go to state 51 + numbersym shift, and go to state 52 + "+" shift, and go to state 53 + "-" shift, and go to state 54 + "(" shift, and go to state 55 + + factor go to state 71 + + +State 54 + + 55 factor: "-" • factor + + identsym shift, and go to state 51 + numbersym shift, and go to state 52 + "+" shift, and go to state 53 + "-" shift, and go to state 54 + "(" shift, and go to state 55 + + factor go to state 72 + + +State 55 + + 57 factor: "(" • expr ")" + + identsym shift, and go to state 51 + numbersym shift, and go to state 52 + "+" shift, and go to state 53 + "-" shift, and go to state 54 + "(" shift, and go to state 55 + + expr go to state 73 + term go to state 61 + factor go to state 62 + + +State 56 + + 39 dbCondition: "divisible" • expr "by" expr + + identsym shift, and go to state 51 + numbersym shift, and go to state 52 + "+" shift, and go to state 53 + "-" shift, and go to state 54 + "(" shift, and go to state 55 + + expr go to state 74 + term go to state 61 + factor go to state 62 + + +State 57 + + 31 ifStmt: "if" condition • "then" stmts "else" stmts "end" + 32 | "if" condition • "then" stmts "end" + + "then" shift, and go to state 75 + + +State 58 + + 37 condition: dbCondition • + + $default reduce using rule 37 (condition) + + +State 59 + + 38 condition: relOpCondition • + + $default reduce using rule 38 (condition) + + +State 60 + + 40 relOpCondition: expr • relOp expr + 48 expr: expr • "+" term + 49 | expr • "-" term + + "+" shift, and go to state 76 + "-" shift, and go to state 77 + "==" shift, and go to state 78 + "!=" shift, and go to state 79 + "<" shift, and go to state 80 + "<=" shift, and go to state 81 + ">" shift, and go to state 82 + ">=" shift, and go to state 83 + + relOp go to state 84 + + +State 61 + + 47 expr: term • + 51 term: term • "*" factor + 52 | term • "/" factor + + "*" shift, and go to state 85 + "/" shift, and go to state 86 + + $default reduce using rule 47 (expr) + + +State 62 + + 50 term: factor • + + $default reduce using rule 50 (term) + + +State 63 + + 33 whileStmt: "while" condition • "do" stmts "end" + + "do" shift, and go to state 87 + + +State 64 + + 34 readStmt: "read" identsym • + + $default reduce using rule 34 (readStmt) + + +State 65 + + 35 printStmt: "print" expr • + 48 expr: expr • "+" term + 49 | expr • "-" term + + "+" shift, and go to state 76 + "-" shift, and go to state 77 + + $default reduce using rule 35 (printStmt) + + +State 66 + + 2 block: "begin" constDecls varDecls procDecls stmts "end" • + + $default reduce using rule 2 (block) + + +State 67 + + 21 stmtList: stmtList ";" • stmt + + identsym shift, and go to state 24 + "call" shift, and go to state 26 + "begin" shift, and go to state 1 + "if" shift, and go to state 27 + "while" shift, and go to state 28 + "read" shift, and go to state 29 + "print" shift, and go to state 30 + + block go to state 31 + stmt go to state 88 + assignStmt go to state 37 + callStmt go to state 38 + ifStmt go to state 39 + whileStmt go to state 40 + readStmt go to state 41 + printStmt go to state 42 + blockStmt go to state 43 + + +State 68 + + 14 identList: identList "," identsym • + + $default reduce using rule 14 (identList) + + +State 69 + + 29 assignStmt: identsym ":=" expr • + 48 expr: expr • "+" term + 49 | expr • "-" term + + "+" shift, and go to state 76 + "-" shift, and go to state 77 + + $default reduce using rule 29 (assignStmt) + + +State 70 + + 17 procDecl: "proc" identsym block • ";" + + ";" shift, and go to state 89 + + +State 71 + + 56 factor: "+" factor • + + $default reduce using rule 56 (factor) + + +State 72 + + 55 factor: "-" factor • + + $default reduce using rule 55 (factor) + + +State 73 + + 48 expr: expr • "+" term + 49 | expr • "-" term + 57 factor: "(" expr • ")" + + "+" shift, and go to state 76 + "-" shift, and go to state 77 + ")" shift, and go to state 90 + + +State 74 + + 39 dbCondition: "divisible" expr • "by" expr + 48 expr: expr • "+" term + 49 | expr • "-" term + + "+" shift, and go to state 76 + "-" shift, and go to state 77 + "by" shift, and go to state 91 + + +State 75 + + 31 ifStmt: "if" condition "then" • stmts "else" stmts "end" + 32 | "if" condition "then" • stmts "end" + + identsym shift, and go to state 24 + "call" shift, and go to state 26 + "begin" shift, and go to state 1 + "if" shift, and go to state 27 + "while" shift, and go to state 28 + "read" shift, and go to state 29 + "print" shift, and go to state 30 + + $default reduce using rule 5 (empty) + + block go to state 31 + empty go to state 32 + stmts go to state 92 + stmtList go to state 35 + stmt go to state 36 + assignStmt go to state 37 + callStmt go to state 38 + ifStmt go to state 39 + whileStmt go to state 40 + readStmt go to state 41 + printStmt go to state 42 + blockStmt go to state 43 + + +State 76 + + 48 expr: expr "+" • term + + identsym shift, and go to state 51 + numbersym shift, and go to state 52 + "+" shift, and go to state 53 + "-" shift, and go to state 54 + "(" shift, and go to state 55 + + term go to state 93 + factor go to state 62 + + +State 77 + + 49 expr: expr "-" • term + + identsym shift, and go to state 51 + numbersym shift, and go to state 52 + "+" shift, and go to state 53 + "-" shift, and go to state 54 + "(" shift, and go to state 55 + + term go to state 94 + factor go to state 62 + + +State 78 + + 41 relOp: "==" • + + $default reduce using rule 41 (relOp) + + +State 79 + + 42 relOp: "!=" • + + $default reduce using rule 42 (relOp) + + +State 80 + + 43 relOp: "<" • + + $default reduce using rule 43 (relOp) + + +State 81 + + 44 relOp: "<=" • + + $default reduce using rule 44 (relOp) + + +State 82 + + 45 relOp: ">" • + + $default reduce using rule 45 (relOp) + + +State 83 + + 46 relOp: ">=" • + + $default reduce using rule 46 (relOp) + + +State 84 + + 40 relOpCondition: expr relOp • expr + + identsym shift, and go to state 51 + numbersym shift, and go to state 52 + "+" shift, and go to state 53 + "-" shift, and go to state 54 + "(" shift, and go to state 55 + + expr go to state 95 + term go to state 61 + factor go to state 62 + + +State 85 + + 51 term: term "*" • factor + + identsym shift, and go to state 51 + numbersym shift, and go to state 52 + "+" shift, and go to state 53 + "-" shift, and go to state 54 + "(" shift, and go to state 55 + + factor go to state 96 + + +State 86 + + 52 term: term "/" • factor + + identsym shift, and go to state 51 + numbersym shift, and go to state 52 + "+" shift, and go to state 53 + "-" shift, and go to state 54 + "(" shift, and go to state 55 + + factor go to state 97 + + +State 87 + + 33 whileStmt: "while" condition "do" • stmts "end" + + identsym shift, and go to state 24 + "call" shift, and go to state 26 + "begin" shift, and go to state 1 + "if" shift, and go to state 27 + "while" shift, and go to state 28 + "read" shift, and go to state 29 + "print" shift, and go to state 30 + + $default reduce using rule 5 (empty) + + block go to state 31 + empty go to state 32 + stmts go to state 98 + stmtList go to state 35 + stmt go to state 36 + assignStmt go to state 37 + callStmt go to state 38 + ifStmt go to state 39 + whileStmt go to state 40 + readStmt go to state 41 + printStmt go to state 42 + blockStmt go to state 43 + + +State 88 + + 21 stmtList: stmtList ";" stmt • + + $default reduce using rule 21 (stmtList) + + +State 89 + + 17 procDecl: "proc" identsym block ";" • + + $default reduce using rule 17 (procDecl) + + +State 90 + + 57 factor: "(" expr ")" • + + $default reduce using rule 57 (factor) + + +State 91 + + 39 dbCondition: "divisible" expr "by" • expr + + identsym shift, and go to state 51 + numbersym shift, and go to state 52 + "+" shift, and go to state 53 + "-" shift, and go to state 54 + "(" shift, and go to state 55 + + expr go to state 99 + term go to state 61 + factor go to state 62 + + +State 92 + + 31 ifStmt: "if" condition "then" stmts • "else" stmts "end" + 32 | "if" condition "then" stmts • "end" + + "end" shift, and go to state 100 + "else" shift, and go to state 101 + + +State 93 + + 48 expr: expr "+" term • + 51 term: term • "*" factor + 52 | term • "/" factor + + "*" shift, and go to state 85 + "/" shift, and go to state 86 + + $default reduce using rule 48 (expr) + + +State 94 + + 49 expr: expr "-" term • + 51 term: term • "*" factor + 52 | term • "/" factor + + "*" shift, and go to state 85 + "/" shift, and go to state 86 + + $default reduce using rule 49 (expr) + + +State 95 + + 40 relOpCondition: expr relOp expr • + 48 expr: expr • "+" term + 49 | expr • "-" term + + "+" shift, and go to state 76 + "-" shift, and go to state 77 + + $default reduce using rule 40 (relOpCondition) + + +State 96 + + 51 term: term "*" factor • + + $default reduce using rule 51 (term) + + +State 97 + + 52 term: term "/" factor • + + $default reduce using rule 52 (term) + + +State 98 + + 33 whileStmt: "while" condition "do" stmts • "end" + + "end" shift, and go to state 102 + + +State 99 + + 39 dbCondition: "divisible" expr "by" expr • + 48 expr: expr • "+" term + 49 | expr • "-" term + + "+" shift, and go to state 76 + "-" shift, and go to state 77 + + $default reduce using rule 39 (dbCondition) + + +State 100 + + 32 ifStmt: "if" condition "then" stmts "end" • + + $default reduce using rule 32 (ifStmt) + + +State 101 + + 31 ifStmt: "if" condition "then" stmts "else" • stmts "end" + + identsym shift, and go to state 24 + "call" shift, and go to state 26 + "begin" shift, and go to state 1 + "if" shift, and go to state 27 + "while" shift, and go to state 28 + "read" shift, and go to state 29 + "print" shift, and go to state 30 + + $default reduce using rule 5 (empty) + + block go to state 31 + empty go to state 32 + stmts go to state 103 + stmtList go to state 35 + stmt go to state 36 + assignStmt go to state 37 + callStmt go to state 38 + ifStmt go to state 39 + whileStmt go to state 40 + readStmt go to state 41 + printStmt go to state 42 + blockStmt go to state 43 + + +State 102 + + 33 whileStmt: "while" condition "do" stmts "end" • + + $default reduce using rule 33 (whileStmt) + + +State 103 + + 31 ifStmt: "if" condition "then" stmts "else" stmts • "end" + + "end" shift, and go to state 104 + + +State 104 + + 31 ifStmt: "if" condition "then" stmts "else" stmts "end" • + + $default reduce using rule 31 (ifStmt) diff --git a/FromGithub/spl.tab.c b/FromGithub/spl.tab.c new file mode 100644 index 0000000..e123819 --- /dev/null +++ b/FromGithub/spl.tab.c @@ -0,0 +1,2319 @@ +/* A Bison parser, made by GNU Bison 3.8.2. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, + Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, + especially those whose name start with YY_ or yy_. They are + private implementation details that can be changed or removed. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output, and Bison version. */ +#define YYBISON 30802 + +/* Bison version string. */ +#define YYBISON_VERSION "3.8.2" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + +/* "%code top" blocks. */ +#line 3 "spl.y" + +#include + +#line 72 "spl.tab.c" + + + + +# ifndef YY_CAST +# ifdef __cplusplus +# define YY_CAST(Type, Val) static_cast (Val) +# define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast (Val) +# else +# define YY_CAST(Type, Val) ((Type) (Val)) +# define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val)) +# endif +# endif +# ifndef YY_NULLPTR +# if defined __cplusplus +# if 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif +# else +# define YY_NULLPTR ((void*)0) +# endif +# endif + +#include "spl.tab.h" +/* Symbol kind. */ +enum yysymbol_kind_t +{ + YYSYMBOL_YYEMPTY = -2, + YYSYMBOL_YYEOF = 0, /* "end of file" */ + YYSYMBOL_YYerror = 1, /* error */ + YYSYMBOL_YYUNDEF = 2, /* "invalid token" */ + YYSYMBOL_identsym = 3, /* identsym */ + YYSYMBOL_numbersym = 4, /* numbersym */ + YYSYMBOL_plussym = 5, /* "+" */ + YYSYMBOL_minussym = 6, /* "-" */ + YYSYMBOL_multsym = 7, /* "*" */ + YYSYMBOL_divsym = 8, /* "/" */ + YYSYMBOL_periodsym = 9, /* "." */ + YYSYMBOL_semisym = 10, /* ";" */ + YYSYMBOL_eqsym = 11, /* "=" */ + YYSYMBOL_commasym = 12, /* "," */ + YYSYMBOL_becomessym = 13, /* ":=" */ + YYSYMBOL_lparensym = 14, /* "(" */ + YYSYMBOL_rparensym = 15, /* ")" */ + YYSYMBOL_constsym = 16, /* "const" */ + YYSYMBOL_varsym = 17, /* "var" */ + YYSYMBOL_procsym = 18, /* "proc" */ + YYSYMBOL_callsym = 19, /* "call" */ + YYSYMBOL_beginsym = 20, /* "begin" */ + YYSYMBOL_endsym = 21, /* "end" */ + YYSYMBOL_ifsym = 22, /* "if" */ + YYSYMBOL_thensym = 23, /* "then" */ + YYSYMBOL_elsesym = 24, /* "else" */ + YYSYMBOL_whilesym = 25, /* "while" */ + YYSYMBOL_dosym = 26, /* "do" */ + YYSYMBOL_readsym = 27, /* "read" */ + YYSYMBOL_printsym = 28, /* "print" */ + YYSYMBOL_divisiblesym = 29, /* "divisible" */ + YYSYMBOL_bysym = 30, /* "by" */ + YYSYMBOL_eqeqsym = 31, /* "==" */ + YYSYMBOL_neqsym = 32, /* "!=" */ + YYSYMBOL_ltsym = 33, /* "<" */ + YYSYMBOL_leqsym = 34, /* "<=" */ + YYSYMBOL_gtsym = 35, /* ">" */ + YYSYMBOL_geqsym = 36, /* ">=" */ + YYSYMBOL_YYACCEPT = 37, /* $accept */ + YYSYMBOL_program = 38, /* program */ + YYSYMBOL_block = 39, /* block */ + YYSYMBOL_constDecls = 40, /* constDecls */ + YYSYMBOL_empty = 41, /* empty */ + YYSYMBOL_constDecl = 42, /* constDecl */ + YYSYMBOL_constDefList = 43, /* constDefList */ + YYSYMBOL_constDef = 44, /* constDef */ + YYSYMBOL_varDecls = 45, /* varDecls */ + YYSYMBOL_varDecl = 46, /* varDecl */ + YYSYMBOL_identList = 47, /* identList */ + YYSYMBOL_procDecls = 48, /* procDecls */ + YYSYMBOL_procDecl = 49, /* procDecl */ + YYSYMBOL_stmts = 50, /* stmts */ + YYSYMBOL_stmtList = 51, /* stmtList */ + YYSYMBOL_stmt = 52, /* stmt */ + YYSYMBOL_assignStmt = 53, /* assignStmt */ + YYSYMBOL_callStmt = 54, /* callStmt */ + YYSYMBOL_ifStmt = 55, /* ifStmt */ + YYSYMBOL_whileStmt = 56, /* whileStmt */ + YYSYMBOL_readStmt = 57, /* readStmt */ + YYSYMBOL_printStmt = 58, /* printStmt */ + YYSYMBOL_blockStmt = 59, /* blockStmt */ + YYSYMBOL_condition = 60, /* condition */ + YYSYMBOL_dbCondition = 61, /* dbCondition */ + YYSYMBOL_relOpCondition = 62, /* relOpCondition */ + YYSYMBOL_relOp = 63, /* relOp */ + YYSYMBOL_expr = 64, /* expr */ + YYSYMBOL_term = 65, /* term */ + YYSYMBOL_factor = 66 /* factor */ +}; +typedef enum yysymbol_kind_t yysymbol_kind_t; + + + +/* Unqualified %code blocks. */ +#line 106 "spl.y" + + /* extern declarations provided by the lexer */ +extern int yylex(void); + + /* The AST for the program, set by the semantic action + for the nonterminal program. */ +block_t progast; + + /* Set the program's ast to be t */ +extern void setProgAST(block_t t); + +#line 188 "spl.tab.c" + +#ifdef short +# undef short +#endif + +/* On compilers that do not define __PTRDIFF_MAX__ etc., make sure + and (if available) are included + so that the code can choose integer types of a good width. */ + +#ifndef __PTRDIFF_MAX__ +# include /* INFRINGES ON USER NAME SPACE */ +# if defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_STDINT_H +# endif +#endif + +/* Narrow types that promote to a signed type and that can represent a + signed or unsigned integer of at least N bits. In tables they can + save space and decrease cache pressure. Promoting to a signed type + helps avoid bugs in integer arithmetic. */ + +#ifdef __INT_LEAST8_MAX__ +typedef __INT_LEAST8_TYPE__ yytype_int8; +#elif defined YY_STDINT_H +typedef int_least8_t yytype_int8; +#else +typedef signed char yytype_int8; +#endif + +#ifdef __INT_LEAST16_MAX__ +typedef __INT_LEAST16_TYPE__ yytype_int16; +#elif defined YY_STDINT_H +typedef int_least16_t yytype_int16; +#else +typedef short yytype_int16; +#endif + +/* Work around bug in HP-UX 11.23, which defines these macros + incorrectly for preprocessor constants. This workaround can likely + be removed in 2023, as HPE has promised support for HP-UX 11.23 + (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of + . */ +#ifdef __hpux +# undef UINT_LEAST8_MAX +# undef UINT_LEAST16_MAX +# define UINT_LEAST8_MAX 255 +# define UINT_LEAST16_MAX 65535 +#endif + +#if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ +typedef __UINT_LEAST8_TYPE__ yytype_uint8; +#elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ + && UINT_LEAST8_MAX <= INT_MAX) +typedef uint_least8_t yytype_uint8; +#elif !defined __UINT_LEAST8_MAX__ && UCHAR_MAX <= INT_MAX +typedef unsigned char yytype_uint8; +#else +typedef short yytype_uint8; +#endif + +#if defined __UINT_LEAST16_MAX__ && __UINT_LEAST16_MAX__ <= __INT_MAX__ +typedef __UINT_LEAST16_TYPE__ yytype_uint16; +#elif (!defined __UINT_LEAST16_MAX__ && defined YY_STDINT_H \ + && UINT_LEAST16_MAX <= INT_MAX) +typedef uint_least16_t yytype_uint16; +#elif !defined __UINT_LEAST16_MAX__ && USHRT_MAX <= INT_MAX +typedef unsigned short yytype_uint16; +#else +typedef int yytype_uint16; +#endif + +#ifndef YYPTRDIFF_T +# if defined __PTRDIFF_TYPE__ && defined __PTRDIFF_MAX__ +# define YYPTRDIFF_T __PTRDIFF_TYPE__ +# define YYPTRDIFF_MAXIMUM __PTRDIFF_MAX__ +# elif defined PTRDIFF_MAX +# ifndef ptrdiff_t +# include /* INFRINGES ON USER NAME SPACE */ +# endif +# define YYPTRDIFF_T ptrdiff_t +# define YYPTRDIFF_MAXIMUM PTRDIFF_MAX +# else +# define YYPTRDIFF_T long +# define YYPTRDIFF_MAXIMUM LONG_MAX +# endif +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif defined __STDC_VERSION__ && 199901 <= __STDC_VERSION__ +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned +# endif +#endif + +#define YYSIZE_MAXIMUM \ + YY_CAST (YYPTRDIFF_T, \ + (YYPTRDIFF_MAXIMUM < YY_CAST (YYSIZE_T, -1) \ + ? YYPTRDIFF_MAXIMUM \ + : YY_CAST (YYSIZE_T, -1))) + +#define YYSIZEOF(X) YY_CAST (YYPTRDIFF_T, sizeof (X)) + + +/* Stored state numbers (used for stacks). */ +typedef yytype_int8 yy_state_t; + +/* State numbers in computations. */ +typedef int yy_state_fast_t; + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +# endif +# endif +# ifndef YY_ +# define YY_(Msgid) Msgid +# endif +#endif + + +#ifndef YY_ATTRIBUTE_PURE +# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__) +# define YY_ATTRIBUTE_PURE __attribute__ ((__pure__)) +# else +# define YY_ATTRIBUTE_PURE +# endif +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__) +# define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) +# else +# define YY_ATTRIBUTE_UNUSED +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YY_USE(E) ((void) (E)) +#else +# define YY_USE(E) /* empty */ +#endif + +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__ +# if __GNUC__ * 100 + __GNUC_MINOR__ < 407 +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") +# else +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# endif +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") +#else +# define YY_INITIAL_VALUE(Value) Value +#endif +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif + +#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__ +# define YY_IGNORE_USELESS_CAST_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuseless-cast\"") +# define YY_IGNORE_USELESS_CAST_END \ + _Pragma ("GCC diagnostic pop") +#endif +#ifndef YY_IGNORE_USELESS_CAST_BEGIN +# define YY_IGNORE_USELESS_CAST_BEGIN +# define YY_IGNORE_USELESS_CAST_END +#endif + + +#define YY_ASSERT(E) ((void) (0 && (E))) + +#if 1 + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's 'empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +# define YYCOPY_NEEDED 1 +#endif /* 1 */ + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \ + && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yy_state_t yyss_alloc; + YYSTYPE yyvs_alloc; + YYLTYPE yyls_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (YYSIZEOF (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (YYSIZEOF (yy_state_t) + YYSIZEOF (YYSTYPE) \ + + YYSIZEOF (YYLTYPE)) \ + + 2 * YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYPTRDIFF_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * YYSIZEOF (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / YYSIZEOF (*yyptr); \ + } \ + while (0) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, YY_CAST (YYSIZE_T, (Count)) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYPTRDIFF_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (0) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 6 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 94 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 37 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 30 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 58 +/* YYNSTATES -- Number of states. */ +#define YYNSTATES 105 + +/* YYMAXUTOK -- Last valid token kind. */ +#define YYMAXUTOK 291 + + +/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, with out-of-bounds checking. */ +#define YYTRANSLATE(YYX) \ + (0 <= (YYX) && (YYX) <= YYMAXUTOK \ + ? YY_CAST (yysymbol_kind_t, yytranslate[YYX]) \ + : YYSYMBOL_YYUNDEF) + +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex. */ +static const yytype_int8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36 +}; + +#if YYDEBUG +/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +static const yytype_uint8 yyrline[] = +{ + 0, 121, 121, 124, 128, 129, 133, 140, 142, 143, + 147, 149, 150, 153, 155, 156, 159, 160, 163, 165, + 166, 169, 170, 173, 174, 175, 176, 177, 178, 179, + 182, 184, 186, 188, 192, 195, 197, 199, 201, 202, + 205, 207, 209, 209, 209, 209, 209, 209, 211, 212, + 214, 218, 219, 221, 225, 226, 227, 228, 229 +}; +#endif + +/** Accessing symbol of state STATE. */ +#define YY_ACCESSING_SYMBOL(State) YY_CAST (yysymbol_kind_t, yystos[State]) + +#if 1 +/* The user-facing name of the symbol whose (internal) number is + YYSYMBOL. No bounds checking. */ +static const char *yysymbol_name (yysymbol_kind_t yysymbol) YY_ATTRIBUTE_UNUSED; + +static const char * +yysymbol_name (yysymbol_kind_t yysymbol) +{ + static const char *const yy_sname[] = + { + "end of file", "error", "invalid token", "identsym", "numbersym", "+", + "-", "*", "/", ".", ";", "=", ",", ":=", "(", ")", "const", "var", + "proc", "call", "begin", "end", "if", "then", "else", "while", "do", + "read", "print", "divisible", "by", "==", "!=", "<", "<=", ">", ">=", + "$accept", "program", "block", "constDecls", "empty", "constDecl", + "constDefList", "constDef", "varDecls", "varDecl", "identList", + "procDecls", "procDecl", "stmts", "stmtList", "stmt", "assignStmt", + "callStmt", "ifStmt", "whileStmt", "readStmt", "printStmt", "blockStmt", + "condition", "dbCondition", "relOpCondition", "relOp", "expr", "term", + "factor", YY_NULLPTR + }; + return yy_sname[yysymbol]; +} +#endif + +#define YYPACT_NINF (-59) + +#define yypact_value_is_default(Yyn) \ + ((Yyn) == YYPACT_NINF) + +#define YYTABLE_NINF (-1) + +#define yytable_value_is_error(Yyn) \ + 0 + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +static const yytype_int8 yypact[] = +{ + -16, -59, 22, 36, -7, -59, -59, -59, 24, -59, + -59, 31, 41, 18, -59, 62, -59, -59, 44, 70, + -59, 24, -59, 43, 64, 75, 78, 2, 2, 79, + 9, -59, -59, -59, 63, 73, -59, -59, -59, -59, + -59, -59, -59, -59, -59, -59, -59, 82, 9, -16, + -59, -59, -59, 9, 9, 9, 9, 65, -59, -59, + 5, 50, -59, 60, -59, 54, -59, 48, -59, 54, + 77, -59, -59, 27, 14, 48, 9, 9, -59, -59, + -59, -59, -59, -59, 9, 9, 9, 48, -59, -59, + -59, 9, 0, 50, 50, 54, -59, -59, 68, 54, + -59, 48, -59, 69, -59 +}; + +/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ +static const yytype_int8 yydefact[] = +{ + 0, 6, 0, 0, 6, 4, 1, 2, 0, 11, + 5, 6, 0, 0, 8, 0, 16, 12, 6, 0, + 7, 0, 14, 0, 0, 0, 0, 0, 0, 0, + 0, 37, 19, 17, 0, 20, 21, 23, 24, 25, + 26, 27, 28, 29, 10, 9, 13, 0, 0, 0, + 31, 54, 55, 0, 0, 0, 0, 0, 38, 39, + 0, 48, 51, 0, 35, 36, 3, 0, 15, 30, + 0, 57, 56, 0, 0, 6, 0, 0, 42, 43, + 44, 45, 46, 47, 0, 0, 0, 6, 22, 18, + 58, 0, 0, 49, 50, 41, 52, 53, 0, 40, + 33, 6, 34, 0, 32 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -59, -59, 1, -59, 45, -59, -59, 71, -59, -59, + -59, -59, -59, -58, -59, 26, -59, -59, -59, -59, + -59, -59, -59, 66, -59, -59, -59, -30, 3, -51 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + 0, 2, 31, 4, 32, 10, 13, 14, 11, 17, + 23, 18, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 57, 58, 59, 84, 60, 61, 62 +}; + +/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ +static const yytype_int8 yytable[] = +{ + 65, 3, 71, 72, 1, 51, 52, 53, 54, 8, + 76, 77, 51, 52, 53, 54, 55, 92, 69, 76, + 77, 100, 6, 55, 101, 73, 74, 12, 20, 98, + 21, 56, 76, 77, 96, 97, 78, 79, 80, 81, + 82, 83, 90, 103, 91, 7, 5, 24, 15, 9, + 70, 24, 19, 46, 95, 47, 16, 85, 86, 76, + 77, 99, 25, 26, 1, 22, 27, 26, 1, 28, + 27, 29, 30, 28, 44, 29, 30, 48, 49, 93, + 94, 50, 64, 67, 66, 68, 87, 89, 75, 102, + 104, 0, 45, 88, 63 +}; + +static const yytype_int8 yycheck[] = +{ + 30, 0, 53, 54, 20, 3, 4, 5, 6, 16, + 5, 6, 3, 4, 5, 6, 14, 75, 48, 5, + 6, 21, 0, 14, 24, 55, 56, 3, 10, 87, + 12, 29, 5, 6, 85, 86, 31, 32, 33, 34, + 35, 36, 15, 101, 30, 9, 1, 3, 17, 4, + 49, 3, 11, 10, 84, 12, 11, 7, 8, 5, + 6, 91, 18, 19, 20, 3, 22, 19, 20, 25, + 22, 27, 28, 25, 4, 27, 28, 13, 3, 76, + 77, 3, 3, 10, 21, 3, 26, 10, 23, 21, + 21, -1, 21, 67, 28 +}; + +/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of + state STATE-NUM. */ +static const yytype_int8 yystos[] = +{ + 0, 20, 38, 39, 40, 41, 0, 9, 16, 41, + 42, 45, 3, 43, 44, 17, 41, 46, 48, 11, + 10, 12, 3, 47, 3, 18, 19, 22, 25, 27, + 28, 39, 41, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 4, 44, 10, 12, 13, 3, + 3, 3, 4, 5, 6, 14, 29, 60, 61, 62, + 64, 65, 66, 60, 3, 64, 21, 10, 3, 64, + 39, 66, 66, 64, 64, 23, 5, 6, 31, 32, + 33, 34, 35, 36, 63, 7, 8, 26, 52, 10, + 15, 30, 50, 65, 65, 64, 66, 66, 50, 64, + 21, 24, 21, 50, 21 +}; + +/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ +static const yytype_int8 yyr1[] = +{ + 0, 37, 38, 39, 40, 40, 41, 42, 43, 43, + 44, 45, 45, 46, 47, 47, 48, 48, 49, 50, + 50, 51, 51, 52, 52, 52, 52, 52, 52, 52, + 53, 54, 55, 55, 56, 57, 58, 59, 60, 60, + 61, 62, 63, 63, 63, 63, 63, 63, 64, 64, + 64, 65, 65, 65, 66, 66, 66, 66, 66 +}; + +/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ +static const yytype_int8 yyr2[] = +{ + 0, 2, 2, 6, 1, 2, 0, 3, 1, 3, + 3, 1, 2, 3, 1, 3, 1, 2, 4, 1, + 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, + 3, 2, 7, 5, 5, 2, 2, 1, 1, 1, + 4, 3, 1, 1, 1, 1, 1, 1, 1, 3, + 3, 1, 3, 3, 1, 1, 2, 2, 3 +}; + + +enum { YYENOMEM = -2 }; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab +#define YYNOMEM goto yyexhaustedlab + + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ + do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + YY_LAC_DISCARD ("YYBACKUP"); \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (file_name, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ + while (0) + +/* Backward compatibility with an undocumented macro. + Use YYerror or YYUNDEF. */ +#define YYERRCODE YYUNDEF + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (N) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (0) +#endif + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) + + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + + +/* YYLOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +# ifndef YYLOCATION_PRINT + +# if defined YY_LOCATION_PRINT + + /* Temporary convenience wrapper in case some people defined the + undocumented and private YY_LOCATION_PRINT macros. */ +# define YYLOCATION_PRINT(File, Loc) YY_LOCATION_PRINT(File, *(Loc)) + +# elif defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL + +/* Print *YYLOCP on YYO. Private, do not rely on its existence. */ + +YY_ATTRIBUTE_UNUSED +static int +yy_location_print_ (FILE *yyo, YYLTYPE const * const yylocp) +{ + int res = 0; + int end_col = 0 != yylocp->last_column ? yylocp->last_column - 1 : 0; + if (0 <= yylocp->first_line) + { + res += YYFPRINTF (yyo, "%d", yylocp->first_line); + if (0 <= yylocp->first_column) + res += YYFPRINTF (yyo, ".%d", yylocp->first_column); + } + if (0 <= yylocp->last_line) + { + if (yylocp->first_line < yylocp->last_line) + { + res += YYFPRINTF (yyo, "-%d", yylocp->last_line); + if (0 <= end_col) + res += YYFPRINTF (yyo, ".%d", end_col); + } + else if (0 <= end_col && yylocp->first_column < end_col) + res += YYFPRINTF (yyo, "-%d", end_col); + } + return res; +} + +# define YYLOCATION_PRINT yy_location_print_ + + /* Temporary convenience wrapper in case some people defined the + undocumented and private YY_LOCATION_PRINT macros. */ +# define YY_LOCATION_PRINT(File, Loc) YYLOCATION_PRINT(File, &(Loc)) + +# else + +# define YYLOCATION_PRINT(File, Loc) ((void) 0) + /* Temporary convenience wrapper in case some people defined the + undocumented and private YY_LOCATION_PRINT macros. */ +# define YY_LOCATION_PRINT YYLOCATION_PRINT + +# endif +# endif /* !defined YYLOCATION_PRINT */ + + +# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Kind, Value, Location, file_name); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + + +/*-----------------------------------. +| Print this symbol's value on YYO. | +`-----------------------------------*/ + +static void +yy_symbol_value_print (FILE *yyo, + yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, char const *file_name) +{ + FILE *yyoutput = yyo; + YY_USE (yyoutput); + YY_USE (yylocationp); + YY_USE (file_name); + if (!yyvaluep) + return; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YY_USE (yykind); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + +/*---------------------------. +| Print this symbol on YYO. | +`---------------------------*/ + +static void +yy_symbol_print (FILE *yyo, + yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, char const *file_name) +{ + YYFPRINTF (yyo, "%s %s (", + yykind < YYNTOKENS ? "token" : "nterm", yysymbol_name (yykind)); + + YYLOCATION_PRINT (yyo, yylocationp); + YYFPRINTF (yyo, ": "); + yy_symbol_value_print (yyo, yykind, yyvaluep, yylocationp, file_name); + YYFPRINTF (yyo, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +static void +yy_stack_print (yy_state_t *yybottom, yy_state_t *yytop) +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +static void +yy_reduce_print (yy_state_t *yyssp, YYSTYPE *yyvsp, YYLTYPE *yylsp, + int yyrule, char const *file_name) +{ + int yylno = yyrline[yyrule]; + int yynrhs = yyr2[yyrule]; + int yyi; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %d):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, + YY_ACCESSING_SYMBOL (+yyssp[yyi + 1 - yynrhs]), + &yyvsp[(yyi + 1) - (yynrhs)], + &(yylsp[(yyi + 1) - (yynrhs)]), file_name); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyssp, yyvsp, yylsp, Rule, file_name); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) ((void) 0) +# define YY_SYMBOL_PRINT(Title, Kind, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +/* Given a state stack such that *YYBOTTOM is its bottom, such that + *YYTOP is either its top or is YYTOP_EMPTY to indicate an empty + stack, and such that *YYCAPACITY is the maximum number of elements it + can hold without a reallocation, make sure there is enough room to + store YYADD more elements. If not, allocate a new stack using + YYSTACK_ALLOC, copy the existing elements, and adjust *YYBOTTOM, + *YYTOP, and *YYCAPACITY to reflect the new capacity and memory + location. If *YYBOTTOM != YYBOTTOM_NO_FREE, then free the old stack + using YYSTACK_FREE. Return 0 if successful or if no reallocation is + required. Return YYENOMEM if memory is exhausted. */ +static int +yy_lac_stack_realloc (YYPTRDIFF_T *yycapacity, YYPTRDIFF_T yyadd, +#if YYDEBUG + char const *yydebug_prefix, + char const *yydebug_suffix, +#endif + yy_state_t **yybottom, + yy_state_t *yybottom_no_free, + yy_state_t **yytop, yy_state_t *yytop_empty) +{ + YYPTRDIFF_T yysize_old = + *yytop == yytop_empty ? 0 : *yytop - *yybottom + 1; + YYPTRDIFF_T yysize_new = yysize_old + yyadd; + if (*yycapacity < yysize_new) + { + YYPTRDIFF_T yyalloc = 2 * yysize_new; + yy_state_t *yybottom_new; + /* Use YYMAXDEPTH for maximum stack size given that the stack + should never need to grow larger than the main state stack + needs to grow without LAC. */ + if (YYMAXDEPTH < yysize_new) + { + YYDPRINTF ((stderr, "%smax size exceeded%s", yydebug_prefix, + yydebug_suffix)); + return YYENOMEM; + } + if (YYMAXDEPTH < yyalloc) + yyalloc = YYMAXDEPTH; + yybottom_new = + YY_CAST (yy_state_t *, + YYSTACK_ALLOC (YY_CAST (YYSIZE_T, + yyalloc * YYSIZEOF (*yybottom_new)))); + if (!yybottom_new) + { + YYDPRINTF ((stderr, "%srealloc failed%s", yydebug_prefix, + yydebug_suffix)); + return YYENOMEM; + } + if (*yytop != yytop_empty) + { + YYCOPY (yybottom_new, *yybottom, yysize_old); + *yytop = yybottom_new + (yysize_old - 1); + } + if (*yybottom != yybottom_no_free) + YYSTACK_FREE (*yybottom); + *yybottom = yybottom_new; + *yycapacity = yyalloc; + } + return 0; +} + +/* Establish the initial context for the current lookahead if no initial + context is currently established. + + We define a context as a snapshot of the parser stacks. We define + the initial context for a lookahead as the context in which the + parser initially examines that lookahead in order to select a + syntactic action. Thus, if the lookahead eventually proves + syntactically unacceptable (possibly in a later context reached via a + series of reductions), the initial context can be used to determine + the exact set of tokens that would be syntactically acceptable in the + lookahead's place. Moreover, it is the context after which any + further semantic actions would be erroneous because they would be + determined by a syntactically unacceptable token. + + YY_LAC_ESTABLISH should be invoked when a reduction is about to be + performed in an inconsistent state (which, for the purposes of LAC, + includes consistent states that don't know they're consistent because + their default reductions have been disabled). Iff there is a + lookahead token, it should also be invoked before reporting a syntax + error. This latter case is for the sake of the debugging output. + + For parse.lac=full, the implementation of YY_LAC_ESTABLISH is as + follows. If no initial context is currently established for the + current lookahead, then check if that lookahead can eventually be + shifted if syntactic actions continue from the current context. + Report a syntax error if it cannot. */ +#define YY_LAC_ESTABLISH \ +do { \ + if (!yy_lac_established) \ + { \ + YYDPRINTF ((stderr, \ + "LAC: initial context established for %s\n", \ + yysymbol_name (yytoken))); \ + yy_lac_established = 1; \ + switch (yy_lac (yyesa, &yyes, &yyes_capacity, yyssp, yytoken)) \ + { \ + case YYENOMEM: \ + YYNOMEM; \ + case 1: \ + goto yyerrlab; \ + } \ + } \ +} while (0) + +/* Discard any previous initial lookahead context because of Event, + which may be a lookahead change or an invalidation of the currently + established initial context for the current lookahead. + + The most common example of a lookahead change is a shift. An example + of both cases is syntax error recovery. That is, a syntax error + occurs when the lookahead is syntactically erroneous for the + currently established initial context, so error recovery manipulates + the parser stacks to try to find a new initial context in which the + current lookahead is syntactically acceptable. If it fails to find + such a context, it discards the lookahead. */ +#if YYDEBUG +# define YY_LAC_DISCARD(Event) \ +do { \ + if (yy_lac_established) \ + { \ + YYDPRINTF ((stderr, "LAC: initial context discarded due to " \ + Event "\n")); \ + yy_lac_established = 0; \ + } \ +} while (0) +#else +# define YY_LAC_DISCARD(Event) yy_lac_established = 0 +#endif + +/* Given the stack whose top is *YYSSP, return 0 iff YYTOKEN can + eventually (after perhaps some reductions) be shifted, return 1 if + not, or return YYENOMEM if memory is exhausted. As preconditions and + postconditions: *YYES_CAPACITY is the allocated size of the array to + which *YYES points, and either *YYES = YYESA or *YYES points to an + array allocated with YYSTACK_ALLOC. yy_lac may overwrite the + contents of either array, alter *YYES and *YYES_CAPACITY, and free + any old *YYES other than YYESA. */ +static int +yy_lac (yy_state_t *yyesa, yy_state_t **yyes, + YYPTRDIFF_T *yyes_capacity, yy_state_t *yyssp, yysymbol_kind_t yytoken) +{ + yy_state_t *yyes_prev = yyssp; + yy_state_t *yyesp = yyes_prev; + /* Reduce until we encounter a shift and thereby accept the token. */ + YYDPRINTF ((stderr, "LAC: checking lookahead %s:", yysymbol_name (yytoken))); + if (yytoken == YYSYMBOL_YYUNDEF) + { + YYDPRINTF ((stderr, " Always Err\n")); + return 1; + } + while (1) + { + int yyrule = yypact[+*yyesp]; + if (yypact_value_is_default (yyrule) + || (yyrule += yytoken) < 0 || YYLAST < yyrule + || yycheck[yyrule] != yytoken) + { + /* Use the default action. */ + yyrule = yydefact[+*yyesp]; + if (yyrule == 0) + { + YYDPRINTF ((stderr, " Err\n")); + return 1; + } + } + else + { + /* Use the action from yytable. */ + yyrule = yytable[yyrule]; + if (yytable_value_is_error (yyrule)) + { + YYDPRINTF ((stderr, " Err\n")); + return 1; + } + if (0 < yyrule) + { + YYDPRINTF ((stderr, " S%d\n", yyrule)); + return 0; + } + yyrule = -yyrule; + } + /* By now we know we have to simulate a reduce. */ + YYDPRINTF ((stderr, " R%d", yyrule - 1)); + { + /* Pop the corresponding number of values from the stack. */ + YYPTRDIFF_T yylen = yyr2[yyrule]; + /* First pop from the LAC stack as many tokens as possible. */ + if (yyesp != yyes_prev) + { + YYPTRDIFF_T yysize = yyesp - *yyes + 1; + if (yylen < yysize) + { + yyesp -= yylen; + yylen = 0; + } + else + { + yyesp = yyes_prev; + yylen -= yysize; + } + } + /* Only afterwards look at the main stack. */ + if (yylen) + yyesp = yyes_prev -= yylen; + } + /* Push the resulting state of the reduction. */ + { + yy_state_fast_t yystate; + { + const int yylhs = yyr1[yyrule] - YYNTOKENS; + const int yyi = yypgoto[yylhs] + *yyesp; + yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyesp + ? yytable[yyi] + : yydefgoto[yylhs]); + } + if (yyesp == yyes_prev) + { + yyesp = *yyes; + YY_IGNORE_USELESS_CAST_BEGIN + *yyesp = YY_CAST (yy_state_t, yystate); + YY_IGNORE_USELESS_CAST_END + } + else + { + if (yy_lac_stack_realloc (yyes_capacity, 1, +#if YYDEBUG + " (", ")", +#endif + yyes, yyesa, &yyesp, yyes_prev)) + { + YYDPRINTF ((stderr, "\n")); + return YYENOMEM; + } + YY_IGNORE_USELESS_CAST_BEGIN + *++yyesp = YY_CAST (yy_state_t, yystate); + YY_IGNORE_USELESS_CAST_END + } + YYDPRINTF ((stderr, " G%d", yystate)); + } + } +} + +/* Context of a parse error. */ +typedef struct +{ + yy_state_t *yyssp; + yy_state_t *yyesa; + yy_state_t **yyes; + YYPTRDIFF_T *yyes_capacity; + yysymbol_kind_t yytoken; + YYLTYPE *yylloc; +} yypcontext_t; + +/* Put in YYARG at most YYARGN of the expected tokens given the + current YYCTX, and return the number of tokens stored in YYARG. If + YYARG is null, return the number of expected tokens (guaranteed to + be less than YYNTOKENS). Return YYENOMEM on memory exhaustion. + Return 0 if there are more than YYARGN expected tokens, yet fill + YYARG up to YYARGN. */ +static int +yypcontext_expected_tokens (const yypcontext_t *yyctx, + yysymbol_kind_t yyarg[], int yyargn) +{ + /* Actual size of YYARG. */ + int yycount = 0; + + int yyx; + for (yyx = 0; yyx < YYNTOKENS; ++yyx) + { + yysymbol_kind_t yysym = YY_CAST (yysymbol_kind_t, yyx); + if (yysym != YYSYMBOL_YYerror && yysym != YYSYMBOL_YYUNDEF) + switch (yy_lac (yyctx->yyesa, yyctx->yyes, yyctx->yyes_capacity, yyctx->yyssp, yysym)) + { + case YYENOMEM: + return YYENOMEM; + case 1: + continue; + default: + if (!yyarg) + ++yycount; + else if (yycount == yyargn) + return 0; + else + yyarg[yycount++] = yysym; + } + } + if (yyarg && yycount == 0 && 0 < yyargn) + yyarg[0] = YYSYMBOL_YYEMPTY; + return yycount; +} + + + + +#ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen(S) (YY_CAST (YYPTRDIFF_T, strlen (S))) +# else +/* Return the length of YYSTR. */ +static YYPTRDIFF_T +yystrlen (const char *yystr) +{ + YYPTRDIFF_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +#endif + +#ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +yystpcpy (char *yydest, const char *yysrc) +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +#endif + + + +static int +yy_syntax_error_arguments (const yypcontext_t *yyctx, + yysymbol_kind_t yyarg[], int yyargn) +{ + /* Actual size of YYARG. */ + int yycount = 0; + /* There are many possibilities here to consider: + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + In the first two cases, it might appear that the current syntax + error should have been detected in the previous state when yy_lac + was invoked. However, at that time, there might have been a + different syntax error that discarded a different initial context + during error recovery, leaving behind the current lookahead. + */ + if (yyctx->yytoken != YYSYMBOL_YYEMPTY) + { + int yyn; + YYDPRINTF ((stderr, "Constructing syntax error message\n")); + if (yyarg) + yyarg[yycount] = yyctx->yytoken; + ++yycount; + yyn = yypcontext_expected_tokens (yyctx, + yyarg ? yyarg + 1 : yyarg, yyargn - 1); + if (yyn == YYENOMEM) + return YYENOMEM; + else if (yyn == 0) + YYDPRINTF ((stderr, "No expected tokens.\n")); + else + yycount += yyn; + } + return yycount; +} + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. In order to see if a particular token T is a + valid looakhead, invoke yy_lac (YYESA, YYES, YYES_CAPACITY, YYSSP, T). + + Return 0 if *YYMSG was successfully written. Return -1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return YYENOMEM if the + required number of bytes is too large to store or if + yy_lac returned YYENOMEM. */ +static int +yysyntax_error (YYPTRDIFF_T *yymsg_alloc, char **yymsg, + const yypcontext_t *yyctx) +{ + enum { YYARGS_MAX = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULLPTR; + /* Arguments of yyformat: reported tokens (one for the "unexpected", + one per "expected"). */ + yysymbol_kind_t yyarg[YYARGS_MAX]; + /* Cumulated lengths of YYARG. */ + YYPTRDIFF_T yysize = 0; + + /* Actual size of YYARG. */ + int yycount = yy_syntax_error_arguments (yyctx, yyarg, YYARGS_MAX); + if (yycount == YYENOMEM) + return YYENOMEM; + + switch (yycount) + { +#define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + default: /* Avoid compiler warnings. */ + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +#undef YYCASE_ + } + + /* Compute error message size. Don't count the "%s"s, but reserve + room for the terminator. */ + yysize = yystrlen (yyformat) - 2 * yycount + 1; + { + int yyi; + for (yyi = 0; yyi < yycount; ++yyi) + { + YYPTRDIFF_T yysize1 + = yysize + yystrlen (yysymbol_name (yyarg[yyi])); + if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM) + yysize = yysize1; + else + return YYENOMEM; + } + } + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return -1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp = yystpcpy (yyp, yysymbol_name (yyarg[yyi++])); + yyformat += 2; + } + else + { + ++yyp; + ++yyformat; + } + } + return 0; +} + + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +static void +yydestruct (const char *yymsg, + yysymbol_kind_t yykind, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, char const *file_name) +{ + YY_USE (yyvaluep); + YY_USE (yylocationp); + YY_USE (file_name); + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YY_USE (yykind); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + +/* Lookahead token kind. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; +/* Location data for the lookahead symbol. */ +YYLTYPE yylloc +# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL + = { 1, 1, 1, 1 } +# endif +; +/* Number of syntax errors so far. */ +int yynerrs; + + + + +/*----------. +| yyparse. | +`----------*/ + +int +yyparse (char const *file_name) +{ + yy_state_fast_t yystate = 0; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus = 0; + + /* Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* Their size. */ + YYPTRDIFF_T yystacksize = YYINITDEPTH; + + /* The state stack: array, bottom, top. */ + yy_state_t yyssa[YYINITDEPTH]; + yy_state_t *yyss = yyssa; + yy_state_t *yyssp = yyss; + + /* The semantic value stack: array, bottom, top. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + YYSTYPE *yyvsp = yyvs; + + /* The location stack: array, bottom, top. */ + YYLTYPE yylsa[YYINITDEPTH]; + YYLTYPE *yyls = yylsa; + YYLTYPE *yylsp = yyls; + + yy_state_t yyesa[20]; + yy_state_t *yyes = yyesa; + YYPTRDIFF_T yyes_capacity = 20 < YYMAXDEPTH ? 20 : YYMAXDEPTH; + + /* Whether LAC context is established. A Boolean. */ + int yy_lac_established = 0; + int yyn; + /* The return value of yyparse. */ + int yyresult; + /* Lookahead symbol kind. */ + yysymbol_kind_t yytoken = YYSYMBOL_YYEMPTY; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + YYLTYPE yyloc; + + /* The locations where the error started and ended. */ + YYLTYPE yyerror_range[3]; + + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYPTRDIFF_T yymsg_alloc = sizeof yymsgbuf; + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yychar = YYEMPTY; /* Cause a token to be read. */ + + yylsp[0] = yylloc; + goto yysetstate; + + +/*------------------------------------------------------------. +| yynewstate -- push a new state, which is found in yystate. | +`------------------------------------------------------------*/ +yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + +/*--------------------------------------------------------------------. +| yysetstate -- set current state (the top of the stack) to yystate. | +`--------------------------------------------------------------------*/ +yysetstate: + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + YY_ASSERT (0 <= yystate && yystate < YYNSTATES); + YY_IGNORE_USELESS_CAST_BEGIN + *yyssp = YY_CAST (yy_state_t, yystate); + YY_IGNORE_USELESS_CAST_END + YY_STACK_PRINT (yyss, yyssp); + + if (yyss + yystacksize - 1 <= yyssp) +#if !defined yyoverflow && !defined YYSTACK_RELOCATE + YYNOMEM; +#else + { + /* Get the current used size of the three stacks, in elements. */ + YYPTRDIFF_T yysize = yyssp - yyss + 1; + +# if defined yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + yy_state_t *yyss1 = yyss; + YYSTYPE *yyvs1 = yyvs; + YYLTYPE *yyls1 = yyls; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * YYSIZEOF (*yyssp), + &yyvs1, yysize * YYSIZEOF (*yyvsp), + &yyls1, yysize * YYSIZEOF (*yylsp), + &yystacksize); + yyss = yyss1; + yyvs = yyvs1; + yyls = yyls1; + } +# else /* defined YYSTACK_RELOCATE */ + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + YYNOMEM; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yy_state_t *yyss1 = yyss; + union yyalloc *yyptr = + YY_CAST (union yyalloc *, + YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); + if (! yyptr) + YYNOMEM; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); + YYSTACK_RELOCATE (yyls_alloc, yyls); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + yylsp = yyls + yysize - 1; + + YY_IGNORE_USELESS_CAST_BEGIN + YYDPRINTF ((stderr, "Stack size increased to %ld\n", + YY_CAST (long, yystacksize))); + YY_IGNORE_USELESS_CAST_END + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } +#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ + + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either empty, or end-of-input, or a valid lookahead. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token\n")); + yychar = yylex (); + } + + if (yychar <= YYEOF) + { + yychar = YYEOF; + yytoken = YYSYMBOL_YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else if (yychar == YYerror) + { + /* The scanner already issued an error message, process directly + to error recovery. But do not keep the error token as + lookahead, it is too special and may lead us to an endless + loop in error recovery. */ + yychar = YYUNDEF; + yytoken = YYSYMBOL_YYerror; + yyerror_range[1] = yylloc; + goto yyerrlab1; + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + { + YY_LAC_ESTABLISH; + goto yydefault; + } + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + YY_LAC_ESTABLISH; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + *++yylsp = yylloc; + + /* Discard the shifted token. */ + yychar = YYEMPTY; + YY_LAC_DISCARD ("shift"); + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + '$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + /* Default location. */ + YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); + yyerror_range[1] = yyloc; + YY_REDUCE_PRINT (yyn); + { + int yychar_backup = yychar; + switch (yyn) + { + case 2: /* program: block "." */ +#line 121 "spl.y" + { setProgAST((yyvsp[-1].block)); } +#line 1781 "spl.tab.c" + break; + + case 3: /* block: "begin" constDecls varDecls procDecls stmts "end" */ +#line 125 "spl.y" + { (yyval.block) = ast_block((yyvsp[-5].token),(yyvsp[-4].const_decls),(yyvsp[-3].var_decls),(yyvsp[-2].proc_decls),(yyvsp[-1].stmts)); } +#line 1787 "spl.tab.c" + break; + + case 4: /* constDecls: empty */ +#line 128 "spl.y" + { (yyval.const_decls) = ast_const_decls_empty((yyvsp[0].empty)); } +#line 1793 "spl.tab.c" + break; + + case 5: /* constDecls: constDecls constDecl */ +#line 130 "spl.y" + { (yyval.const_decls) = ast_const_decls((yyvsp[-1].const_decls), (yyvsp[0].const_decl)); } +#line 1799 "spl.tab.c" + break; + + case 6: /* empty: %empty */ +#line 134 "spl.y" + { file_location *file_loc + = file_location_make(lexer_filename(), lexer_line()); + (yyval.empty) = ast_empty(file_loc); + } +#line 1808 "spl.tab.c" + break; + + case 7: /* constDecl: "const" constDefList ";" */ +#line 140 "spl.y" + { (yyval.const_decl) = ast_const_decl((yyvsp[-1].const_def_list)); } +#line 1814 "spl.tab.c" + break; + + case 8: /* constDefList: constDef */ +#line 142 "spl.y" + { (yyval.const_def_list) = ast_const_def_list_singleton((yyvsp[0].const_def)); } +#line 1820 "spl.tab.c" + break; + + case 9: /* constDefList: constDefList "," constDef */ +#line 144 "spl.y" + { (yyval.const_def_list) = ast_const_def_list((yyvsp[-2].const_def_list), (yyvsp[0].const_def)); } +#line 1826 "spl.tab.c" + break; + + case 10: /* constDef: identsym "=" numbersym */ +#line 147 "spl.y" + { (yyval.const_def) = ast_const_def((yyvsp[-2].ident), (yyvsp[0].number)); } +#line 1832 "spl.tab.c" + break; + + case 11: /* varDecls: empty */ +#line 149 "spl.y" + { (yyval.var_decls) = ast_var_decls_empty((yyvsp[0].empty)); } +#line 1838 "spl.tab.c" + break; + + case 12: /* varDecls: varDecls varDecl */ +#line 150 "spl.y" + { (yyval.var_decls) = ast_var_decls((yyvsp[-1].var_decls), (yyvsp[0].var_decl)); } +#line 1844 "spl.tab.c" + break; + + case 13: /* varDecl: "var" identList ";" */ +#line 153 "spl.y" + { (yyval.var_decl) = ast_var_decl((yyvsp[-1].ident_list)); } +#line 1850 "spl.tab.c" + break; + + case 14: /* identList: identsym */ +#line 155 "spl.y" + { (yyval.ident_list) = ast_ident_list_singleton((yyvsp[0].ident)); } +#line 1856 "spl.tab.c" + break; + + case 15: /* identList: identList "," identsym */ +#line 156 "spl.y" + { (yyval.ident_list) = ast_ident_list((yyvsp[-2].ident_list), (yyvsp[0].ident)); } +#line 1862 "spl.tab.c" + break; + + case 16: /* procDecls: empty */ +#line 159 "spl.y" + { (yyval.proc_decls) = ast_proc_decls_empty((yyvsp[0].empty)); } +#line 1868 "spl.tab.c" + break; + + case 17: /* procDecls: procDecls procDecl */ +#line 160 "spl.y" + { (yyval.proc_decls) = ast_proc_decls((yyvsp[-1].proc_decls), (yyvsp[0].proc_decl)); } +#line 1874 "spl.tab.c" + break; + + case 18: /* procDecl: "proc" identsym block ";" */ +#line 163 "spl.y" + { (yyval.proc_decl) = ast_proc_decl((yyvsp[-2].ident), (yyvsp[-1].block)); } +#line 1880 "spl.tab.c" + break; + + case 19: /* stmts: empty */ +#line 165 "spl.y" + { (yyval.stmts) = ast_stmts_empty((yyvsp[0].empty)); } +#line 1886 "spl.tab.c" + break; + + case 20: /* stmts: stmtList */ +#line 166 "spl.y" + { (yyval.stmts) = ast_stmts((yyvsp[0].stmt_list)); } +#line 1892 "spl.tab.c" + break; + + case 21: /* stmtList: stmt */ +#line 169 "spl.y" + { (yyval.stmt_list) = ast_stmt_list_singleton((yyvsp[0].stmt)); } +#line 1898 "spl.tab.c" + break; + + case 22: /* stmtList: stmtList ";" stmt */ +#line 170 "spl.y" + { (yyval.stmt_list) = ast_stmt_list((yyvsp[-2].stmt_list),(yyvsp[0].stmt)); } +#line 1904 "spl.tab.c" + break; + + case 23: /* stmt: assignStmt */ +#line 173 "spl.y" + { (yyval.stmt) = ast_stmt_assign((yyvsp[0].assign_stmt)); } +#line 1910 "spl.tab.c" + break; + + case 24: /* stmt: callStmt */ +#line 174 "spl.y" + { (yyval.stmt) = ast_stmt_call((yyvsp[0].call_stmt)); } +#line 1916 "spl.tab.c" + break; + + case 25: /* stmt: ifStmt */ +#line 175 "spl.y" + { (yyval.stmt) = ast_stmt_if((yyvsp[0].if_stmt)); } +#line 1922 "spl.tab.c" + break; + + case 26: /* stmt: whileStmt */ +#line 176 "spl.y" + { (yyval.stmt) = ast_stmt_while((yyvsp[0].while_stmt)); } +#line 1928 "spl.tab.c" + break; + + case 27: /* stmt: readStmt */ +#line 177 "spl.y" + { (yyval.stmt) = ast_stmt_read((yyvsp[0].read_stmt)); } +#line 1934 "spl.tab.c" + break; + + case 28: /* stmt: printStmt */ +#line 178 "spl.y" + { (yyval.stmt) = ast_stmt_print((yyvsp[0].print_stmt)); } +#line 1940 "spl.tab.c" + break; + + case 29: /* stmt: blockStmt */ +#line 179 "spl.y" + { (yyval.stmt) = ast_stmt_block((yyvsp[0].block_stmt)); } +#line 1946 "spl.tab.c" + break; + + case 30: /* assignStmt: identsym ":=" expr */ +#line 182 "spl.y" + { (yyval.assign_stmt) = ast_assign_stmt((yyvsp[-2].ident),(yyvsp[0].expr)); } +#line 1952 "spl.tab.c" + break; + + case 31: /* callStmt: "call" identsym */ +#line 184 "spl.y" + { (yyval.call_stmt) = ast_call_stmt((yyvsp[0].ident)); } +#line 1958 "spl.tab.c" + break; + + case 32: /* ifStmt: "if" condition "then" stmts "else" stmts "end" */ +#line 187 "spl.y" + { (yyval.if_stmt) = ast_if_then_else_stmt((yyvsp[-5].condition), (yyvsp[-3].stmts), (yyvsp[-1].stmts)); } +#line 1964 "spl.tab.c" + break; + + case 33: /* ifStmt: "if" condition "then" stmts "end" */ +#line 189 "spl.y" + { (yyval.if_stmt) = ast_if_then_stmt((yyvsp[-3].condition), (yyvsp[-1].stmts)); } +#line 1970 "spl.tab.c" + break; + + case 34: /* whileStmt: "while" condition "do" stmts "end" */ +#line 193 "spl.y" + { (yyval.while_stmt) = ast_while_stmt((yyvsp[-3].condition),(yyvsp[-1].stmts)); } +#line 1976 "spl.tab.c" + break; + + case 35: /* readStmt: "read" identsym */ +#line 195 "spl.y" + { (yyval.read_stmt) = ast_read_stmt((yyvsp[0].ident)); } +#line 1982 "spl.tab.c" + break; + + case 36: /* printStmt: "print" expr */ +#line 197 "spl.y" + { (yyval.print_stmt) = ast_print_stmt((yyvsp[0].expr)); } +#line 1988 "spl.tab.c" + break; + + case 37: /* blockStmt: block */ +#line 199 "spl.y" + { (yyval.block_stmt) = ast_block_stmt((yyvsp[0].block)); } +#line 1994 "spl.tab.c" + break; + + case 38: /* condition: dbCondition */ +#line 201 "spl.y" + { (yyval.condition) = ast_condition_db((yyvsp[0].db_condition)); } +#line 2000 "spl.tab.c" + break; + + case 39: /* condition: relOpCondition */ +#line 202 "spl.y" + { (yyval.condition) = ast_condition_rel_op((yyvsp[0].rel_op_condition)); } +#line 2006 "spl.tab.c" + break; + + case 40: /* dbCondition: "divisible" expr "by" expr */ +#line 205 "spl.y" + { (yyval.db_condition) = ast_db_condition((yyvsp[-2].expr),(yyvsp[0].expr)); } +#line 2012 "spl.tab.c" + break; + + case 41: /* relOpCondition: expr relOp expr */ +#line 207 "spl.y" + { (yyval.rel_op_condition) = ast_rel_op_condition((yyvsp[-2].expr), (yyvsp[-1].token), (yyvsp[0].expr)); } +#line 2018 "spl.tab.c" + break; + + case 49: /* expr: expr "+" term */ +#line 213 "spl.y" + { (yyval.expr) = ast_expr_binary_op(ast_binary_op_expr((yyvsp[-2].expr), (yyvsp[-1].token), (yyvsp[0].expr))); } +#line 2024 "spl.tab.c" + break; + + case 50: /* expr: expr "-" term */ +#line 215 "spl.y" + { (yyval.expr) = ast_expr_binary_op(ast_binary_op_expr((yyvsp[-2].expr), (yyvsp[-1].token), (yyvsp[0].expr))); } +#line 2030 "spl.tab.c" + break; + + case 52: /* term: term "*" factor */ +#line 220 "spl.y" + { (yyval.expr) = ast_expr_binary_op(ast_binary_op_expr((yyvsp[-2].expr), (yyvsp[-1].token), (yyvsp[0].expr))); } +#line 2036 "spl.tab.c" + break; + + case 53: /* term: term "/" factor */ +#line 222 "spl.y" + { (yyval.expr) = ast_expr_binary_op(ast_binary_op_expr((yyvsp[-2].expr), (yyvsp[-1].token), (yyvsp[0].expr))); } +#line 2042 "spl.tab.c" + break; + + case 54: /* factor: identsym */ +#line 225 "spl.y" + { (yyval.expr) = ast_expr_ident((yyvsp[0].ident)); } +#line 2048 "spl.tab.c" + break; + + case 55: /* factor: numbersym */ +#line 226 "spl.y" + { (yyval.expr) = ast_expr_number((yyvsp[0].number)); } +#line 2054 "spl.tab.c" + break; + + case 56: /* factor: "-" factor */ +#line 227 "spl.y" + { (yyval.expr) = ast_expr_signed_expr((yyvsp[-1].token), (yyvsp[0].expr)); } +#line 2060 "spl.tab.c" + break; + + case 57: /* factor: "+" factor */ +#line 228 "spl.y" + { (yyval.expr) = ast_expr_signed_expr((yyvsp[-1].token), (yyvsp[0].expr)); } +#line 2066 "spl.tab.c" + break; + + case 58: /* factor: "(" expr ")" */ +#line 229 "spl.y" + { (yyval.expr) = (yyvsp[-1].expr); } +#line 2072 "spl.tab.c" + break; + + +#line 2076 "spl.tab.c" + + default: break; + } + if (yychar_backup != yychar) + YY_LAC_DISCARD ("yychar change"); + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", YY_CAST (yysymbol_kind_t, yyr1[yyn]), &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + + *++yyvsp = yyval; + *++yylsp = yyloc; + + /* Now 'shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + { + const int yylhs = yyr1[yyn] - YYNTOKENS; + const int yyi = yypgoto[yylhs] + *yyssp; + yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp + ? yytable[yyi] + : yydefgoto[yylhs]); + } + + goto yynewstate; + + +/*--------------------------------------. +| yyerrlab -- here on detecting error. | +`--------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYSYMBOL_YYEMPTY : YYTRANSLATE (yychar); + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; + { + yypcontext_t yyctx + = {yyssp, yyesa, &yyes, &yyes_capacity, yytoken, &yylloc}; + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + if (yychar != YYEMPTY) + YY_LAC_ESTABLISH; + yysyntax_error_status = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == -1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = YY_CAST (char *, + YYSTACK_ALLOC (YY_CAST (YYSIZE_T, yymsg_alloc))); + if (yymsg) + { + yysyntax_error_status + = yysyntax_error (&yymsg_alloc, &yymsg, &yyctx); + yymsgp = yymsg; + } + else + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = YYENOMEM; + } + } + yyerror (file_name, yymsgp); + if (yysyntax_error_status == YYENOMEM) + YYNOMEM; + } + } + + yyerror_range[1] = yylloc; + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval, &yylloc, file_name); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + /* Pacify compilers when the user code never invokes YYERROR and the + label yyerrorlab therefore never appears in user code. */ + if (0) + YYERROR; + ++yynerrs; + + /* Do not reclaim the symbols of the rule whose action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + /* Pop stack until we find a state that shifts the error token. */ + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYSYMBOL_YYerror; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYSYMBOL_YYerror) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + yyerror_range[1] = *yylsp; + yydestruct ("Error: popping", + YY_ACCESSING_SYMBOL (yystate), yyvsp, yylsp, file_name); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + /* If the stack popping above didn't lose the initial context for the + current lookahead token, the shift below will for sure. */ + YY_LAC_DISCARD ("error recovery"); + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + yyerror_range[2] = yylloc; + ++yylsp; + YYLLOC_DEFAULT (*yylsp, yyerror_range, 2); + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", YY_ACCESSING_SYMBOL (yyn), yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturnlab; + + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturnlab; + + +/*-----------------------------------------------------------. +| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. | +`-----------------------------------------------------------*/ +yyexhaustedlab: + yyerror (file_name, YY_("memory exhausted")); + yyresult = 2; + goto yyreturnlab; + + +/*----------------------------------------------------------. +| yyreturnlab -- parsing is finished, clean up and return. | +`----------------------------------------------------------*/ +yyreturnlab: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval, &yylloc, file_name); + } + /* Do not reclaim the symbols of the rule whose action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + YY_ACCESSING_SYMBOL (+*yyssp), yyvsp, yylsp, file_name); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif + if (yyes != yyesa) + YYSTACK_FREE (yyes); + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + return yyresult; +} + +#line 232 "spl.y" + + +// Set the program's ast to be ast +void setProgAST(block_t ast) { progast = ast; } diff --git a/FromGithub/spl.tab.h b/FromGithub/spl.tab.h new file mode 100644 index 0000000..67e53e1 --- /dev/null +++ b/FromGithub/spl.tab.h @@ -0,0 +1,133 @@ +/* A Bison parser, made by GNU Bison 3.8.2. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, + Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual, + especially those whose name start with YY_ or yy_. They are + private implementation details that can be changed or removed. */ + +#ifndef YY_YY_SPL_TAB_H_INCLUDED +# define YY_YY_SPL_TAB_H_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif +/* "%code requires" blocks. */ +#line 7 "spl.y" + + + /* Including "ast.h" must be at the top, to define the AST type */ +#include "ast.h" +#include "machine_types.h" +#include "parser_types.h" +#include "lexer.h" + + /* Report an error to the user on stderr */ +extern void yyerror(const char *filename, const char *msg); + + +#line 62 "spl.tab.h" + +/* Token kinds. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + YYEMPTY = -2, + YYEOF = 0, /* "end of file" */ + YYerror = 256, /* error */ + YYUNDEF = 257, /* "invalid token" */ + identsym = 258, /* identsym */ + numbersym = 259, /* numbersym */ + plussym = 260, /* "+" */ + minussym = 261, /* "-" */ + multsym = 262, /* "*" */ + divsym = 263, /* "/" */ + periodsym = 264, /* "." */ + semisym = 265, /* ";" */ + eqsym = 266, /* "=" */ + commasym = 267, /* "," */ + becomessym = 268, /* ":=" */ + lparensym = 269, /* "(" */ + rparensym = 270, /* ")" */ + constsym = 271, /* "const" */ + varsym = 272, /* "var" */ + procsym = 273, /* "proc" */ + callsym = 274, /* "call" */ + beginsym = 275, /* "begin" */ + endsym = 276, /* "end" */ + ifsym = 277, /* "if" */ + thensym = 278, /* "then" */ + elsesym = 279, /* "else" */ + whilesym = 280, /* "while" */ + dosym = 281, /* "do" */ + readsym = 282, /* "read" */ + printsym = 283, /* "print" */ + divisiblesym = 284, /* "divisible" */ + bysym = 285, /* "by" */ + eqeqsym = 286, /* "==" */ + neqsym = 287, /* "!=" */ + ltsym = 288, /* "<" */ + leqsym = 289, /* "<=" */ + gtsym = 290, /* ">" */ + geqsym = 291 /* ">=" */ + }; + typedef enum yytokentype yytoken_kind_t; +#endif + +/* Value type. */ + +/* Location type. */ +#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED +typedef struct YYLTYPE YYLTYPE; +struct YYLTYPE +{ + int first_line; + int first_column; + int last_line; + int last_column; +}; +# define YYLTYPE_IS_DECLARED 1 +# define YYLTYPE_IS_TRIVIAL 1 +#endif + + +extern YYSTYPE yylval; +extern YYLTYPE yylloc; + +int yyparse (char const *file_name); + + +#endif /* !YY_YY_SPL_TAB_H_INCLUDED */ diff --git a/FromGithub/spl.tab.o b/FromGithub/spl.tab.o new file mode 100644 index 0000000000000000000000000000000000000000..da4b8686b86e2f72c339e89076f8cc156866cb05 GIT binary patch literal 68272 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 +} + +%code requires { + + /* Including "ast.h" must be at the top, to define the AST type */ +#include "ast.h" +#include "machine_types.h" +#include "parser_types.h" +#include "lexer.h" + + /* Report an error to the user on stderr */ +extern void yyerror(const char *filename, const char *msg); + +} /* end of %code requires */ + +%verbose +%define parse.lac full +%define parse.error detailed + + /* the following passes file_name to yyerror, + and declares it as an formal parameter of yyparse. */ +%parse-param { char const *file_name } + +%token identsym +%token numbersym +%token plussym "+" +%token minussym "-" +%token multsym "*" +%token divsym "/" + +%token periodsym "." +%token semisym ";" +%token eqsym "=" +%token commasym "," +%token becomessym ":=" +%token lparensym "(" +%token rparensym ")" + +%token constsym "const" +%token varsym "var" +%token procsym "proc" +%token callsym "call" +%token beginsym "begin" +%token endsym "end" +%token ifsym "if" +%token thensym "then" +%token elsesym "else" +%token whilesym "while" +%token dosym "do" +%token readsym "read" +%token printsym "print" +%token divisiblesym "divisible" +%token bysym "by" + +%token eqeqsym "==" +%token neqsym "!=" +%token ltsym "<" +%token leqsym "<=" +%token gtsym ">" +%token geqsym ">=" + +%type program + +%type block + +%type constDecls +%type constDecl +%type constDefList +%type constDef + +%type varDecls +%type varDecl +%type identList + +%type procDecls +%type procDecl + + +%type stmts +%type empty +%type stmtList +%type stmt +%type assignStmt +%type callStmt +%type ifStmt +%type whileStmt +%type readStmt +%type printStmt +%type blockStmt + +%type condition +%type dbCondition +%type relOpCondition +%type relOp + +%type expr +%type term +%type factor + +%start program + +%code { + /* extern declarations provided by the lexer */ +extern int yylex(void); + + /* The AST for the program, set by the semantic action + for the nonterminal program. */ +block_t progast; + + /* Set the program's ast to be t */ +extern void setProgAST(block_t t); +} + +%% + /* Write your grammar rules below and before the next %% */ + +program : block "." { setProgAST($1); } ; + + +block : "begin" constDecls varDecls procDecls stmts "end" + { $$ = ast_block($1,$2,$3,$4,$5); } + ; + +constDecls : empty { $$ = ast_const_decls_empty($1); } + | constDecls constDecl + { $$ = ast_const_decls($1, $2); } + ; + +empty : %empty + { file_location *file_loc + = file_location_make(lexer_filename(), lexer_line()); + $$ = ast_empty(file_loc); + } + ; + +constDecl : "const" constDefList ";" { $$ = ast_const_decl($2); } ; + +constDefList : constDef { $$ = ast_const_def_list_singleton($1); } + | constDefList "," constDef + { $$ = ast_const_def_list($1, $3); } + ; + +constDef : identsym "=" numbersym { $$ = ast_const_def($1, $3); } ; + +varDecls : empty { $$ = ast_var_decls_empty($1); } + | varDecls varDecl { $$ = ast_var_decls($1, $2); } + ; + +varDecl : "var" identList ";" { $$ = ast_var_decl($2); } ; + +identList : identsym { $$ = ast_ident_list_singleton($1); } + | identList "," identsym { $$ = ast_ident_list($1, $3); } + ; + +procDecls : empty { $$ = ast_proc_decls_empty($1); } + | procDecls procDecl { $$ = ast_proc_decls($1, $2); } + ; + +procDecl : "proc" identsym block ";" { $$ = ast_proc_decl($2, $3); } ; + +stmts : empty { $$ = ast_stmts_empty($1); } + | stmtList { $$ = ast_stmts($1); } + ; + +stmtList : stmt { $$ = ast_stmt_list_singleton($1); } + | stmtList ";" stmt { $$ = ast_stmt_list($1,$3); } + ; + +stmt : assignStmt { $$ = ast_stmt_assign($1); } + | callStmt { $$ = ast_stmt_call($1); } + | ifStmt { $$ = ast_stmt_if($1); } + | whileStmt { $$ = ast_stmt_while($1); } + | readStmt { $$ = ast_stmt_read($1); } + | printStmt { $$ = ast_stmt_print($1); } + | blockStmt { $$ = ast_stmt_block($1); } + ; + +assignStmt : identsym ":=" expr { $$ = ast_assign_stmt($1,$3); } ; + +callStmt : "call" identsym { $$ = ast_call_stmt($2); } ; + +ifStmt : "if" condition "then" stmts "else" stmts "end" + { $$ = ast_if_then_else_stmt($2, $4, $6); } + | "if" condition "then" stmts "end" + { $$ = ast_if_then_stmt($2, $4); } + ; + +whileStmt : "while" condition "do" stmts "end" + { $$ = ast_while_stmt($2,$4); } ; + +readStmt : "read" identsym { $$ = ast_read_stmt($2); } ; + +printStmt : "print" expr { $$ = ast_print_stmt($2); } ; + +blockStmt : block { $$ = ast_block_stmt($1); } ; + +condition : dbCondition { $$ = ast_condition_db($1); } + | relOpCondition { $$ = ast_condition_rel_op($1); } + ; + +dbCondition : "divisible" expr "by" expr { $$ = ast_db_condition($2,$4); } ; + +relOpCondition : expr relOp expr { $$ = ast_rel_op_condition($1, $2, $3); } ; + +relOp : "==" | "!=" | "<" | "<=" | ">" | ">=" ; + +expr : term + | expr "+" term + { $$ = ast_expr_binary_op(ast_binary_op_expr($1, $2, $3)); } + | expr "-" term + { $$ = ast_expr_binary_op(ast_binary_op_expr($1, $2, $3)); } + ; + +term : factor + | term "*" factor + { $$ = ast_expr_binary_op(ast_binary_op_expr($1, $2, $3)); } + | term "/" factor + { $$ = ast_expr_binary_op(ast_binary_op_expr($1, $2, $3)); } + ; + +factor : identsym { $$ = ast_expr_ident($1); } + | numbersym { $$ = ast_expr_number($1); } + | "-" factor { $$ = ast_expr_signed_expr($1, $2); } + | "+" factor { $$ = ast_expr_signed_expr($1, $2); } + | "(" expr ")" { $$ = $2; } + ; + +%% + +// Set the program's ast to be ast +void setProgAST(block_t ast) { progast = ast; } diff --git a/FromGithub/spl_lexer.c b/FromGithub/spl_lexer.c new file mode 100644 index 0000000..54a334b --- /dev/null +++ b/FromGithub/spl_lexer.c @@ -0,0 +1,2236 @@ +#line 2 "spl_lexer.c" + +#line 4 "spl_lexer.c" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 4 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +#ifdef yyget_lval +#define yyget_lval_ALREADY_DEFINED +#else +#define yyget_lval yyget_lval +#endif + +#ifdef yyset_lval +#define yyset_lval_ALREADY_DEFINED +#else +#define yyset_lval yyset_lval +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#ifndef SIZE_MAX +#define SIZE_MAX (~(size_t)0) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +/* begin standard C++ headers. */ + +/* TODO: this is always defined, so inline it */ +#define yyconst const + +#if defined(__GNUC__) && __GNUC__ >= 3 +#define yynoreturn __attribute__((__noreturn__)) +#else +#define yynoreturn +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an + * integer in range [0..255] for use as an array index. + */ +#define YY_SC_TO_UI(c) ((YY_CHAR) (c)) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else +#define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern int yyleng; + +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires + * access to the local variable yy_act. Since yyless() is a macro, it would break + * existing scanners that call yyless() from OUTSIDE yylex. + * One obvious solution it to make yy_act a global. I tried that, and saw + * a 5% performance hit in a non-yylineno scanner, because yy_act is + * normally declared as a register variable-- so it is not worth it. + */ + #define YY_LESS_LINENO(n) \ + do { \ + int yyl;\ + for ( yyl = n; yyl < yyleng; ++yyl )\ + if ( yytext[yyl] == '\n' )\ + --yylineno;\ + }while(0) + #define YY_LINENO_REWIND_TO(dst) \ + do {\ + const char *p;\ + for ( p = yy_cp-1; p >= (dst); --p)\ + if ( *p == '\n' )\ + --yylineno;\ + }while(0) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) +#define unput(c) yyunput( c, (yytext_ptr) ) + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + int yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; +static int yy_n_chars; /* number of characters read into yy_ch_buf */ +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = NULL; +static int yy_init = 0; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart ( FILE *input_file ); +void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); +void yy_delete_buffer ( YY_BUFFER_STATE b ); +void yy_flush_buffer ( YY_BUFFER_STATE b ); +void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state ( void ); + +static void yyensure_buffer_stack ( void ); +static void yy_load_buffer_state ( void ); +static void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file ); +#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); +YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len ); + +void *yyalloc ( yy_size_t ); +void *yyrealloc ( void *, yy_size_t ); +void yyfree ( void * ); + +#define yy_new_buffer yy_create_buffer +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ +typedef flex_uint8_t YY_CHAR; + +FILE *yyin = NULL, *yyout = NULL; + +typedef int yy_state_type; + +extern int yylineno; +int yylineno = 1; + +extern char *yytext; +#ifdef yytext_ptr +#undef yytext_ptr +#endif +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state ( void ); +static yy_state_type yy_try_NUL_trans ( yy_state_type current_state ); +static int yy_get_next_buffer ( void ); +static void yynoreturn yy_fatal_error ( const char* msg ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; +#define YY_NUM_RULES 39 +#define YY_END_OF_BUFFER 40 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static const flex_int16_t yy_accept[90] = + { 0, + 0, 0, 40, 38, 1, 3, 1, 38, 2, 20, + 21, 7, 5, 11, 6, 9, 8, 4, 38, 10, + 19, 14, 18, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 3, 15, 2, 4, 12, 16, + 13, 17, 37, 37, 36, 37, 37, 37, 32, 37, + 37, 28, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 27, 37, 37, 37, 37, 23, 37, 37, + 25, 37, 37, 30, 37, 24, 33, 29, 37, 26, + 22, 37, 34, 31, 37, 37, 37, 35, 0 + } ; + +static const YY_CHAR yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 2, 2, 4, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 5, 1, 1, 1, 6, 1, 1, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 16, 17, 18, + 19, 20, 1, 1, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 1, 1, 1, 1, 1, 1, 22, 23, 24, 25, + + 26, 27, 28, 29, 30, 21, 21, 31, 21, 32, + 33, 34, 21, 35, 36, 37, 21, 38, 39, 21, + 40, 21, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static const YY_CHAR yy_meta[41] = + { 0, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 + } ; + +static const flex_int16_t yy_base[92] = + { 0, + 0, 0, 97, 98, 98, 98, 93, 76, 0, 98, + 98, 98, 98, 98, 98, 98, 98, 79, 74, 98, + 73, 72, 71, 0, 15, 20, 13, 13, 62, 53, + 61, 57, 63, 55, 98, 98, 0, 68, 98, 98, + 98, 98, 0, 54, 0, 50, 48, 41, 0, 42, + 52, 0, 17, 54, 49, 39, 43, 42, 40, 34, + 39, 42, 0, 35, 42, 40, 32, 0, 32, 30, + 0, 24, 24, 0, 22, 0, 0, 0, 31, 0, + 0, 24, 0, 0, 29, 20, 23, 0, 98, 55, + 45 + + } ; + +static const flex_int16_t yy_def[92] = + { 0, + 89, 1, 89, 89, 89, 89, 89, 89, 90, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 89, 89, 90, 89, 89, 89, + 89, 89, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 0, 89, + 89 + + } ; + +static const flex_int16_t yy_nxt[139] = + { 0, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 24, 25, 26, 27, 28, 24, 24, 24, 29, + 24, 24, 24, 30, 31, 24, 32, 33, 34, 24, + 44, 46, 48, 50, 51, 49, 64, 43, 88, 65, + 87, 86, 47, 85, 45, 37, 84, 37, 83, 82, + 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, + 71, 70, 69, 68, 67, 66, 63, 62, 61, 60, + 59, 58, 38, 57, 56, 55, 54, 53, 52, 42, + 41, 40, 39, 38, 36, 35, 89, 3, 89, 89, + + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89 + } ; + +static const flex_int16_t yy_chk[139] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 25, 26, 27, 28, 28, 27, 53, 91, 87, 53, + 86, 85, 26, 82, 25, 90, 79, 90, 75, 73, + 72, 70, 69, 67, 66, 65, 64, 62, 61, 60, + 59, 58, 57, 56, 55, 54, 51, 50, 48, 47, + 46, 44, 38, 34, 33, 32, 31, 30, 29, 23, + 22, 21, 19, 18, 8, 7, 3, 89, 89, 89, + + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89 + } ; + +/* Table of booleans, true if rule could match eol. */ +static const flex_int32_t yy_rule_can_match_eol[40] = + { 0, +0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int yy_flex_debug; +int yy_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "spl_lexer.l" +/* $Id: spl_lexer.l,v 1.1 2024/10/23 12:17:38 leavens Exp $ */ +/* Lexical Analyzer for SPL */ +#line 10 "spl_lexer.l" +#include +#include +#include +#include +#include +#include "ast.h" +#include "parser_types.h" +#include "utilities.h" +#include "lexer.h" + + /* Tokens generated by Bison */ +#include "spl.tab.h" + + /* need declaration of fileno, part of the C standard library. + (Putting an extern declaration here shuts off a gcc warning.) */ +extern int fileno(FILE *stream); + +/* The filename of the file being read */ +static char *input_filename; + +/* Have any errors been noted? */ +static bool errors_noted; + +/* The value of a token */ +extern YYSTYPE yylval; + +/* The FILE used by the generated lexer */ +extern FILE *yyin; + +// We are not using yyunput or input +#define YY_NO_UNPUT +#define YY_NO_INPUT + +#undef yywrap /* sometimes a macro by default */ + +// apparently strdup is not declared in +extern char *strdup(const char *s); + +// set the lexer's value for a token in yylval as an AST +static void tok2ast(int code) { + AST t; + t.token.file_loc = file_location_make(input_filename, yylineno); + t.token.type_tag = token_ast; + t.token.code = code; + t.token.text = strdup(yytext); + yylval = t; +} + +static void ident2ast(const char *name) { + AST t; + assert(input_filename != NULL); + t.ident.file_loc = file_location_make(input_filename, yylineno); + t.ident.type_tag = ident_ast; + t.ident.name = strdup(name); + yylval = t; +} + +static void number2ast(unsigned int val) +{ + AST t; + t.number.file_loc = file_location_make(input_filename, yylineno); + t.number.type_tag = number_ast; + t.number.text = strdup(yytext); + t.number.value = val; + yylval = t; +} + +#line 609 "spl_lexer.c" +#line 80 "spl_lexer.l" + /* you can add actual definitions below, before the %% */ +#line 612 "spl_lexer.c" + +#define INITIAL 0 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +static int yy_init_globals ( void ); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy ( void ); + +int yyget_debug ( void ); + +void yyset_debug ( int debug_flag ); + +YY_EXTRA_TYPE yyget_extra ( void ); + +void yyset_extra ( YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in ( void ); + +void yyset_in ( FILE * _in_str ); + +FILE *yyget_out ( void ); + +void yyset_out ( FILE * _out_str ); + + int yyget_leng ( void ); + +char *yyget_text ( void ); + +int yyget_lineno ( void ); + +void yyset_lineno ( int _line_number ); + +YYSTYPE * yyget_lval ( void ); + +void yyset_lval ( YYSTYPE * yylval_param ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap ( void ); +#else +extern int yywrap ( void ); +#endif +#endif + +#ifndef YY_NO_UNPUT + + static void yyunput ( int c, char *buf_ptr ); + +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy ( char *, const char *, int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen ( const char * ); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput ( void ); +#else +static int input ( void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else +#define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + int n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex \ + (YYSTYPE * yylval_param ); + +#define YY_DECL int yylex \ + (YYSTYPE * yylval_param ) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK /*LINTED*/break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + yy_state_type yy_current_state; + char *yy_cp, *yy_bp; + int yy_act; + + YYSTYPE * yylval; + + yylval = yylval_param; + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + { +#line 94 "spl_lexer.l" + + + /* fill in the rules for your lexer here! */ + +#line 844 "spl_lexer.c" + + while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 90 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 98 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + + if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) + { + int yyl; + for ( yyl = 0; yyl < yyleng; ++yyl ) + if ( yytext[yyl] == '\n' ) + + yylineno++; +; + } + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 98 "spl_lexer.l" +{ ; } /* do nothing */ + YY_BREAK +case 2: +YY_RULE_SETUP +#line 99 "spl_lexer.l" +{ ; } /* ignore comments */ + YY_BREAK +case 3: +/* rule 3 can match eol */ +YY_RULE_SETUP +#line 100 "spl_lexer.l" +{ ; } /* ignore EOL */ + YY_BREAK +case 4: +YY_RULE_SETUP +#line 102 "spl_lexer.l" +{ unsigned long lval; + int ssf_ret; + ssf_ret = sscanf(yytext, "%lu", &lval); + if (ssf_ret != 1) { + bail_with_error("Number (%s) couldn't be read by lexer!", + yytext); + } + if (INT_MAX < lval ) { + char msgbuf[512]; + if (strlen(yytext) >= 300) { + snprintf(msgbuf, 327, "Number (%s...) is too large!", + yytext); + } else { + sprintf(msgbuf, "Number (%s) is too large!", yytext); + } + yyerror(lexer_filename(), msgbuf); + } + number2ast((int) lval); + return numbersym; + } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 123 "spl_lexer.l" +{ tok2ast(plussym); return plussym; } + YY_BREAK +case 6: +YY_RULE_SETUP +#line 124 "spl_lexer.l" +{ tok2ast(minussym); return minussym; } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 125 "spl_lexer.l" +{ tok2ast(multsym); return multsym; } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 126 "spl_lexer.l" +{ tok2ast(divsym); return divsym; } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 128 "spl_lexer.l" +{ return periodsym; } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 129 "spl_lexer.l" +{ return semisym; } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 130 "spl_lexer.l" +{ return commasym; } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 131 "spl_lexer.l" +{ return becomessym; } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 132 "spl_lexer.l" +{ tok2ast(eqsym); return eqeqsym; } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 133 "spl_lexer.l" +{ tok2ast(eqsym); return eqsym; } + YY_BREAK +case 15: +YY_RULE_SETUP +#line 134 "spl_lexer.l" +{ tok2ast(neqsym); return neqsym; } + YY_BREAK +case 16: +YY_RULE_SETUP +#line 135 "spl_lexer.l" +{ tok2ast(leqsym); return leqsym; } + YY_BREAK +case 17: +YY_RULE_SETUP +#line 136 "spl_lexer.l" +{ tok2ast(geqsym); return geqsym; } + YY_BREAK +case 18: +YY_RULE_SETUP +#line 137 "spl_lexer.l" +{ tok2ast(gtsym); return gtsym; } + YY_BREAK +case 19: +YY_RULE_SETUP +#line 138 "spl_lexer.l" +{ tok2ast(ltsym); return ltsym; } + YY_BREAK +case 20: +YY_RULE_SETUP +#line 139 "spl_lexer.l" +{ tok2ast(lparensym); return lparensym; } + YY_BREAK +case 21: +YY_RULE_SETUP +#line 140 "spl_lexer.l" +{ tok2ast(rparensym); return rparensym; } + YY_BREAK +case 22: +YY_RULE_SETUP +#line 142 "spl_lexer.l" +{ tok2ast(constsym); return constsym; } + YY_BREAK +case 23: +YY_RULE_SETUP +#line 143 "spl_lexer.l" +{ tok2ast(varsym); return varsym; } + YY_BREAK +case 24: +YY_RULE_SETUP +#line 144 "spl_lexer.l" +{ tok2ast(procsym); return procsym; } + YY_BREAK +case 25: +YY_RULE_SETUP +#line 145 "spl_lexer.l" +{ tok2ast(callsym); return callsym; } + YY_BREAK +case 26: +YY_RULE_SETUP +#line 146 "spl_lexer.l" +{ tok2ast(beginsym); return beginsym; } + YY_BREAK +case 27: +YY_RULE_SETUP +#line 147 "spl_lexer.l" +{ tok2ast(endsym); return endsym; } + YY_BREAK +case 28: +YY_RULE_SETUP +#line 148 "spl_lexer.l" +{ tok2ast(ifsym); return ifsym; } + YY_BREAK +case 29: +YY_RULE_SETUP +#line 149 "spl_lexer.l" +{ tok2ast(thensym); return thensym; } + YY_BREAK +case 30: +YY_RULE_SETUP +#line 150 "spl_lexer.l" +{ tok2ast(elsesym); return elsesym; } + YY_BREAK +case 31: +YY_RULE_SETUP +#line 151 "spl_lexer.l" +{ tok2ast(whilesym); return whilesym; } + YY_BREAK +case 32: +YY_RULE_SETUP +#line 152 "spl_lexer.l" +{ tok2ast(dosym); return dosym; } + YY_BREAK +case 33: +YY_RULE_SETUP +#line 153 "spl_lexer.l" +{ tok2ast(readsym); return readsym; } + YY_BREAK +case 34: +YY_RULE_SETUP +#line 154 "spl_lexer.l" +{ tok2ast(printsym); return printsym; } + YY_BREAK +case 35: +YY_RULE_SETUP +#line 155 "spl_lexer.l" +{ tok2ast(divisiblesym); return divisiblesym; } + YY_BREAK +case 36: +YY_RULE_SETUP +#line 156 "spl_lexer.l" +{ tok2ast(bysym); return bysym; } + YY_BREAK +case 37: +YY_RULE_SETUP +#line 158 "spl_lexer.l" +{ ident2ast(yytext); return identsym; } + YY_BREAK +case 38: +YY_RULE_SETUP +#line 160 "spl_lexer.l" +{ char msgbuf[512]; + sprintf(msgbuf, "invalid character: '%c' ('\\0%o')", *yytext, *yytext); + yyerror(lexer_filename(), msgbuf); + } + YY_BREAK +case 39: +YY_RULE_SETUP +#line 164 "spl_lexer.l" +ECHO; + YY_BREAK +#line 1129 "spl_lexer.c" +case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of user's declarations */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + char *source = (yytext_ptr); + int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc( (void *) b->yy_ch_buf, + (yy_size_t) (b->yy_buf_size + 2) ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = NULL; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc( + (void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + /* "- 2" to take care of EOB's */ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2); + } + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + yy_state_type yy_current_state; + char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 90 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + int yy_is_jam; + char *yy_cp = (yy_c_buf_p); + + YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 90 ) + yy_c = yy_meta[yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; + yy_is_jam = (yy_current_state == 89); + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_UNPUT + + static void yyunput (int c, char * yy_bp ) +{ + char *yy_cp; + + yy_cp = (yy_c_buf_p); + + /* undo effects of setting up yytext */ + *yy_cp = (yy_hold_char); + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + int number_to_move = (yy_n_chars) + 2; + char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = (int) YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + if ( c == '\n' ){ + --yylineno; + } + + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} + +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (int) ((yy_c_buf_p) - (yytext_ptr)); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return 0; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + if ( c == '\n' ) + + yylineno++; +; + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_init_buffer( YY_CURRENT_BUFFER, input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2) ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yy_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree( (void *) b->yy_ch_buf ); + + yyfree( (void *) b ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (void) +{ + yy_size_t num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */ + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + yy_size_t grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + if ( ! (yy_buffer_stack) ) + YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return NULL; + + b = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = NULL; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (const char * yystr ) +{ + + return yy_scan_bytes( yystr, (int) strlen(yystr) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param yybytes the byte buffer to scan + * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (const char * yybytes, int _yybytes_len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = (yy_size_t) (_yybytes_len + 2); + buf = (char *) yyalloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yynoreturn yy_fatal_error (const char* msg ) +{ + fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int yyget_lineno (void) +{ + + return yylineno; +} + +/** Get the input stream. + * + */ +FILE *yyget_in (void) +{ + return yyin; +} + +/** Get the output stream. + * + */ +FILE *yyget_out (void) +{ + return yyout; +} + +/** Get the length of the current token. + * + */ +int yyget_leng (void) +{ + return yyleng; +} + +/** Get the current token. + * + */ + +char *yyget_text (void) +{ + return yytext; +} + +/** Set the current line number. + * @param _line_number line number + * + */ +void yyset_lineno (int _line_number ) +{ + + yylineno = _line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param _in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * _in_str ) +{ + yyin = _in_str ; +} + +void yyset_out (FILE * _out_str ) +{ + yyout = _out_str ; +} + +int yyget_debug (void) +{ + return yy_flex_debug; +} + +void yyset_debug (int _bdebug ) +{ + yy_flex_debug = _bdebug ; +} + +static int yy_init_globals (void) +{ + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from yylex_destroy(), so don't allocate here. + */ + + /* We do not touch yylineno unless the option is enabled. */ + yylineno = 1; + + (yy_buffer_stack) = NULL; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + (yy_c_buf_p) = NULL; + (yy_init) = 0; + (yy_start) = 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = NULL; + yyout = NULL; +#endif + + /* For future reference: Set errno on error, since we are called by + * yylex_init() + */ + return 0; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer( YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * yylex() is called, initialization will occur. */ + yy_init_globals( ); + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, const char * s2, int n ) +{ + + int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (const char * s ) +{ + int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return malloc(size); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return realloc(ptr, size); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#line 164 "spl_lexer.l" + + + /* This code goes in the user code section of the spl_lexer.l file, + following the last %% above. */ + +// Requires: fname != NULL +// Requires: fname is the name of a readable file +// Initialize the lexer and start it reading +// from the given file name +void lexer_init(char *fname) +{ + errors_noted = false; + yyin = fopen(fname, "r"); + if (yyin == NULL) { + bail_with_error("Cannot open %s", fname); + } + input_filename = fname; +} + +// Close the file yyin +// and return 0 to indicate that there are no more files +int yywrap() { + if (yyin != NULL) { + int rc = fclose(yyin); + if (rc == EOF) { + bail_with_error("Cannot close %s!", input_filename); + } + } + input_filename = NULL; + return 1; /* no more input */ +} + +// Return the name of the current input file +const char *lexer_filename() { + return input_filename; +} + +// Return the line number of the next token +unsigned int lexer_line() { + return yylineno; +} + +/* Report an error to the user on stderr */ +void yyerror(const char *filename, const char *msg) +{ + fflush(stdout); + fprintf(stderr, "%s:%d: %s\n", input_filename, lexer_line(), msg); + errors_noted = true; +} + +// On standard output: +// Print a message about the file name of the lexer's input +// and then print a heading for the lexer's output. +void lexer_print_output_header() +{ + printf("Tokens from file %s\n", lexer_filename()); + printf("%-6s %-4s %s\n", "Number", "Line", "Text"); +} + +// Have any errors been noted by the lexer? +bool lexer_has_errors() +{ + return errors_noted; +} + +// Print information about the token t to stdout +// followed by a newline +void lexer_print_token(enum yytokentype t, unsigned int tline, + const char *txt) +{ + printf("%-6d %-4d \"%s\"\n", t, tline, txt); +} + + +/* Read all the tokens from the input file + * and print each token on standard output + * using the format in lexer_print_token */ +void lexer_output() +{ + lexer_print_output_header(); + AST dummy; + yytoken_kind_t t; + do { + t = yylex(&dummy); + if (t == YYEOF) { + break; + } + lexer_print_token(t, yylineno, yytext); + } while (t != YYEOF); +} + diff --git a/FromGithub/spl_lexer.h b/FromGithub/spl_lexer.h new file mode 100644 index 0000000..a0e11df --- /dev/null +++ b/FromGithub/spl_lexer.h @@ -0,0 +1,492 @@ +#ifndef yyHEADER_H +#define yyHEADER_H 1 +#define yyIN_HEADER 1 + +#line 6 "spl_lexer.h" + +#line 8 "spl_lexer.h" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 6 +#define YY_FLEX_SUBMINOR_VERSION 4 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +#ifdef yyget_lval +#define yyget_lval_ALREADY_DEFINED +#else +#define yyget_lval yyget_lval +#endif + +#ifdef yyset_lval +#define yyset_lval_ALREADY_DEFINED +#else +#define yyset_lval yyset_lval +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#ifndef SIZE_MAX +#define SIZE_MAX (~(size_t)0) +#endif + +#endif /* ! C99 */ + +#endif /* ! FLEXINT_H */ + +/* begin standard C++ headers. */ + +/* TODO: this is always defined, so inline it */ +#define yyconst const + +#if defined(__GNUC__) && __GNUC__ >= 3 +#define yynoreturn __attribute__((__noreturn__)) +#else +#define yynoreturn +#endif + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k. + * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. + * Ditto for the __ia64__ case accordingly. + */ +#define YY_BUF_SIZE 32768 +#else +#define YY_BUF_SIZE 16384 +#endif /* __ia64__ */ +#endif + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +extern int yyleng; + +extern FILE *yyin, *yyout; + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + int yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +void yyrestart ( FILE *input_file ); +void yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size ); +void yy_delete_buffer ( YY_BUFFER_STATE b ); +void yy_flush_buffer ( YY_BUFFER_STATE b ); +void yypush_buffer_state ( YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state ( void ); + +YY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size ); +YY_BUFFER_STATE yy_scan_string ( const char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes ( const char *bytes, int len ); + +void *yyalloc ( yy_size_t ); +void *yyrealloc ( void *, yy_size_t ); +void yyfree ( void * ); + +/* Begin user sect3 */ + +extern int yylineno; + +extern char *yytext; +#ifdef yytext_ptr +#undef yytext_ptr +#endif +#define yytext_ptr yytext + +#ifdef YY_HEADER_EXPORT_START_CONDITIONS +#define INITIAL 0 + +#endif + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int yylex_destroy ( void ); + +int yyget_debug ( void ); + +void yyset_debug ( int debug_flag ); + +YY_EXTRA_TYPE yyget_extra ( void ); + +void yyset_extra ( YY_EXTRA_TYPE user_defined ); + +FILE *yyget_in ( void ); + +void yyset_in ( FILE * _in_str ); + +FILE *yyget_out ( void ); + +void yyset_out ( FILE * _out_str ); + + int yyget_leng ( void ); + +char *yyget_text ( void ); + +int yyget_lineno ( void ); + +void yyset_lineno ( int _line_number ); + +YYSTYPE * yyget_lval ( void ); + +void yyset_lval ( YYSTYPE * yylval_param ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap ( void ); +#else +extern int yywrap ( void ); +#endif +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy ( char *, const char *, int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen ( const char * ); +#endif + +#ifndef YY_NO_INPUT + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#ifdef __ia64__ +/* On IA-64, the buffer size is 16k, not 8k */ +#define YY_READ_BUF_SIZE 16384 +#else +#define YY_READ_BUF_SIZE 8192 +#endif /* __ia64__ */ +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex \ + (YYSTYPE * yylval_param ); + +#define YY_DECL int yylex \ + (YYSTYPE * yylval_param ) +#endif /* !YY_DECL */ + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +#undef YY_NEW_FILE +#undef YY_FLUSH_BUFFER +#undef yy_set_bol +#undef yy_new_buffer +#undef yy_set_interactive +#undef YY_DO_BEFORE_ACTION + +#ifdef YY_DECL_IS_OURS +#undef YY_DECL_IS_OURS +#undef YY_DECL +#endif + +#ifndef yy_create_buffer_ALREADY_DEFINED +#undef yy_create_buffer +#endif +#ifndef yy_delete_buffer_ALREADY_DEFINED +#undef yy_delete_buffer +#endif +#ifndef yy_scan_buffer_ALREADY_DEFINED +#undef yy_scan_buffer +#endif +#ifndef yy_scan_string_ALREADY_DEFINED +#undef yy_scan_string +#endif +#ifndef yy_scan_bytes_ALREADY_DEFINED +#undef yy_scan_bytes +#endif +#ifndef yy_init_buffer_ALREADY_DEFINED +#undef yy_init_buffer +#endif +#ifndef yy_flush_buffer_ALREADY_DEFINED +#undef yy_flush_buffer +#endif +#ifndef yy_load_buffer_state_ALREADY_DEFINED +#undef yy_load_buffer_state +#endif +#ifndef yy_switch_to_buffer_ALREADY_DEFINED +#undef yy_switch_to_buffer +#endif +#ifndef yypush_buffer_state_ALREADY_DEFINED +#undef yypush_buffer_state +#endif +#ifndef yypop_buffer_state_ALREADY_DEFINED +#undef yypop_buffer_state +#endif +#ifndef yyensure_buffer_stack_ALREADY_DEFINED +#undef yyensure_buffer_stack +#endif +#ifndef yylex_ALREADY_DEFINED +#undef yylex +#endif +#ifndef yyrestart_ALREADY_DEFINED +#undef yyrestart +#endif +#ifndef yylex_init_ALREADY_DEFINED +#undef yylex_init +#endif +#ifndef yylex_init_extra_ALREADY_DEFINED +#undef yylex_init_extra +#endif +#ifndef yylex_destroy_ALREADY_DEFINED +#undef yylex_destroy +#endif +#ifndef yyget_debug_ALREADY_DEFINED +#undef yyget_debug +#endif +#ifndef yyset_debug_ALREADY_DEFINED +#undef yyset_debug +#endif +#ifndef yyget_extra_ALREADY_DEFINED +#undef yyget_extra +#endif +#ifndef yyset_extra_ALREADY_DEFINED +#undef yyset_extra +#endif +#ifndef yyget_in_ALREADY_DEFINED +#undef yyget_in +#endif +#ifndef yyset_in_ALREADY_DEFINED +#undef yyset_in +#endif +#ifndef yyget_out_ALREADY_DEFINED +#undef yyget_out +#endif +#ifndef yyset_out_ALREADY_DEFINED +#undef yyset_out +#endif +#ifndef yyget_leng_ALREADY_DEFINED +#undef yyget_leng +#endif +#ifndef yyget_text_ALREADY_DEFINED +#undef yyget_text +#endif +#ifndef yyget_lineno_ALREADY_DEFINED +#undef yyget_lineno +#endif +#ifndef yyset_lineno_ALREADY_DEFINED +#undef yyset_lineno +#endif +#ifndef yyget_column_ALREADY_DEFINED +#undef yyget_column +#endif +#ifndef yyset_column_ALREADY_DEFINED +#undef yyset_column +#endif +#ifndef yywrap_ALREADY_DEFINED +#undef yywrap +#endif +#ifndef yyget_lval_ALREADY_DEFINED +#undef yyget_lval +#endif +#ifndef yyset_lval_ALREADY_DEFINED +#undef yyset_lval +#endif +#ifndef yyget_lloc_ALREADY_DEFINED +#undef yyget_lloc +#endif +#ifndef yyset_lloc_ALREADY_DEFINED +#undef yyset_lloc +#endif +#ifndef yyalloc_ALREADY_DEFINED +#undef yyalloc +#endif +#ifndef yyrealloc_ALREADY_DEFINED +#undef yyrealloc +#endif +#ifndef yyfree_ALREADY_DEFINED +#undef yyfree +#endif +#ifndef yytext_ALREADY_DEFINED +#undef yytext +#endif +#ifndef yyleng_ALREADY_DEFINED +#undef yyleng +#endif +#ifndef yyin_ALREADY_DEFINED +#undef yyin +#endif +#ifndef yyout_ALREADY_DEFINED +#undef yyout +#endif +#ifndef yy_flex_debug_ALREADY_DEFINED +#undef yy_flex_debug +#endif +#ifndef yylineno_ALREADY_DEFINED +#undef yylineno +#endif +#ifndef yytables_fload_ALREADY_DEFINED +#undef yytables_fload +#endif +#ifndef yytables_destroy_ALREADY_DEFINED +#undef yytables_destroy +#endif +#ifndef yyTABLES_NAME_ALREADY_DEFINED +#undef yyTABLES_NAME +#endif + +#line 164 "spl_lexer.l" + + +#line 491 "spl_lexer.h" +#undef yyIN_HEADER +#endif /* yyHEADER_H */ diff --git a/FromGithub/spl_lexer.l b/FromGithub/spl_lexer.l new file mode 100644 index 0000000..9a79bac --- /dev/null +++ b/FromGithub/spl_lexer.l @@ -0,0 +1,252 @@ +/* $Id: spl_lexer.l,v 1.1 2024/10/23 12:17:38 leavens Exp $ */ +/* Lexical Analyzer for SPL */ + +%option header-file = "spl_lexer.h" +%option outfile = "spl_lexer.c" +%option yylineno +%option bison-bridge + +%{ +#include +#include +#include +#include +#include +#include "ast.h" +#include "parser_types.h" +#include "utilities.h" +#include "lexer.h" + + /* Tokens generated by Bison */ +#include "spl.tab.h" + + /* need declaration of fileno, part of the C standard library. + (Putting an extern declaration here shuts off a gcc warning.) */ +extern int fileno(FILE *stream); + +/* The filename of the file being read */ +static char *input_filename; + +/* Have any errors been noted? */ +static bool errors_noted; + +/* The value of a token */ +extern YYSTYPE yylval; + +/* The FILE used by the generated lexer */ +extern FILE *yyin; + +// We are not using yyunput or input +#define YY_NO_UNPUT +#define YY_NO_INPUT + +#undef yywrap /* sometimes a macro by default */ + +// apparently strdup is not declared in +extern char *strdup(const char *s); + +// set the lexer's value for a token in yylval as an AST +static void tok2ast(int code) { + AST t; + t.token.file_loc = file_location_make(input_filename, yylineno); + t.token.type_tag = token_ast; + t.token.code = code; + t.token.text = strdup(yytext); + yylval = t; +} + +static void ident2ast(const char *name) { + AST t; + assert(input_filename != NULL); + t.ident.file_loc = file_location_make(input_filename, yylineno); + t.ident.type_tag = ident_ast; + t.ident.name = strdup(name); + yylval = t; +} + +static void number2ast(unsigned int val) +{ + AST t; + t.number.file_loc = file_location_make(input_filename, yylineno); + t.number.type_tag = number_ast; + t.number.text = strdup(yytext); + t.number.value = val; + yylval = t; +} + +%} + + /* you can add actual definitions below, before the %% */ + +DIGIT [0-9] +NUMBER {DIGIT}+ +LETTER [a-zA-Z] +LETTERORDIGIT ({LETTER}|{DIGIT}) +IDENT {LETTER}({LETTERORDIGIT}*) +NEWLINE \n +CR \r +EOL ({NEWLINE}|({CR}{NEWLINE})) +COMMENTSTART % +COMMENT {COMMENTSTART}.* +IGNORED [ \t\v\f\r] + +%% + + /* fill in the rules for your lexer here! */ + +{IGNORED} { ; } /* do nothing */ +{COMMENT} { ; } /* ignore comments */ +{EOL} { ; } /* ignore EOL */ + +{NUMBER} { unsigned long lval; + int ssf_ret; + ssf_ret = sscanf(yytext, "%lu", &lval); + if (ssf_ret != 1) { + bail_with_error("Number (%s) couldn't be read by lexer!", + yytext); + } + if (INT_MAX < lval ) { + char msgbuf[512]; + if (strlen(yytext) >= 300) { + snprintf(msgbuf, 327, "Number (%s...) is too large!", + yytext); + } else { + sprintf(msgbuf, "Number (%s) is too large!", yytext); + } + yyerror(lexer_filename(), msgbuf); + } + number2ast((int) lval); + return numbersym; + } + +\+ { tok2ast(plussym); return plussym; } +- { tok2ast(minussym); return minussym; } +\* { tok2ast(multsym); return multsym; } +\/ { tok2ast(divsym); return divsym; } + +\. { return periodsym; } +\; { return semisym; } +, { return commasym; } +:= { return becomessym; } +== { tok2ast(eqsym); return eqeqsym; } += { tok2ast(eqsym); return eqsym; } +!= { tok2ast(neqsym); return neqsym; } +\<= { tok2ast(leqsym); return leqsym; } +\>= { tok2ast(geqsym); return geqsym; } +\> { tok2ast(gtsym); return gtsym; } +\< { tok2ast(ltsym); return ltsym; } +\( { tok2ast(lparensym); return lparensym; } +\) { tok2ast(rparensym); return rparensym; } + +const { tok2ast(constsym); return constsym; } +var { tok2ast(varsym); return varsym; } +proc { tok2ast(procsym); return procsym; } +call { tok2ast(callsym); return callsym; } +begin { tok2ast(beginsym); return beginsym; } +end { tok2ast(endsym); return endsym; } +if { tok2ast(ifsym); return ifsym; } +then { tok2ast(thensym); return thensym; } +else { tok2ast(elsesym); return elsesym; } +while { tok2ast(whilesym); return whilesym; } +do { tok2ast(dosym); return dosym; } +read { tok2ast(readsym); return readsym; } +print { tok2ast(printsym); return printsym; } +divisible { tok2ast(divisiblesym); return divisiblesym; } +by { tok2ast(bysym); return bysym; } + +{IDENT} { ident2ast(yytext); return identsym; } + +. { char msgbuf[512]; + sprintf(msgbuf, "invalid character: '%c' ('\\0%o')", *yytext, *yytext); + yyerror(lexer_filename(), msgbuf); + } +%% + + /* This code goes in the user code section of the spl_lexer.l file, + following the last %% above. */ + +// Requires: fname != NULL +// Requires: fname is the name of a readable file +// Initialize the lexer and start it reading +// from the given file name +void lexer_init(char *fname) +{ + errors_noted = false; + yyin = fopen(fname, "r"); + if (yyin == NULL) { + bail_with_error("Cannot open %s", fname); + } + input_filename = fname; +} + +// Close the file yyin +// and return 0 to indicate that there are no more files +int yywrap() { + if (yyin != NULL) { + int rc = fclose(yyin); + if (rc == EOF) { + bail_with_error("Cannot close %s!", input_filename); + } + } + input_filename = NULL; + return 1; /* no more input */ +} + +// Return the name of the current input file +const char *lexer_filename() { + return input_filename; +} + +// Return the line number of the next token +unsigned int lexer_line() { + return yylineno; +} + +/* Report an error to the user on stderr */ +void yyerror(const char *filename, const char *msg) +{ + fflush(stdout); + fprintf(stderr, "%s:%d: %s\n", input_filename, lexer_line(), msg); + errors_noted = true; +} + +// On standard output: +// Print a message about the file name of the lexer's input +// and then print a heading for the lexer's output. +void lexer_print_output_header() +{ + printf("Tokens from file %s\n", lexer_filename()); + printf("%-6s %-4s %s\n", "Number", "Line", "Text"); +} + +// Have any errors been noted by the lexer? +bool lexer_has_errors() +{ + return errors_noted; +} + +// Print information about the token t to stdout +// followed by a newline +void lexer_print_token(enum yytokentype t, unsigned int tline, + const char *txt) +{ + printf("%-6d %-4d \"%s\"\n", t, tline, txt); +} + + +/* Read all the tokens from the input file + * and print each token on standard output + * using the format in lexer_print_token */ +void lexer_output() +{ + lexer_print_output_header(); + AST dummy; + yytoken_kind_t t; + do { + t = yylex(&dummy); + if (t == YYEOF) { + break; + } + lexer_print_token(t, yylineno, yytext); + } while (t != YYEOF); +} diff --git a/FromGithub/spl_lexer.o b/FromGithub/spl_lexer.o new file mode 100644 index 0000000000000000000000000000000000000000..a257ff786f758344335226ba8c92c997144341f0 GIT binary patch literal 67688 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

    lYs5^7i;HcT}$LsnkjQm)@H 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≈ob6${z-N+uo+|K%X?#@(oUiLI5cm$#=PJTIAg&kwUdIE3b%K5g>6zchXZlQP z*Hwak7U}sHgfsmRvXh$y&h`FQ@L@aW_wkv}J5=w-g3l)6e@yV<=a~Y1P5ZcCt|NQv zNjUTWocI(8`bHXG(*%72&3B99&{tddAP|AN(W$raA%Opb>~M|XAEExeQqT`4`F|_$ zoy2E{;4>H-2;s1xPa*uDf_|N*hVQZTGZEGs-}me%aDG3kh;U@9MI`x87WCzWFS6*p zR41Nl1wB7kN!_6R_5h2X-2HLy^O8Ae`V)YDJeA?HC2Pi#V;Ga@@mcYNI^gMy{`>P8Do<;q*Sl|VOpC#~tgqI7vi12EGk0ZQZ;4=wt z6gdB$R*S&-z1GzN=ik#>EAWen|78Ndg77N@zKQUk3VbW!TLk`V!mkzh1BBlw@EwG2 z6Zlhv|4QJ0Ap9PIzd<$;)TKE`?7IA7qr{%jC9uX}$ga9%&(CvaZ3zbtTG{~s1OUtjS1!Yn6W zr|^3rjPrHVd;}mc&ev-V0_W?&p9-9>L+=wfUvKOcIA0eZ6gXdB`+c$U@OAnif%El# zsla*PpibbtFR@YJyzgjXXT>uwY{?;GDG zaNd`8idxnz4_8#eIoxc{bsTFBHB=PoA6G4^t_W8+MU^crPLW2Nn+&28`WH3f$2x18 zoFWsisH|)btt484nkyP>Lr~r%n;UBz>RZCh&w%4(S`lgvuc5j_b>%h970W}$X#O{jK`4tZf!7nv zs+b}l^ku}H$$hvWZu_B06uXFt?ERTJFT_O!gf8%hWog;%(Cq{V*B^+}uz;8egZh~> znH$5pE;j*@q40-1W%&_Q{sNnrXl-a5B(Q$8Lpu~x`4n6LSs`e}F**|dP{v~TvqS!4 zCiN)^hV4gFmF=GanA9njoJ$L>^&|&k7$ogfz&fkn|AZ!Y@@WBv_2VU*tbYMuk|&mY z$bylJBMR=kbLK@sPBa0^XVY3rYSRWLPLaUI$3|uLcZxN<9srp`A?oA3&l5 z*U#sh0PU>&@KuKXZ%k;CZd)1N9;bZz8dCtrmmRnqpC5%xj@xu6Qh6K0xTJj^Ftp3# z#vhdrLY^I1e~kSNBFIygUrOcqeQc(e<^K#Bo%NspJ5yo;WPGtD zC3ploBL9JQ$i513E{~VZ(syD0!8SZP&Y!7%lR931S&-3L`C@v(?;sbXv(*3p0y>pd AmjD0& literal 0 HcmV?d00001 diff --git a/FromGithub/symtab.c b/FromGithub/symtab.c new file mode 100644 index 0000000..fc00ab4 --- /dev/null +++ b/FromGithub/symtab.c @@ -0,0 +1,169 @@ +/* $Id: symtab.c,v 1.9 2024/11/10 22:48:40 leavens Exp $ */ +#include +#include "symtab.h" +#include "scope.h" +#include "utilities.h" + +// The symbol table is a stack of scope (see the scope module). + +// index of the top of the stack of scopes +static int symtab_top_idx = -1; + +// the symbol table itself +static scope_t *symtab[MAX_NESTING]; + +// initialize the symbol table +void symtab_initialize() +{ + // initialize the internal state + symtab_top_idx = -1; + for (int i = 0; i < MAX_NESTING; i++) { + symtab[i] = NULL; + } +} + +// Return the number of scopes currently in the symbol table. +unsigned int symtab_size() +{ + return symtab_top_idx + 1; +} + +// Does this symbol table have any scopes in it? +bool symtab_empty() +{ + return symtab_size() == 0; +} + +// Return the current scope's next location count +// (of constants and variables). +unsigned int symtab_scope_loc_count() +{ + return scope_loc_count(symtab[symtab_top_idx]); +} + +// Return the current scope's size (the number of declared ids). +unsigned int symtab_scope_size() +{ + return scope_size(symtab[symtab_top_idx]); +} + +// Is the current scope full? +bool symtab_scope_full() +{ + return scope_full(symtab[symtab_top_idx]); +} + +// Return the current nesting level of the symbol table +// (this is the number of (client made) symtab_enter_scope() calls +// minus the number of symtab_leave_scope() calls +unsigned int symtab_current_nesting_level() +{ + // assert(symtab_top_idx >= 0); + return symtab_top_idx; +} + +// Is the symbol table itself full +// (i.e., is symtab_current_nesting_level() equal to MAX_NESTING-1)? +bool symtab_full() +{ + return symtab_current_nesting_level() == MAX_NESTING - 1; +} + +// Is the given name associated with some attributes? +// (this looks back through all scopes). +bool symtab_defined(const char *name) +{ + return symtab_lookup(name) != NULL; +} + +// Is the given name associated with some attributes in the current scope? +// (this only looks in the current scope). +bool symtab_defined_in_current_scope(const char *name) +{ + id_attrs *attrs = scope_lookup(symtab[symtab_top_idx], name); + return attrs != NULL; +} + + +// Put the given name, which is to be declared with kind k, +// and has its declaration at the given file location (floc), +// into the current scope's symbol table at the offset scope_next_offset(). +static void add_ident(scope_t *s, const char*name, id_attrs *attrs) +{ + id_attrs *old_attrs = scope_lookup(s, name); + if (old_attrs != NULL) { + bail_with_prog_error(attrs->file_loc, + "%s \"%s\" is already declared as a %s", + id_attrs_id_kind_string(attrs->kind), name, + id_attrs_id_kind_string(old_attrs->kind)); + } else { + scope_insert(s, name, attrs); + } +} + +// Requires: !symtab_defined(name) && attrs != NULL +// Modify the current scope (as recorded in the symbol table) to +// add an association from the given name to attributes appropriate +// for k and floc. +void symtab_insert(const char *name, id_attrs *attrs) +{ + add_ident(symtab[symtab_top_idx], name, attrs); +} + +// Requires: !symtab_full() +// Start a new scope (for a procedure) +void symtab_enter_scope() +{ + symtab_top_idx++; + symtab[symtab_top_idx] = scope_create(); +} + +// Requires: !symtab_empty() +void symtab_leave_scope() +{ + if (symtab_top_idx < 0) { + bail_with_error("Cannot leave scope, no scope on symtab's stack!"); + } + symtab_top_idx--; +} + +// Return (a pointer to) the attributes of the given name +// or NULL if there is no association for name in the symbol table. +// (this looks back through all scopes). +id_use *symtab_lookup(const char *name) +{ + unsigned int levelsOut = 0; + for (int level = symtab_top_idx; 0 <= level; level--) { + id_attrs *attrs = scope_lookup(symtab[level], name); + if (attrs != NULL) { + // debug_print("symtab_lookup returning with levelsOut == %d for %s\n", + // levelsOut, name); + return id_use_create(attrs, levelsOut); + } + levelsOut++; + } + return NULL; +} + +// We'll use lexical addresses in HW4... +// Requires: symtab_defined(name) +// Return (a pointer to) the lexical address of the given name +// or NULL if there is no association for name. +/* +lexical_address *symtab_lexical_address(const char *name) +{ + // maintaining: -1 <= level <= symtab_top_idx; + // maintaining: (for all int j: + // level < j <= symtab_top_idx + // ==> !scope_defined(symtab[j], name)) + for (int level = symtab_top_idx; 0 <= level; level--) { + id_attrs *attrs = scope_lookup(symtab[level], name); + if (attrs != NULL) { + return lexical_address_create(symtab_top_idx - level, + attrs->loc_offset); + } + } + bail_with_error("Couldn't find %s for symtab_lexical_address!", name); + return NULL; +} +*/ diff --git a/FromGithub/symtab.h b/FromGithub/symtab.h new file mode 100644 index 0000000..742c205 --- /dev/null +++ b/FromGithub/symtab.h @@ -0,0 +1,66 @@ +/* $Id: symtab.h,v 1.5 2023/11/13 12:52:01 leavens Exp $ */ +#ifndef _SYMTAB_H +#define _SYMTAB_H + +#include "scope.h" +#include "id_use.h" + +// Maximum number of declarations that can be stored in a scope +#define MAX_NESTING 100 + +// initialize the symbol table +extern void symtab_initialize(); + +// Return the number of scopes currently in the symbol table. +extern unsigned int symtab_size(); + +// Does this symbol table have any scopes in it? +extern bool symtab_empty(); + +// Return the current scope's next location count +// (of constants and variables). +extern unsigned int symtab_scope_loc_count(); + +// Return the current scope's size (the number of declared ids). +extern unsigned int symtab_scope_size(); + +// Is the current scope full? +extern bool symtab_scope_full(); + +// Return the current nesting level of the symbol table +// (this is the number of symtab_enter_scope() calls +// minus the number of symtab_leave_scope() calls +extern unsigned int symtab_current_nesting_level(); + +// Is the symbol table itself full +// (i.e., is symtab_current_nesting_level() equal to MAX_NESTING-1)? +extern bool symtab_full(); + +// Is the given name associated with some attributes? +// (this looks back through all scopes). +extern bool symtab_defined(const char *name); + +// Is the given name associated with some attributes in the current scope? +// (this only looks in the current scope). +extern bool symtab_defined_in_current_scope(const char *name); + +// Requires: !symtab_defined_in_current_scope(name) && attrs != NULL +// Modify the current scope (as recorded in the symbol table) to +// add an association from the given name to the given attributes attrs. +extern void symtab_insert(const char *name, id_attrs *attrs); + +// Requires: !symtab_full() +// Start a new scope (for a procedure) +extern void symtab_enter_scope(); + +// Requires: !symtab_empty() +extern void symtab_leave_scope(); + +// Return (a pointer to) a struct containing: +// the attributes of the given name (attrs) +// and the number of lexical levels outward +// from the current scope at which the name was declared, +// or NULL if there is no association for name. +extern id_use *symtab_lookup(const char *name); + +#endif diff --git a/FromGithub/symtab.o b/FromGithub/symtab.o new file mode 100644 index 0000000000000000000000000000000000000000..c71f8fa2103da9ef2e01d876254b73ce15a81a8c GIT binary patch literal 12184 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 ZvS=jCXv+WVt)?%oRr=pjm&&)P|G$SO^R55@ literal 0 HcmV?d00001 diff --git a/FromGithub/unparser.c b/FromGithub/unparser.c new file mode 100644 index 0000000..4ad5b40 --- /dev/null +++ b/FromGithub/unparser.c @@ -0,0 +1,427 @@ +/* $Id: unparser.c,v 1.11 2024/10/23 13:38:20 leavens Exp $ */ +#include +#include +#include "unparser.h" +#include "utilities.h" + +// Amount of spaces to indent per nesting level +#define SPACES_PER_LEVEL 2 + +// Print SPACES_PER_LEVEL * level spaces to out +static void indent(FILE *out, int level) +{ + int num = SPACES_PER_LEVEL * level; + for (int i = 0; i < num; i++) { + fprintf(out, " "); + } +} + +// Print (to out) a semicolon, but only if addSemiToEnd is true, +// and then print a newline. +static void newlineAndOptionalSemi(FILE *out, bool addSemiToEnd) +{ + fprintf(out, "%s\n", (addSemiToEnd ? ";" : "")); +} + +// Unparse the given program AST and then print a period and an newline +void unparseProgram(FILE *out, block_t prog) +{ + unparseBlock(out, prog, 0, false); + fprintf(out, ".\n"); +} + +// Unparse the given block, indented by the given level, to out +// adding a semicolon to the end if addSemiToEnd is true. +extern void unparseBlock(FILE *out, block_t blk, int level, + bool addSemiToEnd) +{ + indent(out, level); + fprintf(out, "begin\n"); + unparseConstDecls(out, blk.const_decls, level+1); + unparseVarDecls(out, blk.var_decls, level+1); + unparseProcDecls(out, blk.proc_decls, level+1); + unparseStmts(out, blk.stmts, level+1); + indent(out, level); + fprintf(out, "end"); + newlineAndOptionalSemi(out, addSemiToEnd); +} + +// Unparse the list of const-decls given by the AST cds to out +// with the given nesting level +// (note that if cds == NULL, then nothing is printed) +void unparseConstDecls(FILE *out, const_decls_t cds, int level) +{ + // debug_print("unparseConstDecls entry ...\n"); + assert(cds.type_tag == const_decls_ast); + const_decl_t *cd_listp = cds.start; + while (cd_listp != NULL) { + unparseConstDecl(out, *cd_listp, level); + cd_listp = cd_listp->next; + } +} + +// Unparse a single const-def given by the AST cd to out, +// indented for the given nesting level +void unparseConstDecl(FILE *out, const_decl_t cd, int level) +{ + // debug_print("unparseConstDecl entry ...\n"); + indent(out, level); + fprintf(out, "const "); + unparseConstDefList(out, cd.const_def_list, level); +} + +// Unparse the list of const-defs given by the AST cdl to out +// with the given nesting level, followed by a semicolon and a newline. +void unparseConstDefList(FILE *out, const_def_list_t cdl, int level) +{ + // debug_print("unparseConstDefList entry ...\n"); + assert(cdl.type_tag == const_def_list_ast); + bool printed_already = false; + const_def_t *cdp = cdl.start; + while (cdp != NULL) { + if (printed_already) { + fprintf(out, ", "); + } + unparseConstDef(out, *cdp, level); + printed_already = true; + cdp = cdp->next; + } + fprintf(out, ";\n"); +} + +// Unparse the const-def given by the AST cdf to out +// with the given nesting level +extern void unparseConstDef(FILE *out, const_def_t cdf, int level) +{ + fprintf(out, "%s = %d", cdf.ident.name, cdf.number.value); +} + +// Unparse the list of vart-decls given by the AST vds to out +// with the given nesting level +// (note that if vds.var_decls == NULL, then nothing is printed) +void unparseVarDecls(FILE *out, var_decls_t vds, int level) +{ + // debug_print("Entering unparseVarDecls ...\n"); + assert(vds.type_tag == var_decls_ast); + var_decl_t *vdp = vds.var_decls; + while (vdp != NULL) { + unparseVarDecl(out, *vdp, level); + vdp = vdp->next; + } +} + +// Unparse a single var-decl given by the AST vd to out, +// indented for the given nesting level +void unparseVarDecl(FILE *out, var_decl_t vd, int level) +{ + // debug_print("Entering unparseVarDecl ...\n"); + indent(out, level); + fprintf(out, "var"); + unparseIdentList(out, vd.ident_list); + fprintf(out, ";\n"); +} + +// Unparse the identifiers in idents to out, with a space before each, +// and a comma as a separator +void unparseIdentList(FILE *out, ident_list_t ident_list) +{ + // debug_print("Entering unparseIdentList ...\n"); + ident_t *ip = ident_list.start; + bool already_printed =false; + while (ip != NULL) { + // debug_print("in unparseIdents ip is %x\n", ip); + // debug_print("in unparseIdents ip->name is %s\n", ip->name); + if (already_printed) { + fprintf(out, ", %s", ip->name); + } else { + fprintf(out, " %s", ip->name); + } + already_printed = true; + ip = ip->next; + } +} + +// Unparse the list of proc-decls given by the AST pds to out +// with the given nesting level +// (note that if pds.proc_decls is NULL, then nothing is printed) +void unparseProcDecls(FILE *out, proc_decls_t pds, int level) +{ + // debug_print("unparseProcDecls entry ...\n"); + assert(pds.type_tag == proc_decls_ast); + proc_decl_t *pdp = pds.proc_decls; + while (pdp != NULL) { + unparseProcDecl(out, *pdp, level); + pdp = pdp ->next; + } +} + +// Unparse the given proc-decl given by the AST pd to out +// with the given nesting level followed by a semicolon +void unparseProcDecl(FILE *out, proc_decl_t pd, int level) +{ + // debug_print("unparseProcDecl entry ...\n"); + indent(out, level); + fprintf(out, "proc %s\n", pd.name); + unparseBlock(out, *(pd.block), level, true); +} + + +// Unparse the stmts given by stmt to out +// with indentation level given by level. +// (The statements always occur before an end, so a semicolon is never added.) +void unparseStmts(FILE *out, stmts_t stmts, int level) +{ + // indent(out, level); + // fprintf(out, "%% stmts at level %d\n", level); + if (stmts.stmts_kind != empty_stmts_e) { + stmt_list_t sl = stmts.stmt_list; + unparseStmtList(out, sl, level, false); + } +} + +// Unparse the stmts given by stmt to out +// with indentation level given by level, +// and add a semicolon at the end if addSemiToEnd is true. +void unparseStmtList(FILE *out, stmt_list_t stmt_list, int level, + bool addSemiToEnd) +{ + // indent(out, level); + // fprintf(out, "%% stmtList at level %d\n", level); + stmt_t *s = stmt_list.start; + while (s != NULL) { + unparseStmt(out, *s, level, addSemiToEnd || (s->next != NULL)); + s = s->next; + } +} + +// Unparse the statement given by the AST stmt to out, +// indented for the given level, +// adding a semicolon to the end if addSemiToENd is true. +void unparseStmt(FILE *out, stmt_t stmt, int level, bool addSemiToEnd) +{ + // debug_print("In unparseStmt stmt.type_tag is %d\n", stmt.type_tag); + assert(stmt.type_tag == stmt_ast); + switch (stmt.stmt_kind) { + case assign_stmt: + assert(stmt.data.assign_stmt.type_tag == assign_stmt_ast); + unparseAssignStmt(out, stmt.data.assign_stmt, level, addSemiToEnd); + break; + case call_stmt: + unparseCallStmt(out, stmt.data.call_stmt, level, addSemiToEnd); + break; + case if_stmt: + unparseIfStmt(out, stmt.data.if_stmt, level, addSemiToEnd); + break; + case while_stmt: + unparseWhileStmt(out, stmt.data.while_stmt, level, addSemiToEnd); + break; + case read_stmt: + unparseReadStmt(out, stmt.data.read_stmt, level, addSemiToEnd); + break; + case print_stmt: + unparsePrintStmt(out, stmt.data.print_stmt, level, addSemiToEnd); + break; + case block_stmt: + unparseBlockStmt(out, stmt.data.block_stmt, level, addSemiToEnd); + break; + default: + bail_with_error("Unknown stmt_kind (%d) in unparseStmt!", + stmt.stmt_kind); + break; + } +} + +// Unparse the assignment statment given by stmt to out +// with indentation level given by level, +// and add a semicolon at the end if addSemiToEnd is true. +void unparseAssignStmt(FILE *out, assign_stmt_t stmt, int level, + bool addSemiToEnd) +{ + indent(out, level); + fprintf(out, "%s := ", stmt.name); + if (stmt.expr == NULL) { + bail_with_error("Found null expression in assignment statment!"); + } + unparseExpr(out, *(stmt.expr)); + newlineAndOptionalSemi(out, addSemiToEnd); +} + +// Unparse the call statment given by stmt to out +// with indentation level given by level, +// and add a semicolon at the end if addSemiToEnd is true. +void unparseCallStmt(FILE *out, call_stmt_t stmt, int level, + bool addSemiToEnd) +{ + indent(out, level); + fprintf(out, "call %s", stmt.name); + newlineAndOptionalSemi(out, addSemiToEnd); +} + +// Unparse the sequential statment given by stmt to out +// with indentation level given by level (indenting the body one more level) +// and add a semicolon at the end if addSemiToEnd is true. +void unparseBlockStmt(FILE *out, block_stmt_t stmt, int level, + bool addSemiToEnd) +{ + unparseBlock(out, *(stmt.block), level, addSemiToEnd); +} + +// Unparse the if-statment given by stmt to out +// with indentation level given by level (and each body indented one more), +// and add a semicolon at the end if addSemiToEnd is true. +void unparseIfStmt(FILE *out, if_stmt_t stmt, int level, bool addSemiToEnd) +{ + indent(out, level); + fprintf(out, "if "); + unparseCondition(out, stmt.condition); + fprintf(out, "\n"); + indent(out, level); + fprintf(out, "then\n"); + unparseStmts(out, *(stmt.then_stmts), level+1); + if (stmt.else_stmts != NULL) { + indent(out, level); + fprintf(out, "else\n"); + unparseStmts(out, *(stmt.else_stmts), level+1); + } + indent(out, level); + fprintf(out, "end"); + newlineAndOptionalSemi(out, addSemiToEnd); +} + +// Unparse the while-statment given by stmt to out +// with indentation level given by level (and the body indented one more), +// and add a semicolon at the end if addSemiToEnd is true. +void unparseWhileStmt(FILE *out, while_stmt_t stmt, int level, + bool addSemiToEnd) +{ + indent(out, level); + fprintf(out, "while "); + unparseCondition(out, stmt.condition); + fprintf(out, "\n"); + indent(out, level); + fprintf(out, "do\n"); + unparseStmts(out, *(stmt.body), level+1); + indent(out, level); + fprintf(out, "end"); + newlineAndOptionalSemi(out, addSemiToEnd); +} + +// Unparse the read statment given by stmt to out +// and add a semicolon at the end if addSemiToEnd is true. +void unparseReadStmt(FILE *out, read_stmt_t stmt, int level, bool addSemiToEnd) +{ + indent(out, level); + fprintf(out, "read %s", stmt.name); + newlineAndOptionalSemi(out, addSemiToEnd); +} + +// Unparse the write statment given by stmt to out +// and add a semicolon at the end if addSemiToEnd is true. +void unparsePrintStmt(FILE *out, print_stmt_t stmt, int level, + bool addSemiToEnd) +{ + indent(out, level); + fprintf(out, "print "); + unparseExpr(out, stmt.expr); + newlineAndOptionalSemi(out, addSemiToEnd); +} + +// Unparse the condition given by cond to out +void unparseCondition(FILE *out, condition_t cond) +{ + switch (cond.cond_kind) { + case ck_db: + unparseDbCond(out, cond.data.db_cond); + break; + case ck_rel: + unparseRelOpCond(out, cond.data.rel_op_cond); + break; + default: + bail_with_error("Unexpected condition_kind_e (%d) in unparseCondition!", + cond.cond_kind); + break; + } +} + +// Unparse the odd condition given by cond to out +void unparseDbCond(FILE *out, db_condition_t dbcond) +{ + fprintf(out, "divisible "); + unparseExpr(out, dbcond.dividend); + fprintf(out, " by "); + unparseExpr(out, dbcond.divisor); +} + +// Unparse the binary relation condition given by cond to out +void unparseRelOpCond(FILE *out, rel_op_condition_t cond) +{ + unparseExpr(out, cond.expr1); + fprintf(out, " "); + unparseToken(out, cond.rel_op); + fprintf(out, " "); + unparseExpr(out, cond.expr2); +} + +// Unparse the given token, t, to out +void unparseToken(FILE *out, token_t t) +{ + fprintf(out, "%s", t.text); +} + +// Unparse the expression given by the AST exp to out +// adding parentheses to indicate the nesting relationships +void unparseExpr(FILE *out, expr_t exp) +{ + switch (exp.expr_kind) { + case expr_bin: + unparseBinOpExpr(out, exp.data.binary); + break; + case expr_negated: + unparseNegatedExpr(out, exp.data.negated); + break; + case expr_ident: + unparseIdent(out, exp.data.ident); + break; + case expr_number: + unparseNumber(out, exp.data.number); + break; + default: + bail_with_error("Unexpected expr_kind_e (%d) in unparseExpr!", + exp.expr_kind); + break; + } +} + +// Unparse the expression given by the AST exp to out +// adding parentheses (whether needed or not) +void unparseBinOpExpr(FILE *out, binary_op_expr_t exp) +{ + fprintf(out, "("); + unparseExpr(out, *(exp.expr1)); + fprintf(out, " "); + unparseToken(out, exp.arith_op); + fprintf(out, " "); + unparseExpr(out, *(exp.expr2)); + fprintf(out, ")"); +} + +// Unparse the expression given by the AST exp to out +// adding parentheses (whether needed or not) +void unparseNegatedExpr(FILE *out, negated_expr_t exp) +{ + fprintf(out, "-("); + unparseExpr(out, *(exp.expr)); + fprintf(out, ")"); +} + +// Unparse the given identifier reference (i.e., identifier use), id, to out +void unparseIdent(FILE *out, ident_t id) +{ + fprintf(out, "%s", id.name); +} + +// Unparse the given number AST, num, to out in decimal format +void unparseNumber(FILE *out, number_t num) +{ + fprintf(out, "%d", num.value); +} diff --git a/FromGithub/unparser.h b/FromGithub/unparser.h new file mode 100644 index 0000000..b3e65b0 --- /dev/null +++ b/FromGithub/unparser.h @@ -0,0 +1,138 @@ +/* $Id: unparser.h,v 1.6 2024/10/23 14:55:24 leavens Exp $ */ +#ifndef _UNPARSER_H +#define _UNPARSER_H +#include +#include "ast.h" + +// Unparse the given program AST and then print a period and an newline +extern void unparseProgram(FILE *out, block_t prog); + +// Unparse the given block, indented by the given level, to out +// adding a semicolon to the end if addSemiToEnd is true. +extern void unparseBlock(FILE *out, block_t blk, int indentLevel, + bool addSemiToEnd); + +// Unparse the list of const-decls given by the AST cds to out +// with the given nesting level +// (note that if cds is empty, then nothing is printed) +extern void unparseConstDecls(FILE *out, const_decls_t cds, int level); + +// Unparse the const-decl given by the AST cd to out +// with the given nesting level +extern void unparseConstDecl(FILE *out, const_decl_t cd, int level); + +// Unparse the list of const-defs given by the AST cdl to out +// with the given nesting level +extern void unparseConstDefList(FILE *out, const_def_list_t cdl, int level); + +// Unparse the const-def given by the AST cdf to out +// with the given nesting level +extern void unparseConstDef(FILE *out, const_def_t cdf, int level); + +// Unparse the list of var-decls given by the AST vds to out +// with the given nesting level +// (note that if vds.var_decls == NULL, then nothing is printed) +extern void unparseVarDecls(FILE *out, var_decls_t vds, int level); + +// Unparse the var-decl given by the AST vd to out +// with the given nesting level +extern void unparseVarDecl(FILE *out, var_decl_t vd, int level); + +// Unparse the identifiers in idents to out, with a space before each, +// and a comma as a separator +extern void unparseIdentList(FILE *out, ident_list_t ident_list); + +// Unparse the list of proc-decls given by the AST pds to out +// with the given nesting level +// (note that if pds.proc_decls is NULL, then nothing is printed) +extern void unparseProcDecls(FILE *out, proc_decls_t pds, int level); + +// Unparse the given proc-decl given by the AST pd to out +// with the given nesting level +extern void unparseProcDecl(FILE *out, proc_decl_t pd, int level); + +// Unparse the statement given by the AST stmt to out, +// indented for the given level, +// adding a semicolon to the end if addSemiToEnd is true. +extern void unparseStmt(FILE *out, stmt_t stmt, int indentLevel, + bool addSemiToEnd); + +// Unparse the statement given by the AST stmt to out, +// indented for the given level, +// adding a semicolon to the end if addSemiToEnd is true. +extern void unparseAssignStmt(FILE *out, assign_stmt_t stmt, int level, bool addSemiToEnd); + +// Unparse the statement given by the AST stmt to out, +// indented for the given level, +// adding a semicolon to the end if addSemiToEnd is true. +extern void unparseCallStmt(FILE *out, call_stmt_t stmt, int level, bool addSemiToEnd); + +// Unparse the statement given by the AST stmt to out, +// indented for the given level, +// adding a semicolon to the end if addSemiToEnd is true. +extern void unparseBlockStmt(FILE *out, block_stmt_t stmt, int level, bool addSemiToEnd); + +// Unparse the statements given by the AST stmts to out, +// indented for the given level. +// (The statements always occur before an end, so a semicolon is never added.) +extern void unparseStmts(FILE *out, stmts_t stmts, int level); + +// Unparse the stmts given by stmt to out +// with indentation level given by level, +// and add a semicolon at the end if addSemiToEnd is true. +void unparseStmtList(FILE *out, stmt_list_t stmt_list, int level, + bool addSemiToEnd); + +// Unparse the statement given by the AST stmt to out, +// indented for the given level, +// adding a semicolon to the end if addSemiToEnd is true. +extern void unparseIfStmt(FILE *out, if_stmt_t stmt, int level, + bool addSemiToEnd); + +// Unparse the statement given by the AST stmt to out, +// indented for the given level, +// adding a semicolon to the end if addSemiToEnd is true. +extern void unparseWhileStmt(FILE *out, while_stmt_t stmt, int level, + bool addSemiToEnd); + +// Unparse the statement given by the AST stmt to out, +// indented for the given level, +// adding a semicolon to the end if addSemiToEnd is true. +extern void unparseReadStmt(FILE *out, read_stmt_t stmt, int level, + bool addSemiToEnd); + +// Unparse the statement given by the AST stmt to out, +// indented for the given level, +// adding a semicolon to the end if addSemiToEnd is true. +extern void unparsePrintStmt(FILE *out, print_stmt_t stmt, int level, bool addSemiToEnd); + +// Unparse the condition given by cond to out +extern void unparseCondition(FILE *out, condition_t cond); + +extern void unparseDbCond(FILE *out, db_condition_t cond); + +extern void unparseRelOpCond(FILE *out, rel_op_condition_t cond); + +// Unparse the given token, t, to out +extern void unparseToken(FILE *out, token_t t); + +// Unparse the expression given by the AST exp to out +// adding parentheses to indicate the nesting relationships +extern void unparseExpr(FILE *out, expr_t exp); + +extern void unparseBinOpExpr(FILE *out, binary_op_expr_t exp); + +// Unparse the given bin_arith_opo to out +extern void unparseArithOp(FILE *out, token_t arith_op); + +// Unparse the expression given by the AST exp to out +// adding parentheses (whether needed or not) +extern void unparseNegatedExpr(FILE *out, negated_expr_t exp); + +// Unparse the given identifer reference (use) to out +extern void unparseIdent(FILE *out, ident_t id); + +// Unparse the given number to out in decimal format +extern void unparseNumber(FILE *out, number_t num); + +#endif diff --git a/FromGithub/unparser.o b/FromGithub/unparser.o new file mode 100644 index 0000000000000000000000000000000000000000..1cf3aa198096805de07a69f57bca783466fdb182 GIT binary patch literal 37816 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 literal 0 HcmV?d00001 diff --git a/FromGithub/utilities.c b/FromGithub/utilities.c new file mode 100644 index 0000000..07ada71 --- /dev/null +++ b/FromGithub/utilities.c @@ -0,0 +1,113 @@ +/* $Id: utilities.c,v 1.4 2024/10/23 12:17:39 leavens Exp $ */ +#include +#include +#include +#include +#include +#include +#include "utilities.h" + +// to turn off debugging support (assertions and debug_print) +// define the symbol NDEBUG (by writing uncommenting the following) +// #define NDEBUG + +#ifdef NDEBUG +#define debug_print() ((void)0) +#else +// otherwise debugging is on, and debug_print is defined as follows... +// (note that assert is a macro defined in +static void vdebug_print(const char *fmt, va_list args); + +// If debugging is false, do nothing, otherwise (when debugging) +// flush stderr and stdout, then print the message given on stderr, +// using printf formatting from the format string fmt. +// This function returns normally. +void debug_print(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + vdebug_print(fmt, args); + va_end(args); +} + +// The variadic version of debug_print +static void vdebug_print(const char *fmt, va_list args) +{ + // flush output streams to synchronize outputs + fflush(stdout); + fflush(stderr); + vfprintf(stderr, fmt, args); + fflush(stderr); +} +#endif + +static void vbail_with_error(const char* fmt, va_list args); + +// Format a string error message and print it followed by a newline on stderr +// using perror (for an OS error, if the errno is not 0) +// then exit with a failure code, so a call to this does not return. +void bail_with_error(const char *fmt, ...) +{ + fflush(stdout); // flush so output comes after what has happened already + va_list(args); + va_start(args, fmt); + vbail_with_error(fmt, args); +} + +// The variadic version of bail_with_error +static void vbail_with_error(const char* fmt, va_list args) +{ + extern int errno; + char buff[2048]; + vsprintf(buff, fmt, args); + if (errno != 0) { + perror(buff); + } else { + fprintf(stderr, "%s\n", buff); + } + fflush(stderr); + exit(EXIT_FAILURE); +} + +// Print an error message on stderr +// starting with the file name and line number from the floc argument +// (prints: filename, a colon, " line ", the line number, and a space) +// and then the message. +// Then exit with a failure code, so this function does not return. +void bail_with_prog_error(file_location floc, const char *fmt, ...) +{ + fflush(stdout); // flush so output comes after what has happened already + // print file, line, column information + fprintf(stderr, "%s: line %d ", floc.filename, floc.line); + + va_list(args); + va_start(args, fmt); + vbail_with_error(fmt, args); +} + +#define BUF_SIZE 1024 + +// Call yyerror to print an error message on stderr +// starting with the filename, ":", the lexer's current line number, ": ", +// and then the formatted message (as in sprintf) +extern void formatted_yyerror(const char *filename, const char *fmt, ...) +{ + fflush(stdout); // flush so output comes after what has happened already + + char buf[BUF_SIZE]; + va_list(args); + va_start(args, fmt); + vsnprintf(buf, BUF_SIZE, fmt, args); + yyerror(filename, buf); + va_end(args); +} + + + +// print a newline on out and flush out +void newline(FILE *out) +{ + fprintf(out, "\n"); + fflush(out); +} + diff --git a/FromGithub/utilities.h b/FromGithub/utilities.h new file mode 100644 index 0000000..7a10aae --- /dev/null +++ b/FromGithub/utilities.h @@ -0,0 +1,37 @@ +/* $Id: utilities.h,v 1.5 2024/11/13 14:08:23 leavens Exp $ */ +#ifndef _UTILITIES_H +#define _UTILITIES_H +#include +#include +#include +#include "file_location.h" +#include "lexer_utilities.h" + +#define MAX(x,y) (((x)>(y))?(x):(y)) + +// If NDEBUG is defined, do nothing, otherwise (when debugging) +// flush stderr and stdout, then print the message given on stderr, +// using printf formatting from the format string fmt. +// This function returns normally. +void debug_print(const char *fmt, ...); + +// Format a string error message and print it using perror (for an OS error) +// then exit with a failure code, so a call to this does not return. +extern void bail_with_error(const char *fmt, ...); + +// Print an error message on stderr +// starting with the file name and line number from the floc argument +// (prints: filename, a colon, " line ", the line number, and a space) +// and then the message. +// Then exit with a failure code, so this function does not return. +extern void bail_with_prog_error(file_location floc, const char *fmt, ...); + +// Call yyerror to print an error message on stderr +// starting with the filename, ":", the lexer's current line number, ": ", +// and then the formatted message (as in sprintf) +extern void formatted_yyerror(const char *filename, const char *fmt, ...); + +// print a newline on out and flush out +extern void newline(FILE *out); + +#endif diff --git a/FromGithub/utilities.o b/FromGithub/utilities.o new file mode 100644 index 0000000000000000000000000000000000000000..a0954e200883cb9846c1a330c23596ac2d85e8ae GIT binary patch literal 11960 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 IG}86|7eIEl9RL6T literal 0 HcmV?d00001 From d91c24eb2d64a5ba72a0aef31baaf65551104dda Mon Sep 17 00:00:00 2001 From: MarkMango21 Date: Thu, 21 Nov 2024 15:02:09 -0800 Subject: [PATCH 4/6] Ok --- FromGithub/CopyWork.zip | Bin 0 -> 278136 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 FromGithub/CopyWork.zip diff --git a/FromGithub/CopyWork.zip b/FromGithub/CopyWork.zip new file mode 100644 index 0000000000000000000000000000000000000000..94af7c38611c27bbd9d01db128a8206272098945 GIT binary patch literal 278136 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

    84voS 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 literal 0 HcmV?d00001 From 6dff09e45aeb73d207fd0da27e0168a40cff9b0e Mon Sep 17 00:00:00 2001 From: MarkMango21 Date: Thu, 21 Nov 2024 15:53:11 -0800 Subject: [PATCH 5/6] ok --- .vscode/c_cpp_properties.json | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .vscode/c_cpp_properties.json diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..f18a699 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "windows-gcc-x64", + "includePath": [ + "${workspaceFolder}/**" + ], + "compilerPath": "C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/gcc.exe", + "cStandard": "${default}", + "cppStandard": "${default}", + "intelliSenseMode": "windows-gcc-x64", + "compilerArgs": [ + "" + ] + } + ], + "version": 4 +} \ No newline at end of file From bb5e8814432dbfafc8e3325bcaf01622df3e678c Mon Sep 17 00:00:00 2001 From: MarkMango21 Date: Thu, 21 Nov 2024 15:54:52 -0800 Subject: [PATCH 6/6] ok --- FromGithub/bof.c | 105 +++++++++++++++++++++++++++-------------------- 1 file changed, 61 insertions(+), 44 deletions(-) diff --git a/FromGithub/bof.c b/FromGithub/bof.c index 598aaac..c42f73b 100644 --- a/FromGithub/bof.c +++ b/FromGithub/bof.c @@ -9,9 +9,10 @@ #include "utilities.h" #define MAGIC "BO32" - -// a type for treating bytes as a word -typedef union { +// this is a comment +// a type for treating bytes as a word +typedef union +{ unsigned char buf[BYTES_PER_WORD]; word_type w; } word_pun_t; @@ -19,15 +20,17 @@ typedef union { // Open filename for reading as a binary file // Exit the program with an error if this fails, // otherwise return the BOFFILE struct for the file -BOFFILE bof_read_open(const char *filename) { +BOFFILE bof_read_open(const char *filename) +{ BOFFILE bf; bf.fileptr = fopen(filename, "rb"); bf.filename = filename; - if (bf.fileptr == NULL) { - bail_with_error("Error opening file for reading: %s", filename); + if (bf.fileptr == NULL) + { + bail_with_error("Error opening file for reading: %s", filename); } - + return bf; } @@ -35,15 +38,16 @@ BOFFILE bof_read_open(const char *filename) { size_t bof_file_bytes(BOFFILE bf) { struct stat st; - if (stat(bf.filename, &st) < 0) { - bail_with_error("Cannot stat %s to get its size!", bf.filename); - } - ; + if (stat(bf.filename, &st) < 0) + { + bail_with_error("Cannot stat %s to get its size!", bf.filename); + }; return st.st_size; } // Return true just when bf is at its end, false otherwise -bool bof_at_eof(BOFFILE bf) { +bool bof_at_eof(BOFFILE bf) +{ return feof(bf.fileptr); } @@ -55,10 +59,11 @@ word_type bof_read_word(BOFFILE bf) word_pun_t b; assert(!bof_at_eof(bf)); size_t bytes_read = bof_read_bytes(bf, BYTES_PER_WORD, b.buf); - if (bytes_read == 0) { - bail_with_error( - "Cannot read a word from %s (got %d bytes), at EOF: %d", - bf.filename, bytes_read, bof_at_eof(bf)); + if (bytes_read == 0) + { + bail_with_error( + "Cannot read a word from %s (got %d bytes), at EOF: %d", + bf.filename, bytes_read, bof_at_eof(bf)); } return b.w; } @@ -66,7 +71,8 @@ word_type bof_read_word(BOFFILE bf) // Requires: bf.fileptr is open for reading in binary // and buf is of size at least bytes // Read the given number of bytes into buf and return the number of bytes read -size_t bof_read_bytes(BOFFILE bf, size_t bytes, void *buf) { +size_t bof_read_bytes(BOFFILE bf, size_t bytes, void *buf) +{ int elems_read = fread(buf, bytes, 1, bf.fileptr); return elems_read; } @@ -74,22 +80,25 @@ size_t bof_read_bytes(BOFFILE bf, size_t bytes, void *buf) { // Requires: bf is open for reading in binary // Read the header of bf as a BOFHeader and return that header // If any errors are encountered, exit with an error message. -BOFHeader bof_read_header(BOFFILE bf) { +BOFHeader bof_read_header(BOFFILE bf) +{ BOFHeader ret; size_t rd = fread(&ret, sizeof(ret), 1, bf.fileptr); - if (rd != 1) { - bail_with_error("Cannot read header from %s", bf.filename); + if (rd != 1) + { + bail_with_error("Cannot read header from %s", bf.filename); } - if (!bof_has_correct_magic_number(ret)) { - bail_with_error("Wrong magic number code in file '%s'!", - bf.filename); + if (!bof_has_correct_magic_number(ret)) + { + bail_with_error("Wrong magic number code in file '%s'!", + bf.filename); } return ret; /* bof_read_bytes(bf, MAGIC_BUFFER_SIZE, &ret.magic); if (strncmp(ret.magic, MAGIC, MAGIC_BUFFER_SIZE) != 0) { - bail_with_error("File %s is not a BOF format file, bad magic number!", - bf.filename); + bail_with_error("File %s is not a BOF format file, bad magic number!", + bf.filename); } bof_read_bytes(bf, BYTES_PER_WORD, &ret.text_start_address); bof_read_bytes(bf, BYTES_PER_WORD, &ret.text_length); @@ -107,7 +116,7 @@ BOFHeader bof_read_header(BOFFILE bf) { void bof_write_magic(FILE *f) { fprintf(f, "%s", "0x"); for (int i = 0; i < MAGIC_BUFFER_SIZE; i++) { - fprintf(f, "%x", MAGIC[i]); + fprintf(f, "%x", MAGIC[i]); } fprintf(f, "\n"); } @@ -116,15 +125,17 @@ void bof_write_magic(FILE *f) { // Open filename for writing as a binary file // Exit the program with an error if this fails, // otherwise return the BOFFILE for it. -BOFFILE bof_write_open(const char *filename) { +BOFFILE bof_write_open(const char *filename) +{ BOFFILE bf; bf.fileptr = fopen(filename, "wb"); bf.filename = filename; - if (bf.fileptr == NULL) { - bail_with_error("Error opening file for writing: %s", filename); + if (bf.fileptr == NULL) + { + bail_with_error("Error opening file for writing: %s", filename); } - + return bf; } @@ -133,12 +144,12 @@ BOFFILE bof_write_open(const char *filename) { // Exit the program with an error if this fails. void bof_close(BOFFILE bf) { - if (fclose(bf.fileptr) != 0) { - bail_with_error("Could not close %s", bf.filename); + if (fclose(bf.fileptr) != 0) + { + bail_with_error("Could not close %s", bf.filename); } } - // Requires: bf is open for writing in binary. // Write the given word into bf // Exit the program with an error if this fails. @@ -154,20 +165,24 @@ extern void bof_write_word(BOFFILE bf, word_type w) // Write the given number of bytes from buf into f. // Exit the program with an error if this fails. void bof_write_bytes(BOFFILE bf, size_t bytes, - const void *buf) { + const void *buf) +{ size_t wr = fwrite(buf, bytes, 1, bf.fileptr); - if (wr != 1) { - bail_with_error("Cannot write %u bytes to %s", bytes, bf.filename); + if (wr != 1) + { + bail_with_error("Cannot write %u bytes to %s", bytes, bf.filename); } } // Requires: bf is open for writing in binary // Write the given header to f // Exit the program with an error if this fails. -void bof_write_header(BOFFILE bf, const BOFHeader hdr) { +void bof_write_header(BOFFILE bf, const BOFHeader hdr) +{ size_t wr = fwrite(&hdr, sizeof(BOFHeader), 1, bf.fileptr); - if (wr != 1) { - bail_with_error("Canot write header to %s", bf.filename); + if (wr != 1) + { + bail_with_error("Canot write header to %s", bf.filename); } } @@ -175,8 +190,9 @@ void bof_write_header(BOFFILE bf, const BOFHeader hdr) { void bof_write_magic_to_header(BOFHeader *bh) { const char *magic = MAGIC; - for (int i = 0; i < MAGIC_BUFFER_SIZE; i++) { - bh->magic[i] = magic[i]; + for (int i = 0; i < MAGIC_BUFFER_SIZE; i++) + { + bh->magic[i] = magic[i]; } assert(bof_has_correct_magic_number(*bh)); } @@ -184,9 +200,10 @@ void bof_write_magic_to_header(BOFHeader *bh) // Does the given header have the appropriate magic number? bool bof_has_correct_magic_number(BOFHeader bh) { - char buf[MAGIC_BUFFER_SIZE+1]; - for (int i = 0; i < MAGIC_BUFFER_SIZE; i++) { - buf[i] = bh.magic[i]; + char buf[MAGIC_BUFFER_SIZE + 1]; + for (int i = 0; i < MAGIC_BUFFER_SIZE; i++) + { + buf[i] = bh.magic[i]; } buf[MAGIC_BUFFER_SIZE] = '\0'; return (0 == strncmp(buf, MAGIC, MAGIC_BUFFER_SIZE));

    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%0D@= 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