diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2024-05-12 13:50:06 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2024-05-12 13:50:06 -0400 |
| commit | d143c72b2267883c229a09cc27bbeafcf2c3fd70 (patch) | |
| tree | 90312f0e4ee553e0588dc3c45f955b5184bf3778 /parse.c | |
| parent | a20f522fd61698282d3e01931260c588dd7f40b1 (diff) | |
WIP, but functional interfaces
Diffstat (limited to 'parse.c')
| -rw-r--r-- | parse.c | 38 |
1 files changed, 38 insertions, 0 deletions
@@ -91,6 +91,7 @@ static PARSER(parse_var); static PARSER(parse_enum_def); static PARSER(parse_struct_def); static PARSER(parse_lang_def); +static PARSER(parse_interface_def); static PARSER(parse_text); static PARSER(parse_func_def); static PARSER(parse_extern); @@ -1597,6 +1598,7 @@ PARSER(parse_namespace) { if ((stmt=optional(ctx, &pos, parse_struct_def)) ||(stmt=optional(ctx, &pos, parse_enum_def)) ||(stmt=optional(ctx, &pos, parse_lang_def)) + ||(stmt=optional(ctx, &pos, parse_interface_def)) ||(stmt=optional(ctx, &pos, parse_func_def)) ||(stmt=optional(ctx, &pos, parse_use)) ||(stmt=optional(ctx, &pos, parse_linker)) @@ -1632,6 +1634,7 @@ PARSER(parse_file_body) { if ((stmt=optional(ctx, &pos, parse_struct_def)) ||(stmt=optional(ctx, &pos, parse_enum_def)) ||(stmt=optional(ctx, &pos, parse_lang_def)) + ||(stmt=optional(ctx, &pos, parse_interface_def)) ||(stmt=optional(ctx, &pos, parse_func_def)) ||(stmt=optional(ctx, &pos, parse_use)) ||(stmt=optional(ctx, &pos, parse_linker)) @@ -1809,6 +1812,41 @@ PARSER(parse_lang_def) { return NewAST(ctx->file, start, pos, LangDef, .name=name, .namespace=namespace); } +PARSER(parse_interface_def) { + // interface Name(T; field:type, ...): namespace... + const char *start = pos; + if (!match_word(&pos, "interface")) return NULL; + int64_t starting_indent = get_indent(ctx, pos); + spaces(&pos); + const char *name = get_id(&pos); + if (!name) + parser_err(ctx, start, pos, "I expected a name for this interface"); + spaces(&pos); + + if (!match(&pos, "(")) + parser_err(ctx, pos, pos, "I expected a '(' and a list of fields here"); + type_ast_t *type_param = expect(ctx, start, &pos, parse_type, "I couldn't parse the type parameter for this interface"); + whitespace(&pos); + expect_str(ctx, start, &pos, ";", "I expected a ';' here"); + arg_ast_t *fields = parse_args(ctx, &pos, false); + expect_closing(ctx, &pos, ")", "I wasn't able to parse the rest of this interface definition"); + + ast_t *namespace = NULL; + if (match(&pos, ":")) { + const char *ns_pos = pos; + whitespace(&ns_pos); + int64_t ns_indent = get_indent(ctx, ns_pos); + if (ns_indent > starting_indent) { + pos = ns_pos; + namespace = optional(ctx, &pos, parse_namespace); + } + } + if (!namespace) + namespace = NewAST(ctx->file, pos, pos, Block, .statements=NULL); + + return NewAST(ctx->file, start, pos, InterfaceDef, .name=name, .type_parameter=type_param, .fields=fields, .namespace=namespace); +} + arg_ast_t *parse_args(parse_ctx_t *ctx, const char **pos, bool allow_unnamed) { arg_ast_t *args = NULL; |
