First Commit

This commit is contained in:
2025-02-06 22:24:29 +08:00
parent ed7df4c81e
commit 7539e6a53c
18116 changed files with 6181499 additions and 0 deletions

View File

@@ -0,0 +1,132 @@
// Copyright 2014 Tony Wasserka
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the owner nor the names of its contributors may
// be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/spirit/include/qi.hpp>
#include "nihstro/parser_assembly.h"
#include "nihstro/parser_assembly_private.h"
#include "nihstro/shader_binary.h"
#include "nihstro/shader_bytecode.h"
using spirit::_1;
using spirit::_2;
using spirit::_3;
using spirit::_4;
using namespace nihstro;
// Adapt parser data structures for use with boost::spirit
BOOST_FUSION_ADAPT_STRUCT(
ConditionInput,
(bool, invert)
(Identifier, identifier)
(boost::optional<InputSwizzlerMask>, swizzler_mask)
)
BOOST_FUSION_ADAPT_STRUCT(
StatementDeclaration::Extra,
(std::vector<float>, constant_value)
(boost::optional<OutputRegisterInfo::Type>, output_semantic)
)
BOOST_FUSION_ADAPT_STRUCT(
StatementDeclaration,
(std::string, alias_name)
(Identifier, identifier_start)
(boost::optional<Identifier>, identifier_end)
(boost::optional<InputSwizzlerMask>, swizzle_mask)
(StatementDeclaration::Extra, extra)
)
// Manually define a swap() overload for qi::hold to work.
/*namespace boost {
namespace spirit {
void swap(nihstro::Condition& a, nihstro::Condition& b) {
boost::fusion::swap(a, b);
}
}
}*/
template<>
DeclarationParser<ParserIterator>::DeclarationParser(const ParserContext& context)
: DeclarationParser::base_type(declaration),
common(context),
identifier(common.identifier), swizzle_mask(common.swizzle_mask),
end_of_statement(common.end_of_statement),
diagnostics(common.diagnostics) {
// Setup symbol table
output_semantics.add("position", OutputRegisterInfo::POSITION);
output_semantics.add("quaternion", OutputRegisterInfo::QUATERNION);
output_semantics.add("color", OutputRegisterInfo::COLOR);
output_semantics.add("texcoord0", OutputRegisterInfo::TEXCOORD0);
output_semantics.add("texcoord1", OutputRegisterInfo::TEXCOORD1);
output_semantics.add("texcoord2", OutputRegisterInfo::TEXCOORD2);
output_semantics.add("view", OutputRegisterInfo::VIEW);
output_semantics_rule = qi::lexeme[output_semantics];
// Setup rules
alias_identifier = qi::omit[qi::lexeme["alias" >> ascii::blank]] > identifier;
// e.g. 5.4 or (1.1, 2, 3)
constant = (qi::repeat(1)[qi::float_]
| (qi::lit('(') > (qi::float_ % qi::lit(',')) > qi::lit(')')));
dummy_const = qi::attr(std::vector<float>());
dummy_semantic = qi::attr(boost::optional<OutputRegisterInfo::Type>());
// match a constant or a semantic, and fill the respective other one with a dummy
const_or_semantic = (dummy_const >> output_semantics_rule) | (constant >> dummy_semantic);
// TODO: Would like to use +ascii::blank instead, but somehow that fails to parse lines like ".alias name o2.xy texcoord0" correctly
string_as = qi::omit[qi::no_skip[*/*+*/ascii::blank >> qi::lit("as") >> +ascii::blank]];
declaration = ((qi::lit('.') > alias_identifier) >> identifier >> -(qi::lit('-') > identifier) >> -(qi::lit('.') > swizzle_mask))
>> (
(string_as > const_or_semantic)
| (dummy_const >> dummy_semantic)
)
> end_of_statement;
// Error handling
output_semantics_rule.name("output semantic after \"as\"");
alias_identifier.name("known preprocessor directive (i.e. alias).");
const_or_semantic.name("constant or semantic after \"as\"");
BOOST_SPIRIT_DEBUG_NODE(output_semantics_rule);
BOOST_SPIRIT_DEBUG_NODE(constant);
BOOST_SPIRIT_DEBUG_NODE(alias_identifier);
BOOST_SPIRIT_DEBUG_NODE(const_or_semantic);
BOOST_SPIRIT_DEBUG_NODE(declaration);
qi::on_error<qi::fail>(declaration, error_handler(phoenix::ref(diagnostics), _1, _2, _3, _4));
}