-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Linked list for tokens and boilerplate for parser v2
full list of changes: - separate debug print functions into debug.c - make the lexer output a linked list of tokens instead of an array - create necessary types for parser - set up some AST boilerplate - manually create and free an AST with a single statement to ensure no mem leaks - gitignore vgcore files
- Loading branch information
Showing
8 changed files
with
356 additions
and
175 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,3 +2,4 @@ build | |
result | ||
experiments | ||
old | ||
vgcore.* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
#include <stdio.h> | ||
|
||
#include "debug.h" | ||
#include "lexer.h" | ||
|
||
char *stringify_token_type(TokenType token_type) { | ||
switch (token_type) { | ||
case TOKEN_LET: return "LET"; | ||
case TOKEN_NAME: return "NAME"; | ||
case TOKEN_ASSIGN: return "ASSIGN"; | ||
case TOKEN_INT: return "INT"; | ||
case TOKEN_NEGATE: return "NEGATE"; | ||
case TOKEN_BINARY_OP: return "BINARY_OP"; | ||
case TOKEN_UNARY_OP: return "UNARY_OP"; | ||
case TOKEN_OPEN_PAREN: return "OPEN_PAREN"; | ||
case TOKEN_CLOSE_PAREN: return "CLOSE_PAREN"; | ||
case TOKEN_PRINT: return "PRINT"; | ||
case TOKEN_STRING: return "STRING"; | ||
case TOKEN_COMMA: return "COMMA"; | ||
case TOKEN_END_STATEMENT: return "END_STATEMENT"; | ||
case TOKEN_EOF: return "EOF"; | ||
case TOKEN_INVALID: return "INVALID"; | ||
} | ||
} | ||
|
||
void print_token(Token token) { | ||
printf("%s ", stringify_token_type(token.type)); | ||
if (token.literal != NULL) | ||
printf("\"%s\" ", token.literal); | ||
printf("at %zu:%zu", token.line, token.column); | ||
} | ||
|
||
// prints in reverse order because i'm lazy | ||
void print_token_linked_list(Token *tokens) { | ||
if (tokens == NULL) { | ||
printf("[]\n"); | ||
return; | ||
} | ||
|
||
printf("[\n"); | ||
|
||
Token *current = tokens; | ||
while (current != NULL) { | ||
printf(" "); | ||
print_token(*current); | ||
if (current->next != NULL) | ||
printf(",\n"); | ||
current = current->next; | ||
} | ||
|
||
printf("\n]\n"); | ||
} | ||
|
||
void print_lexer_errors(LexerErrorList errors) { | ||
if (errors.length == 0) { | ||
printf("[]\n"); | ||
return; | ||
} | ||
|
||
printf("[\n"); | ||
|
||
for (size_t i = 0; i < errors.length; i++) { | ||
LexerError err = errors.errors[i]; | ||
printf( | ||
" %s (erroneous token starts at: %zu:%zu, error at %zu:%zu)", | ||
err.message, | ||
err.line, | ||
err.start_column, | ||
err.line, | ||
err.error_column | ||
); | ||
if (i < errors.length - 1) printf(",\n"); | ||
} | ||
|
||
printf("\n]\n"); | ||
} | ||
|
||
void print_expr(Expr expr) { | ||
switch (expr.type) { | ||
case EXPR_INT: printf("(INT %s)", expr.expr.int_literal); break; | ||
case EXPR_VAR: printf("(VAR %c)", expr.expr.variable); break; | ||
case EXPR_FUNC: | ||
printf("(FUNC %s ", expr.expr.func.name); | ||
print_expr_list(expr.expr.func.args); | ||
} | ||
} | ||
|
||
void print_expr_list(ExprList *exprs) { | ||
if (exprs->length == 0) { | ||
printf("[]"); | ||
return; | ||
} | ||
|
||
printf("["); | ||
|
||
for (size_t i = 0; i < exprs->length; i++) { | ||
print_expr(exprs->exprs[i]); | ||
if (i < exprs->length - 1) printf(", "); | ||
} | ||
|
||
printf("]"); | ||
} | ||
|
||
void print_ast(AST ast) { | ||
if (ast.length == 0) { | ||
printf("[]\n"); | ||
return; | ||
} | ||
|
||
printf("[\n"); | ||
|
||
for (size_t i = 0; i < ast.length; i++) { | ||
printf(" "); | ||
Statement s = ast.statements[i]; | ||
switch (s.type) { | ||
case STATEMENT_ASSIGNMENT: | ||
printf("ASSIGNMENT %c = ", s.statement.assignment.variable); | ||
print_expr(s.statement.assignment.expr); | ||
break; | ||
case STATEMENT_PRINT: | ||
printf("PRINT "); | ||
print_expr_list(s.statement.print); | ||
} | ||
} | ||
|
||
printf("\n]\n"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#ifndef INCLUDE_DEBUG_H | ||
#define INCLUDE_DEBUG_H | ||
|
||
#include "lexer.h" | ||
#include "parser.h" | ||
|
||
extern char *stringify_token_type(TokenType token_type); | ||
extern void print_token(Token token); | ||
extern void print_token_linked_list(Token *tokens); | ||
|
||
extern void print_lexer_errors(LexerErrorList errors); | ||
|
||
extern void print_expr(Expr expr); | ||
extern void print_expr_list(ExprList *exprs); | ||
extern void print_ast(AST ast); | ||
|
||
#endif // INCLUDE_DEBUG_H |
Oops, something went wrong.