├── .editorconfig ├── .github └── workflows │ └── rust.yml ├── .gitignore ├── CHANGELOG.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── build ├── gen_macros.rs └── main.rs ├── doc ├── comparison-to-thtk.md ├── img │ └── sexy-error.png └── syntax.md ├── map ├── README.md ├── any.anmm ├── any.eclm ├── any.msgm ├── any.stdm ├── debug.eclm ├── th06.eclm ├── th06.msgm ├── th06.stdm ├── th07.eclm ├── th07.stdm ├── th08.eclm ├── th095.stdm ├── th10.msgm ├── th11-scene.msgm ├── th11.msgm ├── th14.stdm ├── v0.anmm ├── v2.anmm ├── v4.anmm └── v8.anmm ├── scripts └── make-win-release.py ├── snapshots ├── truth__diagnostic__unspanned.snap ├── truth__fmt__tests__fancy_formatting__after_trigger.snap ├── truth__fmt__tests__fancy_formatting__before_trigger.snap ├── truth__fmt__tests__fancy_formatting__fully_block.snap ├── truth__fmt__tests__fancy_formatting__fully_inline.snap ├── truth__fmt__tests__fancy_formatting__mixed_style.snap ├── truth__fmt__tests__goto__no_time.snap ├── truth__fmt__tests__goto__with_time.snap ├── truth__fmt__tests__optional_parens__cond_block.snap ├── truth__fmt__tests__optional_parens__cond_jump.snap ├── truth__fmt__tests__optional_parens__while.snap ├── truth__fmt__tests__optional_parens__with.snap ├── truth__fmt__tests__optional_parens__without.snap ├── truth__parse__abi__tests__attr_only_comma.snap ├── truth__parse__abi__tests__attr_trailing_comma.snap ├── truth__parse__abi__tests__bad_token.snap ├── truth__parse__abi__tests__double_attr.snap ├── truth__parse__abi__tests__duplicate_attr.snap ├── truth__parse__abi__tests__errant_close_paren.snap ├── truth__parse__abi__tests__errant_eq.snap ├── truth__parse__abi__tests__errant_quote.snap ├── truth__parse__abi__tests__initial_paren.snap ├── truth__parse__abi__tests__trick_close_paren_in_string.snap ├── truth__parse__abi__tests__trick_escaped_quote_in_string.snap ├── truth__parse__abi__tests__unclosed_paren.snap ├── truth__parse__tests__bad_escape.snap ├── truth__parse__tests__bad_escape_end.snap ├── truth__parse__tests__bad_ins_empty.snap ├── truth__parse__tests__bad_ins_identifier.snap ├── truth__parse__tests__bad_ins_identifier_2.snap ├── truth__parse__tests__bad_ins_overflow.snap ├── truth__parse__tests__big_reg.snap ├── truth__parse__tests__duplicate_meta_key.snap ├── truth__parse__tests__integer_overflow.snap ├── truth__parse__tests__invalid_token.snap ├── truth__parse__tests__unclosed_comment.snap ├── truth__parse__tests__unexpected_eof.snap ├── truth__parse__tests__unexpected_token.snap ├── truth__resolve__tests__call_of_undefined_func.snap ├── truth__resolve__tests__const_after_scope_end.snap ├── truth__resolve__tests__const_redefinition.snap ├── truth__resolve__tests__const_scoped_redefinition.snap ├── truth__resolve__tests__const_scoped_using_local.snap ├── truth__resolve__tests__const_scoped_using_outer_local.snap ├── truth__resolve__tests__const_shadow.snap ├── truth__resolve__tests__const_shadows_outer_local.snap ├── truth__resolve__tests__func_after_scope_end.snap ├── truth__resolve__tests__func_redefinition.snap ├── truth__resolve__tests__func_scoped_redefinition.snap ├── truth__resolve__tests__func_scoped_shadows_ins_alias.snap ├── truth__resolve__tests__func_scoped_using_local.snap ├── truth__resolve__tests__func_scoped_using_outer_param.snap ├── truth__resolve__tests__func_scoped_using_outer_shadowed_const.snap ├── truth__resolve__tests__local_after_scope_end.snap ├── truth__resolve__tests__local_disjoint.snap ├── truth__resolve__tests__local_redefinition.snap ├── truth__resolve__tests__local_shadow.snap ├── truth__resolve__tests__local_shadows_outer_const.snap ├── truth__resolve__tests__local_shadows_reg_alias.snap ├── truth__resolve__tests__local_using_itself.snap ├── truth__resolve__tests__param_redefinition.snap └── truth__resolve__tests__separate_namespaces.snap ├── src ├── api.rs ├── ast │ ├── meta.rs │ ├── mod.rs │ └── pseudo.rs ├── bin │ ├── common │ │ └── mod.rs │ ├── truanm.rs │ ├── truecl.rs │ ├── trumsg.rs │ ├── trustd.rs │ └── truth-core.rs ├── bitset.rs ├── cli_def.rs ├── context │ ├── consts.rs │ ├── defs.rs │ ├── diff_flags.rs │ └── mod.rs ├── core_mapfiles │ ├── anm.rs │ ├── ecl.rs │ ├── mod.rs │ ├── msg.rs │ └── std.rs ├── debug_info │ └── mod.rs ├── diagnostic.rs ├── diff_switch_utils.rs ├── error.rs ├── fmt.rs ├── formats │ ├── anm │ │ ├── image_io.rs │ │ ├── mod.rs │ │ ├── read_write.rs │ │ └── soft_option.rs │ ├── ecl │ │ ├── ecl_06.rs │ │ ├── ecl_10.rs │ │ └── mod.rs │ ├── mission.rs │ ├── mod.rs │ ├── msg.rs │ └── std.rs ├── game.rs ├── ident.rs ├── image │ ├── color.rs │ └── mod.rs ├── io.rs ├── lib.rs ├── llir │ ├── abi.rs │ ├── intrinsic.rs │ ├── lower.rs │ ├── lower │ │ ├── intrinsic.rs │ │ └── stackless.rs │ ├── mod.rs │ ├── raise.rs │ └── raise │ │ ├── early.rs │ │ ├── infer_pcb_signatures.rs │ │ ├── late.rs │ │ └── recognize.rs ├── mapfile.rs ├── parse │ ├── abi.rs │ ├── abi_attrs.lalrpop │ ├── lalrparser.lalrpop │ ├── lalrparser_util.rs │ ├── lexer.rs │ ├── mod.rs │ ├── seqmap.rs │ ├── tests.rs │ └── token_macro.rs ├── passes │ ├── const_simplify.rs │ ├── debug │ │ └── make_idents_unique.rs │ ├── decompile_loop.rs │ ├── desugar_blocks.rs │ ├── mod.rs │ ├── resolution.rs │ ├── semantics │ │ └── time_and_difficulty.rs │ ├── type_check.rs │ ├── unused_labels.rs │ └── validate_difficulty.rs ├── pos │ ├── mod.rs │ ├── source_map.rs │ ├── source_str.rs │ └── span.rs ├── quote.rs ├── raw.rs ├── resolve │ ├── mod.rs │ └── tests.rs ├── util_macros.rs ├── value.rs └── vm.rs ├── tests ├── cli-help-version.rs ├── compile-fail │ ├── integration__integration__anm_consts__decompile_double_id.snap │ ├── integration__integration__anm_consts__err_sprite_clash.snap │ ├── integration__integration__anm_consts__err_sprite_clash_implicit.snap │ ├── integration__integration__anm_consts__meta_non_const.snap │ ├── integration__integration__anm_consts__meta_sprite_id_circular_dependency.snap │ ├── integration__integration__anm_consts__meta_sprite_id_dupe_non_const.snap │ ├── integration__integration__anm_consts__meta_sprite_id_dupe_type_error.snap │ ├── integration__integration__anm_consts__meta_sprite_id_non_const.snap │ ├── integration__integration__anm_consts__meta_sprite_id_type_error.snap │ ├── integration__integration__anm_consts__sprite_as_script_id.snap │ ├── integration__integration__anm_features__anti_scratch_bad_in_func.snap │ ├── integration__integration__anm_features__orphaned_script.snap │ ├── integration__integration__count_jmps__gt_jmp_can_suggest_ne.snap │ ├── integration__integration__count_jmps__ne_jmp_can_suggest_gt.snap │ ├── integration__integration__decompile_block__decompile_labels_before_smorgasboard.snap │ ├── integration__integration__difficulty__diff_label_in_non_ecl.snap │ ├── integration__integration__difficulty__diff_label_with_time_label_bad_1.snap │ ├── integration__integration__difficulty__diff_label_with_time_label_bad_2.snap │ ├── integration__integration__difficulty__diff_switch_in_const_fn_call.snap │ ├── integration__integration__difficulty__diff_switch_in_inline_fn_call.snap │ ├── integration__integration__difficulty__diff_switch_in_non_ecl.snap │ ├── integration__integration__difficulty__diff_switch_mismatched_number_of_cases.snap │ ├── integration__integration__difficulty__diff_switch_too_many_cases.snap │ ├── integration__integration__ecl_features__eosd_cant_cast.snap │ ├── integration__integration__ecl_features__eosd_exported_fn_bad_siggies.snap │ ├── integration__integration__ecl_features__eosd_exported_fn_bad_siggy_return_type.snap │ ├── integration__integration__ecl_features__eosd_exported_fn_bad_siggy_string.snap │ ├── integration__integration__ecl_features__eosd_exported_fn_const_fn_name_clash.snap │ ├── integration__integration__ecl_features__eosd_exported_fn_no_blob.snap │ ├── integration__integration__ecl_features__eosd_exported_fn_no_pseudos.snap │ ├── integration__integration__ecl_features__eosd_param_alias_warning_named.snap │ ├── integration__integration__ecl_features__eosd_param_alias_warning_reg.snap │ ├── integration__integration__ecl_features__eosd_param_is_not_scratch.snap │ ├── integration__integration__ecl_features__eosd_patchy_is_goddamn_dangerous.snap │ ├── integration__integration__ecl_features__eosd_unnamed_param_still_prevents_scratch.snap │ ├── integration__integration__ecl_features__olde_unsupported_extern.snap │ ├── integration__integration__ecl_features__olde_unsupported_return_type.snap │ ├── integration__integration__enums__compile_bad_conflict.snap │ ├── integration__integration__enums__decompile_bad_conflict.snap │ ├── integration__integration__enums__deduction_in_const_fn.snap │ ├── integration__integration__enums__enum_arg_not_ident.snap │ ├── integration__integration__enums__enum_def_not_ident.snap │ ├── integration__integration__enums__legal_conflict_used_ambiguously.snap │ ├── integration__integration__enums__other_enum.snap │ ├── integration__integration__enums__undefined_enum__compile_undefined.snap │ ├── integration__integration__enums__undefined_enum__compile_undefined_in_ast.snap │ ├── integration__integration__enums__undefined_enum__compile_undefined_in_dot_syntax.snap │ ├── integration__integration__enums__undefined_enum__decompile_undefined.snap │ ├── integration__integration__enums__undefined_enum__suggestion.snap │ ├── integration__integration__expr_compile__unary_neg_fallbacks_unavailable.snap │ ├── integration__integration__general__anm_bitwise.snap │ ├── integration__integration__general__arg_count_fixed.snap │ ├── integration__integration__general__arg_count_range.snap │ ├── integration__integration__general__bad_signature_in_mapfile.snap │ ├── integration__integration__general__break_outside_loop.snap │ ├── integration__integration__general__break_outside_loop_in_nested_func.snap │ ├── integration__integration__general__const_calling_non_const.snap │ ├── integration__integration__general__const_difficulty.snap │ ├── integration__integration__general__const_reg.snap │ ├── integration__integration__general__const_sigil.snap │ ├── integration__integration__general__const_untyped.snap │ ├── integration__integration__general__const_void.snap │ ├── integration__integration__general__decompile_missing_signature.snap │ ├── integration__integration__general__duplicate_label.snap │ ├── integration__integration__general__eosd_anm_early_end.snap │ ├── integration__integration__general__func_const_ins.snap │ ├── integration__integration__general__func_const_reg.snap │ ├── integration__integration__general__func_exported_string.snap │ ├── integration__integration__general__func_inline_const.snap │ ├── integration__integration__general__func_param_named_after_reg.snap │ ├── integration__integration__general__func_untyped.snap │ ├── integration__integration__general__jump_missing_label.snap │ ├── integration__integration__general__jump_offsetof_expression.snap │ ├── integration__integration__general__local_in_std.snap │ ├── integration__integration__general__local_named_after_reg.snap │ ├── integration__integration__general__local_string.snap │ ├── integration__integration__general__local_void.snap │ ├── integration__integration__general__recursive_const.snap │ ├── integration__integration__general__reg_in_unsupported_lang.snap │ ├── integration__integration__general__stackless__untyped_var.snap │ ├── integration__integration__general__uninitialized_const.snap │ ├── integration__integration__general__unknown_instr_name.snap │ ├── integration__integration__general__unknown_instr_signature.snap │ ├── integration__integration__general__unknown_variable.snap │ ├── integration__integration__general__xcrement_in_unsupported_spot.snap │ ├── integration__integration__image_sources__anm_import_wrong_img_height__failure.snap │ ├── integration__integration__image_sources__anm_import_wrong_img_height_then_png__failure.snap │ ├── integration__integration__image_sources__color_formats__bad_dummy.snap │ ├── integration__integration__image_sources__color_formats__bad_dummy_with_no_span.snap │ ├── integration__integration__image_sources__color_formats__bad_image.snap │ ├── integration__integration__image_sources__color_formats__bad_image_into_with_no_span.snap │ ├── integration__integration__image_sources__color_formats__bad_transcode_from.snap │ ├── integration__integration__image_sources__color_formats__bad_transcode_into.snap │ ├── integration__integration__image_sources__image_source_does_not_exist.snap │ ├── integration__integration__image_sources__image_source_in_msg.snap │ ├── integration__integration__image_sources__image_source_in_olde_ecl.snap │ ├── integration__integration__image_sources__image_source_in_std.snap │ ├── integration__integration__image_sources__no_source__err_dummy_missing_img_dim.snap │ ├── integration__integration__image_sources__no_source__err_missing_image.snap │ ├── integration__integration__image_sources__no_source__err_missing_metadata.snap │ ├── integration__integration__image_sources__png_import_buf_not_power_2.snap │ ├── integration__integration__image_sources__png_import_buf_too_small.snap │ ├── integration__integration__image_sources__png_import_with_offset_too_big__failure.snap │ ├── integration__integration__image_sources__png_import_wrong_img_height__failure.snap │ ├── integration__integration__interrupts__sugar_register.snap │ ├── integration__integration__mapfiles__abi_multiple_o.snap │ ├── integration__integration__mapfiles__abi_string_errors.snap │ ├── integration__integration__mapfiles__diff_flags_bad_index.snap │ ├── integration__integration__mapfiles__diff_flags_syntax_errors.snap │ ├── integration__integration__mapfiles__enum_type_conflicts_with_builtin.snap │ ├── integration__integration__mapfiles__intrinsic_has_extra_arg.snap │ ├── integration__integration__mapfiles__intrinsic_has_insufficient_args.snap │ ├── integration__integration__mapfiles__intrinsic_jmp_mislabeled_time.snap │ ├── integration__integration__mapfiles__intrinsic_jmp_needs_offset.snap │ ├── integration__integration__mapfiles__intrinsic_jmp_non_consecutive_offset_time.snap │ ├── integration__integration__mapfiles__intrinsic_name_garbage.snap │ ├── integration__integration__mapfiles__intrinsic_op_input_arg_wrong_type.snap │ ├── integration__integration__mapfiles__intrinsic_op_output_arg_wrong_type.snap │ ├── integration__integration__mapfiles__intrinsic_with_mismatched_signature_in_core_map.snap │ ├── integration__integration__mapfiles__intrinsic_without_signature.snap │ ├── integration__integration__mapfiles__keywords_or_forbidden_idents.snap │ ├── integration__integration__mapfiles__mapfile_does_not_exist.snap │ ├── integration__integration__mapfiles__seqmap_missing_magic.snap │ ├── integration__integration__mapfiles__seqmap_missing_section_header.snap │ ├── integration__integration__msg_features__duplicate_script.snap │ ├── integration__integration__msg_features__integer_meta_key_normalization.snap │ ├── integration__integration__msg_features__table_len_too_short.snap │ ├── integration__integration__msg_features__unused_script.snap │ ├── integration__integration__pseudo__pseudo_after_arg.snap │ ├── integration__integration__pseudo__pseudo_bad_name.snap │ ├── integration__integration__pseudo__pseudo_blob_with_arg.snap │ ├── integration__integration__pseudo__pseudo_dupe.snap │ ├── integration__integration__pseudo__pseudo_in_const_call.snap │ ├── integration__integration__pseudo__pseudo_in_inline_call.snap │ ├── integration__integration__pseudo__pseudo_len_ndiv_4.snap │ ├── integration__integration__pseudo__pseudo_non_const.snap │ ├── integration__integration__std_features__bad_object_name.snap │ ├── integration__integration__std_features__renamed_layer_conflict.snap │ ├── integration__integration__std_features__renamed_layer_missing.snap │ ├── integration__integration__std_features__strip_in_bad_game.snap │ ├── integration__integration__strings__compile_string_arg_too_big_eq.snap │ ├── integration__integration__strings__compile_string_arg_too_big_gt.snap │ ├── integration__integration__strings__compile_string_arg_too_big_gt_nulless.snap │ ├── integration__integration__strings__decompile_string_arg_with_null_1.snap │ ├── integration__integration__strings__decompile_string_arg_with_null_2.snap │ ├── integration__integration__strings__decompile_string_arg_with_null_3.snap │ ├── integration__integration__strings__decompile_string_arg_with_null_4.snap │ ├── integration__integration__strings__decompile_string_arg_without_null_bs.snap │ ├── integration__integration__strings__decompile_string_arg_without_null_fixed.snap │ ├── integration__integration__strings__decompile_string_reg.snap │ ├── integration__integration__strings__encoding_error_in_arg.snap │ ├── integration__integration__strings__encoding_error_in_meta.snap │ ├── integration__integration__strings__shift_jis_in_source_file.snap │ ├── integration__integration__strings__std_string128_overflow.snap │ ├── integration__integration__time_label_compilation__non_const.snap │ ├── integration__integration__time_label_formatting__after_neg.snap │ ├── integration__integration__time_label_formatting__compression.snap │ ├── integration__integration__time_label_formatting__general_1.snap │ ├── integration__integration__time_label_formatting__general_2.snap │ ├── integration__integration__timeline_arg0__bad_arity_with_required_arg0.snap │ ├── integration__integration__timeline_arg0__bad_type_for_explicit_arg0.snap │ ├── integration__integration__timeline_arg0__reg_as_positional_arg0.snap │ ├── integration__integration__timeline_arg0__signature_with_arg0_in_not_timeline.snap │ ├── integration__integration__timeline_arg0__signature_with_arg0_in_th08_timeline.snap │ ├── integration__integration__timeline_arg0__warn_arg0_collision.snap │ ├── integration__integration__timeline_arg0__wrong_lang.snap │ ├── integration__integration__timelines__duplicate.snap │ ├── integration__integration__timelines__duplicate_implicit.snap │ ├── integration__integration__timelines__missing.snap │ ├── integration__integration__timelines__mixture_of_auto_and_explicit.snap │ ├── integration__integration__timelines__negative.snap │ ├── integration__integration__timelines__too_many_6.snap │ ├── integration__integration__timelines__too_many_7.snap │ ├── integration__integration__type_check__bad_declaration.snap │ ├── integration__integration__type_check__basic_type_checking.snap │ ├── integration__integration__type_check__binop_two_strings.snap │ ├── integration__integration__type_check__const_short_circuit.snap │ ├── integration__integration__type_check__diffswitch.snap │ ├── integration__integration__type_check__diffswitch__missing_first.snap │ ├── integration__integration__type_check__ins_arg_binop_str__stackless.snap │ ├── integration__integration__type_check__ins_arg_neg_str.snap │ ├── integration__integration__type_check__ins_arg_var.snap │ ├── integration__integration__type_check__jump_time.snap │ ├── integration__integration__type_check__jumps.snap │ ├── integration__integration__type_check__non_void_expr_statement.snap │ ├── integration__integration__type_check__pseudo.snap │ ├── integration__integration__type_check__return__missing_from_value.snap │ ├── integration__integration__type_check__return__missing_from_void__stackless.snap │ ├── integration__integration__type_check__return__none_from_value.snap │ ├── integration__integration__type_check__return__none_from_void.snap │ ├── integration__integration__type_check__return__value_from_value.snap │ ├── integration__integration__type_check__return__value_from_void.snap │ ├── integration__integration__type_check__return__void_from_value.snap │ ├── integration__integration__type_check__return__void_from_void.snap │ ├── integration__integration__type_check__simple_expr_types.snap │ ├── integration__integration__type_check__sprite_is_int.snap │ ├── integration__integration__type_check__times.snap │ └── integration__integration__type_check__untyped_vars.snap ├── expr_compile.rs ├── integration.rs ├── integration │ ├── anm_consts.rs │ ├── anm_features.rs │ ├── bits-2-bits │ │ ├── th06-general.std │ │ ├── th06-multiple-scripts.msg │ │ ├── th06-z-string.msg │ │ ├── th08-empty-script.std │ │ ├── th08-instance-order.std │ │ ├── th08-m-string.msg │ │ ├── th08-nonzero-padding.std │ │ ├── th08-rects.std │ │ ├── th08-strip.std │ │ ├── th09-default-mismatched-flags.msg │ │ ├── th09-default-zero-with-flags.msg │ │ ├── th09-default-zero.msg │ │ ├── th09-m-string.msg │ │ ├── th09-no-default.msg │ │ ├── th11-furibug-not-applicable.msg │ │ ├── th12-anchor-ss-signature.anm │ │ ├── th12-furibug.msg │ │ ├── th12-general.std │ │ ├── th12-registers.anm │ │ ├── th12-sprite-duplicates.anm │ │ ├── th12-sprite-non-sequential.anm │ │ ├── th12-sprite-script-args.anm │ │ ├── th12-sprite-unset.anm │ │ ├── th12-weird-color-format.anm │ │ └── th17-furibug-ex-regression.msg │ ├── bits_2_bits.rs │ ├── count_jmps.rs │ ├── decompile_block.rs │ ├── difficulty.rs │ ├── ecl_features.rs │ ├── enums.rs │ ├── expr_compile.rs │ ├── general.rs │ ├── image_sources.rs │ ├── interrupts.rs │ ├── mapfiles.rs │ ├── msg_features.rs │ ├── pseudo.rs │ ├── resources │ │ ├── dir-with-bad-images │ │ │ └── subdir │ │ │ │ ├── hai-10x18+105+9.png │ │ │ │ └── hi-32x16.png │ │ ├── dir-with-images │ │ │ └── subdir │ │ │ │ ├── hai-10x18+105+9.png │ │ │ │ ├── hai-10x18.png │ │ │ │ ├── hi-32x16.png │ │ │ │ ├── hi-7x20.png │ │ │ │ └── modified-size.png │ │ ├── dir-with-modified-images │ │ │ └── subdir │ │ │ │ ├── hai-10x18+105+9.png │ │ │ │ ├── hai-10x18.png │ │ │ │ └── modified-size.png │ │ ├── dir-with-nothing-really │ │ │ └── .gitkeep │ │ ├── dir-with-other-images │ │ │ ├── lmao.png │ │ │ └── teeny.png │ │ ├── multiple-mapfiles-1.anmm │ │ ├── multiple-mapfiles-2.anmm │ │ ├── th12-embedded-bad-image-source.anm │ │ ├── th12-embedded-bad-image-source.anm.spec │ │ ├── th12-embedded-image-source.anm │ │ ├── th12-embedded-image-source.anm.spec │ │ ├── th12-embedded-weird-format-source.anm │ │ ├── th12-embedded-weird-format-source.anm.spec │ │ ├── th12-multiple-match-source.anm │ │ ├── th12-multiple-match-source.anm.spec │ │ ├── th12-multiple-same-source.anm │ │ └── th12-multiple-same-source.anm.spec │ ├── snapshots │ │ ├── integration__integration__bits_2_bits__anm12_anchor_ss_signature.snap │ │ ├── integration__integration__bits_2_bits__anm12_registers.snap │ │ ├── integration__integration__bits_2_bits__anm12_sprite_duplicates.snap │ │ ├── integration__integration__bits_2_bits__anm12_sprite_non_sequential.snap │ │ ├── integration__integration__bits_2_bits__anm12_sprite_script_args.snap │ │ ├── integration__integration__bits_2_bits__anm12_sprite_unset.snap │ │ ├── integration__integration__bits_2_bits__anm12_unknown_signature.snap │ │ ├── integration__integration__bits_2_bits__anm12_weird_color_format.snap │ │ ├── integration__integration__bits_2_bits__msg06_multiple_scripts.snap │ │ ├── integration__integration__bits_2_bits__msg06_z_string.snap │ │ ├── integration__integration__bits_2_bits__msg08_m_string.snap │ │ ├── integration__integration__bits_2_bits__msg09_default_mismatched_flags.snap │ │ ├── integration__integration__bits_2_bits__msg09_default_zero.snap │ │ ├── integration__integration__bits_2_bits__msg09_default_zero_with_flags.snap │ │ ├── integration__integration__bits_2_bits__msg09_m_string.snap │ │ ├── integration__integration__bits_2_bits__msg09_no_default.snap │ │ ├── integration__integration__bits_2_bits__msg11_furibug_not_applicable.snap │ │ ├── integration__integration__bits_2_bits__msg12_furibug.snap │ │ ├── integration__integration__bits_2_bits__msg17_furibug_ex_regression.snap │ │ ├── integration__integration__bits_2_bits__std06_general.snap │ │ ├── integration__integration__bits_2_bits__std08_empty_script.snap │ │ ├── integration__integration__bits_2_bits__std08_instance_order.snap │ │ ├── integration__integration__bits_2_bits__std08_nonzero_padding.snap │ │ ├── integration__integration__bits_2_bits__std08_rects.snap │ │ ├── integration__integration__bits_2_bits__std08_strip.snap │ │ └── integration__integration__bits_2_bits__std12_general.snap │ ├── std_features.rs │ ├── strings.rs │ ├── time_label_compilation.rs │ ├── time_label_formatting.rs │ ├── timeline_arg0.rs │ ├── timelines.rs │ └── type_check.rs └── integration_impl │ ├── formats.rs │ ├── mod.rs │ ├── parse_errors.rs │ ├── source_test.rs │ └── test_file.rs ├── update-dumps-example.yaml └── update-dumps.py /.editorconfig: -------------------------------------------------------------------------------- 1 | # top-most EditorConfig file 2 | root = true 3 | 4 | # Unix-style newlines with a newline ending every file 5 | [*] 6 | end_of_line = lf 7 | insert_final_newline = true 8 | -------------------------------------------------------------------------------- /.github/workflows/rust.yml: -------------------------------------------------------------------------------- 1 | name: Cargo Build & Test 2 | 3 | on: 4 | push: 5 | branches: ["main"] 6 | pull_request: 7 | 8 | env: 9 | CARGO_TERM_COLOR: always 10 | 11 | jobs: 12 | build_and_test: 13 | name: Rust project - latest 14 | runs-on: ubuntu-latest 15 | strategy: 16 | matrix: 17 | toolchain: 18 | - stable 19 | - beta 20 | steps: 21 | - uses: actions/checkout@v2 22 | - run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }} 23 | - run: cargo build --verbose 24 | - run: cargo test --verbose 25 | 26 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /release 3 | .idea 4 | .vscode 5 | /all-dumps 6 | update-dumps.yaml 7 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "truth" 3 | version = "0.5.2" 4 | authors = ["Michael Lamparski "] 5 | edition = "2021" 6 | build = "build/main.rs" 7 | default-run = "truth-core" 8 | license = "Apache-2.0" 9 | 10 | [build-dependencies] 11 | lalrpop = { version = "0.19.5", features = ['lexer'] } 12 | 13 | [dependencies] 14 | lazy_static = "1.4.0" 15 | lalrpop-util = { version = "0.19.0", features = ['lexer'] } 16 | regex = "1" 17 | getopts = "0.2.21" 18 | indexmap = "1.6.1" 19 | byteorder = "1.3" 20 | thiserror = "1.0" 21 | codespan-reporting = "0.11" 22 | codespan = "0.11" 23 | enum-map = "0.6.4" 24 | git-version = "0.3.4" 25 | logos = "0.12" 26 | encoding_rs = "0.8" 27 | atty = "0.2" 28 | walkdir = "2" 29 | arrayvec = "0.7" 30 | strum = { version = "0.22", features = ['derive'] } 31 | strsim = "0.10" 32 | serde = { version = "1.0", features = ['derive'] } 33 | serde_json = "1.0" 34 | 35 | [dependencies.image] 36 | version = "0.23.14" 37 | default-features = false 38 | features = ['png', 'gif', 'bmp'] 39 | 40 | [dev-dependencies] 41 | insta = "1.3" 42 | tempfile = "3.0" 43 | assert_cmd = "1.0" 44 | predicates = "1.0" 45 | rand = "0.7.3" 46 | bstr = "0.2" 47 | 48 | [profile.release] 49 | debug = true 50 | 51 | # This is used at build time, so optimizing it immensely speeds up debug builds. 52 | [profile.dev.package.lalrpop] 53 | opt-level = 3 54 | -------------------------------------------------------------------------------- /build/main.rs: -------------------------------------------------------------------------------- 1 | mod gen_macros; 2 | use lalrpop; 3 | 4 | fn main() { 5 | lalrpop::Configuration::new() 6 | .emit_rerun_directives(true) 7 | .process_current_dir().unwrap(); 8 | 9 | let out_dir = std::path::PathBuf::from(std::env::var("OUT_DIR").unwrap()); 10 | std::fs::write(out_dir.join("generated_macros.rs"), gen_macros::gen_ast_macros()).unwrap(); 11 | } 12 | -------------------------------------------------------------------------------- /doc/img/sexy-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/doc/img/sexy-error.png -------------------------------------------------------------------------------- /map/README.md: -------------------------------------------------------------------------------- 1 | # pre-packaged mapfiles 2 | 3 | These mapfiles are available for your personal use. They are mostly based on [priw8's eclfiles repo](https://github.com/Priw8/eclmap). 4 | 5 | The recommended files to use are: 6 | 7 | * `any.anmm` for ANM 8 | * `any.stdm` for STD 9 | 10 | If you mess around a lot with decompilation and hate writing the path to this directory, you can tell `truth` to use these files by default during decompilation by pointing `TRUTH_MAPFILE_PATH` to this directory. (the resulting scripts will contain an absolute path reference to this directory, so don't do this for things you're checking into VCS!) 11 | -------------------------------------------------------------------------------- /map/any.anmm: -------------------------------------------------------------------------------- 1 | !gamemap 2 | !game_files 3 | 6 v0.anmm 4 | 7 v2.anmm 5 | 8 v2.anmm 6 | 9 v2.anmm 7 | 95 v4.anmm 8 | 10 v4.anmm 9 | 103 v4.anmm 10 | 11 v4.anmm 11 | 12 v4.anmm 12 | 125 v4.anmm 13 | 128 v4.anmm 14 | 13 v8.anmm 15 | 14 v8.anmm 16 | 143 v8.anmm 17 | 15 v8.anmm 18 | 16 v8.anmm 19 | 165 v8.anmm 20 | 17 v8.anmm 21 | 18 v8.anmm 22 | 185 v8.anmm 23 | # NEWHU: 185 24 | -------------------------------------------------------------------------------- /map/any.eclm: -------------------------------------------------------------------------------- 1 | !gamemap 2 | !game_files 3 | 6 th06.eclm 4 | 7 th07.eclm 5 | 8 th08.eclm 6 | 9 th08.eclm 7 | 95 th095.eclm 8 | 10 debug.eclm 9 | 103 debug.eclm 10 | 11 debug.eclm 11 | 12 debug.eclm 12 | 125 debug.eclm 13 | 128 debug.eclm 14 | 13 debug.eclm 15 | 14 debug.eclm 16 | 143 debug.eclm 17 | 15 debug.eclm 18 | 16 debug.eclm 19 | 165 debug.eclm 20 | 17 debug.eclm 21 | 18 debug.eclm 22 | 185 debug.eclm 23 | # NEWHU: 185 24 | -------------------------------------------------------------------------------- /map/any.msgm: -------------------------------------------------------------------------------- 1 | !gamemap 2 | !game_files 3 | 6 th06.msgm 4 | 7 th06.msgm 5 | 8 th06.msgm 6 | 9 th06.msgm 7 | 95 empty.msgm 8 | 10 th10.msgm 9 | 103 th10.msgm 10 | 11 th11.msgm 11 | 12 th11.msgm 12 | 125 empty.msgm 13 | 128 th11.msgm 14 | 13 th11.msgm 15 | 14 th11.msgm 16 | 143 th11-scene.msgm 17 | 15 th11.msgm 18 | 16 th11.msgm 19 | 165 th11-scene.msgm 20 | 17 th11.msgm 21 | 18 th11.msgm 22 | 185 th11.msgm 23 | # NEWHU: 185 24 | -------------------------------------------------------------------------------- /map/any.stdm: -------------------------------------------------------------------------------- 1 | !gamemap 2 | !game_files 3 | 6 th06.stdm 4 | 7 th07.stdm 5 | 8 th07.stdm 6 | 9 th07.stdm 7 | 95 th095.stdm 8 | 10 th095.stdm 9 | 103 th095.stdm 10 | 11 th095.stdm 11 | 12 th095.stdm 12 | 125 th095.stdm 13 | 128 th095.stdm 14 | 13 th095.stdm 15 | 14 th14.stdm 16 | 143 th14.stdm 17 | 15 th14.stdm 18 | 16 th14.stdm 19 | 165 th14.stdm 20 | 17 th14.stdm 21 | 18 th14.stdm 22 | 185 th14.stdm 23 | # NEWHU: 185 24 | -------------------------------------------------------------------------------- /map/debug.eclm: -------------------------------------------------------------------------------- 1 | !eclmap 2 | 3 | !ins_names 4 | 2 5 | 27 cmpInt 6 | 29 jmpLt 7 | 8 | 10 eclOnly 9 | 11 dummy 10 | 11 | !ins_signatures 12 | 2 to 13 | 10 SS 14 | 11 15 | 27 SS 16 | 29 to 17 | 18 | !gvar_names 19 | -10001 I0 20 | 21 | !gvar_types 22 | -10001 $ 23 | 24 | !timeline_ins_names 25 | 10 timelineOnly 26 | 11 hasSubArg0 27 | 12 hasMsgArg0 28 | 13 hasUnusedArg0 29 | 30 | !timeline_ins_signatures 31 | 10 ff 32 | 11 s(arg0;enum="EclSub")SS 33 | 12 s(arg0;enum="MsgScript")SS 34 | 13 SS 35 | -------------------------------------------------------------------------------- /map/th06.msgm: -------------------------------------------------------------------------------- 1 | !msgmap 2 | !ins_names 3 | 0 end 4 | 1 show 5 | 2 face 6 | 3 textSet 7 | 4 textPause 8 | 5 anmInterrupt 9 | 6 eclResume 10 | 7 music 11 | 8 intro # introduction text 12 | 9 stageResults 13 | 10 stop # wait(infinity) 14 | 11 stageEnd 15 | 12 musicEnd 16 | 13 skippable 17 | 14 screenFade 18 | 15 focusSetEx 19 | 16 textAdd 20 | 17 focusSet 21 | # 18 only in TH08 msg4dm.dat 22 | 19 optionA 23 | 20 optionB 24 | 21 optionPause 25 | 22 option22 26 | # FIXME 23-28 27 | -------------------------------------------------------------------------------- /map/th06.stdm: -------------------------------------------------------------------------------- 1 | !stdmap 2 | 3 | # STD - TH06 only 4 | 5 | !ins_names 6 | 0 posKeyframe 7 | 1 fog 8 | 2 facing 9 | 3 facingTime 10 | 4 fogTime 11 | 5 pause # unpause from ECL 12 | 13 | # that's all, folks 14 | -------------------------------------------------------------------------------- /map/th07.stdm: -------------------------------------------------------------------------------- 1 | !stdmap 2 | 3 | # STD - TH07 to TH09 4 | 5 | !ins_names 6 | 0 posKeyframe 7 | 1 fog 8 | 2 fogTime 9 | 3 stop 10 | 4 jmp 11 | 5 pos 12 | 6 posTime 13 | 7 facing 14 | 8 facingTime 15 | 9 up 16 | 10 upTime 17 | 11 fov 18 | 12 fovTime 19 | 13 clearColor 20 | 14 posInitial 21 | 15 posFinal 22 | 16 posInitialDeriv 23 | 17 posFinalDeriv 24 | 18 posBezier 25 | 19 facingInitial 26 | 20 facingFinal 27 | 21 facingInitialDeriv 28 | 22 facingFinalDeriv 29 | 23 facingBezier 30 | 24 upInitial 31 | 25 upFinal 32 | 26 upInitialDeriv 33 | 27 upFinalDeriv 34 | 28 upBezier 35 | 29 spriteA 36 | 30 spriteB 37 | 31 interruptLabel 38 | 32 rockVector # added in IN 39 | 33 rockMode # added in IN 40 | 34 spriteC # added in IN 41 | 42 | # STD in these games don't actually have a designated nop instruction. 43 | # However, it still treats all unrecognized opcodes as nops, so we can cheat. 44 | 9000 nop 45 | -------------------------------------------------------------------------------- /map/th095.stdm: -------------------------------------------------------------------------------- 1 | !stdmap 2 | 3 | # STD - TH095 to TH13 4 | 5 | !ins_names 6 | 0 stop 7 | 1 jmp 8 | 2 pos 9 | 3 posTime 10 | 4 facing 11 | 5 facingTime 12 | 6 up 13 | 7 fov 14 | 8 fog 15 | 9 fogTime 16 | 10 posBezier 17 | 11 facingBezier 18 | 12 rockingMode 19 | 13 bgColor 20 | 14 sprite 21 | # 15 might be a nop 22 | 16 interruptLabel 23 | 17 distortion # distorts bottom of screen 24 | 18 upTime 25 | -------------------------------------------------------------------------------- /map/th10.msgm: -------------------------------------------------------------------------------- 1 | !msgmap 2 | !ins_names 3 | 4 | # These names are solely guesses based on reversing without much testing. 5 | # (e.g. this vm depends on the stage, so it must be the enemy, etc.) 6 | # Notes here: https://gist.github.com/ExpHP/6742c797523800075e911f659c000ca2 7 | 8 | 0 end 9 | 1 playerShow 10 | 2 bossShow 11 | 3 textboxShow 12 | 4 playerHide 13 | 5 bossHide 14 | 6 textboxHide 15 | 7 speakerPlayer 16 | 8 speakerBoss 17 | 9 skippable 18 | 10 textPause 19 | 11 eclResume 20 | 12 playerFace 21 | 13 bossFace 22 | 14 textLine1 # never used 23 | 15 textLine2 # never used 24 | 16 textAdd 25 | 17 textClear 26 | 18 musicBoss 27 | 19 intro 28 | 20 stageEnd 29 | 21 musicEnd 30 | 22 playerShake 31 | 23 bossShake # like nitori 32 | -------------------------------------------------------------------------------- /map/th11-scene.msgm: -------------------------------------------------------------------------------- 1 | !msgmap 2 | !ins_names 3 | 4 | 0 end 5 | 1 playerShow 6 | 2 bossShow 7 | 3 textboxShow # nop in TH128+ 8 | 4 playerHide 9 | 5 bossHide 10 | 6 textboxHide 11 | 7 speakerPlayer 12 | 8 speakerBoss 13 | 9 speakerNone # Inserted in TH09, shifting IDs of remaining instrs 14 | 10 skippable 15 | 11 textPause 16 | 12 eclResume 17 | 13 playerFace 18 | 14 bossFace 19 | 15 textLine1 # never used 20 | 16 textLine2 # never used 21 | 17 textAdd 22 | 18 textClear 23 | 19 musicBoss 24 | 20 intro 25 | 21 stageEnd 26 | 22 musicEnd 27 | 23 playerShake 28 | 24 bossShake 29 | 25 textOffsetY # only used in TH11 30 | # 25 (S) sets y offset (pos2) of 4c,50,54,58. No longer used after TH12 31 | # 26 () enables flag 2 32 | 27 musicFade 33 | 28 bubblePos 34 | 29 bubbleType 35 | 30 routeSelect # GFW only 36 | # 31: (S) TH13 37 | # 32: (S) TH14 38 | 33 tutorial # DIFFERENT IN TH16!!! 39 | -------------------------------------------------------------------------------- /map/th11.msgm: -------------------------------------------------------------------------------- 1 | !msgmap 2 | !ins_names 3 | 4 | 0 end 5 | 1 playerShow 6 | 2 bossShow 7 | 3 textboxShow # nop in TH128+ 8 | 4 playerHide 9 | 5 bossHide 10 | 6 textboxHide 11 | 7 speakerPlayer 12 | 8 speakerBoss 13 | 9 speakerNone # Inserted in TH09, shifting IDs of remaining instrs 14 | 10 skippable 15 | 11 textPause 16 | 12 eclResume 17 | 13 playerFace 18 | 14 bossFace 19 | 15 textLine1 # never used 20 | 16 textLine2 # never used 21 | 17 textAdd 22 | 18 textClear 23 | 19 musicBoss 24 | 20 intro 25 | 21 stageEnd 26 | 22 musicEnd 27 | 23 playerShake 28 | 24 bossShake 29 | 25 textOffsetY # only used in TH11 30 | # 25 (S) sets y offset (pos2) of 4c,50,54,58. No longer used after TH12 31 | # 26 () enables flag 2 32 | 27 musicFade 33 | 28 bubblePos 34 | 29 bubbleType 35 | 30 routeSelect # GFW only 36 | # 31: (S) TH13 37 | # 32: (S) TH14 38 | 33 portraitDarken # DIFFERENT IN TH143 AND TH165!!! 39 | 34 portraitHighlight 40 | 35 lightsOut 41 | 36 store # TH18 only 42 | -------------------------------------------------------------------------------- /map/th14.stdm: -------------------------------------------------------------------------------- 1 | !stdmap 2 | 3 | # STD - TH14 to TH17 4 | 5 | !ins_names 6 | 0 stop 7 | 1 jmp 8 | 2 pos 9 | 3 posTime 10 | 4 facing 11 | 5 facingTime 12 | 6 up 13 | 7 fov 14 | 8 fog 15 | 9 fogTime 16 | 10 posBezier 17 | 11 facingBezier 18 | 12 rockingMode 19 | 13 bgColor 20 | 14 sprite 21 | # 15 might be a nop 22 | 16 interruptLabel 23 | 17 distortion # distorts bottom of screen 24 | 18 upTime 25 | 21 fovTime 26 | -------------------------------------------------------------------------------- /map/v0.anmm: -------------------------------------------------------------------------------- 1 | !anmmap 2 | 3 | # v0.anmm - for EoSD only 4 | # created with help from https://pytouhou.linkmauve.fr/doc/06/anm.xml 5 | 6 | !ins_names 7 | 0 delete 8 | 1 sprite 9 | 2 scale 10 | 3 alpha 11 | 4 color 12 | 5 jmp 13 | 6 nop 14 | 7 flipX 15 | 8 flipY 16 | 9 rotate 17 | 10 angleVel 18 | 11 scaleGrowth 19 | 12 alphaTimeLinear 20 | 13 blendAdditive 21 | 14 blendDefault 22 | 15 static 23 | 16 spriteRand 24 | 17 pos 25 | 18 posTimeLinear 26 | 19 posTimeDecel # quadratic 27 | 20 posTimeDecel2 # quartic. pytouhou called this "posTimeAccel"?! 28 | 21 stop 29 | 22 interruptLabel 30 | 23 anchorTopLeft 31 | 24 stopHide 32 | 25 posMode 33 | # 26 - sets word-sized field. Supposedly this is rotateAuto? Why a whole word? 34 | 27 scrollNowX 35 | 28 scrollNowY 36 | 29 visible 37 | 30 scaleTimeLinear 38 | 31 zWriteDisable 39 | 40 | !gvar_names 41 | # EoSD has no vars 42 | -------------------------------------------------------------------------------- /map/v2.anmm: -------------------------------------------------------------------------------- 1 | !anmmap 2 | 3 | # v2.anmm - for version 2: PCB 4 | # and version 3: IN, PoFV (but not StB) 5 | 6 | !ins_names 7 | 0 nop 8 | 1 delete 9 | 2 static 10 | 3 sprite 11 | 4 jmp 12 | 5 jmpDec 13 | 14 | 6 pos 15 | 7 scale 16 | 8 alpha 17 | 9 color 18 | 10 flipX 19 | 11 flipY 20 | 12 rotate 21 | 13 angleVel 22 | 14 scaleGrowth 23 | 15 alphaTimeLinear 24 | 16 blendAdditiveSet 25 | 17 posTimeLinear 26 | 18 posTimeDecel # mode 4 - quadratic ease out 27 | 19 posTimeDecel2 # mode 6 - quartic ease out 28 | 20 stop 29 | 21 interruptLabel 30 | 22 anchorTopLeft 31 | 23 stopHide 32 | 24 posMode 33 | # 25 sets a word field. Might be rotateAuto? Why a whole word? 34 | 26 scrollNowX 35 | 27 scrollNowY 36 | 28 visible 37 | 29 scaleTimeLinear 38 | 30 zWriteDisable 39 | # 31 sets state of flag 40 | 32 posTime 41 | 33 colorTime 42 | 34 alphaTime 43 | 35 rotateTime 44 | 36 scaleTime 45 | 46 | 37 iset 47 | 38 fset 48 | 39 iadd 49 | 40 fadd 50 | 41 isub 51 | 42 fsub 52 | 43 imul 53 | 44 fmul 54 | 45 idiv 55 | 46 fdiv 56 | 47 imod 57 | 48 fmod 58 | 49 isetAdd 59 | 50 fsetAdd 60 | 51 isetSub 61 | 52 fsetSub 62 | 53 isetMul 63 | 54 fsetMul 64 | 55 isetDiv 65 | 56 fsetDiv 66 | 57 isetMod 67 | 58 fsetMod 68 | 69 | 59 isetRand 70 | 60 fsetRand 71 | 61 fsin 72 | 62 fcos 73 | 63 ftan 74 | 64 acos 75 | 65 fatan 76 | 66 validRad 77 | 78 | 67 ije 79 | 68 fje 80 | 69 ijne 81 | 70 fjne 82 | 71 ijl 83 | 72 fjl 84 | 73 ijle 85 | 74 fjle 86 | 75 ijg 87 | 76 fjg 88 | 77 ijge 89 | 78 fjge 90 | 91 | 79 wait 92 | 80 scrollX 93 | 81 scrollY 94 | 82 blendMode 95 | # 83 dword field 96 | 84 color2 97 | 85 alpha2 98 | 86 color2Time 99 | 87 alpha2Time 100 | # 88 bitflag but weird 101 | 89 caseReturn 102 | 103 | !gvar_names 104 | 10000 I0 105 | 10001 I1 106 | 10002 I2 107 | 10003 I3 108 | 10004 F0 109 | 10005 F1 110 | 10006 F2 111 | 10007 F3 112 | 10008 I4 113 | 10009 I5 114 | 10010 RANDRAD 115 | 10011 RANDF 116 | 10012 RANDF2 117 | -------------------------------------------------------------------------------- /snapshots/truth__diagnostic__unspanned.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/diagnostic.rs 3 | expression: stderr 4 | --- 5 | warning: a.txt: thing 3: while eating a sub: blah 20 6 | 7 | 8 | -------------------------------------------------------------------------------- /snapshots/truth__fmt__tests__fancy_formatting__after_trigger.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/fmt.rs 3 | expression: "f(15, r#\"{a: [10, 23], b: 30}\"#).trim()\n\nThis should use BLOCK formatting for 'a'" 4 | --- 5 | { 6 | a: [ 7 | 10, 8 | 23, 9 | ], 10 | b: 30, 11 | } 12 | -------------------------------------------------------------------------------- /snapshots/truth__fmt__tests__fancy_formatting__before_trigger.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/fmt.rs 3 | expression: "f(16, r#\"{a: [10, 23], b: 30}\"#).trim()\n\nThis should use INLINE formatting for 'a'" 4 | --- 5 | { 6 | a: [10, 23], 7 | b: 30, 8 | } 9 | -------------------------------------------------------------------------------- /snapshots/truth__fmt__tests__fancy_formatting__fully_block.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/fmt.rs 3 | expression: "f(3, r#\"{ apple: \"delicious\" ,numbers : [1 ,2]}\"#).trim()\n\nThis should be ENTIRELY BLOCK FORMAT!" 4 | --- 5 | { 6 | apple: "delicious", 7 | numbers: [ 8 | 1, 9 | 2, 10 | ], 11 | } 12 | -------------------------------------------------------------------------------- /snapshots/truth__fmt__tests__fancy_formatting__fully_inline.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/fmt.rs 3 | expression: "f(100, r#\"{ apple: \"delicious\" ,numbers : [1 ,2, 3]}\"#).trim()\n\nThis should be all on ONE LINE!" 4 | --- 5 | {apple: "delicious", numbers: [1, 2, 3]} 6 | -------------------------------------------------------------------------------- /snapshots/truth__fmt__tests__fancy_formatting__mixed_style.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/fmt.rs 3 | expression: "f(30, r#\"{a: [10, 23], b: [10000000, 230000000, 4900000]}\"#).trim()\n\n'a' should be inline and 'b' should be block" 4 | --- 5 | { 6 | a: [10, 23], 7 | b: [ 8 | 10000000, 9 | 230000000, 10 | 4900000, 11 | ], 12 | } 13 | -------------------------------------------------------------------------------- /snapshots/truth__fmt__tests__goto__no_time.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/fmt.rs 3 | expression: "f(9999, r#\" goto lol ;\"#).trim()" 4 | --- 5 | goto lol; 6 | -------------------------------------------------------------------------------- /snapshots/truth__fmt__tests__goto__with_time.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/fmt.rs 3 | expression: "f(9999, r#\" goto lol@ 123;\"#).trim()" 4 | --- 5 | goto lol @ 123; 6 | -------------------------------------------------------------------------------- /snapshots/truth__fmt__tests__optional_parens__cond_block.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/fmt.rs 3 | expression: "f(9999, r#\"if (a == 3) { nop(); }\"#).trim()" 4 | --- 5 | if (a == 3) { 6 | nop(); 7 | } 8 | -------------------------------------------------------------------------------- /snapshots/truth__fmt__tests__optional_parens__cond_jump.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/fmt.rs 3 | expression: "f(9999, r#\"if (a == 3) goto end;\"#).trim()" 4 | --- 5 | if (a == 3) goto end; 6 | -------------------------------------------------------------------------------- /snapshots/truth__fmt__tests__optional_parens__while.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/fmt.rs 3 | expression: "f(9999, r#\"while (a == 3) { nop(); }\"#).trim()" 4 | --- 5 | while (a == 3) { 6 | nop(); 7 | } 8 | -------------------------------------------------------------------------------- /snapshots/truth__fmt__tests__optional_parens__with.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/fmt.rs 3 | expression: "f(9999, r#\"x = (a + 3) * 4;\"#).trim()" 4 | --- 5 | x = (a + 3) * 4; 6 | -------------------------------------------------------------------------------- /snapshots/truth__fmt__tests__optional_parens__without.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/fmt.rs 3 | expression: "f(9999, r#\"x = a + 3;\"#).trim()" 4 | --- 5 | x = a + 3; 6 | -------------------------------------------------------------------------------- /snapshots/truth__parse__abi__tests__attr_only_comma.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/parse/abi.rs 3 | expression: "expect_parse_error(\"unexpected\", r##\"a(bs=,)\"##).trim()" 4 | --- 5 | error: unexpected token `,` 6 | ┌─ :1:6 7 | │ 8 | 1 │ a(bs=,) 9 | │ ^ unexpected token 10 | │ 11 | = 12 | Expected one of "-", INT or STRING 13 | -------------------------------------------------------------------------------- /snapshots/truth__parse__abi__tests__attr_trailing_comma.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/parse/abi.rs 3 | expression: "expect_parse_error(\"unexpected\", r##\"a(bs=3,)\"##).trim()" 4 | --- 5 | error: unexpected token `)` 6 | ┌─ :1:8 7 | │ 8 | 1 │ a(bs=3,) 9 | │ ^ unexpected token 10 | │ 11 | = 12 | Expected one of "-", INT or STRING 13 | -------------------------------------------------------------------------------- /snapshots/truth__parse__abi__tests__bad_token.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/parse/abi.rs 3 | expression: "expect_parse_error(\"invalid token\", r##\"a(&)\"##).trim()" 4 | --- 5 | error: invalid token 6 | ┌─ :1:3 7 | │ 8 | 1 │ a(&) 9 | │ ^ invalid token 10 | -------------------------------------------------------------------------------- /snapshots/truth__parse__abi__tests__double_attr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/parse/abi.rs 3 | expression: "expect_parse_error(\"unexpected\", r##\"a()()\"##).trim()" 4 | --- 5 | error: unexpected '(' 6 | ┌─ :1:4 7 | │ 8 | 1 │ a()() 9 | │ ^ 10 | -------------------------------------------------------------------------------- /snapshots/truth__parse__abi__tests__duplicate_attr.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/parse/abi.rs 3 | expression: "expect_parse_error(\"duplicate\", r##\"a(bs=4; x=3; bs=2)\"##).trim()" 4 | --- 5 | error: duplicate attribute bs 6 | ┌─ :1:14 7 | │ 8 | 1 │ a(bs=4; x=3; bs=2) 9 | │ -- ^^ 10 | -------------------------------------------------------------------------------- /snapshots/truth__parse__abi__tests__errant_close_paren.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/parse/abi.rs 3 | expression: "expect_parse_error(\"unexpected\", r##\")\"##).trim()" 4 | --- 5 | error: unexpected ')' 6 | ┌─ :1:1 7 | │ 8 | 1 │ ) 9 | │ ^ 10 | -------------------------------------------------------------------------------- /snapshots/truth__parse__abi__tests__errant_eq.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/parse/abi.rs 3 | expression: "expect_parse_error(\"unexpected\", r##\"=\"##).trim()" 4 | --- 5 | error: unexpected '=' 6 | ┌─ :1:1 7 | │ 8 | 1 │ = 9 | │ ^ 10 | -------------------------------------------------------------------------------- /snapshots/truth__parse__abi__tests__errant_quote.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/parse/abi.rs 3 | expression: "expect_parse_error(\"unexpected\", r##\"\"\"\"##).trim()" 4 | --- 5 | error: unexpected '\"' 6 | ┌─ :1:1 7 | │ 8 | 1 │ "" 9 | │ ^ 10 | -------------------------------------------------------------------------------- /snapshots/truth__parse__abi__tests__initial_paren.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/parse/abi.rs 3 | expression: "expect_parse_error(\"unexpected\", r##\"()\"##).trim()" 4 | --- 5 | error: unexpected '(' 6 | ┌─ :1:1 7 | │ 8 | 1 │ () 9 | │ ^ 10 | -------------------------------------------------------------------------------- /snapshots/truth__parse__abi__tests__trick_close_paren_in_string.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/parse/abi.rs 3 | expression: "expect_parse_error(\"unclosed\", r##\"S(enum=\")\"\"##).trim()" 4 | --- 5 | error: missing closing parenthesis for attribute list 6 | ┌─ :1:2 7 | │ 8 | 1 │ S(enum=")" 9 | │ ^ unclosed parenthesis 10 | -------------------------------------------------------------------------------- /snapshots/truth__parse__abi__tests__trick_escaped_quote_in_string.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/parse/abi.rs 3 | expression: "expect_parse_error(\"unclosed\", r##\"S(enum=\"\\\")\"\"##).trim()" 4 | --- 5 | error: missing closing parenthesis for attribute list 6 | ┌─ :1:2 7 | │ 8 | 1 │ S(enum="\")" 9 | │ ^ unclosed parenthesis 10 | -------------------------------------------------------------------------------- /snapshots/truth__parse__abi__tests__unclosed_paren.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/parse/abi.rs 3 | expression: "expect_parse_error(\"unclosed\", r##\"a(bs=2\"##).trim()" 4 | --- 5 | error: missing closing parenthesis for attribute list 6 | ┌─ :1:2 7 | │ 8 | 1 │ a(bs=2 9 | │ ^ unclosed parenthesis 10 | -------------------------------------------------------------------------------- /snapshots/truth__parse__tests__bad_escape.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/parse/tests.rs 3 | expression: "expect_parse_error::(\"escape\", r#\" \"abc\\jefg\" \"#).trim()" 4 | --- 5 | error: invalid escape character 'j' 6 | ┌─ :1:2 7 | │ 8 | 1 │ "abc\jefg" 9 | │ ^^^^^^^^^^ contains invalid escape 10 | -------------------------------------------------------------------------------- /snapshots/truth__parse__tests__bad_escape_end.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/parse/tests.rs 3 | expression: "expect_parse_error::(\"token\", r#\" \"abcefg\\\"#).trim()" 4 | --- 5 | error: invalid token 6 | ┌─ :1:2 7 | │ 8 | 1 │ "abcefg\ 9 | │ ^^^^^^^ invalid token 10 | -------------------------------------------------------------------------------- /snapshots/truth__parse__tests__bad_ins_empty.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/parse/tests.rs 3 | expression: "expect_parse_error::(\"instruction\", r#\" ins_() \"#).trim()" 4 | --- 5 | error: invalid instruction identifier 6 | ┌─ :1:2 7 | │ 8 | 1 │ ins_() 9 | │ ^^^^ invalid instruction identifier 10 | │ 11 | = identifiers beginning with 'ins_' must end in a canonically-formatted integer, e.g. 'ins_42'. 12 | -------------------------------------------------------------------------------- /snapshots/truth__parse__tests__bad_ins_identifier.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/parse/tests.rs 3 | expression: "expect_parse_error::(\"instruction\", r#\" ins_04() \"#).trim()" 4 | --- 5 | error: invalid instruction identifier 6 | ┌─ :1:2 7 | │ 8 | 1 │ ins_04() 9 | │ ^^^^^^ invalid instruction identifier 10 | │ 11 | = identifiers beginning with 'ins_' must end in a canonically-formatted integer, e.g. 'ins_42'. 12 | -------------------------------------------------------------------------------- /snapshots/truth__parse__tests__bad_ins_identifier_2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/parse/tests.rs 3 | expression: "expect_parse_error::(\"instruction\", r#\" ins_a() \"#).trim()" 4 | --- 5 | error: invalid instruction identifier 6 | ┌─ :1:2 7 | │ 8 | 1 │ ins_a() 9 | │ ^^^^^ invalid instruction identifier 10 | │ 11 | = identifiers beginning with 'ins_' must end in a canonically-formatted integer, e.g. 'ins_42'. 12 | -------------------------------------------------------------------------------- /snapshots/truth__parse__tests__bad_ins_overflow.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/parse/tests.rs 3 | expression: "expect_parse_error::(\"instruction\",\n r#\" ins_99999999999999() \"#).trim()" 4 | --- 5 | error: invalid instruction identifier 6 | ┌─ :1:2 7 | │ 8 | 1 │ ins_99999999999999() 9 | │ ^^^^^^^^^^^^^^^^^^ number too large to fit in target type 10 | -------------------------------------------------------------------------------- /snapshots/truth__parse__tests__big_reg.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/parse/tests.rs 3 | expression: "expect_parse_error::(\"too large\",\n \"float x = %REG[1234258905623];\").trim()" 4 | --- 5 | error: bad integer literal 6 | ┌─ :1:16 7 | │ 8 | 1 │ float x = %REG[1234258905623]; 9 | │ ^^^^^^^^^^^^^ number too large to fit in target type 10 | -------------------------------------------------------------------------------- /snapshots/truth__parse__tests__duplicate_meta_key.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/parse/tests.rs 3 | expression: "expect_parse_error::(\"duplicate\",\n r#\"{\n a: {\n thing: 100,\n another: 101,\n yet_another: 102,\n thing: 103,\n },\n}\"#).trim()" 4 | --- 5 | error: duplicate metadata field 'thing' 6 | ┌─ :6:5 7 | │ 8 | 3 │ thing: 100, 9 | │ ----- previously supplied here 10 | · 11 | 6 │ thing: 103, 12 | │ ^^^^^ duplicate key 13 | -------------------------------------------------------------------------------- /snapshots/truth__parse__tests__integer_overflow.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/parse/tests.rs 3 | expression: "expect_parse_error::(\"too large\", \"124712894724479\").trim()" 4 | --- 5 | error: bad integer literal 6 | ┌─ :1:1 7 | │ 8 | 1 │ 124712894724479 9 | │ ^^^^^^^^^^^^^^^ number too large to fit in target type 10 | -------------------------------------------------------------------------------- /snapshots/truth__parse__tests__invalid_token.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/parse/tests.rs 3 | expression: "expect_parse_error::(\"token\", \"(32 + \\u{306F})\").trim()" 4 | --- 5 | error: invalid token 6 | ┌─ :1:7 7 | │ 8 | 1 │ (32 + は) 9 | │ ^^ invalid token 10 | -------------------------------------------------------------------------------- /snapshots/truth__parse__tests__unclosed_comment.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/parse/tests.rs 3 | expression: "expect_parse_error::(\"token\", r#\" /* comment \"#).trim()" 4 | --- 5 | error: invalid token 6 | ┌─ :1:2 7 | │ 8 | 1 │ /* comment 9 | │ ^^^^^^^^^^^ invalid token 10 | -------------------------------------------------------------------------------- /snapshots/truth__parse__tests__unexpected_eof.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/parse/tests.rs 3 | expression: "expect_parse_error::(\"EOF\", \"int x = 3\").trim()" 4 | --- 5 | error: unexpected EOF 6 | ┌─ :1:10 7 | │ 8 | 1 │ int x = 3 9 | │ ^ unexpected EOF 10 | │ 11 | = 12 | Expected one of "," or ";" 13 | -------------------------------------------------------------------------------- /snapshots/truth__parse__tests__unexpected_token.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/parse/tests.rs 3 | expression: "expect_parse_error::(\"unexpected\", \"int x = int;\").trim()" 4 | --- 5 | error: unexpected token `;` 6 | ┌─ :1:12 7 | │ 8 | 1 │ int x = int; 9 | │ ^ unexpected token 10 | │ 11 | = 12 | Expected one of "(" 13 | -------------------------------------------------------------------------------- /snapshots/truth__resolve__tests__call_of_undefined_func.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/resolve/tests.rs 3 | expression: "resolve_expect_err::(r#\"{\n missingFunc(missingVar);\n}\"#,\n \"unknown\").trim()" 4 | --- 5 | error: unknown ECL instruction or function 'missingFunc' 6 | ┌─ :2:5 7 | │ 8 | 2 │ missingFunc(missingVar); 9 | │ ^^^^^^^^^^^ not found in this scope 10 | 11 | error: unknown ECL register or variable 'missingVar' 12 | ┌─ :2:17 13 | │ 14 | 2 │ missingFunc(missingVar); 15 | │ ^^^^^^^^^^ not found in this scope 16 | -------------------------------------------------------------------------------- /snapshots/truth__resolve__tests__const_after_scope_end.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/resolve/tests.rs 3 | expression: "resolve_expect_err::(r#\"{\n if (true) {\n const int a = 4;\n int b = a; // should be OK\n }\n int c = a; // should fail at `a`\n}\"#,\n \"in this scope\").trim()" 4 | --- 5 | error: unknown ECL register or variable 'a' 6 | ┌─ :6:13 7 | │ 8 | 6 │ int c = a; // should fail at `a` 9 | │ ^ not found in this scope 10 | -------------------------------------------------------------------------------- /snapshots/truth__resolve__tests__const_redefinition.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/resolve/tests.rs 3 | expression: "resolve_expect_err::(r#\"\nconst int BLUE = 1;\nconst int RED = 3;\nconst int BLUE = RED;\n\"#,\n \"redefinition\").trim()" 4 | --- 5 | error: redefinition of const 'BLUE' 6 | ┌─ :4:11 7 | │ 8 | 2 │ const int BLUE = 1; 9 | │ ---- originally defined here 10 | 3 │ const int RED = 3; 11 | 4 │ const int BLUE = RED; 12 | │ ^^^^ redefinition of const 13 | -------------------------------------------------------------------------------- /snapshots/truth__resolve__tests__const_scoped_redefinition.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/resolve/tests.rs 3 | expression: "resolve_expect_err::(r#\"{\n if (true) {\n const int BLUE = 1;\n const int RED = 3;\n const int BLUE = RED;\n }\n}\"#,\n \"redefinition\").trim()" 4 | --- 5 | error: redefinition of const 'BLUE' 6 | ┌─ :5:19 7 | │ 8 | 3 │ const int BLUE = 1; 9 | │ ---- originally defined here 10 | 4 │ const int RED = 3; 11 | 5 │ const int BLUE = RED; 12 | │ ^^^^ redefinition of const 13 | -------------------------------------------------------------------------------- /snapshots/truth__resolve__tests__const_scoped_using_local.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/resolve/tests.rs 3 | expression: "resolve_expect_err::(r#\"{\n int x = 2;\n const int foo = x; // should fail at `x`\n}\"#,\n \"nested const\").trim()" 4 | --- 5 | error: cannot use local from outside const 6 | ┌─ :3:21 7 | │ 8 | 2 │ int x = 2; 9 | │ - defined here 10 | 3 │ const int foo = x; // should fail at `x` 11 | │ ^ used in a nested const 12 | -------------------------------------------------------------------------------- /snapshots/truth__resolve__tests__const_scoped_using_outer_local.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/resolve/tests.rs 3 | expression: "resolve_expect_err::(r#\"{\n int x = 2;\n if (true) {\n const int foo = x; // should fail at `x`\n }\n}\"#,\n \"nested const\").trim()" 4 | --- 5 | error: cannot use local from outside const 6 | ┌─ :4:25 7 | │ 8 | 2 │ int x = 2; 9 | │ - defined here 10 | 3 │ if (true) { 11 | 4 │ const int foo = x; // should fail at `x` 12 | │ ^ used in a nested const 13 | -------------------------------------------------------------------------------- /snapshots/truth__resolve__tests__const_shadow.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/resolve/tests.rs 3 | expression: "resolve_reformat::(r#\"{\n const int a = 3;\n {\n const int a = 4; // should be different from outer `a`\n int b = a * a; // should use inner `a`\n }\n int c = a * a; // should use outer `a`\n}\"#).trim()" 4 | --- 5 | { 6 | const int a_0 = 3; 7 | { 8 | const int a_1 = 4; 9 | int b_0 = (a_1 * a_1); 10 | } 11 | int c_0 = (a_0 * a_0); 12 | } 13 | -------------------------------------------------------------------------------- /snapshots/truth__resolve__tests__const_shadows_outer_local.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/resolve/tests.rs 3 | expression: "resolve_reformat::(r#\"{\n int a = 3;\n {\n int b = a * a; // should use inner `a`\n const int a = 4;\n }\n}\"#).trim()" 4 | --- 5 | { 6 | int a_0 = 3; 7 | { 8 | int b_0 = (a_1 * a_1); 9 | const int a_1 = 4; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /snapshots/truth__resolve__tests__func_after_scope_end.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/resolve/tests.rs 3 | expression: "resolve_expect_err::(r#\"{\n if (true) {\n int foo() { return 4; }\n int b = foo(); // should be OK\n }\n int c = foo(); // should fail at `foo`\n}\"#,\n \"in this scope\").trim()" 4 | --- 5 | error: unknown ECL instruction or function 'foo' 6 | ┌─ :6:13 7 | │ 8 | 6 │ int c = foo(); // should fail at `foo` 9 | │ ^^^ not found in this scope 10 | -------------------------------------------------------------------------------- /snapshots/truth__resolve__tests__func_redefinition.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/resolve/tests.rs 3 | expression: "resolve_expect_err::(r#\"\nint foo(int x) {\n return x;\n}\n\nint foo(float y) {\n return y;\n}\n\"#,\n \"redefinition\").trim()" 4 | --- 5 | error: redefinition of function 'foo' 6 | ┌─ :6:5 7 | │ 8 | 2 │ int foo(int x) { 9 | │ --- originally defined here 10 | · 11 | 6 │ int foo(float y) { 12 | │ ^^^ redefinition of function 13 | -------------------------------------------------------------------------------- /snapshots/truth__resolve__tests__func_scoped_redefinition.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/resolve/tests.rs 3 | expression: "resolve_expect_err::(r#\"{\n if (true) {\n int foo(int x) {\n return x;\n }\n\n int foo(float y) {\n return y;\n }\n }\n}\"#,\n \"redefinition\").trim()" 4 | --- 5 | error: redefinition of function 'foo' 6 | ┌─ :7:13 7 | │ 8 | 3 │ int foo(int x) { 9 | │ --- originally defined here 10 | · 11 | 7 │ int foo(float y) { 12 | │ ^^^ redefinition of function 13 | -------------------------------------------------------------------------------- /snapshots/truth__resolve__tests__func_scoped_shadows_ins_alias.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/resolve/tests.rs 3 | expression: "resolve_reformat::(r#\"{\n alias(4, 3.0);\n if (true) {\n void alias() {} // should be different `alias`\n alias();\n }\n alias(4, 3.0); // should be original `alias`\n}\"#).trim()" 4 | --- 5 | { 6 | alias_0(4, 3.0); 7 | if (true_0) { 8 | void alias_1() { 9 | } 10 | 11 | alias_1(); 12 | } 13 | alias_0(4, 3.0); 14 | } 15 | -------------------------------------------------------------------------------- /snapshots/truth__resolve__tests__func_scoped_using_local.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/resolve/tests.rs 3 | expression: "resolve_expect_err::(r#\"{\n int x = 2;\n int foo() {\n return x; // should fail at `x`\n }\n}\"#,\n \"nested function\").trim()" 4 | --- 5 | error: cannot use local from outside function 6 | ┌─ :4:16 7 | │ 8 | 2 │ int x = 2; 9 | │ - defined here 10 | 3 │ int foo() { 11 | 4 │ return x; // should fail at `x` 12 | │ ^ used in a nested function 13 | -------------------------------------------------------------------------------- /snapshots/truth__resolve__tests__func_scoped_using_outer_param.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/resolve/tests.rs 3 | expression: "resolve_expect_err::(r#\"{\n void foo(int a) {\n int bar() {\n return a; // should fail at `a`\n }\n }\n}\"#,\n \"nested function\").trim()" 4 | --- 5 | error: cannot use parameter from outside function 6 | ┌─ :4:20 7 | │ 8 | 2 │ void foo(int a) { 9 | │ - defined here 10 | 3 │ int bar() { 11 | 4 │ return a; // should fail at `a` 12 | │ ^ used in a nested function 13 | -------------------------------------------------------------------------------- /snapshots/truth__resolve__tests__func_scoped_using_outer_shadowed_const.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/resolve/tests.rs 3 | expression: "resolve_expect_err::(r#\"{\n const int x = 2;\n if (true) {\n int x = 2;\n int foo() {\n return x; // should fail at 'x'\n }\n }\n}\"#,\n \"nested function\").trim()" 4 | --- 5 | error: cannot use local from outside function 6 | ┌─ :6:20 7 | │ 8 | 4 │ int x = 2; 9 | │ - defined here 10 | 5 │ int foo() { 11 | 6 │ return x; // should fail at 'x' 12 | │ ^ used in a nested function 13 | -------------------------------------------------------------------------------- /snapshots/truth__resolve__tests__local_after_scope_end.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/resolve/tests.rs 3 | expression: "resolve_expect_err::(r#\"{\n if (true) {\n int a = 4;\n int b = a; // should be OK\n }\n int c = a; // should fail at `a`\n}\"#,\n \"in this scope\").trim()" 4 | --- 5 | error: unknown ECL register or variable 'a' 6 | ┌─ :6:13 7 | │ 8 | 6 │ int c = a; // should fail at `a` 9 | │ ^ not found in this scope 10 | -------------------------------------------------------------------------------- /snapshots/truth__resolve__tests__local_disjoint.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/resolve/tests.rs 3 | expression: "resolve_reformat::(r#\"{\n {\n int a = 4;\n int b = a * a; // should use inner `a`\n }\n {\n int a = 4; // should be different from other inner `a`\n int b = a * a; // should use new inner `a`\n }\n}\"#).trim()" 4 | --- 5 | { 6 | { 7 | int a_0 = 4; 8 | int b_0 = (a_0 * a_0); 9 | } 10 | { 11 | int a_1 = 4; 12 | int b_1 = (a_1 * a_1); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /snapshots/truth__resolve__tests__local_redefinition.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/resolve/tests.rs 3 | expression: "resolve_expect_err::(r#\"{\n if (true) {\n int a = 4;\n int b = 3, a = 5; // should fail on `a`\n }\n}\"#,\n \"redefinition\").trim()" 4 | --- 5 | error: redefinition of local 'a' 6 | ┌─ :4:20 7 | │ 8 | 3 │ int a = 4; 9 | │ - originally defined here 10 | 4 │ int b = 3, a = 5; // should fail on `a` 11 | │ ^ redefinition of local 12 | -------------------------------------------------------------------------------- /snapshots/truth__resolve__tests__local_shadow.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/resolve/tests.rs 3 | expression: "resolve_reformat::(r#\"{\n int a = 3;\n {\n int a = 4;\n int b = a * a; // should use inner `a`\n }\n int c = a * a; // should use outer `a`\n}\"#).trim()" 4 | --- 5 | { 6 | int a_0 = 3; 7 | { 8 | int a_1 = 4; 9 | int b_0 = (a_1 * a_1); 10 | } 11 | int c_0 = (a_0 * a_0); 12 | } 13 | -------------------------------------------------------------------------------- /snapshots/truth__resolve__tests__local_shadows_outer_const.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/resolve/tests.rs 3 | expression: "resolve_reformat::(r#\"{\n const int a = 3; // should be a_0\n {\n int b = a * a; // should be a_0 * a_0\n int a = 4; // should be a_1\n int c = a * a; // should be a_1 * a_1\n }\n}\"#).trim()" 4 | --- 5 | { 6 | const int a_0 = 3; 7 | { 8 | int b_0 = (a_0 * a_0); 9 | int a_1 = 4; 10 | int c_0 = (a_1 * a_1); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /snapshots/truth__resolve__tests__local_shadows_reg_alias.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/resolve/tests.rs 3 | expression: "resolve_reformat::(r#\"{\n ins_21(ALIAS, 3.0);\n if (true) {\n float ALIAS = 4.0; // should be different `ALIAS`\n float b = ALIAS;\n }\n ins_21(ALIAS, 3.0); // should be original `ALIAS`\n}\"#).trim()" 4 | --- 5 | { 6 | ins_21(ALIAS_0, 3.0); 7 | if (true_0) { 8 | float ALIAS_1 = 4.0; 9 | float b_0 = ALIAS_1; 10 | } 11 | ins_21(ALIAS_0, 3.0); 12 | } 13 | -------------------------------------------------------------------------------- /snapshots/truth__resolve__tests__local_using_itself.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/resolve/tests.rs 3 | expression: "resolve_expect_err::(r#\"{\n int a = a; // should fail at second `a`\n}\"#,\n \"in this scope\").trim()" 4 | --- 5 | error: unknown ECL register or variable 'a' 6 | ┌─ :2:13 7 | │ 8 | 2 │ int a = a; // should fail at second `a` 9 | │ ^ not found in this scope 10 | -------------------------------------------------------------------------------- /snapshots/truth__resolve__tests__param_redefinition.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/resolve/tests.rs 3 | expression: "resolve_expect_err::(r#\"{\n void foo(int a, int b, float a) { // should fail at second `a`\n }\n}\"#,\n \"redefinition\").trim()" 4 | --- 5 | error: redefinition of parameter 'a' 6 | ┌─ :2:34 7 | │ 8 | 2 │ void foo(int a, int b, float a) { // should fail at second `a` 9 | │ - ^ redefinition of parameter 10 | │ │ 11 | │ originally defined here 12 | -------------------------------------------------------------------------------- /snapshots/truth__resolve__tests__separate_namespaces.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: src/resolve/tests.rs 3 | expression: "resolve_reformat::(r#\"\n const int a = a(); // should be a_0 then a_1\n const int a() { return a; } // should be a_1 then a_0\n\"#).trim()" 4 | --- 5 | const int a_0 = a_1(); 6 | 7 | const int a_1() { 8 | return a_0; 9 | } 10 | -------------------------------------------------------------------------------- /src/bin/common/mod.rs: -------------------------------------------------------------------------------- 1 | // IMPORTANT: DO NOT USE ANYTHING FROM THE LIB CRATE HERE! 2 | // 3 | // If you do, you'll cause linking to occur and full package builds using --all-targets 4 | // or --tests will take quite measurably longer! 5 | 6 | pub fn run_truth_subcommand(subcommand: &str) { 7 | let exe_path = std::env::current_exe().unwrap_or_else(|e| { 8 | eprintln!("ERROR: could not get current exe path: {}", e); 9 | std::process::exit(1); 10 | }); 11 | 12 | let exe_dir = exe_path.parent().unwrap_or_else(|| { 13 | eprintln!("ERROR: exe path has no parent?! What sorcery is this?!"); 14 | std::process::exit(1); 15 | }); 16 | 17 | // find a binary named 'truth' in the same dir with the same extension as us 18 | let mut truth_path = exe_dir.join("truth-core"); 19 | if let Some(ext) = exe_path.extension() { 20 | truth_path = truth_path.with_extension(ext); 21 | } 22 | if !truth_path.exists() { 23 | eprintln!("ERROR: cannot find 'truth-core' in '{}'. Exiting.", exe_dir.display()); 24 | std::process::exit(1); 25 | } 26 | 27 | let status = { 28 | std::process::Command::new(truth_path) 29 | .arg(subcommand) 30 | .args(std::env::args_os().skip(1)) 31 | .status() 32 | .unwrap_or_else(|e| { 33 | eprintln!("ERROR: unable to start 'truth-core': {}", e); 34 | std::process::exit(1); 35 | }) 36 | }; 37 | 38 | if !status.success() { 39 | std::process::exit(1); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/bin/truanm.rs: -------------------------------------------------------------------------------- 1 | // This binary is just a shim that calls 'truth-core' with the first argument set. 2 | // 3 | // IMPORTANT: DO NOT USE ANYTHING FROM THE LIB CRATE HERE! 4 | // 5 | // If you do, you'll cause linking to occur and full package builds using --all-targets 6 | // or --tests will take quite measurably longer! 7 | 8 | mod common; 9 | 10 | fn main() { 11 | common::run_truth_subcommand("truanm"); 12 | } 13 | -------------------------------------------------------------------------------- /src/bin/truecl.rs: -------------------------------------------------------------------------------- 1 | // This binary is just a shim that calls 'truth-core' with the first argument set. 2 | // 3 | // IMPORTANT: DO NOT USE ANYTHING FROM THE LIB CRATE HERE! 4 | // 5 | // If you do, you'll cause linking to occur and full package builds using --all-targets 6 | // or --tests will take quite measurably longer! 7 | 8 | mod common; 9 | 10 | fn main() { 11 | common::run_truth_subcommand("truecl"); 12 | } 13 | -------------------------------------------------------------------------------- /src/bin/trumsg.rs: -------------------------------------------------------------------------------- 1 | // This binary is just a shim that calls 'truth-core' with the first argument set. 2 | // 3 | // IMPORTANT: DO NOT USE ANYTHING FROM THE LIB CRATE HERE! 4 | // 5 | // If you do, you'll cause linking to occur and full package builds using --all-targets 6 | // or --tests will take quite measurably longer! 7 | 8 | mod common; 9 | 10 | fn main() { 11 | common::run_truth_subcommand("trumsg"); 12 | } 13 | -------------------------------------------------------------------------------- /src/bin/trustd.rs: -------------------------------------------------------------------------------- 1 | // This binary is just a shim that calls 'truth-core' with the first argument set. 2 | // 3 | // IMPORTANT: DO NOT USE ANYTHING FROM THE LIB CRATE HERE! 4 | // 5 | // If you do, you'll cause linking to occur and full package builds using --all-targets 6 | // or --tests will take quite measurably longer! 7 | 8 | mod common; 9 | 10 | fn main() { 11 | common::run_truth_subcommand("trustd"); 12 | } 13 | -------------------------------------------------------------------------------- /src/bin/truth-core.rs: -------------------------------------------------------------------------------- 1 | fn main() -> ! { 2 | // note: this call to git_version!() is placed as high up the dependency tree as we possibly 3 | // can, because it triggers rebuilds on pretty much anything you touch. (even files 4 | // outside of `src/`...) 5 | let version = git_version::git_version!(); 6 | 7 | truth::cli_def::main(version); 8 | } 9 | -------------------------------------------------------------------------------- /src/formats/anm/soft_option.rs: -------------------------------------------------------------------------------- 1 | use crate::pos::Sp; 2 | 3 | #[derive(Debug, Copy, Clone, PartialEq, Eq)] 4 | pub(in crate::formats::anm) enum SoftOption { 5 | Missing, 6 | /// A value obtained from an image source. Soft values can still be replaced by newer values. 7 | Soft(T), 8 | /// A value explicitly provided by the user. These do NOT get replaced by newer values. 9 | Explicit(Sp), 10 | } 11 | 12 | impl Default for SoftOption { 13 | fn default() -> Self { SoftOption::Missing } 14 | } 15 | 16 | #[allow(unused)] 17 | impl SoftOption { 18 | pub fn is_missing(&self) -> bool { matches!(self, SoftOption::Missing) } 19 | 20 | /// Set `self` "explicitly" (preventing future modification). 21 | pub fn set_explicit(&mut self, value: Sp) { 22 | if matches!(self, SoftOption::Missing | SoftOption::Soft(_)) { 23 | *self = SoftOption::Explicit(value); 24 | } 25 | } 26 | /// Set `self` "softly" (allowing future calls to overwrite it again). 27 | pub fn set_soft(&mut self, value: T) { 28 | if matches!(self, SoftOption::Missing | SoftOption::Soft(_)) { 29 | *self = SoftOption::Soft(value); 30 | } 31 | } 32 | /// Set `self` "softly", only if the value is missing. (use to supply a default value) 33 | pub fn set_soft_if_missing(&mut self, value: T) { 34 | if matches!(self, SoftOption::Missing) { 35 | *self = SoftOption::Soft(value); 36 | } 37 | } 38 | pub fn filter(self, predicate: impl FnOnce(&T) -> bool) -> Self { 39 | if let SoftOption::Soft(x) | SoftOption::Explicit(sp_pat!(x)) = &self { 40 | if predicate(x) { 41 | return SoftOption::Missing; 42 | } 43 | } 44 | self 45 | } 46 | pub fn into_option(self) -> Option { 47 | match self { 48 | SoftOption::Missing => None, 49 | SoftOption::Soft(value) => Some(value), 50 | SoftOption::Explicit(value) => Some(value.value), 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/formats/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod anm; 2 | pub mod std; 3 | pub mod msg; 4 | pub mod ecl; 5 | pub mod mission; 6 | -------------------------------------------------------------------------------- /src/image/mod.rs: -------------------------------------------------------------------------------- 1 | pub use color::ColorFormat; 2 | pub mod color; 3 | -------------------------------------------------------------------------------- /src/llir/raise/infer_pcb_signatures.rs: -------------------------------------------------------------------------------- 1 | use super::{RaiseIntrinsicKind, RaiseScript}; 2 | 3 | use crate::ast; 4 | use crate::context::CompilerContext; 5 | use crate::ident::Ident; 6 | use crate::resolve::IdMap; 7 | use crate::value::ReadType; 8 | 9 | use RaiseIntrinsicKind as RIKind; 10 | 11 | /// Signatures for [`IKind::CallReg`] deduced directly from callsites. 12 | pub struct CallRegSignatures { 13 | pub signatures: IdMap>, 14 | } 15 | 16 | impl CallRegSignatures { 17 | /// Collect signatures from callsites, automatically setting [`RIKind::CallProper`] on those that 18 | /// match the returned signatures. 19 | pub fn infer_from_calls<'a>( 20 | scripts: impl IntoIterator, 21 | ctx: &CompilerContext<'_>, 22 | ) -> CallRegSignatures { 23 | let mut signatures = IdMap::default(); 24 | for script in scripts { 25 | for instr in &mut script.instrs { 26 | if instr.kind == RIKind::CallRegsGiven { 27 | if let Some(param_types) = param_types_from_args(&instr.parts.plain_args, ctx) { 28 | let saved_param_types = { 29 | &*signatures 30 | .entry(instr.parts.sub_id.clone().unwrap()) 31 | .or_insert_with(|| param_types.clone()) 32 | }; 33 | if ¶m_types == saved_param_types { 34 | instr.kind = RIKind::CallProper; 35 | } 36 | } 37 | } 38 | } 39 | } 40 | CallRegSignatures { signatures } 41 | } 42 | } 43 | 44 | // NOTE: I don't think it is possible for this to ever return None as that would suggest that 45 | // somehow something other than an int or float operand was decompiled from a register assignment. 46 | // But never say never... 47 | fn param_types_from_args(args: &[ast::Expr], ctx: &CompilerContext<'_>) -> Option> { 48 | args.iter() 49 | .map(|arg| { 50 | arg.compute_ty(ctx) 51 | .as_value_ty() 52 | .and_then(ReadType::from_ty) 53 | }) 54 | .collect() 55 | } 56 | -------------------------------------------------------------------------------- /src/parse/token_macro.rs: -------------------------------------------------------------------------------- 1 | macro_rules! define_token_enum { 2 | ( 3 | $( #[$($meta:tt)+] )* 4 | $vis:vis enum $Token:ident<$lt:lifetime> { 5 | $( #[token($fixed_str:literal)] $fixed_variant:ident, )* 6 | 7 | $( 8 | #[regex($($regex_tt:tt)+)] 9 | $regex_variant:ident($regex_ty:ty), 10 | )* 11 | 12 | #[error] 13 | $( #[ $($error_meta:tt)+ ] )* 14 | Error, 15 | 16 | $($other_variants:tt)* 17 | } 18 | ) => { 19 | $( #[$($meta)+] )* 20 | $vis enum $Token<$lt> { 21 | $( #[token($fixed_str)] $fixed_variant, )* 22 | 23 | $( #[regex($($regex_tt)+)] $regex_variant($regex_ty), )* 24 | 25 | #[error] 26 | $( #[ $($error_meta)+ ] )* 27 | Error, 28 | 29 | $($other_variants)* 30 | } 31 | 32 | const _: () = { 33 | use ::core::fmt; 34 | 35 | impl<'input> $Token<'input> { 36 | pub(super) fn as_str(&self) -> &'input str { 37 | match self { 38 | $( $Token::$fixed_variant => $fixed_str, )* 39 | $( $Token::$regex_variant(str) => str, )* 40 | $Token::Error => "", 41 | 42 | // e.g. virtual tokens 43 | #[allow(unreachable_patterns)] 44 | _ => "", 45 | } 46 | } 47 | } 48 | 49 | impl fmt::Display for Token<'_> { 50 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 51 | fmt::Display::fmt(&self.as_str(), f) 52 | } 53 | } 54 | }; 55 | }; 56 | } 57 | -------------------------------------------------------------------------------- /src/pos/mod.rs: -------------------------------------------------------------------------------- 1 | //! Source code locations (some parts borrowed from [qluon]) 2 | //! 3 | //! [qluon]: https://github.com/gluon-lang/gluon/blob/master/base/src/pos.rs 4 | 5 | pub type FileId = Option; 6 | pub use codespan::{ByteIndex as BytePos, ByteOffset, RawIndex, RawOffset}; 7 | 8 | pub use span::{Sp, Span, HasSpan}; 9 | #[macro_use] mod span; 10 | 11 | pub use source_map::Files; 12 | mod source_map; 13 | 14 | pub use source_str::SourceStr; 15 | mod source_str; 16 | -------------------------------------------------------------------------------- /src/raw.rs: -------------------------------------------------------------------------------- 1 | //! Raw integer aliases. 2 | //! 3 | //! Using these everywhere is not obligatory but they can help reduce memorization and 4 | //! they can also explain choices when there are competing reasonable alternatives 5 | //! for an integer size. 6 | //! 7 | //! You are meant to import this as `use crate::raw;` and then use the names qualified, 8 | //! e.g. `raw::LangInt`. This helps these types stand out as names that stand in for 9 | //! primitive types. 10 | 11 | /// An integer in the high-level abstract machine. 12 | /// 13 | /// The vast majority of integers in the AST will be of this type, even if they represent 14 | /// something of a lower bit-width in the target binary, as this may help them be replaced 15 | /// with const expressions in the future. 16 | pub type LangInt = i32; 17 | 18 | /// A floating point number in the high-level abstract machine. 19 | pub type LangFloat = f32; 20 | 21 | /// The preferred type for representing the time field of an instruction. 22 | pub type Time = i32; 23 | 24 | /// The preferred type for representing an instruction opcode. 25 | pub type Opcode = u16; 26 | 27 | /// The preferred type for representing a register ID. 28 | pub type Register = i32; 29 | 30 | /// The preferred type for representing the parameter mask field of an instruction. 31 | pub type ParamMask = u16; 32 | 33 | /// The preferred type for representing the extra argument of an ECL timeline instruction. 34 | pub type ExtraArg = i16; 35 | 36 | /// The preferred type for representing the difficulty mask field of an ECL instruction. 37 | pub type DifficultyMask = u8; 38 | 39 | /// The preferred type for representing the argument count field of an ECL instruction. 40 | pub type ArgCount = u8; 41 | 42 | /// An dword-sized integer serving as a bag of 32 bits. It's possible that these bits actually 43 | /// encode data of a different type. (e.g. a signed integer or a float...) 44 | pub type RawDwordBits = u32; 45 | 46 | /// The preferred type for representing the stack pop field of a modern ECL instruction. 47 | pub type StackPop = u8; 48 | 49 | /// The preferred type for representing an instruction's unsigned byte position relative to 50 | /// the beginning of a compiled subroutine. 51 | pub type BytePos = u64; 52 | -------------------------------------------------------------------------------- /tests/cli-help-version.rs: -------------------------------------------------------------------------------- 1 | //! Regression test to make sure that --help always works. 2 | 3 | use std::process::Command; 4 | 5 | use assert_cmd::prelude::*; 6 | use predicates::function::function as pred; 7 | 8 | #[test] 9 | fn help_actually_helps() { 10 | Command::cargo_bin("truanm").unwrap() 11 | .arg("compile") 12 | .arg("--help") 13 | .assert() 14 | .success() 15 | // check that the help text was shown by looking for part of the --game argument help 16 | .stderr(pred(|s: &str| s.contains("game number, e.g."))) 17 | ; 18 | } 19 | 20 | #[test] 21 | fn show_subcommands_error() { 22 | Command::cargo_bin("truanm").unwrap() 23 | .assert() 24 | .failure() 25 | // it should do a listing of subcommands. 26 | .stderr(pred(|s: &str| s.contains("truanm compile"))) 27 | .stderr(pred(|s: &str| s.contains("truanm decompile"))) 28 | ; 29 | } 30 | 31 | #[test] 32 | fn show_subcommands_help() { 33 | Command::cargo_bin("truanm").unwrap() 34 | .arg("--help") 35 | .assert() 36 | .success() // should succeed as long as --help is given 37 | .stderr(pred(|s: &str| s.contains("truanm compile"))) 38 | .stderr(pred(|s: &str| s.contains("truanm decompile"))) 39 | ; 40 | } 41 | 42 | #[test] 43 | fn subcommand_version() { 44 | Command::cargo_bin("truanm").unwrap() 45 | .arg("compile") 46 | .arg("--version") 47 | .assert() 48 | .success() 49 | ; 50 | } 51 | 52 | #[test] 53 | fn main_version() { 54 | Command::cargo_bin("truanm").unwrap() 55 | .arg("--version") 56 | .assert() 57 | .success() 58 | ; 59 | } 60 | 61 | #[test] 62 | fn core_version() { 63 | Command::cargo_bin("truth-core").unwrap() 64 | .arg("--version") 65 | .assert() 66 | .success() 67 | ; 68 | } 69 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__anm_consts__decompile_double_id.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/anm_consts.rs 3 | expression: stderr 4 | --- 5 | warning: : sprite ID 10 appeared twice in same entry; only one will be kept 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__anm_consts__err_sprite_clash.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/anm_consts.rs 3 | expression: stderr 4 | --- 5 | error: ambiguous value for enum const 'my_sprite' 6 | ┌─ :7:15 7 | │ 8 | 7 │ sprites: {my_sprite: {x: 1.0, y: 1.0, w: 111.0, h: 111.0, id: 0}}, 9 | │ ^^^^^^^^^ definition with value 0 10 | · 11 | 14 │ sprites: {my_sprite: {x: 2.0, y: 2.0, w: 222.0, h: 220.0, id: 1}}, 12 | │ ^^^^^^^^^ definition with value 1 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__anm_consts__err_sprite_clash_implicit.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/anm_consts.rs 3 | expression: stderr 4 | --- 5 | error: ambiguous value for enum const 'my_sprite' 6 | ┌─ :7:15 7 | │ 8 | 7 │ sprites: {my_sprite: {x: 1.0, y: 1.0, w: 111.0, h: 111.0, id: 1}}, 9 | │ ^^^^^^^^^ definition with value 1 10 | · 11 | 14 │ sprites: {my_sprite: {x: 2.0, y: 2.0, w: 222.0, h: 220.0}}, 12 | │ ^^^^^^^^^ definition with value 2 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__anm_consts__meta_non_const.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/anm_consts.rs 3 | expression: stderr 4 | --- 5 | error: unknown variable 'I0' 6 | ┌─ :28:26 7 | │ 8 | 28 │ memory_priority: 3 * I0, 9 | │ ^^ not found in this scope 10 | │ 11 | = there is a 'I0' defined in ANM, which is not a const expression 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__anm_consts__meta_sprite_id_circular_dependency.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/anm_consts.rs 3 | expression: stderr 4 | --- 5 | error: cycle in const definition 6 | ┌─ :30:9 7 | │ 8 | 30 │ coolSprite: {x: 0.0, y: 0.0, w: 512.0, h: 480.0, id: bestSprite * 3}, 9 | │ ^^^^^^^^^^ cyclic const 10 | · 11 | 33 │ coolestSprite: {x: 0.0, y: 0.0, w: 512.0, h: 480.0, id: coolSprite + 1}, 12 | │ ---------- depends on its own value here 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__anm_consts__meta_sprite_id_dupe_non_const.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/anm_consts.rs 3 | expression: stderr 4 | --- 5 | error: unknown variable 'I0' 6 | ┌─ :36:66 7 | │ 8 | 36 │ coolSprite: {x: 0.0, y: 0.0, w: 512.0, h: 480.0, id: 3 * I0}, 9 | │ ^^ not found in this scope 10 | │ 11 | = there is a 'I0' defined in ANM, which is not a const expression 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__anm_consts__meta_sprite_id_dupe_type_error.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/anm_consts.rs 3 | expression: stderr 4 | --- 5 | error: type error 6 | ┌─ :36:62 7 | │ 8 | 36 │ coolSprite: {x: 0.0, y: 0.0, w: 512.0, h: 480.0, id: 3.5}, 9 | │ ^^^ a float 10 | │ 11 | = an integer is required 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__anm_consts__meta_sprite_id_non_const.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/anm_consts.rs 3 | expression: stderr 4 | --- 5 | error: unknown variable 'I0' 6 | ┌─ :29:65 7 | │ 8 | 29 │ sprite200: {x: 0.0, y: 0.0, w: 512.0, h: 480.0, id: 3 * I0}, 9 | │ ^^ not found in this scope 10 | │ 11 | = there is a 'I0' defined in ANM, which is not a const expression 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__anm_consts__meta_sprite_id_type_error.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/anm_consts.rs 3 | expression: stderr 4 | --- 5 | error: type error 6 | ┌─ :29:62 7 | │ 8 | 29 │ coolSprite: {x: 0.0, y: 0.0, w: 512.0, h: 480.0, id: 3.5}, 9 | │ ^^^ a float 10 | │ 11 | = an integer is required 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__anm_consts__sprite_as_script_id.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/anm_consts.rs 3 | expression: stderr 4 | --- 5 | warning: suspicious use of enum AnmSprite 'imASprite' as enum AnmScript 6 | ┌─ :14:15 7 | │ 8 | 14 │ scriptNew(imASprite); 9 | │ ^^^^^^^^^ const in enum AnmSprite 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__anm_features__anti_scratch_bad_in_func.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/anm_features.rs 3 | expression: stderr 4 | --- 5 | error: scratch registers are disabled in this script 6 | ┌─ :35:27 7 | │ 8 | 35 │ F3 = (F0 + 1.0) * ((F0 + 2.0) * (F0 + 3.0)); 9 | │ ^^^^^^^^^^^^^^^^^^^^^^^^^ this fancy expression requires a scratch register 10 | 36 │ 11 | 37 │ copyVars(); 12 | │ ^^^^^^^^^^ this disables scratch registers 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__anm_features__orphaned_script.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/anm_features.rs 3 | expression: stderr 4 | --- 5 | error: orphaned ANM script with no entry 6 | ┌─ :4:1 7 | │ 8 | 4 │ ╭ script batman { 9 | 5 │ │ nop(); 10 | 6 │ │ } 11 | │ ╰─^ orphaned script 12 | │ 13 | = at least one `entry` must come before scripts in an ANM file 14 | 15 | 16 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__count_jmps__gt_jmp_can_suggest_ne.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/count_jmps.rs 3 | expression: stderr 4 | --- 5 | error: feature not supported by format 6 | ┌─ :29:13 7 | │ 8 | 29 │ if (--I2 > 0) goto label; 9 | │ ^^^^^^^^^^^^^^^^^^^^^^^^^ decrement jump of this form not supported in this game 10 | │ 11 | = this language supports a different form of decrement jump; try 'if (--I2)' 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__count_jmps__ne_jmp_can_suggest_gt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/count_jmps.rs 3 | expression: stderr 4 | --- 5 | error: feature not supported by format 6 | ┌─ :11:13 7 | │ 8 | 11 │ if (--I2) goto label; 9 | │ ^^^^^^^^^^^^^^^^^^^^^ decrement jump of this form not supported in this game 10 | │ 11 | = this language supports a different form of decrement jump; try 'if (--I2 > 0)' 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__decompile_block__decompile_labels_before_smorgasboard.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/decompile_block.rs 3 | expression: stderr 4 | --- 5 | warning: ECL instructions with unknown signatures were decompiled to byte blobs. 6 | = The following opcodes were affected: 9999 7 | 8 | 9 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__difficulty__diff_label_in_non_ecl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/difficulty.rs 3 | expression: stderr 4 | --- 5 | error: difficulty is not supported in this format 6 | ┌─ :28:5 7 | │ 8 | 28 │ {"012"}: int x = 1; 9 | │ ^^^^^^^^ difficulty label 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__difficulty__diff_label_with_time_label_bad_1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/difficulty.rs 3 | expression: stderr 4 | --- 5 | warning: conditional chain inside difficulty label may have surprising behavior 6 | ┌─ :13:9 7 | │ 8 | 11 │ {"ENH"}: { 9 | │ -------- in this difficulty label 10 | 12 │ nop(); 11 | 13 │ ╭ if (I0 == 0) { 12 | 14 │ │ +10: 13 | 15 │ │ nop(); 14 | 16 │ │ } 15 | │ ╰─────────^ conditional chain 16 | │ 17 | = This code may not behave as expected! Try using the difficulty register instead, e.g. `if (DIFFICULTY == 2)` instead of a difficulty label. 18 | 19 | warning: time label inside difficulty label may have surprising behavior 20 | ┌─ :14:1 21 | │ 22 | 11 │ {"ENH"}: { 23 | │ -------- in this difficulty label 24 | · 25 | 14 │ +10: 26 | │ ^^^^ time label 27 | │ 28 | = This code may not behave as expected! Try using the difficulty register instead, e.g. `if (DIFFICULTY == 2)` instead of a difficulty label. 29 | 30 | 31 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__difficulty__diff_label_with_time_label_bad_2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/difficulty.rs 3 | expression: stderr 4 | --- 5 | warning: conditional chain inside difficulty label may have surprising behavior 6 | ┌─ :10:5 7 | │ 8 | 10 │ ╭ {"ENH"}: if (I0 == 0) { 9 | │ -------- in this difficulty label 10 | 11 │ │ {"L"}: nop(); 11 | 12 │ │ } 12 | │ ╰─────^ conditional chain 13 | │ 14 | = This code may not behave as expected! Try using the difficulty register instead, e.g. `if (DIFFICULTY == 2)` instead of a difficulty label. 15 | 16 | 17 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__difficulty__diff_switch_in_const_fn_call.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/difficulty.rs 3 | expression: stderr 4 | --- 5 | error: feature not supported by format 6 | ┌─ :7:1 7 | │ 8 | 7 │ ╭ const int foo(int a) { 9 | 8 │ │ return 2 * a; 10 | 9 │ │ } 11 | │ ╰─^ not supported by old-format ECL files 12 | 13 | error: feature not supported by format 14 | ┌─ :12:10 15 | │ 16 | 12 │ I0 = foo(2:3:4:5); 17 | │ ^^^^^^^^^^^^ this expression not supported by format 18 | 19 | 20 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__difficulty__diff_switch_in_inline_fn_call.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/difficulty.rs 3 | expression: stderr 4 | --- 5 | error: feature not supported by format 6 | ┌─ :7:1 7 | │ 8 | 7 │ ╭ inline void foo(int a) { 9 | 8 │ │ I1 = 2 * a; 10 | 9 │ │ } 11 | │ ╰─^ not supported by old-format ECL files 12 | 13 | error: feature not supported by format 14 | ┌─ :12:5 15 | │ 16 | 12 │ foo(2:3:4:5); 17 | │ ^^^^^^^^^^^^ call to inline func not supported by format 18 | 19 | 20 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__difficulty__diff_switch_in_non_ecl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/difficulty.rs 3 | expression: stderr 4 | --- 5 | error: difficulty is not supported in this format 6 | ┌─ :28:13 7 | │ 8 | 28 │ int x = (1:2:3:4); 9 | │ ^^^^^^^^^ difficulty switch 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__difficulty__diff_switch_mismatched_number_of_cases.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/difficulty.rs 3 | expression: stderr 4 | --- 5 | error: mismatched diff switch lengths in a single statement 6 | ┌─ :10:10 7 | │ 8 | 10 │ I0 = (2:3:4:5) + (1:2:3:4:5); 9 | │ ^^^^^^^^^ ^^^^^^^^^^^ 5 cases 10 | │ │ 11 | │ 4 cases 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__difficulty__diff_switch_too_many_cases.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/difficulty.rs 3 | expression: stderr 4 | --- 5 | error: too many cases in diff switch 6 | ┌─ :10:10 7 | │ 8 | 10 │ I0 = (2::::::::); 9 | │ ^^^^^^^^^^^ 9 cases 10 | │ 11 | = difficulty masks are only 8 bits wide 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__ecl_features__eosd_cant_cast.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/ecl_features.rs 3 | expression: stderr 4 | --- 5 | error: feature not supported by format 6 | ┌─ :10:17 7 | │ 8 | 10 │ int a = int(F0 + 2.0); 9 | │ ^^^^^^^^^^^^^ this unary operation not supported by format 10 | 11 | error: feature not supported by format 12 | ┌─ :11:19 13 | │ 14 | 11 │ float x = float(I0 + 2); 15 | │ ^^^^^^^^^^^^^ this unary operation not supported by format 16 | 17 | 18 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__ecl_features__eosd_exported_fn_bad_siggies.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/ecl_features.rs 3 | expression: stderr 4 | --- 5 | error: invalid type for param in EoSD ECL 6 | ┌─ :7:11 7 | │ 8 | 7 │ void bad2(var x) {} 9 | │ ^^^ 10 | 11 | error: too many int params for EoSD ECL function 12 | ┌─ :9:18 13 | │ 14 | 9 │ void bad3(int x, int y) {} 15 | │ ^^^^^ extra int param 16 | │ 17 | = exported EoSD ECL functions are limited to 1 int and 1 float 18 | 19 | error: too many float params for EoSD ECL function 20 | ┌─ :11:27 21 | │ 22 | 11 │ void bad4(float x, int y, float z) {} 23 | │ ^^^^^^^ extra float param 24 | │ 25 | = exported EoSD ECL functions are limited to 1 int and 1 float 26 | 27 | 28 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__ecl_features__eosd_exported_fn_bad_siggy_return_type.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/ecl_features.rs 3 | expression: stderr 4 | --- 5 | error: return types are not supported in old-style ECL subs like 'bad5' 6 | ┌─ :7:1 7 | │ 8 | 7 │ int bad5(int x) { return 2; } 9 | │ ^^^ unsupported return type 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__ecl_features__eosd_exported_fn_bad_siggy_string.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/ecl_features.rs 3 | expression: stderr 4 | --- 5 | error: non-const string variable 6 | ┌─ :7:11 7 | │ 8 | 7 │ void bad1(string arg) {} 9 | │ ^^^^^^ only possible for const vars 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__ecl_features__eosd_exported_fn_const_fn_name_clash.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/ecl_features.rs 3 | expression: stderr 4 | --- 5 | error: redefinition of function 'name' 6 | ┌─ :8:16 7 | │ 8 | 7 │ void name() {} 9 | │ ---- originally defined here 10 | 8 │ const void name() {} 11 | │ ^^^^ redefinition of function 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__ecl_features__eosd_exported_fn_no_blob.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/ecl_features.rs 3 | expression: stderr 4 | --- 5 | error: forbidden pseudo-arg in function call 6 | ┌─ :15:7 7 | │ 8 | 15 │ i(@blob="ffffffff"); 9 | │ - ^^^^^^^^^^^^^^^^ 10 | │ │ 11 | │ not an instruction 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__ecl_features__eosd_exported_fn_no_pseudos.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/ecl_features.rs 3 | expression: stderr 4 | --- 5 | error: forbidden pseudo-arg in function call 6 | ┌─ :15:7 7 | │ 8 | 15 │ i(@mask=3, 4); 9 | │ - ^^^^^^^ 10 | │ │ 11 | │ not an instruction 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__ecl_features__eosd_param_alias_warning_named.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/ecl_features.rs 3 | expression: stderr 4 | --- 5 | warning: register F0 used under multiple names 6 | ┌─ :7:10 7 | │ 8 | 7 │ void foo(float x, int a) { 9 | │ ^^^^^^^ 10 | 8 │ %F0 = 24.0; 11 | │ ^^^ 12 | │ 13 | = EoSD ECL subs pass their arguments in I0 and F0 14 | 15 | 16 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__ecl_features__eosd_param_alias_warning_reg.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/ecl_features.rs 3 | expression: stderr 4 | --- 5 | warning: register F0 used under multiple names 6 | ┌─ :7:10 7 | │ 8 | 7 │ void foo(float x, int a) { 9 | │ ^^^^^^^ 10 | 8 │ %REG[-10005] = 24.0; 11 | │ ^^^^^^^^^^^^ 12 | │ 13 | = EoSD ECL subs pass their arguments in I0 and F0 14 | 15 | 16 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__ecl_features__eosd_param_is_not_scratch.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/ecl_features.rs 3 | expression: stderr 4 | --- 5 | error: script too complex to compile 6 | ┌─ :11:11 7 | │ 8 | 7 │ void i_f(int a, float x) { 9 | │ ------- F0 holds this 10 | 8 │ float t1 = 1.0; 11 | │ -- F1 holds this 12 | 9 │ float t2 = 2.0; 13 | │ -- F2 holds this 14 | 10 │ float t3 = 3.0; 15 | │ -- F3 holds this 16 | 11 │ float t4 = 4.0; 17 | │ ^^ no more registers of this type! 18 | 19 | 20 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__ecl_features__eosd_patchy_is_goddamn_dangerous.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/ecl_features.rs 3 | expression: stderr 4 | --- 5 | error: scratch registers are disabled in this entire file 6 | ┌─ :16:27 7 | │ 8 | 9 │ ins_130(1); // that one that disables the call stack 9 | │ ---------- Patchouli has tainted this entire file 10 | · 11 | 16 │ F3 = (F0 + 1.0) * ((F0 + 2.0) * (F0 + 3.0)); 12 | │ ^^^^^^^^^^^^^^^^^^^^^^^^^ this fancy expression requires a scratch register 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__ecl_features__eosd_unnamed_param_still_prevents_scratch.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/ecl_features.rs 3 | expression: stderr 4 | --- 5 | error: script too complex to compile 6 | ┌─ :11:11 7 | │ 8 | 7 │ void foo(float, int a) { 9 | │ ----- F0 holds this 10 | · 11 | 11 │ float z; 12 | │ ^ no more registers of this type! 13 | │ 14 | = the following registers are unavailable due to explicit use: F1, F2, F3 15 | 16 | 17 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__ecl_features__olde_unsupported_extern.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/ecl_features.rs 3 | expression: stderr 4 | --- 5 | error: extern functions are not supported in old-style ECL file 6 | ┌─ :7:1 7 | │ 8 | 7 │ void externFunc(); 9 | │ ^^^^^^^^^^^^^^^^^^ unsupported extern function 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__ecl_features__olde_unsupported_return_type.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/ecl_features.rs 3 | expression: stderr 4 | --- 5 | error: return types are not supported in old-style ECL subs like 'bouba' 6 | ┌─ :7:1 7 | │ 8 | 7 │ int bouba() { 9 | │ ^^^ unsupported return type 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__enums__compile_bad_conflict.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/enums.rs 3 | expression: stderr 4 | --- 5 | error: ambiguous value for enum const 'Name' 6 | ┌─ :3:4 7 | │ 8 | 3 │ 20 Name 9 | │ ^^^^ definition with value 20 10 | 4 │ 40 Name 11 | │ ^^^^ definition with value 40 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__enums__decompile_bad_conflict.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/enums.rs 3 | expression: stderr 4 | --- 5 | error: ambiguous value for enum const 'Name' 6 | ┌─ :3:4 7 | │ 8 | 3 │ 20 Name 9 | │ ^^^^ definition with value 20 10 | 4 │ 40 Name 11 | │ ^^^^ definition with value 40 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__enums__deduction_in_const_fn.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/enums.rs 3 | expression: stderr 4 | --- 5 | error: unexpected token `enum` 6 | ┌─ :25:27 7 | │ 8 | 25 │ const int ConstFn(enum FooEnum x) { 9 | │ ^^^^ unexpected token 10 | │ 11 | = 12 | Expected one of ")", "float", "int", "string", "var" or "void" 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__enums__enum_arg_not_ident.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/enums.rs 3 | expression: stderr 4 | --- 5 | error: invalid identifier: ax@3 6 | ┌─ :3:12 7 | │ 8 | 3 │ 999 S(enum="ax@3") 9 | │ ^^^^^^ 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__enums__enum_def_not_ident.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/enums.rs 3 | expression: stderr 4 | --- 5 | error: at enum sp!(9..26 => "ax@3"): invalid identifier: ax@3 6 | ┌─ :2:2 7 | │ 8 | 2 │ !enum(name="ax@3") 9 | │ ^^^^^^^^^^^^^^^^^ bad identifier 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__enums__legal_conflict_used_ambiguously.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/enums.rs 3 | expression: stderr 4 | --- 5 | error: ambiguous enum const 'Name' 6 | ┌─ :22:17 7 | │ 8 | 22 │ ins_400(Name); 9 | │ ^^^^ belongs to multiple enums 10 | 11 | error: ambiguous enum const 'Name' 12 | ┌─ :23:23 13 | │ 14 | 23 │ ins_999(@mask=Name, @blob="01000000"); 15 | │ ^^^^ belongs to multiple enums 16 | 17 | 18 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__enums__other_enum.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/enums.rs 3 | expression: stderr 4 | --- 5 | warning: suspicious use of enum BarEnum 'BarOnly' as enum FooEnum 6 | ┌─ :28:17 7 | │ 8 | 28 │ ins_400(BarOnly); 9 | │ ^^^^^^^ const in enum BarEnum 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__enums__undefined_enum__compile_undefined.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/enums.rs 3 | expression: stderr 4 | --- 5 | error: no such enum 'TestEnum' 6 | ┌─ :3:5 7 | │ 8 | 3 │ 400 S(enum="TestEnum") 9 | │ ^^^^^^^^^^^^^^^^^^ no such enum 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__enums__undefined_enum__compile_undefined_in_ast.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/enums.rs 3 | expression: stderr 4 | --- 5 | error: unexpected token `enum` 6 | ┌─ :19:31 7 | │ 8 | 19 │ const int ConstFn(enum NotAnEnum x) { 9 | │ ^^^^ unexpected token 10 | │ 11 | = 12 | Expected one of ")", "float", "int", "string", "var" or "void" 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__enums__undefined_enum__compile_undefined_in_dot_syntax.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/enums.rs 3 | expression: stderr 4 | --- 5 | error: no such enum 'NotAnEnum' 6 | ┌─ :28:18 7 | │ 8 | 28 │ I0 = NotAnEnum.Test; 9 | │ ^^^^^^^^^ no such enum 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__enums__undefined_enum__decompile_undefined.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/enums.rs 3 | expression: stderr 4 | --- 5 | error: no such enum 'TestEnum' 6 | ┌─ :3:5 7 | │ 8 | 3 │ 400 S(enum="TestEnum") 9 | │ ^^^^^^^^^^^^^^^^^^ no such enum 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__enums__undefined_enum__suggestion.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/enums.rs 3 | expression: stderr 4 | --- 5 | error: no such enum 'TesEnum' 6 | ┌─ :3:5 7 | │ 8 | 3 │ 400 S(enum="TesEnum") 9 | │ ^^^^^^^^^^^^^^^^^ 10 | │ │ 11 | │ no such enum 12 | │ did you mean `TestEnum`? 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__expr_compile__unary_neg_fallbacks_unavailable.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/expr_compile.rs 3 | expression: stderr 4 | --- 5 | error: feature not supported by format 6 | ┌─ :28:13 7 | │ 8 | 28 │ int a = -$I0; 9 | │ ^^^^ this unary operation not supported by format 10 | 11 | error: feature not supported by format 12 | ┌─ :29:15 13 | │ 14 | 29 │ float x = -%F0; 15 | │ ^^^^ this unary operation not supported by format 16 | 17 | 18 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__anm_bitwise.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: feature not supported by format 6 | ┌─ :28:14 7 | │ 8 | 28 │ I0 = I0 | I1; 9 | │ ^^^^^^^ this binary operation not supported in this game 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__arg_count_fixed.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: wrong number of arguments to 'posKeyframe' 6 | ┌─ :21:9 7 | │ 8 | 21 │ posKeyframe(0f, 0f, 0f, 0f); 9 | │ ^^^^^^^^^^^ expects 3 arguments, got 4 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__arg_count_range.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: wrong number of arguments to 'ins_2' 6 | ┌─ :21:9 7 | │ 8 | 21 │ ins_2(); 9 | │ ^^^^^ expects 1 to 3 arguments, got 0 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__bad_signature_in_mapfile.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: bad signature: 'z' or 'm' arguments with 'bs=' can only appear at the very end 6 | ┌─ :3:6 7 | │ 8 | 3 │ 1000 z(bs=4)S 9 | │ ^^^^^^^^ 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__break_outside_loop.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: break outside of a loop 6 | ┌─ :21:9 7 | │ 8 | 21 │ break; 9 | │ ^^^^^ not valid outside of a loop 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__break_outside_loop_in_nested_func.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: break outside of a loop 6 | ┌─ :23:17 7 | │ 8 | 23 │ break; 9 | │ ^^^^^ not valid outside of a loop 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__const_calling_non_const.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: const evaluation error 6 | ┌─ :12:27 7 | │ 8 | 12 │ const int konst = foo(3); 9 | │ ----- ^^^^^^ non-const expression 10 | │ │ 11 | │ while evaluating this const 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__const_difficulty.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: const evaluation error 6 | ┌─ :10:23 7 | │ 8 | 10 │ const int x = (2:3:4:5); 9 | │ - ^^^^^^^^^ non-const expression 10 | │ │ 11 | │ while evaluating this const 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__const_reg.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: raw register in const context 6 | ┌─ :25:23 7 | │ 8 | 25 │ const int y = $REG[10000]; 9 | │ ^^^^^^^^^^^ forbidden in this context 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__const_sigil.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: const evaluation error 6 | ┌─ :10:23 7 | │ 8 | 10 │ const int x = $(2.0 + 3.0); 9 | │ - ^^^^^^^^^^^^ non-const expression 10 | │ │ 11 | │ while evaluating this const 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__const_untyped.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: illegal untyped const 6 | ┌─ :25:15 7 | │ 8 | 25 │ const var x = 3; 9 | │ ^^^ const vars must have a type 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__const_void.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: void-typed variable 6 | ┌─ :25:15 7 | │ 8 | 25 │ const void x = delete(); 9 | │ ^^^^ variables must have a value 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__decompile_missing_signature.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | warning: ANM instructions with unknown signatures were decompiled to byte blobs. 6 | = The following opcodes were affected: 777 7 | 8 | 9 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__duplicate_label.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: duplicate label 'label' 6 | ┌─ :22:5 7 | │ 8 | 21 │ label: 9 | │ ----- originally defined here 10 | 22 │ label: 11 | │ ^^^^^ redefined here 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__eosd_anm_early_end.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: statement after end of script 6 | ┌─ :29:9 7 | │ 8 | 28 │ ins_0(); 9 | │ ----- marks the end of the script 10 | 29 │ pos(0f, 0f, 0f); 11 | │ ^^^^^^^^^^^^^^^^ forbidden statement 12 | │ 13 | = In EoSD ANM, every script must have a single exit point (opcode 0 or 15), as the final instruction. 14 | 15 | 16 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__func_const_ins.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: raw instruction in const context 6 | ┌─ :26:13 7 | │ 8 | 26 │ ins_23(); 9 | │ ^^^^^^ forbidden in this context 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__func_const_reg.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: raw register in const context 6 | ┌─ :26:25 7 | │ 8 | 26 │ int x = 3 + $REG[10000]; 9 | │ ^^^^^^^^^^^ forbidden in this context 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__func_exported_string.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: feature not supported by format 6 | ┌─ :25:9 7 | │ 8 | 25 │ string foo() { return "hi"; } 9 | │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not supported by ANM files 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__func_inline_const.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: too many function qualifiers 6 | ┌─ :25:16 7 | │ 8 | 25 │ inline const int foo() { return 1; } 9 | │ ^^^^^ extra qualifier 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__func_param_named_after_reg.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: unexpected token `REG` 6 | ┌─ :25:22 7 | │ 8 | 25 │ void foo(int REG[100]) {} 9 | │ ^^^ unexpected token 10 | │ 11 | = 12 | Expected one of ")", ",", ";", "anim", "case", "default", "ecli", "entry", "mapfile", "script" or IDENT 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__func_untyped.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: var-typed function 6 | ┌─ :25:9 7 | │ 8 | 25 │ var foo() { return 1; } 9 | │ ^^^ cannot be used on functions 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__jump_missing_label.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: undefined label 'label' 6 | ┌─ :21:14 7 | │ 8 | 21 │ goto label; 9 | │ ^^^^^ there is no label by this name 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__jump_offsetof_expression.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: argument must be a compile-time constant 6 | ┌─ :10:18 7 | │ 8 | 10 │ jump(30, (offsetof(label) + 4) * 2); 9 | │ ^^^^^^^^^^^^^^^^^^^^^^^^^ not constant 10 | │ 11 | = because the argument is a jump offset 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__local_in_std.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: feature not supported by format 6 | ┌─ :21:13 7 | │ 8 | 21 │ int x = 4; 9 | │ ^^^^^ update assignment with this operation not supported by format 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__local_named_after_reg.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: unexpected token `REG` 6 | ┌─ :28:13 7 | │ 8 | 28 │ int REG[100] = 3; 9 | │ ^^^ unexpected token 10 | │ 11 | = 12 | Expected one of "(", ";", "anim", "case", "default", "ecli", "entry", "mapfile", "script" or IDENT 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__local_string.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: non-const string variable 6 | ┌─ :28:9 7 | │ 8 | 28 │ string x = "hi"; 9 | │ ^^^^^^ only possible for const vars 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__local_void.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: void-typed variable 6 | ┌─ :28:9 7 | │ 8 | 28 │ void x = delete(); 9 | │ ^^^^ variables must have a value 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__recursive_const.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: cycle in const definition 6 | ┌─ :19:19 7 | │ 8 | 19 │ const int UH_OH = UMMMM; 9 | │ ^^^^^ cyclic const 10 | 20 │ const int UMMMM = HALP; 11 | 21 │ const int HALP = UH_OH; 12 | │ ----- depends on its own value here 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__reg_in_unsupported_lang.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: non-constant expression in language without registers 6 | ┌─ :14:20 7 | │ 8 | 14 │ textSet(0, $REG[0], "cheese"); 9 | │ ^^^^^^^ non-const expression 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__stackless__untyped_var.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: feature not supported by format 6 | ┌─ :28:9 7 | │ 8 | 28 │ var x; 9 | │ ^^^ untyped variables not supported by format 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__uninitialized_const.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: uninitialized const var 6 | ┌─ :25:26 7 | │ 8 | 25 │ const int y = 3, z, w = 4; 9 | │ ^ needs a value 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__unknown_instr_name.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: unknown ANM instruction or function 'iMadeThisUpYesterday' 6 | ┌─ :28:9 7 | │ 8 | 28 │ iMadeThisUpYesterday(0, 0, 0); 9 | │ ^^^^^^^^^^^^^^^^^^^^ not found in this scope 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__unknown_instr_signature.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: signature not known for ANM opcode 6000 6 | ┌─ :28:9 7 | │ 8 | 28 │ ins_6000(0, 0, 0); 9 | │ ^^^^^^^^ signature not known 10 | │ 11 | = try adding this instruction's signature to your mapfiles 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__unknown_variable.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: unknown ANM register or variable 'y' 6 | ┌─ :28:17 7 | │ 8 | 28 │ int x = y; 9 | │ ^ not found in this scope 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__general__xcrement_in_unsupported_spot.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/general.rs 3 | expression: stderr 4 | --- 5 | error: feature not supported by format 6 | ┌─ :28:17 7 | │ 8 | 28 │ int x = --I0; 9 | │ ^^^^ this expression not supported by format 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__image_sources__anm_import_wrong_img_height__failure.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/image_sources.rs 3 | expression: stderr 4 | --- 5 | error: provided dimensions for 'subdir/hi-32x16.png' do not match image source: 32x16 in script, 32x12 in image source 6 | ┌─ :6:17 7 | │ 8 | 6 │ img_height: 16, 9 | │ ^^ 10 | │ 11 | = image was loaded from 'tests/integration/resources/th12-embedded-bad-image-source.anm' 12 | = you can remove these explicit dimensions to infer them from the image source 13 | = you can add another image source to override this image 14 | = you can use `has_image: "dummy"` to ignore the image in the source and generate dummy data 15 | 16 | 17 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__image_sources__anm_import_wrong_img_height_then_png__failure.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/image_sources.rs 3 | expression: stderr 4 | --- 5 | error: provided dimensions for 'subdir/hi-32x16.png' do not match image source: 32x16 in script, 32x12 in image source 6 | ┌─ :6:17 7 | │ 8 | 6 │ img_height: 16, 9 | │ ^^ 10 | │ 11 | = image was loaded from 'tests/integration/resources/th12-embedded-bad-image-source.anm' 12 | = you can remove these explicit dimensions to infer them from the image source 13 | = you can add another image source to override this image 14 | = you can use `has_image: "dummy"` to ignore the image in the source and generate dummy data 15 | 16 | 17 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__image_sources__color_formats__bad_dummy.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/image_sources.rs 3 | expression: stderr 4 | --- 5 | error: unknown color format 8 (for image 'i-dont-exist.png') 6 | = has_data: "dummy" requires one of the following formats: FORMAT_ARGB_8888, FORMAT_RGB_565, FORMAT_ARGB_4444, FORMAT_GRAY_8 7 | 8 | 9 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__image_sources__color_formats__bad_dummy_with_no_span.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/image_sources.rs 3 | expression: stderr 4 | --- 5 | error: unknown color format 8 (for image 'teeny.png') 6 | = has_data: "dummy" requires one of the following formats: FORMAT_ARGB_8888, FORMAT_RGB_565, FORMAT_ARGB_4444, FORMAT_GRAY_8 7 | 8 | 9 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__image_sources__color_formats__bad_image.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/image_sources.rs 3 | expression: stderr 4 | --- 5 | error: cannot transcode into unknown color format 8 (for image 'subdir/hi-7x20.png') 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__image_sources__color_formats__bad_image_into_with_no_span.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/image_sources.rs 3 | expression: stderr 4 | --- 5 | error: cannot transcode into unknown color format 8 (for image 'teeny.png') 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__image_sources__color_formats__bad_transcode_from.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/image_sources.rs 3 | expression: stderr 4 | --- 5 | error: cannot transcode from unknown color format 8 (for image 'teeny.png') 6 | = color format 8 appears in 'tests/integration/resources/th12-embedded-weird-format-source.anm' 7 | 8 | 9 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__image_sources__color_formats__bad_transcode_into.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/image_sources.rs 3 | expression: stderr 4 | --- 5 | error: cannot transcode into unknown color format 8 (for image 'lmao.png') 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__image_sources__image_source_does_not_exist.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/image_sources.rs 3 | expression: stderr 4 | --- 5 | error: while resolving 'this/is/a/bad/path': (os error) 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__image_sources__image_source_in_msg.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/image_sources.rs 3 | expression: stderr 4 | --- 5 | error: unexpected image_source 6 | ┌─ :11:30 7 | │ 8 | 11 │ #pragma image_source "tests/integration/resources/th12-embedded-image-source.anm" 9 | │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ image_source not valid in this format 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__image_sources__image_source_in_olde_ecl.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/image_sources.rs 3 | expression: stderr 4 | --- 5 | error: unexpected image_source 6 | ┌─ :7:30 7 | │ 8 | 7 │ #pragma image_source "tests/integration/resources/th12-embedded-image-source.anm" 9 | │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ image_source not valid in this format 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__image_sources__image_source_in_std.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/image_sources.rs 3 | expression: stderr 4 | --- 5 | error: unexpected image_source 6 | ┌─ :18:30 7 | │ 8 | 18 │ #pragma image_source "tests/integration/resources/th12-embedded-image-source.anm" 9 | │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ image_source not valid in this format 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__image_sources__no_source__err_dummy_missing_img_dim.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/image_sources.rs 3 | expression: stderr 4 | --- 5 | error: missing required field 'img_width' (for image 'subdir/file.png') 6 | ┌─ :6:15 7 | │ 8 | 6 │ has_data: "dummy", 9 | │ ^^^^^^^ requires setting 'img_width'' 10 | │ 11 | = you can use '-i ANM_FILE' or '-i path/to/patchdir' to copy the image dimensions from an image source 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__image_sources__no_source__err_missing_image.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/image_sources.rs 3 | expression: stderr 4 | --- 5 | error: no bitmap data available for 'subdir/file.png' 6 | = you can use '-i ANM_FILE' or '-i path/to/patchdir' to import images 7 | = alternatively, use 'has_data: false' to compile with no image, or 'has_data: "dummy"' to generate a magenta placeholder 8 | 9 | 10 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__image_sources__no_source__err_missing_metadata.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/image_sources.rs 3 | expression: stderr 4 | --- 5 | error: missing required field 'rt_width'! 6 | ┌─ :6:15 7 | │ 8 | 6 │ has_data: false, 9 | │ ^^^^^ requires setting 'rt_width' 10 | │ 11 | = you can also set 'img_width' to infer 'rt_width' as the next power of 2 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__image_sources__png_import_buf_not_power_2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/image_sources.rs 3 | expression: stderr 4 | --- 5 | warning: rt_height = 21 should be a power of two 6 | ┌─ :8:16 7 | │ 8 | 8 │ rt_height: 21, 9 | │ ^^ not a power of two 10 | 11 | warning: rt_width = 7 should be a power of two 12 | ┌─ :7:15 13 | │ 14 | 7 │ rt_width: 7, 15 | │ ^ not a power of two 16 | 17 | 18 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__image_sources__png_import_buf_too_small.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/image_sources.rs 3 | expression: stderr 4 | --- 5 | warning: while writing '':in entry 0 (for 'subdir/hi-32x16.png'): runtime width of 16 too small for image width of 32 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__image_sources__png_import_with_offset_too_big__failure.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/image_sources.rs 3 | expression: stderr 4 | --- 5 | error: tests/integration/resources/dir-with-bad-images/subdir/hai-10x18+105+9.png: image too small (10x18) for an offset of (105, 9) 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__image_sources__png_import_wrong_img_height__failure.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/image_sources.rs 3 | expression: stderr 4 | --- 5 | error: tests/integration/resources/dir-with-bad-images/subdir/hi-32x16.png: wrong image dimensions (expected 32x16, got 32x12) 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__interrupts__sugar_register.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/interrupts.rs 3 | expression: stderr 4 | --- 5 | error: const evaluation error in interrupt label 6 | ┌─ :29:15 7 | │ 8 | 29 │ interrupt[I0]: 9 | │ ^^ non-const expression 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__mapfiles__abi_multiple_o.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/mapfiles.rs 3 | expression: stderr 4 | --- 5 | error: bad signature: signature has multiple 'o' args 6 | ┌─ :3:5 7 | │ 8 | 3 │ 300 oot 9 | │ ^^^ 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__mapfiles__abi_string_errors.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/mapfiles.rs 3 | expression: stderr 4 | --- 5 | error: mutually exclusive attributes 'len' and 'bs' in 'z' format 6 | ┌─ :3:5 7 | │ 8 | 3 │ 0 z(len=20;bs=4) 9 | │ ^^^ ^^ 10 | 11 | error: 'len' attribute is not supported by 'p' 12 | ┌─ :4:5 13 | │ 14 | 4 │ 1 p(len=20) 15 | │ ^^^ 16 | 17 | error: missing length attribute ('len' or 'bs') for 'p' 18 | ┌─ :5:3 19 | │ 20 | 5 │ 2 p 21 | │ ^ 22 | 23 | 24 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__mapfiles__diff_flags_bad_index.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/mapfiles.rs 3 | expression: stderr 4 | --- 5 | error: difficulty flag index out of range 6 | ┌─ :3:3 7 | │ 8 | 3 │ 8 b- 9 | │ ^^ must be from 0 to 7 inclusive 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__mapfiles__diff_flags_syntax_errors.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/mapfiles.rs 3 | expression: stderr 4 | --- 5 | error: invalid difficulty flag definition 6 | ┌─ :3:3 7 | │ 8 | 3 │ 1 @- 9 | │ ^^ 10 | │ 11 | = the definition must consist of a ASCII alphanumeric character and a +/- (+ means enabled by default) 12 | 13 | error: invalid difficulty flag definition 14 | ┌─ :4:3 15 | │ 16 | 4 │ 2 X@ 17 | │ ^^ 18 | │ 19 | = the definition must consist of a ASCII alphanumeric character and a +/- (+ means enabled by default) 20 | 21 | error: invalid difficulty flag definition 22 | ┌─ :5:3 23 | │ 24 | 5 │ 3 a 25 | │ ^ 26 | │ 27 | = the definition must consist of a ASCII alphanumeric character and a +/- (+ means enabled by default) 28 | 29 | error: invalid difficulty flag definition 30 | ┌─ :6:3 31 | │ 32 | 6 │ 4 θ # a two byte character 33 | │ ^ 34 | │ 35 | = the definition must consist of a ASCII alphanumeric character and a +/- (+ means enabled by default) 36 | 37 | 38 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__mapfiles__enum_type_conflicts_with_builtin.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/mapfiles.rs 3 | expression: stderr 4 | --- 5 | error: incorrect type for enum EclSubName 6 | ┌─ :2:2 7 | │ 8 | 2 │ !enum(name="EclSubName") 9 | │ ^^^^^^^^^^^^^^^^^^^^^^^ declaration with type int 10 | │ 11 | = the built-in type of enum EclSubName is string 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__mapfiles__intrinsic_has_extra_arg.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/mapfiles.rs 3 | expression: stderr 4 | --- 5 | error: bad ABI for intrinsic AssignOp(op="="; type="int"): unexpected dword integer arg at index 3 6 | ┌─ :3:4 7 | │ 8 | 3 │ 99 AssignOp(op="="; type="int") 9 | │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ intrinsic defined here 10 | 4 │ !ins_signatures 11 | 5 │ 99 SSS 12 | │ ^^^ signature defined here 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__mapfiles__intrinsic_has_insufficient_args.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/mapfiles.rs 3 | expression: stderr 4 | --- 5 | error: bad ABI for intrinsic AssignOp(op="="; type="int"): not enough arguments 6 | ┌─ :3:4 7 | │ 8 | 3 │ 99 AssignOp(op="="; type="int") 9 | │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ intrinsic defined here 10 | 4 │ !ins_signatures 11 | 5 │ 99 S 12 | │ ^ signature defined here 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__mapfiles__intrinsic_jmp_mislabeled_time.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/mapfiles.rs 3 | expression: stderr 4 | --- 5 | error: bad ABI for intrinsic Jmp(): unexpected dword integer arg at index 1 6 | ┌─ :3:3 7 | │ 8 | 3 │ 4 Jmp() 9 | │ ^^^^^ intrinsic defined here 10 | 4 │ !ins_signatures 11 | 5 │ 4 So 12 | │ ^^ signature defined here 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__mapfiles__intrinsic_jmp_needs_offset.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/mapfiles.rs 3 | expression: stderr 4 | --- 5 | error: bad signature: signature has a 't' arg without an 'o' arg 6 | ┌─ :5:3 7 | │ 8 | 5 │ 4 St 9 | │ ^^ 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__mapfiles__intrinsic_jmp_non_consecutive_offset_time.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/mapfiles.rs 3 | expression: stderr 4 | --- 5 | error: bad ABI for intrinsic CountJmp(): offset ('o') and time ('t') args must be consecutive 6 | ┌─ :3:5 7 | │ 8 | 3 │ 300 tSo 9 | │ ^^^ signature defined here 10 | 4 │ !ins_intrinsics 11 | 5 │ 300 CountJmp() 12 | │ ^^^^^^^^^^ intrinsic defined here 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__mapfiles__intrinsic_name_garbage.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/mapfiles.rs 3 | expression: stderr 4 | --- 5 | error: expected open parenthesis 6 | ┌─ :5:8 7 | │ 8 | 5 │ 4 lmfao 9 | │ ^ 10 | 11 | error: missing closing parenthesis for attribute list 12 | ┌─ :8:10 13 | │ 14 | 8 │ 5 CondJmp(op=">";type="int" 15 | │ ^ unclosed parenthesis 16 | 17 | warning: unsupported or unknown attribute 'type' for 'Jmp' 18 | ┌─ :11:7 19 | │ 20 | 11 │ 6 Jmp(type="int") 21 | │ ^^^^ 22 | 23 | error: missing attribute 'type' for 'CondJmp' 24 | ┌─ :14:3 25 | │ 26 | 14 │ 7 CondJmp(op=">=") 27 | │ ^^^^^^^ 28 | 29 | error: Matching variant not found 30 | ┌─ :17:3 31 | │ 32 | 17 │ 8 CondimentJmp(op=">=";type="int") 33 | │ ^^^^^^^^^^^^ 34 | 35 | error: unexpected token after attributes 36 | ┌─ :20:31 37 | │ 38 | 20 │ 9 CondJmp(op=">=";type="int") lol 39 | │ ^^^ 40 | 41 | error: expected identifier 42 | ┌─ :23:4 43 | │ 44 | 23 │ 10 10() 45 | │ ^^ 46 | 47 | error: invalid identifier: break 48 | ┌─ :26:4 49 | │ 50 | 26 │ 11 break() 51 | │ ^^^^^ 52 | 53 | 54 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__mapfiles__intrinsic_op_input_arg_wrong_type.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/mapfiles.rs 3 | expression: stderr 4 | --- 5 | error: bad ABI for intrinsic AssignOp(op="="; type="int"): ABI input arg has unexpected encoding (float) 6 | ┌─ :3:4 7 | │ 8 | 3 │ 99 AssignOp(op="="; type="int") 9 | │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ intrinsic defined here 10 | 4 │ !ins_signatures 11 | 5 │ 99 Sf 12 | │ ^^ signature defined here 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__mapfiles__intrinsic_op_output_arg_wrong_type.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/mapfiles.rs 3 | expression: stderr 4 | --- 5 | error: bad ABI for intrinsic AssignOp(op="="; type="int"): output arg has unexpected encoding (float) 6 | ┌─ :3:4 7 | │ 8 | 3 │ 99 AssignOp(op="="; type="int") 9 | │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ intrinsic defined here 10 | 4 │ !ins_signatures 11 | 5 │ 99 fS 12 | │ ^^ signature defined here 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__mapfiles__intrinsic_with_mismatched_signature_in_core_map.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/mapfiles.rs 3 | expression: stderr 4 | --- 5 | error: bad ABI for intrinsic Jmp(): missing jump offset ('o') 6 | ┌─ :3:3 7 | │ 8 | 3 │ 3 Jmp() # id of 'sprite' 9 | │ ^^^^^ intrinsic defined here 10 | │ 11 | = the built-in signature for ANM opcode 3 is "n" 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__mapfiles__intrinsic_without_signature.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/mapfiles.rs 3 | expression: stderr 4 | --- 5 | error: opcode 999 is an intrinsic but has no signature 6 | ┌─ :3:5 7 | │ 8 | 3 │ 999 Jmp() 9 | │ ^^^^^ defined as an intrinsic here 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__mapfiles__keywords_or_forbidden_idents.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/mapfiles.rs 3 | expression: stderr 4 | --- 5 | error: at key 99: invalid identifier: break 6 | ┌─ :3:4 7 | │ 8 | 3 │ 99 break 9 | │ ^^^^^ bad identifier 10 | 11 | error: at key 100: invalid identifier: ins_200 12 | ┌─ :4:5 13 | │ 14 | 4 │ 100 ins_200 15 | │ ^^^^^^^ bad identifier 16 | 17 | 18 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__mapfiles__mapfile_does_not_exist.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/mapfiles.rs 3 | expression: stderr 4 | --- 5 | error: while resolving 'this/is/a/bad/path': (os error) 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__mapfiles__seqmap_missing_magic.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/mapfiles.rs 3 | expression: stderr 4 | --- 5 | error: missing magic for mapfile 6 | ┌─ :1:1 7 | │ 8 | 1 │ 9 | │ ^ line does not begin with '!' 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__mapfiles__seqmap_missing_section_header.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/mapfiles.rs 3 | expression: stderr 4 | --- 5 | error: mapfile missing section header 6 | ┌─ :2:1 7 | │ 8 | 2 │ 300 ot 9 | │ ^^^^^^ entry without section header 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__msg_features__duplicate_script.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/msg_features.rs 3 | expression: stderr 4 | --- 5 | error: redefinition of script 'script0' 6 | ┌─ :9:8 7 | │ 8 | 8 │ script script0 {} 9 | │ ------- ...but 'script0' was already defined here 10 | 9 │ script script0 {} 11 | │ ^^^^^^^ this defines a script called 'script0'... 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__msg_features__integer_meta_key_normalization.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/msg_features.rs 3 | expression: stderr 4 | --- 5 | error: duplicate metadata field '0' 6 | ┌─ :7:9 7 | │ 8 | 5 │ 0: {script: "script0"}, 9 | │ - previously supplied here 10 | 6 │ 1: {script: "script0"}, 11 | 7 │ 0x0: {script: "script0"}, 12 | │ ^^^ duplicate key 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__msg_features__table_len_too_short.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/msg_features.rs 3 | expression: stderr 4 | --- 5 | warning: unused script table entry 6 | ┌─ :6:9 7 | │ 8 | 3 │ table_len: 1, 9 | │ - unused due to this length 10 | · 11 | 6 │ 1: {script: "script1"}, 12 | │ ^ unused table entry 13 | 7 │ 2: {script: "script2"}, 14 | │ ^ unused table entry 15 | 8 │ 3: {script: "script2"}, 16 | │ ^ unused table entry 17 | 18 | 19 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__msg_features__unused_script.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/msg_features.rs 3 | expression: stderr 4 | --- 5 | warning: unused script 'foo' 6 | ┌─ :10:8 7 | │ 8 | 10 │ script foo {} 9 | │ ^^^ unused script 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__pseudo__pseudo_after_arg.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/pseudo.rs 3 | expression: stderr 4 | --- 5 | error: invalid pseudo-arg 6 | ┌─ :28:18 7 | │ 8 | 28 │ wait(12, @mask=0b1); 9 | │ ^^^^^^ must come before other arguments 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__pseudo__pseudo_bad_name.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/pseudo.rs 3 | expression: stderr 4 | --- 5 | error: invalid pseudo-arg 6 | ┌─ :28:15 7 | │ 8 | 28 │ wait(@blobloblob="0f000000"); 9 | │ ^^^^^^^^^^ not a pseudo-arg 10 | │ 11 | = valid pseudo-args are: pop, mask, blob, arg0, nargs 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__pseudo__pseudo_blob_with_arg.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/pseudo.rs 3 | expression: stderr 4 | --- 5 | error: cannot supply both normal arguments and an args blob 6 | ┌─ :28:32 7 | │ 8 | 28 │ wait(@blob="0f000000", 15); 9 | │ ---------- ^^ redundant normal argument 10 | │ │ 11 | │ represents all args 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__pseudo__pseudo_dupe.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/pseudo.rs 3 | expression: stderr 4 | --- 5 | error: duplicate pseudo-arg 6 | ┌─ :28:38 7 | │ 8 | 28 │ wait(@blob="0f000000", @blob="0f000000"); 9 | │ ---------- ^^^^^^^^^^ duplicate pseudo-arg 10 | │ │ 11 | │ previously supplied here 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__pseudo__pseudo_in_const_call.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/pseudo.rs 3 | expression: stderr 4 | --- 5 | error: forbidden pseudo-arg in function call 6 | ┌─ :30:21 7 | │ 8 | 30 │ int x = foo(@mask=0b1, 12); 9 | │ --- ^^^^^^^^^ 10 | │ │ 11 | │ not an instruction 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__pseudo__pseudo_in_inline_call.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/pseudo.rs 3 | expression: stderr 4 | --- 5 | error: forbidden pseudo-arg in function call 6 | ┌─ :30:13 7 | │ 8 | 30 │ foo(@mask=0b1, 12); 9 | │ --- ^^^^^^^^^ 10 | │ │ 11 | │ not an instruction 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__pseudo__pseudo_len_ndiv_4.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/pseudo.rs 3 | expression: stderr 4 | --- 5 | error: number of bytes in blob not divisible by 4 6 | ┌─ :28:20 7 | │ 8 | 28 │ wait(@blob="0f0000"); 9 | │ ^^^^^^^^ blob literal of length 3 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__pseudo__pseudo_non_const.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/pseudo.rs 3 | expression: stderr 4 | --- 5 | error: non-const pseudo-arg 6 | ┌─ :29:20 7 | │ 8 | 29 │ wait(@mask=I0, @blob="10270000"); 9 | │ ^^ non-const pseudo-arg 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__std_features__bad_object_name.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/std_features.rs 3 | expression: stderr 4 | --- 5 | error: no object named blarb 6 | ┌─ :30:9 7 | │ 8 | 30 │ blarb {pos: [-192.0, 6344.0, 0.0]}, 9 | │ ^^^^^ not an object 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__std_features__renamed_layer_conflict.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/std_features.rs 3 | expression: stderr 4 | --- 5 | error: cannot supply both 'unknown' and 'layer' 6 | ┌─ :9:13 7 | │ 8 | 9 │ unknown: 3, 9 | │ ^^^^^^^ conflicting field 10 | 10 │ layer: 4, 11 | │ ^^^^^ conflicting field 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__std_features__renamed_layer_missing.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/std_features.rs 3 | expression: stderr 4 | --- 5 | error: incomplete metadata object 6 | ┌─ :8:16 7 | │ 8 | 8 │ thing: { 9 | │ ╭────────────────^ 10 | 9 │ │ pos: [10.0, 20.0, 30.0], 11 | 10 │ │ size: [10.0, 20.0, 30.0], 12 | 11 │ │ quads: [], 13 | 12 │ │ }, 14 | │ ╰─────────^ missing field 'layer' 15 | 16 | 17 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__std_features__strip_in_bad_game.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/std_features.rs 3 | expression: stderr 4 | --- 5 | warning: while writing '':'strip' quads can only be used in TH08 and TH09! 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__strings__compile_string_arg_too_big_eq.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/strings.rs 3 | expression: stderr 4 | --- 5 | error: string argument too large for buffer 6 | ┌─ :10:11 7 | │ 8 | 10 │ fixed("abcdefgh"); 9 | │ ^^^^^^^^^^ requires 9 bytes 10 | │ 11 | = this argument is written to a 8-byte buffer 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__strings__compile_string_arg_too_big_gt.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/strings.rs 3 | expression: stderr 4 | --- 5 | error: string argument too large for buffer 6 | ┌─ :10:11 7 | │ 8 | 10 │ fixed("abcdefghi"); 9 | │ ^^^^^^^^^^^ requires 10 bytes 10 | │ 11 | = this argument is written to a 8-byte buffer 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__strings__compile_string_arg_too_big_gt_nulless.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/strings.rs 3 | expression: stderr 4 | --- 5 | error: string argument too large for buffer 6 | ┌─ :10:13 7 | │ 8 | 10 │ nulless("abcdefghi"); 9 | │ ^^^^^^^^^^^ requires 9 bytes 10 | │ 11 | = this argument is written to a 8-byte buffer 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__strings__decompile_string_arg_with_null_1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/strings.rs 3 | expression: stderr 4 | --- 5 | warning: : in sub0: instr 0 (opcode 444, offset 0x0): argument 1: string will be truncated at first null 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__strings__decompile_string_arg_with_null_2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/strings.rs 3 | expression: stderr 4 | --- 5 | warning: : in sub0: instr 0 (opcode 444, offset 0x0): argument 1: string will be truncated at first null 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__strings__decompile_string_arg_with_null_3.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/strings.rs 3 | expression: stderr 4 | --- 5 | warning: : in sub0: instr 0 (opcode 555, offset 0x0): argument 1: string will be truncated at first null 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__strings__decompile_string_arg_with_null_4.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/strings.rs 3 | expression: stderr 4 | --- 5 | warning: : in sub0: instr 0 (opcode 666, offset 0x0): argument 1: string will be truncated at first null 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__strings__decompile_string_arg_without_null_bs.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/strings.rs 3 | expression: stderr 4 | --- 5 | warning: : in sub0: instr 0 (opcode 444, offset 0x0): argument 1: missing null terminator will be appended to string 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__strings__decompile_string_arg_without_null_fixed.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/strings.rs 3 | expression: stderr 4 | --- 5 | warning: : in sub0: instr 0 (opcode 555, offset 0x0): argument 1: missing null terminator will be appended to string 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__strings__decompile_string_reg.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/strings.rs 3 | expression: stderr 4 | --- 5 | error: : in script0: instr 0 (opcode 444, offset 0x0): argument 1: unexpected register bit on a string value 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__strings__encoding_error_in_arg.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/strings.rs 3 | expression: stderr 4 | --- 5 | error: string encoding error 6 | ┌─ :13:21 7 | │ 8 | 13 │ textSet(0, 0, "⏄"); 9 | │ ^^^ cannot be encoded using 'Shift_JIS' 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__strings__encoding_error_in_meta.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/strings.rs 3 | expression: stderr 4 | --- 5 | error: string encoding error 6 | ┌─ :6:17 7 | │ 8 | 6 │ stage_name: "⏄", 9 | │ ^^^ cannot be encoded using 'Shift_JIS' 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__strings__shift_jis_in_source_file.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/strings.rs 3 | expression: stderr 4 | --- 5 | error: invalid UTF-8 6 | ┌─ :6:18 7 | │ 8 | 6 │ stage_name: "����ɂ���", 9 | │ ^ not valid UTF-8 10 | │ 11 | = truth expects all input script files to be UTF-8 regardless of the output encoding 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__strings__std_string128_overflow.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/strings.rs 3 | expression: stderr 4 | --- 5 | error: string is too long 6 | ┌─ :6:17 7 | │ 8 | 6 │ stage_name: " 9 | │ ╭─────────────────^ 10 | 7 │ │ 0123456789abcdef 0123456789abcdef 0123456789abcdef 11 | 8 │ │ 0123456789abcdef 0123456789abcdef 0123456789abcdef 12 | 9 │ │ 0123456789abcdef 0123456789abcdef 0123456789abcdef 13 | · │ 14 | 12 │ │ 0123456789abcdef 0123456789abcdef 0123456789abcdef 15 | 13 │ │ ", 16 | │ ╰─^ 307 bytes (max allowed: 127) 17 | 18 | 19 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__time_label_compilation__non_const.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/time_label_compilation.rs 3 | expression: stderr 4 | --- 5 | error: const evaluation error in time label 6 | ┌─ :11:5 7 | │ 8 | 11 │ +I0: nop(); 9 | │ ^^^ non-const expression 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__time_label_formatting__after_neg.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/time_label_formatting.rs 3 | expression: decompiled 4 | --- 5 | script timeline0 { 6 | } 7 | 8 | 9 | void sub0(int IPAR, float FPAR) { 10 | -1: 11 | ins_0(); 12 | 0: 13 | ins_0(); 14 | -1: 15 | ins_0(); 16 | 0: 17 | +6: // 6 18 | ins_0(); 19 | } 20 | 21 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__time_label_formatting__compression.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/time_label_formatting.rs 3 | expression: decompiled 4 | --- 5 | script timeline0 { 6 | } 7 | 8 | 9 | void sub0(int IPAR, float FPAR) { 10 | ins_0(); 11 | ins_0(); 12 | +6: // 6 13 | ins_0(); 14 | ins_0(); 15 | -1: 16 | ins_0(); 17 | ins_0(); 18 | } 19 | 20 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__time_label_formatting__general_1.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/time_label_formatting.rs 3 | expression: decompiled 4 | --- 5 | script timeline0 { 6 | } 7 | 8 | 9 | void sub0(int IPAR, float FPAR) { 10 | ins_0(); 11 | +2: // 2 12 | ins_0(); 13 | +3: // 5 14 | ins_0(); 15 | } 16 | 17 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__time_label_formatting__general_2.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/time_label_formatting.rs 3 | expression: decompiled 4 | --- 5 | script timeline0 { 6 | } 7 | 8 | 9 | void sub0(int IPAR, float FPAR) { 10 | +5: // 5 11 | ins_0(); 12 | 3: 13 | ins_0(); 14 | 0: 15 | ins_0(); 16 | } 17 | 18 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__timeline_arg0__bad_arity_with_required_arg0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/timeline_arg0.rs 3 | expression: stderr 4 | --- 5 | error: wrong number of arguments to 'hasMsgArg0' 6 | ┌─ :7:5 7 | │ 8 | 7 │ hasMsgArg0(@arg0=10, 3, 3); 9 | │ ^^^^^^^^^^ expects 3 arguments, got 2 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__timeline_arg0__bad_type_for_explicit_arg0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/timeline_arg0.rs 3 | expression: stderr 4 | --- 5 | error: type error 6 | ┌─ :6:25 7 | │ 8 | 6 │ hasUnusedArg0(@arg0=5.5, 3, 3); 9 | │ ---- ^^^ a float 10 | │ │ 11 | │ expects an integer 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__timeline_arg0__reg_as_positional_arg0.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/timeline_arg0.rs 3 | expression: stderr 4 | --- 5 | error: argument must be a compile-time constant 6 | ┌─ :6:16 7 | │ 8 | 6 │ hasMsgArg0($REG[20], 3, 3); 9 | │ ^^^^^^^^ not constant 10 | │ 11 | = because the argument is a word-sized integer 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__timeline_arg0__signature_with_arg0_in_not_timeline.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/timeline_arg0.rs 3 | expression: stderr 4 | --- 5 | error: arg0 args are only valid in th06 and th07 timelines 6 | ┌─ :3:6 7 | │ 8 | 3 │ 1000 s(arg0; enum="MsgScript") 9 | │ ^^^^^^^^^^^^^^^^^^^^^^^^^ 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__timeline_arg0__signature_with_arg0_in_th08_timeline.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/timeline_arg0.rs 3 | expression: stderr 4 | --- 5 | error: arg0 args are only valid in th06 and th07 timelines 6 | ┌─ :3:6 7 | │ 8 | 3 │ 1000 s(arg0; enum="MsgScript") 9 | │ ^^^^^^^^^^^^^^^^^^^^^^^^^ 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__timeline_arg0__warn_arg0_collision.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/timeline_arg0.rs 3 | expression: stderr 4 | --- 5 | warning: explicit @arg0 overrides value supplied naturally 6 | ┌─ :6:26 7 | │ 8 | 6 │ hasMsgArg0(@arg0=10, 5, 3, 3); 9 | │ ^ this value will be ignored 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__timeline_arg0__wrong_lang.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/timeline_arg0.rs 3 | expression: stderr 4 | --- 5 | error: unknown ECL Timeline instruction or function 'eclOnly' 6 | ┌─ :3:5 7 | │ 8 | 3 │ eclOnly(0, 3, 3); 9 | │ ^^^^^^^ not found in this scope 10 | │ 11 | = there is a 'eclOnly' defined in ECL 12 | 13 | error: unknown ECL instruction or function 'timelineOnly' 14 | ┌─ :7:5 15 | │ 16 | 7 │ timelineOnly(0, 3, 3); 17 | │ ^^^^^^^^^^^^ not found in this scope 18 | │ 19 | = there is a 'timelineOnly' defined in ECL Timeline 20 | 21 | 22 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__timelines__duplicate.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/timelines.rs 3 | expression: stderr 4 | --- 5 | error: duplicate timeline for index 0 6 | ┌─ :3:8 7 | │ 8 | 2 │ script 0 foo { ins_10(100); } 9 | │ - previously defined here 10 | 3 │ script 0 bar { ins_10(200); } 11 | │ ^ redefined here 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__timelines__duplicate_implicit.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/timelines.rs 3 | expression: stderr 4 | --- 5 | warning: mixture of explicit and automatic timeline indices 6 | ┌─ :2:8 7 | │ 8 | 2 │ script 0 foo { ins_10(100); } 9 | │ ^ explicit index 10 | 3 │ script bar { ins_10(100); } 11 | │ --- implicitly has index 0 12 | 13 | error: duplicate timeline for index 0 14 | ┌─ :3:8 15 | │ 16 | 2 │ script 0 foo { ins_10(100); } 17 | │ - previously defined here 18 | 3 │ script bar { ins_10(100); } 19 | │ ^^^ redefined here 20 | 21 | 22 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__timelines__missing.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/timelines.rs 3 | expression: stderr 4 | --- 5 | error: missing timeline(s) for index 1, 2 6 | ┌─ :3:8 7 | │ 8 | 3 │ script 4 bar { } 9 | │ ^ defining this timeline requires all lesser indices 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__timelines__mixture_of_auto_and_explicit.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/timelines.rs 3 | expression: stderr 4 | --- 5 | warning: mixture of explicit and automatic timeline indices 6 | ┌─ :2:8 7 | │ 8 | 2 │ script 2 foo { ins_10(300); } 9 | │ ^ explicit index 10 | 3 │ script bar { ins_10(100); } 11 | │ --- implicitly has index 0 12 | 4 │ script baz { ins_10(200); } 13 | │ --- implicitly has index 1 14 | 15 | 16 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__timelines__negative.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/timelines.rs 3 | expression: stderr 4 | --- 5 | error: negative timeline indices are forbidden 6 | ┌─ :2:8 7 | │ 8 | 2 │ script -1 foo { } 9 | │ ^^ 10 | 11 | error: negative timeline indices are forbidden 12 | ┌─ :3:8 13 | │ 14 | 3 │ script -2 bar { } 15 | │ ^^ 16 | 17 | 18 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__timelines__too_many_6.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/timelines.rs 3 | expression: stderr 4 | --- 5 | error: while writing '':too many timelines! (max allowed in this game is 1) 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__timelines__too_many_7.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/timelines.rs 3 | expression: stderr 4 | --- 5 | error: while writing '':too many timelines! (max allowed in this game is 15) 6 | 7 | 8 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__type_check__bad_declaration.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/type_check.rs 3 | expression: stderr 4 | --- 5 | error: unexpected token `%` 6 | ┌─ :27:11 7 | │ 8 | 27 │ int %x; 9 | │ ^ unexpected token 10 | │ 11 | = 12 | Expected one of "(", ";", "anim", "case", "default", "ecli", "entry", "mapfile", "script" or IDENT 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__type_check__binop_two_strings.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/type_check.rs 3 | expression: stderr 4 | --- 5 | error: type error 6 | ┌─ :14:23 7 | │ 8 | 14 │ textSet(0, 0, "F1" - "2.0"); 9 | │ ^^^^ - requires a numeric type 10 | │ │ 11 | │ a string 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__type_check__const_short_circuit.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/type_check.rs 3 | expression: stderr 4 | --- 5 | error: type error 6 | ┌─ :28:24 7 | │ 8 | 28 │ F0 = 5 ? 1.0 : 0; // ternary left 9 | │ --- - ^ an integer 10 | │ │ │ 11 | │ │ same types required by this 12 | │ a float 13 | 14 | error: type error 15 | ┌─ :29:26 16 | │ 17 | 29 │ F0 = 0 ? "lol" : 1.0; // ternary right 18 | │ ----- - ^^^ a float 19 | │ │ │ 20 | │ │ same types required by this 21 | │ a string 22 | 23 | error: type error 24 | ┌─ :30:19 25 | │ 26 | 30 │ I0 = 1 && "lmao"; // and 27 | │ - -- ^^^^^^ a string 28 | │ │ │ 29 | │ │ same types required by this 30 | │ an integer 31 | 32 | error: type error 33 | ┌─ :31:14 34 | │ 35 | 31 │ I0 = 0.0 || 1; // or 36 | │ ^^^ -- expects an integer 37 | │ │ 38 | │ a float 39 | 40 | 41 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__type_check__diffswitch.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/type_check.rs 3 | expression: stderr 4 | --- 5 | error: type error 6 | ┌─ :10:20 7 | │ 8 | 10 │ int x = 3::4.5:; // arg 9 | │ ---^^^- 10 | │ │ │ 11 | │ │ a float 12 | │ same types required by this 13 | │ an integer 14 | 15 | error: type error 16 | ┌─ :11:19 17 | │ 18 | 11 │ float a = 3:4::4; // out 19 | │ ----- ^^^^^^ an integer 20 | │ │ 21 | │ expects a float 22 | 23 | error: type error 24 | ┌─ :12:17 25 | │ 26 | 12 │ int y = ins_0():::; // void expr 27 | │ ^^^^^^^--- 28 | │ │ 29 | │ expects a value 30 | │ void type 31 | 32 | error: type error 33 | ┌─ :13:32 34 | │ 35 | 13 │ int z = (3.0:4.0:3.0 + 1:5.0); // interior 36 | │ --- - ^ an integer 37 | │ │ │ 38 | │ │ same types required by this 39 | │ a float 40 | 41 | error: type error 42 | ┌─ :14:10 43 | │ 44 | 14 │ (ins_0():::); // void stmt 45 | │ -^^^^^^^---- 46 | │ ││ 47 | │ │void type 48 | │ expects a value 49 | 50 | 51 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__type_check__diffswitch__missing_first.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/type_check.rs 3 | expression: stderr 4 | --- 5 | error: unexpected token `:` 6 | ┌─ :10:17 7 | │ 8 | 10 │ int x = :4:4:6; 9 | │ ^ unexpected token 10 | │ 11 | = 12 | Expected one of "!", "$", "%", "(", "++", "-", "--", "REG", "_S", "_f", "anim", "case", "cos", "default", "ecli", "entry", "float", "int", "mapfile", "offsetof", "script", "sin", "sqrt", "timeof", "~", FLOAT, FLOAT_RAD, IDENT, INSTR, INT or STRING 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__type_check__ins_arg_binop_str__stackless.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/type_check.rs 3 | expression: stderr 4 | --- 5 | error: runtime temporary of non-numeric type 6 | ┌─ :11:31 7 | │ 8 | 11 │ spellcard_start(0, 0, I0 ? "abc" : "def"); 9 | │ ^^^^^^^^^^^^^^^^^^ temporary strings cannot be created 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__type_check__ins_arg_neg_str.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/type_check.rs 3 | expression: stderr 4 | --- 5 | error: type error 6 | ┌─ :14:24 7 | │ 8 | 14 │ textSet(0, 0, -"abc"); 9 | │ -^^^^^ a string 10 | │ │ 11 | │ requires a numeric type 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__type_check__ins_arg_var.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/type_check.rs 3 | expression: stderr 4 | --- 5 | error: type error 6 | ┌─ :28:18 7 | │ 8 | 28 │ pos(0.0, I0, 3.0); // var 9 | │ --- ^^ an integer 10 | │ │ 11 | │ expects a float for parameter 2 12 | 13 | error: type error 14 | ┌─ :29:18 15 | │ 16 | 29 │ pos(0.0, 5, 3.0); // literal 17 | │ --- ^ an integer 18 | │ │ 19 | │ expects a float for parameter 2 20 | 21 | error: type error 22 | ┌─ :30:18 23 | │ 24 | 30 │ pos(0.0, I0 + I2, 3.0); // complex 25 | │ --- ^^^^^^^ an integer 26 | │ │ 27 | │ expects a float for parameter 2 28 | 29 | 30 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__type_check__jump_time.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/type_check.rs 3 | expression: stderr 4 | --- 5 | error: unexpected token `2.4` 6 | ┌─ :28:34 7 | │ 8 | 28 │ if (2 == 2) goto label @ 2.4; 9 | │ ^^^ unexpected token 10 | │ 11 | = 12 | Expected one of "-" or INT 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__type_check__jumps.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/type_check.rs 3 | expression: stderr 4 | --- 5 | error: type error 6 | ┌─ :26:14 7 | │ 8 | 26 │ if (2 == 3.0) goto label; 9 | │ - -- ^^^ a float 10 | │ │ │ 11 | │ │ same types required by this 12 | │ an integer 13 | 14 | error: type error 15 | ┌─ :31:9 16 | │ 17 | 31 │ if (3.0) goto label; 18 | │ ^^^ a float 19 | │ 20 | = an integer is required 21 | 22 | error: type error 23 | ┌─ :37:14 24 | │ 25 | 37 │ if (2 && 3.0) goto label1; 26 | │ - -- ^^^ a float 27 | │ │ │ 28 | │ │ same types required by this 29 | │ an integer 30 | 31 | error: type error 32 | ┌─ :40:9 33 | │ 34 | 40 │ if (2.0 && 3.0) goto label2; 35 | │ ^^^ -- expects an integer 36 | │ │ 37 | │ a float 38 | 39 | error: type error 40 | ┌─ :45:11 41 | │ 42 | 45 │ if (--F0) goto label; 43 | │ --^^ a float 44 | │ │ 45 | │ expects an integer 46 | 47 | 48 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__type_check__non_void_expr_statement.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/type_check.rs 3 | expression: stderr 4 | --- 5 | error: type error 6 | ┌─ :28:9 7 | │ 8 | 28 │ 3.0; 9 | │ ^^^ a float 10 | │ 11 | = expression statements must be of void type 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__type_check__pseudo.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/type_check.rs 3 | expression: stderr 4 | --- 5 | error: type error 6 | ┌─ :28:19 7 | │ 8 | 28 │ pos(@blob=12); 9 | │ ---- ^^ an integer 10 | │ │ 11 | │ expects a string 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__type_check__return__missing_from_value.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/type_check.rs 3 | expression: stderr 4 | --- 5 | warning: value-returning function without a return 6 | ┌─ :25:1 7 | │ 8 | 25 │ inline int foo() { } 9 | │ ^^^^^^^^^^^^^^^^^^^^ has no return statements 10 | 11 | error: feature not supported by format 12 | ┌─ :25:1 13 | │ 14 | 25 │ inline int foo() { } 15 | │ ^^^^^^^^^^^^^^^^^^^^ not supported by ANM files 16 | 17 | 18 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__type_check__return__missing_from_void__stackless.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/type_check.rs 3 | expression: stderr 4 | --- 5 | error: feature not supported by format 6 | ┌─ :25:1 7 | │ 8 | 25 │ inline void foo() { } 9 | │ ^^^^^^^^^^^^^^^^^^^^^ not supported by ANM files 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__type_check__return__none_from_value.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/type_check.rs 3 | expression: stderr 4 | --- 5 | error: type error 6 | ┌─ :25:22 7 | │ 8 | 25 │ inline float foo() { return; } 9 | │ ----- ^^^^^^ void 10 | │ │ 11 | │ expects a float 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__type_check__return__none_from_void.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/type_check.rs 3 | expression: stderr 4 | --- 5 | error: feature not supported by format 6 | ┌─ :25:1 7 | │ 8 | 25 │ inline void foo() { return; } 9 | │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not supported by ANM files 10 | 11 | 12 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__type_check__return__value_from_value.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/type_check.rs 3 | expression: stderr 4 | --- 5 | error: type error 6 | ┌─ :25:29 7 | │ 8 | 25 │ inline float foo() { return 0; } 9 | │ ----- ^ an integer 10 | │ │ 11 | │ expects a float 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__type_check__return__value_from_void.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/type_check.rs 3 | expression: stderr 4 | --- 5 | error: type error 6 | ┌─ :25:28 7 | │ 8 | 25 │ inline void foo() { return 0; } 9 | │ ---- ^ an integer 10 | │ │ 11 | │ expects void 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__type_check__return__void_from_value.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/type_check.rs 3 | expression: stderr 4 | --- 5 | error: type error 6 | ┌─ :25:29 7 | │ 8 | 25 │ inline float foo() { return sprite(0); } 9 | │ ------ ^^^^^^^^^ void type 10 | │ │ 11 | │ expects a value 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__type_check__return__void_from_void.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/type_check.rs 3 | expression: stderr 4 | --- 5 | error: type error 6 | ┌─ :25:28 7 | │ 8 | 25 │ inline void foo() { return sprite(0); } 9 | │ ------ ^^^^^^^^^ void type 10 | │ │ 11 | │ expects a value 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__type_check__simple_expr_types.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/type_check.rs 3 | expression: stderr 4 | --- 5 | error: type error 6 | ┌─ :28:14 7 | │ 8 | 28 │ I0 = 4.0; 9 | │ -- - ^^^ a float 10 | │ │ │ 11 | │ │ same types required by this 12 | │ an integer 13 | 14 | error: type error 15 | ┌─ :29:14 16 | │ 17 | 29 │ I0 = F0; 18 | │ -- - ^^ a float 19 | │ │ │ 20 | │ │ same types required by this 21 | │ an integer 22 | 23 | error: type error 24 | ┌─ :30:14 25 | │ 26 | 30 │ I0 = %I1; 27 | │ -- - ^^^ a float 28 | │ │ │ 29 | │ │ same types required by this 30 | │ an integer 31 | 32 | 33 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__type_check__sprite_is_int.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/type_check.rs 3 | expression: stderr 4 | --- 5 | error: type error 6 | ┌─ :28:14 7 | │ 8 | 28 │ F0 = sprite0; 9 | │ -- - ^^^^^^^ an integer 10 | │ │ │ 11 | │ │ same types required by this 12 | │ a float 13 | 14 | 15 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__type_check__times.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/type_check.rs 3 | expression: stderr 4 | --- 5 | error: type error 6 | ┌─ :28:15 7 | │ 8 | 28 │ times(F0) {} // count 9 | │ ^^ a float 10 | │ 11 | = an integer is required 12 | 13 | error: type error 14 | ┌─ :29:20 15 | │ 16 | 29 │ times(F0 = 4) {} // clobber 17 | │ -- ^ an integer 18 | │ │ 19 | │ a float 20 | 21 | 22 | -------------------------------------------------------------------------------- /tests/compile-fail/integration__integration__type_check__untyped_vars.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/type_check.rs 3 | expression: stderr 4 | --- 5 | error: variable requires a type prefix 6 | ┌─ :10:13 7 | │ 8 | 10 │ var untyped_local = 2; 9 | │ ^^^^^^^^^^^^^ needs a '$' or '%' prefix 10 | │ 11 | = consider adding an explicit type to its declaration 12 | 13 | error: variable requires a type prefix 14 | ┌─ :11:14 15 | │ 16 | 11 │ I0 = RAND_RANGE; 17 | │ ^^^^^^^^^^ needs a '$' or '%' prefix 18 | 19 | error: variable requires a type prefix 20 | ┌─ :12:14 21 | │ 22 | 12 │ I1 = GVAR_WITH_NO_TYPE; 23 | │ ^^^^^^^^^^^^^^^^^ needs a '$' or '%' prefix 24 | │ 25 | = consider adding 42069 to !gvar_types in your mapfile 26 | 27 | 28 | -------------------------------------------------------------------------------- /tests/integration/bits-2-bits/th06-general.std: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/bits-2-bits/th06-general.std -------------------------------------------------------------------------------- /tests/integration/bits-2-bits/th06-multiple-scripts.msg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/bits-2-bits/th06-multiple-scripts.msg -------------------------------------------------------------------------------- /tests/integration/bits-2-bits/th06-z-string.msg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/bits-2-bits/th06-z-string.msg -------------------------------------------------------------------------------- /tests/integration/bits-2-bits/th08-empty-script.std: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/bits-2-bits/th08-empty-script.std -------------------------------------------------------------------------------- /tests/integration/bits-2-bits/th08-instance-order.std: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/bits-2-bits/th08-instance-order.std -------------------------------------------------------------------------------- /tests/integration/bits-2-bits/th08-m-string.msg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/bits-2-bits/th08-m-string.msg -------------------------------------------------------------------------------- /tests/integration/bits-2-bits/th08-nonzero-padding.std: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/bits-2-bits/th08-nonzero-padding.std -------------------------------------------------------------------------------- /tests/integration/bits-2-bits/th08-rects.std: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/bits-2-bits/th08-rects.std -------------------------------------------------------------------------------- /tests/integration/bits-2-bits/th08-strip.std: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/bits-2-bits/th08-strip.std -------------------------------------------------------------------------------- /tests/integration/bits-2-bits/th09-default-mismatched-flags.msg: -------------------------------------------------------------------------------- 1 |    -------------------------------------------------------------------------------- /tests/integration/bits-2-bits/th09-default-zero-with-flags.msg: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /tests/integration/bits-2-bits/th09-default-zero.msg: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /tests/integration/bits-2-bits/th09-m-string.msg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/bits-2-bits/th09-m-string.msg -------------------------------------------------------------------------------- /tests/integration/bits-2-bits/th09-no-default.msg: -------------------------------------------------------------------------------- 1 |  $ -------------------------------------------------------------------------------- /tests/integration/bits-2-bits/th11-furibug-not-applicable.msg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/bits-2-bits/th11-furibug-not-applicable.msg -------------------------------------------------------------------------------- /tests/integration/bits-2-bits/th12-anchor-ss-signature.anm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/bits-2-bits/th12-anchor-ss-signature.anm -------------------------------------------------------------------------------- /tests/integration/bits-2-bits/th12-furibug.msg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/bits-2-bits/th12-furibug.msg -------------------------------------------------------------------------------- /tests/integration/bits-2-bits/th12-general.std: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/bits-2-bits/th12-general.std -------------------------------------------------------------------------------- /tests/integration/bits-2-bits/th12-registers.anm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/bits-2-bits/th12-registers.anm -------------------------------------------------------------------------------- /tests/integration/bits-2-bits/th12-sprite-duplicates.anm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/bits-2-bits/th12-sprite-duplicates.anm -------------------------------------------------------------------------------- /tests/integration/bits-2-bits/th12-sprite-non-sequential.anm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/bits-2-bits/th12-sprite-non-sequential.anm -------------------------------------------------------------------------------- /tests/integration/bits-2-bits/th12-sprite-script-args.anm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/bits-2-bits/th12-sprite-script-args.anm -------------------------------------------------------------------------------- /tests/integration/bits-2-bits/th12-sprite-unset.anm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/bits-2-bits/th12-sprite-unset.anm -------------------------------------------------------------------------------- /tests/integration/bits-2-bits/th12-weird-color-format.anm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/bits-2-bits/th12-weird-color-format.anm -------------------------------------------------------------------------------- /tests/integration/bits-2-bits/th17-furibug-ex-regression.msg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/bits-2-bits/th17-furibug-ex-regression.msg -------------------------------------------------------------------------------- /tests/integration/count_jmps.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused)] 2 | use crate::integration_impl::{expected, formats::*, Format}; 3 | 4 | const FORMAT_WITH_GT_JMP: Format = ECL_08; 5 | const FORMAT_WITH_NE_JMP: Format = ANM_12; 6 | 7 | source_test!( 8 | FORMAT_WITH_NE_JMP, ne_jmp_can_roundtrip, 9 | main_body: r#" 10 | label: 11 | if (--I2) goto label; 12 | "#, 13 | check_decompiled: |decompiled| { assert!(decompiled.contains("(--$REG[10002])")); }, 14 | ); 15 | 16 | source_test!( 17 | FORMAT_WITH_GT_JMP, gt_jmp_can_roundtrip, 18 | main_body: r#" 19 | label: 20 | if (--I2 > 0) goto label; 21 | "#, 22 | check_decompiled: |decompiled| { assert!(decompiled.contains("(--$REG[10002] > 0)")); }, 23 | ); 24 | 25 | source_test!( 26 | FORMAT_WITH_GT_JMP, ne_jmp_can_suggest_gt, 27 | main_body: r#" 28 | label: 29 | if (--I2) goto label; //~ ERROR (--I2 > 0) 30 | "#, 31 | ); 32 | 33 | source_test!( 34 | FORMAT_WITH_NE_JMP, gt_jmp_can_suggest_ne, 35 | main_body: r#" 36 | label: 37 | if (--I2 > 0) goto label; //~ ERROR (--I2) 38 | "#, 39 | ); 40 | 41 | source_test!( 42 | FORMAT_WITH_NE_JMP, ne_format_can_compile_times, 43 | main_body: r#" 44 | times(I2=5) { nop(); } 45 | "#, 46 | check_compiled: |_, _| { /* just compile */ }, 47 | ); 48 | 49 | source_test!( 50 | FORMAT_WITH_GT_JMP, gt_format_can_compile_times, 51 | main_body: r#" 52 | times(I2=5) { nop(); } 53 | "#, 54 | check_compiled: |_, _| { /* just compile */ }, 55 | ); 56 | -------------------------------------------------------------------------------- /tests/integration/interrupts.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused)] 2 | use crate::integration_impl::{expected, formats::*}; 3 | 4 | source_test!( 5 | STD_08, new_lines, 6 | main_body: r#" 7 | interrupt[1]: 8 | posKeyframe(0.0, 0.0, 0.0); 9 | interrupt[2]: 10 | interrupt[3]: 11 | posKeyframe(0.0, 0.0, 0.0); 12 | "#, 13 | check_decompiled: |decompiled| { 14 | // test for blank line before interrupt[2] but NOT before interrupt[3] 15 | assert!(decompiled.contains("\n\ninterrupt[2]:\ninterrupt[3]:\n"), "{:?}", decompiled); 16 | }, 17 | ); 18 | 19 | source_test!( 20 | #[ignore = "unignore this once 'imm' is implemented"] 21 | ANM_12, decompile_register, 22 | main_body: r#" 23 | ins_64(45); 24 | ins_64($REG[10000]); 25 | "#, 26 | check_decompiled: |decompiled| { 27 | // the second one should have fallen back to raw syntax 28 | assert!(decompiled.contains("($REG[10000])")); 29 | // specificity (prove that we have the right opcode) 30 | assert!(decompiled.contains("interrupt[45]")); 31 | }, 32 | ); 33 | 34 | source_test!( 35 | ANM_12, sugar_const, 36 | items: r#" 37 | const int MY_INTERRUPT = 5; 38 | "#, 39 | main_body: r#" 40 | interrupt[MY_INTERRUPT]: 41 | "#, 42 | check_compiled: |output, format| { 43 | let anm = output.read_anm(format); 44 | assert_eq!(anm.entries[0].scripts[0].instrs[0].args_blob, blobify![5]); 45 | }, 46 | ); 47 | 48 | source_test!( 49 | ANM_12, sugar_register, 50 | main_body: r#" 51 | interrupt[45]: 52 | interrupt[I0]: //~ ERROR const 53 | "#, 54 | ); 55 | 56 | source_test!( 57 | ANM_12, decompile_enum, 58 | mapfile: r#"!anmmap 59 | !ins_signatures 60 | 64 S(enum="AnmInterrupt") 61 | 62 | !enum(name="AnmInterrupt") 63 | 13 MyInterrupt 64 | "#, 65 | main_body: r#" 66 | interrupt[13]: 67 | "#, 68 | check_decompiled: |decompiled| { 69 | assert!(decompiled.contains("interrupt[MyInterrupt]:")) 70 | }, 71 | ); 72 | -------------------------------------------------------------------------------- /tests/integration/resources/dir-with-bad-images/subdir/hai-10x18+105+9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/resources/dir-with-bad-images/subdir/hai-10x18+105+9.png -------------------------------------------------------------------------------- /tests/integration/resources/dir-with-bad-images/subdir/hi-32x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/resources/dir-with-bad-images/subdir/hi-32x16.png -------------------------------------------------------------------------------- /tests/integration/resources/dir-with-images/subdir/hai-10x18+105+9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/resources/dir-with-images/subdir/hai-10x18+105+9.png -------------------------------------------------------------------------------- /tests/integration/resources/dir-with-images/subdir/hai-10x18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/resources/dir-with-images/subdir/hai-10x18.png -------------------------------------------------------------------------------- /tests/integration/resources/dir-with-images/subdir/hi-32x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/resources/dir-with-images/subdir/hi-32x16.png -------------------------------------------------------------------------------- /tests/integration/resources/dir-with-images/subdir/hi-7x20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/resources/dir-with-images/subdir/hi-7x20.png -------------------------------------------------------------------------------- /tests/integration/resources/dir-with-images/subdir/modified-size.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/resources/dir-with-images/subdir/modified-size.png -------------------------------------------------------------------------------- /tests/integration/resources/dir-with-modified-images/subdir/hai-10x18+105+9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/resources/dir-with-modified-images/subdir/hai-10x18+105+9.png -------------------------------------------------------------------------------- /tests/integration/resources/dir-with-modified-images/subdir/hai-10x18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/resources/dir-with-modified-images/subdir/hai-10x18.png -------------------------------------------------------------------------------- /tests/integration/resources/dir-with-modified-images/subdir/modified-size.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/resources/dir-with-modified-images/subdir/modified-size.png -------------------------------------------------------------------------------- /tests/integration/resources/dir-with-nothing-really/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/resources/dir-with-nothing-really/.gitkeep -------------------------------------------------------------------------------- /tests/integration/resources/dir-with-other-images/lmao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/resources/dir-with-other-images/lmao.png -------------------------------------------------------------------------------- /tests/integration/resources/dir-with-other-images/teeny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/resources/dir-with-other-images/teeny.png -------------------------------------------------------------------------------- /tests/integration/resources/multiple-mapfiles-1.anmm: -------------------------------------------------------------------------------- 1 | !anmmap 2 | # Test file for multiple -m arguments 3 | !ins_signatures 4 | 2000 SS 5 | !ins_names 6 | 2000 aaa 7 | -------------------------------------------------------------------------------- /tests/integration/resources/multiple-mapfiles-2.anmm: -------------------------------------------------------------------------------- 1 | !anmmap 2 | # Test file for multiple -m arguments 3 | !ins_signatures 4 | 2001 SS 5 | !ins_names 6 | 2001 bbb 7 | -------------------------------------------------------------------------------- /tests/integration/resources/th12-embedded-bad-image-source.anm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/resources/th12-embedded-bad-image-source.anm -------------------------------------------------------------------------------- /tests/integration/resources/th12-embedded-bad-image-source.anm.spec: -------------------------------------------------------------------------------- 1 | // NOTE: This file shows what was compiled to produce `th12-embedded-bad-image-source.anm`. (minus the image) 2 | // It is mostly here for explanatory purposes. 3 | // Since it is not tested, it may fall out of date with the latest compiler syntax. 4 | 5 | #pragma image_source "./tests/integration/resources/dir-with-bad-images" 6 | #pragma mapfile "map/any.anmm" 7 | 8 | // a fairly mundane image (resized in this "bad" version) 9 | entry { 10 | path: "subdir/hi-32x16.png", 11 | img_format: FORMAT_ARGB_8888, 12 | img_height: 12, // differs from the one in th12-embedded-image-source.anm 13 | sprites: {sprite1: {id: 0, x: 0.0, y: 0.0, w: 10.0, h: 18.0}}, 14 | } 15 | 16 | 17 | // an image with an offset (missing in this "bad" version) 18 | entry { 19 | path: "subdir/hai-10x18+105+9.png", 20 | img_format: FORMAT_ARGB_8888, 21 | offset_x: 0, // differs from the one in th12-embedded-image-source.anm 22 | offset_y: 0, // differs from the one in th12-embedded-image-source.anm 23 | sprites: {sprite1: {id: 0, x: 0.0, y: 0.0, w: 10.0, h: 18.0}}, 24 | } 25 | -------------------------------------------------------------------------------- /tests/integration/resources/th12-embedded-image-source.anm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/resources/th12-embedded-image-source.anm -------------------------------------------------------------------------------- /tests/integration/resources/th12-embedded-image-source.anm.spec: -------------------------------------------------------------------------------- 1 | // NOTE: This file shows what was compiled to produce `th12-embedded-image-source.anm`. (minus the image) 2 | // It is mostly here for explanatory purposes. 3 | // Since it is not tested, it may fall out of date with the latest compiler syntax. 4 | 5 | #pragma image_source "./tests/integration/resources/dir-with-images" 6 | #pragma image_source "./tests/integration/resources/dir-with-other-images" 7 | #pragma mapfile "map/any.anmm" 8 | 9 | entry { 10 | path: "lmao.png", 11 | has_data: true, 12 | img_format: FORMAT_RGB_565, 13 | sprites: {sprite0: {id: 0, x: 0.0, y: 0.0, w: 40.0, h: 60.0}}, 14 | } 15 | 16 | 17 | script -45 script0 { 18 | ins_1(); 19 | } 20 | 21 | 22 | // a fairly mundane image 23 | entry { 24 | path: "subdir/hi-32x16.png", 25 | img_format: FORMAT_ARGB_8888, 26 | sprites: {sprite1: {id: 0, x: 0.0, y: 0.0, w: 10.0, h: 18.0}}, 27 | } 28 | 29 | 30 | // an image with a marker suitable for testing transcoding 31 | entry { 32 | path: "subdir/hai-10x18.png", 33 | img_format: FORMAT_ARGB_8888, 34 | sprites: {sprite1: {id: 0, x: 0.0, y: 0.0, w: 10.0, h: 18.0}}, 35 | } 36 | 37 | 38 | // an image with an offset 39 | entry { 40 | path: "subdir/hai-10x18+105+9.png", 41 | img_format: FORMAT_ARGB_8888, 42 | offset_x: 105, 43 | offset_y: 9, 44 | sprites: {sprite1: {id: 0, x: 0.0, y: 0.0, w: 10.0, h: 18.0}}, 45 | } 46 | 47 | 48 | // an image that differs between two image sources. 49 | entry { 50 | path: "subdir/modified-size.png", 51 | has_data: true, 52 | img_format: FORMAT_ARGB_8888, 53 | sprites: {sprite1: {id: 0, x: 0.0, y: 0.0, w: 2.0, h: 2.0}}, 54 | } 55 | -------------------------------------------------------------------------------- /tests/integration/resources/th12-embedded-weird-format-source.anm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/resources/th12-embedded-weird-format-source.anm -------------------------------------------------------------------------------- /tests/integration/resources/th12-embedded-weird-format-source.anm.spec: -------------------------------------------------------------------------------- 1 | // NOTE: This file shows what was compiled to produce `th12-embedded-weird-format-source.anm`. (minus the image) 2 | // It is mostly here for explanatory purposes. 3 | // Since it is not tested, it may fall out of date with the latest compiler syntax. 4 | 5 | #pragma mapfile "map/any.anmm" 6 | 7 | entry { 8 | path: "teeny.png", 9 | has_data: true, 10 | img_width: 27, 11 | img_height: 25, 12 | // this was compiled with img_format: 7 then modified to 8 in a hex editor 13 | img_format: 8, 14 | rt_width: 128, 15 | rt_height: 128, 16 | offset_x: 0, 17 | offset_y: 0, 18 | colorkey: 0, 19 | memory_priority: 0, 20 | low_res_scale: false, 21 | sprites: {sprite0: {id: 0, x: 0.0, y: 0.0, w: 40.0, h: 60.0}}, 22 | } 23 | 24 | script script0 {} 25 | -------------------------------------------------------------------------------- /tests/integration/resources/th12-multiple-match-source.anm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/resources/th12-multiple-match-source.anm -------------------------------------------------------------------------------- /tests/integration/resources/th12-multiple-match-source.anm.spec: -------------------------------------------------------------------------------- 1 | // NOTE: This file shows what was compiled to produce `th12-multiple-match-source.anm`. 2 | // It is mostly here for explanatory purposes. 3 | // Since it is not tested, it may fall out of date with the latest compiler syntax. 4 | 5 | entry { 6 | path: "subdir/file1.png", 7 | has_data: false, 8 | rt_width: 1024, 9 | rt_height: 1024, 10 | offset_x: 0, 11 | offset_y: 0, 12 | img_format: 3, 13 | colorkey: 0, 14 | memory_priority: 0, 15 | low_res_scale: false, 16 | sprites: {sprite0: {id: 0, x: 1.0, y: 1.0, w: 111.0, h: 111.0}}, 17 | } 18 | 19 | 20 | script script0 { 21 | ins_1(); 22 | } 23 | 24 | 25 | entry { 26 | path: "subdir/file2.png", 27 | has_data: false, 28 | rt_width: 2048, 29 | rt_height: 2048, 30 | offset_x: 0, 31 | offset_y: 0, 32 | img_format: 3, 33 | colorkey: 0, 34 | memory_priority: 0, 35 | low_res_scale: false, 36 | sprites: {sprite1: {id: 1, x: 2.0, y: 2.0, w: 222.0, h: 220.0}}, 37 | } 38 | 39 | 40 | script script1 { 41 | ins_2(); 42 | } 43 | 44 | -------------------------------------------------------------------------------- /tests/integration/resources/th12-multiple-same-source.anm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ExpHP/truth/0f32abf274fb7949b32be9c43c88766907a696e2/tests/integration/resources/th12-multiple-same-source.anm -------------------------------------------------------------------------------- /tests/integration/resources/th12-multiple-same-source.anm.spec: -------------------------------------------------------------------------------- 1 | // NOTE: This file shows what was compiled to produce `th12-multiple-same-source.anm`. 2 | // It is mostly here for explanatory purposes. 3 | // Since it is not tested, it may fall out of date with the latest compiler syntax. 4 | 5 | entry { 6 | path: "@R", 7 | has_data: false, 8 | rt_width: 1024, 9 | rt_height: 1024, 10 | rt_format: 3, 11 | offset_x: 0, 12 | offset_y: 0, 13 | colorkey: 0, 14 | memory_priority: 0, 15 | low_res_scale: false, 16 | sprites: {sprite0: {id: 0, x: 0.0, y: 0.0, w: 50.0, h: 50.0}}, 17 | } 18 | 19 | 20 | script script0 { 21 | ins_0(); 22 | } 23 | 24 | 25 | entry { 26 | path: "@R", 27 | has_data: false, 28 | rt_width: 2048, 29 | rt_height: 2048, 30 | rt_format: 3, 31 | offset_x: 0, 32 | offset_y: 0, 33 | colorkey: 0, 34 | memory_priority: 0, 35 | low_res_scale: false, 36 | sprites: {sprite1: {id: 1, x: 0.0, y: 0.0, w: 50.0, h: 50.0}}, 37 | } 38 | 39 | 40 | script script1 { 41 | ins_0(); 42 | } 43 | 44 | -------------------------------------------------------------------------------- /tests/integration/snapshots/integration__integration__bits_2_bits__anm12_anchor_ss_signature.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/bits_2_bits.rs 3 | expression: s 4 | --- 5 | #pragma mapfile "map/any.anmm" 6 | 7 | entry { 8 | path: "subdir/file.png", 9 | has_data: false, 10 | rt_width: 512, 11 | rt_height: 512, 12 | rt_format: FORMAT_RGB_565, 13 | memory_priority: 0, 14 | sprites: {sprite0: {x: 0.0, y: 0.0, w: 512.0, h: 480.0}}, 15 | } 16 | 17 | 18 | script 0 script0 { 19 | anchor(1, 2); 20 | pos(0.0, 0.0, 0.0); 21 | } 22 | 23 | -------------------------------------------------------------------------------- /tests/integration/snapshots/integration__integration__bits_2_bits__anm12_registers.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/bits_2_bits.rs 3 | expression: s 4 | --- 5 | #pragma mapfile "map/any.anmm" 6 | 7 | entry { 8 | path: "subdir/file.png", 9 | has_data: false, 10 | rt_width: 512, 11 | rt_height: 512, 12 | rt_format: FORMAT_RGB_565, 13 | memory_priority: 0, 14 | sprites: {sprite0: {x: 0.0, y: 0.0, w: 512.0, h: 480.0}}, 15 | } 16 | 17 | 18 | script 0 script0 { 19 | I0 = 3; 20 | I1 = I0; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /tests/integration/snapshots/integration__integration__bits_2_bits__anm12_sprite_duplicates.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/bits_2_bits.rs 3 | expression: s 4 | --- 5 | #pragma mapfile "map/any.anmm" 6 | 7 | entry { 8 | path: "subdir/file.png", 9 | has_data: false, 10 | rt_width: 512, 11 | rt_height: 512, 12 | rt_format: FORMAT_RGB_565, 13 | memory_priority: 0, 14 | sprites: { 15 | sprite0: {x: 0.0, y: 0.0, w: 512.0, h: 480.0}, 16 | sprite1: {x: 0.0, y: 0.0, w: 512.0, h: 480.0}, 17 | sprite2: {x: 0.0, y: 0.0, w: 512.0, h: 480.0}, 18 | }, 19 | } 20 | 21 | 22 | entry { 23 | path: "subdir/file-2.png", 24 | has_data: false, 25 | rt_width: 512, 26 | rt_height: 512, 27 | rt_format: FORMAT_RGB_565, 28 | memory_priority: 0, 29 | sprites: { 30 | sprite0: {x: 0.0, y: 0.0, w: 512.0, h: 480.0, id: 0}, 31 | sprite1: {x: 0.0, y: 0.0, w: 512.0, h: 480.0}, 32 | sprite2: {x: 0.0, y: 0.0, w: 512.0, h: 480.0}, 33 | }, 34 | } 35 | 36 | 37 | script 0 script0 { 38 | } 39 | 40 | -------------------------------------------------------------------------------- /tests/integration/snapshots/integration__integration__bits_2_bits__anm12_sprite_non_sequential.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/bits_2_bits.rs 3 | expression: s 4 | --- 5 | #pragma mapfile "map/any.anmm" 6 | 7 | entry { 8 | path: "subdir/file.png", 9 | has_data: false, 10 | rt_width: 512, 11 | rt_height: 512, 12 | rt_format: FORMAT_RGB_565, 13 | memory_priority: 0, 14 | sprites: { 15 | sprite0: {x: 0.0, y: 0.0, w: 512.0, h: 480.0}, 16 | sprite1: {x: 0.0, y: 0.0, w: 512.0, h: 480.0}, 17 | sprite46: {x: 0.0, y: 0.0, w: 512.0, h: 480.0, id: 46}, 18 | sprite47: {x: 0.0, y: 0.0, w: 512.0, h: 480.0}, 19 | }, 20 | } 21 | 22 | 23 | script 0 script0 { 24 | sprite(sprite46); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /tests/integration/snapshots/integration__integration__bits_2_bits__anm12_sprite_script_args.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/bits_2_bits.rs 3 | expression: s 4 | --- 5 | #pragma mapfile "map/any.anmm" 6 | 7 | entry { 8 | path: "subdir/file.png", 9 | has_data: false, 10 | rt_width: 512, 11 | rt_height: 512, 12 | rt_format: FORMAT_RGB_565, 13 | memory_priority: 0, 14 | sprites: {sprite0: {x: 0.0, y: 0.0, w: 512.0, h: 480.0}}, 15 | } 16 | 17 | 18 | script 0 script0 { 19 | scriptNew(script1); 20 | } 21 | 22 | 23 | script 1 script1 { 24 | sprite(sprite0); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /tests/integration/snapshots/integration__integration__bits_2_bits__anm12_sprite_unset.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/bits_2_bits.rs 3 | expression: s 4 | --- 5 | #pragma mapfile "map/any.anmm" 6 | 7 | entry { 8 | path: "subdir/file.png", 9 | has_data: false, 10 | rt_width: 512, 11 | rt_height: 512, 12 | rt_format: FORMAT_RGB_565, 13 | memory_priority: 0, 14 | sprites: {sprite0: {x: 0.0, y: 0.0, w: 512.0, h: 480.0}}, 15 | } 16 | 17 | 18 | script 0 script0 { 19 | sprite(-1); 20 | } 21 | 22 | -------------------------------------------------------------------------------- /tests/integration/snapshots/integration__integration__bits_2_bits__anm12_unknown_signature.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/bits_2_bits.rs 3 | expression: s 4 | --- 5 | #pragma mapfile "tests/integration/bits-2-bits/th12-unknown-signature.anmm" 6 | 7 | entry { 8 | path: "subdir/file1.png", 9 | has_data: false, 10 | rt_width: 1000, 11 | rt_height: 1000, 12 | rt_format: FORMAT_RGB_565, 13 | memory_priority: 0, 14 | sprites: {sprite0: {x: 1.0, y: 1.0, w: 111.0, h: 111.0}}, 15 | } 16 | 17 | 18 | script 0 script0 { 19 | hasNameButNoSignature(@mask=0b101, @blob="00501c46 00000040 00541c46"); 20 | ins_1011(@mask=0b101, @blob="00501c46 00000040 00541c46"); 21 | } 22 | 23 | -------------------------------------------------------------------------------- /tests/integration/snapshots/integration__integration__bits_2_bits__anm12_weird_color_format.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/bits_2_bits.rs 3 | expression: s 4 | --- 5 | #pragma mapfile "map/any.anmm" 6 | 7 | entry { 8 | path: "teeny.png", 9 | img_width: 27, 10 | img_height: 25, 11 | img_format: 8, 12 | rt_width: 128, 13 | rt_height: 128, 14 | memory_priority: 0, 15 | sprites: {sprite0: {x: 0.0, y: 0.0, w: 40.0, h: 60.0}}, 16 | } 17 | 18 | 19 | script 0 script0 { 20 | } 21 | 22 | -------------------------------------------------------------------------------- /tests/integration/snapshots/integration__integration__bits_2_bits__msg06_multiple_scripts.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/bits_2_bits.rs 3 | expression: s 4 | --- 5 | #pragma mapfile "map/any.msgm" 6 | 7 | meta { 8 | table: { 9 | 0: {script: "script0"}, 10 | 1: {script: "script1"}, 11 | 10: {script: "script10"}, 12 | 11: {script: "script11"}, 13 | default: {script: "script0"}, 14 | }, 15 | } 16 | 17 | 18 | script script0 { 19 | show(0, 0); 20 | face(0, 0); 21 | anmInterrupt(0, 1); 22 | +60: // 60 23 | textPause(300); 24 | } 25 | 26 | 27 | script script1 { 28 | show(0, 0); 29 | stop(); 30 | } 31 | 32 | 33 | script script10 { 34 | show(0, 0); 35 | face(0, 0); 36 | anmInterrupt(0, 1); 37 | } 38 | 39 | 40 | script script11 { 41 | show(0, 0); 42 | anmInterrupt(0, 1); 43 | } 44 | 45 | -------------------------------------------------------------------------------- /tests/integration/snapshots/integration__integration__bits_2_bits__msg06_z_string.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/bits_2_bits.rs 3 | expression: s 4 | --- 5 | #pragma mapfile "map/any.msgm" 6 | 7 | meta {table: {0: {script: "script0"}}} 8 | 9 | 10 | script script0 { 11 | anmInterrupt(0, 1); 12 | +60: // 60 13 | textSet(0, 0, "でも..."); 14 | anmInterrupt(0, 0); 15 | textSet(0, 0, "also here's an ascii string so it's not all mojibake"); 16 | textPause(300); 17 | } 18 | 19 | -------------------------------------------------------------------------------- /tests/integration/snapshots/integration__integration__bits_2_bits__msg08_m_string.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/bits_2_bits.rs 3 | expression: s 4 | --- 5 | #pragma mapfile "map/any.msgm" 6 | 7 | meta {table: {0: {script: "script0"}}} 8 | 9 | 10 | script script0 { 11 | anmInterrupt(0, 1); 12 | +60: // 60 13 | textSet(0, 0, "でも..."); 14 | anmInterrupt(0, 0); 15 | textSet(0, 0, "also here's an ascii string so it's not all mojibake"); 16 | textPause(300); 17 | } 18 | 19 | -------------------------------------------------------------------------------- /tests/integration/snapshots/integration__integration__bits_2_bits__msg09_default_mismatched_flags.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/bits_2_bits.rs 3 | expression: s 4 | --- 5 | #pragma mapfile "map/any.msgm" 6 | 7 | meta { 8 | table: { 9 | 0: {script: "script0", flags: 32}, 10 | 2: {script: "script0", flags: 256}, 11 | default: {script: "script0", flags: 32}, 12 | }, 13 | } 14 | 15 | 16 | script script0 { 17 | } 18 | 19 | -------------------------------------------------------------------------------- /tests/integration/snapshots/integration__integration__bits_2_bits__msg09_default_zero.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/bits_2_bits.rs 3 | expression: s 4 | --- 5 | #pragma mapfile "map/any.msgm" 6 | 7 | meta {table_len: 3, table: {1: {script: "script0", flags: 256}}} 8 | 9 | 10 | script script0 { 11 | } 12 | 13 | -------------------------------------------------------------------------------- /tests/integration/snapshots/integration__integration__bits_2_bits__msg09_default_zero_with_flags.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/bits_2_bits.rs 3 | expression: s 4 | --- 5 | #pragma mapfile "map/any.msgm" 6 | 7 | meta { 8 | table_len: 3, 9 | table: { 10 | 1: {script: "script0", flags: 256}, 11 | default: {script: 0, flags: 256}, 12 | }, 13 | } 14 | 15 | 16 | script script0 { 17 | } 18 | 19 | -------------------------------------------------------------------------------- /tests/integration/snapshots/integration__integration__bits_2_bits__msg09_m_string.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/bits_2_bits.rs 3 | expression: s 4 | --- 5 | #pragma mapfile "map/any.msgm" 6 | 7 | meta {table: {0: {script: "script0"}}} 8 | 9 | 10 | script script0 { 11 | anmInterrupt(0, 1); 12 | +60: // 60 13 | textSet(0, 0, "でも..."); 14 | anmInterrupt(0, 0); 15 | textSet(0, 0, "also here's an ascii string so it's not all mojibake"); 16 | textPause(300); 17 | } 18 | 19 | -------------------------------------------------------------------------------- /tests/integration/snapshots/integration__integration__bits_2_bits__msg09_no_default.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/bits_2_bits.rs 3 | expression: s 4 | --- 5 | #pragma mapfile "map/any.msgm" 6 | 7 | meta { 8 | table: { 9 | 0: {script: "script0", flags: 32}, 10 | 1: {script: "script1", flags: 32}, 11 | 2: {script: "script2", flags: 256}, 12 | }, 13 | } 14 | 15 | 16 | script script0 { 17 | } 18 | 19 | 20 | script script1 { 21 | } 22 | 23 | 24 | script script2 { 25 | } 26 | 27 | -------------------------------------------------------------------------------- /tests/integration/snapshots/integration__integration__bits_2_bits__msg11_furibug_not_applicable.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/bits_2_bits.rs 3 | expression: s 4 | --- 5 | #pragma mapfile "map/any.msgm" 6 | 7 | meta {table: {0: {script: "script0", flags: 256}}} 8 | 9 | 10 | script script0 { 11 | textAdd("|4,9,abcdefghijklmn"); 12 | textAdd("ABCD_EFGHIJK"); 13 | textAdd("ABCD_EFGHIJK"); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /tests/integration/snapshots/integration__integration__bits_2_bits__msg12_furibug.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/bits_2_bits.rs 3 | expression: s 4 | --- 5 | #pragma mapfile "map/any.msgm" 6 | 7 | meta {table: {0: {script: "script0", flags: 256}}} 8 | 9 | 10 | script script0 { 11 | textAdd("|4,9,abcdefghijklmn"); 12 | textAdd("ABCD_EFGHIJK"); 13 | textAdd("ABCD_EFGHIJK"); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /tests/integration/snapshots/integration__integration__bits_2_bits__msg17_furibug_ex_regression.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/bits_2_bits.rs 3 | expression: s 4 | --- 5 | #pragma mapfile "map/any.msgm" 6 | 7 | meta {table: {0: {script: "script0", flags: 256}}} 8 | 9 | 10 | script script0 { 11 | textAdd("|4,9,abcdefghijklmn"); 12 | textAdd("ABCD_EFGHIJKLMN"); 13 | textAdd("ABCD_EFGHIJKLMN"); 14 | } 15 | 16 | -------------------------------------------------------------------------------- /tests/integration/snapshots/integration__integration__bits_2_bits__std08_empty_script.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/bits_2_bits.rs 3 | expression: s 4 | --- 5 | #pragma mapfile "map/any.stdm" 6 | 7 | meta { 8 | unknown: 0, 9 | stage_name: "dm", 10 | bgm: [ 11 | {path: "bgm/th08_08.mid", name: "dm"}, 12 | {path: "bgm/th08_09.mid", name: "dm"}, 13 | {path: " ", name: " "}, 14 | {path: " ", name: " "}, 15 | ], 16 | objects: {}, 17 | instances: [], 18 | } 19 | 20 | 21 | script main { 22 | } 23 | 24 | -------------------------------------------------------------------------------- /tests/integration/snapshots/integration__integration__bits_2_bits__std08_instance_order.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/bits_2_bits.rs 3 | expression: s 4 | --- 5 | #pragma mapfile "map/any.stdm" 6 | 7 | meta { 8 | unknown: 0, 9 | stage_name: "dm", 10 | bgm: [ 11 | {path: "bgm/th08_08.mid", name: "dm"}, 12 | {path: "bgm/th08_09.mid", name: "dm"}, 13 | {path: " ", name: " "}, 14 | {path: " ", name: " "}, 15 | ], 16 | objects: { 17 | object0: { 18 | layer: 0, 19 | pos: [-320.0, -128.0, -12.0], 20 | size: [768.0, 384.0, 0.0], 21 | quads: [ 22 | rect { 23 | anm_script: 0, 24 | pos: [-64.0, 0.0, -12.0], 25 | size: [512.0, 256.0], 26 | }, 27 | ], 28 | }, 29 | object1: { 30 | layer: 1, 31 | pos: [-81.602196, -140.91132, -425.6022], 32 | size: [531.2044, 505.268, 571.2044], 33 | quads: [ 34 | rect { 35 | anm_script: 2, 36 | pos: [64.0, 224.0, -64.0], 37 | size: [112.0, 96.0], 38 | }, 39 | ], 40 | }, 41 | }, 42 | instances: [ 43 | object0 {pos: [-192.0, 6600.0, 0.0]}, 44 | object1 {pos: [320.0, 4296.0, 0.0]}, 45 | object0 {pos: [-192.0, 6344.0, 0.0]}, 46 | object0 {pos: [320.0, 4296.0, 0.0]}, 47 | ], 48 | } 49 | 50 | 51 | script main { 52 | posKeyframe(0.0, 0.0, 0.0); 53 | } 54 | 55 | -------------------------------------------------------------------------------- /tests/integration/snapshots/integration__integration__bits_2_bits__std08_nonzero_padding.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/bits_2_bits.rs 3 | expression: s 4 | --- 5 | #pragma mapfile "map/any.stdm" 6 | 7 | meta { 8 | unknown: 0, 9 | stage_name: "dm", 10 | bgm: [ 11 | {path: "bgm/th08_08.mid", name: "dm"}, 12 | {path: "bgm/th08_09.mid", name: "dm"}, 13 | {path: " ", name: " "}, 14 | {path: " ", name: " "}, 15 | ], 16 | objects: {}, 17 | instances: [], 18 | } 19 | 20 | 21 | script main { 22 | posTime(1024, 0, 60); 23 | } 24 | 25 | -------------------------------------------------------------------------------- /tests/integration/snapshots/integration__integration__bits_2_bits__std08_rects.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/bits_2_bits.rs 3 | expression: s 4 | --- 5 | #pragma mapfile "map/any.stdm" 6 | 7 | meta { 8 | unknown: 0, 9 | stage_name: "dm", 10 | bgm: [ 11 | {path: "bgm/th08_08.mid", name: "dm"}, 12 | {path: "bgm/th08_09.mid", name: "dm"}, 13 | {path: " ", name: " "}, 14 | {path: " ", name: " "}, 15 | ], 16 | objects: { 17 | object0: { 18 | layer: 1, 19 | pos: [-81.602196, -140.91132, -425.6022], 20 | size: [531.2044, 505.268, 571.2044], 21 | quads: [ 22 | rect { 23 | anm_script: 2, 24 | pos: [64.0, 224.0, -64.0], 25 | size: [112.0, 96.0], 26 | }, 27 | rect { 28 | anm_script: 2, 29 | pos: [234.0, 224.0, -202.0], 30 | size: [-112.0, 96.0], 31 | }, 32 | ], 33 | }, 34 | }, 35 | instances: [object0 {pos: [-192.0, 6600.0, 0.0]}], 36 | } 37 | 38 | 39 | script main { 40 | posKeyframe(0.0, 0.0, 0.0); 41 | } 42 | 43 | -------------------------------------------------------------------------------- /tests/integration/snapshots/integration__integration__bits_2_bits__std08_strip.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/bits_2_bits.rs 3 | expression: s 4 | --- 5 | #pragma mapfile "map/any.stdm" 6 | 7 | meta { 8 | unknown: 0, 9 | stage_name: "dm", 10 | bgm: [ 11 | {path: "bgm/th08_08.mid", name: "dm"}, 12 | {path: "bgm/th08_09.mid", name: "dm"}, 13 | {path: " ", name: " "}, 14 | {path: " ", name: " "}, 15 | ], 16 | objects: { 17 | object0: { 18 | layer: 1, 19 | pos: [-81.602196, -140.91132, -425.6022], 20 | size: [531.2044, 505.268, 571.2044], 21 | quads: [ 22 | strip { 23 | anm_script: 1, 24 | start: [273.0, 224.0, 0.0], 25 | end: [253.0, 224.0, -280.0], 26 | width: 5.0, 27 | }, 28 | rect { 29 | anm_script: 2, 30 | pos: [64.0, 224.0, -64.0], 31 | size: [112.0, 96.0], 32 | }, 33 | strip { 34 | anm_script: 1, 35 | start: [218.0, 192.0, 0.0], 36 | end: [268.0, 192.0, -280.0], 37 | width: 5.0, 38 | }, 39 | ], 40 | }, 41 | }, 42 | instances: [object0 {pos: [-192.0, 6600.0, 0.0]}], 43 | } 44 | 45 | 46 | script main { 47 | posKeyframe(0.0, 0.0, 0.0); 48 | } 49 | 50 | -------------------------------------------------------------------------------- /tests/integration/snapshots/integration__integration__bits_2_bits__std12_general.snap: -------------------------------------------------------------------------------- 1 | --- 2 | source: tests/integration/bits_2_bits.rs 3 | expression: s 4 | --- 5 | #pragma mapfile "map/any.stdm" 6 | 7 | meta { 8 | unknown: 0, 9 | anm_path: "stage01.anm", 10 | objects: { 11 | object0: { 12 | layer: 0, 13 | pos: [-2.0, 0.0, -3.0], 14 | size: [751.0, 512.0, 5.0], 15 | quads: [ 16 | rect { 17 | anm_script: 0, 18 | pos: [124.0, 0.0, 0.0], 19 | size: [256.0, 512.0], 20 | }, 21 | ], 22 | }, 23 | }, 24 | instances: [ 25 | object0 {pos: [0.0, 512.0, 0.0]}, 26 | object0 {pos: [0.0, 1024.0, 0.0]}, 27 | object0 {pos: [0.0, 1536.0, 0.0]}, 28 | ], 29 | } 30 | 31 | 32 | script main { 33 | fog(0xffefefff, 200.0, 1100.0); 34 | fogTime(600, 0, 0xffc0d0ff, 800.0, 1200.0); 35 | posBezier(690, 8, 0.0, 0.0, 0.0, 0.0, 2400.0, -700.0, 0.0, 1800.0, 0.0); 36 | loop { 37 | pos(0.0, 4724.0, -700.0); 38 | posTime(1280, 0, 0.0, 8820.0, -700.0); 39 | +1280: // 1280 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /tests/integration/time_label_compilation.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused)] 2 | use crate::integration_impl::{expected, formats::*}; 3 | 4 | source_test!( 5 | ECL_06, basic, 6 | main_body: r#" 7 | 0: nop(); 8 | +20: nop(); 9 | +30: nop(); 10 | 10: nop(); 11 | +20: nop(); 12 | +-15: nop(); 13 | "#, 14 | check_compiled: |output, format| { 15 | let ecl = output.read_olde_ecl(format); 16 | assert_eq!(ecl.subs[0][0].time, 0); 17 | assert_eq!(ecl.subs[0][1].time, 20); 18 | assert_eq!(ecl.subs[0][2].time, 50); 19 | assert_eq!(ecl.subs[0][3].time, 10); 20 | assert_eq!(ecl.subs[0][4].time, 30); 21 | assert_eq!(ecl.subs[0][5].time, 15); 22 | }, 23 | ); 24 | 25 | source_test!( 26 | ECL_06, r#const, 27 | items: r#" 28 | const int BLOOP = 60; 29 | "#, 30 | main_body: r#" 31 | 70: nop(); 32 | +BLOOP: nop(); 33 | "#, 34 | check_compiled: |output, format| { 35 | let ecl = output.read_olde_ecl(format); 36 | assert_eq!(ecl.subs[0][0].time, 70); 37 | assert_eq!(ecl.subs[0][1].time, 130); 38 | }, 39 | ); 40 | 41 | source_test!( 42 | ECL_06, non_const, 43 | main_body: r#" 44 | 70: nop(); 45 | +I0: nop(); //~ ERROR const 46 | "#, 47 | ); 48 | 49 | source_test!( 50 | ECL_06, overflow, 51 | items: r#" 52 | const int BLOOP = 60; 53 | "#, 54 | main_body: r#" 55 | +0x70000000: nop(); 56 | +0x70000000: nop(); 57 | +0x70000000: nop(); 58 | "#, 59 | check_compiled: |output, format| { 60 | let ecl = output.read_olde_ecl(format); 61 | assert_eq!(ecl.subs[0][0].time, 0x7000_0000); 62 | assert_eq!(ecl.subs[0][1].time, 0xe000_0000_u32 as i32); 63 | assert_eq!(ecl.subs[0][2].time, 0x5000_0000); 64 | }, 65 | ); 66 | -------------------------------------------------------------------------------- /tests/integration/time_label_formatting.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused)] 2 | use crate::integration_impl::{expected, formats::*}; 3 | 4 | source_test!( 5 | ECL_06, general_1, 6 | main_body: r#" 7 | 0: nop(); 8 | 2: nop(); 9 | 5: nop(); 10 | "#, 11 | check_decompiled: |decompiled| { 12 | assert!(!decompiled.contains("\n0:")); // suppress initial 0 label 13 | assert!(decompiled.contains("\n+2:")); // prefer relative labels 14 | assert_snapshot!(decompiled) 15 | }, 16 | ); 17 | 18 | source_test!( 19 | ECL_06, general_2, 20 | main_body: r#" 21 | 5: nop(); 22 | 3: nop(); 23 | 0: nop(); 24 | "#, 25 | check_decompiled: |decompiled| { 26 | assert!(decompiled.contains("5:")); // nonzero beginning, don't care if rel or absolute 27 | assert!(decompiled.contains("\n3:")); // decreased label 28 | assert!(decompiled.contains("\n0:")); // explicit zero label 29 | assert_snapshot!(decompiled) 30 | }, 31 | ); 32 | 33 | source_test!( 34 | ECL_06, after_neg, 35 | // negative label followed by 0 or positive. 36 | main_body: r#" 37 | -1: nop(); 38 | 0: nop(); 39 | -1: nop(); 40 | 6: nop(); 41 | "#, 42 | check_decompiled: |decompiled| { 43 | assert_eq!(decompiled.matches("\n-1:").count(), 2); 44 | assert_eq!(decompiled.matches("\n0:").count(), 2); // the "6:" should become "0: +6" 45 | assert_eq!(decompiled.matches("\n+6:").count(), 1); 46 | assert_snapshot!(decompiled) 47 | }, 48 | ); 49 | 50 | source_test!( 51 | ECL_06, neg_neg, 52 | // increasing or decreasing negative labels 53 | main_body: r#" 54 | -1: nop(); 55 | -2: nop(); 56 | -1: nop(); 57 | "#, 58 | check_decompiled: |_decompiled| { 59 | // mostly just care that the output is correct, this never shows up in practice 60 | }, 61 | ); 62 | 63 | source_test!( 64 | ECL_06, compression, 65 | // compression of identical time labels, regardless of sign 66 | main_body: r#" 67 | 0: nop(); nop(); 68 | 6: nop(); nop(); 69 | -1: nop(); nop(); 70 | "#, 71 | check_decompiled: |decompiled| { 72 | assert_eq!(decompiled.matches(":").count(), 2); 73 | assert_snapshot!(decompiled); 74 | }, 75 | ); 76 | -------------------------------------------------------------------------------- /update-dumps-example.yaml: -------------------------------------------------------------------------------- 1 | directories: 2 | # Directory with child directories for all Windows touhou games. 3 | # Each directory must contain the output of 'thdat -x' for that game. 4 | # They must all end in the game number (zero padded if < 10), with a common prefix. 5 | # e.g. th06, th095, th14 6 | input: 7 | root: /home/exp/thcrap/decomp 8 | subdir-prefix: th 9 | # Output directory for decompilation. Will be created if it does not exist. 10 | text-dump: 11 | root: all-dumps 12 | subdir-prefix: th 13 | # Output directory for recompilation. Will be created if it does not exist. 14 | # Can be same as text-dump. 15 | binary-dump: 16 | root: all-dumps 17 | subdir-prefix: th 18 | --------------------------------------------------------------------------------