From 978835e3dd8dd59a1efaa869f2f603eb9eea5a3f Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Mon, 25 Aug 2025 23:59:09 -0400 Subject: Split out utility functions --- src/formatter/utils.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 src/formatter/utils.c (limited to 'src/formatter/utils.c') diff --git a/src/formatter/utils.c b/src/formatter/utils.c new file mode 100644 index 00000000..472829d9 --- /dev/null +++ b/src/formatter/utils.c @@ -0,0 +1,112 @@ +// This file defines utility functions for autoformatting code + +#include +#include + +#include "../ast.h" +#include "../parse/context.h" +#include "../stdlib/datatypes.h" +#include "../stdlib/optionals.h" +#include "../stdlib/tables.h" +#include "../stdlib/text.h" + +const Text_t single_indent = Text(" "); + +void add_line(Text_t *code, Text_t line, Text_t indent) { + if (code->length == 0) { + *code = line; + } else { + if (line.length > 0) *code = Texts(*code, "\n", indent, line); + else *code = Texts(*code, "\n"); + } +} + +OptionalText_t next_comment(Table_t comments, const char **pos, const char *end) { + for (const char *p = *pos; p < end; p++) { + const char **comment_end = Table$get(comments, &p, parse_comments_info); + if (comment_end) { + *pos = *comment_end; + return Text$from_strn(p, (int64_t)(*comment_end - p)); + } + } + return NONE_TEXT; +} + +bool range_has_comment(const char *start, const char *end, Table_t comments) { + OptionalText_t comment = next_comment(comments, &start, end); + return (comment.length >= 0); +} + +CONSTFUNC bool should_have_blank_line(ast_t *ast) { + switch (ast->tag) { + case If: + case When: + case Repeat: + case While: + case For: + case Block: + case FunctionDef: + case StructDef: + case EnumDef: + case LangDef: + case ConvertDef: + case Extend: return true; + default: return false; + } +} + +Text_t indent_code(Text_t code) { + if (code.length <= 0) return code; + return Texts(single_indent, Text$replace(code, Text("\n"), Texts("\n", single_indent))); +} + +Text_t parenthesize(Text_t code, Text_t indent) { + if (Text$has(code, Text("\n"))) return Texts("(\n", indent, indent_code(code), "\n", indent, ")"); + else return Texts("(", code, ")"); +} + +CONSTFUNC ast_t *unwrap_block(ast_t *ast) { + if (ast == NULL) return NULL; + while (ast->tag == Block && Match(ast, Block)->statements && Match(ast, Block)->statements->next == NULL) { + ast = Match(ast, Block)->statements->ast; + } + return ast; +} + +CONSTFUNC const char *binop_tomo_operator(ast_e tag) { + switch (tag) { + case Power: return "^"; + case PowerUpdate: return "^="; + case Concat: return "++"; + case ConcatUpdate: return "++="; + case Multiply: return "*"; + case MultiplyUpdate: return "*="; + case Divide: return "/"; + case DivideUpdate: return "/="; + case Mod: return "mod"; + case ModUpdate: return "mod="; + case Mod1: return "mod1"; + case Mod1Update: return "mod1="; + case Plus: return "+"; + case PlusUpdate: return "+="; + case Minus: return "-"; + case MinusUpdate: return "-="; + case LeftShift: return "<<"; + case LeftShiftUpdate: return "<<="; + case RightShift: return ">>"; + case RightShiftUpdate: return ">>="; + case And: return "and"; + case AndUpdate: return "and="; + case Or: return "or"; + case OrUpdate: return "or="; + case Xor: return "xor"; + case XorUpdate: return "xor="; + case Equals: return "=="; + case NotEquals: return "!="; + case LessThan: return "<"; + case LessThanOrEquals: return "<="; + case GreaterThan: return ">"; + case GreaterThanOrEquals: return ">="; + default: return NULL; + } +} -- cgit v1.2.3 From 5b06702dde3f53510a3d64a8156a349914afa605 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Tue, 26 Aug 2025 02:54:56 -0400 Subject: Fixes for unops --- src/formatter/utils.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src/formatter/utils.c') diff --git a/src/formatter/utils.c b/src/formatter/utils.c index 472829d9..37751377 100644 --- a/src/formatter/utils.c +++ b/src/formatter/utils.c @@ -9,6 +9,7 @@ #include "../stdlib/optionals.h" #include "../stdlib/tables.h" #include "../stdlib/text.h" +#include "formatter.h" const Text_t single_indent = Text(" "); @@ -110,3 +111,22 @@ CONSTFUNC const char *binop_tomo_operator(ast_e tag) { default: return NULL; } } + +OptionalText_t termify_inline(ast_t *ast, Table_t comments) { + if (range_has_comment(ast->start, ast->end, comments)) return NONE_TEXT; + switch (ast->tag) { + case BINOP_CASES: + case Not: + case Negative: return parenthesize(format_inline_code(ast, comments), EMPTY_TEXT); + default: return format_inline_code(ast, comments); + } +} + +Text_t termify(ast_t *ast, Table_t comments, Text_t indent) { + switch (ast->tag) { + case BINOP_CASES: + case Not: + case Negative: return parenthesize(format_code(ast, comments, indent), indent); + default: return format_inline_code(ast, comments); + } +} -- cgit v1.2.3 From 4715487a4be9f03ad58cb3199e95573e262f6387 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Tue, 26 Aug 2025 02:56:51 -0400 Subject: More termify fixes --- src/formatter/utils.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/formatter/utils.c') diff --git a/src/formatter/utils.c b/src/formatter/utils.c index 37751377..a032ec2f 100644 --- a/src/formatter/utils.c +++ b/src/formatter/utils.c @@ -117,7 +117,9 @@ OptionalText_t termify_inline(ast_t *ast, Table_t comments) { switch (ast->tag) { case BINOP_CASES: case Not: - case Negative: return parenthesize(format_inline_code(ast, comments), EMPTY_TEXT); + case Negative: + case HeapAllocate: + case StackReference: return parenthesize(format_inline_code(ast, comments), EMPTY_TEXT); default: return format_inline_code(ast, comments); } } @@ -126,7 +128,9 @@ Text_t termify(ast_t *ast, Table_t comments, Text_t indent) { switch (ast->tag) { case BINOP_CASES: case Not: - case Negative: return parenthesize(format_code(ast, comments, indent), indent); + case Negative: + case HeapAllocate: + case StackReference: return parenthesize(format_code(ast, comments, indent), indent); default: return format_inline_code(ast, comments); } } -- cgit v1.2.3 From cb1d36c6d8bc84f3422c71ab3eb29606e80f7837 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Tue, 26 Aug 2025 14:58:51 -0400 Subject: Formatting for reductions --- src/formatter/utils.c | 38 -------------------------------------- 1 file changed, 38 deletions(-) (limited to 'src/formatter/utils.c') diff --git a/src/formatter/utils.c b/src/formatter/utils.c index a032ec2f..fa4ec806 100644 --- a/src/formatter/utils.c +++ b/src/formatter/utils.c @@ -74,44 +74,6 @@ CONSTFUNC ast_t *unwrap_block(ast_t *ast) { return ast; } -CONSTFUNC const char *binop_tomo_operator(ast_e tag) { - switch (tag) { - case Power: return "^"; - case PowerUpdate: return "^="; - case Concat: return "++"; - case ConcatUpdate: return "++="; - case Multiply: return "*"; - case MultiplyUpdate: return "*="; - case Divide: return "/"; - case DivideUpdate: return "/="; - case Mod: return "mod"; - case ModUpdate: return "mod="; - case Mod1: return "mod1"; - case Mod1Update: return "mod1="; - case Plus: return "+"; - case PlusUpdate: return "+="; - case Minus: return "-"; - case MinusUpdate: return "-="; - case LeftShift: return "<<"; - case LeftShiftUpdate: return "<<="; - case RightShift: return ">>"; - case RightShiftUpdate: return ">>="; - case And: return "and"; - case AndUpdate: return "and="; - case Or: return "or"; - case OrUpdate: return "or="; - case Xor: return "xor"; - case XorUpdate: return "xor="; - case Equals: return "=="; - case NotEquals: return "!="; - case LessThan: return "<"; - case LessThanOrEquals: return "<="; - case GreaterThan: return ">"; - case GreaterThanOrEquals: return ">="; - default: return NULL; - } -} - OptionalText_t termify_inline(ast_t *ast, Table_t comments) { if (range_has_comment(ast->start, ast->end, comments)) return NONE_TEXT; switch (ast->tag) { -- cgit v1.2.3 From 76aac20d8ed7482f4ee7f3b3a69e3e08138251fa Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Tue, 26 Aug 2025 15:54:54 -0400 Subject: Add formatting for defer --- src/formatter/utils.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/formatter/utils.c') diff --git a/src/formatter/utils.c b/src/formatter/utils.c index fa4ec806..084a6667 100644 --- a/src/formatter/utils.c +++ b/src/formatter/utils.c @@ -51,7 +51,8 @@ CONSTFUNC bool should_have_blank_line(ast_t *ast) { case EnumDef: case LangDef: case ConvertDef: - case Extend: return true; + case Extend: + case Defer: return true; default: return false; } } -- cgit v1.2.3 From 2d3021728bf5c74f8bf6854c1ae4951a6ebbf9c7 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Fri, 29 Aug 2025 14:04:55 -0400 Subject: Formatting tweaks/fixes --- src/formatter/utils.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'src/formatter/utils.c') diff --git a/src/formatter/utils.c b/src/formatter/utils.c index 084a6667..1f4e64d8 100644 --- a/src/formatter/utils.c +++ b/src/formatter/utils.c @@ -38,7 +38,7 @@ bool range_has_comment(const char *start, const char *end, Table_t comments) { return (comment.length >= 0); } -CONSTFUNC bool should_have_blank_line(ast_t *ast) { +CONSTFUNC int suggested_blank_lines(ast_t *ast) { switch (ast->tag) { case If: case When: @@ -46,14 +46,15 @@ CONSTFUNC bool should_have_blank_line(ast_t *ast) { case While: case For: case Block: - case FunctionDef: + case Defer: return 1; + case Use: return 1; + case ConvertDef: + case FunctionDef: return 1; case StructDef: case EnumDef: case LangDef: - case ConvertDef: - case Extend: - case Defer: return true; - default: return false; + case Extend: return 2; + default: return 0; } } -- cgit v1.2.3 From f2ad722780f96dc5fb7d93f536c7267741be3f6f Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sat, 30 Aug 2025 14:29:50 -0400 Subject: Fix line gaps --- src/formatter/utils.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) (limited to 'src/formatter/utils.c') diff --git a/src/formatter/utils.c b/src/formatter/utils.c index 1f4e64d8..5619e6ce 100644 --- a/src/formatter/utils.c +++ b/src/formatter/utils.c @@ -38,24 +38,45 @@ bool range_has_comment(const char *start, const char *end, Table_t comments) { return (comment.length >= 0); } -CONSTFUNC int suggested_blank_lines(ast_t *ast) { - switch (ast->tag) { +CONSTFUNC int suggested_blank_lines(ast_t *first, ast_t *second) { + if (second == NULL) return 0; + + if (first->tag == Use && second->tag != Use) return 1; + + switch (first->tag) { + case If: + case When: + case Repeat: + case While: + case For: + case Block: + case Defer: + case ConvertDef: + case FunctionDef: + case StructDef: + case EnumDef: + case LangDef: + case Extend: return 1; + default: break; + } + + switch (second->tag) { case If: case When: case Repeat: case While: case For: case Block: - case Defer: return 1; - case Use: return 1; + case Defer: case ConvertDef: - case FunctionDef: return 1; + case FunctionDef: case StructDef: case EnumDef: case LangDef: - case Extend: return 2; - default: return 0; + case Extend: return 1; + default: break; } + return 0; } Text_t indent_code(Text_t code) { @@ -73,6 +94,7 @@ CONSTFUNC ast_t *unwrap_block(ast_t *ast) { while (ast->tag == Block && Match(ast, Block)->statements && Match(ast, Block)->statements->next == NULL) { ast = Match(ast, Block)->statements->ast; } + if (ast->tag == Block && Match(ast, Block)->statements == NULL) return NULL; return ast; } -- cgit v1.2.3 From ca3b72d1f5a230cc5b25edd55918864c2df248b5 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sat, 30 Aug 2025 14:44:13 -0400 Subject: Tweaks for blank lines --- src/formatter/utils.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'src/formatter/utils.c') diff --git a/src/formatter/utils.c b/src/formatter/utils.c index 5619e6ce..80445ec3 100644 --- a/src/formatter/utils.c +++ b/src/formatter/utils.c @@ -41,7 +41,21 @@ bool range_has_comment(const char *start, const char *end, Table_t comments) { CONSTFUNC int suggested_blank_lines(ast_t *first, ast_t *second) { if (second == NULL) return 0; - if (first->tag == Use && second->tag != Use) return 1; + for (;;) { + if (first->tag == Declare && Match(first, Declare)->value) { + first = Match(first, Declare)->value; + } else if (first->tag == DocTest && Match(first, DocTest)->expr && Match(first, DocTest)->expected == NULL) { + first = Match(first, DocTest)->expr; + } else break; + } + + for (;;) { + if (second->tag == Declare && Match(second, Declare)->value) { + second = Match(second, Declare)->value; + } else if (second->tag == DocTest && Match(second, DocTest)->expr && Match(second, DocTest)->expected == NULL) { + second = Match(second, DocTest)->expr; + } else break; + } switch (first->tag) { case If: @@ -53,10 +67,27 @@ CONSTFUNC int suggested_blank_lines(ast_t *first, ast_t *second) { case Defer: case ConvertDef: case FunctionDef: + case Lambda: case StructDef: case EnumDef: case LangDef: case Extend: return 1; + case Use: { + if (second->tag != Use) return 1; + break; + } + case Declare: { + DeclareMatch(decl, first, Declare); + if (decl->value) return suggested_blank_lines(decl->value, second); + break; + } + case Assign: { + DeclareMatch(assign, first, Assign); + for (ast_list_t *val = assign->values; val; val = val->next) { + if (suggested_blank_lines(val->ast, second) > 0) return 1; + } + break; + } default: break; } @@ -70,6 +101,7 @@ CONSTFUNC int suggested_blank_lines(ast_t *first, ast_t *second) { case Defer: case ConvertDef: case FunctionDef: + case Lambda: case StructDef: case EnumDef: case LangDef: -- cgit v1.2.3 From 0eae0e70b3475ab2cf3d8486dc3a609a22faa75a Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Mon, 1 Sep 2025 17:41:55 -0400 Subject: Fixes --- src/formatter/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/formatter/utils.c') diff --git a/src/formatter/utils.c b/src/formatter/utils.c index 80445ec3..bbe74d7f 100644 --- a/src/formatter/utils.c +++ b/src/formatter/utils.c @@ -27,7 +27,7 @@ OptionalText_t next_comment(Table_t comments, const char **pos, const char *end) const char **comment_end = Table$get(comments, &p, parse_comments_info); if (comment_end) { *pos = *comment_end; - return Text$from_strn(p, (int64_t)(*comment_end - p)); + return Text$from_strn(p, (size_t)(*comment_end - p)); } } return NONE_TEXT; -- cgit v1.2.3