Add FunctionName, Signature to repr::Function.

Simplify the uses in parser.rs to avoid too many module qualifiers.
This commit is contained in:
Jakob Stoklund Olesen
2016-04-28 14:02:16 -07:00
parent 41d95c0342
commit 021bde1191
3 changed files with 55 additions and 24 deletions

View File

@@ -1,7 +1,7 @@
//! Representation of Cretonne IL functions. //! Representation of Cretonne IL functions.
use types::Type; use types::{Type, FunctionName, Signature};
use immediates::*; use immediates::*;
use std::fmt::{self, Display, Formatter, Write}; use std::fmt::{self, Display, Formatter, Write};
use std::u32; use std::u32;
@@ -39,6 +39,12 @@ pub const NO_VALUE: Value = Value(u32::MAX);
/// container for those objects by implementing both `Index<Inst>` and `Index<Ebb>`. /// container for those objects by implementing both `Index<Inst>` and `Index<Ebb>`.
/// ///
pub struct Function { pub struct Function {
/// Name of this function. Mostly used by `.cton` files.
name: FunctionName,
/// Signature of this function.
signature: Signature,
/// Data about all of the instructions in the function. The instructions in this vector is not /// Data about all of the instructions in the function. The instructions in this vector is not
/// necessarily in program order. The `Inst` reference indexes into this vector. /// necessarily in program order. The `Inst` reference indexes into this vector.
instructions: Vec<InstructionData>, instructions: Vec<InstructionData>,
@@ -269,9 +275,11 @@ impl InstructionData {
} }
impl Function { impl Function {
/// Create a new empty function. /// Create a function with the given name and signature.
pub fn new() -> Function { pub fn with_name_signature(name: FunctionName, sig: Signature) -> Function {
Function { Function {
name: name,
signature: sig,
instructions: Vec::new(), instructions: Vec::new(),
extended_basic_blocks: Vec::new(), extended_basic_blocks: Vec::new(),
extended_values: Vec::new(), extended_values: Vec::new(),
@@ -279,6 +287,11 @@ impl Function {
} }
} }
/// Create a new empty, anomymous function.
pub fn new() -> Function {
Self::with_name_signature(FunctionName::new(), Signature::new())
}
/// Resolve an instruction reference. /// Resolve an instruction reference.
pub fn inst(&self, i: Inst) -> &InstructionData { pub fn inst(&self, i: Inst) -> &InstructionData {
&self.instructions[i.0 as usize] &self.instructions[i.0 as usize]

View File

@@ -194,6 +194,12 @@ impl Display for Type {
// //
// ====--------------------------------------------------------------------------------------====// // ====--------------------------------------------------------------------------------------====//
/// The name of a function can be any UTF-8 string.
///
/// Function names are mostly a testing and debugging tool. In partucular, `.cton` files use
/// function names to identify functions.
pub type FunctionName = String;
/// Function argument extension options. /// Function argument extension options.
/// ///
/// On some architectures, small integer function arguments are extended to the width of a /// On some architectures, small integer function arguments are extended to the width of a

View File

@@ -8,7 +8,8 @@
use std::result; use std::result;
use std::fmt::{self, Display, Formatter, Write}; use std::fmt::{self, Display, Formatter, Write};
use lexer::{self, Lexer, Token}; use lexer::{self, Lexer, Token};
use cretonne::{types, repr}; use cretonne::types::{FunctionName, Signature, ArgumentType, ArgumentExtension};
use cretonne::repr::Function;
pub use lexer::Location; pub use lexer::Location;
@@ -51,7 +52,7 @@ impl<'a> Parser<'a> {
} }
/// Parse the entire string into a list of functions. /// Parse the entire string into a list of functions.
pub fn parse(text: &'a str) -> Result<Vec<repr::Function>> { pub fn parse(text: &'a str) -> Result<Vec<Function>> {
Self::new(text).parse_function_list() Self::new(text).parse_function_list()
} }
@@ -113,7 +114,7 @@ impl<'a> Parser<'a> {
/// Parse a list of function definitions. /// Parse a list of function definitions.
/// ///
/// This is the top-level parse function matching the whole contents of a file. /// This is the top-level parse function matching the whole contents of a file.
pub fn parse_function_list(&mut self) -> Result<Vec<repr::Function>> { pub fn parse_function_list(&mut self) -> Result<Vec<Function>> {
let mut list = Vec::new(); let mut list = Vec::new();
while self.token().is_some() { while self.token().is_some() {
list.push(try!(self.parse_function())); list.push(try!(self.parse_function()));
@@ -123,25 +124,36 @@ impl<'a> Parser<'a> {
// Parse a whole function definition. // Parse a whole function definition.
// //
// function ::= * "function" name signature { ... } // function ::= * function-spec "{" preample function-body "}"
// //
fn parse_function(&mut self) -> Result<repr::Function> { fn parse_function(&mut self) -> Result<Function> {
try!(self.match_token(Token::Function, "expected 'function' keyword")); let (name, sig) = try!(self.parse_function_spec());
let mut func = Function::with_name_signature(name, sig);
// function ::= "function" * name signature { ... }
let name = try!(self.parse_function_name());
// function ::= "function" name * signature { ... }
let sig = try!(self.parse_signature());
let mut func = repr::Function::new();
// function ::= function-spec * "{" preample function-body "}"
try!(self.match_token(Token::LBrace, "expected '{' before function body")); try!(self.match_token(Token::LBrace, "expected '{' before function body"));
// function ::= function-spec "{" preample function-body * "}"
try!(self.match_token(Token::RBrace, "expected '}' after function body")); try!(self.match_token(Token::RBrace, "expected '}' after function body"));
Ok(func) Ok(func)
} }
// Parse a function spec.
//
// function-spec ::= * "function" name signature
//
fn parse_function_spec(&mut self) -> Result<(FunctionName, Signature)> {
try!(self.match_token(Token::Function, "expected 'function' keyword"));
// function-spec ::= "function" * name signature
let name = try!(self.parse_function_name());
// function-spec ::= "function" name * signature
let sig = try!(self.parse_signature());
Ok((name, sig))
}
// Parse a function name. // Parse a function name.
// //
// function ::= "function" * name signature { ... } // function ::= "function" * name signature { ... }
@@ -160,8 +172,8 @@ impl<'a> Parser<'a> {
// //
// signature ::= * "(" [arglist] ")" ["->" retlist] [call_conv] // signature ::= * "(" [arglist] ")" ["->" retlist] [call_conv]
// //
fn parse_signature(&mut self) -> Result<types::Signature> { fn parse_signature(&mut self) -> Result<Signature> {
let mut sig = types::Signature::new(); let mut sig = 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]
@@ -182,7 +194,7 @@ impl<'a> Parser<'a> {
// //
// arglist ::= * arg { "," arg } // arglist ::= * arg { "," arg }
// //
fn parse_argument_list(&mut self) -> Result<Vec<types::ArgumentType>> { fn parse_argument_list(&mut self) -> Result<Vec<ArgumentType>> {
let mut list = Vec::new(); let mut list = Vec::new();
// arglist ::= * arg { "," arg } // arglist ::= * arg { "," arg }
@@ -198,10 +210,10 @@ impl<'a> Parser<'a> {
} }
// Parse a single argument type with flags. // Parse a single argument type with flags.
fn parse_argument_type(&mut self) -> Result<types::ArgumentType> { fn parse_argument_type(&mut self) -> Result<ArgumentType> {
// arg ::= * type { flag } // arg ::= * type { flag }
let mut arg = if let Some(Token::Type(t)) = self.token() { let mut arg = if let Some(Token::Type(t)) = self.token() {
types::ArgumentType::new(t) ArgumentType::new(t)
} else { } else {
return Err(self.error("expected argument type")); return Err(self.error("expected argument type"));
}; };
@@ -210,8 +222,8 @@ impl<'a> Parser<'a> {
// arg ::= type * { flag } // arg ::= type * { flag }
while let Some(Token::Identifier(s)) = self.token() { while let Some(Token::Identifier(s)) = self.token() {
match s { match s {
"uext" => arg.extension = types::ArgumentExtension::Uext, "uext" => arg.extension = ArgumentExtension::Uext,
"sext" => arg.extension = types::ArgumentExtension::Sext, "sext" => arg.extension = ArgumentExtension::Sext,
"inreg" => arg.inreg = true, "inreg" => arg.inreg = true,
_ => break, _ => break,
} }