private IOperationCollection pushVariableAssignment(Scope scope) { // We need something of the form "type variableName" if (_iterator.Is(TokenType.Name)) { // At this point it is not entirely clear whether we are dealing // with a variable assignment. Therefore we have to remember everything // we read from now on so that we can restore it. _iterator.CreateRevertPoint(); // Read the variable type long theTypePosition = _iterator.Position; string theTypePath; string theTypeContextPath; IType theTypeInstance; try { theTypePath = string.Join("::", readNamespacePath(false).ToArray()); theTypeContextPath = Helper.PrependNamespace(theTypePath, _function.Signature.Namespace); // the current namespace might be implicit if (_function.TypeTable.Has(theTypePath)) { theTypeInstance = _function.TypeTable.Lookup(theTypePath); } else if (_function.TypeTable.Has(theTypeContextPath)) { theTypeInstance = _function.TypeTable.Lookup(theTypeContextPath); } else { throw new SyntaxException(theTypePosition, "Unrecognized type: " + theTypePath); } } catch (SyntaxException) { // Something failed, so we are not dealing with a variable assignment. // Proceed with the next layer. _iterator.Revert(); return(pushAssign(scope)); } // We read the name of the (base) type, now it might be // that case that it is followed by arbitrarily many "[]" // which indicate an array declaration // Read "[]" tokens which identify the type as array type int listDimension = 0; while (_iterator.Is(TokenType.SquareBracketLeft)) { listDimension++; _iterator.Next(); if (!_iterator.Is(TokenType.SquareBracketRight)) { listDimension = -1; break; } _iterator.Next(); } // If reading "[]" did not fail and the next token is a name, // we finally know that it *is* a variable assignment if (listDimension >= 0 && _iterator.Is(TokenType.Name)) { // Phew. Now remember to destroy the revert point. _iterator.Commit(); // Apply the array dimension to the type for (int i = 0; i < listDimension; i++) { theTypeInstance = new ArrayType(theTypeInstance); } string theVariableName = _iterator.GetValue <string>(); _iterator.Next(); switch (_iterator.Current.Type) { case TokenType.EndOfInstruction: var ops1 = new OperationCollection(); ops1.Append(new SimpleOperation(OperationType.LoadUndefined, theTypePosition)); ops1.Append(new TwoParametrizedOperation <IType, string>(OperationType.CreateVariable, theTypePosition, theTypeInstance, theVariableName)); return(ops1); case TokenType.OperatorAssign: _iterator.Next(); var ops2 = new OperationCollection(); ops2.Append(pushAssign(scope)); ops2.Append(new TwoParametrizedOperation <IType, string>(OperationType.CreateVariable, theTypePosition, theTypeInstance, theVariableName)); return(ops2); default: throw new SyntaxException(_iterator.Position, "Unexpected token: " + _iterator.Current.Type); } } else { // Otherwise restore everything from the revert point // and proceed with the next layer _iterator.Revert(); return(pushAssign(scope)); } } else { return(pushAssign(scope)); } }