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 --- Makefile | 2 +- src/formatter/formatter.c | 58 +++++++++++++++++++++++++++++++---------------- src/formatter/utils.c | 20 ++++++++++++++++ src/formatter/utils.h | 2 ++ 4 files changed, 62 insertions(+), 20 deletions(-) diff --git a/Makefile b/Makefile index 58a8d01f..adcffed2 100644 --- a/Makefile +++ b/Makefile @@ -129,7 +129,7 @@ build/lib/$(AR_FILE): $(STDLIB_OBJS) ar -rcs $@ $^ tags: - ctags src/*.{c,h} src/stdlib/*.{c,h} src/compile/*.{c,h} src/parse/*.{c,h} + ctags src/*.{c,h} src/stdlib/*.{c,h} src/compile/*.{c,h} src/parse/*.{c,h} src/format/*.{c,h} config.mk: configure.sh bash ./configure.sh diff --git a/src/formatter/formatter.c b/src/formatter/formatter.c index 7c27d053..96bdf632 100644 --- a/src/formatter/formatter.c +++ b/src/formatter/formatter.c @@ -165,31 +165,39 @@ OptionalText_t format_inline_code(ast_t *ast, Table_t comments) { ast_t *value = Match(ast, Return)->value; return value ? Texts("return ", fmt_inline(value, comments)) : Text("return"); } + /*inline*/ case Not: { + ast_t *val = Match(ast, Not)->value; + return Texts("not ", must(termify_inline(val, comments))); + } + /*inline*/ case Negative: { + ast_t *val = Match(ast, Negative)->value; + return Texts("-", must(termify_inline(val, comments))); + } /*inline*/ case HeapAllocate: { ast_t *val = Match(ast, HeapAllocate)->value; - return Texts("@", fmt_inline(val, comments)); + return Texts("@", must(termify_inline(val, comments))); } /*inline*/ case StackReference: { ast_t *val = Match(ast, StackReference)->value; - return Texts("&", fmt_inline(val, comments)); + return Texts("&", must(termify_inline(val, comments))); } /*inline*/ case Optional: { ast_t *val = Match(ast, Optional)->value; - return Texts(fmt_inline(val, comments), "?"); + return Texts(must(termify_inline(val, comments)), "?"); } /*inline*/ case NonOptional: { ast_t *val = Match(ast, NonOptional)->value; - return Texts(fmt_inline(val, comments), "!"); + return Texts(must(termify_inline(val, comments)), "!"); } /*inline*/ case FieldAccess: { DeclareMatch(access, ast, FieldAccess); - return Texts(fmt_inline(access->fielded, comments), ".", Text$from_str(access->field)); + return Texts(must(termify_inline(access->fielded, comments)), ".", Text$from_str(access->field)); } /*inline*/ case Index: { DeclareMatch(index, ast, Index); - if (index->index) - return Texts(fmt_inline(index->indexed, comments), "[", fmt_inline(index->index, comments), "]"); - else return Texts(fmt_inline(index->indexed, comments), "[]"); + Text_t indexed = must(termify_inline(index->indexed, comments)); + if (index->index) return Texts(indexed, "[", fmt_inline(index->index, comments), "]"); + else return Texts(indexed, "[]"); } /*inline*/ case TextJoin: { // TODO: choose quotation mark more smartly @@ -231,8 +239,10 @@ OptionalText_t format_inline_code(ast_t *ast, Table_t comments) { } /*inline*/ case MethodCall: { DeclareMatch(call, ast, MethodCall); - return Texts(fmt_inline(call->self, comments), ".", Text$from_str(call->name), "(", - must(format_inline_args(call->args, comments)), ")"); + Text_t self = fmt_inline(call->self, comments); + if (is_binary_operation(call->self) || call->self->tag == Negative || call->self->tag == Not) + self = parenthesize(self, EMPTY_TEXT); + return Texts(self, ".", Text$from_str(call->name), "(", must(format_inline_args(call->args, comments)), ")"); } /*inline*/ case BINOP_CASES: { binary_operands_t operands = BINARY_OPERANDS(ast); @@ -488,35 +498,45 @@ Text_t format_code(ast_t *ast, Table_t comments, Text_t indent) { ast_t *value = Match(ast, Return)->value; return value ? Texts("return ", fmt(value, comments, indent)) : Text("return"); } + /*inline*/ case Not: { + ast_t *val = Match(ast, Not)->value; + if (is_binary_operation(val)) return Texts("not ", termify(val, comments, indent)); + else return Texts("not ", fmt(val, comments, indent)); + } + /*inline*/ case Negative: { + ast_t *val = Match(ast, Negative)->value; + if (is_binary_operation(val)) return Texts("-", termify(val, comments, indent)); + else return Texts("-", fmt(val, comments, indent)); + } /*multiline*/ case HeapAllocate: { if (inlined_fits) return inlined; ast_t *val = Match(ast, HeapAllocate)->value; - return Texts("@(", fmt(val, comments, indent), ")"); + return Texts("@", termify(val, comments, indent), ""); } /*multiline*/ case StackReference: { if (inlined_fits) return inlined; ast_t *val = Match(ast, StackReference)->value; - return Texts("&(", fmt(val, comments, indent), ")"); + return Texts("&(", termify(val, comments, indent), ")"); } /*multiline*/ case Optional: { if (inlined_fits) return inlined; ast_t *val = Match(ast, Optional)->value; - return Texts("(", fmt(val, comments, indent), ")?"); + return Texts(termify(val, comments, indent), "?"); } /*multiline*/ case NonOptional: { if (inlined_fits) return inlined; ast_t *val = Match(ast, NonOptional)->value; - return Texts("(", fmt(val, comments, indent), ")!"); + return Texts(termify(val, comments, indent), "!"); } /*multiline*/ case FieldAccess: { DeclareMatch(access, ast, FieldAccess); - return Texts(fmt(access->fielded, comments, indent), ".", Text$from_str(access->field)); + return Texts(termify(access->fielded, comments, indent), ".", Text$from_str(access->field)); } /*multiline*/ case Index: { DeclareMatch(index, ast, Index); if (index->index) - return Texts(fmt(index->indexed, comments, indent), "[", fmt(index->index, comments, indent), "]"); - else return Texts(fmt(index->indexed, comments, indent), "[]"); + return Texts(termify(index->indexed, comments, indent), "[", fmt(index->index, comments, indent), "]"); + else return Texts(termify(index->indexed, comments, indent), "[]"); } /*multiline*/ case TextJoin: { if (inlined_fits) return inlined; @@ -565,8 +585,8 @@ Text_t format_code(ast_t *ast, Table_t comments, Text_t indent) { /*multiline*/ case MethodCall: { if (inlined_fits) return inlined; DeclareMatch(call, ast, MethodCall); - return Texts(fmt(call->self, comments, indent), ".", Text$from_str(call->name), "(\n", indent, single_indent, - format_args(call->args, comments, Texts(indent, single_indent)), "\n", indent, ")"); + return Texts(termify(call->self, comments, indent), ".", Text$from_str(call->name), "(\n", indent, + single_indent, format_args(call->args, comments, Texts(indent, single_indent)), "\n", indent, ")"); } /*multiline*/ case DocTest: { DeclareMatch(test, ast, DocTest); 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); + } +} diff --git a/src/formatter/utils.h b/src/formatter/utils.h index a8def627..df9c9b92 100644 --- a/src/formatter/utils.h +++ b/src/formatter/utils.h @@ -26,3 +26,5 @@ 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); +OptionalText_t termify_inline(ast_t *ast, Table_t comments); +Text_t termify(ast_t *ast, Table_t comments, Text_t indent); -- cgit v1.2.3