some memory management
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user