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
{
22 public MalException(MalVal
value) {
25 public MalException(string value) {
26 this.value = new MalString(value);
28 public MalVal
getValue() { return value; }
35 public static bool _equal_Q(MalVal a
, MalVal b
) {
36 Type ota
= a
.GetType(), otb
= b
.GetType();
38 (a
is MalList
&& b
is MalList
))) {
41 if (a
is MalInteger
) {
42 return ((MalInteger
)a
).getValue() ==
43 ((MalInteger
)b
).getValue();
44 } else if (a
is MalSymbol
) {
45 return ((MalSymbol
)a
).getName() ==
46 ((MalSymbol
)b
).getName();
47 } else if (a
is MalString
) {
48 return ((MalString
)a
).getValue() ==
49 ((MalString
)b
).getValue();
50 } else if (a
is MalList
) {
51 if (((MalList
)a
).size() != ((MalList
)b
).size()) {
54 for (int i
=0; i
<((MalList
)a
).size(); i
++) {
55 if (! _equal_Q(((MalList
)a
)[i
], ((MalList
)b
)[i
])) {
67 public abstract class MalVal
{
68 // Default is just to call regular toString()
69 public virtual string ToString(bool print_readably
) {
70 return this.ToString();
72 public virtual bool list_Q() { return false; }
75 public class MalConstant
: MalVal
{
77 public MalConstant(string name
) { value = name; }
78 public MalConstant
copy() { return this; }
80 public override string ToString() {
83 public override string ToString(bool print_readably
) {
88 static public MalConstant Nil
= new MalConstant("nil");
89 static public MalConstant True
= new MalConstant("true");
90 static public MalConstant False
= new MalConstant("false");
92 public class MalInteger
: MalVal
{
94 public MalInteger(int v
) { value = v; }
95 public MalInteger
copy() { return this; }
97 public int getValue() { return value; }
98 public override string ToString() {
99 return value.ToString();
101 public override string ToString(bool print_readably
) {
102 return value.ToString();
104 public static MalConstant
operator <(MalInteger a
, MalInteger b
) {
105 return a
.getValue() < b
.getValue() ? True
: False
;
107 public static MalConstant
operator <=(MalInteger a
, MalInteger b
) {
108 return a
.getValue() <= b
.getValue() ? True
: False
;
110 public static MalConstant
operator >(MalInteger a
, MalInteger b
) {
111 return a
.getValue() > b
.getValue() ? True
: False
;
113 public static MalConstant
operator >=(MalInteger a
, MalInteger b
) {
114 return a
.getValue() >= b
.getValue() ? True
: False
;
116 public static MalInteger
operator +(MalInteger a
, MalInteger b
) {
117 return new MalInteger(a
.getValue() + b
.getValue());
119 public static MalInteger
operator -(MalInteger a
, MalInteger b
) {
120 return new MalInteger(a
.getValue() - b
.getValue());
122 public static MalInteger
operator *(MalInteger a
, MalInteger b
) {
123 return new MalInteger(a
.getValue() * b
.getValue());
125 public static MalInteger
operator /(MalInteger a
, MalInteger b
) {
126 return new MalInteger(a
.getValue() / b
.getValue());
130 public class MalSymbol
: MalVal
{
132 public MalSymbol(string v
) { value = v; }
133 public MalSymbol
copy() { return this; }
135 public string getName() { return value; }
136 public override string ToString() {
139 public override string ToString(bool print_readably
) {
144 public class MalString
: MalVal
{
146 public MalString(string v
) { value = v; }
147 public MalString
copy() { return this; }
149 public string getValue() { return value; }
150 public override string ToString() {
151 return "\"" + value + "\"";
153 public override string ToString(bool print_readably
) {
154 if (print_readably
) {
155 return "\"" + value.Replace("\\", "\\\\")
156 .Replace("\"", "\\\"")
157 .Replace("\n", "\\n") + "\"";
166 public class MalList
: MalVal
{
167 public string start
= "(", end
= ")";
170 value = new List
<MalVal
>();
172 public MalList(List
<MalVal
> val
) {
175 public MalList(params MalVal
[] mvs
) {
176 value = new List
<MalVal
>();
180 public MalList
copy() {
181 return (MalList
)this.MemberwiseClone();
184 public List
<MalVal
> getValue() { return value; }
185 public override bool list_Q() { return true; }
187 public override string ToString() {
188 return start
+ printer
.join(value, " ", true) + end
;
190 public override string ToString(bool print_readably
) {
191 return start
+ printer
.join(value, " ", print_readably
) + end
;
194 public MalList
conj_BANG(params MalVal
[] mvs
) {
195 for (int i
= 0; i
< mvs
.Length
; i
++) {
201 public int size() { return value.Count; }
202 public MalVal
nth(int idx
) { return value[idx]; }
203 public MalVal
this[int idx
] {
204 get { return value[idx]; }
206 public MalList
rest() {
208 return new MalList(value.GetRange(1, value.Count
-1));
210 return new MalList();
213 public virtual MalList
slice(int start
) {
214 return new MalList(value.GetRange(start
, value.Count
-start
));
216 public virtual MalList
slice(int start
, int end
) {
217 return new MalList(value.GetRange(start
, end
-start
));
222 public class MalVector
: MalList
{
223 // Same implementation except for instantiation methods
224 public MalVector() :base() {
228 public MalVector(List
<MalVal
> val
)
234 public MalVector(MalVal[] mvs) : base(mvs.ToArray()) {
239 public new MalVector
copy() {
240 return (MalVector
)this.MemberwiseClone();
243 public override bool list_Q() { return false; }
245 public override MalList
slice(int start
, int end
) {
246 var val
= this.getValue();
247 return new MalVector(val
.GetRange(start
, val
.Count
-start
));
251 public class MalHashMap
: MalVal
{
252 Dictionary
<string, MalVal
> value;
253 public MalHashMap(Dictionary
<string, MalVal
> val
) {
256 public MalHashMap(MalList lst
) {
257 value = new Dictionary
<String
, MalVal
>();
258 assoc_BANG(lst
.getValue().ToArray());
261 public MalHashMap(params MalVal[] mvs) {
262 value = new Dictionary<String, MalVal>();
266 public MalHashMap
copy() {
267 return (MalHashMap
)this.MemberwiseClone();
270 public Dictionary
<string, MalVal
> getValue() { return value; }
272 public override string ToString() {
273 return "{" + printer.join(value, " ", true) + "}";
275 public override string ToString(bool print_readably
) {
276 return "{" + printer.join(value, " ", print_readably) + "}";
280 public Set _entries() {
281 return value.entrySet();
285 public MalHashMap
assoc_BANG(params MalVal
[] mvs
) {
286 for (int i
=0; i
<mvs
.Length
; i
+=2) {
287 value.Add(((MalString
)mvs
[i
]).getValue(), mvs
[i
+1]);
293 public class MalFunction
: MalVal
{
294 Func
<MalList
, MalVal
> fn
= null;
296 Mal
.env
.Env env
= null;
298 public MalFunction(Func
<MalList
, MalVal
> fn
) {
301 public MalFunction(MalVal ast
, Mal
.env
.Env env
, MalList fparams
,
302 Func
<MalList
, MalVal
> fn
) {
306 this.fparams
= fparams
;
309 public override string ToString() {
311 return "<fn* " + Mal
.printer
._pr_str(fparams
,true) +
312 " " + Mal
.printer
._pr_str(ast
, true) + ">";
314 return "<builtin_function " + fn
.ToString() + ">";
318 public MalVal
apply(MalList args
) {
322 public MalVal
getAst() { return ast; }
323 public Mal
.env
.Env
getEnv() { return env; }
324 public MalList
getFParams() { return fparams; }
325 public Mal
.env
.Env
genEnv(MalList args
) {
326 return new Mal
.env
.Env(env
, fparams
, args
);