renaming "ast_node" -> "lisp_object"
This commit is contained in:
+1
-1
@@ -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;
|
||||||
|
|||||||
+206
-206
File diff suppressed because it is too large
Load Diff
+9
-9
@@ -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
@@ -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) {
|
if (arguments->type == Lisp_Object_Type::Pair) {
|
||||||
// TODO(Felix): here we create new ast_node_symbols from
|
// 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),
|
create_lisp_object_symbol(defined_keyword),
|
||||||
copy_ast_node(function->keyword_arguments->values->data[i]), new_env);
|
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_lisp_object_symbol(function->rest_argument),
|
||||||
create_ast_node_nil(), new_env);
|
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) {
|
while (arguments->type == Lisp_Object_Type::Pair) {
|
||||||
if (arguments->value.pair->first->type == Ast_Node_Type::Keyword) {
|
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 != Lisp_Object_Type::Pair) {
|
||||||
if (arguments->type != Ast_Node_Type::Nil)
|
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 ||
|
if (arguments->type != Lisp_Object_Type::Pair ||
|
||||||
arguments->value.pair->first->type != Ast_Node_Type::Symbol)
|
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) {
|
while (arguments->type == Lisp_Object_Type::Pair) {
|
||||||
if (arguments->value.pair->first->type == Ast_Node_Type::Keyword) {
|
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;
|
Lisp_Object* next = arguments->value.pair->rest;
|
||||||
if (next->type == Ast_Node_Type::Pair &&
|
if (next->type == Lisp_Object_Type::Pair &&
|
||||||
next->value.pair->first->type == Ast_Node_Type::Keyword &&
|
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 != Lisp_Object_Type::Pair) {
|
||||||
if (arguments->type != Ast_Node_Type::Nil)
|
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 ||
|
if (arguments->type != Lisp_Object_Type::Pair ||
|
||||||
arguments->value.pair->first->type != Ast_Node_Type::Symbol)
|
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) {
|
int list_length(Lisp_Object* node) {
|
||||||
if (node->type == Ast_Node_Type::Nil)
|
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);
|
Lisp_Object* evaluated_arguments = create_lisp_object_pair(nullptr, nullptr);
|
||||||
Ast_Node* evaluated_arguments_head = evaluated_arguments;
|
Lisp_Object* evaluated_arguments_head = evaluated_arguments;
|
||||||
Ast_Node* current_head = arguments;
|
Lisp_Object* current_head = arguments;
|
||||||
while (current_head->type == Ast_Node_Type::Pair) {
|
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) {
|
if (current_head->type == Lisp_Object_Type::Pair) {
|
||||||
evaluated_arguments_head->value.pair->rest = create_ast_node_pair(nullptr, nullptr);
|
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 Lisp_Object_Type::T:
|
||||||
case Ast_Node_Type::Nil:
|
case Lisp_Object_Type::Nil:
|
||||||
return node;
|
return node;
|
||||||
case Ast_Node_Type::Symbol: {
|
case Lisp_Object_Type::Symbol: {
|
||||||
Ast_Node* 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 Lisp_Object_Type::Number:
|
||||||
case Ast_Node_Type::Keyword:
|
case Lisp_Object_Type::Keyword:
|
||||||
case Ast_Node_Type::String:
|
case Lisp_Object_Type::String:
|
||||||
return node;
|
return node;
|
||||||
case Ast_Node_Type::Pair: {
|
case Lisp_Object_Type::Pair: {
|
||||||
Ast_Node* lispOperator;
|
Lisp_Object* lispOperator;
|
||||||
if (node->value.pair->first->type != Ast_Node_Type::CFunction &&
|
if (node->value.pair->first->type != Lisp_Object_Type::CFunction &&
|
||||||
node->value.pair->first->type != Ast_Node_Type::Function)
|
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) {
|
if (lispOperator->type == Lisp_Object_Type::CFunction) {
|
||||||
Ast_Node* 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 == 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) {
|
bool is_truthy (Lisp_Object* expression, Environment* env) {
|
||||||
Ast_Node* result;
|
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
@@ -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): {
|
case (Lisp_Object_Type::Pair): {
|
||||||
Ast_Node* head = node;
|
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): {
|
case (Lisp_Object_Type::Pair): {
|
||||||
Ast_Node* head = node;
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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(Lisp_Object_Type::Nil): return "nil";
|
||||||
case(Ast_Node_Type::T): return "t";
|
case(Lisp_Object_Type::T): return "t";
|
||||||
case(Ast_Node_Type::Number): return "number";
|
case(Lisp_Object_Type::Number): return "number";
|
||||||
case(Ast_Node_Type::String): return "string";
|
case(Lisp_Object_Type::String): return "string";
|
||||||
case(Ast_Node_Type::Symbol): return "symbol";
|
case(Lisp_Object_Type::Symbol): return "symbol";
|
||||||
case(Ast_Node_Type::Keyword): return "keyword";
|
case(Lisp_Object_Type::Keyword): return "keyword";
|
||||||
case(Ast_Node_Type::Function): return "function";
|
case(Lisp_Object_Type::Function): return "function";
|
||||||
case(Ast_Node_Type::CFunction): return "C-function";
|
case(Lisp_Object_Type::CFunction): return "C-function";
|
||||||
case(Ast_Node_Type::Pair): return "pair";
|
case(Lisp_Object_Type::Pair): return "pair";
|
||||||
}
|
}
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
@@ -47,12 +47,12 @@ struct String {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Pair {
|
struct Pair {
|
||||||
Ast_Node* first;
|
Lisp_Object* first;
|
||||||
Ast_Node* rest;
|
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
|
// value[Lisp_Object*]) here
|
||||||
Ast_Node_Array_List* keyword_keys;
|
Lisp_Object_Array_List* keyword_keys;
|
||||||
Ast_Node_Array_List* keyword_values;
|
Lisp_Object_Array_List* keyword_values;
|
||||||
};
|
};
|
||||||
|
|
||||||
Ast_Node* create_ast_node() {
|
Lisp_Object* create_lisp_object() {
|
||||||
Ast_Node* node = new(Ast_Node);
|
Lisp_Object* node = new(Lisp_Object);
|
||||||
node->sourceCodeLocation = nullptr;
|
node->sourceCodeLocation = nullptr;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* create_ast_node_nil() {
|
Lisp_Object* create_lisp_object_nil() {
|
||||||
Ast_Node* node = create_ast_node();
|
Lisp_Object* node = create_lisp_object();
|
||||||
node->type = Ast_Node_Type::Nil;
|
node->type = Lisp_Object_Type::Nil;
|
||||||
node->value.pair = nullptr;
|
node->value.pair = nullptr;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* create_ast_node_t() {
|
Lisp_Object* create_lisp_object_t() {
|
||||||
Ast_Node* node = create_ast_node();
|
Lisp_Object* node = create_lisp_object();
|
||||||
node->type = Ast_Node_Type::T;
|
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) {
|
Lisp_Object* create_lisp_object_number(double number) {
|
||||||
Ast_Node* node = create_ast_node();
|
Lisp_Object* node = create_lisp_object();
|
||||||
node->type = Ast_Node_Type::Number;
|
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) {
|
Lisp_Object* create_lisp_object_string(char* str, int length) {
|
||||||
Ast_Node* node = create_ast_node();
|
Lisp_Object* node = create_lisp_object();
|
||||||
node->type = Ast_Node_Type::String;
|
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) {
|
Lisp_Object* create_lisp_object_symbol(char* identifier) {
|
||||||
Ast_Node* node = create_ast_node();
|
Lisp_Object* node = create_lisp_object();
|
||||||
node->type = Ast_Node_Type::Symbol;
|
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) {
|
Lisp_Object* create_lisp_object_keyword(char* keyword) {
|
||||||
Ast_Node* node = create_ast_node();
|
Lisp_Object* node = create_lisp_object();
|
||||||
node->type = Ast_Node_Type::Keyword;
|
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) {
|
Lisp_Object* create_lisp_object_cfunction(std::function<Lisp_Object*(Lisp_Object*, Environment*)> function) {
|
||||||
Ast_Node* node = create_ast_node();
|
Lisp_Object* node = create_lisp_object();
|
||||||
node->type = Ast_Node_Type::CFunction;
|
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) {
|
Lisp_Object* create_lisp_object_pair(Lisp_Object* first, Lisp_Object* rest) {
|
||||||
Ast_Node* node = create_ast_node();
|
Lisp_Object* node = create_lisp_object();
|
||||||
node->type = Ast_Node_Type::Pair;
|
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) {
|
Lisp_Object* copy_lisp_object(Lisp_Object* n) {
|
||||||
Ast_Node* target = create_ast_node();
|
Lisp_Object* target = create_lisp_object();
|
||||||
*target = *n;
|
*target = *n;
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
+5
-5
@@ -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
@@ -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*);
|
Lisp_Object* eval_expr(Lisp_Object*, Environment*);
|
||||||
void parse_argument_list(Ast_Node*, Function*);
|
void parse_argument_list(Lisp_Object*, Function*);
|
||||||
int list_length(Ast_Node*);
|
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(
|
return create_lisp_object_pair(
|
||||||
create_ast_node_symbol("quote"),
|
create_lisp_object_symbol("quote"),
|
||||||
create_ast_node_pair(result, create_ast_node_nil()));
|
create_lisp_object_pair(result, create_lisp_object_nil()));
|
||||||
else if (quoteType == '`')
|
else if (quoteType == '`')
|
||||||
return create_ast_node_pair(
|
return create_lisp_object_pair(
|
||||||
create_ast_node_symbol("quasiquote"),
|
create_lisp_object_symbol("quasiquote"),
|
||||||
create_ast_node_pair(result, create_ast_node_nil()));
|
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(
|
return create_lisp_object_pair(
|
||||||
create_ast_node_symbol("unquote"),
|
create_lisp_object_symbol("unquote"),
|
||||||
create_ast_node_pair(result, create_ast_node_nil()));
|
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);
|
Lisp_Object* head = new(Lisp_Object);
|
||||||
head->type = Ast_Node_Type::Pair;
|
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(
|
function->body = create_lisp_object_pair(
|
||||||
create_ast_node_symbol("prog"),
|
create_lisp_object_symbol("prog"),
|
||||||
arguments);
|
arguments);
|
||||||
|
|
||||||
Ast_Node* macro = new(Ast_Node);
|
Lisp_Object* macro = new(Lisp_Object);
|
||||||
macro->type = Ast_Node_Type::Function;
|
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
@@ -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), \
|
Lisp_Object_Type_to_string(node->type), \
|
||||||
Ast_Node_Type_to_string(_type), char*, "%s"); \
|
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, Lisp_Object_Type::Pair);
|
||||||
assert_equal_type(operands->value.pair->first, Ast_Node_Type::Number);
|
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, Lisp_Object_Type::Pair);
|
||||||
assert_equal_type(operands->value.pair->first, Ast_Node_Type::Number);
|
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, Lisp_Object_Type::Pair);
|
||||||
assert_equal_type(operands->value.pair->first, Ast_Node_Type::String);
|
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, Lisp_Object_Type::Pair);
|
||||||
assert_equal_type(operands->value.pair->first, Ast_Node_Type::Keyword);
|
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, Lisp_Object_Type::Pair);
|
||||||
assert_equal_type(result->value.pair->first, Ast_Node_Type::Symbol);
|
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, Lisp_Object_Type::Pair);
|
||||||
assert_equal_type(result->value.pair->first, Ast_Node_Type::Symbol);
|
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, Lisp_Object_Type::Pair);
|
||||||
assert_equal_type(result->value.pair->first, Ast_Node_Type::Number);
|
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, Lisp_Object_Type::Pair);
|
||||||
assert_equal_type(result->value.pair->first, Ast_Node_Type::Symbol);
|
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, Lisp_Object_Type::Pair);
|
||||||
assert_equal_type(result->value.pair->first, Ast_Node_Type::Symbol);
|
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, Lisp_Object_Type::Pair);
|
||||||
assert_equal_type(result->value.pair->first, Ast_Node_Type::Pair);
|
assert_equal_type(result->value.pair->first, Lisp_Object_Type::Pair);
|
||||||
assert_equal_type(result->value.pair->first->value.pair->first, Ast_Node_Type::Symbol);
|
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);
|
Lisp_Object* expression = Parser::parse_single_expression(exp_string);
|
||||||
Ast_Node* result = eval_expr(expression, create_built_ins_environment());
|
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);
|
Lisp_Object* expression = Parser::parse_single_expression(exp_string);
|
||||||
Ast_Node* result = eval_expr(expression, create_built_ins_environment());
|
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);
|
Lisp_Object* expression = Parser::parse_single_expression(exp_string);
|
||||||
Ast_Node* result = eval_expr(expression, create_built_ins_environment());
|
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);
|
Lisp_Object* expression = Parser::parse_single_expression(exp_string);
|
||||||
Ast_Node* result = eval_expr(expression, create_built_ins_environment());
|
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);
|
Lisp_Object* expression = Parser::parse_single_expression(exp_string1);
|
||||||
Ast_Node* result = eval_expr(expression, create_built_ins_environment());
|
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);
|
Lisp_Object* expression = Parser::parse_single_expression(exp_string1);
|
||||||
Ast_Node* result = eval_expr(expression, create_built_ins_environment());
|
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);
|
Lisp_Object* expression = Parser::parse_single_expression(exp_string1);
|
||||||
Ast_Node* result = eval_expr(expression, create_built_ins_environment());
|
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);
|
Lisp_Object* expression = Parser::parse_single_expression(exp_string1);
|
||||||
Ast_Node* result = eval_expr(expression, create_built_ins_environment());
|
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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user