implement vectors
This commit is contained in:
+31
-1
@@ -22,6 +22,7 @@ proc lisp_object_equal(Lisp_Object* n1, Lisp_Object* n2) -> bool {
|
||||
case Lisp_Object_Type::Number: return n1->value.number == n2->value.number;
|
||||
case Lisp_Object_Type::String: return string_equal(n1->value.string, n2->value.string);
|
||||
case Lisp_Object_Type::Pair:
|
||||
case Lisp_Object_Type::Vector:
|
||||
create_not_yet_implemented_error();
|
||||
return false;
|
||||
}
|
||||
@@ -456,7 +457,7 @@ proc load_built_ins_into_environment() -> void {
|
||||
try assert_type(target_symbol, Lisp_Object_Type::Symbol);
|
||||
|
||||
Environment* target_env = find_binding_environment(target_symbol->value.symbol.identifier, get_current_environment());
|
||||
assert(target_env);
|
||||
try assert(target_env);
|
||||
|
||||
push_environment(target_env);
|
||||
defer {
|
||||
@@ -465,6 +466,28 @@ proc load_built_ins_into_environment() -> void {
|
||||
|
||||
define_symbol(target_symbol, source);
|
||||
|
||||
return source;
|
||||
});
|
||||
defun("set-car!", "TODO", __LINE__, cLambda {
|
||||
try evaluated_arguments = eval_arguments(arguments, &arguments_length);
|
||||
try assert_arguments_length(2, arguments_length);
|
||||
Lisp_Object* target = evaluated_arguments->value.pair.first;
|
||||
Lisp_Object* source = evaluated_arguments->value.pair.rest->value.pair.first;
|
||||
|
||||
assert_type(target, Lisp_Object_Type::Pair);
|
||||
|
||||
*target->value.pair.first = *source;
|
||||
return source;
|
||||
});
|
||||
defun("set-cdr!", "TODO", __LINE__, cLambda {
|
||||
try evaluated_arguments = eval_arguments(arguments, &arguments_length);
|
||||
try assert_arguments_length(2, arguments_length);
|
||||
Lisp_Object* target = evaluated_arguments->value.pair.first;
|
||||
Lisp_Object* source = evaluated_arguments->value.pair.rest->value.pair.first;
|
||||
|
||||
assert_type(target, Lisp_Object_Type::Pair);
|
||||
|
||||
*target->value.pair.rest = *source;
|
||||
return source;
|
||||
});
|
||||
defun("if", "TODO", __LINE__, cLambda {
|
||||
@@ -750,6 +773,12 @@ proc load_built_ins_into_environment() -> void {
|
||||
try evaluated_arguments = eval_arguments(arguments, &arguments_length);
|
||||
return evaluated_arguments;
|
||||
});
|
||||
defun("vector", "TODO", __LINE__, cLambda {
|
||||
try evaluated_arguments = eval_arguments(arguments, &arguments_length);
|
||||
Lisp_Object* ret;
|
||||
try ret = Memory::create_lisp_object_vector(arguments_length, evaluated_arguments);
|
||||
return ret;
|
||||
});
|
||||
defun("pair", "TODO", __LINE__, cLambda {
|
||||
try evaluated_arguments = eval_arguments(arguments, &arguments_length);
|
||||
try assert_arguments_length(2, arguments_length);
|
||||
@@ -829,6 +858,7 @@ proc load_built_ins_into_environment() -> void {
|
||||
case Lisp_Object_Type::T: return Memory::get_or_create_lisp_object_keyword("t");
|
||||
case Lisp_Object_Type::Number: return Memory::get_or_create_lisp_object_keyword("number");
|
||||
case Lisp_Object_Type::Pair: return Memory::get_or_create_lisp_object_keyword("pair");
|
||||
case Lisp_Object_Type::Vector: return Memory::get_or_create_lisp_object_keyword("vector");
|
||||
case Lisp_Object_Type::String: return Memory::get_or_create_lisp_object_keyword("string");
|
||||
case Lisp_Object_Type::Symbol: return Memory::get_or_create_lisp_object_keyword("symbol");
|
||||
}
|
||||
|
||||
@@ -294,6 +294,14 @@ proc print(Lisp_Object* node, bool print_repr = false, FILE* file = stdout) -> v
|
||||
else
|
||||
fputs(Memory::get_c_str(node->value.string), file);
|
||||
} break;
|
||||
case (Lisp_Object_Type::Vector): {
|
||||
fputs("[vector", file);
|
||||
for (int i = 0; i < node->value.vector.length; ++i) {
|
||||
fputs(" ", file);
|
||||
print(node->value.vector.data+i);
|
||||
}
|
||||
fputs("]", file);
|
||||
} break;
|
||||
case (Lisp_Object_Type::Function): {
|
||||
if (node->userType) {
|
||||
fprintf(file, "[%s]", Memory::get_c_str(node->userType->value.symbol.identifier));
|
||||
|
||||
@@ -21,6 +21,7 @@ proc Lisp_Object_Type_to_string(Lisp_Object_Type type) -> const char* {
|
||||
case(Lisp_Object_Type::CFunction): return "C-function";
|
||||
case(Lisp_Object_Type::Continuation): return "continuation";
|
||||
case(Lisp_Object_Type::Pair): return "pair";
|
||||
case(Lisp_Object_Type::Vector): return "vector";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
@@ -226,6 +226,50 @@ namespace Memory {
|
||||
return node;
|
||||
}
|
||||
|
||||
proc allocate_vector(int size) -> Lisp_Object* {
|
||||
/*
|
||||
int object_memory_size;
|
||||
Int_Array_List* free_spots_in_object_memory;
|
||||
Lisp_Object* object_memory;
|
||||
int next_index_in_object_memory = 0;
|
||||
|
||||
*/
|
||||
|
||||
if (object_memory_size - next_index_in_object_memory < size) {
|
||||
create_out_of_memory_error(
|
||||
"There is not enough space in the lisp object "
|
||||
"memory to allocate additional lisp objects. "
|
||||
"Maybe try increasing the Memory size when "
|
||||
"calling Memory::init()");
|
||||
return nullptr;
|
||||
}
|
||||
int start = next_index_in_object_memory;
|
||||
next_index_in_object_memory += size;
|
||||
return object_memory+start;
|
||||
}
|
||||
|
||||
proc create_lisp_object_vector(int length, Lisp_Object* element_list) -> Lisp_Object* {
|
||||
try assert_type(element_list, Lisp_Object_Type::Pair);
|
||||
|
||||
Lisp_Object* node;
|
||||
try node = create_lisp_object();
|
||||
set_type(node, Lisp_Object_Type::Vector);
|
||||
|
||||
node->value.vector.length = length;
|
||||
try node->value.vector.data = allocate_vector(length);
|
||||
|
||||
Lisp_Object* head = element_list;
|
||||
|
||||
int i = 0;
|
||||
while (head != Memory::nil) {
|
||||
node->value.vector.data[i] = *head->value.pair.first;
|
||||
head = head->value.pair.rest;
|
||||
++i;
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
proc get_or_create_lisp_object_symbol(String* identifier) -> Lisp_Object* {
|
||||
// TODO(Felix): if we already have it stored somewhere then
|
||||
// reuse it and dont create new one
|
||||
|
||||
@@ -16,6 +16,7 @@ enum struct Lisp_Object_Type {
|
||||
Number,
|
||||
String,
|
||||
Pair,
|
||||
Vector,
|
||||
Continuation,
|
||||
// Pointer,
|
||||
// OwningPointer,
|
||||
@@ -76,6 +77,11 @@ struct Pair {
|
||||
Lisp_Object* rest;
|
||||
};
|
||||
|
||||
struct Vector {
|
||||
int length;
|
||||
Lisp_Object* data;
|
||||
};
|
||||
|
||||
struct Positional_Arguments {
|
||||
Lisp_Object** symbols; // Array of Pointers to Lisp_Object<Symbol>
|
||||
int next_index;
|
||||
@@ -87,6 +93,7 @@ struct Keyword_Arguments {
|
||||
// NOTE(Felix): values[i] will be nullptr if no defalut value was
|
||||
// declared for key identifiers[i]
|
||||
Lisp_Object_Array_List* values;
|
||||
// TODO(Felix): Why do we use a Array list here??
|
||||
int next_index;
|
||||
int length;
|
||||
};
|
||||
@@ -116,6 +123,7 @@ struct Lisp_Object {
|
||||
double number;
|
||||
String* string;
|
||||
Pair pair;
|
||||
Vector vector;
|
||||
Function function;
|
||||
cFunction* cFunction;
|
||||
Continuation continuation;
|
||||
|
||||
@@ -639,6 +639,8 @@ proc run_all_tests() -> bool {
|
||||
invoke_test_script("import_and_load");
|
||||
invoke_test_script("sicp");
|
||||
invoke_test_script("macro_expand");
|
||||
invoke_test_script("automata");
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user