Пример #1
0
 public bool DoExecute(ActionBase ac)      // execute if control state
 {
     return(execstate[execlevel] == ExecState.On || ac.Type >= ActionBase.ActionType.If);
 }
Пример #2
0
        // true is reported on an error, or we need to get the next action.

        public bool LevelUp(int up, ActionBase action)      // action may be null at end of program
        {
            while (up-- > 0)
            {
                if (execlevel == 0)
                {
                    ReportError("Nested program level error, tring to move up while on level 0");
                    return(true);
                }

                if (IsExecutingType(ActionBase.ActionType.Do))                // DO needs a while at level -1..
                {
                    if (action != null && action.Type == ActionBase.ActionType.While)
                    {
                        if (action.LevelUp == 1)                // only 1, otherwise its incorrectly nested
                        {
                            ActionWhile w = action as ActionWhile;
                            if (w.ExecuteEndDo(this))    // if this indicates (due to true) we need to fetch next instruction
                            {
                                return(true);
                            }
                            else
                            {
                                RemoveLevel();      // else, just remove level..
                            }
                        }
                        else
                        {
                            ReportError("While incorrectly nested under Do");
                            return(true);
                        }
                    }
                    else
                    {
                        ReportError("While missing after Do");
                        return(true);
                    }
                }
                else if (IsExecutingType(ActionBase.ActionType.Loop)) // active loop, need to consider if we need to go back
                {
                    // break may have cancelled this
                    if (PushPos >= 0 && ((ActionLoop)GetStep(PushPos)).ExecuteEndLoop(this))      // if true, it wants to move back, so go back and get next value.
                    {
                        return(true);
                    }
                    else
                    {
                        RemoveLevel();      // else, just remove level..
                    }
                }
                else if (IsExecutingType(ActionBase.ActionType.ForEach)) // active For, need to consider if we need to go back
                {
                    // break may have cancelled this
                    if (PushPos >= 0 && ((ActionForEach)GetStep(PushPos)).ExecuteEndFor(this))      // if true, it wants to move back, so go back and get next value.
                    {
                        return(true);
                    }
                    else
                    {
                        RemoveLevel();      // else, just remove level..
                    }
                }
                else
                {                                               // normal, just see if need to loop back
                    int stepback = PushPos;

                    RemoveLevel();

                    if (stepback >= 0)
                    {
                        Goto(stepback);
                        return(true);
                    }
                }
            }

            return(false);
        }
Пример #3
0
 public void Add(ActionBase ap)
 {
     programsteps.Add(ap);
 }
Пример #4
0
 public void Insert(int pos, ActionBase ap)
 {
     programsteps.Insert(pos, ap);
 }
