Skip to content

Commit

Permalink
complete (a4)
Browse files Browse the repository at this point in the history
  • Loading branch information
SantriptaSharma committed Nov 25, 2023
1 parent e7fd5d6 commit 98038a1
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 24 deletions.
8 changes: 7 additions & 1 deletion 15_A4.tex
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,13 @@ \section{Augmenting the Grammar}

\begin{itemize}
\item We first define our attributed grammar, specifying which attribute is associated with each terminal/non-terminal symbol. The list of attributes is available at the top of the bison file (in the union), with comments.
\item Next, we add
\item Next, we augment the grammar with some symbols, particularly, the marker and the guard symbol, both of which produce only epsilon, but have associated actions or attributes. A description of the action is available in the bison file alongside each rule.
\end{itemize}

\section{Setting up data structures}
We create the various compile-time data structures we require for translation, as well as functions for those structures. The declarations can be found in the header file, along with comments explaining their purpose (when not self-evident).

\section{Writing actions}
We write semantic actions for filling up our compile-time structures, and generating our translated TAC. One important note, is that in a few rules, we have used mid-rule actions, to either facilitate conversion of non-boolean expressions into boolean expressions (endowing them with true/false lists), used in the case of value-based conditionals, or in function definitions, to allow us to inspect/inherit attributes from sibling symbols in the parse tree.

\end{document}
37 changes: 17 additions & 20 deletions 15_A4.y
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,6 @@
void yyerror(char *s);
%}

/*
TODO: go through all rules, make sure no rules just logging remain
TODO: write everything up in assignment pdf
*/


%union {
// Attribute for all expressions, contains pointers to a symbol, and optional pointers to true/false lists (non-null for bool exprs)
ExprAttrib expr;
Expand All @@ -35,17 +29,22 @@ TODO: write everything up in assignment pdf
// A single argument, either a declaration (for params) or an expression (for call args)
ArgListElem arg;


// Attribute for an optional_expression, contains the expression attribute and a flag indicating whether it's present
struct _opt_expr {
ExprAttrib expr;
char has_expr;
} opt_expr;

// Attribute for type specifier (int, char, void) tokens, just an enum mapping to INT_T, CHAR_T, VOID_T
PRIMITIVE_TYPE type_spec;

// Attribute for statements & guards, contains a pointer to their dangling exit quad addresses
QuadList *next_list;

// Attribute for a marker, contains the number of quads emitted at the time of the marker's reduction
size_t quad_index;

// Attribute for constants
char *string;
int val;
}
Expand Down Expand Up @@ -114,11 +113,11 @@ TODO: write everything up in assignment pdf

%%
/* auxiliary symbols */
marker: { $$ = quads_size; }
guard: { $$ = MakeList(quads_size); Emit(Jump(AImm(0))); }
marker: { $$ = quads_size; } // just store the quad index of the next instruction on reduction
guard: { $$ = MakeList(quads_size); Emit(Jump(AImm(0))); } // emit an unconditional jump, and store a next list to be filled in by rules that use guards

