gen: basic dereference operator

This commit is contained in:
corey 2024-01-30 12:16:12 -06:00
parent f2140b02a3
commit 8b308ef51a
3 changed files with 41 additions and 10 deletions

47
gen.c
View File

@ -732,6 +732,18 @@ void gen_eval(Gen*gen,const PNode*pn,FILE*file)
}
}
// Find LSMUL, analyze context, convert
// to LSDEREF if used as unary op
for(size_t i=0;i<pn->tokens.size;++i)
{
if(vec_at(&pn->tokens,i,Tok*)->subtype==LSMUL)
{
Tok*prev=vec_at(&pn->tokens,i-1,Tok*);
if(i==0||(prev->type==LOPERATOR&&prev->subtype!=LRPAREN&&prev->subtype!=LLPAREN))
vec_at(&pn->tokens,i,Tok*)->subtype=LSDEREF;
}
}
rpn_stack=gen_i2r(&pn->tokens);
if(gen->showrpn)vec_print_tokens(&rpn_stack);
@ -802,14 +814,12 @@ void gen_eval(Gen*gen,const PNode*pn,FILE*file)
eval_elem elem[2]={{0}};
size_t nops=2; // 2 unless unary operator
if(vec_at(&rpn_stack,i,const Tok*)->subtype==LSNOT)
nops=1;
if(vec_at(&rpn_stack,i,const Tok*)->subtype==LSCOMMA)
nops=0;
if(vec_at(&rpn_stack,i,const Tok*)->subtype==LSREF)
nops=1;
// Find operators with nops != 2
switch(vec_at(&rpn_stack,i,const Tok*)->subtype)
{
case LSNOT:case LSREF:case LSDEREF:nops=1;break;
case LSCOMMA:nops=0;break;
}
// Get top two stack elements (variables, integers, etc.)
for(size_t k=0;k<nops;++k)
@ -996,6 +1006,8 @@ void gen_evalop(Gen*gen,PNode*pn,eval_elem*elem,size_t nops,Tok*curtok,FILE*file
sprintf(operator,"movl");
else if(curtok->subtype==LSREF)
sprintf(operator,ld.lea_wordsize);
else if(curtok->subtype==LSDEREF)
sprintf(operator,ld.mov_32);
// Print output
if(gen->showeval)
@ -1068,6 +1080,25 @@ void gen_evalop(Gen*gen,PNode*pn,eval_elem*elem,size_t nops,Tok*curtok,FILE*file
tmpelem=(eval_elem){.type=EE_ACC,.val={0}};
break;
// Dereference
case LSDEREF:
switch(elem[0].type)
{
case EE_VAR:
opos+=sprintf(output_buffer+opos,"\t%s %s,%%%s\n",ld.mov_wordsize,operands[0],ld.acc_wordsize);
opos+=sprintf(output_buffer+opos,"\t%s (%%%s),%%%s\n",operator,ld.acc_wordsize,ld.acc_32);
break;
default:
err_log("%u: cannot dereference '%s'",vec_at(&pn->tokens,0,Tok*)->line,operands[0]);
break;
}
tmpelem=(eval_elem){.type=EE_ACC,.val={0}};
break;
}
if(push_elem)

2
lex.c
View File

@ -12,7 +12,7 @@
const char*lextype_names[]={"LNONE","LIDENTIFIER","LINTEGER","LFLOAT","LSTRING","LOPERATOR","LKEYWORD","LCOMMENT","LMINUS","LFAKE",NULL};
const char*lextype_colors[]={"\033[0m","\033[0m","\033[36m","\033[35m","\033[32m","\033[0m","\033[33m","\033[34m"};
const char*lexsubtype_names[]={"LENDSTATEMENT","LASSIGN","LLPAREN","LRPAREN","LLCBRACE","LRCBRACE","LSMINUS","LADD","LSMUL","LSDIV","LSNOT","LSCOLON","LSCOMMA","LSREF",NULL};
const char*lexsubtype_names[]={"LENDSTATEMENT","LASSIGN","LLPAREN","LRPAREN","LLCBRACE","LRCBRACE","LSMINUS","LADD","LSMUL","LSDIV","LSNOT","LSCOLON","LSCOMMA","LSREF","LSDEREF",NULL};
static const char*operator_chars="-+*/=;(),.{}<>\\!:&";
static const char*keywords[]={"do","false","fn","for","if","let","ret","true","while","call","asm","ext",
/* type specifiers */

2
lex.h
View File

@ -13,7 +13,7 @@
#define vec_pushl(v,l) do{Tok x=l;vec_push(v,&x);}while(0)
enum LEXTYPE {LNONE=0, LIDENTIFIER, LINTEGER, LFLOAT, LSTRING, LOPERATOR, LKEYWORD, LCOMMENT, LMINUS, LFAKE, };
enum LEXSUBTYPE {LENDSTATEMENT=55, LASSIGN, LLPAREN, LRPAREN, LLCBRACE, LRCBRACE, LSMINUS, LADD, LSMUL, LSDIV, LSNOT, LSCOLON, LSCOMMA, LSREF, };
enum LEXSUBTYPE {LENDSTATEMENT=55, LASSIGN, LLPAREN, LRPAREN, LLCBRACE, LRCBRACE, LSMINUS, LADD, LSMUL, LSDIV, LSNOT, LSCOLON, LSCOMMA, LSREF, LSDEREF, };
extern const char*lextype_names[];
extern const char*lexsubtype_names[];
extern const char*lextype_colors[];