1
0

Rename Parser to Compiler

This commit is contained in:
Jeff 2024-11-06 15:40:37 -05:00
parent 74bb8a429a
commit e99a7b5e1e
20 changed files with 291 additions and 287 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +1,15 @@
//! Top-level Dust errors.use annotate_snippets::{Level, Renderer, Snippet};
//! Top-level Dust errors with source code annotations.
use annotate_snippets::{Level, Renderer, Snippet};
use crate::{vm::VmError, ParseError, Span};
use crate::{vm::VmError, CompileError, Span};
/// A top-level error that can occur during the execution of Dust code.
///
/// This error can display nicely formatted messages with source code annotations.
#[derive(Debug, PartialEq)]
pub enum DustError<'src> {
Parse {
error: ParseError,
Compile {
error: CompileError,
source: &'src str,
},
Runtime {
@ -26,7 +26,7 @@ impl<'src> DustError<'src> {
match self {
DustError::Runtime { error, source } => {
let position = error.position();
let label = format!("Runtime error: {}", error.description());
let label = format!("{}: {}", VmError::title(), error.description());
let details = error
.details()
.unwrap_or_else(|| "While running this code".to_string());
@ -38,9 +38,9 @@ impl<'src> DustError<'src> {
report.push_str(&renderer.render(message).to_string());
}
DustError::Parse { error, source } => {
DustError::Compile { error, source } => {
let position = error.position();
let label = format!("Parse error: {}", error.description());
let label = format!("{}: {}", CompileError::title(), error.description());
let details = error
.details()
.unwrap_or_else(|| "While parsing this code".to_string());

View File

@ -3,7 +3,7 @@ use std::mem::replace;
use colored::{ColoredString, Colorize, CustomColor};
use crate::{DustError, LexError, Lexer, ParseError, Token};
use crate::{CompileError, DustError, LexError, Lexer, Token};
pub fn format(source: &str, line_numbers: bool, colored: bool) -> Result<String, DustError> {
let lexer = Lexer::new(source);
@ -11,8 +11,8 @@ pub fn format(source: &str, line_numbers: bool, colored: bool) -> Result<String,
.line_numbers(line_numbers)
.colored(colored)
.format()
.map_err(|error| DustError::Parse {
error: ParseError::Lex(error),
.map_err(|error| DustError::Compile {
error: CompileError::Lex(error),
source,
})?;

View File

@ -8,7 +8,7 @@ use std::fmt::{self, Display, Formatter};
use serde::{Deserialize, Serialize};
use crate::{dust_error::AnnotatedError, DustError, ParseError, Span, Token};
use crate::{dust_error::AnnotatedError, CompileError, DustError, Span, Token};
/// Lexes the input and returns a vector of tokens and their positions.
///
@ -37,8 +37,8 @@ pub fn lex<'tokens, 'src: 'tokens>(
let mut tokens = Vec::new();
loop {
let (token, span) = lexer.next_token().map_err(|error| DustError::Parse {
error: ParseError::Lex(error),
let (token, span) = lexer.next_token().map_err(|error| DustError::Compile {
error: CompileError::Lex(error),
source,
})?;
let is_eof = matches!(token, Token::Eof);

View File

@ -1,6 +1,7 @@
//! The Dust programming language library.
pub mod chunk;
pub mod compiler;
pub mod dust_error;
pub mod formatter;
pub mod instruction;
@ -8,13 +9,13 @@ pub mod lexer;
pub mod native_function;
pub mod operation;
pub mod optimizer;
pub mod parser;
pub mod token;
pub mod r#type;
pub mod value;
pub mod vm;
pub use crate::chunk::{Chunk, ChunkDisassembler, ChunkError, Local, Scope};
pub use crate::compiler::{compile, CompileError, Compiler};
pub use crate::dust_error::{AnnotatedError, DustError};
pub use crate::formatter::{format, Formatter};
pub use crate::instruction::Instruction;
@ -22,7 +23,6 @@ pub use crate::lexer::{lex, LexError, Lexer};
pub use crate::native_function::{NativeFunction, NativeFunctionError};
pub use crate::operation::Operation;
pub use crate::optimizer::{optimize, Optimizer};
pub use crate::parser::{parse, ParseError};
pub use crate::r#type::{EnumType, FunctionType, RangeableType, StructType, Type, TypeConflict};
pub use crate::token::{Token, TokenKind, TokenOwned};
pub use crate::value::{ConcreteValue, Function, Value, ValueError};

View File

@ -6,8 +6,8 @@ type MapToOperation = fn(&(Instruction, Span)) -> Operation;
type OperationIter<'iter> = Map<Iter<'iter, (Instruction, Span)>, MapToOperation>;
pub fn optimize(instructions: &mut [(Instruction, Span)]) {
Optimizer::new(instructions).optimize();
pub fn optimize(instructions: &mut [(Instruction, Span)]) -> usize {
Optimizer::new(instructions).optimize()
}
#[derive(Debug, Eq, PartialEq, PartialOrd, Ord)]
@ -24,7 +24,9 @@ impl<'chunk> Optimizer<'chunk> {
self.instructions = instructions;
}
pub fn optimize(&mut self) {
pub fn optimize(&mut self) -> usize {
let mut optimizations = 0;
if matches!(
self.get_operations(),
Some([
@ -35,7 +37,11 @@ impl<'chunk> Optimizer<'chunk> {
])
) {
self.optimize_comparison();
optimizations += 1;
}
optimizations
}
fn optimize_comparison(&mut self) {

View File

@ -2,13 +2,13 @@
use std::{cmp::Ordering, mem::replace};
use crate::{
parse, value::ConcreteValue, AnnotatedError, Chunk, ChunkError, DustError, FunctionType,
compile, value::ConcreteValue, AnnotatedError, Chunk, ChunkError, DustError, FunctionType,
Instruction, Local, NativeFunction, NativeFunctionError, Operation, Span, Type, Value,
ValueError,
};
pub fn run(source: &str) -> Result<Option<Value>, DustError> {
let chunk = parse(source)?;
let chunk = compile(source)?;
let vm = Vm::new(chunk);
vm.run()

View File

@ -5,7 +5,7 @@ fn constant() {
let source = "42";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -25,7 +25,7 @@ fn empty() {
let source = "";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![(Instruction::r#return(false), Span(0, 0))],
@ -41,7 +41,7 @@ fn parentheses_precedence() {
let source = "(1 + 2) * 3";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![

View File

@ -5,7 +5,7 @@ fn equal() {
let source = "1 == 2";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -33,7 +33,7 @@ fn greater() {
let source = "1 > 2";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -61,7 +61,7 @@ fn greater_than_or_equal() {
let source = "1 >= 2";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -89,7 +89,7 @@ fn less_than() {
let source = "1 < 2";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -117,7 +117,7 @@ fn less_than_or_equal() {
let source = "1 <= 2";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -145,7 +145,7 @@ fn not_equal() {
let source = "1 != 2";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![

View File

@ -5,7 +5,7 @@ fn equality_assignment_long() {
let source = "let a = if 4 == 4 { true } else { false }; a";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -35,7 +35,7 @@ fn equality_assignment_short() {
let source = "let a = 4 == 4 a";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -73,7 +73,7 @@ fn if_else_assigment_false() {
a"#;
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -131,7 +131,7 @@ fn if_else_assigment_true() {
a"#;
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -186,7 +186,7 @@ fn if_else_complex() {
}";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -297,7 +297,7 @@ fn if_else_false() {
let source = "if 1 == 2 { panic() } else { 42 }";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -329,7 +329,7 @@ fn if_else_true() {
let source = "if 1 == 1 { 42 } else { panic() }";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -361,7 +361,7 @@ fn if_false() {
let source = "if 1 == 2 { 2 }";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -388,7 +388,7 @@ fn if_true() {
let source = "if 1 == 1 { 2 }";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![

View File

@ -33,7 +33,7 @@ fn function_call() {
let source = "fn(a: int, b: int) -> int { a + b }(1, 2)";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -78,7 +78,7 @@ fn function_declaration() {
let source = "fn add (a: int, b: int) -> int { a + b }";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![

View File

@ -5,7 +5,7 @@ fn empty_list() {
let source = "[]";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -25,7 +25,7 @@ fn list() {
let source = "[1, 2, 3]";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -55,7 +55,7 @@ fn list_with_complex_expression() {
let source = "[1, 2 + 3 - 4 * 5]";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -102,7 +102,7 @@ fn list_with_simple_expression() {
let source = "[1, 2 + 3, 4]";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![

View File

@ -5,7 +5,7 @@ fn and() {
let source = "true && false";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -28,7 +28,7 @@ fn or() {
let source = "true || false";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -51,7 +51,7 @@ fn variable_and() {
let source = "let a = true; let b = false; a && b";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![

View File

@ -5,7 +5,7 @@ fn r#while() {
let source = "let mut x = 0; while x < 5 { x = x + 1 } x";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![

View File

@ -5,7 +5,7 @@ fn add() {
let source = "1 + 2";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -30,7 +30,7 @@ fn add_assign() {
let source = "let mut a = 1; a += 2; a";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -53,9 +53,9 @@ fn add_assign_expects_mutable_variable() {
let source = "1 += 2";
assert_eq!(
parse(source),
Err(DustError::Parse {
error: ParseError::ExpectedMutableVariable {
compile(source),
Err(DustError::Compile {
error: CompileError::ExpectedMutableVariable {
found: Token::Integer("1").to_owned(),
position: Span(0, 1)
},
@ -85,7 +85,7 @@ fn divide() {
let source = "2 / 2";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -110,7 +110,7 @@ fn divide_assign() {
let source = "let mut a = 2; a /= 2; a";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -136,9 +136,9 @@ fn divide_assign_expects_mutable_variable() {
let source = "1 -= 2";
assert_eq!(
parse(source),
Err(DustError::Parse {
error: ParseError::ExpectedMutableVariable {
compile(source),
Err(DustError::Compile {
error: CompileError::ExpectedMutableVariable {
found: Token::Integer("1").to_owned(),
position: Span(0, 1)
},
@ -152,7 +152,7 @@ fn math_operator_precedence() {
let source = "1 + 2 - 3 * 4 / 5";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -194,7 +194,7 @@ fn multiply() {
let source = "1 * 2";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -219,7 +219,7 @@ fn multiply_assign() {
let source = "let mut a = 2; a *= 3 a";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -245,9 +245,9 @@ fn multiply_assign_expects_mutable_variable() {
let source = "1 *= 2";
assert_eq!(
parse(source),
Err(DustError::Parse {
error: ParseError::ExpectedMutableVariable {
compile(source),
Err(DustError::Compile {
error: CompileError::ExpectedMutableVariable {
found: Token::Integer("1").to_owned(),
position: Span(0, 1)
},
@ -261,7 +261,7 @@ fn subtract() {
let source = "1 - 2";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -286,7 +286,7 @@ fn subtract_assign() {
let source = "let mut x = 42; x -= 2; x";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -312,9 +312,9 @@ fn subtract_assign_expects_mutable_variable() {
let source = "1 -= 2";
assert_eq!(
parse(source),
Err(DustError::Parse {
error: ParseError::ExpectedMutableVariable {
compile(source),
Err(DustError::Compile {
error: CompileError::ExpectedMutableVariable {
found: Token::Integer("1").to_owned(),
position: Span(0, 1)
},

View File

@ -5,7 +5,7 @@ fn panic() {
let source = "panic(\"Goodbye world!\", 42)";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -39,7 +39,7 @@ fn to_string() {
let source = "to_string(42)";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![

View File

@ -27,7 +27,7 @@ fn block_scope() {
";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -90,7 +90,7 @@ fn multiple_block_scopes() {
";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -154,8 +154,8 @@ fn disallow_access_to_child_scope() {
assert_eq!(
run(source),
Err(DustError::Parse {
error: ParseError::VariableOutOfScope {
Err(DustError::Compile {
error: CompileError::VariableOutOfScope {
identifier: "x".to_string(),
position: Span(52, 53),
variable_scope: Scope::new(1, 1),
@ -179,8 +179,8 @@ fn disallow_access_to_child_scope_nested() {
assert_eq!(
run(source),
Err(DustError::Parse {
error: ParseError::VariableOutOfScope {
Err(DustError::Compile {
error: CompileError::VariableOutOfScope {
identifier: "x".to_string(),
position: Span(78, 79),
variable_scope: Scope::new(2, 2),
@ -204,8 +204,8 @@ fn disallow_access_to_sibling_scope() {
assert_eq!(
run(source),
Err(DustError::Parse {
error: ParseError::VariableOutOfScope {
Err(DustError::Compile {
error: CompileError::VariableOutOfScope {
identifier: "x".to_string(),
variable_scope: Scope::new(1, 1),
access_scope: Scope::new(1, 2),
@ -231,8 +231,8 @@ fn disallow_access_to_sibling_scope_nested() {
assert_eq!(
run(source),
Err(DustError::Parse {
error: ParseError::VariableOutOfScope {
Err(DustError::Compile {
error: CompileError::VariableOutOfScope {
identifier: "x".to_string(),
variable_scope: Scope::new(2, 2),
access_scope: Scope::new(2, 3),

View File

@ -5,7 +5,7 @@ fn negate() {
let source = "-(42)";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -25,7 +25,7 @@ fn not() {
let source = "!true";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![

View File

@ -5,7 +5,7 @@ fn define_local() {
let source = "let x = 42;";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![
@ -26,9 +26,9 @@ fn let_statement_expects_identifier() {
let source = "let 1 = 2";
assert_eq!(
parse(source),
Err(DustError::Parse {
error: ParseError::ExpectedToken {
compile(source),
Err(DustError::Compile {
error: CompileError::ExpectedToken {
expected: TokenKind::Identifier,
found: Token::Integer("1").to_owned(),
position: Span(4, 5)
@ -43,7 +43,7 @@ fn set_local() {
let source = "let mut x = 41; x = 42; x";
assert_eq!(
parse(source),
compile(source),
Ok(Chunk::with_data(
None,
vec![

View File

@ -2,7 +2,7 @@ use std::{fs::read_to_string, io::Write};
use clap::Parser;
use colored::Colorize;
use dust_lang::{format, parse, run};
use dust_lang::{compile, format, run};
use log::{Level, LevelFilter};
#[derive(Parser)]
@ -96,7 +96,7 @@ fn main() {
log::info!("Parsing source");
match parse(source) {
match compile(source) {
Ok(chunk) => {
let disassembly = chunk
.disassembler()