Skip to content

Commit

Permalink
add types to returning values.
Browse files Browse the repository at this point in the history
  • Loading branch information
kjs committed Jun 13, 2012
1 parent 4cc3ea0 commit 1534c85
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 43 deletions.
1 change: 1 addition & 0 deletions src/ast.h
Expand Up @@ -70,6 +70,7 @@ typedef struct m1_assignment {
typedef struct m1_funcall {
char *name;
struct m1_expression *arguments;
struct m1_decl *typedecl;

} m1_funcall;

Expand Down
2 changes: 2 additions & 0 deletions src/compiler.h
Expand Up @@ -43,6 +43,8 @@ typedef struct M1_compiler {

struct m1_symboltable *currentsymtab;

struct m1_symboltable *globalsymtab;

int enum_const_counter; /* for parsing enums that don't specify values. */

char registers[REG_TYPE_NUM][REG_NUM];
Expand Down
63 changes: 32 additions & 31 deletions src/gencode.c
Expand Up @@ -41,6 +41,11 @@ This happens in gencode_number().
#define debug(x)
#endif

/* See PDD32 for these constants. */
#define M0_REG_I0 12
#define M0_REG_N0 73
#define M0_REG_S0 134
#define M0_REG_P0 195

static void gencode_expr(M1_compiler *comp, m1_expression *e);
static void gencode_block(M1_compiler *comp, m1_block *block);
Expand Down Expand Up @@ -745,25 +750,32 @@ gencode_return(M1_compiler *comp, m1_expression *e) {
m1_reg retpc_reg = use_reg(comp, VAL_INT);
m1_reg retpc_index = use_reg(comp, VAL_INT);

fprintf(OUT, "\tset_imm I%d, 0, RETPC\n", retpc_index.no);
fprintf(OUT, "\tderef I%d, PCF, I%d\n", retpc_reg.no, retpc_index.no);

unuse_reg(comp, retpc_index);

if (e != NULL) {
/* returning a value:
<code for expr> # result is stored in RY.
set_imm IX, 0, R0 # get the number of index R0 and store in IX
set_ref CF, IX, RY # store value in RY in CF[IX].
*/
gencode_expr(comp, e);
m1_reg r = popreg(comp->regstack);
m1_reg indexreg = use_reg(comp, VAL_INT);
/* load the number of register I0 */
fprintf(OUT, "\tset_imm\tI%d, 0, I0\n", indexreg.no);
/* index the current callframe, and set in its I0 register the value from the return expression. */
fprintf(OUT, "\tset_ref\tCF, I%d, I%d\n", indexreg.no, r.no);
fprintf(OUT, "\tset_ref\tCF, I%d, %c%d\n", indexreg.no, reg_chars[(int)r.type], r.no);
pushreg(comp->regstack, r);

}

chunk_index = use_reg(comp, VAL_INT);

fprintf(OUT, "\tset_imm I%d, 0, RETPC\n", retpc_index.no);
fprintf(OUT, "\tderef I%d, PCF, I%d\n", retpc_reg.no, retpc_index.no);
fprintf(OUT, "\tset_imm I%d, 0, CHUNK\n", chunk_index.no);
fprintf(OUT, "\tderef I%d, PCF, I%d\n", chunk_index.no, chunk_index.no);
fprintf(OUT, "\tgoto_chunk I%d, I%d, x\n", chunk_index.no, retpc_reg.no);
Expand Down Expand Up @@ -1426,16 +1438,15 @@ static void
gencode_funcall(M1_compiler *comp, m1_funcall *f) {
m1_symbol *fun;
fun = sym_find_chunk(&comp->currentchunk->constants, f->name);
m1_reg pc_reg, cont_offset, return_reg;
m1_reg pc_reg,
cont_offset;

if (fun == NULL) { // XXX need to check in semcheck
fprintf(stderr, "Cant find function '%s'\n", f->name);
++comp->errors;
return;
}



m1_reg cf_reg = use_reg(comp, VAL_CHUNK);
m1_reg sizereg = use_reg(comp, VAL_INT);
m1_reg flagsreg = use_reg(comp, VAL_INT);
Expand All @@ -1454,10 +1465,6 @@ gencode_funcall(M1_compiler *comp, m1_funcall *f) {

m1_expression *argiter = f->arguments;

#define M0_REG_I0 12
#define M0_REG_N0 73
#define M0_REG_S0 134
#define M0_REG_P0 195

int regindexes[4] = { M0_REG_I0,
M0_REG_N0,
Expand Down Expand Up @@ -1561,19 +1568,6 @@ gencode_funcall(M1_compiler *comp, m1_funcall *f) {
m1_reg I0 = use_reg(comp, VAL_INT);
fprintf(OUT, "\tset_imm I%d, 0, 0\n", I0.no);
fprintf(OUT, "\tgoto_chunk P%d, I%d, x\n", cf_reg.no, I0.no);


/* XXX: This just makes comp->regstack->sp won't be 0, which makes m1 happy */

/*
return_reg.no = 60;
return_reg.type = VAL_INT;
m1_reg idxreg = use_reg(comp, VAL_INT);
// fprintf(OUT, "\tset\tI%d, I60, x\n", idxreg.no);
fprintf(OUT, "\tderef\tI%d, CF, 72\n", idxreg.no);
pushreg(comp->regstack, idxreg);
*/
unuse_reg(comp, I0);


Expand Down Expand Up @@ -1645,17 +1639,24 @@ gencode_funcall(M1_compiler *comp, m1_funcall *f) {
*/
fprintf(OUT, "\tset CF, PCF, x\n");

return_reg.no = 60;
return_reg.type = VAL_INT;

/* generate code to get the return value. */
/*
set_imm IX, 0, R0 # get the number of register R0 into IX
deref RY, PZ, IX # index the callee's CF with that index, and store result in RY
*/
/* retrieve the return value. */
m1_reg idxreg = use_reg(comp, VAL_INT);
m1_reg idxreg = use_reg(comp, f->typedecl->valtype);
/* load the number of register I0. */
fprintf(OUT, "\tset_imm\tI%d, 0, I0\n", idxreg.no);
/* index the callee's frame (Px) with the index _of_ register I0. That's where the callee
left any return value.
fprintf(OUT, "\tset_imm\tI%d, 0, %c0\n", idxreg.no, reg_chars[(int)idxreg.type]);

/* index the callee's frame (Px) with the index _of_ register X0.
That's where the callee left any return value.
*/
fprintf(OUT, "\tderef\tI%d, P%d, I%d\n", idxreg.no, cf_reg.no, idxreg.no);
fprintf(OUT, "\tderef\t%c%d, P%d, I%d\n", reg_chars[(int)idxreg.type], idxreg.no,
cf_reg.no, idxreg.no);

/* make it available for use by another statement. */
pushreg(comp->regstack, idxreg);

Expand Down Expand Up @@ -2013,7 +2014,7 @@ gencode_consts(m1_symboltable *consttable) {
fprintf(OUT, "%d &%s\n", iter->constindex, iter->value.sval);
break;
default:
fprintf(stderr, "unknown symbol type");
fprintf(stderr, "unknown symbol type (%d)\n", iter->valtype);
assert(0); /* should never happen. */
}
iter = iter->next;
Expand Down
6 changes: 6 additions & 0 deletions src/m1.y
Expand Up @@ -480,7 +480,9 @@ function_definition : function_init '(' parameters ')' open_block statements '}'
{
M1_compiler *comp = (M1_compiler *)yyget_extra(yyscanner);
$1->block = $5->expr.blck;
/* store the list of statements ($6) in the block ($5). */
block_set_stat($5, $6);

$$ = $1;
$$->parameters = $3;

Expand Down Expand Up @@ -508,8 +510,12 @@ function_init : return_type TK_IDENT
M1_compiler *comp = (M1_compiler *)yyget_extra(yyscanner);
$$ = chunk(comp, $1, $2);
comp->currentchunk = $$;

/* enter name of function declaration in table */
sym_enter_chunk(comp, &comp->currentchunk->constants, $2);

/* enter name of function in global symbol table. */
sym_new_symbol(comp, comp->globalsymtab, $2, $1, 1);
}
;

Expand Down
1 change: 1 addition & 0 deletions src/main.c
Expand Up @@ -38,6 +38,7 @@ init_compiler(M1_compiler *comp) {
type_enter_type(comp, "string", DECL_STRING, 4); /* strings are pointers, so size is 4. */
type_enter_type(comp, "char", DECL_CHAR, 4); /* XXX can this be 1? what about padding in structs? */

comp->globalsymtab = new_symtab();
}

int
Expand Down
15 changes: 15 additions & 0 deletions src/semcheck.c
Expand Up @@ -389,6 +389,21 @@ check_funcall(M1_compiler *comp, m1_funcall *f, unsigned line) {
/* check arguments of the function call; this is a list of m1_expressions. */
check_exprlist(comp, f->arguments);

m1_symbol *funsym = sym_lookup_symbol(comp->globalsymtab, f->name);
if (funsym == NULL) {
type_error_extra(comp, line, "function '%s' not defined\n", f->name);
return NULL;
}
/* set the function's return type declaration as stored in the symbol. */
if (funsym->typedecl == NULL) {
/* type wasn't declared yet at time that function was defined. */
f->typedecl = type_find_def(comp, funsym->type_name);
}
else {
assert(funsym->typedecl != NULL);
f->typedecl = funsym->typedecl;
}

/* find declaration of function, check arguments against function signature. */
/* TODO */
return rettype;
Expand Down
6 changes: 3 additions & 3 deletions src/symtab.c
Expand Up @@ -65,7 +65,7 @@ sym_new_symbol(M1_compiler *comp, m1_symboltable *table, char *varname, char *ty
m1_symbol *sym = NULL;

assert(varname != NULL);
assert(type != NULL);
//assert(type != NULL);
assert(table != NULL);

/* check whether symbol exists already. */
Expand All @@ -89,8 +89,8 @@ sym_new_symbol(M1_compiler *comp, m1_symboltable *table, char *varname, char *ty
sym->name = varname; /* name of this symbol */
sym->regno = NO_REG_ALLOCATED_YET; /* need to allocate a register later. */
sym->next = NULL; /* symbols are stored in a list */

sym->type_name = type;

link_sym(table, sym);

return sym;
Expand Down
1 change: 1 addition & 0 deletions src/symtab.h
Expand Up @@ -60,6 +60,7 @@ typedef union m1_value {
*/
typedef struct m1_symbol {
char *name; /* name of this symbol */
char *type_name; /* name of type. */
m1_value value; /* for const declarations. */
m1_valuetype valtype; /* selector of value union. */

Expand Down
13 changes: 4 additions & 9 deletions t/return.m1
@@ -1,19 +1,14 @@
int main() {
print("1..1\n");
int i = 2;
i = foo(i);
// string ok = getok();
// print(ok);
print("ok "); // can't return strings yet, only ints at this moment.
int i; // = 1; // this doesn't work yet.
string ok = getok();
print(ok);
i = 1;
print(i);
print("\n");
}


int foo(int j) {
return j - 1;
}

string getok() {
string s = "ok ";
return s;
Expand Down

0 comments on commit 1534c85

Please sign in to comment.