Initial commit

This commit is contained in:
Dan Sinclair 2020-03-02 15:47:43 -05:00
commit 6e581895a5
285 changed files with 28191 additions and 0 deletions

2
.clang-format Normal file
View File

@ -0,0 +1,2 @@
# http://clang.llvm.org/docs/ClangFormatStyleOptions.html
BasedOnStyle: Chromium

8
.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
.vscode
.DS_Store
build
out
third_party/cpplint
third_party/googletest
third_party/spirv-headers
third_party/spirv-tools

140
CMakeLists.txt Normal file
View File

@ -0,0 +1,140 @@
# Copyright 2020 The Tint Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
cmake_minimum_required(VERSION 3.10.2)
project(tint)
enable_testing()
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_DEBUG_POSTFIX "")
if ("${CMAKE_BUILD_TYPE}" STREQUAL "")
message(STATUS "No build type selected, default to Debug")
set(CMAKE_BUILD_TYPE "Debug")
endif()
option(TINT_BUILD_DOCS "Build documentation" ON)
option(TINT_BUILD_SPV_PARSER "Build the SPIR-V input parser" OFF)
option(TINT_BUILD_FUZZERS "Build fuzzers" OFF)
option(TINT_ENABLE_MSAN "Enable memory sanitizer" OFF)
option(TINT_ENABLE_ASAN "Enable address sanitizer" OFF)
option(TINT_ENABLE_UBSAN "Enable undefined behaviour sanitizer" OFF)
message(STATUS "Tint build docs: ${TINT_BUILD_DOCS}")
message(STATUS "Tint build SPIR-V parser: ${TINT_BUILD_SPV_PARSER}")
message(STATUS "Tint build fuzzers: ${TINT_BUILD_FUZZERS}")
message(STATUS "Tint build with ASAN: ${TINT_ENABLE_ASAN}")
message(STATUS "Tint build with MSAN: ${TINT_ENABLE_MSAN}")
message(STATUS "Tint build with UBSAN: ${TINT_ENABLE_UBSAN}")
message(STATUS "Using python3")
find_package(PythonInterp 3 REQUIRED)
if (${TINT_BUILD_SPV_PARSER})
include_directories("${PROJECT_SOURCE_DIR}/third_party/spirv-tools/include")
endif()
if(("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") OR
("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") OR
(("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") AND
(NOT CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")))
set(COMPILER_IS_LIKE_GNU TRUE)
endif()
find_package(Doxygen)
if(DOXYGEN_FOUND)
add_custom_target(tint_docs ALL
COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Generating API documentation"
VERBATIM)
else()
message("Doxygen not found. Skipping documentation")
endif()
function(tint_default_compile_options TARGET)
include_directories("${PROJECT_SOURCE_DIR}")
if (${COMPILER_IS_LIKE_GNU})
target_compile_options(${TARGET} PRIVATE
-std=c++14
-fno-exceptions
-fno-rtti
-fvisibility=hidden
-Wall
-Werror
-Wextra
-Wno-documentation-unknown-command
-Wno-padded
-Wno-switch-enum
-Wno-unknown-pragmas
-pedantic-errors
)
if (("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") OR
("${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang"))
target_compile_options(${TARGET} PRIVATE
-Wno-c++98-compat
-Wno-c++98-compat-pedantic
-Wno-format-pedantic
-Wno-return-std-move-in-c++11
-Wno-unknown-warning-option
-Weverything
)
endif()
if (${TINT_ENABLE_MSAN})
target_compile_options(${TARGET} PRIVATE -fsanitize=memory)
target_link_options(${TARGET} PRIVATE -fsanitize=memory)
elseif (${TINT_ENABLE_ASAN})
target_compile_options(${TARGET} PRIVATE -fsanitize=address)
target_link_options(${TARGET} PRIVATE -fsanitize=address)
elseif (${TINT_ENABLE_UBSAN})
target_compile_options(${TARGET} PRIVATE -fsanitize=undefined)
target_link_options(${TARGET} PRIVATE -fsanitize=undefined)
endif()
endif()
if (MSVC)
# Specify /EHs for exception handling.
target_compile_options(${TARGET} PRIVATE
/bigobj
/EHsc
/W3
/WX
/wd4068
/wd4514
/wd4571
/wd4625
/wd4626
/wd4710
/wd4774
/wd4820
/wd5026
/wd5027
)
endif()
endfunction()
add_subdirectory(third_party)
add_subdirectory(src)
add_subdirectory(samples)
if (${TINT_BUILD_FUZZERS})
add_subdirectory(fuzz)
endif()

93
CODE_OF_CONDUCT.md Normal file
View File

@ -0,0 +1,93 @@
# Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of
experience, education, socio-economic status, nationality, personal appearance,
race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, or to ban temporarily or permanently any
contributor for other behaviors that they deem inappropriate, threatening,
offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
This Code of Conduct also applies outside the project spaces when the Project
Steward has a reasonable belief that an individual's behavior may have a
negative impact on the project or its community.
## Conflict Resolution
We do not believe that all conflict is bad; healthy debate and disagreement
often yield positive results. However, it is never okay to be disrespectful or
to engage in behavior that violates the projects code of conduct.
If you see someone violating the code of conduct, you are encouraged to address
the behavior directly with those involved. Many issues can be resolved quickly
and easily, and this gives people more control over the outcome of their
dispute. If you are unable to resolve the matter for any reason, or if the
behavior is threatening or harassing, report it. We are dedicated to providing
an environment where participants feel welcome and safe.
Reports should be directed to David Neto <dneto@google.com>, the
Project Steward(s) for Tint. It is the Project Stewards duty to
receive and address reported violations of the code of conduct. They will then
work with a committee consisting of representatives from the Open Source
Programs Office and the Google Open Source Strategy team. If for any reason you
are uncomfortable reaching out the Project Steward, please email
opensource@google.com.
We will investigate every complaint, but you may not receive a direct response.
We will use our discretion in determining when and how to follow up on reported
incidents, which may range from not taking action to permanent expulsion from
the project and project-sponsored spaces. We will notify the accused of the
report and provide them an opportunity to discuss it before any action is taken.
The identity of the reporter will be omitted from the details of the report
supplied to the accused. In potentially harmful situations, such as ongoing
harassment or threats to anyone's safety, we may take action without notice.
## Attribution
This Code of Conduct is adapted from the Contributor Covenant, version 1.4,
available at
https://www.contributor-covenant.org/version/1/4/code-of-conduct.html

28
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,28 @@
# How to Contribute
We'd love to accept your patches and contributions to this project. There are
just a few small guidelines you need to follow.
## Contributor License Agreement
Contributions to this project must be accompanied by a Contributor License
Agreement. You (or your employer) retain the copyright to your contribution;
this simply gives us permission to use and redistribute your contributions as
part of the project. Head over to <https://cla.developers.google.com/> to see
your current agreements on file or to sign a new one.
You generally only need to submit a CLA once, so if you've already submitted one
(even if it was for a different project), you probably don't need to do it
again.
## Code reviews
All submissions, including submissions by project members, require review. We
use GitHub pull requests for this purpose. Consult
[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
information on using pull requests.
## Community Guidelines
This project follows
[Google's Open Source Community Guidelines](https://opensource.google.com/conduct/).

2
CPPLINT.cfg Normal file
View File

@ -0,0 +1,2 @@
set noparent
headers=h,hpp

25
DEPS Normal file
View File

@ -0,0 +1,25 @@
use_relative_paths = True
vars = {
'google_git': 'https://github.com/google',
'khronos_git': 'https://github.com/KhronosGroup',
'cpplint_revision': '26470f9ccb354ff2f6d098f831271a1833701b28',
'googletest_revision': '41b5f149ab306e96b5b2faf523505d75acffd98a',
'spirv_headers_revision': '5dbc1c32182e17b8ab8e8158a802ecabaf35aad3',
'spirv_tools_revision': 'fe10239f92f4539e9050da375dab095328fec196',
}
deps = {
'third_party/cpplint': Var('google_git') + '/styleguide.git@' +
Var('cpplint_revision'),
'third_party/googletest': Var('google_git') + '/googletest.git@' +
Var('googletest_revision'),
'third_party/spirv-headers': Var('khronos_git') + '/SPIRV-Headers.git@' +
Var('spirv_headers_revision'),
'third_party/spirv-tools': Var('khronos_git') + '/SPIRV-Tools.git@' +
Var('spirv_tools_revision'),
}

2485
Doxyfile Normal file

File diff suppressed because it is too large Load Diff

202
LICENSE Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

28
README.md Normal file
View File

@ -0,0 +1,28 @@
# Tint
Tint is a compiler for the WebGPU Shader Language (WGSL).
This is not an officially supported Google product.
## Requirements
* Git
* CMake (3.10.2 or later)
* Ninja (or other build tool)
* Python, for fetching dependencies
## Build options
* `TINT_BUILD_SPV_PARSER` : enable the SPIR-V input parser
## Building
```
./tools/git-sync-deps
mkdir -p out/Debug
cd out/Debug
cmake -GNinja ../..
ninja
```
## Contributing
Please see the CONTRIBUTING and CODE_OF_CONDUCT files on how to contribute to
Tint.

29
fuzz/CMakeLists.txt Normal file
View File

@ -0,0 +1,29 @@
# Copyright 2020 The Tint Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
add_executable(tint_fuzz tint_fuzz.cc)
target_link_libraries(tint_fuzz libtint)
tint_default_compile_options(tint_fuzz)
target_link_options(tint_fuzz PRIVATE
-fno-omit-frame-pointer
-fsanitize=fuzzer,address,undefined
-fsanitize-address-use-after-scope
-O1
-g
)
target_compile_options(tint_fuzz PRIVATE
-fsanitize=fuzzer,address,undefined
-Wno-missing-prototypes
)

27
fuzz/tint_fuzz.cc Normal file
View File

@ -0,0 +1,27 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <string>
#include "src/reader/wgsl/parser.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
std::string str(reinterpret_cast<const char*>(data), size);
tint::reader::wgsl::Parser parser(str);
parser.Parse();
return 0;
}

23
samples/CMakeLists.txt Normal file
View File

@ -0,0 +1,23 @@
# Copyright 2020 The Tint Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set(TINT_SRCS
main.cc
)
## Tint executable
add_executable(tint ${TINT_SRCS})
target_link_libraries(tint libtint SPIRV-Tools)
tint_default_compile_options(tint)

278
samples/main.cc Normal file
View File

@ -0,0 +1,278 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <fstream>
#include <iostream>
#include <memory>
#include <vector>
#include "spirv-tools/libspirv.hpp"
#include "src/reader/reader.h"
#include "src/reader/wgsl/parser.h"
#include "src/type_determiner.h"
#include "src/validator.h"
#include "src/writer/spv/generator.h"
#include "src/writer/wgsl/generator.h"
#include "src/writer/writer.h"
namespace {
enum class Format {
kNone = -1,
kSpirv,
kSpvAsm,
kWgsl,
};
struct Options {
bool show_help = false;
std::string input_filename;
std::string output_name = "";
std::string output_ext = "spv";
bool parse_only = false;
bool dump_ast = false;
Format format = Format::kSpirv;
};
const char kUsage[] = R"(Usage: tint [options] SCRIPT [SCRIPTS...]
options:
--format <spirv|spvasm|wgsl> -- Output format
--output-name <name> -- Name for the output file, without extension
--parse-only -- Stop after parsing the input
--dump-ast -- Dump the generated AST to stdout
-h -- This help text)";
Format parse_format(const std::string& fmt) {
if (fmt == "spirv")
return Format::kSpirv;
if (fmt == "spvasm")
return Format::kSpvAsm;
if (fmt == "wgsl")
return Format::kWgsl;
return Format::kNone;
}
bool ParseArgs(const std::vector<std::string>& args, Options* opts) {
for (size_t i = 1; i < args.size(); ++i) {
const std::string& arg = args[i];
if (arg == "--format") {
++i;
if (i >= args.size()) {
std::cerr << "Missing value for --format argument." << std::endl;
return false;
}
opts->format = parse_format(args[i]);
if (opts->format == Format::kNone) {
std::cerr << "Unknown output format: " << args[i] << std::endl;
return false;
}
if (opts->format == Format::kSpvAsm)
opts->output_ext = "spvasm";
else if (opts->format == Format::kWgsl)
opts->output_ext = "wgsl";
}
if (arg == "--output-name") {
++i;
if (i >= args.size()) {
std::cerr << "Missing value for --output_name argument." << std::endl;
return false;
}
opts->output_name = args[i];
} else if (arg == "-h" || arg == "--help") {
opts->show_help = true;
} else if (arg == "--parse-only") {
opts->parse_only = true;
} else if (arg == "--dump-ast") {
opts->dump_ast = true;
} else if (!arg.empty()) {
opts->input_filename = arg;
}
}
return true;
}
std::vector<uint8_t> ReadFile(const std::string& input_file) {
FILE* file = nullptr;
#if defined(_MSC_VER)
fopen_s(&file, input_file.c_str(), "rb");
#else
file = fopen(input_file.c_str(), "rb");
#endif
if (!file) {
std::cerr << "Failed to open " << input_file << std::endl;
return {};
}
fseek(file, 0, SEEK_END);
uint64_t tell_file_size = static_cast<uint64_t>(ftell(file));
if (tell_file_size <= 0) {
std::cerr << "Input file of incorrect size: " << input_file << std::endl;
fclose(file);
return {};
}
fseek(file, 0, SEEK_SET);
size_t file_size = static_cast<size_t>(tell_file_size);
std::vector<uint8_t> data;
data.resize(file_size);
size_t bytes_read = fread(data.data(), sizeof(uint8_t), file_size, file);
fclose(file);
if (bytes_read != file_size) {
std::cerr << "Failed to read " << input_file << std::endl;
return {};
}
return data;
}
std::string Disassemble(const std::vector<uint32_t>& data) {
std::string spv_errors;
spv_target_env target_env = SPV_ENV_UNIVERSAL_1_0;
auto msg_consumer = [&spv_errors](spv_message_level_t level, const char*,
const spv_position_t& position,
const char* message) {
switch (level) {
case SPV_MSG_FATAL:
case SPV_MSG_INTERNAL_ERROR:
case SPV_MSG_ERROR:
spv_errors += "error: line " + std::to_string(position.index) + ": " +
message + "\n";
break;
case SPV_MSG_WARNING:
spv_errors += "warning: line " + std::to_string(position.index) + ": " +
message + "\n";
break;
case SPV_MSG_INFO:
spv_errors += "info: line " + std::to_string(position.index) + ": " +
message + "\n";
break;
case SPV_MSG_DEBUG:
break;
}
};
spvtools::SpirvTools tools(target_env);
tools.SetMessageConsumer(msg_consumer);
std::string result;
tools.Disassemble(data, &result,
SPV_BINARY_TO_TEXT_OPTION_INDENT |
SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES);
return result;
}
} // namespace
int main(int argc, const char** argv) {
std::vector<std::string> args(argv, argv + argc);
Options options;
if (!ParseArgs(args, &options)) {
std::cerr << "Failed to parse arguments." << std::endl;
return 1;
}
if (options.show_help) {
std::cout << kUsage << std::endl;
return 0;
}
if (options.input_filename == "") {
std::cerr << "Input file missing" << std::endl;
std::cout << kUsage << std::endl;
return 1;
}
auto data = ReadFile(options.input_filename);
if (data.size() == 0)
return 1;
std::unique_ptr<tint::reader::Reader> reader;
std::string ext = "wgsl";
if (options.input_filename.size() > 4 &&
options.input_filename.substr(options.input_filename.size() - 4) ==
"wgsl") {
reader = std::make_unique<tint::reader::wgsl::Parser>(
std::string(data.begin(), data.end()));
}
if (!reader) {
std::cerr << "Failed to create reader for input file: "
<< options.input_filename << std::endl;
return 1;
}
if (!reader->Parse()) {
std::cerr << reader->error() << std::endl;
return 1;
}
auto module = reader->module();
if (options.dump_ast) {
std::cout << std::endl << module.to_str() << std::endl;
}
if (options.parse_only) {
return 1;
}
tint::TypeDeterminer td;
if (!td.Determine(&module)) {
std::cerr << td.error() << std::endl;
return 1;
}
tint::Validator v;
if (!v.Validate(module)) {
std::cerr << v.error() << std::endl;
return 1;
}
std::unique_ptr<tint::writer::Writer> writer;
if (options.format == Format::kSpirv || options.format == Format::kSpvAsm) {
writer = std::make_unique<tint::writer::spv::Generator>(std::move(module));
} else if (options.format == Format::kWgsl) {
writer = std::make_unique<tint::writer::wgsl::Generator>(std::move(module));
} else {
std::cerr << "Unknown output format specified" << std::endl;
return 1;
}
if (!writer->Generate()) {
std::cerr << "Failed to generate SPIR-V: " << writer->error() << std::endl;
return 1;
}
if (options.format == Format::kSpvAsm) {
auto w = static_cast<tint::writer::spv::Generator*>(writer.get());
auto str = Disassemble(w->result());
// TODO(dsinclair): Write to file if output_file given
std::cout << str << std::endl;
} else if (options.format == Format::kSpirv) {
// auto w = static_cast<tint::writer::spv::Generator*>(writer.get());
// TODO(dsincliair): Write to to file
} else if (options.format == Format::kWgsl) {
auto w = static_cast<tint::writer::wgsl::Generator*>(writer.get());
std::cout << w->result() << std::endl;
}
return 0;
}

310
src/CMakeLists.txt Normal file
View File

@ -0,0 +1,310 @@
# Copyright 2020 The Tint Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set(TINT_LIB_SRCS
ast/array_accessor_expression.cc
ast/array_accessor_expression.h
ast/as_expression.cc
ast/as_expression.h
ast/assignment_statement.cc
ast/assignment_statement.h
ast/binding_decoration.cc
ast/binding_decoration.h
ast/bool_literal.h
ast/bool_literal.cc
ast/break_statement.cc
ast/break_statement.h
ast/builtin.cc
ast/builtin.h
ast/builtin_decoration.cc
ast/builtin_decoration.h
ast/call_expression.cc
ast/call_expression.h
ast/case_statement.cc
ast/case_statement.h
ast/cast_expression.cc
ast/cast_expression.h
ast/const_initializer_expression.cc
ast/const_initializer_expression.h
ast/continue_statement.cc
ast/continue_statement.h
ast/decorated_variable.cc
ast/decorated_variable.h
ast/derivative_modifier.cc
ast/derivative_modifier.h
ast/else_statement.cc
ast/else_statement.h
ast/entry_point.cc
ast/entry_point.h
ast/expression.cc
ast/expression.h
ast/fallthrough_statement.cc
ast/fallthrough_statement.h
ast/float_literal.cc
ast/float_literal.h
ast/function.cc
ast/function.h
ast/identifier_expression.cc
ast/identifier_expression.h
ast/if_statement.cc
ast/if_statement.h
ast/import.cc
ast/import.h
ast/initializer_expression.cc
ast/initializer_expression.h
ast/int_literal.cc
ast/int_literal.h
ast/kill_statement.cc
ast/kill_statement.h
ast/literal.h
ast/literal.cc
ast/location_decoration.cc
ast/location_decoration.h
ast/loop_statement.cc
ast/loop_statement.h
ast/member_accessor_expression.cc
ast/member_accessor_expression.h
ast/module.cc
ast/module.h
ast/node.cc
ast/node.h
ast/nop_statement.cc
ast/nop_statement.h
ast/pipeline_stage.cc
ast/pipeline_stage.h
ast/regardless_statement.cc
ast/regardless_statement.h
ast/relational_expression.cc
ast/relational_expression.h
ast/return_statement.cc
ast/return_statement.h
ast/set_decoration.cc
ast/set_decoration.h
ast/statement.cc
ast/statement.h
ast/statement_condition.cc
ast/statement_condition.h
ast/storage_class.cc
ast/storage_class.h
ast/struct_decoration.cc
ast/struct_decoration.h
ast/struct.cc
ast/struct.h
ast/struct_member.cc
ast/struct_member.h
ast/struct_member_decoration.cc
ast/struct_member_decoration.h
ast/struct_member_offset_decoration.cc
ast/struct_member_offset_decoration.h
ast/switch_statement.cc
ast/switch_statement.h
ast/type_initializer_expression.h
ast/type_initializer_expression.cc
ast/type/alias_type.cc
ast/type/alias_type.h
ast/type/array_type.cc
ast/type/array_type.h
ast/type/bool_type.cc
ast/type/bool_type.h
ast/type/f32_type.cc
ast/type/f32_type.h
ast/type/i32_type.cc
ast/type/i32_type.h
ast/type/matrix_type.cc
ast/type/matrix_type.h
ast/type/pointer_type.cc
ast/type/pointer_type.h
ast/type/struct_type.cc
ast/type/struct_type.h
ast/type/type.cc
ast/type/type.h
ast/type/u32_type.cc
ast/type/u32_type.h
ast/type/vector_type.cc
ast/type/vector_type.h
ast/type/void_type.cc
ast/type/void_type.h
ast/uint_literal.cc
ast/uint_literal.h
ast/unary_derivative.cc
ast/unary_derivative.h
ast/unary_derivative_expression.cc
ast/unary_derivative_expression.h
ast/unary_method.cc
ast/unary_method.h
ast/unary_method_expression.cc
ast/unary_method_expression.h
ast/unary_op.cc
ast/unary_op.h
ast/unary_op_expression.cc
ast/unary_op_expression.h
ast/unless_statement.cc
ast/unless_statement.h
ast/variable.cc
ast/variable.h
ast/variable_decoration.cc
ast/variable_decoration.h
ast/variable_statement.cc
ast/variable_statement.h
reader/reader.cc
reader/reader.h
reader/wgsl/lexer.cc
reader/wgsl/lexer.h
reader/wgsl/parser.cc
reader/wgsl/parser.h
reader/wgsl/parser_impl.cc
reader/wgsl/parser_impl.h
reader/wgsl/token.cc
reader/wgsl/token.h
source.h
type_determiner.cc
type_determiner.h
type_manager.cc
type_manager.h
validator.cc
validator.h
# TODO(dsinclair): The writers should all be optional
writer/spv/generator.cc
writer/spv/generator.h
writer/wgsl/generator.cc
writer/wgsl/generator.h
writer/writer.cc
writer/writer.h
)
if(TINT_BUILD_SPV_PARSER)
list(APPEND TINT_LIB_SRCS
reader/spv/parser.cc
reader/spv/parser.h
)
endif()
set(TINT_TEST_SRCS
ast/binding_decoration_test.cc
ast/bool_literal_test.cc
ast/builtin_decoration_test.cc
ast/entry_point_test.cc
ast/import_test.cc
ast/int_literal_test.cc
ast/location_decoration_test.cc
ast/module_test.cc
ast/set_decoration_test.cc
ast/struct_member_test.cc
ast/struct_member_offset_decoration_test.cc
ast/struct_test.cc
ast/type/alias_type_test.cc
ast/type/array_type_test.cc
ast/type/bool_type_test.cc
ast/type/f32_type_test.cc
ast/type/i32_type_test.cc
ast/type/matrix_type_test.cc
ast/type/pointer_type_test.cc
ast/type/struct_type_test.cc
ast/type/u32_type_test.cc
ast/type/vector_type_test.cc
ast/uint_literal_test.cc
ast/variable_test.cc
reader/wgsl/lexer_test.cc
reader/wgsl/parser_test.cc
reader/wgsl/parser_impl_additive_expression_test.cc
reader/wgsl/parser_impl_and_expression_test.cc
reader/wgsl/parser_impl_argument_expression_list_test.cc
reader/wgsl/parser_impl_assignment_stmt_test.cc
reader/wgsl/parser_impl_body_stmt_test.cc
reader/wgsl/parser_impl_break_stmt_test.cc
reader/wgsl/parser_impl_builtin_decoration_test.cc
reader/wgsl/parser_impl_case_body_test.cc
reader/wgsl/parser_impl_const_expr_test.cc
reader/wgsl/parser_impl_const_literal_test.cc
reader/wgsl/parser_impl_continue_stmt_test.cc
reader/wgsl/parser_impl_continuing_stmt_test.cc
reader/wgsl/parser_impl_derivative_modifier_test.cc
reader/wgsl/parser_impl_else_stmt_test.cc
reader/wgsl/parser_impl_elseif_stmt_test.cc
reader/wgsl/parser_impl_entry_point_decl_test.cc
reader/wgsl/parser_impl_equality_expression_test.cc
reader/wgsl/parser_impl_exclusive_or_expression_test.cc
reader/wgsl/parser_impl_function_decl_test.cc
reader/wgsl/parser_impl_function_header_test.cc
reader/wgsl/parser_impl_function_type_decl_test.cc
reader/wgsl/parser_impl_global_constant_decl_test.cc
reader/wgsl/parser_impl_global_decl_test.cc
reader/wgsl/parser_impl_global_variable_decl_test.cc
reader/wgsl/parser_impl_if_stmt_test.cc
reader/wgsl/parser_impl_import_decl_test.cc
reader/wgsl/parser_impl_inclusive_or_expression_test.cc
reader/wgsl/parser_impl_logical_and_expression_test.cc
reader/wgsl/parser_impl_logical_or_expression_test.cc
reader/wgsl/parser_impl_loop_stmt_test.cc
reader/wgsl/parser_impl_multiplicative_expression_test.cc
reader/wgsl/parser_impl_param_list_test.cc
reader/wgsl/parser_impl_paren_rhs_stmt_test.cc
reader/wgsl/parser_impl_pipeline_stage_test.cc
reader/wgsl/parser_impl_postfix_expression_test.cc
reader/wgsl/parser_impl_premerge_stmt_test.cc
reader/wgsl/parser_impl_primary_expression_test.cc
reader/wgsl/parser_impl_regardless_stmt_test.cc
reader/wgsl/parser_impl_relational_expression_test.cc
reader/wgsl/parser_impl_shift_expression_test.cc
reader/wgsl/parser_impl_statement_test.cc
reader/wgsl/parser_impl_statements_test.cc
reader/wgsl/parser_impl_storage_class_test.cc
reader/wgsl/parser_impl_struct_body_decl_test.cc
reader/wgsl/parser_impl_struct_decl_test.cc
reader/wgsl/parser_impl_struct_decoration_decl_test.cc
reader/wgsl/parser_impl_struct_decoration_test.cc
reader/wgsl/parser_impl_struct_member_decoration_decl_test.cc
reader/wgsl/parser_impl_struct_member_decoration_test.cc
reader/wgsl/parser_impl_struct_member_test.cc
reader/wgsl/parser_impl_switch_body_test.cc
reader/wgsl/parser_impl_switch_stmt_test.cc
reader/wgsl/parser_impl_test.cc
reader/wgsl/parser_impl_type_alias_test.cc
reader/wgsl/parser_impl_type_decl_test.cc
reader/wgsl/parser_impl_unary_expression_test.cc
reader/wgsl/parser_impl_unless_stmt_test.cc
reader/wgsl/parser_impl_variable_decl_test.cc
reader/wgsl/parser_impl_variable_decoration_list_test.cc
reader/wgsl/parser_impl_variable_decoration_test.cc
reader/wgsl/parser_impl_variable_ident_decl_test.cc
reader/wgsl/parser_impl_variable_stmt_test.cc
reader/wgsl/parser_impl_variable_storage_decoration_test.cc
reader/wgsl/token_test.cc
type_manager_test.cc
)
## Tint library
add_library(libtint ${TINT_LIB_SRCS})
tint_default_compile_options(libtint)
set_target_properties(libtint PROPERTIES OUTPUT_NAME "tint")
if(${TINT_ENABLE_SPV_PARSER})
target_link_libraries(libtint SPIRV-Tools)
endif()
add_executable(tint_unittests ${TINT_TEST_SRCS})
if (NOT MSVC)
target_compile_options(tint_unittests PRIVATE
-Wno-global-constructors
-Wno-weak-vtables
)
endif()
## Test executable
target_include_directories(
tint_unittests PRIVATE ${gmock_SOURCE_DIR}/include)
target_link_libraries(tint_unittests libtint gmock_main)
tint_default_compile_options(tint_unittests)
add_test(NAME tint_unittests COMMAND tint_unittests)

View File

@ -0,0 +1,49 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/array_accessor_expression.h"
namespace tint {
namespace ast {
ArrayAccessorExpression::ArrayAccessorExpression(
std::unique_ptr<Expression> array,
std::unique_ptr<Expression> idx_expr)
: Expression(), array_(std::move(array)), idx_expr_(std::move(idx_expr)) {}
ArrayAccessorExpression::ArrayAccessorExpression(
const Source& source,
std::unique_ptr<Expression> array,
std::unique_ptr<Expression> idx_expr)
: Expression(source),
array_(std::move(array)),
idx_expr_(std::move(idx_expr)) {}
ArrayAccessorExpression::~ArrayAccessorExpression() = default;
bool ArrayAccessorExpression::IsValid() const {
return array_ != nullptr && idx_expr_ != nullptr;
}
void ArrayAccessorExpression::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent);
out << "ArrayAccessor{" << std::endl;
array_->to_str(out, indent + 2);
idx_expr_->to_str(out, indent + 2);
make_indent(out, indent);
out << "}" << std::endl;
}
} // namespace ast
} // namespace tint

