aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--src/formatter.h11
-rw-r--r--src/formatter/args.c55
-rw-r--r--src/formatter/args.h15
-rw-r--r--src/formatter/enums.c45
-rw-r--r--src/formatter/enums.h11
-rw-r--r--src/formatter/formatter.c (renamed from src/formatter.c)142
-rw-r--r--src/formatter/formatter.h26
-rw-r--r--src/formatter/types.c30
-rw-r--r--src/formatter/types.h9
-rw-r--r--src/tomo.c2
11 files changed, 208 insertions, 140 deletions
diff --git a/Makefile b/Makefile
index 95f07128..58a8d01f 100644
--- a/Makefile
+++ b/Makefile
@@ -95,7 +95,7 @@ else
endif
EXE_FILE=tomo_$(TOMO_VERSION)
-COMPILER_OBJS=$(patsubst %.c,%.o,$(wildcard src/*.c src/compile/*.c src/parse/*.c))
+COMPILER_OBJS=$(patsubst %.c,%.o,$(wildcard src/*.c src/compile/*.c src/parse/*.c src/formatter/*.c))
STDLIB_OBJS=$(patsubst %.c,%.o,$(wildcard src/stdlib/*.c))
TESTS=$(patsubst test/%.tm,test/results/%.tm.testresult,$(wildcard test/*.tm))
API_YAML=$(wildcard api/*.yaml)
diff --git a/src/formatter.h b/src/formatter.h
deleted file mode 100644
index bead52ec..00000000
--- a/src/formatter.h
+++ /dev/null
@@ -1,11 +0,0 @@
-// This code defines functions for transforming ASTs back into Tomo source text
-
-#pragma once
-
-#include "ast.h"
-#include "stdlib/datatypes.h"
-
-Text_t format_file(const char *path);
-Text_t format_code(ast_t *ast, Table_t comments, Text_t indentation);
-OptionalText_t format_inline_code(ast_t *ast, Table_t comments);
-OptionalText_t next_comment(Table_t comments, const char **pos, const char *end);
diff --git a/src/formatter/args.c b/src/formatter/args.c
new file mode 100644
index 00000000..9467c9fe
--- /dev/null
+++ b/src/formatter/args.c
@@ -0,0 +1,55 @@
+// Logic for formatting arguments and argument lists
+
+#include "../ast.h"
+#include "../stdlib/datatypes.h"
+#include "../stdlib/optionals.h"
+#include "../stdlib/text.h"
+#include "formatter.h"
+#include "types.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;
+ if (arg->name == NULL && arg->value) return must(format_inline_code(arg->value, comments));
+ Text_t code = Text$from_str(arg->name);
+ if (arg->type) code = Texts(code, ":", must(format_inline_type(arg->type, comments)));
+ if (arg->value) code = Texts(code, " = ", must(format_inline_code(arg->value, comments)));
+ return code;
+}
+
+Text_t format_arg(arg_ast_t *arg, Table_t comments, Text_t indent) {
+ OptionalText_t inline_arg = format_inline_arg(arg, comments);
+ if (inline_arg.length >= 0 && inline_arg.length <= MAX_WIDTH) return inline_arg;
+ if (arg->name == NULL && arg->value) return format_code(arg->value, comments, indent);
+ Text_t code = Text$from_str(arg->name);
+ if (arg->type) code = Texts(code, ":", format_type(arg->type, comments, indent));
+ if (arg->value) code = Texts(code, " = ", format_code(arg->value, comments, indent));
+ return code;
+}
+
+OptionalText_t format_inline_args(arg_ast_t *args, Table_t comments) {
+ Text_t code = EMPTY_TEXT;
+ for (; args; args = args->next) {
+ if (args->name && args->next && args->type == args->next->type && args->value == args->next->value) {
+ code = Texts(code, Text$from_str(args->name), ",");
+ } else {
+ code = Texts(code, must(format_inline_arg(args, comments)));
+ if (args->next) code = Texts(code, ", ");
+ }
+ if (args->next && range_has_comment(args->end, args->next->start, comments)) return NONE_TEXT;
+ }
+ return code;
+}
+
+Text_t format_args(arg_ast_t *args, Table_t comments, Text_t indent) {
+ OptionalText_t inline_args = format_inline_args(args, comments);
+ if (inline_args.length >= 0 && inline_args.length <= MAX_WIDTH) return inline_args;
+ Text_t code = EMPTY_TEXT;
+ for (; args; args = args->next) {
+ if (args->name && args->next && args->type == args->next->type && args->value == args->next->value) {
+ code = Texts(code, Text$from_str(args->name), ",");
+ } else {
+ add_line(&code, Texts(format_arg(args, comments, indent), ","), indent);
+ }
+ }
+ return code;
+}
diff --git a/src/formatter/args.h b/src/formatter/args.h
new file mode 100644
index 00000000..815069a4
--- /dev/null
+++ b/src/formatter/args.h
@@ -0,0 +1,15 @@
+// Logic for formatting arguments and argument lists
+
+#pragma once
+
+#include "../ast.h"
+#include "../stdlib/datatypes.h"
+
+OptionalText_t format_inline_arg(arg_ast_t *arg, Table_t comments);
+Text_t format_arg(arg_ast_t *arg, Table_t comments, Text_t indent);
+OptionalText_t format_inline_args(arg_ast_t *args, Table_t comments);
+Text_t format_args(arg_ast_t *args, Table_t comments, Text_t indent);
+OptionalText_t format_inline_tag(tag_ast_t *tag, Table_t comments);
+Text_t format_tag(tag_ast_t *tag, Table_t comments, Text_t indent);
+OptionalText_t format_inline_tags(tag_ast_t *tags, Table_t comments);
+Text_t format_tags(tag_ast_t *tags, Table_t comments, Text_t indent);
diff --git a/src/formatter/enums.c b/src/formatter/enums.c
new file mode 100644
index 00000000..430e72ea
--- /dev/null
+++ b/src/formatter/enums.c
@@ -0,0 +1,45 @@
+// Logic for formatting enums and enum tags
+
+#include "../ast.h"
+#include "../stdlib/datatypes.h"
+#include "../stdlib/optionals.h"
+#include "../stdlib/text.h"
+#include "args.h"
+#include "formatter.h"
+#include "types.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;
+ Text_t code = Texts(Text$from_str(tag->name), "(", must(format_inline_args(tag->fields, comments)));
+ if (tag->secret) code = Texts(code, "; secret");
+ return Texts(code, ")");
+}
+
+Text_t format_tag(tag_ast_t *tag, Table_t comments, Text_t indent) {
+ OptionalText_t inline_tag = format_inline_tag(tag, comments);
+ if (inline_tag.length >= 0) return inline_tag;
+ Text_t code =
+ Texts(Text$from_str(tag->name), "(", format_args(tag->fields, comments, Texts(indent, single_indent)));
+ if (tag->secret) code = Texts(code, "; secret");
+ return Texts(code, ")");
+}
+
+OptionalText_t format_inline_tags(tag_ast_t *tags, Table_t comments) {
+ Text_t code = EMPTY_TEXT;
+ for (; tags; tags = tags->next) {
+ code = Texts(code, must(format_inline_tag(tags, comments)));
+ if (tags->next) code = Texts(code, ", ");
+ if (tags->next && range_has_comment(tags->end, tags->next->start, comments)) return NONE_TEXT;
+ }
+ return code;
+}
+
+Text_t format_tags(tag_ast_t *tags, Table_t comments, Text_t indent) {
+ OptionalText_t inline_tags = format_inline_tags(tags, comments);
+ if (inline_tags.length >= 0) return inline_tags;
+ Text_t code = EMPTY_TEXT;
+ for (; tags; tags = tags->next) {
+ add_line(&code, Texts(format_tag(tags, comments, indent), ","), indent);
+ }
+ return code;
+}
diff --git a/src/formatter/enums.h b/src/formatter/enums.h
new file mode 100644
index 00000000..e7233df4
--- /dev/null
+++ b/src/formatter/enums.h
@@ -0,0 +1,11 @@
+// Logic for formatting enums and enum tags
+
+#pragma once
+
+#include "../ast.h"
+#include "../stdlib/datatypes.h"
+
+OptionalText_t format_inline_tag(tag_ast_t *tag, Table_t comments);
+Text_t format_tag(tag_ast_t *tag, Table_t comments, Text_t indent);
+OptionalText_t format_inline_tags(tag_ast_t *tags, Table_t comments);
+Text_t format_tags(tag_ast_t *tags, Table_t comments, Text_t indent);
diff --git a/src/formatter.c b/src/formatter/formatter.c
index 51155015..d2168231 100644
--- a/src/formatter.c
+++ b/src/formatter/formatter.c
@@ -3,30 +3,24 @@
#include <assert.h>
#include <setjmp.h>
-#include "ast.h"
+#include "../ast.h"
+#include "../parse/context.h"
+#include "../parse/files.h"
+#include "../parse/utils.h"
+#include "../stdlib/datatypes.h"
+#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 "parse/context.h"
-#include "parse/files.h"
-#include "parse/utils.h"
-#include "stdlib/datatypes.h"
-#include "stdlib/integers.h"
-#include "stdlib/optionals.h"
-#include "stdlib/stdlib.h"
-#include "stdlib/tables.h"
-#include "stdlib/text.h"
-
-#define MAX_WIDTH 100
-
-#define must(expr) \
- ({ \
- OptionalText_t _expr = expr; \
- if (_expr.length < 0) return NONE_TEXT; \
- (Text_t) _expr; \
- })
+#include "types.h"
const Text_t single_indent = Text(" ");
-static void add_line(Text_t *code, Text_t line, Text_t indent) {
+void add_line(Text_t *code, Text_t line, Text_t indent) {
if (code->length == 0) {
*code = line;
} else {
@@ -46,7 +40,7 @@ OptionalText_t next_comment(Table_t comments, const char **pos, const char *end)
return NONE_TEXT;
}
-static bool range_has_comment(const char *start, const char *end, Table_t comments) {
+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);
}
@@ -79,112 +73,6 @@ static Text_t parenthesize(Text_t code, Text_t indent) {
else return Texts("(", code, ")");
}
-static OptionalText_t format_inline_type(type_ast_t *type, Table_t comments) {
- if (range_has_comment(type->start, type->end, comments)) return NONE_TEXT;
- switch (type->tag) {
- default: {
- Text_t code = Text$from_strn(type->start, (int64_t)(type->end - type->start));
- if (Text$has(code, Text("\n"))) return NONE_TEXT;
- return Text$replace(code, Text("\t"), single_indent);
- }
- }
-}
-
-static Text_t format_type(type_ast_t *type, Table_t comments, Text_t indent) {
- (void)comments, (void)indent;
- switch (type->tag) {
- default: {
- OptionalText_t inline_type = format_inline_type(type, comments);
- if (inline_type.length >= 0) return inline_type;
- Text_t code = Text$from_strn(type->start, (int64_t)(type->end - type->start));
- return Text$replace(code, Text("\t"), single_indent);
- }
- }
-}
-
-static OptionalText_t format_inline_arg(arg_ast_t *arg, Table_t comments) {
- if (range_has_comment(arg->start, arg->end, comments)) return NONE_TEXT;
- if (arg->name == NULL && arg->value) return must(format_inline_code(arg->value, comments));
- Text_t code = Text$from_str(arg->name);
- if (arg->type) code = Texts(code, ":", must(format_inline_type(arg->type, comments)));
- if (arg->value) code = Texts(code, " = ", must(format_inline_code(arg->value, comments)));
- return code;
-}
-
-static Text_t format_arg(arg_ast_t *arg, Table_t comments, Text_t indent) {
- OptionalText_t inline_arg = format_inline_arg(arg, comments);
- if (inline_arg.length >= 0 && inline_arg.length <= MAX_WIDTH) return inline_arg;
- if (arg->name == NULL && arg->value) return format_code(arg->value, comments, indent);
- Text_t code = Text$from_str(arg->name);
- if (arg->type) code = Texts(code, ":", format_type(arg->type, comments, indent));
- if (arg->value) code = Texts(code, " = ", format_code(arg->value, comments, indent));
- return code;
-}
-
-static OptionalText_t format_inline_args(arg_ast_t *args, Table_t comments) {
- Text_t code = EMPTY_TEXT;
- for (; args; args = args->next) {
- if (args->name && args->next && args->type == args->next->type && args->value == args->next->value) {
- code = Texts(code, Text$from_str(args->name), ",");
- } else {
- code = Texts(code, must(format_inline_arg(args, comments)));
- if (args->next) code = Texts(code, ", ");
- }
- if (args->next && range_has_comment(args->end, args->next->start, comments)) return NONE_TEXT;
- }
- return code;
-}
-
-static Text_t format_args(arg_ast_t *args, Table_t comments, Text_t indent) {
- OptionalText_t inline_args = format_inline_args(args, comments);
- if (inline_args.length >= 0 && inline_args.length <= MAX_WIDTH) return inline_args;
- Text_t code = EMPTY_TEXT;
- for (; args; args = args->next) {
- if (args->name && args->next && args->type == args->next->type && args->value == args->next->value) {
- code = Texts(code, Text$from_str(args->name), ",");
- } else {
- add_line(&code, Texts(format_arg(args, comments, indent), ","), indent);
- }
- }
- return code;
-}
-
-static OptionalText_t format_inline_tag(tag_ast_t *tag, Table_t comments) {
- if (range_has_comment(tag->start, tag->end, comments)) return NONE_TEXT;
- Text_t code = Texts(Text$from_str(tag->name), "(", must(format_inline_args(tag->fields, comments)));
- if (tag->secret) code = Texts(code, "; secret");
- return Texts(code, ")");
-}
-
-static Text_t format_tag(tag_ast_t *tag, Table_t comments, Text_t indent) {
- OptionalText_t inline_tag = format_inline_tag(tag, comments);
- if (inline_tag.length >= 0) return inline_tag;
- Text_t code =
- Texts(Text$from_str(tag->name), "(", format_args(tag->fields, comments, Texts(indent, single_indent)));
- if (tag->secret) code = Texts(code, "; secret");
- return Texts(code, ")");
-}
-
-static OptionalText_t format_inline_tags(tag_ast_t *tags, Table_t comments) {
- Text_t code = EMPTY_TEXT;
- for (; tags; tags = tags->next) {
- code = Texts(code, must(format_inline_tag(tags, comments)));
- if (tags->next) code = Texts(code, ", ");
- if (tags->next && range_has_comment(tags->end, tags->next->start, comments)) return NONE_TEXT;
- }
- return code;
-}
-
-static Text_t format_tags(tag_ast_t *tags, Table_t comments, Text_t indent) {
- OptionalText_t inline_tags = format_inline_tags(tags, comments);
- if (inline_tags.length >= 0) return inline_tags;
- Text_t code = EMPTY_TEXT;
- for (; tags; tags = tags->next) {
- add_line(&code, Texts(format_tag(tags, comments, indent), ","), indent);
- }
- return 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) {
diff --git a/src/formatter/formatter.h b/src/formatter/formatter.h
new file mode 100644
index 00000000..83bb9e56
--- /dev/null
+++ b/src/formatter/formatter.h
@@ -0,0 +1,26 @@
+// This code defines functions for transforming ASTs back into Tomo source text
+
+#pragma once
+
+#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);
+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
new file mode 100644
index 00000000..282a299f
--- /dev/null
+++ b/src/formatter/types.c
@@ -0,0 +1,30 @@
+// Logic for formatting types
+
+#include "../ast.h"
+#include "../stdlib/datatypes.h"
+#include "../stdlib/optionals.h"
+#include "../stdlib/text.h"
+#include "formatter.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;
+ switch (type->tag) {
+ default: {
+ Text_t code = Text$from_strn(type->start, (int64_t)(type->end - type->start));
+ if (Text$has(code, Text("\n"))) return NONE_TEXT;
+ return Text$replace(code, Text("\t"), single_indent);
+ }
+ }
+}
+
+Text_t format_type(type_ast_t *type, Table_t comments, Text_t indent) {
+ (void)comments, (void)indent;
+ switch (type->tag) {
+ default: {
+ OptionalText_t inline_type = format_inline_type(type, comments);
+ if (inline_type.length >= 0) return inline_type;
+ Text_t code = Text$from_strn(type->start, (int64_t)(type->end - type->start));
+ return Text$replace(code, Text("\t"), single_indent);
+ }
+ }
+}
diff --git a/src/formatter/types.h b/src/formatter/types.h
new file mode 100644
index 00000000..1f0698b3
--- /dev/null
+++ b/src/formatter/types.h
@@ -0,0 +1,9 @@
+// Logic for formatting types
+
+#pragma once
+
+#include "../ast.h"
+#include "../stdlib/datatypes.h"
+
+OptionalText_t format_inline_type(type_ast_t *type, Table_t comments);
+Text_t format_type(type_ast_t *type, Table_t comments, Text_t indent);
diff --git a/src/tomo.c b/src/tomo.c
index 36a47b7f..25a92889 100644
--- a/src/tomo.c
+++ b/src/tomo.c
@@ -19,7 +19,7 @@
#include "compile/files.h"
#include "compile/headers.h"
#include "config.h"
-#include "formatter.h"
+#include "formatter/formatter.h"
#include "modules.h"
#include "naming.h"
#include "parse/files.h"