public ListNode(IField field) { Field = field; if (field is IClassField cf) { ChildCtor = i => new ScalarClassNode(cf, i); ChildReloader = (i, n) => ((ScalarClassNode)n).FullReload(cf, i); } else if (field is IEnumField ef) { ChildCtor = i => new ScalarEnumNode(ef, i); ChildReloader = (i, n) => ((ScalarEnumNode)n).FullReload(ef, i); } else if (field is IPrimitiveField pf) { ChildCtor = i => new ScalarPrimitiveNode(pf, i); ChildReloader = (i, n) => ((ScalarPrimitiveNode)n).FullReload(pf, i); } else { throw new ArgumentException("Unknown field type"); } Name = field.Name; Actions = new IActionNode[] { new ReloadNode("Reload List", this), new ListAppendNode(field) }; SubGroups = Enumerable.Range(0, Field.Count).Select(ChildCtor).ToArray(); Field.CollectionChanged += ModelCollectionChanged; }
public ParallelNode(IActionNode blockRoot) { m_BlockRoot = blockRoot; int i = 0; IActionNode currentBlock = m_BlockRoot; while (currentBlock != null) { i++; currentBlock = currentBlock.Next; } m_ExecutionList = new List<IActionNode>(i); }
public void rm_act(IActionNode act) { if (act.id < 0 || act.id > max_act_count) { return; } if (actions[act.id] == null) { return; } actions[act.id] = null; }
public void add_act(IActionNode act) { if (act.id < 0 || act.id > max_act_count) { return; } if (actions[act.id] != null) { return; } actions[act.id] = act; conditions[act.id] = act.condition; effects[act.id] = act.effect; }
/// <summary> /// 获取容器节点中的最后一个 /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="T1"></typeparam> /// <param name="self"></param> /// <param name="action"></param> /// <returns></returns> public static T LastNode <T, T1>(this T self, Action <T1> action) where T : IContainerNode where T1 : IActionNode { IActionNode last = self.last; if (last == null) { Log.E("There is nothing in this node"); } else { if (action != null) { action((T1)last); } } return(self); }
private int ParseParallelBlock(CompilationContext compilationContext, int index, List<Token> tokens, ref IActionNode currentParent) { Token currentToken; var blockStream = new List<Token>(); int skipTokens = GetInnerBlock(index, tokens, ref blockStream); // Compile consequence IActionNode consequnce = Compile(blockStream, compilationContext); index += skipTokens; currentToken = tokens[index]; var conditionalCommand = new ParallelNode(consequnce); currentParent.Next = conditionalCommand; currentParent = currentParent.Next; return index; }
private int ParseFlagAccess(CompilationContext compilationContext, Token currentToken, List<Token> tokens, int index, ref IActionNode currentParent) { int varIndex = currentToken.GetAccessIndex(m_Engine.HostBridge.EnumDefineTable); // Map enums to their index counterparts if (currentToken.Type == TokenType.LocalFlagAccessEnum) currentToken.Type = TokenType.LocalFlagAccess; if (currentToken.Type == TokenType.GlobalFlagAccessEnum) currentToken.Type = TokenType.GlobalFlagAccess; // Global or local? var op = TokenType.GlobalFlagAccess; if (currentToken.Type == TokenType.LocalFlagAccess) op = TokenType.LocalFlagAccess; currentToken = tokens[++index]; // Assignment AssertExpectedTokenType(currentToken, TokenType.Assignment, "Expected Assignment"); currentToken = tokens[++index]; Expression expression; int skip = ParseExpression(index, tokens, compilationContext, out expression); index += skip; currentToken = tokens[index]; // Create the assignment command currentParent.Next = new ModifyFlag(varIndex, op, expression); currentParent = currentParent.Next; return index; }
private int ParseEvent(CompilationContext compilationContext, List<Token> tokens, int index, ref IActionNode currentParent) { Token currentToken = tokens[++index]; if (currentToken.Type == TokenType.ReferenceAction) { throw new GossipScriptException("Only Properties may be called on an event parameter"); } if (currentToken.Type == TokenType.ReferencePropertySet) { Token operand = currentToken; Expression expression; currentToken = tokens[++index]; AssertExpectedTokenType(currentToken, TokenType.Assignment, "Unexpected token"); currentToken = tokens[++index]; int skip = ParseExpression(index, tokens, compilationContext, out expression); index += skip; currentToken = tokens[index]; if (!m_Engine.HostBridge.TypeBindingTable.SetPropertyExists(operand.Value, compilationContext.EventType)) throw new GossipScriptException(String.Format("Property {0} not found or is read only.", operand.Value)); PropertySetBinding setter = m_Engine.HostBridge.TypeBindingTable.GetPropertySetByName(operand.Value, compilationContext .EventType); if (setter.ParameterType != expression.ReturnType) throw new GossipScriptException("Incompatile property set parameter"); currentParent.Next = new AssignReferenceProperty(-2, setter.Id, expression); currentParent = currentParent.Next; return index; } throw new Exception("Unexpected token"); }
private int ParseEvaluateExpression(CompilationContext compilationContext, List<Token> tokens, int index, ref IActionNode currentParent) { Token currentToken = tokens[++index]; AssertExpectedTokenValue(currentToken, "(", "Expected Open Bracket"); currentToken = tokens[++index]; // Parameters // Parse logical expression Expression expression; int skipTokens = ParseExpression(index - 1, tokens, compilationContext, out expression); index += (skipTokens - 2); currentToken = tokens[index]; // Close Bracket AssertExpectedTokenValue(currentToken, ")", "Expected Close Bracket"); var conditionalCommand = new EvalAction(expression); currentParent.Next = conditionalCommand; currentParent = currentParent.Next; return index; }
private int ParseConditional(CompilationContext compilationContext, List<Token> tokens, int index, ref IActionNode currentParent) { Token currentToken; currentToken = tokens[++index]; // Open Bracket AssertExpectedTokenValue(currentToken, "(", "Expected Open Bracket"); currentToken = tokens[++index]; // Parameters // Parse logical expression Expression expression; int skipTokens = ParseExpression(index - 1, tokens, compilationContext, out expression); index += (skipTokens - 2); currentToken = tokens[index]; // Close Bracket AssertExpectedTokenValue(currentToken, ")", "Expected Close Bracket"); // Obtain consequence block var blockStream = new List<Token>(); skipTokens = GetInnerBlock(index, tokens, ref blockStream); // Compile consequence IActionNode consequnce = Compile(blockStream, compilationContext); // Jump ahead in the Token stream index += skipTokens; if (index >= tokens.Count) throw new GossipScriptException("Unexpected end of input"); currentToken = tokens[index]; // Obtain Else consequence IActionNode elseConsequnce = null; if (tokens[index + 1].Value == "else") { var elseBlockStream = new List<Token>(); skipTokens = GetInnerBlock(index + 1, tokens, ref elseBlockStream); elseConsequnce = Compile(elseBlockStream, compilationContext); // Jump ahead in the Token stream index += (skipTokens + 1); currentToken = tokens[index]; } var conditionalCommand = new ConditionalNode(expression, consequnce, elseConsequnce); currentParent.Next = conditionalCommand; currentParent = currentParent.Next; return index; }
private IActionNode ParseReturn(IActionNode currentParent, List<Token> tokens, ref int index) { Token currentToken; var conditionalCommand = new ReturnNode(); currentParent.Next = conditionalCommand; currentParent = currentParent.Next; currentToken = tokens[++index]; AssertExpectedTokenType(currentToken, TokenType.EndStatement, "Expected ;"); return currentParent; }
private int ParseVariableAccess(CompilationContext compilationContext, Token currentToken, List<Token> tokens, int index, ref IActionNode currentParent) { int varIndex = currentToken.GetAccessIndex(m_Engine.HostBridge.EnumDefineTable); // Map enums to their index counterparts if (currentToken.Type == TokenType.LocalVariableAccessEnum) currentToken.Type = TokenType.LocalVariableAccess; if (currentToken.Type == TokenType.GlobalVariableAccessEnum) currentToken.Type = TokenType.GlobalVariableAccess; // Global or local? var op = TokenType.GlobalVariableAccess; if (currentToken.Type == TokenType.LocalVariableAccess) op = TokenType.LocalVariableAccess; currentToken = tokens[++index]; // Assignment or increment or decrement if (currentToken.Value != "=" && currentToken.Value != "++" && currentToken.Value != "--" && currentToken.Value != "+=" && currentToken.Value != "-=") throw new GossipScriptException("Unexpected Token following variable access", currentToken); if (currentToken.Value == "++") { currentParent.Next = new ModifyVariable(varIndex, op, TokenType.Increment, 1); currentParent = currentParent.Next; return index; } if (currentToken.Value == "--") { currentParent.Next = new ModifyVariable(varIndex, op, TokenType.Decrement, 1); currentParent = currentParent.Next; return index; } if (currentToken.Type == TokenType.Assignment || currentToken.Type == TokenType.IncrementAndAssign || currentToken.Type == TokenType.DecrementAndAssign) { TokenType tokenType = currentToken.Type; currentToken = tokens[++index]; // First token after assignment Expression expression; int skip = ParseExpression(index, tokens, compilationContext, out expression); if (expression.ReturnType != GossipType.Number) throw new GossipScriptException(String.Format("Invalid return type:{0}, Expected Number", expression.ReturnType)); index += skip; currentToken = tokens[index]; // Specal case if (op == TokenType.LocalVariableAccess && currentToken.Type == TokenType.Assignment && expression.Instructions.Count == 1) { currentParent.Next = new AssignLocalVariableWithLiteral(varIndex, Convert.ToDouble( expression.Instructions[0].Data)); currentParent = currentParent.Next; return index; } // Generic Case currentParent.Next = new AssignVariable(varIndex, op, tokenType, expression); currentParent = currentParent.Next; return index; } return index; }
private int ParseStringAccess(CompilationContext compilationContext, Token currentToken, List<Token> tokens, int index, ref IActionNode currentParent) { int destIndex = currentToken.GetAccessIndex(m_Engine.HostBridge.EnumDefineTable); // Map enums to their index counterparts if (currentToken.Type == TokenType.LocalStringAccessEnum) currentToken.Type = TokenType.LocalStringAccess; if (currentToken.Type == TokenType.GlobalFlagAccessEnum) currentToken.Type = TokenType.GlobalFlagAccess; // Global or local? var destScope = VariableScope.Global; if (currentToken.Type == TokenType.LocalStringAccess) destScope = VariableScope.Local; currentToken = tokens[++index]; if (currentToken.Type != TokenType.Assignment) throw new GossipScriptException("Unexpected Token following string access", currentToken); Token op = currentToken; currentToken = tokens[++index]; if (currentToken.Type == TokenType.StringLiteral) { string stringValue = currentToken.Value.Substring(1, currentToken.Value.Length - 2); currentParent.Next = new AssignStringLiteral(destIndex, destScope, stringValue); currentParent = currentParent.Next; return index; } // If none of the above it must be an expression Expression expression; int skipTokens = ParseExpression(index, tokens, compilationContext, out expression); index += skipTokens; currentToken = tokens[index]; currentParent.Next = new AssignString(destIndex, destScope, expression); currentParent = currentParent.Next; return index; }
public void Config(IActionNode node) { this._node = node as ActionNode; SetDataDirty(); this.env.BindUpdate(MoveNext); }
private int ParsePropertySet(CompilationContext compilationContext, int index, List<Token> tokens, ref IActionNode currentParent, int enounterAssignmentIndex) { Expression lhsExpression; int lhsSkip = ParseExpression(index, tokens, compilationContext, out lhsExpression); Token propertyToken = tokens[enounterAssignmentIndex - 1]; if (propertyToken.Type != TokenType.ReferencePropertySet) throw new GossipScriptException("Expected property set"); // Get Set Method PropertySetBinding setMethod = m_Engine.HostBridge.TypeBindingTable.GetPropertySetByName( propertyToken.Value, lhsExpression.HostReturnType); // Skip Assignment Token currentToken = tokens[enounterAssignmentIndex]; if (currentToken.Type != TokenType.Assignment) throw new Exception("Exprected assignment"); index = enounterAssignmentIndex + 1; // Parse Right hand side Expression rhsExpression; int rhsSkip = ParseExpression(index, tokens, compilationContext, out rhsExpression); currentParent.Next = new AssignReferenceProperty(lhsExpression, setMethod.Id, rhsExpression); currentParent = currentParent.Next; return index + rhsSkip; }
private int ParseReferenceObjectAccess(CompilationContext compilationContext, Token currentToken, List<Token> tokens, int index, ref IActionNode currentParent) { int varIndex = currentToken.GetAccessIndex(m_Engine.HostBridge.EnumDefineTable); // Map enums to their index counterparts if (currentToken.Type == TokenType.ReferenceObjectAccessEnum) currentToken.Type = TokenType.ReferenceObjectAccess; currentToken = tokens[++index]; // Assignment or Property set or Action only Token operand = currentToken; Expression expression; if (currentToken.Type == TokenType.ReferencePropertySet) { currentToken = tokens[++index]; AssertExpectedTokenType(currentToken, TokenType.Assignment, "Unexpected token"); currentToken = tokens[++index]; int skip = ParseExpression(index, tokens, compilationContext, out expression); index += skip; currentToken = tokens[index]; ReferenceAssignment assignment = compilationContext.ReferenceAssignmentTable.GetAssignment(varIndex); if (!m_Engine.HostBridge.TypeBindingTable.SetPropertyExists(operand.Value, assignment.Type)) throw new GossipScriptException(String.Format("Property {0} not found or is read only.", operand.Value)); PropertySetBinding setter = m_Engine.HostBridge.TypeBindingTable.GetPropertySetByName(operand.Value, assignment.Type); if (setter.ParameterType != expression.ReturnType) throw new GossipScriptException("Incompatile property set parameter"); currentParent.Next = new AssignReferenceProperty(varIndex, setter.Id, expression); currentParent = currentParent.Next; return index; } if (currentToken.Type == TokenType.Assignment) { currentToken = tokens[++index]; int skip = ParseExpression(index, tokens, compilationContext, out expression); index += skip; currentToken = tokens[index]; compilationContext.ReferenceAssignmentTable.TrackReference(varIndex, expression.HostReturnType); if (expression.ReturnType != GossipType.ReferenceObject) throw new GossipScriptException("Expected return type reference object"); // Create the assignment command currentParent.Next = new AssignReference(varIndex, expression); currentParent = currentParent.Next; return index; } // Parse Action { int skip = ParseExpression(index - 1, tokens, compilationContext, out expression); index += (skip); currentToken = tokens[index - 1]; if (currentToken.Type == TokenType.ReferenceAction) { // Create an action ReferenceAssignment actionType = compilationContext.ReferenceAssignmentTable.GetAssignment(varIndex); ActionBinding action = compilationContext.TypeBindingTable.GetActionByName(currentToken.Value, actionType.Type); ICustomActionNode node = action.CreateActionNode(); int refIndex = varIndex; // Unless the expression result is List<Expression> expressions; skip = ParseActionParameters(index, tokens, compilationContext, out expressions); if (action.NumParameters != expressions.Count) throw new GossipScriptParameterException( String.Format("Invalid number of parameters for action:{0} found:{1} expected:{2}", action.Name, expressions.Count, action.NumParameters)); var customActionContext = new CustomActionContext(expressions, refIndex); currentParent.Next = new ExecuteCustomActionNode(node, customActionContext); currentParent = currentParent.Next; index += (skip + 1); currentToken = tokens[index]; return index; } } throw new GossipScriptException("Unhandled operand"); }
private int ParseWait(List<Token> tokens, int index, ref IActionNode currentParent) { Token currentToken; currentToken = tokens[++index]; // Open Bracket AssertExpectedTokenValue(currentToken, "(", "Expected Open Bracket"); currentToken = tokens[++index]; // Parameters List<string> parameters = ParseParameters(currentToken.Value); int ms = Int32.Parse(parameters[0]); currentParent.Next = new WaitNode(ms) {Next = new ActionNode()}; currentParent = currentParent.Next; currentToken = tokens[++index]; // Close Bracket AssertExpectedTokenValue(currentToken, ")", "Expected Close Bracket"); return index; }
private int ParseSelf(CompilationContext compilationContext, List<Token> tokens, int index, ref IActionNode currentParent) { Token currentToken = tokens[++index]; if (currentToken.Type == TokenType.ReferenceAction) { // Create an action ActionBinding action = compilationContext.TypeBindingTable.GetActionByName(currentToken.Value, compilationContext .ScriptOwnerType); ICustomActionNode node = action.CreateActionNode(); List<Expression> expressions; int skip = ParseActionParameters(index + 1, tokens, compilationContext, out expressions); if (action.NumParameters != expressions.Count) throw new GossipScriptParameterException(String.Format("Invalid number of parameters for action:{0} found:{1} expected:{2}", action.Name,expressions.Count, action.NumParameters)); var customActionContext = new CustomActionContext(expressions); currentParent.Next = new ExecuteCustomActionNode(node, customActionContext); currentParent = currentParent.Next; index += (skip + 1); currentToken = tokens[index]; return index; } if (currentToken.Type == TokenType.ReferencePropertySet) { Token operand = currentToken; Expression expression; currentToken = tokens[++index]; AssertExpectedTokenType(currentToken, TokenType.Assignment, "Unexpected token"); currentToken = tokens[++index]; int skip = ParseExpression(index, tokens, compilationContext, out expression); index += skip; currentToken = tokens[index]; if ( !m_Engine.HostBridge.TypeBindingTable.SetPropertyExists(operand.Value, compilationContext.ScriptOwnerType)) throw new GossipScriptException(String.Format("Property {0} not found or is read only.", operand.Value)); PropertySetBinding setter = m_Engine.HostBridge.TypeBindingTable.GetPropertySetByName(operand.Value, compilationContext .ScriptOwnerType); if (setter.ParameterType != expression.ReturnType) throw new GossipScriptException("Incompatile property set parameter"); currentParent.Next = new AssignReferenceProperty(-1, setter.Id, expression); currentParent = currentParent.Next; return index; } // Parse Action { // First check if we are going to encounter an assignment Int32 enounterAssignmentIndex = 0; if (EncounterAssignment(index, tokens, ref enounterAssignmentIndex)) { return ParsePropertySet(compilationContext, index - 1, tokens, ref currentParent, enounterAssignmentIndex); } Expression expression; int skip = ParseExpression(index - 1, tokens, compilationContext, out expression); index += (skip); currentToken = tokens[index - 1]; if (currentToken.Type == TokenType.ReferenceAction) { // Create an action ActionBinding action = compilationContext.TypeBindingTable.GetActionByName(currentToken.Value, expression.HostReturnType); ICustomActionNode node = action.CreateActionNode(); List<Expression> expressions; skip = ParseActionParameters(index, tokens, compilationContext, out expressions); if (action.NumParameters != expressions.Count) throw new GossipScriptParameterException( String.Format("Invalid number of parameters for action:{0} found:{1} expected:{2}", action.Name, expressions.Count, action.NumParameters)); var customActionContext = new CustomActionContext(expressions, expression); currentParent.Next = new ExecuteCustomActionNode(node, customActionContext); currentParent = currentParent.Next; index += (skip + 1); currentToken = tokens[index]; return index; } } throw new Exception("Unexpected token"); }
private int ParseApiCalls(CompilationContext compilationContext, string currentTokenValue, int index, List<Token> tokens, Token currentToken, ref IActionNode currentParent) { bool match = false; foreach (ActionInfo function in m_Engine.GlobalActions.Values) { if (currentTokenValue == function.TokenName) { List<Expression> parametersAsExpressions; int skip = ParseFunctionParameterExpressions(index, tokens, compilationContext,out parametersAsExpressions); currentParent.Next = new ExecuteAction(function, parametersAsExpressions) {Next = new ActionNode()}; currentParent = currentParent.Next; match = true; index += skip; currentToken = tokens[index]; break; } } if (match == false) { foreach (HostCall function in m_Engine.HostBridge.HostCallTable.Values) { if (function.ReturnType == GossipType.ReferenceObject) { // First check if we are going to encounter an assignment Int32 enounterAssignmentIndex = 0; if (EncounterAssignment(index, tokens, ref enounterAssignmentIndex)) { return ParsePropertySet(compilationContext, index, tokens, ref currentParent, enounterAssignmentIndex); } Expression expression; int skip = ParseExpression(index, tokens, compilationContext, out expression); if (tokens[index + skip].Type == TokenType.ReferenceAction) { index = index + skip; currentToken = tokens[index]; // Create Action ActionBinding action = compilationContext.TypeBindingTable.GetActionByName(currentToken.Value, expression.HostReturnType); ICustomActionNode node = action.CreateActionNode(); List<Expression> expressions; skip = ParseActionParameters(index + 1, tokens, compilationContext, out expressions); if (action.NumParameters != expressions.Count) throw new GossipScriptParameterException( String.Format("Invalid number of parameters for action:{0} found:{1} expected:{2}", action.Name, expressions.Count, action.NumParameters)); var customActionContext = new CustomActionContext(expressions, expression); currentParent.Next = new ExecuteCustomActionNode(node, customActionContext); currentParent = currentParent.Next; index += (skip + 1); currentToken = tokens[index]; return index; } throw new NotImplementedException( "TODO anything that returns a reference might want to be invoked"); } } } if (match == false) throw new GossipScriptException("Encountered Unknown Token", currentToken); return index; }