converted all typedefs to c++ types and enums to enum structs
This commit is contained in:
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
void assert_type (Ast_Node* node, Ast_Node_Type type) {
|
void assert_type (Ast_Node* node, Ast_Node_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;
|
||||||
create_error(Error_Type_Type_Missmatch, node->sourceCodeLocation);
|
create_error(Error_Type::Type_Missmatch, node->sourceCodeLocation);
|
||||||
}
|
}
|
||||||
|
|||||||
+49
-52
@@ -1,73 +1,71 @@
|
|||||||
struct Ast_Node;
|
struct Ast_Node;
|
||||||
define_array_list(struct Ast_Node*, Ast_Node);
|
define_array_list(struct Ast_Node*, Ast_Node);
|
||||||
|
|
||||||
typedef enum {
|
enum struct Ast_Node_Type {
|
||||||
Ast_Node_Type_Nil,
|
Nil,
|
||||||
Ast_Node_Type_T,
|
T,
|
||||||
|
Symbol,
|
||||||
Ast_Node_Type_Symbol,
|
Keyword,
|
||||||
Ast_Node_Type_Keyword,
|
Number,
|
||||||
Ast_Node_Type_Number,
|
String,
|
||||||
Ast_Node_Type_String,
|
Pair,
|
||||||
|
Function,
|
||||||
Ast_Node_Type_Pair,
|
CFunction,
|
||||||
Ast_Node_Type_Function,
|
};
|
||||||
Ast_Node_Type_CFunction,
|
|
||||||
} Ast_Node_Type;
|
|
||||||
|
|
||||||
char* Ast_Node_Type_to_string(Ast_Node_Type type) {
|
char* Ast_Node_Type_to_string(Ast_Node_Type type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case(Ast_Node_Type_Nil): return "nil";
|
case(Ast_Node_Type::Nil): return "nil";
|
||||||
case(Ast_Node_Type_T): return "t";
|
case(Ast_Node_Type::T): return "t";
|
||||||
case(Ast_Node_Type_Number): return "number";
|
case(Ast_Node_Type::Number): return "number";
|
||||||
case(Ast_Node_Type_String): return "string";
|
case(Ast_Node_Type::String): return "string";
|
||||||
case(Ast_Node_Type_Symbol): return "symbol";
|
case(Ast_Node_Type::Symbol): return "symbol";
|
||||||
case(Ast_Node_Type_Keyword): return "keyword";
|
case(Ast_Node_Type::Keyword): return "keyword";
|
||||||
case(Ast_Node_Type_Function): return "function";
|
case(Ast_Node_Type::Function): return "function";
|
||||||
case(Ast_Node_Type_CFunction): return "C-function";
|
case(Ast_Node_Type::CFunction): return "C-function";
|
||||||
case(Ast_Node_Type_Pair): return "pair";
|
case(Ast_Node_Type::Pair): return "pair";
|
||||||
}
|
}
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
struct Symbol {
|
||||||
char* identifier;
|
char* identifier;
|
||||||
} Symbol;
|
};
|
||||||
|
|
||||||
typedef struct {
|
struct Keyword {
|
||||||
char* identifier;
|
char* identifier;
|
||||||
} Keyword;
|
};
|
||||||
|
|
||||||
typedef struct {
|
struct Number {
|
||||||
double value;
|
double value;
|
||||||
} Number;
|
};
|
||||||
|
|
||||||
typedef struct {
|
struct String {
|
||||||
char* value;
|
char* value;
|
||||||
int length;
|
int length;
|
||||||
} String;
|
};
|
||||||
|
|
||||||
typedef struct {
|
struct Pair {
|
||||||
struct Ast_Node* first;
|
struct Ast_Node* first;
|
||||||
struct Ast_Node* rest;
|
struct Ast_Node* rest;
|
||||||
} Pair;
|
};
|
||||||
|
|
||||||
typedef struct {
|
struct Positional_Arguments {
|
||||||
// TODO(Felix) use Ast_Node_symbols here instead, so we don't have
|
// TODO(Felix) use Ast_Node_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;
|
||||||
int length;
|
int length;
|
||||||
} Positional_Arguments;
|
};
|
||||||
|
|
||||||
typedef struct {
|
struct Keyword_Arguments {
|
||||||
char** identifiers;
|
char** identifiers;
|
||||||
// values[i] will be nullptr if no defalut value was declared for
|
// values[i] will be nullptr if no defalut value was declared for
|
||||||
// key identifiers[i]
|
// key identifiers[i]
|
||||||
Ast_Node_Array_List* values;
|
Ast_Node_Array_List* values;
|
||||||
int next_index;
|
int next_index;
|
||||||
int length;
|
int length;
|
||||||
} Keyword_Arguments;
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Ast_Node_Array_List* create_Ast_Node_Array_List(int initial_length); */
|
/* Ast_Node_Array_List* create_Ast_Node_Array_List(int initial_length); */
|
||||||
@@ -112,7 +110,7 @@ void append_to_keyword_argument_list(Keyword_Arguments* args,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
struct Function {
|
||||||
bool is_macro;
|
bool is_macro;
|
||||||
char* docstring;
|
char* docstring;
|
||||||
Positional_Arguments* positional_arguments;
|
Positional_Arguments* positional_arguments;
|
||||||
@@ -120,12 +118,13 @@ typedef struct {
|
|||||||
// 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;
|
||||||
struct Ast_Node* body; // implicit prog
|
struct Ast_Node* body; // implicit prog
|
||||||
} Function;
|
};
|
||||||
|
|
||||||
struct Environment;
|
struct Environment;
|
||||||
typedef struct {
|
|
||||||
|
struct CFunction {
|
||||||
std::function<Ast_Node*(Ast_Node*, Environment*)> function;
|
std::function<Ast_Node*(Ast_Node*, Environment*)> function;
|
||||||
} CFunction;
|
};
|
||||||
|
|
||||||
struct Ast_Node {
|
struct Ast_Node {
|
||||||
Source_Code_Location* sourceCodeLocation;
|
Source_Code_Location* sourceCodeLocation;
|
||||||
@@ -140,16 +139,14 @@ struct Ast_Node {
|
|||||||
CFunction* cfunction;
|
CFunction* cfunction;
|
||||||
} value;
|
} value;
|
||||||
};
|
};
|
||||||
// was forward declarated
|
|
||||||
typedef struct Ast_Node Ast_Node;
|
|
||||||
|
|
||||||
typedef struct {
|
struct Parsed_Arguments {
|
||||||
Ast_Node_Array_List* positional_arguments;
|
Ast_Node_Array_List* positional_arguments;
|
||||||
// TODO(Felix): Really use hashmap (keyword[sting] ->
|
// TODO(Felix): Really use hashmap (keyword[sting] ->
|
||||||
// value[Ast_Node*]) here
|
// value[Ast_Node*]) here
|
||||||
Ast_Node_Array_List* keyword_keys;
|
Ast_Node_Array_List* keyword_keys;
|
||||||
Ast_Node_Array_List* keyword_values;
|
Ast_Node_Array_List* keyword_values;
|
||||||
} Parsed_Arguments;
|
};
|
||||||
|
|
||||||
Ast_Node* create_ast_node() {
|
Ast_Node* create_ast_node() {
|
||||||
Ast_Node* node = new(Ast_Node);
|
Ast_Node* node = new(Ast_Node);
|
||||||
@@ -159,21 +156,21 @@ Ast_Node* create_ast_node() {
|
|||||||
|
|
||||||
Ast_Node* create_ast_node_nil() {
|
Ast_Node* create_ast_node_nil() {
|
||||||
Ast_Node* node = create_ast_node();
|
Ast_Node* node = create_ast_node();
|
||||||
node->type = Ast_Node_Type_Nil;
|
node->type = Ast_Node_Type::Nil;
|
||||||
node->value.pair = nullptr;
|
node->value.pair = nullptr;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* create_ast_node_t() {
|
Ast_Node* create_ast_node_t() {
|
||||||
Ast_Node* node = create_ast_node();
|
Ast_Node* node = create_ast_node();
|
||||||
node->type = Ast_Node_Type_T;
|
node->type = Ast_Node_Type::T;
|
||||||
node->value.pair = nullptr;
|
node->value.pair = nullptr;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* create_ast_node_number(double number) {
|
Ast_Node* create_ast_node_number(double number) {
|
||||||
Ast_Node* node = create_ast_node();
|
Ast_Node* node = create_ast_node();
|
||||||
node->type = Ast_Node_Type_Number;
|
node->type = Ast_Node_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;
|
||||||
@@ -181,7 +178,7 @@ Ast_Node* create_ast_node_number(double number) {
|
|||||||
|
|
||||||
Ast_Node* create_ast_node_string(char* str, int length) {
|
Ast_Node* create_ast_node_string(char* str, int length) {
|
||||||
Ast_Node* node = create_ast_node();
|
Ast_Node* node = create_ast_node();
|
||||||
node->type = Ast_Node_Type_String;
|
node->type = Ast_Node_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;
|
||||||
@@ -190,7 +187,7 @@ Ast_Node* create_ast_node_string(char* str, int length) {
|
|||||||
|
|
||||||
Ast_Node* create_ast_node_symbol(char* identifier) {
|
Ast_Node* create_ast_node_symbol(char* identifier) {
|
||||||
Ast_Node* node = create_ast_node();
|
Ast_Node* node = create_ast_node();
|
||||||
node->type = Ast_Node_Type_Symbol;
|
node->type = Ast_Node_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;
|
||||||
@@ -198,7 +195,7 @@ Ast_Node* create_ast_node_symbol(char* identifier) {
|
|||||||
|
|
||||||
Ast_Node* create_ast_node_keyword(char* keyword) {
|
Ast_Node* create_ast_node_keyword(char* keyword) {
|
||||||
Ast_Node* node = create_ast_node();
|
Ast_Node* node = create_ast_node();
|
||||||
node->type = Ast_Node_Type_Keyword;
|
node->type = Ast_Node_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;
|
||||||
@@ -206,7 +203,7 @@ Ast_Node* create_ast_node_keyword(char* keyword) {
|
|||||||
|
|
||||||
Ast_Node* create_ast_node_cfunction(std::function<Ast_Node*(Ast_Node*, Environment*)> function) {
|
Ast_Node* create_ast_node_cfunction(std::function<Ast_Node*(Ast_Node*, Environment*)> function) {
|
||||||
Ast_Node* node = create_ast_node();
|
Ast_Node* node = create_ast_node();
|
||||||
node->type = Ast_Node_Type_CFunction;
|
node->type = Ast_Node_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;
|
||||||
@@ -214,7 +211,7 @@ Ast_Node* create_ast_node_cfunction(std::function<Ast_Node*(Ast_Node*, Environme
|
|||||||
|
|
||||||
Ast_Node* create_ast_node_pair(Ast_Node* first, Ast_Node* rest) {
|
Ast_Node* create_ast_node_pair(Ast_Node* first, Ast_Node* rest) {
|
||||||
Ast_Node* node = create_ast_node();
|
Ast_Node* node = create_ast_node();
|
||||||
node->type = Ast_Node_Type_Pair;
|
node->type = Ast_Node_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;
|
||||||
|
|||||||
+119
-119
@@ -11,34 +11,34 @@ bool ast_node_equal(Ast_Node* n1, Ast_Node* n2) {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
switch (n1->type) {
|
switch (n1->type) {
|
||||||
case Ast_Node_Type_CFunction:
|
case Ast_Node_Type::CFunction:
|
||||||
// TODO(Felix): make comparing work again.
|
// TODO(Felix): make comparing work again.
|
||||||
return false;
|
return false;
|
||||||
/* 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::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->sourceCodeLocation);
|
create_error(Error_Type::Not_Yet_Implemented, n1->sourceCodeLocation);
|
||||||
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);
|
||||||
@@ -54,12 +54,12 @@ Ast_Node* built_in_equals(Ast_Node* arguments, Environment* env) {
|
|||||||
arguments = eval_arguments(arguments, env, &arguments_length);
|
arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arguments->type == Ast_Node_Type_Nil)
|
if (arguments->type == Ast_Node_Type::Nil)
|
||||||
return create_ast_node_t();
|
return create_ast_node_t();
|
||||||
|
|
||||||
Ast_Node* first = arguments->value.pair->first;
|
Ast_Node* first = arguments->value.pair->first;
|
||||||
|
|
||||||
while (arguments->type == Ast_Node_Type_Pair) {
|
while (arguments->type == Ast_Node_Type::Pair) {
|
||||||
if (!ast_node_equal(arguments->value.pair->first, first))
|
if (!ast_node_equal(arguments->value.pair->first, first))
|
||||||
return create_ast_node_nil();
|
return create_ast_node_nil();
|
||||||
arguments = arguments->value.pair->rest;
|
arguments = arguments->value.pair->rest;
|
||||||
@@ -76,9 +76,9 @@ Ast_Node* built_in_greater(Ast_Node* arguments, Environment* env) {
|
|||||||
|
|
||||||
double last_number = strtod("Inf", NULL);
|
double last_number = strtod("Inf", NULL);
|
||||||
|
|
||||||
while (arguments->type == Ast_Node_Type_Pair) {
|
while (arguments->type == Ast_Node_Type::Pair) {
|
||||||
try {
|
try {
|
||||||
assert_type(arguments->value.pair->first, Ast_Node_Type_Number);
|
assert_type(arguments->value.pair->first, Ast_Node_Type::Number);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arguments->value.pair->first->value.number->value >= last_number)
|
if (arguments->value.pair->first->value.number->value >= last_number)
|
||||||
@@ -99,9 +99,9 @@ Ast_Node* built_in_greater_equal(Ast_Node* arguments, Environment* env) {
|
|||||||
|
|
||||||
double last_number = strtod("Inf", NULL);
|
double last_number = strtod("Inf", NULL);
|
||||||
|
|
||||||
while (arguments->type == Ast_Node_Type_Pair) {
|
while (arguments->type == Ast_Node_Type::Pair) {
|
||||||
try {
|
try {
|
||||||
assert_type(arguments->value.pair->first, Ast_Node_Type_Number);
|
assert_type(arguments->value.pair->first, Ast_Node_Type::Number);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arguments->value.pair->first->value.number->value > last_number)
|
if (arguments->value.pair->first->value.number->value > last_number)
|
||||||
@@ -122,9 +122,9 @@ Ast_Node* built_in_less(Ast_Node* arguments, Environment* env) {
|
|||||||
|
|
||||||
double last_number = strtod("-Inf", NULL);
|
double last_number = strtod("-Inf", NULL);
|
||||||
|
|
||||||
while (arguments->type == Ast_Node_Type_Pair) {
|
while (arguments->type == Ast_Node_Type::Pair) {
|
||||||
try {
|
try {
|
||||||
assert_type(arguments->value.pair->first, Ast_Node_Type_Number);
|
assert_type(arguments->value.pair->first, Ast_Node_Type::Number);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arguments->value.pair->first->value.number->value <= last_number)
|
if (arguments->value.pair->first->value.number->value <= last_number)
|
||||||
@@ -145,9 +145,9 @@ Ast_Node* built_in_less_equal(Ast_Node* arguments, Environment* env) {
|
|||||||
|
|
||||||
double last_number = strtod("-Inf", NULL);
|
double last_number = strtod("-Inf", NULL);
|
||||||
|
|
||||||
while (arguments->type == Ast_Node_Type_Pair) {
|
while (arguments->type == Ast_Node_Type::Pair) {
|
||||||
try {
|
try {
|
||||||
assert_type(arguments->value.pair->first, Ast_Node_Type_Number);
|
assert_type(arguments->value.pair->first, Ast_Node_Type::Number);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arguments->value.pair->first->value.number->value < last_number)
|
if (arguments->value.pair->first->value.number->value < last_number)
|
||||||
@@ -167,9 +167,9 @@ Ast_Node* built_in_add(Ast_Node* arguments, Environment* env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
double sum = 0;
|
double sum = 0;
|
||||||
while (arguments->type == Ast_Node_Type_Pair) {
|
while (arguments->type == Ast_Node_Type::Pair) {
|
||||||
try {
|
try {
|
||||||
assert_type(arguments->value.pair->first, Ast_Node_Type_Number);
|
assert_type(arguments->value.pair->first, Ast_Node_Type::Number);
|
||||||
}
|
}
|
||||||
sum += arguments->value.pair->first->value.number->value;
|
sum += arguments->value.pair->first->value.number->value;
|
||||||
arguments = arguments->value.pair->rest;
|
arguments = arguments->value.pair->rest;
|
||||||
@@ -185,14 +185,14 @@ Ast_Node* built_in_substract(Ast_Node* arguments, Environment* env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
assert_type(arguments->value.pair->first, Ast_Node_Type_Number);
|
assert_type(arguments->value.pair->first, Ast_Node_Type::Number);
|
||||||
}
|
}
|
||||||
double difference = arguments->value.pair->first->value.number->value;
|
double difference = arguments->value.pair->first->value.number->value;
|
||||||
|
|
||||||
arguments = arguments->value.pair->rest;
|
arguments = arguments->value.pair->rest;
|
||||||
while (arguments->type == Ast_Node_Type_Pair) {
|
while (arguments->type == Ast_Node_Type::Pair) {
|
||||||
try {
|
try {
|
||||||
assert_type(arguments->value.pair->first, Ast_Node_Type_Number);
|
assert_type(arguments->value.pair->first, Ast_Node_Type::Number);
|
||||||
}
|
}
|
||||||
|
|
||||||
difference -= arguments->value.pair->first->value.number->value;
|
difference -= arguments->value.pair->first->value.number->value;
|
||||||
@@ -208,14 +208,14 @@ Ast_Node* built_in_multiply(Ast_Node* arguments, Environment* env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
assert_type(arguments->value.pair->first, Ast_Node_Type_Number);
|
assert_type(arguments->value.pair->first, Ast_Node_Type::Number);
|
||||||
}
|
}
|
||||||
double product = arguments->value.pair->first->value.number->value;
|
double product = arguments->value.pair->first->value.number->value;
|
||||||
|
|
||||||
arguments = arguments->value.pair->rest;
|
arguments = arguments->value.pair->rest;
|
||||||
while (arguments->type == Ast_Node_Type_Pair) {
|
while (arguments->type == Ast_Node_Type::Pair) {
|
||||||
try {
|
try {
|
||||||
assert_type(arguments->value.pair->first, Ast_Node_Type_Number);
|
assert_type(arguments->value.pair->first, Ast_Node_Type::Number);
|
||||||
}
|
}
|
||||||
|
|
||||||
product *= arguments->value.pair->first->value.number->value;
|
product *= arguments->value.pair->first->value.number->value;
|
||||||
@@ -231,14 +231,14 @@ Ast_Node* built_in_divide(Ast_Node* arguments, Environment* env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
assert_type(arguments->value.pair->first, Ast_Node_Type_Number);
|
assert_type(arguments->value.pair->first, Ast_Node_Type::Number);
|
||||||
}
|
}
|
||||||
double quotient = arguments->value.pair->first->value.number->value;
|
double quotient = arguments->value.pair->first->value.number->value;
|
||||||
|
|
||||||
arguments = arguments->value.pair->rest;
|
arguments = arguments->value.pair->rest;
|
||||||
while (arguments->type == Ast_Node_Type_Pair) {
|
while (arguments->type == Ast_Node_Type::Pair) {
|
||||||
try {
|
try {
|
||||||
assert_type(arguments->value.pair->first, Ast_Node_Type_Number);
|
assert_type(arguments->value.pair->first, Ast_Node_Type::Number);
|
||||||
}
|
}
|
||||||
|
|
||||||
quotient /= arguments->value.pair->first->value.number->value;
|
quotient /= arguments->value.pair->first->value.number->value;
|
||||||
@@ -263,7 +263,7 @@ Ast_Node* built_in_load(char* file_name, Environment* env) {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
create_error(Error_Type_Unknown_Error, nullptr);
|
create_error(Error_Type::Unknown_Error, nullptr);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -300,19 +300,19 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (arguments_length != 2) {
|
if (arguments_length != 2) {
|
||||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* symbol = arguments->value.pair->first;
|
Ast_Node* symbol = arguments->value.pair->first;
|
||||||
|
|
||||||
if (symbol->type == Ast_Node_Type_Pair) {
|
if (symbol->type == Ast_Node_Type::Pair) {
|
||||||
try {
|
try {
|
||||||
symbol = eval_expr(symbol, env);
|
symbol = eval_expr(symbol, env);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (symbol->type != Ast_Node_Type_Symbol) {
|
if (symbol->type != Ast_Node_Type::Symbol) {
|
||||||
report_error(Error_Type_Type_Missmatch);
|
report_error(Error_Type::Type_Missmatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* value = arguments->value.pair->rest->value.pair->first;
|
Ast_Node* value = arguments->value.pair->rest->value.pair->first;
|
||||||
@@ -330,19 +330,19 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (arguments_length != 2) {
|
if (arguments_length != 2) {
|
||||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* symbol = arguments->value.pair->first;
|
Ast_Node* symbol = arguments->value.pair->first;
|
||||||
|
|
||||||
if (symbol->type == Ast_Node_Type_Pair) {
|
if (symbol->type == Ast_Node_Type::Pair) {
|
||||||
try {
|
try {
|
||||||
symbol = eval_expr(symbol, env);
|
symbol = eval_expr(symbol, env);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (symbol->type != Ast_Node_Type_Symbol) {
|
if (symbol->type != Ast_Node_Type::Symbol) {
|
||||||
report_error(Error_Type_Type_Missmatch);
|
report_error(Error_Type::Type_Missmatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* value = arguments->value.pair->rest->value.pair->first;
|
Ast_Node* value = arguments->value.pair->rest->value.pair->first;
|
||||||
@@ -360,12 +360,12 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (arguments_length != 2)
|
if (arguments_length != 2)
|
||||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
||||||
|
|
||||||
if (evaluated_arguments->value.pair->first->type == Ast_Node_Type_Nil ||
|
if (evaluated_arguments->value.pair->first->type == Ast_Node_Type::Nil ||
|
||||||
evaluated_arguments->value.pair->first->type == Ast_Node_Type_Keyword)
|
evaluated_arguments->value.pair->first->type == Ast_Node_Type::Keyword)
|
||||||
{
|
{
|
||||||
report_error(Error_Type_Type_Missmatch);
|
report_error(Error_Type::Type_Missmatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* target = evaluated_arguments->value.pair->first;
|
Ast_Node* target = evaluated_arguments->value.pair->first;
|
||||||
@@ -380,7 +380,7 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (arguments_length != 2 && arguments_length != 3) {
|
if (arguments_length != 2 && arguments_length != 3) {
|
||||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* condition = arguments->value.pair->first;
|
Ast_Node* condition = arguments->value.pair->first;
|
||||||
@@ -411,16 +411,16 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (arguments_length != 1) {
|
if (arguments_length != 1) {
|
||||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
return arguments->value.pair->first;
|
return arguments->value.pair->first;
|
||||||
});
|
});
|
||||||
defun("and", cLambda {
|
defun("and", cLambda {
|
||||||
bool result = true;
|
bool result = true;
|
||||||
while (arguments->type != Ast_Node_Type_Nil) {
|
while (arguments->type != Ast_Node_Type::Nil) {
|
||||||
if (arguments->type != Ast_Node_Type_Pair) {
|
if (arguments->type != Ast_Node_Type::Pair) {
|
||||||
report_error(Error_Type_Ill_Formed_List);
|
report_error(Error_Type::Ill_Formed_List);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
result &= is_truthy(arguments->value.pair->first, env);
|
result &= is_truthy(arguments->value.pair->first, env);
|
||||||
@@ -434,9 +434,9 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
});
|
});
|
||||||
defun("or", cLambda {
|
defun("or", cLambda {
|
||||||
bool result = false;
|
bool result = false;
|
||||||
while (arguments->type != Ast_Node_Type_Nil) {
|
while (arguments->type != Ast_Node_Type::Nil) {
|
||||||
if (arguments->type != Ast_Node_Type_Pair) {
|
if (arguments->type != Ast_Node_Type::Pair) {
|
||||||
report_error(Error_Type_Ill_Formed_List);
|
report_error(Error_Type::Ill_Formed_List);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
result |= is_truthy(arguments->value.pair->first, env);
|
result |= is_truthy(arguments->value.pair->first, env);
|
||||||
@@ -454,7 +454,7 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (arguments_length != 1) {
|
if (arguments_length != 1) {
|
||||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
||||||
}
|
}
|
||||||
bool truthy;
|
bool truthy;
|
||||||
try {
|
try {
|
||||||
@@ -470,7 +470,7 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (arguments_length < 2) {
|
if (arguments_length < 2) {
|
||||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
||||||
}
|
}
|
||||||
Ast_Node* condition_part = arguments->value.pair->first;
|
Ast_Node* condition_part = arguments->value.pair->first;
|
||||||
Ast_Node* condition;
|
Ast_Node* condition;
|
||||||
@@ -481,7 +481,7 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
try {
|
try {
|
||||||
condition = eval_expr(condition_part, env);
|
condition = eval_expr(condition_part, env);
|
||||||
}
|
}
|
||||||
if (condition->type == Ast_Node_Type_Nil) {
|
if (condition->type == Ast_Node_Type::Nil) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
@@ -498,27 +498,27 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (arguments_length < 1)
|
if (arguments_length < 1)
|
||||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
||||||
|
|
||||||
Environment* let_env = create_child_environment(env, Environment_Type_Let);
|
Environment* let_env = create_child_environment(env, Environment_Type::Let);
|
||||||
Ast_Node* bindings = arguments->value.pair->first;
|
Ast_Node* bindings = arguments->value.pair->first;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (bindings->type == Ast_Node_Type_Nil) {
|
if (bindings->type == Ast_Node_Type::Nil) {
|
||||||
break;
|
break;
|
||||||
} else if (bindings->type != Ast_Node_Type_Pair) {
|
} else if (bindings->type != Ast_Node_Type::Pair) {
|
||||||
report_error(Error_Type_Ill_Formed_Arguments);
|
report_error(Error_Type::Ill_Formed_Arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* sym = bindings->value.pair->first->value.pair->first;
|
Ast_Node* sym = bindings->value.pair->first->value.pair->first;
|
||||||
if(sym->type != Ast_Node_Type_Symbol) {
|
if(sym->type != Ast_Node_Type::Symbol) {
|
||||||
report_error(Error_Type_Ill_Formed_Arguments);
|
report_error(Error_Type::Ill_Formed_Arguments);
|
||||||
}
|
}
|
||||||
Ast_Node* rest_sym = bindings->value.pair->first->value.pair->rest;
|
Ast_Node* rest_sym = bindings->value.pair->first->value.pair->rest;
|
||||||
if (rest_sym->type != Ast_Node_Type_Pair) {
|
if (rest_sym->type != Ast_Node_Type::Pair) {
|
||||||
report_error(Error_Type_Ill_Formed_Arguments);
|
report_error(Error_Type::Ill_Formed_Arguments);
|
||||||
}
|
}
|
||||||
if (rest_sym->value.pair->rest->type != Ast_Node_Type_Nil) {
|
if (rest_sym->value.pair->rest->type != Ast_Node_Type::Nil) {
|
||||||
report_error(Error_Type_Ill_Formed_Arguments);
|
report_error(Error_Type::Ill_Formed_Arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* value = eval_expr(rest_sym->value.pair->first, env);
|
Ast_Node* value = eval_expr(rest_sym->value.pair->first, env);
|
||||||
@@ -535,7 +535,7 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
evaluated_arguments = eval_arguments(arguments, let_env, &arguments_length);
|
evaluated_arguments = eval_arguments(arguments, let_env, &arguments_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evaluated_arguments->type == Ast_Node_Type_Nil)
|
if (evaluated_arguments->type == Ast_Node_Type::Nil)
|
||||||
return evaluated_arguments;
|
return evaluated_arguments;
|
||||||
|
|
||||||
// skip to the last evaluated operand and return it,
|
// skip to the last evaluated operand and return it,
|
||||||
@@ -543,7 +543,7 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
// manually, because we want to increase code reuse,
|
// manually, because we want to increase code reuse,
|
||||||
// but at the cost that we have to find the end of the
|
// but at the cost that we have to find the end of the
|
||||||
// list again
|
// list again
|
||||||
while (evaluated_arguments->value.pair->rest->type == Ast_Node_Type_Pair) {
|
while (evaluated_arguments->value.pair->rest->type == Ast_Node_Type::Pair) {
|
||||||
evaluated_arguments = evaluated_arguments->value.pair->rest;
|
evaluated_arguments = evaluated_arguments->value.pair->rest;
|
||||||
}
|
}
|
||||||
return evaluated_arguments->value.pair->first;
|
return evaluated_arguments->value.pair->first;
|
||||||
@@ -558,7 +558,7 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (arguments_length == 0)
|
if (arguments_length == 0)
|
||||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
||||||
|
|
||||||
Function* function = new(Function);
|
Function* function = new(Function);
|
||||||
/* if (lispOperator->value.built_in_function->type == Built_In_Macro) { */
|
/* if (lispOperator->value.built_in_function->type == Built_In_Macro) { */
|
||||||
@@ -568,9 +568,9 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
/* } */
|
/* } */
|
||||||
|
|
||||||
// if parameters were specified
|
// if parameters were specified
|
||||||
if (arguments->value.pair->first->type != Ast_Node_Type_Nil) {
|
if (arguments->value.pair->first->type != Ast_Node_Type::Nil) {
|
||||||
try {
|
try {
|
||||||
assert_type(arguments->value.pair->first, Ast_Node_Type_Pair);
|
assert_type(arguments->value.pair->first, Ast_Node_Type::Pair);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
parse_argument_list(arguments->value.pair->first, function);
|
parse_argument_list(arguments->value.pair->first, function);
|
||||||
@@ -583,7 +583,7 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
|
|
||||||
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 == Ast_Node_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 {
|
||||||
@@ -597,7 +597,7 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
arguments);
|
arguments);
|
||||||
|
|
||||||
Ast_Node* ret = new(Ast_Node);
|
Ast_Node* ret = new(Ast_Node);
|
||||||
ret->type = Ast_Node_Type_Function;
|
ret->type = Ast_Node_Type::Function;
|
||||||
ret->value.function = function;
|
ret->value.function = function;
|
||||||
return ret;
|
return ret;
|
||||||
});
|
});
|
||||||
@@ -611,15 +611,15 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (arguments_length == 0)
|
if (arguments_length == 0)
|
||||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
||||||
|
|
||||||
Function* function = new(Function);
|
Function* function = new(Function);
|
||||||
function->is_macro = true;
|
function->is_macro = true;
|
||||||
|
|
||||||
// if parameters were specified
|
// if parameters were specified
|
||||||
if (arguments->value.pair->first->type != Ast_Node_Type_Nil) {
|
if (arguments->value.pair->first->type != Ast_Node_Type::Nil) {
|
||||||
try {
|
try {
|
||||||
assert_type(arguments->value.pair->first, Ast_Node_Type_Pair);
|
assert_type(arguments->value.pair->first, Ast_Node_Type::Pair);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
parse_argument_list(arguments->value.pair->first, function);
|
parse_argument_list(arguments->value.pair->first, function);
|
||||||
@@ -632,7 +632,7 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
|
|
||||||
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 == Ast_Node_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 {
|
||||||
@@ -646,7 +646,7 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
arguments);
|
arguments);
|
||||||
|
|
||||||
Ast_Node* ret = new(Ast_Node);
|
Ast_Node* ret = new(Ast_Node);
|
||||||
ret->type = Ast_Node_Type_Function;
|
ret->type = Ast_Node_Type::Function;
|
||||||
ret->value.function = function;
|
ret->value.function = function;
|
||||||
return ret;
|
return ret;
|
||||||
});
|
});
|
||||||
@@ -655,7 +655,7 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
}
|
}
|
||||||
if (arguments_length != 1) {
|
if (arguments_length != 1) {
|
||||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
||||||
}
|
}
|
||||||
Ast_Node* result;
|
Ast_Node* result;
|
||||||
try {
|
try {
|
||||||
@@ -670,7 +670,7 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evaluated_arguments->type == Ast_Node_Type_Nil)
|
if (evaluated_arguments->type == Ast_Node_Type::Nil)
|
||||||
return evaluated_arguments;
|
return evaluated_arguments;
|
||||||
|
|
||||||
// skip to the last evaluated operand and return it,
|
// skip to the last evaluated operand and return it,
|
||||||
@@ -678,7 +678,7 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
// manually, because we want to increase code reuse,
|
// manually, because we want to increase code reuse,
|
||||||
// but at the cost that we have to find the end of the
|
// but at the cost that we have to find the end of the
|
||||||
// list again
|
// list again
|
||||||
while (evaluated_arguments->value.pair->rest->type == Ast_Node_Type_Pair) {
|
while (evaluated_arguments->value.pair->rest->type == Ast_Node_Type::Pair) {
|
||||||
evaluated_arguments = evaluated_arguments->value.pair->rest;
|
evaluated_arguments = evaluated_arguments->value.pair->rest;
|
||||||
}
|
}
|
||||||
return evaluated_arguments->value.pair->first;
|
return evaluated_arguments->value.pair->first;
|
||||||
@@ -699,7 +699,7 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
// BUG(Felix): Why is arguments_length for '(1 (2)) == 3 and not 2??
|
// BUG(Felix): Why is arguments_length for '(1 (2)) == 3 and not 2??
|
||||||
/* if (arguments_length != 2) { */
|
/* if (arguments_length != 2) { */
|
||||||
if (list_length(evaluated_arguments) != 2) {
|
if (list_length(evaluated_arguments) != 2) {
|
||||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
||||||
}
|
}
|
||||||
return create_ast_node_pair(evaluated_arguments->value.pair->first, evaluated_arguments->value.pair->rest->value.pair->first);
|
return create_ast_node_pair(evaluated_arguments->value.pair->first, evaluated_arguments->value.pair->rest->value.pair->first);
|
||||||
});
|
});
|
||||||
@@ -708,12 +708,12 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
}
|
}
|
||||||
if (arguments_length != 1) {
|
if (arguments_length != 1) {
|
||||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
||||||
}
|
}
|
||||||
if (evaluated_arguments->value.pair->first->type == Ast_Node_Type_Nil)
|
if (evaluated_arguments->value.pair->first->type == Ast_Node_Type::Nil)
|
||||||
return create_ast_node_nil();
|
return create_ast_node_nil();
|
||||||
if (evaluated_arguments->value.pair->first->type != Ast_Node_Type_Pair)
|
if (evaluated_arguments->value.pair->first->type != Ast_Node_Type::Pair)
|
||||||
report_error(Error_Type_Type_Missmatch);
|
report_error(Error_Type::Type_Missmatch);
|
||||||
|
|
||||||
return evaluated_arguments->value.pair->first->value.pair->first;
|
return evaluated_arguments->value.pair->first->value.pair->first;
|
||||||
});
|
});
|
||||||
@@ -722,12 +722,12 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
}
|
}
|
||||||
if (arguments_length != 1) {
|
if (arguments_length != 1) {
|
||||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
||||||
}
|
}
|
||||||
if (evaluated_arguments->value.pair->first->type == Ast_Node_Type_Nil)
|
if (evaluated_arguments->value.pair->first->type == Ast_Node_Type::Nil)
|
||||||
return create_ast_node_nil();
|
return create_ast_node_nil();
|
||||||
if (evaluated_arguments->value.pair->first->type != Ast_Node_Type_Pair)
|
if (evaluated_arguments->value.pair->first->type != Ast_Node_Type::Pair)
|
||||||
report_error(Error_Type_Type_Missmatch);
|
report_error(Error_Type::Type_Missmatch);
|
||||||
|
|
||||||
return evaluated_arguments->value.pair->first->value.pair->rest;
|
return evaluated_arguments->value.pair->first->value.pair->rest;
|
||||||
});
|
});
|
||||||
@@ -736,24 +736,24 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
}
|
}
|
||||||
if (arguments_length != 1) {
|
if (arguments_length != 1) {
|
||||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node_Type type = evaluated_arguments->value.pair->first->type;
|
Ast_Node_Type type = evaluated_arguments->value.pair->first->type;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Ast_Node_Type_CFunction: return create_ast_node_keyword("cfunction");
|
case Ast_Node_Type::CFunction: return create_ast_node_keyword("cfunction");
|
||||||
case Ast_Node_Type_Function: {
|
case Ast_Node_Type::Function: {
|
||||||
if (evaluated_arguments->value.pair->first->value.function->is_macro)
|
if (evaluated_arguments->value.pair->first->value.function->is_macro)
|
||||||
return create_ast_node_keyword("dynamic-macro");
|
return create_ast_node_keyword("dynamic-macro");
|
||||||
return create_ast_node_keyword("dynamic-function");
|
return create_ast_node_keyword("dynamic-function");
|
||||||
}
|
}
|
||||||
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::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");
|
||||||
case Ast_Node_Type_Symbol: return create_ast_node_keyword("symbol");
|
case Ast_Node_Type::Symbol: return create_ast_node_keyword("symbol");
|
||||||
}
|
}
|
||||||
return create_ast_node_keyword("unknown");
|
return create_ast_node_keyword("unknown");
|
||||||
});
|
});
|
||||||
@@ -763,7 +763,7 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (arguments_length != 1) {
|
if (arguments_length != 1) {
|
||||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
print(arguments->value.pair->first);
|
print(arguments->value.pair->first);
|
||||||
@@ -780,7 +780,7 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
// 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")))
|
||||||
{
|
{
|
||||||
@@ -836,7 +836,7 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
}
|
}
|
||||||
if (arguments_length != 1) {
|
if (arguments_length != 1) {
|
||||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
||||||
}
|
}
|
||||||
print(evaluated_arguments->value.pair->first);
|
print(evaluated_arguments->value.pair->first);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
@@ -848,12 +848,12 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (arguments_length > 1) {
|
if (arguments_length > 1) {
|
||||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arguments_length == 1) {
|
if (arguments_length == 1) {
|
||||||
Ast_Node* prompt = evaluated_arguments->value.pair->first;
|
Ast_Node* prompt = evaluated_arguments->value.pair->first;
|
||||||
/* if (prompt->type == Ast_Node_Type_String) */
|
/* if (prompt->type == Ast_Node_Type::String) */
|
||||||
/* printf("%s", prompt->value.string->value); */
|
/* printf("%s", prompt->value.string->value); */
|
||||||
/* else */
|
/* else */
|
||||||
print(evaluated_arguments->value.pair->first);
|
print(evaluated_arguments->value.pair->first);
|
||||||
@@ -867,13 +867,13 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (arguments_length > 1) {
|
if (arguments_length > 1) {
|
||||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arguments_length == 1) {
|
if (arguments_length == 1) {
|
||||||
Ast_Node* error_code = evaluated_arguments->value.pair->first;
|
Ast_Node* error_code = evaluated_arguments->value.pair->first;
|
||||||
if (error_code->type != Ast_Node_Type_Number)
|
if (error_code->type != Ast_Node_Type::Number)
|
||||||
report_error(Error_Type_Type_Missmatch);
|
report_error(Error_Type::Type_Missmatch);
|
||||||
|
|
||||||
exit((int)error_code->value.number->value);
|
exit((int)error_code->value.number->value);
|
||||||
}
|
}
|
||||||
@@ -892,7 +892,7 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (arguments_length != 2) {
|
if (arguments_length != 2) {
|
||||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* try_part = arguments->value.pair->first;
|
Ast_Node* try_part = arguments->value.pair->first;
|
||||||
@@ -914,10 +914,10 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (arguments_length != 1)
|
if (arguments_length != 1)
|
||||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
||||||
|
|
||||||
if (evaluated_arguments->value.pair->first->type != Ast_Node_Type_String)
|
if (evaluated_arguments->value.pair->first->type != Ast_Node_Type::String)
|
||||||
report_error(Error_Type_Type_Missmatch);
|
report_error(Error_Type::Type_Missmatch);
|
||||||
|
|
||||||
Ast_Node* result;
|
Ast_Node* result;
|
||||||
try {
|
try {
|
||||||
@@ -933,12 +933,12 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (arguments_length != 1)
|
if (arguments_length != 1)
|
||||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
||||||
|
|
||||||
if (evaluated_arguments->value.pair->first->type == Ast_Node_Type_Nil ||
|
if (evaluated_arguments->value.pair->first->type == Ast_Node_Type::Nil ||
|
||||||
evaluated_arguments->value.pair->first->type == Ast_Node_Type_Keyword)
|
evaluated_arguments->value.pair->first->type == Ast_Node_Type::Keyword)
|
||||||
{
|
{
|
||||||
report_error(Error_Type_Type_Missmatch);
|
report_error(Error_Type::Type_Missmatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* target = new(Ast_Node);
|
Ast_Node* target = new(Ast_Node);
|
||||||
@@ -952,9 +952,9 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
}
|
}
|
||||||
if (arguments_length != 0) {
|
if (arguments_length != 0) {
|
||||||
report_error(Error_Type_Wrong_Number_Of_Arguments);
|
report_error(Error_Type::Wrong_Number_Of_Arguments);
|
||||||
}
|
}
|
||||||
report_error(Error_Type_Unknown_Error);
|
report_error(Error_Type::Unknown_Error);
|
||||||
});
|
});
|
||||||
|
|
||||||
#undef report_error
|
#undef report_error
|
||||||
@@ -962,7 +962,7 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Environment* create_built_ins_environment() {
|
Environment* create_built_ins_environment() {
|
||||||
Environment* ret = create_child_environment(nullptr, Environment_Type_Let);
|
Environment* ret = create_child_environment(nullptr, Environment_Type::Let);
|
||||||
load_built_ins_into_environment(ret);
|
load_built_ins_into_environment(ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-20
@@ -1,8 +1,8 @@
|
|||||||
typedef enum {
|
enum struct Environment_Type {
|
||||||
Environment_Type_Let,
|
Let,
|
||||||
Environment_Type_Lambda,
|
Lambda,
|
||||||
Environment_Type_Macro,
|
Macro,
|
||||||
} Environment_Type;
|
};
|
||||||
|
|
||||||
struct Environment {
|
struct Environment {
|
||||||
struct Environment* parent;
|
struct Environment* parent;
|
||||||
@@ -15,8 +15,6 @@ struct Environment {
|
|||||||
Ast_Node** values;
|
Ast_Node** values;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct Environment Environment;
|
|
||||||
|
|
||||||
Environment* create_child_environment(Environment* parent, Environment_Type type) {
|
Environment* create_child_environment(Environment* parent, Environment_Type type) {
|
||||||
Environment* env = new(Environment);
|
Environment* env = new(Environment);
|
||||||
|
|
||||||
@@ -37,7 +35,7 @@ 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,
|
||||||
@@ -63,14 +61,14 @@ 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->sourceCodeLocation);
|
create_error(Error_Type::Unknown_Error, symbol->sourceCodeLocation);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
env->type = Environment_Type_Lambda;
|
env->type = Environment_Type::Lambda;
|
||||||
define_symbol(symbol, value, env);
|
define_symbol(symbol, value, env);
|
||||||
env->type = Environment_Type_Macro;
|
env->type = Environment_Type::Macro;
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_environment(Environment* env);
|
void print_environment(Environment* env);
|
||||||
@@ -85,7 +83,7 @@ Ast_Node* lookup_symbol_in_this_envt(Symbol* sym, Environment* env) {
|
|||||||
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;
|
||||||
}
|
}
|
||||||
@@ -99,7 +97,7 @@ Ast_Node* lookup_symbol_from_let_or_macro_env(Symbol* sym, Environment* env) {
|
|||||||
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;
|
||||||
@@ -107,7 +105,7 @@ Ast_Node* lookup_symbol_from_let_or_macro_env(Symbol* sym, Environment* 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;
|
||||||
}
|
}
|
||||||
@@ -127,7 +125,7 @@ Ast_Node* lookup_symbol(Ast_Node* node, Environment* env) {
|
|||||||
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);
|
||||||
@@ -152,7 +150,7 @@ Ast_Node* lookup_symbol(Ast_Node* node, Environment* env) {
|
|||||||
/* if (result) */
|
/* if (result) */
|
||||||
/* return result; */
|
/* return result; */
|
||||||
|
|
||||||
create_error(Error_Type_Symbol_Not_Defined, node->sourceCodeLocation);
|
create_error(Error_Type::Symbol_Not_Defined, node->sourceCodeLocation);
|
||||||
/* printf("%s\n", sym->identifier); */
|
/* printf("%s\n", sym->identifier); */
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -172,11 +170,11 @@ void print_environment_indent(Environment* env, int indent) {
|
|||||||
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);
|
||||||
|
|||||||
+31
-31
@@ -1,24 +1,24 @@
|
|||||||
typedef enum {
|
enum struct Error_Type {
|
||||||
Error_Type_Ill_Formed_Arguments,
|
Ill_Formed_Arguments,
|
||||||
Error_Type_Ill_Formed_Lambda_List,
|
Ill_Formed_Lambda_List,
|
||||||
Error_Type_Ill_Formed_List,
|
Ill_Formed_List,
|
||||||
Error_Type_Not_A_Function,
|
Not_A_Function,
|
||||||
Error_Type_Not_Yet_Implemented,
|
Not_Yet_Implemented,
|
||||||
Error_Type_Symbol_Not_Defined,
|
Symbol_Not_Defined,
|
||||||
Error_Type_Syntax_Error,
|
Syntax_Error,
|
||||||
Error_Type_Trailing_Garbage,
|
Trailing_Garbage,
|
||||||
Error_Type_Type_Missmatch,
|
Type_Missmatch,
|
||||||
Error_Type_Unbalanced_Parenthesis,
|
Unbalanced_Parenthesis,
|
||||||
Error_Type_Unexpected_Eof,
|
Unexpected_Eof,
|
||||||
Error_Type_Unknown_Error,
|
Unknown_Error,
|
||||||
Error_Type_Unknown_Keyword_Argument,
|
Unknown_Keyword_Argument,
|
||||||
Error_Type_Wrong_Number_Of_Arguments,
|
Wrong_Number_Of_Arguments,
|
||||||
} Error_Type;
|
};
|
||||||
|
|
||||||
typedef struct Error_t {
|
struct Error {
|
||||||
Error_Type type;
|
Error_Type type;
|
||||||
Source_Code_Location* location;
|
Source_Code_Location* location;
|
||||||
} Error;
|
};
|
||||||
|
|
||||||
Error* error;
|
Error* error;
|
||||||
|
|
||||||
@@ -39,19 +39,19 @@ void create_error(Error_Type type, Source_Code_Location* location) {
|
|||||||
|
|
||||||
char* Error_Type_to_string(Error_Type type) {
|
char* Error_Type_to_string(Error_Type type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Error_Type_Ill_Formed_Arguments: return "Evaluation-error: Ill formed arguments";
|
case Error_Type::Ill_Formed_Arguments: return "Evaluation-error: Ill formed arguments";
|
||||||
case Error_Type_Ill_Formed_Lambda_List: return "Evaluation-error: Ill formed lambda list";
|
case Error_Type::Ill_Formed_Lambda_List: return "Evaluation-error: Ill formed lambda list";
|
||||||
case Error_Type_Ill_Formed_List: return "Evaluation-error: Ill formed list";
|
case Error_Type::Ill_Formed_List: return "Evaluation-error: Ill formed list";
|
||||||
case Error_Type_Not_A_Function: return "Evaluation-error: Not a function";
|
case Error_Type::Not_A_Function: return "Evaluation-error: Not a function";
|
||||||
case Error_Type_Not_Yet_Implemented: return "Evaluation-error: Not yet implemented";
|
case Error_Type::Not_Yet_Implemented: return "Evaluation-error: Not yet implemented";
|
||||||
case Error_Type_Symbol_Not_Defined: return "Evaluation-error: Symbol not defined";
|
case Error_Type::Symbol_Not_Defined: return "Evaluation-error: Symbol not defined";
|
||||||
case Error_Type_Syntax_Error: return "Syntax Error";
|
case Error_Type::Syntax_Error: return "Syntax Error";
|
||||||
case Error_Type_Trailing_Garbage: return "Evaluation-error: Trailing garbage following expression";
|
case Error_Type::Trailing_Garbage: return "Evaluation-error: Trailing garbage following expression";
|
||||||
case Error_Type_Type_Missmatch: return "Evaluation-error: Type Missmatch";
|
case Error_Type::Type_Missmatch: return "Evaluation-error: Type Missmatch";
|
||||||
case Error_Type_Unbalanced_Parenthesis: return "Parsing-error: Unbalanced parenthesis";
|
case Error_Type::Unbalanced_Parenthesis: return "Parsing-error: Unbalanced parenthesis";
|
||||||
case Error_Type_Unexpected_Eof: return "Parsing-error: Unexpected EOF";
|
case Error_Type::Unexpected_Eof: return "Parsing-error: Unexpected EOF";
|
||||||
case Error_Type_Unknown_Keyword_Argument: return "Evaluation-error: Unknown keyword argument";
|
case Error_Type::Unknown_Keyword_Argument: return "Evaluation-error: Unknown keyword argument";
|
||||||
case Error_Type_Wrong_Number_Of_Arguments: return "Evaluation-error: Wrong number of arguments";
|
case Error_Type::Wrong_Number_Of_Arguments: return "Evaluation-error: Wrong number of arguments";
|
||||||
default: return "Unknown Error";
|
default: return "Unknown Error";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+69
-69
@@ -6,11 +6,11 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
|
|||||||
// switching between "define_symbol" and "define_macro_symbol" all
|
// switching between "define_symbol" and "define_macro_symbol" all
|
||||||
// the time
|
// the time
|
||||||
|
|
||||||
Environment* new_env = create_child_environment(parent, Environment_Type_Lambda);
|
Environment* new_env = create_child_environment(parent, Environment_Type::Lambda);
|
||||||
|
|
||||||
// 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 == Ast_Node_Type::Pair) {
|
||||||
// TODO(Felix): here we create new ast_node_symbols from
|
// TODO(Felix): here we create new ast_node_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?
|
||||||
@@ -19,13 +19,13 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
|
|||||||
arguments->value.pair->first, new_env);
|
arguments->value.pair->first, new_env);
|
||||||
} else {
|
} else {
|
||||||
// not enough arguments given
|
// not enough arguments given
|
||||||
create_error(Error_Type_Ill_Formed_Arguments, arguments->sourceCodeLocation);
|
create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
arguments = arguments->value.pair->rest;
|
arguments = arguments->value.pair->rest;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arguments->type == Ast_Node_Type_Nil)
|
if (arguments->type == Ast_Node_Type::Nil)
|
||||||
goto eval_time;
|
goto eval_time;
|
||||||
|
|
||||||
String_Array_List* read_in_keywords = create_String_array_list(16);
|
String_Array_List* read_in_keywords = create_String_array_list(16);
|
||||||
@@ -34,7 +34,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
|
|||||||
// 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 == Ast_Node_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) {
|
||||||
@@ -47,7 +47,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!accepted) {
|
if (!accepted) {
|
||||||
create_error(Error_Type_Ill_Formed_Arguments, arguments->sourceCodeLocation);
|
create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
|
|||||||
// necessary keywords then we have to count the rest
|
// necessary keywords then we have to count the rest
|
||||||
// as :rest here, instead od always creating an error
|
// as :rest here, instead od always creating an error
|
||||||
// (special case with default variables)
|
// (special case with default variables)
|
||||||
create_error(Error_Type_Ill_Formed_Arguments, arguments->sourceCodeLocation);
|
create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,8 +69,8 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
|
|||||||
// 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 != Ast_Node_Type::Pair) {
|
||||||
create_error(Error_Type_Ill_Formed_Arguments, arguments->sourceCodeLocation);
|
create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
|
|||||||
// 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 == Ast_Node_Type::Nil) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,7 +107,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
|
|||||||
if (function->keyword_arguments->values->data[i] == nullptr) {
|
if (function->keyword_arguments->values->data[i] == nullptr) {
|
||||||
// if this one does not have a default value
|
// if this one does not have a default value
|
||||||
if (!was_set) {
|
if (!was_set) {
|
||||||
create_error(Error_Type_Ill_Formed_Arguments, arguments->sourceCodeLocation);
|
create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -122,7 +122,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (arguments->type == Ast_Node_Type_Nil) {
|
if (arguments->type == Ast_Node_Type::Nil) {
|
||||||
if (function->rest_argument) {
|
if (function->rest_argument) {
|
||||||
define_symbol(
|
define_symbol(
|
||||||
create_ast_node_symbol(function->rest_argument),
|
create_ast_node_symbol(function->rest_argument),
|
||||||
@@ -135,7 +135,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
|
|||||||
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
|
||||||
create_error(Error_Type_Ill_Formed_Arguments, arguments->sourceCodeLocation);
|
create_error(Error_Type::Ill_Formed_Arguments, arguments->sourceCodeLocation);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -146,7 +146,7 @@ Ast_Node* apply_arguments_to_function(Ast_Node* arguments, Function* function, E
|
|||||||
// 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);
|
||||||
@@ -180,19 +180,19 @@ void parse_argument_list(Ast_Node* arguments, Function* function) {
|
|||||||
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 == Ast_Node_Type::Pair) {
|
||||||
if (arguments->value.pair->first->type == Ast_Node_Type_Keyword) {
|
if (arguments->value.pair->first->type == Ast_Node_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;
|
||||||
else {
|
else {
|
||||||
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_Symbol) {
|
if (arguments->value.pair->first->type != Ast_Node_Type::Symbol) {
|
||||||
create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,35 +206,35 @@ void parse_argument_list(Ast_Node* arguments, Function* function) {
|
|||||||
|
|
||||||
// okay we are done with positional arguments, lets check for
|
// okay we are done with positional arguments, lets check for
|
||||||
// keywords,
|
// keywords,
|
||||||
if (arguments->type != Ast_Node_Type_Pair) {
|
if (arguments->type != Ast_Node_Type::Pair) {
|
||||||
if (arguments->type != Ast_Node_Type_Nil)
|
if (arguments->type != Ast_Node_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 == Ast_Node_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 != Ast_Node_Type::Pair ||
|
||||||
arguments->value.pair->first->type != Ast_Node_Type_Symbol)
|
arguments->value.pair->first->type != Ast_Node_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 == Ast_Node_Type::Pair) {
|
||||||
if (arguments->value.pair->first->type == Ast_Node_Type_Keyword) {
|
if (arguments->value.pair->first->type == Ast_Node_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 {
|
||||||
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_Symbol) {
|
if (arguments->value.pair->first->type != Ast_Node_Type::Symbol) {
|
||||||
create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,21 +242,21 @@ void parse_argument_list(Ast_Node* arguments, Function* function) {
|
|||||||
// 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;
|
Ast_Node* next = arguments->value.pair->rest;
|
||||||
if (next->type == Ast_Node_Type_Pair &&
|
if (next->type == Ast_Node_Type::Pair &&
|
||||||
next->value.pair->first->type == Ast_Node_Type_Keyword &&
|
next->value.pair->first->type == Ast_Node_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 == Ast_Node_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);
|
||||||
arguments = next->value.pair->rest;
|
arguments = next->value.pair->rest;
|
||||||
} else {
|
} else {
|
||||||
create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -272,51 +272,51 @@ void parse_argument_list(Ast_Node* arguments, Function* function) {
|
|||||||
|
|
||||||
// Now we are also done with keyword arguments, lets check for
|
// Now we are also done with keyword arguments, lets check for
|
||||||
// if there is a rest argument
|
// if there is a rest argument
|
||||||
if (arguments->type != Ast_Node_Type_Pair) {
|
if (arguments->type != Ast_Node_Type::Pair) {
|
||||||
if (arguments->type != Ast_Node_Type_Nil)
|
if (arguments->type != Ast_Node_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 == Ast_Node_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 != Ast_Node_Type::Pair ||
|
||||||
arguments->value.pair->first->type != Ast_Node_Type_Symbol)
|
arguments->value.pair->first->type != Ast_Node_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 != Ast_Node_Type::Nil) {
|
||||||
create_error(Error_Type_Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
create_error(Error_Type::Ill_Formed_Lambda_List, arguments->sourceCodeLocation);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("this should not happen?");
|
printf("this should not happen?");
|
||||||
create_error(Error_Type_Unknown_Error, arguments->sourceCodeLocation);
|
create_error(Error_Type::Unknown_Error, arguments->sourceCodeLocation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int list_length(Ast_Node* node) {
|
int list_length(Ast_Node* node) {
|
||||||
if (node->type == Ast_Node_Type_Nil)
|
if (node->type == Ast_Node_Type::Nil)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (node->type != Ast_Node_Type_Pair) {
|
if (node->type != Ast_Node_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 == Ast_Node_Type::Pair) {
|
||||||
++len;
|
++len;
|
||||||
node = node->value.pair->rest;
|
node = node->value.pair->rest;
|
||||||
if (node->type == Ast_Node_Type_Nil)
|
if (node->type == Ast_Node_Type::Nil)
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
create_error(Error_Type_Ill_Formed_List, node->sourceCodeLocation);
|
create_error(Error_Type::Ill_Formed_List, node->sourceCodeLocation);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,27 +333,27 @@ Ast_Node* extract_keyword_value(char* keyword, Parsed_Arguments* args) {
|
|||||||
|
|
||||||
Ast_Node* eval_arguments(Ast_Node* arguments, Environment* env, int *out_arguments_length) {
|
Ast_Node* eval_arguments(Ast_Node* arguments, Environment* env, int *out_arguments_length) {
|
||||||
*out_arguments_length = 0;
|
*out_arguments_length = 0;
|
||||||
if (arguments->type == Ast_Node_Type_Nil) {
|
if (arguments->type == Ast_Node_Type::Nil) {
|
||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node* evaluated_arguments = create_ast_node_pair(nullptr, nullptr);
|
Ast_Node* evaluated_arguments = create_ast_node_pair(nullptr, nullptr);
|
||||||
Ast_Node* evaluated_arguments_head = evaluated_arguments;
|
Ast_Node* evaluated_arguments_head = evaluated_arguments;
|
||||||
Ast_Node* current_head = arguments;
|
Ast_Node* current_head = arguments;
|
||||||
while (current_head->type == Ast_Node_Type_Pair) {
|
while (current_head->type == Ast_Node_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 == Ast_Node_Type::Pair) {
|
||||||
evaluated_arguments_head->value.pair->rest = create_ast_node_pair(nullptr, nullptr);
|
evaluated_arguments_head->value.pair->rest = create_ast_node_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 == Ast_Node_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);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
++(*out_arguments_length);
|
++(*out_arguments_length);
|
||||||
@@ -372,24 +372,24 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
|
|||||||
|
|
||||||
Ast_Node* ret = new(Ast_Node);
|
Ast_Node* ret = new(Ast_Node);
|
||||||
switch (node->type) {
|
switch (node->type) {
|
||||||
case Ast_Node_Type_T:
|
case Ast_Node_Type::T:
|
||||||
case Ast_Node_Type_Nil:
|
case Ast_Node_Type::Nil:
|
||||||
return node;
|
return node;
|
||||||
case Ast_Node_Type_Symbol: {
|
case Ast_Node_Type::Symbol: {
|
||||||
Ast_Node* symbol;
|
Ast_Node* symbol;
|
||||||
try {
|
try {
|
||||||
symbol = lookup_symbol(node, env);
|
symbol = lookup_symbol(node, env);
|
||||||
}
|
}
|
||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
case Ast_Node_Type_Number:
|
case Ast_Node_Type::Number:
|
||||||
case Ast_Node_Type_Keyword:
|
case Ast_Node_Type::Keyword:
|
||||||
case Ast_Node_Type_String:
|
case Ast_Node_Type::String:
|
||||||
return node;
|
return node;
|
||||||
case Ast_Node_Type_Pair: {
|
case Ast_Node_Type::Pair: {
|
||||||
Ast_Node* lispOperator;
|
Ast_Node* lispOperator;
|
||||||
if (node->value.pair->first->type != Ast_Node_Type_CFunction &&
|
if (node->value.pair->first->type != Ast_Node_Type::CFunction &&
|
||||||
node->value.pair->first->type != Ast_Node_Type_Function)
|
node->value.pair->first->type != Ast_Node_Type::Function)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
lispOperator = eval_expr(node->value.pair->first, env);
|
lispOperator = eval_expr(node->value.pair->first, env);
|
||||||
@@ -402,13 +402,13 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
|
|||||||
int arguments_length;
|
int arguments_length;
|
||||||
|
|
||||||
// check for c function
|
// check for c function
|
||||||
if (lispOperator->type == Ast_Node_Type_CFunction) {
|
if (lispOperator->type == Ast_Node_Type::CFunction) {
|
||||||
Ast_Node* result = lispOperator->value.cfunction->function(arguments, env);
|
Ast_Node* result = lispOperator->value.cfunction->function(arguments, env);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for list function
|
// check for list function
|
||||||
if (lispOperator->type == Ast_Node_Type_Function) {
|
if (lispOperator->type == Ast_Node_Type::Function) {
|
||||||
if (!lispOperator->value.function->is_macro) {
|
if (!lispOperator->value.function->is_macro) {
|
||||||
try {
|
try {
|
||||||
arguments = eval_arguments(arguments, env, &arguments_length);
|
arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
@@ -426,7 +426,7 @@ Ast_Node* eval_expr(Ast_Node* node, Environment* env) {
|
|||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
__debugbreak();
|
__debugbreak();
|
||||||
#endif
|
#endif
|
||||||
report_error(Error_Type_Not_A_Function);
|
report_error(Error_Type::Not_A_Function);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#undef report_error
|
#undef report_error
|
||||||
@@ -437,7 +437,7 @@ bool is_truthy (Ast_Node* expression, Environment* env) {
|
|||||||
try {
|
try {
|
||||||
result = eval_expr(expression, env);
|
result = eval_expr(expression, env);
|
||||||
}
|
}
|
||||||
if (result->type == Ast_Node_Type_Nil)
|
if (result->type == Ast_Node_Type::Nil)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|||||||
+4
-9
@@ -27,11 +27,11 @@
|
|||||||
|
|
||||||
|
|
||||||
#define define_array_list(type, name) \
|
#define define_array_list(type, name) \
|
||||||
typedef struct { \
|
struct name##_Array_List { \
|
||||||
type* data; \
|
type* data; \
|
||||||
int length; \
|
int length; \
|
||||||
int next_index; \
|
int next_index; \
|
||||||
} name##_Array_List; \
|
}; \
|
||||||
\
|
\
|
||||||
\
|
\
|
||||||
void append_to_##name##_array_list(name##_Array_List* arraylist, type element) { \
|
void append_to_##name##_array_list(name##_Array_List* arraylist, type element) { \
|
||||||
@@ -55,8 +55,6 @@
|
|||||||
define_array_list(char*, String);
|
define_array_list(char*, String);
|
||||||
|
|
||||||
|
|
||||||
//typedef enum { false, true } bool;
|
|
||||||
|
|
||||||
int string_equal(char* a, char* b) {
|
int string_equal(char* a, char* b) {
|
||||||
return !strcmp(a, b);
|
return !strcmp(a, b);
|
||||||
}
|
}
|
||||||
@@ -99,9 +97,6 @@ static char get_nibble(char c) {
|
|||||||
return (c - '0');
|
return (c - '0');
|
||||||
}
|
}
|
||||||
|
|
||||||
#define true 1
|
|
||||||
#define false 0
|
|
||||||
#define bool char
|
|
||||||
bool unescape_string(char* in) {
|
bool unescape_string(char* in) {
|
||||||
if (!in)
|
if (!in)
|
||||||
return true;
|
return true;
|
||||||
@@ -278,11 +273,11 @@ char* read_line() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
struct Source_Code_Location {
|
||||||
char* file;
|
char* file;
|
||||||
int line;
|
int line;
|
||||||
int column;
|
int column;
|
||||||
} Source_Code_Location;
|
};
|
||||||
|
|
||||||
Source_Code_Location* create_source_code_location(char* file, int line, int col) {
|
Source_Code_Location* create_source_code_location(char* file, int line, int col) {
|
||||||
if (!file)
|
if (!file)
|
||||||
|
|||||||
+28
-30
@@ -1,24 +1,22 @@
|
|||||||
/* #define console_normal "\x1B[0m" */
|
// #define console_normal "\x1B[0m"
|
||||||
/* #define console_red "\x1B[31m" */
|
// #define console_red "\x1B[31m"
|
||||||
/* #define console_green "\x1B[32m" */
|
// #define console_green "\x1B[32m"
|
||||||
/* #define console_cyan "\x1B[36m" */
|
// #define console_cyan "\x1B[36m"
|
||||||
|
|
||||||
#define console_normal ""
|
#define console_normal ""
|
||||||
#define console_red ""
|
#define console_red ""
|
||||||
#define console_green ""
|
#define console_green ""
|
||||||
#define console_cyan ""
|
#define console_cyan ""
|
||||||
|
|
||||||
|
enum struct Log_Level {
|
||||||
|
None,
|
||||||
|
Critical,
|
||||||
|
Warning,
|
||||||
|
Info,
|
||||||
|
Debug,
|
||||||
|
};
|
||||||
|
|
||||||
typedef enum {
|
Log_Level log_level = Log_Level::Debug;
|
||||||
Log_Level_None,
|
|
||||||
|
|
||||||
Log_Level_Critical,
|
|
||||||
Log_Level_Warning,
|
|
||||||
Log_Level_Info,
|
|
||||||
Log_Level_Debug,
|
|
||||||
} Log_Level;
|
|
||||||
|
|
||||||
Log_Level log_level = Log_Level_Debug;
|
|
||||||
|
|
||||||
void log_message(Log_Level type, char* message) {
|
void log_message(Log_Level type, char* message) {
|
||||||
if (type > log_level)
|
if (type > log_level)
|
||||||
@@ -26,50 +24,50 @@ void log_message(Log_Level type, char* message) {
|
|||||||
|
|
||||||
char* prefix;
|
char* prefix;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Log_Level_Critical: prefix = "CRITICAL"; break;
|
case Log_Level::Critical: prefix = "CRITICAL"; break;
|
||||||
case Log_Level_Warning: prefix = "WARNING"; break;
|
case Log_Level::Warning: prefix = "WARNING"; break;
|
||||||
case Log_Level_Info: prefix = "INFO"; break;
|
case Log_Level::Info: prefix = "INFO"; break;
|
||||||
case Log_Level_Debug: prefix = "DEBUG"; break;
|
case Log_Level::Debug: prefix = "DEBUG"; break;
|
||||||
default: return;
|
default: return;
|
||||||
}
|
}
|
||||||
printf("%s: %s\n",prefix, message);
|
printf("%s: %s\n",prefix, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void panic(char* message) {
|
void panic(char* message) {
|
||||||
log_message(Log_Level_Critical, message);
|
log_message(Log_Level::Critical, message);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void print(Ast_Node* node) {
|
void print(Ast_Node* node) {
|
||||||
switch (node->type) {
|
switch (node->type) {
|
||||||
case (Ast_Node_Type_Nil): {
|
case (Ast_Node_Type::Nil): {
|
||||||
printf("nil");
|
printf("nil");
|
||||||
} break;
|
} break;
|
||||||
case (Ast_Node_Type_T): {
|
case (Ast_Node_Type::T): {
|
||||||
printf("t");
|
printf("t");
|
||||||
} break;
|
} break;
|
||||||
case (Ast_Node_Type_Number): {
|
case (Ast_Node_Type::Number): {
|
||||||
printf("%f", node->value.number->value);
|
printf("%f", node->value.number->value);
|
||||||
} break;
|
} break;
|
||||||
case (Ast_Node_Type_String): {
|
case (Ast_Node_Type::String): {
|
||||||
printf("%s", node->value.string->value);
|
printf("%s", node->value.string->value);
|
||||||
} break;
|
} break;
|
||||||
case (Ast_Node_Type_Symbol): {
|
case (Ast_Node_Type::Symbol): {
|
||||||
printf("%s", node->value.symbol->identifier);
|
printf("%s", node->value.symbol->identifier);
|
||||||
} break;
|
} break;
|
||||||
case (Ast_Node_Type_Keyword): {
|
case (Ast_Node_Type::Keyword): {
|
||||||
printf(":%s", node->value.keyword->identifier);
|
printf(":%s", node->value.keyword->identifier);
|
||||||
} break;
|
} break;
|
||||||
case (Ast_Node_Type_Function): {
|
case (Ast_Node_Type::Function): {
|
||||||
if (node->value.function->is_macro)
|
if (node->value.function->is_macro)
|
||||||
printf("[macro]");
|
printf("[macro]");
|
||||||
else
|
else
|
||||||
printf("[lambda]");
|
printf("[lambda]");
|
||||||
} break;
|
} break;
|
||||||
case (Ast_Node_Type_CFunction): {
|
case (Ast_Node_Type::CFunction): {
|
||||||
printf("[C-function]");
|
printf("[C-function]");
|
||||||
} break;
|
} break;
|
||||||
case (Ast_Node_Type_Pair): {
|
case (Ast_Node_Type::Pair): {
|
||||||
Ast_Node* head = node;
|
Ast_Node* head = node;
|
||||||
printf("(");
|
printf("(");
|
||||||
|
|
||||||
@@ -81,12 +79,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 != Ast_Node_Type::Pair)
|
||||||
break;
|
break;
|
||||||
printf(" ");
|
printf(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (head->type != Ast_Node_Type_Nil) {
|
if (head->type != Ast_Node_Type::Nil) {
|
||||||
printf(" . ");
|
printf(" . ");
|
||||||
print(head);
|
print(head);
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -22,7 +22,7 @@
|
|||||||
Ast_Node* interprete_file (char* file_name) {
|
Ast_Node* 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ast_Node_Array_List* program;
|
Ast_Node_Array_List* program;
|
||||||
@@ -30,7 +30,7 @@ Ast_Node* interprete_file (char* file_name) {
|
|||||||
program = parse_program(file_name, file_content);
|
program = parse_program(file_name, file_content);
|
||||||
}
|
}
|
||||||
|
|
||||||
Environment* env = create_empty_environment(Environment_Type_Let);
|
Environment* env = create_empty_environment(Environment_Type::Let);
|
||||||
load_built_ins_into_environment(env);
|
load_built_ins_into_environment(env);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -50,7 +50,7 @@ Ast_Node* interprete_file (char* file_name) {
|
|||||||
int interprete_stdin () {
|
int interprete_stdin () {
|
||||||
printf("Welcome to the lispy interpreter.\n");
|
printf("Welcome to the lispy interpreter.\n");
|
||||||
char* line;
|
char* line;
|
||||||
Environment* env = create_empty_environment(Environment_Type_Let);
|
Environment* env = create_empty_environment(Environment_Type::Let);
|
||||||
load_built_ins_into_environment(env);
|
load_built_ins_into_environment(env);
|
||||||
|
|
||||||
built_in_load("pre.slime", env);
|
built_in_load("pre.slime", env);
|
||||||
|
|||||||
+6
-6
@@ -161,7 +161,7 @@ Ast_Node* parse_string(char* text, int* index_in_text) {
|
|||||||
|
|
||||||
if (!unescape_string(text+(*index_in_text))) {
|
if (!unescape_string(text+(*index_in_text))) {
|
||||||
create_error(
|
create_error(
|
||||||
Error_Type_Unknown_Error,
|
Error_Type::Unknown_Error,
|
||||||
create_source_code_location(parser_file, parser_line, parser_col));
|
create_source_code_location(parser_file, parser_line, parser_col));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -243,7 +243,7 @@ Ast_Node* parse_expression(char* text, int* index_in_text) {
|
|||||||
|
|
||||||
// okay there is something
|
// okay there is something
|
||||||
Ast_Node* head = new(Ast_Node);
|
Ast_Node* head = new(Ast_Node);
|
||||||
head->type = Ast_Node_Type_Pair;
|
head->type = Ast_Node_Type::Pair;
|
||||||
head->value.pair = new(Pair);
|
head->value.pair = new(Pair);
|
||||||
Ast_Node* expression = head;
|
Ast_Node* expression = head;
|
||||||
|
|
||||||
@@ -260,7 +260,7 @@ Ast_Node* parse_expression(char* text, int* index_in_text) {
|
|||||||
|
|
||||||
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') {
|
||||||
create_error(Error_Type_Unexpected_Eof, create_source_code_location(parser_file, parser_line, parser_col));
|
create_error(Error_Type::Unexpected_Eof, create_source_code_location(parser_file, parser_line, parser_col));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -283,7 +283,7 @@ Ast_Node* parse_expression(char* text, int* index_in_text) {
|
|||||||
eat_until_code(text, index_in_text);
|
eat_until_code(text, index_in_text);
|
||||||
|
|
||||||
if (text[(*index_in_text)] != ')')
|
if (text[(*index_in_text)] != ')')
|
||||||
create_error(Error_Type_Syntax_Error, create_source_code_location(parser_file, parser_line, parser_col));
|
create_error(Error_Type::Syntax_Error, create_source_code_location(parser_file, parser_line, parser_col));
|
||||||
++parser_col;
|
++parser_col;
|
||||||
++(*index_in_text);
|
++(*index_in_text);
|
||||||
break;
|
break;
|
||||||
@@ -316,7 +316,7 @@ Ast_Node* parse_single_expression(char* text) {
|
|||||||
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 result;
|
return result;
|
||||||
create_error(Error_Type_Trailing_Garbage, create_source_code_location(parser_file, parser_line, parser_col));
|
create_error(Error_Type::Trailing_Garbage, create_source_code_location(parser_file, parser_line, parser_col));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -348,7 +348,7 @@ Ast_Node_Array_List* parse_program(char* file_name, char* text) {
|
|||||||
} break;
|
} break;
|
||||||
default:
|
default:
|
||||||
/* syntax error */
|
/* syntax error */
|
||||||
create_error(Error_Type_Syntax_Error, create_source_code_location(parser_file, parser_line, parser_col));
|
create_error(Error_Type::Syntax_Error, create_source_code_location(parser_file, parser_line, parser_col));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+42
-42
@@ -94,26 +94,26 @@ testresult test_eval_operands() {
|
|||||||
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, Ast_Node_Type::Pair);
|
||||||
assert_equal_type(operands->value.pair->first, Ast_Node_Type_Number);
|
assert_equal_type(operands->value.pair->first, Ast_Node_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, Ast_Node_Type::Pair);
|
||||||
assert_equal_type(operands->value.pair->first, Ast_Node_Type_Number);
|
assert_equal_type(operands->value.pair->first, Ast_Node_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, Ast_Node_Type::Pair);
|
||||||
assert_equal_type(operands->value.pair->first, Ast_Node_Type_String);
|
assert_equal_type(operands->value.pair->first, Ast_Node_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, Ast_Node_Type::Pair);
|
||||||
assert_equal_type(operands->value.pair->first, Ast_Node_Type_Keyword);
|
assert_equal_type(operands->value.pair->first, Ast_Node_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;
|
||||||
@@ -130,46 +130,46 @@ testresult test_parse_atom() {
|
|||||||
// test numbers
|
// test numbers
|
||||||
Ast_Node* result = parse_atom(string, &index_in_text);
|
Ast_Node* result = parse_atom(string, &index_in_text);
|
||||||
|
|
||||||
assert_equal_type(result, Ast_Node_Type_Number);
|
assert_equal_type(result, Ast_Node_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 = parse_atom(string, &index_in_text);
|
result = parse_atom(string, &index_in_text);
|
||||||
assert_equal_type(result, Ast_Node_Type_Number);
|
assert_equal_type(result, Ast_Node_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 = parse_atom(string, &index_in_text);
|
result = parse_atom(string, &index_in_text);
|
||||||
assert_equal_type(result, Ast_Node_Type_String);
|
assert_equal_type(result, Ast_Node_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 = parse_atom(string, &index_in_text);
|
result = parse_atom(string, &index_in_text);
|
||||||
assert_equal_type(result, Ast_Node_Type_Keyword);
|
assert_equal_type(result, Ast_Node_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 = parse_atom(string, &index_in_text);
|
result = parse_atom(string, &index_in_text);
|
||||||
assert_equal_type(result, Ast_Node_Type_Keyword);
|
assert_equal_type(result, Ast_Node_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 = parse_atom(string, &index_in_text);
|
result = parse_atom(string, &index_in_text);
|
||||||
assert_equal_type(result, Ast_Node_Type_Symbol);
|
assert_equal_type(result, Ast_Node_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 = parse_atom(string, &index_in_text);
|
result = parse_atom(string, &index_in_text);
|
||||||
assert_equal_type(result, Ast_Node_Type_Symbol);
|
assert_equal_type(result, Ast_Node_Type::Symbol);
|
||||||
assert_equal_string(result->value.symbol->identifier, "+");
|
assert_equal_string(result->value.symbol->identifier, "+");
|
||||||
|
|
||||||
return pass;
|
return pass;
|
||||||
@@ -182,25 +182,25 @@ testresult test_parse_expression() {
|
|||||||
Ast_Node* result = parse_expression(string, &index_in_text);
|
Ast_Node* result = 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, Ast_Node_Type::Pair);
|
||||||
assert_equal_type(result->value.pair->first, Ast_Node_Type_Symbol);
|
assert_equal_type(result->value.pair->first, Ast_Node_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, Ast_Node_Type::Pair);
|
||||||
assert_equal_type(result->value.pair->first, Ast_Node_Type_Symbol);
|
assert_equal_type(result->value.pair->first, Ast_Node_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, Ast_Node_Type::Pair);
|
||||||
assert_equal_type(result->value.pair->first, Ast_Node_Type_Number);
|
assert_equal_type(result->value.pair->first, Ast_Node_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, Ast_Node_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 = parse_expression(string2, &index_in_text);
|
result = 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, Ast_Node_Type::Pair);
|
||||||
assert_equal_type(result->value.pair->first, Ast_Node_Type_Symbol);
|
assert_equal_type(result->value.pair->first, Ast_Node_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, Ast_Node_Type::Pair);
|
||||||
assert_equal_type(result->value.pair->first, Ast_Node_Type_Symbol);
|
assert_equal_type(result->value.pair->first, Ast_Node_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, Ast_Node_Type::Pair);
|
||||||
assert_equal_type(result->value.pair->first, Ast_Node_Type_Pair);
|
assert_equal_type(result->value.pair->first, Ast_Node_Type::Pair);
|
||||||
assert_equal_type(result->value.pair->first->value.pair->first, Ast_Node_Type_Symbol);
|
assert_equal_type(result->value.pair->first->value.pair->first, Ast_Node_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;
|
||||||
@@ -237,7 +237,7 @@ testresult test_built_in_add() {
|
|||||||
|
|
||||||
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, Ast_Node_Type::Number);
|
||||||
assert_equal_double(result->value.number->value, 14);
|
assert_equal_double(result->value.number->value, 14);
|
||||||
|
|
||||||
return pass;
|
return pass;
|
||||||
@@ -250,7 +250,7 @@ testresult test_built_in_substract() {
|
|||||||
|
|
||||||
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, Ast_Node_Type::Number);
|
||||||
assert_equal_double(result->value.number->value, 6);
|
assert_equal_double(result->value.number->value, 6);
|
||||||
|
|
||||||
return pass;
|
return pass;
|
||||||
@@ -264,7 +264,7 @@ testresult test_built_in_multiply() {
|
|||||||
|
|
||||||
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, Ast_Node_Type::Number);
|
||||||
assert_equal_double(result->value.number->value, 40);
|
assert_equal_double(result->value.number->value, 40);
|
||||||
|
|
||||||
return pass;
|
return pass;
|
||||||
@@ -278,7 +278,7 @@ testresult test_built_in_divide() {
|
|||||||
|
|
||||||
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, Ast_Node_Type::Number);
|
||||||
assert_equal_double(result->value.number->value, 5);
|
assert_equal_double(result->value.number->value, 5);
|
||||||
|
|
||||||
return pass;
|
return pass;
|
||||||
@@ -292,7 +292,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, Ast_Node_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, Ast_Node_Type::Number);
|
||||||
assert_equal_double(result->value.number->value, 5);
|
assert_equal_double(result->value.number->value, 5);
|
||||||
|
|
||||||
return pass;
|
return pass;
|
||||||
@@ -314,7 +314,7 @@ 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_T);
|
assert_equal_type(result, Ast_Node_Type::T);
|
||||||
|
|
||||||
// a false case
|
// a false case
|
||||||
char exp_string2[] = "(and () \"asd\" 4)";
|
char exp_string2[] = "(and () \"asd\" 4)";
|
||||||
@@ -323,7 +323,7 @@ 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, Ast_Node_Type::Nil);
|
||||||
|
|
||||||
return pass;
|
return pass;
|
||||||
}
|
}
|
||||||
@@ -335,7 +335,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_T);
|
assert_equal_type(result, Ast_Node_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, Ast_Node_Type::Nil);
|
||||||
|
|
||||||
return pass;
|
return pass;
|
||||||
}
|
}
|
||||||
@@ -358,7 +358,7 @@ testresult test_built_in_not() {
|
|||||||
// 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, Ast_Node_Type::T);
|
||||||
|
|
||||||
// a false case
|
// a false case
|
||||||
char exp_string2[] = "(not \"asd xD\")";
|
char exp_string2[] = "(not \"asd xD\")";
|
||||||
@@ -367,13 +367,13 @@ 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, Ast_Node_Type::Nil);
|
||||||
|
|
||||||
return pass;
|
return pass;
|
||||||
}
|
}
|
||||||
|
|
||||||
void run_all_tests() {
|
void run_all_tests() {
|
||||||
log_level = Log_Level_None;
|
log_level = Log_Level::None;
|
||||||
|
|
||||||
printf("-- Parsing --\n");
|
printf("-- Parsing --\n");
|
||||||
invoke_test(test_parse_atom);
|
invoke_test(test_parse_atom);
|
||||||
|
|||||||
Reference in New Issue
Block a user