static public node ParseExpression(node branch, List <Token> expression, bool gotSplit = false) { List <Token> leftBuffer = new List <Token>(); List <Token> rightBuffer = new List <Token>(); int i = -1; int opPC = opPrecedence.Count; for (int j = 0; j < opPC; j++) { OperatorCategory Cat = opPrecedence[j]; bool rtl = Cat.rightToLeft; byte cnt = Cat.count; int k = rtl ? Cat.operators.Length - 1 : 0; bool loop = true; bool obrk = false; while (loop) { i = -1; bool brk = false; bool isPar = false; int rParCount = 0; int parPairs = 0; bool surroundedPar = false; bool firstIsPar = false; bool firstIsMethod = false; bool methodPar = false; bool expressionIsMethod = false; Method foundMethod = null; string op = Tokenizer.processPunctuator(Cat.operators[k]); while (i < expression.Count - 1) { i++; Token token = expression[i]; if (MethodHandler.Exists(token.value)) { if (i == 0) { firstIsMethod = true; foundMethod = MethodHandler.Get(token.value); } } // If a left parenthesis is found, increase rParCount so we can keep track of the current pair if (token.value == "lpar") { rParCount++; isPar = true; if (i == 0) { firstIsPar = true; } else if (i == 1 && firstIsMethod) { methodPar = true; } } if (isPar) { // If a right parenthesis is found, decrease rParCount so we can keep track of the current pair if (token.value == "rpar") { rParCount--; // If rParCount == 0, it means that we found a matching pair of parenthesis if (rParCount == 0) { parPairs++; isPar = false; if (i == expression.Count - 1 && firstIsPar && parPairs == 1) { surroundedPar = true; break; } if (i == expression.Count - 1 && methodPar) { expressionIsMethod = true; break; } continue; } } else { // Skip until we find the matching right parenthesis continue; } } if (op == token.value) { node newNode = new node(); node addNode; newNode.depth = branch.depth + 1; newNode.body = token.value; // All of the tokens on the left leftBuffer = expression.GetRange(0, i); // All of the tokens on the right rightBuffer = expression.GetRange(i + 1, expression.Count - i - 1); if (op == "dec" || op == "inc") { if (leftBuffer.Count > 0 && rightBuffer.Count == 0) { newNode.body = "p" + Tokenizer.processPunctuator(op); addNode = ParseExpression(newNode, leftBuffer, true); } else { newNode.body = Tokenizer.processPunctuator(op); addNode = ParseExpression(newNode, rightBuffer, true); } if (addNode != null) { newNode.nodes.Add(addNode); } } else { // Parsing a node from the left buffer if (cnt != 1) { addNode = ParseExpression(newNode, leftBuffer, true); if (addNode != null) { newNode.nodes.Add(addNode); } } if (op == "return") { if (rightBuffer.Count > 0) { Console.WriteLine(stringList(rightBuffer)); // Parsing a node from the right buffer addNode = ParseExpression(newNode, rightBuffer, true); if (addNode != null) { newNode.nodes.Add(addNode); } } } else { // Parsing a node from the right buffer addNode = ParseExpression(newNode, rightBuffer, true); if (addNode != null) { newNode.nodes.Add(addNode); } } } branch.nodes.Add(newNode); // Break out of all loops brk = true; break; } } // Parse an expression thats between a pair of parenthesis, but ONLY // if it wasn't split up before, and only if the whole block is surrounded by matching parenthesis if (surroundedPar) { expression = expression.GetRange(1, expression.Count - 2); return(ParseExpression(branch, expression)); } else if (expressionIsMethod) { node addNode = null; if (expression.Count > 2) { if (expression[0].type == TokenType.Identifier && expression[1].value == "lpar" && expression[expression.Count - 1].value == "rpar" ) { addNode = ParseMethod(branch, expression, foundMethod); if (addNode != null && !gotSplit) { branch.nodes.Add(addNode); return(null); } } } return(addNode); } // Loop direction (0 to length - 1 or length - 1 to 0) if (rtl) { loop = k > 0; k--; } else { loop = k < Cat.operators.Length - 1; k++; } // Break out of all loops if (brk) { obrk = true; break; } } // Break out of all loops if (obrk) { break; } } // Return no node if the expression list contains more than 1 token at this point if (expression.Count > 1) { return(null); } Token tkn = expression[0]; object Value = null; switch (tkn.type) { case TokenType.Numeric: Value = double.Parse(tkn.value); break; case TokenType.String: Value = tkn.value.Substring(1, tkn.value.Length - 2); break; case TokenType.Boolean: if (tkn.value == "true") { Value = true; } else { Value = false; } break; default: break; } // Return leaf node return(new node() { body = expression[0].value, depth = branch.depth + 1, Value = Value, type = tkn.type }); }
static public Variable ExecuteMethod(node methodNode, List <Variable> scopeContext) { if (!MethodHandler.Exists(methodNode.body)) { throw new SkryptMethodDoesNotExistException(methodNode.body); } Method method = MethodHandler.Get(methodNode.body); SkryptMethod skmethod = MethodHandler.GetSk(methodNode.body); string type = methodNode.nodes[0].body; List <node> argNodes = null; object[] args = new object[0]; List <Variable> scopedVars = new List <Variable>(); if (method.arguments.Length > 0 && method.arguments != null) { argNodes = methodNode.nodes[1].nodes; args = new object[argNodes.Count]; int i = 0; foreach (node argNode in argNodes) { node Expr = argNode.nodes[0]; Variable solved = ExecuteExpression(Expr, scopedVars); args[i] = solved.Value; i++; } } Variable returnVariable; if (method.predefined) { returnVariable = method.Run(args); } else { if (argNodes != null) { int i = 0; foreach (node argNode in argNodes) { node Expr = argNode.nodes[0]; Variable solved = ExecuteExpression(Expr, scopedVars); solved.Identifier = argNode.body; if (Variables.Exists(x => x.Identifier == argNode.body)) { Variables[Variables.IndexOf(Variables.Find(x => x.Identifier == argNode.body))].Value = solved.Value; } scopedVars.Add(solved); i++; } } returnVariable = skmethod.Run(scopedVars); DeleteVariables(scopedVars); } return(returnVariable); }