I think I did Lisp_Object SSO
This commit is contained in:
+41
-48
@@ -293,7 +293,7 @@ namespace Parser {
|
||||
// okay there is something
|
||||
Lisp_Object* head = Memory::create_lisp_object();
|
||||
head->type = Lisp_Object_Type::Pair;
|
||||
head->value.pair = new(Pair);
|
||||
// head->value.pair = new(Pair);
|
||||
Lisp_Object* expression = head;
|
||||
|
||||
while (true) {
|
||||
@@ -304,11 +304,11 @@ namespace Parser {
|
||||
text[*index_in_text] == ',')
|
||||
{
|
||||
try {
|
||||
head->value.pair->first = parse_expression(text, index_in_text);
|
||||
head->value.pair.first = parse_expression(text, index_in_text);
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
head->value.pair->first = parse_atom(text, index_in_text);
|
||||
head->value.pair.first = parse_atom(text, index_in_text);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -320,7 +320,7 @@ namespace Parser {
|
||||
|
||||
|
||||
if (text[(*index_in_text)] == ')') {
|
||||
head->value.pair->rest = Memory::nil;
|
||||
head->value.pair.rest = Memory::nil;
|
||||
++parser_col;
|
||||
++(*index_in_text);
|
||||
break;
|
||||
@@ -330,9 +330,9 @@ namespace Parser {
|
||||
eat_until_code(text, index_in_text);
|
||||
|
||||
if (text[(*index_in_text)] == '(')
|
||||
head->value.pair->rest = parse_expression(text, index_in_text);
|
||||
head->value.pair.rest = parse_expression(text, index_in_text);
|
||||
else
|
||||
head->value.pair->rest = parse_atom(text, index_in_text);
|
||||
head->value.pair.rest = parse_atom(text, index_in_text);
|
||||
|
||||
eat_until_code(text, index_in_text);
|
||||
|
||||
@@ -342,16 +342,16 @@ namespace Parser {
|
||||
++(*index_in_text);
|
||||
break;
|
||||
} else {
|
||||
head->value.pair->rest = Memory::create_lisp_object_pair(nullptr, nullptr);
|
||||
head = head->value.pair->rest;
|
||||
head->value.pair.rest = Memory::create_lisp_object_pair(nullptr, nullptr);
|
||||
head = head->value.pair.rest;
|
||||
}
|
||||
}
|
||||
|
||||
// check if we have to create or delete or run macros
|
||||
if (expression->value.pair->first->type == Lisp_Object_Type::Symbol) {
|
||||
if (string_equal("define-syntax", expression->value.pair->first->value.symbol->identifier)) {
|
||||
if (expression->value.pair.first->type == Lisp_Object_Type::Symbol) {
|
||||
if (string_equal("define-syntax", expression->value.pair.first->value.identifier)) {
|
||||
// create a new macro
|
||||
Lisp_Object* arguments = expression->value.pair->rest;
|
||||
Lisp_Object* arguments = expression->value.pair.rest;
|
||||
int arguments_length;
|
||||
|
||||
// HACK(Felix): almost code duplicate from
|
||||
@@ -366,57 +366,57 @@ namespace Parser {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (arguments->value.pair->first->type != Lisp_Object_Type::Symbol) {
|
||||
if (arguments->value.pair.first->type != Lisp_Object_Type::Symbol) {
|
||||
create_error(Error_Type::Type_Missmatch, expression->sourceCodeLocation);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// extract the name
|
||||
Lisp_Object* symbol_for_macro = arguments->value.pair->first;
|
||||
arguments = arguments->value.pair->rest;
|
||||
Lisp_Object* symbol_for_macro = arguments->value.pair.first;
|
||||
arguments = arguments->value.pair.rest;
|
||||
|
||||
Function* function = new(Function);
|
||||
function->parent_environment = environment_for_macros;
|
||||
function->type = Function_Type::Macro;
|
||||
// Function* function = new(Function);
|
||||
Lisp_Object* macro = Memory::create_lisp_object();
|
||||
macro->type = Lisp_Object_Type::Function;
|
||||
macro->value.function.parent_environment = environment_for_macros;
|
||||
macro->value.function.type = Function_Type::Macro;
|
||||
|
||||
// if parameters were specified
|
||||
if (arguments->value.pair->first->type != Lisp_Object_Type::Nil) {
|
||||
if (arguments->value.pair.first->type != Lisp_Object_Type::Nil) {
|
||||
try {
|
||||
assert_type(arguments->value.pair->first, Lisp_Object_Type::Pair);
|
||||
assert_type(arguments->value.pair.first, Lisp_Object_Type::Pair);
|
||||
}
|
||||
try {
|
||||
parse_argument_list(arguments->value.pair->first, function);
|
||||
parse_argument_list(arguments->value.pair.first, ¯o->value.function);
|
||||
}
|
||||
} else {
|
||||
function->positional_arguments = create_positional_argument_list(1);
|
||||
function->keyword_arguments = create_keyword_argument_list(1);
|
||||
function->rest_argument = nullptr;
|
||||
macro->value.function.positional_arguments = create_positional_argument_list(1);
|
||||
macro->value.function.keyword_arguments = create_keyword_argument_list(1);
|
||||
macro->value.function.rest_argument = nullptr;
|
||||
}
|
||||
|
||||
arguments = arguments->value.pair->rest;
|
||||
arguments = arguments->value.pair.rest;
|
||||
// if there is a docstring, use it
|
||||
if (arguments->value.pair->first->type == Lisp_Object_Type::String) {
|
||||
function->docstring = arguments->value.pair->first->value.string;
|
||||
arguments = arguments->value.pair->rest;
|
||||
if (arguments->value.pair.first->type == Lisp_Object_Type::String) {
|
||||
macro->value.function.docstring = arguments->value.pair.first->value.string;
|
||||
arguments = arguments->value.pair.rest;
|
||||
} else {
|
||||
function->docstring = nullptr;
|
||||
macro->value.function.docstring = nullptr;
|
||||
}
|
||||
|
||||
// we are now in the function body, just wrap it in an
|
||||
// implicit prog
|
||||
function->body = Memory::create_lisp_object_pair(
|
||||
macro->value.function.body = Memory::create_lisp_object_pair(
|
||||
Memory::get_or_create_lisp_object_symbol("prog"),
|
||||
arguments);
|
||||
|
||||
Lisp_Object* macro = Memory::create_lisp_object();
|
||||
macro->type = Lisp_Object_Type::Function;
|
||||
macro->value.function = function;
|
||||
// macro->value.function = function;
|
||||
define_symbol(symbol_for_macro, macro, environment_for_macros);
|
||||
|
||||
// print_environment(environment_for_macros);
|
||||
return Memory::nil;
|
||||
|
||||
} else if (string_equal("delete-syntax", expression->value.pair->first->value.symbol->identifier)) {
|
||||
} else if (string_equal("delete-syntax", expression->value.pair.first->value.identifier)) {
|
||||
/* --- deleting an existing macro --- */
|
||||
// TODO(Felix): this is a hard one because when
|
||||
// environments will be made from hashmaps, how can we
|
||||
@@ -436,21 +436,12 @@ namespace Parser {
|
||||
// if not it is regular code, dont touch.
|
||||
|
||||
for (int i = 0; i < environment_for_macros->next_index; ++i) {
|
||||
if (string_equal(expression->value.pair->first->value.symbol->identifier, environment_for_macros->keys[i]) &&
|
||||
if (string_equal(expression->value.pair.first->value.identifier, environment_for_macros->keys[i]) &&
|
||||
environment_for_macros->values[i]->type == Lisp_Object_Type::Function &&
|
||||
environment_for_macros->values[i]->value.function->type == Function_Type::Macro)
|
||||
environment_for_macros->values[i]->value.function.type == Function_Type::Macro)
|
||||
{
|
||||
try {
|
||||
// if (string_equal(environment_for_macros->keys[i], "when")) {
|
||||
// printf("invoking macro for %s in %s:%d to:\n\t", environment_for_macros->keys[i], parser_file, parser_line);
|
||||
// print(environment_for_macros->values[i]->value.function->body);
|
||||
// }
|
||||
expression = eval_expr(expression, environment_for_macros);
|
||||
// if (string_equal(environment_for_macros->keys[i], "when")) {
|
||||
// printf("\nresult: \n\t");
|
||||
// print(expression);
|
||||
// printf("\n\n");
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -536,6 +527,11 @@ namespace Parser {
|
||||
strcat(newName, ext);
|
||||
|
||||
FILE *f = fopen(newName, "w");
|
||||
defer {
|
||||
fclose(f);
|
||||
free(newName);
|
||||
};
|
||||
|
||||
if (f == NULL) {
|
||||
printf("Error opening file!\n");
|
||||
exit(1);
|
||||
@@ -545,12 +541,9 @@ namespace Parser {
|
||||
// a macro will parse as nil for now, so we skip those
|
||||
if (program->data[i]->type == Lisp_Object_Type::Nil)
|
||||
continue;
|
||||
fprint(f, program->data[i]);
|
||||
print(program->data[i], true, f);
|
||||
fprintf(f, "\n\n");
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
free(newName);
|
||||
}
|
||||
|
||||
proc parse_program(String* file_name, char* text) -> Lisp_Object_Array_List* {
|
||||
|
||||
Reference in New Issue
Block a user