Пример #5
0
        public string Read(System.IO.TextReader sr, ref int lineno)         // read from stream
        {
            string err = "";

            programsteps = new List <ActionBase>();
            Name         = "";

            List <int> indents     = new List <int>();
            List <int> level       = new List <int>();
            int        indentpos   = -1;
            int        structlevel = 0;

            string completeline;

            int initiallineno = lineno;

            while ((completeline = sr.ReadLine()) != null)
            {
                lineno++;

                completeline = completeline.Replace("\t", "    ");  // detab, to spaces, tabs are worth 4.
                BaseUtils.StringParser p = new BaseUtils.StringParser(completeline);

                if (!p.IsEOL)
                {
                    int    curindent = p.Position;
                    string cmd       = "";
                    if (p.IsStringMoveOn("//"))         // special, this is allowed to butt against text and still work
                    {
                        cmd = "//";
                    }
                    else
                    {
                        cmd = p.NextWord();
                    }

                    if (cmd.Equals("Else", StringComparison.InvariantCultureIgnoreCase))
                    {
                        //System.Diagnostics.Debug.WriteLine("Else " + cmd + " " + p.LineLeft);
                        if (p.IsStringMoveOn("If", StringComparison.InvariantCultureIgnoreCase))   // if Else followed by IF
                        {
                            cmd = "Else If";
                        }
                    }

                    string line = p.LineLeft;           // and the rest of the line..

                    int    commentpos = line.LastIndexOf("//");
                    string comment    = "";

                    if (cmd != "//" && commentpos >= 0 && !line.InQuotes(commentpos))       // if not // command, and we have one..
                    {
                        comment = line.Substring(commentpos + 2).Trim();
                        line    = line.Substring(0, commentpos).TrimEnd();
                        //System.Diagnostics.Debug.WriteLine("Line <" + line + "> <" + comment + ">");
                    }

                    if (cmd.Equals("PROGRAM", StringComparison.InvariantCultureIgnoreCase))
                    {
                        Name = line;
                    }
                    else if (cmd.Equals("END", StringComparison.InvariantCultureIgnoreCase) && line.Equals("PROGRAM", StringComparison.InvariantCultureIgnoreCase))
                    {
                        break;
                    }
                    else
                    {
                        ActionBase a = ActionBase.CreateAction(cmd, line, comment);
                        string     vmsg;

                        if (a == null)
                        {
                            err += lineno + " " + Name + " Unrecognised command " + cmd + Environment.NewLine;
                        }
                        else if ((vmsg = a.VerifyActionCorrect()) != null)
                        {
                            err += lineno + " " + Name + ":" + vmsg + Environment.NewLine + " " + completeline.Trim() + Environment.NewLine;
                        }
                        else
                        {
                            //System.Diagnostics.Debug.WriteLine(indentpos + ":" + structlevel + ": Cmd " + cmd + " : " + line);

                            if (indentpos == -1)
                            {
                                indentpos = curindent;
                            }
                            else if (curindent > indentpos)        // more indented, up one structure
                            {
                                structlevel++;
                                indentpos = curindent;
                            }
                            else if (curindent < indentpos)   // deindented
                            {
                                int tolevel = -1;
                                for (int i = indents.Count - 1; i >= 0; i--)            // search up and find the entry with the indent..
                                {
                                    if (indents[i] <= curindent)
                                    {
                                        tolevel = i;
                                        break;
                                    }
                                }

                                if (tolevel >= 0)       // if found, we have a statement to hook to..
                                {                       // while in DO loop, or Else/Elseif in IF
                                    if ((a.Type == ActionBase.ActionType.While && programsteps[tolevel].Type == ActionBase.ActionType.Do) ||
                                        ((a.Type == ActionBase.ActionType.Else || a.Type == ActionBase.ActionType.ElseIf) && programsteps[tolevel].Type == ActionBase.ActionType.If))
                                    {
                                        int reallevel = level[tolevel] + 1;     // else, while are dedented, but they really are on level+1
                                        a.LevelUp   = structlevel - reallevel;
                                        structlevel = reallevel;
                                        indentpos   = indents[tolevel] + 4;     // and our indent should continue 4 in, so we don't match against this when we do indent
                                    }
                                    else
                                    {
                                        a.LevelUp   = structlevel - level[tolevel];
                                        structlevel = level[tolevel];   // if found, we are at that.. except..
                                        indentpos   = indents[tolevel]; // and back to this level
                                    }
                                }
                            }

                            a.LineNumber = lineno;

                            //System.Diagnostics.Debug.WriteLine("    >>>> " + indentpos + ":" + structlevel);

                            indents.Add(indentpos);
                            level.Add(structlevel);
                            programsteps.Add(a);
                        }
                    }
                }
                else
                {
                    if (programsteps.Count > 0)
                    {
                        programsteps[programsteps.Count - 1].Whitespace = 1;
                    }
                }
            }

            if (programsteps.Count > 0)
            {
                programsteps[programsteps.Count - 1].Whitespace = 0;        // last cannot have whitespace..
            }
            progclass = Classify();
            return(err);
        }
