Beispiel #1
0
        /// <summary>
        /// Gets int value from node.
        /// </summary>
        /// <param name="node">SyntaxTree node.</param>
        protected void getIntValue(DTreeNode <string> node)
        {
            int value;

            Int32.TryParse(LexemTypeHelper.getParsedValue(node.Value), out value);
            ilg.Emit(OpCodes.Ldc_I4, value);
        }
Beispiel #2
0
        /// <summary>
        /// Analyzes a single syntaxTree node to decide what to do next.
        /// </summary>
        /// <param name="parentNode">Current syntaxTree node to precess.</param>
        protected void analyzeNode(DTreeNode <string> parentNode)
        {
            int    type = 0;
            string s    = LexemTypeHelper.parse(ref type, parentNode.Value);
            string identType;

            switch (type)
            {
            case 1:
                if (s == "=" || s == "+")
                {
                    checkAssignment(parentNode);
                }
                break;

            case 3:
                if (identifiers.TryGetValue(s, out identType))
                {
                    checkDeclaring(parentNode);
                }
                else
                {
                    identifiers.Add(s, LexemTypeHelper.getParsedValue(parentNode.Nodes[0].Value));
                }
                break;
            }

            foreach (DTreeNode <string> node in parentNode.Nodes)
            {
                analyzeNode(node);
            }
        }
Beispiel #3
0
 /// <summary>
 /// Duplicate identifier error occured.
 /// </summary>
 /// <param name="node">SyntaxTree node with duplicated identifier.</param>
 protected void identifierError(DTreeNode <string> node)
 {
     Console.WriteLine("Error - duplicate identifier: " +
                       LexemTypeHelper.getParsedValue(node.Value) + ".");
     Console.ReadLine();
     Environment.Exit(-2);
 }
Beispiel #4
0
        /// <summary>
        /// Launches method generation process.
        /// </summary>
        public void generate()
        {
            int num = 0;

            for (num = 0; num < node.Nodes.Count; num++)
            {
                if (node.Nodes[num].Value == "declares:args")
                {
                    break;
                }
            }
            Type[] paramTypes = getArguments(node.Nodes[num]);
            Type   returnType = getRetType(node, num - 1);
            int    attrNum    = (LexemTypeHelper.getParsedValue(node.Nodes[num - 1].Value)
                                 == "[]") ? num - 3 : num - 2;
            MethodAttributes attr     = getAttributes(node, attrNum);
            MethodBuilder    mBuilder = tBuilder.DefineMethod(
                LexemTypeHelper.getParsedValue(node.Value), attr, returnType,
                paramTypes);

            if (LexemTypeHelper.getParsedValue(node.Value) == "main")
            {
                ab.SetEntryPoint(mBuilder);
            }

            ILGenerator ilGenerator = mBuilder.GetILGenerator();

            new GeneratorCode(node.Nodes[node.Nodes.Count - 1], ilGenerator).generate(false);
        }
Beispiel #5
0
        /// <summary>
        /// Gets double value from node.
        /// </summary>
        /// <param name="node">SyntaxTree node.</param>
        protected void getDoubleValue(DTreeNode <string> node)
        {
            double value;

            Double.TryParse(LexemTypeHelper.getParsedValue(node.Value), out value);
            ilg.Emit(OpCodes.Ldc_R4, value);
        }
Beispiel #6
0
        /// <summary>
        /// Gets value after a single mathematic operation or identifier.
        /// </summary>
        /// <param name="node">SyntaxTree node of operation or identifier.</param>
        protected void getValue(DTreeNode <string> node)
        {
            switch (LexemTypeHelper.getParsedType(node.Value))
            {
            case 1:
                switch (LexemTypeHelper.getParsedValue(node.Value))
                {
                case "+": handlePlus(node); break;

                case "-": handleMinus(node); break;

                case "*": handleMultiply(node); break;
                }
                break;

            case 3:
                getIdentifierValue(node);
                break;

            case 4:
                getDoubleValue(node);
                break;

            case 5:
                getIntValue(node);
                break;
            }
        }
