Przeglądaj źródła

ran the odinfmt - looks good, except for multi line binary operations

Daniel Gavin 4 lat temu
rodzic
commit
22daa50374
2 zmienionych plików z 1442 dodań i 1466 usunięć
  1. 315 331
      core/odin/printer/printer.odin
  2. 1127 1135
      core/odin/printer/visit.odin

+ 315 - 331
core/odin/printer/printer.odin

@@ -8,483 +8,467 @@ import "core:fmt"
 import "core:unicode/utf8"
 import "core:mem"
 
-Line_Type_Enum :: enum{Line_Comment, Value_Decl, Switch_Stmt, Struct};
+Line_Type_Enum :: enum {Line_Comment, Value_Decl, Switch_Stmt, Struct}
 
 Line_Type :: bit_set[Line_Type_Enum];
 
 Line :: struct {
     format_tokens: [dynamic] Format_Token,
-    finalized: bool,
-    used: bool,
-	depth: int,
-	types: Line_Type, //for performance, so you don't have to verify what types are in it by going through the tokens - might give problems when adding linebreaking
+    finalized:     bool,
+    used:          bool,
+    depth:         int,
+    types:         Line_Type, //for performance, so you don't have to verify what types are in it by going through the tokens - might give problems when adding linebreaking
 }
 
 Format_Token :: struct {
-    kind: tokenizer.Token_Kind,
-    text: string,
-    spaces_before: int,
-	parameter_count: int,
+    kind:            tokenizer.Token_Kind,
+    text:            string,
+    spaces_before:   int,
+    parameter_count: int,
 }
 
 Printer :: struct {
-	string_builder:       strings.Builder,
-	config:               Config,
-	depth:                int, //the identation depth
-	comments:             [dynamic]^ast.Comment_Group,
-	latest_comment_index: int,
-	allocator:            mem.Allocator,
-	file:                 ^ast.File,
+    string_builder:       strings.Builder,
+    config:               Config,
+    depth:                int, //the identation depth
+    comments:             [dynamic] ^ast.Comment_Group,
+    latest_comment_index: int,
+    allocator:            mem.Allocator,
+    file:                 ^ast.File,
     source_position:      tokenizer.Pos,
-	last_source_position: tokenizer.Pos,
+    last_source_position: tokenizer.Pos,
     lines:                [dynamic] Line, //need to look into a better data structure, one that can handle inserting lines rather than appending
     skip_semicolon:       bool,
-	current_line:         ^Line,
-	current_line_index:   int,
-	last_line_index:      int,
-	last_token:           ^Format_Token,
-	merge_next_token:     bool,
-	space_next_token:     bool,
-	debug:                bool,
+    current_line:         ^Line,
+    current_line_index:   int,
+    last_line_index:      int,
+    last_token:           ^Format_Token,
+    merge_next_token:     bool,
+    space_next_token:     bool,
+    debug:                bool,
 }
 
 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,
-	align_switch:         bool,
-	brace_style:          Brace_Style,
-	align_assignments:    bool,
-	align_structs:        bool,
-	align_style:          Alignment_Style,
-	indent_cases:         bool,
-	newline_style:        Newline_Style,
+    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,
+    align_switch:         bool,
+    brace_style:          Brace_Style,
+    align_assignments:    bool,
+    align_structs:        bool,
+    align_style:          Alignment_Style,
+    indent_cases:         bool,
+    newline_style:        Newline_Style,
 }
 
 Brace_Style :: enum {
-	_1TBS,
-	Allman,
-	Stroustrup,
-	K_And_R,
+    _1TBS,
+    Allman,
+    Stroustrup,
+    K_And_R,
 }
 
 Block_Type :: enum {
-	None,
-	If_Stmt,
-	Proc,
-	Generic,
-	Comp_Lit,
-	Switch_Stmt,
+    None,
+    If_Stmt,
+    Proc,
+    Generic,
+    Comp_Lit,
+    Switch_Stmt,
 }
 
 Alignment_Style :: enum {
-	Align_On_Colon_And_Equals,
-	Align_On_Type_And_Equals,
+    Align_On_Colon_And_Equals,
+    Align_On_Type_And_Equals,
 }
 
 Newline_Style :: enum {
-	CRLF,
-	LF,
+    CRLF,
+    LF,
 }
 
 default_style := Config {
-	spaces = 4,
-	newline_limit = 2,
-	convert_do = false,
-	semicolons = true,
-	tabs = false,
-	brace_style = ._1TBS,
-	split_multiple_stmts = true,
-	align_assignments = true,
-	align_style = .Align_On_Type_And_Equals,
-	indent_cases = false,
-	align_switch = true,
-	align_structs = true,
-	newline_style = .LF,
+    spaces = 4,
+    newline_limit = 2,
+    convert_do = false,
+    semicolons = true,
+    tabs = false,
+    brace_style = ._1TBS,
+    split_multiple_stmts = true,
+    align_assignments = true,
+    align_style = .Align_On_Type_And_Equals,
+    indent_cases = false,
+    align_switch = true,
+    align_structs = true,
+    newline_style = .CRLF,
 };
 
 make_printer :: proc(config: Config, allocator := context.allocator) -> Printer {
-	return {
-		config = config,
-		allocator = allocator,
-		debug = false,
-	};
+    return {
+        config = config,
+        allocator = allocator,
+        debug = false,
+    };
 }
 
 print :: proc(p: ^Printer, file: ^ast.File) -> string {
 
-	p.comments = file.comments;
-	
-	if len(file.decls) > 0 {
-		p.lines = make([dynamic] Line, 0, (file.decls[len(file.decls)-1].end.line - file.decls[0].pos.line) * 2, context.temp_allocator);
-	}
+    p.comments = file.comments;
 
-	set_line(p, 0);
+    if len(file.decls) > 0 {
+        p.lines = make([dynamic] Line, 0, (file.decls[len(file.decls) - 1].end.line - file.decls[0].pos.line) * 2, context.temp_allocator);
+    }
+
+    set_line(p, 0);
 
-	push_generic_token(p, .Package, 0);
-	push_ident_token(p, file.pkg_name, 1);
+    push_generic_token(p, .Package, 0);
+    push_ident_token(p, file.pkg_name, 1);
 
     for decl in file.decls {
         visit_decl(p, cast(^ast.Decl)decl);
     }
 
-	if len(p.comments) > 0 {
-		infinite := p.comments[len(p.comments)-1].end;
-		infinite.offset = 9999999;
-		push_comments(p, infinite);
-	}
+    if len(p.comments) > 0 {
+        infinite := p.comments[len(p.comments) - 1].end;
+        infinite.offset = 9999999;
+        push_comments(p, infinite);
+    }
 
-	fix_lines(p);
+    fix_lines(p);
 
     builder := strings.make_builder(0, mem.megabytes(5), p.allocator);
 
     last_line := 0;
 
-	newline: string;
+    newline: string;
 
-	if p.config.newline_style == .LF {
-		newline = "\n";
-	} else {
-		newline = "\r\n";
-	}
+    if p.config.newline_style == .LF {
+        newline = "\n";
+    } else {
+        newline = "\r\n";
+    }
 
     for line, line_index in p.lines {
         diff_line := line_index - last_line;
 
-		for i := 0; i < diff_line; i += 1 {
-			strings.write_string(&builder, newline);
-		}
-		
-		if p.config.tabs {
-			for i := 0; i < line.depth; i += 1 {
-				strings.write_byte(&builder, '\t');
-			}
-		} else {
-			for i := 0; i < line.depth * p.config.spaces; i += 1 {
-				strings.write_byte(&builder, ' ');
-			}
-		}
-
-		if p.debug {
-			strings.write_string(&builder, fmt.tprintf("line %v: ", line_index));
-		}
-
-		for format_token in line.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 = line_index;
+        for i := 0; i < diff_line; i += 1 {
+            strings.write_string(&builder, newline);
+        }
+
+        if p.config.tabs {
+            for i := 0; i < line.depth; i += 1 {
+                strings.write_byte(&builder, '\t');
+            }
+        } else {
+            for i := 0; i < line.depth * p.config.spaces; i += 1 {
+                strings.write_byte(&builder, ' ');
+            }
+        }
+
+        if p.debug {
+            strings.write_string(&builder, fmt.tprintf("line %v: ", line_index));
+        }
+
+        for format_token in line.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 = line_index;
     }
 
     return strings.to_string(builder);
 }
 
 fix_lines :: proc(p: ^Printer) {
-	align_var_decls(p);
-	align_blocks(p);
-	align_comments(p); //align them last since they rely on the other alignments
+    align_var_decls(p);
+    align_blocks(p);
+    align_comments(p); //align them last since they rely on the other alignments
 }
 
 align_var_decls :: proc(p: ^Printer) {
-
 }
 
 align_switch_smt :: proc(p: ^Printer, index: int) {
 
-	switch_found := false;
-	brace_token: Format_Token;
-	brace_line: int;
-
-	found_switch_brace: for line, line_index in p.lines[index:] {
-
-		for format_token in line.format_tokens {
-
-			if format_token.kind == .Open_Brace && switch_found {
-				brace_token = format_token;
-				brace_line = line_index+index;
-				break found_switch_brace;
-			} else if format_token.kind == .Open_Brace {
-				break;
-			} else if format_token.kind == .Switch {
-				switch_found = true;
-			}
-
-		}
+    switch_found := false;
+    brace_token: Format_Token;
+    brace_line: int;
 
-	}
+    found_switch_brace: for line, line_index in p.lines[index:] {
 
-	if !switch_found {
-		return;
-	}
+        for format_token in line.format_tokens {
 
-	largest := 0;
-	case_count := 0;
-
-	//find all the switch cases that are one lined
-	for line, line_index in p.lines[brace_line+1:] {
+            if format_token.kind == .Open_Brace && switch_found {
+                brace_token = format_token;
+                brace_line = line_index + index;
+                break found_switch_brace;
+            } else if format_token.kind == .Open_Brace {
+                break;
+            } else if format_token.kind == .Switch {
+                switch_found = true;
+            }
+        }
+    }
 
-		case_found := false;
-		colon_found := false;
-		length := 0;
+    if !switch_found {
+        return;
+    }
 
-		for format_token in line.format_tokens {
+    largest := 0;
+    case_count := 0;
 
-			if format_token.kind == .Comment {
-				continue;
-			}
+    //find all the switch cases that are one lined
+    for line, line_index in p.lines[brace_line + 1:] {
 
-			//this will only happen if the case is one lined
-			if case_found && colon_found {
-				largest = max(length, largest);
-				break;
-			}
+        case_found := false;
+        colon_found := false;
+        length := 0;
 
-			if format_token.kind == .Case {
-				case_found = true;
-				case_count += 1;
-			} else if format_token.kind == .Colon {
-				colon_found = true;
-			} 
+        for format_token in line.format_tokens {
 
-			length += len(format_token.text) + format_token.spaces_before;
-		}
+            if format_token.kind == .Comment {
+                continue;
+            }
 
-		if case_count >= brace_token.parameter_count {
-			break;
-		}
+            //this will only happen if the case is one lined
+            if case_found && colon_found {
+                largest = max(length, largest);
+                break;
+            }
 
-	}
+            if format_token.kind == .Case {
+                case_found = true;
+                case_count += 1;
+            } else if format_token.kind == .Colon {
+                colon_found = true;
+            }
 
-	case_count = 0;
+            length += len(format_token.text) + format_token.spaces_before;
+        }
 
-	for line, line_index in p.lines[brace_line+1:] {
+        if case_count >= brace_token.parameter_count {
+            break;
+        }
+    }
 
-		case_found := false;
-		colon_found := false;
-		length := 0;
+    case_count = 0;
 
-		for format_token, i in line.format_tokens {
+    for line, line_index in p.lines[brace_line + 1:] {
 
-			if format_token.kind == .Comment {
-				continue;
-			}
+        case_found := false;
+        colon_found := false;
+        length := 0;
 
-			//this will only happen if the case is one lined
-			if case_found && colon_found {
-				line.format_tokens[i].spaces_before += (largest - length);
-				break;
-			}
+        for format_token, i in line.format_tokens {
 
-			if format_token.kind == .Case {
-				case_found = true;
-				case_count += 1;
-			} else if format_token.kind == .Colon {
-				colon_found = true;
-			} 
+            if format_token.kind == .Comment {
+                continue;
+            }
 
-			length += len(format_token.text) + format_token.spaces_before;
+            //this will only happen if the case is one lined
+            if case_found && colon_found {
+                line.format_tokens[i].spaces_before += (largest - length);
+                break;
+            }
 
-		}
+            if format_token.kind == .Case {
+                case_found = true;
+                case_count += 1;
+            } else if format_token.kind == .Colon {
+                colon_found = true;
+            }
 
-		if case_count >= brace_token.parameter_count {
-			break;
-		}
-	}
+            length += len(format_token.text) + format_token.spaces_before;
+        }
 
+        if case_count >= brace_token.parameter_count {
+            break;
+        }
+    }
 }
 
 align_struct :: proc(p: ^Printer, index: int) {
 
-	struct_found := false;
-	brace_token: Format_Token;
-	brace_line: int;
-
-	found_struct_brace: for line, line_index in p.lines[index:] {
-
-		for format_token in line.format_tokens {
+    struct_found := false;
+    brace_token: Format_Token;
+    brace_line: int;
 
-			if format_token.kind == .Open_Brace && struct_found {
-				brace_token = format_token;
-				brace_line = line_index+index;
-				break found_struct_brace;
-			} else if format_token.kind == .Open_Brace {
-				break;
-			} else if format_token.kind == .Struct {
-				struct_found = true;
-			}
+    found_struct_brace: for line, line_index in p.lines[index:] {
 
-		}
+        for format_token in line.format_tokens {
 
-	}
-
-	if !struct_found {
-		return;
-	}
+            if format_token.kind == .Open_Brace && struct_found {
+                brace_token = format_token;
+                brace_line = line_index + index;
+                break found_struct_brace;
+            } else if format_token.kind == .Open_Brace {
+                break;
+            } else if format_token.kind == .Struct {
+                struct_found = true;
+            }
+        }
+    }
 
-	largest := 0;
-	colon_count := 0;
+    if !struct_found {
+        return;
+    }
 
-	for line, line_index in p.lines[brace_line+1:] {
+    largest := 0;
+    colon_count := 0;
 
-		length := 0;
+    for line, line_index in p.lines[brace_line + 1:] {
 
-		for format_token in line.format_tokens {
+        length := 0;
 
-			if format_token.kind == .Comment {
-				continue;
-			}
+        for format_token in line.format_tokens {
 
-			if format_token.kind == .Colon {
-				colon_count += 1;
-				largest = max(length, largest);
-				break;
-			} 
+            if format_token.kind == .Comment {
+                continue;
+            }
 
-			length += len(format_token.text) + format_token.spaces_before;
-		}
+            if format_token.kind == .Colon {
+                colon_count += 1;
+                largest = max(length, largest);
+                break;
+            }
 
-		if colon_count >= brace_token.parameter_count {
-			break;
-		}
-	}
+            length += len(format_token.text) + format_token.spaces_before;
+        }
 
-	colon_count = 0;
+        if colon_count >= brace_token.parameter_count {
+            break;
+        }
+    }
 
-	for line, line_index in p.lines[brace_line+1:] {
+    colon_count = 0;
 
-		length := 0;
+    for line, line_index in p.lines[brace_line + 1:] {
 
-		for format_token, i in line.format_tokens {
+        length := 0;
 
-			if format_token.kind == .Comment {
-				continue;
-			}
+        for format_token, i in line.format_tokens {
 
-			if format_token.kind == .Colon {
-				colon_count += 1;
-				line.format_tokens[i+1].spaces_before = largest - length + 1;
-				break;
-			} 
+            if format_token.kind == .Comment {
+                continue;
+            }
 
-			length += len(format_token.text) + format_token.spaces_before;
-		}
+            if format_token.kind == .Colon {
+                colon_count += 1;
+                line.format_tokens[i + 1].spaces_before = largest - length + 1;
+                break;
+            }
 
-		if colon_count >= brace_token.parameter_count {
-			break;
-		}
-	}
+            length += len(format_token.text) + format_token.spaces_before;
+        }
 
+        if colon_count >= brace_token.parameter_count {
+            break;
+        }
+    }
 }
 
 align_blocks :: proc(p: ^Printer) {
 
-	for line, line_index in p.lines {
-
-		if len(line.format_tokens) <= 0 {
-			continue;
-		}
+    for line, line_index in p.lines {
 
-		if .Switch_Stmt in line.types && p.config.align_switch {
-			align_switch_smt(p, line_index);
-		} 
-		
-		if .Struct in line.types && p.config.align_structs {
-			align_struct(p, line_index);
-		}
+        if len(line.format_tokens) <= 0 {
+            continue;
+        }
 
-	}
+        if .Switch_Stmt in line.types && p.config.align_switch {
+            align_switch_smt(p, line_index);
+        }
 
+        if .Struct in line.types && p.config.align_structs {
+            align_struct(p, line_index);
+        }
+    }
 }
 
 align_comments :: proc(p: ^Printer) {
-	
-	Comment_Align_Info :: struct {
-		length: int,
-		begin: int,
-		end: int,
-		depth: int,
-	};
-
-	comment_infos := make([dynamic]Comment_Align_Info, 0, context.temp_allocator);
-
-	current_info: Comment_Align_Info;
-
-	for line, line_index in p.lines {
-
-		if len(line.format_tokens) <= 0 {
-			continue;
-		}
 
-		if .Line_Comment in line.types {
+    Comment_Align_Info :: struct {
+        length: int,
+        begin:  int,
+        end:    int,
+        depth:  int,
+    };
 
-			if current_info.end + 1 != line_index || current_info.depth != line.depth ||
-			   (current_info.begin == current_info.end && current_info.length == 0) {
+    comment_infos := make([dynamic] Comment_Align_Info, 0, context.temp_allocator);
 
-				if (current_info.begin != 0 && current_info.end != 0) || current_info.length > 0 {
-					append(&comment_infos, current_info);
-				}
+    current_info: Comment_Align_Info;
 
-				current_info.begin = line_index;
-				current_info.end = line_index;
-				current_info.depth = line.depth;
-				current_info.length = 0;
-			}
+    for line, line_index in p.lines {
 
-			length := 0;
+        if len(line.format_tokens) <= 0 {
+            continue;
+        }
 
-			for format_token, i in line.format_tokens {
+        if .Line_Comment in line.types {
 
-				if format_token.kind == .Comment {
-					current_info.length = max(current_info.length, length);
-					current_info.end = line_index;
-				}
+            if current_info.end + 1 != line_index || current_info.depth != line.depth ||
+            (current_info.begin == current_info.end && current_info.length == 0) {
 
-				length += format_token.spaces_before + len(format_token.text);
-			}
+                if (current_info.begin != 0 && current_info.end != 0) || current_info.length > 0 {
+                    append(&comment_infos, current_info);
+                }
 
-		}
+                current_info.begin = line_index;
+                current_info.end = line_index;
+                current_info.depth = line.depth;
+                current_info.length = 0;
+            }
 
-	}
+            length := 0;
 
-	if (current_info.begin != 0 && current_info.end != 0) || current_info.length > 0 {
-		append(&comment_infos, current_info);
-	}
+            for format_token, i in line.format_tokens {
 
-	for info in comment_infos {
+                if format_token.kind == .Comment {
+                    current_info.length = max(current_info.length, length);
+                    current_info.end = line_index;
+                }
 
-		if info.begin == info.end || info.length == 0 {
-			continue;
-		}
+                length += format_token.spaces_before + len(format_token.text);
+            }
+        }
+    }
 
-		for i := info.begin; i <= info.end; i += 1 {
+    if (current_info.begin != 0 && current_info.end != 0) || current_info.length > 0 {
+        append(&comment_infos, current_info);
+    }
 
-			l := p.lines[i];
+    for info in comment_infos {
 
-			length := 0;
+        if info.begin == info.end || info.length == 0 {
+            continue;
+        }
 
-			for format_token, i in l.format_tokens {
+        for i := info.begin; i <= info.end; i += 1 {
 
-				if format_token.kind == .Comment {
-					if len(l.format_tokens) == 1 {
-						l.format_tokens[i].spaces_before += info.length + 1;
-					} else {
-						l.format_tokens[i].spaces_before += info.length - length;
-					}			
-				}
+            l := p.lines[i];
 
-				length += format_token.spaces_before + len(format_token.text);
-			}
+            length := 0;
 
-		}
+            for format_token, i in l.format_tokens {
 
-	}
+                if format_token.kind == .Comment {
+                    if len(l.format_tokens) == 1 {
+                        l.format_tokens[i].spaces_before += info.length + 1;
+                    } else {
+                        l.format_tokens[i].spaces_before += info.length - length;
+                    }
+                }
 
+                length += format_token.spaces_before + len(format_token.text);
+            }
+        }
+    }
 }

