From 5008891f9dc1fa194a4db0e8c05772a7749dad39 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Fri, 11 Apr 2025 22:51:58 +0200 Subject: a --- attocc.c | 470 +++++++++++---------------------------------------------------- 1 file changed, 76 insertions(+), 394 deletions(-) diff --git a/attocc.c b/attocc.c index 4c901c6..f2035ef 100644 --- a/attocc.c +++ b/attocc.c @@ -624,421 +624,103 @@ void token_print(struct token tok) { } #endif -struct node { - enum node_kind { - NO_BINOP, - NO_UNOP, - NO_MEMBER_ACCESS, - NO_STRUCT, - NO_UNION, - NO_ENUM, - NO_TYPE_PRIMITIVE, - NO_TYPE_POINTER, - NO_FUNCTION, - NO_COMPOUND, - NO_TR_UNIT, - } kind; - union node_data { - struct node *type_pointer; - enum node_primitive_type { - PRIMTY_U64, - PRIMTY_I32, - PRIMTY_U8, - } primitive_type; - struct node_data_tr_unit { - unsigned long num_elements; - struct node **elements; - } tr_unit; - struct node_data_function { - struct node *return_type; - char *name; - unsigned long num_arguments; - struct function_argument { - char *name; - struct node *type; - } *arguments; - struct node *body; - } function; - struct node_data_compound { - unsigned long num_statements; - struct node **statements; - } compount; - struct node_data_binop { - struct node *lhs; - struct node *rhs; - } binop; - struct node_data_enum { - char *name; - char is_decl; - unsigned long num_members; - struct enum_member { - int value; - char *name; - } *members; - } enum_; - } data; -}; - -struct node *parse_enum_decl(int *p, struct token *tokens, struct error *error); -struct node *parse_function(int *p, struct token *tokens, struct error *error); -struct node *parse_type(int *p, struct token *tokens, struct error *error); -struct node *parse_toplevel(int *p, struct token *tokens, struct error *error); - -struct node *parse(int *p, struct token *tokens, struct error *error) { - int num_elements = 0; - struct node **elements = NULL; - while (tokens[*p].kind != TOK_END) { - struct node *el = parse_toplevel(p, tokens, error); - if (!el) - return NULL; - num_elements += 1; - elements = realloc_failsafe(elements, num_elements * sizeof(struct node *)); - elements[num_elements - 1] = el; - } - struct node *node = realloc_failsafe(NULL, sizeof(struct node)); - node->kind = NO_TR_UNIT; - node->data.tr_unit.elements = elements; - node->data.tr_unit.num_elements = num_elements; - return node; -} - -struct node *parse_toplevel(int *p, struct token *tokens, struct error *error) { - struct node *out; - out = parse_type(p, tokens, error); - if (out) - return out; - out = parse_function(p, tokens, error); - if (out) - return out; - - return NULL; +int token_step(struct token_iter *iter, struct token *a) { + token_free(*a); + *a = token_iter_next(iter); + return a->kind == TOK_END || a->kind == TOK_ERROR; } -struct node *parse_type(int *p, struct token *tokens, struct error *error) { - struct node *out; - out = parse_enum_decl(p, tokens, error); - if (out) - return out; - - if (tokens[*p].kind == TOK_IDENTIFIER) { - struct node *node = realloc_failsafe(NULL, sizeof(struct node)); - node->kind = NO_TYPE_PRIMITIVE; - node->data.primitive_type = PRIMTY_I32; - } - - error->message = "type expected"; - error->position = tokens[*p].position; - return NULL; -} +enum type_kind { + PRIMITIVE, + ENUM, + STRUCT, + UNION, +}; -struct node *parse_function(int *p, struct token *tokens, struct error *error) { - struct node *return_type = parse_type(p, tokens, error); - if (!return_type) - return NULL; +struct struct_decl {}; +struct union_decl {}; - if (tokens[*p].kind != TOK_IDENTIFIER) - return NULL; - char *name = strdup_failsafe(tokens[*p].data.identifier); - *p += 1; +struct type { + enum type_kind kind; + int index; +}; - if (tokens[*p].kind != TOK_SEPERATOR || - tokens[*p].data.seperator != SEP_LPAREN) - return NULL; - *p += 1; +struct constant { + struct type type; +}; - int num_arguments = 0; - struct function_argument *arguments = NULL; +struct global_context { + int num_constants; + struct constant *constants; +}; +int enum_decl(struct global_context *gcx, struct token_iter *iter, + struct token *a) { + int value = 0; while (1) { - if (tokens[*p].kind == TOK_END) - return NULL; - if (tokens[*p].kind == TOK_SEPERATOR && - tokens[*p].data.seperator == SEP_RPAREN) - break; - - struct node *type = parse_type(p, tokens, error); - if (tokens[*p].kind != TOK_IDENTIFIER) - return NULL; - char *name = strdup_failsafe(tokens->data.identifier); - *p += 1; - - if (tokens[*p].kind == TOK_SEPERATOR && - tokens[*p].data.seperator == SEP_COMMA) - *p += 1; - - num_arguments += 1; - arguments = realloc_failsafe( - arguments, num_arguments * sizeof(struct function_argument)); - arguments[num_arguments - 1].name = name; - arguments[num_arguments - 1].type = type; - } - - struct node *node = realloc_failsafe(NULL, sizeof(struct node)); - node->kind = NO_FUNCTION; - node->data.function.return_type = return_type; - node->data.function.name = name; - return node; -} - -struct node *parse_enum_decl(int *p, struct token *tokens, - struct error *error) { - if (tokens[*p].kind != TOK_KEYWORD || tokens[*p].data.keyword != KW_ENUM) { - error->message = "expected enum keyword"; - error->position = tokens[*p].position; - return NULL; - } - *p += 1; - - char *ident = NULL; - if (tokens[*p].kind == TOK_IDENTIFIER) { - ident = tokens[*p].data.identifier; - *p += 1; - } - - char is_decl = 0; - struct enum_member *members = NULL; - unsigned long num_members = 0; - - if (tokens[*p].kind == TOK_SEPERATOR && - tokens[*p].data.seperator == SEP_LCURLY) { - *p += 1; - is_decl = 1; - - int value = 0; - - while (1) { - if (tokens[*p].kind == TOK_SEPERATOR && - tokens[*p].data.seperator == SEP_RCURLY) - break; - - if (tokens[*p].kind == TOK_END) { - error->message = "unexpected eof in enum decl"; - error->position = tokens[*p].position; - return NULL; - } - - if (tokens[*p].kind == TOK_SEPERATOR && - tokens[*p].data.seperator == SEP_COMMA) { - *p += 1; - continue; - } - - if (tokens[*p].kind != TOK_IDENTIFIER) { - error->message = "expected identifier in enum decl"; - error->position = tokens[*p].position; - return NULL; - } - - char *m_ident = tokens[*p].data.identifier; - - if (tokens[*p].kind == TOK_OPERATOR && - tokens[*p].data.operator== OP_ASSIGN) { - *p += 1; - - if (tokens[*p].kind == TOK_END) { - error->message = "unexpected eof in enum decl"; - error->position = tokens[*p].position; - return NULL; + if (a->kind == TOK_IDENTIFIER) { + char *name = strdup(a->data.identifier); + if (token_step(iter, a)) + return 1; + + if (a->kind == TOK_OPERATOR && a->kind == OP_ASSIGN) { + if (token_step(iter, a)) + return 1; + if (a->kind == TOK_CONSTANT && a->data.constant_kind == CONST_INT) { + value = a->data.constant_int_value; + } else { + fprintf(stderr, "expected int const after enum assign\n"); + return 1; } - - if (tokens[*p].kind != TOK_CONSTANT || - tokens[*p].data.constant_kind != CONST_INT) { - error->message = "expected integer constant as enum value"; - error->position = tokens[*p].position; - return NULL; - } - - value = tokens[*p].data.constant_int_value; - *p += 1; - } - - num_members++; - members = - realloc_failsafe(members, sizeof(struct enum_member) * num_members); - struct enum_member *new_member = &members[num_members - 1]; - new_member->value = value++; - new_member->name = strdup_failsafe(m_ident); - - *p += 1; - } - } else if (tokens[*p].kind == TOK_SEPERATOR && - tokens[*p].data.seperator == SEP_SEMICOLON) { - - } else { - error->message = "expected semicolon or enum variants"; - error->position = tokens[*p].position; - return NULL; - } - - struct node *node = realloc_failsafe(NULL, sizeof(struct node)); - node->kind = NO_ENUM; - node->data.enum_.is_decl = is_decl; - node->data.enum_.name = strdup_failsafe(ident); - node->data.enum_.num_members = num_members; - node->data.enum_.members = members; - return node; -} - -#ifdef DEBUG -void indent(int k) { - for (int i = 0; i < k; i++) { - printf(" "); - } -} - -void debug_node(struct node *node, int k) { - switch (node->kind) { - case NO_ENUM: - indent(k); - printf("NO_ENUM\n"); - indent(k + 1); - printf("name=%s\n", node->data.enum_.name); - indent(k + 1); - printf("is_decl=%i\n", node->data.enum_.is_decl); - if (node->data.enum_.is_decl) { - indent(k + 1); - printf("num_members=%li\n", node->data.enum_.num_members); - indent(k + 1); - printf("members\n"); - for (unsigned long i = 0; i < node->data.enum_.num_members; i++) { - indent(k + 2); - printf("%s=%i\n", node->data.enum_.members[i].name, - node->data.enum_.members[i].value); + } else if (a->kind == TOK_SEPERATOR && a->data.seperator == SEP_COMMA) { + if (token_step(iter, a)) + return 1; + continue; + } else { + fprintf(stderr, "expected assign or comma after enum ident\n"); + return 1; } - } - break; - case NO_BINOP: - indent(k); - printf("NO_BINOP\n"); - indent(k + 1); - printf("lhs: "); - debug_node(node->data.binop.lhs, k + 2); - printf("\n"); - indent(k + 1); - printf("rhs: "); - debug_node(node->data.binop.rhs, k + 2); - printf("\n"); - break; - case NO_MEMBER_ACCESS: - printf("NO_MEMBER_ACCESS\n"); - break; - case NO_FUNCTION: - printf("NO_FUNCTION\n"); - break; - case NO_STRUCT: - printf("NO_STRUCT\n"); - break; - case NO_UNION: - printf("NO_UNION\n"); - break; - case NO_UNOP: - printf("NO_UNOP\n"); - break; - case NO_TR_UNIT: - indent(k); - printf("NO_TR_UNIT\n"); - for (unsigned long i = 0; i < node->data.tr_unit.num_elements; i++) - debug_node(node->data.tr_unit.elements[i], k + 1); - default: - break; - } -} -#endif - -struct token_buffer { - struct token tokens[4]; - struct token_iter *iter; -}; - -struct token_buffer token_buffer_new(struct token_iter *iter) { - struct token_buffer buf; - for (int i = 0; i < 4; i++) { - buf.tokens[i] = token_iter_next(iter); - if (buf.tokens[i].kind == TOK_END) - break; - } - buf.iter = iter; - return buf; -} - -struct token token_buffer_next(struct token_buffer *buf) { - struct token out = buf->tokens[0]; - for (int i = 0; i < 3; i++) - buf->tokens[i] = buf->tokens[i + 1]; - buf->tokens[3] = token_iter_next(buf->iter); - return out; -} + -struct token *token_buffer_peek(struct token_buffer *buf, int off) { - if (off < 4) - return &buf->tokens[off]; - fprintf(stderr, "peek too far\n"); - exit(3); -} - -int peek_type_size(struct token_buffer *buf) { - struct token *a = token_buffer_peek(buf, 0); - if (a->kind == TOK_KEYWORD && - (a->data.keyword == KW_STRUCT || a->data.keyword == KW_ENUM || - a->data.keyword == KW_UNION)) { - struct token *b = token_buffer_peek(buf, 1); - if (b->kind == TOK_IDENTIFIER) { - return 2; + value += 1; + } else if (a->kind == TOK_SEPERATOR && a->data.seperator == SEP_RCURLY) { + if (token_step(iter, a)) + return 1; + return 0; } else { - return -1; - } - } else if (a->kind == TOK_IDENTIFIER) { - return 1; - } else { - return -1; - } -} - -void toplevel(struct token_buffer *buf) { - int ts = peek_type_size(buf); - if (ts >= 0) { - struct token *a = token_buffer_peek(buf, ts); - struct token *b = token_buffer_peek(buf, ts + 1); - if (a->kind == TOK_SEPERATOR && a->data.seperator == SEP_LCURLY) { - printf("type\n"); - // likely type definition - } else if (a->kind == TOK_IDENTIFIER && b->kind == TOK_SEPERATOR && - b->data.seperator == SEP_LPAREN) { - printf("function\n"); - // likely function - } else if (a->kind == TOK_IDENTIFIER && b->kind == TOK_OPERATOR && - b->data.operator== OP_ASSIGN) { - printf("global\n"); - // likely global variable + fprintf(stderr, "expected enum ident or rcurly\n"); + return 1; } } } -int token_step(struct token_iter *iter, struct token *a) { - token_free(*a); - *a = token_iter_next(iter); - return a->kind == TOK_END || a->kind == TOK_ERROR; -} - -void toplevel2(struct token_iter *iter) { +int toplevel(struct token_iter *iter) { struct token a = token_iter_next(iter); if (a.kind == TOK_KEYWORD) { switch (a.data.keyword) { case KW_ENUM: - a = token_iter_next(iter); + if (token_step(iter, &a)) + return 1; if (a.kind == TOK_IDENTIFIER) { char *type_name = strdup(a.data.identifier); if (token_step(iter, &a)) - return; + return 1; + } + if (a.kind == TOK_SEPERATOR && a.data.seperator == SEP_LCURLY) { + if (token_step(iter, &a)) + return 1; + if (enum_decl(iter, &a)) + return 1; } break; default: printf("unhandled keyword: "); token_print(a); - exit(1); + return 1; } } + return 0; } #ifdef TEST @@ -1120,19 +802,19 @@ int main(int argc, char **argv) { iter = token_iter_new(source); // buf = token_buffer_new(&iter); // toplevel(&buf); - // toplevel2(&iter); + toplevel(&iter); - while (1) { - tok = token_iter_next(&iter); -#ifdef DEBUG - token_print(tok); -#endif + // while (1) { + // tok = token_iter_next(&iter); + // #ifdef DEBUG + // token_print(tok); + // #endif - if (tok.kind == TOK_END) - break; + // if (tok.kind == TOK_END) + // break; - token_free(tok); - }; + // token_free(tok); + // }; return 0; } -- cgit v1.2.3-70-g09d2