void InOrReadParam(out Expression exp)
 {
     exp = null;
     if (la.kind == 1) {
     Get();
     exp = new PLRString(t.val); SetPos(exp, t);
     } else if (la.kind == 3) {
     Get();
     exp = new VariableBinding(t.val.Replace("!", "")); SetPos(exp, t);
     } else if (StartOf(2)) {
     Expression(out exp);
     } else SynErr(33);
 }
        public override void Compile(CompileContext context)
        {
            Type        procType = typeof(ProcessBase);
            ILGenerator il       = context.ILGenerator;

            EmitDebug("Preparing to sync now...", context);
            LocalBuilder syncObject = il.DeclareLocal(typeof(KLAIMAction));

            il.Emit(OpCodes.Ldarg_0); //this
            il.Emit(OpCodes.Ldarg_0); //this
            il.Emit(OpCodes.Ldstr, this.ToString());
            il.Emit(OpCodes.Newobj, typeof(KLAIMAction).GetConstructors()[0]);
            il.Emit(OpCodes.Call, SyncMethod);

            //..and here we actually do something...
            context.MarkSequencePoint(this.LexicalInfo);

            LocalBuilder loc   = il.DeclareLocal(typeof(Locality));
            LocalBuilder arr   = il.DeclareLocal(typeof(object[]));
            LocalBuilder tuple = il.DeclareLocal(typeof(Tuple));

            if (this.At is Variable && ((Variable)this.At).Name == "self")
            {
                il.Emit(OpCodes.Ldstr, this.Locality);
            }
            else
            {
                this.At.Compile(context);
            }
            il.Emit(OpCodes.Call, typeof(Net).GetMethod("GetLocality"));
            il.Emit(OpCodes.Stloc, loc);

            il.Emit(OpCodes.Ldc_I4, this.ChildNodes.Count - 1);
            il.Emit(OpCodes.Newarr, typeof(object));
            il.Emit(OpCodes.Stloc, arr);


            for (int i = 1; i < this.ChildNodes.Count; i++)
            {
                Node node = this.ChildNodes[i];
                il.Emit(OpCodes.Ldloc, arr);
                il.Emit(OpCodes.Ldc_I4, i - 1);
                node.Compile(context);
                if (node is ArithmeticExpression)
                {
                    il.Emit(OpCodes.Box, typeof(int));
                }
                il.Emit(OpCodes.Stelem_Ref);
            }

            il.Emit(OpCodes.Ldloc, loc);
            il.Emit(OpCodes.Ldloc, arr);
            il.Emit(OpCodes.Call, typeof(Locality).GetMethod(_methodName));

            //We might be blocked at this location for a very long time...

            il.Emit(OpCodes.Stloc, tuple);
            //Now lets bind our variables... if they are used in the process
            for (int i = 1; i < this.ChildNodes.Count; i++)
            {
                if (_children[i] is VariableBinding)
                {
                    VariableBinding var = (VariableBinding)_children[i];
                    if (context.Options.Optimize && !var.IsUsed)
                    {
                        continue;
                    }

                    //Get the value to assign to it...
                    il.Emit(OpCodes.Ldloc, tuple);
                    il.Emit(OpCodes.Ldc_I4, i - 1);
                    il.Emit(OpCodes.Call, typeof(Tuple).GetMethod("GetValueAt"));

                    //...and assign it
                    LocalBuilder bindLoc = context.Type.GetLocal(var.Name);
                    if (bindLoc == null)
                    {
                        bindLoc = il.DeclareLocal(typeof(object));
                        context.Type.Locals.Add(var.Name, bindLoc);
                        if (context.Options.Debug)
                        {
                            bindLoc.SetLocalSymInfo(var.Name);
                        }
                    }
                    il.Emit(OpCodes.Stloc, bindLoc);
                }
            }

            //Ok, we got past the input action. If our parent is not null then we are a replicated
            //process and should notify our parent that we have really started.
            Label noParent = il.DefineLabel();

            il.Emit(OpCodes.Ldarg_0); //Load the "this" pointer
            il.Emit(OpCodes.Call, typeof(ProcessBase).GetMethod("get_Parent"));
            il.Emit(OpCodes.Brfalse, noParent);
            {
                il.Emit(OpCodes.Ldarg_0);                                           //Load the "this" pointer
                il.Emit(OpCodes.Call, typeof(ProcessBase).GetMethod("get_Parent"));
                il.Emit(OpCodes.Call, typeof(ProcessBase).GetMethod("get_Thread")); //find our parent thread
                il.Emit(OpCodes.Call, typeof(Thread).GetMethod("Resume"));

                //Now we've woken up our parent. Set the Parent property to null, so it doesn't get passed
                //on to the rest of this process, KLAIM has no need for the Parent and passing it on might
                //lead to later in actions spawning extra instances of the replicated process.
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldnull);
                il.Emit(OpCodes.Call, typeof(ProcessBase).GetMethod("set_Parent"));
            }
            il.MarkLabel(noParent);

            //Now lets print out the net for fun...

            il.EmitWriteLine("************** CURRENT TUPLES **************");
            il.Emit(OpCodes.Call, typeof(Net).GetMethod("Display"));
            il.Emit(OpCodes.Call, typeof(System.Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
            //TODO: Notify possible replicated process
        }