Package aterm.pure

Source Code of aterm.pure.ATermReader

/*
* Copyright (c) 2002-2007, CWI and INRIA
*
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of the University of California, Berkeley nor the
*       names of its contributors may be used to endorse or promote products
*       derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package aterm.pure;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;

import shared.SharedObject;
import shared.SharedObjectFactory;
import aterm.AFun;
import aterm.ATerm;
import aterm.ATermAppl;
import aterm.ATermBlob;
import aterm.ATermFactory;
import aterm.ATermInt;
import aterm.ATermList;
import aterm.ATermLong;
import aterm.ATermPlaceholder;
import aterm.ATermReal;
import aterm.ParseError;
import aterm.pure.binary.BAFReader;
import aterm.pure.binary.BinaryReader;

public class PureFactory extends SharedObjectFactory implements ATermFactory {

  private static int DEFAULT_TERM_TABLE_SIZE = 16; // means 2^16 entries

  private final ATermList empty;

  static boolean isBase64(int c) {
    return Character.isLetterOrDigit(c) || c == '+' || c == '/';
  }

  static public int abbrevSize(int abbrev) {
    int size = 1;

    if (abbrev == 0) {
      return 2;
    }

    while (abbrev > 0) {
      size++;
      abbrev /= 64;
    }

    return size;
  }

  public PureFactory() {
    this(DEFAULT_TERM_TABLE_SIZE);
  }

  public PureFactory(int termTableSize) {
    super(termTableSize);

    ATermListImpl protoList = new ATermListImpl(this);

    /*
     * 240146486 is a fix-point hashcode such that
     * empty.hashcode = empty.getAnnotations().hashCode
     * this magic value can be found using: findEmptyHashCode()
     */
    protoList.init(240146486, null, null, null);
    empty = (ATermList) build(protoList);
    //int magicHash = ((ATermListImpl) empty).findEmptyHashCode();
    ((ATermListImpl) empty).init(240146486, empty, null, null);

  }

  public ATermInt makeInt(int val) {
    return makeInt(val, empty);
  }

  public ATermLong makeLong(long val) {
    return makeLong(val, empty);
  }

  public ATermReal makeReal(double val) {
    return makeReal(val, empty);
  }

  public ATermList makeList() {
    return empty;
  }

  public ATermList makeList(ATerm singleton) {
    return makeList(singleton, empty, empty);
  }

  public ATermList makeList(ATerm first, ATermList next) {
    return makeList(first, next, empty);
  }

  public ATermPlaceholder makePlaceholder(ATerm type) {
    return makePlaceholder(type, empty);
  }

  public ATermBlob makeBlob(byte[] data) {
    return makeBlob(data, empty);
  }

  public AFun makeAFun(String name, int arity, boolean isQuoted) {
      return (AFun) build(new AFunImpl(this, name, arity, isQuoted));
  }

  public ATermInt makeInt(int value, ATermList annos) {
      return (ATermInt) build(new ATermIntImpl(this, annos, value));
  }

  public ATermLong makeLong(long value, ATermList annos) {
      return (ATermLong) build(new ATermLongImpl(this, annos, value));
  }

  public ATermReal makeReal(double value, ATermList annos) {
      return (ATermReal) build(new ATermRealImpl(this, annos, value));
  }

  public ATermPlaceholder makePlaceholder(ATerm type, ATermList annos) {
      return (ATermPlaceholder) build(new ATermPlaceholderImpl(this, annos, type));
  }

  public ATermBlob makeBlob(byte[] data, ATermList annos) {
      return (ATermBlob) build(new ATermBlobImpl(this, annos, data));
  }

  public ATermList makeList(ATerm first, ATermList next, ATermList annos) {
      return (ATermList) build(new ATermListImpl(this, annos, first, next));
  }

  private static ATerm[] array0 = new ATerm[0];

  public ATermAppl makeAppl(AFun fun, ATerm[] args) {
    return makeAppl(fun, args, empty);
  }

  public ATermAppl makeAppl(AFun fun, ATerm[] args, ATermList annos) {
      return (ATermAppl) build(new ATermApplImpl(this, annos, fun, args));
  }

  public ATermAppl makeApplList(AFun fun, ATermList list) {
    return makeApplList(fun, list, empty);
  }

  public ATermAppl makeApplList(AFun fun, ATermList list, ATermList annos) {
    ATerm[] arg_array;

    arg_array = new ATerm[list.getLength()];

    int i = 0;
    while (!list.isEmpty()) {
      arg_array[i++] = list.getFirst();
      list = list.getNext();
    }
    return makeAppl(fun, arg_array, annos);
  }

  public ATermAppl makeAppl(AFun fun) {
    return makeAppl(fun, array0);
  }

  public ATermAppl makeAppl(AFun fun, ATerm arg) {
    ATerm[] argarray1 = new ATerm[] { arg };
    return makeAppl(fun, argarray1);
  }

  public ATermAppl makeAppl(AFun fun, ATerm arg1, ATerm arg2) {
    ATerm[] argarray2 = new ATerm[] { arg1, arg2 };
    return makeAppl(fun, argarray2);
  }

  public ATermAppl makeAppl(AFun fun, ATerm arg1, ATerm arg2, ATerm arg3) {
    ATerm[] argarray3 = new ATerm[] { arg1, arg2, arg3 };
    return makeAppl(fun, argarray3);
  }

  public ATermAppl makeAppl(AFun fun, ATerm arg1, ATerm arg2, ATerm arg3,
      ATerm arg4) {
    ATerm[] argarray4 = new ATerm[] { arg1, arg2, arg3, arg4 };
    return makeAppl(fun, argarray4);
  }

  public ATermAppl makeAppl(AFun fun, ATerm arg1, ATerm arg2, ATerm arg3,
      ATerm arg4, ATerm arg5) {
    ATerm[] argarray5 = new ATerm[] { arg1, arg2, arg3, arg4, arg5 };
    return makeAppl(fun, argarray5);
  }

  public ATermAppl makeAppl(AFun fun, ATerm arg1, ATerm arg2, ATerm arg3,
      ATerm arg4, ATerm arg5, ATerm arg6) {
    ATerm[] args = { arg1, arg2, arg3, arg4, arg5, arg6 };
    return makeAppl(fun, args);
  }

  public ATermAppl makeAppl(AFun fun, ATerm arg1, ATerm arg2, ATerm arg3,
      ATerm arg4, ATerm arg5, ATerm arg6, ATerm arg7) {
    ATerm[] args = { arg1, arg2, arg3, arg4, arg5, arg6, arg7 };
    return makeAppl(fun, args);
  }

  public ATermList getEmpty() {
    return empty;
  }

  private ATerm parseAbbrev(ATermReader reader) throws IOException {
    ATerm result;
    int abbrev;

    int c = reader.read();

    abbrev = 0;
    while (isBase64(c)) {
      abbrev *= 64;
      if (c >= 'A' && c <= 'Z') {
        abbrev += c - 'A';
      } else if (c >= 'a' && c <= 'z') {
        abbrev += c - 'a' + 26;
      } else if (c >= '0' && c <= '9') {
        abbrev += c - '0' + 52;
      } else if (c == '+') {
        abbrev += 62;
      } else if (c == '/') {
        abbrev += 63;
      } else {
        throw new RuntimeException("not a base-64 digit: " + c);
      }

      c = reader.read();
    }

    result = reader.getTerm(abbrev);

    return result;
  }

  private ATerm parseNumber(ATermReader reader) throws IOException {
  StringBuilder str = new StringBuilder();
    ATerm result;

    do {
      str.append((char) reader.getLastChar());
    } while (Character.isDigit(reader.read()));

    if (reader.getLastChar() != '.' && reader.getLastChar() != 'e'
        && reader.getLastChar() != 'E' && reader.getLastChar() != 'l'
        && reader.getLastChar() != 'L') {
      int val;
      try {
        val = Integer.parseInt(str.toString());
      } catch (NumberFormatException e) {
        throw new ParseError("malformed int");
      }
      result = makeInt(val);
    } else if (reader.getLastChar() == 'l' || reader.getLastChar() == 'L') {
      reader.read();
      long val;
      try {
        val = Long.parseLong(str.toString());
      } catch (NumberFormatException e) {
        throw new ParseError("malformed long");
      }
      result = makeLong(val);
    } else {
      if (reader.getLastChar() == '.') {
        str.append('.');
        reader.read();
        if (!Character.isDigit(reader.getLastChar()))
          throw new ParseError("digit expected");
        do {
          str.append((char) reader.getLastChar());
        } while (Character.isDigit(reader.read()));
      }
      if (reader.getLastChar() == 'e' || reader.getLastChar() == 'E') {
        str.append((char) reader.getLastChar());
        reader.read();
        if (reader.getLastChar() == '-' || reader.getLastChar() == '+') {
          str.append((char) reader.getLastChar());
          reader.read();
        }
        if (!Character.isDigit(reader.getLastChar()))
          throw new ParseError("digit expected!");
        do {
          str.append((char) reader.getLastChar());
        } while (Character.isDigit(reader.read()));
      }
      double val;
      try {
        val = Double.valueOf(str.toString()).doubleValue();
      } catch (NumberFormatException e) {
        throw new ParseError("malformed real");
      }
      result = makeReal(val);
    }
    return result;
  }

  private String parseId(ATermReader reader) throws IOException {
    int c = reader.getLastChar();
    StringBuilder buf = new StringBuilder(32);

    do {
      buf.append((char) c);
      c = reader.read();
    } while (Character.isLetterOrDigit(c) || c == '_' || c == '-'
        || c == '+' || c == '*' || c == '$');

    return buf.toString();
  }

  private String parseString(ATermReader reader) throws IOException {
    boolean escaped;
    StringBuilder str = new StringBuilder();

    do {
      escaped = false;
      if (reader.read() == '\\') {
        reader.read();
        escaped = true;
      }
     
      int lastChar = reader.getLastChar();
      if(lastChar == -1) throw new ParseError("Unterminated quoted function symbol: " + str);
     
      if (escaped) {
        switch (lastChar) {
          case 'n':
            str.append('\n');
            break;
          case 't':
            str.append('\t');
            break;
          case 'b':
            str.append('\b');
            break;
          case 'r':
            str.append('\r');
            break;
          case 'f':
            str.append('\f');
            break;
          case '\\':
            str.append('\\');
            break;
          case '\'':
            str.append('\'');
            break;
            case '\"':
              str.append('\"');
            break;
          case '0':
          case '1':
          case '2':
          case '3':
          case '4':
          case '5':
          case '6':
          case '7':
            str.append(reader.readOct());
            break;
          default:
            str.append('\\').append((char) reader.getLastChar());
        }
      }else if (lastChar != '\"'){
        str.append((char) lastChar);
      }
    } while (escaped || reader.getLastChar() != '"');

    return str.toString();
  }

  private ATermList parseATerms(ATermReader reader) throws IOException {
    ATerm[] terms = parseATermsArray(reader);
    ATermList result = empty;
    for (int i = terms.length - 1; i >= 0; i--) {
      result = makeList(terms[i], result);
    }

    return result;
  }

  private ATerm[] parseATermsArray(ATermReader reader) throws IOException {
    List<ATerm> list = new ArrayList<ATerm>();
   
    ATerm term = parseFromReader(reader);
    list.add(term);
    while (reader.getLastChar() == ',') {
      reader.readSkippingWS();
      term = parseFromReader(reader);
      list.add(term);
    }

    ATerm[] array = new ATerm[list.size()];
    ListIterator<ATerm> iter = list.listIterator();
    int index = 0;
    while (iter.hasNext()) {
      array[index++] = iter.next();
    }
    return array;
  }

  private ATerm parseFromReader(ATermReader reader) throws IOException {
    ATerm result;
    int c, start, end;
    String funname;

    start = reader.getPosition();
    switch (reader.getLastChar()) {
      case -1:
        throw new ParseError("premature EOF encountered.");

      case '#':
        return parseAbbrev(reader);

      case '[':
        c = reader.readSkippingWS();
        if (c == -1) {
          throw new ParseError("premature EOF encountered.");
        }

        if (c == ']') {
          c = reader.readSkippingWS();
          result = empty;
        } else {
          result = parseATerms(reader);
          if (reader.getLastChar() != ']') {
            throw new ParseError("expected ']' but got '" + (char) reader.getLastChar() + "'");
          }
          c = reader.readSkippingWS();
        }

        break;

      case '<':
        c = reader.readSkippingWS();
        ATerm ph = parseFromReader(reader);

        if (reader.getLastChar() != '>') {
          throw new ParseError("expected '>' but got '" + (char) reader.getLastChar() + "'");
        }

        c = reader.readSkippingWS();

        result = makePlaceholder(ph);

        break;

      case '"':
        funname = parseString(reader);

        c = reader.readSkippingWS();
        if (reader.getLastChar() == '(') {
          c = reader.readSkippingWS();
          if (c == -1) {
            throw new ParseError("premature EOF encountered.");
          }
          if (reader.getLastChar() == ')') {
            result = makeAppl(makeAFun(funname, 0, true));
          } else {
            ATerm[] list = parseATermsArray(reader);

            if (reader.getLastChar() != ')') {
              throw new ParseError("expected ')' but got '" + reader.getLastChar() + "'");
            }
            result = makeAppl(makeAFun(funname, list.length, true), list);
          }
          c = reader.readSkippingWS();
        } else {
          result = makeAppl(makeAFun(funname, 0, true));
        }

        break;

      case '(':
        c = reader.readSkippingWS();
        if (c == -1) {
          throw new ParseError("premature EOF encountered.");
        }
        if (reader.getLastChar() == ')') {
          result = makeAppl(makeAFun("", 0, false));
        } else {
          ATerm[] list = parseATermsArray(reader);

          if (reader.getLastChar() != ')') {
            throw new ParseError("expected ')' but got '" + (char)reader.getLastChar() + "'");
          }
          result = makeAppl(makeAFun("", list.length, false), list);
        }
        c = reader.readSkippingWS();

        break;

      case '-':
      case '0':
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      case '9':
        result = parseNumber(reader);
        c = reader.skipWS();
        break;

      default:
        c = reader.getLastChar();
        if (Character.isLetter(c)) {
          funname = parseId(reader);
          c = reader.skipWS();
          if (reader.getLastChar() == '(') {
            c = reader.readSkippingWS();
            if (c == -1) {
              throw new ParseError("premature EOF encountered.");
            }
            if (reader.getLastChar() == ')') {
              result = makeAppl(makeAFun(funname, 0, false));
            } else {
              ATerm[] list = parseATermsArray(reader);

              if (reader.getLastChar() != ')') {
                throw new ParseError("expected ')' but got '" + (char) reader.getLastChar() + "'");
              }
              result = makeAppl(makeAFun(funname, list.length, false), list);
            }
            c = reader.readSkippingWS();
          } else {
            result = makeAppl(makeAFun(funname, 0, false));
          }
        } else {
          throw new ParseError("illegal character: '" + (char) reader.getLastChar() + "'");
        }
    }

    if (reader.getLastChar() == '{') {
      ATermList annos;
      if (reader.readSkippingWS() == '}') {
        reader.readSkippingWS();
        annos = empty;
      } else {
        annos = parseATerms(reader);
        if (reader.getLastChar() != '}') {
          throw new ParseError("'}' expected '" + (char) reader.getLastChar() + "'");
        }
        reader.readSkippingWS();
      }
      result = result.setAnnotations(annos);
    }

    /* Parse some ToolBus anomalies for backwards compatibility */
    if (reader.getLastChar() == ':') {
      reader.read();
      ATerm anno = parseFromReader(reader);
      result = result.setAnnotation(parse("type"), anno);
    }

    if (reader.getLastChar() == '?') {
      reader.readSkippingWS();
      result = result.setAnnotation(parse("result"), parse("true"));
    }

    end = reader.getPosition();
    reader.storeNextTerm(result, end - start);

    return result;
  }

  public ATerm parse(String trm) {
    try {
      ATermReader reader = new ATermReader(new StringReader(trm), trm.length());
      reader.readSkippingWS();
      ATerm result = parseFromReader(reader);
      return result;
    } catch (IOException e) {
      throw new ParseError("premature end of string");
    }
  }

  public ATerm make(String trm) {
    return parse(trm);
  }

  public ATerm make(String pattern, List<Object> args) {
    return make(parse(pattern), args);
  }

  public ATerm make(String pattern, Object arg1) {
    List<Object> args = new LinkedList<Object>();
    args.add(arg1);
    return make(pattern, args);
  }

  public ATerm make(String pattern, Object arg1, Object arg2) {
    List<Object> args = new LinkedList<Object>();
    args.add(arg1);
    args.add(arg2);
    return make(pattern, args);
  }

  public ATerm make(String pattern, Object arg1, Object arg2, Object arg3) {
    List<Object> args = new LinkedList<Object>();
    args.add(arg1);
    args.add(arg2);
    args.add(arg3);
    return make(pattern, args);
  }

  public ATerm make(String pattern, Object arg1, Object arg2, Object arg3, Object arg4) {
    List<Object> args = new LinkedList<Object>();
    args.add(arg1);
    args.add(arg2);
    args.add(arg3);
    args.add(arg4);
    return make(pattern, args);
  }

  public ATerm make(String pattern, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) {
    List<Object> args = new LinkedList<Object>();
    args.add(arg1);
    args.add(arg2);
    args.add(arg3);
    args.add(arg4);
    args.add(arg5);
    return make(pattern, args);
  }

  public ATerm make(String pattern, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) {
    List<Object> args = new LinkedList<Object>();
    args.add(arg1);
    args.add(arg2);
    args.add(arg3);
    args.add(arg4);
    args.add(arg5);
    args.add(arg6);
    return make(pattern, args);
  }

  public ATerm make(String pattern, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7) {
    List<Object> args = new LinkedList<Object>();
    args.add(arg1);
    args.add(arg2);
    args.add(arg3);
    args.add(arg4);
    args.add(arg5);
    args.add(arg6);
    args.add(arg7);
    return make(pattern, args);
  }

  public ATerm make(ATerm pattern, List<Object> args) {
    return pattern.make(args);
  }

  ATerm parsePattern(String pattern) throws ParseError {
    return parse(pattern);
  }

  protected boolean isDeepEqual(ATermImpl t1, ATerm t2) {
    throw new UnsupportedOperationException("not yet implemented!");
  }

  private ATerm readFromSharedTextFile(ATermReader reader) throws IOException {
    reader.initializeSharing();
    return parseFromReader(reader);
  }

  private ATerm readFromTextFile(ATermReader reader) throws IOException {
    return parseFromReader(reader);
  }

  public ATerm readFromTextFile(InputStream stream) throws IOException {
    ATermReader reader = new ATermReader(new BufferedReader(new InputStreamReader(stream)));
    reader.readSkippingWS();

    return readFromTextFile(reader);
  }

  public ATerm readFromSharedTextFile(InputStream stream) throws IOException {
    ATermReader reader = new ATermReader(new BufferedReader(new InputStreamReader(stream)));
    reader.readSkippingWS();

    if (reader.getLastChar() != '!') {
      throw new IOException("not a shared text file!");
    }

    reader.readSkippingWS();

    return readFromSharedTextFile(reader);
  }

  public ATerm readFromBinaryFile(InputStream stream) throws IOException{
    return readFromBinaryFile(stream, false);
  }

  private ATerm readFromBinaryFile(InputStream stream, boolean headerRead) throws ParseError, IOException {
    BAFReader r = new BAFReader(this, stream);
    return r.readFromBinaryFile(headerRead);
  }
 
  private ATerm readSAFFromOldStyleStream(InputStream stream) throws IOException{
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] buffer = new byte[4096];
    int nrOfBytesRead;
    while((nrOfBytesRead = stream.read(buffer, 0, buffer.length)) != -1){
      baos.write(buffer, 0, nrOfBytesRead);
    }
    return BinaryReader.readTermFromSAFString(this, baos.toByteArray());
  }

  public ATerm readFromFile(InputStream stream) throws IOException{
    int firstToken;
    do{
      firstToken = stream.read();
      if(firstToken == -1) throw new IOException("Premature EOF.");
    }while(Character.isWhitespace((char) firstToken));
   
    char typeByte = (char) firstToken;
   
    if(typeByte == '!'){
      ATermReader reader = new ATermReader(new BufferedReader(new InputStreamReader(stream)));
      reader.readSkippingWS();
      return readFromSharedTextFile(reader);
    }else if(typeByte == '?'){
      return readSAFFromOldStyleStream(stream);
    }else if(Character.isLetterOrDigit(typeByte) || typeByte == '_' || typeByte == '[' || typeByte == '-'){
      ATermReader reader = new ATermReader(new BufferedReader(new InputStreamReader(stream)));
      reader.last_char = typeByte; // Reinsert the type into the stream (since in this case it wasn't a type byte).
      return readFromTextFile(reader);
    }else if(firstToken == 0){
      BufferedInputStream bis = new BufferedInputStream(stream);
      if(BAFReader.isBinaryATerm(bis)){
        return readFromBinaryFile(bis, true);
      }
    }
    throw new RuntimeException("Unsupported file type");
  }
 
  public ATerm readFromFile(String filename) throws IOException{
    ATerm result;
   
    FileInputStream fis = new FileInputStream(filename);
    try{
      result = readFromFile(fis);
    }finally{
      fis.close();
    }
   
    return result;
  }
 
  /**
   * @see ATermFactory#importTerm(ATerm)
   */
  public ATerm importTerm(ATerm term){
    SharedObject object = (SharedObject) term;
    if(contains(object)) return term;
   
    ATerm result;
   
    switch(term.getType()){
      case ATerm.APPL:
        ATermAppl appl = (ATermAppl) term;
       
        AFun fun = (AFun) importTerm(appl.getAFun());
       
        int nrOfArguments = appl.getArity();
        ATerm[] newArguments = new ATerm[nrOfArguments];
        for(int i = nrOfArguments - 1; i >= 0; i--){
          newArguments[i] = importTerm(appl.getArgument(i));
        }
       
        result = makeAppl(fun, newArguments);
        break;
      case ATerm.LIST:
        ATermList list = (ATermList) term;
        if(list.isEmpty()){
          result = empty;
          break;
        }
        ATerm first = importTerm(list.getFirst());
        ATermList next = (ATermList) importTerm(list.getNext());
       
        result = makeList(first, next);
        break;
      case ATerm.INT:
        ATermInt integer = (ATermInt) term;
       
        result = makeInt(integer.getInt());
        break;
      case ATerm.LONG:
        ATermLong elongatedType = (ATermLong) term;
       
        result = makeLong(elongatedType.getLong());
        break;
      case ATerm.REAL:
        ATermReal real = (ATermReal) term;
       
        result = makeReal(real.getReal());
        break;
      case ATerm.PLACEHOLDER:
        ATermPlaceholder placeHolder = (ATermPlaceholder) term;
       
        result = makePlaceholder(importTerm(placeHolder.getPlaceholder()));
        break;
      case ATerm.AFUN:
        AFun afun = (AFun) term;
       
        return makeAFun(afun.getName(), afun.getArity(), afun.isQuoted());
      default:
        throw new RuntimeException("Unknown term type id: "+term.getType());
    }
   
    if(term.hasAnnotations()){
      ATermList annotations = term.getAnnotations();
      result = result.setAnnotations(annotations);
    }
   
    return result;
  }
}

