コード例 #1
0
 def register_names(self):
     for i, tracktype in enumerate(self.tracktype_list):
         if isinstance(tracktype, assignment.Assignment):
             name = tracktype.name
             val_list = []
             for rt in tracktype.value:
                 if isinstance(rt, expression.Identifier):
                     val_list.append(
                         expression.StringLiteral(rt.value, rt.pos))
                 else:
                     val_list.append(rt)
                 expression.parse_string_to_dword(
                     val_list[-1]
                 )  # we don't care about the result, only validate the input
             self.tracktype_list[i] = val_list if len(
                 val_list) > 1 else val_list[0]
         else:
             name = tracktype
             if isinstance(tracktype, expression.Identifier):
                 self.tracktype_list[i] = expression.StringLiteral(
                     tracktype.value, tracktype.pos)
             expression.parse_string_to_dword(
                 self.tracktype_list[i]
             )  # we don't care about the result, only validate the input
         self.tracktype_table[name.value] = i
コード例 #2
0
ファイル: cargotable.py プロジェクト: stormcone/nml
 def register_names(self):
     generic.OnlyOnce.enforce(self, "cargo table")
     for i, cargo in enumerate(self.cargo_list):
         if isinstance(cargo, expression.Identifier):
             self.cargo_list[i] = expression.StringLiteral(
                 cargo.value, cargo.pos)
         expression.parse_string_to_dword(
             self.cargo_list[i]
         )  # we don't care about the result, only validate the input
         global_constants.cargo_numbers[self.cargo_list[i].value] = i
コード例 #3
0
    def pre_process(self):
        if len(self.args) not in (1, 2):
            raise generic.ScriptError("engine_override expects 1 or 2 parameters", self.pos)

        if len(self.args) == 1:
            try:
                self.source_grfid = expression.Identifier('GRFID').reduce(global_constants.const_list).value
                assert isinstance(self.source_grfid, int)
            except generic.ScriptError:
                raise generic.ScriptError("GRFID of this grf is required, but no grf-block is defined.", self.pos)
        else:
            self.source_grfid = expression.parse_string_to_dword(self.args[0].reduce(global_constants.const_list))

        self.grfid = expression.parse_string_to_dword(self.args[-1].reduce(global_constants.const_list))
コード例 #4
0
ファイル: grf.py プロジェクト: stormcone/nml
    def pre_process(self):
        if None in (self.name, self.desc, self.grfid, self.version, self.min_compatible_version):
            raise generic.ScriptError("A GRF-block requires the 'name', 'desc', 'grfid', 'version' and 'min_compatible_version' properties to be set.", self.pos)

        self.grfid = self.grfid.reduce()
        global_constants.constant_numbers['GRFID'] = expression.parse_string_to_dword(self.grfid)
        self.name = self.name.reduce()
        if not isinstance(self.name, expression.String):
            raise generic.ScriptError("GRF-name must be a string", self.name.pos)
        grfstrings.validate_string(self.name)
        self.desc = self.desc.reduce()
        if not isinstance(self.desc, expression.String):
            raise generic.ScriptError("GRF-description must be a string", self.desc.pos)
        grfstrings.validate_string(self.desc)
        if self.url is not None:
            self.url = self.url.reduce()
            if not isinstance(self.url, expression.String):
                raise generic.ScriptError("URL must be a string", self.url.pos)
            grfstrings.validate_string(self.url)
        self.version = self.version.reduce_constant()
        self.min_compatible_version = self.min_compatible_version.reduce_constant()

        global param_stats

        param_num = 0
        for param in self.params:
            param.pre_process(expression.ConstantNumeric(param_num))
            param_num = param.num.value + 1
            if param_num > param_stats[1]:
                raise generic.ScriptError("No free parameters available. Consider assigning <num> manually and combine multiple bool parameters into a single bitmask parameter using <bit>.", self.pos)
            if param_num > param_stats[0]:
                param_stats[0] = param_num
コード例 #5
0
    def preprocess_storageop(self, expr):
        assert isinstance(expr, expression.StorageOp)
        if expr.info["perm"] and self.var_feature not in (0x08, 0x0A, 0x0D):
            raise generic.ScriptError(
                "Persistent storage is not supported for feature '{}'".format(general.feature_name(self.var_feature)),
                expr.pos,
            )

        if expr.info["store"]:
            op = nmlop.STO_PERM if expr.info["perm"] else nmlop.STO_TMP
            ret = expression.BinOp(op, expr.value, expr.register, expr.pos)
        else:
            var_num = 0x7C if expr.info["perm"] else 0x7D
            ret = expression.Variable(expression.ConstantNumeric(var_num), param=expr.register, pos=expr.pos)

        if expr.info["perm"] and self.var_feature == 0x08:
            # store grfid in register 0x100 for town persistent storage
            grfid = expression.ConstantNumeric(
                0xFFFFFFFF if expr.grfid is None else expression.parse_string_to_dword(expr.grfid)
            )
            store_op = nmlop.STO_TMP(grfid, 0x100, expr.pos)
            ret = nmlop.VAL2(store_op, ret)
        elif expr.grfid is not None:
            raise generic.ScriptError("Specifying a grfid is only possible for town persistent storage.", expr.pos)
        return ret
