async def compile_as_arr(self, ctx: CompileContext) -> Register: """Compile an array literal but inline the inner values.""" if (isinstance((await self.type).to, types.Array) and (not isinstance(self.first_elem, ArrayLiteral))): # Maybe just cast the internal type to a pointer. raise self.error( "Internal type is of array type but is not a literal.") if self.var is None: self.var = ctx.declare_unique_variable(await self.type) self.var.lvalue_is_rvalue = True base = ctx.get_register(types.Pointer.size) index = ctx.get_register(types.Pointer.size) ctx.emit(LoadVar(self.var, base)) ctx.emit(Mov(index, base)) elem_size = (await self.type).to.size for i in self.exprs: await i.compile_as_arr_helper(ctx, index) # NOTE: will we ever hit this? if self.float_size: ctx.emit(Binary.add(index, Immediate(elem_size * self.float_size))) return base
async def compile_as_ref(self, ctx: CompileContext) -> Register: """Compile to the array literal and return a reference to the start. This function is for when an array of references is the wanted outcome. This function will not work on array types. """ if self.var is None: self.var = ctx.declare_unique_variable(await self.type) self.var.lvalue_is_rvalue = True if (isinstance(self.first_elem, ArrayLiteral) and (not isinstance( (await self.type).to, types.Pointer))): raise self.error( "Cannot compile to references if internal array type is an array and not a pointer" ) base = ctx.get_register(types.Pointer.size) index = ctx.get_register(types.Pointer.size) ctx.emit(LoadVar(self.var, base)) ctx.emit(Mov(index, base)) elem_type = (await self.type).to for i in self.exprs: r = await i.compile(ctx) if r.size != elem_type.size: r0 = r.resize(elem_type.size, elem_type.signed) ctx.emit(Resize(r, r0)) r = r0 ctx.emit(Mov(Dereference(index, r.size), r)) ctx.emit(Binary.add(index, Immediate(r.size, types.Pointer.size))) if self.float_size: # fill in missing values ctx.emit( Binary.add( index, Immediate(elem_type.size * self.float_size, index.size))) return base