public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            AASTNode returnNode = new AASTNode(astNode, parent, SemanticAnalyzer.no_type);
            // Check if "return" is in right place - inside the routine body
            ASTNode?parentCopy = returnNode.Parent;

            while (parentCopy != null)
            {
                if (parentCopy.ASTType.Equals("Routine body"))
                {
                    // Perform the rest of checks
                    if (astNode.Children[1].Children[0].Children.Count > 0) // If it has something to return
                    {
                        if (astNode.Children[1].Children[0].Children[0].Children[0].ASTType.Equals("Call"))
                        {
                            returnNode.Children.Add(base.Annotate(astNode.Children[1].Children[0].Children[0], returnNode));
                        }
                        else
                        {
                            returnNode.Children.Add(base.Annotate(astNode.Children[1].Children[0].Children[0].Children[0], returnNode));
                        }
                    }
                    return(returnNode);
                }
                parentCopy = parentCopy.Parent;
            }
            throw new SemanticErrorException(
                      "Return is not in place!!!\r\n" +
                      "  At (Line: " + astNode.Children[0].Token.Position.Line.ToString() + ", " +
                      "Char: " + astNode.Children[0].Token.Position.Char.ToString() + ")."
                      );
        }
        public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            AASTNode loop = new AASTNode(astNode, parent, SemanticAnalyzer.no_type);

            loop.Children.Add(base.Annotate(astNode.Children[1], loop));
            return(loop);
        }
        public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            AASTNode gotoNode = new AASTNode(astNode, parent, SemanticAnalyzer.no_type);

            gotoNode.Children.Add(base.Annotate(astNode.Children[1], gotoNode));
            return(gotoNode);
        }
        public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            // TODO: name of the block body (if we really need it)
            string   bbName = "name";
            AASTNode bb     = new AASTNode(astNode, parent, SemanticAnalyzer.no_type);

            bb.Context = new Context("BlockBody_" + bbName, SemanticAnalyzer.FindParentContext(parent), bb);
            bool   setLIEnd = false;
            string varName  = "";

            if (Program.currentCompiler.semantics.varToAddToCtx != null)
            {
                bb.Context.AddVar(Program.currentCompiler.semantics.varToAddToCtx, Program.currentCompiler.semantics.varToAddToCtx.Token.Value);
                varName  = Program.currentCompiler.semantics.varToAddToCtx.Token.Value;
                setLIEnd = true;
                Program.currentCompiler.semantics.varToAddToCtx = null;
            }
            foreach (ASTNode child in astNode.Children)
            {
                bb.Children.Add(base.Annotate(child, bb));
            }
            if (setLIEnd)
            {
                bb.Context.SetLIEnd(varName, SemanticAnalyzer.GetMaxDepth(bb));
            }
            return(bb);
        }
示例#5
0
        public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            AASTNode call = new AASTNode(astNode, parent, SemanticAnalyzer.no_type);

            call.Children.Add(base.Annotate(astNode.Children[0], call));
            call.Children.Add(base.Annotate(astNode.Children[1], call));
            return(call);
        }
示例#6
0
        public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            AASTNode literal = new AASTNode(astNode, parent, SemanticAnalyzer.no_type)
            {
                AASTValue = int.Parse(astNode.Children[1].Token.Value) * (astNode.Children[0].Children.Count > 0 ? -1 : 1)
            };

            return(literal);
        }
示例#7
0
        public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            AASTNode nodeToPass = new AASTNode(astNode, parent, SemanticAnalyzer.no_type);

            foreach (ASTNode child in astNode.Children)
            {
                nodeToPass.Children.Add(base.Annotate(child, nodeToPass));
            }
            return(nodeToPass);
        }