コード例 #6
0
ファイル: action0.py プロジェクト: spnda/nml
def get_tracktypelist_action(table_prop_id, cond_tracktype_not_defined,
                             tracktype_list):
    action6.free_parameters.save()
    act6 = action6.Action6()

    action_list = []
    action0, offset = create_action0(0x08, expression.ConstantNumeric(0), act6,
                                     action_list)
    id_table = []
    offset += 1  # Skip property number
    for tracktype in tracktype_list:
        if isinstance(tracktype, expression.StringLiteral):
            id_table.append(tracktype)
            offset += 4
            continue
        param, extra_actions = actionD.get_tmp_parameter(
            expression.ConstantNumeric(
                expression.parse_string_to_dword(tracktype[-1])))
        action_list.extend(extra_actions)
        for idx in range(len(tracktype) - 2, -1, -1):
            val = expression.ConstantNumeric(
                expression.parse_string_to_dword(tracktype[idx]))
            action_list.append(
                action7.SkipAction(0x09, 0x00, 4,
                                   (cond_tracktype_not_defined, None),
                                   val.value, 1))
            action_list.append(
                actionD.ActionD(
                    expression.ConstantNumeric(param),
                    expression.ConstantNumeric(0xFF),
                    nmlop.ASSIGN,
                    expression.ConstantNumeric(0xFF),
                    val,
                ))
        act6.modify_bytes(param, 4, offset)
        id_table.append(expression.StringLiteral(r"\00\00\00\00", None))
        offset += 4
    action0.prop_list.append(IDListProp(table_prop_id, id_table))
    action0.num_ids = len(tracktype_list)

    if len(act6.modifications) > 0:
        action_list.append(act6)

    action_list.append(action0)
    action6.free_parameters.restore()
    return action_list
コード例 #7
0
ファイル: cargotable.py プロジェクト: spnda/nml
 def register_names(self):
     generic.OnlyOnce.enforce(self, "cargo table")
     for i, cargo in enumerate(self.cargo_list):
         if isinstance(cargo, expression.Identifier):
             self.cargo_list[i] = expression.StringLiteral(
                 cargo.value, cargo.pos)
         expression.parse_string_to_dword(
             self.cargo_list[i]
         )  # we don't care about the result, only validate the input
         if self.cargo_list[i].value in global_constants.cargo_numbers:
             generic.print_warning(
                 generic.Warning.GENERIC,
                 "Duplicate entry in cargo table: {}".format(
                     self.cargo_list[i].value),
                 cargo.pos,
             )
         else:
             global_constants.cargo_numbers[self.cargo_list[i].value] = i
コード例 #8
0
ファイル: railtypetable.py プロジェクト: stormcone/nml
 def register_names(self):
     generic.OnlyOnce.enforce(self, "rail type table")
     global_constants.is_default_railtype_table = False
     global_constants.railtype_table.clear()
     for i, railtype in enumerate(self.railtype_list):
         if isinstance(railtype, assignment.Assignment):
             name = railtype.name
             val_list = []
             for rt in railtype.value:
                 if isinstance(rt, expression.Identifier):
                     val_list.append(expression.StringLiteral(rt.value, rt.pos))
                 else:
                     val_list.append(rt)
                 expression.parse_string_to_dword(val_list[-1]) # we don't care about the result, only validate the input
             self.railtype_list[i] = val_list if len(val_list) > 1 else val_list[0]
         else:
             name = railtype
             if isinstance(railtype, expression.Identifier):
                 self.railtype_list[i] = expression.StringLiteral(railtype.value, railtype.pos)
             expression.parse_string_to_dword(self.railtype_list[i]) # we don't care about the result, only validate the input
         global_constants.railtype_table[name.value] = i
コード例 #9
0
ファイル: deactivate.py プロジェクト: werbfred/nml
 def pre_process(self):
     # Parse (string-)expressions to integers
     self.grfid_list = [
         expression.parse_string_to_dword(grfid.reduce())
         for grfid in self.grfid_list
     ]
