Пример #1
0
        /// <summary>
        /// functionDefine ::= def identifier '(' functionParameters ')' block
        /// </summary>
        /// <exception cref="DynException"></exception>
        public DynAstNodeFunctionDefine MatchFunctionDefine()
        {
            var r = new DynAstNodeFunctionDefine();

            var defLexeme = NextLexeme();

            if (defLexeme.Token != DynToken.KeywordDef)
            {
                throw new DynException($"语法错误,不是有效的函数定义 {defLexeme}");
            }

            var idLexeme = NextLexeme();

            if (idLexeme.Token != DynToken.Identifier)
            {
                throw new DynException($"语法错误,不是有效的函数标识符 {idLexeme}");
            }
            r.Name = idLexeme.Identifier;

            var plt = NextLexeme();

            if (plt.Token != DynToken.SymbolPareLeft)
            {
                throw new DynException($"语法错误,不是左括弧( {plt}");
            }

            r.Parameters = MatchFunctionParameters();

            var prt = NextLexeme();

            if (prt.Token != DynToken.SymbolPareRight)
            {
                throw new DynException($"语法错误,不是右括弧) {prt}");
            }

            r.Block = MatchBlock();
            return(r);
        }
Пример #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="fd"></param>
        public void CreateFunction(DynAstNodeFunctionDefine fd)
        {
            var methodBuilder = mainTypeBuider.DefineMethod(
                fd.Name,
                MethodAttributes.Public | MethodAttributes.Static,
                anyType,
                fd.Parameters.Select(i => anyType).ToArray()
                );
            var milg = methodBuilder.GetILGenerator();
            Dictionary <string, LocalBuilder> methodScope = new Dictionary <string, LocalBuilder>();
            Dictionary <string, int>          args        = new Dictionary <string, int>();

            for (int pi = 0; pi < fd.Parameters.Count; ++pi)
            {
                args.Add(fd.Parameters[pi].Identifier, pi);
            }
            foreach (var s in fd.Block.Statements)
            {
                switch (s.Type)
                {
                case DynAstType.Statement:
                {
                    var ss = s as DynAstNodeStatement;
                    EmitExpression(ss.Expression, milg, methodScope, args);
                    if (ss.IsReturn)
                    {
                        milg.Emit(OpCodes.Ret);
                        //var r = milg.DeclareLocal(anyType);
                        //var nle = milg.DefineLabel();
                        //milg.Emit(OpCodes.Dup);
                        //milg.Emit(OpCodes.Isinst, typeof(int));
                        //milg.Emit(OpCodes.Ldnull);
                        //milg.Emit(OpCodes.Cgt);
                        //milg.Emit(OpCodes.Brfalse, nle);
                        //milg.Emit(OpCodes.Newobj, anyType.GetConstructor(new Type[] { typeof(int) }));
                        //milg.Emit(OpCodes.Stloc, r);
                        //milg.Emit(OpCodes.Ldloc, r);
                        //milg.Emit(OpCodes.Ret);
                        //milg.MarkLabel(nle);

                        //var sle = milg.DefineLabel();
                        //milg.Emit(OpCodes.Dup);
                        //milg.Emit(OpCodes.Isinst, typeof(string));
                        //milg.Emit(OpCodes.Ldnull);
                        //milg.Emit(OpCodes.Cgt);
                        //milg.Emit(OpCodes.Brfalse,sle);
                        //milg.Emit(OpCodes.Newobj, anyType.GetConstructor(new Type[] { typeof(string) }));
                        //milg.Emit(OpCodes.Stloc, r);
                        //milg.Emit(OpCodes.Ldloc, r);
                        //milg.Emit(OpCodes.Ret);
                        //milg.MarkLabel(sle);

                        //var e = milg.DeclareLocal(typeof(DynException));
                        //milg.Emit(OpCodes.Ldstr, $"语法错误,未支持的类型。");
                        //milg.Emit(OpCodes.Newobj, typeof(DynException).GetConstructor(new Type[] { typeof(string) }));
                        //milg.Emit(OpCodes.Stloc, e);
                        //milg.Emit(OpCodes.Ldloc, e);
                        //milg.ThrowException(typeof(DynException));

                        //milg.Emit(OpCodes.Ldnull);
                        //milg.Emit(OpCodes.Ret);
                    }
                    break;
                }

                default:
                    throw new DynException($"语法错误,函数内部出现非语句,{s.Type}");
                }
            }
        }