feat: implement file writer
This commit is contained in:
@@ -13,6 +13,7 @@ add_executable(fzc
|
|||||||
src/compiler/fzl_parser.c
|
src/compiler/fzl_parser.c
|
||||||
src/compiler/fzl_debug.c
|
src/compiler/fzl_debug.c
|
||||||
src/compiler/fzl_walker.c
|
src/compiler/fzl_walker.c
|
||||||
|
src/compiler/fzl_writer.c
|
||||||
src/compiler/utils/fzl_const_pool.c
|
src/compiler/utils/fzl_const_pool.c
|
||||||
src/compiler/main.c)
|
src/compiler/main.c)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef FZL_WRITER_H
|
||||||
|
#define FZL_WRITER_H
|
||||||
|
|
||||||
|
#include <compiler/fzl_walker.h>
|
||||||
|
#include <compiler/utils/fzl_const_pool.h>
|
||||||
|
|
||||||
|
// File writer descriptor
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
const char *filepath;
|
||||||
|
} fzl_writer_t;
|
||||||
|
|
||||||
|
// Allocate writer
|
||||||
|
fzl_writer_t *fzl_mkwriter(const char *filepath);
|
||||||
|
|
||||||
|
// Write out a file
|
||||||
|
int fzl_write(fzl_writer_t *writer, fzl_walker_t *walker);
|
||||||
|
|
||||||
|
// Get last writer error message
|
||||||
|
char *fzl_writer_geterror();
|
||||||
|
|
||||||
|
// Free writer
|
||||||
|
void fzl_freewriter(fzl_writer_t *writer);
|
||||||
|
|
||||||
|
#endif // FZL_WRITER_H
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
#include <compiler/fzl_writer.h>
|
||||||
|
#include <compiler/utils/fzl_const_pool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
char wrlast_err[256];
|
||||||
|
|
||||||
|
fzl_writer_t *fzl_mkwriter(const char *filepath)
|
||||||
|
{
|
||||||
|
if (strlen(filepath) < 1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
fzl_writer_t *writer = malloc(sizeof(fzl_writer_t));
|
||||||
|
if (!writer)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
writer->filepath = filepath;
|
||||||
|
|
||||||
|
return writer;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fzl_write(fzl_writer_t *writer, fzl_walker_t *walker)
|
||||||
|
{
|
||||||
|
if (!writer || !walker)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
FILE *fp = fopen(writer->filepath, "wb");
|
||||||
|
if (!fp)
|
||||||
|
{
|
||||||
|
snprintf(wrlast_err, sizeof(wrlast_err), "failed to open '%s' to write",
|
||||||
|
writer->filepath);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char hdr[5] = {'F', 'Z', 'L', 0x0, 0x1};
|
||||||
|
fwrite(hdr, sizeof(char), 5, fp);
|
||||||
|
fwrite(&walker->consts->size, sizeof(size_t), 1, fp);
|
||||||
|
fwrite(&walker->op_count, sizeof(size_t), 1, fp);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < walker->consts->size; i++)
|
||||||
|
{
|
||||||
|
fzl_const_t c = walker->consts->array[i];
|
||||||
|
fwrite(&c.type, sizeof(fzl_consttype_t), 1, fp);
|
||||||
|
|
||||||
|
if (c.type == FZL_CONSTTYPE_STRING)
|
||||||
|
{
|
||||||
|
size_t strlen = c.as.string.length;
|
||||||
|
fwrite(&c.as.string.length, sizeof(size_t), 1, fp);
|
||||||
|
fwrite(c.as.string.chars, sizeof(char), strlen, fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (walker->op_count > 0)
|
||||||
|
fwrite(walker->ops, sizeof(uint64_t), walker->op_count, fp);
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *fzl_writer_geterror() { return wrlast_err; }
|
||||||
|
|
||||||
|
void fzl_freewriter(fzl_writer_t *writer)
|
||||||
|
{
|
||||||
|
if (!writer)
|
||||||
|
return;
|
||||||
|
|
||||||
|
free(writer);
|
||||||
|
}
|
||||||
+40
-1
@@ -2,6 +2,7 @@
|
|||||||
#include <compiler/fzl_parser.h>
|
#include <compiler/fzl_parser.h>
|
||||||
#include <compiler/fzl_reader.h>
|
#include <compiler/fzl_reader.h>
|
||||||
#include <compiler/fzl_walker.h>
|
#include <compiler/fzl_walker.h>
|
||||||
|
#include <compiler/fzl_writer.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -11,6 +12,7 @@
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
char *filepath;
|
char *filepath;
|
||||||
|
char *outpath;
|
||||||
bool verbose;
|
bool verbose;
|
||||||
bool help;
|
bool help;
|
||||||
} build_args_t;
|
} build_args_t;
|
||||||
@@ -32,6 +34,7 @@ build_args_t *getargs(int argc, char **argv)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
args->filepath = NULL;
|
args->filepath = NULL;
|
||||||
|
args->outpath = NULL;
|
||||||
args->verbose = false;
|
args->verbose = false;
|
||||||
args->help = false;
|
args->help = false;
|
||||||
|
|
||||||
@@ -53,6 +56,15 @@ build_args_t *getargs(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
args->verbose = true;
|
args->verbose = true;
|
||||||
}
|
}
|
||||||
|
else if (strcmp(argv[i], "-o") == 0 || strcmp(argv[i], "--out") == 0)
|
||||||
|
{
|
||||||
|
if (!argv[i + 1] || argv[i + 1][0] == '-')
|
||||||
|
{
|
||||||
|
printf("Error: file path is not specified.\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
args->outpath = argv[++i];
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("Error: unknown argument '%s'\n", argv[i]);
|
printf("Error: unknown argument '%s'\n", argv[i]);
|
||||||
@@ -156,7 +168,8 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
printf("ok!\n");
|
printf("ok!\n");
|
||||||
fzl_debug_print_ast(parser->root);
|
fzl_debug_print_ast(parser->root);
|
||||||
printf("-> walking AST...");
|
printf("> building\n");
|
||||||
|
printf("-> walking AST...\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
fzl_walker_t *walker = fzl_mkwalker(parser->root);
|
fzl_walker_t *walker = fzl_mkwalker(parser->root);
|
||||||
@@ -178,13 +191,39 @@ int main(int argc, char **argv)
|
|||||||
printf("--> Ops:\n");
|
printf("--> Ops:\n");
|
||||||
for (size_t i = 0; i < walker->op_count; i++)
|
for (size_t i = 0; i < walker->op_count; i++)
|
||||||
printf("---> %lu\n", walker->ops[i]);
|
printf("---> %lu\n", walker->ops[i]);
|
||||||
|
|
||||||
|
printf("-> preparing final write\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char outpath[256];
|
||||||
|
if (args->outpath)
|
||||||
|
strcpy(outpath, args->outpath);
|
||||||
|
else
|
||||||
|
strcpy(outpath, "a.fzlc");
|
||||||
|
|
||||||
|
if (args->verbose)
|
||||||
|
{
|
||||||
|
printf("-> output file path is: %s", outpath);
|
||||||
|
printf("-> writing file...");
|
||||||
|
}
|
||||||
|
|
||||||
|
fzl_writer_t *writer = fzl_mkwriter(outpath);
|
||||||
|
result = fzl_write(writer, walker);
|
||||||
|
if (result != 0)
|
||||||
|
{
|
||||||
|
printf("Error: %s\n", fzl_writer_geterror());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args->verbose)
|
||||||
|
printf("ok!\n");
|
||||||
|
|
||||||
free(args);
|
free(args);
|
||||||
fzl_freereader(rd);
|
fzl_freereader(rd);
|
||||||
fzl_freeparser(parser);
|
fzl_freeparser(parser);
|
||||||
fzl_freeast(parser->root);
|
fzl_freeast(parser->root);
|
||||||
fzl_freewalker(walker);
|
fzl_freewalker(walker);
|
||||||
|
fzl_freewriter(writer);
|
||||||
|
|
||||||
printf("done.\n");
|
printf("done.\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user