Просмотр исходного кода

Moved type info into a flags field in the lisp objects

master
Felix Brendel 7 лет назад
Родитель
Сommit
3277e50164
9 измененных файлов: 139 добавлений и 131 удалений
  1. +43
    -41
      src/built_ins.cpp
  2. +2
    -2
      src/defines.cpp
  3. +42
    -41
      src/eval.cpp
  4. +1
    -0
      src/forward_decls.cpp
  5. +4
    -4
      src/io.cpp
  6. +24
    -9
      src/memory.cpp
  7. +7
    -7
      src/parse.cpp
  8. +10
    -21
      src/structs.cpp
  9. +6
    -6
      src/testing.cpp

+ 43
- 41
src/built_ins.cpp Просмотреть файл

@@ -1,10 +1,10 @@
proc lisp_object_equal(Lisp_Object* n1, Lisp_Object* n2) -> bool { proc lisp_object_equal(Lisp_Object* n1, Lisp_Object* n2) -> bool {
if (n1 == n2) if (n1 == n2)
return true; return true;
if (n1->type != n2->type)
if (Memory::get_type(n1) != Memory::get_type(n2))
return false; return false;


switch (n1->type) {
switch (Memory::get_type(n1)) {


case Lisp_Object_Type::CFunction: // if they have the same case Lisp_Object_Type::CFunction: // if they have the same
// pointer, true is returned a // pointer, true is returned a
@@ -72,7 +72,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
proc parse_lambda_starting_from_args = [&](Lisp_Object* arguments, Environment* env, bool is_special = false) -> Lisp_Object* { proc parse_lambda_starting_from_args = [&](Lisp_Object* arguments, Environment* env, bool is_special = false) -> Lisp_Object* {
// Function* function = new(Function); // Function* function = new(Function);
Lisp_Object* ret = Memory::create_lisp_object(); Lisp_Object* ret = Memory::create_lisp_object();
ret->type = Lisp_Object_Type::Function;
Memory::set_type(ret, Lisp_Object_Type::Function);


ret->value.function.parent_environment = env; ret->value.function.parent_environment = env;


@@ -82,7 +82,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
ret->value.function.type = Function_Type::Lambda; ret->value.function.type = Function_Type::Lambda;


// if parameters were specified // if parameters were specified
if (arguments->value.pair.first->type != Lisp_Object_Type::Nil) {
if (arguments->value.pair.first != Memory::nil) {
try { try {
assert_type(arguments->value.pair.first, Lisp_Object_Type::Pair); assert_type(arguments->value.pair.first, Lisp_Object_Type::Pair);
} }
@@ -97,7 +97,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {


arguments = arguments->value.pair.rest; arguments = arguments->value.pair.rest;
// if there is a docstring, use it // if there is a docstring, use it
if (arguments->value.pair.first->type == Lisp_Object_Type::String) {
if (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::String) {
ret->value.function.docstring = arguments->value.pair.first->value.string; ret->value.function.docstring = arguments->value.pair.first->value.string;
arguments = arguments->value.pair.rest; arguments = arguments->value.pair.rest;
} else { } else {
@@ -121,12 +121,12 @@ proc load_built_ins_into_environment(Environment* env) -> void {
arguments = eval_arguments(arguments, env, &arguments_length); arguments = eval_arguments(arguments, env, &arguments_length);
} }


if (arguments->type == Lisp_Object_Type::Nil)
if (arguments == Memory::nil)
return Memory::t; return Memory::t;


Lisp_Object* first = arguments->value.pair.first; Lisp_Object* first = arguments->value.pair.first;


while (arguments->type == Lisp_Object_Type::Pair) {
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) {
if (!lisp_object_equal(arguments->value.pair.first, first)) if (!lisp_object_equal(arguments->value.pair.first, first))
return Memory::nil; return Memory::nil;
arguments = arguments->value.pair.rest; arguments = arguments->value.pair.rest;
@@ -142,7 +142,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {


double last_number = strtod("Inf", NULL); double last_number = strtod("Inf", NULL);


while (arguments->type == Lisp_Object_Type::Pair) {
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) {
try { try {
assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); assert_type(arguments->value.pair.first, Lisp_Object_Type::Number);
} }
@@ -164,7 +164,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {


double last_number = strtod("Inf", NULL); double last_number = strtod("Inf", NULL);


while (arguments->type == Lisp_Object_Type::Pair) {
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) {
try { try {
assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); assert_type(arguments->value.pair.first, Lisp_Object_Type::Number);
} }
@@ -186,7 +186,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {


double last_number = strtod("-Inf", NULL); double last_number = strtod("-Inf", NULL);


while (arguments->type == Lisp_Object_Type::Pair) {
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) {
try { try {
assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); assert_type(arguments->value.pair.first, Lisp_Object_Type::Number);
} }
@@ -208,7 +208,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {


double last_number = strtod("-Inf", NULL); double last_number = strtod("-Inf", NULL);


while (arguments->type == Lisp_Object_Type::Pair) {
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) {
try { try {
assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); assert_type(arguments->value.pair.first, Lisp_Object_Type::Number);
} }
@@ -229,7 +229,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
} }


double sum = 0; double sum = 0;
while (arguments->type == Lisp_Object_Type::Pair) {
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) {
try { try {
assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); assert_type(arguments->value.pair.first, Lisp_Object_Type::Number);
} }
@@ -251,7 +251,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
double difference = arguments->value.pair.first->value.number; double difference = arguments->value.pair.first->value.number;


arguments = arguments->value.pair.rest; arguments = arguments->value.pair.rest;
while (arguments->type == Lisp_Object_Type::Pair) {
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) {
try { try {
assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); assert_type(arguments->value.pair.first, Lisp_Object_Type::Number);
} }
@@ -273,7 +273,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
double product = arguments->value.pair.first->value.number; double product = arguments->value.pair.first->value.number;


arguments = arguments->value.pair.rest; arguments = arguments->value.pair.rest;
while (arguments->type == Lisp_Object_Type::Pair) {
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) {
try { try {
assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); assert_type(arguments->value.pair.first, Lisp_Object_Type::Number);
} }
@@ -295,7 +295,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
double quotient = arguments->value.pair.first->value.number; double quotient = arguments->value.pair.first->value.number;


arguments = arguments->value.pair.rest; arguments = arguments->value.pair.rest;
while (arguments->type == Lisp_Object_Type::Pair) {
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) {
try { try {
assert_type(arguments->value.pair.first, Lisp_Object_Type::Number); assert_type(arguments->value.pair.first, Lisp_Object_Type::Number);
} }
@@ -351,7 +351,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
Lisp_Object* symbol = arguments->value.pair.first; Lisp_Object* symbol = arguments->value.pair.first;
Lisp_Object* value; Lisp_Object* value;


if (symbol->type == Lisp_Object_Type::Pair) {
if (Memory::get_type(symbol) == Lisp_Object_Type::Pair) {
/* /*
1: arguments 1: arguments
2: symbol 2: symbol
@@ -433,9 +433,9 @@ proc load_built_ins_into_environment(Environment* env) -> void {
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
try assert(arguments_length == 2); try assert(arguments_length == 2);


if (evaluated_arguments->value.pair.first->type == Lisp_Object_Type::Nil ||
evaluated_arguments->value.pair.first->type == Lisp_Object_Type::T ||
evaluated_arguments->value.pair.first->type == Lisp_Object_Type::Keyword)
if (evaluated_arguments->value.pair.first == Memory::nil ||
evaluated_arguments->value.pair.first == Memory::t ||
Memory::get_type(evaluated_arguments->value.pair.first) == Lisp_Object_Type::Keyword)
{ {
create_generic_error("You cannot mutate nil, t or keywords"); create_generic_error("You cannot mutate nil, t or keywords");
} }
@@ -486,12 +486,12 @@ proc load_built_ins_into_environment(Environment* env) -> void {
std::function<Lisp_Object*(Lisp_Object*)> unquoteSomeExpressions; // = [] (Lisp_Object* expr) -> Lisp_Object* {return nullptr;}; std::function<Lisp_Object*(Lisp_Object*)> unquoteSomeExpressions; // = [] (Lisp_Object* expr) -> Lisp_Object* {return nullptr;};
unquoteSomeExpressions = [&unquoteSomeExpressions, &env] (Lisp_Object* expr) -> Lisp_Object* { unquoteSomeExpressions = [&unquoteSomeExpressions, &env] (Lisp_Object* expr) -> Lisp_Object* {
// if it is an atom, return it // if it is an atom, return it
if (expr->type != Lisp_Object_Type::Pair)
if (Memory::get_type(expr) != Lisp_Object_Type::Pair)
return Memory::copy_lisp_object(expr); return Memory::copy_lisp_object(expr);


// it is a pair! // it is a pair!
Lisp_Object* originalPair = expr->value.pair.first; Lisp_Object* originalPair = expr->value.pair.first;
if (originalPair->type == Lisp_Object_Type::Symbol &&
if (Memory::get_type(originalPair) == Lisp_Object_Type::Symbol &&
string_equal(originalPair->value.identifier, "unquote")) string_equal(originalPair->value.identifier, "unquote"))
{ {
// eval replace the stuff // eval replace the stuff
@@ -510,10 +510,10 @@ proc load_built_ins_into_environment(Environment* env) -> void {
Lisp_Object* newPair = Memory::create_lisp_object_pair(nullptr, nullptr); Lisp_Object* newPair = Memory::create_lisp_object_pair(nullptr, nullptr);
Lisp_Object* newPairHead = newPair; Lisp_Object* newPairHead = newPair;
Lisp_Object* head = expr; Lisp_Object* head = expr;
while (head->type == Lisp_Object_Type::Pair) {
while (Memory::get_type(head) == Lisp_Object_Type::Pair) {
newPairHead->value.pair.first = unquoteSomeExpressions(head->value.pair.first); newPairHead->value.pair.first = unquoteSomeExpressions(head->value.pair.first);


if (head->value.pair.rest->type != Lisp_Object_Type::Pair)
if (Memory::get_type(head->value.pair.rest) != Lisp_Object_Type::Pair)
break; break;


newPairHead->value.pair.rest = Memory::create_lisp_object_pair(nullptr, nullptr); newPairHead->value.pair.rest = Memory::create_lisp_object_pair(nullptr, nullptr);
@@ -534,7 +534,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
}); });
defun("and", cLambda { defun("and", cLambda {
bool result = true; bool result = true;
while (arguments->type != Lisp_Object_Type::Nil) {
while (arguments != Memory::nil) {
try assert_type(arguments, Lisp_Object_Type::Pair); try assert_type(arguments, Lisp_Object_Type::Pair);
try result &= is_truthy(arguments->value.pair.first, env); try result &= is_truthy(arguments->value.pair.first, env);


@@ -545,7 +545,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
}); });
defun("or", cLambda { defun("or", cLambda {
bool result = false; bool result = false;
while (arguments->type != Lisp_Object_Type::Nil) {
while (arguments != Memory::nil) {
try assert_type(arguments, Lisp_Object_Type::Pair); try assert_type(arguments, Lisp_Object_Type::Pair);
try result |= is_truthy(arguments->value.pair.first, env); try result |= is_truthy(arguments->value.pair.first, env);


@@ -576,7 +576,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
while (true) { while (true) {
try condition = eval_expr(condition_part, env); try condition = eval_expr(condition_part, env);


if (condition->type == Lisp_Object_Type::Nil)
if (condition == Memory::nil)
break; break;


try result = eval_expr(then_part->value.pair.first, env); try result = eval_expr(then_part->value.pair.first, env);
@@ -592,7 +592,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
Environment* let_env = Memory::create_child_environment(env); Environment* let_env = Memory::create_child_environment(env);
Lisp_Object* bindings = arguments->value.pair.first; Lisp_Object* bindings = arguments->value.pair.first;
while (true) { while (true) {
if (bindings->type == Lisp_Object_Type::Nil) {
if (bindings == Memory::nil) {
break; break;
} }


@@ -622,7 +622,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
Lisp_Object* evaluated_arguments; Lisp_Object* evaluated_arguments;
try evaluated_arguments = eval_arguments(arguments, let_env, &arguments_length); try evaluated_arguments = eval_arguments(arguments, let_env, &arguments_length);


if (evaluated_arguments->type == Lisp_Object_Type::Nil)
if (evaluated_arguments == Memory::nil)
return evaluated_arguments; return evaluated_arguments;


// skip to the last evaluated operand and return it, // skip to the last evaluated operand and return it,
@@ -630,7 +630,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
// manually, because we want to increase code reuse, // manually, because we want to increase code reuse,
// but at the cost that we have to find the end of the // but at the cost that we have to find the end of the
// list again // list again
while (evaluated_arguments->value.pair.rest->type == Lisp_Object_Type::Pair) {
while (Memory::get_type(evaluated_arguments->value.pair.rest) == Lisp_Object_Type::Pair) {
evaluated_arguments = evaluated_arguments->value.pair.rest; evaluated_arguments = evaluated_arguments->value.pair.rest;
} }
return evaluated_arguments->value.pair.first; return evaluated_arguments->value.pair.first;
@@ -670,7 +670,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
defun("prog", cLambda { defun("prog", cLambda {
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);


if (evaluated_arguments->type == Lisp_Object_Type::Nil)
if (evaluated_arguments == Memory::nil)
return evaluated_arguments; return evaluated_arguments;


// skip to the last evaluated operand and return it, // skip to the last evaluated operand and return it,
@@ -678,7 +678,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
// manually, because we want to increase code reuse, // manually, because we want to increase code reuse,
// but at the cost that we have to find the end of the // but at the cost that we have to find the end of the
// list again // list again
while (evaluated_arguments->value.pair.rest->type == Lisp_Object_Type::Pair) {
while (Memory::get_type(evaluated_arguments->value.pair.rest) == Lisp_Object_Type::Pair) {
evaluated_arguments = evaluated_arguments->value.pair.rest; evaluated_arguments = evaluated_arguments->value.pair.rest;
} }
return evaluated_arguments->value.pair.first; return evaluated_arguments->value.pair.first;
@@ -698,7 +698,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
try assert(arguments_length == 1); try assert(arguments_length == 1);


if (evaluated_arguments->value.pair.first->type == Lisp_Object_Type::Nil)
if (evaluated_arguments->value.pair.first == Memory::nil)
return Memory::nil; return Memory::nil;


try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::Pair); try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::Pair);
@@ -709,7 +709,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length); try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
try assert(arguments_length == 1); try assert(arguments_length == 1);


if (evaluated_arguments->value.pair.first->type == Lisp_Object_Type::Nil)
if (evaluated_arguments->value.pair.first == Memory::nil)
return Memory::nil; return Memory::nil;


try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::Pair); try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::Pair);
@@ -743,7 +743,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
return evaluated_arguments->value.pair.first->userType; return evaluated_arguments->value.pair.first->userType;
} }


Lisp_Object_Type type = evaluated_arguments->value.pair.first->type;
Lisp_Object_Type type = Memory::get_type(evaluated_arguments->value.pair.first);
switch (type) { switch (type) {
case Lisp_Object_Type::CFunction: return Memory::get_or_create_lisp_object_keyword("cfunction"); case Lisp_Object_Type::CFunction: return Memory::get_or_create_lisp_object_keyword("cfunction");
case Lisp_Object_Type::Function: { case Lisp_Object_Type::Function: {
@@ -784,7 +784,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
printf("\n\n"); printf("\n\n");


// TODO(Felix): Maybe don't compare strings here?? Wtf // TODO(Felix): Maybe don't compare strings here?? Wtf
if (type->type == Lisp_Object_Type::Keyword &&
if (Memory::get_type(type) == Lisp_Object_Type::Keyword &&
(string_equal(type->value.identifier, "lambda") || (string_equal(type->value.identifier, "lambda") ||
string_equal(type->value.identifier, "special-lambda") || string_equal(type->value.identifier, "special-lambda") ||
string_equal(type->value.identifier, "macro"))) string_equal(type->value.identifier, "macro")))
@@ -937,11 +937,13 @@ proc load_built_ins_into_environment(Environment* env) -> void {
try assert(arguments_length == 1); try assert(arguments_length == 1);




if (evaluated_arguments->value.pair.first->type == Lisp_Object_Type::Nil ||
evaluated_arguments->value.pair.first->type == Lisp_Object_Type::T ||
evaluated_arguments->value.pair.first->type == Lisp_Object_Type::Keyword)
if (evaluated_arguments->value.pair.first == Memory::nil ||
evaluated_arguments->value.pair.first == Memory::t ||
Memory::get_type(evaluated_arguments->value.pair.first) == Lisp_Object_Type::Symbol ||
Memory::get_type(evaluated_arguments->value.pair.first) == Lisp_Object_Type::Keyword)
{ {
create_generic_error("The values of 'nil', 't', and keywords can't be copied.");
// we don't copy singleton objects
return evaluated_arguments->value.pair.first;
} }


Lisp_Object* target = Memory::create_lisp_object(); Lisp_Object* target = Memory::create_lisp_object();
@@ -995,7 +997,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {


Lisp_Object* head = evaluated_arguments; Lisp_Object* head = evaluated_arguments;


while (head->type == Lisp_Object_Type::Pair) {
while (Memory::get_type(head) == Lisp_Object_Type::Pair) {
try assert_type(head->value.pair.first, Lisp_Object_Type::String); try assert_type(head->value.pair.first, Lisp_Object_Type::String);


resulting_string_len += head->value.pair.first->value.string->length; resulting_string_len += head->value.pair.first->value.string->length;
@@ -1007,7 +1009,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
String* resulting_string = Memory::create_string("", resulting_string_len); String* resulting_string = Memory::create_string("", resulting_string_len);
int index_in_string = 0; int index_in_string = 0;


while (head->type == Lisp_Object_Type::Pair) {
while (Memory::get_type(head) == Lisp_Object_Type::Pair) {
strcpy((&resulting_string->data)+index_in_string, strcpy((&resulting_string->data)+index_in_string,
Memory::get_c_str(head->value.pair.first->value.string)); Memory::get_c_str(head->value.pair.first->value.string));
index_in_string += head->value.pair.first->value.string->length; index_in_string += head->value.pair.first->value.string->length;


+ 2
- 2
src/defines.cpp Просмотреть файл

@@ -151,8 +151,8 @@ struct {


#define assert_type(_node, _type) \ #define assert_type(_node, _type) \
do { \ do { \
if (_node->type != _type) { \
create_type_missmatch_error("symbol", Lisp_Object_Type_to_string(_node->type)); \
if (Memory::get_type(_node) != _type) { \
create_type_missmatch_error("symbol", Lisp_Object_Type_to_string(Memory::get_type(_node))); \
} \ } \
} while(0) } while(0)




+ 42
- 41
src/eval.cpp Просмотреть файл

@@ -3,7 +3,7 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->


// positional arguments // positional arguments
for (int i = 0; i < function->positional_arguments->next_index; ++i) { for (int i = 0; i < function->positional_arguments->next_index; ++i) {
if (arguments->type != Lisp_Object_Type::Pair) {
if (Memory::get_type(arguments) != Lisp_Object_Type::Pair) {
create_wrong_number_of_arguments_error(function->positional_arguments->next_index, i); create_wrong_number_of_arguments_error(function->positional_arguments->next_index, i);
return nullptr; return nullptr;
} }
@@ -19,14 +19,14 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->


String_Array_List* read_in_keywords = create_String_array_list(); String_Array_List* read_in_keywords = create_String_array_list();


if (arguments->type == Lisp_Object_Type::Nil)
if (Memory::get_type(arguments) == Lisp_Object_Type::Nil)
goto checks; goto checks;
// keyword arguments: use all given ones and keep track of the // keyword arguments: use all given ones and keep track of the
// added ones (array list), if end of parameters in encountered or // added ones (array list), if end of parameters in encountered or
// something that is not a keyword is encountered or a keyword // something that is not a keyword is encountered or a keyword
// that is not recognized is encoutered, jump out of the loop. // that is not recognized is encoutered, jump out of the loop.


while (arguments->value.pair.first->type == Lisp_Object_Type::Keyword) {
while (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Keyword) {
// check if this one is even an accepted keyword // check if this one is even an accepted keyword
bool accepted = false; bool accepted = false;
for (int i = 0; i < function->keyword_arguments->next_index; ++i) { for (int i = 0; i < function->keyword_arguments->next_index; ++i) {
@@ -69,7 +69,7 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->
// okay so we found a keyword that has to be read in and was // okay so we found a keyword that has to be read in and was
// not already read in, is there a next element to actually // not already read in, is there a next element to actually
// set it to? // set it to?
if (arguments->value.pair.rest->type != Lisp_Object_Type::Pair) {
if (Memory::get_type(arguments->value.pair.rest) != Lisp_Object_Type::Pair) {
create_generic_error( create_generic_error(
"Attempting to set the keyword argument ':%s', but no value was supplied.", "Attempting to set the keyword argument ':%s', but no value was supplied.",
&(arguments->value.pair.first->value.identifier)); &(arguments->value.pair.first->value.identifier));
@@ -87,7 +87,7 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->
// overstep both for next one // overstep both for next one
arguments = arguments->value.pair.rest->value.pair.rest; arguments = arguments->value.pair.rest->value.pair.rest;


if (arguments->type == Lisp_Object_Type::Nil) {
if (arguments == Memory::nil) {
break; break;
} }
} }
@@ -127,7 +127,7 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->
} }




if (arguments->type == Lisp_Object_Type::Nil) {
if (arguments == Memory::nil) {
if (function->rest_argument) { if (function->rest_argument) {
define_symbol( define_symbol(
Memory::get_or_create_lisp_object_symbol(function->rest_argument), Memory::get_or_create_lisp_object_symbol(function->rest_argument),
@@ -181,8 +181,8 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void {
function->rest_argument = nullptr; function->rest_argument = nullptr;


// okay let's try to read some positional arguments // okay let's try to read some positional arguments
while (arguments->type == Lisp_Object_Type::Pair) {
if (arguments->value.pair.first->type == Lisp_Object_Type::Keyword) {
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) {
if (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Keyword) {
if (string_equal(arguments->value.pair.first->value.identifier, "keys") || if (string_equal(arguments->value.pair.first->value.identifier, "keys") ||
string_equal(arguments->value.pair.first->value.identifier, "rest")) string_equal(arguments->value.pair.first->value.identifier, "rest"))
break; break;
@@ -194,10 +194,10 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void {
} }
} }


if (arguments->value.pair.first->type != Lisp_Object_Type::Symbol) {
if (Memory::get_type(arguments->value.pair.first) != Lisp_Object_Type::Symbol) {
create_parsing_error("Only symbols and keywords can be " create_parsing_error("Only symbols and keywords can be "
"parsed here, but found '%s'", "parsed here, but found '%s'",
Lisp_Object_Type_to_string(arguments->value.pair.first->type));
Lisp_Object_Type_to_string(Memory::get_type(arguments->value.pair.first)));
return; return;
} }


@@ -211,17 +211,17 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void {


// okay we are done with positional arguments, lets check for // okay we are done with positional arguments, lets check for
// keywords, // keywords,
if (arguments->type != Lisp_Object_Type::Pair) {
if (arguments->type != Lisp_Object_Type::Nil)
if (Memory::get_type(arguments) != Lisp_Object_Type::Pair) {
if (arguments != Memory::nil)
create_parsing_error("The lambda list must be nil terminated."); create_parsing_error("The lambda list must be nil terminated.");
return; return;
} }


if (arguments->value.pair.first->type == Lisp_Object_Type::Keyword &&
if (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Keyword &&
string_equal(arguments->value.pair.first->value.identifier, "keys")) string_equal(arguments->value.pair.first->value.identifier, "keys"))
{ {
arguments = arguments->value.pair.rest; arguments = arguments->value.pair.rest;
if (arguments->type != Lisp_Object_Type::Pair) {
if (Memory::get_type(arguments) != Lisp_Object_Type::Pair) {
create_parsing_error("Actual keys have to follow the :keys indicator."); create_parsing_error("Actual keys have to follow the :keys indicator.");
} }
// if (arguments->value.pair.first->type != Lisp_Object_Type::Symbol) { // if (arguments->value.pair.first->type != Lisp_Object_Type::Symbol) {
@@ -231,8 +231,8 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void {
// return; // return;
// } // }


while (arguments->type == Lisp_Object_Type::Pair) {
if (arguments->value.pair.first->type == Lisp_Object_Type::Keyword) {
while (Memory::get_type(arguments) == Lisp_Object_Type::Pair) {
if (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Keyword) {
if (string_equal(arguments->value.pair.first->value.identifier, "rest")) if (string_equal(arguments->value.pair.first->value.identifier, "rest"))
break; break;
else { else {
@@ -243,10 +243,10 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void {
} }
} }


if (arguments->value.pair.first->type != Lisp_Object_Type::Symbol) {
if (Memory::get_type(arguments->value.pair.first) != Lisp_Object_Type::Symbol) {
create_parsing_error( create_parsing_error(
"Only symbols can be parsed here, but found '%s'.", "Only symbols can be parsed here, but found '%s'.",
Lisp_Object_Type_to_string(arguments->value.pair.first->type));
Lisp_Object_Type_to_string(Memory::get_type(arguments->value.pair.first)));
return; return;
} }


@@ -254,15 +254,15 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void {
// the keyword args! Let's check if the next arguement is // the keyword args! Let's check if the next arguement is
// :defaults-to // :defaults-to
Lisp_Object* next = arguments->value.pair.rest; Lisp_Object* next = arguments->value.pair.rest;
if (next->type == Lisp_Object_Type::Pair &&
next->value.pair.first->type == Lisp_Object_Type::Keyword &&
if (Memory::get_type(next) == Lisp_Object_Type::Pair &&
Memory::get_type(next->value.pair.first) == Lisp_Object_Type::Keyword &&
string_equal(next->value.pair.first->value.identifier, string_equal(next->value.pair.first->value.identifier,
"defaults-to")) "defaults-to"))
{ {
// check if there is a next argument too, otherwise it // check if there is a next argument too, otherwise it
// would be an error // would be an error
next = next->value.pair.rest; next = next->value.pair.rest;
if (next->type == Lisp_Object_Type::Pair) {
if (Memory::get_type(next) == Lisp_Object_Type::Pair) {
append_to_keyword_argument_list(function->keyword_arguments, append_to_keyword_argument_list(function->keyword_arguments,
arguments->value.pair.first->value.identifier, arguments->value.pair.first->value.identifier,
next->value.pair.first); next->value.pair.first);
@@ -284,24 +284,24 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void {


// Now we are also done with keyword arguments, lets check for // Now we are also done with keyword arguments, lets check for
// if there is a rest argument // if there is a rest argument
if (arguments->type != Lisp_Object_Type::Pair) {
if (arguments->type != Lisp_Object_Type::Nil)
if (Memory::get_type(arguments) != Lisp_Object_Type::Pair) {
if (arguments != Memory::nil)
create_parsing_error("The lambda list must be nil terminated."); create_parsing_error("The lambda list must be nil terminated.");
return; return;
} }


if (arguments->value.pair.first->type == Lisp_Object_Type::Keyword &&
if (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::Keyword &&
string_equal(arguments->value.pair.first->value.identifier, "rest")) string_equal(arguments->value.pair.first->value.identifier, "rest"))
{ {
arguments = arguments->value.pair.rest; arguments = arguments->value.pair.rest;
if (// arguments->type != Lisp_Object_Type::Pair || if (// arguments->type != Lisp_Object_Type::Pair ||
arguments->value.pair.first->type != Lisp_Object_Type::Symbol)
Memory::get_type(arguments->value.pair.first) != Lisp_Object_Type::Symbol)
{ {
create_parsing_error("After the 'rest' marker there must follow a symbol."); create_parsing_error("After the 'rest' marker there must follow a symbol.");
return; return;
} }
function->rest_argument = arguments->value.pair.first->value.identifier; function->rest_argument = arguments->value.pair.first->value.identifier;
if (arguments->value.pair.rest->type != Lisp_Object_Type::Nil) {
if (arguments->value.pair.rest != Memory::nil) {
create_parsing_error("The lambda list must end after the rest symbol"); create_parsing_error("The lambda list must end after the rest symbol");
} }
} else { } else {
@@ -312,16 +312,16 @@ proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void {




proc list_length(Lisp_Object* node) -> int { proc list_length(Lisp_Object* node) -> int {
if (node->type == Lisp_Object_Type::Nil)
if (node == Memory::nil)
return 0; return 0;


assert_type(node, Lisp_Object_Type::Pair); assert_type(node, Lisp_Object_Type::Pair);


int len = 0; int len = 0;
while (node->type == Lisp_Object_Type::Pair) {
while (Memory::get_type(node) == Lisp_Object_Type::Pair) {
++len; ++len;
node = node->value.pair.rest; node = node->value.pair.rest;
if (node->type == Lisp_Object_Type::Nil)
if (node == Memory::nil)
return len; return len;
} }


@@ -340,7 +340,7 @@ proc extract_keyword_value(char* keyword, Parsed_Arguments* args) -> Lisp_Object


proc eval_arguments(Lisp_Object* arguments, Environment* env, int *out_arguments_length) -> Lisp_Object* { proc eval_arguments(Lisp_Object* arguments, Environment* env, int *out_arguments_length) -> Lisp_Object* {
int my_out_arguments_length = 0; int my_out_arguments_length = 0;
if (arguments->type == Lisp_Object_Type::Nil) {
if (arguments == Memory::nil) {
*(out_arguments_length) = 0; *(out_arguments_length) = 0;
return arguments; return arguments;
} }
@@ -348,7 +348,7 @@ proc eval_arguments(Lisp_Object* arguments, Environment* env, int *out_arguments
Lisp_Object* evaluated_arguments = Memory::create_lisp_object_pair(nullptr, nullptr); Lisp_Object* evaluated_arguments = Memory::create_lisp_object_pair(nullptr, nullptr);
Lisp_Object* evaluated_arguments_head = evaluated_arguments; Lisp_Object* evaluated_arguments_head = evaluated_arguments;
Lisp_Object* current_head = arguments; Lisp_Object* current_head = arguments;
while (current_head->type == Lisp_Object_Type::Pair) {
while (Memory::get_type(current_head) == Lisp_Object_Type::Pair) {
try { try {
evaluated_arguments_head->value.pair.first = evaluated_arguments_head->value.pair.first =
eval_expr(current_head->value.pair.first, env); eval_expr(current_head->value.pair.first, env);
@@ -356,10 +356,10 @@ proc eval_arguments(Lisp_Object* arguments, Environment* env, int *out_arguments
evaluated_arguments_head->value.pair.first->sourceCodeLocation = current_head->value.pair.first->sourceCodeLocation; evaluated_arguments_head->value.pair.first->sourceCodeLocation = current_head->value.pair.first->sourceCodeLocation;
current_head = current_head->value.pair.rest; current_head = current_head->value.pair.rest;


if (current_head->type == Lisp_Object_Type::Pair) {
if (Memory::get_type(current_head) == Lisp_Object_Type::Pair) {
evaluated_arguments_head->value.pair.rest = Memory::create_lisp_object_pair(nullptr, nullptr); evaluated_arguments_head->value.pair.rest = Memory::create_lisp_object_pair(nullptr, nullptr);
evaluated_arguments_head = evaluated_arguments_head->value.pair.rest; evaluated_arguments_head = evaluated_arguments_head->value.pair.rest;
} else if (current_head->type == Lisp_Object_Type::Nil) {
} else if (current_head == Memory::nil) {
evaluated_arguments_head->value.pair.rest = current_head; evaluated_arguments_head->value.pair.rest = current_head;
} else { } else {
create_parsing_error("Attempting to evaluate ill formed argument list."); create_parsing_error("Attempting to evaluate ill formed argument list.");
@@ -372,7 +372,9 @@ proc eval_arguments(Lisp_Object* arguments, Environment* env, int *out_arguments
} }


proc eval_expr(Lisp_Object* node, Environment* env) -> Lisp_Object* { proc eval_expr(Lisp_Object* node, Environment* env) -> Lisp_Object* {
switch (node->type) {
Globals::current_source_code = node;

switch (Memory::get_type(node)) {
case Lisp_Object_Type::T: case Lisp_Object_Type::T:
case Lisp_Object_Type::Nil: case Lisp_Object_Type::Nil:
case Lisp_Object_Type::Number: case Lisp_Object_Type::Number:
@@ -387,11 +389,10 @@ proc eval_expr(Lisp_Object* node, Environment* env) -> Lisp_Object* {
return symbol; return symbol;
} }
case Lisp_Object_Type::Pair: { case Lisp_Object_Type::Pair: {
Globals::current_source_code = node;


Lisp_Object* lispOperator; Lisp_Object* lispOperator;
if (node->value.pair.first->type != Lisp_Object_Type::CFunction &&
node->value.pair.first->type != Lisp_Object_Type::Function)
if (Memory::get_type(node->value.pair.first) != Lisp_Object_Type::CFunction &&
Memory::get_type(node->value.pair.first) != Lisp_Object_Type::Function)
{ {
try { try {
lispOperator = eval_expr(node->value.pair.first, env); lispOperator = eval_expr(node->value.pair.first, env);
@@ -404,13 +405,13 @@ proc eval_expr(Lisp_Object* node, Environment* env) -> Lisp_Object* {
int arguments_length; int arguments_length;


// check for c function // check for c function
if (lispOperator->type == Lisp_Object_Type::CFunction) {
if (Memory::get_type(lispOperator) == Lisp_Object_Type::CFunction) {
Lisp_Object* result = lispOperator->value.cFunction->function(arguments, env); Lisp_Object* result = lispOperator->value.cFunction->function(arguments, env);
return result; return result;
} }


// check for lisp function // check for lisp function
if (lispOperator->type == Lisp_Object_Type::Function) {
if (Memory::get_type(lispOperator) == Lisp_Object_Type::Function) {
// only for lambdas we evaluate the arguments before // only for lambdas we evaluate the arguments before
// apllying // apllying
if (lispOperator->value.function.type == Function_Type::Lambda) { if (lispOperator->value.function.type == Function_Type::Lambda) {
@@ -427,7 +428,7 @@ proc eval_expr(Lisp_Object* node, Environment* env) -> Lisp_Object* {
} }
} }
default: { default: {
create_generic_error("%s is not a function.", Lisp_Object_Type_to_string(node->type));
create_generic_error("%s is not a function.", Lisp_Object_Type_to_string(Memory::get_type(node)));
return nullptr; return nullptr;
} }
} }
@@ -438,7 +439,7 @@ proc is_truthy (Lisp_Object* expression, Environment* env) -> bool {
try { try {
result = eval_expr(expression, env); result = eval_expr(expression, env);
} }
if (result->type == Lisp_Object_Type::Nil)
if (result == Memory::nil)
return false; return false;
return true; return true;
} }


+ 1
- 0
src/forward_decls.cpp Просмотреть файл

@@ -15,6 +15,7 @@ proc Lisp_Object_Type_to_string(Lisp_Object_Type type) -> const char*;


namespace Memory { namespace Memory {
proc get_or_create_lisp_object_keyword(const char* identifier) -> Lisp_Object*; proc get_or_create_lisp_object_keyword(const char* identifier) -> Lisp_Object*;
inline proc get_type(Lisp_Object* node) -> Lisp_Object_Type;
} }


namespace Globals { namespace Globals {


+ 4
- 4
src/io.cpp Просмотреть файл

@@ -230,12 +230,12 @@ proc panic(char* message) -> void {


proc print(Lisp_Object* node, bool print_quotes = false, FILE* file = stdout) -> void { proc print(Lisp_Object* node, bool print_quotes = false, FILE* file = stdout) -> void {


switch (node->type) {
switch (Memory::get_type(node)) {
case (Lisp_Object_Type::Nil): fputs("()", file); break; case (Lisp_Object_Type::Nil): fputs("()", file); break;
case (Lisp_Object_Type::T): fputs("t", file); break; case (Lisp_Object_Type::T): fputs("t", file); break;
case (Lisp_Object_Type::Number): fprintf(file, "%f", node->value.number); break; case (Lisp_Object_Type::Number): fprintf(file, "%f", node->value.number); break;
case (Lisp_Object_Type::Keyword): fputs(":", file); // NOTE(Felix): intentionall fallthough case (Lisp_Object_Type::Keyword): fputs(":", file); // NOTE(Felix): intentionall fallthough
case (Lisp_Object_Type::Symbol): fprintf(file, Memory::get_c_str(node->value.identifier)); break;
case (Lisp_Object_Type::Symbol): fprintf(file, "%s", Memory::get_c_str(node->value.identifier)); break;
case (Lisp_Object_Type::CFunction): fputs("[C-function]", file); break; case (Lisp_Object_Type::CFunction): fputs("[C-function]", file); break;
case (Lisp_Object_Type::String): { case (Lisp_Object_Type::String): {
if (print_quotes) { if (print_quotes) {
@@ -268,12 +268,12 @@ proc print(Lisp_Object* node, bool print_quotes = false, FILE* file = stdout) ->
head = head->value.pair.rest; head = head->value.pair.rest;
if (!head) if (!head)
return; return;
if (head->type != Lisp_Object_Type::Pair)
if (Memory::get_type(head) != Lisp_Object_Type::Pair)
break; break;
putc(' ', file); putc(' ', file);
} }


if (head->type != Lisp_Object_Type::Nil) {
if (Memory::get_type(head) != Lisp_Object_Type::Nil) {
fputs(" . ", file); fputs(" . ", file);
print(head); print(head);
} }


+ 24
- 9
src/memory.cpp Просмотреть файл

@@ -51,6 +51,21 @@ namespace Memory {
return get_c_str(str->value.string); return get_c_str(str->value.string);
} }


inline proc get_type(Lisp_Object* node) -> Lisp_Object_Type {
// the type is in the bits 0 to 5 (including)
return (Lisp_Object_Type) ((u64)node->flags & (u64)0xffffff);
}


inline proc set_type(Lisp_Object* node, Lisp_Object_Type type) {
// the type is in the bits 0 to 5 (including)
u64 bitmask = (u64)-1;
bitmask -= 0xffffff;
bitmask += (u64) type;
node->flags = (u64)(node->flags) | bitmask;
}


proc create_string(const char* str, int len) -> String* { proc create_string(const char* str, int len) -> String* {
// TODO(Felix): check the holes first, not just always append // TODO(Felix): check the holes first, not just always append
// at the end // at the end
@@ -136,11 +151,11 @@ namespace Memory {


// init nil // init nil
nil = create_lisp_object(); nil = create_lisp_object();
nil->type = Lisp_Object_Type::Nil;
set_type(nil, Lisp_Object_Type::Nil);


// init t // init t
t = create_lisp_object(); t = create_lisp_object();
t->type = Lisp_Object_Type::T;
set_type(t, Lisp_Object_Type::T);
} }


proc reset() -> void { proc reset() -> void {
@@ -152,21 +167,21 @@ namespace Memory {


proc create_lisp_object_number(double number) -> Lisp_Object* { proc create_lisp_object_number(double number) -> Lisp_Object* {
Lisp_Object* node = create_lisp_object(); Lisp_Object* node = create_lisp_object();
node->type = Lisp_Object_Type::Number;
set_type(node, Lisp_Object_Type::Number);
node->value.number = number; node->value.number = number;
return node; return node;
} }


proc create_lisp_object_string(String* str) -> Lisp_Object* { proc create_lisp_object_string(String* str) -> Lisp_Object* {
Lisp_Object* node = create_lisp_object(); Lisp_Object* node = create_lisp_object();
node->type = Lisp_Object_Type::String;
set_type(node, Lisp_Object_Type::String);
node->value.string = str; node->value.string = str;
return node; return node;
} }


proc create_lisp_object_string(char* str) -> Lisp_Object* { proc create_lisp_object_string(char* str) -> Lisp_Object* {
Lisp_Object* node = create_lisp_object(); Lisp_Object* node = create_lisp_object();
node->type = Lisp_Object_Type::String;
set_type(node, Lisp_Object_Type::String);
node->value.string = create_string(str); node->value.string = create_string(str);
return node; return node;
} }
@@ -175,7 +190,7 @@ namespace Memory {
// TODO(Felix): if we already have it stored somewhere then // TODO(Felix): if we already have it stored somewhere then
// reuse it and dont create new one // reuse it and dont create new one
Lisp_Object* node = create_lisp_object(); Lisp_Object* node = create_lisp_object();
node->type = Lisp_Object_Type::Symbol;
set_type(node, Lisp_Object_Type::Symbol);
// node->value.symbol = new(Symbol); // node->value.symbol = new(Symbol);
node->value.identifier = identifier; node->value.identifier = identifier;
return node; return node;
@@ -193,7 +208,7 @@ namespace Memory {
// TODO(Felix): if we already have it stored somewhere then // TODO(Felix): if we already have it stored somewhere then
// reuse it and dont create new one // reuse it and dont create new one
Lisp_Object* node = create_lisp_object(); Lisp_Object* node = create_lisp_object();
node->type = Lisp_Object_Type::Keyword;
set_type(node, Lisp_Object_Type::Keyword);
// node->value.keyword = new(Keyword); // node->value.keyword = new(Keyword);
node->value.identifier = keyword; node->value.identifier = keyword;
return node; return node;
@@ -209,7 +224,7 @@ namespace Memory {


proc create_lisp_object_cfunction(std::function<Lisp_Object* (Lisp_Object*, Environment*)> function) -> Lisp_Object* { proc create_lisp_object_cfunction(std::function<Lisp_Object* (Lisp_Object*, Environment*)> function) -> Lisp_Object* {
Lisp_Object* node = create_lisp_object(); Lisp_Object* node = create_lisp_object();
node->type = Lisp_Object_Type::CFunction;
set_type(node, Lisp_Object_Type::CFunction);
// node->value.lambdaWrapper = new Lambda_Wrapper(function); // node->value.lambdaWrapper = new Lambda_Wrapper(function);
node->value.cFunction = new(cFunction); node->value.cFunction = new(cFunction);
node->value.cFunction->function = function; node->value.cFunction->function = function;
@@ -218,7 +233,7 @@ namespace Memory {


proc create_lisp_object_pair(Lisp_Object* first, Lisp_Object* rest) -> Lisp_Object* { proc create_lisp_object_pair(Lisp_Object* first, Lisp_Object* rest) -> Lisp_Object* {
Lisp_Object* node = create_lisp_object(); Lisp_Object* node = create_lisp_object();
node->type = Lisp_Object_Type::Pair;
set_type(node, Lisp_Object_Type::Pair);
// node->value.pair = new(Pair); // node->value.pair = new(Pair);
node->value.pair.first = first; node->value.pair.first = first;
node->value.pair.rest = rest; node->value.pair.rest = rest;


+ 7
- 7
src/parse.cpp Просмотреть файл

@@ -292,7 +292,7 @@ namespace Parser {


// okay there is something // okay there is something
Lisp_Object* head = Memory::create_lisp_object(); Lisp_Object* head = Memory::create_lisp_object();
head->type = Lisp_Object_Type::Pair;
Memory::set_type(head, Lisp_Object_Type::Pair);
// head->value.pair = new(Pair); // head->value.pair = new(Pair);
Lisp_Object* expression = head; Lisp_Object* expression = head;


@@ -352,7 +352,7 @@ namespace Parser {
} }


// check if we have to create or delete or run macros // check if we have to create or delete or run macros
if (expression->value.pair.first->type == Lisp_Object_Type::Symbol) {
if (Memory::get_type(expression->value.pair.first) == Lisp_Object_Type::Symbol) {
if (string_equal("define-syntax", expression->value.pair.first->value.identifier)) { if (string_equal("define-syntax", expression->value.pair.first->value.identifier)) {
// create a new macro // create a new macro
Lisp_Object* arguments = expression->value.pair.rest; Lisp_Object* arguments = expression->value.pair.rest;
@@ -378,12 +378,12 @@ namespace Parser {


// Function* function = new(Function); // Function* function = new(Function);
Lisp_Object* macro = Memory::create_lisp_object(); Lisp_Object* macro = Memory::create_lisp_object();
macro->type = Lisp_Object_Type::Function;
Memory::set_type(macro, Lisp_Object_Type::Function);
macro->value.function.parent_environment = environment_for_macros; macro->value.function.parent_environment = environment_for_macros;
macro->value.function.type = Function_Type::Macro; macro->value.function.type = Function_Type::Macro;


// if parameters were specified // if parameters were specified
if (arguments->value.pair.first->type != Lisp_Object_Type::Nil) {
if (Memory::get_type(arguments->value.pair.first) != Lisp_Object_Type::Nil) {
try { try {
assert_type(arguments->value.pair.first, Lisp_Object_Type::Pair); assert_type(arguments->value.pair.first, Lisp_Object_Type::Pair);
} }
@@ -398,7 +398,7 @@ namespace Parser {


arguments = arguments->value.pair.rest; arguments = arguments->value.pair.rest;
// if there is a docstring, use it // if there is a docstring, use it
if (arguments->value.pair.first->type == Lisp_Object_Type::String) {
if (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::String) {
macro->value.function.docstring = arguments->value.pair.first->value.string; macro->value.function.docstring = arguments->value.pair.first->value.string;
arguments = arguments->value.pair.rest; arguments = arguments->value.pair.rest;
} else { } else {
@@ -439,7 +439,7 @@ namespace Parser {


for (int i = 0; i < environment_for_macros->next_index; ++i) { for (int i = 0; i < environment_for_macros->next_index; ++i) {
if (string_equal(expression->value.pair.first->value.identifier, environment_for_macros->keys[i]) && if (string_equal(expression->value.pair.first->value.identifier, environment_for_macros->keys[i]) &&
environment_for_macros->values[i]->type == Lisp_Object_Type::Function &&
Memory::get_type(environment_for_macros->values[i]) == Lisp_Object_Type::Function &&
environment_for_macros->values[i]->value.function.type == Function_Type::Macro) environment_for_macros->values[i]->value.function.type == Function_Type::Macro)
{ {
try { try {
@@ -543,7 +543,7 @@ namespace Parser {


for (int i = 0; i < program->next_index; ++i) { for (int i = 0; i < program->next_index; ++i) {
// a macro will parse as nil for now, so we skip those // a macro will parse as nil for now, so we skip those
if (program->data[i]->type == Lisp_Object_Type::Nil)
if (program->data[i] == Memory::nil)
continue; continue;
print(program->data[i], true, f); print(program->data[i], true, f);
fprintf(f, "\n\n"); fprintf(f, "\n\n");


+ 10
- 21
src/structs.cpp Просмотреть файл

@@ -16,36 +16,25 @@ enum struct Lisp_Object_Type {
String, String,
Pair, Pair,
// Pointer, // Pointer,
// OwningPointer,
Function, Function,
CFunction, CFunction,
}; };


typedef uint64_t u64;

enum class Lisp_Object_Flags : u64
{
// bits 0 to 5 will be reserved for the type
aliveness = 1 << 6,
};

enum struct Function_Type { enum struct Function_Type {
Lambda, Lambda,
Special_Lambda, Special_Lambda,
Macro Macro
}; };


// enum struct Error_Type {
// Assertion_Error,
// File_Not_Found,
// Ill_Formed_Arguments,
// Ill_Formed_Lambda_List,
// Ill_Formed_List,
// Not_A_Function,
// Not_Yet_Implemented,
// Out_Of_Memory,
// Symbol_Not_Defined,
// Syntax_Error,
// Trailing_Garbage,
// Type_Missmatch,
// Unbalanced_Parenthesis,
// Unexpected_Eof,
// Unknown_Error,
// Unknown_Keyword_Argument,
// Wrong_Number_Of_Arguments,
// };

enum struct Log_Level { enum struct Log_Level {
None, None,
Critical, Critical,
@@ -116,7 +105,7 @@ struct cFunction {


struct Lisp_Object { struct Lisp_Object {
Source_Code_Location* sourceCodeLocation; Source_Code_Location* sourceCodeLocation;
Lisp_Object_Type type;
u64 flags;
Lisp_Object* userType; Lisp_Object* userType;
union { union {
String* identifier; // used for symbols and keywords String* identifier; // used for symbols and keywords


+ 6
- 6
src/testing.cpp Просмотреть файл

@@ -63,13 +63,13 @@
return fail; \ return fail; \
} }


#define assert_equal_type(node, _type) \
if (node->type != _type) { \
print_assert_equal_fail( \
Lisp_Object_Type_to_string(node->type), \
#define assert_equal_type(node, _type) \
if (Memory::get_type(node) != _type) { \
print_assert_equal_fail( \
Lisp_Object_Type_to_string(Memory::get_type(node)), \
Lisp_Object_Type_to_string(_type), char*, "%s"); \ Lisp_Object_Type_to_string(_type), char*, "%s"); \
return fail; \
} \
return fail; \
} \


#define assert_null(variable) \ #define assert_null(variable) \
assert_equal_int(variable, nullptr) assert_equal_int(variable, nullptr)


Загрузка…
Отмена
Сохранить