Beispiel #1
0
        private bool ValidateSource(List <InitStatus> statusList, Core.DataAccess source)
        {
            var initialized = CheckSourceRecursive(statusList, source);

            if (!initialized &&
                !this.alreadyReportedSet.Contains(source.span))
            {
                this.foundErrors = true;
                this.alreadyReportedSet.Add(source.span);

                var srcReg = source as Core.DataAccessRegister;
                if (srcReg != null && srcReg.registerIndex == 0)
                {
                    this.session.AddMessage(
                        Diagnostics.MessageKind.Error,
                        Diagnostics.MessageCode.UninitializedUse,
                        "not returning a value but expecting '" +
                        funct.GetReturnType().GetString(session) + "'",
                        source.span);
                }
                else
                {
                    this.session.AddMessage(
                        Diagnostics.MessageKind.Error,
                        Diagnostics.MessageCode.UninitializedUse,
                        "use of possibly uninitialized value",
                        source.span);
                }
            }

            return(initialized);
        }
Beispiel #2
0
        private bool CheckSourceRecursive(List <InitStatus> statusList, Core.DataAccess access)
        {
            var accessField = access as Core.DataAccessField;

            if (accessField != null)
            {
                return(CheckSourceRecursive(statusList, accessField.baseAccess));
            }

            var accessReg = access as Core.DataAccessRegister;

            if (accessReg != null)
            {
                return(statusList[accessReg.registerIndex].IsInitialized());
            }

            var accessDeref = access as Core.DataAccessDereference;

            if (accessDeref != null)
            {
                return(CheckSourceRecursive(statusList, accessDeref.innerAccess));
            }

            return(false);
        }
Beispiel #3
0
        private void ResolveExprCall(Grammar.ASTNodeExprCall exprCall, ref int curSegment, Core.DataAccess output)
        {
            // Parse called expression.
            var callTargetReg = Core.DataAccessRegister.ForRegister(
                exprCall.calledExpr.GetSpan(),
                funct.CreateRegister(new Core.TypePlaceholder(), false));

            ResolveExpr(exprCall.calledExpr, ref curSegment, callTargetReg);

            // Parse argument expressions.
            var argumentRegs = new Core.DataAccess[exprCall.argumentExprs.Count];

            for (var i = 0; i < exprCall.argumentExprs.Count; i++)
            {
                argumentRegs[i] = Core.DataAccessRegister.ForRegister(
                    exprCall.argumentExprs[i].GetSpan(),
                    funct.CreateRegister(new Core.TypePlaceholder(), false));

                ResolveExpr(exprCall.argumentExprs[i], ref curSegment, argumentRegs[i]);
            }

            // Generate call instruction.
            funct.AddInstruction(curSegment,
                                 Core.InstructionMoveCallResult.For(exprCall.GetSpan(), output, callTargetReg, argumentRegs));
        }
Beispiel #4
0
        private string GenerateDataAccess(Core.DataAccess access, Core.DeclFunct funct)
        {
            var accessReg = access as Core.DataAccessRegister;

            if (accessReg != null)
            {
                return("var" + accessReg.registerIndex);
            }

            var accessDeref = access as Core.DataAccessDereference;

            if (accessDeref != null)
            {
                return("*(" + GenerateDataAccess(accessDeref.innerAccess, funct) + ")");
            }

            var accessField = access as Core.DataAccessField;

            if (accessField != null)
            {
                var baseType =
                    Semantics.TypeResolver.GetDataAccessType(this.session, funct, accessField.baseAccess);

                var fieldName =
                    Semantics.TypeResolver.GetFieldName(this.session, baseType, accessField.fieldIndex);

                return("(" + GenerateDataAccess(accessField.baseAccess, funct) +
                       ")." + fieldName.GetString());
            }

            return("??");
        }
