func (v *Codegen) genIfStat(n *parser.IfStat) { // Warning to all who tread here: // This function is complicated, but theoretically it should never need to // be changed again. God help the soul who has to edit this. if !v.inFunction() { panic("tried to gen if stat not in function") } statTerm := semantic.IsNodeTerminating(n) var end llvm.BasicBlock if !statTerm { end = llvm.AddBasicBlock(v.currentLLVMFunction(), "end") } for i, expr := range n.Exprs { cond := v.genExpr(expr) ifTrue := llvm.AddBasicBlock(v.currentLLVMFunction(), "if_true") ifFalse := llvm.AddBasicBlock(v.currentLLVMFunction(), "if_false") v.builder().CreateCondBr(cond, ifTrue, ifFalse) v.builder().SetInsertPointAtEnd(ifTrue) v.genBlock(n.Bodies[i]) if !statTerm && !n.Bodies[i].IsTerminating && !isBreakOrNext(n.Bodies[i].LastNode()) { v.builder().CreateBr(end) } v.builder().SetInsertPointAtEnd(ifFalse) if !statTerm { end.MoveAfter(ifFalse) } } if n.Else != nil { v.genBlock(n.Else) } if !statTerm && (n.Else == nil || (!n.Else.IsTerminating && !isBreakOrNext(n.Else.LastNode()))) { v.builder().CreateBr(end) } if !statTerm { v.builder().SetInsertPointAtEnd(end) } }