/// <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); }
/// <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); } }
/// <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); }
/// <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); }
/// <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); }
/// <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; } }
/// <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); } }
/// <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> /// 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> /// 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(); }
/// <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)); } }