linux fixes
This commit is contained in:
@@ -2,5 +2,7 @@ clang src/main.c -g -o ./bin/slime --std=c99 || exit 1
|
|||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "--- Output Start ---"
|
echo "--- Output Start ---"
|
||||||
./bin/slime
|
pushd bin
|
||||||
|
./slime
|
||||||
|
popd
|
||||||
echo "--- Output End ---"
|
echo "--- Output End ---"
|
||||||
|
|||||||
+92
-91
@@ -2,39 +2,40 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env);
|
|||||||
|
|
||||||
bool ast_node_equal(Ast_Node* n1, Ast_Node* n2) {
|
bool ast_node_equal(Ast_Node* n1, Ast_Node* n2) {
|
||||||
if (n1 == n2)
|
if (n1 == n2)
|
||||||
return true;
|
return true;
|
||||||
if (n1->type != n2->type)
|
if (n1->type != n2->type)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
switch (n1->type) {
|
switch (n1->type) {
|
||||||
case Ast_Node_Type_Built_In_Function:
|
case Ast_Node_Type_Built_In_Function:
|
||||||
return n1->value.built_in_function->type
|
return n1->value.built_in_function->type
|
||||||
== n2->value.built_in_function->type;
|
== n2->value.built_in_function->type;
|
||||||
case Ast_Node_Type_Function:
|
case Ast_Node_Type_Function:
|
||||||
// if they have the same pointer, true is
|
// if they have the same pointer, true is
|
||||||
// returned a few lines above
|
// returned a few lines above
|
||||||
return false;
|
return false;
|
||||||
case Ast_Node_Type_Keyword:
|
case Ast_Node_Type_Keyword:
|
||||||
return string_equal(
|
return string_equal(
|
||||||
n1->value.keyword->identifier,
|
n1->value.keyword->identifier,
|
||||||
n2->value.keyword->identifier);
|
n2->value.keyword->identifier);
|
||||||
|
case Ast_Node_Type_T:
|
||||||
case Ast_Node_Type_Nil:
|
case Ast_Node_Type_Nil:
|
||||||
return true;
|
return true;
|
||||||
case Ast_Node_Type_Number:
|
case Ast_Node_Type_Number:
|
||||||
return
|
return
|
||||||
n1->value.number->value ==
|
n1->value.number->value ==
|
||||||
n2->value.number->value;
|
n2->value.number->value;
|
||||||
case Ast_Node_Type_Pair:
|
case Ast_Node_Type_Pair:
|
||||||
create_error(Error_Type_Not_Yet_Implemented, n1);
|
create_error(Error_Type_Not_Yet_Implemented, n1);
|
||||||
return false;
|
return false;
|
||||||
case Ast_Node_Type_String:
|
case Ast_Node_Type_String:
|
||||||
return string_equal(
|
return string_equal(
|
||||||
n1->value.string->value,
|
n1->value.string->value,
|
||||||
n2->value.string->value);
|
n2->value.string->value);
|
||||||
case Ast_Node_Type_Symbol:
|
case Ast_Node_Type_Symbol:
|
||||||
return string_equal(
|
return string_equal(
|
||||||
n1->value.symbol->identifier,
|
n1->value.symbol->identifier,
|
||||||
n2->value.symbol->identifier);
|
n2->value.symbol->identifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
// we should never reach here
|
// we should never reach here
|
||||||
@@ -43,32 +44,32 @@ bool ast_node_equal(Ast_Node* n1, Ast_Node* n2) {
|
|||||||
|
|
||||||
Ast_Node* built_in_equals(Ast_Node* operands) {
|
Ast_Node* built_in_equals(Ast_Node* operands) {
|
||||||
if (operands->type == Ast_Node_Type_Nil)
|
if (operands->type == Ast_Node_Type_Nil)
|
||||||
return create_ast_node_t();
|
return create_ast_node_t();
|
||||||
|
|
||||||
Ast_Node* first = operands->value.pair->first;
|
Ast_Node* first = operands->value.pair->first;
|
||||||
|
|
||||||
while (operands->type == Ast_Node_Type_Pair) {
|
while (operands->type == Ast_Node_Type_Pair) {
|
||||||
if (!ast_node_equal(operands->value.pair->first, first))
|
if (!ast_node_equal(operands->value.pair->first, first))
|
||||||
return create_ast_node_nil();
|
return create_ast_node_nil();
|
||||||
operands = operands->value.pair->rest;
|
operands = operands->value.pair->rest;
|
||||||
}
|
}
|
||||||
|
|
||||||
return create_ast_node_t();
|
return create_ast_node_t();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* built_in_greater(Ast_Node* operands) {
|
Ast_Node* built_in_greater(Ast_Node* operands) {
|
||||||
double last_number = strtod("Inf", NULL);
|
double last_number = strtod("Inf", NULL);
|
||||||
|
|
||||||
while (operands->type == Ast_Node_Type_Pair) {
|
while (operands->type == Ast_Node_Type_Pair) {
|
||||||
try {
|
try {
|
||||||
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (operands->value.pair->first->value.number->value >= last_number)
|
if (operands->value.pair->first->value.number->value >= last_number)
|
||||||
return create_ast_node_nil();
|
return create_ast_node_nil();
|
||||||
|
|
||||||
last_number = operands->value.pair->first->value.number->value;
|
last_number = operands->value.pair->first->value.number->value;
|
||||||
operands = operands->value.pair->rest;
|
operands = operands->value.pair->rest;
|
||||||
}
|
}
|
||||||
|
|
||||||
return create_ast_node_t();
|
return create_ast_node_t();
|
||||||
@@ -78,15 +79,15 @@ Ast_Node* built_in_greater_equal(Ast_Node* operands) {
|
|||||||
double last_number = strtod("Inf", NULL);
|
double last_number = strtod("Inf", NULL);
|
||||||
|
|
||||||
while (operands->type == Ast_Node_Type_Pair) {
|
while (operands->type == Ast_Node_Type_Pair) {
|
||||||
try {
|
try {
|
||||||
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (operands->value.pair->first->value.number->value > last_number)
|
if (operands->value.pair->first->value.number->value > last_number)
|
||||||
return create_ast_node_nil();
|
return create_ast_node_nil();
|
||||||
|
|
||||||
last_number = operands->value.pair->first->value.number->value;
|
last_number = operands->value.pair->first->value.number->value;
|
||||||
operands = operands->value.pair->rest;
|
operands = operands->value.pair->rest;
|
||||||
}
|
}
|
||||||
|
|
||||||
return create_ast_node_t();
|
return create_ast_node_t();
|
||||||
@@ -96,15 +97,15 @@ Ast_Node* built_in_less(Ast_Node* operands) {
|
|||||||
double last_number = strtod("-Inf", NULL);
|
double last_number = strtod("-Inf", NULL);
|
||||||
|
|
||||||
while (operands->type == Ast_Node_Type_Pair) {
|
while (operands->type == Ast_Node_Type_Pair) {
|
||||||
try {
|
try {
|
||||||
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (operands->value.pair->first->value.number->value <= last_number)
|
if (operands->value.pair->first->value.number->value <= last_number)
|
||||||
return create_ast_node_nil();
|
return create_ast_node_nil();
|
||||||
|
|
||||||
last_number = operands->value.pair->first->value.number->value;
|
last_number = operands->value.pair->first->value.number->value;
|
||||||
operands = operands->value.pair->rest;
|
operands = operands->value.pair->rest;
|
||||||
}
|
}
|
||||||
|
|
||||||
return create_ast_node_t();
|
return create_ast_node_t();
|
||||||
@@ -114,15 +115,15 @@ Ast_Node* built_in_less_equal(Ast_Node* operands) {
|
|||||||
double last_number = strtod("-Inf", NULL);
|
double last_number = strtod("-Inf", NULL);
|
||||||
|
|
||||||
while (operands->type == Ast_Node_Type_Pair) {
|
while (operands->type == Ast_Node_Type_Pair) {
|
||||||
try {
|
try {
|
||||||
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (operands->value.pair->first->value.number->value < last_number)
|
if (operands->value.pair->first->value.number->value < last_number)
|
||||||
return create_ast_node_nil();
|
return create_ast_node_nil();
|
||||||
|
|
||||||
last_number = operands->value.pair->first->value.number->value;
|
last_number = operands->value.pair->first->value.number->value;
|
||||||
operands = operands->value.pair->rest;
|
operands = operands->value.pair->rest;
|
||||||
}
|
}
|
||||||
|
|
||||||
return create_ast_node_t();
|
return create_ast_node_t();
|
||||||
@@ -131,11 +132,11 @@ Ast_Node* built_in_less_equal(Ast_Node* operands) {
|
|||||||
Ast_Node* built_in_add(Ast_Node* operands) {
|
Ast_Node* built_in_add(Ast_Node* operands) {
|
||||||
double sum = 0;
|
double sum = 0;
|
||||||
while (operands->type == Ast_Node_Type_Pair) {
|
while (operands->type == Ast_Node_Type_Pair) {
|
||||||
try {
|
try {
|
||||||
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
||||||
}
|
}
|
||||||
sum += operands->value.pair->first->value.number->value;
|
sum += operands->value.pair->first->value.number->value;
|
||||||
operands = operands->value.pair->rest;
|
operands = operands->value.pair->rest;
|
||||||
}
|
}
|
||||||
|
|
||||||
return create_ast_node_number(sum);
|
return create_ast_node_number(sum);
|
||||||
@@ -143,54 +144,54 @@ Ast_Node* built_in_add(Ast_Node* operands) {
|
|||||||
|
|
||||||
Ast_Node* built_in_substract(Ast_Node* operands) {
|
Ast_Node* built_in_substract(Ast_Node* operands) {
|
||||||
try {
|
try {
|
||||||
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
||||||
}
|
}
|
||||||
double difference = operands->value.pair->first->value.number->value;
|
double difference = operands->value.pair->first->value.number->value;
|
||||||
|
|
||||||
operands = operands->value.pair->rest;
|
operands = operands->value.pair->rest;
|
||||||
while (operands->type == Ast_Node_Type_Pair) {
|
while (operands->type == Ast_Node_Type_Pair) {
|
||||||
try {
|
try {
|
||||||
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
||||||
}
|
}
|
||||||
|
|
||||||
difference -= operands->value.pair->first->value.number->value;
|
difference -= operands->value.pair->first->value.number->value;
|
||||||
operands = operands->value.pair->rest;
|
operands = operands->value.pair->rest;
|
||||||
}
|
}
|
||||||
return create_ast_node_number(difference);
|
return create_ast_node_number(difference);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* built_in_multiply(Ast_Node* operands) {
|
Ast_Node* built_in_multiply(Ast_Node* operands) {
|
||||||
try {
|
try {
|
||||||
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
||||||
}
|
}
|
||||||
double product = operands->value.pair->first->value.number->value;
|
double product = operands->value.pair->first->value.number->value;
|
||||||
|
|
||||||
operands = operands->value.pair->rest;
|
operands = operands->value.pair->rest;
|
||||||
while (operands->type == Ast_Node_Type_Pair) {
|
while (operands->type == Ast_Node_Type_Pair) {
|
||||||
try {
|
try {
|
||||||
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
||||||
}
|
}
|
||||||
|
|
||||||
product *= operands->value.pair->first->value.number->value;
|
product *= operands->value.pair->first->value.number->value;
|
||||||
operands = operands->value.pair->rest;
|
operands = operands->value.pair->rest;
|
||||||
}
|
}
|
||||||
return create_ast_node_number(product);
|
return create_ast_node_number(product);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* built_in_divide(Ast_Node* operands) {
|
Ast_Node* built_in_divide(Ast_Node* operands) {
|
||||||
try {
|
try {
|
||||||
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
||||||
}
|
}
|
||||||
double quotient = operands->value.pair->first->value.number->value;
|
double quotient = operands->value.pair->first->value.number->value;
|
||||||
|
|
||||||
operands = operands->value.pair->rest;
|
operands = operands->value.pair->rest;
|
||||||
while (operands->type == Ast_Node_Type_Pair) {
|
while (operands->type == Ast_Node_Type_Pair) {
|
||||||
try {
|
try {
|
||||||
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number);
|
||||||
}
|
}
|
||||||
|
|
||||||
quotient /= operands->value.pair->first->value.number->value;
|
quotient /= operands->value.pair->first->value.number->value;
|
||||||
operands = operands->value.pair->rest;
|
operands = operands->value.pair->rest;
|
||||||
}
|
}
|
||||||
return create_ast_node_number(quotient);
|
return create_ast_node_number(quotient);
|
||||||
}
|
}
|
||||||
@@ -199,19 +200,19 @@ Ast_Node* built_in_divide(Ast_Node* operands) {
|
|||||||
Ast_Node* built_in_load(char* file_name, Environment* env) {
|
Ast_Node* built_in_load(char* file_name, Environment* env) {
|
||||||
char* file_content = read_entire_file(file_name);
|
char* file_content = read_entire_file(file_name);
|
||||||
if (file_content) {
|
if (file_content) {
|
||||||
Ast_Node* result = create_ast_node_nil();
|
Ast_Node* result = create_ast_node_nil();
|
||||||
Ast_Node_Array_List* program;
|
Ast_Node_Array_List* program;
|
||||||
try {
|
try {
|
||||||
program = parse_program(file_content);
|
program = parse_program(file_content);
|
||||||
}
|
}
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
create_error(Error_Type_Unknown_Error, create_ast_node_nil());
|
create_error(Error_Type_Unknown_Error, create_ast_node_nil());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ typedef enum {
|
|||||||
|
|
||||||
struct Environment {
|
struct Environment {
|
||||||
struct Environment* parent;
|
struct Environment* parent;
|
||||||
Environment_Type type;
|
Environment_Type type;
|
||||||
|
|
||||||
int capacity;
|
int capacity;
|
||||||
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;
|
Ast_Node** values;
|
||||||
@@ -22,12 +22,12 @@ Environment* create_child_environment(Environment* parent, Environment_Type type
|
|||||||
|
|
||||||
int start_capacity = 16;
|
int start_capacity = 16;
|
||||||
|
|
||||||
env->type = type;
|
env->type = type;
|
||||||
env->parent = parent;
|
env->parent = 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 = (Ast_Node**)malloc(start_capacity * sizeof(Ast_Node*));
|
||||||
|
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
@@ -38,12 +38,12 @@ Environment* create_empty_environment(Environment_Type type) {
|
|||||||
|
|
||||||
void define_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) {
|
void define_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) {
|
||||||
if (env->type == Environment_Type_Macro) {
|
if (env->type == Environment_Type_Macro) {
|
||||||
// NOTE(Felix): we know we have a parent because every
|
// NOTE(Felix): we know we have a parent because every
|
||||||
// environment has a parent except the top level environment.
|
// environment has a parent except the top level environment.
|
||||||
// However the top level environment is not a let-environment,
|
// However the top level environment is not a let-environment,
|
||||||
// so we would not land here
|
// so we would not land here
|
||||||
define_symbol(symbol, value, env->parent);
|
define_symbol(symbol, value, env->parent);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE(Felix): right now we are simply adding the symol at the
|
// NOTE(Felix): right now we are simply adding the symol at the
|
||||||
@@ -52,9 +52,9 @@ void define_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) {
|
|||||||
// latest defined one first, but a bit messy. Later we should use
|
// latest defined one first, but a bit messy. Later we should use
|
||||||
// a hashmap here. @refactor
|
// a hashmap here. @refactor
|
||||||
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 = (Ast_Node**)realloc(env->values, env->capacity * sizeof(Ast_Node*));
|
||||||
}
|
}
|
||||||
|
|
||||||
env->keys [env->next_index] = symbol->value.symbol->identifier;
|
env->keys [env->next_index] = symbol->value.symbol->identifier;
|
||||||
@@ -63,9 +63,9 @@ void define_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void define_macro_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) {
|
void define_macro_symbol(Ast_Node* symbol, Ast_Node* value, Environment* env) {
|
||||||
if (!env->type == Environment_Type_Macro) {
|
if (env->type != Environment_Type_Macro) {
|
||||||
create_error(Error_Type_Unknown_Error, symbol);
|
create_error(Error_Type_Unknown_Error, symbol);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
env->type = Environment_Type_Lambda;
|
env->type = Environment_Type_Lambda;
|
||||||
@@ -77,19 +77,19 @@ void print_environment(Environment* env);
|
|||||||
|
|
||||||
Ast_Node* lookup_symbol_in_this_envt(Symbol* sym, Environment* env) {
|
Ast_Node* 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_from_lambda_env(Symbol* sym, Environment* env) {
|
Ast_Node* lookup_symbol_from_lambda_env(Symbol* sym, Environment* env) {
|
||||||
Ast_Node* result;
|
Ast_Node* result;
|
||||||
do {
|
do {
|
||||||
if (env->type != Environment_Type_Lambda) {
|
if (env->type != Environment_Type_Lambda) {
|
||||||
result = lookup_symbol_in_this_envt(sym, env);
|
result = lookup_symbol_in_this_envt(sym, env);
|
||||||
if (result) return result;
|
if (result) return result;
|
||||||
}
|
}
|
||||||
env = env->parent;
|
env = env->parent;
|
||||||
} while (env);
|
} while (env);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -97,22 +97,22 @@ Ast_Node* lookup_symbol_from_lambda_env(Symbol* sym, Environment* env) {
|
|||||||
Ast_Node* lookup_symbol_from_let_or_macro_env(Symbol* sym, Environment* env) {
|
Ast_Node* lookup_symbol_from_let_or_macro_env(Symbol* sym, Environment* env) {
|
||||||
Ast_Node* result;
|
Ast_Node* result;
|
||||||
do {
|
do {
|
||||||
result = lookup_symbol_in_this_envt(sym, env);
|
result = lookup_symbol_in_this_envt(sym, env);
|
||||||
if (result) return result;
|
if (result) return result;
|
||||||
if (env->type == Environment_Type_Lambda)
|
if (env->type == Environment_Type_Lambda)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
env = env->parent;
|
env = env->parent;
|
||||||
} while (env);
|
} while (env);
|
||||||
|
|
||||||
if (env) {
|
if (env) {
|
||||||
do {
|
do {
|
||||||
if (env->type != Environment_Type_Lambda) {
|
if (env->type != Environment_Type_Lambda) {
|
||||||
result = lookup_symbol_in_this_envt(sym, env);
|
result = lookup_symbol_in_this_envt(sym, env);
|
||||||
if (result) return result;
|
if (result) return result;
|
||||||
}
|
}
|
||||||
env = env->parent;
|
env = env->parent;
|
||||||
} while (env);
|
} while (env);
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -123,29 +123,29 @@ Ast_Node* lookup_symbol(Symbol* sym, Environment* env) {
|
|||||||
Ast_Node* result;
|
Ast_Node* 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;
|
||||||
|
|
||||||
if (env->parent) {
|
if (env->parent) {
|
||||||
if (env->type == Environment_Type_Lambda) {
|
if (env->type == Environment_Type_Lambda) {
|
||||||
result = lookup_symbol_from_lambda_env(sym, env->parent);
|
result = lookup_symbol_from_lambda_env(sym, env->parent);
|
||||||
} else {
|
} else {
|
||||||
result = lookup_symbol_from_let_or_macro_env(sym, env->parent);
|
result = lookup_symbol_from_let_or_macro_env(sym, env->parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string_equal(sym->identifier, "nil")) {
|
if (string_equal(sym->identifier, "nil")) {
|
||||||
return create_ast_node_nil();
|
return create_ast_node_nil();
|
||||||
}
|
}
|
||||||
if (string_equal(sym->identifier, "t")) {
|
if (string_equal(sym->identifier, "t")) {
|
||||||
return create_ast_node_t();
|
return create_ast_node_t();
|
||||||
}
|
}
|
||||||
|
|
||||||
result = create_ast_node_built_in_function(sym->identifier);
|
result = create_ast_node_built_in_function(sym->identifier);
|
||||||
if (result)
|
if (result)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
create_error(Error_Type_Symbol_Not_Defined, create_ast_node_nil());
|
create_error(Error_Type_Symbol_Not_Defined, create_ast_node_nil());
|
||||||
/* printf("%s\n", sym->identifier); */
|
/* printf("%s\n", sym->identifier); */
|
||||||
@@ -153,28 +153,28 @@ Ast_Node* lookup_symbol(Symbol* sym, Environment* env) {
|
|||||||
}
|
}
|
||||||
void print_indent(int indent) {
|
void print_indent(int indent) {
|
||||||
for (int i = 0; i < indent; ++i) {
|
for (int i = 0; i < indent; ++i) {
|
||||||
printf(" ");
|
printf(" ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_environment_indent(Environment* env, int indent) {
|
void print_environment_indent(Environment* env, int indent) {
|
||||||
for (int i = 0; i < env->next_index; ++i) {
|
for (int i = 0; i < env->next_index; ++i) {
|
||||||
print_indent(indent);
|
print_indent(indent);
|
||||||
printf("%s -> ", env->keys[i]);
|
printf("%s -> ", env->keys[i]);
|
||||||
print(env->values[i]);
|
print(env->values[i]);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
if (env->parent) {
|
if (env->parent) {
|
||||||
print_indent(indent);
|
print_indent(indent);
|
||||||
printf("parent");
|
printf("parent");
|
||||||
if (env->parent->type == Environment_Type_Lambda)
|
if (env->parent->type == Environment_Type_Lambda)
|
||||||
printf(" (lambda)");
|
printf(" (lambda)");
|
||||||
else if (env->parent->type == Environment_Type_Macro)
|
else if (env->parent->type == Environment_Type_Macro)
|
||||||
printf(" (macro)");
|
printf(" (macro)");
|
||||||
else if (env->parent->type == Environment_Type_Let)
|
else if (env->parent->type == Environment_Type_Let)
|
||||||
printf(" (let)");
|
printf(" (let)");
|
||||||
printf(":\n");
|
printf(":\n");
|
||||||
print_environment_indent(env->parent, indent+4);
|
print_environment_indent(env->parent, indent+4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+15
-13
@@ -139,20 +139,21 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
eval_time:
|
eval_time: {
|
||||||
Ast_Node* result;
|
Ast_Node* result;
|
||||||
|
|
||||||
// don't have to check every time if it is macro environment or
|
// don't have to check every time if it is macro environment or
|
||||||
// not
|
// not
|
||||||
if (function->is_macro)
|
if (function->is_macro)
|
||||||
new_env->type = Environment_Type_Macro;
|
new_env->type = Environment_Type_Macro;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
result = eval_expr(function->body, new_env);
|
result = eval_expr(function->body, new_env);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(new_env);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(new_env);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -433,8 +434,8 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
|
|||||||
// just make sure type was not redefined and
|
// just make sure type was not redefined and
|
||||||
// returns something that is not a keyword
|
// returns something that is not a keyword
|
||||||
if (type->type == Ast_Node_Type_Keyword &&
|
if (type->type == Ast_Node_Type_Keyword &&
|
||||||
string_equal(type->value.keyword->identifier, "dynamic-function") ||
|
(string_equal(type->value.keyword->identifier, "dynamic-function") ||
|
||||||
string_equal(type->value.keyword->identifier, "dynamic-macro"))
|
string_equal(type->value.keyword->identifier, "dynamic-macro")))
|
||||||
{
|
{
|
||||||
Ast_Node* fun = eval_expr(arguments->value.pair->first, env);
|
Ast_Node* fun = eval_expr(arguments->value.pair->first, env);
|
||||||
printf("\nMacro? %s\n", (fun->value.function->is_macro) ? "yes" : "no");
|
printf("\nMacro? %s\n", (fun->value.function->is_macro) ? "yes" : "no");
|
||||||
@@ -866,6 +867,7 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
|
|||||||
}
|
}
|
||||||
case Ast_Node_Type_Keyword: return create_ast_node_keyword("keyword");
|
case Ast_Node_Type_Keyword: return create_ast_node_keyword("keyword");
|
||||||
case Ast_Node_Type_Nil: return create_ast_node_keyword("nil");
|
case Ast_Node_Type_Nil: return create_ast_node_keyword("nil");
|
||||||
|
case Ast_Node_Type_T: return create_ast_node_keyword("t");
|
||||||
case Ast_Node_Type_Number: return create_ast_node_keyword("number");
|
case Ast_Node_Type_Number: return create_ast_node_keyword("number");
|
||||||
case Ast_Node_Type_Pair: return create_ast_node_keyword("pair");
|
case Ast_Node_Type_Pair: return create_ast_node_keyword("pair");
|
||||||
case Ast_Node_Type_String: return create_ast_node_keyword("string");
|
case Ast_Node_Type_String: return create_ast_node_keyword("string");
|
||||||
|
|||||||
Reference in New Issue
Block a user