diff -r d94b30d4092f nml/actions/action2var.py --- a/nml/actions/action2var.py Fri Mar 20 20:42:28 2015 +0100 +++ b/nml/actions/action2var.py Fri Mar 27 21:35:03 2015 +0100 @@ -298,14 +298,6 @@ self.size = size self.offset = offset -def pow2(expr): - #2**x = (1 ror (32 - x)) - if isinstance(expr, expression.ConstantNumeric): - return expression.ConstantNumeric(1 << expr.value) - expr = expression.BinOp(nmlop.SUB, expression.ConstantNumeric(32), expr) - expr = expression.BinOp(nmlop.ROT_RIGHT, expression.ConstantNumeric(1), expr) - return expr - class Varaction2Parser(object): def __init__(self, feature): self.feature = feature # Depends on feature and var_range @@ -360,22 +352,13 @@ expr = expression.BinOp(nmlop.AND, expr, expression.ConstantNumeric(1)) expr = expression.BinOp(nmlop.XOR, expr, expression.ConstantNumeric(1)) - elif expr.op == nmlop.SHIFT_LEFT: - #a << b ==> a * (2**b) - expr = expression.BinOp(nmlop.MUL, expr.expr1, pow2(expr.expr2)) - elif expr.op == nmlop.SHIFT_RIGHT: - #a >> b ==> a / (2**b) - expr = expression.BinOp(nmlop.DIV, expr.expr1, pow2(expr.expr2)) - elif expr.op == nmlop.SHIFTU_RIGHT: - #a >>> b ==> (uint)a / (2**b) - expr = expression.BinOp(nmlop.DIVU, expr.expr1, pow2(expr.expr2)) elif expr.op == nmlop.HASBIT: # hasbit(x, n) ==> (x >> n) & 1 - expr = expression.BinOp(nmlop.DIV, expr.expr1, pow2(expr.expr2)) + expr = expression.BinOp(nmlop.SHIFTU_RIGHT, expr.expr1, expr.expr2) expr = expression.BinOp(nmlop.AND, expr, expression.ConstantNumeric(1)) elif expr.op == nmlop.NOTHASBIT: # !hasbit(x, n) ==> ((x >> n) & 1) ^ 1 - expr = expression.BinOp(nmlop.DIV, expr.expr1, pow2(expr.expr2)) + expr = expression.BinOp(nmlop.SHIFTU_RIGHT, expr.expr1, expr.expr2) expr = expression.BinOp(nmlop.AND, expr, expression.ConstantNumeric(1)) expr = expression.BinOp(nmlop.XOR, expr, expression.ConstantNumeric(1)) diff -r d94b30d4092f nml/expression/functioncall.py --- a/nml/expression/functioncall.py Fri Mar 20 20:42:28 2015 +0100 +++ b/nml/expression/functioncall.py Fri Mar 27 21:35:03 2015 +0100 @@ -249,6 +249,22 @@ raise generic.ScriptError(name + "() must have exactly two parameters", pos) return BinOp(nmlop.HASBIT, args[0], args[1], pos) +def builtin_getbits(name, args, pos): + """ + getbits(value, first, amount) builtin function. + + @return Extract C{amount} bits starting at C{first} from C{value}, that is (C{value} >> C{first}) & (1 << C{amount} - 1) + """ + if len(args) != 3: + raise generic.ScriptError(name + "() must have exactly three parameters", pos) + + # getbits(value, first, amount) = (value >> first) & ((0xFFFFFFFF << amount) ^ 0xFFFFFFFF) + part1 = expression.BinOp(nmlop.SHIFTU_RIGHT, args[0], args[1], pos) + part2 = expression.BinOp(nmlop.SHIFT_LEFT, expression.ConstantNumeric(0xFFFFFFFF), args[2], pos) + part3 = expression.BinOp(nmlop.XOR, part2, expression.ConstantNumeric(0xFFFFFFFF), pos) + + return BinOp(nmlop.AND, part1, part3, pos) + def builtin_version_openttd(name, args, pos): """ version_openttd(major, minor, revision[, build]) builtin function. @@ -623,6 +639,7 @@ 'LOAD_TEMP' : builtin_storage, 'LOAD_PERM' : builtin_storage, 'hasbit' : builtin_hasbit, + 'getbits' : builtin_getbits, 'version_openttd' : builtin_version_openttd, 'cargotype_available' : builtin_cargotype_available, 'railtype_available' : builtin_railtype_available,