1use std::{
2 borrow::Borrow,
3 cell::RefCell,
4 fmt::Write,
5 io::{Cursor, Read},
6 iter,
7 marker::PhantomData,
8 path::Path,
9 rc::Rc,
10};
11
12use fxhash::FxHashMap;
13
14use crate::{
15 expr::{Expr, ExprNode},
16 fileman::{FileManager, FileSystem},
17 intern::{PathRef, StrInterner, StrRef},
18 lexer::{
19 ArchTokens, DirectiveName, LabelKind, Lexer, LexerError, SourceLoc, SymbolName, Token,
20 },
21 linker::{Link, Module},
22 symtab::{Symbol, Symtab},
23};
24
25#[cfg(test)]
26mod tests;
27
28macro_rules! asm_err {
29 ($loc:expr, $($arg:tt)*) => {
30 Err(($loc, AssemblerError(format!($($arg)*))))
31 };
32}
33
34enum TokenSource<R, A: ArchTokens> {
35 Lexer(Lexer<R, A>),
37 ParseLexer(Lexer<Cursor<String>, A>),
39 Macro(MacroState<A>),
41}
42
43impl<R: Read, A: ArchTokens> TokenSource<R, A> {
44 pub fn loc(&self) -> SourceLoc {
45 match self {
46 Self::Lexer(lexer) => lexer.loc(),
47 Self::ParseLexer(lexer) => lexer.loc(),
48 Self::Macro(state) => state.loc,
49 }
50 }
51
52 pub fn included_from(&self) -> Option<SourceLoc> {
53 match self {
54 Self::Lexer(lexer) => lexer.included_from(),
55 Self::ParseLexer(lexer) => lexer.included_from(),
56 Self::Macro(state) => state.included_from,
57 }
58 }
59
60 fn next(
61 &mut self,
62 macros: &mut FxHashMap<StrRef, Macro<A>>,
63 ) -> Option<Result<Token<A>, (SourceLoc, AssemblerError)>> {
64 match self {
65 Self::Lexer(lexer) => lexer.next().map(|res| res.map_err(LexerError::into)),
66 Self::ParseLexer(lexer) => lexer.next().map(|res| res.map_err(LexerError::into)),
67 Self::Macro(state) => {
68 let mac = macros.get_mut(&state.name).unwrap();
69
70 loop {
71 if state.macro_offset >= mac.tokens.len() {
72 return None;
73 }
74
75 if let Some(arg) = state.expanding_macro_arg {
76 let arg_toks = &state.args[arg];
77 if state.macro_arg_offset >= arg_toks.len() {
78 state.expanding_macro_arg = None;
79 state.macro_offset += 1;
80 continue;
81 }
82
83 let tok = arg_toks[state.macro_arg_offset];
85 state.macro_arg_offset += 1;
86 state.loc = tok.loc();
87 return Some(Ok(tok));
88 }
89
90 let tok = mac.tokens[state.macro_offset];
91 match tok {
92 MacroToken::Token(tok) => {
93 state.macro_offset += 1;
94 state.loc = tok.loc();
95 return Some(Ok(tok));
96 }
97
98 MacroToken::Argument { index, .. } => {
99 state.expanding_macro_arg = Some(index);
100 state.macro_arg_offset = 0;
101 continue;
102 }
103
104 MacroToken::Entropy { loc } => {
105 state.macro_offset += 1;
106 state.loc = loc;
107 return Some(Ok(Token::String {
108 loc,
109 value: state.entropy,
110 }));
111 }
112 }
113 }
114 }
115 }
116 }
117}
118
119#[derive(Copy, Clone, Debug)]
120enum MacroToken<A: ArchTokens> {
121 Token(Token<A>),
122 Argument { index: usize },
123 Entropy { loc: SourceLoc },
124}
125
126struct Macro<A: ArchTokens> {
127 args: Vec<StrRef>,
128 tokens: Vec<MacroToken<A>>,
129}
130
131#[derive(thiserror::Error, Debug)]
132#[error("{0}")]
133pub struct AssemblerError(pub String);
134
135impl From<LexerError> for (SourceLoc, AssemblerError) {
136 fn from(e: LexerError) -> Self {
137 (e.loc(), AssemblerError(format!("{e}")))
138 }
139}
140
141struct MacroState<A: ArchTokens> {
142 name: StrRef,
143 args: Vec<Vec<Token<A>>>,
144 macro_offset: usize,
145 expanding_macro_arg: Option<usize>,
146 macro_arg_offset: usize,
147 loc: SourceLoc,
148 included_from: Option<SourceLoc>,
149 entropy: StrRef,
150}
151
152enum SegmentMode {
153 Code,
154 Addr,
155}
156
157pub struct Assembler<S, R, A: ArchTokens, Z> {
158 file_manager: FileManager<S>,
159 pub(crate) str_interner: Rc<RefCell<StrInterner>>,
160 token_sources: Vec<TokenSource<R, A>>,
161 token_source: Option<TokenSource<R, A>>,
162 cwds: Vec<PathRef>,
163 cwd: Option<PathRef>,
164 macros: FxHashMap<StrRef, Macro<A>>,
165 pub(crate) symtab: Symtab,
166 pub(crate) data: Vec<u8>,
167 seg_mode: SegmentMode,
168 pub(crate) links: Vec<Link>,
169
170 entropy: usize,
171 stash: Option<Token<A>>,
172 loc: Option<SourceLoc>,
173 pub(crate) here: u32,
174 active_namespace: Option<StrRef>,
175 active_macro: Option<StrRef>,
176 if_level: usize,
177
178 marker: PhantomData<Z>,
179}
180
181pub trait ArchAssembler<S, R, A: ArchTokens> {
182 fn parse(
183 asm: &mut Assembler<S, R, A, Self>,
184 name: A::OperationName,
185 ) -> Result<(), (SourceLoc, AssemblerError)>
186 where
187 Self: Sized;
188}
189
190impl<S, R, A, Z> Assembler<S, R, A, Z>
191where
192 S: FileSystem<Reader = R>,
193 R: Read,
194 A: ArchTokens,
195 Z: ArchAssembler<S, R, A>,
196{
197 pub fn new(file_system: S, _: Z) -> Self {
198 Self {
199 file_manager: FileManager::new(file_system),
200 str_interner: Rc::new(RefCell::new(StrInterner::new())),
201 token_sources: Vec::new(),
202 token_source: None,
203 cwds: Vec::new(),
204 cwd: None,
205 macros: FxHashMap::default(),
206 symtab: Symtab::new(),
207 data: Vec::new(),
208 seg_mode: SegmentMode::Code,
209 links: Vec::new(),
210
211 entropy: 0,
212 stash: None,
213 loc: None,
214 here: 0,
215 active_namespace: None,
216 active_macro: None,
217 if_level: 0,
218
219 marker: PhantomData,
220 }
221 }
222
223 pub fn add_search_path<C: AsRef<Path>, P: AsRef<Path>>(
224 &mut self,
225 cwd: C,
226 path: P,
227 ) -> Result<(), AssemblerError> {
228 let path = path.as_ref();
229 self.file_manager.add_search_path(cwd, path).map_err(|e| {
230 AssemblerError(format!(
231 "Failed to find include path \"{}\": {e}",
232 path.display()
233 ))
234 })?;
235 Ok(())
236 }
237
238 pub fn assemble<C: AsRef<Path>, P: AsRef<Path>>(
239 mut self,
240 cwd: C,
241 path: P,
242 ) -> Result<Module<S>, AssemblerError> {
243 let path = path.as_ref();
244 let (pathref, reader) = match self.file_manager.reader(&cwd, path) {
245 Ok(Some(tup)) => tup,
246 Ok(None) => {
247 return Err(AssemblerError(format!(
248 "File not found: \"{}\"",
249 path.display()
250 )))
251 }
252 Err(e) => {
253 return Err(AssemblerError(format!(
254 "Failed to open \"{}\" for reading: {e}",
255 path.display()
256 )))
257 }
258 };
259
260 self.token_source = Some(TokenSource::Lexer(Lexer::new(
261 self.str_interner.clone(),
262 None,
263 pathref,
264 reader,
265 )));
266 self.cwd = Some(self.file_manager.intern(cwd, "."));
267
268 if let Err((loc, e)) = self.parse_all() {
269 return Err(self.trace_error(loc, e));
270 }
271
272 let Self {
273 str_interner,
274 file_manager,
275 symtab,
276 data,
277 links,
278 ..
279 } = self;
280 Ok(Module::new(str_interner, file_manager, symtab, data, links))
281 }
282
283 #[inline]
284 fn loc(&mut self) -> SourceLoc {
285 self.loc.unwrap()
286 }
287
288 pub(crate) fn peek(&mut self) -> Result<Option<Token<A>>, (SourceLoc, AssemblerError)> {
289 loop {
290 if self.token_source.is_none() {
291 self.token_source = self.token_sources.pop();
292 self.cwd = self.cwds.pop();
293 }
294 match self.stash {
295 Some(_) => return Ok(self.stash),
296
297 None => match &mut self.token_source {
298 None => return Ok(None),
299
300 Some(token_source) => {
301 let tok = token_source.next(&mut self.macros).transpose()?;
302 if let Some(Token::Symbol {
306 name: SymbolName::BackSlash,
307 ..
308 }) = tok
309 {
310 match token_source.next(&mut self.macros).transpose()? {
311 None => return self.end_of_input_err(),
312
313 Some(Token::Comment { .. } | Token::NewLine { .. }) => {
314 continue;
315 }
316
317 Some(tok) => {
318 return asm_err!(
319 tok.loc(),
320 "Unexpected {}, expected a line break or comment after a backslash",
321 tok.as_display(&self.str_interner)
322 );
323 }
324 }
325 }
326
327 if self.active_macro.is_none() {
329 if let Some(Token::Label {
331 kind: LabelKind::Global,
332 value,
333 ..
334 }) = tok
335 {
336 if self.macros.contains_key(&value) {
337 let mac = self.expect_macro_invoke(value)?;
338 self.token_sources.push(self.token_source.take().unwrap());
339 self.cwds.push(self.cwd.unwrap());
340
341 self.token_sources.push(TokenSource::Macro(mac));
342 self.cwds.push(self.cwd.take().unwrap());
343 continue;
344 }
345 }
346
347 match tok {
349 Some(Token::Directive {
350 loc,
351 name: DirectiveName::String,
352 }) => {
353 self.stash = Some(self.expect_string_directive_arg(loc)?);
354 self.loc = Some(loc);
355 continue;
356 }
357
358 Some(Token::Directive {
359 loc,
360 name: DirectiveName::Label,
361 }) => {
362 self.stash = Some(self.expect_label_directive_arg(loc)?);
363 self.loc = Some(loc);
364 continue;
365 }
366
367 Some(Token::Directive {
368 loc,
369 name: DirectiveName::Count,
370 }) => {
371 let mac = self.expect_count_directive(loc)?;
372
373 self.token_sources.push(self.token_source.take().unwrap());
374 self.cwds.push(self.cwd.unwrap());
375
376 self.token_sources.push(TokenSource::Macro(mac));
377 self.cwds.push(self.cwd.take().unwrap());
378 continue;
379 }
380
381 Some(Token::Directive {
382 loc,
383 name: DirectiveName::GetMeta,
384 }) => {
385 let direct = match self.next()? {
386 None => return self.end_of_input_err(),
387
388 Some(Token::Label { loc, value, kind }) => match kind {
389 LabelKind::Global | LabelKind::Direct => value,
390
391 LabelKind::Local => {
392 if let Some(namespace) = self.active_namespace {
393 let global_label = {
394 let interner =
395 self.str_interner.as_ref().borrow();
396 let global =
397 interner.get(namespace).unwrap();
398 let label = interner.get(value).unwrap();
399 format!("{global}{label}")
400 };
401 self.str_interner
402 .borrow_mut()
403 .intern(global_label)
404 } else {
405 let interner =
406 self.str_interner.as_ref().borrow();
407 let label = interner.get(value).unwrap();
408 return asm_err!(loc, "The local symbol \"{label}\" is being read but there was no global label defined before it");
409 }
410 }
411 },
412
413 Some(tok) => {
414 return asm_err!(
415 tok.loc(),
416 "Unexpected {}, expected a label",
417 tok.as_display(&self.str_interner)
418 )
419 }
420 };
421
422 self.expect_symbol(SymbolName::Comma)?;
423
424 let key = match self.next()? {
425 None => return self.end_of_input_err(),
426 Some(Token::String { value, .. }) => value,
427 Some(tok) => {
428 return asm_err!(
429 tok.loc(),
430 "Unexpected {}, expected a metadata key",
431 tok.as_display(&self.str_interner)
432 );
433 }
434 };
435
436 let mut toks = Vec::new();
437 if let Some(sym) = self.symtab.get(direct) {
438 if let Some(meta) =
439 self.symtab.meta_interner().get(sym.meta())
440 {
441 for item in meta {
442 if item[0] == key {
443 toks.push(MacroToken::Token(Token::String {
444 loc,
445 value: item[1],
446 }));
447 }
448 }
449 }
450 } else {
451 let mut interner = self.str_interner.borrow_mut();
452 let value = interner.intern("");
453 toks.push(MacroToken::Token(Token::String { loc, value }));
454 }
455
456 let (name, entropy) = {
457 let mut interner = self.str_interner.borrow_mut();
458 let name = interner
459 .intern(format!("@metaget Invocation{}", self.entropy));
460 let entropy =
461 interner.intern(format!("__{}", self.entropy));
462 (name, entropy)
463 };
464 self.entropy += 1;
465 self.macros.insert(
466 name,
467 Macro {
468 args: Vec::new(),
469 tokens: toks,
470 },
471 );
472
473 self.token_sources.push(self.token_source.take().unwrap());
474 self.cwds.push(self.cwd.unwrap());
475
476 self.token_sources.push(TokenSource::Macro(MacroState {
477 name,
478 args: Vec::new(),
479 macro_offset: 0,
480 expanding_macro_arg: None,
481 macro_arg_offset: 0,
482 loc,
483 included_from: Some(loc),
484 entropy,
485 }));
486 self.cwds.push(self.cwd.take().unwrap());
487 continue;
488 }
489
490 Some(Token::Directive {
491 loc,
492 name: DirectiveName::Parse,
493 }) => {
494 let reader = match self.next()? {
495 None => return self.end_of_input_err(),
496 Some(Token::String { value, .. }) => {
497 let interner = self.str_interner.as_ref().borrow();
498 Cursor::new(interner.get(value).unwrap().to_owned())
500 }
501 Some(tok) => {
502 return asm_err!(
503 tok.loc(),
504 "Unexpected {}, expected a string to parse",
505 tok.as_display(&self.str_interner)
506 )
507 }
508 };
509
510 self.token_sources.push(self.token_source.take().unwrap());
511 self.cwds.push(self.cwd.unwrap());
512
513 self.token_sources.push(TokenSource::ParseLexer(Lexer::new(
514 self.str_interner.clone(),
515 Some(loc),
516 loc.pathref,
517 reader,
518 )));
519 self.cwds.push(self.cwd.take().unwrap());
520 continue;
521 }
522
523 Some(Token::Directive {
524 loc,
525 name: DirectiveName::Each,
526 }) => {
527 let mut states = self.expect_each_directive(loc)?;
528 self.token_sources.push(self.token_source.take().unwrap());
529 self.cwds.push(self.cwd.unwrap());
530
531 for _ in 0..states.len() {
532 self.cwds.push(self.cwd.unwrap());
533 }
534 self.cwd = None;
535 self.token_sources
536 .extend(states.drain(..).rev().map(TokenSource::Macro));
537 continue;
538 }
539
540 Some(Token::Directive {
541 loc,
542 name: DirectiveName::Hex,
543 }) => {
544 let mac = self.expect_number_directive_arg(
545 loc,
546 DirectiveName::Hex,
547 16,
548 )?;
549
550 self.token_sources.push(self.token_source.take().unwrap());
551 self.cwds.push(self.cwd.unwrap());
552
553 self.token_sources.push(TokenSource::Macro(mac));
554 self.cwds.push(self.cwd.take().unwrap());
555 continue;
556 }
557
558 Some(Token::Directive {
559 loc,
560 name: DirectiveName::Bin,
561 }) => {
562 let mac = self.expect_number_directive_arg(
563 loc,
564 DirectiveName::Bin,
565 2,
566 )?;
567
568 self.token_sources.push(self.token_source.take().unwrap());
569 self.cwds.push(self.cwd.unwrap());
570
571 self.token_sources.push(TokenSource::Macro(mac));
572 self.cwds.push(self.cwd.take().unwrap());
573 continue;
574 }
575
576 Some(Token::Directive {
577 loc,
578 name: DirectiveName::IsDef,
579 }) => {
580 let direct = match self.next()? {
581 None => return self.end_of_input_err(),
582
583 Some(Token::Label { loc, value, kind }) => match kind {
584 LabelKind::Global | LabelKind::Direct => value,
585
586 LabelKind::Local => {
587 if let Some(namespace) = self.active_namespace {
588 let global_label = {
589 let interner =
590 self.str_interner.as_ref().borrow();
591 let global =
592 interner.get(namespace).unwrap();
593 let label = interner.get(value).unwrap();
594 format!("{global}{label}")
595 };
596 self.str_interner
597 .borrow_mut()
598 .intern(global_label)
599 } else {
600 let interner =
601 self.str_interner.as_ref().borrow();
602 let label = interner.get(value).unwrap();
603 return asm_err!(loc, "The local symbol \"{label}\" is being read but there was no global label defined before it");
604 }
605 }
606 },
607
608 Some(tok) => {
609 return asm_err!(
610 tok.loc(),
611 "Unexpected {}, expected a label",
612 tok.as_display(&self.str_interner)
613 )
614 }
615 };
616 let value = if self.symtab.get(direct).is_some() {
617 1
618 } else {
619 0
620 };
621 self.stash = Some(Token::Number { loc, value });
622 self.loc = Some(loc);
623 continue;
624 }
625
626 _ => {}
627 }
628 }
629
630 self.stash = tok;
631 self.loc = Some(token_source.loc());
632 if self.stash.is_none() {
633 self.token_source = None;
634 self.cwd = None;
635 }
636 }
637 },
638 }
639 }
640 }
641
642 pub(crate) fn next(&mut self) -> Result<Option<Token<A>>, (SourceLoc, AssemblerError)> {
643 self.peek()?;
644 Ok(self.stash.take())
645 }
646
647 fn trace_error(&self, loc: SourceLoc, e: AssemblerError) -> AssemblerError {
648 let mut msg = String::new();
649 let fmt_msg = &mut msg as &mut dyn Write;
650
651 let path = self.file_manager.borrow().path(loc.pathref).unwrap();
652 writeln!(fmt_msg, "In \"{}\"", path.display()).unwrap();
653
654 if let Some(token_source) = self.token_source.as_ref() {
655 let mut included_from = token_source.included_from();
656 for token_source in self.token_sources.iter().rev() {
657 let loc = included_from.unwrap();
659 let path = self.file_manager.borrow().path(loc.pathref).unwrap();
660 writeln!(
661 fmt_msg,
662 "\tIncluded from {}:{}:{}",
663 path.display(),
664 loc.line,
665 if loc.column == 0 { 1 } else { loc.column }
666 )
667 .unwrap();
668 included_from = token_source.included_from();
669 }
670 }
671 writeln!(
672 fmt_msg,
673 "\n{}:{}:{}:",
674 path.file_name().unwrap().to_str().unwrap(),
675 loc.line,
676 if loc.column == 0 { 1 } else { loc.column }
677 )
678 .unwrap();
679 writeln!(fmt_msg, "{e}").unwrap();
680 AssemblerError(msg)
681 }
682
683 #[inline]
684 pub(crate) fn end_of_input_err<T>(&mut self) -> Result<T, (SourceLoc, AssemblerError)> {
685 asm_err!(self.loc(), "Unexpected end of input")
686 }
687
688 #[inline]
689 pub(crate) fn expect_symbol(
690 &mut self,
691 sym: SymbolName,
692 ) -> Result<(), (SourceLoc, AssemblerError)> {
693 match self.next()? {
694 Some(Token::Symbol { loc, name }) => {
695 if name != sym {
696 asm_err!(loc, "Unexpected symbol: \"{name}\", expected \"{sym}\"")
697 } else {
698 Ok(())
699 }
700 }
701 Some(tok) => asm_err!(
702 tok.loc(),
703 "Unexpected \"{}\", expected the symbol \"{sym}\"",
704 tok.as_display(&self.str_interner)
705 ),
706 None => self.end_of_input_err(),
707 }
708 }
709
710 #[inline]
711 pub(crate) fn expect_register(
712 &mut self,
713 reg: A::RegisterName,
714 ) -> Result<(), (SourceLoc, AssemblerError)> {
715 match self.next()? {
716 Some(Token::Register { loc, name }) => {
717 if name != reg {
718 asm_err!(
719 loc,
720 "Unexpected register: \"{name}\", expected the register \"{reg}\""
721 )
722 } else {
723 Ok(())
724 }
725 }
726 Some(tok) => asm_err!(
727 tok.loc(),
728 "Unexpected {}, expected the register \"{reg}\"",
729 tok.as_display(&self.str_interner)
730 ),
731 None => self.end_of_input_err(),
732 }
733 }
734
735 pub(crate) fn expect_immediate(&mut self) -> Result<(), (SourceLoc, AssemblerError)> {
736 let (loc, expr) = self.expr()?;
737 if let Some(value) = expr.evaluate(&self.symtab, &self.str_interner) {
738 if (value as u32) > (u8::MAX as u32) {
739 return asm_err!(loc, "Expression result ({value}) will not fit in a byte");
740 }
741 self.data.push(value as u8);
742 } else {
743 self.links.push(Link::byte(loc, self.data.len(), expr));
744 self.data.push(0);
745 }
746 Ok(())
747 }
748
749 pub(crate) fn expect_hmem_immediate(&mut self) -> Result<(), (SourceLoc, AssemblerError)> {
750 let (loc, expr) = self.expr()?;
751 if let Some(value) = expr.evaluate(&self.symtab, &self.str_interner) {
752 if (value as u32) > (u8::MAX as u32) {
753 if (value as u32) > (u16::MAX as u32) {
754 return asm_err!(loc, "Expression result ({value}) will not fit in a word");
755 }
756 if !(0xFF00..=0xFFFF).contains(&value) {
757 return asm_err!(
758 loc,
759 "Expression result ({value}) must be between $FF00 and $FFFF"
760 );
761 }
762 }
763 self.data.push(value as u8);
764 } else {
765 self.links.push(Link::byte(loc, self.data.len(), expr));
766 self.data.push(0);
767 }
768 Ok(())
769 }
770
771 pub(crate) fn expect_wide_immediate(&mut self) -> Result<(), (SourceLoc, AssemblerError)> {
772 let (loc, expr) = self.expr()?;
773 if let Some(value) = expr.evaluate(&self.symtab, &self.str_interner) {
774 if (value as u32) > (u16::MAX as u32) {
775 return asm_err!(loc, "Expression result ({value}) will not fit in a word");
776 }
777 self.data.extend_from_slice(&(value as u16).to_le_bytes());
778 } else {
779 self.links.push(Link::word(loc, self.data.len(), expr));
780 self.data.push(0);
781 self.data.push(0);
782 }
783 Ok(())
784 }
785
786 pub(crate) fn expect_branch_immediate(&mut self) -> Result<(), (SourceLoc, AssemblerError)> {
787 let (loc, mut expr) = self.expr()?;
788 expr.push(ExprNode::Value(self.here.wrapping_add(2) as i32)); expr.push(ExprNode::Sub);
790 if let Some(value) = expr.evaluate(&self.symtab, &self.str_interner) {
791 if (value < (i8::MIN as i32)) || (value > (i8::MAX as i32)) {
792 return asm_err!(loc, "Branch distance ({value}) will not fit in a byte");
793 }
794 self.data.push(value as u8);
795 } else {
796 self.links
797 .push(Link::signed_byte(loc, self.data.len(), expr));
798 self.data.push(0);
799 }
800 Ok(())
801 }
802
803 fn expect_macro_invoke(
804 &mut self,
805 name: StrRef,
806 ) -> Result<MacroState<A>, (SourceLoc, AssemblerError)> {
807 let mut args = Vec::new();
808 let arg_count = self.macros.get(&name).unwrap().args.len();
809 let loc = self.loc();
810
811 for i in 0..arg_count {
812 let mut toks = Vec::new();
813
814 let mut brace_depth = 0;
815 loop {
816 match self.next()? {
817 None => return self.end_of_input_err(),
818
819 Some(Token::NewLine { .. } | Token::Comment { .. }) => {}
820
821 Some(
822 tok @ Token::Symbol {
823 name: SymbolName::BraceOpen,
824 ..
825 },
826 ) => {
827 if brace_depth > 0 {
828 toks.push(tok);
829 }
830 brace_depth += 1;
831 }
832
833 Some(
834 tok @ Token::Symbol {
835 name: SymbolName::BraceClose,
836 ..
837 },
838 ) => {
839 brace_depth -= 1;
840 if brace_depth == 0 {
841 break;
842 }
843 toks.push(tok);
844 }
845
846 Some(tok) => {
847 toks.push(tok);
848 if brace_depth == 0 {
849 break;
850 }
851 }
852 }
853 }
854 args.push(toks);
855 if i < arg_count - 1 {
856 self.expect_symbol(SymbolName::Comma)?;
857 }
858 }
859
860 let entropy = self
861 .str_interner
862 .borrow_mut()
863 .intern(format!("__{}", self.entropy));
864 self.entropy += 1;
865 Ok(MacroState {
866 name,
867 args,
868 macro_offset: 0,
869 expanding_macro_arg: None,
870 macro_arg_offset: 0,
871 loc,
872 included_from: Some(loc),
873 entropy,
874 })
875 }
876
877 fn expect_string_directive_arg(
878 &mut self,
879 loc: SourceLoc,
880 ) -> Result<Token<A>, (SourceLoc, AssemblerError)> {
881 let mut string = String::new();
882 let mut brace_depth = 0;
883 loop {
884 match self.next()? {
885 None => return self.end_of_input_err(),
886
887 Some(Token::NewLine { .. } | Token::Comment { .. }) => {}
888
889 Some(Token::Symbol {
890 name: SymbolName::BraceOpen,
891 ..
892 }) => {
893 if brace_depth > 0 {
894 string.push('{');
895 }
896 brace_depth += 1;
897 }
898
899 Some(Token::Symbol {
900 name: SymbolName::BraceClose,
901 ..
902 }) => {
903 brace_depth -= 1;
904 if brace_depth == 0 {
905 break;
906 }
907 string.push('}');
908 }
909
910 Some(Token::String { value, .. }) => {
911 let interner = self.str_interner.as_ref().borrow();
912 let value = interner.get(value).unwrap();
913 string.push_str(value);
914 }
915
916 Some(Token::Label { value, .. }) => {
917 let interner = self.str_interner.as_ref().borrow();
918 let value = interner.get(value).unwrap();
919 string.push_str(value);
920 }
921
922 Some(Token::Number { value, .. }) => {
923 write!(string, "{value:x}").unwrap();
924 }
925
926 Some(Token::Operation { name, .. }) => {
927 write!(string, "{name}").unwrap();
928 }
929
930 Some(Token::Register { name, .. }) => {
931 write!(string, "{name}").unwrap();
932 }
933
934 Some(Token::Symbol { name, .. }) => {
935 write!(string, "{name}").unwrap();
936 }
937
938 Some(tok) => {
939 return asm_err!(
940 tok.loc(),
941 "Cannot stringify token: {}",
942 tok.as_display(&self.str_interner)
943 );
944 }
945 }
946 if brace_depth == 0 {
947 break;
948 }
949 }
950 let value = self.str_interner.borrow_mut().intern(&string);
951 Ok(Token::String { loc, value })
952 }
953
954 fn expect_number_directive_arg(
955 &mut self,
956 loc: SourceLoc,
957 directive_name: DirectiveName,
958 base: u32,
959 ) -> Result<MacroState<A>, (SourceLoc, AssemblerError)> {
960 let value = match self.const_expr()? {
961 (_, Some(value)) => {
962 value
963 }
964 (loc, None) => {
965 return asm_err!(
966 loc,
967 "The expression following an \"{directive_name}\" directive must be immediately solvable"
968 )
969 }
970 };
971
972 let mut interner = self.str_interner.borrow_mut();
973 let name = interner.intern(format!("{directive_name} Invocation{}", self.entropy));
974 let entropy = interner.intern(format!("__{}", self.entropy));
975 self.entropy += 1;
976 let value = match base {
977 2 => interner.intern(format!("{value:b}")),
978 16 => interner.intern(format!("{value:x}")),
979 _ => unreachable!(),
980 };
981 let mut toks = Vec::new();
982 toks.push(MacroToken::Token(Token::String { loc, value }));
983
984 if let Some(tok) = self.stash.take() {
990 toks.push(MacroToken::Token(tok));
991 }
992
993 self.macros.insert(
994 name,
995 Macro {
996 args: Vec::new(),
997 tokens: toks,
998 },
999 );
1000
1001 Ok(MacroState {
1002 name,
1003 args: Vec::new(),
1004 macro_offset: 0,
1005 expanding_macro_arg: None,
1006 macro_arg_offset: 0,
1007 loc,
1008 included_from: Some(loc),
1009 entropy,
1010 })
1011 }
1012
1013 fn expect_count_directive(
1014 &mut self,
1015 loc: SourceLoc,
1016 ) -> Result<MacroState<A>, (SourceLoc, AssemblerError)> {
1017 let count = match self.const_expr()? {
1018 (loc, Some(value)) => {
1019 if value < 0 {
1020 return asm_err!(
1021 loc,
1022 "\"@count\" expression result ({value}) must be positive"
1023 );
1024 }
1025 value as usize
1026 }
1027 (loc, None) => {
1028 return asm_err!(
1029 loc,
1030 "The expression following an \"@count\" directive must be immediately solvable"
1031 )
1032 }
1033 };
1034
1035 let (name, entropy) = {
1036 let mut interner = self.str_interner.borrow_mut();
1037 let name = interner.intern(format!("@count Invocation{}", self.entropy));
1038 let entropy = interner.intern(format!("__{}", self.entropy));
1039 (name, entropy)
1040 };
1041 self.entropy += 1;
1042 let mut toks = Vec::new();
1043 for i in 0..count {
1044 toks.push(MacroToken::Token(Token::Number {
1045 loc,
1046 value: i as u32,
1047 }));
1048 }
1049
1050 if let Some(tok) = self.stash.take() {
1056 toks.push(MacroToken::Token(tok));
1057 }
1058
1059 self.macros.insert(
1060 name,
1061 Macro {
1062 args: Vec::new(),
1063 tokens: toks,
1064 },
1065 );
1066
1067 Ok(MacroState {
1068 name,
1069 args: Vec::new(),
1070 macro_offset: 0,
1071 expanding_macro_arg: None,
1072 macro_arg_offset: 0,
1073 loc,
1074 included_from: Some(loc),
1075 entropy,
1076 })
1077 }
1078
1079 fn expect_label_directive_arg(
1080 &mut self,
1081 loc: SourceLoc,
1082 ) -> Result<Token<A>, (SourceLoc, AssemblerError)> {
1083 let mut string = String::new();
1084 let mut brace_depth = 0;
1085 loop {
1086 match self.next()? {
1087 None => return self.end_of_input_err(),
1088
1089 Some(Token::NewLine { .. } | Token::Comment { .. }) => {}
1090
1091 Some(Token::Symbol {
1092 name: SymbolName::BraceOpen,
1093 ..
1094 }) => {
1095 if brace_depth > 0 {
1096 string.push('{');
1097 }
1098 brace_depth += 1;
1099 }
1100
1101 Some(Token::Symbol {
1102 name: SymbolName::BraceClose,
1103 ..
1104 }) => {
1105 brace_depth -= 1;
1106 if brace_depth == 0 {
1107 break;
1108 }
1109 string.push('}');
1110 }
1111
1112 Some(Token::String { value, .. }) => {
1113 let interner = self.str_interner.as_ref().borrow();
1114 let value = interner.get(value).unwrap();
1115 string.push_str(value);
1116 }
1117
1118 Some(Token::Label { value, .. }) => {
1119 let interner = self.str_interner.as_ref().borrow();
1120 let value = interner.get(value).unwrap();
1121 string.push_str(value);
1122 }
1123
1124 Some(Token::Number { value, .. }) => {
1125 write!(string, "{value:x}").unwrap();
1126 }
1127
1128 Some(Token::Operation { name, .. }) => {
1129 write!(string, "{name}").unwrap();
1130 }
1131
1132 Some(Token::Register { name, .. }) => {
1133 write!(string, "{name}").unwrap();
1134 }
1135
1136 Some(Token::Symbol { name, .. }) => {
1137 write!(string, "{name}").unwrap();
1138 }
1139
1140 Some(tok) => {
1141 return asm_err!(
1142 tok.loc(),
1143 "Cannot labelify token: {}",
1144 tok.as_display(&self.str_interner)
1145 );
1146 }
1147 }
1148 if brace_depth == 0 {
1149 break;
1150 }
1151 }
1152 if string.split_whitespace().count() > 1 {
1153 return asm_err!(loc, "Malformed label: \"{string}\"");
1154 }
1155 let value = self.str_interner.borrow_mut().intern(&string);
1156 match string.chars().filter(|c| *c == '.').count() {
1157 0 => Ok(Token::Label {
1158 loc,
1159 kind: LabelKind::Global,
1160 value,
1161 }),
1162 1 => {
1163 if string.starts_with('.') {
1164 Ok(Token::Label {
1165 loc,
1166 kind: LabelKind::Local,
1167 value,
1168 })
1169 } else {
1170 Ok(Token::Label {
1171 loc,
1172 kind: LabelKind::Direct,
1173 value,
1174 })
1175 }
1176 }
1177 _ => asm_err!(loc, "Malformed label: \"{string}\""),
1178 }
1179 }
1180
1181 fn expect_each_directive(
1182 &mut self,
1183 loc: SourceLoc,
1184 ) -> Result<Vec<MacroState<A>>, (SourceLoc, AssemblerError)> {
1185 let arg_value = match self.next()? {
1186 None => return self.end_of_input_err(),
1187
1188 Some(Token::Label { loc, kind, value }) => {
1189 let interner = self.str_interner.as_ref().borrow();
1190 let str_value = interner.get(value).unwrap();
1191 if kind != LabelKind::Global {
1192 return asm_err!(
1193 loc,
1194 "\"@each\" label \"{str_value}\" must be a global label",
1195 );
1196 }
1197 value
1198 }
1199
1200 Some(tok) => {
1201 return asm_err!(
1202 tok.loc(),
1203 "Unexpected {}, expected an \"@each\" token placeholder name",
1204 tok.as_display(&self.str_interner)
1205 );
1206 }
1207 };
1208
1209 self.expect_symbol(SymbolName::Comma)?;
1210
1211 let mut args = Vec::new();
1212 let mut brace_depth = 0;
1213 loop {
1214 match self.next()? {
1215 None => return self.end_of_input_err(),
1216
1217 Some(Token::NewLine { .. } | Token::Comment { .. }) => {}
1218
1219 Some(
1220 tok @ Token::Symbol {
1221 name: SymbolName::BraceOpen,
1222 ..
1223 },
1224 ) => {
1225 if brace_depth > 0 {
1226 args.push(tok);
1227 }
1228 brace_depth += 1;
1229 }
1230
1231 Some(
1232 tok @ Token::Symbol {
1233 name: SymbolName::BraceClose,
1234 ..
1235 },
1236 ) => {
1237 brace_depth -= 1;
1238 if brace_depth == 0 {
1239 break;
1240 }
1241 args.push(tok);
1242 }
1243
1244 Some(tok) => {
1245 args.push(tok);
1246 }
1247 }
1248 if brace_depth == 0 {
1249 break;
1250 }
1251 }
1252
1253 let (name, entropy) = {
1254 let mut interner = self.str_interner.borrow_mut();
1255 let name = interner.intern(format!("@each Invocation{}", self.entropy));
1256 let entropy = interner.intern(format!("__{}", self.entropy));
1257 (name, entropy)
1258 };
1259 self.entropy += 1;
1260 let mut toks = Vec::new();
1261 loop {
1262 match self.next()? {
1263 None => return self.end_of_input_err(),
1264
1265 Some(Token::Directive {
1266 name: DirectiveName::EndEach,
1267 ..
1268 }) => {
1269 break;
1270 }
1271
1272 Some(Token::Directive {
1273 loc,
1274 name: DirectiveName::Entropy,
1275 }) => {
1276 toks.push(MacroToken::Entropy { loc });
1277 }
1278
1279 Some(Token::Label { kind, value, .. })
1280 if kind == LabelKind::Global && value == arg_value =>
1281 {
1282 toks.push(MacroToken::Argument { index: 0 });
1283 }
1284
1285 Some(tok) => {
1286 toks.push(MacroToken::Token(tok));
1287 }
1288 }
1289 }
1290
1291 self.macros.insert(
1292 name,
1293 Macro {
1294 args: vec![arg_value], tokens: toks,
1296 },
1297 );
1298
1299 let mut states = Vec::new();
1300 for arg in args {
1301 states.push(MacroState {
1302 name,
1303 args: vec![vec![arg]],
1304 macro_offset: 0,
1305 expanding_macro_arg: None,
1306 macro_arg_offset: 0,
1307 loc,
1308 included_from: Some(loc),
1309 entropy,
1310 });
1311 }
1312 Ok(states)
1313 }
1314
1315 pub(crate) fn const_expr(
1316 &mut self,
1317 ) -> Result<(SourceLoc, Option<i32>), (SourceLoc, AssemblerError)> {
1318 self.expr()
1319 .map(|(loc, expr)| (loc, expr.evaluate(&self.symtab, &self.str_interner)))
1320 }
1321
1322 pub(crate) fn expr(&mut self) -> Result<(SourceLoc, Expr), (SourceLoc, AssemblerError)> {
1323 let mut nodes = Vec::new();
1324 let loc = self.expr_prec_0(&mut nodes)?;
1325 Ok((loc, Expr::new(nodes)))
1326 }
1327
1328 fn expr_prec_0(
1329 &mut self,
1330 nodes: &mut Vec<ExprNode>,
1331 ) -> Result<SourceLoc, (SourceLoc, AssemblerError)> {
1332 let loc = self.expr_prec_1(nodes)?;
1333
1334 loop {
1335 match self.peek()? {
1336 Some(Token::Symbol {
1337 name: SymbolName::Question,
1338 ..
1339 }) => {
1340 self.next()?;
1341 self.expr_prec_1(nodes)?;
1342 if self.peeked_symbol(SymbolName::Colon)?.is_none() {
1343 return asm_err!(self.loc(), "Expected a \":\" in ternary expression");
1344 }
1345 self.next()?;
1346 self.expr_prec_1(nodes)?;
1347 nodes.push(ExprNode::Ternary);
1348 return Ok(loc);
1349 }
1350
1351 _ => return Ok(loc),
1352 }
1353 }
1354 }
1355
1356 fn expr_prec_1(
1357 &mut self,
1358 nodes: &mut Vec<ExprNode>,
1359 ) -> Result<SourceLoc, (SourceLoc, AssemblerError)> {
1360 let loc = self.expr_prec_2(nodes)?;
1361
1362 loop {
1363 match self.peek()? {
1364 Some(Token::Symbol {
1365 name: SymbolName::DoublePipe,
1366 ..
1367 }) => {
1368 self.next()?;
1369 self.expr_prec_2(nodes)?;
1370 nodes.push(ExprNode::OrLogical);
1371 }
1372 _ => return Ok(loc),
1373 }
1374 }
1375 }
1376
1377 fn expr_prec_2(
1378 &mut self,
1379 nodes: &mut Vec<ExprNode>,
1380 ) -> Result<SourceLoc, (SourceLoc, AssemblerError)> {
1381 let loc = self.expr_prec_3(nodes)?;
1382
1383 loop {
1384 match self.peek()? {
1385 Some(Token::Symbol {
1386 name: SymbolName::DoubleAmpersand,
1387 ..
1388 }) => {
1389 self.next()?;
1390 self.expr_prec_3(nodes)?;
1391 nodes.push(ExprNode::AndLogical);
1392 }
1393 _ => return Ok(loc),
1394 }
1395 }
1396 }
1397
1398 fn expr_prec_3(
1399 &mut self,
1400 nodes: &mut Vec<ExprNode>,
1401 ) -> Result<SourceLoc, (SourceLoc, AssemblerError)> {
1402 let loc = self.expr_prec_4(nodes)?;
1403
1404 loop {
1405 match self.peek()? {
1406 Some(Token::Symbol {
1407 name: SymbolName::Pipe,
1408 ..
1409 }) => {
1410 self.next()?;
1411 self.expr_prec_4(nodes)?;
1412 nodes.push(ExprNode::Or);
1413 }
1414 _ => return Ok(loc),
1415 }
1416 }
1417 }
1418
1419 fn expr_prec_4(
1420 &mut self,
1421 nodes: &mut Vec<ExprNode>,
1422 ) -> Result<SourceLoc, (SourceLoc, AssemblerError)> {
1423 let loc = self.expr_prec_5(nodes)?;
1424
1425 loop {
1426 match self.peek()? {
1427 Some(Token::Symbol {
1428 name: SymbolName::Caret,
1429 ..
1430 }) => {
1431 self.next()?;
1432 self.expr_prec_5(nodes)?;
1433 nodes.push(ExprNode::Xor);
1434 }
1435 _ => return Ok(loc),
1436 }
1437 }
1438 }
1439
1440 fn expr_prec_5(
1441 &mut self,
1442 nodes: &mut Vec<ExprNode>,
1443 ) -> Result<SourceLoc, (SourceLoc, AssemblerError)> {
1444 let loc = self.expr_prec_6(nodes)?;
1445
1446 loop {
1447 match self.peek()? {
1448 Some(Token::Symbol {
1449 name: SymbolName::Ampersand,
1450 ..
1451 }) => {
1452 self.next()?;
1453 self.expr_prec_6(nodes)?;
1454 nodes.push(ExprNode::And);
1455 }
1456 _ => return Ok(loc),
1457 }
1458 }
1459 }
1460
1461 fn expr_prec_6(
1462 &mut self,
1463 nodes: &mut Vec<ExprNode>,
1464 ) -> Result<SourceLoc, (SourceLoc, AssemblerError)> {
1465 let loc = self.expr_prec_7(nodes)?;
1466
1467 loop {
1468 match self.peek()? {
1469 Some(Token::Symbol {
1470 name: SymbolName::Equal,
1471 ..
1472 }) => {
1473 self.next()?;
1474 self.expr_prec_7(nodes)?;
1475 nodes.push(ExprNode::Equal);
1476 }
1477 Some(Token::Symbol {
1478 name: SymbolName::NotEqual,
1479 ..
1480 }) => {
1481 self.next()?;
1482 self.expr_prec_7(nodes)?;
1483 nodes.push(ExprNode::NotEqual);
1484 }
1485 _ => return Ok(loc),
1486 }
1487 }
1488 }
1489
1490 fn expr_prec_7(
1491 &mut self,
1492 nodes: &mut Vec<ExprNode>,
1493 ) -> Result<SourceLoc, (SourceLoc, AssemblerError)> {
1494 let loc = self.expr_prec_8(nodes)?;
1495
1496 loop {
1497 match self.peek()? {
1498 Some(Token::Symbol {
1499 name: SymbolName::LessThan,
1500 ..
1501 }) => {
1502 self.next()?;
1503 self.expr_prec_8(nodes)?;
1504 nodes.push(ExprNode::LessThan);
1505 }
1506 Some(Token::Symbol {
1507 name: SymbolName::LessEqual,
1508 ..
1509 }) => {
1510 self.next()?;
1511 self.expr_prec_8(nodes)?;
1512 nodes.push(ExprNode::LessThanEqual);
1513 }
1514 Some(Token::Symbol {
1515 name: SymbolName::GreaterThan,
1516 ..
1517 }) => {
1518 self.next()?;
1519 self.expr_prec_8(nodes)?;
1520 nodes.push(ExprNode::GreaterThan);
1521 }
1522 Some(Token::Symbol {
1523 name: SymbolName::GreaterEqual,
1524 ..
1525 }) => {
1526 self.next()?;
1527 self.expr_prec_8(nodes)?;
1528 nodes.push(ExprNode::GreaterThanEqual);
1529 }
1530 _ => return Ok(loc),
1531 }
1532 }
1533 }
1534
1535 fn expr_prec_8(
1536 &mut self,
1537 nodes: &mut Vec<ExprNode>,
1538 ) -> Result<SourceLoc, (SourceLoc, AssemblerError)> {
1539 let loc = self.expr_prec_9(nodes)?;
1540
1541 loop {
1542 match self.peek()? {
1543 Some(Token::Symbol {
1544 name: SymbolName::ShiftLeft,
1545 ..
1546 }) => {
1547 self.next()?;
1548 self.expr_prec_9(nodes)?;
1549 nodes.push(ExprNode::ShiftLeft);
1550 }
1551 Some(Token::Symbol {
1552 name: SymbolName::ShiftLeftLogical,
1553 ..
1554 }) => {
1555 self.next()?;
1556 self.expr_prec_9(nodes)?;
1557 nodes.push(ExprNode::ShiftLeftLogical);
1558 }
1559 Some(Token::Symbol {
1560 name: SymbolName::ShiftRight,
1561 ..
1562 }) => {
1563 self.next()?;
1564 self.expr_prec_9(nodes)?;
1565 nodes.push(ExprNode::ShiftRight);
1566 }
1567 Some(Token::Symbol {
1568 name: SymbolName::ShiftRightLogical,
1569 ..
1570 }) => {
1571 self.next()?;
1572 self.expr_prec_9(nodes)?;
1573 nodes.push(ExprNode::ShiftRightLogical);
1574 }
1575 _ => return Ok(loc),
1576 }
1577 }
1578 }
1579
1580 fn expr_prec_9(
1581 &mut self,
1582 nodes: &mut Vec<ExprNode>,
1583 ) -> Result<SourceLoc, (SourceLoc, AssemblerError)> {
1584 let loc = self.expr_prec_10(nodes)?;
1585
1586 loop {
1587 match self.peek()? {
1588 Some(Token::Symbol {
1589 name: SymbolName::Plus,
1590 ..
1591 }) => {
1592 self.next()?;
1593 self.expr_prec_10(nodes)?;
1594 nodes.push(ExprNode::Add);
1595 }
1596 Some(Token::Symbol {
1597 name: SymbolName::Minus,
1598 ..
1599 }) => {
1600 self.next()?;
1601 self.expr_prec_10(nodes)?;
1602 nodes.push(ExprNode::Sub);
1603 }
1604 _ => return Ok(loc),
1605 }
1606 }
1607 }
1608
1609 fn expr_prec_10(
1610 &mut self,
1611 nodes: &mut Vec<ExprNode>,
1612 ) -> Result<SourceLoc, (SourceLoc, AssemblerError)> {
1613 let loc = self.expr_prec_11(nodes)?;
1614
1615 loop {
1616 match self.peek()? {
1617 Some(Token::Symbol {
1618 name: SymbolName::Star,
1619 ..
1620 }) => {
1621 self.next()?;
1622 self.expr_prec_11(nodes)?;
1623 nodes.push(ExprNode::Mul);
1624 }
1625 Some(Token::Symbol {
1626 name: SymbolName::Div,
1627 ..
1628 }) => {
1629 self.next()?;
1630 self.expr_prec_11(nodes)?;
1631 nodes.push(ExprNode::Div);
1632 }
1633 Some(Token::Symbol {
1634 name: SymbolName::Mod,
1635 ..
1636 }) => {
1637 self.next()?;
1638 self.expr_prec_11(nodes)?;
1639 nodes.push(ExprNode::Rem);
1640 }
1641 _ => return Ok(loc),
1642 }
1643 }
1644 }
1645
1646 fn expr_prec_11(
1647 &mut self,
1648 nodes: &mut Vec<ExprNode>,
1649 ) -> Result<SourceLoc, (SourceLoc, AssemblerError)> {
1650 loop {
1651 match self.peek()? {
1652 None => return self.end_of_input_err(),
1653 Some(Token::Symbol {
1654 loc,
1655 name: SymbolName::Minus,
1656 }) => {
1657 self.next()?;
1658 self.expr_prec_11(nodes)?;
1659 nodes.push(ExprNode::Neg);
1660 return Ok(loc);
1661 }
1662 Some(Token::Symbol {
1663 loc,
1664 name: SymbolName::Plus,
1665 }) => {
1666 self.next()?;
1667 self.expr_prec_11(nodes)?;
1668 return Ok(loc);
1669 }
1670 Some(Token::Symbol {
1671 loc,
1672 name: SymbolName::Bang,
1673 }) => {
1674 self.next()?;
1675 self.expr_prec_11(nodes)?;
1676 nodes.push(ExprNode::NotLogical);
1677 return Ok(loc);
1678 }
1679 Some(Token::Symbol {
1680 loc,
1681 name: SymbolName::Tilde,
1682 }) => {
1683 self.next()?;
1684 self.expr_prec_11(nodes)?;
1685 nodes.push(ExprNode::Invert);
1686 return Ok(loc);
1687 }
1688 Some(Token::Symbol {
1689 loc,
1690 name: SymbolName::LessThan,
1691 }) => {
1692 self.next()?;
1693 self.expr_prec_11(nodes)?;
1694 nodes.push(ExprNode::Lo);
1695 return Ok(loc);
1696 }
1697 Some(Token::Symbol {
1698 loc,
1699 name: SymbolName::GreaterThan,
1700 }) => {
1701 self.next()?;
1702 self.expr_prec_11(nodes)?;
1703 nodes.push(ExprNode::Hi);
1704 return Ok(loc);
1705 }
1706 Some(Token::Symbol {
1707 loc,
1708 name: SymbolName::ParenOpen,
1709 }) => {
1710 self.next()?;
1711 self.expr_prec_0(nodes)?;
1712 if self.peeked_symbol(SymbolName::ParenClose)?.is_none() {
1713 return asm_err!(self.loc(), "Expected a \")\" to close expression");
1714 }
1715 self.next()?;
1716 return Ok(loc);
1717 }
1718 Some(Token::Number { loc, value }) => {
1719 self.next()?;
1720 nodes.push(ExprNode::Value(value as i32));
1721 return Ok(loc);
1722 }
1723 Some(Token::Directive { loc, name }) => match name {
1724 DirectiveName::Here => {
1725 self.next()?;
1726 nodes.push(ExprNode::Value(self.here as i32));
1727 return Ok(loc);
1728 }
1729
1730 DirectiveName::SizeOf => {
1731 self.next()?;
1732 match self.next()? {
1733 None => return self.end_of_input_err(),
1734
1735 Some(Token::Label { loc, kind, value }) => {
1736 let direct = match kind {
1737 LabelKind::Global | LabelKind::Direct => value,
1738
1739 LabelKind::Local => {
1740 if let Some(namespace) = self.active_namespace {
1741 let direct_label = {
1742 let interner = self.str_interner.as_ref().borrow();
1743 let label = interner.get(value).unwrap();
1744 let global = interner.get(namespace).unwrap();
1745 format!("{global}{label}")
1746 };
1747 self.str_interner.borrow_mut().intern(direct_label)
1748 } else {
1749 let interner = self.str_interner.as_ref().borrow();
1750 let label = interner.get(value).unwrap();
1751 return asm_err!(loc, "The local label \"{label}\" is being evaluated but there was no global label defined before it");
1752 }
1753 }
1754 };
1755
1756 nodes.push(ExprNode::SizeOf(direct));
1757 self.symtab.touch(direct, loc);
1760 return Ok(loc);
1761 }
1762
1763 Some(tok) => {
1764 return asm_err!(
1765 tok.loc(),
1766 "Unexpected {}, expected a struct field label",
1767 tok.as_display(&self.str_interner)
1768 )
1769 }
1770 }
1771 }
1772
1773 _ => {
1774 return asm_err!(
1775 loc,
1776 "\"{name}\" directives are not allowed in expressions"
1777 )
1778 }
1779 },
1780 Some(Token::Label { loc, kind, value }) => {
1781 self.next()?;
1782 let direct = match kind {
1783 LabelKind::Global | LabelKind::Direct => value,
1784
1785 LabelKind::Local => {
1786 if let Some(namespace) = self.active_namespace {
1787 let direct_label = {
1788 let interner = self.str_interner.as_ref().borrow();
1789 let label = interner.get(value).unwrap();
1790 let global = interner.get(namespace).unwrap();
1791 format!("{global}{label}")
1792 };
1793 self.str_interner.borrow_mut().intern(direct_label)
1794 } else {
1795 let interner = self.str_interner.as_ref().borrow();
1796 let label = interner.get(value).unwrap();
1797 return asm_err!(loc, "The local label \"{label}\" is being evaluated but there was no global label defined before it");
1798 }
1799 }
1800 };
1801
1802 if let Some(sym) = self.symtab.get(direct) {
1803 match sym.inner() {
1804 Symbol::Value(value) => {
1805 nodes.push(ExprNode::Value(*value));
1806 }
1807 Symbol::Expr(expr) => {
1808 if let Some(value) = expr.evaluate(&self.symtab, &self.str_interner)
1809 {
1810 nodes.push(ExprNode::Value(value));
1811 } else {
1812 nodes.push(ExprNode::Label(direct));
1813 }
1814 }
1815 }
1816 } else {
1817 nodes.push(ExprNode::Label(direct));
1818 }
1819 self.symtab.touch(direct, loc);
1822 return Ok(loc);
1823 }
1824 Some(tok) => {
1825 return asm_err!(
1826 tok.loc(),
1827 "Unexpected {} in expression",
1828 tok.as_display(&self.str_interner)
1829 )
1830 }
1831 }
1832 }
1833 }
1834
1835 #[inline]
1836 pub(crate) fn peeked_symbol(
1837 &mut self,
1838 sym: SymbolName,
1839 ) -> Result<Option<Token<A>>, (SourceLoc, AssemblerError)> {
1840 match self.peek()? {
1841 Some(tok @ Token::Symbol { name, .. }) if name == sym => Ok(Some(tok)),
1842 _ => Ok(None),
1843 }
1844 }
1845
1846 fn parse_all(&mut self) -> Result<(), (SourceLoc, AssemblerError)> {
1847 loop {
1848 match self.peek()? {
1849 None => return Ok(()),
1850
1851 Some(Token::NewLine { .. } | Token::Comment { .. }) => {
1853 self.next()?;
1854 }
1855
1856 Some(Token::Label { loc, value, kind }) => {
1857 let direct = match kind {
1858 LabelKind::Global => {
1859 self.active_namespace = Some(value);
1860 value
1861 }
1862
1863 LabelKind::Direct => value,
1864
1865 LabelKind::Local => {
1866 if let Some(namespace) = self.active_namespace {
1867 let direct_label = {
1868 let interner = self.str_interner.as_ref().borrow();
1869 let label = interner.get(value).unwrap();
1870 let global = interner.get(namespace).unwrap();
1871 format!("{global}{label}")
1872 };
1873 self.str_interner.borrow_mut().intern(direct_label)
1874 } else {
1875 let interner = self.str_interner.as_ref().borrow();
1876 let label = interner.get(value).unwrap();
1877 return asm_err!(loc, "The local label \"{label}\" is being defined but there was no global label defined before it");
1878 }
1879 }
1880 };
1881
1882 if self.symtab.get(direct).is_some() {
1883 let interner = self.str_interner.as_ref().borrow();
1884 let label = interner.get(direct).unwrap();
1885 return asm_err!(loc, "The label \"{label}\" was already defined");
1886 }
1887 self.symtab.insert(direct, Symbol::Value(self.here as i32));
1888 self.next()?;
1889
1890 if self.peeked_symbol(SymbolName::Colon)?.is_some() {
1891 self.next()?;
1892 }
1893 }
1894
1895 Some(tok @ Token::Directive { loc, name }) => {
1896 match name {
1897 DirectiveName::Org => {
1898 self.next()?;
1899
1900 self.here = match self.const_expr()? {
1901 (loc, Some(value)) => {
1902 if (value as u32) > (u16::MAX as u32) {
1903 return asm_err!(loc, "\"@org\" expression result ({value}) is not a valid address");
1904 }
1905 value as u32
1906 },
1907 (loc, None) => return asm_err!(loc, "The expression following an \"@org\" directive must be immediately solvable"),
1908 };
1909 }
1910
1911 DirectiveName::Echo => {
1912 self.next()?;
1913
1914 match self.peek()? {
1915 Some(Token::String { value, .. }) => {
1916 self.next()?;
1917 let interner = self.str_interner.as_ref().borrow();
1918 let value = interner.get(value).unwrap();
1919 eprintln!("{value}");
1920 }
1921
1922 Some(_) => {
1923 match self.const_expr()? {
1924 (_, Some(value)) => {
1925 eprintln!("{value}");
1926 },
1927 (loc, None) => return asm_err!(loc, "An expression following an \"@echo\" directive must be immediately solvable"),
1928 }
1929 }
1930
1931 None => return self.end_of_input_err()
1932 }
1933 }
1934
1935 DirectiveName::Die => {
1936 self.next()?;
1937
1938 match self.peek()? {
1939 None => return self.end_of_input_err(),
1940
1941 Some(Token::String { value, .. }) => {
1942 self.next()?;
1943 let interner = self.str_interner.as_ref().borrow();
1944 let value = interner.get(value).unwrap();
1945 return asm_err!(loc, "{value}");
1946 }
1947
1948 Some(_) => {
1949 match self.const_expr()? {
1950 (_, Some(value)) => return asm_err!(loc, "{value}"),
1951 (loc, None) => return asm_err!(loc, "An expression following an \"@die\" directive must be immediately solvable"),
1952 }
1953 }
1954 }
1955 }
1956
1957 DirectiveName::Assert => {
1958 self.next()?;
1959
1960 let (loc, expr) = self.expr()?;
1961 let msg = if self.peeked_symbol(SymbolName::Comma)?.is_some() {
1962 self.next()?;
1963 match self.next()? {
1964 None => return self.end_of_input_err(),
1965 Some(Token::String { value, .. }) => Some(value),
1966 Some(tok) => {
1967 return asm_err!(
1968 tok.loc(),
1969 "Unexpected {}, expected a string",
1970 tok.as_display(&self.str_interner)
1971 );
1972 }
1973 }
1974 } else {
1975 None
1976 };
1977
1978 if let Some(value) = expr.evaluate(&self.symtab, &self.str_interner) {
1979 if value == 0 {
1980 if let Some(msg) = msg {
1981 let interner = self.str_interner.as_ref().borrow();
1982 let msg = interner.get(msg).unwrap();
1983 return asm_err!(loc, "Assertion failed: {msg}",);
1984 } else {
1985 return asm_err!(loc, "Assertion failed");
1986 }
1987 }
1988 } else {
1989 self.links.push(Link::assert(loc, msg, expr));
1990 }
1991 }
1992
1993 DirectiveName::Defl => {
1994 self.next()?;
1995
1996 let (direct, loc) = match self.peek()? {
1997 None => return self.end_of_input_err(),
1998
1999 Some(Token::Label { loc, value, kind }) => match kind {
2000 LabelKind::Global | LabelKind::Direct => (value, loc),
2001
2002 LabelKind::Local => {
2003 if let Some(namespace) = self.active_namespace {
2004 let global_label = {
2005 let interner = self.str_interner.as_ref().borrow();
2006 let global = interner.get(namespace).unwrap();
2007 let label = interner.get(value).unwrap();
2008 format!("{global}{label}")
2009 };
2010 (
2011 self.str_interner.borrow_mut().intern(global_label),
2012 loc,
2013 )
2014 } else {
2015 let interner = self.str_interner.as_ref().borrow();
2016 let label = interner.get(value).unwrap();
2017 return asm_err!(loc, "The local label \"{label}\" is being defined but there was no global label defined before it");
2018 }
2019 }
2020 },
2021 Some(tok) => {
2022 return asm_err!(tok.loc(), "A label name is required")
2023 }
2024 };
2025 self.next()?;
2026
2027 if self.symtab.get(direct).is_some() {
2028 let interner = self.str_interner.as_ref().borrow();
2029 let label = interner.get(direct).unwrap();
2030 return asm_err!(loc, "The label \"{label}\" was already defined");
2031 }
2032
2033 self.expect_symbol(SymbolName::Comma)?;
2034 let (_, expr) = self.expr()?;
2035 self.symtab.insert(direct, Symbol::Expr(expr));
2036 }
2037
2038 DirectiveName::Defn => {
2039 self.next()?;
2040
2041 let (direct, loc) = match self.peek()? {
2042 None => return self.end_of_input_err(),
2043
2044 Some(Token::Label { loc, value, kind }) => match kind {
2045 LabelKind::Global | LabelKind::Direct => (value, loc),
2046
2047 LabelKind::Local => {
2048 if let Some(namespace) = self.active_namespace {
2049 let global_label = {
2050 let interner = self.str_interner.as_ref().borrow();
2051 let global = interner.get(namespace).unwrap();
2052 let label = interner.get(value).unwrap();
2053 format!("{global}{label}")
2054 };
2055 (
2056 self.str_interner.borrow_mut().intern(global_label),
2057 loc,
2058 )
2059 } else {
2060 let interner = self.str_interner.as_ref().borrow();
2061 let label = interner.get(value).unwrap();
2062 return asm_err!(loc, "The local constant \"{label}\" is being defined but there was no global label defined before it");
2063 }
2064 }
2065 },
2066 Some(tok) => {
2067 return asm_err!(tok.loc(), "A constant name is required")
2068 }
2069 };
2070 self.next()?;
2071
2072 if self.symtab.get(direct).is_some() {
2073 let interner = self.str_interner.as_ref().borrow();
2074 let label = interner.get(direct).unwrap();
2075 return asm_err!(
2076 loc,
2077 "The constant \"{label}\" was already defined"
2078 );
2079 }
2080
2081 self.expect_symbol(SymbolName::Comma)?;
2082 let (_, expr) = self.expr()?;
2083 self.symtab
2084 .insert_with_meta(direct, Symbol::Expr(expr), &[]);
2085 }
2086
2087 DirectiveName::ReDefl => {
2088 self.next()?;
2089
2090 let direct = match self.next()? {
2091 None => return self.end_of_input_err(),
2092
2093 Some(Token::Label { loc, value, kind }) => match kind {
2094 LabelKind::Global | LabelKind::Direct => value,
2095
2096 LabelKind::Local => {
2097 if let Some(namespace) = self.active_namespace {
2098 let global_label = {
2099 let interner = self.str_interner.as_ref().borrow();
2100 let global = interner.get(namespace).unwrap();
2101 let label = interner.get(value).unwrap();
2102 format!("{global}{label}")
2103 };
2104 self.str_interner.borrow_mut().intern(global_label)
2105 } else {
2106 let interner = self.str_interner.as_ref().borrow();
2107 let label = interner.get(value).unwrap();
2108 return asm_err!(loc, "The local label \"{label}\" is being defined but there was no global label defined before it");
2109 }
2110 }
2111 },
2112
2113 Some(tok) => {
2114 return asm_err!(
2115 tok.loc(),
2116 "Unexpected {}, expected a label",
2117 tok.as_display(&self.str_interner)
2118 )
2119 }
2120 };
2121
2122 self.expect_symbol(SymbolName::Comma)?;
2123 let (_, expr) = self.expr()?;
2124 self.symtab.insert(direct, Symbol::Expr(expr));
2125 }
2126
2127 DirectiveName::ReDefn => {
2128 self.next()?;
2129
2130 let direct = match self.next()? {
2131 None => return self.end_of_input_err(),
2132
2133 Some(Token::Label { loc, value, kind }) => match kind {
2134 LabelKind::Global | LabelKind::Direct => value,
2135
2136 LabelKind::Local => {
2137 if let Some(namespace) = self.active_namespace {
2138 let global_label = {
2139 let interner = self.str_interner.as_ref().borrow();
2140 let global = interner.get(namespace).unwrap();
2141 let label = interner.get(value).unwrap();
2142 format!("{global}{label}")
2143 };
2144 self.str_interner.borrow_mut().intern(global_label)
2145 } else {
2146 let interner = self.str_interner.as_ref().borrow();
2147 let label = interner.get(value).unwrap();
2148 return asm_err!(loc, "The local constant \"{label}\" is being defined but there was no global label defined before it");
2149 }
2150 }
2151 },
2152
2153 Some(tok) => {
2154 return asm_err!(
2155 tok.loc(),
2156 "Unexpected {}, expected a label",
2157 tok.as_display(&self.str_interner)
2158 )
2159 }
2160 };
2161
2162 self.expect_symbol(SymbolName::Comma)?;
2163 let (_, expr) = self.expr()?;
2164 self.symtab
2165 .insert_with_meta(direct, Symbol::Expr(expr), &[]);
2166 }
2167
2168 DirectiveName::UnDef => {
2169 self.next()?;
2170
2171 let direct = match self.next()? {
2172 None => return self.end_of_input_err(),
2173
2174 Some(Token::Label { loc, value, kind }) => match kind {
2175 LabelKind::Global | LabelKind::Direct => value,
2176
2177 LabelKind::Local => {
2178 if let Some(namespace) = self.active_namespace {
2179 let global_label = {
2180 let interner = self.str_interner.as_ref().borrow();
2181 let global = interner.get(namespace).unwrap();
2182 let label = interner.get(value).unwrap();
2183 format!("{global}{label}")
2184 };
2185 self.str_interner.borrow_mut().intern(global_label)
2186 } else {
2187 let interner = self.str_interner.as_ref().borrow();
2188 let label = interner.get(value).unwrap();
2189 return asm_err!(loc, "The local symbol \"{label}\" is being undefined but there was no global label defined before it");
2190 }
2191 }
2192 },
2193
2194 Some(tok) => {
2195 return asm_err!(
2196 tok.loc(),
2197 "Unexpected {}, expected a label",
2198 tok.as_display(&self.str_interner)
2199 )
2200 }
2201 };
2202 self.symtab.remove(direct);
2203 }
2204
2205 DirectiveName::Db => {
2206 self.next()?;
2207
2208 match self.seg_mode {
2209 SegmentMode::Addr => {
2210 if (self.here as usize) + 1 > (u16::MAX as usize) + 1 {
2211 return asm_err!(
2212 loc,
2213 "\"@db\" bytes extend past address $ffff"
2214 );
2215 }
2216 self.here += 1;
2217 }
2218
2219 SegmentMode::Code => loop {
2220 match self.peek()? {
2221 Some(Token::String { loc, value, .. }) => {
2222 self.next()?;
2223 let interner = self.str_interner.as_ref().borrow();
2224 let bytes = interner.get(value).unwrap().as_bytes();
2225
2226 if (self.here as usize) + bytes.len()
2227 > (u16::MAX as usize) + 1
2228 {
2229 return asm_err!(
2230 loc,
2231 "\"@db\" bytes extend past address $ffff"
2232 );
2233 }
2234 self.here += bytes.len() as u32;
2235 self.data.extend_from_slice(bytes);
2236 }
2237
2238 _ => {
2239 let (loc, expr) = self.expr()?;
2240 if let Some(value) =
2241 expr.evaluate(&self.symtab, &self.str_interner)
2242 {
2243 if (value as u32) > (u8::MAX as u32) {
2244 return asm_err!(loc, "\"@db\" expression result ({value}) will not fit in a byte");
2245 }
2246 if (self.here as usize) + 1
2247 > (u16::MAX as usize) + 1
2248 {
2249 return asm_err!(
2250 loc,
2251 "\"@db\" bytes extend past address $ffff"
2252 );
2253 }
2254 self.here += 1;
2255 self.data.push(value as u8);
2256 } else {
2257 self.here += 1;
2258 self.links.push(Link::byte(
2259 loc,
2260 self.data.len(),
2261 expr,
2262 ));
2263 self.data.push(0);
2264 }
2265 }
2266 }
2267
2268 if self.peeked_symbol(SymbolName::Comma)?.is_some() {
2269 self.next()?;
2270 continue;
2271 }
2272 break;
2273 },
2274 }
2275 }
2276
2277 DirectiveName::Dw => {
2278 self.next()?;
2279
2280 match self.seg_mode {
2281 SegmentMode::Addr => {
2282 if (self.here as usize) + 2 > (u16::MAX as usize) + 1 {
2283 return asm_err!(
2284 loc,
2285 "\"@dw\" bytes extend past address $ffff"
2286 );
2287 }
2288 self.here += 2;
2289 }
2290
2291 SegmentMode::Code => loop {
2292 self.peek()?;
2293 let (loc, expr) = self.expr()?;
2294 if let Some(value) =
2295 expr.evaluate(&self.symtab, &self.str_interner)
2296 {
2297 if (value as u32) > (u16::MAX as u32) {
2298 return asm_err!(
2299 loc,
2300 "\"@dw\" expression result ({value}) will not fit in a word"
2301 );
2302 }
2303 if (self.here as usize) + 2 > (u16::MAX as usize) + 1 {
2304 return asm_err!(
2305 loc,
2306 "\"@dw\" bytes extend past address $ffff"
2307 );
2308 }
2309 self.here += 2;
2310 self.data.extend_from_slice(&(value as u16).to_le_bytes());
2311 } else {
2312 self.here += 2;
2313 self.links.push(Link::word(loc, self.data.len(), expr));
2314 self.data.push(0);
2315 self.data.push(0);
2316 }
2317
2318 if self.peeked_symbol(SymbolName::Comma)?.is_some() {
2319 self.next()?;
2320 continue;
2321 }
2322 break;
2323 },
2324 }
2325 }
2326
2327 DirectiveName::Ds => {
2328 self.next()?;
2329
2330 let size = match self.const_expr()? {
2331 (loc, None) => {
2332 return asm_err!(
2333 loc,
2334 "The size of a \"@ds\" directive must be immediately solvable"
2335 );
2336 }
2337 (loc, Some(size)) => {
2338 if (size as u32) > (u16::MAX as u32) {
2339 return asm_err!(
2340 loc,
2341 "\"@ds\" size expression result ({size}) will not fit in a word"
2342 );
2343 }
2344 if (self.here as usize) + (size as usize)
2345 > (u16::MAX as usize) + 1
2346 {
2347 return asm_err!(
2348 loc,
2349 "\"@ds\" size extends past address $ffff"
2350 );
2351 }
2352 self.here += size as u32;
2353 size as usize
2354 }
2355 };
2356
2357 match self.seg_mode {
2358 SegmentMode::Addr => {}
2359
2360 SegmentMode::Code => {
2361 let value = if self.peeked_symbol(SymbolName::Comma)?.is_some()
2362 {
2363 self.next()?;
2364 let (loc, expr) = self.expr()?;
2365 if let Some(value) =
2366 expr.evaluate(&self.symtab, &self.str_interner)
2367 {
2368 if (value as u32) > (u8::MAX as u32) {
2369 return asm_err!(
2370 loc,
2371 "\"@ds\" value expression result ({value}) will not fit in a byte"
2372 );
2373 }
2374 value as u8
2375 } else {
2376 self.links.push(Link::space(
2377 loc,
2378 self.data.len(),
2379 size,
2380 expr,
2381 ));
2382 0
2383 }
2384 } else {
2385 0
2386 };
2387 self.data.extend(iter::repeat(value).take(size));
2388 }
2389 }
2390 }
2391
2392 DirectiveName::Include => {
2393 self.next()?;
2394 match self.next()? {
2395 None => return self.end_of_input_err(),
2396 Some(Token::String { loc, value }) => {
2397 let cwd = self
2398 .file_manager
2399 .path(self.cwd.unwrap())
2400 .unwrap()
2401 .to_path_buf();
2402 let interner = self.str_interner.as_ref().borrow();
2403 let path = interner.get(value).unwrap();
2404 let (pathref, reader) =
2405 match self.file_manager.reader(&cwd, path) {
2406 Ok(Some(tup)) => tup,
2407 Ok(None) => {
2408 return asm_err!(loc, "File not found: \"{path}\"");
2409 }
2410 Err(e) => {
2411 return asm_err!(
2412 loc,
2413 "Failed to open \"{path}\" for reading: {e}"
2414 );
2415 }
2416 };
2417
2418 self.token_sources.push(self.token_source.take().unwrap());
2420 self.cwds.push(self.cwd.take().unwrap());
2421
2422 self.token_source = Some(TokenSource::Lexer(Lexer::new(
2424 self.str_interner.clone(),
2425 Some(loc),
2426 pathref,
2427 reader,
2428 )));
2429 let cwd = self
2430 .file_manager
2431 .path(pathref)
2432 .unwrap()
2433 .parent()
2434 .unwrap()
2435 .to_path_buf();
2436 self.cwd = Some(self.file_manager.intern(cwd, "."));
2437 }
2438 Some(tok) => {
2439 return asm_err!(
2440 tok.loc(),
2441 "Unexpected {}, expected file name string",
2442 tok.as_display(&self.str_interner)
2443 );
2444 }
2445 }
2446 }
2447
2448 DirectiveName::Segment => {
2449 self.next()?;
2450 match self.next()? {
2451 None => return self.end_of_input_err(),
2452
2453 Some(Token::String { loc, value }) => {
2454 let interner = self.str_interner.borrow_mut();
2455 if interner.eq_some("CODE", value)
2456 || interner.eq_some("code", value)
2457 {
2458 self.seg_mode = SegmentMode::Code
2459 } else if interner.eq_some("ADDR", value)
2460 || interner.eq_some("addr", value)
2461 {
2462 self.seg_mode = SegmentMode::Addr
2463 } else {
2464 let value = interner.get(value).unwrap();
2465 return asm_err!(
2466 loc,
2467 "Unrecognized segment name \"{value}\", only \"CODE\" or \"ADDR\" are valid segment names",
2468 );
2469 }
2470 }
2471
2472 Some(tok) => {
2473 return asm_err!(
2474 tok.loc(),
2475 "Unexpected {}, expected segment name string",
2476 tok.as_display(&self.str_interner)
2477 );
2478 }
2479 }
2480 }
2481
2482 DirectiveName::Incbin => {
2483 if let SegmentMode::Addr = self.seg_mode {
2484 return asm_err!(
2485 self.loc(),
2486 "Binary data cannot be included in an \"ADDR\" segment"
2487 );
2488 }
2489 self.next()?;
2490 match self.next()? {
2491 None => return self.end_of_input_err(),
2492 Some(Token::String { loc, value }) => {
2493 let cwd = self
2494 .file_manager
2495 .path(self.cwd.unwrap())
2496 .unwrap()
2497 .to_path_buf();
2498 let interner = self.str_interner.as_ref().borrow();
2499 let path = interner.get(value).unwrap();
2500 let (pathref, reader) =
2501 match self.file_manager.reader(&cwd, path) {
2502 Ok(Some(tup)) => tup,
2503 Ok(None) => {
2504 return asm_err!(loc, "File not found: \"{path}\"");
2505 }
2506 Err(e) => {
2507 return asm_err!(
2508 loc,
2509 "Failed to open \"{path}\" for reading: {e}"
2510 );
2511 }
2512 };
2513
2514 let path = self.file_manager.path(pathref).unwrap();
2515 for result in reader.bytes() {
2516 match result {
2517 Ok(b) => {
2518 if (self.here as usize) + 1
2519 > (u16::MAX as usize) + 1
2520 {
2521 return asm_err!(
2522 loc,
2523 "\"@incbin\" bytes extend past address $ffff"
2524 );
2525 }
2526 self.here += 1;
2527 self.data.push(b);
2528 }
2529 Err(e) => {
2530 return asm_err!(
2531 loc,
2532 "Error reading \"{}\": {e}",
2533 path.display()
2534 );
2535 }
2536 }
2537 }
2538 }
2539 Some(tok) => {
2540 return asm_err!(
2541 tok.loc(),
2542 "Unexpected {}, expected file name string",
2543 tok.as_display(&self.str_interner)
2544 );
2545 }
2546 }
2547 }
2548
2549 DirectiveName::Macro => {
2550 self.next()?;
2551
2552 let (value, loc) = match self.next()? {
2553 None => return self.end_of_input_err(),
2554
2555 Some(Token::Label {
2556 loc,
2557 kind: LabelKind::Global,
2558 value,
2559 }) => (value, loc),
2560
2561 Some(tok) => {
2562 return asm_err!(
2563 tok.loc(),
2564 "Unexpected {}, expected a macro name",
2565 tok.as_display(&self.str_interner)
2566 );
2567 }
2568 };
2569 if self.macros.contains_key(&value) {
2570 let interner = self.str_interner.as_ref().borrow();
2571 let name = interner.get(value).unwrap();
2572 return asm_err!(loc, "The macro \"{name}\" was already defined");
2573 }
2574
2575 self.expect_symbol(SymbolName::Comma)?;
2576
2577 let args_count = match self.next()? {
2578 None => return self.end_of_input_err(),
2579 Some(Token::Number { value, .. }) => value as usize,
2580 Some(tok) => {
2581 return asm_err!(
2582 tok.loc(),
2583 "Unexpected {}, expected number of macro arguments",
2584 tok.as_display(&self.str_interner)
2585 );
2586 }
2587 };
2588
2589 let mut args = Vec::new();
2590 for _ in 0..args_count {
2591 self.expect_symbol(SymbolName::Comma)?;
2592
2593 match self.next()? {
2594 None => return self.end_of_input_err(),
2595
2596 Some(Token::Label { loc, kind, value }) => {
2597 let interner = self.str_interner.as_ref().borrow();
2598 let str_value = interner.get(value).unwrap();
2599 if kind != LabelKind::Global {
2600 return asm_err!(
2601 loc,
2602 "\"@macro\" argument name \"{str_value}\" must be a global label"
2603 );
2604 }
2605 args.push(value);
2606 }
2607
2608 Some(tok) => {
2609 return asm_err!(
2610 tok.loc(),
2611 "Unexpected {}, expected a macro argument name",
2612 tok.as_display(&self.str_interner)
2613 );
2614 }
2615 };
2616 }
2617
2618 self.active_macro = Some(value);
2619 let mut toks = Vec::new();
2620 let mut macro_depth = 0;
2621 loop {
2622 match self.next()? {
2623 None => return self.end_of_input_err(),
2624 Some(Token::Comment { .. } | Token::NewLine { .. }) => {}
2625
2626 Some(
2627 tok @ Token::Directive {
2628 name: DirectiveName::Macro,
2629 ..
2630 },
2631 ) => {
2632 macro_depth += 1;
2633 toks.push(MacroToken::Token(tok));
2634 }
2635
2636 Some(
2637 tok @ Token::Directive {
2638 name: DirectiveName::EndMacro,
2639 ..
2640 },
2641 ) => {
2642 if macro_depth == 0 {
2643 self.active_macro = None;
2644 break;
2645 }
2646 macro_depth -= 1;
2647 toks.push(MacroToken::Token(tok));
2648 }
2649
2650 Some(Token::Directive {
2651 loc,
2652 name: DirectiveName::Entropy,
2653 }) => {
2654 toks.push(MacroToken::Entropy { loc });
2655 }
2656
2657 Some(Token::Label { kind, value, .. })
2658 if kind == LabelKind::Global && args.contains(&value) =>
2659 {
2660 toks.push(MacroToken::Argument {
2661 index: args
2662 .iter()
2663 .position(|arg| arg == &value)
2664 .unwrap(),
2665 })
2666 }
2667
2668 Some(tok) => {
2669 toks.push(MacroToken::Token(tok));
2670 }
2671 }
2672 }
2673
2674 self.macros.insert(value, Macro { args, tokens: toks });
2675 }
2676
2677 DirectiveName::Struct => {
2678 self.next()?;
2679
2680 let (value, loc) = match self.next()? {
2681 None => return self.end_of_input_err(),
2682 Some(Token::Label {
2683 loc,
2684 kind: LabelKind::Global,
2685 value,
2686 }) => (value, loc),
2687 Some(tok) => {
2688 return asm_err!(
2689 tok.loc(),
2690 "Unexpected {}, expected struct name",
2691 tok.as_display(&self.str_interner)
2692 );
2693 }
2694 };
2695
2696 let old_namespace = self.active_namespace;
2697 if self.symtab.get(value).is_some() {
2698 let interner = self.str_interner.as_ref().borrow();
2699 let label = interner.get(value).unwrap();
2700 return asm_err!(loc, "The label \"{label}\" was already defined");
2701 }
2702 self.active_namespace = Some(value);
2703 let mut struct_size = 0i32;
2704 loop {
2705 match self.next()? {
2706 None => return self.end_of_input_err(),
2707 Some(Token::NewLine { .. } | Token::Comment { .. }) => {}
2708 Some(Token::Directive {
2709 name: DirectiveName::Ds,
2710 ..
2711 }) => match self.peek()? {
2712 None => return self.end_of_input_err(),
2713 Some(_) => match self.const_expr()? {
2714 (loc, None) => {
2715 return asm_err!(
2716 loc,
2717 "Padding size must be immediately solvable",
2718 );
2719 }
2720 (_, Some(pad_size)) => {
2721 struct_size = struct_size.wrapping_add(pad_size);
2722 }
2723 },
2724 },
2725 Some(Token::Directive {
2726 name: DirectiveName::Align,
2727 ..
2728 }) => match self.peek()? {
2729 None => return self.end_of_input_err(),
2730 Some(_) => match self.const_expr()? {
2731 (loc, None) => {
2732 return asm_err!(
2733 loc,
2734 "Alignment must be immediately solvable",
2735 );
2736 }
2737 (_, Some(alignment)) => {
2738 if alignment < 2 {
2739 return asm_err!(
2740 loc,
2741 "Alignment value ({alignment}) must be greater than 1",
2742 );
2743 }
2744 let padding = (alignment
2745 - (struct_size % alignment))
2746 % alignment;
2747 struct_size = struct_size.wrapping_add(padding);
2748 }
2749 },
2750 },
2751 Some(Token::Directive {
2752 name: DirectiveName::EndStruct,
2753 ..
2754 }) => break,
2755 Some(Token::Label {
2756 loc,
2757 kind: LabelKind::Global,
2758 value: field,
2759 }) => {
2760 let direct_label = {
2761 let interner = self.str_interner.as_ref().borrow();
2762 let global = interner.get(value).unwrap();
2763 let label = interner.get(field).unwrap();
2764 format!("{global}.{label}")
2765 };
2766 let direct =
2767 self.str_interner.borrow_mut().intern(&direct_label);
2768 if self.symtab.get(direct).is_some() {
2769 return asm_err!(
2770 loc,
2771 "The field \"{direct_label}\" was already defined",
2772 );
2773 }
2774
2775 if let Some(Token::Symbol {
2777 name: SymbolName::Colon,
2778 ..
2779 }) = self.peek()?
2780 {
2781 self.next()?;
2782 }
2783
2784 match self.peek()? {
2785 None => return self.end_of_input_err(),
2786 Some(Token::Directive {
2787 name: DirectiveName::Db,
2788 ..
2789 }) => {
2790 self.next()?;
2791 let mut interner = self.str_interner.borrow_mut();
2792 let key = interner.intern("@SIZEOF");
2793 let value = interner.intern(format!("1"));
2794 self.symtab.insert_with_meta(
2795 direct,
2796 Symbol::Value(struct_size),
2797 &[[key, value]],
2798 );
2799 struct_size = struct_size.wrapping_add(1);
2800 }
2801 Some(Token::Directive {
2802 name: DirectiveName::Dw,
2803 ..
2804 }) => {
2805 self.next()?;
2806 let mut interner = self.str_interner.borrow_mut();
2807 let key = interner.intern("@SIZEOF");
2808 let value = interner.intern(format!("2"));
2809 self.symtab.insert_with_meta(
2810 direct,
2811 Symbol::Value(struct_size),
2812 &[[key, value]],
2813 );
2814 struct_size = struct_size.wrapping_add(2);
2815 }
2816 Some(_) => match self.const_expr()? {
2817 (loc, None) => {
2818 return asm_err!(
2819 loc,
2820 "Field \"{direct_label}\"'s size must be immediately solvable",
2821 );
2822 }
2823 (_, Some(field_size)) => {
2824 let mut interner =
2825 self.str_interner.borrow_mut();
2826 let key = interner.intern("@SIZEOF");
2827 let value =
2828 interner.intern(format!("{field_size}"));
2829 self.symtab.insert_with_meta(
2830 direct,
2831 Symbol::Value(struct_size),
2832 &[[key, value]],
2833 );
2834 struct_size =
2835 struct_size.wrapping_add(field_size);
2836 }
2837 },
2838 }
2839 }
2840 Some(tok) => {
2841 return asm_err!(
2842 tok.loc(),
2843 "Unexpected {}, expected field name or \"@endstruct\"",
2844 tok.as_display(&self.str_interner)
2845 );
2846 }
2847 }
2848 }
2849 self.active_namespace = old_namespace;
2850 self.symtab
2851 .insert_with_meta(value, Symbol::Value(struct_size), &[]);
2852 }
2853
2854 DirectiveName::Align => {
2855 self.next()?;
2856 match self.peek()? {
2857 None => return self.end_of_input_err(),
2858 Some(_) => match self.const_expr()? {
2859 (loc, None) => {
2860 return asm_err!(
2861 loc,
2862 "Alignment must be immediately solvable"
2863 );
2864 }
2865 (loc, Some(alignment)) => {
2866 if alignment < 2 {
2867 return asm_err!(
2868 loc,
2869 "Alignment value ({alignment}) must be greater than 1",
2870 );
2871 }
2872 let alignment = alignment as u32;
2873 let padding =
2874 (alignment - (self.here % alignment)) % alignment;
2875 if padding > (u16::MAX as u32) {
2876 return asm_err!(
2877 loc,
2878 "Alignment padding ({padding}) will not fit in a word"
2879 );
2880 }
2881 if (self.here as usize) + (padding as usize)
2882 > (u16::MAX as usize) + 1
2883 {
2884 return asm_err!(
2885 loc,
2886 "Alignment padding extends past address $ffff"
2887 );
2888 }
2889 self.here += padding;
2890 self.data.extend(iter::repeat(0).take(padding as usize));
2891 }
2892 },
2893 }
2894 }
2895
2896 DirectiveName::Meta => {
2897 self.next()?;
2898
2899 let mut pairs = Vec::new();
2900 loop {
2901 match self.next()? {
2902 None => return self.end_of_input_err(),
2903
2904 Some(Token::String { value: key, .. }) => match self.next()? {
2905 None => return self.end_of_input_err(),
2906
2907 Some(Token::String { value, .. }) => {
2908 pairs.push([key, value]);
2909 }
2910
2911 Some(tok) => {
2912 return asm_err!(
2913 tok.loc(),
2914 "Unexpected {}, expected a metadata value",
2915 tok.as_display(&self.str_interner)
2916 );
2917 }
2918 },
2919
2920 Some(tok) => {
2921 return asm_err!(
2922 tok.loc(),
2923 "Unexpected {}, expected a metadata key",
2924 tok.as_display(&self.str_interner)
2925 );
2926 }
2927 }
2928
2929 if self.peeked_symbol(SymbolName::Comma)?.is_none() {
2930 break;
2931 }
2932 self.next()?;
2933 }
2934 self.symtab.set_meta(pairs);
2935 }
2936
2937 DirectiveName::EndMeta => {
2938 self.next()?;
2939 self.symtab.set_meta(&[]);
2940 }
2941
2942 DirectiveName::If => {
2943 self.next()?;
2944
2945 let result = match self.const_expr()? {
2946 (_, Some(value)) => value,
2947 (loc, None) => {
2948 return asm_err!(
2949 loc,
2950 "The expression following an \"@if\" directive must be immediately solvable"
2951 )
2952 }
2953 };
2954
2955 if result != 0 {
2956 self.if_level += 1;
2957 } else {
2958 let mut if_level = 1;
2959 loop {
2960 match self.next()? {
2961 None => return self.end_of_input_err(),
2962
2963 Some(Token::Directive {
2964 name: DirectiveName::If,
2965 ..
2966 }) => {
2967 if_level += 1;
2968 }
2969
2970 Some(Token::Directive {
2971 name: DirectiveName::EndIf,
2972 ..
2973 }) => {
2974 if_level -= 1;
2975 if if_level == 0 {
2976 break;
2977 }
2978 }
2979
2980 Some(_) => {}
2981 }
2982 }
2983 }
2984 }
2985
2986 DirectiveName::EndIf => {
2987 self.next()?;
2988 if self.if_level == 0 {
2989 return asm_err!(tok.loc(), "Unexpected \"@endif\"");
2990 }
2991 self.if_level -= 1;
2992 }
2993
2994 _ => {
2995 return asm_err!(
2996 tok.loc(),
2997 "Unexpected {}",
2998 tok.as_display(&self.str_interner)
2999 );
3000 }
3001 }
3002 }
3003
3004 Some(Token::Operation { name, .. }) => {
3005 if let SegmentMode::Addr = self.seg_mode {
3006 return asm_err!(
3007 self.loc(),
3008 "Cannot place instructions in an \"ADDR\" segment",
3009 );
3010 }
3011
3012 let old_len = self.data.len();
3013 <Z as ArchAssembler<S, R, A>>::parse(self, name)?;
3014 self.here += (self.data.len() - old_len) as u32;
3015 }
3016
3017 Some(tok) => {
3018 return asm_err!(
3019 tok.loc(),
3020 "Unexpected {}",
3021 tok.as_display(&self.str_interner)
3022 )
3023 }
3024 }
3025 }
3026 }
3027}