// Track 1: Core Infrastructure & Basic Expressions // * Add Bison actions for arithmetic expressions: // - Addition: $$ = new_temp(); emit_binary_op($$, "ADD", $1, $3); // - Subtraction, multiplication, division, modulo #pragma once #include "symbol_table.h" #include #include // these are from page 364 typedef enum { E_LABEL = 10000, // this is not in the book E_ADD, // 1 from the list E_SUB, // 1 E_MUL, // 1 E_DIV, // 1 E_MOD, // 1 E_OR, // 1 E_AND, // 1 E_NEG, // 2 E_NOT, // 2 E_ASSIGN, // 3 E_GOTO, // 4 E_COND_GOTO, // 5 I don't thik I need this because we could just follow the < or the = and just assume that it's a cond got E_IF_X_TRUE, // 5 E_IF_X_FALSE, // 5 E_LESS_THAN, // 6 rule 1 + 5 E_EQUAL_TO, // 6 rule 1 + 5 E_CALL, // 7 E_PARAM, // 7 E_RETURN, // 7 E_INDEX_COPY_RIGHT, // 8 this is x = y[i] E_INDEX_COPY_LEFT, // 8 x[i] = y E_ADDRESS_OF, // 9 x = &y E_DEREF_RIGHT, // 9 x = *y E_DEREF_LEFT // 9 x* = y } Op; typedef enum { NODE = 11000, // TableNode INTEGER, // int STRING, // char * CHARACTER, // char ADDRESS, // void * BOOLEAN // bool } Discriminant; typedef union { TableNode * node; int integer; char * string; char character; void * address; bool Boolean; } TNConstUnion; typedef struct { Discriminant d; TNConstUnion * tnc_union; } TNodeOrConst; typedef struct Instruction Instruction; typedef struct Instruction { Op opcode; TableNode * result; TNodeOrConst * operand1; TNodeOrConst * operand2; int label; int index; Instruction * prev; Instruction * next; } Instruction; typedef struct TFList { Instruction * i; TFList * next; } TFList; TFList * make_list(Instruction * i); // - makelist(i) function to create instruction lists void merge(TFList * l1, TFList * l2); // - merge(p1,p2) function to concatenate lists void backpatch(TFList * l, int label); // - backpatch(p,i) function to fill in jump targets extern Instruction * begin; extern Instruction * current; int temp_count = 0; int label_count = 0; bool code_gen = true; TNodeOrConst * tn_or_const(Discriminant , void * ); void emit_binary_op(Op op, TableNode * result, TNodeOrConst * arg1, TNodeOrConst * arg2); void emit_unary_op(Op op, TableNode * result, TNodeOrConst * arg); void emit_assignment(TableNode * target, TNodeOrConst * source); void emit_as_file(FILE * out_file, Instruction * instr_arr); void emit_label(int label); void emit_jump(int label); void emit_conditional_jump(Op condition, int label, ...); void emit_function_start(int name); void emit_parameter(TNodeOrConst * param); void emit_function_call(TableNode * result, int param_count, TNodeOrConst * name); void emit_return(TNodeOrConst * value); void emit_reserve(TableNode * result, TNodeOrConst * size); void emit_release(TableNode * pointer); void emit_field_access(char* result, char* record, char* field); void emit_array_access(Op op, TableNode * result, TNodeOrConst * array, TNodeOrConst * index); void emit_bounds_check(TNodeOrConst * index, TNodeOrConst * arr, int error_label); // * Implement instruction array storage for backpatching /* Track 2: Control Flow & Boolean Expressions * Implement backpatching infrastructure: * Create truelist and falselist attributes for Boolean expressions * Create control flow emission functions: * Add Bison actions for control structures: - if-then-else with backpatching - while loops with backpatching * Implement short-circuit Boolean operations (&&, ||, !) * Add marker (M) nonterminal for recording instruction positions */ /* Track 3: Functions & Complex Types * Implement function-related emission: * Add Bison actions for the 'as' clause * Create memory layout calculation functions: - calculate_record_size(Record_Type* type) → returns bytes needed - calculate_array_size(Array_Type* type, int dimensions[]) → returns total bytes - calculate_field_offset(Record_Type* type, char* field_name) → returns offset * Add Bison actions for arrays and records */ /* Track 4: Memory Access & Integration * Implement array and record access code: - emit_field_access(char* result, char* record, char* field) - emit_array_access(char* result, char* array, char* index, char* dimension) * Add array dimension access (a._1, a._2, etc.) * Implement bounds checking emission: - emit_bounds_check(char* index, char* size, char* error_label) * Create the code generation driver function * Implement common error handling * Document the complete intermediate instruction set * Build integration test suite covering all language features * Implement row-major/column-major array layout calculation */