Example #1
0
        /// <summary>
        ///     For testing expression parsing only
        /// </summary>
        public Expression CompileExpression(string input, bool normalize = true)
        {
            var tokens = Lexer.Tokenize(input).ToList();
            var commandNodeRoot = new ActionNodeRoot();

            // Build string tables
            foreach (Token token in tokens)
            {
                if (token.Type == TokenType.StringLiteral)
                {
                    string data = token.Value.Substring(1, token.Value.Count() - 2);
                    commandNodeRoot.StringTable.RegisterString(data);
                }
            }

            var compilationContext = new CompilationContext(m_HostCallTable,
                                                            commandNodeRoot.StringTable,
                                                            m_Engine.HostBridge.EnumDefineTable,
                                                            m_Engine.HostBridge.TypeBindingTable,
                                                            m_Engine.HostBridge.EventBindingTable);

            Expression expression = ExpressionParser.Parse(tokens, compilationContext, normalize);
            return expression;
        }
Example #2
0
        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;
        }
Example #3
0
        private Int32 ParseFunctionParameterExpressions(Int32 startIndex, List<Token> tokenStream,
                                                        CompilationContext compilationContext, out List<Expression> rv)
        {
            rv = new List<Expression>();

            int currentIndex = startIndex;
            var positionStack = new Stack<Int32>();
            Token currentToken = tokenStream[startIndex];
            int position = startIndex;
            while (currentToken.Type != TokenType.EndStatement)
            {
                if (currentToken.Type == TokenType.OpenBracket)
                {
                    positionStack.Push(currentIndex);
                }
                if (currentToken.Type == TokenType.CloseBracket)
                {
                    position = positionStack.Pop();
                }
                if ((currentToken.Type == TokenType.FunctionArgumentSeperator && positionStack.Count == 1) ||
                    (currentToken.Type == TokenType.CloseBracket && positionStack.Count == 0))
                {
                    if (position == startIndex)
                        position += 1;

                    var tokens = new List<Token>();

                    for (int i = position + 1; i < currentIndex; i++)
                    {
                        tokens.Add(tokenStream[i]);
                    }
                    if (tokens.Count > 0)
                    {
                        tokens.Add(new Token(TokenType.EndStatement, OperationType.None, "", new TokenPosition(0, 0, 0)));
                        Expression expression;
                        ParseExpression(0, tokens, compilationContext, out expression);
                        rv.Add(expression);

                        if (positionStack.Count == 1)
                        {
                            positionStack.Pop();
                            positionStack.Push(currentIndex);
                            position = currentIndex;
                        }
                    }
                }

                currentToken = tokenStream[++currentIndex];
            }

            return currentIndex - startIndex;
        }
Example #4
0
        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");
        }
Example #5
0
        /// <summary>
        ///     Returns number of tokens to skip
        /// </summary>
        private Int32 ParseExpression(Int32 startIndex, List<Token> tokenStream, CompilationContext compilationContext, out Expression rv)
        {
            var countTokensToProcess = 0;
            int currentIndex = startIndex;
            var expressionTokenstream = new List<Token>();
            var currentToken = tokenStream[startIndex];
            while (currentToken.Type != TokenType.OpenCurlyBrace &&
                   currentToken.Type != TokenType.EndStatement &&
                   currentToken.Type != TokenType.EndOfProgram &&
                   currentToken.Type != TokenType.ReferenceAction &&
                   currentToken.Type != TokenType.ReferencePropertySet)
            {
                countTokensToProcess++;
                expressionTokenstream.Add(currentToken);
                currentToken = tokenStream[++currentIndex];
            }

            var expression = ExpressionParser.Parse(expressionTokenstream, compilationContext);

            rv = expression;
            return countTokensToProcess;
        }
