예제 #1
0
        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;
            }
        }
예제 #2
0
        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);
        }