spirv_utils/parse/
mod.rs

1// Copyright 2016 James Miller
2//
3// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6// option. This file may not be copied, modified, or distributed
7// except according to those terms.
8
9use std::{self, fmt, error};
10use std::io;
11
12use desc::Id;
13
14mod parser;
15mod read;
16
17pub use self::read::Reader;
18pub use self::parser::parse_raw_instruction;
19
20
21#[derive(Clone, Debug)]
22pub struct RawInstruction {
23    pub opcode: u16,
24    pub params: Vec<u32>
25}
26
27#[derive(Clone, Debug)]
28pub struct Header {
29    pub version: (u8, u8),
30    pub generator_id: u32,
31    pub id_bound: u32
32}
33
34
35pub type Result<T> = std::result::Result<T, ParseError>;
36
37#[derive(Debug)]
38pub enum ParseError {
39    DuplicateId(Id, usize),
40    UnknownOpcode(u16),
41    IdOutOfRange(Id),
42    InvalidParamValue(u32, &'static str),
43    InstructionTooShort,
44    IoError(io::Error),
45    InvalidMagicNumber(u32)
46}
47
48impl From<io::Error> for ParseError {
49    fn from(e: io::Error) -> ParseError {
50        ParseError::IoError(e)
51    }
52}
53
54impl fmt::Display for ParseError {
55    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
56        use self::ParseError::*;
57
58        try!(f.write_str("Error while parsing: "));
59        match *self {
60            DuplicateId(id, idx) => {
61                write!(f, "duplicate definition of id `{:?}` at instruction {}",
62                       id, idx)
63            }
64            UnknownOpcode(op) => {
65                write!(f, "unknown opcode value `{}`", op)
66            }
67            IdOutOfRange(id) => {
68                write!(f, "id `{:?}` is outside valid range", id)
69            }
70            InvalidParamValue(val, ty) => {
71                write!(f, "invalid value `{}` for parameter of type {}",
72                       val, ty)
73            }
74            InstructionTooShort => f.write_str("instruction is too short"),
75            IoError(ref e) => fmt::Display::fmt(e, f),
76            InvalidMagicNumber(n) => {
77                write!(f, "invalid magic number: {:#08x}", n)
78            }
79        }
80    }
81}
82
83impl error::Error for ParseError {
84    fn description(&self) -> &str {
85        use self::ParseError::*;
86        match *self {
87            DuplicateId(_, _) => "duplicate id definition",
88            UnknownOpcode(_) => "unknown instruction opcode",
89            IdOutOfRange(_) => "id outside valid range",
90            InvalidParamValue(_, _) => "parameter value not valid for type",
91            InstructionTooShort => "instruction is too short",
92            IoError(ref e) => e.description(),
93            InvalidMagicNumber(_) => "invalid magic number"
94        }
95    }
96
97    fn cause(&self) -> Option<&error::Error> {
98        use self::ParseError::*;
99        match *self {
100            IoError(ref e) => Some(e),
101            _ => None
102        }
103    }
104}