git.haldean.org tau / cdef2f1
switch stack machine to use little visitor objects haldean 4 years ago
5 changed file(s) with 146 addition(s) and 3 deletion(s). Raw diff Collapse all Expand all
33 xmlns:local="clr-namespace:Tau"
44 StartupUri="MainWindow.xaml">
55 <Application.Resources>
6
76 </Application.Resources>
87 </Application>
44 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
55 xmlns:local="clr-namespace:Tau"
66 mc:Ignorable="d"
7 Title="MainWindow" Height="350" Width="525">
7 FocusManager.FocusedElement="{Binding ElementName=Input}"
8 Title="tau" Height="257.492" Width="160.859" WindowStyle="ToolWindow">
89 <Grid>
9
10 <TextBlock TextWrapping="Wrap" Text="0" Margin="10,10,10,30" FontFamily="PragmataPro" Name="Result" FontSize="20"/>
11 <TextBox Margin="10,0,10,9" TextWrapping="Wrap" VerticalAlignment="Bottom" FontFamily="PragmataPro" Name="Input" FontSize="20" KeyUp="InputKey"/>
1012 </Grid>
1113 </Window>
1919 /// </summary>
2020 public partial class MainWindow : Window
2121 {
22 StackMachine sm;
23 TextBlock result;
24
2225 public MainWindow()
2326 {
2427 InitializeComponent();
28 sm = StackMachine.New();
29 result = (TextBlock) FindName("Result");
30 }
31
32 private void InputKey(object sender, KeyEventArgs e)
33 {
34 switch (e.Key)
35 {
36 case Key.Enter:
37 TextBox t = (TextBox)sender;
38 sm.Run(t.Text);
39 result.Text = sm.State();
40 t.Text = "";
41 break;
42 default:
43 break;
44 }
2545 }
2646 }
2747 }
0 ´╗┐using System;
1 using System.Collections.Generic;
2 using System.Linq;
3 using System.Text;
4 using System.Threading.Tasks;
5
6 namespace Tau
7 {
8 class Op
9 {
10 public delegate void Visitor(Stack<Double> s);
11 public string Name;
12 public Visitor Func;
13 public string Doc;
14
15 public Op(string n, string d, Visitor f)
16 {
17 Name = n;
18 Func = f;
19 Doc = d;
20 }
21 }
22
23 public class StackMachine
24 {
25 private Stack<Double> values;
26 private Dictionary<string, Op> ops;
27
28 protected StackMachine()
29 {
30 values = new Stack<double>();
31 ops = new Dictionary<string, Op>();
32 }
33
34 void AddOp(Op o)
35 {
36 ops.Add(o.Name, o);
37 }
38
39 private delegate double Binary(double v1, double v2);
40 private static Op.Visitor BinOp(Binary func)
41 {
42 return (Stack<Double> values) =>
43 {
44 if (values.Count == 0)
45 return;
46 double v1 = values.Pop();
47 double v2 = values.Count == 0 ? v1 : values.Pop();
48 values.Push(func(v1, v2));
49 };
50 }
51
52 public static StackMachine New()
53 {
54 StackMachine sm = new StackMachine();
55 sm.AddOp(new Op("+", "adds the top two values", BinOp((v1, v2) => { return v2 + v1; })));
56 sm.AddOp(new Op("*", "multiplies the top two values", BinOp((v1, v2) => { return v2 * v1; })));
57 sm.AddOp(new Op("-", "subtracts the top value from the value below it", BinOp((v1, v2) => { return v2 - v1; })));
58 sm.AddOp(new Op("/", "divides the top value into the value below it", BinOp((v1, v2) => { return v2 - v1; })));
59 sm.AddOp(new Op("dup", "duplicates the top value on the stack", (Stack<Double> values) => {
60 if (values.Count == 0)
61 return;
62 double v = values.Pop();
63 values.Push(v);
64 values.Push(v);
65 }));
66 sm.AddOp(new Op("swap", "swaps the top two values on the stack", (Stack<Double> values) => {
67 if (values.Count < 2)
68 return;
69 double v1 = values.Pop();
70 double v2 = values.Pop();
71 values.Push(v1);
72 values.Push(v2);
73 }));
74 return sm;
75 }
76
77 public void Run(string data)
78 {
79 string[] bits = data.Split();
80 foreach (string b in bits)
81 {
82 double res;
83 if (Double.TryParse(b, out res))
84 {
85 Push(res);
86 continue;
87 }
88 Push(b);
89 }
90 }
91
92
93 public void Push(string opname)
94 {
95 Op op;
96 if (ops.TryGetValue(opname, out op))
97 {
98 op.Func(values);
99 }
100 }
101
102 public void Push(Double v)
103 {
104 values.Push(v);
105 }
106
107 public string State()
108 {
109 List<Double> st = values.ToList();
110 st.Reverse();
111 StringBuilder res = new StringBuilder();
112 foreach (double s in st)
113 {
114 res.Append(s);
115 res.Append("\n");
116 }
117 return res.ToString();
118 }
119 }
120 }
5353 <Generator>MSBuild:Compile</Generator>
5454 <SubType>Designer</SubType>
5555 </ApplicationDefinition>
56 <Compile Include="StackMachine.cs" />
5657 <Page Include="MainWindow.xaml">
5758 <Generator>MSBuild:Compile</Generator>
5859 <SubType>Designer</SubType>