Skip to content
This repository has been archived by the owner on Jan 29, 2025. It is now read-only.

Commit

Permalink
Check constant types (#54)
Browse files Browse the repository at this point in the history
* Check constant types

A baby step towards #43

* Move tp src/proc/typifier, remove unneeded return

* Don't do pub(crate)

* Don't use crate::proc::UnexpectedConstantTypeError

Co-authored-by: Paul Kernfeld <[email protected]>
  • Loading branch information
paulkernfeld and Paul Kernfeld authored May 22, 2020
1 parent 2a3fc6d commit b108a50
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 2 deletions.
23 changes: 23 additions & 0 deletions src/front/wgsl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ mod lex {
#[derive(Debug)]
pub enum Error<'a> {
Unexpected(Token<'a>),
UnexpectedConstantType(crate::proc::UnexpectedConstantTypeError),
BadInteger(&'a str, std::num::ParseIntError),
BadFloat(&'a str, std::num::ParseFloatError),
BadAccessor(&'a str),
Expand All @@ -158,6 +159,12 @@ pub enum Error<'a> {
Other,
}

impl<'a> From<crate::proc::UnexpectedConstantTypeError> for Error<'a> {
fn from(error: crate::proc::UnexpectedConstantTypeError) -> Self {
Error::UnexpectedConstantType(error)
}
}

#[derive(Clone)]
struct Lexer<'a> {
input: &'a str,
Expand Down Expand Up @@ -1300,6 +1307,7 @@ impl Parser {
lexer.expect(Token::Operation('='))?;
let inner = self.parse_const_expression(lexer, &mut module.types, &mut module.constants)?;
lexer.expect(Token::Separator(';'))?;
crate::proc::check_constant_types(&inner, &module.types[ty].inner)?;
let const_handle = module.constants.append(crate::Constant {
name: Some(name.to_owned()),
specialization: None,
Expand Down Expand Up @@ -1400,3 +1408,18 @@ impl Parser {
pub fn parse_str(source: &str) -> Result<crate::Module, ParseError> {
Parser::new().parse(source)
}

#[cfg(test)]
mod tests {
#[test]
fn check_constant_type_scalar_ok() {
let wgsl = "const a : i32 = 2;";
assert!(super::parse_str(wgsl).is_ok());
}

#[test]
fn check_constant_type_scalar_err() {
let wgsl = "const a : i32 = 2.0;";
assert!(super::parse_str(wgsl).is_err());
}
}
3 changes: 2 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,8 @@ pub struct Constant {
pub ty: Handle<Type>,
}

#[derive(Debug, PartialEq)]
// Clone is used only for error reporting and is not intended for end users
#[derive(Clone, Debug, PartialEq)]
pub enum ConstantInner {
Sint(i64),
Uint(u64),
Expand Down
2 changes: 1 addition & 1 deletion src/proc/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
mod interface;
mod typifier;

pub use typifier::{ResolveError, Typifier};
pub use typifier::{ResolveError, Typifier, UnexpectedConstantTypeError, check_constant_types};
35 changes: 35 additions & 0 deletions src/proc/typifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,38 @@ impl Typifier {
})
}
}

#[derive(Debug)]
pub struct UnexpectedConstantTypeError(crate::ConstantInner, crate::TypeInner);

pub fn check_constant_types(
inner: &crate::ConstantInner,
type_inner: &crate::TypeInner
) -> Result<(), UnexpectedConstantTypeError> {
match (inner, type_inner) {
(
crate::ConstantInner::Sint(_),
crate::TypeInner::Scalar { kind: crate::ScalarKind::Sint, width: _ },
) => Ok(()),
(
crate::ConstantInner::Uint(_),
crate::TypeInner::Scalar { kind: crate::ScalarKind::Uint, width: _ },
) => Ok(()),
(
crate::ConstantInner::Float(_),
crate::TypeInner::Scalar { kind: crate::ScalarKind::Float, width: _ },
) => Ok(()),
(
crate::ConstantInner::Bool(_),
crate::TypeInner::Scalar { kind: crate::ScalarKind::Bool, width: _ },
) => Ok(()),
(
crate::ConstantInner::Composite(_inner),
_
) => Ok(()), // TODO recursively check composite types
(other_inner, other_type_inner) => Err(UnexpectedConstantTypeError(
other_inner.clone(),
other_type_inner.clone(),
)),
}
}

0 comments on commit b108a50

Please sign in to comment.