浏览代码

damn, ran the odinfmt with spaces instead of tabs...

Daniel Gavin 4 年之前
父节点
当前提交
a12db382e0
共有 2 个文件被更改,包括 1515 次插入1515 次删除
  1. 342 342
      core/odin/printer/printer.odin
  2. 1173 1173
      core/odin/printer/visit.odin

+ 342 - 342
core/odin/printer/printer.odin

@@ -13,184 +13,184 @@ 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
+	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
 }
 
 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,
-    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,
+	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,
+	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,
 }
 
 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 = .CRLF,
+	spaces = 4,
+	newline_limit = 2,
+	convert_do = false,
+	semicolons = true,
+	tabs = true,
+	brace_style = ._1TBS,
+	split_multiple_stmts = true,
+	align_assignments = true,
+	align_style = .Align_On_Type_And_Equals,
+	indent_cases = false,
+	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;
+	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);
-    }
+	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);
+	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);
-    }
+	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);
+	builder := strings.make_builder(0, mem.megabytes(5), p.allocator);
 
-    last_line := 0;
+	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 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);
-        }
+		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.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));
-        }
+		if p.debug {
+			strings.write_string(&builder, fmt.tprintf("line %v: ", line_index));
+		}
 
-        for format_token in line.format_tokens {
+		for format_token in line.format_tokens {
 
-            for i := 0; i < format_token.spaces_before; i += 1 {
-                strings.write_byte(&builder, ' ');
-            }
+			for i := 0; i < format_token.spaces_before; i += 1 {
+				strings.write_byte(&builder, ' ');
+			}
 
-            strings.write_string(&builder, format_token.text);
-        }
+			strings.write_string(&builder, format_token.text);
+		}
 
-        last_line = line_index;
-    }
+		last_line = line_index;
+	}
 
-    return strings.to_string(builder);
+	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) {
@@ -198,277 +198,277 @@ 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;
-            }
-        }
-    }
-
-    if !switch_found {
-        return;
-    }
-
-    largest := 0;
-    case_count := 0;
-
-    //find all the switch cases that are one lined
-    for line, line_index in p.lines[brace_line + 1:] {
-
-        case_found := false;
-        colon_found := false;
-        length := 0;
-
-        for format_token in line.format_tokens {
-
-            if format_token.kind == .Comment {
-                continue;
-            }
-
-            //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;
-            }
-
-            length += len(format_token.text) + format_token.spaces_before;
-        }
-
-        if case_count >= brace_token.parameter_count {
-            break;
-        }
-    }
-
-    case_count = 0;
-
-    for line, line_index in p.lines[brace_line + 1:] {
-
-        case_found := false;
-        colon_found := false;
-        length := 0;
-
-        for format_token, i in line.format_tokens {
-
-            if format_token.kind == .Comment {
-                continue;
-            }
-
-            //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;
-            }
-
-            length += len(format_token.text) + format_token.spaces_before;
-        }
-
-        if case_count >= brace_token.parameter_count {
-            break;
-        }
-    }
+	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;
+			}
+		}
+	}
+
+	if !switch_found {
+		return;
+	}
+
+	largest := 0;
+	case_count := 0;
+
+	//find all the switch cases that are one lined
+	for line, line_index in p.lines[brace_line + 1:] {
+
+		case_found := false;
+		colon_found := false;
+		length := 0;
+
+		for format_token in line.format_tokens {
+
+			if format_token.kind == .Comment {
+				continue;
+			}
+
+			//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;
+			}
+
+			length += len(format_token.text) + format_token.spaces_before;
+		}
+
+		if case_count >= brace_token.parameter_count {
+			break;
+		}
+	}
+
+	case_count = 0;
+
+	for line, line_index in p.lines[brace_line + 1:] {
+
+		case_found := false;
+		colon_found := false;
+		length := 0;
+
+		for format_token, i in line.format_tokens {
+
+			if format_token.kind == .Comment {
+				continue;
+			}
+
+			//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;
+			}
+
+			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;
+	struct_found := false;
+	brace_token: Format_Token;
+	brace_line: int;
 
-    found_struct_brace: for line, line_index in p.lines[index:] {
+	found_struct_brace: for line, line_index in p.lines[index:] {
 
-        for format_token in line.format_tokens {
+		for format_token in line.format_tokens {
 
-            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;
-            }
-        }
-    }
+			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;
+			}
+		}
+	}
 
-    if !struct_found {
-        return;
-    }
+	if !struct_found {
+		return;
+	}
 
-    largest := 0;
-    colon_count := 0;
+	largest := 0;
+	colon_count := 0;
 
-    for line, line_index in p.lines[brace_line + 1:] {
+	for line, line_index in p.lines[brace_line + 1:] {
 
-        length := 0;
+		length := 0;
 
-        for format_token in line.format_tokens {
+		for format_token in line.format_tokens {
 
-            if format_token.kind == .Comment {
-                continue;
-            }
+			if format_token.kind == .Comment {
+				continue;
+			}
 
-            if format_token.kind == .Colon {
-                colon_count += 1;
-                largest = max(length, largest);
-                break;
-            }
+			if format_token.kind == .Colon {
+				colon_count += 1;
+				largest = max(length, largest);
+				break;
+			}
 
-            length += len(format_token.text) + format_token.spaces_before;
-        }
+			length += len(format_token.text) + format_token.spaces_before;
+		}
 
-        if colon_count >= brace_token.parameter_count {
-            break;
-        }
-    }
+		if colon_count >= brace_token.parameter_count {
+			break;
+		}
+	}
 
-    colon_count = 0;
+	colon_count = 0;
 
-    for line, line_index in p.lines[brace_line + 1:] {
+	for line, line_index in p.lines[brace_line + 1:] {
 
-        length := 0;
+		length := 0;
 
-        for format_token, i in line.format_tokens {
+		for format_token, i in line.format_tokens {
 
-            if format_token.kind == .Comment {
-                continue;
-            }
+			if format_token.kind == .Comment {
+				continue;
+			}
 
-            if format_token.kind == .Colon {
-                colon_count += 1;
-                line.format_tokens[i + 1].spaces_before = largest - length + 1;
-                break;
-            }
+			if format_token.kind == .Colon {
+				colon_count += 1;
+				line.format_tokens[i + 1].spaces_before = largest - length + 1;
+				break;
+			}
 
-            length += len(format_token.text) + format_token.spaces_before;
-        }
+			length += len(format_token.text) + format_token.spaces_before;
+		}
 
-        if colon_count >= brace_token.parameter_count {
-            break;
-        }
-    }
+		if colon_count >= brace_token.parameter_count {
+			break;
+		}
+	}
 }
 
 align_blocks :: proc(p: ^Printer) {
 
-    for line, line_index in p.lines {
+	for line, line_index in p.lines {
 
-        if len(line.format_tokens) <= 0 {
-            continue;
-        }
+		if len(line.format_tokens) <= 0 {
+			continue;
+		}
 
-        if .Switch_Stmt in line.types && p.config.align_switch {
-            align_switch_smt(p, line_index);
-        }
+		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 .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_Align_Info :: struct {
+		length: int,
+		begin:  int,
+		end:    int,
+		depth:  int,
+	};
 
-    comment_infos := make([dynamic] Comment_Align_Info, 0, context.temp_allocator);
+	comment_infos := make([dynamic] Comment_Align_Info, 0, context.temp_allocator);
 
-    current_info: Comment_Align_Info;
+	current_info: Comment_Align_Info;
 
-    for line, line_index in p.lines {
+	for line, line_index in p.lines {
 
-        if len(line.format_tokens) <= 0 {
-            continue;
-        }
+		if len(line.format_tokens) <= 0 {
+			continue;
+		}
 
-        if .Line_Comment in line.types {
+		if .Line_Comment in line.types {
 
-            if current_info.end + 1 != line_index || current_info.depth != line.depth ||
-            (current_info.begin == current_info.end && current_info.length == 0) {
+			if current_info.end + 1 != line_index || current_info.depth != line.depth ||
+			(current_info.begin == current_info.end && current_info.length == 0) {
 
-                if (current_info.begin != 0 && current_info.end != 0) || current_info.length > 0 {
-                    append(&comment_infos, current_info);
-                }
+				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;
-            }
+				current_info.begin = line_index;
+				current_info.end = line_index;
+				current_info.depth = line.depth;
+				current_info.length = 0;
+			}
 
-            length := 0;
+			length := 0;
 
-            for format_token, i in line.format_tokens {
+			for format_token, i in line.format_tokens {
 
-                if format_token.kind == .Comment {
-                    current_info.length = max(current_info.length, length);
-                    current_info.end = line_index;
-                }
+				if format_token.kind == .Comment {
+					current_info.length = max(current_info.length, length);
+					current_info.end = line_index;
+				}
 
-                length += format_token.spaces_before + len(format_token.text);
-            }
-        }
-    }
+				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);
-    }
+	if (current_info.begin != 0 && current_info.end != 0) || current_info.length > 0 {
+		append(&comment_infos, current_info);
+	}
 
-    for info in comment_infos {
+	for info in comment_infos {
 
-        if info.begin == info.end || info.length == 0 {
-            continue;
-        }
+		if info.begin == info.end || info.length == 0 {
+			continue;
+		}
 
-        for i := info.begin; i <= info.end; i += 1 {
+		for i := info.begin; i <= info.end; i += 1 {
 
-            l := p.lines[i];
+			l := p.lines[i];
 
-            length := 0;
+			length := 0;
 
-            for format_token, i in l.format_tokens {
+			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;
-                    }
-                }
+				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);
-            }
-        }
-    }
+				length += format_token.spaces_before + len(format_token.text);
+			}
+		}
+	}
 }

