diff options
author | metamuffin <metamuffin@disroot.org> | 2024-06-14 22:14:31 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-06-14 22:14:31 +0200 |
commit | 8a2d1b4928150c361413f4b294e016ee5011a017 (patch) | |
tree | 76e1e98f8336f83550592a25e96377df0f0ef044 | |
download | attocc-8a2d1b4928150c361413f4b294e016ee5011a017.tar attocc-8a2d1b4928150c361413f4b294e016ee5011a017.tar.bz2 attocc-8a2d1b4928150c361413f4b294e016ee5011a017.tar.zst |
a
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | attocc.c | 134 |
2 files changed, 135 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5cc1205 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/attocc diff --git a/attocc.c b/attocc.c new file mode 100644 index 0000000..c18156c --- /dev/null +++ b/attocc.c @@ -0,0 +1,134 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define NUM_KEYWORDS 32 +static char *KEYWORDS[NUM_KEYWORDS] = { + "auto", "break", "case", "char", "const", "continue", + "default", "do", "double", "else", "enum", "extern", + "float", "for", "goto", "if", "int", "long", + "register", "return", "short", "signed", "sizeof", "static", + "struct", "switch", "typedef", "union", "unsigned", "void", + "volatile", "while"}; + +enum keyword { + kW_AUTO, + KW_BREAK, + KW_CASE, + KW_CHAR, + KW_CONST, + KW_CONTINUE, + KW_DEFAULT, + KW_DO, + KW_DOUBLE, + KW_ELSE, + KW_ENUM, + KW_EXTERN, + KW_FLOAT, + KW_FOR, + KW_GOTO, + KW_IF, + KW_INT, + KW_LONG, + KW_REGISTER, + KW_RETURN, + KW_SHORT, + KW_SIGNED, + KW_SIZEOF, + KW_STATIC, + KW_STRUCT, + KW_SWITCH, + KW_TYPEDEF, + KW_UNION, + KW_UNSIGNED, + KW_VOID, + KW_VOLATILE, + KW_WHILE, +}; +enum operator{ + OP_ADD, + OP_SUB, + OP_MUL, + OP_DIV, + OP_MOD, +}; +enum token_kind { + IDENTIFIER, + KEYWORD, + CONSTANT, + OPERATOR, + END, +}; +union token_data { + char *identifier; + enum keyword keyword; + int constant_value; + enum operator operator; +}; +struct token { + enum token_kind kind; + union token_data data; +}; + +struct token *tokenize(char *source) { + char *end = source + strlen(source); + char *p = source; + int num_tokens = 0; + struct token *tokens; + while (*p) { + int remaining = end - p; + + //* comments + if (remaining >= 2) { + if (p[0] == '/' && p[1] == '/') { + p += 2; + while (*p) { + if (*p++ == '\n') { + break; + } + } + continue; + } else if (p[0] == '/' && p[1] == '*') { + p += 2; + char last = '\0'; + while (*p) { + if (*p == '/' && last == '*') { + p++; + break; + } + last = *p; + p++; + } + continue; + } + } + + //* keyword + for (int i = 0; i < NUM_KEYWORDS; i++) { + char *kw = KEYWORDS[i]; + if (remaining >= strlen(kw)) { + if (strcmp(kw, p) == 0) { + num_tokens += 1; + + tokens = realloc(tokens, sizeof(struct token) * num_tokens); + if (!tokens) { + fprintf(stderr, "realloc failed"); + return NULL; + } + struct token *new_token = &tokens[num_tokens - 1]; + new_token->kind = KEYWORD; + new_token->data.keyword = i; + + p += strlen(kw); + continue; + } + } + } + + fprintf(stderr, "unknown token\n"); + return NULL; + } + return tokens; +} + +int main() {} |