1
0

Add time feature to CLI

This commit is contained in:
Jeff 2024-12-10 16:04:36 -05:00
parent a8960b0f70
commit cdd76618cb
7 changed files with 88 additions and 14 deletions

View File

@ -157,7 +157,7 @@ Dust supports the following basic values:
- Float: A 64-bit floating-point number
- Function: An executable chunk of code
- Integer: A signed 64-bit integer
- String: A UTF-8 encoded string
- String: A UTF-8 encoded byte sequence
Dust's "basic" values are conceptually similar because they are singular as opposed to composite.
Most of these values are stored on the stack but some are heap-allocated. A Dust string is a

View File

@ -4,11 +4,12 @@ use std::{fs::read_to_string, path::PathBuf};
use clap::{Args, Parser};
use colored::Colorize;
use dust_lang::{compile, run, CompileError, DustError, Lexer, Span, Token};
use dust_lang::{compile, CompileError, Compiler, DustError, Lexer, Span, Token, Vm};
use log::{Level, LevelFilter};
#[derive(Parser)]
#[clap(
name = env!("CARGO_PKG_NAME"),
version = env!("CARGO_PKG_VERSION"),
author = env!("CARGO_PKG_AUTHORS"),
about = env!("CARGO_PKG_DESCRIPTION"),
@ -34,6 +35,10 @@ struct ModeFlags {
#[arg(short, long)]
run: bool,
/// Print the time taken to compile and run the source code
#[arg(long, requires("run"))]
time: bool,
#[arg(long, requires("run"))]
/// Do not print the run result
no_output: bool,
@ -172,9 +177,31 @@ fn main() {
return;
}
let run_result = run(&source);
let lexer = Lexer::new(&source);
let mut compiler = match Compiler::new(lexer) {
Ok(compiler) => compiler,
Err(error) => {
handle_compile_error(error, &source);
match run_result {
return;
}
};
match compiler.compile() {
Ok(()) => {}
Err(error) => {
handle_compile_error(error, &source);
return;
}
}
let compile_end = start_time.elapsed();
let chunk = compiler.finish(None, None);
let mut vm = Vm::new(&source, &chunk, None);
match vm.run() {
Ok(Some(value)) => {
if !mode.no_output {
println!("{}", value)
@ -182,9 +209,33 @@ fn main() {
}
Ok(None) => {}
Err(error) => {
eprintln!("{}", error);
let dust_error = DustError::runtime(error, &source);
let report = dust_error.report();
eprintln!("{report}");
}
}
let run_end = start_time.elapsed();
if mode.time {
let compile_time = compile_end.as_micros();
let run_time = run_end - compile_end;
println!(
"Compile time: {compile_time}µs Run time: {}s{}ms{}µs",
run_time.as_secs(),
run_time.subsec_millis(),
run_time.subsec_micros()
);
}
}
fn handle_compile_error(error: CompileError, source: &str) {
let dust_error = DustError::compile(error, source);
let report = dust_error.report();
eprintln!("{report}");
}
#[cfg(test)]

View File

@ -94,13 +94,14 @@ impl Chunk {
self.instructions()
.iter()
.rev()
.find_map(|(instruction, _)| {
.filter_map(|(instruction, _)| {
if instruction.yields_value() {
Some(instruction.a as usize + 1)
} else {
None
}
})
.max()
.unwrap_or(0)
}

View File

@ -23,6 +23,10 @@ pub enum CompileError {
CannotChainComparison {
position: Span,
},
ExpectedBoolean {
found: TokenOwned,
position: Span,
},
ExpectedExpression {
found: TokenOwned,
position: Span,
@ -185,6 +189,7 @@ impl AnnotatedError for CompileError {
Self::CannotSubtractType { .. } => "Cannot subtract from this type",
Self::CannotSubtractArguments { .. } => "Cannot subtract these types",
Self::ConstantIndexOutOfBounds { .. } => "Constant index out of bounds",
Self::ExpectedBoolean { .. } => "Expected a boolean",
Self::ExpectedExpression { .. } => "Expected an expression",
Self::ExpectedFunction { .. } => "Expected a function",
Self::ExpectedFunctionType { .. } => "Expected a function type",

View File

@ -1249,6 +1249,30 @@ impl<'src> Compiler<'src> {
self.parse_expression()?;
let (expression_instruction, expression_type, expression_position) =
self.instructions.last().unwrap();
if expression_type != &Type::Boolean {
return Err(CompileError::ExpectedFunction {
found: self.previous_token.to_owned(),
actual_type: expression_type.clone(),
position: *expression_position,
});
}
let test_argument = match expression_instruction.as_argument() {
Some(argument) => argument,
None => {
return Err(CompileError::ExpectedExpression {
found: self.previous_token.to_owned(),
position: *expression_position,
})
}
};
let test = Instruction::test(test_argument, true);
self.emit_instruction(test, Type::None, self.current_position);
if matches!(
self.get_last_operations(),
Some([

View File

@ -2,7 +2,7 @@
//! annotations.
use std::fmt::{self, Display, Formatter};
use annotate_snippets::{Annotation, Level, Renderer, Snippet};
use annotate_snippets::{Level, Renderer, Snippet};
use smallvec::SmallVec;
use crate::{CompileError, Span, VmError};

View File

@ -1,7 +0,0 @@
Finished `dev` profile [optimized + debuginfo] target(s) in 0.02s
Running `target/debug/dust -c '42 + true'`
error: Compilation Error: Cannot add to this type
 |
1 | 42 + true
 | ^^^^ While parsing this code
 |