Example #6
0
        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");
        }
        /// <summary>
        ///     Returns a list of semantic tokens in Reverse Polish Notation
        /// </summary>
        public Expression Parse(List<Token> tokenstream, CompilationContext compilationContext, Boolean normalize = true)
        {
            var exp = new Expression();
            var instructions = new List<SemanticToken>();
            List<SemanticToken> opcodes =
                m_ExpressionSemantics.ApplyExpressionSemantics(tokenstream, compilationContext).ToList();
            if (normalize)
                opcodes = m_ExpressionNormalizer.NormalizeExpression(0, opcodes.Count, opcodes);

            var stack = new Stack<SemanticToken>(tokenstream.Count);

            // Shunting Yard Algorithm
            // http://en.wikipedia.org/wiki/Shunting-yard_algorithm
            foreach (SemanticToken opcode in opcodes)
            {
                if (opcode.IsValue())
                {
                    instructions.Add(opcode);
                }
                else
                {
                    if (opcode.IsFunction())
                    {
                        stack.Push(opcode);
                    }
                    else
                    {
                        if (opcode.IsFunctionArgumentSeperator())
                        {
                            while (stack.Count > 0)
                            {
                                if (stack.Peek().TokenType == TokenType.OpenBracket)
                                    break;

                                SemanticToken o = stack.Pop();
                                instructions.Add(o);
                            }
                        }
                        else
                        {
                            if (opcode.IsOperator())
                            {
                                while (stack.Count > 0)
                                {
                                    SemanticToken peek = stack.Peek();
                                    if ((opcode.Precedence < peek.Precedence) ||
                                        opcode.OperatorAssociativity == OperatorAssociativity.Left &&
                                        opcode.Precedence == peek.Precedence)
                                    {
                                        instructions.Add(stack.Pop());
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }

                                stack.Push(opcode);
                            }
                            else
                            {
                                // Left Bracket
                                if (opcode.TokenType == TokenType.OpenBracket)
                                    stack.Push(opcode);

                                if (opcode.TokenType == TokenType.CloseBracket)
                                {
                                    SemanticToken token = stack.Pop();
                                    while (stack.Count > 0 && token.TokenType != TokenType.OpenBracket)
                                    {
                                        instructions.Add(token);
                                        token = stack.Pop();
                                    }

                                    if (token.TokenType != TokenType.OpenBracket)
                                        throw new GossipScriptException("Mismatched brackets");
                                }
                            }
                        }
                    }
                }
            }

            // When there are no more tokens to read
            while (stack.Count > 0)
            {
                SemanticToken op = stack.Pop();
                if (op.IsBracket())
                    throw new GossipScriptException("Mismatched brackets");

                instructions.Add(op);
            }

            // Apply the instructs to the expression and determine the return type
            ExtendedTypeAdapter result = m_ExpressionAnalyzer.DetermineReturnType(instructions, compilationContext);
            exp.Instructions = ConvertToInstructions(instructions);
            exp.ReturnType = result.TypeAdapter.GossipType;
            exp.HostReturnType = result.TypeAdapter.HostType;

            // TODO split into ExpressionInfo and Expression classes
            exp.HostData = (Int32) result.Data;
            exp.Target = (Int32) result.Target;
            return exp;
        }
Example #8
0
        private ActionNodeRoot CompileEvent(List<Token> tokens, Type selfTarget, StringTable stringTable,
                                            Type eventType = null)
        {
            var commandNodeRoot = new ActionNodeRoot();

            var compilationContext = new CompilationContext(m_HostCallTable,
                                                            stringTable,
                                                            m_Engine.HostBridge.EnumDefineTable,
                                                            m_Engine.HostBridge.TypeBindingTable,
                                                            m_Engine.HostBridge.EventBindingTable);
            compilationContext.ScriptOwnerType = selfTarget;
            compilationContext.EventType = eventType;
            commandNodeRoot.Next = Compile(tokens, compilationContext);

            return commandNodeRoot;
        }
Example #9
0
        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;
        }
Example #10
0
        public Int32 ParseActionParameters(Int32 startIndex, List<Token> tokenStream, CompilationContext context,
                                           out List<Expression> expressions)
        {
            if (tokenStream[startIndex].Type != TokenType.OpenBracket)
                throw new GossipScriptException("Expected Open bracket as first token");

            expressions = new List<Expression>();
            int height = 1;
            int currentIndex = startIndex;
            var tokens = new List<Token>();
            for (int i = 1; i < tokenStream.Count; i++)
            {
                currentIndex = i + startIndex;

                if (tokenStream[currentIndex].Type == TokenType.OpenBracket)
                    height++;

                if (tokenStream[currentIndex].Type == TokenType.CloseBracket)
                    height--;

                if (height == 0 || tokenStream[currentIndex].Type == TokenType.FunctionArgumentSeperator)
                {
                    // Parse
                    if (tokens.Count > 0)
                    {
                        Expression expression = ExpressionParser.Parse(tokens, context);
                        expressions.Add(expression);
                        tokens.Clear();
                    }
                }
                else
                {
                    tokens.Add(tokenStream[currentIndex]);
                }

                if (height == 0)
                    break;
            }

            return currentIndex - startIndex;
        }
