From c482e1df4e19b124768ea00c0abbcafbedbc1c32 Mon Sep 17 00:00:00 2001 From: woxjro Date: Wed, 2 Oct 2024 20:53:52 +0900 Subject: [PATCH] feat(compiler): added supports for the following ops - sha256 - sha3 - sha512 --- src/michelify/ast.rs | 10 ++++ src/michelify/phase.rs | 95 ++++++++++++++++++++++++++++--- src/mlir/dialect/michelson/ast.rs | 50 ++++++++++++---- src/mlir_parser.lalrpop | 6 ++ 4 files changed, 142 insertions(+), 19 deletions(-) diff --git a/src/michelify/ast.rs b/src/michelify/ast.rs index a855853..a7b13f1 100644 --- a/src/michelify/ast.rs +++ b/src/michelify/ast.rs @@ -98,6 +98,11 @@ fn stupidly_from(ty: michelson_dialect::Type) -> StackType { michelson_dialect::Type::Contract { ty } => StackType::Contract { ty: Box::new(stupidly_from(ty.as_ref().to_owned())), }, + michelson_dialect::Type::Bytes + | michelson_dialect::Type::Int + | michelson_dialect::Type::Nat => { + todo!() + } } } @@ -147,6 +152,11 @@ impl From for MichelsonType { ty: Box::new(MichelsonType::from(*ty)), }, michelson_dialect::Type::Address => MichelsonType::Address, + michelson_dialect::Type::Bytes + | michelson_dialect::Type::Int + | michelson_dialect::Type::Nat => { + todo!() + } } } } diff --git a/src/michelify/phase.rs b/src/michelify/phase.rs index c9ca47d..f06a793 100644 --- a/src/michelify/phase.rs +++ b/src/michelify/phase.rs @@ -90,7 +90,9 @@ pub fn stack_initialization( type_heap_addresses: &HashMap, ) -> Vec { let mut michelson_instructions = vec![ - instruction_row!(MichelsonInstruction::Comment("------ stack initialization ------ {".to_string())), + instruction_row!(MichelsonInstruction::Comment( + "------ stack initialization ------ {".to_string() + )), //TODO: 引数が Option で包まなければいけない型の場合の処理をする instruction_row!( MichelsonInstruction::Unpair, @@ -128,7 +130,9 @@ pub fn stack_initialization( )); } - michelson_instructions.push(instruction_row!(MichelsonInstruction::Comment("---------------------------------- }".to_string()))); + michelson_instructions.push(instruction_row!(MichelsonInstruction::Comment( + "---------------------------------- }".to_string() + ))); michelson_instructions } @@ -154,9 +158,9 @@ pub fn compile_operations( (*get_address_closure)(GetAddressClosureArg::Value(result.get_value())); instructions.append( &mut [MichelsonInstruction::Comment(format!( - "{} = michelson.get_unit() {{ }}", - result.get_value().get_id() - ))] + "{} = michelson.get_unit() {{ }}", + result.get_value().get_id() + ))] .iter() .map(|instr| instr.to_wrapped_instruction()) .collect::>(), @@ -167,9 +171,9 @@ pub fn compile_operations( (*get_address_closure)(GetAddressClosureArg::Value(result.get_value())); instructions.append( &mut [MichelsonInstruction::Comment(format!( - "{} = michelson.get_source() {{ }}", - result.get_value().get_id() - ))] + "{} = michelson.get_source() {{ }}", + result.get_value().get_id() + ))] .iter() .map(|instr| instr.to_wrapped_instruction()) .collect::>(), @@ -383,6 +387,81 @@ pub fn compile_operations( .collect::>(), ); } + michelson::ast::Operation::Sha256Op { result, bytes } => { + let operand_address = + (*get_address_closure)(GetAddressClosureArg::Value(bytes.get_value())); + let result_address = + (*get_address_closure)(GetAddressClosureArg::Value(result.get_value())); + + instructions.append( + &mut vec![ + MichelsonInstruction::Comment(format!( + "{} = michelson.sha256({}) {{", + result.get_value().get_id(), + bytes.get_value().get_id() + )), + MichelsonInstruction::DupN(operand_address), + MichelsonInstruction::Sha256, + MichelsonInstruction::DigN(result_address), + MichelsonInstruction::Drop, + MichelsonInstruction::DugN(result_address - 1), + MichelsonInstruction::Comment("}".to_string()), + ] + .iter() + .map(|instr| instr.to_wrapped_instruction()) + .collect::>(), + ); + } + michelson::ast::Operation::Sha3Op { result, bytes } => { + let operand_address = + (*get_address_closure)(GetAddressClosureArg::Value(bytes.get_value())); + let result_address = + (*get_address_closure)(GetAddressClosureArg::Value(result.get_value())); + + instructions.append( + &mut vec![ + MichelsonInstruction::Comment(format!( + "{} = michelson.sha3({}) {{", + result.get_value().get_id(), + bytes.get_value().get_id() + )), + MichelsonInstruction::DupN(operand_address), + MichelsonInstruction::Sha3, + MichelsonInstruction::DigN(result_address), + MichelsonInstruction::Drop, + MichelsonInstruction::DugN(result_address - 1), + MichelsonInstruction::Comment("}".to_string()), + ] + .iter() + .map(|instr| instr.to_wrapped_instruction()) + .collect::>(), + ); + } + michelson::ast::Operation::Sha512Op { result, bytes } => { + let operand_address = + (*get_address_closure)(GetAddressClosureArg::Value(bytes.get_value())); + let result_address = + (*get_address_closure)(GetAddressClosureArg::Value(result.get_value())); + + instructions.append( + &mut vec![ + MichelsonInstruction::Comment(format!( + "{} = michelson.sha512({}) {{", + result.get_value().get_id(), + bytes.get_value().get_id() + )), + MichelsonInstruction::DupN(operand_address), + MichelsonInstruction::Sha512, + MichelsonInstruction::DigN(result_address), + MichelsonInstruction::Drop, + MichelsonInstruction::DugN(result_address - 1), + MichelsonInstruction::Comment("}".to_string()), + ] + .iter() + .map(|instr| instr.to_wrapped_instruction()) + .collect::>(), + ); + } } } mlir::dialect::Operation::FuncOp { operation } => { diff --git a/src/mlir/dialect/michelson/ast.rs b/src/mlir/dialect/michelson/ast.rs index 56328f8..6a439a2 100644 --- a/src/mlir/dialect/michelson/ast.rs +++ b/src/mlir/dialect/michelson/ast.rs @@ -7,7 +7,10 @@ lalrpop_mod!(pub mlir_parser); #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum Type { Address, + Bytes, Unit, + Int, + Nat, Mutez, Operation, Option { ty: Box }, @@ -20,17 +23,6 @@ impl Type { pub fn get_dialect(&self) -> dialect::DialectKind { dialect::DialectKind::Michelson } - - /// 型がスタックに積める値を持つか否かを判定する関数 - /// 例えば - /// - Type::Mutez は 0 をというスタックに積める値をもつため true - /// - Type::Address は 初期値に相当する値は無いため false - pub fn has_initial_value(&self) -> bool { - match self { - Type::Pair { .. } => false, - _ => true, - } - } } impl From for Type { @@ -41,7 +33,10 @@ impl From for Type { pub enum Tok { Unit, + Int, + Nat, Address, + Bytes, Contract, Option, Mutez, @@ -88,6 +83,18 @@ pub enum Operation { fst: ast::Operand, snd: ast::Operand, }, + Sha256Op { + result: ast::Result, + bytes: ast::Operand, + }, + Sha3Op { + result: ast::Result, + bytes: ast::Operand, + }, + Sha512Op { + result: ast::Result, + bytes: ast::Operand, + }, } enum OperationKind { @@ -100,6 +107,9 @@ enum OperationKind { GetContractOp, MakeListOp, MakePairOp, + Sha256Op, + Sha3Op, + Sha512Op, } impl ToString for OperationKind { @@ -114,6 +124,9 @@ impl ToString for OperationKind { OperationKind::GetContractOp => "get_contract".to_owned(), OperationKind::MakeListOp => "make_list".to_owned(), OperationKind::MakePairOp => "make_pair".to_owned(), + OperationKind::Sha256Op => "sha256".to_owned(), + OperationKind::Sha3Op => "sha3".to_owned(), + OperationKind::Sha512Op => "sha512".to_owned(), } } } @@ -167,6 +180,21 @@ impl From for Operation { address: operation.operands[0].to_owned(), result: operation.results[0].to_owned(), } + } else if operation.get_mnemonic() == OperationKind::Sha256Op.to_string() { + Operation::Sha256Op { + bytes: operation.operands[0].to_owned(), + result: operation.results[0].to_owned(), + } + } else if operation.get_mnemonic() == OperationKind::Sha3Op.to_string() { + Operation::Sha3Op { + bytes: operation.operands[0].to_owned(), + result: operation.results[0].to_owned(), + } + } else if operation.get_mnemonic() == OperationKind::Sha512Op.to_string() { + Operation::Sha512Op { + bytes: operation.operands[0].to_owned(), + result: operation.results[0].to_owned(), + } } else { todo!("'{}' is an unsupported operation", operation.get_mnemonic()) } diff --git a/src/mlir_parser.lalrpop b/src/mlir_parser.lalrpop index 3c92e67..43fcc35 100644 --- a/src/mlir_parser.lalrpop +++ b/src/mlir_parser.lalrpop @@ -5,7 +5,10 @@ grammar; pub MType: MType = { => MType::Address, + => MType::Bytes, => MType::Unit, + => MType::Int, + => MType::Nat, => MType::Mutez, => MType::Operation, "<" ">" => MType::List { ty: Box::new(ty) }, @@ -24,8 +27,11 @@ pub FType: FType = { Unit: Tok = => Tok::Unit; Address: Tok = => Tok::Address; +Bytes: Tok = => Tok::Bytes; Option: Tok = => Tok::Option; Mutez: Tok = => Tok::Mutez; +Int: Tok = => Tok::Int; +Nat: Tok = => Tok::Nat; Contract: Tok = => Tok::Contract; Operation: Tok = => Tok::Operation; List: Tok = => Tok::List;