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); }
public ProtoSpecSubset GetFullSpec(ProtoSpecAction action) { ProtoSpecSubset resultSpec = new ProtoSpecSubset(action); if (ClassBaseName != null) { ProtoSpecClassDef classBaseDef = null; if (ClassBaseModule != null) { classBaseDef = ParentModule.ParentDocument.GetClassDef(ClassBaseModule, ClassBaseName, true); } else { classBaseDef = ParentModule.ParentDocument.GetClassDef(ParentModule.Name, ClassBaseName, true); } if (classBaseDef == null) { if (ClassBaseModule != null) { throw new Exception("无法找到类型'" + ParentModule.Name + "." + ClassName + "'的基类'" + ClassBaseModule + "." + ClassBaseName + "'"); } else { throw new Exception("无法找到类型'" + ParentModule.Name + "." + ClassName + "'的基类'" + ClassBaseName + "'"); } } ProtoSpecSubset classBaseSpec = classBaseDef.GetFullSpec(action); foreach (ProtoSpecColumn column in classBaseSpec.Columns) { resultSpec.Columns.Add(column.Colon(action)); } } foreach (ProtoSpecColumn column in ClassBody.Columns) { resultSpec.Columns.Add(column.Colon(action)); } return(resultSpec); }
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; } } }
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); }
public ProtoSpecColumn Colon(ProtoSpecAction parentAction) { ProtoSpecColumn result = new ProtoSpecColumn(Name, this.ColumnType); result.Values = this.Values; result.ClassModule = this.ClassModule; result.ClassName = this.ClassName; result.ParentAction = parentAction; ProtoSpecSubset format = null; if (ClassName != null) { ProtoSpecClassDef classDef = GetClassDef(parentAction, ClassModule, ClassName); format = classDef.GetFullSpec(parentAction); } else { format = this.Format; } if (format != null) { ProtoSpecSubset newformat = new ProtoSpecSubset(parentAction); foreach (ProtoSpecColumn column in format.Columns) { newformat.Columns.Add(column.Colon(parentAction)); } result.Format = newformat; } return(result); }
private static TestScriptValue SendData(TestScriptEvalContext context, ProtoSpecAction action, TestScriptExpressionList paramList) { Socket socket = context.Sock; MemoryStream stream = new MemoryStream(); stream.WriteByte(0); stream.WriteByte(0); stream.WriteByte(0); stream.WriteByte(0); byte moduleId = byte.Parse(action.ParentModule.ModuleId); byte actionId = byte.Parse(action.ActionId); stream.WriteByte(moduleId); stream.WriteByte(actionId); int i = 0; #region Generate Data foreach (ProtoSpecColumn column in action.Input.Columns) { TestScriptValue param = Eval(paramList[i], context); i++; switch (column.ColumnType) { case ProtoSpecColumnType.Enum: stream.WriteByte((byte)(long)param.Value); break; case ProtoSpecColumnType.Byte: stream.WriteByte((byte)(long)param.Value); break; case ProtoSpecColumnType.Short: { short value = (short)(long)param.Value; byte[] bytes = BitConverter.GetBytes(value); stream.WriteByte(bytes[1]); stream.WriteByte(bytes[0]); } break; case ProtoSpecColumnType.Int: { int value = (int)(long)param.Value; byte[] bytes = BitConverter.GetBytes(value); stream.WriteByte(bytes[3]); stream.WriteByte(bytes[2]); stream.WriteByte(bytes[1]); stream.WriteByte(bytes[0]); } break; case ProtoSpecColumnType.Long: { long value = (long)param.Value; byte[] bytes = BitConverter.GetBytes(value); stream.WriteByte(bytes[7]); stream.WriteByte(bytes[6]); stream.WriteByte(bytes[5]); stream.WriteByte(bytes[4]); stream.WriteByte(bytes[3]); stream.WriteByte(bytes[2]); stream.WriteByte(bytes[1]); stream.WriteByte(bytes[0]); } break; case ProtoSpecColumnType.String: { byte[] bytes = Encoding.UTF8.GetBytes((string)param.Value); short length = (short)bytes.Length; byte[] head = BitConverter.GetBytes(length); stream.WriteByte(head[1]); stream.WriteByte(head[0]); stream.Write(bytes, 0, bytes.Length); } break; } } #endregion byte[] buffer = stream.ToArray(); byte[] packHead = BitConverter.GetBytes(buffer.Length - 4); buffer[0] = packHead[3]; buffer[1] = packHead[2]; buffer[2] = packHead[1]; buffer[3] = packHead[0]; socket.Send(buffer); stream.Close(); stream.Dispose(); return(null); }
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); }
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); }
public ProtoSpecColumnList(ProtoSpecAction parentAction) { ParentAction = parentAction; }
public ProtoSpecSubset(ProtoSpecAction parentAction) { Columns = new ProtoSpecColumnList(parentAction); ParentAction = parentAction; }
private ProtoSpecSubset ParseSpecSubset(ProtoSpecAction action) { if (CurrentToken.Type != ProtoSpecTokenType.LeftBrace) { Error("规格定义起始位置,缺少'{'"); } ProtoSpecSubset subset = new ProtoSpecSubset(action); while (true) { NextToken(); if (CurrentToken.Type != ProtoSpecTokenType.Identifier) { if (CurrentToken.Type != ProtoSpecTokenType.EndOfFile && CurrentToken.Type != ProtoSpecTokenType.RightBrace) { Error("缺少列名"); } break; } string name = CurrentToken.Text; NextToken(); if (CurrentToken.Type != ProtoSpecTokenType.Colon) { Error("列名之后缺少':'"); break; } NextToken(); if (IsColumnType(CurrentToken.Type) == false) { Error("缺少类型定义"); break; } ProtoSpecColumnType type = (ProtoSpecColumnType)CurrentToken.Type; ProtoSpecColumn column = null; if (CurrentToken.Type == ProtoSpecTokenType.List) { NextToken(); if (CurrentToken.Type == ProtoSpecTokenType.LeftAngular) { NextToken(); if (CurrentToken.Type != ProtoSpecTokenType.Identifier) { Error("列表类型缺少类型名"); break; } string part1 = CurrentToken.Text; string part2 = null; NextToken(); if (CurrentToken.Type == ProtoSpecTokenType.Dot) { NextToken(); if (CurrentToken.Type != ProtoSpecTokenType.Identifier) { Error("列表类型的模块名后缺少类型名"); break; } part2 = CurrentToken.Text; NextToken(); } if (CurrentToken.Type != ProtoSpecTokenType.RightAngular) { Error("列表类型后缺少闭合符号'>'"); break; } if (part2 == null) { column = new ProtoSpecColumn(name, type, part1); } else { column = new ProtoSpecColumn(name, type, part1, part2); } } else { ProtoSpecSubset format = ParseSpecSubset(action); column = new ProtoSpecColumn(name, type, format); } } else if (CurrentToken.Type == ProtoSpecTokenType.TypeOf) { NextToken(); if (CurrentToken.Type != ProtoSpecTokenType.LeftAngular) { Error("自定义类型前缺少起始符号'<'"); break; } NextToken(); if (CurrentToken.Type != ProtoSpecTokenType.Identifier) { Error("自定义类型的模块名后缺少类型名"); break; } string part1 = CurrentToken.Text; string part2 = null; NextToken(); if (CurrentToken.Type == ProtoSpecTokenType.Dot) { NextToken(); if (CurrentToken.Type != ProtoSpecTokenType.Identifier) { Error("自定义类型的模块名后缺少类型名"); break; } part2 = CurrentToken.Text; NextToken(); } if (CurrentToken.Type != ProtoSpecTokenType.RightAngular) { Error("自定义类型后缺少闭合符号'>'"); break; } if (part2 == null) { column = new ProtoSpecColumn(name, type, part1); } else { column = new ProtoSpecColumn(name, type, part1, part2); } } else if (CurrentToken.Type == ProtoSpecTokenType.Enum) { ProtoSpecEnumValueList values = ParseEnum(); column = new ProtoSpecColumn(name, type, values); } else { column = new ProtoSpecColumn(name, type); } subset.Columns.Add(column); } if (CurrentToken.Type != ProtoSpecTokenType.RightBrace) { Error("规格定义结束位置,缺少'}'"); } return(subset); }
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); }