cleanup
This commit is contained in:
@@ -1,22 +0,0 @@
|
|||||||
ACME_MODULE(
|
|
||||||
#==========================================================================
|
|
||||||
# general module information
|
|
||||||
#==========================================================================
|
|
||||||
NAME TSE_LispIntegration
|
|
||||||
TYPE LIBRARY
|
|
||||||
|
|
||||||
#==========================================================================
|
|
||||||
# files of this module
|
|
||||||
#==========================================================================
|
|
||||||
INCLUDE_BASE src
|
|
||||||
bin
|
|
||||||
FILES_PRIVATE_HEADER src/*.h
|
|
||||||
FILES_SOURCE src/main.cpp
|
|
||||||
#DEPENDENCIES TSE_Engine
|
|
||||||
)
|
|
||||||
|
|
||||||
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/bin/pre.slime
|
|
||||||
DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
|
|
||||||
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/bin/test.slime
|
|
||||||
DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
|
|
||||||
Binary file not shown.
@@ -1,9 +0,0 @@
|
|||||||
@echo off
|
|
||||||
pushd %~dp0\bin
|
|
||||||
|
|
||||||
call ..\build.bat
|
|
||||||
if %errorlevel% == 0 (
|
|
||||||
echo ---------- Running ----------
|
|
||||||
call timecmd slime.exe
|
|
||||||
)
|
|
||||||
popd
|
|
||||||
+14
-14
@@ -1,4 +1,4 @@
|
|||||||
bool lisp_object_equal(Lisp_Object* n1, Lisp_Object* n2) {
|
proc lisp_object_equal(Lisp_Object* n1, Lisp_Object* n2) -> bool {
|
||||||
if (n1 == n2)
|
if (n1 == n2)
|
||||||
return true;
|
return true;
|
||||||
if (n1->type != n2->type)
|
if (n1->type != n2->type)
|
||||||
@@ -42,7 +42,7 @@ bool lisp_object_equal(Lisp_Object* n1, Lisp_Object* n2) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* built_in_equals(Lisp_Object* arguments, Environment* env) {
|
proc built_in_equals(Lisp_Object* arguments, Environment* env) -> Lisp_Object* {
|
||||||
int arguments_length;
|
int arguments_length;
|
||||||
try {
|
try {
|
||||||
arguments = eval_arguments(arguments, env, &arguments_length);
|
arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
@@ -62,7 +62,7 @@ Lisp_Object* built_in_equals(Lisp_Object* arguments, Environment* env) {
|
|||||||
return Memory::create_lisp_object_t();
|
return Memory::create_lisp_object_t();
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* built_in_greater(Lisp_Object* arguments, Environment* env) {
|
proc built_in_greater(Lisp_Object* arguments, Environment* env) -> Lisp_Object* {
|
||||||
int arguments_length;
|
int arguments_length;
|
||||||
try {
|
try {
|
||||||
arguments = eval_arguments(arguments, env, &arguments_length);
|
arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
@@ -85,7 +85,7 @@ Lisp_Object* built_in_greater(Lisp_Object* arguments, Environment* env) {
|
|||||||
return Memory::create_lisp_object_t();
|
return Memory::create_lisp_object_t();
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* built_in_greater_equal(Lisp_Object* arguments, Environment* env) {
|
proc built_in_greater_equal(Lisp_Object* arguments, Environment* env) -> Lisp_Object* {
|
||||||
int arguments_length;
|
int arguments_length;
|
||||||
try {
|
try {
|
||||||
arguments = eval_arguments(arguments, env, &arguments_length);
|
arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
@@ -108,7 +108,7 @@ Lisp_Object* built_in_greater_equal(Lisp_Object* arguments, Environment* env) {
|
|||||||
return Memory::create_lisp_object_t();
|
return Memory::create_lisp_object_t();
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* built_in_less(Lisp_Object* arguments, Environment* env) {
|
proc built_in_less(Lisp_Object* arguments, Environment* env) -> Lisp_Object* {
|
||||||
int arguments_length;
|
int arguments_length;
|
||||||
try {
|
try {
|
||||||
arguments = eval_arguments(arguments, env, &arguments_length);
|
arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
@@ -131,7 +131,7 @@ Lisp_Object* built_in_less(Lisp_Object* arguments, Environment* env) {
|
|||||||
return Memory::create_lisp_object_t();
|
return Memory::create_lisp_object_t();
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* built_in_less_equal(Lisp_Object* arguments, Environment* env) {
|
proc built_in_less_equal(Lisp_Object* arguments, Environment* env) -> Lisp_Object* {
|
||||||
int arguments_length;
|
int arguments_length;
|
||||||
try {
|
try {
|
||||||
arguments = eval_arguments(arguments, env, &arguments_length);
|
arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
@@ -154,7 +154,7 @@ Lisp_Object* built_in_less_equal(Lisp_Object* arguments, Environment* env) {
|
|||||||
return Memory::create_lisp_object_t();
|
return Memory::create_lisp_object_t();
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* built_in_add(Lisp_Object* arguments, Environment* env) {
|
proc built_in_add(Lisp_Object* arguments, Environment* env) -> Lisp_Object* {
|
||||||
int arguments_length;
|
int arguments_length;
|
||||||
try {
|
try {
|
||||||
arguments = eval_arguments(arguments, env, &arguments_length);
|
arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
@@ -172,7 +172,7 @@ Lisp_Object* built_in_add(Lisp_Object* arguments, Environment* env) {
|
|||||||
return Memory::create_lisp_object_number(sum);
|
return Memory::create_lisp_object_number(sum);
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* built_in_substract(Lisp_Object* arguments, Environment* env) {
|
proc built_in_substract(Lisp_Object* arguments, Environment* env) -> Lisp_Object* {
|
||||||
int arguments_length;
|
int arguments_length;
|
||||||
try {
|
try {
|
||||||
arguments = eval_arguments(arguments, env, &arguments_length);
|
arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
@@ -195,7 +195,7 @@ Lisp_Object* built_in_substract(Lisp_Object* arguments, Environment* env) {
|
|||||||
return Memory::create_lisp_object_number(difference);
|
return Memory::create_lisp_object_number(difference);
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* built_in_multiply(Lisp_Object* arguments, Environment* env) {
|
proc built_in_multiply(Lisp_Object* arguments, Environment* env) -> Lisp_Object* {
|
||||||
int arguments_length;
|
int arguments_length;
|
||||||
try {
|
try {
|
||||||
arguments = eval_arguments(arguments, env, &arguments_length);
|
arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
@@ -218,7 +218,7 @@ Lisp_Object* built_in_multiply(Lisp_Object* arguments, Environment* env) {
|
|||||||
return Memory::create_lisp_object_number(product);
|
return Memory::create_lisp_object_number(product);
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* built_in_divide(Lisp_Object* arguments, Environment* env) {
|
proc built_in_divide(Lisp_Object* arguments, Environment* env) -> Lisp_Object* {
|
||||||
int arguments_length;
|
int arguments_length;
|
||||||
try {
|
try {
|
||||||
arguments = eval_arguments(arguments, env, &arguments_length);
|
arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
@@ -241,7 +241,7 @@ Lisp_Object* built_in_divide(Lisp_Object* arguments, Environment* env) {
|
|||||||
return Memory::create_lisp_object_number(quotient);
|
return Memory::create_lisp_object_number(quotient);
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* built_in_exponentiate(Lisp_Object* arguments, Environment* env) {
|
proc built_in_exponentiate(Lisp_Object* arguments, Environment* env) -> Lisp_Object* {
|
||||||
int arguments_length;
|
int arguments_length;
|
||||||
try {
|
try {
|
||||||
arguments = eval_arguments(arguments, env, &arguments_length);
|
arguments = eval_arguments(arguments, env, &arguments_length);
|
||||||
@@ -270,7 +270,7 @@ Lisp_Object* built_in_exponentiate(Lisp_Object* arguments, Environment* env) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Lisp_Object* built_in_load(char* file_name, Environment* env) {
|
proc built_in_load(char* file_name, Environment* env) -> Lisp_Object* {
|
||||||
char* file_content = read_entire_file(file_name);
|
char* file_content = read_entire_file(file_name);
|
||||||
if (file_content) {
|
if (file_content) {
|
||||||
Lisp_Object* result = Memory::create_lisp_object_nil();
|
Lisp_Object* result = Memory::create_lisp_object_nil();
|
||||||
@@ -290,7 +290,7 @@ Lisp_Object* built_in_load(char* file_name, Environment* env) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void load_built_ins_into_environment(Environment* env) {
|
proc load_built_ins_into_environment(Environment* env) -> void {
|
||||||
int arguments_length;
|
int arguments_length;
|
||||||
Lisp_Object* evaluated_arguments;
|
Lisp_Object* evaluated_arguments;
|
||||||
|
|
||||||
@@ -300,7 +300,7 @@ void load_built_ins_into_environment(Environment* env) {
|
|||||||
return nullptr; \
|
return nullptr; \
|
||||||
}
|
}
|
||||||
|
|
||||||
auto defun = [&](char* name, std::function<Lisp_Object*(Lisp_Object*, Environment*)> fun) {
|
proc defun = [&](char* name, std::function<Lisp_Object*(Lisp_Object*, Environment*)> fun) {
|
||||||
define_symbol(
|
define_symbol(
|
||||||
Memory::create_lisp_object_symbol(name),
|
Memory::create_lisp_object_symbol(name),
|
||||||
Memory::create_lisp_object_cfunction(fun),
|
Memory::create_lisp_object_cfunction(fun),
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
#define new(type) new type
|
||||||
|
#define proc auto
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
constexpr bool is_debug_build = true;
|
||||||
|
#else
|
||||||
|
constexpr bool is_debug_build = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define if_debug if constexpr (is_debug_build)
|
||||||
|
|
||||||
|
#define assert(cond) \
|
||||||
|
if_debug { \
|
||||||
|
if (!cond) { \
|
||||||
|
printf("Assertion failed: %s %d", __FILE__, __LINE__); \
|
||||||
|
__debugbreak(); \
|
||||||
|
} \
|
||||||
|
} else {} \
|
||||||
|
|
||||||
|
|
||||||
|
#define concat_( a, b) a##b
|
||||||
|
#define label(prefix, lnum) concat_(prefix,lnum)
|
||||||
|
#define try \
|
||||||
|
if (1) \
|
||||||
|
goto label(body,__LINE__); \
|
||||||
|
else \
|
||||||
|
while (1) \
|
||||||
|
if (1) { \
|
||||||
|
if(error) return 0; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
else label(body,__LINE__):
|
||||||
|
|
||||||
|
#define try_void \
|
||||||
|
if (1) \
|
||||||
|
goto label(body,__LINE__); \
|
||||||
|
else \
|
||||||
|
while (1) \
|
||||||
|
if (1) { \
|
||||||
|
if(error) return; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
else label(body,__LINE__):
|
||||||
|
|
||||||
|
|
||||||
|
#define define_array_list(type, name) \
|
||||||
|
struct name##_Array_List { \
|
||||||
|
type* data; \
|
||||||
|
int length; \
|
||||||
|
int next_index; \
|
||||||
|
}; \
|
||||||
|
\
|
||||||
|
\
|
||||||
|
proc append_to_##name##_array_list(name##_Array_List* arraylist, type element) -> void { \
|
||||||
|
if (arraylist->next_index == arraylist->length) { \
|
||||||
|
arraylist->length *= 2; \
|
||||||
|
arraylist->data = \
|
||||||
|
(type*)realloc(arraylist->data, arraylist->length * sizeof(type)); \
|
||||||
|
} \
|
||||||
|
arraylist->data[arraylist->next_index++] = element; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
\
|
||||||
|
proc create_##name##_array_list(int initial_capacity = 16) -> name##_Array_List* { \
|
||||||
|
name##_Array_List* ret = new(name##_Array_List); \
|
||||||
|
ret->data = (type*)malloc(initial_capacity * sizeof(type)); \
|
||||||
|
ret->next_index = 0; \
|
||||||
|
ret->length = initial_capacity; \
|
||||||
|
return ret; \
|
||||||
|
}
|
||||||
|
|
||||||
|
// #define console_normal "\x1B[0m"
|
||||||
|
// #define console_red "\x1B[31m"
|
||||||
|
// #define console_green "\x1B[32m"
|
||||||
|
// #define console_cyan "\x1B[36m"
|
||||||
|
#define console_normal ""
|
||||||
|
#define console_red ""
|
||||||
|
#define console_green ""
|
||||||
|
#define console_cyan ""
|
||||||
+7
-8
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
void define_symbol(Lisp_Object* symbol, Lisp_Object* value, Environment* env) {
|
proc define_symbol(Lisp_Object* symbol, Lisp_Object* value, Environment* env) -> void {
|
||||||
// NOTE(Felix): right now we are simply adding the symol at the
|
// NOTE(Felix): right now we are simply adding the symol at the
|
||||||
// back of the list without checking if it already exists but are
|
// back of the list without checking if it already exists but are
|
||||||
// also searching for thesymbol from the back, so we will find the
|
// also searching for thesymbol from the back, so we will find the
|
||||||
@@ -16,16 +16,14 @@ void define_symbol(Lisp_Object* symbol, Lisp_Object* value, Environment* env) {
|
|||||||
++env->next_index;
|
++env->next_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_environment(Environment* env);
|
proc lookup_symbol_in_this_envt(Symbol* sym, Environment* env) -> Lisp_Object* {
|
||||||
|
|
||||||
Lisp_Object* lookup_symbol_in_this_envt(Symbol* sym, Environment* env) {
|
|
||||||
for (int i = env->next_index - 1; i >= 0; --i)
|
for (int i = env->next_index - 1; i >= 0; --i)
|
||||||
if (string_equal(env->keys[i], sym->identifier))
|
if (string_equal(env->keys[i], sym->identifier))
|
||||||
return env->values[i];
|
return env->values[i];
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* lookup_symbol(Lisp_Object* node, Environment* env) {
|
proc lookup_symbol(Lisp_Object* node, Environment* env) -> Lisp_Object* {
|
||||||
// first check current environment
|
// first check current environment
|
||||||
Symbol* sym = node->value.symbol;
|
Symbol* sym = node->value.symbol;
|
||||||
Lisp_Object* result;
|
Lisp_Object* result;
|
||||||
@@ -51,13 +49,14 @@ Lisp_Object* lookup_symbol(Lisp_Object* node, Environment* env) {
|
|||||||
printf("%s\n", sym->identifier);
|
printf("%s\n", sym->identifier);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
void print_indent(int indent) {
|
|
||||||
|
proc print_indent(int indent) -> void {
|
||||||
for (int i = 0; i < indent; ++i) {
|
for (int i = 0; i < indent; ++i) {
|
||||||
printf(" ");
|
printf(" ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_environment_indent(Environment* env, int indent) {
|
proc print_environment_indent(Environment* env, int indent) -> void {
|
||||||
for (int i = 0; i < env->next_index; ++i) {
|
for (int i = 0; i < env->next_index; ++i) {
|
||||||
print_indent(indent);
|
print_indent(indent);
|
||||||
print(env->values[i]);
|
print(env->values[i]);
|
||||||
@@ -72,7 +71,7 @@ void print_environment_indent(Environment* env, int indent) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_environment(Environment* env) {
|
proc print_environment(Environment* env) -> void {
|
||||||
printf("\n=== Environment ===\n");
|
printf("\n=== Environment ===\n");
|
||||||
print_environment_indent(env, 0);
|
print_environment_indent(env, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-4
@@ -1,21 +1,23 @@
|
|||||||
Error* error;
|
Error* error;
|
||||||
|
|
||||||
void delete_error() {
|
proc delete_error() -> void {
|
||||||
if (error) {
|
if (error) {
|
||||||
free(error);
|
free(error);
|
||||||
error = nullptr;
|
error = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void create_error(Error_Type type, Source_Code_Location* location) {
|
proc create_error(Error_Type type, Source_Code_Location* location) -> void {
|
||||||
delete_error();
|
delete_error();
|
||||||
|
if_debug {
|
||||||
__debugbreak();
|
__debugbreak();
|
||||||
|
}
|
||||||
error = new(Error);
|
error = new(Error);
|
||||||
error->type = type;
|
error->type = type;
|
||||||
error->location = location;
|
error->location = location;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* Error_Type_to_string(Error_Type type) {
|
proc Error_Type_to_string(Error_Type type) -> char* {
|
||||||
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";
|
||||||
@@ -35,7 +37,7 @@ char* Error_Type_to_string(Error_Type type) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void assert_type(Lisp_Object* node, Lisp_Object_Type type) {
|
proc assert_type(Lisp_Object* node, Lisp_Object_Type type) -> void {
|
||||||
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;
|
||||||
|
|||||||
+76
-12
@@ -1,6 +1,4 @@
|
|||||||
Lisp_Object* eval_expr(Lisp_Object*, Environment*);
|
proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) -> Lisp_Object* {
|
||||||
|
|
||||||
Lisp_Object* apply_arguments_to_function(Lisp_Object* arguments, Function* function) {
|
|
||||||
Environment* new_env = Memory::create_child_environment(function->parent_environment);
|
Environment* new_env = Memory::create_child_environment(function->parent_environment);
|
||||||
|
|
||||||
// positional arguments
|
// positional arguments
|
||||||
@@ -162,7 +160,7 @@ Lisp_Object* apply_arguments_to_function(Lisp_Object* arguments, Function* funct
|
|||||||
positional_arguments, keyword_arguments and rest_argument and
|
positional_arguments, keyword_arguments and rest_argument and
|
||||||
filling it in
|
filling it in
|
||||||
*/
|
*/
|
||||||
void parse_argument_list(Lisp_Object* arguments, Function* function) {
|
proc parse_argument_list(Lisp_Object* arguments, Function* function) -> void {
|
||||||
// first init the fields
|
// first init the fields
|
||||||
function->positional_arguments = create_positional_argument_list(16);
|
function->positional_arguments = create_positional_argument_list(16);
|
||||||
function->keyword_arguments = create_keyword_argument_list(16);
|
function->keyword_arguments = create_keyword_argument_list(16);
|
||||||
@@ -288,7 +286,7 @@ void parse_argument_list(Lisp_Object* arguments, Function* function) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int list_length(Lisp_Object* node) {
|
proc list_length(Lisp_Object* node) -> int {
|
||||||
if (node->type == Lisp_Object_Type::Nil)
|
if (node->type == Lisp_Object_Type::Nil)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -309,9 +307,7 @@ int list_length(Lisp_Object* node) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_truthy (Lisp_Object* expression, Environment* env);
|
proc extract_keyword_value(char* keyword, Parsed_Arguments* args) -> Lisp_Object* {
|
||||||
|
|
||||||
Lisp_Object* extract_keyword_value(char* keyword, Parsed_Arguments* args) {
|
|
||||||
// NOTE(Felix): This will be a hashmap lookup later
|
// NOTE(Felix): This will be a hashmap lookup later
|
||||||
for (int i = 0; i < args->keyword_keys->next_index; ++i) {
|
for (int i = 0; i < args->keyword_keys->next_index; ++i) {
|
||||||
if (string_equal(args->keyword_keys->data[i]->value.keyword->identifier, keyword))
|
if (string_equal(args->keyword_keys->data[i]->value.keyword->identifier, keyword))
|
||||||
@@ -320,7 +316,7 @@ Lisp_Object* extract_keyword_value(char* keyword, Parsed_Arguments* args) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* eval_arguments(Lisp_Object* arguments, Environment* env, int *out_arguments_length) {
|
proc eval_arguments(Lisp_Object* arguments, Environment* env, int *out_arguments_length) -> Lisp_Object* {
|
||||||
int my_out_arguments_length = 0;
|
int my_out_arguments_length = 0;
|
||||||
if (arguments->type == Lisp_Object_Type::Nil) {
|
if (arguments->type == Lisp_Object_Type::Nil) {
|
||||||
return arguments;
|
return arguments;
|
||||||
@@ -351,7 +347,7 @@ Lisp_Object* eval_arguments(Lisp_Object* arguments, Environment* env, int *out_a
|
|||||||
return evaluated_arguments;
|
return evaluated_arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* eval_expr(Lisp_Object* node, Environment* env) {
|
proc eval_expr(Lisp_Object* node, Environment* env) -> Lisp_Object* {
|
||||||
#define report_error(_type) { \
|
#define report_error(_type) { \
|
||||||
create_error(_type, node->sourceCodeLocation); \
|
create_error(_type, node->sourceCodeLocation); \
|
||||||
return nullptr; \
|
return nullptr; \
|
||||||
@@ -420,7 +416,7 @@ Lisp_Object* eval_expr(Lisp_Object* node, Environment* env) {
|
|||||||
#undef report_error
|
#undef report_error
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_truthy (Lisp_Object* expression, Environment* env) {
|
proc is_truthy (Lisp_Object* expression, Environment* env) -> bool {
|
||||||
Lisp_Object* result;
|
Lisp_Object* result;
|
||||||
try {
|
try {
|
||||||
result = eval_expr(expression, env);
|
result = eval_expr(expression, env);
|
||||||
@@ -428,5 +424,73 @@ bool is_truthy (Lisp_Object* expression, Environment* env) {
|
|||||||
if (result->type == Lisp_Object_Type::Nil)
|
if (result->type == Lisp_Object_Type::Nil)
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
proc interprete_file (char* file_name) -> Lisp_Object* {
|
||||||
|
Memory::init();
|
||||||
|
Environment* env = Memory::create_empty_environment();
|
||||||
|
Parser::init(env);
|
||||||
|
|
||||||
|
char* file_content = read_entire_file(file_name);
|
||||||
|
if (!file_content) {
|
||||||
|
create_error(Error_Type::Unknown_Error, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
load_built_ins_into_environment(env);
|
||||||
|
|
||||||
|
try {
|
||||||
|
built_in_load("pre.slime", env);
|
||||||
|
}
|
||||||
|
|
||||||
|
Lisp_Object_Array_List* program;
|
||||||
|
try {
|
||||||
|
program = Parser::parse_program(file_name, file_content);
|
||||||
|
}
|
||||||
|
|
||||||
|
Lisp_Object* result = Memory::create_lisp_object_nil();
|
||||||
|
for (int i = 0; i < program->next_index; ++i) {
|
||||||
|
try {
|
||||||
|
result = eval_expr(program->data[i], env);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
proc interprete_stdin() -> void {
|
||||||
|
Memory::init();
|
||||||
|
Environment* env = Memory::create_built_ins_environment();
|
||||||
|
Parser::init(env);
|
||||||
|
|
||||||
|
printf("Welcome to the lispy interpreter.\n");
|
||||||
|
|
||||||
|
char* line;
|
||||||
|
|
||||||
|
built_in_load("pre.slime", env);
|
||||||
|
built_in_load("test.slime", env);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
log_error();
|
||||||
|
delete_error();
|
||||||
|
}
|
||||||
|
|
||||||
|
Lisp_Object* parsed, * evaluated;
|
||||||
|
while (true) {
|
||||||
|
printf(">");
|
||||||
|
line = read_expression();
|
||||||
|
parsed = Parser::parse_single_expression(line);
|
||||||
|
if (error) {
|
||||||
|
log_error();
|
||||||
|
delete_error();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
evaluated = eval_expr(parsed, env);
|
||||||
|
if (error) {
|
||||||
|
log_error();
|
||||||
|
delete_error();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
print(evaluated);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
Lisp_Object* eval_arguments(Lisp_Object* arguments, Environment* env, int *out_arguments_length);
|
proc print_environment(Environment* env) -> void;
|
||||||
Lisp_Object* eval_expr(Lisp_Object*, Environment*);
|
proc eval_arguments(Lisp_Object* arguments, Environment* env, int *out_arguments_length) -> Lisp_Object*;
|
||||||
bool is_truthy (Lisp_Object* expression, Environment* env);
|
proc eval_expr(Lisp_Object*, Environment*) -> Lisp_Object*;
|
||||||
int list_length(Lisp_Object*);
|
proc is_truthy (Lisp_Object* expression, Environment* env) -> bool;
|
||||||
void load_built_ins_into_environment(Environment*);
|
proc list_length(Lisp_Object*) -> int;
|
||||||
void parse_argument_list(Lisp_Object*, Function*);
|
proc load_built_ins_into_environment(Environment*) -> void;
|
||||||
|
proc parse_argument_list(Lisp_Object*, Function*) -> void;
|
||||||
|
|||||||
-313
@@ -1,313 +0,0 @@
|
|||||||
#define new(type) new type
|
|
||||||
|
|
||||||
#ifdef _DEBUG
|
|
||||||
constexpr bool is_debug_build = true;
|
|
||||||
#else
|
|
||||||
constexpr bool is_debug_build = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define if_debug if constexpr (is_debug_build)
|
|
||||||
|
|
||||||
#define assert(cond) \
|
|
||||||
if_debug { \
|
|
||||||
if (!cond) { \
|
|
||||||
printf("Assertion failed: %s %d", __FILE__, __LINE__); \
|
|
||||||
__debugbreak(); \
|
|
||||||
} \
|
|
||||||
} else {} \
|
|
||||||
|
|
||||||
|
|
||||||
#define concat_( a, b) a##b
|
|
||||||
#define label(prefix, lnum) concat_(prefix,lnum)
|
|
||||||
#define try \
|
|
||||||
if (1) \
|
|
||||||
goto label(body,__LINE__); \
|
|
||||||
else \
|
|
||||||
while (1) \
|
|
||||||
if (1) { \
|
|
||||||
if(error) return 0; \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
else label(body,__LINE__):
|
|
||||||
|
|
||||||
#define try_void \
|
|
||||||
if (1) \
|
|
||||||
goto label(body,__LINE__); \
|
|
||||||
else \
|
|
||||||
while (1) \
|
|
||||||
if (1) { \
|
|
||||||
if(error) return; \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
else label(body,__LINE__):
|
|
||||||
|
|
||||||
|
|
||||||
#define define_array_list(type, name) \
|
|
||||||
struct name##_Array_List { \
|
|
||||||
type* data; \
|
|
||||||
int length; \
|
|
||||||
int next_index; \
|
|
||||||
}; \
|
|
||||||
\
|
|
||||||
\
|
|
||||||
void append_to_##name##_array_list(name##_Array_List* arraylist, type element) { \
|
|
||||||
if (arraylist->next_index == arraylist->length) { \
|
|
||||||
arraylist->length *= 2; \
|
|
||||||
arraylist->data = \
|
|
||||||
(type*)realloc(arraylist->data, arraylist->length * sizeof(type)); \
|
|
||||||
} \
|
|
||||||
arraylist->data[arraylist->next_index++] = element; \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
\
|
|
||||||
name##_Array_List* create_##name##_array_list(int initial_capacity = 16) { \
|
|
||||||
name##_Array_List* ret = new(name##_Array_List); \
|
|
||||||
ret->data = (type*)malloc(initial_capacity * sizeof(type)); \
|
|
||||||
ret->next_index = 0; \
|
|
||||||
ret->length = initial_capacity; \
|
|
||||||
return ret; \
|
|
||||||
}
|
|
||||||
|
|
||||||
int string_equal(char input[],char check[])
|
|
||||||
{
|
|
||||||
int i,result=1;
|
|
||||||
for(i=0; input[i]!='\0' || check[i]!='\0'; i++) {
|
|
||||||
if(input[i] != check[i]) {
|
|
||||||
result=0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// asprintf implementation
|
|
||||||
int _vscprintf_so(const char * format, va_list pargs) {
|
|
||||||
int retval;
|
|
||||||
va_list argcopy;
|
|
||||||
va_copy(argcopy, pargs);
|
|
||||||
retval = vsnprintf(nullptr, 0, format, argcopy);
|
|
||||||
va_end(argcopy);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
int vasprintf(char **strp, const char *fmt, va_list ap) {
|
|
||||||
int len = _vscprintf_so(fmt, ap);
|
|
||||||
if (len == -1) return -1;
|
|
||||||
char *str = (char *)malloc((size_t) len + 1);
|
|
||||||
if (!str) return -1;
|
|
||||||
int r = vsnprintf(str, len + 1, fmt, ap); /* "secure" version of vsprintf */
|
|
||||||
if (r == -1) return free(str), -1;
|
|
||||||
*strp = str;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
int asprintf(char *strp[], const char *fmt, ...) {
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
int r = vasprintf(strp, fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
// asprintf implementation end
|
|
||||||
|
|
||||||
static char get_nibble(char c) {
|
|
||||||
if (c >= 'A' && c <= 'F')
|
|
||||||
return (c - 'a') + 10;
|
|
||||||
else if (c >= 'a' && c <= 'f')
|
|
||||||
return (c - 'A') + 10;
|
|
||||||
return (c - '0');
|
|
||||||
}
|
|
||||||
|
|
||||||
bool unescape_string(char* in) {
|
|
||||||
if (!in)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
char *out = in, *p = in;
|
|
||||||
const char *int_err = nullptr;
|
|
||||||
|
|
||||||
while (*p && !int_err) {
|
|
||||||
if (*p != '\\') {
|
|
||||||
/* normal case */
|
|
||||||
*out++ = *p++;
|
|
||||||
} else {
|
|
||||||
/* escape sequence */
|
|
||||||
switch (*++p) {
|
|
||||||
case 'a': *out++ = '\a'; ++p; break;
|
|
||||||
case 'b': *out++ = '\b'; ++p; break;
|
|
||||||
case 'f': *out++ = '\f'; ++p; break;
|
|
||||||
case 'n': *out++ = '\n'; ++p; break;
|
|
||||||
case 'r': *out++ = '\r'; ++p; break;
|
|
||||||
case 't': *out++ = '\t'; ++p; break;
|
|
||||||
case 'v': *out++ = '\v'; ++p; break;
|
|
||||||
|
|
||||||
case '"':
|
|
||||||
case '\'':
|
|
||||||
case '\\':
|
|
||||||
*out++ = *p++;
|
|
||||||
case '?':
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'x':
|
|
||||||
case 'X':
|
|
||||||
if (!isxdigit(p[1]) || !isxdigit(p[2])) {
|
|
||||||
int_err = "Invalid character on hexadecimal escape.";
|
|
||||||
} else {
|
|
||||||
*out++ = (char)(get_nibble(p[1]) * 0x10 + get_nibble(p[2]));
|
|
||||||
p += 3;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
int_err = "Unexpected '\\' with no escape sequence.";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set the end of string. */
|
|
||||||
*out = '\0';
|
|
||||||
if (int_err)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* read_entire_file (char* filename) {
|
|
||||||
char *fileContent = nullptr;
|
|
||||||
FILE *fp = fopen(filename, "r");
|
|
||||||
if (fp) {
|
|
||||||
/* Go to the end of the file. */
|
|
||||||
if (fseek(fp, 0L, SEEK_END) == 0) {
|
|
||||||
/* Get the size of the file. */
|
|
||||||
long bufsize = ftell(fp);
|
|
||||||
if (bufsize == -1) {
|
|
||||||
fputs("Empty file", stderr);
|
|
||||||
goto closeFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Go back to the start of the file. */
|
|
||||||
if (fseek(fp, 0L, SEEK_SET) != 0) {
|
|
||||||
fputs("Error reading file", stderr);
|
|
||||||
goto closeFile;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate our buffer to that size. */
|
|
||||||
fileContent = (char*)calloc(bufsize, sizeof(char));
|
|
||||||
|
|
||||||
/* Read the entire file into memory. */
|
|
||||||
size_t newLen = fread(fileContent, sizeof(char), bufsize, fp);
|
|
||||||
|
|
||||||
fileContent[newLen] = '\0';
|
|
||||||
if ( ferror( fp ) != 0 ) {
|
|
||||||
fputs("Error reading file", stderr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
closeFile:
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fileContent;
|
|
||||||
/* Don't forget to call free() later! */
|
|
||||||
}
|
|
||||||
|
|
||||||
char* read_expression() {
|
|
||||||
char* line = (char*)malloc(100), * linep = line;
|
|
||||||
size_t lenmax = 100, len = lenmax;
|
|
||||||
int c;
|
|
||||||
|
|
||||||
int nesting = 0;
|
|
||||||
|
|
||||||
if(line == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
for(;;) {
|
|
||||||
c = fgetc(stdin);
|
|
||||||
if(c == EOF)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if(--len == 0) {
|
|
||||||
len = lenmax;
|
|
||||||
char * linen = (char*)realloc(linep, lenmax *= 2);
|
|
||||||
|
|
||||||
if(linen == NULL) {
|
|
||||||
free(linep);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
line = linen + (line - linep);
|
|
||||||
linep = linen;
|
|
||||||
}
|
|
||||||
|
|
||||||
*line++;
|
|
||||||
if((*line = (char)c) == '(')
|
|
||||||
++nesting;
|
|
||||||
else if((*line = (char)c) == ')')
|
|
||||||
--nesting;
|
|
||||||
else if((*line = (char)c) == '\n')
|
|
||||||
if (nesting == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
(*line)--; // we dont want the \n actually
|
|
||||||
*line = '\0';
|
|
||||||
// BUG(Felix): Why do we have to add 1 here?
|
|
||||||
return linep + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* read_line() {
|
|
||||||
char* line = (char*)malloc(100), * linep = line;
|
|
||||||
size_t lenmax = 100, len = lenmax;
|
|
||||||
int c;
|
|
||||||
|
|
||||||
int nesting = 0;
|
|
||||||
|
|
||||||
if(line == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
for(;;) {
|
|
||||||
c = fgetc(stdin);
|
|
||||||
if(c == EOF)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if(--len == 0) {
|
|
||||||
len = lenmax;
|
|
||||||
char* linen = (char*)realloc(linep, lenmax *= 2);
|
|
||||||
|
|
||||||
if(linen == NULL) {
|
|
||||||
free(linep);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
line = linen + (line - linep);
|
|
||||||
linep = linen;
|
|
||||||
}
|
|
||||||
|
|
||||||
*line++;
|
|
||||||
if((*line = (char)c) == '(')
|
|
||||||
++nesting;
|
|
||||||
else if((*line = (char)c) == ')')
|
|
||||||
--nesting;
|
|
||||||
else if((*line = (char)c) == '\n')
|
|
||||||
if (nesting == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
(*line)--; // we dont want the \n actually
|
|
||||||
*line = '\0';
|
|
||||||
// BUG(Felix): Why do we have to add 1 here?
|
|
||||||
return linep + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct Source_Code_Location {
|
|
||||||
char* file;
|
|
||||||
int line;
|
|
||||||
int column;
|
|
||||||
};
|
|
||||||
|
|
||||||
Source_Code_Location* create_source_code_location(char* file, int line, int col) {
|
|
||||||
if (!file)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
Source_Code_Location* ret = new(Source_Code_Location);
|
|
||||||
ret->file = file;
|
|
||||||
ret->line = line;
|
|
||||||
ret->column = col;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
+196
-14
@@ -1,16 +1,198 @@
|
|||||||
// #define console_normal "\x1B[0m"
|
proc string_equal(char input[],char check[]) -> bool {
|
||||||
// #define console_red "\x1B[31m"
|
int i;
|
||||||
// #define console_green "\x1B[32m"
|
for(i = 0; input[i] != '\0' || check[i] != '\0'; i++) {
|
||||||
// #define console_cyan "\x1B[36m"
|
if(input[i] != check[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
proc get_nibble(char c) -> char {
|
||||||
|
if (c >= 'A' && c <= 'F')
|
||||||
|
return (c - 'a') + 10;
|
||||||
|
else if (c >= 'a' && c <= 'f')
|
||||||
|
return (c - 'A') + 10;
|
||||||
|
return (c - '0');
|
||||||
|
}
|
||||||
|
|
||||||
|
proc unescape_string(char* in) -> bool {
|
||||||
|
if (!in)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
char *out = in, *p = in;
|
||||||
|
const char *int_err = nullptr;
|
||||||
|
|
||||||
|
while (*p && !int_err) {
|
||||||
|
if (*p != '\\') {
|
||||||
|
/* normal case */
|
||||||
|
*out++ = *p++;
|
||||||
|
} else {
|
||||||
|
/* escape sequence */
|
||||||
|
switch (*++p) {
|
||||||
|
case 'a': *out++ = '\a'; ++p; break;
|
||||||
|
case 'b': *out++ = '\b'; ++p; break;
|
||||||
|
case 'f': *out++ = '\f'; ++p; break;
|
||||||
|
case 'n': *out++ = '\n'; ++p; break;
|
||||||
|
case 'r': *out++ = '\r'; ++p; break;
|
||||||
|
case 't': *out++ = '\t'; ++p; break;
|
||||||
|
case 'v': *out++ = '\v'; ++p; break;
|
||||||
|
|
||||||
|
case '"':
|
||||||
|
case '\'':
|
||||||
|
case '\\':
|
||||||
|
*out++ = *p++;
|
||||||
|
case '?':
|
||||||
|
break;
|
||||||
|
// case 'x':
|
||||||
|
// case 'X':
|
||||||
|
// if (!isxdigit(p[1]) || !isxdigit(p[2])) {
|
||||||
|
// int_err = "Invalid character on hexadecimal escape.";
|
||||||
|
// } else {
|
||||||
|
// *out++ = (char)(get_nibble(p[1]) * 0x10 + get_nibble(p[2]));
|
||||||
|
// p += 3;
|
||||||
|
// }
|
||||||
|
// break;
|
||||||
|
default:
|
||||||
|
int_err = "Unexpected '\\' with no escape sequence.";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the end of string. */
|
||||||
|
*out = '\0';
|
||||||
|
if (int_err)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
proc read_entire_file (char* filename) -> char* {
|
||||||
|
char *fileContent = nullptr;
|
||||||
|
FILE *fp = fopen(filename, "r");
|
||||||
|
if (fp) {
|
||||||
|
/* Go to the end of the file. */
|
||||||
|
if (fseek(fp, 0L, SEEK_END) == 0) {
|
||||||
|
/* Get the size of the file. */
|
||||||
|
long bufsize = ftell(fp);
|
||||||
|
if (bufsize == -1) {
|
||||||
|
fputs("Empty file", stderr);
|
||||||
|
goto closeFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Go back to the start of the file. */
|
||||||
|
if (fseek(fp, 0L, SEEK_SET) != 0) {
|
||||||
|
fputs("Error reading file", stderr);
|
||||||
|
goto closeFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate our buffer to that size. */
|
||||||
|
fileContent = (char*)calloc(bufsize, sizeof(char));
|
||||||
|
|
||||||
|
/* Read the entire file into memory. */
|
||||||
|
size_t newLen = fread(fileContent, sizeof(char), bufsize, fp);
|
||||||
|
|
||||||
|
fileContent[newLen] = '\0';
|
||||||
|
if ( ferror( fp ) != 0 ) {
|
||||||
|
fputs("Error reading file", stderr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closeFile:
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileContent;
|
||||||
|
/* Don't forget to call free() later! */
|
||||||
|
}
|
||||||
|
|
||||||
|
proc read_expression() -> char* {
|
||||||
|
char* line = (char*)malloc(100), * linep = line;
|
||||||
|
size_t lenmax = 100, len = lenmax;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
int nesting = 0;
|
||||||
|
|
||||||
|
if(line == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
c = fgetc(stdin);
|
||||||
|
if(c == EOF)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(--len == 0) {
|
||||||
|
len = lenmax;
|
||||||
|
char * linen = (char*)realloc(linep, lenmax *= 2);
|
||||||
|
|
||||||
|
if(linen == NULL) {
|
||||||
|
free(linep);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
line = linen + (line - linep);
|
||||||
|
linep = linen;
|
||||||
|
}
|
||||||
|
|
||||||
|
*line++;
|
||||||
|
if((*line = (char)c) == '(')
|
||||||
|
++nesting;
|
||||||
|
else if((*line = (char)c) == ')')
|
||||||
|
--nesting;
|
||||||
|
else if((*line = (char)c) == '\n')
|
||||||
|
if (nesting == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
(*line)--; // we dont want the \n actually
|
||||||
|
*line = '\0';
|
||||||
|
// BUG(Felix): Why do we have to add 1 here?
|
||||||
|
return linep + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
proc read_line() -> char* {
|
||||||
|
char* line = (char*)malloc(100), * linep = line;
|
||||||
|
size_t lenmax = 100, len = lenmax;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
int nesting = 0;
|
||||||
|
|
||||||
|
if(line == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
c = fgetc(stdin);
|
||||||
|
if(c == EOF)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(--len == 0) {
|
||||||
|
len = lenmax;
|
||||||
|
char* linen = (char*)realloc(linep, lenmax *= 2);
|
||||||
|
|
||||||
|
if(linen == NULL) {
|
||||||
|
free(linep);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
line = linen + (line - linep);
|
||||||
|
linep = linen;
|
||||||
|
}
|
||||||
|
|
||||||
|
*line++;
|
||||||
|
if((*line = (char)c) == '(')
|
||||||
|
++nesting;
|
||||||
|
else if((*line = (char)c) == ')')
|
||||||
|
--nesting;
|
||||||
|
else if((*line = (char)c) == '\n')
|
||||||
|
if (nesting == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
(*line)--; // we dont want the \n actually
|
||||||
|
*line = '\0';
|
||||||
|
// BUG(Felix): Why do we have to add 1 here?
|
||||||
|
return linep + 1;
|
||||||
|
}
|
||||||
|
|
||||||
#define console_normal ""
|
|
||||||
#define console_red ""
|
|
||||||
#define console_green ""
|
|
||||||
#define console_cyan ""
|
|
||||||
|
|
||||||
Log_Level log_level = Log_Level::Debug;
|
Log_Level log_level = Log_Level::Debug;
|
||||||
|
|
||||||
void log_message(Log_Level type, char* message) {
|
proc log_message(Log_Level type, char* message) -> void {
|
||||||
if (type > log_level)
|
if (type > log_level)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -25,12 +207,12 @@ void log_message(Log_Level type, char* message) {
|
|||||||
printf("%s: %s\n",prefix, message);
|
printf("%s: %s\n",prefix, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void panic(char* message) {
|
proc panic(char* message) -> void {
|
||||||
log_message(Log_Level::Critical, message);
|
log_message(Log_Level::Critical, message);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void print(Lisp_Object* node) {
|
proc print(Lisp_Object* node) -> void {
|
||||||
switch (node->type) {
|
switch (node->type) {
|
||||||
case (Lisp_Object_Type::Nil): {
|
case (Lisp_Object_Type::Nil): {
|
||||||
printf("nil");
|
printf("nil");
|
||||||
@@ -91,7 +273,7 @@ void print(Lisp_Object* node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// XXX(Felix): obv code dublicate
|
// XXX(Felix): obv code dublicate
|
||||||
void fprint(FILE* f, Lisp_Object* node) {
|
proc fprint(FILE* f, Lisp_Object* node) -> void {
|
||||||
switch (node->type) {
|
switch (node->type) {
|
||||||
case (Lisp_Object_Type::Nil): {
|
case (Lisp_Object_Type::Nil): {
|
||||||
fprintf(f, "nil");
|
fprintf(f, "nil");
|
||||||
@@ -151,7 +333,7 @@ void fprint(FILE* f, Lisp_Object* node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_error_location() {
|
proc print_error_location() -> void {
|
||||||
if (error->location) {
|
if (error->location) {
|
||||||
printf("%s (line %d, position %d)",
|
printf("%s (line %d, position %d)",
|
||||||
error->location->file,
|
error->location->file,
|
||||||
@@ -162,7 +344,7 @@ void print_error_location() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void log_error() {
|
proc log_error() -> void {
|
||||||
printf("%s%s%s\n", console_red,
|
printf("%s%s%s\n", console_red,
|
||||||
Error_Type_to_string(error->type),
|
Error_Type_to_string(error->type),
|
||||||
console_normal);
|
console_normal);
|
||||||
|
|||||||
+17
-6
@@ -1,4 +1,15 @@
|
|||||||
char* Lisp_Object_Type_to_string(Lisp_Object_Type type) {
|
proc create_source_code_location(char* file, int line, int col) -> Source_Code_Location* {
|
||||||
|
if (!file)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
Source_Code_Location* ret = new(Source_Code_Location);
|
||||||
|
ret->file = file;
|
||||||
|
ret->line = line;
|
||||||
|
ret->column = col;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
proc Lisp_Object_Type_to_string(Lisp_Object_Type type) -> char* {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case(Lisp_Object_Type::Nil): return "nil";
|
case(Lisp_Object_Type::Nil): return "nil";
|
||||||
case(Lisp_Object_Type::T): return "t";
|
case(Lisp_Object_Type::T): return "t";
|
||||||
@@ -13,7 +24,7 @@ char* Lisp_Object_Type_to_string(Lisp_Object_Type type) {
|
|||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
Positional_Arguments* create_positional_argument_list(int initial_capacity) {
|
proc create_positional_argument_list(int initial_capacity) -> Positional_Arguments* {
|
||||||
Positional_Arguments* ret = new(Positional_Arguments);
|
Positional_Arguments* ret = new(Positional_Arguments);
|
||||||
ret->identifiers = (char**)malloc(initial_capacity * sizeof(char*));
|
ret->identifiers = (char**)malloc(initial_capacity * sizeof(char*));
|
||||||
ret->next_index = 0;
|
ret->next_index = 0;
|
||||||
@@ -21,7 +32,7 @@ Positional_Arguments* create_positional_argument_list(int initial_capacity) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void append_to_positional_argument_list(Positional_Arguments* args, char* identifier) {
|
proc append_to_positional_argument_list(Positional_Arguments* args, char* identifier) -> void {
|
||||||
if (args->next_index == args->length) {
|
if (args->next_index == args->length) {
|
||||||
args->length *= 2;
|
args->length *= 2;
|
||||||
args->identifiers = (char**)realloc(args->identifiers, args->length * sizeof(char*));
|
args->identifiers = (char**)realloc(args->identifiers, args->length * sizeof(char*));
|
||||||
@@ -29,7 +40,7 @@ void append_to_positional_argument_list(Positional_Arguments* args, char* identi
|
|||||||
args->identifiers[args->next_index++] = identifier;
|
args->identifiers[args->next_index++] = identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
Keyword_Arguments* create_keyword_argument_list(int initial_capacity) {
|
proc create_keyword_argument_list(int initial_capacity) -> Keyword_Arguments* {
|
||||||
Keyword_Arguments* ret = new(Keyword_Arguments);
|
Keyword_Arguments* ret = new(Keyword_Arguments);
|
||||||
ret->identifiers = (char**)malloc(initial_capacity * sizeof(char*));
|
ret->identifiers = (char**)malloc(initial_capacity * sizeof(char*));
|
||||||
ret->values = create_Lisp_Object_array_list(initial_capacity);
|
ret->values = create_Lisp_Object_array_list(initial_capacity);
|
||||||
@@ -38,9 +49,9 @@ Keyword_Arguments* create_keyword_argument_list(int initial_capacity) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void append_to_keyword_argument_list(Keyword_Arguments* args,
|
proc append_to_keyword_argument_list(Keyword_Arguments* args,
|
||||||
char* identifier,
|
char* identifier,
|
||||||
struct Lisp_Object* default_value)
|
struct Lisp_Object* default_value) -> void
|
||||||
{
|
{
|
||||||
if (args->next_index == args->length) {
|
if (args->next_index == args->length) {
|
||||||
args->length *= 2;
|
args->length *= 2;
|
||||||
|
|||||||
+2
-93
@@ -1,95 +1,4 @@
|
|||||||
#pragma once
|
#include "slime.h"
|
||||||
#define _CRT_SECURE_NO_DEPRECATE
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdarg.h> /* needed for va_list */
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
#include "./helpers.cpp"
|
|
||||||
#include "./structs.cpp"
|
|
||||||
#include "./forward_decls.cpp"
|
|
||||||
#include "./lisp_object.cpp"
|
|
||||||
#include "./error.cpp"
|
|
||||||
#include "./io.cpp"
|
|
||||||
#include "./memory.cpp"
|
|
||||||
#include "./env.cpp"
|
|
||||||
#include "./parse.cpp"
|
|
||||||
#include "./built_ins.cpp"
|
|
||||||
#include "./eval.cpp"
|
|
||||||
#include "./testing.cpp"
|
|
||||||
|
|
||||||
Lisp_Object* interprete_file (char* file_name) {
|
|
||||||
Memory::init();
|
|
||||||
Environment* env = Memory::create_empty_environment();
|
|
||||||
Parser::init(env);
|
|
||||||
|
|
||||||
char* file_content = read_entire_file(file_name);
|
|
||||||
if (!file_content) {
|
|
||||||
create_error(Error_Type::Unknown_Error, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
load_built_ins_into_environment(env);
|
|
||||||
|
|
||||||
try {
|
|
||||||
built_in_load("pre.slime", env);
|
|
||||||
}
|
|
||||||
|
|
||||||
Lisp_Object_Array_List* program;
|
|
||||||
try {
|
|
||||||
program = Parser::parse_program(file_name, file_content);
|
|
||||||
}
|
|
||||||
|
|
||||||
Lisp_Object* result = Memory::create_lisp_object_nil();
|
|
||||||
for (int i = 0; i < program->next_index; ++i) {
|
|
||||||
try {
|
|
||||||
result = eval_expr(program->data[i], env);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int interprete_stdin () {
|
|
||||||
Memory::init();
|
|
||||||
Environment* env = Memory::create_built_ins_environment();
|
|
||||||
Parser::init(env);
|
|
||||||
|
|
||||||
printf("Welcome to the lispy interpreter.\n");
|
|
||||||
|
|
||||||
char* line;
|
|
||||||
|
|
||||||
built_in_load("pre.slime", env);
|
|
||||||
built_in_load("test.slime", env);
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
log_error();
|
|
||||||
delete_error();
|
|
||||||
}
|
|
||||||
|
|
||||||
Lisp_Object* parsed, * evaluated;
|
|
||||||
while (true) {
|
|
||||||
printf(">");
|
|
||||||
line = read_expression();
|
|
||||||
parsed = Parser::parse_single_expression(line);
|
|
||||||
if (error) {
|
|
||||||
log_error();
|
|
||||||
delete_error();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
evaluated = eval_expr(parsed, env);
|
|
||||||
if (error) {
|
|
||||||
log_error();
|
|
||||||
delete_error();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
print(evaluated);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
@@ -99,7 +8,7 @@ int main (int argc, char *argv[]) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// run_all_tests();
|
run_all_tests();
|
||||||
return interprete_stdin();
|
return interprete_stdin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-17
@@ -5,12 +5,12 @@ namespace Memory {
|
|||||||
Lisp_Object* memory;
|
Lisp_Object* memory;
|
||||||
int nextFreeSpot = 0;
|
int nextFreeSpot = 0;
|
||||||
|
|
||||||
void init() {
|
proc init() -> void {
|
||||||
memory = (Lisp_Object*)malloc(maxLispObjects * sizeof(Lisp_Object));
|
memory = (Lisp_Object*)malloc(maxLispObjects * sizeof(Lisp_Object));
|
||||||
freeSpots = create_Int_array_list();
|
freeSpots = create_Int_array_list();
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_status() {
|
proc print_status() -> void {
|
||||||
printf("Memory Status:\n"
|
printf("Memory Status:\n"
|
||||||
" - %f%% of the memory is used\n"
|
" - %f%% of the memory is used\n"
|
||||||
" - %d of %d total Lisp_Objects are in use\n"
|
" - %d of %d total Lisp_Objects are in use\n"
|
||||||
@@ -20,7 +20,7 @@ namespace Memory {
|
|||||||
freeSpots->next_index);
|
freeSpots->next_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* create_lisp_object() {
|
proc create_lisp_object() -> Lisp_Object* {
|
||||||
int index;
|
int index;
|
||||||
// if we have no free spots then append at the end
|
// if we have no free spots then append at the end
|
||||||
if (freeSpots->next_index == 0) {
|
if (freeSpots->next_index == 0) {
|
||||||
@@ -39,21 +39,21 @@ namespace Memory {
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* create_lisp_object_nil() {
|
proc create_lisp_object_nil() -> Lisp_Object* {
|
||||||
Lisp_Object* node = create_lisp_object();
|
Lisp_Object* node = create_lisp_object();
|
||||||
node->type = Lisp_Object_Type::Nil;
|
node->type = Lisp_Object_Type::Nil;
|
||||||
node->value.pair = nullptr;
|
node->value.pair = nullptr;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* create_lisp_object_t() {
|
proc create_lisp_object_t() -> Lisp_Object* {
|
||||||
Lisp_Object* node = create_lisp_object();
|
Lisp_Object* node = create_lisp_object();
|
||||||
node->type = Lisp_Object_Type::T;
|
node->type = Lisp_Object_Type::T;
|
||||||
node->value.pair = nullptr;
|
node->value.pair = nullptr;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* create_lisp_object_number(double number) {
|
proc create_lisp_object_number(double number) -> Lisp_Object* {
|
||||||
Lisp_Object* node = create_lisp_object();
|
Lisp_Object* node = create_lisp_object();
|
||||||
node->type = Lisp_Object_Type::Number;
|
node->type = Lisp_Object_Type::Number;
|
||||||
node->value.number = new(Number);
|
node->value.number = new(Number);
|
||||||
@@ -61,7 +61,7 @@ namespace Memory {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* create_lisp_object_string(char* str, int length) {
|
proc create_lisp_object_string(char* str, int length) -> Lisp_Object* {
|
||||||
Lisp_Object* node = create_lisp_object();
|
Lisp_Object* node = create_lisp_object();
|
||||||
node->type = Lisp_Object_Type::String;
|
node->type = Lisp_Object_Type::String;
|
||||||
node->value.string = new(String);
|
node->value.string = new(String);
|
||||||
@@ -70,7 +70,7 @@ namespace Memory {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* create_lisp_object_symbol(char* identifier) {
|
proc create_lisp_object_symbol(char* identifier) -> Lisp_Object* {
|
||||||
Lisp_Object* node = create_lisp_object();
|
Lisp_Object* node = create_lisp_object();
|
||||||
node->type = Lisp_Object_Type::Symbol;
|
node->type = Lisp_Object_Type::Symbol;
|
||||||
node->value.symbol = new(Symbol);
|
node->value.symbol = new(Symbol);
|
||||||
@@ -78,7 +78,7 @@ namespace Memory {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* create_lisp_object_keyword(char* keyword) {
|
proc create_lisp_object_keyword(char* keyword) -> Lisp_Object* {
|
||||||
Lisp_Object* node = create_lisp_object();
|
Lisp_Object* node = create_lisp_object();
|
||||||
node->type = Lisp_Object_Type::Keyword;
|
node->type = Lisp_Object_Type::Keyword;
|
||||||
node->value.keyword = new(Keyword);
|
node->value.keyword = new(Keyword);
|
||||||
@@ -86,7 +86,7 @@ namespace Memory {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* create_lisp_object_cfunction(std::function<Lisp_Object*(Lisp_Object*, Environment*)> function) {
|
proc create_lisp_object_cfunction(std::function<Lisp_Object*(Lisp_Object*, Environment*)> function) -> Lisp_Object* {
|
||||||
Lisp_Object* node = create_lisp_object();
|
Lisp_Object* node = create_lisp_object();
|
||||||
node->type = Lisp_Object_Type::CFunction;
|
node->type = Lisp_Object_Type::CFunction;
|
||||||
node->value.cfunction = new(CFunction);
|
node->value.cfunction = new(CFunction);
|
||||||
@@ -94,7 +94,7 @@ namespace Memory {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* create_lisp_object_pair(Lisp_Object* first, Lisp_Object* rest) {
|
proc create_lisp_object_pair(Lisp_Object* first, Lisp_Object* rest) -> Lisp_Object* {
|
||||||
Lisp_Object* node = create_lisp_object();
|
Lisp_Object* node = create_lisp_object();
|
||||||
node->type = Lisp_Object_Type::Pair;
|
node->type = Lisp_Object_Type::Pair;
|
||||||
node->value.pair = new(Pair);
|
node->value.pair = new(Pair);
|
||||||
@@ -103,15 +103,13 @@ namespace Memory {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* copy_lisp_object(Lisp_Object* n) {
|
proc copy_lisp_object(Lisp_Object* n) -> Lisp_Object* {
|
||||||
Lisp_Object* target = create_lisp_object();
|
Lisp_Object* target = create_lisp_object();
|
||||||
*target = *n;
|
*target = *n;
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
// environments
|
proc create_child_environment(Environment* parent) -> Environment* {
|
||||||
|
|
||||||
Environment* create_child_environment(Environment* parent) {
|
|
||||||
Environment* env = new(Environment);
|
Environment* env = new(Environment);
|
||||||
|
|
||||||
int start_capacity = 16;
|
int start_capacity = 16;
|
||||||
@@ -125,11 +123,11 @@ namespace Memory {
|
|||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
|
||||||
Environment* create_empty_environment() {
|
proc create_empty_environment() -> Environment* {
|
||||||
return create_child_environment(nullptr);
|
return create_child_environment(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
Environment* create_built_ins_environment() {
|
proc create_built_ins_environment() -> Environment* {
|
||||||
Environment* ret = create_child_environment(nullptr);
|
Environment* ret = create_child_environment(nullptr);
|
||||||
load_built_ins_into_environment(ret);
|
load_built_ins_into_environment(ret);
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define _CRT_SECURE_NO_DEPRECATE
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include "./defines.cpp"
|
||||||
|
#include "./structs.cpp"
|
||||||
|
#include "./forward_decls.cpp"
|
||||||
|
#include "./lisp_object.cpp"
|
||||||
|
#include "./error.cpp"
|
||||||
|
#include "./io.cpp"
|
||||||
|
#include "./memory.cpp"
|
||||||
|
#include "./env.cpp"
|
||||||
|
#include "./parse.cpp"
|
||||||
|
#include "./built_ins.cpp"
|
||||||
|
#include "./eval.cpp"
|
||||||
|
#include "./testing.cpp"
|
||||||
|
#include "./undefines.cpp"
|
||||||
|
|
||||||
|
#undef _CRT_SECURE_NO_DEPRECATE
|
||||||
+30
-24
@@ -17,6 +17,30 @@ enum struct Lisp_Object_Type {
|
|||||||
CFunction,
|
CFunction,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum struct Function_Type {
|
||||||
|
Lambda,
|
||||||
|
Special_Lambda,
|
||||||
|
Macro
|
||||||
|
};
|
||||||
|
|
||||||
|
enum struct Error_Type {
|
||||||
|
Ill_Formed_Arguments,
|
||||||
|
Ill_Formed_Lambda_List,
|
||||||
|
Ill_Formed_List,
|
||||||
|
Not_A_Function,
|
||||||
|
Not_Yet_Implemented,
|
||||||
|
Symbol_Not_Defined,
|
||||||
|
Syntax_Error,
|
||||||
|
Trailing_Garbage,
|
||||||
|
Type_Missmatch,
|
||||||
|
Unbalanced_Parenthesis,
|
||||||
|
Unexpected_Eof,
|
||||||
|
Unknown_Error,
|
||||||
|
Unknown_Keyword_Argument,
|
||||||
|
Wrong_Number_Of_Arguments,
|
||||||
|
Out_Of_Memory,
|
||||||
|
};
|
||||||
|
|
||||||
enum struct Log_Level {
|
enum struct Log_Level {
|
||||||
None,
|
None,
|
||||||
Critical,
|
Critical,
|
||||||
@@ -25,6 +49,12 @@ enum struct Log_Level {
|
|||||||
Debug,
|
Debug,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Source_Code_Location {
|
||||||
|
char* file;
|
||||||
|
int line;
|
||||||
|
int column;
|
||||||
|
};
|
||||||
|
|
||||||
struct Symbol {
|
struct Symbol {
|
||||||
char* identifier;
|
char* identifier;
|
||||||
};
|
};
|
||||||
@@ -64,12 +94,6 @@ struct Keyword_Arguments {
|
|||||||
int length;
|
int length;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum struct Function_Type {
|
|
||||||
Lambda,
|
|
||||||
Special_Lambda,
|
|
||||||
Macro
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Function {
|
struct Function {
|
||||||
Function_Type type;
|
Function_Type type;
|
||||||
char* docstring;
|
char* docstring;
|
||||||
@@ -118,24 +142,6 @@ struct Environment {
|
|||||||
Lisp_Object** values;
|
Lisp_Object** values;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum struct Error_Type {
|
|
||||||
Ill_Formed_Arguments,
|
|
||||||
Ill_Formed_Lambda_List,
|
|
||||||
Ill_Formed_List,
|
|
||||||
Not_A_Function,
|
|
||||||
Not_Yet_Implemented,
|
|
||||||
Symbol_Not_Defined,
|
|
||||||
Syntax_Error,
|
|
||||||
Trailing_Garbage,
|
|
||||||
Type_Missmatch,
|
|
||||||
Unbalanced_Parenthesis,
|
|
||||||
Unexpected_Eof,
|
|
||||||
Unknown_Error,
|
|
||||||
Unknown_Keyword_Argument,
|
|
||||||
Wrong_Number_Of_Arguments,
|
|
||||||
Out_Of_Memory,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Error {
|
struct Error {
|
||||||
Error_Type type;
|
Error_Type type;
|
||||||
Source_Code_Location* location;
|
Source_Code_Location* location;
|
||||||
|
|||||||
+30
-13
@@ -85,7 +85,7 @@
|
|||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
testresult test_eval_operands() {
|
proc test_eval_operands() -> testresult {
|
||||||
char operands_string[] = "((eval 1) (+ 1 2) \"okay\" (eval :haha))";
|
char operands_string[] = "((eval 1) (+ 1 2) \"okay\" (eval :haha))";
|
||||||
Lisp_Object* operands = Parser::parse_single_expression(operands_string);
|
Lisp_Object* operands = Parser::parse_single_expression(operands_string);
|
||||||
int operands_length;
|
int operands_length;
|
||||||
@@ -119,7 +119,7 @@ testresult test_eval_operands() {
|
|||||||
return pass;
|
return pass;
|
||||||
}
|
}
|
||||||
|
|
||||||
testresult test_parse_atom() {
|
proc test_parse_atom() -> testresult {
|
||||||
int index_in_text = 0;
|
int index_in_text = 0;
|
||||||
char string[] =
|
char string[] =
|
||||||
"123 -1.23e-2 " // numbers
|
"123 -1.23e-2 " // numbers
|
||||||
@@ -175,7 +175,7 @@ testresult test_parse_atom() {
|
|||||||
return pass;
|
return pass;
|
||||||
}
|
}
|
||||||
|
|
||||||
testresult test_parse_expression() {
|
proc test_parse_expression() -> testresult {
|
||||||
int index_in_text = 0;
|
int index_in_text = 0;
|
||||||
char string[] = "(fun + 12)";
|
char string[] = "(fun + 12)";
|
||||||
|
|
||||||
@@ -230,7 +230,7 @@ testresult test_parse_expression() {
|
|||||||
return pass;
|
return pass;
|
||||||
}
|
}
|
||||||
|
|
||||||
testresult test_built_in_add() {
|
proc test_built_in_add() -> testresult {
|
||||||
char exp_string[] = "(+ 10 4)";
|
char exp_string[] = "(+ 10 4)";
|
||||||
Lisp_Object* expression = Parser::parse_single_expression(exp_string);
|
Lisp_Object* expression = Parser::parse_single_expression(exp_string);
|
||||||
Lisp_Object* result = eval_expr(expression, Memory::create_built_ins_environment());
|
Lisp_Object* result = eval_expr(expression, Memory::create_built_ins_environment());
|
||||||
@@ -243,7 +243,7 @@ testresult test_built_in_add() {
|
|||||||
return pass;
|
return pass;
|
||||||
}
|
}
|
||||||
|
|
||||||
testresult test_built_in_substract() {
|
proc test_built_in_substract() -> testresult {
|
||||||
char exp_string[] = "(- 10 4)";
|
char exp_string[] = "(- 10 4)";
|
||||||
Lisp_Object* expression = Parser::parse_single_expression(exp_string);
|
Lisp_Object* expression = Parser::parse_single_expression(exp_string);
|
||||||
Lisp_Object* result = eval_expr(expression, Memory::create_built_ins_environment());
|
Lisp_Object* result = eval_expr(expression, Memory::create_built_ins_environment());
|
||||||
@@ -257,7 +257,7 @@ testresult test_built_in_substract() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
testresult test_built_in_multiply() {
|
proc test_built_in_multiply() -> testresult {
|
||||||
char exp_string[] = "(* 10 4)";
|
char exp_string[] = "(* 10 4)";
|
||||||
Lisp_Object* expression = Parser::parse_single_expression(exp_string);
|
Lisp_Object* expression = Parser::parse_single_expression(exp_string);
|
||||||
Lisp_Object* result = eval_expr(expression, Memory::create_built_ins_environment());
|
Lisp_Object* result = eval_expr(expression, Memory::create_built_ins_environment());
|
||||||
@@ -271,7 +271,7 @@ testresult test_built_in_multiply() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
testresult test_built_in_divide() {
|
proc test_built_in_divide() -> testresult {
|
||||||
char exp_string[] = "(/ 20 4)";
|
char exp_string[] = "(/ 20 4)";
|
||||||
Lisp_Object* expression = Parser::parse_single_expression(exp_string);
|
Lisp_Object* expression = Parser::parse_single_expression(exp_string);
|
||||||
Lisp_Object* result = eval_expr(expression, Memory::create_built_ins_environment());
|
Lisp_Object* result = eval_expr(expression, Memory::create_built_ins_environment());
|
||||||
@@ -285,7 +285,7 @@ testresult test_built_in_divide() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
testresult test_built_in_if() {
|
proc test_built_in_if() -> testresult {
|
||||||
char exp_string1[] = "(if 1 4 5)";
|
char exp_string1[] = "(if 1 4 5)";
|
||||||
Lisp_Object* expression = Parser::parse_single_expression(exp_string1);
|
Lisp_Object* expression = Parser::parse_single_expression(exp_string1);
|
||||||
Lisp_Object* result = eval_expr(expression, Memory::create_built_ins_environment());
|
Lisp_Object* result = eval_expr(expression, Memory::create_built_ins_environment());
|
||||||
@@ -307,7 +307,7 @@ testresult test_built_in_if() {
|
|||||||
return pass;
|
return pass;
|
||||||
}
|
}
|
||||||
|
|
||||||
testresult test_built_in_and() {
|
proc test_built_in_and() -> testresult {
|
||||||
char exp_string1[] = "(and 1 \"asd\" 4)";
|
char exp_string1[] = "(and 1 \"asd\" 4)";
|
||||||
Lisp_Object* expression = Parser::parse_single_expression(exp_string1);
|
Lisp_Object* expression = Parser::parse_single_expression(exp_string1);
|
||||||
Lisp_Object* result = eval_expr(expression, Memory::create_built_ins_environment());
|
Lisp_Object* result = eval_expr(expression, Memory::create_built_ins_environment());
|
||||||
@@ -328,7 +328,7 @@ testresult test_built_in_and() {
|
|||||||
return pass;
|
return pass;
|
||||||
}
|
}
|
||||||
|
|
||||||
testresult test_built_in_or() {
|
proc test_built_in_or() -> testresult {
|
||||||
char exp_string1[] = "(or \"asd\" nil)";
|
char exp_string1[] = "(or \"asd\" nil)";
|
||||||
Lisp_Object* expression = Parser::parse_single_expression(exp_string1);
|
Lisp_Object* expression = Parser::parse_single_expression(exp_string1);
|
||||||
Lisp_Object* result = eval_expr(expression, Memory::create_built_ins_environment());
|
Lisp_Object* result = eval_expr(expression, Memory::create_built_ins_environment());
|
||||||
@@ -350,7 +350,7 @@ testresult test_built_in_or() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
testresult test_built_in_not() {
|
proc test_built_in_not() -> testresult {
|
||||||
char exp_string1[] = "(not ())";
|
char exp_string1[] = "(not ())";
|
||||||
Lisp_Object* expression = Parser::parse_single_expression(exp_string1);
|
Lisp_Object* expression = Parser::parse_single_expression(exp_string1);
|
||||||
Lisp_Object* result = eval_expr(expression, Memory::create_built_ins_environment());
|
Lisp_Object* result = eval_expr(expression, Memory::create_built_ins_environment());
|
||||||
@@ -372,7 +372,7 @@ testresult test_built_in_not() {
|
|||||||
return pass;
|
return pass;
|
||||||
}
|
}
|
||||||
|
|
||||||
void run_all_tests() {
|
proc run_all_tests() -> void {
|
||||||
log_level = Log_Level::None;
|
log_level = Log_Level::None;
|
||||||
Memory::init();
|
Memory::init();
|
||||||
Parser::init(Memory::create_built_ins_environment());
|
Parser::init(Memory::create_built_ins_environment());
|
||||||
@@ -393,5 +393,22 @@ void run_all_tests() {
|
|||||||
invoke_test(test_built_in_and);
|
invoke_test(test_built_in_and);
|
||||||
invoke_test(test_built_in_or);
|
invoke_test(test_built_in_or);
|
||||||
invoke_test(test_built_in_not);
|
invoke_test(test_built_in_not);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef epsilon
|
||||||
|
#undef testresult
|
||||||
|
#undef pass
|
||||||
|
#undef fail
|
||||||
|
|
||||||
|
#undef print_assert_equal_fail
|
||||||
|
#undef print_assert_not_equal_fail
|
||||||
|
#undef assert_no_error
|
||||||
|
#undef assert_equal_int
|
||||||
|
#undef assert_not_equal_int
|
||||||
|
#undef assert_equal_double
|
||||||
|
#undef assert_not_equal_double
|
||||||
|
#undef assert_equal_string
|
||||||
|
#undef assert_equal_type
|
||||||
|
#undef assert_null
|
||||||
|
#undef assert_not_null
|
||||||
|
#undef invoke_test
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#undef new
|
||||||
|
#undef proc
|
||||||
|
|
||||||
|
#undef if_debug
|
||||||
|
#undef assert
|
||||||
|
#undef concat_
|
||||||
|
#undef label
|
||||||
|
|
||||||
|
#undef try
|
||||||
|
#undef try_void
|
||||||
|
|
||||||
|
#undef define_array_list
|
||||||
|
|
||||||
|
#undef console_normal
|
||||||
|
#undef console_red
|
||||||
|
#undef console_green
|
||||||
|
#undef console_cyan
|
||||||
Reference in New Issue
Block a user