Beispiel #5
0
 private void ResolveExpr(Grammar.ASTNodeExpr expr, ref int curSegment, Core.DataAccess outputReg)
 {
     if (expr is Grammar.ASTNodeExprParenthesized)
     {
         this.ResolveExpr(((Grammar.ASTNodeExprParenthesized)expr).innerExpr, ref curSegment, outputReg);
     }
     else if (expr is Grammar.ASTNodeExprBlock)
     {
         this.ResolveExprBlock((Grammar.ASTNodeExprBlock)expr, ref curSegment, outputReg);
     }
     else if (expr is Grammar.ASTNodeExprLet)
     {
         this.ResolveExprLet((Grammar.ASTNodeExprLet)expr, ref curSegment, outputReg);
     }
     else if (expr is Grammar.ASTNodeExprIf)
     {
         this.ResolveExprIf((Grammar.ASTNodeExprIf)expr, ref curSegment, outputReg);
     }
     else if (expr is Grammar.ASTNodeExprWhile)
     {
         this.ResolveExprWhile((Grammar.ASTNodeExprWhile)expr, ref curSegment, outputReg);
     }
     else if (expr is Grammar.ASTNodeExprReturn)
     {
         this.ResolveExprReturn((Grammar.ASTNodeExprReturn)expr, ref curSegment, outputReg);
     }
     else if (expr is Grammar.ASTNodeExprCall)
     {
         this.ResolveExprCall((Grammar.ASTNodeExprCall)expr, ref curSegment, outputReg);
     }
     else if (expr is Grammar.ASTNodeExprUnaryOp)
     {
         this.ResolveExprUnaryOp((Grammar.ASTNodeExprUnaryOp)expr, ref curSegment, outputReg);
     }
     else if (expr is Grammar.ASTNodeExprBinaryOp)
     {
         this.ResolveExprBinaryOp((Grammar.ASTNodeExprBinaryOp)expr, ref curSegment, outputReg);
     }
     else if (expr is Grammar.ASTNodeExprName)
     {
         this.ResolveExprName((Grammar.ASTNodeExprName)expr, ref curSegment, outputReg);
     }
     else if (expr is Grammar.ASTNodeExprLiteralBool)
     {
         this.ResolveExprLiteralBool((Grammar.ASTNodeExprLiteralBool)expr, ref curSegment, outputReg);
     }
     else if (expr is Grammar.ASTNodeExprLiteralInt)
     {
         this.ResolveExprLiteralInt((Grammar.ASTNodeExprLiteralInt)expr, ref curSegment, outputReg);
     }
     else if (expr is Grammar.ASTNodeExprLiteralStruct)
     {
         this.ResolveExprLiteralStruct((Grammar.ASTNodeExprLiteralStruct)expr, ref curSegment, outputReg);
     }
     else
     {
         throw new System.NotImplementedException();
     }
 }
Beispiel #6
0
        private string GenerateDataStore(Core.DataAccess dest, Core.DeclFunct funct)
        {
            var destType = Semantics.TypeResolver.GetDataAccessType(this.session, funct, dest);

            if (destType.IsZeroSized(this.session))
            {
                return("");
            }

            return(GenerateDataAccess(dest, funct) + " = ");
        }
Beispiel #7
0
        private bool ApplyToDataAccess(Core.DataAccess access, Core.Type type)
        {
            var regAccess = access as Core.DataAccessRegister;

            if (regAccess != null)
            {
                this.funct.registerTypes[regAccess.registerIndex] = type;
                return(true);
            }

            return(false);
        }
Beispiel #8
0
        private void ResolveExprIf(Grammar.ASTNodeExprIf exprIf, ref int curSegment, Core.DataAccess output)
        {
            // Parse condition.
            var conditionReg = Core.DataAccessRegister.ForRegister(
                exprIf.conditionExpr.GetSpan(),
                funct.CreateRegister(Core.TypeStruct.Of(session.PrimitiveBool), false));

            this.ResolveExpr(
                exprIf.conditionExpr,
                ref curSegment,
                conditionReg);

            var flowBranch = new Core.SegmentFlowBranch {
                conditionReg = conditionReg
            };

            funct.SetSegmentFlow(curSegment, flowBranch);

            // Parse true branch.
            var trueSegment = funct.CreateSegment(exprIf.trueBranchExpr.GetSpan().JustBefore());

            flowBranch.destinationSegmentIfTaken = trueSegment;

            ResolveExpr(exprIf.trueBranchExpr, ref trueSegment, output);

            // Parse false branch, if there is one.
            if (exprIf.falseBranchExpr != null)
            {
                var falseSegment = funct.CreateSegment(exprIf.falseBranchExpr.GetSpan().JustBefore());
                flowBranch.destinationSegmentIfNotTaken = falseSegment;

                ResolveExpr(exprIf.falseBranchExpr, ref falseSegment, output);

                var afterSegment = funct.CreateSegment(exprIf.GetSpan().JustAfter());
                funct.SetSegmentFlow(trueSegment, Core.SegmentFlowGoto.To(afterSegment));
                funct.SetSegmentFlow(falseSegment, Core.SegmentFlowGoto.To(afterSegment));
                curSegment = afterSegment;
            }
            // Or else, just route the false segment path to the next segment.
            else
            {
                var afterSegment = funct.CreateSegment(exprIf.GetSpan().JustAfter());
                funct.SetSegmentFlow(trueSegment, Core.SegmentFlowGoto.To(afterSegment));
                flowBranch.destinationSegmentIfNotTaken = afterSegment;
                curSegment = afterSegment;
            }
        }
