private static int ReplaceMacros(Env env) { int replaceCount = 0; foreach (string key in env.GetEnvKeys()) { if (env.TryGetValue(key, out Node node)) { Node newNode = ExpandMacros(node, env, out int expansionsCount); if (newNode != node) { env.Add(key, newNode); } replaceCount += expansionsCount; } } return(replaceCount); }
private static Node CreateParameterizedEnv(Node parameterNames, Node node, Env env, Logger logger, out Env outEnv) { int numParameters = ListOps.CalculateListLength(parameterNames); logger.LogVerbose("envFunction has " + numParameters + " parameters."); // Create child env. Env localEnv = new Env(env); // At 0 is the function name. int parameterValueIndex = 1; // Add all parameters to local env. for (int i = 0; i < numParameters; i++) { string parameterName = NodeOps.GetChild(parameterNames, i).Content.ToString(); if (parameterName.StartsWith("&")) { // Handle special parameter. if ("&rest".Equals(parameterName)) { string restParameterName = NodeOps.GetChild(parameterNames, i + 1).Content.ToString(); int nodeChildrenCount = ListOps.CalculateListLength(node); Node restParameterValues = null; for (int j = parameterValueIndex; j < nodeChildrenCount; j++) { Node parameter = Evaluator.Evaluate(NodeOps.GetChild(node, j), env); restParameterValues = ListOps.AppendToList(parameter, restParameterValues); } localEnv.Add(restParameterName, restParameterValues); outEnv = localEnv; return(Node.NIL); } } else { Node parameterValue = Evaluator.Evaluate(NodeOps.GetChild(node, parameterValueIndex), env); logger.LogVerbose("Adding parameterValue " + i + "(" + parameterName + "): " + parameterValue); localEnv.Add(parameterName, parameterValue); parameterValueIndex++; } } int nodeChildrenCount2 = ListOps.CalculateListLength(node); if (nodeChildrenCount2 != parameterValueIndex) { int remainingParameterCount = nodeChildrenCount2 - parameterValueIndex; string errorMsg = "EvaluateEnvFunction/CreateParameterizedEnv: " + remainingParameterCount + " additional parameters found."; outEnv = null; return(new Node(StdNodeTypes.Error, errorMsg)); } outEnv = localEnv; return(Node.NIL); }