logo
class

compiler::Assembler

sys::Obj
  compiler::CompilerSupport
    compiler::Assembler

Mixin: 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      // TODO: eventually we should merge these facets
  52      // with user defined facets passed in on the input
  53      buf := Buf.make
  54      buf.writeI2(4)
  55      buf.writeI2(fpod.addName("description")); buf.writeUtf(input.description.toCode)
  56      buf.writeI2(fpod.addName("buildHost"));   buf.writeUtf(Sys.hostName.toCode)
  57      buf.writeI2(fpod.addName("buildUser"));   buf.writeUtf(Sys.userName.toCode)
  58      buf.writeI2(fpod.addName("buildTime"));   buf.writeUtf(DateTime.now.toStr.toCode)
  59      asm.add(FConst.FacetsAttr, buf)
  60  
  61      return asm.attrs
  62    }
  63  
  64    private FType assembleType(TypeDef def)
  65    {
  66      t := FType.make(fpod)
  67  
  68      t.hollow = false
  69      t.flags  = def.flags
  70      t.self   = typeRef(def)
  71      t.fbase  = (def.base == null) ? -1 : typeRef(def.base)
  72      def.mixins.map(t.fmixins = Int[,]) |CType m->Obj| { return typeRef(m) }
  73      def.fieldDefs.map(t.ffields = FField[,]) |FieldDef f->Obj| { return assembleField(t, f) }
  74      def.methodDefs.map(t.fmethods = FMethod[,]) |MethodDef m->Obj| { return assembleMethod(t, m) }
  75  
  76      attrs := AttrAsm.make(compiler, fpod)
  77      if (compiler.input.mode == CompilerInputMode.str)
  78        attrs.sourceFile(def.location.fileUri)
  79      else
  80        attrs.sourceFile(def.location.filename)
  81      attrs.lineNumber(def.location.line)
  82      attrs.facets(def.facets)
  83      t.fattrs = attrs.attrs
  84  
  85      return t
  86    }
  87  
  88    FField assembleField(FType fparent, FieldDef def)
  89    {
  90      f := FField.make(fparent)
  91      f.nameIndex = name(def.name)
  92      f.flags     = def.flags
  93      f.typeRef   = typeRef(def.fieldType)
  94  
  95      attrs := AttrAsm.make(compiler, fpod)
  96      attrs.lineNumber(def.location.line)
  97      attrs.facets(def.facets)
  98      f.fattrs = attrs.attrs
  99  
 100      return f;
 101    }
 102  
 103    FMethod assembleMethod(FType fparent, MethodDef def)
 104    {
 105      attrs := AttrAsm.make(compiler, fpod)
 106  
 107      m := FMethod.make(fparent)
 108  
 109      m.nameIndex    = name(def.name)
 110      m.flags        = def.flags
 111      m.ret          = typeRef(def.ret)
 112      m.inheritedRet = typeRef(def.inheritedReturnType)
 113      m.paramCount   = def.params.size
 114      m.localCount   = def.vars.size - def.params.size
 115  
 116      m.vars = FMethodVar[,]
 117      def.vars.map(m.vars) |MethodVar v->Obj|
 118      {
 119        f := FMethodVar.make(m)
 120        f.nameIndex = name(v.name)
 121        f.typeRef   = typeRef(v.ctype)
 122        f.flags     = v.flags
 123        if (v.paramDef != null)
 124        {
 125          f.defNameIndex = name(ParamDefaultAttr)
 126          f.def = assembleExpr(v.paramDef.def)
 127        }
 128        return f
 129      }
 130  
 131      m.code = assembleCode(def, attrs)
 132  
 133      attrs.lineNumber(def.location.line)
 134      attrs.facets(def.facets)
 135      m.fattrs = attrs.attrs
 136  
 137      return m;
 138    }
 139  
 140  //////////////////////////////////////////////////////////////////////////
 141  // Utils
 142  //////////////////////////////////////////////////////////////////////////
 143  
 144    Int typeRef(CType type)
 145    {
 146      return fpod.addTypeRef(type)
 147    }
 148  
 149    Int name(Str val)
 150    {
 151      return fpod.addName(val)
 152    }
 153  
 154    private Buf assembleCode(MethodDef def , AttrAsm attrs)
 155    {
 156      block := def.code
 157      if (block == null) return null
 158  
 159      asm := CodeAsm.make(compiler, def.location, fpod)
 160      if (def.ctorChain != null) asm.expr(def.ctorChain)
 161      asm.block(block)
 162  
 163      if (asm.errCount > 0) attrs.add(ErrTableAttr, asm.finishErrTable)
 164      if (asm.lineCount > 0) attrs.add(LineNumbersAttr, asm.finishLines)
 165  
 166      return asm.finishCode
 167    }
 168  
 169    private Buf assembleExpr(Expr expr)
 170    {
 171      if (expr == null) return null
 172      asm := CodeAsm.make(compiler, expr.location, fpod)
 173      asm.expr(expr)
 174      return asm.finishCode
 175    }
 176  
 177  //////////////////////////////////////////////////////////////////////////
 178  // Fields
 179  //////////////////////////////////////////////////////////////////////////
 180  
 181    FPod fpod
 182  }