private void WriteFunction(string name, FunctionAst fnc, List<string> vars)
 {
     file.WriteLine();
     file.WriteLine("function {0}()", name);
     bool writeLE = WriteLinearEquations(fnc.Node, vars, "");
     WriteFunctionBody(fnc.Body, vars, "", writeLE);
 }
 public bool CheckAST(ProgramAst program)
 {
     foreach (string fncName in program.OrigFncs.Keys)
     {
         FunctionAst fnc = program.OrigFncs[fncName];
         BaseAst     err = CheckFunctionAST(program, fnc);
         if ((err.Token != TokenTypes.End) && (err.IsError))
         {
             Console.WriteLine("Error: '{0}'", err.ErrorMessage);
             return(false);
         }
     }
     return(true);
 }
        private BaseAst GetFunctionAST(FunctionAst fnc)
        {
            if (fnc == null)
            {
                return(BaseAst.GetErrorAstNode("Chybne volana funkce 'GetFunctionNode(FunctionAst fnc)', parametr 'fnc' je null"));
            }

            ReadNextAst();
            if (actualNode.Token != TokenTypes.Identifier)
            {
                return(BaseAst.GetErrorAstNode(string.Format("Je ocekavan identifikator funkce, radek {0}, sloupec {1}", actualNode.TokenStartLine, actualNode.TokenStartColumn)));
            }
            if (program.OrigFncs.Keys.Contains(actualNode.TokenText))
            {
                return(BaseAst.GetErrorAstNode(string.Format("Funkce '{0}' j*z byla deklarovana, radek {1}, sloupec {2}", actualNode.TokenText, actualNode.TokenStartLine, actualNode.TokenStartColumn)));
            }

            program.OrigFncs.Add(actualNode.TokenText, fnc);

            ReadNextAst();
            if (actualNode.Token != TokenTypes.ParenthesisLeft)
            {
                return(BaseAst.GetErrorAstNode(string.Format("Je ocekavana leva zavorka '(', radek {0}, sloupec {1}", actualNode.TokenStartLine, actualNode.TokenStartColumn)));
            }

            ReadNextAst();
            if (actualNode.Token != TokenTypes.ParenthesisRight)
            {
                return(BaseAst.GetErrorAstNode(string.Format("Je ocekavana prava zavorka ')', radek {0}, sloupec {1}", actualNode.TokenStartLine, actualNode.TokenStartColumn)));
            }

            ReadNextAst();
            if ((actualNode.Token != TokenTypes.BraceLeft) && !(actualNode is BlockAst))
            {
                return(BaseAst.GetErrorAstNode(string.Format("Je ocekavana leva slozena zavorka '{{', radek {0}, sloupec {1}", actualNode.TokenStartLine, actualNode.TokenStartColumn)));
            }

            BaseAst node = GetFncBodyAST(actualNode as BlockAst);

            if (node.IsError)
            {
                return(node);
            }
            fnc.Body = node as BlockAst;

            return(fnc);
        }
        public bool ConvertToIfGoto(ProgramAst program)
        {
            if (isPrint)
            {
                PrintVarsDecl(program);
            }

            foreach (string fncName in program.OrigFncs.Keys)
            {
                FunctionAst fnc = program.OrigFncs[fncName];
                FunctionAst cf  = ConvertTo <FunctionAst>(fnc, AstNodeTypes.Function);
                cf.Body = ConvertFncBodyAST(fnc.Body);

                if (isPrint)
                {
                    PrintSAFncDecl(fncName, cf.Body);
                }

                program.ConvFncs.Add(fncName, cf);
            }
            return(true);
        }
        private BaseAst CheckFunctionAST(ProgramAst program, FunctionAst fnc)
        {
            BaseAst err = CheckFunctionCallsInBlockAST(program, fnc.Body);

            return(err);
        }
        private bool CreateFunctionGraphs(ProgramAst program)
        {
            foreach (string fncName in program.ConvFncs.Keys)
            {
                FunctionAst fnc = program.ConvFncs[fncName] as FunctionAst;
                if (fnc != null)
                {
                    if ((fnc.Body != null) && (fnc.Body.Statements != null) && (fnc.Body.Statements.Count > 0))
                    {
                        bool isAnyCmd = false;
                        foreach (BaseAst st in fnc.Body.Statements)
                        {
                            if ((st is OperatorAst) || (st is ConditionAst) || (st.AstType == AstNodeTypes.FunctionCall) || (st.AstType == AstNodeTypes.Return))
                            {
                                isAnyCmd = true;
                                break;
                            }
                        }
                        if (isAnyCmd)
                        {
                            Dictionary <string, IaNode> lbls = new Dictionary <string, IaNode>();
                            List <Tuple <string, IaNode, string, int> > gts = new List <Tuple <string, IaNode, string, int> >();

                            IaNode node = new IaNode {
                                FncName = fncName, Name = fncName + "_fnc_begin"
                            };
                            program.OrigFncs[fncName].Node = node;
                            program.Graph.Add(fncName, node);
                            int i = 0;
                            while (i < fnc.Body.Statements.Count)
                            {
                                BaseAst st = fnc.Body.Statements[i];
                                if (st is OperatorAst)
                                {
                                    IaNode next = new IaNode {
                                        FncName = fncName, Name = fncName + "_after_expr_line#" + st.TokenStartLine
                                    };
                                    st.Node   = next;
                                    node.Next = new IaEdge {
                                        Name = fncName + "_expr_line#" + st.TokenStartLine, Ast = st, From = node, To = next
                                    };
                                    node = next;
                                    i++;
                                    continue;
                                }
                                if (st.AstType == AstNodeTypes.FunctionCall)
                                {
                                    IaNode next = new IaNode {
                                        FncName = fncName, Name = fncName + "_after_fnccall_line#" + st.TokenStartLine
                                    };
                                    st.Node   = next;
                                    node.Next = new IaEdge {
                                        Name = fncName + "_fnccall_line#" + st.TokenStartLine, Ast = st, From = node, To = next
                                    };
                                    node = next;
                                    i++;
                                    continue;
                                }
                                if (st is ConditionAst)
                                {
                                    IaNode next = new IaNode {
                                        FncName = fncName, Name = fncName + "_after_condition_line#" + st.TokenStartLine
                                    };
                                    st.Node   = next;
                                    node.Next = new IaEdge {
                                        Name = fncName + "_condition_line#" + st.TokenStartLine, Ast = st, From = node, To = next
                                    };
                                    node = next;
                                    i++;

                                    BaseAst gt = fnc.Body.Statements[i];
                                    node.ReverseAst = gt;
                                    gts.Add(new Tuple <string, IaNode, string, int>("IsTrue", node, (gt as GotoAst).Label, st.TokenStartLine));
                                    next = new IaNode {
                                        FncName = fncName, Name = fncName + "_condition_false_line#" + st.TokenStartLine
                                    };
                                    node.IsFalse = new IaEdge {
                                        Name = fncName + "_condition_false_line#" + st.TokenStartLine, From = node, To = next
                                    };
                                    node = next;
                                    i++;
                                    continue;
                                }
                                if (st.AstType == AstNodeTypes.Label)
                                {
                                    node.Name = fncName + "_label_" + st.TokenText;
                                    lbls.Add(st.TokenText, node);
                                    i++;
                                    continue;
                                }
                                if (st is GotoAst)
                                {
                                    node.ReverseAst = st;
                                    gts.Add(new Tuple <string, IaNode, string, int>("Next", node, (st as GotoAst).Label, st.TokenStartLine));
                                    node = new IaNode {
                                        FncName = fncName, Name = fncName + "_after_goto_line#" + (st as GotoAst).Label
                                    };                                                                                                     // po goto musi byt novy node (nova vetev)
                                    i++;
                                    continue;
                                }
                                if (st.AstType == AstNodeTypes.Return)
                                {
                                    node.ReverseAst = st;
                                    gts.Add(new Tuple <string, IaNode, string, int>("End", node, "$End$", st.TokenStartLine));
                                    node = new IaNode {
                                        FncName = fncName, Name = fncName + "_after_return_line#" + st.TokenStartLine
                                    };                                                                                                   // aktualni node je konec funkce, novy node pro pokracovani, jinak se zahodi
                                    i++;
                                    continue;
                                }
                            }

                            program.LastNode.Add(fncName, node);
                            lbls.Add("$End$", node);

                            foreach (Tuple <string, IaNode, string, int> gt in gts)
                            {
                                IaNode to = lbls[gt.Item3];
                                if (to == null)
                                {
                                    Console.WriteLine("Neznamy label {0} pri vytvareni grafu.", gt.Item3);
                                    return(false);
                                }
                                if (gt.Item1 == "Next")
                                {
                                    gt.Item2.Next = new IaEdge {
                                        Name = fncName + "_goto_line#" + gt.Item4, From = gt.Item2, To = to
                                    }
                                }
                                ;
                                else if (gt.Item1 == "IsTrue")
                                {
                                    gt.Item2.IsTrue = new IaEdge {
                                        Name = fncName + "_condition_true_line#" + gt.Item4, From = gt.Item2, To = to
                                    }
                                }
                                ;
                                else if (gt.Item1 == "End")
                                {
                                    gt.Item2.Next = new IaEdge {
                                        Name = fncName + "_return#" + gt.Item4, From = gt.Item2, To = to
                                    }
                                }
                                ;

                                if (gt.Item2.ReverseAst != null)
                                {
                                    gt.Item2.ReverseAst.Node = to;
                                }
                            }
                        }
                    }
                }
            }
            return(true);
        }