Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ path = "src/lib.rs"
# linker = "clang"

[dependencies]
colorex = "0.1.0"
utils = { path = "utils" }
lexer = { path = "front/lexer" }
parser = { path = "front/parser" }
error = { path = "front/error" }
Expand All @@ -25,5 +25,6 @@ members = [
"front/parser",
"llvm_temporary",
"front/error",
"utils",
".",
]
2 changes: 1 addition & 1 deletion front/error/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ version = "0.1.0"
edition = "2021"

[dependencies]
colorex = "0.1.1"
utils = { path = "../../utils" }
2 changes: 1 addition & 1 deletion front/error/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ impl WaveError {

/// Display error in Rust-style format
pub fn display(&self) {
use colorex::Colorize;
use utils::colorex::*;

let severity_str = match self.severity {
ErrorSeverity::Error => "error".color("255,71,71").bold(),
Expand Down
1 change: 0 additions & 1 deletion front/lexer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,3 @@ name = "lexer"
version = "0.1.0"
edition = "2021"

[dependencies]
2 changes: 1 addition & 1 deletion front/parser/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ edition = "2021"
[dependencies]
lexer = { path = "../lexer" }
error = { path = "../error" }
regex = "1.11.1"
utils = { path = "../../utils" }
17 changes: 4 additions & 13 deletions front/parser/src/parser/io.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::iter::Peekable;
use std::slice::Iter;
use regex::Regex;
use utils::formatx::*;
use lexer::Token;
use lexer::token::TokenType;
use crate::ast::{ASTNode, StatementNode};
Expand All @@ -25,10 +25,7 @@ pub fn parse_println(tokens: &mut Peekable<Iter<Token>>) -> Option<ASTNode> {
return None;
};

let placeholder_count = Regex::new(r"\{[^}]*\}")
.unwrap()
.find_iter(&content)
.count();
let placeholder_count = count_placeholders(&content);

if placeholder_count == 0 {
if tokens.peek()?.token_type != TokenType::Rparen {
Expand Down Expand Up @@ -110,10 +107,7 @@ pub fn parse_print(tokens: &mut Peekable<Iter<Token>>) -> Option<ASTNode> {
return None;
};

let placeholder_count = Regex::new(r"\{[^}]*\}")
.unwrap()
.find_iter(&content)
.count();
let placeholder_count = count_placeholders(&content);

if placeholder_count == 0 {
// No format → Print just a string
Expand Down Expand Up @@ -195,10 +189,7 @@ pub fn parse_input(tokens: &mut Peekable<Iter<Token>>) -> Option<ASTNode> {
return None;
};

let placeholder_count = Regex::new(r"\{[^}]*\}")
.unwrap()
.find_iter(&content)
.count();
let placeholder_count = count_placeholders(&content);

let mut args = Vec::new();
while let Some(Token {
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pub mod runner;
pub mod version;

use crate::version::get_os_pretty_name;
use colorex::Colorize;
use utils::colorex::*;
use std::path::Path;

use commands::DebugFlags;
Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::path::Path;
use std::{env, process};

use colorex::Colorize;
use utils::colorex::*;
use wavec::commands::{handle_build, handle_run, DebugFlags};
use wavec::errors::CliError;
use wavec::version_wave;
Expand Down
4 changes: 4 additions & 0 deletions utils/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[package]
name = "utils"
version = "0.1.0"
edition = "2021"
92 changes: 92 additions & 0 deletions utils/src/colorex.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
pub struct Color(u8, u8, u8);

impl Color {
pub fn from_rgb(rgb: &str) -> Result<Color, &'static str> {
let parts: Vec<&str> = rgb.split(',').collect();
if parts.len() == 3 {
let r = parts[0].parse::<u8>().map_err(|_| "Invalid RGB format")?;
let g = parts[1].parse::<u8>().map_err(|_| "Invalid RGB format")?;
let b = parts[2].parse::<u8>().map_err(|_| "Invalid RGB format")?;
Ok(Color(r, g, b))
} else {
Err("Invalid RGB format")
}
}

pub fn from_hex(hex: &str) -> Result<Color, &'static str> {
if hex.len() != 7 || !hex.starts_with('#') {
return Err("Invalid HEX format");
}

let r = u8::from_str_radix(&hex[1..3], 16).map_err(|_| "Invalid HEX value")?;
let g = u8::from_str_radix(&hex[3..5], 16).map_err(|_| "Invalid HEX value")?;
let b = u8::from_str_radix(&hex[5..7], 16).map_err(|_| "Invalid HEX value")?;

Ok(Color(r, g, b))
}
}

pub trait Colorize {
fn color(self, color: &str) -> String;
fn bg_color(self, color: &str) -> String;
fn bold(self) -> String;
fn italic(self) -> String;
fn underline(self) -> String;
fn strikethrough(self) -> String;
fn dim(self) -> String;
fn invert(self) -> String;
}

impl Colorize for &str {
fn color(self, color: &str) -> String {
let color = if color.starts_with('#') {
Color::from_hex(color)
} else {
Color::from_rgb(color)
};

match color {
Ok(c) => format!("\x1b[38;2;{};{};{}m{}\x1b[0m", c.0, c.1, c.2, self),
Err(_) => self.to_string(),
}
}

fn bg_color(self, color: &str) -> String {
let color = if color.starts_with('#') {
Color::from_hex(color)
} else {
Color::from_rgb(color)
};

match color {
Ok(c) => format!("\x1b[48;2;{};{};{}m{}\x1b[0m", c.0, c.1, c.2, self),
Err(_) => self.to_string(),
}
}

fn bold(self) -> String {
format!("\x1b[1m{}\x1b[0m", self)
}

fn italic(self) -> String {
format!("\x1b[3m{}\x1b[0m", self)
}

fn underline(self) -> String {
format!("\x1b[4m{}\x1b[0m", self)
}

fn strikethrough(self) -> String {
format!("\x1b[9m{}\x1b[0m", self)
}

fn dim(self) -> String {
format!("\x1b[2m{}\x1b[0m", self)
}

fn invert(self) -> String {
format!("\x1b[7m{}\x1b[0m", self)
}
}


43 changes: 43 additions & 0 deletions utils/src/formatx.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// utils/formatx.rs
//
// Wave internal format utilities.
// This module replaces regex usage for placeholder detection.
// Supported pattern: `{ ... }` (non-nested, no escape)

/// Count `{...}` placeholders in the given string.
///
/// Equivalent to the regex pattern: `\{[^}]*\}`
///
/// Examples:
/// - "hello {}" -> 1
/// - "{a}{b}{c}" -> 3
/// - "{ not closed" -> 0
pub fn count_placeholders(input: &str) -> usize {
let bytes = input.as_bytes();
let mut i = 0;
let mut count = 0;

while i < bytes.len() {
if bytes[i] == b'{' {
let start = i;
i += 1;

while i < bytes.len() {
if bytes[i] == b'}' {
count += 1;
i += 1;
break;
}
i += 1;
}

if i >= bytes.len() && bytes[start] == b'{' {
break;
}
} else {
i += 1;
}
}

count
}
4 changes: 4 additions & 0 deletions utils/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pub mod colorex;
pub mod formatx;

pub use colorex::Colorize;