diff --git a/main.c b/main.c index e03d567..d39256a 100644 --- a/main.c +++ b/main.c @@ -71,6 +71,14 @@ static struct Object *expr(); static struct Object *parens(); static struct Object *parens_part(); +/******** + * Eval * + ********/ + +static struct Object *eval(struct Object *program); + +static struct Object *func_sum(struct Object *numbers); + /******************* * Implementations * *******************/ @@ -89,6 +97,7 @@ int main() } struct Object *const program = parse(); + struct Object *const result = eval(program); exit(EXIT_SUCCESS); } @@ -357,7 +366,7 @@ struct Object *expr() case STATE_NUM: { struct Object *const object = prepare_object(TYPE_NUMBER); - object->s = tokens->val; + object->i = atoll(tokens->val); shift_token(); return object; } @@ -391,3 +400,60 @@ struct Object *parens_part() return object; } + +/******** + * Eval * + ********/ + +struct Object *eval(struct Object *const program) +{ + if (program->type != TYPE_PAIR) { + error("eval expects pair"); + return NULL; + } + + if (!program->a || program->a->type != TYPE_ATOM) { + error("eval expects atom"); + return NULL; + } + + if (strcmp(program->a->s, "sum") != 0) { + error("unknown func"); + return NULL; + } + + return func_sum(program->b); +} + +struct Object *func_sum(struct Object *const numbers) +{ + struct Object *const object = prepare_object(TYPE_NUMBER); + object->i = 0; + + if (numbers) { + if (numbers->type == TYPE_NUMBER) { + object->i = numbers->i; + } else if (numbers->type == TYPE_PAIR) { + if (numbers->a->type != TYPE_NUMBER) { + error("type error"); + return NULL; + } + + object->i = numbers->a->i; + + struct Object *b = eval(numbers->b); + + if (numbers->b->type != TYPE_NUMBER) { + error("type error"); + return NULL; + } + + object->i += b->i; + } else { + error("type error"); + return NULL; + } + } + + return object; +}