Beispiel #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="op"></param>
        /// <param name="ilg"></param>
        /// <param name="scope"></param>
        /// <param name="args"></param>
        /// <exception cref="DynException"></exception>
        public void EmitOperand(DynAstNodeOperand op, ILGenerator ilg, Dictionary <string, LocalBuilder> scope, Dictionary <string, int> args)
        {
            switch (op.Lexeme.Token)
            {
            case DynToken.Number:
                ilg.Emit(OpCodes.Ldc_R8, op.Lexeme.Number.Value);
                ilg.Emit(OpCodes.Newobj, anyType.GetConstructor(new Type[] { typeof(double) }));
                return;

            case DynToken.Identifier:
                if (scope.ContainsKey(op.Lexeme.Identifier))
                {
                    LocalBuilder lb = scope[op.Lexeme.Identifier];
                    ilg.Emit(OpCodes.Ldloc, lb.LocalIndex);
                }
                else if (args.ContainsKey(op.Lexeme.Identifier))
                {
                    ilg.Emit(OpCodes.Ldarg, args[op.Lexeme.Identifier]);
                }
                else if (GlobalVariables.Contains(op.Lexeme.Identifier))
                {
                    ilg.Emit(OpCodes.Ldfld, op.Lexeme.Identifier);
                }
                else
                {
                    throw new DynException($"语法错误,未知变量 {op.Lexeme}");
                }
                return;
            }
            throw new DynException($"语法错误,未知的操作数 {op.Lexeme}");
        }
Beispiel #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}");
            }
        }