void ScanBlock(RandomAccessIterator <SourceLine> lines) { var ix = lines.Index; var line = lines.Current; var closures = new Stack <Token>(); closures.Push(line.Instruction); while (lines.MoveNext() && closures.Count > 0) { if (lines.Current.Instruction != null) { if (lines.Current.Instruction.Name.Equals(_openClosures[closures.Peek().Name], Services.StringViewComparer)) { closures.Pop(); } else if (_openClosures.ContainsKey(lines.Current.Instruction.Name)) { closures.Push(lines.Current.Instruction); } } } if (closures.Count > 0) { throw new SyntaxException(closures.Peek(), $"Missing closure \"{_openClosures[closures.Peek().Name]}\" for directive \"{closures.Peek().Name}\"."); } lines.SetIndex(ix); }
/// <summary> /// Determines whether the tokenized expression is a string. /// </summary> /// <param name="iterator">The iterator to the tokenized expression.</param> /// <param name="services">The shared assembly services.</param> /// <returns></returns> public static bool ExpressionIsAString(RandomAccessIterator <Token> iterator, AssemblyServices services) { var token = iterator.Current; if (token.IsDoubleQuote()) { return(token.Name.Length > 2 && Token.IsEnd(iterator.PeekNext())); } var ix = iterator.Index; var result = false; if (token.Type == TokenType.Function && (token.Name.Equals("format", services.StringComparison) || token.Name.Equals("char", services.StringComparison))) { iterator.MoveNext(); var parms = Token.GetGroup(iterator); var last = iterator.Current; result = Token.IsEnd(last); if (token.Name.Equals("char", services.StringComparison)) { result &= services.Evaluator.Evaluate(parms.GetIterator(), 0, 0x10FFFF).IsInteger(); } } else if (token.Type == TokenType.Operand && (char.IsLetter(token.Name[0]) || token.Name[0] == '_') && !services.Evaluator.IsReserved(token.Name)) { var sym = services.SymbolManager.GetSymbol(token, false); if (sym != null) { if (iterator.MoveNext() && iterator.Current.Name.Equals("[")) { var subscript = (int)services.Evaluator.Evaluate(iterator); result = Token.IsEnd(iterator.Current) && subscript >= 0 && subscript < sym.StringVector.Count; } else { result = Token.IsEnd(iterator.Current) && sym.StorageType == StorageType.Scalar && sym.DataType == DataType.String; } } } iterator.SetIndex(ix); return(result); }