Tests for signature parser.
This commit is contained in:
@@ -224,6 +224,7 @@ pub struct ArgumentType {
|
|||||||
///
|
///
|
||||||
/// The function signature describes the types of arguments and return values along with other
|
/// The function signature describes the types of arguments and return values along with other
|
||||||
/// details that are needed to call a function correctly.
|
/// details that are needed to call a function correctly.
|
||||||
|
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||||
pub struct Signature {
|
pub struct Signature {
|
||||||
pub argument_types: Vec<ArgumentType>,
|
pub argument_types: Vec<ArgumentType>,
|
||||||
pub return_types: Vec<ArgumentType>,
|
pub return_types: Vec<ArgumentType>,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
// ====--------------------------------------------------------------------------------------====//
|
// ====--------------------------------------------------------------------------------------====//
|
||||||
|
|
||||||
use std::result;
|
use std::result;
|
||||||
|
use std::fmt::{self, Display, Formatter, Write};
|
||||||
use lexer::{self, Lexer, Token};
|
use lexer::{self, Lexer, Token};
|
||||||
use cretonne::{types, repr};
|
use cretonne::{types, repr};
|
||||||
|
|
||||||
@@ -18,6 +19,12 @@ pub struct Error {
|
|||||||
pub message: String,
|
pub message: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Error {
|
||||||
|
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
|
||||||
|
write!(f, "{}: {}", self.location.line_number, self.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub type Result<T> = result::Result<T, Error>;
|
pub type Result<T> = result::Result<T, Error>;
|
||||||
|
|
||||||
pub struct Parser<'a> {
|
pub struct Parser<'a> {
|
||||||
@@ -156,7 +163,7 @@ impl<'a> Parser<'a> {
|
|||||||
fn parse_signature(&mut self) -> Result<types::Signature> {
|
fn parse_signature(&mut self) -> Result<types::Signature> {
|
||||||
let mut sig = types::Signature::new();
|
let mut sig = types::Signature::new();
|
||||||
|
|
||||||
try!(self.match_token(Token::LPar, "expected function signature: '(' args... ')'"));
|
try!(self.match_token(Token::LPar, "expected function signature: ( args... )"));
|
||||||
// signature ::= "(" * [arglist] ")" ["->" retlist] [call_conv]
|
// signature ::= "(" * [arglist] ")" ["->" retlist] [call_conv]
|
||||||
if self.token() != Some(Token::RPar) {
|
if self.token() != Some(Token::RPar) {
|
||||||
sig.argument_types = try!(self.parse_argument_list());
|
sig.argument_types = try!(self.parse_argument_list());
|
||||||
@@ -234,4 +241,27 @@ mod tests {
|
|||||||
assert_eq!(location.line_number, 1);
|
assert_eq!(location.line_number, 1);
|
||||||
assert_eq!(message, "expected argument type");
|
assert_eq!(message, "expected argument type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn signature() {
|
||||||
|
let sig = Parser::new("()").parse_signature().unwrap();
|
||||||
|
assert_eq!(sig.argument_types.len(), 0);
|
||||||
|
assert_eq!(sig.return_types.len(), 0);
|
||||||
|
|
||||||
|
let sig2 = Parser::new("(i8 inreg uext, f32, f64) -> i32 sext, f64")
|
||||||
|
.parse_signature()
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(format!("{}", sig2),
|
||||||
|
"(i8 uext inreg, f32, f64) -> i32 sext, f64");
|
||||||
|
|
||||||
|
// `void` is not recognized as a type by the lexer. It should not appear in files.
|
||||||
|
assert_eq!(format!("{}",
|
||||||
|
Parser::new("() -> void").parse_signature().unwrap_err()),
|
||||||
|
"1: expected argument type");
|
||||||
|
assert_eq!(format!("{}", Parser::new("i8 -> i8").parse_signature().unwrap_err()),
|
||||||
|
"1: expected function signature: ( args... )");
|
||||||
|
assert_eq!(format!("{}",
|
||||||
|
Parser::new("(i8 -> i8").parse_signature().unwrap_err()),
|
||||||
|
"1: expected ')' after function arguments");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user