示例#8
0
        public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            AASTNode body = new AASTNode(astNode, parent, SemanticAnalyzer.no_type);

            foreach (ASTNode child in astNode.Children[1].Children)
            {
                body.Children.Add(base.Annotate(child, body));
            }
            return(body);
        }
 /// <summary>
 /// Main method that is usually being overwritten by child Node Annotators.
 /// </summary>
 /// <param name="astNode">AST node to be annotated.</param>
 /// <param name="parent">Possible AAST parent node.</param>
 /// <returns>Annotated AST node.</returns>
 public virtual AASTNode Annotate(ASTNode astNode, AASTNode?parent)
 {
     if (Program.currentCompiler.semantics.nodeAnnotators.ContainsKey(astNode.ASTType))
     {
         return(Program.currentCompiler.semantics.nodeAnnotators[astNode.ASTType].Annotate(astNode, parent));
     }
     else
     {
         return(Program.currentCompiler.semantics.nodeAnnotators["Default"].Annotate(astNode, parent));
     }
 }
示例#10
0
        public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            AASTNode swap = new AASTNode(astNode, parent, SemanticAnalyzer.no_type);

            // TODO: perform type check
            foreach (ASTNode child in astNode.Children)
            {
                swap.Children.Add(base.Annotate(child, swap));
            }
            return(swap);
        }
示例#11
0
        public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            AASTNode anns = new AASTNode(astNode, parent, SemanticAnalyzer.no_type);

            // Annotate the first child
            anns.Children.Add(base.Annotate(astNode.Children[1], anns));
            // Repeat for the rest
            foreach (ASTNode child in astNode.Children[2].Children)
            {
                anns.Children.Add(base.Annotate(child, anns));
            }
            return(anns);
        }
示例#12
0
        public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            AASTNode forNode = new AASTNode(astNode, parent, SemanticAnalyzer.no_type);

            forNode.Children.Add(base.Annotate(astNode.Children[1], forNode));
            ((AASTNode)forNode.Children[0]).AASTType        = new VarType(VarType.ERAType.INT);
            ((AASTNode)forNode.Children[0]).LIStart         = 1;
            Program.currentCompiler.semantics.varToAddToCtx = (AASTNode)forNode.Children[0];
            // If 'from' expression exists
            if (astNode.Children[2].Children.Count > 0)
            {
                forNode.Children.Add(base.Annotate(astNode.Children[2].Children[1], forNode));
                ((AASTNode)forNode.Children[^ 1]).AASTValue = 1; // For generator
        public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            VarType type = SemanticAnalyzer.IdentifyType(astNode.Children[0], astNode.Children[1].Children[0].ASTType.Equals("Constant"));

            if (astNode.Children[1].Children[0].ASTType.Equals("Array"))
            {
                type = new ArrayType(type);
            }
            AASTNode varDecl = new AASTNode(astNode, parent, SemanticAnalyzer.no_type);

            varDecl.Children.AddRange(IdentifyVarDecl(astNode.Children[1].Children[0], varDecl, type));
            return(varDecl);
        }
        public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            Context? ctx    = SemanticAnalyzer.FindParentContext(parent);
            AASTNode module = new AASTNode(astNode, parent, new VarType(VarType.ERAType.MODULE));

            module.Context = new Context(astNode.Children[1].Token.Value, ctx, module);
            foreach (ASTNode child in astNode.Children[2].Children)
            {
                module.Children.Add(base.Annotate(child, module));
            }
            ctx?.AddVar(module, astNode.Children[1].Token.Value);
            return(module);
        }
示例#15
0
        public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            AASTNode ifNode = new AASTNode(astNode, parent, SemanticAnalyzer.no_type);

            ifNode.Children.Add(base.Annotate(astNode.Children[1], ifNode));
            ifNode.Children.Add(base.Annotate(astNode.Children[3], ifNode)); // If true
            // Annotate else block if any
            if (astNode.Children[4].Children[0].Children.Count > 0)
            {
                ifNode.Children.Add(base.Annotate(astNode.Children[4].Children[0].Children[1], ifNode));
            }
            return(ifNode);
        }
