public static Cons Assoc(object item, Cons alist, params object[] args) { var kwargs = ParseKwargs(args, new string[] { "key", "test" }); var key = GetClosure(kwargs[0]); var test = GetClosure(kwargs[1], EqualApply); return SeqBase.Assoc(item, alist, test, key); }
public static void CheckMaxLength(Cons form, int length) { if (Length(form) > length) { throw new LispException("{0}: expected list with length less than {1}", form, length); } }
public static Cons AsList(IEnumerable seq) { if (seq == null) { return null; } var v = seq as Cons; if (v != null) { return (Cons)Force(v); } Cons head = null; Cons tail = null; foreach (var item in seq) { if (head == null) { tail = head = new Cons(item, null); } else { tail = tail.Cdr = new Cons(item, null); } } return head; }
public static void CheckLength(Cons form, int length) { if (Length(form) != length) { throw new LispException("{0}: expected list with length equal to {1}", form, length); } }
public static Cons Pairlis(IEnumerable keys, IEnumerable values, Cons alist) { var iter1 = ToIter(keys).GetEnumerator(); var iter2 = ToIter(values).GetEnumerator(); while (iter1.MoveNext() && iter2.MoveNext()) { alist = MakeCons(MakeList(iter1.Current, iter2.Current), alist); } return alist; }
public static int LogBeginCall(Cons form) { if (ProfilingEntries != null) { long time = ReadTimer(); int index = ProfilingEntries.Count; ProfilingEntries.Add(new ProfilingEntry(index + 1, time, form)); return index; } else { return -1; } }
public static int LogBeginCall(Cons form) { if (ProfilingEntries != null) { long time = ReadTimer(); int index = ProfilingEntries.Count; ProfilingEntries.Add(new ProfilingEntry(index + 1, time, form)); return(index); } else { return(-1); } }
public static Cons MakeMatchResult(Match match) { Cons result = null; if (match.Success) { for (var i = match.Groups.Count - 1; i >= 0; --i) { var group = match.Groups[i]; result = new Cons(group.Value, result); } } return(result); }
public static void RunCommand(Action <object> func, Cons lispCode, bool showTime = false) { var output = GetConsoleOut(); if (lispCode != null) { var head = Runtime.First(lispCode) as Symbol; var t1 = Runtime.GetCpuTime(); foreach (var expr in lispCode) { var val = EvalCommand(expr, 0); var forcing = Runtime.ToBool(Runtime.GetDynamic(Symbols.ReplForceIt)); if (forcing) { val = Runtime.Force(val); } if (func == null) { Runtime.SetSymbolValue(Symbols.It, val); if (val != Runtime.MissingValue) { Runtime.PrintStream(output, "", "it: "); Runtime.PrettyPrintLine(output, 4, null, val); } } else { func(val); } } if (showTime) { var t2 = Runtime.GetCpuTime(); var t = t2 - t1; var msg = String.Format("Time {0:N3}s user {1:N3}s system", t.User, t.System); Runtime.PrintTrace(msg); } } else { func(Runtime.SymbolValue(Symbols.It)); } }
public object[] MakeArgumentFrame(object[] input, object env, Cons wholeMacroForm) { var sig = Definition.Signature; if (sig.Kind != LambdaKind.Macro && sig.RequiredArgsCount == input.Length && sig.Names.Count == input.Length && sig.WholeArg == null) { // fast track if all arguments (no nested parameters) are accounted for. return(input); } var output = new object[sig.Names.Count + (sig.WholeArg == null ? 0 : 1) + (sig.EnvArg == null ? 0 : 1)]; FillDataFrame(sig, input, output, 0, env, wholeMacroForm); return(output); }
public static Cons Last(int count, Cons seq) { if (seq == null || count <= 0) { return(null); } var list = seq; var size = Length(list); for (var i = count; i < size; ++i) { list = list.Cdr; } return(list); }
public static Cons AssocIf(IApply predicate, Cons seq, IApply key) { int i = -1; foreach (Cons x in ToIter(seq)) { ++i; if (FuncallBool(predicate, Funcall(key, Car(x)))) { return(x); } } return(null); }
public static Cons Assoc(object item, Cons seq, IApply test, IApply key) { int i = -1; foreach (Cons x in ToIter(seq)) { ++i; if (FuncallBool(test, item, Funcall(key, Car(x)))) { return(x); } } return(null); }
public static Cons Last(int count, Cons seq) { if (seq == null || count <= 0) { return null; } var list = seq; var size = Length(list); for (var i = count; i < size; ++i) { list = list.Cdr; } return list; }
public static Cons AssocIf(IApply predicate, Cons seq, IApply key) { int i = -1; foreach (Cons x in ToIter(seq)) { ++i; if (FuncallBool(predicate, Funcall(key, Car(x)))) { return x; } } return null; }
public static Cons Assoc(object item, Cons seq, IApply test, IApply key) { int i = -1; foreach (Cons x in ToIter(seq)) { ++i; if (FuncallBool(test, item, Funcall(key, Car(x)))) { return x; } } return null; }
public static Cons MakeListStar(params object[] items) { if (items.Length == 0) { return(null); } var list = AsLazyList((IEnumerable)items[items.Length - 1]); for (var i = items.Length - 2; i >= 0; --i) { list = new Cons(items[i], list); } return(list); }
object IApply.Apply(object[] args) { switch (args.Length) { case 0: return(Last); case 1: return(((Cons)args[0]).Cdr); case 2: default: Last.Cdr = new Cons(args[1], null); Last = Last.Cdr; return(args[0]); } }
// When BQ-ATTACH-APPEND is called, the OP should be #:BQ-APPEND // or #:BQ-NCONC. This produces a form (op item result) but // some simplifications are done on the fly: // // (op '(a b c) '(d e f g)) => '(a b c d e f g) // (op item 'nil) => item, provided item is not a splicable frob // (op item 'nil) => (op item), if item is a splicable frob // (op item (op a b c)) => (op item a b c) public static Cons AttachAppend(Symbol op, object item, Cons result) { if (NullOrQuoted(item) && NullOrQuoted(result)) { return(MakeList(Symbols.bqQuote, Append((Cons)Second(item), (Cons)Second(result)))); } else if (result == null || StructurallyEqual(result, bqQuoteNil)) { return((Cons)item); } else if (Consp(result) && First(result) == op) { return(MakeListStar(op, item, Cdr(result))); } else { return(MakeList(op, item, result)); } }
// The effect of BQ-ATTACH-CONSES is to produce a form as if by // `(LIST* ,@items ,result) but some simplifications are done // on the fly. // // (LIST* 'a 'b 'c 'd) => '(a b c . d) // (LIST* a b c 'nil) => (LIST a b c) // (LIST* a b c (LIST* d e f g)) => (LIST* a b c d e f g) // (LIST* a b c (LIST d e f g)) => (LIST a b c d e f g) public static Cons AttachConses(Cons items, Cons result) { if (Every(NullOrQuoted, items) && NullOrQuoted(result)) { return(MakeList(Symbols.bqQuote, Append(Map(Second, items), (Cons)Second(result)))); } else if (result == null || StructurallyEqual(result, bqQuoteNil)) { return(new Cons(Symbols.bqList, items)); } else if (Consp(result) && (Car(result) == Symbols.bqList || Car(result) == Symbols.bqListStar)) { return(new Cons(Car(result), Append(items, Cdr(result)))); } else { return(new Cons(Symbols.bqList, Append(items, MakeList(result)))); } }
public static bool ParseCompleteSourceCode(string data, out Cons code) { code = null; if (data.Trim() == "") { return(true); } try { code = Runtime.ReadAllFromString(data); return(true); } catch (LispException ex) { return(!ex.Message.Contains("EOF:")); } }
public bool MoveNext() { if (initialized) { if (list == null) { return(false); } else { list = list.Cdr; return(list != null); } } else { initialized = true; return(list != null); } }
public static Cons CodeWalkListAt(int pos, Cons forms, Func <object, AnalysisScope, object> transform, AnalysisScope env) { if (env == null) { env = new AnalysisScope(null); } if (forms == null) { return(null); } else if (pos > 0) { return(MakeCons(forms.Car, CodeWalkListAt(pos - 1, forms.Cdr, transform, env))); } else { return(MakeCons(CodeWalk(forms.Car, transform, env), CodeWalkListAt(0, forms.Cdr, transform, env))); } }
public Cons ReadDelimitedList(string terminator) { if (terminator.Length != 1) { throw MakeScannerException("Terminator string must contain exactly one character: {0}", terminator); } var term = terminator[0]; Cons head = null; Cons tail = null; while (true) { SkipWhitespace(); var ch = ReadChar(); if (IsEof) { throw MakeScannerException("EOF: missing terminator: '{0}'", terminator); } if (ch == term) { return(head); } UnreadChar(); var first = MaybeRead(); if (first != VOID.Value) { if (head == null) { head = tail = Runtime.MakeCons(first, (Cons)null); } else { var newTail = Runtime.MakeCons(first, (Cons)null); tail.Cdr = newTail; tail = newTail; } } } }
public object ApplyLambdaBind(Cons lambdaList, object[] args, bool bound, object env, Cons wholeMacroForm) { if (!Definition.ProcInitialized) { // race condition?? lock (Definition) { if (!Definition.ProcInitialized) { Definition.Proc = Definition.ProcBuilder(); Definition.ProcInitialized = true; } } } var context = Runtime.CurrentThreadContext; var saved = context.Frame; context.Frame = HoistFrame; object result; if (!bound) { args = MakeArgumentFrame(args, env, wholeMacroForm); } if (Runtime.DebugLevel >= 1) { context.EvaluationStack = Runtime.MakeListStar(saved, context.SpecialStack, context.EvaluationStack); result = Definition.Proc(lambdaList, Owner ?? this, args, HoistFrame.Values); context.EvaluationStack = Runtime.Cddr(context.EvaluationStack); } else { result = Definition.Proc(lambdaList, Owner ?? this, args, HoistFrame.Values); } context.Frame = saved; return(result); }
public int GrepShortLambdaParameters(Cons form) { var last = 0; if (form != null) { for (var head = form; head != null; head = head.Cdr) { var sym = head.Car as Symbol; var seq = head.Car as Cons; var index = -1; if (sym != null) { var position = Runtime.Position(sym, Symbols.ShortLambdaVariables); if (position != null) { index = (int)position; if (index == 0) { index = 1; head.Car = Symbols.ShortLambdaVariables[index]; } } } else if (seq != null) { index = GrepShortLambdaParameters(seq); } if (index != -1) { last = (last < index) ? index : last; } } } return(last); }
public int GrepShortLambdaParameters(Cons form) { var last = 0; if (form != null) { for (var head = form; head != null; head = head.Cdr) { var sym = head.Car as Symbol; var seq = head.Car as Cons; var index = -1; if (sym != null) { var position = Runtime.Position(sym, Symbols.ShortLambdaVariables); if (position != null) { index = (int)position; if (index == 0) { index = 1; head.Car = Symbols.ShortLambdaVariables[index]; } } } else if (seq != null) { index = GrepShortLambdaParameters(seq); } if (index != -1) { last = (last < index) ? index : last; } } } return last; }
public static Cons CodeWalkListTry(Cons forms, Func <object, AnalysisScope, object> transform, AnalysisScope env) { if (forms == null) { return(null); } else { object result; if (forms.Car is Cons) { var list = (Cons)forms.Car; var head = First(list); if (head == Symbols.Catch) { // catch (sym type) expr... result = CodeWalkListAt(2, list, transform, env); } else if (head == Symbols.Finally) { // finally expr... result = CodeWalkListAt(1, list, transform, env); } else { result = CodeWalk(list, transform, env); } } else { result = CodeWalk(forms.Car, transform, env); } return(MakeCons(result, CodeWalkListTry(forms.Cdr, transform, env))); } }
public object ApplyLambdaBind(Cons lambdaList, object[] args, bool bound, object env, Cons wholeMacroForm) { var context = Runtime.CurrentThreadContext; var saved = context.Frame; context.Frame = Frame; object result; if (!bound) { args = MakeArgumentFrame(args, env, wholeMacroForm); } if (Runtime.DebugMode) { context.EvaluationStack = Runtime.MakeListStar(saved, context.SpecialStack, context.EvaluationStack); result = Definition.Proc(lambdaList, Owner ?? this, args); context.EvaluationStack = Runtime.Cddr(context.EvaluationStack); } else { result = Definition.Proc(lambdaList, Owner ?? this, args); } context.Frame = saved; return(result); }
public static object QuasiQuoteExpandList(Cons list) { var stack = new Stack(); while (list != null) { object item1 = First(list); list = Cdr(list); if (item1 is Cons) { var item2 = (Cons)item1; if (First(item2) == Symbols.Unquote) { var data = MakeList(Symbols.bqForce, Second(item2)); stack.Push(MakeList(Symbols.bqList, data)); continue; } else if (First(item2) == Symbols.UnquoteSplicing) { var data = MakeList(Symbols.bqForce, Second(item2)); stack.Push(data); continue; } } object expansion = QuasiQuoteExpandRest(item1); stack.Push(MakeList(Symbols.bqList, expansion)); } Cons code = null; list = null; while (stack.Count > 0) { var expr2 = stack.Pop(); var temp = expr2 as Cons; if (temp != null && First(temp) == Symbols.bqList) { list = new Cons(Second(temp), list); } else { if (list != null) { code = new Cons(new Cons(Symbols.bqList, list), code); list = null; } code = new Cons(expr2, code); } } if (list != null) { code = new Cons(new Cons(Symbols.bqList, list), code); list = null; } if (code != null && Cdr(code) == null) { //return new Cons( Symbols.bqAppend, code ); return(First(code)); } else { return(new Cons(Symbols.bqAppend, code)); } }
public static Cons CodeWalkList(Cons forms, Func <object, object> transform) { Func <object, AnalysisScope, object> wrapper = (x, y) => transform(x); return(CodeWalkListAt(0, forms, wrapper, null)); }
public static Cons CodeWalkList(Cons forms, Func <object, AnalysisScope, object> transform, AnalysisScope env) { return(CodeWalkListAt(0, forms, transform, env)); }
//public static bool printCompact = true; public string ToString(bool escape, int radix = -1) { if (!(cdr is IEnumerator || cdr is DelayedExpression)) { bool printCompact = Runtime.ToBool(Runtime.GetDynamic(Symbols.PrintCompact)); if (escape && printCompact) { var first = Runtime.First(this); var second = Runtime.Second(this); var third = Runtime.Third(this); if (first == Symbols.Dot && second is string && third == null) { return(string.Format(".{0}", second)); } else if (first == Symbols.NullableDot && second is string && third == null) { return(string.Format("?{0}", second)); } else if (first == Symbols.Quote && third == null) { return(string.Format("'{0}", second)); } } } var buf = new StringWriter(); if (escape) { buf.Write("("); } Cons list = this; bool needcomma = false; while (list != null) { if (needcomma) { buf.Write(" "); } buf.Write(Runtime.ToPrintString(list.Car, escape, radix)); if (escape) { if (list.cdr is IEnumerator || list.cdr is DelayedExpression) { buf.Write(" ..."); break; } } needcomma = true; list = list.Cdr; } if (escape) { buf.Write(")"); } return(buf.ToString()); }
public static Cons Cdr(Cons list) { return list == null ? null : list.Cdr; }
public static ThreadContextState SaveStackAndFrameWith(Frame frame, Cons form) { // used by compiler generated code return(CurrentThreadContext.SaveStackAndFrame(frame, form)); }
public static Cons Cdar(Cons list) { return Cdr(ToCons(Car(list))); }
public static Cons Cddr(Cons list) { return Cdr(Cdr(list)); }
public static object Car(Cons list) { return list == null ? null : list.Car; }
public static Cons SimplifyArgs( Cons x ) { Cons result = null; foreach ( var arg in Reverse( Cdr( x ) ) ) { var list = arg as Cons; if ( list == null ) { result = AttachAppend( Symbols.bqAppend, arg, result ); } else if ( First( list ) == Symbols.bqList && true ) { result = AttachConses( Cdr( list ), result ); } else if ( First( list ) == Symbols.bqListStar && true ) { result = AttachConses( Reverse( Cdr( Reverse( Cdr( list ) ) ) ), AttachAppend( Symbols.bqAppend, Car( Last( list ) ), result ) ); } else if ( First( list ) == Symbols.bqQuote && Consp( Second( list ) ) && true && Cddr( list ) == null ) { result = AttachConses( MakeList( MakeList( Symbols.bqQuote, First( Second( list ) ) ) ), result ); } else { result = AttachAppend( Symbols.bqAppend, list, result ); } } return result; }
public static object SetCdr(Cons list, Cons item) { if (list == null) { throw new LispException("Cannot set-cdr of null"); } list.Cdr = item; return item; }
public static void EvalPrintCommand(string data, bool debugging) { var output = GetConsoleOut(); bool leadingSpace = char.IsWhiteSpace(data, 0); Cons code = Runtime.ReadAllFromString(data); if (code == null) { return; } Runtime.RestoreStackAndFrame(state.Peek()); var head = Runtime.First(code) as Symbol; if (head != null && (Runtime.Keywordp(head) || head.Name == "?")) { var dotCommand = Runtime.First(code).ToString(); var command = ""; var commandsPrefix = ReplCommands.Where(x => x.StartsWith(dotCommand)).ToList(); var commandsExact = ReplCommands.Where(x => x == dotCommand).ToList(); if (commandsPrefix.Count == 0) { Runtime.PrintLine(output, "Command not found"); return; } else if (commandsExact.Count == 1) { command = commandsExact[0]; } else if (commandsPrefix.Count == 1) { command = commandsPrefix[0]; } else { Runtime.PrintLine(output, "Ambiguous command. Did you mean:"); for (var i = 0; i < commandsPrefix.Count; ++i) { var str = string.Format("{0} {1}", (i == 0 ? "" : i + 1 == commandsPrefix.Count ? " or" : ","), commandsPrefix[i]); Runtime.PrintLine(output, str); } Runtime.PrintLine(output, "?"); return; } switch (command) { case ":continue": { if (debugging) { throw new ContinueFromBreakpointException(); } break; } case ":clear": { History.Clear(); ResetDisplayFunctionImp(); state = new Stack <ThreadContextState>(); state.Push(Runtime.SaveStackAndFrame()); break; } case ":abort": { if (state.Count > 1) { state.Pop(); } else if (debugging) { throw new AbortingDebuggerException(); } break; } case ":top": { while (state.Count > 1) { state.Pop(); } break; } case ":quit": { Quit(); break; } case ":globals": { var pattern = (string)Runtime.Second(code); Runtime.DumpDictionary(output, Runtime.GetGlobalVariablesDictionary(pattern)); break; } case ":variables": { var pos = Runtime.Integerp(Runtime.Second(code)) ? (int)Runtime.Second(code) : 0; Runtime.DumpDictionary(output, Runtime.GetLexicalVariablesDictionary(pos)); break; } case ":$variables": { var pos = Runtime.Integerp(Runtime.Second(code)) ? (int)Runtime.Second(code) : 0; Runtime.DumpDictionary(output, Runtime.GetDynamicVariablesDictionary(pos)); break; } case ":backtrace": { Runtime.PrintLine(output, Runtime.GetEvaluationStack()); break; } case ":Exception": { Runtime.PrintLine(output, LastException.ToString()); break; } case ":exception": { Runtime.PrintLine(output, RemoveDlrReferencesFromException(LastException)); break; } case ":force": { var expr = Runtime.Second(code) ?? Symbols.It; RunCommand(null, Runtime.MakeList(Runtime.MakeList(Symbols.Force, expr))); break; } case ":time": { var expr = Runtime.Second(code) ?? Symbols.It; RunCommand(null, Runtime.MakeList(expr), showTime: true); break; } case ":describe": { RunCommand(x => { Runtime.SetSymbolValue(Symbols.It, x); Runtime.Describe(x); }, Runtime.Cdr(code)); break; } case ":reset": { var level = Runtime.Integerp(Runtime.Second(code)) ? (int)Runtime.Second(code) : 0; while (state.Count > 1) { state.Pop(); } timer.Reset(); timer.Start(); ResetRuntimeFunctionImp(level); timer.Stop(); var time = timer.ElapsedMilliseconds; Runtime.PrintTrace("Startup time: ", time, "ms"); break; } } } else { RunCommand(null, code, smartParens: !leadingSpace); } }
public static Cons Last(Cons seq) { return Last(1, seq); }
public static object Caar(Cons list) { return Car(ToCons(Car(list))); }
// The effect of BQ-ATTACH-CONSES is to produce a form as if by // `(LIST* ,@items ,result) but some simplifications are done // on the fly. // // (LIST* 'a 'b 'c 'd) => '(a b c . d) // (LIST* a b c 'nil) => (LIST a b c) // (LIST* a b c (LIST* d e f g)) => (LIST* a b c d e f g) // (LIST* a b c (LIST d e f g)) => (LIST a b c d e f g) public static Cons AttachConses(Cons items, Cons result) { if ( Every( NullOrQuoted, items ) && NullOrQuoted( result ) ) { return MakeList( Symbols.bqQuote, Append( Map( Second, items ), (Cons) Second( result ) ) ); } else if ( result == null || StructurallyEqual( result, bqQuoteNil ) ) { return new Cons( Symbols.bqList, items ); } else if ( Consp( result ) && ( Car( result ) == Symbols.bqList || Car( result ) == Symbols.bqListStar ) ) { return new Cons( Car( result ), Append( items, Cdr( result ) ) ); } else { return new Cons( Symbols.bqList, Append( items, MakeList( result ) ) ); } }
public object this[int index] { get { int n = index; Cons list = this; if (n < 0) { throw new IndexOutOfRangeException(); } while (n-- > 0) { if (list == null) { return(null); } list = list.Cdr; } if (list == null) { return(null); } else { return(list.Car); } } set { int n = index; Cons list = this; if (n < 0) { throw new IndexOutOfRangeException(); } while (n-- > 0) { if (list == null) { throw new IndexOutOfRangeException(); } list = list.Cdr; } if (list == null) { throw new IndexOutOfRangeException(); } else { list.Car = value; } } }
public static Cons MakeMatchResult(Match match) { Cons result = null; if (match.Success) { for (var i = match.Groups.Count - 1; i >= 0; --i) { var group = match.Groups[i]; result = new Cons(group.Value, result); } } return result; }
public ListEnumerator(Cons list) { this.list = list; }
public static ThreadContextState SaveStackAndFrameWith(Frame frame, Cons form) { // used by compiler generated code return CurrentThreadContext.SaveStackAndFrame(frame, form); }
public static Cons MakeCons(object item, Cons list) { return(new Cons(item, list)); }
public static object QuasiQuoteExpandList(Cons list) { var stack = new Stack(); while (list != null) { object item1 = First(list); list = Cdr(list); if (item1 is Cons) { var item2 = (Cons)item1; if (First(item2) == Symbols.Unquote) { var data = MakeList(Symbols.bqForce, Second(item2)); stack.Push(MakeList(Symbols.bqList, data)); continue; } else if (First(item2) == Symbols.UnquoteSplicing) { var data = MakeList(Symbols.bqForce, Second(item2)); stack.Push(data); continue; } } object expansion = QuasiQuoteExpandRest(item1); stack.Push(MakeList(Symbols.bqList, expansion)); } Cons code = null; list = null; while (stack.Count > 0) { var expr2 = stack.Pop(); var temp = expr2 as Cons; if (temp != null && First(temp) == Symbols.bqList) { list = new Cons(Second(temp), list); } else { if (list != null) { code = new Cons(new Cons(Symbols.bqList, list), code); list = null; } code = new Cons(expr2, code); } } if (list != null) { code = new Cons(new Cons(Symbols.bqList, list), code); list = null; } if (code != null && Cdr(code) == null) { //return new Cons( Symbols.bqAppend, code ); return First(code); } else { return new Cons(Symbols.bqAppend, code); } }
public static IEnumerable OnListEnumerator(Cons seq, IApply step) { while (seq != null) { yield return seq; seq = (Cons)Funcall(step, seq); } }
// When BQ-ATTACH-APPEND is called, the OP should be #:BQ-APPEND // or #:BQ-NCONC. This produces a form (op item result) but // some simplifications are done on the fly: // // (op '(a b c) '(d e f g)) => '(a b c d e f g) // (op item 'nil) => item, provided item is not a splicable frob // (op item 'nil) => (op item), if item is a splicable frob // (op item (op a b c)) => (op item a b c) public static Cons AttachAppend( Symbol op, object item, Cons result ) { if ( NullOrQuoted( item ) && NullOrQuoted( result ) ) { return MakeList( Symbols.bqQuote, Append( (Cons) Second( item ), (Cons) Second( result ) ) ); } else if ( result == null || StructurallyEqual( result, bqQuoteNil ) ) { return (Cons)item; } else if ( Consp( result ) && First( result ) == op ) { return MakeListStar( op, item, Cdr( result ) ); } else { return MakeList( op, item, result ); } }
public static void RunCommand(Action<object> func, Cons lispCode, bool showTime = false, bool smartParens = false) { var output = GetConsoleOut(); if (lispCode != null) { var head = Runtime.First(lispCode) as Symbol; var scope = Runtime.ReplGetCurrentAnalysisScope(); if (smartParens && head != null) { if (Runtime.LooksLikeFunction(head)) { lispCode = Runtime.MakeCons(lispCode, (Cons)null); } } timer.Reset(); foreach (var expr in lispCode) { var expr2 = Runtime.Compile(expr, scope); timer.Start(); object val = Runtime.Execute(expr2); if (Runtime.ToBool(Runtime.GetDynamic(Symbols.ReplForceIt))) { val = Runtime.Force(val); } timer.Stop(); if (func == null) { Runtime.SetSymbolValue(Symbols.It, val); if (val != VOID.Value) { Runtime.PrintStream(output, "", "it: "); Runtime.PrettyPrintLine(output, 4, null, val); } } else { func(val); } } var time = timer.ElapsedMilliseconds; if (showTime) { Runtime.PrintStream(GetConsoleLog(), "info", Runtime.MakeString("Elapsed time: ", time, " ms\n")); } } else { func(Runtime.SymbolValue(Symbols.It)); } }
public static void SplitAt(int count, IEnumerable seq, out Cons left, out Cons right) { if (seq == null) { left = null; right = null; return; } var vleft = new Vector(); var iter = seq.GetEnumerator(); if (count > 0) { while (--count >= 0) { if (!iter.MoveNext()) { break; } vleft.Add(iter.Current); } } left = AsList(vleft); right = MakeCons(iter); }
public static bool ParseCompleteSourceCode(string data, out Cons code) { code = null; if (data.Trim() == "") { return true; } try { code = Runtime.ReadAllFromString(data); return true; } catch (LispException ex) { return !ex.Message.Contains("EOF:"); } }
public static void SplitWith(IApply predicate, IEnumerable seq, out Cons left, out Cons right) { left = null; right = null; if (seq != null) { var iter = seq.GetEnumerator(); var v = new Vector(); while (iter.MoveNext()) { if (FuncallBool(predicate, iter.Current)) { v.Add(iter.Current); } else { left = AsList(v); right = MakeCons(iter.Current, iter); return; } } left = AsList(v); } }
public Exception FillDataFrame(LambdaSignature signature, object[] input, object[] output, int offsetOutput, object env, Cons wholeMacroForm) { var offset = 0; var firstKey = -1; var usedKeys = 0; var haveAll = false; var firstArg = 0; if (signature.Kind != LambdaKind.Macro && signature.RequiredArgsCount > 0) { // This does not work for nested parameters. var n = signature.RequiredArgsCount; if (input.Length < n) { throw new LispException("Missing required parameters"); } Array.Copy(input, 0, output, offsetOutput, n); offsetOutput += n; firstArg = n; offset = n; } for (var iArg = firstArg; !haveAll && iArg < signature.Parameters.Count; ++iArg) { var mod = (iArg < signature.RequiredArgsCount) ? null : signature.ArgModifier; var arg = signature.Parameters[iArg]; object val; if (mod == Symbols.Params) { var buf = new object[input.Length - offset]; Array.Copy(input, offset, buf, 0, buf.Length); val = buf; haveAll = true; } else if (mod == Symbols.Vector) { var v = new Vector(input.Length - offset); for (var i = offset; i < input.Length; ++i) { v.Add(input[i]); } val = v; haveAll = true; } else if (mod == Symbols.Rest || mod == Symbols.Body) { Cons list = null; for (var i = input.Length - 1; i >= offset; --i) { list = new Cons(input[i], list); } val = list; haveAll = true; } else if (mod == Symbols.Key) { if (firstKey == -1) { firstKey = offset; for (var i = firstKey; i < input.Length; i += 2) { if (!Runtime.Keywordp(input[i]) || i + 1 == input.Length) { throw new LispException("Invalid keyword/value list"); } } } val = Runtime.MissingValue; for (var i = firstKey; i + 1 < input.Length; i += 2) { if (arg.Sym.Name == ((Symbol)input[i]).Name) { val = input[i + 1]; ++usedKeys; break; } } } else if (offset < input.Length) { val = input[offset]; ++offset; } else if (mod == Symbols.Optional) { val = Runtime.MissingValue; } else { throw new LispException("Missing required argument: {0}", arg.Sym); } if (val == Runtime.MissingValue) { if (arg.InitFormProc != null) { val = arg.InitFormProc(); } else { val = null; } } if (arg.NestedParameters != null) { // required macro parameter var nestedInput = Runtime.AsArray((IEnumerable)val); FillDataFrame(arg.NestedParameters, nestedInput, output, offsetOutput, env, null); offsetOutput += arg.NestedParameters.Names.Count; } else { output[offsetOutput++] = val; } } if (signature.WholeArg != null) { Cons list = wholeMacroForm; if (list == null) { for (var i = input.Length - 1; i >= 0; --i) { list = new Cons(input[i], list); } } int j = output.Length - 1 - ((signature.EnvArg != null) ? 1 : 0); output[j] = list; haveAll = true; } if (signature.EnvArg != null) { int j = output.Length - 1; output[j] = env; } if (offset < input.Length && !haveAll && firstKey == -1) { throw new LispException("Too many parameters supplied"); } return(null); }
public Symbol(string name, Package package = null) { Name = name; if (Name[0] == '$') { IsDynamic = true; } else if (Name.Length >= 3 && Name[0] == '*' && Name[Name.Length - 1] == '*') { IsDynamic = true; } else { IsDynamic = false; } PropList = null; Package = package; if (package == Runtime.KeywordPackage) { _value = this; Usage = SymbolUsage.Constant; } else { _value = null; Usage = SymbolUsage.None; } }
public static object Cadr(Cons list) { return Car(Cdr(list)); }
public static void EvalPrintCommand(string data, bool debugging) { var output = GetConsoleOut(); if (data == null) { return; } Cons code = Runtime.ReadAllFromString(data); if (code == null) { return; } bool leadingSpace = char.IsWhiteSpace(data, 0); Runtime.RestoreStackAndFrame(state.Peek()); var dotCommand = ExtractCommand(code); if (dotCommand != null) { var command = ""; var commandsPrefix = ReplCommands.Where(x => x.StartsWith(dotCommand)).ToList(); var commandsExact = ReplCommands.Where(x => x == dotCommand).ToList(); if (commandsPrefix.Count == 0) { Runtime.PrintLine(output, "Command not found"); return; } else if (commandsExact.Count == 1) { command = commandsExact[0]; } else if (commandsPrefix.Count == 1) { command = commandsPrefix[0]; } else { Runtime.PrintLine(output, "Ambiguous command. Did you mean:"); for (var i = 0; i < commandsPrefix.Count; ++i) { var str = string.Format("{0} {1}", (i == 0 ? "" : i + 1 == commandsPrefix.Count ? " or" : ","), commandsPrefix[i]); Runtime.PrintLine(output, str); } Runtime.PrintLine(output, "?"); return; } switch (command) { case "continue": { if (debugging) { throw new ContinueFromBreakpointException(); } break; } case "clear": { History.Clear(); Console.Clear(); state = new Stack <ThreadContextState>(); state.Push(Runtime.SaveStackAndFrame()); break; } case "abort": { if (state.Count > 1) { state.Pop(); } else if (debugging) { throw new AbortingDebuggerException(); } break; } case "top": { while (state.Count > 1) { state.Pop(); } break; } case "quit": { Quit(); break; } case "globals": { var pattern = (string)Runtime.Second(code); Runtime.DumpDictionary(output, Runtime.GetGlobalVariablesDictionary(pattern)); break; } case "eval": { var expr = Runtime.Second(code); var pos = Runtime.Integerp(Runtime.Third(code)) ? (int)Runtime.Third(code) : 0; var val = EvalCommand(expr, pos); if (Runtime.ToBool(Runtime.GetDynamic(Symbols.ReplForceIt))) { val = Runtime.Force(val); } Runtime.SetSymbolValue(Symbols.It, val); if (val != Runtime.MissingValue) { Runtime.PrintStream(output, "", "it: "); Runtime.PrettyPrintLine(output, 4, null, val); } break; } case "modify": { var name = (Symbol)Runtime.Second(code); var expr = Runtime.Third(code); var pos = Runtime.Integerp(Runtime.Fourth(code)) ? (int)Runtime.Fourth(code) : 0; ModifyCommand(name, expr, pos); break; } case "variables": { var pos = Runtime.Integerp(Runtime.Second(code)) ? (int)Runtime.Second(code) : 0; Runtime.DumpDictionary(output, Runtime.GetLexicalVariablesDictionary(pos)); break; } case "$variables": { var pos = Runtime.Integerp(Runtime.Second(code)) ? (int)Runtime.Second(code) : 0; Runtime.DumpDictionary(output, Runtime.GetDynamicVariablesDictionary(pos)); break; } case "backtrace": { Runtime.PrintLine(output, Runtime.GetEvaluationStack()); break; } case "Exception": { Runtime.PrintLine(output, LastException.ToString()); break; } case "exception": { Runtime.PrintLine(output, RemoveDlrReferencesFromException(LastException)); break; } case "force": { var expr = Runtime.Second(code) ?? Symbols.It; RunCommand(null, Runtime.MakeList(Runtime.MakeList(Symbols.Force, expr))); break; } case "time": { var expr = Runtime.Second(code) ?? Symbols.It; RunCommand(null, Runtime.MakeList(expr), showTime: true); break; } case "describe": { RunCommand(x => { Runtime.SetSymbolValue(Symbols.It, x); Runtime.Describe(x); }, Runtime.Cdr(code)); break; } case "reset": { var level = Runtime.Integerp(Runtime.Second(code)) ? (int)Runtime.Second(code) : -1; while (state.Count > 1) { state.Pop(); } var t1 = Runtime.GetCpuTime(); Reset(level); var t2 = Runtime.GetCpuTime(); var t = t2 - t1; var msg = String.Format("Reset {0:N3}s user {1:N3}s system", t.User, t.System); Runtime.PrintTrace(msg); break; } } } else if (leadingSpace || !Runtime.ToBool(Symbols.ReplOptionalParentheses.Value)) { RunCommand(null, code, smartParens: false); } else { RunCommand(null, code, smartParens: true); } }