Compare commits
193 Commits
feature/t6
...
dev
Author | SHA1 | Date | |
---|---|---|---|
|
d2443394f6 | ||
|
2caaf75128 | ||
|
fdd052dad9 | ||
|
b8d2c84ae0 | ||
|
0e6238a6ab | ||
|
228293c0bf | ||
|
8b03229a19 | ||
|
08405c0c90 | ||
|
2dbff1a408 | ||
|
9b885e3439 | ||
|
6b69996713 | ||
|
fe0f793d10 | ||
|
638ff54d93 | ||
|
ecffa889ad | ||
|
c5db0fa49f | ||
|
3896ec0e4e | ||
|
50ebfd2b25 | ||
|
b41a9f7d54 | ||
|
a44a9bf300 | ||
|
7f31582cc3 | ||
|
d975cc7d03 | ||
|
76eca569b3 | ||
|
8e1326c36e | ||
|
fb755ef937 | ||
|
4806a285b6 | ||
|
f367d198f9 | ||
|
cbfcce1dd6 | ||
|
139f9ce55c | ||
|
030065f1de | ||
|
cf8a7566be | ||
|
9e2dcf8d36 | ||
|
834e4023f5 | ||
|
898e575978 | ||
|
32e168cd1b | ||
|
4721acaa4c | ||
|
008d545bdb | ||
|
6e489a21cd | ||
|
43adb166b3 | ||
|
07e4563446 | ||
|
7dfc343fad | ||
|
f17d68aa1c | ||
|
d7365e471a | ||
|
2c5a74a172 | ||
|
39fe362938 | ||
|
16afa9398c | ||
|
401ad99dc3 | ||
|
799b5d99ae | ||
|
3ac5ce54d5 | ||
|
4973ceceb1 | ||
|
3125c2e879 | ||
|
64c2f1ef70 | ||
|
34a67d97c6 | ||
|
4f0573c5f4 | ||
|
9277e03011 | ||
|
f0264876df | ||
|
5a144a3ba7 | ||
|
806b5249fa | ||
|
f21bf9646a | ||
|
7198ccdd58 | ||
|
07184a5d0f | ||
|
a8a62c2667 | ||
|
76989d7c9d | ||
|
d6307893d5 | ||
|
04c0e0fce0 | ||
|
c314990402 | ||
|
15526ab79a | ||
|
e05d853ba6 | ||
|
f6ae955f34 | ||
|
1bca247808 | ||
|
30efba5424 | ||
|
9155ce7c4b | ||
|
28ae5d5e57 | ||
|
b44a51d8ac | ||
|
9318c6e0ae | ||
|
dc8be10fb6 | ||
|
c0fd2a1b69 | ||
|
c515ef6890 | ||
|
9c08cbd8c6 | ||
|
105c0630d2 | ||
|
f51bdd2c4f | ||
|
c1cfa44631 | ||
|
5fbb0cea7d | ||
|
64bb892778 | ||
|
dc18fcea00 | ||
|
adf88fc5c9 | ||
|
9a7bb1fac7 | ||
|
bd05f90a34 | ||
|
b3ac7d2562 | ||
|
281cbb95f8 | ||
|
66d158bed8 | ||
|
9cbf2c9c47 | ||
|
c24f17dd2c | ||
|
2140772f9d | ||
|
4fc912b91a | ||
|
66ecf90171 | ||
|
9b471160dd | ||
|
a3d4838603 | ||
|
b63fea4f0b | ||
|
df8f74bbce | ||
|
d73793833e | ||
|
b3a6fc5809 | ||
|
6eeb6b7c8c | ||
|
08bbfcb67a | ||
|
bc0cc6d0f5 | ||
|
e4e884d110 | ||
|
775702323a | ||
|
59e9ff458a | ||
|
652e21e232 | ||
|
b3f502944e | ||
|
8c37255aeb | ||
|
821f59c694 | ||
|
8bc4bec600 | ||
|
79759d91ab | ||
|
309cf4b985 | ||
|
202249abdb | ||
|
cac1ba577b | ||
|
ecf7fff345 | ||
|
532e5f5e88 | ||
|
d47c0d1520 | ||
|
61a1fae515 | ||
|
de2c7fd529 | ||
|
95469a0724 | ||
|
0e1da895d7 | ||
|
2ab5118d16 | ||
|
9b7f14c7a2 | ||
|
9b7ee7971d | ||
|
e5d6196da1 | ||
|
379e3a03ae | ||
|
4e4480792a | ||
|
b0ed15dc6c | ||
|
ebafbf5c31 | ||
|
bfae2b81f3 | ||
|
6a3f0d6ecc | ||
|
b04538aaa2 | ||
|
25f20d87ea | ||
|
88b4539bbf | ||
|
a9e08a7171 | ||
|
3261566d17 | ||
|
f91a2552b3 | ||
|
7cc15969db | ||
|
6d85d0969d | ||
|
01e25f8929 | ||
|
430f321477 | ||
|
4c410238e9 | ||
|
094bc0e815 | ||
|
effbbbfcb5 | ||
|
88ae3e74a7 | ||
|
98d610d13f | ||
|
7695f42155 | ||
|
ac9cb07286 | ||
|
de834116af | ||
|
8929499bbd | ||
|
af064c5f40 | ||
|
cfe8c3de0e | ||
|
6efacd1ef2 | ||
|
797b4e055d | ||
|
e083420e10 | ||
|
487b825bc1 | ||
|
7430679532 | ||
|
38b66bd46f | ||
|
b52ce98b6d | ||
|
06a30ddd99 | ||
|
32d4ec28d7 | ||
|
d09c261d0f | ||
|
9c50ff461d | ||
|
0420e0457a | ||
|
ced80282e8 | ||
|
3236e6e079 | ||
|
0fc0834a83 | ||
|
0527d294ed | ||
|
e876097517 | ||
|
4e2eeced30 | ||
|
f6f958eb21 | ||
|
d008fc0ab8 | ||
|
c44c54f815 | ||
|
b8cc78d106 | ||
|
900ce1db26 | ||
|
6048902ec7 | ||
|
b73a47bd6e | ||
|
6a097f48f1 | ||
|
3c58f911ab | ||
|
e8ba428353 | ||
|
9ecd86a1d7 | ||
|
b966e986c7 | ||
|
cb531e7f1f | ||
|
0ddfafd98e | ||
|
87810ff72d | ||
|
242ee33f07 | ||
|
9910527d60 | ||
|
8b8fffd59e | ||
|
48165edfad | ||
|
64d107404d | ||
|
dba70d126f |
3
.github/FUNDING.yml
vendored
3
.github/FUNDING.yml
vendored
@ -1,2 +1,3 @@
|
|||||||
|
github: xensik
|
||||||
ko_fi: xensik
|
ko_fi: xensik
|
||||||
custom: https://www.paypal.me/xensik
|
custom: paypal.me/xensik
|
||||||
|
7
.github/dependabot.yml
vendored
7
.github/dependabot.yml
vendored
@ -1,7 +0,0 @@
|
|||||||
version: 2
|
|
||||||
updates:
|
|
||||||
- package-ecosystem: "gitsubmodule"
|
|
||||||
directory: "/"
|
|
||||||
schedule:
|
|
||||||
interval: "daily"
|
|
||||||
open-pull-requests-limit: 10
|
|
220
.github/workflows/main.yml
vendored
Normal file
220
.github/workflows/main.yml
vendored
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
name: Main
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "**"
|
||||||
|
tags:
|
||||||
|
- '[0-9]+.[0-9]+.[0-9]+'
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- "**"
|
||||||
|
types: [opened, synchronize, reopened]
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
env:
|
||||||
|
PREMAKE_VERSION: "5.0.0-beta2"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-windows:
|
||||||
|
name: Build Windows
|
||||||
|
runs-on: windows-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
config:
|
||||||
|
- release
|
||||||
|
arch:
|
||||||
|
- x86
|
||||||
|
- x64
|
||||||
|
include:
|
||||||
|
- arch: x86
|
||||||
|
platform: Win32
|
||||||
|
- arch: x64
|
||||||
|
platform: x64
|
||||||
|
steps:
|
||||||
|
- name: Check out files
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: true
|
||||||
|
fetch-depth: 0
|
||||||
|
lfs: false
|
||||||
|
|
||||||
|
- name: Add msbuild to PATH
|
||||||
|
uses: microsoft/setup-msbuild@v1.3.1
|
||||||
|
|
||||||
|
- name: Add premake5 to PATH
|
||||||
|
uses: abel0b/setup-premake@v2.3
|
||||||
|
with:
|
||||||
|
version: ${{ env.PREMAKE_VERSION }}
|
||||||
|
|
||||||
|
- name: Generate project files
|
||||||
|
run: premake5 vs2022
|
||||||
|
|
||||||
|
- name: Set up problem matching
|
||||||
|
uses: ammaraskar/msvc-problem-matcher@master
|
||||||
|
|
||||||
|
- name: Build ${{matrix.arch}} ${{matrix.config}} binaries
|
||||||
|
run: msbuild /m /v:minimal /p:Configuration=${{matrix.config}} /p:Platform=${{matrix.platform}} build/gsc-tool.sln
|
||||||
|
|
||||||
|
- name: Upload ${{matrix.arch}} ${{matrix.config}} binaries
|
||||||
|
uses: actions/upload-artifact@v3.1.3
|
||||||
|
with:
|
||||||
|
name: windows-${{matrix.arch}}-${{matrix.config}}
|
||||||
|
path: |
|
||||||
|
build/bin/${{matrix.arch}}/${{matrix.config}}/gsc-tool.exe
|
||||||
|
|
||||||
|
build-macos:
|
||||||
|
name: Build macOS
|
||||||
|
runs-on: macos-13
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
config:
|
||||||
|
- release
|
||||||
|
arch:
|
||||||
|
- x64
|
||||||
|
- arm64
|
||||||
|
steps:
|
||||||
|
- name: Check out files
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: true
|
||||||
|
fetch-depth: 0
|
||||||
|
lfs: false
|
||||||
|
|
||||||
|
- name: Set up Homebrew
|
||||||
|
uses: Homebrew/actions/setup-homebrew@master
|
||||||
|
|
||||||
|
- name: Install LLVM
|
||||||
|
run: brew install llvm
|
||||||
|
|
||||||
|
- name: Add LLVM to PATH
|
||||||
|
run: |
|
||||||
|
echo "/usr/local/opt/llvm/bin" >> $GITHUB_PATH
|
||||||
|
|
||||||
|
- name: Add premake5 to PATH
|
||||||
|
uses: abel0b/setup-premake@v2.3
|
||||||
|
with:
|
||||||
|
version: ${{ env.PREMAKE_VERSION }}
|
||||||
|
|
||||||
|
- name: Generate project files
|
||||||
|
run: premake5 gmake2
|
||||||
|
|
||||||
|
- name: Set up problem matching
|
||||||
|
uses: ammaraskar/gcc-problem-matcher@master
|
||||||
|
|
||||||
|
- name: Build ${{matrix.arch}} ${{matrix.config}} binaries
|
||||||
|
run: |
|
||||||
|
pushd build
|
||||||
|
make config=${{matrix.config}}_${{matrix.arch}} -j$(sysctl -n hw.logicalcpu)
|
||||||
|
|
||||||
|
- name: Upload ${{matrix.arch}} ${{matrix.config}} binaries
|
||||||
|
uses: actions/upload-artifact@v3.1.3
|
||||||
|
with:
|
||||||
|
name: macos-${{matrix.arch}}-${{matrix.config}}
|
||||||
|
path: |
|
||||||
|
build/bin/${{matrix.arch}}/${{matrix.config}}/gsc-tool
|
||||||
|
|
||||||
|
build-linux:
|
||||||
|
name: Build Linux
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
config:
|
||||||
|
- release
|
||||||
|
arch:
|
||||||
|
- x64
|
||||||
|
# - arm64
|
||||||
|
steps:
|
||||||
|
- name: Check out files
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: true
|
||||||
|
fetch-depth: 0
|
||||||
|
lfs: false
|
||||||
|
|
||||||
|
- name: Install LLVM
|
||||||
|
run: |
|
||||||
|
wget https://apt.llvm.org/llvm.sh
|
||||||
|
chmod +x llvm.sh
|
||||||
|
sudo ./llvm.sh 17
|
||||||
|
|
||||||
|
# - name: Install dependencies (arm64)
|
||||||
|
# if: matrix.arch == 'arm64'
|
||||||
|
# run: sudo apt-get install crossbuild-essential-arm64 -y
|
||||||
|
|
||||||
|
- name: Add premake5 to PATH
|
||||||
|
uses: abel0b/setup-premake@v2.3
|
||||||
|
with:
|
||||||
|
version: ${{ env.PREMAKE_VERSION }}
|
||||||
|
|
||||||
|
- name: Generate project files
|
||||||
|
run: premake5 gmake2
|
||||||
|
|
||||||
|
- name: Set up problem matching
|
||||||
|
uses: ammaraskar/gcc-problem-matcher@master
|
||||||
|
|
||||||
|
- name: Build ${{matrix.arch}} ${{matrix.config}} binaries
|
||||||
|
run: |
|
||||||
|
pushd build
|
||||||
|
make config=${{matrix.config}}_${{matrix.arch}} -j$(nproc)
|
||||||
|
env:
|
||||||
|
CC: clang-17
|
||||||
|
CXX: clang++-17
|
||||||
|
|
||||||
|
- name: Upload ${{matrix.arch}} ${{matrix.config}} binaries
|
||||||
|
uses: actions/upload-artifact@v3.1.3
|
||||||
|
with:
|
||||||
|
name: linux-${{matrix.arch}}-${{matrix.config}}
|
||||||
|
path: |
|
||||||
|
build/bin/${{matrix.arch}}/${{matrix.config}}/gsc-tool
|
||||||
|
|
||||||
|
deploy:
|
||||||
|
name: Deploy Release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [ build-windows, build-macos, build-linux ]
|
||||||
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
|
steps:
|
||||||
|
- name: Checkout Source
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
sparse-checkout: |
|
||||||
|
Dockerfile
|
||||||
|
sparse-checkout-cone-mode: false
|
||||||
|
|
||||||
|
- name: Download Binaries
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
|
||||||
|
- name: Compress Binaries
|
||||||
|
run: |
|
||||||
|
for dir in */; do
|
||||||
|
if [[ $dir == *"windows"* ]]; then
|
||||||
|
cd "$dir" && zip -r "../${dir%/}.zip" . && cd ..
|
||||||
|
else
|
||||||
|
tar -czvf "${dir%/}.tar.gz" -C "$dir" .
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
- name: Create Release
|
||||||
|
uses: "marvinpinto/action-automatic-releases@latest"
|
||||||
|
with:
|
||||||
|
repo_token: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
|
prerelease: false
|
||||||
|
draft: true
|
||||||
|
files: |
|
||||||
|
*.zip
|
||||||
|
*.tar.gz
|
||||||
|
|
||||||
|
- name: Build and Publish Docker Image
|
||||||
|
uses: VaultVulp/gp-docker-action@1.6.0
|
||||||
|
with:
|
||||||
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
image-name: gsc-tool
|
||||||
|
extract-git-tag: true
|
||||||
|
additional-image-tags: latest
|
17
.gitignore
vendored
17
.gitignore
vendored
@ -149,18 +149,15 @@ user*.bat
|
|||||||
# VScode
|
# VScode
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|
||||||
|
# Output folders
|
||||||
|
renamed/
|
||||||
|
parsed/
|
||||||
compiled/
|
compiled/
|
||||||
decompiled/
|
decompiled/
|
||||||
assembled/
|
assembled/
|
||||||
disassembled/
|
disassembled/
|
||||||
|
|
||||||
data/iw5/
|
data/*
|
||||||
data/iw6/
|
|
||||||
data/iw7/
|
# Version file
|
||||||
data/iw8/
|
include/xsk/version.hpp
|
||||||
data/h1/
|
|
||||||
data/h2/
|
|
||||||
data/s1/
|
|
||||||
data/s2/
|
|
||||||
data/s4/
|
|
||||||
data/t6/
|
|
||||||
|
4
.gitmodules
vendored
4
.gitmodules
vendored
@ -1,3 +1,7 @@
|
|||||||
[submodule "deps/zlib"]
|
[submodule "deps/zlib"]
|
||||||
path = deps/zlib
|
path = deps/zlib
|
||||||
url = https://github.com/madler/zlib
|
url = https://github.com/madler/zlib
|
||||||
|
branch = master
|
||||||
|
[submodule "deps/cxxopts"]
|
||||||
|
path = deps/cxxopts
|
||||||
|
url = https://github.com/jarro2783/cxxopts.git
|
||||||
|
10
Dockerfile
Normal file
10
Dockerfile
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
FROM alpine:3.19
|
||||||
|
|
||||||
|
RUN apk add --no-cache gcompat libstdc++
|
||||||
|
|
||||||
|
COPY --chmod=755 ./linux-x64-release/gsc-tool /usr/local/bin/
|
||||||
|
|
||||||
|
RUN addgroup -S gsc-tool && adduser -S gsc-tool -G gsc-tool
|
||||||
|
USER gsc-tool
|
||||||
|
|
||||||
|
ENTRYPOINT ["/usr/local/bin/gsc-tool"]
|
97
README.md
97
README.md
@ -1,38 +1,52 @@
|
|||||||
[![Build status](https://ci.appveyor.com/api/projects/status/defmhg4753c1ap1o?svg=true)](https://ci.appveyor.com/project/xensik/gsc-tool)
|
[![sonar](https://sonarcloud.io/api/project_badges/measure?project=xensik_gsc-tool&metric=alert_status)](https://sonarcloud.io/summary/overall?id=xensik_gsc-tool)
|
||||||
![license](https://img.shields.io/github/license/xensik/gsc-tool.svg)
|
[![build](https://github.com/xensik/gsc-tool/workflows/Build/badge.svg)](https://github.com/xensik/gsc-tool/actions)
|
||||||
[![GitHub issues](https://img.shields.io/github/issues/xensik/gsc-tool)](https://github.com/xensik/gsc-tool/issues)
|
[![issues](https://img.shields.io/github/issues/xensik/gsc-tool)](https://github.com/xensik/gsc-tool/issues)
|
||||||
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/xensik/gsc-tool)](https://github.com/xensik/gsc-tool/releases)
|
[![license](https://img.shields.io/github/license/xensik/gsc-tool.svg)](https://github.com/xensik/gsc-tool/blob/dev/LICENSE)
|
||||||
|
[![releases](https://img.shields.io/github/v/release/xensik/gsc-tool)](https://github.com/xensik/gsc-tool/releases)
|
||||||
|
[![paypal](https://img.shields.io/badge/PayPal-support-blue.svg?logo=paypal)](https://www.paypal.me/xensik)
|
||||||
|
|
||||||
# GSC Tool
|
# GSC Tool
|
||||||
A utility to compile & decompile IW engine game scripts.
|
A utility to compile & decompile IW engine game scripts.
|
||||||
|
|
||||||
## Supported Games
|
## Supported Games
|
||||||
- **IW5** *(Call of Duty: Modern Warfare 3)*
|
- **IW5** *(Call of Duty: Modern Warfare 3)* `PC` `PS3` `Xbox 360`
|
||||||
- **IW6** *(Call of Duty: Ghosts)*
|
- **IW6** *(Call of Duty: Ghosts)* `PC` `PS3` `PS4` `Xbox 360` `Xbox One`
|
||||||
- **IW7** *(Call of Duty: Infinite Warfare)*
|
- **IW7** *(Call of Duty: Infinite Warfare)* `PC` `PS4` `Xbox One`
|
||||||
- **IW8** *(Call of Duty: Modern Warfare (2019))*
|
- **IW8** *(Call of Duty: Modern Warfare (2019) / Warzone)* `PC` `PS4` `PS5` `Xbox One` `Xbox Series X|S`
|
||||||
- **S1** *(Call of Duty: Advanced Warfare)*
|
- **IW9** *(Call of Duty: Modern Warfare II (2022) / Warzone 2)* `PC` `PS4` `PS5` `Xbox One` `Xbox Series X|S`
|
||||||
- **S2** *(Call of Duty: WWII)*
|
- **S1** *(Call of Duty: Advanced Warfare)* `PC` `PS3` `PS4` `Xbox 360` `Xbox One`
|
||||||
- **S4** *(Call of Duty: Vanguard)*
|
- **S2** *(Call of Duty: WWII)* `PC` `PS4` `Xbox One`
|
||||||
- **H1** *(Call of Duty: Modern Warfare Remastered)*
|
- **S4** *(Call of Duty: Vanguard)* `PC` `PS4` `PS5` `Xbox One` `Xbox Series X|S`
|
||||||
- **H2** *(Call of Duty: Modern Warfare 2 Campaign Remastered)*
|
- **H1** *(Call of Duty: Modern Warfare Remastered)* `PC` `PS4` `Xbox One`
|
||||||
- **T4** *(Call of Duty: World at War)* ***\*WIP\****
|
- **H2** *(Call of Duty: Modern Warfare 2 Campaign Remastered)* `PC` `PS4` `PS5` `Xbox One` `Xbox Series X|S`
|
||||||
- **T5** *(Call of Duty: Black Ops)* ***\*WIP\****
|
- **T6** *(Call of Duty: Black Ops II)* `PC` `PS3` `Xbox 360` `Wii U`
|
||||||
- **T6** *(Call of Duty: Black Ops II)*
|
- **T7** *(Call of Duty: Black Ops III)* `PC` *(Decompiler)*
|
||||||
- **T7** *(Call of Duty: Black Ops III)* ***\*WIP\****
|
- **T8** *(Call of Duty: Black Ops 4)* ***\*WIP\****
|
||||||
|
- **T9** *(Call of Duty: Black Ops Cold War)* ***\*WIP\****
|
||||||
|
- **JUP** *(Call of Duty: Modern Warfare III (2023)* ***\*WIP\****
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
``./gsc-tool.exe <mode> <game> <path>``
|
``gsc-tool [OPTIONS..] <path>``
|
||||||
|
|
||||||
**modes**: `asm`, `disasm`, `comp`, `decomp`
|
- **path**: file or directory to process
|
||||||
|
|
||||||
**games**: `iw5`, `iw6`, `iw7`, `iw8`, `s1`, `s2`, `s4`, `h1`, `h2`, `t6`
|
- **options:**
|
||||||
|
|
||||||
**paths**: `file`, `directory` (recursive process all files inside dir)
|
``-m, --mode <mode>`` [REQUIRED] one of: `asm`, `disasm`, `comp`, `decomp`, `parse`
|
||||||
|
|
||||||
for zonetool files (*.cgsc*, *.cgsc.stack*) use: `zasm`, `zdisasm`, `zcomp`, `zdecomp` modes
|
``-g, --game <game>`` [REQUIRED] one of: `iw5`, `iw6`, `iw7`, `iw8`, `iw9`, `s1`, `s2`, `s4`, `h1`, `h2`, `t6` `t7` `t8` `t9` `jup`
|
||||||
|
|
||||||
Example: ``./gsc-tool.exe comp iw5 ./data/iw5/my_fancy_script.gsc``
|
``-s, --system <system>`` [REQUIRED] one of: `pc`, `ps3`, `ps4`, `ps5`, `xb2` (*360*), `xb3` (*One*), `xb4` (*Series X|S*), `wiiu`
|
||||||
|
|
||||||
|
``-d, --dev`` Enable developer mode (dev blocks & generate bytecode map).
|
||||||
|
|
||||||
|
``-z, --zonetool`` Enable zonetool mode (use .cgsc files).
|
||||||
|
|
||||||
|
``-h, --help`` Display help.
|
||||||
|
|
||||||
|
``-v, --version`` Display version.
|
||||||
|
|
||||||
|
Example: ``gsc-tool -m comp -g iw5 -s pc ./data/iw5/my_fancy_script.gsc``
|
||||||
|
|
||||||
| Mode |Description | Output |
|
| Mode |Description | Output |
|
||||||
|:---------|:--------------------------|:------------|
|
|:---------|:--------------------------|:------------|
|
||||||
@ -40,24 +54,41 @@ Example: ``./gsc-tool.exe comp iw5 ./data/iw5/my_fancy_script.gsc``
|
|||||||
|`disasm` |dissasemble a `file.gscbin`|`file.gscasm`|
|
|`disasm` |dissasemble a `file.gscbin`|`file.gscasm`|
|
||||||
|`comp` |compile a `file.gsc` |`file.gscbin`|
|
|`comp` |compile a `file.gsc` |`file.gscbin`|
|
||||||
|`decomp` |decompile a `file.gscbin` |`file.gsc` |
|
|`decomp` |decompile a `file.gscbin` |`file.gsc` |
|
||||||
|
|`parse` |parse a `file.gsc` |`file.gsc` |
|
||||||
|
|
||||||
## File Format
|
## File Format
|
||||||
If you need to extract scripts from fastfiles or game memory, use [Zonetool](https://github.com/ZoneTool/zonetool) or [Jekyll](https://github.com/EthanC/Jekyll).
|
If you need to extract scripts from fastfiles or game memory, use [Zonetool](https://github.com/ZoneTool/zonetool) or [Jekyll](https://github.com/EthanC/Jekyll).
|
||||||
|
|
||||||
- gsc-tool ``.gscbin`` format is a serialized ScriptFile struct: <br/>
|
- gsc-tool `.gscbin` binary format is a serialized ScriptFile struct: <br/>
|
||||||
***name***: null-terminated string <br/>
|
|
||||||
***compressedLen***: 4 byte uint <br/>
|
|
||||||
***len***: 4 byte uint <br/>
|
|
||||||
***bytecodeLen***: 4 byte uint <br/>
|
|
||||||
***buffer***: byte array[compressedLen] <br/>
|
|
||||||
***bytecode***: byte array[bytecodeLen] <br/>
|
|
||||||
|
|
||||||
- zonetool (IW5) format made of bytecode file ``.cgsc`` and decompressed stack buffer ``.cgsc.stack``.
|
- ***magic***: `"GSC\0"` 4 byte <br/>
|
||||||
|
- ***compressedLen***: 4 byte usigned integer <br/>
|
||||||
|
- ***len***: 4 byte usigned integer <br/>
|
||||||
|
- ***bytecodeLen***: 4 byte usigned integer <br/>
|
||||||
|
- ***buffer***: byte array[compressedLen] <br/>
|
||||||
|
- ***bytecode***: byte array[bytecodeLen] <br/>
|
||||||
|
|
||||||
- treyarch (T6) format is a single buffer with gscobj data ``.gsc`` or ``.csc``.
|
note: for PS3 & Xbox 360 `.gscbin` files *(compressedLen, len, bytecodeLen)* are saved as little-endian!!
|
||||||
|
|
||||||
|
- zonetool (IW5) format made of bytecode file `.cgsc` and decompressed stack buffer `.cgsc.stack`.
|
||||||
|
|
||||||
|
- treyarch (T6) format is a single buffer with gscobj data `.gsc` or `.csc`.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
- install [*premake5*](https://premake.github.io) on your system PATH
|
||||||
|
- clone this repository
|
||||||
|
- update the submodules ``git submodule update --init --recursive``
|
||||||
|
- run prebuild script ``premake5 vs2022`` (windows) or ``premake5 gmake2`` (linux/macos)
|
||||||
|
|
||||||
|
## Contribute
|
||||||
|
If you like my work, consider sponsoring/donating! Would allow me to spend more time adding new features & fixing bugs.
|
||||||
|
|
||||||
|
BTC: bc1qky7x9kpjlt6nsvt7pckc3wwzk8rk9pgtnmw98u\
|
||||||
|
ETH: 0x6261BBE1a33F6Fec4b722DbCe2c28B4CC02c9C7B\
|
||||||
|
[![pypl](https://img.shields.io/badge/PayPal-00457C?style=for-the-badge&logo=paypal&logoColor=white)](https://www.paypal.me/xensik) [![kofi](https://img.shields.io/badge/Ko--fi-F16061?style=for-the-badge&logo=ko-fi&logoColor=white)](https://ko-fi.com/xensik)
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
This project is based on [*RektInator's* gsc-asm](https://github.com/ZoneTool/gsc-asm). Special thanks to **RektInator**, **JTAG** & **Dasfonia**.
|
This project is based on [*RektInator's* gsc-asm](https://github.com/ZoneTool/gsc-asm). Special thanks to **RektInator**, **JTAG** & **Dasfonia**.
|
||||||
|
|
||||||
## Disclaimer
|
## Disclaimer
|
||||||
This software has been created purely for the purposes of academic research. Project maintainers are not responsible or liable for misuse of the software. Use responsibly.
|
This software has been created purely for the purposes of academic research. Project maintainers are not responsible or liable for misuse of the software. Use responsibly.
|
||||||
|
20
appveyor.yml
20
appveyor.yml
@ -1,20 +0,0 @@
|
|||||||
version: 1.0.{build}
|
|
||||||
skip_tags: true
|
|
||||||
image: Visual Studio 2022
|
|
||||||
configuration: Release
|
|
||||||
platform: x64
|
|
||||||
before_build:
|
|
||||||
- git submodule update --init --recursive
|
|
||||||
- ps: tools\windows\premake5.exe vs2022
|
|
||||||
build:
|
|
||||||
project: build/gsc-tool.sln
|
|
||||||
verbosity: minimal
|
|
||||||
test: false
|
|
||||||
artifacts:
|
|
||||||
- path: build/bin/release/gsc-tool.exe
|
|
||||||
deploy:
|
|
||||||
- provider: GitHub
|
|
||||||
auth_token:
|
|
||||||
secure: VTY5eMFd/IOYDIZQeMM0J0uYss+wmTwreE+Hi0lXAQABQ/4igmCvqCFZ5DsrWhY/
|
|
||||||
on:
|
|
||||||
branch: prod
|
|
1
deps/cxxopts
vendored
Submodule
1
deps/cxxopts
vendored
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit eb787304d67ec22f7c3a184ee8b4c481d04357fd
|
11
deps/cxxopts.lua
vendored
Normal file
11
deps/cxxopts.lua
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
cxxopts = { base = path.join(dependencies.base, "cxxopts") }
|
||||||
|
|
||||||
|
function cxxopts:include()
|
||||||
|
includedirs { path.join(cxxopts.base, "include") }
|
||||||
|
end
|
||||||
|
|
||||||
|
function cxxopts:link()
|
||||||
|
self:include()
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(dependencies, cxxopts)
|
2
deps/zlib
vendored
2
deps/zlib
vendored
@ -1 +1 @@
|
|||||||
Subproject commit 21767c654d31d2dccdde4330529775c6c5fd5389
|
Subproject commit 09155eaa2f9270dc4ed1fa13e2b4b2613e6e4851
|
22
deps/zlib.lua
vendored
22
deps/zlib.lua
vendored
@ -15,20 +15,24 @@ function zlib:project()
|
|||||||
language "C"
|
language "C"
|
||||||
warnings "off"
|
warnings "off"
|
||||||
|
|
||||||
|
if os.istarget("linux") or os.istarget("macosx") then
|
||||||
|
defines {
|
||||||
|
"HAVE_UNISTD_H"
|
||||||
|
}
|
||||||
|
elseif os.istarget("windows") then
|
||||||
|
defines {
|
||||||
|
"_CRT_SECURE_NO_WARNINGS",
|
||||||
|
"_CRT_NONSTDC_NO_DEPRECATE",
|
||||||
|
"_CRT_SECURE_NO_DEPRECATE",
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
self:include()
|
self:include()
|
||||||
|
|
||||||
files
|
files {
|
||||||
{
|
|
||||||
path.join(zlib.base, "*.h"),
|
path.join(zlib.base, "*.h"),
|
||||||
path.join(zlib.base, "*.c")
|
path.join(zlib.base, "*.c")
|
||||||
}
|
}
|
||||||
|
|
||||||
defines
|
|
||||||
{
|
|
||||||
"_CRT_SECURE_NO_WARNINGS",
|
|
||||||
"_CRT_NONSTDC_NO_DEPRECATE",
|
|
||||||
"_CRT_SECURE_NO_DEPRECATE",
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
table.insert(dependencies, zlib)
|
table.insert(dependencies, zlib)
|
||||||
|
@ -1 +0,0 @@
|
|||||||
# GSC Syntax
|
|
10
gen/arc/Makefile
Normal file
10
gen/arc/Makefile
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
generate: arc
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf ./parser.hpp
|
||||||
|
rm -rf ./parser.cpp
|
||||||
|
|
||||||
|
arc: parser.ypp
|
||||||
|
bison parser.ypp -Wcounterexamples
|
||||||
|
mv parser.hpp ../../include/xsk/arc/
|
||||||
|
mv parser.cpp ../../src/arc/
|
1351
gen/arc/parser.ypp
Normal file
1351
gen/arc/parser.ypp
Normal file
File diff suppressed because it is too large
Load Diff
10
gen/gsc/Makefile
Normal file
10
gen/gsc/Makefile
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
generate: gsc
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf ./parser.hpp
|
||||||
|
rm -rf ./parser.cpp
|
||||||
|
|
||||||
|
gsc: parser.ypp
|
||||||
|
bison parser.ypp -Wcounterexamples
|
||||||
|
mv parser.hpp ../../include/xsk/gsc/
|
||||||
|
mv parser.cpp ../../src/gsc/
|
1249
gen/gsc/parser.ypp
Normal file
1249
gen/gsc/parser.ypp
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,9 +0,0 @@
|
|||||||
generate: H1
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf ./parser.hpp
|
|
||||||
rm -rf ./parser.cpp
|
|
||||||
|
|
||||||
H1: parser.ypp
|
|
||||||
bison parser.ypp -Wcounterexamples
|
|
||||||
mv parser.hpp parser.cpp ../../src/h1/xsk/
|
|
@ -1,875 +0,0 @@
|
|||||||
/* Copyright 2022 xensik. All rights reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a GNU GPLv3 license
|
|
||||||
// that can be found in the LICENSE file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
%require "3.7"
|
|
||||||
%skeleton "lalr1.cc"
|
|
||||||
%language "c++"
|
|
||||||
%output "parser.cpp"
|
|
||||||
%defines "parser.hpp"
|
|
||||||
%define api.prefix {H1}
|
|
||||||
%define api.namespace {xsk::gsc::h1}
|
|
||||||
%define api.location.type {xsk::gsc::location}
|
|
||||||
%define api.value.type variant
|
|
||||||
%define api.token.constructor
|
|
||||||
%define api.token.raw
|
|
||||||
%define parse.assert
|
|
||||||
%define parse.trace
|
|
||||||
%define parse.error detailed
|
|
||||||
%define parse.lac full
|
|
||||||
%locations
|
|
||||||
%lex-param { xsk::gsc::h1::lexer& lexer }
|
|
||||||
%parse-param { xsk::gsc::h1::lexer& lexer }
|
|
||||||
%parse-param { xsk::gsc::ast::program::ptr& ast }
|
|
||||||
|
|
||||||
%code requires
|
|
||||||
{
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(disable:4065)
|
|
||||||
#pragma warning(disable:4127)
|
|
||||||
#endif
|
|
||||||
#include "h1.hpp"
|
|
||||||
namespace xsk::gsc::h1 { class lexer; }
|
|
||||||
}
|
|
||||||
|
|
||||||
%code top
|
|
||||||
{
|
|
||||||
#include "stdafx.hpp"
|
|
||||||
#include "parser.hpp"
|
|
||||||
#include "lexer.hpp"
|
|
||||||
using namespace xsk::gsc;
|
|
||||||
xsk::gsc::h1::parser::symbol_type H1lex(xsk::gsc::h1::lexer& lexer);
|
|
||||||
}
|
|
||||||
|
|
||||||
%token SH_DEFINE "#define"
|
|
||||||
%token SH_UNDEF "#undef"
|
|
||||||
%token SH_IFDEF "#ifdef"
|
|
||||||
%token SH_IFNDEF "#ifndef"
|
|
||||||
%token SH_IF "#if"
|
|
||||||
%token SH_ELIF "#elif"
|
|
||||||
%token SH_ELSE "#else"
|
|
||||||
%token SH_ENDIF "#endif"
|
|
||||||
%token DEVBEGIN "/#"
|
|
||||||
%token DEVEND "#/"
|
|
||||||
%token INLINE "#inline"
|
|
||||||
%token INCLUDE "#include"
|
|
||||||
%token USINGTREE "#using_animtree"
|
|
||||||
%token ANIMTREE "#animtree"
|
|
||||||
%token ENDON "endon"
|
|
||||||
%token NOTIFY "notify"
|
|
||||||
%token WAIT "wait"
|
|
||||||
%token WAITTILL "waittill"
|
|
||||||
%token WAITTILLMATCH "waittillmatch"
|
|
||||||
%token WAITTILLFRAMEEND "waittillframeend"
|
|
||||||
%token WAITFRAME "waitframe"
|
|
||||||
%token IF "if"
|
|
||||||
%token ELSE "else"
|
|
||||||
%token DO "do"
|
|
||||||
%token WHILE "while"
|
|
||||||
%token FOR "for"
|
|
||||||
%token FOREACH "foreach"
|
|
||||||
%token IN "in"
|
|
||||||
%token SWITCH "switch"
|
|
||||||
%token CASE "case"
|
|
||||||
%token DEFAULT "default"
|
|
||||||
%token BREAK "break"
|
|
||||||
%token CONTINUE "continue"
|
|
||||||
%token RETURN "return"
|
|
||||||
%token BREAKPOINT "breakpoint"
|
|
||||||
%token PROFBEGIN "prof_begin"
|
|
||||||
%token PROFEND "prof_end"
|
|
||||||
%token THREAD "thread"
|
|
||||||
%token CHILDTHREAD "childthread"
|
|
||||||
%token THISTHREAD "thisthread"
|
|
||||||
%token CALL "call"
|
|
||||||
%token TRUE "true"
|
|
||||||
%token FALSE "false"
|
|
||||||
%token UNDEFINED "undefined"
|
|
||||||
%token SIZE "size"
|
|
||||||
%token GAME "game"
|
|
||||||
%token SELF "self"
|
|
||||||
%token ANIM "anim"
|
|
||||||
%token LEVEL "level"
|
|
||||||
%token LPAREN "("
|
|
||||||
%token RPAREN ")"
|
|
||||||
%token LBRACE "{"
|
|
||||||
%token RBRACE "}"
|
|
||||||
%token LBRACKET "["
|
|
||||||
%token RBRACKET "]"
|
|
||||||
%token COMMA ","
|
|
||||||
%token DOT "."
|
|
||||||
%token DOUBLECOLON "::"
|
|
||||||
%token COLON ":"
|
|
||||||
%token SEMICOLON ";"
|
|
||||||
%token QMARK "?"
|
|
||||||
%token INCREMENT "++"
|
|
||||||
%token DECREMENT "--"
|
|
||||||
%token LSHIFT "<<"
|
|
||||||
%token RSHIFT ">>"
|
|
||||||
%token OR "||"
|
|
||||||
%token AND "&&"
|
|
||||||
%token EQUALITY "=="
|
|
||||||
%token INEQUALITY "!="
|
|
||||||
%token LESS_EQUAL "<="
|
|
||||||
%token GREATER_EQUAL ">="
|
|
||||||
%token LESS "<"
|
|
||||||
%token GREATER ">"
|
|
||||||
%token NOT "!"
|
|
||||||
%token COMPLEMENT "~"
|
|
||||||
%token ASSIGN "="
|
|
||||||
%token ASSIGN_ADD "+="
|
|
||||||
%token ASSIGN_SUB "-="
|
|
||||||
%token ASSIGN_MUL "*="
|
|
||||||
%token ASSIGN_DIV "/="
|
|
||||||
%token ASSIGN_MOD "%="
|
|
||||||
%token ASSIGN_BW_OR "|="
|
|
||||||
%token ASSIGN_BW_AND "&="
|
|
||||||
%token ASSIGN_BW_EXOR "^="
|
|
||||||
%token ASSIGN_RSHIFT ">>="
|
|
||||||
%token ASSIGN_LSHIFT "<<="
|
|
||||||
%token BITWISE_OR "|"
|
|
||||||
%token BITWISE_AND "&"
|
|
||||||
%token BITWISE_EXOR "^"
|
|
||||||
%token ADD "+"
|
|
||||||
%token SUB "-"
|
|
||||||
%token MUL "*"
|
|
||||||
%token DIV "/"
|
|
||||||
%token MOD "%"
|
|
||||||
%token <std::string> PATH "path"
|
|
||||||
%token <std::string> IDENTIFIER "identifier"
|
|
||||||
%token <std::string> STRING "string literal"
|
|
||||||
%token <std::string> ISTRING "localized string"
|
|
||||||
%token <std::string> FLOAT "float"
|
|
||||||
%token <std::string> INTEGER "integer"
|
|
||||||
|
|
||||||
%type <ast::program::ptr> program
|
|
||||||
%type <ast::include::ptr> include
|
|
||||||
%type <ast::decl> declaration
|
|
||||||
%type <ast::decl_usingtree::ptr> decl_usingtree
|
|
||||||
%type <ast::decl_constant::ptr> decl_constant
|
|
||||||
%type <ast::decl_thread::ptr> decl_thread
|
|
||||||
%type <ast::stmt> stmt
|
|
||||||
%type <ast::stmt> stmt_or_dev
|
|
||||||
%type <ast::stmt_list::ptr> stmt_list
|
|
||||||
%type <ast::stmt_list::ptr> stmt_or_dev_list
|
|
||||||
%type <ast::stmt_dev::ptr> stmt_dev
|
|
||||||
%type <ast::stmt_list::ptr> stmt_block
|
|
||||||
%type <ast::stmt_expr::ptr> stmt_expr
|
|
||||||
%type <ast::stmt_call::ptr> stmt_call
|
|
||||||
%type <ast::stmt_assign::ptr> stmt_assign
|
|
||||||
%type <ast::stmt_endon::ptr> stmt_endon
|
|
||||||
%type <ast::stmt_notify::ptr> stmt_notify
|
|
||||||
%type <ast::stmt_wait::ptr> stmt_wait
|
|
||||||
%type <ast::stmt_waittill::ptr> stmt_waittill
|
|
||||||
%type <ast::stmt_waittillmatch::ptr> stmt_waittillmatch
|
|
||||||
%type <ast::stmt_waittillframeend::ptr> stmt_waittillframeend
|
|
||||||
%type <ast::stmt_waitframe::ptr> stmt_waitframe
|
|
||||||
%type <ast::stmt_if::ptr> stmt_if
|
|
||||||
%type <ast::stmt_ifelse::ptr> stmt_ifelse
|
|
||||||
%type <ast::stmt_while::ptr> stmt_while
|
|
||||||
%type <ast::stmt_dowhile::ptr> stmt_dowhile
|
|
||||||
%type <ast::stmt_for::ptr> stmt_for
|
|
||||||
%type <ast::stmt_foreach::ptr> stmt_foreach
|
|
||||||
%type <ast::stmt_switch::ptr> stmt_switch
|
|
||||||
%type <ast::stmt_case::ptr> stmt_case
|
|
||||||
%type <ast::stmt_default::ptr> stmt_default
|
|
||||||
%type <ast::stmt_break::ptr> stmt_break
|
|
||||||
%type <ast::stmt_continue::ptr> stmt_continue
|
|
||||||
%type <ast::stmt_return::ptr> stmt_return
|
|
||||||
%type <ast::stmt_breakpoint::ptr> stmt_breakpoint
|
|
||||||
%type <ast::stmt_prof_begin::ptr> stmt_prof_begin
|
|
||||||
%type <ast::stmt_prof_end::ptr> stmt_prof_end
|
|
||||||
%type <ast::expr> expr
|
|
||||||
%type <ast::expr> expr_or_empty
|
|
||||||
%type <ast::expr> expr_assign
|
|
||||||
%type <ast::expr> expr_increment
|
|
||||||
%type <ast::expr> expr_decrement
|
|
||||||
%type <ast::expr> expr_ternary
|
|
||||||
%type <ast::expr> expr_binary
|
|
||||||
%type <ast::expr> expr_primitive
|
|
||||||
%type <ast::expr_complement::ptr> expr_complement
|
|
||||||
%type <ast::expr_negate::ptr> expr_negate
|
|
||||||
%type <ast::expr_not::ptr> expr_not
|
|
||||||
%type <ast::expr_call::ptr> expr_call
|
|
||||||
%type <ast::expr_method::ptr> expr_method
|
|
||||||
%type <ast::call> expr_function
|
|
||||||
%type <ast::call> expr_pointer
|
|
||||||
%type <ast::expr_add_array::ptr> expr_add_array
|
|
||||||
%type <ast::expr_parameters::ptr> expr_parameters
|
|
||||||
%type <ast::expr_arguments::ptr> expr_arguments
|
|
||||||
%type <ast::expr_arguments::ptr> expr_arguments_no_empty
|
|
||||||
%type <ast::expr_reference::ptr> expr_reference
|
|
||||||
%type <ast::expr_array::ptr> expr_array
|
|
||||||
%type <ast::expr_field::ptr> expr_field
|
|
||||||
%type <ast::expr_size::ptr> expr_size
|
|
||||||
%type <ast::expr_paren::ptr> expr_paren
|
|
||||||
%type <ast::expr> expr_object
|
|
||||||
%type <ast::expr_thisthread::ptr> expr_thisthread
|
|
||||||
%type <ast::expr_empty_array::ptr> expr_empty_array
|
|
||||||
%type <ast::expr_undefined::ptr> expr_undefined
|
|
||||||
%type <ast::expr_game::ptr> expr_game
|
|
||||||
%type <ast::expr_self::ptr> expr_self
|
|
||||||
%type <ast::expr_anim::ptr> expr_anim
|
|
||||||
%type <ast::expr_level::ptr> expr_level
|
|
||||||
%type <ast::expr_animation::ptr> expr_animation
|
|
||||||
%type <ast::expr_animtree::ptr> expr_animtree
|
|
||||||
%type <ast::expr_identifier::ptr> expr_identifier_nosize
|
|
||||||
%type <ast::expr_identifier::ptr> expr_identifier
|
|
||||||
%type <ast::expr_path::ptr> expr_path
|
|
||||||
%type <ast::expr_istring::ptr> expr_istring
|
|
||||||
%type <ast::expr_string::ptr> expr_string
|
|
||||||
%type <ast::expr_vector::ptr> expr_vector
|
|
||||||
%type <ast::expr_float::ptr> expr_float
|
|
||||||
%type <ast::expr_integer::ptr> expr_integer
|
|
||||||
%type <ast::expr_false::ptr> expr_false
|
|
||||||
%type <ast::expr_true::ptr> expr_true
|
|
||||||
|
|
||||||
%nonassoc SIZEOF
|
|
||||||
%nonassoc ADD_ARRAY
|
|
||||||
%nonassoc RBRACKET
|
|
||||||
%nonassoc THEN
|
|
||||||
%nonassoc ELSE
|
|
||||||
%nonassoc INCREMENT DECREMENT
|
|
||||||
|
|
||||||
%precedence TERN
|
|
||||||
%right QMARK
|
|
||||||
%left OR
|
|
||||||
%left AND
|
|
||||||
%left BITWISE_OR
|
|
||||||
%left BITWISE_EXOR
|
|
||||||
%left BITWISE_AND
|
|
||||||
%left EQUALITY INEQUALITY
|
|
||||||
%left LESS GREATER LESS_EQUAL GREATER_EQUAL
|
|
||||||
%left LSHIFT RSHIFT
|
|
||||||
%left ADD SUB
|
|
||||||
%left MUL DIV MOD
|
|
||||||
%right NOT COMPLEMENT
|
|
||||||
|
|
||||||
%precedence NEG
|
|
||||||
%precedence ANIMREF
|
|
||||||
%precedence PREINC PREDEC
|
|
||||||
%precedence POSTINC POSTDEC
|
|
||||||
|
|
||||||
%start root
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
root
|
|
||||||
: program { ast = std::move($1); }
|
|
||||||
| { ast = std::make_unique<ast::program>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
program
|
|
||||||
: program inline
|
|
||||||
{ $$ = std::move($1); }
|
|
||||||
| program include
|
|
||||||
{ $$ = std::move($1); $$->includes.push_back(std::move($2)); }
|
|
||||||
| program declaration
|
|
||||||
{ $$ = std::move($1); $$->declarations.push_back(std::move($2)); }
|
|
||||||
| inline
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); }
|
|
||||||
| include
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); $$->includes.push_back(std::move($1)); }
|
|
||||||
| declaration
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); $$->declarations.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
inline
|
|
||||||
: INLINE expr_path SEMICOLON { lexer.push_header($2->value); }
|
|
||||||
;
|
|
||||||
|
|
||||||
include
|
|
||||||
: INCLUDE expr_path SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::include>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
declaration
|
|
||||||
: DEVBEGIN { $$.as_dev_begin = std::make_unique<ast::decl_dev_begin>(@$); }
|
|
||||||
| DEVEND { $$.as_dev_end = std::make_unique<ast::decl_dev_end>(@$); }
|
|
||||||
| decl_usingtree { $$.as_usingtree = std::move($1); }
|
|
||||||
| decl_constant { $$.as_constant = std::move($1); }
|
|
||||||
| decl_thread { $$.as_thread = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_usingtree
|
|
||||||
: USINGTREE LPAREN expr_string RPAREN SEMICOLON
|
|
||||||
{ lexer.ban_header(@$); $$ = std::make_unique<ast::decl_usingtree>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_constant
|
|
||||||
: expr_identifier ASSIGN expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::decl_constant>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_thread
|
|
||||||
: expr_identifier LPAREN expr_parameters RPAREN stmt_block
|
|
||||||
{ lexer.ban_header(@$); $$ = std::make_unique<ast::decl_thread>(@$, std::move($1), std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt
|
|
||||||
: stmt_block { $$.as_list = std::move($1); }
|
|
||||||
| stmt_call { $$.as_call = std::move($1); }
|
|
||||||
| stmt_assign { $$.as_assign = std::move($1); }
|
|
||||||
| stmt_endon { $$.as_endon = std::move($1); }
|
|
||||||
| stmt_notify { $$.as_notify = std::move($1); }
|
|
||||||
| stmt_wait { $$.as_wait = std::move($1); }
|
|
||||||
| stmt_waittill { $$.as_waittill = std::move($1); }
|
|
||||||
| stmt_waittillmatch { $$.as_waittillmatch = std::move($1); }
|
|
||||||
| stmt_waittillframeend { $$.as_waittillframeend = std::move($1); }
|
|
||||||
| stmt_waitframe { $$.as_waitframe = std::move($1); }
|
|
||||||
| stmt_if { $$.as_if = std::move($1); }
|
|
||||||
| stmt_ifelse { $$.as_ifelse = std::move($1); }
|
|
||||||
| stmt_while { $$.as_while = std::move($1); }
|
|
||||||
| stmt_dowhile { $$.as_dowhile = std::move($1); }
|
|
||||||
| stmt_for { $$.as_for = std::move($1); }
|
|
||||||
| stmt_foreach { $$.as_foreach = std::move($1); }
|
|
||||||
| stmt_switch { $$.as_switch = std::move($1); }
|
|
||||||
| stmt_case { $$.as_case = std::move($1); }
|
|
||||||
| stmt_default { $$.as_default = std::move($1); }
|
|
||||||
| stmt_break { $$.as_break = std::move($1); }
|
|
||||||
| stmt_continue { $$.as_continue = std::move($1); }
|
|
||||||
| stmt_return { $$.as_return = std::move($1); }
|
|
||||||
| stmt_breakpoint { $$.as_breakpoint = std::move($1); }
|
|
||||||
| stmt_prof_begin { $$.as_prof_begin = std::move($1); }
|
|
||||||
| stmt_prof_end { $$.as_prof_end = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_or_dev
|
|
||||||
: stmt { $$ = std::move($1); }
|
|
||||||
| stmt_dev { $$.as_dev = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_list
|
|
||||||
: stmt_list stmt
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($2)); }
|
|
||||||
| stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_list>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_or_dev_list
|
|
||||||
: stmt_or_dev_list stmt_or_dev
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($2)); }
|
|
||||||
| stmt_or_dev
|
|
||||||
{ $$ = std::make_unique<ast::stmt_list>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_dev
|
|
||||||
: DEVBEGIN stmt_list DEVEND { $$ = std::make_unique<ast::stmt_dev>(@$, std::move($2)); }
|
|
||||||
| DEVBEGIN DEVEND { $$ = std::make_unique<ast::stmt_dev>(@$, std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_block
|
|
||||||
: LBRACE stmt_or_dev_list RBRACE { $$ = std::move($2); }
|
|
||||||
| LBRACE RBRACE { $$ = std::make_unique<ast::stmt_list>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_expr
|
|
||||||
: expr_assign
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
| expr_increment
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
| expr_decrement
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::make_unique<ast::node>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_call
|
|
||||||
: expr_call SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_call>(@$, ast::expr(std::move($1))); }
|
|
||||||
| expr_method SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_call>(@$, ast::expr(std::move($1))); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_assign
|
|
||||||
: expr_assign SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
| expr_increment SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
| expr_decrement SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_endon
|
|
||||||
: expr_object ENDON LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_endon>(@$, std::move($1), std::move($4)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_notify
|
|
||||||
: expr_object NOTIFY LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_notify>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object NOTIFY LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_notify>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_wait
|
|
||||||
: WAIT expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_wait>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittill
|
|
||||||
: expr_object WAITTILL LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittill>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object WAITTILL LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittill>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittillmatch
|
|
||||||
: expr_object WAITTILLMATCH LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillmatch>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object WAITTILLMATCH LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillmatch>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittillframeend
|
|
||||||
: WAITTILLFRAMEEND SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillframeend>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waitframe
|
|
||||||
: WAITFRAME SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waitframe>(@$); }
|
|
||||||
| WAITFRAME LPAREN RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waitframe>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_if
|
|
||||||
: IF LPAREN expr RPAREN stmt %prec THEN
|
|
||||||
{ $$ = std::make_unique<ast::stmt_if>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_ifelse
|
|
||||||
: IF LPAREN expr RPAREN stmt ELSE stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_ifelse>(@$, std::move($3), std::move($5), std::move($7)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_while
|
|
||||||
: WHILE LPAREN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_while>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_dowhile
|
|
||||||
: DO stmt WHILE LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_dowhile>(@$, std::move($5), std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_for
|
|
||||||
: FOR LPAREN stmt_expr SEMICOLON expr_or_empty SEMICOLON stmt_expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_for>(@$, ast::stmt(std::move($3)), std::move($5), ast::stmt(std::move($7)), std::move($9)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_foreach
|
|
||||||
: FOREACH LPAREN expr_identifier IN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_foreach>(@$, ast::expr(std::move($3)), std::move($5), std::move($7)); }
|
|
||||||
| FOREACH LPAREN expr_identifier COMMA expr_identifier IN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_foreach>(@$, ast::expr(std::move($3)), ast::expr(std::move($5)), std::move($7), std::move($9)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_switch
|
|
||||||
: SWITCH LPAREN expr RPAREN stmt_block
|
|
||||||
{ $$ = std::make_unique<ast::stmt_switch>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_case
|
|
||||||
: CASE expr_integer COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_case>(@$, ast::expr(std::move($2)), std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
| CASE expr_string COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_case>(@$, ast::expr(std::move($2)), std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_default
|
|
||||||
: DEFAULT COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_default>(@$, std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_break
|
|
||||||
: BREAK SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_break>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_continue
|
|
||||||
: CONTINUE SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_continue>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_return
|
|
||||||
: RETURN expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_return>(@$, std::move($2)); }
|
|
||||||
| RETURN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_return>(@$, std::make_unique<ast::node>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_breakpoint
|
|
||||||
: BREAKPOINT SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_breakpoint>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_prof_begin
|
|
||||||
: PROFBEGIN LPAREN expr_arguments RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_prof_begin>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_prof_end
|
|
||||||
: PROFEND LPAREN expr_arguments RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_prof_end>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr
|
|
||||||
: expr_ternary { $$ = std::move($1); }
|
|
||||||
| expr_binary { $$ = std::move($1); }
|
|
||||||
| expr_primitive { $$ = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_or_empty
|
|
||||||
: expr { $$ = std::move($1); }
|
|
||||||
| { $$.as_node = std::make_unique<ast::node>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_assign
|
|
||||||
: expr_object ASSIGN expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_EXOR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_exor>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_LSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_shift_left>(@$, std::move($1),std::move( $3)); }
|
|
||||||
| expr_object ASSIGN_RSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_shift_right>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_ADD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_add>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_SUB expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_sub>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_MUL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_mul>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_DIV expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_div>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_MOD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_mod>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_increment
|
|
||||||
: INCREMENT expr_object %prec PREINC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_increment>(@$, std::move($2), true); }
|
|
||||||
| expr_object INCREMENT %prec POSTINC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_increment>(@$, std::move($1), false); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_decrement
|
|
||||||
: DECREMENT expr_object %prec PREDEC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_decrement>(@$, std::move($2), true); }
|
|
||||||
| expr_object DECREMENT %prec POSTDEC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_decrement>(@$, std::move($1), false); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_ternary
|
|
||||||
: expr QMARK expr COLON expr %prec TERN
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_ternary>(@$, std::move($1), std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_binary
|
|
||||||
: expr OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr EQUALITY expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_equality>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr INEQUALITY expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_inequality>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LESS_EQUAL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_less_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr GREATER_EQUAL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_greater_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LESS expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_less>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr GREATER expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_greater>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_EXOR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_exor>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_shift_left>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr RSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_shift_right>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr ADD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_add>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr SUB expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_sub>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr MUL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_mul>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr DIV expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_div>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr MOD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_mod>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_primitive
|
|
||||||
: expr_complement { $$.as_node = std::move($1); }
|
|
||||||
| expr_negate { $$.as_node = std::move($1); }
|
|
||||||
| expr_not { $$.as_node = std::move($1); }
|
|
||||||
| expr_call { $$.as_node = std::move($1); }
|
|
||||||
| expr_method { $$.as_node = std::move($1); }
|
|
||||||
| expr_add_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_reference { $$.as_node = std::move($1); }
|
|
||||||
| expr_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_field { $$.as_node = std::move($1); }
|
|
||||||
| expr_size { $$.as_node = std::move($1); }
|
|
||||||
| expr_paren { $$.as_node = std::move($1); }
|
|
||||||
| expr_thisthread { $$.as_node = std::move($1); }
|
|
||||||
| expr_empty_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_undefined { $$.as_node = std::move($1); }
|
|
||||||
| expr_game { $$.as_node = std::move($1); }
|
|
||||||
| expr_self { $$.as_node = std::move($1); }
|
|
||||||
| expr_anim { $$.as_node = std::move($1); }
|
|
||||||
| expr_level { $$.as_node = std::move($1); }
|
|
||||||
| expr_animation { $$.as_node = std::move($1); }
|
|
||||||
| expr_animtree { $$.as_node = std::move($1); }
|
|
||||||
| expr_identifier { $$.as_node = std::move($1); }
|
|
||||||
| expr_istring { $$.as_node = std::move($1); }
|
|
||||||
| expr_string { $$.as_node = std::move($1); }
|
|
||||||
| expr_vector { $$.as_node = std::move($1); }
|
|
||||||
| expr_float { $$.as_node = std::move($1); }
|
|
||||||
| expr_integer { $$.as_node = std::move($1); }
|
|
||||||
| expr_false { $$.as_node = std::move($1); }
|
|
||||||
| expr_true { $$.as_node = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_complement
|
|
||||||
: COMPLEMENT expr
|
|
||||||
{ $$ = std::make_unique<ast::expr_complement>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_negate
|
|
||||||
: SUB expr_identifier %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_paren %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_array %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_field %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_not
|
|
||||||
: NOT expr
|
|
||||||
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_call
|
|
||||||
: expr_function { $$ = std::make_unique<ast::expr_call>(@$, std::move($1)); }
|
|
||||||
| expr_pointer { $$ = std::make_unique<ast::expr_call>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
expr_method
|
|
||||||
: expr_object expr_function { $$ = std::make_unique<ast::expr_method>(@$, std::move($1), std::move($2)); }
|
|
||||||
| expr_object expr_pointer { $$ = std::make_unique<ast::expr_method>(@$, std::move($1), std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_function
|
|
||||||
: expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($1), std::move($3), ast::call::mode::normal); }
|
|
||||||
| expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($1), std::move($3), std::move($5), ast::call::mode::normal); }
|
|
||||||
| THREAD expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($2), std::move($4), ast::call::mode::thread); }
|
|
||||||
| THREAD expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($2), std::move($4), std::move($6), ast::call::mode::thread); }
|
|
||||||
| CHILDTHREAD expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($2), std::move($4), ast::call::mode::childthread); }
|
|
||||||
| CHILDTHREAD expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($2), std::move($4), std::move($6), ast::call::mode::childthread); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_pointer
|
|
||||||
: LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($3), std::move($7), ast::call::mode::normal); }
|
|
||||||
| THREAD LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::thread); }
|
|
||||||
| CHILDTHREAD LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::childthread); }
|
|
||||||
| CALL LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::builtin); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_add_array
|
|
||||||
: LBRACKET expr_arguments_no_empty RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_add_array>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_parameters
|
|
||||||
: expr_parameters COMMA expr_identifier
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($3)); }
|
|
||||||
| expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_parameters>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::expr_parameters>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_arguments
|
|
||||||
: expr_arguments_no_empty
|
|
||||||
{ $$ = std::move($1); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::expr_arguments>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_arguments_no_empty
|
|
||||||
: expr_arguments COMMA expr
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($3)); }
|
|
||||||
| expr %prec ADD_ARRAY
|
|
||||||
{ $$ = std::make_unique<ast::expr_arguments>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_reference
|
|
||||||
: DOUBLECOLON expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_reference>(@$, std::make_unique<ast::expr_path>(@$), std::move($2)); }
|
|
||||||
| expr_path DOUBLECOLON expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_reference>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_array
|
|
||||||
: expr_object LBRACKET expr RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_array>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_field
|
|
||||||
: expr_object DOT expr_identifier_nosize
|
|
||||||
{ $$ = std::make_unique<ast::expr_field>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_size
|
|
||||||
: expr_object DOT SIZE %prec SIZEOF
|
|
||||||
{ $$ = std::make_unique<ast::expr_size>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_paren
|
|
||||||
: LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_paren>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_object
|
|
||||||
: expr_call { $$.as_node = std::move($1); }
|
|
||||||
| expr_method { $$.as_node = std::move($1); }
|
|
||||||
| expr_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_field { $$.as_node = std::move($1); }
|
|
||||||
| expr_game { $$.as_node = std::move($1); }
|
|
||||||
| expr_self { $$.as_node = std::move($1); }
|
|
||||||
| expr_anim { $$.as_node = std::move($1); }
|
|
||||||
| expr_level { $$.as_node = std::move($1); }
|
|
||||||
| expr_identifier { $$.as_node = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_thisthread
|
|
||||||
: THISTHREAD
|
|
||||||
{ $$ = std::make_unique<ast::expr_thisthread>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_empty_array
|
|
||||||
: LBRACKET RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_empty_array>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_undefined
|
|
||||||
: UNDEFINED
|
|
||||||
{ $$ = std::make_unique<ast::expr_undefined>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_game
|
|
||||||
: GAME
|
|
||||||
{ $$ = std::make_unique<ast::expr_game>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_self
|
|
||||||
: SELF
|
|
||||||
{ $$ = std::make_unique<ast::expr_self>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_anim
|
|
||||||
: ANIM
|
|
||||||
{ $$ = std::make_unique<ast::expr_anim>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_level
|
|
||||||
: LEVEL
|
|
||||||
{ $$ = std::make_unique<ast::expr_level>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_animation
|
|
||||||
: MOD IDENTIFIER %prec ANIMREF
|
|
||||||
{ $$ = std::make_unique<ast::expr_animation>(@$, $2); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_animtree
|
|
||||||
: ANIMTREE
|
|
||||||
{ $$ = std::make_unique<ast::expr_animtree>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_identifier_nosize
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_identifier
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, $1); };
|
|
||||||
| SIZE
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, "size"); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_path
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_path>(@$, $1); };
|
|
||||||
| PATH
|
|
||||||
{ $$ = std::make_unique<ast::expr_path>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_istring
|
|
||||||
: ISTRING
|
|
||||||
{ $$ = std::make_unique<ast::expr_istring>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_string
|
|
||||||
: STRING
|
|
||||||
{ $$ = std::make_unique<ast::expr_string>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_vector
|
|
||||||
: LPAREN expr COMMA expr COMMA expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_vector>(@$, std::move($2), std::move($4), std::move($6)); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_float
|
|
||||||
: SUB FLOAT %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_float>(@$, "-" + $2); };
|
|
||||||
| FLOAT
|
|
||||||
{ $$ = std::make_unique<ast::expr_float>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_integer
|
|
||||||
: SUB INTEGER %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_integer>(@$, "-" + $2); };
|
|
||||||
| INTEGER
|
|
||||||
{ $$ = std::make_unique<ast::expr_integer>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_false
|
|
||||||
: FALSE
|
|
||||||
{ $$ = std::make_unique<ast::expr_false>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_true
|
|
||||||
: TRUE
|
|
||||||
{ $$ = std::make_unique<ast::expr_true>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
void xsk::gsc::h1::parser::error(const xsk::gsc::location& loc, const std::string& msg)
|
|
||||||
{
|
|
||||||
throw xsk::gsc::comp_error(loc, msg);
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
generate: H2
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf ./parser.hpp
|
|
||||||
rm -rf ./parser.cpp
|
|
||||||
|
|
||||||
H2: parser.ypp
|
|
||||||
bison parser.ypp -Wcounterexamples
|
|
||||||
mv parser.hpp parser.cpp ../../src/h2/xsk/
|
|
@ -1,875 +0,0 @@
|
|||||||
/* Copyright 2022 xensik. All rights reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a GNU GPLv3 license
|
|
||||||
// that can be found in the LICENSE file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
%require "3.7"
|
|
||||||
%skeleton "lalr1.cc"
|
|
||||||
%language "c++"
|
|
||||||
%output "parser.cpp"
|
|
||||||
%defines "parser.hpp"
|
|
||||||
%define api.prefix {H2}
|
|
||||||
%define api.namespace {xsk::gsc::h2}
|
|
||||||
%define api.location.type {xsk::gsc::location}
|
|
||||||
%define api.value.type variant
|
|
||||||
%define api.token.constructor
|
|
||||||
%define api.token.raw
|
|
||||||
%define parse.assert
|
|
||||||
%define parse.trace
|
|
||||||
%define parse.error detailed
|
|
||||||
%define parse.lac full
|
|
||||||
%locations
|
|
||||||
%lex-param { xsk::gsc::h2::lexer& lexer }
|
|
||||||
%parse-param { xsk::gsc::h2::lexer& lexer }
|
|
||||||
%parse-param { xsk::gsc::ast::program::ptr& ast }
|
|
||||||
|
|
||||||
%code requires
|
|
||||||
{
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(disable:4065)
|
|
||||||
#pragma warning(disable:4127)
|
|
||||||
#endif
|
|
||||||
#include "h2.hpp"
|
|
||||||
namespace xsk::gsc::h2 { class lexer; }
|
|
||||||
}
|
|
||||||
|
|
||||||
%code top
|
|
||||||
{
|
|
||||||
#include "stdafx.hpp"
|
|
||||||
#include "parser.hpp"
|
|
||||||
#include "lexer.hpp"
|
|
||||||
using namespace xsk::gsc;
|
|
||||||
xsk::gsc::h2::parser::symbol_type H2lex(xsk::gsc::h2::lexer& lexer);
|
|
||||||
}
|
|
||||||
|
|
||||||
%token SH_DEFINE "#define"
|
|
||||||
%token SH_UNDEF "#undef"
|
|
||||||
%token SH_IFDEF "#ifdef"
|
|
||||||
%token SH_IFNDEF "#ifndef"
|
|
||||||
%token SH_IF "#if"
|
|
||||||
%token SH_ELIF "#elif"
|
|
||||||
%token SH_ELSE "#else"
|
|
||||||
%token SH_ENDIF "#endif"
|
|
||||||
%token DEVBEGIN "/#"
|
|
||||||
%token DEVEND "#/"
|
|
||||||
%token INLINE "#inline"
|
|
||||||
%token INCLUDE "#include"
|
|
||||||
%token USINGTREE "#using_animtree"
|
|
||||||
%token ANIMTREE "#animtree"
|
|
||||||
%token ENDON "endon"
|
|
||||||
%token NOTIFY "notify"
|
|
||||||
%token WAIT "wait"
|
|
||||||
%token WAITTILL "waittill"
|
|
||||||
%token WAITTILLMATCH "waittillmatch"
|
|
||||||
%token WAITTILLFRAMEEND "waittillframeend"
|
|
||||||
%token WAITFRAME "waitframe"
|
|
||||||
%token IF "if"
|
|
||||||
%token ELSE "else"
|
|
||||||
%token DO "do"
|
|
||||||
%token WHILE "while"
|
|
||||||
%token FOR "for"
|
|
||||||
%token FOREACH "foreach"
|
|
||||||
%token IN "in"
|
|
||||||
%token SWITCH "switch"
|
|
||||||
%token CASE "case"
|
|
||||||
%token DEFAULT "default"
|
|
||||||
%token BREAK "break"
|
|
||||||
%token CONTINUE "continue"
|
|
||||||
%token RETURN "return"
|
|
||||||
%token BREAKPOINT "breakpoint"
|
|
||||||
%token PROFBEGIN "prof_begin"
|
|
||||||
%token PROFEND "prof_end"
|
|
||||||
%token THREAD "thread"
|
|
||||||
%token CHILDTHREAD "childthread"
|
|
||||||
%token THISTHREAD "thisthread"
|
|
||||||
%token CALL "call"
|
|
||||||
%token TRUE "true"
|
|
||||||
%token FALSE "false"
|
|
||||||
%token UNDEFINED "undefined"
|
|
||||||
%token SIZE "size"
|
|
||||||
%token GAME "game"
|
|
||||||
%token SELF "self"
|
|
||||||
%token ANIM "anim"
|
|
||||||
%token LEVEL "level"
|
|
||||||
%token LPAREN "("
|
|
||||||
%token RPAREN ")"
|
|
||||||
%token LBRACE "{"
|
|
||||||
%token RBRACE "}"
|
|
||||||
%token LBRACKET "["
|
|
||||||
%token RBRACKET "]"
|
|
||||||
%token COMMA ","
|
|
||||||
%token DOT "."
|
|
||||||
%token DOUBLECOLON "::"
|
|
||||||
%token COLON ":"
|
|
||||||
%token SEMICOLON ";"
|
|
||||||
%token QMARK "?"
|
|
||||||
%token INCREMENT "++"
|
|
||||||
%token DECREMENT "--"
|
|
||||||
%token LSHIFT "<<"
|
|
||||||
%token RSHIFT ">>"
|
|
||||||
%token OR "||"
|
|
||||||
%token AND "&&"
|
|
||||||
%token EQUALITY "=="
|
|
||||||
%token INEQUALITY "!="
|
|
||||||
%token LESS_EQUAL "<="
|
|
||||||
%token GREATER_EQUAL ">="
|
|
||||||
%token LESS "<"
|
|
||||||
%token GREATER ">"
|
|
||||||
%token NOT "!"
|
|
||||||
%token COMPLEMENT "~"
|
|
||||||
%token ASSIGN "="
|
|
||||||
%token ASSIGN_ADD "+="
|
|
||||||
%token ASSIGN_SUB "-="
|
|
||||||
%token ASSIGN_MUL "*="
|
|
||||||
%token ASSIGN_DIV "/="
|
|
||||||
%token ASSIGN_MOD "%="
|
|
||||||
%token ASSIGN_BW_OR "|="
|
|
||||||
%token ASSIGN_BW_AND "&="
|
|
||||||
%token ASSIGN_BW_EXOR "^="
|
|
||||||
%token ASSIGN_RSHIFT ">>="
|
|
||||||
%token ASSIGN_LSHIFT "<<="
|
|
||||||
%token BITWISE_OR "|"
|
|
||||||
%token BITWISE_AND "&"
|
|
||||||
%token BITWISE_EXOR "^"
|
|
||||||
%token ADD "+"
|
|
||||||
%token SUB "-"
|
|
||||||
%token MUL "*"
|
|
||||||
%token DIV "/"
|
|
||||||
%token MOD "%"
|
|
||||||
%token <std::string> PATH "path"
|
|
||||||
%token <std::string> IDENTIFIER "identifier"
|
|
||||||
%token <std::string> STRING "string literal"
|
|
||||||
%token <std::string> ISTRING "localized string"
|
|
||||||
%token <std::string> FLOAT "float"
|
|
||||||
%token <std::string> INTEGER "integer"
|
|
||||||
|
|
||||||
%type <ast::program::ptr> program
|
|
||||||
%type <ast::include::ptr> include
|
|
||||||
%type <ast::decl> declaration
|
|
||||||
%type <ast::decl_usingtree::ptr> decl_usingtree
|
|
||||||
%type <ast::decl_constant::ptr> decl_constant
|
|
||||||
%type <ast::decl_thread::ptr> decl_thread
|
|
||||||
%type <ast::stmt> stmt
|
|
||||||
%type <ast::stmt> stmt_or_dev
|
|
||||||
%type <ast::stmt_list::ptr> stmt_list
|
|
||||||
%type <ast::stmt_list::ptr> stmt_or_dev_list
|
|
||||||
%type <ast::stmt_dev::ptr> stmt_dev
|
|
||||||
%type <ast::stmt_list::ptr> stmt_block
|
|
||||||
%type <ast::stmt_expr::ptr> stmt_expr
|
|
||||||
%type <ast::stmt_call::ptr> stmt_call
|
|
||||||
%type <ast::stmt_assign::ptr> stmt_assign
|
|
||||||
%type <ast::stmt_endon::ptr> stmt_endon
|
|
||||||
%type <ast::stmt_notify::ptr> stmt_notify
|
|
||||||
%type <ast::stmt_wait::ptr> stmt_wait
|
|
||||||
%type <ast::stmt_waittill::ptr> stmt_waittill
|
|
||||||
%type <ast::stmt_waittillmatch::ptr> stmt_waittillmatch
|
|
||||||
%type <ast::stmt_waittillframeend::ptr> stmt_waittillframeend
|
|
||||||
%type <ast::stmt_waitframe::ptr> stmt_waitframe
|
|
||||||
%type <ast::stmt_if::ptr> stmt_if
|
|
||||||
%type <ast::stmt_ifelse::ptr> stmt_ifelse
|
|
||||||
%type <ast::stmt_while::ptr> stmt_while
|
|
||||||
%type <ast::stmt_dowhile::ptr> stmt_dowhile
|
|
||||||
%type <ast::stmt_for::ptr> stmt_for
|
|
||||||
%type <ast::stmt_foreach::ptr> stmt_foreach
|
|
||||||
%type <ast::stmt_switch::ptr> stmt_switch
|
|
||||||
%type <ast::stmt_case::ptr> stmt_case
|
|
||||||
%type <ast::stmt_default::ptr> stmt_default
|
|
||||||
%type <ast::stmt_break::ptr> stmt_break
|
|
||||||
%type <ast::stmt_continue::ptr> stmt_continue
|
|
||||||
%type <ast::stmt_return::ptr> stmt_return
|
|
||||||
%type <ast::stmt_breakpoint::ptr> stmt_breakpoint
|
|
||||||
%type <ast::stmt_prof_begin::ptr> stmt_prof_begin
|
|
||||||
%type <ast::stmt_prof_end::ptr> stmt_prof_end
|
|
||||||
%type <ast::expr> expr
|
|
||||||
%type <ast::expr> expr_or_empty
|
|
||||||
%type <ast::expr> expr_assign
|
|
||||||
%type <ast::expr> expr_increment
|
|
||||||
%type <ast::expr> expr_decrement
|
|
||||||
%type <ast::expr> expr_ternary
|
|
||||||
%type <ast::expr> expr_binary
|
|
||||||
%type <ast::expr> expr_primitive
|
|
||||||
%type <ast::expr_complement::ptr> expr_complement
|
|
||||||
%type <ast::expr_negate::ptr> expr_negate
|
|
||||||
%type <ast::expr_not::ptr> expr_not
|
|
||||||
%type <ast::expr_call::ptr> expr_call
|
|
||||||
%type <ast::expr_method::ptr> expr_method
|
|
||||||
%type <ast::call> expr_function
|
|
||||||
%type <ast::call> expr_pointer
|
|
||||||
%type <ast::expr_add_array::ptr> expr_add_array
|
|
||||||
%type <ast::expr_parameters::ptr> expr_parameters
|
|
||||||
%type <ast::expr_arguments::ptr> expr_arguments
|
|
||||||
%type <ast::expr_arguments::ptr> expr_arguments_no_empty
|
|
||||||
%type <ast::expr_reference::ptr> expr_reference
|
|
||||||
%type <ast::expr_array::ptr> expr_array
|
|
||||||
%type <ast::expr_field::ptr> expr_field
|
|
||||||
%type <ast::expr_size::ptr> expr_size
|
|
||||||
%type <ast::expr_paren::ptr> expr_paren
|
|
||||||
%type <ast::expr> expr_object
|
|
||||||
%type <ast::expr_thisthread::ptr> expr_thisthread
|
|
||||||
%type <ast::expr_empty_array::ptr> expr_empty_array
|
|
||||||
%type <ast::expr_undefined::ptr> expr_undefined
|
|
||||||
%type <ast::expr_game::ptr> expr_game
|
|
||||||
%type <ast::expr_self::ptr> expr_self
|
|
||||||
%type <ast::expr_anim::ptr> expr_anim
|
|
||||||
%type <ast::expr_level::ptr> expr_level
|
|
||||||
%type <ast::expr_animation::ptr> expr_animation
|
|
||||||
%type <ast::expr_animtree::ptr> expr_animtree
|
|
||||||
%type <ast::expr_identifier::ptr> expr_identifier_nosize
|
|
||||||
%type <ast::expr_identifier::ptr> expr_identifier
|
|
||||||
%type <ast::expr_path::ptr> expr_path
|
|
||||||
%type <ast::expr_istring::ptr> expr_istring
|
|
||||||
%type <ast::expr_string::ptr> expr_string
|
|
||||||
%type <ast::expr_vector::ptr> expr_vector
|
|
||||||
%type <ast::expr_float::ptr> expr_float
|
|
||||||
%type <ast::expr_integer::ptr> expr_integer
|
|
||||||
%type <ast::expr_false::ptr> expr_false
|
|
||||||
%type <ast::expr_true::ptr> expr_true
|
|
||||||
|
|
||||||
%nonassoc SIZEOF
|
|
||||||
%nonassoc ADD_ARRAY
|
|
||||||
%nonassoc RBRACKET
|
|
||||||
%nonassoc THEN
|
|
||||||
%nonassoc ELSE
|
|
||||||
%nonassoc INCREMENT DECREMENT
|
|
||||||
|
|
||||||
%precedence TERN
|
|
||||||
%right QMARK
|
|
||||||
%left OR
|
|
||||||
%left AND
|
|
||||||
%left BITWISE_OR
|
|
||||||
%left BITWISE_EXOR
|
|
||||||
%left BITWISE_AND
|
|
||||||
%left EQUALITY INEQUALITY
|
|
||||||
%left LESS GREATER LESS_EQUAL GREATER_EQUAL
|
|
||||||
%left LSHIFT RSHIFT
|
|
||||||
%left ADD SUB
|
|
||||||
%left MUL DIV MOD
|
|
||||||
%right NOT COMPLEMENT
|
|
||||||
|
|
||||||
%precedence NEG
|
|
||||||
%precedence ANIMREF
|
|
||||||
%precedence PREINC PREDEC
|
|
||||||
%precedence POSTINC POSTDEC
|
|
||||||
|
|
||||||
%start root
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
root
|
|
||||||
: program { ast = std::move($1); }
|
|
||||||
| { ast = std::make_unique<ast::program>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
program
|
|
||||||
: program inline
|
|
||||||
{ $$ = std::move($1); }
|
|
||||||
| program include
|
|
||||||
{ $$ = std::move($1); $$->includes.push_back(std::move($2)); }
|
|
||||||
| program declaration
|
|
||||||
{ $$ = std::move($1); $$->declarations.push_back(std::move($2)); }
|
|
||||||
| inline
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); }
|
|
||||||
| include
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); $$->includes.push_back(std::move($1)); }
|
|
||||||
| declaration
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); $$->declarations.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
inline
|
|
||||||
: INLINE expr_path SEMICOLON { lexer.push_header($2->value); }
|
|
||||||
;
|
|
||||||
|
|
||||||
include
|
|
||||||
: INCLUDE expr_path SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::include>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
declaration
|
|
||||||
: DEVBEGIN { $$.as_dev_begin = std::make_unique<ast::decl_dev_begin>(@$); }
|
|
||||||
| DEVEND { $$.as_dev_end = std::make_unique<ast::decl_dev_end>(@$); }
|
|
||||||
| decl_usingtree { $$.as_usingtree = std::move($1); }
|
|
||||||
| decl_constant { $$.as_constant = std::move($1); }
|
|
||||||
| decl_thread { $$.as_thread = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_usingtree
|
|
||||||
: USINGTREE LPAREN expr_string RPAREN SEMICOLON
|
|
||||||
{ lexer.ban_header(@$); $$ = std::make_unique<ast::decl_usingtree>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_constant
|
|
||||||
: expr_identifier ASSIGN expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::decl_constant>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_thread
|
|
||||||
: expr_identifier LPAREN expr_parameters RPAREN stmt_block
|
|
||||||
{ lexer.ban_header(@$); $$ = std::make_unique<ast::decl_thread>(@$, std::move($1), std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt
|
|
||||||
: stmt_block { $$.as_list = std::move($1); }
|
|
||||||
| stmt_call { $$.as_call = std::move($1); }
|
|
||||||
| stmt_assign { $$.as_assign = std::move($1); }
|
|
||||||
| stmt_endon { $$.as_endon = std::move($1); }
|
|
||||||
| stmt_notify { $$.as_notify = std::move($1); }
|
|
||||||
| stmt_wait { $$.as_wait = std::move($1); }
|
|
||||||
| stmt_waittill { $$.as_waittill = std::move($1); }
|
|
||||||
| stmt_waittillmatch { $$.as_waittillmatch = std::move($1); }
|
|
||||||
| stmt_waittillframeend { $$.as_waittillframeend = std::move($1); }
|
|
||||||
| stmt_waitframe { $$.as_waitframe = std::move($1); }
|
|
||||||
| stmt_if { $$.as_if = std::move($1); }
|
|
||||||
| stmt_ifelse { $$.as_ifelse = std::move($1); }
|
|
||||||
| stmt_while { $$.as_while = std::move($1); }
|
|
||||||
| stmt_dowhile { $$.as_dowhile = std::move($1); }
|
|
||||||
| stmt_for { $$.as_for = std::move($1); }
|
|
||||||
| stmt_foreach { $$.as_foreach = std::move($1); }
|
|
||||||
| stmt_switch { $$.as_switch = std::move($1); }
|
|
||||||
| stmt_case { $$.as_case = std::move($1); }
|
|
||||||
| stmt_default { $$.as_default = std::move($1); }
|
|
||||||
| stmt_break { $$.as_break = std::move($1); }
|
|
||||||
| stmt_continue { $$.as_continue = std::move($1); }
|
|
||||||
| stmt_return { $$.as_return = std::move($1); }
|
|
||||||
| stmt_breakpoint { $$.as_breakpoint = std::move($1); }
|
|
||||||
| stmt_prof_begin { $$.as_prof_begin = std::move($1); }
|
|
||||||
| stmt_prof_end { $$.as_prof_end = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_or_dev
|
|
||||||
: stmt { $$ = std::move($1); }
|
|
||||||
| stmt_dev { $$.as_dev = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_list
|
|
||||||
: stmt_list stmt
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($2)); }
|
|
||||||
| stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_list>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_or_dev_list
|
|
||||||
: stmt_or_dev_list stmt_or_dev
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($2)); }
|
|
||||||
| stmt_or_dev
|
|
||||||
{ $$ = std::make_unique<ast::stmt_list>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_dev
|
|
||||||
: DEVBEGIN stmt_list DEVEND { $$ = std::make_unique<ast::stmt_dev>(@$, std::move($2)); }
|
|
||||||
| DEVBEGIN DEVEND { $$ = std::make_unique<ast::stmt_dev>(@$, std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_block
|
|
||||||
: LBRACE stmt_or_dev_list RBRACE { $$ = std::move($2); }
|
|
||||||
| LBRACE RBRACE { $$ = std::make_unique<ast::stmt_list>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_expr
|
|
||||||
: expr_assign
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
| expr_increment
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
| expr_decrement
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::make_unique<ast::node>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_call
|
|
||||||
: expr_call SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_call>(@$, ast::expr(std::move($1))); }
|
|
||||||
| expr_method SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_call>(@$, ast::expr(std::move($1))); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_assign
|
|
||||||
: expr_assign SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
| expr_increment SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
| expr_decrement SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_endon
|
|
||||||
: expr_object ENDON LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_endon>(@$, std::move($1), std::move($4)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_notify
|
|
||||||
: expr_object NOTIFY LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_notify>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object NOTIFY LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_notify>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_wait
|
|
||||||
: WAIT expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_wait>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittill
|
|
||||||
: expr_object WAITTILL LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittill>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object WAITTILL LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittill>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittillmatch
|
|
||||||
: expr_object WAITTILLMATCH LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillmatch>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object WAITTILLMATCH LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillmatch>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittillframeend
|
|
||||||
: WAITTILLFRAMEEND SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillframeend>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waitframe
|
|
||||||
: WAITFRAME SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waitframe>(@$); }
|
|
||||||
| WAITFRAME LPAREN RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waitframe>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_if
|
|
||||||
: IF LPAREN expr RPAREN stmt %prec THEN
|
|
||||||
{ $$ = std::make_unique<ast::stmt_if>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_ifelse
|
|
||||||
: IF LPAREN expr RPAREN stmt ELSE stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_ifelse>(@$, std::move($3), std::move($5), std::move($7)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_while
|
|
||||||
: WHILE LPAREN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_while>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_dowhile
|
|
||||||
: DO stmt WHILE LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_dowhile>(@$, std::move($5), std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_for
|
|
||||||
: FOR LPAREN stmt_expr SEMICOLON expr_or_empty SEMICOLON stmt_expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_for>(@$, ast::stmt(std::move($3)), std::move($5), ast::stmt(std::move($7)), std::move($9)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_foreach
|
|
||||||
: FOREACH LPAREN expr_identifier IN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_foreach>(@$, ast::expr(std::move($3)), std::move($5), std::move($7)); }
|
|
||||||
| FOREACH LPAREN expr_identifier COMMA expr_identifier IN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_foreach>(@$, ast::expr(std::move($3)), ast::expr(std::move($5)), std::move($7), std::move($9)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_switch
|
|
||||||
: SWITCH LPAREN expr RPAREN stmt_block
|
|
||||||
{ $$ = std::make_unique<ast::stmt_switch>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_case
|
|
||||||
: CASE expr_integer COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_case>(@$, ast::expr(std::move($2)), std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
| CASE expr_string COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_case>(@$, ast::expr(std::move($2)), std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_default
|
|
||||||
: DEFAULT COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_default>(@$, std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_break
|
|
||||||
: BREAK SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_break>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_continue
|
|
||||||
: CONTINUE SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_continue>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_return
|
|
||||||
: RETURN expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_return>(@$, std::move($2)); }
|
|
||||||
| RETURN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_return>(@$, std::make_unique<ast::node>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_breakpoint
|
|
||||||
: BREAKPOINT SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_breakpoint>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_prof_begin
|
|
||||||
: PROFBEGIN LPAREN expr_arguments RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_prof_begin>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_prof_end
|
|
||||||
: PROFEND LPAREN expr_arguments RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_prof_end>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr
|
|
||||||
: expr_ternary { $$ = std::move($1); }
|
|
||||||
| expr_binary { $$ = std::move($1); }
|
|
||||||
| expr_primitive { $$ = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_or_empty
|
|
||||||
: expr { $$ = std::move($1); }
|
|
||||||
| { $$.as_node = std::make_unique<ast::node>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_assign
|
|
||||||
: expr_object ASSIGN expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_EXOR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_exor>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_LSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_shift_left>(@$, std::move($1),std::move( $3)); }
|
|
||||||
| expr_object ASSIGN_RSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_shift_right>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_ADD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_add>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_SUB expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_sub>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_MUL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_mul>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_DIV expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_div>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_MOD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_mod>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_increment
|
|
||||||
: INCREMENT expr_object %prec PREINC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_increment>(@$, std::move($2), true); }
|
|
||||||
| expr_object INCREMENT %prec POSTINC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_increment>(@$, std::move($1), false); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_decrement
|
|
||||||
: DECREMENT expr_object %prec PREDEC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_decrement>(@$, std::move($2), true); }
|
|
||||||
| expr_object DECREMENT %prec POSTDEC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_decrement>(@$, std::move($1), false); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_ternary
|
|
||||||
: expr QMARK expr COLON expr %prec TERN
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_ternary>(@$, std::move($1), std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_binary
|
|
||||||
: expr OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr EQUALITY expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_equality>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr INEQUALITY expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_inequality>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LESS_EQUAL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_less_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr GREATER_EQUAL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_greater_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LESS expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_less>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr GREATER expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_greater>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_EXOR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_exor>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_shift_left>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr RSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_shift_right>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr ADD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_add>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr SUB expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_sub>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr MUL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_mul>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr DIV expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_div>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr MOD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_mod>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_primitive
|
|
||||||
: expr_complement { $$.as_node = std::move($1); }
|
|
||||||
| expr_negate { $$.as_node = std::move($1); }
|
|
||||||
| expr_not { $$.as_node = std::move($1); }
|
|
||||||
| expr_call { $$.as_node = std::move($1); }
|
|
||||||
| expr_method { $$.as_node = std::move($1); }
|
|
||||||
| expr_add_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_reference { $$.as_node = std::move($1); }
|
|
||||||
| expr_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_field { $$.as_node = std::move($1); }
|
|
||||||
| expr_size { $$.as_node = std::move($1); }
|
|
||||||
| expr_paren { $$.as_node = std::move($1); }
|
|
||||||
| expr_thisthread { $$.as_node = std::move($1); }
|
|
||||||
| expr_empty_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_undefined { $$.as_node = std::move($1); }
|
|
||||||
| expr_game { $$.as_node = std::move($1); }
|
|
||||||
| expr_self { $$.as_node = std::move($1); }
|
|
||||||
| expr_anim { $$.as_node = std::move($1); }
|
|
||||||
| expr_level { $$.as_node = std::move($1); }
|
|
||||||
| expr_animation { $$.as_node = std::move($1); }
|
|
||||||
| expr_animtree { $$.as_node = std::move($1); }
|
|
||||||
| expr_identifier { $$.as_node = std::move($1); }
|
|
||||||
| expr_istring { $$.as_node = std::move($1); }
|
|
||||||
| expr_string { $$.as_node = std::move($1); }
|
|
||||||
| expr_vector { $$.as_node = std::move($1); }
|
|
||||||
| expr_float { $$.as_node = std::move($1); }
|
|
||||||
| expr_integer { $$.as_node = std::move($1); }
|
|
||||||
| expr_false { $$.as_node = std::move($1); }
|
|
||||||
| expr_true { $$.as_node = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_complement
|
|
||||||
: COMPLEMENT expr
|
|
||||||
{ $$ = std::make_unique<ast::expr_complement>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_negate
|
|
||||||
: SUB expr_identifier %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_paren %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_array %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_field %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_not
|
|
||||||
: NOT expr
|
|
||||||
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_call
|
|
||||||
: expr_function { $$ = std::make_unique<ast::expr_call>(@$, std::move($1)); }
|
|
||||||
| expr_pointer { $$ = std::make_unique<ast::expr_call>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
expr_method
|
|
||||||
: expr_object expr_function { $$ = std::make_unique<ast::expr_method>(@$, std::move($1), std::move($2)); }
|
|
||||||
| expr_object expr_pointer { $$ = std::make_unique<ast::expr_method>(@$, std::move($1), std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_function
|
|
||||||
: expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($1), std::move($3), ast::call::mode::normal); }
|
|
||||||
| expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($1), std::move($3), std::move($5), ast::call::mode::normal); }
|
|
||||||
| THREAD expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($2), std::move($4), ast::call::mode::thread); }
|
|
||||||
| THREAD expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($2), std::move($4), std::move($6), ast::call::mode::thread); }
|
|
||||||
| CHILDTHREAD expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($2), std::move($4), ast::call::mode::childthread); }
|
|
||||||
| CHILDTHREAD expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($2), std::move($4), std::move($6), ast::call::mode::childthread); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_pointer
|
|
||||||
: LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($3), std::move($7), ast::call::mode::normal); }
|
|
||||||
| THREAD LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::thread); }
|
|
||||||
| CHILDTHREAD LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::childthread); }
|
|
||||||
| CALL LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::builtin); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_add_array
|
|
||||||
: LBRACKET expr_arguments_no_empty RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_add_array>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_parameters
|
|
||||||
: expr_parameters COMMA expr_identifier
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($3)); }
|
|
||||||
| expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_parameters>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::expr_parameters>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_arguments
|
|
||||||
: expr_arguments_no_empty
|
|
||||||
{ $$ = std::move($1); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::expr_arguments>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_arguments_no_empty
|
|
||||||
: expr_arguments COMMA expr
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($3)); }
|
|
||||||
| expr %prec ADD_ARRAY
|
|
||||||
{ $$ = std::make_unique<ast::expr_arguments>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_reference
|
|
||||||
: DOUBLECOLON expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_reference>(@$, std::make_unique<ast::expr_path>(@$), std::move($2)); }
|
|
||||||
| expr_path DOUBLECOLON expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_reference>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_array
|
|
||||||
: expr_object LBRACKET expr RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_array>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_field
|
|
||||||
: expr_object DOT expr_identifier_nosize
|
|
||||||
{ $$ = std::make_unique<ast::expr_field>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_size
|
|
||||||
: expr_object DOT SIZE %prec SIZEOF
|
|
||||||
{ $$ = std::make_unique<ast::expr_size>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_paren
|
|
||||||
: LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_paren>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_object
|
|
||||||
: expr_call { $$.as_node = std::move($1); }
|
|
||||||
| expr_method { $$.as_node = std::move($1); }
|
|
||||||
| expr_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_field { $$.as_node = std::move($1); }
|
|
||||||
| expr_game { $$.as_node = std::move($1); }
|
|
||||||
| expr_self { $$.as_node = std::move($1); }
|
|
||||||
| expr_anim { $$.as_node = std::move($1); }
|
|
||||||
| expr_level { $$.as_node = std::move($1); }
|
|
||||||
| expr_identifier { $$.as_node = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_thisthread
|
|
||||||
: THISTHREAD
|
|
||||||
{ $$ = std::make_unique<ast::expr_thisthread>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_empty_array
|
|
||||||
: LBRACKET RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_empty_array>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_undefined
|
|
||||||
: UNDEFINED
|
|
||||||
{ $$ = std::make_unique<ast::expr_undefined>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_game
|
|
||||||
: GAME
|
|
||||||
{ $$ = std::make_unique<ast::expr_game>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_self
|
|
||||||
: SELF
|
|
||||||
{ $$ = std::make_unique<ast::expr_self>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_anim
|
|
||||||
: ANIM
|
|
||||||
{ $$ = std::make_unique<ast::expr_anim>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_level
|
|
||||||
: LEVEL
|
|
||||||
{ $$ = std::make_unique<ast::expr_level>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_animation
|
|
||||||
: MOD IDENTIFIER %prec ANIMREF
|
|
||||||
{ $$ = std::make_unique<ast::expr_animation>(@$, $2); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_animtree
|
|
||||||
: ANIMTREE
|
|
||||||
{ $$ = std::make_unique<ast::expr_animtree>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_identifier_nosize
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_identifier
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, $1); };
|
|
||||||
| SIZE
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, "size"); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_path
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_path>(@$, $1); };
|
|
||||||
| PATH
|
|
||||||
{ $$ = std::make_unique<ast::expr_path>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_istring
|
|
||||||
: ISTRING
|
|
||||||
{ $$ = std::make_unique<ast::expr_istring>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_string
|
|
||||||
: STRING
|
|
||||||
{ $$ = std::make_unique<ast::expr_string>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_vector
|
|
||||||
: LPAREN expr COMMA expr COMMA expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_vector>(@$, std::move($2), std::move($4), std::move($6)); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_float
|
|
||||||
: SUB FLOAT %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_float>(@$, "-" + $2); };
|
|
||||||
| FLOAT
|
|
||||||
{ $$ = std::make_unique<ast::expr_float>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_integer
|
|
||||||
: SUB INTEGER %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_integer>(@$, "-" + $2); };
|
|
||||||
| INTEGER
|
|
||||||
{ $$ = std::make_unique<ast::expr_integer>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_false
|
|
||||||
: FALSE
|
|
||||||
{ $$ = std::make_unique<ast::expr_false>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_true
|
|
||||||
: TRUE
|
|
||||||
{ $$ = std::make_unique<ast::expr_true>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
void xsk::gsc::h2::parser::error(const xsk::gsc::location& loc, const std::string& msg)
|
|
||||||
{
|
|
||||||
throw xsk::gsc::comp_error(loc, msg);
|
|
||||||
}
|
|
1
gen/hash/cmd.txt
Normal file
1
gen/hash/cmd.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
clang++ -Wall -std=c++20 iw9_hash.cpp -o iw9_hash
|
75105
gen/hash/iw9_hash.cpp
Normal file
75105
gen/hash/iw9_hash.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,9 +0,0 @@
|
|||||||
generate: IW5
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf ./parser.hpp
|
|
||||||
rm -rf ./parser.cpp
|
|
||||||
|
|
||||||
IW5: parser.ypp
|
|
||||||
bison parser.ypp -Wcounterexamples
|
|
||||||
mv parser.hpp parser.cpp ../../src/iw5/xsk/
|
|
@ -1,865 +0,0 @@
|
|||||||
/* Copyright 2022 xensik. All rights reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a GNU GPLv3 license
|
|
||||||
// that can be found in the LICENSE file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
%require "3.7"
|
|
||||||
%skeleton "lalr1.cc"
|
|
||||||
%language "c++"
|
|
||||||
%output "parser.cpp"
|
|
||||||
%defines "parser.hpp"
|
|
||||||
%define api.prefix {IW5}
|
|
||||||
%define api.namespace {xsk::gsc::iw5}
|
|
||||||
%define api.location.type {xsk::gsc::location}
|
|
||||||
%define api.value.type variant
|
|
||||||
%define api.token.constructor
|
|
||||||
%define api.token.raw
|
|
||||||
%define parse.assert
|
|
||||||
%define parse.trace
|
|
||||||
%define parse.error detailed
|
|
||||||
%define parse.lac full
|
|
||||||
%locations
|
|
||||||
%lex-param { xsk::gsc::iw5::lexer& lexer }
|
|
||||||
%parse-param { xsk::gsc::iw5::lexer& lexer }
|
|
||||||
%parse-param { xsk::gsc::ast::program::ptr& ast }
|
|
||||||
|
|
||||||
%code requires
|
|
||||||
{
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(disable:4065)
|
|
||||||
#pragma warning(disable:4127)
|
|
||||||
#endif
|
|
||||||
#include "iw5.hpp"
|
|
||||||
namespace xsk::gsc::iw5 { class lexer; }
|
|
||||||
}
|
|
||||||
|
|
||||||
%code top
|
|
||||||
{
|
|
||||||
#include "stdafx.hpp"
|
|
||||||
#include "parser.hpp"
|
|
||||||
#include "lexer.hpp"
|
|
||||||
using namespace xsk::gsc;
|
|
||||||
xsk::gsc::iw5::parser::symbol_type IW5lex(xsk::gsc::iw5::lexer& lexer);
|
|
||||||
}
|
|
||||||
|
|
||||||
%token SH_DEFINE "#define"
|
|
||||||
%token SH_UNDEF "#undef"
|
|
||||||
%token SH_IFDEF "#ifdef"
|
|
||||||
%token SH_IFNDEF "#ifndef"
|
|
||||||
%token SH_IF "#if"
|
|
||||||
%token SH_ELIF "#elif"
|
|
||||||
%token SH_ELSE "#else"
|
|
||||||
%token SH_ENDIF "#endif"
|
|
||||||
%token DEVBEGIN "/#"
|
|
||||||
%token DEVEND "#/"
|
|
||||||
%token INLINE "#inline"
|
|
||||||
%token INCLUDE "#include"
|
|
||||||
%token USINGTREE "#using_animtree"
|
|
||||||
%token ANIMTREE "#animtree"
|
|
||||||
%token ENDON "endon"
|
|
||||||
%token NOTIFY "notify"
|
|
||||||
%token WAIT "wait"
|
|
||||||
%token WAITTILL "waittill"
|
|
||||||
%token WAITTILLMATCH "waittillmatch"
|
|
||||||
%token WAITTILLFRAMEEND "waittillframeend"
|
|
||||||
%token IF "if"
|
|
||||||
%token ELSE "else"
|
|
||||||
%token DO "do"
|
|
||||||
%token WHILE "while"
|
|
||||||
%token FOR "for"
|
|
||||||
%token FOREACH "foreach"
|
|
||||||
%token IN "in"
|
|
||||||
%token SWITCH "switch"
|
|
||||||
%token CASE "case"
|
|
||||||
%token DEFAULT "default"
|
|
||||||
%token BREAK "break"
|
|
||||||
%token CONTINUE "continue"
|
|
||||||
%token RETURN "return"
|
|
||||||
%token BREAKPOINT "breakpoint"
|
|
||||||
%token PROFBEGIN "prof_begin"
|
|
||||||
%token PROFEND "prof_end"
|
|
||||||
%token THREAD "thread"
|
|
||||||
%token CHILDTHREAD "childthread"
|
|
||||||
%token THISTHREAD "thisthread"
|
|
||||||
%token CALL "call"
|
|
||||||
%token TRUE "true"
|
|
||||||
%token FALSE "false"
|
|
||||||
%token UNDEFINED "undefined"
|
|
||||||
%token SIZE "size"
|
|
||||||
%token GAME "game"
|
|
||||||
%token SELF "self"
|
|
||||||
%token ANIM "anim"
|
|
||||||
%token LEVEL "level"
|
|
||||||
%token LPAREN "("
|
|
||||||
%token RPAREN ")"
|
|
||||||
%token LBRACE "{"
|
|
||||||
%token RBRACE "}"
|
|
||||||
%token LBRACKET "["
|
|
||||||
%token RBRACKET "]"
|
|
||||||
%token COMMA ","
|
|
||||||
%token DOT "."
|
|
||||||
%token DOUBLECOLON "::"
|
|
||||||
%token COLON ":"
|
|
||||||
%token SEMICOLON ";"
|
|
||||||
%token QMARK "?"
|
|
||||||
%token INCREMENT "++"
|
|
||||||
%token DECREMENT "--"
|
|
||||||
%token LSHIFT "<<"
|
|
||||||
%token RSHIFT ">>"
|
|
||||||
%token OR "||"
|
|
||||||
%token AND "&&"
|
|
||||||
%token EQUALITY "=="
|
|
||||||
%token INEQUALITY "!="
|
|
||||||
%token LESS_EQUAL "<="
|
|
||||||
%token GREATER_EQUAL ">="
|
|
||||||
%token LESS "<"
|
|
||||||
%token GREATER ">"
|
|
||||||
%token NOT "!"
|
|
||||||
%token COMPLEMENT "~"
|
|
||||||
%token ASSIGN "="
|
|
||||||
%token ASSIGN_ADD "+="
|
|
||||||
%token ASSIGN_SUB "-="
|
|
||||||
%token ASSIGN_MUL "*="
|
|
||||||
%token ASSIGN_DIV "/="
|
|
||||||
%token ASSIGN_MOD "%="
|
|
||||||
%token ASSIGN_BW_OR "|="
|
|
||||||
%token ASSIGN_BW_AND "&="
|
|
||||||
%token ASSIGN_BW_EXOR "^="
|
|
||||||
%token ASSIGN_RSHIFT ">>="
|
|
||||||
%token ASSIGN_LSHIFT "<<="
|
|
||||||
%token BITWISE_OR "|"
|
|
||||||
%token BITWISE_AND "&"
|
|
||||||
%token BITWISE_EXOR "^"
|
|
||||||
%token ADD "+"
|
|
||||||
%token SUB "-"
|
|
||||||
%token MUL "*"
|
|
||||||
%token DIV "/"
|
|
||||||
%token MOD "%"
|
|
||||||
%token <std::string> PATH "path"
|
|
||||||
%token <std::string> IDENTIFIER "identifier"
|
|
||||||
%token <std::string> STRING "string literal"
|
|
||||||
%token <std::string> ISTRING "localized string"
|
|
||||||
%token <std::string> FLOAT "float"
|
|
||||||
%token <std::string> INTEGER "integer"
|
|
||||||
|
|
||||||
%type <ast::program::ptr> program
|
|
||||||
%type <ast::include::ptr> include
|
|
||||||
%type <ast::decl> declaration
|
|
||||||
%type <ast::decl_usingtree::ptr> decl_usingtree
|
|
||||||
%type <ast::decl_constant::ptr> decl_constant
|
|
||||||
%type <ast::decl_thread::ptr> decl_thread
|
|
||||||
%type <ast::stmt> stmt
|
|
||||||
%type <ast::stmt> stmt_or_dev
|
|
||||||
%type <ast::stmt_list::ptr> stmt_list
|
|
||||||
%type <ast::stmt_list::ptr> stmt_or_dev_list
|
|
||||||
%type <ast::stmt_dev::ptr> stmt_dev
|
|
||||||
%type <ast::stmt_list::ptr> stmt_block
|
|
||||||
%type <ast::stmt_expr::ptr> stmt_expr
|
|
||||||
%type <ast::stmt_call::ptr> stmt_call
|
|
||||||
%type <ast::stmt_assign::ptr> stmt_assign
|
|
||||||
%type <ast::stmt_endon::ptr> stmt_endon
|
|
||||||
%type <ast::stmt_notify::ptr> stmt_notify
|
|
||||||
%type <ast::stmt_wait::ptr> stmt_wait
|
|
||||||
%type <ast::stmt_waittill::ptr> stmt_waittill
|
|
||||||
%type <ast::stmt_waittillmatch::ptr> stmt_waittillmatch
|
|
||||||
%type <ast::stmt_waittillframeend::ptr> stmt_waittillframeend
|
|
||||||
%type <ast::stmt_if::ptr> stmt_if
|
|
||||||
%type <ast::stmt_ifelse::ptr> stmt_ifelse
|
|
||||||
%type <ast::stmt_while::ptr> stmt_while
|
|
||||||
%type <ast::stmt_dowhile::ptr> stmt_dowhile
|
|
||||||
%type <ast::stmt_for::ptr> stmt_for
|
|
||||||
%type <ast::stmt_foreach::ptr> stmt_foreach
|
|
||||||
%type <ast::stmt_switch::ptr> stmt_switch
|
|
||||||
%type <ast::stmt_case::ptr> stmt_case
|
|
||||||
%type <ast::stmt_default::ptr> stmt_default
|
|
||||||
%type <ast::stmt_break::ptr> stmt_break
|
|
||||||
%type <ast::stmt_continue::ptr> stmt_continue
|
|
||||||
%type <ast::stmt_return::ptr> stmt_return
|
|
||||||
%type <ast::stmt_breakpoint::ptr> stmt_breakpoint
|
|
||||||
%type <ast::stmt_prof_begin::ptr> stmt_prof_begin
|
|
||||||
%type <ast::stmt_prof_end::ptr> stmt_prof_end
|
|
||||||
%type <ast::expr> expr
|
|
||||||
%type <ast::expr> expr_or_empty
|
|
||||||
%type <ast::expr> expr_assign
|
|
||||||
%type <ast::expr> expr_increment
|
|
||||||
%type <ast::expr> expr_decrement
|
|
||||||
%type <ast::expr> expr_ternary
|
|
||||||
%type <ast::expr> expr_binary
|
|
||||||
%type <ast::expr> expr_primitive
|
|
||||||
%type <ast::expr_complement::ptr> expr_complement
|
|
||||||
%type <ast::expr_negate::ptr> expr_negate
|
|
||||||
%type <ast::expr_not::ptr> expr_not
|
|
||||||
%type <ast::expr_call::ptr> expr_call
|
|
||||||
%type <ast::expr_method::ptr> expr_method
|
|
||||||
%type <ast::call> expr_function
|
|
||||||
%type <ast::call> expr_pointer
|
|
||||||
%type <ast::expr_add_array::ptr> expr_add_array
|
|
||||||
%type <ast::expr_parameters::ptr> expr_parameters
|
|
||||||
%type <ast::expr_arguments::ptr> expr_arguments
|
|
||||||
%type <ast::expr_arguments::ptr> expr_arguments_no_empty
|
|
||||||
%type <ast::expr_reference::ptr> expr_reference
|
|
||||||
%type <ast::expr_array::ptr> expr_array
|
|
||||||
%type <ast::expr_field::ptr> expr_field
|
|
||||||
%type <ast::expr_size::ptr> expr_size
|
|
||||||
%type <ast::expr_paren::ptr> expr_paren
|
|
||||||
%type <ast::expr> expr_object
|
|
||||||
%type <ast::expr_thisthread::ptr> expr_thisthread
|
|
||||||
%type <ast::expr_empty_array::ptr> expr_empty_array
|
|
||||||
%type <ast::expr_undefined::ptr> expr_undefined
|
|
||||||
%type <ast::expr_game::ptr> expr_game
|
|
||||||
%type <ast::expr_self::ptr> expr_self
|
|
||||||
%type <ast::expr_anim::ptr> expr_anim
|
|
||||||
%type <ast::expr_level::ptr> expr_level
|
|
||||||
%type <ast::expr_animation::ptr> expr_animation
|
|
||||||
%type <ast::expr_animtree::ptr> expr_animtree
|
|
||||||
%type <ast::expr_identifier::ptr> expr_identifier_nosize
|
|
||||||
%type <ast::expr_identifier::ptr> expr_identifier
|
|
||||||
%type <ast::expr_path::ptr> expr_path
|
|
||||||
%type <ast::expr_istring::ptr> expr_istring
|
|
||||||
%type <ast::expr_string::ptr> expr_string
|
|
||||||
%type <ast::expr_vector::ptr> expr_vector
|
|
||||||
%type <ast::expr_float::ptr> expr_float
|
|
||||||
%type <ast::expr_integer::ptr> expr_integer
|
|
||||||
%type <ast::expr_false::ptr> expr_false
|
|
||||||
%type <ast::expr_true::ptr> expr_true
|
|
||||||
|
|
||||||
%nonassoc SIZEOF
|
|
||||||
%nonassoc ADD_ARRAY
|
|
||||||
%nonassoc RBRACKET
|
|
||||||
%nonassoc THEN
|
|
||||||
%nonassoc ELSE
|
|
||||||
%nonassoc INCREMENT DECREMENT
|
|
||||||
|
|
||||||
%precedence TERN
|
|
||||||
%right QMARK
|
|
||||||
%left OR
|
|
||||||
%left AND
|
|
||||||
%left BITWISE_OR
|
|
||||||
%left BITWISE_EXOR
|
|
||||||
%left BITWISE_AND
|
|
||||||
%left EQUALITY INEQUALITY
|
|
||||||
%left LESS GREATER LESS_EQUAL GREATER_EQUAL
|
|
||||||
%left LSHIFT RSHIFT
|
|
||||||
%left ADD SUB
|
|
||||||
%left MUL DIV MOD
|
|
||||||
%right NOT COMPLEMENT
|
|
||||||
|
|
||||||
%precedence NEG
|
|
||||||
%precedence ANIMREF
|
|
||||||
%precedence PREINC PREDEC
|
|
||||||
%precedence POSTINC POSTDEC
|
|
||||||
|
|
||||||
%start root
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
root
|
|
||||||
: program { ast = std::move($1); }
|
|
||||||
| { ast = std::make_unique<ast::program>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
program
|
|
||||||
: program inline
|
|
||||||
{ $$ = std::move($1); }
|
|
||||||
| program include
|
|
||||||
{ $$ = std::move($1); $$->includes.push_back(std::move($2)); }
|
|
||||||
| program declaration
|
|
||||||
{ $$ = std::move($1); $$->declarations.push_back(std::move($2)); }
|
|
||||||
| inline
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); }
|
|
||||||
| include
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); $$->includes.push_back(std::move($1)); }
|
|
||||||
| declaration
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); $$->declarations.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
inline
|
|
||||||
: INLINE expr_path SEMICOLON { lexer.push_header($2->value); }
|
|
||||||
;
|
|
||||||
|
|
||||||
include
|
|
||||||
: INCLUDE expr_path SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::include>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
declaration
|
|
||||||
: DEVBEGIN { $$.as_dev_begin = std::make_unique<ast::decl_dev_begin>(@$); }
|
|
||||||
| DEVEND { $$.as_dev_end = std::make_unique<ast::decl_dev_end>(@$); }
|
|
||||||
| decl_usingtree { $$.as_usingtree = std::move($1); }
|
|
||||||
| decl_constant { $$.as_constant = std::move($1); }
|
|
||||||
| decl_thread { $$.as_thread = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_usingtree
|
|
||||||
: USINGTREE LPAREN expr_string RPAREN SEMICOLON
|
|
||||||
{ lexer.ban_header(@$); $$ = std::make_unique<ast::decl_usingtree>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_constant
|
|
||||||
: expr_identifier ASSIGN expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::decl_constant>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_thread
|
|
||||||
: expr_identifier LPAREN expr_parameters RPAREN stmt_block
|
|
||||||
{ lexer.ban_header(@$); $$ = std::make_unique<ast::decl_thread>(@$, std::move($1), std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt
|
|
||||||
: stmt_block { $$.as_list = std::move($1); }
|
|
||||||
| stmt_call { $$.as_call = std::move($1); }
|
|
||||||
| stmt_assign { $$.as_assign = std::move($1); }
|
|
||||||
| stmt_endon { $$.as_endon = std::move($1); }
|
|
||||||
| stmt_notify { $$.as_notify = std::move($1); }
|
|
||||||
| stmt_wait { $$.as_wait = std::move($1); }
|
|
||||||
| stmt_waittill { $$.as_waittill = std::move($1); }
|
|
||||||
| stmt_waittillmatch { $$.as_waittillmatch = std::move($1); }
|
|
||||||
| stmt_waittillframeend { $$.as_waittillframeend = std::move($1); }
|
|
||||||
| stmt_if { $$.as_if = std::move($1); }
|
|
||||||
| stmt_ifelse { $$.as_ifelse = std::move($1); }
|
|
||||||
| stmt_while { $$.as_while = std::move($1); }
|
|
||||||
| stmt_dowhile { $$.as_dowhile = std::move($1); }
|
|
||||||
| stmt_for { $$.as_for = std::move($1); }
|
|
||||||
| stmt_foreach { $$.as_foreach = std::move($1); }
|
|
||||||
| stmt_switch { $$.as_switch = std::move($1); }
|
|
||||||
| stmt_case { $$.as_case = std::move($1); }
|
|
||||||
| stmt_default { $$.as_default = std::move($1); }
|
|
||||||
| stmt_break { $$.as_break = std::move($1); }
|
|
||||||
| stmt_continue { $$.as_continue = std::move($1); }
|
|
||||||
| stmt_return { $$.as_return = std::move($1); }
|
|
||||||
| stmt_breakpoint { $$.as_breakpoint = std::move($1); }
|
|
||||||
| stmt_prof_begin { $$.as_prof_begin = std::move($1); }
|
|
||||||
| stmt_prof_end { $$.as_prof_end = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_or_dev
|
|
||||||
: stmt { $$ = std::move($1); }
|
|
||||||
| stmt_dev { $$.as_dev = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_list
|
|
||||||
: stmt_list stmt
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($2)); }
|
|
||||||
| stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_list>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_or_dev_list
|
|
||||||
: stmt_or_dev_list stmt_or_dev
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($2)); }
|
|
||||||
| stmt_or_dev
|
|
||||||
{ $$ = std::make_unique<ast::stmt_list>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_dev
|
|
||||||
: DEVBEGIN stmt_list DEVEND { $$ = std::make_unique<ast::stmt_dev>(@$, std::move($2)); }
|
|
||||||
| DEVBEGIN DEVEND { $$ = std::make_unique<ast::stmt_dev>(@$, std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_block
|
|
||||||
: LBRACE stmt_or_dev_list RBRACE { $$ = std::move($2); }
|
|
||||||
| LBRACE RBRACE { $$ = std::make_unique<ast::stmt_list>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_expr
|
|
||||||
: expr_assign
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
| expr_increment
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
| expr_decrement
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::make_unique<ast::node>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_call
|
|
||||||
: expr_call SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_call>(@$, ast::expr(std::move($1))); }
|
|
||||||
| expr_method SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_call>(@$, ast::expr(std::move($1))); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_assign
|
|
||||||
: expr_assign SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
| expr_increment SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
| expr_decrement SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_endon
|
|
||||||
: expr_object ENDON LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_endon>(@$, std::move($1), std::move($4)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_notify
|
|
||||||
: expr_object NOTIFY LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_notify>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object NOTIFY LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_notify>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_wait
|
|
||||||
: WAIT expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_wait>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittill
|
|
||||||
: expr_object WAITTILL LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittill>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object WAITTILL LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittill>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittillmatch
|
|
||||||
: expr_object WAITTILLMATCH LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillmatch>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object WAITTILLMATCH LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillmatch>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittillframeend
|
|
||||||
: WAITTILLFRAMEEND SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillframeend>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_if
|
|
||||||
: IF LPAREN expr RPAREN stmt %prec THEN
|
|
||||||
{ $$ = std::make_unique<ast::stmt_if>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_ifelse
|
|
||||||
: IF LPAREN expr RPAREN stmt ELSE stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_ifelse>(@$, std::move($3), std::move($5), std::move($7)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_while
|
|
||||||
: WHILE LPAREN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_while>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_dowhile
|
|
||||||
: DO stmt WHILE LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_dowhile>(@$, std::move($5), std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_for
|
|
||||||
: FOR LPAREN stmt_expr SEMICOLON expr_or_empty SEMICOLON stmt_expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_for>(@$, ast::stmt(std::move($3)), std::move($5), ast::stmt(std::move($7)), std::move($9)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_foreach
|
|
||||||
: FOREACH LPAREN expr_identifier IN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_foreach>(@$, ast::expr(std::move($3)), std::move($5), std::move($7)); }
|
|
||||||
| FOREACH LPAREN expr_identifier COMMA expr_identifier IN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_foreach>(@$, ast::expr(std::move($3)), ast::expr(std::move($5)), std::move($7), std::move($9)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_switch
|
|
||||||
: SWITCH LPAREN expr RPAREN stmt_block
|
|
||||||
{ $$ = std::make_unique<ast::stmt_switch>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_case
|
|
||||||
: CASE expr_integer COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_case>(@$, ast::expr(std::move($2)), std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
| CASE expr_string COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_case>(@$, ast::expr(std::move($2)), std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_default
|
|
||||||
: DEFAULT COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_default>(@$, std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_break
|
|
||||||
: BREAK SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_break>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_continue
|
|
||||||
: CONTINUE SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_continue>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_return
|
|
||||||
: RETURN expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_return>(@$, std::move($2)); }
|
|
||||||
| RETURN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_return>(@$, std::make_unique<ast::node>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_breakpoint
|
|
||||||
: BREAKPOINT SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_breakpoint>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_prof_begin
|
|
||||||
: PROFBEGIN LPAREN expr_arguments RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_prof_begin>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_prof_end
|
|
||||||
: PROFEND LPAREN expr_arguments RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_prof_end>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr
|
|
||||||
: expr_ternary { $$ = std::move($1); }
|
|
||||||
| expr_binary { $$ = std::move($1); }
|
|
||||||
| expr_primitive { $$ = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_or_empty
|
|
||||||
: expr { $$ = std::move($1); }
|
|
||||||
| { $$.as_node = std::make_unique<ast::node>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_assign
|
|
||||||
: expr_object ASSIGN expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_EXOR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_exor>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_LSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_shift_left>(@$, std::move($1),std::move( $3)); }
|
|
||||||
| expr_object ASSIGN_RSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_shift_right>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_ADD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_add>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_SUB expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_sub>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_MUL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_mul>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_DIV expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_div>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_MOD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_mod>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_increment
|
|
||||||
: INCREMENT expr_object %prec PREINC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_increment>(@$, std::move($2), true); }
|
|
||||||
| expr_object INCREMENT %prec POSTINC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_increment>(@$, std::move($1), false); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_decrement
|
|
||||||
: DECREMENT expr_object %prec PREDEC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_decrement>(@$, std::move($2), true); }
|
|
||||||
| expr_object DECREMENT %prec POSTDEC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_decrement>(@$, std::move($1), false); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_ternary
|
|
||||||
: expr QMARK expr COLON expr %prec TERN
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_ternary>(@$, std::move($1), std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_binary
|
|
||||||
: expr OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr EQUALITY expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_equality>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr INEQUALITY expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_inequality>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LESS_EQUAL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_less_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr GREATER_EQUAL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_greater_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LESS expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_less>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr GREATER expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_greater>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_EXOR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_exor>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_shift_left>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr RSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_shift_right>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr ADD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_add>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr SUB expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_sub>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr MUL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_mul>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr DIV expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_div>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr MOD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_mod>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_primitive
|
|
||||||
: expr_complement { $$.as_node = std::move($1); }
|
|
||||||
| expr_negate { $$.as_node = std::move($1); }
|
|
||||||
| expr_not { $$.as_node = std::move($1); }
|
|
||||||
| expr_call { $$.as_node = std::move($1); }
|
|
||||||
| expr_method { $$.as_node = std::move($1); }
|
|
||||||
| expr_add_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_reference { $$.as_node = std::move($1); }
|
|
||||||
| expr_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_field { $$.as_node = std::move($1); }
|
|
||||||
| expr_size { $$.as_node = std::move($1); }
|
|
||||||
| expr_paren { $$.as_node = std::move($1); }
|
|
||||||
| expr_thisthread { $$.as_node = std::move($1); }
|
|
||||||
| expr_empty_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_undefined { $$.as_node = std::move($1); }
|
|
||||||
| expr_game { $$.as_node = std::move($1); }
|
|
||||||
| expr_self { $$.as_node = std::move($1); }
|
|
||||||
| expr_anim { $$.as_node = std::move($1); }
|
|
||||||
| expr_level { $$.as_node = std::move($1); }
|
|
||||||
| expr_animation { $$.as_node = std::move($1); }
|
|
||||||
| expr_animtree { $$.as_node = std::move($1); }
|
|
||||||
| expr_identifier { $$.as_node = std::move($1); }
|
|
||||||
| expr_istring { $$.as_node = std::move($1); }
|
|
||||||
| expr_string { $$.as_node = std::move($1); }
|
|
||||||
| expr_vector { $$.as_node = std::move($1); }
|
|
||||||
| expr_float { $$.as_node = std::move($1); }
|
|
||||||
| expr_integer { $$.as_node = std::move($1); }
|
|
||||||
| expr_false { $$.as_node = std::move($1); }
|
|
||||||
| expr_true { $$.as_node = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_complement
|
|
||||||
: COMPLEMENT expr
|
|
||||||
{ $$ = std::make_unique<ast::expr_complement>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_negate
|
|
||||||
: SUB expr_identifier %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_paren %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_array %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_field %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_not
|
|
||||||
: NOT expr
|
|
||||||
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_call
|
|
||||||
: expr_function { $$ = std::make_unique<ast::expr_call>(@$, std::move($1)); }
|
|
||||||
| expr_pointer { $$ = std::make_unique<ast::expr_call>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
expr_method
|
|
||||||
: expr_object expr_function { $$ = std::make_unique<ast::expr_method>(@$, std::move($1), std::move($2)); }
|
|
||||||
| expr_object expr_pointer { $$ = std::make_unique<ast::expr_method>(@$, std::move($1), std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_function
|
|
||||||
: expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($1), std::move($3), ast::call::mode::normal); }
|
|
||||||
| expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($1), std::move($3), std::move($5), ast::call::mode::normal); }
|
|
||||||
| THREAD expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($2), std::move($4), ast::call::mode::thread); }
|
|
||||||
| THREAD expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($2), std::move($4), std::move($6), ast::call::mode::thread); }
|
|
||||||
| CHILDTHREAD expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($2), std::move($4), ast::call::mode::childthread); }
|
|
||||||
| CHILDTHREAD expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($2), std::move($4), std::move($6), ast::call::mode::childthread); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_pointer
|
|
||||||
: LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($3), std::move($7), ast::call::mode::normal); }
|
|
||||||
| THREAD LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::thread); }
|
|
||||||
| CHILDTHREAD LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::childthread); }
|
|
||||||
| CALL LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::builtin); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_add_array
|
|
||||||
: LBRACKET expr_arguments_no_empty RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_add_array>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_parameters
|
|
||||||
: expr_parameters COMMA expr_identifier
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($3)); }
|
|
||||||
| expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_parameters>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::expr_parameters>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_arguments
|
|
||||||
: expr_arguments_no_empty
|
|
||||||
{ $$ = std::move($1); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::expr_arguments>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_arguments_no_empty
|
|
||||||
: expr_arguments COMMA expr
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($3)); }
|
|
||||||
| expr %prec ADD_ARRAY
|
|
||||||
{ $$ = std::make_unique<ast::expr_arguments>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_reference
|
|
||||||
: DOUBLECOLON expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_reference>(@$, std::make_unique<ast::expr_path>(@$), std::move($2)); }
|
|
||||||
| expr_path DOUBLECOLON expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_reference>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_array
|
|
||||||
: expr_object LBRACKET expr RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_array>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_field
|
|
||||||
: expr_object DOT expr_identifier_nosize
|
|
||||||
{ $$ = std::make_unique<ast::expr_field>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_size
|
|
||||||
: expr_object DOT SIZE %prec SIZEOF
|
|
||||||
{ $$ = std::make_unique<ast::expr_size>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_paren
|
|
||||||
: LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_paren>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_object
|
|
||||||
: expr_call { $$.as_node = std::move($1); }
|
|
||||||
| expr_method { $$.as_node = std::move($1); }
|
|
||||||
| expr_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_field { $$.as_node = std::move($1); }
|
|
||||||
| expr_game { $$.as_node = std::move($1); }
|
|
||||||
| expr_self { $$.as_node = std::move($1); }
|
|
||||||
| expr_anim { $$.as_node = std::move($1); }
|
|
||||||
| expr_level { $$.as_node = std::move($1); }
|
|
||||||
| expr_identifier { $$.as_node = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_thisthread
|
|
||||||
: THISTHREAD
|
|
||||||
{ $$ = std::make_unique<ast::expr_thisthread>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_empty_array
|
|
||||||
: LBRACKET RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_empty_array>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_undefined
|
|
||||||
: UNDEFINED
|
|
||||||
{ $$ = std::make_unique<ast::expr_undefined>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_game
|
|
||||||
: GAME
|
|
||||||
{ $$ = std::make_unique<ast::expr_game>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_self
|
|
||||||
: SELF
|
|
||||||
{ $$ = std::make_unique<ast::expr_self>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_anim
|
|
||||||
: ANIM
|
|
||||||
{ $$ = std::make_unique<ast::expr_anim>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_level
|
|
||||||
: LEVEL
|
|
||||||
{ $$ = std::make_unique<ast::expr_level>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_animation
|
|
||||||
: MOD IDENTIFIER %prec ANIMREF
|
|
||||||
{ $$ = std::make_unique<ast::expr_animation>(@$, $2); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_animtree
|
|
||||||
: ANIMTREE
|
|
||||||
{ $$ = std::make_unique<ast::expr_animtree>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_identifier_nosize
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_identifier
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, $1); };
|
|
||||||
| SIZE
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, "size"); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_path
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_path>(@$, $1); };
|
|
||||||
| PATH
|
|
||||||
{ $$ = std::make_unique<ast::expr_path>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_istring
|
|
||||||
: ISTRING
|
|
||||||
{ $$ = std::make_unique<ast::expr_istring>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_string
|
|
||||||
: STRING
|
|
||||||
{ $$ = std::make_unique<ast::expr_string>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_vector
|
|
||||||
: LPAREN expr COMMA expr COMMA expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_vector>(@$, std::move($2), std::move($4), std::move($6)); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_float
|
|
||||||
: SUB FLOAT %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_float>(@$, "-" + $2); };
|
|
||||||
| FLOAT
|
|
||||||
{ $$ = std::make_unique<ast::expr_float>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_integer
|
|
||||||
: SUB INTEGER %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_integer>(@$, "-" + $2); };
|
|
||||||
| INTEGER
|
|
||||||
{ $$ = std::make_unique<ast::expr_integer>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_false
|
|
||||||
: FALSE
|
|
||||||
{ $$ = std::make_unique<ast::expr_false>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_true
|
|
||||||
: TRUE
|
|
||||||
{ $$ = std::make_unique<ast::expr_true>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
void xsk::gsc::iw5::parser::error(const xsk::gsc::location& loc, const std::string& msg)
|
|
||||||
{
|
|
||||||
throw xsk::gsc::comp_error(loc, msg);
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
generate: IW6
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf ./parser.hpp
|
|
||||||
rm -rf ./parser.cpp
|
|
||||||
|
|
||||||
IW6: parser.ypp
|
|
||||||
bison parser.ypp -Wcounterexamples
|
|
||||||
mv parser.hpp parser.cpp ../../src/iw6/xsk/
|
|
@ -1,865 +0,0 @@
|
|||||||
/* Copyright 2022 xensik. All rights reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a GNU GPLv3 license
|
|
||||||
// that can be found in the LICENSE file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
%require "3.7"
|
|
||||||
%skeleton "lalr1.cc"
|
|
||||||
%language "c++"
|
|
||||||
%output "parser.cpp"
|
|
||||||
%defines "parser.hpp"
|
|
||||||
%define api.prefix {IW6}
|
|
||||||
%define api.namespace {xsk::gsc::iw6}
|
|
||||||
%define api.location.type {xsk::gsc::location}
|
|
||||||
%define api.value.type variant
|
|
||||||
%define api.token.constructor
|
|
||||||
%define api.token.raw
|
|
||||||
%define parse.assert
|
|
||||||
%define parse.trace
|
|
||||||
%define parse.error detailed
|
|
||||||
%define parse.lac full
|
|
||||||
%locations
|
|
||||||
%lex-param { xsk::gsc::iw6::lexer& lexer }
|
|
||||||
%parse-param { xsk::gsc::iw6::lexer& lexer }
|
|
||||||
%parse-param { xsk::gsc::ast::program::ptr& ast }
|
|
||||||
|
|
||||||
%code requires
|
|
||||||
{
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(disable:4065)
|
|
||||||
#pragma warning(disable:4127)
|
|
||||||
#endif
|
|
||||||
#include "iw6.hpp"
|
|
||||||
namespace xsk::gsc::iw6 { class lexer; }
|
|
||||||
}
|
|
||||||
|
|
||||||
%code top
|
|
||||||
{
|
|
||||||
#include "stdafx.hpp"
|
|
||||||
#include "parser.hpp"
|
|
||||||
#include "lexer.hpp"
|
|
||||||
using namespace xsk::gsc;
|
|
||||||
xsk::gsc::iw6::parser::symbol_type IW6lex(xsk::gsc::iw6::lexer& lexer);
|
|
||||||
}
|
|
||||||
|
|
||||||
%token SH_DEFINE "#define"
|
|
||||||
%token SH_UNDEF "#undef"
|
|
||||||
%token SH_IFDEF "#ifdef"
|
|
||||||
%token SH_IFNDEF "#ifndef"
|
|
||||||
%token SH_IF "#if"
|
|
||||||
%token SH_ELIF "#elif"
|
|
||||||
%token SH_ELSE "#else"
|
|
||||||
%token SH_ENDIF "#endif"
|
|
||||||
%token DEVBEGIN "/#"
|
|
||||||
%token DEVEND "#/"
|
|
||||||
%token INLINE "#inline"
|
|
||||||
%token INCLUDE "#include"
|
|
||||||
%token USINGTREE "#using_animtree"
|
|
||||||
%token ANIMTREE "#animtree"
|
|
||||||
%token ENDON "endon"
|
|
||||||
%token NOTIFY "notify"
|
|
||||||
%token WAIT "wait"
|
|
||||||
%token WAITTILL "waittill"
|
|
||||||
%token WAITTILLMATCH "waittillmatch"
|
|
||||||
%token WAITTILLFRAMEEND "waittillframeend"
|
|
||||||
%token IF "if"
|
|
||||||
%token ELSE "else"
|
|
||||||
%token DO "do"
|
|
||||||
%token WHILE "while"
|
|
||||||
%token FOR "for"
|
|
||||||
%token FOREACH "foreach"
|
|
||||||
%token IN "in"
|
|
||||||
%token SWITCH "switch"
|
|
||||||
%token CASE "case"
|
|
||||||
%token DEFAULT "default"
|
|
||||||
%token BREAK "break"
|
|
||||||
%token CONTINUE "continue"
|
|
||||||
%token RETURN "return"
|
|
||||||
%token BREAKPOINT "breakpoint"
|
|
||||||
%token PROFBEGIN "prof_begin"
|
|
||||||
%token PROFEND "prof_end"
|
|
||||||
%token THREAD "thread"
|
|
||||||
%token CHILDTHREAD "childthread"
|
|
||||||
%token THISTHREAD "thisthread"
|
|
||||||
%token CALL "call"
|
|
||||||
%token TRUE "true"
|
|
||||||
%token FALSE "false"
|
|
||||||
%token UNDEFINED "undefined"
|
|
||||||
%token SIZE "size"
|
|
||||||
%token GAME "game"
|
|
||||||
%token SELF "self"
|
|
||||||
%token ANIM "anim"
|
|
||||||
%token LEVEL "level"
|
|
||||||
%token LPAREN "("
|
|
||||||
%token RPAREN ")"
|
|
||||||
%token LBRACE "{"
|
|
||||||
%token RBRACE "}"
|
|
||||||
%token LBRACKET "["
|
|
||||||
%token RBRACKET "]"
|
|
||||||
%token COMMA ","
|
|
||||||
%token DOT "."
|
|
||||||
%token DOUBLECOLON "::"
|
|
||||||
%token COLON ":"
|
|
||||||
%token SEMICOLON ";"
|
|
||||||
%token QMARK "?"
|
|
||||||
%token INCREMENT "++"
|
|
||||||
%token DECREMENT "--"
|
|
||||||
%token LSHIFT "<<"
|
|
||||||
%token RSHIFT ">>"
|
|
||||||
%token OR "||"
|
|
||||||
%token AND "&&"
|
|
||||||
%token EQUALITY "=="
|
|
||||||
%token INEQUALITY "!="
|
|
||||||
%token LESS_EQUAL "<="
|
|
||||||
%token GREATER_EQUAL ">="
|
|
||||||
%token LESS "<"
|
|
||||||
%token GREATER ">"
|
|
||||||
%token NOT "!"
|
|
||||||
%token COMPLEMENT "~"
|
|
||||||
%token ASSIGN "="
|
|
||||||
%token ASSIGN_ADD "+="
|
|
||||||
%token ASSIGN_SUB "-="
|
|
||||||
%token ASSIGN_MUL "*="
|
|
||||||
%token ASSIGN_DIV "/="
|
|
||||||
%token ASSIGN_MOD "%="
|
|
||||||
%token ASSIGN_BW_OR "|="
|
|
||||||
%token ASSIGN_BW_AND "&="
|
|
||||||
%token ASSIGN_BW_EXOR "^="
|
|
||||||
%token ASSIGN_RSHIFT ">>="
|
|
||||||
%token ASSIGN_LSHIFT "<<="
|
|
||||||
%token BITWISE_OR "|"
|
|
||||||
%token BITWISE_AND "&"
|
|
||||||
%token BITWISE_EXOR "^"
|
|
||||||
%token ADD "+"
|
|
||||||
%token SUB "-"
|
|
||||||
%token MUL "*"
|
|
||||||
%token DIV "/"
|
|
||||||
%token MOD "%"
|
|
||||||
%token <std::string> PATH "path"
|
|
||||||
%token <std::string> IDENTIFIER "identifier"
|
|
||||||
%token <std::string> STRING "string literal"
|
|
||||||
%token <std::string> ISTRING "localized string"
|
|
||||||
%token <std::string> FLOAT "float"
|
|
||||||
%token <std::string> INTEGER "integer"
|
|
||||||
|
|
||||||
%type <ast::program::ptr> program
|
|
||||||
%type <ast::include::ptr> include
|
|
||||||
%type <ast::decl> declaration
|
|
||||||
%type <ast::decl_usingtree::ptr> decl_usingtree
|
|
||||||
%type <ast::decl_constant::ptr> decl_constant
|
|
||||||
%type <ast::decl_thread::ptr> decl_thread
|
|
||||||
%type <ast::stmt> stmt
|
|
||||||
%type <ast::stmt> stmt_or_dev
|
|
||||||
%type <ast::stmt_list::ptr> stmt_list
|
|
||||||
%type <ast::stmt_list::ptr> stmt_or_dev_list
|
|
||||||
%type <ast::stmt_dev::ptr> stmt_dev
|
|
||||||
%type <ast::stmt_list::ptr> stmt_block
|
|
||||||
%type <ast::stmt_expr::ptr> stmt_expr
|
|
||||||
%type <ast::stmt_call::ptr> stmt_call
|
|
||||||
%type <ast::stmt_assign::ptr> stmt_assign
|
|
||||||
%type <ast::stmt_endon::ptr> stmt_endon
|
|
||||||
%type <ast::stmt_notify::ptr> stmt_notify
|
|
||||||
%type <ast::stmt_wait::ptr> stmt_wait
|
|
||||||
%type <ast::stmt_waittill::ptr> stmt_waittill
|
|
||||||
%type <ast::stmt_waittillmatch::ptr> stmt_waittillmatch
|
|
||||||
%type <ast::stmt_waittillframeend::ptr> stmt_waittillframeend
|
|
||||||
%type <ast::stmt_if::ptr> stmt_if
|
|
||||||
%type <ast::stmt_ifelse::ptr> stmt_ifelse
|
|
||||||
%type <ast::stmt_while::ptr> stmt_while
|
|
||||||
%type <ast::stmt_dowhile::ptr> stmt_dowhile
|
|
||||||
%type <ast::stmt_for::ptr> stmt_for
|
|
||||||
%type <ast::stmt_foreach::ptr> stmt_foreach
|
|
||||||
%type <ast::stmt_switch::ptr> stmt_switch
|
|
||||||
%type <ast::stmt_case::ptr> stmt_case
|
|
||||||
%type <ast::stmt_default::ptr> stmt_default
|
|
||||||
%type <ast::stmt_break::ptr> stmt_break
|
|
||||||
%type <ast::stmt_continue::ptr> stmt_continue
|
|
||||||
%type <ast::stmt_return::ptr> stmt_return
|
|
||||||
%type <ast::stmt_breakpoint::ptr> stmt_breakpoint
|
|
||||||
%type <ast::stmt_prof_begin::ptr> stmt_prof_begin
|
|
||||||
%type <ast::stmt_prof_end::ptr> stmt_prof_end
|
|
||||||
%type <ast::expr> expr
|
|
||||||
%type <ast::expr> expr_or_empty
|
|
||||||
%type <ast::expr> expr_assign
|
|
||||||
%type <ast::expr> expr_increment
|
|
||||||
%type <ast::expr> expr_decrement
|
|
||||||
%type <ast::expr> expr_ternary
|
|
||||||
%type <ast::expr> expr_binary
|
|
||||||
%type <ast::expr> expr_primitive
|
|
||||||
%type <ast::expr_complement::ptr> expr_complement
|
|
||||||
%type <ast::expr_negate::ptr> expr_negate
|
|
||||||
%type <ast::expr_not::ptr> expr_not
|
|
||||||
%type <ast::expr_call::ptr> expr_call
|
|
||||||
%type <ast::expr_method::ptr> expr_method
|
|
||||||
%type <ast::call> expr_function
|
|
||||||
%type <ast::call> expr_pointer
|
|
||||||
%type <ast::expr_add_array::ptr> expr_add_array
|
|
||||||
%type <ast::expr_parameters::ptr> expr_parameters
|
|
||||||
%type <ast::expr_arguments::ptr> expr_arguments
|
|
||||||
%type <ast::expr_arguments::ptr> expr_arguments_no_empty
|
|
||||||
%type <ast::expr_reference::ptr> expr_reference
|
|
||||||
%type <ast::expr_array::ptr> expr_array
|
|
||||||
%type <ast::expr_field::ptr> expr_field
|
|
||||||
%type <ast::expr_size::ptr> expr_size
|
|
||||||
%type <ast::expr_paren::ptr> expr_paren
|
|
||||||
%type <ast::expr> expr_object
|
|
||||||
%type <ast::expr_thisthread::ptr> expr_thisthread
|
|
||||||
%type <ast::expr_empty_array::ptr> expr_empty_array
|
|
||||||
%type <ast::expr_undefined::ptr> expr_undefined
|
|
||||||
%type <ast::expr_game::ptr> expr_game
|
|
||||||
%type <ast::expr_self::ptr> expr_self
|
|
||||||
%type <ast::expr_anim::ptr> expr_anim
|
|
||||||
%type <ast::expr_level::ptr> expr_level
|
|
||||||
%type <ast::expr_animation::ptr> expr_animation
|
|
||||||
%type <ast::expr_animtree::ptr> expr_animtree
|
|
||||||
%type <ast::expr_identifier::ptr> expr_identifier_nosize
|
|
||||||
%type <ast::expr_identifier::ptr> expr_identifier
|
|
||||||
%type <ast::expr_path::ptr> expr_path
|
|
||||||
%type <ast::expr_istring::ptr> expr_istring
|
|
||||||
%type <ast::expr_string::ptr> expr_string
|
|
||||||
%type <ast::expr_vector::ptr> expr_vector
|
|
||||||
%type <ast::expr_float::ptr> expr_float
|
|
||||||
%type <ast::expr_integer::ptr> expr_integer
|
|
||||||
%type <ast::expr_false::ptr> expr_false
|
|
||||||
%type <ast::expr_true::ptr> expr_true
|
|
||||||
|
|
||||||
%nonassoc SIZEOF
|
|
||||||
%nonassoc ADD_ARRAY
|
|
||||||
%nonassoc RBRACKET
|
|
||||||
%nonassoc THEN
|
|
||||||
%nonassoc ELSE
|
|
||||||
%nonassoc INCREMENT DECREMENT
|
|
||||||
|
|
||||||
%precedence TERN
|
|
||||||
%right QMARK
|
|
||||||
%left OR
|
|
||||||
%left AND
|
|
||||||
%left BITWISE_OR
|
|
||||||
%left BITWISE_EXOR
|
|
||||||
%left BITWISE_AND
|
|
||||||
%left EQUALITY INEQUALITY
|
|
||||||
%left LESS GREATER LESS_EQUAL GREATER_EQUAL
|
|
||||||
%left LSHIFT RSHIFT
|
|
||||||
%left ADD SUB
|
|
||||||
%left MUL DIV MOD
|
|
||||||
%right NOT COMPLEMENT
|
|
||||||
|
|
||||||
%precedence NEG
|
|
||||||
%precedence ANIMREF
|
|
||||||
%precedence PREINC PREDEC
|
|
||||||
%precedence POSTINC POSTDEC
|
|
||||||
|
|
||||||
%start root
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
root
|
|
||||||
: program { ast = std::move($1); }
|
|
||||||
| { ast = std::make_unique<ast::program>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
program
|
|
||||||
: program inline
|
|
||||||
{ $$ = std::move($1); }
|
|
||||||
| program include
|
|
||||||
{ $$ = std::move($1); $$->includes.push_back(std::move($2)); }
|
|
||||||
| program declaration
|
|
||||||
{ $$ = std::move($1); $$->declarations.push_back(std::move($2)); }
|
|
||||||
| inline
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); }
|
|
||||||
| include
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); $$->includes.push_back(std::move($1)); }
|
|
||||||
| declaration
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); $$->declarations.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
inline
|
|
||||||
: INLINE expr_path SEMICOLON { lexer.push_header($2->value); }
|
|
||||||
;
|
|
||||||
|
|
||||||
include
|
|
||||||
: INCLUDE expr_path SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::include>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
declaration
|
|
||||||
: DEVBEGIN { $$.as_dev_begin = std::make_unique<ast::decl_dev_begin>(@$); }
|
|
||||||
| DEVEND { $$.as_dev_end = std::make_unique<ast::decl_dev_end>(@$); }
|
|
||||||
| decl_usingtree { $$.as_usingtree = std::move($1); }
|
|
||||||
| decl_constant { $$.as_constant = std::move($1); }
|
|
||||||
| decl_thread { $$.as_thread = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_usingtree
|
|
||||||
: USINGTREE LPAREN expr_string RPAREN SEMICOLON
|
|
||||||
{ lexer.ban_header(@$); $$ = std::make_unique<ast::decl_usingtree>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_constant
|
|
||||||
: expr_identifier ASSIGN expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::decl_constant>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_thread
|
|
||||||
: expr_identifier LPAREN expr_parameters RPAREN stmt_block
|
|
||||||
{ lexer.ban_header(@$); $$ = std::make_unique<ast::decl_thread>(@$, std::move($1), std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt
|
|
||||||
: stmt_block { $$.as_list = std::move($1); }
|
|
||||||
| stmt_call { $$.as_call = std::move($1); }
|
|
||||||
| stmt_assign { $$.as_assign = std::move($1); }
|
|
||||||
| stmt_endon { $$.as_endon = std::move($1); }
|
|
||||||
| stmt_notify { $$.as_notify = std::move($1); }
|
|
||||||
| stmt_wait { $$.as_wait = std::move($1); }
|
|
||||||
| stmt_waittill { $$.as_waittill = std::move($1); }
|
|
||||||
| stmt_waittillmatch { $$.as_waittillmatch = std::move($1); }
|
|
||||||
| stmt_waittillframeend { $$.as_waittillframeend = std::move($1); }
|
|
||||||
| stmt_if { $$.as_if = std::move($1); }
|
|
||||||
| stmt_ifelse { $$.as_ifelse = std::move($1); }
|
|
||||||
| stmt_while { $$.as_while = std::move($1); }
|
|
||||||
| stmt_dowhile { $$.as_dowhile = std::move($1); }
|
|
||||||
| stmt_for { $$.as_for = std::move($1); }
|
|
||||||
| stmt_foreach { $$.as_foreach = std::move($1); }
|
|
||||||
| stmt_switch { $$.as_switch = std::move($1); }
|
|
||||||
| stmt_case { $$.as_case = std::move($1); }
|
|
||||||
| stmt_default { $$.as_default = std::move($1); }
|
|
||||||
| stmt_break { $$.as_break = std::move($1); }
|
|
||||||
| stmt_continue { $$.as_continue = std::move($1); }
|
|
||||||
| stmt_return { $$.as_return = std::move($1); }
|
|
||||||
| stmt_breakpoint { $$.as_breakpoint = std::move($1); }
|
|
||||||
| stmt_prof_begin { $$.as_prof_begin = std::move($1); }
|
|
||||||
| stmt_prof_end { $$.as_prof_end = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_or_dev
|
|
||||||
: stmt { $$ = std::move($1); }
|
|
||||||
| stmt_dev { $$.as_dev = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_list
|
|
||||||
: stmt_list stmt
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($2)); }
|
|
||||||
| stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_list>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_or_dev_list
|
|
||||||
: stmt_or_dev_list stmt_or_dev
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($2)); }
|
|
||||||
| stmt_or_dev
|
|
||||||
{ $$ = std::make_unique<ast::stmt_list>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_dev
|
|
||||||
: DEVBEGIN stmt_list DEVEND { $$ = std::make_unique<ast::stmt_dev>(@$, std::move($2)); }
|
|
||||||
| DEVBEGIN DEVEND { $$ = std::make_unique<ast::stmt_dev>(@$, std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_block
|
|
||||||
: LBRACE stmt_or_dev_list RBRACE { $$ = std::move($2); }
|
|
||||||
| LBRACE RBRACE { $$ = std::make_unique<ast::stmt_list>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_expr
|
|
||||||
: expr_assign
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
| expr_increment
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
| expr_decrement
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::make_unique<ast::node>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_call
|
|
||||||
: expr_call SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_call>(@$, ast::expr(std::move($1))); }
|
|
||||||
| expr_method SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_call>(@$, ast::expr(std::move($1))); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_assign
|
|
||||||
: expr_assign SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
| expr_increment SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
| expr_decrement SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_endon
|
|
||||||
: expr_object ENDON LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_endon>(@$, std::move($1), std::move($4)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_notify
|
|
||||||
: expr_object NOTIFY LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_notify>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object NOTIFY LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_notify>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_wait
|
|
||||||
: WAIT expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_wait>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittill
|
|
||||||
: expr_object WAITTILL LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittill>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object WAITTILL LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittill>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittillmatch
|
|
||||||
: expr_object WAITTILLMATCH LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillmatch>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object WAITTILLMATCH LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillmatch>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittillframeend
|
|
||||||
: WAITTILLFRAMEEND SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillframeend>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_if
|
|
||||||
: IF LPAREN expr RPAREN stmt %prec THEN
|
|
||||||
{ $$ = std::make_unique<ast::stmt_if>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_ifelse
|
|
||||||
: IF LPAREN expr RPAREN stmt ELSE stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_ifelse>(@$, std::move($3), std::move($5), std::move($7)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_while
|
|
||||||
: WHILE LPAREN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_while>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_dowhile
|
|
||||||
: DO stmt WHILE LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_dowhile>(@$, std::move($5), std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_for
|
|
||||||
: FOR LPAREN stmt_expr SEMICOLON expr_or_empty SEMICOLON stmt_expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_for>(@$, ast::stmt(std::move($3)), std::move($5), ast::stmt(std::move($7)), std::move($9)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_foreach
|
|
||||||
: FOREACH LPAREN expr_identifier IN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_foreach>(@$, ast::expr(std::move($3)), std::move($5), std::move($7)); }
|
|
||||||
| FOREACH LPAREN expr_identifier COMMA expr_identifier IN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_foreach>(@$, ast::expr(std::move($3)), ast::expr(std::move($5)), std::move($7), std::move($9)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_switch
|
|
||||||
: SWITCH LPAREN expr RPAREN stmt_block
|
|
||||||
{ $$ = std::make_unique<ast::stmt_switch>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_case
|
|
||||||
: CASE expr_integer COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_case>(@$, ast::expr(std::move($2)), std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
| CASE expr_string COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_case>(@$, ast::expr(std::move($2)), std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_default
|
|
||||||
: DEFAULT COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_default>(@$, std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_break
|
|
||||||
: BREAK SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_break>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_continue
|
|
||||||
: CONTINUE SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_continue>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_return
|
|
||||||
: RETURN expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_return>(@$, std::move($2)); }
|
|
||||||
| RETURN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_return>(@$, std::make_unique<ast::node>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_breakpoint
|
|
||||||
: BREAKPOINT SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_breakpoint>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_prof_begin
|
|
||||||
: PROFBEGIN LPAREN expr_arguments RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_prof_begin>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_prof_end
|
|
||||||
: PROFEND LPAREN expr_arguments RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_prof_end>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr
|
|
||||||
: expr_ternary { $$ = std::move($1); }
|
|
||||||
| expr_binary { $$ = std::move($1); }
|
|
||||||
| expr_primitive { $$ = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_or_empty
|
|
||||||
: expr { $$ = std::move($1); }
|
|
||||||
| { $$.as_node = std::make_unique<ast::node>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_assign
|
|
||||||
: expr_object ASSIGN expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_EXOR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_exor>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_LSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_shift_left>(@$, std::move($1),std::move( $3)); }
|
|
||||||
| expr_object ASSIGN_RSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_shift_right>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_ADD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_add>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_SUB expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_sub>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_MUL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_mul>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_DIV expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_div>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_MOD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_mod>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_increment
|
|
||||||
: INCREMENT expr_object %prec PREINC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_increment>(@$, std::move($2), true); }
|
|
||||||
| expr_object INCREMENT %prec POSTINC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_increment>(@$, std::move($1), false); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_decrement
|
|
||||||
: DECREMENT expr_object %prec PREDEC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_decrement>(@$, std::move($2), true); }
|
|
||||||
| expr_object DECREMENT %prec POSTDEC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_decrement>(@$, std::move($1), false); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_ternary
|
|
||||||
: expr QMARK expr COLON expr %prec TERN
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_ternary>(@$, std::move($1), std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_binary
|
|
||||||
: expr OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr EQUALITY expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_equality>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr INEQUALITY expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_inequality>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LESS_EQUAL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_less_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr GREATER_EQUAL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_greater_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LESS expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_less>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr GREATER expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_greater>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_EXOR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_exor>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_shift_left>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr RSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_shift_right>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr ADD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_add>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr SUB expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_sub>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr MUL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_mul>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr DIV expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_div>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr MOD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_mod>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_primitive
|
|
||||||
: expr_complement { $$.as_node = std::move($1); }
|
|
||||||
| expr_negate { $$.as_node = std::move($1); }
|
|
||||||
| expr_not { $$.as_node = std::move($1); }
|
|
||||||
| expr_call { $$.as_node = std::move($1); }
|
|
||||||
| expr_method { $$.as_node = std::move($1); }
|
|
||||||
| expr_add_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_reference { $$.as_node = std::move($1); }
|
|
||||||
| expr_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_field { $$.as_node = std::move($1); }
|
|
||||||
| expr_size { $$.as_node = std::move($1); }
|
|
||||||
| expr_paren { $$.as_node = std::move($1); }
|
|
||||||
| expr_thisthread { $$.as_node = std::move($1); }
|
|
||||||
| expr_empty_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_undefined { $$.as_node = std::move($1); }
|
|
||||||
| expr_game { $$.as_node = std::move($1); }
|
|
||||||
| expr_self { $$.as_node = std::move($1); }
|
|
||||||
| expr_anim { $$.as_node = std::move($1); }
|
|
||||||
| expr_level { $$.as_node = std::move($1); }
|
|
||||||
| expr_animation { $$.as_node = std::move($1); }
|
|
||||||
| expr_animtree { $$.as_node = std::move($1); }
|
|
||||||
| expr_identifier { $$.as_node = std::move($1); }
|
|
||||||
| expr_istring { $$.as_node = std::move($1); }
|
|
||||||
| expr_string { $$.as_node = std::move($1); }
|
|
||||||
| expr_vector { $$.as_node = std::move($1); }
|
|
||||||
| expr_float { $$.as_node = std::move($1); }
|
|
||||||
| expr_integer { $$.as_node = std::move($1); }
|
|
||||||
| expr_false { $$.as_node = std::move($1); }
|
|
||||||
| expr_true { $$.as_node = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_complement
|
|
||||||
: COMPLEMENT expr
|
|
||||||
{ $$ = std::make_unique<ast::expr_complement>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_negate
|
|
||||||
: SUB expr_identifier %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_paren %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_array %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_field %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_not
|
|
||||||
: NOT expr
|
|
||||||
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_call
|
|
||||||
: expr_function { $$ = std::make_unique<ast::expr_call>(@$, std::move($1)); }
|
|
||||||
| expr_pointer { $$ = std::make_unique<ast::expr_call>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
expr_method
|
|
||||||
: expr_object expr_function { $$ = std::make_unique<ast::expr_method>(@$, std::move($1), std::move($2)); }
|
|
||||||
| expr_object expr_pointer { $$ = std::make_unique<ast::expr_method>(@$, std::move($1), std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_function
|
|
||||||
: expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($1), std::move($3), ast::call::mode::normal); }
|
|
||||||
| expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($1), std::move($3), std::move($5), ast::call::mode::normal); }
|
|
||||||
| THREAD expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($2), std::move($4), ast::call::mode::thread); }
|
|
||||||
| THREAD expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($2), std::move($4), std::move($6), ast::call::mode::thread); }
|
|
||||||
| CHILDTHREAD expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($2), std::move($4), ast::call::mode::childthread); }
|
|
||||||
| CHILDTHREAD expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($2), std::move($4), std::move($6), ast::call::mode::childthread); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_pointer
|
|
||||||
: LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($3), std::move($7), ast::call::mode::normal); }
|
|
||||||
| THREAD LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::thread); }
|
|
||||||
| CHILDTHREAD LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::childthread); }
|
|
||||||
| CALL LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::builtin); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_add_array
|
|
||||||
: LBRACKET expr_arguments_no_empty RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_add_array>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_parameters
|
|
||||||
: expr_parameters COMMA expr_identifier
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($3)); }
|
|
||||||
| expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_parameters>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::expr_parameters>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_arguments
|
|
||||||
: expr_arguments_no_empty
|
|
||||||
{ $$ = std::move($1); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::expr_arguments>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_arguments_no_empty
|
|
||||||
: expr_arguments COMMA expr
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($3)); }
|
|
||||||
| expr %prec ADD_ARRAY
|
|
||||||
{ $$ = std::make_unique<ast::expr_arguments>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_reference
|
|
||||||
: DOUBLECOLON expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_reference>(@$, std::make_unique<ast::expr_path>(@$), std::move($2)); }
|
|
||||||
| expr_path DOUBLECOLON expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_reference>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_array
|
|
||||||
: expr_object LBRACKET expr RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_array>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_field
|
|
||||||
: expr_object DOT expr_identifier_nosize
|
|
||||||
{ $$ = std::make_unique<ast::expr_field>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_size
|
|
||||||
: expr_object DOT SIZE %prec SIZEOF
|
|
||||||
{ $$ = std::make_unique<ast::expr_size>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_paren
|
|
||||||
: LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_paren>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_object
|
|
||||||
: expr_call { $$.as_node = std::move($1); }
|
|
||||||
| expr_method { $$.as_node = std::move($1); }
|
|
||||||
| expr_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_field { $$.as_node = std::move($1); }
|
|
||||||
| expr_game { $$.as_node = std::move($1); }
|
|
||||||
| expr_self { $$.as_node = std::move($1); }
|
|
||||||
| expr_anim { $$.as_node = std::move($1); }
|
|
||||||
| expr_level { $$.as_node = std::move($1); }
|
|
||||||
| expr_identifier { $$.as_node = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_thisthread
|
|
||||||
: THISTHREAD
|
|
||||||
{ $$ = std::make_unique<ast::expr_thisthread>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_empty_array
|
|
||||||
: LBRACKET RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_empty_array>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_undefined
|
|
||||||
: UNDEFINED
|
|
||||||
{ $$ = std::make_unique<ast::expr_undefined>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_game
|
|
||||||
: GAME
|
|
||||||
{ $$ = std::make_unique<ast::expr_game>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_self
|
|
||||||
: SELF
|
|
||||||
{ $$ = std::make_unique<ast::expr_self>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_anim
|
|
||||||
: ANIM
|
|
||||||
{ $$ = std::make_unique<ast::expr_anim>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_level
|
|
||||||
: LEVEL
|
|
||||||
{ $$ = std::make_unique<ast::expr_level>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_animation
|
|
||||||
: MOD IDENTIFIER %prec ANIMREF
|
|
||||||
{ $$ = std::make_unique<ast::expr_animation>(@$, $2); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_animtree
|
|
||||||
: ANIMTREE
|
|
||||||
{ $$ = std::make_unique<ast::expr_animtree>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_identifier_nosize
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_identifier
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, $1); };
|
|
||||||
| SIZE
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, "size"); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_path
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_path>(@$, $1); };
|
|
||||||
| PATH
|
|
||||||
{ $$ = std::make_unique<ast::expr_path>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_istring
|
|
||||||
: ISTRING
|
|
||||||
{ $$ = std::make_unique<ast::expr_istring>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_string
|
|
||||||
: STRING
|
|
||||||
{ $$ = std::make_unique<ast::expr_string>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_vector
|
|
||||||
: LPAREN expr COMMA expr COMMA expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_vector>(@$, std::move($2), std::move($4), std::move($6)); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_float
|
|
||||||
: SUB FLOAT %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_float>(@$, "-" + $2); };
|
|
||||||
| FLOAT
|
|
||||||
{ $$ = std::make_unique<ast::expr_float>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_integer
|
|
||||||
: SUB INTEGER %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_integer>(@$, "-" + $2); };
|
|
||||||
| INTEGER
|
|
||||||
{ $$ = std::make_unique<ast::expr_integer>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_false
|
|
||||||
: FALSE
|
|
||||||
{ $$ = std::make_unique<ast::expr_false>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_true
|
|
||||||
: TRUE
|
|
||||||
{ $$ = std::make_unique<ast::expr_true>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
void xsk::gsc::iw6::parser::error(const xsk::gsc::location& loc, const std::string& msg)
|
|
||||||
{
|
|
||||||
throw xsk::gsc::comp_error(loc, msg);
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
generate: IW7
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf ./parser.hpp
|
|
||||||
rm -rf ./parser.cpp
|
|
||||||
|
|
||||||
IW7: parser.ypp
|
|
||||||
bison parser.ypp -Wcounterexamples
|
|
||||||
mv parser.hpp parser.cpp ../../src/iw7/xsk/
|
|
@ -1,865 +0,0 @@
|
|||||||
/* Copyright 2022 xensik. All rights reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a GNU GPLv3 license
|
|
||||||
// that can be found in the LICENSE file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
%require "3.7"
|
|
||||||
%skeleton "lalr1.cc"
|
|
||||||
%language "c++"
|
|
||||||
%output "parser.cpp"
|
|
||||||
%defines "parser.hpp"
|
|
||||||
%define api.prefix {IW7}
|
|
||||||
%define api.namespace {xsk::gsc::iw7}
|
|
||||||
%define api.location.type {xsk::gsc::location}
|
|
||||||
%define api.value.type variant
|
|
||||||
%define api.token.constructor
|
|
||||||
%define api.token.raw
|
|
||||||
%define parse.assert
|
|
||||||
%define parse.trace
|
|
||||||
%define parse.error detailed
|
|
||||||
%define parse.lac full
|
|
||||||
%locations
|
|
||||||
%lex-param { xsk::gsc::iw7::lexer& lexer }
|
|
||||||
%parse-param { xsk::gsc::iw7::lexer& lexer }
|
|
||||||
%parse-param { xsk::gsc::ast::program::ptr& ast }
|
|
||||||
|
|
||||||
%code requires
|
|
||||||
{
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(disable:4065)
|
|
||||||
#pragma warning(disable:4127)
|
|
||||||
#endif
|
|
||||||
#include "iw7.hpp"
|
|
||||||
namespace xsk::gsc::iw7 { class lexer; }
|
|
||||||
}
|
|
||||||
|
|
||||||
%code top
|
|
||||||
{
|
|
||||||
#include "stdafx.hpp"
|
|
||||||
#include "parser.hpp"
|
|
||||||
#include "lexer.hpp"
|
|
||||||
using namespace xsk::gsc;
|
|
||||||
xsk::gsc::iw7::parser::symbol_type IW7lex(xsk::gsc::iw7::lexer& lexer);
|
|
||||||
}
|
|
||||||
|
|
||||||
%token SH_DEFINE "#define"
|
|
||||||
%token SH_UNDEF "#undef"
|
|
||||||
%token SH_IFDEF "#ifdef"
|
|
||||||
%token SH_IFNDEF "#ifndef"
|
|
||||||
%token SH_IF "#if"
|
|
||||||
%token SH_ELIF "#elif"
|
|
||||||
%token SH_ELSE "#else"
|
|
||||||
%token SH_ENDIF "#endif"
|
|
||||||
%token DEVBEGIN "/#"
|
|
||||||
%token DEVEND "#/"
|
|
||||||
%token INLINE "#inline"
|
|
||||||
%token INCLUDE "#include"
|
|
||||||
%token USINGTREE "#using_animtree"
|
|
||||||
%token ANIMTREE "#animtree"
|
|
||||||
%token ENDON "endon"
|
|
||||||
%token NOTIFY "notify"
|
|
||||||
%token WAIT "wait"
|
|
||||||
%token WAITTILL "waittill"
|
|
||||||
%token WAITTILLMATCH "waittillmatch"
|
|
||||||
%token WAITTILLFRAMEEND "waittillframeend"
|
|
||||||
%token IF "if"
|
|
||||||
%token ELSE "else"
|
|
||||||
%token DO "do"
|
|
||||||
%token WHILE "while"
|
|
||||||
%token FOR "for"
|
|
||||||
%token FOREACH "foreach"
|
|
||||||
%token IN "in"
|
|
||||||
%token SWITCH "switch"
|
|
||||||
%token CASE "case"
|
|
||||||
%token DEFAULT "default"
|
|
||||||
%token BREAK "break"
|
|
||||||
%token CONTINUE "continue"
|
|
||||||
%token RETURN "return"
|
|
||||||
%token BREAKPOINT "breakpoint"
|
|
||||||
%token PROFBEGIN "prof_begin"
|
|
||||||
%token PROFEND "prof_end"
|
|
||||||
%token THREAD "thread"
|
|
||||||
%token CHILDTHREAD "childthread"
|
|
||||||
%token THISTHREAD "thisthread"
|
|
||||||
%token CALL "call"
|
|
||||||
%token TRUE "true"
|
|
||||||
%token FALSE "false"
|
|
||||||
%token UNDEFINED "undefined"
|
|
||||||
%token SIZE "size"
|
|
||||||
%token GAME "game"
|
|
||||||
%token SELF "self"
|
|
||||||
%token ANIM "anim"
|
|
||||||
%token LEVEL "level"
|
|
||||||
%token LPAREN "("
|
|
||||||
%token RPAREN ")"
|
|
||||||
%token LBRACE "{"
|
|
||||||
%token RBRACE "}"
|
|
||||||
%token LBRACKET "["
|
|
||||||
%token RBRACKET "]"
|
|
||||||
%token COMMA ","
|
|
||||||
%token DOT "."
|
|
||||||
%token DOUBLECOLON "::"
|
|
||||||
%token COLON ":"
|
|
||||||
%token SEMICOLON ";"
|
|
||||||
%token QMARK "?"
|
|
||||||
%token INCREMENT "++"
|
|
||||||
%token DECREMENT "--"
|
|
||||||
%token LSHIFT "<<"
|
|
||||||
%token RSHIFT ">>"
|
|
||||||
%token OR "||"
|
|
||||||
%token AND "&&"
|
|
||||||
%token EQUALITY "=="
|
|
||||||
%token INEQUALITY "!="
|
|
||||||
%token LESS_EQUAL "<="
|
|
||||||
%token GREATER_EQUAL ">="
|
|
||||||
%token LESS "<"
|
|
||||||
%token GREATER ">"
|
|
||||||
%token NOT "!"
|
|
||||||
%token COMPLEMENT "~"
|
|
||||||
%token ASSIGN "="
|
|
||||||
%token ASSIGN_ADD "+="
|
|
||||||
%token ASSIGN_SUB "-="
|
|
||||||
%token ASSIGN_MUL "*="
|
|
||||||
%token ASSIGN_DIV "/="
|
|
||||||
%token ASSIGN_MOD "%="
|
|
||||||
%token ASSIGN_BW_OR "|="
|
|
||||||
%token ASSIGN_BW_AND "&="
|
|
||||||
%token ASSIGN_BW_EXOR "^="
|
|
||||||
%token ASSIGN_RSHIFT ">>="
|
|
||||||
%token ASSIGN_LSHIFT "<<="
|
|
||||||
%token BITWISE_OR "|"
|
|
||||||
%token BITWISE_AND "&"
|
|
||||||
%token BITWISE_EXOR "^"
|
|
||||||
%token ADD "+"
|
|
||||||
%token SUB "-"
|
|
||||||
%token MUL "*"
|
|
||||||
%token DIV "/"
|
|
||||||
%token MOD "%"
|
|
||||||
%token <std::string> PATH "path"
|
|
||||||
%token <std::string> IDENTIFIER "identifier"
|
|
||||||
%token <std::string> STRING "string literal"
|
|
||||||
%token <std::string> ISTRING "localized string"
|
|
||||||
%token <std::string> FLOAT "float"
|
|
||||||
%token <std::string> INTEGER "integer"
|
|
||||||
|
|
||||||
%type <ast::program::ptr> program
|
|
||||||
%type <ast::include::ptr> include
|
|
||||||
%type <ast::decl> declaration
|
|
||||||
%type <ast::decl_usingtree::ptr> decl_usingtree
|
|
||||||
%type <ast::decl_constant::ptr> decl_constant
|
|
||||||
%type <ast::decl_thread::ptr> decl_thread
|
|
||||||
%type <ast::stmt> stmt
|
|
||||||
%type <ast::stmt> stmt_or_dev
|
|
||||||
%type <ast::stmt_list::ptr> stmt_list
|
|
||||||
%type <ast::stmt_list::ptr> stmt_or_dev_list
|
|
||||||
%type <ast::stmt_dev::ptr> stmt_dev
|
|
||||||
%type <ast::stmt_list::ptr> stmt_block
|
|
||||||
%type <ast::stmt_expr::ptr> stmt_expr
|
|
||||||
%type <ast::stmt_call::ptr> stmt_call
|
|
||||||
%type <ast::stmt_assign::ptr> stmt_assign
|
|
||||||
%type <ast::stmt_endon::ptr> stmt_endon
|
|
||||||
%type <ast::stmt_notify::ptr> stmt_notify
|
|
||||||
%type <ast::stmt_wait::ptr> stmt_wait
|
|
||||||
%type <ast::stmt_waittill::ptr> stmt_waittill
|
|
||||||
%type <ast::stmt_waittillmatch::ptr> stmt_waittillmatch
|
|
||||||
%type <ast::stmt_waittillframeend::ptr> stmt_waittillframeend
|
|
||||||
%type <ast::stmt_if::ptr> stmt_if
|
|
||||||
%type <ast::stmt_ifelse::ptr> stmt_ifelse
|
|
||||||
%type <ast::stmt_while::ptr> stmt_while
|
|
||||||
%type <ast::stmt_dowhile::ptr> stmt_dowhile
|
|
||||||
%type <ast::stmt_for::ptr> stmt_for
|
|
||||||
%type <ast::stmt_foreach::ptr> stmt_foreach
|
|
||||||
%type <ast::stmt_switch::ptr> stmt_switch
|
|
||||||
%type <ast::stmt_case::ptr> stmt_case
|
|
||||||
%type <ast::stmt_default::ptr> stmt_default
|
|
||||||
%type <ast::stmt_break::ptr> stmt_break
|
|
||||||
%type <ast::stmt_continue::ptr> stmt_continue
|
|
||||||
%type <ast::stmt_return::ptr> stmt_return
|
|
||||||
%type <ast::stmt_breakpoint::ptr> stmt_breakpoint
|
|
||||||
%type <ast::stmt_prof_begin::ptr> stmt_prof_begin
|
|
||||||
%type <ast::stmt_prof_end::ptr> stmt_prof_end
|
|
||||||
%type <ast::expr> expr
|
|
||||||
%type <ast::expr> expr_or_empty
|
|
||||||
%type <ast::expr> expr_assign
|
|
||||||
%type <ast::expr> expr_increment
|
|
||||||
%type <ast::expr> expr_decrement
|
|
||||||
%type <ast::expr> expr_ternary
|
|
||||||
%type <ast::expr> expr_binary
|
|
||||||
%type <ast::expr> expr_primitive
|
|
||||||
%type <ast::expr_complement::ptr> expr_complement
|
|
||||||
%type <ast::expr_negate::ptr> expr_negate
|
|
||||||
%type <ast::expr_not::ptr> expr_not
|
|
||||||
%type <ast::expr_call::ptr> expr_call
|
|
||||||
%type <ast::expr_method::ptr> expr_method
|
|
||||||
%type <ast::call> expr_function
|
|
||||||
%type <ast::call> expr_pointer
|
|
||||||
%type <ast::expr_add_array::ptr> expr_add_array
|
|
||||||
%type <ast::expr_parameters::ptr> expr_parameters
|
|
||||||
%type <ast::expr_arguments::ptr> expr_arguments
|
|
||||||
%type <ast::expr_arguments::ptr> expr_arguments_no_empty
|
|
||||||
%type <ast::expr_reference::ptr> expr_reference
|
|
||||||
%type <ast::expr_array::ptr> expr_array
|
|
||||||
%type <ast::expr_field::ptr> expr_field
|
|
||||||
%type <ast::expr_size::ptr> expr_size
|
|
||||||
%type <ast::expr_paren::ptr> expr_paren
|
|
||||||
%type <ast::expr> expr_object
|
|
||||||
%type <ast::expr_thisthread::ptr> expr_thisthread
|
|
||||||
%type <ast::expr_empty_array::ptr> expr_empty_array
|
|
||||||
%type <ast::expr_undefined::ptr> expr_undefined
|
|
||||||
%type <ast::expr_game::ptr> expr_game
|
|
||||||
%type <ast::expr_self::ptr> expr_self
|
|
||||||
%type <ast::expr_anim::ptr> expr_anim
|
|
||||||
%type <ast::expr_level::ptr> expr_level
|
|
||||||
%type <ast::expr_animation::ptr> expr_animation
|
|
||||||
%type <ast::expr_animtree::ptr> expr_animtree
|
|
||||||
%type <ast::expr_identifier::ptr> expr_identifier_nosize
|
|
||||||
%type <ast::expr_identifier::ptr> expr_identifier
|
|
||||||
%type <ast::expr_path::ptr> expr_path
|
|
||||||
%type <ast::expr_istring::ptr> expr_istring
|
|
||||||
%type <ast::expr_string::ptr> expr_string
|
|
||||||
%type <ast::expr_vector::ptr> expr_vector
|
|
||||||
%type <ast::expr_float::ptr> expr_float
|
|
||||||
%type <ast::expr_integer::ptr> expr_integer
|
|
||||||
%type <ast::expr_false::ptr> expr_false
|
|
||||||
%type <ast::expr_true::ptr> expr_true
|
|
||||||
|
|
||||||
%nonassoc SIZEOF
|
|
||||||
%nonassoc ADD_ARRAY
|
|
||||||
%nonassoc RBRACKET
|
|
||||||
%nonassoc THEN
|
|
||||||
%nonassoc ELSE
|
|
||||||
%nonassoc INCREMENT DECREMENT
|
|
||||||
|
|
||||||
%precedence TERN
|
|
||||||
%right QMARK
|
|
||||||
%left OR
|
|
||||||
%left AND
|
|
||||||
%left BITWISE_OR
|
|
||||||
%left BITWISE_EXOR
|
|
||||||
%left BITWISE_AND
|
|
||||||
%left EQUALITY INEQUALITY
|
|
||||||
%left LESS GREATER LESS_EQUAL GREATER_EQUAL
|
|
||||||
%left LSHIFT RSHIFT
|
|
||||||
%left ADD SUB
|
|
||||||
%left MUL DIV MOD
|
|
||||||
%right NOT COMPLEMENT
|
|
||||||
|
|
||||||
%precedence NEG
|
|
||||||
%precedence ANIMREF
|
|
||||||
%precedence PREINC PREDEC
|
|
||||||
%precedence POSTINC POSTDEC
|
|
||||||
|
|
||||||
%start root
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
root
|
|
||||||
: program { ast = std::move($1); }
|
|
||||||
| { ast = std::make_unique<ast::program>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
program
|
|
||||||
: program inline
|
|
||||||
{ $$ = std::move($1); }
|
|
||||||
| program include
|
|
||||||
{ $$ = std::move($1); $$->includes.push_back(std::move($2)); }
|
|
||||||
| program declaration
|
|
||||||
{ $$ = std::move($1); $$->declarations.push_back(std::move($2)); }
|
|
||||||
| inline
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); }
|
|
||||||
| include
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); $$->includes.push_back(std::move($1)); }
|
|
||||||
| declaration
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); $$->declarations.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
inline
|
|
||||||
: INLINE expr_path SEMICOLON { lexer.push_header($2->value); }
|
|
||||||
;
|
|
||||||
|
|
||||||
include
|
|
||||||
: INCLUDE expr_path SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::include>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
declaration
|
|
||||||
: DEVBEGIN { $$.as_dev_begin = std::make_unique<ast::decl_dev_begin>(@$); }
|
|
||||||
| DEVEND { $$.as_dev_end = std::make_unique<ast::decl_dev_end>(@$); }
|
|
||||||
| decl_usingtree { $$.as_usingtree = std::move($1); }
|
|
||||||
| decl_constant { $$.as_constant = std::move($1); }
|
|
||||||
| decl_thread { $$.as_thread = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_usingtree
|
|
||||||
: USINGTREE LPAREN expr_string RPAREN SEMICOLON
|
|
||||||
{ lexer.ban_header(@$); $$ = std::make_unique<ast::decl_usingtree>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_constant
|
|
||||||
: expr_identifier ASSIGN expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::decl_constant>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_thread
|
|
||||||
: expr_identifier LPAREN expr_parameters RPAREN stmt_block
|
|
||||||
{ lexer.ban_header(@$); $$ = std::make_unique<ast::decl_thread>(@$, std::move($1), std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt
|
|
||||||
: stmt_block { $$.as_list = std::move($1); }
|
|
||||||
| stmt_call { $$.as_call = std::move($1); }
|
|
||||||
| stmt_assign { $$.as_assign = std::move($1); }
|
|
||||||
| stmt_endon { $$.as_endon = std::move($1); }
|
|
||||||
| stmt_notify { $$.as_notify = std::move($1); }
|
|
||||||
| stmt_wait { $$.as_wait = std::move($1); }
|
|
||||||
| stmt_waittill { $$.as_waittill = std::move($1); }
|
|
||||||
| stmt_waittillmatch { $$.as_waittillmatch = std::move($1); }
|
|
||||||
| stmt_waittillframeend { $$.as_waittillframeend = std::move($1); }
|
|
||||||
| stmt_if { $$.as_if = std::move($1); }
|
|
||||||
| stmt_ifelse { $$.as_ifelse = std::move($1); }
|
|
||||||
| stmt_while { $$.as_while = std::move($1); }
|
|
||||||
| stmt_dowhile { $$.as_dowhile = std::move($1); }
|
|
||||||
| stmt_for { $$.as_for = std::move($1); }
|
|
||||||
| stmt_foreach { $$.as_foreach = std::move($1); }
|
|
||||||
| stmt_switch { $$.as_switch = std::move($1); }
|
|
||||||
| stmt_case { $$.as_case = std::move($1); }
|
|
||||||
| stmt_default { $$.as_default = std::move($1); }
|
|
||||||
| stmt_break { $$.as_break = std::move($1); }
|
|
||||||
| stmt_continue { $$.as_continue = std::move($1); }
|
|
||||||
| stmt_return { $$.as_return = std::move($1); }
|
|
||||||
| stmt_breakpoint { $$.as_breakpoint = std::move($1); }
|
|
||||||
| stmt_prof_begin { $$.as_prof_begin = std::move($1); }
|
|
||||||
| stmt_prof_end { $$.as_prof_end = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_or_dev
|
|
||||||
: stmt { $$ = std::move($1); }
|
|
||||||
| stmt_dev { $$.as_dev = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_list
|
|
||||||
: stmt_list stmt
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($2)); }
|
|
||||||
| stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_list>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_or_dev_list
|
|
||||||
: stmt_or_dev_list stmt_or_dev
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($2)); }
|
|
||||||
| stmt_or_dev
|
|
||||||
{ $$ = std::make_unique<ast::stmt_list>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_dev
|
|
||||||
: DEVBEGIN stmt_list DEVEND { $$ = std::make_unique<ast::stmt_dev>(@$, std::move($2)); }
|
|
||||||
| DEVBEGIN DEVEND { $$ = std::make_unique<ast::stmt_dev>(@$, std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_block
|
|
||||||
: LBRACE stmt_or_dev_list RBRACE { $$ = std::move($2); }
|
|
||||||
| LBRACE RBRACE { $$ = std::make_unique<ast::stmt_list>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_expr
|
|
||||||
: expr_assign
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
| expr_increment
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
| expr_decrement
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::make_unique<ast::node>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_call
|
|
||||||
: expr_call SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_call>(@$, ast::expr(std::move($1))); }
|
|
||||||
| expr_method SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_call>(@$, ast::expr(std::move($1))); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_assign
|
|
||||||
: expr_assign SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
| expr_increment SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
| expr_decrement SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_endon
|
|
||||||
: expr_object ENDON LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_endon>(@$, std::move($1), std::move($4)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_notify
|
|
||||||
: expr_object NOTIFY LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_notify>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object NOTIFY LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_notify>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_wait
|
|
||||||
: WAIT expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_wait>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittill
|
|
||||||
: expr_object WAITTILL LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittill>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object WAITTILL LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittill>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittillmatch
|
|
||||||
: expr_object WAITTILLMATCH LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillmatch>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object WAITTILLMATCH LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillmatch>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittillframeend
|
|
||||||
: WAITTILLFRAMEEND SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillframeend>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_if
|
|
||||||
: IF LPAREN expr RPAREN stmt %prec THEN
|
|
||||||
{ $$ = std::make_unique<ast::stmt_if>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_ifelse
|
|
||||||
: IF LPAREN expr RPAREN stmt ELSE stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_ifelse>(@$, std::move($3), std::move($5), std::move($7)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_while
|
|
||||||
: WHILE LPAREN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_while>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_dowhile
|
|
||||||
: DO stmt WHILE LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_dowhile>(@$, std::move($5), std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_for
|
|
||||||
: FOR LPAREN stmt_expr SEMICOLON expr_or_empty SEMICOLON stmt_expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_for>(@$, ast::stmt(std::move($3)), std::move($5), ast::stmt(std::move($7)), std::move($9)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_foreach
|
|
||||||
: FOREACH LPAREN expr_identifier IN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_foreach>(@$, ast::expr(std::move($3)), std::move($5), std::move($7)); }
|
|
||||||
| FOREACH LPAREN expr_identifier COMMA expr_identifier IN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_foreach>(@$, ast::expr(std::move($3)), ast::expr(std::move($5)), std::move($7), std::move($9)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_switch
|
|
||||||
: SWITCH LPAREN expr RPAREN stmt_block
|
|
||||||
{ $$ = std::make_unique<ast::stmt_switch>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_case
|
|
||||||
: CASE expr_integer COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_case>(@$, ast::expr(std::move($2)), std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
| CASE expr_string COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_case>(@$, ast::expr(std::move($2)), std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_default
|
|
||||||
: DEFAULT COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_default>(@$, std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_break
|
|
||||||
: BREAK SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_break>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_continue
|
|
||||||
: CONTINUE SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_continue>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_return
|
|
||||||
: RETURN expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_return>(@$, std::move($2)); }
|
|
||||||
| RETURN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_return>(@$, std::make_unique<ast::node>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_breakpoint
|
|
||||||
: BREAKPOINT SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_breakpoint>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_prof_begin
|
|
||||||
: PROFBEGIN LPAREN expr_arguments RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_prof_begin>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_prof_end
|
|
||||||
: PROFEND LPAREN expr_arguments RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_prof_end>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr
|
|
||||||
: expr_ternary { $$ = std::move($1); }
|
|
||||||
| expr_binary { $$ = std::move($1); }
|
|
||||||
| expr_primitive { $$ = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_or_empty
|
|
||||||
: expr { $$ = std::move($1); }
|
|
||||||
| { $$.as_node = std::make_unique<ast::node>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_assign
|
|
||||||
: expr_object ASSIGN expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_EXOR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_exor>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_LSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_shift_left>(@$, std::move($1),std::move( $3)); }
|
|
||||||
| expr_object ASSIGN_RSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_shift_right>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_ADD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_add>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_SUB expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_sub>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_MUL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_mul>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_DIV expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_div>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_MOD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_mod>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_increment
|
|
||||||
: INCREMENT expr_object %prec PREINC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_increment>(@$, std::move($2), true); }
|
|
||||||
| expr_object INCREMENT %prec POSTINC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_increment>(@$, std::move($1), false); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_decrement
|
|
||||||
: DECREMENT expr_object %prec PREDEC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_decrement>(@$, std::move($2), true); }
|
|
||||||
| expr_object DECREMENT %prec POSTDEC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_decrement>(@$, std::move($1), false); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_ternary
|
|
||||||
: expr QMARK expr COLON expr %prec TERN
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_ternary>(@$, std::move($1), std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_binary
|
|
||||||
: expr OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr EQUALITY expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_equality>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr INEQUALITY expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_inequality>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LESS_EQUAL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_less_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr GREATER_EQUAL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_greater_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LESS expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_less>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr GREATER expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_greater>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_EXOR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_exor>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_shift_left>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr RSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_shift_right>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr ADD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_add>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr SUB expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_sub>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr MUL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_mul>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr DIV expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_div>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr MOD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_mod>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_primitive
|
|
||||||
: expr_complement { $$.as_node = std::move($1); }
|
|
||||||
| expr_negate { $$.as_node = std::move($1); }
|
|
||||||
| expr_not { $$.as_node = std::move($1); }
|
|
||||||
| expr_call { $$.as_node = std::move($1); }
|
|
||||||
| expr_method { $$.as_node = std::move($1); }
|
|
||||||
| expr_add_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_reference { $$.as_node = std::move($1); }
|
|
||||||
| expr_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_field { $$.as_node = std::move($1); }
|
|
||||||
| expr_size { $$.as_node = std::move($1); }
|
|
||||||
| expr_paren { $$.as_node = std::move($1); }
|
|
||||||
| expr_thisthread { $$.as_node = std::move($1); }
|
|
||||||
| expr_empty_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_undefined { $$.as_node = std::move($1); }
|
|
||||||
| expr_game { $$.as_node = std::move($1); }
|
|
||||||
| expr_self { $$.as_node = std::move($1); }
|
|
||||||
| expr_anim { $$.as_node = std::move($1); }
|
|
||||||
| expr_level { $$.as_node = std::move($1); }
|
|
||||||
| expr_animation { $$.as_node = std::move($1); }
|
|
||||||
| expr_animtree { $$.as_node = std::move($1); }
|
|
||||||
| expr_identifier { $$.as_node = std::move($1); }
|
|
||||||
| expr_istring { $$.as_node = std::move($1); }
|
|
||||||
| expr_string { $$.as_node = std::move($1); }
|
|
||||||
| expr_vector { $$.as_node = std::move($1); }
|
|
||||||
| expr_float { $$.as_node = std::move($1); }
|
|
||||||
| expr_integer { $$.as_node = std::move($1); }
|
|
||||||
| expr_false { $$.as_node = std::move($1); }
|
|
||||||
| expr_true { $$.as_node = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_complement
|
|
||||||
: COMPLEMENT expr
|
|
||||||
{ $$ = std::make_unique<ast::expr_complement>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_negate
|
|
||||||
: SUB expr_identifier %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_paren %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_array %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_field %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_not
|
|
||||||
: NOT expr
|
|
||||||
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_call
|
|
||||||
: expr_function { $$ = std::make_unique<ast::expr_call>(@$, std::move($1)); }
|
|
||||||
| expr_pointer { $$ = std::make_unique<ast::expr_call>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
expr_method
|
|
||||||
: expr_object expr_function { $$ = std::make_unique<ast::expr_method>(@$, std::move($1), std::move($2)); }
|
|
||||||
| expr_object expr_pointer { $$ = std::make_unique<ast::expr_method>(@$, std::move($1), std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_function
|
|
||||||
: expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($1), std::move($3), ast::call::mode::normal); }
|
|
||||||
| expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($1), std::move($3), std::move($5), ast::call::mode::normal); }
|
|
||||||
| THREAD expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($2), std::move($4), ast::call::mode::thread); }
|
|
||||||
| THREAD expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($2), std::move($4), std::move($6), ast::call::mode::thread); }
|
|
||||||
| CHILDTHREAD expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($2), std::move($4), ast::call::mode::childthread); }
|
|
||||||
| CHILDTHREAD expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($2), std::move($4), std::move($6), ast::call::mode::childthread); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_pointer
|
|
||||||
: LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($3), std::move($7), ast::call::mode::normal); }
|
|
||||||
| THREAD LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::thread); }
|
|
||||||
| CHILDTHREAD LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::childthread); }
|
|
||||||
| CALL LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::builtin); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_add_array
|
|
||||||
: LBRACKET expr_arguments_no_empty RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_add_array>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_parameters
|
|
||||||
: expr_parameters COMMA expr_identifier
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($3)); }
|
|
||||||
| expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_parameters>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::expr_parameters>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_arguments
|
|
||||||
: expr_arguments_no_empty
|
|
||||||
{ $$ = std::move($1); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::expr_arguments>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_arguments_no_empty
|
|
||||||
: expr_arguments COMMA expr
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($3)); }
|
|
||||||
| expr %prec ADD_ARRAY
|
|
||||||
{ $$ = std::make_unique<ast::expr_arguments>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_reference
|
|
||||||
: DOUBLECOLON expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_reference>(@$, std::make_unique<ast::expr_path>(@$), std::move($2)); }
|
|
||||||
| expr_path DOUBLECOLON expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_reference>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_array
|
|
||||||
: expr_object LBRACKET expr RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_array>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_field
|
|
||||||
: expr_object DOT expr_identifier_nosize
|
|
||||||
{ $$ = std::make_unique<ast::expr_field>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_size
|
|
||||||
: expr_object DOT SIZE %prec SIZEOF
|
|
||||||
{ $$ = std::make_unique<ast::expr_size>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_paren
|
|
||||||
: LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_paren>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_object
|
|
||||||
: expr_call { $$.as_node = std::move($1); }
|
|
||||||
| expr_method { $$.as_node = std::move($1); }
|
|
||||||
| expr_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_field { $$.as_node = std::move($1); }
|
|
||||||
| expr_game { $$.as_node = std::move($1); }
|
|
||||||
| expr_self { $$.as_node = std::move($1); }
|
|
||||||
| expr_anim { $$.as_node = std::move($1); }
|
|
||||||
| expr_level { $$.as_node = std::move($1); }
|
|
||||||
| expr_identifier { $$.as_node = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_thisthread
|
|
||||||
: THISTHREAD
|
|
||||||
{ $$ = std::make_unique<ast::expr_thisthread>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_empty_array
|
|
||||||
: LBRACKET RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_empty_array>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_undefined
|
|
||||||
: UNDEFINED
|
|
||||||
{ $$ = std::make_unique<ast::expr_undefined>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_game
|
|
||||||
: GAME
|
|
||||||
{ $$ = std::make_unique<ast::expr_game>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_self
|
|
||||||
: SELF
|
|
||||||
{ $$ = std::make_unique<ast::expr_self>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_anim
|
|
||||||
: ANIM
|
|
||||||
{ $$ = std::make_unique<ast::expr_anim>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_level
|
|
||||||
: LEVEL
|
|
||||||
{ $$ = std::make_unique<ast::expr_level>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_animation
|
|
||||||
: MOD IDENTIFIER %prec ANIMREF
|
|
||||||
{ $$ = std::make_unique<ast::expr_animation>(@$, $2); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_animtree
|
|
||||||
: ANIMTREE
|
|
||||||
{ $$ = std::make_unique<ast::expr_animtree>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_identifier_nosize
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_identifier
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, $1); };
|
|
||||||
| SIZE
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, "size"); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_path
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_path>(@$, $1); };
|
|
||||||
| PATH
|
|
||||||
{ $$ = std::make_unique<ast::expr_path>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_istring
|
|
||||||
: ISTRING
|
|
||||||
{ $$ = std::make_unique<ast::expr_istring>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_string
|
|
||||||
: STRING
|
|
||||||
{ $$ = std::make_unique<ast::expr_string>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_vector
|
|
||||||
: LPAREN expr COMMA expr COMMA expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_vector>(@$, std::move($2), std::move($4), std::move($6)); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_float
|
|
||||||
: SUB FLOAT %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_float>(@$, "-" + $2); };
|
|
||||||
| FLOAT
|
|
||||||
{ $$ = std::make_unique<ast::expr_float>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_integer
|
|
||||||
: SUB INTEGER %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_integer>(@$, "-" + $2); };
|
|
||||||
| INTEGER
|
|
||||||
{ $$ = std::make_unique<ast::expr_integer>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_false
|
|
||||||
: FALSE
|
|
||||||
{ $$ = std::make_unique<ast::expr_false>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_true
|
|
||||||
: TRUE
|
|
||||||
{ $$ = std::make_unique<ast::expr_true>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
void xsk::gsc::iw7::parser::error(const xsk::gsc::location& loc, const std::string& msg)
|
|
||||||
{
|
|
||||||
throw xsk::gsc::comp_error(loc, msg);
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
generate: IW8
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf ./parser.hpp
|
|
||||||
rm -rf ./parser.cpp
|
|
||||||
|
|
||||||
IW8: parser.ypp
|
|
||||||
bison parser.ypp -Wcounterexamples
|
|
||||||
mv parser.hpp parser.cpp ../../src/iw8/xsk/
|
|
@ -1,891 +0,0 @@
|
|||||||
/* Copyright 2022 xensik. All rights reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a GNU GPLv3 license
|
|
||||||
// that can be found in the LICENSE file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
%require "3.7"
|
|
||||||
%skeleton "lalr1.cc"
|
|
||||||
%language "c++"
|
|
||||||
%output "parser.cpp"
|
|
||||||
%defines "parser.hpp"
|
|
||||||
%define api.prefix {IW8}
|
|
||||||
%define api.namespace {xsk::gsc::iw8}
|
|
||||||
%define api.location.type {xsk::gsc::location}
|
|
||||||
%define api.value.type variant
|
|
||||||
%define api.token.constructor
|
|
||||||
%define api.token.raw
|
|
||||||
%define parse.assert
|
|
||||||
%define parse.trace
|
|
||||||
%define parse.error detailed
|
|
||||||
%define parse.lac full
|
|
||||||
%locations
|
|
||||||
%lex-param { xsk::gsc::iw8::lexer& lexer }
|
|
||||||
%parse-param { xsk::gsc::iw8::lexer& lexer }
|
|
||||||
%parse-param { xsk::gsc::ast::program::ptr& ast }
|
|
||||||
|
|
||||||
%code requires
|
|
||||||
{
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(disable:4065)
|
|
||||||
#pragma warning(disable:4127)
|
|
||||||
#endif
|
|
||||||
#include "iw8.hpp"
|
|
||||||
namespace xsk::gsc::iw8 { class lexer; }
|
|
||||||
}
|
|
||||||
|
|
||||||
%code top
|
|
||||||
{
|
|
||||||
#include "stdafx.hpp"
|
|
||||||
#include "parser.hpp"
|
|
||||||
#include "lexer.hpp"
|
|
||||||
using namespace xsk::gsc;
|
|
||||||
xsk::gsc::iw8::parser::symbol_type IW8lex(xsk::gsc::iw8::lexer& lexer);
|
|
||||||
}
|
|
||||||
|
|
||||||
%token SH_DEFINE "#define"
|
|
||||||
%token SH_UNDEF "#undef"
|
|
||||||
%token SH_IFDEF "#ifdef"
|
|
||||||
%token SH_IFNDEF "#ifndef"
|
|
||||||
%token SH_IF "#if"
|
|
||||||
%token SH_ELIF "#elif"
|
|
||||||
%token SH_ELSE "#else"
|
|
||||||
%token SH_ENDIF "#endif"
|
|
||||||
%token DEVBEGIN "/#"
|
|
||||||
%token DEVEND "#/"
|
|
||||||
%token INLINE "#inline"
|
|
||||||
%token INCLUDE "#include"
|
|
||||||
%token USINGTREE "#using_animtree"
|
|
||||||
%token ANIMTREE "#animtree"
|
|
||||||
%token ENDON "endon"
|
|
||||||
%token NOTIFY "notify"
|
|
||||||
%token WAIT "wait"
|
|
||||||
%token WAITTILL "waittill"
|
|
||||||
%token WAITTILLMATCH "waittillmatch"
|
|
||||||
%token WAITTILLFRAMEEND "waittillframeend"
|
|
||||||
%token WAITFRAME "waitframe"
|
|
||||||
%token IF "if"
|
|
||||||
%token ELSE "else"
|
|
||||||
%token DO "do"
|
|
||||||
%token WHILE "while"
|
|
||||||
%token FOR "for"
|
|
||||||
%token FOREACH "foreach"
|
|
||||||
%token IN "in"
|
|
||||||
%token SWITCH "switch"
|
|
||||||
%token CASE "case"
|
|
||||||
%token DEFAULT "default"
|
|
||||||
%token BREAK "break"
|
|
||||||
%token CONTINUE "continue"
|
|
||||||
%token RETURN "return"
|
|
||||||
%token BREAKPOINT "breakpoint"
|
|
||||||
%token PROFBEGIN "prof_begin"
|
|
||||||
%token PROFEND "prof_end"
|
|
||||||
%token THREAD "thread"
|
|
||||||
%token CHILDTHREAD "childthread"
|
|
||||||
%token THISTHREAD "thisthread"
|
|
||||||
%token CALL "call"
|
|
||||||
%token TRUE "true"
|
|
||||||
%token FALSE "false"
|
|
||||||
%token UNDEFINED "undefined"
|
|
||||||
%token SIZE "size"
|
|
||||||
%token GAME "game"
|
|
||||||
%token SELF "self"
|
|
||||||
%token ANIM "anim"
|
|
||||||
%token LEVEL "level"
|
|
||||||
%token ISDEFINED "isdefined"
|
|
||||||
%token ISTRUE "istrue"
|
|
||||||
%token LPAREN "("
|
|
||||||
%token RPAREN ")"
|
|
||||||
%token LBRACE "{"
|
|
||||||
%token RBRACE "}"
|
|
||||||
%token LBRACKET "["
|
|
||||||
%token RBRACKET "]"
|
|
||||||
%token COMMA ","
|
|
||||||
%token DOT "."
|
|
||||||
%token DOUBLECOLON "::"
|
|
||||||
%token COLON ":"
|
|
||||||
%token SEMICOLON ";"
|
|
||||||
%token QMARK "?"
|
|
||||||
%token INCREMENT "++"
|
|
||||||
%token DECREMENT "--"
|
|
||||||
%token LSHIFT "<<"
|
|
||||||
%token RSHIFT ">>"
|
|
||||||
%token OR "||"
|
|
||||||
%token AND "&&"
|
|
||||||
%token EQUALITY "=="
|
|
||||||
%token INEQUALITY "!="
|
|
||||||
%token LESS_EQUAL "<="
|
|
||||||
%token GREATER_EQUAL ">="
|
|
||||||
%token LESS "<"
|
|
||||||
%token GREATER ">"
|
|
||||||
%token NOT "!"
|
|
||||||
%token COMPLEMENT "~"
|
|
||||||
%token ASSIGN "="
|
|
||||||
%token ASSIGN_ADD "+="
|
|
||||||
%token ASSIGN_SUB "-="
|
|
||||||
%token ASSIGN_MUL "*="
|
|
||||||
%token ASSIGN_DIV "/="
|
|
||||||
%token ASSIGN_MOD "%="
|
|
||||||
%token ASSIGN_BW_OR "|="
|
|
||||||
%token ASSIGN_BW_AND "&="
|
|
||||||
%token ASSIGN_BW_EXOR "^="
|
|
||||||
%token ASSIGN_RSHIFT ">>="
|
|
||||||
%token ASSIGN_LSHIFT "<<="
|
|
||||||
%token BITWISE_OR "|"
|
|
||||||
%token BITWISE_AND "&"
|
|
||||||
%token BITWISE_EXOR "^"
|
|
||||||
%token ADD "+"
|
|
||||||
%token SUB "-"
|
|
||||||
%token MUL "*"
|
|
||||||
%token DIV "/"
|
|
||||||
%token MOD "%"
|
|
||||||
%token <std::string> PATH "path"
|
|
||||||
%token <std::string> IDENTIFIER "identifier"
|
|
||||||
%token <std::string> STRING "string literal"
|
|
||||||
%token <std::string> ISTRING "localized string"
|
|
||||||
%token <std::string> FLOAT "float"
|
|
||||||
%token <std::string> INTEGER "integer"
|
|
||||||
|
|
||||||
%type <ast::program::ptr> program
|
|
||||||
%type <ast::include::ptr> include
|
|
||||||
%type <ast::decl> declaration
|
|
||||||
%type <ast::decl_usingtree::ptr> decl_usingtree
|
|
||||||
%type <ast::decl_constant::ptr> decl_constant
|
|
||||||
%type <ast::decl_thread::ptr> decl_thread
|
|
||||||
%type <ast::stmt> stmt
|
|
||||||
%type <ast::stmt> stmt_or_dev
|
|
||||||
%type <ast::stmt_list::ptr> stmt_list
|
|
||||||
%type <ast::stmt_list::ptr> stmt_or_dev_list
|
|
||||||
%type <ast::stmt_dev::ptr> stmt_dev
|
|
||||||
%type <ast::stmt_list::ptr> stmt_block
|
|
||||||
%type <ast::stmt_expr::ptr> stmt_expr
|
|
||||||
%type <ast::stmt_call::ptr> stmt_call
|
|
||||||
%type <ast::stmt_assign::ptr> stmt_assign
|
|
||||||
%type <ast::stmt_endon::ptr> stmt_endon
|
|
||||||
%type <ast::stmt_notify::ptr> stmt_notify
|
|
||||||
%type <ast::stmt_wait::ptr> stmt_wait
|
|
||||||
%type <ast::stmt_waittill::ptr> stmt_waittill
|
|
||||||
%type <ast::stmt_waittillmatch::ptr> stmt_waittillmatch
|
|
||||||
%type <ast::stmt_waittillframeend::ptr> stmt_waittillframeend
|
|
||||||
%type <ast::stmt_waitframe::ptr> stmt_waitframe
|
|
||||||
%type <ast::stmt_if::ptr> stmt_if
|
|
||||||
%type <ast::stmt_ifelse::ptr> stmt_ifelse
|
|
||||||
%type <ast::stmt_while::ptr> stmt_while
|
|
||||||
%type <ast::stmt_dowhile::ptr> stmt_dowhile
|
|
||||||
%type <ast::stmt_for::ptr> stmt_for
|
|
||||||
%type <ast::stmt_foreach::ptr> stmt_foreach
|
|
||||||
%type <ast::stmt_switch::ptr> stmt_switch
|
|
||||||
%type <ast::stmt_case::ptr> stmt_case
|
|
||||||
%type <ast::stmt_default::ptr> stmt_default
|
|
||||||
%type <ast::stmt_break::ptr> stmt_break
|
|
||||||
%type <ast::stmt_continue::ptr> stmt_continue
|
|
||||||
%type <ast::stmt_return::ptr> stmt_return
|
|
||||||
%type <ast::stmt_breakpoint::ptr> stmt_breakpoint
|
|
||||||
%type <ast::stmt_prof_begin::ptr> stmt_prof_begin
|
|
||||||
%type <ast::stmt_prof_end::ptr> stmt_prof_end
|
|
||||||
%type <ast::expr> expr
|
|
||||||
%type <ast::expr> expr_or_empty
|
|
||||||
%type <ast::expr> expr_assign
|
|
||||||
%type <ast::expr> expr_increment
|
|
||||||
%type <ast::expr> expr_decrement
|
|
||||||
%type <ast::expr> expr_ternary
|
|
||||||
%type <ast::expr> expr_binary
|
|
||||||
%type <ast::expr> expr_primitive
|
|
||||||
%type <ast::expr_complement::ptr> expr_complement
|
|
||||||
%type <ast::expr_negate::ptr> expr_negate
|
|
||||||
%type <ast::expr_not::ptr> expr_not
|
|
||||||
%type <ast::expr_call::ptr> expr_call
|
|
||||||
%type <ast::expr_method::ptr> expr_method
|
|
||||||
%type <ast::call> expr_function
|
|
||||||
%type <ast::call> expr_pointer
|
|
||||||
%type <ast::expr_add_array::ptr> expr_add_array
|
|
||||||
%type <ast::expr_parameters::ptr> expr_parameters
|
|
||||||
%type <ast::expr_arguments::ptr> expr_arguments
|
|
||||||
%type <ast::expr_arguments::ptr> expr_arguments_no_empty
|
|
||||||
%type <ast::expr_isdefined::ptr> expr_isdefined
|
|
||||||
%type <ast::expr_istrue::ptr> expr_istrue
|
|
||||||
%type <ast::expr_reference::ptr> expr_reference
|
|
||||||
%type <ast::expr_array::ptr> expr_array
|
|
||||||
%type <ast::expr_field::ptr> expr_field
|
|
||||||
%type <ast::expr_size::ptr> expr_size
|
|
||||||
%type <ast::expr_paren::ptr> expr_paren
|
|
||||||
%type <ast::expr> expr_object
|
|
||||||
%type <ast::expr_thisthread::ptr> expr_thisthread
|
|
||||||
%type <ast::expr_empty_array::ptr> expr_empty_array
|
|
||||||
%type <ast::expr_undefined::ptr> expr_undefined
|
|
||||||
%type <ast::expr_game::ptr> expr_game
|
|
||||||
%type <ast::expr_self::ptr> expr_self
|
|
||||||
%type <ast::expr_anim::ptr> expr_anim
|
|
||||||
%type <ast::expr_level::ptr> expr_level
|
|
||||||
%type <ast::expr_animation::ptr> expr_animation
|
|
||||||
%type <ast::expr_animtree::ptr> expr_animtree
|
|
||||||
%type <ast::expr_identifier::ptr> expr_identifier_nosize
|
|
||||||
%type <ast::expr_identifier::ptr> expr_identifier
|
|
||||||
%type <ast::expr_path::ptr> expr_path
|
|
||||||
%type <ast::expr_istring::ptr> expr_istring
|
|
||||||
%type <ast::expr_string::ptr> expr_string
|
|
||||||
%type <ast::expr_vector::ptr> expr_vector
|
|
||||||
%type <ast::expr_float::ptr> expr_float
|
|
||||||
%type <ast::expr_integer::ptr> expr_integer
|
|
||||||
%type <ast::expr_false::ptr> expr_false
|
|
||||||
%type <ast::expr_true::ptr> expr_true
|
|
||||||
|
|
||||||
%nonassoc SIZEOF
|
|
||||||
%nonassoc ADD_ARRAY
|
|
||||||
%nonassoc RBRACKET
|
|
||||||
%nonassoc THEN
|
|
||||||
%nonassoc ELSE
|
|
||||||
%nonassoc INCREMENT DECREMENT
|
|
||||||
|
|
||||||
%precedence TERN
|
|
||||||
%right QMARK
|
|
||||||
%left OR
|
|
||||||
%left AND
|
|
||||||
%left BITWISE_OR
|
|
||||||
%left BITWISE_EXOR
|
|
||||||
%left BITWISE_AND
|
|
||||||
%left EQUALITY INEQUALITY
|
|
||||||
%left LESS GREATER LESS_EQUAL GREATER_EQUAL
|
|
||||||
%left LSHIFT RSHIFT
|
|
||||||
%left ADD SUB
|
|
||||||
%left MUL DIV MOD
|
|
||||||
%right NOT COMPLEMENT
|
|
||||||
|
|
||||||
%precedence NEG
|
|
||||||
%precedence ANIMREF
|
|
||||||
%precedence PREINC PREDEC
|
|
||||||
%precedence POSTINC POSTDEC
|
|
||||||
|
|
||||||
%start root
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
root
|
|
||||||
: program { ast = std::move($1); }
|
|
||||||
| { ast = std::make_unique<ast::program>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
program
|
|
||||||
: program inline
|
|
||||||
{ $$ = std::move($1); }
|
|
||||||
| program include
|
|
||||||
{ $$ = std::move($1); $$->includes.push_back(std::move($2)); }
|
|
||||||
| program declaration
|
|
||||||
{ $$ = std::move($1); $$->declarations.push_back(std::move($2)); }
|
|
||||||
| inline
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); }
|
|
||||||
| include
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); $$->includes.push_back(std::move($1)); }
|
|
||||||
| declaration
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); $$->declarations.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
inline
|
|
||||||
: INLINE expr_path SEMICOLON { lexer.push_header($2->value); }
|
|
||||||
;
|
|
||||||
|
|
||||||
include
|
|
||||||
: INCLUDE expr_path SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::include>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
declaration
|
|
||||||
: DEVBEGIN { $$.as_dev_begin = std::make_unique<ast::decl_dev_begin>(@$); }
|
|
||||||
| DEVEND { $$.as_dev_end = std::make_unique<ast::decl_dev_end>(@$); }
|
|
||||||
| decl_usingtree { $$.as_usingtree = std::move($1); }
|
|
||||||
| decl_constant { $$.as_constant = std::move($1); }
|
|
||||||
| decl_thread { $$.as_thread = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_usingtree
|
|
||||||
: USINGTREE LPAREN expr_string RPAREN SEMICOLON
|
|
||||||
{ lexer.ban_header(@$); $$ = std::make_unique<ast::decl_usingtree>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_constant
|
|
||||||
: expr_identifier ASSIGN expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::decl_constant>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_thread
|
|
||||||
: expr_identifier LPAREN expr_parameters RPAREN stmt_block
|
|
||||||
{ lexer.ban_header(@$); $$ = std::make_unique<ast::decl_thread>(@$, std::move($1), std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt
|
|
||||||
: stmt_block { $$.as_list = std::move($1); }
|
|
||||||
| stmt_call { $$.as_call = std::move($1); }
|
|
||||||
| stmt_assign { $$.as_assign = std::move($1); }
|
|
||||||
| stmt_endon { $$.as_endon = std::move($1); }
|
|
||||||
| stmt_notify { $$.as_notify = std::move($1); }
|
|
||||||
| stmt_wait { $$.as_wait = std::move($1); }
|
|
||||||
| stmt_waittill { $$.as_waittill = std::move($1); }
|
|
||||||
| stmt_waittillmatch { $$.as_waittillmatch = std::move($1); }
|
|
||||||
| stmt_waittillframeend { $$.as_waittillframeend = std::move($1); }
|
|
||||||
| stmt_waitframe { $$.as_waitframe = std::move($1); }
|
|
||||||
| stmt_if { $$.as_if = std::move($1); }
|
|
||||||
| stmt_ifelse { $$.as_ifelse = std::move($1); }
|
|
||||||
| stmt_while { $$.as_while = std::move($1); }
|
|
||||||
| stmt_dowhile { $$.as_dowhile = std::move($1); }
|
|
||||||
| stmt_for { $$.as_for = std::move($1); }
|
|
||||||
| stmt_foreach { $$.as_foreach = std::move($1); }
|
|
||||||
| stmt_switch { $$.as_switch = std::move($1); }
|
|
||||||
| stmt_case { $$.as_case = std::move($1); }
|
|
||||||
| stmt_default { $$.as_default = std::move($1); }
|
|
||||||
| stmt_break { $$.as_break = std::move($1); }
|
|
||||||
| stmt_continue { $$.as_continue = std::move($1); }
|
|
||||||
| stmt_return { $$.as_return = std::move($1); }
|
|
||||||
| stmt_breakpoint { $$.as_breakpoint = std::move($1); }
|
|
||||||
| stmt_prof_begin { $$.as_prof_begin = std::move($1); }
|
|
||||||
| stmt_prof_end { $$.as_prof_end = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_or_dev
|
|
||||||
: stmt { $$ = std::move($1); }
|
|
||||||
| stmt_dev { $$.as_dev = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_list
|
|
||||||
: stmt_list stmt
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($2)); }
|
|
||||||
| stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_list>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_or_dev_list
|
|
||||||
: stmt_or_dev_list stmt_or_dev
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($2)); }
|
|
||||||
| stmt_or_dev
|
|
||||||
{ $$ = std::make_unique<ast::stmt_list>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_dev
|
|
||||||
: DEVBEGIN stmt_list DEVEND { $$ = std::make_unique<ast::stmt_dev>(@$, std::move($2)); }
|
|
||||||
| DEVBEGIN DEVEND { $$ = std::make_unique<ast::stmt_dev>(@$, std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_block
|
|
||||||
: LBRACE stmt_or_dev_list RBRACE { $$ = std::move($2); }
|
|
||||||
| LBRACE RBRACE { $$ = std::make_unique<ast::stmt_list>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_expr
|
|
||||||
: expr_assign
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
| expr_increment
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
| expr_decrement
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::make_unique<ast::node>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_call
|
|
||||||
: expr_call SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_call>(@$, ast::expr(std::move($1))); }
|
|
||||||
| expr_method SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_call>(@$, ast::expr(std::move($1))); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_assign
|
|
||||||
: expr_assign SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
| expr_increment SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
| expr_decrement SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_endon
|
|
||||||
: expr_object ENDON LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_endon>(@$, std::move($1), std::move($4)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_notify
|
|
||||||
: expr_object NOTIFY LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_notify>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object NOTIFY LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_notify>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_wait
|
|
||||||
: WAIT expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_wait>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittill
|
|
||||||
: expr_object WAITTILL LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittill>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object WAITTILL LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittill>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittillmatch
|
|
||||||
: expr_object WAITTILLMATCH LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillmatch>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object WAITTILLMATCH LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillmatch>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittillframeend
|
|
||||||
: WAITTILLFRAMEEND SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillframeend>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waitframe
|
|
||||||
: WAITFRAME SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waitframe>(@$); }
|
|
||||||
| WAITFRAME LPAREN RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waitframe>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_if
|
|
||||||
: IF LPAREN expr RPAREN stmt %prec THEN
|
|
||||||
{ $$ = std::make_unique<ast::stmt_if>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_ifelse
|
|
||||||
: IF LPAREN expr RPAREN stmt ELSE stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_ifelse>(@$, std::move($3), std::move($5), std::move($7)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_while
|
|
||||||
: WHILE LPAREN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_while>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_dowhile
|
|
||||||
: DO stmt WHILE LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_dowhile>(@$, std::move($5), std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_for
|
|
||||||
: FOR LPAREN stmt_expr SEMICOLON expr_or_empty SEMICOLON stmt_expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_for>(@$, ast::stmt(std::move($3)), std::move($5), ast::stmt(std::move($7)), std::move($9)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_foreach
|
|
||||||
: FOREACH LPAREN expr_identifier IN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_foreach>(@$, ast::expr(std::move($3)), std::move($5), std::move($7)); }
|
|
||||||
| FOREACH LPAREN expr_identifier COMMA expr_identifier IN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_foreach>(@$, ast::expr(std::move($3)), ast::expr(std::move($5)), std::move($7), std::move($9)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_switch
|
|
||||||
: SWITCH LPAREN expr RPAREN stmt_block
|
|
||||||
{ $$ = std::make_unique<ast::stmt_switch>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_case
|
|
||||||
: CASE expr_integer COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_case>(@$, ast::expr(std::move($2)), std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
| CASE expr_string COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_case>(@$, ast::expr(std::move($2)), std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_default
|
|
||||||
: DEFAULT COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_default>(@$, std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_break
|
|
||||||
: BREAK SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_break>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_continue
|
|
||||||
: CONTINUE SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_continue>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_return
|
|
||||||
: RETURN expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_return>(@$, std::move($2)); }
|
|
||||||
| RETURN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_return>(@$, std::make_unique<ast::node>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_breakpoint
|
|
||||||
: BREAKPOINT SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_breakpoint>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_prof_begin
|
|
||||||
: PROFBEGIN LPAREN expr_arguments RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_prof_begin>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_prof_end
|
|
||||||
: PROFEND LPAREN expr_arguments RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_prof_end>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr
|
|
||||||
: expr_ternary { $$ = std::move($1); }
|
|
||||||
| expr_binary { $$ = std::move($1); }
|
|
||||||
| expr_primitive { $$ = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_or_empty
|
|
||||||
: expr { $$ = std::move($1); }
|
|
||||||
| { $$.as_node = std::make_unique<ast::node>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_assign
|
|
||||||
: expr_object ASSIGN expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_EXOR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_exor>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_LSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_shift_left>(@$, std::move($1),std::move( $3)); }
|
|
||||||
| expr_object ASSIGN_RSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_shift_right>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_ADD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_add>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_SUB expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_sub>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_MUL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_mul>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_DIV expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_div>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_MOD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_mod>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_increment
|
|
||||||
: INCREMENT expr_object %prec PREINC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_increment>(@$, std::move($2), true); }
|
|
||||||
| expr_object INCREMENT %prec POSTINC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_increment>(@$, std::move($1), false); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_decrement
|
|
||||||
: DECREMENT expr_object %prec PREDEC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_decrement>(@$, std::move($2), true); }
|
|
||||||
| expr_object DECREMENT %prec POSTDEC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_decrement>(@$, std::move($1), false); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_ternary
|
|
||||||
: expr QMARK expr COLON expr %prec TERN
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_ternary>(@$, std::move($1), std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_binary
|
|
||||||
: expr OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr EQUALITY expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_equality>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr INEQUALITY expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_inequality>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LESS_EQUAL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_less_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr GREATER_EQUAL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_greater_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LESS expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_less>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr GREATER expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_greater>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_EXOR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_exor>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_shift_left>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr RSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_shift_right>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr ADD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_add>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr SUB expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_sub>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr MUL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_mul>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr DIV expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_div>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr MOD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_mod>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_primitive
|
|
||||||
: expr_complement { $$.as_node = std::move($1); }
|
|
||||||
| expr_negate { $$.as_node = std::move($1); }
|
|
||||||
| expr_not { $$.as_node = std::move($1); }
|
|
||||||
| expr_call { $$.as_node = std::move($1); }
|
|
||||||
| expr_method { $$.as_node = std::move($1); }
|
|
||||||
| expr_add_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_isdefined { $$.as_node = std::move($1); }
|
|
||||||
| expr_istrue { $$.as_node = std::move($1); }
|
|
||||||
| expr_reference { $$.as_node = std::move($1); }
|
|
||||||
| expr_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_field { $$.as_node = std::move($1); }
|
|
||||||
| expr_size { $$.as_node = std::move($1); }
|
|
||||||
| expr_paren { $$.as_node = std::move($1); }
|
|
||||||
| expr_thisthread { $$.as_node = std::move($1); }
|
|
||||||
| expr_empty_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_undefined { $$.as_node = std::move($1); }
|
|
||||||
| expr_game { $$.as_node = std::move($1); }
|
|
||||||
| expr_self { $$.as_node = std::move($1); }
|
|
||||||
| expr_anim { $$.as_node = std::move($1); }
|
|
||||||
| expr_level { $$.as_node = std::move($1); }
|
|
||||||
| expr_animation { $$.as_node = std::move($1); }
|
|
||||||
| expr_animtree { $$.as_node = std::move($1); }
|
|
||||||
| expr_identifier { $$.as_node = std::move($1); }
|
|
||||||
| expr_istring { $$.as_node = std::move($1); }
|
|
||||||
| expr_string { $$.as_node = std::move($1); }
|
|
||||||
| expr_vector { $$.as_node = std::move($1); }
|
|
||||||
| expr_float { $$.as_node = std::move($1); }
|
|
||||||
| expr_integer { $$.as_node = std::move($1); }
|
|
||||||
| expr_false { $$.as_node = std::move($1); }
|
|
||||||
| expr_true { $$.as_node = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_complement
|
|
||||||
: COMPLEMENT expr
|
|
||||||
{ $$ = std::make_unique<ast::expr_complement>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_negate
|
|
||||||
: SUB expr_identifier %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_paren %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_array %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_field %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_not
|
|
||||||
: NOT expr
|
|
||||||
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_call
|
|
||||||
: expr_function { $$ = std::make_unique<ast::expr_call>(@$, std::move($1)); }
|
|
||||||
| expr_pointer { $$ = std::make_unique<ast::expr_call>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
expr_method
|
|
||||||
: expr_object expr_function { $$ = std::make_unique<ast::expr_method>(@$, std::move($1), std::move($2)); }
|
|
||||||
| expr_object expr_pointer { $$ = std::make_unique<ast::expr_method>(@$, std::move($1), std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_function
|
|
||||||
: expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($1), std::move($3), ast::call::mode::normal); }
|
|
||||||
| expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($1), std::move($3), std::move($5), ast::call::mode::normal); }
|
|
||||||
| THREAD expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($2), std::move($4), ast::call::mode::thread); }
|
|
||||||
| THREAD expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($2), std::move($4), std::move($6), ast::call::mode::thread); }
|
|
||||||
| CHILDTHREAD expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($2), std::move($4), ast::call::mode::childthread); }
|
|
||||||
| CHILDTHREAD expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($2), std::move($4), std::move($6), ast::call::mode::childthread); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_pointer
|
|
||||||
: LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($3), std::move($7), ast::call::mode::normal); }
|
|
||||||
| THREAD LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::thread); }
|
|
||||||
| CHILDTHREAD LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::childthread); }
|
|
||||||
| CALL LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::builtin); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_add_array
|
|
||||||
: LBRACKET expr_arguments_no_empty RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_add_array>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_parameters
|
|
||||||
: expr_parameters COMMA expr_identifier
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($3)); }
|
|
||||||
| expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_parameters>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::expr_parameters>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_arguments
|
|
||||||
: expr_arguments_no_empty
|
|
||||||
{ $$ = std::move($1); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::expr_arguments>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_arguments_no_empty
|
|
||||||
: expr_arguments COMMA expr
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($3)); }
|
|
||||||
| expr %prec ADD_ARRAY
|
|
||||||
{ $$ = std::make_unique<ast::expr_arguments>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_isdefined
|
|
||||||
: ISDEFINED LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_isdefined>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_istrue
|
|
||||||
: ISTRUE LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_istrue>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_reference
|
|
||||||
: DOUBLECOLON expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_reference>(@$, std::make_unique<ast::expr_path>(@$), std::move($2)); }
|
|
||||||
| expr_path DOUBLECOLON expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_reference>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_array
|
|
||||||
: expr_object LBRACKET expr RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_array>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_field
|
|
||||||
: expr_object DOT expr_identifier_nosize
|
|
||||||
{ $$ = std::make_unique<ast::expr_field>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_size
|
|
||||||
: expr_object DOT SIZE %prec SIZEOF
|
|
||||||
{ $$ = std::make_unique<ast::expr_size>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_paren
|
|
||||||
: LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_paren>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_object
|
|
||||||
: expr_call { $$.as_node = std::move($1); }
|
|
||||||
| expr_method { $$.as_node = std::move($1); }
|
|
||||||
| expr_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_field { $$.as_node = std::move($1); }
|
|
||||||
| expr_game { $$.as_node = std::move($1); }
|
|
||||||
| expr_self { $$.as_node = std::move($1); }
|
|
||||||
| expr_anim { $$.as_node = std::move($1); }
|
|
||||||
| expr_level { $$.as_node = std::move($1); }
|
|
||||||
| expr_identifier { $$.as_node = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_thisthread
|
|
||||||
: THISTHREAD
|
|
||||||
{ $$ = std::make_unique<ast::expr_thisthread>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_empty_array
|
|
||||||
: LBRACKET RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_empty_array>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_undefined
|
|
||||||
: UNDEFINED
|
|
||||||
{ $$ = std::make_unique<ast::expr_undefined>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_game
|
|
||||||
: GAME
|
|
||||||
{ $$ = std::make_unique<ast::expr_game>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_self
|
|
||||||
: SELF
|
|
||||||
{ $$ = std::make_unique<ast::expr_self>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_anim
|
|
||||||
: ANIM
|
|
||||||
{ $$ = std::make_unique<ast::expr_anim>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_level
|
|
||||||
: LEVEL
|
|
||||||
{ $$ = std::make_unique<ast::expr_level>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_animation
|
|
||||||
: MOD IDENTIFIER %prec ANIMREF
|
|
||||||
{ $$ = std::make_unique<ast::expr_animation>(@$, $2); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_animtree
|
|
||||||
: ANIMTREE
|
|
||||||
{ $$ = std::make_unique<ast::expr_animtree>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_identifier_nosize
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_identifier
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, $1); };
|
|
||||||
| SIZE
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, "size"); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_path
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_path>(@$, $1); };
|
|
||||||
| PATH
|
|
||||||
{ $$ = std::make_unique<ast::expr_path>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_istring
|
|
||||||
: ISTRING
|
|
||||||
{ $$ = std::make_unique<ast::expr_istring>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_string
|
|
||||||
: STRING
|
|
||||||
{ $$ = std::make_unique<ast::expr_string>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_vector
|
|
||||||
: LPAREN expr COMMA expr COMMA expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_vector>(@$, std::move($2), std::move($4), std::move($6)); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_float
|
|
||||||
: SUB FLOAT %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_float>(@$, "-" + $2); };
|
|
||||||
| FLOAT
|
|
||||||
{ $$ = std::make_unique<ast::expr_float>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_integer
|
|
||||||
: SUB INTEGER %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_integer>(@$, "-" + $2); };
|
|
||||||
| INTEGER
|
|
||||||
{ $$ = std::make_unique<ast::expr_integer>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_false
|
|
||||||
: FALSE
|
|
||||||
{ $$ = std::make_unique<ast::expr_false>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_true
|
|
||||||
: TRUE
|
|
||||||
{ $$ = std::make_unique<ast::expr_true>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
void xsk::gsc::iw8::parser::error(const xsk::gsc::location& loc, const std::string& msg)
|
|
||||||
{
|
|
||||||
throw xsk::gsc::comp_error(loc, msg);
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
generate: S1
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf ./parser.hpp
|
|
||||||
rm -rf ./parser.cpp
|
|
||||||
|
|
||||||
S1: parser.ypp
|
|
||||||
bison parser.ypp -Wcounterexamples
|
|
||||||
mv parser.hpp parser.cpp ../../src/s1/xsk/
|
|
@ -1,875 +0,0 @@
|
|||||||
/* Copyright 2022 xensik. All rights reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a GNU GPLv3 license
|
|
||||||
// that can be found in the LICENSE file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
%require "3.7"
|
|
||||||
%skeleton "lalr1.cc"
|
|
||||||
%language "c++"
|
|
||||||
%output "parser.cpp"
|
|
||||||
%defines "parser.hpp"
|
|
||||||
%define api.prefix {S1}
|
|
||||||
%define api.namespace {xsk::gsc::s1}
|
|
||||||
%define api.location.type {xsk::gsc::location}
|
|
||||||
%define api.value.type variant
|
|
||||||
%define api.token.constructor
|
|
||||||
%define api.token.raw
|
|
||||||
%define parse.assert
|
|
||||||
%define parse.trace
|
|
||||||
%define parse.error detailed
|
|
||||||
%define parse.lac full
|
|
||||||
%locations
|
|
||||||
%lex-param { xsk::gsc::s1::lexer& lexer }
|
|
||||||
%parse-param { xsk::gsc::s1::lexer& lexer }
|
|
||||||
%parse-param { xsk::gsc::ast::program::ptr& ast }
|
|
||||||
|
|
||||||
%code requires
|
|
||||||
{
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(disable:4065)
|
|
||||||
#pragma warning(disable:4127)
|
|
||||||
#endif
|
|
||||||
#include "s1.hpp"
|
|
||||||
namespace xsk::gsc::s1 { class lexer; }
|
|
||||||
}
|
|
||||||
|
|
||||||
%code top
|
|
||||||
{
|
|
||||||
#include "stdafx.hpp"
|
|
||||||
#include "parser.hpp"
|
|
||||||
#include "lexer.hpp"
|
|
||||||
using namespace xsk::gsc;
|
|
||||||
xsk::gsc::s1::parser::symbol_type S1lex(xsk::gsc::s1::lexer& lexer);
|
|
||||||
}
|
|
||||||
|
|
||||||
%token SH_DEFINE "#define"
|
|
||||||
%token SH_UNDEF "#undef"
|
|
||||||
%token SH_IFDEF "#ifdef"
|
|
||||||
%token SH_IFNDEF "#ifndef"
|
|
||||||
%token SH_IF "#if"
|
|
||||||
%token SH_ELIF "#elif"
|
|
||||||
%token SH_ELSE "#else"
|
|
||||||
%token SH_ENDIF "#endif"
|
|
||||||
%token DEVBEGIN "/#"
|
|
||||||
%token DEVEND "#/"
|
|
||||||
%token INLINE "#inline"
|
|
||||||
%token INCLUDE "#include"
|
|
||||||
%token USINGTREE "#using_animtree"
|
|
||||||
%token ANIMTREE "#animtree"
|
|
||||||
%token ENDON "endon"
|
|
||||||
%token NOTIFY "notify"
|
|
||||||
%token WAIT "wait"
|
|
||||||
%token WAITTILL "waittill"
|
|
||||||
%token WAITTILLMATCH "waittillmatch"
|
|
||||||
%token WAITTILLFRAMEEND "waittillframeend"
|
|
||||||
%token WAITFRAME "waitframe"
|
|
||||||
%token IF "if"
|
|
||||||
%token ELSE "else"
|
|
||||||
%token DO "do"
|
|
||||||
%token WHILE "while"
|
|
||||||
%token FOR "for"
|
|
||||||
%token FOREACH "foreach"
|
|
||||||
%token IN "in"
|
|
||||||
%token SWITCH "switch"
|
|
||||||
%token CASE "case"
|
|
||||||
%token DEFAULT "default"
|
|
||||||
%token BREAK "break"
|
|
||||||
%token CONTINUE "continue"
|
|
||||||
%token RETURN "return"
|
|
||||||
%token BREAKPOINT "breakpoint"
|
|
||||||
%token PROFBEGIN "prof_begin"
|
|
||||||
%token PROFEND "prof_end"
|
|
||||||
%token THREAD "thread"
|
|
||||||
%token CHILDTHREAD "childthread"
|
|
||||||
%token THISTHREAD "thisthread"
|
|
||||||
%token CALL "call"
|
|
||||||
%token TRUE "true"
|
|
||||||
%token FALSE "false"
|
|
||||||
%token UNDEFINED "undefined"
|
|
||||||
%token SIZE "size"
|
|
||||||
%token GAME "game"
|
|
||||||
%token SELF "self"
|
|
||||||
%token ANIM "anim"
|
|
||||||
%token LEVEL "level"
|
|
||||||
%token LPAREN "("
|
|
||||||
%token RPAREN ")"
|
|
||||||
%token LBRACE "{"
|
|
||||||
%token RBRACE "}"
|
|
||||||
%token LBRACKET "["
|
|
||||||
%token RBRACKET "]"
|
|
||||||
%token COMMA ","
|
|
||||||
%token DOT "."
|
|
||||||
%token DOUBLECOLON "::"
|
|
||||||
%token COLON ":"
|
|
||||||
%token SEMICOLON ";"
|
|
||||||
%token QMARK "?"
|
|
||||||
%token INCREMENT "++"
|
|
||||||
%token DECREMENT "--"
|
|
||||||
%token LSHIFT "<<"
|
|
||||||
%token RSHIFT ">>"
|
|
||||||
%token OR "||"
|
|
||||||
%token AND "&&"
|
|
||||||
%token EQUALITY "=="
|
|
||||||
%token INEQUALITY "!="
|
|
||||||
%token LESS_EQUAL "<="
|
|
||||||
%token GREATER_EQUAL ">="
|
|
||||||
%token LESS "<"
|
|
||||||
%token GREATER ">"
|
|
||||||
%token NOT "!"
|
|
||||||
%token COMPLEMENT "~"
|
|
||||||
%token ASSIGN "="
|
|
||||||
%token ASSIGN_ADD "+="
|
|
||||||
%token ASSIGN_SUB "-="
|
|
||||||
%token ASSIGN_MUL "*="
|
|
||||||
%token ASSIGN_DIV "/="
|
|
||||||
%token ASSIGN_MOD "%="
|
|
||||||
%token ASSIGN_BW_OR "|="
|
|
||||||
%token ASSIGN_BW_AND "&="
|
|
||||||
%token ASSIGN_BW_EXOR "^="
|
|
||||||
%token ASSIGN_RSHIFT ">>="
|
|
||||||
%token ASSIGN_LSHIFT "<<="
|
|
||||||
%token BITWISE_OR "|"
|
|
||||||
%token BITWISE_AND "&"
|
|
||||||
%token BITWISE_EXOR "^"
|
|
||||||
%token ADD "+"
|
|
||||||
%token SUB "-"
|
|
||||||
%token MUL "*"
|
|
||||||
%token DIV "/"
|
|
||||||
%token MOD "%"
|
|
||||||
%token <std::string> PATH "path"
|
|
||||||
%token <std::string> IDENTIFIER "identifier"
|
|
||||||
%token <std::string> STRING "string literal"
|
|
||||||
%token <std::string> ISTRING "localized string"
|
|
||||||
%token <std::string> FLOAT "float"
|
|
||||||
%token <std::string> INTEGER "integer"
|
|
||||||
|
|
||||||
%type <ast::program::ptr> program
|
|
||||||
%type <ast::include::ptr> include
|
|
||||||
%type <ast::decl> declaration
|
|
||||||
%type <ast::decl_usingtree::ptr> decl_usingtree
|
|
||||||
%type <ast::decl_constant::ptr> decl_constant
|
|
||||||
%type <ast::decl_thread::ptr> decl_thread
|
|
||||||
%type <ast::stmt> stmt
|
|
||||||
%type <ast::stmt> stmt_or_dev
|
|
||||||
%type <ast::stmt_list::ptr> stmt_list
|
|
||||||
%type <ast::stmt_list::ptr> stmt_or_dev_list
|
|
||||||
%type <ast::stmt_dev::ptr> stmt_dev
|
|
||||||
%type <ast::stmt_list::ptr> stmt_block
|
|
||||||
%type <ast::stmt_expr::ptr> stmt_expr
|
|
||||||
%type <ast::stmt_call::ptr> stmt_call
|
|
||||||
%type <ast::stmt_assign::ptr> stmt_assign
|
|
||||||
%type <ast::stmt_endon::ptr> stmt_endon
|
|
||||||
%type <ast::stmt_notify::ptr> stmt_notify
|
|
||||||
%type <ast::stmt_wait::ptr> stmt_wait
|
|
||||||
%type <ast::stmt_waittill::ptr> stmt_waittill
|
|
||||||
%type <ast::stmt_waittillmatch::ptr> stmt_waittillmatch
|
|
||||||
%type <ast::stmt_waittillframeend::ptr> stmt_waittillframeend
|
|
||||||
%type <ast::stmt_waitframe::ptr> stmt_waitframe
|
|
||||||
%type <ast::stmt_if::ptr> stmt_if
|
|
||||||
%type <ast::stmt_ifelse::ptr> stmt_ifelse
|
|
||||||
%type <ast::stmt_while::ptr> stmt_while
|
|
||||||
%type <ast::stmt_dowhile::ptr> stmt_dowhile
|
|
||||||
%type <ast::stmt_for::ptr> stmt_for
|
|
||||||
%type <ast::stmt_foreach::ptr> stmt_foreach
|
|
||||||
%type <ast::stmt_switch::ptr> stmt_switch
|
|
||||||
%type <ast::stmt_case::ptr> stmt_case
|
|
||||||
%type <ast::stmt_default::ptr> stmt_default
|
|
||||||
%type <ast::stmt_break::ptr> stmt_break
|
|
||||||
%type <ast::stmt_continue::ptr> stmt_continue
|
|
||||||
%type <ast::stmt_return::ptr> stmt_return
|
|
||||||
%type <ast::stmt_breakpoint::ptr> stmt_breakpoint
|
|
||||||
%type <ast::stmt_prof_begin::ptr> stmt_prof_begin
|
|
||||||
%type <ast::stmt_prof_end::ptr> stmt_prof_end
|
|
||||||
%type <ast::expr> expr
|
|
||||||
%type <ast::expr> expr_or_empty
|
|
||||||
%type <ast::expr> expr_assign
|
|
||||||
%type <ast::expr> expr_increment
|
|
||||||
%type <ast::expr> expr_decrement
|
|
||||||
%type <ast::expr> expr_ternary
|
|
||||||
%type <ast::expr> expr_binary
|
|
||||||
%type <ast::expr> expr_primitive
|
|
||||||
%type <ast::expr_complement::ptr> expr_complement
|
|
||||||
%type <ast::expr_negate::ptr> expr_negate
|
|
||||||
%type <ast::expr_not::ptr> expr_not
|
|
||||||
%type <ast::expr_call::ptr> expr_call
|
|
||||||
%type <ast::expr_method::ptr> expr_method
|
|
||||||
%type <ast::call> expr_function
|
|
||||||
%type <ast::call> expr_pointer
|
|
||||||
%type <ast::expr_add_array::ptr> expr_add_array
|
|
||||||
%type <ast::expr_parameters::ptr> expr_parameters
|
|
||||||
%type <ast::expr_arguments::ptr> expr_arguments
|
|
||||||
%type <ast::expr_arguments::ptr> expr_arguments_no_empty
|
|
||||||
%type <ast::expr_reference::ptr> expr_reference
|
|
||||||
%type <ast::expr_array::ptr> expr_array
|
|
||||||
%type <ast::expr_field::ptr> expr_field
|
|
||||||
%type <ast::expr_size::ptr> expr_size
|
|
||||||
%type <ast::expr_paren::ptr> expr_paren
|
|
||||||
%type <ast::expr> expr_object
|
|
||||||
%type <ast::expr_thisthread::ptr> expr_thisthread
|
|
||||||
%type <ast::expr_empty_array::ptr> expr_empty_array
|
|
||||||
%type <ast::expr_undefined::ptr> expr_undefined
|
|
||||||
%type <ast::expr_game::ptr> expr_game
|
|
||||||
%type <ast::expr_self::ptr> expr_self
|
|
||||||
%type <ast::expr_anim::ptr> expr_anim
|
|
||||||
%type <ast::expr_level::ptr> expr_level
|
|
||||||
%type <ast::expr_animation::ptr> expr_animation
|
|
||||||
%type <ast::expr_animtree::ptr> expr_animtree
|
|
||||||
%type <ast::expr_identifier::ptr> expr_identifier_nosize
|
|
||||||
%type <ast::expr_identifier::ptr> expr_identifier
|
|
||||||
%type <ast::expr_path::ptr> expr_path
|
|
||||||
%type <ast::expr_istring::ptr> expr_istring
|
|
||||||
%type <ast::expr_string::ptr> expr_string
|
|
||||||
%type <ast::expr_vector::ptr> expr_vector
|
|
||||||
%type <ast::expr_float::ptr> expr_float
|
|
||||||
%type <ast::expr_integer::ptr> expr_integer
|
|
||||||
%type <ast::expr_false::ptr> expr_false
|
|
||||||
%type <ast::expr_true::ptr> expr_true
|
|
||||||
|
|
||||||
%nonassoc SIZEOF
|
|
||||||
%nonassoc ADD_ARRAY
|
|
||||||
%nonassoc RBRACKET
|
|
||||||
%nonassoc THEN
|
|
||||||
%nonassoc ELSE
|
|
||||||
%nonassoc INCREMENT DECREMENT
|
|
||||||
|
|
||||||
%precedence TERN
|
|
||||||
%right QMARK
|
|
||||||
%left OR
|
|
||||||
%left AND
|
|
||||||
%left BITWISE_OR
|
|
||||||
%left BITWISE_EXOR
|
|
||||||
%left BITWISE_AND
|
|
||||||
%left EQUALITY INEQUALITY
|
|
||||||
%left LESS GREATER LESS_EQUAL GREATER_EQUAL
|
|
||||||
%left LSHIFT RSHIFT
|
|
||||||
%left ADD SUB
|
|
||||||
%left MUL DIV MOD
|
|
||||||
%right NOT COMPLEMENT
|
|
||||||
|
|
||||||
%precedence NEG
|
|
||||||
%precedence ANIMREF
|
|
||||||
%precedence PREINC PREDEC
|
|
||||||
%precedence POSTINC POSTDEC
|
|
||||||
|
|
||||||
%start root
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
root
|
|
||||||
: program { ast = std::move($1); }
|
|
||||||
| { ast = std::make_unique<ast::program>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
program
|
|
||||||
: program inline
|
|
||||||
{ $$ = std::move($1); }
|
|
||||||
| program include
|
|
||||||
{ $$ = std::move($1); $$->includes.push_back(std::move($2)); }
|
|
||||||
| program declaration
|
|
||||||
{ $$ = std::move($1); $$->declarations.push_back(std::move($2)); }
|
|
||||||
| inline
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); }
|
|
||||||
| include
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); $$->includes.push_back(std::move($1)); }
|
|
||||||
| declaration
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); $$->declarations.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
inline
|
|
||||||
: INLINE expr_path SEMICOLON { lexer.push_header($2->value); }
|
|
||||||
;
|
|
||||||
|
|
||||||
include
|
|
||||||
: INCLUDE expr_path SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::include>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
declaration
|
|
||||||
: DEVBEGIN { $$.as_dev_begin = std::make_unique<ast::decl_dev_begin>(@$); }
|
|
||||||
| DEVEND { $$.as_dev_end = std::make_unique<ast::decl_dev_end>(@$); }
|
|
||||||
| decl_usingtree { $$.as_usingtree = std::move($1); }
|
|
||||||
| decl_constant { $$.as_constant = std::move($1); }
|
|
||||||
| decl_thread { $$.as_thread = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_usingtree
|
|
||||||
: USINGTREE LPAREN expr_string RPAREN SEMICOLON
|
|
||||||
{ lexer.ban_header(@$); $$ = std::make_unique<ast::decl_usingtree>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_constant
|
|
||||||
: expr_identifier ASSIGN expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::decl_constant>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_thread
|
|
||||||
: expr_identifier LPAREN expr_parameters RPAREN stmt_block
|
|
||||||
{ lexer.ban_header(@$); $$ = std::make_unique<ast::decl_thread>(@$, std::move($1), std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt
|
|
||||||
: stmt_block { $$.as_list = std::move($1); }
|
|
||||||
| stmt_call { $$.as_call = std::move($1); }
|
|
||||||
| stmt_assign { $$.as_assign = std::move($1); }
|
|
||||||
| stmt_endon { $$.as_endon = std::move($1); }
|
|
||||||
| stmt_notify { $$.as_notify = std::move($1); }
|
|
||||||
| stmt_wait { $$.as_wait = std::move($1); }
|
|
||||||
| stmt_waittill { $$.as_waittill = std::move($1); }
|
|
||||||
| stmt_waittillmatch { $$.as_waittillmatch = std::move($1); }
|
|
||||||
| stmt_waittillframeend { $$.as_waittillframeend = std::move($1); }
|
|
||||||
| stmt_waitframe { $$.as_waitframe = std::move($1); }
|
|
||||||
| stmt_if { $$.as_if = std::move($1); }
|
|
||||||
| stmt_ifelse { $$.as_ifelse = std::move($1); }
|
|
||||||
| stmt_while { $$.as_while = std::move($1); }
|
|
||||||
| stmt_dowhile { $$.as_dowhile = std::move($1); }
|
|
||||||
| stmt_for { $$.as_for = std::move($1); }
|
|
||||||
| stmt_foreach { $$.as_foreach = std::move($1); }
|
|
||||||
| stmt_switch { $$.as_switch = std::move($1); }
|
|
||||||
| stmt_case { $$.as_case = std::move($1); }
|
|
||||||
| stmt_default { $$.as_default = std::move($1); }
|
|
||||||
| stmt_break { $$.as_break = std::move($1); }
|
|
||||||
| stmt_continue { $$.as_continue = std::move($1); }
|
|
||||||
| stmt_return { $$.as_return = std::move($1); }
|
|
||||||
| stmt_breakpoint { $$.as_breakpoint = std::move($1); }
|
|
||||||
| stmt_prof_begin { $$.as_prof_begin = std::move($1); }
|
|
||||||
| stmt_prof_end { $$.as_prof_end = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_or_dev
|
|
||||||
: stmt { $$ = std::move($1); }
|
|
||||||
| stmt_dev { $$.as_dev = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_list
|
|
||||||
: stmt_list stmt
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($2)); }
|
|
||||||
| stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_list>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_or_dev_list
|
|
||||||
: stmt_or_dev_list stmt_or_dev
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($2)); }
|
|
||||||
| stmt_or_dev
|
|
||||||
{ $$ = std::make_unique<ast::stmt_list>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_dev
|
|
||||||
: DEVBEGIN stmt_list DEVEND { $$ = std::make_unique<ast::stmt_dev>(@$, std::move($2)); }
|
|
||||||
| DEVBEGIN DEVEND { $$ = std::make_unique<ast::stmt_dev>(@$, std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_block
|
|
||||||
: LBRACE stmt_or_dev_list RBRACE { $$ = std::move($2); }
|
|
||||||
| LBRACE RBRACE { $$ = std::make_unique<ast::stmt_list>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_expr
|
|
||||||
: expr_assign
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
| expr_increment
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
| expr_decrement
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::make_unique<ast::node>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_call
|
|
||||||
: expr_call SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_call>(@$, ast::expr(std::move($1))); }
|
|
||||||
| expr_method SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_call>(@$, ast::expr(std::move($1))); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_assign
|
|
||||||
: expr_assign SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
| expr_increment SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
| expr_decrement SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_endon
|
|
||||||
: expr_object ENDON LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_endon>(@$, std::move($1), std::move($4)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_notify
|
|
||||||
: expr_object NOTIFY LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_notify>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object NOTIFY LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_notify>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_wait
|
|
||||||
: WAIT expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_wait>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittill
|
|
||||||
: expr_object WAITTILL LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittill>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object WAITTILL LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittill>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittillmatch
|
|
||||||
: expr_object WAITTILLMATCH LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillmatch>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object WAITTILLMATCH LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillmatch>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittillframeend
|
|
||||||
: WAITTILLFRAMEEND SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillframeend>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waitframe
|
|
||||||
: WAITFRAME SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waitframe>(@$); }
|
|
||||||
| WAITFRAME LPAREN RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waitframe>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_if
|
|
||||||
: IF LPAREN expr RPAREN stmt %prec THEN
|
|
||||||
{ $$ = std::make_unique<ast::stmt_if>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_ifelse
|
|
||||||
: IF LPAREN expr RPAREN stmt ELSE stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_ifelse>(@$, std::move($3), std::move($5), std::move($7)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_while
|
|
||||||
: WHILE LPAREN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_while>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_dowhile
|
|
||||||
: DO stmt WHILE LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_dowhile>(@$, std::move($5), std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_for
|
|
||||||
: FOR LPAREN stmt_expr SEMICOLON expr_or_empty SEMICOLON stmt_expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_for>(@$, ast::stmt(std::move($3)), std::move($5), ast::stmt(std::move($7)), std::move($9)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_foreach
|
|
||||||
: FOREACH LPAREN expr_identifier IN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_foreach>(@$, ast::expr(std::move($3)), std::move($5), std::move($7)); }
|
|
||||||
| FOREACH LPAREN expr_identifier COMMA expr_identifier IN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_foreach>(@$, ast::expr(std::move($3)), ast::expr(std::move($5)), std::move($7), std::move($9)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_switch
|
|
||||||
: SWITCH LPAREN expr RPAREN stmt_block
|
|
||||||
{ $$ = std::make_unique<ast::stmt_switch>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_case
|
|
||||||
: CASE expr_integer COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_case>(@$, ast::expr(std::move($2)), std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
| CASE expr_string COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_case>(@$, ast::expr(std::move($2)), std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_default
|
|
||||||
: DEFAULT COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_default>(@$, std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_break
|
|
||||||
: BREAK SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_break>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_continue
|
|
||||||
: CONTINUE SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_continue>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_return
|
|
||||||
: RETURN expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_return>(@$, std::move($2)); }
|
|
||||||
| RETURN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_return>(@$, std::make_unique<ast::node>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_breakpoint
|
|
||||||
: BREAKPOINT SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_breakpoint>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_prof_begin
|
|
||||||
: PROFBEGIN LPAREN expr_arguments RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_prof_begin>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_prof_end
|
|
||||||
: PROFEND LPAREN expr_arguments RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_prof_end>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr
|
|
||||||
: expr_ternary { $$ = std::move($1); }
|
|
||||||
| expr_binary { $$ = std::move($1); }
|
|
||||||
| expr_primitive { $$ = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_or_empty
|
|
||||||
: expr { $$ = std::move($1); }
|
|
||||||
| { $$.as_node = std::make_unique<ast::node>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_assign
|
|
||||||
: expr_object ASSIGN expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_EXOR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_exor>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_LSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_shift_left>(@$, std::move($1),std::move( $3)); }
|
|
||||||
| expr_object ASSIGN_RSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_shift_right>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_ADD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_add>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_SUB expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_sub>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_MUL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_mul>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_DIV expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_div>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_MOD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_mod>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_increment
|
|
||||||
: INCREMENT expr_object %prec PREINC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_increment>(@$, std::move($2), true); }
|
|
||||||
| expr_object INCREMENT %prec POSTINC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_increment>(@$, std::move($1), false); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_decrement
|
|
||||||
: DECREMENT expr_object %prec PREDEC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_decrement>(@$, std::move($2), true); }
|
|
||||||
| expr_object DECREMENT %prec POSTDEC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_decrement>(@$, std::move($1), false); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_ternary
|
|
||||||
: expr QMARK expr COLON expr %prec TERN
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_ternary>(@$, std::move($1), std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_binary
|
|
||||||
: expr OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr EQUALITY expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_equality>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr INEQUALITY expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_inequality>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LESS_EQUAL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_less_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr GREATER_EQUAL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_greater_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LESS expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_less>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr GREATER expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_greater>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_EXOR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_exor>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_shift_left>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr RSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_shift_right>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr ADD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_add>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr SUB expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_sub>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr MUL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_mul>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr DIV expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_div>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr MOD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_mod>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_primitive
|
|
||||||
: expr_complement { $$.as_node = std::move($1); }
|
|
||||||
| expr_negate { $$.as_node = std::move($1); }
|
|
||||||
| expr_not { $$.as_node = std::move($1); }
|
|
||||||
| expr_call { $$.as_node = std::move($1); }
|
|
||||||
| expr_method { $$.as_node = std::move($1); }
|
|
||||||
| expr_add_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_reference { $$.as_node = std::move($1); }
|
|
||||||
| expr_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_field { $$.as_node = std::move($1); }
|
|
||||||
| expr_size { $$.as_node = std::move($1); }
|
|
||||||
| expr_paren { $$.as_node = std::move($1); }
|
|
||||||
| expr_thisthread { $$.as_node = std::move($1); }
|
|
||||||
| expr_empty_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_undefined { $$.as_node = std::move($1); }
|
|
||||||
| expr_game { $$.as_node = std::move($1); }
|
|
||||||
| expr_self { $$.as_node = std::move($1); }
|
|
||||||
| expr_anim { $$.as_node = std::move($1); }
|
|
||||||
| expr_level { $$.as_node = std::move($1); }
|
|
||||||
| expr_animation { $$.as_node = std::move($1); }
|
|
||||||
| expr_animtree { $$.as_node = std::move($1); }
|
|
||||||
| expr_identifier { $$.as_node = std::move($1); }
|
|
||||||
| expr_istring { $$.as_node = std::move($1); }
|
|
||||||
| expr_string { $$.as_node = std::move($1); }
|
|
||||||
| expr_vector { $$.as_node = std::move($1); }
|
|
||||||
| expr_float { $$.as_node = std::move($1); }
|
|
||||||
| expr_integer { $$.as_node = std::move($1); }
|
|
||||||
| expr_false { $$.as_node = std::move($1); }
|
|
||||||
| expr_true { $$.as_node = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_complement
|
|
||||||
: COMPLEMENT expr
|
|
||||||
{ $$ = std::make_unique<ast::expr_complement>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_negate
|
|
||||||
: SUB expr_identifier %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_paren %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_array %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_field %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_not
|
|
||||||
: NOT expr
|
|
||||||
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_call
|
|
||||||
: expr_function { $$ = std::make_unique<ast::expr_call>(@$, std::move($1)); }
|
|
||||||
| expr_pointer { $$ = std::make_unique<ast::expr_call>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
expr_method
|
|
||||||
: expr_object expr_function { $$ = std::make_unique<ast::expr_method>(@$, std::move($1), std::move($2)); }
|
|
||||||
| expr_object expr_pointer { $$ = std::make_unique<ast::expr_method>(@$, std::move($1), std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_function
|
|
||||||
: expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($1), std::move($3), ast::call::mode::normal); }
|
|
||||||
| expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($1), std::move($3), std::move($5), ast::call::mode::normal); }
|
|
||||||
| THREAD expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($2), std::move($4), ast::call::mode::thread); }
|
|
||||||
| THREAD expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($2), std::move($4), std::move($6), ast::call::mode::thread); }
|
|
||||||
| CHILDTHREAD expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($2), std::move($4), ast::call::mode::childthread); }
|
|
||||||
| CHILDTHREAD expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($2), std::move($4), std::move($6), ast::call::mode::childthread); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_pointer
|
|
||||||
: LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($3), std::move($7), ast::call::mode::normal); }
|
|
||||||
| THREAD LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::thread); }
|
|
||||||
| CHILDTHREAD LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::childthread); }
|
|
||||||
| CALL LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::builtin); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_add_array
|
|
||||||
: LBRACKET expr_arguments_no_empty RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_add_array>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_parameters
|
|
||||||
: expr_parameters COMMA expr_identifier
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($3)); }
|
|
||||||
| expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_parameters>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::expr_parameters>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_arguments
|
|
||||||
: expr_arguments_no_empty
|
|
||||||
{ $$ = std::move($1); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::expr_arguments>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_arguments_no_empty
|
|
||||||
: expr_arguments COMMA expr
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($3)); }
|
|
||||||
| expr %prec ADD_ARRAY
|
|
||||||
{ $$ = std::make_unique<ast::expr_arguments>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_reference
|
|
||||||
: DOUBLECOLON expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_reference>(@$, std::make_unique<ast::expr_path>(@$), std::move($2)); }
|
|
||||||
| expr_path DOUBLECOLON expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_reference>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_array
|
|
||||||
: expr_object LBRACKET expr RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_array>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_field
|
|
||||||
: expr_object DOT expr_identifier_nosize
|
|
||||||
{ $$ = std::make_unique<ast::expr_field>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_size
|
|
||||||
: expr_object DOT SIZE %prec SIZEOF
|
|
||||||
{ $$ = std::make_unique<ast::expr_size>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_paren
|
|
||||||
: LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_paren>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_object
|
|
||||||
: expr_call { $$.as_node = std::move($1); }
|
|
||||||
| expr_method { $$.as_node = std::move($1); }
|
|
||||||
| expr_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_field { $$.as_node = std::move($1); }
|
|
||||||
| expr_game { $$.as_node = std::move($1); }
|
|
||||||
| expr_self { $$.as_node = std::move($1); }
|
|
||||||
| expr_anim { $$.as_node = std::move($1); }
|
|
||||||
| expr_level { $$.as_node = std::move($1); }
|
|
||||||
| expr_identifier { $$.as_node = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_thisthread
|
|
||||||
: THISTHREAD
|
|
||||||
{ $$ = std::make_unique<ast::expr_thisthread>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_empty_array
|
|
||||||
: LBRACKET RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_empty_array>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_undefined
|
|
||||||
: UNDEFINED
|
|
||||||
{ $$ = std::make_unique<ast::expr_undefined>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_game
|
|
||||||
: GAME
|
|
||||||
{ $$ = std::make_unique<ast::expr_game>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_self
|
|
||||||
: SELF
|
|
||||||
{ $$ = std::make_unique<ast::expr_self>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_anim
|
|
||||||
: ANIM
|
|
||||||
{ $$ = std::make_unique<ast::expr_anim>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_level
|
|
||||||
: LEVEL
|
|
||||||
{ $$ = std::make_unique<ast::expr_level>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_animation
|
|
||||||
: MOD IDENTIFIER %prec ANIMREF
|
|
||||||
{ $$ = std::make_unique<ast::expr_animation>(@$, $2); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_animtree
|
|
||||||
: ANIMTREE
|
|
||||||
{ $$ = std::make_unique<ast::expr_animtree>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_identifier_nosize
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_identifier
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, $1); };
|
|
||||||
| SIZE
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, "size"); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_path
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_path>(@$, $1); };
|
|
||||||
| PATH
|
|
||||||
{ $$ = std::make_unique<ast::expr_path>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_istring
|
|
||||||
: ISTRING
|
|
||||||
{ $$ = std::make_unique<ast::expr_istring>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_string
|
|
||||||
: STRING
|
|
||||||
{ $$ = std::make_unique<ast::expr_string>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_vector
|
|
||||||
: LPAREN expr COMMA expr COMMA expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_vector>(@$, std::move($2), std::move($4), std::move($6)); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_float
|
|
||||||
: SUB FLOAT %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_float>(@$, "-" + $2); };
|
|
||||||
| FLOAT
|
|
||||||
{ $$ = std::make_unique<ast::expr_float>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_integer
|
|
||||||
: SUB INTEGER %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_integer>(@$, "-" + $2); };
|
|
||||||
| INTEGER
|
|
||||||
{ $$ = std::make_unique<ast::expr_integer>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_false
|
|
||||||
: FALSE
|
|
||||||
{ $$ = std::make_unique<ast::expr_false>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_true
|
|
||||||
: TRUE
|
|
||||||
{ $$ = std::make_unique<ast::expr_true>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
void xsk::gsc::s1::parser::error(const xsk::gsc::location& loc, const std::string& msg)
|
|
||||||
{
|
|
||||||
throw xsk::gsc::comp_error(loc, msg);
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
generate: S2
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf ./parser.hpp
|
|
||||||
rm -rf ./parser.cpp
|
|
||||||
|
|
||||||
S2: parser.ypp
|
|
||||||
bison parser.ypp -Wcounterexamples
|
|
||||||
mv parser.hpp parser.cpp ../../src/s2/xsk/
|
|
@ -1,875 +0,0 @@
|
|||||||
/* Copyright 2022 xensik. All rights reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a GNU GPLv3 license
|
|
||||||
// that can be found in the LICENSE file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
%require "3.7"
|
|
||||||
%skeleton "lalr1.cc"
|
|
||||||
%language "c++"
|
|
||||||
%output "parser.cpp"
|
|
||||||
%defines "parser.hpp"
|
|
||||||
%define api.prefix {S2}
|
|
||||||
%define api.namespace {xsk::gsc::s2}
|
|
||||||
%define api.location.type {xsk::gsc::location}
|
|
||||||
%define api.value.type variant
|
|
||||||
%define api.token.constructor
|
|
||||||
%define api.token.raw
|
|
||||||
%define parse.assert
|
|
||||||
%define parse.trace
|
|
||||||
%define parse.error detailed
|
|
||||||
%define parse.lac full
|
|
||||||
%locations
|
|
||||||
%lex-param { xsk::gsc::s2::lexer& lexer }
|
|
||||||
%parse-param { xsk::gsc::s2::lexer& lexer }
|
|
||||||
%parse-param { xsk::gsc::ast::program::ptr& ast }
|
|
||||||
|
|
||||||
%code requires
|
|
||||||
{
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(disable:4065)
|
|
||||||
#pragma warning(disable:4127)
|
|
||||||
#endif
|
|
||||||
#include "s2.hpp"
|
|
||||||
namespace xsk::gsc::s2 { class lexer; }
|
|
||||||
}
|
|
||||||
|
|
||||||
%code top
|
|
||||||
{
|
|
||||||
#include "stdafx.hpp"
|
|
||||||
#include "parser.hpp"
|
|
||||||
#include "lexer.hpp"
|
|
||||||
using namespace xsk::gsc;
|
|
||||||
xsk::gsc::s2::parser::symbol_type S2lex(xsk::gsc::s2::lexer& lexer);
|
|
||||||
}
|
|
||||||
|
|
||||||
%token SH_DEFINE "#define"
|
|
||||||
%token SH_UNDEF "#undef"
|
|
||||||
%token SH_IFDEF "#ifdef"
|
|
||||||
%token SH_IFNDEF "#ifndef"
|
|
||||||
%token SH_IF "#if"
|
|
||||||
%token SH_ELIF "#elif"
|
|
||||||
%token SH_ELSE "#else"
|
|
||||||
%token SH_ENDIF "#endif"
|
|
||||||
%token DEVBEGIN "/#"
|
|
||||||
%token DEVEND "#/"
|
|
||||||
%token INLINE "#inline"
|
|
||||||
%token INCLUDE "#include"
|
|
||||||
%token USINGTREE "#using_animtree"
|
|
||||||
%token ANIMTREE "#animtree"
|
|
||||||
%token ENDON "endon"
|
|
||||||
%token NOTIFY "notify"
|
|
||||||
%token WAIT "wait"
|
|
||||||
%token WAITTILL "waittill"
|
|
||||||
%token WAITTILLMATCH "waittillmatch"
|
|
||||||
%token WAITTILLFRAMEEND "waittillframeend"
|
|
||||||
%token WAITFRAME "waitframe"
|
|
||||||
%token IF "if"
|
|
||||||
%token ELSE "else"
|
|
||||||
%token DO "do"
|
|
||||||
%token WHILE "while"
|
|
||||||
%token FOR "for"
|
|
||||||
%token FOREACH "foreach"
|
|
||||||
%token IN "in"
|
|
||||||
%token SWITCH "switch"
|
|
||||||
%token CASE "case"
|
|
||||||
%token DEFAULT "default"
|
|
||||||
%token BREAK "break"
|
|
||||||
%token CONTINUE "continue"
|
|
||||||
%token RETURN "return"
|
|
||||||
%token BREAKPOINT "breakpoint"
|
|
||||||
%token PROFBEGIN "prof_begin"
|
|
||||||
%token PROFEND "prof_end"
|
|
||||||
%token THREAD "thread"
|
|
||||||
%token CHILDTHREAD "childthread"
|
|
||||||
%token THISTHREAD "thisthread"
|
|
||||||
%token CALL "call"
|
|
||||||
%token TRUE "true"
|
|
||||||
%token FALSE "false"
|
|
||||||
%token UNDEFINED "undefined"
|
|
||||||
%token SIZE "size"
|
|
||||||
%token GAME "game"
|
|
||||||
%token SELF "self"
|
|
||||||
%token ANIM "anim"
|
|
||||||
%token LEVEL "level"
|
|
||||||
%token LPAREN "("
|
|
||||||
%token RPAREN ")"
|
|
||||||
%token LBRACE "{"
|
|
||||||
%token RBRACE "}"
|
|
||||||
%token LBRACKET "["
|
|
||||||
%token RBRACKET "]"
|
|
||||||
%token COMMA ","
|
|
||||||
%token DOT "."
|
|
||||||
%token DOUBLECOLON "::"
|
|
||||||
%token COLON ":"
|
|
||||||
%token SEMICOLON ";"
|
|
||||||
%token QMARK "?"
|
|
||||||
%token INCREMENT "++"
|
|
||||||
%token DECREMENT "--"
|
|
||||||
%token LSHIFT "<<"
|
|
||||||
%token RSHIFT ">>"
|
|
||||||
%token OR "||"
|
|
||||||
%token AND "&&"
|
|
||||||
%token EQUALITY "=="
|
|
||||||
%token INEQUALITY "!="
|
|
||||||
%token LESS_EQUAL "<="
|
|
||||||
%token GREATER_EQUAL ">="
|
|
||||||
%token LESS "<"
|
|
||||||
%token GREATER ">"
|
|
||||||
%token NOT "!"
|
|
||||||
%token COMPLEMENT "~"
|
|
||||||
%token ASSIGN "="
|
|
||||||
%token ASSIGN_ADD "+="
|
|
||||||
%token ASSIGN_SUB "-="
|
|
||||||
%token ASSIGN_MUL "*="
|
|
||||||
%token ASSIGN_DIV "/="
|
|
||||||
%token ASSIGN_MOD "%="
|
|
||||||
%token ASSIGN_BW_OR "|="
|
|
||||||
%token ASSIGN_BW_AND "&="
|
|
||||||
%token ASSIGN_BW_EXOR "^="
|
|
||||||
%token ASSIGN_RSHIFT ">>="
|
|
||||||
%token ASSIGN_LSHIFT "<<="
|
|
||||||
%token BITWISE_OR "|"
|
|
||||||
%token BITWISE_AND "&"
|
|
||||||
%token BITWISE_EXOR "^"
|
|
||||||
%token ADD "+"
|
|
||||||
%token SUB "-"
|
|
||||||
%token MUL "*"
|
|
||||||
%token DIV "/"
|
|
||||||
%token MOD "%"
|
|
||||||
%token <std::string> PATH "path"
|
|
||||||
%token <std::string> IDENTIFIER "identifier"
|
|
||||||
%token <std::string> STRING "string literal"
|
|
||||||
%token <std::string> ISTRING "localized string"
|
|
||||||
%token <std::string> FLOAT "float"
|
|
||||||
%token <std::string> INTEGER "integer"
|
|
||||||
|
|
||||||
%type <ast::program::ptr> program
|
|
||||||
%type <ast::include::ptr> include
|
|
||||||
%type <ast::decl> declaration
|
|
||||||
%type <ast::decl_usingtree::ptr> decl_usingtree
|
|
||||||
%type <ast::decl_constant::ptr> decl_constant
|
|
||||||
%type <ast::decl_thread::ptr> decl_thread
|
|
||||||
%type <ast::stmt> stmt
|
|
||||||
%type <ast::stmt> stmt_or_dev
|
|
||||||
%type <ast::stmt_list::ptr> stmt_list
|
|
||||||
%type <ast::stmt_list::ptr> stmt_or_dev_list
|
|
||||||
%type <ast::stmt_dev::ptr> stmt_dev
|
|
||||||
%type <ast::stmt_list::ptr> stmt_block
|
|
||||||
%type <ast::stmt_expr::ptr> stmt_expr
|
|
||||||
%type <ast::stmt_call::ptr> stmt_call
|
|
||||||
%type <ast::stmt_assign::ptr> stmt_assign
|
|
||||||
%type <ast::stmt_endon::ptr> stmt_endon
|
|
||||||
%type <ast::stmt_notify::ptr> stmt_notify
|
|
||||||
%type <ast::stmt_wait::ptr> stmt_wait
|
|
||||||
%type <ast::stmt_waittill::ptr> stmt_waittill
|
|
||||||
%type <ast::stmt_waittillmatch::ptr> stmt_waittillmatch
|
|
||||||
%type <ast::stmt_waittillframeend::ptr> stmt_waittillframeend
|
|
||||||
%type <ast::stmt_waitframe::ptr> stmt_waitframe
|
|
||||||
%type <ast::stmt_if::ptr> stmt_if
|
|
||||||
%type <ast::stmt_ifelse::ptr> stmt_ifelse
|
|
||||||
%type <ast::stmt_while::ptr> stmt_while
|
|
||||||
%type <ast::stmt_dowhile::ptr> stmt_dowhile
|
|
||||||
%type <ast::stmt_for::ptr> stmt_for
|
|
||||||
%type <ast::stmt_foreach::ptr> stmt_foreach
|
|
||||||
%type <ast::stmt_switch::ptr> stmt_switch
|
|
||||||
%type <ast::stmt_case::ptr> stmt_case
|
|
||||||
%type <ast::stmt_default::ptr> stmt_default
|
|
||||||
%type <ast::stmt_break::ptr> stmt_break
|
|
||||||
%type <ast::stmt_continue::ptr> stmt_continue
|
|
||||||
%type <ast::stmt_return::ptr> stmt_return
|
|
||||||
%type <ast::stmt_breakpoint::ptr> stmt_breakpoint
|
|
||||||
%type <ast::stmt_prof_begin::ptr> stmt_prof_begin
|
|
||||||
%type <ast::stmt_prof_end::ptr> stmt_prof_end
|
|
||||||
%type <ast::expr> expr
|
|
||||||
%type <ast::expr> expr_or_empty
|
|
||||||
%type <ast::expr> expr_assign
|
|
||||||
%type <ast::expr> expr_increment
|
|
||||||
%type <ast::expr> expr_decrement
|
|
||||||
%type <ast::expr> expr_ternary
|
|
||||||
%type <ast::expr> expr_binary
|
|
||||||
%type <ast::expr> expr_primitive
|
|
||||||
%type <ast::expr_complement::ptr> expr_complement
|
|
||||||
%type <ast::expr_negate::ptr> expr_negate
|
|
||||||
%type <ast::expr_not::ptr> expr_not
|
|
||||||
%type <ast::expr_call::ptr> expr_call
|
|
||||||
%type <ast::expr_method::ptr> expr_method
|
|
||||||
%type <ast::call> expr_function
|
|
||||||
%type <ast::call> expr_pointer
|
|
||||||
%type <ast::expr_add_array::ptr> expr_add_array
|
|
||||||
%type <ast::expr_parameters::ptr> expr_parameters
|
|
||||||
%type <ast::expr_arguments::ptr> expr_arguments
|
|
||||||
%type <ast::expr_arguments::ptr> expr_arguments_no_empty
|
|
||||||
%type <ast::expr_reference::ptr> expr_reference
|
|
||||||
%type <ast::expr_array::ptr> expr_array
|
|
||||||
%type <ast::expr_field::ptr> expr_field
|
|
||||||
%type <ast::expr_size::ptr> expr_size
|
|
||||||
%type <ast::expr_paren::ptr> expr_paren
|
|
||||||
%type <ast::expr> expr_object
|
|
||||||
%type <ast::expr_thisthread::ptr> expr_thisthread
|
|
||||||
%type <ast::expr_empty_array::ptr> expr_empty_array
|
|
||||||
%type <ast::expr_undefined::ptr> expr_undefined
|
|
||||||
%type <ast::expr_game::ptr> expr_game
|
|
||||||
%type <ast::expr_self::ptr> expr_self
|
|
||||||
%type <ast::expr_anim::ptr> expr_anim
|
|
||||||
%type <ast::expr_level::ptr> expr_level
|
|
||||||
%type <ast::expr_animation::ptr> expr_animation
|
|
||||||
%type <ast::expr_animtree::ptr> expr_animtree
|
|
||||||
%type <ast::expr_identifier::ptr> expr_identifier_nosize
|
|
||||||
%type <ast::expr_identifier::ptr> expr_identifier
|
|
||||||
%type <ast::expr_path::ptr> expr_path
|
|
||||||
%type <ast::expr_istring::ptr> expr_istring
|
|
||||||
%type <ast::expr_string::ptr> expr_string
|
|
||||||
%type <ast::expr_vector::ptr> expr_vector
|
|
||||||
%type <ast::expr_float::ptr> expr_float
|
|
||||||
%type <ast::expr_integer::ptr> expr_integer
|
|
||||||
%type <ast::expr_false::ptr> expr_false
|
|
||||||
%type <ast::expr_true::ptr> expr_true
|
|
||||||
|
|
||||||
%nonassoc SIZEOF
|
|
||||||
%nonassoc ADD_ARRAY
|
|
||||||
%nonassoc RBRACKET
|
|
||||||
%nonassoc THEN
|
|
||||||
%nonassoc ELSE
|
|
||||||
%nonassoc INCREMENT DECREMENT
|
|
||||||
|
|
||||||
%precedence TERN
|
|
||||||
%right QMARK
|
|
||||||
%left OR
|
|
||||||
%left AND
|
|
||||||
%left BITWISE_OR
|
|
||||||
%left BITWISE_EXOR
|
|
||||||
%left BITWISE_AND
|
|
||||||
%left EQUALITY INEQUALITY
|
|
||||||
%left LESS GREATER LESS_EQUAL GREATER_EQUAL
|
|
||||||
%left LSHIFT RSHIFT
|
|
||||||
%left ADD SUB
|
|
||||||
%left MUL DIV MOD
|
|
||||||
%right NOT COMPLEMENT
|
|
||||||
|
|
||||||
%precedence NEG
|
|
||||||
%precedence ANIMREF
|
|
||||||
%precedence PREINC PREDEC
|
|
||||||
%precedence POSTINC POSTDEC
|
|
||||||
|
|
||||||
%start root
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
root
|
|
||||||
: program { ast = std::move($1); }
|
|
||||||
| { ast = std::make_unique<ast::program>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
program
|
|
||||||
: program inline
|
|
||||||
{ $$ = std::move($1); }
|
|
||||||
| program include
|
|
||||||
{ $$ = std::move($1); $$->includes.push_back(std::move($2)); }
|
|
||||||
| program declaration
|
|
||||||
{ $$ = std::move($1); $$->declarations.push_back(std::move($2)); }
|
|
||||||
| inline
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); }
|
|
||||||
| include
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); $$->includes.push_back(std::move($1)); }
|
|
||||||
| declaration
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); $$->declarations.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
inline
|
|
||||||
: INLINE expr_path SEMICOLON { lexer.push_header($2->value); }
|
|
||||||
;
|
|
||||||
|
|
||||||
include
|
|
||||||
: INCLUDE expr_path SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::include>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
declaration
|
|
||||||
: DEVBEGIN { $$.as_dev_begin = std::make_unique<ast::decl_dev_begin>(@$); }
|
|
||||||
| DEVEND { $$.as_dev_end = std::make_unique<ast::decl_dev_end>(@$); }
|
|
||||||
| decl_usingtree { $$.as_usingtree = std::move($1); }
|
|
||||||
| decl_constant { $$.as_constant = std::move($1); }
|
|
||||||
| decl_thread { $$.as_thread = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_usingtree
|
|
||||||
: USINGTREE LPAREN expr_string RPAREN SEMICOLON
|
|
||||||
{ lexer.ban_header(@$); $$ = std::make_unique<ast::decl_usingtree>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_constant
|
|
||||||
: expr_identifier ASSIGN expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::decl_constant>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_thread
|
|
||||||
: expr_identifier LPAREN expr_parameters RPAREN stmt_block
|
|
||||||
{ lexer.ban_header(@$); $$ = std::make_unique<ast::decl_thread>(@$, std::move($1), std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt
|
|
||||||
: stmt_block { $$.as_list = std::move($1); }
|
|
||||||
| stmt_call { $$.as_call = std::move($1); }
|
|
||||||
| stmt_assign { $$.as_assign = std::move($1); }
|
|
||||||
| stmt_endon { $$.as_endon = std::move($1); }
|
|
||||||
| stmt_notify { $$.as_notify = std::move($1); }
|
|
||||||
| stmt_wait { $$.as_wait = std::move($1); }
|
|
||||||
| stmt_waittill { $$.as_waittill = std::move($1); }
|
|
||||||
| stmt_waittillmatch { $$.as_waittillmatch = std::move($1); }
|
|
||||||
| stmt_waittillframeend { $$.as_waittillframeend = std::move($1); }
|
|
||||||
| stmt_waitframe { $$.as_waitframe = std::move($1); }
|
|
||||||
| stmt_if { $$.as_if = std::move($1); }
|
|
||||||
| stmt_ifelse { $$.as_ifelse = std::move($1); }
|
|
||||||
| stmt_while { $$.as_while = std::move($1); }
|
|
||||||
| stmt_dowhile { $$.as_dowhile = std::move($1); }
|
|
||||||
| stmt_for { $$.as_for = std::move($1); }
|
|
||||||
| stmt_foreach { $$.as_foreach = std::move($1); }
|
|
||||||
| stmt_switch { $$.as_switch = std::move($1); }
|
|
||||||
| stmt_case { $$.as_case = std::move($1); }
|
|
||||||
| stmt_default { $$.as_default = std::move($1); }
|
|
||||||
| stmt_break { $$.as_break = std::move($1); }
|
|
||||||
| stmt_continue { $$.as_continue = std::move($1); }
|
|
||||||
| stmt_return { $$.as_return = std::move($1); }
|
|
||||||
| stmt_breakpoint { $$.as_breakpoint = std::move($1); }
|
|
||||||
| stmt_prof_begin { $$.as_prof_begin = std::move($1); }
|
|
||||||
| stmt_prof_end { $$.as_prof_end = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_or_dev
|
|
||||||
: stmt { $$ = std::move($1); }
|
|
||||||
| stmt_dev { $$.as_dev = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_list
|
|
||||||
: stmt_list stmt
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($2)); }
|
|
||||||
| stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_list>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_or_dev_list
|
|
||||||
: stmt_or_dev_list stmt_or_dev
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($2)); }
|
|
||||||
| stmt_or_dev
|
|
||||||
{ $$ = std::make_unique<ast::stmt_list>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_dev
|
|
||||||
: DEVBEGIN stmt_list DEVEND { $$ = std::make_unique<ast::stmt_dev>(@$, std::move($2)); }
|
|
||||||
| DEVBEGIN DEVEND { $$ = std::make_unique<ast::stmt_dev>(@$, std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_block
|
|
||||||
: LBRACE stmt_or_dev_list RBRACE { $$ = std::move($2); }
|
|
||||||
| LBRACE RBRACE { $$ = std::make_unique<ast::stmt_list>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_expr
|
|
||||||
: expr_assign
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
| expr_increment
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
| expr_decrement
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::make_unique<ast::node>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_call
|
|
||||||
: expr_call SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_call>(@$, ast::expr(std::move($1))); }
|
|
||||||
| expr_method SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_call>(@$, ast::expr(std::move($1))); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_assign
|
|
||||||
: expr_assign SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
| expr_increment SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
| expr_decrement SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_endon
|
|
||||||
: expr_object ENDON LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_endon>(@$, std::move($1), std::move($4)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_notify
|
|
||||||
: expr_object NOTIFY LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_notify>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object NOTIFY LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_notify>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_wait
|
|
||||||
: WAIT expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_wait>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittill
|
|
||||||
: expr_object WAITTILL LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittill>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object WAITTILL LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittill>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittillmatch
|
|
||||||
: expr_object WAITTILLMATCH LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillmatch>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object WAITTILLMATCH LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillmatch>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittillframeend
|
|
||||||
: WAITTILLFRAMEEND SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillframeend>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waitframe
|
|
||||||
: WAITFRAME SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waitframe>(@$); }
|
|
||||||
| WAITFRAME LPAREN RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waitframe>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_if
|
|
||||||
: IF LPAREN expr RPAREN stmt %prec THEN
|
|
||||||
{ $$ = std::make_unique<ast::stmt_if>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_ifelse
|
|
||||||
: IF LPAREN expr RPAREN stmt ELSE stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_ifelse>(@$, std::move($3), std::move($5), std::move($7)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_while
|
|
||||||
: WHILE LPAREN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_while>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_dowhile
|
|
||||||
: DO stmt WHILE LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_dowhile>(@$, std::move($5), std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_for
|
|
||||||
: FOR LPAREN stmt_expr SEMICOLON expr_or_empty SEMICOLON stmt_expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_for>(@$, ast::stmt(std::move($3)), std::move($5), ast::stmt(std::move($7)), std::move($9)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_foreach
|
|
||||||
: FOREACH LPAREN expr_identifier IN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_foreach>(@$, ast::expr(std::move($3)), std::move($5), std::move($7)); }
|
|
||||||
| FOREACH LPAREN expr_identifier COMMA expr_identifier IN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_foreach>(@$, ast::expr(std::move($3)), ast::expr(std::move($5)), std::move($7), std::move($9)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_switch
|
|
||||||
: SWITCH LPAREN expr RPAREN stmt_block
|
|
||||||
{ $$ = std::make_unique<ast::stmt_switch>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_case
|
|
||||||
: CASE expr_integer COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_case>(@$, ast::expr(std::move($2)), std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
| CASE expr_string COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_case>(@$, ast::expr(std::move($2)), std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_default
|
|
||||||
: DEFAULT COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_default>(@$, std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_break
|
|
||||||
: BREAK SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_break>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_continue
|
|
||||||
: CONTINUE SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_continue>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_return
|
|
||||||
: RETURN expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_return>(@$, std::move($2)); }
|
|
||||||
| RETURN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_return>(@$, std::make_unique<ast::node>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_breakpoint
|
|
||||||
: BREAKPOINT SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_breakpoint>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_prof_begin
|
|
||||||
: PROFBEGIN LPAREN expr_arguments RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_prof_begin>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_prof_end
|
|
||||||
: PROFEND LPAREN expr_arguments RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_prof_end>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr
|
|
||||||
: expr_ternary { $$ = std::move($1); }
|
|
||||||
| expr_binary { $$ = std::move($1); }
|
|
||||||
| expr_primitive { $$ = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_or_empty
|
|
||||||
: expr { $$ = std::move($1); }
|
|
||||||
| { $$.as_node = std::make_unique<ast::node>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_assign
|
|
||||||
: expr_object ASSIGN expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_EXOR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_exor>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_LSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_shift_left>(@$, std::move($1),std::move( $3)); }
|
|
||||||
| expr_object ASSIGN_RSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_shift_right>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_ADD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_add>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_SUB expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_sub>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_MUL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_mul>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_DIV expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_div>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_MOD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_mod>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_increment
|
|
||||||
: INCREMENT expr_object %prec PREINC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_increment>(@$, std::move($2), true); }
|
|
||||||
| expr_object INCREMENT %prec POSTINC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_increment>(@$, std::move($1), false); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_decrement
|
|
||||||
: DECREMENT expr_object %prec PREDEC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_decrement>(@$, std::move($2), true); }
|
|
||||||
| expr_object DECREMENT %prec POSTDEC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_decrement>(@$, std::move($1), false); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_ternary
|
|
||||||
: expr QMARK expr COLON expr %prec TERN
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_ternary>(@$, std::move($1), std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_binary
|
|
||||||
: expr OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr EQUALITY expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_equality>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr INEQUALITY expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_inequality>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LESS_EQUAL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_less_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr GREATER_EQUAL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_greater_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LESS expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_less>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr GREATER expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_greater>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_EXOR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_exor>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_shift_left>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr RSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_shift_right>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr ADD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_add>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr SUB expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_sub>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr MUL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_mul>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr DIV expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_div>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr MOD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_mod>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_primitive
|
|
||||||
: expr_complement { $$.as_node = std::move($1); }
|
|
||||||
| expr_negate { $$.as_node = std::move($1); }
|
|
||||||
| expr_not { $$.as_node = std::move($1); }
|
|
||||||
| expr_call { $$.as_node = std::move($1); }
|
|
||||||
| expr_method { $$.as_node = std::move($1); }
|
|
||||||
| expr_add_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_reference { $$.as_node = std::move($1); }
|
|
||||||
| expr_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_field { $$.as_node = std::move($1); }
|
|
||||||
| expr_size { $$.as_node = std::move($1); }
|
|
||||||
| expr_paren { $$.as_node = std::move($1); }
|
|
||||||
| expr_thisthread { $$.as_node = std::move($1); }
|
|
||||||
| expr_empty_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_undefined { $$.as_node = std::move($1); }
|
|
||||||
| expr_game { $$.as_node = std::move($1); }
|
|
||||||
| expr_self { $$.as_node = std::move($1); }
|
|
||||||
| expr_anim { $$.as_node = std::move($1); }
|
|
||||||
| expr_level { $$.as_node = std::move($1); }
|
|
||||||
| expr_animation { $$.as_node = std::move($1); }
|
|
||||||
| expr_animtree { $$.as_node = std::move($1); }
|
|
||||||
| expr_identifier { $$.as_node = std::move($1); }
|
|
||||||
| expr_istring { $$.as_node = std::move($1); }
|
|
||||||
| expr_string { $$.as_node = std::move($1); }
|
|
||||||
| expr_vector { $$.as_node = std::move($1); }
|
|
||||||
| expr_float { $$.as_node = std::move($1); }
|
|
||||||
| expr_integer { $$.as_node = std::move($1); }
|
|
||||||
| expr_false { $$.as_node = std::move($1); }
|
|
||||||
| expr_true { $$.as_node = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_complement
|
|
||||||
: COMPLEMENT expr
|
|
||||||
{ $$ = std::make_unique<ast::expr_complement>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_negate
|
|
||||||
: SUB expr_identifier %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_paren %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_array %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_field %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_not
|
|
||||||
: NOT expr
|
|
||||||
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_call
|
|
||||||
: expr_function { $$ = std::make_unique<ast::expr_call>(@$, std::move($1)); }
|
|
||||||
| expr_pointer { $$ = std::make_unique<ast::expr_call>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
expr_method
|
|
||||||
: expr_object expr_function { $$ = std::make_unique<ast::expr_method>(@$, std::move($1), std::move($2)); }
|
|
||||||
| expr_object expr_pointer { $$ = std::make_unique<ast::expr_method>(@$, std::move($1), std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_function
|
|
||||||
: expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($1), std::move($3), ast::call::mode::normal); }
|
|
||||||
| expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($1), std::move($3), std::move($5), ast::call::mode::normal); }
|
|
||||||
| THREAD expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($2), std::move($4), ast::call::mode::thread); }
|
|
||||||
| THREAD expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($2), std::move($4), std::move($6), ast::call::mode::thread); }
|
|
||||||
| CHILDTHREAD expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($2), std::move($4), ast::call::mode::childthread); }
|
|
||||||
| CHILDTHREAD expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($2), std::move($4), std::move($6), ast::call::mode::childthread); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_pointer
|
|
||||||
: LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($3), std::move($7), ast::call::mode::normal); }
|
|
||||||
| THREAD LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::thread); }
|
|
||||||
| CHILDTHREAD LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::childthread); }
|
|
||||||
| CALL LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::builtin); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_add_array
|
|
||||||
: LBRACKET expr_arguments_no_empty RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_add_array>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_parameters
|
|
||||||
: expr_parameters COMMA expr_identifier
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($3)); }
|
|
||||||
| expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_parameters>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::expr_parameters>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_arguments
|
|
||||||
: expr_arguments_no_empty
|
|
||||||
{ $$ = std::move($1); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::expr_arguments>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_arguments_no_empty
|
|
||||||
: expr_arguments COMMA expr
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($3)); }
|
|
||||||
| expr %prec ADD_ARRAY
|
|
||||||
{ $$ = std::make_unique<ast::expr_arguments>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_reference
|
|
||||||
: DOUBLECOLON expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_reference>(@$, std::make_unique<ast::expr_path>(@$), std::move($2)); }
|
|
||||||
| expr_path DOUBLECOLON expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_reference>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_array
|
|
||||||
: expr_object LBRACKET expr RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_array>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_field
|
|
||||||
: expr_object DOT expr_identifier_nosize
|
|
||||||
{ $$ = std::make_unique<ast::expr_field>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_size
|
|
||||||
: expr_object DOT SIZE %prec SIZEOF
|
|
||||||
{ $$ = std::make_unique<ast::expr_size>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_paren
|
|
||||||
: LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_paren>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_object
|
|
||||||
: expr_call { $$.as_node = std::move($1); }
|
|
||||||
| expr_method { $$.as_node = std::move($1); }
|
|
||||||
| expr_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_field { $$.as_node = std::move($1); }
|
|
||||||
| expr_game { $$.as_node = std::move($1); }
|
|
||||||
| expr_self { $$.as_node = std::move($1); }
|
|
||||||
| expr_anim { $$.as_node = std::move($1); }
|
|
||||||
| expr_level { $$.as_node = std::move($1); }
|
|
||||||
| expr_identifier { $$.as_node = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_thisthread
|
|
||||||
: THISTHREAD
|
|
||||||
{ $$ = std::make_unique<ast::expr_thisthread>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_empty_array
|
|
||||||
: LBRACKET RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_empty_array>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_undefined
|
|
||||||
: UNDEFINED
|
|
||||||
{ $$ = std::make_unique<ast::expr_undefined>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_game
|
|
||||||
: GAME
|
|
||||||
{ $$ = std::make_unique<ast::expr_game>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_self
|
|
||||||
: SELF
|
|
||||||
{ $$ = std::make_unique<ast::expr_self>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_anim
|
|
||||||
: ANIM
|
|
||||||
{ $$ = std::make_unique<ast::expr_anim>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_level
|
|
||||||
: LEVEL
|
|
||||||
{ $$ = std::make_unique<ast::expr_level>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_animation
|
|
||||||
: MOD IDENTIFIER %prec ANIMREF
|
|
||||||
{ $$ = std::make_unique<ast::expr_animation>(@$, $2); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_animtree
|
|
||||||
: ANIMTREE
|
|
||||||
{ $$ = std::make_unique<ast::expr_animtree>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_identifier_nosize
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_identifier
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, $1); };
|
|
||||||
| SIZE
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, "size"); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_path
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_path>(@$, $1); };
|
|
||||||
| PATH
|
|
||||||
{ $$ = std::make_unique<ast::expr_path>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_istring
|
|
||||||
: ISTRING
|
|
||||||
{ $$ = std::make_unique<ast::expr_istring>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_string
|
|
||||||
: STRING
|
|
||||||
{ $$ = std::make_unique<ast::expr_string>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_vector
|
|
||||||
: LPAREN expr COMMA expr COMMA expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_vector>(@$, std::move($2), std::move($4), std::move($6)); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_float
|
|
||||||
: SUB FLOAT %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_float>(@$, "-" + $2); };
|
|
||||||
| FLOAT
|
|
||||||
{ $$ = std::make_unique<ast::expr_float>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_integer
|
|
||||||
: SUB INTEGER %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_integer>(@$, "-" + $2); };
|
|
||||||
| INTEGER
|
|
||||||
{ $$ = std::make_unique<ast::expr_integer>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_false
|
|
||||||
: FALSE
|
|
||||||
{ $$ = std::make_unique<ast::expr_false>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_true
|
|
||||||
: TRUE
|
|
||||||
{ $$ = std::make_unique<ast::expr_true>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
void xsk::gsc::s2::parser::error(const xsk::gsc::location& loc, const std::string& msg)
|
|
||||||
{
|
|
||||||
throw xsk::gsc::comp_error(loc, msg);
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
generate: S4
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf ./parser.hpp
|
|
||||||
rm -rf ./parser.cpp
|
|
||||||
|
|
||||||
S4: parser.ypp
|
|
||||||
bison parser.ypp -Wcounterexamples
|
|
||||||
mv parser.hpp parser.cpp ../../src/s4/xsk/
|
|
@ -1,891 +0,0 @@
|
|||||||
/* Copyright 2022 xensik. All rights reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a GNU GPLv3 license
|
|
||||||
// that can be found in the LICENSE file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
%require "3.7"
|
|
||||||
%skeleton "lalr1.cc"
|
|
||||||
%language "c++"
|
|
||||||
%output "parser.cpp"
|
|
||||||
%defines "parser.hpp"
|
|
||||||
%define api.prefix {S4}
|
|
||||||
%define api.namespace {xsk::gsc::s4}
|
|
||||||
%define api.location.type {xsk::gsc::location}
|
|
||||||
%define api.value.type variant
|
|
||||||
%define api.token.constructor
|
|
||||||
%define api.token.raw
|
|
||||||
%define parse.assert
|
|
||||||
%define parse.trace
|
|
||||||
%define parse.error detailed
|
|
||||||
%define parse.lac full
|
|
||||||
%locations
|
|
||||||
%lex-param { xsk::gsc::s4::lexer& lexer }
|
|
||||||
%parse-param { xsk::gsc::s4::lexer& lexer }
|
|
||||||
%parse-param { xsk::gsc::ast::program::ptr& ast }
|
|
||||||
|
|
||||||
%code requires
|
|
||||||
{
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(disable:4065)
|
|
||||||
#pragma warning(disable:4127)
|
|
||||||
#endif
|
|
||||||
#include "s4.hpp"
|
|
||||||
namespace xsk::gsc::s4 { class lexer; }
|
|
||||||
}
|
|
||||||
|
|
||||||
%code top
|
|
||||||
{
|
|
||||||
#include "stdafx.hpp"
|
|
||||||
#include "parser.hpp"
|
|
||||||
#include "lexer.hpp"
|
|
||||||
using namespace xsk::gsc;
|
|
||||||
xsk::gsc::s4::parser::symbol_type S4lex(xsk::gsc::s4::lexer& lexer);
|
|
||||||
}
|
|
||||||
|
|
||||||
%token SH_DEFINE "#define"
|
|
||||||
%token SH_UNDEF "#undef"
|
|
||||||
%token SH_IFDEF "#ifdef"
|
|
||||||
%token SH_IFNDEF "#ifndef"
|
|
||||||
%token SH_IF "#if"
|
|
||||||
%token SH_ELIF "#elif"
|
|
||||||
%token SH_ELSE "#else"
|
|
||||||
%token SH_ENDIF "#endif"
|
|
||||||
%token DEVBEGIN "/#"
|
|
||||||
%token DEVEND "#/"
|
|
||||||
%token INLINE "#inline"
|
|
||||||
%token INCLUDE "#include"
|
|
||||||
%token USINGTREE "#using_animtree"
|
|
||||||
%token ANIMTREE "#animtree"
|
|
||||||
%token ENDON "endon"
|
|
||||||
%token NOTIFY "notify"
|
|
||||||
%token WAIT "wait"
|
|
||||||
%token WAITTILL "waittill"
|
|
||||||
%token WAITTILLMATCH "waittillmatch"
|
|
||||||
%token WAITTILLFRAMEEND "waittillframeend"
|
|
||||||
%token WAITFRAME "waitframe"
|
|
||||||
%token IF "if"
|
|
||||||
%token ELSE "else"
|
|
||||||
%token DO "do"
|
|
||||||
%token WHILE "while"
|
|
||||||
%token FOR "for"
|
|
||||||
%token FOREACH "foreach"
|
|
||||||
%token IN "in"
|
|
||||||
%token SWITCH "switch"
|
|
||||||
%token CASE "case"
|
|
||||||
%token DEFAULT "default"
|
|
||||||
%token BREAK "break"
|
|
||||||
%token CONTINUE "continue"
|
|
||||||
%token RETURN "return"
|
|
||||||
%token BREAKPOINT "breakpoint"
|
|
||||||
%token PROFBEGIN "prof_begin"
|
|
||||||
%token PROFEND "prof_end"
|
|
||||||
%token THREAD "thread"
|
|
||||||
%token CHILDTHREAD "childthread"
|
|
||||||
%token THISTHREAD "thisthread"
|
|
||||||
%token CALL "call"
|
|
||||||
%token TRUE "true"
|
|
||||||
%token FALSE "false"
|
|
||||||
%token UNDEFINED "undefined"
|
|
||||||
%token SIZE "size"
|
|
||||||
%token GAME "game"
|
|
||||||
%token SELF "self"
|
|
||||||
%token ANIM "anim"
|
|
||||||
%token LEVEL "level"
|
|
||||||
%token ISDEFINED "isdefined"
|
|
||||||
%token ISTRUE "istrue"
|
|
||||||
%token LPAREN "("
|
|
||||||
%token RPAREN ")"
|
|
||||||
%token LBRACE "{"
|
|
||||||
%token RBRACE "}"
|
|
||||||
%token LBRACKET "["
|
|
||||||
%token RBRACKET "]"
|
|
||||||
%token COMMA ","
|
|
||||||
%token DOT "."
|
|
||||||
%token DOUBLECOLON "::"
|
|
||||||
%token COLON ":"
|
|
||||||
%token SEMICOLON ";"
|
|
||||||
%token QMARK "?"
|
|
||||||
%token INCREMENT "++"
|
|
||||||
%token DECREMENT "--"
|
|
||||||
%token LSHIFT "<<"
|
|
||||||
%token RSHIFT ">>"
|
|
||||||
%token OR "||"
|
|
||||||
%token AND "&&"
|
|
||||||
%token EQUALITY "=="
|
|
||||||
%token INEQUALITY "!="
|
|
||||||
%token LESS_EQUAL "<="
|
|
||||||
%token GREATER_EQUAL ">="
|
|
||||||
%token LESS "<"
|
|
||||||
%token GREATER ">"
|
|
||||||
%token NOT "!"
|
|
||||||
%token COMPLEMENT "~"
|
|
||||||
%token ASSIGN "="
|
|
||||||
%token ASSIGN_ADD "+="
|
|
||||||
%token ASSIGN_SUB "-="
|
|
||||||
%token ASSIGN_MUL "*="
|
|
||||||
%token ASSIGN_DIV "/="
|
|
||||||
%token ASSIGN_MOD "%="
|
|
||||||
%token ASSIGN_BW_OR "|="
|
|
||||||
%token ASSIGN_BW_AND "&="
|
|
||||||
%token ASSIGN_BW_EXOR "^="
|
|
||||||
%token ASSIGN_RSHIFT ">>="
|
|
||||||
%token ASSIGN_LSHIFT "<<="
|
|
||||||
%token BITWISE_OR "|"
|
|
||||||
%token BITWISE_AND "&"
|
|
||||||
%token BITWISE_EXOR "^"
|
|
||||||
%token ADD "+"
|
|
||||||
%token SUB "-"
|
|
||||||
%token MUL "*"
|
|
||||||
%token DIV "/"
|
|
||||||
%token MOD "%"
|
|
||||||
%token <std::string> PATH "path"
|
|
||||||
%token <std::string> IDENTIFIER "identifier"
|
|
||||||
%token <std::string> STRING "string literal"
|
|
||||||
%token <std::string> ISTRING "localized string"
|
|
||||||
%token <std::string> FLOAT "float"
|
|
||||||
%token <std::string> INTEGER "integer"
|
|
||||||
|
|
||||||
%type <ast::program::ptr> program
|
|
||||||
%type <ast::include::ptr> include
|
|
||||||
%type <ast::decl> declaration
|
|
||||||
%type <ast::decl_usingtree::ptr> decl_usingtree
|
|
||||||
%type <ast::decl_constant::ptr> decl_constant
|
|
||||||
%type <ast::decl_thread::ptr> decl_thread
|
|
||||||
%type <ast::stmt> stmt
|
|
||||||
%type <ast::stmt> stmt_or_dev
|
|
||||||
%type <ast::stmt_list::ptr> stmt_list
|
|
||||||
%type <ast::stmt_list::ptr> stmt_or_dev_list
|
|
||||||
%type <ast::stmt_dev::ptr> stmt_dev
|
|
||||||
%type <ast::stmt_list::ptr> stmt_block
|
|
||||||
%type <ast::stmt_expr::ptr> stmt_expr
|
|
||||||
%type <ast::stmt_call::ptr> stmt_call
|
|
||||||
%type <ast::stmt_assign::ptr> stmt_assign
|
|
||||||
%type <ast::stmt_endon::ptr> stmt_endon
|
|
||||||
%type <ast::stmt_notify::ptr> stmt_notify
|
|
||||||
%type <ast::stmt_wait::ptr> stmt_wait
|
|
||||||
%type <ast::stmt_waittill::ptr> stmt_waittill
|
|
||||||
%type <ast::stmt_waittillmatch::ptr> stmt_waittillmatch
|
|
||||||
%type <ast::stmt_waittillframeend::ptr> stmt_waittillframeend
|
|
||||||
%type <ast::stmt_waitframe::ptr> stmt_waitframe
|
|
||||||
%type <ast::stmt_if::ptr> stmt_if
|
|
||||||
%type <ast::stmt_ifelse::ptr> stmt_ifelse
|
|
||||||
%type <ast::stmt_while::ptr> stmt_while
|
|
||||||
%type <ast::stmt_dowhile::ptr> stmt_dowhile
|
|
||||||
%type <ast::stmt_for::ptr> stmt_for
|
|
||||||
%type <ast::stmt_foreach::ptr> stmt_foreach
|
|
||||||
%type <ast::stmt_switch::ptr> stmt_switch
|
|
||||||
%type <ast::stmt_case::ptr> stmt_case
|
|
||||||
%type <ast::stmt_default::ptr> stmt_default
|
|
||||||
%type <ast::stmt_break::ptr> stmt_break
|
|
||||||
%type <ast::stmt_continue::ptr> stmt_continue
|
|
||||||
%type <ast::stmt_return::ptr> stmt_return
|
|
||||||
%type <ast::stmt_breakpoint::ptr> stmt_breakpoint
|
|
||||||
%type <ast::stmt_prof_begin::ptr> stmt_prof_begin
|
|
||||||
%type <ast::stmt_prof_end::ptr> stmt_prof_end
|
|
||||||
%type <ast::expr> expr
|
|
||||||
%type <ast::expr> expr_or_empty
|
|
||||||
%type <ast::expr> expr_assign
|
|
||||||
%type <ast::expr> expr_increment
|
|
||||||
%type <ast::expr> expr_decrement
|
|
||||||
%type <ast::expr> expr_ternary
|
|
||||||
%type <ast::expr> expr_binary
|
|
||||||
%type <ast::expr> expr_primitive
|
|
||||||
%type <ast::expr_complement::ptr> expr_complement
|
|
||||||
%type <ast::expr_negate::ptr> expr_negate
|
|
||||||
%type <ast::expr_not::ptr> expr_not
|
|
||||||
%type <ast::expr_call::ptr> expr_call
|
|
||||||
%type <ast::expr_method::ptr> expr_method
|
|
||||||
%type <ast::call> expr_function
|
|
||||||
%type <ast::call> expr_pointer
|
|
||||||
%type <ast::expr_add_array::ptr> expr_add_array
|
|
||||||
%type <ast::expr_parameters::ptr> expr_parameters
|
|
||||||
%type <ast::expr_arguments::ptr> expr_arguments
|
|
||||||
%type <ast::expr_arguments::ptr> expr_arguments_no_empty
|
|
||||||
%type <ast::expr_isdefined::ptr> expr_isdefined
|
|
||||||
%type <ast::expr_istrue::ptr> expr_istrue
|
|
||||||
%type <ast::expr_reference::ptr> expr_reference
|
|
||||||
%type <ast::expr_array::ptr> expr_array
|
|
||||||
%type <ast::expr_field::ptr> expr_field
|
|
||||||
%type <ast::expr_size::ptr> expr_size
|
|
||||||
%type <ast::expr_paren::ptr> expr_paren
|
|
||||||
%type <ast::expr> expr_object
|
|
||||||
%type <ast::expr_thisthread::ptr> expr_thisthread
|
|
||||||
%type <ast::expr_empty_array::ptr> expr_empty_array
|
|
||||||
%type <ast::expr_undefined::ptr> expr_undefined
|
|
||||||
%type <ast::expr_game::ptr> expr_game
|
|
||||||
%type <ast::expr_self::ptr> expr_self
|
|
||||||
%type <ast::expr_anim::ptr> expr_anim
|
|
||||||
%type <ast::expr_level::ptr> expr_level
|
|
||||||
%type <ast::expr_animation::ptr> expr_animation
|
|
||||||
%type <ast::expr_animtree::ptr> expr_animtree
|
|
||||||
%type <ast::expr_identifier::ptr> expr_identifier_nosize
|
|
||||||
%type <ast::expr_identifier::ptr> expr_identifier
|
|
||||||
%type <ast::expr_path::ptr> expr_path
|
|
||||||
%type <ast::expr_istring::ptr> expr_istring
|
|
||||||
%type <ast::expr_string::ptr> expr_string
|
|
||||||
%type <ast::expr_vector::ptr> expr_vector
|
|
||||||
%type <ast::expr_float::ptr> expr_float
|
|
||||||
%type <ast::expr_integer::ptr> expr_integer
|
|
||||||
%type <ast::expr_false::ptr> expr_false
|
|
||||||
%type <ast::expr_true::ptr> expr_true
|
|
||||||
|
|
||||||
%nonassoc SIZEOF
|
|
||||||
%nonassoc ADD_ARRAY
|
|
||||||
%nonassoc RBRACKET
|
|
||||||
%nonassoc THEN
|
|
||||||
%nonassoc ELSE
|
|
||||||
%nonassoc INCREMENT DECREMENT
|
|
||||||
|
|
||||||
%precedence TERN
|
|
||||||
%right QMARK
|
|
||||||
%left OR
|
|
||||||
%left AND
|
|
||||||
%left BITWISE_OR
|
|
||||||
%left BITWISE_EXOR
|
|
||||||
%left BITWISE_AND
|
|
||||||
%left EQUALITY INEQUALITY
|
|
||||||
%left LESS GREATER LESS_EQUAL GREATER_EQUAL
|
|
||||||
%left LSHIFT RSHIFT
|
|
||||||
%left ADD SUB
|
|
||||||
%left MUL DIV MOD
|
|
||||||
%right NOT COMPLEMENT
|
|
||||||
|
|
||||||
%precedence NEG
|
|
||||||
%precedence ANIMREF
|
|
||||||
%precedence PREINC PREDEC
|
|
||||||
%precedence POSTINC POSTDEC
|
|
||||||
|
|
||||||
%start root
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
root
|
|
||||||
: program { ast = std::move($1); }
|
|
||||||
| { ast = std::make_unique<ast::program>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
program
|
|
||||||
: program inline
|
|
||||||
{ $$ = std::move($1); }
|
|
||||||
| program include
|
|
||||||
{ $$ = std::move($1); $$->includes.push_back(std::move($2)); }
|
|
||||||
| program declaration
|
|
||||||
{ $$ = std::move($1); $$->declarations.push_back(std::move($2)); }
|
|
||||||
| inline
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); }
|
|
||||||
| include
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); $$->includes.push_back(std::move($1)); }
|
|
||||||
| declaration
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); $$->declarations.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
inline
|
|
||||||
: INLINE expr_path SEMICOLON { lexer.push_header($2->value); }
|
|
||||||
;
|
|
||||||
|
|
||||||
include
|
|
||||||
: INCLUDE expr_path SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::include>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
declaration
|
|
||||||
: DEVBEGIN { $$.as_dev_begin = std::make_unique<ast::decl_dev_begin>(@$); }
|
|
||||||
| DEVEND { $$.as_dev_end = std::make_unique<ast::decl_dev_end>(@$); }
|
|
||||||
| decl_usingtree { $$.as_usingtree = std::move($1); }
|
|
||||||
| decl_constant { $$.as_constant = std::move($1); }
|
|
||||||
| decl_thread { $$.as_thread = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_usingtree
|
|
||||||
: USINGTREE LPAREN expr_string RPAREN SEMICOLON
|
|
||||||
{ lexer.ban_header(@$); $$ = std::make_unique<ast::decl_usingtree>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_constant
|
|
||||||
: expr_identifier ASSIGN expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::decl_constant>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_thread
|
|
||||||
: expr_identifier LPAREN expr_parameters RPAREN stmt_block
|
|
||||||
{ lexer.ban_header(@$); $$ = std::make_unique<ast::decl_thread>(@$, std::move($1), std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt
|
|
||||||
: stmt_block { $$.as_list = std::move($1); }
|
|
||||||
| stmt_call { $$.as_call = std::move($1); }
|
|
||||||
| stmt_assign { $$.as_assign = std::move($1); }
|
|
||||||
| stmt_endon { $$.as_endon = std::move($1); }
|
|
||||||
| stmt_notify { $$.as_notify = std::move($1); }
|
|
||||||
| stmt_wait { $$.as_wait = std::move($1); }
|
|
||||||
| stmt_waittill { $$.as_waittill = std::move($1); }
|
|
||||||
| stmt_waittillmatch { $$.as_waittillmatch = std::move($1); }
|
|
||||||
| stmt_waittillframeend { $$.as_waittillframeend = std::move($1); }
|
|
||||||
| stmt_waitframe { $$.as_waitframe = std::move($1); }
|
|
||||||
| stmt_if { $$.as_if = std::move($1); }
|
|
||||||
| stmt_ifelse { $$.as_ifelse = std::move($1); }
|
|
||||||
| stmt_while { $$.as_while = std::move($1); }
|
|
||||||
| stmt_dowhile { $$.as_dowhile = std::move($1); }
|
|
||||||
| stmt_for { $$.as_for = std::move($1); }
|
|
||||||
| stmt_foreach { $$.as_foreach = std::move($1); }
|
|
||||||
| stmt_switch { $$.as_switch = std::move($1); }
|
|
||||||
| stmt_case { $$.as_case = std::move($1); }
|
|
||||||
| stmt_default { $$.as_default = std::move($1); }
|
|
||||||
| stmt_break { $$.as_break = std::move($1); }
|
|
||||||
| stmt_continue { $$.as_continue = std::move($1); }
|
|
||||||
| stmt_return { $$.as_return = std::move($1); }
|
|
||||||
| stmt_breakpoint { $$.as_breakpoint = std::move($1); }
|
|
||||||
| stmt_prof_begin { $$.as_prof_begin = std::move($1); }
|
|
||||||
| stmt_prof_end { $$.as_prof_end = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_or_dev
|
|
||||||
: stmt { $$ = std::move($1); }
|
|
||||||
| stmt_dev { $$.as_dev = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_list
|
|
||||||
: stmt_list stmt
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($2)); }
|
|
||||||
| stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_list>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_or_dev_list
|
|
||||||
: stmt_or_dev_list stmt_or_dev
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($2)); }
|
|
||||||
| stmt_or_dev
|
|
||||||
{ $$ = std::make_unique<ast::stmt_list>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_dev
|
|
||||||
: DEVBEGIN stmt_list DEVEND { $$ = std::make_unique<ast::stmt_dev>(@$, std::move($2)); }
|
|
||||||
| DEVBEGIN DEVEND { $$ = std::make_unique<ast::stmt_dev>(@$, std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_block
|
|
||||||
: LBRACE stmt_or_dev_list RBRACE { $$ = std::move($2); }
|
|
||||||
| LBRACE RBRACE { $$ = std::make_unique<ast::stmt_list>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_expr
|
|
||||||
: expr_assign
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
| expr_increment
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
| expr_decrement
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::make_unique<ast::node>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_call
|
|
||||||
: expr_call SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_call>(@$, ast::expr(std::move($1))); }
|
|
||||||
| expr_method SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_call>(@$, ast::expr(std::move($1))); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_assign
|
|
||||||
: expr_assign SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
| expr_increment SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
| expr_decrement SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_endon
|
|
||||||
: expr_object ENDON LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_endon>(@$, std::move($1), std::move($4)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_notify
|
|
||||||
: expr_object NOTIFY LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_notify>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object NOTIFY LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_notify>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_wait
|
|
||||||
: WAIT expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_wait>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittill
|
|
||||||
: expr_object WAITTILL LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittill>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object WAITTILL LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittill>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittillmatch
|
|
||||||
: expr_object WAITTILLMATCH LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillmatch>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object WAITTILLMATCH LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillmatch>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittillframeend
|
|
||||||
: WAITTILLFRAMEEND SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillframeend>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waitframe
|
|
||||||
: WAITFRAME SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waitframe>(@$); }
|
|
||||||
| WAITFRAME LPAREN RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waitframe>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_if
|
|
||||||
: IF LPAREN expr RPAREN stmt %prec THEN
|
|
||||||
{ $$ = std::make_unique<ast::stmt_if>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_ifelse
|
|
||||||
: IF LPAREN expr RPAREN stmt ELSE stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_ifelse>(@$, std::move($3), std::move($5), std::move($7)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_while
|
|
||||||
: WHILE LPAREN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_while>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_dowhile
|
|
||||||
: DO stmt WHILE LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_dowhile>(@$, std::move($5), std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_for
|
|
||||||
: FOR LPAREN stmt_expr SEMICOLON expr_or_empty SEMICOLON stmt_expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_for>(@$, ast::stmt(std::move($3)), std::move($5), ast::stmt(std::move($7)), std::move($9)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_foreach
|
|
||||||
: FOREACH LPAREN expr_identifier IN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_foreach>(@$, ast::expr(std::move($3)), std::move($5), std::move($7)); }
|
|
||||||
| FOREACH LPAREN expr_identifier COMMA expr_identifier IN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_foreach>(@$, ast::expr(std::move($3)), ast::expr(std::move($5)), std::move($7), std::move($9)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_switch
|
|
||||||
: SWITCH LPAREN expr RPAREN stmt_block
|
|
||||||
{ $$ = std::make_unique<ast::stmt_switch>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_case
|
|
||||||
: CASE expr_integer COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_case>(@$, ast::expr(std::move($2)), std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
| CASE expr_string COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_case>(@$, ast::expr(std::move($2)), std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_default
|
|
||||||
: DEFAULT COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_default>(@$, std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_break
|
|
||||||
: BREAK SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_break>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_continue
|
|
||||||
: CONTINUE SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_continue>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_return
|
|
||||||
: RETURN expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_return>(@$, std::move($2)); }
|
|
||||||
| RETURN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_return>(@$, std::make_unique<ast::node>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_breakpoint
|
|
||||||
: BREAKPOINT SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_breakpoint>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_prof_begin
|
|
||||||
: PROFBEGIN LPAREN expr_arguments RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_prof_begin>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_prof_end
|
|
||||||
: PROFEND LPAREN expr_arguments RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_prof_end>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr
|
|
||||||
: expr_ternary { $$ = std::move($1); }
|
|
||||||
| expr_binary { $$ = std::move($1); }
|
|
||||||
| expr_primitive { $$ = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_or_empty
|
|
||||||
: expr { $$ = std::move($1); }
|
|
||||||
| { $$.as_node = std::make_unique<ast::node>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_assign
|
|
||||||
: expr_object ASSIGN expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_EXOR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_exor>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_LSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_shift_left>(@$, std::move($1),std::move( $3)); }
|
|
||||||
| expr_object ASSIGN_RSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_shift_right>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_ADD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_add>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_SUB expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_sub>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_MUL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_mul>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_DIV expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_div>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_MOD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_mod>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_increment
|
|
||||||
: INCREMENT expr_object %prec PREINC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_increment>(@$, std::move($2), true); }
|
|
||||||
| expr_object INCREMENT %prec POSTINC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_increment>(@$, std::move($1), false); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_decrement
|
|
||||||
: DECREMENT expr_object %prec PREDEC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_decrement>(@$, std::move($2), true); }
|
|
||||||
| expr_object DECREMENT %prec POSTDEC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_decrement>(@$, std::move($1), false); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_ternary
|
|
||||||
: expr QMARK expr COLON expr %prec TERN
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_ternary>(@$, std::move($1), std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_binary
|
|
||||||
: expr OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr EQUALITY expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_equality>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr INEQUALITY expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_inequality>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LESS_EQUAL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_less_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr GREATER_EQUAL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_greater_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LESS expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_less>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr GREATER expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_greater>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_EXOR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_exor>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_shift_left>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr RSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_shift_right>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr ADD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_add>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr SUB expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_sub>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr MUL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_mul>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr DIV expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_div>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr MOD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_mod>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_primitive
|
|
||||||
: expr_complement { $$.as_node = std::move($1); }
|
|
||||||
| expr_negate { $$.as_node = std::move($1); }
|
|
||||||
| expr_not { $$.as_node = std::move($1); }
|
|
||||||
| expr_call { $$.as_node = std::move($1); }
|
|
||||||
| expr_method { $$.as_node = std::move($1); }
|
|
||||||
| expr_add_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_isdefined { $$.as_node = std::move($1); }
|
|
||||||
| expr_istrue { $$.as_node = std::move($1); }
|
|
||||||
| expr_reference { $$.as_node = std::move($1); }
|
|
||||||
| expr_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_field { $$.as_node = std::move($1); }
|
|
||||||
| expr_size { $$.as_node = std::move($1); }
|
|
||||||
| expr_paren { $$.as_node = std::move($1); }
|
|
||||||
| expr_thisthread { $$.as_node = std::move($1); }
|
|
||||||
| expr_empty_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_undefined { $$.as_node = std::move($1); }
|
|
||||||
| expr_game { $$.as_node = std::move($1); }
|
|
||||||
| expr_self { $$.as_node = std::move($1); }
|
|
||||||
| expr_anim { $$.as_node = std::move($1); }
|
|
||||||
| expr_level { $$.as_node = std::move($1); }
|
|
||||||
| expr_animation { $$.as_node = std::move($1); }
|
|
||||||
| expr_animtree { $$.as_node = std::move($1); }
|
|
||||||
| expr_identifier { $$.as_node = std::move($1); }
|
|
||||||
| expr_istring { $$.as_node = std::move($1); }
|
|
||||||
| expr_string { $$.as_node = std::move($1); }
|
|
||||||
| expr_vector { $$.as_node = std::move($1); }
|
|
||||||
| expr_float { $$.as_node = std::move($1); }
|
|
||||||
| expr_integer { $$.as_node = std::move($1); }
|
|
||||||
| expr_false { $$.as_node = std::move($1); }
|
|
||||||
| expr_true { $$.as_node = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_complement
|
|
||||||
: COMPLEMENT expr
|
|
||||||
{ $$ = std::make_unique<ast::expr_complement>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_negate
|
|
||||||
: SUB expr_identifier %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_paren %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_array %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_field %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_not
|
|
||||||
: NOT expr
|
|
||||||
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_call
|
|
||||||
: expr_function { $$ = std::make_unique<ast::expr_call>(@$, std::move($1)); }
|
|
||||||
| expr_pointer { $$ = std::make_unique<ast::expr_call>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
expr_method
|
|
||||||
: expr_object expr_function { $$ = std::make_unique<ast::expr_method>(@$, std::move($1), std::move($2)); }
|
|
||||||
| expr_object expr_pointer { $$ = std::make_unique<ast::expr_method>(@$, std::move($1), std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_function
|
|
||||||
: expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($1), std::move($3), ast::call::mode::normal); }
|
|
||||||
| expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($1), std::move($3), std::move($5), ast::call::mode::normal); }
|
|
||||||
| THREAD expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($2), std::move($4), ast::call::mode::thread); }
|
|
||||||
| THREAD expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($2), std::move($4), std::move($6), ast::call::mode::thread); }
|
|
||||||
| CHILDTHREAD expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($2), std::move($4), ast::call::mode::childthread); }
|
|
||||||
| CHILDTHREAD expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($2), std::move($4), std::move($6), ast::call::mode::childthread); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_pointer
|
|
||||||
: LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($3), std::move($7), ast::call::mode::normal); }
|
|
||||||
| THREAD LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::thread); }
|
|
||||||
| CHILDTHREAD LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::childthread); }
|
|
||||||
| CALL LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::builtin); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_add_array
|
|
||||||
: LBRACKET expr_arguments_no_empty RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_add_array>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_parameters
|
|
||||||
: expr_parameters COMMA expr_identifier
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($3)); }
|
|
||||||
| expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_parameters>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::expr_parameters>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_arguments
|
|
||||||
: expr_arguments_no_empty
|
|
||||||
{ $$ = std::move($1); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::expr_arguments>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_arguments_no_empty
|
|
||||||
: expr_arguments COMMA expr
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($3)); }
|
|
||||||
| expr %prec ADD_ARRAY
|
|
||||||
{ $$ = std::make_unique<ast::expr_arguments>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_isdefined
|
|
||||||
: ISDEFINED LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_isdefined>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_istrue
|
|
||||||
: ISTRUE LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_istrue>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_reference
|
|
||||||
: DOUBLECOLON expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_reference>(@$, std::make_unique<ast::expr_path>(@$), std::move($2)); }
|
|
||||||
| expr_path DOUBLECOLON expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_reference>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_array
|
|
||||||
: expr_object LBRACKET expr RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_array>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_field
|
|
||||||
: expr_object DOT expr_identifier_nosize
|
|
||||||
{ $$ = std::make_unique<ast::expr_field>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_size
|
|
||||||
: expr_object DOT SIZE %prec SIZEOF
|
|
||||||
{ $$ = std::make_unique<ast::expr_size>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_paren
|
|
||||||
: LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_paren>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_object
|
|
||||||
: expr_call { $$.as_node = std::move($1); }
|
|
||||||
| expr_method { $$.as_node = std::move($1); }
|
|
||||||
| expr_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_field { $$.as_node = std::move($1); }
|
|
||||||
| expr_game { $$.as_node = std::move($1); }
|
|
||||||
| expr_self { $$.as_node = std::move($1); }
|
|
||||||
| expr_anim { $$.as_node = std::move($1); }
|
|
||||||
| expr_level { $$.as_node = std::move($1); }
|
|
||||||
| expr_identifier { $$.as_node = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_thisthread
|
|
||||||
: THISTHREAD
|
|
||||||
{ $$ = std::make_unique<ast::expr_thisthread>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_empty_array
|
|
||||||
: LBRACKET RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_empty_array>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_undefined
|
|
||||||
: UNDEFINED
|
|
||||||
{ $$ = std::make_unique<ast::expr_undefined>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_game
|
|
||||||
: GAME
|
|
||||||
{ $$ = std::make_unique<ast::expr_game>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_self
|
|
||||||
: SELF
|
|
||||||
{ $$ = std::make_unique<ast::expr_self>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_anim
|
|
||||||
: ANIM
|
|
||||||
{ $$ = std::make_unique<ast::expr_anim>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_level
|
|
||||||
: LEVEL
|
|
||||||
{ $$ = std::make_unique<ast::expr_level>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_animation
|
|
||||||
: MOD IDENTIFIER %prec ANIMREF
|
|
||||||
{ $$ = std::make_unique<ast::expr_animation>(@$, $2); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_animtree
|
|
||||||
: ANIMTREE
|
|
||||||
{ $$ = std::make_unique<ast::expr_animtree>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_identifier_nosize
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_identifier
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, $1); };
|
|
||||||
| SIZE
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, "size"); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_path
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_path>(@$, $1); };
|
|
||||||
| PATH
|
|
||||||
{ $$ = std::make_unique<ast::expr_path>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_istring
|
|
||||||
: ISTRING
|
|
||||||
{ $$ = std::make_unique<ast::expr_istring>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_string
|
|
||||||
: STRING
|
|
||||||
{ $$ = std::make_unique<ast::expr_string>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_vector
|
|
||||||
: LPAREN expr COMMA expr COMMA expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_vector>(@$, std::move($2), std::move($4), std::move($6)); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_float
|
|
||||||
: SUB FLOAT %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_float>(@$, "-" + $2); };
|
|
||||||
| FLOAT
|
|
||||||
{ $$ = std::make_unique<ast::expr_float>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_integer
|
|
||||||
: SUB INTEGER %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_integer>(@$, "-" + $2); };
|
|
||||||
| INTEGER
|
|
||||||
{ $$ = std::make_unique<ast::expr_integer>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_false
|
|
||||||
: FALSE
|
|
||||||
{ $$ = std::make_unique<ast::expr_false>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_true
|
|
||||||
: TRUE
|
|
||||||
{ $$ = std::make_unique<ast::expr_true>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
void xsk::gsc::s4::parser::error(const xsk::gsc::location& loc, const std::string& msg)
|
|
||||||
{
|
|
||||||
throw xsk::gsc::comp_error(loc, msg);
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
generate: T6
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf ./parser.hpp
|
|
||||||
rm -rf ./parser.cpp
|
|
||||||
|
|
||||||
T6: parser.ypp
|
|
||||||
bison parser.ypp -Wcounterexamples
|
|
||||||
mv parser.hpp parser.cpp ../../src/t6/xsk/
|
|
@ -1,997 +0,0 @@
|
|||||||
/* Copyright 2022 xensik. All rights reserved.
|
|
||||||
//
|
|
||||||
// Use of this source code is governed by a GNU GPLv3 license
|
|
||||||
// that can be found in the LICENSE file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
%require "3.7"
|
|
||||||
%skeleton "lalr1.cc"
|
|
||||||
%language "c++"
|
|
||||||
%output "parser.cpp"
|
|
||||||
%defines "parser.hpp"
|
|
||||||
%define api.prefix {T6}
|
|
||||||
%define api.namespace {xsk::arc::t6}
|
|
||||||
%define api.location.type {xsk::arc::location}
|
|
||||||
%define api.value.type variant
|
|
||||||
%define api.token.constructor
|
|
||||||
%define api.token.raw
|
|
||||||
%define parse.assert
|
|
||||||
%define parse.trace
|
|
||||||
%define parse.error detailed
|
|
||||||
%define parse.lac full
|
|
||||||
%locations
|
|
||||||
%lex-param { xsk::arc::t6::lexer& lexer }
|
|
||||||
%parse-param { xsk::arc::t6::lexer& lexer }
|
|
||||||
%parse-param { xsk::arc::ast::program::ptr& ast }
|
|
||||||
|
|
||||||
%code requires
|
|
||||||
{
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(disable:4065)
|
|
||||||
#pragma warning(disable:4127)
|
|
||||||
#endif
|
|
||||||
#include "t6.hpp"
|
|
||||||
namespace xsk::arc::t6 { class lexer; }
|
|
||||||
}
|
|
||||||
|
|
||||||
%code top
|
|
||||||
{
|
|
||||||
#include "stdafx.hpp"
|
|
||||||
#include "parser.hpp"
|
|
||||||
#include "lexer.hpp"
|
|
||||||
using namespace xsk::arc;
|
|
||||||
xsk::arc::t6::parser::symbol_type T6lex(xsk::arc::t6::lexer& lexer);
|
|
||||||
}
|
|
||||||
|
|
||||||
%token SH_DEFINE "#define"
|
|
||||||
%token SH_UNDEF "#undef"
|
|
||||||
%token SH_IFDEF "#ifdef"
|
|
||||||
%token SH_IFNDEF "#ifndef"
|
|
||||||
%token SH_IF "#if"
|
|
||||||
%token SH_ELIF "#elif"
|
|
||||||
%token SH_ELSE "#else"
|
|
||||||
%token SH_ENDIF "#endif"
|
|
||||||
%token DEVBEGIN "/#"
|
|
||||||
%token DEVEND "#/"
|
|
||||||
%token INLINE "#inline"
|
|
||||||
%token INCLUDE "#include"
|
|
||||||
%token USINGTREE "#using_animtree"
|
|
||||||
%token ENDON "endon"
|
|
||||||
%token NOTIFY "notify"
|
|
||||||
%token WAIT "wait"
|
|
||||||
%token WAITTILL "waittill"
|
|
||||||
%token WAITTILLMATCH "waittillmatch"
|
|
||||||
%token WAITTILLFRAMEEND "waittillframeend"
|
|
||||||
%token IF "if"
|
|
||||||
%token ELSE "else"
|
|
||||||
%token DO "do"
|
|
||||||
%token WHILE "while"
|
|
||||||
%token FOR "for"
|
|
||||||
%token FOREACH "foreach"
|
|
||||||
%token IN "in"
|
|
||||||
%token SWITCH "switch"
|
|
||||||
%token CASE "case"
|
|
||||||
%token DEFAULT "default"
|
|
||||||
%token BREAK "break"
|
|
||||||
%token CONTINUE "continue"
|
|
||||||
%token RETURN "return"
|
|
||||||
%token PROFBEGIN "prof_begin"
|
|
||||||
%token PROFEND "prof_end"
|
|
||||||
%token THREAD "thread"
|
|
||||||
%token TRUE "true"
|
|
||||||
%token FALSE "false"
|
|
||||||
%token UNDEFINED "undefined"
|
|
||||||
%token SIZE "size"
|
|
||||||
%token GAME "game"
|
|
||||||
%token SELF "self"
|
|
||||||
%token ANIM "anim"
|
|
||||||
%token LEVEL "level"
|
|
||||||
%token GETNEXTARRAYKEY "getnextarraykey"
|
|
||||||
%token GETFIRSTARRAYKEY "getfirstarraykey"
|
|
||||||
%token GETDVARCOLORALPHA "getdvarcoloralpha"
|
|
||||||
%token GETDVARCOLORBLUE "getdvarcolorblue"
|
|
||||||
%token GETDVARCOLORGREEN "getdvarcolorgreen"
|
|
||||||
%token GETDVARCOLORRED "getdvarcolorred"
|
|
||||||
%token GETDVARVECTOR "getdvarvector"
|
|
||||||
%token GETDVARFLOAT "getdvarfloat"
|
|
||||||
%token GETDVARINT "getdvarint"
|
|
||||||
%token GETDVAR "getdvar"
|
|
||||||
%token GETTIME "gettime"
|
|
||||||
%token ABS "abs"
|
|
||||||
%token VECTORTOANGLES "vectortoangles"
|
|
||||||
%token ANGLECLAMP180 "angleclamp180"
|
|
||||||
%token ANGLESTOFORWARD "anglestoforward"
|
|
||||||
%token ANGLESTORIGHT "anglestoright"
|
|
||||||
%token ANGLESTOUP "anglestoup"
|
|
||||||
%token VECTORSCALE "vectorscale"
|
|
||||||
%token ISDEFINED "isdefined"
|
|
||||||
%token LPAREN "("
|
|
||||||
%token RPAREN ")"
|
|
||||||
%token LBRACE "{"
|
|
||||||
%token RBRACE "}"
|
|
||||||
%token LBRACKET "["
|
|
||||||
%token RBRACKET "]"
|
|
||||||
%token COMMA ","
|
|
||||||
%token DOT "."
|
|
||||||
%token DOUBLECOLON "::"
|
|
||||||
%token COLON ":"
|
|
||||||
%token SEMICOLON ";"
|
|
||||||
%token QMARK "?"
|
|
||||||
%token INCREMENT "++"
|
|
||||||
%token DECREMENT "--"
|
|
||||||
%token LSHIFT "<<"
|
|
||||||
%token RSHIFT ">>"
|
|
||||||
%token OR "||"
|
|
||||||
%token AND "&&"
|
|
||||||
%token EQUALITY "=="
|
|
||||||
%token INEQUALITY "!="
|
|
||||||
%token LESS_EQUAL "<="
|
|
||||||
%token GREATER_EQUAL ">="
|
|
||||||
%token LESS "<"
|
|
||||||
%token GREATER ">"
|
|
||||||
%token NOT "!"
|
|
||||||
%token COMPLEMENT "~"
|
|
||||||
%token ASSIGN "="
|
|
||||||
%token ASSIGN_ADD "+="
|
|
||||||
%token ASSIGN_SUB "-="
|
|
||||||
%token ASSIGN_MUL "*="
|
|
||||||
%token ASSIGN_DIV "/="
|
|
||||||
%token ASSIGN_MOD "%="
|
|
||||||
%token ASSIGN_BW_OR "|="
|
|
||||||
%token ASSIGN_BW_AND "&="
|
|
||||||
%token ASSIGN_BW_EXOR "^="
|
|
||||||
%token ASSIGN_RSHIFT ">>="
|
|
||||||
%token ASSIGN_LSHIFT "<<="
|
|
||||||
%token BITWISE_OR "|"
|
|
||||||
%token BITWISE_AND "&"
|
|
||||||
%token BITWISE_EXOR "^"
|
|
||||||
%token ADD "+"
|
|
||||||
%token SUB "-"
|
|
||||||
%token MUL "*"
|
|
||||||
%token DIV "/"
|
|
||||||
%token MOD "%"
|
|
||||||
%token <std::string> PATH "path"
|
|
||||||
%token <std::string> IDENTIFIER "identifier"
|
|
||||||
%token <std::string> STRING "string literal"
|
|
||||||
%token <std::string> ISTRING "localized string"
|
|
||||||
%token <std::string> HASH "hash"
|
|
||||||
%token <std::string> FLOAT "float"
|
|
||||||
%token <std::string> INTEGER "integer"
|
|
||||||
|
|
||||||
%type <ast::program::ptr> program
|
|
||||||
%type <ast::include::ptr> include
|
|
||||||
%type <ast::decl> declaration
|
|
||||||
%type <ast::decl_usingtree::ptr> decl_usingtree
|
|
||||||
%type <ast::decl_constant::ptr> decl_constant
|
|
||||||
%type <ast::decl_thread::ptr> decl_thread
|
|
||||||
%type <ast::stmt> stmt
|
|
||||||
%type <ast::stmt> stmt_or_dev
|
|
||||||
%type <ast::stmt_list::ptr> stmt_list
|
|
||||||
%type <ast::stmt_list::ptr> stmt_or_dev_list
|
|
||||||
%type <ast::stmt_dev::ptr> stmt_dev
|
|
||||||
%type <ast::stmt_list::ptr> stmt_block
|
|
||||||
%type <ast::stmt_expr::ptr> stmt_expr
|
|
||||||
%type <ast::stmt_call::ptr> stmt_call
|
|
||||||
%type <ast::stmt_assign::ptr> stmt_assign
|
|
||||||
%type <ast::stmt_endon::ptr> stmt_endon
|
|
||||||
%type <ast::stmt_notify::ptr> stmt_notify
|
|
||||||
%type <ast::stmt_wait::ptr> stmt_wait
|
|
||||||
%type <ast::stmt_waittill::ptr> stmt_waittill
|
|
||||||
%type <ast::stmt_waittillmatch::ptr> stmt_waittillmatch
|
|
||||||
%type <ast::stmt_waittillframeend::ptr> stmt_waittillframeend
|
|
||||||
%type <ast::stmt_if::ptr> stmt_if
|
|
||||||
%type <ast::stmt_ifelse::ptr> stmt_ifelse
|
|
||||||
%type <ast::stmt_while::ptr> stmt_while
|
|
||||||
%type <ast::stmt_dowhile::ptr> stmt_dowhile
|
|
||||||
%type <ast::stmt_for::ptr> stmt_for
|
|
||||||
%type <ast::stmt_foreach::ptr> stmt_foreach
|
|
||||||
%type <ast::stmt_switch::ptr> stmt_switch
|
|
||||||
%type <ast::stmt_case::ptr> stmt_case
|
|
||||||
%type <ast::stmt_default::ptr> stmt_default
|
|
||||||
%type <ast::stmt_break::ptr> stmt_break
|
|
||||||
%type <ast::stmt_continue::ptr> stmt_continue
|
|
||||||
%type <ast::stmt_return::ptr> stmt_return
|
|
||||||
%type <ast::stmt_prof_begin::ptr> stmt_prof_begin
|
|
||||||
%type <ast::stmt_prof_end::ptr> stmt_prof_end
|
|
||||||
%type <ast::expr> expr
|
|
||||||
%type <ast::expr> expr_or_empty
|
|
||||||
%type <ast::expr> expr_assign
|
|
||||||
%type <ast::expr> expr_increment
|
|
||||||
%type <ast::expr> expr_decrement
|
|
||||||
%type <ast::expr> expr_ternary
|
|
||||||
%type <ast::expr> expr_binary
|
|
||||||
%type <ast::expr> expr_primitive
|
|
||||||
%type <ast::expr_complement::ptr> expr_complement
|
|
||||||
%type <ast::expr_negate::ptr> expr_negate
|
|
||||||
%type <ast::expr_not::ptr> expr_not
|
|
||||||
%type <ast::expr_call::ptr> expr_call
|
|
||||||
%type <ast::expr_method::ptr> expr_method
|
|
||||||
%type <ast::call> expr_function
|
|
||||||
%type <ast::call> expr_pointer
|
|
||||||
%type <ast::expr_parameters::ptr> expr_parameters
|
|
||||||
%type <ast::expr_arguments::ptr> expr_arguments
|
|
||||||
%type <ast::expr_arguments::ptr> expr_arguments_no_empty
|
|
||||||
%type <ast::expr_getnextarraykey::ptr> expr_getnextarraykey
|
|
||||||
%type <ast::expr_getfirstarraykey::ptr> expr_getfirstarraykey
|
|
||||||
%type <ast::expr_getdvarcoloralpha::ptr> expr_getdvarcoloralpha
|
|
||||||
%type <ast::expr_getdvarcolorblue::ptr> expr_getdvarcolorblue
|
|
||||||
%type <ast::expr_getdvarcolorgreen::ptr> expr_getdvarcolorgreen
|
|
||||||
%type <ast::expr_getdvarcolorred::ptr> expr_getdvarcolorred
|
|
||||||
%type <ast::expr_getdvarvector::ptr> expr_getdvarvector
|
|
||||||
%type <ast::expr_getdvarfloat::ptr> expr_getdvarfloat
|
|
||||||
%type <ast::expr_getdvarint::ptr> expr_getdvarint
|
|
||||||
%type <ast::expr_getdvar::ptr> expr_getdvar
|
|
||||||
%type <ast::expr_gettime::ptr> expr_gettime
|
|
||||||
%type <ast::expr_abs::ptr> expr_abs
|
|
||||||
%type <ast::expr_vectortoangles::ptr> expr_vectortoangles
|
|
||||||
%type <ast::expr_angleclamp180::ptr> expr_angleclamp180
|
|
||||||
%type <ast::expr_anglestoforward::ptr> expr_anglestoforward
|
|
||||||
%type <ast::expr_anglestoright::ptr> expr_anglestoright
|
|
||||||
%type <ast::expr_anglestoup::ptr> expr_anglestoup
|
|
||||||
%type <ast::expr_vectorscale::ptr> expr_vectorscale
|
|
||||||
%type <ast::expr_isdefined::ptr> expr_isdefined
|
|
||||||
%type <ast::expr_reference::ptr> expr_reference
|
|
||||||
%type <ast::expr_array::ptr> expr_array
|
|
||||||
%type <ast::expr_field::ptr> expr_field
|
|
||||||
%type <ast::expr_size::ptr> expr_size
|
|
||||||
%type <ast::expr_paren::ptr> expr_paren
|
|
||||||
%type <ast::expr> expr_object
|
|
||||||
%type <ast::expr_empty_array::ptr> expr_empty_array
|
|
||||||
%type <ast::expr_undefined::ptr> expr_undefined
|
|
||||||
%type <ast::expr_game::ptr> expr_game
|
|
||||||
%type <ast::expr_self::ptr> expr_self
|
|
||||||
%type <ast::expr_anim::ptr> expr_anim
|
|
||||||
%type <ast::expr_level::ptr> expr_level
|
|
||||||
%type <ast::expr_animation::ptr> expr_animation
|
|
||||||
%type <ast::expr_identifier::ptr> expr_identifier_nosize
|
|
||||||
%type <ast::expr_identifier::ptr> expr_identifier
|
|
||||||
%type <ast::expr_path::ptr> expr_path
|
|
||||||
%type <ast::expr_istring::ptr> expr_istring
|
|
||||||
%type <ast::expr_string::ptr> expr_string
|
|
||||||
%type <ast::expr_vector::ptr> expr_vector
|
|
||||||
%type <ast::expr_hash::ptr> expr_hash
|
|
||||||
%type <ast::expr_float::ptr> expr_float
|
|
||||||
%type <ast::expr_integer::ptr> expr_integer
|
|
||||||
%type <ast::expr_false::ptr> expr_false
|
|
||||||
%type <ast::expr_true::ptr> expr_true
|
|
||||||
|
|
||||||
%nonassoc SIZEOF
|
|
||||||
%nonassoc RBRACKET
|
|
||||||
%nonassoc THEN
|
|
||||||
%nonassoc ELSE
|
|
||||||
%nonassoc INCREMENT DECREMENT
|
|
||||||
|
|
||||||
%precedence TERN
|
|
||||||
%right QMARK
|
|
||||||
%left OR
|
|
||||||
%left AND
|
|
||||||
%left BITWISE_OR
|
|
||||||
%left BITWISE_EXOR
|
|
||||||
%left BITWISE_AND
|
|
||||||
%left EQUALITY INEQUALITY
|
|
||||||
%left LESS GREATER LESS_EQUAL GREATER_EQUAL
|
|
||||||
%left LSHIFT RSHIFT
|
|
||||||
%left ADD SUB
|
|
||||||
%left MUL DIV MOD
|
|
||||||
%right NOT COMPLEMENT
|
|
||||||
|
|
||||||
%precedence NEG
|
|
||||||
%precedence ANIMREF
|
|
||||||
%precedence PREINC PREDEC
|
|
||||||
%precedence POSTINC POSTDEC
|
|
||||||
|
|
||||||
%start root
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
root
|
|
||||||
: program { ast = std::move($1); }
|
|
||||||
| { ast = std::make_unique<ast::program>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
program
|
|
||||||
: program inline
|
|
||||||
{ $$ = std::move($1); }
|
|
||||||
| program include
|
|
||||||
{ $$ = std::move($1); $$->includes.push_back(std::move($2)); }
|
|
||||||
| program declaration
|
|
||||||
{ $$ = std::move($1); $$->declarations.push_back(std::move($2)); }
|
|
||||||
| inline
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); }
|
|
||||||
| include
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); $$->includes.push_back(std::move($1)); }
|
|
||||||
| declaration
|
|
||||||
{ $$ = std::make_unique<ast::program>(@$); $$->declarations.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
inline
|
|
||||||
: INLINE expr_path SEMICOLON { lexer.push_header($2->value); }
|
|
||||||
;
|
|
||||||
|
|
||||||
include
|
|
||||||
: INCLUDE expr_path SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::include>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
declaration
|
|
||||||
: DEVBEGIN { $$.as_dev_begin = std::make_unique<ast::decl_dev_begin>(@$); }
|
|
||||||
| DEVEND { $$.as_dev_end = std::make_unique<ast::decl_dev_end>(@$); }
|
|
||||||
| decl_usingtree { $$.as_usingtree = std::move($1); }
|
|
||||||
| decl_constant { $$.as_constant = std::move($1); }
|
|
||||||
| decl_thread { $$.as_thread = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_usingtree
|
|
||||||
: USINGTREE LPAREN expr_string RPAREN SEMICOLON
|
|
||||||
{ lexer.ban_header(@$); $$ = std::make_unique<ast::decl_usingtree>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_constant
|
|
||||||
: expr_identifier ASSIGN expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::decl_constant>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
decl_thread
|
|
||||||
: expr_identifier LPAREN expr_parameters RPAREN stmt_block
|
|
||||||
{ lexer.ban_header(@$); $$ = std::make_unique<ast::decl_thread>(@$, std::move($1), std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt
|
|
||||||
: stmt_block { $$.as_list = std::move($1); }
|
|
||||||
| stmt_call { $$.as_call = std::move($1); }
|
|
||||||
| stmt_assign { $$.as_assign = std::move($1); }
|
|
||||||
| stmt_endon { $$.as_endon = std::move($1); }
|
|
||||||
| stmt_notify { $$.as_notify = std::move($1); }
|
|
||||||
| stmt_wait { $$.as_wait = std::move($1); }
|
|
||||||
| stmt_waittill { $$.as_waittill = std::move($1); }
|
|
||||||
| stmt_waittillmatch { $$.as_waittillmatch = std::move($1); }
|
|
||||||
| stmt_waittillframeend { $$.as_waittillframeend = std::move($1); }
|
|
||||||
| stmt_if { $$.as_if = std::move($1); }
|
|
||||||
| stmt_ifelse { $$.as_ifelse = std::move($1); }
|
|
||||||
| stmt_while { $$.as_while = std::move($1); }
|
|
||||||
| stmt_dowhile { $$.as_dowhile = std::move($1); }
|
|
||||||
| stmt_for { $$.as_for = std::move($1); }
|
|
||||||
| stmt_foreach { $$.as_foreach = std::move($1); }
|
|
||||||
| stmt_switch { $$.as_switch = std::move($1); }
|
|
||||||
| stmt_case { $$.as_case = std::move($1); }
|
|
||||||
| stmt_default { $$.as_default = std::move($1); }
|
|
||||||
| stmt_break { $$.as_break = std::move($1); }
|
|
||||||
| stmt_continue { $$.as_continue = std::move($1); }
|
|
||||||
| stmt_return { $$.as_return = std::move($1); }
|
|
||||||
| stmt_prof_begin { $$.as_prof_begin = std::move($1); }
|
|
||||||
| stmt_prof_end { $$.as_prof_end = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_or_dev
|
|
||||||
: stmt { $$ = std::move($1); }
|
|
||||||
| stmt_dev { $$.as_dev = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_list
|
|
||||||
: stmt_list stmt
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($2)); }
|
|
||||||
| stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_list>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_or_dev_list
|
|
||||||
: stmt_or_dev_list stmt_or_dev
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($2)); }
|
|
||||||
| stmt_or_dev
|
|
||||||
{ $$ = std::make_unique<ast::stmt_list>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_dev
|
|
||||||
: DEVBEGIN stmt_list DEVEND { $$ = std::make_unique<ast::stmt_dev>(@$, std::move($2)); }
|
|
||||||
| DEVBEGIN DEVEND { $$ = std::make_unique<ast::stmt_dev>(@$, std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_block
|
|
||||||
: LBRACE stmt_or_dev_list RBRACE { $$ = std::move($2); }
|
|
||||||
| LBRACE RBRACE { $$ = std::make_unique<ast::stmt_list>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_expr
|
|
||||||
: expr_assign
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
| expr_increment
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
| expr_decrement
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::move($1)); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::stmt_expr>(@$, std::make_unique<ast::node>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_call
|
|
||||||
: expr_call SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_call>(@$, ast::expr(std::move($1))); }
|
|
||||||
| expr_method SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_call>(@$, ast::expr(std::move($1))); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_assign
|
|
||||||
: expr_assign SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
| expr_increment SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
| expr_decrement SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_assign>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_endon
|
|
||||||
: expr_object ENDON LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_endon>(@$, std::move($1), std::move($4)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_notify
|
|
||||||
: expr_object NOTIFY LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_notify>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object NOTIFY LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_notify>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_wait
|
|
||||||
: WAIT expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_wait>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittill
|
|
||||||
: expr_object WAITTILL LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittill>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object WAITTILL LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittill>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittillmatch
|
|
||||||
: expr_object WAITTILLMATCH LPAREN expr COMMA expr_arguments_no_empty RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillmatch>(@$, std::move($1), std::move($4), std::move($6)); }
|
|
||||||
| expr_object WAITTILLMATCH LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillmatch>(@$, std::move($1), std::move($4), std::make_unique<ast::expr_arguments>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_waittillframeend
|
|
||||||
: WAITTILLFRAMEEND SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_waittillframeend>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_if
|
|
||||||
: IF LPAREN expr RPAREN stmt %prec THEN
|
|
||||||
{ $$ = std::make_unique<ast::stmt_if>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_ifelse
|
|
||||||
: IF LPAREN expr RPAREN stmt ELSE stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_ifelse>(@$, std::move($3), std::move($5), std::move($7)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_while
|
|
||||||
: WHILE LPAREN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_while>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_dowhile
|
|
||||||
: DO stmt WHILE LPAREN expr RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_dowhile>(@$, std::move($5), std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_for
|
|
||||||
: FOR LPAREN stmt_expr SEMICOLON expr_or_empty SEMICOLON stmt_expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_for>(@$, ast::stmt(std::move($3)), std::move($5), ast::stmt(std::move($7)), std::move($9)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_foreach
|
|
||||||
: FOREACH LPAREN expr_identifier IN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_foreach>(@$, ast::expr(std::move($3)), std::move($5), std::move($7)); }
|
|
||||||
| FOREACH LPAREN expr_identifier COMMA expr_identifier IN expr RPAREN stmt
|
|
||||||
{ $$ = std::make_unique<ast::stmt_foreach>(@$, ast::expr(std::move($3)), ast::expr(std::move($5)), std::move($7), std::move($9)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_switch
|
|
||||||
: SWITCH LPAREN expr RPAREN stmt_block
|
|
||||||
{ $$ = std::make_unique<ast::stmt_switch>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_case
|
|
||||||
: CASE expr_integer COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_case>(@$, ast::expr(std::move($2)), std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
| CASE expr_string COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_case>(@$, ast::expr(std::move($2)), std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_default
|
|
||||||
: DEFAULT COLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_default>(@$, std::make_unique<ast::stmt_list>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_break
|
|
||||||
: BREAK SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_break>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_continue
|
|
||||||
: CONTINUE SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_continue>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_return
|
|
||||||
: RETURN expr SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_return>(@$, std::move($2)); }
|
|
||||||
| RETURN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_return>(@$, std::make_unique<ast::node>(@$)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_prof_begin
|
|
||||||
: PROFBEGIN LPAREN expr_arguments RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_prof_begin>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
stmt_prof_end
|
|
||||||
: PROFEND LPAREN expr_arguments RPAREN SEMICOLON
|
|
||||||
{ $$ = std::make_unique<ast::stmt_prof_end>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr
|
|
||||||
: expr_ternary { $$ = std::move($1); }
|
|
||||||
| expr_binary { $$ = std::move($1); }
|
|
||||||
| expr_primitive { $$ = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_or_empty
|
|
||||||
: expr { $$ = std::move($1); }
|
|
||||||
| { $$.as_node = std::make_unique<ast::node>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_assign
|
|
||||||
: expr_object ASSIGN expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_BW_EXOR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_bitwise_exor>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_LSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_shift_left>(@$, std::move($1),std::move( $3)); }
|
|
||||||
| expr_object ASSIGN_RSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_shift_right>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_ADD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_add>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_SUB expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_sub>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_MUL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_mul>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_DIV expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_div>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_object ASSIGN_MOD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_assign_mod>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_increment
|
|
||||||
: INCREMENT expr_object %prec PREINC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_increment>(@$, std::move($2), true); }
|
|
||||||
| expr_object INCREMENT %prec POSTINC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_increment>(@$, std::move($1), false); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_decrement
|
|
||||||
: DECREMENT expr_object %prec PREDEC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_decrement>(@$, std::move($2), true); }
|
|
||||||
| expr_object DECREMENT %prec POSTDEC
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_decrement>(@$, std::move($1), false); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_ternary
|
|
||||||
: expr QMARK expr COLON expr %prec TERN
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_ternary>(@$, std::move($1), std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_binary
|
|
||||||
: expr OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr EQUALITY expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_equality>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr INEQUALITY expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_inequality>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LESS_EQUAL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_less_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr GREATER_EQUAL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_greater_equal>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LESS expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_less>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr GREATER expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_greater>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_OR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_or>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_AND expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_and>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr BITWISE_EXOR expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_bitwise_exor>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr LSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_shift_left>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr RSHIFT expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_shift_right>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr ADD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_add>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr SUB expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_sub>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr MUL expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_mul>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr DIV expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_div>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr MOD expr
|
|
||||||
{ $$.as_node = std::make_unique<ast::expr_mod>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_primitive
|
|
||||||
: expr_complement { $$.as_node = std::move($1); }
|
|
||||||
| expr_negate { $$.as_node = std::move($1); }
|
|
||||||
| expr_not { $$.as_node = std::move($1); }
|
|
||||||
| expr_call { $$.as_node = std::move($1); }
|
|
||||||
| expr_method { $$.as_node = std::move($1); }
|
|
||||||
| expr_getnextarraykey { $$.as_node = std::move($1); }
|
|
||||||
| expr_getfirstarraykey { $$.as_node = std::move($1); }
|
|
||||||
| expr_getdvarcoloralpha { $$.as_node = std::move($1); }
|
|
||||||
| expr_getdvarcolorblue { $$.as_node = std::move($1); }
|
|
||||||
| expr_getdvarcolorgreen { $$.as_node = std::move($1); }
|
|
||||||
| expr_getdvarcolorred { $$.as_node = std::move($1); }
|
|
||||||
| expr_getdvarvector { $$.as_node = std::move($1); }
|
|
||||||
| expr_getdvarfloat { $$.as_node = std::move($1); }
|
|
||||||
| expr_getdvarint { $$.as_node = std::move($1); }
|
|
||||||
| expr_getdvar { $$.as_node = std::move($1); }
|
|
||||||
| expr_gettime { $$.as_node = std::move($1); }
|
|
||||||
| expr_abs { $$.as_node = std::move($1); }
|
|
||||||
| expr_vectortoangles { $$.as_node = std::move($1); }
|
|
||||||
| expr_angleclamp180 { $$.as_node = std::move($1); }
|
|
||||||
| expr_anglestoforward { $$.as_node = std::move($1); }
|
|
||||||
| expr_anglestoright { $$.as_node = std::move($1); }
|
|
||||||
| expr_anglestoup { $$.as_node = std::move($1); }
|
|
||||||
| expr_vectorscale { $$.as_node = std::move($1); }
|
|
||||||
| expr_isdefined { $$.as_node = std::move($1); }
|
|
||||||
| expr_reference { $$.as_node = std::move($1); }
|
|
||||||
| expr_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_field { $$.as_node = std::move($1); }
|
|
||||||
| expr_size { $$.as_node = std::move($1); }
|
|
||||||
| expr_paren { $$.as_node = std::move($1); }
|
|
||||||
| expr_empty_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_undefined { $$.as_node = std::move($1); }
|
|
||||||
| expr_game { $$.as_node = std::move($1); }
|
|
||||||
| expr_self { $$.as_node = std::move($1); }
|
|
||||||
| expr_anim { $$.as_node = std::move($1); }
|
|
||||||
| expr_level { $$.as_node = std::move($1); }
|
|
||||||
| expr_animation { $$.as_node = std::move($1); }
|
|
||||||
| expr_identifier { $$.as_node = std::move($1); }
|
|
||||||
| expr_istring { $$.as_node = std::move($1); }
|
|
||||||
| expr_string { $$.as_node = std::move($1); }
|
|
||||||
| expr_vector { $$.as_node = std::move($1); }
|
|
||||||
| expr_hash { $$.as_node = std::move($1); }
|
|
||||||
| expr_float { $$.as_node = std::move($1); }
|
|
||||||
| expr_integer { $$.as_node = std::move($1); }
|
|
||||||
| expr_false { $$.as_node = std::move($1); }
|
|
||||||
| expr_true { $$.as_node = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_complement
|
|
||||||
: COMPLEMENT expr
|
|
||||||
{ $$ = std::make_unique<ast::expr_complement>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_negate
|
|
||||||
: SUB expr_identifier %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_paren %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_array %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
| SUB expr_field %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_negate>(@$, ast::expr(std::move($2))); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_not
|
|
||||||
: NOT expr
|
|
||||||
{ $$ = std::make_unique<ast::expr_not>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_call
|
|
||||||
: expr_function { $$ = std::make_unique<ast::expr_call>(@$, std::move($1)); }
|
|
||||||
| expr_pointer { $$ = std::make_unique<ast::expr_call>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
expr_method
|
|
||||||
: expr_object expr_function { $$ = std::make_unique<ast::expr_method>(@$, std::move($1), std::move($2)); }
|
|
||||||
| expr_object expr_pointer { $$ = std::make_unique<ast::expr_method>(@$, std::move($1), std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_function
|
|
||||||
: expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($1), std::move($3), ast::call::mode::normal); }
|
|
||||||
| expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($1), std::move($3), std::move($5), ast::call::mode::normal); }
|
|
||||||
| THREAD expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::make_unique<ast::expr_path>(@$), std::move($2), std::move($4), ast::call::mode::thread); }
|
|
||||||
| THREAD expr_path DOUBLECOLON expr_identifier LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_function = std::make_unique<ast::expr_function>(@$, std::move($2), std::move($4), std::move($6), ast::call::mode::thread); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_pointer
|
|
||||||
: LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($3), std::move($7), ast::call::mode::normal); }
|
|
||||||
| THREAD LBRACKET LBRACKET expr RBRACKET RBRACKET LPAREN expr_arguments RPAREN
|
|
||||||
{ $$.as_pointer = std::make_unique<ast::expr_pointer>(@$, std::move($4), std::move($8), ast::call::mode::thread); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_parameters
|
|
||||||
: expr_parameters COMMA expr_identifier
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($3)); }
|
|
||||||
| expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_parameters>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::expr_parameters>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_arguments
|
|
||||||
: expr_arguments_no_empty
|
|
||||||
{ $$ = std::move($1); }
|
|
||||||
|
|
|
||||||
{ $$ = std::make_unique<ast::expr_arguments>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_arguments_no_empty
|
|
||||||
: expr_arguments COMMA expr
|
|
||||||
{ $$ = std::move($1); $$->list.push_back(std::move($3)); }
|
|
||||||
| expr
|
|
||||||
{ $$ = std::make_unique<ast::expr_arguments>(@$); $$->list.push_back(std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_getnextarraykey
|
|
||||||
: GETNEXTARRAYKEY LPAREN expr COMMA expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_getnextarraykey>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_getfirstarraykey
|
|
||||||
: GETFIRSTARRAYKEY LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_getfirstarraykey>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_getdvarcoloralpha
|
|
||||||
: GETDVARCOLORALPHA LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_getdvarcoloralpha>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_getdvarcolorblue
|
|
||||||
: GETDVARCOLORBLUE LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_getdvarcolorblue>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_getdvarcolorgreen
|
|
||||||
: GETDVARCOLORGREEN LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_getdvarcolorgreen>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_getdvarcolorred
|
|
||||||
: GETDVARCOLORRED LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_getdvarcolorred>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_getdvarvector
|
|
||||||
: GETDVARVECTOR LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_getdvarvector>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_getdvarfloat
|
|
||||||
: GETDVARFLOAT LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_getdvarfloat>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_getdvarint
|
|
||||||
: GETDVARINT LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_getdvarint>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_getdvar
|
|
||||||
: GETDVAR LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_getdvar>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_gettime
|
|
||||||
: GETTIME LPAREN RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_gettime>(@$); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_abs
|
|
||||||
: ABS LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_abs>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_vectortoangles
|
|
||||||
: VECTORTOANGLES LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_vectortoangles>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_angleclamp180
|
|
||||||
: ANGLECLAMP180 LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_angleclamp180>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_anglestoforward
|
|
||||||
: ANGLESTOFORWARD LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_anglestoforward>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_anglestoright
|
|
||||||
: ANGLESTORIGHT LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_anglestoright>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_anglestoup
|
|
||||||
: ANGLESTOUP LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_anglestoup>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_vectorscale
|
|
||||||
: VECTORSCALE LPAREN expr COMMA expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_vectorscale>(@$, std::move($3), std::move($5)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_isdefined
|
|
||||||
: ISDEFINED LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_isdefined>(@$, std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_reference
|
|
||||||
: DOUBLECOLON expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_reference>(@$, std::make_unique<ast::expr_path>(@$), std::move($2)); }
|
|
||||||
| expr_path DOUBLECOLON expr_identifier
|
|
||||||
{ $$ = std::make_unique<ast::expr_reference>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_array
|
|
||||||
: expr_object LBRACKET expr RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_array>(@$, std::move($1), std::move($3)); }
|
|
||||||
| expr_getdvarvector LBRACKET expr RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_array>(@$, ast::expr(std::move($1)), std::move($3)); }
|
|
||||||
| expr_vectortoangles LBRACKET expr RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_array>(@$, ast::expr(std::move($1)), std::move($3)); }
|
|
||||||
| expr_angleclamp180 LBRACKET expr RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_array>(@$, ast::expr(std::move($1)), std::move($3)); }
|
|
||||||
| expr_anglestoforward LBRACKET expr RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_array>(@$, ast::expr(std::move($1)), std::move($3)); }
|
|
||||||
| expr_anglestoright LBRACKET expr RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_array>(@$, ast::expr(std::move($1)), std::move($3)); }
|
|
||||||
| expr_anglestoup LBRACKET expr RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_array>(@$, ast::expr(std::move($1)), std::move($3)); }
|
|
||||||
| expr_vectorscale LBRACKET expr RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_array>(@$, ast::expr(std::move($1)), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_field
|
|
||||||
: expr_object DOT expr_identifier_nosize
|
|
||||||
{ $$ = std::make_unique<ast::expr_field>(@$, std::move($1), std::move($3)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_size
|
|
||||||
: expr_object DOT SIZE %prec SIZEOF
|
|
||||||
{ $$ = std::make_unique<ast::expr_size>(@$, std::move($1)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_paren
|
|
||||||
: LPAREN expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_paren>(@$, std::move($2)); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_object
|
|
||||||
: expr_call { $$.as_node = std::move($1); }
|
|
||||||
| expr_method { $$.as_node = std::move($1); }
|
|
||||||
| expr_array { $$.as_node = std::move($1); }
|
|
||||||
| expr_field { $$.as_node = std::move($1); }
|
|
||||||
| expr_game { $$.as_node = std::move($1); }
|
|
||||||
| expr_self { $$.as_node = std::move($1); }
|
|
||||||
| expr_anim { $$.as_node = std::move($1); }
|
|
||||||
| expr_level { $$.as_node = std::move($1); }
|
|
||||||
| expr_identifier { $$.as_node = std::move($1); }
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_empty_array
|
|
||||||
: LBRACKET RBRACKET
|
|
||||||
{ $$ = std::make_unique<ast::expr_empty_array>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_undefined
|
|
||||||
: UNDEFINED
|
|
||||||
{ $$ = std::make_unique<ast::expr_undefined>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_game
|
|
||||||
: GAME
|
|
||||||
{ $$ = std::make_unique<ast::expr_game>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_self
|
|
||||||
: SELF
|
|
||||||
{ $$ = std::make_unique<ast::expr_self>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_anim
|
|
||||||
: ANIM
|
|
||||||
{ $$ = std::make_unique<ast::expr_anim>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_level
|
|
||||||
: LEVEL
|
|
||||||
{ $$ = std::make_unique<ast::expr_level>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_animation
|
|
||||||
: MOD IDENTIFIER %prec ANIMREF
|
|
||||||
{ $$ = std::make_unique<ast::expr_animation>(@$, $2); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_identifier_nosize
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_identifier
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, $1); };
|
|
||||||
| SIZE
|
|
||||||
{ $$ = std::make_unique<ast::expr_identifier>(@$, "size"); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_path
|
|
||||||
: IDENTIFIER
|
|
||||||
{ $$ = std::make_unique<ast::expr_path>(@$, $1); };
|
|
||||||
| PATH
|
|
||||||
{ $$ = std::make_unique<ast::expr_path>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_istring
|
|
||||||
: ISTRING
|
|
||||||
{ $$ = std::make_unique<ast::expr_istring>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_string
|
|
||||||
: STRING
|
|
||||||
{ $$ = std::make_unique<ast::expr_string>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_vector
|
|
||||||
: LPAREN expr COMMA expr COMMA expr RPAREN
|
|
||||||
{ $$ = std::make_unique<ast::expr_vector>(@$, std::move($2), std::move($4), std::move($6)); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_hash
|
|
||||||
: HASH
|
|
||||||
{ $$ = std::make_unique<ast::expr_hash>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_float
|
|
||||||
: SUB FLOAT %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_float>(@$, "-" + $2); };
|
|
||||||
| FLOAT
|
|
||||||
{ $$ = std::make_unique<ast::expr_float>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_integer
|
|
||||||
: SUB INTEGER %prec NEG
|
|
||||||
{ $$ = std::make_unique<ast::expr_integer>(@$, "-" + $2); };
|
|
||||||
| INTEGER
|
|
||||||
{ $$ = std::make_unique<ast::expr_integer>(@$, $1); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_false
|
|
||||||
: FALSE
|
|
||||||
{ $$ = std::make_unique<ast::expr_false>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
expr_true
|
|
||||||
: TRUE
|
|
||||||
{ $$ = std::make_unique<ast::expr_true>(@$); };
|
|
||||||
;
|
|
||||||
|
|
||||||
%%
|
|
||||||
|
|
||||||
void xsk::arc::t6::parser::error(const xsk::arc::location& loc, const std::string& msg)
|
|
||||||
{
|
|
||||||
throw xsk::arc::comp_error(loc, msg);
|
|
||||||
}
|
|
50
include/xsk/arc/assembler.hpp
Normal file
50
include/xsk/arc/assembler.hpp
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/utils/writer.hpp"
|
||||||
|
#include "xsk/arc/common/types.hpp"
|
||||||
|
|
||||||
|
namespace xsk::arc
|
||||||
|
{
|
||||||
|
|
||||||
|
class assembler
|
||||||
|
{
|
||||||
|
context const* ctx_;
|
||||||
|
function const* func_;
|
||||||
|
assembly const* assembly_;
|
||||||
|
utils::writer script_;
|
||||||
|
utils::writer devmap_;
|
||||||
|
std::unordered_map<std::string, u16> strpool_;
|
||||||
|
std::vector<export_ref> exports_;
|
||||||
|
std::vector<import_ref> imports_;
|
||||||
|
std::vector<string_ref> strings_;
|
||||||
|
std::vector<animtree_ref> anims_;
|
||||||
|
u32 devmap_count_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
assembler(context const* ctx);
|
||||||
|
auto assemble(assembly const& data, std::string const& name = {}) -> std::pair<buffer, buffer>;
|
||||||
|
|
||||||
|
private:
|
||||||
|
auto assemble_function(function& func) -> void;
|
||||||
|
auto assemble_instruction(instruction const& inst) -> void;
|
||||||
|
auto assemble_localvars(instruction const& inst) -> void;
|
||||||
|
auto assemble_jump(instruction const& inst) -> void;
|
||||||
|
auto assemble_switch(instruction const& inst) -> void;
|
||||||
|
auto assemble_end_switch(instruction const& inst) -> void;
|
||||||
|
auto process_string(std::string const& data) -> void;
|
||||||
|
auto process_function(function const& func) -> void;
|
||||||
|
auto process_instruction(instruction const& inst) -> void;
|
||||||
|
auto align_instruction(instruction& inst) -> void;
|
||||||
|
auto resolve_label(std::string const& name) -> i32;
|
||||||
|
auto resolve_string(std::string const& name) -> u16;
|
||||||
|
void add_stringref(std::string const& str, string_type type, u32 ref);
|
||||||
|
void add_importref(std::vector<std::string> const& data, u32 ref);
|
||||||
|
void add_animref(std::vector<std::string> const& data, u32 ref);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::arc
|
215
include/xsk/arc/common/assembly.hpp
Normal file
215
include/xsk/arc/common/assembly.hpp
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace xsk::arc
|
||||||
|
{
|
||||||
|
|
||||||
|
constexpr usize opcode_count = 143;
|
||||||
|
|
||||||
|
enum class opcode : u8
|
||||||
|
{
|
||||||
|
OP_Invalid,
|
||||||
|
OP_End,
|
||||||
|
OP_Return,
|
||||||
|
OP_GetUndefined,
|
||||||
|
OP_GetZero,
|
||||||
|
OP_GetByte,
|
||||||
|
OP_GetNegByte,
|
||||||
|
OP_GetUnsignedShort,
|
||||||
|
OP_GetNegUnsignedShort,
|
||||||
|
OP_GetInteger,
|
||||||
|
OP_GetFloat,
|
||||||
|
OP_GetString,
|
||||||
|
OP_GetIString,
|
||||||
|
OP_GetVector,
|
||||||
|
OP_GetLevelObject,
|
||||||
|
OP_GetAnimObject,
|
||||||
|
OP_GetSelf,
|
||||||
|
OP_GetLevel,
|
||||||
|
OP_GetGame,
|
||||||
|
OP_GetAnim,
|
||||||
|
OP_GetAnimation,
|
||||||
|
OP_GetGameRef,
|
||||||
|
OP_GetFunction,
|
||||||
|
OP_CreateLocalVariable,
|
||||||
|
OP_SafeCreateLocalVariables,
|
||||||
|
OP_RemoveLocalVariables,
|
||||||
|
OP_EvalLocalVariableCached,
|
||||||
|
OP_EvalArray,
|
||||||
|
OP_EvalLocalArrayRefCached,
|
||||||
|
OP_EvalArrayRef,
|
||||||
|
OP_ClearArray,
|
||||||
|
OP_EmptyArray,
|
||||||
|
OP_GetSelfObject,
|
||||||
|
OP_EvalFieldVariable,
|
||||||
|
OP_EvalFieldVariableRef,
|
||||||
|
OP_ClearFieldVariable,
|
||||||
|
OP_SafeSetVariableFieldCached,
|
||||||
|
OP_SafeSetWaittillVariableFieldCached,
|
||||||
|
OP_ClearParams,
|
||||||
|
OP_CheckClearParams,
|
||||||
|
OP_EvalLocalVariableRefCached,
|
||||||
|
OP_SetVariableField,
|
||||||
|
OP_CallBuiltin,
|
||||||
|
OP_CallBuiltinMethod,
|
||||||
|
OP_Wait,
|
||||||
|
OP_WaitTillFrameEnd,
|
||||||
|
OP_PreScriptCall,
|
||||||
|
OP_ScriptFunctionCall,
|
||||||
|
OP_ScriptFunctionCallPointer,
|
||||||
|
OP_ScriptMethodCall,
|
||||||
|
OP_ScriptMethodCallPointer,
|
||||||
|
OP_ScriptThreadCall,
|
||||||
|
OP_ScriptThreadCallPointer,
|
||||||
|
OP_ScriptMethodThreadCall,
|
||||||
|
OP_ScriptMethodThreadCallPointer,
|
||||||
|
OP_DecTop,
|
||||||
|
OP_CastFieldObject,
|
||||||
|
OP_CastBool,
|
||||||
|
OP_BoolNot,
|
||||||
|
OP_BoolComplement,
|
||||||
|
OP_JumpOnFalse,
|
||||||
|
OP_JumpOnTrue,
|
||||||
|
OP_JumpOnFalseExpr,
|
||||||
|
OP_JumpOnTrueExpr,
|
||||||
|
OP_Jump,
|
||||||
|
OP_JumpBack,
|
||||||
|
OP_Inc,
|
||||||
|
OP_Dec,
|
||||||
|
OP_Bit_Or,
|
||||||
|
OP_Bit_Xor,
|
||||||
|
OP_Bit_And,
|
||||||
|
OP_Equal,
|
||||||
|
OP_NotEqual,
|
||||||
|
OP_LessThan,
|
||||||
|
OP_GreaterThan,
|
||||||
|
OP_LessThanOrEqualTo,
|
||||||
|
OP_GreaterThanOrEqualTo,
|
||||||
|
OP_ShiftLeft,
|
||||||
|
OP_ShiftRight,
|
||||||
|
OP_Plus,
|
||||||
|
OP_Minus,
|
||||||
|
OP_Multiply,
|
||||||
|
OP_Divide,
|
||||||
|
OP_Modulus,
|
||||||
|
OP_SizeOf,
|
||||||
|
OP_WaitTillMatch,
|
||||||
|
OP_WaitTill,
|
||||||
|
OP_Notify,
|
||||||
|
OP_EndOn,
|
||||||
|
OP_VoidCodePos,
|
||||||
|
OP_Switch,
|
||||||
|
OP_EndSwitch,
|
||||||
|
OP_Vector,
|
||||||
|
OP_GetHash,
|
||||||
|
OP_RealWait,
|
||||||
|
OP_VectorConstant,
|
||||||
|
OP_IsDefined,
|
||||||
|
OP_VectorScale,
|
||||||
|
OP_AnglesToUp,
|
||||||
|
OP_AnglesToRight,
|
||||||
|
OP_AnglesToForward,
|
||||||
|
OP_AngleClamp180,
|
||||||
|
OP_VectorToAngles,
|
||||||
|
OP_Abs,
|
||||||
|
OP_GetTime,
|
||||||
|
OP_GetDvar,
|
||||||
|
OP_GetDvarInt,
|
||||||
|
OP_GetDvarFloat,
|
||||||
|
OP_GetDvarVector,
|
||||||
|
OP_GetDvarColorRed,
|
||||||
|
OP_GetDvarColorGreen,
|
||||||
|
OP_GetDvarColorBlue,
|
||||||
|
OP_GetDvarColorAlpha,
|
||||||
|
OP_FirstArrayKey,
|
||||||
|
OP_NextArrayKey,
|
||||||
|
OP_ProfileStart,
|
||||||
|
OP_ProfileStop,
|
||||||
|
OP_SafeDecTop,
|
||||||
|
OP_Nop,
|
||||||
|
OP_Abort,
|
||||||
|
OP_Object,
|
||||||
|
OP_ThreadObject,
|
||||||
|
OP_EvalLocalVariable,
|
||||||
|
OP_EvalLocalVariableRef,
|
||||||
|
OP_DevblockBegin,
|
||||||
|
OP_DevblockEnd,
|
||||||
|
OP_EvalLocalVariableCachedDebug,
|
||||||
|
OP_EvalLocalVariableRefCachedDebug,
|
||||||
|
OP_LevelEvalFieldVariable,
|
||||||
|
OP_LevelEvalFieldVariableRef,
|
||||||
|
OP_SelfEvalFieldVariable,
|
||||||
|
OP_SelfEvalFieldVariableRef,
|
||||||
|
OP_GetWorld,
|
||||||
|
OP_GetWorldObject,
|
||||||
|
OP_GetClasses,
|
||||||
|
OP_GetClassesObject,
|
||||||
|
OP_New,
|
||||||
|
OP_ScriptFunctionCallClass,
|
||||||
|
OP_ScriptThreadCallClass,
|
||||||
|
OP_GetUintptr,
|
||||||
|
OP_SuperEqual,
|
||||||
|
OP_SuperNotEqual,
|
||||||
|
OP_GetAPIFunction,
|
||||||
|
OP_Count,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sourcepos
|
||||||
|
{
|
||||||
|
u16 line;
|
||||||
|
u16 column;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct instruction
|
||||||
|
{
|
||||||
|
using ptr = std::unique_ptr<instruction>;
|
||||||
|
|
||||||
|
u32 index;
|
||||||
|
u32 size;
|
||||||
|
sourcepos pos;
|
||||||
|
opcode opcode;
|
||||||
|
std::vector<std::string> data;
|
||||||
|
|
||||||
|
static auto make() -> instruction::ptr
|
||||||
|
{
|
||||||
|
return std::unique_ptr<instruction>(new instruction);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct function
|
||||||
|
{
|
||||||
|
using ptr = std::unique_ptr<function>;
|
||||||
|
|
||||||
|
u32 index;
|
||||||
|
u32 size;
|
||||||
|
u8 params;
|
||||||
|
u8 flags;
|
||||||
|
std::string name;
|
||||||
|
std::string space;
|
||||||
|
std::vector<instruction::ptr> instructions;
|
||||||
|
std::unordered_map<u32, std::string> labels;
|
||||||
|
|
||||||
|
static auto make() -> function::ptr
|
||||||
|
{
|
||||||
|
return std::unique_ptr<function>(new function);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct assembly
|
||||||
|
{
|
||||||
|
using ptr = std::unique_ptr<assembly>;
|
||||||
|
|
||||||
|
std::vector<std::string> includes;
|
||||||
|
std::vector<function::ptr> functions;
|
||||||
|
|
||||||
|
static auto make() -> assembly::ptr
|
||||||
|
{
|
||||||
|
return std::unique_ptr<assembly>(new assembly);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::arc
|
127
include/xsk/arc/common/asset.hpp
Normal file
127
include/xsk/arc/common/asset.hpp
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace xsk::arc
|
||||||
|
{
|
||||||
|
|
||||||
|
constexpr usize header_size_v1 = 64;
|
||||||
|
constexpr usize header_size_v2 = 72;
|
||||||
|
constexpr usize header_size_v3 = 0;
|
||||||
|
|
||||||
|
enum class string_type : u8
|
||||||
|
{
|
||||||
|
literal = 0,
|
||||||
|
canonical = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class param_type : u8
|
||||||
|
{
|
||||||
|
value = 0,
|
||||||
|
reference = 1,
|
||||||
|
vararg = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class export_flags : u8
|
||||||
|
{
|
||||||
|
export_none = 0x00,
|
||||||
|
export_public = 0x01,
|
||||||
|
export_autoexec = 0x02,
|
||||||
|
export_private = 0x04,
|
||||||
|
export_codecall = 0x08,
|
||||||
|
export_private2 = 0x10,
|
||||||
|
export_varargs = 0x20,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class import_flags : u8
|
||||||
|
{
|
||||||
|
none = 0,
|
||||||
|
func_reference = 1,
|
||||||
|
func_call = 2,
|
||||||
|
func_call_thread = 3,
|
||||||
|
meth_call = 4,
|
||||||
|
meth_call_thread = 5,
|
||||||
|
developer = 0x10,
|
||||||
|
unk = 0x20, // T7, T8, T9
|
||||||
|
};
|
||||||
|
|
||||||
|
struct header
|
||||||
|
{
|
||||||
|
u64 magic;
|
||||||
|
u32 source_crc;
|
||||||
|
u32 include_offset;
|
||||||
|
u32 animtree_offset;
|
||||||
|
u32 cseg_offset;
|
||||||
|
u32 stringtablefixup_offset;
|
||||||
|
u32 devblock_stringtablefixup_offset;
|
||||||
|
u32 exports_offset;
|
||||||
|
u32 imports_offset;
|
||||||
|
u32 fixup_offset;
|
||||||
|
u32 globalvar_offset;
|
||||||
|
u32 profile_offset;
|
||||||
|
u32 cseg_size;
|
||||||
|
u32 name;
|
||||||
|
u16 stringtablefixup_count;
|
||||||
|
u16 exports_count;
|
||||||
|
u16 imports_count;
|
||||||
|
u16 fixup_count;
|
||||||
|
u16 globalvar_count;
|
||||||
|
u16 profile_count;
|
||||||
|
u16 devblock_stringtablefixup_count;
|
||||||
|
u8 include_count;
|
||||||
|
u8 animtree_count;
|
||||||
|
u8 flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct animation_ref
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
u32 ref;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct animtree_ref
|
||||||
|
{
|
||||||
|
using ptr = std::shared_ptr<animtree_ref>;
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
std::vector<u32> refs;
|
||||||
|
std::vector<animation_ref> anims;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct string_ref
|
||||||
|
{
|
||||||
|
using ptr = std::shared_ptr<string_ref>;
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
u8 type;
|
||||||
|
std::vector<u32> refs;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct import_ref
|
||||||
|
{
|
||||||
|
using ptr = std::shared_ptr<import_ref>;
|
||||||
|
|
||||||
|
std::string space;
|
||||||
|
std::string name;
|
||||||
|
u8 params;
|
||||||
|
u8 flags;
|
||||||
|
std::vector<u32> refs;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct export_ref
|
||||||
|
{
|
||||||
|
using ptr = std::shared_ptr<export_ref>;
|
||||||
|
|
||||||
|
std::string space;
|
||||||
|
std::string name;
|
||||||
|
u32 checksum;
|
||||||
|
u32 offset;
|
||||||
|
u32 size;
|
||||||
|
u8 params;
|
||||||
|
u8 flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::arc
|
1374
include/xsk/arc/common/ast.hpp
Normal file
1374
include/xsk/arc/common/ast.hpp
Normal file
File diff suppressed because it is too large
Load Diff
20
include/xsk/arc/common/buffer.hpp
Normal file
20
include/xsk/arc/common/buffer.hpp
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace xsk::arc
|
||||||
|
{
|
||||||
|
|
||||||
|
struct buffer
|
||||||
|
{
|
||||||
|
u8 const* data;
|
||||||
|
usize const size;
|
||||||
|
|
||||||
|
buffer() : data{ nullptr }, size{ 0 } {}
|
||||||
|
buffer(u8 const* data, usize size) : data{ data }, size{ size } {}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::arc
|
21
include/xsk/arc/common/define.hpp
Normal file
21
include/xsk/arc/common/define.hpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace xsk::arc
|
||||||
|
{
|
||||||
|
|
||||||
|
struct define
|
||||||
|
{
|
||||||
|
enum kind : u8 { PLAIN, BUILTIN, OBJECT, FUNCTION };
|
||||||
|
|
||||||
|
kind type;
|
||||||
|
// bool vararg;
|
||||||
|
std::vector<token> args;
|
||||||
|
std::vector<token> exp;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::arc
|
20
include/xsk/arc/common/directive.hpp
Normal file
20
include/xsk/arc/common/directive.hpp
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace xsk::arc
|
||||||
|
{
|
||||||
|
|
||||||
|
struct directive
|
||||||
|
{
|
||||||
|
enum kind : u8 { IF, IFDEF, IFNDEF, ELIF, ELIFDEF, ELIFNDEF, ELSE, ENDIF, DEFINE, UNDEF, PRAGMA, WARNING, ERROR, LINE, INCLUDE, INLINE, INSERT, USINGTREE };
|
||||||
|
|
||||||
|
kind type;
|
||||||
|
bool skip;
|
||||||
|
bool exec;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::arc
|
47
include/xsk/arc/common/exception.hpp
Normal file
47
include/xsk/arc/common/exception.hpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace xsk::arc
|
||||||
|
{
|
||||||
|
|
||||||
|
class error : public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
error(std::string const& what);
|
||||||
|
};
|
||||||
|
|
||||||
|
class asm_error : public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
asm_error(std::string const& what);
|
||||||
|
};
|
||||||
|
|
||||||
|
class disasm_error : public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
disasm_error(std::string const& what);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ppr_error : public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ppr_error(location const& loc, std::string const& what);
|
||||||
|
};
|
||||||
|
|
||||||
|
class comp_error : public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
comp_error(location const& loc, std::string const& what);
|
||||||
|
};
|
||||||
|
|
||||||
|
class decomp_error : public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
decomp_error(std::string const& what);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::arc
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2022 xensik. All rights reserved.
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a GNU GPLv3 license
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
// that can be found in the LICENSE file.
|
// that can be found in the LICENSE file.
|
||||||
@ -8,20 +8,19 @@
|
|||||||
namespace xsk::arc
|
namespace xsk::arc
|
||||||
{
|
{
|
||||||
|
|
||||||
/// A point in a source file.
|
|
||||||
class position
|
class position
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Type for file name.
|
|
||||||
typedef const std::string filename_type;
|
typedef const std::string filename_type;
|
||||||
/// Type for line and column numbers.
|
typedef u16 counter_type;
|
||||||
typedef int counter_type;
|
|
||||||
|
filename_type *filename;
|
||||||
|
counter_type line;
|
||||||
|
counter_type column;
|
||||||
|
|
||||||
/// Construct a position.
|
|
||||||
explicit position(filename_type *f = nullptr, counter_type l = 1, counter_type c = 1)
|
explicit position(filename_type *f = nullptr, counter_type l = 1, counter_type c = 1)
|
||||||
: filename(f), line(l), column(c) {}
|
: filename(f), line(l), column(c) {}
|
||||||
|
|
||||||
/// Initialization.
|
|
||||||
void initialize(filename_type *fn = nullptr, counter_type l = 1, counter_type c = 1)
|
void initialize(filename_type *fn = nullptr, counter_type l = 1, counter_type c = 1)
|
||||||
{
|
{
|
||||||
filename = fn;
|
filename = fn;
|
||||||
@ -29,9 +28,6 @@ public:
|
|||||||
column = c;
|
column = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \name Line and Column related manipulators
|
|
||||||
** \{ */
|
|
||||||
/// (line related) Advance to the COUNT next lines.
|
|
||||||
void lines(counter_type count = 1)
|
void lines(counter_type count = 1)
|
||||||
{
|
{
|
||||||
if (count)
|
if (count)
|
||||||
@ -41,179 +37,131 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// (column related) Advance to the COUNT next columns.
|
|
||||||
void columns(counter_type count = 1)
|
void columns(counter_type count = 1)
|
||||||
{
|
{
|
||||||
column = add_(column, count, 1);
|
column = add_(column, count, 1);
|
||||||
}
|
}
|
||||||
/** \} */
|
|
||||||
|
|
||||||
/// File name to which this position refers.
|
|
||||||
filename_type *filename;
|
|
||||||
/// Current line number.
|
|
||||||
counter_type line;
|
|
||||||
/// Current column number.
|
|
||||||
counter_type column;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Compute max (min, lhs+rhs).
|
|
||||||
static counter_type add_(counter_type lhs, counter_type rhs, counter_type min)
|
static counter_type add_(counter_type lhs, counter_type rhs, counter_type min)
|
||||||
{
|
{
|
||||||
return lhs + rhs < min ? min : lhs + rhs;
|
return lhs + rhs < min ? min : lhs + rhs;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Add \a width columns, in place.
|
|
||||||
inline position& operator+=(position &res, position::counter_type width)
|
inline position& operator+=(position &res, position::counter_type width)
|
||||||
{
|
{
|
||||||
res.columns(width);
|
res.columns(width);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add \a width columns.
|
|
||||||
inline position operator+(position res, position::counter_type width)
|
inline position operator+(position res, position::counter_type width)
|
||||||
{
|
{
|
||||||
return res += width;
|
return res += width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Subtract \a width columns, in place.
|
|
||||||
inline position& operator-=(position &res, position::counter_type width)
|
inline position& operator-=(position &res, position::counter_type width)
|
||||||
{
|
{
|
||||||
return res += -width;
|
return res += -width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Subtract \a width columns.
|
|
||||||
inline position operator-(position res, position::counter_type width)
|
inline position operator-(position res, position::counter_type width)
|
||||||
{
|
{
|
||||||
return res -= width;
|
return res -= width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Intercept output stream redirection.
|
template <typename T>
|
||||||
** \param ostr the destination output stream
|
std::basic_ostream<T>& operator<<(std::basic_ostream<T> &ostr, const position &pos)
|
||||||
** \param pos a reference to the position to redirect
|
|
||||||
*/
|
|
||||||
template <typename YYChar>
|
|
||||||
std::basic_ostream<YYChar>& operator<<(std::basic_ostream<YYChar> &ostr, const position &pos)
|
|
||||||
{
|
{
|
||||||
if (pos.filename)
|
if (pos.filename)
|
||||||
ostr << *pos.filename << ':';
|
ostr << *pos.filename << ':';
|
||||||
return ostr << pos.line << '.' << pos.column;
|
return ostr << pos.line << '.' << pos.column;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Two points in a source file.
|
|
||||||
class location
|
class location
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Type for file name.
|
|
||||||
typedef position::filename_type filename_type;
|
typedef position::filename_type filename_type;
|
||||||
/// Type for line and column numbers.
|
|
||||||
typedef position::counter_type counter_type;
|
typedef position::counter_type counter_type;
|
||||||
|
|
||||||
/// Construct a location from \a b to \a e.
|
position begin;
|
||||||
|
position end;
|
||||||
|
|
||||||
location(const position &b, const position &e)
|
location(const position &b, const position &e)
|
||||||
: begin(b), end(e) {}
|
: begin(b), end(e) {}
|
||||||
|
|
||||||
/// Construct a 0-width location in \a p.
|
|
||||||
explicit location(const position &p = position())
|
explicit location(const position &p = position())
|
||||||
: begin(p), end(p) {}
|
: begin(p), end(p) {}
|
||||||
|
|
||||||
/// Construct a 0-width location in \a f, \a l, \a c.
|
|
||||||
explicit location(filename_type *f, counter_type l = 1, counter_type c = 1)
|
explicit location(filename_type *f, counter_type l = 1, counter_type c = 1)
|
||||||
: begin(f, l, c), end(f, l, c) {}
|
: begin(f, l, c), end(f, l, c) {}
|
||||||
|
|
||||||
/// Initialization.
|
|
||||||
void initialize(filename_type *f = nullptr, counter_type l = 1, counter_type c = 1)
|
void initialize(filename_type *f = nullptr, counter_type l = 1, counter_type c = 1)
|
||||||
{
|
{
|
||||||
begin.initialize(f, l, c);
|
begin.initialize(f, l, c);
|
||||||
end = begin;
|
end = begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \name Line and Column related manipulators
|
|
||||||
** \{ */
|
|
||||||
public:
|
|
||||||
/// Reset initial location to final location.
|
|
||||||
void step()
|
void step()
|
||||||
{
|
{
|
||||||
begin = end;
|
begin = end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extend the current location to the COUNT next columns.
|
|
||||||
void columns(counter_type count = 1)
|
void columns(counter_type count = 1)
|
||||||
{
|
{
|
||||||
end += count;
|
end += count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extend the current location to the COUNT next lines.
|
|
||||||
void lines(counter_type count = 1)
|
void lines(counter_type count = 1)
|
||||||
{
|
{
|
||||||
end.lines(count);
|
end.lines(count);
|
||||||
}
|
}
|
||||||
/** \} */
|
|
||||||
|
|
||||||
public:
|
|
||||||
auto print() const -> std::string
|
auto print() const -> std::string
|
||||||
{
|
{
|
||||||
return *begin.filename + ":" + std::to_string(begin.line) + ":" + std::to_string(begin.column);
|
return std::format("{}:{}:{}", *begin.filename, begin.line, begin.column);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto label() const -> std::string
|
auto label() const -> std::string
|
||||||
{
|
{
|
||||||
return utils::string::va("loc_%X", begin.line);
|
return std::format("loc_{:X}", begin.line);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
/// Beginning of the located region.
|
|
||||||
position begin;
|
|
||||||
/// End of the located region.
|
|
||||||
position end;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Join two locations, in place.
|
|
||||||
inline location& operator+=(location &res, const location &end)
|
inline location& operator+=(location &res, const location &end)
|
||||||
{
|
{
|
||||||
res.end = end.end;
|
res.end = end.end;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Join two locations.
|
|
||||||
inline location operator+(location res, const location &end)
|
inline location operator+(location res, const location &end)
|
||||||
{
|
{
|
||||||
return res += end;
|
return res += end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add \a width columns to the end position, in place.
|
|
||||||
inline location& operator+=(location &res, location::counter_type width)
|
inline location& operator+=(location &res, location::counter_type width)
|
||||||
{
|
{
|
||||||
res.columns(width);
|
res.columns(width);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add \a width columns to the end position.
|
|
||||||
inline location operator+(location res, location::counter_type width)
|
inline location operator+(location res, location::counter_type width)
|
||||||
{
|
{
|
||||||
return res += width;
|
return res += width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Subtract \a width columns to the end position, in place.
|
|
||||||
inline location& operator-=(location &res, location::counter_type width)
|
inline location& operator-=(location &res, location::counter_type width)
|
||||||
{
|
{
|
||||||
return res += -width;
|
return res += -width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Subtract \a width columns to the end position.
|
|
||||||
inline location operator-(location res, location::counter_type width)
|
inline location operator-(location res, location::counter_type width)
|
||||||
{
|
{
|
||||||
return res -= width;
|
return res -= width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Intercept output stream redirection.
|
template <typename T>
|
||||||
** \param ostr the destination output stream
|
std::basic_ostream<T>& operator<<(std::basic_ostream<T> &ostr, const location &loc)
|
||||||
** \param loc a reference to the location to redirect
|
|
||||||
**
|
|
||||||
** Avoid duplicate information.
|
|
||||||
*/
|
|
||||||
template <typename YYChar>
|
|
||||||
std::basic_ostream<YYChar>& operator<<(std::basic_ostream<YYChar> &ostr, const location &loc)
|
|
||||||
{
|
{
|
||||||
location::counter_type end_col = 0 < loc.end.column ? loc.end.column - 1 : 0;
|
location::counter_type end_col = 0 < loc.end.column ? loc.end.column - 1 : 0;
|
||||||
ostr << loc.begin;
|
ostr << loc.begin;
|
23
include/xsk/arc/common/lookahead.hpp
Normal file
23
include/xsk/arc/common/lookahead.hpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace xsk::arc
|
||||||
|
{
|
||||||
|
|
||||||
|
struct lookahead
|
||||||
|
{
|
||||||
|
char const* buffer_pos;
|
||||||
|
usize available;
|
||||||
|
char last_byte;
|
||||||
|
char curr_byte;
|
||||||
|
|
||||||
|
lookahead(char const* data, usize size);
|
||||||
|
auto advance() -> void;
|
||||||
|
auto ended() { return available == 0; };
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::arc
|
33
include/xsk/arc/common/scope.hpp
Normal file
33
include/xsk/arc/common/scope.hpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace xsk::arc
|
||||||
|
{
|
||||||
|
|
||||||
|
struct scope
|
||||||
|
{
|
||||||
|
using ptr = std::unique_ptr<scope>;
|
||||||
|
|
||||||
|
enum abort_type
|
||||||
|
{
|
||||||
|
abort_none = 0,
|
||||||
|
abort_continue = 1,
|
||||||
|
abort_break = 2,
|
||||||
|
abort_return = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string end;
|
||||||
|
std::string cnt;
|
||||||
|
std::string brk;
|
||||||
|
abort_type abort;
|
||||||
|
bool is_dev;
|
||||||
|
|
||||||
|
scope() : abort(abort_type::abort_none), is_dev(false) {}
|
||||||
|
scope(std::string const& brk, std::string const& cnt) : cnt{ cnt }, brk{ brk }, abort(abort_type::abort_none), is_dev(false) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::arc
|
19
include/xsk/arc/common/space.hpp
Normal file
19
include/xsk/arc/common/space.hpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace xsk::arc
|
||||||
|
{
|
||||||
|
|
||||||
|
enum class spacing : u8
|
||||||
|
{
|
||||||
|
none = 0, // no space between tokens
|
||||||
|
null = 1, // token just after new line
|
||||||
|
back = 2, // token after space
|
||||||
|
empty = 4, // token after new line + space
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::arc
|
43
include/xsk/arc/common/token.hpp
Normal file
43
include/xsk/arc/common/token.hpp
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace xsk::arc
|
||||||
|
{
|
||||||
|
|
||||||
|
struct token
|
||||||
|
{
|
||||||
|
enum kind : u8
|
||||||
|
{
|
||||||
|
PLUS, MINUS, STAR, DIV, MOD, BITOR, BITAND, BITEXOR, SHL, SHR,
|
||||||
|
ASSIGN, PLUSEQ, MINUSEQ, STAREQ, DIVEQ, MODEQ, BITOREQ, BITANDEQ, BITEXOREQ, SHLEQ, SHREQ,
|
||||||
|
INC, DEC, GT, LT, GE, LE, NE, EQ, OR, AND, TILDE, BANG, QMARK, COLON, SHARP, COMMA, DOT,
|
||||||
|
DOUBLEDOT, ELLIPSIS, SEMICOLON, DOUBLECOLON, LBRACKET, RBRACKET, LBRACE, RBRACE, LPAREN, RPAREN,
|
||||||
|
|
||||||
|
NAME, PATH, STRING, ISTRING, HASHSTR, INT, FLT,
|
||||||
|
|
||||||
|
DEVBEGIN, DEVEND, INLINE, INCLUDE, USINGTREE, ANIMTREE, AUTOEXEC, CODECALL, PRIVATE,
|
||||||
|
ENDON, NOTIFY, WAIT, WAITREALTIME, WAITTILL, WAITTILLMATCH, WAITTILLFRAMEEND, IF, ELSE,
|
||||||
|
DO, WHILE, FOR, FOREACH, IN, SWITCH, CASE, DEFAULT, BREAK, CONTINUE, RETURN, PROFBEGIN,
|
||||||
|
PROFEND, THREAD, TRUE, FALSE, UNDEFINED, SIZE, GAME, SELF, ANIM, LEVEL,
|
||||||
|
CONST, ISDEFINED, VECTORSCALE, ANGLESTOUP, ANGLESTORIGHT, ANGLESTOFORWARD, ANGLECLAMP180,
|
||||||
|
VECTORTOANGLES, ABS, GETTIME, GETDVAR, GETDVARINT, GETDVARFLOAT, GETDVARVECTOR, GETDVARCOLORRED,
|
||||||
|
GETDVARCOLORGREEN, GETDVARCOLORBLUE, GETDVARCOLORALPHA, GETFIRSTARRAYKEY, GETNEXTARRAYKEY,
|
||||||
|
|
||||||
|
HASH, NEWLINE, EOS, DEFINED, MACROBEGIN, MACROEND, MACROARG, MACROVAOPT, MACROVAARGS, STRINGIZE, PASTE
|
||||||
|
};
|
||||||
|
|
||||||
|
kind type;
|
||||||
|
spacing space;
|
||||||
|
location pos;
|
||||||
|
std::string data;
|
||||||
|
|
||||||
|
token(kind type, spacing space, location pos) : type{ type }, space{ space }, pos{ pos }, data{} {}
|
||||||
|
token(kind type, spacing space, location pos, std::string data) : type{ type }, space{ space }, pos{ pos }, data{ std::move(data) } {}
|
||||||
|
auto to_string() -> std::string;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::arc
|
127
include/xsk/arc/common/types.hpp
Normal file
127
include/xsk/arc/common/types.hpp
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/arc/common/asset.hpp"
|
||||||
|
#include "xsk/arc/common/assembly.hpp"
|
||||||
|
#include "xsk/arc/common/buffer.hpp"
|
||||||
|
#include "xsk/arc/common/location.hpp"
|
||||||
|
#include "xsk/arc/common/exception.hpp"
|
||||||
|
#include "xsk/arc/common/lookahead.hpp"
|
||||||
|
#include "xsk/arc/common/directive.hpp"
|
||||||
|
#include "xsk/arc/common/scope.hpp"
|
||||||
|
#include "xsk/arc/common/space.hpp"
|
||||||
|
#include "xsk/arc/common/token.hpp"
|
||||||
|
#include "xsk/arc/common/define.hpp"
|
||||||
|
#include "xsk/arc/common/ast.hpp"
|
||||||
|
|
||||||
|
namespace xsk::arc
|
||||||
|
{
|
||||||
|
|
||||||
|
enum class instance : u8
|
||||||
|
{
|
||||||
|
server,
|
||||||
|
client,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class build : u8
|
||||||
|
{
|
||||||
|
prod = 0,
|
||||||
|
dev_blocks = 1 << 0,
|
||||||
|
dev_maps = 1 << 1,
|
||||||
|
dev = dev_blocks | dev_maps,
|
||||||
|
};
|
||||||
|
|
||||||
|
inline build operator&(build lhs, build rhs)
|
||||||
|
{
|
||||||
|
return static_cast<build>(static_cast<std::underlying_type<build>::type>(lhs) & static_cast<std::underlying_type<build>::type>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class endian : u8
|
||||||
|
{
|
||||||
|
little,
|
||||||
|
big,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class system : u8
|
||||||
|
{
|
||||||
|
pc,
|
||||||
|
ps3,
|
||||||
|
ps4,
|
||||||
|
ps5,
|
||||||
|
xb2,
|
||||||
|
xb3,
|
||||||
|
xb4,
|
||||||
|
wiiu,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class engine : u8
|
||||||
|
{
|
||||||
|
t6,
|
||||||
|
t7,
|
||||||
|
t8,
|
||||||
|
t9,
|
||||||
|
jup
|
||||||
|
};
|
||||||
|
|
||||||
|
struct props
|
||||||
|
{
|
||||||
|
enum values : u32
|
||||||
|
{
|
||||||
|
none = 0,
|
||||||
|
v2 = 1 << 0,
|
||||||
|
v3 = 1 << 1,
|
||||||
|
header64 = 1 << 2,
|
||||||
|
header72 = 1 << 3,
|
||||||
|
headerxx = 1 << 4,
|
||||||
|
size64 = 1 << 5,
|
||||||
|
hashids = 1 << 6,
|
||||||
|
devstr = 1 << 7,
|
||||||
|
spaces = 1 << 8,
|
||||||
|
globals = 1 << 9,
|
||||||
|
refvarg = 1 << 10,
|
||||||
|
foreach = 1 << 11,
|
||||||
|
};
|
||||||
|
|
||||||
|
props(values value) : value_(value) {}
|
||||||
|
operator values() { return value_; }
|
||||||
|
operator bool() { return value_ != values::none; }
|
||||||
|
props::values operator|(props::values rhs) const { return static_cast<props::values>(value_ | rhs); }
|
||||||
|
props::values operator&(props::values rhs) const { return static_cast<props::values>(value_ & rhs); }
|
||||||
|
|
||||||
|
friend props::values operator|(props::values lhs, props::values rhs)
|
||||||
|
{
|
||||||
|
return static_cast<props::values>(static_cast<std::underlying_type<props::values>::type>(lhs) | static_cast<std::underlying_type<props::values>::type>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend props::values operator&(props::values lhs, props::values rhs)
|
||||||
|
{
|
||||||
|
return static_cast<props::values>(static_cast<std::underlying_type<props::values>::type>(lhs) & static_cast<std::underlying_type<props::values>::type>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
values value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class switch_type
|
||||||
|
{
|
||||||
|
none,
|
||||||
|
integer,
|
||||||
|
string,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct locjmp
|
||||||
|
{
|
||||||
|
std::string end;
|
||||||
|
std::string cnt;
|
||||||
|
std::string brk;
|
||||||
|
bool is_dev;
|
||||||
|
};
|
||||||
|
|
||||||
|
// fordward decl for modules ref
|
||||||
|
class context;
|
||||||
|
|
||||||
|
} // namespace xsk::arc
|
155
include/xsk/arc/compiler.hpp
Normal file
155
include/xsk/arc/compiler.hpp
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/arc/common/types.hpp"
|
||||||
|
|
||||||
|
namespace xsk::arc
|
||||||
|
{
|
||||||
|
|
||||||
|
class compiler
|
||||||
|
{
|
||||||
|
context* ctx_;
|
||||||
|
assembly::ptr assembly_;
|
||||||
|
function::ptr function_;
|
||||||
|
std::vector<std::string> localfuncs_;
|
||||||
|
std::vector<std::string> stackframe_;
|
||||||
|
std::vector<scope> scopes_;
|
||||||
|
std::unordered_map<std::string, expr const*> constants_;
|
||||||
|
std::string animtree_;
|
||||||
|
sourcepos debug_pos_;
|
||||||
|
u32 index_;
|
||||||
|
u32 label_idx_;
|
||||||
|
bool can_break_;
|
||||||
|
bool can_continue_;
|
||||||
|
bool developer_thread_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
compiler(context* ctx);
|
||||||
|
auto compile(program const& data) -> assembly::ptr;
|
||||||
|
auto compile(std::string const& file, std::vector<u8>& data) -> assembly::ptr;
|
||||||
|
|
||||||
|
private:
|
||||||
|
auto emit_program(program const& prog) -> void;
|
||||||
|
auto emit_include(include const& inc) -> void;
|
||||||
|
auto emit_decl(decl const& dec) -> void;
|
||||||
|
auto emit_decl_usingtree(decl_usingtree const& animtree) -> void;
|
||||||
|
auto emit_decl_function(decl_function const& func) -> void;
|
||||||
|
auto emit_stmt(stmt const& stm) -> void;
|
||||||
|
auto emit_stmt_list(stmt_list const& stm) -> void;
|
||||||
|
auto emit_stmt_comp(stmt_comp const& stm) -> void;
|
||||||
|
auto emit_stmt_dev(stmt_dev const& stm) -> void;
|
||||||
|
auto emit_stmt_expr(stmt_expr const& stm) -> void;
|
||||||
|
auto emit_stmt_endon(stmt_endon const& stm) -> void;
|
||||||
|
auto emit_stmt_notify(stmt_notify const& stm) -> void;
|
||||||
|
auto emit_stmt_wait(stmt_wait const& stm) -> void;
|
||||||
|
auto emit_stmt_waitrealtime(stmt_waitrealtime const& stm) -> void;
|
||||||
|
auto emit_stmt_waittill(stmt_waittill const& stm) -> void;
|
||||||
|
auto emit_stmt_waittillmatch(stmt_waittillmatch const& stm) -> void;
|
||||||
|
auto emit_stmt_waittillframeend(stmt_waittillframeend const& stm) -> void;
|
||||||
|
auto emit_stmt_if(stmt_if const& stm) -> void;
|
||||||
|
auto emit_stmt_ifelse(stmt_ifelse const& stm) -> void;
|
||||||
|
auto emit_stmt_while(stmt_while const& stm) -> void;
|
||||||
|
auto emit_stmt_dowhile(stmt_dowhile const& stm) -> void;
|
||||||
|
auto emit_stmt_for(stmt_for const& stm) -> void;
|
||||||
|
auto emit_stmt_foreach(stmt_foreach const& stm) -> void;
|
||||||
|
auto emit_stmt_switch(stmt_switch const& stm) -> void;
|
||||||
|
auto emit_stmt_case(stmt_case const& stm) -> void;
|
||||||
|
auto emit_stmt_default(stmt_default const& stm) -> void;
|
||||||
|
auto emit_stmt_break(stmt_break const& stm) -> void;
|
||||||
|
auto emit_stmt_continue(stmt_continue const& stm) -> void;
|
||||||
|
auto emit_stmt_return(stmt_return const& stm) -> void;
|
||||||
|
auto emit_stmt_breakpoint(stmt_breakpoint const& stm) -> void;
|
||||||
|
auto emit_stmt_prof_begin(stmt_prof_begin const& stm) -> void;
|
||||||
|
auto emit_stmt_prof_end(stmt_prof_end const& stm) -> void;
|
||||||
|
auto emit_expr(expr const& exp) -> void;
|
||||||
|
auto emit_expr_const(expr_const const& exp) -> void;
|
||||||
|
auto emit_expr_assign(expr_assign const& exp) -> void;
|
||||||
|
auto emit_expr_clear(expr const& exp) -> void;
|
||||||
|
auto emit_expr_clear_local(expr_identifier const& exp) -> void;
|
||||||
|
auto emit_expr_increment(expr_increment const& exp, bool is_stmt) -> void;
|
||||||
|
auto emit_expr_decrement(expr_decrement const& exp, bool is_stmt) -> void;
|
||||||
|
auto emit_expr_ternary(expr_ternary const& exp) -> void;
|
||||||
|
auto emit_expr_binary(expr_binary const& exp) -> void;
|
||||||
|
auto emit_expr_complement(expr_complement const& exp) -> void;
|
||||||
|
auto emit_expr_negate(expr_negate const& exp) -> void;
|
||||||
|
auto emit_expr_not(expr_not const& exp) -> void;
|
||||||
|
auto emit_expr_call(expr_call const& exp, bool is_stmt) -> void;
|
||||||
|
auto emit_expr_call_pointer(expr_pointer const& exp, bool is_stmt) -> void;
|
||||||
|
auto emit_expr_call_function(expr_function const& exp, bool is_stmt) -> void;
|
||||||
|
auto emit_expr_method(expr_method const& exp, bool is_stmt) -> void;
|
||||||
|
auto emit_expr_method_pointer(expr_pointer const& exp, expr const& obj, bool is_stmt) -> void;
|
||||||
|
auto emit_expr_method_function(expr_function const& exp, expr const& obj, bool is_stmt) -> void;
|
||||||
|
auto emit_expr_parameters(expr_parameters const& exp) -> void;
|
||||||
|
auto emit_expr_arguments(expr_arguments const& exp) -> void;
|
||||||
|
auto emit_expr_isdefined(expr_isdefined const& exp) -> void;
|
||||||
|
auto emit_expr_vectorscale(expr_vectorscale const& exp) -> void;
|
||||||
|
auto emit_expr_anglestoup(expr_anglestoup const& exp) -> void;
|
||||||
|
auto emit_expr_anglestoright(expr_anglestoright const& exp) -> void;
|
||||||
|
auto emit_expr_anglestoforward(expr_anglestoforward const& exp) -> void;
|
||||||
|
auto emit_expr_angleclamp180(expr_angleclamp180 const& exp) -> void;
|
||||||
|
auto emit_expr_vectortoangles(expr_vectortoangles const& exp) -> void;
|
||||||
|
auto emit_expr_abs(expr_abs const& exp) -> void;
|
||||||
|
auto emit_expr_gettime(expr_gettime const& exp) -> void;
|
||||||
|
auto emit_expr_getdvar(expr_getdvar const& exp) -> void;
|
||||||
|
auto emit_expr_getdvarint(expr_getdvarint const& exp) -> void;
|
||||||
|
auto emit_expr_getdvarfloat(expr_getdvarfloat const& exp) -> void;
|
||||||
|
auto emit_expr_getdvarvector(expr_getdvarvector const& exp) -> void;
|
||||||
|
auto emit_expr_getdvarcolorred(expr_getdvarcolorred const& exp) -> void;
|
||||||
|
auto emit_expr_getdvarcolorgreen(expr_getdvarcolorgreen const& exp) -> void;
|
||||||
|
auto emit_expr_getdvarcolorblue(expr_getdvarcolorblue const& exp) -> void;
|
||||||
|
auto emit_expr_getdvarcoloralpha(expr_getdvarcoloralpha const& exp) -> void;
|
||||||
|
auto emit_expr_getfirstarraykey(expr_getfirstarraykey const& exp) -> void;
|
||||||
|
auto emit_expr_getnextarraykey(expr_getnextarraykey const& exp) -> void;
|
||||||
|
auto emit_expr_reference(expr_reference const& exp) -> void;
|
||||||
|
auto emit_expr_size(expr_size const& exp) -> void;
|
||||||
|
auto emit_expr_variable_ref(expr const& exp, bool set) -> void;
|
||||||
|
auto emit_expr_array_ref(expr_array const& exp, bool set) -> void;
|
||||||
|
auto emit_expr_field_ref(expr_field const& exp, bool set) -> void;
|
||||||
|
auto emit_expr_local_ref(expr_identifier const& exp, bool set) -> void;
|
||||||
|
auto emit_expr_variable(expr const& exp) -> void;
|
||||||
|
auto emit_expr_array(expr_array const& exp) -> void;
|
||||||
|
auto emit_expr_field(expr_field const& exp) -> void;
|
||||||
|
auto emit_expr_local(expr_identifier const& exp) -> void;
|
||||||
|
auto emit_expr_object(expr const& exp) -> void;
|
||||||
|
auto emit_expr_vector(expr_vector const& exp) -> void;
|
||||||
|
auto emit_expr_animation(expr_animation const& exp) -> void;
|
||||||
|
auto emit_expr_animtree(expr_animtree const& exp) -> void;
|
||||||
|
auto emit_expr_istring(expr_istring const& exp) -> void;
|
||||||
|
auto emit_expr_string(expr_string const& exp) -> void;
|
||||||
|
auto emit_expr_hash(expr_hash const& exp) -> void;
|
||||||
|
auto emit_expr_float(expr_float const& exp) -> void;
|
||||||
|
auto emit_expr_integer(expr_integer const& exp) -> void;
|
||||||
|
auto emit_expr_false(expr_false const& exp) -> void;
|
||||||
|
auto emit_expr_true(expr_true const& exp) -> void;
|
||||||
|
auto emit_opcode(opcode op) -> void;
|
||||||
|
auto emit_opcode(opcode op, std::string const& data) -> void;
|
||||||
|
auto emit_opcode(opcode op, std::vector<std::string> const& data) -> void;
|
||||||
|
auto process_function(decl_function const& func) -> void;
|
||||||
|
auto process_stmt(stmt const& stm) -> void;
|
||||||
|
auto process_stmt_list(stmt_list const& stm) -> void;
|
||||||
|
auto process_stmt_comp(stmt_comp const& stm) -> void;
|
||||||
|
auto process_stmt_dev(stmt_dev const& stm) -> void;
|
||||||
|
auto process_stmt_expr(stmt_expr const& stm) -> void;
|
||||||
|
auto process_stmt_waittill(stmt_waittill const& stm) -> void;
|
||||||
|
auto process_stmt_if(stmt_if const& stm) -> void;
|
||||||
|
auto process_stmt_ifelse(stmt_ifelse const& stm) -> void;
|
||||||
|
auto process_stmt_while(stmt_while const& stm) -> void;
|
||||||
|
auto process_stmt_dowhile(stmt_dowhile const& stm) -> void;
|
||||||
|
auto process_stmt_for(stmt_for const& stm) -> void;
|
||||||
|
auto process_stmt_foreach(stmt_foreach const& stm) -> void;
|
||||||
|
auto process_stmt_switch(stmt_switch const& stm) -> void;
|
||||||
|
auto process_expr(expr const& exp) -> void;
|
||||||
|
auto process_expr_parameters(expr_parameters const& exp) -> void;
|
||||||
|
auto variable_register(expr_identifier const& exp) -> void;
|
||||||
|
auto variable_access(expr_identifier const& exp) -> u8;
|
||||||
|
auto is_constant_condition(expr const& exp) -> bool;
|
||||||
|
auto insert_label(std::string const& label) -> void;
|
||||||
|
auto insert_label() -> std::string;
|
||||||
|
auto create_label() -> std::string;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::arc
|
75
include/xsk/arc/context.hpp
Normal file
75
include/xsk/arc/context.hpp
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/arc/common/types.hpp"
|
||||||
|
#include "xsk/arc/source.hpp"
|
||||||
|
#include "xsk/arc/assembler.hpp"
|
||||||
|
#include "xsk/arc/disassembler.hpp"
|
||||||
|
#include "xsk/arc/compiler.hpp"
|
||||||
|
#include "xsk/arc/decompiler.hpp"
|
||||||
|
|
||||||
|
namespace xsk::arc
|
||||||
|
{
|
||||||
|
|
||||||
|
class context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using fs_callback = std::function<std::vector<u8>(std::string const&)>;
|
||||||
|
|
||||||
|
context(props props, engine engine, endian endian, system system, u64 magic);
|
||||||
|
|
||||||
|
auto props() const -> props { return props_; }
|
||||||
|
auto build() const -> build { return build_; }
|
||||||
|
auto engine() const -> engine { return engine_; }
|
||||||
|
auto endian() const -> endian { return endian_; }
|
||||||
|
auto system() const -> system { return system_; }
|
||||||
|
auto instance() const -> instance { return instance_; }
|
||||||
|
auto magic() const -> u64 { return magic_; }
|
||||||
|
auto source() -> source& { return source_; }
|
||||||
|
auto assembler() -> assembler& { return assembler_; }
|
||||||
|
auto disassembler() -> disassembler& { return disassembler_; }
|
||||||
|
auto compiler() -> compiler& { return compiler_; }
|
||||||
|
auto decompiler() -> decompiler& { return decompiler_; }
|
||||||
|
|
||||||
|
auto init(arc::build build, fs_callback callback) -> void;
|
||||||
|
auto cleanup() -> void;
|
||||||
|
auto engine_name() const -> std::string_view;
|
||||||
|
|
||||||
|
auto opcode_size(opcode op) const -> u32;
|
||||||
|
auto opcode_id(opcode op) const -> u16;
|
||||||
|
auto opcode_name(opcode op) const -> std::string;
|
||||||
|
auto opcode_enum(std::string const& name) const -> opcode;
|
||||||
|
auto opcode_enum(u16 id) const -> opcode;
|
||||||
|
auto hash_id(std::string const& name) const -> u32;
|
||||||
|
auto hash_name(u32 id) const -> std::string;
|
||||||
|
auto make_token(std::string_view str) const -> std::string;
|
||||||
|
auto load_header(std::string const& name) -> std::tuple<std::string const*, char const*, usize>;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
arc::props props_;
|
||||||
|
arc::build build_;
|
||||||
|
arc::engine engine_;
|
||||||
|
arc::endian endian_;
|
||||||
|
arc::system system_;
|
||||||
|
arc::instance instance_;
|
||||||
|
u64 magic_;
|
||||||
|
arc::source source_;
|
||||||
|
arc::assembler assembler_;
|
||||||
|
arc::disassembler disassembler_;
|
||||||
|
arc::compiler compiler_;
|
||||||
|
arc::decompiler decompiler_;
|
||||||
|
|
||||||
|
fs_callback fs_callback_;
|
||||||
|
std::unordered_map<opcode, std::string_view> opcode_map_;
|
||||||
|
std::unordered_map<std::string_view, opcode> opcode_map_rev_;
|
||||||
|
std::unordered_map<u16, opcode> code_map_;
|
||||||
|
std::unordered_map<opcode, u16> code_map_rev_;
|
||||||
|
std::unordered_map<u32, std::string_view> hash_map_;
|
||||||
|
std::unordered_map<std::string, std::vector<u8>> header_files_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::arc
|
106
include/xsk/arc/decompiler.hpp
Normal file
106
include/xsk/arc/decompiler.hpp
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/arc/common/types.hpp"
|
||||||
|
|
||||||
|
namespace xsk::arc
|
||||||
|
{
|
||||||
|
|
||||||
|
class decompiler
|
||||||
|
{
|
||||||
|
context const* ctx_;
|
||||||
|
program::ptr program_;
|
||||||
|
decl_function::ptr func_;
|
||||||
|
std::unordered_set<std::string> vars_;
|
||||||
|
std::unordered_map<u32, std::string> labels_;
|
||||||
|
std::vector<std::string> expr_labels_;
|
||||||
|
std::vector<std::string> tern_labels_;
|
||||||
|
std::vector<std::string> locals_;
|
||||||
|
std::vector<param_type> params_;
|
||||||
|
std::stack<node::ptr> stack_;
|
||||||
|
std::string namespace_;
|
||||||
|
locjmp locs_;
|
||||||
|
bool in_waittill_;
|
||||||
|
bool retbool_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
decompiler(context const* ctx);
|
||||||
|
auto decompile(assembly const& data) -> program::ptr;
|
||||||
|
|
||||||
|
private:
|
||||||
|
auto decompile_function(function const& func) -> void;
|
||||||
|
auto decompile_instruction(instruction const& inst, bool last) -> void;
|
||||||
|
auto decompile_expressions(instruction const& inst) -> void;
|
||||||
|
auto decompile_statements(stmt_list& stm) -> void;
|
||||||
|
auto decompile_infinites(stmt_list& stm) -> void;
|
||||||
|
auto decompile_loops(stmt_list& stm) -> void;
|
||||||
|
auto decompile_switches(stmt_list& stm) -> void;
|
||||||
|
auto decompile_ifelses(stmt_list& stm) -> void;
|
||||||
|
auto decompile_aborts(stmt_list& stm) -> void;
|
||||||
|
auto decompile_devblocks(stmt_list& stm) -> void;
|
||||||
|
auto decompile_if(stmt_list& stm, usize begin, usize end) -> void;
|
||||||
|
auto decompile_ifelse(stmt_list& stm, usize begin, usize end) -> void;
|
||||||
|
auto decompile_inf(stmt_list& stm, usize begin, usize end) -> void;
|
||||||
|
auto decompile_loop(stmt_list& stm, usize begin, usize end) -> void;
|
||||||
|
auto decompile_while(stmt_list& stm, usize begin, usize end) -> void;
|
||||||
|
auto decompile_dowhile(stmt_list& stm, usize begin, usize end) -> void;
|
||||||
|
auto decompile_for(stmt_list& stm, usize begin, usize end) -> void;
|
||||||
|
auto decompile_foreach(stmt_list& stm, usize begin, usize end) -> void;
|
||||||
|
auto decompile_switch(stmt_list& stm, usize begin, usize end) -> void;
|
||||||
|
auto find_location_reference(stmt_list const& stm, usize begin, usize end, std::string const& loc) -> bool;
|
||||||
|
auto find_location_index(stmt_list const& stm, std::string const& loc) -> usize;
|
||||||
|
auto last_location_index(stmt_list const& stm, usize index) -> bool;
|
||||||
|
auto lvalues_match(stmt_expr const& stm1, stmt_expr const& stm2) -> bool;
|
||||||
|
auto resolve_label(std::string const& name) -> u32;
|
||||||
|
auto process_function(decl_function& func) -> void;
|
||||||
|
auto process_stmt(stmt& stm) -> void;
|
||||||
|
auto process_stmt_list(stmt_list& stm) -> void;
|
||||||
|
auto process_stmt_comp(stmt_comp& stm) -> void;
|
||||||
|
auto process_stmt_dev(stmt_dev& stm) -> void;
|
||||||
|
auto process_stmt_expr(stmt_expr& stm) -> void;
|
||||||
|
auto process_stmt_endon(stmt_endon& stm) -> void;
|
||||||
|
auto process_stmt_notify(stmt_notify& stm) -> void;
|
||||||
|
auto process_stmt_wait(stmt_wait& stm) -> void;
|
||||||
|
auto process_stmt_waitrealtime(stmt_waitrealtime& stm) -> void;
|
||||||
|
auto process_stmt_waittill(stmt_waittill& stm) -> void;
|
||||||
|
auto process_stmt_waittillmatch(stmt_waittillmatch& stm) -> void;
|
||||||
|
auto process_stmt_if(stmt_if& stm) -> void;
|
||||||
|
auto process_stmt_ifelse(stmt_ifelse& stm) -> void;
|
||||||
|
auto process_stmt_while(stmt_while& stm) -> void;
|
||||||
|
auto process_stmt_dowhile(stmt_dowhile& stm) -> void;
|
||||||
|
auto process_stmt_for(stmt_for& stm) -> void;
|
||||||
|
auto process_stmt_foreach(stmt_foreach& stm) -> void;
|
||||||
|
auto process_stmt_switch(stmt_switch& stm) -> void;
|
||||||
|
auto process_stmt_break(stmt_break& stm) -> void;
|
||||||
|
auto process_stmt_continue(stmt_continue& stm) -> void;
|
||||||
|
auto process_stmt_return(stmt_return& stm) -> void;
|
||||||
|
auto process_expr(expr::ptr& exp) -> void;
|
||||||
|
auto process_expr_increment(expr_increment& exp) -> void;
|
||||||
|
auto process_expr_decrement(expr_decrement& exp) -> void;
|
||||||
|
auto process_expr_assign(expr_assign::ptr& exp) -> void;
|
||||||
|
auto process_expr_ternary(expr_ternary& exp) -> void;
|
||||||
|
auto process_expr_binary(expr_binary& exp) -> void;
|
||||||
|
auto process_expr_complement(expr_complement& exp) -> void;
|
||||||
|
auto process_expr_not(expr_not& exp) -> void;
|
||||||
|
auto process_expr_call(expr_call& exp) -> void;
|
||||||
|
auto process_expr_method(expr_method& exp) -> void;
|
||||||
|
auto process_expr_call_member(expr_member& exp) -> void;
|
||||||
|
auto process_expr_call_pointer(expr_pointer& exp) -> void;
|
||||||
|
auto process_expr_call_function(expr_function& exp) -> void;
|
||||||
|
auto process_expr_method_pointer(expr_pointer& exp, expr::ptr& obj) -> void;
|
||||||
|
auto process_expr_method_function(expr_function& exp, expr::ptr& obj) -> void;
|
||||||
|
auto process_expr_parameters(expr_parameters& exp) -> void;
|
||||||
|
auto process_expr_arguments(expr_arguments& exp) -> void;
|
||||||
|
auto process_expr_reference(expr_reference& exp) -> void;
|
||||||
|
auto process_expr_array(expr_array& exp) -> void;
|
||||||
|
auto process_expr_field(expr_field& exp) -> void;
|
||||||
|
auto process_expr_size(expr_size& exp) -> void;
|
||||||
|
auto process_expr_vector(expr_vector& exp) -> void;
|
||||||
|
auto process_expr_identifier(expr_identifier& exp) -> void;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::arc
|
44
include/xsk/arc/disassembler.hpp
Normal file
44
include/xsk/arc/disassembler.hpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/utils/reader.hpp"
|
||||||
|
#include "xsk/arc/common/types.hpp"
|
||||||
|
|
||||||
|
namespace xsk::arc
|
||||||
|
{
|
||||||
|
|
||||||
|
class disassembler
|
||||||
|
{
|
||||||
|
context const* ctx_;
|
||||||
|
function::ptr func_;
|
||||||
|
assembly::ptr assembly_;
|
||||||
|
utils::reader script_;
|
||||||
|
std::map<u32, import_ref::ptr> import_refs_;
|
||||||
|
std::map<u32, string_ref::ptr> string_refs_;
|
||||||
|
std::map<u32, animtree_ref::ptr> anim_refs_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
disassembler(context const* ctx);
|
||||||
|
auto disassemble(buffer const& data) -> assembly::ptr;
|
||||||
|
auto disassemble(std::vector<u8> const& data) -> assembly::ptr;
|
||||||
|
auto disassemble(u8 const* data, usize data_size) -> assembly::ptr;
|
||||||
|
|
||||||
|
private:
|
||||||
|
auto disassemble_function(function& func) -> void;
|
||||||
|
auto disassemble_instruction(instruction& inst) -> void;
|
||||||
|
auto disassemble_name(instruction& inst) -> void;
|
||||||
|
auto disassemble_params(instruction& inst) -> void;
|
||||||
|
auto disassemble_import(instruction& inst) -> void;
|
||||||
|
auto disassemble_string(instruction& inst) -> void;
|
||||||
|
auto disassemble_animtree(instruction& inst) -> void;
|
||||||
|
auto disassemble_animation(instruction& inst) -> void;
|
||||||
|
auto disassemble_jump(instruction& inst) -> void;
|
||||||
|
auto disassemble_switch(instruction& inst) -> void;
|
||||||
|
auto disassemble_end_switch(instruction& inst) -> void;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::arc
|
24
include/xsk/arc/engine/jup.hpp
Normal file
24
include/xsk/arc/engine/jup.hpp
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/stdinc.hpp"
|
||||||
|
#include "xsk/arc/context.hpp"
|
||||||
|
|
||||||
|
namespace xsk::arc::jup
|
||||||
|
{
|
||||||
|
|
||||||
|
constexpr usize code_count = 0;
|
||||||
|
constexpr usize hash_count = 0;
|
||||||
|
constexpr u64 header_magic = 0x38000A0D43534780;
|
||||||
|
|
||||||
|
class context : public arc::context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
context();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::arc::jup
|
17
include/xsk/arc/engine/t6.hpp
Normal file
17
include/xsk/arc/engine/t6.hpp
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/stdinc.hpp"
|
||||||
|
#include "xsk/arc/context.hpp"
|
||||||
|
|
||||||
|
namespace xsk::arc::t6
|
||||||
|
{
|
||||||
|
|
||||||
|
constexpr usize code_count = 125;
|
||||||
|
constexpr usize hash_count = 3331;
|
||||||
|
|
||||||
|
} // namespace xsk::arc::t6
|
21
include/xsk/arc/engine/t6_pc.hpp
Normal file
21
include/xsk/arc/engine/t6_pc.hpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/arc/engine/t6.hpp"
|
||||||
|
|
||||||
|
namespace xsk::arc::t6::pc
|
||||||
|
{
|
||||||
|
|
||||||
|
constexpr u64 header_magic = 0x06000A0D43534780;
|
||||||
|
|
||||||
|
class context : public arc::context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
context();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::arc::t6::pc
|
21
include/xsk/arc/engine/t6_ps3.hpp
Normal file
21
include/xsk/arc/engine/t6_ps3.hpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/arc/engine/t6.hpp"
|
||||||
|
|
||||||
|
namespace xsk::arc::t6::ps3
|
||||||
|
{
|
||||||
|
|
||||||
|
constexpr u64 header_magic = 0x804753430D0A0006;
|
||||||
|
|
||||||
|
class context : public arc::context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
context();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::arc::t6::ps3
|
21
include/xsk/arc/engine/t6_wiiu.hpp
Normal file
21
include/xsk/arc/engine/t6_wiiu.hpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/arc/engine/t6.hpp"
|
||||||
|
|
||||||
|
namespace xsk::arc::t6::wiiu
|
||||||
|
{
|
||||||
|
|
||||||
|
constexpr u64 header_magic = 0x804753430D0A0006;
|
||||||
|
|
||||||
|
class context : public arc::context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
context();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::arc::t6::wiiu
|
21
include/xsk/arc/engine/t6_xb2.hpp
Normal file
21
include/xsk/arc/engine/t6_xb2.hpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/arc/engine/t6.hpp"
|
||||||
|
|
||||||
|
namespace xsk::arc::t6::xb2
|
||||||
|
{
|
||||||
|
|
||||||
|
constexpr u64 header_magic = 0x804753430D0A0006;
|
||||||
|
|
||||||
|
class context : public arc::context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
context();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::arc::t6::xb2
|
24
include/xsk/arc/engine/t7.hpp
Normal file
24
include/xsk/arc/engine/t7.hpp
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/stdinc.hpp"
|
||||||
|
#include "xsk/arc/context.hpp"
|
||||||
|
|
||||||
|
namespace xsk::arc::t7
|
||||||
|
{
|
||||||
|
|
||||||
|
constexpr usize code_count = 16384;
|
||||||
|
constexpr usize hash_count = 178806;
|
||||||
|
constexpr u64 header_magic = 0x1C000A0D43534780;
|
||||||
|
|
||||||
|
class context : public arc::context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
context();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::arc::t7
|
24
include/xsk/arc/engine/t8.hpp
Normal file
24
include/xsk/arc/engine/t8.hpp
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/stdinc.hpp"
|
||||||
|
#include "xsk/arc/context.hpp"
|
||||||
|
|
||||||
|
namespace xsk::arc::t8
|
||||||
|
{
|
||||||
|
|
||||||
|
constexpr usize code_count = 0;
|
||||||
|
constexpr usize hash_count = 0;
|
||||||
|
constexpr u64 header_magic = 0x36000A0D43534780;
|
||||||
|
|
||||||
|
class context : public arc::context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
context();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::arc::t8
|
24
include/xsk/arc/engine/t9.hpp
Normal file
24
include/xsk/arc/engine/t9.hpp
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/stdinc.hpp"
|
||||||
|
#include "xsk/arc/context.hpp"
|
||||||
|
|
||||||
|
namespace xsk::arc::t9
|
||||||
|
{
|
||||||
|
|
||||||
|
constexpr usize code_count = 0;
|
||||||
|
constexpr usize hash_count = 0;
|
||||||
|
constexpr u64 header_magic = 0x38000A0D43534780;
|
||||||
|
|
||||||
|
class context : public arc::context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
context();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::arc::t9
|
33
include/xsk/arc/lexer.hpp
Normal file
33
include/xsk/arc/lexer.hpp
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/arc/common/types.hpp"
|
||||||
|
|
||||||
|
namespace xsk::arc
|
||||||
|
{
|
||||||
|
|
||||||
|
class lexer
|
||||||
|
{
|
||||||
|
context const* ctx_;
|
||||||
|
lookahead reader_;
|
||||||
|
location loc_;
|
||||||
|
usize buflen_;
|
||||||
|
spacing spacing_;
|
||||||
|
bool indev_;
|
||||||
|
std::array<char, 0x1000> buffer_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
lexer(context const* ctx, std::string const& name, char const* data, usize size);
|
||||||
|
auto lex() -> token;
|
||||||
|
|
||||||
|
private:
|
||||||
|
auto push(char c) -> void;
|
||||||
|
auto advance() -> void;
|
||||||
|
auto linewrap() -> void;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::arc
|
File diff suppressed because it is too large
Load Diff
92
include/xsk/arc/preprocessor.hpp
Normal file
92
include/xsk/arc/preprocessor.hpp
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/arc/common/types.hpp"
|
||||||
|
#include "xsk/arc/lexer.hpp"
|
||||||
|
|
||||||
|
namespace xsk::arc
|
||||||
|
{
|
||||||
|
|
||||||
|
class preprocessor
|
||||||
|
{
|
||||||
|
context* ctx_;
|
||||||
|
std::stack<lexer> lexer_;
|
||||||
|
std::stack<directive> indents_;
|
||||||
|
std::vector<std::string> includes_;
|
||||||
|
std::unordered_map<std::string_view, directive::kind> directives_;
|
||||||
|
std::unordered_map<std::string, define> defines_;
|
||||||
|
std::set<std::string> reject_;
|
||||||
|
std::deque<token> tokens_;
|
||||||
|
std::vector<token> expr_;
|
||||||
|
std::string date_;
|
||||||
|
std::string time_;
|
||||||
|
usize curr_expr_;
|
||||||
|
u32 expand_;
|
||||||
|
u32 skip_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
preprocessor(context* ctx, std::string const& name, char const* data, usize size);
|
||||||
|
auto process() -> token;
|
||||||
|
auto push_header(std::string const& file) -> void;
|
||||||
|
auto pop_header() -> void;
|
||||||
|
auto ban_header(location const& loc) -> void;
|
||||||
|
|
||||||
|
private:
|
||||||
|
auto skip_line() -> void;
|
||||||
|
auto next_token() -> token;
|
||||||
|
auto read_token() -> token;
|
||||||
|
auto read_directive(token& tok) -> void;
|
||||||
|
auto read_directive_if(token& tok) -> void;
|
||||||
|
auto read_directive_ifdef(token& tok) -> void;
|
||||||
|
auto read_directive_ifndef(token& tok) -> void;
|
||||||
|
auto read_directive_elif(token& tok) -> void;
|
||||||
|
auto read_directive_elifdef(token& tok) -> void;
|
||||||
|
auto read_directive_elifndef(token& tok) -> void;
|
||||||
|
auto read_directive_else(token& tok) -> void;
|
||||||
|
auto read_directive_endif(token& tok) -> void;
|
||||||
|
auto read_directive_define(token& tok) -> void;
|
||||||
|
auto read_directive_undef(token& tok) -> void;
|
||||||
|
auto read_directive_pragma(token& tok) -> void;
|
||||||
|
auto read_directive_warning(token& tok) -> void;
|
||||||
|
auto read_directive_error(token& tok) -> void;
|
||||||
|
auto read_directive_line(token& tok) -> void;
|
||||||
|
auto read_directive_include(token& hash, token& name) -> void;
|
||||||
|
auto read_directive_inline(token& hash, token& name) -> void;
|
||||||
|
auto read_directive_usingtree(token& hash, token& name) -> void;
|
||||||
|
auto read_hashtoken(token& hash) -> void;
|
||||||
|
auto read_hashtoken_animtree(token& hash, token& name) -> void;
|
||||||
|
auto read_hashtoken_hashstr(token& hash, token& name) -> void;
|
||||||
|
auto expand(token& tok, define& def) -> void;
|
||||||
|
auto expand_params(token& tok, define& def) -> std::vector<std::vector<token>>;
|
||||||
|
auto expect(token& tok, token::kind expected, spacing space = spacing::none) -> void;
|
||||||
|
auto evaluate() -> bool;
|
||||||
|
auto eval_next() -> token&;
|
||||||
|
auto eval_peek() -> token&;
|
||||||
|
auto eval_prev() -> token&;
|
||||||
|
auto eval_atend() -> bool;
|
||||||
|
auto eval_check(token::kind type) -> bool;
|
||||||
|
auto eval_match(token::kind type) -> bool;
|
||||||
|
auto eval_consume(token::kind type, std::string_view msg);
|
||||||
|
auto eval_expr() -> i32;
|
||||||
|
auto eval_expr_or() -> i32;
|
||||||
|
auto eval_expr_and() -> i32;
|
||||||
|
auto eval_expr_bwor() -> i32;
|
||||||
|
auto eval_expr_bwexor() -> i32;
|
||||||
|
auto eval_expr_bwand() -> i32;
|
||||||
|
auto eval_expr_eq() -> i32;
|
||||||
|
auto eval_expr_lge() -> i32;
|
||||||
|
auto eval_expr_shift() -> i32;
|
||||||
|
auto eval_expr_add() -> i32;
|
||||||
|
auto eval_expr_factor() -> i32;
|
||||||
|
auto eval_expr_unary() -> i32;
|
||||||
|
auto eval_expr_primary() -> i32;
|
||||||
|
auto get_local_time(std::tm& ltime) -> void;
|
||||||
|
auto get_date_define(std::tm* time_p) -> void;
|
||||||
|
auto get_time_define(std::tm* time_p) -> void;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::arc
|
145
include/xsk/arc/source.hpp
Normal file
145
include/xsk/arc/source.hpp
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/arc/common/types.hpp"
|
||||||
|
|
||||||
|
namespace xsk::arc
|
||||||
|
{
|
||||||
|
|
||||||
|
class source
|
||||||
|
{
|
||||||
|
context* ctx_;
|
||||||
|
std::vector<u8> buf_;
|
||||||
|
u32 indent_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
source(context* ctx);
|
||||||
|
auto parse_assembly(buffer const& data) -> assembly::ptr;
|
||||||
|
auto parse_assembly(std::vector<u8> const& data) -> assembly::ptr;
|
||||||
|
auto parse_assembly(u8 const* data, usize size) -> assembly::ptr;
|
||||||
|
auto parse_program(std::string const& name, buffer const& data) -> program::ptr;
|
||||||
|
auto parse_program(std::string const& name, std::vector<u8> const& data) -> program::ptr;
|
||||||
|
auto parse_program(std::string const& name, u8 const* data, usize size) -> program::ptr;
|
||||||
|
auto dump(assembly const& data) -> std::vector<u8>;
|
||||||
|
auto dump(program const& data) -> std::vector<u8>;
|
||||||
|
|
||||||
|
private:
|
||||||
|
auto dump_assembly(assembly const& data) -> void;
|
||||||
|
auto dump_function(function const& func) -> void;
|
||||||
|
auto dump_instruction(instruction const& inst) -> void;
|
||||||
|
auto dump_program(program const& data) -> void;
|
||||||
|
auto dump_include(include const& inc) -> void;
|
||||||
|
auto dump_decl(decl const& dec) -> void;
|
||||||
|
auto dump_decl_dev_begin(decl_dev_begin const& dec) -> void;
|
||||||
|
auto dump_decl_dev_end(decl_dev_end const& dec) -> void;
|
||||||
|
auto dump_decl_namespace(decl_namespace const& dec) -> void;
|
||||||
|
auto dump_decl_usingtree(decl_usingtree const& dec) -> void;
|
||||||
|
auto dump_decl_function(decl_function const& dec) -> void;
|
||||||
|
auto dump_decl_empty(decl_empty const& dec) -> void;
|
||||||
|
auto dump_stmt(stmt const& stm) -> void;
|
||||||
|
auto dump_stmt_empty(stmt_empty const& stm) -> void;
|
||||||
|
auto dump_stmt_list(stmt_list const& stm) -> void;
|
||||||
|
auto dump_stmt_comp(stmt_comp const& stm) -> void;
|
||||||
|
auto dump_stmt_dev(stmt_dev const& stm) -> void;
|
||||||
|
auto dump_stmt_expr(stmt_expr const& stm) -> void;
|
||||||
|
auto dump_stmt_endon(stmt_endon const& stm) -> void;
|
||||||
|
auto dump_stmt_notify(stmt_notify const& stm) -> void;
|
||||||
|
auto dump_stmt_wait(stmt_wait const& stm) -> void;
|
||||||
|
auto dump_stmt_waitrealtime(stmt_waitrealtime const& stm) -> void;
|
||||||
|
auto dump_stmt_waittill(stmt_waittill const& stm) -> void;
|
||||||
|
auto dump_stmt_waittillmatch(stmt_waittillmatch const& stm) -> void;
|
||||||
|
auto dump_stmt_waittillframeend(stmt_waittillframeend const& stm) -> void;
|
||||||
|
auto dump_stmt_if(stmt_if const& stm) -> void;
|
||||||
|
auto dump_stmt_ifelse(stmt_ifelse const& stm) -> void;
|
||||||
|
auto dump_stmt_while(stmt_while const& stm) -> void;
|
||||||
|
auto dump_stmt_dowhile(stmt_dowhile const& stm) -> void;
|
||||||
|
auto dump_stmt_for(stmt_for const& stm) -> void;
|
||||||
|
auto dump_stmt_foreach(stmt_foreach const& stm) -> void;
|
||||||
|
auto dump_stmt_switch(stmt_switch const& stm) -> void;
|
||||||
|
auto dump_stmt_case(stmt_case const& stm) -> void;
|
||||||
|
auto dump_stmt_default(stmt_default const& stm) -> void;
|
||||||
|
auto dump_stmt_break(stmt_break const& stm) -> void;
|
||||||
|
auto dump_stmt_continue(stmt_continue const& stm) -> void;
|
||||||
|
auto dump_stmt_return(stmt_return const& stm) -> void;
|
||||||
|
auto dump_stmt_breakpoint(stmt_breakpoint const& stm) -> void;
|
||||||
|
auto dump_stmt_prof_begin(stmt_prof_begin const& stm) -> void;
|
||||||
|
auto dump_stmt_prof_end(stmt_prof_end const& stm) -> void;
|
||||||
|
auto dump_stmt_jmp(stmt_jmp const& stm) -> void;
|
||||||
|
auto dump_stmt_jmp_back(stmt_jmp_back const& stm) -> void;
|
||||||
|
auto dump_stmt_jmp_cond(stmt_jmp_cond const& stm) -> void;
|
||||||
|
auto dump_stmt_jmp_true(stmt_jmp_true const& stm) -> void;
|
||||||
|
auto dump_stmt_jmp_false(stmt_jmp_false const& stm) -> void;
|
||||||
|
auto dump_stmt_jmp_switch(stmt_jmp_switch const& stm) -> void;
|
||||||
|
auto dump_stmt_jmp_endswitch(stmt_jmp_endswitch const& stm) -> void;
|
||||||
|
auto dump_stmt_jmp_dev(stmt_jmp_dev const& stm) -> void;
|
||||||
|
auto dump_expr(expr const& exp) -> void;
|
||||||
|
auto dump_expr_increment(expr_increment const& exp) -> void;
|
||||||
|
auto dump_expr_decrement(expr_decrement const& exp) -> void;
|
||||||
|
auto dump_expr_assign(expr_assign const& exp) -> void;
|
||||||
|
auto dump_expr_const(expr_const const& exp) -> void;
|
||||||
|
auto dump_expr_ternary(expr_ternary const& exp) -> void;
|
||||||
|
auto dump_expr_binary(expr_binary const& exp) -> void;
|
||||||
|
auto dump_expr_not(expr_not const& exp) -> void;
|
||||||
|
auto dump_expr_negate(expr_negate const& exp) -> void;
|
||||||
|
auto dump_expr_complement(expr_complement const& exp) -> void;
|
||||||
|
auto dump_expr_new(expr_new const& exp) -> void;
|
||||||
|
auto dump_expr_call(expr_call const& exp) -> void;
|
||||||
|
auto dump_expr_method(expr_method const& exp) -> void;
|
||||||
|
auto dump_call(call const& exp) -> void;
|
||||||
|
auto dump_expr_function(expr_function const& exp) -> void;
|
||||||
|
auto dump_expr_pointer(expr_pointer const& exp) -> void;
|
||||||
|
auto dump_expr_member(expr_member const& exp) -> void;
|
||||||
|
auto dump_expr_parameters(expr_parameters const& exp) -> void;
|
||||||
|
auto dump_expr_arguments(expr_arguments const& exp) -> void;
|
||||||
|
auto dump_expr_isdefined(expr_isdefined const& exp) -> void;
|
||||||
|
auto dump_expr_vectorscale(expr_vectorscale const& exp) -> void;
|
||||||
|
auto dump_expr_anglestoup(expr_anglestoup const& exp) -> void;
|
||||||
|
auto dump_expr_anglestoright(expr_anglestoright const& exp) -> void;
|
||||||
|
auto dump_expr_anglestoforward(expr_anglestoforward const& exp) -> void;
|
||||||
|
auto dump_expr_angleclamp180(expr_angleclamp180 const& exp) -> void;
|
||||||
|
auto dump_expr_vectortoangles(expr_vectortoangles const& exp) -> void;
|
||||||
|
auto dump_expr_abs(expr_abs const& exp) -> void;
|
||||||
|
auto dump_expr_gettime(expr_gettime const& exp) -> void;
|
||||||
|
auto dump_expr_getdvar(expr_getdvar const& exp) -> void;
|
||||||
|
auto dump_expr_getdvarint(expr_getdvarint const& exp) -> void;
|
||||||
|
auto dump_expr_getdvarfloat(expr_getdvarfloat const& exp) -> void;
|
||||||
|
auto dump_expr_getdvarvector(expr_getdvarvector const& exp) -> void;
|
||||||
|
auto dump_expr_getdvarcolorred(expr_getdvarcolorred const& exp) -> void;
|
||||||
|
auto dump_expr_getdvarcolorgreen(expr_getdvarcolorgreen const& exp) -> void;
|
||||||
|
auto dump_expr_getdvarcolorblue(expr_getdvarcolorblue const& exp) -> void;
|
||||||
|
auto dump_expr_getdvarcoloralpha(expr_getdvarcoloralpha const& exp) -> void;
|
||||||
|
auto dump_expr_getfirstarraykey(expr_getfirstarraykey const& exp) -> void;
|
||||||
|
auto dump_expr_getnextarraykey(expr_getnextarraykey const& exp) -> void;
|
||||||
|
auto dump_expr_reference(expr_reference const& exp) -> void;
|
||||||
|
auto dump_expr_array(expr_array const& exp) -> void;
|
||||||
|
auto dump_expr_field(expr_field const& exp) -> void;
|
||||||
|
auto dump_expr_size(expr_size const& exp) -> void;
|
||||||
|
auto dump_expr_paren(expr_paren const& exp) -> void;
|
||||||
|
auto dump_expr_ellipsis(expr_ellipsis const& exp) -> void;
|
||||||
|
auto dump_expr_empty_array(expr_empty_array const& exp) -> void;
|
||||||
|
auto dump_expr_undefined(expr_undefined const& exp) -> void;
|
||||||
|
auto dump_expr_game(expr_game const& exp) -> void;
|
||||||
|
auto dump_expr_self(expr_self const& exp) -> void;
|
||||||
|
auto dump_expr_anim(expr_anim const& exp) -> void;
|
||||||
|
auto dump_expr_level(expr_level const& exp) -> void;
|
||||||
|
auto dump_expr_world(expr_world const& exp) -> void;
|
||||||
|
auto dump_expr_classes(expr_classes const& exp) -> void;
|
||||||
|
auto dump_expr_animation(expr_animation const& exp) -> void;
|
||||||
|
auto dump_expr_animtree(expr_animtree const& exp) -> void;
|
||||||
|
auto dump_expr_identifier(expr_identifier const& exp) -> void;
|
||||||
|
auto dump_expr_path(expr_path const& exp) -> void;
|
||||||
|
auto dump_expr_istring(expr_istring const& exp) -> void;
|
||||||
|
auto dump_expr_string(expr_string const& exp) -> void;
|
||||||
|
auto dump_expr_hash(expr_hash const& exp) -> void;
|
||||||
|
auto dump_expr_vector(expr_vector const& exp) -> void;
|
||||||
|
auto dump_expr_float(expr_float const& exp) -> void;
|
||||||
|
auto dump_expr_integer(expr_integer const& exp) -> void;
|
||||||
|
auto dump_expr_false(expr_false const& exp) -> void;
|
||||||
|
auto dump_expr_true(expr_true const& exp) -> void;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::arc
|
45
include/xsk/gsc/assembler.hpp
Normal file
45
include/xsk/gsc/assembler.hpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/utils/writer.hpp"
|
||||||
|
#include "xsk/gsc/common/types.hpp"
|
||||||
|
|
||||||
|
namespace xsk::gsc
|
||||||
|
{
|
||||||
|
|
||||||
|
class assembler
|
||||||
|
{
|
||||||
|
context const* ctx_;
|
||||||
|
function const* func_;
|
||||||
|
assembly const* assembly_;
|
||||||
|
utils::writer script_;
|
||||||
|
utils::writer stack_;
|
||||||
|
utils::writer devmap_;
|
||||||
|
u32 devmap_count_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
assembler(context const* ctx);
|
||||||
|
auto assemble(assembly const& data) -> std::tuple<buffer, buffer, buffer>;
|
||||||
|
|
||||||
|
private:
|
||||||
|
auto assemble_function(function const& func) -> void;
|
||||||
|
auto assemble_instruction(instruction const& inst) -> void;
|
||||||
|
auto assemble_builtin_call(instruction const& inst, bool method, bool args) -> void;
|
||||||
|
auto assemble_local_call(instruction const& inst, bool thread) -> void;
|
||||||
|
auto assemble_far_call(instruction const& inst, bool thread) -> void;
|
||||||
|
auto assemble_switch(instruction const& inst) -> void;
|
||||||
|
auto assemble_end_switch(instruction const& inst) -> void;
|
||||||
|
auto assemble_field_variable(instruction const& inst) -> void;
|
||||||
|
auto assemble_formal_params(instruction const& inst) -> void;
|
||||||
|
auto assemble_jump(instruction const& inst, bool expr, bool back) -> void;
|
||||||
|
auto assemble_offset(i32 offs) -> void;
|
||||||
|
auto resolve_function(std::string const& name) -> i32;
|
||||||
|
auto resolve_label(std::string const& name) -> i32;
|
||||||
|
auto encrypt_string(std::string const& str) -> std::string;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::gsc
|
274
include/xsk/gsc/common/assembly.hpp
Normal file
274
include/xsk/gsc/common/assembly.hpp
Normal file
@ -0,0 +1,274 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace xsk::gsc
|
||||||
|
{
|
||||||
|
|
||||||
|
constexpr usize opcode_count = 205;
|
||||||
|
|
||||||
|
enum class opcode : u8
|
||||||
|
{
|
||||||
|
vm_invalid,
|
||||||
|
OP_CastFieldObject,
|
||||||
|
OP_SetLocalVariableFieldCached,
|
||||||
|
OP_plus,
|
||||||
|
OP_RemoveLocalVariables,
|
||||||
|
OP_EvalSelfFieldVariableRef,
|
||||||
|
OP_ScriptFarMethodChildThreadCall,
|
||||||
|
OP_GetGameRef,
|
||||||
|
OP_EvalAnimFieldVariable,
|
||||||
|
OP_EvalLevelFieldVariableRef,
|
||||||
|
OP_GetThisthread,
|
||||||
|
OP_greater,
|
||||||
|
OP_waittillmatch,
|
||||||
|
OP_shift_right,
|
||||||
|
OP_dec,
|
||||||
|
OP_JumpOnTrue,
|
||||||
|
OP_bit_or,
|
||||||
|
OP_equality,
|
||||||
|
OP_ClearLocalVariableFieldCached0,
|
||||||
|
OP_notify,
|
||||||
|
OP_GetVector,
|
||||||
|
OP_ScriptMethodChildThreadCallPointer,
|
||||||
|
OP_PreScriptCall,
|
||||||
|
OP_GetByte,
|
||||||
|
OP_ScriptFarThreadCall,
|
||||||
|
OP_SetSelfFieldVariableField,
|
||||||
|
OP_JumpOnFalseExpr,
|
||||||
|
OP_GetUndefined,
|
||||||
|
OP_jumpback,
|
||||||
|
OP_JumpOnTrueExpr,
|
||||||
|
OP_CallBuiltin0,
|
||||||
|
OP_CallBuiltin1,
|
||||||
|
OP_CallBuiltin2,
|
||||||
|
OP_CallBuiltin3,
|
||||||
|
OP_CallBuiltin4,
|
||||||
|
OP_CallBuiltin5,
|
||||||
|
OP_CallBuiltin,
|
||||||
|
OP_SetLocalVariableFieldCached0,
|
||||||
|
OP_ClearFieldVariable,
|
||||||
|
OP_GetLevel,
|
||||||
|
OP_size,
|
||||||
|
OP_SafeSetWaittillVariableFieldCached,
|
||||||
|
OP_ScriptLocalMethodThreadCall,
|
||||||
|
OP_AddArray,
|
||||||
|
OP_endon,
|
||||||
|
OP_EvalFieldVariable,
|
||||||
|
OP_shift_left,
|
||||||
|
OP_EvalLocalArrayRefCached0,
|
||||||
|
OP_Return,
|
||||||
|
OP_CreateLocalVariable,
|
||||||
|
OP_SafeSetVariableFieldCached0,
|
||||||
|
OP_GetBuiltinFunction,
|
||||||
|
OP_ScriptLocalMethodCall,
|
||||||
|
OP_CallBuiltinMethodPointer,
|
||||||
|
OP_ScriptLocalChildThreadCall,
|
||||||
|
OP_GetSelfObject,
|
||||||
|
OP_GetGame,
|
||||||
|
OP_SetLevelFieldVariableField,
|
||||||
|
OP_EvalArray,
|
||||||
|
OP_GetSelf,
|
||||||
|
OP_End,
|
||||||
|
OP_EvalSelfFieldVariable,
|
||||||
|
OP_less_equal,
|
||||||
|
OP_EvalLocalVariableCached0,
|
||||||
|
OP_EvalLocalVariableCached1,
|
||||||
|
OP_EvalLocalVariableCached2,
|
||||||
|
OP_EvalLocalVariableCached3,
|
||||||
|
OP_EvalLocalVariableCached4,
|
||||||
|
OP_EvalLocalVariableCached5,
|
||||||
|
OP_EvalLocalVariableCached,
|
||||||
|
OP_EvalNewLocalArrayRefCached0,
|
||||||
|
OP_ScriptChildThreadCallPointer,
|
||||||
|
OP_EvalLocalVariableObjectCached,
|
||||||
|
OP_ScriptLocalThreadCall,
|
||||||
|
OP_GetInteger,
|
||||||
|
OP_ScriptMethodCallPointer,
|
||||||
|
OP_checkclearparams,
|
||||||
|
OP_SetAnimFieldVariableField,
|
||||||
|
OP_waittillmatch2,
|
||||||
|
OP_minus,
|
||||||
|
OP_ScriptLocalFunctionCall2,
|
||||||
|
OP_GetNegUnsignedShort,
|
||||||
|
OP_GetNegByte,
|
||||||
|
OP_SafeCreateVariableFieldCached,
|
||||||
|
OP_greater_equal,
|
||||||
|
OP_vector,
|
||||||
|
OP_GetBuiltinMethod,
|
||||||
|
OP_endswitch,
|
||||||
|
OP_ClearArray,
|
||||||
|
OP_DecTop,
|
||||||
|
OP_CastBool,
|
||||||
|
OP_EvalArrayRef,
|
||||||
|
OP_SetNewLocalVariableFieldCached0,
|
||||||
|
OP_GetZero,
|
||||||
|
OP_wait,
|
||||||
|
OP_waittill,
|
||||||
|
OP_GetIString,
|
||||||
|
OP_ScriptFarFunctionCall,
|
||||||
|
OP_GetAnimObject,
|
||||||
|
OP_GetAnimTree,
|
||||||
|
OP_EvalLocalArrayCached,
|
||||||
|
OP_mod,
|
||||||
|
OP_ScriptFarMethodThreadCall,
|
||||||
|
OP_GetUnsignedShort,
|
||||||
|
OP_clearparams,
|
||||||
|
OP_ScriptMethodThreadCallPointer,
|
||||||
|
OP_ScriptFunctionCallPointer,
|
||||||
|
OP_EmptyArray,
|
||||||
|
OP_SafeSetVariableFieldCached,
|
||||||
|
OP_ClearVariableField,
|
||||||
|
OP_EvalFieldVariableRef,
|
||||||
|
OP_ScriptLocalMethodChildThreadCall,
|
||||||
|
OP_EvalNewLocalVariableRefCached0,
|
||||||
|
OP_GetFloat,
|
||||||
|
OP_EvalLocalVariableRefCached,
|
||||||
|
OP_JumpOnFalse,
|
||||||
|
OP_BoolComplement,
|
||||||
|
OP_ScriptThreadCallPointer,
|
||||||
|
OP_ScriptFarFunctionCall2,
|
||||||
|
OP_less,
|
||||||
|
OP_BoolNot,
|
||||||
|
OP_waittillFrameEnd,
|
||||||
|
OP_waitframe,
|
||||||
|
OP_GetString,
|
||||||
|
OP_EvalLevelFieldVariable,
|
||||||
|
OP_GetLevelObject,
|
||||||
|
OP_inc,
|
||||||
|
OP_CallBuiltinMethod0,
|
||||||
|
OP_CallBuiltinMethod1,
|
||||||
|
OP_CallBuiltinMethod2,
|
||||||
|
OP_CallBuiltinMethod3,
|
||||||
|
OP_CallBuiltinMethod4,
|
||||||
|
OP_CallBuiltinMethod5,
|
||||||
|
OP_CallBuiltinMethod,
|
||||||
|
OP_GetAnim,
|
||||||
|
OP_switch,
|
||||||
|
OP_SetVariableField,
|
||||||
|
OP_divide,
|
||||||
|
OP_GetLocalFunction,
|
||||||
|
OP_ScriptFarChildThreadCall,
|
||||||
|
OP_multiply,
|
||||||
|
OP_ClearLocalVariableFieldCached,
|
||||||
|
OP_EvalAnimFieldVariableRef,
|
||||||
|
OP_EvalLocalArrayRefCached,
|
||||||
|
OP_EvalLocalVariableRefCached0,
|
||||||
|
OP_bit_and,
|
||||||
|
OP_GetAnimation,
|
||||||
|
OP_GetFarFunction,
|
||||||
|
OP_CallBuiltinPointer,
|
||||||
|
OP_jump,
|
||||||
|
OP_voidCodepos,
|
||||||
|
OP_ScriptFarMethodCall,
|
||||||
|
OP_inequality,
|
||||||
|
OP_ScriptLocalFunctionCall,
|
||||||
|
OP_bit_ex_or,
|
||||||
|
OP_NOP,
|
||||||
|
OP_abort,
|
||||||
|
OP_object,
|
||||||
|
OP_thread_object,
|
||||||
|
OP_EvalLocalVariable,
|
||||||
|
OP_EvalLocalVariableRef,
|
||||||
|
OP_prof_begin,
|
||||||
|
OP_prof_end,
|
||||||
|
OP_breakpoint,
|
||||||
|
OP_assignmentBreakpoint,
|
||||||
|
OP_manualAndAssignmentBreakpoint,
|
||||||
|
OP_BoolNotAfterAnd,
|
||||||
|
OP_FormalParams,
|
||||||
|
OP_IsDefined,
|
||||||
|
OP_IsTrue,
|
||||||
|
OP_NativeGetLocalFunction,
|
||||||
|
OP_NativeLocalFunctionCall,
|
||||||
|
OP_NativeLocalFunctionCall2,
|
||||||
|
OP_NativeLocalMethodCall,
|
||||||
|
OP_NativeLocalFunctionThreadCall,
|
||||||
|
OP_NativeLocalMethodThreadCall,
|
||||||
|
OP_NativeLocalFunctionChildThreadCall,
|
||||||
|
OP_NativeLocalMethodChildThreadCall,
|
||||||
|
OP_NativeGetFarFunction,
|
||||||
|
OP_NativeFarFunctionCall,
|
||||||
|
OP_NativeFarFunctionCall2,
|
||||||
|
OP_NativeFarMethodCall,
|
||||||
|
OP_NativeFarFunctionThreadCall,
|
||||||
|
OP_NativeFarMethodThreadCall,
|
||||||
|
OP_NativeFarFunctionChildThreadCall,
|
||||||
|
OP_NativeFarMethodChildThreadCall,
|
||||||
|
OP_EvalNewLocalArrayRefCached0_Precompiled,
|
||||||
|
OP_SetNewLocalVariableFieldCached0_Precompiled,
|
||||||
|
OP_CreateLocalVariable_Precompiled,
|
||||||
|
OP_SafeCreateVariableFieldCached_Precompiled,
|
||||||
|
OP_FormalParams_Precompiled,
|
||||||
|
OP_GetStatHash,
|
||||||
|
OP_GetUnkxHash,
|
||||||
|
OP_GetEnumHash,
|
||||||
|
OP_GetDvarHash,
|
||||||
|
OP_GetUnsignedInt,
|
||||||
|
OP_GetNegUnsignedInt,
|
||||||
|
OP_GetInteger64,
|
||||||
|
OP_iw9_139,
|
||||||
|
OP_iw9_140,
|
||||||
|
OP_iw9_141,
|
||||||
|
OP_iw9_142,
|
||||||
|
OP_iw9_143,
|
||||||
|
OP_iw9_144,
|
||||||
|
OP_iw9_166,
|
||||||
|
OP_count,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct sourcepos
|
||||||
|
{
|
||||||
|
u16 line;
|
||||||
|
u16 column;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct instruction
|
||||||
|
{
|
||||||
|
using ptr = std::unique_ptr<instruction>;
|
||||||
|
|
||||||
|
u32 index;
|
||||||
|
u32 size;
|
||||||
|
sourcepos pos;
|
||||||
|
opcode opcode;
|
||||||
|
std::vector<std::string> data;
|
||||||
|
|
||||||
|
static auto make() -> instruction::ptr
|
||||||
|
{
|
||||||
|
return std::unique_ptr<instruction>(new instruction);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct function
|
||||||
|
{
|
||||||
|
using ptr = std::unique_ptr<function>;
|
||||||
|
|
||||||
|
u32 index;
|
||||||
|
u32 size;
|
||||||
|
u32 id;
|
||||||
|
std::string name;
|
||||||
|
std::vector<instruction::ptr> instructions;
|
||||||
|
std::unordered_map<u32, std::string> labels;
|
||||||
|
|
||||||
|
static auto make() -> function::ptr
|
||||||
|
{
|
||||||
|
return std::unique_ptr<function>(new function);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct assembly
|
||||||
|
{
|
||||||
|
using ptr = std::unique_ptr<assembly>;
|
||||||
|
|
||||||
|
std::vector<function::ptr> functions;
|
||||||
|
|
||||||
|
static auto make() -> assembly::ptr
|
||||||
|
{
|
||||||
|
return std::unique_ptr<assembly>(new assembly);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::gsc
|
26
include/xsk/gsc/common/asset.hpp
Normal file
26
include/xsk/gsc/common/asset.hpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace xsk::gsc
|
||||||
|
{
|
||||||
|
|
||||||
|
struct asset
|
||||||
|
{
|
||||||
|
using ptr = std::unique_ptr<asset>;
|
||||||
|
|
||||||
|
std::string name;
|
||||||
|
u32 compressedLen;
|
||||||
|
u32 len;
|
||||||
|
u32 bytecodeLen;
|
||||||
|
std::vector<u8> buffer;
|
||||||
|
std::vector<u8> bytecode;
|
||||||
|
|
||||||
|
auto serialize() -> std::vector<u8>;
|
||||||
|
auto deserialize(std::vector<u8> const& data) -> void;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::gsc
|
1215
include/xsk/gsc/common/ast.hpp
Normal file
1215
include/xsk/gsc/common/ast.hpp
Normal file
File diff suppressed because it is too large
Load Diff
20
include/xsk/gsc/common/buffer.hpp
Normal file
20
include/xsk/gsc/common/buffer.hpp
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace xsk::gsc
|
||||||
|
{
|
||||||
|
|
||||||
|
struct buffer
|
||||||
|
{
|
||||||
|
u8 const* data;
|
||||||
|
usize const size;
|
||||||
|
|
||||||
|
buffer() : data{ nullptr }, size{ 0 } {}
|
||||||
|
buffer(u8 const* data, usize size) : data{ data }, size{ size } {}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::gsc
|
21
include/xsk/gsc/common/define.hpp
Normal file
21
include/xsk/gsc/common/define.hpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace xsk::gsc
|
||||||
|
{
|
||||||
|
|
||||||
|
struct define
|
||||||
|
{
|
||||||
|
enum kind : u8 { PLAIN, BUILTIN, OBJECT, FUNCTION };
|
||||||
|
|
||||||
|
kind type;
|
||||||
|
// bool vararg;
|
||||||
|
std::vector<token> args;
|
||||||
|
std::vector<token> exp;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::gsc
|
20
include/xsk/gsc/common/directive.hpp
Normal file
20
include/xsk/gsc/common/directive.hpp
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace xsk::gsc
|
||||||
|
{
|
||||||
|
|
||||||
|
struct directive
|
||||||
|
{
|
||||||
|
enum kind : u8 { IF, IFDEF, IFNDEF, ELIF, ELIFDEF, ELIFNDEF, ELSE, ENDIF, DEFINE, UNDEF, PRAGMA, WARNING, ERROR, LINE, INCLUDE, INLINE, INSERT, USINGTREE };
|
||||||
|
|
||||||
|
kind type;
|
||||||
|
bool skip;
|
||||||
|
bool exec;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::gsc
|
47
include/xsk/gsc/common/exception.hpp
Normal file
47
include/xsk/gsc/common/exception.hpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace xsk::gsc
|
||||||
|
{
|
||||||
|
|
||||||
|
class error : public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
error(std::string const& what);
|
||||||
|
};
|
||||||
|
|
||||||
|
class asm_error : public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
asm_error(std::string const& what);
|
||||||
|
};
|
||||||
|
|
||||||
|
class disasm_error : public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
disasm_error(std::string const& what);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ppr_error : public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ppr_error(location const& loc, std::string const& what);
|
||||||
|
};
|
||||||
|
|
||||||
|
class comp_error : public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
comp_error(location const& loc, std::string const& what);
|
||||||
|
};
|
||||||
|
|
||||||
|
class decomp_error : public std::runtime_error
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
decomp_error(std::string const& what);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::gsc
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2022 xensik. All rights reserved.
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
//
|
//
|
||||||
// Use of this source code is governed by a GNU GPLv3 license
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
// that can be found in the LICENSE file.
|
// that can be found in the LICENSE file.
|
||||||
@ -8,20 +8,19 @@
|
|||||||
namespace xsk::gsc
|
namespace xsk::gsc
|
||||||
{
|
{
|
||||||
|
|
||||||
/// A point in a source file.
|
|
||||||
class position
|
class position
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Type for file name.
|
|
||||||
typedef const std::string filename_type;
|
typedef const std::string filename_type;
|
||||||
/// Type for line and column numbers.
|
typedef u16 counter_type;
|
||||||
typedef int counter_type;
|
|
||||||
|
filename_type *filename;
|
||||||
|
counter_type line;
|
||||||
|
counter_type column;
|
||||||
|
|
||||||
/// Construct a position.
|
|
||||||
explicit position(filename_type *f = nullptr, counter_type l = 1, counter_type c = 1)
|
explicit position(filename_type *f = nullptr, counter_type l = 1, counter_type c = 1)
|
||||||
: filename(f), line(l), column(c) {}
|
: filename(f), line(l), column(c) {}
|
||||||
|
|
||||||
/// Initialization.
|
|
||||||
void initialize(filename_type *fn = nullptr, counter_type l = 1, counter_type c = 1)
|
void initialize(filename_type *fn = nullptr, counter_type l = 1, counter_type c = 1)
|
||||||
{
|
{
|
||||||
filename = fn;
|
filename = fn;
|
||||||
@ -29,9 +28,6 @@ public:
|
|||||||
column = c;
|
column = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \name Line and Column related manipulators
|
|
||||||
** \{ */
|
|
||||||
/// (line related) Advance to the COUNT next lines.
|
|
||||||
void lines(counter_type count = 1)
|
void lines(counter_type count = 1)
|
||||||
{
|
{
|
||||||
if (count)
|
if (count)
|
||||||
@ -41,179 +37,131 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// (column related) Advance to the COUNT next columns.
|
|
||||||
void columns(counter_type count = 1)
|
void columns(counter_type count = 1)
|
||||||
{
|
{
|
||||||
column = add_(column, count, 1);
|
column = add_(column, count, 1);
|
||||||
}
|
}
|
||||||
/** \} */
|
|
||||||
|
|
||||||
/// File name to which this position refers.
|
|
||||||
filename_type *filename;
|
|
||||||
/// Current line number.
|
|
||||||
counter_type line;
|
|
||||||
/// Current column number.
|
|
||||||
counter_type column;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Compute max (min, lhs+rhs).
|
|
||||||
static counter_type add_(counter_type lhs, counter_type rhs, counter_type min)
|
static counter_type add_(counter_type lhs, counter_type rhs, counter_type min)
|
||||||
{
|
{
|
||||||
return lhs + rhs < min ? min : lhs + rhs;
|
return lhs + rhs < min ? min : lhs + rhs;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Add \a width columns, in place.
|
|
||||||
inline position& operator+=(position &res, position::counter_type width)
|
inline position& operator+=(position &res, position::counter_type width)
|
||||||
{
|
{
|
||||||
res.columns(width);
|
res.columns(width);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add \a width columns.
|
|
||||||
inline position operator+(position res, position::counter_type width)
|
inline position operator+(position res, position::counter_type width)
|
||||||
{
|
{
|
||||||
return res += width;
|
return res += width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Subtract \a width columns, in place.
|
|
||||||
inline position& operator-=(position &res, position::counter_type width)
|
inline position& operator-=(position &res, position::counter_type width)
|
||||||
{
|
{
|
||||||
return res += -width;
|
return res += -width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Subtract \a width columns.
|
|
||||||
inline position operator-(position res, position::counter_type width)
|
inline position operator-(position res, position::counter_type width)
|
||||||
{
|
{
|
||||||
return res -= width;
|
return res -= width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Intercept output stream redirection.
|
template <typename T>
|
||||||
** \param ostr the destination output stream
|
std::basic_ostream<T>& operator<<(std::basic_ostream<T> &ostr, const position &pos)
|
||||||
** \param pos a reference to the position to redirect
|
|
||||||
*/
|
|
||||||
template <typename YYChar>
|
|
||||||
std::basic_ostream<YYChar>& operator<<(std::basic_ostream<YYChar> &ostr, const position &pos)
|
|
||||||
{
|
{
|
||||||
if (pos.filename)
|
if (pos.filename)
|
||||||
ostr << *pos.filename << ':';
|
ostr << *pos.filename << ':';
|
||||||
return ostr << pos.line << '.' << pos.column;
|
return ostr << pos.line << '.' << pos.column;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Two points in a source file.
|
|
||||||
class location
|
class location
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// Type for file name.
|
|
||||||
typedef position::filename_type filename_type;
|
typedef position::filename_type filename_type;
|
||||||
/// Type for line and column numbers.
|
|
||||||
typedef position::counter_type counter_type;
|
typedef position::counter_type counter_type;
|
||||||
|
|
||||||
/// Construct a location from \a b to \a e.
|
position begin;
|
||||||
|
position end;
|
||||||
|
|
||||||
location(const position &b, const position &e)
|
location(const position &b, const position &e)
|
||||||
: begin(b), end(e) {}
|
: begin(b), end(e) {}
|
||||||
|
|
||||||
/// Construct a 0-width location in \a p.
|
|
||||||
explicit location(const position &p = position())
|
explicit location(const position &p = position())
|
||||||
: begin(p), end(p) {}
|
: begin(p), end(p) {}
|
||||||
|
|
||||||
/// Construct a 0-width location in \a f, \a l, \a c.
|
|
||||||
explicit location(filename_type *f, counter_type l = 1, counter_type c = 1)
|
explicit location(filename_type *f, counter_type l = 1, counter_type c = 1)
|
||||||
: begin(f, l, c), end(f, l, c) {}
|
: begin(f, l, c), end(f, l, c) {}
|
||||||
|
|
||||||
/// Initialization.
|
|
||||||
void initialize(filename_type *f = nullptr, counter_type l = 1, counter_type c = 1)
|
void initialize(filename_type *f = nullptr, counter_type l = 1, counter_type c = 1)
|
||||||
{
|
{
|
||||||
begin.initialize(f, l, c);
|
begin.initialize(f, l, c);
|
||||||
end = begin;
|
end = begin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \name Line and Column related manipulators
|
|
||||||
** \{ */
|
|
||||||
public:
|
|
||||||
/// Reset initial location to final location.
|
|
||||||
void step()
|
void step()
|
||||||
{
|
{
|
||||||
begin = end;
|
begin = end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extend the current location to the COUNT next columns.
|
|
||||||
void columns(counter_type count = 1)
|
void columns(counter_type count = 1)
|
||||||
{
|
{
|
||||||
end += count;
|
end += count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extend the current location to the COUNT next lines.
|
|
||||||
void lines(counter_type count = 1)
|
void lines(counter_type count = 1)
|
||||||
{
|
{
|
||||||
end.lines(count);
|
end.lines(count);
|
||||||
}
|
}
|
||||||
/** \} */
|
|
||||||
|
|
||||||
public:
|
|
||||||
auto print() const -> std::string
|
auto print() const -> std::string
|
||||||
{
|
{
|
||||||
return *begin.filename + ":" + std::to_string(begin.line) + ":" + std::to_string(begin.column);
|
return std::format("{}:{}:{}", *begin.filename, begin.line, begin.column);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto label() const -> std::string
|
auto label() const -> std::string
|
||||||
{
|
{
|
||||||
return utils::string::va("loc_%X", begin.line);
|
return std::format("loc_{:X}", begin.line);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
/// Beginning of the located region.
|
|
||||||
position begin;
|
|
||||||
/// End of the located region.
|
|
||||||
position end;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Join two locations, in place.
|
|
||||||
inline location& operator+=(location &res, const location &end)
|
inline location& operator+=(location &res, const location &end)
|
||||||
{
|
{
|
||||||
res.end = end.end;
|
res.end = end.end;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Join two locations.
|
|
||||||
inline location operator+(location res, const location &end)
|
inline location operator+(location res, const location &end)
|
||||||
{
|
{
|
||||||
return res += end;
|
return res += end;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add \a width columns to the end position, in place.
|
|
||||||
inline location& operator+=(location &res, location::counter_type width)
|
inline location& operator+=(location &res, location::counter_type width)
|
||||||
{
|
{
|
||||||
res.columns(width);
|
res.columns(width);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add \a width columns to the end position.
|
|
||||||
inline location operator+(location res, location::counter_type width)
|
inline location operator+(location res, location::counter_type width)
|
||||||
{
|
{
|
||||||
return res += width;
|
return res += width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Subtract \a width columns to the end position, in place.
|
|
||||||
inline location& operator-=(location &res, location::counter_type width)
|
inline location& operator-=(location &res, location::counter_type width)
|
||||||
{
|
{
|
||||||
return res += -width;
|
return res += -width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Subtract \a width columns to the end position.
|
|
||||||
inline location operator-(location res, location::counter_type width)
|
inline location operator-(location res, location::counter_type width)
|
||||||
{
|
{
|
||||||
return res -= width;
|
return res -= width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** \brief Intercept output stream redirection.
|
template <typename T>
|
||||||
** \param ostr the destination output stream
|
std::basic_ostream<T>& operator<<(std::basic_ostream<T> &ostr, const location &loc)
|
||||||
** \param loc a reference to the location to redirect
|
|
||||||
**
|
|
||||||
** Avoid duplicate information.
|
|
||||||
*/
|
|
||||||
template <typename YYChar>
|
|
||||||
std::basic_ostream<YYChar>& operator<<(std::basic_ostream<YYChar> &ostr, const location &loc)
|
|
||||||
{
|
{
|
||||||
location::counter_type end_col = 0 < loc.end.column ? loc.end.column - 1 : 0;
|
location::counter_type end_col = 0 < loc.end.column ? loc.end.column - 1 : 0;
|
||||||
ostr << loc.begin;
|
ostr << loc.begin;
|
23
include/xsk/gsc/common/lookahead.hpp
Normal file
23
include/xsk/gsc/common/lookahead.hpp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace xsk::gsc
|
||||||
|
{
|
||||||
|
|
||||||
|
struct lookahead
|
||||||
|
{
|
||||||
|
char const* buffer_pos;
|
||||||
|
usize available;
|
||||||
|
char last_byte;
|
||||||
|
char curr_byte;
|
||||||
|
|
||||||
|
lookahead(char const* data, usize size);
|
||||||
|
auto advance() -> void;
|
||||||
|
auto ended() { return available == 0; };
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::gsc
|
64
include/xsk/gsc/common/scope.hpp
Normal file
64
include/xsk/gsc/common/scope.hpp
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace xsk::gsc
|
||||||
|
{
|
||||||
|
|
||||||
|
struct locjmp
|
||||||
|
{
|
||||||
|
std::string end;
|
||||||
|
std::string cnt;
|
||||||
|
std::string brk;
|
||||||
|
bool last;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct scope
|
||||||
|
{
|
||||||
|
using ptr = std::unique_ptr<scope>;
|
||||||
|
|
||||||
|
enum abort_type
|
||||||
|
{
|
||||||
|
abort_none = 0,
|
||||||
|
abort_continue = 1,
|
||||||
|
abort_break = 2,
|
||||||
|
abort_return = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct var
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
u8 create;
|
||||||
|
bool init;
|
||||||
|
};
|
||||||
|
|
||||||
|
abort_type abort;
|
||||||
|
std::string loc_end;
|
||||||
|
std::string loc_cont;
|
||||||
|
std::string loc_break;
|
||||||
|
u32 create_count;
|
||||||
|
u32 public_count;
|
||||||
|
std::vector<var> vars;
|
||||||
|
bool is_last;
|
||||||
|
|
||||||
|
scope();
|
||||||
|
auto transfer_dec(scope::ptr const& child) -> void;
|
||||||
|
auto transfer(scope::ptr const& child) -> void;
|
||||||
|
auto copy(scope::ptr const& child) -> void;
|
||||||
|
auto append_dec(scope::ptr const& child) -> void;
|
||||||
|
auto append(std::vector<scope*> const& childs) -> void;
|
||||||
|
auto merge(std::vector<scope*> const& childs) -> void;
|
||||||
|
auto init(scope::ptr const& child) -> void;
|
||||||
|
auto init(std::vector<scope*> const& childs) -> void;
|
||||||
|
auto find(usize start, std::string const& name) -> i32;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline auto make_scope() -> std::unique_ptr<scope>
|
||||||
|
{
|
||||||
|
return std::unique_ptr<scope>(new scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace xsk::gsc
|
19
include/xsk/gsc/common/space.hpp
Normal file
19
include/xsk/gsc/common/space.hpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace xsk::gsc
|
||||||
|
{
|
||||||
|
|
||||||
|
enum class spacing : u8
|
||||||
|
{
|
||||||
|
none = 0, // no space between tokens
|
||||||
|
null = 1, // token just after new line
|
||||||
|
back = 2, // token after space
|
||||||
|
empty = 4, // token after new line + space
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::gsc
|
41
include/xsk/gsc/common/token.hpp
Normal file
41
include/xsk/gsc/common/token.hpp
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace xsk::gsc
|
||||||
|
{
|
||||||
|
|
||||||
|
struct token
|
||||||
|
{
|
||||||
|
enum kind : u8
|
||||||
|
{
|
||||||
|
PLUS, MINUS, STAR, DIV, MOD, BITOR, BITAND, BITEXOR, SHL, SHR,
|
||||||
|
ASSIGN, PLUSEQ, MINUSEQ, STAREQ, DIVEQ, MODEQ, BITOREQ, BITANDEQ, BITEXOREQ, SHLEQ, SHREQ,
|
||||||
|
INC, DEC, GT, LT, GE, LE, NE, EQ, OR, AND, TILDE, BANG, QMARK, COLON, SHARP, COMMA, DOT,
|
||||||
|
DOUBLEDOT, ELLIPSIS, SEMICOLON, DOUBLECOLON, LBRACKET, RBRACKET, LBRACE, RBRACE, LPAREN, RPAREN,
|
||||||
|
|
||||||
|
NAME, PATH, STRING, ISTRING, INT, FLT,
|
||||||
|
|
||||||
|
DEVBEGIN, DEVEND, INLINE, INCLUDE, USINGTREE, ANIMTREE, ENDON, NOTIFY, WAIT,
|
||||||
|
WAITTILL, WAITTILLMATCH, WAITTILLFRAMEEND, WAITFRAME, IF, ELSE, DO, WHILE,
|
||||||
|
FOR, FOREACH, IN, SWITCH, CASE, DEFAULT, BREAK, CONTINUE, RETURN, BREAKPOINT,
|
||||||
|
PROFBEGIN, PROFEND, ASSERT, ASSERTEX, ASSERTMSG, THREAD, CHILDTHREAD, THISTHREAD,
|
||||||
|
CALL, TRUE, FALSE, UNDEFINED, SIZE, GAME, SELF, ANIM, LEVEL, ISDEFINED, ISTRUE,
|
||||||
|
|
||||||
|
HASH, NEWLINE, EOS, DEFINED, MACROBEGIN, MACROEND, MACROARG, MACROVAOPT, MACROVAARGS, STRINGIZE, PASTE
|
||||||
|
};
|
||||||
|
|
||||||
|
kind type;
|
||||||
|
spacing space;
|
||||||
|
location pos;
|
||||||
|
std::string data;
|
||||||
|
|
||||||
|
token(kind type, spacing space, location pos) : type{ type }, space{ space }, pos{ pos }, data{} {}
|
||||||
|
token(kind type, spacing space, location pos, std::string data) : type{ type }, space{ space }, pos{ pos }, data{ std::move(data) } {}
|
||||||
|
auto to_string() -> std::string;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::gsc
|
118
include/xsk/gsc/common/types.hpp
Normal file
118
include/xsk/gsc/common/types.hpp
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/gsc/common/asset.hpp"
|
||||||
|
#include "xsk/gsc/common/scope.hpp"
|
||||||
|
#include "xsk/gsc/common/buffer.hpp"
|
||||||
|
#include "xsk/gsc/common/assembly.hpp"
|
||||||
|
#include "xsk/gsc/common/location.hpp"
|
||||||
|
#include "xsk/gsc/common/exception.hpp"
|
||||||
|
#include "xsk/gsc/common/lookahead.hpp"
|
||||||
|
#include "xsk/gsc/common/directive.hpp"
|
||||||
|
#include "xsk/gsc/common/space.hpp"
|
||||||
|
#include "xsk/gsc/common/token.hpp"
|
||||||
|
#include "xsk/gsc/common/define.hpp"
|
||||||
|
#include "xsk/gsc/common/ast.hpp"
|
||||||
|
|
||||||
|
namespace xsk::gsc
|
||||||
|
{
|
||||||
|
|
||||||
|
enum class instance : u8
|
||||||
|
{
|
||||||
|
server,
|
||||||
|
client,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class build : u8
|
||||||
|
{
|
||||||
|
prod = 0,
|
||||||
|
dev_blocks = 1 << 0,
|
||||||
|
dev_maps = 1 << 1,
|
||||||
|
dev = dev_blocks | dev_maps,
|
||||||
|
};
|
||||||
|
|
||||||
|
inline build operator&(build lhs, build rhs)
|
||||||
|
{
|
||||||
|
return static_cast<build>(static_cast<std::underlying_type<build>::type>(lhs) & static_cast<std::underlying_type<build>::type>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class endian : u8
|
||||||
|
{
|
||||||
|
little,
|
||||||
|
big,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class system : u8
|
||||||
|
{
|
||||||
|
pc,
|
||||||
|
ps3,
|
||||||
|
xb2,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class engine : u8
|
||||||
|
{
|
||||||
|
iw5,
|
||||||
|
iw6,
|
||||||
|
iw7,
|
||||||
|
iw8,
|
||||||
|
iw9,
|
||||||
|
s1,
|
||||||
|
s2,
|
||||||
|
s4,
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct props
|
||||||
|
{
|
||||||
|
enum values : u32
|
||||||
|
{
|
||||||
|
none = 0,
|
||||||
|
str4 = 1 << 0, // strings size 4
|
||||||
|
tok4 = 1 << 1, // tokenid size 4
|
||||||
|
waitframe = 1 << 2, // waitframe opcode
|
||||||
|
params = 1 << 3, // packed func params
|
||||||
|
boolfuncs = 1 << 4, // isdefined, istrue
|
||||||
|
boolnotand = 1 << 5, // !&& expr opcode
|
||||||
|
offs8 = 1 << 6, // offset shift by 8
|
||||||
|
offs9 = 1 << 7, // offset shift by 9
|
||||||
|
hash = 1 << 9, // iw9 identifiers
|
||||||
|
farcall = 1 << 9, // iw9 new call system
|
||||||
|
foreach = 1 << 10, // iw9 foreach
|
||||||
|
};
|
||||||
|
|
||||||
|
props(values value) : value_(value) {}
|
||||||
|
operator values() { return value_; }
|
||||||
|
operator bool() { return value_ != values::none; }
|
||||||
|
props::values operator|(props::values rhs) const { return static_cast<props::values>(value_ | rhs); }
|
||||||
|
props::values operator&(props::values rhs) const { return static_cast<props::values>(value_ & rhs); }
|
||||||
|
|
||||||
|
friend props::values operator|(props::values lhs, props::values rhs)
|
||||||
|
{
|
||||||
|
return static_cast<props::values>(static_cast<std::underlying_type<props::values>::type>(lhs) | static_cast<std::underlying_type<props::values>::type>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend props::values operator&(props::values lhs, props::values rhs)
|
||||||
|
{
|
||||||
|
return static_cast<props::values>(static_cast<std::underlying_type<props::values>::type>(lhs) & static_cast<std::underlying_type<props::values>::type>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
values value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class switch_type
|
||||||
|
{
|
||||||
|
none,
|
||||||
|
integer,
|
||||||
|
string,
|
||||||
|
};
|
||||||
|
|
||||||
|
// fordward decl for modules ref
|
||||||
|
class context;
|
||||||
|
|
||||||
|
} // namespace xsk::gsc
|
155
include/xsk/gsc/compiler.hpp
Normal file
155
include/xsk/gsc/compiler.hpp
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/gsc/common/types.hpp"
|
||||||
|
|
||||||
|
namespace xsk::gsc
|
||||||
|
{
|
||||||
|
|
||||||
|
class compiler
|
||||||
|
{
|
||||||
|
context* ctx_;
|
||||||
|
assembly::ptr assembly_;
|
||||||
|
function::ptr function_;
|
||||||
|
std::vector<std::string> localfuncs_;
|
||||||
|
std::vector<std::string> stackframe_;
|
||||||
|
std::unordered_map<std::string, expr const*> constants_;
|
||||||
|
std::unordered_map<node*, scope::ptr> scopes_;
|
||||||
|
std::vector<scope*> break_blks_;
|
||||||
|
std::vector<scope*> continue_blks_;
|
||||||
|
std::string animname_;
|
||||||
|
sourcepos debug_pos_;
|
||||||
|
u32 index_;
|
||||||
|
u32 label_idx_;
|
||||||
|
bool can_break_;
|
||||||
|
bool can_continue_;
|
||||||
|
bool developer_thread_;
|
||||||
|
bool animload_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
compiler(context* ctx);
|
||||||
|
auto compile(program const& data) -> assembly::ptr;
|
||||||
|
auto compile(std::string const& file, std::vector<u8>& data) -> assembly::ptr;
|
||||||
|
|
||||||
|
private:
|
||||||
|
auto emit_program(program const& prog) -> void;
|
||||||
|
auto emit_decl(decl const& dec) -> void;
|
||||||
|
auto emit_decl_usingtree(decl_usingtree const& animtree) -> void;
|
||||||
|
auto emit_decl_constant(decl_constant const& constant) -> void;
|
||||||
|
auto emit_decl_function(decl_function const& func) -> void;
|
||||||
|
auto emit_stmt(stmt const& stm, scope& scp, bool last) -> void;
|
||||||
|
auto emit_stmt_list(stmt_list const& stm, scope& scp, bool last) -> void;
|
||||||
|
auto emit_stmt_comp(stmt_comp const& stm, scope& scp, bool last) -> void;
|
||||||
|
auto emit_stmt_dev(stmt_dev const& stm, scope& scp, bool last) -> void;
|
||||||
|
auto emit_stmt_expr(stmt_expr const& stm, scope& scp) -> void;
|
||||||
|
auto emit_stmt_endon(stmt_endon const& stm, scope& scp) -> void;
|
||||||
|
auto emit_stmt_notify(stmt_notify const& stm, scope& scp) -> void;
|
||||||
|
auto emit_stmt_wait(stmt_wait const& stm, scope& scp) -> void;
|
||||||
|
auto emit_stmt_waittill(stmt_waittill const& stm, scope& scp) -> void;
|
||||||
|
auto emit_stmt_waittillmatch(stmt_waittillmatch const& stm, scope& scp) -> void;
|
||||||
|
auto emit_stmt_waittillframeend(stmt_waittillframeend const& stm, scope& scp) -> void;
|
||||||
|
auto emit_stmt_waitframe(stmt_waitframe const& stm, scope& scp) -> void;
|
||||||
|
auto emit_stmt_if(stmt_if const& stm, scope& scp, bool last) -> void;
|
||||||
|
auto emit_stmt_ifelse(stmt_ifelse const& stm, scope& scp, bool last) -> void;
|
||||||
|
auto emit_stmt_while(stmt_while const& stm, scope& scp) -> void;
|
||||||
|
auto emit_stmt_dowhile(stmt_dowhile const& stm, scope& scp) -> void;
|
||||||
|
auto emit_stmt_for(stmt_for const& stm, scope& scp) -> void;
|
||||||
|
auto emit_stmt_foreach(stmt_foreach const& stm, scope& scp) -> void;
|
||||||
|
auto emit_stmt_switch(stmt_switch const& stm, scope& scp) -> void;
|
||||||
|
auto emit_stmt_case(stmt_case const& stm, scope& scp) -> void;
|
||||||
|
auto emit_stmt_default(stmt_default const& stm, scope& scp) -> void;
|
||||||
|
auto emit_stmt_break(stmt_break const& stm, scope& scp) -> void;
|
||||||
|
auto emit_stmt_continue(stmt_continue const& stm, scope& scp) -> void;
|
||||||
|
auto emit_stmt_return(stmt_return const& stm, scope& scp) -> void;
|
||||||
|
auto emit_stmt_breakpoint(stmt_breakpoint const& stm, scope& scp) -> void;
|
||||||
|
auto emit_stmt_prof_begin(stmt_prof_begin const& stm, scope& scp) -> void;
|
||||||
|
auto emit_stmt_prof_end(stmt_prof_end const& stm, scope& scp) -> void;
|
||||||
|
auto emit_stmt_assert(stmt_assert const& stm, scope& scp) -> void;
|
||||||
|
auto emit_stmt_assertex(stmt_assertex const& stm, scope& scp) -> void;
|
||||||
|
auto emit_stmt_assertmsg(stmt_assertmsg const& stm, scope& scp) -> void;
|
||||||
|
auto emit_expr(expr const& exp, scope& scp) -> void;
|
||||||
|
auto emit_expr_assign(expr_assign const& exp, scope& scp) -> void;
|
||||||
|
auto emit_expr_clear(expr const& exp, scope& scp) -> void;
|
||||||
|
auto emit_expr_clear_local(expr_identifier const& exp, scope& scp) -> void;
|
||||||
|
auto emit_expr_increment(expr_increment const& exp, scope& scp, bool is_stmt) -> void;
|
||||||
|
auto emit_expr_decrement(expr_decrement const& exp, scope& scp, bool is_stmt) -> void;
|
||||||
|
auto emit_expr_ternary(expr_ternary const& exp, scope& scp) -> void;
|
||||||
|
auto emit_expr_binary(expr_binary const& exp, scope& scp) -> void;
|
||||||
|
auto emit_expr_complement(expr_complement const& exp, scope& scp) -> void;
|
||||||
|
auto emit_expr_negate(expr_negate const& exp, scope& scp) -> void;
|
||||||
|
auto emit_expr_not(expr_not const& exp, scope& scp) -> void;
|
||||||
|
auto emit_expr_call(expr_call const& exp, scope& scp, bool is_stmt) -> void;
|
||||||
|
auto emit_expr_call_pointer(expr_pointer const& exp, scope& scp, bool is_stmt) -> void;
|
||||||
|
auto emit_expr_call_function(expr_function const& exp, scope& scp, bool is_stmt) -> void;
|
||||||
|
auto emit_expr_method(expr_method const& exp, scope& scp, bool is_stmt) -> void;
|
||||||
|
auto emit_expr_method_pointer(expr_pointer const& exp, expr const& obj, scope& scp, bool is_stmt) -> void;
|
||||||
|
auto emit_expr_method_function(expr_function const& exp, expr const& obj, scope& scp, bool is_stmt) -> void;
|
||||||
|
auto emit_expr_add_array(expr_add_array const& exp, scope& scp) -> void;
|
||||||
|
auto emit_expr_parameters(expr_parameters const& exp, scope& scp) -> void;
|
||||||
|
auto emit_expr_arguments(expr_arguments const& exp, scope& scp) -> void;
|
||||||
|
auto emit_expr_isdefined(expr_isdefined const& exp, scope& scp) -> void;
|
||||||
|
auto emit_expr_istrue(expr_istrue const& exp, scope& scp) -> void;
|
||||||
|
auto emit_expr_reference(expr_reference const& exp, scope& scp) -> void;
|
||||||
|
auto emit_expr_size(expr_size const& exp, scope& scp) -> void;
|
||||||
|
auto emit_expr_tuple(expr_tuple const& exp, scope& scp) -> void;
|
||||||
|
auto emit_expr_variable_ref(expr const& exp, scope& scp, bool set) -> void;
|
||||||
|
auto emit_expr_array_ref(expr_array const& exp, scope& scp, bool set) -> void;
|
||||||
|
auto emit_expr_field_ref(expr_field const& exp, scope& scp, bool set) -> void;
|
||||||
|
auto emit_expr_local_ref(expr_identifier const& exp, scope& scp, bool set) -> void;
|
||||||
|
auto emit_expr_variable(expr const& exp, scope& scp) -> void;
|
||||||
|
auto emit_expr_array(expr_array const& exp, scope& scp) -> void;
|
||||||
|
auto emit_expr_field(expr_field const& exp, scope& scp) -> void;
|
||||||
|
auto emit_expr_local(expr_identifier const& exp, scope& scp) -> void;
|
||||||
|
auto emit_expr_object(expr const& exp, scope& scp) -> void;
|
||||||
|
auto emit_expr_vector(expr_vector const& exp, scope& scp) -> void;
|
||||||
|
auto emit_expr_animation(expr_animation const& exp) -> void;
|
||||||
|
auto emit_expr_animtree(expr_animtree const& exp) -> void;
|
||||||
|
auto emit_expr_istring(expr_istring const& exp) -> void;
|
||||||
|
auto emit_expr_string(expr_string const& exp) -> void;
|
||||||
|
auto emit_expr_float(expr_float const& exp) -> void;
|
||||||
|
auto emit_expr_integer(expr_integer const& exp) -> void;
|
||||||
|
auto emit_expr_false(expr_false const& exp) -> void;
|
||||||
|
auto emit_expr_true(expr_true const& exp) -> void;
|
||||||
|
auto emit_create_local_vars(scope& scp) -> void;
|
||||||
|
auto emit_remove_local_vars(scope& scp) -> void;
|
||||||
|
auto emit_opcode(opcode op) -> void;
|
||||||
|
auto emit_opcode(opcode op, std::string const& data) -> void;
|
||||||
|
auto emit_opcode(opcode op, std::vector<std::string> const& data) -> void;
|
||||||
|
auto process_function(decl_function const& func) -> void;
|
||||||
|
auto process_stmt(stmt const& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_list(stmt_list const& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_comp(stmt_comp const& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_dev(stmt_dev const& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_expr(stmt_expr const& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_waittill(stmt_waittill const& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_if(stmt_if const& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_ifelse(stmt_ifelse const& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_while(stmt_while const& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_dowhile(stmt_dowhile const& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_for(stmt_for const& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_foreach(stmt_foreach const& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_switch(stmt_switch const& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_break(stmt_break const& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_continue(stmt_continue const& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_return(stmt_return const& stm, scope& scp) -> void;
|
||||||
|
auto process_expr(expr const& exp, scope& scp) -> void;
|
||||||
|
auto process_expr_tuple(expr_tuple const& exp, scope& scp) -> void;
|
||||||
|
auto process_expr_parameters(expr_parameters const& exp, scope& scp) -> void;
|
||||||
|
auto variable_register(expr_identifier const& exp, scope& scp) -> void;
|
||||||
|
auto variable_initialized(expr_identifier const& exp, scope& scp) -> bool;
|
||||||
|
auto variable_initialize(expr_identifier const& exp, scope& scp) -> u8;
|
||||||
|
auto variable_create(expr_identifier const& exp, scope& scp) -> u8;
|
||||||
|
auto variable_access(expr_identifier const& exp, scope& scp) -> u8;
|
||||||
|
auto resolve_function_type(expr_function const& exp, std::string& path) -> call::type;
|
||||||
|
auto resolve_reference_type(expr_reference const& exp, std::string& path, bool& method) -> call::type;
|
||||||
|
auto is_constant_condition(expr const& exp) -> bool;
|
||||||
|
auto insert_label(std::string const& label) -> void;
|
||||||
|
auto create_label() -> std::string;
|
||||||
|
auto insert_label() -> std::string;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::gsc
|
149
include/xsk/gsc/context.hpp
Normal file
149
include/xsk/gsc/context.hpp
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/gsc/common/types.hpp"
|
||||||
|
#include "xsk/gsc/source.hpp"
|
||||||
|
#include "xsk/gsc/assembler.hpp"
|
||||||
|
#include "xsk/gsc/disassembler.hpp"
|
||||||
|
#include "xsk/gsc/compiler.hpp"
|
||||||
|
#include "xsk/gsc/decompiler.hpp"
|
||||||
|
|
||||||
|
namespace xsk::gsc
|
||||||
|
{
|
||||||
|
|
||||||
|
class context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using fs_callback = std::function<std::pair<buffer, std::vector<u8>>(context const*, std::string const&)>;
|
||||||
|
|
||||||
|
context(props props, engine engine, endian endian, system system, u32 str_count);
|
||||||
|
|
||||||
|
auto props() const -> props { return props_; }
|
||||||
|
|
||||||
|
auto build() const -> build { return build_; }
|
||||||
|
|
||||||
|
auto engine() const -> engine { return engine_; }
|
||||||
|
|
||||||
|
auto endian() const -> endian { return endian_; }
|
||||||
|
|
||||||
|
auto system() const -> system { return system_; }
|
||||||
|
|
||||||
|
auto instance() const -> instance { return instance_; }
|
||||||
|
|
||||||
|
auto str_count() const -> u32 { return str_count_; }
|
||||||
|
|
||||||
|
auto source() -> source& { return source_; }
|
||||||
|
|
||||||
|
auto assembler() -> assembler& { return assembler_; }
|
||||||
|
|
||||||
|
auto disassembler() -> disassembler& { return disassembler_; }
|
||||||
|
|
||||||
|
auto compiler() -> compiler& { return compiler_; }
|
||||||
|
|
||||||
|
auto decompiler() -> decompiler& { return decompiler_; }
|
||||||
|
|
||||||
|
auto func_map() const -> std::unordered_map<std::string_view, u16> const& { return func_map_rev_; }
|
||||||
|
auto meth_map() const -> std::unordered_map<std::string_view, u16> const& { return meth_map_rev_; }
|
||||||
|
|
||||||
|
auto init(gsc::build build, fs_callback callback) -> void;
|
||||||
|
|
||||||
|
auto cleanup() -> void;
|
||||||
|
|
||||||
|
auto engine_name() const -> std::string_view;
|
||||||
|
|
||||||
|
auto opcode_size(opcode op) const -> u32;
|
||||||
|
|
||||||
|
auto opcode_id(opcode op) const -> u8;
|
||||||
|
|
||||||
|
auto opcode_name(opcode op) const -> std::string;
|
||||||
|
|
||||||
|
auto opcode_enum(std::string const& name) const -> opcode;
|
||||||
|
|
||||||
|
auto opcode_enum(u8 id) const -> opcode;
|
||||||
|
|
||||||
|
auto func_id(std::string const& name) const -> u16;
|
||||||
|
|
||||||
|
auto func_name(u16 id) const -> std::string;
|
||||||
|
|
||||||
|
auto func2_id(std::string const& name) const -> u64;
|
||||||
|
|
||||||
|
auto func2_name(u64 id) const -> std::string;
|
||||||
|
|
||||||
|
auto func_exists(std::string const& name) const -> bool;
|
||||||
|
|
||||||
|
auto func_add(std::string const& name, u16 id) -> void;
|
||||||
|
|
||||||
|
auto meth_id(std::string const& name) const -> u16;
|
||||||
|
|
||||||
|
auto meth_name(u16 id) const -> std::string;
|
||||||
|
|
||||||
|
auto meth2_id(std::string const& name) const -> u64;
|
||||||
|
|
||||||
|
auto meth2_name(u64 id) const -> std::string;
|
||||||
|
|
||||||
|
auto meth_exists(std::string const& name) const -> bool;
|
||||||
|
|
||||||
|
auto meth_add(std::string const& name, u16 id) -> void;
|
||||||
|
|
||||||
|
auto token_id(std::string const& name) const -> u32;
|
||||||
|
|
||||||
|
auto token_name(u32 id) const -> std::string;
|
||||||
|
|
||||||
|
auto path_id(std::string const& name) const -> u64;
|
||||||
|
|
||||||
|
auto path_name(u64 id) const -> std::string;
|
||||||
|
|
||||||
|
auto hash_id(std::string const& name) const -> u64;
|
||||||
|
|
||||||
|
auto hash_name(u64 id) const -> std::string;
|
||||||
|
|
||||||
|
auto make_token(std::string_view str) const -> std::string;
|
||||||
|
|
||||||
|
auto load_header(std::string const& name) -> std::tuple<std::string const*, char const*, usize>;
|
||||||
|
|
||||||
|
auto load_include(std::string const& name) -> bool;
|
||||||
|
|
||||||
|
auto init_includes() -> void;
|
||||||
|
|
||||||
|
auto is_includecall(std::string const& name, std::string& path) -> bool;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
gsc::props props_;
|
||||||
|
gsc::build build_;
|
||||||
|
gsc::engine engine_;
|
||||||
|
gsc::endian endian_;
|
||||||
|
gsc::system system_;
|
||||||
|
gsc::instance instance_;
|
||||||
|
u32 str_count_;
|
||||||
|
gsc::source source_;
|
||||||
|
gsc::assembler assembler_;
|
||||||
|
gsc::disassembler disassembler_;
|
||||||
|
gsc::compiler compiler_;
|
||||||
|
gsc::decompiler decompiler_;
|
||||||
|
fs_callback fs_callback_;
|
||||||
|
std::unordered_map<opcode, std::string_view> opcode_map_;
|
||||||
|
std::unordered_map<std::string_view, opcode> opcode_map_rev_;
|
||||||
|
std::unordered_map<u8, opcode> code_map_;
|
||||||
|
std::unordered_map<opcode, u8> code_map_rev_;
|
||||||
|
std::unordered_map<u16, std::string_view> func_map_;
|
||||||
|
std::unordered_map<std::string_view, u16> func_map_rev_;
|
||||||
|
std::unordered_map<u16, std::string_view> meth_map_;
|
||||||
|
std::unordered_map<std::string_view, u16> meth_map_rev_;
|
||||||
|
std::unordered_map<u32, std::string_view> token_map_;
|
||||||
|
std::unordered_map<std::string_view, u32> token_map_rev_;
|
||||||
|
std::unordered_map<u64, std::string_view> func_map2_;
|
||||||
|
std::unordered_map<u64, std::string_view> meth_map2_;
|
||||||
|
std::unordered_map<u64, std::string_view> path_map_;
|
||||||
|
std::unordered_map<u64, std::string_view> hash_map_;
|
||||||
|
std::unordered_map<std::string, std::vector<u8>> header_files_;
|
||||||
|
std::unordered_set<std::string_view> includes_;
|
||||||
|
std::unordered_map<std::string, std::vector<std::string>> include_cache_;
|
||||||
|
std::unordered_set<std::string> new_func_map_;
|
||||||
|
std::unordered_set<std::string> new_meth_map_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::gsc
|
100
include/xsk/gsc/decompiler.hpp
Normal file
100
include/xsk/gsc/decompiler.hpp
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/gsc/common/types.hpp"
|
||||||
|
|
||||||
|
namespace xsk::gsc
|
||||||
|
{
|
||||||
|
|
||||||
|
class decompiler
|
||||||
|
{
|
||||||
|
context const* ctx_;
|
||||||
|
program::ptr program_;
|
||||||
|
decl_function::ptr func_;
|
||||||
|
std::unordered_map<u32, std::string> labels_;
|
||||||
|
std::vector<std::string> expr_labels_;
|
||||||
|
std::vector<std::string> tern_labels_;
|
||||||
|
std::stack<node::ptr> stack_;
|
||||||
|
bool in_waittill_;
|
||||||
|
locjmp locs_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
decompiler(context const* ctx);
|
||||||
|
auto decompile(assembly const& data) -> program::ptr;
|
||||||
|
|
||||||
|
private:
|
||||||
|
auto decompile_function(function const& func) -> void;
|
||||||
|
auto decompile_instruction(instruction const& inst) -> void;
|
||||||
|
auto decompile_expressions(instruction const& inst) -> void;
|
||||||
|
auto decompile_statements(stmt_list& stm) -> void;
|
||||||
|
auto decompile_loops(stmt_list& stm) -> void;
|
||||||
|
auto decompile_switches(stmt_list& stm) -> void;
|
||||||
|
auto decompile_ifelses(stmt_list& stm) -> void;
|
||||||
|
auto decompile_aborts(stmt_list& stm) -> void;
|
||||||
|
auto decompile_tuples(stmt_list& stm) -> void;
|
||||||
|
auto decompile_if(stmt_list& stm, usize begin, usize end) -> void;
|
||||||
|
auto decompile_ifelse(stmt_list& stm, usize begin, usize end) -> void;
|
||||||
|
auto decompile_ifelse_end(stmt_list& stm, usize begin, usize end) -> void;
|
||||||
|
auto decompile_inf(stmt_list& stm, usize begin, usize end) -> void;
|
||||||
|
auto decompile_loop(stmt_list& stm, usize begin, usize end) -> void;
|
||||||
|
auto decompile_while(stmt_list& stm, usize begin, usize end) -> void;
|
||||||
|
auto decompile_dowhile(stmt_list& stm, usize begin, usize end) -> void;
|
||||||
|
auto decompile_for(stmt_list& stm, usize begin, usize end) -> void;
|
||||||
|
auto decompile_foreach(stmt_list& stm, usize begin, usize end) -> void;
|
||||||
|
auto decompile_switch(stmt_list& stm, usize begin, usize end) -> void;
|
||||||
|
auto find_location_reference(stmt_list const& stm, usize begin, usize end, std::string const& loc) -> bool;
|
||||||
|
auto find_location_index(stmt_list const& stm, std::string const& loc) -> usize;
|
||||||
|
auto last_location_index(stmt_list const& stm, usize index) -> bool;
|
||||||
|
auto process_function(decl_function& func) -> void;
|
||||||
|
auto process_stmt(stmt& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_list(stmt_list& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_comp(stmt_comp& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_dev(stmt_dev& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_expr(stmt_expr& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_endon(stmt_endon& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_notify(stmt_notify& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_wait(stmt_wait& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_waittill(stmt_waittill& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_waittillmatch(stmt_waittillmatch& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_if(stmt_if& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_ifelse(stmt_ifelse& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_while(stmt_while& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_dowhile(stmt_dowhile& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_for(stmt_for& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_foreach(stmt_foreach& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_switch(stmt_switch& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_break(stmt_break& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_continue(stmt_continue& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_return(stmt_return& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_create(stmt_create& stm, scope& scp) -> void;
|
||||||
|
auto process_stmt_remove(stmt_remove& stm, scope& scp) -> void;
|
||||||
|
auto process_expr(expr::ptr& exp, scope& scp) -> void;
|
||||||
|
auto process_expr_increment(expr_increment& exp, scope& scp) -> void;
|
||||||
|
auto process_expr_decrement(expr_decrement& exp, scope& scp) -> void;
|
||||||
|
auto process_expr_assign(expr_assign::ptr& exp, scope& scp) -> void;
|
||||||
|
auto process_expr_ternary(expr_ternary& exp, scope& scp) -> void;
|
||||||
|
auto process_expr_binary(expr_binary& exp, scope& scp) -> void;
|
||||||
|
auto process_expr_complement(expr_complement& exp, scope& scp) -> void;
|
||||||
|
auto process_expr_not(expr_not& exp, scope& scp) -> void;
|
||||||
|
auto process_expr_call(expr_call& exp, scope& scp) -> void;
|
||||||
|
auto process_expr_method(expr_method& exp, scope& scp) -> void;
|
||||||
|
auto process_expr_call_pointer(expr_pointer& exp, scope& scp) -> void;
|
||||||
|
auto process_expr_call_function(expr_function& exp, scope& scp) -> void;
|
||||||
|
auto process_expr_method_pointer(expr_pointer& exp, expr::ptr& obj, scope& scp) -> void;
|
||||||
|
auto process_expr_method_function(expr_function& exp, expr::ptr& obj, scope& scp) -> void;
|
||||||
|
auto process_expr_arguments(expr_arguments& exp, scope& scp) -> void;
|
||||||
|
auto process_expr_add_array(expr_add_array& exp, scope& scp) -> void;
|
||||||
|
auto process_expr_size(expr_size& exp, scope& scp) -> void;
|
||||||
|
auto process_expr_tuple(expr_tuple& exp, scope& scp) -> void;
|
||||||
|
auto process_expr_array(expr_array& exp, scope& scp) -> void;
|
||||||
|
auto process_expr_field(expr_field& exp, scope& scp) -> void;
|
||||||
|
auto process_expr_vector(expr_vector& exp, scope& scp) -> void;
|
||||||
|
auto process_expr_var_create(expr::ptr& exp, scope& scp) -> void;
|
||||||
|
auto process_expr_var_access(expr::ptr& exp, scope& scp) -> void;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::gsc
|
45
include/xsk/gsc/disassembler.hpp
Normal file
45
include/xsk/gsc/disassembler.hpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/utils/reader.hpp"
|
||||||
|
#include "xsk/gsc/common/types.hpp"
|
||||||
|
|
||||||
|
namespace xsk::gsc
|
||||||
|
{
|
||||||
|
|
||||||
|
class disassembler
|
||||||
|
{
|
||||||
|
context const* ctx_;
|
||||||
|
function::ptr func_;
|
||||||
|
assembly::ptr assembly_;
|
||||||
|
utils::reader script_;
|
||||||
|
utils::reader stack_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
disassembler(context const* ctx);
|
||||||
|
auto disassemble(buffer const& script, buffer const& stack) -> assembly::ptr;
|
||||||
|
auto disassemble(std::vector<u8> const& script, std::vector<u8> const& stack) -> assembly::ptr;
|
||||||
|
auto disassemble(u8 const* script, usize script_size, u8 const* stack, usize stack_size) -> assembly::ptr;
|
||||||
|
|
||||||
|
private:
|
||||||
|
auto dissasemble_function(function& func) -> void;
|
||||||
|
auto dissasemble_instruction(instruction& inst) -> void;
|
||||||
|
auto disassemble_builtin_call(instruction& inst, bool method, bool args) -> void;
|
||||||
|
auto disassemble_local_call(instruction& inst, bool thread) -> void;
|
||||||
|
auto disassemble_far_call(instruction& inst, bool thread) -> void;
|
||||||
|
auto disassemble_switch(instruction& inst) -> void;
|
||||||
|
auto disassemble_end_switch(instruction& inst) -> void;
|
||||||
|
auto disassemble_field_variable(instruction& inst) -> void;
|
||||||
|
auto disassemble_formal_params(instruction& inst) -> void;
|
||||||
|
auto disassemble_jump(instruction& inst, bool expr, bool back) -> void;
|
||||||
|
auto disassemble_offset() -> i32;
|
||||||
|
auto resolve_functions() -> void;
|
||||||
|
auto resolve_function(std::string const& index) -> std::string;
|
||||||
|
auto decrypt_string(std::string const& str) -> std::string;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::gsc
|
26
include/xsk/gsc/engine/h1.hpp
Normal file
26
include/xsk/gsc/engine/h1.hpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/stdinc.hpp"
|
||||||
|
#include "xsk/gsc/context.hpp"
|
||||||
|
|
||||||
|
namespace xsk::gsc::h1
|
||||||
|
{
|
||||||
|
// H1 PC 1.15.1251288
|
||||||
|
constexpr usize code_count = 154;
|
||||||
|
constexpr usize func_count = 778;
|
||||||
|
constexpr usize meth_count = 1415;
|
||||||
|
constexpr usize token_count = 42947;
|
||||||
|
constexpr u32 max_string_id = 42989;
|
||||||
|
|
||||||
|
class context : public gsc::context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
context();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::gsc::h1
|
26
include/xsk/gsc/engine/h2.hpp
Normal file
26
include/xsk/gsc/engine/h2.hpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/stdinc.hpp"
|
||||||
|
#include "xsk/gsc/context.hpp"
|
||||||
|
|
||||||
|
namespace xsk::gsc::h2
|
||||||
|
{
|
||||||
|
// H2 PC 1.0.1280159
|
||||||
|
constexpr usize code_count = 154;
|
||||||
|
constexpr usize func_count = 800;
|
||||||
|
constexpr usize meth_count = 1491;
|
||||||
|
constexpr usize token_count = 42524;
|
||||||
|
constexpr u32 max_string_id = 54743;
|
||||||
|
|
||||||
|
class context : public gsc::context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
context();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::gsc::h2
|
26
include/xsk/gsc/engine/iw5_pc.hpp
Normal file
26
include/xsk/gsc/engine/iw5_pc.hpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/stdinc.hpp"
|
||||||
|
#include "xsk/gsc/context.hpp"
|
||||||
|
|
||||||
|
namespace xsk::gsc::iw5_pc
|
||||||
|
{
|
||||||
|
// IW5 PC 1.9.388110
|
||||||
|
constexpr usize code_count = 153;
|
||||||
|
constexpr usize func_count = 455;
|
||||||
|
constexpr usize meth_count = 780;
|
||||||
|
constexpr usize token_count = 6306;
|
||||||
|
constexpr u32 max_string_id = 33386;
|
||||||
|
|
||||||
|
class context : public gsc::context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
context();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::gsc::iw5_pc
|
26
include/xsk/gsc/engine/iw5_ps.hpp
Normal file
26
include/xsk/gsc/engine/iw5_ps.hpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/stdinc.hpp"
|
||||||
|
#include "xsk/gsc/context.hpp"
|
||||||
|
|
||||||
|
namespace xsk::gsc::iw5_ps
|
||||||
|
{
|
||||||
|
// IW5 PS
|
||||||
|
constexpr usize code_count = 153;
|
||||||
|
constexpr usize func_count = 452;
|
||||||
|
constexpr usize meth_count = 777;
|
||||||
|
constexpr usize token_count = 14221;
|
||||||
|
constexpr u32 max_string_id = 33360;
|
||||||
|
|
||||||
|
class context : public gsc::context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
context();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::gsc::iw5_ps
|
26
include/xsk/gsc/engine/iw5_xb.hpp
Normal file
26
include/xsk/gsc/engine/iw5_xb.hpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/stdinc.hpp"
|
||||||
|
#include "xsk/gsc/context.hpp"
|
||||||
|
|
||||||
|
namespace xsk::gsc::iw5_xb
|
||||||
|
{
|
||||||
|
// IW5 XB 1.8.388110
|
||||||
|
constexpr usize code_count = 153;
|
||||||
|
constexpr usize func_count = 455;
|
||||||
|
constexpr usize meth_count = 779;
|
||||||
|
constexpr usize token_count = 14221;
|
||||||
|
constexpr u32 max_string_id = 33386;
|
||||||
|
|
||||||
|
class context : public gsc::context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
context();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::gsc::iw5_xb
|
26
include/xsk/gsc/engine/iw6_pc.hpp
Normal file
26
include/xsk/gsc/engine/iw6_pc.hpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/stdinc.hpp"
|
||||||
|
#include "xsk/gsc/context.hpp"
|
||||||
|
|
||||||
|
namespace xsk::gsc::iw6_pc
|
||||||
|
{
|
||||||
|
// IW6 PC 3.15.146
|
||||||
|
constexpr usize code_count = 153;
|
||||||
|
constexpr usize func_count = 605;
|
||||||
|
constexpr usize meth_count = 1066;
|
||||||
|
constexpr usize token_count = 38306;
|
||||||
|
constexpr u32 max_string_id = 38305;
|
||||||
|
|
||||||
|
class context : public gsc::context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
context();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::gsc::iw6_pc
|
26
include/xsk/gsc/engine/iw6_ps.hpp
Normal file
26
include/xsk/gsc/engine/iw6_ps.hpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/stdinc.hpp"
|
||||||
|
#include "xsk/gsc/context.hpp"
|
||||||
|
|
||||||
|
namespace xsk::gsc::iw6_ps
|
||||||
|
{
|
||||||
|
|
||||||
|
constexpr usize code_count = 153;
|
||||||
|
constexpr usize func_count = 3;
|
||||||
|
constexpr usize meth_count = 0;
|
||||||
|
constexpr usize token_count = 0;
|
||||||
|
constexpr u32 max_string_id = 0x95A1;
|
||||||
|
|
||||||
|
class context : public gsc::context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
context();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::gsc::iw6_ps
|
26
include/xsk/gsc/engine/iw6_xb.hpp
Normal file
26
include/xsk/gsc/engine/iw6_xb.hpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/stdinc.hpp"
|
||||||
|
#include "xsk/gsc/context.hpp"
|
||||||
|
|
||||||
|
namespace xsk::gsc::iw6_xb
|
||||||
|
{
|
||||||
|
|
||||||
|
constexpr usize code_count = 153;
|
||||||
|
constexpr usize func_count = 3;
|
||||||
|
constexpr usize meth_count = 0;
|
||||||
|
constexpr usize token_count = 0;
|
||||||
|
constexpr u32 max_string_id = 0x8EFA;
|
||||||
|
|
||||||
|
class context : public gsc::context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
context();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::gsc::iw6_xb
|
26
include/xsk/gsc/engine/iw7.hpp
Normal file
26
include/xsk/gsc/engine/iw7.hpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/stdinc.hpp"
|
||||||
|
#include "xsk/gsc/context.hpp"
|
||||||
|
|
||||||
|
namespace xsk::gsc::iw7
|
||||||
|
{
|
||||||
|
|
||||||
|
constexpr usize code_count = 153;
|
||||||
|
constexpr usize func_count = 807;
|
||||||
|
constexpr usize meth_count = 1500;
|
||||||
|
constexpr usize token_count = 682;
|
||||||
|
constexpr u32 max_string_id = 0x13FCC;
|
||||||
|
|
||||||
|
class context : public gsc::context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
context();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::gsc::iw7
|
26
include/xsk/gsc/engine/iw8.hpp
Normal file
26
include/xsk/gsc/engine/iw8.hpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/stdinc.hpp"
|
||||||
|
#include "xsk/gsc/context.hpp"
|
||||||
|
|
||||||
|
namespace xsk::gsc::iw8
|
||||||
|
{
|
||||||
|
|
||||||
|
constexpr usize code_count = 190;
|
||||||
|
constexpr usize func_count = 1065;
|
||||||
|
constexpr usize meth_count = 2032;
|
||||||
|
constexpr usize token_count = 72014;
|
||||||
|
constexpr u32 max_string_id = 0x1472F;
|
||||||
|
|
||||||
|
class context : public gsc::context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
context();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::gsc::iw8
|
26
include/xsk/gsc/engine/iw9.hpp
Normal file
26
include/xsk/gsc/engine/iw9.hpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/stdinc.hpp"
|
||||||
|
#include "xsk/gsc/context.hpp"
|
||||||
|
|
||||||
|
namespace xsk::gsc::iw9
|
||||||
|
{
|
||||||
|
|
||||||
|
constexpr usize code_count = 167;
|
||||||
|
constexpr usize func_count = 905;
|
||||||
|
constexpr usize meth_count = 1469;
|
||||||
|
constexpr usize path_count = 1467;
|
||||||
|
constexpr usize hash_count = 73500;
|
||||||
|
|
||||||
|
class context : public gsc::context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
context();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::gsc::iw9
|
26
include/xsk/gsc/engine/s1_pc.hpp
Normal file
26
include/xsk/gsc/engine/s1_pc.hpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
// Copyright 2024 xensik. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a GNU GPLv3 license
|
||||||
|
// that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "xsk/stdinc.hpp"
|
||||||
|
#include "xsk/gsc/context.hpp"
|
||||||
|
|
||||||
|
namespace xsk::gsc::s1_pc
|
||||||
|
{
|
||||||
|
|
||||||
|
constexpr usize code_count = 154;
|
||||||
|
constexpr usize func_count = 735;
|
||||||
|
constexpr usize meth_count = 1389;
|
||||||
|
constexpr usize token_count = 42942;
|
||||||
|
constexpr u32 max_string_id = 0xA7DC;
|
||||||
|
|
||||||
|
class context : public gsc::context
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
context();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace xsk::gsc::s1_pc
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user