more work on fmt

This commit is contained in:
Daniel Gavin
2021-04-12 17:01:43 +02:00
parent e0e6bba865
commit 9139ca4673
2 changed files with 1117 additions and 924 deletions

View File

@@ -0,0 +1,143 @@
package odin_printer
import "core:odin/ast"
import "core:odin/tokenizer"
import "core:strings"
import "core:runtime"
import "core:fmt"
import "core:unicode/utf8"
import "core:mem"
Line :: struct {
format_tokens: [dynamic] Format_Token,
finalized: bool,
used: bool,
depth: int,
}
Format_Token :: struct {
kind: tokenizer.Token_Kind,
text: string,
spaces_before: int,
}
Printer :: struct {
string_builder: strings.Builder,
config: Config,
depth: int, //the identation depth
comments: [dynamic]^ast.Comment_Group,
allocator: mem.Allocator,
file: ^ast.File,
source_position: tokenizer.Pos,
lines: map [int]^Line,
skip_semicolon: bool,
current_line: ^Line,
current_line_index: int,
last_token: ^Format_Token,
}
Config :: struct {
spaces: int, //Spaces per indentation
newline_limit: int, //The limit of newlines between statements and declarations.
tabs: bool, //Enable or disable tabs
convert_do: bool, //Convert all do statements to brace blocks
semicolons: bool, //Enable semicolons
split_multiple_stmts: bool,
brace_style: Brace_Style,
align_assignments: bool,
align_style: Alignment_Style,
indent_cases: bool,
}
Brace_Style :: enum {
_1TBS,
Allman,
Stroustrup,
K_And_R,
}
Block_Type :: enum {
None,
If_Stmt,
Proc,
Generic,
Comp_Lit,
}
Alignment_Style :: enum {
Align_On_Colon_And_Equals,
Align_On_Type_And_Equals,
}
default_style := Config {
spaces = 4,
newline_limit = 2,
convert_do = false,
semicolons = true,
tabs = true,
brace_style = ._1TBS,
split_multiple_stmts = true,
align_assignments = true,
align_style = .Align_On_Type_And_Equals,
indent_cases = false,
};
make_printer :: proc(config: Config, allocator := context.allocator) -> Printer {
return {
config = config,
allocator = allocator,
};
}
print :: proc(p: ^Printer, file: ^ast.File) -> string {
for decl in file.decls {
visit_stmt(p, decl);
}
fix_lines(p);
builder := strings.make_builder(p.allocator);
last_line := 0;
for key, value in p.lines {
diff_line := min(key - last_line, p.config.newline_limit);
for i := 0; i < diff_line; i += 1 {
strings.write_byte(&builder, '\n');
}
for i := 0; i < value.depth * 4; i += 1 {
strings.write_byte(&builder, ' ');
}
for format_token in value.format_tokens {
for i := 0; i < format_token.spaces_before; i += 1 {
strings.write_byte(&builder, ' ');
}
strings.write_string(&builder, format_token.text);
}
last_line = key;
}
return strings.to_string(builder);
}
fix_lines :: proc(p: ^Printer) {
for key, value in p.lines {
if len(value.format_tokens) <= 0 {
continue;
}
}
}

File diff suppressed because it is too large Load Diff