// slang-ast-expr.h #pragma once #include "slang-ast-base.h" namespace Slang { // Syntax class definitions for expressions. // // A placeholder for where an Expr is expected but is missing from source. class IncompleteExpr : public Expr { SLANG_AST_CLASS(IncompleteExpr) }; // Base class for expressions that will reference declarations class DeclRefExpr: public Expr { SLANG_ABSTRACT_AST_CLASS(DeclRefExpr) // The declaration of the symbol being referenced DeclRef declRef; // The name of the symbol being referenced Name* name = nullptr; // The original expr before DeclRef resolution. Expr* originalExpr = nullptr; SLANG_UNREFLECTED // The scope in which to perform lookup Scope* scope = nullptr; }; class VarExpr : public DeclRefExpr { SLANG_AST_CLASS(VarExpr) }; // An expression that references an overloaded set of declarations // having the same name. class OverloadedExpr : public Expr { SLANG_AST_CLASS(OverloadedExpr) // The name that was looked up and found to be overloaded Name* name = nullptr; // Optional: the base expression is this overloaded result // arose from a member-reference expression. Expr* base = nullptr; // The lookup result that was ambiguous LookupResult lookupResult2; }; // An expression that references an overloaded set of declarations // having the same name. class OverloadedExpr2: public Expr { SLANG_AST_CLASS(OverloadedExpr2) // Optional: the base expression is this overloaded result // arose from a member-reference expression. Expr* base = nullptr; // The lookup result that was ambiguous List candidiateExprs; }; class LiteralExpr : public Expr { SLANG_ABSTRACT_AST_CLASS(LiteralExpr) // The token that was used to express the literal. This can be // used to get the raw text of the literal, including any suffix. Token token; }; class IntegerLiteralExpr : public LiteralExpr { SLANG_AST_CLASS(IntegerLiteralExpr) IntegerLiteralValue value; }; class FloatingPointLiteralExpr: public LiteralExpr { SLANG_AST_CLASS(FloatingPointLiteralExpr) FloatingPointLiteralValue value; }; class BoolLiteralExpr : public LiteralExpr { SLANG_AST_CLASS(BoolLiteralExpr) bool value; }; class NullPtrLiteralExpr : public LiteralExpr { SLANG_AST_CLASS(NullPtrLiteralExpr) }; class NoneLiteralExpr : public LiteralExpr { SLANG_AST_CLASS(NoneLiteralExpr) }; class StringLiteralExpr : public LiteralExpr { SLANG_AST_CLASS(StringLiteralExpr) // TODO: consider storing the "segments" of the string // literal, in the case where multiple literals were //lined up at the lexer level, e.g.: // // "first" "second" "third" // String value; }; // An initializer list, e.g. `{ 1, 2, 3 }` class InitializerListExpr : public Expr { SLANG_AST_CLASS(InitializerListExpr) List args; }; class GetArrayLengthExpr : public Expr { SLANG_AST_CLASS(GetArrayLengthExpr) Expr* arrayExpr = nullptr; }; // A base class for expressions with arguments class ExprWithArgsBase : public Expr { SLANG_ABSTRACT_AST_CLASS(ExprWithArgsBase) List arguments; }; // An aggregate type constructor class AggTypeCtorExpr : public ExprWithArgsBase { SLANG_AST_CLASS(AggTypeCtorExpr) TypeExp base; }; // A base expression being applied to arguments: covers // both ordinary `()` function calls and `<>` generic application class AppExprBase : public ExprWithArgsBase { SLANG_ABSTRACT_AST_CLASS(AppExprBase) Expr* functionExpr = nullptr; // The original function expr before overload resolution. Expr* originalFunctionExpr = nullptr; // The source location of `(`, `)`, and `,` that marks the start/end of the application op and // each argument expr. This info is used by language server. List argumentDelimeterLocs; }; class InvokeExpr: public AppExprBase { SLANG_AST_CLASS(InvokeExpr) }; enum class TryClauseType { None, Standard, // Normal `try` clause Optional, // (Not implemented) `try?` clause that returns an optional value. Assert, // (Not implemented) `try!` clause that should always succeed and triggers runtime error if failed. }; char const* getTryClauseTypeName(TryClauseType value); class TryExpr : public Expr { SLANG_AST_CLASS(TryExpr) Expr* base; TryClauseType tryClauseType = TryClauseType::Standard; // The scope of this expr. Scope* scope = nullptr; }; class NewExpr : public InvokeExpr { SLANG_AST_CLASS(NewExpr) }; class OperatorExpr: public InvokeExpr { SLANG_AST_CLASS(OperatorExpr) }; class InfixExpr: public OperatorExpr { SLANG_AST_CLASS(InfixExpr) }; class PrefixExpr: public OperatorExpr { SLANG_AST_CLASS(PrefixExpr) }; class PostfixExpr: public OperatorExpr { SLANG_AST_CLASS(PostfixExpr) }; class IndexExpr: public Expr { SLANG_AST_CLASS(IndexExpr) Expr* baseExpression; List indexExprs; // The source location of `(`, `)`, and `,` that marks the start/end of the application op and // each argument expr. This info is used by language server. List argumentDelimeterLocs; }; class MemberExpr: public DeclRefExpr { SLANG_AST_CLASS(MemberExpr) Expr* baseExpression = nullptr; SourceLoc memberOperatorLoc; }; // Member looked up on a type, rather than a value class StaticMemberExpr: public DeclRefExpr { SLANG_AST_CLASS(StaticMemberExpr) Expr* baseExpression = nullptr; SourceLoc memberOperatorLoc; }; struct MatrixCoord { bool operator==(const MatrixCoord& rhs) const { return row == rhs.row && col == rhs.col; }; bool operator!=(const MatrixCoord& rhs) const { return !(*this == rhs); }; // Rows and columns are zero indexed int row; int col; }; class MatrixSwizzleExpr : public Expr { SLANG_AST_CLASS(MatrixSwizzleExpr) Expr* base = nullptr; int elementCount; MatrixCoord elementCoords[4]; SourceLoc memberOpLoc; }; class SwizzleExpr: public Expr { SLANG_AST_CLASS(SwizzleExpr) Expr* base = nullptr; int elementCount; int elementIndices[4]; SourceLoc memberOpLoc; }; // An operation to convert an l-value to a reference type. class MakeRefExpr : public Expr { SLANG_AST_CLASS(MakeRefExpr) Expr* base = nullptr; }; // A dereference of a pointer or pointer-like type class DerefExpr: public Expr { SLANG_AST_CLASS(DerefExpr) Expr* base = nullptr; }; // Any operation that performs type-casting class TypeCastExpr: public InvokeExpr { SLANG_AST_CLASS(TypeCastExpr) // TypeExp TargetType; // Expr* Expression = nullptr; }; // An explicit type-cast that appear in the user's code with `(type) expr` syntax class ExplicitCastExpr: public TypeCastExpr { SLANG_AST_CLASS(ExplicitCastExpr) }; // An implicit type-cast inserted during semantic checking class ImplicitCastExpr : public TypeCastExpr { SLANG_AST_CLASS(ImplicitCastExpr) }; /// A cast of a value to a super-type of its type. /// /// The type being cast to is stored as this expression's `type`. /// class CastToSuperTypeExpr: public Expr { SLANG_AST_CLASS(CastToSuperTypeExpr) /// The value being cast to a super type /// /// The type being cast from is `valueArg->type`. /// Expr* valueArg = nullptr; /// A witness showing that `valueArg`'s type is a sub-type of this expression's `type` Val* witnessArg = nullptr; }; /// A `value is Type` expression that evaluates to `true` if type of `value` is a sub-type of /// `Type`. class IsTypeExpr : public Expr { SLANG_AST_CLASS(IsTypeExpr) Expr* value = nullptr; TypeExp typeExpr; // A witness showing that `typeExpr.type` is a subtype of `typeof(value)`. Val* witnessArg = nullptr; // non-null if evaluates to a constant. BoolLiteralExpr* constantVal = nullptr; }; /// A `value as Type` expression that casts `value` to `Type` within type hierarchy. /// The result is undefined if `value` is not `Type`. class AsTypeExpr : public Expr { SLANG_AST_CLASS(AsTypeExpr) Expr* value = nullptr; Expr* typeExpr = nullptr; // A witness showing that `typeExpr` is a subtype of `typeof(value)`. Val* witnessArg = nullptr; }; class MakeOptionalExpr : public Expr { SLANG_AST_CLASS(MakeOptionalExpr) // If `value` is null, this constructs an `Optional` that doesn't have a value. Expr* value = nullptr; Expr* typeExpr = nullptr; }; /// A cast of a value to the same type, with different modifiers. /// /// The type being cast to is stored as this expression's `type`. /// class ModifierCastExpr : public Expr { SLANG_AST_CLASS(ModifierCastExpr) /// The value being cast. /// /// The type being cast from is `valueArg->type`. /// Expr* valueArg = nullptr; }; class SelectExpr: public OperatorExpr { SLANG_AST_CLASS(SelectExpr) }; class GenericAppExpr: public AppExprBase { SLANG_AST_CLASS(GenericAppExpr) }; // An expression representing re-use of the syntax for a type in more // than once conceptually-distinct declaration class SharedTypeExpr: public Expr { SLANG_AST_CLASS(SharedTypeExpr) // The underlying type expression that we want to share TypeExp base; }; class AssignExpr: public Expr { SLANG_AST_CLASS(AssignExpr) Expr* left = nullptr; Expr* right = nullptr; }; // 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. class ParenExpr: public Expr { SLANG_AST_CLASS(ParenExpr) Expr* base = nullptr; }; // An object-oriented `this` expression, used to // refer to the current instance of an enclosing type. class ThisExpr: public Expr { SLANG_AST_CLASS(ThisExpr) SLANG_UNREFLECTED Scope* scope = nullptr; }; // An expression that binds a temporary variable in a local expression context class LetExpr: public Expr { SLANG_AST_CLASS(LetExpr) VarDecl* decl = nullptr; Expr* body = nullptr; }; class ExtractExistentialValueExpr: public Expr { SLANG_AST_CLASS(ExtractExistentialValueExpr) DeclRef declRef; Expr* originalExpr; }; class OpenRefExpr : public Expr { SLANG_AST_CLASS(OpenRefExpr) Expr* innerExpr = nullptr; }; /// Base class for higher-order function application /// Eg: foo(fn) where fn is a function expression. /// class HigherOrderInvokeExpr : public Expr { SLANG_ABSTRACT_AST_CLASS(HigherOrderInvokeExpr) Expr* baseFunction; List newParameterNames; }; class PrimalSubstituteExpr : public HigherOrderInvokeExpr { SLANG_AST_CLASS(PrimalSubstituteExpr) }; class DifferentiateExpr : public HigherOrderInvokeExpr { SLANG_ABSTRACT_AST_CLASS(DifferentiateExpr) }; /// An expression of the form `__fwd_diff(fn)` to access the /// forward-mode derivative version of the function `fn` /// class ForwardDifferentiateExpr: public DifferentiateExpr { SLANG_AST_CLASS(ForwardDifferentiateExpr) }; /// An expression of the form `__bwd_diff(fn)` to access the /// forward-mode derivative version of the function `fn` /// class BackwardDifferentiateExpr: public DifferentiateExpr { SLANG_AST_CLASS(BackwardDifferentiateExpr) }; /// An expression of the form `__dispatch_kernel(fn, threadGroupSize, dispatchSize)` to /// dispatch a compute kernel from host. /// class DispatchKernelExpr : public HigherOrderInvokeExpr { SLANG_AST_CLASS(DispatchKernelExpr) Expr* threadGroupSize; Expr* dispatchSize; }; /// An express to mark its inner expression as an intended non-differential call. class TreatAsDifferentiableExpr : public Expr { SLANG_AST_CLASS(TreatAsDifferentiableExpr) Expr* innerExpr; Scope* scope; }; /// A type expression of the form `__TaggedUnion(A, ...)`. /// /// An expression of this form will resolve to a `TaggedUnionType` /// when checked. /// class TaggedUnionTypeExpr: public Expr { SLANG_AST_CLASS(TaggedUnionTypeExpr) List caseTypes; }; /// A type expression of the form `This` /// /// Refers to the type of `this` in the current context. /// class ThisTypeExpr: public Expr { SLANG_AST_CLASS(ThisTypeExpr) SLANG_UNREFLECTED Scope* scope = nullptr; }; /// A type expression of the form `Left & Right`. class AndTypeExpr : public Expr { SLANG_AST_CLASS(AndTypeExpr); TypeExp left; TypeExp right; }; /// A type exprssion that applies one or more modifiers to another type class ModifiedTypeExpr : public Expr { SLANG_AST_CLASS(ModifiedTypeExpr); Modifiers modifiers; TypeExp base; }; /// A type expression that rrepresents a pointer type, e.g. T* class PointerTypeExpr : public Expr { SLANG_AST_CLASS(PointerTypeExpr); TypeExp base; }; /// An expression that applies a generic to arguments for some, /// but not all, of its explicit parameters. /// class PartiallyAppliedGenericExpr : public Expr { SLANG_AST_CLASS(PartiallyAppliedGenericExpr); public: Expr* originalExpr = nullptr; /// The generic being applied DeclRef baseGenericDeclRef; /// A substitution that includes the generic arguments known so far GenericSubstitution* substWithKnownGenericArgs = nullptr; }; } // namespace Slang