FelixBrendel пре 7 година
родитељ
комит
09582f9669
11 измењених фајлова са 128 додато и 139 уклоњено
  1. +5
    -20
      .dir-locals.el
  2. +15
    -22
      src/built_ins.cpp
  3. +2
    -2
      src/defines.cpp
  4. +0
    -1
      src/env.cpp
  5. +3
    -2
      src/error.cpp
  6. +4
    -4
      src/eval.cpp
  7. +5
    -1
      src/forward_decls.cpp
  8. +42
    -37
      src/io.cpp
  9. +8
    -6
      src/main.cpp
  10. +2
    -2
      src/slime.h
  11. +42
    -42
      src/testing.cpp

+ 5
- 20
.dir-locals.el Прегледај датотеку

@@ -8,34 +8,19 @@
context-mode-map)
(context-mode 1)

;; additional scripts
(defun save-and-find-test-script-and-compile ()
(interactive)
(let ((build-script-name "test.bat"))
(save-and-find-build-script-and-compile)))
(defun save-and-find-run-script-and-compile ()
(interactive)
(let ((build-script-name "run.bat"))
(save-and-find-build-script-and-compile)))
(defun save-and-find-debug-script-and-compile ()
(interactive)
(let ((build-script-name "debug.bat"))
(save-and-find-build-script-and-compile)))

(defhydra hydra-context (context-mode-map "<f2>")
"Context Actions:"
("b" save-and-find-build-script-and-compile "build" :color blue)
("r" save-and-find-run-script-and-compile "run" :color blue)
("d" save-and-find-debug-script-and-compile "debug" :color blue)
("t" save-and-find-test-script-and-compile "test" :color blue)
("o" browse-file-directory "open" :color blue)
("q" nil "quit" :color blue))

(define-key context-mode-map (kbd "<f2>") 'hydra-context/body)

(font-lock-add-keywords 'c++-mode
'(("\\<\\(if_debug\\|if_windows\\|if_linux\\|defer\\|proc\\)\\>" .
font-lock-keyword-face)))))))
(font-lock-add-keywords
'c++-mode
'(("\\<\\(if_debug\\|if_windows\\|if_linux\\|defer\\|proc\\)\\>" .
font-lock-keyword-face)))))))