Beispiel #9
0
        private void MarkTakenMutAddrRecursive(List <InitStatus> statusList, Core.DataAccess access)
        {
            var accessField = access as Core.DataAccessField;

            if (accessField != null)
            {
                MarkTakenMutAddrRecursive(statusList, accessField.baseAccess);
                return;
            }

            var accessReg = access as Core.DataAccessRegister;

            if (accessReg != null)
            {
                statusList[accessReg.registerIndex].takenMutAddr = true;
                return;
            }
        }
Beispiel #10
0
        private void CheckMove(Core.DataAccess destination, Core.Type srcType, Diagnostics.Span srcSpan)
        {
            if (!TypeResolver.ValidateDataAccess(this.session, this.funct, destination))
            {
                this.foundErrors = true;
                return;
            }

            var destType = TypeResolver.GetDataAccessType(this.session, this.funct, destination);

            if (destType == null)
            {
                return;
            }

            if (!srcType.IsConvertibleTo(destType) &&
                ShouldDiagnose(srcType) &&
                ShouldDiagnose(destType))
            {
                this.foundErrors = true;

                var destReg = destination as Core.DataAccessRegister;
                if (destReg != null && destReg.registerIndex == 0)
                {
                    this.session.AddMessage(
                        Diagnostics.MessageKind.Error,
                        Diagnostics.MessageCode.IncompatibleTypes,
                        "returning '" + srcType.GetString(this.session) + "' " +
                        "but expecting '" + destType.GetString(this.session) + "'",
                        srcSpan,
                        destination.span);
                }
                else
                {
                    this.session.AddMessage(
                        Diagnostics.MessageKind.Error,
                        Diagnostics.MessageCode.IncompatibleTypes,
                        "moving '" + srcType.GetString(this.session) + "' " +
                        "into '" + destType.GetString(this.session) + "'",
                        srcSpan,
                        destination.span);
                }
            }
        }
Beispiel #11
0
        public static Core.Type GetDataAccessType(
            Core.Session session,
            Core.DeclFunct funct,
            Core.DataAccess access)
        {
            var regAccess = access as Core.DataAccessRegister;

            if (regAccess != null)
            {
                return(funct.registerTypes[regAccess.registerIndex]);
            }

            var regField = access as Core.DataAccessField;

            if (regField != null)
            {
                return(GetFieldType(
                           session, GetDataAccessType(session, funct, regField.baseAccess), regField.fieldIndex));
            }

            var regDeref = access as Core.DataAccessDereference;

            if (regDeref != null)
            {
                var innerType = GetDataAccessType(session, funct, regDeref.innerAccess);
                var innerPtr  = innerType as Core.TypePointer;
                if (innerPtr == null)
                {
                    return(new Core.TypeError());
                }

                return(innerPtr.pointedToType);
            }

            var regDiscard = access as Core.DataAccessDiscard;

            if (regDiscard != null)
            {
                return(Core.TypeTuple.Empty());
            }

            return(new Core.TypeError());
        }
Beispiel #12
0
        public static bool GetDataAccessMutability(
            Core.Session session,
            Core.DeclFunct funct,
            Core.DataAccess access)
        {
            var regAccess = access as Core.DataAccessRegister;

            if (regAccess != null)
            {
                return(funct.registerMutabilities[regAccess.registerIndex]);
            }

            var regField = access as Core.DataAccessField;

            if (regField != null)
            {
                return(GetDataAccessMutability(session, funct, regField.baseAccess));
            }

            var regDeref = access as Core.DataAccessDereference;

            if (regDeref != null)
            {
                var innerType = GetDataAccessType(session, funct, regDeref.innerAccess);
                var innerPtr  = innerType as Core.TypePointer;
                if (innerPtr == null)
                {
                    return(false);
                }

                if (!innerPtr.mutable)
                {
                    return(false);
                }

                return(true);
            }

            return(false);
        }
