mirror of
https://github.com/SpaceManiac/SpacemanDMM.git
synced 2025-12-23 05:36:47 +00:00
Fix regression on defined() preprocessing (#152)
Fixes #96.
0a650be853 changed the preprocessor to
always substitute macros for their value if they were defined, as such
`#if defined(FOO)` would cause a lint error if `FOO` was defined.
There were two different errors with the exact same message, the first
would happen if `#define FOO` because `defined()` would have no
arguments. The second would happen if `#define FOO 1` because `1`
isn't an ident.
Because of those tangentially related things I discovered in my
attempts to fix the bug, I've changed the error messages to be more
specific.
This commit is contained in:
parent
b945de9315
commit
bb70113d0f
2 changed files with 18 additions and 6 deletions
|
|
@ -743,7 +743,7 @@ impl<'a> ConstantFolder<'a> {
|
|||
"rgb" => {
|
||||
use std::fmt::Write;
|
||||
if args.len() != 3 && args.len() != 4 {
|
||||
return Err(self.error("malformed rgb() call"));
|
||||
return Err(self.error(format!("malformed rgb() call, must have 3 or 4 arguments and instead has {}", args.len())));
|
||||
}
|
||||
let mut result = String::with_capacity(7);
|
||||
result.push_str("#");
|
||||
|
|
@ -752,7 +752,7 @@ impl<'a> ConstantFolder<'a> {
|
|||
let clamped = std::cmp::max(::std::cmp::min(i, 255), 0);
|
||||
let _ = write!(result, "{:02x}", clamped);
|
||||
} else {
|
||||
return Err(self.error("malformed rgb() call"));
|
||||
return Err(self.error("malformed rgb() call, argument wasn't an int"));
|
||||
}
|
||||
}
|
||||
Constant::String(result)
|
||||
|
|
@ -760,7 +760,7 @@ impl<'a> ConstantFolder<'a> {
|
|||
"defined" if self.defines.is_some() => {
|
||||
let defines = self.defines.unwrap(); // annoying, but keeps the match clean
|
||||
if args.len() != 1 {
|
||||
return Err(self.error("malformed defined() call"));
|
||||
return Err(self.error(format!("malformed defined() call, must have 1 argument and instead has {}", args.len())));
|
||||
}
|
||||
match args[0] {
|
||||
Expression::Base {
|
||||
|
|
@ -770,7 +770,7 @@ impl<'a> ConstantFolder<'a> {
|
|||
} if unary.is_empty() && follow.is_empty() => {
|
||||
Constant::Int(if defines.contains_key(ident) { 1 } else { 0 })
|
||||
},
|
||||
_ => return Err(self.error("malformed defined() call")),
|
||||
_ => return Err(self.error("malformed defined() call, argument given isn't an Ident.")),
|
||||
}
|
||||
}
|
||||
// other functions are no-goes
|
||||
|
|
@ -789,7 +789,7 @@ impl<'a> ConstantFolder<'a> {
|
|||
|
||||
fn trig_op(&mut self, mut args: Vec<Expression>, op: fn(f32) -> f32) -> Result<Constant, DMError> {
|
||||
if args.len() != 1 {
|
||||
Err(self.error("trig function requires exactly 1 argument"))
|
||||
Err(self.error(format!("trig function requires exactly 1 argument, instead found {}", args.len())))
|
||||
} else if let Some(f) = self.expr(args.remove(0), None)?.to_float() {
|
||||
Ok(Constant::Float(op(f)))
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -930,7 +930,7 @@ impl<'ctx> Preprocessor<'ctx> {
|
|||
// anything other than directives may be ifdef'd out
|
||||
_ if disabled => return Ok(()),
|
||||
// identifiers may be macros
|
||||
Token::Ident(ref ident, _) => {
|
||||
Token::Ident(ref ident, whitespace) => {
|
||||
self.flush_docs();
|
||||
|
||||
// lint for BYOND bug
|
||||
|
|
@ -955,6 +955,18 @@ impl<'ctx> Preprocessor<'ctx> {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
// special case for inside a defined() call
|
||||
if let Some(Token::Punct(Punctuation::LParen)) = self.output.back() {
|
||||
if let Some(idx) = self.output.len().checked_sub(2) {
|
||||
if let Some(Token::Ident(identname, _)) = self.output.get(idx) {
|
||||
if identname.as_str() == "defined" {
|
||||
self.output.push_back(Token::Ident(ident.to_owned(), whitespace));
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if it's a define, perform the substitution
|
||||
let mut expansion = self.defines.get(ident).cloned(); // TODO: don't clone?
|
||||
if expansion.is_some() && self.include_stack.stack.len() > MAX_RECURSION_DEPTH {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue