#include "reader.h" #include #include static int parse_expression( memory_pool_t *pool, const char *input, int len, expression_t **out); static int parse_number( memory_pool_t *pool, const char *input, int len, expression_t **out) { int value = 0, used = 0; while (used < len && isdigit(input[used])) { value *= 10; value += input[used] - '0'; ++used; } if (0 == used) return 0; expression_t *number = allocate_expression(pool); number->is_number = true; number->number = value; *out = number; return used; } static int parse_factor( memory_pool_t *pool, const char *input, int len, expression_t **out) { if (len > 1 && input[0] == '(') { const int result = parse_expression(pool, input + 1, len - 1, out); if (0 == result) return 0; const int used = result + 1; return len >= used && input[used] == ')' ? used + 1 : 0; } else { return parse_number(pool, input, len, out); } } static int parse_term( memory_pool_t *pool, const char *input, int len, expression_t **out) { int result, used = 0; expression_t *expr; result = parse_factor(pool, input, len, &expr); if (0 >= result) return 0; used += result; while (len > used) { const expression_t *term0 = expr; operator_t operator; if ('*' == input[used]) operator= OPERATOR_MULTIPLY; else if ('/' == input[used]) operator= OPERATOR_DIVIDE; else break; ++used; expression_t *term1; result = parse_factor(pool, input + used, len - used, &term1); if (0 >= result) return 0; used += result; expr = allocate_expression(pool); expr->is_number = false; expr->application.operator= operator; expr->application.operands[0] = term0; expr->application.operands[1] = term1; } *out = expr; return used; } static int parse_expression( memory_pool_t *pool, const char *input, int len, expression_t **out) { int result, used = 0; expression_t *expr; result = parse_term(pool, input, len, &expr); if (0 >= result) return 0; used += result; while (len > used) { const expression_t *term0 = expr; operator_t operator; if ('+' == input[used]) operator= OPERATOR_ADD; else if ('-' == input[used]) operator= OPERATOR_SUBTRACT; else break; ++used; expression_t *term1; result = parse_term(pool, input + used, len - used, &term1); if (0 >= result) return 0; used += result; expr = allocate_expression(pool); expr->is_number = false; expr->application.operator= operator; expr->application.operands[0] = term0; expr->application.operands[1] = term1; } *out = expr; return used; } const expression_t * read_expression(memory_pool_t *pool, const char *input, int len) { expression_t *expression; parse_expression(pool, input, len, &expression); return expression; }