|
- /* Ast_Node* apply_to_lambda () {} */
-
- /* Ast_Node* apply_to_built_in (Ast_Node* function, Ast_Node* arguments) { */
-
- /* } */
-
- Ast_Node* eval_expr(Ast_Node* node, Environment* env);
- int is_truthy (Ast_Node* expression, Environment* env);
-
- int list_length(Ast_Node* node) {
- if (node->type != Ast_Node_Type_Nil)
- return 0;
-
- if (node->type != Ast_Node_Type_Pair) {
- create_error(Error_Type_Type_Missmatch, node);
- return 0;
- }
-
- int len = 1;
- while (1) {
- break;
- }
-
- return len;
- }
-
- void eval_operands(Ast_Node* operands, Environment* env) {
- while (!error) {
- if (operands->type == Ast_Node_Type_Pair) {
- operands->value.pair->first = eval_expr(operands->value.pair->first, env);
- operands = operands->value.pair->rest;
- } else {
- return;
- }
- }
- }
-
- Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
- #define report_error(_type) \
- create_error(_type, node); \
- return NULL
-
- Ast_Node* ret = new(Ast_Node);
- switch (node->type) {
- case Ast_Node_Type_Nil:
- ret->type = Ast_Node_Type_Nil;
- return ret;
- case Ast_Node_Type_Symbol:
- return lookup_symbol(node->value.symbol, env);
- case Ast_Node_Type_Number:
- case Ast_Node_Type_String:
- return node;
-
- case Ast_Node_Type_Pair: {
- Ast_Node* operator = eval_expr(node->value.pair->first, env);
- Ast_Node* operands = node->value.pair->rest;
-
- // check for built ins functions
- if (operator->type == Ast_Node_Type_Built_In_Function) {
- char* operator_name = operator->value.built_in_function->identifier;
- if (string_equal("quote", operator_name)) {
- return node->value.pair->rest;
- } else if (string_equal("+", operator_name)) {
- eval_operands(operands, env);
- return built_in_add(operands);
- } else if (string_equal("-", operator_name)) {
- eval_operands(operands, env);
- return built_in_substract(operands);
- } else if (string_equal("*", operator_name)) {
- eval_operands(operands, env);
- return built_in_multiply(operands);
- } else if (string_equal("/", operator_name)) {
- eval_operands(operands, env);
- return built_in_divide(operands);
- } else if (string_equal("if", operator_name)) {
- if (list_length(operands) != 3) {
- report_error(Error_Type_Wrong_Number_Of_Arguments);
- }
-
- Ast_Node* condition = operands->value.pair->first;
- Ast_Node* then_part = operands->value.pair->rest;
- Ast_Node* else_part = then_part->value.pair->rest;
-
- if (is_truthy(condition, env))
- return eval_expr(then_part->value.pair->first, env);
- else
- return eval_expr(else_part->value.pair->first, env);
- /* } else if (string_equal("not", operator_name)) { */
-
- /* } else if (string_equal("and", operator_name)) { */
- /* } else if (string_equal("or", operator_name)) { */
- } else {
- report_error(Error_Type_Not_Yet_Implemented);
- }
- }
-
- // assume it's lambda function and evaluate the operands in
- // place
- eval_operands(operands, env);
- }
-
- default:
- report_error(Error_Type_Unknown_Error);
- }
- #undef report_error
- }
-
- int is_truthy (Ast_Node* expression, Environment* env) {
- Ast_Node* result = eval_expr(expression, env);
- switch (result->type) {
- case Ast_Node_Type_Nil: return 0;
- case Ast_Node_Type_Number: return result->value.number->value != 0;
- default: return 1;
- }
- }
|