region-based memory management in a c-like form
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

matching on literals

+101 -30
+36 -13
codegen/src/llvm.rs
··· 20 20 21 21 struct FunctionLocalInfo<'ctx> { 22 22 ty: BasicTypeEnum<'ctx>, 23 + tk: mir::Ty, 23 24 alloc: PointerValue<'ctx>, 24 25 defining_block: BasicBlock<'ctx>, 25 26 } ··· 27 28 impl<'ctx> FunctionLocalInfo<'ctx> { 28 29 fn new( 29 30 ty: BasicTypeEnum<'ctx>, 31 + tk: mir::Ty, 30 32 alloc: PointerValue<'ctx>, 31 33 defining_block: BasicBlock<'ctx>, 32 34 ) -> Self { 33 35 Self { 34 36 ty, 37 + tk, 35 38 alloc, 36 39 defining_block, 37 40 } ··· 515 518 } 516 519 mir::Terminator::BrTable(local_id, jump_table) => { 517 520 let jump_local_info = self.function_locals.get(&local_id).unwrap(); 521 + let (jump_val, switch_type) = match jump_local_info.tk { 522 + mir::Ty::Int => { 523 + let switch_type = self.ctx().i32_type(); 518 524 519 - let jump_ptr = self.builder.build_struct_gep( 520 - jump_local_info.ty, 521 - jump_local_info.alloc, 522 - 0, 523 - "jump_ptr", 524 - )?; 525 + let jump_val = self 526 + .builder 527 + .build_load(switch_type, jump_local_info.alloc, "jump_val") 528 + .unwrap() 529 + .into_int_value(); 530 + 531 + (jump_val, switch_type) 532 + } 533 + mir::Ty::TaggedUnion(_) => { 534 + let switch_type = self.ctx().i8_type(); 535 + 536 + let jump_ptr = self.builder.build_struct_gep( 537 + jump_local_info.ty, 538 + jump_local_info.alloc, 539 + 0, 540 + "jump_ptr", 541 + )?; 542 + 543 + let jump_val = self 544 + .builder 545 + .build_load(switch_type, jump_ptr, "jump_val") 546 + .unwrap() 547 + .into_int_value(); 525 548 526 - let jump_val = self 527 - .builder 528 - .build_load(self.ctx().i8_type(), jump_ptr, "jump_val") 529 - .unwrap() 530 - .into_int_value(); 549 + (jump_val, switch_type) 550 + } 551 + _ => todo!(), 552 + }; 531 553 532 554 let default_bb = self.get_or_create_bb(llvm_fn, jump_table.default); 533 555 ··· 535 557 for (val, block_id) in jump_table.cases { 536 558 let bb = self.get_or_create_bb(llvm_fn, block_id); 537 559 538 - let val = self.ctx().i8_type().const_int(val as u64, false); 560 + let val = switch_type.const_int(val as u64, false); 539 561 cases.push((val, bb)); 540 562 } 541 563 ··· 591 613 .builder 592 614 .build_alloca(local_ty, format!("x{}", local.id).as_str())?; 593 615 594 - let local_info = FunctionLocalInfo::new(local_ty, local_alloca, entry_block); 616 + let local_info = 617 + FunctionLocalInfo::new(local_ty, local.ty.clone(), local_alloca, entry_block); 595 618 self.function_locals.insert(local.id, local_info); 596 619 } 597 620
+40 -16
frontend/src/ast_visitor.rs
··· 254 254 255 255 fn get_scrutinee_type_and_local(&mut self, scrutinee: Expr) -> (TypeKind, mir::LocalId) { 256 256 let scru_rvalue = self.visit_expr(scrutinee); 257 - let scru_ty = self 258 - .local_types 259 - .get(&scru_rvalue.place().unwrap().local) 260 - .unwrap() 261 - .clone(); 262 - let scru_local = self.ensure_local(scru_rvalue, &scru_ty); 263 - (scru_ty, scru_local) 257 + match &scru_rvalue.place() { 258 + Some(place) => { 259 + let scru_ty = self.local_types.get(&place.local).unwrap().clone(); 260 + let scru_local = self.ensure_local(scru_rvalue, &scru_ty); 261 + (scru_ty, scru_local) 262 + } 263 + None => { 264 + // need to load this into memory now 265 + match &scru_rvalue { 266 + mir::RValue::Use(mir::Operand::Constant(cnst)) => { 267 + let scru_ty = match cnst { 268 + mir::Constant::Int(_) => TypeKind::Int, 269 + mir::Constant::Bool(_) => TypeKind::Bool, 270 + }; 271 + 272 + let scru_local = self.new_local(&scru_ty); 273 + self.get_current_block() 274 + .stmts 275 + .push(mir::Statement::Assign(scru_local, scru_rvalue)); 276 + (scru_ty, scru_local) 277 + } 278 + _ => todo!(), 279 + } 280 + } 281 + } 264 282 } 265 283 266 284 fn get_variant_tag(&self, scrutinee_ty: &TypeKind, variant_name: Symbol) -> Option<u8> { ··· 655 673 match &arm.pat.node { 656 674 PatKind::Variant { name, bindings } => { 657 675 if let Some(tag) = self.get_variant_tag(&scru_ty, *name) { 658 - cases.push((tag as u32, arm_block_id)); 676 + cases.push((tag as i32, arm_block_id)); 659 677 660 678 if !bindings.is_empty() { 661 679 let idx = self.get_variant_index(&scru_ty, *name).unwrap(); ··· 677 695 self.bind_pattern(&arm.pat, scru_local, &scru_ty); 678 696 default_arm_block_id = Some(arm_block_id); 679 697 } 680 - PatKind::Record(fields) => { 681 - for field in fields { 682 - let field_idx = self.get_record_field_index(&scru_ty, field.name); 683 - if let Some(idx) = field_idx { 684 - let field_local = self.extract_record_field(scru_local, idx); 685 - self.symbol_table.insert(field.name, field_local); 686 - } 698 + PatKind::Literal(lit) => match lit { 699 + ValueKind::Int(i) => { 700 + cases.push((*i, arm_block_id)); 687 701 } 688 - } 702 + _ => todo!(), 703 + }, 704 + // PatKind::Record(fields) => { 705 + // for field in fields { 706 + // let field_idx = self.get_record_field_index(&scru_ty, field.name); 707 + // if let Some(idx) = field_idx { 708 + // let field_local = self.extract_record_field(scru_local, idx); 709 + // self.symbol_table.insert(field.name, field_local); 710 + // } 711 + // } 712 + // } 689 713 _ => {} 690 714 } 691 715
+1 -1
frontend/src/mir/ir.rs
··· 222 222 #[derive(Debug, PartialEq, Eq, Clone)] 223 223 pub struct JumpTable { 224 224 pub default: BlockId, 225 - pub cases: Vec<(u32, BlockId)>, 225 + pub cases: Vec<(i32, BlockId)>, 226 226 } 227 227 228 228 #[derive(Debug, PartialEq, Eq, Clone)]
+14
frontend/src/typecheck.rs
··· 626 626 ctx.type_map.insert(field.name, field.ty.clone().unwrap()); 627 627 } 628 628 } 629 + PatKind::Literal(lit) => match lit { 630 + ValueKind::Int(_) => { 631 + if scrutinee_ty.node != TypeKind::Int { 632 + return Err(TypeError::new( 633 + TypeErrorKind::ExpectedType { 634 + expected: TypeKind::Int, 635 + found: scrutinee_ty.node.clone(), 636 + }, 637 + scrutinee_ty.span.clone(), 638 + )); 639 + } 640 + } 641 + _ => todo!(), 642 + }, 629 643 PatKind::Wildcard => {} 630 644 _ => todo!(), 631 645 }
+10
tests/working_subset.nm
··· 37 37 Some(x) => { printf(fmt_string, x) } 38 38 | None => { printf(fmt_string, 0) } 39 39 40 + match typed_int with 41 + 1 => { printf(fmt_string, 1) } 42 + | 2 => { printf(fmt_string, 2) } 43 + | _ => { printf(fmt_string, 999) } 44 + 45 + match 3 with 46 + 1 => { printf(fmt_string, 1) } 47 + | 2 => { printf(fmt_string, 2) } 48 + | _ => { printf(fmt_string, 999) } 49 + 40 50 // dyn_array := [] { 1, 2 } 41 51 }