Beispiel #1
0
//-----------------------------------------------------------------------------
// Parse a Type Sig
//
// ** rules **
// TypeSig -> id ('.' id)* '[ ','* ]'*
//-----------------------------------------------------------------------------
    protected NonRefTypeSig ParseTypeSig()
    {
    // Currently, we implement this by parsing ObjExpressions. That's easier
    // for us, but may let us parse illegal things. That's ok. The TypeSig
    // container class along with semantic checking will still give us the
    // expected error control.
        NonRefTypeSig sig = null;
    
        Identifier stId = ReadExpectedIdentifier();        
        Exp o = new SimpleObjExp(stId);
        
        Token t = m_lexer.PeekNextToken();        
        while (t.TokenType == Token.Type.cDot)
        {
            ConsumeNextToken();
        
            stId = ReadExpectedIdentifier();
            o = new DotObjExp(o, stId);
                        
            t = m_lexer.PeekNextToken();
        }  
        
        sig = new SimpleTypeSig(o);
        
    // Check for arrays
        while (t.TokenType == Token.Type.cLRSquare)
        {   
            sig = new ArrayTypeSig(sig, 1);
            
            ConsumeNextToken();            
            t = m_lexer.PeekNextToken();
        }          
                
        return sig;
    }
Beispiel #2
0
//-----------------------------------------------------------------------------
// Parse a new Expression (either array or non-array)
// -> 'new' id_list '(' exp, exp ... ')'
//
// -> 'new' id_list '[x]' '[]'* array_init?
// -> 'new' id_list '[]'* array_init
// 
// array_init-> '{' exp, exp, exp, ...'}'
//-----------------------------------------------------------------------------
    protected Exp ParseNewExp()
    {                   
        ReadExpectedToken(Token.Type.cNew);
                   
        // A typesig would allow [] to be part of the type
        // An id_list doesn't.
        Exp oe = ParseDottedIdList();
        SimpleTypeSig type = new SimpleTypeSig(oe);
        
        Token t2 = m_lexer.PeekNextToken();
        
        // If next is a '(', then this is a ctor call (and not an array)
        if (t2.TokenType == Token.Type.cLParen)
        {                
            Exp [] eList = ParseExpList();
            Exp e = new NewObjExp(type, eList);
            return e;
        } 
        
        // Array case
        if (t2.TokenType == Token.Type.cLRSquare || t2.TokenType == Token.Type.cLSquare)
        {            
                            
            ArrayTypeSig typeArray = null;
            ArrayInitializer init = null;
                            
            // dynamic size explicitly in rank specifier
            // -> 'new' id_list '[x]' '[]'* array_init?                
            if (t2.TokenType == Token.Type.cLSquare)
            {                    
                Exp [] eList = ParseExpList(Token.Type.cLSquare, Token.Type.cRSquare); // includes [ and ]
                                
                int dim = eList.Length;
                                            
                NonRefTypeSig s = ParseOptionalArrayDecl(type);
                typeArray = new ArrayTypeSig(s, dim);
                
                if (m_lexer.PeekNextToken().TokenType == Token.Type.cLCurly)
                {
                    init = this.ParseArrayInitList();
                }
                
                Exp e = new NewArrayObjExp(typeArray,eList,init);
                return e;
            }
            
            // static size implicitly from array_initializer
            // -> 'new' id_list '[]'* array_init
            else if (t2.TokenType == Token.Type.cLRSquare)
            {
                NonRefTypeSig t = ParseOptionalArrayDecl(type);
                typeArray = t.AsArraySig;
                init = this.ParseArrayInitList();
                
                Exp e = new NewArrayObjExp(typeArray,init);
                return e;
            }
        } 
        
        
        ThrowError(E_UnexpectedToken(t2));
        return null;
    }    
