/* 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; } }