Open Wuerfel21 opened 2 years ago
Having a library (or at least being able to run in a browser via emscripten) would be really useful, I agree. I've started taking some baby steps in that direction by checking in a new pool memory allocator so that freeing all the memory we've used would be easy.
Next step would be moving globals into a struct. For standalone builds, this can just be a single global instance and nothing changes, for a library build it should be using a thread-local pointer.
This has been simmering in my head for ages, so I guess I'll write another burner issue so it can simmer here for another century.
Basically, it'd be real swell if you could call into flexspin as a library. Potential applications include:
Challenges:
Draft
libflexspin.h
API:flexapi_set_file_callback
might need to be slightly more complex to deal with library files. Is dealing with library paths domain of the compiler or of the file callback?struct flexapi_compiler; // Opaque struct typedef struct flexapi_compiler flexapi_compiler;
/ Allocates new compiler object. / flexapi_compiler flexapi_create_compiler(); / Frees a compiler object. / void flexapi_free_compiler(flexapi_compiler gl); / Resets a compiler object. This is semantically identical to freeing one and creating another, but with less overhead. / void flexapi_reset_compiler(flexapi_compiler *gl);
enum flexapi_option_type { FLEXAPI_OPTION_INT = 1, FLEXAPI_OPTION_STRING, FLEXAPI_OPTION_STRING_MULTI, // Used for source files, preprocessor defines, etc... FLEXAPI_OPTION_ENUM, };
// Struct struct flexapi_option { const struct flexapi_option next; const char name; // Internally used option identifier const char long_name,description; // Long name / description for human consumption flexapi_option_type type; }; typedef struct flexapi_option flexapi_option;
/ List possible compiler options. / const flexapi_option * flexapi_list_options();
/ List possible values for an enum-typed option. This re-uses the same flexapi_option type, take care. / const flexapi_option flexapi_list_enum_vals(char opt);
/ Sets a compiler option to a given value. Do note that you can not "unset" an option without resetting the compiler. Returns negative value on failure. / int flexapi_set_option(flexapi_compiler gl,const char opt, const char value); / Same as flexapi_set_option, but for setting an integer value without having to create a string. / int flexapi_set_option_int(flexapi_compiler gl,const char *opt, int value);
/* Set callback used to read source files. Should read the entire file into memory and return it. The returned buffer is owned by libflexspin, so create a copy if neccessary.
/ void flexapi_set_file_callback(flexapi_compiler gl, char(filecb)(const char name));
/ Run compiler. This can only be called once per compiler instance before it needs to be reset. If result is negative, it means an error has occurred. / int flexapi_do_compile(flexapi_compiler *gl);
/ Get compiled binary's size. / int flexapi_get_binary_size(flexapi_compiler gl); / Get compiled binary. / const char flexapi_get_binary(flexapi_compiler gl); / Get listing (zero terminated). / const char flexapi_get_listing(flexapi_compiler gl); / Get intermediate asm (zero terminated). / const char flexapi_get_asmgen(flexapi_compiler *gl);
enum flexapi_mesg_type { FLEXAPI_MESG_DEBUG = 1, FLEXAPI_MESG_INFO, FLEXAPI_MESG_WARNING, FLEXAPI_MESG_ERROR, };
struct flexapi_message { const struct flexapi_message next; // NULL means last message flexapi_mesg_type type; unsigned int line; // 0 means unknown line const char file; const char *text; }; typedef struct flexapi_message flexapi_message;
/ Get diagnostic messages from last compiler run. Returns NULL if there are no messages. Returned pointer only stays valid until the compiler is freed or reset. / const flexapi_message flexapi_get_messages(flexapi_compiler gl);