diff --git a/.gitignore b/.gitignore index c733e44..0b667e7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .build .DS_store tmp +tmp.* diff --git a/mx-rust-semantics/main/expression/mx-to-rust.md b/mx-rust-semantics/main/expression/mx-to-rust.md index 082f135..4caced7 100644 --- a/mx-rust-semantics/main/expression/mx-to-rust.md +++ b/mx-rust-semantics/main/expression/mx-to-rust.md @@ -4,6 +4,7 @@ module MX-RUST-EXPRESSION-MX-TO-RUST imports private K-EQUAL-SYNTAX imports private MX-COMMON-SYNTAX imports private MX-RUST-REPRESENTATION + imports private RUST-ERROR-SYNTAX imports private RUST-HELPERS imports private RUST-VALUE-SYNTAX @@ -11,6 +12,9 @@ module MX-RUST-EXPRESSION-MX-TO-RUST rule isMxToRustValue(_:K) => false [owise] rule isMxToRustValue(_:PtrValue) => true rule isMxToRustValue(mxToRustField(_, V:MxToRust)) => isMxToRustValue(V) + rule isMxToRustValue(.MxToRustList) => true + rule isMxToRustValue(V:MxToRust , Vs:MxToRustList) + => isMxToRustValue(V) andBool isMxToRustValue(Vs) syntax Bool ::= isMxToRustFieldValue(K) [function, total, symbol(isMxToRustFieldValue)] rule isMxToRustFieldValue(_:K) => false [owise] @@ -32,6 +36,11 @@ module MX-RUST-EXPRESSION-MX-TO-RUST , mxListValue(Values:MxValueList) ) => mxToRustStruct(StructName, pairFields(Fields, Values)) + rule mxToRustTyped + ( (Types:NonEmptyTypeCsv) + , mxListValue(Values:MxValueList) + ) + => mxToRustTuple(pairTuple(Types, Values)) rule mxToRustTyped(() , mxUnitValue()) => ptrValue(null, tuple(.ValueList)) context HOLE:MxRustFieldValue , _:MxRustFieldValues [result(MxToRustFieldValue)] @@ -80,6 +89,40 @@ module MX-RUST-EXPRESSION-MX-TO-RUST rule fieldsToMap((Field , _:MxRustFieldValues), _:Map) => error("Unexpected field", ListItem(Field)) [owise] + + rule (.K => mxToRustListToValueList(L)) ~> mxToRustTuple(L:MxToRustList) + requires isMxToRustValue(L) + rule (L:ValueList ~> mxToRustTuple(_:MxToRustList)) + => mxRustNewValue(tuple(L)) + + syntax ValueListOrError ::= mxToRustListToValueList(MxToRustList) [function, total] + rule mxToRustListToValueList(.MxToRustList) => .ValueList + rule mxToRustListToValueList(ptrValue(_, V:Value) , L:MxToRustList) + => concat(V, mxToRustListToValueList(L)) + rule mxToRustListToValueList(L) => error("mxToRustListToValueList: not evaluated", ListItem(L)) + [owise] + + context HOLE:MxToRust , _:MxToRustList [result(MxToRustValue)] + context V:MxToRust , HOLE:MxToRustList requires isMxToRustValue(V) + [result(MxToRustValue)] + + syntax MxToRustList ::= pairTuple(NonEmptyTypeCsv, MxValueList) [function, total] + rule pairTuple(T:Type, V:MxValue , .MxValueList) + => mxToRustTyped(T, V) , .MxToRustList + rule pairTuple + ( T:Type , Ts:NonEmptyTypeCsv + , V:MxValue , Vs:MxValueList + ) + => mxToRustTyped(T, V) , pairTuple(Ts, Vs) + + rule pairTuple(Ts:NonEmptyTypeCsv, .MxValueList) + => error("Not enough values (pairTuple)", ListItem(Ts)) + rule pairTuple(T:Type, (_ , _ , _:MxValueList) #as L) + => error("Not enough types (pairTuple)", ListItem(T) ListItem(L)) + rule pairTuple(A, B) + => error("Should not happen (pairTuple)", ListItem(A) ListItem(B)) + [owise] + endmodule ``` diff --git a/mx-rust-semantics/main/expression/rust-to-mx.md b/mx-rust-semantics/main/expression/rust-to-mx.md index 1cb6e56..dea7a59 100644 --- a/mx-rust-semantics/main/expression/rust-to-mx.md +++ b/mx-rust-semantics/main/expression/rust-to-mx.md @@ -24,10 +24,13 @@ module MX-RUST-EXPRESSION-RUST-TO-MX Values:Map [owise] + rule rustToMx(tuple(V:ValueList)) + => rustValuesToMxListValue(V, .MxValueList) + rule rustToMx(B:Bool => mxBoolValue(B)) rule rustToMx(S:String => mxStringValue(S)) - rule rustToMx(tuple(V:ValueList)) => rustValuesToMxListValue(V, .MxValueList) + rule rustToMx(V:Value => mxIntValue({valueToInteger(V)}:>Int)) + requires notBool isSemanticsError(valueToInteger(V)) - syntax RustMxInstruction ::= rustValuesToMxListValue(ValueListOrError, MxValueList) rule rustValuesToMxListValue(.ValueList, L:MxValueList) => rustToMx(mxListValue(reverse(L, .MxValueList))) rule (.K => rustToMx(HOLE)) ~> rustValuesToMxListValue(((HOLE:Value , V:ValueList) => V), _:MxValueList) diff --git a/mx-rust-semantics/main/glue.md b/mx-rust-semantics/main/glue.md index 0299c94..e0b9902 100644 --- a/mx-rust-semantics/main/glue.md +++ b/mx-rust-semantics/main/glue.md @@ -56,17 +56,20 @@ module MX-RUST-GLUE (T ==K i32 orBool T ==K u32) orBool (T ==K i64 orBool T ==K u64) - rule - ptr(I:Int) => ptrValue(ptr(I), V) ... - I |-> V:Value ... - rule ptrValue(_, V) ~> rustValueToMx => rustValueToMx(V) - rule rustValueToMx(tuple(.ValueList)) => mxUnitValue() - - rule rustValueToMx(V:Value) => mxIntValue({valueToInteger(V)}:>Int) - requires notBool isSemanticsError(valueToInteger(V)) + rule (.K => rustToMx(V)) ~> rustValueToMx(V:Value) + [owise] + rule (rustToMx(V:MxValue) ~> rustValueToMx(_)) => V + + rule mxIntValue(0) ~> mxRustCheckMxStatus => .K + + rule (.K => rustValuesToMxListValue(Values, .MxValueList)) + ~> rustMxCallHook(_, Values:ValueList) + rule (rustToMx(mxListValue(L:MxValueList)) ~> rustMxCallHook(Hook:MxHookName, _)) + => Hook(L) + rule L:MxValue ~> mxRustWrapInMxList => mxListValue(L) endmodule ``` diff --git a/mx-rust-semantics/main/modules.md b/mx-rust-semantics/main/modules.md index 386d74b..75575f5 100644 --- a/mx-rust-semantics/main/modules.md +++ b/mx-rust-semantics/main/modules.md @@ -2,16 +2,22 @@ requires "modules/address.md" requires "modules/biguint.md" +requires "modules/call-value.md" requires "modules/hooks.md" requires "modules/proxy.md" +requires "modules/send.md" requires "modules/storage.md" +requires "modules/token-identifier.md" module MX-RUST-MODULES imports private MX-RUST-MODULES-ADDRESS imports private MX-RUST-MODULES-BIGUINT + imports private MX-RUST-MODULES-CALL-VALUE imports private MX-RUST-MODULES-HOOKS imports private MX-RUST-MODULES-PROXY + imports private MX-RUST-MODULES-SEND imports private MX-RUST-MODULES-STORAGE + imports private MX-RUST-MODULES-TOKEN-IDENTIFIER endmodule ``` diff --git a/mx-rust-semantics/main/modules/address.md b/mx-rust-semantics/main/modules/address.md index 81f4371..0297393 100644 --- a/mx-rust-semantics/main/modules/address.md +++ b/mx-rust-semantics/main/modules/address.md @@ -28,7 +28,7 @@ module MX-RUST-MODULES-ADDRESS ( struct ( #token("ManagedAddress", "Identifier"):Identifier , #token("mx_address_value", "Identifier"):Identifier |-> AddressValueId:Int - _:Map + .Map ) ) => ptr(AddressValueId) ~> rustValueToMx diff --git a/mx-rust-semantics/main/modules/biguint.md b/mx-rust-semantics/main/modules/biguint.md index 1ac3437..3a52fd4 100644 --- a/mx-rust-semantics/main/modules/biguint.md +++ b/mx-rust-semantics/main/modules/biguint.md @@ -3,6 +3,7 @@ module MX-RUST-MODULES-BIGUINT imports private COMMON-K-CELL imports private MX-COMMON-SYNTAX + imports private MX-RUST-BIGUINT-OPERATORS imports private MX-RUST-REPRESENTATION imports private RUST-EXECUTION-CONFIGURATION imports private RUST-REPRESENTATION @@ -25,9 +26,15 @@ module MX-RUST-MODULES-BIGUINT ValueId |-> V:Value ... + rule normalizedMethodCall + ( #token("BigUint", "Identifier"):Identifier + , #token("zero", "Identifier"):Identifier + , .PtrList + ) + => mxRustBigIntNew(0) + // -------------------------------------- - syntax MxRustType ::= "bigUintType" [function, total] - rule bigUintType + rule bigUintFromValueType => rustStructType ( #token("BigUint", "Identifier"):Identifier , ( mxRustStructField @@ -37,9 +44,19 @@ module MX-RUST-MODULES-BIGUINT , .MxRustStructFields ) ) + rule bigUintFromIdType + => rustStructType + ( #token("BigUint", "Identifier"):Identifier + , ( mxRustStructField + ( #token("mx_biguint_id", "Identifier"):Identifier + , i32 + ) + , .MxRustStructFields + ) + ) // -------------------------------------- rule mxToRustTyped(#token("BigUint", "Identifier"):Identifier, V:MxValue) - => mxToRustTyped(bigUintType, mxListValue(V)) + => mxToRustTyped(bigUintFromValueType, mxListValue(V)) rule (.K => MX#bigIntNew(mxIntValue(I))) ~> mxToRustTyped(MxRust#bigInt, mxIntValue(I:Int)) @@ -51,7 +68,7 @@ module MX-RUST-MODULES-BIGUINT | "mxRustCreateBigUint" rule mxRustBigIntNew(V:Int) - => mxToRustTyped(bigUintType, mxListValue(mxIntValue(V))) + => mxToRustTyped(bigUintFromValueType, mxListValue(mxIntValue(V))) rule mxRustEmptyValue(rustType(#token("BigUint", "Identifier"))) => mxRustBigIntNew(0) @@ -87,6 +104,163 @@ module MX-RUST-MODULES-BIGUINT BigUintIdId |-> i32(BigUintId:MInt{32}) ... + +endmodule + +module MX-RUST-BIGUINT-OPERATORS + imports private COMMON-K-CELL + imports private MX-RUST-REPRESENTATION + imports private RUST-EXECUTION-CONFIGURATION + + syntax MxRustInstruction ::= rustMxBinaryBigUintOperator(MxHookName, Value, Value) + rule + + rustMxBinaryBigUintOperator + ( Hook:MxHookName + , struct + ( #token("BigUint", "Identifier"):Identifier #as BigUint:TypePath + , #token("mx_biguint_id", "Identifier"):Identifier |-> FirstId:Int + _:Map + ) + , struct + ( #token("BigUint", "Identifier"):Identifier #as BigUint:TypePath + , #token("mx_biguint_id", "Identifier"):Identifier |-> SecondId:Int + _:Map + ) + ) + => rustMxCallHook(Hook, (V1, V2, .ValueList)) + ~> mxRustWrapInMxList + ~> mxToRustTyped(bigUintFromIdType) + ... + + + FirstId |-> V1:Value + SecondId |-> V2:Value + ... + + + rule + ptrValue(_, struct(#token("BigUint", "Identifier"):Identifier, _) #as V1:Value) + + ptrValue(_, struct(#token("BigUint", "Identifier"):Identifier, _) #as V2:Value) + => rustMxBinaryBigUintOperator(MX#bigIntAdd, V1, V2) + + rule + ptrValue(_, struct(#token("BigUint", "Identifier"):Identifier, _) #as V1:Value) + - ptrValue(_, struct(#token("BigUint", "Identifier"):Identifier, _) #as V2:Value) + => rustMxBinaryBigUintOperator(MX#bigIntSub, V1, V2) + + rule + ptrValue(_, struct(#token("BigUint", "Identifier"):Identifier, _) #as V1:Value) + * ptrValue(_, struct(#token("BigUint", "Identifier"):Identifier, _) #as V2:Value) + => rustMxBinaryBigUintOperator(MX#bigIntMul, V1, V2) + + rule + ptrValue(_, struct(#token("BigUint", "Identifier"):Identifier, _) #as V1:Value) + / ptrValue(_, struct(#token("BigUint", "Identifier"):Identifier, _) #as V2:Value) + => rustMxBinaryBigUintOperator(MX#bigIntDiv, V1, V2) + + + + rule + (ptrValue(_, struct(#token("BigUint", "Identifier"):Identifier, _)) #as V1:PtrValue) + + (ptrValue(_, u64(_:MInt{64})) #as V2:PtrValue) + => V1 + bigUintFrom(V2) + + rule + (ptrValue(_, struct(#token("BigUint", "Identifier"):Identifier, _)) #as V1:PtrValue) + - (ptrValue(_, u64(_:MInt{64})) #as V2:PtrValue) + => V1 - bigUintFrom(V2) + + rule + (ptrValue(_, struct(#token("BigUint", "Identifier"):Identifier, _)) #as V1:PtrValue) + * (ptrValue(_, u64(_:MInt{64})) #as V2:PtrValue) + => V1 * bigUintFrom(V2) + + rule + (ptrValue(_, struct(#token("BigUint", "Identifier"):Identifier, _)) #as V1:PtrValue) + / (ptrValue(_, u64(_:MInt{64})) #as V2:PtrValue) + => V1 / bigUintFrom(V2) + + syntax Expression ::= bigUintFrom(Expression) [function, total] + rule bigUintFrom(V:Expression) + => ( #token("BigUint", "Identifier"):Identifier + :: #token("from", "Identifier"):Identifier + :: .PathExprSegments + ) + ( V, .CallParamsList ) + + + syntax MxRustInstruction ::= rustMxBinaryBigUintComparisonOperator(MxHookName, Value, Value) + rule + + rustMxBinaryBigUintComparisonOperator + ( Hook:MxHookName + , struct + ( #token("BigUint", "Identifier"):Identifier + , #token("mx_biguint_id", "Identifier"):Identifier |-> FirstId:Int + _:Map + ) + , struct + ( #token("BigUint", "Identifier"):Identifier + , #token("mx_biguint_id", "Identifier"):Identifier |-> SecondId:Int + _:Map + ) + ) + => rustMxCallHook(Hook, (V1, V2, .ValueList)) + ~> mxToRustTyped(i32) + ... + + + FirstId |-> V1:Value + SecondId |-> V2:Value + ... + + + rule + ptrValue(_, struct(#token("BigUint", "Identifier"):Identifier, _) #as V1:Value) + == ptrValue(_, struct(#token("BigUint", "Identifier"):Identifier, _) #as V2:Value) + => rustMxBinaryBigUintComparisonOperator(MX#bigIntCmp, V1, V2) + ~> mxRustEqResult + rule + ptrValue(_, struct(#token("BigUint", "Identifier"):Identifier, _) #as V1:Value) + != ptrValue(_, struct(#token("BigUint", "Identifier"):Identifier, _) #as V2:Value) + => rustMxBinaryBigUintComparisonOperator(MX#bigIntCmp, V1, V2) + ~> mxRustNeResult + rule + ptrValue(_, struct(#token("BigUint", "Identifier"):Identifier, _) #as V1:Value) + < ptrValue(_, struct(#token("BigUint", "Identifier"):Identifier, _) #as V2:Value) // > + => rustMxBinaryBigUintComparisonOperator(MX#bigIntCmp, V1, V2) + ~> mxRustLtResult + rule + ptrValue(_, struct(#token("BigUint", "Identifier"):Identifier, _) #as V1:Value) + <= ptrValue(_, struct(#token("BigUint", "Identifier"):Identifier, _) #as V2:Value) + => rustMxBinaryBigUintComparisonOperator(MX#bigIntCmp, V1, V2) + ~> mxRustLeResult + rule + ptrValue(_, struct(#token("BigUint", "Identifier"):Identifier, _) #as V1:Value) + > ptrValue(_, struct(#token("BigUint", "Identifier"):Identifier, _) #as V2:Value) + => rustMxBinaryBigUintComparisonOperator(MX#bigIntCmp, V1, V2) + ~> mxRustGtResult + rule + ptrValue(_, struct(#token("BigUint", "Identifier"):Identifier, _) #as V1:Value) + >= ptrValue(_, struct(#token("BigUint", "Identifier"):Identifier, _) #as V2:Value) + => rustMxBinaryBigUintComparisonOperator(MX#bigIntCmp, V1, V2) + ~> mxRustGeResult + + syntax MxRustInstruction ::= "mxRustEqResult" + | "mxRustNeResult" + | "mxRustGeResult" + | "mxRustGtResult" + | "mxRustLeResult" + | "mxRustLtResult" + + rule V:PtrValue ~> mxRustEqResult => V == ptrValue(null, i32(0p32)) + rule V:PtrValue ~> mxRustNeResult => V != ptrValue(null, i32(0p32)) + rule V:PtrValue ~> mxRustGeResult => V >= ptrValue(null, i32(0p32)) + rule V:PtrValue ~> mxRustGtResult => V > ptrValue(null, i32(0p32)) + rule V:PtrValue ~> mxRustLtResult => V < ptrValue(null, i32(0p32)) // > + rule V:PtrValue ~> mxRustLeResult => V <= ptrValue(null, i32(0p32)) + endmodule ``` diff --git a/mx-rust-semantics/main/modules/call-value.md b/mx-rust-semantics/main/modules/call-value.md new file mode 100644 index 0000000..c8f458a --- /dev/null +++ b/mx-rust-semantics/main/modules/call-value.md @@ -0,0 +1,61 @@ +```k + +module MX-RUST-MODULES-CALL-VALUE + imports private COMMON-K-CELL + imports private MX-COMMON-SYNTAX + imports private MX-RUST-REPRESENTATION + imports private MX-RUST-REPRESENTATION-CONVERSIONS + imports private RUST-EXECUTION-CONFIGURATION + imports private RUST-SHARED-SYNTAX + + syntax Identifier ::= "MxRust#CallValue" [token] + + syntax MxRustStructType ::= "callValueType" [function, total] + rule callValueType + => rustStructType + ( MxRust#CallValue + , .MxRustStructFields + ) + + rule + normalizedMethodCall + ( MxRust#CallValue + , #token("new", "Identifier"):Identifier + , .PtrList + ) + => mxRustNewStruct + ( callValueType + , .CallParamsList + ) + + rule + normalizedMethodCall + ( MxRust#CallValue + , #token("single_fungible_esdt", "Identifier"):Identifier + , ( ptr(_SelfId:Int) + , .PtrList + ) + ) + => MX#managedGetMultiESDTCallValue(.MxValueList) + ~> getSingleEsdt + ~> mxToRustTyped((str, #token("BigUint", "Identifier"))) + + syntax MxRustInstruction ::= "getSingleEsdt" + + rule .MxEsdtTransferList ~> getSingleEsdt => #exception(UserError, "incorrect number of ESDT transfers") + rule _, _, _:MxEsdtTransferList ~> getSingleEsdt => #exception(UserError, "incorrect number of ESDT transfers") + rule ( mxTransferValue(... token: _:String, nonce: Nonce:Int, value: _:Int) + , .MxEsdtTransferList + ~> getSingleEsdt + ) + => #exception(UserError, "fungible ESDT token expected") + requires Nonce =/=Int 0 + rule ( mxTransferValue(... token: TokenId:String, nonce: 0, value: Value:Int) + , .MxEsdtTransferList + ~> getSingleEsdt + ) + => mxListValue(mxStringValue(TokenId), mxIntValue(Value)) + +endmodule + +``` diff --git a/mx-rust-semantics/main/modules/proxy.md b/mx-rust-semantics/main/modules/proxy.md index d048867..c809f63 100644 --- a/mx-rust-semantics/main/modules/proxy.md +++ b/mx-rust-semantics/main/modules/proxy.md @@ -88,65 +88,63 @@ module MX-RUST-MODULES-PROXY ProxyType MethodName - syntax MxOrRustValueOrInstruction ::= MxOrRustValue | MxRustInstruction - syntax RustMxInstruction ::= rustMxManagedExecuteOnDestContext - ( destination: MxOrRustValueOrInstruction // MxOrRustValue - , egldValue: MxOrRustValueOrInstruction // MxOrRustValue - , mxTransfers: MxOrRustValueOrInstruction // MxOrRustValue - , gasLimit: MxOrRustValueOrInstruction // MxOrRustValue - , function: MxOrRustValueOrInstruction // MxOrRustValue - , args: MxOrRustValueOrInstruction // MxOrRustValue + ( destination: RustToMxOrInstruction // RustToMx + , egldValue: RustToMxOrInstruction // RustToMx + , mxTransfers: RustToMxOrInstruction // RustToMx + , gasLimit: RustToMxOrInstruction // RustToMx + , function: RustToMxOrInstruction // RustToMx + , args: RustToMxOrInstruction // RustToMx ) context rustMxManagedExecuteOnDestContext - (... destination: HOLE:MxOrRustValue => rustToMx(HOLE) - , egldValue: _:MxOrRustValue - , mxTransfers: _:MxOrRustValue - , gasLimit: _:MxOrRustValue - , function: _:MxOrRustValue - , args: _:MxOrRustValue + (... destination: HOLE:RustToMx => rustToMx(HOLE) + , egldValue: _:RustToMx + , mxTransfers: _:RustToMx + , gasLimit: _:RustToMx + , function: _:RustToMx + , args: _:RustToMx ) [result(MxValue)] context rustMxManagedExecuteOnDestContext - (... destination: Destination:MxOrRustValue - , egldValue: HOLE:MxOrRustValue => rustToMx(HOLE) - , mxTransfers: _:MxOrRustValue - , gasLimit: _:MxOrRustValue - , function: _:MxOrRustValue - , args: _:MxOrRustValue + (... destination: Destination:RustToMx + , egldValue: HOLE:RustToMx => rustToMx(HOLE) + , mxTransfers: _:RustToMx + , gasLimit: _:RustToMx + , function: _:RustToMx + , args: _:RustToMx ) requires isMxValue(Destination) [result(MxValue)] context rustMxManagedExecuteOnDestContext - (... destination: Destination:MxOrRustValue - , egldValue: EgldValue:MxOrRustValue - , mxTransfers: HOLE:MxOrRustValue => rustToMx(HOLE) - , gasLimit: _:MxOrRustValue - , function: _:MxOrRustValue - , args: _:MxOrRustValue + (... destination: Destination:RustToMx + , egldValue: EgldValue:RustToMx + , mxTransfers: HOLE:RustToMx => rustToMx(HOLE) + , gasLimit: _:RustToMx + , function: _:RustToMx + , args: _:RustToMx ) requires isMxValue(Destination) andBool isMxValue(EgldValue) [result(MxValue)] context rustMxManagedExecuteOnDestContext - (... destination: Destination:MxOrRustValue - , egldValue: EgldValue:MxOrRustValue - , mxTransfers: MxTransfers:MxOrRustValue - , gasLimit: HOLE:MxOrRustValue => rustToMx(HOLE) - , function: _:MxOrRustValue - , args: _:MxOrRustValue + (... destination: Destination:RustToMx + , egldValue: EgldValue:RustToMx + , mxTransfers: MxTransfers:RustToMx + , gasLimit: HOLE:RustToMx => rustToMx(HOLE) + , function: _:RustToMx + , args: _:RustToMx ) requires isMxValue(Destination) andBool isMxValue(EgldValue) andBool isMxValue(MxTransfers) [result(MxValue)] context rustMxManagedExecuteOnDestContext - (... destination: Destination:MxOrRustValue - , egldValue: EgldValue:MxOrRustValue - , mxTransfers: MxTransfers:MxOrRustValue - , gasLimit: GasLimit:MxOrRustValue - , function: HOLE:MxOrRustValue => rustToMx(HOLE) - , args: _:MxOrRustValue + (... destination: Destination:RustToMx + , egldValue: EgldValue:RustToMx + , mxTransfers: MxTransfers:RustToMx + , gasLimit: GasLimit:RustToMx + , function: HOLE:RustToMx => rustToMx(HOLE) + , args: _:RustToMx ) requires isMxValue(Destination) andBool isMxValue(EgldValue) @@ -154,12 +152,12 @@ module MX-RUST-MODULES-PROXY andBool isMxValue(GasLimit) [result(MxValue)] context rustMxManagedExecuteOnDestContext - (... destination: Destination:MxOrRustValue - , egldValue: EgldValue:MxOrRustValue - , mxTransfers: MxTransfers:MxOrRustValue - , gasLimit: GasLimit:MxOrRustValue - , function: Function:MxOrRustValue - , args: HOLE:MxOrRustValue => rustToMx(HOLE) + (... destination: Destination:RustToMx + , egldValue: EgldValue:RustToMx + , mxTransfers: MxTransfers:RustToMx + , gasLimit: GasLimit:RustToMx + , function: Function:RustToMx + , args: HOLE:RustToMx => rustToMx(HOLE) ) requires isMxValue(Destination) andBool isMxValue(EgldValue) @@ -225,9 +223,6 @@ module MX-RUST-MODULES-PROXY ... - syntax MxInstructions ::= "mxRustCheckMxStatus" - rule mxIntValue(0) ~> mxRustCheckMxStatus => .K - rule implicitCast ( struct(#token("MxRust#Proxy", "Identifier"):Identifier, _) #as V , T diff --git a/mx-rust-semantics/main/modules/send.md b/mx-rust-semantics/main/modules/send.md new file mode 100644 index 0000000..579cbb2 --- /dev/null +++ b/mx-rust-semantics/main/modules/send.md @@ -0,0 +1,122 @@ +```k + +module MX-RUST-MODULES-SEND + imports private COMMON-K-CELL + imports private MX-COMMON-SYNTAX + imports private MX-RUST-REPRESENTATION + imports private MX-RUST-REPRESENTATION-CONVERSIONS + imports private RUST-EXECUTION-CONFIGURATION + imports private RUST-SHARED-SYNTAX + + syntax Identifier ::= "MxRust#Send" [token] + + syntax MxRustStructType ::= "sendType" [function, total] + rule sendType + => rustStructType + ( MxRust#Send + , .MxRustStructFields + ) + + rule + normalizedMethodCall + ( MxRust#Send + , #token("new", "Identifier"):Identifier + , .PtrList + ) + => mxRustNewStruct + ( sendType + , .CallParamsList + ) + + rule + + normalizedMethodCall + ( MxRust#Send + , #token("direct_esdt", "Identifier"):Identifier + , ( ptr(_SelfId:Int) + , ptr(AddressId:Int) + , ptr(TokenIdId:Int) + , ptr(NonceId:Int) + , ptr(AmountId:Int) + , .PtrList + ) + ) + => rustMxDirectEsdt + (... destination: Address + , tokenId: TokenId + , nonce: Nonce + , amount: Amount + ) + ~> mxRustCheckMxStatus + ~> ptrValue(null, ()) + ... + + + AddressId |-> Address:Value + TokenIdId |-> TokenId:Value + NonceId |-> Nonce:Value + AmountId |-> Amount:Value + ... + + + syntax RustMxInstruction ::= rustMxDirectEsdt + ( destination: RustToMxOrInstruction // RustToMx + , tokenId: RustToMxOrInstruction // RustToMx + , nonce: RustToMxOrInstruction // RustToMx + , amount: RustToMxOrInstruction // RustToMx + ) + context rustMxDirectEsdt + (... destination: HOLE:RustToMx => rustToMx(HOLE) + , tokenId: _:RustToMx + , nonce: _:RustToMx + , amount: _:RustToMx + ) + [result(MxValue)] + context rustMxDirectEsdt + (... destination: Destination:RustToMx + , tokenId: HOLE:RustToMx => rustToMx(HOLE) + , nonce: _:RustToMx + , amount: _:RustToMx + ) + requires isMxValue(Destination) + [result(MxValue)] + context rustMxDirectEsdt + (... destination: Destination:RustToMx + , tokenId: TokenId:RustToMx + , nonce: HOLE:RustToMx => rustToMx(HOLE) + , amount: _:RustToMx + ) + requires isMxValue(Destination) + andBool isMxValue(TokenId) + [result(MxValue)] + context rustMxDirectEsdt + (... destination: Destination:RustToMx + , tokenId: TokenId:RustToMx + , nonce: Nonce:RustToMx + , amount: HOLE:RustToMx => rustToMx(HOLE) + ) + requires isMxValue(Destination) + andBool isMxValue(TokenId) + andBool isMxValue(Nonce) + [result(MxValue)] + + rule rustMxDirectEsdt + (... destination: mxListValue(Destination:MxValue , .MxValueList) + , tokenId: mxListValue(mxStringValue(TokenId:String) , .MxValueList) + , nonce: mxIntValue(Nonce:Int) + , amount: mxIntValue(Amount:Int) + ) + => MX#managedMultiTransferESDTNFTExecute + ( Destination + , mxTransfersValue + ( mxTransferValue(... token:TokenId, nonce:Nonce, value: Amount) + , .MxEsdtTransferList + ) + , mxIntValue(0) // TODO: Use some gas value + , mxStringValue("") + , mxListValue(.MxValueList) + ) + +endmodule + +``` diff --git a/mx-rust-semantics/main/modules/token-identifier.md b/mx-rust-semantics/main/modules/token-identifier.md new file mode 100644 index 0000000..6eeb50d --- /dev/null +++ b/mx-rust-semantics/main/modules/token-identifier.md @@ -0,0 +1,38 @@ +```k + +module MX-RUST-MODULES-TOKEN-IDENTIFIER + imports private MX-COMMON-SYNTAX + imports private MX-RUST-REPRESENTATION + imports private MX-RUST-REPRESENTATION-CONVERSIONS + imports private RUST-SHARED-SYNTAX + + syntax MxRustType ::= "tokenIdentifierType" [function, total] + rule tokenIdentifierType + => rustStructType + ( #token("TokenIdentifier", "Identifier"):Identifier + , ( mxRustStructField + ( #token("mx_token_identifier", "Identifier"):Identifier + , str + ) + , .MxRustStructFields + ) + ) + + rule mxRustEmptyValue(rustType(#token("TokenIdentifier", "Identifier"))) + => mxToRustTyped(tokenIdentifierType, mxListValue(mxStringValue(""))) + + rule mxValueToRust(#token("TokenIdentifier", "Identifier"), V:MxValue) + => mxToRustTyped(tokenIdentifierType, mxListValue(V)) + + rule rustValueToMx + ( struct + ( #token("TokenIdentifier", "Identifier"):Identifier + , #token("mx_token_identifier", "Identifier"):Identifier |-> TokenValueId:Int + .Map + ) + ) + => ptr(TokenValueId) ~> rustValueToMx + +endmodule + +``` diff --git a/mx-rust-semantics/main/preprocessing.md b/mx-rust-semantics/main/preprocessing.md index 53598b5..2acaf98 100644 --- a/mx-rust-semantics/main/preprocessing.md +++ b/mx-rust-semantics/main/preprocessing.md @@ -1,10 +1,12 @@ ```k +requires "preprocessing/contract.md" requires "preprocessing/methods.md" requires "preprocessing/proxy.md" requires "preprocessing/traits.md" module MX-RUST-PREPROCESSING + imports private MX-RUST-PREPROCESSING-CONTRACT imports private MX-RUST-PREPROCESSING-METHODS imports private MX-RUST-PREPROCESSING-PROXY imports private MX-RUST-PREPROCESSING-TRAITS diff --git a/mx-rust-semantics/main/preprocessing/contract.md b/mx-rust-semantics/main/preprocessing/contract.md new file mode 100644 index 0000000..6c343ea --- /dev/null +++ b/mx-rust-semantics/main/preprocessing/contract.md @@ -0,0 +1,87 @@ +```k + +module MX-RUST-PREPROCESSING-CONTRACT + imports COMMON-K-CELL + imports MX-RUST-REPRESENTATION + imports RUST-PREPROCESSING-CONFIGURATION + + syntax MxRustInstruction ::= rustMxAddContractSend(TypePath) + | rustMxAddContractCallValue(TypePath) + | rustMxAddContractGenericMethod + ( trait: TypePath + , method: Identifier + , struct: Identifier + ) + + rule rustMxAddContractMethods(Trait:TypePath) + => rustMxAddContractSend(Trait:TypePath) + ~> rustMxAddContractCallValue(Trait:TypePath) + + rule rustMxAddContractSend(Trait:TypePath) + => rustMxAddContractGenericMethod + (... trait: Trait + , method: #token("send", "Identifier") + , struct: #token("MxRust#Send", "Identifier") + ) + + rule rustMxAddContractCallValue(Trait:TypePath) + => rustMxAddContractGenericMethod + (... trait: Trait + , method: #token("call_value", "Identifier") + , struct: #token("MxRust#CallValue", "Identifier") + ) + + rule + + rustMxAddContractGenericMethod + (... trait: Trait:TypePath + , method: Method:Identifier + ) + => error + ( "send already exists for trait" + , ListItem(Trait) + ) + ... + + Trait + Method + [priority(50)] + + rule + + rustMxAddContractGenericMethod + (... trait: Trait:TypePath + , method: Method:Identifier + , struct: Struct:Identifier + ) + => .K + ... + + Trait + ( .Bag + => + Method + self : $selftype , .NormalizedFunctionParameterList + #token("MxRust#CallReturnType", "Identifier") + + block({ + .InnerAttributes + ( + ( + ( Struct + :: (#token("new", "Identifier"):PathExprSegment) + :: .PathExprSegments + ) + ( .CallParamsList ) + ):Expression + ):Statements + }) + + `emptyOuterAttributes`(.KList):OuterAttributes + + ) + [priority(100)] + +endmodule + +``` diff --git a/mx-rust-semantics/main/preprocessing/methods.md b/mx-rust-semantics/main/preprocessing/methods.md index e3beff1..127dca2 100644 --- a/mx-rust-semantics/main/preprocessing/methods.md +++ b/mx-rust-semantics/main/preprocessing/methods.md @@ -64,7 +64,7 @@ module MX-RUST-PREPROCESSING-METHODS T MethodNames:List - rule mxRustPreprocessMethods(_:TypePath, contract, .List) => .K + rule mxRustPreprocessMethods(Trait:TypePath, contract, .List) => rustMxAddContractMethods(Trait) rule mxRustPreprocessMethods(Trait:TypePath, proxy, .List) => rustMxAddProxyMethods(Trait) rule mxRustPreprocessMethods diff --git a/mx-rust-semantics/main/representation.md b/mx-rust-semantics/main/representation.md index c28c7a1..cbf7110 100644 --- a/mx-rust-semantics/main/representation.md +++ b/mx-rust-semantics/main/representation.md @@ -9,6 +9,7 @@ module MX-RUST-REPRESENTATION syntax MxRustInstruction ::= "mxRustPreprocessTraits" | mxRustPreprocessMethods(TypePath, TraitType) + | rustMxAddContractMethods(TypePath) | rustMxAddProxyMethods(TypePath) | mxRustCreateAccount(String) | mxRustCreateContract @@ -19,6 +20,7 @@ module MX-RUST-REPRESENTATION | mxRustNewValue(ValueOrError) | mxRustEmptyValue(MxRustType) | mxValueToRust(Type) + // TODO: Replace with mxToRustTyped | mxValueToRust(Type, MxValue) | "rustValueToMx" | rustValueToMx(Value) @@ -28,11 +30,19 @@ module MX-RUST-REPRESENTATION | mxRustGetStringFromId(Int) | mxRustNewStruct(MxRustStructType, CallParamsList) [strict(2), result(ValueWithPtr)] + | "mxRustCheckMxStatus" + | rustMxCallHook(MxHookName, ValueList) + | "mxRustWrapInMxList" syntax TraitType ::= "contract" | "proxy" - syntax MxRustType ::= "noType" | rustType(Type) + syntax MxRustType ::= "noType" + | rustType(Type) syntax MxRustTypeOrError ::= MxRustType | SemanticsError syntax Value ::= MxRustType + syntax Type ::= "bigUintFromValueType" [function, total] + syntax Type ::= "bigUintFromIdType" [function, total] + + syntax RustToMxOrInstruction ::= RustToMx | MxRustInstruction syntax Expression ::= concatString(Expression, Expression) [seqstrict] | toString(Expression) [strict] @@ -57,8 +67,8 @@ module MX-RUST-REPRESENTATION-CONVERSIONS syntax MxRustStructField ::= mxRustStructField(Identifier, MxRustType) syntax MxRustStructFields ::= List{MxRustStructField, ","} syntax MxRustStructType ::= rustStructType(TypePath, MxRustStructFields) + syntax Type ::= MxRustStructType syntax MxRustType ::= Type // TODO: Remove and use `rustType(_)` - | MxRustStructType syntax MxRustFieldValue ::= mxToRustField(Identifier, MxToRust) [strict(2)] syntax MxRustFieldValueOrError ::= MxRustFieldValue | SemanticsError @@ -67,18 +77,23 @@ module MX-RUST-REPRESENTATION-CONVERSIONS syntax MxToRustIntermediate ::= mxToRustStruct(structName:TypePath, MxRustFieldValues) [strict(2), result(MxToRustFieldValue)] + syntax MxToRustIntermediate ::= mxToRustTuple(MxToRustList) + [strict, result(MxToRustValue)] + syntax MxToRust ::= mxToRustTyped(MxRustType, MxValue) | MxValue | PtrValue | SemanticsError + syntax MxToRustOrError ::= MxToRust | SemanticsError + syntax MxToRustList ::= List{MxToRustOrError, ","} - syntax MxOrRustValue ::= MxValue | Value - syntax MxOrRustValueList ::= List{MxOrRustValue, ","} - syntax MxOrRustValueListOrError ::= MxOrRustValueList | SemanticsError + syntax RustToMx ::= MxValue | Value syntax MxRustInstruction ::= mxToRustTyped(MxRustType) - syntax MxRustInstruction ::= rustToMx(MxOrRustValue) + // TODO: Merge rustToMx and rustValueToMx + syntax MxRustInstruction ::= rustToMx(RustToMx) | "rustToMx" + | rustValuesToMxListValue(ValueListOrError, MxValueList) endmodule ``` diff --git a/mx-semantics/main/calls/hooks.md b/mx-semantics/main/calls/hooks.md index 8f7e048..964eaa1 100644 --- a/mx-semantics/main/calls/hooks.md +++ b/mx-semantics/main/calls/hooks.md @@ -66,6 +66,13 @@ module MX-CALLS-HOOKS ) rule MX#finish ( V:MxValue ) => returnCallData(V) + + rule + + MX#managedGetMultiESDTCallValue(.MxValueList) => Transfers + ... + + Transfers:MxEsdtTransferList endmodule ``` \ No newline at end of file diff --git a/mx-semantics/main/syntax.md b/mx-semantics/main/syntax.md index b9a1e22..3f4ffcf 100644 --- a/mx-semantics/main/syntax.md +++ b/mx-semantics/main/syntax.md @@ -9,6 +9,7 @@ module MX-COMMON-SYNTAX syntax MxEsdtTransferList ::= List{MxEsdtTransfer, ","} syntax MxValue ::= mxIntValue(Int) + | mxBoolValue(Bool) | mxStringValue(String) | mxListValue(MxValueList) | MxEsdtTransfer diff --git a/rust-semantics/error.md b/rust-semantics/error.md index 4c1ad99..0f3f045 100644 --- a/rust-semantics/error.md +++ b/rust-semantics/error.md @@ -9,6 +9,8 @@ module RUST-ERROR-SYNTAX syntax TypePathOrError ::= doubleColonOrError(TypePathSegmentsOrError) [function, total] syntax TypePathOrError ::= injectOrError(TypePathSegmentsOrError) [function, total] syntax TypePathSegmentsOrError ::= concat(TypePathSegment, TypePathSegmentsOrError) [function, total] + syntax ExpressionOrError ::= andOrError(ExpressionOrError, ExpressionOrError) [function, total] + syntax ValueOrError ::= tupleOrError(ValueListOrError) [function, total] endmodule module RUST-ERROR @@ -35,6 +37,13 @@ module RUST-ERROR rule concat(_:TypePathSegment, E) => E rule concat(S:TypePathSegment, Ss:TypePathSegments) => S :: Ss + + rule andOrError(_:ExpressionOrError, E:SemanticsError) => E + rule andOrError(E:SemanticsError, _:Expression) => E + rule andOrError(E1:Expression, E2:Expression) => E1 && E2 + + rule tupleOrError(L:ValueList) => tuple(L) + rule tupleOrError(E:SemanticsError) => E endmodule ``` diff --git a/rust-semantics/execution/let.md b/rust-semantics/execution/let.md index 50bca4e..6e990bb 100644 --- a/rust-semantics/execution/let.md +++ b/rust-semantics/execution/let.md @@ -9,6 +9,8 @@ module RUST-LET imports private RUST-VALUE-SYNTAX // Not all cases are implemented + + // Handling immutable variables rule let Variable:Identifier : T:Type = ptrValue(_, V:Value) ; => .K @@ -26,6 +28,46 @@ module RUST-LET Locals:Map => Locals[Variable <- NextId] Values:Map => Values[NextId <- V] requires notBool mayBeDefaultTypedInt(V) + + // Handling mutable variables + rule + + let mut Variable:Identifier : T:Type = ptrValue(_, V:Value) ; => .K + ... + + NextId:Int => NextId +Int 1 + Locals:Map => Locals[Variable <- NextId] + Values:Map => Values[NextId <- implicitCast(V, T)] + rule + + let mut Variable:Identifier = ptrValue(_, V:Value) ; => .K + ... + + NextId:Int => NextId +Int 1 + Locals:Map => Locals[Variable <- NextId] + Values:Map => Values[NextId <- V] + requires notBool mayBeDefaultTypedInt(V) + + // Handling tuple assignments + rule + let (Variable:PatternNoTopAlt | .PatternNoTopAlts , RemainingToAssign:Patterns):TuplePattern + = ptrValue(_,tuple(Val:Value, ValList:ValueList)) ; + => + let Variable = ptrValue(null, Val); + ~> let (RemainingToAssign:Patterns:TuplePatternItems):TuplePattern + = ptrValue(null, tuple(ValList)); + + + rule + let (.Patterns):TuplePattern = ptrValue(_,tuple(.ValueList)); + => .K + + // Handles the case where the tuple pattern on the let expression has an extra comma, removing it + rule + let (Ps:Patterns,):TuplePattern = V:PtrValue; + => let (Ps):TuplePattern = V; + + endmodule ``` \ No newline at end of file diff --git a/rust-semantics/expression.md b/rust-semantics/expression.md index c44a478..a703e0a 100644 --- a/rust-semantics/expression.md +++ b/rust-semantics/expression.md @@ -3,6 +3,7 @@ requires "expression/assignments.md" requires "expression/blocks.md" requires "expression/bool-operations.md" requires "expression/calls.md" +requires "expression/comparisons.md" requires "expression/constants.md" requires "expression/casts.md" requires "expression/conditionals.md" @@ -22,6 +23,7 @@ module RUST-EXPRESSION imports private RUST-LOOP-EXPRESSIONS imports private RUST-EXPRESSION-ASSIGNMENTS imports private RUST-EXPRESSION-CALLS + imports private RUST-EXPRESSION-COMPARISONS imports private RUST-EXPRESSION-CONSTANTS imports private RUST-EXPRESSION-EXPRESSION-LIST imports private RUST-EXPRESSION-LITERALS diff --git a/rust-semantics/expression/casts.md b/rust-semantics/expression/casts.md index 38140ef..f2d6cdb 100644 --- a/rust-semantics/expression/casts.md +++ b/rust-semantics/expression/casts.md @@ -36,8 +36,11 @@ module RUST-CASTS rule implicitCast(u128(Value), u64) => u64(Int2MInt(MInt2Unsigned(Value))) rule implicitCast(V:Bool, bool) => V + rule implicitCast(S:String, str) => S rule implicitCast(tuple(.ValueList) #as V, ():Type) => V + rule implicitCast(tuple(Vs:ValueList), (Ts:NonEmptyTypeCsv)) + => tupleOrError(implicitCastList(Vs, Ts)) rule implicitCast(struct(T, _) #as V, T) => V rule implicitCast(struct(T, _) #as V, T < _ >) => V @@ -48,6 +51,14 @@ module RUST-CASTS // We don't need a value for the unit type rule implicitCastTo(( )) => .K + syntax ValueListOrError ::= implicitCastList(ValueList, NonEmptyTypeCsv) [function, total] + rule implicitCastList(V:Value , .ValueList, T:Type) => concat(implicitCast(V, T), .ValueList) + rule implicitCastList(V:Value , Vs:ValueList, T:Type, Ts:NonEmptyTypeCsv) + => concat(implicitCast(V, T), implicitCastList(Vs, Ts)) + rule implicitCastList(Vs:ValueList, Ts:NonEmptyTypeCsv) + => error("implicitCastList values not paired with types", ListItem(Vs) ListItem(Ts)) + [owise] + endmodule ``` diff --git a/rust-semantics/expression/comparisons.md b/rust-semantics/expression/comparisons.md new file mode 100644 index 0000000..3071bb0 --- /dev/null +++ b/rust-semantics/expression/comparisons.md @@ -0,0 +1,90 @@ +```k + +module RUST-EXPRESSION-COMPARISONS + imports private RUST-EXPRESSION-STRUCT-COMPARISONS + imports private RUST-EXPRESSION-STRING-COMPARISONS + imports private RUST-INTEGER-RELATIONAL-OPERATIONS +endmodule + +module RUST-EXPRESSION-STRING-COMPARISONS + imports private K-EQUAL-SYNTAX + imports private RUST-SHARED-SYNTAX + imports private RUST-REPRESENTATION + + rule ptrValue(_, A:String) == ptrValue(_, B:String) => ptrValue(null, A ==K B) +endmodule + +module RUST-EXPRESSION-STRUCT-COMPARISONS + imports private RUST-CONVERSIONS-SYNTAX + imports private RUST-ERROR-SYNTAX + imports private RUST-REPRESENTATION + + // TODO: This should use std::cmp::PartialEq::eq + rule (ptrValue(_, struct(StructName:TypePath, FirstFields:Map)) + == ptrValue(_, struct(StructName, SecondFields:Map)) + ):Expression + => allPtrEquality + ( listToPtrList(values(FirstFields)) + , listToPtrList(values(SecondFields)) + ) + [owise] + + syntax ExpressionOrError ::= allPtrEquality(PtrListOrError, PtrListOrError) + [function, total] + + rule allPtrEquality(E:SemanticsError, _:PtrListOrError) => E + rule allPtrEquality(_:PtrList, E:SemanticsError) => E + + rule allPtrEquality(.PtrList, .PtrList) => true + rule allPtrEquality((P:Ptr , Ps:PtrList), (Q:Ptr , Qs:PtrList)) + => andOrError(P == Q , allPtrEquality(Ps, Qs)) + + rule allPtrEquality(.PtrList, (_:Ptr , _:PtrList) #as Ps:PtrList) + => error("allPtrEquality: Second list too long", ListItem(Ps)) + rule allPtrEquality((_:Ptr , _:PtrList) #as Ps:PtrList, .PtrList) + => error("zip(PtrList): First list too long", ListItem(Ps)) + +endmodule + +module RUST-INTEGER-RELATIONAL-OPERATIONS + imports private RUST-SHARED-SYNTAX + imports private RUST-REPRESENTATION + + rule ptrValue(_, i32(A):Value) == ptrValue(_, i32(B):Value) => ptrValue(null, A ==MInt B) + rule ptrValue(_, i32(A):Value) != ptrValue(_, i32(B):Value) => ptrValue(null, A =/=MInt B) + rule ptrValue(_, i32(A):Value) > ptrValue(_, i32(B):Value) => ptrValue(null, A >sMInt B) + rule ptrValue(_, i32(A):Value) < ptrValue(_, i32(B):Value) => ptrValue(null, A = ptrValue(_, i32(B):Value) => ptrValue(null, A >=sMInt B) + rule ptrValue(_, i32(A):Value) <= ptrValue(_, i32(B):Value) => ptrValue(null, A <=sMInt B) + + rule ptrValue(_, u32(A):Value) == ptrValue(_, u32(B):Value) => ptrValue(null, A ==MInt B) + rule ptrValue(_, u32(A):Value) != ptrValue(_, u32(B):Value) => ptrValue(null, A =/=MInt B) + rule ptrValue(_, u32(A):Value) > ptrValue(_, u32(B):Value) => ptrValue(null, A >uMInt B) + rule ptrValue(_, u32(A):Value) < ptrValue(_, u32(B):Value) => ptrValue(null, A = ptrValue(_, u32(B):Value) => ptrValue(null, A >=uMInt B) + rule ptrValue(_, u32(A):Value) <= ptrValue(_, u32(B):Value) => ptrValue(null, A <=uMInt B) + + rule ptrValue(_, i64(A):Value) == ptrValue(_, i64(B):Value) => ptrValue(null, A ==MInt B) + rule ptrValue(_, i64(A):Value) != ptrValue(_, i64(B):Value) => ptrValue(null, A =/=MInt B) + rule ptrValue(_, i64(A):Value) > ptrValue(_, i64(B):Value) => ptrValue(null, A >sMInt B) + rule ptrValue(_, i64(A):Value) < ptrValue(_, i64(B):Value) => ptrValue(null, A = ptrValue(_, i64(B):Value) => ptrValue(null, A >=sMInt B) + rule ptrValue(_, i64(A):Value) <= ptrValue(_, i64(B):Value) => ptrValue(null, A <=sMInt B) + + rule ptrValue(_, u64(A):Value) == ptrValue(_, u64(B):Value) => ptrValue(null, A ==MInt B) + rule ptrValue(_, u64(A):Value) != ptrValue(_, u64(B):Value) => ptrValue(null, A =/=MInt B) + rule ptrValue(_, u64(A):Value) > ptrValue(_, u64(B):Value) => ptrValue(null, A >uMInt B) + rule ptrValue(_, u64(A):Value) < ptrValue(_, u64(B):Value) => ptrValue(null, A = ptrValue(_, u64(B):Value) => ptrValue(null, A >=uMInt B) + rule ptrValue(_, u64(A):Value) <= ptrValue(_, u64(B):Value) => ptrValue(null, A <=uMInt B) + + rule ptrValue(_, u128(A):Value) == ptrValue(_, u128(B):Value) => ptrValue(null, A ==MInt B) + rule ptrValue(_, u128(A):Value) != ptrValue(_, u128(B):Value) => ptrValue(null, A =/=MInt B) + rule ptrValue(_, u128(A):Value) > ptrValue(_, u128(B):Value) => ptrValue(null, A >uMInt B) + rule ptrValue(_, u128(A):Value) < ptrValue(_, u128(B):Value) => ptrValue(null, A = ptrValue(_, u128(B):Value) => ptrValue(null, A >=uMInt B) + rule ptrValue(_, u128(A):Value) <= ptrValue(_, u128(B):Value) => ptrValue(null, A <=uMInt B) + +endmodule + +``` diff --git a/rust-semantics/expression/integer-operations.md b/rust-semantics/expression/integer-operations.md index 1975c27..a334a00 100644 --- a/rust-semantics/expression/integer-operations.md +++ b/rust-semantics/expression/integer-operations.md @@ -2,7 +2,6 @@ module RUST-INTEGER-OPERATIONS imports private RUST-INTEGER-ARITHMETIC-OPERATIONS - imports private RUST-INTEGER-RELATIONAL-OPERATIONS imports private RUST-INTEGER-RANGE-OPERATIONS endmodule @@ -47,48 +46,6 @@ module RUST-INTEGER-ARITHMETIC-OPERATIONS endmodule -module RUST-INTEGER-RELATIONAL-OPERATIONS - imports RUST-SHARED-SYNTAX - imports private RUST-REPRESENTATION - - rule ptrValue(_, i32(A):Value) == ptrValue(_, i32(B):Value) => ptrValue(null, A ==MInt B) - rule ptrValue(_, i32(A):Value) != ptrValue(_, i32(B):Value) => ptrValue(null, A =/=MInt B) - rule ptrValue(_, i32(A):Value) > ptrValue(_, i32(B):Value) => ptrValue(null, A >sMInt B) - rule ptrValue(_, i32(A):Value) < ptrValue(_, i32(B):Value) => ptrValue(null, A = ptrValue(_, i32(B):Value) => ptrValue(null, A >=sMInt B) - rule ptrValue(_, i32(A):Value) <= ptrValue(_, i32(B):Value) => ptrValue(null, A <=sMInt B) - - rule ptrValue(_, u32(A):Value) == ptrValue(_, u32(B):Value) => ptrValue(null, A ==MInt B) - rule ptrValue(_, u32(A):Value) != ptrValue(_, u32(B):Value) => ptrValue(null, A =/=MInt B) - rule ptrValue(_, u32(A):Value) > ptrValue(_, u32(B):Value) => ptrValue(null, A >uMInt B) - rule ptrValue(_, u32(A):Value) < ptrValue(_, u32(B):Value) => ptrValue(null, A = ptrValue(_, u32(B):Value) => ptrValue(null, A >=uMInt B) - rule ptrValue(_, u32(A):Value) <= ptrValue(_, u32(B):Value) => ptrValue(null, A <=uMInt B) - - rule ptrValue(_, i64(A):Value) == ptrValue(_, i64(B):Value) => ptrValue(null, A ==MInt B) - rule ptrValue(_, i64(A):Value) != ptrValue(_, i64(B):Value) => ptrValue(null, A =/=MInt B) - rule ptrValue(_, i64(A):Value) > ptrValue(_, i64(B):Value) => ptrValue(null, A >sMInt B) - rule ptrValue(_, i64(A):Value) < ptrValue(_, i64(B):Value) => ptrValue(null, A = ptrValue(_, i64(B):Value) => ptrValue(null, A >=sMInt B) - rule ptrValue(_, i64(A):Value) <= ptrValue(_, i64(B):Value) => ptrValue(null, A <=sMInt B) - - rule ptrValue(_, u64(A):Value) == ptrValue(_, u64(B):Value) => ptrValue(null, A ==MInt B) - rule ptrValue(_, u64(A):Value) != ptrValue(_, u64(B):Value) => ptrValue(null, A =/=MInt B) - rule ptrValue(_, u64(A):Value) > ptrValue(_, u64(B):Value) => ptrValue(null, A >uMInt B) - rule ptrValue(_, u64(A):Value) < ptrValue(_, u64(B):Value) => ptrValue(null, A = ptrValue(_, u64(B):Value) => ptrValue(null, A >=uMInt B) - rule ptrValue(_, u64(A):Value) <= ptrValue(_, u64(B):Value) => ptrValue(null, A <=uMInt B) - - rule ptrValue(_, u128(A):Value) == ptrValue(_, u128(B):Value) => ptrValue(null, A ==MInt B) - rule ptrValue(_, u128(A):Value) != ptrValue(_, u128(B):Value) => ptrValue(null, A =/=MInt B) - rule ptrValue(_, u128(A):Value) > ptrValue(_, u128(B):Value) => ptrValue(null, A >uMInt B) - rule ptrValue(_, u128(A):Value) < ptrValue(_, u128(B):Value) => ptrValue(null, A = ptrValue(_, u128(B):Value) => ptrValue(null, A >=uMInt B) - rule ptrValue(_, u128(A):Value) <= ptrValue(_, u128(B):Value) => ptrValue(null, A <=uMInt B) - -endmodule - - module RUST-INTEGER-RANGE-OPERATIONS imports RUST-SHARED-SYNTAX imports private RUST-REPRESENTATION diff --git a/rust-semantics/expression/struct.md b/rust-semantics/expression/struct.md index ffdaf7c..26e1ea6 100644 --- a/rust-semantics/expression/struct.md +++ b/rust-semantics/expression/struct.md @@ -2,9 +2,29 @@ module RUST-EXPRESSION-STRUCT imports private COMMON-K-CELL + imports private RUST-CONVERSIONS-SYNTAX + imports private RUST-ERROR-SYNTAX imports private RUST-EXECUTION-CONFIGURATION imports private RUST-REPRESENTATION + rule + + normalizedMethodCall + ( StructName:TypePath + , #token("clone", "Identifier"):Identifier + , (ptr(SelfPtr), .PtrList) + ) + => ptrValue(ptr(NVI), struct(StructName, FieldValues)) + ... + + + ( SelfPtr |-> struct(StructName, FieldValues:Map) + _:Map + ) #as Values + => Values[NVI <- struct(StructName, FieldValues)] + + NVI:Int => NVI +Int 1 + rule Rust#newStruct(P:TypePath, Fields:Map) => ptrValue(ptr(NVI), struct(P, Fields)) ... VALUES:Map => VALUES[NVI <- struct(P, Fields)] diff --git a/rust-semantics/expression/variables.md b/rust-semantics/expression/variables.md index 0ca00cb..9854516 100644 --- a/rust-semantics/expression/variables.md +++ b/rust-semantics/expression/variables.md @@ -25,6 +25,10 @@ module RUST-EXPRESSION-VARIABLES self:PathIdentSegment |-> VarId:Int ... VarId |-> V:Value ... + rule + ptr(I:Int) => ptrValue(ptr(I), V) ... + I |-> V:Value ... + rule [[isLocalVariable(Name:ValueName) => true]] Locals requires Name in_keys(Locals) diff --git a/rust-semantics/representation.md b/rust-semantics/representation.md index e3e324f..8efb6a0 100644 --- a/rust-semantics/representation.md +++ b/rust-semantics/representation.md @@ -85,6 +85,9 @@ module RUST-REPRESENTATION syntax MapOrError ::= Map | SemanticsError + syntax Expression ::= Ptr + syntax ExpressionOrError ::= Expression | SemanticsError + syntax NormalizedFunctionParameterListOrError ::= NormalizedFunctionParameterList | SemanticsError syntax Type ::= "$selftype" diff --git a/tests/execution/let-expression.1.run b/tests/execution/let-expression.1.run new file mode 100644 index 0000000..940bf9b --- /dev/null +++ b/tests/execution/let-expression.1.run @@ -0,0 +1,4 @@ +new Let; +call Let.let_final; +return_value; +check_eq 100_u64 diff --git a/tests/execution/let-expression.2.run b/tests/execution/let-expression.2.run new file mode 100644 index 0000000..30f4c39 --- /dev/null +++ b/tests/execution/let-expression.2.run @@ -0,0 +1,4 @@ +new Let; +call Let.let_mut; +return_value; +check_eq 100_u64 diff --git a/tests/execution/let-expression.3.run b/tests/execution/let-expression.3.run new file mode 100644 index 0000000..0ee91a5 --- /dev/null +++ b/tests/execution/let-expression.3.run @@ -0,0 +1,4 @@ +new Let; +call Let.let_tuple; +return_value; +check_eq 100_u64 diff --git a/tests/execution/let-final-expression.rs b/tests/execution/let-expression.rs similarity index 52% rename from tests/execution/let-final-expression.rs rename to tests/execution/let-expression.rs index c74f9aa..05b3014 100644 --- a/tests/execution/let-final-expression.rs +++ b/tests/execution/let-expression.rs @@ -4,7 +4,7 @@ use multiversx_sc::imports::*; #[multiversx_sc::contract] -pub trait LetFinal { +pub trait Let { #[init] fn init(&self) { } @@ -16,4 +16,15 @@ pub trait LetFinal { let x = 100_u64; x } + + fn let_mut(&self) -> u64 { + let mut x = 99_u64; + x = 100_u64; + x + } + + fn let_tuple(&self) -> u64 { + let (x, y, z, w,) = (100_u64, 99_u64, 98_u64, 97_u64); + x + } } diff --git a/tests/execution/let-final-expression.1.run b/tests/execution/let-final-expression.1.run deleted file mode 100644 index 1814298..0000000 --- a/tests/execution/let-final-expression.1.run +++ /dev/null @@ -1,4 +0,0 @@ -new LetFinal; -call LetFinal.let_final; -return_value; -check_eq 100_u64 diff --git a/tests/mx-rust-contracts/call-value.1.args b/tests/mx-rust-contracts/call-value.1.args new file mode 100644 index 0000000..e69de29 diff --git a/tests/mx-rust-contracts/call-value.1.run b/tests/mx-rust-contracts/call-value.1.run new file mode 100644 index 0000000..7e909d7 --- /dev/null +++ b/tests/mx-rust-contracts/call-value.1.run @@ -0,0 +1,14 @@ +setBalance("Owner", "MyToken", 0, 1234); +setCallee("Owner"); + +push mxListValue(); +push mxStringValue("getTransfer"); +push mxIntValue(0); +push mxTransfersValue(mxTransferValue("MyToken", 0, 10)); +push mxIntValue(0); +push mxStringValue("TestContract"); +call 6 MX#managedExecuteOnDestContext; +check_eq mxIntValue(0); + +push_return_value; +check_eq mxListValue( mxStringValue("MyToken") , mxIntValue(10)) diff --git a/tests/mx-rust-contracts/call-value.rs b/tests/mx-rust-contracts/call-value.rs new file mode 100644 index 0000000..4d3b2a3 --- /dev/null +++ b/tests/mx-rust-contracts/call-value.rs @@ -0,0 +1,19 @@ +#![no_std] + +#[allow(unused_imports)] +use multiversx_sc::imports::*; + +#[multiversx_sc::contract] +pub trait Contract { + #[init] + fn init(&self) {} + + #[upgrade] + fn upgrade(&self) {} + + #[payable("*")] + #[endpoint(getTransfer)] + fn get_transfer(&self) -> (str, BigUint) { + self.call_value().single_fungible_esdt() + } +} diff --git a/tests/mx-rust-contracts/require.3.run b/tests/mx-rust-contracts/require.3.run index 226ddc1..26cee29 100644 --- a/tests/mx-rust-contracts/require.3.run +++ b/tests/mx-rust-contracts/require.3.run @@ -10,4 +10,4 @@ call 6 MX#managedExecuteOnDestContext; check_eq mxIntValue(0); push_return_value; -check_eq mxUnitValue() +check_eq mxListValue() diff --git a/tests/mx-rust-contracts/send.1.args b/tests/mx-rust-contracts/send.1.args new file mode 100644 index 0000000..e69de29 diff --git a/tests/mx-rust-contracts/send.1.run b/tests/mx-rust-contracts/send.1.run new file mode 100644 index 0000000..6688261 --- /dev/null +++ b/tests/mx-rust-contracts/send.1.run @@ -0,0 +1,42 @@ +addAccount("Caller"); +setBalance("TestContract", "MyToken", 0, 1234); +setCallee("Caller"); + +push mxIntValue(0); +push mxStringValue("MyToken"); +push mxStringValue("Caller"); +call 3 MX#bigIntGetESDTExternalBalance; +get_big_int; +check_eq mxIntValue(0); + +push mxIntValue(0); +push mxStringValue("MyToken"); +push mxStringValue("TestContract"); +call 3 MX#bigIntGetESDTExternalBalance; +get_big_int; +check_eq mxIntValue(1234); + +push mxListValue(mxStringValue("Caller"), mxStringValue("MyToken"), mxIntValue(10)); +push mxStringValue("sendTo"); +push mxIntValue(0); +push mxTransfersValue(); +push mxIntValue(0); +push mxStringValue("TestContract"); +call 6 MX#managedExecuteOnDestContext; +get_big_int; +check_eq mxIntValue(0); + +push mxIntValue(0); +push mxStringValue("MyToken"); +push mxStringValue("Caller"); +call 3 MX#bigIntGetESDTExternalBalance; +get_big_int; +check_eq mxIntValue(10); + +push mxIntValue(0); +push mxStringValue("MyToken"); +push mxStringValue("TestContract"); +call 3 MX#bigIntGetESDTExternalBalance; +get_big_int; +check_eq mxIntValue(1224) + diff --git a/tests/mx-rust-contracts/send.rs b/tests/mx-rust-contracts/send.rs new file mode 100644 index 0000000..616673b --- /dev/null +++ b/tests/mx-rust-contracts/send.rs @@ -0,0 +1,18 @@ +#![no_std] + +#[allow(unused_imports)] +use multiversx_sc::imports::*; + +#[multiversx_sc::contract] +pub trait Storage { + #[init] + fn init(&self) {} + + #[upgrade] + fn upgrade(&self) {} + + #[endpoint(sendTo)] + fn send_to(&self, address: ManagedAddress, token: TokenIdentifier, amount: BigUint) { + self.send().direct_esdt(address, token, 0_u64, amount); + } +} diff --git a/tests/mx-rust-contracts/token-identifier.1.args b/tests/mx-rust-contracts/token-identifier.1.args new file mode 100644 index 0000000..e69de29 diff --git a/tests/mx-rust-contracts/token-identifier.1.run b/tests/mx-rust-contracts/token-identifier.1.run new file mode 100644 index 0000000..3c3830a --- /dev/null +++ b/tests/mx-rust-contracts/token-identifier.1.run @@ -0,0 +1,25 @@ +setCallee("Owner"); + +push mxListValue(mxStringValue("MyToken"), mxStringValue("MyToken")); +push mxStringValue("testEquality"); +push mxIntValue(0); +push mxTransfersValue(); +push mxIntValue(0); +push mxStringValue("TestContract"); +call 6 MX#managedExecuteOnDestContext; +check_eq mxIntValue(0); + +push_return_value; +check_eq mxBoolValue(true); + +push mxListValue(mxStringValue("MyToken"), mxStringValue("MyOtherToken")); +push mxStringValue("testEquality"); +push mxIntValue(0); +push mxTransfersValue(); +push mxIntValue(0); +push mxStringValue("TestContract"); +call 6 MX#managedExecuteOnDestContext; +check_eq mxIntValue(0); + +push_return_value; +check_eq mxBoolValue(false) diff --git a/tests/mx-rust-contracts/token-identifier.2.args b/tests/mx-rust-contracts/token-identifier.2.args new file mode 100644 index 0000000..e69de29 diff --git a/tests/mx-rust-contracts/token-identifier.2.run b/tests/mx-rust-contracts/token-identifier.2.run new file mode 100644 index 0000000..b499b36 --- /dev/null +++ b/tests/mx-rust-contracts/token-identifier.2.run @@ -0,0 +1,13 @@ +setCallee("Owner"); + +push mxListValue(mxStringValue("MyToken")); +push mxStringValue("testClone"); +push mxIntValue(0); +push mxTransfersValue(); +push mxIntValue(0); +push mxStringValue("TestContract"); +call 6 MX#managedExecuteOnDestContext; +check_eq mxIntValue(0); + +push_return_value; +check_eq mxStringValue("MyToken") diff --git a/tests/mx-rust-contracts/token-identifier.rs b/tests/mx-rust-contracts/token-identifier.rs new file mode 100644 index 0000000..8f943c1 --- /dev/null +++ b/tests/mx-rust-contracts/token-identifier.rs @@ -0,0 +1,23 @@ +#![no_std] + +#[allow(unused_imports)] +use multiversx_sc::imports::*; + +#[multiversx_sc::contract] +pub trait Storage { + #[init] + fn init(&self) {} + + #[upgrade] + fn upgrade(&self) {} + + #[endpoint(testEquality)] + fn test_equality(&self, t1: TokenIdentifier, t2:TokenIdentifier) -> bool { + t1 == t2 + } + + #[endpoint(testClone)] + fn test_clone(&self, t: TokenIdentifier) -> TokenIdentifier { + t.clone() + } +} diff --git a/tests/mx-rust/biguint.add.run b/tests/mx-rust/biguint.add.run new file mode 100644 index 0000000..1ff677c --- /dev/null +++ b/tests/mx-rust/biguint.add.run @@ -0,0 +1,8 @@ +addAccount("Owner"); +setCallee("Owner"); +new BigUintTest; +push 2u64; +push 3u64; +call BigUintTest.add; +get_bigint_from_struct; +check_eq mxIntValue(5) diff --git a/tests/mx-rust/biguint.add64.run b/tests/mx-rust/biguint.add64.run new file mode 100644 index 0000000..98b2791 --- /dev/null +++ b/tests/mx-rust/biguint.add64.run @@ -0,0 +1,8 @@ +addAccount("Owner"); +setCallee("Owner"); +new BigUintTest; +push 2u64; +push 3u64; +call BigUintTest.add64; +get_bigint_from_struct; +check_eq mxIntValue(5) diff --git a/tests/mx-rust/biguint.div.run b/tests/mx-rust/biguint.div.run new file mode 100644 index 0000000..4362fde --- /dev/null +++ b/tests/mx-rust/biguint.div.run @@ -0,0 +1,8 @@ +addAccount("Owner"); +setCallee("Owner"); +new BigUintTest; +push 20u64; +push 3u64; +call BigUintTest.div; +get_bigint_from_struct; +check_eq mxIntValue(6) diff --git a/tests/mx-rust/biguint.div64.run b/tests/mx-rust/biguint.div64.run new file mode 100644 index 0000000..407701b --- /dev/null +++ b/tests/mx-rust/biguint.div64.run @@ -0,0 +1,8 @@ +addAccount("Owner"); +setCallee("Owner"); +new BigUintTest; +push 20u64; +push 3u64; +call BigUintTest.div64; +get_bigint_from_struct; +check_eq mxIntValue(6) diff --git a/tests/mx-rust/biguint.eq.run b/tests/mx-rust/biguint.eq.run new file mode 100644 index 0000000..6d74ec7 --- /dev/null +++ b/tests/mx-rust/biguint.eq.run @@ -0,0 +1,26 @@ +addAccount("Owner"); +setCallee("Owner"); +new BigUintTest; +set_named "self"; + +push_named "self"; +push 20u64; +push 30u64; +call BigUintTest.eq; +return_value; +check_eq false; + +push_named "self"; +push 30u64; +push 30u64; +call BigUintTest.eq; +return_value; +check_eq true; + +push_named "self"; +push 40u64; +push 30u64; +call BigUintTest.eq; +return_value; +check_eq false + diff --git a/tests/mx-rust/biguint.ge.run b/tests/mx-rust/biguint.ge.run new file mode 100644 index 0000000..8c591f4 --- /dev/null +++ b/tests/mx-rust/biguint.ge.run @@ -0,0 +1,26 @@ +addAccount("Owner"); +setCallee("Owner"); +new BigUintTest; +set_named "self"; + +push_named "self"; +push 20u64; +push 30u64; +call BigUintTest.ge; +return_value; +check_eq false; + +push_named "self"; +push 30u64; +push 30u64; +call BigUintTest.ge; +return_value; +check_eq true; + +push_named "self"; +push 40u64; +push 30u64; +call BigUintTest.ge; +return_value; +check_eq true + diff --git a/tests/mx-rust/biguint.gt.run b/tests/mx-rust/biguint.gt.run new file mode 100644 index 0000000..d5b9536 --- /dev/null +++ b/tests/mx-rust/biguint.gt.run @@ -0,0 +1,26 @@ +addAccount("Owner"); +setCallee("Owner"); +new BigUintTest; +set_named "self"; + +push_named "self"; +push 20u64; +push 30u64; +call BigUintTest.gt; +return_value; +check_eq false; + +push_named "self"; +push 30u64; +push 30u64; +call BigUintTest.gt; +return_value; +check_eq false; + +push_named "self"; +push 40u64; +push 30u64; +call BigUintTest.gt; +return_value; +check_eq true + diff --git a/tests/mx-rust/biguint.le.run b/tests/mx-rust/biguint.le.run new file mode 100644 index 0000000..9c14f53 --- /dev/null +++ b/tests/mx-rust/biguint.le.run @@ -0,0 +1,26 @@ +addAccount("Owner"); +setCallee("Owner"); +new BigUintTest; +set_named "self"; + +push_named "self"; +push 20u64; +push 30u64; +call BigUintTest.le; +return_value; +check_eq true; + +push_named "self"; +push 30u64; +push 30u64; +call BigUintTest.le; +return_value; +check_eq true; + +push_named "self"; +push 40u64; +push 30u64; +call BigUintTest.le; +return_value; +check_eq false + diff --git a/tests/mx-rust/biguint.lt.run b/tests/mx-rust/biguint.lt.run new file mode 100644 index 0000000..09efe07 --- /dev/null +++ b/tests/mx-rust/biguint.lt.run @@ -0,0 +1,26 @@ +addAccount("Owner"); +setCallee("Owner"); +new BigUintTest; +set_named "self"; + +push_named "self"; +push 20u64; +push 30u64; +call BigUintTest.lt; +return_value; +check_eq true; + +push_named "self"; +push 30u64; +push 30u64; +call BigUintTest.lt; +return_value; +check_eq false; + +push_named "self"; +push 40u64; +push 30u64; +call BigUintTest.lt; +return_value; +check_eq false + diff --git a/tests/mx-rust/biguint.mul.run b/tests/mx-rust/biguint.mul.run new file mode 100644 index 0000000..2153334 --- /dev/null +++ b/tests/mx-rust/biguint.mul.run @@ -0,0 +1,8 @@ +addAccount("Owner"); +setCallee("Owner"); +new BigUintTest; +push 15u64; +push 3u64; +call BigUintTest.mul; +get_bigint_from_struct; +check_eq mxIntValue(45) diff --git a/tests/mx-rust/biguint.mul64.run b/tests/mx-rust/biguint.mul64.run new file mode 100644 index 0000000..db44954 --- /dev/null +++ b/tests/mx-rust/biguint.mul64.run @@ -0,0 +1,8 @@ +addAccount("Owner"); +setCallee("Owner"); +new BigUintTest; +push 15u64; +push 3u64; +call BigUintTest.mul64; +get_bigint_from_struct; +check_eq mxIntValue(45) diff --git a/tests/mx-rust/biguint.ne.run b/tests/mx-rust/biguint.ne.run new file mode 100644 index 0000000..e49f403 --- /dev/null +++ b/tests/mx-rust/biguint.ne.run @@ -0,0 +1,26 @@ +addAccount("Owner"); +setCallee("Owner"); +new BigUintTest; +set_named "self"; + +push_named "self"; +push 20u64; +push 30u64; +call BigUintTest.ne; +return_value; +check_eq true; + +push_named "self"; +push 30u64; +push 30u64; +call BigUintTest.ne; +return_value; +check_eq false; + +push_named "self"; +push 40u64; +push 30u64; +call BigUintTest.ne; +return_value; +check_eq true + diff --git a/tests/mx-rust/biguint.rs b/tests/mx-rust/biguint.rs new file mode 100644 index 0000000..9a36e4d --- /dev/null +++ b/tests/mx-rust/biguint.rs @@ -0,0 +1,73 @@ +#![no_std] + +#[allow(unused_imports)] +use multiversx_sc::imports::*; + +#[multiversx_sc::contract] +pub trait BigUintTest { + #[init] + fn init(&self) {} + + #[upgrade] + fn upgrade(&self) {} + + fn zero(&self) -> BigUint { + BigUint::zero() + } + + fn add(&self, a: u64, b: u64) -> BigUint { + BigUint::from(a) + BigUint::from(b) + } + + fn sub(&self, a: u64, b: u64) -> BigUint { + BigUint::from(a) - BigUint::from(b) + } + + fn mul(&self, a: u64, b: u64) -> BigUint { + BigUint::from(a) * BigUint::from(b) + } + + fn div(&self, a: u64, b: u64) -> BigUint { + BigUint::from(a) / BigUint::from(b) + } + + fn lt(&self, a: u64, b: u64) -> bool { + BigUint::from(a) < BigUint::from(b) + } + + fn le(&self, a: u64, b: u64) -> bool { + BigUint::from(a) <= BigUint::from(b) + } + + fn gt(&self, a: u64, b: u64) -> bool { + BigUint::from(a) > BigUint::from(b) + } + + fn ge(&self, a: u64, b: u64) -> bool { + BigUint::from(a) >= BigUint::from(b) + } + + fn eq(&self, a: u64, b: u64) -> bool { + BigUint::from(a) == BigUint::from(b) + } + + fn ne(&self, a: u64, b: u64) -> bool { + BigUint::from(a) != BigUint::from(b) + } + + fn add64(&self, a: u64, b: u64) -> BigUint { + BigUint::from(a) + b + } + + fn sub64(&self, a: u64, b: u64) -> BigUint { + BigUint::from(a) - b + } + + fn mul64(&self, a: u64, b: u64) -> BigUint { + BigUint::from(a) * b + } + + fn div64(&self, a: u64, b: u64) -> BigUint { + BigUint::from(a) / b + } +} diff --git a/tests/mx-rust/biguint.sub.run b/tests/mx-rust/biguint.sub.run new file mode 100644 index 0000000..6c43115 --- /dev/null +++ b/tests/mx-rust/biguint.sub.run @@ -0,0 +1,8 @@ +addAccount("Owner"); +setCallee("Owner"); +new BigUintTest; +push 50u64; +push 3u64; +call BigUintTest.sub; +get_bigint_from_struct; +check_eq mxIntValue(47) diff --git a/tests/mx-rust/biguint.sub64.run b/tests/mx-rust/biguint.sub64.run new file mode 100644 index 0000000..0c619cf --- /dev/null +++ b/tests/mx-rust/biguint.sub64.run @@ -0,0 +1,8 @@ +addAccount("Owner"); +setCallee("Owner"); +new BigUintTest; +push 50u64; +push 3u64; +call BigUintTest.sub64; +get_bigint_from_struct; +check_eq mxIntValue(47) diff --git a/tests/mx-rust/biguint.zero.run b/tests/mx-rust/biguint.zero.run new file mode 100644 index 0000000..9c16cd1 --- /dev/null +++ b/tests/mx-rust/biguint.zero.run @@ -0,0 +1,6 @@ +addAccount("Owner"); +setCallee("Owner"); +new BigUintTest; +call BigUintTest.zero; +get_bigint_from_struct; +check_eq mxIntValue(0)