//sets the override to directly hop to the base when called, while still remaining overridable //only one function per type can be IsBase private void DirectiveIsBase(string val, IBaseFunction func) { val = val.Replace(" ", "").Replace("\n", "").Replace("\t", "").Replace("\r", ""); bool value = (val == "true" || val == "True") ? true : false; if (value) { var samelist = FunctionStack.Where(func.Name).ToList(); foreach (var x in samelist) { //check to make sure this is the only IsBase directive of this type if (x.UID != func.UID && x.Directives != null && x.Directives.ContainsKey("IsBase")) { var stripws = x.Directives["IsBase"].Replace(" ", "").Replace("\n", "").Replace("\t", "").Replace("\r", ""); if (stripws == "true" || stripws == "True") { Compiler.ExceptionListener.Throw($"The function [{func.Name}] has already been set IsBase by a directive. Please remove an IsBase directive."); } } } if (FunctionStack.Contains(func)) { FunctionStack.First(func.UID).SetBase(samelist[samelist.Count - 1]); } } }
private string ParseParameters(string value) { string val = value; //first we have to find all the arrays var regstr = @"(?:(?:\((?>[^()]+|\((?<number>)|\)(?<-number>))*(?(number)(?!))\))|{^()\))+"; var arrayRegex = new Regex(regstr, RegexOptions.Multiline); //var arrayRegex = new Regex(@"\(([^()]*)\)", RegexOptions.Multiline); var arrayMatches = arrayRegex.Matches(val); foreach (var a in arrayMatches) { var param = a.ToString().Substring(1, a.ToString().Length - 2); if (param.Contains("(") && param.Contains(")")) { param = ParseArrays(param); param = ParseParameters(param); param = param.Replace(".", "<-").Replace("\n", "").Replace("\r", "").Replace("\t", ""); param = EvaluateVarExtensions(param); var fext = ParseExtensions(param); var fcheckSplit = param.Split(new string[] { "->" }, StringSplitOptions.None); var fcheck = FunctionStack.First(fcheckSplit[0]); if (fcheck != null) { param = ParseFunctions(param, fext); } } string tokenname = "{AnonGeneratedToken" + TokenParser.AnonymousTokensIndex + "}"; var compCheck = ComparisonCheck(param); if (compCheck != "") { TokenParser.AnonymousTokens.Add(new Token(tokenname, compCheck, val)); } else { var commaRegex = new Regex(",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)"); var commaSplit = commaRegex.Split(param); var tokens = GetTokens(commaSplit, true); //make sure values are being collected and not tokens if (tokens.Count > 0) { for (int i = 0; i < commaSplit.Length; i++) { var obj = tokens.FirstOrDefault(f => f.Name == commaSplit[i]); if (obj != null) { commaSplit[i] = obj.Value; } } param = string.Join(",", commaSplit); } TokenParser.AnonymousTokens.Add(new Token(tokenname, param, val)); } val = val.Replace(a.ToString(), "->" + tokenname + "|"); } return(val); }
private void StartParse() { //start function is an inherit for easier override implementation down the line new Directives(); var startScope = FunctionStack.First("Start"); var awakeScope = FunctionStack.First("Awake"); HaltFunction = FunctionStack.First("Halt"); GuaranteedHaltFunction = FunctionStack.First("GuaranteedHalt"); if (awakeScope != null) { var awakecollection = FunctionStack.Where("Awake"); foreach (var x in awakecollection) { x.TryParse(null); } } if (startScope == null) { Compiler.ExceptionListener.Throw(new ExceptionHandler(ExceptionType.SystemException, $"Your script is missing a 'Start' function.")); } var startCollection = FunctionStack.Where("Start"); if (startCollection.Count() != 2) { Compiler.ExceptionListener.Throw(new ExceptionHandler(ExceptionType.SystemException, $"There must only be one `Start` function. Please remove {startCollection.Count() - 2} `Start` functions")); } //remove the start override from the stack var startIndex = FunctionStack.IndexOf(startScope); FunctionStack.RemoveAt(startIndex); startScope.TryParse(null); }
private string EvaluateVar(string value) { //get the var scope TokenStack varList = null; if (value.Contains("$var%")) { varList = TokenParser.GlobalVariables; } else if (value.Contains("var%")) { varList = _reference.LocalVariables; } if (varList == null) { Compiler.ExceptionListener.Throw(new ExceptionHandler(ExceptionType.SyntaxException, $"[244]Unexpected error occured.", Value)); return(null); } //assign based on operator var strip = value.Replace("$", "").Replace("var%", ""); string[] assign = default(string[]); if (strip.Contains("++")) { assign = strip.Split(new string[] { "++" }, StringSplitOptions.None); } else if (strip.Contains("--")) { assign = strip.Split(new string[] { "--" }, StringSplitOptions.None); } else if (strip.Contains("+=")) { assign = strip.Split(new string[] { "+=" }, StringSplitOptions.None); } else if (strip.Contains("-=")) { assign = strip.Split(new string[] { "-=" }, StringSplitOptions.None); } else if (strip.Contains("=")) { assign = strip.Split(new string[] { "=" }, StringSplitOptions.None); } //get the left hand var leftHand = assign[0].Replace(" ", ""); var varRef = varList.First(leftHand); if (varRef != null && varRef.Locked) { Compiler.ExceptionListener.Throw(new ExceptionHandler(ExceptionType.SyntaxException, $"[282]Cannot re-assign a sealed variable!", Value)); return(null); } //one sided assignment if (strip.Contains("++") || strip.Contains("--")) { if (varRef == null) { Compiler.ExceptionListener.Throw(new ExceptionHandler(ExceptionType.SyntaxException, $"[269]Cannot find the left hand variable.", Value)); return(null); } double numOut = 0; double.TryParse(varRef.ToString(), out numOut); if (strip.Contains("++")) { numOut++; } else { numOut--; } varRef.SetValue(numOut.ToString()); return(""); } Token token = null; var rightHand = assign[1].Replace(" ", ""); //if (rightHand.Contains('+')) //{ var parts = rightHand.Split('+'); string output = ""; foreach (var p in parts) { var x = p; if (x.Contains("->")) { var fext = ParseExtensions(x); var fcheckSplit = x.Split(new string[] { "->" }, StringSplitOptions.None); var fcheck = FunctionStack.First(fcheckSplit[0]); if (fcheck != null) { x = ParseFunctions(x, fext); } } if (x.Contains("<-")) { x = EvaluateVarExtensions(x); } if (x == null || x == "" || x == " ") { Compiler.ExceptionListener.Throw(new ExceptionHandler(ExceptionType.SyntaxException, $"[688]Right hand must be a value.", Value)); return(null); } var prentoken = GetTokens(new string[] { x }); if (prentoken == null) { return(null); } var ntoken = prentoken.ElementAtOrDefault(0); if (ntoken == null) { Compiler.ExceptionListener.Throw(new ExceptionHandler(ExceptionType.SyntaxException, $"[692]Right hand must be a value.", Value)); return(null); } output += ntoken.ToString(); } token = new Token("concatination", output, Value); rightHand = output; //} if (token == null) { Compiler.ExceptionListener.Throw(new ExceptionHandler(ExceptionType.SyntaxException, $"[699]Right hand must be a value.", Value)); return(null); } if (strip.Contains("+=") || strip.Contains("-=")) { if (varRef == null) { Compiler.ExceptionListener.Throw(new ExceptionHandler(ExceptionType.SyntaxException, $"[291]Cannot find the left hand variable.", Value)); return(null); } //check if number and apply the change double leftNumOut = 0; double rightNumOut = 0; //check if token is a number too var nofailRight = double.TryParse(token.ToString(), out rightNumOut); var nofailLeft = double.TryParse(varRef.ToString(), out leftNumOut); if (nofailLeft && nofailRight) { if (strip.Contains("+=")) { leftNumOut += rightNumOut; } else { leftNumOut -= rightNumOut; } varRef.SetValue(leftNumOut.ToString()); } else//one or both arent numbers, which means concatenation intead of incrementation. { var str = varRef.ToString(); if (strip.Contains("+=")) { str += token.ToString(); } else { Compiler.ExceptionListener.Throw(new ExceptionHandler(ExceptionType.SyntaxException, "[314]Cannot apply the operand -= with type string.", Value)); return(null); } varRef.SetValue(str); } return(""); } if (strip.Contains("=")) { if (varRef != null) { varRef.SetValue(token.ToString()); } else { varList.Add(new Token(leftHand, token.ToString(), Value)); } return(""); } Compiler.ExceptionListener.Throw("[330]Unknown error with assignment.", ExceptionType.SyntaxException, Value); return(null); }
private string ParseFunctions(string value, List <EDefinition> ext, bool safelook = false) { TFunction temp = null; string val = value; var firstSplit = value.Split('|')[0]; var secondSplit = firstSplit.Split(new string[] { "->" }, StringSplitOptions.None); var func = FunctionStack.First(secondSplit[0]); if (func == null) { if (safelook) { return(""); } else { Compiler.ExceptionListener.Throw($"[181]Cannot find function [{secondSplit[0]}]", ExceptionType.SyntaxException); return(null); } } //get args var param = GetTokens(new string[] { secondSplit[1] }); if (param.Count != 1) { Compiler.ExceptionListener.Throw("[185]Extensions must provide arguments", ExceptionType.SyntaxException); return(null); } if (func.Invoking) { var invokeFuncName = param[0].ToString(); if (invokeFuncName.Contains("AnonymousFunction")) { var functionToInvoke = FunctionStack.First(invokeFuncName.Replace("\"", "")); if (functionToInvoke != null) { var args = GetTokens(functionToInvoke.ExpectedArgs, true, true); List <string> argsarr = new List <string>(); foreach (var x in args) { argsarr.Add(x.ToString()); } func.SetInvokeProperties(argsarr.ToArray(), _reference.LocalVariables.List, _reference.ProvidedArgs.List); } } } var returnObj = new TFunction(func, ext, param[0].ToString(), _reference); temp = returnObj; //do the whole returning thing var getret = Parse(temp); if (getret != null) { string tokenname = "{AnonGeneratedToken" + TokenParser.AnonymousTokensIndex + "}"; getret.SetName(tokenname); TokenParser.AnonymousTokens.Add(getret); val = tokenname; return(val); } return("null"); }
private List <EDefinition> ParseExtensions(string value) { List <EDefinition> temp = new List <EDefinition>(); if (value.Contains("<-")) { string val = value; var firstSplit = val.Split(new string[] { "<-" }, StringSplitOptions.None); for (int i = 0; i < firstSplit.Length; i++) { if (i == 0) { continue; } var first = firstSplit[i]; var secondSplit = first.Split(new string[] { "->" }, StringSplitOptions.None); if (secondSplit.Length != 2) { Compiler.ExceptionListener.Throw("[160]Extensions must provide arguments", ExceptionType.SyntaxException); return(null); } var original = ExtensionStack.First(secondSplit[0]); if (original == null) { Compiler.ExceptionListener.Throw($"[310]Cannot find extension [{secondSplit[0]}]"); return(null); } //Console.WriteLine(secondSplit[0] + " " + secondSplit[1]); var clone = DeepCopy(original); var param = GetTokens(new string[] { secondSplit[1].Replace("|", "") }); if (param.Count != 1) { Compiler.ExceptionListener.Throw("[166]Extensions must provide arguments", ExceptionType.SyntaxException); return(null); } if (clone.Invoking) { var invokeFuncName = param[0].ToString(); if (invokeFuncName.Contains("AnonymousFunction")) { var functionToInvoke = FunctionStack.First(invokeFuncName.Replace("\"", "")); if (functionToInvoke != null) { //Console.WriteLine($"n: {functionToInvoke.Name} exp: {string.Join(",",functionToInvoke.ExpectedArgs)}"); var args = GetTokens(functionToInvoke.ExpectedArgs, true, true); List <string> argsarr = new List <string>(); foreach (var x in args) { argsarr.Add(x.ToString()); } clone.SetInvokeProperties(argsarr.ToArray()); } } } clone.SetArguments(param[0].ToString()); temp.Add(clone); } } return(temp); }