private void AssignmentPreprocessor(AST.Node lhs) { if (!(lhs is AST.Identifier)) { return; // only need to handle simple assignments } if (!this.isfunction) { return; } AST.Identifier target = (AST.Identifier)lhs; if (target.Type != AST.IdentifierType.UnQualifiedName) { return; } if (target.IsEnclosed) { if (this.variables.LocalAssignment.ContainsKey(target.Name)) { // Found the variable already used in a local assignment target.IsEnclosed = false; this.variables.LocalAssignment[target.Name].Add(target); } else { if (!this.variables.GlobalAssignment.ContainsKey(target.Name)) { // variable did not exists currently as global assignment this.variables.GlobalAssignment[target.Name] = new List <AST.Identifier>(); } // add the target as a global assignment target this.variables.GlobalAssignment[target.Name].Add(target); } } else { if (!this.variables.LocalAssignment.ContainsKey(target.Name)) { this.variables.LocalAssignment[target.Name] = new List <AST.Identifier>(); } if (this.variables.GlobalAssignment.ContainsKey(target.Name)) { // found the same variable as a global assignment target // move it to the local assignments foreach (AST.Identifier item in this.variables.GlobalAssignment[target.Name]) { item.IsEnclosed = false; this.variables.LocalAssignment[target.Name].Add(item); } // remove from the global assignments' list this.variables.GlobalAssignment.Remove(target.Name); } this.variables.LocalAssignment[target.Name].Add(target); } }
public void AddAccess(AST.Identifier variable) { if (!this.Accessing.ContainsKey(variable.Name)) { this.Accessing[variable.Name] = new List <AST.Identifier>(); } this.Accessing[variable.Name].Add(variable); }
/// <summary> /// Checks if an identifier is a reserved word, and throws an exception if that is the case /// </summary> /// <param name="identifier">The identifier to check</param> private void CheckIdentifier(AST.Identifier identifier) { if (AST.Identifier.IsReservedKeyword(identifier.Name)) { throw new ParserException($"The word {identifier.Name} is a keyword", identifier); } if (AST.DataType.IsValidIntrinsicType(identifier.Name)) { throw new ParserException($"The name {identifier.Name} is a a built-in type name", identifier); } }
public static AST.INode Parse(CharStream stream) { var startingPos = stream.Position; try { AST.INode root; if(!Property.PeekAndParse(stream, out root)) { root = IdentifierExpression.Parse(stream); } stream.SkipString("::"); // we either have an expression or a simple identifier AST.INode identifier; if (stream.SkipIfPossible('[')) { identifier = Expression.Parse(stream); stream.SkipCharacter(']'); } else { identifier = new AST.Identifier(Identifier.Parse(stream, false)); } // We can also have optionally a property expression, // starting with a simple identifier or straight away with an expression AST.PropertyExpression propertyExpression = null; if (stream.SkipIfPossible('.')) { propertyExpression = Property.Parse(stream) as AST.PropertyExpression; } else if (stream.SkipIfPossible('[')) { var expression = Expression.Parse(stream); propertyExpression = new AST.PropertyExpression(expression); stream.SkipCharacter(']'); Property.Parse(stream, propertyExpression); } return new AST.AttributeExpression(root, identifier, propertyExpression); } catch (Exception e) { string msg = String.Format( "something went wrong parsing an <property_expression> starting at {0}", stream.ComputeDetailedPosition(startingPos)); throw new Exceptions.ParseException(msg, e); } }
/// <summary> /// Creates an expression for an identifier /// </summary> /// <param name="item">The item to create the expression for</param> /// <returns>An expression that represents the item</returns> public static Expression AsExpression(this AST.Identifier item) { return(new AST.NameExpression(item.SourceToken, new AST.Name(item.SourceToken, new[] { item }, null))); }
/// <summary> /// Returns the current identifier as a name /// </summary> /// <param name="item">The identifier to map as a name</param> /// <returns>A name instance of the identifier</returns> public static AST.Name AsName(this AST.Identifier item) { return(new AST.Name(item.SourceToken, new [] { item }, null)); }
/// <summary> /// Finds the item with the given name /// </summary> /// <param name="name">The name to look for</param> /// <param name="scope">The scope to use</param> /// <returns>The item matching the name, or null</returns> public object FindSymbol(AST.Identifier name, ScopeState scope) { return(FindSymbol(new AST.Name(name.SourceToken, new [] { name ?? throw new ArgumentNullException(nameof(name)) }, null), scope));