1
0
This commit is contained in:
Jeff 2024-11-27 20:36:58 -05:00
parent d83a470638
commit cc963c544f
4 changed files with 11 additions and 242 deletions

View File

@ -50,8 +50,8 @@ use crate::{value::ConcreteValue, Chunk, Local};
const INSTRUCTION_HEADER: [&str; 4] = [ 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);

View File

@ -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,
}

View File

@ -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()
}
} }
} }

View File

@ -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};