Skip to content

Adding boolean operators #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions lib/primitives.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ type address = string
type uint = UInt of int
type sint = SInt of int


let caller () = assert false

(* binary operators for unsigned int *)
Expand All @@ -15,3 +16,10 @@ let ( + ) (SInt x) (SInt y) = SInt (x + y)
let ( - ) (SInt x) (SInt y) = SInt (x - y)
let ( * ) (SInt x) (SInt y) = SInt (x * y)
let ( / ) (SInt x) (SInt y) = SInt (x / y)

(* operations for boolean *)
(* let ( && ) b1 b2 = b1 && b2
let ( || ) b1 b2 = b1 || b2
let not b = not b
let (==) b1 b2 = b1 == b2
let (!=) b1 b2 = not (b1 == b2) *)
7 changes: 7 additions & 0 deletions lib/primitives.mli
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
type address
type uint = UInt of int
type sint = SInt of int
(* type bool_ = bool *)

val caller : unit -> address

Expand All @@ -15,3 +16,9 @@ val ( + ) : sint -> sint -> sint
val ( - ) : sint -> sint -> sint
val ( * ) : sint -> sint -> sint
val ( / ) : sint -> sint -> sint

(* val ( && ) : bool_ -> bool_ -> bool_
val ( || ) : bool_ -> bool_ -> bool_
val not : bool_ -> bool_
val ( == ) : bool_ -> bool_ -> bool_
val ( != ) : bool_ -> bool_ -> bool_ *)
75 changes: 75 additions & 0 deletions sample/contract_test/SimpleStorageIf.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
const assert = require('assert');
const ganache = require('ganache');
const { Web3 } = require('web3');

const web3 = new Web3(ganache.provider())

const { abi, bytecode } = require('../contracts/SimpleStorageIf.json');