Пример #6
0
        private void DoExecute()    // MAIN thread only..
        {
            executing = true;

            System.Diagnostics.Stopwatch timetaken = new System.Diagnostics.Stopwatch();
            timetaken.Start();

            while (true)
            {
                if (progcurrent != null)
                {
                    if (progcurrent.GetErrorList != null)       // any errors pending, handle
                    {
                        actioncontroller.LogLine("Error: " + progcurrent.GetErrorList + Environment.NewLine + StackTrace());
                        TerminateToCloseAtEnd();            // terminate up to a close at end entry, which would have started this stack
                    }
                    else if (progcurrent.IsProgramFinished) // if current program ran out, cancel it
                    {
                        // this catches a LOOP without a statement at the end..  or a DO without a WHILE at the end..
                        if (progcurrent.ExecLevel > 0 && progcurrent.LevelUp(progcurrent.ExecLevel, null)) // see if we have any pending LOOP (or a DO without a while) and continue..
                        {
                            continue;                                                                      // errors or movement causes it to go back.. errors will be picked up above
                        }
                        TerminateCurrent();
                    }
                }

                while (progcurrent == null && progqueue.Count > 0)    // if no program,but something in queue
                {
                    progcurrent = progqueue[0];
                    progqueue.RemoveAt(0);

                    if (progcurrent.variables != null)                         // if not null, its because its just been restarted after a call.. reset globals
                    {
                        progcurrent.Add(actioncontroller.Globals);             // in case they have been updated...
                        progcurrent.Add(progcurrent.ActionFile.FileVariables); // in case they have been updated...
                    }
                    else
                    {
                        progcurrent.PrepareToRun(
                            new Variables(progcurrent.inputvariables, actioncontroller.Globals, progcurrent.ActionFile.FileVariables),
                            new FunctionPersistentData(),
                            new Dictionary <string, ExtendedControls.ConfigurableForm>(), true);    // with new file handles and close at end..
                    }

                    if (progcurrent.IsProgramFinished)          // reject empty programs..
                    {
                        TerminateCurrent();
                        continue;       // and try again
                    }
                }

                if (progcurrent == null)        // Still nothing, game over
                {
                    break;
                }

                ActionBase ac = progcurrent.GetNextStep();      // get the step. move PC on.

                //    System.Diagnostics.Debug.WriteLine((Environment.TickCount % 10000).ToString("00000") + " " + timetaken.ElapsedMilliseconds + " @ " + progcurrent.Location + " Lv " + progcurrent.ExecLevel + " e " + (progcurrent.IsExecuteOn ? "1" : "0") + " up " + ac.LevelUp + " " + progcurrent.PushPos + " " + ac.Name);

                if (ac.LevelUp > 0 && progcurrent.LevelUp(ac.LevelUp, ac))         // level up..
                {
                    //System.Diagnostics.Debug.WriteLine((Environment.TickCount % 10000).ToString("00000") + " Abort Lv" + progcurrent.ExecLevel + " e " + (progcurrent.IsExecuteOn ? "1" : "0") + " up " + ac.LevelUp + ": " + progcurrent.StepNumber + " " + ac.Name + " " + ac.DisplayedUserData);
                    continue;
                }

                if (logtologline || logger != null)
                {
                    string t     = (Environment.TickCount % 10000).ToString("00000") + " ";
                    string index = string.Concat(Enumerable.Repeat(". ", progcurrent.ExecLevel));
                    string s     = progcurrent.GetLastStep().LineNumber.ToString() + (progcurrent.IsExecuteOn ? "+" : "-") + ":" + index + ac.Name + " " + ac.DisplayedUserData;
                    System.Diagnostics.Debug.WriteLine(t + s);
                    if (logtologline)
                    {
                        actioncontroller.LogLine(t + s);
                    }
                    if (logger != null)
                    {
                        logger.WriteLine(s);
                    }
                }

                if (progcurrent.DoExecute(ac))                 // execute is on..
                {
                    if (ac.Type == ActionBase.ActionType.Call) // Call needs to pass info back up thru to us, need a different call
                    {
                        ActionCall acall = ac as ActionCall;
                        string     prog;
                        Variables  paravars;
                        if (acall.ExecuteCallAction(progcurrent, out prog, out paravars)) // if execute ok
                        {
                            //System.Diagnostics.Debug.WriteLine("Call " + prog + " with " + paravars.ToString());

                            Tuple <ActionFile, ActionProgram> ap = actionfilelist.FindProgram(prog, progcurrent.ActionFile);          // find program using this name, prefer this action file first

                            if (ap != null)
                            {
                                Run(true, ap.Item1, ap.Item2, paravars, progcurrent.Functions.persistentdata, progcurrent.Dialogs, false);   // run now with these para vars
                            }
                            else
                            {
                                progcurrent.ReportError("Call cannot find " + prog);
                            }
                        }
                    }
                    else if (ac.Type == ActionBase.ActionType.Return)     // Return needs to pass info back up thru to us, need a different call
                    {
                        ActionReturn ar = ac as ActionReturn;
                        string       retstr;
                        if (ar.ExecuteActionReturn(progcurrent, out retstr))
                        {
                            TerminateCurrent();

                            // if a new program is queued, but not prepared, and this program returns to finish, make sure we don't
                            // screw up since the variables are not preparred yet - they will be above in PrepareToRun

                            if (progqueue.Count > 0 && progqueue[0].variables != null)         // pass return value if program is there AND its prepared
                            {
                                progqueue[0]["ReturnValue"] = retstr;
                            }

                            continue;       // back to top, next action from returned function.
                        }
                    }
                    else if (!ac.ExecuteAction(progcurrent)) // if execute says, stop, i'm waiting for something
                    {
                        return;                              // exit, with executing set true.  ResumeAfterPause will restart it.
                    }
                }

                if (AsyncMode && timetaken.ElapsedMilliseconds > 150)  // no more than ms per go to stop the main thread being blocked
                {
                    System.Diagnostics.Debug.WriteLine((Environment.TickCount % 10000).ToString("00000") + " *** SUSPEND Actions at " + timetaken.ElapsedMilliseconds);
                    restarttick.Start();
                    break;
                }
            }

            executing = false;
        }
