/// <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); }
/// <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}"); } } }