gen_eval, remove gen_x86_64_eval
This commit is contained in:
parent
07bc6a1461
commit
a0f722750f
661
gen.c
661
gen.c
@ -219,20 +219,7 @@ void gen_declare_variable(Gen*gen,PNode*pn,FILE*file)
|
||||
|
||||
// Evaluate initialization expression
|
||||
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;
|
||||
|
||||
}
|
||||
}
|
||||
gen_eval(gen,pn,file);
|
||||
}
|
||||
}
|
||||
|
||||
@ -523,20 +510,7 @@ void gen_code(Gen*gen,PNode*pn,FILE*file)
|
||||
/* 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_eval(gen,pn,file);
|
||||
}
|
||||
gen_epilog(gen,pn,file);
|
||||
fprintf(file,"\tret\n");
|
||||
@ -554,18 +528,7 @@ void gen_code(Gen*gen,PNode*pn,FILE*file)
|
||||
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;
|
||||
|
||||
}
|
||||
gen_eval(gen,pn,file);
|
||||
fprintf(file,"\tcmpl $0,%%eax\n");
|
||||
}
|
||||
size_t labelno_cache=gen->labelno;
|
||||
@ -586,18 +549,7 @@ void gen_code(Gen*gen,PNode*pn,FILE*file)
|
||||
fprintf(file,".L%02lu:\n",pwhile_label1);
|
||||
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;
|
||||
|
||||
}
|
||||
gen_eval(gen,pn,file);
|
||||
fprintf(file,"\tcmpl $0,%%eax\n");
|
||||
}
|
||||
|
||||
@ -679,18 +631,7 @@ void gen_code(Gen*gen,PNode*pn,FILE*file)
|
||||
|
||||
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;
|
||||
|
||||
}
|
||||
gen_eval(gen,pn,file);
|
||||
if(pn->tokens.size>0)
|
||||
{
|
||||
fprintf(file,";#PNODE ID: %s ",partype_names[pn->type]);
|
||||
@ -707,3 +648,595 @@ void gen_code(Gen*gen,PNode*pn,FILE*file)
|
||||
//for(size_t i=0;i<pn->pnodes.size;++i)
|
||||
//gen_code(gen,vec_at(&pn->pnodes,i,PNode*),file);
|
||||
}
|
||||
|
||||
// Convert to infix, then evaluate
|
||||
void gen_eval(Gen*gen,const PNode*pn,FILE*file)
|
||||
{
|
||||
if(gen->buildarch==M_I386)
|
||||
{
|
||||
gen_i386_eval(gen,pn,file);
|
||||
return;
|
||||
}
|
||||
|
||||
Vec rpn_stack={0};
|
||||
Vec stack=vec_new(sizeof(eval_elem));
|
||||
|
||||
rpn_stack=gen_i2r(&pn->tokens);
|
||||
if(gen->showrpn)vec_print_tokens(&rpn_stack);
|
||||
|
||||
/* gen_eval_analyze(pn); */
|
||||
|
||||
// Evaluate RPN
|
||||
if(rpn_stack.buffer&&rpn_stack.size>0)
|
||||
{
|
||||
|
||||
for(size_t i=0;i<rpn_stack.size;++i)
|
||||
{
|
||||
|
||||
switch(vec_at(&rpn_stack,i,const Tok*)->type)
|
||||
{
|
||||
|
||||
case LKEYWORD:
|
||||
{
|
||||
if(strcmp("true",vec_at(&rpn_stack,i,const Tok*)->str.buffer)==0)
|
||||
{
|
||||
eval_elem e={.type=EI32,.val.i32=1};
|
||||
vec_push(&stack,&e);
|
||||
}
|
||||
else if(strcmp("false",vec_at(&rpn_stack,i,const Tok*)->str.buffer)==0)
|
||||
{
|
||||
eval_elem e={.type=EI32,.val.i32=0};
|
||||
vec_push(&stack,&e);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LIDENTIFIER:
|
||||
{
|
||||
eval_elem e={.type=EIDENT,.val.name=vec_at(&rpn_stack,i,const Tok*)->str.buffer};
|
||||
vec_push(&stack,&e);
|
||||
}
|
||||
break;
|
||||
|
||||
case LINTEGER:
|
||||
case LFLOAT:
|
||||
{
|
||||
int32_t d=atoi(vec_at(&rpn_stack,i,const Tok*)->str.buffer);
|
||||
eval_elem e={.type=EI32,.val.i32=d};
|
||||
vec_push(&stack,&e);
|
||||
}
|
||||
break;
|
||||
|
||||
case LOPERATOR:
|
||||
|
||||
// Get operands
|
||||
if(stack.size>1)
|
||||
{
|
||||
|
||||
eval_elem elem[2]={{0}};
|
||||
int32_t integers[2]={0};
|
||||
int32_t res=0;
|
||||
/* size_t var_stackloc[2]={0}; */
|
||||
size_t nops=2; // 2 unless unary operator
|
||||
|
||||
//if(vec_at(&rpn_stack,i,const Tok*)->str.buffer[0]=='!')
|
||||
if(strcmp("!",vec_at(&rpn_stack,i,const Tok*)->str.buffer)==0)
|
||||
nops=1;
|
||||
|
||||
// Get top two stack elements (variables, integers, etc.)
|
||||
for(size_t k=0;k<nops;++k)
|
||||
{
|
||||
|
||||
elem[k]=*vec_at(&stack,stack.size-1,eval_elem*);
|
||||
vec_pop(&stack);
|
||||
|
||||
if(elem[k].type==EIDENT)
|
||||
{
|
||||
bool found=false;
|
||||
|
||||
// Identify functions
|
||||
for(size_t j=0;j<gen->rootnode->funcs.size;++j)
|
||||
{
|
||||
if(strcmp(vec_at(&gen->rootnode->funcs,j,Func*)->name,elem[k].val.name)==0)
|
||||
{
|
||||
elem[k].type=EFUNC;
|
||||
fprintf(file,"\tcall %s\n",elem[k].val.name);
|
||||
{
|
||||
eval_elem e={.type=EACC,.val.i32=0};
|
||||
vec_push(&stack,&e);
|
||||
--k;
|
||||
}
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Identify variables
|
||||
if(!found)
|
||||
{
|
||||
for(size_t j=0;j<gen->stackptr->vars.size;++j)
|
||||
{
|
||||
if(strcmp(vec_at(&gen->stackptr->vars,j,Var*)->name,elem[k].val.name)==0)
|
||||
{
|
||||
elem[k].type=EVAR;
|
||||
elem[k].vstackloc=vec_at(&gen->stackptr->vars,j,Var*)->stackloc;
|
||||
elem[k].vtype=vec_at(&gen->stackptr->vars,j,Var*)->type;
|
||||
//var_stackloc[k]=vec_at(&gen->stackptr->vars,j,Var*)->stackloc;
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found)
|
||||
err_log("%u: undeclared identifier '%s'",vec_at(&pn->tokens,0,Tok*)->line,elem[k].val.name);
|
||||
}
|
||||
}
|
||||
else if(elem[k].type==EI32)
|
||||
integers[k]=elem[k].val.i32;
|
||||
}
|
||||
|
||||
/* // Debugging output */
|
||||
/* if(elem[1].type==EVAR) */
|
||||
/* printf("'%s' ",elem[1].val.name); */
|
||||
/* else if(elem[1].type==EI32) */
|
||||
/* printf("%d ",elem[1].val.i32); */
|
||||
/* else */
|
||||
/* printf("acc "); */
|
||||
/* printf("%s ",vec_at(&rpn_stack,i,Tok*)->str.buffer); */
|
||||
/* if(elem[0].type==EVAR) */
|
||||
/* printf("'%s' ",elem[0].val.name); */
|
||||
/* else if(elem[0].type==EI32) */
|
||||
/* printf("%d ",elem[0].val.i32); */
|
||||
/* else */
|
||||
/* printf("acc "); */
|
||||
/* puts(""); */
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// Extra debugging output
|
||||
if(elem[1].type==EVAR)
|
||||
{
|
||||
printf("'%s'(%u) ",elem[1].val.name,elem[1].vtype);
|
||||
}
|
||||
else if(elem[1].type==EI32)
|
||||
{
|
||||
printf("%d ",elem[1].val.i32);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("acc ");
|
||||
}
|
||||
|
||||
printf("%s ",vec_at(&rpn_stack,i,Tok*)->str.buffer);
|
||||
if(elem[0].type==EVAR)
|
||||
{
|
||||
printf("'%s'(%u) ",elem[0].val.name,elem[0].vtype);
|
||||
}
|
||||
else if(elem[0].type==EI32)
|
||||
{
|
||||
printf("%d ",elem[0].val.i32);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("acc ");
|
||||
}
|
||||
puts("");
|
||||
// ----------------------------------------------------------
|
||||
|
||||
// UNARY OPS
|
||||
if(nops==1)
|
||||
{
|
||||
switch(vec_at(&rpn_stack,i,const Tok*)->str.buffer[0])
|
||||
{
|
||||
case '!':
|
||||
if(elem[0].type==EVAR)
|
||||
{
|
||||
fprintf(file,"\tcmpl $0,-%lu(%%%s)\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\tsete %%al\n");
|
||||
fprintf(file,"\tmovzbl %%al,%%eax\n");
|
||||
/* fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",elem[0].vstackloc,gen_x86_64_bp); */
|
||||
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
vec_push(&stack,&e);
|
||||
}
|
||||
else if(elem[0].type==EI32)
|
||||
{
|
||||
fprintf(file,"\tmovl $%d,%%eax\n",integers[0]);
|
||||
fprintf(file,"\tcmpl $0,%%eax\n");
|
||||
fprintf(file,"\tsete %%al\n");
|
||||
fprintf(file,"\tmovzbl %%al,%%eax\n");
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
vec_push(&stack,&e);
|
||||
}
|
||||
else if(elem[0].type==EACC)
|
||||
{
|
||||
fprintf(file,"\tcmpl $0,%%eax\n");
|
||||
fprintf(file,"\tsete %%al\n");
|
||||
fprintf(file,"\tmovzbl %%al,%%eax\n");
|
||||
//fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
vec_push(&stack,&e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// INT OP INT
|
||||
else if(elem[0].type==EI32&&elem[1].type==EI32)
|
||||
{
|
||||
switch(vec_at(&rpn_stack,i,const Tok*)->str.buffer[0])
|
||||
{
|
||||
|
||||
case '+':res=integers[1]+integers[0];break;
|
||||
case '-':res=integers[1]-integers[0];break;
|
||||
case '*':res=integers[1]*integers[0];break;
|
||||
case '/':res=integers[1]/integers[0];break;
|
||||
|
||||
}
|
||||
eval_elem e={.type=EI32,.val.i32=res};
|
||||
vec_push(&stack,&e);
|
||||
}
|
||||
|
||||
// INT OP ACC
|
||||
else if(
|
||||
(elem[0].type==EACC && elem[1].type==EI32) ||
|
||||
(elem[0].type==EI32 && elem[1].type==EACC)
|
||||
)
|
||||
{
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
|
||||
if(elem[0].type==EI32)
|
||||
{
|
||||
eval_elem etmp=elem[0];
|
||||
elem[0]=elem[1];
|
||||
elem[1]=etmp;
|
||||
}
|
||||
|
||||
switch(vec_at(&rpn_stack,i,Tok*)->str.buffer[0])
|
||||
{
|
||||
|
||||
case '=':
|
||||
err_log("%u: cannot assign to rvalue '%d'",vec_at(&pn->tokens,0,Tok*)->line,elem[1].val.i32);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
fprintf(file,"\taddl $%d,%%eax\n",elem[1].val.i32);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
fprintf(file,"\tsubl $%d,%%eax\n",elem[1].val.i32);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '*':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tmovl $%d,%%%s\n",elem[1].val.i32,gen_x86_64_scratch1);
|
||||
fprintf(file,"\timull %%%s\n",gen_x86_64_scratch1);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '/':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tmovl $%d,%%%s\n",elem[1].val.i32,gen_x86_64_scratch1);
|
||||
fprintf(file,"\tidiv %%%s\n",gen_x86_64_scratch1);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// INT OP IDENT
|
||||
else if(elem[0].type==EVAR && elem[1].type==EI32)
|
||||
{
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
|
||||
switch(vec_at(&rpn_stack,i,Tok*)->str.buffer[0])
|
||||
{
|
||||
|
||||
case '=':
|
||||
err_log("%u: cannot assign to rvalue '%d'",vec_at(&pn->tokens,0,Tok*)->line,elem[1].val.i32);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\taddl $%d,%%eax\n",elem[1].val.i32);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\tsubl $%d,%%eax\n",elem[1].val.i32);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '*':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\tmovl $%d,%%%s\n",elem[1].val.i32,gen_x86_64_scratch1);
|
||||
fprintf(file,"\timull %%%s\n",gen_x86_64_scratch1);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '/':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\tmovl $%d,%%%s\n",elem[1].val.i32,gen_x86_64_scratch1);
|
||||
fprintf(file,"\tidivl %%%s\n",gen_x86_64_scratch1);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// IDENT OP INT
|
||||
else if(elem[0].type==EI32 && elem[1].type==EVAR)
|
||||
{
|
||||
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
|
||||
switch(vec_at(&rpn_stack,i,Tok*)->str.buffer[0])
|
||||
{
|
||||
|
||||
case '=':
|
||||
fprintf(file,"\tmovl $%d,-%lu(%%%s)\n",elem[0].val.i32,elem[1].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\tmovl $%d,%%eax\n",elem[0].val.i32);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\taddl $%d,%%eax\n",elem[0].val.i32);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\tsubl $%d,%%eax\n",elem[0].val.i32);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '*':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\tmovl $%d,%%%s\n",elem[0].val.i32,gen_x86_64_scratch1);
|
||||
fprintf(file,"\timul %%%s\n",gen_x86_64_scratch1);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '/':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\tmovl $%d,%%%s\n",elem[0].val.i32,gen_x86_64_scratch1);
|
||||
fprintf(file,"\tidivl %%%s\n",gen_x86_64_scratch1);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// IDENT OP IDENT
|
||||
else if(elem[0].type==EVAR && elem[1].type==EVAR)
|
||||
{
|
||||
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
|
||||
switch(vec_at(&rpn_stack,i,Tok*)->str.buffer[0])
|
||||
{
|
||||
|
||||
case '=':
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\taddl -%lu(%%%s),%%eax\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\tsubl -%lu(%%%s),%%eax\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '*':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\timull -%lu(%%%s)\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '/':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
fprintf(file,"\tidivl -%lu(%%%s)\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// IDENT OP ACC
|
||||
else if(elem[1].type==EACC && elem[0].type==EVAR)
|
||||
{
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
|
||||
switch(vec_at(&rpn_stack,i,Tok*)->str.buffer[0])
|
||||
{
|
||||
|
||||
case '=':
|
||||
fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
fprintf(file,"\taddl -%lu(%%%s),%%eax\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
fprintf(file,"\tsubl -%lu(%%%s),%%eax\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '*':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\timull -%lu(%%%s)\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '/':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tidivl -%lu(%%%s)\n",elem[0].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// I32 OP ACC
|
||||
else if(elem[1].type==EACC && elem[0].type==EI32)
|
||||
{
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
|
||||
switch(vec_at(&rpn_stack,i,Tok*)->str.buffer[0])
|
||||
{
|
||||
|
||||
case '=':
|
||||
err_log("%u: cannot assign to accumulator",vec_at(&pn->tokens,0,Tok*)->line,e.val.name);
|
||||
/* vec_push(&stack,&e); */
|
||||
break;
|
||||
|
||||
case '+':
|
||||
fprintf(file,"\taddl $%d,%%eax\n",elem[0].val.i32);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
fprintf(file,"\tsubl $%d,%%eax\n",elem[0].val.i32);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '*':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\timull $%d\n",elem[0].val.i32);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '/':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tidivl $%d\n",elem[0].val.i32);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ACC OP IDENT
|
||||
else if(elem[1].type==EVAR && elem[0].type==EACC)
|
||||
{
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
|
||||
switch(vec_at(&rpn_stack,i,Tok*)->str.buffer[0])
|
||||
{
|
||||
|
||||
case '=':
|
||||
fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
fprintf(file,"\taddl -%lu(%%%s),%%eax\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
fprintf(file,"\tsubl -%lu(%%%s),%%eax\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '*':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\timull -%lu(%%%s)\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '/':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tidivl -%lu(%%%s)\n",elem[1].vstackloc,gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Empty remaining variables/integers on the stack
|
||||
if(stack.size>0)
|
||||
{
|
||||
eval_elem e=*vec_at(&stack,stack.size-1,eval_elem*);
|
||||
int32_t value=0;
|
||||
/* size_t var_stackloc=0; */
|
||||
|
||||
if(e.type==EI32)
|
||||
{
|
||||
value=e.val.i32;
|
||||
fprintf(file,"\tmovl $%d,%%eax\n",value);
|
||||
}
|
||||
|
||||
else if(e.type==EIDENT)
|
||||
{
|
||||
bool found=false;
|
||||
|
||||
// Identify functions
|
||||
for(size_t j=0;j<gen->rootnode->funcs.size;++j)
|
||||
{
|
||||
if(strcmp(vec_at(&gen->rootnode->funcs,j,Func*)->name,e.val.name)==0)
|
||||
{
|
||||
e.type=EFUNC;
|
||||
fprintf(file,"\tcall %s\n",e.val.name);
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Identify variables
|
||||
if(!found)
|
||||
{
|
||||
for(size_t j=0;j<gen->stackptr->vars.size;++j)
|
||||
{
|
||||
if(strcmp(vec_at(&gen->stackptr->vars,j,Var*)->name,e.val.name)==0)
|
||||
{
|
||||
e.type=EVAR;
|
||||
e.vtype=vec_at(&gen->stackptr->vars,j,Var*)->type;
|
||||
e.vstackloc=vec_at(&gen->stackptr->vars,j,Var*)->stackloc;
|
||||
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",e.vstackloc,gen_x86_64_bp);
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found)
|
||||
err_log("%u: undeclared identifier '%s'",vec_at(&pn->tokens,0,Tok*)->line,e.val.name);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
vec_free(&rpn_stack);
|
||||
vec_free(&stack);
|
||||
}
|
||||
|
4
gen.h
4
gen.h
@ -27,6 +27,8 @@ enum EVAL_ELEM_TYPE {EI32,EIDENT,EVAR,EFUNC,EACC};
|
||||
typedef struct eval_elem
|
||||
{
|
||||
size_t type;
|
||||
VTYPE vtype;
|
||||
size_t vstackloc;
|
||||
union
|
||||
{
|
||||
int32_t i32;
|
||||
@ -37,6 +39,7 @@ typedef struct eval_elem
|
||||
/* static void gen_print_string(Gen*gen,const PNode*pn,FILE*file,const Str*str) */
|
||||
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);
|
||||
@ -44,6 +47,7 @@ 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);
|
||||
void gen_eval(Gen*gen,const PNode*pn,FILE*file);
|
||||
void gen_eval_analyze(const PNode*pn);
|
||||
void gen_free(Gen*gen);
|
||||
void gen_prolog(Gen*gen,const PNode*pn,FILE*file,size_t stacksize);
|
||||
|
4
mem.h
4
mem.h
@ -7,7 +7,7 @@
|
||||
#include"tok.h"
|
||||
|
||||
// Data types
|
||||
typedef enum{I8,I16,I32,I64,U8,U16,U32,U64,U8P,U16P,U32P,U64P}VTYPE;
|
||||
typedef enum{I8,I16,I32,I64,U8,U16,U32,U64,U8P,U16P,U32P,U64P,STR}VTYPE;
|
||||
|
||||
// Memory location
|
||||
// "Where do I look to find this value?"
|
||||
@ -40,7 +40,7 @@ typedef union Mem
|
||||
typedef struct Var
|
||||
{
|
||||
char*name;
|
||||
// VTYPE type;
|
||||
VTYPE type;
|
||||
// VLOC location;
|
||||
// size_t regnum; // REG: which register?
|
||||
bool is_arg; // Remember to move arg register to stack
|
||||
|
552
x86_64.c
552
x86_64.c
@ -14,555 +14,3 @@ const char*const gen_x86_64_pop_wordsize="popq";
|
||||
const char*const gen_x86_64_sp="rsp";
|
||||
const char*const gen_x86_64_bp="rbp";
|
||||
const char*const gen_x86_64_scratch1="r8d";
|
||||
|
||||
// Convert to infix, then evaluate
|
||||
void gen_x86_64_eval(Gen*gen,const PNode*pn,FILE*file)
|
||||
{
|
||||
Vec rpn_stack={0};
|
||||
Vec stack=vec_new(sizeof(eval_elem));
|
||||
|
||||
rpn_stack=gen_i2r(&pn->tokens);
|
||||
if(gen->showrpn)vec_print_tokens(&rpn_stack);
|
||||
|
||||
/* gen_eval_analyze(pn); */
|
||||
|
||||
// Evaluate RPN
|
||||
if(rpn_stack.buffer&&rpn_stack.size>0)
|
||||
{
|
||||
|
||||
for(size_t i=0;i<rpn_stack.size;++i)
|
||||
{
|
||||
|
||||
switch(vec_at(&rpn_stack,i,const Tok*)->type)
|
||||
{
|
||||
|
||||
case LKEYWORD:
|
||||
{
|
||||
if(strcmp("true",vec_at(&rpn_stack,i,const Tok*)->str.buffer)==0)
|
||||
{
|
||||
eval_elem e={.type=EI32,.val.i32=1};
|
||||
vec_push(&stack,&e);
|
||||
}
|
||||
else if(strcmp("false",vec_at(&rpn_stack,i,const Tok*)->str.buffer)==0)
|
||||
{
|
||||
eval_elem e={.type=EI32,.val.i32=0};
|
||||
vec_push(&stack,&e);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LIDENTIFIER:
|
||||
{
|
||||
eval_elem e={.type=EIDENT,.val.name=vec_at(&rpn_stack,i,const Tok*)->str.buffer};
|
||||
vec_push(&stack,&e);
|
||||
}
|
||||
break;
|
||||
|
||||
case LINTEGER:
|
||||
case LFLOAT:
|
||||
{
|
||||
int32_t d=atoi(vec_at(&rpn_stack,i,const Tok*)->str.buffer);
|
||||
eval_elem e={.type=EI32,.val.i32=d};
|
||||
vec_push(&stack,&e);
|
||||
}
|
||||
break;
|
||||
|
||||
case LOPERATOR:
|
||||
|
||||
// Get operands
|
||||
if(stack.size>1)
|
||||
{
|
||||
|
||||
eval_elem elem[2]={{0}};
|
||||
int32_t integers[2]={0};
|
||||
int32_t res=0;
|
||||
size_t var_stackloc[2]={0};
|
||||
size_t nops=2; // 2 unless unary operator
|
||||
|
||||
//if(vec_at(&rpn_stack,i,const Tok*)->str.buffer[0]=='!')
|
||||
if(strcmp("!",vec_at(&rpn_stack,i,const Tok*)->str.buffer)==0)
|
||||
nops=1;
|
||||
|
||||
// Get top two stack elements (variables, integers, etc.)
|
||||
for(size_t k=0;k<nops;++k)
|
||||
{
|
||||
|
||||
elem[k]=*vec_at(&stack,stack.size-1,eval_elem*);
|
||||
vec_pop(&stack);
|
||||
|
||||
if(elem[k].type==EIDENT)
|
||||
{
|
||||
bool found=false;
|
||||
|
||||
// Identify functions
|
||||
for(size_t j=0;j<gen->rootnode->funcs.size;++j)
|
||||
{
|
||||
if(strcmp(vec_at(&gen->rootnode->funcs,j,Func*)->name,elem[k].val.name)==0)
|
||||
{
|
||||
elem[k].type=EFUNC;
|
||||
fprintf(file,"\tcall %s\n",elem[k].val.name);
|
||||
{
|
||||
eval_elem e={.type=EACC,.val.i32=0};
|
||||
vec_push(&stack,&e);
|
||||
--k;
|
||||
}
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Identify variables
|
||||
if(!found)
|
||||
{
|
||||
for(size_t j=0;j<gen->stackptr->vars.size;++j)
|
||||
{
|
||||
if(strcmp(vec_at(&gen->stackptr->vars,j,Var*)->name,elem[k].val.name)==0)
|
||||
{
|
||||
elem[k].type=EVAR;
|
||||
var_stackloc[k]=vec_at(&gen->stackptr->vars,j,Var*)->stackloc;
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found)
|
||||
err_log("%u: undeclared identifier '%s'",vec_at(&pn->tokens,0,Tok*)->line,elem[k].val.name);
|
||||
}
|
||||
}
|
||||
else if(elem[k].type==EI32)
|
||||
integers[k]=elem[k].val.i32;
|
||||
}
|
||||
|
||||
// Debugging output
|
||||
/* if(elem[1].type==EVAR) */
|
||||
/* printf("'%s' ",elem[1].val.name); */
|
||||
/* else if(elem[1].type==EI32) */
|
||||
/* printf("%d ",elem[1].val.i32); */
|
||||
/* else */
|
||||
/* printf("acc "); */
|
||||
/* printf("%s ",vec_at(&rpn_stack,i,Tok*)->str.buffer); */
|
||||
/* if(elem[0].type==EVAR) */
|
||||
/* printf("'%s' ",elem[0].val.name); */
|
||||
/* else if(e1.type==EI32) */
|
||||
/* printf("%d ",e1.val.i32); */
|
||||
/* else */
|
||||
/* printf("acc "); */
|
||||
/* puts(""); */
|
||||
|
||||
// UNARY OPS
|
||||
if(nops==1)
|
||||
{
|
||||
switch(vec_at(&rpn_stack,i,const Tok*)->str.buffer[0])
|
||||
{
|
||||
case '!':
|
||||
if(elem[0].type==EVAR)
|
||||
{
|
||||
fprintf(file,"\tcmpl $0,-%lu(%%%s)\n",var_stackloc[0],gen_x86_64_bp);
|
||||
fprintf(file,"\tsete %%al\n");
|
||||
fprintf(file,"\tmovzbl %%al,%%eax\n");
|
||||
/* fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",var_stackloc[0],gen_x86_64_bp); */
|
||||
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
vec_push(&stack,&e);
|
||||
}
|
||||
else if(elem[0].type==EI32)
|
||||
{
|
||||
fprintf(file,"\tmovl $%d,%%eax\n",integers[0]);
|
||||
fprintf(file,"\tcmpl $0,%%eax\n");
|
||||
fprintf(file,"\tsete %%al\n");
|
||||
fprintf(file,"\tmovzbl %%al,%%eax\n");
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
vec_push(&stack,&e);
|
||||
}
|
||||
else if(elem[0].type==EACC)
|
||||
{
|
||||
fprintf(file,"\tcmpl $0,%%eax\n");
|
||||
fprintf(file,"\tsete %%al\n");
|
||||
fprintf(file,"\tmovzbl %%al,%%eax\n");
|
||||
//fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",var_stackloc[0],gen_x86_64_bp);
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
vec_push(&stack,&e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// INT OP INT
|
||||
else if(elem[0].type==EI32&&elem[1].type==EI32)
|
||||
{
|
||||
switch(vec_at(&rpn_stack,i,const Tok*)->str.buffer[0])
|
||||
{
|
||||
|
||||
case '+':res=integers[1]+integers[0];break;
|
||||
case '-':res=integers[1]-integers[0];break;
|
||||
case '*':res=integers[1]*integers[0];break;
|
||||
case '/':res=integers[1]/integers[0];break;
|
||||
|
||||
}
|
||||
eval_elem e={.type=EI32,.val.i32=res};
|
||||
vec_push(&stack,&e);
|
||||
}
|
||||
|
||||
// INT OP ACC
|
||||
else if(
|
||||
(elem[0].type==EACC && elem[1].type==EI32) ||
|
||||
(elem[0].type==EI32 && elem[1].type==EACC)
|
||||
)
|
||||
{
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
|
||||
if(elem[0].type==EI32)
|
||||
{
|
||||
eval_elem etmp=elem[0];
|
||||
elem[0]=elem[1];
|
||||
elem[1]=etmp;
|
||||
}
|
||||
|
||||
switch(vec_at(&rpn_stack,i,Tok*)->str.buffer[0])
|
||||
{
|
||||
|
||||
case '=':
|
||||
err_log("%u: cannot assign to rvalue '%d'",vec_at(&pn->tokens,0,Tok*)->line,elem[1].val.i32);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
fprintf(file,"\taddl $%d,%%eax\n",elem[1].val.i32);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
fprintf(file,"\tsubl $%d,%%eax\n",elem[1].val.i32);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '*':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tmovl $%d,%%%s\n",elem[1].val.i32,gen_x86_64_scratch1);
|
||||
fprintf(file,"\timull %%%s\n",gen_x86_64_scratch1);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '/':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tmovl $%d,%%%s\n",elem[1].val.i32,gen_x86_64_scratch1);
|
||||
fprintf(file,"\tidiv %%%s\n",gen_x86_64_scratch1);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// INT OP IDENT
|
||||
else if(elem[0].type==EVAR && elem[1].type==EI32)
|
||||
{
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
|
||||
switch(vec_at(&rpn_stack,i,Tok*)->str.buffer[0])
|
||||
{
|
||||
|
||||
case '=':
|
||||
err_log("%u: cannot assign to rvalue '%d'",vec_at(&pn->tokens,0,Tok*)->line,elem[1].val.i32);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[0],gen_x86_64_bp);
|
||||
fprintf(file,"\taddl $%d,%%eax\n",elem[1].val.i32);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[0],gen_x86_64_bp);
|
||||
fprintf(file,"\tsubl $%d,%%eax\n",elem[1].val.i32);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '*':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[0],gen_x86_64_bp);
|
||||
fprintf(file,"\tmovl $%d,%%%s\n",elem[1].val.i32,gen_x86_64_scratch1);
|
||||
fprintf(file,"\timull %%%s\n",gen_x86_64_scratch1);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '/':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[0],gen_x86_64_bp);
|
||||
fprintf(file,"\tmovl $%d,%%%s\n",elem[1].val.i32,gen_x86_64_scratch1);
|
||||
fprintf(file,"\tidivl %%%s\n",gen_x86_64_scratch1);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// IDENT OP INT
|
||||
else if(elem[0].type==EI32 && elem[1].type==EVAR)
|
||||
{
|
||||
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
|
||||
switch(vec_at(&rpn_stack,i,Tok*)->str.buffer[0])
|
||||
{
|
||||
|
||||
case '=':
|
||||
fprintf(file,"\tmovl $%d,-%lu(%%%s)\n",elem[0].val.i32,var_stackloc[1],gen_x86_64_bp);
|
||||
fprintf(file,"\tmovl $%d,%%eax\n",elem[0].val.i32);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[1],gen_x86_64_bp);
|
||||
fprintf(file,"\taddl $%d,%%eax\n",elem[0].val.i32);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[1],gen_x86_64_bp);
|
||||
fprintf(file,"\tsubl $%d,%%eax\n",elem[0].val.i32);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '*':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[1],gen_x86_64_bp);
|
||||
fprintf(file,"\tmovl $%d,%%%s\n",elem[0].val.i32,gen_x86_64_scratch1);
|
||||
fprintf(file,"\timul %%%s\n",gen_x86_64_scratch1);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '/':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[1],gen_x86_64_bp);
|
||||
fprintf(file,"\tmovl $%d,%%%s\n",elem[0].val.i32,gen_x86_64_scratch1);
|
||||
fprintf(file,"\tidivl %%%s\n",gen_x86_64_scratch1);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// IDENT OP IDENT
|
||||
else if(elem[0].type==EVAR && elem[1].type==EVAR)
|
||||
{
|
||||
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
|
||||
switch(vec_at(&rpn_stack,i,Tok*)->str.buffer[0])
|
||||
{
|
||||
|
||||
case '=':
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[0],gen_x86_64_bp);
|
||||
fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",var_stackloc[1],gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[1],gen_x86_64_bp);
|
||||
fprintf(file,"\taddl -%lu(%%%s),%%eax\n",var_stackloc[0],gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[1],gen_x86_64_bp);
|
||||
fprintf(file,"\tsubl -%lu(%%%s),%%eax\n",var_stackloc[0],gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '*':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[1],gen_x86_64_bp);
|
||||
fprintf(file,"\timull -%lu(%%%s)\n",var_stackloc[0],gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '/':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc[1],gen_x86_64_bp);
|
||||
fprintf(file,"\tidivl -%lu(%%%s)\n",var_stackloc[0],gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// IDENT OP ACC
|
||||
else if(elem[1].type==EACC && elem[0].type==EVAR)
|
||||
{
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
|
||||
switch(vec_at(&rpn_stack,i,Tok*)->str.buffer[0])
|
||||
{
|
||||
|
||||
case '=':
|
||||
fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",var_stackloc[0],gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
fprintf(file,"\taddl -%lu(%%%s),%%eax\n",var_stackloc[0],gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
fprintf(file,"\tsubl -%lu(%%%s),%%eax\n",var_stackloc[0],gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '*':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\timull -%lu(%%%s)\n",var_stackloc[0],gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '/':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tidivl -%lu(%%%s)\n",var_stackloc[0],gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// I32 OP ACC
|
||||
else if(elem[1].type==EACC && elem[0].type==EI32)
|
||||
{
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
|
||||
switch(vec_at(&rpn_stack,i,Tok*)->str.buffer[0])
|
||||
{
|
||||
|
||||
case '=':
|
||||
err_log("%u: cannot assign to accumulator",vec_at(&pn->tokens,0,Tok*)->line,e.val.name);
|
||||
/* vec_push(&stack,&e); */
|
||||
break;
|
||||
|
||||
case '+':
|
||||
fprintf(file,"\taddl $%d,%%eax\n",elem[0].val.i32);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
fprintf(file,"\tsubl $%d,%%eax\n",elem[0].val.i32);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '*':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\timull $%d\n",elem[0].val.i32);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '/':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tidivl $%d\n",elem[0].val.i32);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ACC OP IDENT
|
||||
else if(elem[1].type==EVAR && elem[0].type==EACC)
|
||||
{
|
||||
eval_elem e={.type=EACC,.val={0}};
|
||||
|
||||
switch(vec_at(&rpn_stack,i,Tok*)->str.buffer[0])
|
||||
{
|
||||
|
||||
case '=':
|
||||
fprintf(file,"\tmovl %%eax,-%lu(%%%s)\n",var_stackloc[1],gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '+':
|
||||
fprintf(file,"\taddl -%lu(%%%s),%%eax\n",var_stackloc[1],gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
fprintf(file,"\tsubl -%lu(%%%s),%%eax\n",var_stackloc[1],gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '*':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\timull -%lu(%%%s)\n",var_stackloc[1],gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
case '/':
|
||||
fprintf(file,"\txorl %%edx,%%edx\n");
|
||||
fprintf(file,"\tidivl -%lu(%%%s)\n",var_stackloc[1],gen_x86_64_bp);
|
||||
vec_push(&stack,&e);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Empty remaining variables/integers on the stack
|
||||
if(stack.size>0)
|
||||
{
|
||||
eval_elem e=*vec_at(&stack,stack.size-1,eval_elem*);
|
||||
int32_t value=0;
|
||||
size_t var_stackloc=0;
|
||||
|
||||
if(e.type==EI32)
|
||||
{
|
||||
value=e.val.i32;
|
||||
fprintf(file,"\tmovl $%d,%%eax\n",value);
|
||||
}
|
||||
|
||||
else if(e.type==EIDENT)
|
||||
{
|
||||
bool found=false;
|
||||
|
||||
// Identify functions
|
||||
for(size_t j=0;j<gen->rootnode->funcs.size;++j)
|
||||
{
|
||||
if(strcmp(vec_at(&gen->rootnode->funcs,j,Func*)->name,e.val.name)==0)
|
||||
{
|
||||
e.type=EFUNC;
|
||||
fprintf(file,"\tcall %s\n",e.val.name);
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Identify variables
|
||||
if(!found)
|
||||
{
|
||||
for(size_t j=0;j<gen->stackptr->vars.size;++j)
|
||||
{
|
||||
if(strcmp(vec_at(&gen->stackptr->vars,j,Var*)->name,e.val.name)==0)
|
||||
{
|
||||
e.type=EVAR;
|
||||
var_stackloc=vec_at(&gen->stackptr->vars,j,Var*)->stackloc;
|
||||
|
||||
fprintf(file,"\tmovl -%lu(%%%s),%%eax\n",var_stackloc,gen_x86_64_bp);
|
||||
found=true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!found)
|
||||
err_log("%u: undeclared identifier '%s'",vec_at(&pn->tokens,0,Tok*)->line,e.val.name);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
vec_free(&rpn_stack);
|
||||
vec_free(&stack);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user