Пример #7
0
        string RepositionGroups(bool calcminsize = true)
        {
            SuspendLayout();
            panelVScroll.SuspendLayout();

            string errlist = curprog.CalculateLevels();

            int panelwidth = Math.Max(panelVScroll.Width - panelVScroll.ScrollBarWidth, 10);
            int voff       = panelheightmargin;
            int actstep    = 0;

            toolTip1.RemoveAll();

            foreach (Group g in groups)
            {
                int        indentlevel = 0;
                int        whitespace  = 0;
                int        lineno      = 0;
                ActionBase act         = curprog.GetStep(actstep++);

                if (act != null)
                {
                    System.Diagnostics.Debug.Assert(Object.ReferenceEquals(g.checkit, act));
                    g.left.Enabled   = act.calcAllowLeft;
                    g.right.Enabled  = act.calcAllowRight;
                    indentlevel      = act.calcDisplayLevel;
                    whitespace       = act.Whitespace;
                    lineno           = act.LineNumber;
                    g.prog.Visible   = act.Type == ActionBase.ActionType.Call & EditProgram != null;
                    g.config.Visible = act.ConfigurationMenuInUse;
                }
                else
                {
                    g.left.Enabled   = g.right.Enabled = false;
                    g.prog.Visible   = false;
                    g.config.Visible = false;
                }

                g.panel.SuspendLayout();

                g.panel.Location    = new Point(panelleftmargin, voff + panelVScroll.ScrollOffset);
                g.panel.Size        = new Size(panelwidth, panelheight + ((whitespace > 0) ? (panelheight / 2) : 0));
                g.stepname.Location = new Point(g.right.Right + 8 + 8 * indentlevel, panelheightmargin);
                g.stepname.Size     = new Size(140 - Math.Max((indentlevel - 4) * 8, 0), controlsize);
                g.value.Location    = new Point(g.right.Right + 140 + 8 + 8 * 4 + 8, panelheightmargin * 2);  // 8 spacing, allow 8*4 to indent
                int valuewidth = panelwidth - 350;
                g.value.Size      = new Size(valuewidth, controlsize);
                g.config.Location = new Point(g.value.Right + 4, panelheightmargin);      // 8 spacing, allow 8*4 to indent
                g.up.Location     = new Point(g.config.Right + 4, panelheightmargin);
                g.prog.Location   = new Point(g.up.Right + 4, panelheightmargin);
                g.up.Visible      = groups.IndexOf(g) > 0;

                g.panel.ResumeLayout();

                string tt1 = "Step " + actstep;
                if (indentlevel > 0)
                {
                    tt1 += " Lv " + indentlevel;
                }
                if (lineno > 0)
                {
                    tt1 += " Ln " + lineno;
                }
                if (act != null)
                {
                    tt1 += " SL " + act.calcStructLevel + " LU" + act.LevelUp;
                }

                toolTip1.SetToolTip(g.stepname, tt1);
                toolTip1.SetToolTip(g.stepname.GetInternalSystemControl, tt1);
                if (act != null && act.Comment.Length > 0)
                {
                    toolTip1.SetToolTip(g.value, "Comment: " + act.Comment);
                }

                //DEBUG Keep this useful for debugging structure levels
                //                if (g.programstep != null)
                //                  g.value.Enabled = false; g.value.Text = structlevel.ToString() + " ^ " + g.levelup + " UD: " + g.programstep.DisplayedUserData;g.value.Enabled = true;

                voff += g.panel.Height;
            }

            buttonMore.Location = new Point(panelleftmargin, voff + panelVScroll.ScrollOffset);
            buttonMore.Size     = new Size(controlsize, controlsize);

            Rectangle screenRectangle = RectangleToScreen(this.ClientRectangle);
            int       titleHeight     = screenRectangle.Top - this.Top;

            // Beware Visible - it does not report back the set state, only the visible state.. hence use Enabled.
            voff += buttonMore.Height + titleHeight + panelName.Height + ((panelTop.Enabled) ? (panelTop.Height + statusStripCustom.Height) : 8) + 16 + panelOK.Height;

            if (calcminsize)
            {
                this.MinimumSize = new Size(600, voff);
                this.MaximumSize = new Size(Screen.FromControl(this).WorkingArea.Width - 100, Screen.FromControl(this).WorkingArea.Height - 100);

                if (Bottom > Screen.FromControl(this).WorkingArea.Height)
                {
                    Top = Screen.FromControl(this).WorkingArea.Height - Height - 50;
                }
            }

            panelVScroll.ResumeLayout();
            ResumeLayout();

            return(errlist);
        }
