Beispiel #1
0
        private static TestScriptValue Eval(TestScriptExpression expression, TestScriptEvalContext context)
        {
            switch (expression.Type)
            {
            case TestScriptExpressionType.String:
                return(new TestScriptValue(((TestScriptString)expression).Text, TestScriptValueType.String));

            case TestScriptExpressionType.Integer:
                return(new TestScriptValue(((TestScriptInteger)expression).Value, TestScriptValueType.Long));

            case TestScriptExpressionType.EnumValue:
            {
                TestScriptEnumValue enumExp = (TestScriptEnumValue)expression;

                ProtoSpecModule module = context.ProtoSpec.Modules.GetByName(enumExp.Module, true);

                if (module == null)
                {
                    Error("上下文中并不包含模块“" + module + "”的定义");
                }

                long value = module.EnumValues.GetValueByName(enumExp.Name, true);

                if (value < 0)
                {
                    Error("模块“" + module + "”中并不包含枚举值“" + enumExp.Name + "”的定义");
                }

                return(TestScriptValue.CreateEnum(enumExp.Module, enumExp.Name, value));
            }

            case TestScriptExpressionType.FunctionCall:
            {
                TestScriptFunctionCall funExp = (TestScriptFunctionCall)expression;

                ProtoSpecModule module = context.ProtoSpec.Modules.GetByName(funExp.Module, true);

                if (module == null)
                {
                    Error("上下文中不存在模块“" + module + "”");
                }

                ProtoSpecAction action = module.Actions.GetByName(funExp.Function, true);

                if (action == null)
                {
                    Error("模块“" + module + "”中不存在操作“" + funExp.Function + "”");
                }

                return(SendData(context, action, funExp.ParamList));
            }
            }

            return(null);
        }
Beispiel #2
0
        public ProtoSpecClassDef GetClassDef(string classModule, string className, bool ignoreCase)
        {
            ProtoSpecModule module = Modules.GetByName(classModule, ignoreCase);

            if (module == null)
            {
                return(null);
            }

            ProtoSpecClassDef classDef = module.Classes.GetByName(className, ignoreCase);

            return(classDef);
        }
Beispiel #3
0
        private void ParseModuleBody(ProtoSpecModule module)
        {
            while (true)
            {
                NextToken();

                if (CurrentToken.Type == ProtoSpecTokenType.Class)
                {
                    ProtoSpecClassDef classDef = ParseClass(module);

                    if (classDef == null)
                    {
                        break;
                    }

                    module.Classes.Add(classDef);
                }
                else if (CurrentToken.Type == ProtoSpecTokenType.Identifier)
                {
                    ProtoSpecAction action = ParseAction(module);

                    if (action == null)
                    {
                        break;
                    }

                    module.Actions.Add(action);
                }
                else if (CurrentToken.Type == ProtoSpecTokenType.EndOfFile ||
                         CurrentToken.Type == ProtoSpecTokenType.RightBrace)
                {
                    break;
                }
                else
                {
                    Error("未知的标识符");
                    break;
                }
            }
        }
Beispiel #4
0
        private static ProtoSpecClassDef GetClassDef(ProtoSpecAction parentAction, string classModule, string className)
        {
            ProtoSpecModule module = parentAction.ParentModule;

            if (classModule != null)
            {
                module = parentAction.ParentModule.ParentDocument.Modules.GetByName(classModule, true);

                if (module == null)
                {
                    throw new Exception("模块'" + parentAction.ParentModule.Name + "'的操作'" + parentAction.Name + "'中引用了不存在的模块'" + classModule + "'");
                }
            }

            ProtoSpecClassDef classDef = null;

            if (classModule == null)
            {
                classDef = parentAction.ParentModule.ParentDocument.GetClassDef(parentAction.ParentModule.Name, className, true);
            }
            else
            {
                classDef = parentAction.ParentModule.ParentDocument.GetClassDef(classModule, className, true);
            }

            if (classDef == null)
            {
                if (classModule != null)
                {
                    throw new Exception("模块'" + parentAction.ParentModule.Name + "'的操作'" + parentAction.Name + "'中引用了不存在的类'" + classModule + "." + className + "'");
                }
                else
                {
                    throw new Exception("模块'" + parentAction.ParentModule.Name + "'的操作'" + parentAction.Name + "'中引用了不存在的类'" + className + "'");
                }
            }

            return(classDef);
        }