Beispiel #3
0
//-----------------------------------------------------------------------------
// Helper to parse array decls.
// For arrays, leftmost [] is the outermost
// So X[][,,][,] is 1d of 3d of 2d of X
// Because this is left to right (and not right to left), we have to be
// stack based / recursive (instead of an iterative while)
// 
// sigElemType is the type of the non-array portion (X in the above example)
// Note that if this isn't an array type, we'll just return sigElemType
//-----------------------------------------------------------------------------
    NonRefTypeSig ParseOptionalArrayDecl(NonRefTypeSig sigElemType)
    {
        Token t = m_lexer.PeekNextToken();
        
        if (t.TokenType == Token.Type.cLRSquare)
        {
            ConsumeNextToken();
            
            int dim = t.Dimension;
            NonRefTypeSig sig = ParseOptionalArrayDecl(sigElemType);
            sig = new ArrayTypeSig(sig, dim);
            
            string stTest = sig.ToString();
            
            return sig;
            
        } else {
            return sigElemType;
        }
    }
Beispiel #4
0
 public NewArrayObjExp(
     ArrayTypeSig tArrayType,    // full array type (includes rank)
     Exp [] arExpSize,           // rank to allocate, eval at runtime
     ArrayInitializer aInit      // optional initilizer list        
 )
 {
     Debug.Assert(tArrayType != null);
     Debug.Assert(arExpSize != null);
     
     m_tFullType = tArrayType;
     this.m_arExpList = arExpSize;
     this.m_ArrayInit = aInit;
     
     // @todo - this is wrong
     m_filerange = tArrayType.Location;
 }        
Beispiel #5
0
    // Implicit size from init list
    public NewArrayObjExp(
        ArrayTypeSig tArrayType,    // includes rank specifiers
        ArrayInitializer aInit      // mandatory
    )
    {
        Debug.Assert(tArrayType != null);
        Debug.Assert(aInit != null);
        
        m_tFullType = tArrayType;
        this.m_arExpList = null;
        this.m_ArrayInit = aInit;

        // @todo - this is wrong
        m_filerange = tArrayType.Location;    
    }
