| @@ -1,6 +1,6 @@ | |||||
| void assert_type (Ast_Node* node, Ast_Node_Type type) { | void assert_type (Ast_Node* node, Ast_Node_Type type) { | ||||
| if (!node) | if (!node) | ||||
| create_error(Error_Type_Unknown_Error, nullptr); | |||||
| create_error(Error_Type::Unknown_Error, nullptr); | |||||
| if (node->type == type) return; | if (node->type == type) return; | ||||
| create_error(Error_Type_Type_Missmatch, node->sourceCodeLocation); | |||||
| create_error(Error_Type::Type_Missmatch, node->sourceCodeLocation); | |||||
| } | } | ||||
| @@ -1,73 +1,71 @@ | |||||
| struct Ast_Node; | struct Ast_Node; | ||||
| define_array_list(struct Ast_Node*, Ast_Node); | define_array_list(struct Ast_Node*, Ast_Node); | ||||
| typedef enum { | |||||
| Ast_Node_Type_Nil, | |||||
| Ast_Node_Type_T, | |||||
| Ast_Node_Type_Symbol, | |||||
| Ast_Node_Type_Keyword, | |||||
| Ast_Node_Type_Number, | |||||
| Ast_Node_Type_String, | |||||
| Ast_Node_Type_Pair, | |||||
| Ast_Node_Type_Function, | |||||
| Ast_Node_Type_CFunction, | |||||
| } Ast_Node_Type; | |||||
| enum struct Ast_Node_Type { | |||||
| Nil, | |||||
| T, | |||||
| Symbol, | |||||
| Keyword, | |||||
| Number, | |||||
| String, | |||||
| Pair, | |||||
| Function, | |||||
| CFunction, | |||||
| }; | |||||
| 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_T): return "t"; | |||||
| case(Ast_Node_Type_Number): return "number"; | |||||
| case(Ast_Node_Type_String): return "string"; | |||||
| case(Ast_Node_Type_Symbol): return "symbol"; | |||||
| case(Ast_Node_Type_Keyword): return "keyword"; | |||||
| case(Ast_Node_Type_Function): return "function"; | |||||
| case(Ast_Node_Type_CFunction): return "C-function"; | |||||
| case(Ast_Node_Type_Pair): return "pair"; | |||||
| 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::String): return "string"; | |||||
| case(Ast_Node_Type::Symbol): return "symbol"; | |||||
| case(Ast_Node_Type::Keyword): return "keyword"; | |||||
| case(Ast_Node_Type::Function): return "function"; | |||||
| case(Ast_Node_Type::CFunction): return "C-function"; | |||||
| case(Ast_Node_Type::Pair): return "pair"; | |||||
| } | } | ||||
| return "unknown"; | return "unknown"; | ||||
| } | } | ||||
| typedef struct { | |||||
| struct Symbol { | |||||
| char* identifier; | char* identifier; | ||||
| } Symbol; | |||||
| }; | |||||
| typedef struct { | |||||
| struct Keyword { | |||||
| char* identifier; | char* identifier; | ||||
| } Keyword; | |||||
| }; | |||||
| typedef struct { | |||||
| struct Number { | |||||
| double value; | double value; | ||||
| } Number; | |||||
| }; | |||||
| typedef struct { | |||||
| struct String { | |||||
| char* value; | char* value; | ||||
| int length; | int length; | ||||
| } String; | |||||
| }; | |||||
| typedef struct { | |||||
| struct Pair { | |||||
| struct Ast_Node* first; | struct Ast_Node* first; | ||||
| struct Ast_Node* rest; | struct Ast_Node* rest; | ||||
| } Pair; | |||||
| }; | |||||
| typedef struct { | |||||
| struct Positional_Arguments { | |||||
| // TODO(Felix) use Ast_Node_symbols here instead, so we don't have | // TODO(Felix) use Ast_Node_symbols here instead, so we don't have | ||||
| // to convert them to strings and back to symbols | // to convert them to strings and back to symbols | ||||
| char** identifiers; | char** identifiers; | ||||
| int next_index; | int next_index; | ||||
| int length; | int length; | ||||
| } Positional_Arguments; | |||||
| }; | |||||
| typedef struct { | |||||
| struct Keyword_Arguments { | |||||
| char** identifiers; | char** identifiers; | ||||
| // values[i] will be nullptr if no defalut value was declared for | // values[i] will be nullptr if no defalut value was declared for | ||||
| // key identifiers[i] | // key identifiers[i] | ||||
| Ast_Node_Array_List* values; | Ast_Node_Array_List* values; | ||||
| int next_index; | int next_index; | ||||
| int length; | int length; | ||||
| } Keyword_Arguments; | |||||
| }; | |||||
| /* Ast_Node_Array_List* create_Ast_Node_Array_List(int initial_length); */ | /* Ast_Node_Array_List* create_Ast_Node_Array_List(int initial_length); */ | ||||
| @@ -112,7 +110,7 @@ void append_to_keyword_argument_list(Keyword_Arguments* args, | |||||
| } | } | ||||
| typedef struct { | |||||
| struct Function { | |||||
| bool is_macro; | bool is_macro; | ||||
| char* docstring; | char* docstring; | ||||
| Positional_Arguments* positional_arguments; | Positional_Arguments* positional_arguments; | ||||
| @@ -120,12 +118,13 @@ typedef struct { | |||||
| // rest_argument will be nullptr if no rest argument is declared | // rest_argument will be nullptr if no rest argument is declared | ||||
| char* rest_argument; | char* rest_argument; | ||||
| struct Ast_Node* body; // implicit prog | struct Ast_Node* body; // implicit prog | ||||
| } Function; | |||||
| }; | |||||
| struct Environment; | struct Environment; | ||||
| typedef struct { | |||||
| struct CFunction { | |||||
| std::function<Ast_Node*(Ast_Node*, Environment*)> function; | std::function<Ast_Node*(Ast_Node*, Environment*)> function; | ||||
| } CFunction; | |||||
| }; | |||||
| struct Ast_Node { | struct Ast_Node { | ||||
| Source_Code_Location* sourceCodeLocation; | Source_Code_Location* sourceCodeLocation; | ||||
| @@ -140,16 +139,14 @@ struct Ast_Node { | |||||
| CFunction* cfunction; | CFunction* cfunction; | ||||
| } value; | } value; | ||||
| }; | }; | ||||
| // was forward declarated | |||||
| typedef struct Ast_Node Ast_Node; | |||||
| typedef struct { | |||||
| struct Parsed_Arguments { | |||||
| Ast_Node_Array_List* positional_arguments; | Ast_Node_Array_List* positional_arguments; | ||||
| // TODO(Felix): Really use hashmap (keyword[sting] -> | // TODO(Felix): Really use hashmap (keyword[sting] -> | ||||
| // value[Ast_Node*]) here | // value[Ast_Node*]) here | ||||
| Ast_Node_Array_List* keyword_keys; | Ast_Node_Array_List* keyword_keys; | ||||
| Ast_Node_Array_List* keyword_values; | Ast_Node_Array_List* keyword_values; | ||||
| } Parsed_Arguments; | |||||
| }; | |||||
| Ast_Node* create_ast_node() { | Ast_Node* create_ast_node() { | ||||
| Ast_Node* node = new(Ast_Node); | Ast_Node* node = new(Ast_Node); | ||||
| @@ -159,21 +156,21 @@ Ast_Node* create_ast_node() { | |||||
| Ast_Node* create_ast_node_nil() { | Ast_Node* create_ast_node_nil() { | ||||
| Ast_Node* node = create_ast_node(); | Ast_Node* node = create_ast_node(); | ||||
| node->type = Ast_Node_Type_Nil; | |||||
| node->type = Ast_Node_Type::Nil; | |||||
| node->value.pair = nullptr; | node->value.pair = nullptr; | ||||
| return node; | return node; | ||||
| } | } | ||||
| Ast_Node* create_ast_node_t() { | Ast_Node* create_ast_node_t() { | ||||
| Ast_Node* node = create_ast_node(); | Ast_Node* node = create_ast_node(); | ||||
| node->type = Ast_Node_Type_T; | |||||
| node->type = Ast_Node_Type::T; | |||||
| node->value.pair = nullptr; | node->value.pair = nullptr; | ||||
| return node; | return node; | ||||
| } | } | ||||
| Ast_Node* create_ast_node_number(double number) { | Ast_Node* create_ast_node_number(double number) { | ||||
| Ast_Node* node = create_ast_node(); | Ast_Node* node = create_ast_node(); | ||||
| node->type = Ast_Node_Type_Number; | |||||
| node->type = Ast_Node_Type::Number; | |||||
| node->value.number = new(Number); | node->value.number = new(Number); | ||||
| node->value.number->value = number; | node->value.number->value = number; | ||||
| return node; | return node; | ||||
| @@ -181,7 +178,7 @@ Ast_Node* create_ast_node_number(double number) { | |||||
| Ast_Node* create_ast_node_string(char* str, int length) { | Ast_Node* create_ast_node_string(char* str, int length) { | ||||
| Ast_Node* node = create_ast_node(); | Ast_Node* node = create_ast_node(); | ||||
| node->type = Ast_Node_Type_String; | |||||
| node->type = Ast_Node_Type::String; | |||||
| node->value.string = new(String); | node->value.string = new(String); | ||||
| node->value.string->value = str; | node->value.string->value = str; | ||||
| node->value.string->length = length; | node->value.string->length = length; | ||||
| @@ -190,7 +187,7 @@ Ast_Node* create_ast_node_string(char* str, int length) { | |||||
| Ast_Node* create_ast_node_symbol(char* identifier) { | Ast_Node* create_ast_node_symbol(char* identifier) { | ||||
| Ast_Node* node = create_ast_node(); | Ast_Node* node = create_ast_node(); | ||||
| node->type = Ast_Node_Type_Symbol; | |||||
| node->type = Ast_Node_Type::Symbol; | |||||
| node->value.symbol = new(Symbol); | node->value.symbol = new(Symbol); | ||||
| node->value.symbol->identifier = identifier; | node->value.symbol->identifier = identifier; | ||||
| return node; | return node; | ||||
| @@ -198,7 +195,7 @@ Ast_Node* create_ast_node_symbol(char* identifier) { | |||||
| Ast_Node* create_ast_node_keyword(char* keyword) { | Ast_Node* create_ast_node_keyword(char* keyword) { | ||||
| Ast_Node* node = create_ast_node(); | Ast_Node* node = create_ast_node(); | ||||
| node->type = Ast_Node_Type_Keyword; | |||||
| node->type = Ast_Node_Type::Keyword; | |||||
| node->value.keyword = new(Keyword); | node->value.keyword = new(Keyword); | ||||
| node->value.keyword->identifier = keyword; | node->value.keyword->identifier = keyword; | ||||
| return node; | return node; | ||||
| @@ -206,7 +203,7 @@ Ast_Node* create_ast_node_keyword(char* keyword) { | |||||
| Ast_Node* create_ast_node_cfunction(std::function<Ast_Node*(Ast_Node*, Environment*)> function) { | Ast_Node* create_ast_node_cfunction(std::function<Ast_Node*(Ast_Node*, Environment*)> function) { | ||||
| Ast_Node* node = create_ast_node(); | Ast_Node* node = create_ast_node(); | ||||
| node->type = Ast_Node_Type_CFunction; | |||||
| node->type = Ast_Node_Type::CFunction; | |||||
| node->value.cfunction = new(CFunction); | node->value.cfunction = new(CFunction); | ||||
| node->value.cfunction->function = function; | node->value.cfunction->function = function; | ||||
| return node; | return node; | ||||
| @@ -214,7 +211,7 @@ Ast_Node* create_ast_node_cfunction(std::function<Ast_Node*(Ast_Node*, Environme | |||||
| Ast_Node* create_ast_node_pair(Ast_Node* first, Ast_Node* rest) { | Ast_Node* create_ast_node_pair(Ast_Node* first, Ast_Node* rest) { | ||||
| Ast_Node* node = create_ast_node(); | Ast_Node* node = create_ast_node(); | ||||
| node->type = Ast_Node_Type_Pair; | |||||
| node->type = Ast_Node_Type::Pair; | |||||
| node->value.pair = new(Pair); | node->value.pair = new(Pair); | ||||
| node->value.pair->first = first; | node->value.pair->first = first; | ||||
| node->value.pair->rest = rest; | node->value.pair->rest = rest; | ||||
| @@ -11,34 +11,34 @@ bool ast_node_equal(Ast_Node* n1, Ast_Node* n2) { | |||||
| return false; | return false; | ||||
| switch (n1->type) { | switch (n1->type) { | ||||
| case Ast_Node_Type_CFunction: | |||||
| case Ast_Node_Type::CFunction: | |||||
| // TODO(Felix): make comparing work again. | // TODO(Felix): make comparing work again. | ||||
| return false; | return false; | ||||
| /* return n1->value.built_in_function->type */ | /* return n1->value.built_in_function->type */ | ||||
| /* == n2->value.built_in_function->type; */ | /* == n2->value.built_in_function->type; */ | ||||
| case Ast_Node_Type_Function: | |||||
| case Ast_Node_Type::Function: | |||||
| // if they have the same pointer, true is | // if they have the same pointer, true is | ||||
| // returned a few lines above | // returned a few lines above | ||||
| return false; | return false; | ||||
| case Ast_Node_Type_Keyword: | |||||
| case Ast_Node_Type::Keyword: | |||||
| return string_equal( | return string_equal( | ||||
| n1->value.keyword->identifier, | n1->value.keyword->identifier, | ||||
| n2->value.keyword->identifier); | n2->value.keyword->identifier); | ||||
| case Ast_Node_Type_T: | |||||
| case Ast_Node_Type_Nil: | |||||
| case Ast_Node_Type::T: | |||||
| case Ast_Node_Type::Nil: | |||||
| return true; | return true; | ||||
| case Ast_Node_Type_Number: | |||||
| case Ast_Node_Type::Number: | |||||
| return | return | ||||
| n1->value.number->value == | n1->value.number->value == | ||||
| n2->value.number->value; | n2->value.number->value; | ||||
| case Ast_Node_Type_Pair: | |||||
| create_error(Error_Type_Not_Yet_Implemented, n1->sourceCodeLocation); | |||||
| case Ast_Node_Type::Pair: | |||||
| create_error(Error_Type::Not_Yet_Implemented, n1->sourceCodeLocation); | |||||
| return false; | return false; | ||||
| case Ast_Node_Type_String: | |||||
| case Ast_Node_Type::String: | |||||
| return string_equal( | return string_equal( | ||||
| n1->value.string->value, | n1->value.string->value, | ||||
| n2->value.string->value); | n2->value.string->value); | ||||
| case Ast_Node_Type_Symbol: | |||||
| case Ast_Node_Type::Symbol: | |||||
| return string_equal( | return string_equal( | ||||
| n1->value.symbol->identifier, | n1->value.symbol->identifier, | ||||
| n2->value.symbol->identifier); | n2->value.symbol->identifier); | ||||
| @@ -54,12 +54,12 @@ Ast_Node* built_in_equals(Ast_Node* arguments, Environment* env) { | |||||
| arguments = eval_arguments(arguments, env, &arguments_length); | arguments = eval_arguments(arguments, env, &arguments_length); | ||||
| } | } | ||||
| if (arguments->type == Ast_Node_Type_Nil) | |||||
| if (arguments->type == Ast_Node_Type::Nil) | |||||
| return create_ast_node_t(); | return create_ast_node_t(); | ||||
| Ast_Node* first = arguments->value.pair->first; | Ast_Node* first = arguments->value.pair->first; | ||||
| while (arguments->type == Ast_Node_Type_Pair) { | |||||
| while (arguments->type == Ast_Node_Type::Pair) { | |||||
| if (!ast_node_equal(arguments->value.pair->first, first)) | if (!ast_node_equal(arguments->value.pair->first, first)) | ||||
| return create_ast_node_nil(); | return create_ast_node_nil(); | ||||
| arguments = arguments->value.pair->rest; | arguments = arguments->value.pair->rest; | ||||
| @@ -76,9 +76,9 @@ Ast_Node* built_in_greater(Ast_Node* arguments, Environment* env) { | |||||
| double last_number = strtod("Inf", NULL); | double last_number = strtod("Inf", NULL); | ||||
| while (arguments->type == Ast_Node_Type_Pair) { | |||||
| while (arguments->type == Ast_Node_Type::Pair) { | |||||
| try { | try { | ||||
| assert_type(arguments->value.pair->first, Ast_Node_Type_Number); | |||||
| assert_type(arguments->value.pair->first, Ast_Node_Type::Number); | |||||
| } | } | ||||
| if (arguments->value.pair->first->value.number->value >= last_number) | if (arguments->value.pair->first->value.number->value >= last_number) | ||||
| @@ -99,9 +99,9 @@ Ast_Node* built_in_greater_equal(Ast_Node* arguments, Environment* env) { | |||||
| double last_number = strtod("Inf", NULL); | double last_number = strtod("Inf", NULL); | ||||
| while (arguments->type == Ast_Node_Type_Pair) { | |||||
| while (arguments->type == Ast_Node_Type::Pair) { | |||||
| try { | try { | ||||
| assert_type(arguments->value.pair->first, Ast_Node_Type_Number); | |||||
| assert_type(arguments->value.pair->first, Ast_Node_Type::Number); | |||||
| } | } | ||||
| if (arguments->value.pair->first->value.number->value > last_number) | if (arguments->value.pair->first->value.number->value > last_number) | ||||
| @@ -122,9 +122,9 @@ Ast_Node* built_in_less(Ast_Node* arguments, Environment* env) { | |||||
| double last_number = strtod("-Inf", NULL); | double last_number = strtod("-Inf", NULL); | ||||
| while (arguments->type == Ast_Node_Type_Pair) { | |||||
| while (arguments->type == Ast_Node_Type::Pair) { | |||||
| try { | try { | ||||
| assert_type(arguments->value.pair->first, Ast_Node_Type_Number); | |||||
| assert_type(arguments->value.pair->first, Ast_Node_Type::Number); | |||||
| } | } | ||||
| if (arguments->value.pair->first->value.number->value <= last_number) | if (arguments->value.pair->first->value.number->value <= last_number) | ||||
| @@ -145,9 +145,9 @@ Ast_Node* built_in_less_equal(Ast_Node* arguments, Environment* env) { | |||||
| double last_number = strtod("-Inf", NULL); | double last_number = strtod("-Inf", NULL); | ||||
| while (arguments->type == Ast_Node_Type_Pair) { | |||||
| while (arguments->type == Ast_Node_Type::Pair) { | |||||
| try { | try { | ||||
| assert_type(arguments->value.pair->first, Ast_Node_Type_Number); | |||||
| assert_type(arguments->value.pair->first, Ast_Node_Type::Number); | |||||
| } | } | ||||
| if (arguments->value.pair->first->value.number->value < last_number) | if (arguments->value.pair->first->value.number->value < last_number) | ||||
| @@ -167,9 +167,9 @@ Ast_Node* built_in_add(Ast_Node* arguments, Environment* env) { | |||||
| } | } | ||||
| double sum = 0; | double sum = 0; | ||||
| while (arguments->type == Ast_Node_Type_Pair) { | |||||
| while (arguments->type == Ast_Node_Type::Pair) { | |||||
| try { | try { | ||||
| assert_type(arguments->value.pair->first, Ast_Node_Type_Number); | |||||
| assert_type(arguments->value.pair->first, Ast_Node_Type::Number); | |||||
| } | } | ||||
| sum += arguments->value.pair->first->value.number->value; | sum += arguments->value.pair->first->value.number->value; | ||||
| arguments = arguments->value.pair->rest; | arguments = arguments->value.pair->rest; | ||||
| @@ -185,14 +185,14 @@ Ast_Node* built_in_substract(Ast_Node* arguments, Environment* env) { | |||||
| } | } | ||||
| try { | try { | ||||
| assert_type(arguments->value.pair->first, Ast_Node_Type_Number); | |||||
| assert_type(arguments->value.pair->first, Ast_Node_Type::Number); | |||||
| } | } | ||||
| double difference = arguments->value.pair->first->value.number->value; | double difference = arguments->value.pair->first->value.number->value; | ||||
| arguments = arguments->value.pair->rest; | arguments = arguments->value.pair->rest; | ||||
| while (arguments->type == Ast_Node_Type_Pair) { | |||||
| while (arguments->type == Ast_Node_Type::Pair) { | |||||
| try { | try { | ||||
| assert_type(arguments->value.pair->first, Ast_Node_Type_Number); | |||||
| assert_type(arguments->value.pair->first, Ast_Node_Type::Number); | |||||
| } | } | ||||
| difference -= arguments->value.pair->first->value.number->value; | difference -= arguments->value.pair->first->value.number->value; | ||||
| @@ -208,14 +208,14 @@ Ast_Node* built_in_multiply(Ast_Node* arguments, Environment* env) { | |||||
| } | } | ||||
| try { | try { | ||||
| assert_type(arguments->value.pair->first, Ast_Node_Type_Number); | |||||
| assert_type(arguments->value.pair->first, Ast_Node_Type::Number); | |||||
| } | } | ||||
| double product = arguments->value.pair->first->value.number->value; | double product = arguments->value.pair->first->value.number->value; | ||||
| arguments = arguments->value.pair->rest; | arguments = arguments->value.pair->rest; | ||||
| while (arguments->type == Ast_Node_Type_Pair) { | |||||
| while (arguments->type == Ast_Node_Type::Pair) { | |||||
| try { | try { | ||||
| assert_type(arguments->value.pair->first, Ast_Node_Type_Number); | |||||
| assert_type(arguments->value.pair->first, Ast_Node_Type::Number); | |||||
| } | } | ||||
| product *= arguments->value.pair->first->value.number->value; | product *= arguments->value.pair->first->value.number->value; | ||||
| @@ -231,14 +231,14 @@ Ast_Node* built_in_divide(Ast_Node* arguments, Environment* env) { | |||||
| } | } | ||||
| try { | try { | ||||
| assert_type(arguments->value.pair->first, Ast_Node_Type_Number); | |||||
| assert_type(arguments->value.pair->first, Ast_Node_Type::Number); | |||||
| } | } | ||||
| double quotient = arguments->value.pair->first->value.number->value; | double quotient = arguments->value.pair->first->value.number->value; | ||||
| arguments = arguments->value.pair->rest; | arguments = arguments->value.pair->rest; | ||||
| while (arguments->type == Ast_Node_Type_Pair) { | |||||
| while (arguments->type == Ast_Node_Type::Pair) { | |||||
| try { | try { | ||||
| assert_type(arguments->value.pair->first, Ast_Node_Type_Number); | |||||
| assert_type(arguments->value.pair->first, Ast_Node_Type::Number); | |||||
| } | } | ||||
| quotient /= arguments->value.pair->first->value.number->value; | quotient /= arguments->value.pair->first->value.number->value; | ||||
| @@ -263,7 +263,7 @@ Ast_Node* built_in_load(char* file_name, Environment* env) { | |||||
| } | } | ||||
| return result; | return result; | ||||
| } else { | } else { | ||||
| create_error(Error_Type_Unknown_Error, nullptr); | |||||
| create_error(Error_Type::Unknown_Error, nullptr); | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| } | } | ||||
| @@ -300,19 +300,19 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| } | } | ||||
| if (arguments_length != 2) { | if (arguments_length != 2) { | ||||
| report_error(Error_Type_Wrong_Number_Of_Arguments); | |||||
| report_error(Error_Type::Wrong_Number_Of_Arguments); | |||||
| } | } | ||||
| Ast_Node* symbol = arguments->value.pair->first; | Ast_Node* symbol = arguments->value.pair->first; | ||||
| if (symbol->type == Ast_Node_Type_Pair) { | |||||
| if (symbol->type == Ast_Node_Type::Pair) { | |||||
| try { | try { | ||||
| symbol = eval_expr(symbol, env); | symbol = eval_expr(symbol, env); | ||||
| } | } | ||||
| } | } | ||||
| if (symbol->type != Ast_Node_Type_Symbol) { | |||||
| report_error(Error_Type_Type_Missmatch); | |||||
| if (symbol->type != Ast_Node_Type::Symbol) { | |||||
| report_error(Error_Type::Type_Missmatch); | |||||
| } | } | ||||
| Ast_Node* value = arguments->value.pair->rest->value.pair->first; | Ast_Node* value = arguments->value.pair->rest->value.pair->first; | ||||
| @@ -330,19 +330,19 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| } | } | ||||
| if (arguments_length != 2) { | if (arguments_length != 2) { | ||||
| report_error(Error_Type_Wrong_Number_Of_Arguments); | |||||
| report_error(Error_Type::Wrong_Number_Of_Arguments); | |||||
| } | } | ||||
| Ast_Node* symbol = arguments->value.pair->first; | Ast_Node* symbol = arguments->value.pair->first; | ||||
| if (symbol->type == Ast_Node_Type_Pair) { | |||||
| if (symbol->type == Ast_Node_Type::Pair) { | |||||
| try { | try { | ||||
| symbol = eval_expr(symbol, env); | symbol = eval_expr(symbol, env); | ||||
| } | } | ||||
| } | } | ||||
| if (symbol->type != Ast_Node_Type_Symbol) { | |||||
| report_error(Error_Type_Type_Missmatch); | |||||
| if (symbol->type != Ast_Node_Type::Symbol) { | |||||
| report_error(Error_Type::Type_Missmatch); | |||||
| } | } | ||||
| Ast_Node* value = arguments->value.pair->rest->value.pair->first; | Ast_Node* value = arguments->value.pair->rest->value.pair->first; | ||||
| @@ -360,12 +360,12 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| } | } | ||||
| if (arguments_length != 2) | if (arguments_length != 2) | ||||
| report_error(Error_Type_Wrong_Number_Of_Arguments); | |||||
| report_error(Error_Type::Wrong_Number_Of_Arguments); | |||||
| if (evaluated_arguments->value.pair->first->type == Ast_Node_Type_Nil || | |||||
| evaluated_arguments->value.pair->first->type == Ast_Node_Type_Keyword) | |||||
| if (evaluated_arguments->value.pair->first->type == Ast_Node_Type::Nil || | |||||
| evaluated_arguments->value.pair->first->type == Ast_Node_Type::Keyword) | |||||
| { | { | ||||
| report_error(Error_Type_Type_Missmatch); | |||||
| report_error(Error_Type::Type_Missmatch); | |||||
| } | } | ||||
| Ast_Node* target = evaluated_arguments->value.pair->first; | Ast_Node* target = evaluated_arguments->value.pair->first; | ||||
| @@ -380,7 +380,7 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| } | } | ||||
| if (arguments_length != 2 && arguments_length != 3) { | if (arguments_length != 2 && arguments_length != 3) { | ||||
| report_error(Error_Type_Wrong_Number_Of_Arguments); | |||||
| report_error(Error_Type::Wrong_Number_Of_Arguments); | |||||
| } | } | ||||
| Ast_Node* condition = arguments->value.pair->first; | Ast_Node* condition = arguments->value.pair->first; | ||||
| @@ -411,16 +411,16 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| } | } | ||||
| if (arguments_length != 1) { | if (arguments_length != 1) { | ||||
| report_error(Error_Type_Wrong_Number_Of_Arguments); | |||||
| report_error(Error_Type::Wrong_Number_Of_Arguments); | |||||
| } | } | ||||
| return arguments->value.pair->first; | return arguments->value.pair->first; | ||||
| }); | }); | ||||
| defun("and", cLambda { | defun("and", cLambda { | ||||
| bool result = true; | bool result = true; | ||||
| while (arguments->type != Ast_Node_Type_Nil) { | |||||
| if (arguments->type != Ast_Node_Type_Pair) { | |||||
| report_error(Error_Type_Ill_Formed_List); | |||||
| while (arguments->type != Ast_Node_Type::Nil) { | |||||
| if (arguments->type != Ast_Node_Type::Pair) { | |||||
| report_error(Error_Type::Ill_Formed_List); | |||||
| } | } | ||||
| try { | try { | ||||
| result &= is_truthy(arguments->value.pair->first, env); | result &= is_truthy(arguments->value.pair->first, env); | ||||
| @@ -434,9 +434,9 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| }); | }); | ||||
| defun("or", cLambda { | defun("or", cLambda { | ||||
| bool result = false; | bool result = false; | ||||
| while (arguments->type != Ast_Node_Type_Nil) { | |||||
| if (arguments->type != Ast_Node_Type_Pair) { | |||||
| report_error(Error_Type_Ill_Formed_List); | |||||
| while (arguments->type != Ast_Node_Type::Nil) { | |||||
| if (arguments->type != Ast_Node_Type::Pair) { | |||||
| report_error(Error_Type::Ill_Formed_List); | |||||
| } | } | ||||
| try { | try { | ||||
| result |= is_truthy(arguments->value.pair->first, env); | result |= is_truthy(arguments->value.pair->first, env); | ||||
| @@ -454,7 +454,7 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| } | } | ||||
| if (arguments_length != 1) { | if (arguments_length != 1) { | ||||
| report_error(Error_Type_Wrong_Number_Of_Arguments); | |||||
| report_error(Error_Type::Wrong_Number_Of_Arguments); | |||||
| } | } | ||||
| bool truthy; | bool truthy; | ||||
| try { | try { | ||||
| @@ -470,7 +470,7 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| } | } | ||||
| if (arguments_length < 2) { | if (arguments_length < 2) { | ||||
| report_error(Error_Type_Wrong_Number_Of_Arguments); | |||||
| report_error(Error_Type::Wrong_Number_Of_Arguments); | |||||
| } | } | ||||
| Ast_Node* condition_part = arguments->value.pair->first; | Ast_Node* condition_part = arguments->value.pair->first; | ||||
| Ast_Node* condition; | Ast_Node* condition; | ||||
| @@ -481,7 +481,7 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| try { | try { | ||||
| condition = eval_expr(condition_part, env); | condition = eval_expr(condition_part, env); | ||||
| } | } | ||||
| if (condition->type == Ast_Node_Type_Nil) { | |||||
| if (condition->type == Ast_Node_Type::Nil) { | |||||
| break; | break; | ||||
| } | } | ||||
| try { | try { | ||||
| @@ -498,27 +498,27 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| } | } | ||||
| if (arguments_length < 1) | if (arguments_length < 1) | ||||
| report_error(Error_Type_Wrong_Number_Of_Arguments); | |||||
| report_error(Error_Type::Wrong_Number_Of_Arguments); | |||||
| Environment* let_env = create_child_environment(env, Environment_Type_Let); | |||||
| Environment* let_env = create_child_environment(env, Environment_Type::Let); | |||||
| Ast_Node* bindings = arguments->value.pair->first; | Ast_Node* bindings = arguments->value.pair->first; | ||||
| while (true) { | while (true) { | ||||
| if (bindings->type == Ast_Node_Type_Nil) { | |||||
| if (bindings->type == Ast_Node_Type::Nil) { | |||||
| break; | break; | ||||
| } else if (bindings->type != Ast_Node_Type_Pair) { | |||||
| report_error(Error_Type_Ill_Formed_Arguments); | |||||
| } else if (bindings->type != Ast_Node_Type::Pair) { | |||||
| 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) { | |||||
| report_error(Error_Type_Ill_Formed_Arguments); | |||||
| if(sym->type != Ast_Node_Type::Symbol) { | |||||
| report_error(Error_Type::Ill_Formed_Arguments); | |||||
| } | } | ||||
| Ast_Node* rest_sym = bindings->value.pair->first->value.pair->rest; | Ast_Node* rest_sym = bindings->value.pair->first->value.pair->rest; | ||||
| if (rest_sym->type != Ast_Node_Type_Pair) { | |||||
| report_error(Error_Type_Ill_Formed_Arguments); | |||||
| if (rest_sym->type != Ast_Node_Type::Pair) { | |||||
| report_error(Error_Type::Ill_Formed_Arguments); | |||||
| } | } | ||||
| if (rest_sym->value.pair->rest->type != Ast_Node_Type_Nil) { | |||||
| report_error(Error_Type_Ill_Formed_Arguments); | |||||
| if (rest_sym->value.pair->rest->type != Ast_Node_Type::Nil) { | |||||
| report_error(Error_Type::Ill_Formed_Arguments); | |||||
| } | } | ||||
| Ast_Node* value = eval_expr(rest_sym->value.pair->first, env); | Ast_Node* value = eval_expr(rest_sym->value.pair->first, env); | ||||
| @@ -535,7 +535,7 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| evaluated_arguments = eval_arguments(arguments, let_env, &arguments_length); | evaluated_arguments = eval_arguments(arguments, let_env, &arguments_length); | ||||
| } | } | ||||
| if (evaluated_arguments->type == Ast_Node_Type_Nil) | |||||
| if (evaluated_arguments->type == Ast_Node_Type::Nil) | |||||
| return evaluated_arguments; | return evaluated_arguments; | ||||
| // skip to the last evaluated operand and return it, | // skip to the last evaluated operand and return it, | ||||
| @@ -543,7 +543,7 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| // manually, because we want to increase code reuse, | // manually, because we want to increase code reuse, | ||||
| // but at the cost that we have to find the end of the | // but at the cost that we have to find the end of the | ||||
| // list again | // list again | ||||
| while (evaluated_arguments->value.pair->rest->type == Ast_Node_Type_Pair) { | |||||
| while (evaluated_arguments->value.pair->rest->type == Ast_Node_Type::Pair) { | |||||
| evaluated_arguments = evaluated_arguments->value.pair->rest; | evaluated_arguments = evaluated_arguments->value.pair->rest; | ||||
| } | } | ||||
| return evaluated_arguments->value.pair->first; | return evaluated_arguments->value.pair->first; | ||||
| @@ -558,7 +558,7 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| } | } | ||||
| if (arguments_length == 0) | if (arguments_length == 0) | ||||
| report_error(Error_Type_Wrong_Number_Of_Arguments); | |||||
| report_error(Error_Type::Wrong_Number_Of_Arguments); | |||||
| Function* function = new(Function); | Function* function = new(Function); | ||||
| /* if (lispOperator->value.built_in_function->type == Built_In_Macro) { */ | /* if (lispOperator->value.built_in_function->type == Built_In_Macro) { */ | ||||
| @@ -568,9 +568,9 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| /* } */ | /* } */ | ||||
| // if parameters were specified | // if parameters were specified | ||||
| if (arguments->value.pair->first->type != Ast_Node_Type_Nil) { | |||||
| if (arguments->value.pair->first->type != Ast_Node_Type::Nil) { | |||||
| try { | try { | ||||
| assert_type(arguments->value.pair->first, Ast_Node_Type_Pair); | |||||
| assert_type(arguments->value.pair->first, Ast_Node_Type::Pair); | |||||
| } | } | ||||
| try { | try { | ||||
| parse_argument_list(arguments->value.pair->first, function); | parse_argument_list(arguments->value.pair->first, function); | ||||
| @@ -583,7 +583,7 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| arguments = arguments->value.pair->rest; | arguments = arguments->value.pair->rest; | ||||
| // if there is a docstring, use it | // if there is a docstring, use it | ||||
| if (arguments->value.pair->first->type == Ast_Node_Type_String) { | |||||
| if (arguments->value.pair->first->type == Ast_Node_Type::String) { | |||||
| function->docstring = arguments->value.pair->first->value.string->value; | function->docstring = arguments->value.pair->first->value.string->value; | ||||
| arguments = arguments->value.pair->rest; | arguments = arguments->value.pair->rest; | ||||
| } else { | } else { | ||||
| @@ -597,7 +597,7 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| arguments); | arguments); | ||||
| Ast_Node* ret = new(Ast_Node); | Ast_Node* ret = new(Ast_Node); | ||||
| ret->type = Ast_Node_Type_Function; | |||||
| ret->type = Ast_Node_Type::Function; | |||||
| ret->value.function = function; | ret->value.function = function; | ||||
| return ret; | return ret; | ||||
| }); | }); | ||||
| @@ -611,15 +611,15 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| } | } | ||||
| if (arguments_length == 0) | if (arguments_length == 0) | ||||
| report_error(Error_Type_Wrong_Number_Of_Arguments); | |||||
| report_error(Error_Type::Wrong_Number_Of_Arguments); | |||||
| Function* function = new(Function); | Function* function = new(Function); | ||||
| function->is_macro = true; | function->is_macro = true; | ||||
| // if parameters were specified | // if parameters were specified | ||||
| if (arguments->value.pair->first->type != Ast_Node_Type_Nil) { | |||||
| if (arguments->value.pair->first->type != Ast_Node_Type::Nil) { | |||||
| try { | try { | ||||
| assert_type(arguments->value.pair->first, Ast_Node_Type_Pair); | |||||
| assert_type(arguments->value.pair->first, Ast_Node_Type::Pair); | |||||
| } | } | ||||
| try { | try { | ||||
| parse_argument_list(arguments->value.pair->first, function); | parse_argument_list(arguments->value.pair->first, function); | ||||
| @@ -632,7 +632,7 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| arguments = arguments->value.pair->rest; | arguments = arguments->value.pair->rest; | ||||
| // if there is a docstring, use it | // if there is a docstring, use it | ||||
| if (arguments->value.pair->first->type == Ast_Node_Type_String) { | |||||
| if (arguments->value.pair->first->type == Ast_Node_Type::String) { | |||||
| function->docstring = arguments->value.pair->first->value.string->value; | function->docstring = arguments->value.pair->first->value.string->value; | ||||
| arguments = arguments->value.pair->rest; | arguments = arguments->value.pair->rest; | ||||
| } else { | } else { | ||||
| @@ -646,7 +646,7 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| arguments); | arguments); | ||||
| Ast_Node* ret = new(Ast_Node); | Ast_Node* ret = new(Ast_Node); | ||||
| ret->type = Ast_Node_Type_Function; | |||||
| ret->type = Ast_Node_Type::Function; | |||||
| ret->value.function = function; | ret->value.function = function; | ||||
| return ret; | return ret; | ||||
| }); | }); | ||||
| @@ -655,7 +655,7 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | ||||
| } | } | ||||
| if (arguments_length != 1) { | if (arguments_length != 1) { | ||||
| report_error(Error_Type_Wrong_Number_Of_Arguments); | |||||
| report_error(Error_Type::Wrong_Number_Of_Arguments); | |||||
| } | } | ||||
| Ast_Node* result; | Ast_Node* result; | ||||
| try { | try { | ||||
| @@ -670,7 +670,7 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | ||||
| } | } | ||||
| if (evaluated_arguments->type == Ast_Node_Type_Nil) | |||||
| if (evaluated_arguments->type == Ast_Node_Type::Nil) | |||||
| return evaluated_arguments; | return evaluated_arguments; | ||||
| // skip to the last evaluated operand and return it, | // skip to the last evaluated operand and return it, | ||||
| @@ -678,7 +678,7 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| // manually, because we want to increase code reuse, | // manually, because we want to increase code reuse, | ||||
| // but at the cost that we have to find the end of the | // but at the cost that we have to find the end of the | ||||
| // list again | // list again | ||||
| while (evaluated_arguments->value.pair->rest->type == Ast_Node_Type_Pair) { | |||||
| while (evaluated_arguments->value.pair->rest->type == Ast_Node_Type::Pair) { | |||||
| evaluated_arguments = evaluated_arguments->value.pair->rest; | evaluated_arguments = evaluated_arguments->value.pair->rest; | ||||
| } | } | ||||
| return evaluated_arguments->value.pair->first; | return evaluated_arguments->value.pair->first; | ||||
| @@ -699,7 +699,7 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| // BUG(Felix): Why is arguments_length for '(1 (2)) == 3 and not 2?? | // BUG(Felix): Why is arguments_length for '(1 (2)) == 3 and not 2?? | ||||
| /* if (arguments_length != 2) { */ | /* if (arguments_length != 2) { */ | ||||
| if (list_length(evaluated_arguments) != 2) { | if (list_length(evaluated_arguments) != 2) { | ||||
| report_error(Error_Type_Wrong_Number_Of_Arguments); | |||||
| report_error(Error_Type::Wrong_Number_Of_Arguments); | |||||
| } | } | ||||
| return create_ast_node_pair(evaluated_arguments->value.pair->first, evaluated_arguments->value.pair->rest->value.pair->first); | return create_ast_node_pair(evaluated_arguments->value.pair->first, evaluated_arguments->value.pair->rest->value.pair->first); | ||||
| }); | }); | ||||
| @@ -708,12 +708,12 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | ||||
| } | } | ||||
| if (arguments_length != 1) { | if (arguments_length != 1) { | ||||
| report_error(Error_Type_Wrong_Number_Of_Arguments); | |||||
| report_error(Error_Type::Wrong_Number_Of_Arguments); | |||||
| } | } | ||||
| if (evaluated_arguments->value.pair->first->type == Ast_Node_Type_Nil) | |||||
| if (evaluated_arguments->value.pair->first->type == Ast_Node_Type::Nil) | |||||
| return create_ast_node_nil(); | return create_ast_node_nil(); | ||||
| if (evaluated_arguments->value.pair->first->type != Ast_Node_Type_Pair) | |||||
| report_error(Error_Type_Type_Missmatch); | |||||
| if (evaluated_arguments->value.pair->first->type != Ast_Node_Type::Pair) | |||||
| report_error(Error_Type::Type_Missmatch); | |||||
| return evaluated_arguments->value.pair->first->value.pair->first; | return evaluated_arguments->value.pair->first->value.pair->first; | ||||
| }); | }); | ||||
| @@ -722,12 +722,12 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | ||||
| } | } | ||||
| if (arguments_length != 1) { | if (arguments_length != 1) { | ||||
| report_error(Error_Type_Wrong_Number_Of_Arguments); | |||||
| report_error(Error_Type::Wrong_Number_Of_Arguments); | |||||
| } | } | ||||
| if (evaluated_arguments->value.pair->first->type == Ast_Node_Type_Nil) | |||||
| if (evaluated_arguments->value.pair->first->type == Ast_Node_Type::Nil) | |||||
| return create_ast_node_nil(); | return create_ast_node_nil(); | ||||
| if (evaluated_arguments->value.pair->first->type != Ast_Node_Type_Pair) | |||||
| report_error(Error_Type_Type_Missmatch); | |||||
| if (evaluated_arguments->value.pair->first->type != Ast_Node_Type::Pair) | |||||
| report_error(Error_Type::Type_Missmatch); | |||||
| return evaluated_arguments->value.pair->first->value.pair->rest; | return evaluated_arguments->value.pair->first->value.pair->rest; | ||||
| }); | }); | ||||
| @@ -736,24 +736,24 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | ||||
| } | } | ||||
| if (arguments_length != 1) { | if (arguments_length != 1) { | ||||
| report_error(Error_Type_Wrong_Number_Of_Arguments); | |||||
| report_error(Error_Type::Wrong_Number_Of_Arguments); | |||||
| } | } | ||||
| Ast_Node_Type type = evaluated_arguments->value.pair->first->type; | |||||
| Ast_Node_Type type = evaluated_arguments->value.pair->first->type; | |||||
| switch (type) { | switch (type) { | ||||
| case Ast_Node_Type_CFunction: return create_ast_node_keyword("cfunction"); | |||||
| case Ast_Node_Type_Function: { | |||||
| case Ast_Node_Type::CFunction: return create_ast_node_keyword("cfunction"); | |||||
| case Ast_Node_Type::Function: { | |||||
| if (evaluated_arguments->value.pair->first->value.function->is_macro) | if (evaluated_arguments->value.pair->first->value.function->is_macro) | ||||
| return create_ast_node_keyword("dynamic-macro"); | return create_ast_node_keyword("dynamic-macro"); | ||||
| return create_ast_node_keyword("dynamic-function"); | return create_ast_node_keyword("dynamic-function"); | ||||
| } | } | ||||
| case Ast_Node_Type_Keyword: return create_ast_node_keyword("keyword"); | |||||
| case Ast_Node_Type_Nil: return create_ast_node_keyword("nil"); | |||||
| case Ast_Node_Type_T: return create_ast_node_keyword("t"); | |||||
| case Ast_Node_Type_Number: return create_ast_node_keyword("number"); | |||||
| case Ast_Node_Type_Pair: return create_ast_node_keyword("pair"); | |||||
| case Ast_Node_Type_String: return create_ast_node_keyword("string"); | |||||
| case Ast_Node_Type_Symbol: return create_ast_node_keyword("symbol"); | |||||
| case Ast_Node_Type::Keyword: return create_ast_node_keyword("keyword"); | |||||
| case Ast_Node_Type::Nil: return create_ast_node_keyword("nil"); | |||||
| case Ast_Node_Type::T: return create_ast_node_keyword("t"); | |||||
| case Ast_Node_Type::Number: return create_ast_node_keyword("number"); | |||||
| case Ast_Node_Type::Pair: return create_ast_node_keyword("pair"); | |||||
| case Ast_Node_Type::String: return create_ast_node_keyword("string"); | |||||
| case Ast_Node_Type::Symbol: return create_ast_node_keyword("symbol"); | |||||
| } | } | ||||
| return create_ast_node_keyword("unknown"); | return create_ast_node_keyword("unknown"); | ||||
| }); | }); | ||||
| @@ -763,7 +763,7 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| } | } | ||||
| if (arguments_length != 1) { | if (arguments_length != 1) { | ||||
| report_error(Error_Type_Wrong_Number_Of_Arguments); | |||||
| report_error(Error_Type::Wrong_Number_Of_Arguments); | |||||
| } | } | ||||
| print(arguments->value.pair->first); | print(arguments->value.pair->first); | ||||
| @@ -780,7 +780,7 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| printf("\n"); | printf("\n"); | ||||
| // just make sure type was not redefined and | // just make sure type was not redefined and | ||||
| // returns something that is not a keyword | // returns something that is not a keyword | ||||
| if (type->type == Ast_Node_Type_Keyword && | |||||
| if (type->type == Ast_Node_Type::Keyword && | |||||
| (string_equal(type->value.keyword->identifier, "dynamic-function") || | (string_equal(type->value.keyword->identifier, "dynamic-function") || | ||||
| string_equal(type->value.keyword->identifier, "dynamic-macro"))) | string_equal(type->value.keyword->identifier, "dynamic-macro"))) | ||||
| { | { | ||||
| @@ -836,7 +836,7 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | ||||
| } | } | ||||
| if (arguments_length != 1) { | if (arguments_length != 1) { | ||||
| report_error(Error_Type_Wrong_Number_Of_Arguments); | |||||
| report_error(Error_Type::Wrong_Number_Of_Arguments); | |||||
| } | } | ||||
| print(evaluated_arguments->value.pair->first); | print(evaluated_arguments->value.pair->first); | ||||
| printf("\n"); | printf("\n"); | ||||
| @@ -848,12 +848,12 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| } | } | ||||
| if (arguments_length > 1) { | if (arguments_length > 1) { | ||||
| report_error(Error_Type_Wrong_Number_Of_Arguments); | |||||
| report_error(Error_Type::Wrong_Number_Of_Arguments); | |||||
| } | } | ||||
| if (arguments_length == 1) { | if (arguments_length == 1) { | ||||
| Ast_Node* prompt = evaluated_arguments->value.pair->first; | Ast_Node* prompt = evaluated_arguments->value.pair->first; | ||||
| /* if (prompt->type == Ast_Node_Type_String) */ | |||||
| /* if (prompt->type == Ast_Node_Type::String) */ | |||||
| /* printf("%s", prompt->value.string->value); */ | /* printf("%s", prompt->value.string->value); */ | ||||
| /* else */ | /* else */ | ||||
| print(evaluated_arguments->value.pair->first); | print(evaluated_arguments->value.pair->first); | ||||
| @@ -867,13 +867,13 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| } | } | ||||
| if (arguments_length > 1) { | if (arguments_length > 1) { | ||||
| report_error(Error_Type_Wrong_Number_Of_Arguments); | |||||
| report_error(Error_Type::Wrong_Number_Of_Arguments); | |||||
| } | } | ||||
| if (arguments_length == 1) { | if (arguments_length == 1) { | ||||
| Ast_Node* error_code = evaluated_arguments->value.pair->first; | Ast_Node* error_code = evaluated_arguments->value.pair->first; | ||||
| if (error_code->type != Ast_Node_Type_Number) | |||||
| report_error(Error_Type_Type_Missmatch); | |||||
| if (error_code->type != Ast_Node_Type::Number) | |||||
| report_error(Error_Type::Type_Missmatch); | |||||
| exit((int)error_code->value.number->value); | exit((int)error_code->value.number->value); | ||||
| } | } | ||||
| @@ -892,7 +892,7 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| } | } | ||||
| if (arguments_length != 2) { | if (arguments_length != 2) { | ||||
| report_error(Error_Type_Wrong_Number_Of_Arguments); | |||||
| report_error(Error_Type::Wrong_Number_Of_Arguments); | |||||
| } | } | ||||
| Ast_Node* try_part = arguments->value.pair->first; | Ast_Node* try_part = arguments->value.pair->first; | ||||
| @@ -914,10 +914,10 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| } | } | ||||
| if (arguments_length != 1) | if (arguments_length != 1) | ||||
| report_error(Error_Type_Wrong_Number_Of_Arguments); | |||||
| report_error(Error_Type::Wrong_Number_Of_Arguments); | |||||
| if (evaluated_arguments->value.pair->first->type != Ast_Node_Type_String) | |||||
| report_error(Error_Type_Type_Missmatch); | |||||
| if (evaluated_arguments->value.pair->first->type != Ast_Node_Type::String) | |||||
| report_error(Error_Type::Type_Missmatch); | |||||
| Ast_Node* result; | Ast_Node* result; | ||||
| try { | try { | ||||
| @@ -933,12 +933,12 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| } | } | ||||
| if (arguments_length != 1) | if (arguments_length != 1) | ||||
| report_error(Error_Type_Wrong_Number_Of_Arguments); | |||||
| report_error(Error_Type::Wrong_Number_Of_Arguments); | |||||
| if (evaluated_arguments->value.pair->first->type == Ast_Node_Type_Nil || | |||||
| evaluated_arguments->value.pair->first->type == Ast_Node_Type_Keyword) | |||||
| if (evaluated_arguments->value.pair->first->type == Ast_Node_Type::Nil || | |||||
| evaluated_arguments->value.pair->first->type == Ast_Node_Type::Keyword) | |||||
| { | { | ||||
| report_error(Error_Type_Type_Missmatch); | |||||
| report_error(Error_Type::Type_Missmatch); | |||||
| } | } | ||||
| Ast_Node* target = new(Ast_Node); | Ast_Node* target = new(Ast_Node); | ||||
| @@ -952,9 +952,9 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | evaluated_arguments = eval_arguments(arguments, env, &arguments_length); | ||||
| } | } | ||||
| if (arguments_length != 0) { | if (arguments_length != 0) { | ||||
| report_error(Error_Type_Wrong_Number_Of_Arguments); | |||||
| report_error(Error_Type::Wrong_Number_Of_Arguments); | |||||
| } | } | ||||
| report_error(Error_Type_Unknown_Error); | |||||
| report_error(Error_Type::Unknown_Error); | |||||
| }); | }); | ||||
| #undef report_error | #undef report_error | ||||
| @@ -962,7 +962,7 @@ void load_built_ins_into_environment(Environment* env) { | |||||
| } | } | ||||
| Environment* create_built_ins_environment() { | Environment* create_built_ins_environment() { | ||||
| Environment* ret = create_child_environment(nullptr, Environment_Type_Let); | |||||
| Environment* ret = create_child_environment(nullptr, Environment_Type::Let); | |||||
| load_built_ins_into_environment(ret); | load_built_ins_into_environment(ret); | ||||
| return ret; | return ret; | ||||
| } | } | ||||
| @@ -1,8 +1,8 @@ | |||||
| typedef enum { | |||||
| Environment_Type_Let, | |||||
| Environment_Type_Lambda, | |||||
| Environment_Type_Macro, | |||||
| } Environment_Type; | |||||
| enum struct Environment_Type { | |||||
| Let, | |||||
| Lambda, | |||||
| Macro, | |||||
| }; | |||||
| struct Environment { | struct Environment { | ||||
| struct Environment* parent; | struct Environment* parent; | ||||
| @@ -15,8 +15,6 @@ struct Environment { | |||||
| Ast_Node** values; | Ast_Node** values; | ||||
| }; | }; | ||||
| typedef struct Environment Environment; | |||||
| Environment* create_child_environment(Environment* parent, Environment_Type type) { | Environment* create_child_environment(Environment* parent, Environment_Type type) { | ||||
| Environment* env = new(Environment); | Environment* env = new(Environment); | ||||
| @@ -37,7 +35,7 @@ Environment* create_empty_environment(Environment_Type type) { | |||||
| } | } | ||||
| void define_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) { | void define_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) { | ||||
| if (env->type == Environment_Type_Macro) { | |||||
| if (env->type == Environment_Type::Macro) { | |||||
| // NOTE(Felix): we know we have a parent because every | // NOTE(Felix): we know we have a parent because every | ||||
| // environment has a parent except the top level environment. | // environment has a parent except the top level environment. | ||||
| // However the top level environment is not a let-environment, | // However the top level environment is not a let-environment, | ||||
| @@ -63,14 +61,14 @@ void define_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) { | |||||
| } | } | ||||
| void define_macro_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) { | void define_macro_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) { | ||||
| if (env->type != Environment_Type_Macro) { | |||||
| create_error(Error_Type_Unknown_Error, symbol->sourceCodeLocation); | |||||
| if (env->type != Environment_Type::Macro) { | |||||
| create_error(Error_Type::Unknown_Error, symbol->sourceCodeLocation); | |||||
| return; | return; | ||||
| } | } | ||||
| env->type = Environment_Type_Lambda; | |||||
| env->type = Environment_Type::Lambda; | |||||
| define_symbol(symbol, value, env); | define_symbol(symbol, value, env); | ||||
| env->type = Environment_Type_Macro; | |||||
| env->type = Environment_Type::Macro; | |||||
| } | } | ||||
| void print_environment(Environment* env); | void print_environment(Environment* env); | ||||
| @@ -85,7 +83,7 @@ Ast_Node* lookup_symbol_in_this_envt(Symbol* sym, Environment* env) { | |||||
| Ast_Node* lookup_symbol_from_lambda_env(Symbol* sym, Environment* env) { | Ast_Node* lookup_symbol_from_lambda_env(Symbol* sym, Environment* env) { | ||||
| Ast_Node* result; | Ast_Node* result; | ||||
| do { | do { | ||||
| if (env->type != Environment_Type_Lambda) { | |||||
| if (env->type != Environment_Type::Lambda) { | |||||
| result = lookup_symbol_in_this_envt(sym, env); | result = lookup_symbol_in_this_envt(sym, env); | ||||
| if (result) return result; | if (result) return result; | ||||
| } | } | ||||
| @@ -99,7 +97,7 @@ Ast_Node* lookup_symbol_from_let_or_macro_env(Symbol* sym, Environment* env) { | |||||
| do { | do { | ||||
| result = lookup_symbol_in_this_envt(sym, env); | result = lookup_symbol_in_this_envt(sym, env); | ||||
| if (result) return result; | if (result) return result; | ||||
| if (env->type == Environment_Type_Lambda) | |||||
| if (env->type == Environment_Type::Lambda) | |||||
| break; | break; | ||||
| env = env->parent; | env = env->parent; | ||||
| @@ -107,7 +105,7 @@ Ast_Node* lookup_symbol_from_let_or_macro_env(Symbol* sym, Environment* env) { | |||||
| if (env) { | if (env) { | ||||
| do { | do { | ||||
| if (env->type != Environment_Type_Lambda) { | |||||
| if (env->type != Environment_Type::Lambda) { | |||||
| result = lookup_symbol_in_this_envt(sym, env); | result = lookup_symbol_in_this_envt(sym, env); | ||||
| if (result) return result; | if (result) return result; | ||||
| } | } | ||||
| @@ -127,7 +125,7 @@ Ast_Node* lookup_symbol(Ast_Node* node, Environment* env) { | |||||
| return result; | return result; | ||||
| if (env->parent) { | if (env->parent) { | ||||
| if (env->type == Environment_Type_Lambda) { | |||||
| if (env->type == Environment_Type::Lambda) { | |||||
| result = lookup_symbol_from_lambda_env(sym, env->parent); | result = lookup_symbol_from_lambda_env(sym, env->parent); | ||||
| } else { | } else { | ||||
| result = lookup_symbol_from_let_or_macro_env(sym, env->parent); | result = lookup_symbol_from_let_or_macro_env(sym, env->parent); | ||||
| @@ -152,7 +150,7 @@ Ast_Node* lookup_symbol(Ast_Node* node, Environment* env) { | |||||
| /* if (result) */ | /* if (result) */ | ||||
| /* return result; */ | /* return result; */ | ||||
| create_error(Error_Type_Symbol_Not_Defined, node->sourceCodeLocation); | |||||
| create_error(Error_Type::Symbol_Not_Defined, node->sourceCodeLocation); | |||||
| /* printf("%s\n", sym->identifier); */ | /* printf("%s\n", sym->identifier); */ | ||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| @@ -172,11 +170,11 @@ void print_environment_indent(Environment* env, int indent) { | |||||
| if (env->parent) { | if (env->parent) { | ||||
| print_indent(indent); | print_indent(indent); | ||||
| printf("parent"); | printf("parent"); | ||||
| if (env->parent->type == Environment_Type_Lambda) | |||||
| if (env->parent->type == Environment_Type::Lambda) | |||||
| printf(" (lambda)"); | printf(" (lambda)"); | ||||
| else if (env->parent->type == Environment_Type_Macro) | |||||
| else if (env->parent->type == Environment_Type::Macro) | |||||
| printf(" (macro)"); | printf(" (macro)"); | ||||
| else if (env->parent->type == Environment_Type_Let) | |||||
| else if (env->parent->type == Environment_Type::Let) | |||||
| printf(" (let)"); | printf(" (let)"); | ||||
| printf(":\n"); | printf(":\n"); | ||||
| print_environment_indent(env->parent, indent+4); | print_environment_indent(env->parent, indent+4); | ||||
| @@ -1,24 +1,24 @@ | |||||
| typedef enum { | |||||
| Error_Type_Ill_Formed_Arguments, | |||||
| Error_Type_Ill_Formed_Lambda_List, | |||||
| Error_Type_Ill_Formed_List, | |||||
| Error_Type_Not_A_Function, | |||||
| Error_Type_Not_Yet_Implemented, | |||||
| Error_Type_Symbol_Not_Defined, | |||||
| Error_Type_Syntax_Error, | |||||
| Error_Type_Trailing_Garbage, | |||||
| Error_Type_Type_Missmatch, | |||||
| Error_Type_Unbalanced_Parenthesis, | |||||
| Error_Type_Unexpected_Eof, | |||||
| Error_Type_Unknown_Error, | |||||
| Error_Type_Unknown_Keyword_Argument, | |||||
| Error_Type_Wrong_Number_Of_Arguments, | |||||
| } Error_Type; | |||||
| enum struct Error_Type { | |||||
| Ill_Formed_Arguments, | |||||
| Ill_Formed_Lambda_List, | |||||
| Ill_Formed_List, | |||||
| Not_A_Function, | |||||
| Not_Yet_Implemented, | |||||
| Symbol_Not_Defined, | |||||
| Syntax_Error, | |||||
| Trailing_Garbage, | |||||
| Type_Missmatch, | |||||
| Unbalanced_Parenthesis, | |||||
| Unexpected_Eof, | |||||
| Unknown_Error, | |||||
| Unknown_Keyword_Argument, | |||||
| Wrong_Number_Of_Arguments, | |||||
| }; | |||||
| typedef struct Error_t { | |||||
| struct Error { | |||||
| Error_Type type; | Error_Type type; | ||||
| Source_Code_Location* location; | Source_Code_Location* location; | ||||
| } Error; | |||||
| }; | |||||
| Error* error; | Error* error; | ||||
| @@ -39,19 +39,19 @@ void create_error(Error_Type type, Source_Code_Location* location) { | |||||
| char* Error_Type_to_string(Error_Type type) { | char* Error_Type_to_string(Error_Type type) { | ||||
| switch (type) { | switch (type) { | ||||
| case Error_Type_Ill_Formed_Arguments: return "Evaluation-error: Ill formed arguments"; | |||||
| case Error_Type_Ill_Formed_Lambda_List: return "Evaluation-error: Ill formed lambda list"; | |||||
| case Error_Type_Ill_Formed_List: return "Evaluation-error: Ill formed list"; | |||||
| case Error_Type_Not_A_Function: return "Evaluation-error: Not a function"; | |||||
| case Error_Type_Not_Yet_Implemented: return "Evaluation-error: Not yet implemented"; | |||||
| case Error_Type_Symbol_Not_Defined: return "Evaluation-error: Symbol not defined"; | |||||
| case Error_Type_Syntax_Error: return "Syntax Error"; | |||||
| case Error_Type_Trailing_Garbage: return "Evaluation-error: Trailing garbage following expression"; | |||||
| case Error_Type_Type_Missmatch: return "Evaluation-error: Type Missmatch"; | |||||
| case Error_Type_Unbalanced_Parenthesis: return "Parsing-error: Unbalanced parenthesis"; | |||||
| case Error_Type_Unexpected_Eof: return "Parsing-error: Unexpected EOF"; | |||||
| case Error_Type_Unknown_Keyword_Argument: return "Evaluation-error: Unknown keyword argument"; | |||||
| case Error_Type_Wrong_Number_Of_Arguments: return "Evaluation-error: Wrong number of arguments"; | |||||
| case Error_Type::Ill_Formed_Arguments: return "Evaluation-error: Ill formed arguments"; | |||||
| case Error_Type::Ill_Formed_Lambda_List: return "Evaluation-error: Ill formed lambda list"; | |||||
| case Error_Type::Ill_Formed_List: return "Evaluation-error: Ill formed list"; | |||||
| case Error_Type::Not_A_Function: return "Evaluation-error: Not a function"; | |||||
| case Error_Type::Not_Yet_Implemented: return "Evaluation-error: Not yet implemented"; | |||||
| case Error_Type::Symbol_Not_Defined: return "Evaluation-error: Symbol not defined"; | |||||
| case Error_Type::Syntax_Error: return "Syntax Error"; | |||||
| case Error_Type::Trailing_Garbage: return "Evaluation-error: Trailing garbage following expression"; | |||||
| case Error_Type::Type_Missmatch: return "Evaluation-error: Type Missmatch"; | |||||
| case Error_Type::Unbalanced_Parenthesis: return "Parsing-error: Unbalanced parenthesis"; | |||||
| case Error_Type::Unexpected_Eof: return "Parsing-error: Unexpected EOF"; | |||||
| case Error_Type::Unknown_Keyword_Argument: return "Evaluation-error: Unknown keyword argument"; | |||||
| case Error_Type::Wrong_Number_Of_Arguments: return "Evaluation-error: Wrong number of arguments"; | |||||
| default: return "Unknown Error"; | default: return "Unknown Error"; | ||||
| } | } | ||||
| } | } | ||||
| @@ -6,11 +6,11 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E | |||||
| // switching between "define_symbol" and "define_macro_symbol" all | // switching between "define_symbol" and "define_macro_symbol" all | ||||
| // the time | // the time | ||||
| Environment* new_env = create_child_environment(parent, Environment_Type_Lambda); | |||||
| Environment* new_env = create_child_environment(parent, Environment_Type::Lambda); | |||||
| // positional arguments | // positional arguments | ||||
| for (int i = 0; i < function->positional_arguments->next_index; ++i) { | for (int i = 0; i < function->positional_arguments->next_index; ++i) { | ||||
| if (arguments->type == Ast_Node_Type_Pair) { | |||||
| if (arguments->type == Ast_Node_Type::Pair) { | |||||
| // TODO(Felix): here we create new ast_node_symbols from | // TODO(Felix): here we create new ast_node_symbols from | ||||
| // their identifiers but before we converted them to | // their identifiers but before we converted them to | ||||
| // strings from symbols... Wo maybe just use the symbols? | // strings from symbols... Wo maybe just use the symbols? | ||||
| @@ -19,13 +19,13 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E | |||||
| arguments->value.pair->first, new_env); | arguments->value.pair->first, new_env); | ||||
| } else { | } else { | ||||
| // not enough arguments given | // not enough arguments given | ||||
| create_error(Error_Type_Ill_Formed_Arguments, arguments->sourceCodeLocation); | |||||
| create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation); | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| arguments = arguments->value.pair->rest; | arguments = arguments->value.pair->rest; | ||||
| } | } | ||||
| if (arguments->type == Ast_Node_Type_Nil) | |||||
| if (arguments->type == Ast_Node_Type::Nil) | |||||
| goto eval_time; | goto eval_time; | ||||
| String_Array_List* read_in_keywords = create_String_array_list(16); | String_Array_List* read_in_keywords = create_String_array_list(16); | ||||
| @@ -34,7 +34,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E | |||||
| // something that is not a keyword is encountered or a keyword | // something that is not a keyword is encountered or a keyword | ||||
| // that is not recognized is encoutered, jump out of the loop. | // that is not recognized is encoutered, jump out of the loop. | ||||
| while (arguments->value.pair->first->type == Ast_Node_Type_Keyword) { | |||||
| while (arguments->value.pair->first->type == Ast_Node_Type::Keyword) { | |||||
| // check if this one is even an accepted keyword | // check if this one is even an accepted keyword | ||||
| bool accepted = false; | bool accepted = false; | ||||
| for (int i = 0; i < function->keyword_arguments->next_index; ++i) { | for (int i = 0; i < function->keyword_arguments->next_index; ++i) { | ||||
| @@ -47,7 +47,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E | |||||
| } | } | ||||
| } | } | ||||
| if (!accepted) { | if (!accepted) { | ||||
| create_error(Error_Type_Ill_Formed_Arguments, arguments->sourceCodeLocation); | |||||
| create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation); | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| @@ -61,7 +61,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E | |||||
| // necessary keywords then we have to count the rest | // necessary keywords then we have to count the rest | ||||
| // as :rest here, instead od always creating an error | // as :rest here, instead od always creating an error | ||||
| // (special case with default variables) | // (special case with default variables) | ||||
| create_error(Error_Type_Ill_Formed_Arguments, arguments->sourceCodeLocation); | |||||
| create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation); | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| } | } | ||||
| @@ -69,8 +69,8 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E | |||||
| // okay so we found a keyword that has to be read in and was | // okay so we found a keyword that has to be read in and was | ||||
| // not already read in, is there a next element to actually | // not already read in, is there a next element to actually | ||||
| // set it to? | // set it to? | ||||
| if (arguments->value.pair->rest->type != Ast_Node_Type_Pair) { | |||||
| create_error(Error_Type_Ill_Formed_Arguments, arguments->sourceCodeLocation); | |||||
| if (arguments->value.pair->rest->type != Ast_Node_Type::Pair) { | |||||
| create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation); | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| @@ -85,7 +85,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E | |||||
| // overstep both for next one | // overstep both for next one | ||||
| arguments = arguments->value.pair->rest->value.pair->rest; | arguments = arguments->value.pair->rest->value.pair->rest; | ||||
| if (arguments->type == Ast_Node_Type_Nil) { | |||||
| if (arguments->type == Ast_Node_Type::Nil) { | |||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| @@ -107,7 +107,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E | |||||
| if (function->keyword_arguments->values->data[i] == nullptr) { | if (function->keyword_arguments->values->data[i] == nullptr) { | ||||
| // if this one does not have a default value | // if this one does not have a default value | ||||
| if (!was_set) { | if (!was_set) { | ||||
| create_error(Error_Type_Ill_Formed_Arguments, arguments->sourceCodeLocation); | |||||
| create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation); | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| } else { | } else { | ||||
| @@ -122,7 +122,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E | |||||
| } | } | ||||
| if (arguments->type == Ast_Node_Type_Nil) { | |||||
| if (arguments->type == Ast_Node_Type::Nil) { | |||||
| if (function->rest_argument) { | if (function->rest_argument) { | ||||
| define_symbol( | define_symbol( | ||||
| create_ast_node_symbol(function->rest_argument), | create_ast_node_symbol(function->rest_argument), | ||||
| @@ -135,7 +135,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E | |||||
| arguments, new_env); | arguments, new_env); | ||||
| } else { | } else { | ||||
| // rest was not declared but additional arguments were found | // rest was not declared but additional arguments were found | ||||
| create_error(Error_Type_Ill_Formed_Arguments, arguments->sourceCodeLocation); | |||||
| create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation); | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| } | } | ||||
| @@ -146,7 +146,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E | |||||
| // don't have to check every time if it is macro environment or | // don't have to check every time if it is macro environment or | ||||
| // not | // not | ||||
| if (function->is_macro) | if (function->is_macro) | ||||
| new_env->type = Environment_Type_Macro; | |||||
| new_env->type = Environment_Type::Macro; | |||||
| try { | try { | ||||
| result = eval_expr(function->body, new_env); | result = eval_expr(function->body, new_env); | ||||
| @@ -180,19 +180,19 @@ void parse_argument_list(Ast_Node* arguments, Function* function) { | |||||
| function->rest_argument = nullptr; | function->rest_argument = nullptr; | ||||
| // okay let's try to read some positional arguments | // okay let's try to read some positional arguments | ||||
| while (arguments->type == Ast_Node_Type_Pair) { | |||||
| if (arguments->value.pair->first->type == Ast_Node_Type_Keyword) { | |||||
| while (arguments->type == Ast_Node_Type::Pair) { | |||||
| if (arguments->value.pair->first->type == Ast_Node_Type::Keyword) { | |||||
| if (string_equal(arguments->value.pair->first->value.keyword->identifier, "keys") || | if (string_equal(arguments->value.pair->first->value.keyword->identifier, "keys") || | ||||
| string_equal(arguments->value.pair->first->value.keyword->identifier, "rest")) | string_equal(arguments->value.pair->first->value.keyword->identifier, "rest")) | ||||
| break; | break; | ||||
| else { | else { | ||||
| create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation); | |||||
| create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); | |||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| if (arguments->value.pair->first->type != Ast_Node_Type_Symbol) { | |||||
| create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation); | |||||
| if (arguments->value.pair->first->type != Ast_Node_Type::Symbol) { | |||||
| create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); | |||||
| return; | return; | ||||
| } | } | ||||
| @@ -206,35 +206,35 @@ void parse_argument_list(Ast_Node* arguments, Function* function) { | |||||
| // okay we are done with positional arguments, lets check for | // okay we are done with positional arguments, lets check for | ||||
| // keywords, | // keywords, | ||||
| if (arguments->type != Ast_Node_Type_Pair) { | |||||
| if (arguments->type != Ast_Node_Type_Nil) | |||||
| create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation); | |||||
| if (arguments->type != Ast_Node_Type::Pair) { | |||||
| if (arguments->type != Ast_Node_Type::Nil) | |||||
| create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); | |||||
| return; | return; | ||||
| } | } | ||||
| if (arguments->value.pair->first->type == Ast_Node_Type_Keyword && | |||||
| if (arguments->value.pair->first->type == Ast_Node_Type::Keyword && | |||||
| string_equal(arguments->value.pair->first->value.keyword->identifier, "keys")) | string_equal(arguments->value.pair->first->value.keyword->identifier, "keys")) | ||||
| { | { | ||||
| arguments = arguments->value.pair->rest; | arguments = arguments->value.pair->rest; | ||||
| if (arguments->type != Ast_Node_Type_Pair || | |||||
| arguments->value.pair->first->type != Ast_Node_Type_Symbol) | |||||
| if (arguments->type != Ast_Node_Type::Pair || | |||||
| arguments->value.pair->first->type != Ast_Node_Type::Symbol) | |||||
| { | { | ||||
| create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation); | |||||
| create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); | |||||
| return; | return; | ||||
| } | } | ||||
| while (arguments->type == Ast_Node_Type_Pair) { | |||||
| if (arguments->value.pair->first->type == Ast_Node_Type_Keyword) { | |||||
| while (arguments->type == Ast_Node_Type::Pair) { | |||||
| if (arguments->value.pair->first->type == Ast_Node_Type::Keyword) { | |||||
| if (string_equal(arguments->value.pair->first->value.keyword->identifier, "rest")) | if (string_equal(arguments->value.pair->first->value.keyword->identifier, "rest")) | ||||
| break; | break; | ||||
| else { | else { | ||||
| create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation); | |||||
| create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); | |||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| if (arguments->value.pair->first->type != Ast_Node_Type_Symbol) { | |||||
| create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation); | |||||
| if (arguments->value.pair->first->type != Ast_Node_Type::Symbol) { | |||||
| create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); | |||||
| return; | return; | ||||
| } | } | ||||
| @@ -242,21 +242,21 @@ void parse_argument_list(Ast_Node* arguments, Function* function) { | |||||
| // the keyword args! Let's check if the next arguement is | // the keyword args! Let's check if the next arguement is | ||||
| // :defaults-to | // :defaults-to | ||||
| Ast_Node* next = arguments->value.pair->rest; | Ast_Node* next = arguments->value.pair->rest; | ||||
| if (next->type == Ast_Node_Type_Pair && | |||||
| next->value.pair->first->type == Ast_Node_Type_Keyword && | |||||
| if (next->type == Ast_Node_Type::Pair && | |||||
| next->value.pair->first->type == Ast_Node_Type::Keyword && | |||||
| string_equal(next->value.pair->first->value.keyword->identifier, | string_equal(next->value.pair->first->value.keyword->identifier, | ||||
| "defaults-to")) | "defaults-to")) | ||||
| { | { | ||||
| // check if there is a next argument too, otherwise it | // check if there is a next argument too, otherwise it | ||||
| // would be an error | // would be an error | ||||
| next = next->value.pair->rest; | next = next->value.pair->rest; | ||||
| if (next->type == Ast_Node_Type_Pair) { | |||||
| if (next->type == Ast_Node_Type::Pair) { | |||||
| append_to_keyword_argument_list(function->keyword_arguments, | append_to_keyword_argument_list(function->keyword_arguments, | ||||
| arguments->value.pair->first->value.symbol->identifier, | arguments->value.pair->first->value.symbol->identifier, | ||||
| next->value.pair->first); | next->value.pair->first); | ||||
| arguments = next->value.pair->rest; | arguments = next->value.pair->rest; | ||||
| } else { | } else { | ||||
| create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation); | |||||
| create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); | |||||
| return; | return; | ||||
| } | } | ||||
| } else { | } else { | ||||
| @@ -272,51 +272,51 @@ void parse_argument_list(Ast_Node* arguments, Function* function) { | |||||
| // Now we are also done with keyword arguments, lets check for | // Now we are also done with keyword arguments, lets check for | ||||
| // if there is a rest argument | // if there is a rest argument | ||||
| if (arguments->type != Ast_Node_Type_Pair) { | |||||
| if (arguments->type != Ast_Node_Type_Nil) | |||||
| create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation); | |||||
| if (arguments->type != Ast_Node_Type::Pair) { | |||||
| if (arguments->type != Ast_Node_Type::Nil) | |||||
| create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); | |||||
| return; | return; | ||||
| } | } | ||||
| if (arguments->value.pair->first->type == Ast_Node_Type_Keyword && | |||||
| if (arguments->value.pair->first->type == Ast_Node_Type::Keyword && | |||||
| string_equal(arguments->value.pair->first->value.keyword->identifier, "rest")) | string_equal(arguments->value.pair->first->value.keyword->identifier, "rest")) | ||||
| { | { | ||||
| arguments = arguments->value.pair->rest; | arguments = arguments->value.pair->rest; | ||||
| if (arguments->type != Ast_Node_Type_Pair || | |||||
| arguments->value.pair->first->type != Ast_Node_Type_Symbol) | |||||
| if (arguments->type != Ast_Node_Type::Pair || | |||||
| arguments->value.pair->first->type != Ast_Node_Type::Symbol) | |||||
| { | { | ||||
| create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation); | |||||
| create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); | |||||
| return; | return; | ||||
| } | } | ||||
| function->rest_argument = arguments->value.pair->first->value.symbol->identifier; | function->rest_argument = arguments->value.pair->first->value.symbol->identifier; | ||||
| if (arguments->value.pair->rest->type != Ast_Node_Type_Nil) { | |||||
| create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation); | |||||
| if (arguments->value.pair->rest->type != Ast_Node_Type::Nil) { | |||||
| create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); | |||||
| } | } | ||||
| } else { | } else { | ||||
| printf("this should not happen?"); | printf("this should not happen?"); | ||||
| create_error(Error_Type_Unknown_Error, arguments->sourceCodeLocation); | |||||
| create_error(Error_Type::Unknown_Error, arguments->sourceCodeLocation); | |||||
| } | } | ||||
| } | } | ||||
| int list_length(Ast_Node* node) { | int list_length(Ast_Node* node) { | ||||
| if (node->type == Ast_Node_Type_Nil) | |||||
| if (node->type == Ast_Node_Type::Nil) | |||||
| return 0; | return 0; | ||||
| if (node->type != Ast_Node_Type_Pair) { | |||||
| create_error(Error_Type_Type_Missmatch, node->sourceCodeLocation); | |||||
| if (node->type != Ast_Node_Type::Pair) { | |||||
| create_error(Error_Type::Type_Missmatch, node->sourceCodeLocation); | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| int len = 0; | int len = 0; | ||||
| while (node->type == Ast_Node_Type_Pair) { | |||||
| while (node->type == Ast_Node_Type::Pair) { | |||||
| ++len; | ++len; | ||||
| node = node->value.pair->rest; | node = node->value.pair->rest; | ||||
| if (node->type == Ast_Node_Type_Nil) | |||||
| if (node->type == Ast_Node_Type::Nil) | |||||
| return len; | return len; | ||||
| } | } | ||||
| create_error(Error_Type_Ill_Formed_List, node->sourceCodeLocation); | |||||
| create_error(Error_Type::Ill_Formed_List, node->sourceCodeLocation); | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -333,27 +333,27 @@ Ast_Node* extract_keyword_value(char* keyword, Parsed_Arguments* args) { | |||||
| Ast_Node* eval_arguments(Ast_Node* arguments, Environment* env, int *out_arguments_length) { | Ast_Node* eval_arguments(Ast_Node* arguments, Environment* env, int *out_arguments_length) { | ||||
| *out_arguments_length = 0; | *out_arguments_length = 0; | ||||
| if (arguments->type == Ast_Node_Type_Nil) { | |||||
| if (arguments->type == Ast_Node_Type::Nil) { | |||||
| return arguments; | return arguments; | ||||
| } | } | ||||
| Ast_Node* evaluated_arguments = create_ast_node_pair(nullptr, nullptr); | Ast_Node* evaluated_arguments = create_ast_node_pair(nullptr, nullptr); | ||||
| Ast_Node* evaluated_arguments_head = evaluated_arguments; | Ast_Node* evaluated_arguments_head = evaluated_arguments; | ||||
| Ast_Node* current_head = arguments; | Ast_Node* current_head = arguments; | ||||
| while (current_head->type == Ast_Node_Type_Pair) { | |||||
| while (current_head->type == Ast_Node_Type::Pair) { | |||||
| try { | try { | ||||
| evaluated_arguments_head->value.pair->first = | evaluated_arguments_head->value.pair->first = | ||||
| eval_expr(current_head->value.pair->first, env); | eval_expr(current_head->value.pair->first, env); | ||||
| } | } | ||||
| current_head = current_head->value.pair->rest; | current_head = current_head->value.pair->rest; | ||||
| if (current_head->type == Ast_Node_Type_Pair) { | |||||
| if (current_head->type == Ast_Node_Type::Pair) { | |||||
| evaluated_arguments_head->value.pair->rest = create_ast_node_pair(nullptr, nullptr); | evaluated_arguments_head->value.pair->rest = create_ast_node_pair(nullptr, nullptr); | ||||
| evaluated_arguments_head = evaluated_arguments_head->value.pair->rest; | evaluated_arguments_head = evaluated_arguments_head->value.pair->rest; | ||||
| } else if (current_head->type == Ast_Node_Type_Nil) { | |||||
| } else if (current_head->type == Ast_Node_Type::Nil) { | |||||
| evaluated_arguments_head->value.pair->rest = current_head; | evaluated_arguments_head->value.pair->rest = current_head; | ||||
| } else { | } else { | ||||
| create_error(Error_Type_Ill_Formed_Arguments, arguments->sourceCodeLocation); | |||||
| create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation); | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| ++(*out_arguments_length); | ++(*out_arguments_length); | ||||
| @@ -372,24 +372,24 @@ 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::T: | |||||
| case Ast_Node_Type::Nil: | |||||
| return node; | return node; | ||||
| case Ast_Node_Type_Symbol: { | |||||
| case Ast_Node_Type::Symbol: { | |||||
| Ast_Node* symbol; | Ast_Node* symbol; | ||||
| try { | try { | ||||
| symbol = lookup_symbol(node, env); | symbol = lookup_symbol(node, env); | ||||
| } | } | ||||
| return symbol; | return symbol; | ||||
| } | } | ||||
| case Ast_Node_Type_Number: | |||||
| case Ast_Node_Type_Keyword: | |||||
| case Ast_Node_Type_String: | |||||
| case Ast_Node_Type::Number: | |||||
| case Ast_Node_Type::Keyword: | |||||
| case Ast_Node_Type::String: | |||||
| return node; | return node; | ||||
| case Ast_Node_Type_Pair: { | |||||
| case Ast_Node_Type::Pair: { | |||||
| Ast_Node* lispOperator; | Ast_Node* lispOperator; | ||||
| if (node->value.pair->first->type != Ast_Node_Type_CFunction && | |||||
| node->value.pair->first->type != Ast_Node_Type_Function) | |||||
| if (node->value.pair->first->type != Ast_Node_Type::CFunction && | |||||
| node->value.pair->first->type != Ast_Node_Type::Function) | |||||
| { | { | ||||
| try { | try { | ||||
| lispOperator = eval_expr(node->value.pair->first, env); | lispOperator = eval_expr(node->value.pair->first, env); | ||||
| @@ -402,13 +402,13 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) { | |||||
| int arguments_length; | int arguments_length; | ||||
| // check for c function | // check for c function | ||||
| if (lispOperator->type == Ast_Node_Type_CFunction) { | |||||
| if (lispOperator->type == Ast_Node_Type::CFunction) { | |||||
| Ast_Node* result = lispOperator->value.cfunction->function(arguments, env); | Ast_Node* result = lispOperator->value.cfunction->function(arguments, env); | ||||
| return result; | return result; | ||||
| } | } | ||||
| // check for list function | // check for list function | ||||
| if (lispOperator->type == Ast_Node_Type_Function) { | |||||
| if (lispOperator->type == Ast_Node_Type::Function) { | |||||
| if (!lispOperator->value.function->is_macro) { | if (!lispOperator->value.function->is_macro) { | ||||
| try { | try { | ||||
| arguments = eval_arguments(arguments, env, &arguments_length); | arguments = eval_arguments(arguments, env, &arguments_length); | ||||
| @@ -426,7 +426,7 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) { | |||||
| #ifdef _DEBUG | #ifdef _DEBUG | ||||
| __debugbreak(); | __debugbreak(); | ||||
| #endif | #endif | ||||
| report_error(Error_Type_Not_A_Function); | |||||
| report_error(Error_Type::Not_A_Function); | |||||
| } | } | ||||
| } | } | ||||
| #undef report_error | #undef report_error | ||||
| @@ -437,7 +437,7 @@ bool is_truthy (Ast_Node* expression, Environment* env) { | |||||
| try { | try { | ||||
| result = eval_expr(expression, env); | result = eval_expr(expression, env); | ||||
| } | } | ||||
| if (result->type == Ast_Node_Type_Nil) | |||||
| if (result->type == Ast_Node_Type::Nil) | |||||
| return false; | return false; | ||||
| return true; | return true; | ||||
| @@ -27,11 +27,11 @@ | |||||
| #define define_array_list(type, name) \ | #define define_array_list(type, name) \ | ||||
| typedef struct { \ | |||||
| struct name##_Array_List { \ | |||||
| type* data; \ | type* data; \ | ||||
| int length; \ | int length; \ | ||||
| int next_index; \ | int next_index; \ | ||||
| } name##_Array_List; \ | |||||
| }; \ | |||||
| \ | \ | ||||
| \ | \ | ||||
| void append_to_##name##_array_list(name##_Array_List* arraylist, type element) { \ | void append_to_##name##_array_list(name##_Array_List* arraylist, type element) { \ | ||||
| @@ -55,8 +55,6 @@ | |||||
| define_array_list(char*, String); | define_array_list(char*, String); | ||||
| //typedef enum { false, true } bool; | |||||
| int string_equal(char* a, char* b) { | int string_equal(char* a, char* b) { | ||||
| return !strcmp(a, b); | return !strcmp(a, b); | ||||
| } | } | ||||
| @@ -99,9 +97,6 @@ static char get_nibble(char c) { | |||||
| return (c - '0'); | return (c - '0'); | ||||
| } | } | ||||
| #define true 1 | |||||
| #define false 0 | |||||
| #define bool char | |||||
| bool unescape_string(char* in) { | bool unescape_string(char* in) { | ||||
| if (!in) | if (!in) | ||||
| return true; | return true; | ||||
| @@ -278,11 +273,11 @@ char* read_line() { | |||||
| } | } | ||||
| typedef struct { | |||||
| struct Source_Code_Location { | |||||
| char* file; | char* file; | ||||
| int line; | int line; | ||||
| int column; | int column; | ||||
| } Source_Code_Location; | |||||
| }; | |||||
| Source_Code_Location* create_source_code_location(char* file, int line, int col) { | Source_Code_Location* create_source_code_location(char* file, int line, int col) { | ||||
| if (!file) | if (!file) | ||||
| @@ -1,24 +1,22 @@ | |||||
| /* #define console_normal "\x1B[0m" */ | |||||
| /* #define console_red "\x1B[31m" */ | |||||
| /* #define console_green "\x1B[32m" */ | |||||
| /* #define console_cyan "\x1B[36m" */ | |||||
| // #define console_normal "\x1B[0m" | |||||
| // #define console_red "\x1B[31m" | |||||
| // #define console_green "\x1B[32m" | |||||
| // #define console_cyan "\x1B[36m" | |||||
| #define console_normal "" | #define console_normal "" | ||||
| #define console_red "" | #define console_red "" | ||||
| #define console_green "" | #define console_green "" | ||||
| #define console_cyan "" | #define console_cyan "" | ||||
| enum struct Log_Level { | |||||
| None, | |||||
| Critical, | |||||
| Warning, | |||||
| Info, | |||||
| Debug, | |||||
| }; | |||||
| typedef enum { | |||||
| Log_Level_None, | |||||
| Log_Level_Critical, | |||||
| Log_Level_Warning, | |||||
| Log_Level_Info, | |||||
| Log_Level_Debug, | |||||
| } Log_Level; | |||||
| Log_Level log_level = Log_Level_Debug; | |||||
| Log_Level log_level = Log_Level::Debug; | |||||
| void log_message(Log_Level type, char* message) { | void log_message(Log_Level type, char* message) { | ||||
| if (type > log_level) | if (type > log_level) | ||||
| @@ -26,50 +24,50 @@ void log_message(Log_Level type, char* message) { | |||||
| char* prefix; | char* prefix; | ||||
| switch (type) { | switch (type) { | ||||
| case Log_Level_Critical: prefix = "CRITICAL"; break; | |||||
| case Log_Level_Warning: prefix = "WARNING"; break; | |||||
| case Log_Level_Info: prefix = "INFO"; break; | |||||
| case Log_Level_Debug: prefix = "DEBUG"; break; | |||||
| default: return; | |||||
| case Log_Level::Critical: prefix = "CRITICAL"; break; | |||||
| case Log_Level::Warning: prefix = "WARNING"; break; | |||||
| case Log_Level::Info: prefix = "INFO"; break; | |||||
| case Log_Level::Debug: prefix = "DEBUG"; break; | |||||
| default: return; | |||||
| } | } | ||||
| 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); | ||||
| } | } | ||||
| void print(Ast_Node* node) { | void print(Ast_Node* node) { | ||||
| switch (node->type) { | switch (node->type) { | ||||
| case (Ast_Node_Type_Nil): { | |||||
| case (Ast_Node_Type::Nil): { | |||||
| printf("nil"); | printf("nil"); | ||||
| } break; | } break; | ||||
| case (Ast_Node_Type_T): { | |||||
| case (Ast_Node_Type::T): { | |||||
| printf("t"); | printf("t"); | ||||
| } break; | } 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; | ||||
| case (Ast_Node_Type_String): { | |||||
| case (Ast_Node_Type::String): { | |||||
| printf("%s", node->value.string->value); | printf("%s", node->value.string->value); | ||||
| } break; | } break; | ||||
| case (Ast_Node_Type_Symbol): { | |||||
| case (Ast_Node_Type::Symbol): { | |||||
| printf("%s", node->value.symbol->identifier); | printf("%s", node->value.symbol->identifier); | ||||
| } break; | } break; | ||||
| case (Ast_Node_Type_Keyword): { | |||||
| case (Ast_Node_Type::Keyword): { | |||||
| printf(":%s", node->value.keyword->identifier); | printf(":%s", node->value.keyword->identifier); | ||||
| } break; | } break; | ||||
| case (Ast_Node_Type_Function): { | |||||
| case (Ast_Node_Type::Function): { | |||||
| if (node->value.function->is_macro) | if (node->value.function->is_macro) | ||||
| printf("[macro]"); | printf("[macro]"); | ||||
| else | else | ||||
| printf("[lambda]"); | printf("[lambda]"); | ||||
| } break; | } break; | ||||
| case (Ast_Node_Type_CFunction): { | |||||
| case (Ast_Node_Type::CFunction): { | |||||
| printf("[C-function]"); | printf("[C-function]"); | ||||
| } break; | } break; | ||||
| case (Ast_Node_Type_Pair): { | |||||
| case (Ast_Node_Type::Pair): { | |||||
| Ast_Node* head = node; | Ast_Node* head = node; | ||||
| printf("("); | printf("("); | ||||
| @@ -81,12 +79,12 @@ void print(Ast_Node* node) { | |||||
| head = head->value.pair->rest; | head = head->value.pair->rest; | ||||
| if (!head) | if (!head) | ||||
| return; | return; | ||||
| if (head->type != Ast_Node_Type_Pair) | |||||
| if (head->type != Ast_Node_Type::Pair) | |||||
| break; | break; | ||||
| printf(" "); | printf(" "); | ||||
| } | } | ||||
| if (head->type != Ast_Node_Type_Nil) { | |||||
| if (head->type != Ast_Node_Type::Nil) { | |||||
| printf(" . "); | printf(" . "); | ||||
| print(head); | print(head); | ||||
| } | } | ||||
| @@ -22,7 +22,7 @@ | |||||
| Ast_Node* interprete_file (char* file_name) { | Ast_Node* interprete_file (char* file_name) { | ||||
| char* file_content = read_entire_file(file_name); | char* file_content = read_entire_file(file_name); | ||||
| if (!file_content) { | if (!file_content) { | ||||
| create_error(Error_Type_Unknown_Error, nullptr); | |||||
| create_error(Error_Type::Unknown_Error, nullptr); | |||||
| } | } | ||||
| Ast_Node_Array_List* program; | Ast_Node_Array_List* program; | ||||
| @@ -30,7 +30,7 @@ Ast_Node* interprete_file (char* file_name) { | |||||
| program = parse_program(file_name, file_content); | program = parse_program(file_name, file_content); | ||||
| } | } | ||||
| Environment* env = create_empty_environment(Environment_Type_Let); | |||||
| Environment* env = create_empty_environment(Environment_Type::Let); | |||||
| load_built_ins_into_environment(env); | load_built_ins_into_environment(env); | ||||
| try { | try { | ||||
| @@ -50,7 +50,7 @@ Ast_Node* interprete_file (char* file_name) { | |||||
| int interprete_stdin () { | int interprete_stdin () { | ||||
| printf("Welcome to the lispy interpreter.\n"); | printf("Welcome to the lispy interpreter.\n"); | ||||
| char* line; | char* line; | ||||
| Environment* env = create_empty_environment(Environment_Type_Let); | |||||
| Environment* env = create_empty_environment(Environment_Type::Let); | |||||
| load_built_ins_into_environment(env); | load_built_ins_into_environment(env); | ||||
| built_in_load("pre.slime", env); | built_in_load("pre.slime", env); | ||||
| @@ -161,7 +161,7 @@ Ast_Node* parse_string(char* text, int* index_in_text) { | |||||
| if (!unescape_string(text+(*index_in_text))) { | if (!unescape_string(text+(*index_in_text))) { | ||||
| create_error( | create_error( | ||||
| Error_Type_Unknown_Error, | |||||
| Error_Type::Unknown_Error, | |||||
| create_source_code_location(parser_file, parser_line, parser_col)); | create_source_code_location(parser_file, parser_line, parser_col)); | ||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| @@ -243,7 +243,7 @@ Ast_Node* parse_expression(char* text, int* index_in_text) { | |||||
| // okay there is something | // okay there is something | ||||
| Ast_Node* head = new(Ast_Node); | Ast_Node* head = new(Ast_Node); | ||||
| head->type = Ast_Node_Type_Pair; | |||||
| head->type = Ast_Node_Type::Pair; | |||||
| head->value.pair = new(Pair); | head->value.pair = new(Pair); | ||||
| Ast_Node* expression = head; | Ast_Node* expression = head; | ||||
| @@ -260,7 +260,7 @@ Ast_Node* parse_expression(char* text, int* index_in_text) { | |||||
| eat_until_code(text, index_in_text); | eat_until_code(text, index_in_text); | ||||
| if (text[(*index_in_text)] == '\0') { | if (text[(*index_in_text)] == '\0') { | ||||
| create_error(Error_Type_Unexpected_Eof, create_source_code_location(parser_file, parser_line, parser_col)); | |||||
| create_error(Error_Type::Unexpected_Eof, create_source_code_location(parser_file, parser_line, parser_col)); | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| @@ -283,7 +283,7 @@ Ast_Node* parse_expression(char* text, int* index_in_text) { | |||||
| eat_until_code(text, index_in_text); | eat_until_code(text, index_in_text); | ||||
| if (text[(*index_in_text)] != ')') | if (text[(*index_in_text)] != ')') | ||||
| create_error(Error_Type_Syntax_Error, create_source_code_location(parser_file, parser_line, parser_col)); | |||||
| create_error(Error_Type::Syntax_Error, create_source_code_location(parser_file, parser_line, parser_col)); | |||||
| ++parser_col; | ++parser_col; | ||||
| ++(*index_in_text); | ++(*index_in_text); | ||||
| break; | break; | ||||
| @@ -316,7 +316,7 @@ Ast_Node* parse_single_expression(char* text) { | |||||
| eat_until_code(text, &index_in_text); | eat_until_code(text, &index_in_text); | ||||
| if (text[(index_in_text)] == '\0') | if (text[(index_in_text)] == '\0') | ||||
| return result; | return result; | ||||
| create_error(Error_Type_Trailing_Garbage, create_source_code_location(parser_file, parser_line, parser_col)); | |||||
| create_error(Error_Type::Trailing_Garbage, create_source_code_location(parser_file, parser_line, parser_col)); | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| @@ -348,7 +348,7 @@ Ast_Node_Array_List* parse_program(char* file_name, char* text) { | |||||
| } break; | } break; | ||||
| default: | default: | ||||
| /* syntax error */ | /* syntax error */ | ||||
| create_error(Error_Type_Syntax_Error, create_source_code_location(parser_file, parser_line, parser_col)); | |||||
| create_error(Error_Type::Syntax_Error, create_source_code_location(parser_file, parser_line, parser_col)); | |||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| } | } | ||||
| @@ -94,26 +94,26 @@ testresult test_eval_operands() { | |||||
| assert_no_error(error); | assert_no_error(error); | ||||
| assert_equal_int(list_length(operands), 4); | assert_equal_int(list_length(operands), 4); | ||||
| assert_equal_type(operands, Ast_Node_Type_Pair); | |||||
| assert_equal_type(operands->value.pair->first, Ast_Node_Type_Number); | |||||
| assert_equal_type(operands, Ast_Node_Type::Pair); | |||||
| assert_equal_type(operands->value.pair->first, Ast_Node_Type::Number); | |||||
| assert_equal_double(operands->value.pair->first->value.number->value, 1); | assert_equal_double(operands->value.pair->first->value.number->value, 1); | ||||
| operands = operands->value.pair->rest; | operands = operands->value.pair->rest; | ||||
| assert_equal_type(operands, Ast_Node_Type_Pair); | |||||
| assert_equal_type(operands->value.pair->first, Ast_Node_Type_Number); | |||||
| assert_equal_type(operands, Ast_Node_Type::Pair); | |||||
| assert_equal_type(operands->value.pair->first, Ast_Node_Type::Number); | |||||
| assert_equal_double(operands->value.pair->first->value.number->value, 3); | assert_equal_double(operands->value.pair->first->value.number->value, 3); | ||||
| operands = operands->value.pair->rest; | operands = operands->value.pair->rest; | ||||
| assert_equal_type(operands, Ast_Node_Type_Pair); | |||||
| assert_equal_type(operands->value.pair->first, Ast_Node_Type_String); | |||||
| assert_equal_type(operands, Ast_Node_Type::Pair); | |||||
| assert_equal_type(operands->value.pair->first, Ast_Node_Type::String); | |||||
| assert_equal_string(operands->value.pair->first->value.string->value, "okay"); | assert_equal_string(operands->value.pair->first->value.string->value, "okay"); | ||||
| operands = operands->value.pair->rest; | operands = operands->value.pair->rest; | ||||
| assert_equal_type(operands, Ast_Node_Type_Pair); | |||||
| assert_equal_type(operands->value.pair->first, Ast_Node_Type_Keyword); | |||||
| assert_equal_type(operands, Ast_Node_Type::Pair); | |||||
| assert_equal_type(operands->value.pair->first, Ast_Node_Type::Keyword); | |||||
| assert_equal_string(operands->value.pair->first->value.keyword->identifier, "haha"); | assert_equal_string(operands->value.pair->first->value.keyword->identifier, "haha"); | ||||
| return pass; | return pass; | ||||
| @@ -130,46 +130,46 @@ testresult test_parse_atom() { | |||||
| // test numbers | // test numbers | ||||
| Ast_Node* result = parse_atom(string, &index_in_text); | Ast_Node* result = parse_atom(string, &index_in_text); | ||||
| assert_equal_type(result, Ast_Node_Type_Number); | |||||
| assert_equal_type(result, Ast_Node_Type::Number); | |||||
| assert_equal_double(result->value.number->value, 123); | assert_equal_double(result->value.number->value, 123); | ||||
| ++index_in_text; | ++index_in_text; | ||||
| result = parse_atom(string, &index_in_text); | result = parse_atom(string, &index_in_text); | ||||
| assert_equal_type(result, Ast_Node_Type_Number); | |||||
| assert_equal_type(result, Ast_Node_Type::Number); | |||||
| assert_equal_double(result->value.number->value, -1.23e-2); | assert_equal_double(result->value.number->value, -1.23e-2); | ||||
| // test strings | // test strings | ||||
| ++index_in_text; | ++index_in_text; | ||||
| result = parse_atom(string, &index_in_text); | result = parse_atom(string, &index_in_text); | ||||
| assert_equal_type(result, Ast_Node_Type_String); | |||||
| assert_equal_type(result, Ast_Node_Type::String); | |||||
| assert_equal_string(result->value.string->value, "asd"); | assert_equal_string(result->value.string->value, "asd"); | ||||
| // test keywords | // test keywords | ||||
| ++index_in_text; | ++index_in_text; | ||||
| result = parse_atom(string, &index_in_text); | result = parse_atom(string, &index_in_text); | ||||
| assert_equal_type(result, Ast_Node_Type_Keyword); | |||||
| assert_equal_type(result, Ast_Node_Type::Keyword); | |||||
| assert_equal_string(result->value.keyword->identifier, "key1"); | assert_equal_string(result->value.keyword->identifier, "key1"); | ||||
| ++index_in_text; | ++index_in_text; | ||||
| result = parse_atom(string, &index_in_text); | result = parse_atom(string, &index_in_text); | ||||
| assert_equal_type(result, Ast_Node_Type_Keyword); | |||||
| assert_equal_type(result, Ast_Node_Type::Keyword); | |||||
| assert_equal_string(result->value.keyword->identifier, "key:2"); | assert_equal_string(result->value.keyword->identifier, "key:2"); | ||||
| // test symbols | // test symbols | ||||
| ++index_in_text; | ++index_in_text; | ||||
| result = parse_atom(string, &index_in_text); | result = parse_atom(string, &index_in_text); | ||||
| assert_equal_type(result, Ast_Node_Type_Symbol); | |||||
| assert_equal_type(result, Ast_Node_Type::Symbol); | |||||
| assert_equal_string(result->value.symbol->identifier, "sym"); | assert_equal_string(result->value.symbol->identifier, "sym"); | ||||
| ++index_in_text; | ++index_in_text; | ||||
| result = parse_atom(string, &index_in_text); | result = parse_atom(string, &index_in_text); | ||||
| assert_equal_type(result, Ast_Node_Type_Symbol); | |||||
| assert_equal_type(result, Ast_Node_Type::Symbol); | |||||
| assert_equal_string(result->value.symbol->identifier, "+"); | assert_equal_string(result->value.symbol->identifier, "+"); | ||||
| return pass; | return pass; | ||||
| @@ -182,25 +182,25 @@ testresult test_parse_expression() { | |||||
| Ast_Node* result = parse_expression(string, &index_in_text); | Ast_Node* result = parse_expression(string, &index_in_text); | ||||
| assert_no_error(error); | assert_no_error(error); | ||||
| assert_equal_type(result, Ast_Node_Type_Pair); | |||||
| assert_equal_type(result->value.pair->first, Ast_Node_Type_Symbol); | |||||
| assert_equal_type(result, Ast_Node_Type::Pair); | |||||
| assert_equal_type(result->value.pair->first, Ast_Node_Type::Symbol); | |||||
| assert_equal_string(result->value.pair->first->value.symbol->identifier, "fun"); | assert_equal_string(result->value.pair->first->value.symbol->identifier, "fun"); | ||||
| result = result->value.pair->rest; | result = result->value.pair->rest; | ||||
| assert_equal_type(result, Ast_Node_Type_Pair); | |||||
| assert_equal_type(result->value.pair->first, Ast_Node_Type_Symbol); | |||||
| assert_equal_type(result, Ast_Node_Type::Pair); | |||||
| assert_equal_type(result->value.pair->first, Ast_Node_Type::Symbol); | |||||
| assert_equal_string(result->value.pair->first->value.symbol->identifier, "+"); | assert_equal_string(result->value.pair->first->value.symbol->identifier, "+"); | ||||
| result = result->value.pair->rest; | result = result->value.pair->rest; | ||||
| assert_equal_type(result, Ast_Node_Type_Pair); | |||||
| assert_equal_type(result->value.pair->first, Ast_Node_Type_Number); | |||||
| assert_equal_type(result, Ast_Node_Type::Pair); | |||||
| assert_equal_type(result->value.pair->first, Ast_Node_Type::Number); | |||||
| assert_equal_double(result->value.pair->first->value.number->value, 12); | assert_equal_double(result->value.pair->first->value.number->value, 12); | ||||
| result = result->value.pair->rest; | result = result->value.pair->rest; | ||||
| assert_equal_type(result, Ast_Node_Type_Nil); | |||||
| assert_equal_type(result, Ast_Node_Type::Nil); | |||||
| char string2[] = "(define fun (lambda (x) (+ 5 (* x x ))))"; | char string2[] = "(define fun (lambda (x) (+ 5 (* x x ))))"; | ||||
| index_in_text = 0; | index_in_text = 0; | ||||
| @@ -208,21 +208,21 @@ testresult test_parse_expression() { | |||||
| result = parse_expression(string2, &index_in_text); | result = parse_expression(string2, &index_in_text); | ||||
| assert_no_error(error); | assert_no_error(error); | ||||
| assert_equal_type(result, Ast_Node_Type_Pair); | |||||
| assert_equal_type(result->value.pair->first, Ast_Node_Type_Symbol); | |||||
| assert_equal_type(result, Ast_Node_Type::Pair); | |||||
| assert_equal_type(result->value.pair->first, Ast_Node_Type::Symbol); | |||||
| assert_equal_string(result->value.pair->first->value.symbol->identifier, "define"); | assert_equal_string(result->value.pair->first->value.symbol->identifier, "define"); | ||||
| result = result->value.pair->rest; | result = result->value.pair->rest; | ||||
| assert_equal_type(result, Ast_Node_Type_Pair); | |||||
| assert_equal_type(result->value.pair->first, Ast_Node_Type_Symbol); | |||||
| assert_equal_type(result, Ast_Node_Type::Pair); | |||||
| assert_equal_type(result->value.pair->first, Ast_Node_Type::Symbol); | |||||
| assert_equal_string(result->value.pair->first->value.symbol->identifier, "fun"); | assert_equal_string(result->value.pair->first->value.symbol->identifier, "fun"); | ||||
| result = result->value.pair->rest; | result = result->value.pair->rest; | ||||
| assert_equal_type(result, Ast_Node_Type_Pair); | |||||
| assert_equal_type(result->value.pair->first, Ast_Node_Type_Pair); | |||||
| assert_equal_type(result->value.pair->first->value.pair->first, Ast_Node_Type_Symbol); | |||||
| assert_equal_type(result, Ast_Node_Type::Pair); | |||||
| assert_equal_type(result->value.pair->first, Ast_Node_Type::Pair); | |||||
| assert_equal_type(result->value.pair->first->value.pair->first, Ast_Node_Type::Symbol); | |||||
| assert_equal_string(result->value.pair->first->value.pair->first->value.symbol->identifier, "lambda"); | assert_equal_string(result->value.pair->first->value.pair->first->value.symbol->identifier, "lambda"); | ||||
| result = result->value.pair->rest; | result = result->value.pair->rest; | ||||
| @@ -237,7 +237,7 @@ testresult test_built_in_add() { | |||||
| 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_type(result, Ast_Node_Type::Number); | |||||
| assert_equal_double(result->value.number->value, 14); | assert_equal_double(result->value.number->value, 14); | ||||
| return pass; | return pass; | ||||
| @@ -250,7 +250,7 @@ testresult test_built_in_substract() { | |||||
| 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_type(result, Ast_Node_Type::Number); | |||||
| assert_equal_double(result->value.number->value, 6); | assert_equal_double(result->value.number->value, 6); | ||||
| return pass; | return pass; | ||||
| @@ -264,7 +264,7 @@ testresult test_built_in_multiply() { | |||||
| 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_type(result, Ast_Node_Type::Number); | |||||
| assert_equal_double(result->value.number->value, 40); | assert_equal_double(result->value.number->value, 40); | ||||
| return pass; | return pass; | ||||
| @@ -278,7 +278,7 @@ testresult test_built_in_divide() { | |||||
| assert_null(error); | assert_null(error); | ||||
| assert_not_null(result); | assert_not_null(result); | ||||
| assert_equal_type(result, Ast_Node_Type_Number); | |||||
| assert_equal_type(result, Ast_Node_Type::Number); | |||||
| assert_equal_double(result->value.number->value, 5); | assert_equal_double(result->value.number->value, 5); | ||||
| return pass; | return pass; | ||||
| @@ -292,7 +292,7 @@ testresult test_built_in_if() { | |||||
| 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_type(result, Ast_Node_Type::Number); | |||||
| assert_equal_double(result->value.number->value, 4); | assert_equal_double(result->value.number->value, 4); | ||||
| char exp_string2[] = "(if () 4 5)"; | char exp_string2[] = "(if () 4 5)"; | ||||
| @@ -301,7 +301,7 @@ testresult test_built_in_if() { | |||||
| 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_type(result, Ast_Node_Type::Number); | |||||
| assert_equal_double(result->value.number->value, 5); | assert_equal_double(result->value.number->value, 5); | ||||
| return pass; | return pass; | ||||
| @@ -314,7 +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_T); | |||||
| 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)"; | ||||
| @@ -323,7 +323,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_Nil); | |||||
| assert_equal_type(result, Ast_Node_Type::Nil); | |||||
| return pass; | return pass; | ||||
| } | } | ||||
| @@ -335,7 +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_T); | |||||
| assert_equal_type(result, Ast_Node_Type::T); | |||||
| // a false case | // a false case | ||||
| char exp_string2[] = "(or () ())"; | char exp_string2[] = "(or () ())"; | ||||
| @@ -344,7 +344,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_Nil); | |||||
| assert_equal_type(result, Ast_Node_Type::Nil); | |||||
| return pass; | return pass; | ||||
| } | } | ||||
| @@ -358,7 +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_T); | |||||
| 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\")"; | ||||
| @@ -367,13 +367,13 @@ testresult test_built_in_not() { | |||||
| assert_no_error(error); | assert_no_error(error); | ||||
| assert_not_null(result); | assert_not_null(result); | ||||
| assert_equal_type(result, Ast_Node_Type_Nil); | |||||
| assert_equal_type(result, Ast_Node_Type::Nil); | |||||
| return pass; | return pass; | ||||
| } | } | ||||
| void run_all_tests() { | void run_all_tests() { | ||||
| log_level = Log_Level_None; | |||||
| log_level = Log_Level::None; | |||||
| printf("-- Parsing --\n"); | printf("-- Parsing --\n"); | ||||
| invoke_test(test_parse_atom); | invoke_test(test_parse_atom); | ||||