1use alloc::collections::BTreeMap;
2use core::fmt;
3use super::{error, lir::Program};
4
5use lalrpop_util::lalrpop_mod;
6lalrpop_mod!(pub mir_parser);
7
8
9#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
10pub struct Address(pub u32);
11
12impl fmt::Display for Address {
13 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
14 write!(f, "{}", self.0)
15 }
16}
17
18#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
19pub struct Literal(pub u32);
20
21impl fmt::Display for Literal {
22 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
23 write!(f, "{}", self.0)
24 }
25}
26
27#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
28pub enum Location {
29 Address(Address),
30 Deref(Box<Self>),
31 Offset(Box<Self>, i32),
32}
33
34#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
35pub enum Error {
36 MacroNotDefined(String),
37 CannotGetRuntimeAddress(Location),
38
39 ParseError(String),
40}
41
42impl fmt::Display for Error {
43 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
44 write!(f, "\x1b[91merror: \x1b[m\x1b[0m")?;
45 match self {
46 Error::MacroNotDefined(name) => write!(f, "macro '{}' not defined", name),
47 Error::CannotGetRuntimeAddress(location) => write!(f, "cannot get runtime address of {}", location),
48 Error::ParseError(msg) => write!(f, "\n{}", msg),
49 }
50 }
51}
52
53pub fn parse(code: impl ToString) -> Result<Op, Error> {
54 let code = code.to_string();
55 match mir_parser::MIRParser::new().parse(&code) {
56 Ok(parsed) => {
57 Ok(parsed)
58 },
59 Err(e) => {
60 Err(Error::ParseError(error::format_error(&code, e)))
61 }
62 }
63}
64
65
66pub fn function(mut args: Vec<(String, u32)>, ret_size: u32, code: Vec<Op>) -> Op {
67 let mut offset = 0;
68 let mut args_size = 0;
69 let mut result = Op::Do(code);
70 for (_, size) in &args {
71 args_size += size;
72 }
73
74 while let Some((name, size)) = args.pop() {
75 offset += size;
76 result = Op::Let(name, vec![
77 Op::LoadFrom(FP, 1),
78 Op::Increment(SP.deref(), args_size - offset),
79 ], vec![result]);
80 }
81
82 Op::Frame(args_size, ret_size, vec![result])
83}
84
85impl Location {
86 pub fn get_address(&self) -> Result<Address, Error> {
87 match self {
88 Self::Address(address) => Ok(*address),
89 Self::Offset(inner, offset) => {
90 match inner.get_address() {
91 Ok(address) => Ok(Address((address.0 as i32 + offset) as u32)),
92 Err(error) => Err(error),
93 }
94 }
95 Self::Deref(_) => Err(Error::CannotGetRuntimeAddress(self.clone())),
96 }
97 }
98
99 pub fn deref(&self) -> Self {
100 Self::Deref(Box::new(self.clone()))
101 }
102
103 pub fn offset(&self, count: i32) -> Self {
104 Self::Offset(Box::new(self.clone()), count)
105 }
106
107 pub fn to(&self, program: &mut Program) {
108 match self {
109 Self::Deref(value) => {
110 value.to(program);
111 program.deref();
112 },
113
114 Self::Address(Address(address)) => {
115 program.right(*address);
116 }
117
118 Self::Offset(value, count) => {
119 value.to(program);
120 program.shift(*count);
121 }
122 }
123 }
124
125 pub fn from(&self, program: &mut Program) {
126 match self {
127 Self::Deref(value) => {
128 program.refer();
129 value.from(program);
130 },
131
132 Self::Address(Address(address)) => {
133 program.left(*address);
134 }
135
136 Self::Offset(value, count) => {
137 program.shift(-*count);
138 value.from(program);
139 }
140 }
141 }
142
143 pub fn zero(&self, program: &mut Program) {
144 self.to(program);
145 program.begin_loop();
146 program.minus(1);
147 program.end_loop();
148 self.from(program);
149 }
150
151 pub fn plus(&self, n: u32, program: &mut Program) {
152 self.to(program);
153 program.plus(n);
154 self.from(program);
155 }
156
157 pub fn inc(&self, program: &mut Program) {
158 self.to(program);
159 program.plus(1);
160 self.from(program);
161 }
162
163 pub fn minus(&self, n: u32, program: &mut Program) {
164 self.to(program);
165 program.minus(n);
166 self.from(program);
167 }
168
169 pub fn dec(&self, program: &mut Program) {
170 self.to(program);
171 program.minus(1);
172 self.from(program);
173 }
174
175 pub fn set(&self, value: u32, program: &mut Program) {
176 self.zero(program);
177 self.plus(value, program);
178 }
179
180 pub fn alloc(&self, program: &mut Program) {
181 self.to(program);
182 program.alloc();
183 self.from(program);
184 }
185
186 pub fn free(&self, program: &mut Program) {
187 self.to(program);
188 program.free();
189 program.zero();
190 self.from(program);
191 }
192
193 pub fn put(&self, program: &mut Program) {
194 self.to(program);
195 program.put();
196 self.from(program);
197 }
198
199 pub fn get(&self, program: &mut Program) {
200 self.to(program);
201 program.get();
202 self.from(program);
203 }
204
205 pub fn putnum(&self, program: &mut Program) {
206 self.to(program);
207 program.putnum();
208 self.from(program);
209 }
210
211 pub fn getnum(&self, program: &mut Program) {
212 self.to(program);
213 program.getnum();
214 self.from(program);
215 }
216
217
218 pub fn begin_loop(&self, program: &mut Program) {
219 self.to(program);
220 program.begin_loop();
221 self.from(program);
222 }
223
224 pub fn end_loop(&self, program: &mut Program) {
225 self.to(program);
226 program.end_loop();
227 self.from(program);
228 }
229
230 pub fn push(&self, program: &mut Program) {
231 SP.inc(program);
232 copy_cell(
233 SP.deref(),
234 self.clone(),
235 program
236 );
237 }
238
239 pub fn pop_into(&self, program: &mut Program) {
240 copy_cell(
241 self.clone(),
242 SP.deref(),
243 program
244 );
245 SP.dec(program);
247 }
248
249 pub fn load_ptr(&self, size: u32, program: &mut Program) {
250 for i in 0..size {
251 self.offset(i as i32).push(program);
252 }
253 }
254
255 pub fn store_ptr(&self, size: u32, program: &mut Program) {
256 for i in 0..size {
257 self.offset((size - i - 1) as i32).pop_into(program);
258 }
259 }
260}
261
262impl fmt::Display for Location {
263 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
264 match self {
265 Self::Address(loc) => if self == &SP {
266 write!(f, "SP")
267 } else if self == &FP {
268 write!(f, "FP")
269
270 } else if self == &TMP0 {
271 write!(f, "TMP0")
272 } else if self == &TMP1 {
273 write!(f, "TMP1")
274 } else if self == &TMP2 {
275 write!(f, "TMP2")
276 } else if self == &TMP3 {
277 write!(f, "TMP3")
278 } else if self == &TMP4 {
279 write!(f, "TMP4")
280 } else if self == &TMP5 {
281 write!(f, "TMP5")
282
283 } else if self == &R0 {
284 write!(f, "R0")
285 } else if self == &R1 {
286 write!(f, "R1")
287 } else if self == &R2 {
288 write!(f, "R2")
289 } else if self == &R3 {
290 write!(f, "R3")
291 } else if self == &R4 {
292 write!(f, "R4")
293 } else if self == &R5 {
294 write!(f, "R5")
295
296 } else {
297 write!(f, "{}", loc.0)
298 },
299 Self::Offset(inner, offset) => write!(f, "{} {} +", inner, offset),
300 Self::Deref(inner) => write!(f, "{}@", inner),
301 }
302 }
303}
304
305pub const TOTAL_REGISTERS: u32 = 14;
306
307
308pub const SP: Location = Location::Address(Address(0));
310
311pub const FP: Location = Location::Address(Address(3));
313
314pub const TMP0: Location = Location::Address(Address(1));
316pub const TMP1: Location = Location::Address(Address(2));
317pub const TMP2: Location = Location::Address(Address(4));
318pub const TMP3: Location = Location::Address(Address(5));
319pub const TMP4: Location = Location::Address(Address(6));
320pub const TMP5: Location = Location::Address(Address(7));
321
322pub const R0: Location = Location::Address(Address(8));
324pub const R1: Location = Location::Address(Address(9));
325pub const R2: Location = Location::Address(Address(10));
326pub const R3: Location = Location::Address(Address(11));
327pub const R4: Location = Location::Address(Address(12));
328pub const R5: Location = Location::Address(Address(13));
329
330#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
331pub enum Op {
332 Let(String, Vec<Self>, Vec<Self>),
333 Macro(String),
334
335 Frame(u32, u32, Vec<Self>),
336 Do(Vec<Self>),
337
338
339 Set(Literal),
341
342 StoreAt(Location, u32),
344
345 LoadFrom(Location, u32),
347
348 Store(u32),
350 Load(u32),
352
353 Alloc,
355 Free,
357 Duplicate,
359
360 Putchar,
362
363 Getchar,
365
366 Putnum,
368
369 Getnum,
371
372 While(Vec<Self>, Vec<Self>),
374
375 If(Vec<Self>, Vec<Self>),
377
378 Increment(Location, u32),
379 Decrement(Location, u32),
380
381 Not,
383
384 Or,
386
387 And,
389
390 Add,
392
393 Sub,
395
396 Mul,
398
399 Div,
401
402 Eq,
404
405 Neq,
407
408 Pop(Location),
410
411 PushLiteral(Literal),
413 PushAddress(Address),
415 Push(Location),
417
418 Stalloc(u32),
420 Stfree(u32),
422}
423
424pub fn copy_cell(x: Location, y: Location, program: &mut Program) {
425 TMP0.zero(program);
426 x.zero(program);
427
428 y.begin_loop(program);
429 x.inc(program);
430 TMP0.inc(program);
431 y.dec(program);
432 y.end_loop(program);
433
434 TMP0.begin_loop(program);
435 y.inc(program);
436 TMP0.dec(program);
437 TMP0.end_loop(program);
438}
439
440impl Op {
441 pub fn assemble(&self, program: &mut Program) -> Result<(), Error> {
442 self.assemble_with_scope(&BTreeMap::new(), program)
443 }
444
445 pub fn assemble_with_scope(&self, scope: &BTreeMap<String, Vec<Self>>, program: &mut Program) -> Result<(), Error> {
446 match self {
447 Self::Do(code) => {
448 for op in code {
449 op.assemble_with_scope(&scope, program)?;
450 }
451 }
452 Self::Let(name, val, ret) => {
453 let mut new_scope = scope.clone();
454 new_scope.insert(name.clone(), val.clone());
455
456 for op in ret {
457 op.assemble_with_scope(&new_scope, program)?;
458 }
459 }
460
461 Self::Macro(name) => {
462 if let Some(code) = scope.get(name) {
463 let mut new_scope = scope.clone();
464 new_scope.remove(name);
465 for op in code {
466 op.assemble_with_scope(&new_scope, program)?;
467 }
468 } else {
469 return Err(Error::MacroNotDefined(name.clone()));
470 }
471 }
472
473 Self::Frame(args_size, ret_size, code) => {
474 if *args_size > 0 {
477 Self::PushLiteral(Literal(*args_size)).assemble_with_scope(scope, program)?;
478 Self::Alloc.assemble_with_scope(scope, program)?;
479 Self::Duplicate.assemble_with_scope(scope, program)?;
480 TMP5.pop_into(program);
481 Self::Store(*args_size).assemble_with_scope(scope, program)?;
482 }
483
484
485 FP.push(program);
487 copy_cell(
488 FP,
489 SP,
490 program
491 );
492 FP.inc(program);
494
495 if *args_size > 0 {
496 TMP5.push(program);
498 Self::Load(*args_size).assemble_with_scope(scope, program)?;
499 TMP5.push(program);
501 Self::Free.assemble_with_scope(scope, program)?;
502 }
503 for op in code {
505 op.assemble_with_scope(scope, program)?;
506 }
507
508 if *ret_size > 0 {
509 Self::PushLiteral(Literal(*ret_size)).assemble_with_scope(scope, program)?;
511 Self::Alloc.assemble_with_scope(scope, program)?;
512 Self::Duplicate.assemble_with_scope(scope, program)?;
513 TMP5.pop_into(program);
514 Self::Store(*ret_size).assemble_with_scope(scope, program)?;
515 }
516 if *args_size > 0 {
517 Self::Stfree(*args_size).assemble_with_scope(scope, program)?;
519 }
520 FP.pop_into(program);
522
523 if *ret_size > 0 {
524 TMP5.push(program);
526 Self::Load(*ret_size).assemble_with_scope(scope, program)?;
527 TMP5.push(program);
528 Self::Free.assemble_with_scope(scope, program)?;
529 }
530 TMP5.zero(program);
531 }
532
533 Self::Pop(loc) => {
534 loc.pop_into(program);
535 },
536
537 Self::PushLiteral(Literal(n)) | Self::PushAddress(Address(n)) => {
538 SP.inc(program);
539 SP.deref().set(*n, program);
540 },
541
542 Self::Push(loc) => {
543 loc.push(program);
544 },
545
546 Self::Load(size) => {
547 TMP2.pop_into(program);
548 TMP2.deref().load_ptr(*size, program);
549 },
550
551 Self::Store(size) => {
552 SP.dec(program);
555 for i in 1..*size+1 {
556 SP.deref()
557 .offset(i as i32)
558 .deref()
559 .offset((*size - i) as i32)
560 .pop_into(program);
561 }
562 },
563
564 Self::LoadFrom(loc, size) => {
565 loc.load_ptr(*size, program);
566 },
567
568 Self::StoreAt(loc, size) => {
569 loc.store_ptr(*size, program);
570 },
571
572 Self::Stalloc(size) => {
573 if *size > 0 {
574 SP.plus(*size, program);
575 }
576 }
577
578 Self::Stfree(size) => {
579 if *size > 0 {
580 SP.minus(*size, program);
581 }
582 }
583
584 Self::Alloc => {
585 SP.deref().alloc(program);
586 }
587
588 Self::Free => {
589 SP.deref().free(program);
590 SP.dec(program);
591 }
592
593 Self::Duplicate => {
594 copy_cell(SP.deref().offset(1), SP.deref(), program);
595 SP.inc(program);
596 }
597
598 Self::Decrement(loc, n) => {
599 loc.minus(*n, program)
600 }
601
602 Self::Increment(loc, n) => {
603 loc.plus(*n, program)
604 }
605
606 Self::Not => {
607 let x = SP.deref();
608
609 TMP0.zero(program);
610 x.begin_loop(program);
611 TMP0.inc(program);
612 x.zero(program);
613 x.end_loop(program);
614 x.inc(program);
615
616 TMP0.begin_loop(program);
617 x.dec(program);
618 TMP0.dec(program);
619 TMP0.end_loop(program);
620 }
621
622 Self::Add | Self::Or => {
623 let x = SP.deref().offset(-1);
624 let y = SP.deref();
625
626 TMP0.zero(program);
628 y.begin_loop(program);
629 x.inc(program);
630 TMP0.inc(program);
631 y.dec(program);
632 y.end_loop(program);
633
634 TMP0.begin_loop(program);
635 y.inc(program);
636 TMP0.dec(program);
637 TMP0.end_loop(program);
638
639 SP.dec(program);
640 }
641
642 Self::Sub => {
643 let x = SP.deref().offset(-1);
644 let y = SP.deref();
645
646 TMP0.zero(program);
648 y.begin_loop(program);
649 x.dec(program);
650 TMP0.inc(program);
651 y.dec(program);
652 y.end_loop(program);
653
654 TMP0.begin_loop(program);
655 y.inc(program);
656 TMP0.dec(program);
657 TMP0.end_loop(program);
658
659 SP.dec(program);
660 }
661
662 Self::Mul | Self::And => {
663 let x = SP.deref().offset(-1);
664 let y = SP.deref();
665
666 TMP0.zero(program);
668 TMP1.zero(program);
669
670 x.begin_loop(program);
671 TMP1.inc(program);
672 x.dec(program);
673 x.end_loop(program);
674
675 TMP1.begin_loop(program);
676 y.begin_loop(program);
677 x.inc(program);
678 TMP0.inc(program);
679 y.dec(program);
680 y.end_loop(program);
681
682 TMP0.begin_loop(program);
683 y.inc(program);
684 TMP0.dec(program);
685 TMP0.end_loop(program);
686
687 TMP1.dec(program);
688 TMP1.end_loop(program);
689
690 SP.dec(program);
691 }
692
693 Self::Div => {
694 let x = SP.deref().offset(-1);
695 let y = SP.deref();
696
697 TMP0.zero(program);
699 TMP1.zero(program);
700 TMP2.zero(program);
701 TMP3.zero(program);
702
703 x.begin_loop(program);
704 TMP0.inc(program);
705 x.dec(program);
706 x.end_loop(program);
707
708 TMP0.begin_loop(program);
709
710 y.begin_loop(program);
711 TMP1.inc(program);
712 TMP2.inc(program);
713 y.dec(program);
714 y.end_loop(program);
715
716 TMP2.begin_loop(program);
717 y.inc(program);
718 TMP2.dec(program);
719 TMP2.end_loop(program);
720
721 TMP1.begin_loop(program);
722
723 TMP2.inc(program);
724 TMP0.dec(program);
725 TMP0.begin_loop(program);
726 TMP2.zero(program);
727 TMP3.inc(program);
728 TMP0.dec(program);
729 TMP0.end_loop(program);
730
731 TMP3.begin_loop(program);
732 TMP0.inc(program);
733 TMP3.dec(program);
734 TMP3.end_loop(program);
735
736 TMP2.begin_loop(program);
737 TMP1.dec(program);
738 TMP1.begin_loop(program);
739 x.dec(program);
740 TMP1.zero(program);
741 TMP1.end_loop(program);
742 TMP1.inc(program);
743
744 TMP2.dec(program);
745 TMP2.end_loop(program);
746 TMP1.dec(program);
747
748 TMP1.end_loop(program);
749 x.inc(program);
750 TMP0.end_loop(program);
751
752 SP.dec(program);
753 }
754
755 Self::If(cond, body) => {
756 let x = TMP2;
757 for op in cond {
758 op.assemble_with_scope(scope, program)?;
759 }
760 x.pop_into(program);
761 x.begin_loop(program);
762 for op in body {
763 op.assemble_with_scope(scope, program)?;
764 }
765 x.zero(program);
766 x.end_loop(program);
767 }
768
769 Self::While(cond, body) => {
770 for op in cond {
771 op.assemble_with_scope(scope, program)?;
772 }
773 SP.deref().begin_loop(program);
774 SP.dec(program);
775 for op in body {
776 op.assemble_with_scope(scope, program)?;
777 }
778 for op in cond {
779 op.assemble_with_scope(scope, program)?;
780 }
781 SP.deref().end_loop(program);
782 SP.dec(program);
783 }
784
785 Self::Eq => {
786 let x = SP.deref().offset(-1);
787 let y = SP.deref();
788 TMP0.zero(program);
794 TMP1.zero(program);
795
796 x.begin_loop(program);
797 TMP1.inc(program);
798 x.dec(program);
799 x.end_loop(program);
800 x.inc(program);
801
802 y.begin_loop(program);
803 TMP1.dec(program);
804 TMP0.inc(program);
805 y.dec(program);
806 y.end_loop(program);
807
808 TMP0.begin_loop(program);
809 y.inc(program);
810 TMP0.dec(program);
811 TMP0.end_loop(program);
812
813 TMP1.begin_loop(program);
814 x.dec(program);
815 TMP1.zero(program);
816 TMP1.end_loop(program);
817
818 SP.dec(program);
819 }
821
822 Self::Neq => {
823 Self::Eq.assemble_with_scope(scope, program)?;
824 Self::Not.assemble_with_scope(scope, program)?;
825 }
827
828 Self::Putnum => {
829 SP.deref().putnum(program);
830 SP.dec(program);
832 }
833 Self::Getnum => {
834 SP.inc(program);
837 SP.deref().getnum(program);
838 }
839
840 Self::Putchar => {
841 SP.deref().put(program);
843 SP.dec(program);
844 }
845 Self::Getchar => {
846 SP.inc(program);
849 SP.deref().get(program);
850 }
851
852 _ => unimplemented!()
853 }
854 Ok(())
855 }
856}