├── .cargo
└── config.toml
├── .github
├── dependabot.yml
└── workflows
│ ├── ci.yml
│ ├── package.yml
│ └── release.yml
├── .gitignore
├── .rustfmt.toml
├── Cargo.lock
├── Cargo.toml
├── LICENSE
├── README.md
├── assets
├── archive
│ ├── engine
│ │ └── config
│ │ │ └── base
│ │ │ └── scripts.ini
│ └── r6
│ │ └── config
│ │ └── cybercmd
│ │ └── scc.toml
└── reds
│ └── boot.reds
├── crates
├── cli
│ ├── Cargo.toml
│ └── src
│ │ └── main.rs
├── compiler
│ ├── api
│ │ ├── Cargo.toml
│ │ └── src
│ │ │ └── lib.rs
│ ├── backend
│ │ ├── Cargo.toml
│ │ ├── src
│ │ │ ├── assemble.rs
│ │ │ ├── assemble
│ │ │ │ └── closure.rs
│ │ │ ├── inputs.rs
│ │ │ ├── known_types.rs
│ │ │ ├── lib.rs
│ │ │ └── monomorph.rs
│ │ └── tests
│ │ │ ├── bytecode.rs
│ │ │ ├── data
│ │ │ ├── array-literal.reds
│ │ │ ├── break.reds
│ │ │ ├── cast.reds
│ │ │ ├── continue.reds
│ │ │ ├── dyn-cast.reds
│ │ │ ├── enum.reds
│ │ │ ├── excluded.reds
│ │ │ ├── for-loop.reds
│ │ │ ├── generic-struct.reds
│ │ │ ├── if-else.reds
│ │ │ ├── implicit-convert.reds
│ │ │ ├── lambda.reds
│ │ │ ├── local-init.reds
│ │ │ ├── name-of.reds
│ │ │ ├── named-impl.reds
│ │ │ ├── nested-for-loop.reds
│ │ │ ├── number-literal.reds
│ │ │ ├── return-void.reds
│ │ │ ├── static-arrays.reds
│ │ │ ├── string-interp.reds
│ │ │ ├── string-literal.reds
│ │ │ ├── struct.reds
│ │ │ ├── super.reds
│ │ │ ├── switch.reds
│ │ │ ├── ternary.reds
│ │ │ └── variant.reds
│ │ │ └── snapshots
│ │ │ ├── bytecode__bytecode@array-literal.reds.snap
│ │ │ ├── bytecode__bytecode@break.reds.snap
│ │ │ ├── bytecode__bytecode@cast.reds.snap
│ │ │ ├── bytecode__bytecode@continue.reds.snap
│ │ │ ├── bytecode__bytecode@dyn-cast.reds.snap
│ │ │ ├── bytecode__bytecode@enum.reds.snap
│ │ │ ├── bytecode__bytecode@excluded.reds.snap
│ │ │ ├── bytecode__bytecode@for-loop.reds.snap
│ │ │ ├── bytecode__bytecode@generic-struct.reds.snap
│ │ │ ├── bytecode__bytecode@if-else.reds.snap
│ │ │ ├── bytecode__bytecode@implicit-convert.reds.snap
│ │ │ ├── bytecode__bytecode@lambda.reds.snap
│ │ │ ├── bytecode__bytecode@local-init.reds.snap
│ │ │ ├── bytecode__bytecode@name-of.reds.snap
│ │ │ ├── bytecode__bytecode@named-impl.reds.snap
│ │ │ ├── bytecode__bytecode@nested-for-loop.reds.snap
│ │ │ ├── bytecode__bytecode@number-literal.reds.snap
│ │ │ ├── bytecode__bytecode@return-void.reds.snap
│ │ │ ├── bytecode__bytecode@static-arrays.reds.snap
│ │ │ ├── bytecode__bytecode@string-interp.reds.snap
│ │ │ ├── bytecode__bytecode@string-literal.reds.snap
│ │ │ ├── bytecode__bytecode@struct.reds.snap
│ │ │ ├── bytecode__bytecode@super.reds.snap
│ │ │ ├── bytecode__bytecode@switch.reds.snap
│ │ │ ├── bytecode__bytecode@ternary.reds.snap
│ │ │ └── bytecode__bytecode@variant.reds.snap
│ └── frontend
│ │ ├── Cargo.toml
│ │ ├── src
│ │ ├── cte.rs
│ │ ├── diagnostic.rs
│ │ ├── diagnostic
│ │ │ ├── pass.rs
│ │ │ └── pass
│ │ │ │ └── unused_locals.rs
│ │ ├── ir.rs
│ │ ├── lib.rs
│ │ ├── lower.rs
│ │ ├── modules.rs
│ │ ├── stages.rs
│ │ ├── stages
│ │ │ ├── infer.rs
│ │ │ └── resolution.rs
│ │ ├── symbols.rs
│ │ ├── types.rs
│ │ ├── utils.rs
│ │ ├── utils
│ │ │ ├── fmt.rs
│ │ │ ├── lazy.rs
│ │ │ └── scoped_map.rs
│ │ └── visitor.rs
│ │ └── tests
│ │ ├── data
│ │ ├── annotation-checks.reds
│ │ ├── class-checks.reds
│ │ ├── enum-checks.reds
│ │ ├── expr-checks.reds
│ │ ├── function-checks.reds
│ │ ├── inference.reds
│ │ ├── interpolation-error.reds
│ │ ├── invariance-checks.reds
│ │ ├── item-checks.reds
│ │ └── type-mismatch.reds
│ │ ├── errors.rs
│ │ └── snapshots
│ │ ├── errors__compilation_errors@annotation-checks.reds.snap
│ │ ├── errors__compilation_errors@class-checks.reds.snap
│ │ ├── errors__compilation_errors@enum-checks.reds.snap
│ │ ├── errors__compilation_errors@expr-checks.reds.snap
│ │ ├── errors__compilation_errors@function-checks.reds.snap
│ │ ├── errors__compilation_errors@inference.reds.snap
│ │ ├── errors__compilation_errors@interpolation-error.reds.snap
│ │ ├── errors__compilation_errors@invariance-checks.reds.snap
│ │ ├── errors__compilation_errors@item-checks.reds.snap
│ │ └── errors__compilation_errors@type-mismatch.reds.snap
├── decompiler
│ ├── Cargo.toml
│ └── src
│ │ ├── control_flow.rs
│ │ ├── decompiler.rs
│ │ ├── error.rs
│ │ ├── lib.rs
│ │ └── location.rs
├── dotfile
│ ├── Cargo.toml
│ └── src
│ │ └── lib.rs
├── io
│ ├── Cargo.toml
│ ├── examples
│ │ └── cli.rs
│ ├── src
│ │ ├── bundle.rs
│ │ ├── definition.rs
│ │ ├── index.rs
│ │ ├── instr.rs
│ │ ├── lib.rs
│ │ └── util.rs
│ └── tests
│ │ └── tests.rs
├── scc
│ ├── capi
│ │ ├── Cargo.toml
│ │ ├── include
│ │ │ └── scc.h
│ │ └── src
│ │ │ └── lib.rs
│ ├── cli
│ │ ├── Cargo.toml
│ │ ├── build.rs
│ │ └── src
│ │ │ ├── arguments.rs
│ │ │ ├── capi.rs
│ │ │ ├── main.rs
│ │ │ └── raw.rs
│ └── shared
│ │ ├── Cargo.toml
│ │ └── src
│ │ ├── hints.rs
│ │ ├── lib.rs
│ │ ├── logger.rs
│ │ ├── output.rs
│ │ ├── report.rs
│ │ ├── settings.rs
│ │ └── timestamp.rs
└── syntax
│ ├── ast
│ ├── Cargo.toml
│ └── src
│ │ ├── ast.rs
│ │ ├── files.rs
│ │ ├── lib.rs
│ │ ├── span.rs
│ │ └── visitor.rs
│ ├── formatter
│ ├── Cargo.toml
│ ├── src
│ │ └── lib.rs
│ └── tests
│ │ ├── data
│ │ ├── commented.reds
│ │ ├── control-flow.reds
│ │ ├── module.reds
│ │ └── operators.reds
│ │ ├── formatted.rs
│ │ └── snapshots
│ │ ├── formatted__formatted_files@commented.reds.snap
│ │ ├── formatted__formatted_files@control-flow.reds.snap
│ │ ├── formatted__formatted_files@module.reds.snap
│ │ └── formatted__formatted_files@operators.reds.snap
│ └── parser
│ ├── Cargo.toml
│ └── src
│ ├── lexer.rs
│ ├── lib.rs
│ ├── parser.rs
│ └── parser
│ ├── expr.rs
│ ├── item.rs
│ └── stmt.rs
├── docs
└── types
│ ├── Array.md
│ ├── Bool.md
│ ├── Cname.md
│ ├── Double.md
│ ├── Float.md
│ ├── Int16.md
│ ├── Int32.md
│ ├── Int64.md
│ ├── Int8.md
│ ├── Nothing.md
│ ├── Ref.md
│ ├── ResRef.md
│ ├── ScriptRef.md
│ ├── String.md
│ ├── TweakDbId.md
│ ├── Uint16.md
│ ├── Uint32.md
│ ├── Uint64.md
│ ├── Uint8.md
│ ├── Variant.md
│ ├── Void.md
│ └── Wref.md
└── scripts
├── build-pgo.ps1
└── package.ps1
/.cargo/config.toml:
--------------------------------------------------------------------------------
1 | [target.x86_64-pc-windows-msvc]
2 | linker = "rust-lld.exe"
3 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "cargo"
4 | directory: "/"
5 | schedule:
6 | interval: "daily"
7 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | push:
5 | branches: ["*.*.x"]
6 | pull_request:
7 | branches: ["*.*.x"]
8 |
9 | env:
10 | CARGO_TERM_COLOR: always
11 |
12 | jobs:
13 | check-format:
14 | name: Check formatting
15 | runs-on: ubuntu-latest
16 | steps:
17 | - uses: actions/checkout@v4
18 | - run: rustup toolchain install nightly --profile minimal --component rustfmt --no-self-update
19 | - run: cargo +nightly fmt --all -- --check
20 |
21 | lint:
22 | name: Lint
23 | runs-on: windows-latest
24 | steps:
25 | - uses: actions/checkout@v4
26 | - run: rustup toolchain install stable --profile minimal --component clippy --no-self-update
27 | - uses: Swatinem/rust-cache@v2
28 | - run: cargo clippy --all-features -- -D warnings
29 |
30 | test:
31 | name: Test
32 | runs-on: windows-latest
33 | steps:
34 | - uses: actions/checkout@v4
35 | - run: rustup toolchain install stable --profile minimal --no-self-update
36 | - uses: Swatinem/rust-cache@v2
37 | - run: cargo test --all-features
38 |
39 | package:
40 | name: Package and upload artifacts
41 | uses: ./.github/workflows/package.yml
42 |
--------------------------------------------------------------------------------
/.github/workflows/package.yml:
--------------------------------------------------------------------------------
1 | on:
2 | workflow_call:
3 |
4 | env:
5 | CARGO_TERM_COLOR: always
6 |
7 | jobs:
8 | package:
9 | runs-on: windows-latest
10 | steps:
11 | - uses: actions/checkout@v4
12 | with:
13 | fetch-depth: 0
14 | filter: tree:0
15 | - run: rustup toolchain install stable --profile minimal --no-self-update
16 | - uses: Swatinem/rust-cache@v2
17 | - run: cargo build --release
18 | - id: tag
19 | run: echo "tag=$(git describe --tags $(git rev-list --tags --max-count=1))" >> $env:GITHUB_OUTPUT
20 | - run: .\scripts\package.ps1 -zipPath redscript-${{ steps.tag.outputs.tag }}.zip
21 | - uses: actions/upload-artifact@v4
22 | with:
23 | path: |
24 | redscript-${{ steps.tag.outputs.tag }}.zip
25 | target/release/redscript-cli.exe
26 | if-no-files-found: error
27 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release
2 |
3 | on:
4 | push:
5 | tags:
6 | - "v[0-9]+.[0-9]+.[0-9]+"
7 | - "v[0-9]+.[0-9]+.[0-9]+-*"
8 |
9 | env:
10 | CARGO_TERM_COLOR: always
11 |
12 | jobs:
13 | package:
14 | name: Package and upload artifacts
15 | uses: ./.github/workflows/package.yml
16 |
17 | publish:
18 | name: Publish release
19 | runs-on: ubuntu-latest
20 | needs: package
21 | permissions:
22 | contents: write
23 | steps:
24 | - uses: actions/checkout@v4
25 | - uses: actions/download-artifact@v4
26 | with:
27 | path: artifacts
28 | merge-multiple: true
29 | - name: Publish release
30 | env:
31 | GH_TOKEN: ${{ github.token }}
32 | run: |
33 | FLAGS=()
34 | ARTIFACTS=$(find ./artifacts -type f)
35 |
36 | if echo ${{ github.ref_name }} | grep -E 'v[0-9]+\.[0-9]+\.[0-9]+-.+'; then
37 | FLAGS+=(--prerelease)
38 | fi
39 |
40 | gh release create ${{ github.ref_name }} ${FLAGS[@]} $ARTIFACTS
41 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | final.redscripts.modded
3 |
--------------------------------------------------------------------------------
/.rustfmt.toml:
--------------------------------------------------------------------------------
1 | max_width = 100
2 | unstable_features = true
3 | use_field_init_shorthand = true
4 | imports_granularity = "Module"
5 | reorder_imports = true
6 | group_imports = "StdExternalCrate"
7 | reorder_impl_items = true
8 | reorder_modules = true
9 | edition = "2024"
10 |
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [workspace]
2 | resolver = "2"
3 | members = [
4 | "crates/syntax/ast",
5 | "crates/syntax/parser",
6 | "crates/syntax/formatter",
7 | "crates/io",
8 | "crates/compiler/frontend",
9 | "crates/compiler/backend",
10 | "crates/compiler/api",
11 | "crates/decompiler",
12 | "crates/cli",
13 | "crates/scc/shared",
14 | "crates/scc/capi",
15 | "crates/scc/cli",
16 | "crates/dotfile",
17 | ]
18 |
19 | [workspace.package]
20 | version = "1.0.0-preview.13"
21 | authors = ["jekky"]
22 | edition = "2024"
23 |
24 | [workspace.dependencies]
25 | redscript-ast.path = "crates/syntax/ast"
26 | redscript-parser.path = "crates/syntax/parser"
27 | redscript-formatter.path = "crates/syntax/formatter"
28 | redscript-io.path = "crates/io"
29 | redscript-compiler-frontend.path = "crates/compiler/frontend"
30 | redscript-compiler-backend.path = "crates/compiler/backend"
31 | redscript-compiler-api.path = "crates/compiler/api"
32 | redscript-decompiler.path = "crates/decompiler"
33 | scc-shared.path = "crates/scc/shared"
34 | redscript-dotfile.path = "crates/dotfile"
35 |
36 | log = "0.4"
37 | thiserror = "2"
38 | anyhow = "1"
39 | chrono = "0.4"
40 | derive-where = "1"
41 | paste = "1"
42 | bitflags = "2"
43 | bitfield-struct = "0.11"
44 | identity-hash = "0.1"
45 | foldhash = "0.1"
46 | slab = "0.4"
47 | smallvec = { version = "1", features = ["union", "const_generics"] }
48 | hashbrown = "0.15"
49 | indexmap = "2"
50 | elsa = { version = "1", features = ["indexmap"] }
51 | serde = "1"
52 | toml = { version = "0.8", default-features = false }
53 | fern = "0.7"
54 | flexi_logger = { version = "0.30", default-features = false }
55 | argh = "0.1"
56 | chumsky = { version = "1.0.0-alpha.7", features = ["label"] }
57 | crc32fast = "1"
58 | ignore = "0.4"
59 | vmap = "0.6"
60 | file-id = "0.2"
61 | fd-lock = "4"
62 | msgbox = "0.7"
63 | pretty_dtoa = "0.3"
64 | minidl = "0.1"
65 | bindgen = "0.71"
66 | mimalloc = "0.1"
67 |
68 | similar-asserts = "1"
69 | insta = { version = "1", features = ["glob"] }
70 |
71 | [workspace.dependencies.byte]
72 | git = "https://github.com/jac3km4/byte"
73 | rev = "da71833"
74 | features = ["alloc", "derive"]
75 |
76 | [workspace.dependencies.sequence_trie]
77 | git = "https://github.com/jac3km4/rust_sequence_trie"
78 | rev = "20c28c4"
79 | features = ["hashbrown"]
80 |
81 | [patch.crates-io]
82 | stable_deref_trait = { git = "https://github.com/Storyyeller/stable_deref_trait", rev = "59a35e0" }
83 |
84 | [workspace.lints.rust]
85 | warnings = "warn"
86 | future-incompatible = "warn"
87 | let-underscore = "warn"
88 | nonstandard-style = "warn"
89 | rust-2018-compatibility = "warn"
90 | rust-2018-idioms = "warn"
91 | rust-2021-compatibility = "warn"
92 | rust-2024-compatibility = "warn"
93 |
94 | [workspace.lints.clippy]
95 | all = "warn"
96 | match_same_arms = "warn"
97 | semicolon_if_nothing_returned = "warn"
98 | single_match_else = "warn"
99 | redundant_closure_for_method_calls = "warn"
100 | cloned_instead_of_copied = "warn"
101 | redundant_else = "warn"
102 | unnested_or_patterns = "warn"
103 | unreadable_literal = "warn"
104 | type_repetition_in_bounds = "warn"
105 | equatable_if_let = "warn"
106 | implicit_clone = "warn"
107 | default_trait_access = "warn"
108 | explicit_deref_methods = "warn"
109 | explicit_iter_loop = "warn"
110 | inefficient_to_string = "warn"
111 | match_bool = "warn"
112 |
113 | [profile.release]
114 | strip = true
115 | lto = true
116 | codegen-units = 1
117 | panic = "abort"
118 |
119 | [workspace.metadata.release]
120 | pre-release-commit-message = "chore: release {{version}}"
121 | tag-prefix = ""
122 | shared-version = true
123 | publish = false
124 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 jac3km4
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |