Add FunctionName, Signature to repr::Function.
Simplify the uses in parser.rs to avoid too many module qualifiers.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
|
||||
//! Representation of Cretonne IL functions.
|
||||
|
||||
use types::Type;
|
||||
use types::{Type, FunctionName, Signature};
|
||||
use immediates::*;
|
||||
use std::fmt::{self, Display, Formatter, Write};
|
||||
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>`.
|
||||
///
|
||||
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
|
||||
/// necessarily in program order. The `Inst` reference indexes into this vector.
|
||||
instructions: Vec<InstructionData>,
|
||||
@@ -269,9 +275,11 @@ impl InstructionData {
|
||||
}
|
||||
|
||||
impl Function {
|
||||
/// Create a new empty function.
|
||||
pub fn new() -> Function {
|
||||
/// Create a function with the given name and signature.
|
||||
pub fn with_name_signature(name: FunctionName, sig: Signature) -> Function {
|
||||
Function {
|
||||
name: name,
|
||||
signature: sig,
|
||||
instructions: Vec::new(),
|
||||
extended_basic_blocks: 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.
|
||||
pub fn inst(&self, i: Inst) -> &InstructionData {
|
||||
&self.instructions[i.0 as usize]
|
||||
|
||||
@@ -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.
|
||||
///
|
||||
/// On some architectures, small integer function arguments are extended to the width of a
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
use std::result;
|
||||
use std::fmt::{self, Display, Formatter, Write};
|
||||
use lexer::{self, Lexer, Token};
|
||||
use cretonne::{types, repr};
|
||||
use cretonne::types::{FunctionName, Signature, ArgumentType, ArgumentExtension};
|
||||
use cretonne::repr::Function;
|
||||
|
||||
pub use lexer::Location;
|
||||
|
||||
@@ -51,7 +52,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
/// 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()
|
||||
}
|
||||
|
||||
@@ -113,7 +114,7 @@ impl<'a> Parser<'a> {
|
||||
/// Parse a list of function definitions.
|
||||
///
|
||||
/// 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();
|
||||
while self.token().is_some() {
|
||||
list.push(try!(self.parse_function()));
|
||||
@@ -123,25 +124,36 @@ impl<'a> Parser<'a> {
|
||||
|
||||
// Parse a whole function definition.
|
||||
//
|
||||
// function ::= * "function" name signature { ... }
|
||||
// function ::= * function-spec "{" preample function-body "}"
|
||||
//
|
||||
fn parse_function(&mut self) -> Result<repr::Function> {
|
||||
try!(self.match_token(Token::Function, "expected 'function' keyword"));
|
||||
|
||||
// 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();
|
||||
fn parse_function(&mut self) -> Result<Function> {
|
||||
let (name, sig) = try!(self.parse_function_spec());
|
||||
let mut func = Function::with_name_signature(name, sig);
|
||||
|
||||
// function ::= function-spec * "{" preample 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"));
|
||||
|
||||
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.
|
||||
//
|
||||
// function ::= "function" * name signature { ... }
|
||||
@@ -160,8 +172,8 @@ impl<'a> Parser<'a> {
|
||||
//
|
||||
// signature ::= * "(" [arglist] ")" ["->" retlist] [call_conv]
|
||||
//
|
||||
fn parse_signature(&mut self) -> Result<types::Signature> {
|
||||
let mut sig = types::Signature::new();
|
||||
fn parse_signature(&mut self) -> Result<Signature> {
|
||||
let mut sig = Signature::new();
|
||||
|
||||
try!(self.match_token(Token::LPar, "expected function signature: ( args... )"));
|
||||
// signature ::= "(" * [arglist] ")" ["->" retlist] [call_conv]
|
||||
@@ -182,7 +194,7 @@ impl<'a> Parser<'a> {
|
||||
//
|
||||
// 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();
|
||||
|
||||
// arglist ::= * arg { "," arg }
|
||||
@@ -198,10 +210,10 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
// 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 }
|
||||
let mut arg = if let Some(Token::Type(t)) = self.token() {
|
||||
types::ArgumentType::new(t)
|
||||
ArgumentType::new(t)
|
||||
} else {
|
||||
return Err(self.error("expected argument type"));
|
||||
};
|
||||
@@ -210,8 +222,8 @@ impl<'a> Parser<'a> {
|
||||
// arg ::= type * { flag }
|
||||
while let Some(Token::Identifier(s)) = self.token() {
|
||||
match s {
|
||||
"uext" => arg.extension = types::ArgumentExtension::Uext,
|
||||
"sext" => arg.extension = types::ArgumentExtension::Sext,
|
||||
"uext" => arg.extension = ArgumentExtension::Uext,
|
||||
"sext" => arg.extension = ArgumentExtension::Sext,
|
||||
"inreg" => arg.inreg = true,
|
||||
_ => break,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user