renaming "ast_node" -> "lisp_object"

This commit is contained in:
FelixBrendel
2019-01-18 22:03:39 +01:00
parent fec24d11c7
commit a297f59946
9 changed files with 493 additions and 493 deletions
+230
View File
@@ -0,0 +1,230 @@
struct Lisp_Object;
define_array_list(Lisp_Object*, Lisp_Object);
enum struct Lisp_Object_Type {
Nil,
T,
Symbol,
Keyword,
Number,
String,
Pair,
Function,
CFunction,
};
char* Lisp_Object_Type_to_string(Lisp_Object_Type type) {
switch (type) {
case(Lisp_Object_Type::Nil): return "nil";
case(Lisp_Object_Type::T): return "t";
case(Lisp_Object_Type::Number): return "number";
case(Lisp_Object_Type::String): return "string";
case(Lisp_Object_Type::Symbol): return "symbol";
case(Lisp_Object_Type::Keyword): return "keyword";
case(Lisp_Object_Type::Function): return "function";
case(Lisp_Object_Type::CFunction): return "C-function";
case(Lisp_Object_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 {
Lisp_Object* first;
Lisp_Object* rest;
};
struct Positional_Arguments {
// TODO(Felix) use Lisp_Object_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;
// NOTE(Felix): values[i] will be nullptr if no defalut value was
// declared for key identifiers[i]
Lisp_Object_Array_List* values;
int next_index;
int length;
};
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_Lisp_Object_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 Lisp_Object* 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_Lisp_Object_array_list(args->values, default_value);
}
struct Environment;
enum struct Function_Type {
Lambda,
Special_Lambda,
Macro
};
struct Function {
Function_Type type;
char* docstring;
Positional_Arguments* positional_arguments;
Keyword_Arguments* keyword_arguments;
// rest_argument will be nullptr if no rest argument is declared
char* rest_argument;
Lisp_Object* body; // implicit prog
Environment* parent_environment; // we are doing closures now!!
};
struct CFunction {
std::function<Lisp_Object* (Lisp_Object*, Environment*)> function;
};
struct Lisp_Object {
Source_Code_Location* sourceCodeLocation;
Lisp_Object_Type type;
union {
Symbol* symbol;
Keyword* keyword;
Number* number;
String* string;
Pair* pair;
Function* function;
CFunction* cfunction;
} value;
};
struct Parsed_Arguments {
Lisp_Object_Array_List* positional_arguments;
// TODO(Felix): Really use hashmap (keyword[sting] ->
// value[Lisp_Object*]) here
Lisp_Object_Array_List* keyword_keys;
Lisp_Object_Array_List* keyword_values;
};
Lisp_Object* create_lisp_object() {
Lisp_Object* node = new(Lisp_Object);
node->sourceCodeLocation = nullptr;
return node;
}
Lisp_Object* create_lisp_object_nil() {
Lisp_Object* node = create_lisp_object();
node->type = Lisp_Object_Type::Nil;
node->value.pair = nullptr;
return node;
}
Lisp_Object* create_lisp_object_t() {
Lisp_Object* node = create_lisp_object();
node->type = Lisp_Object_Type::T;
node->value.pair = nullptr;
return node;
}
Lisp_Object* create_lisp_object_number(double number) {
Lisp_Object* node = create_lisp_object();
node->type = Lisp_Object_Type::Number;
node->value.number = new(Number);
node->value.number->value = number;
return node;
}
Lisp_Object* create_lisp_object_string(char* str, int length) {
Lisp_Object* node = create_lisp_object();
node->type = Lisp_Object_Type::String;
node->value.string = new(String);
node->value.string->value = str;
node->value.string->length = length;
return node;
}
Lisp_Object* create_lisp_object_symbol(char* identifier) {
Lisp_Object* node = create_lisp_object();
node->type = Lisp_Object_Type::Symbol;
node->value.symbol = new(Symbol);
node->value.symbol->identifier = identifier;
return node;
}
Lisp_Object* create_lisp_object_keyword(char* keyword) {
Lisp_Object* node = create_lisp_object();
node->type = Lisp_Object_Type::Keyword;
node->value.keyword = new(Keyword);
node->value.keyword->identifier = keyword;
return node;
}
Lisp_Object* create_lisp_object_cfunction(std::function<Lisp_Object*(Lisp_Object*, Environment*)> function) {
Lisp_Object* node = create_lisp_object();
node->type = Lisp_Object_Type::CFunction;
node->value.cfunction = new(CFunction);
node->value.cfunction->function = function;
return node;
}
Lisp_Object* create_lisp_object_pair(Lisp_Object* first, Lisp_Object* rest) {
Lisp_Object* node = create_lisp_object();
node->type = Lisp_Object_Type::Pair;
node->value.pair = new(Pair);
node->value.pair->first = first;
node->value.pair->rest = rest;
return node;
}
Lisp_Object* copy_lisp_object(Lisp_Object* n) {
Lisp_Object* target = create_lisp_object();
*target = *n;
return target;
}