Esempio n. 1
0
        /// <summary>
        /// expression ::=
        ///     operand '=' expression
        ///     operand '+' expression
        ///     operand '-' expression
        ///     operand '*' expression
        ///     operand
        /// </summary>
        /// <exception cref="DynException"></exception>
        public DynAstNodeExpression MatchExpression()
        {
            var r = new DynAstNodeExpression();

            r.Left = MatchOperand();

            var lexeme = PeekLexeme();

            switch (lexeme.Token)
            {
            case DynToken.SymbolPlus:
            case DynToken.SymbolMinus:
            case DynToken.SymbolStar:
            case DynToken.SymbolEqual:
                NextLexeme();
                r.Operation = lexeme;
                r.Right     = MatchExpression();
                break;
            }
            return(r);
        }
Esempio n. 2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="e"></param>
        /// <param name="ilg"></param>
        /// <param name="scope"></param>
        /// <param name="args"></param>
        /// <exception cref="DynException"></exception>
        public void EmitExpression(DynAstNodeExpression e, ILGenerator ilg, Dictionary <string, LocalBuilder> scope, Dictionary <string, int> args)
        {
            if (e.Operation is null)
            {
                EmitOperand(e.Left, ilg, scope, args);
                return;
            }

            switch (e.Operation.Token)
            {
            case DynToken.SymbolEqual:
            {
                if (e.Left.Lexeme.Token != DynToken.Identifier)
                {
                    throw new DynException($"语法错误,赋值操作只可作用于左值。");
                }
                // Right
                EmitExpression(e.Right, ilg, scope, args);

                if (GlobalVariables.Contains(e.Left.Lexeme.Identifier))
                {
                    ilg.Emit(OpCodes.Stfld, e.Left.Lexeme.Identifier);
                    break;
                }
                if (!scope.ContainsKey(e.Left.Lexeme.Identifier))
                {
                    LocalBuilder lbt = ilg.DeclareLocal(anyType);
                    scope.Add(e.Left.Lexeme.Identifier, lbt);
                }
                LocalBuilder lb = scope[e.Left.Lexeme.Identifier];
                ilg.Emit(OpCodes.Stloc, lb.LocalIndex);
                break;
            }

            case DynToken.SymbolPlus:
            {
                // Left
                EmitOperand(e.Left, ilg, scope, args);

                // Right
                EmitExpression(e.Right, ilg, scope, args);

                //ilg.Emit(OpCodes.Add);
                ilg.Emit(OpCodes.Call, anyType.GetMethod("add_operator"));
                break;
            }

            case DynToken.SymbolMinus:
            {
                // Left
                EmitOperand(e.Left, ilg, scope, args);

                // Right
                EmitExpression(e.Right, ilg, scope, args);

                ilg.Emit(OpCodes.Sub);
                break;
            }

            case DynToken.SymbolStar:
            {
                // Left
                EmitOperand(e.Left, ilg, scope, args);

                // Right
                EmitExpression(e.Right, ilg, scope, args);

                ilg.Emit(OpCodes.Mul);
                break;
            }

            default:
                throw new DynException($"语法错误,未知的表达式 {e.Operation}");
            }
        }