From ae44478b30d890fe0fb04022f44d474dcdcc3f9d Mon Sep 17 00:00:00 2001 From: Lassi Pulkkinen Date: Thu, 31 Oct 2024 03:11:21 +0200 Subject: Initial commit (import old repo) --- bstates.ha | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 bstates.ha (limited to 'bstates.ha') diff --git a/bstates.ha b/bstates.ha new file mode 100644 index 0000000..bf329f2 --- /dev/null +++ b/bstates.ha @@ -0,0 +1,107 @@ +use types; +use strings; + +type BstateId = u32; +type BlockPropId = u32; + +type BlockBstates = struct { + state0: BstateId, + nstates: u32, + props: [](str, []str), + prop_moduli: []u32, +}; + +type BstateInfo = struct { + block: BlockId, +}; + +let BLOCKS_BSTATES: []BlockBstates = []; +let BSTATES_INFO: []BstateInfo = []; + +fn bstates_handle_blocks_onregister(blk: BlockId) void = { + append(BLOCKS_BSTATES, BlockBstates { ... }); +}; + +fn block_addprop(blk: BlockId, name: str, values: []str) BlockPropId = { + assert(len(values) != 0, "Block property must have at least 1 value"); + const bstates = &BLOCKS_BSTATES[blk]; + assert(len(bstates.props) < types::U32_MAX - 1, + "Too many block properties"); + append(bstates.props, (strings::dup(name), strings::dupall(values))); + return len(bstates.props): u32 - 1; +}; + +fn init_bstates() void = { + for (let blk: BlockId = 0; blk < blocks_count(); blk += 1) { + const bstates = &BLOCKS_BSTATES[blk]; + + bstates.prop_moduli = alloc([], len(bstates.props)); + let mod = 1u32; + for (let j = 0z; j < len(bstates.props); j += 1) { + // TODO: overflow... + mod *= len(bstates.props[j].1): u32; + static append(bstates.prop_moduli, mod); + }; + bstates.state0 = len(BSTATES_INFO): u32; + bstates.nstates = mod; + + assert(bstates.state0 + bstates.nstates > bstates.state0, + "Too many blockstates"); + + for (let j = 0u32; j < mod; j += 1) { + append(BSTATES_INFO, BstateInfo { + block = blk, + }); + }; + }; +}; + +fn destroy_bstates() void = { + for (let blk: BlockId = 0; blk < blocks_count(); blk += 1) { + const bstates = &BLOCKS_BSTATES[blk]; + for (let i = 0z; i < len(bstates.props); i += 1) { + free(bstates.props[i].0); + strings::freeall(bstates.props[i].1); + }; + free(bstates.prop_moduli); + }; + free(BLOCKS_BSTATES); + free(BSTATES_INFO); +}; + +fn block_propcount(blk: BlockId) u32 = + len(BLOCKS_BSTATES[blk].props): u32; + +fn block_propname(blk: BlockId, prop: BlockPropId) str = + BLOCKS_BSTATES[blk].props[prop].0; + +fn block_findprop(blk: BlockId, name: str) (BlockPropId | void) = { + for (let prop: BlockPropId = 0; + prop < block_propcount(blk); prop += 1) { + if (block_propname(blk, prop) == name) + return prop; + }; +}; + +fn block_propvalcount(blk: BlockId, prop: BlockPropId) u32 = + len(BLOCKS_BSTATES[blk].props[prop].1): u32; + +fn block_propvalname(blk: BlockId, prop: BlockPropId, val: u32) str = + BLOCKS_BSTATES[blk].props[prop].1[val]; + +fn block_findpropval(blk: BlockId, prop: BlockPropId, name: str) + (u32 | void) = { + for (let val = 0u32; val < block_propvalcount(blk, prop); val += 1) { + if (block_propvalname(blk, prop, val) == name) + return val; + }; +}; + +fn bstate_getblock(bstate: BstateId) BlockId = + BSTATES_INFO[bstate].block; + +fn bstate_getprop(bstate: BstateId, blk: BlockId, prop: BlockPropId) u32 = { + const bstates = &BLOCKS_BSTATES[blk]; + return (bstate - bstates.state0) % bstates.prop_moduli[prop] + / (if (prop == 0) 1u32 else bstates.prop_moduli[prop - 1]); +}; -- cgit v1.2.3