+ 1127 - 1135
core/odin/printer/visit.odin

@@ -11,239 +11,238 @@ import "core:sort"
 
 //right the attribute order is not linearly parsed(bug?)
 @(private)
-sort_attribute :: proc(s: ^[dynamic]^ast.Attribute) -> sort.Interface {
-	return sort.Interface {
-		collection = rawptr(s),
-		len = proc(it: sort.Interface) -> int {
-			s := (^[dynamic]^ast.Attribute)(it.collection);
-			return len(s^);
-		},
-		less = proc(it: sort.Interface, i, j: int) -> bool {
-			s := (^[dynamic]^ast.Attribute)(it.collection);
-			return s[i].pos.offset < s[j].pos.offset;
-		},
-		swap = proc(it: sort.Interface, i, j: int) {
-			s := (^[dynamic]^ast.Attribute)(it.collection);
-			s[i], s[j] = s[j], s[i];
-		},
-	};
+sort_attribute :: proc(s: ^[dynamic] ^ast.Attribute) -> sort.Interface {
+    return sort.Interface {
+        collection = rawptr(s),
+        len = proc(it: sort.Interface) -> int {
+            s := (^[dynamic] ^ast.Attribute)(it.collection);
+            return len(s^);
+        },
+        less = proc(it: sort.Interface, i, j: int) -> bool {
+            s := (^[dynamic] ^ast.Attribute)(it.collection);
+            return s[i].pos.offset < s[j].pos.offset;
+        },
+        swap = proc(it: sort.Interface, i, j: int) {
+            s := (^[dynamic] ^ast.Attribute)(it.collection);
+            s[i], s[j] = s[j], s[i];
+        },
+    };
 }
 
 @(private)
 comment_before_position :: proc(p: ^Printer, pos: tokenizer.Pos) -> bool {
 
-	if len(p.comments) <= p.latest_comment_index {
-		return false;
-	}
+    if len(p.comments) <= p.latest_comment_index {
+        return false;
+    }
 
-	comment := p.comments[p.latest_comment_index];
+    comment := p.comments[p.latest_comment_index];
 
-	return comment.pos.offset < pos.offset;
+    return comment.pos.offset < pos.offset;
 }
 
 @(private)
 next_comment_group :: proc(p: ^Printer) {
-	p.latest_comment_index += 1;
+    p.latest_comment_index += 1;
 }
- 
-@(private) 
+
+@(private)
 push_comment :: proc(p: ^Printer, comment: tokenizer.Token) -> int {
 
-	if len(comment.text) == 0 {
-		return 0;
-	}
-
-	if comment.text[0] == '/' && comment.text[1] == '/' {
-		format_token := Format_Token {
-			spaces_before = 1,
-			kind = .Comment,
-			text = comment.text,
-		};
-
-		if len(p.current_line.format_tokens) == 0 {
-			format_token.spaces_before = 0;
-		}
-
-		if !p.current_line.used {
-			p.current_line.used = true;
-			p.current_line.depth = p.depth;
-		}
-
-		append(&p.current_line.format_tokens, format_token); 
-		p.last_token = &p.current_line.format_tokens[len(p.current_line.format_tokens)-1];
-
-		hint_current_line(p, {.Line_Comment});
-
-		return 0;
-	} else {
-
-		builder := strings.make_builder(context.temp_allocator);
-
-		c_len := len(comment.text);
-		trim_space := true;
-
-		multilines: [dynamic] string;
-
-		for i := 0; i < len(comment.text); i += 1 {
-
-			c := comment.text[i];
-
-			if c != ' ' && c != '\t' {
-				trim_space = false;
-			}
-
-			if (c == ' ' || c == '\t' || c == '\n') && trim_space {
-				continue;
-			} else if c == 13 && comment.text[min(c_len - 1, i + 1)] == 10 {
-				append(&multilines, strings.to_string(builder));
-				builder = strings.make_builder(context.temp_allocator);
-				trim_space = true;
-				i += 1;
-			} else if c == 10 {
-				append(&multilines, strings.to_string(builder));
-				builder = strings.make_builder(context.temp_allocator);
-				trim_space = true;
-			} else if c == '/' && comment.text[min(c_len - 1, i + 1)] == '*' {
-				strings.write_string(&builder, "/*");
-				trim_space = true;
-				p.depth += 1;
-				i += 1;
-			} else if c == '*' && comment.text[min(c_len - 1, i + 1)] == '/' {
-				p.depth -= 1;
-				trim_space = true;
-				strings.write_string(&builder, "*/");
-				i += 1;
-			} else {
-				strings.write_byte(&builder, c);
-			}
-
-		}
-
-		if strings.builder_len(builder) > 0 {
-			append(&multilines, strings.to_string(builder));
-		}
-
-		for line in multilines {
-			format_token := Format_Token {
-				spaces_before = 1,
-				kind = .Comment,
-				text = line,
-			};
-
-			if len(p.current_line.format_tokens) == 0 {
-				format_token.spaces_before = 0;
-			}
-
-			if strings.contains(line, "*/")  {
-				unindent(p);
-			}
-
-			if !p.current_line.used {
-				p.current_line.used = true;
-				p.current_line.depth = p.depth;
-			}
-
-			append(&p.current_line.format_tokens, format_token); 
-			p.last_token = &p.current_line.format_tokens[len(p.current_line.format_tokens)-1];
-
-			if strings.contains(line, "/*") {
-				indent(p);
-			} 
-
-			newline_position(p, 1);
-		}
-
-		return len(multilines);
-	}
+    if len(comment.text) == 0 {
+        return 0;
+    }
+
+    if comment.text[0] == '/' && comment.text[1] == '/' {
+        format_token := Format_Token {
+            spaces_before = 1,
+            kind = .Comment,
+            text = comment.text,
+        };
+
+        if len(p.current_line.format_tokens) == 0 {
+            format_token.spaces_before = 0;
+        }
+
+        if !p.current_line.used {
+            p.current_line.used = true;
+            p.current_line.depth = p.depth;
+        }
+
+        append(&p.current_line.format_tokens, format_token);
+        p.last_token = &p.current_line.format_tokens[len(p.current_line.format_tokens) - 1];
+
+        hint_current_line(p,{.Line_Comment});
+
+        return 0;
+    } else {
+
+        builder := strings.make_builder(context.temp_allocator);
+
+        c_len := len(comment.text);
+        trim_space := true;
+
+        multilines: [dynamic] string;
+
+        for i := 0; i < len(comment.text); i += 1 {
+
+            c := comment.text[i];
+
+            if c != ' ' && c != '\t' {
+                trim_space = false;
+            }
+
+            if (c == ' ' || c == '\t' || c == '\n') && trim_space {
+                continue;
+            } else if c == 13 && comment.text[min(c_len - 1, i + 1)] == 10 {
+                append(&multilines, strings.to_string(builder));
+                builder = strings.make_builder(context.temp_allocator);
+                trim_space = true;
+                i += 1;
+            } else if c == 10 {
+                append(&multilines, strings.to_string(builder));
+                builder = strings.make_builder(context.temp_allocator);
+                trim_space = true;
+            } else if c == '/' && comment.text[min(c_len - 1, i + 1)] == '*' {
+                strings.write_string(&builder, "/*");
+                trim_space = true;
+                p.depth += 1;
+                i += 1;
+            } else if c == '*' && comment.text[min(c_len - 1, i + 1)] == '/' {
+                p.depth -= 1;
+                trim_space = true;
+                strings.write_string(&builder, "*/");
+                i += 1;
+            } else {
+                strings.write_byte(&builder, c);
+            }
+        }
+
+        if strings.builder_len(builder) > 0 {
+            append(&multilines, strings.to_string(builder));
+        }
+
+        for line in multilines {
+            format_token := Format_Token {
+                spaces_before = 1,
+                kind = .Comment,
+                text = line,
+            };
+
+            if len(p.current_line.format_tokens) == 0 {
+                format_token.spaces_before = 0;
+            }
+
+            if strings.contains(line, "*/") {
+                unindent(p);
+            }
+
+            if !p.current_line.used {
+                p.current_line.used = true;
+                p.current_line.depth = p.depth;
+            }
+
+            append(&p.current_line.format_tokens, format_token);
+            p.last_token = &p.current_line.format_tokens[len(p.current_line.format_tokens) - 1];
+
+            if strings.contains(line, "/*") {
+                indent(p);
+            }
+
+            newline_position(p, 1);
+        }
+
+        return len(multilines);
+    }
 }
 
 @(private)
 push_comments :: proc(p: ^Printer, pos: tokenizer.Pos) {
 
-	prev_comment: ^tokenizer.Token;
-	prev_comment_lines: int;
+    prev_comment: ^tokenizer.Token;
+    prev_comment_lines: int;
 
-	for comment_before_position(p, pos) {
+    for comment_before_position(p, pos) {
 
-		comment_group := p.comments[p.latest_comment_index];
+        comment_group := p.comments[p.latest_comment_index];
 
-		if prev_comment == nil {
-			lines := comment_group.pos.line - p.last_source_position.line;
-			set_line(p, p.last_line_index + min(p.config.newline_limit, lines));
-		}
+        if prev_comment == nil {
+            lines := comment_group.pos.line - p.last_source_position.line;
+            set_line(p, p.last_line_index + min(p.config.newline_limit, lines));
+        }
 
-		for comment, i in comment_group.list {
+        for comment, i in comment_group.list {
 
-			if prev_comment != nil && p.last_source_position.line != comment.pos.line {
-			 	newline_position(p, min(p.config.newline_limit, comment.pos.line - prev_comment.pos.line - prev_comment_lines));
-			}
+            if prev_comment != nil && p.last_source_position.line != comment.pos.line {
+                newline_position(p, min(p.config.newline_limit, comment.pos.line - prev_comment.pos.line - prev_comment_lines));
+            }
+
+            prev_comment_lines = push_comment(p, comment);
+            prev_comment = &comment_group.list[i];
+        }
 
-			prev_comment_lines = push_comment(p, comment);
-			prev_comment = &comment_group.list[i];
-		}
+        next_comment_group(p);
+    }
 
-		next_comment_group(p);
-	}
- 
-	if prev_comment != nil {
-		newline_position(p, min(p.config.newline_limit, p.source_position.line - prev_comment.pos.line));
-	}
+    if prev_comment != nil {
+        newline_position(p, min(p.config.newline_limit, p.source_position.line - prev_comment.pos.line));
+    }
 }
 
 @(private)
 append_format_token :: proc(p: ^Printer, format_token: Format_Token) -> ^Format_Token {
 
-	format_token := format_token;
-
-	if p.last_token != nil && (p.last_token.kind == .Ellipsis  || p.last_token.kind == .Range_Half || 
-							   p.last_token.kind == .Open_Paren || p.last_token.kind == .Period ||
-							   p.last_token.kind == .Open_Brace || p.last_token.kind == .Open_Bracket) {
-		format_token.spaces_before = 0;
-	} else if p.merge_next_token {
-		format_token.spaces_before = 0;
-		p.merge_next_token = false;
-	} else if p.space_next_token {
-		format_token.spaces_before = 1;
-		p.space_next_token = false;
-	}
-
-	push_comments(p, p.source_position);
-
-	unwrapped_line := p.current_line;
-
-	if !unwrapped_line.used {
-    	unwrapped_line.used = true;
-		unwrapped_line.depth = p.depth;
-	}
-
-	if len(unwrapped_line.format_tokens) == 0 && format_token.spaces_before == 1 {
-		format_token.spaces_before = 0;
-	}
-    
-	p.last_source_position = p.source_position;
-	p.last_line_index = p.current_line_index;
-
-	append(&unwrapped_line.format_tokens, format_token); 
-	return &unwrapped_line.format_tokens[len(unwrapped_line.format_tokens)-1];
+    format_token := format_token;
+
+    if p.last_token != nil && (p.last_token.kind == .Ellipsis || p.last_token.kind == .Range_Half ||
+    p.last_token.kind == .Open_Paren || p.last_token.kind == .Period ||
+    p.last_token.kind == .Open_Brace || p.last_token.kind == .Open_Bracket) {
+        format_token.spaces_before = 0;
+    } else if p.merge_next_token {
+        format_token.spaces_before = 0;
+        p.merge_next_token = false;
+    } else if p.space_next_token {
+        format_token.spaces_before = 1;
+        p.space_next_token = false;
+    }
+
+    push_comments(p, p.source_position);
+
+    unwrapped_line := p.current_line;
+
+    if !unwrapped_line.used {
+        unwrapped_line.used = true;
+        unwrapped_line.depth = p.depth;
+    }
+
+    if len(unwrapped_line.format_tokens) == 0 && format_token.spaces_before == 1 {
+        format_token.spaces_before = 0;
+    }
+
+    p.last_source_position = p.source_position;
+    p.last_line_index = p.current_line_index;
+
+    append(&unwrapped_line.format_tokens, format_token);
+    return &unwrapped_line.format_tokens[len(unwrapped_line.format_tokens) - 1];
 }
 
 @(private)
 push_format_token :: proc(p: ^Printer, format_token: Format_Token) {
-	p.last_token = append_format_token(p, format_token);
+    p.last_token = append_format_token(p, format_token);
 }
 
 @(private)
 push_generic_token :: proc(p: ^Printer, kind: tokenizer.Token_Kind, spaces_before: int, value := "") {
- 
+
     format_token := Format_Token {
         spaces_before = spaces_before,
         kind = kind,
         text = tokenizer.tokens[kind],
     };
 
-	if value != "" {
-		format_token.text = value;
-	}
+    if value != "" {
+        format_token.text = value;
+    }
 
     p.last_token = append_format_token(p, format_token);
 }
@@ -269,1204 +268,1197 @@ push_ident_token :: proc(p: ^Printer, text: string, spaces_before: int) {
         text = text,
     };
 
-    p.last_token = append_format_token(p, format_token); 
+    p.last_token = append_format_token(p, format_token);
 }
 
 @(private)
 set_source_position :: proc(p: ^Printer, pos: tokenizer.Pos) {
-	p.source_position = pos;
+    p.source_position = pos;
 }
 
 @(private)
 move_line :: proc(p: ^Printer, pos: tokenizer.Pos) {
-	move_line_limit(p, pos, p.config.newline_limit);
+    move_line_limit(p, pos, p.config.newline_limit);
 }
 
 @(private)
 move_line_limit :: proc(p: ^Printer, pos: tokenizer.Pos, limit: int) -> bool {
-	lines := min(pos.line - p.source_position.line, limit);
+    lines := min(pos.line - p.source_position.line, limit);
 
-	if lines < 0 {
-		return false;
-	}
+    if lines < 0 {
+        return false;
+    }
 
-	p.source_position = pos;
-	p.current_line_index += lines;
-	set_line(p, p.current_line_index);
-	return lines > 0;
+    p.source_position = pos;
+    p.current_line_index += lines;
+    set_line(p, p.current_line_index);
+    return lines > 0;
 }
 
 @(private)
 set_line :: proc(p: ^Printer, line: int) -> ^Line {
 
-	unwrapped_line: ^Line;
+    unwrapped_line: ^Line;
 
-	if line >= len(p.lines) {
-		for i := len(p.lines); i <= line; i += 1 {
-			new_line: Line;
-			new_line.format_tokens = make([dynamic] Format_Token, 0, 50, p.allocator);
-			append(&p.lines, new_line);
-		}
-		unwrapped_line = &p.lines[line];
+    if line >= len(p.lines) {
+        for i := len(p.lines); i <= line; i += 1 {
+            new_line: Line;
+            new_line.format_tokens = make([dynamic] Format_Token, 0, 50, p.allocator);
+            append(&p.lines, new_line);
+        }
+        unwrapped_line = &p.lines[line];
     } else {
         unwrapped_line = &p.lines[line];
     }
 
-	p.current_line = unwrapped_line;
-	p.current_line_index = line;
+    p.current_line = unwrapped_line;
+    p.current_line_index = line;
 
-	return unwrapped_line;
+    return unwrapped_line;
 }
 
 @(private)
 newline_position :: proc(p: ^Printer, count: int) {
-	p.current_line_index += count;
-	set_line(p, p.current_line_index);
+    p.current_line_index += count;
+    set_line(p, p.current_line_index);
 }
 
 @(private)
 indent :: proc(p: ^Printer) {
-	p.depth += 1;
+    p.depth += 1;
 }
 
 @(private)
 unindent :: proc(p: ^Printer) {
-	p.depth -= 1;
+    p.depth -= 1;
 }
 
 @(private)
 merge_next_token :: proc(p: ^Printer) {
-	p.merge_next_token = true;
+    p.merge_next_token = true;
 }
 
 @(private)
 space_next_token :: proc(p: ^Printer) {
-	p.space_next_token = true;
+    p.space_next_token = true;
 }
 
 @(private)
 hint_current_line :: proc(p: ^Printer, hint: Line_Type) {
-	p.current_line.types |= hint;
+    p.current_line.types |= hint;
 }
 
 @(private)
 visit_decl :: proc(p: ^Printer, decl: ^ast.Decl, called_in_stmt := false) {
 
-	using ast;
+    using ast;
 
-	if decl == nil {
-		return;
-	}
+    if decl == nil {
+        return;
+    }
 
-	switch v in &decl.derived {
-	case Expr_Stmt:
-		move_line(p, decl.pos);
-		visit_expr(p, v.expr);
-		if p.config.semicolons {
+    switch v in &decl.derived {
+    case Expr_Stmt:
+        move_line(p, decl.pos);
+        visit_expr(p, v.expr);
+        if p.config.semicolons {
             push_generic_token(p, .Semicolon, 0);
-		}
-	case When_Stmt:
-		visit_stmt(p, cast(^Stmt)decl);
-	case Foreign_Import_Decl:
-		if len(v.attributes) > 0 {
-			sort.sort(sort_attribute(&v.attributes));
-			move_line(p, v.attributes[0].pos);
-			visit_attributes(p, v.attributes);
-		} 
-
-		move_line(p, decl.pos);
-		
+        }
+    case When_Stmt:
+        visit_stmt(p, cast(^Stmt)decl);
+    case Foreign_Import_Decl:
+        if len(v.attributes) > 0 {
+            sort.sort(sort_attribute(&v.attributes));
+            move_line(p, v.attributes[0].pos);
+            visit_attributes(p, v.attributes);
+        }
+
+        move_line(p, decl.pos);
+
         push_generic_token(p, v.foreign_tok.kind, 0);
         push_generic_token(p, v.import_tok.kind, 1);
 
-		if v.name != nil {
+        if v.name != nil {
             push_ident_token(p, v.name.name, 1);
-		} 
+        }
 
-		for path in v.fullpaths {
+        for path in v.fullpaths {
             push_ident_token(p, path, 0);
-		}
-	case Foreign_Block_Decl:
-
-		if len(v.attributes) > 0 {
-			sort.sort(sort_attribute(&v.attributes));
-			move_line(p, v.attributes[0].pos);
-			visit_attributes(p, v.attributes);
-		} 
-			
-		move_line(p, decl.pos);
-		
+        }
+    case Foreign_Block_Decl:
+
+        if len(v.attributes) > 0 {
+            sort.sort(sort_attribute(&v.attributes));
+            move_line(p, v.attributes[0].pos);
+            visit_attributes(p, v.attributes);
+        }
+
+        move_line(p, decl.pos);
+
         push_generic_token(p, .Foreign, 0);
 
-		visit_expr(p, v.foreign_library);
-		visit_stmt(p, v.body);
-	case Import_Decl:
-		move_line(p, decl.pos);
+        visit_expr(p, v.foreign_library);
+        visit_stmt(p, v.body);
+    case Import_Decl:
+        move_line(p, decl.pos);
 
-		if v.name.text != "" {
+        if v.name.text != "" {
             push_generic_token(p, v.import_tok.kind, 1);
             push_generic_token(p, v.name.kind, 1, v.name.text);
             push_ident_token(p, v.fullpath, 1);
-		} else {
+        } else {
             push_generic_token(p, v.import_tok.kind, 1);
             push_ident_token(p, v.fullpath, 1);
-		}
+        }
 
-	case Value_Decl:
-		if len(v.attributes) > 0 {
-			sort.sort(sort_attribute(&v.attributes));
-			move_line(p, v.attributes[0].pos);
-			visit_attributes(p, v.attributes);
-		}
+    case Value_Decl:
+        if len(v.attributes) > 0 {
+            sort.sort(sort_attribute(&v.attributes));
+            move_line(p, v.attributes[0].pos);
+            visit_attributes(p, v.attributes);
+        }
 
-		move_line(p, decl.pos);
+        move_line(p, decl.pos);
 
-		if v.is_using {
+        if v.is_using {
             push_generic_token(p, .Using, 0);
-		}
+        }
 
-		visit_exprs(p, v.names, true);
+        visit_exprs(p, v.names, true);
 
-		if v.type != nil {
+        if v.type != nil {
             if !v.is_mutable && v.type != nil {
                 push_generic_token(p, .Colon, 0);
-		    } else {
+            } else {
                 push_generic_token(p, .Colon, 0);
             }
 
-			visit_expr(p, v.type);
-		} else {
+            visit_expr(p, v.type);
+        } else {
             if !v.is_mutable && v.type == nil {
                 push_generic_token(p, .Colon, 1);
-			    push_generic_token(p, .Colon, 0);
+                push_generic_token(p, .Colon, 0);
             } else {
                 push_generic_token(p, .Colon, 1);
             }
-		}
+        }
 
-		if v.is_mutable && v.type != nil && len(v.values) != 0 {
+        if v.is_mutable && v.type != nil && len(v.values) != 0 {
             push_generic_token(p, .Eq, 1);
-		} else if v.is_mutable && v.type == nil && len(v.values) != 0 {
-			push_generic_token(p, .Eq, 0);
-		} else if !v.is_mutable && v.type != nil {
+        } else if v.is_mutable && v.type == nil && len(v.values) != 0 {
+            push_generic_token(p, .Eq, 0);
+        } else if !v.is_mutable && v.type != nil {
             push_generic_token(p, .Colon, 0);
-		}
+        }
 
-		visit_exprs(p, v.values, true);
+        visit_exprs(p, v.values, true);
 
-		add_semicolon := true;
+        add_semicolon := true;
 
-		for value in v.values {
-			switch a in value.derived {
-			case Proc_Lit, Union_Type, Enum_Type, Struct_Type:
-				add_semicolon = false || called_in_stmt;
-			}
-		}
+        for value in v.values {
+            switch a in value.derived {
+            case Proc_Lit, Union_Type, Enum_Type, Struct_Type:
+                add_semicolon = false || called_in_stmt;
+            }
+        }
 
-		if add_semicolon && p.config.semicolons && !p.skip_semicolon {
+        if add_semicolon && p.config.semicolons && !p.skip_semicolon {
             push_generic_token(p, .Semicolon, 0);
-		}
+        }
 
-	case:
-		panic(fmt.aprint(decl.derived));
-	}
+    case:
+        panic(fmt.aprint(decl.derived));
+    }
 }
 
 @(private)
-visit_exprs :: proc(p: ^Printer, list: []^ast.Expr, add_comma := false, trailing := false) {
+visit_exprs :: proc(p: ^Printer, list: [] ^ast.Expr, add_comma := false, trailing := false) {
 
-	if len(list) == 0 {
-		return;
-	}
+    if len(list) == 0 {
+        return;
+    }
 
-	//we have to newline the expressions to respect the source
-	for expr, i in list {
+    //we have to newline the expressions to respect the source
+    for expr, i in list {
 
-		move_line_limit(p, expr.pos, 1);
+        move_line_limit(p, expr.pos, 1);
 
-		visit_expr(p, expr);
+        visit_expr(p, expr);
 
-		if (i != len(list) - 1 || trailing) && add_comma {
-			push_generic_token(p, .Comma, 0);
-		} 
-	}
+        if (i != len(list) - 1 || trailing) && add_comma {
+            push_generic_token(p, .Comma, 0);
+        }
+    }
 }
 
 @(private)
-visit_attributes :: proc(p: ^Printer, attributes: [dynamic]^ast.Attribute) {
+visit_attributes :: proc(p: ^Printer, attributes: [dynamic] ^ast.Attribute) {
 
-	if len(attributes) == 0 {
-		return;
-	}
+    if len(attributes) == 0 {
+        return;
+    }
 
-	for attribute, i in attributes {
+    for attribute, i in attributes {
 
-		move_line_limit(p, attribute.pos, 1);
+        move_line_limit(p, attribute.pos, 1);
 
-		push_generic_token(p, .At, 0);
-		push_generic_token(p, .Open_Paren, 0);
+        push_generic_token(p, .At, 0);
+        push_generic_token(p, .Open_Paren, 0);
 
-		visit_exprs(p, attribute.elems, true);
+        visit_exprs(p, attribute.elems, true);
 
-		push_generic_token(p, .Close_Paren, 0);	
-	}
+        push_generic_token(p, .Close_Paren, 0);
+    }
 }
 
 @(private)
 visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Generic, empty_block := false, block_stmt := false) {
 
-	using ast;
+    using ast;
 
-	if stmt == nil {
-		return;
-	}
+    if stmt == nil {
+        return;
+    }
 
-	switch v in stmt.derived {
-	case Value_Decl:
-		visit_decl(p, cast(^Decl)stmt, true);
-		return;
-	case Foreign_Import_Decl:
-		visit_decl(p, cast(^Decl)stmt, true);
-		return;
-	case Foreign_Block_Decl:
-		visit_decl(p, cast(^Decl)stmt, true);
-		return;
-	}
+    switch v in stmt.derived {
+    case Value_Decl:
+        visit_decl(p, cast(^Decl)stmt, true);
+        return;
+    case Foreign_Import_Decl:
+        visit_decl(p, cast(^Decl)stmt, true);
+        return;
+    case Foreign_Block_Decl:
+        visit_decl(p, cast(^Decl)stmt, true);
+        return;
+    }
 
-	switch v in stmt.derived {
-	case Using_Stmt:
-		move_line(p, v.pos);
+    switch v in stmt.derived {
+    case Using_Stmt:
+        move_line(p, v.pos);
 
-		push_generic_token(p, .Using, 1);
+        push_generic_token(p, .Using, 1);
 
-		visit_exprs(p, v.list, true);
+        visit_exprs(p, v.list, true);
 
-		if p.config.semicolons {
-			push_generic_token(p, .Semicolon, 0);
-		}
-	case Block_Stmt:
-		move_line(p, v.pos);
+        if p.config.semicolons {
+            push_generic_token(p, .Semicolon, 0);
+        }
+    case Block_Stmt:
+        move_line(p, v.pos);
 
-		if v.pos.line == v.end.line {
-			if !empty_block {
-				push_generic_token(p, .Open_Brace, 0);
-			}
+        if v.pos.line == v.end.line {
+            if !empty_block {
+                push_generic_token(p, .Open_Brace, 0);
+            }
 
-			set_source_position(p, v.pos);
+            set_source_position(p, v.pos);
 
-			visit_block_stmts(p, v.stmts, len(v.stmts) > 1 && p.config.split_multiple_stmts);
+            visit_block_stmts(p, v.stmts, len(v.stmts) > 1 && p.config.split_multiple_stmts);
 
-			set_source_position(p, v.end);
+            set_source_position(p, v.end);
 
-			if !empty_block {
-				push_generic_token(p, .Close_Brace, 0);
-			}
-		} else {
-			if !empty_block {
-				visit_begin_brace(p, v.pos, block_type, len(v.stmts));
-			}
+            if !empty_block {
+                push_generic_token(p, .Close_Brace, 0);
+            }
+        } else {
+            if !empty_block {
+                visit_begin_brace(p, v.pos, block_type, len(v.stmts));
+            }
 
-			set_source_position(p, v.pos);
+            set_source_position(p, v.pos);
 
-			visit_block_stmts(p, v.stmts, len(v.stmts) > 1 && p.config.split_multiple_stmts);
+            visit_block_stmts(p, v.stmts, len(v.stmts) > 1 && p.config.split_multiple_stmts);
 
-			set_source_position(p, v.end);
+            set_source_position(p, v.end);
 
-			if !empty_block {
-				visit_end_brace(p, v.end);
-			}
-		}
-	case If_Stmt:
-		move_line(p, v.pos);
+            if !empty_block {
+                visit_end_brace(p, v.end);
+            }
+        }
+    case If_Stmt:
+        move_line(p, v.pos);
 
-		if v.label != nil {
-			visit_expr(p, v.label);
-			push_generic_token(p, .Colon, 0);
-		}
+        if v.label != nil {
+            visit_expr(p, v.label);
+            push_generic_token(p, .Colon, 0);
+        }
 
-		push_generic_token(p, .If, 1);
+        push_generic_token(p, .If, 1);
 
-		if v.init != nil {
-			p.skip_semicolon = true;
-			visit_stmt(p, v.init);
-			p.skip_semicolon = false;
-			push_generic_token(p, .Semicolon, 0);
-		}
+        if v.init != nil {
+            p.skip_semicolon = true;
+            visit_stmt(p, v.init);
+            p.skip_semicolon = false;
+            push_generic_token(p, .Semicolon, 0);
+        }
 
-		visit_expr(p, v.cond);
+        visit_expr(p, v.cond);
 
-		uses_do := false;
+        uses_do := false;
 
-		if check_stmt, ok := v.body.derived.(Block_Stmt); ok && check_stmt.uses_do {
-			uses_do = true;
-		}
+        if check_stmt, ok := v.body.derived.(Block_Stmt); ok && check_stmt.uses_do {
+            uses_do = true;
+        }
 
-		if uses_do && !p.config.convert_do {
-			push_generic_token(p, .Do, 1);
-			visit_stmt(p, v.body, .If_Stmt, true);
-		} else {
-			if uses_do {
-				newline_position(p, 1);
-			}
+        if uses_do && !p.config.convert_do {
+            push_generic_token(p, .Do, 1);
+            visit_stmt(p, v.body, .If_Stmt, true);
+        } else {
+            if uses_do {
+                newline_position(p, 1);
+            }
 
-			visit_stmt(p, v.body, .If_Stmt);
-		}
+            visit_stmt(p, v.body, .If_Stmt);
+        }
 
-		if v.else_stmt != nil {
+        if v.else_stmt != nil {
 
-			if p.config.brace_style == .Allman || p.config.brace_style == .Stroustrup {
-				newline_position(p, 1);
-			} 
+            if p.config.brace_style == .Allman || p.config.brace_style == .Stroustrup {
+                newline_position(p, 1);
+            }
 
-			push_generic_token(p, .Else, 1);
+            push_generic_token(p, .Else, 1);
 
-			set_source_position(p, v.else_stmt.pos);
+            set_source_position(p, v.else_stmt.pos);
 
-			visit_stmt(p, v.else_stmt);
-		}
-	case Switch_Stmt:
-		move_line(p, v.pos);
+            visit_stmt(p, v.else_stmt);
+        }
+    case Switch_Stmt:
+        move_line(p, v.pos);
 
-		if v.label != nil {
-			visit_expr(p, v.label);
-			push_generic_token(p, .Colon, 0);
-		}
+        if v.label != nil {
+            visit_expr(p, v.label);
+            push_generic_token(p, .Colon, 0);
+        }
 
-		if v.partial {
-			push_ident_token(p, "#partial", 1);
-		}
+        if v.partial {
+            push_ident_token(p, "#partial", 1);
+        }
 
-		push_generic_token(p, .Switch, 1);
+        push_generic_token(p, .Switch, 1);
 
-		hint_current_line(p, {.Switch_Stmt});
+        hint_current_line(p,{.Switch_Stmt});
 
-		if v.init != nil {
-			p.skip_semicolon = true;
-			visit_stmt(p, v.init);
-			p.skip_semicolon = false;
-		}
+        if v.init != nil {
+            p.skip_semicolon = true;
+            visit_stmt(p, v.init);
+            p.skip_semicolon = false;
+        }
 
-		if v.init != nil && v.cond != nil {
-			push_generic_token(p, .Semicolon, 0);
-		}
+        if v.init != nil && v.cond != nil {
+            push_generic_token(p, .Semicolon, 0);
+        }
 
-		visit_expr(p, v.cond);
-		visit_stmt(p, v.body);
-	case Case_Clause:
-		move_line(p, v.pos);
+        visit_expr(p, v.cond);
+        visit_stmt(p, v.body);
+    case Case_Clause:
+        move_line(p, v.pos);
 
-		if !p.config.indent_cases {
-			unindent(p);
-		}
+        if !p.config.indent_cases {
+            unindent(p);
+        }
 
-		push_generic_token(p, .Case, 0);
+        push_generic_token(p, .Case, 0);
 
-		if v.list != nil {
-			visit_exprs(p, v.list, true);
-		}
+        if v.list != nil {
+            visit_exprs(p, v.list, true);
+        }
 
-		push_generic_token(p, v.terminator.kind, 0);
+        push_generic_token(p, v.terminator.kind, 0);
 
-		indent(p);
+        indent(p);
 
-		visit_block_stmts(p, v.body);
+        visit_block_stmts(p, v.body);
 
-		unindent(p);
+        unindent(p);
 
-		if !p.config.indent_cases {
-			indent(p);
-		}
-	case Type_Switch_Stmt:
-		move_line(p, v.pos);
+        if !p.config.indent_cases {
+            indent(p);
+        }
+    case Type_Switch_Stmt:
+        move_line(p, v.pos);
 
-		if v.label != nil {
-			visit_expr(p, v.label);
-			push_generic_token(p, .Colon, 0);
-		}
+        if v.label != nil {
+            visit_expr(p, v.label);
+            push_generic_token(p, .Colon, 0);
+        }
 
-		if v.partial {
-			push_ident_token(p, "#partial", 1);
-		}
+        if v.partial {
+            push_ident_token(p, "#partial", 1);
+        }
 
-		push_generic_token(p, .Switch, 1);
+        push_generic_token(p, .Switch, 1);
 
-		visit_stmt(p, v.tag);
-		visit_stmt(p, v.body);
-	case Assign_Stmt:
-		move_line(p, v.pos);
+        visit_stmt(p, v.tag);
+        visit_stmt(p, v.body);
+    case Assign_Stmt:
+        move_line(p, v.pos);
 
-		visit_exprs(p, v.lhs, true);
+        visit_exprs(p, v.lhs, true);
 
-		push_generic_token(p, v.op.kind, 1);
+        push_generic_token(p, v.op.kind, 1);
 
-		visit_exprs(p, v.rhs, true);
+        visit_exprs(p, v.rhs, true);
 
-		if block_stmt && p.config.semicolons {
-			push_generic_token(p, .Semicolon, 0);
-		}
-	case Expr_Stmt:
-		move_line(p, v.pos);
-		visit_expr(p, v.expr);
-		if block_stmt && p.config.semicolons {
-			push_generic_token(p, .Semicolon, 0);
-		}
-	case For_Stmt:
-		//this should be simplified
-		move_line(p, v.pos);
+        if block_stmt && p.config.semicolons {
+            push_generic_token(p, .Semicolon, 0);
+        }
+    case Expr_Stmt:
+        move_line(p, v.pos);
+        visit_expr(p, v.expr);
+        if block_stmt && p.config.semicolons {
+            push_generic_token(p, .Semicolon, 0);
+        }
+    case For_Stmt:
+        //this should be simplified
+        move_line(p, v.pos);
 
-		if v.label != nil {
-			visit_expr(p, v.label);
-			push_generic_token(p, .Colon, 0);
-		}
+        if v.label != nil {
+            visit_expr(p, v.label);
+            push_generic_token(p, .Colon, 0);
+        }
 
-		push_generic_token(p, .For, 1);
+        push_generic_token(p, .For, 1);
 
-		if v.init != nil {
-			p.skip_semicolon = true;
-			visit_stmt(p, v.init);
-			p.skip_semicolon = false;
-			push_generic_token(p, .Semicolon, 0);
-		} else if v.post != nil {
-			push_generic_token(p, .Semicolon, 0);
-		}
+        if v.init != nil {
+            p.skip_semicolon = true;
+            visit_stmt(p, v.init);
+            p.skip_semicolon = false;
+            push_generic_token(p, .Semicolon, 0);
+        } else if v.post != nil {
+            push_generic_token(p, .Semicolon, 0);
+        }
 
-		if v.cond != nil {
-			visit_expr(p, v.cond);
-		}
+        if v.cond != nil {
+            visit_expr(p, v.cond);
+        }
 
-		if v.post != nil {
-			push_generic_token(p, .Semicolon, 0);
-			visit_stmt(p, v.post);
-		} else if v.post == nil && v.cond != nil && v.init != nil {
-			push_generic_token(p, .Semicolon, 0);
-		}
+        if v.post != nil {
+            push_generic_token(p, .Semicolon, 0);
+            visit_stmt(p, v.post);
+        } else if v.post == nil && v.cond != nil && v.init != nil {
+            push_generic_token(p, .Semicolon, 0);
+        }
 
-		visit_stmt(p, v.body);
-	case Inline_Range_Stmt:
+        visit_stmt(p, v.body);
+    case Inline_Range_Stmt:
 
-		move_line(p, v.pos);
+        move_line(p, v.pos);
 
-		if v.label != nil {
-			visit_expr(p, v.label);
-			push_generic_token(p, .Colon, 0);
-		}
+        if v.label != nil {
+            visit_expr(p, v.label);
+            push_generic_token(p, .Colon, 0);
+        }
 
-		push_ident_token(p, "#unroll", 0);
+        push_ident_token(p, "#unroll", 0);
 
-		push_generic_token(p, .For, 1);
-		visit_expr(p, v.val0);
+        push_generic_token(p, .For, 1);
+        visit_expr(p, v.val0);
 
-		if v.val1 != nil {
-			push_generic_token(p, .Comma, 0);
-			visit_expr(p, v.val1);
-		}
+        if v.val1 != nil {
+            push_generic_token(p, .Comma, 0);
+            visit_expr(p, v.val1);
+        }
 
-		push_generic_token(p, .In, 1);
+        push_generic_token(p, .In, 1);
 
-		visit_expr(p, v.expr);
-		visit_stmt(p, v.body);
-	case Range_Stmt:
+        visit_expr(p, v.expr);
+        visit_stmt(p, v.body);
+    case Range_Stmt:
 
-		move_line(p, v.pos);
+        move_line(p, v.pos);
 
-		if v.label != nil {
-			visit_expr(p, v.label);
-			push_generic_token(p, .Colon, 0);
-		}
+        if v.label != nil {
+            visit_expr(p, v.label);
+            push_generic_token(p, .Colon, 0);
+        }
 
-		push_generic_token(p, .For, 1);
+        push_generic_token(p, .For, 1);
 
-		if len(v.vals) >= 1 {
-			visit_expr(p, v.vals[0]);
-		}
+        if len(v.vals) >= 1 {
+            visit_expr(p, v.vals[0]);
+        }
 
-		if len(v.vals) >= 2 {
-			push_generic_token(p, .Comma, 0);
-			visit_expr(p, v.vals[1]);
-		} 
+        if len(v.vals) >= 2 {
+            push_generic_token(p, .Comma, 0);
+            visit_expr(p, v.vals[1]);
+        }
 
-		push_generic_token(p, .In, 1);
+        push_generic_token(p, .In, 1);
 
-		visit_expr(p, v.expr);
+        visit_expr(p, v.expr);
 
-		visit_stmt(p, v.body);
-	case Return_Stmt:
-		move_line(p, v.pos);
+        visit_stmt(p, v.body);
+    case Return_Stmt:
+        move_line(p, v.pos);
 
-		push_generic_token(p, .Return, 1);
+        push_generic_token(p, .Return, 1);
 
-		if v.results != nil {
-			visit_exprs(p, v.results, true);
-		}
+        if v.results != nil {
+            visit_exprs(p, v.results, true);
+        }
 
-		if block_stmt && p.config.semicolons {
-			push_generic_token(p, .Semicolon, 0);
-		}
-	case Defer_Stmt:
-		move_line(p, v.pos);
-		push_generic_token(p, .Defer, 0);
+        if block_stmt && p.config.semicolons {
+            push_generic_token(p, .Semicolon, 0);
+        }
+    case Defer_Stmt:
+        move_line(p, v.pos);
+        push_generic_token(p, .Defer, 0);
 
-		visit_stmt(p, v.stmt);
+        visit_stmt(p, v.stmt);
 
-		if p.config.semicolons {
-			push_generic_token(p, .Semicolon, 0);
-		}
-	case When_Stmt:
-		move_line(p, v.pos);
-		push_generic_token(p, .When, 1);
-		visit_expr(p, v.cond);
+        if p.config.semicolons {
+            push_generic_token(p, .Semicolon, 0);
+        }
+    case When_Stmt:
+        move_line(p, v.pos);
+        push_generic_token(p, .When, 1);
+        visit_expr(p, v.cond);
 
-		visit_stmt(p, v.body);
+        visit_stmt(p, v.body);
 
-		if v.else_stmt != nil {
+        if v.else_stmt != nil {
 
-			if p.config.brace_style == .Allman {
-				newline_position(p, 1);
-			} 
+            if p.config.brace_style == .Allman {
+                newline_position(p, 1);
+            }
 
-			push_generic_token(p, .Else, 1);
+            push_generic_token(p, .Else, 1);
 
-			set_source_position(p, v.else_stmt.pos);
+            set_source_position(p, v.else_stmt.pos);
 
-			visit_stmt(p, v.else_stmt);
-		}
+            visit_stmt(p, v.else_stmt);
+        }
 
-	case Branch_Stmt:
+    case Branch_Stmt:
 
-		move_line(p, v.pos);
+        move_line(p, v.pos);
 
-		push_generic_token(p, v.tok.kind, 0);
+        push_generic_token(p, v.tok.kind, 0);
 
-		if v.label != nil {
-			visit_expr(p, v.label);
-		}
+        if v.label != nil {
+            visit_expr(p, v.label);
+        }
 
-		if p.config.semicolons {
-			push_generic_token(p, .Semicolon, 0);
-		}
-	case:
-		panic(fmt.aprint(stmt.derived));
-	}
+        if p.config.semicolons {
+            push_generic_token(p, .Semicolon, 0);
+        }
+    case:
+        panic(fmt.aprint(stmt.derived));
+    }
 
-	set_source_position(p, stmt.end);
+    set_source_position(p, stmt.end);
 }
 
-
 @(private)
 visit_expr :: proc(p: ^Printer, expr: ^ast.Expr) {
 
-	using ast;
-
-	if expr == nil {
-		return;
-	}
-
-	set_source_position(p, expr.pos);
-
-	switch v in expr.derived {
-	case Inline_Asm_Expr:
-		push_generic_token(p, v.tok.kind, 1, v.tok.text);
-
-		push_generic_token(p, .Open_Paren, 1);
-		visit_exprs(p, v.param_types, true, false);
-		push_generic_token(p, .Close_Paren, 0);
-
-		push_generic_token(p, .Sub, 1);
-		push_generic_token(p, .Gt, 0);
-
-		visit_expr(p, v.return_type);
-
-		push_generic_token(p, .Open_Brace, 1);
-		visit_expr(p, v.asm_string);
-		push_generic_token(p, .Comma, 0);
-		visit_expr(p, v.constraints_string);
-		push_generic_token(p, .Close_Brace, 0);
-	case Undef:
-		push_generic_token(p, .Undef, 1);
-	case Auto_Cast:
-		push_generic_token(p, v.op.kind, 1);
-		visit_expr(p, v.expr);
-	case Ternary_Expr:
-		visit_expr(p, v.cond);
-		push_generic_token(p, v.op1.kind, 1);
-		visit_expr(p, v.x);
-		push_generic_token(p, v.op2.kind, 1);
-		visit_expr(p, v.y);
-	case Ternary_If_Expr:
-		visit_expr(p, v.x);
-		push_generic_token(p, v.op1.kind, 1);
-		visit_expr(p, v.cond);
-		push_generic_token(p, v.op2.kind, 1);
-		visit_expr(p, v.y);
-	case Ternary_When_Expr:
-		visit_expr(p, v.x);
-		push_generic_token(p, v.op1.kind, 1);
-		visit_expr(p, v.cond);
-		push_generic_token(p, v.op2.kind, 1);
-		visit_expr(p, v.y);
-	case Selector_Call_Expr:
-		visit_expr(p, v.call.expr);
-		push_generic_token(p, .Open_Paren, 1);
-		visit_exprs(p, v.call.args, true);
-		push_generic_token(p, .Close_Paren, 0);
-	case Ellipsis:
-		push_generic_token(p, .Ellipsis, 1);
-		visit_expr(p, v.expr);
-	case Relative_Type:
-		visit_expr(p, v.tag);
-		visit_expr(p, v.type);
-	case Slice_Expr:
-		visit_expr(p, v.expr);
-		push_generic_token(p, .Open_Bracket, 0);
-		visit_expr(p, v.low);
-		push_generic_token(p, v.interval.kind, 0);
-		if v.high != nil {
-			merge_next_token(p);
-			visit_expr(p, v.high);
-		}
-		push_generic_token(p, .Close_Bracket, 0);
-	case Ident:
-		push_ident_token(p, v.name, 1);
-	case Deref_Expr:
-		visit_expr(p, v.expr);
-		push_generic_token(p, v.op.kind, 0);
-	case Type_Cast:
-		push_generic_token(p, v.tok.kind, 1);
-		push_generic_token(p, .Open_Paren, 0);
-		visit_expr(p, v.type);
-		push_generic_token(p, .Close_Paren, 0);
-		merge_next_token(p);
-		visit_expr(p, v.expr);
-	case Basic_Directive:
-		push_generic_token(p, v.tok.kind, 1);
-		push_ident_token(p, v.name, 0);
-	case Distinct_Type:
-		push_generic_token(p, .Distinct, 1);
-		visit_expr(p, v.type);
-	case Dynamic_Array_Type:
-		visit_expr(p, v.tag);
-		push_generic_token(p, .Open_Bracket, 1);
-		push_generic_token(p, .Dynamic, 0);
-		push_generic_token(p, .Close_Bracket, 0);
-		visit_expr(p, v.elem);
-	case Bit_Set_Type:
-		push_generic_token(p, .Bit_Set, 1);
-		push_generic_token(p, .Open_Bracket, 0);
-
-		visit_expr(p, v.elem);
-
-		if v.underlying != nil {
-			push_generic_token(p, .Semicolon, 0);
-			visit_expr(p, v.underlying);
-		}
-
-		push_generic_token(p, .Close_Bracket, 0);
-	case Union_Type:
-		push_generic_token(p, .Union, 1);
-
-		if v.poly_params != nil {
-			push_generic_token(p, .Open_Paren, 0);
-			visit_field_list(p, v.poly_params, true, false);
-			push_generic_token(p, .Close_Paren, 0);
-		}
-		
-		if v.is_maybe {
-			push_ident_token(p, "#maybe", 1);
-		}
-
-		if v.where_clauses != nil {
-			move_line(p, v.where_clauses[0].pos);
-			push_generic_token(p, .Where, 1);
-			visit_exprs(p, v.where_clauses, true);
-		}
-
-		if v.variants != nil && (len(v.variants) == 0 || v.pos.line == v.end.line) {
-			push_generic_token(p, .Open_Brace, 1);
-			visit_exprs(p, v.variants, true);
-			push_generic_token(p, .Close_Brace, 0);
-		} else {
-			visit_begin_brace(p, v.pos, .Generic);
-			newline_position(p, 1);
-			set_source_position(p, v.variants[0].pos);
-			visit_exprs(p, v.variants, true, true);
-			visit_end_brace(p, v.end);
-		}
-	case Enum_Type:
-		push_generic_token(p, .Enum, 1);
-
-		if v.base_type != nil {
-			visit_expr(p, v.base_type);
-		}
-
-		if v.fields != nil && (len(v.fields) == 0 || v.pos.line == v.end.line) {
-			push_generic_token(p, .Open_Brace, 1);
-			visit_exprs(p, v.fields, true);
-			push_generic_token(p, .Close_Brace, 0);
-		} else {
-			visit_begin_brace(p, v.pos, .Generic);
-			newline_position(p, 1);
-			set_source_position(p, v.fields[0].pos);
-			visit_exprs(p, v.fields, true, true);
-			visit_end_brace(p, v.end);
-		}
-
-		set_source_position(p, v.end);
-	case Struct_Type:
-		push_generic_token(p, .Struct, 1);
-
-		hint_current_line(p, {.Struct});
-
-		if v.is_packed {
-			push_ident_token(p, "#packed", 1);
-		}
-
-		if v.is_raw_union {
-			push_ident_token(p, "#raw_union", 1);
-		}
-
-		if v.align != nil {
-			push_ident_token(p, "#align", 1);
-			visit_expr(p, v.align);
-		}
-
-		if v.poly_params != nil {
-			push_generic_token(p, .Open_Paren, 0);
-			visit_field_list(p, v.poly_params, true, false);
-			push_generic_token(p, .Close_Paren, 0);
-		}
-
-		if v.where_clauses != nil {
-			move_line(p, v.where_clauses[0].pos);
-			push_generic_token(p, .Where, 1);
-			visit_exprs(p, v.where_clauses, true);
-		}
-
-		if v.fields != nil && (len(v.fields.list) == 0 || v.pos.line == v.end.line) {
-			push_generic_token(p, .Open_Brace, 1);
-			set_source_position(p, v.fields.pos);
-			visit_field_list(p, v.fields, true);
-			push_generic_token(p, .Close_Brace, 0);
-		} else if v.fields != nil {
-			visit_begin_brace(p, v.pos, .Generic, len(v.fields.list));
-			set_source_position(p, v.fields.pos);
-			visit_field_list(p, v.fields, true, true, true);
-			visit_end_brace(p, v.end);
-		}
-
-		set_source_position(p, v.end);
-	case Proc_Lit:
-
-		if v.inlining == .Inline {
-			push_ident_token(p, "#force_inline", 0);
-		}
-
-		visit_proc_type(p, v.type^);
-
-		if v.where_clauses != nil {
-			move_line(p, v.where_clauses[0].pos);
-			push_generic_token(p, .Where, 1);
-			visit_exprs(p, v.where_clauses, true);
-		}
-
-		if v.body != nil {
-			set_source_position(p, v.body.pos);
-			visit_stmt(p, v.body, .Proc);
-		} else {
-			push_generic_token(p, .Undef, 1);
-		}
-	case Proc_Type:
-		visit_proc_type(p, v);
-	case Basic_Lit:
-		push_generic_token(p, v.tok.kind, 1, v.tok.text);
-	case Binary_Expr:
-		visit_binary_expr(p, v);
-	case Implicit_Selector_Expr:
-		push_generic_token(p, .Period, 1);
-		push_ident_token(p, v.field.name, 0);
-	case Call_Expr:
-		visit_expr(p, v.expr);
-		push_generic_token(p, .Open_Paren, 0);
-		visit_call_exprs(p, v.args, v.ellipsis.kind == .Ellipsis);
-		push_generic_token(p, .Close_Paren, 0);
-	case Typeid_Type:
-		push_generic_token(p, .Typeid, 1);
-
-		if v.specialization != nil {
-			push_generic_token(p, .Quo, 0);
-			visit_expr(p, v.specialization);
-		}
-	case Selector_Expr:
-		visit_expr(p, v.expr);
-		push_generic_token(p, v.op.kind, 0);
-		visit_expr(p, v.field);
-	case Paren_Expr:
-		push_generic_token(p, .Open_Paren, 1);
-		visit_expr(p, v.expr);
-		push_generic_token(p, .Close_Paren, 0);
-	case Index_Expr:
-		visit_expr(p, v.expr);
-		push_generic_token(p, .Open_Bracket, 0);
-		visit_expr(p, v.index);
-		push_generic_token(p, .Close_Bracket, 0);
-	case Proc_Group:
-	
-		push_generic_token(p, v.tok.kind, 0);
-
-		if len(v.args) != 0 && v.pos.line != v.args[len(v.args) - 1].pos.line {
-			visit_begin_brace(p, v.pos, .Generic);
-			newline_position(p, 1);
-			set_source_position(p, v.args[0].pos);
-			visit_exprs(p, v.args, true, true);
-			visit_end_brace(p, v.end);
-		} else {
-			push_generic_token(p, .Open_Brace, 0);
-			visit_exprs(p, v.args, true);
-			push_generic_token(p, .Close_Brace, 0);
-		}
-		
-	case Comp_Lit:
-		
-		if v.type != nil {
-			visit_expr(p, v.type);
-		}
-
-		if len(v.elems) != 0 && v.pos.line != v.elems[len(v.elems) - 1].pos.line {
-			visit_begin_brace(p, v.pos, .Comp_Lit);
-			newline_position(p, 1);
-			set_source_position(p, v.elems[0].pos);
-			visit_exprs(p, v.elems, true, true);
-			visit_end_brace(p, v.end);
-		} else {
-			push_generic_token(p, .Open_Brace, 0);
-			visit_exprs(p, v.elems, true);
-			push_generic_token(p, .Close_Brace, 0);
-		}
-		
-	case Unary_Expr:
-		push_generic_token(p, v.op.kind, 1);
-		merge_next_token(p);
-		visit_expr(p, v.expr);
-	case Field_Value:
-		visit_expr(p, v.field);
-		push_generic_token(p, .Eq, 1);
-		visit_expr(p, v.value);
-	case Type_Assertion:
-		visit_expr(p, v.expr);
-
-		if unary, ok := v.type.derived.(Unary_Expr); ok && unary.op.text == "?" {
-			push_generic_token(p, .Period, 0);
-			visit_expr(p, v.type);
-		} else {
-			push_generic_token(p, .Period, 0);
-			push_generic_token(p, .Open_Paren, 0);
-			visit_expr(p, v.type);
-			push_generic_token(p, .Close_Paren, 0);
-		}
-
-	case Pointer_Type:
-		push_generic_token(p, .Pointer, 1);
-		merge_next_token(p);
-		visit_expr(p, v.elem);
-	case Implicit:
-		push_generic_token(p, v.tok.kind, 1);
-	case Poly_Type:
-		push_generic_token(p, .Dollar, 1);
-		merge_next_token(p);
-		visit_expr(p, v.type);
-
-		if v.specialization != nil {
-			push_generic_token(p, .Quo, 0);
-			merge_next_token(p);
-			visit_expr(p, v.specialization);
-		}
-	case Array_Type:
-		visit_expr(p, v.tag);
-		push_generic_token(p, .Open_Bracket, 1);
-		visit_expr(p, v.len);
-		push_generic_token(p, .Close_Bracket, 0);
-		visit_expr(p, v.elem);
-	case Map_Type:
-		push_generic_token(p, .Map, 1);
-		push_generic_token(p, .Open_Bracket, 0);
-		visit_expr(p, v.key);
-		push_generic_token(p, .Close_Bracket, 0);
-		visit_expr(p, v.value);
-	case Helper_Type:
-		visit_expr(p, v.type);
-	case:
-		panic(fmt.aprint(expr.derived));
-	}
-}
+    using ast;
 
+    if expr == nil {
+        return;
+    }
+
+    set_source_position(p, expr.pos);
+
+    switch v in expr.derived {
+    case Inline_Asm_Expr:
+        push_generic_token(p, v.tok.kind, 1, v.tok.text);
+
+        push_generic_token(p, .Open_Paren, 1);
+        visit_exprs(p, v.param_types, true, false);
+        push_generic_token(p, .Close_Paren, 0);
+
+        push_generic_token(p, .Sub, 1);
+        push_generic_token(p, .Gt, 0);
+
+        visit_expr(p, v.return_type);
+
+        push_generic_token(p, .Open_Brace, 1);
+        visit_expr(p, v.asm_string);
+        push_generic_token(p, .Comma, 0);
+        visit_expr(p, v.constraints_string);
+        push_generic_token(p, .Close_Brace, 0);
+    case Undef:
+        push_generic_token(p, .Undef, 1);
+    case Auto_Cast:
+        push_generic_token(p, v.op.kind, 1);
+        visit_expr(p, v.expr);
+    case Ternary_Expr:
+        visit_expr(p, v.cond);
+        push_generic_token(p, v.op1.kind, 1);
+        visit_expr(p, v.x);
+        push_generic_token(p, v.op2.kind, 1);
+        visit_expr(p, v.y);
+    case Ternary_If_Expr:
+        visit_expr(p, v.x);
+        push_generic_token(p, v.op1.kind, 1);
+        visit_expr(p, v.cond);
+        push_generic_token(p, v.op2.kind, 1);
+        visit_expr(p, v.y);
+    case Ternary_When_Expr:
+        visit_expr(p, v.x);
+        push_generic_token(p, v.op1.kind, 1);
+        visit_expr(p, v.cond);
+        push_generic_token(p, v.op2.kind, 1);
+        visit_expr(p, v.y);
+    case Selector_Call_Expr:
+        visit_expr(p, v.call.expr);
+        push_generic_token(p, .Open_Paren, 1);
+        visit_exprs(p, v.call.args, true);
+        push_generic_token(p, .Close_Paren, 0);
+    case Ellipsis:
+        push_generic_token(p, .Ellipsis, 1);
+        visit_expr(p, v.expr);
+    case Relative_Type:
+        visit_expr(p, v.tag);
+        visit_expr(p, v.type);
+    case Slice_Expr:
+        visit_expr(p, v.expr);
+        push_generic_token(p, .Open_Bracket, 0);
+        visit_expr(p, v.low);
+        push_generic_token(p, v.interval.kind, 0);
+        if v.high != nil {
+            merge_next_token(p);
+            visit_expr(p, v.high);
+        }
+        push_generic_token(p, .Close_Bracket, 0);
+    case Ident:
+        push_ident_token(p, v.name, 1);
+    case Deref_Expr:
+        visit_expr(p, v.expr);
+        push_generic_token(p, v.op.kind, 0);
+    case Type_Cast:
+        push_generic_token(p, v.tok.kind, 1);
+        push_generic_token(p, .Open_Paren, 0);
+        visit_expr(p, v.type);
+        push_generic_token(p, .Close_Paren, 0);
+        merge_next_token(p);
+        visit_expr(p, v.expr);
+    case Basic_Directive:
+        push_generic_token(p, v.tok.kind, 1);
+        push_ident_token(p, v.name, 0);
+    case Distinct_Type:
+        push_generic_token(p, .Distinct, 1);
+        visit_expr(p, v.type);
+    case Dynamic_Array_Type:
+        visit_expr(p, v.tag);
+        push_generic_token(p, .Open_Bracket, 1);
+        push_generic_token(p, .Dynamic, 0);
+        push_generic_token(p, .Close_Bracket, 0);
+        visit_expr(p, v.elem);
+    case Bit_Set_Type:
+        push_generic_token(p, .Bit_Set, 1);
+        push_generic_token(p, .Open_Bracket, 0);
+
+        visit_expr(p, v.elem);
+
+        if v.underlying != nil {
+            push_generic_token(p, .Semicolon, 0);
+            visit_expr(p, v.underlying);
+        }
+
+        push_generic_token(p, .Close_Bracket, 0);
+    case Union_Type:
+        push_generic_token(p, .Union, 1);
+
+        if v.poly_params != nil {
+            push_generic_token(p, .Open_Paren, 0);
+            visit_field_list(p, v.poly_params, true, false);
+            push_generic_token(p, .Close_Paren, 0);
+        }
+
+        if v.is_maybe {
+            push_ident_token(p, "#maybe", 1);
+        }
+
+        if v.where_clauses != nil {
+            move_line(p, v.where_clauses[0].pos);
+            push_generic_token(p, .Where, 1);
+            visit_exprs(p, v.where_clauses, true);
+        }
+
+        if v.variants != nil && (len(v.variants) == 0 || v.pos.line == v.end.line) {
+            push_generic_token(p, .Open_Brace, 1);
+            visit_exprs(p, v.variants, true);
+            push_generic_token(p, .Close_Brace, 0);
+        } else {
+            visit_begin_brace(p, v.pos, .Generic);
+            newline_position(p, 1);
+            set_source_position(p, v.variants[0].pos);
+            visit_exprs(p, v.variants, true, true);
+            visit_end_brace(p, v.end);
+        }
+    case Enum_Type:
+        push_generic_token(p, .Enum, 1);
+
+        if v.base_type != nil {
+            visit_expr(p, v.base_type);
+        }
+
+        if v.fields != nil && (len(v.fields) == 0 || v.pos.line == v.end.line) {
+            push_generic_token(p, .Open_Brace, 1);
+            visit_exprs(p, v.fields, true);
+            push_generic_token(p, .Close_Brace, 0);
+        } else {
+            visit_begin_brace(p, v.pos, .Generic);
+            newline_position(p, 1);
+            set_source_position(p, v.fields[0].pos);
+            visit_exprs(p, v.fields, true, true);
+            visit_end_brace(p, v.end);
+        }
+
+        set_source_position(p, v.end);
+    case Struct_Type:
+        push_generic_token(p, .Struct, 1);
+
+        hint_current_line(p,{.Struct});
+
+        if v.is_packed {
+            push_ident_token(p, "#packed", 1);
+        }
+
+        if v.is_raw_union {
+            push_ident_token(p, "#raw_union", 1);
+        }
+
+        if v.align != nil {
+            push_ident_token(p, "#align", 1);
+            visit_expr(p, v.align);
+        }
+
+        if v.poly_params != nil {
+            push_generic_token(p, .Open_Paren, 0);
+            visit_field_list(p, v.poly_params, true, false);
+            push_generic_token(p, .Close_Paren, 0);
+        }
+
+        if v.where_clauses != nil {
+            move_line(p, v.where_clauses[0].pos);
+            push_generic_token(p, .Where, 1);
+            visit_exprs(p, v.where_clauses, true);
+        }
+
+        if v.fields != nil && (len(v.fields.list) == 0 || v.pos.line == v.end.line) {
+            push_generic_token(p, .Open_Brace, 1);
+            set_source_position(p, v.fields.pos);
+            visit_field_list(p, v.fields, true);
+            push_generic_token(p, .Close_Brace, 0);
+        } else if v.fields != nil {
+            visit_begin_brace(p, v.pos, .Generic, len(v.fields.list));
+            set_source_position(p, v.fields.pos);
+            visit_field_list(p, v.fields, true, true, true);
+            visit_end_brace(p, v.end);
+        }
+
+        set_source_position(p, v.end);
+    case Proc_Lit:
+
+        if v.inlining == .Inline {
+            push_ident_token(p, "#force_inline", 0);
+        }
+
+        visit_proc_type(p, v.type^);
+
+        if v.where_clauses != nil {
+            move_line(p, v.where_clauses[0].pos);
+            push_generic_token(p, .Where, 1);
+            visit_exprs(p, v.where_clauses, true);
+        }
+
+        if v.body != nil {
+            set_source_position(p, v.body.pos);
+            visit_stmt(p, v.body, .Proc);
+        } else {
+            push_generic_token(p, .Undef, 1);
+        }
+    case Proc_Type:
+        visit_proc_type(p, v);
+    case Basic_Lit:
+        push_generic_token(p, v.tok.kind, 1, v.tok.text);
+    case Binary_Expr:
+        visit_binary_expr(p, v);
+    case Implicit_Selector_Expr:
+        push_generic_token(p, .Period, 1);
+        push_ident_token(p, v.field.name, 0);
+    case Call_Expr:
+        visit_expr(p, v.expr);
+        push_generic_token(p, .Open_Paren, 0);
+        visit_call_exprs(p, v.args, v.ellipsis.kind == .Ellipsis);
+        push_generic_token(p, .Close_Paren, 0);
+    case Typeid_Type:
+        push_generic_token(p, .Typeid, 1);
+
+        if v.specialization != nil {
+            push_generic_token(p, .Quo, 0);
+            visit_expr(p, v.specialization);
+        }
+    case Selector_Expr:
+        visit_expr(p, v.expr);
+        push_generic_token(p, v.op.kind, 0);
+        visit_expr(p, v.field);
+    case Paren_Expr:
+        push_generic_token(p, .Open_Paren, 1);
+        visit_expr(p, v.expr);
+        push_generic_token(p, .Close_Paren, 0);
+    case Index_Expr:
+        visit_expr(p, v.expr);
+        push_generic_token(p, .Open_Bracket, 0);
+        visit_expr(p, v.index);
+        push_generic_token(p, .Close_Bracket, 0);
+    case Proc_Group:
+
+        push_generic_token(p, v.tok.kind, 0);
+
+        if len(v.args) != 0 && v.pos.line != v.args[len(v.args) - 1].pos.line {
+            visit_begin_brace(p, v.pos, .Generic);
+            newline_position(p, 1);
+            set_source_position(p, v.args[0].pos);
+            visit_exprs(p, v.args, true, true);
+            visit_end_brace(p, v.end);
+        } else {
+            push_generic_token(p, .Open_Brace, 0);
+            visit_exprs(p, v.args, true);
+            push_generic_token(p, .Close_Brace, 0);
+        }
+
+    case Comp_Lit:
+
+        if v.type != nil {
+            visit_expr(p, v.type);
+        }
+
+        if len(v.elems) != 0 && v.pos.line != v.elems[len(v.elems) - 1].pos.line {
+            visit_begin_brace(p, v.pos, .Comp_Lit);
+            newline_position(p, 1);
+            set_source_position(p, v.elems[0].pos);
+            visit_exprs(p, v.elems, true, true);
+            visit_end_brace(p, v.end);
+        } else {
+            push_generic_token(p, .Open_Brace, 0);
+            visit_exprs(p, v.elems, true);
+            push_generic_token(p, .Close_Brace, 0);
+        }
+
+    case Unary_Expr:
+        push_generic_token(p, v.op.kind, 1);
+        merge_next_token(p);
+        visit_expr(p, v.expr);
+    case Field_Value:
+        visit_expr(p, v.field);
+        push_generic_token(p, .Eq, 1);
+        visit_expr(p, v.value);
+    case Type_Assertion:
+        visit_expr(p, v.expr);
+
+        if unary, ok := v.type.derived.(Unary_Expr); ok && unary.op.text == "?" {
+            push_generic_token(p, .Period, 0);
+            visit_expr(p, v.type);
+        } else {
+            push_generic_token(p, .Period, 0);
+            push_generic_token(p, .Open_Paren, 0);
+            visit_expr(p, v.type);
+            push_generic_token(p, .Close_Paren, 0);
+        }
+
+    case Pointer_Type:
+        push_generic_token(p, .Pointer, 1);
+        merge_next_token(p);
+        visit_expr(p, v.elem);
+    case Implicit:
+        push_generic_token(p, v.tok.kind, 1);
+    case Poly_Type:
+        push_generic_token(p, .Dollar, 1);
+        merge_next_token(p);
+        visit_expr(p, v.type);
+
+        if v.specialization != nil {
+            push_generic_token(p, .Quo, 0);
+            merge_next_token(p);
+            visit_expr(p, v.specialization);
+        }
+    case Array_Type:
+        visit_expr(p, v.tag);
+        push_generic_token(p, .Open_Bracket, 1);
+        visit_expr(p, v.len);
+        push_generic_token(p, .Close_Bracket, 0);
+        visit_expr(p, v.elem);
+    case Map_Type:
+        push_generic_token(p, .Map, 1);
+        push_generic_token(p, .Open_Bracket, 0);
+        visit_expr(p, v.key);
+        push_generic_token(p, .Close_Bracket, 0);
+        visit_expr(p, v.value);
+    case Helper_Type:
+        visit_expr(p, v.type);
+    case:
+        panic(fmt.aprint(expr.derived));
+    }
+}
 
 visit_begin_brace :: proc(p: ^Printer, begin: tokenizer.Pos, type: Block_Type, count := 0) {
 
-	set_source_position(p, begin);
-
-	newline_braced := p.config.brace_style == .Allman;
-	newline_braced |= p.config.brace_style == .K_And_R && type == .Proc;
-	newline_braced &= p.config.brace_style != ._1TBS;
-
-	format_token := Format_Token {
-		kind = .Open_Brace,
-		parameter_count = count,
-		text = "{",
-	};
-
-	if newline_braced {
-		newline_position(p, 1);
-		push_format_token(p, format_token);
-		indent(p);
-	} else {
-		format_token.spaces_before = 1;
-		push_format_token(p, format_token);
-		indent(p);
-	}
+    set_source_position(p, begin);
+
+    newline_braced := p.config.brace_style == .Allman;
+    newline_braced |= p.config.brace_style == .K_And_R && type == .Proc;
+    newline_braced &= p.config.brace_style != ._1TBS;
+
+    format_token := Format_Token {
+        kind = .Open_Brace,
+        parameter_count = count,
+        text = "{",
+    };
+
+    if newline_braced {
+        newline_position(p, 1);
+        push_format_token(p, format_token);
+        indent(p);
+    } else {
+        format_token.spaces_before = 1;
+        push_format_token(p, format_token);
+        indent(p);
+    }
 }
 
 visit_end_brace :: proc(p: ^Printer, end: tokenizer.Pos) {
-	set_source_position(p, end);
-	newline_position(p, 1);
-	push_generic_token(p, .Close_Brace, 0);
-	unindent(p); 
-	p.current_line.depth = p.depth;
+    set_source_position(p, end);
+    newline_position(p, 1);
+    push_generic_token(p, .Close_Brace, 0);
+    unindent(p);
+    p.current_line.depth = p.depth;
 }
 
-visit_block_stmts :: proc(p: ^Printer, stmts: []^ast.Stmt, split := false) {
-	for stmt, i in stmts {
-		visit_stmt(p, stmt, .Generic, false, true);
+visit_block_stmts :: proc(p: ^Printer, stmts: [] ^ast.Stmt, split := false) {
+    for stmt, i in stmts {
+        visit_stmt(p, stmt, .Generic, false, true);
 
-		if split && i != len(stmts)-1 && stmt.pos.line == stmts[i+1].pos.line {
-			newline_position(p, 1);
-		}
-	}
+        if split && i != len(stmts) - 1 && stmt.pos.line == stmts[i + 1].pos.line {
+            newline_position(p, 1);
+        }
+    }
 }
 
 visit_field_list :: proc(p: ^Printer, list: ^ast.Field_List, add_comma := false, trailing := false, enforce_newline := false) {
 
-	if list.list == nil {
-		return;
-	}
-
-	for field, i in list.list {
-
-		if !move_line_limit(p, field.pos, 1) && enforce_newline {
-			newline_position(p, 1);
-		}	
-
-		if .Using in field.flags {
-			push_generic_token(p, .Using, 0);
-		}
-
-		visit_exprs(p, field.names, true);
-
-		if field.type != nil {
-			if len(field.names) != 0 {
-				push_generic_token(p, .Colon, 0);
-			}
-			visit_expr(p, field.type);
-		} else {
-			push_generic_token(p, .Colon, 1);
-			push_generic_token(p, .Eq, 0);
-			visit_expr(p, field.default_value);
-		}
-
-		if field.tag.text != "" {
-			push_generic_token(p, field.tag.kind, 1, field.tag.text);
-		}
-
-		if (i != len(list.list) - 1 || trailing) && add_comma {
-			push_generic_token(p, .Comma, 0);
-		}
-	}
+    if list.list == nil {
+        return;
+    }
+
+    for field, i in list.list {
+
+        if !move_line_limit(p, field.pos, 1) && enforce_newline {
+            newline_position(p, 1);
+        }
+
+        if .Using in field.flags {
+            push_generic_token(p, .Using, 0);
+        }
+
+        visit_exprs(p, field.names, true);
+
+        if field.type != nil {
+            if len(field.names) != 0 {
+                push_generic_token(p, .Colon, 0);
+            }
+            visit_expr(p, field.type);
+        } else {
+            push_generic_token(p, .Colon, 1);
+            push_generic_token(p, .Eq, 0);
+            visit_expr(p, field.default_value);
+        }
+
+        if field.tag.text != "" {
+            push_generic_token(p, field.tag.kind, 1, field.tag.text);
+        }
+
+        if (i != len(list.list) - 1 || trailing) && add_comma {
+            push_generic_token(p, .Comma, 0);
+        }
+    }
 }
 
 visit_proc_type :: proc(p: ^Printer, proc_type: ast.Proc_Type) {
 
-	push_generic_token(p, .Proc, 1);
-
-	explicit_calling := false;
-
-	switch proc_type.calling_convention {
-	case .Odin:
-	case .Contextless:
-		push_string_token(p, "\"contextless\"", 1);
-		explicit_calling = true;
-	case .C_Decl:
-		push_string_token(p, "\"c\"", 1);
-		explicit_calling = true;
-	case .Std_Call:
-		push_string_token(p, "\"std\"", 1);
-		explicit_calling = true;
-	case .Fast_Call:
-		push_string_token(p, "\"fast\"", 1);
-		explicit_calling = true;
-	case .None:
-			//nothing i guess
-	case .Invalid:
-			//nothing i guess
-	case .Foreign_Block_Default:
-	}
-
-	if explicit_calling {
-		push_generic_token(p, .Open_Paren, 1);
-	} else {
-		push_generic_token(p, .Open_Paren, 0);
-	}
-
-	visit_signature_list(p, proc_type.params, false);
-
-	push_generic_token(p, .Close_Paren, 0);
-
-	if proc_type.results != nil {
-		push_generic_token(p, .Sub, 1);
-		push_generic_token(p, .Gt, 0);
-
-		use_parens := false;
-		use_named  := false;
-
-		if len(proc_type.results.list) > 1 {
-			use_parens = true;
-		} else if len(proc_type.results.list) == 1 {
-
-			for name in proc_type.results.list[0].names {
-				if ident, ok := name.derived.(ast.Ident); ok {
-					if ident.name != "_" {
-						use_parens = true;
-					}
-				}
-			}
-		}
-
-		if use_parens {
-			push_generic_token(p, .Open_Paren, 1);
-			visit_signature_list(p, proc_type.results);
-			push_generic_token(p, .Close_Paren, 0);
-		} else {
-			visit_signature_list(p, proc_type.results);
-		}
-	}
-	
+    push_generic_token(p, .Proc, 1);
+
+    explicit_calling := false;
+
+    switch proc_type.calling_convention {
+    case .Odin:
+    case .Contextless:
+        push_string_token(p, "\"contextless\"", 1);
+        explicit_calling = true;
+    case .C_Decl:
+        push_string_token(p, "\"c\"", 1);
+        explicit_calling = true;
+    case .Std_Call:
+        push_string_token(p, "\"std\"", 1);
+        explicit_calling = true;
+    case .Fast_Call:
+        push_string_token(p, "\"fast\"", 1);
+        explicit_calling = true;
+    case .None:
+    //nothing i guess
+    case .Invalid:
+    //nothing i guess
+    case .Foreign_Block_Default:
+    }
+
+    if explicit_calling {
+        push_generic_token(p, .Open_Paren, 1);
+    } else {
+        push_generic_token(p, .Open_Paren, 0);
+    }
+
+    visit_signature_list(p, proc_type.params, false);
+
+    push_generic_token(p, .Close_Paren, 0);
+
+    if proc_type.results != nil {
+        push_generic_token(p, .Sub, 1);
+        push_generic_token(p, .Gt, 0);
+
+        use_parens := false;
+        use_named := false;
+
+        if len(proc_type.results.list) > 1 {
+            use_parens = true;
+        } else if len(proc_type.results.list) == 1 {
+
+            for name in proc_type.results.list[0].names {
+                if ident, ok := name.derived.(ast.Ident); ok {
+                    if ident.name != "_" {
+                        use_parens = true;
+                    }
+                }
+            }
+        }
+
+        if use_parens {
+            push_generic_token(p, .Open_Paren, 1);
+            visit_signature_list(p, proc_type.results);
+            push_generic_token(p, .Close_Paren, 0);
+        } else {
+            visit_signature_list(p, proc_type.results);
+        }
+    }
 }
 
 visit_binary_expr :: proc(p: ^Printer, binary: ast.Binary_Expr) {
 
-	move_line(p, binary.left.pos);
-
-	if v, ok := binary.left.derived.(ast.Binary_Expr); ok {
-		visit_binary_expr(p, v);
-	} else {
-		visit_expr(p, binary.left);
-	}
+    move_line(p, binary.left.pos);
 
-	if binary.op.kind == .Ellipsis || binary.op.kind == .Range_Half {
-		push_generic_token(p, binary.op.kind, 0);
-	} else {
-		push_generic_token(p, binary.op.kind, 1);
-	}
+    if v, ok := binary.left.derived.(ast.Binary_Expr); ok {
+        visit_binary_expr(p, v);
+    } else {
+        visit_expr(p, binary.left);
+    }
 
-	move_line(p, binary.right.pos);
+    if binary.op.kind == .Ellipsis || binary.op.kind == .Range_Half {
+        push_generic_token(p, binary.op.kind, 0);
+    } else {
+        push_generic_token(p, binary.op.kind, 1);
+    }
 
-	if v, ok := binary.right.derived.(ast.Binary_Expr); ok {
-		visit_binary_expr(p, v);
-	} else {
-		visit_expr(p, binary.right);
-	}
+    move_line(p, binary.right.pos);
 
+    if v, ok := binary.right.derived.(ast.Binary_Expr); ok {
+        visit_binary_expr(p, v);
+    } else {
+        visit_expr(p, binary.right);
+    }
 }
 
-visit_call_exprs :: proc(p: ^Printer, list: []^ast.Expr, ellipsis := false) {
+visit_call_exprs :: proc(p: ^Printer, list: [] ^ast.Expr, ellipsis := false) {
 
-	if len(list) == 0 {
-		return;
-	}
+    if len(list) == 0 {
+        return;
+    }
 
-	//all the expression are on the line
-	if list[0].pos.line == list[len(list) - 1].pos.line {
-		for expr, i in list {
+    //all the expression are on the line
+    if list[0].pos.line == list[len(list) - 1].pos.line {
+        for expr, i in list {
 
-			if i == len(list) - 1 && ellipsis {
-				push_generic_token(p, .Ellipsis, 0);
-			}
+            if i == len(list) - 1 && ellipsis {
+                push_generic_token(p, .Ellipsis, 0);
+            }
 
-			visit_expr(p, expr);
+            visit_expr(p, expr);
 
-			if i != len(list) - 1 {
-				push_generic_token(p, .Comma, 0);
-			}
-		}
-	} else {
-		for expr, i in list {
+            if i != len(list) - 1 {
+                push_generic_token(p, .Comma, 0);
+            }
+        }
+    } else {
+        for expr, i in list {
 
-			//we have to newline the expressions to respect the source
-			move_line_limit(p, expr.pos, 1);
-			
+            //we have to newline the expressions to respect the source
+            move_line_limit(p, expr.pos, 1);
 
-			if i == len(list) - 1 && ellipsis {
-				push_generic_token(p, .Ellipsis, 0);
-			}
+            if i == len(list) - 1 && ellipsis {
+                push_generic_token(p, .Ellipsis, 0);
+            }
 
-			visit_expr(p, expr);
+            visit_expr(p, expr);
 
-			if i != len(list) - 1 {
-				push_generic_token(p, .Comma, 0);
-			}
-		}
-	}
+            if i != len(list) - 1 {
+                push_generic_token(p, .Comma, 0);
+            }
+        }
+    }
 }
 
-
 visit_signature_list :: proc(p: ^Printer, list: ^ast.Field_List, remove_blank := true) {
 
-	if list.list == nil {
-		return;
-	}
-
-	for field, i in list.list {
-
-		move_line_limit(p, field.pos, 1);
-
-		if .Using in field.flags {
-			push_generic_token(p, .Using, 0);
-		}
-
-		named := false;
-
-		for name in field.names {
-			if ident, ok := name.derived.(ast.Ident); ok {
-				//for some reason the parser uses _ to mean empty
-				if ident.name != "_" || !remove_blank {
-					named = true;
-				}
-			} else {
-				//alternative is poly names
-				named = true;
-			}
-		}
-
-		if named {
-			visit_exprs(p, field.names, true);
-
-			if len(field.names) != 0 && field.type != nil {
-				push_generic_token(p, .Colon, 0);
-			} 
-		}
-
-		if field.type != nil && field.default_value != nil {
-			visit_expr(p, field.type);
-			push_generic_token(p, .Eq, 0);
-			visit_expr(p, field.default_value);
-		} else if field.type != nil {
-			visit_expr(p, field.type);
-		} else {
-			push_generic_token(p, .Colon, 1);
-			push_generic_token(p, .Eq, 0);
-			visit_expr(p, field.default_value);
-		}
-
-		if i != len(list.list) - 1 {
-			push_generic_token(p, .Comma, 0);
-		}
-	}
-}
+    if list.list == nil {
+        return;
+    }
+
+    for field, i in list.list {
+
+        move_line_limit(p, field.pos, 1);
+
+        if .Using in field.flags {
+            push_generic_token(p, .Using, 0);
+        }
 
+        named := false;
+
+        for name in field.names {
+            if ident, ok := name.derived.(ast.Ident); ok {
+                //for some reason the parser uses _ to mean empty
+                if ident.name != "_" || !remove_blank {
+                    named = true;
+                }
+            } else {
+                //alternative is poly names
+                named = true;
+            }
+        }
+
+        if named {
+            visit_exprs(p, field.names, true);
+
+            if len(field.names) != 0 && field.type != nil {
+                push_generic_token(p, .Colon, 0);
+            }
+        }
+
+        if field.type != nil && field.default_value != nil {
+            visit_expr(p, field.type);
+            push_generic_token(p, .Eq, 1);
+            visit_expr(p, field.default_value);
+        } else if field.type != nil {
+            visit_expr(p, field.type);
+        } else {
+            push_generic_token(p, .Colon, 1);
+            push_generic_token(p, .Eq, 0);
+            visit_expr(p, field.default_value);
+        }
+
+        if i != len(list.list) - 1 {
+            push_generic_token(p, .Comma, 0);
+        }
+    }
+}