Beispiel #7
0
        /// <summary>
        /// Gets identifier value.
        /// </summary>
        /// <param name="node">SyntaxTree node of identifier.</param>
        protected void getIdentifierValue(DTreeNode <string> node)
        {
            string       name = LexemTypeHelper.getParsedValue(node.Value);
            LocalBuilder lBuilder;

            if (locals.TryGetValue(name, out lBuilder))
            {
                ilg.Emit(OpCodes.Ldloc, lBuilder);
            }
        }
Beispiel #8
0
 /// <summary>
 /// Handles System keyword. !!!On any System... calls
 /// System.Console.WriteLine(...);
 /// </summary>
 /// <param name="node">SyntaxTree node of System keyword.</param>
 protected void handleSystem(DTreeNode <string> node)
 {
     if (node.Nodes.Count > 0)
     {
         handleSystem(node.Nodes[0]);
     }
     else
     {
         ilg.EmitWriteLine(handleIdentifier(node));
     }
     if (LexemTypeHelper.getParsedValue(node.Value) == "System" &&
         node.Nodes.Count > 1)
     {
         next(node.Nodes[1]);
     }
 }
Beispiel #9
0
        /// <summary>
        /// Handles the operator as the next command.
        /// </summary>
        /// <param name="node">SyntaxTree node of the operator.</param>
        protected void handeOperator(DTreeNode <string> node)
        {
            switch (LexemTypeHelper.getParsedValue(node.Value))
            {
            case "=": handleAssignment(node); break;

            /*case "+": handlePlus(node); break;
             * case "-": handleMinus(node); break;
             * case "*": handleMultiply(node); break;
             * case "<": handleLess(node); break;
             * case ">": handleBigger(node);break;
             * case "==": handleEqual(node); break;
             * case "!=": handleNotEqual(node); break;*/
            default: break;
            }
        }
Beispiel #10
0
        /// <summary>
        /// Handles identifier. Get LocalBuilder or creates it.
        /// </summary>
        /// <param name="node">SyntaxTree node of identifier.</param>
        /// <returns>LocalBUilder instance that represents the identifier.</returns>
        protected LocalBuilder handleIdentifier(DTreeNode <string> node)
        {
            int          type = 0;
            string       s    = LexemTypeHelper.parse(ref type, node.Value);
            LocalBuilder lBuilder;

            if (!locals.TryGetValue(s, out lBuilder))
            {
                if (node.Nodes.Count == 0)
                {
                    // ERROR! TODO
                }
                lBuilder = ilg.DeclareLocal(ILHelper.getILType(LexemTypeHelper.getParsedValue(node.Nodes[0].Value)));
                locals.Add(s, lBuilder);
            }
            return(lBuilder);
        }
        /// <summary>
        /// Starts the generation process.
        /// </summary>
        public void generate()
        {
            TypeBuilder tBuilder = mBuilder.DefineType(LexemTypeHelper.getParsedValue(node.Value));

            foreach (DTreeNode <string> childNode in node.Nodes)
            {
                switch (childNode.Value)
                {
                case "declares:methods": generateMethods(childNode, tBuilder); break;

                case "declares:fields": generateFields(childNode, tBuilder); break;

                default: continue;
                }
            }
            tBuilder.CreateType();
        }
Beispiel #12
0
        /// <summary>
        /// Gets method's attributes.
        /// </summary>
        /// <param name="node">SyntaxTree node of the declaration of attributes.</param>
        /// <param name="endPos">End position of arguments.</param>
        /// <returns>Int-based MethodAttributes value.</returns>
        protected MethodAttributes getAttributes(DTreeNode <string> node, int endPos)
        {
            MethodAttributes attr = 0;

            for (int i = 0; i <= endPos; i++)
            {
                switch (LexemTypeHelper.getParsedValue(node.Nodes[i].Value))
                {
                case "public": attr = attr | MethodAttributes.Public; break;

                case "static": attr = attr | MethodAttributes.Static; break;

                default: break;
                }
            }
            return(attr);
        }
