|
|
|
@@ -2,39 +2,40 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env); |
|
|
|
|
|
|
|
bool ast_node_equal(Ast_Node* n1, Ast_Node* n2) { |
|
|
|
if (n1 == n2) |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
if (n1->type != n2->type) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
switch (n1->type) { |
|
|
|
case Ast_Node_Type_Built_In_Function: |
|
|
|
return n1->value.built_in_function->type |
|
|
|
== n2->value.built_in_function->type; |
|
|
|
return n1->value.built_in_function->type |
|
|
|
== n2->value.built_in_function->type; |
|
|
|
case Ast_Node_Type_Function: |
|
|
|
// if they have the same pointer, true is |
|
|
|
// returned a few lines above |
|
|
|
return false; |
|
|
|
// if they have the same pointer, true is |
|
|
|
// returned a few lines above |
|
|
|
return false; |
|
|
|
case Ast_Node_Type_Keyword: |
|
|
|
return string_equal( |
|
|
|
n1->value.keyword->identifier, |
|
|
|
n2->value.keyword->identifier); |
|
|
|
return string_equal( |
|
|
|
n1->value.keyword->identifier, |
|
|
|
n2->value.keyword->identifier); |
|
|
|
case Ast_Node_Type_T: |
|
|
|
case Ast_Node_Type_Nil: |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
case Ast_Node_Type_Number: |
|
|
|
return |
|
|
|
n1->value.number->value == |
|
|
|
n2->value.number->value; |
|
|
|
return |
|
|
|
n1->value.number->value == |
|
|
|
n2->value.number->value; |
|
|
|
case Ast_Node_Type_Pair: |
|
|
|
create_error(Error_Type_Not_Yet_Implemented, n1); |
|
|
|
return false; |
|
|
|
create_error(Error_Type_Not_Yet_Implemented, n1); |
|
|
|
return false; |
|
|
|
case Ast_Node_Type_String: |
|
|
|
return string_equal( |
|
|
|
n1->value.string->value, |
|
|
|
n2->value.string->value); |
|
|
|
return string_equal( |
|
|
|
n1->value.string->value, |
|
|
|
n2->value.string->value); |
|
|
|
case Ast_Node_Type_Symbol: |
|
|
|
return string_equal( |
|
|
|
n1->value.symbol->identifier, |
|
|
|
n2->value.symbol->identifier); |
|
|
|
return string_equal( |
|
|
|
n1->value.symbol->identifier, |
|
|
|
n2->value.symbol->identifier); |
|
|
|
} |
|
|
|
|
|
|
|
// 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) { |
|
|
|
if (operands->type == Ast_Node_Type_Nil) |
|
|
|
return create_ast_node_t(); |
|
|
|
return create_ast_node_t(); |
|
|
|
|
|
|
|
Ast_Node* first = operands->value.pair->first; |
|
|
|
|
|
|
|
while (operands->type == Ast_Node_Type_Pair) { |
|
|
|
if (!ast_node_equal(operands->value.pair->first, first)) |
|
|
|
return create_ast_node_nil(); |
|
|
|
operands = operands->value.pair->rest; |
|
|
|
if (!ast_node_equal(operands->value.pair->first, first)) |
|
|
|
return create_ast_node_nil(); |
|
|
|
operands = operands->value.pair->rest; |
|
|
|
} |
|
|
|
|
|
|
|
return create_ast_node_t(); |
|
|
|
return create_ast_node_t(); |
|
|
|
} |
|
|
|
|
|
|
|
Ast_Node* built_in_greater(Ast_Node* operands) { |
|
|
|
double last_number = strtod("Inf", NULL); |
|
|
|
|
|
|
|
while (operands->type == Ast_Node_Type_Pair) { |
|
|
|
try { |
|
|
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number); |
|
|
|
} |
|
|
|
try { |
|
|
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number); |
|
|
|
} |
|
|
|
|
|
|
|
if (operands->value.pair->first->value.number->value >= last_number) |
|
|
|
return create_ast_node_nil(); |
|
|
|
if (operands->value.pair->first->value.number->value >= last_number) |
|
|
|
return create_ast_node_nil(); |
|
|
|
|
|
|
|
last_number = operands->value.pair->first->value.number->value; |
|
|
|
operands = operands->value.pair->rest; |
|
|
|
last_number = operands->value.pair->first->value.number->value; |
|
|
|
operands = operands->value.pair->rest; |
|
|
|
} |
|
|
|
|
|
|
|
return create_ast_node_t(); |
|
|
|
@@ -78,15 +79,15 @@ Ast_Node* built_in_greater_equal(Ast_Node* operands) { |
|
|
|
double last_number = strtod("Inf", NULL); |
|
|
|
|
|
|
|
while (operands->type == Ast_Node_Type_Pair) { |
|
|
|
try { |
|
|
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number); |
|
|
|
} |
|
|
|
try { |
|
|
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number); |
|
|
|
} |
|
|
|
|
|
|
|
if (operands->value.pair->first->value.number->value > last_number) |
|
|
|
return create_ast_node_nil(); |
|
|
|
if (operands->value.pair->first->value.number->value > last_number) |
|
|
|
return create_ast_node_nil(); |
|
|
|
|
|
|
|
last_number = operands->value.pair->first->value.number->value; |
|
|
|
operands = operands->value.pair->rest; |
|
|
|
last_number = operands->value.pair->first->value.number->value; |
|
|
|
operands = operands->value.pair->rest; |
|
|
|
} |
|
|
|
|
|
|
|
return create_ast_node_t(); |
|
|
|
@@ -96,15 +97,15 @@ Ast_Node* built_in_less(Ast_Node* operands) { |
|
|
|
double last_number = strtod("-Inf", NULL); |
|
|
|
|
|
|
|
while (operands->type == Ast_Node_Type_Pair) { |
|
|
|
try { |
|
|
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number); |
|
|
|
} |
|
|
|
try { |
|
|
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number); |
|
|
|
} |
|
|
|
|
|
|
|
if (operands->value.pair->first->value.number->value <= last_number) |
|
|
|
return create_ast_node_nil(); |
|
|
|
if (operands->value.pair->first->value.number->value <= last_number) |
|
|
|
return create_ast_node_nil(); |
|
|
|
|
|
|
|
last_number = operands->value.pair->first->value.number->value; |
|
|
|
operands = operands->value.pair->rest; |
|
|
|
last_number = operands->value.pair->first->value.number->value; |
|
|
|
operands = operands->value.pair->rest; |
|
|
|
} |
|
|
|
|
|
|
|
return create_ast_node_t(); |
|
|
|
@@ -114,15 +115,15 @@ Ast_Node* built_in_less_equal(Ast_Node* operands) { |
|
|
|
double last_number = strtod("-Inf", NULL); |
|
|
|
|
|
|
|
while (operands->type == Ast_Node_Type_Pair) { |
|
|
|
try { |
|
|
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number); |
|
|
|
} |
|
|
|
try { |
|
|
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number); |
|
|
|
} |
|
|
|
|
|
|
|
if (operands->value.pair->first->value.number->value < last_number) |
|
|
|
return create_ast_node_nil(); |
|
|
|
if (operands->value.pair->first->value.number->value < last_number) |
|
|
|
return create_ast_node_nil(); |
|
|
|
|
|
|
|
last_number = operands->value.pair->first->value.number->value; |
|
|
|
operands = operands->value.pair->rest; |
|
|
|
last_number = operands->value.pair->first->value.number->value; |
|
|
|
operands = operands->value.pair->rest; |
|
|
|
} |
|
|
|
|
|
|
|
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) { |
|
|
|
double sum = 0; |
|
|
|
while (operands->type == Ast_Node_Type_Pair) { |
|
|
|
try { |
|
|
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number); |
|
|
|
} |
|
|
|
sum += operands->value.pair->first->value.number->value; |
|
|
|
operands = operands->value.pair->rest; |
|
|
|
try { |
|
|
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number); |
|
|
|
} |
|
|
|
sum += operands->value.pair->first->value.number->value; |
|
|
|
operands = operands->value.pair->rest; |
|
|
|
} |
|
|
|
|
|
|
|
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) { |
|
|
|
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; |
|
|
|
|
|
|
|
operands = operands->value.pair->rest; |
|
|
|
while (operands->type == Ast_Node_Type_Pair) { |
|
|
|
try { |
|
|
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number); |
|
|
|
} |
|
|
|
try { |
|
|
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number); |
|
|
|
} |
|
|
|
|
|
|
|
difference -= operands->value.pair->first->value.number->value; |
|
|
|
operands = operands->value.pair->rest; |
|
|
|
difference -= operands->value.pair->first->value.number->value; |
|
|
|
operands = operands->value.pair->rest; |
|
|
|
} |
|
|
|
return create_ast_node_number(difference); |
|
|
|
} |
|
|
|
|
|
|
|
Ast_Node* built_in_multiply(Ast_Node* operands) { |
|
|
|
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; |
|
|
|
|
|
|
|
operands = operands->value.pair->rest; |
|
|
|
while (operands->type == Ast_Node_Type_Pair) { |
|
|
|
try { |
|
|
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number); |
|
|
|
} |
|
|
|
try { |
|
|
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number); |
|
|
|
} |
|
|
|
|
|
|
|
product *= operands->value.pair->first->value.number->value; |
|
|
|
operands = operands->value.pair->rest; |
|
|
|
product *= operands->value.pair->first->value.number->value; |
|
|
|
operands = operands->value.pair->rest; |
|
|
|
} |
|
|
|
return create_ast_node_number(product); |
|
|
|
} |
|
|
|
|
|
|
|
Ast_Node* built_in_divide(Ast_Node* operands) { |
|
|
|
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; |
|
|
|
|
|
|
|
operands = operands->value.pair->rest; |
|
|
|
while (operands->type == Ast_Node_Type_Pair) { |
|
|
|
try { |
|
|
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number); |
|
|
|
} |
|
|
|
try { |
|
|
|
assert_type(operands->value.pair->first, Ast_Node_Type_Number); |
|
|
|
} |
|
|
|
|
|
|
|
quotient /= operands->value.pair->first->value.number->value; |
|
|
|
operands = operands->value.pair->rest; |
|
|
|
quotient /= operands->value.pair->first->value.number->value; |
|
|
|
operands = operands->value.pair->rest; |
|
|
|
} |
|
|
|
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) { |
|
|
|
char* file_content = read_entire_file(file_name); |
|
|
|
if (file_content) { |
|
|
|
Ast_Node* result = create_ast_node_nil(); |
|
|
|
Ast_Node_Array_List* program; |
|
|
|
try { |
|
|
|
program = parse_program(file_content); |
|
|
|
} |
|
|
|
for (int i = 0; i < program->next_index; ++i) { |
|
|
|
try { |
|
|
|
result = eval_expr(program->data[i], env); |
|
|
|
} |
|
|
|
} |
|
|
|
return result; |
|
|
|
Ast_Node* result = create_ast_node_nil(); |
|
|
|
Ast_Node_Array_List* program; |
|
|
|
try { |
|
|
|
program = parse_program(file_content); |
|
|
|
} |
|
|
|
for (int i = 0; i < program->next_index; ++i) { |
|
|
|
try { |
|
|
|
result = eval_expr(program->data[i], env); |
|
|
|
} |
|
|
|
} |
|
|
|
return result; |
|
|
|
} else { |
|
|
|
create_error(Error_Type_Unknown_Error, create_ast_node_nil()); |
|
|
|
return nullptr; |
|
|
|
create_error(Error_Type_Unknown_Error, create_ast_node_nil()); |
|
|
|
return nullptr; |
|
|
|
} |
|
|
|
} |