Example #11
0
        private IActionNode Compile(List<Token> tokenlist, CompilationContext compilationContext)
        {
            Precompiler.CompilationContext = compilationContext;
            List<Token> tokens = m_Precompiler.ApplyPrecompileSemantic(tokenlist);

            IActionNode rootNode = new ActionNode();
            IActionNode currentParent = rootNode;

            int index = -1;
            while (index < tokens.Count - 2)
            {
                Token currentToken = tokens[++index];
                string currentTokenValue = tokens[index].Value;

                switch (currentToken.Type)
                {
                    case TokenType.EndStatement:
                        continue;
                    case TokenType.EvaluateExpression:
                        index = ParseEvaluateExpression(compilationContext, tokens, index, ref currentParent);
                        continue;
                    case TokenType.ParallelBlock:
                        index = ParseParallelBlock(compilationContext, index, tokens, ref currentParent);
                        continue;
                    case TokenType.LocalStringAccess:
                    case TokenType.LocalStringAccessEnum:
                    case TokenType.GlobalStringAccess:
                    case TokenType.GlobalStringAccessEnum:
                        index = ParseStringAccess(compilationContext, currentToken, tokens, index, ref currentParent);
                        continue;
                    case TokenType.LocalVariableAccess:
                    case TokenType.LocalVariableAccessEnum:
                    case TokenType.GlobalVariableAccess:
                    case TokenType.GlobalVariableAccessEnum:
                        index = ParseVariableAccess(compilationContext, currentToken, tokens, index, ref currentParent);
                        continue;
                    case TokenType.GlobalFlagAccess:
                    case TokenType.GlobalFlagAccessEnum:
                    case TokenType.LocalFlagAccess:
                    case TokenType.LocalFlagAccessEnum:
                        index = ParseFlagAccess(compilationContext, currentToken, tokens, index, ref currentParent);
                        continue;
                    case TokenType.Event:
                        index = ParseEvent(compilationContext, tokens, index, ref currentParent);
                        continue;
                    case TokenType.Self:
                        index = ParseSelf(compilationContext, tokens, index, ref currentParent);
                        continue;
                    //case TokenType.ModuleAccess:
                    //    index = ParseModuleAccess(compilationContext, index, tokens, ref currentParent);
                    //    continue;
                    case TokenType.ReferenceObjectAccess:
                    case TokenType.ReferenceObjectAccessEnum:
                        index = ParseReferenceObjectAccess(compilationContext, currentToken, tokens, index,
                                                           ref currentParent);
                        continue;
                    case TokenType.WaitStatement:
                        index = ParseWait(tokens, index, ref currentParent);
                        continue;
                    case TokenType.If:
                        index = ParseConditional(compilationContext, tokens, index, ref currentParent);
                        continue;
                    case TokenType.Else:
                        throw new GossipScriptException("Else without If", currentToken);
                    case TokenType.Yeild:
                        currentParent = ParseYeild(currentParent, tokens, ref index);
                        continue;
                    case TokenType.Return:
                        currentParent = ParseReturn(currentParent, tokens, ref index);
                        continue;
                    case TokenType.Exit:
                        currentParent = ParseExit(currentParent, tokens, ref index);
                        continue;
                }

                // If none of the above in the switch statement
                index = ParseApiCalls(compilationContext, currentTokenValue, index, tokens, currentToken, ref currentParent);
            }

            return rootNode;
        }
Example #12
0
        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;
        }
