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,