コード例 #1
0
ファイル: Compiler.cs プロジェクト: SealedSun/prx
        private static void _parseParameters(CompilerState state)
        {
            for (var i = 0; i < state.Source.Parameters.Count; i++)
            {
                var id = state.Source.Parameters[i];
                var sym = state.Symbols[id];
                LocalBuilder local;

                //Determine whether local variables for parameters have already been created and create them if necessary
                switch (sym.Kind)
                {
                    case SymbolKind.Local:
                        local = sym.Local ?? state.Il.DeclareLocal(typeof (PValue));
                        break;
                    case SymbolKind.LocalRef:
                        if (sym.Local == null)
                        {
                            local = state.Il.DeclareLocal(typeof (PVariable));
                            state.Il.Emit(OpCodes.Newobj, NewPVariableCtor);
                            state.EmitStoreLocal(local);
                            //PVariable objects already contain PValue.Null and need not be initialized if no
                            //  argument has been passed.
                        }
                        else
                        {
                            local = sym.Local;
                        }
                        break;
                    default:
                        throw new PrexoniteException("Cannot create variable to represent symbol");
                }

                sym.Local = local;

                var hasArg = state.Il.DefineLabel();
                var end = state.Il.DefineLabel();

                if (sym.Kind == SymbolKind.Local) // var = idx < len ? args[idx] : null;
                {
                    //The closure below is only accessed once. The capture is therefore transparent.
                    // ReSharper disable AccessToModifiedClosure
                    state.EmitStorePValue
                        (
                            sym,
                            delegate
                                {
                                    //(idx < argc) ? args[idx] : null; 
                                    state.EmitLdcI4(i);
                                    state.EmitLoadLocal(state.ArgcLocal);
                                    state.Il.Emit(OpCodes.Blt_S, hasArg);
                                    state.EmitLoadNullAsPValue();
                                    state.Il.Emit(OpCodes.Br_S, end);
                                    state.Il.MarkLabel(hasArg);
                                    state.EmitLoadArg(CompilerState.ParamArgsIndex);
                                    state.EmitLdcI4(i);
                                    state.Il.Emit(OpCodes.Ldelem_Ref);
                                    state.Il.MarkLabel(end);
                                }
                        );
                    // ReSharper restore AccessToModifiedClosure
                }
                else // if(idx < len) var = args[idx];
                {
                    state.EmitLdcI4(i);
                    state.EmitLoadLocal(state.ArgcLocal);
                    state.Il.Emit(OpCodes.Bge_S, end);

                    //The following closure is only accessed once. The capture is therefore transparent.
                    // ReSharper disable AccessToModifiedClosure
                    state.EmitStorePValue
                        (
                            sym,
                            delegate
                                {
                                    state.EmitLoadArg(CompilerState.ParamArgsIndex);
                                    state.EmitLdcI4(i);
                                    state.Il.Emit(OpCodes.Ldelem_Ref);
                                });
                    // ReSharper restore AccessToModifiedClosure
                    state.Il.MarkLabel(end);
                }
            }
        }