Beispiel #5
0
        public static TestScriptValue Do(TestScriptDocument script, TestScriptEvalContext context)
        {
            Eval(script.Statements, context);

            Socket socket = context.Sock;

            TestScriptValue list = TestScriptValue.CreateList();

            System.Threading.Thread.Sleep(1000);

            while (socket.Available > 0)
            {
                byte[] head = new byte[4];

                int received = 0;

                while (received != 4)
                {
                    received += socket.Receive(head);
                }

                Array.Reverse(head);

                int length = BitConverter.ToInt32(head, 0);

                received = 0;

                byte[] data = new byte[length];

                while (received != length)
                {
                    received += socket.Receive(data, received, length - received, SocketFlags.None);
                }

                ProtoSpecModule recvModule = context.ProtoSpec.Modules.GetById(data[0].ToString());

                if (recvModule == null)
                {
                    Error("数据接收失败,无法找到ID为“" + data[0] + "”的模块");
                }

                ProtoSpecAction recvAction = recvModule.Actions.GetById(data[1].ToString());

                if (recvAction == null)
                {
                    Error("数据接收失败,在模块“" + recvModule.Name + "”中无法找到ID位“" + data[1] + "”的操作");
                }

                if (recvAction.Output.Columns.Count > 0)
                {
                    int parseOffset = 2;

                    TestScriptValue recvValue = TestScriptValue.CreateObject();

                    ParseResponse(recvModule.Name, data, ref parseOffset, recvAction.Output, recvValue);

                    TestScriptValue actionResult = TestScriptValue.CreateActionResult(recvModule.Name, recvAction.Name, recvValue);

                    list.AddItem(actionResult);
                }
            }

            return(list);
        }
Beispiel #6
0
        private static TestScriptValue Eval(TestScriptExpression expression, TestScriptEvalContext context)
        {
            switch (expression.Type)
            {
            case TestScriptExpressionType.String:
                return(new TestScriptValue(((TestScriptString)expression).Text, TestScriptValueType.String));

            case TestScriptExpressionType.Integer:
                return(new TestScriptValue(((TestScriptInteger)expression).Value, TestScriptValueType.Long));

            case TestScriptExpressionType.EnumValue:
            {
                TestScriptEnumValue enumExp = (TestScriptEnumValue)expression;

                ProtoSpecModule module = context.ProtoSpec.Modules.GetByName(enumExp.Module, true);

                if (module == null)
                {
                    Error("上下文中并不包含模块“" + module + "”的定义");
                }

                long value = module.EnumValues.GetValueByName(enumExp.Name, true);

                if (value < 0)
                {
                    Error("模块“" + module + "”中并不包含枚举值“" + enumExp.Name + "”的定义");
                }

                return(TestScriptValue.CreateEnum(enumExp.Module, enumExp.Name, value));
            }

            case TestScriptExpressionType.FunctionCall:
            {
                TestScriptFunctionCall funExp = (TestScriptFunctionCall)expression;

                if (funExp.Module == "proto")
                {
                    switch (funExp.Function)
                    {
                    case "clean":
                        if (funExp.ParamList.Count == 0)
                        {
                            Clean(context, 1000);
                        }
                        else if (funExp.ParamList.Count == 1 && funExp.ParamList[0].Type == TestScriptExpressionType.Integer)
                        {
                            Clean(context, (int)((TestScriptInteger)funExp.ParamList[0]).Value);
                        }
                        else
                        {
                            Error("函数“proto:clean()”的参数个数应该为0个或1个");
                        }
                        break;
                    }

                    return(null);
                }
                else
                {
                    ProtoSpecModule module = context.ProtoSpec.Modules.GetByName(funExp.Module, true);

                    if (module == null)
                    {
                        Error("上下文中不存在模块“" + module + "”");
                    }

                    ProtoSpecAction action = module.Actions.GetByName(funExp.Function, true);

                    if (action == null)
                    {
                        Error("模块“" + module + "”中不存在操作“" + funExp.Function + "”");
                    }

                    return(SendData(context, action, funExp.ParamList));
                }
            }
            }

            return(null);
        }
Beispiel #7
0
 public ProtoSpecClassDefList(ProtoSpecModule parentModule)
 {
     ParentModule = parentModule;
 }
Beispiel #8
0
 public ProtoSpecActionList(ProtoSpecModule parentModule)
 {
     ParentModule = parentModule;
 }
