170 lines
3.4 KiB
C
170 lines
3.4 KiB
C
#include "backend.h"
|
|
#include "ctx.h"
|
|
#include "interface.h"
|
|
#include "lex.h"
|
|
#include "line-source.h"
|
|
#include "msg.h"
|
|
#include "parse.h"
|
|
|
|
#include <fx/cmd.h>
|
|
#include <fx/io/file.h>
|
|
#include <fx/io/path.h>
|
|
|
|
#define CMD_ID 0
|
|
|
|
enum {
|
|
ARG_SRCPATH,
|
|
OPT_BACKEND,
|
|
OPT_BACKEND_ARG_NAME,
|
|
};
|
|
|
|
int main(int argc, const char **argv)
|
|
{
|
|
return fx_command_dispatch(CMD_ID, argc, argv);
|
|
}
|
|
|
|
static void print_msg(struct msg_definition *msg)
|
|
{
|
|
printf(" msg: %s\n", msg->msg_name);
|
|
|
|
fx_queue_entry *entry = fx_queue_first(&msg->msg_params);
|
|
while (entry) {
|
|
struct msg_parameter *param
|
|
= fx_unbox(struct msg_parameter, entry, p_entry);
|
|
|
|
printf(" param:");
|
|
type_print(param->p_type);
|
|
printf(" %s\n", param->p_name);
|
|
|
|
entry = fx_queue_next(entry);
|
|
}
|
|
|
|
entry = fx_queue_first(&msg->msg_results);
|
|
while (entry) {
|
|
struct msg_parameter *param
|
|
= fx_unbox(struct msg_parameter, entry, p_entry);
|
|
|
|
printf(" result:");
|
|
type_print(param->p_type);
|
|
printf(" %s\n", param->p_name);
|
|
|
|
entry = fx_queue_next(entry);
|
|
}
|
|
}
|
|
|
|
static void print_interface(struct interface_definition *iface)
|
|
{
|
|
printf("interface: %s\n", iface->if_name);
|
|
fx_queue_entry *entry = fx_queue_first(&iface->if_msg);
|
|
while (entry) {
|
|
struct msg_definition *msg
|
|
= fx_unbox(struct msg_definition, entry, msg_entry);
|
|
print_msg(msg);
|
|
entry = fx_queue_next(entry);
|
|
}
|
|
}
|
|
|
|
static int xpcg(
|
|
const fx_command *self,
|
|
const fx_arglist *opt,
|
|
const fx_array *args)
|
|
{
|
|
const char *path = NULL;
|
|
fx_arglist_get_string(opt, FX_COMMAND_INVALID_ID, ARG_SRCPATH, 0, &path);
|
|
if (!path) {
|
|
fx_arglist_report_missing_args(
|
|
opt,
|
|
FX_COMMAND_INVALID_ID,
|
|
ARG_SRCPATH,
|
|
0);
|
|
return -1;
|
|
}
|
|
|
|
fx_file *file = NULL;
|
|
fx_result result
|
|
= fx_file_open(NULL, FX_RV_PATH(path), FX_FILE_READ_ONLY, &file);
|
|
if (fx_result_is_error(result)) {
|
|
fx_throw(result);
|
|
return -1;
|
|
}
|
|
|
|
struct line_source src;
|
|
line_source_init(&src, path, file);
|
|
|
|
struct ctx *ctx = ctx_create();
|
|
struct lex *lex = lex_create(&src);
|
|
#if 0
|
|
struct token *tok = lex_peek(lex);
|
|
while (tok) {
|
|
printf("%s", token_type_to_string(tok->tok_type));
|
|
|
|
switch (tok->tok_value_type) {
|
|
case TOK_V_INT:
|
|
printf(" %lld", tok->tok_int);
|
|
break;
|
|
case TOK_V_STRING:
|
|
printf(" %s", tok->tok_str);
|
|
break;
|
|
case TOK_V_SYMBOL:
|
|
printf(" %s", token_symbol_to_string(tok->tok_sym));
|
|
break;
|
|
case TOK_V_KEYWORD:
|
|
printf(" %s", token_keyword_to_string(tok->tok_kw));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
printf("\n");
|
|
lex_advance(lex);
|
|
tok = lex_peek(lex);
|
|
}
|
|
#endif
|
|
|
|
struct interface_definition *iface
|
|
= parse_interface_definition(ctx, lex);
|
|
if (!iface) {
|
|
return -1;
|
|
}
|
|
|
|
const struct backend *backend = c_mpc_backend();
|
|
int err = backend->b_emit(iface);
|
|
|
|
return err;
|
|
}
|
|
|
|
FX_COMMAND(CMD_ID, FX_COMMAND_INVALID_ID)
|
|
{
|
|
FX_COMMAND_NAME("xpcg");
|
|
FX_COMMAND_DESC("xpc interface generator.");
|
|
FX_COMMAND_FLAGS(FX_COMMAND_SHOW_HELP_BY_DEFAULT);
|
|
FX_COMMAND_FUNCTION(xpcg);
|
|
FX_COMMAND_HELP_OPTION();
|
|
|
|
FX_COMMAND_ARG(ARG_SRCPATH)
|
|
{
|
|
FX_ARG_NAME("source-file");
|
|
FX_ARG_DESC("the interface file to compile.");
|
|
FX_ARG_NR_VALUES(1);
|
|
}
|
|
|
|
FX_COMMAND_OPTION(OPT_BACKEND)
|
|
{
|
|
FX_OPTION_LONG_NAME("backend");
|
|
FX_OPTION_SHORT_NAME('b');
|
|
FX_OPTION_DESC("which backend to use.");
|
|
FX_OPTION_ARG(OPT_BACKEND_ARG_NAME)
|
|
{
|
|
FX_ARG_NAME("backend-name");
|
|
FX_ARG_NR_VALUES(1);
|
|
FX_ARG_ALLOWED_VALUES("c-mpc");
|
|
}
|
|
}
|
|
|
|
FX_COMMAND_USAGE()
|
|
{
|
|
FX_COMMAND_USAGE_ARG(ARG_SRCPATH);
|
|
FX_COMMAND_USAGE_OPT(OPT_BACKEND);
|
|
}
|
|
}
|