void parseAttribute(TokenStream gStream) { AttributeReader reader = new AttributeReader(gStream); var attr = reader.Read(); switch (attr.Name) { case "AllowBuiltins": compilerConfig.AllowBuiltins = true; break; case "AddMeta": case "Info": case "Define": { if ((attr.Data.Count > 2 || attr.Data.Count < 1 || !(attr.Data[0].Value is string)) && !attr.Data[0].IsOptional) { InfoProvider.AddError("@AddMeta: Incorrect data", ExceptionType.AttributeException, gStream.SourcePosition); //throw new AttributeException("AddMeta", "Incorrect data"); } Metadata md = new Metadata(); if (attr.Data[0].IsOptional) { md.Key = attr.Data[0].Key; md.Value = attr.Data[0].Value; md.Type = attr.Data[0].Type; } else { md.Key = attr.Data[0].Value as string; if (attr.Data.Count == 2) { md.Value = attr.Data[1].Value; md.Type = attr.Data[1].Type; } else { md.Type = DataTypes.Void; } } var mlist = from m in metadataList where m.Key == md.Key select m; if (mlist.ToList().Count != 0) { InfoProvider.AddError("Meta key " + md.Key + " exists", ExceptionType.MetaKeyExists, gStream.SourcePosition); } //throw new CompilerException(ExceptionType.MetaKeyExists, "Meta key " + md.key + " in module " + CommandArgs.source + " exists", tokens); metadataList.Add(md); } break; case "Module": if (attr.Data.Count != 1 && !(attr.Data[0].Value is string)) { InfoProvider.AddError("@Module: Incorrect name", ExceptionType.AttributeException, gStream.SourcePosition); } //throw new AttributeException("Module", "Incorrect module name"); if (compilerConfig.OutBinaryFile == null) { compilerConfig.OutBinaryFile = (attr.Data[0].Value as string) + ".vas"; // TODO: FIXME } break; case "RuntimeInternal": if (attr.Data.Count != 0) { InfoProvider.AddError("@RuntimeInternal: Too many arguments", ExceptionType.AttributeException, gStream.SourcePosition); } //throw new AttributeException("RuntimeInternal", "Too many arguments"); if (!attr.Binded) { InfoProvider.AddError("@RuntimeInternal must be binded to method (check `;`)", ExceptionType.AttributeException, gStream.SourcePosition); } //throw new AttributeException("RuntimeInternal", "`@RuntimeInternal` must be binded to function (check `;`)"); bindedAttributeList.Add(attr); break; case "Entry": if (attr.Data.Count != 0) { InfoProvider.AddError("@Entry: Too many arguments", ExceptionType.AttributeException, gStream.SourcePosition); } //throw new AttributeException("Entry", "Too many arguments"); if (!attr.Binded) { InfoProvider.AddError("@Entry must be binded to method (check `;`)", ExceptionType.AttributeException, gStream.SourcePosition); } //throw new AttributeException("Entry", "`@Entry` must be binded to function (check `;`)"); bindedAttributeList.Add(attr); break; case "Debug:Set": { if (!compilerConfig.DebugBuild) { goto default; // YAAAY ;D } if ((attr.Data.Count > 2 || attr.Data.Count < 1 || !(attr.Data[0].Value is string)) && !attr.Data[0].IsOptional) { InfoProvider.AddError("@Debug:Set: Incorrect data", ExceptionType.AttributeException, gStream.SourcePosition); //throw new AttributeException("Debug:Set", "Incorrect data"); } RuntimeMetadata md = new RuntimeMetadata(); md.Prefix = attr.Name; if (attr.Data[0].IsOptional) { md.Key = attr.Data[0].Key; md.Value = attr.Data[0].Value; md.Type = attr.Data[0].Type; } else { md.Key = attr.Data[0].Value as string; if (attr.Data.Count == 2) { md.Value = attr.Data[1].Value; md.Type = attr.Data[1].Type; } else { md.Type = DataTypes.Void; } } var mlist = from m in metadataList where m.Key == md.Key select m; if (mlist.ToList().Count != 0) { foreach (var m in mlist) { metadataList.Remove(m); } } metadataList.Add(md); } break; default: InfoProvider.AddWarning("Unknown attribute `@" + attr.Name + "`", ExceptionType.AttributeException, gStream.SourcePosition); //Console.WriteLine("Warning: unknown attribute `" + attr.Name + "`"); break; } }
private AttributeObject read() { aobj.Binded = false; aobj.Data = new AttributeDataList(); aobj.Name = ts.Next(); if (!ts.Current.IsIdentifier()) { InfoProvider.AddError("Wrong name `" + aobj.Name + "`", ExceptionType.AttributeException, ts.SourcePosition); } //throw new AttributeException(aobj.Name, "Wrong name"); if (ts.IsNext(";")) // Like "RuntimeInternal;" { return(aobj); } else if (ts.Is(":")) // Like "Debug:Log" { do { aobj.Name += ":" + ts.Next(); if (!ts.Current.IsIdentifier()) { InfoProvider.AddError("Wrong name `" + aobj.Name + "`", ExceptionType.AttributeException, ts.SourcePosition); } } while(ts.IsNext(":")); //_ts.PushBack(); } if (!ts.Is("(")) { aobj.Binded = true; ts.PushBack(); return(aobj); } if (!ts.IsNext("(")) { if (ts.IsNext(";")) { return(aobj); } aobj.Binded = true; ts.PushBack(); return(aobj); } //_ts.Next(); while (true) { AttributeData ad = new AttributeData(); ad.IsOptional = false; var type = ts.Current.ConstType; var val = ts.ToString(); if (ts.Current.IsIdentifier()) //For smth like @Attr(<Key>=<Value>) { if (ts.IsNext("=")) { ad.IsOptional = true; ad.Key = val; val = ts.Next(); type = ts.Current.ConstType; } else //For @Attr(<Value>) { ts.PushBack(); } } switch (type) { case ConstantType.Bool: ad.Value = bool.Parse(val); ad.Type = DataTypes.Bool; break; case ConstantType.Double: ad.Value = ts.Current.GetDouble(); ad.Type = DataTypes.Double; break; case ConstantType.I32: ad.Value = ts.Current.GetI32(); ad.Type = DataTypes.I32; break; case ConstantType.String: var str = ts.Current.Unquoted; ad.Value = str.Remove(str.LastIndexOf('"')).Replace("\\\"", "\""); ad.Type = DataTypes.String; break; default: InfoProvider.AddError("Unsupported data type: " + type.ToString().Replace("DataTypes.", ""), ExceptionType.AttributeException, ts.SourcePosition); break; } aobj.Data.Add(ad); if (ts.IsNext(")")) { break; } else if (!ts.Is(",")) { InfoProvider.AddError("Unexpected character " + ts, ExceptionType.AttributeException, ts.SourcePosition); } ts.Next(); } if (ts.IsNext(";")) { return(aobj); } aobj.Binded = true; ts.PushBack(); return(aobj); }