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); }
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); }
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); }
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); }
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)); } }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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() + ")." ); }
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); }
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); }