list view for displaying registers
haldean
5 years ago
5 | 5 | xmlns:local="clr-namespace:Tau" |
6 | 6 | mc:Ignorable="d" |
7 | 7 | FocusManager.FocusedElement="{Binding ElementName=Input}" |
8 | Title="tau" Height="249.621" Width="159.735" WindowStyle="ToolWindow"> | |
8 | Title="tau" Height="338.621" Width="224.735" WindowStyle="ToolWindow"> | |
9 | 9 | <Grid> |
10 | 10 | <Grid.RowDefinitions> |
11 | 11 | <RowDefinition Height="*"/> |
12 | 12 | <RowDefinition Height="Auto"/> |
13 | 13 | <RowDefinition Height="40"/> |
14 | 14 | </Grid.RowDefinitions> |
15 | <TextBlock Name="Result" TextWrapping="Wrap" Text="0" Margin="10,10,10,72" FontFamily="PragmataPro" FontSize="20"/> | |
15 | <ListBox Name="Output" Margin="10" Grid.Row="0" BorderBrush="{x:Null}"> | |
16 | <ListBox.ItemTemplate> | |
17 | <DataTemplate> | |
18 | <StackPanel Orientation="Horizontal"> | |
19 | <TextBlock Margin="0,0,10,0" FontFamily="PragmataPro" FontSize="20" Text="{Binding Name, Mode=OneWay}"/> | |
20 | <TextBlock FontFamily="PragmataPro" FontSize="20" Text="{Binding Value, Mode=OneWay}"/> | |
21 | </StackPanel> | |
22 | </DataTemplate> | |
23 | </ListBox.ItemTemplate> | |
24 | </ListBox> | |
16 | 25 | <TextBlock Name="Help" FontFamily="PragmataPro" FontSize="9" VerticalAlignment="Bottom" Grid.Row="1" Margin="10,0" TextWrapping="Wrap"/> |
17 | <TextBox Name="Input" Margin="10,0,10,10" TextWrapping="Wrap" VerticalAlignment="Bottom" FontFamily="PragmataPro" FontSize="20" KeyUp="InputKey" Grid.Row="2"/> | |
26 | <TextBox Name="Input" Margin="10,0,10,10" TextWrapping="Wrap" VerticalAlignment="Bottom" FontFamily="PragmataPro" FontSize="20" KeyUp="InputKey" Grid.Row="2" BorderBrush="{x:Null}"/> | |
18 | 27 | </Grid> |
19 | 28 | </Window> |
21 | 21 | { |
22 | 22 | StackMachine sm; |
23 | 23 | OpParser parser; |
24 | TextBlock result; | |
24 | ListBox output; | |
25 | 25 | TextBlock help; |
26 | 26 | |
27 | 27 | public MainWindow() |
29 | 29 | InitializeComponent(); |
30 | 30 | sm = new StackMachine(); |
31 | 31 | parser = OpParser.New(); |
32 | result = (TextBlock)FindName("Result"); | |
32 | output = (ListBox)FindName("Output"); | |
33 | 33 | help = (TextBlock)FindName("Help"); |
34 | 34 | } |
35 | 35 | |
42 | 42 | if (e.Key == Key.Enter) |
43 | 43 | { |
44 | 44 | sm.Run(parsed); |
45 | result.Text = sm.State(); | |
45 | output.ItemsSource = sm.Items(); | |
46 | 46 | t.Text = ""; |
47 | 47 | return; |
48 | 48 | } |
32 | 32 | public static OpParser New() |
33 | 33 | { |
34 | 34 | OpParser parser = new OpParser(); |
35 | ||
36 | /* arithmetic */ | |
35 | 37 | parser.AddOp(new Op("+", "adds the top two values", BinOp((v1, v2) => { return v2 + v1; }))); |
36 | 38 | parser.AddOp(new Op("*", "multiplies the top two values", BinOp((v1, v2) => { return v2 * v1; }))); |
37 | 39 | parser.AddOp(new Op("-", "subtracts the top value from the value below it", BinOp((v1, v2) => { return v2 - v1; }))); |
38 | 40 | parser.AddOp(new Op("/", "divides the top value into the value below it", BinOp((v1, v2) => { return v2 / v1; }))); |
39 | parser.AddOp(new Op("dup", "duplicates the top value on the stack", (Stack<Double> values) => { | |
41 | ||
42 | /* stack */ | |
43 | parser.AddOp(new Op("dup", "duplicates the top value on the stack", (Stack<Double> values) => | |
44 | { | |
40 | 45 | if (values.Count == 0) |
41 | 46 | return; |
42 | 47 | double v = values.Pop(); |
43 | 48 | values.Push(v); |
44 | 49 | values.Push(v); |
45 | 50 | })); |
46 | parser.AddOp(new Op("swap", "swaps the top two values on the stack", (Stack<Double> values) => { | |
51 | parser.AddOp(new Op("swap", "swaps the top two values on the stack", (Stack<Double> values) => | |
52 | { | |
47 | 53 | if (values.Count < 2) |
48 | 54 | return; |
49 | 55 | double v1 = values.Pop(); |
51 | 57 | values.Push(v1); |
52 | 58 | values.Push(v2); |
53 | 59 | })); |
60 | ||
61 | /* trig */ | |
62 | parser.AddOp(new Op("sin", "the sine of the top value, assumes value is in radians", UnOp((v) => { return Math.Sin(v); }))); | |
63 | parser.AddOp(new Op("cos", "the cosine of the top value, assumes value is in radians", UnOp((v) => { return Math.Cos(v); }))); | |
64 | parser.AddOp(new Op("tan", "the tangent of the top value, assumes value is in radians", UnOp((v) => { return Math.Tan(v); }))); | |
65 | parser.AddOp(new Op("pi", "pushes the value of π onto the stack", Const(Math.PI))); | |
66 | parser.AddOp(new Op("tau", "pushes the value of τ onto the stack", Const(Math.PI * 2))); | |
67 | parser.AddOp(new Op("rad", "converts the top value from degrees to radians", UnOp((v) => { return Math.PI * v / 180; }))); | |
68 | parser.AddOp(new Op("deg", "converts the top value from radians to degrees", UnOp((v) => { return 180 * v / Math.PI; }))); | |
69 | ||
54 | 70 | return parser; |
55 | 71 | } |
56 | 72 | |
69 | 85 | double v1 = values.Pop(); |
70 | 86 | double v2 = values.Count == 0 ? v1 : values.Pop(); |
71 | 87 | values.Push(func(v1, v2)); |
88 | }; | |
89 | } | |
90 | private delegate double Unary(double v); | |
91 | private static Op.Visitor UnOp(Unary func) | |
92 | { | |
93 | return (Stack<Double> values) => | |
94 | { | |
95 | if (values.Count == 0) | |
96 | return; | |
97 | double v = values.Pop(); | |
98 | values.Push(func(v)); | |
99 | }; | |
100 | } | |
101 | private static Op.Visitor Const(double v) | |
102 | { | |
103 | return (Stack<Double> values) => | |
104 | { | |
105 | values.Push(v); | |
72 | 106 | }; |
73 | 107 | } |
74 | 108 |
5 | 5 | |
6 | 6 | namespace Tau |
7 | 7 | { |
8 | public class StackItem | |
9 | { | |
10 | internal StackItem(string name, double v) | |
11 | { | |
12 | Name = name; | |
13 | Value = v; | |
14 | } | |
15 | public string Name { get; } | |
16 | public double Value { get; } | |
17 | ||
18 | internal static string NameIndex(int i) | |
19 | { | |
20 | switch (i) | |
21 | { | |
22 | case 0: return "X"; | |
23 | case 1: return "Y"; | |
24 | case 2: return "Z"; | |
25 | case 3: return "A"; | |
26 | case 4: return "B"; | |
27 | case 5: return "C"; | |
28 | } | |
29 | var sb = new StringBuilder(); | |
30 | sb.Append("R"); | |
31 | sb.Append(i); | |
32 | return sb.ToString(); | |
33 | } | |
34 | ||
35 | public override string ToString() | |
36 | { | |
37 | var sb = new StringBuilder(); | |
38 | sb.Append(Name); | |
39 | sb.Append(" = "); | |
40 | sb.Append(Value); | |
41 | return sb.ToString(); | |
42 | } | |
43 | } | |
44 | ||
8 | 45 | public class StackMachine |
9 | 46 | { |
10 | 47 | private Stack<Double> values; |
13 | 50 | { |
14 | 51 | values = new Stack<double>(); |
15 | 52 | } |
16 | ||
53 | ||
17 | 54 | public void Run(IEnumerable<Op> stream) |
18 | 55 | { |
19 | 56 | foreach (Op o in stream) |
22 | 59 | } |
23 | 60 | } |
24 | 61 | |
25 | public string State() | |
62 | public IEnumerable<StackItem> Items() | |
26 | 63 | { |
27 | List<Double> st = values.ToList(); | |
28 | st.Reverse(); | |
29 | StringBuilder res = new StringBuilder(); | |
30 | foreach (double s in st) | |
31 | { | |
32 | res.Append(s); | |
33 | res.Append("\n"); | |
34 | } | |
35 | return res.ToString(); | |
64 | return from v in values.Zip(Enumerable.Range(0, values.Count), | |
65 | (double v, int i) => { return new { Idx = i, V = v }; }) | |
66 | select new StackItem(StackItem.NameIndex(v.Idx), v.V); | |
36 | 67 | } |
68 | ||
37 | 69 | } |
38 | 70 | } |
35 | 35 | <ItemGroup> |
36 | 36 | <Reference Include="System" /> |
37 | 37 | <Reference Include="System.Data" /> |
38 | <Reference Include="System.ValueTuple, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> | |
39 | <HintPath>..\packages\System.ValueTuple.4.3.0\lib\netstandard1.0\System.ValueTuple.dll</HintPath> | |
40 | </Reference> | |
38 | 41 | <Reference Include="System.Xml" /> |
39 | 42 | <Reference Include="Microsoft.CSharp" /> |
40 | 43 | <Reference Include="System.Core" /> |
86 | 89 | <Generator>ResXFileCodeGenerator</Generator> |
87 | 90 | <LastGenOutput>Resources.Designer.cs</LastGenOutput> |
88 | 91 | </EmbeddedResource> |
92 | <None Include="packages.config" /> | |
89 | 93 | <None Include="Properties\Settings.settings"> |
90 | 94 | <Generator>SettingsSingleFileGenerator</Generator> |
91 | 95 | <LastGenOutput>Settings.Designer.cs</LastGenOutput> |