예제 #1
0
        /// <summary>
        /// Parse a box
        /// </summary>
        public SyntaxBox ParseBox()
        {
            SyntaxBox box = ParseBoxPrototype();

            // Skip box if we don't find 'is' after the prototype
            if (mTokenName != "is")
            {
                Reject("Expecting 'is' after box prototype", REJECT_BOX);
                return(box);
            }
            Accept("is");

            box.Statements = ParseStatements(box, true);

            // Parse end of box statement
            if (mTokenName == "end")
            {
                mToken.InfoString = box.NameDecl.ToString();
                Connect(box.NameDecl.TypeName, mToken);
                Accept();
            }
            else
            {
                Reject("Expecting 'end' - end of box body", REJECT_BOX);
            }

            return(box);
        }
예제 #2
0
        /// <summary>
        /// Recompile or display hover message when necessary
        /// </summary>
        private void timer1_Tick(object sender, EventArgs e)
        {
            // Recompile 250 milliseconds after the user stops typing
            if (mLastEditorChangedTime != new DateTime() &&
                (DateTime.Now - mLastEditorChangedTime).TotalMilliseconds > 250)
            {
                try
                {
                    // Reset the lexer, re-parse, and compile
                    mLastEditorChangedTime = new DateTime();
                    Parser    parser  = new Parser(editor1.Lexer);
                    DateTime  t1      = DateTime.Now;
                    SyntaxBox program = parser.Parse();
                    DateTime  t2      = DateTime.Now;
                    CodeBox   code    = new CodeBox(null, program);
                    DateTime  t3      = DateTime.Now;
                    editor1.Invalidate();

                    // Debug times
                    TimeSpan parseTime = t2 - t1;
                    TimeSpan genTime   = t3 - t2;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(this, "Error compiling: " + ex.Message, App.Name);
                }
            }

            // Find out if all simulation form windows have closed
            for (int i = 0; i < mSimulationForms.Count; i++)
            {
                if (mSimulationForms[i].IsDisposed)
                {
                    mSimulationForms.RemoveAt(i);
                }
            }

            // Make the editor read-only if there is a simulation form open
            editor1.ReadOnly = mSimulationForms.Count != 0;

            // Display the hover message (after no mouse movement for 150 milliseconds)
            if (mHoverToken != null &&
                mHoverToken.Type != eTokenType.Comment &&
                mHoverToken.InfoString != "" &&
                (DateTime.Now - mLastMouseMoveTime).TotalMilliseconds > 150 &&
                !mHoverMessageForm.Visible)
            {
                // Set form size, location, and text
                mHoverMessageForm.Message.Text = mHoverToken.InfoString;
                Size s = mHoverMessageForm.Message.Size;
                mHoverMessageForm.ClientSize = new Size(s.Width + 8, s.Height + 8);
                Point p = editor1.PointToScreen(editor1.LocationToken(mHoverToken.Location));
                p.Y -= s.Height + 32;
                mHoverMessageForm.Location = p;

                // Display the form
                mHoverMessageForm.Show(this);
                this.Focus();
            }
        }
예제 #3
0
        /// <summary>
        /// Parse multiple statements until 'box', 'end', 'else', or 'elif'
        /// is found.  Returns the statements that are parsed.
        /// Adds declarations to the box locals.  Never returns NULL.
        /// </summary>
        public SyntaxExpr ParseStatements(SyntaxBox box, bool topLevel)
        {
            // Create an "{" expression, which (for now means "statements")
            SyntaxExpr statements = new SyntaxExpr(mInternalTokenStatement);

            // While not end of file and not end of box and not new box
            while (mTokenName != "" &&
                   mTokenName != "box" &&
                   mTokenName != "end" &&
                   mTokenName != "else" &&
                   mTokenName != "elif")
            {
                // Skip blank statements
                while (mTokenName == ";")
                {
                    Accept();
                }

                // Parse the statement
                SyntaxExpr statement = ParseStatement(box, topLevel);
                if (statement != null)
                {
                    statements.AddParam(statement);
                }

                while (mTokenName == ";")
                {
                    Accept();
                }
            }
            return(statements);
        }
예제 #4
0
        /// <summary>
        /// Parse an if statement (expects 'if' at the input)
        /// </summary>
        SyntaxExpr ParseIfStatement(SyntaxBox box)
        {
            // Parse "if" token, condition, and statements
            Token ifToken = mToken;

            Accept("if");
            SyntaxExpr ifExpr = new SyntaxExpr(ifToken);

            ifExpr.AddParam(ParseIfCond());
            ifExpr.AddParam(ParseStatements(box, false));

            // Parse "elif" statements
            SyntaxExpr elseExpr = ifExpr;

            while (mTokenName == "elif")
            {
                // Parse "elif" token, condition, and statements
                // NOTE: "elif" token is converted to "if"
                Connect(ifToken, mToken);
                Accept("elif");
                SyntaxExpr newIf = new SyntaxExpr(ifToken);
                newIf.AddParam(ParseIfCond());
                newIf.AddParam(ParseStatements(box, false));

                // Convert the new "elif" to "else if"
                elseExpr.AddParam(newIf);
                elseExpr = newIf;
            }

            // Parse the "else" clause (if it exists)
            if (mTokenName == "else")
            {
                Connect(ifToken, mToken);
                Accept("else");
                elseExpr.AddParam(ParseStatements(box, false));
            }

            // Parse end of box statement
            if (mTokenName == "end")
            {
                mToken.InfoString = "end if";
                Connect(ifToken, mToken);
                Accept();
            }
            else
            {
                Reject("Expecting 'end' - end of if statement body", REJECT_BOX);
            }

            // Parse "else" part
            return(ifExpr);
        }
