public DelegateT Parse() { var method = new DynamicMethod( "Evaluate", typeof(long), new Type[] { typeof(long), typeof(long), typeof(long) } ); var generator = method.GetILGenerator(); PeekToken(); if (TestNoShift(Token.Type.VarDefStatement)) { VarDefStatement defStt = token.GetData <VarDefStatement>(); defStt.Emit(generator); int i = 0; defStt.names.ForEach(name => vars[name] = new Variable(name, i++, true)); PeekToken(ProgramState.AfterDef); } foreach (var(name, obj) in globalVars) { if (!vars.ContainsKey(name)) { vars[name] = obj; } } IBaseStatement stt = null; bool returns = false; while (HasToken()) { stt = token.GetData <IBaseStatement>(); returns |= stt.CheckReturn(); stt.Emit(generator); CommitPeek(); if (lexer.Source.CommitAndCheckIsEnd()) { break; } RePeekToken(ProgramState.AfterDef); } if (!returns) { throw new CompileException( "end of function is reachable without any return statement" ); } if (!(stt is ReturnStatement)) { new ReturnStatement(new Const(0)).Emit(generator); // load dummy to not get error } return((DelegateT)method.CreateDelegate(typeof(DelegateT))); }
public bool CheckReturn() { if (precalc.HasValue) { // precalculated if (precalc.Value) { return(ifBranch.CheckReturn()); } else if (elseBranch != null) { return(elseBranch.CheckReturn()); } else { return(false); } } // general case return(ifBranch.CheckReturn() && elseBranch != null && elseBranch.CheckReturn()); }