From 72a60c6e4ebd9bfeeecb67b5b51793130f0809d3 Mon Sep 17 00:00:00 2001 From: z80 Date: Thu, 14 Dec 2023 00:11:58 -0500 Subject: [PATCH] 0.1.29 w/ IR changes --- dasy/__init__.py | 2 +- dasy/builtin/functions.py | 33 ++++++++++++++++++++++++++++----- dasy/parser/utils.hy | 22 +++++++++++++++++++++- examples/venom.dasy | 17 ++++------------- examples/venom_comp.vy | 5 +---- pyproject.toml | 2 +- tests/parser/test_utils.py | 11 ++++++++++- tests/test_dasy.py | 4 ++-- 8 files changed, 68 insertions(+), 28 deletions(-) diff --git a/dasy/__init__.py b/dasy/__init__.py index a4db70b..ddeaf5c 100644 --- a/dasy/__init__.py +++ b/dasy/__init__.py @@ -6,4 +6,4 @@ from .parser import parse from .parser.parse import parse_src, parse_node -__version__ = "0.1.28" +__version__ = "0.1.29" diff --git a/dasy/builtin/functions.py b/dasy/builtin/functions.py index 8e4f813..daa7662 100644 --- a/dasy/builtin/functions.py +++ b/dasy/builtin/functions.py @@ -2,16 +2,29 @@ from vyper.ast import Call, Expr from vyper.ir.s_expressions import parse_s_exp from vyper.codegen.ir_node import IRnode -from vyper.builtins.functions import STMT_DISPATCH_TABLE, BuiltinFunction +from vyper.builtins.functions import ( + STMT_DISPATCH_TABLE, + DISPATCH_TABLE, + BuiltinFunction, +) from vyper.compiler import phases from dasy import parser +from dasy.parser.utils import get_ir_type from hy import repr -def parse_venom(expr): - ir = IRnode.from_list((parse_s_exp(repr(expr[1])[1:]))[0]) +def parse_ir(expr): + # check for optional return type annotation as second element + ret_type = None + ir_expr = None + if len(expr) == 3: + ret_type = get_ir_type(expr[1].name) + ir_expr = expr[2] + elif len(expr) == 2: + ir_expr = expr[1] + ir = IRnode.from_list((parse_s_exp(repr(ir_expr)[1:]))[0], typ=ret_type) # generate some vyper code to patch in. IDENTIFIER = f"__DASY_VENOM_BUILTIN_{parser.next_nodeid()}__" @@ -21,13 +34,23 @@ def parse_venom(expr): class generated_builtin(BuiltinFunction): _id = IDENTIFIER _inputs = () - _return_type = None + _return_type = ret_type + + def fetch_call_return(self, node): + return self._return_type + + def infer_arg_types(self, node): + return [] def build_IR(self, expr, context): return ir - STMT_DISPATCH_TABLE[IDENTIFIER] = generated_builtin() + if ret_type is not None: + DISPATCH_TABLE[IDENTIFIER] = generated_builtin() + gend_ast = phases.generate_ast(insert_code, 0, "") + return gend_ast[1].body[0].value + STMT_DISPATCH_TABLE[IDENTIFIER] = generated_builtin() return phases.generate_ast(insert_code, 0, "")[1].body[0] diff --git a/dasy/parser/utils.hy b/dasy/parser/utils.hy index 1ea3706..259b4e4 100644 --- a/dasy/parser/utils.hy +++ b/dasy/parser/utils.hy @@ -1,6 +1,26 @@ (import vyper.ast.nodes * hy.models [Symbol Sequence] - hyrule.iterables [flatten]) + hyrule.iterables [flatten] + vyper.semantics.types.primitives [SINT UINT BytesM_T]) + +(require + hyrule.control [branch] + hyrule.argmove [->]) + +(defn get-ir-type [name] + ;; check if starts with "uint" or "int" + ;; if so, return the corresponding type + ;; otherwise, return None + (let [name-str (str name) + [type-constructor size-index] (branch (name-str.startswith it) + "uint" [UINT 4] + "int" [SINT 3] + "bytes" [BytesM_T 5] + )] + (-> name-str + (cut size-index None) + int + type-constructor))) (require hyrule [assoc] diff --git a/examples/venom.dasy b/examples/venom.dasy index b36c86f..94f4fd7 100644 --- a/examples/venom.dasy +++ b/examples/venom.dasy @@ -1,16 +1,7 @@ (defn retOne [] :uint256 :external - (defvar x :uint256 0) - (venom (mstore 64 1)) - x) + (ir :uint256 (seq 1))) - -;; this works as-is but unecessary variable costs gas (defn addTwoNums [:uint256 x y] :uint256 :external - (defvar z :uint256 0) ;; first variable is at offset 64 - (venom (mstore 64 (add (calldataload 4) (calldataload 36)))) - z) - -;; ;; this might be ideal, removing implicit returns around venom blocks -;; (defn addTwoNums2 [:uint256 x y] :uint256 :external -;; (venom (seq -;; (mstore 64 (add (calldataload 4) (calldataload 36)))))) + (ir :uint256 + (add (calldataload 4) + (calldataload 36)))) diff --git a/examples/venom_comp.vy b/examples/venom_comp.vy index d15cd60..50b5610 100644 --- a/examples/venom_comp.vy +++ b/examples/venom_comp.vy @@ -1,11 +1,8 @@ @external def retOne() -> uint256: - x: uint256 = 0 - x = 1 - return x + return 1 -# 71 gas @external def addTwoNums(a: uint256, b: uint256) -> uint256: return unsafe_add(a, b) diff --git a/pyproject.toml b/pyproject.toml index e85f977..52392f3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "dasy" -version = "0.1.28" +version = "0.1.29" description = "an evm lisp" authors = ["z80 "] diff --git a/tests/parser/test_utils.py b/tests/parser/test_utils.py index 4229efd..2c5cf51 100644 --- a/tests/parser/test_utils.py +++ b/tests/parser/test_utils.py @@ -1,4 +1,13 @@ -from dasy.parser.utils import process_body, add_src_map, set_parent_children, build_node, next_node_id_maker, pairwise, filename_to_contract_name, has_return +from dasy.parser.utils import ( + process_body, + add_src_map, + set_parent_children, + build_node, + next_node_id_maker, + pairwise, + filename_to_contract_name, + has_return, +) from vyper.ast.nodes import Expr import dasy diff --git a/tests/test_dasy.py b/tests/test_dasy.py index 8e45ff2..c5e9e84 100644 --- a/tests/test_dasy.py +++ b/tests/test_dasy.py @@ -319,12 +319,12 @@ def testInterface(): def test_reentrancy(): - c = compile("examples/nonreentrant.dasy") # noqa: F841 + c = compile("examples/nonreentrant.dasy") # noqa: F841 def test_auction(): a = boa.env.generate_address() - c = compile("examples/simple_auction.dasy", a, 100, 10000000) # noqa: F841 + c = compile("examples/simple_auction.dasy", a, 100, 10000000) # noqa: F841 def test_token():