summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--attocc.c169
1 files changed, 130 insertions, 39 deletions
diff --git a/attocc.c b/attocc.c
index 5c92ac7..545b93a 100644
--- a/attocc.c
+++ b/attocc.c
@@ -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;