فهرست منبع

have to sort attributes because they are not ordered by position(maybe bug on parser)

Daniel Gavin 4 سال پیش
والد
کامیت
1cb3a31f32
1فایلهای تغییر یافته به همراه42 افزوده شده و 19 حذف شده
  1. 42 19
      core/odin/printer/visit.odin

+ 42 - 19
core/odin/printer/visit.odin

@@ -7,7 +7,26 @@ import "core:runtime"
 import "core:fmt"
 import "core:unicode/utf8"
 import "core:mem"
+import "core:sort"
 
+@(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];
+		},
+	};
+}
 
 @(private)
 comment_before_position :: proc(p: ^Printer, pos: tokenizer.Pos) -> bool {
@@ -253,6 +272,11 @@ move_line :: proc(p: ^Printer, pos: tokenizer.Pos) {
 @(private)
 move_line_limit :: proc(p: ^Printer, pos: tokenizer.Pos, limit: int) -> bool {
 	lines := min(pos.line - p.source_position.line, limit);
+
+	if lines < 0 {
+		return false;
+	}
+
 	p.source_position = pos;
 	p.current_line_index += lines;
 	set_line(p, p.current_line_index);
@@ -321,7 +345,7 @@ visit_decl :: proc(p: ^Printer, decl: ^ast.Decl, called_in_stmt := false) {
 		return;
 	}
 
-	switch v in decl.derived {
+	switch v in &decl.derived {
 	case Expr_Stmt:
 		move_line(p, decl.pos);
 		visit_expr(p, v.expr);
@@ -332,13 +356,13 @@ visit_decl :: proc(p: ^Printer, decl: ^ast.Decl, called_in_stmt := false) {
 		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);
-		} else {
-			move_line(p, decl.pos);
-		}
-
-		visit_attributes(p, v.attributes);
+			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);
 
@@ -352,13 +376,13 @@ visit_decl :: proc(p: ^Printer, decl: ^ast.Decl, called_in_stmt := false) {
 	case Foreign_Block_Decl:
 
 		if len(v.attributes) > 0 {
+			sort.sort(sort_attribute(&v.attributes));
 			move_line(p, v.attributes[0].pos);
-		} else {
-			move_line(p, decl.pos);
-		}
-
-		visit_attributes(p, v.attributes);
-
+			visit_attributes(p, v.attributes);
+		} 
+			
+		move_line(p, decl.pos);
+		
         push_generic_token(p, .Foreign, 0);
 
 		visit_expr(p, v.foreign_library);
@@ -377,6 +401,7 @@ visit_decl :: proc(p: ^Printer, decl: ^ast.Decl, called_in_stmt := false) {
 
 	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);
 		}
@@ -463,16 +488,14 @@ visit_attributes :: proc(p: ^Printer, attributes: [dynamic]^ast.Attribute) {
 
 	for attribute, i in attributes {
 
+		move_line_limit(p, attribute.pos, 1);
+
 		push_generic_token(p, .At, 0);
 		push_generic_token(p, .Open_Paren, 0);
 
 		visit_exprs(p, attribute.elems, true);
 
-		push_generic_token(p, .Close_Paren, 0);
-
-		if len(attributes) - 1 != i {
-			newline_position(p, 1);
-		}
+		push_generic_token(p, .Close_Paren, 0);	
 	}
 }
 
@@ -1047,7 +1070,7 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr) {
 			set_source_position(p, v.body.pos);
 			visit_stmt(p, v.body, .Proc);
 		} else {
-			push_generic_token(p, .Ellipsis, 1);
+			push_generic_token(p, .Undef, 1);
 		}
 	case Proc_Type:
 		visit_proc_type(p, v);
@@ -1240,7 +1263,7 @@ visit_field_list :: proc(p: ^Printer, list: ^ast.Field_List, add_comma := false,
 		}
 
 		if field.tag.text != "" {
-			push_generic_token(p, field.tag.kind, 1);
+			push_generic_token(p, field.tag.kind, 1, field.tag.text);
 		}
 
 		if (i != len(list.list) - 1 || trailing) && add_comma {