Beispiel #13
0
        public static bool ValidateDataAccess(
            Core.Session session,
            Core.DeclFunct funct,
            Core.DataAccess access)
        {
            var regDeref = access as Core.DataAccessDereference;

            if (regDeref != null)
            {
                var innerType = GetDataAccessType(session, funct, regDeref.innerAccess);
                var innerPtr  = innerType as Core.TypePointer;
                if (innerPtr == null)
                {
                    session.AddMessage(
                        Diagnostics.MessageKind.Error,
                        Diagnostics.MessageCode.CannotDereferenceType,
                        "dereferencing '" + innerType.GetString(session) + "'",
                        access.span);
                    return(false);
                }
            }
            return(true);
        }
Beispiel #14
0
        private void CheckAndInitDestinationRecursive(List <InitStatus> statusList, Core.DataAccess access)
        {
            var accessField = access as Core.DataAccessField;

            if (accessField != null)
            {
                if (ValidateSource(statusList, accessField.baseAccess))
                {
                    CheckAndInitDestinationRecursive(statusList, accessField.baseAccess);
                }

                return;
            }

            var accessReg = access as Core.DataAccessRegister;

            if (accessReg != null)
            {
                var status = statusList[accessReg.registerIndex];

                if (status.IsInitialized())
                {
                    var destMut = TypeResolver.GetDataAccessMutability(this.session, this.funct, accessReg);
                    if (!destMut)
                    {
                        this.foundErrors = true;
                        this.session.AddMessage(
                            Diagnostics.MessageKind.Error,
                            Diagnostics.MessageCode.IncompatibleMutability,
                            "value is not mutable",
                            accessReg.span);
                    }
                }

                status.SetStatus(true);
                status.IncrementCounter();
                return;
            }

            var accessDeref = access as Core.DataAccessDereference;

            if (accessDeref != null)
            {
                if (ValidateSource(statusList, accessDeref.innerAccess))
                {
                    var destType = TypeResolver.GetDataAccessType(this.session, this.funct, accessDeref.innerAccess);
                    var destPtr  = destType as Core.TypePointer;
                    if (destPtr != null && !destPtr.mutable)
                    {
                        this.foundErrors = true;
                        this.session.AddMessage(
                            Diagnostics.MessageKind.Error,
                            Diagnostics.MessageCode.IncompatibleMutability,
                            "value through pointer is not mutable",
                            accessDeref.innerAccess.span);
                    }
                }

                return;
            }
        }
Beispiel #15
0
 private void CheckAndInitDestination(List <InitStatus> statusList, Core.DataAccess destination)
 {
     CheckAndInitDestinationRecursive(statusList, destination);
 }
Beispiel #16
0
        private void ResolveExprName(Grammar.ASTNodeExprName exprName, ref int curSegment, Core.DataAccess output)
        {
            var name = NameResolver.Resolve(((Grammar.ASTNodeExprNameConcrete)exprName).name);

            // Try to find a local with the same name.
            var bindingIndex = FindLocalBinding(name);

            if (bindingIndex >= 0)
            {
                funct.AddInstruction(curSegment,
                                     Core.InstructionMoveData.Of(
                                         exprName.GetSpan(),
                                         output,
                                         Core.DataAccessRegister.ForRegister(
                                             exprName.GetSpan(),
                                             funct.localBindings[bindingIndex].registerIndex)));
                return;
            }

            // Try to find a group of functs with the same name.
            var functList = session.GetDeclsWithUseDirectives(name, false, useDirectives);

            if (session.ValidateSingleDecl(functList, name, exprName.GetSpan()) &&
                session.ValidateAsFunct(functList[0], name, exprName.GetSpan()))
            {
                funct.AddInstruction(curSegment,
                                     Core.InstructionMoveLiteralFunct.With(exprName.GetSpan(), output, functList[0].index));
                return;
            }

            this.foundErrors = true;
            session.AddMessage(
                Diagnostics.MessageKind.Error,
                Diagnostics.MessageCode.Unknown,
                "unknown '" + name.GetString() + "'",
                exprName.GetSpan());
            throw new Core.CheckException();
        }