示例#16
0
        public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            AASTNode program = new AASTNode(astNode, parent, SemanticAnalyzer.no_type);

            program.Context = new Context("Program", null, program);

            foreach (ASTNode child in astNode.Children)
            {
                program.Children.Add(base.Annotate(child, program));
            }

            return(program);
        }
        public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            AASTNode stmnt = new AASTNode(astNode, parent, SemanticAnalyzer.no_type);

            // Label if any
            if (astNode.Children[0].Children.Count > 0)
            {
                stmnt.Children.Add(base.Annotate(astNode.Children[0].Children[0], stmnt));
            }

            // The statement itself
            stmnt.Children.Add(base.Annotate(astNode.Children[1].Children[0], stmnt));

            return(stmnt);
        }
        public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            AASTNode asmBlock = new AASTNode(astNode, parent, SemanticAnalyzer.no_type);

            asmBlock.Children.Add(base.Annotate(astNode.Children[1], asmBlock)); // First child
            foreach (ASTNode child in astNode.Children[3].Children)
            {
                // Something wrong here... UPD: nothing wrong
                if (child.ASTType.Equals("Assembly statement"))
                {
                    asmBlock.Children.Add(base.Annotate(child, asmBlock));
                }
            }
            return(asmBlock);
        }
        public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            Context  ctx  = SemanticAnalyzer.FindParentContext(parent);
            AASTNode data = new AASTNode(astNode, parent, new DataType());

            ((DataType)data.AASTType).Size = astNode.Children[3].Children.Count + 1;
            data.Children.Add(base.Annotate(astNode.Children[1], data)); // Identifier
            data.Children.Add(base.Annotate(astNode.Children[2], data)); // The first literal
            foreach (ASTNode child in astNode.Children[3].Children)
            {
                data.Children.Add(base.Annotate(child, data)); // The rest of literals
            }
            ctx.AddVar(data, astNode.Children[1].Token.Value);
            return(data);
        }
        public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            AASTNode code = new AASTNode(astNode, parent, new VarType(VarType.ERAType.MODULE));

            code.Context = new Context("code", SemanticAnalyzer.FindParentContext(parent), code);

            foreach (ASTNode child in astNode.Children[1].Children)
            {
                code.Children.Add(base.Annotate(child, code));
            }

            SemanticAnalyzer.FindParentContext(parent).AddVar(code, "code");

            return(code);
        }
示例#21
0
        public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            string   structName = astNode.Children[1].Token.Value;
            AASTNode structure  = new AASTNode(astNode, parent, new StructType(structName));
            Context? ctx        = SemanticAnalyzer.FindParentContext(parent)
                                  ?? throw new SemanticErrorException("No parent context found!!!\r\n  At line " + astNode.Token.Position.Line);

            ctx?.AddVar(structure, structName);
            structure.Context = new Context(structName, ctx, structure);
            foreach (ASTNode child in astNode.Children[2].Children)
            {
                structure.Children.Add(base.Annotate(child, structure));
            }
            return(structure);
        }
