Beispiel #1
0
        public override ASTNode VisitReference([NotNull] DaedalusParser.ReferenceContext context)
        {
            List <ReferencePartNode> referencePartNodes = new List <ReferencePartNode>();

            foreach (var referenceAtomContext in context.referenceAtom())
            {
                AttributeNode attributeNode = new AttributeNode(
                    referenceAtomContext.nameNode().GetText(),
                    GetLocation(referenceAtomContext)
                    );
                referencePartNodes.Add(attributeNode);

                if (referenceAtomContext.arrayIndex() != null)
                {
                    ArrayIndexNode arrayIndexNode = (ArrayIndexNode)VisitArrayIndex(referenceAtomContext.arrayIndex());
                    attributeNode.ArrayIndexNode = arrayIndexNode;
                    referencePartNodes.Add(arrayIndexNode);
                }
            }

            string name = ((AttributeNode)referencePartNodes[0]).Name;

            referencePartNodes.RemoveAt(0);
            ReferenceNode referenceNode = new ReferenceNode(name, referencePartNodes, GetLocation(context));

            ReferenceNodes.Add(referenceNode);
            return(referenceNode);
        }
Beispiel #2
0
        protected override NodeValue VisitArrayIndexNode(ArrayIndexNode arrayIndexNode)
        {
            if (arrayIndexNode.ParentNode.Annotations.Count > 0)
            {
                return(null);
            }

            arrayIndexNode.Value = Visit(arrayIndexNode.ExpressionNode);

            switch (arrayIndexNode.Value)
            {
            case IntValue arrayIndexValue:
                ReferenceNode referenceNode = (ReferenceNode)arrayIndexNode.ParentNode;
                if (referenceNode.Symbol == null)
                {
                    break;
                }

                if (referenceNode.Symbol.Node is IArrayDeclarationNode arrayDeclarationNode)
                {
                    NodeValue arraySizeNodeValue = Visit(arrayDeclarationNode.ArraySizeNode);
                    if (arraySizeNodeValue is IntValue arraySizeValue)
                    {
                        if (arrayIndexValue.Value >= arraySizeValue.Value)
                        {
                            arrayIndexNode.Annotations.Add(new IndexOutOfRangeError(arraySizeValue.Value));    //+
                            return(new UndefinedValue());
                        }

                        if (arrayIndexValue.Value > 255)
                        {
                            arrayIndexNode.Annotations.Add(new TooBigArrayIndexError());    //+
                            return(new UndefinedValue());
                        }
                    }
                    else
                    {
                        return(new UndefinedValue());
                    }
                }
                break;

            case UndefinedValue _:
                break;

            default:
                arrayIndexNode.Annotations.Add(new ArrayIndexNotConstIntegerError());
                return(new UndefinedValue());
            }


            return(arrayIndexNode.Value);
        }
        public ReferenceNode(string name, List <ReferencePartNode> partNodes, NodeLocation location) : base(location)
        {
            Symbol     = null;
            BaseSymbol = null;
            Name       = name;
            PartNodes  = partNodes;
            IndexNode  = null;

            DoCastToInt = false;
            DoesHaveNestedAttributes = false;

            /*
             * When CastToInt = true, this node should produce PushInt instruction.
             * It should happen in following situations:
             * - assignment/return/parameter of type func
             * - assignment/return/parameter of type int && symbol's builtin type isn't int
             * - inside conditional
             */

            foreach (var partNode in partNodes)
            {
                partNode.ParentNode = this;
            }
        }