/* expressions */
/* TODO: validate types and add implicit conversions, on every operation and assignment */
/* TODO: validate types and add implicit conversions, on every operation and assignment (wont do) */
constant:
INTCONST
| CHARCONST
Expand Down Expand Up @@ -158,7 +157,7 @@ postfix_expression:
Emit(IndexRead(ASym($$), ASym($1), ASym($3)));
}
| postfix_expression '(' argument_expression_list ')' {
// TODO: validate type of params
// TODO: validate type of params (wont do)
if ($1.sym->type.kind != FUNC_T) {
yyerror("can't call non-function type");
YYABORT;
Expand Down Expand Up @@ -217,8 +216,6 @@ argument_expression_list:
assignment_expression {$$ = MakeArgList(ARG_EXPR($1));}
| argument_expression_list ',' assignment_expression {InsertArg($1, ARG_EXPR($3)); $$ = $1;}

// TODO: write out relational actions using dummy keys

unary_expression:
postfix_expression
| '&' unary_expression {
Expand Down Expand Up @@ -529,15 +526,15 @@ declaration:
yyerror(err);
YYABORT;
} else if (existing != NULL) {
// TODO: validate signature against existing entry
// TODO: validate signature against existing entry (wont do)
SymFree($$.sym);
$$.sym = existing;
} else {
SymInsert($$.sym);
}


// TODO: verify types before emitting assignment
// TODO: verify types before emitting assignment (wont do)
if ($$.has_init == 1) {
Emit(Mov(ASym($$), ASym($$.init)));
}
Expand Down Expand Up @@ -735,12 +732,12 @@ jump_statement:

/* TLU */
translation_unit:
external_declaration {log("translation-unit")}
| translation_unit external_declaration {log("translation-unit")}
external_declaration
| translation_unit external_declaration

external_declaration:
function_definition {log("external-declaration")}
| declaration {log("external-declaration")}
function_definition
| declaration

function_definition:
type_specifier declarator {
Expand All @@ -765,7 +762,7 @@ function_definition:
Symbol *existing = SymLookup($2.sym->name, 0);

if (existing != NULL) {
// TODO: validate signature against existing entry
// TODO: validate signature against existing entry (wont do)
SymFree($2.sym);
$2.sym = existing;
} else {
Expand Down
2 changes: 0 additions & 2 deletions 15_A4_translator.c
Original file line number Diff line number Diff line change
Expand Up @@ -706,8 +706,6 @@ int main() {
InitQuads();
InitTables();

SymTableDispl(current_table);

yyparse();

SymTableDispl(current_table);
Expand Down
20 changes: 19 additions & 1 deletion 15_A4_translator.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ extern const unsigned int size_of_pointer;

struct _Symbol;

// Struct representing a single address in a 3-address code, either a symbol or an immediate
typedef struct _Addr {
enum ADDR_KIND {SYMBOL_A, IMMEDIATE} kind;
union {
Expand All @@ -21,31 +22,40 @@ typedef struct _QuadList {
struct _QuadList *next;
} QuadList;

// Keep track of all true/false/next lists we use so we can free them later (could technically be freed on backpatch but oh well)
extern int existing_lists_size, existing_lists_capacity;
extern QuadList **existing_lists;

void InitLists();
void AddList(QuadList *list);
void DestroyLists();

// Create a new list with a single element
QuadList *MakeList(int ind);
// Insert an element into a list
void Insert(QuadList* list, int ind);
// Merge two lists
QuadList *Merge(QuadList *list1, QuadList *list2);
// Fill out all jump quads in a list with the given destination
void Backpatch(QuadList *list, int dest);
// Free a single list
void FreeList(QuadList *list);

// Struct representing a single 3-address instruction
typedef struct {
enum OPCODE {ADD, SUB, MUL, DIV, MOD, MOV, POS, NEG, ADDR, DEREF, JMP, JIF, JNT,
JLT, JGT, JEQ, JNE, JLE, JGE, PAR, CAL, RET, INDR, INDW, PTRW, FN_LABEL} opcode;
Addr rs, rt, rd;
} Quad;

// Dynamic array of instructions
extern int quads_size, quads_capacity;
extern Quad *quads;

#define AImm(x) ((Addr){IMMEDIATE, .imm = x})
#define ASym(x) ((Addr){SYMBOL_A, .sym = x.sym})

// Emit a quad
void Emit(Quad q);

#define Mov(dest, source) ((Quad){MOV, source, AImm(0), dest})
Expand All @@ -69,6 +79,7 @@ void Emit(Quad q);
#define DerefWrite(dest, source) ((Quad){PTRW, dest, AImm(0), source})
#define FnLabel(label) ((Quad){FN_LABEL, AImm(0), AImm(0), label})

// Functions for printing a quad & the quads list
void DisplayQuad(Quad q);
void DisplayQuads();

Expand All @@ -83,15 +94,19 @@ typedef struct _SymbolTable {

extern SymbolTable glb_table, *current_table;

// Create a new symbol table
SymbolTable *Create_SymbolTable(const char *name, enum Scope scope, SymbolTable *parent);
// Free a symbol table
void Destroy_SymbolTable(SymbolTable *table);
// Print a symbol table
void SymTableDispl(SymbolTable *table);
typedef enum { INT_T, CHAR_T, VOID_T } PRIMITIVE_TYPE;

typedef enum { INT_T, CHAR_T, VOID_T } PRIMITIVE_TYPE;
#define prim2type(x) ((Type){.kind = PRIMITIVE_T, .primitive = x})

struct _ArgList;

// Struct representing a type, either a primitive or a pointer (with some extra specialisation)
typedef struct _Type {
// needs some kind of types table + hashing mechanism to reuse types, instead of always creating new ones (wont implement for now)
enum KIND_T {PRIMITIVE_PTR, ARRAY_PTR, PRIMITIVE_T, ARRAY_T, FUNC_T} kind;
Expand Down Expand Up @@ -135,6 +150,7 @@ void SymInsert(Symbol *sym);
void SymFree(Symbol *sym);
void SymDispl(Symbol *sym);

// Struct representing an expression, holds a pointer to a symbol, and optionally true/false lists for boolean expressions
typedef struct _ExprAttrib {
Symbol *sym;
QuadList *truelist, *falselist;
Expand All @@ -143,6 +159,7 @@ typedef struct _ExprAttrib {
#define PURE_EXPR(x) ((ExprAttrib){.sym = x, .truelist = NULL, .falselist = NULL})
#define BOOL_EXPR(x, tl, fl) ((ExprAttrib){.sym = x, .truelist = tl, .falselist = fl})

// Struct representing a single argument an arglist, can either be an expression (for calls) or a type name pair (for parameters in declarations)
typedef struct _ArgListElem {
enum {EXPR, DECL} kind;
union {
Expand All @@ -154,6 +171,7 @@ typedef struct _ArgListElem {
};
} ArgListElem;

// Struct representing a list of arguments, used for both calls & declarations
typedef struct _ArgList {
ArgListElem elem;
struct _ArgList *next;
Expand Down
Binary file modified tex_build/15_A4.pdf
Binary file not shown.

0 comments on commit 98038a1

Please sign in to comment.