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; }
//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); }
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; }
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); }
//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)); }
//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); } } }
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())); }
public CompilerResult Compile(ElaProgram prog, CompilerOptions options, ExportVars builtins) { var frame = new CodeFrame(); return(Compile(prog, options, builtins, frame, new Scope(false, null))); }
internal ModuleReference(CodeFrame parent, string moduleName) : this(parent, moduleName, null, null, 0, 0, false, 0) { }
internal CompilerResult(CodeFrame frame, bool success, IEnumerable <ElaMessage> messages) : base(success, messages) { CodeFrame = frame; }