Пример #8
0
        Group CreateStep(int insertpos, ActionBase step = null)
        {
            SuspendLayout();
            panelVScroll.SuspendLayout();

            Group g = new Group();

            g.checkit = step;

            g.panel = new Panel();
            g.panel.SuspendLayout();

            g.panel.MouseUp         += panelVScroll_MouseUp;
            g.panel.MouseDown       += panelVScroll_MouseDown;
            g.panel.MouseMove       += panelVScroll_MouseMove;
            g.panel.ContextMenuStrip = contextMenuStrip1;

            g.left          = new ExtendedControls.ButtonExt();
            g.left.Location = new Point(0, panelheightmargin);      // 8 spacing, allow 8*4 to indent
            g.left.Size     = new Size(controlsize, controlsize);
            g.left.Text     = "<";
            g.left.Click   += Left_Clicked;
            g.panel.Controls.Add(g.left);

            g.right          = new ExtendedControls.ButtonExt();
            g.right.Location = new Point(g.left.Right + 2, panelheightmargin);      // 8 spacing, allow 8*4 to indent
            g.right.Size     = new Size(controlsize, controlsize);
            g.right.Text     = ">";
            g.right.Click   += Right_Clicked;
            g.panel.Controls.Add(g.right);

            g.stepname = new ExtendedControls.ComboBoxCustom();
            g.stepname.Items.AddRange(ActionBase.GetActionNameList());
            g.stepname.DropDownHeight = 400;
            if (step != null)
            {
                g.stepname.Text = step.Name;
            }
            g.stepname.SelectedIndexChanged += Stepname_SelectedIndexChanged;
            g.panel.Controls.Add(g.stepname);

            g.value = new ExtendedControls.TextBoxBorder();
            SetValue(g.value, step);
            g.value.TextChanged += Value_TextChanged;
            g.value.Click       += Value_Click;
            g.panel.Controls.Add(g.value);         // must be next

            g.config        = new ExtendedControls.ButtonExt();
            g.config.Text   = "C";
            g.config.Size   = new Size(controlsize, controlsize);
            g.config.Click += ActionConfig_Clicked;
            g.panel.Controls.Add(g.config);         // must be next

            g.up        = new ExtendedControls.ButtonExt();
            g.up.Size   = new Size(controlsize, controlsize);
            g.up.Text   = "^";
            g.up.Click += Up_Clicked;
            g.panel.Controls.Add(g.up);

            g.prog        = new ExtendedControls.ButtonExt();
            g.prog.Size   = new Size(controlsize, controlsize);
            g.prog.Text   = ">";
            g.prog.Click += Prog_Clicked;
            g.panel.Controls.Add(g.prog);

            g.config.Tag = g.stepname.Tag = g.up.Tag = g.value.Tag = g.left.Tag = g.right.Tag = g.prog.Tag = g;

            ExtendedControls.ThemeableFormsInstance.Instance.ApplyToControls(g.panel, SystemFonts.DefaultFont);

            panelVScroll.Controls.Add(g.panel);

            if (insertpos == -1)
            {
                groups.Add(g);
            }
            else
            {
                groups.Insert(insertpos, g);
            }

            g.panel.ResumeLayout();

            panelVScroll.ResumeLayout();
            ResumeLayout();
            return(g);
        }
        Group CreateStep(int insertpos, ActionBase step = null)
        {
            SuspendLayout();
            panelVScroll.SuspendLayout();

            Group g = new Group();

            // layout sizes as if its in 12 point, then its scaled.

            g.checkit = step;

            g.panel = new Panel();
            g.panel.SuspendLayout();

            g.panel.MouseUp         += panelVScroll_MouseUp;
            g.panel.MouseDown       += panelVScroll_MouseDown;
            g.panel.MouseMove       += panelVScroll_MouseMove;
            g.panel.ContextMenuStrip = contextMenuStrip1;

            int controlsize = 22; // for a 12 point layout..

            g.left          = new ExtendedControls.ExtButton();
            g.left.Location = new Point(0, panelheightmargin);
            g.left.Size     = new Size(controlsize, controlsize);
            g.left.Text     = "<";
            g.left.Click   += Left_Clicked;
            g.panel.Controls.Add(g.left);

            g.right          = new ExtendedControls.ExtButton();
            g.right.Location = new Point(g.left.Right + 2, panelheightmargin);
            g.right.Size     = new Size(controlsize, controlsize);
            g.right.Text     = ">";
            g.right.Click   += Right_Clicked;
            g.panel.Controls.Add(g.right);

            g.stepname      = new ExtendedControls.ExtComboBox();
            g.stepname.Size = new Size(10, controlsize);        // width set by positioning
            g.stepname.Items.AddRange(ActionBase.GetActionNameList());
            if (step != null)
            {
                g.stepname.Text = step.Name;
            }
            g.stepname.SelectedIndexChanged += Stepname_SelectedIndexChanged;
            g.panel.Controls.Add(g.stepname);

            g.value          = new ExtendedControls.ExtTextBox();
            g.value.Location = new Point(200, panelheightmargin); // fixed ref point in 12 point space
            g.value.Size     = new Size(10, controlsize);         // width set by positioning
            SetValue(g.value, step);
            g.value.TextChanged += Value_TextChanged;
            g.value.Click       += Value_Click;
            g.panel.Controls.Add(g.value);         // must be next

            g.config        = new ExtendedControls.ExtButton();
            g.config.Text   = "C";
            g.config.Size   = new Size(controlsize, controlsize);
            g.config.Click += ActionConfig_Clicked;
            g.panel.Controls.Add(g.config);         // must be next

            g.up        = new ExtendedControls.ExtButton();
            g.up.Size   = new Size(controlsize, controlsize);
            g.up.Text   = "^";
            g.up.Click += Up_Clicked;
            g.panel.Controls.Add(g.up);

            g.prog        = new ExtendedControls.ExtButton();
            g.prog.Size   = new Size(controlsize, controlsize);
            g.prog.Text   = ">";
            g.prog.Click += Prog_Clicked;
            g.panel.Controls.Add(g.prog);

            g.config.Tag = g.stepname.Tag = g.up.Tag = g.value.Tag = g.left.Tag = g.right.Tag = g.prog.Tag = g;

            ExtendedControls.Theme.Current.ApplyDialog(g.panel);
            g.panel.Scale(this.CurrentAutoScaleFactor());

            panelVScroll.Controls.Add(g.panel);

            if (insertpos == -1)
            {
                groups.Add(g);
            }
            else
            {
                groups.Insert(insertpos, g);
            }

            g.panel.ResumeLayout();

            panelVScroll.ResumeLayout();
            ResumeLayout();
            return(g);
        }