https://github.com/shader-slang/slang
Tip revision: b68516e2c2e39af79dda2ec7871fe4d821ef67c4 authored by Yong He on 03 April 2023, 22:54:16 UTC
Emit simpler vector element access code. (#2770)
Emit simpler vector element access code. (#2770)
Tip revision: b68516e
slang-emit-precedence.h
// slang-emit-precedence.h
#ifndef SLANG_EMIT_PRECEDENCE_H_INCLUDED
#define SLANG_EMIT_PRECEDENCE_H_INCLUDED
#include "../core/slang-basic.h"
#include "slang-ir.h"
namespace Slang
{
// Macros for setting up precedence
#define SLANG_PRECEDENCE_LEFT(NAME) \
kEPrecedence_##NAME##_Left, \
kEPrecedence_##NAME##_Right,
#define SLANG_PRECEDENCE_RIGHT(NAME) \
kEPrecedence_##NAME##_Right, \
kEPrecedence_##NAME##_Left,
#define SLANG_PRECEDENCE_NON_ASSOC(NAME) \
kEPrecedence_##NAME##_Left, \
kEPrecedence_##NAME##_Right = kEPrecedence_##NAME##_Left,
#define SLANG_PRECEDENCE_EXPAND(NAME, ASSOC) SLANG_PRECEDENCE_##ASSOC(NAME)
// x macro of precedence of types in order.
// Used because in header, need to prefix macros to avoid clashes, and this style allows for prefixing without additional clutter
#define SLANG_PRECEDENCE(x) \
x(None, NON_ASSOC) \
x(Comma, LEFT) \
\
x(General, NON_ASSOC) \
\
x(Assign, RIGHT) \
\
x(Conditional, RIGHT) \
\
x(Or, LEFT) \
x(And, LEFT) \
x(BitOr, LEFT) \
x(BitXor, LEFT) \
x(BitAnd, LEFT) \
\
x(Equality, LEFT) \
x(Relational, LEFT) \
x(Shift, LEFT) \
x(Additive, LEFT) \
x(Multiplicative, LEFT) \
x(Prefix, RIGHT) \
x(Postfix, LEFT) \
x(Atomic, NON_ASSOC)
// Precedence enum produced from the SLANG_PRECEDENCE macro
enum EPrecedence
{
SLANG_PRECEDENCE(SLANG_PRECEDENCE_EXPAND)
};
// Macro for define OpInfo and an associated enum type. Order or macro parameters is
// Op, OpName, Precedence
#define SLANG_OP_INFO(x) \
x(None, "", None) \
\
x(Comma, ",", Comma) \
\
x(General, "", General) \
\
x(Assign, "=", Assign) \
x(AddAssign, "+=", Assign) \
x(SubAssign, "-=", Assign) \
x(MulAssign, "*=", Assign) \
x(DivAssign, "/=", Assign) \
x(ModAssign, "%=", Assign) \
x(LshAssign, "<<=", Assign) \
x(RshAssign, ">>=", Assign) \
x(OrAssign, "|=", Assign) \
x(AndAssign, "&=", Assign) \
x(XorAssign, "^=", Assign) \
\
x(Conditional, "?:", Conditional) \
\
x(Or, "||", Or) \
x(And, "&&", And) \
x(BitOr, "|", BitOr) \
x(BitXor, "^", BitXor) \
x(BitAnd, "&", BitAnd) \
\
x(Eql, "==", Equality) \
x(Neq, "!=", Equality) \
\
x(Less, "<", Relational) \
x(Greater, ">", Relational) \
x(Leq, "<=", Relational) \
x(Geq, ">=", Relational) \
\
x(Lsh, "<<", Shift) \
x(Rsh, ">>", Shift) \
\
x(Add, "+", Additive) \
x(Sub, "-", Additive) \
\
x(Mul, "*", Multiplicative) \
x(Div, "/", Multiplicative) \
x(Rem, "%", Multiplicative) \
\
x(Prefix, "", Prefix) \
x(Postfix, "", Postfix) \
x(Atomic, "", Atomic) \
\
x(Not, "!", Prefix) \
x(Neg, "-", Prefix) \
x(BitNot, "~", Prefix)
#define SLANG_OP_INFO_ENUM(op, name, precedence) op,
enum class EmitOp
{
SLANG_OP_INFO(SLANG_OP_INFO_ENUM)
CountOf,
};
// Info on an op for emit purposes
struct EmitOpInfo
{
SLANG_FORCE_INLINE static const EmitOpInfo& get(EmitOp inOp) { return s_infos[int(inOp)]; }
char const* op;
EPrecedence leftPrecedence;
EPrecedence rightPrecedence;
static const EmitOpInfo s_infos[int(EmitOp::CountOf)];
};
SLANG_FORCE_INLINE const EmitOpInfo& getInfo(EmitOp op) { return EmitOpInfo::s_infos[int(op)]; }
SLANG_INLINE EmitOpInfo leftSide(EmitOpInfo const& outerPrec, EmitOpInfo const& prec)
{
EmitOpInfo result;
result.op = nullptr;
result.leftPrecedence = outerPrec.leftPrecedence;
result.rightPrecedence = prec.leftPrecedence;
return result;
}
SLANG_INLINE EmitOpInfo rightSide(EmitOpInfo const& prec, EmitOpInfo const& outerPrec)
{
EmitOpInfo result;
result.op = nullptr;
result.leftPrecedence = prec.rightPrecedence;
result.rightPrecedence = outerPrec.rightPrecedence;
return result;
}
EmitOp getEmitOpForOp(IROp op);
// Precedence macros no longer needed
#undef SLANG_PRECEDENCE_EXPAND
#undef SLANG_PRECEDENCE_NON_ASSOC
#undef SLANG_PRECEDENCE_RIGHT
#undef SLANG_PRECEDENCE_LEFT
}
#endif