Skip to content

Commit

Permalink
extract out some FromStr implementations from abstractBril conversions
Browse files Browse the repository at this point in the history
  • Loading branch information
Pat-Lafon committed Sep 5, 2024
1 parent 7bb4e0e commit 276beba
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 98 deletions.
109 changes: 12 additions & 97 deletions bril-rs/src/conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ use std::fmt::Display;

use crate::{
AbstractArgument, AbstractCode, AbstractFunction, AbstractInstruction, AbstractProgram,
AbstractType, Argument, Code, EffectOps, Function, Instruction, Position, Program, Type,
ValueOps,
AbstractType, Argument, Code, Function, Instruction, Position, Program, Type,
};

use thiserror::Error;

// This is a nifty trick to supply a global value for pos when it is not defined
#[cfg(not(feature = "position"))]
#[allow(non_upper_case_globals)]
#[expect(
non_upper_case_globals,
reason = "This is a nifty trick to supply a global value for pos when it is not defined"
)]
const pos: Option<Position> = None;

/// This is the [`std::error::Error`] implementation for `bril_rs`. This crate currently only supports errors from converting between [`AbstractProgram`] and [Program]
Expand Down Expand Up @@ -213,66 +214,7 @@ impl TryFrom<AbstractInstruction> for Instruction {
.map_err(|e: ConversionError| e.add_pos(pos.clone()))?,
#[cfg(feature = "position")]
pos: pos.clone(),
op: match op.as_ref() {
"add" => ValueOps::Add,
"mul" => ValueOps::Mul,
"div" => ValueOps::Div,
"eq" => ValueOps::Eq,
"lt" => ValueOps::Lt,
"gt" => ValueOps::Gt,
"le" => ValueOps::Le,
"ge" => ValueOps::Ge,
"not" => ValueOps::Not,
"and" => ValueOps::And,
"or" => ValueOps::Or,
"call" => ValueOps::Call,
"id" => ValueOps::Id,
"sub" => ValueOps::Sub,
#[cfg(feature = "ssa")]
"phi" => ValueOps::Phi,
#[cfg(feature = "float")]
"fadd" => ValueOps::Fadd,
#[cfg(feature = "float")]
"fsub" => ValueOps::Fsub,
#[cfg(feature = "float")]
"fmul" => ValueOps::Fmul,
#[cfg(feature = "float")]
"fdiv" => ValueOps::Fdiv,
#[cfg(feature = "float")]
"feq" => ValueOps::Feq,
#[cfg(feature = "float")]
"flt" => ValueOps::Flt,
#[cfg(feature = "float")]
"fgt" => ValueOps::Fgt,
#[cfg(feature = "float")]
"fle" => ValueOps::Fle,
#[cfg(feature = "float")]
"fge" => ValueOps::Fge,
#[cfg(feature = "char")]
"ceq" => ValueOps::Ceq,
#[cfg(feature = "char")]
"clt" => ValueOps::Clt,
#[cfg(feature = "char")]
"cgt" => ValueOps::Cgt,
#[cfg(feature = "char")]
"cle" => ValueOps::Cle,
#[cfg(feature = "char")]
"cge" => ValueOps::Cge,
#[cfg(feature = "char")]
"char2int" => ValueOps::Char2int,
#[cfg(feature = "char")]
"int2char" => ValueOps::Int2char,
#[cfg(feature = "memory")]
"alloc" => ValueOps::Alloc,
#[cfg(feature = "memory")]
"load" => ValueOps::Load,
#[cfg(feature = "memory")]
"ptradd" => ValueOps::PtrAdd,
v => {
return Err(ConversionError::InvalidValueOps(v.to_string()))
.map_err(|e| e.add_pos(pos))
}
},
op: op.parse().map_err(|e: ConversionError| e.add_pos(pos))?,
},
AbstractInstruction::Effect {
args,
Expand All @@ -287,28 +229,7 @@ impl TryFrom<AbstractInstruction> for Instruction {
labels,
#[cfg(feature = "position")]
pos: pos.clone(),
op: match op.as_ref() {
"jmp" => EffectOps::Jump,
"br" => EffectOps::Branch,
"call" => EffectOps::Call,
"ret" => EffectOps::Return,
"print" => EffectOps::Print,
"nop" => EffectOps::Nop,
#[cfg(feature = "memory")]
"store" => EffectOps::Store,
#[cfg(feature = "memory")]
"free" => EffectOps::Free,
#[cfg(feature = "speculate")]
"speculate" => EffectOps::Speculate,
#[cfg(feature = "speculate")]
"commit" => EffectOps::Commit,
#[cfg(feature = "speculate")]
"guard" => EffectOps::Guard,
e => {
return Err(ConversionError::InvalidEffectOps(e.to_string()))
.map_err(|e| e.add_pos(pos))
}
},
op: op.parse().map_err(|e: ConversionError| e.add_pos(pos))?,
},
})
}
Expand All @@ -325,21 +246,15 @@ impl TryFrom<Option<AbstractType>> for Type {
impl TryFrom<AbstractType> for Type {
type Error = ConversionError;
fn try_from(value: AbstractType) -> Result<Self, Self::Error> {
Ok(match value {
AbstractType::Primitive(t) if t == "int" => Self::Int,
AbstractType::Primitive(t) if t == "bool" => Self::Bool,
#[cfg(feature = "float")]
AbstractType::Primitive(t) if t == "float" => Self::Float,
#[cfg(feature = "char")]
AbstractType::Primitive(t) if t == "char" => Self::Char,
AbstractType::Primitive(t) => return Err(ConversionError::InvalidPrimitive(t)),
match value {
AbstractType::Primitive(t) => t.parse(),
#[cfg(feature = "memory")]
AbstractType::Parameterized(t, ty) if t == "ptr" => {
Self::Pointer(Box::new((*ty).try_into()?))
Ok(Self::Pointer(Box::new((*ty).try_into()?)))
}
AbstractType::Parameterized(t, ty) => {
return Err(ConversionError::InvalidParameterized(t, ty.to_string()))
Err(ConversionError::InvalidParameterized(t, ty.to_string()))
}
})
}
}
}
1 change: 0 additions & 1 deletion bril-rs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#![warn(missing_docs)]
#![warn(clippy::allow_attributes)]
#![doc = include_str!("../README.md")]
#![allow(clippy::too_many_lines)]

/// Provides the unstructured representation of Bril programs
pub mod abstract_program;
Expand Down
109 changes: 109 additions & 0 deletions bril-rs/src/program.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use std::{
fmt::{self, Display, Formatter},
hash::Hash,
str::FromStr,
};

use serde::{Deserialize, Serialize};

use crate::conversion::ConversionError;

/// Equivalent to a file of bril code
#[cfg_attr(not(feature = "float"), derive(Eq))]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
Expand Down Expand Up @@ -389,6 +392,32 @@ impl Display for EffectOps {
}
}

