/// <summary> /// Handles assignment operator. /// </summary> /// <param name="node">SyntaxTree node of operator.</param> protected void handleAssignment(DTreeNode <string> node) { int type = 0; string name = LexemTypeHelper.parse(ref type, node.Nodes[0].Value); getValue(node.Nodes[1]); ilg.Emit(OpCodes.Stloc, handleIdentifier(node.Nodes[0])); if (node.Nodes.Count > 2) { next(node.Nodes[2]); } }
/// <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; } }
/// <summary> /// Processes the next independent command in the code. /// </summary> /// <param name="node">SyntaxTree node of the command.</param> protected void next(DTreeNode <string> node) { int type = 0; string value = LexemTypeHelper.parse(ref type, node.Value); switch (type) { case 1: handeOperator(node); break; case 2: handleKeyword(node); break; case 3: handleIdentifier(node); break; default: break; } }
/// <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]); } }
/// <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(); }
/// <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> /// 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); }
/// <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; } }
/// <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; } }
/// <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); }
/// <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); }
/// <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)); } }