some memory management

This commit is contained in:
FelixBrendel
2019-01-28 13:39:10 +01:00
parent a297f59946
commit 29bd534525
15 changed files with 430 additions and 395 deletions
-178
View File
@@ -1,19 +1,3 @@
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";
@@ -29,46 +13,6 @@ char* Lisp_Object_Type_to_string(Lisp_Object_Type type) {
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*));
@@ -106,125 +50,3 @@ void append_to_keyword_argument_list(Keyword_Arguments* args,
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;
}