logo

class

compiler::FTable

sys::Obj
  compiler::FTable
   1  //
   2  // Copyright (c) 2006, Brian Frank and Andy Frank
   3  // Licensed under the Academic Free License version 3.0
   4  //
   5  // History:
   6  //   26 Dec 05  Brian Frank  Creation
   7  //   19 Aug 06  Brian Frank  Ported from Java to Fan
   8  //
   9  
  10  **
  11  ** FTable is a 16-bit indexed lookup table for pod constants.
  12  **
  13  class FTable
  14  {
  15  
  16  //////////////////////////////////////////////////////////////////////////
  17  // Factories
  18  //////////////////////////////////////////////////////////////////////////
  19  
  20    static FTable makeStrs(FPod pod)
  21    {
  22      return make(pod,
  23        |OutStream out, Obj obj| { out.writeUtf((Str)obj) },
  24        |InStream in->Obj| { return in.readUtf.intern })
  25    }
  26  
  27    static FTable makeTypeRefs(FPod pod)
  28    {
  29      return make(pod,
  30        |OutStream out, Obj obj| { ((FTypeRef)obj).write(out) },
  31        |InStream in->Obj| { return FTypeRef.read(in) })
  32    }
  33  
  34    static FTable makeFieldRefs(FPod pod)
  35    {
  36      return make(pod,
  37        |OutStream out, Obj obj| { ((FFieldRef)obj).write(out) },
  38        |InStream in->Obj| { return FFieldRef.read(in) })
  39    }
  40  
  41    static FTable makeMethodRefs(FPod pod)
  42    {
  43      return make(pod,
  44        |OutStream out, Obj obj| { ((FMethodRef)obj).write(out) },
  45        |InStream in->Obj| { return FMethodRef.read(in) })
  46    }
  47  
  48    static FTable makeInts(FPod pod)
  49    {
  50      return make(pod,
  51        |OutStream out, Obj obj| { out.writeI8((Int)obj) },
  52        |InStream in->Obj| { return in.readS8 })
  53    }
  54  
  55    static FTable makeFloats(FPod pod)
  56    {
  57      return make(pod,
  58        |OutStream out, Obj obj| { out.writeF8((Float)obj) },
  59        |InStream in->Obj| { return in.readF8 })
  60    }
  61  
  62    static FTable makeDurations(FPod pod)
  63    {
  64      return make(pod,
  65        |OutStream out, Obj obj| { out.writeI8(((Duration)obj).ticks) },
  66        |InStream in->Obj| { return Duration.make(in.readS8) })
  67    }
  68  
  69  //////////////////////////////////////////////////////////////////////////
  70  // Constructor
  71  //////////////////////////////////////////////////////////////////////////
  72  
  73    new make(FPod pod, |OutStream out, Obj obj| writter, |InStream in->Obj| reader)
  74    {
  75      this.pod     = pod
  76      this.writter = writter
  77      this.reader  = reader
  78      this.table   = [,]
  79      this.reverse = Obj:Int[:]
  80    }
  81  
  82  //////////////////////////////////////////////////////////////////////////
  83  // Access
  84  //////////////////////////////////////////////////////////////////////////
  85  
  86    **
  87    ** Return if this table is empty
  88    **
  89    Bool isEmpty()
  90    {
  91      return table.isEmpty
  92    }
  93  
  94    **
  95    ** Get the object identified by the specified 16-bit index.
  96    **
  97    Obj get(Int index)
  98    {
  99      return table[index]
 100    }
 101  
 102    **
 103    ** Perform a reverse lookup to map a value to it's index (only
 104    ** available at compile time).  If the value isn't in the table
 105    ** yet, then add it.
 106    **
 107    Int add(Obj val)
 108    {
 109      index := reverse[val]
 110      if (index == null)
 111      {
 112        index = table.size
 113        table.add(val)
 114        reverse[val] = index
 115      }
 116      return index
 117    }
 118  
 119    **
 120    ** Serialize.
 121    **
 122    FTable read(InStream in)
 123    {
 124      table = [,]
 125      if (in == null) return this
 126      in.readU2.times |,| { table.add(reader.call1(in)) }
 127      in.close
 128      return this
 129    }
 130  
 131    **
 132    ** Deserialize.
 133    **
 134    Void write(OutStream out)
 135    {
 136      out.writeI2(table.size)
 137      table.each |Obj obj| { writter.call2(out, obj) }
 138      out.close
 139    }
 140  
 141  //////////////////////////////////////////////////////////////////////////
 142  // Fields
 143  //////////////////////////////////////////////////////////////////////////
 144  
 145    FPod pod
 146    Obj[] table
 147    Obj:Int reverse
 148    |OutStream out, Obj obj| writter
 149    |InStream in->Obj| reader
 150  }