Преглед изворни кода

renaming "ast_node" -> "lisp_object"

master
FelixBrendel пре 7 година
родитељ
комит
a297f59946
9 измењених фајлова са 495 додато и 495 уклоњено
  1. +1
    -1
      src/assert.cpp
  2. +208
    -208
      src/built_ins.cpp
  3. +9
    -9
      src/env.cpp
  4. +76
    -76
      src/eval.cpp
  5. +26
    -26
      src/io.cpp
  6. +56
    -56
      src/lisp_object.cpp
  7. +5
    -5
      src/main.cpp
  8. +52
    -52
      src/parse.cpp
  9. +62
    -62
      src/testing.cpp

+ 1
- 1
src/assert.cpp Прегледај датотеку

@@ -1,4 +1,4 @@
void assert_type (Ast_Node* node, Ast_Node_Type type) {
void assert_type (Lisp_Object* node, Lisp_Object_Type type) {
if (!node) if (!node)
create_error(Error_Type::Unknown_Error, nullptr); create_error(Error_Type::Unknown_Error, nullptr);
if (node->type == type) return; if (node->type == type) return;


+ 208
- 208
src/built_ins.cpp
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


+ 9
- 9
src/env.cpp Прегледај датотеку

@@ -5,7 +5,7 @@ struct Environment {
int next_index; int next_index;
// TODO(Felix): Use a hashmap here. // TODO(Felix): Use a hashmap here.
char** keys; char** keys;
Ast_Node** values;
Lisp_Object** values;
}; };


Environment* create_child_environment(Environment* parent) { Environment* create_child_environment(Environment* parent) {
@@ -17,7 +17,7 @@ Environment* create_child_environment(Environment* parent) {
env->capacity = start_capacity; env->capacity = start_capacity;
env->next_index = 0; env->next_index = 0;
env->keys = (char**)malloc(start_capacity * sizeof(char*)); env->keys = (char**)malloc(start_capacity * sizeof(char*));
env->values = (Ast_Node**)malloc(start_capacity * sizeof(Ast_Node*));
env->values = (Lisp_Object**)malloc(start_capacity * sizeof(Lisp_Object*));


return env; return env;
} }
@@ -26,7 +26,7 @@ Environment* create_empty_environment() {
return create_child_environment(nullptr); return create_child_environment(nullptr);
} }


void define_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) {
void define_symbol(Lisp_Object* symbol, Lisp_Object* value, Environment* env) {
// NOTE(Felix): right now we are simply adding the symol at the // NOTE(Felix): right now we are simply adding the symol at the
// back of the list without checking if it already exists but are // back of the list without checking if it already exists but are
// also searching for thesymbol from the back, so we will find the // also searching for thesymbol from the back, so we will find the
@@ -35,7 +35,7 @@ void define_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) {
if (env->next_index == env->capacity) { if (env->next_index == env->capacity) {
env->capacity *= 2; env->capacity *= 2;
env->keys = (char**)realloc(env->keys, env->capacity * sizeof(char*)); env->keys = (char**)realloc(env->keys, env->capacity * sizeof(char*));
env->values = (Ast_Node**)realloc(env->values, env->capacity * sizeof(Ast_Node*));
env->values = (Lisp_Object**)realloc(env->values, env->capacity * sizeof(Lisp_Object*));
} }


env->keys [env->next_index] = symbol->value.symbol->identifier; env->keys [env->next_index] = symbol->value.symbol->identifier;
@@ -45,17 +45,17 @@ void define_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) {


void print_environment(Environment* env); void print_environment(Environment* env);


Ast_Node* lookup_symbol_in_this_envt(Symbol* sym, Environment* env) {
Lisp_Object* lookup_symbol_in_this_envt(Symbol* sym, Environment* env) {
for (int i = env->next_index - 1; i >= 0; --i) for (int i = env->next_index - 1; i >= 0; --i)
if (string_equal(env->keys[i], sym->identifier)) if (string_equal(env->keys[i], sym->identifier))
return env->values[i]; return env->values[i];
return nullptr; return nullptr;
} }


Ast_Node* lookup_symbol(Ast_Node* node, Environment* env) {
Lisp_Object* lookup_symbol(Lisp_Object* node, Environment* env) {
// first check current environment // first check current environment
Symbol* sym = node->value.symbol; Symbol* sym = node->value.symbol;
Ast_Node* result;
Lisp_Object* result;
result = lookup_symbol_in_this_envt(sym, env); result = lookup_symbol_in_this_envt(sym, env);
if (result) if (result)
return result; return result;
@@ -68,10 +68,10 @@ Ast_Node* lookup_symbol(Ast_Node* node, Environment* env) {
} }


if (string_equal(sym->identifier, "nil")) { if (string_equal(sym->identifier, "nil")) {
return create_ast_node_nil();
return create_lisp_object_nil();
} }
if (string_equal(sym->identifier, "t")) { if (string_equal(sym->identifier, "t")) {
return create_ast_node_t();
return create_lisp_object_t();
} }


create_error(Error_Type::Symbol_Not_Defined, node->sourceCodeLocation); create_error(Error_Type::Symbol_Not_Defined, node->sourceCodeLocation);


+ 76
- 76
src/eval.cpp Прегледај датотеку

@@ -1,16 +1,16 @@
Ast_Node* eval_expr(Ast_Node*, Environment*);
Lisp_Object* eval_expr(Lisp_Object*, Environment*);


Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function) {
Lisp_Object* apply_arguments_to_function(Lisp_Object* arguments, Function* function) {
Environment* new_env = create_child_environment(function->parent_environment); Environment* new_env = create_child_environment(function->parent_environment);


// 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 == Ast_Node_Type::Pair) {
// TODO(Felix): here we create new ast_node_symbols from
if (arguments->type == Lisp_Object_Type::Pair) {
// TODO(Felix): here we create new lisp_object_symbols from
// their identifiers but before we converted them to // their identifiers but before we converted them to
// strings from symbols... Wo maybe just use the symbols? // strings from symbols... Wo maybe just use the symbols?
define_symbol( define_symbol(
create_ast_node_symbol(function->positional_arguments->identifiers[i]),
create_lisp_object_symbol(function->positional_arguments->identifiers[i]),
arguments->value.pair->first, new_env); arguments->value.pair->first, new_env);
} else { } else {


@@ -22,14 +22,14 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function) {


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


if (arguments->type == Ast_Node_Type::Nil)
if (arguments->type == 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 == Ast_Node_Type::Keyword) {
while (arguments->value.pair->first->type == 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) {
@@ -64,14 +64,14 @@ Ast_Node* apply_arguments_to_function(Ast_Node* 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 != Ast_Node_Type::Pair) {
if (arguments->value.pair->rest->type != Lisp_Object_Type::Pair) {
create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation); create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation);
return nullptr; return nullptr;
} }


// if not set it and then add it to the array list // if not set it and then add it to the array list
define_symbol( define_symbol(
create_ast_node_symbol(arguments->value.pair->first->value.keyword->identifier),
create_lisp_object_symbol(arguments->value.pair->first->value.keyword->identifier),
arguments->value.pair->rest->value.pair->first, arguments->value.pair->rest->value.pair->first,
new_env); new_env);


@@ -80,7 +80,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* 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 == Ast_Node_Type::Nil) {
if (arguments->type == Lisp_Object_Type::Nil) {
break; break;
} }
} }
@@ -110,23 +110,23 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function) {
// to use it or if the user supplied his own // to use it or if the user supplied his own
if (!was_set) { if (!was_set) {
define_symbol( define_symbol(
create_ast_node_symbol(defined_keyword),
copy_ast_node(function->keyword_arguments->values->data[i]), new_env);
create_lisp_object_symbol(defined_keyword),
copy_lisp_object(function->keyword_arguments->values->data[i]), new_env);
} }
} }
} }