Beispiel #17
0
        private void ResolveExprWhile(Grammar.ASTNodeExprWhile exprWhile, ref int curSegment, Core.DataAccess output)
        {
            var registerIndexBefore = funct.registerTypes.Count;

            var conditionSegment = funct.CreateSegment(exprWhile.conditionExpr.GetSpan());

            funct.SetSegmentFlow(curSegment, Core.SegmentFlowGoto.To(conditionSegment));

            // Parse condition.
            var conditionReg = Core.DataAccessRegister.ForRegister(
                exprWhile.conditionExpr.GetSpan(),
                funct.CreateRegister(Core.TypeStruct.Of(session.PrimitiveBool), false));

            this.ResolveExpr(
                exprWhile.conditionExpr,
                ref conditionSegment,
                conditionReg);

            var flowBranch = new Core.SegmentFlowBranch {
                conditionReg = conditionReg
            };

            funct.SetSegmentFlow(conditionSegment, flowBranch);

            // Parse body.
            var bodySegment = funct.CreateSegment(exprWhile.bodyExpr.GetSpan().JustBefore());

            flowBranch.destinationSegmentIfTaken = bodySegment;

            ResolveExpr(exprWhile.bodyExpr, ref bodySegment, output);

            // Deinit inner registers.
            for (var i = funct.registerTypes.Count - 1; i >= registerIndexBefore; i--)
            {
                funct.AddInstruction(bodySegment, Core.InstructionDeinit.ForRegister(i));
            }

            // Route segments.
            var afterSegment = funct.CreateSegment(exprWhile.GetSpan().JustAfter());

            funct.SetSegmentFlow(bodySegment, Core.SegmentFlowGoto.To(conditionSegment));
            flowBranch.destinationSegmentIfNotTaken = afterSegment;
            curSegment = afterSegment;
        }
Beispiel #18
0
        private void ResolveExprLet(Grammar.ASTNodeExprLet exprLet, ref int curSegment, Core.DataAccess output)
        {
            // Create a new storage location and name binding.
            var registerIndex = funct.CreateRegister(new Core.TypePlaceholder(), exprLet.mutable);
            var name          = NameResolver.Resolve(((Grammar.ASTNodeExprNameConcrete)exprLet.name).name);

            funct.CreateBinding(
                name,
                registerIndex,
                exprLet.name.GetSpan());

            localScopeLivenesses.Add(true);

            // Parse type annotation, if there is one.
            if (exprLet.type != null)
            {
                funct.registerTypes[registerIndex] =
                    TypeResolver.Resolve(session, exprLet.type, useDirectives, false);
            }

            // Parse init expression, if there is one.
            if (exprLet.initExpr != null)
            {
                ResolveExpr(exprLet.initExpr, ref curSegment,
                            Core.DataAccessRegister.ForRegister(exprLet.name.GetSpan(), registerIndex));
            }

            // Generate a void store.
            funct.AddInstruction(curSegment,
                                 Core.InstructionMoveLiteralTuple.Empty(exprLet.GetSpan(), output));
        }
