Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- enum ExecutionState
- {
- S_EVAL,
- S_CALL1,
- S_CALL2
- };
- enum NodeType
- {
- AND_OPERATOR,
- OR_OPERATOR,
- VALUE
- };
- class LocalVars
- {
- public IEnumerator<Node> Enumerator;
- public bool Result;
- }
- class Context
- {
- public Node Node;
- public LocalVars LocalVariables;
- public ExecutionState State;
- public Context(Node node, ExecutionState state)
- {
- this.Node = node;
- this.State = state;
- this.LocalVariables = new LocalVars();
- }
- };
- class Node
- {
- public bool Value;
- public NodeType Type;
- public List<Node> Childrens;
- };
- static bool EvaluateNode(Node node)
- {
- Stack<Context> stack = new Stack<Context>();
- Context context = new Context(node, ExecutionState.S_EVAL);
- stack.Push(context);
- bool returnresult = false;
- while(stack.Any())
- {
- context = stack.Pop();
- switch(context.State)
- {
- case ExecutionState.S_EVAL:
- switch(context.Node.Type)
- {
- case NodeType.AND_OPERATOR:
- if(context.LocalVariables.Enumerator == null)
- {
- context.LocalVariables.Enumerator = context.Node.Childrens.GetEnumerator();
- context.LocalVariables.Result = true;
- }
- if(context.LocalVariables.Enumerator.MoveNext())
- {
- context.State = ExecutionState.S_CALL1;
- stack.Push(context); // push resume with S_CALL1
- Context call = new Context(context.LocalVariables.Enumerator.Current, ExecutionState.S_EVAL);
- stack.Push(call); // push call
- }
- else
- {
- returnresult = context.LocalVariables.Result; // no push -> return
- }
- break;
- case NodeType.OR_OPERATOR:
- if(context.LocalVariables.Enumerator == null)
- {
- context.LocalVariables.Enumerator = context.Node.Childrens.GetEnumerator();
- context.LocalVariables.Result = false;
- }
- if(context.LocalVariables.Enumerator.MoveNext())
- {
- context.State = ExecutionState.S_CALL2;
- stack.Push(context); // push resume with S_CALL2
- Context call = new Context(context.LocalVariables.Enumerator.Current, ExecutionState.S_EVAL);
- stack.Push(call); // push call
- }
- else
- {
- returnresult = context.LocalVariables.Result; // no push -> return
- }
- break;
- case NodeType.VALUE:
- returnresult = context.Node.Value; // no push -> return
- break;
- }
- break;
- case ExecutionState.S_CALL1:
- context.LocalVariables.Result = context.LocalVariables.Result && returnresult;
- context.State = ExecutionState.S_EVAL;
- stack.Push(context); // continue with S_EVAL
- break;
- case ExecutionState.S_CALL2:
- context.LocalVariables.Result = context.LocalVariables.Result || returnresult;
- context.State = ExecutionState.S_EVAL;
- stack.Push(context); // continue with S_EVAL
- break;
- }
- }
- return returnresult;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement