File: Synopsis/PTree/Node.hh
  1//
  2// Copyright (C) 1997-2000 Shigeru Chiba
  3// Copyright (C) 2000 Stefan Seefeld
  4// Copyright (C) 2000 Stephen Davies
  5// All rights reserved.
  6// Licensed to the public under the terms of the GNU LGPL (>= 2),
  7// see the file COPYING for details.
  8//
  9#ifndef Synopsis_PTree_Node_hh_
 10#define Synopsis_PTree_Node_hh_
 11
 12#include <Synopsis/PTree/GC.hh>
 13#include <Synopsis/PTree/Encoding.hh>
 14#include <Synopsis/PTree/Visitor.hh>
 15#include <Synopsis/Token.hh>
 16#include <ostream>
 17#include <iterator>
 18
 19namespace Synopsis
 20{
 21namespace PTree
 22{
 23
 24class Node : public LightObject 
 25{
 26public:
 27  virtual ~Node() {}
 28  virtual bool is_atom() const = 0;
 29  virtual void accept(Visitor *visitor) = 0;
 30
 31  //. return the start address of this Ptree in the buffer
 32  const char *begin() const;
 33  //. return the one-past-the-end address of this Ptree in the buffer
 34  const char *end() const;
 35
 36  const char *position() const { return my_data.leaf.position;}
 37  size_t length() const { return my_data.leaf.length;}
 38
 39  const Node *car() const { return my_data.nonleaf.child;}
 40  Node *car() { return my_data.nonleaf.child;}
 41  const Node *cdr() const { return my_data.nonleaf.next;}
 42  Node *cdr() { return my_data.nonleaf.next;}
 43  void set_car(Node *p) { my_data.nonleaf.child = p;}
 44  void set_cdr(Node *p) { my_data.nonleaf.next = p;}
 45
 46  virtual Encoding encoded_type() const { return Encoding();}
 47  virtual Encoding encoded_name() const { return Encoding();}
 48
 49protected:
 50  //. used by Atom
 51  Node(const char *ptr, size_t len);
 52  //. used by List
 53  Node(Node *p, Node *q);
 54
 55private:
 56  union 
 57  {
 58    struct 
 59    {
 60      Node *child;
 61      Node *next;
 62    } nonleaf;
 63    struct 
 64    {
 65      const char* position;
 66      int  length;
 67    } leaf;
 68  } my_data;
 69};
 70
 71class Iterator : public LightObject 
 72{
 73public:
 74  Iterator(Node *p) { ptree = p;}
 75  Node *operator () () { return pop();}
 76  Node *pop();
 77  bool next(Node *&);
 78  void reset(Node *p) { ptree = p;}
 79
 80  Node *get() { return ptree ? ptree->car() : 0;}
 81  Node *operator *() { return get();}
 82  Node *operator ++() { pop(); return get();}
 83  Node *operator ++(int) { return pop();}
 84  bool empty() { return ptree == 0;}
 85private:
 86  Node *ptree;
 87};
 88
 89class Array : public LightObject 
 90{
 91public:
 92  Array(size_t = 8);
 93  size_t number() { return num;}
 94  Node *&operator [] (size_t index) { return ref(index);}
 95  Node *&ref(size_t index);
 96  void append(Node *);
 97  void clear() { num = 0;}
 98  Node *all();
 99private:
100  size_t num, size;
101  Node **array;
102  Node *default_buf[8];
103};
104
105class Atom : public Node
106{
107public:
108  Atom(const char *p, size_t l) : Node(p, l) {}
109  Atom(const Token &t) : Node(t.ptr, t.length) {}
110  bool is_atom() const { return true;}
111  virtual void accept(Visitor *visitor) { visitor->visit(this);}
112};
113
114class List : public Node
115{
116public:
117  List(Node *p, Node *q) : Node(p, q) {}
118  bool is_atom() const { return false;}
119  virtual void accept(Visitor *visitor) { visitor->visit(this);}
120};
121
122}
123}
124
125#endif