Beispiel #4
0
        protected override void VisitReference(ReferenceNode referenceNode)
        {
            Symbol symbol = GetBaseReferenceSymbol(referenceNode);

            referenceNode.BaseSymbol = symbol;
            if (symbol == null)
            {
                referenceNode.Annotations.Add(new UndeclaredIdentifierError(referenceNode.Name));
                return;
            }

            if (symbol.Node.Annotations.Count > 0)
            {
                return;
            }

            DeclarationNode declarationNode;

            declarationNode = (DeclarationNode)symbol.Node;
            declarationNode.Usages.Add(referenceNode);

            int            attributeDepth      = 0;
            bool           arrayIndexNodeFound = false;
            ArrayIndexNode firstArrayIndexNode = null;

            string symbolLocalPath = referenceNode.Name;

            foreach (ReferencePartNode partNode in referenceNode.PartNodes)
            {
                if (arrayIndexNodeFound)
                {
                    partNode.Annotations.Add(new AccessToAttributeOfArrayElementNotSupportedError());
                    return;
                }

                switch (partNode)
                {
                case AttributeNode attributeNode:


                    NestableSymbol resultNestableSymbol;
                    switch (symbol)
                    {
                    case InstanceSymbol instanceSymbol:
                        ClassSymbol baseClassSymbol = instanceSymbol.BaseClassSymbol;
                        if (baseClassSymbol != null)
                        {
                            if (baseClassSymbol.BodySymbols.TryGetValue(attributeNode.Name.ToUpper(), out resultNestableSymbol))
                            {
                                symbol               = resultNestableSymbol;
                                symbolLocalPath      = $"{symbolLocalPath}.{attributeNode.Name}";
                                attributeNode.Symbol = symbol;
                                attributeDepth++;

                                declarationNode = (DeclarationNode)symbol.Node;
                                declarationNode.Usages.Add(attributeNode);
                            }
                            else
                            {
                                attributeNode.Annotations.Add(new ClassDoesNotHaveAttributeError(symbolLocalPath, baseClassSymbol.Name, attributeNode.Name));
                                return;
                            }
                        }
                        else
                        {
                            // TODO shouldn't we annotate something here?
                        }
                        break;

                    case NestableSymbol nestableSymbol:
                        if (nestableSymbol.ComplexType is ClassSymbol classSymbol)
                        {
                            if (classSymbol.BodySymbols.TryGetValue(attributeNode.Name.ToUpper(), out resultNestableSymbol))
                            {
                                symbol               = resultNestableSymbol;
                                symbolLocalPath      = $"{symbolLocalPath}.{attributeNode.Name}";
                                attributeNode.Symbol = symbol;
                                attributeDepth++;

                                declarationNode = (DeclarationNode)symbol.Node;
                                declarationNode.Usages.Add(attributeNode);
                            }
                            else
                            {
                                attributeNode.Annotations.Add(new ClassDoesNotHaveAttributeError(symbolLocalPath, classSymbol.Name, attributeNode.Name));         //TODO does it ever occur?
                                return;
                            }
                        }
                        else
                        {
                            attributeNode.Annotations.Add(new AttributeOfNonInstanceError(attributeNode.Name, symbolLocalPath));
                        }
                        break;


                    default:
                        attributeNode.Annotations.Add(new AttributeOfNonInstanceError(attributeNode.Name, symbolLocalPath));
                        return;
                    }
                    break;

                case ArrayIndexNode arrayIndexNode:
                    arrayIndexNodeFound = true;
                    firstArrayIndexNode = arrayIndexNode;

                    if (!(symbol.Node is IArrayDeclarationNode))
                    {
                        referenceNode.Annotations.Add(new ReferencedSymbolIsNotArrayError(referenceNode.Name));
                        return;
                    }

                    ArrayIndexNodes.Add(arrayIndexNode);
                    break;

                default:
                    throw new Exception();
                }
            }
            referenceNode.Symbol    = symbol;
            referenceNode.IndexNode = firstArrayIndexNode;
            if (attributeDepth > 1)
            {
                referenceNode.DoesHaveNestedAttributes = true;
            }
        }
Beispiel #5
0
 protected virtual T VisitArrayIndexNode(ArrayIndexNode arrayIndexNode)
 {
     Visit(arrayIndexNode.ExpressionNode);
     return(DefaultResult);
 }
 protected virtual void VisitArrayIndexNode(ArrayIndexNode arrayIndexNode)
 {
     Visit(arrayIndexNode.ExpressionNode);
 }
 public AttributeNode(string name, NodeLocation location) : base(location)
 {
     Name           = name;
     ArrayIndexNode = null;
 }