public bool AddInherit(string text) { //HACK CITY! //first, we need to find where to put the inherit command. We are assuming //the code file already has at least one inherit command (dangerous) or //some meta-comment that singlas where they should go (also dangerous) so we'll //insert our new one after that for (int index = 0; index < this.Tokens.Count; index++) { Parser.Token insertPoint = this.Tokens[index]; if (insertPoint != null) { if (insertPoint.Type == Parser.TokenType.CommentLine && insertPoint.Code.Trim() == Globals.Generator.InheritCode) { //stick 'er in there! Parser.Token newline = new Parser.Token("\n"); Parser.Token token = new Parser.Token(text); this.Tokens.Insert(index, newline); this.Tokens.Insert(index, token); return(true); } } } return(false); }
public void AddLine(string line, string bodyName) { const int FUNC_BODY = 1; Parser.Token body = this.Code.GetFunctionBody(bodyName); body.InsertTextAsTokensBeginning(line, FUNC_BODY); }
/// <summary> /// Obtains values from parsed LPC code and applies them to /// the room model's data. /// </summary> /// <param name="?"></param> private void PullDataFromCode() { //first, find main function Parser.Token body = this.Code.GetFunctionBody("create"); if (body == null) { MessageBox.Show("DEBUG ERROR: Room model's code failed to load properly. The 'create' function body was not found."); return; } //don't assume we have children in the function body if (body.Children.Count < 2) { MessageBox.Show("DEBUG ERROR: Missing function body for 'create'. The Parser has mismatched token children."); return; } //build a list of all function calls found in the LPC object Dictionary <string, Parser.Token> list = this.Code.GetAllFunctionCalls(body); //update all function call controls if they have matching info from the aforementioned list foreach (string dataCall in list.Keys) { const int FUNCTION_PARAMS = 0; if (list.ContainsKey(dataCall)) { StringBuilder str = new StringBuilder(""); //can't use foreach because some children may be null for (int index = 0; index < list[dataCall].Children.Count; index++) { if (list[dataCall].Children != null && list[dataCall].Children[FUNCTION_PARAMS] != null) { str.Append(list[dataCall].Children[FUNCTION_PARAMS][index].Code); } } this.FunctionCalls.DefineCall(dataCall, str.ToString()); } } //update exists and enters list if (this.FunctionCalls.CallList.ContainsKey("SetExits")) { this.EditorState.ExitsList = ParserTools.StringIntoMap(this.FunctionCalls.CallList["SetExits"], "SetExits"); } if (this.FunctionCalls.CallList.ContainsKey("SetEnters")) { this.EditorState.EntersList = ParserTools.StringIntoMap(this.FunctionCalls.CallList["SetEnters"], "SetEnters"); } //check for evidence that the room supports day/night settings for light or long descriptions if (this.FunctionCalls.CallList.ContainsKey("SetDayLong") || this.FunctionCalls.CallList.ContainsKey("SetNightLong") || this.FunctionCalls.CallList.ContainsKey("SetDayLight") || this.FunctionCalls.CallList.ContainsKey("SetNightLight")) { this.EditorState.UseDayNight = true; } }
public Dictionary <string, Parser.Token> GetAllFunctionCalls(Parser.Token root) { //List<Parser.Token> calls = new List<Parser.Token>(); Dictionary <string, Parser.Token> calls = new Dictionary <string, Parser.Token>(); Dictionary <string, int> FuncInstanceCount = new Dictionary <string, int>(); foreach (Parser.Token token in root.Children[1]) { if (token.Type == Parser.TokenType.FunctionCall) { string funcName = ""; //gotta find out the form of the function call with respect to //the scope resolution operator for (int index = 0; index < token.Lexmes.Count; index++) { Lexer.Lexme lexme = token.Lexmes[index]; if (lexme.Data.ToString() == "::") { funcName = token.Lexmes[index + 1].Data.ToString(); break; } if (lexme.Type == Lexer.LexmeType.Identifier) { //look ahead if (token.Lexmes[index + 1].Data.ToString() == "::") { funcName = token.Lexmes[index + 2].Data.ToString(); break; } else { funcName = lexme.Data.ToString(); break; } } } if (funcName.Length < 1 || funcName == "") { throw new Exception("Unidentifiable form for function name."); } if (calls.ContainsKey(funcName)) { calls.Add(funcName + Globals.Generator.FunctionHashSymbol + FuncInstanceCount[funcName], token); FuncInstanceCount[funcName] += 1; } else { calls.Add(funcName, token); FuncInstanceCount.Add(funcName, 1); } } } return(calls); }
public void DeleteFunctionsInCode(string bodyName) { const int FUNC_PARAMS = 0; const int FUNC_BODY = 1; Parser.Token body = this.Code.GetFunctionBody(bodyName); Dictionary <string, Parser.Token> list = this.Code.GetAllFunctionCalls(body); body.Children[FUNC_BODY] = new List <Stellarmass.LPC.Parser.Token>(); }
public bool AddInclude(string fileName) { //search through every token until the end of the file. //if we didn't already file the included file we do it at the top foreach (Parser.Token t in Tokens) { if (t.Type == Stellarmass.LPC.Parser.TokenType.Include) { if (t.Code.Contains(fileName)) { return(true); } } } Parser.Token newline = new Parser.Token("\n"); Parser.Token token = new Parser.Token("#include <" + fileName + ">"); this.Tokens.Insert(0, newline); this.Tokens.Insert(0, token); return(true); }
/// <summary> /// Converts the room model's data back into parsed LPC. /// </summary> private void PushFunctionDataToCode(FunctionCallsCollection functions) { //first, find main function Parser.Token body = this.Code.GetFunctionBody("create"); if (body == null) { MessageBox.Show("DEBUG ERROR: Item model's code failed to update properly. The 'create' function body was not found."); return; } //assume we have children in the function body if (body.Children.Count < 2) { MessageBox.Show("DEBUG ERROR: Missing function body for 'create'. Parser mismatched token children."); return; } //build a list of all function calls that already exist and just need to be changed Dictionary <string, Parser.Token> list = this.Code.GetAllFunctionCalls(body); List <string> remaining = new List <string>(functions.CallList.Keys); //build list of relevant function calls within body foreach (string codeCall in list.Keys) { foreach (string dataCall in functions.CallList.Keys) { if (dataCall == codeCall.Trim()) { //edit currently existsing data within the parsed LPC object if (list[dataCall].Type == Parser.TokenType.FunctionCall) { //make sure hash symbol is removed before adding string[] temp = dataCall.Split(Globals.Generator.FunctionHashSymbol.ToCharArray()); string functionName = temp[0]; //edit exiting function const int FUNCTION_CALL_PARAMS = 0; list[dataCall].SetTextAsTokens(functions.CallList[functionName], FUNCTION_CALL_PARAMS); } remaining.Remove(dataCall); } } } //now deal with all the remaining function calls from //the model that aren't in the LPC parse map yet. List <string> removedFunctions = new List <string>(); foreach (string dataCall in remaining) { /* * const int FUNCTION_BODY = 1; * //make sure hash symbol is removed before adding * string[] temp = dataCall.Split(Globals.Generator.FunctionHashSymbol.ToCharArray()); * string functionName = temp[0]; * * //add functiuons that don't exist within the parsed LPC * //but do exist within the model * body.InsertTextAsTokensEnd("\t" + functionName + "();\n",FUNCTION_BODY); */ const int FUNCTION_BODY = 1; //make sure hash symbol is removed before adding string parameters = functions.CallList[dataCall]; if (parameters.Length > 0 && parameters != null && parameters != "({})" && parameters != "([])" && parameters != "\"\"") { string[] temp = dataCall.Split(Globals.Generator.FunctionHashSymbol.ToCharArray()); string functionName = temp[0]; //add functiuons that don't exist within the parsed LPC //but do exist within the model body.InsertTextAsTokensEnd("\t" + functionName + "();\n", FUNCTION_BODY); } else { removedFunctions.Add(dataCall); } } //loop through again to fill in the parameters for everything we just created list = this.Code.GetAllFunctionCalls(body); //HACK ALERT!!! //when we entered the functions with the hash symbol they used whatever value was tagged onto the end of them //However, now they are using a number count assigned by the 'GetAllFunctionCalls()' which will inevitably make //the results turn sour. So we need to convert all hashed function values to a numeric system, while //also keeing in mind that the first function with a given name is not given a hash symbol by 'GetAllFunctionCalls()'. //Basically we are going to tack on a numbered count after each instance of a function call except the first. Dictionary <string, int> funcHashCount = new Dictionary <string, int>(); foreach (string dataCall in remaining) { string functionKey = dataCall; if (!removedFunctions.Contains(dataCall)) { //hack alert: see above if (functionKey.Contains(Globals.Generator.FunctionHashSymbol)) { string[] temp = functionKey.Split(Globals.Generator.FunctionHashSymbol.ToCharArray()); functionKey = temp[0]; //don't add hash to first instance of a function call if (!funcHashCount.ContainsKey(functionKey)) { funcHashCount.Add(functionKey, 0); } else { funcHashCount[functionKey]++; functionKey = functionKey + Globals.Generator.FunctionHashSymbol + funcHashCount[functionKey]; } } //end hack alert const int FUNCTION_CALL_PARAMS = 0; if (functionKey != null && functionKey.Length > 0 && list[functionKey].Type == Parser.TokenType.FunctionCall) { //make sure hash symbol is removed before adding string[] temp = functionKey.Split(Globals.Generator.FunctionHashSymbol.ToCharArray()); string functionName = temp[0]; list[functionKey].SetTextAsTokens(functions.CallList[dataCall], FUNCTION_CALL_PARAMS); } } //end if not in removed } foreach (string file in functions.AdditionalIncludes) { this.Code.AddInclude(file); } return; }
/// <summary> /// This function /// </summary> /// <param name="name"></param> /// <param name="root"></param> private void RemoveFunctionCallFromCode(string name, Parser.Token root) { const int FUNC_BODY_TOKENS = 1; //foreach(Parser.Token token in root.Children[FUNC_BODY_TOKENS]) for (int count = 0; count < root.Children[FUNC_BODY_TOKENS].Count; count++) { Parser.Token token = root.Children[FUNC_BODY_TOKENS][count]; if (token.Type == Parser.TokenType.FunctionCall) { string funcName = ""; //gotta find out the form of the function call with respect to //the scope resolution operator for (int index = 0; index < token.Lexmes.Count; index++) { Lexer.Lexme lexme = token.Lexmes[index]; if (lexme.Data.ToString() == "::") { funcName = token.Lexmes[index + 1].Data.ToString(); break; } if (lexme.Type == Lexer.LexmeType.Identifier) { //look ahead if (token.Lexmes[index + 1].Data.ToString() == "::") { funcName = token.Lexmes[index + 2].Data.ToString(); break; } else { //found the name of the currently investigated grammar token. //is it the one we are looking for? funcName = lexme.Data.ToString(); if (name == funcName) { Parser.Token funccall = root.Children[FUNC_BODY_TOKENS][count]; Parser.Token pretab = null, newline = null; if (count > 0) { pretab = root.Children[FUNC_BODY_TOKENS][count - 1]; } if (root.Children[FUNC_BODY_TOKENS].Count - 1 <= count + 1) { newline = root.Children[FUNC_BODY_TOKENS][count + 1]; } //WARNING - hackish! //This parameter is used to remove the tab token and newline token that were //placed after the function back in 'PushDataToCode'. It should only be set //if you knoew for sure there is a tab before this function and a newline after. //It is used to remove all that exra space generated when a new function is created and then never used. //yup root.Children[FUNC_BODY_TOKENS].Remove(funccall); //if(pretab != null) {root.Children[FUNC_BODY_TOKENS].Remove(pretab);} //if(newline != null) {root.Children[FUNC_BODY_TOKENS].Remove(newline);} } break; } } } } } return; }
/// <summary> /// Converts the room model's data back into parsed LPC. /// </summary> private void PushDataToCode() { //first, find main function Parser.Token body = this.Code.GetFunctionBody("create"); if (body == null) { MessageBox.Show("DEBUG ERROR: Room model's code failed to update properly. The 'create' function body was not found."); return; } //assume we have children in the function body if (body.Children.Count < 2) { MessageBox.Show("DEBUG ERROR: Missing function body for 'create'. Parser mismatched token children."); return; } //build a list of all function calls that already exist and just need to be changed Dictionary <string, Parser.Token> list = this.Code.GetAllFunctionCalls(body); List <string> remaining = new List <string>(this.FunctionCalls.CallList.Keys); //build list of relevant function calls within body foreach (string codeCall in list.Keys) { foreach (string dataCall in this.FunctionCalls.CallList.Keys) { if (dataCall == null || dataCall.Length < 1) { MessageBox.Show("Warning! A function with no name was produced for '" + this.RawFileName + "'. The flawed data has not been written but you you should verify the contents of the file."); } else { if (dataCall == codeCall.Trim()) { //edit currently existsing data within the parsed LPC object const int FUNCTION_CALL_PARAMS = 0; string parameters = this.FunctionCalls.CallList[dataCall]; if (parameters.Length < 1 || parameters == "({})" || parameters == "([])" || parameters == "\"\"") { //don't remove if it's the create function if (dataCall == "create") { list[dataCall].SetTextAsTokens(parameters, FUNCTION_CALL_PARAMS); remaining.Remove(dataCall); } else { RemoveFunctionCallFromCode(dataCall, body); } } else { string encodedText = parameters; list[dataCall].SetTextAsTokens(encodedText, FUNCTION_CALL_PARAMS); remaining.Remove(dataCall); } } } } } //now deal with all the remaining function calls from //the model that aren't in the LPC parse map yet. List <string> removedFunctions = new List <string>(); foreach (string dataCall in remaining) { const int FUNCTION_BODY = 1; string parameters = this.FunctionCalls.CallList[dataCall]; //add functiuons that don't exist within the parsed LPC //but do exist within the model. But only add them it the //the parameters aren't empty if (parameters.Length > 0 && parameters != null && parameters != "({})" && parameters != "([])" && parameters != "\"\"") { body.InsertTextAsTokensEnd("\t" + dataCall + "();\n", FUNCTION_BODY); } else { removedFunctions.Add(dataCall); } } //loop through again to fill in the parameters for everything we just created //if the parameters are empty remove that function call from the code list = this.Code.GetAllFunctionCalls(body); foreach (string dataCall in remaining) { if (dataCall == null || dataCall.Length < 1) { MessageBox.Show("Warning! A function with no name was produced for '" + this.RawFileName + "'. The flawed data has not been written but you you should verify the contents of the file."); } else { if (!removedFunctions.Contains(dataCall)) { const int FUNCTION_CALL_PARAMS = 0; string parameters = this.FunctionCalls.CallList[dataCall]; list[dataCall].SetTextAsTokens(parameters, FUNCTION_CALL_PARAMS); } } } foreach (string file in FunctionCalls.AdditionalIncludes) { this.Code.AddInclude(file); } return; }