diff --git a/src/comment.jule b/src/comment.jule index 87dde78..d9d25d6 100644 --- a/src/comment.jule +++ b/src/comment.jule @@ -9,6 +9,7 @@ use std::jule::lex::{ struct Comment { row: int + col: int txt: str } @@ -30,6 +31,7 @@ impl CommentMap { } cm.map = append(cm.map, &Comment{ row: token.row, + col: token.column, txt: token.kind, }) _ = copy(tokens[i:], tokens[i + 1:]) diff --git a/src/format.jule b/src/format.jule index e3f66e2..9715151 100644 --- a/src/format.jule +++ b/src/format.jule @@ -17,6 +17,11 @@ struct Field { expr: str } +struct RowAlign { + row: int + max: bool +} + struct Formatter { indent_len: int = 4 indent_str: str = " " @@ -27,17 +32,17 @@ struct Formatter { mut indent: str mut cm: CommentMap - mut ef: ExprFormatter - mut sf: ScopeFormatter - mut tf: TypeFormatter + mut ef: &ExprFormatter + mut sf: &ScopeFormatter + mut tf: &TypeFormatter } impl Formatter { static fn new(): &Formatter { let mut fmt = new(Formatter) - fmt.ef = ExprFormatter{fmt: fmt} - fmt.sf = ScopeFormatter{fmt: fmt} - fmt.tf = TypeFormatter{fmt: fmt} + fmt.ef = &ExprFormatter{fmt: fmt} + fmt.sf = &ScopeFormatter{fmt: fmt} + fmt.tf = &TypeFormatter{fmt: fmt} ret fmt } @@ -104,25 +109,35 @@ impl Formatter { ret self.write_comments_except(row + 1) } - fn pop_row_comments_by_f(&self, row: int, f: fn(_: &Comment)) { - for i, c in self.cm.map { - if c.row == row { + fn pop_row_comments_by_f(&self, row: int, col: int, f: fn(_: &Comment)) { + let mut i = 0 + for i < self.cm.map.len { + let c = self.cm.map[i] + if c.row == row && (col == -1 || c.col < col) { f(c) self.cm.map = append(self.cm.map[:i], self.cm.map[i + 1:]...) continue } else if c.row > row { break } + i++ } } fn pop_row_comments_by(&self, row: int) { - self.pop_row_comments_by_f(row, fn(c: &Comment) { + self.pop_row_comments_by_f(row, -1, fn(c: &Comment) { self.write(" ") self.write_comment(c) }) } + fn pop_row_comments_by_c(&self, row: int, col: int) { + self.pop_row_comments_by_f(row, col, fn(c: &Comment) { + self.write(c.txt) + self.write(" ") + }) + } + fn pop_row_comments(&self, row: int) { for { let c = self.cm.pop(row) @@ -542,7 +557,7 @@ impl Formatter { let row = rows[k] self.write_comments_except(row) self.write(line) - self.pop_row_comments_by_f(row, fn (c: &Comment) { + self.pop_row_comments_by_f(row, -1, fn (c: &Comment) { self.write(strings::repeat(" ", padding_abs(max - line.len) + 1)) self.write_comment(c) }) @@ -607,7 +622,7 @@ impl Formatter { let row = rows[j] self.write_comments_except(row) self.write(line) - self.pop_row_comments_by_f(row, fn(c: &Comment) { + self.pop_row_comments_by_f(row, -1, fn(c: &Comment) { self.write(strings::repeat(" ", padding_abs(max - line.len) + 1)) self.write_comment(c) }) @@ -1156,16 +1171,16 @@ impl ScopeFormatter { } struct ExprFormatter { - mut fmt: &Formatter - mut row: int // Last seen row. + mut fmt: &Formatter + mut row: int // Last seen row. } impl ExprFormatter { - fn write(self, s: str) { + fn write(&self, s: str) { self.fmt.buf += s } - fn tuple(self, mut tup: &ast::TupleExpr) { + fn tuple(&self, mut tup: &ast::TupleExpr) { for (i, mut expr) in tup.expr { self.format(expr) if i + 1 < tup.expr.len { @@ -1174,39 +1189,39 @@ impl ExprFormatter { } } - fn lit(self, l: &ast::LitExpr) { + fn lit(&self, l: &ast::LitExpr) { self.write(l.value) } - fn unsafexpr(self, mut u: &ast::UnsafeExpr) { + fn unsafexpr(&self, mut u: &ast::UnsafeExpr) { self.write("unsafe { ") self.format(u.expr) self.write(" }") } - fn coexpr(self, mut c: &ast::CoExpr) { + fn coexpr(&self, mut c: &ast::CoExpr) { self.write("co ") self.format(c.expr) } - fn ident(self, id: &ast::IdentExpr) { + fn ident(&self, id: &ast::IdentExpr) { if id.cpp_linked { self.write("cpp.") } self.write(id.ident) } - fn unary(self, mut u: &ast::UnaryExpr) { + fn unary(&self, mut u: &ast::UnaryExpr) { self.write(u.op.kind) self.format(u.expr) } - fn variadic(self, mut v: &ast::VariadicExpr) { + fn variadic(&self, mut v: &ast::VariadicExpr) { self.format(v.expr) self.write("...") } - fn cast(self, mut c: &ast::CastExpr) { + fn cast(&self, mut c: &ast::CastExpr) { self.write("(") self.fmt.format_type(c.kind) self.write(")") @@ -1215,7 +1230,7 @@ impl ExprFormatter { self.write(")") } - fn nselect(self, ns: &ast::NsSelectionExpr) { + fn nselect(&self, ns: &ast::NsSelectionExpr) { for _, s in ns.ns { self.write(s.kind) self.write("::") @@ -1223,19 +1238,22 @@ impl ExprFormatter { self.write(ns.ident.kind) } - fn sub_ident(self, mut si: &ast::SubIdentExpr) { + fn sub_ident(&self, mut si: &ast::SubIdentExpr) { self.format(si.expr) self.write(".") self.write(si.ident.kind) } - fn binary(self, mut bin: &ast::BinopExpr) { + fn binary(&self, mut bin: &ast::BinopExpr) { + self.fmt.pop_row_comments_by_c(bin.left.token.row, bin.left.token.column) self.format(bin.left) self.write(" ") + self.fmt.pop_row_comments_by_c(bin.op.row, bin.op.column) self.write(bin.op.kind) rep: if bin.op.row == bin.right.token.row { self.write(" ") + self.fmt.pop_row_comments_by_c(bin.right.token.row, bin.right.token.column) self.format(bin.right) ret } @@ -1243,22 +1261,28 @@ impl ExprFormatter { self.fmt.pop_row_comments_by(bin.op.row) self.write("\n") self.write(self.fmt.indent) + self.fmt.pop_row_comments_by_c(bin.right.token.row, bin.right.token.column) match type bin.right.kind { | &ast::BinopExpr: bin = (&ast::BinopExpr)(bin.right.kind) + self.fmt.pop_row_comments_by_c(bin.left.token.row, bin.left.token.column) self.format(bin.left) self.write(" ") + self.fmt.pop_row_comments_by_c(bin.left.token.row, bin.left.token.column) + self.fmt.pop_row_comments_by_c(bin.op.row, bin.op.column) self.write(bin.op.kind) + self.fmt.pop_row_comments(bin.op.row) self.fmt.done_indent() goto rep |: + self.fmt.pop_row_comments_by_c(bin.right.token.row, bin.right.token.column) self.format(bin.right) self.row = bin.right.token.row } self.fmt.done_indent() } - fn args(self, mut &args: []&ast::Expr) { + fn args(&self, mut &args: []&ast::Expr) { if args.len == 0 { ret } @@ -1279,7 +1303,9 @@ impl ExprFormatter { } else if i > 0 { self.write(" ") } + self.fmt.pop_row_comments_by_c(arg.token.row, arg.token.column) self.format(arg) + self.fmt.pop_row_comments_by_c(arg.token.row, arg.token.column) row = self.fmt.ef.row } if indented { @@ -1287,7 +1313,7 @@ impl ExprFormatter { } } - fn fn_call(self, mut f: &ast::FnCallExpr) { + fn fn_call(&self, mut f: &ast::FnCallExpr) { self.format(f.expr) let tf = TypeFormatter{ fmt: self.fmt, @@ -1307,7 +1333,7 @@ impl ExprFormatter { } } - fn field_expr_pair(self, mut pair: &ast::FieldExprPair) { + fn field_expr_pair(&self, mut pair: &ast::FieldExprPair) { if pair.is_targeted() { self.write(pair.field.kind) self.write(": ") @@ -1315,7 +1341,7 @@ impl ExprFormatter { self.format(pair.expr) } - fn struct_lit(self, mut lit: &ast::StructLit) { + fn struct_lit(&self, mut lit: &ast::StructLit) { self.fmt.format_type(lit.kind) if lit.exprs.len == 0 { self.write("{}") @@ -1336,15 +1362,20 @@ impl ExprFormatter { } self.fmt.add_indent() for (i, mut expr) in lit.exprs { + let diff = lit.exprs.len - i if newline { self.write(self.fmt.indent) } + self.fmt.pop_row_comments_by_c(expr.token.row, expr.token.column) self.format(expr) + self.fmt.pop_row_comments_by_c(expr.token.row, expr.token.column) if newline { self.write(",") - self.fmt.pop_row_comments(self.fmt.ef.row) + if diff < 2 || lit.exprs[i + 1].token.row != self.fmt.ef.row { + self.fmt.pop_row_comments(self.fmt.ef.row) + } self.write("\n") - } else if lit.exprs.len - i > 1 { + } else if diff > 1 { self.write(", ") } } @@ -1355,10 +1386,10 @@ impl ExprFormatter { self.write("}") } - fn responsive_exprs[T](self, mut &lit: T) { + fn responsive_exprs[T](&self, mut &lit: T) { const CAP = 1 << 8 let mut exprs = make([]str, 0, CAP) - let mut rows = make([]int, 0, CAP) + let mut rows = make([]RowAlign, 0, CAP) let n = self.fmt.buf.len let mut max = 0 @@ -1376,12 +1407,17 @@ impl ExprFormatter { } exprs = append(exprs, self.fmt.buf[n:]) self.fmt.buf = self.fmt.buf[:n] - rows = append(rows, self.fmt.ef.row) + rows = append(rows, RowAlign{ + row: self.fmt.ef.row, + max: self.fmt.ef.row == row, + }) } } else if i > 0 { self.write(" ") } + self.fmt.pop_row_comments_by_c(expr.token.row, expr.token.column) self.format(expr) + self.fmt.pop_row_comments_by_c(expr.token.row, expr.token.column) row = expr.token.row if lined || lit.exprs.len - i > 1 { self.write(",") @@ -1393,7 +1429,10 @@ impl ExprFormatter { max = diff } exprs = append(exprs, self.fmt.buf[n:]) - rows = append(rows, self.fmt.ef.row) + rows = append(rows, RowAlign{ + row: self.fmt.ef.row, + max: self.fmt.ef.row == row, + }) self.fmt.buf = self.fmt.buf[:n] } @@ -1405,11 +1444,15 @@ impl ExprFormatter { let erow = rows[i] self.write(expr) for { - let c = self.fmt.cm.pop(erow) + let c = self.fmt.cm.pop(erow.row) if c == nil { break } - self.write(strings::repeat(" ", padding_abs(max - expr.len) + 1)) + if erow.max { + self.write(strings::repeat(" ", padding_abs(max - expr.len) + 1)) + } else { + self.write(" ") + } self.fmt.write_comment(c) } if exprs.len - i > 1 { @@ -1426,34 +1469,34 @@ impl ExprFormatter { } } - fn brace_lit(self, mut lit: &ast::BraceLit) { + fn brace_lit(&self, mut lit: &ast::BraceLit) { self.write("{") self.responsive_exprs[&ast::BraceLit](lit) self.write("}") self.fmt.pop_row_comments(lit.token.row) } - fn key_val_pair(self, mut pair: &ast::KeyValPair) { + fn key_val_pair(&self, mut pair: &ast::KeyValPair) { self.format(pair.key) self.write(": ") self.format(pair.val) } - fn slice(self, mut s: &ast::SliceExpr) { + fn slice(&self, mut s: &ast::SliceExpr) { self.write("[") self.responsive_exprs[&ast::SliceExpr](s) self.write("]") self.fmt.pop_row_comments(s.token.row) } - fn indexing(self, mut i: &ast::IndexingExpr) { + fn indexing(&self, mut i: &ast::IndexingExpr) { self.format(i.expr) self.write("[") self.format(i.index) self.write("]") } - fn slicing(self, mut i: &ast::SlicingExpr) { + fn slicing(&self, mut i: &ast::SlicingExpr) { self.format(i.expr) self.write("[") self.format(i.start) @@ -1462,7 +1505,7 @@ impl ExprFormatter { self.write("]") } - fn ternary(self, mut t: &ast::TernaryExpr) { + fn ternary(&self, mut t: &ast::TernaryExpr) { self.write("if ") self.format(t.condition) self.write(" { ") @@ -1472,7 +1515,7 @@ impl ExprFormatter { self.write(" }") } - fn format_kind(self, mut &kind: any) { + fn format_kind(&self, mut &kind: any) { match type kind { | &ast::Expr: let mut expr = (&ast::Expr)(kind) @@ -1523,7 +1566,7 @@ impl ExprFormatter { } } - fn format(self, mut &expr: &ast::Expr) { + fn format(&self, mut &expr: &ast::Expr) { if expr == nil { ret }