summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--attocc.c468
1 files changed, 75 insertions, 393 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 (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;
+ 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;
}
-
- 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;
}