public void includeAnalysis(string text, ref List <functionData> functionList) { List <string> errorList = new List <string>(); List <lexicalToken> tokens = lexicalAnalysis(text, ref errorList); int max = tokens.Count; for (int i = 0; i != tokens.Count; i++) { lexicalToken t = tokens[i]; if (t.type == tokenType.identifer) { //Abort if callback: if (lexicalHelper.isCallback(t.value)) { continue; } //Skip keywords like if (they look like functions): if (lexicalHelper.isKeyword(t.value)) { //Skip until all () are closed again i++; if (i == max) { break; } t = tokens[i]; if (t.type == tokenType.parenthesis_open) { int parenthesis_count = 1; while (parenthesis_count != 0) { i++; if (i == max) { break; } t = tokens[i]; if (t.type == tokenType.parenthesis_open) { parenthesis_count++; } else if (t.type == tokenType.parenthesis_close) { parenthesis_count--; } } } else { //Error: Expected parenthesis } } else { //Check if the identifer is a function identifer: //Create variables: functionData function = new functionData(); function.identifer = t.value; int beginning_token = i; //Check if identifer is a function: i++; if (i == max) { break; } t = tokens[i]; //There is a ( following: if (t.type == tokenType.parenthesis_open) { //Add all arguments until all () are closed again: int parenthesis_count = 1; while (parenthesis_count != 0) { i++; if (i == max) { break; } t = tokens[i]; if (t.type == tokenType.parenthesis_open) { parenthesis_count++; } else if (t.type == tokenType.parenthesis_close) { parenthesis_count--; } else if (t.type == tokenType.identifer) { function.arguments.Add(t.value); } else if (t.type == tokenType.brace_open || t.type == tokenType.brace_close) { break; } } if (parenthesis_count != 0) { if (i == max) { //Error: File ended unexpectedly! break; } else //The loop broke because of a { or } { //Error: Probably missing at least one ")" } } //Proceed to next tokens: //Skip all unnessecary tokens: do { i++; if (i == max) { break; } t = tokens[i]; }while (t.type == tokenType.newline); functionData foundFunction = functionList.Find(item => item.identifer == function.identifer); //Proceed to next tokens: if (t.type == tokenType.brace_open) { //We found the implementation of the function: if (foundFunction != null) { //Error: Function redefinition? continue; } //If the function is a callback implementation, abort: if (lexicalHelper.isCallback(function.identifer)) { continue; } function.isImplemented = true; function.implementation = t.line - 1; } else if (t.type == tokenType.semicolon) { //We found no implementation of the function: //Abort (there could be natives) function.isImplemented = false; function.implementation = -1; } else { //Error: Missing semicolon: } //Get tags and add to list: int j = beginning_token; List <string> dataTypeList = new List <string>(); do { j--; if (j <= 0) { break; } t = tokens[j]; if (!((t.type == tokenType.newline) || (t.type == tokenType.semicolon))) { dataTypeList.Add(t.value); } }while (j > 0 && t.type != tokenType.newline && t.type != tokenType.semicolon); if (dataTypeList.Count > 0) { function.dataTypes = dataTypeList; } //Add to list or update on list: if (dataTypeList.Find(item => item.Contains("native")) != null) { string arg = "("; foreach (string x in function.arguments) { arg += x + ","; } arg += ")"; arg = arg.Replace(",)", ")"); function.fullIdentifer = function.identifer + arg; arg = ""; foreach (string x in function.dataTypes) { arg = arg.Replace("\n", ""); arg += x + " "; } function.fullIdentiferDataTypes = arg + function.fullIdentifer; functionList.Add(function); } else { continue; } //Else: Function is a prototype that is no native. Not interested in those. } else { //There is no ( following to the identifer: i--; } } } } }
public void codeAnalysis(string text, ref List <defineData> defineList, ref List <functionData> functionList, bool skipCallbacks = true) { List <string> errorList = new List <string>(); List <lexicalToken> tokens = lexicalAnalysis(text, ref errorList); defineList = new List <defineData>(); functionList = new List <functionData>(); List <functionCallData> functionCallDataList = new List <functionCallData>(); int max = tokens.Count; for (int i = 0; i != tokens.Count; i++) { lexicalToken t = tokens[i]; if (t.type == tokenType.define) { //Create new define object: defineData define = new defineData(); //Proceed to next token: i++; if (i == max) { break; } t = tokens[i]; //If the token is a identifer, add that to the define object: if (t.type == tokenType.identifer) { define.identifer = t.value; } else { //Error: No define identifer found! errorList.Add("Missing define identifer."); continue; } // Add all following tokens to the define value: do { i++; if (i == max) { break; } t = tokens[i]; define.value += t.value + " "; }while (t.type != tokenType.newline); //Add the define object to the list: defineList.Add(define); } else if (t.type == tokenType.identifer) { //Abort if callback: if (skipCallbacks && lexicalHelper.isCallback(t.value)) { continue; } //Skip keywords like if (they look like functions): if (lexicalHelper.isKeyword(t.value)) { //Skip until all () are closed again i++; if (i == max) { break; } t = tokens[i]; if (t.type == tokenType.parenthesis_open) { int parenthesis_count = 1; while (parenthesis_count != 0) { i++; if (i == max) { break; } t = tokens[i]; if (t.type == tokenType.parenthesis_open) { parenthesis_count++; } else if (t.type == tokenType.parenthesis_close) { parenthesis_count--; } } } else { //Error: Expected parenthesis } } else { //Check if the identifer is a function identifer: //Create variables: functionData function = new functionData(); function.identifer = t.value; int beginning_token = i; //Check if identifer is a function: i++; if (i == max) { break; } t = tokens[i]; //There is a ( following: if (t.type == tokenType.parenthesis_open) { int identiferLine = t.line; //Line on which the identifer lies. //Add all arguments until all () are closed again: int parenthesis_count = 1; while (parenthesis_count != 0) { i++; if (i == max) { break; } t = tokens[i]; if (t.type == tokenType.parenthesis_open) { parenthesis_count++; } else if (t.type == tokenType.parenthesis_close) { parenthesis_count--; } else if (t.type == tokenType.identifer) { function.arguments.Add(t.value); } else if (t.type == tokenType.brace_open || t.type == tokenType.brace_close) { break; } } if (parenthesis_count != 0) { if (i == max) { //Error: File ended unexpectedly! break; } else //The loop broke because of a { or } { //Error: Probably missing at least one ")" } } //Proceed to next tokens: //Skip all unnessecary tokens: do { i++; if (i == max) { break; } t = tokens[i]; }while (t.type == tokenType.newline); functionData foundFunction = functionList.Find(item => item.identifer == function.identifer); //Proceed to next tokens: if (t.type == tokenType.brace_open) { //We found the implementation of the function: if (foundFunction != null) { //Error: Function redefinition? continue; } //If the function is a callback implementation, abort: if (lexicalHelper.isCallback(function.identifer)) { continue; } function.isImplemented = true; function.implementation = identiferLine; } else if (t.type == tokenType.semicolon) { //We found no implementation of the function: functionCallData foundFunctionData = functionCallDataList.Find(item => item.identifer == function.identifer); if (foundFunctionData != null) { foundFunctionData.calls.Add(identiferLine); } else { foundFunctionData = new functionCallData(); foundFunctionData.identifer = function.identifer; foundFunctionData.calls.Add(identiferLine); functionCallDataList.Add(foundFunctionData); } continue; } else { //Error: Missing semicolon: } //Get tags and add to list: int j = beginning_token; List <string> dataTypeList = new List <string>(); do { j -= 2; if (j <= 0) { break; } t = tokens[j]; if (!((t.type == tokenType.newline) || (t.type == tokenType.semicolon))) { dataTypeList.Add(t.value); } }while (j > 0 && t.type != tokenType.newline && t.type != tokenType.semicolon); if (dataTypeList.Count > 0) { function.dataTypes = dataTypeList; } if (!function.isImplemented) { continue; } //Add to list or update on list: //Process arguments: string arg = "("; foreach (string x in function.arguments) { arg += x + ","; } arg += ")"; arg = arg.Replace(",)", ")"); function.fullIdentifer = function.identifer + arg; arg = ""; foreach (string x in function.dataTypes) { arg = arg.Replace("\n", ""); arg += x + " "; } function.fullIdentiferDataTypes = arg + function.fullIdentifer; functionList.Add(function); } else { //There is no ( following to the identifer: i--; } } } } foreach (functionCallData i in functionCallDataList) { functionData f = functionList.Find(item => item.identifer == i.identifer); if (f != null) { f.occurences = i.calls; } } }