Beispiel #19
0
        private void ResolveExprLiteralStruct(Grammar.ASTNodeExprLiteralStruct exprLiteralStruct, ref int curSegment, Core.DataAccess output)
        {
            var type = TypeResolver.ResolveStruct(session, exprLiteralStruct.name, useDirectives, true);

            if (!type.IsResolved())
            {
                return;
            }

            var typeStruct     = type as Core.TypeStruct;
            var fieldNum       = TypeResolver.GetFieldNum(this.session, typeStruct);
            var fieldDestSpans = new Diagnostics.Span?[fieldNum];

            var fieldRegs = new int[fieldNum];

            for (var i = 0; i < fieldNum; i++)
            {
                fieldRegs[i] = funct.CreateRegister(
                    TypeResolver.GetFieldType(this.session, typeStruct, i), false);
            }

            var fieldRegAccesses = new Core.DataAccess[fieldNum];

            for (var i = 0; i < fieldNum; i++)
            {
                fieldRegAccesses[i] =
                    Core.DataAccessRegister.ForRegister(exprLiteralStruct.name.GetSpan(), fieldRegs[i]);
            }

            foreach (var fieldInit in exprLiteralStruct.fields)
            {
                var name = NameResolver.Resolve(fieldInit.name);

                int fieldIndex;
                if (!this.session.GetStruct(typeStruct.structIndex).fieldNames.FindByName(name, out fieldIndex))
                {
                    this.foundErrors = true;
                    session.AddMessage(
                        Diagnostics.MessageKind.Error,
                        Diagnostics.MessageCode.Unknown,
                        "unknown field '" + name.GetString() + "' in '" +
                        type.GetString(this.session) + "'",
                        fieldInit.name.GetSpan());
                    continue;
                }

                if (fieldDestSpans[fieldIndex].HasValue)
                {
                    this.foundErrors = true;
                    session.AddMessage(
                        Diagnostics.MessageKind.Error,
                        Diagnostics.MessageCode.Unknown,
                        "duplicate field '" + name.GetString() + "' initialization",
                        fieldInit.name.GetSpan(),
                        fieldDestSpans[fieldIndex].Value);
                    continue;
                }

                fieldRegAccesses[fieldIndex].span = fieldInit.name.GetSpan();
                fieldDestSpans[fieldIndex]        = fieldInit.name.GetSpan();
                this.ResolveExpr(fieldInit.expr, ref curSegment, fieldRegAccesses[fieldIndex]);
            }

            var missingFields = new List <int>();

            for (var i = 0; i < fieldNum; i++)
            {
                if (!fieldDestSpans[i].HasValue)
                {
                    missingFields.Add(i);
                }
            }

            if (missingFields.Count > 0)
            {
                Core.Name fieldName;
                session.GetStruct(typeStruct.structIndex).fieldNames.FindByValue(missingFields[0], out fieldName);

                this.foundErrors = true;
                session.AddMessage(
                    Diagnostics.MessageKind.Error,
                    Diagnostics.MessageCode.Unknown,
                    "missing initializer" + (missingFields.Count > 1 ? "s" : "") +
                    " for field '" + fieldName.GetString() + "'" +
                    (missingFields.Count > 1 ? " and other " + (missingFields.Count - 1) : ""),
                    exprLiteralStruct.GetSpan());
            }
            else
            {
                var finalFieldDestSpans = new Diagnostics.Span[fieldNum];
                for (var i = 0; i < fieldNum; i++)
                {
                    finalFieldDestSpans[i] = fieldDestSpans[i].Value;
                }

                funct.AddInstruction(curSegment, Core.InstructionMoveLiteralStruct.Of(
                                         exprLiteralStruct.GetSpan(), output,
                                         typeStruct.structIndex, fieldRegAccesses, finalFieldDestSpans));
            }
        }
Beispiel #20
0
        private void ResolveExprCall(Grammar.ASTNodeExprCall exprCall, ref int curSegment, Core.DataAccess output)
        {
            // Parse called expression.
            var callTargetReg = Core.DataAccessRegister.ForRegister(
                exprCall.calledExpr.GetSpan(),
                funct.CreateRegister(new Core.TypePlaceholder(), false));

            ResolveExpr(exprCall.calledExpr, ref curSegment, callTargetReg);

            // Parse argument expressions.
            var argumentRegs = new Core.DataAccess[exprCall.argumentExprs.Count];

            for (var i = 0; i < exprCall.argumentExprs.Count; i++)
            {
                argumentRegs[i] = Core.DataAccessRegister.ForRegister(
                    exprCall.argumentExprs[i].GetSpan(),
                    funct.CreateRegister(new Core.TypePlaceholder(), false));

                ResolveExpr(exprCall.argumentExprs[i], ref curSegment, argumentRegs[i]);
            }

            // Generate call instruction.
            funct.AddInstruction(curSegment,
                Core.InstructionMoveCallResult.For(exprCall.GetSpan(), output, callTargetReg, argumentRegs));
        }
Beispiel #21
0
        private void ResolveExprBinaryOp(Grammar.ASTNodeExprBinaryOp exprBinOp, ref int curSegment, Core.DataAccess output)
        {
            if (exprBinOp.oper == Grammar.ASTNodeExprBinaryOp.Operator.Equal)
            {
                var access = ResolveDataAccess(exprBinOp.lhsOperand, ref curSegment, false, false);
                if (access == null)
                {
                    return;
                }

                // Parse right-hand side expression.
                ResolveExpr(
                    exprBinOp.rhsOperand,
                    ref curSegment,
                    access);

                // Generate a void store.
                funct.AddInstruction(
                    curSegment,
                    Core.InstructionMoveLiteralTuple.Empty(exprBinOp.GetSpan(), output));

                return;
            }
            else if (exprBinOp.oper == Grammar.ASTNodeExprBinaryOp.Operator.Dot)
            {
                var access = ResolveDataAccess(exprBinOp, ref curSegment, false, false);
                if (access == null)
                {
                    return;
                }

                funct.AddInstruction(curSegment,
                                     Core.InstructionMoveData.Of(
                                         exprBinOp.GetSpan(),
                                         output,
                                         access));
                return;
            }

            throw new System.NotImplementedException();
        }
