toolchain: replace ifc interface compiler with xpcg
xpcg is used to generate xpc interfaces
This commit is contained in:
@@ -14,4 +14,4 @@ add_subdirectory(
|
|||||||
../kernel/tools
|
../kernel/tools
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/kernel-tools)
|
${CMAKE_CURRENT_BINARY_DIR}/kernel-tools)
|
||||||
|
|
||||||
add_subdirectory(ifc)
|
add_subdirectory(xpcg)
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
file(GLOB sources
|
|
||||||
*.c *.h
|
|
||||||
backend/c-mpc/*.c backend/c-mpc/*.h)
|
|
||||||
|
|
||||||
add_executable(ifc ${sources})
|
|
||||||
|
|
||||||
target_link_libraries(ifc Bluelib::Core Bluelib::Ds Bluelib::Cmd Bluelib::Io)
|
|
||||||
7
toolchain/xpcg/CMakeLists.txt
Normal file
7
toolchain/xpcg/CMakeLists.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
file(GLOB sources
|
||||||
|
*.c *.h
|
||||||
|
backend/c-mpc/*.c backend/c-mpc/*.h)
|
||||||
|
|
||||||
|
add_executable(xpcg ${sources})
|
||||||
|
|
||||||
|
target_link_libraries(xpcg Bluelib::Core Bluelib::Ds Bluelib::Cmd Bluelib::Io)
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#ifndef IFC_BACKEND_H_
|
#ifndef XPCG_BACKEND_H_
|
||||||
#define IFC_BACKEND_H_
|
#define XPCG_BACKEND_H_
|
||||||
|
|
||||||
struct interface_definition;
|
struct interface_definition;
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -43,6 +43,14 @@ const struct type *ctx_get_type(struct ctx *ctx, const char *name)
|
|||||||
return ctx_get_builtin_type(ctx, TYPE_HANDLE);
|
return ctx_get_builtin_type(ctx, TYPE_HANDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strcmp(name, "size")) {
|
||||||
|
return ctx_get_builtin_type(ctx, TYPE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(name, "buffer")) {
|
||||||
|
return ctx_get_builtin_type(ctx, TYPE_BUFFER);
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#ifndef IFC_CTX_H_
|
#ifndef XPCG_CTX_H_
|
||||||
#define IFC_CTX_H_
|
#define XPCG_CTX_H_
|
||||||
|
|
||||||
#include "type.h"
|
#include "type.h"
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#ifndef IFC_FILE_SPAN_H_
|
#ifndef XPCG_FILE_SPAN_H_
|
||||||
#define IFC_FILE_SPAN_H_
|
#define XPCG_FILE_SPAN_H_
|
||||||
|
|
||||||
struct file_cell {
|
struct file_cell {
|
||||||
unsigned int c_row, c_col;
|
unsigned int c_row, c_col;
|
||||||
@@ -6,7 +6,9 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
struct interface_definition *interface_definition_create(const char *name)
|
struct interface_definition *interface_definition_create(
|
||||||
|
const char *name,
|
||||||
|
long long id)
|
||||||
{
|
{
|
||||||
struct interface_definition *out = malloc(sizeof *out);
|
struct interface_definition *out = malloc(sizeof *out);
|
||||||
if (!out) {
|
if (!out) {
|
||||||
@@ -16,6 +18,7 @@ struct interface_definition *interface_definition_create(const char *name)
|
|||||||
memset(out, 0x0, sizeof *out);
|
memset(out, 0x0, sizeof *out);
|
||||||
|
|
||||||
out->if_name = b_strdup(name);
|
out->if_name = b_strdup(name);
|
||||||
|
out->if_id = id;
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#ifndef IFC_INTERFACE_H_
|
#ifndef XPCG_INTERFACE_H_
|
||||||
#define IFC_INTERFACE_H_
|
#define XPCG_INTERFACE_H_
|
||||||
|
|
||||||
#include <blue/core/queue.h>
|
#include <blue/core/queue.h>
|
||||||
|
|
||||||
@@ -7,11 +7,13 @@ struct msg_definition;
|
|||||||
|
|
||||||
struct interface_definition {
|
struct interface_definition {
|
||||||
char *if_name;
|
char *if_name;
|
||||||
|
long long if_id;
|
||||||
b_queue if_msg;
|
b_queue if_msg;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct interface_definition *interface_definition_create(
|
extern struct interface_definition *interface_definition_create(
|
||||||
const char *name);
|
const char *name,
|
||||||
|
long long id);
|
||||||
extern void interface_definition_destroy(struct interface_definition *iface);
|
extern void interface_definition_destroy(struct interface_definition *iface);
|
||||||
|
|
||||||
extern bool interface_definition_has_msg(
|
extern bool interface_definition_has_msg(
|
||||||
@@ -29,18 +29,21 @@
|
|||||||
static struct lex_token_def symbols[] = {
|
static struct lex_token_def symbols[] = {
|
||||||
LEX_TOKEN_DEF(SYM_COMMA, ","),
|
LEX_TOKEN_DEF(SYM_COMMA, ","),
|
||||||
LEX_TOKEN_DEF(SYM_HYPHEN, "-"),
|
LEX_TOKEN_DEF(SYM_HYPHEN, "-"),
|
||||||
|
LEX_TOKEN_DEF(SYM_LEFT_BRACKET, "["),
|
||||||
|
LEX_TOKEN_DEF(SYM_RIGHT_BRACKET, "]"),
|
||||||
LEX_TOKEN_DEF(SYM_LEFT_BRACE, "{"),
|
LEX_TOKEN_DEF(SYM_LEFT_BRACE, "{"),
|
||||||
LEX_TOKEN_DEF(SYM_RIGHT_BRACE, "}"),
|
LEX_TOKEN_DEF(SYM_RIGHT_BRACE, "}"),
|
||||||
LEX_TOKEN_DEF(SYM_LEFT_PAREN, "("),
|
LEX_TOKEN_DEF(SYM_LEFT_PAREN, "("),
|
||||||
LEX_TOKEN_DEF(SYM_RIGHT_PAREN, ")"),
|
LEX_TOKEN_DEF(SYM_RIGHT_PAREN, ")"),
|
||||||
LEX_TOKEN_DEF(SYM_SEMICOLON, ";"),
|
LEX_TOKEN_DEF(SYM_SEMICOLON, ";"),
|
||||||
|
LEX_TOKEN_DEF(SYM_COLON, ":"),
|
||||||
LEX_TOKEN_DEF(SYM_HYPHEN_RIGHT_ANGLE, "->"),
|
LEX_TOKEN_DEF(SYM_HYPHEN_RIGHT_ANGLE, "->"),
|
||||||
};
|
};
|
||||||
static const size_t nr_symbols = sizeof symbols / sizeof symbols[0];
|
static const size_t nr_symbols = sizeof symbols / sizeof symbols[0];
|
||||||
|
|
||||||
static struct lex_token_def keywords[] = {
|
static struct lex_token_def keywords[] = {
|
||||||
LEX_TOKEN_DEF(KW_INTERFACE, "interface"),
|
LEX_TOKEN_DEF(KW_INTERFACE, "interface"),
|
||||||
LEX_TOKEN_DEF(KW_MSG, "msg"),
|
LEX_TOKEN_DEF(KW_FUNC, "func"),
|
||||||
};
|
};
|
||||||
static const size_t nr_keywords = sizeof keywords / sizeof keywords[0];
|
static const size_t nr_keywords = sizeof keywords / sizeof keywords[0];
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#ifndef IFC_LEX_H_
|
#ifndef XPCG_LEX_H_
|
||||||
#define IFC_LEX_H_
|
#define XPCG_LEX_H_
|
||||||
|
|
||||||
#include "status.h"
|
#include "status.h"
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
@@ -64,7 +64,10 @@ static void print_interface(struct interface_definition *iface)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ifc(const b_command *self, const b_arglist *opt, const b_array *args)
|
static int xpcg(
|
||||||
|
const b_command *self,
|
||||||
|
const b_arglist *opt,
|
||||||
|
const b_array *args)
|
||||||
{
|
{
|
||||||
const char *path = NULL;
|
const char *path = NULL;
|
||||||
b_arglist_get_string(opt, B_COMMAND_INVALID_ID, ARG_SRCPATH, 0, &path);
|
b_arglist_get_string(opt, B_COMMAND_INVALID_ID, ARG_SRCPATH, 0, &path);
|
||||||
@@ -132,10 +135,10 @@ static int ifc(const b_command *self, const b_arglist *opt, const b_array *args)
|
|||||||
|
|
||||||
B_COMMAND(CMD_ID, B_COMMAND_INVALID_ID)
|
B_COMMAND(CMD_ID, B_COMMAND_INVALID_ID)
|
||||||
{
|
{
|
||||||
B_COMMAND_NAME("ifc");
|
B_COMMAND_NAME("xpcg");
|
||||||
B_COMMAND_DESC("interface definition compiler.");
|
B_COMMAND_DESC("xpc interface generator.");
|
||||||
B_COMMAND_FLAGS(B_COMMAND_SHOW_HELP_BY_DEFAULT);
|
B_COMMAND_FLAGS(B_COMMAND_SHOW_HELP_BY_DEFAULT);
|
||||||
B_COMMAND_FUNCTION(ifc);
|
B_COMMAND_FUNCTION(xpcg);
|
||||||
B_COMMAND_HELP_OPTION();
|
B_COMMAND_HELP_OPTION();
|
||||||
|
|
||||||
B_COMMAND_ARG(ARG_SRCPATH)
|
B_COMMAND_ARG(ARG_SRCPATH)
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
struct msg_definition *msg_definition_create(const char *name)
|
struct msg_definition *msg_definition_create(const char *name, long long id)
|
||||||
{
|
{
|
||||||
struct msg_definition *out = malloc(sizeof *out);
|
struct msg_definition *out = malloc(sizeof *out);
|
||||||
if (!out) {
|
if (!out) {
|
||||||
@@ -14,6 +14,7 @@ struct msg_definition *msg_definition_create(const char *name)
|
|||||||
memset(out, 0x0, sizeof *out);
|
memset(out, 0x0, sizeof *out);
|
||||||
|
|
||||||
out->msg_name = b_strdup(name);
|
out->msg_name = b_strdup(name);
|
||||||
|
out->msg_id = id;
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#ifndef IFC_MSG_H_
|
#ifndef XPCG_MSG_H_
|
||||||
#define IFC_MSG_H_
|
#define XPCG_MSG_H_
|
||||||
|
|
||||||
#include <blue/core/queue.h>
|
#include <blue/core/queue.h>
|
||||||
|
|
||||||
@@ -13,13 +13,16 @@ struct msg_parameter {
|
|||||||
|
|
||||||
struct msg_definition {
|
struct msg_definition {
|
||||||
char *msg_name;
|
char *msg_name;
|
||||||
|
long long msg_id;
|
||||||
b_queue_entry msg_entry;
|
b_queue_entry msg_entry;
|
||||||
|
|
||||||
b_queue msg_params;
|
b_queue msg_params;
|
||||||
b_queue msg_results;
|
b_queue msg_results;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct msg_definition *msg_definition_create(const char *name);
|
extern struct msg_definition *msg_definition_create(
|
||||||
|
const char *name,
|
||||||
|
long long id);
|
||||||
extern void msg_definition_destroy(struct msg_definition *msg);
|
extern void msg_definition_destroy(struct msg_definition *msg);
|
||||||
|
|
||||||
extern bool msg_definition_has_param(
|
extern bool msg_definition_has_param(
|
||||||
@@ -48,26 +48,55 @@ static bool parse_word(struct lex *lex, char **out)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool parse_int(struct lex *lex, long long *out)
|
||||||
|
{
|
||||||
|
struct token *tok = lex_peek(lex);
|
||||||
|
if (!tok || tok->tok_type != TOK_INT) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out = tok->tok_int;
|
||||||
|
lex_advance(lex);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
struct msg_definition *parse_msg_definition(struct ctx *ctx, struct lex *lex)
|
struct msg_definition *parse_msg_definition(struct ctx *ctx, struct lex *lex)
|
||||||
{
|
{
|
||||||
struct msg_definition *msg = NULL;
|
struct msg_definition *msg = NULL;
|
||||||
|
|
||||||
if (!parse_keyword(lex, KW_MSG)) {
|
if (!parse_keyword(lex, KW_FUNC)) {
|
||||||
report_error("expected `msg` keyword\n");
|
report_error("expected `func` keyword\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *msg_name = NULL;
|
char *msg_name = NULL;
|
||||||
if (!parse_word(lex, &msg_name)) {
|
if (!parse_word(lex, &msg_name)) {
|
||||||
report_error("expected message identifier\n");
|
report_error("expected function identifier\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = msg_definition_create(msg_name);
|
long long msg_id = 0;
|
||||||
|
if (!parse_symbol(lex, SYM_LEFT_BRACKET)) {
|
||||||
|
report_error("expected `[` after function identifier\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parse_int(lex, &msg_id)) {
|
||||||
|
report_error("expected function id number after `[`\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parse_symbol(lex, SYM_RIGHT_BRACKET)) {
|
||||||
|
report_error("expected `]` after function id number\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg = msg_definition_create(msg_name, msg_id);
|
||||||
free(msg_name);
|
free(msg_name);
|
||||||
|
|
||||||
if (!parse_symbol(lex, SYM_LEFT_PAREN)) {
|
if (!parse_symbol(lex, SYM_LEFT_PAREN)) {
|
||||||
report_error("expected `(` after message identifier\n");
|
report_error(
|
||||||
|
"expected `(` after function id number specifier\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,14 +108,31 @@ struct msg_definition *parse_msg_definition(struct ctx *ctx, struct lex *lex)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (i > 0 && !parse_symbol(lex, SYM_COMMA)) {
|
if (i > 0 && !parse_symbol(lex, SYM_COMMA)) {
|
||||||
report_error("expected `,` after message parameter\n");
|
report_error(
|
||||||
|
"expected `,` after function "
|
||||||
|
"parameter\n");
|
||||||
|
ok = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *param_name;
|
||||||
|
if (!parse_word(lex, ¶m_name)) {
|
||||||
|
report_error("expected function parameter name\n");
|
||||||
|
ok = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parse_symbol(lex, SYM_COLON)) {
|
||||||
|
report_error(
|
||||||
|
"expected `:` after function parameter "
|
||||||
|
"name\n");
|
||||||
ok = false;
|
ok = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *type_name;
|
char *type_name;
|
||||||
if (!parse_word(lex, &type_name)) {
|
if (!parse_word(lex, &type_name)) {
|
||||||
report_error("expected message parameter type\n");
|
report_error("expected function parameter type\n");
|
||||||
ok = false;
|
ok = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -94,7 +140,7 @@ struct msg_definition *parse_msg_definition(struct ctx *ctx, struct lex *lex)
|
|||||||
const struct type *type = ctx_get_type(ctx, type_name);
|
const struct type *type = ctx_get_type(ctx, type_name);
|
||||||
if (!type) {
|
if (!type) {
|
||||||
report_error(
|
report_error(
|
||||||
"message parameter has unknown type "
|
"function parameter has unknown type "
|
||||||
"'%s'\n",
|
"'%s'\n",
|
||||||
type_name);
|
type_name);
|
||||||
free(type_name);
|
free(type_name);
|
||||||
@@ -104,19 +150,13 @@ struct msg_definition *parse_msg_definition(struct ctx *ctx, struct lex *lex)
|
|||||||
|
|
||||||
free(type_name);
|
free(type_name);
|
||||||
|
|
||||||
char *param_name;
|
|
||||||
if (!parse_word(lex, ¶m_name)) {
|
|
||||||
report_error("expected message parameter name\n");
|
|
||||||
ok = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool duplicate = msg_definition_has_param(msg, param_name)
|
bool duplicate = msg_definition_has_param(msg, param_name)
|
||||||
|| msg_definition_has_result(msg, param_name);
|
|| msg_definition_has_result(msg, param_name);
|
||||||
if (duplicate) {
|
if (duplicate) {
|
||||||
free(param_name);
|
free(param_name);
|
||||||
report_error(
|
report_error(
|
||||||
"message has multiple parameters/results with "
|
"function has multiple "
|
||||||
|
"parameters/results with "
|
||||||
"name '%s'\n",
|
"name '%s'\n",
|
||||||
param_name);
|
param_name);
|
||||||
ok = false;
|
ok = false;
|
||||||
@@ -133,12 +173,14 @@ struct msg_definition *parse_msg_definition(struct ctx *ctx, struct lex *lex)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!parse_symbol(lex, SYM_HYPHEN_RIGHT_ANGLE)) {
|
if (!parse_symbol(lex, SYM_HYPHEN_RIGHT_ANGLE)) {
|
||||||
report_error("expected `->` after message parameter list\n");
|
report_error(
|
||||||
|
"expected `->` after function parameter "
|
||||||
|
"list\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parse_symbol(lex, SYM_LEFT_PAREN)) {
|
if (!parse_symbol(lex, SYM_LEFT_PAREN)) {
|
||||||
report_error("expected `(` for message results list\n");
|
report_error("expected `(` for function results list\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,14 +192,30 @@ struct msg_definition *parse_msg_definition(struct ctx *ctx, struct lex *lex)
|
|||||||
|
|
||||||
if (i > 0 && !parse_symbol(lex, SYM_COMMA)) {
|
if (i > 0 && !parse_symbol(lex, SYM_COMMA)) {
|
||||||
report_error(
|
report_error(
|
||||||
"expected `,` or `)` after message result\n");
|
"expected `,` or `)` after function "
|
||||||
|
"result\n");
|
||||||
|
ok = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *result_name;
|
||||||
|
if (!parse_word(lex, &result_name)) {
|
||||||
|
report_error("expected function parameter name\n");
|
||||||
|
ok = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parse_symbol(lex, SYM_COLON)) {
|
||||||
|
report_error(
|
||||||
|
"expected `:` after function result "
|
||||||
|
"name\n");
|
||||||
ok = false;
|
ok = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *type_name;
|
char *type_name;
|
||||||
if (!parse_word(lex, &type_name)) {
|
if (!parse_word(lex, &type_name)) {
|
||||||
report_error("expected message result type\n");
|
report_error("expected function result type\n");
|
||||||
ok = false;
|
ok = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -165,7 +223,7 @@ struct msg_definition *parse_msg_definition(struct ctx *ctx, struct lex *lex)
|
|||||||
const struct type *type = ctx_get_type(ctx, type_name);
|
const struct type *type = ctx_get_type(ctx, type_name);
|
||||||
if (!type) {
|
if (!type) {
|
||||||
report_error(
|
report_error(
|
||||||
"message result has unknown type "
|
"function result has unknown type "
|
||||||
"'%s'\n",
|
"'%s'\n",
|
||||||
type_name);
|
type_name);
|
||||||
free(type_name);
|
free(type_name);
|
||||||
@@ -174,18 +232,12 @@ struct msg_definition *parse_msg_definition(struct ctx *ctx, struct lex *lex)
|
|||||||
}
|
}
|
||||||
free(type_name);
|
free(type_name);
|
||||||
|
|
||||||
char *result_name;
|
|
||||||
if (!parse_word(lex, &result_name)) {
|
|
||||||
report_error("expected message parameter name\n");
|
|
||||||
ok = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool duplicate = msg_definition_has_param(msg, result_name)
|
bool duplicate = msg_definition_has_param(msg, result_name)
|
||||||
|| msg_definition_has_result(msg, result_name);
|
|| msg_definition_has_result(msg, result_name);
|
||||||
if (duplicate) {
|
if (duplicate) {
|
||||||
report_error(
|
report_error(
|
||||||
"message has multiple parameters/results with "
|
"function has multiple "
|
||||||
|
"parameters/results with "
|
||||||
"name '%s'\n",
|
"name '%s'\n",
|
||||||
result_name);
|
result_name);
|
||||||
free(result_name);
|
free(result_name);
|
||||||
@@ -199,7 +251,7 @@ struct msg_definition *parse_msg_definition(struct ctx *ctx, struct lex *lex)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!parse_symbol(lex, SYM_SEMICOLON)) {
|
if (!parse_symbol(lex, SYM_SEMICOLON)) {
|
||||||
report_error("expected `;` after message definition\n");
|
report_error("expected `;` after function definition\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,29 +278,35 @@ struct interface_definition *parse_interface_definition(
|
|||||||
|
|
||||||
char *if_name = NULL;
|
char *if_name = NULL;
|
||||||
if (!parse_word(lex, &if_name)) {
|
if (!parse_word(lex, &if_name)) {
|
||||||
report_error("expected interface identifier");
|
report_error("expected interface name");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
iface = interface_definition_create(if_name);
|
long long if_id = 0;
|
||||||
|
if (!parse_int(lex, &if_id)) {
|
||||||
|
report_error("expected interface id number");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parse_symbol(lex, SYM_SEMICOLON)) {
|
||||||
|
report_error("expected `;` after interface definition");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
iface = interface_definition_create(if_name, if_id);
|
||||||
free(if_name);
|
free(if_name);
|
||||||
if (!iface) {
|
if (!iface) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!parse_symbol(lex, SYM_LEFT_BRACE)) {
|
|
||||||
report_error("expected `{` after interface identifier");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
|
|
||||||
while (ok) {
|
while (ok) {
|
||||||
if (parse_symbol(lex, SYM_RIGHT_BRACE)) {
|
if (!lex_peek(lex) && lex_get_status(lex) == ERR_EOF) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (peek_keyword(lex, KW_MSG)) {
|
if (peek_keyword(lex, KW_FUNC)) {
|
||||||
struct msg_definition *msg
|
struct msg_definition *msg
|
||||||
= parse_msg_definition(ctx, lex);
|
= parse_msg_definition(ctx, lex);
|
||||||
if (!msg) {
|
if (!msg) {
|
||||||
@@ -268,7 +326,7 @@ struct interface_definition *parse_interface_definition(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
report_error("expected `}` or message definition\n");
|
report_error("expected eof or function definition\n");
|
||||||
ok = false;
|
ok = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#ifndef IFC_PARSE_H_
|
#ifndef XPCG_PARSE_H_
|
||||||
#define IFC_PARSE_H_
|
#define XPCG_PARSE_H_
|
||||||
|
|
||||||
struct ctx;
|
struct ctx;
|
||||||
struct lex;
|
struct lex;
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#ifndef IFC_STATUS_H_
|
#ifndef XPCG_STATUS_H_
|
||||||
#define IFC_STATUS_H_
|
#define XPCG_STATUS_H_
|
||||||
|
|
||||||
enum status {
|
enum status {
|
||||||
SUCCESS = 0,
|
SUCCESS = 0,
|
||||||
@@ -40,6 +40,7 @@ const char *token_symbol_to_string(enum token_symbol sym)
|
|||||||
ENUM_STR(SYM_NONE);
|
ENUM_STR(SYM_NONE);
|
||||||
ENUM_STR(SYM_COMMA);
|
ENUM_STR(SYM_COMMA);
|
||||||
ENUM_STR(SYM_SEMICOLON);
|
ENUM_STR(SYM_SEMICOLON);
|
||||||
|
ENUM_STR(SYM_COLON);
|
||||||
ENUM_STR(SYM_HYPHEN);
|
ENUM_STR(SYM_HYPHEN);
|
||||||
ENUM_STR(SYM_LEFT_BRACE);
|
ENUM_STR(SYM_LEFT_BRACE);
|
||||||
ENUM_STR(SYM_RIGHT_BRACE);
|
ENUM_STR(SYM_RIGHT_BRACE);
|
||||||
@@ -56,7 +57,7 @@ const char *token_keyword_to_string(enum token_keyword kw)
|
|||||||
switch (kw) {
|
switch (kw) {
|
||||||
ENUM_STR(KW_NONE);
|
ENUM_STR(KW_NONE);
|
||||||
ENUM_STR(KW_INTERFACE);
|
ENUM_STR(KW_INTERFACE);
|
||||||
ENUM_STR(KW_MSG);
|
ENUM_STR(KW_FUNC);
|
||||||
default:
|
default:
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#ifndef IFC_TOKEN_H_
|
#ifndef XPCG_TOKEN_H_
|
||||||
#define IFC_TOKEN_H_
|
#define XPCG_TOKEN_H_
|
||||||
|
|
||||||
#include "file-span.h"
|
#include "file-span.h"
|
||||||
|
|
||||||
@@ -34,6 +34,9 @@ enum token_symbol {
|
|||||||
SYM_COMMA = __TOK_UBOUND,
|
SYM_COMMA = __TOK_UBOUND,
|
||||||
SYM_HYPHEN,
|
SYM_HYPHEN,
|
||||||
SYM_SEMICOLON,
|
SYM_SEMICOLON,
|
||||||
|
SYM_COLON,
|
||||||
|
SYM_LEFT_BRACKET,
|
||||||
|
SYM_RIGHT_BRACKET,
|
||||||
SYM_LEFT_BRACE,
|
SYM_LEFT_BRACE,
|
||||||
SYM_RIGHT_BRACE,
|
SYM_RIGHT_BRACE,
|
||||||
SYM_LEFT_PAREN,
|
SYM_LEFT_PAREN,
|
||||||
@@ -45,7 +48,7 @@ enum token_symbol {
|
|||||||
enum token_keyword {
|
enum token_keyword {
|
||||||
KW_NONE = 0,
|
KW_NONE = 0,
|
||||||
KW_INTERFACE = __SYM_UBOUND,
|
KW_INTERFACE = __SYM_UBOUND,
|
||||||
KW_MSG,
|
KW_FUNC,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct token {
|
struct token {
|
||||||
@@ -11,6 +11,12 @@ void type_print(const struct type *ty)
|
|||||||
case TYPE_STRING:
|
case TYPE_STRING:
|
||||||
printf("string");
|
printf("string");
|
||||||
break;
|
break;
|
||||||
|
case TYPE_SIZE:
|
||||||
|
printf("size");
|
||||||
|
break;
|
||||||
|
case TYPE_BUFFER:
|
||||||
|
printf("buffer");
|
||||||
|
break;
|
||||||
case TYPE_HANDLE:
|
case TYPE_HANDLE:
|
||||||
printf("handle");
|
printf("handle");
|
||||||
break;
|
break;
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
#ifndef IFC_TYPE_H_
|
#ifndef XPCG_TYPE_H_
|
||||||
#define IFC_TYPE_H_
|
#define XPCG_TYPE_H_
|
||||||
|
|
||||||
enum type_id {
|
enum type_id {
|
||||||
TYPE_NONE,
|
TYPE_NONE,
|
||||||
TYPE_INT,
|
TYPE_INT,
|
||||||
|
TYPE_SIZE,
|
||||||
TYPE_STRING,
|
TYPE_STRING,
|
||||||
|
TYPE_BUFFER,
|
||||||
TYPE_HANDLE,
|
TYPE_HANDLE,
|
||||||
TYPE_OTHER,
|
TYPE_OTHER,
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user