auto doc generation
This commit is contained in:
+98
-61
@@ -32,6 +32,8 @@ proc lisp_object_equal(Lisp_Object* n1, Lisp_Object* n2) -> bool {
|
||||
proc built_in_load(String* file_name, Environment* env) -> Lisp_Object* {
|
||||
// char* full_file_name = find_slime_file(file_name);
|
||||
char* file_content;
|
||||
char fullpath[4096];
|
||||
sprintf(fullpath, "%s", Memory::get_c_str(file_name));
|
||||
file_content = read_entire_file(Memory::get_c_str(file_name));
|
||||
|
||||
if (!file_content) {
|
||||
@@ -43,8 +45,8 @@ proc built_in_load(String* file_name, Environment* env) -> Lisp_Object* {
|
||||
defer {
|
||||
free(exe_path);
|
||||
};
|
||||
char fullpath[4096];
|
||||
|
||||
fullpath[0] = '\0';
|
||||
sprintf(fullpath, "%s%s", exe_path, Memory::get_c_str(file_name));
|
||||
// printf("Fullpath: %s\n", fullpath);
|
||||
file_content = read_entire_file(fullpath);
|
||||
@@ -59,7 +61,7 @@ proc built_in_load(String* file_name, Environment* env) -> Lisp_Object* {
|
||||
|
||||
Lisp_Object* result = Memory::nil;
|
||||
Lisp_Object_Array_List* program;
|
||||
try program = Parser::parse_program(file_name, file_content);
|
||||
try program = Parser::parse_program(Memory::create_string(fullpath), file_content);
|
||||
|
||||
for (int i = 0; i < program->next_index; ++i) {
|
||||
try result = eval_expr(program->data[i], env);
|
||||
@@ -86,13 +88,20 @@ proc built_in_import(String* file_name, Environment* env) -> Lisp_Object* {
|
||||
proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
int arguments_length;
|
||||
Lisp_Object* evaluated_arguments;
|
||||
String* file_name_built_ins = Memory::create_string(__FILE__);
|
||||
|
||||
#define cLambda [=](Lisp_Object* arguments, Environment* env) mutable -> Lisp_Object*
|
||||
|
||||
proc defun = [&](const char* name, auto fun) {
|
||||
// TODO(Felix): inline the params again after debugging
|
||||
proc defun = [&](const char* name, const char* docs, int linenum, auto fun) {
|
||||
auto sym = Memory::get_or_create_lisp_object_symbol(name);
|
||||
auto sfun = Memory::create_lisp_object_cfunction(fun);
|
||||
|
||||
sfun->sourceCodeLocation = new(Source_Code_Location);
|
||||
sfun->sourceCodeLocation->file = file_name_built_ins;
|
||||
sfun->sourceCodeLocation->line = linenum;
|
||||
sfun->sourceCodeLocation->column = 0;
|
||||
|
||||
sfun->docstring = Memory::create_string(docs);
|
||||
define_symbol(sym, sfun, env);
|
||||
};
|
||||
|
||||
@@ -126,10 +135,10 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
arguments = arguments->value.pair.rest;
|
||||
// if there is a docstring, use it
|
||||
if (Memory::get_type(arguments->value.pair.first) == Lisp_Object_Type::String) {
|
||||
ret->value.function.docstring = arguments->value.pair.first->value.string;
|
||||
ret->docstring = arguments->value.pair.first->value.string;
|
||||
arguments = arguments->value.pair.rest;
|
||||
} else {
|
||||
ret->value.function.docstring = nullptr;
|
||||
ret->docstring = nullptr;
|
||||
}
|
||||
|
||||
// we are now in the function body, just wrap it in an
|
||||
@@ -143,7 +152,10 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
return ret;
|
||||
};
|
||||
|
||||
defun("=", cLambda {
|
||||
defun("=",
|
||||
"Takes 0 or more arguments and returns =t= if all arguments are equal "
|
||||
"and =()= otherwise.",
|
||||
__LINE__, cLambda {
|
||||
int arguments_length;
|
||||
try arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
|
||||
@@ -160,7 +172,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
|
||||
return Memory::t;
|
||||
});
|
||||
defun(">", cLambda {
|
||||
defun(">", "TODO", __LINE__, cLambda {
|
||||
int arguments_length;
|
||||
try arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
|
||||
@@ -178,7 +190,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
|
||||
return Memory::t;
|
||||
});
|
||||
defun(">=", cLambda {
|
||||
defun(">=", "TODO", __LINE__, cLambda {
|
||||
int arguments_length;
|
||||
try arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
|
||||
@@ -196,7 +208,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
|
||||
return Memory::t;
|
||||
});
|
||||
defun("<", cLambda {
|
||||
defun("<", "TODO", __LINE__, cLambda {
|
||||
int arguments_length;
|
||||
try {
|
||||
arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
@@ -216,7 +228,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
|
||||
return Memory::t;
|
||||
});
|
||||
defun("<=", cLambda {
|
||||
defun("<=", "TODO", __LINE__, cLambda {
|
||||
int arguments_length;
|
||||
try arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
|
||||
@@ -234,7 +246,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
|
||||
return Memory::t;
|
||||
});
|
||||
defun("+", cLambda {
|
||||
defun("+", "TODO", __LINE__, cLambda {
|
||||
int arguments_length;
|
||||
try arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
|
||||
@@ -247,7 +259,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
}
|
||||
return Memory::create_lisp_object_number(sum);
|
||||
});
|
||||
defun("-", cLambda {
|
||||
defun("-", "TODO", __LINE__, cLambda {
|
||||
int arguments_length;
|
||||
try arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
|
||||
@@ -270,7 +282,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
}
|
||||
return Memory::create_lisp_object_number(difference);
|
||||
});
|
||||
defun("*", cLambda {
|
||||
defun("*", "TODO", __LINE__, cLambda {
|
||||
int arguments_length;
|
||||
try arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
|
||||
@@ -291,7 +303,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
}
|
||||
return Memory::create_lisp_object_number(product);
|
||||
});
|
||||
defun("/", cLambda {
|
||||
defun("/", "TODO", __LINE__, cLambda {
|
||||
int arguments_length;
|
||||
try arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
|
||||
@@ -312,7 +324,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
}
|
||||
return Memory::create_lisp_object_number(quotient);
|
||||
});
|
||||
defun("**", cLambda {
|
||||
defun("**", "TODO", __LINE__, cLambda {
|
||||
int arguments_length;
|
||||
try arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
try assert_arguments_length(2, arguments_length);
|
||||
@@ -328,7 +340,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
|
||||
return Memory::create_lisp_object_number(pow(base, exponent));
|
||||
});
|
||||
defun("%", cLambda {
|
||||
defun("%", "TODO", __LINE__, cLambda {
|
||||
int arguments_length;
|
||||
try arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
try assert_arguments_length(2, arguments_length);
|
||||
@@ -344,7 +356,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
|
||||
return Memory::create_lisp_object_number((int)a % (int)b);
|
||||
});
|
||||
defun("assert", cLambda {
|
||||
defun("assert", "TODO", __LINE__, cLambda {
|
||||
int arguments_length;
|
||||
|
||||
try arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
@@ -356,7 +368,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
create_generic_error("Userland assertion.");
|
||||
return nullptr;
|
||||
});
|
||||
defun("define", cLambda {
|
||||
defun("define", "TODO", __LINE__, cLambda {
|
||||
|
||||
try arguments_length = list_length(arguments);
|
||||
try assert_arguments_length_greater_equal(2, arguments_length);
|
||||
@@ -396,19 +408,29 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
value = parse_lambda_starting_from_args(fake_lambda, env);
|
||||
symbol = real_symbol;
|
||||
} else {
|
||||
try assert_arguments_length_less_equal(2, arguments_length);
|
||||
try assert_arguments_length_greater_equal(2, arguments_length);
|
||||
try assert_arguments_length_less_equal(3, arguments_length);
|
||||
String* doc = nullptr;
|
||||
if (arguments_length == 3) {
|
||||
try assert_type(arguments->value.pair.rest->value.pair.first, Lisp_Object_Type::String);
|
||||
doc = arguments->value.pair.rest->value.pair.first->value.string;
|
||||
arguments = arguments->value.pair.rest;
|
||||
}
|
||||
|
||||
try assert_type(symbol, Lisp_Object_Type::Symbol);
|
||||
|
||||
value = arguments->value.pair.rest->value.pair.first;
|
||||
|
||||
try value = eval_expr(value, env);
|
||||
if (doc)
|
||||
value->docstring = doc;
|
||||
}
|
||||
|
||||
define_symbol(symbol, value, env);
|
||||
|
||||
return value;
|
||||
});
|
||||
defun("mutate", cLambda {
|
||||
defun("mutate", "TODO", __LINE__, cLambda {
|
||||
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
try assert_arguments_length(2, arguments_length);
|
||||
Lisp_Object* target = evaluated_arguments->value.pair.first;
|
||||
@@ -433,7 +455,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
*target = *source;
|
||||
return target;
|
||||
});
|
||||
defun("if", cLambda {
|
||||
defun("if", "TODO", __LINE__, cLambda {
|
||||
try arguments_length = list_length(arguments);
|
||||
try assert_arguments_length_greater_equal(2, arguments_length);
|
||||
try assert_arguments_length_less_equal(3, arguments_length);
|
||||
@@ -455,12 +477,12 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
|
||||
return result;
|
||||
});
|
||||
defun("quote", cLambda {
|
||||
defun("quote", "TODO", __LINE__, cLambda {
|
||||
try arguments_length = list_length(arguments);
|
||||
try assert_arguments_length(1, arguments_length);
|
||||
return arguments->value.pair.first;
|
||||
});
|
||||
defun("quasiquote", cLambda {
|
||||
defun("quasiquote", "TODO", __LINE__, cLambda {
|
||||
try arguments_length = list_length(arguments);
|
||||
try assert_arguments_length(1, arguments_length);
|
||||
|
||||
@@ -558,7 +580,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
ret = unquoteSomeExpressions(ret);
|
||||
return ret;
|
||||
});
|
||||
defun("and", cLambda {
|
||||
defun("and", "TODO", __LINE__, cLambda {
|
||||
bool result = true;
|
||||
while (arguments != Memory::nil) {
|
||||
try assert_type(arguments, Lisp_Object_Type::Pair);
|
||||
@@ -569,7 +591,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
}
|
||||
return Memory::t;
|
||||
});
|
||||
defun("or", cLambda {
|
||||
defun("or", "TODO", __LINE__, cLambda {
|
||||
bool result = false;
|
||||
while (arguments != Memory::nil) {
|
||||
try assert_type(arguments, Lisp_Object_Type::Pair);
|
||||
@@ -580,7 +602,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
}
|
||||
return Memory::nil;
|
||||
});
|
||||
defun("not", cLambda {
|
||||
defun("not", "TODO", __LINE__, cLambda {
|
||||
try arguments_length = list_length(arguments);
|
||||
try assert_arguments_length(1, arguments_length);
|
||||
|
||||
@@ -590,7 +612,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
|
||||
return (truthy) ? Memory::nil : Memory::t;
|
||||
});
|
||||
defun("while", cLambda {
|
||||
defun("while", "TODO", __LINE__, cLambda {
|
||||
try arguments_length = list_length(arguments);
|
||||
try assert(arguments_length >= 2);
|
||||
|
||||
@@ -616,7 +638,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
return result;
|
||||
|
||||
});
|
||||
// defun("let", cLambda {
|
||||
// defun("let", "TODO", __LINE__, cLambda {
|
||||
// // (let ((a 10)(b 20)) (body1) (body2))
|
||||
// try arguments_length = list_length(arguments);
|
||||
// try assert_arguments_length_greater_equal(1, arguments_length);
|
||||
@@ -668,7 +690,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
// }
|
||||
// return evaluated_arguments->value.pair.first;
|
||||
// });
|
||||
defun("lambda", cLambda {
|
||||
defun("lambda", "TODO", __LINE__, cLambda {
|
||||
/* TODO(Felix): first one crashes
|
||||
* (lambda ())
|
||||
* (lambda (x d) (+ 1 2) (- 1 2) (* 1 2))
|
||||
@@ -680,7 +702,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
|
||||
return function;
|
||||
});
|
||||
defun("special-lambda", cLambda {
|
||||
defun("special-lambda", "TODO", __LINE__, cLambda {
|
||||
try arguments_length = list_length(arguments);
|
||||
try assert_arguments_length_greater_equal(1, arguments_length);
|
||||
|
||||
@@ -688,7 +710,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
|
||||
return function;
|
||||
});
|
||||
defun("eval", cLambda {
|
||||
defun("eval", "TODO", __LINE__, cLambda {
|
||||
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
try assert_arguments_length(1, arguments_length);
|
||||
|
||||
@@ -700,11 +722,11 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
});
|
||||
|
||||
|
||||
defun("begin", cLambda {
|
||||
defun("begin", "TODO", __LINE__, cLambda {
|
||||
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
|
||||
if (evaluated_arguments == Memory::nil)
|
||||
return evaluated_arguments;
|
||||
return Memory::nil;
|
||||
|
||||
// skip to the last evaluated operand and return it,
|
||||
// we use eval_arguments here instead of doing it
|
||||
@@ -716,11 +738,11 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
}
|
||||
return evaluated_arguments->value.pair.first;
|
||||
});
|
||||
defun("list", cLambda {
|
||||
defun("list", "TODO", __LINE__, cLambda {
|
||||
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
return evaluated_arguments;
|
||||
});
|
||||
defun("pair", cLambda {
|
||||
defun("pair", "TODO", __LINE__, cLambda {
|
||||
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
try assert_arguments_length(2, arguments_length);
|
||||
|
||||
@@ -730,7 +752,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
evaluated_arguments->value.pair.rest->value.pair.first);
|
||||
return ret;
|
||||
});
|
||||
defun("first", cLambda {
|
||||
defun("first", "TODO", __LINE__, cLambda {
|
||||
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
try assert_arguments_length(1, arguments_length);
|
||||
|
||||
@@ -741,7 +763,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
|
||||
return evaluated_arguments->value.pair.first->value.pair.first;
|
||||
});
|
||||
defun("rest", cLambda {
|
||||
defun("rest", "TODO", __LINE__, cLambda {
|
||||
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
try assert_arguments_length(1, arguments_length);
|
||||
|
||||
@@ -752,7 +774,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
|
||||
return evaluated_arguments->value.pair.first->value.pair.rest;
|
||||
});
|
||||
defun("set-type", cLambda {
|
||||
defun("set-type", "TODO", __LINE__, cLambda {
|
||||
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
try assert_arguments_length(2, arguments_length);
|
||||
|
||||
@@ -764,14 +786,14 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
object->userType = type;
|
||||
return object;
|
||||
});
|
||||
defun("delete-type", cLambda {
|
||||
defun("delete-type", "TODO", __LINE__, cLambda {
|
||||
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
try assert_arguments_length(1, arguments_length);
|
||||
|
||||
evaluated_arguments->value.pair.first->userType = nullptr;
|
||||
return Memory::t;
|
||||
});
|
||||
defun("type", cLambda {
|
||||
defun("type", "TODO", __LINE__, cLambda {
|
||||
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
try assert_arguments_length(1, arguments_length);
|
||||
|
||||
@@ -803,7 +825,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
}
|
||||
return Memory::get_or_create_lisp_object_keyword("unknown");
|
||||
});
|
||||
defun("info", cLambda {
|
||||
defun("info", "TODO", __LINE__, cLambda {
|
||||
try arguments_length = list_length(arguments);
|
||||
try assert_arguments_length(1, arguments_length);
|
||||
|
||||
@@ -817,9 +839,15 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
env);
|
||||
|
||||
if (type) {
|
||||
Lisp_Object* val = eval_expr(arguments->value.pair.first, env);
|
||||
printf(" is of type ");
|
||||
print(type);
|
||||
printf("\n\n");
|
||||
printf("\nand is printed as: ");
|
||||
print(val);
|
||||
printf("\n\ndocs: \n %s\n",
|
||||
(val->docstring)
|
||||
? Memory::get_c_str(val->docstring)
|
||||
: "No docs avaliable");
|
||||
|
||||
// TODO(Felix): Maybe don't compare strings here?? Wtf
|
||||
if (Memory::get_type(type) == Lisp_Object_Type::Keyword &&
|
||||
@@ -829,8 +857,8 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
{
|
||||
Lisp_Object* fun = eval_expr(arguments->value.pair.first, env);
|
||||
|
||||
if (fun->value.function.docstring)
|
||||
printf("Docstring:\n==========\n%s\n\n", Memory::get_c_str(fun->value.function.docstring));
|
||||
if (fun->docstring)
|
||||
printf("Docstring:\n==========\n%s\n\n", Memory::get_c_str(fun->docstring));
|
||||
else
|
||||
printf("No docstring avaliable\n");
|
||||
|
||||
@@ -879,7 +907,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
|
||||
return Memory::nil;
|
||||
});
|
||||
defun("show", cLambda {
|
||||
defun("show", "TODO", __LINE__, cLambda {
|
||||
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
try assert_arguments_length(1, arguments_length);
|
||||
try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::Function);
|
||||
@@ -891,13 +919,22 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
|
||||
return Memory::nil;
|
||||
});
|
||||
defun("addr-of", cLambda {
|
||||
defun("addr-of", "TODO", __LINE__, cLambda {
|
||||
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
try assert_arguments_length(1, arguments_length);
|
||||
|
||||
return Memory::create_lisp_object_number((u64)&(evaluated_arguments->value.pair.first->value));
|
||||
});
|
||||
defun("print", cLambda {
|
||||
defun("generate-docs", "TODO", __LINE__, cLambda {
|
||||
try arguments_length = list_length(arguments);
|
||||
try assert_arguments_length(1, arguments_length);
|
||||
try assert_type(arguments->value.pair.first, Lisp_Object_Type::String);
|
||||
|
||||
generate_docs(env, arguments->value.pair.first->value.string);
|
||||
|
||||
return Memory::t;
|
||||
});
|
||||
defun("print", "TODO", __LINE__, cLambda {
|
||||
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
try assert_arguments_length(1, arguments_length);
|
||||
|
||||
@@ -905,7 +942,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
|
||||
return Memory::nil;
|
||||
});
|
||||
defun("read", cLambda {
|
||||
defun("read", "TODO", __LINE__, cLambda {
|
||||
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
try assert_arguments_length_less_equal(1, arguments_length);
|
||||
|
||||
@@ -922,7 +959,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
String* strLine = Memory::create_string(line);
|
||||
return Memory::create_lisp_object_string(strLine);
|
||||
});
|
||||
defun("exit", cLambda {
|
||||
defun("exit", "TODO", __LINE__, cLambda {
|
||||
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
try assert_arguments_length_less_equal(1, arguments_length);
|
||||
|
||||
@@ -933,16 +970,16 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
}
|
||||
exit(0);
|
||||
});
|
||||
defun("break", cLambda {
|
||||
defun("break", "TODO", __LINE__, cLambda {
|
||||
print_environment(env);
|
||||
debug_break();
|
||||
return Memory::nil;
|
||||
});
|
||||
defun("memstat", cLambda {
|
||||
defun("memstat", "TODO", __LINE__, cLambda {
|
||||
Memory::print_status();
|
||||
return Memory::nil;
|
||||
});
|
||||
defun("try", cLambda {
|
||||
defun("try", "TODO", __LINE__, cLambda {
|
||||
try arguments_length = list_length(arguments);
|
||||
try assert_arguments_length(2, arguments_length);
|
||||
|
||||
@@ -957,7 +994,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
}
|
||||
return result;
|
||||
});
|
||||
defun("load", cLambda {
|
||||
defun("load", "TODO", __LINE__, cLambda {
|
||||
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
try assert_arguments_length(1, arguments_length);
|
||||
try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::String);
|
||||
@@ -968,7 +1005,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
return result;
|
||||
|
||||
});
|
||||
defun("import", cLambda {
|
||||
defun("import", "TODO", __LINE__, cLambda {
|
||||
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
try assert_arguments_length(1, arguments_length);
|
||||
try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::String);
|
||||
@@ -979,7 +1016,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
return result;
|
||||
|
||||
});
|
||||
defun("copy", cLambda {
|
||||
defun("copy", "TODO", __LINE__, cLambda {
|
||||
// TODO(Felix): if we are copying string nodes, then
|
||||
// shouldn't the string itself also get copied??
|
||||
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
@@ -987,14 +1024,14 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
|
||||
return Memory::copy_lisp_object(evaluated_arguments->value.pair.first);
|
||||
});
|
||||
defun("error", cLambda {
|
||||
defun("error", "TODO", __LINE__, cLambda {
|
||||
// TODO(Felix): make the error function useful
|
||||
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
try assert_arguments_length(0, arguments_length);
|
||||
create_generic_error("Userlanderror");
|
||||
return nullptr;
|
||||
});
|
||||
defun("symbol->keyword", cLambda {
|
||||
defun("symbol->keyword", "TODO", __LINE__, cLambda {
|
||||
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
try assert_arguments_length(1, arguments_length);
|
||||
try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::Symbol);
|
||||
@@ -1003,7 +1040,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
|
||||
return Memory::get_or_create_lisp_object_keyword(source->value.symbol.identifier);
|
||||
});
|
||||
defun("string->symbol", cLambda {
|
||||
defun("string->symbol", "TODO", __LINE__, cLambda {
|
||||
// TODO(Felix): do some sanity checks on the string. For
|
||||
// example, numbers are not valid symbols.
|
||||
|
||||
@@ -1015,7 +1052,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
|
||||
return Memory::get_or_create_lisp_object_symbol(Memory::duplicate_string(source->value.string));
|
||||
});
|
||||
defun("symbol->string", cLambda {
|
||||
defun("symbol->string", "TODO", __LINE__, cLambda {
|
||||
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
try assert_arguments_length(1, arguments_length);
|
||||
try assert_type(evaluated_arguments->value.pair.first, Lisp_Object_Type::Symbol);
|
||||
@@ -1024,7 +1061,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
||||
|
||||
return Memory::create_lisp_object_string(Memory::duplicate_string(source->value.symbol.identifier));
|
||||
});
|
||||
defun("concat-strings", cLambda {
|
||||
defun("concat-strings", "TODO", __LINE__, cLambda {
|
||||
try evaluated_arguments = eval_arguments(arguments, env, &arguments_length);
|
||||
try assert_arguments_length_greater_equal(1, arguments_length);
|
||||
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
proc generate_docs(Environment* env, String* path) -> void {
|
||||
// save the current working directory
|
||||
char cwd[1024];
|
||||
getcwd(cwd, 1024);
|
||||
// get the direction of the exe
|
||||
char* exe_path = exe_dir();
|
||||
chdir(exe_path);
|
||||
free(exe_path);
|
||||
|
||||
defer {
|
||||
// switch back to the users directory
|
||||
chdir(cwd);
|
||||
};
|
||||
|
||||
FILE *f = fopen(Memory::get_c_str(path), "w");
|
||||
if (!f) {
|
||||
create_generic_error("The file for writing the documentation "
|
||||
"could not be opened for writing.");
|
||||
return;
|
||||
}
|
||||
defer {
|
||||
fclose(f);
|
||||
};
|
||||
|
||||
Environment_Array_List* visited = create_Environment_array_list();
|
||||
|
||||
std::function<void(Environment*, char* prefix)> print_this_env;
|
||||
print_this_env = [&](Environment* env, char* prefix) -> void {
|
||||
bool we_already_printed = false;
|
||||
// TODO(Felix): Make a generic array_list_contains function
|
||||
for (int i = 0; i < visited->next_index; ++i) {
|
||||
if (visited->data[i] == env) {
|
||||
we_already_printed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!we_already_printed) {
|
||||
append_to_array_list(visited, env);
|
||||
for (int i = 0; i < env->next_index; ++i) {
|
||||
fprintf(f, "\n* =%s%s= \n"
|
||||
// " :PROPERTIES:\n"
|
||||
// " :UNNUMBERED: t\n"
|
||||
// " :END:"
|
||||
,prefix, env->keys[i]);
|
||||
/*
|
||||
* sourcecodeLocation
|
||||
*/
|
||||
if (env->values[i]->sourceCodeLocation) {
|
||||
fprintf(f, "\n - defined in :: =%s:%d:%d=",
|
||||
Memory::get_c_str(env->values[i]->sourceCodeLocation->file),
|
||||
env->values[i]->sourceCodeLocation->line,
|
||||
env->values[i]->sourceCodeLocation->column);
|
||||
}
|
||||
/*
|
||||
* type
|
||||
*/
|
||||
Lisp_Object_Type type = Memory::get_type(env->values[i]);
|
||||
Lisp_Object* LOtype;
|
||||
try_void LOtype = eval_expr(Memory::create_list(
|
||||
Memory::get_or_create_lisp_object_symbol("type"),
|
||||
env->values[i]), env);
|
||||
|
||||
fprintf(f, "\n - type :: =");
|
||||
print(LOtype, true, f);
|
||||
fprintf(f, "=");
|
||||
|
||||
|
||||
/*
|
||||
* if printable value -> print it
|
||||
*/
|
||||
switch (type) {
|
||||
case(Lisp_Object_Type::Nil):
|
||||
case(Lisp_Object_Type::T):
|
||||
case(Lisp_Object_Type::Number):
|
||||
case(Lisp_Object_Type::String):
|
||||
case(Lisp_Object_Type::Pair):
|
||||
case(Lisp_Object_Type::Symbol):
|
||||
case(Lisp_Object_Type::Keyword): {
|
||||
fprintf(f, "\n - value :: =");
|
||||
print(env->values[i], true, f);
|
||||
fprintf(f, "=");
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
/*
|
||||
* if function then print arguments
|
||||
*/
|
||||
if (type == Lisp_Object_Type::Function) {
|
||||
Lisp_Object* fun = env->values[i];
|
||||
bool printed_at_least_some_args = false;
|
||||
fprintf(f, "\n - arguments :: ");
|
||||
if (fun->value.function.positional_arguments->next_index != 0) {
|
||||
if (!printed_at_least_some_args)
|
||||
fprintf(f, ":");
|
||||
fprintf(f, "\n - postitional :: ");
|
||||
fprintf(f, "=%s=", Memory::get_c_str(fun->value.function.positional_arguments->identifiers[0]));
|
||||
for (int i = 1; i < fun->value.function.positional_arguments->next_index; ++i) {
|
||||
fprintf(f, ", =%s=", Memory::get_c_str(fun->value.function.positional_arguments->identifiers[i]));
|
||||
}
|
||||
}
|
||||
if (fun->value.function.keyword_arguments->next_index != 0) {
|
||||
if (!printed_at_least_some_args)
|
||||
fprintf(f, ":");
|
||||
fprintf(f, "\n - keyword :: ");
|
||||
fprintf(f, "=%s=", Memory::get_c_str(fun->value.function.keyword_arguments->identifiers[0]));
|
||||
if (fun->value.function.keyword_arguments->values->data[0]) {
|
||||
fprintf(f, " =(");
|
||||
print(fun->value.function.keyword_arguments->values->data[0], true, f);
|
||||
fprintf(f, ")=");
|
||||
}
|
||||
for (int i = 1; i < fun->value.function.keyword_arguments->next_index; ++i) {
|
||||
fprintf(f, ", =%s=", Memory::get_c_str(fun->value.function.keyword_arguments->identifiers[i]));
|
||||
if (fun->value.function.keyword_arguments->values->data[i]) {
|
||||
fprintf(f, " =(");
|
||||
print(fun->value.function.keyword_arguments->values->data[i], true, f);
|
||||
fprintf(f, ")=");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fun->value.function.rest_argument) {
|
||||
if (!printed_at_least_some_args)
|
||||
fprintf(f, ":");
|
||||
fprintf(f, "\n - rest :: =%s=", Memory::get_c_str(fun->value.function.rest_argument));
|
||||
}
|
||||
// if no args at all
|
||||
if (fun->value.function.positional_arguments->next_index == 0 &&
|
||||
fun->value.function.keyword_arguments->next_index == 0 &&
|
||||
!fun->value.function.rest_argument)
|
||||
{
|
||||
fprintf(f, "none.");
|
||||
}
|
||||
}
|
||||
fprintf(f, "\n - docu :: ");
|
||||
if (env->values[i]->docstring)
|
||||
fprintf(f, "\n #+BEGIN:\n%s\n #+END:\n",
|
||||
Memory::get_c_str(env->values[i]->docstring));
|
||||
else
|
||||
fprintf(f, "none\n");
|
||||
|
||||
if (Memory::get_type(env->values[i]) == Lisp_Object_Type::Function &&
|
||||
env->values[i]->userType &&
|
||||
(string_equal(env->values[i]->userType->value.symbol.identifier, "package") ||
|
||||
string_equal(env->values[i]->userType->value.symbol.identifier, "constructor")))
|
||||
{
|
||||
char new_prefix[200];
|
||||
strcpy(new_prefix, prefix);
|
||||
strcat(new_prefix, env->keys[i]);
|
||||
strcat(new_prefix, " ");
|
||||
print_this_env(env->values[i]->value.function.parent_environment, new_prefix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < env->parents->next_index; ++i) {
|
||||
print_this_env(env->parents->data[i], prefix);
|
||||
}
|
||||
};
|
||||
|
||||
print_this_env(env, (char*)"");
|
||||
}
|
||||
+5
-5
@@ -68,11 +68,11 @@ proc print_indent(int indent) -> void {
|
||||
}
|
||||
|
||||
proc print_environment_indent(Environment* env, int indent) -> void {
|
||||
// if(env == Globals::root_environment) {
|
||||
// print_indent(indent);
|
||||
// printf("[built-ins]-Environment (%lld)\n", (long long)env);
|
||||
// return;
|
||||
// }
|
||||
if(env == Globals::root_environment) {
|
||||
print_indent(indent);
|
||||
printf("[built-ins]-Environment (%lld)\n", (long long)env);
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < env->next_index; ++i) {
|
||||
print_indent(indent);
|
||||
print(env->values[i]);
|
||||
|
||||
@@ -17,6 +17,7 @@ proc exe_dir() -> char*;
|
||||
proc Lisp_Object_Type_to_string(Lisp_Object_Type type) -> const char*;
|
||||
|
||||
proc visualize_lisp_machine() -> void;
|
||||
proc generate_docs(Environment* env, String* path) -> void;
|
||||
|
||||
namespace Memory {
|
||||
proc create_built_ins_environment() -> Environment*;
|
||||
@@ -27,7 +28,7 @@ namespace Memory {
|
||||
|
||||
namespace Parser {
|
||||
extern Environment* environment_for_macros;
|
||||
|
||||
|
||||
extern String* standard_in;
|
||||
extern String* parser_file;
|
||||
extern int parser_line;
|
||||
|
||||
@@ -260,6 +260,10 @@ proc print(Lisp_Object* node, bool print_quotes = false, FILE* file = stdout) ->
|
||||
fputs(Memory::get_c_str(node->value.string), file);
|
||||
} break;
|
||||
case (Lisp_Object_Type::Function): {
|
||||
if (node->userType) {
|
||||
fprintf(file, "[%s]", Memory::get_c_str(node->userType->value.symbol.identifier));
|
||||
break;
|
||||
}
|
||||
if (node->value.function.type == Function_Type::Lambda)
|
||||
fputs("[lambda]", file);
|
||||
else if (node->value.function.type == Function_Type::Special_Lambda)
|
||||
|
||||
+1
-3
@@ -5,9 +5,7 @@ int main(int argc, char* argv[]) {
|
||||
if (argc > 1) {
|
||||
if (Slime::string_equal(argv[1], "--run-tests")) {
|
||||
return Slime::run_all_tests() ? 0 : 1;
|
||||
} else if (Slime::string_equal(argv[1], "--run-as-emacs-repl")) {
|
||||
Slime::interprete_stdin(true);
|
||||
}
|
||||
}
|
||||
|
||||
Slime::interprete_file(argv[1]);
|
||||
if (Slime::Globals::error) {
|
||||
|
||||
+2
-1
@@ -154,7 +154,8 @@ namespace Memory {
|
||||
Lisp_Object* object = object_memory+index;
|
||||
object->flags = 0;
|
||||
object->sourceCodeLocation = nullptr;
|
||||
object->userType = nullptr;
|
||||
object->userType = nullptr;
|
||||
object->docstring = nullptr;
|
||||
return object;
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -412,10 +412,10 @@ namespace Parser {
|
||||
// arguments = arguments->value.pair.rest;
|
||||
// if there is a docstring, use it
|
||||
if (Memory::get_type(body->value.pair.first) == Lisp_Object_Type::String) {
|
||||
macro->value.function.docstring = body->value.pair.first->value.string;
|
||||
macro->docstring = body->value.pair.first->value.string;
|
||||
body = body->value.pair.rest;
|
||||
} else {
|
||||
macro->value.function.docstring = nullptr;
|
||||
macro->docstring = nullptr;
|
||||
}
|
||||
|
||||
// we are now in the function body, just wrap it in an
|
||||
@@ -424,6 +424,7 @@ namespace Parser {
|
||||
Memory::get_or_create_lisp_object_symbol("begin"),
|
||||
body);
|
||||
|
||||
inject_scl(macro);
|
||||
// macro->value.function = function;
|
||||
define_symbol(symbol_for_macro, macro, environment_for_macros);
|
||||
|
||||
@@ -567,7 +568,7 @@ namespace Parser {
|
||||
};
|
||||
|
||||
if (f == NULL) {
|
||||
printf("Error opening file!\n");
|
||||
printf("Error opening .expanded file for writing!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ namespace Slime {
|
||||
# include "./parse.cpp"
|
||||
# include "./eval.cpp"
|
||||
# include "./visualization.cpp"
|
||||
# include "./docgeneration.cpp"
|
||||
# include "./built_ins.cpp"
|
||||
# include "./testing.cpp"
|
||||
# include "./undefines.cpp"
|
||||
|
||||
+1
-1
@@ -93,7 +93,6 @@ struct Keyword_Arguments {
|
||||
|
||||
struct Function {
|
||||
Function_Type type;
|
||||
String* docstring;
|
||||
Positional_Arguments* positional_arguments;
|
||||
Keyword_Arguments* keyword_arguments;
|
||||
// rest_argument will be nullptr if no rest argument is declared
|
||||
@@ -110,6 +109,7 @@ struct Lisp_Object {
|
||||
Source_Code_Location* sourceCodeLocation;
|
||||
u64 flags;
|
||||
Lisp_Object* userType;
|
||||
String* docstring;
|
||||
union {
|
||||
Symbol symbol; // used for symbols and keywords
|
||||
double number;
|
||||
|
||||
Reference in New Issue
Block a user