Files
fz-lang/src/compiler/main.c
T

271 lines
6.5 KiB
C

#include <common/fzl_colors.h>
#include <compiler/fzl_analyzer.h>
#include <compiler/fzl_debug.h>
#include <compiler/fzl_gen.h>
#include <compiler/fzl_parser.h>
#include <compiler/fzl_reader.h>
#include <compiler/fzl_writer.h>
#include <compiler/utils/fzl_linked.h>
#include <compiler/utils/fzl_options.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
fzl_options_t *opts = fzl_mkoptions(argc, argv);
if (!opts)
{
fzl_freeoptions(opts);
return -1;
}
else if (!opts->should_continue)
{
fzl_freeoptions(opts);
return 0;
}
if (opts->verbose)
printf("%s> analyze\n-> reading file...%s", FZL_CDEBUG, FZL_CRST);
fzl_linked_t *linked = fzl_mklinked();
if (!linked)
{
char *lasterr = fzl_linked_geterror();
if (lasterr[0])
printf("%sError%s: %s\n", FZL_CERROR, FZL_CRST, lasterr);
fzl_freeoptions(opts);
fzl_freelinked(linked);
return -1;
}
bool read_result =
fzl_linked_add_files(linked, opts->files, opts->files_count);
if (!read_result)
{
char *lasterr = fzl_linked_geterror();
if (lasterr[0])
printf("%sError%s: %s\n", FZL_CERROR, FZL_CRST, lasterr);
fzl_freeoptions(opts);
fzl_freelinked(linked);
return -1;
}
if (opts->verbose)
{
printf("%sok%s!\n", FZL_COK, FZL_CRST);
printf("%s--> Red %ld bytes%s\n", FZL_CDEBUG, linked->total_sz, FZL_CRST);
printf("%s-> tokenizing...%s", FZL_CDEBUG, FZL_CRST);
}
fzl_reader_t *rd = fzl_mkreader(linked);
int result = fzl_read(rd);
if (result != 0)
{
printf("%sError%s: %s\n", FZL_CERROR, FZL_CRST, fzl_reader_geterror());
fzl_freeoptions(opts);
fzl_freelinked(linked);
fzl_freereader(rd);
return -1;
}
if (opts->verbose)
printf("%sok%s!\n", FZL_COK, FZL_CRST);
fzl_reader_ll_t *entry = rd->first;
if (opts->verbose)
{
printf("%s--> structure: %s", FZL_CDEBUG, FZL_CRST);
while (entry)
{
if (entry->token)
{
if (entry->token->store_value)
printf("<TOK:%d:%s>", entry->token->type,
(char *)entry->token->value);
else
printf("<TOK:%d>", entry->token->type);
}
entry = entry->next;
}
printf("\n");
printf("%s-> parsing...%s", FZL_CDEBUG, FZL_CRST);
}
fzl_parser_t *parser = fzl_mkparser(rd->first);
if (!parser)
{
printf("%sError%s: failed to allocate writer\n", FZL_CERROR, FZL_CRST);
fzl_freeoptions(opts);
fzl_freereader(rd);
fzl_freelinked(linked);
return -1;
}
result = fzl_parse(parser);
if (result != 0)
{
printf("%sError%s: %s\n", FZL_CERROR, FZL_CRST, fzl_parser_geterror());
fzl_freeoptions(opts);
fzl_freeast(parser->root);
fzl_freeparser(parser);
fzl_freereader(rd);
fzl_freelinked(linked);
return -1;
}
if (opts->verbose)
{
printf("%sok%s!\n", FZL_COK, FZL_CRST);
fzl_debug_print_ast(parser->root);
printf("%s-> analyzing AST...%s", FZL_CDEBUG, FZL_CRST);
}
fzl_analyzer_t *analyzer = fzl_mkanalyzer(parser->root);
if (!analyzer)
{
printf("%sError%s: failed to allocate analyzer\n", FZL_CERROR, FZL_CRST);
fzl_freeoptions(opts);
fzl_freeast(parser->root);
fzl_freeparser(parser);
fzl_freereader(rd);
fzl_freelinked(linked);
}
fzl_analyze(analyzer);
if (analyzer->errors_top > 0)
{
for (ssize_t i = analyzer->errors_top - 1; i >= 0; i--)
printf("%sError%s: %s\n", FZL_CERROR, FZL_CRST, analyzer->errors[i]);
fzl_freeoptions(opts);
fzl_freeanalyzer(analyzer);
fzl_freeast(parser->root);
fzl_freeparser(parser);
fzl_freereader(rd);
fzl_freelinked(linked);
return -1;
}
if (analyzer->warnings_top > 0)
{
for (ssize_t i = analyzer->warnings_top - 1; i >= 0; i--)
printf("%sWarning%s: %s\n", FZL_CWARNING, FZL_CRST,
analyzer->warnings[i]);
}
if (opts->verbose)
{
printf("%sok%s!\n", FZL_COK, FZL_CRST);
printf("%s> generate\n-> generating bytecode...%s", FZL_CDEBUG, FZL_CRST);
}
fzl_gen_t *gen = fzl_mkgen(parser->root);
if (!gen)
{
printf("%sError%s: failed to allocate generator\n", FZL_CERROR, FZL_CRST);
fzl_freeoptions(opts);
fzl_freeast(parser->root);
fzl_freeanalyzer(analyzer);
fzl_freeparser(parser);
fzl_freereader(rd);
fzl_freelinked(linked);
return -1;
}
bool gen_res = fzl_gen_run(gen);
if (!gen_res)
{
printf("%sError%s: couldn't generate operations\n", FZL_CERROR, FZL_CRST);
fzl_freeoptions(opts);
fzl_freegen(gen);
fzl_freeast(parser->root);
fzl_freeanalyzer(analyzer);
fzl_freeparser(parser);
fzl_freereader(rd);
fzl_freelinked(linked);
return -1;
}
if (opts->verbose)
{
printf("%sok%s!\n", FZL_COK, FZL_CRST);
printf("%s--> Constants table%s:\n", FZL_CDEBUG, FZL_CRST);
for (size_t i = 0; i < gen->consts->size; i++)
printf("---> %s\n", gen->consts->array[i].as.string.chars);
printf("%s--> Ops%s:\n", FZL_CDEBUG, FZL_CRST);
printf("---> ");
for (size_t i = 0; i < gen->ops_count; i++)
{
if (i > 0 && i < gen->ops_count)
printf("->");
printf("%lX", gen->ops[i]);
}
printf("\n");
printf("%s-> preparing final write%s\n", FZL_CDEBUG, FZL_CRST);
}
char outpath[256];
if (opts->outname)
strcpy(outpath, opts->outname);
else
strcpy(outpath, "a.fzb");
if (opts->verbose)
{
printf("%s-> output file path is%s: %s\n", FZL_CDEBUG, FZL_CRST, outpath);
printf("%s-> writing file...%s", FZL_CDEBUG, FZL_CRST);
}
fzl_writer_t *writer = fzl_mkwriter(outpath);
if (!writer)
{
printf("%sError%s: failed to allocate writer\n", FZL_CERROR, FZL_CRST);
fzl_freeoptions(opts);
fzl_freegen(gen);
fzl_freeast(parser->root);
fzl_freeanalyzer(analyzer);
fzl_freeparser(parser);
fzl_freereader(rd);
fzl_freelinked(linked);
return -1;
}
result = fzl_write(writer, gen);
if (result != 0)
{
printf("%sError%s: %s\n", FZL_CERROR, FZL_CRST, fzl_writer_geterror());
fzl_freeoptions(opts);
fzl_freewriter(writer);
fzl_freegen(gen);
fzl_freeast(parser->root);
fzl_freeanalyzer(analyzer);
fzl_freeparser(parser);
fzl_freereader(rd);
fzl_freelinked(linked);
return -1;
}
if (opts->verbose)
printf("%sok%s!\n", FZL_COK, FZL_CRST);
fzl_freeoptions(opts);
fzl_freelinked(linked);
fzl_freereader(rd);
fzl_freeast(parser->root);
fzl_freeanalyzer(analyzer);
fzl_freeparser(parser);
fzl_freegen(gen);
fzl_freewriter(writer);
printf("%sCompiled successfully%s.\n", FZL_COK, FZL_CRST);
return 0;
}