https://github.com/shader-slang/slang
Raw File
Tip revision: b68516e2c2e39af79dda2ec7871fe4d821ef67c4 authored by Yong He on 03 April 2023, 22:54:16 UTC
Emit simpler vector element access code. (#2770)
Tip revision: b68516e
slang-ast-expr.h
// 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<Decl> 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<Expr*> 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<Expr*> 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<Expr*> 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<SourceLoc> 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<Expr*> 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<SourceLoc> 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<T>` 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<VarDeclBase> 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<Name*> 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<TypeExp> 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<GenericDecl> baseGenericDeclRef;

        /// A substitution that includes the generic arguments known so far
    GenericSubstitution* substWithKnownGenericArgs = nullptr;
};

} // namespace Slang
back to top