impl FromStr for EffectOps {
type Err = ConversionError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"jmp" => Self::Jump,
"br" => Self::Branch,
"call" => Self::Call,
"ret" => Self::Return,
"print" => Self::Print,
"nop" => Self::Nop,
#[cfg(feature = "memory")]
"store" => Self::Store,
#[cfg(feature = "memory")]
"free" => Self::Free,
#[cfg(feature = "speculate")]
"speculate" => Self::Speculate,
#[cfg(feature = "speculate")]
"commit" => Self::Commit,
#[cfg(feature = "speculate")]
"guard" => Self::Guard,
e => Err(ConversionError::InvalidEffectOps(e.to_string()))?,
})
}
}

/// <https://capra.cs.cornell.edu/bril/lang/syntax.html#value-operation>
#[derive(Serialize, Deserialize, Debug, Copy, Clone, PartialEq, Eq, Hash)]
#[serde(rename_all = "lowercase")]
Expand Down Expand Up @@ -544,6 +573,70 @@ impl Display for ValueOps {
}
}

impl FromStr for ValueOps {
type Err = ConversionError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"add" => Self::Add,
"mul" => Self::Mul,
"div" => Self::Div,
"eq" => Self::Eq,
"lt" => Self::Lt,
"gt" => Self::Gt,
"le" => Self::Le,
"ge" => Self::Ge,
"not" => Self::Not,
"and" => Self::And,
"or" => Self::Or,
"call" => Self::Call,
"id" => Self::Id,
"sub" => Self::Sub,
#[cfg(feature = "ssa")]
"phi" => Self::Phi,
#[cfg(feature = "float")]
"fadd" => Self::Fadd,
#[cfg(feature = "float")]
"fsub" => Self::Fsub,
#[cfg(feature = "float")]
"fmul" => Self::Fmul,
#[cfg(feature = "float")]
"fdiv" => Self::Fdiv,
#[cfg(feature = "float")]
"feq" => Self::Feq,
#[cfg(feature = "float")]
"flt" => Self::Flt,
#[cfg(feature = "float")]
"fgt" => Self::Fgt,
#[cfg(feature = "float")]
"fle" => Self::Fle,
#[cfg(feature = "float")]
"fge" => Self::Fge,
#[cfg(feature = "char")]
"ceq" => Self::Ceq,
#[cfg(feature = "char")]
"clt" => Self::Clt,
#[cfg(feature = "char")]
"cgt" => Self::Cgt,
#[cfg(feature = "char")]
"cle" => Self::Cle,
#[cfg(feature = "char")]
"cge" => Self::Cge,
#[cfg(feature = "char")]
"char2int" => Self::Char2int,
#[cfg(feature = "char")]
"int2char" => Self::Int2char,
#[cfg(feature = "memory")]
"alloc" => Self::Alloc,
#[cfg(feature = "memory")]
"load" => Self::Load,
#[cfg(feature = "memory")]
"ptradd" => Self::PtrAdd,
v => Err(ConversionError::InvalidValueOps(v.to_string()))?,
})
}
}

/// <https://capra.cs.cornell.edu/bril/lang/syntax.html#type>
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[serde(rename_all = "lowercase")]
Expand Down Expand Up @@ -579,6 +672,22 @@ impl Display for Type {
}
}

impl FromStr for Type {
type Err = ConversionError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"int" => Ok(Self::Int),
"bool" => Ok(Self::Bool),
#[cfg(feature = "float")]
"float" => Ok(Self::Float),
#[cfg(feature = "char")]
"char" => Ok(Self::Char),
_ => Err(ConversionError::InvalidPrimitive(s.to_string())),
}
}
}

/// A JSON number/value
#[cfg_attr(not(feature = "float"), derive(Eq, Hash))]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
Expand Down

0 comments on commit 276beba

Please sign in to comment.