Skip to content

Commit c12e988

Browse files
committed
feat: add concat macro
1 parent a074b33 commit c12e988

File tree

2 files changed

+98
-18
lines changed

2 files changed

+98
-18
lines changed

src/lexer/token.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -243,19 +243,19 @@ pub enum Token {
243243
impl Display for Token {
244244
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
245245
match self {
246-
Token::Name(name) => write!(f, "{}", name),
246+
Token::Name(name) => write!(f, "name{}", name),
247247
Token::Define => write!(f, "%define"),
248248
Token::Undef => write!(f, "%undef"),
249249
Token::Newline => write!(f, "\n"),
250250
Token::Backslash => write!(f, "\\"),
251-
Token::Arg(name) => write!(f, "{}", name),
252-
Token::Bin(value) => write!(f, "{}", value),
253-
Token::Oct(value) => write!(f, "{}", value),
254-
Token::Int(value) => write!(f, "{}", value),
255-
Token::Hex(value) => write!(f, "{}", value),
256-
Token::Float(value) => write!(f, "{}", value),
257-
Token::Str(value) => write!(f, "{}", value),
258-
Token::Cmd(value) => write!(f, "{}", value),
251+
Token::Arg(name) => write!(f, "${}", name),
252+
Token::Bin(value) => write!(f, "bin{}", value),
253+
Token::Oct(value) => write!(f, "oct{}", value),
254+
Token::Int(value) => write!(f, "int{}", value),
255+
Token::Hex(value) => write!(f, "hex{}", value),
256+
Token::Float(value) => write!(f, "float{}", value),
257+
Token::Str(value) => write!(f, "str{}", value),
258+
Token::Cmd(value) => write!(f, "cmd{}", value),
259259
Token::Costumes => write!(f, "costumes"),
260260
Token::Sounds => write!(f, "sounds"),
261261
Token::Local => write!(f, "local"),

src/pre_processor.rs

Lines changed: 89 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ impl<'a, 'b> PreProcessor<'a, 'b> {
6060
span: &mut Span,
6161
suppress: &FxHashSet<SmolStr>,
6262
) -> Result<(), Diagnostic> {
63+
let mut dirty = false;
6364
*self.i = span.start;
6465
while *self.i < span.end {
6566
if let Some(define_name) = self.parse_define_begin(span)? {
@@ -69,15 +70,24 @@ impl<'a, 'b> PreProcessor<'a, 'b> {
6970
self.parse_simple_define(span, define_name)?;
7071
continue;
7172
}
73+
if self.parse_undef(span)? {
74+
continue;
75+
}
7276
if self.substitute_simple_define(span, suppress)? {
7377
continue;
7478
}
7579
if self.substitute_function_define(span, suppress)? {
7680
continue;
7781
}
82+
if self.substitute_concat(span)? {
83+
dirty = true;
84+
continue;
85+
}
7886
*self.i += 1;
7987
}
80-
88+
if dirty {
89+
self.process(span, suppress)?;
90+
}
8191
Ok(())
8292
}
8393

@@ -133,7 +143,7 @@ impl<'a, 'b> PreProcessor<'a, 'b> {
133143
if !matches!(name, Token::Name(_) | Token::LParen) {
134144
return Ok(false);
135145
}
136-
self.tokens.remove(*self.i);
146+
self.remove_token(span);
137147
let mut args = vec![];
138148
while name != Token::RParen {
139149
if name != Token::Comma {
@@ -165,18 +175,21 @@ impl<'a, 'b> PreProcessor<'a, 'b> {
165175
let mut body = vec![];
166176
self.expect_no_eof()?;
167177
let mut token = get_token(&self.tokens[*self.i]);
168-
while token != &Token::Newline {
169-
body.push(token.clone());
170-
self.remove_token(span);
171-
self.expect_no_eof()?;
172-
token = get_token(&self.tokens[*self.i]);
178+
loop {
173179
if token == &Token::Backslash {
174180
self.remove_token(span);
175181
self.expect_no_eof()?;
176182
self.remove_token(span);
177183
self.expect_no_eof()?;
178184
token = get_token(&self.tokens[*self.i]);
179185
}
186+
if token == &Token::Newline {
187+
break;
188+
}
189+
body.push(token.clone());
190+
self.remove_token(span);
191+
self.expect_no_eof()?;
192+
token = get_token(&self.tokens[*self.i]);
180193
}
181194
self.remove_token(span);
182195
Ok(body)
@@ -208,7 +221,8 @@ impl<'a, 'b> PreProcessor<'a, 'b> {
208221
let subspan_end = *self.i + simple_define_body.len();
209222
let mut subspan = *self.i..subspan_end;
210223
self.process(&mut subspan, &suppress)?;
211-
span.end += subspan.end - subspan_end;
224+
span.end =
225+
((span.end as isize) + ((subspan.end as isize) - (subspan_end as isize))) as usize;
212226
Ok(true)
213227
}
214228

@@ -298,7 +312,73 @@ impl<'a, 'b> PreProcessor<'a, 'b> {
298312
suppress.insert(macro_name);
299313
let mut subspan = *self.i..i;
300314
self.process(&mut subspan, &suppress)?;
301-
span.end += subspan.end - i;
315+
span.end = ((span.end as isize) + ((subspan.end as isize) - (i as isize))) as usize;
316+
Ok(true)
317+
}
318+
319+
fn parse_undef(&mut self, span: &mut Span) -> Result<bool, Diagnostic> {
320+
if get_token(&self.tokens[*self.i]) != &Token::Undef {
321+
return Ok(false);
322+
}
323+
self.remove_token(span);
324+
self.expect_no_eof()?;
325+
let name = get_token(&self.tokens[*self.i]).clone();
326+
self.simple_defines.remove(name.to_string().as_str());
327+
self.function_defines.remove(name.to_string().as_str());
328+
self.remove_token(span);
329+
Ok(true)
330+
}
331+
332+
fn substitute_concat(&mut self, span: &mut Span) -> Result<bool, Diagnostic> {
333+
let Token::Name(macro_name) = get_token(&self.tokens[*self.i]) else {
334+
return Ok(false);
335+
};
336+
let macro_name_span = get_span(&self.tokens[*self.i]);
337+
if macro_name != "CONCAT" {
338+
return Ok(false);
339+
}
340+
if self
341+
.tokens
342+
.get(*self.i + 1)
343+
.is_none_or(|token| get_token(token) != &Token::LParen)
344+
{
345+
return Ok(false);
346+
}
347+
if self
348+
.tokens
349+
.get(*self.i + 3)
350+
.is_none_or(|token| get_token(token) != &Token::Comma)
351+
{
352+
return Ok(false);
353+
}
354+
if self
355+
.tokens
356+
.get(*self.i + 5)
357+
.is_none_or(|token| get_token(token) != &Token::RParen)
358+
{
359+
return Ok(false);
360+
}
361+
let Some(Token::Name(left)) = self.tokens.get(*self.i + 2).map(get_token).cloned() else {
362+
return Ok(false);
363+
};
364+
let Some(Token::Name(right)) = self.tokens.get(*self.i + 4).map(get_token).cloned() else {
365+
return Ok(false);
366+
};
367+
self.remove_token(span);
368+
self.remove_token(span);
369+
self.remove_token(span);
370+
self.remove_token(span);
371+
self.remove_token(span);
372+
self.remove_token(span);
373+
self.tokens.insert(
374+
*self.i,
375+
(
376+
macro_name_span.start,
377+
Token::Name(format!("{}{}", left, right).into()),
378+
macro_name_span.end,
379+
),
380+
);
381+
span.end += 1;
302382
Ok(true)
303383
}
304384
}

0 commit comments

Comments
 (0)