private void FormatCode() { ITextSnapshot snapshot = this.wpfTextView.TextSnapshot; if (snapshot != snapshot.TextBuffer.CurrentSnapshot) { return; } using (ITextEdit edit = this.wpfTextView.TextBuffer.CreateEdit()) { var tokenizer = new Tokenizer(); foreach (var line in edit.Snapshot.Lines) { if (!edit.Replace(new Span(line.Start, line.End - line.Start), FormatLine(tokenizer, line.GetText()))) { return; } } edit.Apply(); } }
// I wish it was cleaner... private static string FormatLine(Tokenizer tokenizer, string rawLine) { Contract.Requires(tokenizer != null); Contract.Requires(rawLine != null); Contract.Ensures(Contract.Result<string>() != null); var state = State.BeforeInstruction; var formattedLine = new StringBuilder(); foreach (var token in tokenizer.Tokenize(rawLine)) { switch (token.Type) { case _64TassTokenType._6502Instruction: case _64TassTokenType._6502IllegalInstruction: if (state == State.BeforeInstruction) { PadToColumn(formattedLine, CodeStartPosition).Append(token.Value).Append(' '); state = State.BeforeInstructionArgument; } else { formattedLine.Append(token.Value).Append(' '); } break; case _64TassTokenType.Star: if (state == State.BeforeInstructionArgument) { formattedLine.Append(token.Value); state = State.InstructionArgument; } else if (state == State.InstructionArgument) { goto case _64TassTokenType.Equals; } else { PadToColumn(formattedLine, CodeStartPosition).Append(token.Value); // change state for comment alignment state = State.InstructionArgument; } break; case _64TassTokenType.CompilerDirective: PadToColumn(formattedLine, CodeStartPosition).Append(token.Value).Append(' '); break; case _64TassTokenType.Minus: case _64TassTokenType.Plus: Contract.Assert(token.Value == "+" || token.Value == "-"); if (state == State.BeforeInstructionArgument) { formattedLine.Append(token.Value); state = State.InstructionArgument; } else if (state == State.InstructionArgument) { if (formattedLine[formattedLine.Length - 1] == '-') { formattedLine.Append(token.Value); } else { goto case _64TassTokenType.Equals; } } else { formattedLine.Append(token.Value).Append(' '); } break; case _64TassTokenType.Equals: formattedLine.Append(' ').Append(token.Value).Append(' '); break; case _64TassTokenType.Comment: if (state == State.BeforeInstructionArgument || state == State.InstructionArgument) { PadToColumn(formattedLine, AfterCodeCommentStartPosition).Append(token.Value).Append(' '); } else { // if the line starts with a comment leave it as it is if (!(formattedLine.Length == 0 && rawLine.IndexOf(';') == 0)) { PadToColumn(formattedLine, CodeCommentStartPosition); } formattedLine.Append(token.Value).Append(' '); } break; case _64TassTokenType.BinaryNumber: formattedLine.Append('%') .Append('0', ((((token.Value.Length - 2) >> 3) + 1) << 3) - token.Value.Length + 1) .Append(token.Value.Substring(1)); state = State.InstructionArgument; break; case _64TassTokenType.HexadecimalNumber: if ((token.Value.Length & 0x01) == 0) { formattedLine.Append("$0").Append(token.Value.Substring(1)); } else { formattedLine.Append(token.Value); } state = State.InstructionArgument; break; case _64TassTokenType.Label: formattedLine.Append(token.Value); if (state == State.BeforeInstructionArgument) { state = State.InstructionArgument; } break; case _64TassTokenType.Hash: case _64TassTokenType.StringLiteral: case _64TassTokenType.DecimalNumber: case _64TassTokenType.Coma: case _64TassTokenType.LeftParen: case _64TassTokenType.RightParen: case _64TassTokenType.GreaterThan: case _64TassTokenType.LessThan: case _64TassTokenType.DontKnow: formattedLine.Append(token.Value); if (state == State.BeforeInstructionArgument) { state = State.InstructionArgument; } break; } } return formattedLine.ToString(); }