2 using System
.Collections
.Generic
;
10 public class MalThrowable
: Exception
{
11 public MalThrowable() : base() { }
12 public MalThrowable(string msg
) : base(msg
) { }
14 public class MalError
: MalThrowable
{
15 public MalError(string msg
) :base(msg
) { }
17 public class MalContinue
: MalThrowable { }
19 // Thrown by throw function
20 public class MalException
: MalThrowable
{
23 public MalException(MalVal
value) {
26 public MalException(string value) :base(value) {
27 this.value = new MalString(value);
29 public MalVal
getValue() { return value; }
36 public static bool _equal_Q(MalVal a
, MalVal b
) {
37 Type ota
= a
.GetType(), otb
= b
.GetType();
39 (a
is MalList
&& b
is MalList
))) {
42 if (a
is MalInteger
) {
43 return ((MalInteger
)a
).getValue() ==
44 ((MalInteger
)b
).getValue();
45 } else if (a
is MalSymbol
) {
46 return ((MalSymbol
)a
).getName() ==
47 ((MalSymbol
)b
).getName();
48 } else if (a
is MalString
) {
49 return ((MalString
)a
).getValue() ==
50 ((MalString
)b
).getValue();
51 } else if (a
is MalList
) {
52 if (((MalList
)a
).size() != ((MalList
)b
).size()) {
55 for (int i
=0; i
<((MalList
)a
).size(); i
++) {
56 if (! _equal_Q(((MalList
)a
)[i
], ((MalList
)b
)[i
])) {
68 public abstract class MalVal
{
70 public virtual MalVal
copy() {
71 return (MalVal
)this.MemberwiseClone();
74 // Default is just to call regular toString()
75 public virtual string ToString(bool print_readably
) {
76 return this.ToString();
78 public MalVal
getMeta() { return meta; }
79 public MalVal
setMeta(MalVal m
) { meta = m; return this; }
80 public virtual bool list_Q() { return false; }
83 public class MalConstant
: MalVal
{
85 public MalConstant(string name
) { value = name; }
86 public new MalConstant
copy() { return this; }
88 public override string ToString() {
91 public override string ToString(bool print_readably
) {
96 static public MalConstant Nil
= new MalConstant("nil");
97 static public MalConstant True
= new MalConstant("true");
98 static public MalConstant False
= new MalConstant("false");
100 public class MalInteger
: MalVal
{
102 public MalInteger(int v
) { value = v; }
103 public new MalInteger
copy() { return this; }
105 public int getValue() { return value; }
106 public override string ToString() {
107 return value.ToString();
109 public override string ToString(bool print_readably
) {
110 return value.ToString();
112 public static MalConstant
operator <(MalInteger a
, MalInteger b
) {
113 return a
.getValue() < b
.getValue() ? True
: False
;
115 public static MalConstant
operator <=(MalInteger a
, MalInteger b
) {
116 return a
.getValue() <= b
.getValue() ? True
: False
;
118 public static MalConstant
operator >(MalInteger a
, MalInteger b
) {
119 return a
.getValue() > b
.getValue() ? True
: False
;
121 public static MalConstant
operator >=(MalInteger a
, MalInteger b
) {
122 return a
.getValue() >= b
.getValue() ? True
: False
;
124 public static MalInteger
operator +(MalInteger a
, MalInteger b
) {
125 return new MalInteger(a
.getValue() + b
.getValue());
127 public static MalInteger
operator -(MalInteger a
, MalInteger b
) {
128 return new MalInteger(a
.getValue() - b
.getValue());
130 public static MalInteger
operator *(MalInteger a
, MalInteger b
) {
131 return new MalInteger(a
.getValue() * b
.getValue());
133 public static MalInteger
operator /(MalInteger a
, MalInteger b
) {
134 return new MalInteger(a
.getValue() / b
.getValue());
138 public class MalSymbol
: MalVal
{
140 public MalSymbol(string v
) { value = v; }
141 public new MalSymbol
copy() { return this; }
143 public string getName() { return value; }
144 public override string ToString() {
147 public override string ToString(bool print_readably
) {
152 public class MalString
: MalVal
{
154 public MalString(string v
) { value = v; }
155 public new MalString
copy() { return this; }
157 public string getValue() { return value; }
158 public override string ToString() {
159 return "\"" + value + "\"";
161 public override string ToString(bool print_readably
) {
162 if (print_readably
) {
163 return "\"" + value.Replace("\\", "\\\\")
164 .Replace("\"", "\\\"")
165 .Replace("\n", "\\n") + "\"";
174 public class MalList
: MalVal
{
175 public string start
= "(", end
= ")";
178 value = new List
<MalVal
>();
180 public MalList(List
<MalVal
> val
) {
183 public MalList(params MalVal
[] mvs
) {
184 value = new List
<MalVal
>();
188 public List
<MalVal
> getValue() { return value; }
189 public override bool list_Q() { return true; }
191 public override string ToString() {
192 return start
+ printer
.join(value, " ", true) + end
;
194 public override string ToString(bool print_readably
) {
195 return start
+ printer
.join(value, " ", print_readably
) + end
;
198 public MalList
conj_BANG(params MalVal
[] mvs
) {
199 for (int i
= 0; i
< mvs
.Length
; i
++) {
205 public int size() { return value.Count; }
206 public MalVal
nth(int idx
) {
207 return value.Count
> 0 ? value[idx
] : Nil
;
209 public MalVal
this[int idx
] {
210 get { return value.Count > 0 ? value[idx] : Nil; }
212 public MalList
rest() {
214 return new MalList(value.GetRange(1, value.Count
-1));
216 return new MalList();
219 public virtual MalList
slice(int start
) {
220 return new MalList(value.GetRange(start
, value.Count
-start
));
222 public virtual MalList
slice(int start
, int end
) {
223 return new MalList(value.GetRange(start
, end
-start
));
228 public class MalVector
: MalList
{
229 // Same implementation except for instantiation methods
230 public MalVector() :base() {
234 public MalVector(List
<MalVal
> val
)
240 public override bool list_Q() { return false; }
242 public override MalList
slice(int start
, int end
) {
243 var val
= this.getValue();
244 return new MalVector(val
.GetRange(start
, val
.Count
-start
));
248 public class MalHashMap
: MalVal
{
249 Dictionary
<string, MalVal
> value;
250 public MalHashMap(Dictionary
<string, MalVal
> val
) {
253 public MalHashMap(MalList lst
) {
254 value = new Dictionary
<String
, MalVal
>();
257 public new MalHashMap
copy() {
258 var new_self
= (MalHashMap
)this.MemberwiseClone();
259 new_self
.value = new Dictionary
<string, MalVal
>(value);
263 public Dictionary
<string, MalVal
> getValue() { return value; }
265 public override string ToString() {
266 return "{" + printer.join(value, " ", true) + "}";
268 public override string ToString(bool print_readably
) {
269 return "{" + printer.join(value, " ", print_readably) + "}";
272 public MalHashMap
assoc_BANG(MalList lst
) {
273 for (int i
=0; i
<lst
.size(); i
+=2) {
274 value[((MalString
)lst
[i
]).getValue()] = lst
[i
+1];
279 public MalHashMap
dissoc_BANG(MalList lst
) {
280 for (int i
=0; i
<lst
.size(); i
++) {
281 value.Remove(((MalString
)lst
[i
]).getValue());
287 public class MalAtom
: MalVal
{
289 public MalAtom(MalVal
value) { this.value = value; }
290 //public MalAtom copy() { return new MalAtom(value); }
291 public MalVal
getValue() { return value; }
292 public MalVal
setValue(MalVal
value) { return this.value = value; }
293 public override string ToString() {
294 return "(atom " + printer
._pr_str(value, true) + ")";
296 public override string ToString(Boolean print_readably
) {
297 return "(atom " + printer
._pr_str(value, print_readably
) + ")";
301 public class MalFunction
: MalVal
{
302 Func
<MalList
, MalVal
> fn
= null;
304 Mal
.env
.Env env
= null;
307 public MalFunction(Func
<MalList
, MalVal
> fn
) {
310 public MalFunction(MalVal ast
, Mal
.env
.Env env
, MalList fparams
,
311 Func
<MalList
, MalVal
> fn
) {
315 this.fparams
= fparams
;
318 public override string ToString() {
320 return "<fn* " + Mal
.printer
._pr_str(fparams
,true) +
321 " " + Mal
.printer
._pr_str(ast
, true) + ">";
323 return "<builtin_function " + fn
.ToString() + ">";
327 public MalVal
apply(MalList args
) {
331 public MalVal
getAst() { return ast; }
332 public Mal
.env
.Env
getEnv() { return env; }
333 public MalList
getFParams() { return fparams; }
334 public Mal
.env
.Env
genEnv(MalList args
) {
335 return new Mal
.env
.Env(env
, fparams
, args
);
337 public bool isMacro() { return macro; }
338 public void setMacro() { macro = true; }