// $Id: XobjectPrintWriter.java,v 1.9 2002/02/20 17:43:30 msato Exp $
// $RWC_Release: Omni-1.6 $
// $RWC_Copyright:
//  Omni Compiler Software Version 1.5-1.6
//  Copyright (C) 2002 PC Cluster Consortium
//  
//  This software is free software; you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License version
//  2.1 published by the Free Software Foundation.
//  
//  Omni Compiler Software Version 1.0-1.4
//  Copyright (C) 1999, 2000, 2001.
//   Tsukuba Research Center, Real World Computing Partnership, Japan.
//  
//  Please check the Copyright and License information in the files named
//  COPYRIGHT and LICENSE under the top  directory of the Omni Compiler
//  Software release kit.
//  
//  
//  $
package exc.object;

import java.io.*;

public class XobjectPrintWriter extends PrintWriter {

  // constructor 
  public XobjectPrintWriter(OutputStream out){
    super(out,true);
  }

  public XobjectPrintWriter(Writer out){
    super(out,true);
  }

  void fatal(String msg){
    System.err.println("Fatal XobjectPrintWriter: "+msg);
    Thread.dumpStack();
    System.exit(1);
  }

  public void print(Xobject v){ printObject(v); }

  public void printInt(int i){
    print("0x");
    print(Integer.toHexString(i));
  }

  public void printBool(boolean b){
    if(b) print("1");else print("0");
  }

  public void printObject(Xobject v){
    printObjectRec(v,0);
    println();
    flush();
  }

  public void printObjectNoIndent(Xobject v){
    printObjectRec(v,-1);
    flush();
  }

  void printObjectRec(Xobject v,int l){
    int opcode;
    Xtype type;

    /* indent */
    for(int i = 0; i < l; i++) print("  ");
	
    if(v == null){ /* special case */
      print("()");
      return;
    }

    opcode = v.Opcode();
    /* XCODE NAME */
    if(opcode < Xcode.MAX_CODE){
      print("(");
      print(Xcode.getName(opcode));
      if((type = v.Type()) != null){
	print(":");
	printType(type);
      }
    } else {
      print(v.toString());
      return;
    }

    if(v.isTerminal()){
      switch(opcode){
      case Xcode.ID_LIST:
	printIdentList(v);
	print(")");
	return;
      case Xcode.IDENT:		/* NAME */
      case Xcode.VAR_ADDR:		/* ICON */
      case Xcode.LVAR_ADDR:
      case Xcode.PARAM_ADDR:
      case Xcode.PARAM_VAR:
      case Xcode.LVAR:
      case Xcode.VAR:
      case Xcode.ARRAY_ADDR:
      case Xcode.LARRAY_ADDR:
      case Xcode.FUNC_ADDR:
      case Xcode.MOE_CONSTANT:
      case Xcode.FPARAM_ARRAY_ADDR:
      case Xcode.FPARAM_VAR_ADDR:
      case Xcode.FPARAM_VAR:
	print(" "+v.getSym()+")");
	return;
      case Xcode.CXX_ATTR_DECL:
      case Xcode.INT_CONSTANT:
      case Xcode.LONG_CONSTANT:
      case Xcode.REG:
	print(" 0x"+Integer.toHexString(v.getInt())+")");
	return;
      case Xcode.STRING_CONSTANT:
	print(" \""+v.getString()+"\")");
	return;
      case Xcode.LONGLONG_CONSTANT:
      case Xcode.FLOAT_CONSTANT:
	print(" 0x"+Integer.toHexString(v.getIntHIGH())+
	      " 0x"+Integer.toHexString(v.getIntLOW())+")");
	return;
      }
      fatal("unknown terminal");
    }

    LineNo ln = v.getLineNo();
    if(ln != null)
      print("@"+ln.lineNo()+"."+ln.fileName());

    if(v.getArgs() != null){
      if(l < 0) print(" ");
      else {
	println();
	l++;
      } 
      for(XobjArgs a = v.getArgs(); a != null; a=a.nextArgs()){
	printObjectRec(a.getArg(),l);
	if(a.nextArgs() != null){
	  if(l < 0) print(" ");
	  else println();
	}
      }
    }
    print(")");
  }
    
  public void printIdentList(Xobject o){
    for(XobjArgs a = o.getArgs(); a != null; a = a.nextArgs()){
      print(" "+a.getArg());
    }
  }

  public void printType(Xtype type){
    if(type.copyed != null){
	print("B");
	print(Integer.toHexString(type.Id()));
	return;
    }
    switch(type.getKind()){
    case Xtype.BASIC:
      print(BasicType.getName(type.getBasicType()));
      break;
    case Xtype.POINTER:
      print("P");
      print(Integer.toHexString(type.Id()));
      break;
    case Xtype.ARRAY:
      print("A");
      print(Integer.toHexString(type.Id()));
      break;
    case Xtype.FUNCTION:
      print("F");
      print(Integer.toHexString(type.Id()));
      break;
    case Xtype.ENUM:
      print("E");
      print(Integer.toHexString(type.Id()));
      break;
    case Xtype.STRUCT:
      print("S");
      print(Integer.toHexString(type.Id()));
      break;
    case Xtype.UNION:
      print("U");
      print(Integer.toHexString(type.Id()));
      break;
    case Xtype.CLASS:
      print("C");
      print(Integer.toHexString(type.Id()));
      break;
    default:
      fatal("printType: bad type="+type+
	    " kind="+type.getKind()+" id="+type.Id());
    }
  }
}







