public override SValue Clone() { SDict ret = new SDict((Dictionary <string, SValue>)Underlying); SValue.CopyAttributes(ret, this); return(ret); }
public override SValue Evaluate(ExecEnvironment env) { var regex = this.regex.Evaluate(env); if (!(regex.Underlying is Regex)) { throw new VMException("the first argument must be a regex object", headAtom); } var text = this.text.Evaluate(env) as SString; if (text == null) { throw new VMException("the second argument must be a string", headAtom); } var start = this.start.Evaluate(env) as SNumber; if (start == null) { throw new VMException("the start position must be a number", headAtom); } var length = this.length.Evaluate(env) as SNumber; if (length == null) { throw new VMException("the length must be a number", headAtom); } var len = (int)length.Get <Decimal>(); if (len == -1) { len = text.Get <String>().Length - (int)start.Get <Decimal>(); } Regex re = regex.Underlying as Regex; try { Match m = re.Match(text.Get <String>(), (int)start.Get <Decimal>(), len); var capturedGroups = new Dictionary <string, SValue>(); foreach (string gn in re.GetGroupNames()) { if (m.Groups[gn].Success && m.Groups[gn].Captures.Count > 0) { capturedGroups[gn] = new SDict(new Dictionary <string, SValue>() { { "capture", new SString(m.Groups[gn].Value) }, { "index", new SNumber(m.Groups[gn].Index) }, { "length", new SNumber(m.Groups[gn].Length) }, }); } } return(new SDict(capturedGroups)); } catch { throw new VMException("error ocurred when matching", headAtom); } }
public override SValue Evaluate(ExecEnvironment env) { var newEnv = new ExecEnvironment(); SValue _closure; SClosure closure = null; if (lambdaObject == null) { if (env.ContainsKey(closureName)) { _closure = env[closureName].Evaluate(env); closure = _closure as SClosure; } else { _closure = new SString(closureName); env[closureName] = _closure; } } else { _closure = lambdaObject.Evaluate(env); closure = _closure as SClosure; } List <SValue> arguments = SExpression.EvalSExpressions(this.arguments, env); if (closure == null) { List <SValue> ret = new List <SValue>(); ret.Add(_closure); foreach (var a in arguments) { ret.Add(a); } return(new SList(ret)); } if (closure.Arguments.Count() > arguments.Count()) { var argNames = closure.Arguments.Skip(arguments.Count); return(new SClosure( env, argNames.ToList(), new SECall( closure, arguments.ConvertAll(a => (SExpression)a) .Concat(argNames.Select(a => new SEVariable(a, headAtom, tailCompound))).ToList(), headAtom, tailCompound ) )); } // prepare the executing environment for (int i = 0; i < closure.Arguments.Count(); i++) { string argName = closure.Arguments[i]; if (argName.Length > 3 && argName.Substring(argName.Length - 3) == "...") { argName = argName.Substring(0, argName.Length - 3); newEnv[argName] = new SList(arguments.Skip(i).ToList()); break; } else { newEnv[argName] = arguments[i]; } } newEnv["~parent"] = new SDict(closure.InnerEnv); newEnv["~atom"] = new SObject(headAtom); newEnv.ParentEnv = closure.InnerEnv; return(closure.Body.Evaluate(newEnv)); }