|
|
|
@@ -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); |
|
|
|
|