
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 }