From 3139398d475830f976895d27e772d4e926490881 Mon Sep 17 00:00:00 2001 From: c Date: Tue, 5 Dec 2023 12:41:05 -0500 Subject: Made AST output look fancy. --- src/lexer.c | 6 +++++ src/parser.c | 52 +++++++++++------------------------- src/token.c | 7 ++--- src/tree.c | 87 ++++++++++++++++++++++++++++++++++-------------------------- 4 files changed, 74 insertions(+), 78 deletions(-) diff --git a/src/lexer.c b/src/lexer.c index 41d5fc4..e6a083b 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -82,6 +82,12 @@ void lexer_do_reg(lexer_t* lexer) { case SYNTAX_RGROUP: lexer_add_current_char(lexer, TOKEN_RGROUP); break; + case SYNTAX_LBLOCK: + lexer_add_current_char(lexer, TOKEN_LBLOCK); + break; + case SYNTAX_RBLOCK: + lexer_add_current_char(lexer, TOKEN_RBLOCK); + break; case SYNTAX_EXPR_END: lexer_add_current_char(lexer, TOKEN_EXPR_END); break; diff --git a/src/parser.c b/src/parser.c index 06c72d4..7b9dbaa 100644 --- a/src/parser.c +++ b/src/parser.c @@ -73,6 +73,11 @@ tree_t* parser_parse_expr(parser_t* parser) { break; case TOKEN_TAG: expr->data.expr.val = parser_parse_def(parser); + break; + case TOKEN_LBLOCK: + parser_nxt_token(parser); + expr->data.expr.val = parser_parse_block(parser); + break; default: return expr; } @@ -81,37 +86,16 @@ tree_t* parser_parse_expr(parser_t* parser) { } tree_t* parser_parse_block(parser_t* parser) { + if (!parser->token || parser->token->type == TOKEN_EXPR_END || parser->token->type == TOKEN_RBLOCK) { return NULL; } + tree_t* block; block = tree_init(TREE_TYPE_BLOCK); - if (parser->token->type == TOKEN_EXPR_END) { - if (parser_nxt_token(parser)) { - block->data.block.val = parser_parse_expr(parser); - } else { - block->data.block.val = NULL; - } - - if (parser_nxt_token(parser)) { - block->data.block.nxt = parser_parse_block(parser); - } else { - block->data.block.nxt = NULL; - } - - return block; - } - - if (parser->token) { - block->data.block.val = parser_parse_expr(parser); - } else { - block->data.block.val = NULL; - } - - if (parser_nxt_token(parser)) { - block->data.block.nxt = parser_parse_block(parser); - } else { - block->data.block.nxt = NULL; - } + block->data.block.val = parser_parse_expr(parser); + block->data.block.nxt = parser_nxt_token_match(parser, TOKEN_EXPR_END) && parser_nxt_token(parser) ? + parser_parse_block(parser) : + NULL; return block; } @@ -153,17 +137,11 @@ tree_t* parser_parse_def(parser_t* parser) { def = tree_init(TREE_TYPE_DEF); def->data.def.tag = parser_parse_tag(parser); - if (parser->token->type != TOKEN_APPLY) { goto finish; } - else { parser_nxt_token(parser); } - - def->data.def.arg = parser_parse_darg(parser); - if (parser->token->type != TOKEN_SET) { goto finish; } - else { parser_nxt_token(parser); } - - def->data.def.val = parser_parse_expr(parser); - finish: - return def; + parser->token->type == TOKEN_APPLY && parser_nxt_token(parser) && (def->data.def.arg = parser_parse_darg(parser)); + parser->token->type == TOKEN_SET && parser_nxt_token(parser) && (def->data.def.val = parser_parse_expr(parser)); + + return def; } tree_t* parser_parse_carg(parser_t* parser) { diff --git a/src/token.c b/src/token.c index df71d17..bcb4c18 100644 --- a/src/token.c +++ b/src/token.c @@ -14,6 +14,8 @@ token_t* token_init(int type, char val) { } void token_destroy(token_t* token) { + if (!token) { return; } + if (token->nxt) { token_destroy(token->nxt); token->nxt = NULL; @@ -44,9 +46,8 @@ void token_add_char(token_t* token, char c) { } void token_print(token_t* token) { - - log_dbg("token/t=%d\t/v=%s", token->type, token->val); - + if (!token) { return; } + log_dbg("token/t=%d\t/v=%s", token->type, token->val); if (token->nxt) { token_print(token->nxt); } diff --git a/src/tree.c b/src/tree.c index 48c3acf..5ae4944 100644 --- a/src/tree.c +++ b/src/tree.c @@ -92,84 +92,95 @@ void tree_destroy(tree_t* tree) { void tree_print(tree_t* tree, int nest) { char* spaces; + int ncolor; + char* color; + char* bcolor; int i; /* Aaahhh. */ for(i=0,spaces=ecalloc(nest+1,sizeof(char)),spaces[nest]='\0';i<=nest-1;spaces[i++]=' '); + ncolor=31+nest%6; + color=malloc(9*sizeof(char)); + bcolor=malloc(11*sizeof(char)); + sprintf(color,"\x1b[%dm",ncolor); + sprintf(bcolor,"\x1b[%d;1m",ncolor); - #define NEST(TEXT) log_raw("%s"TEXT"\n",spaces); - #define NEST2(TEXT) log_raw("%s"TEXT,spaces); + #define NEST0(TEXT) log_raw("%s%s"TEXT"\x1b[0m\n",bcolor,spaces); + #define NEST1(TEXT) log_raw("%s%s"TEXT"\x1b[0m\n",color,spaces); + #define NEST2(TEXT) log_raw("%s \x1b[39;49;4m%s\x1b[0m\n",spaces,TEXT); + #define NEST3(TEXT) log_raw("%s \x1b[39;49;4m%d\x1b[0m\n",spaces,TEXT); - if (!tree) { - NEST("NULL"); - goto tree_print_exit; - } + if (!tree) { NEST2("NULL"); goto end; } switch (tree->type) { case TREE_TYPE_BLOCK: - NEST("[block]"); - NEST("val:"); + NEST0("[block]"); + NEST1("val:"); tree_print(tree->data.block.val, nest + 1); - NEST("nxt:"); + NEST1("nxt:"); tree_print(tree->data.block.nxt, nest + 1); break; case TREE_TYPE_EXPR: - NEST("[expression]"); - NEST("val:"); + NEST0("[expression]"); + NEST1("val:"); tree_print(tree->data.expr.val, nest + 1); break; case TREE_TYPE_LINT: - NEST("[lint]"); - NEST("val:"); - log_raw("%s %d\n", spaces, tree->data.lint.val); + NEST0("[lint]"); + NEST1("val:"); + NEST3(tree->data.lint.val); break; case TREE_TYPE_LSTR: - NEST("[lstr]"); - NEST("val:"); - log_raw("%s %s\n", spaces, tree->data.lstr.val); - NEST("len:"); - log_raw("%s %d\n", spaces, tree->data.lstr.len); + NEST0("[lstr]"); + NEST1("val:"); + NEST2(tree->data.lstr.val); + NEST1("len:"); + NEST3(tree->data.lstr.len); break; case TREE_TYPE_CALL: - NEST("[call]"); - NEST("target:"); - log_raw("%s %s\n", spaces, tree->data.call.target); - NEST("arg:") + NEST0("[call]"); + NEST1("target:"); + NEST2(tree->data.call.target); + NEST1("arg:") tree_print(tree->data.call.arg, nest + 1); break; case TREE_TYPE_CARG: - NEST("[carg]"); - NEST("val:"); + NEST0("[carg]"); + NEST1("val:"); tree_print(tree->data.carg.val, nest + 1); - NEST("nxt:"); + NEST1("nxt:"); tree_print(tree->data.carg.nxt, nest + 1); break; case TREE_TYPE_DEF: - NEST("[def]"); - NEST("tag:"); + NEST0("[def]"); + NEST1("tag:"); tree_print(tree->data.def.tag, nest + 1); - NEST("arg:"); + NEST1("arg:"); tree_print(tree->data.def.arg, nest + 1); - NEST("val:"); + NEST1("val:"); tree_print(tree->data.def.val, nest + 1); break; case TREE_TYPE_TAG: - NEST("[tag]"); - NEST("val:"); - log_raw("%s %s\n", spaces, tree->data.call.target); - NEST("nxt:"); + NEST0("[tag]"); + NEST1("val:"); + NEST2(tree->data.call.target); + NEST1("nxt:"); tree_print(tree->data.tag.nxt, nest + 1); break; case TREE_TYPE_DARG: - NEST("[darg]"); - NEST("tag:"); + NEST0("[darg]"); + NEST1("tag:"); tree_print(tree->data.darg.tag, nest + 1); - NEST("nxt:"); + NEST1("nxt:"); tree_print(tree->data.darg.nxt, nest + 1); break; default: log_err("%d", __LINE__); } - tree_print_exit: free(spaces); return; + end: + free(spaces); + free(color); + free(bcolor); + return; } -- cgit v1.2.3