Пример #1
0
 internal ModuleReference(CodeFrame parent, string moduleName, string dllName, string[] path, int line, int column, bool requireQualified, int logicalHandle)
 {
     ModuleName        = moduleName;
     DllName           = dllName;
     Path              = path ?? new string[0];
     Line              = line;
     Column            = column;
     RequireQuailified = requireQualified;
     LogicalHandle     = logicalHandle;
     Parent            = parent;
 }
Пример #2
0
        //This function tries to autogenerate an instance (similar to derived in Haskell).
        //It can fully or partially generate it. A default instance (instance without a type) is
        //used for such purpose.
        private List <String> TryGenerateMembers(List <String> members, CodeFrame mod, ElaClassInstance inst)
        {
            if (members.Count == 0)
            {
                return(members);
            }

            var newMem = new List <String>(members);

            for (var i = 0; i < newMem.Count; i++)
            {
                var m     = newMem[i];
                var btVar = ObtainClassFunction(inst.TypeClassPrefix, inst.TypeClassName, m, inst.Line, inst.Column);

                //This is less likely but we better check this anyway
                if (btVar.IsEmpty())
                {
                    AddError(ElaCompilerError.MemberInvalid, inst, m, inst.TypeClassName);
                }

                var defVar = GetGlobalVariable("$default$" + m, GetFlags.NoError, inst.Line, inst.Column);

                //We dont' need to generate errors here, errors will be captured later.
                if (!defVar.IsEmpty())
                {
                    var builtin = (btVar.Flags & ElaVariableFlags.Builtin) == ElaVariableFlags.Builtin;

                    //Check if this member is implemented directly by compiler
                    if (!TryAutogenerate(defVar, inst))
                    {
                        PushVar(defVar);
                    }

                    if (!builtin)
                    {
                        PushVar(btVar);
                    }
                    else
                    {
                        cw.Emit(Op.PushI4, (Int32)btVar.Data);
                    }

                    EmitSpecName(inst.TypePrefix, "$$" + inst.TypeName, inst, ElaCompilerError.UndefinedType);
                    cw.Emit(Op.Addmbr);
                    members.Remove(m);
                }
            }

            return(members);
        }
Пример #3
0
        private ExportVars exports;                      //Exports for current module

        //globalScope is not empty (e.g. new Scope()) only if we are resuming in interactive mode
        internal Builder(CodeFrame frame, ElaCompiler comp, ExportVars exportVars, Scope globalScope)
        {
            this.frame       = frame;
            this.options     = comp.Options;
            this.exports     = exportVars;
            this.comp        = comp;
            this.cw          = new CodeWriter(frame.Ops, frame.OpData);
            this.globalScope = globalScope;

            CurrentScope = globalScope;
            debug        = options.GenerateDebugInfo;
            opt          = options.Optimize;

            stringLookup = new Dictionary <String, Int32>();
            cleans.Push(true);

            ResumeIndexer();
            Success = true;
        }
Пример #4
0
        public CodeFrame Clone()
        {
            var copy = new CodeFrame();

            copy.Layouts     = Layouts.Clone();
            copy.Strings     = Strings.Clone();
            copy.GlobalScope = GlobalScope.Clone();
            copy.Ops         = Ops.Clone();
            copy.OpData      = OpData.Clone();
            copy._references = new ReferenceMap(_references);
            copy.Symbols     = Symbols != null?Symbols.Clone() : null;

            copy.HandleMap            = HandleMap.Clone();
            copy.InternalTypes        = new Dictionary <String, Int32>(InternalTypes);
            copy._internalClasses     = new ClassMap(_internalClasses);
            copy.InternalInstances    = InternalInstances.Clone();
            copy.LateBounds           = LateBounds.Clone();
            copy.InternalConstructors = InternalConstructors.Clone();
            return(copy);
        }
Пример #5
0
        //A generic method used to loop a prefixed var in a module.
        private ScopeVar FindByPrefix(string prefix, string var, out CodeFrame fr)
        {
            var sv  = GetVariable(prefix, CurrentScope, GetFlags.NoError, 0, 0);
            var mod = default(ModuleReference);

            fr = null;

            //Looks like a target object is not a module
            if ((sv.Flags & ElaVariableFlags.Module) != ElaVariableFlags.Module ||
                !frame.References.TryGetValue(prefix, out mod))
            {
                return(ScopeVar.Empty);
            }

            var fieldSv = default(ScopeVar);

            //We have such a reference but looks like it couldn't be obtained
            //We don't need to handle this situation here, it is already reported by a linker
            fr = refs[mod.LogicalHandle];

            if (fr == null)
            {
                return(ScopeVar.Empty);
            }

            //No such name, now captured statically
            if (!refs[mod.LogicalHandle].GlobalScope.Locals.TryGetValue(var, out fieldSv) &&
                !options.IgnoreUndefined)
            {
                return(ScopeVar.Empty);
            }

            //Name is private, now captured statically
            if ((fieldSv.VariableFlags & ElaVariableFlags.Private) == ElaVariableFlags.Private)
            {
                return(ScopeVar.Empty);
            }

            return(new ScopeVar(fieldSv.Flags | ElaVariableFlags.External, mod.LogicalHandle | fieldSv.Address << 8, fieldSv.Data));
        }
Пример #6
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);
                }
            }
        }
Пример #7
0
        public CompilerResult Compile(ElaProgram prog, CompilerOptions options, ExportVars builtins, CodeFrame frame, Scope globalScope)
        {
            Options = options;
            var helper = new Builder(frame, this, builtins, globalScope);

            try
            {
                helper.CompileUnit(prog);
            }
            catch (TerminationException)
            {
                //Nothing should be done here. This was thrown to stop compilation.
            }
#if !DEBUG
            catch (Exception ex)
            {
                if (ex is ElaCompilerException)
                {
                    throw;
                }

                throw new ElaCompilerException(Strings.GetMessage("Ice", ex.Message), ex);
            }
#endif

            frame.Symbols = frame.Symbols == null ? helper.Symbols :
                            helper.Symbols != null?frame.Symbols.Merge(helper.Symbols) : frame.Symbols;

            frame.GlobalScope = globalScope;
            return(new CompilerResult(frame, helper.Success, helper.Errors.ToArray()));
        }
Пример #8
0
        public CompilerResult Compile(ElaProgram prog, CompilerOptions options, ExportVars builtins)
        {
            var frame = new CodeFrame();

            return(Compile(prog, options, builtins, frame, new Scope(false, null)));
        }
Пример #9
0
 internal ModuleReference(CodeFrame parent, string moduleName) : this(parent, moduleName, null, null, 0, 0, false, 0)
 {
 }
Пример #10
0
 internal CompilerResult(CodeFrame frame, bool success, IEnumerable <ElaMessage> messages) : base(success, messages)
 {
     CodeFrame = frame;
 }