diff --git a/day18/ex1-c.c b/day18/ex1-c.c new file mode 100644 index 0000000..3f6ddfb --- /dev/null +++ b/day18/ex1-c.c @@ -0,0 +1,168 @@ +/* ex1-c: Advent2020 game, day 18/task 1 + */ + +#include +#include +#include + +#define T_SUB (-1) +#define T_END (-2) +#define T_PLUS (-4) +#define T_MULT (-8) +#define T_ERR (-16) + +#define DIGIT(c) (((c) >= '0') && ((c) <= '9')) + +static long eval_expr(); + +static char *saveptr=NULL; +static long get_tok() //, char **saveptr, long *res) +{ + char *p, c; + long val=0; + + //printf("%s(%p, %p)\n", __func__, ptr, *saveptr); + p=saveptr; + //printf("%s: str=[%s]\n", __func__, p); + while (!val) { + c=*p; + //printf(" %s: c=[%c] str=[%s]\n", __func__, c, p); + switch (c) { + case ' ': + //case '\n': + break; + case '(': + val=T_SUB; + p++; + saveptr=p; + return eval_expr(); + break; + case ')': + case '\n': + val=T_END; + break; + case '*': + val=T_MULT; + break; + case '+': + val=T_PLUS; + break; + default: + if (! DIGIT(c)) { + val=T_ERR; + break; + } + while (DIGIT(c)) { + //printf(" int parse: c=[%c] val=%d\n", c, val); + val=(val*10 + c - '0'); + //printf(" -> val=%d\n", val); + p++; + c=*p; + } + p--; + break; + } + p++; + } + saveptr=p; + //printf("%s END: str=[%s] val=%ld p=[%s]\n", __func__, p, val, *saveptr); + return val; +} +static char* debug_tok(long tok) +{ + static char res[32]; + + switch (tok) { + case T_END: + sprintf (res, "T_END"); + break; + case T_PLUS: + sprintf (res, "T_PLUS"); + break; + case T_MULT: + sprintf (res, "T_MULT"); + break; + case T_ERR: + sprintf (res, "T_ERR"); + break; + case T_SUB: + sprintf (res, "T_SUB"); + break; + default: + sprintf (res, "TNUM[%ld]", tok); + break; + } + return res; +} + +static long eval_expr() +{ + long res=T_SUB, op=T_ERR; + long left=0; + + res=get_tok(); + left=res; + printf("--->EVAL TOK=: %ld tag=%s \n", res, debug_tok(res)); + while (res!=T_ERR && res!=T_END) { + switch (res) { + case T_END: + //printf ("RETURNING: %ld\n", left); + //return left; + goto end; + break; + case T_PLUS: + case T_MULT: + op=res; + break; + case T_ERR: + left=res; + //return T_ERR; + goto end; + break; + //case T_SUB: + //sprintf (res, "T_SUB"); + //break; + default: + //printf ("DEFAULT(left=%ld, res=%ld)\n" , left, res); + switch (op) { + case T_PLUS: + left+=res; + break; + case T_MULT: + left*=res; + break; + } + printf ("DEFAULT(left=%ld, res=%ld) - " , left, res); + printf ("New left: %ld\n", left); + break; + } + res=get_tok(); + printf("get_tok: %ld tag=%s \n", res, debug_tok(res)); + // printf("get_tok: %ld tag=%s \n", res, debug_tok(res)); + + } +end: + printf ("RETURNING: %ld\n", left); + return left; +} + +int main(ac, av) + int ac; + char **av; +{ + char line[1024]; + long res=0, tmp; + + while (fgets(line, sizeof line, stdin)) { + //*(line+strlen(line)-1)=0; + saveptr=line; + //printf("get_tok: %ld tag=%s \n", res, debug_tok(res)); + tmp=eval_expr(); + printf("EXPR=%s\n", debug_tok(tmp)); + res+=tmp; + //} while (res!=T_ERR && res!=T_END); + //res+=build_tree(line, &pnext); + } + printf("%s : res=%ld\n", *av, res); + exit (0); +}