From 5a8c7b4f90a3f48ed2bbd574cac0b38862e4742d Mon Sep 17 00:00:00 2001 From: Daniel Gavin Date: Fri, 16 Apr 2021 02:15:29 +0200 Subject: [PATCH] support multiline for and if --- core/odin/printer/printer.odin | 131 ++++++++++++++++++++++++++++++++- core/odin/printer/visit.odin | 9 +++ 2 files changed, 137 insertions(+), 3 deletions(-) diff --git a/core/odin/printer/printer.odin b/core/odin/printer/printer.odin index 98a7e9ade..700d9ef63 100644 --- a/core/odin/printer/printer.odin +++ b/core/odin/printer/printer.odin @@ -8,7 +8,7 @@ import "core:fmt" import "core:unicode/utf8" import "core:mem" -Type_Enum :: enum {Line_Comment, Value_Decl, Switch_Stmt, Struct, Assign, Call, Enum} +Type_Enum :: enum {Line_Comment, Value_Decl, Switch_Stmt, Struct, Assign, Call, Enum, If, For} Line_Type :: bit_set[Type_Enum]; @@ -320,13 +320,130 @@ format_call :: proc(p: ^Printer, index: int) { return; } + } +} + +format_for :: proc(p: ^Printer, index: int) { + + for_found := false; + for_token: Format_Token; + for_line: int; + largest := 0; + + found_for: for line, line_index in p.lines[index:] { + for format_token in line.format_tokens { + + largest += len(format_token.text) + format_token.spaces_before; + + if format_token.kind == .For { + for_token = format_token; + for_line = line_index + index; + for_found = true; + break found_for; + } + } + } + + if !for_found { + return; + } + + brace_count := 0; + done := false; + + for line, line_index in p.lines[for_line:] { + + if len(line.format_tokens) == 0 { + continue; + } + + for format_token, i in line.format_tokens { + + if format_token.kind == .Open_Brace { + brace_count += 1; + } else if format_token.kind == .Close_Brace { + brace_count -= 1; + } + + if brace_count == 1 { + done = true; + } + + } + + if line_index != 0 { + line.format_tokens[0].spaces_before += largest + 1; + } + + if done { + return; + } + + } + +} + +format_if :: proc(p: ^Printer, index: int) { + + if_found := false; + if_token: Format_Token; + if_line: int; + largest := 0; + + found_if: for line, line_index in p.lines[index:] { + for format_token in line.format_tokens { + + largest += len(format_token.text) + format_token.spaces_before; + + if format_token.kind == .If { + if_token = format_token; + if_line = line_index + index; + if_found = true; + break found_if; + } + } + } + + if !if_found { + return; + } + + brace_count := 0; + done := false; + + for line, line_index in p.lines[if_line:] { + + if len(line.format_tokens) == 0 { + continue; + } + + for format_token, i in line.format_tokens { + + if format_token.kind == .Open_Brace { + brace_count += 1; + } else if format_token.kind == .Close_Brace { + brace_count -= 1; + } + + if brace_count == 1 { + done = true; + } + + } + + if line_index != 0 { + line.format_tokens[0].spaces_before += largest + 1; + } + + if done { + break; + } } - - } + format_generic :: proc(p: ^Printer) { for line, line_index in p.lines { @@ -354,6 +471,14 @@ format_generic :: proc(p: ^Printer) { if .Call in line.types { format_call(p, line_index); } + + if .If in line.types { + format_if(p, line_index); + } + + if .For in line.types { + format_for(p, line_index); + } } } diff --git a/core/odin/printer/visit.odin b/core/odin/printer/visit.odin index d8ec98e17..36c8c42d9 100644 --- a/core/odin/printer/visit.odin +++ b/core/odin/printer/visit.odin @@ -587,6 +587,8 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener push_generic_token(p, .If, 1); + hint_current_line(p, {.If}); + if v.init != nil { p.skip_semicolon = true; visit_stmt(p, v.init); @@ -724,6 +726,8 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener push_generic_token(p, .For, 1); + hint_current_line(p, {.For}); + if v.init != nil { p.skip_semicolon = true; visit_stmt(p, v.init); @@ -759,6 +763,9 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener push_ident_token(p, "#unroll", 0); push_generic_token(p, .For, 1); + + hint_current_line(p, {.For}); + visit_expr(p, v.val0); if v.val1 != nil { @@ -781,6 +788,8 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener push_generic_token(p, .For, 1); + hint_current_line(p, {.For}); + if len(v.vals) >= 1 { visit_expr(p, v.vals[0]); }