summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Foley <tfoley@nvidia.com>2017-06-26 14:09:53 -0700
committerTim Foley <tfoley@nvidia.com>2017-06-26 14:14:06 -0700
commit7d97d424c0a754ec49cccfc8af6c8983e0d06d80 (patch)
tree3669bf42ed6e971cde176cb422beab6c53158e8c
parent0259ddb0a72d3b12278404847f6e30b63e97cfc3 (diff)
Fix parsing of string literals.
String literals can be used as part of attributes, but we lacked an actual AST representation for them. This change adds basic parsing for string literals, as well as emit logic for them. I also included a fix for parsing of chained right-associative operators. To test these fixes, I've re-enabled one of the HLSL tests I disabled a while back. It would be good to go through and see how many of those we can re-enable now.
-rw-r--r--source/slang/emit.cpp31
-rw-r--r--source/slang/parser.cpp31
-rw-r--r--source/slang/syntax.h6
-rw-r--r--tests/hlsl/dxsdk/SimpleBezier11/SimpleBezier11.hlsl1
4 files changed, 64 insertions, 5 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index eae9cd052..699294d84 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -765,6 +765,34 @@ static void emitCallExpr(
emitSimpleCallExpr(context, callExpr, outerPrec);
}
+static void emitStringLiteral(
+ EmitContext* context,
+ String const& value)
+{
+ emit(context, "\"");
+ for (auto c : value)
+ {
+ // TODO: This needs a more complete implementation,
+ // especially if we want to support Unicode.
+
+ char buffer[] = { c, 0 };
+ switch (c)
+ {
+ default:
+ emit(context, buffer);
+ break;
+
+ case '\"': emit(context, "\\\"");
+ case '\'': emit(context, "\\\'");
+ case '\\': emit(context, "\\\\");
+ case '\n': emit(context, "\\n");
+ case '\r': emit(context, "\\r");
+ case '\t': emit(context, "\\t");
+ }
+ }
+ emit(context, "\"");
+}
+
static void EmitExprWithPrecedence(EmitContext* context, RefPtr<ExpressionSyntaxNode> expr, int outerPrec)
{
bool needClose = false;
@@ -874,6 +902,9 @@ static void EmitExprWithPrecedence(EmitContext* context, RefPtr<ExpressionSyntax
case ConstantExpressionSyntaxNode::ConstantType::Bool:
Emit(context, litExpr->IntValue ? "true" : "false");
break;
+ case ConstantExpressionSyntaxNode::ConstantType::String:
+ emitStringLiteral(context, litExpr->stringValue);
+ break;
default:
assert(!"unreachable");
break;
diff --git a/source/slang/parser.cpp b/source/slang/parser.cpp
index 61d7b225d..8edc3a122 100644
--- a/source/slang/parser.cpp
+++ b/source/slang/parser.cpp
@@ -3014,9 +3014,7 @@ namespace Slang
{
auto nextOpPrec = GetOpLevel(parser, parser->tokenReader.PeekTokenType());
- if((GetAssociativityFromLevel(nextOpPrec) == Associativity::Right) && (nextOpPrec != opPrec))
- break;
- else if( nextOpPrec <= opPrec)
+ if((GetAssociativityFromLevel(nextOpPrec) == Associativity::Right) ? (nextOpPrec < opPrec) : (nextOpPrec <= opPrec))
break;
right = parseInfixExprWithPrecedence(parser, right, nextOpPrec);
@@ -3206,6 +3204,33 @@ namespace Slang
return constExpr;
}
+ case TokenType::StringLiterial:
+ {
+ RefPtr<ConstantExpressionSyntaxNode> constExpr = new ConstantExpressionSyntaxNode();
+ auto token = parser->tokenReader.AdvanceToken();
+ parser->FillPosition(constExpr.Ptr());
+ constExpr->ConstType = ConstantExpressionSyntaxNode::ConstantType::String;
+
+ if (!parser->LookAheadToken(TokenType::StringLiterial))
+ {
+ // Easy/common case: a single string
+ constExpr->stringValue = getStringLiteralTokenValue(token);
+ }
+ else
+ {
+ StringBuilder sb;
+ sb << getStringLiteralTokenValue(token);
+ while (parser->LookAheadToken(TokenType::StringLiterial))
+ {
+ token = parser->tokenReader.AdvanceToken();
+ sb << getStringLiteralTokenValue(token);
+ }
+ constExpr->stringValue = sb.ProduceString();
+ }
+
+ return constExpr;
+ }
+
case TokenType::Identifier:
{
// TODO(tfoley): Need a name-lookup step here to resolve
diff --git a/source/slang/syntax.h b/source/slang/syntax.h
index 5eb62462e..7a1701b88 100644
--- a/source/slang/syntax.h
+++ b/source/slang/syntax.h
@@ -1917,7 +1917,10 @@ namespace Slang
public:
enum class ConstantType
{
- Int, Bool, Float
+ Int,
+ Bool,
+ Float,
+ String,
};
ConstantType ConstType;
union
@@ -1925,6 +1928,7 @@ namespace Slang
int IntValue;
FloatingPointLiteralValue FloatValue;
};
+ String stringValue;
virtual RefPtr<SyntaxNode> Accept(SyntaxVisitor * visitor) override;
};
diff --git a/tests/hlsl/dxsdk/SimpleBezier11/SimpleBezier11.hlsl b/tests/hlsl/dxsdk/SimpleBezier11/SimpleBezier11.hlsl
index 7b7a1489c..5558449d2 100644
--- a/tests/hlsl/dxsdk/SimpleBezier11/SimpleBezier11.hlsl
+++ b/tests/hlsl/dxsdk/SimpleBezier11/SimpleBezier11.hlsl
@@ -1,4 +1,3 @@
-//TEST_IGNORE_FILE: Currently failing due to Spire compiler issues.
//TEST:COMPARE_HLSL: -target dxbc-assembly -profile vs_4_0 -entry BezierVS -profile hs_5_0 -entry BezierHS -profile ds_5_0 -entry BezierDS -profile ps_4_0 -entry BezierPS -entry SolidColorPS
//--------------------------------------------------------------------------------------
// File: SimpleBezier11.hlsl