示例#22
0
        public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            AASTNode label = new AASTNode(astNode, parent, new VarType(VarType.ERAType.LABEL));

            // Add label to the context
            Context?ctx = SemanticAnalyzer.FindParentContext(parent);

            ctx?.AddVar(label, astNode.Children[1].Token.Value);
            label.Token.Value = astNode.Children[1].Token.Value;

            // Put identifier
            label.Children.Add(base.Annotate(astNode.Children[1], label));

            return(label);
        }
 /// <summary>
 /// Used for current context retrieval
 /// </summary>
 /// <param name="parent">Parent (or current) node from which to start the search</param>
 /// <returns>Nearest context (may return global Program context)</returns>
 public static Context?FindParentContext(AASTNode?parent)
 {
     while (true)
     {
         if (parent == null)
         {
             break;
         }
         if (parent.Context != null)
         {
             return(parent.Context);
         }
         parent = (AASTNode?)parent.Parent;
     }
     return(null);
 }
        public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            AASTNode asgnmt = new AASTNode(astNode, parent, SemanticAnalyzer.no_type);

            // TODO: check for type accordance (debatable)
            // TODO: dot-notation here
            if (astNode.Children[0].Children[0].ASTType.Equals("Primary") &&
                SemanticAnalyzer.FindParentContext(asgnmt).IsVarConstant(astNode.Children[0].Children[0].Token))
            {
                Token id = astNode.Children[0].Children[0].Token;
                throw new SemanticErrorException("Attempt to modify a constant!!!\n" +
                                                 "  At(Line: " + id.Position.Line + ", Char: " + id.Position.Char + ").");
            }
            asgnmt.Children.Add(base.Annotate(astNode.Children[0], asgnmt)); // Receiver
            asgnmt.Children.Add(base.Annotate(astNode.Children[2], asgnmt)); // Expression
            return(asgnmt);
        }
示例#25
0
        public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            AASTNode pragmaNode  = new AASTNode(astNode, parent, SemanticAnalyzer.no_type);
            string   pragmaName  = astNode.Children[0].Token.Value;
            string   pragmaParam = "none";

            if (astNode.Children[2].Children.Count > 0)
            {
                pragmaParam = astNode.Children[2].Children[1].Token.Value;
            }
            switch (pragmaName)
            {
            case "memory":     // Tells the compiler how much memory to allocate for stack and heap combined
            {
                // Usage: (b | kb | mb | gb) *number (ulong)*. Example:  memory("mb 16")
                List <string> expectedArgs = new List <string>()
                {
                    "b", "kb", "mb", "gb"
                };
                string[] args = pragmaParam.Split(' ');
                if (args.Length != 2 || !expectedArgs.Contains(args[0]))
                {
                    throw new SemanticErrorException("Wrong 'memory' pragma usage!!!\r\nUsage: (b | kb | mb | gb) (number (ulong)). Example: memory(\"mb 16\")");
                }
                ulong mem;
                try
                {
                    mem = ulong.Parse(args[1]) * (ulong)Math.Pow(1024, expectedArgs.IndexOf(args[0]));
                }
                catch (Exception)
                {
                    throw new SemanticErrorException("Wrong 'memory' pragma number!!! 'ulong' expected!!!");
                }
                Program.config.MemorySize = mem;
                break;
            }

            default:
            {
                break;
            }
            }
            return(pragmaNode);
        }
        public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            AASTNode breakNode = new AASTNode(astNode, parent, SemanticAnalyzer.no_type);
            // Check if "break" is in the right place - inside the loop body
            ASTNode?parentCopy = breakNode.Parent;

            while (parentCopy != null)
            {
                if (parentCopy.ASTType.Equals("Loop body"))
                {
                    return(breakNode);
                }
                parentCopy = parentCopy.Parent;
            }
            throw new SemanticErrorException(
                      "Break is not in place!!!\r\n" +
                      "  At (Line: " + astNode.Children[0].Token.Position.Line.ToString() + ", " +
                      "Char: " + astNode.Children[0].Token.Position.Char.ToString() + ")."
                      );
        }
