feat: enhance compiler
- Add comments and test for it - Add semicolon as required end of some expressions - Add new arguments parser - Add multi-file compilation - Add colors in output
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
#include <common/fzl_colors.h>
|
||||
#include <compiler/utils/fzl_options.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
const char version[] = "FZL Compiler 1.0";
|
||||
|
||||
void print_help()
|
||||
{
|
||||
printf("Usage: fzc [flags] <sources...>\n");
|
||||
printf("Available flags:\n");
|
||||
printf("\t-h\t--help\t\tPrint help\n");
|
||||
printf("\t-v\t--verbose\tDisplay compilation info (tokens, AST, consts "
|
||||
"table, etc)\n");
|
||||
printf("\t-V\t--version\tPrint compiler version\n");
|
||||
printf("\t-o\t--out\t\tSet compiled file name\n");
|
||||
}
|
||||
|
||||
fzl_options_t *fzl_mkoptions(int argc, char **argv)
|
||||
{
|
||||
fzl_options_t *opts = malloc(sizeof(fzl_options_t));
|
||||
if (!opts)
|
||||
{
|
||||
printf("%sBruh... Potato PC%s\n", FZL_CERROR, FZL_CRST);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(opts, 0, sizeof(fzl_options_t));
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
print_help();
|
||||
opts->should_continue = false;
|
||||
return opts;
|
||||
}
|
||||
|
||||
size_t i;
|
||||
for (i = 1; i < argc; i++)
|
||||
{
|
||||
if (argv[i][0] != '-')
|
||||
break;
|
||||
|
||||
if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0)
|
||||
{
|
||||
print_help();
|
||||
opts->should_continue = false;
|
||||
break;
|
||||
}
|
||||
else if (strcmp(argv[i], "-V") == 0 || strcmp(argv[i], "--version") == 0)
|
||||
{
|
||||
printf("%s\n", version);
|
||||
opts->should_continue = false;
|
||||
break;
|
||||
}
|
||||
else if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0)
|
||||
{
|
||||
opts->verbose = true;
|
||||
}
|
||||
else if (strcmp(argv[i], "-o") == 0 || strcmp(argv[i], "--out") == 0)
|
||||
{
|
||||
if (i == argc - 1)
|
||||
{
|
||||
printf("%sError%s: missing out file name\n", FZL_CERROR, FZL_CRST);
|
||||
free(opts);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *filename = argv[++i];
|
||||
opts->outname = filename;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%sError%s: undefined flag '%s'\n", FZL_CERROR, FZL_CRST, argv[i]);
|
||||
free(opts);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
size_t fremainder = 2;
|
||||
size_t fcount = 0;
|
||||
char **files = malloc(fremainder * sizeof(char *));
|
||||
|
||||
for (; i < argc; i++)
|
||||
{
|
||||
if (argv[i][0] == '-')
|
||||
{
|
||||
printf(
|
||||
"%sWarning%s: unhandled flag '%s' (should be defined before sources "
|
||||
"list)\n",
|
||||
FZL_CWARNING, FZL_CRST, argv[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (fremainder <= fcount)
|
||||
{
|
||||
fremainder *= 2;
|
||||
files = realloc(files, fremainder * sizeof(char *));
|
||||
}
|
||||
|
||||
files[fcount++] = argv[i];
|
||||
}
|
||||
|
||||
opts->files = files;
|
||||
opts->files_count = fcount;
|
||||
|
||||
if (i < argc - 1)
|
||||
{
|
||||
printf("%sError%s: flags should go before source files list.\n", FZL_CERROR,
|
||||
FZL_CRST);
|
||||
printf("Remain %zu arguments are not handled.\n", argc - 1 - i);
|
||||
|
||||
free(files);
|
||||
free(opts);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
opts->should_continue = true;
|
||||
return opts;
|
||||
}
|
||||
|
||||
void fzl_freeoptions(fzl_options_t *options)
|
||||
{
|
||||
if (!options)
|
||||
return;
|
||||
|
||||
if (options->files)
|
||||
free(options->files);
|
||||
|
||||
free(options);
|
||||
}
|
||||
Reference in New Issue
Block a user