lisp-take-1/main.c

170 lines
3.8 KiB
C

#include <stdio.h>
#include <debug.h>
#include <defines/MAX_MACRO_DEPTH.h>
#include <cmdln/struct.h>
#include <cmdln/process.h>
#include <cmdln/free.h>
#include <gc/new.h>
#include <gc/mark_as_mortal.h>
#include <gc/dec_external_refcount.h>
#include <gc/free.h>
#include <parse/istream/file/new.h>
#include <parse/istream/read.h>
#include <parse/istream/free.h>
#include <parse/tokenizer/struct.h>
#include <parse/tokenizer/new.h>
#include <parse/tokenizer/next.h>
#include <parse/tokenizer/free.h>
#include <parse/parse.h>
#include <value/prettyprint.h>
#include <value/environment/new.h>
#include <value/environment/add_builtins.h>
#include <stringtree/prepend.h>
#include <stringtree/println.h>
#include <stringtree/free.h>
#include "expand_macro.h"
#include "evaluate.h"
int main(
int argc, char* const* argv)
{
unsigned i;
ENTER;
struct cmdln_flags* flags = process_cmdln_flags(argc, argv);
struct gc* gc = new_gc(
/* garbage collection flags: */ &flags->gc_flags);
struct value* environments[MAX_MACRO_DEPTH + 1];
for (i = 0; i < MAX_MACRO_DEPTH; i++)
{
struct value* environment = new_environment_value(
/* garbage collector: */ gc,
/* fallback environment: */ NULL);
environment_value_add_builtins(
/* this: */ environment,
/* macro-depth: */ MAX_MACRO_DEPTH - i);
environments[i] = environment;
}
environments[i] = new_environment_value(
/* garbage collector: */ gc,
/* fallback environment: */ NULL);
environment_value_add_builtins(
/* this: */ environments[i],
/* macro-depth (proper evaluation is zero depth): */ 0);
struct istream* stream = new_file_istream(
/* path: */ flags->input_file);
istream_read(stream);
struct tokenizer* tokenizer = new_tokenizer(stream);
tokenizer_next_token(tokenizer);
while (tokenizer->token != t_EOF)
{
struct value* value = parse(tokenizer, gc);
if (flags->verbose)
{
struct stringtree* tree = value_prettyprint(value);
stringtree_prepend_string_const(tree, "parsed: ");
stringtree_println(tree, stdout);
free_stringtree(tree);
}
// macro expansions:
for (i = 0; i < MAX_MACRO_DEPTH; i++)
{
struct value* expanded = expand_macro(
/* expression: */ value,
/* environment: */ environments[i],
/* garbage collector/allocator: */ gc);
if (flags->verbose)
{
struct stringtree* tree = value_prettyprint(expanded);
stringtree_prepend_string_const(tree, "macro expanded: ");
stringtree_println(tree, stdout);
free_stringtree(tree);
}
gc_dec_external_refcount(gc, value), value = expanded;
}
// evaluate:
struct value* result = evaluate(
/* expression: */ value,
/* environment: */ environments[i],
/* garbage collector/allocator: */ gc);
if (flags->verbose)
{
struct stringtree* tree = value_prettyprint(result);
stringtree_prepend_string_const(tree, "result: ");
stringtree_println(tree, stdout);
free_stringtree(tree);
}
gc_dec_external_refcount(gc, result);
gc_dec_external_refcount(gc, value);
}
free_tokenizer(tokenizer);
free_istream(stream);
free_gc(gc);
free_cmdln_flags(flags);
EXIT;
return 0;
}