Beispiel #1
0
def validate_func_int(expr1, expr2, pos):
    if expr1.type() != Type.INTEGER or expr2.type() != Type.INTEGER:
        if expr1.type() == Type.SPRITEGROUP_REF:
            raise generic.ProcCallSyntaxError(expr1.name, expr1.pos)
        if expr2.type() == Type.SPRITEGROUP_REF:
            raise generic.ProcCallSyntaxError(expr2.name, expr2.pos)
        raise generic.ScriptError(
            "Binary operator requires both operands to be integers.", pos)
Beispiel #2
0
 def reduce(self, id_dicts=None, unknown_id_fatal=True):
     expr = self.expr.reduce(id_dicts)
     if expr.type() != Type.INTEGER:
         if expr.type() == Type.SPRITEGROUP_REF:
             raise generic.ProcCallSyntaxError(expr.name, expr.pos)
         raise generic.ScriptError(
             "Not-operator (!) requires an integer argument.", expr.pos)
     if isinstance(expr, ConstantNumeric):
         return ConstantNumeric(expr.value == 0)
     if isinstance(expr, Not):
         return Boolean(expr.expr).reduce()
     if isinstance(expr, BinOp):
         if expr.op == nmlop.CMP_EQ:
             return nmlop.CMP_NEQ(expr.expr1, expr.expr2)
         if expr.op == nmlop.CMP_NEQ:
             return nmlop.CMP_EQ(expr.expr1, expr.expr2)
         if expr.op == nmlop.CMP_LE:
             return nmlop.CMP_GT(expr.expr1, expr.expr2)
         if expr.op == nmlop.CMP_GE:
             return nmlop.CMP_LT(expr.expr1, expr.expr2)
         if expr.op == nmlop.CMP_LT:
             return nmlop.CMP_GE(expr.expr1, expr.expr2)
         if expr.op == nmlop.CMP_GT:
             return nmlop.CMP_LE(expr.expr1, expr.expr2)
         if expr.op == nmlop.HASBIT:
             return nmlop.NOTHASBIT(expr.expr1, expr.expr2)
         if expr.op == nmlop.NOTHASBIT:
             return nmlop.HASBIT(expr.expr1, expr.expr2)
     return Not(expr)
Beispiel #3
0
 def reduce(self, id_dicts=None, unknown_id_fatal=True):
     expr = self.expr.reduce(id_dicts)
     if expr.type() != Type.INTEGER:
         if expr.type() == Type.SPRITEGROUP_REF:
             raise generic.ProcCallSyntaxError(expr.name, expr.pos)
         raise generic.ScriptError(
             "Only integers can be converted to a boolean value.", expr.pos)
     if expr.is_boolean():
         return expr
     return Boolean(expr)
Beispiel #4
0
def validate_func_float(expr1, expr2, pos):
    if expr1.type() not in (Type.INTEGER,
                            Type.FLOAT) or expr2.type() not in (Type.INTEGER,
                                                                Type.FLOAT):
        if expr1.type() == Type.SPRITEGROUP_REF:
            raise generic.ProcCallSyntaxError(expr1.name, expr1.pos)
        if expr2.type() == Type.SPRITEGROUP_REF:
            raise generic.ProcCallSyntaxError(expr2.name, expr2.pos)
        raise generic.ScriptError(
            "Binary operator requires both operands to be integers or floats.",
            pos)
    # If one is a float, the other must be constant since we can't handle floats at runtime
    if (expr1.type() == Type.FLOAT
            and not isinstance(expr2, (ConstantNumeric, ConstantFloat))) or (
                expr2.type() == Type.FLOAT
                and not isinstance(expr1, (ConstantNumeric, ConstantFloat))):
        raise generic.ScriptError(
            "Floating-point operations are only possible when both operands are compile-time constants.",
            pos)
Beispiel #5
0
 def reduce(self, id_dicts=None, unknown_id_fatal=True):
     expr = self.expr.reduce(id_dicts)
     if expr.type() != Type.INTEGER:
         if expr.type() == Type.SPRITEGROUP_REF:
             raise generic.ProcCallSyntaxError(expr.name, expr.pos)
         raise generic.ScriptError("abs() requires an integer argument.", expr.pos)
     if isinstance(expr, ConstantNumeric):
         if expr.value < 0:
             return ConstantNumeric(-expr.value)
         else:
             return ConstantNumeric(expr.value)
     return AbsOp(expr, self.pos)
