mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-07 08:08:50 +00:00
format call and binary expression
This commit is contained in:
+174
-24
@@ -8,9 +8,9 @@ import "core:fmt"
|
|||||||
import "core:unicode/utf8"
|
import "core:unicode/utf8"
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
|
|
||||||
Line_Type_Enum :: enum {Line_Comment, Value_Decl, Switch_Stmt, Struct}
|
Type_Enum :: enum {Line_Comment, Value_Decl, Switch_Stmt, Struct, Assign, Call, Enum}
|
||||||
|
|
||||||
Line_Type :: bit_set[Line_Type_Enum];
|
Line_Type :: bit_set[Type_Enum];
|
||||||
|
|
||||||
Line :: struct {
|
Line :: struct {
|
||||||
format_tokens: [dynamic]Format_Token,
|
format_tokens: [dynamic]Format_Token,
|
||||||
@@ -23,6 +23,7 @@ Line :: struct {
|
|||||||
Format_Token :: struct {
|
Format_Token :: struct {
|
||||||
kind: tokenizer.Token_Kind,
|
kind: tokenizer.Token_Kind,
|
||||||
text: string,
|
text: string,
|
||||||
|
type: Type_Enum,
|
||||||
spaces_before: int,
|
spaces_before: int,
|
||||||
parameter_count: int,
|
parameter_count: int,
|
||||||
}
|
}
|
||||||
@@ -188,15 +189,182 @@ print :: proc(p: ^Printer, file: ^ast.File) -> string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fix_lines :: proc(p: ^Printer) {
|
fix_lines :: proc(p: ^Printer) {
|
||||||
align_var_decls(p);
|
align_var_decls_and_assignments(p);
|
||||||
align_blocks(p);
|
format_generic(p);
|
||||||
align_comments(p); //align them last since they rely on the other alignments
|
align_comments(p); //align them last since they rely on the other alignments
|
||||||
}
|
}
|
||||||
|
|
||||||
align_var_decls :: proc(p: ^Printer) {
|
format_value_decl :: proc(p: ^Printer, index: int) {
|
||||||
|
|
||||||
|
eq_found := false;
|
||||||
|
eq_token: Format_Token;
|
||||||
|
eq_line: int;
|
||||||
|
largest := 0;
|
||||||
|
|
||||||
|
found_eq: for line, line_index in p.lines[index:] {
|
||||||
|
for format_token in line.format_tokens {
|
||||||
|
|
||||||
|
largest += len(format_token.text) + format_token.spaces_before;
|
||||||
|
|
||||||
|
if format_token.kind == .Eq {
|
||||||
|
eq_token = format_token;
|
||||||
|
eq_line = line_index + index;
|
||||||
|
eq_found = true;
|
||||||
|
break found_eq;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
align_switch_smt :: proc(p: ^Printer, index: int) {
|
if !eq_found {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
align_next := false;
|
||||||
|
|
||||||
|
//check to see if there is a binary operator in the last token(this is guaranteed by the ast visit), otherwise it's not multilined
|
||||||
|
for line, line_index in p.lines[eq_line:] {
|
||||||
|
|
||||||
|
if len(line.format_tokens) == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if align_next {
|
||||||
|
line.format_tokens[0].spaces_before += largest + 1;
|
||||||
|
align_next = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
kind := find_last_token(line.format_tokens).kind;
|
||||||
|
|
||||||
|
if tokenizer.Token_Kind.B_Operator_Begin < kind && kind <= tokenizer.Token_Kind.Cmp_Or {
|
||||||
|
align_next = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !align_next {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
find_last_token :: proc(format_tokens: [dynamic]Format_Token) -> Format_Token {
|
||||||
|
|
||||||
|
for i := len(format_tokens)-1; i >= 0; i -= 1 {
|
||||||
|
|
||||||
|
if format_tokens[i].kind != .Comment {
|
||||||
|
return format_tokens[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
panic("not possible");
|
||||||
|
}
|
||||||
|
|
||||||
|
format_assignment :: proc(p: ^Printer, index: int) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
format_call :: proc(p: ^Printer, index: int) {
|
||||||
|
|
||||||
|
paren_found := false;
|
||||||
|
paren_token: Format_Token;
|
||||||
|
paren_line: int;
|
||||||
|
largest := 0;
|
||||||
|
|
||||||
|
found_paren: for line, line_index in p.lines[index:] {
|
||||||
|
for format_token in line.format_tokens {
|
||||||
|
|
||||||
|
largest += len(format_token.text) + format_token.spaces_before;
|
||||||
|
|
||||||
|
if format_token.kind == .Open_Paren && format_token.type == .Call {
|
||||||
|
paren_token = format_token;
|
||||||
|
paren_line = line_index + index;
|
||||||
|
paren_found = true;
|
||||||
|
break found_paren;
|
||||||
|
} else if format_token.kind == .Open_Paren {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !paren_found {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
paren_count := 1;
|
||||||
|
done := false;
|
||||||
|
|
||||||
|
for line, line_index in p.lines[paren_line+1:] {
|
||||||
|
|
||||||
|
if len(line.format_tokens) == 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for format_token, i in line.format_tokens {
|
||||||
|
|
||||||
|
if format_token.kind == .Open_Paren {
|
||||||
|
paren_count += 1;
|
||||||
|
} else if format_token.kind == .Close_Paren {
|
||||||
|
paren_count -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if paren_count == 0 {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
line.format_tokens[0].spaces_before += largest;
|
||||||
|
|
||||||
|
if done {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
format_generic :: proc(p: ^Printer) {
|
||||||
|
|
||||||
|
for line, line_index in p.lines {
|
||||||
|
|
||||||
|
if len(line.format_tokens) <= 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if .Switch_Stmt in line.types && p.config.align_switch {
|
||||||
|
align_switch_stmt(p, line_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if .Struct in line.types && p.config.align_structs {
|
||||||
|
align_struct(p, line_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if .Value_Decl in line.types {
|
||||||
|
format_value_decl(p, line_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if .Assign in line.types {
|
||||||
|
format_assignment(p, line_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if .Call in line.types {
|
||||||
|
format_call(p, line_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
align_var_decls_and_assignments :: proc(p: ^Printer) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
align_switch_stmt :: proc(p: ^Printer, index: int) {
|
||||||
|
|
||||||
switch_found := false;
|
switch_found := false;
|
||||||
brace_token: Format_Token;
|
brace_token: Format_Token;
|
||||||
@@ -375,24 +543,6 @@ align_struct :: proc(p: ^Printer, index: int) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
align_blocks :: proc(p: ^Printer) {
|
|
||||||
|
|
||||||
for line, line_index in p.lines {
|
|
||||||
|
|
||||||
if len(line.format_tokens) <= 0 {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if .Switch_Stmt in line.types && p.config.align_switch {
|
|
||||||
align_switch_smt(p, line_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
if .Struct in line.types && p.config.align_structs {
|
|
||||||
align_struct(p, line_index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
align_comments :: proc(p: ^Printer) {
|
align_comments :: proc(p: ^Printer) {
|
||||||
|
|
||||||
Comment_Align_Info :: struct {
|
Comment_Align_Info :: struct {
|
||||||
|
|||||||
@@ -185,7 +185,7 @@ push_comments :: proc(p: ^Printer, pos: tokenizer.Pos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if prev_comment != nil {
|
if prev_comment != nil {
|
||||||
newline_position(p, min(p.config.newline_limit, p.source_position.line - prev_comment.pos.line));
|
newline_position(p, min(p.config.newline_limit, p.source_position.line - prev_comment.pos.line - prev_comment_lines));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,18 +427,20 @@ visit_decl :: proc(p: ^Printer, decl: ^ast.Decl, called_in_stmt := false) {
|
|||||||
visit_exprs(p, v.names, true);
|
visit_exprs(p, v.names, true);
|
||||||
|
|
||||||
if v.type != nil {
|
if v.type != nil {
|
||||||
if !v.is_mutable && v.type != nil {
|
if !v.is_mutable {
|
||||||
push_generic_token(p, .Colon, 0);
|
push_generic_token(p, .Colon, 0);
|
||||||
} else {
|
} else {
|
||||||
|
hint_current_line(p, {.Value_Decl});
|
||||||
push_generic_token(p, .Colon, 0);
|
push_generic_token(p, .Colon, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
visit_expr(p, v.type);
|
visit_expr(p, v.type);
|
||||||
} else {
|
} else {
|
||||||
if !v.is_mutable && v.type == nil {
|
if !v.is_mutable {
|
||||||
push_generic_token(p, .Colon, 1);
|
push_generic_token(p, .Colon, 1);
|
||||||
push_generic_token(p, .Colon, 0);
|
push_generic_token(p, .Colon, 0);
|
||||||
} else {
|
} else {
|
||||||
|
hint_current_line(p, {.Value_Decl});
|
||||||
push_generic_token(p, .Colon, 1);
|
push_generic_token(p, .Colon, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -694,6 +696,8 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
|
|||||||
case Assign_Stmt:
|
case Assign_Stmt:
|
||||||
move_line(p, v.pos);
|
move_line(p, v.pos);
|
||||||
|
|
||||||
|
hint_current_line(p, {.Assign});
|
||||||
|
|
||||||
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);
|
||||||
@@ -730,11 +734,13 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
|
|||||||
}
|
}
|
||||||
|
|
||||||
if v.cond != nil {
|
if v.cond != nil {
|
||||||
|
move_line(p, v.cond.pos);
|
||||||
visit_expr(p, v.cond);
|
visit_expr(p, v.cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
if v.post != nil {
|
if v.post != nil {
|
||||||
push_generic_token(p, .Semicolon, 0);
|
push_generic_token(p, .Semicolon, 0);
|
||||||
|
move_line(p, v.post.pos);
|
||||||
visit_stmt(p, v.post);
|
visit_stmt(p, v.post);
|
||||||
} else if v.post == nil && v.cond != nil && v.init != nil {
|
} else if v.post == nil && v.cond != nil && v.init != nil {
|
||||||
push_generic_token(p, .Semicolon, 0);
|
push_generic_token(p, .Semicolon, 0);
|
||||||
@@ -946,6 +952,7 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr) {
|
|||||||
push_generic_token(p, .Open_Bracket, 1);
|
push_generic_token(p, .Open_Bracket, 1);
|
||||||
push_generic_token(p, .Dynamic, 0);
|
push_generic_token(p, .Dynamic, 0);
|
||||||
push_generic_token(p, .Close_Bracket, 0);
|
push_generic_token(p, .Close_Bracket, 0);
|
||||||
|
merge_next_token(p);
|
||||||
visit_expr(p, v.elem);
|
visit_expr(p, v.elem);
|
||||||
case Bit_Set_Type:
|
case Bit_Set_Type:
|
||||||
push_generic_token(p, .Bit_Set, 1);
|
push_generic_token(p, .Bit_Set, 1);
|
||||||
@@ -1083,7 +1090,15 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr) {
|
|||||||
push_ident_token(p, v.field.name, 0);
|
push_ident_token(p, v.field.name, 0);
|
||||||
case Call_Expr:
|
case Call_Expr:
|
||||||
visit_expr(p, v.expr);
|
visit_expr(p, v.expr);
|
||||||
push_generic_token(p, .Open_Paren, 0);
|
|
||||||
|
push_format_token(p, Format_Token {
|
||||||
|
kind = .Open_Paren,
|
||||||
|
type = .Call,
|
||||||
|
text = "(",
|
||||||
|
});
|
||||||
|
|
||||||
|
hint_current_line(p, {.Call});
|
||||||
|
|
||||||
visit_call_exprs(p, v.args, v.ellipsis.kind == .Ellipsis);
|
visit_call_exprs(p, v.args, v.ellipsis.kind == .Ellipsis);
|
||||||
push_generic_token(p, .Close_Paren, 0);
|
push_generic_token(p, .Close_Paren, 0);
|
||||||
case Typeid_Type:
|
case Typeid_Type:
|
||||||
@@ -1135,7 +1150,7 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr) {
|
|||||||
visit_exprs(p, v.elems, true, true);
|
visit_exprs(p, v.elems, true, true);
|
||||||
visit_end_brace(p, v.end);
|
visit_end_brace(p, v.end);
|
||||||
} else {
|
} else {
|
||||||
push_generic_token(p, .Open_Brace, 0);
|
push_generic_token(p, .Open_Brace, 1);
|
||||||
visit_exprs(p, v.elems, true);
|
visit_exprs(p, v.elems, true);
|
||||||
push_generic_token(p, .Close_Brace, 0);
|
push_generic_token(p, .Close_Brace, 0);
|
||||||
}
|
}
|
||||||
@@ -1182,12 +1197,14 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr) {
|
|||||||
push_generic_token(p, .Open_Bracket, 1);
|
push_generic_token(p, .Open_Bracket, 1);
|
||||||
visit_expr(p, v.len);
|
visit_expr(p, v.len);
|
||||||
push_generic_token(p, .Close_Bracket, 0);
|
push_generic_token(p, .Close_Bracket, 0);
|
||||||
|
merge_next_token(p);
|
||||||
visit_expr(p, v.elem);
|
visit_expr(p, v.elem);
|
||||||
case Map_Type:
|
case Map_Type:
|
||||||
push_generic_token(p, .Map, 1);
|
push_generic_token(p, .Map, 1);
|
||||||
push_generic_token(p, .Open_Bracket, 0);
|
push_generic_token(p, .Open_Bracket, 0);
|
||||||
visit_expr(p, v.key);
|
visit_expr(p, v.key);
|
||||||
push_generic_token(p, .Close_Bracket, 0);
|
push_generic_token(p, .Close_Bracket, 0);
|
||||||
|
merge_next_token(p);
|
||||||
visit_expr(p, v.value);
|
visit_expr(p, v.value);
|
||||||
case Helper_Type:
|
case Helper_Type:
|
||||||
visit_expr(p, v.type);
|
visit_expr(p, v.type);
|
||||||
|
|||||||
Reference in New Issue
Block a user