Beispiel #22
0
        private void ResolveExprUnaryOp(Grammar.ASTNodeExprUnaryOp exprUnOp, ref int curSegment, Core.DataAccess output)
        {
            if (exprUnOp.oper == Grammar.ASTNodeExprUnaryOp.Operator.Asterisk ||
                exprUnOp.oper == Grammar.ASTNodeExprUnaryOp.Operator.AsteriskMut)
            {
                var mutable = (exprUnOp.oper == Grammar.ASTNodeExprUnaryOp.Operator.AsteriskMut);

                // Parse addressed expression.
                var access = ResolveDataAccess(exprUnOp.operand, ref curSegment, true, mutable);
                if (access == null)
                {
                    return;
                }

                // Store pointer.
                funct.AddInstruction(
                    curSegment,
                    Core.InstructionMoveAddr.Of(exprUnOp.GetSpan(), output, access, mutable));

                return;
            }
            else if (exprUnOp.oper == Grammar.ASTNodeExprUnaryOp.Operator.At)
            {
                // Parse addressed expression.
                var access = ResolveDataAccess(exprUnOp, ref curSegment, true, false);
                if (access == null)
                {
                    return;
                }

                // Store pointer.
                funct.AddInstruction(
                    curSegment,
                    Core.InstructionMoveData.Of(exprUnOp.GetSpan(), output, access));

                return;
            }

            throw new System.NotImplementedException();
        }
Beispiel #23
0
 private void MarkTakenMutAddr(List <InitStatus> statusList, Core.DataAccess destination)
 {
     MarkTakenMutAddrRecursive(statusList, destination);
 }
Beispiel #24
0
        private void ResolveExprBlock(Grammar.ASTNodeExprBlock exprBlock, ref int curSegment, Core.DataAccess outputReg)
        {
            // Generate an empty tuple store if there are no subexpressions.
            if (exprBlock.subexprs.Count == 0)
            {
                funct.AddInstruction(curSegment,
                                     Core.InstructionMoveLiteralTuple.Empty(exprBlock.GetSpan().Displace(1, -1), outputReg));
                return;
            }

            // Store the indices marking inner locals/registers.
            var localScopeIndexBefore = localScopeLivenesses.Count;
            var registerIndexBefore   = funct.registerTypes.Count;

            for (int i = 0; i < exprBlock.subexprs.Count; i++)
            {
                try
                {
                    var subexprOutput = outputReg;
                    if (i < exprBlock.subexprs.Count - 1)
                    {
                        subexprOutput = new Core.DataAccessDiscard();
                    }

                    this.ResolveExpr(exprBlock.subexprs[i], ref curSegment, subexprOutput);
                }
                catch (Core.CheckException) { }
            }

            // Mark inner locals as out-of-scope.
            for (var i = localScopeIndexBefore; i < localScopeLivenesses.Count; i++)
            {
                localScopeLivenesses[i] = false;
            }

            // Deinit inner registers.
            for (var i = funct.registerTypes.Count - 1; i >= registerIndexBefore; i--)
            {
                funct.AddInstruction(curSegment, Core.InstructionDeinit.ForRegister(i));
            }
        }
Beispiel #25
0
 private void ResolveExprLiteralBool(Grammar.ASTNodeExprLiteralBool exprLiteralBool, ref int curSegment, Core.DataAccess output)
 {
     funct.AddInstruction(curSegment,
                          Core.InstructionMoveLiteralBool.Of(
                              exprLiteralBool.GetSpan(),
                              output,
                              exprLiteralBool.value));
 }
Beispiel #26
0
        private void ResolveExprReturn(Grammar.ASTNodeExprReturn exprRet, ref int curSegment, Core.DataAccess output)
        {
            // Generate a void store.
            funct.AddInstruction(curSegment,
                                 Core.InstructionMoveLiteralTuple.Empty(exprRet.GetSpan(), output));

            // Parse returned expr, if there is one.
            if (exprRet.expr != null)
            {
                ResolveExpr(exprRet.expr, ref curSegment,
                            Core.DataAccessRegister.ForRegister(exprRet.expr.GetSpan(), 0));

                funct.SetSegmentFlow(curSegment, new Core.SegmentFlowEnd());
            }
            // Else, return a void.
            else
            {
                funct.AddInstruction(curSegment,
                                     Core.InstructionMoveLiteralTuple.Empty(
                                         exprRet.GetSpan(), Core.DataAccessRegister.ForRegister(exprRet.expr.GetSpan(), 0)));

                funct.SetSegmentFlow(curSegment, new Core.SegmentFlowEnd());
            }

            // Create next unlinked segment.
            curSegment = funct.CreateSegment(exprRet.GetSpan().JustAfter());
        }