예제 #5
0
        /// <summary>
        /// Show simulation form
        /// </summary>
        private void menuSimulateNew_Click(object sender, EventArgs e)
        {
            // Compile everything
            Parser    parser  = new Parser(editor1.Lexer);
            SyntaxBox program = parser.Parse();
            CodeBox   code    = new CodeBox(null, program);

            editor1.Invalidate();

            // Get the code boxes
            List <CodeBox> boxes = new List <CodeBox>();

            foreach (var box in code.Boxes)
            {
                if (box.Decl.TypeName == "box" && box.CodeBoxValue != null)
                {
                    boxes.Add(box.CodeBoxValue);
                }
            }

            if (boxes.Count == 0)
            {
                MessageBox.Show(this, "No boxes were defined", App.Name);
                return;
            }

            // Show the simulation form
            FormSetupSimulation setupForm = new FormSetupSimulation();

            setupForm.Boxes = boxes;
            setupForm.ShowDialog(this);

            // Show a form if requested by setup form
            if (setupForm.FormResult != null)
            {
                setupForm.FormResult.Show();
            }

            // Go to read-only mode if running a simulation
            if (setupForm.FormResult as FormSimulate != null)
            {
                mSimulationForms.Add(setupForm.FormResult as FormSimulate);
                editor1.ReadOnly = true;
            }
        }
예제 #6
0
        /// <summary>
        /// Parse an entire file.
        /// </summary>
        public SyntaxBox Parse()
        {
            // Top level scope
            SyntaxBox program = new SyntaxBox();

            program.NameDecl.TypeName     = new Token("SCOPE:0", 0, 0);
            program.NameDecl.VariableName = new Token("SCOPE:0", 0, 0);

            while (mTokenName != "")
            {
                // Parse a box
                if (mTokenName == "box")
                {
                    mParseError = false;
                    SyntaxBox box = ParseBox();
                    box.Parent = program;
                    program.Boxes.Add(box);
                    box.Error = mParseError;
                }
                else if (mTokenName == "const")
                {
                    program.Constants.Add(ParseConstStatement());

                    // Ensure we have a valid statement
                    if (mTokenName != ";")
                    {
                        Reject("Expecting end of statement separator ';'", REJECT_LINE);
                    }
                    while (mTokenName == ";")
                    {
                        Accept();
                    }
                }
                else
                {
                    Reject("Invalid token \'" + mTokenName
                           + "\' was found when expecting the keyword 'box' or 'const'",
                           REJECT_BOX);
                }
            }
            return(program);
        }
예제 #7
0
        /// <summary>
        /// Parse a box prototype, returns new box with parameters filled in.
        /// </summary>
        public SyntaxBox ParseBoxPrototype()
        {
            if (mTokenName != "box")
            {
                throw new Exception("ParseBoxPrototype: expecting 'box'");
            }

            // Read box declaration name
            SyntaxBox box = new SyntaxBox();

            box.NameDecl = ParseBoxDeclarationName(REJECT_BOX_PROTOTYPE);

            if (mTokenName == "(")
            {
                box.Params = ParseBoxDeclarationParameters();
            }
            else
            {
                Reject("Expecting \'(\' or \'[\' in box declaration", REJECT_BOX_PROTOTYPE);
            }

            return(box);
        }
예제 #8
0
        /// <summary>
        /// Parse a single statement, which could be an expression.
        /// Adds declaratins to the box locals.
        /// NOTE: This can return NULL if there are no statements.
        /// </summary>
        public SyntaxExpr ParseStatement(SyntaxBox box, bool topLevel)
        {
            while (mTokenName == "else" || mTokenName == "elif")
            {
                Reject("This '" + mTokenName + "' is not inside an 'if' statement");
                Accept();
            }

            // Check statement keywords first
            bool       needsSemicolon = true;
            SyntaxExpr result         = null;

            if (mTokenName == "bit")
            {
                // Parse bit statement (optionally followed by assignment)
                if (!topLevel)
                {
                    Reject("'bit' declarations are only allowed at the top level");
                }
                result = ParseBitStatement(REJECT_LINE);
            }
            else if (mTokenName == "const")
            {
                // Parse const declaration
                if (!topLevel)
                {
                    Reject("'const' declarations are only allowed at the top level");
                }
                result = ParseConstStatement();
            }
            else if (mTokenName == "if")
            {
                // Parse if statement
                needsSemicolon = false;
                result         = ParseIfStatement(box);
            }
            else
            {
                // Parse an expression
                result = ParseExpr();

                // Assignment statement?
                if (mTokenName == "=")
                {
                    // Generate an assignment statement
                    result = new SyntaxExpr(Accept(), result, ParseExpr());
                }
            }

            // Ensure we have a valid statement
            if (needsSemicolon && mTokenName != ";")
            {
                Reject("Expecting end of statement separator ';'", REJECT_LINE);
            }
            if (mTokenName == ";")
            {
                Accept();
            }

            return(result);
        }