diff --git a/Library/src/CodeGen/Libraries.cs b/Library/src/CodeGen/Libraries.cs index c680f51..610d2ae 100644 --- a/Library/src/CodeGen/Libraries.cs +++ b/Library/src/CodeGen/Libraries.cs @@ -273,7 +273,7 @@ public static LibraryDeclaration LoadLibrary(string name, Scope scope, ModuleKin libDecl.AddMethod("isSystem", MethodImplementationType.Custom, VarKind.Bool, new[] { new MethodParameter("target", VarKind.Address) }); libDecl.AddMethod("isInterop", MethodImplementationType.Custom, VarKind.Bool, new[] { new MethodParameter("target", VarKind.Address) }); - GenerateCasts(libDecl, VarKind.Bytes, new VarKind[] { VarKind.String }); + GenerateCasts(libDecl, VarKind.Address, new VarKind[] { VarKind.String }); return libDecl; } diff --git a/Library/tests/CodeGen/CodeGeneratorTests.cs b/Library/tests/CodeGen/CodeGeneratorTests.cs index 1eaac08..187d775 100644 --- a/Library/tests/CodeGen/CodeGeneratorTests.cs +++ b/Library/tests/CodeGen/CodeGeneratorTests.cs @@ -1,6 +1,90 @@ namespace TOMBLib.Tests.CodeGen; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using Phantasma.Core.Cryptography.Structs; +using Phantasma.Core.Domain; +using Phantasma.Core.Domain.Execution.Enums; +using Phantasma.Core.Domain.VM; +using Phantasma.Core.Utils; +using Phantasma.Tomb.Compilers; + public class CodeGeneratorTests -{ - +{ + [Test] + public void AutoCasts() + { + var sourceCode = + @" +contract test { + import Address; + + public castTest(x:address): string { + return Address.toString(x); + } +}"; + + var parser = new TombLangCompiler(); + var contract = parser.Process(sourceCode).First(); + + var storage = new Dictionary(new ByteArrayComparer()); + + var cast = contract.abi.FindMethod("castTest"); + Assert.IsNotNull(cast); + + var expected = "P2K7GyVMC3f9XxKRji5gfg91WvutoHs2RyB6KzQxuaAUUeo"; + var addr = Address.FromText(expected); + + var vm = new TestVM(contract, storage, cast); + vm.Stack.Push(VMObject.FromObject(addr)); + var result = vm.Execute(); + Assert.IsTrue(result == ExecutionState.Halt); + + Assert.IsTrue(vm.Stack.Count == 1); + var val = vm.Stack.Pop().AsString(); + Assert.IsTrue(val == expected); + } + + [Test] + public void IfWithOr() + { + var sourceCode = + @" +contract test { + public check(x:number, y:number): bool { + return (x > 0) && (y < 0); + } +}"; + + var parser = new TombLangCompiler(); + var contract = parser.Process(sourceCode).First(); + + var storage = new Dictionary(new ByteArrayComparer()); + + var countStuff = contract.abi.FindMethod("check"); + Assert.IsNotNull(countStuff); + + var vm = new TestVM(contract, storage, countStuff); + // NOTE - due to using a stack, we're pushing the second argument first (y), then the first argument (y) + vm.Stack.Push(VMObject.FromObject(-3)); + vm.Stack.Push(VMObject.FromObject(3)); + var result = vm.Execute(); + Assert.IsTrue(result == ExecutionState.Halt); + + Assert.IsTrue(vm.Stack.Count == 1); + var val = vm.Stack.Pop().AsBool(); + Assert.IsTrue(val); + + vm = new TestVM(contract, storage, countStuff); + // NOTE - here we invert the order, in this case should fail due to the condition in the contract inside check() + vm.Stack.Push(VMObject.FromObject(3)); + vm.Stack.Push(VMObject.FromObject(-3)); + result = vm.Execute(); + Assert.IsTrue(result == ExecutionState.Halt); + + Assert.IsTrue(vm.Stack.Count == 1); + val = vm.Stack.Pop().AsBool(); + Assert.IsFalse(val); + } } \ No newline at end of file diff --git a/README.md b/README.md index 2f72598..7f8cc07 100644 --- a/README.md +++ b/README.md @@ -859,6 +859,9 @@ See examples below:
```c# contract test { import Time; + import Hash; + import String; + import Address; public convertTimeToNumber(x:timestamp):number { @@ -875,6 +878,11 @@ contract test { return String.toNumber(x); } + public convertAddressToString(x:address):string + { + return Address.toString(x); + } + } ```