//This method is used to generate Push* op typeId for a special name prefixed by $$ or $$$. //Such names are used for hidden variables that contains unique codes of types and classes. //This method can emit a qualified name (with a module prefix) as well as a short name. //It also generates an appropriate error if a name is not found. //Specifying ElaCompilerError.None would force this method to not generate any error messages. private ScopeVar EmitSpecName(string ns, string specName, ElaExpression exp, ElaCompilerError err, out int modId) { if (ns != null) { var v = GetVariable(ns, exp.Line, exp.Column); //A prefix (ns) is not a module alias which is an error if ((v.Flags & ElaVariableFlags.Module) != ElaVariableFlags.Module && err != ElaCompilerError.None) AddError(ElaCompilerError.InvalidQualident, exp, ns); ModuleReference mr; var lh = -1; if (frame.References.TryGetValue(ns, out mr)) lh = mr.LogicalHandle; var extVar = default(ScopeVar); var mod = lh > -1 && lh < refs.Count ? refs[lh] : null; //A name (or even module) not found, generate an error if ((mod == null || !mod.GlobalScope.Locals.TryGetValue(specName, out extVar)) && !options.IgnoreUndefined && err != ElaCompilerError.None) { //No need to apped alias if we want to generate UndefinedName. That would be misleading. if (err == ElaCompilerError.UndefinedName) AddError(err, exp, specName.TrimStart('$')); else AddError(err, exp, ns + "." + specName.TrimStart('$')); } if ((extVar.Flags & ElaVariableFlags.Private) == ElaVariableFlags.Private && err != ElaCompilerError.None) AddError(ElaCompilerError.PrivateNameInModule, exp, specName.TrimStart('$'), ns); modId = lh; extVar = new ScopeVar(extVar.Flags | ElaVariableFlags.External, lh | (extVar.Address << 8), extVar.Data); PushVar(extVar); return extVar; } else { //Without a qualident it is pretty straightforward var a = GetVariable(specName, CurrentScope, GetFlags.NoError, exp.Line, exp.Column); if (a.IsEmpty() && !options.IgnoreUndefined && err != ElaCompilerError.None) AddError(err, exp, specName.TrimStart('$')); modId = (a.Flags & ElaVariableFlags.External) == ElaVariableFlags.External ? a.Address & Byte.MaxValue : -1; PushVar(a); return a; } }
private void AddError(ElaCompilerError error, int line, int col, params object[] args) { Errors.Add(new ElaMessage(Strings.GetError(error, args), MessageType.Error, (Int32)error, line, col)); Success = false; //This is an ad-hoc error limit if (Errors.Count >= 101) { //We generate a 'Too many errors' message and terminate compilation. Errors.Add(new ElaMessage(Strings.GetError(ElaCompilerError.TooManyErrors), MessageType.Error, (Int32)ElaCompilerError.TooManyErrors, line, col)); throw new TerminationException(); } }
internal static string GetError(ElaCompilerError error, params object[] args) { return(String.Format(errors.GetString(error.ToString()), args)); }
private void AddError(ElaCompilerError error, ElaExpression exp, params object[] args) { AddError(error, exp.Line, exp.Column, args); }
internal static string GetError(ElaCompilerError error, params object[] args) { return String.Format(errors.GetString(error.ToString()), args); }
//This method is used to generate Push* op typeId for a special name prefixed by $$ or $$$. //Such names are used for hidden variables that contains unique codes of types and classes. //This method can emit a qualified name (with a module prefix) as well as a short name. //It also generates an appropriate error if a name is not found. //Specifying ElaCompilerError.None would force this method to not generate any error messages. private ScopeVar EmitSpecName(string ns, string specName, ElaExpression exp, ElaCompilerError err, out int modId) { if (ns != null) { var v = GetVariable(ns, exp.Line, exp.Column); //A prefix (ns) is not a module alias which is an error if ((v.Flags & ElaVariableFlags.Module) != ElaVariableFlags.Module && err != ElaCompilerError.None) { AddError(ElaCompilerError.InvalidQualident, exp, ns); } ModuleReference mr; var lh = -1; if (frame.References.TryGetValue(ns, out mr)) { lh = mr.LogicalHandle; } var extVar = default(ScopeVar); var mod = lh > -1 && lh < refs.Count ? refs[lh] : null; //A name (or even module) not found, generate an error if ((mod == null || !mod.GlobalScope.Locals.TryGetValue(specName, out extVar)) && !options.IgnoreUndefined && err != ElaCompilerError.None) { //No need to apped alias if we want to generate UndefinedName. That would be misleading. if (err == ElaCompilerError.UndefinedName) { AddError(err, exp, specName.TrimStart('$')); } else { AddError(err, exp, ns + "." + specName.TrimStart('$')); } } if ((extVar.Flags & ElaVariableFlags.Private) == ElaVariableFlags.Private && err != ElaCompilerError.None) { AddError(ElaCompilerError.PrivateNameInModule, exp, specName.TrimStart('$'), ns); } modId = lh; extVar = new ScopeVar(extVar.Flags | ElaVariableFlags.External, lh | (extVar.Address << 8), extVar.Data); PushVar(extVar); return(extVar); } else { //Without a qualident it is pretty straightforward var a = GetVariable(specName, CurrentScope, GetFlags.NoError, exp.Line, exp.Column); if (a.IsEmpty() && !options.IgnoreUndefined && err != ElaCompilerError.None) { AddError(err, exp, specName.TrimStart('$')); } modId = (a.Flags & ElaVariableFlags.External) == ElaVariableFlags.External ? a.Address & Byte.MaxValue : -1; PushVar(a); return(a); } }
//A simplified version of EmitSpecName, when module ID of a name is not needed. private ScopeVar EmitSpecName(string ns, string specName, ElaExpression exp, ElaCompilerError err) { int _; return(EmitSpecName(ns, specName, exp, err, out _)); }
//A simplified version of EmitSpecName, when module ID of a name is not needed. private ScopeVar EmitSpecName(string ns, string specName, ElaExpression exp, ElaCompilerError err) { int _; return EmitSpecName(ns, specName, exp, err, out _); }