class ATermReader {
  private static final int INITIAL_TABLE_SIZE = 2048;
  private static final int TABLE_INCREMENT = 4096;
 
  private static final int INITIAL_BUFFER_SIZE = 1024;

  private Reader reader;

  int last_char;
  private int pos;

  private int nr_terms;
  private ATerm[] table;
 
  private char[] buffer;
  private int limit;
  private int bufferPos;
 
  public ATermReader(Reader reader) {
  this(reader, INITIAL_BUFFER_SIZE);
  }

  public ATermReader(Reader reader, int bufferSize) {
    this.reader = reader;
    last_char = -1;
    pos = 0;
   
    if(bufferSize < INITIAL_BUFFER_SIZE)
      buffer = new char[bufferSize];
    else
      buffer = new char[INITIAL_BUFFER_SIZE];
    limit = -1;
    bufferPos = -1;
  }

  public void initializeSharing() {
    table = new ATerm[INITIAL_TABLE_SIZE];
    nr_terms = 0;
  }

  public void storeNextTerm(ATerm t, int size) {
    if (table == null) {
      return;
    }

    if (size <= PureFactory.abbrevSize(nr_terms)) {
      return;
    }

    if (nr_terms == table.length) {
      ATerm[] new_table = new ATerm[table.length + TABLE_INCREMENT];
      System.arraycopy(table, 0, new_table, 0, table.length);
      table = new_table;
    }

    table[nr_terms++] = t;
  }

  public ATerm getTerm(int index) {
    if (index < 0 || index >= nr_terms) {
      throw new RuntimeException("illegal index");
    }
    return table[index];
  }

  public int read() throws IOException {
    if(bufferPos == limit){
      limit = reader.read(buffer);
      bufferPos = 0;
    }
   
    if(limit == -1){
      last_char = -1;
    }else{
      last_char = buffer[bufferPos++];
      pos++;
    }
   
    return last_char;
  }

  public int readSkippingWS() throws IOException {
    do {
      last_char = read();
    } while (Character.isWhitespace(last_char));

    return last_char;

  }

  public int skipWS() throws IOException {
    while (Character.isWhitespace(last_char)) {
      last_char = read();
    }

    return last_char;
  }

  public int readOct() throws IOException {
    int val = Character.digit(last_char, 8);
    val += Character.digit(read(), 8);

    if (val < 0) {
      throw new ParseError("octal must have 3 octdigits.");
    }

    val += Character.digit(read(), 8);

    if (val < 0) {
      throw new ParseError("octal must have 3 octdigits");
    }

    return val;
  }

  public int getLastChar() {
    return last_char;
  }

  public int getPosition() {
    return pos;
  }
}
TOP

Related Classes of aterm.pure.ATermReader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.