move codegen to gen.c
This commit is contained in:
parent
948520f551
commit
358449077b
254
gen.c
254
gen.c
@ -300,21 +300,21 @@ void gen_declare_function(Gen*gen,PNode*pn,FILE*file)
|
||||
|
||||
case M_I386:
|
||||
pn->stacksize+=stacksize;
|
||||
stacksize+=gen_i386_stacksize(pn);
|
||||
stacksize+=gen_stacksize(pn);
|
||||
gen_prolog(gen,pn,file,stacksize);
|
||||
/* gen_i386_prolog(pn,file,stacksize); */
|
||||
for(size_t i=0;i<pn->pnodes.size;++i)
|
||||
gen_i386(gen,vec_at(&pn->pnodes,i,PNode*),file);
|
||||
gen_code(gen,vec_at(&pn->pnodes,i,PNode*),file);
|
||||
/* gen_i386_epilog(pn,file); */
|
||||
break;
|
||||
|
||||
case M_X86_64:
|
||||
pn->stacksize+=stacksize;
|
||||
stacksize+=gen_x86_64_stacksize(pn);
|
||||
stacksize+=gen_stacksize(pn);
|
||||
/* gen_x86_64_prolog(pn,file,stacksize); */
|
||||
gen_prolog(gen,pn,file,stacksize);
|
||||
for(size_t i=0;i<pn->pnodes.size;++i)
|
||||
gen_x86_64(gen,vec_at(&pn->pnodes,i,PNode*),file);
|
||||
gen_code(gen,vec_at(&pn->pnodes,i,PNode*),file);
|
||||
/* gen_x86_64_epilog(pn,file); */
|
||||
break;
|
||||
|
||||
@ -493,3 +493,249 @@ void gen_epilog(Gen*gen,const PNode*pn,FILE*file)
|
||||
fprintf(file,"\t%s %%%s\n",pop_wordsize[which],gen_bp());
|
||||
|
||||
}
|
||||
|
||||
size_t gen_stacksize(const PNode*pn)
|
||||
{
|
||||
size_t stacksize=0;
|
||||
|
||||
if(pn->pnodes.size==0)
|
||||
{
|
||||
if(pn->type==PVARDECL)
|
||||
return stacksize+sizeof(uint32_t);
|
||||
else return 0;
|
||||
}
|
||||
|
||||
for(size_t i=0;i<pn->pnodes.size;++i)
|
||||
stacksize+=gen_stacksize(vec_at(&pn->pnodes,i,PNode*));
|
||||
return stacksize;
|
||||
}
|
||||
|
||||
void gen_code(Gen*gen,PNode*pn,FILE*file)
|
||||
{
|
||||
|
||||
if(!pn)
|
||||
{
|
||||
err_log("passed NULL PNode to gen_code");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!file)
|
||||
{
|
||||
err_log("NULL FILE* passed to gen_code");
|
||||
return;
|
||||
}
|
||||
|
||||
if(gen->rootnode==pn)
|
||||
fprintf(file,".text\n");
|
||||
|
||||
switch(pn->type)
|
||||
{
|
||||
|
||||
case PFUNDECL:
|
||||
{
|
||||
bool found=false;
|
||||
gen_declare_function(gen,pn,file);
|
||||
found=gen_findret(pn,false);
|
||||
if(!found)
|
||||
err_log("%u: no return in function '%s'",vec_at(&pn->tokens,0,const Tok*)->line,
|
||||
vec_at(&pn->tokens,0,const Tok*)->str.buffer);
|
||||
}
|
||||
break;
|
||||
|
||||
case PVARDECL:
|
||||
gen_declare_variable(gen,pn,file);
|
||||
break;
|
||||
|
||||
case PRET:
|
||||
if(pn->tokens.size>0)
|
||||
{
|
||||
if(vec_at(&pn->tokens,0,const Tok*)->type==LOPERATOR&&vec_at(&pn->tokens,0,const Tok*)->subtype==LSMINUS)
|
||||
{
|
||||
if(pn->tokens.size<2)
|
||||
err_log("%u: expected integer",vec_at(&pn->tokens,0,const Tok*)->line);
|
||||
else
|
||||
fprintf(file,"\tmovl -%s,%%eax\n",vec_at(&pn->tokens,1,const Tok*)->str.buffer);
|
||||
}
|
||||
/* else if(vec_at(&pn->tokens,0,const Tok*)->type!=LINTEGER) */
|
||||
/* { */
|
||||
/* err_log("%u: returning non-integer",vec_at(&pn->tokens,0,const Tok*)->line); */
|
||||
/* } */
|
||||
else
|
||||
{
|
||||
switch(gen->buildarch)
|
||||
{
|
||||
|
||||
case M_I386:
|
||||
gen_i386_eval(gen,pn,file);
|
||||
break;
|
||||
|
||||
case M_X86_64:
|
||||
gen_x86_64_eval(gen,pn,file);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
gen_epilog(gen,pn,file);
|
||||
fprintf(file,"\tret\n");
|
||||
/*****
|
||||
* IMPORTANT:
|
||||
* This return exits the (recursive)
|
||||
* code generation call and ceases
|
||||
* reading further PNodes belonging
|
||||
* to its parent node (i.e., on the
|
||||
* same level)!!
|
||||
*****/
|
||||
return;
|
||||
break;
|
||||
|
||||
case PIF:
|
||||
if(pn->tokens.size>1)
|
||||
{
|
||||
switch(gen->buildarch)
|
||||
{
|
||||
|
||||
case M_I386:
|
||||
gen_i386_eval(gen,pn,file);
|
||||
break;
|
||||
|
||||
case M_X86_64:
|
||||
gen_x86_64_eval(gen,pn,file);
|
||||
break;
|
||||
|
||||
}
|
||||
fprintf(file,"\tcmpl $0,%%eax\n");
|
||||
}
|
||||
++gen->labelno;
|
||||
fprintf(file,"\tjz .L%02lu\n",gen->labelno);
|
||||
|
||||
for(size_t i=0;i<pn->pnodes.size;++i)
|
||||
gen_code(gen,vec_at(&pn->pnodes,i,PNode*),file);
|
||||
|
||||
fprintf(file,".L%02lu:\n",gen->labelno);
|
||||
break;
|
||||
|
||||
case PWHILE:
|
||||
++gen->labelno;
|
||||
fprintf(file,".L%02lu:\n",gen->labelno);
|
||||
if(pn->tokens.size>1)
|
||||
{
|
||||
switch(gen->buildarch)
|
||||
{
|
||||
|
||||
case M_I386:
|
||||
gen_i386_eval(gen,pn,file);
|
||||
break;
|
||||
|
||||
case M_X86_64:
|
||||
gen_x86_64_eval(gen,pn,file);
|
||||
break;
|
||||
|
||||
}
|
||||
fprintf(file,"\tcmpl $0,%%eax\n");
|
||||
}
|
||||
fprintf(file,"\tjz .L%02lu\n",++gen->labelno);
|
||||
|
||||
for(size_t i=0;i<pn->pnodes.size;++i)
|
||||
gen_code(gen,vec_at(&pn->pnodes,i,PNode*),file);
|
||||
|
||||
fprintf(file,"\tjmp .L%02lu\n",gen->labelno-1);
|
||||
fprintf(file,".L%02lu:\n",gen->labelno);
|
||||
break;
|
||||
|
||||
case PASM:
|
||||
{
|
||||
if(pn->tokens.size<1)
|
||||
err_log("%u: expected string after keyword 'asm'",vec_at(&pn->tokens,0,const Tok*)->line);
|
||||
else
|
||||
{
|
||||
if(pn->tokens.size>2)
|
||||
err_log("%u: unexpected token after 'asm' statement",vec_at(&pn->tokens,0,const Tok*)->line);
|
||||
/* gen_x86_64_print_string(gen,pn,file, */
|
||||
/* &vec_at(&pn->tokens,0,const Tok*)->str); */
|
||||
fprintf(file,"\t%s\n",vec_at(&pn->tokens,0,const Tok*)->str.buffer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PEXTERN:
|
||||
{
|
||||
if(pn->tokens.size<1)
|
||||
err_log("%u: expected identifier after keyword 'ext'",vec_at(&pn->tokens,0,const Tok*)->line);
|
||||
else
|
||||
{
|
||||
if(vec_at(&pn->tokens,0,const Tok*)->type!=LIDENTIFIER)
|
||||
err_log("%u: expected identifier after keyword 'ext'",vec_at(&pn->tokens,0,const Tok*)->line);
|
||||
if(pn->tokens.size>1&&vec_at(&pn->tokens,1,const Tok*)->subtype==LLPAREN)
|
||||
{
|
||||
for(size_t i=0;i<gen->rootnode->funcs.size;++i)
|
||||
{
|
||||
if(strcmp(vec_at(&pn->tokens,0,const Tok*)->str.buffer,vec_at(&gen->rootnode->funcs,i,Func*)->name)==0)
|
||||
{
|
||||
err_log("%u: '%s' already declared",vec_at(&pn->tokens,0,const Tok*)->line,vec_at(&pn->tokens,0,const Tok*)->str.buffer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Func func={
|
||||
.name=vec_at(&pn->tokens,0,const Tok*)->str.buffer,
|
||||
/* .type=I32, */
|
||||
};
|
||||
vec_push((Vec*)&gen->rootnode->funcs,&func);
|
||||
}
|
||||
|
||||
else
|
||||
gen_declare_variable(gen,pn,file);
|
||||
fprintf(file,".extern %s\n",vec_at(&pn->tokens,0,const Tok*)->str.buffer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PCOMMENT:
|
||||
fprintf(file,"\t;%s\n",vec_at(&pn->tokens,0,const Tok*)->str.buffer);
|
||||
break;
|
||||
|
||||
case PBLOCK:
|
||||
for(size_t i=0;i<pn->pnodes.size;++i)
|
||||
gen_code(gen,vec_at(&pn->pnodes,i,PNode*),file);
|
||||
break;
|
||||
|
||||
case PEMPTY:
|
||||
// Root node, otherwise ignore
|
||||
if(pn->parentnode==NULL)
|
||||
{
|
||||
for(size_t i=0;i<pn->pnodes.size;++i)
|
||||
gen_code(gen,vec_at(&pn->pnodes,i,PNode*),file);
|
||||
}
|
||||
break;
|
||||
|
||||
case PEXPRESSION:
|
||||
default:
|
||||
switch(gen->buildarch)
|
||||
{
|
||||
|
||||
case M_I386:
|
||||
gen_i386_eval(gen,pn,file);
|
||||
break;
|
||||
|
||||
case M_X86_64:
|
||||
gen_x86_64_eval(gen,pn,file);
|
||||
break;
|
||||
|
||||
}
|
||||
if(pn->tokens.size>0)
|
||||
{
|
||||
fprintf(file,";#PNODE ID: %s ",partype_names[pn->type]);
|
||||
for(size_t i=0;i<pn->tokens.size;++i)
|
||||
{
|
||||
fprintf(file,"%s",vec_at(&pn->tokens,i,const Tok*)->str.buffer);
|
||||
}
|
||||
fprintf(file,"\n");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//for(size_t i=0;i<pn->pnodes.size;++i)
|
||||
//gen_code(gen,vec_at(&pn->pnodes,i,PNode*),file);
|
||||
}
|
||||
|
3
gen.h
3
gen.h
@ -37,6 +37,9 @@ typedef struct eval_elem
|
||||
Gen gen_new(void);
|
||||
Vec gen_i2r(const Vec*tokens);
|
||||
bool gen_findret(const PNode*pn,bool found);
|
||||
size_t gen_stacksize(const PNode*pn);
|
||||
void gen(Gen*gen,PNode*pn,FILE*file);
|
||||
void gen_code(Gen*gen,PNode*pn,FILE*file);
|
||||
void gen_declare_function(Gen*gen,PNode*pn,FILE*file);
|
||||
void gen_declare_variable(Gen*gen,PNode*pn,FILE*file);
|
||||
void gen_epilog(Gen*gen,const PNode*pn,FILE*file);
|
||||
|
200
i386.c
200
i386.c
@ -13,190 +13,6 @@ char*gen_i386_sp(void){return"esp";}
|
||||
char*gen_i386_bp(void){return"ebp";}
|
||||
char*gen_i386_scratch1(void){return"e8d";};
|
||||
|
||||
void gen_i386(Gen*gen,PNode*pn,FILE*file)
|
||||
{
|
||||
|
||||
if(!pn)
|
||||
{
|
||||
err_log("passed NULL PNode to gen_i386");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!file)
|
||||
{
|
||||
err_log("NULL FILE* passed to gen_i386");
|
||||
return;
|
||||
}
|
||||
|
||||
if(gen->rootnode==pn)
|
||||
fprintf(file,".text\n");
|
||||
|
||||
switch(pn->type)
|
||||
{
|
||||
|
||||
case PFUNDECL:
|
||||
{
|
||||
bool found=false;
|
||||
gen_declare_function(gen,pn,file);
|
||||
found=gen_findret(pn,false);
|
||||
if(!found)
|
||||
err_log("%u: no return in function '%s'",vec_at(&pn->tokens,0,const Tok*)->line,
|
||||
vec_at(&pn->tokens,0,const Tok*)->str.buffer);
|
||||
}
|
||||
break;
|
||||
|
||||
case PVARDECL:
|
||||
gen_declare_variable(gen,pn,file);
|
||||
break;
|
||||
|
||||
case PRET:
|
||||
if(pn->tokens.size>0)
|
||||
{
|
||||
if(vec_at(&pn->tokens,0,const Tok*)->type==LOPERATOR&&vec_at(&pn->tokens,0,const Tok*)->subtype==LSMINUS)
|
||||
{
|
||||
if(pn->tokens.size<2)
|
||||
err_log("%u: expected integer",vec_at(&pn->tokens,0,const Tok*)->line);
|
||||
else
|
||||
fprintf(file,"\tmovl -%s,%%eax\n",vec_at(&pn->tokens,1,const Tok*)->str.buffer);
|
||||
}
|
||||
/* else if(vec_at(&pn->tokens,0,const Tok*)->type!=LINTEGER) */
|
||||
/* { */
|
||||
/* err_log("%u: returning non-integer",vec_at(&pn->tokens,0,const Tok*)->line); */
|
||||
/* } */
|
||||
else
|
||||
gen_i386_eval(gen,pn,file);
|
||||
}
|
||||
gen_epilog(gen,pn,file);
|
||||
fprintf(file,"\tret\n");
|
||||
/*****
|
||||
* IMPORTANT:
|
||||
* This return exits the (recursive)
|
||||
* code generation call and ceases
|
||||
* reading further PNodes belonging
|
||||
* to its parent node (i.e., on the
|
||||
* same level)!!
|
||||
*****/
|
||||
return;
|
||||
break;
|
||||
|
||||
case PIF:
|
||||
if(pn->tokens.size>1)
|
||||
{
|
||||
gen_i386_eval(gen,pn,file);
|
||||
fprintf(file,"\tcmpl $0,%%eax\n");
|
||||
}
|
||||
++gen->labelno;
|
||||
fprintf(file,"\tjz .L%02lu\n",gen->labelno);
|
||||
|
||||
for(size_t i=0;i<pn->pnodes.size;++i)
|
||||
gen_i386(gen,vec_at(&pn->pnodes,i,PNode*),file);
|
||||
|
||||
fprintf(file,".L%02lu:\n",gen->labelno);
|
||||
break;
|
||||
|
||||
case PWHILE:
|
||||
++gen->labelno;
|
||||
fprintf(file,".L%02lu:\n",gen->labelno);
|
||||
if(pn->tokens.size>1)
|
||||
{
|
||||
gen_i386_eval(gen,pn,file);
|
||||
fprintf(file,"\tcmpl $0,%%eax\n");
|
||||
}
|
||||
fprintf(file,"\tjz .L%02lu\n",++gen->labelno);
|
||||
|
||||
for(size_t i=0;i<pn->pnodes.size;++i)
|
||||
gen_i386(gen,vec_at(&pn->pnodes,i,PNode*),file);
|
||||
|
||||
fprintf(file,"\tjmp .L%02lu\n",gen->labelno-1);
|
||||
fprintf(file,".L%02lu:\n",gen->labelno);
|
||||
break;
|
||||
|
||||
case PASM:
|
||||
{
|
||||
if(pn->tokens.size<1)
|
||||
err_log("%u: expected string after keyword 'asm'",vec_at(&pn->tokens,0,const Tok*)->line);
|
||||
else
|
||||
{
|
||||
if(pn->tokens.size>2)
|
||||
err_log("%u: unexpected token after 'asm' statement",vec_at(&pn->tokens,0,const Tok*)->line);
|
||||
/* gen_i386_print_string(gen,pn,file, */
|
||||
/* &vec_at(&pn->tokens,0,const Tok*)->str); */
|
||||
fprintf(file,"\t%s\n",vec_at(&pn->tokens,0,const Tok*)->str.buffer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PEXTERN:
|
||||
{
|
||||
if(pn->tokens.size<1)
|
||||
err_log("%u: expected identifier after keyword 'ext'",vec_at(&pn->tokens,0,const Tok*)->line);
|
||||
else
|
||||
{
|
||||
if(vec_at(&pn->tokens,0,const Tok*)->type!=LIDENTIFIER)
|
||||
err_log("%u: expected identifier after keyword 'ext'",vec_at(&pn->tokens,0,const Tok*)->line);
|
||||
if(pn->tokens.size>1&&vec_at(&pn->tokens,1,const Tok*)->subtype==LLPAREN)
|
||||
{
|
||||
for(size_t i=0;i<gen->rootnode->funcs.size;++i)
|
||||
{
|
||||
if(strcmp(vec_at(&pn->tokens,0,const Tok*)->str.buffer,vec_at(&gen->rootnode->funcs,i,Func*)->name)==0)
|
||||
{
|
||||
err_log("%u: '%s' already declared",vec_at(&pn->tokens,0,const Tok*)->line,vec_at(&pn->tokens,0,const Tok*)->str.buffer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Func func={
|
||||
.name=vec_at(&pn->tokens,0,const Tok*)->str.buffer,
|
||||
/* .type=I32, */
|
||||
};
|
||||
vec_push((Vec*)&gen->rootnode->funcs,&func);
|
||||
}
|
||||
|
||||
else
|
||||
gen_declare_variable(gen,pn,file);
|
||||
fprintf(file,".extern %s\n",vec_at(&pn->tokens,0,const Tok*)->str.buffer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PCOMMENT:
|
||||
fprintf(file,"\t;%s\n",vec_at(&pn->tokens,0,const Tok*)->str.buffer);
|
||||
break;
|
||||
|
||||
case PBLOCK:
|
||||
for(size_t i=0;i<pn->pnodes.size;++i)
|
||||
gen_i386(gen,vec_at(&pn->pnodes,i,PNode*),file);
|
||||
break;
|
||||
|
||||
case PEMPTY:
|
||||
// Root node, otherwise ignore
|
||||
if(pn->parentnode==NULL)
|
||||
{
|
||||
for(size_t i=0;i<pn->pnodes.size;++i)
|
||||
gen_i386(gen,vec_at(&pn->pnodes,i,PNode*),file);
|
||||
}
|
||||
break;
|
||||
|
||||
case PEXPRESSION:
|
||||
default:
|
||||
gen_i386_eval(gen,pn,file);
|
||||
if(pn->tokens.size>0)
|
||||
{
|
||||
fprintf(file,";#PNODE ID: %s ",partype_names[pn->type]);
|
||||
for(size_t i=0;i<pn->tokens.size;++i)
|
||||
{
|
||||
fprintf(file,"%s",vec_at(&pn->tokens,i,const Tok*)->str.buffer);
|
||||
}
|
||||
fprintf(file,"\n");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//for(size_t i=0;i<pn->pnodes.size;++i)
|
||||
//gen_i386(gen,vec_at(&pn->pnodes,i,PNode*),file);
|
||||
}
|
||||
|
||||
// Convert to infix, then evaluate
|
||||
void gen_i386_eval(Gen*gen,const PNode*pn,FILE*file)
|
||||
{
|
||||
@ -703,19 +519,3 @@ void gen_i386_eval(Gen*gen,const PNode*pn,FILE*file)
|
||||
vec_free(&rpn_stack);
|
||||
vec_free(&stack);
|
||||
}
|
||||
|
||||
size_t gen_i386_stacksize(const PNode*pn)
|
||||
{
|
||||
size_t stacksize=0;
|
||||
|
||||
if(pn->pnodes.size==0)
|
||||
{
|
||||
if(pn->type==PVARDECL)
|
||||
return stacksize+sizeof(uint32_t);
|
||||
else return 0;
|
||||
}
|
||||
|
||||
for(size_t i=0;i<pn->pnodes.size;++i)
|
||||
stacksize+=gen_i386_stacksize(vec_at(&pn->pnodes,i,PNode*));
|
||||
return stacksize;
|
||||
}
|
||||
|
2
i386.h
2
i386.h
@ -15,6 +15,4 @@ extern const char*const gen_i386_pop_wordsize;
|
||||
char*gen_i386_bp(void);
|
||||
char*gen_i386_scratch1(void);
|
||||
char*gen_i386_sp(void);
|
||||
size_t gen_i386_stacksize(const PNode*pn);
|
||||
void gen_i386(struct Gen*gen,PNode*pn,FILE*file);
|
||||
void gen_i386_eval(struct Gen*gen,const PNode*pn,FILE*file);
|
||||
|
5
main.c
5
main.c
@ -205,11 +205,8 @@ int main(int argc,char**argv)
|
||||
break;
|
||||
|
||||
case M_X86_64:
|
||||
gen_x86_64(&state.gen,&state.parser.root,state.outfile);
|
||||
break;
|
||||
|
||||
case M_I386:
|
||||
gen_i386(&state.gen,&state.parser.root,state.outfile);
|
||||
gen_code(&state.gen,&state.parser.root,state.outfile);
|
||||
break;
|
||||
|
||||
}
|
||||
|
200
x86_64.c
200
x86_64.c
@ -14,206 +14,6 @@ char*gen_x86_64_sp(void){return"rsp";}
|
||||
char*gen_x86_64_bp(void){return"rbp";}
|
||||
char*gen_x86_64_scratch1(void){return"r8d";};
|
||||
|
||||
void gen_x86_64(Gen*gen,PNode*pn,FILE*file)
|
||||
{
|
||||
|
||||
if(!pn)
|
||||
{
|
||||
err_log("passed NULL PNode to gen_x86_64");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!file)
|
||||
{
|
||||
err_log("NULL FILE* passed to gen_x86_64");
|
||||
return;
|
||||
}
|
||||
|
||||
if(gen->rootnode==pn)
|
||||
fprintf(file,".text\n");
|
||||
|
||||
switch(pn->type)
|
||||
{
|
||||
|
||||
case PFUNDECL:
|
||||
{
|
||||
bool found=false;
|
||||
gen_declare_function(gen,pn,file);
|
||||
found=gen_findret(pn,false);
|
||||
if(!found)
|
||||
err_log("%u: no return in function '%s'",vec_at(&pn->tokens,0,const Tok*)->line,
|
||||
vec_at(&pn->tokens,0,const Tok*)->str.buffer);
|
||||
}
|
||||
break;
|
||||
|
||||
case PVARDECL:
|
||||
gen_declare_variable(gen,pn,file);
|
||||
break;
|
||||
|
||||
case PRET:
|
||||
if(pn->tokens.size>0)
|
||||
{
|
||||
if(vec_at(&pn->tokens,0,const Tok*)->type==LOPERATOR&&vec_at(&pn->tokens,0,const Tok*)->subtype==LSMINUS)
|
||||
{
|
||||
if(pn->tokens.size<2)
|
||||
err_log("%u: expected integer",vec_at(&pn->tokens,0,const Tok*)->line);
|
||||
else
|
||||
fprintf(file,"\tmovl -%s,%%eax\n",vec_at(&pn->tokens,1,const Tok*)->str.buffer);
|
||||
}
|
||||
/* else if(vec_at(&pn->tokens,0,const Tok*)->type!=LINTEGER) */
|
||||
/* { */
|
||||
/* err_log("%u: returning non-integer",vec_at(&pn->tokens,0,const Tok*)->line); */
|
||||
/* } */
|
||||
else
|
||||
gen_x86_64_eval(gen,pn,file);
|
||||
}
|
||||
gen_epilog(gen,pn,file);
|
||||
fprintf(file,"\tret\n");
|
||||
/*****
|
||||
* IMPORTANT:
|
||||
* This return exits the (recursive)
|
||||
* code generation call and ceases
|
||||
* reading further PNodes belonging
|
||||
* to its parent node (i.e., on the
|
||||
* same level)!!
|
||||
*****/
|
||||
return;
|
||||
break;
|
||||
|
||||
case PIF:
|
||||
if(pn->tokens.size>1)
|
||||
{
|
||||
gen_x86_64_eval(gen,pn,file);
|
||||
fprintf(file,"\tcmpl $0,%%eax\n");
|
||||
}
|
||||
++gen->labelno;
|
||||
fprintf(file,"\tjz .L%02lu\n",gen->labelno);
|
||||
|
||||
for(size_t i=0;i<pn->pnodes.size;++i)
|
||||
gen_x86_64(gen,vec_at(&pn->pnodes,i,PNode*),file);
|
||||
|
||||
fprintf(file,".L%02lu:\n",gen->labelno);
|
||||
break;
|
||||
|
||||
case PWHILE:
|
||||
++gen->labelno;
|
||||
fprintf(file,".L%02lu:\n",gen->labelno);
|
||||
if(pn->tokens.size>1)
|
||||
{
|
||||
gen_x86_64_eval(gen,pn,file);
|
||||
fprintf(file,"\tcmpl $0,%%eax\n");
|
||||
}
|
||||
fprintf(file,"\tjz .L%02lu\n",++gen->labelno);
|
||||
|
||||
for(size_t i=0;i<pn->pnodes.size;++i)
|
||||
gen_x86_64(gen,vec_at(&pn->pnodes,i,PNode*),file);
|
||||
|
||||
fprintf(file,"\tjmp .L%02lu\n",gen->labelno-1);
|
||||
fprintf(file,".L%02lu:\n",gen->labelno);
|
||||
break;
|
||||
|
||||
case PASM:
|
||||
{
|
||||
if(pn->tokens.size<1)
|
||||
err_log("%u: expected string after keyword 'asm'",vec_at(&pn->tokens,0,const Tok*)->line);
|
||||
else
|
||||
{
|
||||
if(pn->tokens.size>2)
|
||||
err_log("%u: unexpected token after 'asm' statement",vec_at(&pn->tokens,0,const Tok*)->line);
|
||||
/* gen_x86_64_print_string(gen,pn,file, */
|
||||
/* &vec_at(&pn->tokens,0,const Tok*)->str); */
|
||||
fprintf(file,"\t%s\n",vec_at(&pn->tokens,0,const Tok*)->str.buffer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PEXTERN:
|
||||
{
|
||||
if(pn->tokens.size<1)
|
||||
err_log("%u: expected identifier after keyword 'ext'",vec_at(&pn->tokens,0,const Tok*)->line);
|
||||
else
|
||||
{
|
||||
if(vec_at(&pn->tokens,0,const Tok*)->type!=LIDENTIFIER)
|
||||
err_log("%u: expected identifier after keyword 'ext'",vec_at(&pn->tokens,0,const Tok*)->line);
|
||||
if(pn->tokens.size>1&&vec_at(&pn->tokens,1,const Tok*)->subtype==LLPAREN)
|
||||
{
|
||||
for(size_t i=0;i<gen->rootnode->funcs.size;++i)
|
||||
{
|
||||
if(strcmp(vec_at(&pn->tokens,0,const Tok*)->str.buffer,vec_at(&gen->rootnode->funcs,i,Func*)->name)==0)
|
||||
{
|
||||
err_log("%u: '%s' already declared",vec_at(&pn->tokens,0,const Tok*)->line,vec_at(&pn->tokens,0,const Tok*)->str.buffer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Func func={
|
||||
.name=vec_at(&pn->tokens,0,const Tok*)->str.buffer,
|
||||
/* .type=I32, */
|
||||
};
|
||||
vec_push((Vec*)&gen->rootnode->funcs,&func);
|
||||
}
|
||||
|
||||
else
|
||||
gen_declare_variable(gen,pn,file);
|
||||
fprintf(file,".extern %s\n",vec_at(&pn->tokens,0,const Tok*)->str.buffer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case PCOMMENT:
|
||||
fprintf(file,"\t;%s\n",vec_at(&pn->tokens,0,const Tok*)->str.buffer);
|
||||
break;
|
||||
|
||||
case PBLOCK:
|
||||
for(size_t i=0;i<pn->pnodes.size;++i)
|
||||
gen_x86_64(gen,vec_at(&pn->pnodes,i,PNode*),file);
|
||||
break;
|
||||
|
||||
case PEMPTY:
|
||||
// Root node, otherwise ignore
|
||||
if(pn->parentnode==NULL)
|
||||
{
|
||||
for(size_t i=0;i<pn->pnodes.size;++i)
|
||||
gen_x86_64(gen,vec_at(&pn->pnodes,i,PNode*),file);
|
||||
}
|
||||
break;
|
||||
|
||||
case PEXPRESSION:
|
||||
default:
|
||||
gen_x86_64_eval(gen,pn,file);
|
||||
if(pn->tokens.size>0)
|
||||
{
|
||||
fprintf(file,";#PNODE ID: %s ",partype_names[pn->type]);
|
||||
for(size_t i=0;i<pn->tokens.size;++i)
|
||||
{
|
||||
fprintf(file,"%s",vec_at(&pn->tokens,i,const Tok*)->str.buffer);
|
||||
}
|
||||
fprintf(file,"\n");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//for(size_t i=0;i<pn->pnodes.size;++i)
|
||||
//gen_x86_64(gen,vec_at(&pn->pnodes,i,PNode*),file);
|
||||
}
|
||||
|
||||
size_t gen_x86_64_stacksize(const PNode*pn)
|
||||
{
|
||||
size_t stacksize=0;
|
||||
|
||||
if(pn->pnodes.size==0)
|
||||
{
|
||||
if(pn->type==PVARDECL)
|
||||
return stacksize+sizeof(uint32_t);
|
||||
else return 0;
|
||||
}
|
||||
|
||||
for(size_t i=0;i<pn->pnodes.size;++i)
|
||||
stacksize+=gen_x86_64_stacksize(vec_at(&pn->pnodes,i,PNode*));
|
||||
return stacksize;
|
||||
}
|
||||
|
||||
// Convert to infix, then evaluate
|
||||
void gen_x86_64_eval(Gen*gen,const PNode*pn,FILE*file)
|
||||
{
|
||||
|
1
x86_64.h
1
x86_64.h
@ -15,6 +15,5 @@ extern const char*const gen_x86_64_pop_wordsize;
|
||||
char*gen_x86_64_bp(void);
|
||||
char*gen_x86_64_scratch1(void);
|
||||
char*gen_x86_64_sp(void);
|
||||
size_t gen_x86_64_stacksize(const PNode*pn);
|
||||
void gen_x86_64(struct Gen*gen,PNode*pn,FILE*file);
|
||||
void gen_x86_64_eval(struct Gen*gen,const PNode*pn,FILE*file);
|
||||
|
Loading…
Reference in New Issue
Block a user