summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/slang/check.cpp419
-rw-r--r--source/slang/emit.cpp166
-rw-r--r--source/slang/expr-defs.h10
-rw-r--r--source/slang/intrinsic-defs.h1
-rw-r--r--source/slang/lexer.cpp6
-rw-r--r--source/slang/lower.cpp11
-rw-r--r--source/slang/parser.cpp185
-rw-r--r--source/slang/slang-stdlib.cpp356
-rw-r--r--source/slang/slang-stdlib.h13
-rw-r--r--source/slang/slang.cpp17
-rw-r--r--source/slang/stmt-defs.h5
-rw-r--r--source/slang/syntax.h17
12 files changed, 647 insertions, 559 deletions
diff --git a/source/slang/check.cpp b/source/slang/check.cpp
index 7c67473be..f21f9480c 100644
--- a/source/slang/check.cpp
+++ b/source/slang/check.cpp
@@ -243,14 +243,16 @@ namespace Slang
if (lookupResult.isOverloaded())
{
// We had an ambiguity anyway, so report it.
- getSink()->diagnose(overloadedExpr, Diagnostics::ambiguousReference, lookupResult.items[0].declRef.GetName());
-
- for(auto item : lookupResult.items)
+ if (!isRewriteMode())
{
- String declString = getDeclSignatureString(item);
- getSink()->diagnose(item.declRef, Diagnostics::overloadCandidate, declString);
- }
+ getSink()->diagnose(overloadedExpr, Diagnostics::ambiguousReference, lookupResult.items[0].declRef.GetName());
+ for(auto item : lookupResult.items)
+ {
+ String declString = getDeclSignatureString(item);
+ getSink()->diagnose(item.declRef, Diagnostics::overloadCandidate, declString);
+ }
+ }
// TODO(tfoley): should we construct a new ErrorExpr here?
overloadedExpr->Type = QualType(ExpressionType::Error);
return overloadedExpr;
@@ -276,9 +278,11 @@ namespace Slang
return expr;
}
- getSink()->diagnose(expr, Diagnostics::unimplemented, "expected a type");
- // TODO: construct some kind of `ErrorExpr`?
- return expr;
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(expr, Diagnostics::unimplemented, "expected a type");
+ }
+ return CreateErrorExpr(expr);
}
RefPtr<ExpressionType> ExpectAType(RefPtr<ExpressionSyntaxNode> expr)
@@ -424,7 +428,10 @@ namespace Slang
{
if (outProperType)
{
- getSink()->diagnose(typeExp.exp.Ptr(), Diagnostics::unimplemented, "can't fill in default for generic type parameter");
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(typeExp.exp.Ptr(), Diagnostics::unimplemented, "can't fill in default for generic type parameter");
+ }
*outProperType = ExpressionType::Error;
}
return false;
@@ -440,7 +447,10 @@ namespace Slang
{
if (outProperType)
{
- getSink()->diagnose(typeExp.exp.Ptr(), Diagnostics::unimplemented, "can't fill in default for generic type parameter");
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(typeExp.exp.Ptr(), Diagnostics::unimplemented, "can't fill in default for generic type parameter");
+ }
*outProperType = ExpressionType::Error;
}
return false;
@@ -511,7 +521,10 @@ namespace Slang
if (basicType->BaseType == BaseType::Void)
{
// TODO(tfoley): pick the right diagnostic message
- getSink()->diagnose(result.exp.Ptr(), Diagnostics::invalidTypeVoid);
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(result.exp.Ptr(), Diagnostics::invalidTypeVoid);
+ }
result.type = ExpressionType::Error;
return result;
}
@@ -634,7 +647,9 @@ namespace Slang
CASE(Int, Signed, Int32);
CASE(UInt, Unsigned, Int32);
CASE(UInt64, Unsigned, Int64);
+ CASE(Half, Float, Int16);
CASE(Float, Float, Int32);
+ CASE(Double, Float, Int64);
CASE(Void, Error, Error);
#undef CASE
@@ -972,7 +987,7 @@ namespace Slang
RefPtr<ExpressionType> toType,
RefPtr<ExpressionSyntaxNode> fromExpr)
{
- auto castExpr = new TypeCastExpressionSyntaxNode();
+ auto castExpr = new ImplicitCastExpr();
castExpr->Position = fromExpr->Position;
castExpr->TargetType.type = toType;
castExpr->Type = QualType(toType);
@@ -980,6 +995,10 @@ namespace Slang
return castExpr;
}
+ bool isRewriteMode()
+ {
+ return (getTranslationUnit()->compileFlags & SLANG_COMPILE_FLAG_NO_CHECKING) != 0;
+ }
// Perform type coercion, and emit errors if it isn't possible
RefPtr<ExpressionSyntaxNode> Coerce(
@@ -990,7 +1009,7 @@ namespace Slang
// expressions without a type, and we need to ignore them.
if( !fromExpr->Type.type )
{
- if(getTranslationUnit()->compileFlags & SLANG_COMPILE_FLAG_NO_CHECKING )
+ if(isRewriteMode())
return fromExpr;
}
@@ -1002,7 +1021,7 @@ namespace Slang
fromExpr.Ptr(),
nullptr))
{
- if(!(getTranslationUnit()->compileFlags & SLANG_COMPILE_FLAG_NO_CHECKING))
+ if(!isRewriteMode())
{
getSink()->diagnose(fromExpr->Position, Diagnostics::typeMismatch, toType, fromExpr->Type);
}
@@ -1041,13 +1060,20 @@ namespace Slang
else
{
// TODO: infer a type from the initializers
+
if (!initExpr)
{
- getSink()->diagnose(varDecl, Diagnostics::unimplemented, "variable declaration with no type must have initializer");
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(varDecl, Diagnostics::unimplemented, "variable declaration with no type must have initializer");
+ }
}
else
{
- getSink()->diagnose(varDecl, Diagnostics::unimplemented, "type inference for variable declaration");
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(varDecl, Diagnostics::unimplemented, "type inference for variable declaration");
+ }
}
}
@@ -1122,7 +1148,10 @@ namespace Slang
// If type expression didn't name an interface, we'll emit an error here
// TODO: deal with the case of an error in the type expression (don't cascade)
- getSink()->diagnose( base.exp, Diagnostics::expectedAnInterfaceGot, base.type);
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose( base.exp, Diagnostics::expectedAnInterfaceGot, base.type);
+ }
}
RefPtr<ConstantIntVal> checkConstantIntVal(
@@ -1138,7 +1167,10 @@ namespace Slang
auto constIntVal = intVal.As<ConstantIntVal>();
if(!constIntVal)
{
- getSink()->diagnose(expr->Position, Diagnostics::expectedIntegerConstantNotLiteral);
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(expr->Position, Diagnostics::expectedIntegerConstantNotLiteral);
+ }
return nullptr;
}
return constIntVal;
@@ -1503,7 +1535,10 @@ namespace Slang
if (!funcDecl->ReturnType.Equals(prevFuncDecl->ReturnType))
{
// Bad dedeclaration
- getSink()->diagnose(funcDecl, Diagnostics::unimplemented, "redeclaration has a different return type");
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(funcDecl, Diagnostics::unimplemented, "redeclaration has a different return type");
+ }
// Don't bother emitting other errors at this point
break;
@@ -1517,7 +1552,10 @@ namespace Slang
if (funcDecl->Body && prevFuncDecl->Body)
{
// Redefinition
- getSink()->diagnose(funcDecl, Diagnostics::unimplemented, "function redefinition");
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(funcDecl, Diagnostics::unimplemented, "function redefinition");
+ }
// Don't bother emitting other errors
break;
@@ -1539,7 +1577,12 @@ namespace Slang
para->Type = CheckUsableType(para->Type);
if (para->Type.Equals(ExpressionType::GetVoid()))
- getSink()->diagnose(para, Diagnostics::parameterCannotBeVoid);
+ {
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(para, Diagnostics::parameterCannotBeVoid);
+ }
+ }
}
void VisitFunctionDeclaration(FunctionSyntaxNode *functionNode)
@@ -1556,7 +1599,12 @@ namespace Slang
checkDecl(para);
if (paraNames.Contains(para->Name.Content))
- getSink()->diagnose(para, Diagnostics::parameterAlreadyDefined, para->Name);
+ {
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(para, Diagnostics::parameterAlreadyDefined, para->Name);
+ }
+ }
else
paraNames.Add(para->Name.Content);
}
@@ -1613,7 +1661,10 @@ namespace Slang
auto outer = FindOuterStmt<BreakableStmt>();
if (!outer)
{
- getSink()->diagnose(stmt, Diagnostics::breakOutsideLoop);
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(stmt, Diagnostics::breakOutsideLoop);
+ }
}
stmt->parentStmt = outer;
}
@@ -1622,7 +1673,10 @@ namespace Slang
auto outer = FindOuterStmt<LoopStmt>();
if (!outer)
{
- getSink()->diagnose(stmt, Diagnostics::continueOutsideLoop);
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(stmt, Diagnostics::continueOutsideLoop);
+ }
}
stmt->parentStmt = outer;
}
@@ -1691,7 +1745,10 @@ namespace Slang
if (!switchStmt)
{
- getSink()->diagnose(stmt, Diagnostics::caseOutsideSwitch);
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(stmt, Diagnostics::caseOutsideSwitch);
+ }
}
else
{
@@ -1707,7 +1764,10 @@ namespace Slang
auto switchStmt = FindOuterStmt<SwitchStmt>();
if (!switchStmt)
{
- getSink()->diagnose(stmt, Diagnostics::defaultOutsideSwitch);
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(stmt, Diagnostics::defaultOutsideSwitch);
+ }
}
stmt->parentStmt = switchStmt;
}
@@ -1718,12 +1778,6 @@ namespace Slang
checkStmt(stmt->NegativeStatement);
}
- void visitUnparsedStmt(UnparsedStmt*)
- {
- // Nothing to do
- }
-
-
void visitEmptyStatementSyntaxNode(EmptyStatementSyntaxNode*)
{
// Nothing to do
@@ -1739,7 +1793,12 @@ namespace Slang
if (!stmt->Expression)
{
if (function && !function->ReturnType.Equals(ExpressionType::GetVoid()))
- getSink()->diagnose(stmt, Diagnostics::returnNeedsExpression);
+ {
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(stmt, Diagnostics::returnNeedsExpression);
+ }
+ }
}
else
{
@@ -1832,7 +1891,10 @@ namespace Slang
// TODO(tfoley): How to handle the case where bound isn't known?
if (GetMinBound(elementCount) <= 0)
{
- getSink()->diagnose(varDecl, Diagnostics::invalidArraySize);
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(varDecl, Diagnostics::invalidArraySize);
+ }
return;
}
}
@@ -1853,7 +1915,12 @@ namespace Slang
#endif
varDecl->Type = typeExp;
if (varDecl->Type.Equals(ExpressionType::GetVoid()))
- getSink()->diagnose(varDecl, Diagnostics::invalidTypeVoid);
+ {
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(varDecl, Diagnostics::invalidTypeVoid);
+ }
+ }
if(auto initExpr = varDecl->Expr)
{
@@ -2160,7 +2227,10 @@ namespace Slang
auto result = TryCheckIntegerConstantExpression(expr.Ptr());
if (!result)
{
- getSink()->diagnose(expr, Diagnostics::expectedIntegerConstantNotConstant);
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(expr, Diagnostics::expectedIntegerConstantNotConstant);
+ }
}
return result;
}
@@ -2177,7 +2247,10 @@ namespace Slang
if (!indexExpr->Type->Equals(ExpressionType::GetInt()) &&
!indexExpr->Type->Equals(ExpressionType::GetUInt()))
{
- getSink()->diagnose(indexExpr, Diagnostics::subscriptIndexNonInteger);
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(indexExpr, Diagnostics::subscriptIndexNonInteger);
+ }
return CreateErrorExpr(subscriptExpr.Ptr());
}
@@ -2320,7 +2393,10 @@ namespace Slang
fail:
{
- getSink()->diagnose(subscriptExpr, Diagnostics::subscriptNonArray, baseType);
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(subscriptExpr, Diagnostics::subscriptNonArray, baseType);
+ }
return CreateErrorExpr(subscriptExpr);
}
}
@@ -2419,6 +2495,16 @@ namespace Slang
return appExpr;
}
+ RefPtr<ExpressionSyntaxNode> visitParenExpr(ParenExpr* expr)
+ {
+ auto base = expr->base;
+ base = CheckTerm(base);
+
+ expr->base = base;
+ expr->Type = base->Type;
+ return expr;
+ }
+
//
RefPtr<ExpressionSyntaxNode> visitAssignExpr(AssignExpr* expr)
@@ -2431,7 +2517,10 @@ namespace Slang
if (!type.IsLeftValue)
{
- getSink()->diagnose(expr, Diagnostics::assignNonLValue);
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(expr, Diagnostics::assignNonLValue);
+ }
}
expr->Type = type;
return expr;
@@ -2460,7 +2549,10 @@ namespace Slang
}
else
{
- getSink()->diagnose(decl->targetType.exp, Diagnostics::unimplemented, "expected a nominal type here");
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(decl->targetType.exp, Diagnostics::unimplemented, "expected a nominal type here");
+ }
}
}
else if (decl->targetType->Equals(ExpressionType::Error))
@@ -2469,7 +2561,10 @@ namespace Slang
}
else
{
- getSink()->diagnose(decl->targetType.exp, Diagnostics::unimplemented, "expected a nominal type here");
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(decl->targetType.exp, Diagnostics::unimplemented, "expected a nominal type here");
+ }
}
decl->SetCheckState(DeclCheckState::CheckedHeader);
@@ -3073,12 +3168,18 @@ namespace Slang
{
if (argCount < paramCounts.required)
{
- getSink()->diagnose(context.appExpr, Diagnostics::notEnoughArguments, argCount, paramCounts.required);
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(context.appExpr, Diagnostics::notEnoughArguments, argCount, paramCounts.required);
+ }
}
else
{
assert(argCount > paramCounts.allowed);
- getSink()->diagnose(context.appExpr, Diagnostics::tooManyArguments, argCount, paramCounts.allowed);
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(context.appExpr, Diagnostics::tooManyArguments, argCount, paramCounts.allowed);
+ }
}
}
@@ -3100,8 +3201,11 @@ namespace Slang
if (context.mode != OverloadResolveContext::Mode::JustTrying)
{
- getSink()->diagnose(context.appExpr, Diagnostics::expectedPrefixOperator);
- getSink()->diagnose(decl, Diagnostics::seeDefinitionOf, decl->getName());
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(context.appExpr, Diagnostics::expectedPrefixOperator);
+ getSink()->diagnose(decl, Diagnostics::seeDefinitionOf, decl->getName());
+ }
}
return false;
@@ -3113,8 +3217,11 @@ namespace Slang
if (context.mode != OverloadResolveContext::Mode::JustTrying)
{
- getSink()->diagnose(context.appExpr, Diagnostics::expectedPostfixOperator);
- getSink()->diagnose(decl, Diagnostics::seeDefinitionOf, decl->getName());
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(context.appExpr, Diagnostics::expectedPostfixOperator);
+ getSink()->diagnose(decl, Diagnostics::seeDefinitionOf, decl->getName());
+ }
}
return false;
@@ -3311,13 +3418,16 @@ namespace Slang
if (candidate.status == OverloadCandidate::Status::GenericArgumentInferenceFailed)
{
String callString = GetCallSignatureString(context.appExpr);
- getSink()->diagnose(
- context.appExpr,
- Diagnostics::genericArgumentInferenceFailed,
- callString);
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(
+ context.appExpr,
+ Diagnostics::genericArgumentInferenceFailed,
+ callString);
- String declString = getDeclSignatureString(candidate.item);
- getSink()->diagnose(candidate.item.declRef, Diagnostics::genericSignatureTried, declString);
+ String declString = getDeclSignatureString(candidate.item);
+ getSink()->diagnose(candidate.item.declRef, Diagnostics::genericSignatureTried, declString);
+ }
goto error;
}
@@ -4223,6 +4333,14 @@ namespace Slang
{
return CreateErrorExpr(expr);
}
+ // If any of the arguments is an error, then we should bail out, to avoid
+ // cascading errors where we successfully pick an overload, but not the one
+ // the user meant.
+ for (auto arg : expr->Arguments)
+ {
+ if (IsErrorExpr(arg))
+ return CreateErrorExpr(expr);
+ }
OverloadResolveContext context;
context.appExpr = expr;
@@ -4268,11 +4386,17 @@ namespace Slang
// We will construct a diagnostic message to help out.
if (funcName.Length() != 0)
{
- getSink()->diagnose(expr, Diagnostics::noApplicableOverloadForNameWithArgs, funcName, argsList);
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(expr, Diagnostics::noApplicableOverloadForNameWithArgs, funcName, argsList);
+ }
}
else
{
- getSink()->diagnose(expr, Diagnostics::noApplicableWithArgs, argsList);
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(expr, Diagnostics::noApplicableWithArgs, argsList);
+ }
}
}
else
@@ -4281,32 +4405,41 @@ namespace Slang
if (funcName.Length() != 0)
{
- getSink()->diagnose(expr, Diagnostics::ambiguousOverloadForNameWithArgs, funcName, argsList);
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(expr, Diagnostics::ambiguousOverloadForNameWithArgs, funcName, argsList);
+ }
}
else
{
- getSink()->diagnose(expr, Diagnostics::ambiguousOverloadWithArgs, argsList);
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(expr, Diagnostics::ambiguousOverloadWithArgs, argsList);
+ }
}
}
- UInt candidateCount = context.bestCandidates.Count();
- UInt maxCandidatesToPrint = 10; // don't show too many candidates at once...
- UInt candidateIndex = 0;
- for (auto candidate : context.bestCandidates)
+ if (!isRewriteMode())
{
- String declString = getDeclSignatureString(candidate.item);
+ UInt candidateCount = context.bestCandidates.Count();
+ UInt maxCandidatesToPrint = 10; // don't show too many candidates at once...
+ UInt candidateIndex = 0;
+ for (auto candidate : context.bestCandidates)
+ {
+ String declString = getDeclSignatureString(candidate.item);
- declString = declString + "[" + String(candidate.conversionCostSum) + "]";
+ declString = declString + "[" + String(candidate.conversionCostSum) + "]";
- getSink()->diagnose(candidate.item.declRef, Diagnostics::overloadCandidate, declString);
+ getSink()->diagnose(candidate.item.declRef, Diagnostics::overloadCandidate, declString);
- candidateIndex++;
- if (candidateIndex == maxCandidatesToPrint)
- break;
- }
- if (candidateIndex != candidateCount)
- {
- getSink()->diagnose(expr, Diagnostics::moreOverloadCandidates, candidateCount - candidateIndex);
+ candidateIndex++;
+ if (candidateIndex == maxCandidatesToPrint)
+ break;
+ }
+ if (candidateIndex != candidateCount)
+ {
+ getSink()->diagnose(expr, Diagnostics::moreOverloadCandidates, candidateCount - candidateIndex);
+ }
}
return CreateErrorExpr(expr);
@@ -4322,7 +4455,10 @@ namespace Slang
else
{
// Nothing at all was found that we could even consider invoking
- getSink()->diagnose(expr->FunctionExpr, Diagnostics::expectedFunction);
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(expr->FunctionExpr, Diagnostics::expectedFunction);
+ }
expr->Type = QualType(ExpressionType::Error);
return expr;
}
@@ -4417,7 +4553,10 @@ namespace Slang
// TODO(tfoley): print a reasonable message here...
- getSink()->diagnose(genericAppExpr, Diagnostics::unimplemented, "no applicable generic");
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(genericAppExpr, Diagnostics::unimplemented, "no applicable generic");
+ }
return CreateErrorExpr(genericAppExpr);
}
@@ -4448,76 +4587,12 @@ namespace Slang
else
{
// Nothing at all was found that we could even consider invoking
- getSink()->diagnose(genericAppExpr, Diagnostics::unimplemented, "expected a generic");
- return CreateErrorExpr(genericAppExpr);
- }
-
-
-#if TIMREMOVED
-
- if (IsErrorExpr(base))
- {
- return CreateErrorExpr(typeNode);
- }
- else if(auto baseDeclRefExpr = base.As<DeclRefExpr>())
- {
- auto declRef = baseDeclRefExpr->declRef;
-
- if (auto genericDeclRef = declRef.As<GenericDecl>())
+ if (!isRewriteMode())
{
- int argCount = typeNode->Args.Count();
- int argIndex = 0;
- for (RefPtr<Decl> member : genericDeclRef.getDecl()->Members)
- {
- if (auto typeParam = member.As<GenericTypeParamDecl>())
- {
- if (argIndex == argCount)
- {
- // Too few arguments!
-
- }
-
- // TODO: checking!
- }
- else if (auto valParam = member.As<GenericValueParamDecl>())
- {
- // TODO: checking
- }
- else
- {
-
- }
- }
- if (argIndex != argCount)
- {
- // Too many arguments!
- }
-
- // Now instantiate the declaration given those arguments
- auto type = InstantiateGenericType(genericDeclRef, args);
- typeResult = type;
- typeNode->Type = new TypeExpressionType(type);
- return typeNode;
- }
- }
- else if (auto overloadedExpr = base.As<OverloadedExpr>())
- {
- // We are referring to a bunch of declarations, each of which might be generic
- LookupResult result;
- for (auto item : overloadedExpr->lookupResult2.items)
- {
- auto applied = TryApplyGeneric(item, typeNode);
- if (!applied)
- continue;
-
- AddToLookupResult(result, appliedItem);
+ getSink()->diagnose(genericAppExpr, Diagnostics::unimplemented, "expected a generic");
}
+ return CreateErrorExpr(genericAppExpr);
}
-
- // TODO: correct diagnostic here!
- getSink()->diagnose(typeNode, Diagnostics::expectedAGeneric, base->Type);
- return CreateErrorExpr(typeNode);
-#endif
}
RefPtr<ExpressionSyntaxNode> visitSharedTypeExpr(SharedTypeExpr* expr)
@@ -4568,7 +4643,10 @@ namespace Slang
if (i < expr->Arguments.Count() && expr->Arguments[i]->Type->AsBasicType() &&
!expr->Arguments[i]->Type.IsLeftValue)
{
- getSink()->diagnose(expr->Arguments[i], Diagnostics::argumentExpectedLValue, (*params)[i]->Name);
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(expr->Arguments[i], Diagnostics::argumentExpectedLValue, (*params)[i]->Name);
+ }
}
}
}
@@ -4610,7 +4688,10 @@ namespace Slang
expr);
}
- getSink()->diagnose(expr, Diagnostics::undefinedIdentifier2, expr->name);
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(expr, Diagnostics::undefinedIdentifier2, expr->name);
+ }
return expr;
}
@@ -4651,32 +4732,13 @@ namespace Slang
fail:
// Default: in no other case succeds, then the cast failed and we emit a diagnostic.
- getSink()->diagnose(expr, Diagnostics::invalidTypeCast, expr->Expression->Type, targetType->ToString());
- expr->Type = QualType(ExpressionType::Error);
- return expr;
- }
-#if TIMREMOVED
- virtual RefPtr<ExpressionSyntaxNode> VisitSelectExpression(SelectExpressionSyntaxNode * expr) override
- {
- auto selectorExpr = expr->SelectorExpr;
- selectorExpr = CheckExpr(selectorExpr);
- selectorExpr = Coerce(ExpressionType::GetBool(), selectorExpr);
- expr->SelectorExpr = selectorExpr;
-
- // TODO(tfoley): We need a general purpose "join" on types for inferring
- // generic argument types for builtins/intrinsics, so this should really
- // be using the exact same logic...
- //
- expr->Expr0 = expr->Expr0->Accept(this).As<ExpressionSyntaxNode>();
- expr->Expr1 = expr->Expr1->Accept(this).As<ExpressionSyntaxNode>();
- if (!expr->Expr0->Type->Equals(expr->Expr1->Type.Ptr()))
+ if (!isRewriteMode())
{
- getSink()->diagnose(expr, Diagnostics::selectValuesTypeMismatch);
+ getSink()->diagnose(expr, Diagnostics::invalidTypeCast, expr->Expression->Type, targetType->ToString());
}
- expr->Type = expr->Expr0->Type;
+ expr->Type = QualType(ExpressionType::Error);
return expr;
}
-#endif
// Get the type to use when referencing a declaration
QualType GetTypeForDeclRef(DeclRef<Decl> declRef)
@@ -4771,7 +4833,10 @@ namespace Slang
case 'w': case 'a': elementIndex = 3; break;
default:
// An invalid character in the swizzle is an error
- getSink()->diagnose(swizExpr, Diagnostics::unimplemented, "invalid component name for swizzle");
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(swizExpr, Diagnostics::unimplemented, "invalid component name for swizzle");
+ }
anyError = true;
continue;
}
@@ -4782,7 +4847,10 @@ namespace Slang
// Make sure the index is in range for the source type
if (elementIndex >= limitElement)
{
- getSink()->diagnose(swizExpr, Diagnostics::unimplemented, "swizzle component out of range for type");
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(swizExpr, Diagnostics::unimplemented, "swizzle component out of range for type");
+ }
anyError = true;
continue;
}
@@ -4806,7 +4874,7 @@ namespace Slang
if (anyError)
{
- swizExpr->Type = QualType(ExpressionType::Error);
+ return CreateErrorExpr(memberRefExpr);
}
else if (elementCount == 1)
{
@@ -4844,7 +4912,10 @@ namespace Slang
}
else
{
- getSink()->diagnose(memberRefExpr, Diagnostics::unimplemented, "swizzle on vector of unknown size");
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(memberRefExpr, Diagnostics::unimplemented, "swizzle on vector of unknown size");
+ }
return CreateErrorExpr(memberRefExpr);
}
}
@@ -4928,7 +4999,10 @@ namespace Slang
// catch-all
fail:
- getSink()->diagnose(expr, Diagnostics::noMemberOfNameInType, expr->name, baseType);
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(expr, Diagnostics::noMemberOfNameInType, expr->name, baseType);
+ }
expr->Type = QualType(ExpressionType::Error);
return expr;
}
@@ -4940,7 +5014,10 @@ namespace Slang
if (!baseType->Equals(ExpressionType::Error.Ptr()) &&
expr->Type->Equals(ExpressionType::Error.Ptr()))
{
- getSink()->diagnose(expr, Diagnostics::typeHasNoPublicMemberOfName, baseType, expr->name);
+ if (!isRewriteMode())
+ {
+ getSink()->diagnose(expr, Diagnostics::typeHasNoPublicMemberOfName, baseType, expr->name);
+ }
}
return expr;
}
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index df74d19e4..830ff6d97 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -238,7 +238,9 @@ struct EmitVisitor
if (isReservedWord(name))
{
- name = name + "_";
+ // TODO(tfoley): Need to put this back in, as part of lowering.
+
+// name = name + "_";
}
advanceToSourceLocation(loc);
@@ -970,6 +972,14 @@ struct EmitVisitor
{
e = derefExpr->base;
}
+
+ if (auto declRefExpr = e.As<DeclRefExpr>())
+ {
+ auto decl = declRefExpr->declRef.getDecl();
+ if (decl && decl->HasModifier<TransparentModifier>())
+ return true;
+ }
+
// Is the expression referencing a constant buffer?
if (auto cbufferType = e->Type->As<ConstantBufferType>())
{
@@ -1308,6 +1318,13 @@ struct EmitVisitor
if(needClose) Emit(")");
}
+ void visitParenExpr(ParenExpr* expr, ExprEmitArg const& arg)
+ {
+ Emit("(");
+ EmitExpr(expr->base);
+ Emit(")");
+ }
+
void visitAssignExpr(AssignExpr* assignExpr, ExprEmitArg const& arg)
{
auto outerPrec = arg.outerPrec;
@@ -1318,6 +1335,64 @@ struct EmitVisitor
if(needClose) Emit(")");
}
+ void emitUncheckedCallExpr(
+ RefPtr<InvokeExpressionSyntaxNode> callExpr,
+ String const& funcName,
+ ExprEmitArg const& arg)
+ {
+ auto outerPrec = arg.outerPrec;
+ auto funcExpr = callExpr->FunctionExpr;
+
+ // This can occur when we are dealing with unchecked input syntax,
+ // because we are in "rewriter" mode. In this case we should go
+ // ahead and emit things in the form that they were written.
+ if( auto infixExpr = callExpr.As<InfixExpr>() )
+ {
+ EmitBinExpr(
+ outerPrec,
+ kPrecedence_Comma,
+ funcName.Buffer(),
+ callExpr);
+ }
+ else if( auto prefixExpr = callExpr.As<PrefixExpr>() )
+ {
+ EmitUnaryExpr(
+ outerPrec,
+ kPrecedence_Prefix,
+ funcName.Buffer(),
+ "",
+ callExpr);
+ }
+ else if(auto postfixExpr = callExpr.As<PostfixExpr>())
+ {
+ EmitUnaryExpr(
+ outerPrec,
+ kPrecedence_Postfix,
+ "",
+ funcName.Buffer(),
+ callExpr);
+ }
+ else
+ {
+ bool needClose = MaybeEmitParens(outerPrec, kPrecedence_Postfix);
+
+ auto funcExpr = callExpr->FunctionExpr;
+ EmitExpr(funcExpr);
+
+ Emit("(");
+ UInt argCount = callExpr->Arguments.Count();
+ for (UInt aa = 0; aa < argCount; ++aa)
+ {
+ if (aa != 0) Emit(", ");
+ EmitExpr(callExpr->Arguments[aa]);
+ }
+ Emit(")");
+
+ if (needClose) Emit(")");
+ }
+ }
+
+
void visitInvokeExpressionSyntaxNode(
RefPtr<InvokeExpressionSyntaxNode> callExpr,
ExprEmitArg const& arg)
@@ -1331,39 +1406,7 @@ struct EmitVisitor
auto funcDecl = funcDeclRef.getDecl();
if(!funcDecl)
{
- // This can occur when we are dealing with unchecked input syntax,
- // because we are in "rewriter" mode. In this case we should go
- // ahead and emit things in the form that they were written.
- if( auto infixExpr = callExpr.As<InfixExpr>() )
- {
- EmitBinExpr(
- outerPrec,
- kPrecedence_Comma,
- funcDeclRefExpr->name.Buffer(),
- callExpr);
- }
- else if( auto prefixExpr = callExpr.As<PrefixExpr>() )
- {
- EmitUnaryExpr(
- outerPrec,
- kPrecedence_Prefix,
- funcDeclRefExpr->name.Buffer(),
- "",
- callExpr);
- }
- else if(auto postfixExpr = callExpr.As<PostfixExpr>())
- {
- EmitUnaryExpr(
- outerPrec,
- kPrecedence_Postfix,
- "",
- funcDeclRefExpr->name.Buffer(),
- callExpr);
- }
- else
- {
- emitSimpleCallExpr(callExpr, outerPrec);
- }
+ emitUncheckedCallExpr(callExpr, funcDeclRef.GetName(), arg);
return;
}
else if (auto intrinsicOpModifier = funcDecl->FindModifier<IntrinsicOpModifier>())
@@ -1408,6 +1451,7 @@ struct EmitVisitor
case IntrinsicOp::Sequence: EmitBinExpr(outerPrec, kPrecedence_Comma, ",", callExpr); return;
#define CASE(NAME, OP) case IntrinsicOp::NAME: EmitUnaryExpr(outerPrec, kPrecedence_Prefix, #OP, "", callExpr); return
+ CASE(Pos, +);
CASE(Neg, -);
CASE(Not, !);
CASE(BitNot, ~);
@@ -1603,6 +1647,11 @@ struct EmitVisitor
}
}
}
+ else if (auto overloadedExpr = funcExpr.As<OverloadedExpr>())
+ {
+ emitUncheckedCallExpr(callExpr, overloadedExpr->lookupResult2.getName(), arg);
+ return;
+ }
// Fall through to default handling...
emitSimpleCallExpr(callExpr, outerPrec);
@@ -1633,7 +1682,16 @@ struct EmitVisitor
Emit(".");
}
- emitName(memberExpr->declRef.GetName());
+ if (!memberExpr->declRef)
+ {
+ // This case arises when checking didn't find anything, but we were
+ // in "rewrite" mode so we blazed ahead anyway.
+ emitName(memberExpr->name);
+ }
+ else
+ {
+ emit(memberExpr->declRef.GetName());
+ }
if(needClose) Emit(")");
}
@@ -1655,14 +1713,17 @@ struct EmitVisitor
if(needClose) Emit(")");
}
- void visitIndexExpressionSyntaxNode(IndexExpressionSyntaxNode* indexExpr, ExprEmitArg const& arg)
+ void visitIndexExpressionSyntaxNode(IndexExpressionSyntaxNode* subscriptExpr, ExprEmitArg const& arg)
{
auto outerPrec = arg.outerPrec;
bool needClose = MaybeEmitParens(outerPrec, kPrecedence_Postfix);
- EmitExprWithPrecedence(indexExpr->BaseExpression, kPrecedence_Postfix);
+ EmitExprWithPrecedence(subscriptExpr->BaseExpression, kPrecedence_Postfix);
Emit("[");
- EmitExpr(indexExpr->IndexExpression);
+ if (auto indexExpr = subscriptExpr->IndexExpression)
+ {
+ EmitExpr(indexExpr);
+ }
Emit("]");
if(needClose) Emit(")");
@@ -1696,7 +1757,7 @@ struct EmitVisitor
}
else
{
- emitName(varExpr->name);
+ emit(varExpr->name);
}
if(needClose) Emit(")");
@@ -1777,6 +1838,16 @@ struct EmitVisitor
void visitTypeCastExpressionSyntaxNode(TypeCastExpressionSyntaxNode* castExpr, ExprEmitArg const& arg)
{
+ if (context->isRewrite)
+ {
+ if (dynamic_cast<ImplicitCastExpr*>(castExpr))
+ {
+ // This was an implicit cast, so don't try to output it
+ EmitExprWithPrecedence(castExpr->Expression, arg.outerPrec);
+ return;
+ }
+ }
+
bool needClose = false;
switch(context->shared->target)
{
@@ -1858,18 +1929,6 @@ struct EmitVisitor
}
}
-
- void EmitUnparsedStmt(RefPtr<UnparsedStmt> stmt)
- {
- // TODO: actually emit the tokens that made up the statement...
- Emit("{\n");
- for( auto& token : stmt->tokens )
- {
- emitTokenWithLocation(token);
- }
- Emit("}\n");
- }
-
void EmitStmt(RefPtr<StatementSyntaxNode> stmt)
{
// Try to ensure that debugging can find the right location
@@ -1888,11 +1947,6 @@ struct EmitVisitor
}
return;
}
- else if( auto unparsedStmt = stmt.As<UnparsedStmt>() )
- {
- EmitUnparsedStmt(unparsedStmt);
- return;
- }
else if (auto exprStmt = stmt.As<ExpressionStatementSyntaxNode>())
{
EmitExpr(exprStmt->Expression);
diff --git a/source/slang/expr-defs.h b/source/slang/expr-defs.h
index ca5bfacb8..5ca6629b9 100644
--- a/source/slang/expr-defs.h
+++ b/source/slang/expr-defs.h
@@ -96,6 +96,9 @@ SYNTAX_CLASS(TypeCastExpressionSyntaxNode, ExpressionSyntaxNode)
SYNTAX_FIELD(RefPtr<ExpressionSyntaxNode>, Expression)
END_SYNTAX_CLASS()
+SYNTAX_CLASS(ImplicitCastExpr, TypeCastExpressionSyntaxNode)
+END_SYNTAX_CLASS()
+
SIMPLE_SYNTAX_CLASS(SelectExpressionSyntaxNode, OperatorExpressionSyntaxNode)
SIMPLE_SYNTAX_CLASS(GenericAppExpr, AppExprBase)
@@ -112,3 +115,10 @@ SYNTAX_CLASS(AssignExpr, ExpressionSyntaxNode)
SYNTAX_FIELD(RefPtr<ExpressionSyntaxNode>, right);
END_SYNTAX_CLASS()
+// Just an expression inside parentheses `(exp)`
+//
+// We keep this around explicitly to be sure we don't lose any structure
+// when we do rewriter stuff.
+SYNTAX_CLASS(ParenExpr, ExpressionSyntaxNode)
+ SYNTAX_FIELD(RefPtr<ExpressionSyntaxNode>, base);
+END_SYNTAX_CLASS()
diff --git a/source/slang/intrinsic-defs.h b/source/slang/intrinsic-defs.h
index 19a3899a3..a272bd51c 100644
--- a/source/slang/intrinsic-defs.h
+++ b/source/slang/intrinsic-defs.h
@@ -46,6 +46,7 @@ INTRINSIC(RshAssign)
INTRINSIC(OrAssign)
INTRINSIC(AndAssign)
INTRINSIC(XorAssign)
+INTRINSIC(Pos)
INTRINSIC(Neg)
INTRINSIC(Not)
INTRINSIC(BitNot)
diff --git a/source/slang/lexer.cpp b/source/slang/lexer.cpp
index 2d75e1900..d8211fb20 100644
--- a/source/slang/lexer.cpp
+++ b/source/slang/lexer.cpp
@@ -517,7 +517,7 @@ namespace Slang
if(base > 10)
{
cursor++;
- return c - 'a';
+ return 10 + c - 'a';
}
return -1;
@@ -525,7 +525,7 @@ namespace Slang
if(base > 10)
{
cursor++;
- return c - 'A';
+ return 10 + c - 'A';
}
return -1;
}
@@ -957,7 +957,7 @@ namespace Slang
switch(peek(lexer))
{
default:
- return TokenType::IntegerLiteral;
+ return maybeLexNumberSuffix(lexer, TokenType::IntegerLiteral);
case '.':
advance(lexer);
diff --git a/source/slang/lower.cpp b/source/slang/lower.cpp
index b90573495..c154c96c8 100644
--- a/source/slang/lower.cpp
+++ b/source/slang/lower.cpp
@@ -451,6 +451,7 @@ struct LoweringVisitor
lowerExprCommon(loweredExpr, expr);
loweredExpr->BaseExpression = loweredBase;
loweredExpr->declRef = loweredDeclRef;
+ loweredExpr->name = expr->name;
return loweredExpr;
}
@@ -687,16 +688,6 @@ struct LoweringVisitor
addStmt(loweredStmt);
}
- void visitUnparsedStmt(UnparsedStmt* stmt)
- {
- RefPtr<UnparsedStmt> loweredStmt = new UnparsedStmt();
- lowerStmtFields(loweredStmt, stmt);
-
- loweredStmt->tokens = stmt->tokens;
-
- addStmt(loweredStmt);
- }
-
void visitCaseStmt(CaseStmt* stmt)
{
RefPtr<CaseStmt> loweredStmt = new CaseStmt();
diff --git a/source/slang/parser.cpp b/source/slang/parser.cpp
index b134f9645..2056bf809 100644
--- a/source/slang/parser.cpp
+++ b/source/slang/parser.cpp
@@ -1392,6 +1392,28 @@ namespace Slang
return genericApp;
}
+ // Parse option `[]` braces after a type expression, that indicate an array type
+ static RefPtr<ExpressionSyntaxNode> parsePostfixTypeSuffix(
+ Parser* parser,
+ RefPtr<ExpressionSyntaxNode> inTypeExpr)
+ {
+ auto typeExpr = inTypeExpr;
+ while (parser->LookAheadToken(TokenType::LBracket))
+ {
+ RefPtr<IndexExpressionSyntaxNode> arrType = new IndexExpressionSyntaxNode();
+ arrType->Position = typeExpr->Position;
+ arrType->BaseExpression = typeExpr;
+ parser->ReadToken(TokenType::LBracket);
+ if (!parser->LookAheadToken(TokenType::RBracket))
+ {
+ arrType->IndexExpression = parser->ParseExpression();
+ }
+ parser->ReadToken(TokenType::RBracket);
+ typeExpr = arrType;
+ }
+ return typeExpr;
+ }
+
static TypeSpec
parseTypeSpec(Parser* parser)
{
@@ -1431,11 +1453,16 @@ namespace Slang
typeExpr = parseGenericApp(parser, typeExpr);
}
+ // GLSL allows `[]` directly in a type specifier
+ if (parser->translationUnit->sourceLanguage == SourceLanguage::GLSL)
+ {
+ typeExpr = parsePostfixTypeSuffix(parser, typeExpr);
+ }
+
typeSpec.expr = typeExpr;
return typeSpec;
}
-
static RefPtr<DeclBase> ParseDeclaratorDecl(
Parser* parser,
ContainerDecl* containerDecl)
@@ -2572,50 +2599,6 @@ namespace Slang
RefPtr<StatementSyntaxNode> Parser::ParseBlockStatement()
{
- if( translationUnit->compileFlags & SLANG_COMPILE_FLAG_NO_CHECKING )
- {
- // We have been asked to parse the input, but not attempt to understand it.
-
- // TODO: record start/end locations...
-
- List<Token> tokens;
-
- ReadToken(TokenType::LBrace);
-
- int depth = 1;
- for( ;;)
- {
- switch( tokenReader.PeekTokenType() )
- {
- case TokenType::EndOfFile:
- goto done;
-
- case TokenType::RBrace:
- depth--;
- if(depth == 0)
- goto done;
- break;
-
- case TokenType::LBrace:
- depth++;
- break;
-
- default:
- break;
- }
-
- auto token = tokenReader.AdvanceToken();
- tokens.Add(token);
- }
- done:
- ReadToken(TokenType::RBrace);
-
- RefPtr<UnparsedStmt> unparsedStmt = new UnparsedStmt();
- unparsedStmt->tokens = tokens;
- return unparsedStmt;
- }
-
-
RefPtr<ScopeDecl> scopeDecl = new ScopeDecl();
RefPtr<BlockStmt> blockStatement = new BlockStmt();
blockStatement->scopeDecl = scopeDecl;
@@ -2816,19 +2799,7 @@ namespace Slang
}
auto typeExpr = typeSpec.expr;
- while (LookAheadToken(TokenType::LBracket))
- {
- RefPtr<IndexExpressionSyntaxNode> arrType = new IndexExpressionSyntaxNode();
- arrType->Position = typeExpr->Position;
- arrType->BaseExpression = typeExpr;
- ReadToken(TokenType::LBracket);
- if (!LookAheadToken(TokenType::RBracket))
- {
- arrType->IndexExpression = ParseExpression();
- }
- ReadToken(TokenType::RBracket);
- typeExpr = arrType;
- }
+ typeExpr = parsePostfixTypeSuffix(this, typeExpr);
return typeExpr;
}
@@ -2915,83 +2886,6 @@ namespace Slang
}
}
- Operator GetOpFromToken(Token & token)
- {
- switch(token.Type)
- {
- case TokenType::Comma:
- return Operator::Sequence;
- case TokenType::OpAssign:
- return Operator::Assign;
- case TokenType::OpAddAssign:
- return Operator::AddAssign;
- case TokenType::OpSubAssign:
- return Operator::SubAssign;
- case TokenType::OpMulAssign:
- return Operator::MulAssign;
- case TokenType::OpDivAssign:
- return Operator::DivAssign;
- case TokenType::OpModAssign:
- return Operator::ModAssign;
- case TokenType::OpShlAssign:
- return Operator::LshAssign;
- case TokenType::OpShrAssign:
- return Operator::RshAssign;
- case TokenType::OpOrAssign:
- return Operator::OrAssign;
- case TokenType::OpAndAssign:
- return Operator::AddAssign;
- case TokenType::OpXorAssign:
- return Operator::XorAssign;
- case TokenType::OpOr:
- return Operator::Or;
- case TokenType::OpAnd:
- return Operator::And;
- case TokenType::OpBitOr:
- return Operator::BitOr;
- case TokenType::OpBitXor:
- return Operator::BitXor;
- case TokenType::OpBitAnd:
- return Operator::BitAnd;
- case TokenType::OpEql:
- return Operator::Eql;
- case TokenType::OpNeq:
- return Operator::Neq;
- case TokenType::OpGeq:
- return Operator::Geq;
- case TokenType::OpLeq:
- return Operator::Leq;
- case TokenType::OpGreater:
- return Operator::Greater;
- case TokenType::OpLess:
- return Operator::Less;
- case TokenType::OpLsh:
- return Operator::Lsh;
- case TokenType::OpRsh:
- return Operator::Rsh;
- case TokenType::OpAdd:
- return Operator::Add;
- case TokenType::OpSub:
- return Operator::Sub;
- case TokenType::OpMul:
- return Operator::Mul;
- case TokenType::OpDiv:
- return Operator::Div;
- case TokenType::OpMod:
- return Operator::Mod;
- case TokenType::OpInc:
- return Operator::PostInc;
- case TokenType::OpDec:
- return Operator::PostDec;
- case TokenType::OpNot:
- return Operator::Not;
- case TokenType::OpBitNot:
- return Operator::BitNot;
- default:
- throw "Illegal TokenType.";
- }
- }
-
static RefPtr<ExpressionSyntaxNode> parseOperator(Parser* parser)
{
Token opToken;
@@ -3194,9 +3088,8 @@ namespace Slang
// but for now we will follow some hueristics.
case TokenType::LParent:
{
- parser->ReadToken(TokenType::LParent);
+ Token openParen = parser->ReadToken(TokenType::LParent);
- RefPtr<ExpressionSyntaxNode> expr;
if (peekTypeName(parser) && parser->LookAheadToken(TokenType::RParent, 1))
{
RefPtr<TypeCastExpressionSyntaxNode> tcexpr = new TypeCastExpressionSyntaxNode();
@@ -3204,15 +3097,18 @@ namespace Slang
tcexpr->TargetType = parser->ParseTypeExp();
parser->ReadToken(TokenType::RParent);
tcexpr->Expression = parser->ParseExpression(Precedence::Multiplicative); // Note(tfoley): need to double-check this
- expr = tcexpr;
+ return tcexpr;
}
else
{
- expr = parser->ParseExpression();
+ RefPtr<ExpressionSyntaxNode> base = parser->ParseExpression();
parser->ReadToken(TokenType::RParent);
- }
- return expr;
+ RefPtr<ParenExpr> parenExpr = new ParenExpr();
+ parenExpr->Position = openParen.Position;
+ parenExpr->base = base;
+ return parenExpr;
+ }
}
// An initializer list `{ expr, ... }`
@@ -3476,7 +3372,11 @@ namespace Slang
indexExpr->BaseExpression = expr;
parser->FillPosition(indexExpr.Ptr());
parser->ReadToken(TokenType::LBracket);
- indexExpr->IndexExpression = parser->ParseExpression();
+ // TODO: eventually we may want to support multiple arguments inside the `[]`
+ if (!parser->LookAheadToken(TokenType::RBracket))
+ {
+ indexExpr->IndexExpression = parser->ParseExpression();
+ }
parser->ReadToken(TokenType::RBracket);
expr = indexExpr;
@@ -3539,6 +3439,7 @@ namespace Slang
case TokenType::OpDec:
case TokenType::OpNot:
case TokenType::OpBitNot:
+ case TokenType::OpAdd:
case TokenType::OpSub:
{
RefPtr<PrefixExpr> prefixExpr = new PrefixExpr();
diff --git a/source/slang/slang-stdlib.cpp b/source/slang/slang-stdlib.cpp
index e1bba8885..e2d5829b4 100644
--- a/source/slang/slang-stdlib.cpp
+++ b/source/slang/slang-stdlib.cpp
@@ -7,18 +7,40 @@
#define STRINGIZE2(x) #x
#define LINE_STRING STRINGIZE(__LINE__)
-enum { kLibIncludeStringLine = __LINE__+1 };
-const char * LibIncludeStringChunks[] = { R"=(
+enum { kCoreLibIncludeStringLine = __LINE__ + 1 };
+const char* kCoreLibIncludeStringChunks[] = { R"=(
-typedef uint UINT;
+// A type that can be used as an operand for builtins
+interface __BuiltinType {}
+
+// A type that can be used for arithmetic operations
+interface __BuiltinArithmeticType : __BuiltinType {}
+
+// A type that logically has a sign (positive/negative/zero)
+interface __BuiltinSignedArithmeticType : __BuiltinArithmeticType {}
-__generic<T> __intrinsic_op(Assign) T operator=(out T left, T right);
+// A type that can represent integers
+interface __BuiltinIntegerType : __BuiltinArithmeticType {}
+
+// A type that can represent non-integers
+interface __BuiltinRealType : __BuiltinArithmeticType {}
+
+// A type that uses a floating-point representation
+interface __BuiltinFloatingPointType : __BuiltinRealType, __BuiltinSignedArithmeticType {}
__generic<T,U> __intrinsic_op(Sequence) U operator,(T left, U right);
__generic<T> __intrinsic_op(Select) T operator?:(bool condition, T ifTrue, T ifFalse);
__generic<T, let N : int> __intrinsic_op(Select) vector<T,N> operator?:(vector<bool,N> condition, vector<T,N> ifTrue, vector<T,N> ifFalse);
+)=" };
+
+
+enum { kHLSLLibIncludeStringLine = __LINE__+1 };
+const char * kHLSLLibIncludeStringChunks[] = { R"=(
+
+typedef uint UINT;
+
__generic<T> __magic_type(HLSLAppendStructuredBufferType) struct AppendStructuredBuffer
{
__intrinsic void Append(T value);
@@ -252,24 +274,6 @@ __generic<T> __magic_type(HLSLLineStreamType) struct TriangleStream
// Note(tfoley): Trying to systematically add all the HLSL builtins
-// A type that can be used as an operand for builtins
-interface __BuiltinType {}
-
-// A type that can be used for arithmetic operations
-interface __BuiltinArithmeticType : __BuiltinType {}
-
-// A type that logically has a sign (positive/negative/zero)
-interface __BuiltinSignedArithmeticType : __BuiltinArithmeticType {}
-
-// A type that can represent integers
-interface __BuiltinIntegerType : __BuiltinArithmeticType {}
-
-// A type that can represent non-integers
-interface __BuiltinRealType : __BuiltinArithmeticType {}
-
-// A type that uses a floating-point representation
-interface __BuiltinFloatingPointType : __BuiltinRealType, __BuiltinSignedArithmeticType {}
-
// Try to terminate the current draw or dispatch call (HLSL SM 4.0)
__intrinsic void abort();
@@ -1011,7 +1015,11 @@ namespace Slang
return stdlibPath;
}
- String SlangStdLib::code;
+ // Cached code for the various libraries
+ String coreLibraryCode;
+ String slangLibraryCode;
+ String hlslLibraryCode;
+ String glslLibraryCode;
enum
{
@@ -1029,93 +1037,88 @@ namespace Slang
ANY_MASK = INT_MASK | FLOAT_MASK | BOOL_MASK,
};
- String SlangStdLib::GetCode()
- {
- if (code.Length() > 0)
- return code;
- StringBuilder sb;
-
- // generate operator overloads
-
-
-
- struct OpInfo { IntrinsicOp opCode; char const* opName; unsigned flags; };
-
- OpInfo unaryOps[] = {
- { IntrinsicOp::Neg, "-", ARITHMETIC_MASK },
- { IntrinsicOp::Not, "!", ANY_MASK },
- { IntrinsicOp::BitNot, "~", INT_MASK },
- { IntrinsicOp::PreInc, "++", ARITHMETIC_MASK | ASSIGNMENT },
- { IntrinsicOp::PreDec, "--", ARITHMETIC_MASK | ASSIGNMENT },
- { IntrinsicOp::PostInc, "++", ARITHMETIC_MASK | ASSIGNMENT | POSTFIX },
- { IntrinsicOp::PostDec, "--", ARITHMETIC_MASK | ASSIGNMENT | POSTFIX },
- };
-
- OpInfo binaryOps[] = {
- { IntrinsicOp::Add, "+", ARITHMETIC_MASK },
- { IntrinsicOp::Sub, "-", ARITHMETIC_MASK },
- { IntrinsicOp::Mul, "*", ARITHMETIC_MASK },
- { IntrinsicOp::Div, "/", ARITHMETIC_MASK },
- { IntrinsicOp::Mod, "%", INT_MASK },
-
- { IntrinsicOp::And, "&&", LOGICAL_MASK },
- { IntrinsicOp::Or, "||", LOGICAL_MASK },
-
- { IntrinsicOp::BitAnd, "&", LOGICAL_MASK },
- { IntrinsicOp::BitOr, "|", LOGICAL_MASK },
- { IntrinsicOp::BitXor, "^", LOGICAL_MASK },
+ static const struct {
+ char const* name;
+ BaseType tag;
+ unsigned flags;
+ } kBaseTypes[] = {
+ { "void", BaseType::Void, 0 },
+ { "int", BaseType::Int, SINT_MASK },
+ { "half", BaseType::Half, FLOAT_MASK },
+ { "float", BaseType::Float, FLOAT_MASK },
+ { "double", BaseType::Double, FLOAT_MASK },
+ { "uint", BaseType::UInt, UINT_MASK },
+ { "bool", BaseType::Bool, BOOL_MASK },
+ { "uint64_t", BaseType::UInt64, UINT_MASK },
+ };
- { IntrinsicOp::Lsh, "<<", INT_MASK },
- { IntrinsicOp::Rsh, ">>", INT_MASK },
+ struct OpInfo { IntrinsicOp opCode; char const* opName; unsigned flags; };
+
+ static const OpInfo unaryOps[] = {
+ { IntrinsicOp::Pos, "+", ARITHMETIC_MASK },
+ { IntrinsicOp::Neg, "-", ARITHMETIC_MASK },
+ { IntrinsicOp::Not, "!", ANY_MASK },
+ { IntrinsicOp::BitNot, "~", INT_MASK },
+ { IntrinsicOp::PreInc, "++", ARITHMETIC_MASK | ASSIGNMENT },
+ { IntrinsicOp::PreDec, "--", ARITHMETIC_MASK | ASSIGNMENT },
+ { IntrinsicOp::PostInc, "++", ARITHMETIC_MASK | ASSIGNMENT | POSTFIX },
+ { IntrinsicOp::PostDec, "--", ARITHMETIC_MASK | ASSIGNMENT | POSTFIX },
+ };
- { IntrinsicOp::Eql, "==", ANY_MASK | COMPARISON },
- { IntrinsicOp::Neq, "!=", ANY_MASK | COMPARISON },
+ static const OpInfo binaryOps[] = {
+ { IntrinsicOp::Add, "+", ARITHMETIC_MASK },
+ { IntrinsicOp::Sub, "-", ARITHMETIC_MASK },
+ { IntrinsicOp::Mul, "*", ARITHMETIC_MASK },
+ { IntrinsicOp::Div, "/", ARITHMETIC_MASK },
+ { IntrinsicOp::Mod, "%", INT_MASK },
+
+ { IntrinsicOp::And, "&&", LOGICAL_MASK },
+ { IntrinsicOp::Or, "||", LOGICAL_MASK },
+
+ { IntrinsicOp::BitAnd, "&", LOGICAL_MASK },
+ { IntrinsicOp::BitOr, "|", LOGICAL_MASK },
+ { IntrinsicOp::BitXor, "^", LOGICAL_MASK },
+
+ { IntrinsicOp::Lsh, "<<", INT_MASK },
+ { IntrinsicOp::Rsh, ">>", INT_MASK },
+
+ { IntrinsicOp::Eql, "==", ANY_MASK | COMPARISON },
+ { IntrinsicOp::Neq, "!=", ANY_MASK | COMPARISON },
+
+ { IntrinsicOp::Greater, ">", ARITHMETIC_MASK | COMPARISON },
+ { IntrinsicOp::Less, "<", ARITHMETIC_MASK | COMPARISON },
+ { IntrinsicOp::Geq, ">=", ARITHMETIC_MASK | COMPARISON },
+ { IntrinsicOp::Leq, "<=", ARITHMETIC_MASK | COMPARISON },
+
+ { IntrinsicOp::AddAssign, "+=", ASSIGNMENT | ARITHMETIC_MASK },
+ { IntrinsicOp::SubAssign, "-=", ASSIGNMENT | ARITHMETIC_MASK },
+ { IntrinsicOp::MulAssign, "*=", ASSIGNMENT | ARITHMETIC_MASK },
+ { IntrinsicOp::DivAssign, "/=", ASSIGNMENT | ARITHMETIC_MASK },
+ { IntrinsicOp::ModAssign, "%=", ASSIGNMENT | ARITHMETIC_MASK },
+ { IntrinsicOp::AndAssign, "&=", ASSIGNMENT | LOGICAL_MASK },
+ { IntrinsicOp::OrAssign, "|=", ASSIGNMENT | LOGICAL_MASK },
+ { IntrinsicOp::XorAssign, "^=", ASSIGNMENT | LOGICAL_MASK },
+ { IntrinsicOp::LshAssign, "<<=", ASSIGNMENT | INT_MASK },
+ { IntrinsicOp::RshAssign, ">>=", ASSIGNMENT | INT_MASK },
+ };
- { IntrinsicOp::Greater, ">", ARITHMETIC_MASK | COMPARISON },
- { IntrinsicOp::Less, "<", ARITHMETIC_MASK | COMPARISON },
- { IntrinsicOp::Geq, ">=", ARITHMETIC_MASK | COMPARISON },
- { IntrinsicOp::Leq, "<=", ARITHMETIC_MASK | COMPARISON },
- { IntrinsicOp::AddAssign, "+=", ASSIGNMENT | ARITHMETIC_MASK },
- { IntrinsicOp::SubAssign, "-=", ASSIGNMENT | ARITHMETIC_MASK },
- { IntrinsicOp::MulAssign, "*=", ASSIGNMENT | ARITHMETIC_MASK },
- { IntrinsicOp::DivAssign, "/=", ASSIGNMENT | ARITHMETIC_MASK },
- { IntrinsicOp::ModAssign, "%=", ASSIGNMENT | ARITHMETIC_MASK },
- { IntrinsicOp::AndAssign, "&=", ASSIGNMENT | LOGICAL_MASK },
- { IntrinsicOp::OrAssign, "|=", ASSIGNMENT | LOGICAL_MASK },
- { IntrinsicOp::XorAssign, "^=", ASSIGNMENT | LOGICAL_MASK },
- { IntrinsicOp::LshAssign, "<<=", ASSIGNMENT | INT_MASK },
- { IntrinsicOp::RshAssign, ">>=", ASSIGNMENT | INT_MASK },
+ String getCoreLibraryCode()
+ {
+ if (coreLibraryCode.Length() > 0)
+ return coreLibraryCode;
+ StringBuilder sb;
- };
+ // generate operator overloads
- /*
- String floatTypes[] = { "float", "float2", "float3", "float4" };
- String intTypes[] = { "int", "int2", "int3", "int4" };
- String uintTypes[] = { "uint", "uint2", "uint3", "uint4" };
- */
String path = getStdlibPath();
-
-
#define EMIT_LINE_DIRECTIVE() sb << "#line " << (__LINE__+1) << " \"" << path << "\"\n"
// Generate declarations for all the base types
- static const struct {
- char const* name;
- BaseType tag;
- unsigned flags;
- } kBaseTypes[] = {
- { "void", BaseType::Void, 0 },
- { "int", BaseType::Int, SINT_MASK },
- { "float", BaseType::Float, FLOAT_MASK },
- { "uint", BaseType::UInt, UINT_MASK },
- { "bool", BaseType::Bool, BOOL_MASK },
- { "uint64_t", BaseType::UInt64, UINT_MASK },
- };
static const int kBaseTypeCount = sizeof(kBaseTypes) / sizeof(kBaseTypes[0]);
for (int tt = 0; tt < kBaseTypeCount; ++tt)
{
@@ -1126,7 +1129,7 @@ namespace Slang
sb << "\n : __BuiltinType\n";
- switch( kBaseTypes[tt].tag )
+ switch (kBaseTypes[tt].tag)
{
case BaseType::Float:
sb << "\n , __BuiltinFloatingPointType\n";
@@ -1151,9 +1154,9 @@ namespace Slang
// Declare initializers to convert from various other types
- for( int ss = 0; ss < kBaseTypeCount; ++ss )
+ for (int ss = 0; ss < kBaseTypeCount; ++ss)
{
- if( kBaseTypes[ss].tag == BaseType::Void )
+ if (kBaseTypes[ss].tag == BaseType::Void)
continue;
EMIT_LINE_DIRECTIVE();
@@ -1163,12 +1166,6 @@ namespace Slang
sb << "};\n";
}
- // Declare ad hoc aliases for some types, just to get things compiling
- //
- // TODO(tfoley): At the very least, `double` should be treated as a distinct type.
- sb << "typedef float double;\n";
- sb << "typedef float half;\n";
-
// Declare vector and matrix types
sb << "__generic<T = float, let N : int = 4> __magic_type(Vector) struct vector\n{\n";
@@ -1205,6 +1202,12 @@ namespace Slang
}
}
+ // Declare additional built-in generic types
+// EMIT_LINE_DIRECTIVE();
+ sb << "__generic<T> __magic_type(ConstantBuffer) struct ConstantBuffer {};\n";
+ sb << "__generic<T> __magic_type(TextureBuffer) struct TextureBuffer {};\n";
+
+
static const char* kComponentNames[]{ "x", "y", "z", "w" };
static const char* kVectorNames[]{ "", "x", "xy", "xyz", "xyzw" };
@@ -1292,7 +1295,6 @@ namespace Slang
sb << "}\n";
}
-
// Declare built-in texture and sampler types
sb << "__magic_type(SamplerState," << int(SamplerStateType::Flavor::SamplerState) << ") struct SamplerState {};";
@@ -1372,11 +1374,11 @@ namespace Slang
for(int isFloat = 0; isFloat < 2; ++isFloat)
for(int includeMipInfo = 0; includeMipInfo < 2; ++includeMipInfo)
{
- char const* t = isFloat ? "out float " : "out UINT ";
+ char const* t = isFloat ? "out float " : "out uint ";
sb << "void GetDimensions(";
if(includeMipInfo)
- sb << "UINT mipLevel, ";
+ sb << "uint mipLevel, ";
switch(baseShape)
{
@@ -1671,27 +1673,6 @@ namespace Slang
}
}
- // Declare additional built-in generic types
- EMIT_LINE_DIRECTIVE();
- sb << "__generic<T> __magic_type(ConstantBuffer) struct ConstantBuffer {};\n";
- sb << "__generic<T> __magic_type(TextureBuffer) struct TextureBuffer {};\n";
-
- sb << "__generic<T> __magic_type(PackedBuffer) struct PackedBuffer {};\n";
- sb << "__generic<T> __magic_type(Uniform) struct Uniform {};\n";
- sb << "__generic<T> __magic_type(Patch) struct Patch {};\n";
-
-
- // Stale declarations for GLSL inner-product builtins
-#if 0
- sb << "__intrinsic vec3 operator * (vec3, mat3);\n";
- sb << "__intrinsic vec3 operator * (mat3, vec3);\n";
-
- sb << "__intrinsic vec4 operator * (vec4, mat4);\n";
- sb << "__intrinsic vec4 operator * (mat4, vec4);\n";
-
- sb << "__intrinsic mat3 operator * (mat3, mat3);\n";
- sb << "__intrinsic mat4 operator * (mat4, mat4);\n";
-#endif
for (auto op : unaryOps)
{
@@ -1745,29 +1726,93 @@ namespace Slang
sb << "__intrinsic_op(" << int(op.opCode) << ") vector<" << resultType << ",N> operator" << op.opName << "(" << leftQual << "vector<" << leftType << ",N> left, vector<" << rightType << ",N> right);\n";
// matrix version
+
+ // skip matrix-matrix multiply operations here, so that GLSL doesn't see them
+ switch (op.opCode)
+ {
+ case IntrinsicOp::Mul:
+ case IntrinsicOp::MulAssign:
+ break;
+
+ default:
+ sb << "__generic<let N : int, let M : int> ";
+ sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M> operator" << op.opName << "(" << leftQual << "matrix<" << leftType << ",N,M> left, matrix<" << rightType << ",N,M> right);\n";
+ break;
+ }
+ }
+ }
+
+ // Output a suitable `#line` directive to point at our raw stdlib code above
+ sb << "\n#line " << kCoreLibIncludeStringLine << " \"" << path << "\"\n";
+
+ int chunkCount = sizeof(kCoreLibIncludeStringChunks) / sizeof(kCoreLibIncludeStringChunks[0]);
+ for (int cc = 0; cc < chunkCount; ++cc)
+ {
+ sb << kCoreLibIncludeStringChunks[cc];
+ }
+
+ coreLibraryCode = sb.ProduceString();
+ return coreLibraryCode;
+ }
+
+ String getHLSLLibraryCode()
+ {
+ if (hlslLibraryCode.Length() > 0)
+ return hlslLibraryCode;
+
+ StringBuilder sb;
+
+
+// sb << "__generic<T> __magic_type(PackedBuffer) struct PackedBuffer {};\n";
+// sb << "__generic<T> __magic_type(Uniform) struct Uniform {};\n";
+// sb << "__generic<T> __magic_type(Patch) struct Patch {};\n";
+
+ // Component-wise multiplication ops
+ for(auto op : binaryOps)
+ {
+ switch (op.opCode)
+ {
+ default:
+ continue;
+
+ case IntrinsicOp::Mul:
+ case IntrinsicOp::MulAssign:
+ break;
+ }
+
+ for (auto type : kBaseTypes)
+ {
+ if ((type.flags & op.flags) == 0)
+ continue;
+
+ char const* leftType = type.name;
+ char const* rightType = leftType;
+ char const* resultType = leftType;
+
+ char const* leftQual = "";
+ if(op.flags & ASSIGNMENT) leftQual = "in out ";
+
sb << "__generic<let N : int, let M : int> ";
sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M> operator" << op.opName << "(" << leftQual << "matrix<" << leftType << ",N,M> left, matrix<" << rightType << ",N,M> right);\n";
}
}
// Output a suitable `#line` directive to point at our raw stdlib code above
- sb << "\n#line " << kLibIncludeStringLine << " \"" << path << "\"\n";
+ sb << "\n#line " << kHLSLLibIncludeStringLine << " \"" << getStdlibPath() << "\"\n";
- int chunkCount = sizeof(LibIncludeStringChunks) / sizeof(LibIncludeStringChunks[0]);
+ int chunkCount = sizeof(kHLSLLibIncludeStringChunks) / sizeof(kHLSLLibIncludeStringChunks[0]);
for (int cc = 0; cc < chunkCount; ++cc)
{
- sb << LibIncludeStringChunks[cc];
+ sb << kHLSLLibIncludeStringChunks[cc];
}
- code = sb.ProduceString();
- return code;
+ hlslLibraryCode = sb.ProduceString();
+ return hlslLibraryCode;
}
// GLSL-specific library code
- String glslLibraryCode;
-
String getGLSLLibraryCode()
{
if(glslLibraryCode.Length() != 0)
@@ -1794,16 +1839,42 @@ namespace Slang
// Declare GLSL aliases for HLSL types
for (int vv = 2; vv <= 4; ++vv)
{
- sb << "typedef " << kTypes[tt].name << vv << " " << kTypes[tt].glslPrefix << "vec" << vv << ";\n";
- sb << "typedef " << kTypes[tt].name << vv << "x" << vv << " " << kTypes[tt].glslPrefix << "mat" << vv << ";\n";
+ sb << "typedef vector<" << kTypes[tt].name << "," << vv << "> " << kTypes[tt].glslPrefix << "vec" << vv << ";\n";
+ sb << "typedef matrix<" << kTypes[tt].name << "," << vv << "," << vv << "> " << kTypes[tt].glslPrefix << "mat" << vv << ";\n";
}
for (int rr = 2; rr <= 4; ++rr)
for (int cc = 2; cc <= 4; ++cc)
{
- sb << "typedef " << kTypes[tt].name << rr << "x" << cc << " " << kTypes[tt].glslPrefix << "mat" << rr << "x" << cc << ";\n";
+ sb << "typedef matrix<" << kTypes[tt].name << "," << rr << "," << cc << "> " << kTypes[tt].glslPrefix << "mat" << rr << "x" << cc << ";\n";
}
}
+ // Multiplication operations for vectors + matrices
+
+ // scalar-vector and vector-scalar
+ sb << "__generic<T : __BuiltinArithmeticType, let N : int> __intrinsic_op(Mul) vector<T,N> operator*(vector<T,N> x, T y);\n";
+ sb << "__generic<T : __BuiltinArithmeticType, let N : int> __intrinsic_op(Mul) vector<T,N> operator*(T x, vector<T,N> y);\n";
+
+ // scalar-matrix and matrix-scalar
+ sb << "__generic<T : __BuiltinArithmeticType, let N : int, let M :int> __intrinsic_op(Mul) matrix<T,N,M> operator*(matrix<T,N,M> x, T y);\n";
+ sb << "__generic<T : __BuiltinArithmeticType, let N : int, let M :int> __intrinsic_op(Mul) matrix<T,N,M> operator*(T x, matrix<T,N,M> y);\n";
+
+ // vector-vector (dot product)
+ sb << "__generic<T : __BuiltinArithmeticType, let N : int> __intrinsic_op(Mul) T operator*(vector<T,N> x, vector<T,N> y);\n";
+
+ // vector-matrix
+ sb << "__generic<T : __BuiltinArithmeticType, let N : int, let M : int> __intrinsic_op(Mul) vector<T,M> operator*(vector<T,N> x, matrix<T,N,M> y);\n";
+
+ // matrix-vector
+ sb << "__generic<T : __BuiltinArithmeticType, let N : int, let M : int> __intrinsic_op(Mul) vector<T,N> operator*(matrix<T,N,M> x, vector<T,M> y);\n";
+
+ // matrix-matrix
+ sb << "__generic<T : __BuiltinArithmeticType, let R : int, let N : int, let C : int> __intrinsic_op(Mul) matrix<T,R,C> operator*(matrix<T,R,N> x, matrix<T,N,C> y);\n";
+
+
+
+ //
+
// TODO(tfoley): Need to handle `RW*` variants of texture types as well...
static const struct {
char const* name;
@@ -1909,6 +1980,7 @@ namespace Slang
sb << "__modifier(GLSLPatchModifier) patch;\n";
sb << "__modifier(SimpleModifier) flat;\n";
+ sb << "__modifier(SimpleModifier) highp;\n";
glslLibraryCode = sb.ProduceString();
return glslLibraryCode;
@@ -1918,10 +1990,12 @@ namespace Slang
//
- void SlangStdLib::Finalize()
+ void finalizeShaderLibrary()
{
- code = String();
stdlibPath = String();
+
+ coreLibraryCode = String();
+ hlslLibraryCode = String();
glslLibraryCode = String();
}
diff --git a/source/slang/slang-stdlib.h b/source/slang/slang-stdlib.h
index e4ee8cee3..d21b1e7f1 100644
--- a/source/slang/slang-stdlib.h
+++ b/source/slang/slang-stdlib.h
@@ -5,16 +5,11 @@
namespace Slang
{
- class SlangStdLib
- {
- private:
- static String code;
- public:
- static String GetCode();
- static void Finalize();
- };
-
+ String getCoreLibraryCode();
+ String getHLSLLibraryCode();
String getGLSLLibraryCode();
+
+ void finalizeShaderLibrary();
}
#endif \ No newline at end of file
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index c4944c5a4..e5bfcb923 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -25,8 +25,9 @@ public:
bool useCache = false;
String cacheDir;
- RefPtr<Scope> slangLanguageScope;
+ RefPtr<Scope> coreLanguageScope;
RefPtr<Scope> hlslLanguageScope;
+ RefPtr<Scope> slangLanguageScope;
RefPtr<Scope> glslLanguageScope;
List<RefPtr<ProgramSyntaxNode>> loadedModuleCode;
@@ -43,15 +44,19 @@ public:
// TODO: load these on-demand to avoid parsing
// stdlib code for languages the user won't use.
- slangLanguageScope = new Scope();
+ coreLanguageScope = new Scope();
hlslLanguageScope = new Scope();
- hlslLanguageScope->parent = slangLanguageScope;
+ hlslLanguageScope->nextSibling = coreLanguageScope;
+
+ slangLanguageScope = new Scope();
+ slangLanguageScope->nextSibling = hlslLanguageScope;
glslLanguageScope = new Scope();
- glslLanguageScope->parent = slangLanguageScope;
+ glslLanguageScope->nextSibling = coreLanguageScope;
- addBuiltinSource(slangLanguageScope, "stdlib", SlangStdLib::GetCode());
+ addBuiltinSource(coreLanguageScope, "core", getCoreLibraryCode());
+ addBuiltinSource(hlslLanguageScope, "hlsl", getHLSLLibraryCode());
addBuiltinSource(glslLanguageScope, "glsl", getGLSLLibraryCode());
}
@@ -61,7 +66,7 @@ public:
// code that we might have allocated and loaded into static
// variables (TODO: don't use `static` variables for this stuff)
- SlangStdLib::Finalize();
+ finalizeShaderLibrary();
// Ditto for our type represnetation stuff
diff --git a/source/slang/stmt-defs.h b/source/slang/stmt-defs.h
index c5bcda63b..165ffea83 100644
--- a/source/slang/stmt-defs.h
+++ b/source/slang/stmt-defs.h
@@ -16,11 +16,6 @@ SYNTAX_CLASS(BlockStmt, ScopeStmt)
SYNTAX_FIELD(RefPtr<StatementSyntaxNode>, body);
END_SYNTAX_CLASS()
-SYNTAX_CLASS(UnparsedStmt, StatementSyntaxNode)
- // The tokens that were contained between `{` and `}`
- FIELD(List<Token>, tokens)
-END_SYNTAX_CLASS()
-
SIMPLE_SYNTAX_CLASS(EmptyStatementSyntaxNode, StatementSyntaxNode)
SIMPLE_SYNTAX_CLASS(DiscardStatementSyntaxNode, StatementSyntaxNode)
diff --git a/source/slang/syntax.h b/source/slang/syntax.h
index 1704c1224..de5467c71 100644
--- a/source/slang/syntax.h
+++ b/source/slang/syntax.h
@@ -176,6 +176,7 @@ namespace Slang
Int,
UInt,
UInt64,
+ Half,
Float,
Double,
};
@@ -690,22 +691,6 @@ namespace Slang
LookupMask mask = LookupMask::All;
};
- enum class Operator
- {
- Neg, Not, BitNot, PreInc, PreDec, PostInc, PostDec,
- Mul, Div, Mod,
- Add, Sub,
- Lsh, Rsh,
- Eql, Neq, Greater, Less, Geq, Leq,
- BitAnd, BitXor, BitOr,
- And,
- Or,
- Sequence,
- Select,
- Assign = 200, AddAssign, SubAssign, MulAssign, DivAssign, ModAssign,
- LshAssign, RshAssign, OrAssign, AndAssign, XorAssign,
- };
-
// Generate class definition for all syntax classes
#define SYNTAX_FIELD(TYPE, NAME) TYPE NAME;
#define FIELD(TYPE, NAME) TYPE NAME;