diff --git a/generation/src/Base.hs b/generation/src/Base.hs index 1009133..fe52a76 100644 --- a/generation/src/Base.hs +++ b/generation/src/Base.hs @@ -33,7 +33,7 @@ declareBaseStructure bitsize = #[derive(Clone)] pub struct $$sname { - value: [u64; $$(entriese)] + pub(crate) value: [u64; $$(entriese)] } impl fmt::Debug for $$sname { @@ -59,7 +59,7 @@ declareBaseStructure bitsize = impl Arbitrary for $$sname { fn arbitrary(g: &mut G) -> Self { let mut res = $$sname{ value: [0; $$(entriese)] }; - for entry in res.iter_mut() { + for entry in res.value.iter_mut() { *entry = g.next_u64(); } res diff --git a/generation/src/BinaryOps.hs b/generation/src/BinaryOps.hs index 7181bd2..6a8e5aa 100644 --- a/generation/src/BinaryOps.hs +++ b/generation/src/BinaryOps.hs @@ -5,6 +5,7 @@ module BinaryOps( where import File +import Gen(toLit) import Language.Rust.Data.Ident import Language.Rust.Data.Position import Language.Rust.Quote @@ -51,15 +52,16 @@ declareBinaryOperators bitsize = } impl<'a> Not for &'a $$struct_name { - type Output = Self; + type Output = $$struct_name; - fn not(self) -> Self { + fn not(self) -> Self::Output { let mut output = self.clone(); $@{refNegationStmts} output } } + #[cfg(test)] quickcheck! { fn and_associative(a: $$struct_name, b: $$struct_name, c: $$struct_name) -> bool { ((&a & &b) & &c) == (&a & (&b & &c)) @@ -92,10 +94,10 @@ declareBinaryOperators bitsize = (&a & (&b | &c)) == ((&a & &b) | (&a & &c)) } fn xor_clears(a: $$struct_name) -> bool { - $$struct_name::zero() == (&a ^ *a) + $$struct_name::zero() == (&a ^ &a) } fn double_neg_ident(a: $$struct_name) -> bool { - a == !!$a + a == !!&a } fn and_ident(a: $$struct_name) -> bool { let ones = !$$struct_name::zero(); @@ -111,13 +113,14 @@ negationStatements :: String -> Word -> [Stmt Span] negationStatements target entries = map genStatement [0..entries-1] where genStatement i = - let idx = Lit [] (Int Dec (fromIntegral i) Unsuffixed mempty) mempty + let idx = toLit i v = mkIdent target in [stmt| $$v.value[$$(idx)] = !self.value[$$(idx)]; |] generateBinOps :: String -> Ident -> String -> BinOp -> Word -> [Item Span] generateBinOps trait sname func oper entries = - [normAssign, refAssign] ++ generateAllTheVariants traitIdent funcIdent sname oper + [normAssign, refAssign] ++ + generateAllTheVariants traitIdent funcIdent sname oper entries where traitIdent = mkIdent trait assignIdent = mkIdent (trait ++ "Assign") @@ -132,7 +135,7 @@ generateBinOps trait sname func oper entries = } |] refAssign = [item| - impl $$assignIdent<&'a $$sname> for $$sname { + impl<'a> $$assignIdent<&'a $$sname> for $$sname { fn $$funcAssignIdent(&mut self, rhs: &Self) { $@{assignStatements} } @@ -142,54 +145,57 @@ generateBinOps trait sname func oper entries = assignStatements :: [Stmt Span] assignStatements = map genAssign [0..entries-1] genAssign i = - let idx = Lit [] (Int Dec (fromIntegral i) Unsuffixed mempty) mempty + let idx = toLit i left = [expr| self.value[$$(idx)] |] right = [expr| rhs.value[$$(idx)] |] in Semi (AssignOp [] oper left right mempty) mempty -generateAllTheVariants :: Ident -> Ident -> Ident -> BinOp -> [Item Span] -generateAllTheVariants traitname func sname oper = [ +generateAllTheVariants :: Ident -> Ident -> Ident -> BinOp -> Word -> [Item Span] +generateAllTheVariants traitname func sname oper entries = [ [item| impl $$traitname for $$sname { - type Output = Self; + type Output = $$sname; - fn $$func(mut self, rhs: Self) -> Self { - $${assigner_self_rhs} + fn $$func(mut self, rhs: $$sname) -> Self::Output { + $@{assigners_self_rhs} self } }|] , [item| impl<'a> $$traitname<&'a $$sname> for $$sname { - type Output = Self; + type Output = $$sname; - fn $$func(mut self, rhs: Self) -> Self { - $${assigner_self_rhs} + fn $$func(mut self, rhs: &$$sname) -> Self::Output { + $@{assigners_self_rhs} self } }|] , [item| - impl<'a> $$traitname for &'a $$sname { - type Output = Self; + impl<'a> $$traitname<$$sname> for &'a $$sname { + type Output = $$sname; - fn $$func(mut self, rhs: Self) -> Self { - $${assigner_rhs_self} - self + fn $$func(self, mut rhs: $$sname) -> Self::Output { + $@{assigners_rhs_self} + rhs } }|] , [item| impl<'a,'b> $$traitname<&'a $$sname> for &'b $$sname { - type Output = Self; + type Output = $$sname; - fn $$func(mut self, rhs: Self) -> Self { + fn $$func(self, rhs: &$$sname) -> Self::Output { let mut out = self.clone(); - $${assigner_out_rhs} + $@{assigners_out_rhs} out } }|] ] where - assigner_self_rhs = assigner [expr| self |] [expr| rhs |] - assigner_rhs_self = assigner [expr| rhs |] [expr| self |] - assigner_out_rhs = assigner [expr| out |] [expr| rhs |] - assigner left right = - Semi (AssignOp [] oper left right mempty) mempty + assigners_self_rhs = assigners [expr| self |] [expr| rhs |] + assigners_rhs_self = assigners [expr| rhs |] [expr| self |] + assigners_out_rhs = assigners [expr| out |] [expr| rhs |] + assigners left right = map (genAssign left right . toLit) [0..entries-1] + genAssign left right i = + Semi (AssignOp [] oper [expr| $$(left).value[$$(i)] |] + [expr| $$(right).value[$$(i)] |] + mempty) mempty diff --git a/generation/src/Conversions.hs b/generation/src/Conversions.hs index 556663a..ec5e8ab 100644 --- a/generation/src/Conversions.hs +++ b/generation/src/Conversions.hs @@ -34,7 +34,7 @@ declareConversions bitsize = i128_prims = generateI128Primitives sname in [sourceFile| use core::convert::{From,TryFrom}; - use core::num::TryFromIntError; + use crate::CryptoNum; #[cfg(test)] use quickcheck::quickcheck; use super::$$sname; @@ -57,9 +57,9 @@ generateU128Primitives :: Ident -> Word -> [Item Span] generateU128Primitives sname entries = [ [item|impl From for $$sname { fn from(x: u128) -> Self { - let mut res = $$sname::zero; - res[0] = x as u64; - res[1] = (x >> 64) as u64; + let mut res = $$sname::zero(); + res.value[0] = x as u64; + res.value[1] = (x >> 64) as u64; res } }|] @@ -67,17 +67,17 @@ generateU128Primitives sname entries = [ type Error = ConversionError; fn try_from(x: $$sname) -> Result { - let mut goodConversion = true; - let mut res = 0; + let mut good_conversion = true; + let mut res; - res = (x.values[1] as u128) << 64; - res |= x.values[0] as u128; + res = (x.value[1] as u128) << 64; + res |= x.value[0] as u128; $@{testZeros} - if goodConversion { + if good_conversion { Ok(res) } else { - Err(ConversionError::Overflow); + Err(ConversionError::Overflow) } } }|] @@ -85,17 +85,17 @@ generateU128Primitives sname entries = [ type Error = ConversionError; fn try_from(x: &$$sname) -> Result { - let mut goodConversion = true; - let mut res = 0; + let mut good_conversion = true; + let mut res; - res = (x.values[1] as u128) << 64; - res |= x.values[0] as u128; + res = (x.value[1] as u128) << 64; + res |= x.value[0] as u128; $@{testZeros} - if goodConversion { + if good_conversion { Ok(res) } else { - Err(ConversionError::Overflow()); + Err(ConversionError::Overflow) } } }|] @@ -103,14 +103,14 @@ generateU128Primitives sname entries = [ where testZeros = map (zeroTest . toLit) [2..entries-1] zeroTest i = - [stmt| goodConversion &= x.values[$$(i)] == 0; |] + [stmt| good_conversion &= x.value[$$(i)] == 0; |] buildPrimitives :: Ident -> Ident -> Word -> [Item Span] buildPrimitives sname tname entries = [ [item|impl From<$$tname> for $$sname { fn from(x: $$tname) -> Self { let mut res = $$sname::zero(); - res.values[0] = x as u64; + res.value[0] = x as u64; res } }|] @@ -118,13 +118,11 @@ buildPrimitives sname tname entries = [ type Error = ConversionError; fn try_from(x: $$sname) -> Result { - let mut goodConversion = true; - let mut res = 0; - - res = x.values[0] as $$tname; + let mut good_conversion = true; + let res = x.value[0] as $$tname; $@{testZeros} - if goodConversion { + if good_conversion { Ok(res) } else { Err(ConversionError::Overflow) @@ -135,13 +133,11 @@ buildPrimitives sname tname entries = [ type Error = ConversionError; fn try_from(x: &$$sname) -> Result { - let mut goodConversion = true; - let mut res = 0; - - res = x.values[0] as $$tname; + let mut good_conversion = true; + let res = x.value[0] as $$tname; $@{testZeros} - if goodConversion { + if good_conversion { Ok(res) } else { Err(ConversionError::Overflow) @@ -152,7 +148,7 @@ buildPrimitives sname tname entries = [ where testZeros = map (zeroTest . toLit) [1..entries-1] zeroTest i = - [stmt| goodConversion &= x.values[$$(i)] == 0; |] + [stmt| good_conversion &= x.value[$$(i)] == 0; |] generateSignedPrims :: Ident -> Ident -> Ident -> [Item Span] generateSignedPrims sname unsigned signed = [ @@ -161,7 +157,7 @@ generateSignedPrims sname unsigned signed = [ fn try_from(x: $$signed) -> Result { let mut res = $$sname::zero(); - res.values[0] = x as u64; + res.value[0] = x as u64; if x < 0 { Err(ConversionError::NegativeToUnsigned) } else { @@ -173,7 +169,7 @@ generateSignedPrims sname unsigned signed = [ type Error = ConversionError; fn try_from(x: $$sname) -> Result { - let uns = $$unsigned::from(x)?; + let uns = $$unsigned::try_from(x)?; Ok($$signed::try_from(uns)?) } }|] @@ -181,7 +177,7 @@ generateSignedPrims sname unsigned signed = [ type Error = ConversionError; fn try_from(x: &$$sname) -> Result { - let uns = $$unsigned::from(x)?; + let uns = $$unsigned::try_from(x)?; Ok($$signed::try_from(uns)?) } }|] @@ -194,8 +190,8 @@ generateI128Primitives sname = [ fn try_from(x: i128) -> Result { let mut res = $$sname::zero(); - res.values[0] = x as u64; - res.values[1] = ((x as u128) >> 64) as u64; + res.value[0] = x as u64; + res.value[1] = ((x as u128) >> 64) as u64; if x < 0 { Err(ConversionError::NegativeToUnsigned) } else { @@ -207,7 +203,7 @@ generateI128Primitives sname = [ type Error = ConversionError; fn try_from(x: $$sname) -> Result { - let uns = u128::from(x)?; + let uns = u128::try_from(x)?; Ok(i128::try_from(uns)?) } }|] @@ -215,7 +211,7 @@ generateI128Primitives sname = [ type Error = ConversionError; fn try_from(x: &$$sname) -> Result { - let uns = u128::from(x)?; + let uns = u128::try_from(x)?; Ok(i128::try_from(uns)?) } }|] diff --git a/generation/src/CryptoNum.hs b/generation/src/CryptoNum.hs index 0512188..e498f40 100644 --- a/generation/src/CryptoNum.hs +++ b/generation/src/CryptoNum.hs @@ -27,7 +27,7 @@ declareCryptoNumInstance bitsize = bitlength = toLit bitsize bytelen = bitsize `div` 8 bytelenlit = toLit bytelen - bytebuffer = Delimited mempty Brace (Stream [ + bytebuffer = Delimited mempty Bracket (Stream [ Tree (Token mempty (LiteralTok (IntegerTok "0") Nothing)), Tree (Token mempty Semicolon), Tree (Token mempty (LiteralTok (IntegerTok (show bytelen)) Nothing)) @@ -54,7 +54,7 @@ declareCryptoNumInstance bitsize = fn is_even(&self) -> bool { self.value[0] & 0x1 == 0 } - fn is_off(&self) -> bool { + fn is_odd(&self) -> bool { self.value[0] & 0x1 == 1 } fn bit_length() -> usize { @@ -100,8 +100,8 @@ declareCryptoNumInstance bitsize = let mut idx = 0; let mut shift = 0; - for x in bytes.iter_mut().take($$(bytelenlit)).reverse() { - *x = (self.values[idx] >> shift) as u8; + for x in bytes.iter_mut().take($$(bytelenlit)).rev() { + *x = (self.value[idx] >> shift) as u8; shift += 8; if shift == 64 { idx += 1; @@ -143,5 +143,5 @@ generateZeroTests i entries | i == entries = [] | otherwise = let ilit = toLit i - in [stmt| result = self.values[$$(ilit)] == 0; |] : + in [stmt| result &= self.value[$$(ilit)] == 0; |] : generateZeroTests (i + 1) entries diff --git a/generation/src/Main.hs b/generation/src/Main.hs index f8fd695..30e63e4 100644 --- a/generation/src/Main.hs +++ b/generation/src/Main.hs @@ -9,11 +9,12 @@ import CryptoNum(cryptoNum) import Control.Monad(forM_,unless) import Data.Maybe(mapMaybe) import File(File,Task(..),addModuleTasks,makeTask) -import Language.Rust.Pretty(prettyAnnotated') +import Language.Rust.Pretty(writeSourceFile) import System.Directory(createDirectoryIfMissing) import System.Environment(getArgs) import System.Exit(die) import System.FilePath(takeDirectory,()) +import System.IO(IOMode(..),hPutStrLn,withFile) lowestBitsize :: Word lowestBitsize = 192 @@ -56,4 +57,7 @@ main = forM_ (zip [(1::Word)..] tasks) $ \ (i, task) -> do putStrLn ("[" ++ show i ++ "/" ++ show total ++ "] " ++ outputFile task) createDirectoryIfMissing True (takeDirectory (outputFile task)) - writeFile (outputFile task) (show (prettyAnnotated' (fileData task))) + withFile (outputFile task) WriteMode $ \ targetHandle -> + do hPutStrLn targetHandle + "// WARNING: This file was automatically generated. Do not edit!" + writeSourceFile targetHandle (fileData task)