def gen_get_or_create(cls, top, _): func = top.define_function('_internal/entity_ptr') func.preamble.add(i.PureInsn()) retvar = func.preamble.define(i.ReturnVarInsn(i.VarType.i32)) ct = func.create_compiletime() entry = func.create_block('entry') set_uid = func.create_block('set_uid') set_uid.set_is_function() ctblock = ct.create_block('ct_entry') uid_obj = top.preamble.add(cls.objective(), True, '__uid') sender = func.preamble.define(i.CreateSelector(i.SelectorType.SENDER)) self_uid = func.preamble.define( i.CreateEntityLocalAccess(uid_obj, sender)) next_uid = func.preamble.define( i.CreateEntityLocalAccess(uid_obj, top.lookup('_global_entity'))) ex = func.preamble.define(i.CreateExec()) # unless our uid is 1 or greater... ctblock.add(i.ExecUnlessVar(ex, self_uid, 1, None)) ct.run_and_return() entry.add(i.ExecRun(ex, set_uid)) entry.add(i.SetScore(retvar, self_uid)) entry.add(i.Return()) set_uid.add(i.SetScore(self_uid, next_uid)) set_uid.add(i.AddScore(next_uid, 1)) func.end() return func
def __is_empty(self, compiler, container, args): valvar = args[0].value.valvar() bool = compiler.type('bool') result = bool.allocate(compiler, 'empty') compiler.add_insn(i.SetScore(result, 0)) exec = compiler.define('empty_test', i.CreateExec()) set_empty = compiler.create_block('set_empty') set_empty.is_function = True set_empty.add(i.SetScore(result, 1)) with compiler.compiletime(): compiler.add_insn(i.ExecUnlessNBTVar(exec, valvar)) compiler.add_insn(i.ExecRun(exec, set_empty)) return Temporary(bool, result)
def open_read(self): block, var = self._create_var() # Variable stored on global entity res = self.compiler.create_var('pos%d_' % self.idx, i.VarType.q10) # Copy into res from the temporary block block.add(i.SetScore(res, var)) return res
def _gen_for(size, func, prefix, indexparam, gen_callback, *cb_args): entry = func.create_block('entry') # Copy to local variable due to register allocation speedup index = func.preamble.define(i.DefineVariable(indexparam.type)) entry.add(i.SetScore(index, indexparam)) def pair_name(pair): return '%s_%d_%d' % (prefix, pair.min, pair.max) def branch(func, index, pair): return i.RangeBr(index, pair.min, pair.max, func.get_or_create_block(pair_name(pair)), None) def callback(pair): block = func.get_or_create_block(pair_name(pair)) block.defined = True if pair.left: block.add(branch(func, index, pair.left)) if pair.right: block.add(branch(func, index, pair.right)) if pair.min == pair.max: gen_callback(block, index, pair.min, *cb_args) root = generate_bin_tree(size, callback) entry.add(i.Call(func.get_or_create_block(pair_name(root)))) entry.add(i.Return()) func.end()
def _copy_impl(self, compiler, this, other): thisobj = this.value if self._is_nbt: compiler.add_insn(i.SetScore(thisobj.as_variable(), other.value.as_variable())) else: # Pair each var member for var in self.__var_members.keys(): lvar = thisobj.get_member(compiler, var) rvar = other.value.get_member(compiler, var) lvar.type.dispatch_operator(compiler, '=', lvar, rvar) return other
def gen_get_or_create(cls, top, _): func = top.define_function('_internal/entity_ptr') func.preamble.add(i.PureInsn()) retvar = func.preamble.define(i.ReturnVarInsn(i.VarType.i32)) entry = func.create_block('entry') set_uid = func.create_block('set_uid') end = func.create_block('end') uid_obj = top.preamble.add(cls.objective(), True, '__uid') sender = entry.define(i.CreateSelector(i.SelectorType.SENDER)) self_uid = entry.define(i.CreateEntityLocalAccess(uid_obj, sender)) next_uid = entry.define( i.CreateEntityLocalAccess(uid_obj, top.lookup('_global_entity'))) entry.add(i.RangeBr(self_uid, 0, 0, set_uid, end)) set_uid.add(i.SetScore(self_uid, next_uid)) set_uid.add(i.AddScore(next_uid, 1)) set_uid.add(i.Branch(end)) end.add(i.SetScore(retvar, self_uid)) end.add(i.Return()) func.end() return func
def __set_value(self, compiler, container, args): valvar = args[0].value.valvar() vcontainer = args[1] vars = vcontainer.type.as_variables(vcontainer.value) if len(vars) == 1: # Use actual var if it's a single variable realvar = vars[0] else: # Wrap vars into NBT var nbtwrap = compiler.define('new_compound', i.CreateNBTCompound()) realvar = compiler.create_var('maybewrap', i.VarType.nbt) compiler.add_insn(i.NBTAssign(realvar, nbtwrap)) types = [v.type for v in vars] holders = self.__create_wrap_holders(compiler, realvar, types) for holder, var in zip(holders, vars): compiler.add_insn(i.SetScore(holder, var)) # TODO verify this works correctly if isinstance(args[0], DelegatedWrite): return args[0].write(compiler, realvar) compiler.add_insn(i.SetScore(valvar, realvar)) return args[0] # this
def _create_func(self): func = self.compiler.define_function('_internal/entity_ptr') func.preamble.add(i.PureInsn()) retvar = func.preamble.define(i.ReturnVarInsn(i.VarType.i32)) entry = func.create_block('entry') set_uid = func.create_block('set_uid') end = func.create_block('end') self.uid_obj = self.compiler.global_def( '__uid', i.DefineObjective(i.VirtualString('__uid'), None)) sender = entry.define(i.CreateSelector(i.SelectorType.SENDER)) self_uid = entry.define(i.CreateEntityLocalAccess( self.uid_obj, sender)) next_uid = entry.define( i.CreateEntityLocalAccess( self.uid_obj, self.compiler.top.lookup('_global_entity'))) entry.add(i.RangeBr(self_uid, 0, 0, set_uid, end)) set_uid.add(i.SetScore(self_uid, next_uid)) set_uid.add(i.AddScore(next_uid, 1)) set_uid.add(i.Branch(end)) end.add(i.SetScore(retvar, self_uid)) end.add(i.Return()) func.end() return func
def read(self, compiler): tmp = self.type.allocate(compiler, 'elocal_tmp') var, block = self.as_ptr(compiler) block.add(i.SetScore(tmp, var)) return tmp
def write(self, compiler, other): othervar = other.type.as_variable(other.value) var, block = self.as_ptr(compiler) block.add(i.SetScore(var, othervar)) return other
def _assign_dec(self, compiler, fncontainer, args): other = args[1] with fncontainer.this.open_write() as (block, var): block.add(i.SetScore(var, other.type.as_variable(other.value))) return other
def coerce_to(self, compiler, val, type): if type == compiler.type('int'): v = type.allocate(compiler, 'dcast') compiler.add_insn(i.SetScore(v, val.value)) return Temporary(type, v) return super().coerce_to(compiler, val, type)
def _gen_setter(block, indexvar, indexval, arr, value): path = i.VirtualString('[%d]' % indexval) path_var = block._func.preamble.define( i.NBTSubPath(arr, path, value.type)) block.add(i.SetScore(path_var, value))
def _copy_impl(self, compiler, this, other): if isinstance(this, DelegatedWrite): return this.write(compiler, other) compiler.add_insn(i.SetScore(this.value._var, other.value._var)) return other