Glsl new handle version (#109)

* Fix TokenMetadata for #version

* Add glsl-new #version parsing

* Fix clippy issues

* glsl-new only core profile, allow 440-460

* Cleanup glsl-new profile matching
This commit is contained in:
Pelle Johnsen
2020-07-13 19:40:12 +02:00
committed by GitHub
parent e55c6b56e2
commit 244c587457
7 changed files with 107 additions and 10 deletions

View File

@@ -23,9 +23,7 @@ impl Program {
#[derive(Debug)]
pub enum Profile {
// Compatibility,
Core,
// Es,
}
#[derive(Debug)]

View File

@@ -1,12 +1,15 @@
use super::parser::Token;
use super::token::TokenMetadata;
use std::{fmt, io};
#[derive(Debug)]
pub enum ErrorKind {
InvalidInput,
IoError(io::Error),
InvalidToken(Token),
EndOfFile,
InvalidInput,
InvalidProfile(TokenMetadata, String),
InvalidToken(Token),
InvalidVersion(TokenMetadata, i64),
IoError(io::Error),
ParserFail,
ParserStackOverflow,
}
@@ -14,10 +17,16 @@ pub enum ErrorKind {
impl fmt::Display for ErrorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ErrorKind::InvalidInput => write!(f, "InvalidInput"),
ErrorKind::IoError(error) => write!(f, "IO Error {}", error),
ErrorKind::InvalidToken(token) => write!(f, "Invalid Token {:?}", token),
ErrorKind::EndOfFile => write!(f, "Unexpected end of file"),
ErrorKind::InvalidInput => write!(f, "InvalidInput"),
ErrorKind::InvalidProfile(meta, val) => {
write!(f, "Invalid profile {} at {:?}", val, meta)
}
ErrorKind::InvalidToken(token) => write!(f, "Invalid Token {:?}", token),
ErrorKind::InvalidVersion(meta, val) => {
write!(f, "Invalid version {} at {:?}", val, meta)
}
ErrorKind::IoError(error) => write!(f, "IO Error {}", error),
ErrorKind::ParserFail => write!(f, "Parser failed"),
ErrorKind::ParserStackOverflow => write!(f, "Parser stack overflow"),
}

View File

@@ -206,7 +206,7 @@ pub fn consume_token(mut input: &str) -> (Option<Token>, &str) {
'#' => {
input = chars.as_str();
let (word, rest, pos) = consume_any(input, |c| c.is_alphanumeric() || c == '_');
meta.chars.end = start + pos;
meta.chars.end = start + 1 + pos;
match word {
"version" => (Some(Token::Version(meta)), rest),
_ => (None, input),

View File

@@ -136,3 +136,25 @@ fn glsl_lex_identifier() {
"Unknown((TokenMetadata { line: 0, chars: 25..26 }, \'\'))"
);
}
#[test]
fn glsl_lex_version() {
let source = "#version 890 core";
let lex = Lexer::new(source);
let tokens: Vec<Token> = lex.collect();
assert_eq!(tokens.len(), 3);
let mut iter = tokens.iter();
assert_eq!(
format!("{:?}", iter.next().unwrap()),
"Version(TokenMetadata { line: 0, chars: 0..8 })"
);
assert_eq!(
format!("{:?}", iter.next().unwrap()),
"IntConstant((TokenMetadata { line: 0, chars: 9..12 }, 890))"
);
assert_eq!(
format!("{:?}", iter.next().unwrap()),
"Identifier((TokenMetadata { line: 0, chars: 13..17 }, \"core\"))"
);
}

View File

@@ -11,6 +11,8 @@ use lex::Lexer;
mod error;
use error::ParseError;
mod parser;
#[cfg(test)]
mod parser_tests;
mod token;
pub fn parse_str(source: &str, entry: String, stage: ShaderStage) -> Result<Module, ParseError> {

View File

@@ -41,7 +41,24 @@ pomelo! {
%type function_definition Function;
root ::= version_pragma translation_unit;
version_pragma ::= Version IntConstant Identifier?;
version_pragma ::= Version IntConstant(V) Identifier?(P) {
match V.1 {
440 => (),
450 => (),
460 => (),
_ => return Err(ErrorKind::InvalidVersion(V.0, V.1))
}
extra.version = V.1 as u16;
extra.profile = match P {
Some((meta, profile)) => {
match profile.as_str() {
"core" => Profile::Core,
_ => return Err(ErrorKind::InvalidProfile(meta, profile))
}
},
None => Profile::Core,
}
};
// expression
variable_identifier ::= Identifier;

View File

@@ -0,0 +1,49 @@
use super::ast::Program;
use super::error::ErrorKind;
use super::lex::Lexer;
use super::parser;
fn parse_program(source: &str) -> Result<Program, ErrorKind> {
let mut program = Program::new();
let lex = Lexer::new(source);
let mut parser = parser::Parser::new(&mut program);
for token in lex {
parser.parse(token)?;
}
parser.end_of_input()?;
Ok(program)
}
#[test]
fn glsl_parser_version_invalid() {
assert_eq!(
format!("{:?}", parse_program("#version 99000").err().unwrap()),
"InvalidVersion(TokenMetadata { line: 0, chars: 9..14 }, 99000)"
);
assert_eq!(
format!("{:?}", parse_program("#version 449").err().unwrap()),
"InvalidVersion(TokenMetadata { line: 0, chars: 9..12 }, 449)"
);
assert_eq!(
format!("{:?}", parse_program("#version 450 smart").err().unwrap()),
"InvalidProfile(TokenMetadata { line: 0, chars: 13..18 }, \"smart\")"
);
}
#[test]
fn glsl_parser_version_valid() {
let program = parse_program("#version 450\nvoid main() {}").unwrap();
assert_eq!(
format!("{:?}", (program.version, program.profile)),
"(450, Core)"
);
let program = parse_program("#version 450 core\nvoid main() {}").unwrap();
assert_eq!(
format!("{:?}", (program.version, program.profile)),
"(450, Core)"
);
}