Beispiel #27
0
        private void ResolveExprLiteralStruct(Grammar.ASTNodeExprLiteralStruct exprLiteralStruct, ref int curSegment, Core.DataAccess output)
        {
            var type = TypeResolver.ResolveStruct(session, exprLiteralStruct.name, useDirectives, true);
            if (!type.IsResolved())
                return;

            var typeStruct = type as Core.TypeStruct;
            var fieldNum = TypeResolver.GetFieldNum(this.session, typeStruct);
            var fieldDestSpans = new Diagnostics.Span?[fieldNum];

            var fieldRegs = new int[fieldNum];
            for (var i = 0; i < fieldNum; i++)
            {
                fieldRegs[i] = funct.CreateRegister(
                    TypeResolver.GetFieldType(this.session, typeStruct, i), false);
            }

            var fieldRegAccesses = new Core.DataAccess[fieldNum];
            for (var i = 0; i < fieldNum; i++)
            {
                fieldRegAccesses[i] =
                    Core.DataAccessRegister.ForRegister(exprLiteralStruct.name.GetSpan(), fieldRegs[i]);
            }

            foreach (var fieldInit in exprLiteralStruct.fields)
            {
                var name = NameResolver.Resolve(fieldInit.name);

                int fieldIndex;
                if (!this.session.GetStruct(typeStruct.structIndex).fieldNames.FindByName(name, out fieldIndex))
                {
                    this.foundErrors = true;
                    session.AddMessage(
                        Diagnostics.MessageKind.Error,
                        Diagnostics.MessageCode.Unknown,
                        "unknown field '" + name.GetString() + "' in '" +
                        type.GetString(this.session) + "'",
                        fieldInit.name.GetSpan());
                    continue;
                }

                if (fieldDestSpans[fieldIndex].HasValue)
                {
                    this.foundErrors = true;
                    session.AddMessage(
                        Diagnostics.MessageKind.Error,
                        Diagnostics.MessageCode.Unknown,
                        "duplicate field '" + name.GetString() + "' initialization",
                        fieldInit.name.GetSpan(),
                        fieldDestSpans[fieldIndex].Value);
                    continue;
                }

                fieldRegAccesses[fieldIndex].span = fieldInit.name.GetSpan();
                fieldDestSpans[fieldIndex] = fieldInit.name.GetSpan();
                this.ResolveExpr(fieldInit.expr, ref curSegment, fieldRegAccesses[fieldIndex]);
            }

            var missingFields = new List<int>();
            for (var i = 0; i < fieldNum; i++)
            {
                if (!fieldDestSpans[i].HasValue)
                    missingFields.Add(i);
            }

            if (missingFields.Count > 0)
            {
                Core.Name fieldName;
                session.GetStruct(typeStruct.structIndex).fieldNames.FindByValue(missingFields[0], out fieldName);

                this.foundErrors = true;
                session.AddMessage(
                    Diagnostics.MessageKind.Error,
                    Diagnostics.MessageCode.Unknown,
                    "missing initializer" + (missingFields.Count > 1 ? "s" : "") +
                    " for field '" + fieldName.GetString() + "'" +
                    (missingFields.Count > 1 ? " and other " + (missingFields.Count - 1) : ""),
                    exprLiteralStruct.GetSpan());
            }
            else
            {
                var finalFieldDestSpans = new Diagnostics.Span[fieldNum];
                for (var i = 0; i < fieldNum; i++)
                {
                    finalFieldDestSpans[i] = fieldDestSpans[i].Value;
                }

                funct.AddInstruction(curSegment, Core.InstructionMoveLiteralStruct.Of(
                    exprLiteralStruct.GetSpan(), output,
                    typeStruct.structIndex, fieldRegAccesses, finalFieldDestSpans));
            }
        }
Beispiel #28
0
 private void ResolveExprLiteralInt(Grammar.ASTNodeExprLiteralInt exprLiteralInt, ref int curSegment, Core.DataAccess output)
 {
     funct.AddInstruction(curSegment,
                          Core.InstructionMoveLiteralInt.Of(
                              exprLiteralInt.GetSpan(),
                              output,
                              Core.TypeStruct.Of(session.PrimitiveInt),
                              System.Convert.ToInt64(exprLiteralInt.GetExcerpt())));
 }