Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 97 additions & 2 deletions backend/irgen.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ static unsigned l;
/* Returns a corresponding C type for a given MP_<token> or TT_<token> */
static const char *getCType (unsigned tt) {
switch (tt) {
case UNDEFINED: return "void";
case TT_INTEGER: return "int";
case MP_INTEGER: return "int";
case TT_REAL: return "double";
Expand Down Expand Up @@ -67,6 +68,26 @@ static const char *invOp (unsigned operator) {
exit(EXIT_FAILURE);
}

/* Writes a comma delimited list of C-type datatypes to given FILE */
static void writeDataList (FILE *fp, dataListType dataList, unsigned onlyId) {
for (int i = 0; i < dataList.length; i++) {
dataType *dt = dataList.list[i];
const char *p = (dt->tc == TC_VECTOR) ? "[]" : "";
if (onlyId) {
if (dt->id == NIL) {
fprintf(fp, "t%u", dt->tn);
} else {
fprintf(fp, "%s", identifierAtIndex(dt->id));
}
} else {
fprintf(fp, "%s %s%s", getCType(dt->tt), identifierAtIndex(dt->id), p);
}
if (i < dataList.length - 1) {
fprintf(fp, ", ");
}
}
}

/*
***************************************************************************
* Expression Generation Routines
Expand All @@ -84,8 +105,12 @@ unsigned genConst (unsigned tt, double n) {
}

/* Generates a T-Label for given identifier. Returns T-Label num */
unsigned genId (unsigned tt, const char *identifier) {
fprintf(irfp, "%s t%u = %s;\n", getCType(tt), t, identifier);
unsigned genId (unsigned tc, unsigned tt, const char *identifier) {
if (tc == TC_SCALAR) {
fprintf(irfp, "%s t%u = %s;\n", getCType(tt), t, identifier);
} else {
fprintf(irfp, "%s *t%u = %s;\n", getCType(tt), t, identifier);
}
return t++;
}

Expand Down Expand Up @@ -115,6 +140,39 @@ unsigned genBoolOp (unsigned tx, unsigned ty) {
return t++;
}

/* Generates a T-Label for a function invocation. Returns T-Label num. */
unsigned genFuncCall (unsigned tt, const char *name, dataListType args) {

// Generate call head.
fprintf(irfp, "%s t%u = %s", getCType(tt), t, name);

// Generate args.
putc('(', irfp);
writeDataList(irfp, args, 1);
putc(')', irfp);

// Generate call end.
fprintf(irfp, ";\n");

return t++;
}

/* Generates a T-Label for a procedure invocation. No label returned. */
void genProcCall (const char *name, dataListType args) {

// Generate call head.
fprintf(irfp, "%s", name);

// Generate args.
putc('(', irfp);
writeDataList(irfp, args, 1);
putc(')', irfp);

// Generate call end.
fprintf(irfp, ";\n");
}


/*
***************************************************************************
* Assignment Generation Routines
Expand Down Expand Up @@ -187,6 +245,33 @@ void genVectorDec (unsigned tt, unsigned n, const char *identifier) {
fprintf(irfp, "%s %s[%d];\n", getCType(tt), identifier, n);
}

/*
***************************************************************************
* Routine Generation Routines
***************************************************************************
*/

/* Generates a routine declaration */
void genRoutineDec (unsigned tt, const char *name, dataListType args) {

// Install return type and name.
fprintf(irfp, "%s %s", getCType(tt), name);

// Install arguments */
putc('(', irfp);
writeDataList(irfp, args, 0);
putc(')', irfp);
}

/* Generates a routine return statement */
void genReturn (unsigned tt, unsigned id) {
if (tt == UNDEFINED) {
fprintf(irfp, "return;\n");
} else {
fprintf(irfp, "return %s;\n", identifierAtIndex(id));
}
}

/*
***************************************************************************
* Structural Generation Routines
Expand All @@ -203,6 +288,16 @@ void genMainEnd () {
fprintf(irfp, "return 0;\n}\n");
}

/* Generates the opening of a block (newline + Opening brace + newline) */
void genBlockStart() {
fprintf(irfp, "\n{\n");
}

/* Generates the end of a block (newline + Closing brace + newline) */
void genBlockEnd() {
fprintf(irfp, "}\n");
}

/*
***************************************************************************
* Library Procedure Generation Routines
Expand Down
26 changes: 25 additions & 1 deletion backend/irgen.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ extern FILE *irfp;
unsigned genConst (unsigned tt, double n);

/* Generates a T-Label for given identifier. Returns T-Label num */
unsigned genId (unsigned tt, const char *identifier);
unsigned genId (unsigned tc, unsigned tt, const char *identifier);

/* Generates a T-Label for an T-indexed vector. Returns T-Label num. */
unsigned genVecIdx (unsigned tt, const char *identifier, unsigned ti, unsigned vb);
Expand All @@ -47,6 +47,12 @@ unsigned genArithOp (unsigned tt, unsigned operator, unsigned tx, unsigned ty);
/* Generates a T-Label for a boolean operation (tx - ty). Returns T-Label num. */
unsigned genBoolOp (unsigned tx, unsigned ty);

/* Generates a T-Label for a function invocation. Returns T-Label num. */
unsigned genFuncCall (unsigned tt, const char *name, dataListType args);

/* Generates a T-Label for a procedure invocation. No label returned. */
void genProcCall (const char *name, dataListType args);

/*
***************************************************************************
* Assignment Generation Prototypes
Expand Down Expand Up @@ -95,6 +101,18 @@ void genScalarDec (unsigned tt, const char *identifier);
/* Generates a vector decalaration. */
void genVectorDec (unsigned tt, unsigned n, const char *identifier);

/*
***************************************************************************
* Routine Generation Prototypes
***************************************************************************
*/

/* Generates a routine declaration */
void genRoutineDec (unsigned tt, const char *name, dataListType args);

/* Generates a routine return statement */
void genReturn (unsigned tt, unsigned id);

/*
***************************************************************************
* Structural Generation Prototypes
Expand All @@ -107,6 +125,12 @@ void genMainHeader ();
/* Generates the return statement and closing brace for main */
void genMainEnd ();

/* Generates the opening of a block (Opening brace + newline) */
void genBlockStart();

/* Generates the end of a block (Closing brace + newline) */
void genBlockEnd();

/*
***************************************************************************
* Library Procedure Generation Prototypes
Expand Down
120 changes: 102 additions & 18 deletions backend/mpascal.y
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,10 @@ int yyerror(char *s) {
}

// Nonterminal return type rules.
%type <num> standardType sign identifier
%type <desc> type
%type <num> standardType sign identifier
%type <desc> type subprogramHead
%type <data> variable expression factor term simpleExpression
%type <dataList> declarations identifierList expressionList
%type <dataList> declarations identifierList expressionList parameterList arguments

// Starting Grammar Rule.
%start program
Expand Down Expand Up @@ -205,20 +205,93 @@ subprogramDeclarations : subprogramDeclarations subprogramDeclaration MP_SCOLON
|
;

subprogramDeclaration : subprogramHead declarations
compoundStatement
subprogramDeclaration : subprogramHead { /* Generate the opening brace after the header */
genBlockStart();
}
declarations {
/* If the routine is a function, install a local scalar declaration to return */
if ($1.tc != UNDEFINED) {
installIdEntry($1.tt, TC_SCALAR, $1.tc, 0, 0);
genScalarDec($1.tc, identifierAtIndex($1.tt));
}

/* Install all remaining local variable declarations. */
for (int i = 0; i < $3.length; i++) {
dataType *d = $3.list[i];

/* Install each entry into the symbol table */
installIdEntry(d->id, d->tc, d->tt, d->vb, d->vl);

/* Generate an appropriate declaration (Vector | Scalar) */
if (d->tc == TC_VECTOR) {
genVectorDec(d->tt, d->vl, identifierAtIndex(d->id));
} else {
genScalarDec(d->tt, identifierAtIndex(d->id));
}
}

/* Clean up allocated memory */
freeDataList($3);
}
compoundStatement { /* Generate the return statement, close the block, and decrement table scope */
genReturn($1.tc, $1.tt); genBlockEnd(); decrementTableScope();
}
;

subprogramHead : MP_FUNCTION identifier arguments MP_COLON standardType MP_SCOLON
| MP_PROCEDURE identifier arguments MP_SCOLON
subprogramHead : MP_FUNCTION identifier arguments MP_COLON standardType MP_SCOLON { /* Install function header */
genRoutineDec($5, identifierAtIndex($2), $3);

/* Install entry: Vector-Count (vc) stores arg count */
installIdEntry($2, TC_ROUTINE, $5, 0, $3.length);

/* Increment table scope before installing arguments */
incrementTableScope();

/* Install arguments */
for (int i = 0; i < $3.length; i++) {
dataType *d = $3.list[i];

/* Install each entry into the symbol table */
installIdEntry(d->id, d->tc, d->tt, d->vb, d->vl);
}

/* Free allocated memory */
freeDataList($3);

/* Custom DescType (.tc = Return Token-Type, .tt = Routine Name) */
$$ = (descType){.tc = $5, .tt = $2, .vb = 0, .vl = 0};
}
| MP_PROCEDURE identifier arguments MP_SCOLON { /* Install void function header */
genRoutineDec(UNDEFINED, identifierAtIndex($2), $3);

/* Install entry: Vector-Count (vc) stores arg count */
installIdEntry($2, TC_ROUTINE, UNDEFINED, 0, $3.length);

/* Increment table scope before installing arguments */
incrementTableScope();

/* Install arguments */
for (int i = 0; i < $3.length; i++) {
dataType *d = $3.list[i];

/* Install each entry into the symbol table */
installIdEntry(d->id, d->tc, d->tt, d->vb, d->vl);
}

/* Free allocated memory */
freeDataList($3);

/* Custom DescType (.tc = Return Token-Type, .tt = Routine Name) */
$$ = (descType){.tc = UNDEFINED, .tt = $2, .vb = 0, .vl = 0};
}
;

arguments : MP_POPEN parameterList MP_PCLOSE
|
arguments : MP_POPEN parameterList MP_PCLOSE { $$ = $2; }
| { $$ = initDataListType(); }
;

parameterList : identifierList MP_COLON type
| parameterList MP_SCOLON identifierList MP_COLON type
parameterList : identifierList MP_COLON type { $$ = mapDescToDataList($3, $1); }
| parameterList MP_SCOLON identifierList MP_COLON type { $$ = appendDataList(mapDescToDataList($5, $3), $1); }
;

compoundStatement : MP_BEGIN optionalStatements MP_END
Expand Down Expand Up @@ -261,10 +334,15 @@ variable : identifier { /* Initializ
}

procedureStatement : identifier
| identifier MP_POPEN expressionList MP_PCLOSE { /* Procedure calls are disabled */
| identifier MP_POPEN expressionList MP_PCLOSE { /* Procedure call */

/* Extract routine IdEntry */

/* Generate routine call */
genProcCall(identifierAtIndex($1), $3);

/* Free allocated memory */
freeDataList($3);
fprintf(stderr, "Error: Procedure calls are not available!\n");
exit(EXIT_FAILURE);
}
| MP_READLN MP_POPEN expressionList MP_PCLOSE { /* Generate corresponding readln function in C. */
genReadLn($3);
Expand Down Expand Up @@ -310,12 +388,18 @@ term : factor { $$ = $1; }
factor : identifier {
/* Extracting Entry and populating dataType fields. */
IdEntry *entry = containsIdEntry($1, TC_ANY, SYMTAB_SCOPE_ALL);
$$ = initExprVarDataType(genId(entry->tt, identifierAtIndex($1)), entry->tc, entry->tt, $1);
$$ = initExprVarDataType(genId(entry->tc, entry->tt, identifierAtIndex($1)), entry->tc, entry->tt, $1);
}
| identifier MP_POPEN expressionList MP_PCLOSE { /* This is currently disabled */
| identifier MP_POPEN expressionList MP_PCLOSE { /* Function call */

/* Extract routine IdEntry */
IdEntry *entry = containsIdEntry($1, TC_ROUTINE, SYMTAB_SCOPE_ALL);

/* Generate routine call */
$$ = initExprConstDataType(genFuncCall(entry->tt, identifierAtIndex($1), $3), entry->tt);

/* Free allocated memory */
freeDataList($3);
fprintf(stderr, "Error: Function calls are not available!\n");
exit(EXIT_FAILURE);
}
| identifier MP_BOPEN expression MP_BCLOSE {
/* Extracting Entry. Generating indexed variable code */
Expand Down
Loading