lr/run.c

252 lines
4.9 KiB
C

#include<stdio.h>
#include<stdlib.h>
#include"run.h"
#include"state.h"
void gen_run_eval(const Vec*tokens);
void gen_run(Gen*gen,const PNode*pn,FILE*file)
{
if(!pn)
{
err_log("NULL PNode passed to gen_run");
return;
}
if(!file)
{
err_log("NULL FILE* passed to gen_run");
return;
}
/* printf("pn: %p\nfile: %p\n",pn,file); */
switch(pn->type)
{
case PRET:
case PVARDECL:
case PEXPRESSION:
{
printf("%p: ",pn);
printf("%s\n",partype_names[pn->type]);
if(pn->tokens.size>0)
{
for(size_t i=0;i<pn->tokens.size;++i)
printf("%s ",vec_at(&pn->tokens,i,const Tok*)->str.buffer);
printf("\n");
gen_run_eval(&pn->tokens);
}
if(pn->pnodes.size>0)
{
for(size_t i=0;i<pn->pnodes.size;++i)
gen_run(gen,vec_at(&pn->pnodes,i,const PNode*),file);
printf("\n");
}
}
break;
default:
{
printf("%p: ",pn);
printf("%s\n",partype_names[pn->type]);
if(pn->tokens.size>0)
{
for(size_t i=0;i<pn->tokens.size;++i)
printf("%s ",vec_at(&pn->tokens,i,const Tok*)->str.buffer);
printf("\n");
}
if(pn->pnodes.size>0)
{
for(size_t i=0;i<pn->pnodes.size;++i)
gen_run(gen,vec_at(&pn->pnodes,i,const PNode*),file);
printf("\n");
}
}
break;
}
}
// Convert infix to RPN
// Vec<Tok>
Vec gen_run_i2r(const Vec*tokens)
{
Vec stack=vec_new(sizeof(const Tok));
Vec operators=vec_new(sizeof(const Tok));
int precedence[1024]={0};
precedence['(']=5;
precedence[')']=5;
precedence['+']=10;
precedence['-']=10;
precedence['*']=20;
precedence['/']=20;
if(tokens->size>0)
{
for(size_t i=0;i<tokens->size;++i)
{
// identifiers
if(vec_at(tokens,i,const Tok*)->type==LIDENTIFIER)
vec_push(&stack,vec_at(tokens,i,const Tok*));
// integers
if(vec_at(tokens,i,const Tok*)->type==LINTEGER)
vec_push(&stack,vec_at(tokens,i,const Tok*));
// operators
else if(vec_at(tokens,i,const Tok*)->type==LOPERATOR)
{
// '('
if(vec_at(tokens,i,const Tok*)->subtype==LLPAREN)
{
vec_push(&operators,vec_at(tokens,i,const Tok*));
}
// ')'
else if(vec_at(tokens,i,const Tok*)->subtype==LRPAREN)
{
while(operators.size>0&&vec_at(&operators,operators.size-1,const Tok*)->subtype!=LLPAREN)
{
const Tok*newtok=vec_at(&operators,operators.size-1,const Tok*);
vec_push(&stack,newtok);
vec_pop(&operators);
}
vec_pop(&operators);
}
// Default operators
else
{
// Pop operators from operators ==> stack
// who have higher precedence than current
// operator
while(operators.size>0&&precedence[(uint32_t)vec_at(&operators,operators.size-1,const Tok*)->str.buffer[0]]>=precedence[(uint32_t)vec_at(tokens,i,const Tok*)->str.buffer[0]])
{
const Tok*newtok=vec_at(&operators,operators.size-1,const Tok*);
vec_push(&stack,newtok);
vec_pop(&operators);
}
vec_push(&operators,vec_at(tokens,i,const Tok*));
}
}
}
}
while(operators.size>0)
{
const Tok*newtok=vec_at(&operators,operators.size-1,const Tok*);
vec_push(&stack,newtok);
vec_pop(&operators);
}
/* printf("s:"); */
/* vec_print_tokens(&stack); */
/* printf("o:"); */
/* vec_print_tokens(&operators); */
/* vec_free(&stack); */
vec_free(&operators);
// move ownership to caller
return stack;
}
// Convert to infix, then evaluate
void gen_run_eval(const Vec*tokens)
{
Vec rpn_stack={0};
Vec stack=vec_new(sizeof(const int));
rpn_stack=gen_run_i2r(tokens);
vec_print_tokens(&rpn_stack);
// Evaluate RPN
if(rpn_stack.buffer&&rpn_stack.size>0)
{
for(size_t i=0;i<rpn_stack.size;++i)
{
/* vec_print(&stack,"%d"); */
switch(vec_at(&rpn_stack,i,const Tok*)->type)
{
case LIDENTIFIER:
{
printf("ignoring '%s'\n",vec_at(&rpn_stack,i,const Tok*)->str.buffer);
}
break;
case LINTEGER:
{
int32_t d=atoi(vec_at(&rpn_stack,i,const Tok*)->str.buffer);
vec_pushi(&stack,d);
}
break;
case LOPERATOR:
/* printf("op:'%s'\n",vec_at(&rpn_stack,i,const Tok*)->str.buffer); */
if(stack.size>1)
{
int32_t i1=0;
int32_t i2=0;
int32_t res=0;
i1=*vec_at(&stack,stack.size-1,const int*);
vec_pop(&stack);
i2=*vec_at(&stack,stack.size-1,const int*);
vec_pop(&stack);
printf("%d%s%d\n",
i2,
vec_at(&rpn_stack,i,const Tok*)->str.buffer,
i1
);
switch(vec_at(&rpn_stack,i,const Tok*)->str.buffer[0])
{
case '+':res=i2+i1;break;
case '-':res=i2-i1;break;
case '*':res=i2*i1;break;
case '/':res=i2/i1;break;
}
vec_pushi(&stack,res);
}
/* else */
/* printf("stack less than 2\n"); */
break;
}
}
}
if(stack.size>0)
{
int32_t res=*vec_at(&stack,stack.size-1,const int32_t*);
printf("%d\n",res);
}
/* printf("s:"); */
/* vec_print(&stack,"%s"); */
vec_free(&rpn_stack);
vec_free(&stack);
}