Synopsis - Cross-Reference

File: src/Synopsis/PTree/Node.cc
  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#include <Synopsis/PTree/Node.hh>
 10#include <Synopsis/PTree/Encoding.hh>
 11#include <Synopsis/PTree/operations.hh>
 12#include <Synopsis/Buffer.hh>
 13#include <iostream>
 14#include <sstream>
 15#include <cstring>
 16#include <cassert>
 17#include <stdexcept>
 18
 19#if defined(_MSC_VER) || defined(IRIX_CC) || defined(__GLIBC__)
 20#include <stdlib.h>		// for exit()
 21#endif
 22
 23using namespace Synopsis;
 24using namespace PTree;
 25
 26namespace
 27{
 28  //. Make sure the garbage collector is properly initialized.
 29  struct Initializer
 30  {
 31    Initializer() { init_gc();}
 32  } initializer;
 33}
 34
 35
 36Node::Node(const char *ptr, size_t len)
 37{
 38  my_data.leaf.position = ptr;
 39  my_data.leaf.length = len;
 40}
 41
 42Node::Node(Node *p, Node *q)
 43{
 44  my_data.nonleaf.child = p;
 45  my_data.nonleaf.next = q;
 46}
 47
 48const char *Node::begin() const
 49{
 50  if (is_atom()) return position();
 51  else
 52  {
 53    for (const Node *p = this; p; p = p->cdr())
 54    {
 55      const char *b = p->car() ? p->car()->begin() : 0;
 56      if (b) return b;
 57    }
 58    return 0;
 59  }
 60}
 61
 62const char *Node::end() const
 63{
 64  if (is_atom()) return position() + length();
 65  else
 66  {
 67    int n = PTree::length(this);
 68    while(n > 0)
 69    {
 70      const char *e = PTree::nth(this, --n)->end();
 71      if (e) return e;
 72    }    
 73    return 0;
 74  }
 75}
 76
 77namespace Synopsis
 78{
 79// error messages
 80
 81void MopErrorMessage(const char* where, const char* msg)
 82{
 83    std::cerr << "MOP error: in " << where << ", " << msg << '\n';
 84    exit(1);
 85}
 86
 87void MopErrorMessage2(const char* msg1, const char* msg2)
 88{
 89    std::cerr << "MOP error: " << msg1 << msg2 << '\n';
 90    exit(1);
 91}
 92
 93void MopWarningMessage(const char* where, const char* msg)
 94{
 95    std::cerr << "MOP warning: in " << where << ", " << msg << '\n';
 96}
 97
 98void MopWarningMessage2(const char* msg1, const char* msg2)
 99{
100    std::cerr << "MOP warning: " << msg1 << msg2 << '\n';
101}
102
103void MopMoreWarningMessage(const char* msg1, const char* msg2)
104{
105    std::cerr << "             " << msg1;
106    if(msg2 != 0)
107	std::cerr << msg2;
108
109    std::cerr << '\n';
110}
111}
112
113Node *Iterator::pop()
114{
115  if(!ptree) return 0;
116  else
117  {
118    Node *p = ptree->car();
119    ptree = ptree->cdr();
120    return p;
121  }
122}
123
124bool Iterator::next(Node *& car)
125{
126  if(!ptree) return false;
127  else
128  {
129    car = ptree->car();
130    ptree = ptree->cdr();
131    return true;
132  }
133}
134
135Array::Array(size_t s)
136{
137  num = 0;
138  if(s > 8)
139  {
140    size = s;
141    array = new (GC) Node *[s];
142  }
143  else
144  {
145    size = 8;
146    array = default_buf;
147  }
148}
149
150void Array::append(Node *p)
151{
152  if(num >= size)
153  {
154    size += 8;
155    Node **a = new (GC) Node *[size];
156    memmove(a, array, size_t(num * sizeof(Node *)));
157    array = a;
158  }
159  array[num++] = p;
160}
161
162Node *&Array::ref(size_t i)
163{
164  if(i < num) return array[i];
165  else throw std::range_error("Array: out of range");
166}
167
168Node *Array::all()
169{
170  Node *lst = 0;
171  for(int i = number() - 1; i >= 0; --i)
172    lst = cons(ref(i), lst);
173  return lst;
174}