Beispiel #13
0
        /// <summary>
        /// Gets the values of compare statement into the stack
        /// and compares them.
        /// </summary>
        /// <param name="node">SyntaxTree node of compare operator.</param>
        /// <param name="ifLabel">Label that will be executed, if statement
        /// is true.</param>
        /// <param name="elseLabel">Label that will be executed if statement
        /// is false.</param>
        /// <param name="isElse">Only for if statement. Is there the else
        /// code branch. Otherwise, shoud be false.</param>
        protected void handleComparison(DTreeNode <string> node, Label ifLabel, Label elseLabel, bool isElse)
        {
            getValue(node.Nodes[0]);
            getValue(node.Nodes[1]);
            //ilg.EmitWriteLine(handleIdentifier(node.Nodes[1]));
            //ilg.EmitWriteLine(handleIdentifier(node.Nodes[0]));

            switch (LexemTypeHelper.getParsedValue(node.Value))
            {
            case "==": handleEqual(ifLabel, elseLabel, isElse); break;

            case "!=": handleNotEqual(ifLabel, elseLabel, isElse); break;

            case ">": handleBigger(ifLabel, elseLabel, isElse); break;

            case "<": handleLess(ifLabel, elseLabel, isElse); break;
            }
        }
Beispiel #14
0
        /// <summary>
        /// Handles the keyword as the next command.
        /// </summary>
        /// <param name="node">SyntaxTree node of the keyword.</param>
        protected void handleKeyword(DTreeNode <string> node)
        {
            string name = LexemTypeHelper.getParsedValue(node.Value);

            switch (name)
            {
            case "while":
                handleWhile(node);
                break;

            case "if":
                handleIf(node);
                break;

            case "System":
                handleSystem(node);
                break;
            }
        }
Beispiel #15
0
        /// <summary>
        /// Gets one of the possible variable types.
        /// </summary>
        /// <param name="node">SyntexTree node of variable name.</param>
        /// <returns></returns>
        protected Type getArgType(DTreeNode <string> node)
        {
            Type type;

            switch (LexemTypeHelper.getParsedValue(node.Nodes[0].Value))
            {
            case "int":
                if (node.Nodes.Count == 1)
                {
                    type = typeof(int);
                }
                else
                {
                    type = typeof(int[]);
                } break;

            case "double":
                if (node.Nodes.Count == 1)
                {
                    type = typeof(double);
                }
                else
                {
                    type = typeof(double[]);
                } break;

            case "String":
                if (node.Nodes.Count == 1)
                {
                    type = typeof(String);
                }
                else
                {
                    type = typeof(String[]);
                } break;

            default: type = null; break;
            }
            return(type);
        }
Beispiel #16
0
        /// <summary>
        /// Gets return type of the method.
        /// </summary>
        /// <param name="node">SyntaxTree node of the method's name.</param>
        /// <param name="num">Possible position in SyntaxTree of return type.
        /// It's because return type can be array and consists of 2 nodes.</param>
        /// <returns>Return type of the method.</returns>
        protected Type getRetType(DTreeNode <string> node, int num)
        {
            Type type;

            if (LexemTypeHelper.getParsedValue(node.Nodes[num].Value) == "[]")
            {
                switch (LexemTypeHelper.getParsedValue(node.Nodes[num - 1].Value))
                {
                case "int": type = typeof(int[]); break;

                case "double": type = typeof(int[]); break;

                case "String": type = typeof(int[]); break;

                default: type = null; break;
                }
            }
            else
            {
                type = ILHelper.getILType(LexemTypeHelper.getParsedValue(node.Nodes[num].Value));
            }
            return(type);
        }
Beispiel #17
0
        /// <summary>
        /// Gets type of identifier (variable).
        /// </summary>
        /// <param name="parentNode">Current syntaxTree node to process
        /// (holds a name of variable).</param>
        /// <param name="s">Possible, name of variable.</param>
        /// <returns></returns>
        protected Type getIdentifierType(DTreeNode <string> parentNode, string s)
        {
            string identType;

            if (!identifiers.TryGetValue(s, out identType) && parentNode.Nodes.Count == 1)
            {
                identType = LexemTypeHelper.getParsedValue(parentNode.Nodes[0].Value);
            }
            switch (identType)
            {
            case "int":
                return(typeof(int));

            case "double":
                return(typeof(double));

            case "String":
                return(typeof(string));

            default:
                undefError();
                return(typeof(int));
            }
        }