Example #1
0
 /// <summary>
 /// Génère une instruction d'affectation.
 /// </summary>
 /// <param name="instruction"></param>
 /// <returns></returns>
 string GenerateAffectationInstruction(AffectationInstruction instruction)
 {
     return(GenerateBinaryExpressionGroup(instruction.Expression, false) + ";");
 }
        /// <summary>
        /// Parse une intruction basique : appel de méthode ou affectation.
        /// La liste doit comprendre un seul jeton et pas de ;
        /// </summary>
        /// <returns></returns>
        static Instruction ParseInstruction(TokenList tokens, GlobalContext mainContext)
        {
            // Traitement spécial si return.
            if ((tokens.First().Type == TokenType.Statement))
            {
                if (tokens.Count == 2)
                {
                    InfoToken firstToken = (InfoToken)tokens[0];
                    switch (firstToken.Content)
                    {
                    case "return":
                        ReturnInstruction returnInst = new ReturnInstruction();
                        returnInst.Expression = ParseExpression(tokens[1], mainContext);
                        return(returnInst);

                    case "patchkey":
                        PatchkeyInstruction patchkeyInst = new PatchkeyInstruction();
                        patchkeyInst.Key = ((InfoToken)((OperandToken)tokens[1]).Tokens.First()).Content;
                        return(patchkeyInst);

                    default:
                        throw new Exception("Unexpected instruction");
                    }
                }
                else if (tokens.Count == 1)
                {
                    return(new ReturnInstruction());
                }
                else
                {
                    throw new Exception("Invalid 'return' expression");
                }
            }

            if (tokens.Count != 1)
            {
                // TODO : traiter les using, etc...
                throw new Exception("Unexpected token list");
            }
            Token token = tokens.First();

            // On commence les deux types d'instructions habituels.
            if (token.Type == TokenType.ExpressionGroup)
            {
                // OperandGroup + ";" : c'est une affectation, s'il n'y a pas de signe 'égal' dedans,
                // bah c'est rien du tout.
                ExpressionGroupToken   tok = (ExpressionGroupToken)token;
                AffectationInstruction ins = new AffectationInstruction();

                List <string> validTokens = new List <string>()
                {
                    "=", "+=", "-=",
                    "/=", "*="
                };

                // Si on a pas de "=", on a une expression.
                if (!validTokens.Contains(((InfoToken)tok.Operator).Content))
                {
                    throw new Exception("An expression can't be used as instruction");
                }

                ins.LeftMember = ParseSubExpression(((OperandToken)tok.Operand1).Tokens, mainContext);
                switch (((InfoToken)tok.Operator).Content)
                {
                case "=":
                    ins.RightMember = ParseExpression(tok.Operand2, mainContext);
                    break;

                case "+=":
                case "-=":
                case "/=":
                case "*=":
                    string   opString = ((InfoToken)tok.Operator).Content.Remove(1);
                    Operator op       = Operators.Mapping[opString];
                    ins.RightMember = new ExpressionGroup((IGettable)ins.LeftMember, op,
                                                          ParseExpression(tok.Operand2, mainContext));
                    break;

                default:
                    throw new Exception();
                }
                //ParseOperand((OperandToken)tok.Operand2);
                return(ins);
            }
            else if (token.Type == TokenType.OperandTokens)
            {
                TokenList internalTokens = ((TokenContainer)token).Tokens;
                Token     first          = internalTokens.First();

                // Instructions pré-faites.
                if (first.Type == TokenType.Noun)
                {
                    InfoToken itoken = (InfoToken)first;
                    switch (itoken.Content)
                    {
                    case "using":
                        if (internalTokens.Count != 2 || internalTokens[1].Type != TokenType.String)
                        {
                            throw new Exception("Invalid using instruction");
                        }
                        InfoToken itoken2 = (InfoToken)internalTokens[1];
                        mainContext.LoadedNamespaces.Add(itoken2.Content);
                        return(new UseNamespaceInstruction(itoken2.Content));

                    case "include":
                        if (internalTokens.Count != 2 || internalTokens[1].Type != TokenType.String)
                        {
                            throw new Exception("Invalid using instruction");
                        }
                        InfoToken itoken3 = (InfoToken)internalTokens[1];
                        mainContext.LoadedAssemblies.Add(itoken3.Content, Assembly.LoadWithPartialName(itoken3.Content));
                        return(new LoadAssemblyInstruction(itoken3.Content));
                    }
                }

                // C'est un appel de méthode.
                return(new MethodCallInstruction(ParseSubExpression(internalTokens, mainContext)));
            }
            throw new Exception("Uncorrect instruction");
        }