Example #1
0
        //This method returns type class data including: type class metadata (ClassData), module local ID
        //(modId) and compiled module where class is defined.
        private int ObtainTypeClass(ElaClassInstance s, out ClassData mbr, out int modId, out CodeFrame mod)
        {
            mbr   = null;
            modId = -1;
            mod   = null;

            //If a type class prefix is not set we need to obtain a type class ID using a special '$$$*' variable
            //that is initialized during type class compilation
            if (s.TypeClassPrefix == null)
            {
                //We first check if a class definition is non-local
                if (!frame.InternalClasses.TryGetValue(s.TypeClassName, out mbr))
                {
                    var sv = GetVariable("$$$" + s.TypeClassName, CurrentScope, GetFlags.NoError, s.Line, s.Column);

                    if (sv.IsEmpty() && !options.IgnoreUndefined)
                    {
                        AddError(ElaCompilerError.UnknownClass, s, s.TypeClassName);
                        return(-1);
                    }

                    //The trick is - here sv can be only an external name (we do check prior to this
                    //if a class is not local). If it is an external name that first byte contains a
                    //local index of a referenced module - that is exactly what we need here to obtain
                    //a compiled module frame (from refs array).
                    modId = sv.Address & Byte.MaxValue;

                    if (modId < refs.Count && modId >= 0)
                    {
                        mod = refs[modId];
                    }

                    return(sv.Data);
                }
                else
                {
                    var sv = GetVariable("$$$" + s.TypeClassName, CurrentScope, GetFlags.NoError, s.Line, s.Column);
                    return(sv.Data);
                }
            }
            else
            {
                //Type class prefix is set. The prefix itself should be local name (a module alias)
                var sv = GetVariable(s.TypeClassPrefix, s.Line, s.Column);

                if (sv.IsEmpty())
                {
                    return(-1);
                }

                //A name was found but this is not a module alias
                if ((sv.Flags & ElaVariableFlags.Module) != ElaVariableFlags.Module)
                {
                    AddError(ElaCompilerError.InvalidQualident, s, s.TypeClassPrefix);
                    return(-1);
                }

                //In this case we can look for a reference based on its alias (alias should be unique within
                //the current module).
                modId = frame.References[s.TypeClassPrefix].LogicalHandle;

                if (modId < refs.Count && modId >= 0)
                {
                    mod = refs[modId];
                }

                //Now we need to obtain 'data' of a type class variable - it might a type class
                //typeId if this type class is built-in.
                ScopeVar sv2;

                if (mod != null && mod.GlobalScope.Locals.TryGetValue("$$$" + s.TypeClassName, out sv2))
                {
                    return(sv.Data);
                }
                else
                {
                    return(-1);
                }
            }
        }
Example #2
0
        //This method returns type class data including: type class metadata (ClassData), module local ID
        //(modId) and compiled module where class is defined.
        private int ObtainTypeClass(ElaClassInstance s, out ClassData mbr, out int modId, out CodeFrame mod)
        {
            mbr = null;
            modId = -1;
            mod = null;

            //If a type class prefix is not set we need to obtain a type class ID using a special '$$$*' variable
            //that is initialized during type class compilation
            if (s.TypeClassPrefix == null)
            {
                //We first check if a class definition is non-local
                if (!frame.InternalClasses.TryGetValue(s.TypeClassName, out mbr))
                {
                    var sv = GetVariable("$$$" + s.TypeClassName, CurrentScope, GetFlags.NoError, s.Line, s.Column);

                    if (sv.IsEmpty() && !options.IgnoreUndefined)
                    {
                        AddError(ElaCompilerError.UnknownClass, s, s.TypeClassName);
                        return -1;
                    }

                    //The trick is - here sv can be only an external name (we do check prior to this
                    //if a class is not local). If it is an external name that first byte contains a
                    //local index of a referenced module - that is exactly what we need here to obtain
                    //a compiled module frame (from refs array).
                    modId = sv.Address & Byte.MaxValue;

                    if (modId < refs.Count && modId >= 0)
                        mod = refs[modId];

                    return sv.Data;
                }
                else
                {
                    var sv = GetVariable("$$$" + s.TypeClassName, CurrentScope, GetFlags.NoError, s.Line, s.Column);
                    return sv.Data;
                }
            }
            else
            {
                //Type class prefix is set. The prefix itself should be local name (a module alias)
                var sv = GetVariable(s.TypeClassPrefix, s.Line, s.Column);

                if (sv.IsEmpty())
                    return -1;

                //A name was found but this is not a module alias
                if ((sv.Flags & ElaVariableFlags.Module) != ElaVariableFlags.Module)
                {
                    AddError(ElaCompilerError.InvalidQualident, s, s.TypeClassPrefix);
                    return -1;
                }

                //In this case we can look for a reference based on its alias (alias should be unique within
                //the current module).
                modId = frame.References[s.TypeClassPrefix].LogicalHandle;

                if (modId < refs.Count && modId >= 0)
                    mod = refs[modId];

                //Now we need to obtain 'data' of a type class variable - it might a type class
                //typeId if this type class is built-in.
                ScopeVar sv2;

                if (mod != null && mod.GlobalScope.Locals.TryGetValue("$$$" + s.TypeClassName, out sv2))
                    return sv.Data;
                else
                    return -1;
            }
        }