public void Execute(string source) { lock (protect) { this.Context = this.Execute(Brief.Parse(source, this.Context.Dictionary), this.Context); } }
public Machine() { this.Context = new Context(); this.Context.AddWord10("trace", "Enable/disable debug tracing (`trace true`, `trace false`, `trace <bool>`)", b => this.trace = b); this.Context.AddWord10("print", "Print message to console (`print 'hello`, `print \"this is a test\"`)", s => Console.WriteLine(s)); this.Context.AddWord21("+", "Addition (`+ 3 4`, `+ <int/double> <int/double>`)", (a, b) => a + b); this.Context.AddWord21("-", "Subtraction (`- 3 4`, `- <int/double> <int/double>`)", (a, b) => a - b); this.Context.AddWord21("*", "Multiplication (`* 3 4`, `* <int/double> <int/double>`)", (a, b) => a * b); this.Context.AddWord21("/", "Division (`/ 3 4`, `/ <int/double> <int/double>`)", (a, b) => a / b); this.Context.AddWord21("mod", "Modulus (`mod 3 4`, `mod <int/double> <int/double>`)", (a, b) => a / b); this.Context.AddWord22("swap", "Swap top two stack elements (`swap`)", (a, b) => new Tuple <dynamic, dynamic>(b, a)); this.Context.AddWord12("dup", "Duplicate top stack element (`dup`)", a => new Tuple <dynamic, dynamic>(a, a)); this.Context.AddWord10("drop", "Drop top stack element (`drop`)", _ => { }); this.Context.AddWord(".", "Display top of stack (`.`)", c => { Console.WriteLine(c.Stack.Peek()); return(c); }); this.Context.AddWord(".s", "Display stack (`.s`)", c => { DisplayStack(c.Stack); return(c); }); this.Context.AddWord("clear", "Clear stack values (`clear`)", c => { c.Stack.Clear(); return(c); }); this.Context.AddWord21("=", "Equality comparision (`= x y`)", (a, b) => a == b); this.Context.AddWord21(">", "Greater than comparision (`> x y`)", (a, b) => a > b); this.Context.AddWord21(">=", "Greater than or equal comparision (`>= x y`)", (a, b) => a >= b); this.Context.AddWord21("<", "Less than comparision (`< x y`)", (a, b) => a < b); this.Context.AddWord21("<=", "Less than or equal comparision (`<= x y`)", (a, b) => a <= b); this.Context.AddWord21("and", "Boolean conjunction (`and x y`)", (a, b) => a && b); this.Context.AddWord21("or", "Boolean disjunction (`or x y`)", (a, b) => a || b); this.Context.AddWord11("not", "Negation (`not x y`)", a => !a); this.Context.AddWord("if", "Conditionally execute a quotation (`if [<when true>] [<when false>] <predicate>`)", c => { LinkedList <Word> t = c.Pop(); LinkedList <Word> f = c.Pop(); var p = c.Pop(); return(Execute(p ? t : f, c)); }); this.Context.AddWord20("def", "Define secondary word (`def 'myword [<my code>]`)", (name, quotation) => { Func <Context, Context> fn = c => Execute(quotation, c); this.Context.AddWord(name, Brief.Print(quotation), fn); }); this.Context.AddWord10("load", "Load source from file (`load 'foo.b`, `load <file>`)", path => { foreach (var line in ((string[])File.ReadAllLines(path))) { if (line.Length > 0 && !line.StartsWith("// ")) { this.Execute(line); } } }); this.Context.AddWord00("words", "Lists words available in the current dictionary", () => { foreach (var w in this.Context.Dictionary.Values) { Console.WriteLine($"`{w.Name}` - {w.Description}"); } }); this.Context.AddWord10("help", "Help with a particular word (`help dup`)", n => { Word w = this.Context.Dictionary[n]; Console.WriteLine($"Word: {w.Name}\nDescription: {w.Description}\nType: {w.Type}"); }); }
Context Execute(IEnumerable <Word> code, Context context) { if (this.trace) { Console.WriteLine($"Execute: {Brief.Print(code)}"); } foreach (var word in code) { context = word.Function(context); if (this.trace) { Console.WriteLine($"{word} -> {(context.Stack.Count == 0 ? "<empty>" : context.Stack.Peek())}"); } } return(context); }