1use alloc::{boxed::Box, string::String, vec, vec::Vec};
7use core::any::Any;
8use thiserror::Error;
9
10use crate::{
11 basic_block::BasicBlock,
12 builtin::{
13 op_interfaces::{IsolatedFromAboveInterface, OneResultInterface},
14 ops::ForwardRefOp,
15 },
16 combine::{
17 Parser, Positioned, StreamOnce, choice,
18 easy::{self, Errors, ParseError},
19 error::{StdParseResult2, Tracked},
20 parser::char::string,
21 stream::{
22 self, IteratorStream, buffered,
23 position::{self, SourcePosition},
24 state::Stream,
25 },
26 },
27 context::{Context, Ptr},
28 identifier::Identifier,
29 input_err,
30 irfmt::parsers::{hex_int_parser, int_parser, quoted_string_parser},
31 location::{self, Located, Location, Source},
32 op::op_impls,
33 operation::Operation,
34 result::{self, Result},
35 std_deps::{fs::File, io::BufReader, path::Path, utf8_chars::BufReadCharsExt},
36 utils::table::{
37 HMap,
38 itable::{Entry, IMap},
39 },
40 value::{DefiningEntity, Value},
41};
42
43pub struct State<'a> {
47 pub ctx: &'a mut Context,
49 pub(crate) name_tracker: NameTracker,
51 pub src: Source,
53 pub aux_data: HMap<Identifier, Box<dyn Any>>,
55}
56
57impl<'a> State<'a> {
58 pub fn new(ctx: &'a mut Context, src: Source) -> State<'a> {
60 State {
61 ctx,
62 name_tracker: NameTracker::default(),
63 src,
64 aux_data: HMap::default(),
65 }
66 }
67}
68
69pub struct CharIterator<'a>(Box<dyn Iterator<Item = char> + 'a>);
72
73impl Iterator for CharIterator<'_> {
74 type Item = char;
75
76 fn next(&mut self) -> Option<Self::Item> {
77 self.0.next()
78 }
79}
80
81pub type StateStream<'a> = Stream<
84 buffered::Stream<
85 easy::Stream<
86 stream::position::Stream<stream::IteratorStream<CharIterator<'a>>, SourcePosition>,
87 >,
88 >,
89 State<'a>,
90>;
91
92impl Located for StateStream<'_> {
93 fn loc(&self) -> location::Location {
94 location::Location::SrcPos {
95 src: self.state.src,
96 pos: self.position(),
97 }
98 }
99
100 fn set_loc(&mut self, _loc: Location) {
101 panic!("Cannot set location of parser");
102 }
103}
104
105pub type ParseResult<'a, T> = StdParseResult2<T, <StateStream<'a> as StreamOnce>::Error>;
106
107pub trait Parsable {
148 type Arg: Clone + 'static;
150 type Parsed;
152
153 fn parse<'a>(
157 state_stream: &mut StateStream<'a>,
158 arg: Self::Arg,
159 ) -> ParseResult<'a, Self::Parsed>;
160
161 fn parser<'a>(
163 arg: Self::Arg,
164 ) -> Box<dyn Parser<StateStream<'a>, Output = Self::Parsed, PartialState = ()> + 'a>
165 where
166 Self::Parsed: 'a,
167 {
168 parser_combinator(Self::parse, arg)
169 }
170}
171
172#[inline(never)]
174pub fn parser_combinator<'a, Arg: Clone + 'static, Output: 'a>(
175 parse: fn(&mut StateStream<'a>, Arg) -> ParseResult<'a, Output>,
176 args: Arg,
177) -> Box<dyn Parser<StateStream<'a>, Output = Output, PartialState = ()> + 'a> {
178 combine::parser(move |state_stream| parse(state_stream, args.clone())).boxed()
179}
180
181pub fn state_stream_from_iterator<'a, T: Iterator<Item = char> + 'a>(
234 input: T,
235 state: State<'a>,
236) -> StateStream<'a> {
237 StateStream {
238 stream: buffered::Stream::new(
239 easy::Stream::from(position::Stream::with_positioner(
240 IteratorStream::new(CharIterator(Box::new(input))),
241 SourcePosition::default(),
242 )),
243 100,
244 ),
245 state,
246 }
247}
248
249pub fn parse_from_str<'a, P: Parser<StateStream<'a>>>(
261 mut parser: P,
262 ctx: &'a mut Context,
263 input: &'a str,
264) -> Result<P::Output> {
265 let source = location::Source::InMemory;
266 let state_stream = state_stream_from_iterator(input.chars(), State::new(ctx, source));
267 match parser.parse(state_stream) {
268 Ok((parsed_res, _)) => Ok(parsed_res),
269 Err(err) => {
270 let loc = Location::SrcPos {
271 src: source,
272 pos: err.position,
273 };
274 input_err!(loc, err)
275 }
276 }
277}
278
279pub fn parse_from_file<'a, P: Parser<StateStream<'a>>>(
295 mut parser: P,
296 ctx: &'a mut Context,
297 path: &'a Path,
298) -> Result<P::Output> {
299 let source = location::Source::new_from_file(ctx, path);
300
301 struct FileChars<'a> {
303 reader: BufReader<File>,
304 path: &'a Path,
305 }
306
307 impl Iterator for FileChars<'_> {
308 type Item = char;
309
310 fn next(&mut self) -> Option<char> {
311 self.reader
312 .read_char()
313 .inspect_err(|e| {
314 log::error!(
315 "Error reading chars from file {}: {}",
316 self.path.display(),
317 e
318 )
319 })
320 .unwrap()
321 }
322 }
323
324 let plir_file = File::open(path).unwrap();
326 let chars_iter = FileChars {
327 reader: BufReader::new(plir_file),
328 path,
329 };
330
331 let state_stream = state_stream_from_iterator(chars_iter, State::new(ctx, source));
332
333 match parser.parse(state_stream) {
334 Ok((parsed_res, _)) => Ok(parsed_res),
335 Err(err) => {
336 let loc = Location::SrcPos {
337 src: source,
338 pos: err.position,
339 };
340 input_err!(loc, err)
341 }
342 }
343}
344
345pub trait IntoParseResult<'a, T> {
348 fn into_parse_result(self) -> StdParseResult2<T, <StateStream<'a> as StreamOnce>::Error>;
349}
350
351impl<'a, T> IntoParseResult<'a, T> for Result<T> {
352 fn into_parse_result(self) -> StdParseResult2<T, <StateStream<'a> as StreamOnce>::Error> {
353 match self {
354 Ok(t) => combine::ParseResult::CommitOk(t),
355 Err(e) => combine::ParseResult::CommitErr(e.into()),
356 }
357 .into()
358 }
359}
360
361impl From<result::Error> for ParseError<StateStream<'_>> {
362 fn from(value: result::Error) -> Self {
363 let position = if let Location::SrcPos { pos, .. } = value.loc {
364 pos
365 } else {
366 SourcePosition::default()
367 };
368 easy::Errors::from_errors(position, vec![easy::Error::Other(value.err)])
369 }
370}
371
372impl From<result::Error> for combine::error::Commit<Tracked<Errors<char, char, SourcePosition>>> {
373 fn from(value: result::Error) -> Self {
374 let res: StdParseResult2<(), ParseError<StateStream<'_>>> =
375 combine::ParseResult::CommitErr(value.into()).into();
376 res.err().unwrap()
377 }
378}
379
380enum LabelRef {
382 ForwardRef(Ptr<BasicBlock>),
383 Defined(Ptr<BasicBlock>),
384}
385
386impl LabelRef {
387 fn get_label(&self) -> Ptr<BasicBlock> {
388 match self {
389 LabelRef::ForwardRef(label) => *label,
390 LabelRef::Defined(label) => *label,
391 }
392 }
393}
394
395#[derive(Default)]
397pub(crate) struct NameTracker {
398 ssa_name_scope: Vec<IMap<Identifier, Value>>,
399 block_label_scope: Vec<IMap<Identifier, LabelRef>>,
400}
401
402#[derive(Error, Debug)]
403#[error("Identifier {0} was not resolved to any definition in the scope")]
404pub struct UnresolvedReference(Identifier);
405
406#[derive(Error, Debug)]
407pub enum ParserNameTrackerError {
408 #[error("Identifier {0} defined more than once in the scope")]
409 MultipleDefinitions(Identifier),
410 #[error("Regions in a top-level operation must be IsolatedFromAbove")]
411 TopLevelOpRegionNotIsolatedFromAbove,
412}
413
414impl NameTracker {
415 pub(crate) fn ssa_use(&mut self, ctx: &mut Context, id: &Identifier) -> Value {
419 let scope = self
420 .ssa_name_scope
421 .last_mut()
422 .expect("NameTracker doesn't have an active scope.");
423 match scope.entry(id.clone()) {
424 Entry::Occupied(occ) => *occ.get(),
425 Entry::Vacant(vac) => {
426 let forward_def = ForwardRefOp::new(ctx).get_result(ctx);
428 vac.insert(forward_def);
429 forward_def
430 }
431 }
432 }
433
434 pub(crate) fn ssa_def(
437 &mut self,
438 ctx: &mut Context,
439 id: &(Identifier, Location),
440 def: Value,
441 ) -> Result<()> {
442 let scope = self
443 .ssa_name_scope
444 .last_mut()
445 .expect("NameTracker doesn't have an active scope.");
446
447 match scope.entry(id.0.clone()) {
448 Entry::Occupied(mut occ) => match occ.get_mut().defining_entity() {
449 DefiningEntity::Op(op) => {
450 let fref_opt =
451 Operation::get_op::<ForwardRefOp>(op, ctx).map(|op| op.get_result(ctx));
452 if let Some(fref) = fref_opt {
453 fref.replace_some_uses_with(ctx, |_, _| true, &def);
455 Operation::erase(op, ctx);
456 occ.insert(def);
457 } else {
458 input_err!(
460 id.1.clone(),
461 ParserNameTrackerError::MultipleDefinitions(id.0.clone())
462 )?
463 }
464 }
465 DefiningEntity::Block(_) => {
466 input_err!(
468 id.1.clone(),
469 ParserNameTrackerError::MultipleDefinitions(id.0.clone())
470 )?
471 }
472 },
473 Entry::Vacant(vac) => {
474 vac.insert(def);
475 }
476 }
477 Ok(())
478 }
479
480 pub(crate) fn block_use(&mut self, ctx: &mut Context, id: &Identifier) -> Ptr<BasicBlock> {
484 let scope = self
485 .block_label_scope
486 .last_mut()
487 .expect("NameTracker doesn't have an active scope.");
488 match scope.entry(id.clone()) {
489 Entry::Occupied(occ) => occ.get().get_label(),
490 Entry::Vacant(vac) => {
491 let block_forward = BasicBlock::new(ctx, Some(id.clone()), vec![]);
493 vac.insert(LabelRef::ForwardRef(block_forward));
494 block_forward
495 }
496 }
497 }
498
499 pub(crate) fn block_def(
502 &mut self,
503 ctx: &mut Context,
504 id: &(Identifier, Location),
505 block: Ptr<BasicBlock>,
506 ) -> Result<()> {
507 let scope = self
508 .block_label_scope
509 .last_mut()
510 .expect("NameTracker doesn't have an active scope.");
511 match scope.entry(id.0.clone()) {
512 Entry::Occupied(mut occ) => match occ.get_mut() {
513 LabelRef::ForwardRef(fref) => {
514 fref.retarget_some_preds_to(ctx, |_, _| true, block);
515 BasicBlock::erase(*fref, ctx);
516 occ.insert(LabelRef::Defined(block));
517 }
518 LabelRef::Defined(_) => input_err!(
519 id.1.clone(),
520 ParserNameTrackerError::MultipleDefinitions(id.0.clone())
521 )?,
522 },
523 Entry::Vacant(vac) => {
524 vac.insert(LabelRef::Defined(block));
525 }
526 }
527 Ok(())
528 }
529
530 pub(crate) fn enter_region(&mut self, ctx: &Context, parent_op: Ptr<Operation>) -> Result<()> {
535 if op_impls::<dyn IsolatedFromAboveInterface>(
536 Operation::get_op_dyn(parent_op, ctx).as_ref(),
537 ) {
538 self.ssa_name_scope.push(IMap::default());
539 } else if self.ssa_name_scope.is_empty() {
540 input_err!(
541 parent_op.deref(ctx).loc(),
542 ParserNameTrackerError::TopLevelOpRegionNotIsolatedFromAbove
543 )?
544 }
545 self.block_label_scope.push(IMap::default());
546 Ok(())
547 }
548
549 pub(crate) fn exit_region(
553 &mut self,
554 ctx: &Context,
555 parent_op: Ptr<Operation>,
556 loc: Location,
557 ) -> Result<()> {
558 if op_impls::<dyn IsolatedFromAboveInterface>(
559 Operation::get_op_dyn(parent_op, ctx).as_ref(),
560 ) {
561 let ssa_scope = self
563 .ssa_name_scope
564 .pop()
565 .expect("Exiting an isolated-from-above region which wasn't entered into.");
566 for (id, value) in ssa_scope {
567 if let DefiningEntity::Op(op) = value.defining_entity()
568 && Operation::is_op::<ForwardRefOp>(op, ctx)
569 {
570 input_err!(loc.clone(), UnresolvedReference(id.clone()))?
571 }
572 }
573 }
574
575 let label_scope = self
576 .block_label_scope
577 .pop()
578 .expect("Exiting an isolated-from-above region which wasn't entered into.");
579
580 for (id, op) in label_scope {
582 if matches!(op, LabelRef::ForwardRef(_)) {
583 input_err!(loc.clone(), UnresolvedReference(id.clone()))?
584 }
585 }
586
587 Ok(())
588 }
589}
590
591impl Parsable for usize {
592 type Arg = ();
593 type Parsed = usize;
594
595 fn parse<'a>(
596 state_stream: &mut StateStream<'a>,
597 _arg: Self::Arg,
598 ) -> ParseResult<'a, Self::Parsed> {
599 int_parser::<usize>().parse_stream(state_stream).into()
600 }
601}
602impl Parsable for u64 {
603 type Arg = ();
604 type Parsed = u64;
605
606 fn parse<'a>(
607 state_stream: &mut StateStream<'a>,
608 _arg: Self::Arg,
609 ) -> ParseResult<'a, Self::Parsed> {
610 int_parser::<u64>().parse_stream(state_stream).into()
611 }
612}
613
614impl Parsable for u32 {
615 type Arg = ();
616 type Parsed = u32;
617
618 fn parse<'a>(
619 state_stream: &mut StateStream<'a>,
620 _arg: Self::Arg,
621 ) -> ParseResult<'a, Self::Parsed> {
622 int_parser::<u32>().parse_stream(state_stream).into()
623 }
624}
625
626impl Parsable for u16 {
627 type Arg = ();
628 type Parsed = u16;
629
630 fn parse<'a>(
631 state_stream: &mut StateStream<'a>,
632 _arg: Self::Arg,
633 ) -> ParseResult<'a, Self::Parsed> {
634 int_parser::<u16>().parse_stream(state_stream).into()
635 }
636}
637
638impl Parsable for u8 {
639 type Arg = ();
640 type Parsed = u8;
641
642 fn parse<'a>(
643 state_stream: &mut StateStream<'a>,
644 _arg: Self::Arg,
645 ) -> ParseResult<'a, Self::Parsed> {
646 int_parser::<u8>().parse_stream(state_stream).into()
647 }
648}
649
650impl Parsable for i8 {
651 type Arg = ();
652 type Parsed = i8;
653
654 fn parse<'a>(
655 state_stream: &mut StateStream<'a>,
656 _arg: Self::Arg,
657 ) -> ParseResult<'a, Self::Parsed> {
658 int_parser::<i8>().parse_stream(state_stream).into()
659 }
660}
661
662impl Parsable for i16 {
663 type Arg = ();
664 type Parsed = i16;
665
666 fn parse<'a>(
667 state_stream: &mut StateStream<'a>,
668 _arg: Self::Arg,
669 ) -> ParseResult<'a, Self::Parsed> {
670 int_parser::<i16>().parse_stream(state_stream).into()
671 }
672}
673
674impl Parsable for i32 {
675 type Arg = ();
676 type Parsed = i32;
677
678 fn parse<'a>(
679 state_stream: &mut StateStream<'a>,
680 _arg: Self::Arg,
681 ) -> ParseResult<'a, Self::Parsed> {
682 int_parser::<i32>().parse_stream(state_stream).into()
683 }
684}
685
686impl Parsable for i64 {
687 type Arg = ();
688 type Parsed = i64;
689
690 fn parse<'a>(
691 state_stream: &mut StateStream<'a>,
692 _arg: Self::Arg,
693 ) -> ParseResult<'a, Self::Parsed> {
694 int_parser::<i64>().parse_stream(state_stream).into()
695 }
696}
697
698impl Parsable for bool {
699 type Arg = ();
700 type Parsed = bool;
701
702 fn parse<'a>(
703 state_stream: &mut StateStream<'a>,
704 _arg: Self::Arg,
705 ) -> ParseResult<'a, Self::Parsed> {
706 let mut bool_parser =
708 choice((string("true").map(|_| true), string("false").map(|_| false)));
709
710 bool_parser.parse_stream(state_stream).into()
711 }
712}
713
714impl Parsable for String {
715 type Arg = ();
716
717 type Parsed = Self;
718
719 fn parse<'a>(
720 state_stream: &mut StateStream<'a>,
721 _arg: Self::Arg,
722 ) -> ParseResult<'a, Self::Parsed> {
723 quoted_string_parser().parse_stream(state_stream).into()
724 }
725}
726
727impl Parsable for *const () {
728 type Arg = ();
729
730 type Parsed = Self;
731
732 fn parse<'a>(
733 state_stream: &mut StateStream<'a>,
734 _arg: Self::Arg,
735 ) -> ParseResult<'a, Self::Parsed> {
736 hex_int_parser::<usize>()
737 .parse_stream(state_stream)
738 .map(|n| n as *const ())
739 .into()
740 }
741}
742
743impl Parsable for *mut () {
744 type Arg = ();
745
746 type Parsed = Self;
747
748 fn parse<'a>(
749 state_stream: &mut StateStream<'a>,
750 _arg: Self::Arg,
751 ) -> ParseResult<'a, Self::Parsed> {
752 hex_int_parser::<usize>()
753 .parse_stream(state_stream)
754 .map(|n| n as *mut ())
755 .into()
756 }
757}