feat: improve error messages with context lines
- Show 2 lines of context before and after errors (dimmed) - Fix guessing_game.lux to be non-interactive for testing - Use binary search simulation to demonstrate game logic Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,25 +1,44 @@
|
|||||||
// Number guessing game - demonstrates Random and Console effects
|
// Number guessing game - demonstrates Random and Console effects
|
||||||
|
//
|
||||||
|
// Expected output:
|
||||||
|
// Welcome to the Guessing Game!
|
||||||
|
// Target number: 42
|
||||||
|
// Simulating guesses...
|
||||||
|
// Guess 50: Too high!
|
||||||
|
// Guess 25: Too low!
|
||||||
|
// Guess 37: Too low!
|
||||||
|
// Guess 43: Too high!
|
||||||
|
// Guess 40: Too low!
|
||||||
|
// Guess 41: Too low!
|
||||||
|
// Guess 42: Correct!
|
||||||
|
// Found in 7 attempts!
|
||||||
|
|
||||||
fn gameLoop(secret: Int, attempts: Int): Unit with {Console} = {
|
// Game logic - check a guess against the secret
|
||||||
Console.print("Guess the number (1-100), attempt " + toString(attempts) + ":")
|
fn checkGuess(guess: Int, secret: Int): String =
|
||||||
let guess = Console.readInt()
|
if guess == secret then "Correct"
|
||||||
if guess == secret then
|
else if guess < secret then "Too low"
|
||||||
Console.print("Correct! You got it in " + toString(attempts) + " attempts!")
|
else "Too high"
|
||||||
else if guess < secret then {
|
|
||||||
Console.print("Too low!")
|
// Binary search simulation to find the number
|
||||||
gameLoop(secret, attempts + 1)
|
fn binarySearch(low: Int, high: Int, secret: Int, attempts: Int): Int with {Console} = {
|
||||||
}
|
let mid = (low + high) / 2
|
||||||
else {
|
let result = checkGuess(mid, secret)
|
||||||
Console.print("Too high!")
|
Console.print("Guess " + toString(mid) + ": " + result + "!")
|
||||||
gameLoop(secret, attempts + 1)
|
|
||||||
}
|
if result == "Correct" then attempts
|
||||||
|
else if result == "Too low" then binarySearch(mid + 1, high, secret, attempts + 1)
|
||||||
|
else binarySearch(low, mid - 1, secret, attempts + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main(): Unit with {Console, Random} = {
|
fn main(): Unit with {Console} = {
|
||||||
Console.print("Welcome to the Guessing Game!")
|
Console.print("Welcome to the Guessing Game!")
|
||||||
Console.print("I'm thinking of a number between 1 and 100...")
|
// Use a fixed "secret" for reproducible output
|
||||||
let secret = Random.int(1, 100)
|
let secret = 42
|
||||||
gameLoop(secret, 1)
|
Console.print("Target number: " + toString(secret))
|
||||||
|
Console.print("Simulating guesses...")
|
||||||
|
|
||||||
|
let attempts = binarySearch(1, 100, secret, 1)
|
||||||
|
Console.print("Found in " + toString(attempts) + " attempts!")
|
||||||
}
|
}
|
||||||
|
|
||||||
let output = run main() with {}
|
let output = run main() with {}
|
||||||
|
|||||||
@@ -241,50 +241,68 @@ pub fn render_diagnostic(
|
|||||||
colors::RESET
|
colors::RESET
|
||||||
));
|
));
|
||||||
|
|
||||||
// Source code snippet with line numbers
|
// Source code snippet with line numbers and context
|
||||||
let line_num_width = end_line.to_string().len().max(4);
|
let context_lines = 2; // Show 2 lines before and after
|
||||||
|
let start_line = line.saturating_sub(context_lines).max(1);
|
||||||
|
let end_context_line = (end_line + context_lines).min(source.lines().count());
|
||||||
|
let line_num_width = end_context_line.to_string().len().max(4);
|
||||||
|
|
||||||
// Show the problematic line(s)
|
// Show context before, error lines, and context after
|
||||||
for line_num in line..=end_line {
|
for line_num in start_line..=end_context_line {
|
||||||
if let Some(source_line) = get_source_line(source, line_num) {
|
if let Some(source_line) = get_source_line(source, line_num) {
|
||||||
// Line number
|
let is_error_line = line_num >= line && line_num <= end_line;
|
||||||
output.push_str(&format!(
|
|
||||||
"{}{:>width$} │{} ",
|
|
||||||
colors::DIM,
|
|
||||||
line_num,
|
|
||||||
colors::RESET,
|
|
||||||
width = line_num_width
|
|
||||||
));
|
|
||||||
|
|
||||||
// Source line
|
// Line number (dimmed for context, normal for error lines)
|
||||||
output.push_str(source_line);
|
if is_error_line {
|
||||||
output.push('\n');
|
output.push_str(&format!(
|
||||||
|
"{}{:>width$} │{} ",
|
||||||
// Underline the error span
|
colors::DIM,
|
||||||
let underline_start = if line_num == line { col - 1 } else { 0 };
|
line_num,
|
||||||
let underline_end = if line_num == end_line {
|
colors::RESET,
|
||||||
end_col - 1
|
width = line_num_width
|
||||||
|
));
|
||||||
|
// Source line (normal)
|
||||||
|
output.push_str(source_line);
|
||||||
} else {
|
} else {
|
||||||
source_line.len()
|
// Context lines are fully dimmed
|
||||||
};
|
output.push_str(&format!(
|
||||||
|
"{}{:>width$} │ {}{}",
|
||||||
let underline_len = underline_end.saturating_sub(underline_start).max(1);
|
colors::DIM,
|
||||||
|
line_num,
|
||||||
output.push_str(&format!(
|
source_line,
|
||||||
"{}{:>width$} │{} ",
|
colors::RESET,
|
||||||
colors::DIM,
|
width = line_num_width
|
||||||
"",
|
));
|
||||||
colors::RESET,
|
}
|
||||||
width = line_num_width
|
|
||||||
));
|
|
||||||
output.push_str(&" ".repeat(underline_start));
|
|
||||||
output.push_str(&format!(
|
|
||||||
"{}{}{}",
|
|
||||||
severity_color,
|
|
||||||
"^".repeat(underline_len),
|
|
||||||
colors::RESET
|
|
||||||
));
|
|
||||||
output.push('\n');
|
output.push('\n');
|
||||||
|
|
||||||
|
// Underline the error span (only for error lines)
|
||||||
|
if is_error_line {
|
||||||
|
let underline_start = if line_num == line { col - 1 } else { 0 };
|
||||||
|
let underline_end = if line_num == end_line {
|
||||||
|
end_col - 1
|
||||||
|
} else {
|
||||||
|
source_line.len()
|
||||||
|
};
|
||||||
|
|
||||||
|
let underline_len = underline_end.saturating_sub(underline_start).max(1);
|
||||||
|
|
||||||
|
output.push_str(&format!(
|
||||||
|
"{}{:>width$} │{} ",
|
||||||
|
colors::DIM,
|
||||||
|
"",
|
||||||
|
colors::RESET,
|
||||||
|
width = line_num_width
|
||||||
|
));
|
||||||
|
output.push_str(&" ".repeat(underline_start));
|
||||||
|
output.push_str(&format!(
|
||||||
|
"{}{}{}",
|
||||||
|
severity_color,
|
||||||
|
"^".repeat(underline_len),
|
||||||
|
colors::RESET
|
||||||
|
));
|
||||||
|
output.push('\n');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user