private static void Field(Compiler c, bool allowAssignment) { // Initialize it with a fake value so we can keep parsing and minimize the // number of cascaded errors. int field = 255; ClassCompiler enclosingClass = c.GetEnclosingClass(); if (enclosingClass == null) { c.Error("Cannot reference a field outside of a class definition."); } else if (enclosingClass.IsStaticMethod) { c.Error("Cannot use an instance field in a static method."); } else { // Look up the field, or implicitly define it. string fieldName = c._parser.Source.Substring(c._parser.Previous.Start, c._parser.Previous.Length); field = enclosingClass.Fields.IndexOf(fieldName); if (field < 0) { enclosingClass.Fields.Add(fieldName); field = enclosingClass.Fields.IndexOf(fieldName); } if (field >= MaxFields) { c.Error(string.Format("A class can only have {0} fields.", MaxFields)); } } // If there's an "=" after a field name, it's an assignment. bool isLoad = true; if (c.Match(TokenType.Eq)) { if (!allowAssignment) c.Error("Invalid assignment."); // Compile the right-hand side. c.Expression(); isLoad = false; } // If we're directly inside a method, use a more optimal instruction. if (c._parent != null && c._parent._enclosingClass == enclosingClass) { c.EmitByteArg(isLoad ? Instruction.LOAD_FIELD_THIS : Instruction.STORE_FIELD_THIS, field); } else { c.LoadThis(); c.EmitByteArg(isLoad ? Instruction.LOAD_FIELD : Instruction.STORE_FIELD, field); } }