private void ResolveExprIf(ref int segment, sema.Code.Lvalue destination, syn.Node.If node) { var conditionRegIndex = this.ResolveIntoNewRegister( ref segment, node.condition, new sema.Type.Structure { def = ctx.primitiveBool }); var conditionLvalue = new sema.Code.Lvalue.Register { index = conditionRegIndex, span = node.condition.span }; this.ResolveExpr(ref segment, conditionLvalue, node.condition); var branch = new sema.Code.Terminator.Branch { conditionRegisterIndex = conditionRegIndex }; this.code.SetTerminator(segment, branch); var trueSegment = this.code.CreateSegment(); branch.trueSegmentIndex = trueSegment; this.ResolveExpr(ref trueSegment, new sema.Code.Lvalue.Discard { span = node.trueBlock.span }, node.trueBlock); if (node.falseBlock != null) { var falseSegment = this.code.CreateSegment(); branch.falseSegmentIndex = falseSegment; this.ResolveExpr(ref falseSegment, new sema.Code.Lvalue.Discard { span = node.falseBlock.span }, node.falseBlock); var afterSegment = this.code.CreateSegment(); this.code.SetTerminator(trueSegment, new sema.Code.Terminator.Goto { segmentIndex = afterSegment }); this.code.SetTerminator(falseSegment, new sema.Code.Terminator.Goto { segmentIndex = afterSegment }); segment = afterSegment; } else { var afterSegment = this.code.CreateSegment(); branch.falseSegmentIndex = afterSegment; this.code.SetTerminator(trueSegment, new sema.Code.Terminator.Goto { segmentIndex = afterSegment }); segment = afterSegment; } this.AddVoidInstruction(segment, destination, node.span); }
private void ResolveExprWhile(ref int segment, sema.Code.Lvalue destination, syn.Node.While node) { var conditionSegment = this.code.CreateSegment(); var conditionSegmentEnd = conditionSegment; this.code.SetTerminator(segment, new sema.Code.Terminator.Goto { segmentIndex = conditionSegment }); var conditionRegIndex = this.ResolveIntoNewRegister( ref conditionSegmentEnd, node.condition, new sema.Type.Structure { def = ctx.primitiveBool }); var conditionLvalue = new sema.Code.Lvalue.Register { index = conditionRegIndex, span = node.condition.span }; this.ResolveExpr(ref conditionSegmentEnd, conditionLvalue, node.condition); var branch = new sema.Code.Terminator.Branch { conditionRegisterIndex = conditionRegIndex }; this.code.SetTerminator(conditionSegmentEnd, branch); var bodySegment = this.code.CreateSegment(); var afterSegment = this.code.CreateSegment(); branch.trueSegmentIndex = bodySegment; this.breakSegments.Push(afterSegment); this.continueSegments.Push(conditionSegment); this.ResolveExpr(ref bodySegment, new sema.Code.Lvalue.Discard { span = node.block.span }, node.block); this.code.SetTerminator(bodySegment, new sema.Code.Terminator.Goto { segmentIndex = conditionSegment }); this.breakSegments.Pop(); this.continueSegments.Pop(); branch.falseSegmentIndex = afterSegment; segment = afterSegment; this.AddVoidInstruction(segment, destination, node.span); }