logo

class

compiler::Assembler

sys::Obj
  compiler::CompilerSupport
    compiler::Assembler : compiler::FConst
   1  //
   2  // Copyright (c) 2006, Brian Frank and Andy Frank
   3  // Licensed under the Academic Free License version 3.0
   4  //
   5  // History:
   6  //   15 Sep 05  Brian Frank  Creation
   7  //
   8  
   9  **
  10  ** Assembler assembles all the TypeDefs into their fcode representation.
  11  **
  12  class Assembler : CompilerSupport, FConst
  13  {
  14  
  15  //////////////////////////////////////////////////////////////////////////
  16  // Construction
  17  //////////////////////////////////////////////////////////////////////////
  18  
  19    new make(Compiler compiler)
  20      : super(compiler)
  21    {
  22    }
  23  
  24  //////////////////////////////////////////////////////////////////////////
  25  // Assemble
  26  //////////////////////////////////////////////////////////////////////////
  27  
  28    FPod assemblePod()
  29    {
  30      fpod = FPod.make(null, compiler.pod.name, null)
  31  
  32      fpod.name    = compiler.input.podName
  33      fpod.version = compiler.input.version
  34      fpod.depends = compiler.input.depends
  35      fpod.fattrs  = assemblePodAttrs(fpod)
  36  
  37      fpod.ftypes = FType[,]
  38      types.each |TypeDef t|
  39      {
  40        fpod.ftypes.add(assembleType(t))
  41      }
  42  
  43      return fpod
  44    }
  45  
  46    private FAttr[] assemblePodAttrs(FPod fpod)
  47    {
  48      input := compiler.input
  49      asm := AttrAsm.make(compiler, fpod)
  50  
  51      buf := Buf.make
  52      buf.writeI2(4 + input.podFacets.size)
  53      buf.writeI2(fpod.addName("description")); buf.writeUtf(input.description.toCode)
  54      buf.writeI2(fpod.addName("buildHost"));   buf.writeUtf(Sys.hostName.toCode)
  55      buf.writeI2(fpod.addName("buildUser"));   buf.writeUtf(Sys.userName.toCode)
  56      buf.writeI2(fpod.addName("buildTime"));   buf.writeUtf(DateTime.now.toStr.toCode)
  57      input.podFacets.each |Obj val, Str key|
  58      {
  59        buf.writeI2(fpod.addName(key));
  60        buf.writeUtf(Buf.make.writeObj(val).flip.readAllStr)
  61      }
  62      asm.add(FConst.FacetsAttr, buf)
  63  
  64      return asm.attrs
  65    }
  66  
  67    private FType assembleType(TypeDef def)
  68    {
  69      t := FType.make(fpod)
  70  
  71      t.hollow = false
  72      t.flags  = def.flags
  73      t.self   = typeRef(def)
  74      t.fbase  = (def.base == null) ? -1 : typeRef(def.base)
  75      def.mixins.map(t.fmixins = Int[,]) |CType m->Obj| { return typeRef(m) }
  76      def.fieldDefs.map(t.ffields = FField[,]) |FieldDef f->Obj| { return assembleField(t, f) }
  77      def.methodDefs.map(t.fmethods = FMethod[,]) |MethodDef m->Obj| { return assembleMethod(t, m) }
  78  
  79      attrs := AttrAsm.make(compiler, fpod)
  80      if (compiler.input.mode == CompilerInputMode.str)
  81        attrs.sourceFile(def.location.fileUri)
  82      else
  83        attrs.sourceFile(def.location.filename)
  84      attrs.lineNumber(def.location.line)
  85      attrs.facets(def.facets)
  86      t.fattrs = attrs.attrs
  87  
  88      return t
  89    }
  90  
  91    FField assembleField(FType fparent, FieldDef def)
  92    {
  93      f := FField.make(fparent)
  94      f.nameIndex = name(def.name)
  95      f.flags     = def.flags
  96      f.typeRef   = typeRef(def.fieldType)
  97  
  98      attrs := AttrAsm.make(compiler, fpod)
  99      attrs.lineNumber(def.location.line)
 100      attrs.facets(def.facets)
 101      f.fattrs = attrs.attrs
 102  
 103      return f;
 104    }
 105  
 106    FMethod assembleMethod(FType fparent, MethodDef def)
 107    {
 108      attrs := AttrAsm.make(compiler, fpod)
 109  
 110      m := FMethod.make(fparent)
 111  
 112      m.nameIndex    = name(def.name)
 113      m.flags        = def.flags
 114      m.ret          = typeRef(def.ret)
 115      m.inheritedRet = typeRef(def.inheritedReturnType)
 116      m.paramCount   = def.params.size
 117      m.localCount   = def.vars.size - def.params.size
 118  
 119      m.vars = FMethodVar[,]
 120      def.vars.map(m.vars) |MethodVar v->Obj|
 121      {
 122        f := FMethodVar.make(m)
 123        f.nameIndex = name(v.name)
 124        f.typeRef   = typeRef(v.ctype)
 125        f.flags     = v.flags
 126        if (v.paramDef != null)
 127        {
 128          f.defNameIndex = name(ParamDefaultAttr)
 129          f.def = assembleExpr(v.paramDef.def)
 130        }
 131        return f
 132      }
 133  
 134      m.code = assembleCode(def, attrs)
 135  
 136      attrs.lineNumber(def.location.line)
 137      attrs.facets(def.facets)
 138      m.fattrs = attrs.attrs
 139  
 140      return m;
 141    }
 142  
 143  //////////////////////////////////////////////////////////////////////////
 144  // Utils
 145  //////////////////////////////////////////////////////////////////////////
 146  
 147    Int typeRef(CType type)
 148    {
 149      return fpod.addTypeRef(type)
 150    }
 151  
 152    Int name(Str val)
 153    {
 154      return fpod.addName(val)
 155    }
 156  
 157    private Buf assembleCode(MethodDef def , AttrAsm attrs)
 158    {
 159      block := def.code
 160      if (block == null) return null
 161  
 162      asm := CodeAsm.make(compiler, def.location, fpod)
 163      if (def.ctorChain != null) asm.expr(def.ctorChain)
 164      asm.block(block)
 165  
 166      if (asm.errCount > 0) attrs.add(ErrTableAttr, asm.finishErrTable)
 167      if (asm.lineCount > 0) attrs.add(LineNumbersAttr, asm.finishLines)
 168  
 169      return asm.finishCode
 170    }
 171  
 172    private Buf assembleExpr(Expr expr)
 173    {
 174      if (expr == null) return null
 175      asm := CodeAsm.make(compiler, expr.location, fpod)
 176      asm.expr(expr)
 177      return asm.finishCode
 178    }
 179  
 180  //////////////////////////////////////////////////////////////////////////
 181  // Fields
 182  //////////////////////////////////////////////////////////////////////////
 183  
 184    FPod fpod
 185  }