gensym: hide the counter in an environment, define inc in stepA.
[jackhill/mal.git] / dart / printer.dart
1 import 'types.dart';
2
3 String pr_str(MalType data, {bool print_readably: true}) {
4 if (data is MalSymbol) {
5 return data.value;
6 } else if (data is MalInt) {
7 return '${data.value}';
8 } else if (data is MalList) {
9 var printedElements =
10 data.elements.map((e) => pr_str(e, print_readably: print_readably));
11 return '(${printedElements.join(" ")})';
12 } else if (data is MalVector) {
13 var printedElements =
14 data.elements.map((e) => pr_str(e, print_readably: print_readably));
15 return '[${printedElements.join(" ")}]';
16 } else if (data is MalHashMap) {
17 var printedElements = <String>[];
18 data.value.forEach((key, value) {
19 printedElements.add(pr_str(key, print_readably: print_readably));
20 printedElements.add(pr_str(value, print_readably: print_readably));
21 });
22 return '{${printedElements.join(" ")}}';
23 } else if (data is MalString) {
24 if (print_readably) {
25 var readableValue = data.value
26 .replaceAll('\\', r'\\')
27 .replaceAll('\n', r'\n')
28 .replaceAll('\"', r'\"');
29 return '"$readableValue"';
30 } else {
31 return '${data.value}';
32 }
33 } else if (data is MalKeyword) {
34 return ':${data.value}';
35 } else if (data is MalBool) {
36 return '${data.value}';
37 } else if (data is MalNil) {
38 return 'nil';
39 } else if (data is MalBuiltin) {
40 return '#<built in function>';
41 } else if (data is MalClosure) {
42 return '#<function>';
43 } else if (data is MalAtom) {
44 return "(atom ${pr_str(data.value, print_readably: print_readably)})";
45 }
46 throw new ArgumentError("Unrecognized type: ${data.runtimeType}");
47 }