View File

@ -0,0 +1,83 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_ARRAY_ACCESSOR_EXPRESSION_H_
#define SRC_AST_ARRAY_ACCESSOR_EXPRESSION_H_
#include <memory>
#include <utility>
#include "src/ast/expression.h"
#include "src/ast/literal.h"
namespace tint {
namespace ast {
/// An array accessor expression
class ArrayAccessorExpression : public Expression {
public:
/// Constructor
/// @param array the array
/// @param idx_expr the index expression
ArrayAccessorExpression(std::unique_ptr<Expression> array,
std::unique_ptr<Expression> idx_expr);
/// Constructor
/// @param source the initializer source
/// @param array the array
/// @param idx_expr the index expression
ArrayAccessorExpression(const Source& source,
std::unique_ptr<Expression> array,
std::unique_ptr<Expression> idx_expr);
/// Move constructor
ArrayAccessorExpression(ArrayAccessorExpression&&) = default;
~ArrayAccessorExpression() override;
/// Sets the array
/// @param array the array
void set_array(std::unique_ptr<Expression> array) {
array_ = std::move(array);
}
/// @returns the array
Expression* array() const { return array_.get(); }
/// Sets the index expression
/// @param idx_expr the index expression
void set_idx_expr(std::unique_ptr<Expression> idx_expr) {
idx_expr_ = std::move(idx_expr);
}
/// @returns the index expression
Expression* idx_expr() const { return idx_expr_.get(); }
/// @returns true if this is an array accessor expression
bool IsArrayAccessor() const override { return true; }
/// @returns true if the node is valid
bool IsValid() const override;
/// Writes a representation of the node to the output stream
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void to_str(std::ostream& out, size_t indent) const override;
private:
ArrayAccessorExpression(const ArrayAccessorExpression&) = delete;
std::unique_ptr<Expression> array_;
std::unique_ptr<Expression> idx_expr_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_ARRAY_ACCESSOR_EXPRESSION_H_

41
src/ast/as_expression.cc Normal file
View File

@ -0,0 +1,41 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/as_expression.h"
namespace tint {
namespace ast {
AsExpression::AsExpression(type::Type* type, std::unique_ptr<Expression> expr)
: Expression(), type_(type), expr_(std::move(expr)) {}
AsExpression::AsExpression(const Source& source,
type::Type* type,
std::unique_ptr<Expression> expr)
: Expression(source), type_(type), expr_(std::move(expr)) {}
AsExpression::~AsExpression() = default;
bool AsExpression::IsValid() const {
return type_ != nullptr && expr_ != nullptr;
}
void AsExpression::to_str(std::ostream& out, size_t indent) const {
out << "as<" << type_->type_name() << ">(";
expr_->to_str(out, indent);
out << ")";
}
} // namespace ast
} // namespace tint

80
src/ast/as_expression.h Normal file
View File

@ -0,0 +1,80 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_AS_EXPRESSION_H_
#define SRC_AST_AS_EXPRESSION_H_
#include <memory>
#include <utility>
#include <vector>
#include "src/ast/expression.h"
#include "src/ast/literal.h"
#include "src/ast/type/type.h"
namespace tint {
namespace ast {
/// An as expression
class AsExpression : public Expression {
public:
/// Constructor
/// @param type the type
/// @param expr the expr
AsExpression(type::Type* type, std::unique_ptr<Expression> expr);
/// Constructor
/// @param source the initializer source
/// @param type the type
/// @param expr the expr
AsExpression(const Source& source,
type::Type* type,
std::unique_ptr<Expression> expr);
/// Move constructor
AsExpression(AsExpression&&) = default;
~AsExpression() override;
/// Sets the type
/// @param type the type
void set_type(type::Type* type) { type_ = std::move(type); }
/// @returns the left side expression
type::Type* type() const { return type_; }
/// Sets the expr
/// @param expr the expression
void set_expr(std::unique_ptr<Expression> expr) { expr_ = std::move(expr); }
/// @returns the expression
Expression* expr() const { return expr_.get(); }
/// @returns true if this is an as expression
bool IsAs() const override { return true; }
/// @returns true if the node is valid
bool IsValid() const override;
/// Writes a representation of the node to the output stream
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void to_str(std::ostream& out, size_t indent) const override;
private:
AsExpression(const AsExpression&) = delete;
type::Type* type_;
std::unique_ptr<Expression> expr_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_AS_EXPRESSION_H_

View File

@ -0,0 +1,47 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/assignment_statement.h"
namespace tint {
namespace ast {
AssignmentStatement::AssignmentStatement(std::unique_ptr<Expression> lhs,
std::unique_ptr<Expression> rhs)
: Statement(), lhs_(std::move(lhs)), rhs_(std::move(rhs)) {}
AssignmentStatement::AssignmentStatement(const Source& source,
std::unique_ptr<Expression> lhs,
std::unique_ptr<Expression> rhs)
: Statement(source), lhs_(std::move(lhs)), rhs_(std::move(rhs)) {}
AssignmentStatement::~AssignmentStatement() = default;
bool AssignmentStatement::IsValid() const {
return lhs_ != nullptr && rhs_ != nullptr;
}
void AssignmentStatement::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent);
out << "Assignment{" << std::endl;
lhs_->to_str(out, indent + 2);
out << std::endl;
rhs_->to_str(out, indent + 2);
out << std::endl;
make_indent(out, indent);
out << "}" << std::endl;
}
} // namespace ast
} // namespace tint

View File

@ -0,0 +1,80 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_ASSIGNMENT_STATEMENT_H_
#define SRC_AST_ASSIGNMENT_STATEMENT_H_
#include <memory>
#include <utility>
#include "src/ast/expression.h"
#include "src/ast/literal.h"
#include "src/ast/statement.h"
namespace tint {
namespace ast {
/// An assignment statement
class AssignmentStatement : public Statement {
public:
/// Constructor
/// @param lhs the left side of the expression
/// @param rhs the right side of the expression
AssignmentStatement(std::unique_ptr<Expression> lhs,
std::unique_ptr<Expression> rhs);
/// Constructor
/// @param source the initializer source
/// @param lhs the left side of the expression
/// @param rhs the right side of the expression
AssignmentStatement(const Source& source,
std::unique_ptr<Expression> lhs,
std::unique_ptr<Expression> rhs);
/// Move constructor
AssignmentStatement(AssignmentStatement&&) = default;
~AssignmentStatement() override;
/// Sets the left side of the statement
/// @param lhs the left side to set
void set_lhs(std::unique_ptr<Expression> lhs) { lhs_ = std::move(lhs); }
/// @returns the left side expression
Expression* lhs() const { return lhs_.get(); }
/// Sets the right side of the statement
/// @param rhs the right side to set
void set_rhs(std::unique_ptr<Expression> rhs) { rhs_ = std::move(rhs); }
/// @returns the right side expression
Expression* rhs() const { return rhs_.get(); }
/// @returns true if this is an assignment statement
bool IsAssign() const override { return true; }
/// @returns true if the node is valid
bool IsValid() const override;
/// Writes a representation of the node to the output stream
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void to_str(std::ostream& out, size_t indent) const override;
private:
AssignmentStatement(const AssignmentStatement&) = delete;
std::unique_ptr<Expression> lhs_;
std::unique_ptr<Expression> rhs_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_ASSIGNMENT_STATEMENT_H_

View File

@ -0,0 +1,29 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/binding_decoration.h"
namespace tint {
namespace ast {
BindingDecoration::BindingDecoration(size_t val) : value_(val) {}
BindingDecoration::~BindingDecoration() = default;
void BindingDecoration::to_str(std::ostream& out) const {
out << "binding " << value_;
}
} // namespace ast
} // namespace tint

View File

@ -0,0 +1,50 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_BINDING_DECORATION_H_
#define SRC_AST_BINDING_DECORATION_H_
#include <stddef.h>
#include "src/ast/variable_decoration.h"
namespace tint {
namespace ast {
/// A binding decoration
class BindingDecoration : public VariableDecoration {
public:
/// constructor
/// @param value the binding value
explicit BindingDecoration(size_t value);
~BindingDecoration() override;
/// @returns true if this is a binding decoration
bool IsBinding() const override { return true; }
/// @returns the binding value
size_t value() const { return value_; }
/// Outputs the decoration to the given stream
/// @param out the stream to output too
void to_str(std::ostream& out) const override;
private:
size_t value_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_BINDING_DECORATION_H_

View File

@ -0,0 +1,38 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/binding_decoration.h"
#include "gtest/gtest.h"
namespace tint {
namespace ast {
using BindingDecorationTest = testing::Test;
TEST_F(BindingDecorationTest, Creation) {
BindingDecoration d{2};
EXPECT_EQ(2, d.value());
}
TEST_F(BindingDecorationTest, Is) {
BindingDecoration d{2};
EXPECT_TRUE(d.IsBinding());
EXPECT_FALSE(d.IsBuiltin());
EXPECT_FALSE(d.IsLocation());
EXPECT_FALSE(d.IsSet());
}
} // namespace ast
} // namespace tint

29
src/ast/bool_literal.cc Normal file
View File

@ -0,0 +1,29 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/bool_literal.h"
namespace tint {
namespace ast {
BoolLiteral::BoolLiteral(bool value) : value_(value) {}
BoolLiteral::~BoolLiteral() = default;
std::string BoolLiteral::to_str() const {
return value_ ? "true" : "false";
}
} // namespace ast
} // namespace tint

51
src/ast/bool_literal.h Normal file
View File

@ -0,0 +1,51 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_BOOL_LITERAL_H_
#define SRC_AST_BOOL_LITERAL_H_
#include <string>
#include "src/ast/literal.h"
namespace tint {
namespace ast {
/// A boolean literal
class BoolLiteral : public Literal {
public:
/// Constructor
/// @param value the bool literals value
explicit BoolLiteral(bool value);
~BoolLiteral() override;
/// @returns true if this is a bool literal
bool IsBool() const override { return true; }
/// @returns true if the bool literal is true
bool IsTrue() const { return value_; }
/// @returns true if the bool literal is false
bool IsFalse() const { return !value_; }
/// @returns the literal as a string
std::string to_str() const override;
private:
bool value_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_BOOL_LITERAL_H_

View File

@ -0,0 +1,55 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/bool_literal.h"
#include "gtest/gtest.h"
namespace tint {
namespace ast {
using BoolLiteralTest = testing::Test;
TEST_F(BoolLiteralTest, True) {
BoolLiteral b{true};
ASSERT_TRUE(b.IsBool());
ASSERT_TRUE(b.IsTrue());
ASSERT_FALSE(b.IsFalse());
}
TEST_F(BoolLiteralTest, False) {
BoolLiteral b{false};
ASSERT_TRUE(b.IsBool());
ASSERT_FALSE(b.IsTrue());
ASSERT_TRUE(b.IsFalse());
}
TEST_F(BoolLiteralTest, Is) {
BoolLiteral b{false};
EXPECT_TRUE(b.IsBool());
EXPECT_FALSE(b.IsInt());
EXPECT_FALSE(b.IsFloat());
EXPECT_FALSE(b.IsUint());
}
TEST_F(BoolLiteralTest, ToStr) {
BoolLiteral t{true};
BoolLiteral f{false};
EXPECT_EQ(t.to_str(), "true");
EXPECT_EQ(f.to_str(), "false");
}
} // namespace ast
} // namespace tint

View File

@ -0,0 +1,58 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/break_statement.h"
namespace tint {
namespace ast {
BreakStatement::BreakStatement(StatementCondition condition,
std::unique_ptr<Expression> conditional)
: Statement(),
condition_(condition),
conditional_(std::move(conditional)) {}
BreakStatement::BreakStatement(const Source& source,
StatementCondition condition,
std::unique_ptr<Expression> conditional)
: Statement(source),
condition_(condition),
conditional_(std::move(conditional)) {}
BreakStatement::~BreakStatement() = default;
bool BreakStatement::IsValid() const {
return condition_ == StatementCondition::kNone || conditional_ != nullptr;
}
void BreakStatement::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent);
out << "Break";
if (condition_ != StatementCondition::kNone) {
out << "{" << std::endl;
make_indent(out, indent + 2);
out << condition_ << std::endl;
conditional_->to_str(out, indent + 2);
make_indent(out, indent);
out << "}";
}
out << std::endl;
}
} // namespace ast
} // namespace tint

84
src/ast/break_statement.h Normal file
View File

@ -0,0 +1,84 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_BREAK_STATEMENT_H_
#define SRC_AST_BREAK_STATEMENT_H_
#include <memory>
#include <utility>
#include "src/ast/expression.h"
#include "src/ast/statement.h"
#include "src/ast/statement_condition.h"
namespace tint {
namespace ast {
/// An break statement
class BreakStatement : public Statement {
public:
/// Constructor
BreakStatement();
/// Constructor
/// @param condition the condition type
/// @param conditional the condition expression
BreakStatement(StatementCondition condition,
std::unique_ptr<Expression> conditional);
/// Constructor
/// @param source the initializer source
/// @param condition the condition type
/// @param conditional the condition expression
BreakStatement(const Source& source,
StatementCondition condition,
std::unique_ptr<Expression> conditional);
/// Move constructor
BreakStatement(BreakStatement&&) = default;
~BreakStatement() override;
/// Sets the condition type
/// @param condition the condition type
void set_condition(StatementCondition condition) { condition_ = condition; }
/// @returns the condition type
StatementCondition condition() const { return condition_; }
/// Sets the conditional expression
/// @param conditional the conditional expression
void set_conditional(std::unique_ptr<Expression> conditional) {
conditional_ = std::move(conditional);
}
/// @returns the conditional expression
Expression* conditional() const { return conditional_.get(); }
/// @returns true if this is an break statement
bool IsBreak() const override { return true; }
/// @returns true if the node is valid
bool IsValid() const override;
/// Writes a representation of the node to the output stream
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void to_str(std::ostream& out, size_t indent) const override;
private:
BreakStatement(const BreakStatement&) = delete;
StatementCondition condition_ = StatementCondition::kNone;
std::unique_ptr<Expression> conditional_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_BREAK_STATEMENT_H_

75
src/ast/builtin.cc Normal file
View File

@ -0,0 +1,75 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/builtin.h"
namespace tint {
namespace ast {
std::ostream& operator<<(std::ostream& out, Builtin builtin) {
switch (builtin) {
case Builtin::kNone: {
out << "none";
break;
}
case Builtin::kPosition: {
out << "position";
break;
}
case Builtin::kVertexIdx: {
out << "vertex_idx";
break;
}
case Builtin::kInstanceIdx: {
out << "instance_idx";
break;
}
case Builtin::kFrontFacing: {
out << "front_facing";
break;
}
case Builtin::kFragCoord: {
out << "frag_coord";
break;
}
case Builtin::kFragDepth: {
out << "frag_depth";
break;
}
case Builtin::kNumWorkgroups: {
out << "num_workgroups";
break;
}
case Builtin::kWorkgroupSize: {
out << "workgroup_size";
break;
}
case Builtin::kLocalInvocationId: {
out << "local_invocation_id";
break;
}
case Builtin::kLocalInvocationIdx: {
out << "local_invocation_idx";
break;
}
case Builtin::kGlobalInvocationId: {
out << "global_invocation_id";
break;
}
}
return out;
}
} // namespace ast
} // namespace tint

44
src/ast/builtin.h Normal file
View File

@ -0,0 +1,44 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_BUILTIN_H_
#define SRC_AST_BUILTIN_H_
#include <ostream>
namespace tint {
namespace ast {
/// The builtin identifiers
enum class Builtin {
kNone = -1,
kPosition,
kVertexIdx,
kInstanceIdx,
kFrontFacing,
kFragCoord,
kFragDepth,
kNumWorkgroups,
kWorkgroupSize,
kLocalInvocationId,
kLocalInvocationIdx,
kGlobalInvocationId
};
std::ostream& operator<<(std::ostream& out, Builtin builtin);
} // namespace ast
} // namespace tint
#endif // SRC_AST_BUILTIN_H_

View File

@ -0,0 +1,29 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/builtin_decoration.h"
namespace tint {
namespace ast {
BuiltinDecoration::BuiltinDecoration(Builtin builtin) : builtin_(builtin) {}
BuiltinDecoration::~BuiltinDecoration() = default;
void BuiltinDecoration::to_str(std::ostream& out) const {
out << "builtin " << builtin_;
}
} // namespace ast
} // namespace tint

View File

@ -0,0 +1,49 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_BUILTIN_DECORATION_H_
#define SRC_AST_BUILTIN_DECORATION_H_
#include "src/ast/builtin.h"
#include "src/ast/variable_decoration.h"
namespace tint {
namespace ast {
/// A builtin decoration
class BuiltinDecoration : public VariableDecoration {
public:
/// constructor
/// @param builtin the builtin value
explicit BuiltinDecoration(Builtin builtin);
~BuiltinDecoration() override;
/// @returns true if this is a builtin decoration
bool IsBuiltin() const override { return true; }
/// @returns the builtin value
Builtin value() const { return builtin_; }
/// Outputs the decoration to the given stream
/// @param out the stream to output too
void to_str(std::ostream& out) const override;
private:
Builtin builtin_ = Builtin::kNone;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_BUILTIN_DECORATION_H_

View File

@ -0,0 +1,38 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/builtin_decoration.h"
#include "gtest/gtest.h"
namespace tint {
namespace ast {
using BuiltinDecorationTest = testing::Test;
TEST_F(BuiltinDecorationTest, Creation) {
BuiltinDecoration d{Builtin::kFragDepth};
EXPECT_EQ(Builtin::kFragDepth, d.value());
}
TEST_F(BuiltinDecorationTest, Is) {
BuiltinDecoration d{Builtin::kFragDepth};
EXPECT_FALSE(d.IsBinding());
EXPECT_TRUE(d.IsBuiltin());
EXPECT_FALSE(d.IsLocation());
EXPECT_FALSE(d.IsSet());
}
} // namespace ast
} // namespace tint

View File

@ -0,0 +1,47 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/call_expression.h"
namespace tint {
namespace ast {
CallExpression::CallExpression(std::unique_ptr<Expression> func,
std::vector<std::unique_ptr<Expression>> params)
: Expression(), func_(std::move(func)), params_(std::move(params)) {}
CallExpression::CallExpression(const Source& source,
std::unique_ptr<Expression> func,
std::vector<std::unique_ptr<Expression>> params)
: Expression(source), func_(std::move(func)), params_(std::move(params)) {}
CallExpression::~CallExpression() = default;
bool CallExpression::IsValid() const {
return func_ != nullptr;
}
void CallExpression::to_str(std::ostream& out, size_t indent) const {
func_->to_str(out, indent);
make_indent(out, indent + 2);
out << "(" << std::endl;
for (const auto& param : params_)
param->to_str(out, indent + 4);
make_indent(out, indent + 2);
out << ")" << std::endl;
}
} // namespace ast
} // namespace tint

84
src/ast/call_expression.h Normal file
View File

@ -0,0 +1,84 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_CALL_EXPRESSION_H_
#define SRC_AST_CALL_EXPRESSION_H_
#include <memory>
#include <utility>
#include <vector>
#include "src/ast/expression.h"
#include "src/ast/literal.h"
namespace tint {
namespace ast {
/// A call expression
class CallExpression : public Expression {
public:
/// Constructor
/// @param func the function
/// @param params the parameters
CallExpression(std::unique_ptr<Expression> func,
std::vector<std::unique_ptr<Expression>> params);
/// Constructor
/// @param source the initializer source
/// @param func the function
/// @param params the parameters
CallExpression(const Source& source,
std::unique_ptr<Expression> func,
std::vector<std::unique_ptr<Expression>> params);
/// Move constructor
CallExpression(CallExpression&&) = default;
~CallExpression() override;
/// Sets the func
/// @param func the func
void set_func(std::unique_ptr<Expression> func) { func_ = std::move(func); }
/// @returns the func
Expression* func() const { return func_.get(); }
/// Sets the parameters
/// @param params the parameters
void set_params(std::vector<std::unique_ptr<Expression>> params) {
params_ = std::move(params);
}
/// @returns the parameters
const std::vector<std::unique_ptr<Expression>>& params() const {
return params_;
}
/// @returns true if this is a call expression
bool IsCall() const override { return true; }
/// @returns true if the node is valid
bool IsValid() const override;
/// Writes a representation of the node to the output stream
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void to_str(std::ostream& out, size_t indent) const override;
private:
CallExpression(const CallExpression&) = delete;
std::unique_ptr<Expression> func_;
std::vector<std::unique_ptr<Expression>> params_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_CALL_EXPRESSION_H_

56
src/ast/case_statement.cc Normal file
View File

@ -0,0 +1,56 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/case_statement.h"
namespace tint {
namespace ast {
CaseStatement::CaseStatement() : Statement() {}
CaseStatement::CaseStatement(std::unique_ptr<Literal> condition,
std::vector<std::unique_ptr<Statement>> body)
: Statement(), condition_(std::move(condition)), body_(std::move(body)) {}
CaseStatement::CaseStatement(const Source& source,
std::unique_ptr<Literal> condition,
std::vector<std::unique_ptr<Statement>> body)
: Statement(source),
condition_(std::move(condition)),
body_(std::move(body)) {}
CaseStatement::~CaseStatement() = default;
bool CaseStatement::IsValid() const {
return true;
}
void CaseStatement::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent);
if (IsDefault()) {
out << "default{" << std::endl;
} else {
out << "Case " << condition_->to_str() << "{" << std::endl;
}
for (const auto& stmt : body_)
stmt->to_str(out, indent + 2);
make_indent(out, indent);
out << "}" << std::endl;
}
} // namespace ast
} // namespace tint

90
src/ast/case_statement.h Normal file
View File

@ -0,0 +1,90 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_CASE_STATEMENT_H_
#define SRC_AST_CASE_STATEMENT_H_
#include <memory>
#include <utility>
#include <vector>
#include "src/ast/expression.h"
#include "src/ast/literal.h"
#include "src/ast/statement.h"
#include "src/ast/statement_condition.h"
namespace tint {
namespace ast {
/// A case statement
class CaseStatement : public Statement {
public:
/// Constructor
CaseStatement();
/// Constructor
/// @param condition the case condition
/// @param body the case body
CaseStatement(std::unique_ptr<Literal> condition,
std::vector<std::unique_ptr<Statement>> body);
/// Constructor
/// @param source the source information
/// @param condition the case condition
/// @param body the case body
CaseStatement(const Source& source,
std::unique_ptr<Literal> condition,
std::vector<std::unique_ptr<Statement>> body);
/// Move constructor
CaseStatement(CaseStatement&&) = default;
~CaseStatement() override;
/// Sets the condition for the case statement
/// @param condition the condition to set
void set_condition(std::unique_ptr<Literal> condition) {
condition_ = std::move(condition);
}
/// @returns the case condition or nullptr if none set
Literal* condition() const { return condition_.get(); }
/// @returns true if this is a default statement
bool IsDefault() const { return condition_ == nullptr; }
/// Sets the case body
/// @param body the case body
void set_body(std::vector<std::unique_ptr<Statement>> body) {
body_ = std::move(body);
}
/// @returns the case body
const std::vector<std::unique_ptr<Statement>>& body() const { return body_; }
/// @returns true if this is a case statement
bool IsCase() const override { return true; }
/// @returns true if the node is valid
bool IsValid() const override;
/// Writes a representation of the node to the output stream
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void to_str(std::ostream& out, size_t indent) const override;
private:
CaseStatement(const CaseStatement&) = delete;
std::unique_ptr<Literal> condition_;
std::vector<std::unique_ptr<Statement>> body_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_CASE_STATEMENT_H_

View File

@ -0,0 +1,42 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/cast_expression.h"
namespace tint {
namespace ast {
CastExpression::CastExpression(type::Type* type,
std::unique_ptr<Expression> expr)
: Expression(), type_(type), expr_(std::move(expr)) {}
CastExpression::CastExpression(const Source& source,
type::Type* type,
std::unique_ptr<Expression> expr)
: Expression(source), type_(type), expr_(std::move(expr)) {}
CastExpression::~CastExpression() = default;
bool CastExpression::IsValid() const {
return type_ != nullptr && expr_ != nullptr;
}
void CastExpression::to_str(std::ostream& out, size_t indent) const {
out << "cast<" << type_->type_name() << ">(";
expr_->to_str(out, indent);
out << ")";
}
} // namespace ast
} // namespace tint

80
src/ast/cast_expression.h Normal file
View File

@ -0,0 +1,80 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_CAST_EXPRESSION_H_
#define SRC_AST_CAST_EXPRESSION_H_
#include <memory>
#include <utility>
#include <vector>
#include "src/ast/expression.h"
#include "src/ast/literal.h"
#include "src/ast/type/type.h"
namespace tint {
namespace ast {
/// A cast expression
class CastExpression : public Expression {
public:
/// Constructor
/// @param type the type
/// @param expr the expr
CastExpression(type::Type* type, std::unique_ptr<Expression> expr);
/// Constructor
/// @param source the initializer source
/// @param type the type
/// @param expr the expr
CastExpression(const Source& source,
type::Type* type,
std::unique_ptr<Expression> expr);
/// Move constructor
CastExpression(CastExpression&&) = default;
~CastExpression() override;
/// Sets the type
/// @param type the type
void set_type(type::Type* type) { type_ = std::move(type); }
/// @returns the left side expression
type::Type* type() const { return type_; }
/// Sets the expr
/// @param expr the expression
void set_expr(std::unique_ptr<Expression> expr) { expr_ = std::move(expr); }
/// @returns the expression
Expression* expr() const { return expr_.get(); }
/// @returns true if this is a cast expression
bool IsCast() const override { return true; }
/// @returns true if the node is valid
bool IsValid() const override;
/// Writes a representation of the node to the output stream
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void to_str(std::ostream& out, size_t indent) const override;
private:
CastExpression(const CastExpression&) = delete;
type::Type* type_;
std::unique_ptr<Expression> expr_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_CAST_EXPRESSION_H_

View File

@ -0,0 +1,42 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/const_initializer_expression.h"
namespace tint {
namespace ast {
ConstInitializerExpression::ConstInitializerExpression(
std::unique_ptr<Literal> literal)
: InitializerExpression(), literal_(std::move(literal)) {}
ConstInitializerExpression::ConstInitializerExpression(
const Source& source,
std::unique_ptr<Literal> litearl)
: InitializerExpression(source), literal_(std::move(litearl)) {}
ConstInitializerExpression::~ConstInitializerExpression() = default;
bool ConstInitializerExpression::IsValid() const {
return literal_ != nullptr;
}
void ConstInitializerExpression::to_str(std::ostream& out,
size_t indent) const {
make_indent(out, indent);
out << "ConstInitializer{" << literal_->to_str() << "}" << std::endl;
}
} // namespace ast
} // namespace tint

View File

@ -0,0 +1,70 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_CONST_INITIALIZER_EXPRESSION_H_
#define SRC_AST_CONST_INITIALIZER_EXPRESSION_H_
#include <memory>
#include <utility>
#include "src/ast/initializer_expression.h"
#include "src/ast/literal.h"
namespace tint {
namespace ast {
/// A constant initializer
class ConstInitializerExpression : public InitializerExpression {
public:
/// Constructor
/// @param literal the const literal
explicit ConstInitializerExpression(std::unique_ptr<Literal> literal);
/// Constructor
/// @param source the initializer source
/// @param literal the const literal
ConstInitializerExpression(const Source& source,
std::unique_ptr<Literal> literal);
/// Move constructor
ConstInitializerExpression(ConstInitializerExpression&&) = default;
~ConstInitializerExpression() override;
/// @returns true if this is a constant initializer
bool IsConstInitializer() const override { return true; }
/// Set the literal value
/// @param literal the literal
void set_literal(std::unique_ptr<Literal> literal) {
literal_ = std::move(literal);
}
/// @returns the literal value
Literal* literal() const { return literal_.get(); }
/// @returns true if the node is valid
bool IsValid() const override;
/// Writes a representation of the node to the output stream
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void to_str(std::ostream& out, size_t indent) const override;
private:
ConstInitializerExpression(const ConstInitializerExpression&) = delete;
std::unique_ptr<Literal> literal_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_CONST_INITIALIZER_EXPRESSION_H_

View File

@ -0,0 +1,57 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/continue_statement.h"
namespace tint {
namespace ast {
ContinueStatement::ContinueStatement(StatementCondition condition,
std::unique_ptr<Expression> conditional)
: Statement(),
condition_(condition),
conditional_(std::move(conditional)) {}
ContinueStatement::ContinueStatement(const Source& source,
StatementCondition condition,
std::unique_ptr<Expression> conditional)
: Statement(source),
condition_(condition),
conditional_(std::move(conditional)) {}
ContinueStatement::~ContinueStatement() = default;
bool ContinueStatement::IsValid() const {
return condition_ == StatementCondition::kNone || conditional_ != nullptr;
}
void ContinueStatement::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent);
out << "Continue";
if (condition_ != StatementCondition::kNone) {
out << "{" << std::endl;
make_indent(out, indent + 2);
out << condition_ << std::endl;
conditional_->to_str(out, indent + 2);
make_indent(out, indent);
out << "}";
}
out << std::endl;
}
} // namespace ast
} // namespace tint

View File

@ -0,0 +1,84 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_CONTINUE_STATEMENT_H_
#define SRC_AST_CONTINUE_STATEMENT_H_
#include <memory>
#include <utility>
#include "src/ast/expression.h"
#include "src/ast/statement.h"
#include "src/ast/statement_condition.h"
namespace tint {
namespace ast {
/// An continue statement
class ContinueStatement : public Statement {
public:
/// Constructor
ContinueStatement();
/// Constructor
/// @param condition the condition type
/// @param conditional the condition expression
ContinueStatement(StatementCondition condition,
std::unique_ptr<Expression> conditional);
/// Constructor
/// @param source the initializer source
/// @param condition the condition type
/// @param conditional the condition expression
ContinueStatement(const Source& source,
StatementCondition condition,
std::unique_ptr<Expression> conditional);
/// Move constructor
ContinueStatement(ContinueStatement&&) = default;
~ContinueStatement() override;
/// Sets the condition type
/// @param condition the condition type
void set_condition(StatementCondition condition) { condition_ = condition; }
/// @returns the condition type
StatementCondition condition() const { return condition_; }
/// Sets the conditional expression
/// @param conditional the conditional expression
void set_conditional(std::unique_ptr<Expression> conditional) {
conditional_ = std::move(conditional);
}
/// @returns the conditional expression
Expression* conditional() const { return conditional_.get(); }
/// @returns true if this is an continue statement
bool IsContinue() const override { return true; }
/// @returns true if the node is valid
bool IsValid() const override;
/// Writes a representation of the node to the output stream
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void to_str(std::ostream& out, size_t indent) const override;
private:
ContinueStatement(const ContinueStatement&) = delete;
StatementCondition condition_ = StatementCondition::kNone;
std::unique_ptr<Expression> conditional_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_CONTINUE_STATEMENT_H_

View File

@ -0,0 +1,51 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/decorated_variable.h"
namespace tint {
namespace ast {
DecoratedVariable::DecoratedVariable() = default;
DecoratedVariable::DecoratedVariable(DecoratedVariable&&) = default;
DecoratedVariable::~DecoratedVariable() = default;
bool DecoratedVariable::IsValid() const {
return Variable::IsValid();
}
void DecoratedVariable::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent);
out << "DecoratedVariable{" << std::endl;
make_indent(out, indent + 2);
out << "decorations{" << std::endl;
for (const auto& deco : decorations_) {
make_indent(out, indent + 4);
deco->to_str(out);
out << std::endl;
}
make_indent(out, indent + 2);
out << "}" << std::endl;
info_to_str(out, indent + 2);
make_indent(out, indent);
out << "}" << std::endl;
}
} // namespace ast
} // namespace tint

View File

@ -0,0 +1,67 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_DECORATED_VARIABLE_H_
#define SRC_AST_DECORATED_VARIABLE_H_
#include <memory>
#include <utility>
#include <vector>
#include "src/ast/variable.h"
#include "src/ast/variable_decoration.h"
namespace tint {
namespace ast {
/// A Decorated Variable statement.
class DecoratedVariable : public Variable {
public:
/// Create a new empty decorated variable statement
DecoratedVariable();
/// Move constructor
DecoratedVariable(DecoratedVariable&&);
~DecoratedVariable() override;
/// Sets a decoration to the variable
/// @param decos the decorations to set
void set_decorations(std::vector<std::unique_ptr<VariableDecoration>> decos) {
decorations_ = std::move(decos);
}
/// @returns the decorations attached to this variable
const std::vector<std::unique_ptr<VariableDecoration>>& decorations() const {
return decorations_;
}
/// @returns true if this is a decorated variable
bool IsDecorated() const override { return true; }
/// @returns true if the name and path are both present
bool IsValid() const override;
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void to_str(std::ostream& out, size_t indent) const override;
private:
DecoratedVariable(const DecoratedVariable&) = delete;
std::vector<std::unique_ptr<VariableDecoration>> decorations_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_DECORATED_VARIABLE_H_

View File

@ -0,0 +1,39 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/derivative_modifier.h"
namespace tint {
namespace ast {
std::ostream& operator<<(std::ostream& out, DerivativeModifier mod) {
switch (mod) {
case DerivativeModifier::kNone: {
out << "none";
break;
}
case DerivativeModifier::kFine: {
out << "fine";
break;
}
case DerivativeModifier::kCoarse: {
out << "coarse";
break;
}
}
return out;
}
} // namespace ast
} // namespace tint

View File

@ -0,0 +1,31 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_DERIVATIVE_MODIFIER_H_
#define SRC_AST_DERIVATIVE_MODIFIER_H_
#include <ostream>
namespace tint {
namespace ast {
/// The derivative modifier
enum class DerivativeModifier { kNone = -1, kFine, kCoarse };
std::ostream& operator<<(std::ostream& out, DerivativeModifier mod);
} // namespace ast
} // namespace tint
#endif // SRC_AST_DERIVATIVE_MODIFIER_H_

63
src/ast/else_statement.cc Normal file
View File

@ -0,0 +1,63 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/else_statement.h"
namespace tint {
namespace ast {
ElseStatement::ElseStatement() : Statement() {}
ElseStatement::ElseStatement(std::vector<std::unique_ptr<Statement>> body)
: Statement(), body_(std::move(body)) {}
ElseStatement::ElseStatement(std::unique_ptr<Expression> condition,
std::vector<std::unique_ptr<Statement>> body)
: Statement(), condition_(std::move(condition)), body_(std::move(body)) {}
ElseStatement::ElseStatement(const Source& source,
std::vector<std::unique_ptr<Statement>> body)
: Statement(source), body_(std::move(body)) {}
ElseStatement::ElseStatement(const Source& source,
std::unique_ptr<Expression> condition,
std::vector<std::unique_ptr<Statement>> body)
: Statement(source),
condition_(std::move(condition)),
body_(std::move(body)) {}
ElseStatement::~ElseStatement() = default;
bool ElseStatement::IsValid() const {
return true;
}
void ElseStatement::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent);
out << "Else{" << std::endl;
if (condition_ != nullptr)
condition_->to_str(out, indent + 2);
make_indent(out, indent + 2);
out << "{" << std::endl;
for (const auto& stmt : body_)
stmt->to_str(out, indent + 4);
make_indent(out, indent + 2);
out << "}" << std::endl;
}
} // namespace ast
} // namespace tint

96
src/ast/else_statement.h Normal file
View File

@ -0,0 +1,96 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_ELSE_STATEMENT_H_
#define SRC_AST_ELSE_STATEMENT_H_
#include <memory>
#include <utility>
#include <vector>
#include "src/ast/expression.h"
#include "src/ast/statement.h"
namespace tint {
namespace ast {
/// An else statement
class ElseStatement : public Statement {
public:
/// Constructor
ElseStatement();
/// Constructor
/// @param body the else body
explicit ElseStatement(std::vector<std::unique_ptr<Statement>> body);
/// Constructor
/// @param condition the else condition
/// @param body the else body
ElseStatement(std::unique_ptr<Expression> condition,
std::vector<std::unique_ptr<Statement>> body);
/// Constructor
/// @param source the source information
/// @param body the else body
ElseStatement(const Source& source,
std::vector<std::unique_ptr<Statement>> body);
/// Constructor
/// @param source the source information
/// @param condition the else condition
/// @param body the else body
ElseStatement(const Source& source,
std::unique_ptr<Expression> condition,
std::vector<std::unique_ptr<Statement>> body);
/// Move constructor
ElseStatement(ElseStatement&&) = default;
~ElseStatement() override;
/// Sets the condition for the else statement
/// @param condition the condition to set
void set_condition(std::unique_ptr<Expression> condition) {
condition_ = std::move(condition);
}
/// @returns the else condition or nullptr if none set
Expression* condition() const { return condition_.get(); }
/// @returns true if the else has a condition
bool HasCondition() const { return condition_ != nullptr; }
/// Sets the else body
/// @param body the else body
void set_body(std::vector<std::unique_ptr<Statement>> body) {
body_ = std::move(body);
}
/// @returns the else body
const std::vector<std::unique_ptr<Statement>>& body() const { return body_; }
/// @returns true if this is a else statement
bool IsElse() const override { return true; }
/// @returns true if the node is valid
bool IsValid() const override;
/// Writes a representation of the node to the output stream
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void to_str(std::ostream& out, size_t indent) const override;
private:
ElseStatement(const ElseStatement&) = delete;
std::unique_ptr<Expression> condition_;
std::vector<std::unique_ptr<Statement>> body_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_ELSE_STATEMENT_H_

50
src/ast/entry_point.cc Normal file
View File

@ -0,0 +1,50 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/entry_point.h"
namespace tint {
namespace ast {
EntryPoint::EntryPoint(PipelineStage stage,
const std::string& name,
const std::string& fn_name)
: Node(), stage_(stage), name_(name), fn_name_(fn_name) {}
EntryPoint::EntryPoint(const Source& source,
PipelineStage stage,
const std::string& name,
const std::string& fn_name)
: Node(source), stage_(stage), name_(name), fn_name_(fn_name) {}
EntryPoint::~EntryPoint() = default;
bool EntryPoint::IsValid() const {
if (stage_ == PipelineStage::kNone) {
return false;
}
if (fn_name_.length() == 0) {
return false;
}
return true;
}
void EntryPoint::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent);
out << R"(EntryPoint{")" << stage_ << R"(" as ")" << name_ << R"(" = )"
<< fn_name_ << "}" << std::endl;
}
} // namespace ast
} // namespace tint

89
src/ast/entry_point.h Normal file
View File

@ -0,0 +1,89 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_ENTRY_POINT_H_
#define SRC_AST_ENTRY_POINT_H_
#include <ostream>
#include <string>
#include "src/ast/node.h"
#include "src/ast/pipeline_stage.h"
namespace tint {
namespace ast {
/// An entry point statement.
class EntryPoint : public Node {
public:
/// Constructor
EntryPoint() = default;
/// Constructor
/// @param stage the entry point stage
/// @param name the entry point name
/// @param fn_name the function name
EntryPoint(PipelineStage stage,
const std::string& name,
const std::string& fn_name);
/// Constructor
/// @param source the source of the entry point
/// @param stage the entry point stage
/// @param name the entry point name
/// @param fn_name the function name
EntryPoint(const Source& source,
PipelineStage stage,
const std::string& name,
const std::string& fn_name);
/// Move constructor
EntryPoint(EntryPoint&&) = default;
~EntryPoint() override;
/// Sets the entry point name
/// @param name the name to set
void set_name(const std::string& name) { name_ = name; }
/// @returns the entry points name
const std::string& name() const { return name_; }
/// Sets the entry point function name
/// @param name the function name
void set_function_name(const std::string& name) { fn_name_ = name; }
/// @returns the function name for the entry point
const std::string& function_name() const { return fn_name_; }
/// Sets the piepline stage
/// @param stage the stage to set
void set_pipeline_stage(PipelineStage stage) { stage_ = stage; }
/// @returns the pipeline stage for the entry point
PipelineStage stage() const { return stage_; }
/// @returns true if the entry point is valid
bool IsValid() const override;
/// Writes a representation of the entry point to the output stream
/// @param out the stream to write too
/// @param indent number of spaces to ident the node when writing
void to_str(std::ostream& out, size_t indent) const override;
private:
EntryPoint(const EntryPoint&) = delete;
Source source_;
PipelineStage stage_;
std::string name_;
std::string fn_name_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_ENTRY_POINT_H_

View File

@ -0,0 +1,91 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/entry_point.h"
#include <sstream>
#include "gtest/gtest.h"
namespace tint {
namespace ast {
using EntryPointTest = testing::Test;
TEST_F(EntryPointTest, Creation) {
EntryPoint e(PipelineStage::kVertex, "main", "vtx_main");
EXPECT_EQ(e.name(), "main");
EXPECT_EQ(e.function_name(), "vtx_main");
EXPECT_EQ(e.stage(), PipelineStage::kVertex);
EXPECT_EQ(e.line(), 0);
EXPECT_EQ(e.column(), 0);
}
TEST_F(EntryPointTest, CreationWithSource) {
Source s{27, 4};
EntryPoint e(s, PipelineStage::kVertex, "main", "vtx_main");
EXPECT_EQ(e.name(), "main");
EXPECT_EQ(e.function_name(), "vtx_main");
EXPECT_EQ(e.stage(), PipelineStage::kVertex);
EXPECT_EQ(e.line(), 27);
EXPECT_EQ(e.column(), 4);
}
TEST_F(EntryPointTest, CreationEmpty) {
Source s{27, 4};
EntryPoint e;
e.set_source(s);
e.set_pipeline_stage(PipelineStage::kFragment);
e.set_function_name("my_func");
e.set_name("a_name");
EXPECT_EQ(e.function_name(), "my_func");
EXPECT_EQ(e.name(), "a_name");
EXPECT_EQ(e.stage(), PipelineStage::kFragment);
EXPECT_EQ(e.line(), 27);
EXPECT_EQ(e.column(), 4);
}
TEST_F(EntryPointTest, to_str) {
EntryPoint e(PipelineStage::kVertex, "text", "vtx_main");
std::ostringstream out;
e.to_str(out, 0);
EXPECT_EQ(out.str(), R"(EntryPoint{"vertex" as "text" = vtx_main}
)");
}
TEST_F(EntryPointTest, IsValid) {
EntryPoint e(PipelineStage::kVertex, "main", "vtx_main");
EXPECT_TRUE(e.IsValid());
}
TEST_F(EntryPointTest, IsValid_MissingFunctionName) {
EntryPoint e(PipelineStage::kVertex, "main", "");
EXPECT_FALSE(e.IsValid());
}
TEST_F(EntryPointTest, IsValid_MissingStage) {
EntryPoint e(PipelineStage::kNone, "main", "fn");
EXPECT_FALSE(e.IsValid());
}
TEST_F(EntryPointTest, IsValid_MissingBoth) {
EntryPoint e;
EXPECT_FALSE(e.IsValid());
}
} // namespace ast
} // namespace tint

96
src/ast/expression.cc Normal file
View File

@ -0,0 +1,96 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/expression.h"
#include <assert.h>
#include "src/ast/array_accessor_expression.h"
#include "src/ast/as_expression.h"
#include "src/ast/call_expression.h"
#include "src/ast/cast_expression.h"
#include "src/ast/identifier_expression.h"
#include "src/ast/initializer_expression.h"
#include "src/ast/member_accessor_expression.h"
#include "src/ast/relational_expression.h"
#include "src/ast/unary_derivative_expression.h"
#include "src/ast/unary_method_expression.h"
#include "src/ast/unary_op_expression.h"
namespace tint {
namespace ast {
Expression::Expression() = default;
Expression::Expression(const Source& source) : Node(source) {}
Expression::~Expression() = default;
ArrayAccessorExpression* Expression::AsArrayAccessor() {
assert(IsArrayAccessor());
return static_cast<ArrayAccessorExpression*>(this);
}
AsExpression* Expression::AsAs() {
assert(IsAs());
return static_cast<AsExpression*>(this);
}
CallExpression* Expression::AsCall() {
assert(IsCall());
return static_cast<CallExpression*>(this);
}
CastExpression* Expression::AsCast() {
assert(IsCast());
return static_cast<CastExpression*>(this);
}
IdentifierExpression* Expression::AsIdentifier() {
assert(IsIdentifier());
return static_cast<IdentifierExpression*>(this);
}
InitializerExpression* Expression::AsInitializer() {
assert(IsInitializer());
return static_cast<InitializerExpression*>(this);
}
MemberAccessorExpression* Expression::AsMemberAccessor() {
assert(IsMemberAccessor());
return static_cast<MemberAccessorExpression*>(this);
}
RelationalExpression* Expression::AsRelational() {
assert(IsRelational());
return static_cast<RelationalExpression*>(this);
}
UnaryDerivativeExpression* Expression::AsUnaryDerivative() {
assert(IsUnaryDerivative());
return static_cast<UnaryDerivativeExpression*>(this);
}
UnaryMethodExpression* Expression::AsUnaryMethod() {
assert(IsUnaryMethod());
return static_cast<UnaryMethodExpression*>(this);
}
UnaryOpExpression* Expression::AsUnaryOp() {
assert(IsUnaryOp());
return static_cast<UnaryOpExpression*>(this);
}
} // namespace ast
} // namespace tint

102
src/ast/expression.h Normal file
View File

@ -0,0 +1,102 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_EXPRESSION_H_
#define SRC_AST_EXPRESSION_H_
#include "src/ast/node.h"
namespace tint {
namespace ast {
class ArrayAccessorExpression;
class AsExpression;
class CallExpression;
class CastExpression;
class IdentifierExpression;
class InitializerExpression;
class MemberAccessorExpression;
class RelationalExpression;
class UnaryDerivativeExpression;
class UnaryMethodExpression;
class UnaryOpExpression;
/// Base expression class
class Expression : public Node {
public:
~Expression() override;
/// @returns true if this is an array accessor expression
virtual bool IsArrayAccessor() const { return false; }
/// @returns true if this is an as expression
virtual bool IsAs() const { return false; }
/// @returns true if this is a call expression
virtual bool IsCall() const { return false; }
/// @returns true if this is a cast expression
virtual bool IsCast() const { return false; }
/// @returns true if this is an identifier expression
virtual bool IsIdentifier() const { return false; }
/// @returns true if this is an initializer expression
virtual bool IsInitializer() const { return false; }
/// @returns true if this is a member accessor expression
virtual bool IsMemberAccessor() const { return false; }
/// @returns true if this is a relational expression
virtual bool IsRelational() const { return false; }
/// @returns true if this is a unary derivative expression
virtual bool IsUnaryDerivative() const { return false; }
/// @returns true if this is a unary method expression
virtual bool IsUnaryMethod() const { return false; }
/// @returns true if this is a unary op expression
virtual bool IsUnaryOp() const { return false; }
/// @returns the expression as an array accessor
ArrayAccessorExpression* AsArrayAccessor();
/// @returns the expression as an as
AsExpression* AsAs();
/// @returns the expression as a call
CallExpression* AsCall();
/// @returns the expression as a cast
CastExpression* AsCast();
/// @returns the expression as an identifier
IdentifierExpression* AsIdentifier();
/// @returns the expression as an initializer
InitializerExpression* AsInitializer();
/// @returns the expression as a member accessor
MemberAccessorExpression* AsMemberAccessor();
/// @returns the expression as a relational expression
RelationalExpression* AsRelational();
/// @returns the expression as a unary derivative expression
UnaryDerivativeExpression* AsUnaryDerivative();
/// @returns the expression as a unary method expression
UnaryMethodExpression* AsUnaryMethod();
/// @returns the expression as a unary op expression
UnaryOpExpression* AsUnaryOp();
protected:
/// Constructor
Expression();
/// Constructor
/// @param source the source of the expression
explicit Expression(const Source& source);
/// Move constructor
Expression(Expression&&) = default;
private:
Expression(const Expression&) = delete;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_EXPRESSION_H_

View File

@ -0,0 +1,37 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/fallthrough_statement.h"
namespace tint {
namespace ast {
FallthroughStatement::FallthroughStatement() : Statement() {}
FallthroughStatement::FallthroughStatement(const Source& source)
: Statement(source) {}
FallthroughStatement::~FallthroughStatement() = default;
bool FallthroughStatement::IsValid() const {
return true;
}
void FallthroughStatement::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent);
out << "Fallthrough" << std::endl;
}
} // namespace ast
} // namespace tint

View File

@ -0,0 +1,58 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_FALLTHROUGH_STATEMENT_H_
#define SRC_AST_FALLTHROUGH_STATEMENT_H_
#include <memory>
#include <utility>
#include "src/ast/expression.h"
#include "src/ast/statement.h"
#include "src/ast/statement_condition.h"
namespace tint {
namespace ast {
/// An fallthrough statement
class FallthroughStatement : public Statement {
public:
/// Constructor
FallthroughStatement();
/// Constructor
/// @param source the source information
explicit FallthroughStatement(const Source& source);
/// Move constructor
FallthroughStatement(FallthroughStatement&&) = default;
~FallthroughStatement() override;
/// @returns true if this is an fallthrough statement
bool IsFallthrough() const override { return true; }
/// @returns true if the node is valid
bool IsValid() const override;
/// Writes a representation of the node to the output stream
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void to_str(std::ostream& out, size_t indent) const override;
private:
FallthroughStatement(const FallthroughStatement&) = delete;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_FALLTHROUGH_STATEMENT_H_

29
src/ast/float_literal.cc Normal file
View File

@ -0,0 +1,29 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/float_literal.h"
namespace tint {
namespace ast {
FloatLiteral::FloatLiteral(float value) : value_(value) {}
FloatLiteral::~FloatLiteral() = default;
std::string FloatLiteral::to_str() const {
return std::to_string(value_);
}
} // namespace ast
} // namespace tint

49
src/ast/float_literal.h Normal file
View File

@ -0,0 +1,49 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_FLOAT_LITERAL_H_
#define SRC_AST_FLOAT_LITERAL_H_
#include <string>
#include "src/ast/literal.h"
namespace tint {
namespace ast {
/// A float literal
class FloatLiteral : public Literal {
public:
/// Constructor
/// @param value the float literals value
explicit FloatLiteral(float value);
~FloatLiteral() override;
/// @returns true if this is a float literal
bool IsFloat() const override { return true; }
/// @returns the float literal value
float value() const { return value_; }
/// @returns the literal as a string
std::string to_str() const override;
private:
float value_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_FLOAT_LITERAL_H_

View File

@ -0,0 +1,45 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/float_literal.h"
#include "gtest/gtest.h"
namespace tint {
namespace ast {
using FloatLiteralTest = testing::Test;
TEST_F(FloatLiteralTest, Value) {
FloatLiteral f{47.2};
ASSERT_TRUE(f.IsFloat());
EXPECT_EQ(f.value(), 47.2);
}
TEST_F(FloatLiteralTest, Is) {
FloatLiteral f{42};
EXPECT_FALSE(f.IsBool());
EXPECT_FALSE(f.IsInt());
EXPECT_TRUE(f.IsFloat());
EXPECT_FALSE(f.IsUint());
}
TEST_F(FloatLiteralTest, ToStr) {
FloatLiteral f{42.1};
EXPECT_EQ(f.to_str(), "42.1");
}
} // namespace ast
} // namespace tint

71
src/ast/function.cc Normal file
View File

@ -0,0 +1,71 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/function.h"
namespace tint {
namespace ast {
Function::Function(const std::string& name,
std::vector<std::unique_ptr<Variable>> params,
type::Type* return_type)
: Node(),
name_(name),
params_(std::move(params)),
return_type_(return_type) {}
Function::Function(const Source& source,
const std::string& name,
std::vector<std::unique_ptr<Variable>> params,
type::Type* return_type)
: Node(source),
name_(name),
params_(std::move(params)),
return_type_(return_type) {}
Function::~Function() = default;
bool Function::IsValid() const {
if (name_.length() == 0) {
return false;
}
if (return_type_ == nullptr) {
return false;
}
return true;
}
void Function::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent);
out << "function -> " << return_type_->type_name() << "{" << std::endl;
make_indent(out, indent + 2);
out << name_ << std::endl;
for (const auto& param : params_)
param->to_str(out, indent + 2);
make_indent(out, indent + 2);
out << "{" << std::endl;
for (const auto& stmt : body_)
stmt->to_str(out, indent + 4);
make_indent(out, indent + 2);
out << "}" << std::endl;
make_indent(out, indent);
out << "}" << std::endl;
}
} // namespace ast
} // namespace tint

109
src/ast/function.h Normal file
View File

@ -0,0 +1,109 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_FUNCTION_H_
#define SRC_AST_FUNCTION_H_
#include <memory>
#include <ostream>
#include <string>
#include <utility>
#include <vector>
#include "src/ast/expression.h"
#include "src/ast/node.h"
#include "src/ast/statement.h"
#include "src/ast/type/type.h"
#include "src/ast/variable.h"
namespace tint {
namespace ast {
/// A Function statement.
class Function : public Node {
public:
/// Create a new empty function statement
Function() = default;
/// Create a function
/// @param name the function name
/// @param params the function parameters
/// @param return_type the return type
Function(const std::string& name,
std::vector<std::unique_ptr<Variable>> params,
type::Type* return_type);
/// Create a function
/// @param source the variable source
/// @param name the function name
/// @param params the function parameters
/// @param return_type the return type
Function(const Source& source,
const std::string& name,
std::vector<std::unique_ptr<Variable>> params,
type::Type* return_type);
/// Move constructor
Function(Function&&) = default;
~Function() override;
/// Sets the function name
/// @param name the name to set
void set_name(const std::string& name) { name_ = name; }
/// @returns the function name
const std::string& name() { return name_; }
/// Sets the function parameters
/// @param params the function parameters
void set_params(std::vector<std::unique_ptr<Variable>> params) {
params_ = std::move(params);
}
/// @returns the function params
const std::vector<std::unique_ptr<Variable>>& params() const {
return params_;
}
/// Sets the return type of the function
/// @param type the return type
void set_return_type(type::Type* type) { return_type_ = type; }
/// @returns the function return type.
type::Type* return_type() const { return return_type_; }
/// Sets the body of the function
/// @param body the function body
void set_body(std::vector<std::unique_ptr<Statement>> body) {
body_ = std::move(body);
}
/// @returns the function body
const std::vector<std::unique_ptr<Statement>>& body() const { return body_; }
/// @returns true if the name and path are both present
bool IsValid() const override;
/// Writes a representation of the node to the output stream
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void to_str(std::ostream& out, size_t indent) const override;
private:
Function(const Function&) = delete;
std::string name_;
std::vector<std::unique_ptr<Variable>> params_;
type::Type* return_type_ = nullptr;
std::vector<std::unique_ptr<Statement>> body_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_FUNCTION_H_

View File

@ -0,0 +1,55 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/identifier_expression.h"
namespace tint {
namespace ast {
IdentifierExpression::IdentifierExpression(const std::string& name)
: Expression(), name_({name}) {}
IdentifierExpression::IdentifierExpression(const Source& source,
const std::string& name)
: Expression(source), name_({name}) {}
IdentifierExpression::IdentifierExpression(std::vector<std::string> name)
: Expression(), name_(std::move(name)) {}
IdentifierExpression::IdentifierExpression(const Source& source,
std::vector<std::string> name)
: Expression(source), name_(std::move(name)) {}
IdentifierExpression::~IdentifierExpression() = default;
bool IdentifierExpression::IsValid() const {
return name_.size() > 0 && name_[1].size() > 0;
}
void IdentifierExpression::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent);
out << "Identifier{";
bool first = true;
for (const auto& name : name_) {
if (!first)
out << "::";
first = false;
out << name;
}
out << "}" << std::endl;
}
} // namespace ast
} // namespace tint

View File

@ -0,0 +1,75 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_IDENTIFIER_EXPRESSION_H_
#define SRC_AST_IDENTIFIER_EXPRESSION_H_
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "src/ast/expression.h"
namespace tint {
namespace ast {
/// An identifier expression
class IdentifierExpression : public Expression {
public:
/// Constructor
/// @param name the name
explicit IdentifierExpression(const std::string& name);
/// Constructor
/// @param source the source
/// @param name the name
IdentifierExpression(const Source& source, const std::string& name);
/// Constructor
/// @param name the name
explicit IdentifierExpression(std::vector<std::string> name);
/// Constructor
/// @param source the initializer source
/// @param name the name
IdentifierExpression(const Source& source, std::vector<std::string> name);
/// Move constructor
IdentifierExpression(IdentifierExpression&&) = default;
~IdentifierExpression() override;
/// Sets the name
/// @param name the name
void set_name(std::vector<std::string> name) { name_ = std::move(name); }
/// @returns the name
std::vector<std::string> name() const { return name_; }
/// @returns true if this is an identifier expression
bool IsIdentifier() const override { return true; }
/// @returns true if the node is valid
bool IsValid() const override;
/// Writes a representation of the node to the output stream
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void to_str(std::ostream& out, size_t indent) const override;
private:
IdentifierExpression(const IdentifierExpression&) = delete;
std::vector<std::string> name_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_IDENTIFIER_EXPRESSION_H_

77
src/ast/if_statement.cc Normal file
View File

@ -0,0 +1,77 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/if_statement.h"
#include "src/ast/else_statement.h"
namespace tint {
namespace ast {
IfStatement::IfStatement() : Statement() {}
IfStatement::IfStatement(std::unique_ptr<Expression> condition,
std::vector<std::unique_ptr<Statement>> body)
: Statement(), condition_(std::move(condition)), body_(std::move(body)) {}
IfStatement::IfStatement(const Source& source,
std::unique_ptr<Expression> condition,
std::vector<std::unique_ptr<Statement>> body)
: Statement(source),
condition_(std::move(condition)),
body_(std::move(body)) {}
IfStatement::~IfStatement() = default;
bool IfStatement::IsValid() const {
if (condition_ == nullptr)
return false;
if (premerge_.size() > 0 && else_statements_.size() > 1)
return false;
return true;
}
void IfStatement::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent);
out << "If{" << std::endl;
condition_->to_str(out, indent + 2);
out << std::endl;
make_indent(out, indent + 2);
out << "{" << std::endl;
for (const auto& stmt : body_)
stmt->to_str(out, indent + 4);
make_indent(out, indent + 2);
out << "}" << std::endl;
for (const auto& e : else_statements_)
e->to_str(out, indent + 2);
if (premerge_.size() > 0) {
make_indent(out, indent + 2);
out << "premerge{" << std::endl;
for (const auto& stmt : premerge_)
stmt->to_str(out, indent + 4);
make_indent(out, indent + 2);
out << "}" << std::endl;
}
}
} // namespace ast
} // namespace tint

109
src/ast/if_statement.h Normal file
View File

@ -0,0 +1,109 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_IF_STATEMENT_H_
#define SRC_AST_IF_STATEMENT_H_
#include <memory>
#include <utility>
#include <vector>
#include "src/ast/expression.h"
#include "src/ast/statement.h"
namespace tint {
namespace ast {
/// An if statement
class IfStatement : public Statement {
public:
/// Constructor
IfStatement();
/// Constructor
/// @param condition the if condition
/// @param body the if body
IfStatement(std::unique_ptr<Expression> condition,
std::vector<std::unique_ptr<Statement>> body);
/// Constructor
/// @param source the source information
/// @param condition the if condition
/// @param body the if body
IfStatement(const Source& source,
std::unique_ptr<Expression> condition,
std::vector<std::unique_ptr<Statement>> body);
/// Move constructor
IfStatement(IfStatement&&) = default;
~IfStatement() override;
/// Sets the condition for the if statement
/// @param condition the condition to set
void set_condition(std::unique_ptr<Expression> condition) {
condition_ = std::move(condition);
}
/// @returns the if condition or nullptr if none set
Expression* condition() const { return condition_.get(); }
/// Sets the if body
/// @param body the if body
void set_body(std::vector<std::unique_ptr<Statement>> body) {
body_ = std::move(body);
}
/// @returns the if body
const std::vector<std::unique_ptr<Statement>>& body() const { return body_; }
/// Sets the else statements
/// @param else_statements the else statements to set
void set_else_statements(
std::vector<std::unique_ptr<ElseStatement>> else_statements) {
else_statements_ = std::move(else_statements);
}
/// @returns the else statements
const std::vector<std::unique_ptr<ElseStatement>>& else_statements() const {
return else_statements_;
}
/// Sets the premerge statements
/// @param premerge the premerge statements
void set_premerge(std::vector<std::unique_ptr<Statement>> premerge) {
premerge_ = std::move(premerge);
}
/// @returns the premerge statements
const std::vector<std::unique_ptr<Statement>>& premerge() const {
return premerge_;
}
/// @returns true if this is a if statement
bool IsIf() const override { return true; }
/// @returns true if the node is valid
bool IsValid() const override;
/// Writes a representation of the node to the output stream
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void to_str(std::ostream& out, size_t indent) const override;
private:
IfStatement(const IfStatement&) = delete;
std::unique_ptr<Expression> condition_;
std::vector<std::unique_ptr<Statement>> body_;
std::vector<std::unique_ptr<ElseStatement>> else_statements_;
std::vector<std::unique_ptr<Statement>> premerge_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_IF_STATEMENT_H_

54
src/ast/import.cc Normal file
View File

@ -0,0 +1,54 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/import.h"
namespace tint {
namespace ast {
Import::Import(const std::string& path, const std::string& name)
: Node(), path_(path), name_(name) {}
Import::Import(const Source& source,
const std::string& path,
const std::string& name)
: Node(source), path_(path), name_(name) {}
Import::~Import() = default;
bool Import::IsValid() const {
if (path_.length() == 0) {
return false;
}
auto len = name_.length();
if (len == 0) {
return false;
}
// Verify the import name ends in a character, number or _
if (len > 2 && !std::isalnum(name_[len - 1]) && name_[len] != '_') {
return false;
}
return true;
}
void Import::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent);
out << R"(Import{")" + path_ + R"(" as )" + name_ + "}" << std::endl;
}
} // namespace ast
} // namespace tint

76
src/ast/import.h Normal file
View File

@ -0,0 +1,76 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_IMPORT_H_
#define SRC_AST_IMPORT_H_
#include <ostream>
#include <string>
#include "src/ast/node.h"
namespace tint {
namespace ast {
/// An import statement.
class Import : public Node {
public:
/// Create a new empty import statement
Import() = default;
/// Create a new import statement
/// @param path The import path e.g. GLSL.std.430
/// @param name The import reference name e.g. std::
Import(const std::string& path, const std::string& name);
/// Create a new import statement
/// @param source The input source for the import statement
/// @param path The import path e.g. GLSL.std.430
/// @param name The import reference name e.g. std::
Import(const Source& source,
const std::string& path,
const std::string& name);
/// Move constructor
Import(Import&&) = default;
~Import() override;
/// Sets the import path
/// @param path the path to set
void set_path(const std::string& path) { path_ = path; }
/// @returns the import path
const std::string& path() const { return path_; }
/// Sets the import name
/// @param name the name to set
void set_name(const std::string& name) { name_ = name; }
/// @returns the import name
const std::string& name() const { return name_; }
/// @returns true if the name and path are both present
bool IsValid() const override;
/// Writes a representation of the node to the output stream
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void to_str(std::ostream& out, size_t indent) const override;
private:
Import(const Import&) = delete;
std::string path_;
std::string name_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_IMPORT_H_

91
src/ast/import_test.cc Normal file
View File

@ -0,0 +1,91 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/import.h"
#include <sstream>
#include "gtest/gtest.h"
namespace tint {
namespace ast {
using ImportTest = testing::Test;
TEST_F(ImportTest, Creation) {
Import i("GLSL.std.430", "std::glsl");
EXPECT_EQ(i.path(), "GLSL.std.430");
EXPECT_EQ(i.name(), "std::glsl");
EXPECT_EQ(i.line(), 0);
EXPECT_EQ(i.column(), 0);
}
TEST_F(ImportTest, CreationWithSource) {
Source s{27, 4};
Import i(s, "GLSL.std.430", "std::glsl");
EXPECT_EQ(i.path(), "GLSL.std.430");
EXPECT_EQ(i.name(), "std::glsl");
EXPECT_EQ(i.line(), 27);
EXPECT_EQ(i.column(), 4);
}
TEST_F(ImportTest, CreationEmpty) {
Source s{27, 4};
Import i;
i.set_source(s);
i.set_path("GLSL.std.430");
i.set_name("std::glsl");
EXPECT_EQ(i.path(), "GLSL.std.430");
EXPECT_EQ(i.name(), "std::glsl");
EXPECT_EQ(i.line(), 27);
EXPECT_EQ(i.column(), 4);
}
TEST_F(ImportTest, to_str) {
Import i{"GLSL.std.430", "std::glsl"};
std::ostringstream out;
i.to_str(out, 2);
EXPECT_EQ(out.str(), " Import{\"GLSL.std.430\" as std::glsl}\n");
}
TEST_F(ImportTest, IsValid) {
Import i{"GLSL.std.430", "std::glsl"};
EXPECT_TRUE(i.IsValid());
}
TEST_F(ImportTest, IsValid_MissingPath) {
Import i{"", "std::glsl"};
EXPECT_FALSE(i.IsValid());
}
TEST_F(ImportTest, IsValid_MissingName) {
Import i{"GLSL.std.430", ""};
EXPECT_FALSE(i.IsValid());
}
TEST_F(ImportTest, IsValid_MissingBoth) {
Import i;
EXPECT_FALSE(i.IsValid());
}
TEST_F(ImportTest, IsValid_InvalidEndingCharacter) {
Import i{"GLSL.std.430", "std::glsl::"};
EXPECT_FALSE(i.IsValid());
}
} // namespace ast
} // namespace tint

View File

@ -0,0 +1,43 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/initializer_expression.h"
#include <assert.h>
#include "src/ast/const_initializer_expression.h"
#include "src/ast/type_initializer_expression.h"
namespace tint {
namespace ast {
InitializerExpression::InitializerExpression() = default;
InitializerExpression::~InitializerExpression() = default;
InitializerExpression::InitializerExpression(const Source& source)
: Expression(source) {}
ConstInitializerExpression* InitializerExpression::AsConstInitializer() {
assert(IsConstInitializer());
return static_cast<ConstInitializerExpression*>(this);
}
TypeInitializerExpression* InitializerExpression::AsTypeInitializer() {
assert(IsTypeInitializer());
return static_cast<TypeInitializerExpression*>(this);
}
} // namespace ast
} // namespace tint

View File

@ -0,0 +1,60 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_INITIALIZER_EXPRESSION_H_
#define SRC_AST_INITIALIZER_EXPRESSION_H_
#include "src/ast/expression.h"
namespace tint {
namespace ast {
class ConstInitializerExpression;
class TypeInitializerExpression;
/// Base class for initializer style expressions
class InitializerExpression : public Expression {
public:
~InitializerExpression() override;
/// @returns true if this is an initializer expression
bool IsInitializer() const override { return true; }
/// @returns true if this is a constant initializer
virtual bool IsConstInitializer() const { return false; }
/// @returns true if this is a type initializer
virtual bool IsTypeInitializer() const { return false; }
/// @returns this as a const initializer expression
ConstInitializerExpression* AsConstInitializer();
/// @returns this as a type initializer expression
TypeInitializerExpression* AsTypeInitializer();
protected:
/// Constructor
InitializerExpression();
/// Constructor
/// @param source the initializer source
explicit InitializerExpression(const Source& source);
/// Move constructor
InitializerExpression(InitializerExpression&&) = default;
private:
InitializerExpression(const InitializerExpression&) = delete;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_INITIALIZER_EXPRESSION_H_

29
src/ast/int_literal.cc Normal file
View File

@ -0,0 +1,29 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/int_literal.h"
namespace tint {
namespace ast {
IntLiteral::IntLiteral(int32_t value) : value_(value) {}
IntLiteral::~IntLiteral() = default;
std::string IntLiteral::to_str() const {
return std::to_string(value_);
}
} // namespace ast
} // namespace tint

49
src/ast/int_literal.h Normal file
View File

@ -0,0 +1,49 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_INT_LITERAL_H_
#define SRC_AST_INT_LITERAL_H_
#include <string>
#include "src/ast/literal.h"
namespace tint {
namespace ast {
/// A int literal
class IntLiteral : public Literal {
public:
/// Constructor
/// @param value the int literals value
explicit IntLiteral(int32_t value);
~IntLiteral() override;
/// @returns true if this is a int literal
bool IsInt() const override { return true; }
/// @returns the int literal value
int32_t value() const { return value_; }
/// @returns the literal as a string
std::string to_str() const override;
private:
int32_t value_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_INT_LITERAL_H_

View File

@ -0,0 +1,45 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/int_literal.h"
#include "gtest/gtest.h"
namespace tint {
namespace ast {
using IntLiteralTest = testing::Test;
TEST_F(IntLiteralTest, Value) {
IntLiteral i{47};
ASSERT_TRUE(i.IsInt());
EXPECT_EQ(i.value(), 47);
}
TEST_F(IntLiteralTest, Is) {
IntLiteral i{42};
EXPECT_FALSE(i.IsBool());
EXPECT_TRUE(i.IsInt());
EXPECT_FALSE(i.IsFloat());
EXPECT_FALSE(i.IsUint());
}
TEST_F(IntLiteralTest, ToStr) {
IntLiteral i{-42};
EXPECT_EQ(i.to_str(), "-42");
}
} // namespace ast
} // namespace tint

36
src/ast/kill_statement.cc Normal file
View File

@ -0,0 +1,36 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/kill_statement.h"
namespace tint {
namespace ast {
KillStatement::KillStatement() : Statement() {}
KillStatement::KillStatement(const Source& source) : Statement(source) {}
KillStatement::~KillStatement() = default;
bool KillStatement::IsValid() const {
return true;
}
void KillStatement::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent);
out << "Kill{}" << std::endl;
}
} // namespace ast
} // namespace tint

53
src/ast/kill_statement.h Normal file
View File

@ -0,0 +1,53 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_KILL_STATEMENT_H_
#define SRC_AST_KILL_STATEMENT_H_
#include "src/ast/statement.h"
namespace tint {
namespace ast {
/// A kill statement
class KillStatement : public Statement {
public:
/// Constructor
KillStatement();
/// Constructor
/// @param source the initializer source
explicit KillStatement(const Source& source);
/// Move constructor
KillStatement(KillStatement&&) = default;
~KillStatement() override;
/// @returns true if this is a kill statement
bool IsKill() const override { return true; }
/// @returns true if the node is valid
bool IsValid() const override;
/// Writes a representation of the node to the output stream
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void to_str(std::ostream& out, size_t indent) const override;
private:
KillStatement(const KillStatement&) = delete;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_KILL_STATEMENT_H_

52
src/ast/literal.cc Normal file
View File

@ -0,0 +1,52 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/literal.h"
#include <assert.h>
#include "src/ast/bool_literal.h"
#include "src/ast/float_literal.h"
#include "src/ast/int_literal.h"
#include "src/ast/uint_literal.h"
namespace tint {
namespace ast {
Literal::Literal() = default;
Literal::~Literal() = default;
BoolLiteral* Literal::AsBool() {
assert(IsBool());
return static_cast<BoolLiteral*>(this);
}
FloatLiteral* Literal::AsFloat() {
assert(IsFloat());
return static_cast<FloatLiteral*>(this);
}
IntLiteral* Literal::AsInt() {
assert(IsInt());
return static_cast<IntLiteral*>(this);
}
UintLiteral* Literal::AsUint() {
assert(IsUint());
return static_cast<UintLiteral*>(this);
}
} // namespace ast
} // namespace tint

62
src/ast/literal.h Normal file
View File

@ -0,0 +1,62 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_LITERAL_H_
#define SRC_AST_LITERAL_H_
#include <string>
namespace tint {
namespace ast {
class BoolLiteral;
class FloatLiteral;
class IntLiteral;
class UintLiteral;
/// Base class for a literal value
class Literal {
public:
virtual ~Literal();
/// @returns true if this is a bool literal
virtual bool IsBool() const { return false; }
/// @returns true if this is a float literal
virtual bool IsFloat() const { return false; }
/// @returns true if this is a signed int literal
virtual bool IsInt() const { return false; }
/// @returns true if this is a unsigned int literal
virtual bool IsUint() const { return false; }
/// @returns the literal as a boolean literal
BoolLiteral* AsBool();
/// @returns the literal as a float literal
FloatLiteral* AsFloat();
/// @returns the literal as a int literal
IntLiteral* AsInt();
/// @returns the literal as a unsigned int literal
UintLiteral* AsUint();
/// @returns the literal as a string
virtual std::string to_str() const = 0;
protected:
/// Constructor
Literal();
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_LITERAL_H_

View File

@ -0,0 +1,29 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/location_decoration.h"
namespace tint {
namespace ast {
LocationDecoration::LocationDecoration(size_t val) : value_(val) {}
LocationDecoration::~LocationDecoration() = default;
void LocationDecoration::to_str(std::ostream& out) const {
out << "location " << value_;
}
} // namespace ast
} // namespace tint

View File

@ -0,0 +1,50 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_LOCATION_DECORATION_H_
#define SRC_AST_LOCATION_DECORATION_H_
#include <stddef.h>
#include "src/ast/variable_decoration.h"
namespace tint {
namespace ast {
/// A location decoration
class LocationDecoration : public VariableDecoration {
public:
/// constructor
/// @param value the location value
explicit LocationDecoration(size_t value);
~LocationDecoration() override;
/// @returns true if this is a location decoration
bool IsLocation() const override { return true; }
/// @returns the location value
size_t value() const { return value_; }
/// Outputs the decoration to the given stream
/// @param out the stream to output too
void to_str(std::ostream& out) const override;
private:
size_t value_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_LOCATION_DECORATION_H_

View File

@ -0,0 +1,38 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/location_decoration.h"
#include "gtest/gtest.h"
namespace tint {
namespace ast {
using LocationDecorationTest = testing::Test;
TEST_F(LocationDecorationTest, Creation) {
LocationDecoration d{2};
EXPECT_EQ(2, d.value());
}
TEST_F(LocationDecorationTest, Is) {
LocationDecoration d{2};
EXPECT_FALSE(d.IsBinding());
EXPECT_FALSE(d.IsBuiltin());
EXPECT_TRUE(d.IsLocation());
EXPECT_FALSE(d.IsSet());
}
} // namespace ast
} // namespace tint

58
src/ast/loop_statement.cc Normal file
View File

@ -0,0 +1,58 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/loop_statement.h"
namespace tint {
namespace ast {
LoopStatement::LoopStatement(std::vector<std::unique_ptr<Statement>> body,
std::vector<std::unique_ptr<Statement>> continuing)
: Statement(), body_(std::move(body)), continuing_(std::move(continuing)) {}
LoopStatement::LoopStatement(const Source& source,
std::vector<std::unique_ptr<Statement>> body,
std::vector<std::unique_ptr<Statement>> continuing)
: Statement(source),
body_(std::move(body)),
continuing_(std::move(continuing)) {}
LoopStatement::~LoopStatement() = default;
bool LoopStatement::IsValid() const {
return true;
}
void LoopStatement::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent);
out << "Loop{" << std::endl;
for (const auto& stmt : body_)
stmt->to_str(out, indent + 2);
make_indent(out, indent + 2);
out << "continuing {" << std::endl;
for (const auto& stmt : continuing_)
stmt->to_str(out, indent + 4);
make_indent(out, indent + 2);
out << "}" << std::endl;
make_indent(out, indent);
out << "}" << std::endl;
}
} // namespace ast
} // namespace tint

85
src/ast/loop_statement.h Normal file
View File

@ -0,0 +1,85 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_LOOP_STATEMENT_H_
#define SRC_AST_LOOP_STATEMENT_H_
#include <memory>
#include <utility>
#include <vector>
#include "src/ast/statement.h"
namespace tint {
namespace ast {
/// A loop statement
class LoopStatement : public Statement {
public:
/// Constructor
/// @param body the body statements
/// @param continuing the continuing statements
LoopStatement(std::vector<std::unique_ptr<Statement>> body,
std::vector<std::unique_ptr<Statement>> continuing);
/// Constructor
/// @param source the initializer source
/// @param body the body statements
/// @param continuing the continuing statements
LoopStatement(const Source& source,
std::vector<std::unique_ptr<Statement>> body,
std::vector<std::unique_ptr<Statement>> continuing);
/// Move constructor
LoopStatement(LoopStatement&&) = default;
~LoopStatement() override;
/// Sets the body statements
/// @param body the body statements
void set_body(std::vector<std::unique_ptr<Statement>> body) {
body_ = std::move(body);
}
/// @returns the body statements
const std::vector<std::unique_ptr<Statement>>& body() const { return body_; }
/// Sets the continuing statements
/// @param continuing the continuing statements
void set_continuing(std::vector<std::unique_ptr<Statement>> continuing) {
continuing_ = std::move(continuing);
}
/// @returns the continuing statements
const std::vector<std::unique_ptr<Statement>>& continuing() const {
return continuing_;
}
/// @returns true if this is a loop statement
bool IsLoop() const override { return true; }
/// @returns true if the node is valid
bool IsValid() const override;
/// Writes a representation of the node to the output stream
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void to_str(std::ostream& out, size_t indent) const override;
private:
LoopStatement(const LoopStatement&) = delete;
std::vector<std::unique_ptr<Statement>> body_;
std::vector<std::unique_ptr<Statement>> continuing_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_LOOP_STATEMENT_H_

View File

@ -0,0 +1,49 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/member_accessor_expression.h"
namespace tint {
namespace ast {
MemberAccessorExpression::MemberAccessorExpression(
std::unique_ptr<Expression> structure,
std::unique_ptr<IdentifierExpression> member)
: Expression(), struct_(std::move(structure)), member_(std::move(member)) {}
MemberAccessorExpression::MemberAccessorExpression(
const Source& source,
std::unique_ptr<Expression> structure,
std::unique_ptr<IdentifierExpression> member)
: Expression(source),
struct_(std::move(structure)),
member_(std::move(member)) {}
MemberAccessorExpression::~MemberAccessorExpression() = default;
bool MemberAccessorExpression::IsValid() const {
return struct_ != nullptr && member_ != nullptr;
}
void MemberAccessorExpression::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent);
out << "MemberAccessor{" << std::endl;
struct_->to_str(out, indent + 2);
member_->to_str(out, indent + 2);
make_indent(out, indent);
out << "}" << std::endl;
}
} // namespace ast
} // namespace tint

View File

@ -0,0 +1,85 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_MEMBER_ACCESSOR_EXPRESSION_H_
#define SRC_AST_MEMBER_ACCESSOR_EXPRESSION_H_
#include <memory>
#include <string>
#include <utility>
#include "src/ast/expression.h"
#include "src/ast/identifier_expression.h"
#include "src/ast/literal.h"
namespace tint {
namespace ast {
/// A member accessor expression
class MemberAccessorExpression : public Expression {
public:
/// Constructor
/// @param structure the structure
/// @param member the member
MemberAccessorExpression(std::unique_ptr<Expression> structure,
std::unique_ptr<IdentifierExpression> member);
/// Constructor
/// @param source the initializer source
/// @param structure the structure
/// @param member the member
MemberAccessorExpression(const Source& source,
std::unique_ptr<Expression> structure,
std::unique_ptr<IdentifierExpression> member);
/// Move constructor
MemberAccessorExpression(MemberAccessorExpression&&) = default;
~MemberAccessorExpression() override;
/// Sets the structure
/// @param structure the structure
void set_structure(std::unique_ptr<Expression> structure) {
struct_ = std::move(structure);
}
/// @returns the structure
Expression* structure() const { return struct_.get(); }
/// Sets the member
/// @param member the member
void set_member(std::unique_ptr<IdentifierExpression> member) {
member_ = std::move(member);
}
/// @returns the member expression
IdentifierExpression* member() const { return member_.get(); }
/// @returns true if this is a member accessor expression
bool IsMemberAccessor() const override { return true; }
/// @returns true if the node is valid
bool IsValid() const override;
/// Writes a representation of the node to the output stream
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void to_str(std::ostream& out, size_t indent) const override;
private:
MemberAccessorExpression(const MemberAccessorExpression&) = delete;
std::unique_ptr<Expression> struct_;
std::unique_ptr<IdentifierExpression> member_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_MEMBER_ACCESSOR_EXPRESSION_H_

61
src/ast/module.cc Normal file
View File

@ -0,0 +1,61 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/module.h"
#include <sstream>
namespace tint {
namespace ast {
const Import* Module::FindImportByName(const std::string& name) {
for (const auto& import : imports_) {
if (import->name() == name)
return import.get();
}
return nullptr;
}
bool Module::IsValid() const {
for (const auto& import : imports_) {
if (!import->IsValid())
return false;
}
return true;
}
std::string Module::to_str() const {
std::ostringstream out;
for (const auto& import : imports_) {
import->to_str(out, 0);
}
for (const auto& var : global_variables_) {
var->to_str(out, 0);
}
for (const auto& ep : entry_points_) {
ep->to_str(out, 0);
}
for (const auto& alias : alias_types_) {
out << alias->name() << " -> " << alias->type()->type_name() << std::endl;
}
for (const auto& func : functions_) {
func->to_str(out, 0);
}
return out.str();
}
} // namespace ast
} // namespace tint

110
src/ast/module.h Normal file
View File

@ -0,0 +1,110 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_MODULE_H_
#define SRC_AST_MODULE_H_
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "src/ast/entry_point.h"
#include "src/ast/function.h"
#include "src/ast/import.h"
#include "src/ast/type/alias_type.h"
#include "src/ast/variable.h"
namespace tint {
namespace ast {
/// Represents all the source in a given program.
class Module {
public:
Module() = default;
/// Move constructor
Module(Module&&) = default;
~Module() = default;
/// Add the given import to the module
/// @param import The import to add.
void AddImport(std::unique_ptr<Import> import) {
imports_.push_back(std::move(import));
}
/// @returns the imports for this module
const std::vector<std::unique_ptr<Import>>& imports() { return imports_; }
/// Find the import of the given name
/// @param name The import name to search for
/// @returns the import with the given name if found, nullptr otherwise.
const Import* FindImportByName(const std::string& name);
/// Add a global variable to the module
/// @param var the variable to add
void AddGlobalVariable(std::unique_ptr<Variable> var) {
global_variables_.push_back(std::move(var));
}
/// @returns the global variables for the module
const std::vector<std::unique_ptr<Variable>>& global_variables() const {
return global_variables_;
}
/// Adds an entry point to the module
/// @param ep the entry point to add
void AddEntryPoint(std::unique_ptr<EntryPoint> ep) {
entry_points_.push_back(std::move(ep));
}
/// @returns the entry points in the module
const std::vector<std::unique_ptr<EntryPoint>>& entry_points() const {
return entry_points_;
}
/// Adds a type alias to the module
/// @param type the alias to add
void AddAliasType(type::AliasType* type) { alias_types_.push_back(type); }
/// @returns the alias types in the module
const std::vector<type::AliasType*>& alias_types() const {
return alias_types_;
}
/// Adds a function to the module
/// @param func the function
void AddFunction(std::unique_ptr<Function> func) {
functions_.push_back(std::move(func));
}
/// @returns the modules functions
const std::vector<std::unique_ptr<Function>>& functions() const {
return functions_;
}
/// @returns true if all required fields in the AST are present.
bool IsValid() const;
/// @returns a string representation of the module
std::string to_str() const;
private:
Module(const Module&) = delete;
std::vector<std::unique_ptr<Import>> imports_;
std::vector<std::unique_ptr<Variable>> global_variables_;
std::vector<std::unique_ptr<EntryPoint>> entry_points_;
// The alias types are owned by the type manager
std::vector<type::AliasType*> alias_types_;
std::vector<std::unique_ptr<Function>> functions_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_MODULE_H_

78
src/ast/module_test.cc Normal file
View File

@ -0,0 +1,78 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/module.h"
#include <utility>
#include "gtest/gtest.h"
namespace tint {
namespace ast {
using ModuleTest = testing::Test;
TEST_F(ModuleTest, Creation) {
Module m;
EXPECT_EQ(m.imports().size(), 0);
}
TEST_F(ModuleTest, Imports) {
Module m;
m.AddImport(std::make_unique<Import>("GLSL.std.430", "std::glsl"));
m.AddImport(std::make_unique<Import>("OpenCL.debug.100", "std::debug"));
EXPECT_EQ(2, m.imports().size());
EXPECT_EQ("std::glsl", m.imports()[0]->name());
}
TEST_F(ModuleTest, LookupImport) {
Module m;
auto i = std::make_unique<Import>("GLSL.std.430", "std::glsl");
m.AddImport(std::move(i));
m.AddImport(std::make_unique<Import>("OpenCL.debug.100", "std::debug"));
auto import = m.FindImportByName("std::glsl");
ASSERT_NE(nullptr, import);
EXPECT_EQ(import->path(), "GLSL.std.430");
EXPECT_EQ(import->name(), "std::glsl");
}
TEST_F(ModuleTest, LookupImportMissing) {
Module m;
EXPECT_EQ(nullptr, m.FindImportByName("Missing"));
}
TEST_F(ModuleTest, IsValid_Empty) {
Module m;
EXPECT_TRUE(m.IsValid());
}
TEST_F(ModuleTest, IsValid_InvalidImport) {
Module m;
m.AddImport(std::make_unique<Import>());
EXPECT_FALSE(m.IsValid());
}
TEST_F(ModuleTest, IsValid_ValidImport) {
Module m;
m.AddImport(std::make_unique<Import>("GLSL.std.430", "std::glsl"));
EXPECT_TRUE(m.IsValid());
}
} // namespace ast
} // namespace tint

40
src/ast/node.cc Normal file
View File

@ -0,0 +1,40 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/node.h"
#include <sstream>
namespace tint {
namespace ast {
Node::Node() = default;
Node::Node(const Source& source) : source_(source) {}
Node::~Node() = default;
void Node::make_indent(std::ostream& out, size_t indent) const {
for (size_t i = 0; i < indent; ++i)
out << " ";
}
std::string Node::str() const {
std::ostringstream out;
to_str(out, 0);
return out.str();
}
} // namespace ast
} // namespace tint

77
src/ast/node.h Normal file
View File

@ -0,0 +1,77 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_NODE_H_
#define SRC_AST_NODE_H_
#include <ostream>
#include <string>
#include "src/source.h"
namespace tint {
namespace ast {
/// AST base class node
class Node {
public:
virtual ~Node();
/// @returns the node source data
const Source& source() const { return source_; }
/// Sets the source data
/// @param source the source data
void set_source(const Source& source) { source_ = source; }
/// @returns the line the node was declared on
size_t line() const { return source_.line; }
/// @returns the column the node was declared on
size_t column() const { return source_.column; }
/// @returns true if the node is valid
virtual bool IsValid() const = 0;
/// Writes a representation of the node to the output stream
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
virtual void to_str(std::ostream& out, size_t indent) const = 0;
/// Convenience wrapper around the |to_str| method.
/// @returns the node as a string
std::string str() const;
protected:
/// Create a new node
Node();
/// Create a new node
/// @param source The input source for the node
explicit Node(const Source& source);
/// Move constructor
Node(Node&&) = default;
/// Writes indent into stream
/// @param out the stream to write to
/// @param indent the number of spaces to write
void make_indent(std::ostream& out, size_t indent) const;
private:
Node(const Node&) = delete;
Source source_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_NODE_H_

36
src/ast/nop_statement.cc Normal file
View File

@ -0,0 +1,36 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/nop_statement.h"
namespace tint {
namespace ast {
NopStatement::NopStatement() : Statement() {}
NopStatement::NopStatement(const Source& source) : Statement(source) {}
NopStatement::~NopStatement() = default;
bool NopStatement::IsValid() const {
return true;
}
void NopStatement::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent);
out << "Nop{}" << std::endl;
}
} // namespace ast
} // namespace tint

53
src/ast/nop_statement.h Normal file
View File

@ -0,0 +1,53 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_NOP_STATEMENT_H_
#define SRC_AST_NOP_STATEMENT_H_
#include "src/ast/statement.h"
namespace tint {
namespace ast {
/// A nop statement
class NopStatement : public Statement {
public:
/// Constructor
NopStatement();
/// Constructor
/// @param source the initializer source
explicit NopStatement(const Source& source);
/// Move constructor
NopStatement(NopStatement&&) = default;
~NopStatement() override;
/// @returns true if this is a nop statement
bool IsNop() const override { return true; }
/// @returns true if the node is valid
bool IsValid() const override;
/// Writes a representation of the node to the output stream
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void to_str(std::ostream& out, size_t indent) const override;
private:
NopStatement(const NopStatement&) = delete;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_NOP_STATEMENT_H_

43
src/ast/pipeline_stage.cc Normal file
View File

@ -0,0 +1,43 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/pipeline_stage.h"
namespace tint {
namespace ast {
std::ostream& operator<<(std::ostream& out, PipelineStage stage) {
switch (stage) {
case PipelineStage::kNone: {
out << "none";
break;
}
case PipelineStage::kVertex: {
out << "vertex";
break;
}
case PipelineStage::kFragment: {
out << "fragment";
break;
}
case PipelineStage::kCompute: {
out << "compute";
break;
}
}
return out;
}
} // namespace ast
} // namespace tint

31
src/ast/pipeline_stage.h Normal file
View File

@ -0,0 +1,31 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_PIPELINE_STAGE_H_
#define SRC_AST_PIPELINE_STAGE_H_
#include <ostream>
namespace tint {
namespace ast {
/// The pipeline stage
enum class PipelineStage { kNone = -1, kVertex, kFragment, kCompute };
std::ostream& operator<<(std::ostream& out, PipelineStage stage);
} // namespace ast
} // namespace tint
#endif // SRC_AST_PIPELINE_STAGE_H_

View File

@ -0,0 +1,58 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/regardless_statement.h"
namespace tint {
namespace ast {
RegardlessStatement::RegardlessStatement(
std::unique_ptr<Expression> condition,
std::vector<std::unique_ptr<Statement>> body)
: Statement(), condition_(std::move(condition)), body_(std::move(body)) {}
RegardlessStatement::RegardlessStatement(
const Source& source,
std::unique_ptr<Expression> condition,
std::vector<std::unique_ptr<Statement>> body)
: Statement(source),
condition_(std::move(condition)),
body_(std::move(body)) {}
RegardlessStatement::~RegardlessStatement() = default;
bool RegardlessStatement::IsValid() const {
return condition_ != nullptr;
}
void RegardlessStatement::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent);
out << "Regardless{" << std::endl;
condition_->to_str(out, indent + 2);
make_indent(out, indent);
out << "{" << std::endl;
for (const auto& stmt : body_)
stmt->to_str(out, indent + 4);
make_indent(out, indent + 2);
out << "}";
make_indent(out, indent);
out << "}" << std::endl;
}
} // namespace ast
} // namespace tint

View File

@ -0,0 +1,84 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_REGARDLESS_STATEMENT_H_
#define SRC_AST_REGARDLESS_STATEMENT_H_
#include <memory>
#include <utility>
#include <vector>
#include "src/ast/expression.h"
#include "src/ast/statement.h"
namespace tint {
namespace ast {
/// A regardless statement
class RegardlessStatement : public Statement {
public:
/// Constructor
/// @param condition the condition expression
/// @param body the body statements
RegardlessStatement(std::unique_ptr<Expression> condition,
std::vector<std::unique_ptr<Statement>> body);
/// Constructor
/// @param source the initializer source
/// @param condition the condition expression
/// @param body the body statements
RegardlessStatement(const Source& source,
std::unique_ptr<Expression> condition,
std::vector<std::unique_ptr<Statement>> body);
/// Move constructor
RegardlessStatement(RegardlessStatement&&) = default;
~RegardlessStatement() override;
/// Sets the condition expression
/// @param condition the condition expression
void set_condition(std::unique_ptr<Expression> condition) {
condition_ = std::move(condition);
}
/// @returns the condition statements
Expression* condition() const { return condition_.get(); }
/// Sets the body statements
/// @param body the body statements
void set_body(std::vector<std::unique_ptr<Statement>> body) {
body_ = std::move(body);
}
/// @returns the body statements
const std::vector<std::unique_ptr<Statement>>& body() const { return body_; }
/// @returns true if this is an regardless statement
bool IsRegardless() const override { return true; }
/// @returns true if the node is valid
bool IsValid() const override;
/// Writes a representation of the node to the output stream
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void to_str(std::ostream& out, size_t indent) const override;
private:
RegardlessStatement(const RegardlessStatement&) = delete;
std::unique_ptr<Expression> condition_;
std::vector<std::unique_ptr<Statement>> body_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_REGARDLESS_STATEMENT_H_

View File

@ -0,0 +1,55 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/relational_expression.h"
namespace tint {
namespace ast {
RelationalExpression::RelationalExpression(Relation relation,
std::unique_ptr<Expression> lhs,
std::unique_ptr<Expression> rhs)
: Expression(),
relation_(relation),
lhs_(std::move(lhs)),
rhs_(std::move(rhs)) {}
RelationalExpression::RelationalExpression(const Source& source,
Relation relation,
std::unique_ptr<Expression> lhs,
std::unique_ptr<Expression> rhs)
: Expression(source),
relation_(relation),
lhs_(std::move(lhs)),
rhs_(std::move(rhs)) {}
RelationalExpression::~RelationalExpression() = default;
bool RelationalExpression::IsValid() const {
return relation_ != Relation::kNone && lhs_ != nullptr && rhs_ != nullptr;
}
void RelationalExpression::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent);
out << relation_ << "(" << std::endl;
lhs_->to_str(out, indent + 2);
out << std::endl;
rhs_->to_str(out, indent + 2);
out << std::endl;
make_indent(out, indent);
out << ")" << std::endl;
}
} // namespace ast
} // namespace tint

View File

@ -0,0 +1,220 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_RELATIONAL_EXPRESSION_H_
#define SRC_AST_RELATIONAL_EXPRESSION_H_
#include <memory>
#include <utility>
#include "src/ast/expression.h"
#include "src/ast/literal.h"
namespace tint {
namespace ast {
/// The relation type
enum class Relation {
kNone = 0,
kAnd,
kOr,
kXor,
kLogicalAnd,
kLogicalOr,
kEqual,
kNotEqual,
kLessThan,
kGreaterThan,
kLessThanEqual,
kGreaterThanEqual,
kUnordGreaterThan,
kUnordGreaterThanEqual,
kUnordLessThan,
kUnordLessThanEqual,
kUnordEqual,
kUnordNotEqual,
kSignedGreaterThan,
kSignedGreaterThanEqual,
kSignedLessThan,
kSignedLessThanEqual,
kShiftLeft,
kShiftRight,
kShiftRightArith,
kAdd,
kSubtract,
kMultiply,
kDivide,
kModulo,
};
/// An xor expression
class RelationalExpression : public Expression {
public:
/// Constructor
/// @param relation the relation type
/// @param lhs the left side of the expression
/// @param rhs the right side of the expression
RelationalExpression(Relation relation,
std::unique_ptr<Expression> lhs,
std::unique_ptr<Expression> rhs);
/// Constructor
/// @param source the initializer source
/// @param relation the relation type
/// @param lhs the left side of the expression
/// @param rhs the right side of the expression
RelationalExpression(const Source& source,
Relation relation,
std::unique_ptr<Expression> lhs,
std::unique_ptr<Expression> rhs);
/// Move constructor
RelationalExpression(RelationalExpression&&) = default;
~RelationalExpression() override;
/// Sets the relation type
/// @param relation the relation type
void set_relation(Relation relation) { relation_ = relation; }
/// @returns the relation
Relation relation() const { return relation_; }
/// Sets the left side of the expression
/// @param lhs the left side to set
void set_lhs(std::unique_ptr<Expression> lhs) { lhs_ = std::move(lhs); }
/// @returns the left side expression
Expression* lhs() const { return lhs_.get(); }
/// Sets the right side of the expression
/// @param rhs the right side to set
void set_rhs(std::unique_ptr<Expression> rhs) { rhs_ = std::move(rhs); }
/// @returns the right side expression
Expression* rhs() const { return rhs_.get(); }
/// @returns true if this is a relational expression
bool IsRelational() const override { return true; }
/// @returns true if the node is valid
bool IsValid() const override;
/// Writes a representation of the node to the output stream
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void to_str(std::ostream& out, size_t indent) const override;
private:
RelationalExpression(const RelationalExpression&) = delete;
Relation relation_ = Relation::kNone;
std::unique_ptr<Expression> lhs_;
std::unique_ptr<Expression> rhs_;
};
inline std::ostream& operator<<(std::ostream& out, Relation relation) {
switch (relation) {
case Relation::kNone:
out << "none";
break;
case Relation::kAnd:
out << "and";
break;
case Relation::kOr:
out << "or";
break;
case Relation::kXor:
out << "xor";
break;
case Relation::kLogicalAnd:
out << "logical_and";
break;
case Relation::kLogicalOr:
out << "logical_or";
break;
case Relation::kEqual:
out << "equal";
break;
case Relation::kNotEqual:
out << "not_equal";
break;
case Relation::kLessThan:
out << "less_than";
break;
case Relation::kGreaterThan:
out << "greater_than";
break;
case Relation::kLessThanEqual:
out << "less_than_equal";
break;
case Relation::kGreaterThanEqual:
out << "greater_than_equal";
break;
case Relation::kUnordGreaterThan:
out << "unord_greater_than";
break;
case Relation::kUnordGreaterThanEqual:
out << "unord_greater_than_equal";
break;
case Relation::kUnordLessThan:
out << "unord_less_than";
break;
case Relation::kUnordLessThanEqual:
out << "unord_less_than_equal";
break;
case Relation::kUnordEqual:
out << "unord_equal";
break;
case Relation::kUnordNotEqual:
out << "unord_not_equal";
break;
case Relation::kSignedGreaterThan:
out << "signed_greateR_than";
break;
case Relation::kSignedGreaterThanEqual:
out << "signed_greater_than_equal";
break;
case Relation::kSignedLessThan:
out << "signed_less_than";
break;
case Relation::kSignedLessThanEqual:
out << "signed_less_than_equal";
break;
case Relation::kShiftLeft:
out << "shift_left";
break;
case Relation::kShiftRight:
out << "shift_right";
break;
case Relation::kShiftRightArith:
out << "shift_right_arith";
break;
case Relation::kAdd:
out << "add";
break;
case Relation::kSubtract:
out << "subtract";
break;
case Relation::kMultiply:
out << "multiply";
break;
case Relation::kDivide:
out << "divide";
break;
case Relation::kModulo:
out << "modulo";
break;
}
return out;
}
} // namespace ast
} // namespace tint
#endif // SRC_AST_RELATIONAL_EXPRESSION_H_

View File

@ -0,0 +1,48 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/ast/return_statement.h"
namespace tint {
namespace ast {
ReturnStatement::ReturnStatement() : Statement() {}
ReturnStatement::ReturnStatement(std::unique_ptr<Expression> value)
: Statement(), value_(std::move(value)) {}
ReturnStatement::ReturnStatement(const Source& source,
std::unique_ptr<Expression> value)
: Statement(source), value_(std::move(value)) {}
ReturnStatement::~ReturnStatement() = default;
bool ReturnStatement::IsValid() const {
return true;
}
void ReturnStatement::to_str(std::ostream& out, size_t indent) const {
make_indent(out, indent);
out << "Return{";
if (value_) {
out << std::endl;
value_->to_str(out, indent);
make_indent(out, indent);
}
out << "}" << std::endl;
}
} // namespace ast
} // namespace tint

View File

@ -0,0 +1,71 @@
// Copyright 2020 The Tint Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SRC_AST_RETURN_STATEMENT_H_
#define SRC_AST_RETURN_STATEMENT_H_
#include <memory>
#include <utility>
#include "src/ast/expression.h"
#include "src/ast/statement.h"
namespace tint {
namespace ast {
/// A return statement
class ReturnStatement : public Statement {
public:
/// Constructor
ReturnStatement();
/// Constructor
/// @param value the return value
explicit ReturnStatement(std::unique_ptr<Expression> value);
/// Constructor
/// @param source the initializer source
/// @param value the return value
ReturnStatement(const Source& source, std::unique_ptr<Expression> value);
/// Move constructor
ReturnStatement(ReturnStatement&&) = default;
~ReturnStatement() override;
/// Sets the value
/// @param value the value
void set_value(std::unique_ptr<Expression> value) {
value_ = std::move(value);
}
/// @returns the value
Expression* value() const { return value_.get(); }
/// @returns true if this is a return statement
bool IsReturn() const override { return true; }
/// @returns true if the node is valid
bool IsValid() const override;
/// Writes a representation of the node to the output stream
/// @param out the stream to write to
/// @param indent number of spaces to indent the node when writing
void to_str(std::ostream& out, size_t indent) const override;
private:
ReturnStatement(const ReturnStatement&) = delete;
std::unique_ptr<Expression> value_;
};
} // namespace ast
} // namespace tint
#endif // SRC_AST_RETURN_STATEMENT_H_

Some files were not shown because too many files have changed in this diff Show More