Example #13
0
        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 ExtendedTypeAdapter DetermineReturnType(List<SemanticToken> tokens, CompilationContext context)
        {
            var stack = new Stack<ExtendedTypeAdapter>(tokens.Count);

            foreach (SemanticToken opcode in tokens)
            {
                if (opcode.IsNumber())
                {
                    stack.Push(new ExtendedTypeAdapter(GossipType.Number));
                }
                else
                {
                    // Evaluate opcode
                    switch (opcode.TokenType)
                    {
                        case TokenType.ModuleAccess:
                            {
                                var result = new ExtendedTypeAdapter(GossipType.ReferenceModule);
                                result.Data = opcode.Data; // Module Id

                                stack.Push(result);
                                break;
                            }
                        case TokenType.Event:
                            {
                                var adapter = new ExtendedTypeAdapter(GossipType.ReferenceObject);
                                adapter.Data = -2; // Reference type -2 indicates the event object
                                //  adapter.Target = opcode.Data;
                                stack.Push(adapter);
                                break;
                            }
                        case TokenType.Self:
                            {
                                var adapter = new ExtendedTypeAdapter(GossipType.ReferenceObject);
                                adapter.Data = -1; // Reference type -1 indicates the script owner
                                stack.Push(adapter);
                                break;
                            }
                        case TokenType.Addition:
                            {
                                GossipType rhs = stack.Pop().TypeAdapter.GossipType;
                                GossipType lhs = stack.Pop().TypeAdapter.GossipType;

                                if (rhs == GossipType.String && lhs == GossipType.String)
                                {
                                    opcode.TokenType = TokenType.StringStringConcatination;
                                    stack.Push(new ExtendedTypeAdapter(GossipType.String));
                                    break;
                                }

                                if (rhs == GossipType.String && lhs == GossipType.Number)
                                {
                                    opcode.TokenType = TokenType.DoubleStringConcatination;
                                    stack.Push(new ExtendedTypeAdapter(GossipType.String));
                                    break;
                                }

                                if (rhs == GossipType.Number && lhs == GossipType.String)
                                {
                                    opcode.TokenType = TokenType.StringDoubleConcatination;
                                    stack.Push(new ExtendedTypeAdapter(GossipType.String));
                                    break;
                                }

                                if (rhs == GossipType.Number && lhs == GossipType.Number)
                                {
                                    stack.Push(new ExtendedTypeAdapter(GossipType.Number));
                                    break;
                                }

                                throw new GossipScriptException(
                                    String.Format("Invalid operands: {0},{1} on operator:{2}", rhs, lhs,
                                                  opcode.TokenType));

                                break;
                            }
                        case TokenType.HostFunctionCall:
                            {
                                var functionId = (Int32) opcode.Data;
                                HostCall function = context.HostCallTable.GetFunctionById(functionId);
                                for (int i = 0; i < function.NumParameters; i++)
                                {
                                    stack.Pop(); // TODO Check function parameter types are expected
                                }
                                stack.Push(new ExtendedTypeAdapter(function.ReturnType, function.HostType));
                                break;
                            }
                        case TokenType.Negation:
                            {
                                GossipType rhs = stack.Peek().TypeAdapter.GossipType;
                                if (rhs != GossipType.Number)
                                    throw new GossipScriptException(String.Format("Invalid operator:{0} on string",
                                                                                  opcode.TokenType));

                                break;
                            }

                        case TokenType.Subtract:
                        case TokenType.Multiply:
                        case TokenType.Divide:
                        case TokenType.PowerOf:
                        case TokenType.UnaryMinus:
                        case TokenType.Modulo:
                        case TokenType.LogicalAnd:
                        case TokenType.LogicalOr:
                            {
                                GossipType rhs = stack.Pop().TypeAdapter.GossipType;
                                GossipType lhs = stack.Pop().TypeAdapter.GossipType;
                                if (rhs == GossipType.String || lhs == GossipType.String)
                                    throw new GossipScriptException(String.Format("Invalid operator:{0} on string",
                                                                                  opcode.TokenType));

                                stack.Push(new ExtendedTypeAdapter(GossipType.Number));

                                break;
                            }
                        case TokenType.Equal:
                        case TokenType.NotEqual:
                        case TokenType.GreaterThan: //  TODO Implement for strings
                        case TokenType.LessThan: // TODO Implement for strings
                        case TokenType.GreaterThanOrEqualTo: //  TODO Implement for strings
                        case TokenType.LessThanOrEqualTo: //  TODO Implement for strings
                            {
                                GossipType rhs = stack.Pop().TypeAdapter.GossipType;
                                GossipType lhs = stack.Pop().TypeAdapter.GossipType;
                                if (rhs == GossipType.String && lhs == GossipType.String)
                                {
                                    opcode.TokenType = OperatorToStringOperator(opcode.TokenType);
                                    stack.Push(new ExtendedTypeAdapter(GossipType.Number));
                                    break;
                                }
                                if (rhs == GossipType.Number && lhs == GossipType.Number)
                                {
                                    stack.Push(new ExtendedTypeAdapter(GossipType.Number));
                                    break;
                                }
                                if (rhs == GossipType.ReferenceObject &&
                                    lhs == GossipType.ReferenceObject)
                                {
                                    opcode.TokenType = OperatorToReferenceOperator(opcode.TokenType);
                                    stack.Push(new ExtendedTypeAdapter(GossipType.Number));
                                    break;
                                }

                                throw new GossipScriptException(
                                    String.Format("Invalid operands: {0},{1} on operator:{2}", rhs, lhs,
                                                  opcode.TokenType));
                                break;
                            }
                        case TokenType.LocalVariableAccess:
                        case TokenType.GlobalVariableAccess:
                        case TokenType.GlobalFlagAccess:
                        case TokenType.LocalFlagAccess:
                            {
                                stack.Push(new ExtendedTypeAdapter(GossipType.Number));
                                break;
                            }
                        case TokenType.ReferenceObjectAccess:
                            {
                                var result = new ExtendedTypeAdapter(GossipType.ReferenceObject);
                                result.Data = opcode.Data;
                                stack.Push(result);
                                break;
                            }
                        case TokenType.GlobalStringAccess:
                        case TokenType.LocalStringAccess:
                        case TokenType.StringLiteral:
                            {
                                stack.Push(new ExtendedTypeAdapter(GossipType.String));
                                break;
                            }
                        case TokenType.StringEquality:
                            {
                                stack.Push(new ExtendedTypeAdapter(GossipType.Number));
                                break;
                            }
                        case TokenType.StringInequality:
                            {
                                stack.Push(new ExtendedTypeAdapter(GossipType.Number));
                                break;
                            }
                        case TokenType.ReferenceAction:
                            {
                                ExtendedTypeAdapter stackObject = stack.Pop(); // The reference object
                                Type objType = stackObject.TypeAdapter.HostType;
                                var target = (Int32) TargetObjectType.TempReferenceObject; // Target Temp Object

                                if (objType == null) // Unknown object, need to look at the assignment table
                                {
                                    var id = (Int32) stackObject.Data; // Reference Index
                                    if (context.ReferenceAssignmentTable.HasAssignment(id) == false)
                                        throw new GossipScriptException(
                                            String.Format("Ref[{0}] has not been assigned any value", id));

                                    ReferenceAssignment reference = context.ReferenceAssignmentTable.GetAssignment(id);
                                    objType = reference.Type;

                                    target = id; // Ref index
                                }

                                string name = opcode.StringData; // Should be name of Action
                                ActionBinding action = context.TypeBindingTable.GetActionByName(name, objType);
                                opcode.Data = action.Id; // write back the id

                                // Pop off number of parameters from the stack
                                for (int i = 0; i < action.NumParameters; i++)
                                {
                                    TypeAdapter parameter = stack.Pop().TypeAdapter;
                                    if (action.ParameterInfo[i].GossipType != parameter.GossipType)
                                    {
                                        throw new GossipScriptException(
                                            String.Format(
                                                "Invalid parameter type:{0} for parameter #{1} expected type:{2}",
                                                parameter.GossipType, i + 1, action.ParameterInfo[i].GossipType));
                                    }
                                }

                                var typeAdapter = new ExtendedTypeAdapter(GossipType.Action, objType)
                                    {
                                        Data = opcode.Data, // Action Id
                                        Target = target
                                    };
                                stack.Push(typeAdapter);
                                break;
                            }
                        //case TokenType.ModulePropertyGet:
                        //    {
                        //        ExtendedTypeAdapter stackObject = stack.Pop();
                        //            // This should be the object to call the method on
                        //        var moduleId = (Int32) stackObject.Data;
                        //        ModuleBinding module = context.ModuleBindingTable.GetModuleById(moduleId);

                        //        string name = opcode.StringData; // Should be name of method
                        //        PropertyGetBinding method = context.ModuleBindingTable.GetPropertyGetByName(name,
                        //                                                                                    module
                        //                                                                                        .ModuleType);
                        //        opcode.Data = method.Id; // write back the id

                        //        var typeAdapter = new ExtendedTypeAdapter(method.GossipType, method.HostType,
                        //                                                  (Int32) opcode.Data);
                        //        stack.Push(typeAdapter);
                        //        break;
                        //    }
                        //case TokenType.ModuleMethodCall:
                        //    {
                        //        ExtendedTypeAdapter stackObject = stack.Pop();
                        //            // This should be the object to call the method on
                        //        var moduleId = (Int32) stackObject.Data;
                        //        ModuleBinding module = context.ModuleBindingTable.GetModuleById(moduleId);

                        //        string name = opcode.StringData; // Should be name of method
                        //        MethodBinding method = context.ModuleBindingTable.GetMethodBindingByName(name,
                        //                                                                                 module
                        //                                                                                     .ModuleType);
                        //        opcode.Data = method.Id; // write back the id

                        //        // Pop off number of parameters from the stack
                        //        for (int i = 0; i < method.NumParameters; i++)
                        //        {
                        //            TypeAdapter parameter = stack.Pop().TypeAdapter;
                        //            if (method.ParameterInfo[i].GossipType != parameter.GossipType)
                        //                throw new GossipScriptParameterException(
                        //                    String.Format(
                        //                        "Invalid parameter type:{0} for parameter #{1} expected type:{2}",
                        //                        parameter.GossipType, i + 1, method.ParameterInfo[i].GossipType));
                        //        }
                        //        var typeAdapter = new ExtendedTypeAdapter(method.GossipType, method.HostReturnType,
                        //                                                  (Int32) opcode.Data);
                        //        stack.Push(typeAdapter);
                        //        break;
                        //    }
                        case TokenType.MethodCall:
                            {
                                ExtendedTypeAdapter stackObject = stack.Pop();
                                    // This should be the object to call the method on
                                Type objType = stackObject.TypeAdapter.HostType;

                                if (objType == null) // Unknown object, need to look at the assignment table
                                {
                                    var id = (Int32) stackObject.Data; // Reference Index
                                    if (id == -1)
                                    {
                                        objType = context.ScriptOwnerType;
                                    }
                                    else
                                    {
                                        if (context.ReferenceAssignmentTable.HasAssignment(id) == false)
                                            throw new GossipScriptException(
                                                String.Format("Ref[{0}] has not been assigned any value", id));

                                        ReferenceAssignment reference =
                                            context.ReferenceAssignmentTable.GetAssignment(id);
                                        objType = reference.Type;
                                    }
                                }

                                string name = opcode.StringData; // Should be name of method
                                MethodBinding method = context.TypeBindingTable.GetMethodByName(name, objType);
                                opcode.Data = method.Id; // write back the id

                                // Pop off number of parameters from the stack
                                for (int i = 0; i < method.NumParameters; i++)
                                {
                                    TypeAdapter parameter = stack.Pop().TypeAdapter;
                                    if (method.ParameterInfo[i].GossipType != parameter.GossipType)
                                    {
                                        throw new GossipScriptParameterException(
                                            String.Format(
                                                "Invalid parameter type:{0} for parameter #{1} expected type:{2}",
                                                parameter.GossipType, i + 1, method.ParameterInfo[i].GossipType));
                                    }
                                }
                                var typeAdapter = new ExtendedTypeAdapter(method.GossipType, method.HostReturnType)
                                    {
                                        Data = opcode.Data
                                    };
                                stack.Push(typeAdapter);
                                break;
                            }
                        case TokenType.ReferencePropertyGet:
                            {
                                ExtendedTypeAdapter stackObject = stack.Pop();
                                Type objType = stackObject.TypeAdapter.HostType;
                                if (objType == null) // Unknown object, need to look at the assignment table
                                {
                                    var id = (Int32) stackObject.Data; // Reference Index
                                    if (id == -1)
                                    {
                                        objType = context.ScriptOwnerType;
                                    }
                                    else
                                    {
                                        if (id == -2)
                                        {
                                            objType = context.EventType;
                                        }
                                        else
                                        {
                                            if (context.ReferenceAssignmentTable.HasAssignment(id) == false)
                                                throw new GossipScriptException(
                                                    String.Format("Ref[{0}] has not been assigned any value", id));

                                            ReferenceAssignment reference =
                                                context.ReferenceAssignmentTable.GetAssignment(id);
                                            objType = reference.Type;
                                        }
                                    }
                                }

                                string index = opcode.StringData; // Property Index
                                PropertyGetBinding property = context.TypeBindingTable.GetPropertyGetByName(index,
                                                                                                            objType);
                                opcode.Data = property.Id; // write back the id

                                stack.Push(new ExtendedTypeAdapter(property.GossipType, property.HostType));
                                break;
                            }
                        default:
                            throw new Exception(String.Format("Unknown operator{0}", opcode.TokenType));
                            break;
                    }
                }
            }

            if (stack.Count > 1)
                throw new Exception("Stack should only have one remaining entry");

            ExtendedTypeAdapter r = stack.Pop();
            return r;
        }
