Skip to content

Commit

Permalink
asm (a5): generate data segment, and divide quads
Browse files Browse the repository at this point in the history
  • Loading branch information
SantriptaSharma committed Dec 6, 2023
1 parent 4ec5429 commit 933c6b5
Show file tree
Hide file tree
Showing 6 changed files with 355 additions and 24 deletions.
8 changes: 4 additions & 4 deletions 15_A5.y
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,9 @@ postfix_expression:

enum KIND_T kind = $1.sym->type.kind == ARRAY_PTR ? PRIMITIVE_PTR : PRIMITIVE_T;
$$ = PURE_EXPR(SymInit(kind));
size_t len = strlen($1.sym->name) + 15;
size_t len = strlen($1.sym->name) + 18;
char *name = malloc(len);
sprintf(name, "%s__[%d]", $1.sym->name, current_table->temp_count++);
sprintf(name, "%s__ind_%d_", $1.sym->name, current_table->temp_count++);
$$.sym->name = name;
$$.sym->type = $1.sym->type.kind == PRIMITIVE_PTR ? prim2type($1.sym->type.primitive) : prim2type($1.sym->type.array.base);
$$.sym->size = GetSize($$.sym->type);
Expand Down Expand Up @@ -244,9 +244,9 @@ unary_expression:
}

enum KIND_T kind = $2.sym->type.kind == ARRAY_PTR ? ARRAY_T : PRIMITIVE_T;
size_t len = strlen($2.sym->name) + 4;
size_t len = strlen($2.sym->name) + 8;
char *name = malloc(len);
sprintf(name, "*__%s", $2.sym->name);
sprintf(name, "deref__%s", $2.sym->name);

$$ = PURE_EXPR(SymInit(kind));

Expand Down
35 changes: 18 additions & 17 deletions 15_A5_translator.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ extern int yyparse();
extern void yyerror(char *s);

const unsigned int size_of_char = 1;
const unsigned int size_of_int = 4;
const unsigned int size_of_pointer = 4;
const unsigned int size_of_int = sizeof (int);
const unsigned int size_of_pointer = sizeof(void *);

int label_count = 0;

Expand Down Expand Up @@ -633,21 +633,21 @@ Symbol *GenTemp()

sym->name = strdup(name);
sym->type = (Type) {
.kind = PRIMITIVE_T,
.primitive = INT_T
.kind = PRIMITIVE_PTR,
.primitive = VOID_T
};
sym->initial_value = 0;
sym->size = size_of_int;
sym->size = size_of_pointer;
sym->offset = 0;
sym->inner_table = NULL;
sym->next = NULL;

SymInsert(sym);
}

sym->type.kind = PRIMITIVE_T;
sym->type.kind = PRIMITIVE_PTR;
sym->is_temp = 1;
sym->type.primitive = INT_T;
sym->type.primitive = VOID_T;

sym->size = GetSize(sym->type);

