Ejemplo n.º 1
0
        protected override void VisitAssignmentSyntax(AssignmentSyntax pNode)
        {
            base.VisitAssignmentSyntax(pNode);
            if (pNode.Value.Type == SmallTypeCache.NoValue)
            {
                CompilerErrors.ExpressionNoValue(pNode.Value.Span);
            }

            var isTuple = pNode.Value.Type.IsTuple;

            for (int i = 0; i < pNode.Variables.Count; i++)
            {
                //Check if we are assigning to a const variable
                if (_locals.TryGetVariable(pNode.Variables[i].Value, out LocalDefinition ld) && ld.IsConst)
                {
                    CompilerErrors.CannotAssignCost(pNode.Variables[i], pNode.Variables[i].Span);
                }

                var t = isTuple ? pNode.Value.Type.GetFieldType(i) : pNode.Value.Type;

                //We have to set the type of discards so the tuple is created properly
                if (SyntaxHelper.IsDiscard(pNode.Variables[i]))
                {
                    ((DiscardSyntax)pNode.Variables[i]).SetType(t);
                }
            }
        }
Ejemplo n.º 2
0
        protected override void VisitDeclarationSyntax(DeclarationSyntax pNode)
        {
            Visit(pNode.Value);

            var isTuple = pNode.Value.Type.IsTuple;

            for (int i = 0; i < pNode.Variables.Count; i++)
            {
                if (!SyntaxHelper.IsDiscard(pNode.Variables[i]))
                {
                    if (_locals.IsVariableDefinedInScope(pNode.Variables[i].Value))
                    {
                        CompilerErrors.IdentifierAlreadyDeclared(pNode.Variables[i], pNode.Span);
                    }
                    else
                    {
                        //We do not allow variables to have the same names as types
                        //This makes it easier to check for "static" method/fields
                        if (SmallTypeCache.IsTypeDefined(pNode.Variables[i].Value))
                        {
                            CompilerErrors.ValueDefinedAsType(pNode.Variables[i], pNode.Variables[i].Span);
                        }
                        else
                        {
                            //For tuple types we set the individual variables to the tuple field type... not the tuple itself
                            var t = isTuple ? pNode.Value.Type.GetFieldType(i) : pNode.Value.Type;

                            //Report expression errors and change the type to Undefined so we don't get further no expression errors
                            if (pNode.Value.Type == SmallTypeCache.NoValue)
                            {
                                CompilerErrors.ExpressionNoValue(pNode.Value.Span);
                                t = SmallTypeCache.Undefined;
                            }

                            pNode.Variables[i].SetType(t);
                            _locals.DefineVariableInScope(pNode.Variables[i].Value, LocalDefinition.Create(pNode.IsConst, pNode.Variables[i].Type));
                        }
                    }
                }
            }

            //Check that we are declaring the proper number of variables
            if (isTuple && pNode.Value.Type.GetFieldCount() != pNode.Variables.Count)
            {
                CompilerErrors.DeclarationCountMismatch(pNode.Value.Type.GetFieldCount(), pNode.Variables.Count, pNode.Span);
            }
        }
Ejemplo n.º 3
0
        protected override void VisitMethodCallSyntax(MethodCallSyntax pNode)
        {
            base.VisitMethodCallSyntax(pNode);

            SmallType[] types = new SmallType[pNode.Arguments.Count];
            for (int i = 0; i < types.Length; i++)
            {
                types[i] = pNode.Arguments[i].Type;
                if (types[i] == SmallTypeCache.NoValue)
                {
                    CompilerErrors.ExpressionNoValue(pNode.Arguments[i].Span);
                }
            }

            if (SyntaxHelper.HasUndefinedCastAsArg(pNode))
            {
                IList <MethodDefinition> matches = _unit.GetAllMatches(Namespace, pNode.Value, pNode.Arguments.Count);
                if (matches.Count > 1)
                {
                    //If multiple matches are found the implicit cast could map to either method, so we can't tell
                    CompilerErrors.InferImplicitCast(pNode.Span);
                    return;
                }
                else if (matches.Count == 1)
                {
                    //Check if we can determine implicit cast type yet
                    for (int j = 0; j < Math.Min(matches[0].ArgumentTypes.Count, pNode.Arguments.Count); j++)
                    {
                        if (SyntaxHelper.IsUndefinedCast(pNode.Arguments[j]))
                        {
                            TrySetImplicitCastType(pNode.Arguments[j], matches[0].ArgumentTypes[j]);
                            types[j] = pNode.Arguments[j].Type;
                        }
                    }
                }
            }



            //Check to ensure this method exists
            var result = SyntaxHelper.FindMethodOnType(out MethodDefinition m, _unit, Namespace, pNode.Value, CurrentType, types);

            switch (result)
            {
            case Compiler.FindResult.NotFound:
                CompilerErrors.MethodNotFound(m, Struct, pNode.Value, pNode.Arguments, pNode.Span);
                return;

            case Compiler.FindResult.IncorrectScope:
                CompilerErrors.MethodNotInScope(m, Struct, pNode.Value, pNode.Arguments, pNode.Span);
                return;
            }

            for (int i = 0; i < m.ArgumentTypes.Count; i++)
            {
                ForceCastLiteral(m.ArgumentTypes[i], pNode.Arguments[i]);
            }

            //Poly our method definition to match any generic types
            m = m.MakeConcreteDefinition(CurrentType);
            pNode.SetType(m.ReturnType);
        }