Synopsis - Cross-Reference

File: src/Synopsis/PTree/Writer.cc
 1//
 2// Copyright (C) 2004 Stefan Seefeld
 3// All rights reserved.
 4// Licensed to the public under the terms of the GNU LGPL (>= 2),
 5// see the file COPYING for details.
 6//
 7
 8#include <Synopsis/PTree/Writer.hh>
 9#include <stdexcept>
10
11using namespace Synopsis;
12using namespace PTree;
13
14Writer::Writer(std::ostream &os)
15  : my_os(os),
16    my_indent(0),
17    my_lines(0)
18{
19}
20
21unsigned long Writer::write(Node const *n)
22{
23  const_cast<Node *>(n)->accept(this);
24  unsigned long lines = my_lines;
25  my_lines = 0;
26  return lines;
27}
28
29void Writer::visit(Atom *a)
30{
31  const char *ptr = a->position();
32  size_t len = a->length();
33  while(len-- > 0)
34  {
35    char c = *ptr++;
36    if(c == '\n') newline();
37    else my_os.put(c);
38  }
39}
40
41void Writer::visit(List *l) 
42{
43  Node *p = l;
44  while(true)
45  {
46    Node *head = p->car();
47    if(head != 0) head->accept(this);
48    p = p->cdr();
49    if(!p) break;
50    else if(p->is_atom())
51      throw std::runtime_error("Writer::visit(List *): not list");
52    else my_os.put(' ');
53  }
54}
55
56void Writer::visit(Brace *l)
57{
58  my_os << '{';
59  ++my_indent;
60  Node *p = cadr(l);
61  while(p)
62  {
63    if(p->is_atom())
64      throw std::runtime_error("Writer::visit(Brace *): non list");
65    else
66    {
67      newline();
68      Node *q = p->car();
69      p = p->cdr();
70      if(q) q->accept(this);
71    }
72  }
73  --my_indent;
74  newline();
75  my_os << '}';
76}
77
78void Writer::newline()
79{
80  my_os.put('\n');
81  for(size_t i = 0; i != my_indent; ++i) my_os.put(' ');
82  ++my_lines;
83}
84