diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2025-08-26 00:32:13 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2025-08-26 00:32:13 -0400 |
| commit | f192834a6405d9a568782b637943588c6af7a8de (patch) | |
| tree | 5ec28d24e220dffdbb2fa581bf6ba70319aff41a /src | |
| parent | 978835e3dd8dd59a1efaa869f2f603eb9eea5a3f (diff) | |
Add more formatting
Diffstat (limited to 'src')
| -rw-r--r-- | src/formatter/args.h | 2 | ||||
| -rw-r--r-- | src/formatter/formatter.c | 376 |
2 files changed, 250 insertions, 128 deletions
diff --git a/src/formatter/args.h b/src/formatter/args.h index 815069a4..42722f32 100644 --- a/src/formatter/args.h +++ b/src/formatter/args.h @@ -11,5 +11,3 @@ 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/formatter.c b/src/formatter/formatter.c index e4c92542..b0fad38a 100644 --- a/src/formatter/formatter.c +++ b/src/formatter/formatter.c @@ -20,28 +20,33 @@ #include "types.h" #include "utils.h" +#define fmt_inline(...) must(format_inline_code(__VA_ARGS__)) +#define fmt(...) format_code(__VA_ARGS__) + 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))); + return Texts("\n", indent, single_indent, fmt(namespace, comments, Texts(indent, single_indent))); } 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) { - case Unknown: fail("Invalid AST"); - case Block: { + /*inline*/ case Unknown: + fail("Invalid AST"); + /*inline*/ case Block: { ast_list_t *statements = Match(ast, Block)->statements; if (statements == NULL) return Text("pass"); - else if (statements->next == NULL) return format_inline_code(statements->ast, comments); + else if (statements->next == NULL) return fmt_inline(statements->ast, comments); else return NONE_TEXT; } - case StructDef: - case EnumDef: - case LangDef: - case Extend: - case FunctionDef: - case DocTest: return NONE_TEXT; - case If: { + /*inline*/ case StructDef: + /*inline*/ case EnumDef: + /*inline*/ case LangDef: + /*inline*/ case Extend: + /*inline*/ case FunctionDef: + /*inline*/ case DocTest: + return NONE_TEXT; + /*inline*/ case If: { DeclareMatch(if_, ast, If); if (if_->else_body == NULL && if_->condition->tag != Declare) { @@ -49,81 +54,122 @@ OptionalText_t format_inline_code(ast_t *ast, Table_t comments) { switch (stmt->tag) { case Return: case Skip: - case Stop: - return Texts(must(format_inline_code(stmt, comments)), " if ", - must(format_inline_code(if_->condition, comments))); + case Stop: return Texts(fmt_inline(stmt, comments), " if ", fmt_inline(if_->condition, comments)); default: break; } } - Text_t code = Texts("if ", must(format_inline_code(if_->condition, comments)), " then ", - must(format_inline_code(if_->body, comments))); - if (if_->else_body) code = Texts(code, " else ", must(format_inline_code(if_->else_body, comments))); + Text_t code = Texts("if ", fmt_inline(if_->condition, comments), " then ", fmt_inline(if_->body, comments)); + if (if_->else_body) code = Texts(code, " else ", fmt_inline(if_->else_body, comments)); return code; } - case Repeat: return Texts("repeat ", must(format_inline_code(Match(ast, Repeat)->body, comments))); - case While: { + /*inline*/ case Repeat: + return Texts("repeat ", fmt_inline(Match(ast, Repeat)->body, comments)); + /*inline*/ case While: { DeclareMatch(loop, ast, While); - return Texts("while ", must(format_inline_code(loop->condition, comments)), " do ", - must(format_inline_code(loop->body, comments))); + return Texts("while ", fmt_inline(loop->condition, comments), " do ", fmt_inline(loop->body, comments)); + } + /*inline*/ case For: { + DeclareMatch(loop, ast, For); + Text_t code = Text("for "); + for (ast_list_t *var = loop->vars; var; var = var->next) { + code = Texts(code, fmt_inline(var->ast, comments)); + if (var->next) code = Texts(code, ", "); + } + code = Texts(code, " in ", fmt_inline(loop->iter, comments), " do ", fmt_inline(loop->body, comments)); + if (loop->empty) code = Texts(code, " else ", fmt_inline(loop->empty, comments)); + return code; } - case List: - case Set: { + /*inline*/ case Comprehension: { + DeclareMatch(comp, ast, Comprehension); + Text_t code = Texts(fmt_inline(comp->expr, comments), " for "); + for (ast_list_t *var = comp->vars; var; var = var->next) { + code = Texts(code, fmt_inline(var->ast, comments)); + if (var->next) code = Texts(code, ", "); + } + code = Texts(code, " in ", fmt_inline(comp->iter, comments)); + if (comp->filter) code = Texts(code, " if ", fmt_inline(comp->filter, comments)); + return code; + } + /*inline*/ case List: + /*inline*/ case Set: { ast_list_t *items = ast->tag == List ? Match(ast, List)->items : Match(ast, Set)->items; Text_t code = EMPTY_TEXT; for (ast_list_t *item = items; item; item = item->next) { - code = Texts(code, must(format_inline_code(item->ast, comments))); + code = Texts(code, fmt_inline(item->ast, comments)); if (item->next) code = Texts(code, ", "); } return ast->tag == List ? Texts("[", code, "]") : Texts("|", code, "|"); } - case Declare: { + /*inline*/ case Table: { + DeclareMatch(table, ast, Table); + Text_t code = EMPTY_TEXT; + for (ast_list_t *entry = table->entries; entry; entry = entry->next) { + code = Texts(code, fmt_inline(entry->ast, comments)); + if (entry->next) code = Texts(code, ", "); + } + if (table->fallback) code = Texts(code, "; fallback=", fmt_inline(table->fallback, comments)); + if (table->default_value) code = Texts(code, "; default=", fmt_inline(table->default_value, comments)); + return Texts("{", code, "}"); + } + /*inline*/ case TableEntry: { + DeclareMatch(entry, ast, TableEntry); + return Texts(fmt_inline(entry->key, comments), "=", fmt_inline(entry->value, comments)); + } + /*inline*/ case Declare: { DeclareMatch(decl, ast, Declare); - Text_t code = must(format_inline_code(decl->var, comments)); + Text_t code = fmt_inline(decl->var, comments); if (decl->type) code = Texts(code, " : ", must(format_inline_type(decl->type, comments))); - if (decl->value) - code = - Texts(code, decl->type ? Text(" = ") : Text(" := "), must(format_inline_code(decl->value, comments))); + if (decl->value) code = Texts(code, decl->type ? Text(" = ") : Text(" := "), fmt_inline(decl->value, comments)); return code; } - case Assign: { + /*inline*/ case Assign: { DeclareMatch(assign, ast, Assign); Text_t code = EMPTY_TEXT; for (ast_list_t *target = assign->targets; target; target = target->next) { - code = Texts(code, must(format_inline_code(target->ast, comments))); + code = Texts(code, fmt_inline(target->ast, comments)); if (target->next) code = Texts(code, ", "); } code = Texts(code, " = "); for (ast_list_t *value = assign->values; value; value = value->next) { - code = Texts(code, must(format_inline_code(value->ast, comments))); + code = Texts(code, fmt_inline(value->ast, comments)); if (value->next) code = Texts(code, ", "); } return code; } - case Return: { + /*inline*/ case Pass: + return Text("pass"); + /*inline*/ case Return: { ast_t *value = Match(ast, Return)->value; - return value ? Texts("return ", must(format_inline_code(value, comments))) : Text("return"); + return value ? Texts("return ", fmt_inline(value, comments)) : Text("return"); + } + /*inline*/ case HeapAllocate: { + ast_t *val = Match(ast, HeapAllocate)->value; + return Texts("@", fmt_inline(val, comments)); + } + /*inline*/ case StackReference: { + ast_t *val = Match(ast, StackReference)->value; + return Texts("&", fmt_inline(val, comments)); } - case Optional: { + /*inline*/ case Optional: { ast_t *val = Match(ast, Optional)->value; - return Texts(must(format_inline_code(val, comments)), "?"); + return Texts(fmt_inline(val, comments), "?"); } - case NonOptional: { + /*inline*/ case NonOptional: { ast_t *val = Match(ast, NonOptional)->value; - return Texts(must(format_inline_code(val, comments)), "!"); + return Texts(fmt_inline(val, comments), "!"); } - case FieldAccess: { + /*inline*/ case FieldAccess: { DeclareMatch(access, ast, FieldAccess); - return Texts(must(format_inline_code(access->fielded, comments)), ".", Text$from_str(access->field)); + return Texts(fmt_inline(access->fielded, comments), ".", Text$from_str(access->field)); } - case Index: { + /*inline*/ case Index: { DeclareMatch(index, ast, Index); if (index->index) - return Texts(must(format_inline_code(index->indexed, comments)), "[", - must(format_inline_code(index->index, comments)), "]"); - else return Texts(must(format_inline_code(index->indexed, comments)), "[]"); + return Texts(fmt_inline(index->indexed, comments), "[", fmt_inline(index->index, comments), "]"); + else return Texts(fmt_inline(index->indexed, comments), "[]"); } - case TextJoin: { + /*inline*/ case TextJoin: { // TODO: choose quotation mark more smartly Text_t source = Text$from_strn(ast->start, (int64_t)(ast->end - ast->start)); Text_t quote = Text$to(source, I(1)); @@ -134,42 +180,44 @@ OptionalText_t format_inline_code(ast_t *ast, Table_t comments) { Text_t literal = Match(chunk->ast, TextLiteral)->text; code = Texts(code, Text$slice(Text$quoted(literal, false, quote), I(2), I(-2))); } else { - code = Texts(code, "$(", must(format_inline_code(chunk->ast, comments)), ")"); + code = Texts(code, "$(", fmt_inline(chunk->ast, comments), ")"); } } return Texts(code, quote); } - case TextLiteral: { - fail("Something went wrong, we shouldn't be formatting text literals directly"); - } - case Stop: { + /*inline*/ case TextLiteral: { fail("Something went wrong, we shouldn't be formatting text literals directly"); } + /*inline*/ case Stop: { const char *target = Match(ast, Stop)->target; return target ? Texts("stop ", Text$from_str(target)) : Text("stop"); } - case Skip: { + /*inline*/ case Skip: { const char *target = Match(ast, Skip)->target; return target ? Texts("skip ", Text$from_str(target)) : Text("skip"); } - case None: - case Bool: - case Int: - case Num: - case Var: { + /*inline*/ case None: + /*inline*/ case Bool: + /*inline*/ case Int: + /*inline*/ case Num: + /*inline*/ case Var: { Text_t code = Text$from_strn(ast->start, (int64_t)(ast->end - ast->start)); if (Text$has(code, Text("\n"))) return NONE_TEXT; return code; } - case FunctionCall: { + /*inline*/ case FunctionCall: { DeclareMatch(call, ast, FunctionCall); - return Texts(must(format_inline_code(call->fn, comments)), "(", must(format_inline_args(call->args, comments)), - ")"); + return Texts(fmt_inline(call->fn, comments), "(", must(format_inline_args(call->args, 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)), ")"); } - case BINOP_CASES: { + /*inline*/ case BINOP_CASES: { binary_operands_t operands = BINARY_OPERANDS(ast); const char *op = binop_tomo_operator(ast->tag); - Text_t lhs = must(format_inline_code(operands.lhs, comments)); - Text_t rhs = must(format_inline_code(operands.rhs, comments)); + Text_t lhs = fmt_inline(operands.lhs, comments); + Text_t rhs = fmt_inline(operands.rhs, comments); if (is_update_assignment(ast)) { return Texts(lhs, " ", Text$from_str(op), " ", rhs); @@ -194,8 +242,9 @@ Text_t format_code(ast_t *ast, Table_t comments, Text_t indent) { bool inlined_fits = (inlined.length >= 0 && indent.length + inlined.length <= MAX_WIDTH); switch (ast->tag) { - case Unknown: fail("Invalid AST"); - case Block: { + /*multiline*/ case Unknown: + fail("Invalid AST"); + /*multiline*/ case Block: { Text_t code = EMPTY_TEXT; bool gap_before_comment = false; const char *comment_pos = ast->start; @@ -211,7 +260,7 @@ Text_t format_code(ast_t *ast, Table_t comments, Text_t indent) { add_line(&code, Text$trim(comment, Text(" \t\r\n"), false, true), indent); } - add_line(&code, format_code(stmt->ast, comments, indent), indent); + add_line(&code, fmt(stmt->ast, comments, indent), indent); comment_pos = stmt->ast->end; if (should_have_blank_line(stmt->ast) && stmt->next && !should_have_blank_line(stmt->next->ast)) @@ -228,27 +277,59 @@ Text_t format_code(ast_t *ast, Table_t comments, Text_t indent) { } return code; } - case If: { + /*multiline*/ case If: { DeclareMatch(if_, ast, If); if (inlined_fits && if_->else_body == NULL) return inlined; - Text_t code = Texts("if ", format_code(if_->condition, comments, indent), "\n", indent, single_indent, - format_code(if_->body, comments, Texts(indent, single_indent))); + Text_t code = Texts("if ", fmt(if_->condition, comments, indent), "\n", indent, single_indent, + fmt(if_->body, comments, Texts(indent, single_indent))); if (if_->else_body) code = Texts(code, "\n", indent, "else \n", indent, single_indent, - format_code(if_->else_body, comments, Texts(indent, single_indent))); + fmt(if_->else_body, comments, Texts(indent, single_indent))); return code; } - case Repeat: { + /*multiline*/ case Repeat: { return Texts("repeat\n", indent, single_indent, - format_code(Match(ast, Repeat)->body, comments, Texts(indent, single_indent))); + fmt(Match(ast, Repeat)->body, comments, Texts(indent, single_indent))); } - case While: { + /*multiline*/ case While: { DeclareMatch(loop, ast, While); - return Texts("while ", format_code(loop->condition, comments, indent), "\n", indent, single_indent, - format_code(loop->body, comments, Texts(indent, single_indent))); + return Texts("while ", fmt(loop->condition, comments, indent), "\n", indent, single_indent, + fmt(loop->body, comments, Texts(indent, single_indent))); + } + /*multiline*/ case For: { + DeclareMatch(loop, ast, For); + Text_t code = Text("for "); + for (ast_list_t *var = loop->vars; var; var = var->next) { + code = Texts(code, fmt(var->ast, comments, indent)); + if (var->next) code = Texts(code, ", "); + } + code = Texts(code, " in ", fmt(loop->iter, comments, indent), format_namespace(loop->body, comments, indent)); + if (loop->empty) code = Texts(code, "\n", indent, "else", format_namespace(loop->empty, comments, indent)); + return code; + } + /*multiline*/ case Comprehension: { + if (inlined_fits) return inlined; + DeclareMatch(comp, ast, Comprehension); + Text_t code = Texts("(", fmt(comp->expr, comments, indent)); + if (code.length >= MAX_WIDTH) code = Texts(code, "\n", indent, "for "); + else code = Texts(code, " for "); + + for (ast_list_t *var = comp->vars; var; var = var->next) { + code = Texts(code, fmt(var->ast, comments, indent)); + if (var->next) code = Texts(code, ", "); + } + + code = Texts(code, " in ", fmt(comp->iter, comments, indent)); + + if (comp->filter) { + if (code.length >= MAX_WIDTH) code = Texts(code, "\n", indent, "if "); + else code = Texts(code, " if "); + code = Texts(code, fmt(comp->filter, comments, indent)); + } + return code; } - case FunctionDef: { + /*multiline*/ case FunctionDef: { DeclareMatch(func, ast, FunctionDef); // ast_t *name; // arg_ast_t *args; @@ -256,17 +337,15 @@ Text_t format_code(ast_t *ast, Table_t comments, Text_t indent) { // ast_t *body; // ast_t *cache; // bool is_inline; - Text_t code = - Texts("func ", format_code(func->name, comments, indent), "(", format_args(func->args, comments, indent)); + Text_t code = Texts("func ", fmt(func->name, comments, indent), "(", format_args(func->args, comments, indent)); if (func->ret_type) code = Texts(code, func->args ? Text(" -> ") : Text("-> "), format_type(func->ret_type, comments, indent)); - if (func->cache) code = Texts(code, "; cache=", format_code(func->cache, comments, indent)); + if (func->cache) code = Texts(code, "; cache=", fmt(func->cache, comments, indent)); if (func->is_inline) code = Texts(code, "; inline"); - code = - Texts(code, ")\n", indent, single_indent, format_code(func->body, comments, Texts(indent, single_indent))); + code = Texts(code, ")\n", indent, single_indent, fmt(func->body, comments, Texts(indent, single_indent))); return Texts(code); } - case StructDef: { + /*multiline*/ case StructDef: { DeclareMatch(def, ast, StructDef); Text_t code = Texts("struct ", Text$from_str(def->name), "(", format_args(def->fields, comments, indent)); if (def->secret) code = Texts(code, "; secret"); @@ -274,21 +353,21 @@ Text_t format_code(ast_t *ast, Table_t comments, Text_t indent) { if (def->opaque) code = Texts(code, "; opaque"); return Texts(code, ")", format_namespace(def->namespace, comments, indent)); } - case EnumDef: { + /*multiline*/ case EnumDef: { DeclareMatch(def, ast, EnumDef); Text_t code = Texts("enum ", Text$from_str(def->name), "(", format_tags(def->tags, comments, indent)); return Texts(code, ")", format_namespace(def->namespace, comments, indent)); } - case LangDef: { + /*multiline*/ case LangDef: { DeclareMatch(def, ast, LangDef); return Texts("lang ", Text$from_str(def->name), format_namespace(def->namespace, comments, indent)); } - case Extend: { + /*multiline*/ case Extend: { DeclareMatch(extend, ast, Extend); return Texts("lang ", Text$from_str(extend->name), format_namespace(extend->body, comments, indent)); } - case List: - case Set: { + /*multiline*/ case List: + /*multiline*/ case Set: { if (inlined_fits) return inlined; ast_list_t *items = ast->tag == List ? Match(ast, List)->items : Match(ast, Set)->items; Text_t code = EMPTY_TEXT; @@ -298,7 +377,7 @@ Text_t format_code(ast_t *ast, Table_t comments, Text_t indent) { (comment = next_comment(comments, &comment_pos, item->ast->start)).length > 0;) { add_line(&code, Text$trim(comment, Text(" \t\r\n"), false, true), Texts(indent, single_indent)); } - add_line(&code, Texts(format_code(item->ast, comments, Texts(indent, single_indent)), ","), + add_line(&code, Texts(fmt(item->ast, comments, Texts(indent, single_indent)), ","), Texts(indent, single_indent)); } for (OptionalText_t comment; (comment = next_comment(comments, &comment_pos, ast->end)).length > 0;) { @@ -307,54 +386,95 @@ Text_t format_code(ast_t *ast, Table_t comments, Text_t indent) { return ast->tag == List ? Texts("[\n", indent, single_indent, code, "\n", indent, "]") : Texts("|\n", indent, single_indent, code, "\n", indent, "|"); } - case Declare: { + /*multiline*/ case Table: { + if (inlined_fits) return inlined; + DeclareMatch(table, ast, Table); + Text_t code = EMPTY_TEXT; + const char *comment_pos = ast->start; + for (ast_list_t *entry = table->entries; entry; entry = entry->next) { + for (OptionalText_t comment; + (comment = next_comment(comments, &comment_pos, entry->ast->start)).length > 0;) { + add_line(&code, Text$trim(comment, Text(" \t\r\n"), false, true), Texts(indent, single_indent)); + } + add_line(&code, Texts(fmt(entry->ast, comments, Texts(indent, single_indent)), ","), + Texts(indent, single_indent)); + } + for (OptionalText_t comment; (comment = next_comment(comments, &comment_pos, ast->end)).length > 0;) { + add_line(&code, Text$trim(comment, Text(" \t\r\n"), false, true), Texts(indent, single_indent)); + } + + if (table->fallback) + code = Texts(code, ";\n", indent, single_indent, "fallback=", fmt(table->fallback, comments, indent)); + + if (table->default_value) + code = Texts(code, ";\n", indent, single_indent, "default=", fmt(table->default_value, comments, indent)); + + return Texts("{\n", indent, single_indent, code, "\n", indent, "}"); + } + /*multiline*/ case TableEntry: { + if (inlined_fits) return inlined; + DeclareMatch(entry, ast, TableEntry); + return Texts(fmt(entry->key, comments, indent), "=", fmt(entry->value, comments, indent)); + } + /*multiline*/ case Declare: { DeclareMatch(decl, ast, Declare); - Text_t code = format_code(decl->var, comments, indent); + Text_t code = fmt(decl->var, comments, indent); if (decl->type) code = Texts(code, " : ", format_type(decl->type, comments, indent)); if (decl->value) - code = Texts(code, decl->type ? Text(" = ") : Text(" := "), format_code(decl->value, comments, indent)); + code = Texts(code, decl->type ? Text(" = ") : Text(" := "), fmt(decl->value, comments, indent)); return code; } - case Assign: { + /*multiline*/ case Assign: { DeclareMatch(assign, ast, Assign); Text_t code = EMPTY_TEXT; for (ast_list_t *target = assign->targets; target; target = target->next) { - code = Texts(code, format_code(target->ast, comments, indent)); + code = Texts(code, fmt(target->ast, comments, indent)); if (target->next) code = Texts(code, ", "); } code = Texts(code, " = "); for (ast_list_t *value = assign->values; value; value = value->next) { - code = Texts(code, format_code(value->ast, comments, indent)); + code = Texts(code, fmt(value->ast, comments, indent)); if (value->next) code = Texts(code, ", "); } return code; } - case Return: { + /*multiline*/ case Pass: + return Text("pass"); + /*multiline*/ case Return: { ast_t *value = Match(ast, Return)->value; - return value ? Texts("return ", format_code(value, comments, indent)) : Text("return"); + return value ? Texts("return ", fmt(value, comments, indent)) : Text("return"); + } + /*multiline*/ case HeapAllocate: { + if (inlined_fits) return inlined; + ast_t *val = Match(ast, HeapAllocate)->value; + return Texts("@(", fmt(val, comments, indent), ")"); } - case Optional: { + /*multiline*/ case StackReference: { + if (inlined_fits) return inlined; + ast_t *val = Match(ast, StackReference)->value; + return Texts("&(", fmt(val, comments, indent), ")"); + } + /*multiline*/ case Optional: { if (inlined_fits) return inlined; ast_t *val = Match(ast, Optional)->value; - return Texts("(", format_code(val, comments, indent), ")?"); + return Texts("(", fmt(val, comments, indent), ")?"); } - case NonOptional: { + /*multiline*/ case NonOptional: { if (inlined_fits) return inlined; ast_t *val = Match(ast, NonOptional)->value; - return Texts("(", format_code(val, comments, indent), ")!"); + return Texts("(", fmt(val, comments, indent), ")!"); } - case FieldAccess: { + /*multiline*/ case FieldAccess: { DeclareMatch(access, ast, FieldAccess); - return Texts(format_code(access->fielded, comments, indent), ".", Text$from_str(access->field)); + return Texts(fmt(access->fielded, comments, indent), ".", Text$from_str(access->field)); } - case Index: { + /*multiline*/ case Index: { DeclareMatch(index, ast, Index); if (index->index) - return Texts(format_code(index->indexed, comments, indent), "[", - format_code(index->index, comments, indent), "]"); - else return Texts(format_code(index->indexed, comments, indent), "[]"); + return Texts(fmt(index->indexed, comments, indent), "[", fmt(index->index, comments, indent), "]"); + else return Texts(fmt(index->indexed, comments, indent), "[]"); } - case TextJoin: { + /*multiline*/ case TextJoin: { if (inlined_fits) return inlined; // TODO: choose quotation mark more smartly Text_t source = Text$from_strn(ast->start, (int64_t)(ast->end - ast->start)); @@ -373,7 +493,7 @@ Text_t format_code(ast_t *ast, Table_t comments, Text_t indent) { current_line = *(Text_t *)(lines.data + i * lines.stride); } } else { - code = Texts(code, "$(", must(format_inline_code(chunk->ast, comments)), ")"); + code = Texts(code, "$(", fmt_inline(chunk->ast, comments), ")"); } } add_line(&code, current_line, Texts(indent, single_indent)); @@ -381,42 +501,46 @@ Text_t format_code(ast_t *ast, Table_t comments, Text_t indent) { if (lang) code = Texts("$", Text$from_str(lang), code); return code; } - case TextLiteral: { - fail("Something went wrong, we shouldn't be formatting text literals directly"); - } - case Stop: - case Skip: - case None: - case Bool: - case Int: - case Num: - case Var: { + /*multiline*/ case TextLiteral: { fail("Something went wrong, we shouldn't be formatting text literals directly"); } + /*multiline*/ case Stop: + /*multiline*/ case Skip: + /*multiline*/ case None: + /*multiline*/ case Bool: + /*multiline*/ case Int: + /*multiline*/ case Num: + /*multiline*/ case Var: { assert(inlined.length >= 0); return inlined; } - case FunctionCall: { + /*multiline*/ case FunctionCall: { if (inlined_fits) return inlined; DeclareMatch(call, ast, FunctionCall); - return Texts(format_code(call->fn, comments, indent), "(\n", indent, single_indent, + return Texts(fmt(call->fn, comments, indent), "(\n", indent, single_indent, + format_args(call->args, comments, Texts(indent, single_indent)), "\n", 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, ")"); } - case DocTest: { + /*multiline*/ case DocTest: { DeclareMatch(test, ast, DocTest); - Text_t expr = format_code(test->expr, comments, indent); + Text_t expr = fmt(test->expr, comments, indent); Text_t code = Texts(">> ", Text$replace(expr, Texts("\n", indent), Texts("\n", indent, ".. "))); if (test->expected) { - Text_t expected = format_code(test->expected, comments, indent); + Text_t expected = fmt(test->expected, comments, indent); code = Texts(code, "\n", indent, "= ", Text$replace(expected, Texts("\n", indent), Texts("\n", indent, ".. "))); } return code; } - case BINOP_CASES: { + /*multiline*/ case BINOP_CASES: { if (inlined_fits) return inlined; binary_operands_t operands = BINARY_OPERANDS(ast); const char *op = binop_tomo_operator(ast->tag); - Text_t lhs = format_code(operands.lhs, comments, indent); - Text_t rhs = format_code(operands.rhs, comments, indent); + Text_t lhs = fmt(operands.lhs, comments, indent); + Text_t rhs = fmt(operands.rhs, comments, indent); if (is_update_assignment(ast)) { return Texts(lhs, " ", Text$from_str(op), " ", rhs); @@ -469,7 +593,7 @@ Text_t format_file(const char *path) { for (OptionalText_t comment; (comment = next_comment(ctx.comments, &fmt_pos, ast->start)).length > 0;) { code = Texts(code, Text$trim(comment, Text(" \t\r\n"), false, true), "\n"); } - code = Texts(code, format_code(ast, ctx.comments, EMPTY_TEXT)); + code = Texts(code, fmt(ast, ctx.comments, EMPTY_TEXT)); for (OptionalText_t comment; (comment = next_comment(ctx.comments, &fmt_pos, ast->start)).length > 0;) { code = Texts(code, Text$trim(comment, Text(" \t\r\n"), false, true), "\n"); } |
