| @@ -1,5 +1,3 @@ | |||||
| (define nil ()) | |||||
| (define defmacro | (define defmacro | ||||
| (macro (@name @params :rest @body) | (macro (@name @params :rest @body) | ||||
| "Macro for creating macros with a more concise syntax." | "Macro for creating macros with a more concise syntax." | ||||
| @@ -3,6 +3,7 @@ define_array_list(struct Ast_Node*, Ast_Node); | |||||
| typedef enum { | typedef enum { | ||||
| Ast_Node_Type_Nil, | Ast_Node_Type_Nil, | ||||
| Ast_Node_Type_T, | |||||
| Ast_Node_Type_Symbol, | Ast_Node_Type_Symbol, | ||||
| Ast_Node_Type_Keyword, | Ast_Node_Type_Keyword, | ||||
| @@ -17,6 +18,7 @@ typedef enum { | |||||
| char* Ast_Node_Type_to_string(Ast_Node_Type type) { | char* Ast_Node_Type_to_string(Ast_Node_Type type) { | ||||
| switch (type) { | switch (type) { | ||||
| case(Ast_Node_Type_Nil): return "nil"; | case(Ast_Node_Type_Nil): return "nil"; | ||||
| case(Ast_Node_Type_T): return "t"; | |||||
| case(Ast_Node_Type_Number): return "number"; | case(Ast_Node_Type_Number): return "number"; | ||||
| case(Ast_Node_Type_String): return "string"; | case(Ast_Node_Type_String): return "string"; | ||||
| case(Ast_Node_Type_Symbol): return "symbol"; | case(Ast_Node_Type_Symbol): return "symbol"; | ||||
| @@ -233,6 +235,13 @@ Ast_Node* create_ast_node_nil() { | |||||
| return node; | return node; | ||||
| } | } | ||||
| Ast_Node* create_ast_node_t() { | |||||
| Ast_Node* node = new(Ast_Node); | |||||
| node->type = Ast_Node_Type_T; | |||||
| node->value.pair = nullptr; | |||||
| return node; | |||||
| } | |||||
| Ast_Node* create_ast_node_number(double number) { | Ast_Node* create_ast_node_number(double number) { | ||||
| Ast_Node* node = new(Ast_Node); | Ast_Node* node = new(Ast_Node); | ||||
| node->type = Ast_Node_Type_Number; | node->type = Ast_Node_Type_Number; | ||||
| @@ -43,7 +43,7 @@ bool ast_node_equal(Ast_Node* n1, Ast_Node* n2) { | |||||
| Ast_Node* built_in_equals(Ast_Node* operands) { | Ast_Node* built_in_equals(Ast_Node* operands) { | ||||
| if (operands->type == Ast_Node_Type_Nil) | if (operands->type == Ast_Node_Type_Nil) | ||||
| return create_ast_node_number(1); | |||||
| return create_ast_node_t(); | |||||
| Ast_Node* first = operands->value.pair->first; | Ast_Node* first = operands->value.pair->first; | ||||
| @@ -53,7 +53,7 @@ Ast_Node* built_in_equals(Ast_Node* operands) { | |||||
| operands = operands->value.pair->rest; | operands = operands->value.pair->rest; | ||||
| } | } | ||||
| return create_ast_node_number(1); | |||||
| return create_ast_node_t(); | |||||
| } | } | ||||
| Ast_Node* built_in_greater(Ast_Node* operands) { | Ast_Node* built_in_greater(Ast_Node* operands) { | ||||
| @@ -71,7 +71,7 @@ Ast_Node* built_in_greater(Ast_Node* operands) { | |||||
| operands = operands->value.pair->rest; | operands = operands->value.pair->rest; | ||||
| } | } | ||||
| return create_ast_node_number(1); | |||||
| return create_ast_node_t(); | |||||
| } | } | ||||
| Ast_Node* built_in_greater_equal(Ast_Node* operands) { | Ast_Node* built_in_greater_equal(Ast_Node* operands) { | ||||
| @@ -89,7 +89,7 @@ Ast_Node* built_in_greater_equal(Ast_Node* operands) { | |||||
| operands = operands->value.pair->rest; | operands = operands->value.pair->rest; | ||||
| } | } | ||||
| return create_ast_node_number(1); | |||||
| return create_ast_node_t(); | |||||
| } | } | ||||
| Ast_Node* built_in_less(Ast_Node* operands) { | Ast_Node* built_in_less(Ast_Node* operands) { | ||||
| @@ -107,7 +107,7 @@ Ast_Node* built_in_less(Ast_Node* operands) { | |||||
| operands = operands->value.pair->rest; | operands = operands->value.pair->rest; | ||||
| } | } | ||||
| return create_ast_node_number(1); | |||||
| return create_ast_node_t(); | |||||
| } | } | ||||
| Ast_Node* built_in_less_equal(Ast_Node* operands) { | Ast_Node* built_in_less_equal(Ast_Node* operands) { | ||||
| @@ -125,7 +125,7 @@ Ast_Node* built_in_less_equal(Ast_Node* operands) { | |||||
| operands = operands->value.pair->rest; | operands = operands->value.pair->rest; | ||||
| } | } | ||||
| return create_ast_node_number(1); | |||||
| return create_ast_node_t(); | |||||
| } | } | ||||
| Ast_Node* built_in_add(Ast_Node* operands) { | Ast_Node* built_in_add(Ast_Node* operands) { | ||||
| @@ -371,9 +371,9 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) { | |||||
| Ast_Node* ret = new(Ast_Node); | Ast_Node* ret = new(Ast_Node); | ||||
| switch (node->type) { | switch (node->type) { | ||||
| case Ast_Node_Type_T: | |||||
| case Ast_Node_Type_Nil: | case Ast_Node_Type_Nil: | ||||
| ret->type = Ast_Node_Type_Nil; | |||||
| return ret; | |||||
| return node; | |||||
| case Ast_Node_Type_Symbol: { | case Ast_Node_Type_Symbol: { | ||||
| Ast_Node* symbol; | Ast_Node* symbol; | ||||
| try { | try { | ||||
| @@ -478,7 +478,7 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) { | |||||
| } else if (bindings->type != Ast_Node_Type_Pair) { | } else if (bindings->type != Ast_Node_Type_Pair) { | ||||
| report_error(Error_Type_Ill_Formed_Arguments); | report_error(Error_Type_Ill_Formed_Arguments); | ||||
| } | } | ||||
| Ast_Node* sym = bindings->value.pair->first->value.pair->first; | Ast_Node* sym = bindings->value.pair->first->value.pair->first; | ||||
| if(sym->type != Ast_Node_Type_Symbol) { | if(sym->type != Ast_Node_Type_Symbol) { | ||||
| report_error(Error_Type_Ill_Formed_Arguments); | report_error(Error_Type_Ill_Formed_Arguments); | ||||
| @@ -533,7 +533,7 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) { | |||||
| if (!result) return create_ast_node_nil(); | if (!result) return create_ast_node_nil(); | ||||
| } | } | ||||
| return create_ast_node_number(1); | |||||
| return create_ast_node_t(); | |||||
| } | } | ||||
| case Built_In_Or: { | case Built_In_Or: { | ||||
| bool result = false; | bool result = false; | ||||
| @@ -546,7 +546,7 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) { | |||||
| } | } | ||||
| arguments = arguments->value.pair->rest; | arguments = arguments->value.pair->rest; | ||||
| if (result) return create_ast_node_number(1); | |||||
| if (result) return create_ast_node_t(); | |||||
| } | } | ||||
| return create_ast_node_nil(); | return create_ast_node_nil(); | ||||
| @@ -564,7 +564,7 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) { | |||||
| } | } | ||||
| if (truthy) | if (truthy) | ||||
| return create_ast_node_nil(); | return create_ast_node_nil(); | ||||
| return create_ast_node_number(1); | |||||
| return create_ast_node_t(); | |||||
| } | } | ||||
| case Built_In_If: { | case Built_In_If: { | ||||
| try { | try { | ||||
| @@ -29,7 +29,6 @@ void log_message(Log_Level type, char* message) { | |||||
| printf("%s: %s\n",prefix, message); | printf("%s: %s\n",prefix, message); | ||||
| } | } | ||||
| void panic(char* message) { | void panic(char* message) { | ||||
| log_message(Log_Level_Critical, message); | log_message(Log_Level_Critical, message); | ||||
| exit(1); | exit(1); | ||||
| @@ -40,6 +39,9 @@ void print(Ast_Node* node) { | |||||
| case (Ast_Node_Type_Nil): { | case (Ast_Node_Type_Nil): { | ||||
| printf("nil"); | printf("nil"); | ||||
| } break; | } break; | ||||
| case (Ast_Node_Type_T): { | |||||
| printf("t"); | |||||
| } break; | |||||
| case (Ast_Node_Type_Number): { | case (Ast_Node_Type_Number): { | ||||
| printf("%f", node->value.number->value); | printf("%f", node->value.number->value); | ||||
| } break; | } break; | ||||
| @@ -101,6 +101,13 @@ Ast_Node* parse_keyword(char* text, int* index_in_text) { | |||||
| Ast_Node* parse_symbol(char* text, int* index_in_text) { | Ast_Node* parse_symbol(char* text, int* index_in_text) { | ||||
| // we are now at the first char of the symbol | // we are now at the first char of the symbol | ||||
| char* str_symbol = read_atom(text, index_in_text); | char* str_symbol = read_atom(text, index_in_text); | ||||
| if (string_equal(str_symbol, "nil")) { | |||||
| return create_ast_node_nil(); | |||||
| } | |||||
| if (string_equal(str_symbol, "t")) { | |||||
| return create_ast_node_t(); | |||||
| } | |||||
| return create_ast_node_symbol(str_symbol); | return create_ast_node_symbol(str_symbol); | ||||
| } | } | ||||
| @@ -314,8 +314,7 @@ testresult test_built_in_and() { | |||||
| assert_no_error(error); | assert_no_error(error); | ||||
| assert_not_null(result); | assert_not_null(result); | ||||
| assert_equal_type(result, Ast_Node_Type_Number); | |||||
| assert_equal_double(result->value.number->value, 1); | |||||
| assert_equal_type(result, Ast_Node_Type_T); | |||||
| // a false case | // a false case | ||||
| char exp_string2[] = "(and () \"asd\" 4)"; | char exp_string2[] = "(and () \"asd\" 4)"; | ||||
| @@ -336,8 +335,7 @@ testresult test_built_in_or() { | |||||
| assert_no_error(error); | assert_no_error(error); | ||||
| assert_not_null(result); | assert_not_null(result); | ||||
| assert_equal_type(result, Ast_Node_Type_Number); | |||||
| assert_equal_double(result->value.number->value, 1); | |||||
| assert_equal_type(result, Ast_Node_Type_T); | |||||
| // a false case | // a false case | ||||
| char exp_string2[] = "(or () ())"; | char exp_string2[] = "(or () ())"; | ||||
| @@ -360,8 +358,7 @@ testresult test_built_in_not() { | |||||
| // a true case | // a true case | ||||
| assert_no_error(error); | assert_no_error(error); | ||||
| assert_not_null(result); | assert_not_null(result); | ||||
| assert_equal_type(result, Ast_Node_Type_Number); | |||||
| assert_equal_double(result->value.number->value, 1); | |||||
| assert_equal_type(result, Ast_Node_Type_T); | |||||
| // a false case | // a false case | ||||
| char exp_string2[] = "(not \"asd xD\")"; | char exp_string2[] = "(not \"asd xD\")"; | ||||