//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); } } }
//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; } }