Actually just three programming languages in a trenchcoat
1
fork

Configure Feed

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

array patterns

+79 -4
+7
samples/array_pattern.tri
··· 1 + proc main!() { 2 + let x = [1, 2, 3, 4, 5]; 3 + let [1, ..y] = x; 4 + let [..z, 5] = x; 5 + let [1, ..m, 5] = x; 6 + exit [..y, ..m, ..z]; 7 + }
+50 -3
trilogy-codegen/src/pattern_match.rs
··· 236 236 .unwrap(); 237 237 write_pattern(context, rhs, on_fail); 238 238 } 239 - (Some(ir::Value::Builtin(Builtin::Array)), ..) => todo!(), 240 - (Some(ir::Value::Builtin(Builtin::Record)), ..) => todo!(), 241 - (Some(ir::Value::Builtin(Builtin::Set)), ..) => todo!(), 239 + (None, ir::Value::Builtin(Builtin::Array), ir::Value::Pack(pack)) => { 240 + let cleanup = context.labeler.unique_hint("array_cleanup"); 241 + let end = context.labeler.unique_hint("array_end"); 242 + let mut spread = None; 243 + context.write_instruction(Instruction::Clone); 244 + for element in &pack.values { 245 + if element.is_spread { 246 + spread = Some(&element.expression); 247 + continue; 248 + } 249 + // TODO: this could be way more efficient 250 + if spread.is_none() { 251 + context 252 + .write_instruction(Instruction::Copy) 253 + .write_instruction(Instruction::Const(0.into())) 254 + .write_instruction(Instruction::Access); 255 + write_pattern_match(context, &element.expression, &cleanup); 256 + context 257 + .write_instruction(Instruction::Const(1.into())) 258 + .write_instruction(Instruction::Skip); 259 + } else { 260 + context 261 + .write_instruction(Instruction::Copy) 262 + .write_instruction(Instruction::Length) 263 + .write_instruction(Instruction::Const(1.into())) 264 + .write_instruction(Instruction::Subtract) 265 + .write_instruction(Instruction::LoadRegister(1)) 266 + .write_instruction(Instruction::LoadRegister(1)) 267 + .write_instruction(Instruction::Access); 268 + write_pattern_match(context, &element.expression, &cleanup); 269 + context.write_instruction(Instruction::Take); 270 + } 271 + } 272 + if let Some(spread) = spread { 273 + write_pattern_match(context, spread, on_fail); 274 + } else { 275 + context.write_instruction(Instruction::Pop); 276 + } 277 + context 278 + .jump(&end) 279 + .write_label(cleanup) 280 + .unwrap() 281 + .write_instruction(Instruction::Pop) 282 + .write_instruction(Instruction::Pop) 283 + .jump(on_fail) 284 + .write_label(end) 285 + .unwrap(); 286 + } 287 + (None, ir::Value::Builtin(Builtin::Record), ..) => todo!(), 288 + (None, ir::Value::Builtin(Builtin::Set), ..) => todo!(), 242 289 what => panic!("not a pattern ({what:?})"), 243 290 }, 244 291 ir::Value::Dynamic(dynamic) => {
+21
trilogy-codegen/tests/samples.rs
··· 163 163 Value::from("worldworld") 164 164 ); 165 165 } 166 + 167 + #[test] 168 + fn sample_array_pattern() { 169 + let program = include_tri!("array_pattern.tri"); 170 + assert!(StructuralEq::eq( 171 + &VirtualMachine::load(program).run().unwrap(), 172 + &Value::from(vec![ 173 + Value::from(2), 174 + 3.into(), 175 + 4.into(), 176 + 5.into(), 177 + 2.into(), 178 + 3.into(), 179 + 4.into(), 180 + 1.into(), 181 + 2.into(), 182 + 3.into(), 183 + 4.into(), 184 + ]) 185 + )); 186 + }
+1 -1
trilogy-vm/src/vm/virtual_machine.rs
··· 111 111 ex.stack_push(value); 112 112 } 113 113 OpCode::Clone => { 114 - let value = ex.read_register(0)?; 114 + let value = ex.stack_pop()?; 115 115 ex.stack_push(value.structural_clone()); 116 116 } 117 117 OpCode::TypeOf => {