diff --git a/bin/tests/class_macro.slime b/bin/tests/class_macro.slime index 33fdd3c..38988d3 100644 --- a/bin/tests/class_macro.slime +++ b/bin/tests/class_macro.slime @@ -2,7 +2,7 @@ (set-type obj type) obj) -(define-syntax defclass (name members :rest body) +(define-syntax (defclass name members :rest body) "Macro for creating classes." (define (underscore sym) (string->symbol (concat-strings "_" (symbol->string sym)))) diff --git a/src/defines.cpp b/src/defines.cpp index e07905c..fbd49e0 100644 --- a/src/defines.cpp +++ b/src/defines.cpp @@ -122,7 +122,6 @@ struct { Memory::get_or_create_lisp_object_keyword(keyword), \ __VA_ARGS__) - #define create_out_of_memory_error(...) \ __create_error("out-of-memory", __VA_ARGS__) @@ -148,6 +147,13 @@ struct { "Wrong number of arguments: expected %d, got %d", \ expected, actual) +#define assert_arguments_length(expected, actual) \ + do { \ + if (expected != actual) { \ + create_wrong_number_of_arguments_error(expected, actual); \ + } \ + } while(0) + #define assert_type(_node, _type) \ do { \ @@ -156,6 +162,14 @@ struct { } \ } while(0) +#define assert_arguments_length(expected, actual) \ + do { \ + if (expexted != actual) { \ + create_wrong_number_of_arguments_error(expected, actual); \ + } \ + } while(0) + + #define assert(condition) \ do { \ if (!(condition)) { \ diff --git a/src/memory.cpp b/src/memory.cpp index 3446346..dd7e177 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -180,7 +180,7 @@ namespace Memory { return node; } - proc create_lisp_object_string(char* str) -> Lisp_Object* { + proc create_lisp_object_string(const char* str) -> Lisp_Object* { Lisp_Object* node = create_lisp_object(); set_type(node, Lisp_Object_Type::String); node->value.string = create_string(str); diff --git a/src/parse.cpp b/src/parse.cpp index 036ef36..7820320 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -356,25 +356,25 @@ namespace Parser { if (string_equal("define-syntax", expression->value.pair.first->value.identifier)) { // create a new macro Lisp_Object* arguments = expression->value.pair.rest; + Lisp_Object* body; int arguments_length; // HACK(Felix): almost code duplicate from // `built_ins.cpp`: special-lambda - try { - arguments_length = list_length(arguments); - } + try arguments_length = list_length(arguments); - // (define-syntax defun (name args :rest body) (...)) + // (define-syntax (defun name args :rest body) (...)) if (arguments_length < 2) { create_wrong_number_of_arguments_error(3, arguments_length); return nullptr; } - assert_type(arguments->value.pair.first, Lisp_Object_Type::Symbol); + assert_type(arguments->value.pair.first, Lisp_Object_Type::Pair); // extract the name - Lisp_Object* symbol_for_macro = arguments->value.pair.first; - arguments = arguments->value.pair.rest; + Lisp_Object* symbol_for_macro = arguments->value.pair.first->value.pair.first; + body = arguments->value.pair.rest; + arguments = arguments->value.pair.first->value.pair.rest; // Function* function = new(Function); Lisp_Object* macro = Memory::create_lisp_object(); @@ -383,24 +383,20 @@ namespace Parser { macro->value.function.type = Function_Type::Macro; // if parameters were specified - if (Memory::get_type(arguments->value.pair.first) != Lisp_Object_Type::Nil) { - try { - assert_type(arguments->value.pair.first, Lisp_Object_Type::Pair); - } - try { - parse_argument_list(arguments->value.pair.first, ¯o->value.function); - } + if (arguments != Memory::nil) { + try assert_type(arguments, Lisp_Object_Type::Pair); + try parse_argument_list(arguments, ¯o->value.function); } else { macro->value.function.positional_arguments = create_positional_argument_list(1); macro->value.function.keyword_arguments = create_keyword_argument_list(1); macro->value.function.rest_argument = nullptr; } - arguments = arguments->value.pair.rest; + // arguments = arguments->value.pair.rest; // if there is a docstring, use it - if (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::String) { - macro->value.function.docstring = arguments->value.pair.first->value.string; - arguments = arguments->value.pair.rest; + if (Memory::get_type(body->value.pair.first) == Lisp_Object_Type::String) { + macro->value.function.docstring = body->value.pair.first->value.string; + body = body->value.pair.rest; } else { macro->value.function.docstring = nullptr; } @@ -409,7 +405,7 @@ namespace Parser { // implicit prog macro->value.function.body = Memory::create_lisp_object_pair( Memory::get_or_create_lisp_object_symbol("prog"), - arguments); + body); // macro->value.function = function; define_symbol(symbol_for_macro, macro, environment_for_macros);