diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2025-08-25 23:59:09 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2025-08-25 23:59:09 -0400 |
| commit | 978835e3dd8dd59a1efaa869f2f603eb9eea5a3f (patch) | |
| tree | 112078680658abcb9d9fa310e2f8c8553d0fa40b | |
| parent | 91b6746fe1315aa9c09936b69cea3892c04c11af (diff) | |
Split out utility functions
| -rw-r--r-- | src/formatter/args.c | 1 | ||||
| -rw-r--r-- | src/formatter/enums.c | 3 | ||||
| -rw-r--r-- | src/formatter/formatter.c | 107 | ||||
| -rw-r--r-- | src/formatter/formatter.h | 19 | ||||
| -rw-r--r-- | src/formatter/types.c | 2 | ||||
| -rw-r--r-- | src/formatter/utils.c | 112 | ||||
| -rw-r--r-- | src/formatter/utils.h | 28 |
7 files changed, 150 insertions, 122 deletions
diff --git a/src/formatter/args.c b/src/formatter/args.c index 9467c9fe..2bd115cd 100644 --- a/src/formatter/args.c +++ b/src/formatter/args.c @@ -6,6 +6,7 @@ #include "../stdlib/text.h" #include "formatter.h" #include "types.h" +#include "utils.h" OptionalText_t format_inline_arg(arg_ast_t *arg, Table_t comments) { if (range_has_comment(arg->start, arg->end, comments)) return NONE_TEXT; diff --git a/src/formatter/enums.c b/src/formatter/enums.c index 430e72ea..7a89705d 100644 --- a/src/formatter/enums.c +++ b/src/formatter/enums.c @@ -5,8 +5,7 @@ #include "../stdlib/optionals.h" #include "../stdlib/text.h" #include "args.h" -#include "formatter.h" -#include "types.h" +#include "utils.h" OptionalText_t format_inline_tag(tag_ast_t *tag, Table_t comments) { if (range_has_comment(tag->start, tag->end, comments)) return NONE_TEXT; diff --git a/src/formatter/formatter.c b/src/formatter/formatter.c index d2168231..e4c92542 100644 --- a/src/formatter/formatter.c +++ b/src/formatter/formatter.c @@ -2,6 +2,8 @@ #include <assert.h> #include <setjmp.h> +#include <stdbool.h> +#include <stdint.h> #include "../ast.h" #include "../parse/context.h" @@ -11,119 +13,18 @@ #include "../stdlib/integers.h" #include "../stdlib/optionals.h" #include "../stdlib/stdlib.h" -#include "../stdlib/tables.h" #include "../stdlib/text.h" #include "args.h" #include "enums.h" #include "formatter.h" #include "types.h" +#include "utils.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); -} - -static 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; - } -} - -static 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))); -} - -static 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, ")"); -} - -static 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; -} - -static Text_t format_namespace(ast_t *namespace, Table_t comments, Text_t indent) { +Text_t format_namespace(ast_t *namespace, Table_t comments, Text_t indent) { if (unwrap_block(namespace) == NULL) return EMPTY_TEXT; return Texts("\n", indent, single_indent, format_code(namespace, comments, Texts(indent, single_indent))); } -static 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 format_inline_code(ast_t *ast, Table_t comments) { if (range_has_comment(ast->start, ast->end, comments)) return NONE_TEXT; switch (ast->tag) { diff --git a/src/formatter/formatter.h b/src/formatter/formatter.h index 83bb9e56..a8f9013a 100644 --- a/src/formatter/formatter.h +++ b/src/formatter/formatter.h @@ -2,25 +2,12 @@ #pragma once +#include <stdbool.h> + #include "../ast.h" #include "../stdlib/datatypes.h" -#define MAX_WIDTH 100 - -#define must(expr) \ - ({ \ - OptionalText_t _expr = expr; \ - if (_expr.length < 0) return NONE_TEXT; \ - (Text_t) _expr; \ - }) - -extern const Text_t single_indent; - Text_t format_file(const char *path); Text_t format_code(ast_t *ast, Table_t comments, Text_t indentation); +Text_t format_namespace(ast_t *namespace, Table_t comments, Text_t indent); OptionalText_t format_inline_code(ast_t *ast, Table_t comments); - -OptionalText_t next_comment(Table_t comments, const char **pos, const char *end); -bool range_has_comment(const char *start, const char *end, Table_t comments); -OptionalText_t next_comment(Table_t comments, const char **pos, const char *end); -void add_line(Text_t *code, Text_t line, Text_t indent); diff --git a/src/formatter/types.c b/src/formatter/types.c index 282a299f..34128b0b 100644 --- a/src/formatter/types.c +++ b/src/formatter/types.c @@ -4,7 +4,7 @@ #include "../stdlib/datatypes.h" #include "../stdlib/optionals.h" #include "../stdlib/text.h" -#include "formatter.h" +#include "utils.h" OptionalText_t format_inline_type(type_ast_t *type, Table_t comments) { if (range_has_comment(type->start, type->end, comments)) return NONE_TEXT; 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 <stdbool.h> +#include <stdint.h> + +#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; + } +} diff --git a/src/formatter/utils.h b/src/formatter/utils.h new file mode 100644 index 00000000..a8def627 --- /dev/null +++ b/src/formatter/utils.h @@ -0,0 +1,28 @@ +// This file defines utility functions for autoformatting code + +#pragma once + +#include <stdbool.h> + +#include "../ast.h" +#include "../stdlib/datatypes.h" + +#define MAX_WIDTH 100 + +#define must(expr) \ + ({ \ + OptionalText_t _expr = expr; \ + if (_expr.length < 0) return NONE_TEXT; \ + (Text_t) _expr; \ + }) + +extern const Text_t single_indent; + +void add_line(Text_t *code, Text_t line, Text_t indent); +OptionalText_t next_comment(Table_t comments, const char **pos, const char *end); +bool range_has_comment(const char *start, const char *end, Table_t comments); +CONSTFUNC bool should_have_blank_line(ast_t *ast); +Text_t indent_code(Text_t code); +Text_t parenthesize(Text_t code, Text_t indent); +CONSTFUNC ast_t *unwrap_block(ast_t *ast); +CONSTFUNC const char *binop_tomo_operator(ast_e tag); |
