public DotStepStruct(Token token, StructDefinition structDef, DotStep original, Executable owner) : base(token, owner) { this.DotToken = original.DotToken; this.RawRoot = original.Root; this.RootVar = "v_" + ((Variable)original.Root).Name.Split('$')[1]; this.FieldName = original.StepToken.Value; this.StructDefinition = structDef; }
public void AddStructDefinition(StructDefinition structDefinition) { if (this.structDefinitions.ContainsKey(structDefinition.Name.Value)) { throw new ParserException(structDefinition.FirstToken, "A struct with this name has already been defined."); } this.VerifyNameFree(structDefinition.Name); this.structDefinitions.Add(structDefinition.Name.Value, structDefinition); }
internal override Expression Resolve(Parser parser) { this.Root = this.Root.Resolve(parser); string step = this.StepToken.Value; if (this.Root is EnumReference) { EnumDefinition enumDef = ((EnumReference)this.Root).EnumDefinition; int resolutionState = parser.ConstantAndEnumResolutionState[enumDef]; if (resolutionState != 2) { enumDef.Resolve(parser); } switch (step) { case "length": return(new IntegerConstant(this.FirstToken, enumDef.IntValue.Count, this.FunctionOrClassOwner)); case "max": return(new SpecialEntity.EnumMaxFunction(this.FirstToken, enumDef, this.FunctionOrClassOwner)); case "values": return(new SpecialEntity.EnumValuesFunction(this.FirstToken, enumDef, this.FunctionOrClassOwner)); } if (enumDef.IntValue.ContainsKey(step)) { return(new IntegerConstant(this.FirstToken, enumDef.IntValue[step], this.FunctionOrClassOwner)); } else { throw new ParserException(this.StepToken, "The enum '" + enumDef.Name + "' does not contain a definition for '" + step + "'"); } } Variable variable = this.Root as Variable; if (variable != null) { string varName = variable.Name; if (parser.IsTranslateMode && varName.Contains('$')) { string[] parts = varName.Split('$'); if (parts.Length == 2 && parts[0].Length > 0 && parts[1].Length > 0) { // struct casting string structName = parts[0]; StructDefinition structDef = parser.GetStructDefinition(structName); if (structDef == null) { throw new ParserException(this.Root.FirstToken, "The struct '" + structName + "' does not exist."); } if (!structDef.IndexByField.ContainsKey(step)) { throw new ParserException(this.StepToken, "The struct '" + structDef.Name.Value + "' does not contain a field called '" + step + "'"); } return(new DotStepStruct(this.FirstToken, structDef, this, this.FunctionOrClassOwner)); } } } if (this.Root is BaseKeyword) { return(new BaseMethodReference(this.Root.FirstToken, this.DotToken, this.StepToken, this.FunctionOrClassOwner).Resolve(parser)); } if (this.Root is StringConstant) { if (step == "join") { throw new ParserException(this.StepToken, "There is no join method on strings. Did you mean to do list.join(string) instead?"); } else if (step == "size") { throw new ParserException(this.StepToken, "String size is indicated by string.length."); } else if (step == "length") { int length = ((StringConstant)this.Root).Value.Length; return(new IntegerConstant(this.FirstToken, length, this.FunctionOrClassOwner)); } } return(this); }
internal override Expression Resolve(Parser parser) { string className = this.NameToken.Value; if (parser.IsTranslateMode) { StructDefinition structDefinition = parser.GetStructDefinition(className); if (structDefinition != null) { if (this.Args.Length != structDefinition.Fields.Length) { throw new ParserException(this.FirstToken, "Args length did not match struct field count for '" + structDefinition.Name.Value + "'."); } StructInstance si = new StructInstance(this.FirstToken, this.NameToken, this.Args, this.FunctionOrClassOwner); si = (StructInstance)si.Resolve(parser); return(si); } } for (int i = 0; i < this.Args.Length; ++i) { this.Args[i] = this.Args[i].Resolve(parser); } if (this.Class == null) { throw new ParserException(this.FirstToken, "No class named '" + this.Name + "'"); } if (this.Class.StaticToken != null) { throw new ParserException(this.FirstToken, "Cannot instantiate a static class."); } ConstructorDefinition cons = this.Class.Constructor; if (cons.PrivateAnnotation != null) { if (this.Class != this.FunctionOrClassOwner.FunctionOrClassOwner) { string errorMessage = "The constructor for " + this.Class.NameToken.Value + " is private and cannot be invoked from outside the class."; if (cons.PrivateAnnotation.Args.Length > 0) { StringConstant stringMessage = cons.PrivateAnnotation.Args[0] as StringConstant; if (stringMessage != null) { errorMessage += " " + stringMessage.Value.Trim(); } } throw new ParserException(this.FirstToken, errorMessage); } } if (this.Args.Length < cons.MinArgCount || this.Args.Length > cons.MaxArgCount) { string message = "This constructor has the wrong number of arguments. "; if (cons.MinArgCount == cons.MaxArgCount) { message += "Expected " + cons.MinArgCount + " but found " + this.Args.Length; } else if (this.Args.Length < cons.MinArgCount) { message += " At least " + cons.MinArgCount + " are required but found only " + this.Args.Length + "."; } else { message += " At most " + cons.MaxArgCount + " are allowed but found " + this.Args.Length + "."; } throw new ParserException(this.FirstToken, message); } return(this); }