Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse slang.h for future language binding generation #5804

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions include/slang.h
Original file line number Diff line number Diff line change
Expand Up @@ -1729,8 +1729,6 @@ public: \
typedef slang::IGlobalSession SlangSession;


typedef struct SlangProgramLayout SlangProgramLayout;

/*!
@brief A request for one or more compilation actions to be performed.
*/
Expand Down
4 changes: 3 additions & 1 deletion source/core/slang-string-util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -690,16 +690,18 @@ String StringUtil::replaceAll(
}

int radix = 10;
auto isDigit = CharUtil::isDigit;
auto getDigit = CharUtil::getDecimalDigitValue;
if (cur + 1 < end && *cur == '0' && (*(cur + 1) == 'x' || *(cur + 1) == 'X'))
{
radix = 16;
isDigit = CharUtil::isHexDigit;
getDigit = CharUtil::getHexDigitValue;
cur += 2;
}

// We need at least one digit
if (cur >= end || !CharUtil::isDigit(*cur))
if (cur >= end || !isDigit(*cur))
{
return SLANG_FAIL;
}
Expand Down
13 changes: 13 additions & 0 deletions source/slang/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,18 @@ target_include_directories(
INTERFACE ${SLANG_REFLECT_OUTPUT_DIR}
)

#
# generate language bindings
#

add_custom_target(
generate_language_bindings
COMMAND
slang-binding-generator -d "${slang_SOURCE_DIR}/include" slang.h -unit-test
DEPENDS "${slang_SOURCE_DIR}/include/slang.h" slang-binding-generator
VERBATIM
)