示例#27
0
        public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            AASTNode callArgs = new AASTNode(astNode, parent, SemanticAnalyzer.no_type);

            if (astNode.Children[1].Children.Count > 0) // If some arguments exist
            {
                // First expression
                callArgs.Children.Add(base.Annotate(astNode.Children[1].Children[0], callArgs));
                // The rest of expressions if any
                if (astNode.Children[1].Children[1].Children.Count > 0)
                {
                    foreach (ASTNode child in astNode.Children[1].Children[1].Children)
                    {
                        if (child.ASTType.Equals("Expression")) // Skip comma
                        {
                            callArgs.Children.Add(base.Annotate(child, callArgs));
                        }
                    }
                }
            }
            return(callArgs);
        }
 public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
 {
     return(new AASTNode(astNode, null, SemanticAnalyzer.no_type));
 }
        public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            AASTNode somePrim = new AASTNode(astNode, parent, SemanticAnalyzer.no_type);
            Context? ctx      = SemanticAnalyzer.FindParentContext(parent)
                                ?? throw new SemanticErrorException("No parent context found!!!\r\n  At line " + astNode.Token.Position.Line);

            // Identifier
            somePrim.Children.Add(base.Annotate(astNode.Children[0], somePrim));
            ASTNode idLink = astNode.Children[0];

            // If constant, convert to number
            if (ctx.IsVarDeclared(idLink.Token) && ctx.IsVarConstant(idLink.Token))
            {
                int     constValue = ctx.GetConstValue(idLink.Token);
                ASTNode number     = new ASTNode(parent, new List <ASTNode>(), idLink.Token, "NUMBER");
                ASTNode opMinus    = new ASTNode(number, new List <ASTNode>(), idLink.Token, "[ - ]");
                if (constValue < 0)
                {
                    opMinus.Children.Add(new ASTNode(opMinus, new List <ASTNode>(), idLink.Token, "OPERATOR"));
                    constValue *= -1;
                }
                number.Children.Add(opMinus);
                ASTNode literal = new ASTNode(number, new List <ASTNode>(), new Token(TokenType.NUMBER, constValue.ToString(), idLink.Token.Position), "SOME_LITERAL");
                number.Children.Add(literal);
                return(base.Annotate(number, parent));
            }
            else
            {
                // { '.' Identifier }
                if (astNode.Children[1].Children.Count > 0)
                {
                    foreach (ASTNode child in astNode.Children[1].Children)
                    {
                        if (!ctx.IsVarStruct(idLink.Token))
                        {
                            throw new SemanticErrorException(
                                      "Trying to access non-struct variable via \'.\' notation!!!\r\n" +
                                      "\tAt (Line: " + idLink.Token.Position.Line.ToString() +
                                      ", Char: " + idLink.Token.Position.Char.ToString() + ")."
                                      );
                        }
                        if (child.ASTType.Equals("IDENTIFIER"))
                        {
                            idLink = child;
                        }
                        somePrim.Children.Add(base.Annotate(child, somePrim));
                    }
                }

                // [ ArrayAccess | CallArgs ]
                if (astNode.Children[2].Children.Count > 0)
                {
                    if (astNode.Children[2].Children[0].Children[0].ASTType.Equals("Call arguments"))
                    {
                        somePrim.Children.Add(base.Annotate(astNode.Children[2].Children[0].Children[0], somePrim));
                    }
                    else
                    {
                        if (!ctx.IsVarArray(idLink.Token) && !ctx.IsVarData(idLink.Token.Value))
                        {
                            throw new SemanticErrorException(
                                      "Trying to access non-array variable via \'[]\' notation!!!\r\n" +
                                      "\tAt (Line: " + idLink.Token.Position.Line.ToString() +
                                      ", Char: " + idLink.Token.Position.Char.ToString() + ")."
                                      );
                        }
                        // If expression is constant we can check for array boundaries
                        if (SemanticAnalyzer.IsExprConstant(astNode.Children[2].Children[0].Children[0].Children[1], ctx))
                        {
                            int index   = SemanticAnalyzer.CalculateConstExpr(astNode.Children[2].Children[0].Children[0].Children[1], ctx);
                            int arrSize = ctx.GetArrSize(idLink.Token);
                            if (index < 0)
                            {
                                throw new SemanticErrorException(
                                          "Negative array index!!!\r\n" +
                                          "\tAt (Line: " + idLink.Token.Position.Line.ToString() +
                                          ", Char: " + idLink.Token.Position.Char.ToString() + ")."
                                          );
                            }
                            // If we know the size of the array already (arrSize != 0 indicates this)
                            if (arrSize != 0 && index >= arrSize)
                            {
                                throw new SemanticErrorException(
                                          "Accessing element with index higher than array the size!!!\r\n" +
                                          "\tAt (Line: " + idLink.Token.Position.Line.ToString() +
                                          ", Char: " + idLink.Token.Position.Char.ToString() + ")."
                                          );
                            }
                        }
                        somePrim.Children.Add(base.Annotate(astNode.Children[2].Children[0].Children[0].Children[1], somePrim));
                    }
                }
            }

            return(somePrim);
        }