+ 1173 - 1173
core/odin/printer/visit.odin

@@ -12,1453 +12,1453 @@ 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];
-        },
-    };
+	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)
 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;
+	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;
-    }
+	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);
+	push_comments(p, p.source_position);
 
-    unwrapped_line := p.current_line;
+	unwrapped_line := p.current_line;
 
-    if !unwrapped_line.used {
-        unwrapped_line.used = true;
-        unwrapped_line.depth = p.depth;
-    }
+	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;
-    }
+	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;
+	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];
+	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],
-    };
+	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);
+	p.last_token = append_format_token(p, format_token);
 }
 
 @(private)
 push_string_token :: proc(p: ^Printer, text: string, spaces_before: int) {
 
-    format_token := Format_Token {
-        spaces_before = spaces_before,
-        kind = .String,
-        text = text,
-    };
+	format_token := Format_Token {
+		spaces_before = spaces_before,
+		kind = .String,
+		text = text,
+	};
 
-    p.last_token = append_format_token(p, format_token);
+	p.last_token = append_format_token(p, format_token);
 }
 
 @(private)
 push_ident_token :: proc(p: ^Printer, text: string, spaces_before: int) {
 
-    format_token := Format_Token {
-        spaces_before = spaces_before,
-        kind = .Ident,
-        text = text,
-    };
+	format_token := Format_Token {
+		spaces_before = spaces_before,
+		kind = .Ident,
+		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];
-    } else {
-        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;
-
-    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 {
-            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);
-
-        push_generic_token(p, v.foreign_tok.kind, 0);
-        push_generic_token(p, v.import_tok.kind, 1);
-
-        if v.name != nil {
-            push_ident_token(p, v.name.name, 1);
-        }
-
-        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);
-
-        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);
-
-        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 {
-            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);
-        }
-
-        move_line(p, decl.pos);
-
-        if v.is_using {
-            push_generic_token(p, .Using, 0);
-        }
-
-        visit_exprs(p, v.names, true);
-
-        if v.type != nil {
-            if !v.is_mutable && v.type != nil {
-                push_generic_token(p, .Colon, 0);
-            } else {
-                push_generic_token(p, .Colon, 0);
-            }
-
-            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);
-            } else {
-                push_generic_token(p, .Colon, 1);
-            }
-        }
-
-        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 {
-            push_generic_token(p, .Colon, 0);
-        }
-
-        visit_exprs(p, v.values, 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;
-            }
-        }
-
-        if add_semicolon && p.config.semicolons && !p.skip_semicolon {
-            push_generic_token(p, .Semicolon, 0);
-        }
-
-    case:
-        panic(fmt.aprint(decl.derived));
-    }
+	using ast;
+
+	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 {
+			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);
+
+		push_generic_token(p, v.foreign_tok.kind, 0);
+		push_generic_token(p, v.import_tok.kind, 1);
+
+		if v.name != nil {
+			push_ident_token(p, v.name.name, 1);
+		}
+
+		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);
+
+		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);
+
+		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 {
+			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);
+		}
+
+		move_line(p, decl.pos);
+
+		if v.is_using {
+			push_generic_token(p, .Using, 0);
+		}
+
+		visit_exprs(p, v.names, true);
+
+		if v.type != nil {
+			if !v.is_mutable && v.type != nil {
+				push_generic_token(p, .Colon, 0);
+			} else {
+				push_generic_token(p, .Colon, 0);
+			}
+
+			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);
+			} else {
+				push_generic_token(p, .Colon, 1);
+			}
+		}
+
+		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 {
+			push_generic_token(p, .Colon, 0);
+		}
+
+		visit_exprs(p, v.values, 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;
+			}
+		}
+
+		if add_semicolon && p.config.semicolons && !p.skip_semicolon {
+			push_generic_token(p, .Semicolon, 0);
+		}
+
+	case:
+		panic(fmt.aprint(decl.derived));
+	}
 }
 
 @(private)
 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) {
 
-    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);
+	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);
+	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);
-    }
+	if v, ok := binary.left.derived.(ast.Binary_Expr); ok {
+		visit_binary_expr(p, v);
+	} else {
+		visit_expr(p, binary.left);
+	}
 
-    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 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);
+	}
 
-    move_line(p, binary.right.pos);
+	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);
-    }
+	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) {
 
-    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, 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);
-        }
-    }
+	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);
+		}
+	}
 }