describe('SimpleStorageIf', async () => {
let accounts;
let contract;
let from;

beforeEach(async () => {
accounts = await web3.eth.getAccounts();
from = accounts[0];

contract = await new web3.eth.Contract(JSON.parse(JSON.stringify(abi)))
.deploy({ data: bytecode })
.send({ from: accounts[0], gas: 1000000 });

await contract.methods.set(100).send({ from: from });
});

it('should deploy', () => {
assert.ok(contract.options.address);
});

it('getting value', async () => {
const v = await contract.methods.get(from).call();
assert.equal(100, v);
});

it('setting value', async () => {
await contract.methods.set(200).send({ from: from });
const v = await contract.methods.get().call();
assert.equal(200, v);
});

it('is less than value', async () => {
const v = await contract.methods.lt(1, 2).call();
assert.equal(true, v);
});

it('is greater than value', async () => {
const v = await contract.methods.gt(1, 2).call();
assert.equal(false, v);
});

it('is less than equal value', async () => {
const v = await contract.methods.lte(1, 1).call();
assert.equal(true, v);
});

it('is greater than equal value', async () => {
const v = await contract.methods.gte(1, 1).call();
assert.equal(true, v);
});

it('calculate xor', async () => {
const v = await contract.methods.xor(true, true).call();
assert.equal(false, v);
});

it('equalize xor2 to xor', async () => {
const v = await contract.methods.xor(false, true).call();
const v2 = await contract.methods.xor2(false, true).call();
assert.equal(v, v2);
});

it('calculate max', async () => {
const v = await contract.methods.max(5, 3).call();
assert.equal(5, v);
});
});
84 changes: 84 additions & 0 deletions sample/contracts/SimpleStorageIf.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
{
"contractName": "SimpleStorageIf",
"abi": [
{
"name": "max",
"type": "function",
"inputs": [
{ "name": "", "type": "int256" }, { "name": "", "type": "int256" }
],
"outputs": [ { "name": "", "type": "int256" } ],
"stateMutability": "view"
},
{
"name": "xor2",
"type": "function",
"inputs": [
{ "name": "", "type": "bool" }, { "name": "", "type": "bool" }
],
"outputs": [ { "name": "", "type": "bool" } ],
"stateMutability": "view"
},
{
"name": "xor",
"type": "function",
"inputs": [
{ "name": "", "type": "bool" }, { "name": "", "type": "bool" }
],
"outputs": [ { "name": "", "type": "bool" } ],
"stateMutability": "view"
},
{
"name": "gte",
"type": "function",
"inputs": [
{ "name": "", "type": "int256" }, { "name": "", "type": "int256" }
],
"outputs": [ { "name": "", "type": "bool" } ],
"stateMutability": "view"
},
{
"name": "lte",
"type": "function",
"inputs": [
{ "name": "", "type": "int256" }, { "name": "", "type": "int256" }
],
"outputs": [ { "name": "", "type": "bool" } ],
"stateMutability": "view"
},
{
"name": "gt",
"type": "function",
"inputs": [
{ "name": "", "type": "int256" }, { "name": "", "type": "int256" }
],
"outputs": [ { "name": "", "type": "bool" } ],
"stateMutability": "view"
},
{
"name": "lt",
"type": "function",
"inputs": [
{ "name": "", "type": "int256" }, { "name": "", "type": "int256" }
],
"outputs": [ { "name": "", "type": "bool" } ],
"stateMutability": "view"
},
{
"name": "get",
"type": "function",
"inputs": [],
"outputs": [ { "name": "", "type": "int256" } ],
"stateMutability": "view"
},
{
"name": "set",
"type": "function",
"inputs": [ { "name": "", "type": "int256" } ],
"outputs": [],
"stateMutability": "nonpayable"
}
],
"bytecode": "335f556102f36100115f396102f35ff3fe6100076102d5565b8063e5c19b2d146101a25780636d4ce63c1461018c5780633088003814610163578063ac08973d1461013a57806350b978401461011157806344f45307146100e8578063e95e21bc146100bf578063fd3ce04014610096576381fe57861461006d575f80fd5b6100906100786102c4565b61008260016102dd565b61008b5f6102dd565b61028f565b506102ca565b6100b96100a16102c4565b6100ab60016102e7565b6100b45f6102e7565b61022c565b506102ca565b6100e26100ca6102c4565b6100d460016102e7565b6100dd5f6102e7565b6101f4565b506102ca565b61010b6100f36102c4565b6100fd60016102dd565b6101065f6102dd565b6101eb565b506102ca565b61013461011c6102c4565b61012660016102dd565b61012f5f6102dd565b6101e2565b506102ca565b61015d6101456102c4565b61014f60016102dd565b6101585f6102dd565b6101da565b506102ca565b61018661016e6102c4565b61017860016102dd565b6101815f6102dd565b6101d2565b506102ca565b61019c6101976102c4565b6101cd565b506102ca565b6101c36101be6101b06102c4565b6101b95f6102dd565b6101c8565b6102bf565b6102d1565b905090565b908190565b929192109190565b929192119190565b92919211159190565b92919210159190565b92919280918115610223575b8161021b575b501581610213575b509190565b90505f61020e565b90505f610206565b80925091610200565b909291925f918060011461026a575f1461024657505b9190565b80600114610261575f1461025a575b610242565b505f610255565b50506001610255565b5080600114610287575f1461027f575b610242565b50600161027a565b50505f61027a565b90929192808211915f9290816001146102b657505f146102af57505b9190565b90506102ab565b925050506102ab565b600155565b60015490565b5f5260205ff35b5f80f35b5f3560e01c90565b6020026004013590565b6102f0906102dd565b9056",
"deployedBytecode": "6100076102d5565b8063e5c19b2d146101a25780636d4ce63c1461018c5780633088003814610163578063ac08973d1461013a57806350b978401461011157806344f45307146100e8578063e95e21bc146100bf578063fd3ce04014610096576381fe57861461006d575f80fd5b6100906100786102c4565b61008260016102dd565b61008b5f6102dd565b61028f565b506102ca565b6100b96100a16102c4565b6100ab60016102e7565b6100b45f6102e7565b61022c565b506102ca565b6100e26100ca6102c4565b6100d460016102e7565b6100dd5f6102e7565b6101f4565b506102ca565b61010b6100f36102c4565b6100fd60016102dd565b6101065f6102dd565b6101eb565b506102ca565b61013461011c6102c4565b61012660016102dd565b61012f5f6102dd565b6101e2565b506102ca565b61015d6101456102c4565b61014f60016102dd565b6101585f6102dd565b6101da565b506102ca565b61018661016e6102c4565b61017860016102dd565b6101815f6102dd565b6101d2565b506102ca565b61019c6101976102c4565b6101cd565b506102ca565b6101c36101be6101b06102c4565b6101b95f6102dd565b6101c8565b6102bf565b6102d1565b905090565b908190565b929192109190565b929192119190565b92919211159190565b92919210159190565b92919280918115610223575b8161021b575b501581610213575b509190565b90505f61020e565b90505f610206565b80925091610200565b909291925f918060011461026a575f1461024657505b9190565b80600114610261575f1461025a575b610242565b505f610255565b50506001610255565b5080600114610287575f1461027f575b610242565b50600161027a565b50505f61027a565b90929192808211915f9290816001146102b657505f146102af57505b9190565b90506102ab565b925050506102ab565b600155565b60015490565b5f5260205ff35b5f80f35b5f3560e01c90565b6020026004013590565b6102f0906102dd565b9056"
}
31 changes: 0 additions & 31 deletions sample/src/simple_hash_if.ml

This file was deleted.

36 changes: 36 additions & 0 deletions sample/src/simple_storage_if.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
open OCamYul.Primitives

module SimpleStorageIf : sig
type storage

