|
- struct Ast_Node;
-
- // #define define_array_list(type, name) \
- // struct name##_Array_List { \
- // type* data; \
- // int length; \
- // int next_index; \
- // }; \
- // \
- // \
- // void append_to_##name##_array_list(name##_Array_List* arraylist, type element) { \
- // if (arraylist->next_index == arraylist->length) { \
- // arraylist->length *= 2; \
- // arraylist->data = \
- // (type*)realloc(arraylist->data, arraylist->length * sizeof(type)); \
- // } \
- // arraylist->data[arraylist->next_index++] = element; \
- // } \
- // \
- // \
- // name##_Array_List* create_##name##_array_list(int initial_capacity) { \
- // name##_Array_List* ret = new(name##_Array_List); \
- // ret->data = (type*)malloc(initial_capacity * sizeof(type)); \
- // ret->next_index = 0; \
- // ret->length = initial_capacity; \
- // return ret; \
- // }
-
- define_array_list(Ast_Node*, Ast_Node);
-
- enum struct Ast_Node_Type {
- Nil,
- T,
- Symbol,
- Keyword,
- Number,
- String,
- Pair,
- Function,
- CFunction,
- };
-
- char* Ast_Node_Type_to_string(Ast_Node_Type 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";
- }
- return "unknown";
- }
-
- struct Symbol {
- char* identifier;
- };
-
- struct Keyword {
- char* identifier;
- };
-
- struct Number {
- double value;
- };
-
- struct String {
- char* value;
- int length;
- };
-
- struct Pair {
- struct Ast_Node* first;
- struct Ast_Node* rest;
- };
-
- struct Positional_Arguments {
- // TODO(Felix) use Ast_Node_symbols here instead, so we don't have
- // to convert them to strings and back to symbols
- char** identifiers;
- int next_index;
- int length;
- };
-
- struct Keyword_Arguments {
- char** identifiers;
- // values[i] will be nullptr if no defalut value was declared for
- // key identifiers[i]
- Ast_Node_Array_List* values;
- int next_index;
- int length;
- };
-
-
- /* Ast_Node_Array_List* create_Ast_Node_Array_List(int initial_length); */
- /* void append_to_Ast_Node_Array_List(Ast_Node_Array_List* list, struct Ast_Node* node); */
-
- Positional_Arguments* create_positional_argument_list(int initial_capacity) {
- Positional_Arguments* ret = new(Positional_Arguments);
- ret->identifiers = (char**)malloc(initial_capacity * sizeof(char*));
- ret->next_index = 0;
- ret->length = initial_capacity;
- return ret;
- }
-
- void append_to_positional_argument_list(Positional_Arguments* args, char* identifier) {
- if (args->next_index == args->length) {
- args->length *= 2;
- args->identifiers = (char**)realloc(args->identifiers, args->length * sizeof(char*));
- }
- args->identifiers[args->next_index++] = identifier;
- }
-
- Keyword_Arguments* create_keyword_argument_list(int initial_capacity) {
- Keyword_Arguments* ret = new(Keyword_Arguments);
- ret->identifiers = (char**)malloc(initial_capacity * sizeof(char*));
- ret->values = create_Ast_Node_array_list(initial_capacity);
- ret->next_index = 0;
- ret->length = initial_capacity;
- return ret;
- }
-
- void append_to_keyword_argument_list(Keyword_Arguments* args,
- char* identifier,
- struct Ast_Node* default_value)
- {
- if (args->next_index == args->length) {
- args->length *= 2;
- args->identifiers = (char**)realloc(args->identifiers, args->length * sizeof(char*));
- }
-
- args->identifiers[args->next_index++] = identifier;
- append_to_Ast_Node_array_list(args->values, default_value);
- }
-
- struct Environment;
-
- struct Function {
- bool is_special_form;
- char* docstring;
- Positional_Arguments* positional_arguments;
- Keyword_Arguments* keyword_arguments;
- // rest_argument will be nullptr if no rest argument is declared
- char* rest_argument;
- Ast_Node* body; // implicit prog
- Environment* parent_environment; // we are doing closures now!!
- };
-
-
- struct CFunction {
- std::function<Ast_Node*(Ast_Node*, Environment*)> function;
- };
-
- struct Ast_Node {
- Source_Code_Location* sourceCodeLocation;
- Ast_Node_Type type;
- union {
- Symbol* symbol;
- Keyword* keyword;
- Number* number;
- String* string;
- Pair* pair;
- Function* function;
- CFunction* cfunction;
- } value;
- };
-
- struct Parsed_Arguments {
- Ast_Node_Array_List* positional_arguments;
- // TODO(Felix): Really use hashmap (keyword[sting] ->
- // value[Ast_Node*]) here
- Ast_Node_Array_List* keyword_keys;
- Ast_Node_Array_List* keyword_values;
- };
-
- Ast_Node* create_ast_node() {
- Ast_Node* node = new(Ast_Node);
- node->sourceCodeLocation = nullptr;
- return node;
- }
-
- Ast_Node* create_ast_node_nil() {
- Ast_Node* node = create_ast_node();
- node->type = Ast_Node_Type::Nil;
- node->value.pair = nullptr;
- return node;
- }
-
- Ast_Node* create_ast_node_t() {
- Ast_Node* node = create_ast_node();
- node->type = Ast_Node_Type::T;
- node->value.pair = nullptr;
- return node;
- }
-
- Ast_Node* create_ast_node_number(double number) {
- Ast_Node* node = create_ast_node();
- node->type = Ast_Node_Type::Number;
- node->value.number = new(Number);
- node->value.number->value = number;
- return node;
- }
-
- Ast_Node* create_ast_node_string(char* str, int length) {
- Ast_Node* node = create_ast_node();
- node->type = Ast_Node_Type::String;
- node->value.string = new(String);
- node->value.string->value = str;
- node->value.string->length = length;
- return node;
- }
-
- Ast_Node* create_ast_node_symbol(char* identifier) {
- Ast_Node* node = create_ast_node();
- node->type = Ast_Node_Type::Symbol;
- node->value.symbol = new(Symbol);
- node->value.symbol->identifier = identifier;
- return node;
- }
-
- Ast_Node* create_ast_node_keyword(char* keyword) {
- Ast_Node* node = create_ast_node();
- node->type = Ast_Node_Type::Keyword;
- node->value.keyword = new(Keyword);
- node->value.keyword->identifier = keyword;
- return node;
- }
-
- Ast_Node* create_ast_node_cfunction(std::function<Ast_Node*(Ast_Node*, Environment*)> function) {
- Ast_Node* node = create_ast_node();
- node->type = Ast_Node_Type::CFunction;
- node->value.cfunction = new(CFunction);
- node->value.cfunction->function = function;
- return node;
- }
-
- Ast_Node* create_ast_node_pair(Ast_Node* first, Ast_Node* rest) {
- Ast_Node* node = create_ast_node();
- node->type = Ast_Node_Type::Pair;
- node->value.pair = new(Pair);
- node->value.pair->first = first;
- node->value.pair->rest = rest;
- return node;
- }
-
- Ast_Node* copy_ast_node(Ast_Node* n) {
- Ast_Node* target = create_ast_node();
- *target = *n;
- return target;
- }
|