summaryrefslogtreecommitdiff
path: root/attocc.c
diff options
context:
space:
mode:
Diffstat (limited to 'attocc.c')
-rw-r--r--attocc.c141
1 files changed, 78 insertions, 63 deletions
diff --git a/attocc.c b/attocc.c
index 1015747..298b24c 100644
--- a/attocc.c
+++ b/attocc.c
@@ -584,8 +584,23 @@ struct node {
NO_UNION,
NO_ENUM,
NO_FUNCTION,
+ NO_COMPOUND,
} kind;
union node_data {
+ struct node_data_function {
+ struct node *return_type;
+ char *name;
+ int num_arguments;
+ struct function_argument {
+ char *name;
+ struct node *type;
+ } *arguments;
+ struct node *body;
+ } function;
+ struct node_data_compound {
+ int num_statements;
+ struct node **statements;
+ } compount;
struct node_data_binop {
struct node *lhs;
struct node *rhs;
@@ -602,78 +617,82 @@ struct node {
} data;
};
-char parse_enum_decl(struct token *tokens, struct node **node);
+struct node *parse_enum_decl(int *p, struct token *tokens);
-char parse_type(struct token *tokens, struct node **node) {
- if (parse_enum_decl(tokens, node))
- return 1;
- if (*node)
- return 0;
+struct node *parse_type(int *p, struct token *tokens) {
+ struct node *out;
+ out = parse_enum_decl(p, tokens);
+ if (out)
+ return out;
- return 0;
+ return NULL;
}
-char parse_enum_decl(struct token *tokens, struct node **node) {
- int p = 0;
- printf("1\n");
+struct node *parse_function(int *p, struct token *tokens) {
+ struct node *return_type = parse_type(p, tokens);
+ if (!return_type)
+ return NULL;
- if (tokens[p].kind != TOK_KEYWORD || tokens[p].data.keyword != KW_ENUM)
- return 0;
- p++;
+ struct node *node = realloc_failsafe(NULL, sizeof(struct node));
+ node->kind = NO_FUNCTION;
+ node->data.function.return_type = return_type;
+ return node;
+}
- printf("2\n");
+struct node *parse_enum_decl(int *p, struct token *tokens) {
+ if (tokens[*p].kind != TOK_KEYWORD || tokens[*p].data.keyword != KW_ENUM)
+ return 0;
+ *p += 1;
char *ident = NULL;
- if (tokens[p].kind == TOK_IDENTIFIER) {
- ident = tokens[p].data.identifier;
- p++;
+ if (tokens[*p].kind == TOK_IDENTIFIER) {
+ ident = tokens[*p].data.identifier;
+ *p += 1;
}
- printf("3 %i %i\n", tokens[p].kind, tokens[p].data.seperator);
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++;
+ if (tokens[*p].kind == TOK_SEPERATOR &&
+ tokens[*p].data.seperator == SEP_LCURLY) {
+ *p += 1;
is_decl = 1;
- printf("4\n");
int value = 0;
while (1) {
- if (tokens[p].kind == TOK_SEPERATOR &&
- tokens[p].data.seperator == SEP_RCURLY)
+ if (tokens[*p].kind == TOK_SEPERATOR &&
+ tokens[*p].data.seperator == SEP_RCURLY)
break;
- if (tokens[p].kind == TOK_END)
- return 1;
+ if (tokens[*p].kind == TOK_END)
+ return NULL;
- if (tokens[p].kind == TOK_SEPERATOR &&
- tokens[p].data.seperator == SEP_COMMA) {
- p++;
+ if (tokens[*p].kind == TOK_SEPERATOR &&
+ tokens[*p].data.seperator == SEP_COMMA) {
+ *p += 1;
continue;
}
- if (tokens[p].kind != TOK_IDENTIFIER)
- return 1;
+ if (tokens[*p].kind != TOK_IDENTIFIER)
+ return NULL;
- char *m_ident = tokens[p].data.identifier;
+ char *m_ident = tokens[*p].data.identifier;
- if (tokens[p].kind == TOK_OPERATOR &&
- tokens[p].data.operator== OP_ASSIGN) {
- p++;
+ if (tokens[*p].kind == TOK_OPERATOR &&
+ tokens[*p].data.operator== OP_ASSIGN) {
+ *p += 1;
- if (tokens[p].kind == TOK_END)
- return 1;
+ if (tokens[*p].kind == TOK_END)
+ return NULL;
- if (tokens[p].kind != TOK_CONSTANT ||
- tokens[p].data.constant_kind != CONST_INT)
- return 1;
+ if (tokens[*p].kind != TOK_CONSTANT ||
+ tokens[*p].data.constant_kind != CONST_INT)
+ return NULL;
- value = tokens[p].data.constant_int_value;
- p++;
+ value = tokens[*p].data.constant_int_value;
+ *p += 1;
}
num_members++;
@@ -683,28 +702,27 @@ char parse_enum_decl(struct token *tokens, struct node **node) {
new_member->value = value++;
new_member->name = strdup_failsafe(m_ident);
- p++;
+ *p += 1;
}
- } else if (tokens[p].kind == TOK_SEPERATOR &&
- tokens[p].data.seperator == SEP_SEMICOLON) {
+ } else if (tokens[*p].kind == TOK_SEPERATOR &&
+ tokens[*p].data.seperator == SEP_SEMICOLON) {
} else {
printf("expected members or semicolon\n");
- return 1;
+ return NULL;
}
- *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 0;
+ 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;
}
-char parse(struct token *tokens, struct node **node) {
- return parse_type(tokens, node);
+struct node *parse(int *p, struct token *tokens) {
+ return parse_type(p, tokens);
}
#ifdef DEBUG
@@ -837,18 +855,15 @@ int main(int argc, char **argv) {
#endif
printf("parse\n");
- struct node *nodes = NULL;
- if (parse(tokens, &nodes)) {
+ int p = 0;
+ struct node *node = parse(&p, tokens);
+ if (!node) {
printf("parse failed\n");
return 1;
}
- if (!nodes) {
- printf("parse failed");
- return 1;
- }
#ifdef DEBUG
- debug_node(nodes);
+ debug_node(node);
#endif
free_tokens(tokens);