Esempio n. 1
0
        private IOperationCollection pushVariableAssignment(Scope scope)
        {
            // We need something of the form "type variableName"
            if (_iterator.Is(TokenType.Name))
            {
                // At this point it is not entirely clear whether we are dealing
                // with a variable assignment. Therefore we have to remember everything
                // we read from now on so that we can restore it.
                _iterator.CreateRevertPoint();

                // Read the variable type
                long   theTypePosition = _iterator.Position;
                string theTypePath;
                string theTypeContextPath;
                IType  theTypeInstance;
                try
                {
                    theTypePath        = string.Join("::", readNamespacePath(false).ToArray());
                    theTypeContextPath = Helper.PrependNamespace(theTypePath, _function.Signature.Namespace); // the current namespace might be implicit
                    if (_function.TypeTable.Has(theTypePath))
                    {
                        theTypeInstance = _function.TypeTable.Lookup(theTypePath);
                    }
                    else if (_function.TypeTable.Has(theTypeContextPath))
                    {
                        theTypeInstance = _function.TypeTable.Lookup(theTypeContextPath);
                    }
                    else
                    {
                        throw new SyntaxException(theTypePosition, "Unrecognized type: " + theTypePath);
                    }
                }
                catch (SyntaxException)
                {
                    // Something failed, so we are not dealing with a variable assignment.
                    // Proceed with the next layer.
                    _iterator.Revert();
                    return(pushAssign(scope));
                }

                // We read the name of the (base) type, now it might be
                // that case that it is followed by arbitrarily many "[]"
                // which indicate an array declaration

                // Read "[]" tokens which identify the type as array type
                int listDimension = 0;
                while (_iterator.Is(TokenType.SquareBracketLeft))
                {
                    listDimension++;
                    _iterator.Next();
                    if (!_iterator.Is(TokenType.SquareBracketRight))
                    {
                        listDimension = -1;
                        break;
                    }
                    _iterator.Next();
                }

                // If reading "[]" did not fail and the next token is a name,
                // we finally know that it *is* a variable assignment
                if (listDimension >= 0 && _iterator.Is(TokenType.Name))
                {
                    // Phew. Now remember to destroy the revert point.
                    _iterator.Commit();

                    // Apply the array dimension to the type
                    for (int i = 0; i < listDimension; i++)
                    {
                        theTypeInstance = new ArrayType(theTypeInstance);
                    }

                    string theVariableName = _iterator.GetValue <string>();
                    _iterator.Next();
                    switch (_iterator.Current.Type)
                    {
                    case TokenType.EndOfInstruction:
                        var ops1 = new OperationCollection();
                        ops1.Append(new SimpleOperation(OperationType.LoadUndefined, theTypePosition));
                        ops1.Append(new TwoParametrizedOperation <IType, string>(OperationType.CreateVariable, theTypePosition, theTypeInstance, theVariableName));
                        return(ops1);

                    case TokenType.OperatorAssign:
                        _iterator.Next();
                        var ops2 = new OperationCollection();
                        ops2.Append(pushAssign(scope));
                        ops2.Append(new TwoParametrizedOperation <IType, string>(OperationType.CreateVariable, theTypePosition, theTypeInstance, theVariableName));
                        return(ops2);

                    default:
                        throw new SyntaxException(_iterator.Position, "Unexpected token: " + _iterator.Current.Type);
                    }
                }
                else
                {
                    // Otherwise restore everything from the revert point
                    // and proceed with the next layer
                    _iterator.Revert();
                    return(pushAssign(scope));
                }
            }
            else
            {
                return(pushAssign(scope));
            }
        }