124 lines
3.6 KiB
C
124 lines
3.6 KiB
C
/* Intermediate Code */
|
|
/* The Translators - Spring 2025 */
|
|
|
|
#pragma once
|
|
|
|
#include <stdarg.h>
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "symbol_table.h"
|
|
|
|
// 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;
|
|
|
|
TNodeOrConst* getOperand1(Instruction* i);
|
|
TNodeOrConst* getOperand2(Instruction* i);
|
|
TableNode* getResult(Instruction* i);
|
|
Op getOp(Instruction* i);
|
|
int getLabel(Instruction* i);
|
|
int get_index(Instruction* i);
|
|
void set_label(Instruction* i, int label);
|
|
bool isConst(TNodeOrConst* tnc);
|
|
TNodeOrConst* tn_or_const(Discriminant d, void* tnc);
|
|
static void emit_helper(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);
|
|
char* get_string(TNodeOrConst* tc);
|
|
void emit_as_file(FILE* out_file, Instruction* i);
|
|
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_deref_right();
|
|
void emit_deref_left();
|
|
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);
|
|
char* label_gen();
|
|
TableNode* getTN(TNodeOrConst* tnc);
|
|
int getConst(TNodeOrConst* tnc);
|
|
|
|
extern int label_count;
|
|
extern Instruction* begin;
|
|
extern Instruction* current;
|
|
|
|
extern int offset;
|
|
extern int currentsp;
|
|
extern CGNode* cgList; |