#
# generated lookup tables
#
Expand Down Expand Up @@ -212,6 +224,7 @@ set(slang_build_args
${SLANG_RECORD_REPLAY_SYSTEM}
REQUIRES
copy_slang_headers
generate_language_bindings
)
set(slang_link_args
LINK_WITH_PRIVATE
Expand Down
7 changes: 7 additions & 0 deletions tools/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ generator(
compiler-core
slang-cpp-parser
)
generator(
slang-binding-generator
USE_FEWER_WARNINGS
LINK_WITH_PRIVATE
compiler-core
slang-cpp-parser
)
generator(slang-embed)
generator(slang-generate USE_FEWER_WARNINGS)
generator(slang-lookup-generator LINK_WITH_PRIVATE compiler-core)
Expand Down
161 changes: 161 additions & 0 deletions tools/slang-binding-generator/binding-generator-main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
#include "compiler-core/slang-diagnostic-sink.h"
#include "compiler-core/slang-lexer.h"
#include "compiler-core/slang-name.h"
#include "compiler-core/slang-source-loc.h"
#include "core/slang-file-system.h"
#include "core/slang-io.h"
#include "core/slang-list.h"
#include "core/slang-string-slice-pool.h"
#include "core/slang-string-util.h"
#include "core/slang-string.h"
#include "core/slang-writer.h"
#include "slang-com-helper.h"
#include "slang-cpp-parser/diagnostics.h"
#include "slang-cpp-parser/file-util.h"
#include "slang-cpp-parser/node-tree.h"
#include "slang-cpp-parser/node.h"
#include "slang-cpp-parser/options.h"
#include "slang-cpp-parser/parser.h"
#include "slang-cpp-parser/unit-test.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

namespace BindingGenerator
{

using namespace Slang;
using namespace CppParse;

class App
{
public:
SlangResult execute(const Options& options);

SlangResult executeWithArgs(int argc, const char* const* argv);

const Options& getOptions() const { return m_options; }

App(DiagnosticSink* sink, SourceManager* sourceManager, RootNamePool* rootNamePool)
: m_sink(sink), m_sourceManager(sourceManager), m_slicePool(StringSlicePool::Style::Default)
{
m_namePool.setRootNamePool(rootNamePool);
}

protected:
NamePool m_namePool;

Options m_options;
DiagnosticSink* m_sink;
SourceManager* m_sourceManager;

StringSlicePool m_slicePool;
};

SlangResult App::execute(const Options& options)
{
m_options = options;

if (options.m_runUnitTests)
{
SLANG_RETURN_ON_FAIL(UnitTestUtil::run());
}

IdentifierLookup identifierLookup;
identifierLookup.initDefault(options.m_markPrefix.getUnownedSlice());

NodeTree tree(&m_slicePool, &m_namePool, &identifierLookup);

// Read in each of the input files
for (Index i = 0; i < m_options.m_inputPaths.getCount(); ++i)
{
String inputPath;

if (m_options.m_inputDirectory.getLength())
{
inputPath = Path::combine(m_options.m_inputDirectory, m_options.m_inputPaths[i]);
}
else
{
inputPath = m_options.m_inputPaths[i];
}

// Read the input file
String contents;
SLANG_RETURN_ON_FAIL(FileUtil::readAllText(inputPath, m_sink, contents));

PathInfo pathInfo = PathInfo::makeFromString(inputPath);

SourceFile* sourceFile = m_sourceManager->createSourceFileWithString(pathInfo, contents);

SourceOrigin* sourceOrigin = tree.addSourceOrigin(sourceFile, options);

Parser parser(&tree, m_sink);
SLANG_RETURN_ON_FAIL(parser.parse(sourceOrigin, &m_options));
}

SLANG_RETURN_ON_FAIL(tree.calcDerivedTypes(m_sink));

// Dump out the tree
if (options.m_dump)
{
{
StringBuilder buf;
tree.getRootNode()->dump(0, buf);
m_sink->writer->write(buf.getBuffer(), buf.getLength());
}
}

return SLANG_OK;
}

SlangResult App::executeWithArgs(int argc, const char* const* argv)
{
Options options;
OptionsParser optionsParser;
SLANG_RETURN_ON_FAIL(optionsParser.parse(argc, argv, m_sink, options));
SLANG_RETURN_ON_FAIL(execute(options));
return SLANG_OK;
}

} // namespace BindingGenerator

int main(int argc, const char* const* argv)
{
using namespace Slang;
using namespace BindingGenerator;

ComPtr<ISlangWriter> writer(new FileWriter(stderr, WriterFlag::AutoFlush));

RootNamePool rootNamePool;

SourceManager sourceManager;
sourceManager.initialize(nullptr, nullptr);

DiagnosticSink sink(&sourceManager, Lexer::sourceLocationLexer);
sink.writer = writer;

App app(&sink, &sourceManager, &rootNamePool);

try
{
if (SLANG_FAILED(app.executeWithArgs(argc - 1, argv + 1)))
{
sink.diagnose(SourceLoc(), CPPDiagnostics::extractorFailed);
return 1;
}
if (sink.getErrorCount())
{
sink.diagnose(SourceLoc(), CPPDiagnostics::extractorFailed);
return 1;
}
}
catch (...)
{
sink.diagnose(SourceLoc(), CPPDiagnostics::internalError);
return 1;
}

return 0;
}
20 changes: 20 additions & 0 deletions tools/slang-cpp-parser/node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,26 @@ void ClassLikeNode::dump(int indentCount, StringBuilder& out)

out << " {\n";

if (m_guid != Guid())
{
_indent(indentCount + 1, out);
StringUtil::appendFormat(
out,
"COM_INTERFACE(0x%08lx, 0x%04hx, 0x%04hx, {0x%02hhx, 0x%02hhx, 0x%02hhx, 0x%02hhx, "
"0x%02hhx, 0x%02hhx, 0x%02hhx, 0x%02hhx})\n",
m_guid.data1,
m_guid.data2,
m_guid.data3,
m_guid.data4[0],
m_guid.data4[1],
m_guid.data4[2],
m_guid.data4[3],
m_guid.data4[4],
m_guid.data4[5],
m_guid.data4[6],
m_guid.data4[7]);
}

for (Node* child : m_children)
{
child->dump(indentCount + 1, out);
Expand Down
4 changes: 3 additions & 1 deletion tools/slang-cpp-parser/node.h
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ struct ClassLikeNode : public ScopeNode
virtual void dump(int indent, StringBuilder& out) SLANG_OVERRIDE;

ClassLikeNode(Kind kind)
: Super(kind), m_origin(nullptr), m_typeSet(nullptr), m_superNode(nullptr)
: Super(kind), m_origin(nullptr), m_typeSet(nullptr), m_superNode(nullptr), m_guid(Guid())
{
SLANG_ASSERT(kind == Kind::ClassType || kind == Kind::StructType);
}
Expand All @@ -333,6 +333,8 @@ struct ClassLikeNode : public ScopeNode
Token m_super; ///< Super class name
ClassLikeNode* m_superNode; ///< If this is a class/struct, the type it is derived from (or
///< nullptr if base)

Guid m_guid; ///< The guid associated with this type
};

struct CallableNode : public Node
Expand Down
Loading
Loading