You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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:
Flexspin in browser (emscripten)
Quick compilation of many files from a script (avoid process spawn overhead)
Integration into PropTool (yeah I wish)
Challenges:
Make everything thread-safe and easily resettable (move globals into struct)
Write custom allocator to deallocate internal structures when done
Refactor options system for programmatic interface
Refactor usage of temporary files
Finalize external API
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?
/* Returns version string. Optionally fills int pointers with version number.*/constchar*flexapi_get_version(int*major, int*minor, int*patch);
structflexapi_compiler; // Opaque structtypedefstructflexapi_compilerflexapi_compiler;
/* Allocates new compiler object.*/flexapi_compiler*flexapi_create_compiler();
/* Frees a compiler object.*/voidflexapi_free_compiler(flexapi_compiler*gl);
/* Resets a compiler object. This is semantically identical to freeing one and creating another, but with less overhead.*/voidflexapi_reset_compiler(flexapi_compiler*gl);
enumflexapi_option_type {
FLEXAPI_OPTION_INT=1,
FLEXAPI_OPTION_STRING,
FLEXAPI_OPTION_STRING_MULTI, // Used for source files, preprocessor defines, etc...FLEXAPI_OPTION_ENUM,
};
// Structstructflexapi_option {
conststructflexapi_option*next;
constchar*name; // Internally used option identifierconstchar*long_name,*description; // Long name / description for human consumptionflexapi_option_typetype;
};
typedefstructflexapi_optionflexapi_option;
/* List possible compiler options.*/constflexapi_option*flexapi_list_options();
/* List possible values for an enum-typed option. This re-uses the same flexapi_option type, take care.*/constflexapi_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.*/intflexapi_set_option(flexapi_compiler*gl,constchar*opt, constchar*value);
/* Same as flexapi_set_option, but for setting an integer value without having to create a string.*/intflexapi_set_option_int(flexapi_compiler*gl,constchar*opt, intvalue);
/* 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. If called with NULL or not called at all, a default method is used.*/voidflexapi_set_file_callback(flexapi_compiler*gl, char(*filecb)(constchar*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.*/intflexapi_do_compile(flexapi_compiler*gl);
/* Get compiled binary's size.*/intflexapi_get_binary_size(flexapi_compiler*gl);
/* Get compiled binary.*/constchar*flexapi_get_binary(flexapi_compiler*gl);
/* Get listing (zero terminated).*/constchar*flexapi_get_listing(flexapi_compiler*gl);
/* Get intermediate asm (zero terminated).*/constchar*flexapi_get_asmgen(flexapi_compiler*gl);
enumflexapi_mesg_type {
FLEXAPI_MESG_DEBUG=1,
FLEXAPI_MESG_INFO,
FLEXAPI_MESG_WARNING,
FLEXAPI_MESG_ERROR,
};
structflexapi_message {
conststructflexapi_message*next; // NULL means last messageflexapi_mesg_typetype;
unsigned intline; // 0 means unknown lineconstchar*file;
constchar*text;
};
typedefstructflexapi_messageflexapi_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.*/constflexapi_message*flexapi_get_messages(flexapi_compiler*gl);
Simple example usage (option names are conjecture):
flexapi_compiler*flex=flexapi_create_compiler();
flexapi_set_option(flex,"chip","P1");
flexapi_set_option(flex,"output","asm");
flexapi_set_option(flex,"optlevel","s");
flexapi_set_option(flex,"sourcefile","stuff.c");
flexapi_set_option(flex,"sourcefile","morestuff.c");
intstatus=flexapi_do_compile(flex);
if (status<0) {
printf("Failed to compile\n");
// Print messages here, too lazy to write that right now.
} else {
puts(flexapi_get_asmgen(flex));
}
flexapi_free_compiler(flex);
The text was updated successfully, but these errors were encountered:
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?Simple example usage (option names are conjecture):
The text was updated successfully, but these errors were encountered: