Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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);
        }