Beispiel #6
0
 def reduce(self, id_dicts=None, unknown_id_fatal=True):
     guard = self.guard.reduce(id_dicts)
     expr1 = self.expr1.reduce(id_dicts)
     expr2 = self.expr2.reduce(id_dicts)
     if isinstance(guard, ConstantNumeric):
         if guard.value != 0:
             return expr1
         else:
             return expr2
     if guard.type() != Type.INTEGER or expr1.type(
     ) != Type.INTEGER or expr2.type() != Type.INTEGER:
         if guard.type() == Type.SPRITEGROUP_REF:
             raise generic.ProcCallSyntaxError(guard.name, guard.pos)
         if expr1.type() == Type.SPRITEGROUP_REF:
             raise generic.ProcCallSyntaxError(expr1.name, expr1.pos)
         if expr2.type() == Type.SPRITEGROUP_REF:
             raise generic.ProcCallSyntaxError(expr2.name, expr2.pos)
         raise generic.ScriptError(
             "All parts of the ternary operator (?:) must be integers.",
             self.pos)
     return TernaryOp(guard, expr1, expr2, self.pos)
Beispiel #7
0
 def reduce(self, id_dicts=None, unknown_id_fatal=True):
     expr = self.expr.reduce(id_dicts)
     if expr.type() != Type.INTEGER:
         if expr.type() == Type.SPRITEGROUP_REF:
             raise generic.ProcCallSyntaxError(expr.name, expr.pos)
         raise generic.ScriptError(
             "Not-operator (~) requires an integer argument.", expr.pos)
     if isinstance(expr, ConstantNumeric):
         return ConstantNumeric(0xFFFFFFFF ^ expr.value)
     if isinstance(expr, BinNot):
         return expr.expr
     return BinNot(expr)
Beispiel #8
0
    def reduce(self, id_dicts=None, unknown_id_fatal=True):
        args = []
        if self.value is not None:
            value = self.value.reduce(id_dicts)
            if value.type() != Type.INTEGER:
                if value.type() == Type.SPRITEGROUP_REF:
                    raise generic.ProcCallSyntaxError(value.name, value.pos)
                raise generic.ScriptError("Value to store must be an integer.",
                                          value.pos)
            args.append(value)

        register = self.register.reduce(id_dicts)
        if register.type() != Type.INTEGER:
            if register.type() == Type.SPRITEGROUP_REF:
                raise generic.ProcCallSyntaxError(register.name, register.pos)
            raise generic.ScriptError("Register to access must be an integer.",
                                      register.pos)
        if isinstance(register,
                      ConstantNumeric) and register.value > self.info["max"]:
            raise generic.ScriptError(
                "Maximum register for {} is {:d}".format(
                    self.name, self.info["max"]), self.pos)
        if isinstance(
                register,
                ConstantNumeric) and register.value in self.info["reserved"]:
            raise generic.ScriptError(
                "Temporary registers from 128 to 255 are reserved for NML's internal calculations.",
                self.pos)
        args.append(register)

        if self.grfid is not None:
            grfid = self.grfid.reduce(id_dicts)
            # Test validity
            parse_string_to_dword(grfid)
            args.append(grfid)

        return StorageOp(self.name, args, self.pos)
Beispiel #9
0
 def reduce(self, id_dicts=None, unknown_id_fatal=True):
     ret = ConstantNumeric(0, self.pos)
     for orig_expr in self.values:
         val = orig_expr.reduce(id_dicts)
         if val.type() != Type.INTEGER:
             if val.type() == Type.SPRITEGROUP_REF:
                 raise generic.ProcCallSyntaxError(val.name, val.pos)
             raise generic.ScriptError(
                 "Parameters of 'bitmask' must be integers.", orig_expr.pos)
         if isinstance(val, ConstantNumeric) and val.value >= 32:
             raise generic.ScriptError(
                 "Parameters of 'bitmask' cannot be greater than 31",
                 orig_expr.pos)
         val = nmlop.SHIFT_LEFT(1, val)
         ret = nmlop.OR(ret, val)
     return ret.reduce()