Skip to content

Commit 8f9b0be

Browse files
authored
feat: improve inline asm parsing and type safety (#265)
Enhance inline assembly block parsing and type handling for greater robustness and expressiveness. Changes: - **ASM Parsing**: - `parse_asm_block` now supports generic `Expression` for inputs/outputs, allowing variable references, literals (decimal, hex, binary), pointers (`&x`), and dereferences (`deref x`). - Added `parse_asm_operand` to handle various operand types. - Implemented `parse_asm_inout_clause` for cleaner `in`/`out` parsing. - Enforced `is_assignable` check for `out` operands. - **LLVM Codegen**: - `gen_asm_stmt_ir` refactored to support multiple outputs via struct return values. - `asm_operand_to_value` converts AST expressions to LLVM values, handling literals (with correct radix) and address-of operations. - `store_asm_output` handles writing assembly results back to variables, including pointer casts. - Added `coerce_basic_value` for explicit type conversions (e.g., int to pointer for syscalls) and implicit widening. - **Type Safety**: - Implemented `coerce_to_expected` in function calls to automatically widen integers (e.g., `i32` -> `i64`) and cast pointers where safe. - `gen_variable_ir` now uses `coerce_basic_value` for initializers. - **Tests**: - Updated `test56.wave` (syscalls) to use new asm features and type-safe wrappers (`syscall4i`, `syscall4p`). - Fixed array size in `test66.wave`. - Added explicit type for overflow test in `test69.wave`. - Marked `test56.wave` as a known timeout in test runner (server test). - **Error Reporting**: - Integrated `colorex` crate for colored error messages in `front/error`. - Lexer now produces `IntLiteral` token type, storing the raw string representation for later parsing (preserving radix info). This update makes inline assembly more versatile and integrates it better with the type system. Signed-off-by: LunaStev <luna@lunastev.org>
1 parent a8216e6 commit 8f9b0be

24 files changed

Lines changed: 872 additions & 842 deletions

File tree

front/error/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ version = "0.1.0"
44
edition = "2021"
55

66
[dependencies]
7-
colored = "2.0"
7+
colorex = "0.1.1"

front/error/src/error.rs

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -178,13 +178,13 @@ impl WaveError {
178178

179179
/// Display error in Rust-style format
180180
pub fn display(&self) {
181-
use colored::*;
181+
use colorex::Colorize;
182182

183183
let severity_str = match self.severity {
184-
ErrorSeverity::Error => "error".red().bold(),
185-
ErrorSeverity::Warning => "warning".yellow().bold(),
186-
ErrorSeverity::Note => "note".cyan().bold(),
187-
ErrorSeverity::Help => "help".green().bold(),
184+
ErrorSeverity::Error => "error".color("255,71,71").bold(),
185+
ErrorSeverity::Warning => "warning".color("145,161,2").bold(),
186+
ErrorSeverity::Note => "note".color("0,255,255").bold(),
187+
ErrorSeverity::Help => "help".color("38,139,235").bold(),
188188
};
189189

190190
// Main error message
@@ -193,61 +193,61 @@ impl WaveError {
193193
// Location
194194
eprintln!(
195195
" {} {}:{}:{}",
196-
"-->".blue().bold(),
196+
"-->".color("38,139,235").bold(),
197197
self.file,
198198
self.line,
199199
self.column
200200
);
201-
eprintln!(" {}", "|".blue().bold());
201+
eprintln!(" {}", "|".color("38,139,235").bold());
202202

203203
// Source code with highlighting
204204
if let Some(source_line) = &self.source {
205205
eprintln!(
206206
"{:>3} {} {}",
207-
self.line.to_string().blue().bold(),
208-
"|".blue().bold(),
207+
self.line.to_string().color("38,139,235").bold(),
208+
"|".color("38,139,235").bold(),
209209
source_line
210210
);
211211

212212
// Arrow pointing to the error
213213
let spaces = " ".repeat(self.column.saturating_sub(1));
214214
let arrow = match self.severity {
215-
ErrorSeverity::Error => "^".red().bold(),
216-
ErrorSeverity::Warning => "^".yellow().bold(),
217-
ErrorSeverity::Note => "^".cyan().bold(),
218-
ErrorSeverity::Help => "^".green().bold(),
215+
ErrorSeverity::Error => "^".color("255,71,71").bold(),
216+
ErrorSeverity::Warning => "^".color("145,161,2").bold(),
217+
ErrorSeverity::Note => "^".color("0,255,255").bold(),
218+
ErrorSeverity::Help => "^".color("38,139,235").bold(),
219219
};
220220

221221
if let Some(label) = &self.label {
222222
eprintln!(
223223
" {} {}{} {}",
224-
"|".blue().bold(),
224+
"|".color("38,139,235").bold(),
225225
spaces,
226226
arrow,
227-
label.dimmed()
227+
label.dim()
228228
);
229229
} else {
230-
eprintln!(" {} {}{}", "|".blue().bold(), spaces, arrow);
230+
eprintln!(" {} {}{}", "|".color("38,139,235").bold(), spaces, arrow);
231231
}
232232
}
233233

234-
eprintln!(" {}", "|".blue().bold());
234+
eprintln!(" {}", "|".color("38,139,235").bold());
235235

236236
// Additional information
237237
if let Some(note) = &self.note {
238238
eprintln!(
239239
" {} {}: {}",
240-
"=".blue().bold(),
241-
"note".cyan().bold(),
240+
"=".color("38,139,235").bold(),
241+
"note".color("0,255,255").bold(),
242242
note
243243
);
244244
}
245245

246246
if let Some(help) = &self.help {
247247
eprintln!(
248248
" {} {}: {}",
249-
"=".blue().bold(),
250-
"help".green().bold(),
249+
"=".color("38,139,235").bold(),
250+
"help".color("38,139,235").bold(),
251251
help
252252
);
253253
}
@@ -256,8 +256,8 @@ impl WaveError {
256256
for suggestion in &self.suggestions {
257257
eprintln!(
258258
" {} {}: {}",
259-
"=".blue().bold(),
260-
"suggestion".green().bold(),
259+
"=".color("38,139,235").bold(),
260+
"suggestion".color("38,139,235").bold(),
261261
suggestion
262262
);
263263
}

front/lexer/src/lexer/scan.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -345,10 +345,10 @@ impl<'a> Lexer<'a> {
345345
let value = i64::from_str_radix(&bin_str, 2).unwrap_or(0);
346346

347347
return Token {
348-
token_type: TokenType::Number(value),
348+
token_type: TokenType::IntLiteral(format!("0b{}", bin_str)),
349349
lexeme: format!("0b{}", bin_str),
350350
line: self.line,
351-
}
351+
};
352352
}
353353

354354
if c == '0' && (self.peek() == 'x' || self.peek() == 'X') {
@@ -362,7 +362,7 @@ impl<'a> Lexer<'a> {
362362
let value = i64::from_str_radix(&hex_str, 16).unwrap_or(0);
363363

364364
return Token {
365-
token_type: TokenType::Number(value),
365+
token_type: TokenType::IntLiteral(format!("0x{}", hex_str)),
366366
lexeme: format!("0x{}", hex_str),
367367
line: self.line,
368368
};
@@ -387,7 +387,7 @@ impl<'a> Lexer<'a> {
387387
let token_type = if is_float {
388388
num_str.parse::<f64>().map(TokenType::Float).unwrap()
389389
} else {
390-
num_str.parse::<i64>().map(TokenType::Number).unwrap()
390+
TokenType::IntLiteral(num_str.clone())
391391
};
392392

393393
Token {

front/lexer/src/token.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ pub enum TokenType {
124124
TypeArray(Box<TokenType>, u32),
125125
Identifier(String),
126126
String(String),
127-
Number(i64),
127+
IntLiteral(String),
128128
Float(f64),
129129
Plus, // +
130130
Increment, // ++

front/parser/src/ast.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ pub enum Expression {
142142

143143
#[derive(Debug, Clone)]
144144
pub enum Literal {
145-
Number(i64),
145+
Int(String),
146146
Float(f64),
147147
String(String),
148148
Bool(bool),
@@ -226,8 +226,8 @@ pub enum StatementNode {
226226
},
227227
AsmBlock {
228228
instructions: Vec<String>,
229-
inputs: Vec<(String, String)>,
230-
outputs: Vec<(String, String)>,
229+
inputs: Vec<(String, Expression)>,
230+
outputs: Vec<(String, Expression)>,
231231
},
232232
Break,
233233
Continue,
@@ -281,7 +281,7 @@ impl Expression {
281281
.unwrap_or_else(|| panic!("Variable '{}' not found", name))
282282
.ty
283283
.clone(),
284-
Expression::Literal(Literal::Number(_)) => WaveType::Int(32), // 기본 int
284+
Expression::Literal(Literal::Int(_)) => WaveType::Int(32),
285285
Expression::Literal(Literal::Float(_)) => WaveType::Float(32),
286286
Expression::Literal(Literal::String(_)) => WaveType::String,
287287
Expression::MethodCall { .. } => {

0 commit comments

Comments
 (0)