summaryrefslogtreecommitdiff
path: root/source/slang/slang-source-stream.h
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2019-05-31 13:17:34 -0400
committerTim Foley <tfoleyNV@users.noreply.github.com>2019-05-31 10:17:34 -0700
commitb81ff3ef968d1cc4e954b31a1812b3c391d17b02 (patch)
treed9669f736c3be30c569b1c0dbd0abfaca6e85a0c /source/slang/slang-source-stream.h
parentd4924f5fc67f56b60d11381bf77d21bc01eb8763 (diff)
WIP: Support for other source target language (#971)
* WIP: Setting up C/Cpp source compilation targets. * WIP: Emitting C/CPP. * WIP: Split out SourceSink, and use it for source output on emit. * SourceSink -> SourceStream * * Made SourceStream use m_ prefixing of members. * Make all methods use lower camel * Removed methods from SourceStream interface that are not used externally (use _ prefixing) * Improvements to documentation * EmitContext is now effectively empty, so just use SharedEmitContext as EmitContext. * SharedEmitContext -> EmitContext * Methods to LowerCamel in emit.cpp * Split out EmitContext and ExtensionUsageTracker into separate files. * Split out EmitVisitor into slang-c-like-source-emitter files. * EmitVisitor -> CLikeSourceEmitter * Tidy up around CLikeSourceEmitter - simplify header. * Small tidy up - removing repeated comments that are in header. * Remove EmitContext paramter threading. * Small tidy up. Use prefixed macros for slang-c-like-source-emitter.h * Small tidy up in slang-c-like-source-emitter.cpp * First pass at splitting out UnmangleContext. * MangledNameParser -> MangledLexer. * WIP making EmitOp (EOp) enum available outside of cpp * Generating EmitOpInfo from macro. * Split out emit precedence handling. Don't use kOp_ style anymore, just use an array indexed by EmitOp. * Disable C simple test for now. * Keep g++/clang happy with token pasting. * Fix win32 narrowing warning.
Diffstat (limited to 'source/slang/slang-source-stream.h')
-rw-r--r--source/slang/slang-source-stream.h113
1 files changed, 113 insertions, 0 deletions
diff --git a/source/slang/slang-source-stream.h b/source/slang/slang-source-stream.h
new file mode 100644
index 000000000..8dcd29c8d
--- /dev/null
+++ b/source/slang/slang-source-stream.h
@@ -0,0 +1,113 @@
+// slang-source-stream.h
+#ifndef SLANG_SOURCE_STREAM_H_INCLUDED
+#define SLANG_SOURCE_STREAM_H_INCLUDED
+
+#include "../core/basic.h"
+
+#include "compiler.h"
+
+namespace Slang
+{
+
+/* Class that encapsulates a stream of source. Facilities provided...
+
+* Management of the buffer that holds the source content as it is constructed
+* output line directives
+ + Supports GLSL as well as C/CPP/HLSL style directives
+* Support for line indention */
+class SourceStream
+{
+public:
+ /// Emits without span without any extra processing
+ void emitRawTextSpan(char const* textBegin, char const* textEnd);
+ void emitRawText(char const* text);
+
+ /// Emit different types into the stream
+ void emit(char const* textBegin, char const* textEnd);
+ void emit(char const* text);
+ void emit(const String& text);
+ void emit(const UnownedStringSlice& text);
+ void emit(Name* name);
+ void emit(const NameLoc& nameAndLoc);
+ void emit(IntegerLiteralValue value);
+ void emit(UInt value);
+ void emit(int value);
+ void emit(double value);
+
+ /// Emit names (doing so can also advance to a new source location)
+ void emitName(const NameLoc& nameAndLoc);
+ void emitName(Name* name, const SourceLoc& loc);
+ void emitName(Name* name);
+
+ /// Indent the text
+ void indent();
+ /// Dedent (the opposite of indenting) the text
+ void dedent();
+
+ /// Move the current source location to that specified
+ void advanceToSourceLocation(const SourceLoc& sourceLocation);
+ void advanceToSourceLocation(const HumaneSourceLoc& sourceLocation);
+
+ /// Get the content as a string
+ String getContent() { return m_builder.ProduceString(); }
+ /// Clear the content
+ void clearContent() { m_builder.Clear(); }
+ /// Get the content as a string and clear the internal representation
+ String getContentAndClear();
+
+ /// Get the line directive mode used
+ LineDirectiveMode getLineDirectiveMode() const { return m_lineDirectiveMode; }
+ /// Get the source manager user
+ SourceManager* getSourceManager() const { return m_sourceManager; }
+
+ /// Ctor
+ SourceStream(SourceManager* sourceManager, LineDirectiveMode lineDirectiveMode);
+
+protected:
+ void _emitTextSpan(char const* textBegin, char const* textEnd);
+ void _flushSourceLocationChange();
+
+ // Emit a `#line` directive to the output, and also
+ // ensure that source location tracking information
+ // is correct based on the directive we just output.
+ void _emitLineDirectiveAndUpdateSourceLocation(const HumaneSourceLoc& sourceLocation);
+
+ void _emitLineDirectiveIfNeeded(const HumaneSourceLoc& sourceLocation);
+
+ // Emit a `#line` directive to the output.
+ // Doesn't update state of source-location tracking.
+ void _emitLineDirective(const HumaneSourceLoc& sourceLocation);
+
+ // The string of code we've built so far.
+ // TODO(JS): We could store the text in chunks, and then only sew together into one buffer
+ // when we are done. Doing so would not require copies/reallocs until the full buffer has been
+ // produced. A downside to doing this is that it won't be so simple to debug by trying to
+ // look at the current contents of the buffer
+ StringBuilder m_builder;
+
+ // Current source position for tracking purposes...
+ HumaneSourceLoc m_loc;
+ HumaneSourceLoc m_nextSourceLocation;
+ bool m_needToUpdateSourceLocation = false;
+
+ // Are we at the start of a line, so that we should indent
+ // before writing any other text?
+ bool m_isAtStartOfLine = true;
+
+ // How far are we indented?
+ Int m_indentLevel = 0;
+
+ SourceManager* m_sourceManager = nullptr;
+
+ // For GLSL output, we can't emit traditional `#line` directives
+ // with a file path in them, so we maintain a map that associates
+ // each path with a unique integer, and then we output those
+ // instead.
+ Dictionary<String, int> m_mapGLSLSourcePathToID;
+ int m_glslSourceIDCount = 0;
+
+ LineDirectiveMode m_lineDirectiveMode;
+};
+
+}
+#endif