示例#30
0
        public override AASTNode Annotate(ASTNode astNode, AASTNode?parent)
        {
            AASTNode       expr     = new AASTNode(astNode, parent, SemanticAnalyzer.no_type);
            List <ASTNode> children = astNode.Children;
            Context        ctx      = SemanticAnalyzer.FindParentContext(parent);

            // Special case -1: if we have constant expression - calculate it and return literal instead
            // ATTENTION: need to be tested. UPD: it's okay
            if (SemanticAnalyzer.IsExprConstant(astNode, ctx))
            {
                int     exprValue = SemanticAnalyzer.CalculateConstExpr(astNode, ctx);
                ASTNode number    = new ASTNode(expr, new List <ASTNode>(), expr.Token, "NUMBER");
                ASTNode opMinus   = new ASTNode(number, new List <ASTNode>(), expr.Token, "[ - ]");
                if (exprValue < 0)
                {
                    opMinus.Children.Add(new ASTNode(opMinus, new List <ASTNode>(), expr.Token, "OPERATOR"));
                    exprValue *= -1;
                }
                number.Children.Add(opMinus);
                ASTNode literal = new ASTNode(number, new List <ASTNode>(), new Token(TokenType.NUMBER, exprValue.ToString(), expr.Token.Position), "SOME_LITERAL");
                number.Children.Add(literal);
                expr.Children.Add(base.Annotate(number, expr));
                return(expr);
            }

            // Special case 0: if we have "legal" or initial Expression from Syntax Analyzer
            if (astNode.Children.Count == 2 && astNode.Children[1].ASTType.Equals("{ Operator Operand }"))
            {
                children = astNode.Children[1].Children;
                children.Insert(0, astNode.Children[0]);
            }

            // Special case 1: only one operand
            if (children.Count == 1)
            {
                expr.Children.Add(base.Annotate(children[0], expr));
                return(expr);
            }

            // Special case 2: operand, operator, and operand
            if (children.Count == 3)
            {
                foreach (var child in children)
                {
                    expr.Children.Add(base.Annotate(child, expr));
                }
                return(expr);
            }

            // If more, we need to rearrange the operands and operators to follow the operation priority
            // --  Gospod' dast - srabotaet  --
            // UPD: Gospod' smilovilsya nado mnoy, spasibo emu
            // Priority list
            List <string> ops = new List <string>()
            {
                "*", "+", "-", ">=", "<=", ">", "<", "=", "/=", "&", "^", "|", "?"
            };

            foreach (string op in ops)
            {
                if (children.Count <= 3)
                {
                    break;
                }
                for (int i = 1; i < children.Count; i += 2) // Iterate over operators
                {
                    if (children[i].ASTType.Equals("Operator") && children[i].Token.Value.Equals(op))
                    {
                        ASTNode child_expr = new ASTNode(astNode, new List <ASTNode>(), astNode.Token, "Expression"); // Create additional expression
                        child_expr.Children.Add(children[i - 1]);
                        child_expr.Children.Add(children[i]);
                        child_expr.Children.Add(children[i + 1]);
                        children.RemoveRange(i - 1, 3);
                        children.Insert(i - 1, child_expr);
                        i -= 2;
                    }
                }
            }

            // Annotate modified AST and put it to expression
            foreach (ASTNode child in children)
            {
                expr.Children.Add(base.Annotate(child, expr));
            }

            return(expr);
        }