From 69737d5cdf3d23fdabe1ae927fab3c4f67eb1812 Mon Sep 17 00:00:00 2001 From: FelixBrendel Date: Sun, 21 Apr 2019 21:55:33 +0200 Subject: [PATCH 1/2] assert argument length --- src/defines.cpp | 7 +++++++ src/memory.cpp | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/defines.cpp b/src/defines.cpp index e07905c..ba70d41 100644 --- a/src/defines.cpp +++ b/src/defines.cpp @@ -148,6 +148,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 { \ 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); From 987dbcdd62b0730bdd47d1bf91a5c6687df483b5 Mon Sep 17 00:00:00 2001 From: FelixBrendel Date: Sun, 21 Apr 2019 21:56:59 +0200 Subject: [PATCH 2/2] pre merge --- bin/pre.slime | 10 +++++----- bin/tests/class_macro.slime | 2 +- src/defines.cpp | 9 ++++++++- src/parse.cpp | 34 +++++++++++++++------------------- 4 files changed, 29 insertions(+), 26 deletions(-) diff --git a/bin/pre.slime b/bin/pre.slime index f838b97..fe6b0c5 100644 --- a/bin/pre.slime +++ b/bin/pre.slime @@ -1,8 +1,8 @@ -(define-syntax when (condition :rest body) +(define-syntax (when condition :rest body) "Doc String for 'when'" `(if ,condition ,(pair prog body) nil)) -(define-syntax unless (condition :rest body) +(define-syntax (unless condition :rest body) `(if ,condition nil ,(pair prog body))) ;; (define-syntax defun (name arguments :rest body) @@ -116,11 +116,11 @@ the (rest) of the last element of the sequence." with (pair elem nil)." (extend seq (pair elem nil))) -(define-syntax extend! (seq elem) +(define-syntax (extend! seq elem) "test" `(mutate ,seq (extend ,seq ,elem))) -(define-syntax append! (seq elem) +(define-syntax (append! seq elem) `(mutate ,seq (append ,seq ,elem))) (define (length seq) @@ -237,5 +237,5 @@ las argument." (eval (pair printf-quoted (extend (list :@sep (eval sep) :@end (eval end)) args)))) -(define-syntax pe (expr) +(define-syntax (pe expr) `(printf ',expr "evaluates to" ,(eval expr))) 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..f55c575 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__) @@ -156,6 +155,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/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);