if (arguments->type == Ast_Node_Type::Nil) {
if (arguments->type == Lisp_Object_Type::Nil) {
if (function->rest_argument) { if (function->rest_argument) {
define_symbol( define_symbol(
create_ast_node_symbol(function->rest_argument),
create_ast_node_nil(), new_env);
create_lisp_object_symbol(function->rest_argument),
create_lisp_object_nil(), new_env);
} }
} else { } else {
if (function->rest_argument) { if (function->rest_argument) {
define_symbol( define_symbol(
create_ast_node_symbol(function->rest_argument),
create_lisp_object_symbol(function->rest_argument),
arguments, new_env); arguments, new_env);
} else { } else {
// rest was not declared but additional arguments were found // rest was not declared but additional arguments were found
@@ -136,7 +136,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function) {
} }




Ast_Node* result;
Lisp_Object* result;
try { try {
result = eval_expr(function->body, new_env); result = eval_expr(function->body, new_env);
} }
@@ -162,15 +162,15 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function) {
positional_arguments, keyword_arguments and rest_argument and positional_arguments, keyword_arguments and rest_argument and
filling it in filling it in
*/ */
void parse_argument_list(Ast_Node* arguments, Function* function) {
void parse_argument_list(Lisp_Object* arguments, Function* function) {
// first init the fields // first init the fields
function->positional_arguments = create_positional_argument_list(16); function->positional_arguments = create_positional_argument_list(16);
function->keyword_arguments = create_keyword_argument_list(16); function->keyword_arguments = create_keyword_argument_list(16);
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 == Ast_Node_Type::Pair) {
if (arguments->value.pair->first->type == Ast_Node_Type::Keyword) {
while (arguments->type == Lisp_Object_Type::Pair) {
if (arguments->value.pair->first->type == Lisp_Object_Type::Keyword) {
if (string_equal(arguments->value.pair->first->value.keyword->identifier, "keys") || if (string_equal(arguments->value.pair->first->value.keyword->identifier, "keys") ||
string_equal(arguments->value.pair->first->value.keyword->identifier, "rest")) string_equal(arguments->value.pair->first->value.keyword->identifier, "rest"))
break; break;
@@ -180,7 +180,7 @@ void parse_argument_list(Ast_Node* arguments, Function* function) {
} }
} }


if (arguments->value.pair->first->type != Ast_Node_Type::Symbol) {
if (arguments->value.pair->first->type != Lisp_Object_Type::Symbol) {
create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
return; return;
} }
@@ -195,25 +195,25 @@ void parse_argument_list(Ast_Node* arguments, Function* function) {


// 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 != Ast_Node_Type::Pair) {
if (arguments->type != Ast_Node_Type::Nil)
if (arguments->type != Lisp_Object_Type::Pair) {
if (arguments->type != Lisp_Object_Type::Nil)
create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
return; return;
} }


if (arguments->value.pair->first->type == Ast_Node_Type::Keyword &&
if (arguments->value.pair->first->type == Lisp_Object_Type::Keyword &&
string_equal(arguments->value.pair->first->value.keyword->identifier, "keys")) string_equal(arguments->value.pair->first->value.keyword->identifier, "keys"))
{ {
arguments = arguments->value.pair->rest; arguments = arguments->value.pair->rest;
if (arguments->type != Ast_Node_Type::Pair ||
arguments->value.pair->first->type != Ast_Node_Type::Symbol)
if (arguments->type != Lisp_Object_Type::Pair ||
arguments->value.pair->first->type != Lisp_Object_Type::Symbol)
{ {
create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
return; return;
} }


while (arguments->type == Ast_Node_Type::Pair) {
if (arguments->value.pair->first->type == Ast_Node_Type::Keyword) {
while (arguments->type == Lisp_Object_Type::Pair) {
if (arguments->value.pair->first->type == Lisp_Object_Type::Keyword) {
if (string_equal(arguments->value.pair->first->value.keyword->identifier, "rest")) if (string_equal(arguments->value.pair->first->value.keyword->identifier, "rest"))
break; break;
else { else {
@@ -222,7 +222,7 @@ void parse_argument_list(Ast_Node* arguments, Function* function) {
} }
} }


if (arguments->value.pair->first->type != Ast_Node_Type::Symbol) {
if (arguments->value.pair->first->type != Lisp_Object_Type::Symbol) {
create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
return; return;
} }
@@ -230,16 +230,16 @@ void parse_argument_list(Ast_Node* arguments, Function* function) {
// we found a symbol (arguments->value.pair->first) for // we found a symbol (arguments->value.pair->first) for
// 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
Ast_Node* next = arguments->value.pair->rest;
if (next->type == Ast_Node_Type::Pair &&
next->value.pair->first->type == Ast_Node_Type::Keyword &&
Lisp_Object* next = arguments->value.pair->rest;
if (next->type == Lisp_Object_Type::Pair &&
next->value.pair->first->type == Lisp_Object_Type::Keyword &&
string_equal(next->value.pair->first->value.keyword->identifier, string_equal(next->value.pair->first->value.keyword->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 == Ast_Node_Type::Pair) {
if (next->type == 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.symbol->identifier, arguments->value.pair->first->value.symbol->identifier,
next->value.pair->first); next->value.pair->first);
@@ -261,24 +261,24 @@ void parse_argument_list(Ast_Node* arguments, Function* function) {


// 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 != Ast_Node_Type::Pair) {
if (arguments->type != Ast_Node_Type::Nil)
if (arguments->type != Lisp_Object_Type::Pair) {
if (arguments->type != Lisp_Object_Type::Nil)
create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
return; return;
} }


if (arguments->value.pair->first->type == Ast_Node_Type::Keyword &&
if (arguments->value.pair->first->type == Lisp_Object_Type::Keyword &&
string_equal(arguments->value.pair->first->value.keyword->identifier, "rest")) string_equal(arguments->value.pair->first->value.keyword->identifier, "rest"))
{ {
arguments = arguments->value.pair->rest; arguments = arguments->value.pair->rest;
if (arguments->type != Ast_Node_Type::Pair ||
arguments->value.pair->first->type != Ast_Node_Type::Symbol)
if (arguments->type != Lisp_Object_Type::Pair ||
arguments->value.pair->first->type != Lisp_Object_Type::Symbol)
{ {
create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
return; return;
} }
function->rest_argument = arguments->value.pair->first->value.symbol->identifier; function->rest_argument = arguments->value.pair->first->value.symbol->identifier;
if (arguments->value.pair->rest->type != Ast_Node_Type::Nil) {
if (arguments->value.pair->rest->type != Lisp_Object_Type::Nil) {
create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation); create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
} }
} else { } else {
@@ -288,20 +288,20 @@ void parse_argument_list(Ast_Node* arguments, Function* function) {
} }




int list_length(Ast_Node* node) {
if (node->type == Ast_Node_Type::Nil)
int list_length(Lisp_Object* node) {
if (node->type == Lisp_Object_Type::Nil)
return 0; return 0;


if (node->type != Ast_Node_Type::Pair) {
if (node->type != Lisp_Object_Type::Pair) {
create_error(Error_Type::Type_Missmatch, node->sourceCodeLocation); create_error(Error_Type::Type_Missmatch, node->sourceCodeLocation);
return 0; return 0;
} }


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


@@ -309,9 +309,9 @@ int list_length(Ast_Node* node) {
return 0; return 0;
} }


bool is_truthy (Ast_Node* expression, Environment* env);
bool is_truthy (Lisp_Object* expression, Environment* env);


Ast_Node* extract_keyword_value(char* keyword, Parsed_Arguments* args) {
Lisp_Object* extract_keyword_value(char* keyword, Parsed_Arguments* args) {
// NOTE(Felix): This will be a hashmap lookup later // NOTE(Felix): This will be a hashmap lookup later
for (int i = 0; i < args->keyword_keys->next_index; ++i) { for (int i = 0; i < args->keyword_keys->next_index; ++i) {
if (string_equal(args->keyword_keys->data[i]->value.keyword->identifier, keyword)) if (string_equal(args->keyword_keys->data[i]->value.keyword->identifier, keyword))
@@ -320,26 +320,26 @@ Ast_Node* extract_keyword_value(char* keyword, Parsed_Arguments* args) {
return nullptr; return nullptr;
} }


Ast_Node* eval_arguments(Ast_Node* arguments, Environment* env, int *out_arguments_length) {
Lisp_Object* eval_arguments(Lisp_Object* arguments, Environment* env, int *out_arguments_length) {
int my_out_arguments_length = 0; int my_out_arguments_length = 0;
if (arguments->type == Ast_Node_Type::Nil) {
if (arguments->type == Lisp_Object_Type::Nil) {
return arguments; return arguments;
} }


Ast_Node* evaluated_arguments = create_ast_node_pair(nullptr, nullptr);
Ast_Node* evaluated_arguments_head = evaluated_arguments;
Ast_Node* current_head = arguments;
while (current_head->type == Ast_Node_Type::Pair) {
Lisp_Object* evaluated_arguments = create_lisp_object_pair(nullptr, nullptr);
Lisp_Object* evaluated_arguments_head = evaluated_arguments;
Lisp_Object* current_head = arguments;
while (current_head->type == 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);
} }
current_head = current_head->value.pair->rest; current_head = current_head->value.pair->rest;


if (current_head->type == Ast_Node_Type::Pair) {
evaluated_arguments_head->value.pair->rest = create_ast_node_pair(nullptr, nullptr);
if (current_head->type == Lisp_Object_Type::Pair) {
evaluated_arguments_head->value.pair->rest = 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 == Ast_Node_Type::Nil) {
} else if (current_head->type == Lisp_Object_Type::Nil) {
evaluated_arguments_head->value.pair->rest = current_head; evaluated_arguments_head->value.pair->rest = current_head;
} else { } else {
create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation); create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation);
@@ -351,7 +351,7 @@ Ast_Node* eval_arguments(Ast_Node* arguments, Environment* env, int *out_argumen
return evaluated_arguments; return evaluated_arguments;
} }


Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
Lisp_Object* eval_expr(Lisp_Object* node, Environment* env) {
#define report_error(_type) { \ #define report_error(_type) { \
create_error(_type, node->sourceCodeLocation); \ create_error(_type, node->sourceCodeLocation); \
return nullptr; \ return nullptr; \
@@ -360,26 +360,26 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
if (error) if (error)
return nullptr; return nullptr;


Ast_Node* ret = new(Ast_Node);
Lisp_Object* ret = new(Lisp_Object);
switch (node->type) { switch (node->type) {
case Ast_Node_Type::T:
case Ast_Node_Type::Nil:
case Lisp_Object_Type::T:
case Lisp_Object_Type::Nil:
return node; return node;
case Ast_Node_Type::Symbol: {
Ast_Node* symbol;
case Lisp_Object_Type::Symbol: {
Lisp_Object* symbol;
try { try {
symbol = lookup_symbol(node, env); symbol = lookup_symbol(node, env);
} }
return symbol; return symbol;
} }
case Ast_Node_Type::Number:
case Ast_Node_Type::Keyword:
case Ast_Node_Type::String:
case Lisp_Object_Type::Number:
case Lisp_Object_Type::Keyword:
case Lisp_Object_Type::String:
return node; return node;
case Ast_Node_Type::Pair: {
Ast_Node* lispOperator;
if (node->value.pair->first->type != Ast_Node_Type::CFunction &&
node->value.pair->first->type != Ast_Node_Type::Function)
case Lisp_Object_Type::Pair: {
Lisp_Object* lispOperator;
if (node->value.pair->first->type != Lisp_Object_Type::CFunction &&
node->value.pair->first->type != Lisp_Object_Type::Function)
{ {
try { try {
lispOperator = eval_expr(node->value.pair->first, env); lispOperator = eval_expr(node->value.pair->first, env);
@@ -388,17 +388,17 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
lispOperator = node->value.pair->first; lispOperator = node->value.pair->first;
} }


Ast_Node* arguments = node->value.pair->rest;
Lisp_Object* arguments = node->value.pair->rest;
int arguments_length; int arguments_length;


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


// check for lisp function // check for lisp function
if (lispOperator->type == Ast_Node_Type::Function) {
if (lispOperator->type == 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) {
@@ -407,7 +407,7 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
} }
} }


Ast_Node* result;
Lisp_Object* result;
try { try {
result = apply_arguments_to_function(arguments, lispOperator->value.function); result = apply_arguments_to_function(arguments, lispOperator->value.function);
} }
@@ -421,12 +421,12 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
#undef report_error #undef report_error
} }


bool is_truthy (Ast_Node* expression, Environment* env) {
Ast_Node* result;
bool is_truthy (Lisp_Object* expression, Environment* env) {
Lisp_Object* result;
try { try {
result = eval_expr(expression, env); result = eval_expr(expression, env);
} }
if (result->type == Ast_Node_Type::Nil)
if (result->type == Lisp_Object_Type::Nil)
return false; return false;
return true; return true;




+ 26
- 26
src/io.cpp Прегледај датотеку

@@ -38,27 +38,27 @@ void panic(char* message) {
exit(1); exit(1);
} }


void print(Ast_Node* node) {
void print(Lisp_Object* node) {
switch (node->type) { switch (node->type) {
case (Ast_Node_Type::Nil): {
case (Lisp_Object_Type::Nil): {
printf("nil"); printf("nil");
} break; } break;
case (Ast_Node_Type::T): {
case (Lisp_Object_Type::T): {
printf("t"); printf("t");
} break; } break;
case (Ast_Node_Type::Number): {
case (Lisp_Object_Type::Number): {
printf("%f", node->value.number->value); printf("%f", node->value.number->value);
} break; } break;
case (Ast_Node_Type::String): {
case (Lisp_Object_Type::String): {
printf("\"%s\"", node->value.string->value); printf("\"%s\"", node->value.string->value);
} break; } break;
case (Ast_Node_Type::Symbol): {
case (Lisp_Object_Type::Symbol): {
printf("%s", node->value.symbol->identifier); printf("%s", node->value.symbol->identifier);
} break; } break;
case (Ast_Node_Type::Keyword): {
case (Lisp_Object_Type::Keyword): {
printf(":%s", node->value.keyword->identifier); printf(":%s", node->value.keyword->identifier);
} break; } break;
case (Ast_Node_Type::Function): {
case (Lisp_Object_Type::Function): {
if (node->value.function->type == Function_Type::Lambda) if (node->value.function->type == Function_Type::Lambda)
printf("[lambda]"); printf("[lambda]");
else if (node->value.function->type == Function_Type::Special_Lambda) else if (node->value.function->type == Function_Type::Special_Lambda)
@@ -68,11 +68,11 @@ void print(Ast_Node* node) {
else else
assert(false); assert(false);
} break; } break;
case (Ast_Node_Type::CFunction): {
case (Lisp_Object_Type::CFunction): {
printf("[C-function]"); printf("[C-function]");
} break; } break;
case (Ast_Node_Type::Pair): {
Ast_Node* head = node;
case (Lisp_Object_Type::Pair): {
Lisp_Object* head = node;
printf("("); printf("(");


// NOTE(Felix): We cold do a while true here, however in case // NOTE(Felix): We cold do a while true here, however in case
@@ -83,12 +83,12 @@ void print(Ast_Node* node) {
head = head->value.pair->rest; head = head->value.pair->rest;
if (!head) if (!head)
return; return;
if (head->type != Ast_Node_Type::Pair)
if (head->type != Lisp_Object_Type::Pair)
break; break;
printf(" "); printf(" ");
} }


if (head->type != Ast_Node_Type::Nil) {
if (head->type != Lisp_Object_Type::Nil) {
printf(" . "); printf(" . ");
print(head); print(head);
} }
@@ -99,27 +99,27 @@ void print(Ast_Node* node) {
} }


// XXX(Felix): obv code dublicate // XXX(Felix): obv code dublicate
void fprint(FILE* f, Ast_Node* node) {
void fprint(FILE* f, Lisp_Object* node) {
switch (node->type) { switch (node->type) {
case (Ast_Node_Type::Nil): {
case (Lisp_Object_Type::Nil): {
fprintf(f, "nil"); fprintf(f, "nil");
} break; } break;
case (Ast_Node_Type::T): {
case (Lisp_Object_Type::T): {
fprintf(f, "t"); fprintf(f, "t");
} break; } break;
case (Ast_Node_Type::Number): {
case (Lisp_Object_Type::Number): {
fprintf(f, "%f", node->value.number->value); fprintf(f, "%f", node->value.number->value);
} break; } break;
case (Ast_Node_Type::String): {
case (Lisp_Object_Type::String): {
fprintf(f, "\"%s\"", node->value.string->value); fprintf(f, "\"%s\"", node->value.string->value);
} break; } break;
case (Ast_Node_Type::Symbol): {
case (Lisp_Object_Type::Symbol): {
fprintf(f, "%s", node->value.symbol->identifier); fprintf(f, "%s", node->value.symbol->identifier);
} break; } break;
case (Ast_Node_Type::Keyword): {
case (Lisp_Object_Type::Keyword): {
fprintf(f, ":%s", node->value.keyword->identifier); fprintf(f, ":%s", node->value.keyword->identifier);
} break; } break;
case (Ast_Node_Type::Function): {
case (Lisp_Object_Type::Function): {
if (node->value.function->type == Function_Type::Lambda) if (node->value.function->type == Function_Type::Lambda)
fprintf(f, "[lambda]"); fprintf(f, "[lambda]");
else if (node->value.function->type == Function_Type::Special_Lambda) else if (node->value.function->type == Function_Type::Special_Lambda)
@@ -129,11 +129,11 @@ void fprint(FILE* f, Ast_Node* node) {
else else
assert(false); assert(false);
} break; } break;
case (Ast_Node_Type::CFunction): {
case (Lisp_Object_Type::CFunction): {
fprintf(f, "[C-function]"); fprintf(f, "[C-function]");
} break; } break;
case (Ast_Node_Type::Pair): {
Ast_Node* head = node;
case (Lisp_Object_Type::Pair): {
Lisp_Object* head = node;
fprintf(f, "("); fprintf(f, "(");


// NOTE(Felix): We cold do a while true here, however in case // NOTE(Felix): We cold do a while true here, however in case
@@ -144,12 +144,12 @@ void fprint(FILE* f, Ast_Node* node) {
head = head->value.pair->rest; head = head->value.pair->rest;
if (!head) if (!head)
return; return;
if (head->type != Ast_Node_Type::Pair)
if (head->type != Lisp_Object_Type::Pair)
break; break;
fprintf(f, " "); fprintf(f, " ");
} }


if (head->type != Ast_Node_Type::Nil) {
if (head->type != Lisp_Object_Type::Nil) {
fprintf(f, " . "); fprintf(f, " . ");
print(head); print(head);
} }


src/ast.cpp → src/lisp_object.cpp Прегледај датотеку

@@ -1,8 +1,8 @@
struct Ast_Node;
struct Lisp_Object;


define_array_list(Ast_Node*, Ast_Node);
define_array_list(Lisp_Object*, Lisp_Object);


enum struct Ast_Node_Type {
enum struct Lisp_Object_Type {
Nil, Nil,
T, T,
Symbol, Symbol,
@@ -14,17 +14,17 @@ enum struct Ast_Node_Type {
CFunction, CFunction,
}; };


char* Ast_Node_Type_to_string(Ast_Node_Type type) {
char* Lisp_Object_Type_to_string(Lisp_Object_Type type) {
switch (type) { switch (type) {
case(Ast_Node_Type::Nil): return "nil";
case(Ast_Node_Type::T): return "t";
case(Ast_Node_Type::Number): return "number";
case(Ast_Node_Type::String): return "string";
case(Ast_Node_Type::Symbol): return "symbol";
case(Ast_Node_Type::Keyword): return "keyword";
case(Ast_Node_Type::Function): return "function";
case(Ast_Node_Type::CFunction): return "C-function";
case(Ast_Node_Type::Pair): return "pair";
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"; return "unknown";
} }
@@ -47,12 +47,12 @@ struct String {
}; };


struct Pair { struct Pair {
Ast_Node* first;
Ast_Node* rest;
Lisp_Object* first;
Lisp_Object* rest;
}; };


struct Positional_Arguments { struct Positional_Arguments {
// TODO(Felix) use Ast_Node_symbols here instead, so we don't have
// TODO(Felix) use Lisp_Object_symbols here instead, so we don't have
// to convert them to strings and back to symbols // to convert them to strings and back to symbols
char** identifiers; char** identifiers;
int next_index; int next_index;
@@ -63,7 +63,7 @@ struct Keyword_Arguments {
char** identifiers; char** identifiers;
// NOTE(Felix): values[i] will be nullptr if no defalut value was // NOTE(Felix): values[i] will be nullptr if no defalut value was
// declared for key identifiers[i] // declared for key identifiers[i]
Ast_Node_Array_List* values;
Lisp_Object_Array_List* values;
int next_index; int next_index;
int length; int length;
}; };
@@ -88,7 +88,7 @@ void append_to_positional_argument_list(Positional_Arguments* args, char* identi
Keyword_Arguments* create_keyword_argument_list(int initial_capacity) { Keyword_Arguments* create_keyword_argument_list(int initial_capacity) {
Keyword_Arguments* ret = new(Keyword_Arguments); Keyword_Arguments* ret = new(Keyword_Arguments);
ret->identifiers = (char**)malloc(initial_capacity * sizeof(char*)); ret->identifiers = (char**)malloc(initial_capacity * sizeof(char*));
ret->values = create_Ast_Node_array_list(initial_capacity);
ret->values = create_Lisp_Object_array_list(initial_capacity);
ret->next_index = 0; ret->next_index = 0;
ret->length = initial_capacity; ret->length = initial_capacity;
return ret; return ret;
@@ -96,7 +96,7 @@ Keyword_Arguments* create_keyword_argument_list(int initial_capacity) {


void append_to_keyword_argument_list(Keyword_Arguments* args, void append_to_keyword_argument_list(Keyword_Arguments* args,
char* identifier, char* identifier,
struct Ast_Node* default_value)
struct Lisp_Object* default_value)
{ {
if (args->next_index == args->length) { if (args->next_index == args->length) {
args->length *= 2; args->length *= 2;
@@ -104,7 +104,7 @@ void append_to_keyword_argument_list(Keyword_Arguments* args,
} }


args->identifiers[args->next_index++] = identifier; args->identifiers[args->next_index++] = identifier;
append_to_Ast_Node_array_list(args->values, default_value);
append_to_Lisp_Object_array_list(args->values, default_value);
} }


struct Environment; struct Environment;
@@ -122,18 +122,18 @@ struct Function {
Keyword_Arguments* keyword_arguments; Keyword_Arguments* keyword_arguments;
// rest_argument will be nullptr if no rest argument is declared // rest_argument will be nullptr if no rest argument is declared
char* rest_argument; char* rest_argument;
Ast_Node* body; // implicit prog
Lisp_Object* body; // implicit prog
Environment* parent_environment; // we are doing closures now!! Environment* parent_environment; // we are doing closures now!!
}; };




struct CFunction { struct CFunction {
std::function<Ast_Node*(Ast_Node*, Environment*)> function;
std::function<Lisp_Object* (Lisp_Object*, Environment*)> function;
}; };


struct Ast_Node {
struct Lisp_Object {
Source_Code_Location* sourceCodeLocation; Source_Code_Location* sourceCodeLocation;
Ast_Node_Type type;
Lisp_Object_Type type;
union { union {
Symbol* symbol; Symbol* symbol;
Keyword* keyword; Keyword* keyword;
@@ -146,85 +146,85 @@ struct Ast_Node {
}; };


struct Parsed_Arguments { struct Parsed_Arguments {
Ast_Node_Array_List* positional_arguments;
Lisp_Object_Array_List* positional_arguments;
// TODO(Felix): Really use hashmap (keyword[sting] -> // TODO(Felix): Really use hashmap (keyword[sting] ->
// value[Ast_Node*]) here
Ast_Node_Array_List* keyword_keys;
Ast_Node_Array_List* keyword_values;
// value[Lisp_Object*]) here
Lisp_Object_Array_List* keyword_keys;
Lisp_Object_Array_List* keyword_values;
}; };


Ast_Node* create_ast_node() {
Ast_Node* node = new(Ast_Node);
Lisp_Object* create_lisp_object() {
Lisp_Object* node = new(Lisp_Object);
node->sourceCodeLocation = nullptr; node->sourceCodeLocation = nullptr;
return node; return node;
} }


Ast_Node* create_ast_node_nil() {
Ast_Node* node = create_ast_node();
node->type = Ast_Node_Type::Nil;
Lisp_Object* create_lisp_object_nil() {
Lisp_Object* node = create_lisp_object();
node->type = Lisp_Object_Type::Nil;
node->value.pair = nullptr; node->value.pair = nullptr;
return node; return node;
} }


Ast_Node* create_ast_node_t() {
Ast_Node* node = create_ast_node();
node->type = Ast_Node_Type::T;
Lisp_Object* create_lisp_object_t() {
Lisp_Object* node = create_lisp_object();
node->type = Lisp_Object_Type::T;
node->value.pair = nullptr; node->value.pair = nullptr;
return node; return node;
} }


Ast_Node* create_ast_node_number(double number) {
Ast_Node* node = create_ast_node();
node->type = Ast_Node_Type::Number;
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 = new(Number);
node->value.number->value = number; node->value.number->value = number;
return node; return node;
} }


Ast_Node* create_ast_node_string(char* str, int length) {
Ast_Node* node = create_ast_node();
node->type = Ast_Node_Type::String;
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 = new(String);
node->value.string->value = str; node->value.string->value = str;
node->value.string->length = length; node->value.string->length = length;
return node; return node;
} }


Ast_Node* create_ast_node_symbol(char* identifier) {
Ast_Node* node = create_ast_node();
node->type = Ast_Node_Type::Symbol;
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 = new(Symbol);
node->value.symbol->identifier = identifier; node->value.symbol->identifier = identifier;
return node; return node;
} }


Ast_Node* create_ast_node_keyword(char* keyword) {
Ast_Node* node = create_ast_node();
node->type = Ast_Node_Type::Keyword;
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 = new(Keyword);
node->value.keyword->identifier = keyword; node->value.keyword->identifier = keyword;
return node; return node;
} }


Ast_Node* create_ast_node_cfunction(std::function<Ast_Node*(Ast_Node*, Environment*)> function) {
Ast_Node* node = create_ast_node();
node->type = Ast_Node_Type::CFunction;
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 = new(CFunction);
node->value.cfunction->function = function; node->value.cfunction->function = function;
return node; return node;
} }


Ast_Node* create_ast_node_pair(Ast_Node* first, Ast_Node* rest) {
Ast_Node* node = create_ast_node();
node->type = Ast_Node_Type::Pair;
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 = new(Pair);
node->value.pair->first = first; node->value.pair->first = first;
node->value.pair->rest = rest; node->value.pair->rest = rest;
return node; return node;
} }


Ast_Node* copy_ast_node(Ast_Node* n) {
Ast_Node* target = create_ast_node();
Lisp_Object* copy_lisp_object(Lisp_Object* n) {
Lisp_Object* target = create_lisp_object();
*target = *n; *target = *n;
return target; return target;
} }

+ 5
- 5
src/main.cpp Прегледај датотеку

@@ -9,7 +9,7 @@
#include <functional> #include <functional>


#include "./helpers.cpp" #include "./helpers.cpp"
#include "./ast.cpp"
#include "./lisp_object.cpp"
#include "./error.cpp" #include "./error.cpp"
#include "./io.cpp" #include "./io.cpp"
#include "./assert.cpp" #include "./assert.cpp"
@@ -19,7 +19,7 @@
#include "./eval.cpp" #include "./eval.cpp"
#include "./testing.cpp" #include "./testing.cpp"


Ast_Node* interprete_file (char* file_name) {
Lisp_Object* interprete_file (char* file_name) {
char* file_content = read_entire_file(file_name); char* file_content = read_entire_file(file_name);
if (!file_content) { if (!file_content) {
create_error(Error_Type::Unknown_Error, nullptr); create_error(Error_Type::Unknown_Error, nullptr);
@@ -34,12 +34,12 @@ Ast_Node* interprete_file (char* file_name) {
built_in_load("pre.slime", env); built_in_load("pre.slime", env);
} }


Ast_Node_Array_List* program;
Lisp_Object_Array_List* program;
try { try {
program = Parser::parse_program(file_name, file_content); program = Parser::parse_program(file_name, file_content);
} }


Ast_Node* result = create_ast_node_nil();
Lisp_Object* result = create_lisp_object_nil();
for (int i = 0; i < program->next_index; ++i) { for (int i = 0; i < program->next_index; ++i) {
try { try {
result = eval_expr(program->data[i], env); result = eval_expr(program->data[i], env);
@@ -64,7 +64,7 @@ int interprete_stdin () {
delete_error(); delete_error();
} }


Ast_Node* parsed, * evaluated;
Lisp_Object* parsed, * evaluated;
while (true) { while (true) {
printf(">"); printf(">");
line = read_expression(); line = read_expression();


+ 52
- 52
src/parse.cpp Прегледај датотеку

@@ -1,8 +1,8 @@
// forward decls -- start // forward decls -- start
void load_built_ins_into_environment(Environment*); void load_built_ins_into_environment(Environment*);
Ast_Node* eval_expr(Ast_Node*, Environment*);
void parse_argument_list(Ast_Node*, Function*);
int list_length(Ast_Node*);
Lisp_Object* eval_expr(Lisp_Object*, Environment*);
void parse_argument_list(Lisp_Object*, Function*);
int list_length(Lisp_Object*);
// forward decls -- end // forward decls -- end




@@ -109,34 +109,34 @@ namespace Parser {
return atom; return atom;
} }


Ast_Node* parse_number(char* text, int* index_in_text) {
Lisp_Object* parse_number(char* text, int* index_in_text) {
double number; double number;
char* str_number = read_atom(text, index_in_text); char* str_number = read_atom(text, index_in_text);
sscanf(str_number, "%lf", &number); sscanf(str_number, "%lf", &number);
Ast_Node* ret = create_ast_node_number(number);
Lisp_Object* ret = create_lisp_object_number(number);
inject_scl(ret); inject_scl(ret);
return ret; return ret;
} }


Ast_Node* parse_keyword(char* text, int* index_in_text) {
Lisp_Object* parse_keyword(char* text, int* index_in_text) {
// we are now on the colon // we are now on the colon
++(*index_in_text); ++(*index_in_text);
++parser_col; ++parser_col;
char* str_keyword = read_atom(text, index_in_text); char* str_keyword = read_atom(text, index_in_text);
Ast_Node* ret = create_ast_node_keyword(str_keyword);
Lisp_Object* ret = create_lisp_object_keyword(str_keyword);
inject_scl(ret); inject_scl(ret);
return ret; return ret;
} }


Ast_Node* parse_symbol(char* text, int* index_in_text) {
Lisp_Object* parse_symbol(char* text, int* index_in_text) {
// we are now at the first char of the symbol // we are now at the first char of the symbol
char* str_symbol = read_atom(text, index_in_text); char* str_symbol = read_atom(text, index_in_text);
Ast_Node* ret = create_ast_node_symbol(str_symbol);
Lisp_Object* ret = create_lisp_object_symbol(str_symbol);
inject_scl(ret); inject_scl(ret);
return ret; return ret;
} }


Ast_Node* parse_string(char* text, int* index_in_text) {
Lisp_Object* parse_string(char* text, int* index_in_text) {
// the first character is the '"' // the first character is the '"'
++(*index_in_text); ++(*index_in_text);
++parser_col; ++parser_col;
@@ -146,7 +146,7 @@ namespace Parser {
if (text[*index_in_text] == '"') { if (text[*index_in_text] == '"') {
char* str = new(char); char* str = new(char);
*str = '\0'; *str = '\0';
Ast_Node* ret = create_ast_node_string(str, 0);
Lisp_Object* ret = create_lisp_object_string(str, 0);
inject_scl(ret); inject_scl(ret);


// plus one because we want to go after the quotes // plus one because we want to go after the quotes
@@ -187,12 +187,12 @@ namespace Parser {
*index_in_text += string_length +1; // plus one because we want to *index_in_text += string_length +1; // plus one because we want to
// go after the quotes // go after the quotes


Ast_Node* ret = create_ast_node_string(string, string_length);
Lisp_Object* ret = create_lisp_object_string(string, string_length);
inject_scl(ret); inject_scl(ret);
return ret; return ret;
} }


Ast_Node* parse_atom(char* text, int* index_in_text) {
Lisp_Object* parse_atom(char* text, int* index_in_text) {
// numbers // numbers
if ((text[*index_in_text] <= 57 && // if number if ((text[*index_in_text] <= 57 && // if number
text[*index_in_text] >= 48) text[*index_in_text] >= 48)
@@ -220,7 +220,7 @@ namespace Parser {
return parse_symbol(text, index_in_text); return parse_symbol(text, index_in_text);
} }


Ast_Node* parse_expression(char* text, int* index_in_text) {
Lisp_Object* parse_expression(char* text, int* index_in_text) {


// if it is quoted // if it is quoted
if (text[*index_in_text] == '\'' || if (text[*index_in_text] == '\'' ||
@@ -230,7 +230,7 @@ namespace Parser {
char quoteType = text[*index_in_text]; char quoteType = text[*index_in_text];
++(*index_in_text); ++(*index_in_text);
++parser_col; ++parser_col;
Ast_Node* result;
Lisp_Object* result;
if (text[*index_in_text] == '(' || if (text[*index_in_text] == '(' ||
text[*index_in_text] == '\'' || text[*index_in_text] == '\'' ||
text[*index_in_text] == '`' || text[*index_in_text] == '`' ||
@@ -246,17 +246,17 @@ namespace Parser {
} }


if (quoteType == '\'') if (quoteType == '\'')
return create_ast_node_pair(
create_ast_node_symbol("quote"),
create_ast_node_pair(result, create_ast_node_nil()));
return create_lisp_object_pair(
create_lisp_object_symbol("quote"),
create_lisp_object_pair(result, create_lisp_object_nil()));
else if (quoteType == '`') else if (quoteType == '`')
return create_ast_node_pair(
create_ast_node_symbol("quasiquote"),
create_ast_node_pair(result, create_ast_node_nil()));
return create_lisp_object_pair(
create_lisp_object_symbol("quasiquote"),
create_lisp_object_pair(result, create_lisp_object_nil()));
// it has to be an unquote // it has to be an unquote
return create_ast_node_pair(
create_ast_node_symbol("unquote"),
create_ast_node_pair(result, create_ast_node_nil()));
return create_lisp_object_pair(
create_lisp_object_symbol("unquote"),
create_lisp_object_pair(result, create_lisp_object_nil()));
} }




@@ -271,14 +271,14 @@ namespace Parser {
if (text[(*index_in_text)] == ')') { if (text[(*index_in_text)] == ')') {
++(*index_in_text); ++(*index_in_text);
++parser_col; ++parser_col;
return create_ast_node_nil();
return create_lisp_object_nil();
} }


// okay there is something // okay there is something
Ast_Node* head = new(Ast_Node);
head->type = Ast_Node_Type::Pair;
Lisp_Object* head = new(Lisp_Object);
head->type = Lisp_Object_Type::Pair;
head->value.pair = new(Pair); head->value.pair = new(Pair);
Ast_Node* expression = head;
Lisp_Object* expression = head;


while (true) { while (true) {
if (text[*index_in_text] == '(' || if (text[*index_in_text] == '(' ||
@@ -303,7 +303,7 @@ namespace Parser {




if (text[(*index_in_text)] == ')') { if (text[(*index_in_text)] == ')') {
head->value.pair->rest = create_ast_node_nil();
head->value.pair->rest = create_lisp_object_nil();
++parser_col; ++parser_col;
++(*index_in_text); ++(*index_in_text);
break; break;
@@ -325,16 +325,16 @@ namespace Parser {
++(*index_in_text); ++(*index_in_text);
break; break;
} else { } else {
head->value.pair->rest = create_ast_node_pair(nullptr, nullptr);
head->value.pair->rest = create_lisp_object_pair(nullptr, nullptr);
head = head->value.pair->rest; head = head->value.pair->rest;
} }
} }


// 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 == Ast_Node_Type::Symbol) {
if (expression->value.pair->first->type == Lisp_Object_Type::Symbol) {
if (string_equal("define-syntax", expression->value.pair->first->value.symbol->identifier)) { if (string_equal("define-syntax", expression->value.pair->first->value.symbol->identifier)) {
// create a new macro // create a new macro
Ast_Node* arguments = expression->value.pair->rest;
Lisp_Object* arguments = expression->value.pair->rest;
int arguments_length; int arguments_length;


// HACK(Felix): almost code duplicate from // HACK(Felix): almost code duplicate from
@@ -349,13 +349,13 @@ namespace Parser {
return nullptr; return nullptr;
} }


if (arguments->value.pair->first->type != Ast_Node_Type::Symbol) {
if (arguments->value.pair->first->type != Lisp_Object_Type::Symbol) {
create_error(Error_Type::Type_Missmatch, expression->sourceCodeLocation); create_error(Error_Type::Type_Missmatch, expression->sourceCodeLocation);
return nullptr; return nullptr;
} }


// extract the name // extract the name
Ast_Node* symbol_for_macro = arguments->value.pair->first;
Lisp_Object* symbol_for_macro = arguments->value.pair->first;
arguments = arguments->value.pair->rest; arguments = arguments->value.pair->rest;


Function* function = new(Function); Function* function = new(Function);
@@ -363,9 +363,9 @@ namespace Parser {
function->type = Function_Type::Macro; function->type = Function_Type::Macro;


// if parameters were specified // if parameters were specified
if (arguments->value.pair->first->type != Ast_Node_Type::Nil) {
if (arguments->value.pair->first->type != Lisp_Object_Type::Nil) {
try { try {
assert_type(arguments->value.pair->first, Ast_Node_Type::Pair);
assert_type(arguments->value.pair->first, Lisp_Object_Type::Pair);
} }
try { try {
parse_argument_list(arguments->value.pair->first, function); parse_argument_list(arguments->value.pair->first, function);
@@ -378,7 +378,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 == Ast_Node_Type::String) {
if (arguments->value.pair->first->type == Lisp_Object_Type::String) {
function->docstring = arguments->value.pair->first->value.string->value; function->docstring = arguments->value.pair->first->value.string->value;
arguments = arguments->value.pair->rest; arguments = arguments->value.pair->rest;
} else { } else {
@@ -387,17 +387,17 @@ namespace Parser {


// we are now in the function body, just wrap it in an // we are now in the function body, just wrap it in an
// implicit prog // implicit prog
function->body = create_ast_node_pair(
create_ast_node_symbol("prog"),
function->body = create_lisp_object_pair(
create_lisp_object_symbol("prog"),
arguments); arguments);


Ast_Node* macro = new(Ast_Node);
macro->type = Ast_Node_Type::Function;
Lisp_Object* macro = new(Lisp_Object);
macro->type = Lisp_Object_Type::Function;
macro->value.function = function; macro->value.function = function;
define_symbol(symbol_for_macro, macro, environment_for_macros); define_symbol(symbol_for_macro, macro, environment_for_macros);


// print_environment(environment_for_macros); // print_environment(environment_for_macros);
return create_ast_node_nil();
return create_lisp_object_nil();


} else if (string_equal("delete-syntax", expression->value.pair->first->value.symbol->identifier)) { } else if (string_equal("delete-syntax", expression->value.pair->first->value.symbol->identifier)) {
/* --- deleting an existing macro --- */ /* --- deleting an existing macro --- */
@@ -420,7 +420,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.symbol->identifier, environment_for_macros->keys[i]) && if (string_equal(expression->value.pair->first->value.symbol->identifier, environment_for_macros->keys[i]) &&
environment_for_macros->values[i]->type == Ast_Node_Type::Function &&
environment_for_macros->values[i]->type == 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 {
@@ -444,16 +444,16 @@ namespace Parser {
return expression; return expression;
} }


Ast_Node* parse_single_expression(char* text) {
Lisp_Object* parse_single_expression(char* text) {
parser_file = "stdin"; parser_file = "stdin";
parser_line = 1; parser_line = 1;
parser_col = 1; parser_col = 1;


int index_in_text = 0; int index_in_text = 0;
Ast_Node* result;
Lisp_Object* result;
eat_until_code(text, &index_in_text); eat_until_code(text, &index_in_text);
if (text[(index_in_text)] == '\0') if (text[(index_in_text)] == '\0')
return create_ast_node_nil();
return create_lisp_object_nil();
if (text[index_in_text] == '(' || if (text[index_in_text] == '(' ||
text[index_in_text] == '\'' || text[index_in_text] == '\'' ||
text[index_in_text] == '`' || text[index_in_text] == '`' ||
@@ -474,7 +474,7 @@ namespace Parser {
return nullptr; return nullptr;
} }


void write_expanded_file(char* file_name, Ast_Node_Array_List* program) {
void write_expanded_file(char* file_name, Lisp_Object_Array_List* program) {
char* ext = ".expanded"; char* ext = ".expanded";
char* newName = (char*)calloc(4 + strlen(file_name), sizeof(char)); char* newName = (char*)calloc(4 + strlen(file_name), sizeof(char));
strcpy(newName, file_name); strcpy(newName, file_name);
@@ -488,7 +488,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 == Ast_Node_Type::Nil)
if (program->data[i]->type == Lisp_Object_Type::Nil)
continue; continue;
fprint(f, program->data[i]); fprint(f, program->data[i]);
fprintf(f, "\n\n"); fprintf(f, "\n\n");
@@ -497,24 +497,24 @@ namespace Parser {
fclose(f); fclose(f);
} }


Ast_Node_Array_List* parse_program(char* file_name, char* text) {
Lisp_Object_Array_List* parse_program(char* file_name, char* text) {
parser_file = (char*)malloc(strlen(file_name) * sizeof(char) + 1); parser_file = (char*)malloc(strlen(file_name) * sizeof(char) + 1);
strcpy(parser_file, file_name); strcpy(parser_file, file_name);
parser_line = 1; parser_line = 1;
parser_col = 0; parser_col = 0;


Ast_Node_Array_List* program = create_Ast_Node_array_list(16);
Lisp_Object_Array_List* program = create_Lisp_Object_array_list(16);


int index_in_text = 0; int index_in_text = 0;


while (text[index_in_text] != '\0') { while (text[index_in_text] != '\0') {
switch (text[index_in_text]) { switch (text[index_in_text]) {
case '(': { case '(': {
Ast_Node* parsed;
Lisp_Object* parsed;
try { try {
parsed = parse_expression(text, &index_in_text); parsed = parse_expression(text, &index_in_text);
} }
append_to_Ast_Node_array_list(program, parsed);
append_to_Lisp_Object_array_list(program, parsed);
} break; } break;
case ';': case ';':
case ' ': case ' ':


+ 62
- 62
src/testing.cpp Прегледај датотеку

@@ -57,8 +57,8 @@
#define assert_equal_type(node, _type) \ #define assert_equal_type(node, _type) \
if (node->type != _type) { \ if (node->type != _type) { \
print_assert_equal_fail( \ print_assert_equal_fail( \
Ast_Node_Type_to_string(node->type), \
Ast_Node_Type_to_string(_type), char*, "%s"); \
Lisp_Object_Type_to_string(node->type), \
Lisp_Object_Type_to_string(_type), char*, "%s"); \
return fail; \ return fail; \
} \ } \


@@ -87,33 +87,33 @@


testresult test_eval_operands() { testresult test_eval_operands() {
char operands_string[] = "((eval 1) (+ 1 2) \"okay\" (eval :haha))"; char operands_string[] = "((eval 1) (+ 1 2) \"okay\" (eval :haha))";
Ast_Node* operands = Parser::parse_single_expression(operands_string);
Lisp_Object* operands = Parser::parse_single_expression(operands_string);
int operands_length; int operands_length;
operands = eval_arguments(operands, create_built_ins_environment(), &operands_length); operands = eval_arguments(operands, create_built_ins_environment(), &operands_length);


assert_no_error(error); assert_no_error(error);
assert_equal_int(list_length(operands), 4); assert_equal_int(list_length(operands), 4);


assert_equal_type(operands, Ast_Node_Type::Pair);
assert_equal_type(operands->value.pair->first, Ast_Node_Type::Number);
assert_equal_type(operands, Lisp_Object_Type::Pair);
assert_equal_type(operands->value.pair->first, Lisp_Object_Type::Number);
assert_equal_double(operands->value.pair->first->value.number->value, 1); assert_equal_double(operands->value.pair->first->value.number->value, 1);


operands = operands->value.pair->rest; operands = operands->value.pair->rest;


assert_equal_type(operands, Ast_Node_Type::Pair);
assert_equal_type(operands->value.pair->first, Ast_Node_Type::Number);
assert_equal_type(operands, Lisp_Object_Type::Pair);
assert_equal_type(operands->value.pair->first, Lisp_Object_Type::Number);
assert_equal_double(operands->value.pair->first->value.number->value, 3); assert_equal_double(operands->value.pair->first->value.number->value, 3);


operands = operands->value.pair->rest; operands = operands->value.pair->rest;


assert_equal_type(operands, Ast_Node_Type::Pair);
assert_equal_type(operands->value.pair->first, Ast_Node_Type::String);
assert_equal_type(operands, Lisp_Object_Type::Pair);
assert_equal_type(operands->value.pair->first, Lisp_Object_Type::String);
assert_equal_string(operands->value.pair->first->value.string->value, "okay"); assert_equal_string(operands->value.pair->first->value.string->value, "okay");


operands = operands->value.pair->rest; operands = operands->value.pair->rest;


assert_equal_type(operands, Ast_Node_Type::Pair);
assert_equal_type(operands->value.pair->first, Ast_Node_Type::Keyword);
assert_equal_type(operands, Lisp_Object_Type::Pair);
assert_equal_type(operands->value.pair->first, Lisp_Object_Type::Keyword);
assert_equal_string(operands->value.pair->first->value.keyword->identifier, "haha"); assert_equal_string(operands->value.pair->first->value.keyword->identifier, "haha");


return pass; return pass;
@@ -128,48 +128,48 @@ testresult test_parse_atom() {
"sym +"; // symbols "sym +"; // symbols


// test numbers // test numbers
Ast_Node* result = Parser::parse_atom(string, &index_in_text);
Lisp_Object* result = Parser::parse_atom(string, &index_in_text);


assert_equal_type(result, Ast_Node_Type::Number);
assert_equal_type(result, Lisp_Object_Type::Number);
assert_equal_double(result->value.number->value, 123); assert_equal_double(result->value.number->value, 123);


++index_in_text; ++index_in_text;


result = Parser::parse_atom(string, &index_in_text); result = Parser::parse_atom(string, &index_in_text);
assert_equal_type(result, Ast_Node_Type::Number);
assert_equal_type(result, Lisp_Object_Type::Number);
assert_equal_double(result->value.number->value, -1.23e-2); assert_equal_double(result->value.number->value, -1.23e-2);


// test strings // test strings
++index_in_text; ++index_in_text;


result = Parser::parse_atom(string, &index_in_text); result = Parser::parse_atom(string, &index_in_text);
assert_equal_type(result, Ast_Node_Type::String);
assert_equal_type(result, Lisp_Object_Type::String);
assert_equal_string(result->value.string->value, "asd"); assert_equal_string(result->value.string->value, "asd");


// test keywords // test keywords
++index_in_text; ++index_in_text;


result = Parser::parse_atom(string, &index_in_text); result = Parser::parse_atom(string, &index_in_text);
assert_equal_type(result, Ast_Node_Type::Keyword);
assert_equal_type(result, Lisp_Object_Type::Keyword);
assert_equal_string(result->value.keyword->identifier, "key1"); assert_equal_string(result->value.keyword->identifier, "key1");


++index_in_text; ++index_in_text;


result = Parser::parse_atom(string, &index_in_text); result = Parser::parse_atom(string, &index_in_text);
assert_equal_type(result, Ast_Node_Type::Keyword);
assert_equal_type(result, Lisp_Object_Type::Keyword);
assert_equal_string(result->value.keyword->identifier, "key:2"); assert_equal_string(result->value.keyword->identifier, "key:2");


// test symbols // test symbols
++index_in_text; ++index_in_text;


result = Parser::parse_atom(string, &index_in_text); result = Parser::parse_atom(string, &index_in_text);
assert_equal_type(result, Ast_Node_Type::Symbol);
assert_equal_type(result, Lisp_Object_Type::Symbol);
assert_equal_string(result->value.symbol->identifier, "sym"); assert_equal_string(result->value.symbol->identifier, "sym");


++index_in_text; ++index_in_text;


result = Parser::parse_atom(string, &index_in_text); result = Parser::parse_atom(string, &index_in_text);
assert_equal_type(result, Ast_Node_Type::Symbol);
assert_equal_type(result, Lisp_Object_Type::Symbol);
assert_equal_string(result->value.symbol->identifier, "+"); assert_equal_string(result->value.symbol->identifier, "+");


return pass; return pass;
@@ -179,28 +179,28 @@ testresult test_parse_expression() {
int index_in_text = 0; int index_in_text = 0;
char string[] = "(fun + 12)"; char string[] = "(fun + 12)";


Ast_Node* result = Parser::parse_expression(string, &index_in_text);
Lisp_Object* result = Parser::parse_expression(string, &index_in_text);
assert_no_error(error); assert_no_error(error);


assert_equal_type(result, Ast_Node_Type::Pair);
assert_equal_type(result->value.pair->first, Ast_Node_Type::Symbol);
assert_equal_type(result, Lisp_Object_Type::Pair);
assert_equal_type(result->value.pair->first, Lisp_Object_Type::Symbol);
assert_equal_string(result->value.pair->first->value.symbol->identifier, "fun"); assert_equal_string(result->value.pair->first->value.symbol->identifier, "fun");


result = result->value.pair->rest; result = result->value.pair->rest;


assert_equal_type(result, Ast_Node_Type::Pair);
assert_equal_type(result->value.pair->first, Ast_Node_Type::Symbol);
assert_equal_type(result, Lisp_Object_Type::Pair);
assert_equal_type(result->value.pair->first, Lisp_Object_Type::Symbol);
assert_equal_string(result->value.pair->first->value.symbol->identifier, "+"); assert_equal_string(result->value.pair->first->value.symbol->identifier, "+");


result = result->value.pair->rest; result = result->value.pair->rest;


assert_equal_type(result, Ast_Node_Type::Pair);
assert_equal_type(result->value.pair->first, Ast_Node_Type::Number);
assert_equal_type(result, Lisp_Object_Type::Pair);
assert_equal_type(result->value.pair->first, Lisp_Object_Type::Number);
assert_equal_double(result->value.pair->first->value.number->value, 12); assert_equal_double(result->value.pair->first->value.number->value, 12);


result = result->value.pair->rest; result = result->value.pair->rest;


assert_equal_type(result, Ast_Node_Type::Nil);
assert_equal_type(result, Lisp_Object_Type::Nil);


char string2[] = "(define fun (lambda (x) (+ 5 (* x x ))))"; char string2[] = "(define fun (lambda (x) (+ 5 (* x x ))))";
index_in_text = 0; index_in_text = 0;
@@ -208,21 +208,21 @@ testresult test_parse_expression() {
result = Parser::parse_expression(string2, &index_in_text); result = Parser::parse_expression(string2, &index_in_text);
assert_no_error(error); assert_no_error(error);


assert_equal_type(result, Ast_Node_Type::Pair);
assert_equal_type(result->value.pair->first, Ast_Node_Type::Symbol);
assert_equal_type(result, Lisp_Object_Type::Pair);
assert_equal_type(result->value.pair->first, Lisp_Object_Type::Symbol);
assert_equal_string(result->value.pair->first->value.symbol->identifier, "define"); assert_equal_string(result->value.pair->first->value.symbol->identifier, "define");


result = result->value.pair->rest; result = result->value.pair->rest;


assert_equal_type(result, Ast_Node_Type::Pair);
assert_equal_type(result->value.pair->first, Ast_Node_Type::Symbol);
assert_equal_type(result, Lisp_Object_Type::Pair);
assert_equal_type(result->value.pair->first, Lisp_Object_Type::Symbol);
assert_equal_string(result->value.pair->first->value.symbol->identifier, "fun"); assert_equal_string(result->value.pair->first->value.symbol->identifier, "fun");


result = result->value.pair->rest; result = result->value.pair->rest;


assert_equal_type(result, Ast_Node_Type::Pair);
assert_equal_type(result->value.pair->first, Ast_Node_Type::Pair);
assert_equal_type(result->value.pair->first->value.pair->first, Ast_Node_Type::Symbol);
assert_equal_type(result, Lisp_Object_Type::Pair);
assert_equal_type(result->value.pair->first, Lisp_Object_Type::Pair);
assert_equal_type(result->value.pair->first->value.pair->first, Lisp_Object_Type::Symbol);
assert_equal_string(result->value.pair->first->value.pair->first->value.symbol->identifier, "lambda"); assert_equal_string(result->value.pair->first->value.pair->first->value.symbol->identifier, "lambda");


result = result->value.pair->rest; result = result->value.pair->rest;
@@ -232,12 +232,12 @@ testresult test_parse_expression() {


testresult test_built_in_add() { testresult test_built_in_add() {
char exp_string[] = "(+ 10 4)"; char exp_string[] = "(+ 10 4)";
Ast_Node* expression = Parser::parse_single_expression(exp_string);
Ast_Node* result = eval_expr(expression, create_built_ins_environment());
Lisp_Object* expression = Parser::parse_single_expression(exp_string);
Lisp_Object* result = eval_expr(expression, create_built_ins_environment());


assert_no_error(error); assert_no_error(error);
assert_not_null(result); assert_not_null(result);
assert_equal_type(result, Ast_Node_Type::Number);
assert_equal_type(result, Lisp_Object_Type::Number);
assert_equal_double(result->value.number->value, 14); assert_equal_double(result->value.number->value, 14);


return pass; return pass;
@@ -245,12 +245,12 @@ testresult test_built_in_add() {


testresult test_built_in_substract() { testresult test_built_in_substract() {
char exp_string[] = "(- 10 4)"; char exp_string[] = "(- 10 4)";
Ast_Node* expression = Parser::parse_single_expression(exp_string);
Ast_Node* result = eval_expr(expression, create_built_ins_environment());
Lisp_Object* expression = Parser::parse_single_expression(exp_string);
Lisp_Object* result = eval_expr(expression, create_built_ins_environment());


assert_no_error(error); assert_no_error(error);
assert_not_null(result); assert_not_null(result);
assert_equal_type(result, Ast_Node_Type::Number);
assert_equal_type(result, Lisp_Object_Type::Number);
assert_equal_double(result->value.number->value, 6); assert_equal_double(result->value.number->value, 6);


return pass; return pass;
@@ -259,12 +259,12 @@ testresult test_built_in_substract() {


testresult test_built_in_multiply() { testresult test_built_in_multiply() {
char exp_string[] = "(* 10 4)"; char exp_string[] = "(* 10 4)";
Ast_Node* expression = Parser::parse_single_expression(exp_string);
Ast_Node* result = eval_expr(expression, create_built_ins_environment());
Lisp_Object* expression = Parser::parse_single_expression(exp_string);
Lisp_Object* result = eval_expr(expression, create_built_ins_environment());


assert_no_error(error); assert_no_error(error);
assert_not_null(result); assert_not_null(result);
assert_equal_type(result, Ast_Node_Type::Number);
assert_equal_type(result, Lisp_Object_Type::Number);
assert_equal_double(result->value.number->value, 40); assert_equal_double(result->value.number->value, 40);


return pass; return pass;
@@ -273,12 +273,12 @@ testresult test_built_in_multiply() {


testresult test_built_in_divide() { testresult test_built_in_divide() {
char exp_string[] = "(/ 20 4)"; char exp_string[] = "(/ 20 4)";
Ast_Node* expression = Parser::parse_single_expression(exp_string);
Ast_Node* result = eval_expr(expression, create_built_ins_environment());
Lisp_Object* expression = Parser::parse_single_expression(exp_string);
Lisp_Object* result = eval_expr(expression, create_built_ins_environment());


assert_null(error); assert_null(error);
assert_not_null(result); assert_not_null(result);
assert_equal_type(result, Ast_Node_Type::Number);
assert_equal_type(result, Lisp_Object_Type::Number);
assert_equal_double(result->value.number->value, 5); assert_equal_double(result->value.number->value, 5);


return pass; return pass;
@@ -287,12 +287,12 @@ testresult test_built_in_divide() {


testresult test_built_in_if() { testresult test_built_in_if() {
char exp_string1[] = "(if 1 4 5)"; char exp_string1[] = "(if 1 4 5)";
Ast_Node* expression = Parser::parse_single_expression(exp_string1);
Ast_Node* result = eval_expr(expression, create_built_ins_environment());
Lisp_Object* expression = Parser::parse_single_expression(exp_string1);
Lisp_Object* result = eval_expr(expression, create_built_ins_environment());


assert_no_error(error); assert_no_error(error);
assert_not_null(result); assert_not_null(result);
assert_equal_type(result, Ast_Node_Type::Number);
assert_equal_type(result, Lisp_Object_Type::Number);
assert_equal_double(result->value.number->value, 4); assert_equal_double(result->value.number->value, 4);


char exp_string2[] = "(if () 4 5)"; char exp_string2[] = "(if () 4 5)";
@@ -301,7 +301,7 @@ testresult test_built_in_if() {


assert_no_error(error); assert_no_error(error);
assert_not_null(result); assert_not_null(result);
assert_equal_type(result, Ast_Node_Type::Number);
assert_equal_type(result, Lisp_Object_Type::Number);
assert_equal_double(result->value.number->value, 5); assert_equal_double(result->value.number->value, 5);


return pass; return pass;
@@ -309,12 +309,12 @@ testresult test_built_in_if() {


testresult test_built_in_and() { testresult test_built_in_and() {
char exp_string1[] = "(and 1 \"asd\" 4)"; char exp_string1[] = "(and 1 \"asd\" 4)";
Ast_Node* expression = Parser::parse_single_expression(exp_string1);
Ast_Node* result = eval_expr(expression, create_built_ins_environment());
Lisp_Object* expression = Parser::parse_single_expression(exp_string1);
Lisp_Object* result = eval_expr(expression, create_built_ins_environment());


assert_no_error(error); assert_no_error(error);
assert_not_null(result); assert_not_null(result);
assert_equal_type(result, Ast_Node_Type::T);
assert_equal_type(result, Lisp_Object_Type::T);


// a false case // a false case
char exp_string2[] = "(and () \"asd\" 4)"; char exp_string2[] = "(and () \"asd\" 4)";
@@ -323,19 +323,19 @@ testresult test_built_in_and() {


assert_no_error(error); assert_no_error(error);
assert_not_null(result); assert_not_null(result);
assert_equal_type(result, Ast_Node_Type::Nil);
assert_equal_type(result, Lisp_Object_Type::Nil);


return pass; return pass;
} }


testresult test_built_in_or() { testresult test_built_in_or() {
char exp_string1[] = "(or \"asd\" nil)"; char exp_string1[] = "(or \"asd\" nil)";
Ast_Node* expression = Parser::parse_single_expression(exp_string1);
Ast_Node* result = eval_expr(expression, create_built_ins_environment());
Lisp_Object* expression = Parser::parse_single_expression(exp_string1);
Lisp_Object* result = eval_expr(expression, create_built_ins_environment());


assert_no_error(error); assert_no_error(error);
assert_not_null(result); assert_not_null(result);
assert_equal_type(result, Ast_Node_Type::T);
assert_equal_type(result, Lisp_Object_Type::T);


// a false case // a false case
char exp_string2[] = "(or () ())"; char exp_string2[] = "(or () ())";
@@ -344,7 +344,7 @@ testresult test_built_in_or() {


assert_no_error(error); assert_no_error(error);
assert_not_null(result); assert_not_null(result);
assert_equal_type(result, Ast_Node_Type::Nil);
assert_equal_type(result, Lisp_Object_Type::Nil);


return pass; return pass;
} }
@@ -352,13 +352,13 @@ testresult test_built_in_or() {


testresult test_built_in_not() { testresult test_built_in_not() {
char exp_string1[] = "(not ())"; char exp_string1[] = "(not ())";
Ast_Node* expression = Parser::parse_single_expression(exp_string1);
Ast_Node* result = eval_expr(expression, create_built_ins_environment());
Lisp_Object* expression = Parser::parse_single_expression(exp_string1);
Lisp_Object* result = eval_expr(expression, create_built_ins_environment());


// a true case // a true case
assert_no_error(error); assert_no_error(error);
assert_not_null(result); assert_not_null(result);
assert_equal_type(result, Ast_Node_Type::T);
assert_equal_type(result, Lisp_Object_Type::T);


// a false case // a false case
char exp_string2[] = "(not \"asd xD\")"; char exp_string2[] = "(not \"asd xD\")";
@@ -367,7 +367,7 @@ testresult test_built_in_not() {


assert_no_error(error); assert_no_error(error);
assert_not_null(result); assert_not_null(result);
assert_equal_type(result, Ast_Node_Type::Nil);
assert_equal_type(result, Lisp_Object_Type::Nil);


return pass; return pass;
} }


Loading…
Откажи
Сачувај