1use super::{
2 position::{Located, Position},
3 std::FOR_FUNC,
4};
5use crate::lang::{
6 ast::*,
7 code::{
8 Address, BinaryOperation, ByteCode, Closure, Location, ObjectSize, Register, Source,
9 Upvalue, VectorSize,
10 },
11 value::Value,
12};
13use std::{
14 cell::RefCell,
15 collections::{HashMap, HashSet},
16 error::Error,
17 rc::Rc,
18};
19
20#[derive(Debug, Default)]
21pub struct Compiler {
22 pub frames: Vec<CompilerFrame>,
23 pub path: Option<String>,
24}
25#[derive(Debug, Default)]
26pub struct CompilerFrame {
27 pub closure: Rc<RefCell<Closure>>,
28 pub(crate) scopes: Vec<Scope>,
29 pub(crate) registers: Register,
30}
31#[derive(Debug, Clone, Default)]
32pub struct Scope {
33 pub(crate) locals: HashMap<String, Register>,
34 pub(crate) register_offset: Register,
35 pub(crate) breaks: HashSet<Address>,
36 pub(crate) continues: HashSet<Address>,
37}
38pub trait Compilable {
39 type Output;
40 fn compile(self, compiler: &mut Compiler) -> Result<Self::Output, Located<Box<dyn Error>>>;
41}
42
43pub const COMPILER_FRAME_EXPECT: &str = "no compiler frame on stack";
44pub const COMPILER_SCOPE_EXPECT: &str = "no scope on stack";
45macro_rules! compiler_frame {
46 ($compiler:ident) => {
47 $compiler.frame().expect(COMPILER_FRAME_EXPECT)
48 };
49}
50macro_rules! compiler_frame_mut {
51 ($compiler:ident) => {
52 $compiler.frame_mut().expect(COMPILER_FRAME_EXPECT)
53 };
54}
55impl Compiler {
56 pub fn new(path: Option<String>) -> Self {
57 Self {
58 frames: vec![CompilerFrame {
59 closure: Rc::new(RefCell::new(Closure {
60 path: path.clone(),
61 ..Default::default()
62 })),
63 scopes: vec![Scope::default()],
64 registers: 0,
65 }],
66 path,
67 }
68 }
69 pub fn push_frame(&mut self, frame: CompilerFrame) {
70 self.frames.push(frame);
71 }
72 pub fn pop_frame(&mut self) -> Option<CompilerFrame> {
73 self.frames.pop()
74 }
75 pub fn frame(&self) -> Option<&CompilerFrame> {
76 self.frames.last()
77 }
78 pub fn frame_mut(&mut self) -> Option<&mut CompilerFrame> {
79 self.frames.last_mut()
80 }
81 pub fn get_variable_location(&mut self, ident: &str) -> Option<Location> {
82 if let Some(register) = self.frame_mut().expect("no frame").get_local(ident) {
83 return Some(Location::Register(register));
84 }
85 for (depth, other_frame) in self.frames.iter_mut().rev().skip(1).enumerate() {
86 if let Some(register) = other_frame.get_local(ident) {
87 let frame = self.frame_mut().expect("no frame");
88 let addr = frame.closure.borrow().upvalues.len() as Address;
89 let upvalue = Upvalue {
90 register,
91 depth: depth as u8,
92 };
93 if let Some(addr) = frame
94 .closure
95 .borrow_mut()
96 .upvalues
97 .iter()
98 .position(|upv| upv == &upvalue)
99 {
100 return Some(Location::Upvalue(addr as Address));
101 }
102 frame.closure.borrow_mut().upvalues.push(upvalue);
103 return Some(Location::Upvalue(addr));
104 }
105 }
106 None
107 }
108}
109impl CompilerFrame {
110 pub fn write(&mut self, bytecode: ByteCode, pos: Position) -> Address {
111 let addr = self.closure.borrow().code.len() as Address;
112 self.closure
113 .borrow_mut()
114 .code
115 .push(Located::new(bytecode, pos));
116 addr
117 }
118 pub fn overwrite(&mut self, addr: Address, bytecode: ByteCode, pos: Option<Position>) {
119 let mut closure = self.closure.borrow_mut();
120 let old = closure.code.get_mut(addr as usize).expect("invalid addr");
121 *old = Located::new(bytecode, pos.unwrap_or(old.pos.clone()));
122 }
123 pub fn addr(&self) -> Address {
124 self.closure.borrow().code.len() as Address
125 }
126 pub fn new_const(&mut self, value: Value) -> Address {
127 let consts = &mut self.closure.borrow_mut().consts;
128 if let Some(pos) = consts.iter().position(|v| v == &value) {
129 return pos as Address;
130 }
131 let addr = consts.len();
132 consts.push(value);
133 addr as Address
134 }
135 pub fn new_closure(&mut self, value: Rc<RefCell<Closure>>) -> Address {
136 let closures = &mut self.closure.borrow_mut().closures;
137 let addr = closures.len();
138 closures.push(value);
139 addr as Address
140 }
141 pub fn new_register(&mut self) -> Register {
142 let addr = self.registers;
143 self.registers += 1;
144 if self.registers > self.closure.borrow().registers {
145 self.closure.borrow_mut().registers = self.registers;
146 }
147 addr
148 }
149 pub fn add_registers(&mut self, amount: Register) {
150 self.registers += amount;
151 if self.registers > self.closure.borrow().registers {
152 self.closure.borrow_mut().registers = self.registers;
153 }
154 }
155 pub fn push_scope(&mut self) {
156 let register_offset = self.registers;
157 self.scopes.push(Scope {
158 register_offset,
159 ..Default::default()
160 });
161 }
162 pub fn pop_scope(&mut self) -> Option<Scope> {
163 if let Some(scope) = self.scopes.pop() {
164 self.registers = scope.register_offset;
165 return Some(scope);
166 }
167 None
168 }
169 pub fn scope(&self) -> Option<&Scope> {
170 self.scopes.last()
171 }
172 pub fn scope_mut(&mut self) -> Option<&mut Scope> {
173 self.scopes.last_mut()
174 }
175 pub fn new_local(&mut self, ident: String) -> Register {
176 let register = self.new_register();
177 let scope = self.scope_mut().expect("no scope");
178 scope.set_local(ident, register);
179 register
180 }
181 pub fn get_local(&self, ident: &str) -> Option<Register> {
182 self.scopes
183 .iter()
184 .rev()
185 .find(|scope| scope.get_local(ident).is_some())
186 .and_then(|scope| scope.get_local(ident))
187 }
188}
189impl Scope {
190 pub fn set_local(&mut self, ident: String, register: Register) -> Option<Register> {
191 self.locals.insert(ident, register)
192 }
193 pub fn get_local(&self, ident: &str) -> Option<Register> {
194 self.locals.get(ident).cloned()
195 }
196}
197
198impl Compilable for Located<Chunk> {
199 type Output = Rc<RefCell<Closure>>;
200 fn compile(self, compiler: &mut Compiler) -> Result<Self::Output, Located<Box<dyn Error>>> {
201 let Located { value: chunk, pos } = self;
202 compiler.push_frame(CompilerFrame {
203 closure: Rc::new(RefCell::new(Closure {
204 path: compiler.path.clone(),
205 ..Default::default()
206 })),
207 scopes: vec![Scope::default()],
208 registers: 0,
209 });
210 for stat in chunk.0 {
211 stat.compile(compiler)?;
212 }
213 compiler_frame_mut!(compiler).write(ByteCode::Return { src: None }, pos);
214 Ok(compiler
215 .pop_frame()
216 .expect("no compiler frame on stack")
217 .closure)
218 }
219}
220impl Compilable for Located<Block> {
221 type Output = Option<Source>;
222 fn compile(self, compiler: &mut Compiler) -> Result<Self::Output, Located<Box<dyn Error>>> {
223 let Located {
224 value: block,
225 pos: _,
226 } = self;
227 for stat in block.0 {
228 stat.compile(compiler)?;
229 }
230 Ok(None)
231 }
232}
233impl Compilable for Located<Statement> {
234 type Output = Option<Source>;
235 fn compile(self, compiler: &mut Compiler) -> Result<Self::Output, Located<Box<dyn Error>>> {
236 let Located { value: stat, pos } = self;
237 match stat {
238 Statement::Block(block) => {
239 compiler_frame_mut!(compiler).push_scope();
240 Located::new(block, pos).compile(compiler)?;
241 let scope = compiler_frame_mut!(compiler)
242 .pop_scope()
243 .expect("no scope on stack");
244 if !scope.breaks.is_empty() {
245 if let Some(prev_scope) = compiler_frame_mut!(compiler).scope_mut() {
246 prev_scope.breaks.extend(scope.breaks);
247 }
248 }
249 if !scope.continues.is_empty() {
250 if let Some(prev_scope) = compiler_frame_mut!(compiler).scope_mut() {
251 prev_scope.continues.extend(scope.continues);
252 }
253 }
254 Ok(None)
255 }
256 Statement::LetBinding { params, mut exprs } => {
257 for Located { value: param, pos } in params.into_iter() {
258 let src = if exprs.is_empty() {
259 Source::default()
260 } else {
261 exprs.remove(0).compile(compiler)?
262 };
263 match param {
264 Parameter::Ident(ident) => {
265 let dst =
266 Location::Register(compiler_frame_mut!(compiler).new_local(ident));
267 compiler_frame_mut!(compiler).write(ByteCode::Move { dst, src }, pos);
268 }
269 Parameter::Object(fields) => {
270 for Located { value: ident, pos } in fields.into_iter() {
271 let field = Source::Constant(
272 compiler_frame_mut!(compiler)
273 .new_const(Value::String(ident.clone())),
274 );
275 let dst = Location::Register(
276 compiler_frame_mut!(compiler).new_local(ident),
277 );
278 compiler_frame_mut!(compiler).write(
279 ByteCode::Field {
280 dst,
281 head: src,
282 field,
283 },
284 pos,
285 );
286 }
287 }
288 Parameter::Vector(idents) => {
289 for (idx, Located { value: ident, pos }) in
290 idents.into_iter().enumerate()
291 {
292 let field = Source::Constant(
293 compiler_frame_mut!(compiler)
294 .new_const(Value::Int(idx as isize as i64)),
295 );
296 let dst = Location::Register(
297 compiler_frame_mut!(compiler).new_local(ident),
298 );
299 compiler_frame_mut!(compiler).write(
300 ByteCode::Field {
301 dst,
302 head: src,
303 field,
304 },
305 pos,
306 );
307 }
308 }
309 }
310 }
311 Ok(None)
312 }
313 Statement::LetElse {
314 param:
315 Located {
316 value: param,
317 pos: _,
318 },
319 expr,
320 else_case,
321 } => {
322 let cond = expr.compile(compiler)?;
323 match param {
324 Parameter::Ident(ident) => {
325 let dst =
326 Location::Register(compiler_frame_mut!(compiler).new_local(ident));
327 compiler_frame_mut!(compiler).write(ByteCode::Move { dst, src: cond }, pos.clone());
328 }
329 Parameter::Object(fields) => {
330 for Located { value: ident, pos } in fields.into_iter() {
331 let field = Source::Constant(
332 compiler_frame_mut!(compiler)
333 .new_const(Value::String(ident.clone())),
334 );
335 let dst =
336 Location::Register(compiler_frame_mut!(compiler).new_local(ident));
337 compiler_frame_mut!(compiler).write(
338 ByteCode::Field {
339 dst,
340 head: cond,
341 field,
342 },
343 pos,
344 );
345 }
346 }
347 Parameter::Vector(idents) => {
348 for (idx, Located { value: ident, pos }) in idents.into_iter().enumerate() {
349 let field = Source::Constant(
350 compiler_frame_mut!(compiler)
351 .new_const(Value::Int(idx as isize as i64)),
352 );
353 let dst =
354 Location::Register(compiler_frame_mut!(compiler).new_local(ident));
355 compiler_frame_mut!(compiler).write(
356 ByteCode::Field {
357 dst,
358 head: cond,
359 field,
360 },
361 pos,
362 );
363 }
364 }
365 }
366 let check_addr =
367 compiler_frame_mut!(compiler).write(ByteCode::default(), Position::default());
368 compiler_frame_mut!(compiler).push_scope();
369 else_case.compile(compiler)?;
370 let scope = compiler_frame_mut!(compiler)
371 .pop_scope()
372 .expect(COMPILER_SCOPE_EXPECT);
373 if !scope.breaks.is_empty() {
374 if let Some(prev_scope) = compiler_frame_mut!(compiler).scope_mut() {
375 prev_scope.breaks.extend(scope.breaks);
376 }
377 }
378 if !scope.continues.is_empty() {
379 if let Some(prev_scope) = compiler_frame_mut!(compiler).scope_mut() {
380 prev_scope.continues.extend(scope.continues);
381 }
382 }
383 let exit_addr = compiler_frame_mut!(compiler).addr();
384 compiler_frame_mut!(compiler).overwrite(
385 check_addr,
386 ByteCode::JumpNull {
387 negative: true,
388 cond,
389 addr: exit_addr + 1,
390 },
391 Some(pos.clone()),
392 );
393 Ok(None)
394 }
395 Statement::Assign { paths, mut exprs } => {
396 for Located {
397 value: path,
398 pos: path_pos,
399 } in paths.into_iter()
400 {
401 let src = if exprs.is_empty() {
402 Source::default()
403 } else {
404 exprs.remove(0).compile(compiler)?
405 };
406 match path {
407 Path::Ident(ident) => {
408 let dst = compiler.get_variable_location(&ident).unwrap_or_else(|| {
409 let addr =
410 compiler_frame_mut!(compiler).new_const(Value::String(ident));
411 Location::Global(addr)
412 });
413 compiler_frame_mut!(compiler)
414 .write(ByteCode::Move { dst, src }, path_pos);
415 }
416 Path::Field {
417 head,
418 field:
419 Located {
420 value: field,
421 pos: _,
422 },
423 } => {
424 let head = head.compile(compiler)?;
425 let field =
426 compiler_frame_mut!(compiler).new_const(Value::String(field));
427 compiler_frame_mut!(compiler).write(
428 ByteCode::SetField {
429 head: head.into(),
430 field: Source::Constant(field),
431 src,
432 },
433 path_pos,
434 );
435 }
436 Path::Index { head, index } => {
437 let head = head.compile(compiler)?;
438 let field = index.compile(compiler)?;
439 compiler_frame_mut!(compiler).write(
440 ByteCode::SetField {
441 head: head.into(),
442 field,
443 src,
444 },
445 path_pos,
446 );
447 }
448 }
449 }
450 Ok(None)
451 }
452 Statement::AssignOperation {
453 op,
454 path:
455 Located {
456 value: path,
457 pos: path_pos,
458 },
459 expr,
460 } => {
461 let src = expr.compile(compiler)?;
462 match path {
463 Path::Ident(ident) => {
464 let dst = compiler.get_variable_location(&ident).unwrap_or_else(|| {
465 let addr =
466 compiler_frame_mut!(compiler).new_const(Value::String(ident));
467 Location::Global(addr)
468 });
469 compiler_frame_mut!(compiler).write(
470 ByteCode::Binary {
471 op: op.into(),
472 dst,
473 left: dst.into(),
474 right: src,
475 },
476 path_pos,
477 );
478 }
479 Path::Field {
480 head,
481 field:
482 Located {
483 value: field,
484 pos: _,
485 },
486 } => {
487 let head = head.compile(compiler)?;
488 let field = compiler_frame_mut!(compiler).new_const(Value::String(field));
489 let dst = compiler_frame_mut!(compiler).new_register();
490 compiler_frame_mut!(compiler).write(
491 ByteCode::Field {
492 dst: Location::Register(dst),
493 head: head.into(),
494 field: Source::Constant(field),
495 },
496 path_pos.clone(),
497 );
498 compiler_frame_mut!(compiler).write(
499 ByteCode::Binary {
500 op: op.into(),
501 dst: Location::Register(dst),
502 left: Source::Register(dst),
503 right: src,
504 },
505 path_pos.clone(),
506 );
507 compiler_frame_mut!(compiler).write(
508 ByteCode::SetField {
509 head: head.into(),
510 field: Source::Constant(field),
511 src: Source::Register(dst),
512 },
513 path_pos,
514 );
515 }
516 Path::Index { head, index } => {
517 let head = head.compile(compiler)?;
518 let field = index.compile(compiler)?;
519 let dst = compiler_frame_mut!(compiler).new_register();
520 compiler_frame_mut!(compiler).write(
521 ByteCode::Field {
522 dst: Location::Register(dst),
523 head: head.into(),
524 field,
525 },
526 path_pos.clone(),
527 );
528 compiler_frame_mut!(compiler).write(
529 ByteCode::Binary {
530 op: op.into(),
531 dst: Location::Register(dst),
532 left: Source::Register(dst),
533 right: src,
534 },
535 path_pos.clone(),
536 );
537 compiler_frame_mut!(compiler).write(
538 ByteCode::SetField {
539 head: head.into(),
540 field,
541 src: Source::Register(dst),
542 },
543 path_pos,
544 );
545 }
546 }
547 Ok(None)
548 }
549 Statement::Call { path, mut args } => {
550 let path_location = path.compile(compiler)?;
551 let amount = args.len() as u8;
552 match amount {
553 0 => {
554 compiler_frame_mut!(compiler).write(
555 ByteCode::CallZero {
556 dst: None,
557 func: path_location.into(),
558 },
559 pos,
560 );
561 }
562 1 => {
563 let arg = args.remove(0).compile(compiler)?;
564 compiler_frame_mut!(compiler).write(
565 ByteCode::CallSingle {
566 dst: None,
567 func: path_location.into(),
568 arg,
569 },
570 pos,
571 );
572 }
573 amount => {
574 let offset = compiler_frame_mut!(compiler).registers;
575 compiler_frame_mut!(compiler).add_registers(amount as Register);
576 for (register, arg) in
577 (offset..offset + amount as Register).zip(args.into_iter())
578 {
579 let pos = arg.pos.clone();
580 let src = arg.compile(compiler)?;
581 compiler_frame_mut!(compiler).write(
582 ByteCode::Move {
583 dst: Location::Register(register),
584 src,
585 },
586 pos,
587 );
588 }
589 compiler_frame_mut!(compiler).registers = offset;
590 compiler_frame_mut!(compiler).write(
591 ByteCode::Call {
592 dst: None,
593 func: path_location.into(),
594 offset,
595 amount,
596 },
597 pos,
598 );
599 }
600 }
601 Ok(None)
602 }
603 Statement::SelfCall {
604 head,
605 field:
606 Located {
607 value: field,
608 pos: field_pos,
609 },
610 args,
611 } => {
612 let head_pos = head.pos.clone();
613 let head_location = head.compile(compiler)?;
614 let func = {
615 let head: Source = head_location.into();
616 let dst = compiler_frame_mut!(compiler).new_register();
617 let field_addr = compiler_frame_mut!(compiler).new_const(Value::String(field));
618 compiler_frame_mut!(compiler).write(
619 ByteCode::Field {
620 dst: Location::Register(dst),
621 head,
622 field: Source::Constant(field_addr),
623 },
624 field_pos,
625 );
626 Source::Register(dst)
627 };
628 let amount = args.len() as u8 + 1;
629 match amount {
630 1 => {
631 let offset = compiler_frame_mut!(compiler).registers;
632 let arg = head_location.into();
633 compiler_frame_mut!(compiler).registers = offset;
634 compiler_frame_mut!(compiler).write(
635 ByteCode::CallSingle {
636 dst: None,
637 func,
638 arg,
639 },
640 pos,
641 );
642 }
643 amount => {
644 let offset = compiler_frame_mut!(compiler).registers;
645 let head_register = compiler_frame_mut!(compiler).new_register();
646 compiler_frame_mut!(compiler).write(
647 ByteCode::Move {
648 dst: Location::Register(head_register),
649 src: head_location.into(),
650 },
651 head_pos,
652 );
653 compiler_frame_mut!(compiler).registers += amount as Register;
654 for (register, arg) in
655 (offset + 1..offset + amount as Register).zip(args.into_iter())
656 {
657 let pos = arg.pos.clone();
658 let src = arg.compile(compiler)?;
659 compiler_frame_mut!(compiler).write(
660 ByteCode::Move {
661 dst: Location::Register(register),
662 src,
663 },
664 pos,
665 );
666 }
667 compiler_frame_mut!(compiler).registers = offset;
668 compiler_frame_mut!(compiler).write(
669 ByteCode::Call {
670 dst: None,
671 func,
672 offset,
673 amount,
674 },
675 pos,
676 );
677 }
678 }
679 Ok(None)
680 }
681 Statement::Fn {
682 path:
683 Located {
684 value: path,
685 pos: path_pos,
686 },
687 params,
688 var_args: _,
689 body,
690 } => {
691 compiler.push_frame(CompilerFrame {
692 closure: Rc::new(RefCell::new(Closure {
693 path: compiler.path.clone(),
694 ..Default::default()
695 })),
696 scopes: vec![Scope::default()],
697 registers: 0,
698 });
699 for Located {
700 value: param,
701 pos: _,
702 } in params
703 {
704 match param {
705 Parameter::Ident(ident) => {
706 compiler_frame_mut!(compiler).new_local(ident);
707 }
708 Parameter::Object(fields) => {
709 let head =
710 Source::Register(compiler_frame_mut!(compiler).new_register());
711 for Located { value: ident, pos } in fields.into_iter() {
712 let field = Source::Constant(
713 compiler_frame_mut!(compiler)
714 .new_const(Value::String(ident.clone())),
715 );
716 let dst = Location::Register(
717 compiler_frame_mut!(compiler).new_local(ident),
718 );
719 compiler_frame_mut!(compiler)
720 .write(ByteCode::Field { dst, head, field }, pos);
721 }
722 }
723 Parameter::Vector(idents) => {
724 let head =
725 Source::Register(compiler_frame_mut!(compiler).new_register());
726 for (idx, Located { value: ident, pos }) in
727 idents.into_iter().enumerate()
728 {
729 let field = Source::Constant(
730 compiler_frame_mut!(compiler)
731 .new_const(Value::Int(idx as isize as i64)),
732 );
733 let dst = Location::Register(
734 compiler_frame_mut!(compiler).new_local(ident),
735 );
736 compiler_frame_mut!(compiler)
737 .write(ByteCode::Field { dst, head, field }, pos);
738 }
739 }
740 }
741 }
742 body.compile(compiler)?;
743 compiler_frame_mut!(compiler).write(ByteCode::Return { src: None }, pos.clone());
744 let closure = compiler
745 .pop_frame()
746 .expect("no compiler frame on stack")
747 .closure;
748 let addr = compiler_frame_mut!(compiler).new_closure(closure);
749 match path {
750 Path::Ident(ident) => {
751 let dst = compiler.get_variable_location(&ident).unwrap_or_else(|| {
752 let addr =
753 compiler_frame_mut!(compiler).new_const(Value::String(ident));
754 Location::Global(addr)
755 });
756 compiler_frame_mut!(compiler).write(ByteCode::Function { dst, addr }, pos);
757 }
758 Path::Field {
759 head,
760 field:
761 Located {
762 value: field,
763 pos: _,
764 },
765 } => {
766 let head = head.compile(compiler)?;
767 let field = compiler_frame_mut!(compiler).new_const(Value::String(field));
768 let register = compiler_frame_mut!(compiler).new_register();
769 compiler_frame_mut!(compiler).write(
770 ByteCode::Function {
771 dst: Location::Register(register),
772 addr,
773 },
774 path_pos.clone(),
775 );
776 compiler_frame_mut!(compiler).write(
777 ByteCode::SetField {
778 head: head.into(),
779 field: Source::Constant(field),
780 src: Source::Register(register),
781 },
782 path_pos,
783 );
784 compiler_frame_mut!(compiler).registers = register;
785 }
786 Path::Index { head, index } => {
787 let head = head.compile(compiler)?;
788 let field = index.compile(compiler)?;
789 let register = compiler_frame_mut!(compiler).new_register();
790 compiler_frame_mut!(compiler).write(
791 ByteCode::Function {
792 dst: Location::Register(register),
793 addr,
794 },
795 path_pos.clone(),
796 );
797 compiler_frame_mut!(compiler).write(
798 ByteCode::SetField {
799 head: head.into(),
800 field,
801 src: Source::Register(register),
802 },
803 path_pos,
804 );
805 compiler_frame_mut!(compiler).registers = register;
806 }
807 }
808 Ok(None)
809 }
810 Statement::LetFn {
811 ident:
812 Located {
813 value: ident,
814 pos: _,
815 },
816 params,
817 var_args: _,
818 body,
819 } => {
820 let dst = Location::Register(compiler_frame_mut!(compiler).new_local(ident));
821 compiler.push_frame(CompilerFrame {
822 closure: Rc::new(RefCell::new(Closure::default())),
823 scopes: vec![Scope::default()],
824 registers: 0,
825 });
826 for Located {
827 value: param,
828 pos: _,
829 } in params
830 {
831 match param {
832 Parameter::Ident(ident) => {
833 compiler_frame_mut!(compiler).new_local(ident);
834 }
835 Parameter::Object(fields) => {
836 let head =
837 Source::Register(compiler_frame_mut!(compiler).new_register());
838 for Located { value: ident, pos } in fields.into_iter() {
839 let field = Source::Constant(
840 compiler_frame_mut!(compiler)
841 .new_const(Value::String(ident.clone())),
842 );
843 let dst = Location::Register(
844 compiler_frame_mut!(compiler).new_local(ident),
845 );
846 compiler_frame_mut!(compiler)
847 .write(ByteCode::Field { dst, head, field }, pos);
848 }
849 }
850 Parameter::Vector(idents) => {
851 let head =
852 Source::Register(compiler_frame_mut!(compiler).new_register());
853 for (idx, Located { value: ident, pos }) in
854 idents.into_iter().enumerate()
855 {
856 let field = Source::Constant(
857 compiler_frame_mut!(compiler)
858 .new_const(Value::Int(idx as isize as i64)),
859 );
860 let dst = Location::Register(
861 compiler_frame_mut!(compiler).new_local(ident),
862 );
863 compiler_frame_mut!(compiler)
864 .write(ByteCode::Field { dst, head, field }, pos);
865 }
866 }
867 }
868 }
869 body.compile(compiler)?;
870 compiler_frame_mut!(compiler).write(ByteCode::Return { src: None }, pos.clone());
871 let closure = compiler
872 .pop_frame()
873 .expect("no compiler frame on stack")
874 .closure;
875 let addr = compiler_frame_mut!(compiler).new_closure(closure);
876 compiler_frame_mut!(compiler).write(ByteCode::Function { dst, addr }, pos);
877 Ok(None)
878 }
879 Statement::If {
880 cond,
881 case,
882 else_case,
883 } => {
884 let cond = cond.compile(compiler)?;
885 let check_addr =
886 compiler_frame_mut!(compiler).write(ByteCode::default(), Position::default());
887
888 compiler_frame_mut!(compiler).push_scope();
889 case.compile(compiler)?;
890 let scope = compiler_frame_mut!(compiler)
891 .pop_scope()
892 .expect(COMPILER_SCOPE_EXPECT);
893 if !scope.breaks.is_empty() {
894 if let Some(prev_scope) = compiler_frame_mut!(compiler).scope_mut() {
895 prev_scope.breaks.extend(scope.breaks);
896 }
897 }
898 if !scope.continues.is_empty() {
899 if let Some(prev_scope) = compiler_frame_mut!(compiler).scope_mut() {
900 prev_scope.continues.extend(scope.continues);
901 }
902 }
903 if let Some(else_case) = else_case {
904 let else_addr = compiler_frame_mut!(compiler)
905 .write(ByteCode::default(), Position::default());
906 compiler_frame_mut!(compiler).push_scope();
907 else_case.compile(compiler)?;
908 let scope = compiler_frame_mut!(compiler)
909 .pop_scope()
910 .expect(COMPILER_SCOPE_EXPECT);
911 if !scope.breaks.is_empty() {
912 if let Some(prev_scope) = compiler_frame_mut!(compiler).scope_mut() {
913 prev_scope.breaks.extend(scope.breaks);
914 }
915 }
916 if !scope.continues.is_empty() {
917 if let Some(prev_scope) = compiler_frame_mut!(compiler).scope_mut() {
918 prev_scope.continues.extend(scope.continues);
919 }
920 }
921 let exit_addr = compiler_frame_mut!(compiler).addr();
922 compiler_frame_mut!(compiler).overwrite(
923 check_addr,
924 ByteCode::JumpIf {
925 negative: true,
926 cond,
927 addr: else_addr + 1,
928 },
929 Some(pos.clone()),
930 );
931 compiler_frame_mut!(compiler).overwrite(
932 else_addr,
933 ByteCode::Jump { addr: exit_addr },
934 Some(pos),
935 );
936 } else {
937 let exit_addr = compiler_frame_mut!(compiler).addr();
938 compiler_frame_mut!(compiler).overwrite(
939 check_addr,
940 ByteCode::JumpIf {
941 negative: true,
942 cond,
943 addr: exit_addr,
944 },
945 Some(pos.clone()),
946 );
947 }
948
949 Ok(None)
950 }
951 Statement::IfLet {
952 param:
953 Located {
954 value: param,
955 pos: _,
956 },
957 expr,
958 case,
959 else_case,
960 } => {
961 compiler_frame_mut!(compiler).push_scope();
962 let cond = {
963 let src = expr.compile(compiler)?;
964 match param {
965 Parameter::Ident(ident) => {
966 let dst =
967 Location::Register(compiler_frame_mut!(compiler).new_local(ident));
968 compiler_frame_mut!(compiler)
969 .write(ByteCode::Move { dst, src }, pos.clone());
970 }
971 Parameter::Object(fields) => {
972 for Located { value: ident, pos } in fields.into_iter() {
973 let field = Source::Constant(
974 compiler_frame_mut!(compiler)
975 .new_const(Value::String(ident.clone())),
976 );
977 let dst = Location::Register(
978 compiler_frame_mut!(compiler).new_local(ident),
979 );
980 compiler_frame_mut!(compiler).write(
981 ByteCode::Field {
982 dst,
983 head: src,
984 field,
985 },
986 pos,
987 );
988 }
989 }
990 Parameter::Vector(idents) => {
991 for (idx, Located { value: ident, pos }) in
992 idents.into_iter().enumerate()
993 {
994 let field = Source::Constant(
995 compiler_frame_mut!(compiler)
996 .new_const(Value::Int(idx as isize as i64)),
997 );
998 let dst = Location::Register(
999 compiler_frame_mut!(compiler).new_local(ident),
1000 );
1001 compiler_frame_mut!(compiler).write(
1002 ByteCode::Field {
1003 dst,
1004 head: src,
1005 field,
1006 },
1007 pos,
1008 );
1009 }
1010 }
1011 }
1012 src
1013 };
1014 let check_addr =
1015 compiler_frame_mut!(compiler).write(ByteCode::default(), Position::default());
1016
1017 case.compile(compiler)?;
1018 let scope = compiler_frame_mut!(compiler)
1019 .pop_scope()
1020 .expect(COMPILER_SCOPE_EXPECT);
1021 if !scope.breaks.is_empty() {
1022 if let Some(prev_scope) = compiler_frame_mut!(compiler).scope_mut() {
1023 prev_scope.breaks.extend(scope.breaks);
1024 }
1025 }
1026 if !scope.continues.is_empty() {
1027 if let Some(prev_scope) = compiler_frame_mut!(compiler).scope_mut() {
1028 prev_scope.continues.extend(scope.continues);
1029 }
1030 }
1031 if let Some(else_case) = else_case {
1032 let else_addr = compiler_frame_mut!(compiler)
1033 .write(ByteCode::default(), Position::default());
1034 compiler_frame_mut!(compiler).push_scope();
1035 else_case.compile(compiler)?;
1036 let scope = compiler_frame_mut!(compiler)
1037 .pop_scope()
1038 .expect(COMPILER_SCOPE_EXPECT);
1039 if !scope.breaks.is_empty() {
1040 if let Some(prev_scope) = compiler_frame_mut!(compiler).scope_mut() {
1041 prev_scope.breaks.extend(scope.breaks);
1042 }
1043 }
1044 if !scope.continues.is_empty() {
1045 if let Some(prev_scope) = compiler_frame_mut!(compiler).scope_mut() {
1046 prev_scope.continues.extend(scope.continues);
1047 }
1048 }
1049 let exit_addr = compiler_frame_mut!(compiler).addr();
1050 compiler_frame_mut!(compiler).overwrite(
1051 check_addr,
1052 ByteCode::JumpNull {
1053 negative: false,
1054 cond,
1055 addr: else_addr + 1,
1056 },
1057 Some(pos.clone()),
1058 );
1059 compiler_frame_mut!(compiler).overwrite(
1060 else_addr,
1061 ByteCode::Jump { addr: exit_addr },
1062 Some(pos),
1063 );
1064 } else {
1065 let exit_addr = compiler_frame_mut!(compiler).addr();
1066 compiler_frame_mut!(compiler).overwrite(
1067 check_addr,
1068 ByteCode::JumpNull {
1069 negative: false,
1070 cond,
1071 addr: exit_addr,
1072 },
1073 Some(pos.clone()),
1074 );
1075 }
1076
1077 Ok(None)
1078 }
1079 Statement::Match { expr, cases } => {
1080 let expr = expr.compile(compiler)?;
1081 let registers = compiler_frame!(compiler).registers;
1082 let dst = Location::Register(compiler_frame_mut!(compiler).new_register());
1083 let mut exits = vec![];
1084 for (pattern, body) in cases {
1085 compiler_frame_mut!(compiler).push_scope();
1086 pattern.compile_match(compiler, expr, dst)?;
1087 let check_addr = compiler_frame_mut!(compiler)
1088 .write(ByteCode::default(), Position::default());
1089 body.compile(compiler)?;
1090 let scope = compiler_frame_mut!(compiler)
1091 .pop_scope()
1092 .expect(COMPILER_SCOPE_EXPECT);
1093 if !scope.breaks.is_empty() {
1094 if let Some(prev_scope) = compiler_frame_mut!(compiler).scope_mut() {
1095 prev_scope.breaks.extend(scope.breaks);
1096 }
1097 }
1098 if !scope.continues.is_empty() {
1099 if let Some(prev_scope) = compiler_frame_mut!(compiler).scope_mut() {
1100 prev_scope.continues.extend(scope.continues);
1101 }
1102 }
1103 let exit_addr = compiler_frame_mut!(compiler)
1104 .write(ByteCode::default(), Position::default());
1105 compiler_frame_mut!(compiler).overwrite(
1106 check_addr,
1107 ByteCode::JumpIf {
1108 negative: true,
1109 cond: dst.into(),
1110 addr: exit_addr + 1,
1111 },
1112 Some(pos.clone()),
1113 );
1114 exits.push(exit_addr);
1115 }
1116 let exit_addr = compiler_frame_mut!(compiler).addr();
1117 for addr in exits {
1118 if addr + 1 != exit_addr {
1119 compiler_frame_mut!(compiler).overwrite(
1120 addr,
1121 ByteCode::Jump { addr: exit_addr },
1122 Some(pos.clone()),
1123 );
1124 }
1125 }
1126 compiler_frame_mut!(compiler).registers = registers;
1127 Ok(None)
1128 }
1129 Statement::While { cond, body } => {
1130 let start_addr = compiler_frame_mut!(compiler).addr();
1131 let cond = cond.compile(compiler)?;
1132 let check_addr =
1133 compiler_frame_mut!(compiler).write(ByteCode::default(), Position::default());
1134 compiler_frame_mut!(compiler).push_scope();
1135 body.compile(compiler)?;
1136 let scope = compiler_frame_mut!(compiler)
1137 .pop_scope()
1138 .expect(COMPILER_SCOPE_EXPECT);
1139 let exit_addr = compiler_frame_mut!(compiler)
1140 .write(ByteCode::Jump { addr: start_addr }, pos.clone());
1141 for addr in scope.breaks {
1142 compiler_frame_mut!(compiler).overwrite(
1143 addr,
1144 ByteCode::Jump {
1145 addr: exit_addr + 1,
1146 },
1147 None,
1148 );
1149 }
1150 for addr in scope.continues {
1151 compiler_frame_mut!(compiler).overwrite(
1152 addr,
1153 ByteCode::Jump { addr: start_addr },
1154 None,
1155 );
1156 }
1157 compiler_frame_mut!(compiler).overwrite(
1158 check_addr,
1159 ByteCode::JumpIf {
1160 negative: true,
1161 cond,
1162 addr: exit_addr + 1,
1163 },
1164 Some(pos),
1165 );
1166 Ok(None)
1167 }
1168 Statement::WhileLet {
1169 param:
1170 Located {
1171 value: param,
1172 pos: _,
1173 },
1174 expr,
1175 body,
1176 } => {
1177 let start_addr = compiler_frame_mut!(compiler).addr();
1178 let cond = {
1179 let src = expr.compile(compiler)?;
1180 match param {
1181 Parameter::Ident(ident) => {
1182 let dst =
1183 Location::Register(compiler_frame_mut!(compiler).new_local(ident));
1184 compiler_frame_mut!(compiler)
1185 .write(ByteCode::Move { dst, src }, pos.clone());
1186 }
1187 Parameter::Object(fields) => {
1188 for Located { value: ident, pos } in fields.into_iter() {
1189 let field = Source::Constant(
1190 compiler_frame_mut!(compiler)
1191 .new_const(Value::String(ident.clone())),
1192 );
1193 let dst = Location::Register(
1194 compiler_frame_mut!(compiler).new_local(ident),
1195 );
1196 compiler_frame_mut!(compiler).write(
1197 ByteCode::Field {
1198 dst,
1199 head: src,
1200 field,
1201 },
1202 pos,
1203 );
1204 }
1205 }
1206 Parameter::Vector(idents) => {
1207 for (idx, Located { value: ident, pos }) in
1208 idents.into_iter().enumerate()
1209 {
1210 let field = Source::Constant(
1211 compiler_frame_mut!(compiler)
1212 .new_const(Value::Int(idx as isize as i64)),
1213 );
1214 let dst = Location::Register(
1215 compiler_frame_mut!(compiler).new_local(ident),
1216 );
1217 compiler_frame_mut!(compiler).write(
1218 ByteCode::Field {
1219 dst,
1220 head: src,
1221 field,
1222 },
1223 pos,
1224 );
1225 }
1226 }
1227 }
1228 src
1229 };
1230 let check_addr =
1231 compiler_frame_mut!(compiler).write(ByteCode::default(), Position::default());
1232 compiler_frame_mut!(compiler).push_scope();
1233 body.compile(compiler)?;
1234 let scope = compiler_frame_mut!(compiler)
1235 .pop_scope()
1236 .expect(COMPILER_SCOPE_EXPECT);
1237 let exit_addr = compiler_frame_mut!(compiler)
1238 .write(ByteCode::Jump { addr: start_addr }, pos.clone());
1239 for addr in scope.breaks {
1240 compiler_frame_mut!(compiler).overwrite(
1241 addr,
1242 ByteCode::Jump {
1243 addr: exit_addr + 1,
1244 },
1245 None,
1246 );
1247 }
1248 for addr in scope.continues {
1249 compiler_frame_mut!(compiler).overwrite(
1250 addr,
1251 ByteCode::Jump { addr: start_addr },
1252 None,
1253 );
1254 }
1255 compiler_frame_mut!(compiler).overwrite(
1256 check_addr,
1257 ByteCode::JumpNull {
1258 negative: false,
1259 cond,
1260 addr: exit_addr + 1,
1261 },
1262 Some(pos),
1263 );
1264 Ok(None)
1265 }
1266 Statement::For {
1267 ident:
1268 Located {
1269 value: ident,
1270 pos: _,
1271 },
1272 iter,
1273 body,
1274 } => {
1275 let iter = iter.compile(compiler)?;
1283 let register = compiler_frame_mut!(compiler).new_local(ident);
1284 let func = Source::Global(
1285 compiler_frame_mut!(compiler).new_const(Value::String(FOR_FUNC.into())),
1286 );
1287 let start_addr = compiler_frame_mut!(compiler).write(
1288 ByteCode::CallSingle {
1289 dst: Some(Location::Register(register)),
1290 func,
1291 arg: iter,
1292 },
1293 pos.clone(),
1294 );
1295 let check_addr =
1296 compiler_frame_mut!(compiler).write(ByteCode::default(), Position::default());
1297 compiler_frame_mut!(compiler).push_scope();
1298 body.compile(compiler)?;
1299 let scope = compiler_frame_mut!(compiler)
1300 .pop_scope()
1301 .expect(COMPILER_SCOPE_EXPECT);
1302 let exit_addr = compiler_frame_mut!(compiler)
1303 .write(ByteCode::Jump { addr: start_addr }, pos.clone());
1304 for addr in scope.breaks {
1305 compiler_frame_mut!(compiler).overwrite(
1306 addr,
1307 ByteCode::Jump {
1308 addr: exit_addr + 1,
1309 },
1310 None,
1311 );
1312 }
1313 for addr in scope.continues {
1314 compiler_frame_mut!(compiler).overwrite(
1315 addr,
1316 ByteCode::Jump { addr: start_addr },
1317 None,
1318 );
1319 }
1320 compiler_frame_mut!(compiler).overwrite(
1321 check_addr,
1322 ByteCode::JumpNull {
1323 negative: false,
1324 cond: Source::Register(register),
1325 addr: exit_addr + 1,
1326 },
1327 Some(pos),
1328 );
1329 Ok(None)
1330 }
1331 Statement::Return(expr) => {
1332 if let Some(expr) = expr {
1333 let src = expr.compile(compiler)?;
1334 compiler_frame_mut!(compiler).write(ByteCode::Return { src: Some(src) }, pos);
1335 Ok(Some(src))
1336 } else {
1337 compiler_frame_mut!(compiler).write(ByteCode::Return { src: None }, pos);
1338 Ok(Some(Source::Null))
1339 }
1340 }
1341 Statement::Break => {
1342 let addr = compiler_frame_mut!(compiler).write(ByteCode::None, pos);
1343 compiler_frame_mut!(compiler)
1344 .scope_mut()
1345 .expect(COMPILER_SCOPE_EXPECT)
1346 .breaks
1347 .insert(addr);
1348 Ok(None)
1349 }
1350 Statement::Continue => {
1351 let addr = compiler_frame_mut!(compiler).write(ByteCode::None, pos);
1352 compiler_frame_mut!(compiler)
1353 .scope_mut()
1354 .expect(COMPILER_SCOPE_EXPECT)
1355 .continues
1356 .insert(addr);
1357 Ok(None)
1358 }
1359 }
1360 }
1361}
1362impl Located<Pattern> {
1363 fn compile_match(
1364 self,
1365 compiler: &mut Compiler,
1366 expr: Source,
1367 dst: Location,
1368 ) -> Result<(), Located<Box<dyn Error>>> {
1369 let Located {
1370 value: pattern,
1371 pos,
1372 } = self;
1373 match pattern {
1374 Pattern::Ident(ident) => {
1375 let ident = compiler_frame_mut!(compiler).new_local(ident);
1376 compiler_frame_mut!(compiler).write(
1377 ByteCode::Move {
1378 dst: Location::Register(ident),
1379 src: expr,
1380 },
1381 pos.clone(),
1382 );
1383 compiler_frame_mut!(compiler).write(
1384 ByteCode::Move {
1385 dst,
1386 src: Source::Bool(true),
1387 },
1388 pos,
1389 );
1390 }
1391 Pattern::Atom(atom) => {
1392 let atom = Located::new(atom, pos.clone()).compile(compiler)?;
1393 compiler_frame_mut!(compiler).write(
1394 ByteCode::Binary {
1395 op: BinaryOperation::EQ,
1396 dst,
1397 left: expr,
1398 right: atom,
1399 },
1400 pos,
1401 );
1402 }
1403 Pattern::Guard { pattern, cond } => {
1404 pattern.compile_match(compiler, expr, dst)?;
1405 let cond = cond.compile(compiler)?;
1406 compiler_frame_mut!(compiler).write(
1407 ByteCode::Binary {
1408 op: BinaryOperation::And,
1409 dst,
1410 left: dst.into(),
1411 right: cond,
1412 },
1413 pos,
1414 );
1415 }
1416 }
1417 Ok(())
1418 }
1419}
1420impl Compilable for Located<Expression> {
1421 type Output = Source;
1422 fn compile(self, compiler: &mut Compiler) -> Result<Self::Output, Located<Box<dyn Error>>> {
1423 let Located { value: expr, pos } = self;
1424 match expr {
1425 Expression::Atom(atom) => Located::new(atom, pos).compile(compiler),
1426 Expression::Binary { op, left, right } => {
1427 let left = left.compile(compiler)?;
1428 let right = right.compile(compiler)?;
1429 let register = compiler_frame_mut!(compiler).new_register();
1430 let dst = Location::Register(register);
1431 compiler_frame_mut!(compiler).write(
1432 ByteCode::Binary {
1433 op: op.into(),
1434 dst,
1435 left,
1436 right,
1437 },
1438 pos,
1439 );
1440 Ok(dst.into())
1441 }
1442 Expression::Unary { op, right } => {
1443 let right = right.compile(compiler)?;
1444 let register = compiler_frame_mut!(compiler).new_register();
1445 let dst = Location::Register(register);
1446 compiler_frame_mut!(compiler).write(
1447 ByteCode::Unary {
1448 op: op.into(),
1449 dst,
1450 src: right,
1451 },
1452 pos,
1453 );
1454 Ok(dst.into())
1455 }
1456 Expression::Call { head, mut args } => {
1457 let head = head.compile(compiler)?;
1458 let amount = args.len() as u8;
1459 match amount {
1460 0 => {
1461 let dst = compiler_frame_mut!(compiler).new_register();
1462 compiler_frame_mut!(compiler).write(
1463 ByteCode::CallZero {
1464 dst: Some(Location::Register(dst)),
1465 func: head.into(),
1466 },
1467 pos,
1468 );
1469 Ok(Source::Register(dst))
1470 }
1471 1 => {
1472 let arg = args.remove(0).compile(compiler)?;
1473 let dst = compiler_frame_mut!(compiler).new_register();
1474 compiler_frame_mut!(compiler).write(
1475 ByteCode::CallSingle {
1476 dst: Some(Location::Register(dst)),
1477 func: head.into(),
1478 arg,
1479 },
1480 pos,
1481 );
1482 Ok(Source::Register(dst))
1483 }
1484 amount => {
1485 let offset = compiler_frame_mut!(compiler).registers;
1486 compiler_frame_mut!(compiler).add_registers(amount as Register);
1487 for (register, arg) in
1488 (offset..offset + amount as Register).zip(args.into_iter())
1489 {
1490 let pos = arg.pos.clone();
1491 let src = arg.compile(compiler)?;
1492 compiler_frame_mut!(compiler).write(
1493 ByteCode::Move {
1494 dst: Location::Register(register),
1495 src,
1496 },
1497 pos,
1498 );
1499 }
1500 compiler_frame_mut!(compiler).registers = offset;
1501 let dst = compiler_frame_mut!(compiler).new_register();
1502 compiler_frame_mut!(compiler).write(
1503 ByteCode::Call {
1504 dst: Some(Location::Register(dst)),
1505 func: head,
1506 offset,
1507 amount,
1508 },
1509 pos,
1510 );
1511 Ok(Source::Register(dst))
1512 }
1513 }
1514 }
1515 Expression::SelfCall {
1516 head,
1517 field:
1518 Located {
1519 value: field,
1520 pos: field_pos,
1521 },
1522 args,
1523 } => {
1524 let head_pos = head.pos.clone();
1525 let head = head.compile(compiler)?;
1526 let func = {
1527 let dst = compiler_frame_mut!(compiler).new_register();
1528 let field_addr = compiler_frame_mut!(compiler).new_const(Value::String(field));
1529 compiler_frame_mut!(compiler).write(
1530 ByteCode::Field {
1531 dst: Location::Register(dst),
1532 head,
1533 field: Source::Constant(field_addr),
1534 },
1535 field_pos,
1536 );
1537 Source::Register(dst)
1538 };
1539 let amount = args.len() as u8 + 1;
1540 match amount {
1541 1 => {
1542 let offset = compiler_frame_mut!(compiler).registers;
1543 let arg = head.into();
1544 compiler_frame_mut!(compiler).registers = offset;
1545 let dst = compiler_frame_mut!(compiler).new_register();
1546 compiler_frame_mut!(compiler).write(
1547 ByteCode::CallSingle {
1548 dst: Some(Location::Register(dst)),
1549 func,
1550 arg,
1551 },
1552 pos,
1553 );
1554 Ok(Source::Register(dst))
1555 }
1556 amount => {
1557 let offset = compiler_frame_mut!(compiler).registers;
1558 let head_register = compiler_frame_mut!(compiler).new_register();
1559 compiler_frame_mut!(compiler).write(
1560 ByteCode::Move {
1561 dst: Location::Register(head_register),
1562 src: head,
1563 },
1564 head_pos,
1565 );
1566 compiler_frame_mut!(compiler).add_registers(amount as Register);
1567 for (register, arg) in
1568 (offset + 1..offset + amount as Register).zip(args.into_iter())
1569 {
1570 let pos = arg.pos.clone();
1571 let src = arg.compile(compiler)?;
1572 compiler_frame_mut!(compiler).write(
1573 ByteCode::Move {
1574 dst: Location::Register(register),
1575 src,
1576 },
1577 pos,
1578 );
1579 }
1580 compiler_frame_mut!(compiler).registers = offset;
1581 let dst = compiler_frame_mut!(compiler).new_register();
1582 compiler_frame_mut!(compiler).write(
1583 ByteCode::Call {
1584 dst: Some(Location::Register(dst)),
1585 func,
1586 offset,
1587 amount,
1588 },
1589 pos,
1590 );
1591 Ok(Source::Register(dst))
1592 }
1593 }
1594 }
1595 Expression::Field {
1596 head,
1597 field:
1598 Located {
1599 value: field,
1600 pos: _,
1601 },
1602 } => {
1603 let head = head.compile(compiler)?;
1604 let field =
1605 Source::Constant(compiler_frame_mut!(compiler).new_const(Value::String(field)));
1606 let dst = compiler_frame_mut!(compiler).new_register();
1607 compiler_frame_mut!(compiler).write(
1608 ByteCode::Field {
1609 dst: Location::Register(dst),
1610 head,
1611 field,
1612 },
1613 pos,
1614 );
1615 Ok(Source::Register(dst))
1616 }
1617 Expression::Index { head, index } => {
1618 let head = head.compile(compiler)?;
1619 let field = index.compile(compiler)?;
1620 let dst = compiler_frame_mut!(compiler).new_register();
1621 compiler_frame_mut!(compiler).write(
1622 ByteCode::Field {
1623 dst: Location::Register(dst),
1624 head,
1625 field,
1626 },
1627 pos,
1628 );
1629 Ok(Source::Register(dst))
1630 }
1631 }
1632 }
1633}
1634impl Compilable for Located<Atom> {
1635 type Output = Source;
1636 fn compile(self, compiler: &mut Compiler) -> Result<Self::Output, Located<Box<dyn Error>>> {
1637 let Located { value: atom, pos } = self;
1638 match atom {
1639 Atom::Path(path) => Ok(Located::new(path, pos).compile(compiler)?.into()),
1640 Atom::Null => Ok(Source::Null),
1641 Atom::Int(v) => Ok(Source::Constant(
1642 compiler_frame_mut!(compiler).new_const(Value::Int(v)),
1643 )),
1644 Atom::Float(v) => Ok(Source::Constant(
1645 compiler_frame_mut!(compiler).new_const(Value::Float(v)),
1646 )),
1647 Atom::Bool(v) => Ok(Source::Bool(v)),
1648 Atom::Char(v) => Ok(Source::Char(v)),
1649 Atom::String(v) => Ok(Source::Constant(
1650 compiler_frame_mut!(compiler).new_const(Value::String(v)),
1651 )),
1652 Atom::Expression(expr) => expr.compile(compiler),
1653 Atom::Vector(exprs) => {
1654 let amount = exprs.len() as VectorSize;
1655 let register = compiler_frame_mut!(compiler).new_register();
1656 let dst = Location::Register(register);
1657 let start = compiler_frame_mut!(compiler).registers;
1658 let registers = (1..=amount)
1659 .map(|_| compiler_frame_mut!(compiler).new_register())
1660 .collect::<Vec<Register>>();
1661 for (expr, register) in exprs.into_iter().zip(registers.into_iter()) {
1662 let expr_pos = expr.pos.clone();
1663 let src = expr.compile(compiler)?;
1664 compiler_frame_mut!(compiler).write(
1665 ByteCode::Move {
1666 dst: Location::Register(register),
1667 src,
1668 },
1669 expr_pos,
1670 );
1671 }
1672 compiler_frame_mut!(compiler).registers = start;
1673 compiler_frame_mut!(compiler).write(ByteCode::Vector { dst, start, amount }, pos);
1674 Ok(dst.into())
1675 }
1676 Atom::Object(entries) => {
1677 let amount = entries.len() as ObjectSize;
1678 let register = compiler_frame_mut!(compiler).new_register();
1679 let dst = Location::Register(register);
1680 let start = compiler_frame_mut!(compiler).registers;
1681 let registers = (1..amount * 2 + 1)
1682 .map(|_| compiler_frame_mut!(compiler).new_register())
1683 .collect::<Vec<Register>>();
1684 for (
1685 (
1686 Located {
1687 value: key,
1688 pos: key_pos,
1689 },
1690 expr,
1691 ),
1692 register,
1693 ) in entries.into_iter().zip(registers.into_iter().step_by(2))
1694 {
1695 let addr = compiler_frame_mut!(compiler).new_const(Value::String(key));
1696 let expr_pos = expr.pos.clone();
1697 let src = expr.compile(compiler)?;
1698 compiler_frame_mut!(compiler).write(
1699 ByteCode::Move {
1700 dst: Location::Register(register),
1701 src: Source::Constant(addr),
1702 },
1703 key_pos,
1704 );
1705 compiler_frame_mut!(compiler).write(
1706 ByteCode::Move {
1707 dst: Location::Register(register + 1),
1708 src,
1709 },
1710 expr_pos,
1711 );
1712 }
1713 compiler_frame_mut!(compiler).registers = start;
1714 compiler_frame_mut!(compiler).write(ByteCode::Object { dst, start, amount }, pos);
1715 Ok(dst.into())
1716 }
1717 Atom::If {
1718 cond,
1719 case,
1720 else_case,
1721 } => {
1722 let cond = cond.compile(compiler)?;
1723 let register = compiler_frame_mut!(compiler).new_register();
1724 let check_addr =
1725 compiler_frame_mut!(compiler).write(ByteCode::default(), Position::default());
1726
1727 let case = case.compile(compiler)?;
1728 compiler_frame_mut!(compiler).write(
1729 ByteCode::Move {
1730 dst: Location::Register(register),
1731 src: case,
1732 },
1733 pos.clone(),
1734 );
1735 let else_addr =
1736 compiler_frame_mut!(compiler).write(ByteCode::default(), Position::default());
1737 let else_case = else_case.compile(compiler)?;
1738 compiler_frame_mut!(compiler).write(
1739 ByteCode::Move {
1740 dst: Location::Register(register),
1741 src: else_case,
1742 },
1743 pos.clone(),
1744 );
1745 let exit_addr = compiler_frame_mut!(compiler).addr();
1746 compiler_frame_mut!(compiler).overwrite(
1747 check_addr,
1748 ByteCode::JumpIf {
1749 negative: true,
1750 cond,
1751 addr: else_addr + 1,
1752 },
1753 Some(pos.clone()),
1754 );
1755 compiler_frame_mut!(compiler).overwrite(
1756 else_addr,
1757 ByteCode::Jump { addr: exit_addr },
1758 Some(pos),
1759 );
1760 Ok(Source::Register(register))
1761 }
1762 Atom::Fn {
1763 params,
1764 var_args: _,
1765 body,
1766 } => {
1767 compiler.push_frame(CompilerFrame {
1768 closure: Rc::new(RefCell::new(Closure::default())),
1769 scopes: vec![Scope::default()],
1770 registers: 0,
1771 });
1772 for Located {
1773 value: param,
1774 pos: _,
1775 } in params
1776 {
1777 match param {
1778 Parameter::Ident(ident) => {
1779 compiler_frame_mut!(compiler).new_local(ident);
1780 }
1781 Parameter::Object(fields) => {
1782 let head =
1783 Source::Register(compiler_frame_mut!(compiler).new_register());
1784 for Located { value: ident, pos } in fields.into_iter() {
1785 let field = Source::Constant(
1786 compiler_frame_mut!(compiler)
1787 .new_const(Value::String(ident.clone())),
1788 );
1789 let dst = Location::Register(
1790 compiler_frame_mut!(compiler).new_local(ident),
1791 );
1792 compiler_frame_mut!(compiler)
1793 .write(ByteCode::Field { dst, head, field }, pos);
1794 }
1795 }
1796 Parameter::Vector(idents) => {
1797 let head =
1798 Source::Register(compiler_frame_mut!(compiler).new_register());
1799 for (idx, Located { value: ident, pos }) in
1800 idents.into_iter().enumerate()
1801 {
1802 let field = Source::Constant(
1803 compiler_frame_mut!(compiler)
1804 .new_const(Value::Int(idx as isize as i64)),
1805 );
1806 let dst = Location::Register(
1807 compiler_frame_mut!(compiler).new_local(ident),
1808 );
1809 compiler_frame_mut!(compiler)
1810 .write(ByteCode::Field { dst, head, field }, pos);
1811 }
1812 }
1813 }
1814 }
1815 body.compile(compiler)?;
1816 compiler_frame_mut!(compiler).write(ByteCode::Return { src: None }, pos.clone());
1817 let closure = compiler
1818 .pop_frame()
1819 .expect("no compiler frame on stack")
1820 .closure;
1821 let addr = compiler_frame_mut!(compiler).new_closure(closure);
1822 let register = compiler_frame_mut!(compiler).new_register();
1823 compiler_frame_mut!(compiler).write(
1824 ByteCode::Function {
1825 dst: Location::Register(register),
1826 addr,
1827 },
1828 pos,
1829 );
1830 Ok(Source::Register(register))
1831 }
1832 }
1833 }
1834}
1835impl Compilable for Located<Path> {
1836 type Output = Location;
1837 fn compile(self, compiler: &mut Compiler) -> Result<Self::Output, Located<Box<dyn Error>>> {
1838 let Located { value: atom, pos } = self;
1839 match atom {
1840 Path::Ident(ident) => {
1841 if let Some(location) = compiler.get_variable_location(&ident) {
1842 Ok(location)
1843 } else {
1844 let addr = compiler_frame_mut!(compiler).new_const(Value::String(ident));
1845 Ok(Location::Global(addr))
1846 }
1847 }
1848 Path::Field {
1849 head,
1850 field:
1851 Located {
1852 value: field,
1853 pos: _,
1854 },
1855 } => {
1856 let head = head.compile(compiler)?;
1857 let field =
1858 Source::Constant(compiler_frame_mut!(compiler).new_const(Value::String(field)));
1859 let dst = compiler_frame_mut!(compiler).new_register();
1860 compiler_frame_mut!(compiler).write(
1861 ByteCode::Field {
1862 dst: Location::Register(dst),
1863 head: head.into(),
1864 field,
1865 },
1866 pos,
1867 );
1868 Ok(Location::Register(dst))
1869 }
1870 Path::Index { head, index } => {
1871 let head = head.compile(compiler)?;
1872 let field = index.compile(compiler)?;
1873 let dst = compiler_frame_mut!(compiler).new_register();
1874 compiler_frame_mut!(compiler).write(
1875 ByteCode::Field {
1876 dst: Location::Register(dst),
1877 head: head.into(),
1878 field,
1879 },
1880 pos,
1881 );
1882 Ok(Location::Register(dst))
1883 }
1884 }
1885 }
1886}