コード例 #10
0
ファイル: actionD.py プロジェクト: OpenTTD/nml
def parse_actionD(assignment):
    assignment.value.supported_by_actionD(True)

    if isinstance(assignment.param, expression.SpecialParameter):
        assignment.param, assignment.value = assignment.param.to_assignment(assignment.value)
    elif isinstance(assignment.param, expression.Identifier):
        if global_constants.identifier_refcount[assignment.param.value] == 0:
            # Named parameter is not referenced, ignoring
            return []
        assignment.param = expression.Parameter(
            expression.ConstantNumeric(global_constants.named_parameters[assignment.param.value]), assignment.param.pos
        )
    assert isinstance(assignment.param, expression.Parameter)

    if isinstance(assignment.value, expression.SpecialParameter):
        assignment.value = assignment.value.to_reading()

    if isinstance(assignment.value, expression.TernaryOp):
        return parse_ternary_op(assignment)

    if isinstance(assignment.value, expression.AbsOp):
        return parse_abs_op(assignment)

    if isinstance(assignment.value, expression.SpecialCheck):
        return parse_special_check(assignment)

    if isinstance(assignment.value, expression.GRMOp):
        return parse_grm(assignment)

    if isinstance(assignment.value, expression.BinOp):
        op = assignment.value.op
        if op == nmlop.HASBIT or op == nmlop.NOTHASBIT:
            return parse_hasbit(assignment)
        elif op == nmlop.MIN or op == nmlop.MAX:
            return parse_min_max(assignment)

    if isinstance(assignment.value, expression.Boolean):
        return parse_boolean(assignment)

    if isinstance(assignment.value, expression.Not):
        expr = nmlop.SUB(1, assignment.value.expr)
        assignment = ParameterAssignment(assignment.param, expr)

    if isinstance(assignment.value, expression.BinNot):
        expr = nmlop.SUB(0xFFFFFFFF, assignment.value.expr)
        assignment = ParameterAssignment(assignment.param, expr)

    action6.free_parameters.save()
    action_list = []
    act6 = action6.Action6()
    assert isinstance(assignment.param, expression.Parameter)
    target = assignment.param.num
    if isinstance(target, expression.Parameter) and isinstance(target.num, expression.ConstantNumeric):
        act6.modify_bytes(target.num.value, 1, 1)
        target = expression.ConstantNumeric(0)
    elif not isinstance(target, expression.ConstantNumeric):
        tmp_param, tmp_param_actions = get_tmp_parameter(target)
        act6.modify_bytes(tmp_param, 1, 1)
        target = expression.ConstantNumeric(0)
        action_list.extend(tmp_param_actions)

    data = None
    # print assignment.value
    if isinstance(assignment.value, expression.ConstantNumeric):
        op = nmlop.ASSIGN
        param1 = expression.ConstantNumeric(0xFF)
        param2 = expression.ConstantNumeric(0)
        data = assignment.value
    elif isinstance(assignment.value, expression.Parameter):
        if isinstance(assignment.value.num, expression.ConstantNumeric):
            op = nmlop.ASSIGN
            param1 = assignment.value.num
        else:
            tmp_param, tmp_param_actions = get_tmp_parameter(assignment.value.num)
            act6.modify_bytes(tmp_param, 1, 3)
            action_list.extend(tmp_param_actions)
            op = nmlop.ASSIGN
            param1 = expression.ConstantNumeric(0)
        param2 = expression.ConstantNumeric(0)
    elif isinstance(assignment.value, expression.OtherGRFParameter):
        op = nmlop.ASSIGN
        if isinstance(assignment.value.num, expression.ConstantNumeric):
            param1 = assignment.value.num
        else:
            tmp_param, tmp_param_actions = get_tmp_parameter(assignment.value.num)
            act6.modify_bytes(tmp_param, 1, 3)
            action_list.extend(tmp_param_actions)
            param1 = expression.ConstantNumeric(0)
        param2 = expression.ConstantNumeric(0xFE)
        data = expression.ConstantNumeric(expression.parse_string_to_dword(assignment.value.grfid))
    elif isinstance(assignment.value, expression.PatchVariable):
        op = nmlop.ASSIGN
        param1 = expression.ConstantNumeric(assignment.value.num)
        param2 = expression.ConstantNumeric(0xFE)
        data = expression.ConstantNumeric(0xFFFF)
    elif isinstance(assignment.value, expression.BinOp):
        op, expr1, expr2, extra_actions = transform_bin_op(assignment)
        action_list.extend(extra_actions)

        if isinstance(expr1, expression.ConstantNumeric):
            param1 = expression.ConstantNumeric(0xFF)
            data = expr1
        elif isinstance(expr1, expression.Parameter) and isinstance(expr1.num, expression.ConstantNumeric):
            param1 = expr1.num
        else:
            tmp_param, tmp_param_actions = get_tmp_parameter(expr1)
            action_list.extend(tmp_param_actions)
            param1 = expression.ConstantNumeric(tmp_param)

        # We can use the data only for one for the parameters.
        # If the first parameter uses "data" we need a temp parameter for this one
        if isinstance(expr2, expression.ConstantNumeric) and data is None:
            param2 = expression.ConstantNumeric(0xFF)
            data = expr2
        elif isinstance(expr2, expression.Parameter) and isinstance(expr2.num, expression.ConstantNumeric):
            param2 = expr2.num
        else:
            tmp_param, tmp_param_actions = get_tmp_parameter(expr2)
            action_list.extend(tmp_param_actions)
            param2 = expression.ConstantNumeric(tmp_param)

    else:
        raise generic.ScriptError("Invalid expression in argument assignment", assignment.value.pos)

    if len(act6.modifications) > 0:
        action_list.append(act6)

    action_list.append(ActionD(target, param1, op, param2, data))
    action6.free_parameters.restore()
    return action_list