Compare commits
27 Commits
dev
...
feature/t6
Author | SHA1 | Date | |
---|---|---|---|
|
30352b21a7 | ||
|
0da3653f26 | ||
|
628749631b | ||
|
18db7e071a | ||
|
15f76542b1 | ||
|
73ed709fed | ||
|
4fec6cda20 | ||
|
66b5c82840 | ||
|
a16c70bd54 | ||
|
328961ee83 | ||
|
8e5cea1af7 | ||
|
4d6d9916bf | ||
|
1a5e39fa0e | ||
|
de254a1293 | ||
|
dcff855efb | ||
|
bbce74f47a | ||
|
2c0a5dce18 | ||
|
89e34cd3a1 | ||
|
7eed6f45f8 | ||
|
5eb63e3284 | ||
|
05fc8a7421 | ||
|
ec91109cc3 | ||
|
0ec0b4d6f5 | ||
|
6a0419b5bf | ||
|
f53fb4fe47 | ||
|
b6777295a1 | ||
|
b1ad170030 |
3
.github/FUNDING.yml
vendored
3
.github/FUNDING.yml
vendored
@ -1,3 +1,2 @@
|
||||
github: xensik
|
||||
ko_fi: xensik
|
||||
custom: paypal.me/xensik
|
||||
custom: https://www.paypal.me/xensik
|
||||
|
7
.github/dependabot.yml
vendored
Normal file
7
.github/dependabot.yml
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "gitsubmodule"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
open-pull-requests-limit: 10
|
220
.github/workflows/main.yml
vendored
220
.github/workflows/main.yml
vendored
@ -1,220 +0,0 @@
|
||||
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,15 +149,18 @@ user*.bat
|
||||
# VScode
|
||||
.vscode/
|
||||
|
||||
# Output folders
|
||||
renamed/
|
||||
parsed/
|
||||
compiled/
|
||||
decompiled/
|
||||
assembled/
|
||||
disassembled/
|
||||
|
||||
data/*
|
||||
|
||||
# Version file
|
||||
include/xsk/version.hpp
|
||||
data/iw5/
|
||||
data/iw6/
|
||||
data/iw7/
|
||||
data/iw8/
|
||||
data/h1/
|
||||
data/h2/
|
||||
data/s1/
|
||||
data/s2/
|
||||
data/s4/
|
||||
data/t6/
|
||||
|
4
.gitmodules
vendored
4
.gitmodules
vendored
@ -1,7 +1,3 @@
|
||||
[submodule "deps/zlib"]
|
||||
path = deps/zlib
|
||||
url = https://github.com/madler/zlib
|
||||
branch = master
|
||||
[submodule "deps/cxxopts"]
|
||||
path = deps/cxxopts
|
||||
url = https://github.com/jarro2783/cxxopts.git
|
||||
|
10
Dockerfile
10
Dockerfile
@ -1,10 +0,0 @@
|
||||
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,52 +1,38 @@
|
||||
[![sonar](https://sonarcloud.io/api/project_badges/measure?project=xensik_gsc-tool&metric=alert_status)](https://sonarcloud.io/summary/overall?id=xensik_gsc-tool)
|
||||
[![build](https://github.com/xensik/gsc-tool/workflows/Build/badge.svg)](https://github.com/xensik/gsc-tool/actions)
|
||||
[![issues](https://img.shields.io/github/issues/xensik/gsc-tool)](https://github.com/xensik/gsc-tool/issues)
|
||||
[![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)
|
||||
[![Build status](https://ci.appveyor.com/api/projects/status/defmhg4753c1ap1o?svg=true)](https://ci.appveyor.com/project/xensik/gsc-tool)
|
||||
![license](https://img.shields.io/github/license/xensik/gsc-tool.svg)
|
||||
[![GitHub 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)
|
||||
|
||||
# GSC Tool
|
||||
A utility to compile & decompile IW engine game scripts.
|
||||
|
||||
## Supported Games
|
||||
- **IW5** *(Call of Duty: Modern Warfare 3)* `PC` `PS3` `Xbox 360`
|
||||
- **IW6** *(Call of Duty: Ghosts)* `PC` `PS3` `PS4` `Xbox 360` `Xbox One`
|
||||
- **IW7** *(Call of Duty: Infinite Warfare)* `PC` `PS4` `Xbox One`
|
||||
- **IW8** *(Call of Duty: Modern Warfare (2019) / Warzone)* `PC` `PS4` `PS5` `Xbox One` `Xbox Series X|S`
|
||||
- **IW9** *(Call of Duty: Modern Warfare II (2022) / Warzone 2)* `PC` `PS4` `PS5` `Xbox One` `Xbox Series X|S`
|
||||
- **S1** *(Call of Duty: Advanced Warfare)* `PC` `PS3` `PS4` `Xbox 360` `Xbox One`
|
||||
- **S2** *(Call of Duty: WWII)* `PC` `PS4` `Xbox One`
|
||||
- **S4** *(Call of Duty: Vanguard)* `PC` `PS4` `PS5` `Xbox One` `Xbox Series X|S`
|
||||
- **H1** *(Call of Duty: Modern Warfare Remastered)* `PC` `PS4` `Xbox One`
|
||||
- **H2** *(Call of Duty: Modern Warfare 2 Campaign Remastered)* `PC` `PS4` `PS5` `Xbox One` `Xbox Series X|S`
|
||||
- **T6** *(Call of Duty: Black Ops II)* `PC` `PS3` `Xbox 360` `Wii U`
|
||||
- **T7** *(Call of Duty: Black Ops III)* `PC` *(Decompiler)*
|
||||
- **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\****
|
||||
- **IW5** *(Call of Duty: Modern Warfare 3)*
|
||||
- **IW6** *(Call of Duty: Ghosts)*
|
||||
- **IW7** *(Call of Duty: Infinite Warfare)*
|
||||
- **IW8** *(Call of Duty: Modern Warfare (2019))*
|
||||
- **S1** *(Call of Duty: Advanced Warfare)*
|
||||
- **S2** *(Call of Duty: WWII)*
|
||||
- **S4** *(Call of Duty: Vanguard)*
|
||||
- **H1** *(Call of Duty: Modern Warfare Remastered)*
|
||||
- **H2** *(Call of Duty: Modern Warfare 2 Campaign Remastered)*
|
||||
- **T4** *(Call of Duty: World at War)* ***\*WIP\****
|
||||
- **T5** *(Call of Duty: Black Ops)* ***\*WIP\****
|
||||
- **T6** *(Call of Duty: Black Ops II)*
|
||||
- **T7** *(Call of Duty: Black Ops III)* ***\*WIP\****
|
||||
|
||||
## Usage
|
||||
``gsc-tool [OPTIONS..] <path>``
|
||||
``./gsc-tool.exe <mode> <game> <path>``
|
||||
|
||||
- **path**: file or directory to process
|
||||
**modes**: `asm`, `disasm`, `comp`, `decomp`
|
||||
|
||||
- **options:**
|
||||
**games**: `iw5`, `iw6`, `iw7`, `iw8`, `s1`, `s2`, `s4`, `h1`, `h2`, `t6`
|
||||
|
||||
``-m, --mode <mode>`` [REQUIRED] one of: `asm`, `disasm`, `comp`, `decomp`, `parse`
|
||||
**paths**: `file`, `directory` (recursive process all files inside dir)
|
||||
|
||||
``-g, --game <game>`` [REQUIRED] one of: `iw5`, `iw6`, `iw7`, `iw8`, `iw9`, `s1`, `s2`, `s4`, `h1`, `h2`, `t6` `t7` `t8` `t9` `jup`
|
||||
for zonetool files (*.cgsc*, *.cgsc.stack*) use: `zasm`, `zdisasm`, `zcomp`, `zdecomp` modes
|
||||
|
||||
``-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``
|
||||
Example: ``./gsc-tool.exe comp iw5 ./data/iw5/my_fancy_script.gsc``
|
||||
|
||||
| Mode |Description | Output |
|
||||
|:---------|:--------------------------|:------------|
|
||||
@ -54,41 +40,24 @@ Example: ``gsc-tool -m comp -g iw5 -s pc ./data/iw5/my_fancy_script.gsc``
|
||||
|`disasm` |dissasemble a `file.gscbin`|`file.gscasm`|
|
||||
|`comp` |compile a `file.gsc` |`file.gscbin`|
|
||||
|`decomp` |decompile a `file.gscbin` |`file.gsc` |
|
||||
|`parse` |parse a `file.gsc` |`file.gsc` |
|
||||
|
||||
## 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).
|
||||
|
||||
- gsc-tool `.gscbin` binary format is a serialized ScriptFile struct: <br/>
|
||||
- gsc-tool ``.gscbin`` 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/>
|
||||
|
||||
- ***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/>
|
||||
- zonetool (IW5) format made of bytecode file ``.cgsc`` and decompressed stack buffer ``.cgsc.stack``.
|
||||
|
||||
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)
|
||||
- treyarch (T6) format is a single buffer with gscobj data ``.gsc`` or ``.csc``.
|
||||
|
||||
## 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
|
||||
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
Normal file
20
appveyor.yml
Normal file
@ -0,0 +1,20 @@
|
||||
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
1
deps/cxxopts
vendored
@ -1 +0,0 @@
|
||||
Subproject commit eb787304d67ec22f7c3a184ee8b4c481d04357fd
|
11
deps/cxxopts.lua
vendored
11
deps/cxxopts.lua
vendored
@ -1,11 +0,0 @@
|
||||
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 09155eaa2f9270dc4ed1fa13e2b4b2613e6e4851
|
||||
Subproject commit 21767c654d31d2dccdde4330529775c6c5fd5389
|
22
deps/zlib.lua
vendored
22
deps/zlib.lua
vendored
@ -15,24 +15,20 @@ function zlib:project()
|
||||
language "C"
|
||||
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()
|
||||
|
||||
files {
|
||||
files
|
||||
{
|
||||
path.join(zlib.base, "*.h"),
|
||||
path.join(zlib.base, "*.c")
|
||||
}
|
||||
|
||||
defines
|
||||
{
|
||||
"_CRT_SECURE_NO_WARNINGS",
|
||||
"_CRT_NONSTDC_NO_DEPRECATE",
|
||||
"_CRT_SECURE_NO_DEPRECATE",
|
||||
}
|
||||
end
|
||||
|
||||
table.insert(dependencies, zlib)
|
||||
|
1
docs/syntax.md
Normal file
1
docs/syntax.md
Normal file
@ -0,0 +1 @@
|
||||
# GSC Syntax
|
@ -1,10 +0,0 @@
|
||||
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
1351
gen/arc/parser.ypp
File diff suppressed because it is too large
Load Diff
@ -1,10 +0,0 @@
|
||||
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
1249
gen/gsc/parser.ypp
File diff suppressed because it is too large
Load Diff
9
gen/h1/Makefile
Normal file
9
gen/h1/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
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/
|
875
gen/h1/parser.ypp
Normal file
875
gen/h1/parser.ypp
Normal file
@ -0,0 +1,875 @@
|
||||
/* 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);
|
||||
}
|
9
gen/h2/Makefile
Normal file
9
gen/h2/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
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/
|
875
gen/h2/parser.ypp
Normal file
875
gen/h2/parser.ypp
Normal file
@ -0,0 +1,875 @@
|
||||
/* 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 +0,0 @@
|
||||
clang++ -Wall -std=c++20 iw9_hash.cpp -o iw9_hash
|
75105
gen/hash/iw9_hash.cpp
75105
gen/hash/iw9_hash.cpp
File diff suppressed because it is too large
Load Diff
9
gen/iw5/Makefile
Normal file
9
gen/iw5/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
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/
|
865
gen/iw5/parser.ypp
Normal file
865
gen/iw5/parser.ypp
Normal file
@ -0,0 +1,865 @@
|
||||
/* 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);
|
||||
}
|
9
gen/iw6/Makefile
Normal file
9
gen/iw6/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
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/
|
865
gen/iw6/parser.ypp
Normal file
865
gen/iw6/parser.ypp
Normal file
@ -0,0 +1,865 @@
|
||||
/* 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);
|
||||
}
|
9
gen/iw7/Makefile
Normal file
9
gen/iw7/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
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/
|
865
gen/iw7/parser.ypp
Normal file
865
gen/iw7/parser.ypp
Normal file
@ -0,0 +1,865 @@
|
||||
/* 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);
|
||||
}
|
9
gen/iw8/Makefile
Normal file
9
gen/iw8/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
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/
|
891
gen/iw8/parser.ypp
Normal file
891
gen/iw8/parser.ypp
Normal file
@ -0,0 +1,891 @@
|
||||
/* 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);
|
||||
}
|
9
gen/s1/Makefile
Normal file
9
gen/s1/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
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/
|
875
gen/s1/parser.ypp
Normal file
875
gen/s1/parser.ypp
Normal file
@ -0,0 +1,875 @@
|
||||
/* 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);
|
||||
}
|
9
gen/s2/Makefile
Normal file
9
gen/s2/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
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/
|
875
gen/s2/parser.ypp
Normal file
875
gen/s2/parser.ypp
Normal file
@ -0,0 +1,875 @@
|
||||
/* 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);
|
||||
}
|
9
gen/s4/Makefile
Normal file
9
gen/s4/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
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/
|
891
gen/s4/parser.ypp
Normal file
891
gen/s4/parser.ypp
Normal file
@ -0,0 +1,891 @@
|
||||
/* 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);
|
||||
}
|
9
gen/t6/Makefile
Normal file
9
gen/t6/Makefile
Normal file
@ -0,0 +1,9 @@
|
||||
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/
|
997
gen/t6/parser.ypp
Normal file
997
gen/t6/parser.ypp
Normal file
@ -0,0 +1,997 @@
|
||||
/* 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);
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
// 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
|
@ -1,215 +0,0 @@
|
||||
// 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
|
@ -1,127 +0,0 @@
|
||||
// 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
|
File diff suppressed because it is too large
Load Diff
@ -1,20 +0,0 @@
|
||||
// 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
|
@ -1,21 +0,0 @@
|
||||
// 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
|
@ -1,20 +0,0 @@
|
||||
// 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
|
@ -1,47 +0,0 @@
|
||||
// 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,23 +0,0 @@
|
||||
// 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
|
@ -1,33 +0,0 @@
|
||||
// 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
|
@ -1,19 +0,0 @@
|
||||
// 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
|
@ -1,43 +0,0 @@
|
||||
// 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
|
@ -1,127 +0,0 @@
|
||||
// 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
|
@ -1,155 +0,0 @@
|
||||
// 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
|
@ -1,75 +0,0 @@
|
||||
// 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
|
@ -1,106 +0,0 @@
|
||||
// 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
|
@ -1,44 +0,0 @@
|
||||
// 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
|
@ -1,24 +0,0 @@
|
||||
// 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
|
@ -1,17 +0,0 @@
|
||||
// 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
|
@ -1,21 +0,0 @@
|
||||
// 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
|
@ -1,21 +0,0 @@
|
||||
// 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
|
@ -1,21 +0,0 @@
|
||||
// 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
|
@ -1,21 +0,0 @@
|
||||
// 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
|
@ -1,24 +0,0 @@
|
||||
// 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
|
@ -1,24 +0,0 @@
|
||||
// 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
|
@ -1,24 +0,0 @@
|
||||
// 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
|
@ -1,33 +0,0 @@
|
||||
// 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
|
@ -1,92 +0,0 @@
|
||||
// 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
|
@ -1,145 +0,0 @@
|
||||
// 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
|
@ -1,45 +0,0 @@
|
||||
// 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
|
@ -1,274 +0,0 @@
|
||||
// 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
|
@ -1,26 +0,0 @@
|
||||
// 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
|
File diff suppressed because it is too large
Load Diff
@ -1,20 +0,0 @@
|
||||
// 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
|
@ -1,21 +0,0 @@
|
||||
// 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
|
@ -1,20 +0,0 @@
|
||||
// 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
|
@ -1,47 +0,0 @@
|
||||
// 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,23 +0,0 @@
|
||||
// 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
|
@ -1,64 +0,0 @@
|
||||
// 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
|
@ -1,19 +0,0 @@
|
||||
// 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
|
@ -1,41 +0,0 @@
|
||||
// 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
|
@ -1,118 +0,0 @@
|
||||
// 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
|
@ -1,155 +0,0 @@
|
||||
// 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
|
@ -1,149 +0,0 @@
|
||||
// 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
|
@ -1,100 +0,0 @@
|
||||
// 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
|
@ -1,45 +0,0 @@
|
||||
// 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
|
@ -1,26 +0,0 @@
|
||||
// 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
|
@ -1,26 +0,0 @@
|
||||
// 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
|
@ -1,26 +0,0 @@
|
||||
// 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
|
@ -1,26 +0,0 @@
|
||||
// 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
|
@ -1,26 +0,0 @@
|
||||
// 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
|
@ -1,26 +0,0 @@
|
||||
// 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
|
@ -1,26 +0,0 @@
|
||||
// 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
|
@ -1,26 +0,0 @@
|
||||
// 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
|
@ -1,26 +0,0 @@
|
||||
// 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
|
@ -1,26 +0,0 @@
|
||||
// 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
|
@ -1,26 +0,0 @@
|
||||
// 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
|
@ -1,26 +0,0 @@
|
||||
// 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
|
@ -1,26 +0,0 @@
|
||||
// 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_ps
|
||||
{
|
||||
|
||||
constexpr usize code_count = 154;
|
||||
constexpr usize func_count = 3;
|
||||
constexpr usize meth_count = 0;
|
||||
constexpr usize token_count = 0;
|
||||
constexpr u32 max_string_id = 0xA51D; // TODO
|
||||
|
||||
class context : public gsc::context
|
||||
{
|
||||
public:
|
||||
context();
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc::s1_ps
|
@ -1,26 +0,0 @@
|
||||
// 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_xb
|
||||
{
|
||||
|
||||
constexpr usize code_count = 154;
|
||||
constexpr usize func_count = 3;
|
||||
constexpr usize meth_count = 0;
|
||||
constexpr usize token_count = 0;
|
||||
constexpr u32 max_string_id = 0xA51D;
|
||||
|
||||
class context : public gsc::context
|
||||
{
|
||||
public:
|
||||
context();
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc::s1_xb
|
@ -1,26 +0,0 @@
|
||||
// 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::s2
|
||||
{
|
||||
|
||||
constexpr usize code_count = 155;
|
||||
constexpr usize func_count = 1000;
|
||||
constexpr usize meth_count = 1700;
|
||||
constexpr usize token_count = 5;
|
||||
constexpr u32 max_string_id = 0xACEE;
|
||||
|
||||
class context : public gsc::context
|
||||
{
|
||||
public:
|
||||
context();
|
||||
};
|
||||
|
||||
} // namespace xsk::gsc::s2
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user