aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/formatter/args.c1
-rw-r--r--src/formatter/enums.c3
-rw-r--r--src/formatter/formatter.c107
-rw-r--r--src/formatter/formatter.h19
-rw-r--r--src/formatter/types.c2
-rw-r--r--src/formatter/utils.c112
-rw-r--r--src/formatter/utils.h28
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);