static unsigned count_conds_in_set( const char* memaddr, unsigned set ) { unsigned index = 0; unsigned count = 0; cheevos_cond_t cond; do { do { while ( *memaddr == ' ' || *memaddr == '_' || *memaddr == '|' || *memaddr == 'S' ) { memaddr++; /* Skip any chars up til the start of the achievement condition */ } parse_cond( &cond, &memaddr ); if ( index == set ) { count++; } } while ( *memaddr == '_' || *memaddr == 'R' || *memaddr == 'P' ); /* AND, ResetIf, PauseIf */ } while( *memaddr == 'S' ); /* Repeat for all subconditions if they exist */ return count; }
static void parse_memaddr( cheevos_cond_t* cond, const char* memaddr ) { do { do { while( *memaddr == ' ' || *memaddr == '_' || *memaddr == '|' || *memaddr == 'S' ) { memaddr++; /* Skip any chars up til the start of the achievement condition */ } parse_cond( cond++, &memaddr ); } while( *memaddr == '_' || *memaddr == 'R' || *memaddr == 'P' ); /* AND, ResetIf, PauseIf */ } while( *memaddr == 'S' ); /* Repeat for all subconditions if they exist */ }
void test_cond() { char tmp; t_quad_arg *r; FILE *inn = fopen("tests/test_cond.txt", "r"); init_fake_symbol_table(); while (!feof(inn)) { in = fopen("test.txt", "w+"); while ((tmp = fgetc(inn)) != '}' && tmp != -1) fprintf(in, "%c", tmp); if (tmp == EOF) break; if (tmp <= 31) continue; fseek(in, 0, SEEK_SET); idx = 0; printf("******************\n"); get_token_with_history(); r = (t_quad_arg *) malloc(sizeof(t_quad_arg)); parse_cond(r); print_quadruples(); fclose(in); remove("test.txt"); } }
struct single *parse_if() { int current = current_token; token t1, t2, t3, t4, t5; struct single *s; s = malloc(sizeof(struct single)); if (s == NULL) { perror("No memory"); return NULL; } t1 = get_token(); t2 = get_token(); if (t1.type != T_O || t2.type != T_RLY) { free(s); current_token = current; return NULL; } s->type = I_IF; s->data.ifelse.c = parse_cond(); if (s->data.ifelse.c == NULL) { free(s); parse_error("expected condition"); return NULL; } t1 = get_token(); t2 = get_token(); t3 = get_token(); t4 = get_token(); t5 = get_token(); if (t1.type != T_QMARK || t2.type != T_SEP || t3.type != T_YA || t4.type != T_RLY || t5.type != T_SEP) { free(s); parse_error("wrong YA RLY syntax"); return NULL; } s->data.ifelse.t = parse_instruction(); if (s->data.ifelse.t == NULL) { free(s); parse_error("expected instruction"); return NULL; } t1 = get_token(); t2 = get_token(); if (t1.type == T_SEP && t2.type == T_OIC) { s->data.ifelse.e = NULL; return s; } t3 = get_token(); t4 = get_token(); if (t1.type != T_SEP || t2.type != T_NO || t3.type != T_WAI || t4.type != T_SEP) { free(s); parse_error("wrong NO WAI syntax"); return NULL; } s->data.ifelse.e = parse_instruction(); if (s->data.ifelse.e == NULL) { free(s); parse_error("expected instruction"); return NULL; } t1 = get_token(); t2 = get_token(); if (t1.type != T_SEP || t2.type != T_OIC) { free(s); parse_error("expected OIC"); return NULL; } return s; }
struct cond* parse_cond() { int error = 0, current = current_token; struct cond *c; token t; c = malloc(sizeof(struct cond)); if (c == NULL) { perror("No memory"); return NULL; } t = get_token(); switch (t.type) { case T_NOT: c->type = C_NOT; c->data.conds.c1 = parse_cond(); if (c->data.conds.c1 == NULL) { error = 1; } break; case T_EITHER: case T_BOTH: if (t.type == T_BOTH) c->type = C_AND; else c->type = C_OR; c->data.conds.c1 = parse_cond(); if (c->data.conds.c1 == NULL) { error = 1; } else { t = get_token(); if (t.type != T_AN) { error = 1; free(c->data.conds.c1); parse_error("expected `AN`"); } else { c->data.conds.c2 = parse_cond(); if (c->data.conds.c2 == NULL) { error = 1; } } } break; case T_DIFFRINT: case T_SAEM: if (t.type == T_DIFFRINT) c->type = C_NEQ; else c->type = C_EQ; c->data.exprs.e1 = parse_expr(); if (c->data.exprs.e1 == NULL) { error = 1; } else { t = get_token(); if (t.type != T_AN) { error = 1; free(c->data.exprs.e1); parse_error("expected `AN`"); } else { c->data.exprs.e2 = parse_expr(); if (c->data.exprs.e2 == NULL) { error = 1; } } } break; default: unget_token(); parse_error("expected condition"); error = 1; } if (error == 1) { free(c); current_token = current; return NULL; } return c; }