コード例 #1
0
        override public (string, object) Evaluate(SymbolTable symbolTable)
        {
            //get func node
            FuncDec node = (FuncDec)symbolTable.GetFromMain((string)this.value).Item2;

            //create the new symbol table for the new escope
            SymbolTable inferiorST = new SymbolTable();

            inferiorST.parent = symbolTable;

            if (node.type != "none")
            {
                //create a var with the same name as the func to return
                inferiorST.Set((string)node.value, null, node.type);
            }


            //get number of arguments
            if (node.varList.Count != varList.Count)
            {
                throw new SystemException($"Function {node.value.ToString()} receives {node.varList.Count} arguments, but {varList.Count} where given. [Line: {Parser.CurrentLine}]");
            }
            Node[] valueNodeList = new Node[varList.Count];

            int counter = 0;

            foreach (Node n in varList)
            {
                valueNodeList[counter++] = n;
            }

            //dec vars and set values
            counter = 0;
            foreach (BinOp dec in node.varList)
            {
                dec.Evaluate(inferiorST);

                (string, object)retVal = valueNodeList[counter++].Evaluate(symbolTable);

                inferiorST.Set((string)dec.children[0].value, retVal.Item2, retVal.Item1);
            }

            //call function
            node.children[0].Evaluate(inferiorST);

            if (node.type == "none")
            {
                return("none", null);
            }

            //return the value by the name
            return(inferiorST.Get(node.value.ToString()));
        }
コード例 #2
0
        public static Node ParseFunction()
        {
            FuncDec root = new FuncDec();

            bool sub = tokens.actual.type == "SUB";

            if (sub)
            {
                Expect("SUB", true);
                root.type = "none";
            }
            else
            {
                Expect("FUNCTION", true);;
            }

            Expect("IDENTIFIER", false);
            root.value = tokens.actual.value;
            tokens.SelectNext();

            Expect("POPEN", true);
            if (tokens.actual.type != "PCLOSE")
            {
                do
                {
                    if (tokens.actual.type == "COMMA")
                    {
                        tokens.SelectNext();
                    }
                    Expect("IDENTIFIER", false);
                    BinOp dim = new BinOp();
                    dim.value             = "vardec";
                    dim.children[0]       = new NoOp();
                    dim.children[0].value = (string)tokens.actual.value;
                    tokens.SelectNext();

                    Expect("AS", true);

                    dim.children[1] = parseType();

                    root.Add(dim);
                } while(tokens.actual.type == "COMMA");
            }
            Expect("PCLOSE", true);

            if (!sub)
            {
                Expect("AS", true);
                switch (tokens.actual.type)
                {
                case "INTEGER":
                    root.type = "integer";
                    break;

                case "BOOLEAN":
                    root.type = "boolean";
                    break;

                default:
                    throw new SystemException($"Expecting a VARTYPE token, got a {tokens.actual.type} (position {tokens.position}) [Line: {CurrentLine}]");
                }
                tokens.SelectNext();
            }
            Expect("LINEBREAK", true);
            CurrentLine++;

            root.children[0] = ParseStatements(sub ? "sub":"func");

            if (sub)
            {
                Expect("SUB", true);
            }
            else
            {
                Expect("FUNCTION", true);
            }

            Expect("LINEBREAK", true);
            CurrentLine++;


            return(root);
        }