aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMustafa Quraish <[email protected]>2022-01-30 02:20:58 -0500
committerMustafa Quraish <[email protected]>2022-01-30 18:04:13 -0500
commitb08bb0a17ed05e7febaee5c71f5cf1ff3447dea1 (patch)
treed10d6f869509b7c9d4650f4aa18850fdaec97904
parentUpdate build system to use Makefile (diff)
downloadcup-b08bb0a17ed05e7febaee5c71f5cf1ff3447dea1.tar.xz
cup-b08bb0a17ed05e7febaee5c71f5cf1ff3447dea1.zip
Put tokens in their own macro to allow looping over them
-rw-r--r--src/lexer.c19
-rw-r--r--src/main.c14
-rw-r--r--src/tokens.c7
-rw-r--r--src/tokens.h26
4 files changed, 36 insertions, 30 deletions
diff --git a/src/lexer.c b/src/lexer.c
index ea095ba..699e960 100644
--- a/src/lexer.c
+++ b/src/lexer.c
@@ -79,9 +79,6 @@ static Token Lexer_make_token(Lexer *lexer, TokenType type, int inc_amount)
return token;
}
-#define LEX_KEYWORD(str, token_type) \
- if (Lexer_starts_with(lexer, str)) return Lexer_make_token(lexer, token_type, strlen(str));
-
Token Lexer_next(Lexer *lexer)
{
while (lexer->pos < lexer->len) {
@@ -98,6 +95,8 @@ Token Lexer_next(Lexer *lexer)
case '~': return Lexer_make_token(lexer, TOKEN_TILDE, 1);
case '?': return Lexer_make_token(lexer, TOKEN_QUESTION, 1);
case ',': return Lexer_make_token(lexer, TOKEN_COMMA, 1);
+ case '*': return Lexer_make_token(lexer, TOKEN_STAR, 1);
+ case '%': return Lexer_make_token(lexer, TOKEN_PERCENT, 1);
case '&': {
if (peek(lexer, 1) == '&')
@@ -162,20 +161,12 @@ Token Lexer_next(Lexer *lexer)
return Lexer_make_token(lexer, TOKEN_SLASH, 1);
}
- case '*': return Lexer_make_token(lexer, TOKEN_STAR, 1);
- case '%': return Lexer_make_token(lexer, TOKEN_PERCENT, 1);
-
default: {
// Handle keywords explicitly
- LEX_KEYWORD("fn", TOKEN_FN);
- LEX_KEYWORD("if", TOKEN_IF);
- LEX_KEYWORD("int", TOKEN_INT);
- LEX_KEYWORD("let", TOKEN_LET);
- LEX_KEYWORD("for", TOKEN_FOR);
- LEX_KEYWORD("else", TOKEN_ELSE);
- LEX_KEYWORD("while", TOKEN_WHILE);
- LEX_KEYWORD("return", TOKEN_RETURN);
+ #define LEX_KEYWORD(token_type, str) if (Lexer_starts_with(lexer, str)) return Lexer_make_token(lexer, token_type, strlen(str));
+ ENUM_KEYWORDS(LEX_KEYWORD)
+ #undef LEX_KEYWORD
if (isdigit(lexer->src[lexer->pos])) {
// TODO: Parse hex and octal numbers
diff --git a/src/main.c b/src/main.c
index 15460ff..c94f8d3 100644
--- a/src/main.c
+++ b/src/main.c
@@ -5,12 +5,15 @@
#include "parser.h"
#include "generator.h"
#include "unistd.h"
+#include <errno.h>
char *filename = NULL;
char *source = NULL;
i64 source_len = 0;
bool dump_ast = false;
+char *output_file = "build/output.nasm";
+
#define MAX_STDIN_SOURCE_LEN 2048
void usage(int exit_status)
@@ -19,6 +22,7 @@ void usage(int exit_status)
printf("Options:\n");
printf(" -c <code> Code to compile\n");
printf(" -h Show this help\n");
+ printf(" -o <file> Output file\n");
printf(" -d Dump AST to stdout\n");
printf("Output file will be named `output.nasm`\n");
exit(exit_status);
@@ -37,6 +41,9 @@ void parse_args(int argc, char **argv)
usage(0);
} else if (strcmp(argv[i], "-d") == 0) {
dump_ast = true;
+ } else if (strcmp(argv[i], "-o") == 0) {
+ i++;
+ output_file = argv[i];
} else if (filename == NULL) {
if (strcmp(argv[i], "-") == 0) {
filename = "stdin";
@@ -73,10 +80,13 @@ int main(int argc, char**argv) {
if (dump_ast)
print_ast(ast);
- FILE *f = fopen("output.nasm", "w");
+ FILE *f = fopen(output_file, "w");
+ if (f == NULL) {
+ fprintf(stderr, "Could not open output file: %s\n", strerror(errno));
+ exit(1);
+ }
generate_asm(ast, f);
-
free(source);
return 0;
}
diff --git a/src/tokens.c b/src/tokens.c
index e562e16..2d99f71 100644
--- a/src/tokens.c
+++ b/src/tokens.c
@@ -47,9 +47,10 @@ char *token_type_to_str(TokenType type)
// Otherwise, just print the token type
switch (type)
{
- #define ENUM_TOKEN(name, str) case name: return str;
- ENUM_TOKENS(ENUM_TOKEN)
- #undef ENUM_TOKEN
+ #define HANDLE_ITEM(name, str) case name: return str;
+ ENUM_TOKENS(HANDLE_ITEM)
+ ENUM_KEYWORDS(HANDLE_ITEM)
+ #undef HANDLE_ITEM
default: assert(false && "Unreachable");
}
}
diff --git a/src/tokens.h b/src/tokens.h
index 44f5e6e..3917f0f 100644
--- a/src/tokens.h
+++ b/src/tokens.h
@@ -12,21 +12,15 @@
F(TOKEN_CLOSE_PAREN, ")") \
F(TOKEN_COLON, ":") \
F(TOKEN_COMMA, ",") \
- F(TOKEN_ELSE, "else") \
F(TOKEN_EOF, "EOF") \
F(TOKEN_EQ, "==") \
F(TOKEN_EXCLAMATION, "!") \
- F(TOKEN_FN, "fn") \
- F(TOKEN_FOR, "for") \
F(TOKEN_GEQ, ">=") \
F(TOKEN_GT, ">") \
F(TOKEN_IDENTIFIER, "identifier") \
- F(TOKEN_IF, "if") \
- F(TOKEN_INT, "int") \
F(TOKEN_INTLIT, "integer literal") \
F(TOKEN_LEQ, "<=") \
F(TOKEN_LSHIFT, "<<") \
- F(TOKEN_LET, "let") \
F(TOKEN_LT, "<") \
F(TOKEN_MINUS, "-") \
F(TOKEN_MINUSEQUALS, "-=") \
@@ -40,20 +34,30 @@
F(TOKEN_PLUSEQUALS, "+=") \
F(TOKEN_PLUSPLUS, "++") \
F(TOKEN_QUESTION, "?") \
- F(TOKEN_RETURN, "return") \
F(TOKEN_RSHIFT, ">>") \
F(TOKEN_SEMICOLON, ";") \
F(TOKEN_SLASH, "/") \
F(TOKEN_STAR, "*") \
F(TOKEN_STRINGLIT, "string literal") \
F(TOKEN_TILDE, "~") \
- F(TOKEN_WHILE, "while") \
F(TOKEN_XOR, "^")
+#define ENUM_KEYWORDS(F) \
+ F(TOKEN_ELSE, "else") \
+ F(TOKEN_FN, "fn") \
+ F(TOKEN_FOR, "for") \
+ F(TOKEN_IF, "if") \
+ F(TOKEN_INT, "int") \
+ F(TOKEN_LET, "let") \
+ F(TOKEN_RETURN, "return") \
+ F(TOKEN_WHILE, "while") \
+
+
typedef enum {
-#define ENUM_TOKEN(name, str) name,
- ENUM_TOKENS(ENUM_TOKEN)
-#undef ENUM_TOKEN
+#define HANDLE_ITEM(name, str) name,
+ ENUM_TOKENS(HANDLE_ITEM)
+ ENUM_KEYWORDS(HANDLE_ITEM)
+#undef HANDLE_ITEM
} TokenType;
typedef struct {