auto doc generation

This commit is contained in:
Felix Brendel
2019-06-11 01:17:36 +02:00
parent d01269aa13
commit 6f5ecc87b0
22 changed files with 2375 additions and 229 deletions
+98 -61
View File
@@ -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);
+160
View File
@@ -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
View File
@@ -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]);
+2 -1
View File
@@ -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;
+4
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
+1
View File
@@ -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
View File
@@ -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;