diff options
-rw-r--r-- | attocc.c | 169 |
1 files changed, 130 insertions, 39 deletions
@@ -20,6 +20,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#define DEBUG const int NUM_KEYWORDS = 32; static char *KEYWORDS[] = { @@ -249,13 +250,18 @@ char map_escape(char c) { } } +void *realloc_failsafe(void *old, unsigned long size) { + void *p = realloc(old, size); + if (!p) { + fprintf(stderr, "malloc failed\n"); + exit(2); + } + return p; +} + struct token *token_push(struct token **tokens, unsigned long *num_tokens) { *num_tokens += 1; - *tokens = realloc(*tokens, sizeof(struct token) * *num_tokens); - if (!tokens) { - fprintf(stderr, "realloc failed\n"); - return NULL; - } + *tokens = realloc_failsafe(*tokens, sizeof(struct token) * *num_tokens); return &(*tokens)[*num_tokens - 1]; } @@ -392,11 +398,7 @@ struct token *tokenize(char *source) { for (char c; (c = *p++) && c != '"';) { // TODO escape str_len++; - str = realloc(str, str_len); - if (!str) { - fprintf(stderr, "realloc failed\n"); - return NULL; - } + str = realloc_failsafe(str, str_len); str[str_len - 1] = c; } @@ -439,11 +441,7 @@ struct token *tokenize(char *source) { for (char c; (c = *p++) && is_ident(c);) ; int ident_len = p - ident_start - 1; - char *ident_str = malloc(ident_len + 1); - if (!ident_str) { - fprintf(stderr, "malloc failed\n"); - return NULL; - } + char *ident_str = realloc_failsafe(NULL, ident_len + 1); for (int i = 0; i < ident_len; i++) ident_str[i] = ident_start[i]; ident_str[ident_len] = '\0'; @@ -534,55 +532,137 @@ void debug_tokens(struct token *tokens) { } #endif -enum node_kind { - NO_BINOP, - NO_UNOP, - NO_MEMBER_ACCESS, - NO_STRUCT, - NO_UNION, - NO_ENUM, - NO_FUNCTION +struct node { + enum node_kind { + NO_BINOP, + NO_UNOP, + NO_MEMBER_ACCESS, + NO_STRUCT, + NO_UNION, + NO_ENUM, + NO_FUNCTION, + } kind; + union node_data { + struct { + struct node *lhs; + struct node *rhs; + } binop; + struct { + char *name; + char is_decl; + unsigned long num_members; + struct enum_member { + int value; + char *name; + } *members; + } enum_; + } data; }; -union node_data { - struct { - struct expr *lhs; - struct expr *rhs; - } binop; -}; +char parse_enum_decl(struct token *tokens, struct node **node); -struct node { - enum node_kind kind; - union node_data data; -}; +char parse_type(struct token *tokens, struct node **node) { + if (parse_enum_decl(tokens, node)) + return 1; + if (*node) + return 0; + + return 0; +} char parse_enum_decl(struct token *tokens, struct node **node) { int p = 0; + printf("1\n"); + if (tokens[p].kind != TOK_KEYWORD || tokens[p].data.keyword != KW_ENUM) - return 1; + return 0; p++; + printf("2\n"); + char *ident = NULL; if (tokens[p].kind == TOK_IDENTIFIER) { ident = tokens[p].data.identifier; p++; } + printf("3\n"); - if (tokens[p].kind != TOK_SEPERATOR || tokens[p].data.seperator != SEP_LCURLY) - return 1; - p++; + char is_decl = 0; + if (tokens[p].kind == TOK_SEPERATOR && + tokens[p].data.seperator != SEP_LCURLY) { + p++; + is_decl = 1; + printf("4\n"); + + struct enum_member *members; + unsigned long num_members; + int value = 0; + + if (tokens[p].kind != TOK_IDENTIFIER) + return 0; + char *m_ident = tokens[p].data.identifier; + p++; + + if (tokens[p].kind == TOK_OPERATOR && tokens[p].data.operator== OP_ASSIGN) { + p++; + } + if (tokens[p].kind != TOK_SEPERATOR || tokens[p].data.operator== SEP_COMMA) + return 1; + + num_members++; + members = realloc_failsafe(NULL, sizeof(struct enum_member) * num_members); + struct enum_member *new_member = &members[num_members - 1]; + new_member->value = value++; + new_member->name = strdup(m_ident); + } *node = malloc(sizeof(struct node)); if (!*node) { fprintf(stderr, "malloc failed\n"); return 1; } - // (**node).data.; + (**node).data.enum_.is_decl = is_decl; + (**node).data.enum_.name = strdup(ident); return 0; } -struct decl *parse(struct token *tokens) { return NULL; } +char parse(struct token *tokens, struct node **node) { + return parse_type(tokens, node); +} + +#ifdef DEBUG +void debug_node(struct node *node) { + switch (node->kind) { + case NO_ENUM: + printf("NO_ENUM\n"); + // printf(" name=%s\n", node->data.enum_.name); + // printf(" is_decl=%i\n", node->data.enum_.is_decl); + // printf(" num_members=%li\n", node->data.enum_.num_members); + break; + case NO_BINOP: + printf("NO_BINOP\n"); + // printf(" lhs: "); + // debug_node(node->data.binop.lhs); + // printf("\n"); + // printf(" rhs: "); + // debug_node(node->data.binop.rhs); + // printf("\n"); + case NO_MEMBER_ACCESS: + printf("NO_MEMBER_ACCESS\n"); + case NO_FUNCTION: + printf("NO_FUNCTION\n"); + case NO_STRUCT: + printf("NO_STRUCT\n"); + case NO_UNION: + printf("NO_UNION\n"); + case NO_UNOP: + printf("NO_UNOP\n"); + default: + break; + } +} +#endif int main(int argc, char **argv) { if (argc < 3) { @@ -635,6 +715,17 @@ int main(int argc, char **argv) { debug_tokens(tokens); #endif + struct node *nodes = NULL; + if (parse(tokens, &nodes)) { + printf("parse failed\n"); + return 1; + } + printf("Hello %p\n", nodes); + +#ifdef DEBUG + debug_node(nodes); +#endif + free_tokens(tokens); return 0; |