-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathAtomicTypes.cs
195 lines (169 loc) · 4.59 KB
/
AtomicTypes.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
using System;
using System.Collections.Generic;
namespace DtxCS.DataTypes
{
/// <summary>
/// The most basic element of dta.
/// </summary>
public class DataAtom : DataNode
{
DataType type;
string sData;
int iData;
float fData;
/// <summary>
/// The type of this Atom.
/// </summary>
public override DataType Type => type;
public override DataNode Evaluate() => this;
/// <summary>
/// The value of this Atom.
/// </summary>
public int Int
{
get
{
if (type == DataType.INT)
return iData;
else throw new Exception("Data is not int");
}
}
/// <summary>
/// The value of this Atom.
/// </summary>
public float Float
{
get
{
if (type == DataType.FLOAT)
return fData;
else throw new Exception("Data is not float");
}
}
/// <summary>
/// The value of this Atom.
/// </summary>
public string String
{
get
{
if (type == DataType.STRING)
return sData;
else throw new Exception("Data is not string");
}
}
/// <summary>
/// Construct an Atom whose value is a string or symbol.
/// </summary>
/// <param name="data">The value assigned to this atom.</param>
public DataAtom(string data)
{
type = DataType.STRING;
sData = data.Replace("\\q", "\"");
}
/// <summary>
/// Construct an Atom whose value is an integer.
/// </summary>
/// <param name="data"></param>
public DataAtom(int data)
{
type = DataType.INT;
iData = data;
}
/// <summary>
/// Construct an Atom whose value is a floating-point value.
/// </summary>
/// <param name="data"></param>
public DataAtom(float data)
{
type = DataType.FLOAT;
fData = data;
}
/// <summary>
/// The string representation of this Atom.
/// </summary>
public override string Name => ToString(true);
private string ToString(bool name)
{
string ret = "";
switch (type)
{
case DataType.STRING:
ret += name ? sData : "\"" + sData + "\"";
break;
case DataType.INT:
ret += iData.ToString();
break;
case DataType.FLOAT:
// Even though the format string uses a dot, it gets changed to a comma on some locales
// unless you give ToString the invariant culture.
ret += fData.ToString("0.0#", System.Globalization.NumberFormatInfo.InvariantInfo);
break;
}
return ret;
}
/// <summary>
/// Returns the string representation of this Atom.
/// </summary>
/// <returns></returns>
public override string ToString() => ToString(false);
}
public class DataVariable : DataNode
{
static Dictionary<string, DataVariable> vars = new Dictionary<string, DataVariable>();
public override string Name { get; }
public override string ToString() => Name;
public override DataType Type => DataType.VARIABLE;
public DataNode Value { get; set; }
public override DataNode Evaluate() => Value;
public static DataVariable Var(string name)
{
DataVariable ret;
if (!vars.TryGetValue(name, out ret))
vars.Add(name, ret = new DataVariable(name, new DataAtom(0)));
return ret;
}
/// <summary>
/// Makes a data variable. Scoping not implemented because we're not an interpreter.
/// Don't give this the $.
/// </summary>
/// <param name="name"></param>
private DataVariable(string name, DataNode value)
{
Name = "$" + name;
Value = value;
}
}
public class DataSymbol : DataNode
{
static Dictionary<string, DataSymbol> symbols = new Dictionary<string, DataSymbol>();
public static DataSymbol Symbol(string value)
{
DataSymbol ret;
if (!symbols.TryGetValue(value, out ret))
symbols.Add(value, ret = new DataSymbol(value));
return ret;
}
public override string Name => value;
public override DataNode Evaluate() => this;
public override DataType Type => DataType.SYMBOL;
private string value;
private bool quote;
private DataSymbol(string value)
{
this.value = value;
foreach(var c in value)
{
// TODO: Is this right?
if(c == ' ' || c == '\r' || c == '\n' || c == '\t'
|| c == '(' || c == ')' || c == '{' || c == '}'
|| c == '[' || c == ']')
{
quote = true;
break;
}
}
}
public override string ToString() => quote ? $"'{Name}'" : Name;
}
}