[wgsl-in] eagerly evaluate const-expressions

[wgsl-in] support const-expressions in attributes

allow `Splat` as an evaluated const-expression type
This commit is contained in:
teoxoy
2023-04-19 14:55:07 +02:00
committed by Teodor Tanasoaia
parent c5d884fca8
commit a730236b68
44 changed files with 2917 additions and 2770 deletions

View File

@@ -1795,7 +1795,7 @@ impl MacroCall {
true => {
let offset_arg = args[num_args];
num_args += 1;
match ctx.solve_constant(offset_arg, meta) {
match ctx.eval_constant(offset_arg, meta) {
Ok(v) => Some(v),
Err(e) => {
frontend.errors.push(e);

File diff suppressed because it is too large Load Diff

View File

@@ -519,7 +519,7 @@ impl<'a> Context<'a> {
// Don't try to generate `AccessIndex` if in a LHS position, since it
// wouldn't produce a pointer.
ExprPos::Lhs => None,
_ => self.solve_constant(index, index_meta).ok(),
_ => self.eval_constant(index, index_meta).ok(),
};
let base = self

View File

@@ -1,5 +1,5 @@
use super::{constants::ConstantSolvingError, token::TokenValue};
use crate::Span;
use super::token::TokenValue;
use crate::{proc::ConstantEvaluatorError, Span};
use pp_rs::token::PreprocessorError;
use std::borrow::Cow;
use thiserror::Error;
@@ -116,8 +116,8 @@ pub enum ErrorKind {
InternalError(&'static str),
}
impl From<ConstantSolvingError> for ErrorKind {
fn from(err: ConstantSolvingError) -> Self {
impl From<ConstantEvaluatorError> for ErrorKind {
fn from(err: ConstantEvaluatorError) -> Self {
ErrorKind::SemanticError(err.to_string().into())
}
}

View File

@@ -22,7 +22,6 @@ use parser::ParsingContext;
mod ast;
mod builtins;
mod constants;
mod context;
mod error;
mod functions;

View File

@@ -226,7 +226,7 @@ impl<'source> ParsingContext<'source> {
let expr = self.parse_conditional(frontend, &mut ctx, &mut stmt_ctx, None)?;
let (root, meta) = ctx.lower_expect(stmt_ctx, frontend, expr, ExprPos::Rhs)?;
Ok((ctx.solve_constant(root, meta)?, meta))
Ok((ctx.eval_constant(root, meta)?, meta))
}
}

View File

@@ -241,7 +241,7 @@ impl<'source> ParsingContext<'source> {
let is_const = ctx.qualifiers.storage.0 == StorageQualifier::Const;
let maybe_const_expr = if ctx.external {
if let Some((root, meta)) = init {
match ctx.ctx.solve_constant(root, meta) {
match ctx.ctx.eval_constant(root, meta) {
Ok(res) => Some(res),
// If the declaration is external (global scope) and is constant qualified
// then the initializer must be a constant expression

View File

@@ -187,11 +187,8 @@ impl<'source> ParsingContext<'source> {
TokenValue::Case => {
self.bump(frontend)?;
let mut stmt = ctx.stmt_ctx();
let expr = self.parse_expression(frontend, ctx, &mut stmt)?;
let (root, meta) =
ctx.lower_expect(stmt, frontend, expr, ExprPos::Rhs)?;
let const_expr = ctx.solve_constant(root, meta)?;
let (const_expr, meta) =
self.parse_constant_expression(frontend, ctx.module)?;
match ctx.module.const_expressions[const_expr] {
Expression::Literal(Literal::I32(value)) => match uint {

View File

@@ -1,4 +1,4 @@
use super::{constants::ConstantSolver, context::Context, Error, ErrorKind, Result, Span};
use super::{context::Context, Error, ErrorKind, Result, Span};
use crate::{
proc::ResolveContext, Bytes, Expression, Handle, ImageClass, ImageDimension, ScalarKind, Type,
TypeInner, VectorSize,
@@ -305,19 +305,28 @@ impl Context<'_> {
})
}
pub(crate) fn solve_constant(
pub(crate) fn eval_constant(
&mut self,
root: Handle<Expression>,
meta: Span,
) -> Result<Handle<Expression>> {
let mut solver = ConstantSolver {
let mut solver = crate::proc::ConstantEvaluator {
types: &mut self.module.types,
expressions: &self.expressions,
expressions: &mut self.module.const_expressions,
constants: &mut self.module.constants,
const_expressions: &mut self.module.const_expressions,
const_expressions: Some(&self.expressions),
append: None::<
Box<
dyn FnMut(
&mut crate::Arena<Expression>,
Expression,
Span,
) -> Handle<Expression>,
>,
>,
};
solver.solve(root).map_err(|e| Error {
solver.eval(root).map_err(|e| Error {
kind: e.into(),
meta,
})