val set : sint -> storage -> unit * storage
val get : unit -> storage -> sint * storage
val lt : sint * sint -> storage -> bool * storage
val gt : sint * sint -> storage -> bool * storage
val lte : sint * sint -> storage -> bool * storage
val gte : sint * sint -> storage -> bool * storage
val xor : bool * bool -> storage -> bool * storage
val xor2 : bool * bool -> storage -> bool * storage
val max : sint * sint -> storage -> sint * storage
end = struct
type storage = sint

let set n _ = ((), n)
let get () s = (s, s)
let lt (x, y) s = (x < y, s)
let gt (x, y) s = (x > y, s)
let lte (x, y) s = (x <= y, s)
let gte (x, y) s = (x >= y, s)

let xor (x, y) s =
let b = (x || y) && not (x && y) in
(b, s)

let xor2 (x, y) s =
let b = if x then (if y then false else true) else (if y then true else false) in
(b, s)

let max (n, m) s =
let b = n > m in
((if b then n else m), s)
end
3 changes: 2 additions & 1 deletion src/abi.ml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ type abi = {
and input = { input_name : string; input_type : param_type }
and output = { output_name : string; output_type : param_type }
and abi_type = Func
and param_type = Uint256 | Int256 | Address
and param_type = Uint256 | Int256 | Address | Bool
and state_mutability = Pure | View | Nonpayable | Payable

let stronger_mutability mut1 mut2 =
Expand All @@ -23,6 +23,7 @@ let string_of_param_type = function
| Uint256 -> "uint256"
| Int256 -> "int256"
| Address -> "address"
| Bool -> "bool"

let string_of_mutability = function
| Pure -> "pure"
Expand Down
2 changes: 1 addition & 1 deletion src/abi.mli
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type abi = {
and input = { input_name : string; input_type : param_type }
and output = { output_name : string; output_type : param_type }
and abi_type = Func
and param_type = Uint256 | Int256 | Address
and param_type = Uint256 | Int256 | Address | Bool
and state_mutability = Pure | View | Nonpayable | Payable

val string_of_mutability : state_mutability -> string
Expand Down
24 changes: 22 additions & 2 deletions src/anormal_ir.ml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,34 @@ let const_to_aval = function
| _ -> assert false

let get_bop s =
if s = "+^" then UAdd
match s with
| "+^" -> UAdd
| "-^" -> USub
| "*^" -> UMul
| "/^" -> UDiv
| "+" -> SAdd
| "-" -> SSub
| "*" -> SMul
| "/" -> SDiv
| "&&" -> And
| "||" -> Or
| "not" -> Not
| "=" -> Eq
| "!=" -> Neq
| "<" -> Lt
| ">" -> Gt
| "<=" -> Lte
| ">=" -> Gte
| _ -> assert false
(*if s = "+^" then UAdd
else if s = "-^" then USub
else if s = "*^" then UMul
else if s = "/^" then UDiv
else if s = "+" then SAdd
else if s = "-" then SSub
else if s = "*" then SMul
else if s = "/" then SDiv
else assert false
else assert false*)

(* operation functions made usable especially, such as replace caller*)
let pdot_to_aval p s =
Expand All @@ -32,6 +51,7 @@ let pdot_to_aval p s =
if Ident.name id = "OCamYul" then
if s = "caller" then Caller else Bop (get_bop s)
else assert false
| Path.Pident id -> if Ident.name id = "Stdlib" then Bop (get_bop s) else assert false
| _ -> assert false

(* The first argument p is a storage. To check whether the storage changes, it is needed.
Expand Down
11 changes: 10 additions & 1 deletion src/normalized_common_ast.ml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
type bop = UAdd | USub | UMul | UDiv | SAdd | SSub | SMul | SDiv
type bop = UAdd | USub | UMul | UDiv | SAdd | SSub | SMul | SDiv | And | Or | Not | Eq | Neq | Lt | Gt | Lte | Gte

type value =
| Var of string
Expand All @@ -20,6 +20,15 @@ let string_of_bop = function
| SSub -> "-"
| SMul -> "*"
| SDiv -> "/"
| And -> "&&"
| Or -> "||"
| Not -> "not"
| Eq -> "="
| Neq -> "!="
| Lt -> "<"
| Gt -> ">"
| Lte -> "<="
| Gte -> ">="

let string_of_value = function
| Var s -> s
Expand Down
2 changes: 1 addition & 1 deletion src/normalized_common_ast.mli
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(** binary operators for signed/unsigned integers *)
type bop = UAdd | USub | UMul | UDiv | SAdd | SSub | SMul | SDiv
type bop = UAdd | USub | UMul | UDiv | SAdd | SSub | SMul | SDiv | And | Or | Not | Eq | Neq | Lt | Gt | Lte | Gte

(** a common part of value expressions *)
type value =
Expand Down
Loading