protected IEnumerable<CilProduction> DoGetRules(MethodInfo method, CilSymbolRef leftSide) { var outcome = CilSymbolRef.Create(method.ReturnType); if (!object.Equals(outcome, leftSide)) { return Enumerable.Empty<CilProduction>(); } var pattern = new List<CilSymbolRef>(); int argShift = 0; CilSymbolRef thisSymbol = GetThisSymbol(); if (thisSymbol != null) { ++argShift; pattern.Add(thisSymbol); } var ruleMask = DoGetRuleMask(method); SubstituteRuleMask(method, pattern, ruleMask); var rule = new CilProduction( outcome: outcome, pattern: pattern, precedence: GetPrecedence(), context: GetContext(method, thisSymbol != null), actionBuilder: code => { if (thisSymbol != null) { code.LdActionArgument(0, method.DeclaringType); } // Pass rule-arguments to the rule-method for (int i = 0; i != method.GetParameters().Length; ++i) { var param = method.GetParameters()[i]; int ruleArgIndex = NthEmptySlotIndex(ruleMask, i); if (thisSymbol != null) { ++ruleArgIndex; } code.LdActionArgument(ruleArgIndex, param.ParameterType); } code.Emit( il => { il.Call(method); if (method.ReturnType == typeof(void)) { il.Ldnull(); } else if (method.ReturnType.IsValueType) { il.Box(il.Types.Import(method.ReturnType)); } return il; }); return code; }); return new[] { rule }; }
protected IEnumerable <CilProduction> DoGetRules(MethodInfo method, CilSymbolRef leftSide) { var outcome = CilSymbolRef.Create(method.ReturnType); if (!object.Equals(outcome, leftSide)) { return(Enumerable.Empty <CilProduction>()); } var pattern = new List <CilSymbolRef>(); int argShift = 0; CilSymbolRef thisSymbol = GetThisSymbol(); if (thisSymbol != null) { ++argShift; pattern.Add(thisSymbol); } var ruleMask = DoGetRuleMask(method); SubstituteRuleMask(method, pattern, ruleMask); var rule = new CilProduction( outcome: outcome, pattern: pattern, precedence: GetPrecedence(), context: GetContext(method, thisSymbol != null), actionBuilder: code => { if (thisSymbol != null) { code.LdActionArgument(0, method.DeclaringType); } // Pass rule-arguments to the rule-method for (int i = 0; i != method.GetParameters().Length; ++i) { var param = method.GetParameters()[i]; int ruleArgIndex = NthEmptySlotIndex(ruleMask, i); if (thisSymbol != null) { ++ruleArgIndex; } code.LdActionArgument(ruleArgIndex, param.ParameterType); } code.Emit( il => { il.Call(method); if (method.ReturnType == typeof(void)) { il.Ldnull(); } else if (method.ReturnType.IsValueType) { il.Box(il.Types.Import(method.ReturnType)); } return(il); }); return(code); }); return(new[] { rule }); }