(c++-mode . ((eval . (company-clang-set-prefix "slime.h"))
(eval . (flycheck-mode 0))
(eval . (rainbow-mode 0))


+ 15
- 22
src/built_ins.cpp Прегледај датотеку

@@ -5,31 +5,24 @@ proc lisp_object_equal(Lisp_Object* n1, Lisp_Object* n2) -> bool {
return false;

switch (n1->type) {
case Lisp_Object_Type::CFunction:
// TODO(Felix): make comparing work again.
return false;
/* return n1->value.built_in_function->type */
/* == n2->value.built_in_function->type; */
case Lisp_Object_Type::Function:
// if they have the same pointer, true is
// returned a few lines above
return false;

case Lisp_Object_Type::CFunction: // if they have the same
// pointer, true is returned a
// few lines above
case Lisp_Object_Type::Function: return false;
case Lisp_Object_Type::T: // code for t and nil should never be
// reached since they are memory unique
case Lisp_Object_Type::Nil: return true;
case Lisp_Object_Type::Symbol: // NOTE(Felix): this will be
// unnecessary once symbols and
// keywords are memory unique
case Lisp_Object_Type::Keyword:
return string_equal(
n1->value.identifier,
n2->value.identifier);
case Lisp_Object_Type::T:
case Lisp_Object_Type::Nil:
return true;
case Lisp_Object_Type::Number:
return n1->value.number == n2->value.number;
return string_equal(n1->value.identifier, n2->value.identifier);
case Lisp_Object_Type::Number: return n1->value.number == n2->value.number;
case Lisp_Object_Type::String: return string_equal(n1->value.string, n2->value.string);
case Lisp_Object_Type::Pair:
create_not_yet_implemented_error();
return false;
case Lisp_Object_Type::String:
return string_equal(n1->value.string, n2->value.string);
case Lisp_Object_Type::Symbol:
return string_equal(n1->value.identifier, n2->value.identifier);
}

// we should never reach here
@@ -916,7 +909,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
Lisp_Object* result;

result = eval_expr(try_part, env);
if (error) {
if (Globals::error) {
delete_error();
try {
result = eval_expr(catch_part, env);


+ 2
- 2
src/defines.cpp Прегледај датотеку

@@ -28,7 +28,7 @@ constexpr bool is_debug_build = false;
else \
while (1) \
if (1) { \
if(error) { \
if(Globals::error) { \
if (log_level == Log_Level::Debug) { \
printf("in %s:%d\n", __FILE__, __LINE__); \
} \
@@ -44,7 +44,7 @@ constexpr bool is_debug_build = false;
else \
while (1) \
if (1) { \
if(error) { \
if(Globals::error) { \
if (log_level == Log_Level::Debug) { \
printf("in %s:%d\n", __FILE__, __LINE__); \
} \


+ 0
- 1
src/env.cpp Прегледај датотеку

@@ -1,4 +1,3 @@

proc define_symbol(Lisp_Object* symbol, Lisp_Object* value, Environment* env) -> void {
// NOTE(Felix): right now we are simply adding the symol at the
// back of the list without checking if it already exists but are


+ 3
- 2
src/error.cpp Прегледај датотеку

@@ -1,6 +1,6 @@
Error* error;

proc delete_error() -> void {
using Globals::error;

if (error) {
free(error);
error = nullptr;
@@ -15,6 +15,7 @@ proc create_error(const char* c_file_name, int c_file_line, Lisp_Object* type, S
delete_error();
debug_break();

using Globals::error;
error = new(Error);
error->type = type;
error->message = message;


+ 4
- 4
src/eval.cpp Прегледај датотеку

@@ -387,7 +387,7 @@ proc eval_expr(Lisp_Object* node, Environment* env) -> Lisp_Object* {
return symbol;
}
case Lisp_Object_Type::Pair: {
current_source_code = node;
Globals::current_source_code = node;

Lisp_Object* lispOperator;
if (node->value.pair.first->type != Lisp_Object_Type::CFunction &&
@@ -486,7 +486,7 @@ proc interprete_stdin() -> void {

built_in_load(Memory::create_string("pre.slime"), env);

if (error) {
if (Globals::error) {
log_error();
delete_error();
}
@@ -497,13 +497,13 @@ proc interprete_stdin() -> void {
line = read_expression();
parsed = Parser::parse_single_expression(line);
free(line);
if (error) {
if (Globals::error) {
log_error();
delete_error();
continue;
}
evaluated = eval_expr(parsed, env);
if (error) {
if (Globals::error) {
log_error();
delete_error();
continue;


+ 5
- 1
src/forward_decls.cpp Прегледај датотеку

@@ -12,8 +12,12 @@ proc parse_argument_list(Lisp_Object*, Function*) -> void;
proc print_environment(Environment*) -> void;

proc Lisp_Object_Type_to_string(Lisp_Object_Type type) -> const char*;

namespace Memory {
proc get_or_create_lisp_object_keyword(const char* identifier) -> Lisp_Object*;
}

Lisp_Object* current_source_code = nullptr;
namespace Globals {
Lisp_Object* current_source_code = nullptr;
Error* error;
}

+ 42
- 37
src/io.cpp Прегледај датотеку

@@ -119,16 +119,17 @@ proc read_entire_file(char* filename) -> char* {

proc read_expression() -> char* {
char* line = (char*)malloc(100);

if(line == nullptr)
return nullptr;

char* linep = line;
size_t lenmax = 100, len = lenmax;
int c;

int nesting = 0;

if(line == NULL)
return NULL;

for(;;) {
while (true) {
c = fgetc(stdin);
if(c == EOF)
break;
@@ -137,9 +138,9 @@ proc read_expression() -> char* {
len = lenmax;
char * linen = (char*)realloc(linep, lenmax *= 2);

if(linen == NULL) {
if(linen == nullptr) {
free(linep);
return NULL;
return nullptr;
}
line = linen + (line - linep);
linep = linen;
@@ -168,8 +169,8 @@ proc read_line() -> char* {

int nesting = 0;

if(line == NULL)
return NULL;
if(line == nullptr)
return nullptr;

for(;;) {
c = fgetc(stdin);
@@ -180,9 +181,9 @@ proc read_line() -> char* {
len = lenmax;
char* linen = (char*)realloc(linep, lenmax *= 2);

if(linen == NULL) {
if(linen == nullptr) {
free(linep);
return NULL;
return nullptr;
}
line = linen + (line - linep);
linep = linen;
@@ -230,31 +231,34 @@ proc panic(char* message) -> void {
proc print(Lisp_Object* node, bool print_quotes = false, FILE* file = stdout) -> void {

switch (node->type) {
case (Lisp_Object_Type::Nil): fprintf(file, "()"); break;
case (Lisp_Object_Type::T): fprintf(file, "t"); break;
case (Lisp_Object_Type::Number): fprintf(file, "%f", node->value.number); break;
case (Lisp_Object_Type::Symbol): fprintf(file, "%s", Memory::get_c_str(node->value.identifier)); break;
case (Lisp_Object_Type::Keyword): fprintf(file, ":%s", Memory::get_c_str(node->value.identifier)); break;
case (Lisp_Object_Type::CFunction): fprintf(file, "[C-function]"); break;
case (Lisp_Object_Type::Nil): fputs("()", file); break;
case (Lisp_Object_Type::T): fputs("t", file); break;
case (Lisp_Object_Type::Number): fprintf(file, "%f", node->value.number); break;
case (Lisp_Object_Type::Keyword): fputs(":", file); // NOTE(Felix): intentionall fallthough
case (Lisp_Object_Type::Symbol): fprintf(file, Memory::get_c_str(node->value.identifier)); break;
case (Lisp_Object_Type::CFunction): fputs("[C-function]", file); break;
case (Lisp_Object_Type::String): {
if (print_quotes)
fprintf(file, "\"%s\"", Memory::get_c_str(node->value.string));
if (print_quotes) {
putc('\"', file);
fputs(Memory::get_c_str(node->value.string), file);
putc('\"', file);
}
else
fprintf(file, "%s", Memory::get_c_str(node->value.string));
fputs(Memory::get_c_str(node->value.string), file);
} break;
case (Lisp_Object_Type::Function): {
if (node->value.function.type == Function_Type::Lambda)
fprintf(file, "[lambda]");
fputs("[lambda]", file);
else if (node->value.function.type == Function_Type::Special_Lambda)
fprintf(file, "[special-lambda]");
fputs("[special-lambda]", file);
else if (node->value.function.type == Function_Type::Macro)
fprintf(file, "[macro]");
fputs("[macro]", file);
else
assert(false);
} break;
case (Lisp_Object_Type::Pair): {
Lisp_Object* head = node;
fprintf(file, "(");
putc('(', file);

// NOTE(Felix): We cold do a while true here, however in case
// we want to print a broken list (for logging the error) we
@@ -266,38 +270,39 @@ proc print(Lisp_Object* node, bool print_quotes = false, FILE* file = stdout) ->
return;
if (head->type != Lisp_Object_Type::Pair)
break;
fprintf(file, " ");
putc(' ', file);
}

if (head->type != Lisp_Object_Type::Nil) {
fprintf(file, " . ");
fputs(" . ", file);
print(head);
}

fprintf(file, ")");
putc(')', file);
} break;
}
}


proc print_error_location() -> void {
if (current_source_code) {
if (Globals::current_source_code) {
printf("%s (line %d, position %d) code:" console_red "\n ",
Memory::get_c_str(
current_source_code->sourceCodeLocation->file),
current_source_code->sourceCodeLocation->line,
current_source_code->sourceCodeLocation->column);
print(current_source_code);
Globals::current_source_code->sourceCodeLocation->file),
Globals::current_source_code->sourceCodeLocation->line,
Globals::current_source_code->sourceCodeLocation->column);
print(Globals::current_source_code);
} else {
printf("no source code location avaliable");
fputs("no source code location avaliable", stdout);
}
}

proc log_error() -> void {
printf("%s%s%s\n", console_red,
Memory::get_c_str(error->message),
console_normal);
printf(" in: %s", console_cyan);
fputs(console_red, stdout);
fputs(Memory::get_c_str(Globals::error->message), stdout);
puts(console_normal);

fputs(" in: " console_cyan, stdout);
print_error_location();
printf("%s\n", console_normal);
puts(console_normal);
}

+ 8
- 6
src/main.cpp Прегледај датотеку

@@ -1,17 +1,19 @@
#include "slime.h"

// using namespace Slime;

int main(int argc, char* argv[]) {
if (argc > 1) {
if (Slime::string_equal(argv[1], "--run-tests")) {
return Slime::run_all_tests() ? 0 : 1;
if (string_equal(argv[1], "--run-tests")) {
return run_all_tests() ? 0 : 1;
}

Slime::interprete_file(argv[1]);
if (Slime::error) {
Slime::log_error();
interprete_file(argv[1]);
if (Globals::error) {
log_error();
return 1;
}
} else {
Slime::interprete_stdin();
interprete_stdin();
}
}

+ 2
- 2
src/slime.h Прегледај датотеку

@@ -12,7 +12,7 @@
#undef _CRT_SECURE_NO_DEPRECATE
#undef _CRT_SECURE_NO_WARNINGS

namespace Slime {
// namespace Slime {
# include "./defines.cpp"
# include "./structs.cpp"
# include "./forward_decls.cpp"
@@ -26,4 +26,4 @@ namespace Slime {
# include "./built_ins.cpp"
# include "./testing.cpp"
# include "./undefines.cpp"
}
// }

+ 42
- 42
src/testing.cpp Прегледај датотеку

@@ -29,20 +29,20 @@
}

#define assert_no_error() \
if (error) { \
print_assert_equal_fail(error, 0, size_t, "%zd"); \
if (Globals::error) { \
print_assert_equal_fail(Globals::error, 0, size_t, "%zd"); \
printf("\nExpected no error to occur," \
" but an error occured anyways:\n"); \
log_error(); \
return fail; \
} \

#define assert_error() \
if (!error) { \
print_assert_not_equal_fail(error, 0, size_t, "%zd"); \
printf("\nExpected an error to occur," \
" but no error occured:\n"); \
return fail; \
#define assert_error() \
if (!Globals::error) { \
print_assert_not_equal_fail(Globals::error, 0, size_t, "%zd"); \
printf("\nExpected an error to occur," \
" but no error occured:\n"); \
return fail; \
} \

#define assert_equal_double(variable, value) \
@@ -77,40 +77,40 @@
#define assert_not_null(variable) \
assert_not_equal_int(variable, nullptr)

#define invoke_test(name) \
printf("" #name ":"); \
if (name() == pass) { \
for(size_t i = strlen(#name); i < 70; ++i) \
printf((i%3==1)? "." : " "); \
printf("%spassed%s\n", console_green, console_normal); \
} \
else { \
result = false; \
for(int i = -1; i < 70; ++i) \
printf((i%3==1)? "." : " "); \
printf("%sfailed%s\n", console_red, console_normal); \
if(error) { \
free(error); \
error = nullptr; \
} \
} \
#define invoke_test(name) \
fputs("" #name ":", stdout); \
if (name() == pass) { \
for(size_t i = strlen(#name); i < 70; ++i) \
fputs((i%3==1)? "." : " ", stdout); \
fputs(console_green "passed\n" console_normal, stdout); \
} \
else { \
result = false; \
for(int i = -1; i < 70; ++i) \
fputs((i%3==1)? "." : " ", stdout); \
fputs(console_red "failed\n" console_normal, stdout); \
if(Globals::error) { \
free(Globals::error); \
Globals::error = nullptr; \
} \
} \

#define invoke_test_script(name) \
printf("" name ":"); \
if (test_file("tests/" name ".slime") == pass) { \
for(size_t i = strlen(name); i < 70; ++i) \
printf((i%3==1)? "." : " "); \
printf("%spassed%s\n", console_green, console_normal); \
} \
else { \
result = false; \
for(int i = -1; i < 70; ++i) \
printf((i%3==1)? "." : " "); \
printf("%sfailed%s\n", console_red, console_normal); \
if(error) { \
free(error); \
error = nullptr; \
} \
#define invoke_test_script(name) \
fputs("" name ":", stdout); \
if (test_file("tests/" name ".slime") == pass) { \
for(size_t i = strlen(name); i < 70; ++i) \
fputs((i%3==1)? "." : " ", stdout); \
fputs(console_green "passed\n" console_normal, stdout); \
} \
else { \
result = false; \
for(int i = -1; i < 70; ++i) \
fputs((i%3==1)? "." : " ", stdout); \
fputs(console_red "failed\n" console_normal, stdout); \
if(Globals::error) { \
free(Globals::error); \
Globals::error = nullptr; \
} \
}

proc test_eval_operands() -> testresult {
@@ -480,7 +480,7 @@ proc test_singular_t_and_nil() -> testresult {

proc test_file(const char* file) -> testresult {
Memory::reset();
static Environment* env = Memory::create_built_ins_environment();
Environment* env = Memory::create_built_ins_environment();

Parser::init(env);



Loading…
Откажи
Сачувај