diff options
| -rw-r--r-- | cup/ast.c | 9 | ||||
| -rw-r--r-- | cup/ast.h | 3 | ||||
| -rw-r--r-- | cup/lexer.c | 4 | ||||
| -rw-r--r-- | cup/main.c | 8 | ||||
| -rw-r--r-- | cup/parser.c | 29 | ||||
| -rw-r--r-- | cup/tokens.h | 5 |
6 files changed, 50 insertions, 8 deletions
@@ -59,6 +59,15 @@ static void do_print_ast(Node *node, int depth) } else if (node->type == AST_RETURN) { printf("return\n"); do_print_ast(node->unary_expr, depth + 1); + } else if (node->type == OP_NEG) { + printf("-\n"); + do_print_ast(node->unary_expr, depth + 1); + } else if (node->type == OP_NOT) { + printf("!\n"); + do_print_ast(node->unary_expr, depth + 1); + } else if (node->type == OP_BWINV) { + printf("~\n"); + do_print_ast(node->unary_expr, depth + 1); } else { printf("(unknown)\n"); } @@ -3,6 +3,9 @@ #include <stdbool.h> #define ENUM_AST_TYPES(F) \ + F(OP_NEG, "neg") \ + F(OP_NOT, "!") \ + F(OP_BWINV, "~") \ F(OP_PLUS, "+") \ F(OP_MINUS, "-") \ F(OP_MUL, "*") \ diff --git a/cup/lexer.c b/cup/lexer.c index 9f9af90..d03ea78 100644 --- a/cup/lexer.c +++ b/cup/lexer.c @@ -93,6 +93,8 @@ Token Lexer_next(Lexer *lexer) case ';': return Lexer_make_token(lexer, TOKEN_SEMICOLON, 1); case ':': return Lexer_make_token(lexer, TOKEN_COLON, 1); case '&': return Lexer_make_token(lexer, TOKEN_AMPERSAND, 1); + case '~': return Lexer_make_token(lexer, TOKEN_TILDE, 1); + case '!': return Lexer_make_token(lexer, TOKEN_EXCLAMATION, 1); case '<': { if (peek(lexer, 1) == '=') @@ -176,7 +178,7 @@ Token Lexer_next(Lexer *lexer) } - printf("Shouldn't have gotten here... char is '%c'\n", lexer->src[lexer->pos]); + die_location(Lexer_loc(lexer), ": ERROR: Unexpected character '%c'\n", lexer->src[lexer->pos]); advance(lexer, 1); } } @@ -3,6 +3,7 @@ #include <string.h> #include "lexer.h" #include "parser.h" +#include "generator.h" #include "unistd.h" int main(int argc, char**argv) { @@ -21,7 +22,12 @@ int main(int argc, char**argv) { // Lexer Lexer lexer = Lexer_new(filename, source, fsize); Node *ast = parse_program(&lexer); - print_ast(ast); + + print_ast(ast); + + FILE *f = fopen("output.nasm", "w"); + generate_asm(ast, f); + // Token token; // while ( (token = Lexer_next(&lexer)).type != TOKEN_EOF) { // Token_print(stdout, &token); diff --git a/cup/parser.c b/cup/parser.c index 0d0ce46..746a139 100644 --- a/cup/parser.c +++ b/cup/parser.c @@ -50,17 +50,38 @@ Type parse_type(Lexer *lexer) return type; } -Node *parse_expression(Lexer *lexer) +Node *parse_literal(Lexer *lexer) { - // TODO: Parse more complicated things - Token token; Node *node = Node_new(AST_LITERAL); - token = assert_token(Lexer_next(lexer), TOKEN_INTLIT); + Token token = assert_token(Lexer_next(lexer), TOKEN_INTLIT); node->literal.type = (Type) {.type = TYPE_INT}; node->literal.as_int = token.value.as_int; return node; } +Node *parse_expression(Lexer *lexer) +{ + // TODO: Parse more complicated things + Token token = Lexer_peek(lexer); + Node *expr; + if (token.type == TOKEN_MINUS) { + Lexer_next(lexer); + expr = Node_new(OP_NEG); + expr->unary_expr = parse_expression(lexer); + } else if (token.type == TOKEN_TILDE) { + Lexer_next(lexer); + expr = Node_new(OP_BWINV); + expr->unary_expr = parse_expression(lexer); + } else if (token.type == TOKEN_EXCLAMATION) { + Lexer_next(lexer); + expr = Node_new(OP_NOT); + expr->unary_expr = parse_expression(lexer); + } else { + return parse_literal(lexer); + } + return expr; +} + Node *parse_statement(Lexer *lexer) { Node *node; diff --git a/cup/tokens.h b/cup/tokens.h index 56ad40c..d8b5070 100644 --- a/cup/tokens.h +++ b/cup/tokens.h @@ -16,6 +16,7 @@ typedef int64_t i64; F(TOKEN_COLON, ":") \ F(TOKEN_EOF, "EOF") \ F(TOKEN_EQ, "==") \ + F(TOKEN_EXCLAMATION, "!") \ F(TOKEN_FN, "fn") \ F(TOKEN_GEQ, ">=") \ F(TOKEN_GT, ">") \ @@ -43,6 +44,7 @@ typedef int64_t i64; F(TOKEN_SLASH, "/") \ F(TOKEN_STAR, "*") \ F(TOKEN_STRINGLIT, "string literal") \ + F(TOKEN_TILDE, "~") \ F(TOKEN_XOR, "^") typedef enum { @@ -53,8 +55,7 @@ typedef enum { typedef struct { char *filename; - int line; - int col; + int line, col; } Location; void Location_print(FILE *f, Location loc); |