Expand Down Expand Up @@ -760,6 +760,7 @@ int main(int argc, const char *argv[]) {
sprintf(asm_filename, "%s.asm", argv[1]);

FILE *quads_file = fopen(out_filename, "w");
free(out_filename);
if (quads_file == NULL) {
printf("Could not open output file %s\n", out_filename);
FreeTables();
Expand Down Expand Up @@ -797,27 +798,27 @@ int main(int argc, const char *argv[]) {
FILE *file = fopen(asm_filename, "w");
if (file == NULL) {
printf("Could not open output file %s\n", asm_filename);
free(asm_filename);
FreeTables();
FreeQuads();
DestroyLists();
return 1;
}
free(asm_filename);

if (!WriteDataSeg(file)) {
printf("Could not write data segment, aborting\n");
fclose(file);
FreeTables();
FreeQuads();
DestroyLists();
return 1;
}
WriteDataSeg(file);

// generate entry point, emit all global instructions
fprintf(file, ".text\n");
fprintf(file, ".global main\n");

WriteEntryPoint(file);

// TODO: generate asm from quads

// TODO: write asm to file

free(out_filename);
free(asm_filename);
fclose(file);
FreeTables();
FreeQuads();
DestroyLists();
Expand Down
14 changes: 13 additions & 1 deletion A4_tests/testsimple.nc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,19 @@ char d = +'c';
char f = -'f';
void *thing = &GLOB;

void printf(char *c, int argv);
void printf(char *c, int argv) {
int j;
j = 5;
}

int a = 5 + 3 + "garbo king";
int *e = a + 5;
int *make_fib_list(int a, int b, int n);
int b = 110 + 'c' + "garbo king" + a;
void garbo();
char c = (e[10] + 12) * 32 - 3 * 4 * "okiii";
void garbo();


int main(int argc, char *argv) {
int i;
Expand Down
164 changes: 163 additions & 1 deletion compiler.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,169 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include "compiler.h"

char WriteDataSegment(FILE *file) {
const char *CONST_DIRECTIVES[] = {
[1] = ".byte",
[2] = ".short",
[4] = ".long",
[8] = ".quad"
};

static void WriteConstSym(Symbol *sym, FILE *file) {
static int strings_count = 0;

if (!sym->is_temp && sym->type.kind != ARRAY_T) {
fprintf(file, ".global %s\n", sym->name);
}

switch (sym->type.kind) {
case PRIMITIVE_T:
case PRIMITIVE_PTR:
fprintf(file, "%s:\n\t%s %d\n", sym->name, CONST_DIRECTIVES[sym->size], sym->initial_value);
break;

case ARRAY_T:
if (sym->type.array.base == CHAR_T) {
size_t it = 0;
const char *pref = "__str_";

while (sym->name[it] == pref[it]) {
it++;
}

if (pref[it] == '\0') {
sym->initial_value = strings_count++;
fprintf(file, "_user_string_%d:\n\t.string \"%s\"\n", sym->initial_value, sym->name + it);
} else {
fprintf(file, ".global %s\n", sym->name);
fprintf(file, "%s:\n\t.zero %d\n", sym->name, sym->size);
}
} else {
fprintf(file, ".global %s\n", sym->name);
fprintf(file, "%s:\n\t.zero %d\n", sym->name, sym->size);
}
break;

case ARRAY_PTR:
fprintf(file, "%s:\n\t.zero %d\n", sym->name, sym->size);
break;
}
}

void WriteDataSeg(FILE *file) {
fprintf(file, ".data\n");

Symbol *sym = glb_table.sym_head;

while (sym != NULL) {
if (sym->type.kind != FUNC_T) {
WriteConstSym(sym, file);
} else {
if (strcmp(sym->name, "main") == 0) {
char *main_label = malloc(strlen(sym->name) + 2);
sprintf(main_label, "_main", sym->name);
free((void *)sym->name);
sym->name = main_label;
}
fprintf(file, ".global %s\n", sym->name);
}
sym = sym->next;
}
}

static struct QuadRange {
int start, end;
} ext_quad_blocks[512], func_quad_blocks[512];

static int ext_count = 0, func_count = 0;

static void FindQuadExtents() {
int next = 0;

// the start position of the last external quad block
int start = 0;

int i = 0;

while (i < quads_size) {
Quad q = quads[i];

if (q.opcode == FN_LABEL && q.rd.kind == SYMBOL_A) {
if (i != start) {
ext_quad_blocks[next].start = start;
ext_quad_blocks[next].end = i - 1;
next++;
}

// find last return statement in the function, scan until eof or next function label
int lastret = i;
int j;
for (j = i + 1; j < quads_size; j++) {
Quad q2 = quads[j];

if (q2.opcode == FN_LABEL && q2.rd.kind == SYMBOL_A) {
break;
}

if (q2.opcode == RET) {
lastret = j;
}
}

if (j == quads_size && lastret == i) lastret = quads_size - 1;

func_quad_blocks[func_count].start = i;
func_quad_blocks[func_count].end = lastret;
func_count++;

i = lastret;
start = i + 1;
}

i++;
}

if (i != start) {
ext_quad_blocks[next].start = start;
ext_quad_blocks[next].end = i - 1;
next++;
}

ext_count = next;
}

static void TranslateQuad(Quad q, FILE *file, SymbolTable *tab) {

}

void WriteEntryPoint(FILE *file) {
FindQuadExtents();

for (int i = 0; i < ext_count; i++) {
printf("External quad block %d: %d - %d\n", i, ext_quad_blocks[i].start, ext_quad_blocks[i].end);
}

for (int i = 0; i < func_count; i++) {
printf("Function quad block %s: %d - %d\n", quads[func_quad_blocks[i].start].rd.sym->name, func_quad_blocks[i].start, func_quad_blocks[i].end);
}

// write the entry point
fprintf(file, ".text\n");
fprintf(file, ".global main\n");
fprintf(file, "main:\n");
// first, write the external quad blocks
for (int i = 0; i < ext_count; i++) {
for (int j = ext_quad_blocks[i].start; j <= ext_quad_blocks[i].end; j++) {
fprintf(file, "\t");
TranslateQuad(quads[j], file, &glb_table);
fprintf(file, "\n");
}
}

fprintf(file, "\n");

// jump to nanoC file's entry point, main, now called _main
fprintf(file, "\tcall _main\n");
}
3 changes: 2 additions & 1 deletion compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define _COMPILER_H_
#include "15_A5_translator.h"

char WriteDataSegment(FILE *file);
void WriteDataSeg(FILE *file);
void WriteEntryPoint(FILE *file);

#endif
Loading

0 comments on commit 933c6b5

Please sign in to comment.