-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLispPrinter.cpp
79 lines (68 loc) · 1.67 KB
/
LispPrinter.cpp
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
#include <cctype>
#include "LispNil.h"
#include "LispFixNum.h"
#include "LispFloatNum.h"
#include "LispString.h"
#include "LispChar.h"
#include "LispSymbol.h"
#include "LispReader.h"
#include "LispCons.h"
#include "LispPrinter.h"
using namespace std;
namespace Lisp {
Printer* Printer::printer = NULL;
Printer::Printer(ostream& output) : output_(output)
{
if (printer != NULL)
return;
printer = this;
}
Printer::~Printer()
{
printer = NULL;
}
void Printer::print_cons(LispObjRef obj) {
print(car(obj));
LispObjRef next(cdr(obj));
if (is_cons(next)) {
output_ << " ";
print_cons(next);
return;
}
if (is_nil(next)) {
return;
}
output_ << " . ";
print(next);
}
void Printer::print(LispObjRef obj) {
if (is_nil(obj))
output_ << "NIL";
else if (is_fixnum(obj))
output_ << get_ctype<FixnumType>(obj); // (CFixnum)(boost::get<FixnumType>(*obj));
else if (is_floatnum(obj))
output_ << get_ctype<FloatnumType>(obj); //(CFloatnum)(boost::get<FloatnumType>(*obj));
else if (is_string(obj))
output_ << "\"" << get_ctype<StringType>(obj) << "\""; // ""(CString)(boost::get<StringType>(*obj)) << "\"";
else if (is_symbol(obj))
output_ << get_ctype<SymbolType>(obj).name; // static_cast<LispSymbol>(boost::get<SymbolType>(*obj)).first;
else if (is_cons(obj)) {
output_ << "(";
print_cons(obj);
output_ << ")";
} else if (is_char(obj)) {
CChar c = get_ctype<CharType>(obj);
if (isprint(c)) {
output_ << c;
} else {
output_ << "#" << std::hex << (int) c << std::dec;
}
}
else
output_ << "#UNPRINTABLE#";
}
void Printer::operator()(LispObjRef obj) {
print(obj);
output_ << endl;
}
}