ParameterList readParams(TokenStream gStream) { var plist = new ParameterList(); while (true) { var param = new Variable(); param.Name = gStream.GetIdentifier(); param.Type = gStream.NextType(false); plist.Add(param); if (gStream.Next() == ")") { break; } if (gStream.Current != ",") { InfoProvider.AddError("`,` or `)` expected in parameter declaration", ExceptionType.IllegalToken, gStream.SourcePosition); } } return(plist); }
public static void Check(this TokenStream toks, string str, ExceptionType extype) { if (!toks.Is(str)) { InfoProvider.AddError("`" + str + "` expected", extype, toks.SourcePosition); } }
void parseClass(TokenStream gStream, Scope classScope) { ClassType clazz = new ClassType(gStream.GetIdentifierNext()); clazz.Scope = classScope; gStream.CheckNext("{", ExceptionType.Brace); while (true) { var entry = readCommonClassEntry(gStream); gStream.Next(); if (gStream.Is("{") || gStream.Is("->")) { // Property if (entry.HasVoidType) { InfoProvider.AddError("Void type not allowed for properties", ExceptionType.IllegalType, gStream.SourcePosition); } if (entry.Modifiers.HasFlag(ClassEntryModifiers.Native)) { InfoProvider.AddError("Properties can't be native", ExceptionType.IllegalModifier, gStream.SourcePosition); } } else if (gStream.Is("(")) { // Method if (entry.Modifiers.HasFlag(ClassEntryModifiers.Const)) { InfoProvider.AddError("Methods can't be const", ExceptionType.IllegalModifier, gStream.SourcePosition); } if (entry.Modifiers.HasFlag(ClassEntryModifiers.Native) && !entry.Modifiers.HasFlag(ClassEntryModifiers.Static)) { InfoProvider.AddError("Native methods must be declared as `static`", ExceptionType.IllegalModifier, gStream.SourcePosition); } Method method = parseMethod(entry, gStream); clazz.SymbolTable.Add(method); } else { // Field if (entry.HasVoidType) { InfoProvider.AddError("Void type not allowed for fields", ExceptionType.IllegalType, gStream.SourcePosition); } if (entry.Modifiers.HasFlag(ClassEntryModifiers.Native)) { InfoProvider.AddError("Fields can't be native", ExceptionType.IllegalModifier, gStream.SourcePosition); } Field field = parseField(entry, gStream); clazz.SymbolTable.Add(field); } } }
public static string GetIdentifier(this TokenStream toks) { var id = toks.Current; if (id.Type != TokenType.Identifier) { InfoProvider.AddError("Identifier expected", ExceptionType.IllegalToken, toks.SourcePosition); } return(id.ToString()); }
public void Add(IClassElement element) { if (base.ContainsKey(element.Name)) { InfoProvider.AddError("Identifier is already in use", ExceptionType.IdentifierInUse, element.DeclarationPosition); InfoProvider.AddError("previously declared here", ExceptionType.AdditionalInfo, base[element.Name].DeclarationPosition); } base.Add(element.Name, element); }
public static IType NextType(this TokenStream toks, bool includeVoid) { string identifier = toks.GetIdentifierNext(); if (identifier == "void" && !includeVoid) { InfoProvider.AddError("Unexpected `void` type", ExceptionType.IllegalType, toks.SourcePosition); } int dimens = 0; while (!toks.Eof) { if (toks.IsNext("[")) { dimens++; } else { toks.PushBack(); break; } toks.CheckNext("]", ExceptionType.Brace); } if (identifier == "void" && dimens > 0) { InfoProvider.AddError("Unexpected `void` typed array", ExceptionType.IllegalType, toks.SourcePosition); } IType result; if (Compiler.IsPlainType(identifier)) { result = new PlainType(identifier); } else { result = new ClassType(identifier); } if (dimens != 0) { return(new ArrayType(result, dimens)); } return(result); }
Field parseField(CommonClassEntry entry, TokenStream gStream) { Field field = new Field(); if (gStream.Is(";") && entry.Modifiers.HasFlag(ClassEntryModifiers.Const)) { InfoProvider.AddError("Const field must be initialized immediately", ExceptionType.UninitedConstant, gStream.SourcePosition); } field.FromClassEntry(entry); if (gStream.Is("=")) { gStream.Next(); field.InitialExpressionPosition = gStream.TokenPosition; gStream.SkipTo(";", true); } return(field); }
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); }