Example #15
0
        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;
        }
Example #16
0
        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;
        }
Example #17
0
        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;
        }
Example #18
0
        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;
        }
Example #19
0
        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");
        }
        public IEnumerable<SemanticToken> ApplyExpressionSemantics(IEnumerable<Token> tokenStream,
                                                                   CompilationContext compilationContext)
        {
            List<Token> tokens = tokenStream.ToList();

            // Preprocess semantics
            for (int i = 0; i < tokens.Count; i++)
            {
                if (tokens[i].Type == TokenType.Subtract)
                {
                    if (tokens.Count - 1 < i + 1)
                        throw new Exception("Unexpected end of token stream");

                    if (tokens[i + 1].Type == TokenType.OpenBracket)
                        tokens[i].Type = TokenType.UnaryMinus;

                    if (i > 0 && tokens[i - 1].OperationType == OperationType.Operator)
                        tokens[i].Type = TokenType.UnaryMinus;

                    if (i > 0 && tokens[i - 1].Type == TokenType.OpenBracket)
                        tokens[i].Type = TokenType.UnaryMinus;

                    if (i == 0)
                        tokens[i].Type = TokenType.UnaryMinus;
                }

                // Missing Semi colon checks
                if (i > 0)
                {
                    if (tokens[i].Type == TokenType.HostFunctionCall)
                    {
                        if (tokens[i - 1].Type != TokenType.OpenBracket &&
                            tokens[i - 1].OperationType != OperationType.Operator &&
                            tokens[i - 1].Type != TokenType.FunctionArgumentSeperator)
                        {
                            throw new GossipScriptMissingSemiColonException("Missing SemiColon", tokens[i]);
                        }
                    }
                }
            }

            // Convert to semantic tokens
            var rv = new List<SemanticToken>(tokens.Count());
            for (int i = 0; i < tokens.Count; i++)
            {
                Token token = tokens[i];

                if (token.Type == TokenType.EndStatement || token.Type == TokenType.EndOfProgram)
                    continue;

                var t = new SemanticToken {TokenType = token.Type, OperationType = OperationType.Operator};

                switch (token.Type)
                {
                    case TokenType.DecimalLiteral:
                        t.OperationType = OperationType.Operand;
                        t.Data = Double.Parse(token.Value);
                        break;
                    case TokenType.Addition:
                        t.Precedence = 6;
                        t.OperatorAssociativity = OperatorAssociativity.Left;
                        break;
                    case TokenType.Subtract:
                        t.Precedence = 6;
                        t.OperatorAssociativity = OperatorAssociativity.Left;
                        break;
                    case TokenType.Multiply:
                        t.Precedence = 7;
                        t.OperatorAssociativity = OperatorAssociativity.Left;
                        break;
                    case TokenType.Divide:
                        t.Precedence = 7;
                        t.OperatorAssociativity = OperatorAssociativity.Left;
                        break;
                    case TokenType.PowerOf:
                        t.Precedence = 7;
                        t.OperatorAssociativity = OperatorAssociativity.Right;
                        break;
                    case TokenType.UnaryMinus:
                        t.Precedence = 8;
                        t.OperatorAssociativity = OperatorAssociativity.Right;
                        break;
                    case TokenType.Negation:
                        t.Precedence = 8;
                        t.OperatorAssociativity = OperatorAssociativity.Right;
                        break;
                    case TokenType.Modulo:
                        t.Precedence = 7;
                        t.OperatorAssociativity = OperatorAssociativity.Left;
                        break;
                    case TokenType.GreaterThan:
                        t.Precedence = 5;
                        t.OperatorAssociativity = OperatorAssociativity.Left;
                        break;
                    case TokenType.GreaterThanOrEqualTo:
                        t.Precedence = 5;
                        t.OperatorAssociativity = OperatorAssociativity.Left;
                        break;
                    case TokenType.LessThan:
                        t.Precedence = 5;
                        t.OperatorAssociativity = OperatorAssociativity.Left;
                        break;
                    case TokenType.LessThanOrEqualTo:
                        t.Precedence = 5;
                        t.OperatorAssociativity = OperatorAssociativity.Left;
                        break;
                    case TokenType.Equal:
                        t.Precedence = 4;
                        t.OperatorAssociativity = OperatorAssociativity.Left;
                        break;
                    case TokenType.NotEqual:
                        t.Precedence = 4;
                        t.OperatorAssociativity = OperatorAssociativity.Left;
                        break;
                    case TokenType.LogicalAnd:
                        t.Precedence = 3;
                        t.OperatorAssociativity = OperatorAssociativity.Left;
                        break;
                    case TokenType.LogicalOr:
                        t.Precedence = 2;
                        t.OperatorAssociativity = OperatorAssociativity.Left;
                        break;
                    case TokenType.HostFunctionCall:
                        HostCall function = compilationContext.HostCallTable.GetFunctionByName(token.Value);
                        t.OperationType = OperationType.FunctionCall;
                        t.Precedence = 9;
                        t.NumOperands = function.NumParameters;
                        t.Data = function.Id;
                        break;
                    case TokenType.FunctionArgumentSeperator:
                        t.OperationType = OperationType.None;
                        break;
                    case TokenType.LocalFlagAccess:
                        t.OperationType = OperationType.Operand;
                        t.Precedence = 9;
                        t.Data = token.GetAccessIndex(compilationContext.EnumTable);
                        break;
                    case TokenType.LocalVariableAccess:
                        t.OperationType = OperationType.Operand;
                        t.Precedence = 9;
                        t.Data = token.GetAccessIndex(compilationContext.EnumTable);
                        break;
                    case TokenType.GlobalFlagAccess:
                        t.OperationType = OperationType.Operand;
                        t.Precedence = 9;
                        t.Data = token.GetAccessIndex(compilationContext.EnumTable);
                        break;
                    case TokenType.GlobalVariableAccess:
                        t.OperationType = OperationType.Operand;
                        t.Precedence = 9;
                        t.Data = token.GetAccessIndex(compilationContext.EnumTable);
                        break;
                    case TokenType.TrueLiteral:
                        t.TokenType = TokenType.DecimalLiteral;
                        t.OperationType = OperationType.Operand;
                        t.Data = 1;
                        t.Precedence = 9;
                        break;
                    case TokenType.FalseLiteral:
                        t.TokenType = TokenType.DecimalLiteral;
                        t.OperationType = OperationType.Operand;
                        t.Precedence = 9;
                        break;
                    case TokenType.OpenBracket:
                        t.OperationType = OperationType.None;
                        break;
                    case TokenType.CloseBracket:
                        t.OperationType = OperationType.None;
                        break;
                    case TokenType.Assignment:
                        throw new GossipScriptException("Assignment operator not allowed within an expression");
                        break;
                    case TokenType.DecrementAndAssign:
                        throw new GossipScriptException("Decrement operator not allowed within an expression");
                        break;
                    case TokenType.IncrementAndAssign:
                        throw new GossipScriptException("Decrement operator not allowed within an expression");
                        break;
                    case TokenType.LocalStringAccess:
                        t.OperationType = OperationType.Operand;
                        t.Precedence = 9;
                        t.Data = token.GetAccessIndex(compilationContext.EnumTable);
                        break;
                    case TokenType.GlobalStringAccess:
                        t.OperationType = OperationType.Operand;
                        t.Precedence = 9;
                        t.Data = token.GetAccessIndex(compilationContext.EnumTable);
                        break;
                    case TokenType.StringLiteral:
                        t.TokenValue = token.Value;
                        t.OperationType = OperationType.Operand;
                        string data = token.Value.Substring(1, token.Value.Length - 2); // Remove brackets
                        t.Data = compilationContext.StringTable.GetIdByString(data);
                        break;
                    case TokenType.ReferenceObjectAccess:
                        t.OperationType = OperationType.Operand;
                        t.Precedence = 9;
                        t.Data = token.GetAccessIndex(compilationContext.EnumTable);
                        break;
                    case TokenType.GlobalStringAccessEnum:
                        t.OperationType = OperationType.Operand;
                        t.Precedence = 9;
                        t.Data = token.GetAccessIndex(compilationContext.EnumTable);
                        t.TokenType = TokenType.GlobalStringAccess;
                        break;
                    case TokenType.LocalStringAccessEnum:
                        t.OperationType = OperationType.Operand;
                        t.Precedence = 9;
                        t.Data = token.GetAccessIndex(compilationContext.EnumTable);
                        t.TokenType = TokenType.LocalStringAccess;
                        break;
                    case TokenType.LocalVariableAccessEnum:
                        t.OperationType = OperationType.Operand;
                        t.Precedence = 9;
                        t.Data = token.GetAccessIndex(compilationContext.EnumTable);
                        t.TokenType = TokenType.LocalVariableAccess;
                        break;
                    case TokenType.GlobalVariableAccessEnum:
                        t.OperationType = OperationType.Operand;
                        t.Precedence = 9;
                        t.Data = token.GetAccessIndex(compilationContext.EnumTable);
                        t.TokenType = TokenType.GlobalVariableAccess;
                        break;
                    case TokenType.LocalFlagAccessEnum:
                        t.OperationType = OperationType.Operand;
                        t.Precedence = 9;
                        t.Data = token.GetAccessIndex(compilationContext.EnumTable);
                        t.TokenType = TokenType.LocalFlagAccess;
                        break;
                    case TokenType.GlobalFlagAccessEnum:
                        t.OperationType = OperationType.Operand;
                        t.Precedence = 9;
                        t.Data = token.GetAccessIndex(compilationContext.EnumTable);
                        t.TokenType = TokenType.GlobalFlagAccess;
                        break;
                    case TokenType.Event:
                    case TokenType.Self:
                        {
                            t.OperationType = OperationType.Operand;
                            t.Precedence = 9;
                            break;
                        }
                    case TokenType.ReferencePropertyGet:
                        {
                            t.OperationType = OperationType.PropertyCall;
                            t.Precedence = 9;
                            t.StringData = token.Value;
                            t.Data = -666; // Unknown at this stage
                            break;
                        }
                    case TokenType.MethodCall:
                        {
                            t.OperationType = OperationType.MethodCall;
                            t.Precedence = 9;
                            t.StringData = token.Value;
                            t.Data = -666; // Unknown at this stage
                            break;
                        }
                    case TokenType.ReferenceAction:
                        {
                            t.OperationType = OperationType.CreateAction;
                            t.Precedence = 9;
                            t.StringData = token.Value;
                            t.Data = -666; // Unknown at this stage
                            break;
                        }
                    //case TokenType.ModuleAccess:
                    //    {
                    //        t.OperationType = OperationType.Operand;
                    //        t.Precedence = 9;
                    //        t.StringData = token.Value;
                    //        t.Data = compilationContext.ModuleBindingTable.GetModuleByName(token.Value).Id;
                    //        break;
                    //    }
                    case TokenType.ModuleMethodCall:
                        {
                            t.OperationType = OperationType.MethodCall;
                            t.Precedence = 9;
                            t.StringData = token.Value;
                            t.Data = -666; // Unknown at this stage
                            break;
                        }
                    case TokenType.ModulePropertyGet:
                        {
                            t.OperationType = OperationType.PropertyCall;
                            t.Precedence = 9;
                            t.StringData = token.Value;
                            t.Data = -666; // Unknown at this stage
                            break;
                        }
                    case TokenType.Enum:
                    {
                            t.TokenType = TokenType.DecimalLiteral;
                            t.OperationType = OperationType.Operand;
                            t.Data = compilationContext.EnumTable.DefinesByString[token.Value];
                            t.Precedence = 9;
                            break;
                        }
                    default:

                        throw new NotImplementedException(t.TokenType.ToString());

                        break;
                }
                rv.Add(t);
            }

            ValidateSemantics(rv);
            return rv;
        }