Clean up
This commit is contained in:
parent
d83a470638
commit
cc963c544f
@ -51,7 +51,7 @@ const INSTRUCTION_HEADER: [&str; 4] = [
|
|||||||
"Instructions",
|
"Instructions",
|
||||||
"------------",
|
"------------",
|
||||||
" i POSITION OPERATION TYPE INFO ",
|
" i POSITION OPERATION TYPE INFO ",
|
||||||
"--- ---------- ------------- ---------------- ------------------------------------",
|
"--- ---------- ------------- ---------------- ----------------------------------",
|
||||||
];
|
];
|
||||||
|
|
||||||
const CONSTANT_HEADER: [&str; 4] = [
|
const CONSTANT_HEADER: [&str; 4] = [
|
||||||
@ -259,10 +259,10 @@ impl<'a> Disassembler<'a> {
|
|||||||
{
|
{
|
||||||
let position = position.to_string();
|
let position = position.to_string();
|
||||||
let operation = instruction.operation().to_string();
|
let operation = instruction.operation().to_string();
|
||||||
|
let r#type = r#type.to_string();
|
||||||
let info = instruction.disassembly_info(self.chunk);
|
let info = instruction.disassembly_info(self.chunk);
|
||||||
|
|
||||||
let instruction_display =
|
let instruction_display =
|
||||||
format!("{index:^3} {position:^10} {operation:13} {type:^16} {info:^36}");
|
format!("{index:^3} {position:^10} {operation:13} {type:^16} {info:^34}");
|
||||||
|
|
||||||
self.push_details(&instruction_display);
|
self.push_details(&instruction_display);
|
||||||
}
|
}
|
||||||
@ -279,7 +279,7 @@ impl<'a> Disassembler<'a> {
|
|||||||
identifier_index,
|
identifier_index,
|
||||||
r#type,
|
r#type,
|
||||||
scope,
|
scope,
|
||||||
is_mutable: mutable,
|
is_mutable,
|
||||||
},
|
},
|
||||||
) in self.chunk.locals().iter().enumerate()
|
) in self.chunk.locals().iter().enumerate()
|
||||||
{
|
{
|
||||||
@ -291,7 +291,7 @@ impl<'a> Disassembler<'a> {
|
|||||||
.unwrap_or_else(|| "unknown".to_string());
|
.unwrap_or_else(|| "unknown".to_string());
|
||||||
let type_display = r#type.to_string();
|
let type_display = r#type.to_string();
|
||||||
let local_display = format!(
|
let local_display = format!(
|
||||||
"{index:^3} {scope:5} {mutable:^7} {type_display:^16} {identifier_display:^16}"
|
"{index:^3} {scope:5} {is_mutable:^7} {type_display:^16} {identifier_display:^16}"
|
||||||
);
|
);
|
||||||
|
|
||||||
self.push_details(&local_display);
|
self.push_details(&local_display);
|
||||||
|
@ -1,229 +0,0 @@
|
|||||||
//! Formatting tools
|
|
||||||
use std::mem::replace;
|
|
||||||
|
|
||||||
use colored::{ColoredString, Colorize, CustomColor};
|
|
||||||
|
|
||||||
use crate::{CompileError, DustError, LexError, Lexer, Token};
|
|
||||||
|
|
||||||
pub fn format(
|
|
||||||
source: &str,
|
|
||||||
colored: bool,
|
|
||||||
_indent: usize,
|
|
||||||
line_numbers: bool,
|
|
||||||
) -> Result<String, DustError> {
|
|
||||||
let lexer = Lexer::new(source);
|
|
||||||
let formatted = Formatter::new(lexer)
|
|
||||||
.line_numbers(line_numbers)
|
|
||||||
.colored(colored)
|
|
||||||
.format()
|
|
||||||
.map_err(|error| DustError::Compile {
|
|
||||||
error: CompileError::Lex(error),
|
|
||||||
source,
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(formatted)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Formatter<'src> {
|
|
||||||
lexer: Lexer<'src>,
|
|
||||||
output_lines: Vec<(String, LineKind, usize)>,
|
|
||||||
next_line: String,
|
|
||||||
indent: usize,
|
|
||||||
|
|
||||||
current_token: Token<'src>,
|
|
||||||
previous_token: Token<'src>,
|
|
||||||
|
|
||||||
// Options
|
|
||||||
line_numbers: bool,
|
|
||||||
colored: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'src> Formatter<'src> {
|
|
||||||
pub fn new(mut lexer: Lexer<'src>) -> Self {
|
|
||||||
let (current_token, _) = lexer.next_token().unwrap();
|
|
||||||
|
|
||||||
Self {
|
|
||||||
lexer,
|
|
||||||
output_lines: Vec::new(),
|
|
||||||
next_line: String::new(),
|
|
||||||
indent: 0,
|
|
||||||
current_token,
|
|
||||||
previous_token: Token::Eof,
|
|
||||||
line_numbers: false,
|
|
||||||
colored: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn line_numbers(mut self, line_numbers: bool) -> Self {
|
|
||||||
self.line_numbers = line_numbers;
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn colored(mut self, colored: bool) -> Self {
|
|
||||||
self.colored = colored;
|
|
||||||
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn format(&mut self) -> Result<String, LexError> {
|
|
||||||
let mut line_kind = LineKind::Empty;
|
|
||||||
|
|
||||||
self.advance()?;
|
|
||||||
|
|
||||||
while self.current_token != Token::Eof {
|
|
||||||
use Token::*;
|
|
||||||
|
|
||||||
if self.current_token.is_expression() && line_kind != LineKind::Assignment {
|
|
||||||
line_kind = LineKind::Expression;
|
|
||||||
}
|
|
||||||
|
|
||||||
match self.current_token {
|
|
||||||
Boolean(boolean) => {
|
|
||||||
self.push_colored(boolean.red());
|
|
||||||
}
|
|
||||||
Byte(byte) => {
|
|
||||||
self.push_colored(byte.green());
|
|
||||||
}
|
|
||||||
Character(character) => {
|
|
||||||
self.push_colored(
|
|
||||||
character
|
|
||||||
.to_string()
|
|
||||||
.custom_color(CustomColor::new(225, 150, 150)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Float(float) => {
|
|
||||||
self.push_colored(float.yellow());
|
|
||||||
}
|
|
||||||
Identifier(identifier) => {
|
|
||||||
self.push_colored(identifier.blue());
|
|
||||||
self.next_line.push(' ');
|
|
||||||
}
|
|
||||||
Integer(integer) => {
|
|
||||||
self.push_colored(integer.cyan());
|
|
||||||
}
|
|
||||||
String(string) => {
|
|
||||||
self.push_colored(string.magenta());
|
|
||||||
}
|
|
||||||
LeftBrace => {
|
|
||||||
self.next_line.push_str(self.current_token.as_str());
|
|
||||||
self.commit_line(LineKind::OpenBlock);
|
|
||||||
|
|
||||||
self.indent += 1;
|
|
||||||
}
|
|
||||||
RightBrace => {
|
|
||||||
self.commit_line(LineKind::CloseBlock);
|
|
||||||
self.next_line.push_str(self.current_token.as_str());
|
|
||||||
|
|
||||||
self.indent -= 1;
|
|
||||||
}
|
|
||||||
Semicolon => {
|
|
||||||
if line_kind != LineKind::Assignment {
|
|
||||||
line_kind = LineKind::Statement;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.next_line.push_str(self.current_token.as_str());
|
|
||||||
self.commit_line(line_kind);
|
|
||||||
}
|
|
||||||
Let => {
|
|
||||||
line_kind = LineKind::Assignment;
|
|
||||||
|
|
||||||
self.push_colored(self.current_token.as_str().bold());
|
|
||||||
self.next_line.push(' ');
|
|
||||||
}
|
|
||||||
Break | Loop | Return | While => {
|
|
||||||
line_kind = LineKind::Statement;
|
|
||||||
|
|
||||||
self.push_colored(self.current_token.as_str().bold());
|
|
||||||
self.next_line.push(' ');
|
|
||||||
}
|
|
||||||
token => {
|
|
||||||
self.next_line.push_str(token.as_str());
|
|
||||||
self.next_line.push(' ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut previous_index = 0;
|
|
||||||
let mut current_index = 1;
|
|
||||||
|
|
||||||
while current_index < self.output_lines.len() {
|
|
||||||
let (_, previous, _) = &self.output_lines[previous_index];
|
|
||||||
let (_, current, _) = &self.output_lines[current_index];
|
|
||||||
|
|
||||||
match (previous, current) {
|
|
||||||
(LineKind::Empty, _)
|
|
||||||
| (_, LineKind::Empty)
|
|
||||||
| (LineKind::OpenBlock, _)
|
|
||||||
| (_, LineKind::CloseBlock) => {}
|
|
||||||
(left, right) if left == right => {}
|
|
||||||
_ => {
|
|
||||||
self.output_lines
|
|
||||||
.insert(current_index, ("".to_string(), LineKind::Empty, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
previous_index += 1;
|
|
||||||
current_index += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
let formatted = String::with_capacity(
|
|
||||||
self.output_lines
|
|
||||||
.iter()
|
|
||||||
.fold(0, |total, (line, _, _)| total + line.len()),
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(self.output_lines.iter().enumerate().fold(
|
|
||||||
formatted,
|
|
||||||
|acc, (index, (line, _, indent))| {
|
|
||||||
let index = if index == 0 {
|
|
||||||
format!("{:<3}| ", index + 1).dimmed()
|
|
||||||
} else {
|
|
||||||
format!("\n{:<3}| ", index + 1).dimmed()
|
|
||||||
};
|
|
||||||
let left_pad = " ".repeat(*indent);
|
|
||||||
|
|
||||||
format!("{}{}{}{}", acc, index, left_pad, line)
|
|
||||||
},
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn advance(&mut self) -> Result<(), LexError> {
|
|
||||||
if self.lexer.is_eof() {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
|
|
||||||
let (new_token, position) = self.lexer.next_token()?;
|
|
||||||
|
|
||||||
log::info!(
|
|
||||||
"Parsing {} at {}",
|
|
||||||
new_token.to_string().bold(),
|
|
||||||
position.to_string()
|
|
||||||
);
|
|
||||||
|
|
||||||
self.previous_token = replace(&mut self.current_token, new_token);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn push_colored(&mut self, colored: ColoredString) {
|
|
||||||
self.next_line.push_str(&format!("{}", colored));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn commit_line(&mut self, line_kind: LineKind) {
|
|
||||||
self.output_lines
|
|
||||||
.push((self.next_line.clone(), line_kind, self.indent));
|
|
||||||
self.next_line.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
|
||||||
pub enum LineKind {
|
|
||||||
Empty,
|
|
||||||
Assignment,
|
|
||||||
Expression,
|
|
||||||
Statement,
|
|
||||||
OpenBlock,
|
|
||||||
CloseBlock,
|
|
||||||
}
|
|
@ -467,11 +467,6 @@ impl Instruction {
|
|||||||
| Operation::Negate
|
| Operation::Negate
|
||||||
| Operation::Not
|
| Operation::Not
|
||||||
| Operation::Call => true,
|
| Operation::Call => true,
|
||||||
Operation::CallNative => {
|
|
||||||
let function = NativeFunction::from(self.b());
|
|
||||||
|
|
||||||
function.returns_value()
|
|
||||||
}
|
|
||||||
Operation::Move
|
Operation::Move
|
||||||
| Operation::Close
|
| Operation::Close
|
||||||
| Operation::DefineLocal
|
| Operation::DefineLocal
|
||||||
@ -483,6 +478,11 @@ impl Instruction {
|
|||||||
| Operation::TestSet
|
| Operation::TestSet
|
||||||
| Operation::Jump
|
| Operation::Jump
|
||||||
| Operation::Return => false,
|
| Operation::Return => false,
|
||||||
|
Operation::CallNative => {
|
||||||
|
let function = NativeFunction::from(self.b());
|
||||||
|
|
||||||
|
function.returns_value()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ pub mod chunk;
|
|||||||
pub mod compiler;
|
pub mod compiler;
|
||||||
pub mod disassembler;
|
pub mod disassembler;
|
||||||
pub mod dust_error;
|
pub mod dust_error;
|
||||||
pub mod formatter;
|
|
||||||
pub mod instruction;
|
pub mod instruction;
|
||||||
pub mod lexer;
|
pub mod lexer;
|
||||||
pub mod native_function;
|
pub mod native_function;
|
||||||
@ -20,7 +19,6 @@ pub use crate::chunk::{Chunk, ChunkError, Local};
|
|||||||
pub use crate::compiler::{compile, CompileError, Compiler};
|
pub use crate::compiler::{compile, CompileError, Compiler};
|
||||||
pub use crate::disassembler::Disassembler;
|
pub use crate::disassembler::Disassembler;
|
||||||
pub use crate::dust_error::{AnnotatedError, DustError};
|
pub use crate::dust_error::{AnnotatedError, DustError};
|
||||||
pub use crate::formatter::{format, Formatter};
|
|
||||||
pub use crate::instruction::{Argument, Instruction};
|
pub use crate::instruction::{Argument, Instruction};
|
||||||
pub use crate::lexer::{lex, LexError, Lexer};
|
pub use crate::lexer::{lex, LexError, Lexer};
|
||||||
pub use crate::native_function::{NativeFunction, NativeFunctionError};
|
pub use crate::native_function::{NativeFunction, NativeFunctionError};
|
||||||
|
Loading…
Reference in New Issue
Block a user