From 41d95c0342fccbec4ed9a2761f6a62d8f6655a70 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Thu, 28 Apr 2016 13:16:13 -0700 Subject: [PATCH] Tests for signature parser. --- src/libcretonne/types.rs | 1 + src/libctonfile/parser.rs | 32 +++++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/libcretonne/types.rs b/src/libcretonne/types.rs index 0aaa30841b..d54b3c51d0 100644 --- a/src/libcretonne/types.rs +++ b/src/libcretonne/types.rs @@ -224,6 +224,7 @@ pub struct ArgumentType { /// /// The function signature describes the types of arguments and return values along with other /// details that are needed to call a function correctly. +#[derive(Clone, PartialEq, Eq, Debug)] pub struct Signature { pub argument_types: Vec, pub return_types: Vec, diff --git a/src/libctonfile/parser.rs b/src/libctonfile/parser.rs index 5069520518..a56d69df00 100644 --- a/src/libctonfile/parser.rs +++ b/src/libctonfile/parser.rs @@ -6,6 +6,7 @@ // ====--------------------------------------------------------------------------------------====// use std::result; +use std::fmt::{self, Display, Formatter, Write}; use lexer::{self, Lexer, Token}; use cretonne::{types, repr}; @@ -18,6 +19,12 @@ pub struct Error { 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 = result::Result; pub struct Parser<'a> { @@ -156,7 +163,7 @@ impl<'a> Parser<'a> { fn parse_signature(&mut self) -> Result { 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] if self.token() != Some(Token::RPar) { sig.argument_types = try!(self.parse_argument_list()); @@ -234,4 +241,27 @@ mod tests { assert_eq!(location.line_number, 1); 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"); + } }