Beispiel #9
0
        private ProtoSpecAction ParseAction(ProtoSpecModule module)
        {
            string name = CurrentToken.Text;

            NextToken();

            if (CurrentToken.Type != ProtoSpecTokenType.Equal)
            {
                Error("接口名'" + name + "'后缺少'='");
                return(null);
            }

            NextToken();

            if (CurrentToken.Type != ProtoSpecTokenType.Numeral)
            {
                Error("接口'" + name + "'的ID不是有效数值");
                return(null);
            }

            string actionId = CurrentToken.Text;

            NextToken();

            if (CurrentToken.Type != ProtoSpecTokenType.LeftBrace)
            {
                Error("操作'" + name + "'的主体起始位置,缺少'{'");
                return(null);
            }

            NextToken();

            if (CurrentToken.Type != ProtoSpecTokenType.In)
            {
                Error("接口'" + name + "'的主体,缺少'in'关键字");
                return(null);
            }

            ProtoSpecAction action = new ProtoSpecAction(name, actionId);

            NextToken();

            ProtoSpecSubset input = ParseSpecSubset(action);

            NextToken();

            if (CurrentToken.Type != ProtoSpecTokenType.Out)
            {
                Error("接口'" + name + "'的主体,缺少'out'关键字");
                return(null);
            }

            NextToken();

            ProtoSpecSubset output = ParseSpecSubset(action);

            NextToken();

            if (CurrentToken.Type != ProtoSpecTokenType.RightBrace)
            {
                Error("接口'" + name + "'的主体结束位置,缺少'}'");
                return(null);
            }

            action.Input  = input;
            action.Output = output;

            return(action);
        }
Beispiel #10
0
        private ProtoSpecClassDef ParseClass(ProtoSpecModule module)
        {
            NextToken();

            if (CurrentToken.Type != ProtoSpecTokenType.Identifier)
            {
                Error("缺少类名");
                return(null);
            }

            string name = CurrentToken.Text;

            string basePart1 = null;
            string basePart2 = null;

            NextToken();

            if (CurrentToken.Type == ProtoSpecTokenType.Colon)
            {
                NextToken();

                if (CurrentToken.Type != ProtoSpecTokenType.Identifier)
                {
                    Error("缺少基类名称");
                    return(null);
                }

                basePart1 = CurrentToken.Text;

                NextToken();

                if (CurrentToken.Type == ProtoSpecTokenType.Dot)
                {
                    NextToken();

                    if (CurrentToken.Type != ProtoSpecTokenType.Identifier)
                    {
                        Error("缺少基类名称");
                        return(null);
                    }

                    basePart2 = CurrentToken.Text;

                    NextToken();
                }
            }

            ProtoSpecSubset classBody = ParseSpecSubset(null);

            if (basePart1 == null)
            {
                return(new ProtoSpecClassDef(name, null, null, classBody));
            }
            else if (basePart2 == null)
            {
                return(new ProtoSpecClassDef(name, null, basePart1, classBody));
            }
            else
            {
                return(new ProtoSpecClassDef(name, basePart1, basePart2, classBody));
            }
        }
Beispiel #11
0
        private void ParseModules(ProtoSpecDocument document)
        {
            while (true)
            {
                ResetEnumContext();

                NextToken();

                if (CurrentToken.Type != ProtoSpecTokenType.Identifier)
                {
                    if (CurrentToken.Type != ProtoSpecTokenType.EndOfFile)
                    {
                        Error("缺少模块名");
                    }

                    break;
                }

                string name = CurrentToken.Text;

                CurrentModule = name;

                NextToken();

                if (CurrentToken.Type != ProtoSpecTokenType.Equal)
                {
                    Error("模块名后缺少'='");
                    break;
                }

                NextToken();

                if (CurrentToken.Type != ProtoSpecTokenType.Numeral)
                {
                    Error("模块ID不是有效数值");
                    break;
                }

                string moduleId = CurrentToken.Text;

                ProtoSpecModule module = new ProtoSpecModule(name, moduleId);

                NextToken();

                if (CurrentToken.Type != ProtoSpecTokenType.LeftBrace)
                {
                    Error("模块主体起始位置,缺少'{'");
                    break;
                }

                ParseModuleBody(module);

                if (CurrentToken.Type != ProtoSpecTokenType.RightBrace)
                {
                    Error("模块主体结束位置,缺少'}'");
                    break;
                }

                ExportEnumValues(module.EnumValues);

                document.Modules.Add(module);
            }
        }