Beispiel #6
0
    // Semantic resolution
    protected override Exp ResolveExpAsRight(ISemanticResolver s)
    {   
        // Only resolve once.     
        if (m_symbol != null)
            return this;
            
        // First, resolve our parameters (because of overloading)
        // We need to know the URT types for our parameters
        // in order to resolve between overloaded operators
        
        Type [] alParamTypes = new Type[m_arParams.Length];
        
        
        for(int i = 0; i < m_arParams.Length; i++)        
        {
            Exp e = m_arParams[i];
            ResolveExpAsRight(ref e, s);
            Debug.Assert(e == m_arParams[i]);
            
            Type tParam = e.CLRType;
            
            //if ((tParam !=null) && tParam.IsByRef)
            //    tParam = tParam.GetElementType();
            
            alParamTypes[i] = tParam;
            //Debug.Assert(alParamTypes[i] != null);
            
        }   
        
        TypeEntry tCur = s.GetCurrentClass();    
        TypeEntry tLeft = null; // Type to lookup in   
        
        // Is this a 'base' access?
        // Convert to the real type and set a non-virtual flag
        if (m_objExp is SimpleObjExp)
        {
            SimpleObjExp e = m_objExp as SimpleObjExp;
            if (e.Name.Text == "base")
            {
                // Set the scope that we lookup in.
                tLeft = tCur.Super;
                
                // Still need to resolve the expression.
                m_objExp = new SimpleObjExp("this");               
                                               
                m_fIsNotPolymorphic = true;
            }
        }
        
#if true
        // See if we have a delegate here
        Exp eDelegate = null;
        if (m_objExp == null)
        {
            Exp e = new SimpleObjExp(m_idName);
            Exp.ResolveExpAsRight(ref e, s);
            if (!(e is SimpleObjExp))                
                eDelegate = e;
        } else {
            // If it's an interface, then we know we can't have a delegate field on it, 
            // so short-circuit now. 
            Exp.ResolveExpAsRight(ref m_objExp, s);
            if (!m_objExp.CLRType.IsInterface)
            {                
                Exp e = new DotObjExp(m_objExp, m_idName);
                Exp.ResolveExpAsRight(ref e, s);
                if (!(e is DotObjExp))                
                    eDelegate = e;        
            }
        }

        if (eDelegate != null)
        {
            if (!DelegateDecl.IsDelegate(eDelegate.CLRType))
            {
                //Debug.Assert(false, "@todo - " + m_strName + " is not a delegate or function"); // @todo - legit
                // Just fall through for now, method resolution will decide if this is a valid function
            } else 
            {            
                Exp e = new MethodCallExp(
                    eDelegate, 
                    new Identifier("Invoke"), 
                    this.m_arParams
                );
                
                Exp.ResolveExpAsRight(ref e, s);
                return e;        
            }
        }        
#endif    
        // No delegate, carry on with a normal function call
                        
        // If there's no objexp, then the function is a method
        // of the current class. 
        // make it either a 'this' or a static call
        if (m_objExp == null)
        {   
            // Lookup
            bool fIsVarArgDummy;
            MethodExpEntry sym = tCur.LookupMethod(s, m_idName, alParamTypes, out fIsVarArgDummy);
            
            if (sym.IsStatic)
            {                
                m_objExp = new TypeExp(tCur);
            } else {
                m_objExp = new SimpleObjExp("this");
            }
        }
        
        // Need to Lookup m_strName in m_objExp's scope (inherited scope)
        Exp.ResolveExpAsRight(ref m_objExp, s);
                    
                
        // Get type of of left side object
        // This call can either be a field on a variable
        // or a static method on a class
        
        bool fIsStaticMember = false;
        
        // If we don't yet know what TypeEntry this methodcall is on, then figure
        // it out based off the expression
        if (tLeft == null)
        {
            if (m_objExp is TypeExp)
            {
                fIsStaticMember = true;
                tLeft = ((TypeExp) m_objExp).Symbol;
            } else {
                fIsStaticMember = false;
                tLeft = s.ResolveCLRTypeToBlueType(m_objExp.CLRType);
            }
        }
        
        // Here's the big lookup. This will jump through all sorts of hoops to match
        // parameters, search base classes, do implied conversions, varargs, 
        // deal with abstract, etc.
        bool fIsVarArg;
        m_symbol = tLeft.LookupMethod(s, m_idName, alParamTypes, out fIsVarArg);
        Debug.Assert(m_symbol != null);
        
        if (m_fIsNotPolymorphic)
        {
            // of the form 'base.X(....)'
            if (m_symbol.IsStatic)
                ThrowError(SymbolError.BaseAccessCantBeStatic(this.Location, m_symbol)); // @todo - PrintError?
        } else {
            // normal method call
            /*
            if (fIsStaticMember && !m_symbol.IsStatic)
                ThrowError(SymbolError.ExpectInstanceMember(this.Location)); // @todo - PrintError?
            else if (!fIsStaticMember && m_symbol.IsStatic)                
                ThrowError(SymbolError.ExpectStaticMember(this.Location)); // @todo - PrintError?
            */
            Debug.Assert(fIsStaticMember == m_symbol.IsStatic, "@todo - user error. Mismatch between static & instance members on line.");
        }
        
        
        // If we have a vararg, then transform it 
        if (fIsVarArg)
        {
        // Create the array
            int cDecl = m_symbol.ParamCount;
            int cCall = this.ParamExps.Length;
            
            ArrayTypeSig tSig = new ArrayTypeSig(m_symbol.ParamCLRType(cDecl - 1), s);
            
            Node [] list = new Node[cCall - cDecl + 1];
            for(int i = 0; i < list.Length; i++)
            {
                list[i] = this.ParamExps[i + cDecl - 1];
            }
            
            Exp eArray = new NewArrayObjExp(
                tSig,
                new ArrayInitializer(
                    list
                )
            );
            
            Exp.ResolveExpAsRight(ref eArray, s);
            
        // Change the parameters to use the array    
            ArgExp [] arParams = new ArgExp[cDecl];
            for(int i = 0; i < cDecl - 1; i++)
                arParams[i] = m_arParams[i];
            arParams[cDecl - 1] = new ArgExp(EArgFlow.cIn, eArray);
            
            m_arParams = arParams;                            
        } // end vararg transformation
                
        this.CalcCLRType(s);
   
        return this;
    }