switched to form char* to Strings mostly
This commit is contained in:
+26
-25
@@ -29,9 +29,7 @@ proc lisp_object_equal(Lisp_Object* n1, Lisp_Object* n2) -> bool {
|
|||||||
create_error(Error_Type::Not_Yet_Implemented, n1->sourceCodeLocation);
|
create_error(Error_Type::Not_Yet_Implemented, n1->sourceCodeLocation);
|
||||||
return false;
|
return false;
|
||||||
case Lisp_Object_Type::String:
|
case Lisp_Object_Type::String:
|
||||||
return string_equal(
|
return string_equal(n1->value.string, n2->value.string);
|
||||||
n1->value.string->value,
|
|
||||||
n2->value.string->value);
|
|
||||||
case Lisp_Object_Type::Symbol:
|
case Lisp_Object_Type::Symbol:
|
||||||
return string_equal(
|
return string_equal(
|
||||||
n1->value.symbol->identifier,
|
n1->value.symbol->identifier,
|
||||||
@@ -270,8 +268,8 @@ proc built_in_exponentiate(Lisp_Object* arguments, Environment* env) -> Lisp_Obj
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
proc built_in_load(const char* file_name, Environment* env) -> Lisp_Object* {
|
proc built_in_load(String* file_name, Environment* env) -> Lisp_Object* {
|
||||||
char* file_content = read_entire_file(file_name);
|
char* file_content = read_entire_file(Memory::get_c_str(file_name));
|
||||||
if (file_content) {
|
if (file_content) {
|
||||||
Lisp_Object* result = Memory::create_lisp_object_nil();
|
Lisp_Object* result = Memory::create_lisp_object_nil();
|
||||||
Lisp_Object_Array_List* program;
|
Lisp_Object_Array_List* program;
|
||||||
@@ -670,7 +668,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
arguments = arguments->value.pair->rest;
|
arguments = arguments->value.pair->rest;
|
||||||
// if there is a docstring, use it
|
// if there is a docstring, use it
|
||||||
if (arguments->value.pair->first->type == Lisp_Object_Type::String) {
|
if (arguments->value.pair->first->type == Lisp_Object_Type::String) {
|
||||||
function->docstring = arguments->value.pair->first->value.string->value;
|
function->docstring = arguments->value.pair->first->value.string;
|
||||||
arguments = arguments->value.pair->rest;
|
arguments = arguments->value.pair->rest;
|
||||||
} else {
|
} else {
|
||||||
function->docstring = nullptr;
|
function->docstring = nullptr;
|
||||||
@@ -720,7 +718,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
arguments = arguments->value.pair->rest;
|
arguments = arguments->value.pair->rest;
|
||||||
// if there is a docstring, use it
|
// if there is a docstring, use it
|
||||||
if (arguments->value.pair->first->type == Lisp_Object_Type::String) {
|
if (arguments->value.pair->first->type == Lisp_Object_Type::String) {
|
||||||
function->docstring = arguments->value.pair->first->value.string->value;
|
function->docstring = arguments->value.pair->first->value.string;
|
||||||
arguments = arguments->value.pair->rest;
|
arguments = arguments->value.pair->rest;
|
||||||
} else {
|
} else {
|
||||||
function->docstring = nullptr;
|
function->docstring = nullptr;
|
||||||
@@ -876,29 +874,33 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
Lisp_Object* fun = eval_expr(arguments->value.pair->first, env);
|
Lisp_Object* fun = eval_expr(arguments->value.pair->first, env);
|
||||||
|
|
||||||
if (fun->value.function->docstring)
|
if (fun->value.function->docstring)
|
||||||
printf("Docstring:\n==========\n%s\n\n", fun->value.function->docstring);
|
printf("Docstring:\n==========\n%s\n\n", Memory::get_c_str(fun->value.function->docstring));
|
||||||
else
|
else
|
||||||
printf("No docstring avaliable\n");
|
printf("No docstring avaliable\n");
|
||||||
|
|
||||||
printf("Arguments:\n==========\n");
|
printf("Arguments:\n==========\n");
|
||||||
printf("Postitional: {");
|
printf("Postitional: {");
|
||||||
if (fun->value.function->positional_arguments->next_index != 0) {
|
if (fun->value.function->positional_arguments->next_index != 0) {
|
||||||
printf("%s", fun->value.function->positional_arguments->identifiers[0]);
|
printf("%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) {
|
for (int i = 1; i < fun->value.function->positional_arguments->next_index; ++i) {
|
||||||
printf(", %s", fun->value.function->positional_arguments->identifiers[i]);
|
printf(", %s",
|
||||||
|
Memory::get_c_str(fun->value.function->positional_arguments->identifiers[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("}\n");
|
printf("}\n");
|
||||||
printf("Keyword: {");
|
printf("Keyword: {");
|
||||||
if (fun->value.function->keyword_arguments->next_index != 0) {
|
if (fun->value.function->keyword_arguments->next_index != 0) {
|
||||||
printf("%s", fun->value.function->keyword_arguments->identifiers[0]);
|
printf("%s",
|
||||||
|
Memory::get_c_str(fun->value.function->keyword_arguments->identifiers[0]));
|
||||||
if (fun->value.function->keyword_arguments->values->data[0]) {
|
if (fun->value.function->keyword_arguments->values->data[0]) {
|
||||||
printf(" (");
|
printf(" (");
|
||||||
print(fun->value.function->keyword_arguments->values->data[0]);
|
print(fun->value.function->keyword_arguments->values->data[0]);
|
||||||
printf(")");
|
printf(")");
|
||||||
}
|
}
|
||||||
for (int i = 1; i < fun->value.function->keyword_arguments->next_index; ++i) {
|
for (int i = 1; i < fun->value.function->keyword_arguments->next_index; ++i) {
|
||||||
printf(", %s", fun->value.function->keyword_arguments->identifiers[i]);
|
printf(", %s",
|
||||||
|
Memory::get_c_str(fun->value.function->keyword_arguments->identifiers[i]));
|
||||||
if (fun->value.function->keyword_arguments->values->data[i]) {
|
if (fun->value.function->keyword_arguments->values->data[i]) {
|
||||||
printf(" (");
|
printf(" (");
|
||||||
print(fun->value.function->keyword_arguments->values->data[i]);
|
print(fun->value.function->keyword_arguments->values->data[i]);
|
||||||
@@ -909,7 +911,8 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
printf("}\n");
|
printf("}\n");
|
||||||
printf("Rest: {");
|
printf("Rest: {");
|
||||||
if (fun->value.function->rest_argument)
|
if (fun->value.function->rest_argument)
|
||||||
printf("%s", fun->value.function->rest_argument);
|
printf("%s",
|
||||||
|
Memory::get_c_str(fun->value.function->rest_argument));
|
||||||
printf("}\n");
|
printf("}\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -948,7 +951,9 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
print(evaluated_arguments->value.pair->first);
|
print(evaluated_arguments->value.pair->first);
|
||||||
}
|
}
|
||||||
char* line = read_line();
|
char* line = read_line();
|
||||||
return Memory::create_lisp_object_string(line, (int)strlen(line));
|
String* strLine = Memory::create_string(line);
|
||||||
|
free(line);
|
||||||
|
return Memory::create_lisp_object_string(strLine);
|
||||||
});
|
});
|
||||||
defun("exit", cLambda {
|
defun("exit", cLambda {
|
||||||
try {
|
try {
|
||||||
@@ -1012,8 +1017,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
|
|
||||||
Lisp_Object* result;
|
Lisp_Object* result;
|
||||||
try {
|
try {
|
||||||
result = built_in_load(
|
result = built_in_load(evaluated_arguments->value.pair->first->value.string, env);
|
||||||
evaluated_arguments->value.pair->first->value.string->value, env);
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
@@ -1070,7 +1074,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
report_error(Error_Type::Type_Missmatch);
|
report_error(Error_Type::Type_Missmatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Memory::create_lisp_object_symbol(_strdup(source->value.string->value));
|
return Memory::create_lisp_object_symbol(Memory::duplicate_string(source->value.string));
|
||||||
});
|
});
|
||||||
defun("symbol->string", cLambda {
|
defun("symbol->string", cLambda {
|
||||||
try {
|
try {
|
||||||
@@ -1086,9 +1090,7 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
if (source->type != Lisp_Object_Type::Symbol) {
|
if (source->type != Lisp_Object_Type::Symbol) {
|
||||||
report_error(Error_Type::Type_Missmatch);
|
report_error(Error_Type::Type_Missmatch);
|
||||||
}
|
}
|
||||||
|
return Memory::create_lisp_object_string(Memory::duplicate_string(source->value.symbol->identifier));
|
||||||
// TODO(Felix): this is not really fast what we are doing here:
|
|
||||||
return Memory::create_lisp_object_string(_strdup(source->value.symbol->identifier), (int)strlen(source->value.symbol->identifier));
|
|
||||||
});
|
});
|
||||||
defun("concat-strings", cLambda {
|
defun("concat-strings", cLambda {
|
||||||
try {
|
try {
|
||||||
@@ -1114,18 +1116,17 @@ proc load_built_ins_into_environment(Environment* env) -> void {
|
|||||||
|
|
||||||
head = evaluated_arguments;
|
head = evaluated_arguments;
|
||||||
|
|
||||||
char* resulting_string = (char*)malloc(resulting_string_len * sizeof(char)) + 1;
|
String* resulting_string = Memory::create_string("", resulting_string_len);
|
||||||
int index_in_string = 0;
|
int index_in_string = 0;
|
||||||
|
|
||||||
while (head->type == Lisp_Object_Type::Pair) {
|
while (head->type == Lisp_Object_Type::Pair) {
|
||||||
strcpy(resulting_string+index_in_string, head->value.pair->first->value.string->value);
|
strcpy((&resulting_string->data)+index_in_string,
|
||||||
|
Memory::get_c_str(head->value.pair->first->value.string));
|
||||||
index_in_string += head->value.pair->first->value.string->length;
|
index_in_string += head->value.pair->first->value.string->length;
|
||||||
head = head->value.pair->rest;
|
head = head->value.pair->rest;
|
||||||
}
|
}
|
||||||
|
|
||||||
resulting_string[index_in_string] = '\0';
|
return Memory::create_lisp_object_string(resulting_string);
|
||||||
|
|
||||||
return Memory::create_lisp_object_string(resulting_string, resulting_string_len);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
#undef report_error
|
#undef report_error
|
||||||
|
|||||||
+5
-5
@@ -11,14 +11,14 @@ proc define_symbol(Lisp_Object* symbol, Lisp_Object* value, Environment* env) ->
|
|||||||
env->values = (Lisp_Object**)realloc(env->values, env->capacity * sizeof(Lisp_Object*));
|
env->values = (Lisp_Object**)realloc(env->values, env->capacity * sizeof(Lisp_Object*));
|
||||||
}
|
}
|
||||||
|
|
||||||
env->keys [env->next_index] = symbol->value.symbol->identifier;
|
env->keys [env->next_index] = Memory::get_c_str(symbol->value.symbol->identifier);
|
||||||
env->values[env->next_index] = value;
|
env->values[env->next_index] = value;
|
||||||
++env->next_index;
|
++env->next_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc lookup_symbol_in_this_envt(Symbol* sym, Environment* env) -> Lisp_Object* {
|
proc lookup_symbol_in_this_envt(Symbol* sym, Environment* env) -> Lisp_Object* {
|
||||||
for (int i = env->next_index - 1; i >= 0; --i)
|
for (int i = env->next_index - 1; i >= 0; --i)
|
||||||
if (string_equal(env->keys[i], sym->identifier))
|
if (string_equal(env->keys[i], Memory::get_c_str(sym->identifier)))
|
||||||
return env->values[i];
|
return env->values[i];
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -38,15 +38,15 @@ proc lookup_symbol(Lisp_Object* node, Environment* env) -> Lisp_Object* {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string_equal(sym->identifier, "nil")) {
|
if (string_equal(Memory::get_c_str(sym->identifier), "nil")) {
|
||||||
return Memory::create_lisp_object_nil();
|
return Memory::create_lisp_object_nil();
|
||||||
}
|
}
|
||||||
if (string_equal(sym->identifier, "t")) {
|
if (string_equal(Memory::get_c_str(sym->identifier), "t")) {
|
||||||
return Memory::create_lisp_object_t();
|
return Memory::create_lisp_object_t();
|
||||||
}
|
}
|
||||||
|
|
||||||
create_error(Error_Type::Symbol_Not_Defined, node->sourceCodeLocation);
|
create_error(Error_Type::Symbol_Not_Defined, node->sourceCodeLocation);
|
||||||
printf("%s\n", sym->identifier);
|
printf("%s\n", Memory::get_c_str(sym->identifier));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-6
@@ -18,7 +18,7 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->
|
|||||||
arguments = arguments->value.pair->rest;
|
arguments = arguments->value.pair->rest;
|
||||||
}
|
}
|
||||||
|
|
||||||
String_Array_List* read_in_keywords = create_String_array_list(16);
|
String_Array_List* read_in_keywords = create_String_array_list();
|
||||||
|
|
||||||
if (arguments->type == Lisp_Object_Type::Nil)
|
if (arguments->type == Lisp_Object_Type::Nil)
|
||||||
goto checks;
|
goto checks;
|
||||||
@@ -86,7 +86,7 @@ proc apply_arguments_to_function(Lisp_Object* arguments, Function* function) ->
|
|||||||
checks:
|
checks:
|
||||||
// check if all necessary keywords have been read in
|
// check if all necessary keywords have been read in
|
||||||
for (int i = 0; i < function->keyword_arguments->next_index; ++i) {
|
for (int i = 0; i < function->keyword_arguments->next_index; ++i) {
|
||||||
char* defined_keyword = function->keyword_arguments->identifiers[i];
|
String* defined_keyword = function->keyword_arguments->identifiers[i];
|
||||||
bool was_set = false;
|
bool was_set = false;
|
||||||
for (int j = 0; j < read_in_keywords->next_index; ++j) {
|
for (int j = 0; j < read_in_keywords->next_index; ++j) {
|
||||||
if (string_equal(
|
if (string_equal(
|
||||||
@@ -439,12 +439,13 @@ proc interprete_file (char* file_name) -> Lisp_Object* {
|
|||||||
load_built_ins_into_environment(env);
|
load_built_ins_into_environment(env);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
built_in_load("pre.slime", env);
|
built_in_load(Memory::create_string("pre.slime"), env);
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object_Array_List* program;
|
Lisp_Object_Array_List* program;
|
||||||
try {
|
try {
|
||||||
program = Parser::parse_program(file_name, file_content);
|
program = Parser::parse_program(
|
||||||
|
Memory::create_string(file_name), file_content);
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* result = Memory::create_lisp_object_nil();
|
Lisp_Object* result = Memory::create_lisp_object_nil();
|
||||||
@@ -466,8 +467,8 @@ proc interprete_stdin() -> void {
|
|||||||
|
|
||||||
char* line;
|
char* line;
|
||||||
|
|
||||||
built_in_load("pre.slime", env);
|
built_in_load(Memory::create_string("pre.slime"), env);
|
||||||
built_in_load("test.slime", env);
|
built_in_load(Memory::create_string("test.slime"), env);
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
log_error();
|
log_error();
|
||||||
@@ -479,6 +480,7 @@ proc interprete_stdin() -> void {
|
|||||||
printf(">");
|
printf(">");
|
||||||
line = read_expression();
|
line = read_expression();
|
||||||
parsed = Parser::parse_single_expression(line);
|
parsed = Parser::parse_single_expression(line);
|
||||||
|
free(line);
|
||||||
if (error) {
|
if (error) {
|
||||||
log_error();
|
log_error();
|
||||||
delete_error();
|
delete_error();
|
||||||
|
|||||||
@@ -5,3 +5,4 @@ proc is_truthy (Lisp_Object*, Environment*) -> bool;
|
|||||||
proc list_length(Lisp_Object*) -> int;
|
proc list_length(Lisp_Object*) -> int;
|
||||||
proc load_built_ins_into_environment(Environment*) -> void;
|
proc load_built_ins_into_environment(Environment*) -> void;
|
||||||
proc parse_argument_list(Lisp_Object*, Function*) -> void;
|
proc parse_argument_list(Lisp_Object*, Function*) -> void;
|
||||||
|
proc create_error(Error_Type type, Source_Code_Location* location) -> void;
|
||||||
|
|||||||
+35
-21
@@ -8,6 +8,18 @@ proc string_equal(const char input[], const char check[]) -> bool {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc string_equal(String* str, const char check[]) -> bool {
|
||||||
|
return string_equal(Memory::get_c_str(str), check);
|
||||||
|
}
|
||||||
|
|
||||||
|
proc string_equal(const char check[], String* str) -> bool {
|
||||||
|
return string_equal(Memory::get_c_str(str), check);
|
||||||
|
}
|
||||||
|
|
||||||
|
proc string_equal(String* str1, String* str2) -> bool {
|
||||||
|
return string_equal(Memory::get_c_str(str1), Memory::get_c_str(str2));
|
||||||
|
}
|
||||||
|
|
||||||
proc get_nibble(char c) -> char {
|
proc get_nibble(char c) -> char {
|
||||||
if (c >= 'A' && c <= 'F')
|
if (c >= 'A' && c <= 'F')
|
||||||
return (c - 'a') + 10;
|
return (c - 'a') + 10;
|
||||||
@@ -67,7 +79,7 @@ proc unescape_string(char* in) -> bool {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc read_entire_file (const char* filename) -> char* {
|
proc read_entire_file(char* filename) -> char* {
|
||||||
char *fileContent = nullptr;
|
char *fileContent = nullptr;
|
||||||
FILE *fp = fopen(filename, "r");
|
FILE *fp = fopen(filename, "r");
|
||||||
if (fp) {
|
if (fp) {
|
||||||
@@ -106,7 +118,8 @@ proc read_entire_file (const char* filename) -> char* {
|
|||||||
}
|
}
|
||||||
|
|
||||||
proc read_expression() -> char* {
|
proc read_expression() -> char* {
|
||||||
char* line = (char*)malloc(100), * linep = line;
|
char* line = (char*)malloc(100);
|
||||||
|
char* linep = line;
|
||||||
size_t lenmax = 100, len = lenmax;
|
size_t lenmax = 100, len = lenmax;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
@@ -132,20 +145,20 @@ proc read_expression() -> char* {
|
|||||||
linep = linen;
|
linep = linen;
|
||||||
}
|
}
|
||||||
|
|
||||||
line++;
|
*line = (char)c;
|
||||||
if((*line = (char)c) == '(')
|
if(*line == '(')
|
||||||
++nesting;
|
++nesting;
|
||||||
else if((*line = (char)c) == ')')
|
else if(*line == ')')
|
||||||
--nesting;
|
--nesting;
|
||||||
else if((*line = (char)c) == '\n')
|
else if(*line == '\n')
|
||||||
if (nesting == 0)
|
if (nesting == 0)
|
||||||
break;
|
break;
|
||||||
|
line++;
|
||||||
}
|
}
|
||||||
(*line)--; // we dont want the \n actually
|
(*line)--; // we dont want the \n actually
|
||||||
*line = '\0';
|
*line = '\0';
|
||||||
// BUG(Felix): Why do we have to add 1 here?
|
|
||||||
|
|
||||||
return linep + 1;
|
return linep;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc read_line() -> char* {
|
proc read_line() -> char* {
|
||||||
@@ -175,19 +188,20 @@ proc read_line() -> char* {
|
|||||||
linep = linen;
|
linep = linen;
|
||||||
}
|
}
|
||||||
|
|
||||||
line++;
|
*line = (char)c;
|
||||||
if((*line = (char)c) == '(')
|
if(*line == '(')
|
||||||
++nesting;
|
++nesting;
|
||||||
else if((*line = (char)c) == ')')
|
else if(*line == ')')
|
||||||
--nesting;
|
--nesting;
|
||||||
else if((*line = (char)c) == '\n')
|
else if(*line == '\n')
|
||||||
if (nesting == 0)
|
if (nesting == 0)
|
||||||
break;
|
break;
|
||||||
|
line++;
|
||||||
}
|
}
|
||||||
(*line)--; // we dont want the \n actually
|
(*line)--; // we dont want the \n actually
|
||||||
*line = '\0';
|
*line = '\0';
|
||||||
// BUG(Felix): Why do we have to add 1 here?
|
|
||||||
return linep + 1;
|
return linep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -225,13 +239,13 @@ proc print(Lisp_Object* node) -> void {
|
|||||||
printf("%f", node->value.number->value);
|
printf("%f", node->value.number->value);
|
||||||
} break;
|
} break;
|
||||||
case (Lisp_Object_Type::String): {
|
case (Lisp_Object_Type::String): {
|
||||||
printf("\"%s\"", node->value.string->value);
|
printf("\"%s\"", Memory::get_c_str(node->value.string));
|
||||||
} break;
|
} break;
|
||||||
case (Lisp_Object_Type::Symbol): {
|
case (Lisp_Object_Type::Symbol): {
|
||||||
printf("%s", node->value.symbol->identifier);
|
printf("%s", Memory::get_c_str(node->value.symbol->identifier));
|
||||||
} break;
|
} break;
|
||||||
case (Lisp_Object_Type::Keyword): {
|
case (Lisp_Object_Type::Keyword): {
|
||||||
printf(":%s", node->value.keyword->identifier);
|
printf(":%s", Memory::get_c_str(node->value.keyword->identifier));
|
||||||
} break;
|
} break;
|
||||||
case (Lisp_Object_Type::Function): {
|
case (Lisp_Object_Type::Function): {
|
||||||
if (node->value.function->type == Function_Type::Lambda)
|
if (node->value.function->type == Function_Type::Lambda)
|
||||||
@@ -286,13 +300,13 @@ proc fprint(FILE* f, Lisp_Object* node) -> void {
|
|||||||
fprintf(f, "%f", node->value.number->value);
|
fprintf(f, "%f", node->value.number->value);
|
||||||
} break;
|
} break;
|
||||||
case (Lisp_Object_Type::String): {
|
case (Lisp_Object_Type::String): {
|
||||||
fprintf(f, "\"%s\"", node->value.string->value);
|
fprintf(f, "\"%s\"", Memory::get_c_str(node->value.string));
|
||||||
} break;
|
} break;
|
||||||
case (Lisp_Object_Type::Symbol): {
|
case (Lisp_Object_Type::Symbol): {
|
||||||
fprintf(f, "%s", node->value.symbol->identifier);
|
fprintf(f, "%s", Memory::get_c_str(node->value.symbol->identifier));
|
||||||
} break;
|
} break;
|
||||||
case (Lisp_Object_Type::Keyword): {
|
case (Lisp_Object_Type::Keyword): {
|
||||||
fprintf(f, ":%s", node->value.keyword->identifier);
|
fprintf(f, ":%s", Memory::get_c_str(node->value.keyword->identifier));
|
||||||
} break;
|
} break;
|
||||||
case (Lisp_Object_Type::Function): {
|
case (Lisp_Object_Type::Function): {
|
||||||
if (node->value.function->type == Function_Type::Lambda)
|
if (node->value.function->type == Function_Type::Lambda)
|
||||||
@@ -337,7 +351,7 @@ proc fprint(FILE* f, Lisp_Object* node) -> void {
|
|||||||
proc print_error_location() -> void {
|
proc print_error_location() -> void {
|
||||||
if (error->location) {
|
if (error->location) {
|
||||||
printf("%s (line %d, position %d)",
|
printf("%s (line %d, position %d)",
|
||||||
error->location->file,
|
Memory::get_c_str(error->location->file),
|
||||||
error->location->line,
|
error->location->line,
|
||||||
error->location->column);
|
error->location->column);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+8
-8
@@ -1,4 +1,4 @@
|
|||||||
proc create_source_code_location(const char* file, int line, int col) -> Source_Code_Location* {
|
proc create_source_code_location(String* file, int line, int col) -> Source_Code_Location* {
|
||||||
if (!file)
|
if (!file)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
@@ -26,23 +26,23 @@ proc Lisp_Object_Type_to_string(Lisp_Object_Type type) -> const char* {
|
|||||||
|
|
||||||
proc create_positional_argument_list(int initial_capacity) -> Positional_Arguments* {
|
proc create_positional_argument_list(int initial_capacity) -> Positional_Arguments* {
|
||||||
Positional_Arguments* ret = new(Positional_Arguments);
|
Positional_Arguments* ret = new(Positional_Arguments);
|
||||||
ret->identifiers = (char**)malloc(initial_capacity * sizeof(char*));
|
ret->identifiers = (String**)malloc(initial_capacity * sizeof(String*));
|
||||||
ret->next_index = 0;
|
ret->next_index = 0;
|
||||||
ret->length = initial_capacity;
|
ret->length = initial_capacity;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc append_to_positional_argument_list(Positional_Arguments* args, char* identifier) -> void {
|
proc append_to_positional_argument_list(Positional_Arguments* args, String* identifier) -> void {
|
||||||
if (args->next_index == args->length) {
|
if (args->next_index == args->length) {
|
||||||
args->length *= 2;
|
args->length *= 2;
|
||||||
args->identifiers = (char**)realloc(args->identifiers, args->length * sizeof(char*));
|
args->identifiers = (String**)realloc(args->identifiers, args->length * sizeof(String*));
|
||||||
}
|
}
|
||||||
args->identifiers[args->next_index++] = identifier;
|
args->identifiers[args->next_index++] = identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc create_keyword_argument_list(int initial_capacity) -> Keyword_Arguments* {
|
proc create_keyword_argument_list(int initial_capacity) -> Keyword_Arguments* {
|
||||||
Keyword_Arguments* ret = new(Keyword_Arguments);
|
Keyword_Arguments* ret = new(Keyword_Arguments);
|
||||||
ret->identifiers = (char**)malloc(initial_capacity * sizeof(char*));
|
ret->identifiers = (String**)malloc(initial_capacity * sizeof(String*));
|
||||||
ret->values = create_Lisp_Object_array_list(initial_capacity);
|
ret->values = create_Lisp_Object_array_list(initial_capacity);
|
||||||
ret->next_index = 0;
|
ret->next_index = 0;
|
||||||
ret->length = initial_capacity;
|
ret->length = initial_capacity;
|
||||||
@@ -50,12 +50,12 @@ proc create_keyword_argument_list(int initial_capacity) -> Keyword_Arguments* {
|
|||||||
}
|
}
|
||||||
|
|
||||||
proc append_to_keyword_argument_list(Keyword_Arguments* args,
|
proc append_to_keyword_argument_list(Keyword_Arguments* args,
|
||||||
char* identifier,
|
String* identifier,
|
||||||
struct Lisp_Object* default_value) -> void
|
Lisp_Object* default_value) -> void
|
||||||
{
|
{
|
||||||
if (args->next_index == args->length) {
|
if (args->next_index == args->length) {
|
||||||
args->length *= 2;
|
args->length *= 2;
|
||||||
args->identifiers = (char**)realloc(args->identifiers, args->length * sizeof(char*));
|
args->identifiers = (String**)realloc(args->identifiers, args->length * sizeof(String*));
|
||||||
}
|
}
|
||||||
|
|
||||||
args->identifiers[args->next_index++] = identifier;
|
args->identifiers[args->next_index++] = identifier;
|
||||||
|
|||||||
+97
-30
@@ -1,40 +1,100 @@
|
|||||||
namespace Memory {
|
namespace Memory {
|
||||||
|
|
||||||
constexpr int maxLispObjects = 4096 * 1024; // == 98304kb == 96mb
|
// ------------------
|
||||||
Int_Array_List* freeSpots;
|
// lisp_object
|
||||||
Lisp_Object* memory;
|
// ------------------
|
||||||
int nextFreeSpot = 0;
|
constexpr int object_memory_size = 4096 * 1024; // == 98304kb == 96mb
|
||||||
|
Int_Array_List* free_spots_in_object_memory;
|
||||||
|
Lisp_Object* object_memory;
|
||||||
|
int next_index_in_object_memory = 0;
|
||||||
|
|
||||||
proc init() -> void {
|
// ------------------
|
||||||
memory = (Lisp_Object*)malloc(maxLispObjects * sizeof(Lisp_Object));
|
// strings
|
||||||
freeSpots = create_Int_array_list();
|
// ------------------
|
||||||
|
constexpr int string_memory_size = 4096 * 1024; // == 98304kb == 96mb
|
||||||
|
// free_spots_in_string_memory is an arraylist of pointers into
|
||||||
|
// the string_memory, where dead String objects live (which give
|
||||||
|
// information about their size)
|
||||||
|
Void_Ptr_Array_List* free_spots_in_string_memory;
|
||||||
|
String* string_memory;
|
||||||
|
String* next_free_spot_in_string_memory;
|
||||||
|
|
||||||
|
proc init() {
|
||||||
|
free_spots_in_object_memory = create_Int_array_list();
|
||||||
|
free_spots_in_string_memory = create_Void_Ptr_array_list();
|
||||||
|
|
||||||
|
object_memory = (Lisp_Object*)malloc(object_memory_size * sizeof(Lisp_Object));
|
||||||
|
string_memory = (String*)malloc(object_memory_size * sizeof(Lisp_Object));
|
||||||
|
|
||||||
|
next_free_spot_in_string_memory = string_memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc print_status() -> void {
|
proc print_status() {
|
||||||
printf("Memory Status:\n"
|
printf("Memory Status:\n"
|
||||||
" - %f%% of the memory is used\n"
|
" - %f%% of the object_memory is used\n"
|
||||||
" - %d of %d total Lisp_Objects are in use\n"
|
" - %d of %d total Lisp_Objects are in use\n"
|
||||||
" - %d holes in used memory (fragmentation)\n",
|
" - %d holes in used memory (fragmentation)\n",
|
||||||
(1.0*nextFreeSpot - freeSpots->next_index)/maxLispObjects,
|
(1.0*next_index_in_object_memory - free_spots_in_object_memory->next_index)/object_memory_size,
|
||||||
nextFreeSpot - freeSpots->next_index, maxLispObjects,
|
next_index_in_object_memory - free_spots_in_object_memory->next_index, object_memory_size,
|
||||||
freeSpots->next_index);
|
free_spots_in_object_memory->next_index);
|
||||||
|
|
||||||
|
printf("Memory Status:\n"
|
||||||
|
" - %f%% of the string_memory is used\n"
|
||||||
|
" - %d holes in used memory (fragmentation)\n",
|
||||||
|
(1.0*(size_t)next_free_spot_in_string_memory - (size_t)string_memory)/string_memory_size,
|
||||||
|
free_spots_in_string_memory->next_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline proc get_c_str(String* str) -> char* {
|
||||||
|
return &str->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
proc create_string(const char* str, int len) -> String* {
|
||||||
|
// TODO(Felix): check the holes first, not just always append
|
||||||
|
// at the end
|
||||||
|
|
||||||
|
String* ret = next_free_spot_in_string_memory;
|
||||||
|
ret->length = len;
|
||||||
|
strcpy(&ret->data, str);
|
||||||
|
|
||||||
|
// now update the next_free_spot_in_string_memory pointer:
|
||||||
|
// overstrep the counter and the first char (thik of it as if
|
||||||
|
// we were overstepping the last ('\0') char) and then we only
|
||||||
|
// need to overstep 'len' more chars
|
||||||
|
next_free_spot_in_string_memory += 1;
|
||||||
|
|
||||||
|
// overstep the other chars
|
||||||
|
next_free_spot_in_string_memory = ((String*)((char*)next_free_spot_in_string_memory)+len);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
proc delete_string(String* str) {
|
||||||
|
append_to_Void_Ptr_array_list(free_spots_in_string_memory, (void*)str);
|
||||||
|
}
|
||||||
|
|
||||||
|
proc duplicate_string(String* str) -> String* {
|
||||||
|
return create_string(get_c_str(str), str->length);
|
||||||
|
}
|
||||||
|
|
||||||
|
proc create_string (const char* str) -> String* {
|
||||||
|
return create_string(str, (int)strlen(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
proc create_lisp_object() -> Lisp_Object* {
|
proc create_lisp_object() -> Lisp_Object* {
|
||||||
int index;
|
int index;
|
||||||
// if we have no free spots then append at the end
|
// if we have no free spots then append at the end
|
||||||
if (freeSpots->next_index == 0) {
|
if (free_spots_in_object_memory->next_index == 0) {
|
||||||
// if we still have space
|
// if we still have space
|
||||||
if (maxLispObjects == nextFreeSpot) {
|
if (object_memory_size == next_index_in_object_memory) {
|
||||||
create_error(Error_Type::Out_Of_Memory, nullptr);
|
create_error(Error_Type::Out_Of_Memory, nullptr);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
index = nextFreeSpot++;
|
index = next_index_in_object_memory++;
|
||||||
} else {
|
} else {
|
||||||
// else fill a free spot
|
// else fill a free spot
|
||||||
index = freeSpots->data[freeSpots->next_index--];
|
index = free_spots_in_object_memory->data[free_spots_in_object_memory->next_index--];
|
||||||
}
|
}
|
||||||
Lisp_Object* object = memory+index;
|
Lisp_Object* object = object_memory+index;
|
||||||
object->sourceCodeLocation = nullptr;
|
object->sourceCodeLocation = nullptr;
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
@@ -61,29 +121,37 @@ namespace Memory {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc create_lisp_object_string(char* str, int length) -> Lisp_Object* {
|
proc create_lisp_object_string(String* str) -> Lisp_Object* {
|
||||||
Lisp_Object* node = create_lisp_object();
|
Lisp_Object* node = create_lisp_object();
|
||||||
node->type = Lisp_Object_Type::String;
|
node->type = Lisp_Object_Type::String;
|
||||||
node->value.string = new(String);
|
node->value.string = str;
|
||||||
node->value.string->value = str;
|
return node;
|
||||||
node->value.string->length = length;
|
}
|
||||||
|
|
||||||
|
proc create_lisp_object_symbol(String* identifier) -> Lisp_Object* {
|
||||||
|
Lisp_Object* node = create_lisp_object();
|
||||||
|
node->type = Lisp_Object_Type::Symbol;
|
||||||
|
node->value.symbol = new(Symbol);
|
||||||
|
node->value.symbol->identifier = identifier;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc create_lisp_object_symbol(const char* identifier) -> Lisp_Object* {
|
proc create_lisp_object_symbol(const char* identifier) -> Lisp_Object* {
|
||||||
|
return create_lisp_object_symbol(
|
||||||
|
Memory::create_string(identifier));
|
||||||
|
}
|
||||||
|
|
||||||
|
proc create_lisp_object_keyword(String* keyword) -> Lisp_Object* {
|
||||||
Lisp_Object* node = create_lisp_object();
|
Lisp_Object* node = create_lisp_object();
|
||||||
node->type = Lisp_Object_Type::Symbol;
|
node->type = Lisp_Object_Type::Keyword;
|
||||||
node->value.symbol = new(Symbol);
|
node->value.keyword = new(Keyword);
|
||||||
node->value.symbol->identifier = (char*) identifier;
|
node->value.keyword->identifier = keyword;
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
proc create_lisp_object_keyword(const char* keyword) -> Lisp_Object* {
|
proc create_lisp_object_keyword(const char* keyword) -> Lisp_Object* {
|
||||||
Lisp_Object* node = create_lisp_object();
|
return create_lisp_object_keyword(
|
||||||
node->type = Lisp_Object_Type::Keyword;
|
Memory::create_string(keyword));
|
||||||
node->value.keyword = new(Keyword);
|
|
||||||
node->value.keyword->identifier = (char*) keyword;
|
|
||||||
return node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
proc create_lisp_object_cfunction(std::function<Lisp_Object*(Lisp_Object*, Environment*)> function) -> Lisp_Object* {
|
proc create_lisp_object_cfunction(std::function<Lisp_Object*(Lisp_Object*, Environment*)> function) -> Lisp_Object* {
|
||||||
@@ -132,5 +200,4 @@ namespace Memory {
|
|||||||
load_built_ins_into_environment(ret);
|
load_built_ins_into_environment(ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+35
-33
@@ -1,15 +1,8 @@
|
|||||||
namespace Parser {
|
namespace Parser {
|
||||||
|
|
||||||
#define inject_scl(_ret) \
|
String* parser_file;
|
||||||
_ret->sourceCodeLocation = new(Source_Code_Location); \
|
|
||||||
_ret->sourceCodeLocation->file = parser_file; \
|
|
||||||
_ret->sourceCodeLocation->line = parser_line; \
|
|
||||||
_ret->sourceCodeLocation->column = parser_col
|
|
||||||
|
|
||||||
const char* parser_file;
|
|
||||||
int parser_line;
|
int parser_line;
|
||||||
int parser_col;
|
int parser_col;
|
||||||
|
|
||||||
// NOTE(Felix): In this environment, the build in functions will
|
// NOTE(Felix): In this environment, the build in functions will
|
||||||
// be loaded, and the macros will be stroed in form of
|
// be loaded, and the macros will be stroed in form of
|
||||||
// special-lambdas, that get executed in this environment at
|
// special-lambdas, that get executed in this environment at
|
||||||
@@ -28,6 +21,13 @@ namespace Parser {
|
|||||||
environment_for_macros = env;
|
environment_for_macros = env;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc inject_scl(Lisp_Object* lo) -> void {
|
||||||
|
lo->sourceCodeLocation = new(Source_Code_Location);
|
||||||
|
lo->sourceCodeLocation->file = parser_file;
|
||||||
|
lo->sourceCodeLocation->line = parser_line;
|
||||||
|
lo->sourceCodeLocation->column = parser_col;
|
||||||
|
}
|
||||||
|
|
||||||
void eat_comment_line(char* text, int* index_in_text) {
|
void eat_comment_line(char* text, int* index_in_text) {
|
||||||
// safety check if we are actually starting a comment here
|
// safety check if we are actually starting a comment here
|
||||||
if (text[*index_in_text] != ';')
|
if (text[*index_in_text] != ';')
|
||||||
@@ -68,7 +68,7 @@ namespace Parser {
|
|||||||
} while (position_before != *index_in_text);
|
} while (position_before != *index_in_text);
|
||||||
}
|
}
|
||||||
|
|
||||||
char* read_atom(char* text, int* index_in_text) {
|
String* read_atom(char* text, int* index_in_text) {
|
||||||
int atom_length = 0;
|
int atom_length = 0;
|
||||||
while (text[*index_in_text+atom_length] != ' ' &&
|
while (text[*index_in_text+atom_length] != ' ' &&
|
||||||
text[*index_in_text+atom_length] != ')' &&
|
text[*index_in_text+atom_length] != ')' &&
|
||||||
@@ -88,8 +88,9 @@ namespace Parser {
|
|||||||
text[*index_in_text+atom_length] = '\0';
|
text[*index_in_text+atom_length] = '\0';
|
||||||
|
|
||||||
// get the atom
|
// get the atom
|
||||||
char* atom = (char*)malloc(atom_length*sizeof(char)+1); // plus null char
|
String* ret = Memory::create_string("", atom_length);
|
||||||
strcpy(atom, text+(*index_in_text));
|
// char* atom = (char*)malloc(atom_length*sizeof(char)+1); // plus null char
|
||||||
|
strcpy(&ret->data, text+(*index_in_text));
|
||||||
|
|
||||||
// restore the original string
|
// restore the original string
|
||||||
text[*index_in_text+atom_length] = before;
|
text[*index_in_text+atom_length] = before;
|
||||||
@@ -98,14 +99,17 @@ namespace Parser {
|
|||||||
// ended
|
// ended
|
||||||
*index_in_text += atom_length;
|
*index_in_text += atom_length;
|
||||||
|
|
||||||
return atom;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* parse_number(char* text, int* index_in_text) {
|
Lisp_Object* parse_number(char* text, int* index_in_text) {
|
||||||
double number;
|
double number;
|
||||||
char* str_number = read_atom(text, index_in_text);
|
// TODO(Felix): parse the number direcrly from the string and
|
||||||
sscanf(str_number, "%lf", &number);
|
// dont create a String first
|
||||||
|
String* str_number = read_atom(text, index_in_text);
|
||||||
|
sscanf(Memory::get_c_str(str_number), "%lf", &number);
|
||||||
Lisp_Object* ret = Memory::create_lisp_object_number(number);
|
Lisp_Object* ret = Memory::create_lisp_object_number(number);
|
||||||
|
|
||||||
inject_scl(ret);
|
inject_scl(ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -114,15 +118,16 @@ namespace Parser {
|
|||||||
// we are now on the colon
|
// we are now on the colon
|
||||||
++(*index_in_text);
|
++(*index_in_text);
|
||||||
++parser_col;
|
++parser_col;
|
||||||
char* str_keyword = read_atom(text, index_in_text);
|
String* str_keyword = read_atom(text, index_in_text);
|
||||||
Lisp_Object* ret = Memory::create_lisp_object_keyword(str_keyword);
|
Lisp_Object* ret = Memory::create_lisp_object_keyword(str_keyword);
|
||||||
|
|
||||||
inject_scl(ret);
|
inject_scl(ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* parse_symbol(char* text, int* index_in_text) {
|
Lisp_Object* parse_symbol(char* text, int* index_in_text) {
|
||||||
// we are now at the first char of the symbol
|
// we are now at the first char of the symbol
|
||||||
char* str_symbol = read_atom(text, index_in_text);
|
String* str_symbol = read_atom(text, index_in_text);
|
||||||
Lisp_Object* ret = Memory::create_lisp_object_symbol(str_symbol);
|
Lisp_Object* ret = Memory::create_lisp_object_symbol(str_symbol);
|
||||||
inject_scl(ret);
|
inject_scl(ret);
|
||||||
return ret;
|
return ret;
|
||||||
@@ -136,9 +141,8 @@ namespace Parser {
|
|||||||
// now we are at the first letter, if this is the closing '"' then
|
// now we are at the first letter, if this is the closing '"' then
|
||||||
// it's easy
|
// it's easy
|
||||||
if (text[*index_in_text] == '"') {
|
if (text[*index_in_text] == '"') {
|
||||||
char* str = new(char);
|
Lisp_Object* ret = Memory::create_lisp_object_string(
|
||||||
*str = '\0';
|
Memory::create_string("", 0));
|
||||||
Lisp_Object* ret = Memory::create_lisp_object_string(str, 0);
|
|
||||||
inject_scl(ret);
|
inject_scl(ret);
|
||||||
|
|
||||||
// plus one because we want to go after the quotes
|
// plus one because we want to go after the quotes
|
||||||
@@ -158,7 +162,7 @@ namespace Parser {
|
|||||||
// we found the end of the string
|
// we found the end of the string
|
||||||
text[*index_in_text+string_length] = '\0';
|
text[*index_in_text+string_length] = '\0';
|
||||||
|
|
||||||
char* string = (char*)malloc(string_length*sizeof(char)+1); // plus null char
|
String* string = Memory::create_string("", string_length);
|
||||||
|
|
||||||
if (!unescape_string(text+(*index_in_text))) {
|
if (!unescape_string(text+(*index_in_text))) {
|
||||||
create_error(
|
create_error(
|
||||||
@@ -166,7 +170,7 @@ namespace Parser {
|
|||||||
create_source_code_location(parser_file, parser_line, parser_col));
|
create_source_code_location(parser_file, parser_line, parser_col));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
strcpy(string, text+(*index_in_text));
|
strcpy(&string->data, text+(*index_in_text));
|
||||||
/* manually copy to parse control sequences correctly */
|
/* manually copy to parse control sequences correctly */
|
||||||
/* int temp_index = 0; */
|
/* int temp_index = 0; */
|
||||||
/* while (text+(temp_index+(*index_in_text)) != '\0') { */
|
/* while (text+(temp_index+(*index_in_text)) != '\0') { */
|
||||||
@@ -179,7 +183,7 @@ namespace Parser {
|
|||||||
*index_in_text += string_length +1; // plus one because we want to
|
*index_in_text += string_length +1; // plus one because we want to
|
||||||
// go after the quotes
|
// go after the quotes
|
||||||
|
|
||||||
Lisp_Object* ret = Memory::create_lisp_object_string(string, string_length);
|
Lisp_Object* ret = Memory::create_lisp_object_string(string);
|
||||||
inject_scl(ret);
|
inject_scl(ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -371,7 +375,7 @@ namespace Parser {
|
|||||||
arguments = arguments->value.pair->rest;
|
arguments = arguments->value.pair->rest;
|
||||||
// if there is a docstring, use it
|
// if there is a docstring, use it
|
||||||
if (arguments->value.pair->first->type == Lisp_Object_Type::String) {
|
if (arguments->value.pair->first->type == Lisp_Object_Type::String) {
|
||||||
function->docstring = arguments->value.pair->first->value.string->value;
|
function->docstring = arguments->value.pair->first->value.string;
|
||||||
arguments = arguments->value.pair->rest;
|
arguments = arguments->value.pair->rest;
|
||||||
} else {
|
} else {
|
||||||
function->docstring = nullptr;
|
function->docstring = nullptr;
|
||||||
@@ -437,7 +441,7 @@ namespace Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object* parse_single_expression(char* text) {
|
Lisp_Object* parse_single_expression(char* text) {
|
||||||
parser_file = "stdin";
|
parser_file = Memory::create_string("stdin");
|
||||||
parser_line = 1;
|
parser_line = 1;
|
||||||
parser_col = 1;
|
parser_col = 1;
|
||||||
|
|
||||||
@@ -466,10 +470,10 @@ namespace Parser {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_expanded_file(const char* file_name, Lisp_Object_Array_List* program) {
|
void write_expanded_file(String* file_name, Lisp_Object_Array_List* program) {
|
||||||
const char* ext = ".expanded";
|
const char* ext = ".expanded";
|
||||||
char* newName = (char*)calloc(4 + strlen(file_name), sizeof(char));
|
char* newName = (char*)calloc(10 + file_name->length, sizeof(char));
|
||||||
strcpy(newName, file_name);
|
strcpy(newName, Memory::get_c_str(file_name));
|
||||||
strcat(newName, ext);
|
strcat(newName, ext);
|
||||||
|
|
||||||
FILE *f = fopen(newName, "w");
|
FILE *f = fopen(newName, "w");
|
||||||
@@ -487,15 +491,15 @@ namespace Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
free(newName);
|
||||||
}
|
}
|
||||||
|
|
||||||
Lisp_Object_Array_List* parse_program(const char* file_name, char* text) {
|
Lisp_Object_Array_List* parse_program(String* file_name, char* text) {
|
||||||
parser_file = (char*)malloc(strlen(file_name) * sizeof(char) + 1);
|
parser_file = file_name;
|
||||||
strcpy((char *)parser_file, file_name);
|
|
||||||
parser_line = 1;
|
parser_line = 1;
|
||||||
parser_col = 0;
|
parser_col = 0;
|
||||||
|
|
||||||
Lisp_Object_Array_List* program = create_Lisp_Object_array_list(16);
|
Lisp_Object_Array_List* program = create_Lisp_Object_array_list();
|
||||||
|
|
||||||
int index_in_text = 0;
|
int index_in_text = 0;
|
||||||
|
|
||||||
@@ -526,6 +530,4 @@ namespace Parser {
|
|||||||
|
|
||||||
return program;
|
return program;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef inject_scl
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -6,10 +6,10 @@
|
|||||||
#include "./defines.cpp"
|
#include "./defines.cpp"
|
||||||
#include "./structs.cpp"
|
#include "./structs.cpp"
|
||||||
#include "./forward_decls.cpp"
|
#include "./forward_decls.cpp"
|
||||||
|
#include "./memory.cpp"
|
||||||
#include "./lisp_object.cpp"
|
#include "./lisp_object.cpp"
|
||||||
#include "./error.cpp"
|
#include "./error.cpp"
|
||||||
#include "./io.cpp"
|
#include "./io.cpp"
|
||||||
#include "./memory.cpp"
|
|
||||||
#include "./env.cpp"
|
#include "./env.cpp"
|
||||||
#include "./parse.cpp"
|
#include "./parse.cpp"
|
||||||
#include "./built_ins.cpp"
|
#include "./built_ins.cpp"
|
||||||
|
|||||||
+15
-13
@@ -1,9 +1,11 @@
|
|||||||
struct Lisp_Object;
|
struct Lisp_Object;
|
||||||
|
struct String;
|
||||||
struct Environment;
|
struct Environment;
|
||||||
|
|
||||||
define_array_list(Lisp_Object*, Lisp_Object);
|
define_array_list(Lisp_Object*, Lisp_Object);
|
||||||
define_array_list(char*, String);
|
define_array_list(String*, String);
|
||||||
define_array_list(int, Int);
|
define_array_list(int, Int);
|
||||||
|
define_array_list(void*, Void_Ptr);
|
||||||
|
|
||||||
enum struct Lisp_Object_Type {
|
enum struct Lisp_Object_Type {
|
||||||
Nil,
|
Nil,
|
||||||
@@ -49,29 +51,29 @@ enum struct Log_Level {
|
|||||||
Debug,
|
Debug,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct String {
|
||||||
|
int length;
|
||||||
|
char data;
|
||||||
|
};
|
||||||
|
|
||||||
struct Source_Code_Location {
|
struct Source_Code_Location {
|
||||||
const char* file;
|
String* file;
|
||||||
int line;
|
int line;
|
||||||
int column;
|
int column;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Symbol {
|
struct Symbol {
|
||||||
char* identifier;
|
String* identifier;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Keyword {
|
struct Keyword {
|
||||||
char* identifier;
|
String* identifier;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Number {
|
struct Number {
|
||||||
double value;
|
double value;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct String {
|
|
||||||
int length;
|
|
||||||
char* value;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Pair {
|
struct Pair {
|
||||||
Lisp_Object* first;
|
Lisp_Object* first;
|
||||||
Lisp_Object* rest;
|
Lisp_Object* rest;
|
||||||
@@ -80,13 +82,13 @@ struct Pair {
|
|||||||
struct Positional_Arguments {
|
struct Positional_Arguments {
|
||||||
// TODO(Felix) use Lisp_Object_symbols here instead, so we don't have
|
// TODO(Felix) use Lisp_Object_symbols here instead, so we don't have
|
||||||
// to convert them to strings and back to symbols
|
// to convert them to strings and back to symbols
|
||||||
char** identifiers;
|
String** identifiers; // Array of Pointers to String
|
||||||
int next_index;
|
int next_index;
|
||||||
int length;
|
int length;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Keyword_Arguments {
|
struct Keyword_Arguments {
|
||||||
char** identifiers;
|
String** identifiers; // Array of Pointers to String
|
||||||
// NOTE(Felix): values[i] will be nullptr if no defalut value was
|
// NOTE(Felix): values[i] will be nullptr if no defalut value was
|
||||||
// declared for key identifiers[i]
|
// declared for key identifiers[i]
|
||||||
Lisp_Object_Array_List* values;
|
Lisp_Object_Array_List* values;
|
||||||
@@ -96,11 +98,11 @@ struct Keyword_Arguments {
|
|||||||
|
|
||||||
struct Function {
|
struct Function {
|
||||||
Function_Type type;
|
Function_Type type;
|
||||||
char* docstring;
|
String* docstring;
|
||||||
Positional_Arguments* positional_arguments;
|
Positional_Arguments* positional_arguments;
|
||||||
Keyword_Arguments* keyword_arguments;
|
Keyword_Arguments* keyword_arguments;
|
||||||
// rest_argument will be nullptr if no rest argument is declared
|
// rest_argument will be nullptr if no rest argument is declared
|
||||||
char* rest_argument;
|
String* rest_argument;
|
||||||
Lisp_Object* body; // implicit prog
|
Lisp_Object* body; // implicit prog
|
||||||
Environment* parent_environment; // we are doing closures now!!
|
Environment* parent_environment; // we are doing closures now!!
|
||||||
};
|
};
|
||||||
|
|||||||
+3
-3
@@ -50,7 +50,7 @@
|
|||||||
|
|
||||||
#define assert_equal_string(variable, value) \
|
#define assert_equal_string(variable, value) \
|
||||||
if (!string_equal(variable, value)) { \
|
if (!string_equal(variable, value)) { \
|
||||||
print_assert_equal_fail(variable, value, char*, "%s"); \
|
print_assert_equal_fail(&variable->data, value, char*, "%s"); \
|
||||||
return fail; \
|
return fail; \
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ proc test_eval_operands() -> testresult {
|
|||||||
|
|
||||||
assert_equal_type(operands, Lisp_Object_Type::Pair);
|
assert_equal_type(operands, Lisp_Object_Type::Pair);
|
||||||
assert_equal_type(operands->value.pair->first, Lisp_Object_Type::String);
|
assert_equal_type(operands->value.pair->first, Lisp_Object_Type::String);
|
||||||
assert_equal_string(operands->value.pair->first->value.string->value, "okay");
|
assert_equal_string(operands->value.pair->first->value.string, "okay");
|
||||||
|
|
||||||
operands = operands->value.pair->rest;
|
operands = operands->value.pair->rest;
|
||||||
|
|
||||||
@@ -144,7 +144,7 @@ proc test_parse_atom() -> testresult {
|
|||||||
|
|
||||||
result = Parser::parse_atom(string, &index_in_text);
|
result = Parser::parse_atom(string, &index_in_text);
|
||||||
assert_equal_type(result, Lisp_Object_Type::String);
|
assert_equal_type(result, Lisp_Object_Type::String);
|
||||||
assert_equal_string(result->value.string->value, "asd");
|
assert_equal_string(result->value.string, "asd");
|
||||||
|
|
||||||
// test keywords
|
// test keywords
|
||||||
++index_in_text;
|
++index_in_text;
|
||||||
|
|||||||
Reference in New Issue
Block a user