private void ResolveExprLet(ref int segment, sema.Code.Lvalue destination, syn.Node.Let node) { var registerIndex = this.CreateRegister(); var register = this.code.registers[registerIndex]; register.spanDef = node.span; register.spanDefName = node.identifier.span; register.name = (node.identifier as syn.Node.Identifier).token.excerpt; if (node.type != null) { register.type = TypeResolver.Resolve(this.ctx, this.reporter, node.type); } else { register.type = new sema.Type.Placeholder(); } if (node.expr != null) { var assignDestination = new sema.Code.Lvalue.Register { span = node.identifier.span, index = registerIndex }; this.ResolveExpr(ref segment, assignDestination, node.expr); } this.AddVoidInstruction(segment, destination, node.span); }
public static void ResolveFunctionBody(Context ctx, diagn.Reporter reporter, sema.Code.Body body, syn.Node node) { var resolver = new CodeResolver(ctx, reporter, body); var segment = body.CreateSegment(); var destination = new sema.Code.Lvalue.Register { index = 0 }; resolver.ResolveExpr(ref segment, destination, node); }
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); }
private int ResolveIntoNewRegister(ref int segment, syn.Node node, sema.Type type = null) { var newRegisterIndex = this.code.registers.Count; this.registersInScope.Add(true); this.code.registers.Add(new sema.Code.Register { spanDef = node.span, type = type ?? new sema.Type.Placeholder() }); var destination = new sema.Code.Lvalue.Register { span = node.span, index = newRegisterIndex }; this.ResolveExpr(ref segment, destination, node); return(newRegisterIndex); }