Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
feat: add support for stringizing in preprocessor
Browse files Browse the repository at this point in the history
  • Loading branch information
Sarrus1 committed Jul 18, 2023
1 parent 8095d45 commit e5b71f6
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 14 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## [0.10.12]

### Added

- Added support for stringizing in preprocessor.

### Fixed

- Fixed "receiving on an empty or disconnected channel" bug when stopping the server.
Expand Down
4 changes: 1 addition & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ tempfile = "3.4.0"
clap = { version = "4.1.13", features = ["derive"] }
fern = "0.6.2"
humantime = "2.1.0"
sourcepawn_lexer = "0.1.0"
sourcepawn_lexer = "0.1.1"
sourcepawn_preprocessor = { path = "src/sourcepawn_preprocessor" }
sentry = "0.31.3"
strip_bom = "1.0.0"
Expand Down
2 changes: 1 addition & 1 deletion src/sourcepawn_preprocessor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ anyhow = "1.0.66"
lazy_static = "1.4.0"
regex = "1.7.0"
fxhash = "0.2.1"
sourcepawn_lexer = "0.1.0"
sourcepawn_lexer = "0.1.1"
92 changes: 92 additions & 0 deletions src/sourcepawn_preprocessor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1135,6 +1135,34 @@ int foo = 1 + 2;
);
}

#[test]
fn macro_expansion_5() {
let input = r#"#define GET_VALUE(%1,%2) \
public %1 Get%2(){ \
%1 i; \
this.GetValue("m_" ... #%2, i); \
return i;}
GET_VALUE(void, Foo)"#;
let output = r#"#define GET_VALUE(%1,%2) \
public %1 Get%2(){ \
%1 i; \
this.GetValue("m_" ... #%2, i); \
return i;}
public void GetFoo(){ void i; this.GetValue("m_" ... "Foo", i); return i;}"#;

assert_eq!(
SourcepawnPreprocessor::new(
Arc::new(Url::parse("https://example.net").unwrap()),
input
)
.preprocess_input(&mut extend_macros)
.unwrap(),
output
);
}

#[test]
fn include_directive_1() {
let input = r#"#include <sourcemod>"#;
Expand Down Expand Up @@ -1184,4 +1212,68 @@ int foo = 1 + 2;
output
);
}

#[test]
fn stringizing_1() {
let input = r#"#define FOO(%0) #%0
char foo[8] = FOO(foo);"#;
let output = r#"#define FOO(%0) #%0
char foo[8] = "foo";"#;
assert_eq!(
SourcepawnPreprocessor::new(
Arc::new(Url::parse("https://example.net").unwrap()),
input
)
.preprocess_input(&mut extend_macros)
.unwrap(),
output
);
}

#[test]
fn stringizing_2() {
let input = r#"#define FOO(%0,%1) #%0 ... #%1
char foo[8] = FOO(foo, bar);"#;
let output = r#"#define FOO(%0,%1) #%0 ... #%1
char foo[8] = "foo" ... "bar";"#;
assert_eq!(
SourcepawnPreprocessor::new(
Arc::new(Url::parse("https://example.net").unwrap()),
input
)
.preprocess_input(&mut extend_macros)
.unwrap(),
output
);
}

#[test]
fn stringizing_3() {
let input = r#"#define DISPOSE_MEMBER(%1) \
Handle m_h%1; \
if(this.GetValue("m_" ... #%1, m_h%1)){ \
delete m_h%1;}
void foo(){
DISPOSE_MEMBER(Foo)
}"#;
let output = r#"#define DISPOSE_MEMBER(%1) \
Handle m_h%1; \
if(this.GetValue("m_" ... #%1, m_h%1)){ \
delete m_h%1;}
void foo(){
Handle m_hFoo; if(this.GetValue("m_" ... "Foo", m_hFoo)){ delete m_hFoo;}
}"#;
assert_eq!(
SourcepawnPreprocessor::new(
Arc::new(Url::parse("https://example.net").unwrap()),
input
)
.preprocess_input(&mut extend_macros)
.unwrap_or_else(|err| {
eprintln!("{:?}", err);
"".to_string()
}),
output
);
}
}
53 changes: 46 additions & 7 deletions src/sourcepawn_preprocessor/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ fn expand_macro(
d: i32,
) -> Result<(), ParseIntError> {
let mut consecutive_percent = 0;
let mut stringize_delta = None;
for (i, child) in macro_.body.iter().enumerate() {
match &child.token_kind {
TokenKind::Operator(Operator::Percent) => {
Expand All @@ -114,9 +115,13 @@ fn expand_macro(
stack.push((child.clone(), child.delta, d + 1))
}
}
TokenKind::Operator(Operator::Stringize) => {
stringize_delta = Some(child.delta);
stack.push((child.clone(), child.delta, d + 1))
}
TokenKind::Literal(Literal::IntegerLiteral) => {
if consecutive_percent == 1 {
stack.pop();
let percent_symbol = stack.pop().unwrap(); // Safe unwrap.
let arg_idx = child
.to_int()
.ok_or_else(|| ParseIntError::new(child.text(), child.range))?
Expand All @@ -129,12 +134,45 @@ fn expand_macro(
if arg_idx >= 10 {
return Err(ParseIntError::new(child.text(), child.range));
}
for (j, sub_child) in args[arg_idx as usize].iter().enumerate() {
stack.push((
sub_child.clone(),
if j == 0 { child.delta } else { sub_child.delta },
d + 1,
));
if let Some(stringize_delta) = stringize_delta.take() {
stack.pop();
let mut stringized = '"'.to_string();
for sub_child in args[arg_idx as usize].iter() {
stringized.push_str(&sub_child.inline_text());
}
stringized.push('"');
let delta = if i == 2 {
symbol.delta
} else {
stringize_delta
};
let symbol = Symbol::new(
TokenKind::Literal(Literal::StringLiteral),
Some(&stringized),
Range::new(
symbol.range.start,
Position::new(
symbol.range.start.line,
symbol.range.start.character + stringized.len() as u32,
),
),
delta,
);
stack.push((symbol, delta, d + 1));
} else {
for (j, sub_child) in args[arg_idx as usize].iter().enumerate() {
stack.push((
sub_child.clone(),
if i == 1 {
symbol.delta
} else if j == 0 {
percent_symbol.1
} else {
sub_child.delta
},
d + 1,
));
}
}
} else {
stack.push((child.clone(), child.delta, d + 1));
Expand All @@ -148,6 +186,7 @@ fn expand_macro(
d + 1,
));
consecutive_percent = 0;
stringize_delta = None;
}
}
}
Expand Down
12 changes: 10 additions & 2 deletions src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,11 @@ impl Store {
self.extend_macros(macros, path, document_uri, quoted)
}),
)
.unwrap_or_else(|_| document.text.clone());
.unwrap_or_else(|err| {
log::error!("{:?}", err);
document.text.clone()
});

document.preprocessed_text = preprocessed_text;
document.macros = preprocessor.macros.clone();
document.offsets = preprocessor.offsets.clone();
Expand Down Expand Up @@ -334,7 +338,11 @@ impl Store {
self.extend_macros(macros, path, document_uri, quoted)
}),
)
.unwrap_or_else(|_| text.clone());
.unwrap_or_else(|err| {
log::error!("{:?}", err);
text.clone()
});

if let Some(document) = self.documents.get_mut(&uri) {
document.preprocessed_text = preprocessed_text;
document.macros = preprocessor.macros.clone();
Expand Down

0 comments on commit e5b71f6

Please sign in to comment.