From 38070ac9e7aa46f771554af0b63c5ac72b0d647e Mon Sep 17 00:00:00 2001 From: Jacques Wagener Date: Fri, 25 Oct 2019 11:00:44 +0200 Subject: [PATCH] Add support for storing booleans --- nimplay/nimplay_macros.nim | 19 +++++++++++++++++-- nimplay/storage.nim | 39 +++++++++++++++++++++++++++++++++++--- nimplay/types.nim | 7 +++++++ nimplay/utils.nim | 1 + 4 files changed, 61 insertions(+), 5 deletions(-) diff --git a/nimplay/nimplay_macros.nim b/nimplay/nimplay_macros.nim index 435c20e..d90d389 100644 --- a/nimplay/nimplay_macros.nim +++ b/nimplay/nimplay_macros.nim @@ -58,6 +58,13 @@ proc get_local_input_type_conversion(tmp_var_name, tmp_var_converted_name, var_t proc get_local_output_type_conversion(tmp_result_name, tmp_result_converted_name, var_type: string): (NimNode, NimNode) = case var_type + of "bool": + var ident_node = newIdentNode(tmp_result_converted_name) + var conversion_node = parseStmt(unindent(fmt""" + var {tmp_result_converted_name}: array[32, byte] + if tmp_result_name: {tmp_result_converted_name}[31] = 1 + """)) + return (ident_node, conversion_node) of "uint256": var ident_node = newIdentNode(tmp_result_converted_name) var conversion_node = nnkVarSection.newTree( @@ -241,7 +248,7 @@ template get_util_functions() {.dirty.} = break to_ba[offset + i] = x - func to_bytes32(a: uint128): bytes32 = + func to_bytes32(a: auto): bytes32 = var tmp: bytes32 copy_into_ba(tmp, 0, a.toBytesLE) @@ -249,12 +256,20 @@ template get_util_functions() {.dirty.} = func to_uint128(a: bytes32): uint128 = var - tmp_ba: array[32, byte] + tmp_ba {.noinit.}: array[32, byte] tmp: uint128 copy_into_ba(tmp_ba, 0, a) tmp = fromBytes(Uint128, tmp_ba) tmp + func to_uint256(a: bytes32): uint256 = + var + tmp_ba {.noinit.}: array[32, byte] + tmp: uint256 + copy_into_ba(tmp_ba, 0, a) + tmp = fromBytes(Uint256, tmp_ba) + tmp + proc assertNotPayable() = var b {.noinit.}: array[16, byte] getCallValue(addr b) diff --git a/nimplay/storage.nim b/nimplay/storage.nim index 8eca339..3187442 100644 --- a/nimplay/storage.nim +++ b/nimplay/storage.nim @@ -61,6 +61,19 @@ proc generate_storage_get_func*(storage_keyword: string, global_ctx: GlobalConte return tmp """) return (new_proc, new_proc_name) + elif var_info.var_type == "bool": + var new_proc = parseStmt(fmt""" + proc {new_proc_name}(): bool = + var + tmp {{.noinit.}}: bytes32 + pos = {$slot_number}.stuint(32).toByteArrayBE + storageLoad(pos, addr tmp) + if tmp[31] == 1: + return true + else: + return false + """) + return (new_proc, new_proc_name) else: raise newException(ParserError, var_info.var_type & " storage is not supported at the moment.") @@ -111,6 +124,17 @@ proc generate_storage_set_func*(storage_keyword: string, global_ctx: GlobalConte storageStore(pos, unsafeAddr value) """) return (new_proc, new_proc_name) + elif var_info.var_type == "bool": + var new_proc = parseStmt(fmt""" + proc {new_proc_name}(value: bool) = + var + pos = {$slot_number}.stuint(32).toByteArrayBE + v: bytes32 + if value: + v[31] = 1u8 + storageStore(pos, unsafeAddr value) + """) + return (new_proc, new_proc_name) else: raise newException(ParserError, var_info.var_type & " storage is not supported at the moment.") @@ -147,16 +171,20 @@ proc generate_storage_table_set_func*(storage_keyword: string, global_ctx: Globa (value_conversion, key_param_arr, key_copy_block, total_key_size) = get_combined_key_info(var_info) if value_type == "bytes32": - value_conversion = "val" + value_conversion = "tmp_val = val" elif value_type in @["wei_value", "uint128"]: - value_conversion = "val.to_bytes32" + value_conversion = "tmp_val = val.to_bytes32" + elif value_type == "uint256": + value_conversion = "tmp_val = val.to_bytes32" + elif value_type == "bool": + value_conversion = "if val: tmp_val[31] = 1" else: raise newException(ParserError, "Unsupported '{value_type}' value type.") var s = fmt""" proc {new_proc_name}({key_param_arr.join(",")}, val: {value_type}) = var - tmp_val = {value_conversion} + {value_conversion} combined_key {{.noinit.}}: array[{total_key_size}, byte] {key_copy_block} setTableValue({table_id}.int32, combined_key, tmp_val) @@ -174,11 +202,16 @@ proc generate_storage_table_get_func*(storage_keyword: string, global_ctx: Globa value_type = var_info.key_types[^1] table_id = var_info.slot (value_conversion, key_param_arr, key_copy_block, total_key_size) = get_combined_key_info(var_info) + echo value_type if value_type == "bytes32": value_conversion = "tmp_val" + elif value_type == "bool": + value_conversion = "tmp_val[31] == 1" elif value_type in @["wei_value", "uint128"]: value_conversion = "tmp_val.to_uint128" + elif value_type == "uint256": + value_conversion = "tmp_val.to_uint256" else: raise newException(ParserError, "Unsupported StorageTable '{value_type}' value type.") diff --git a/nimplay/types.nim b/nimplay/types.nim index ade9ef5..bfb8b24 100644 --- a/nimplay/types.nim +++ b/nimplay/types.nim @@ -77,3 +77,10 @@ let TYPE_NAMES* {.compileTime.} = @["address", "uint256", "bytes32", "int128", "uint128"] ALL_KEYWORDS* {.compileTime.} = concat(TYPE_NAMES, KEYWORDS) ALLOWED_PRAGMAS* {.compileTime.} = @["payable", "event", "self", "msg", "log"] + +# Constants + +let ZERO_ADDRESS*: address = [ + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, + 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8 +] diff --git a/nimplay/utils.nim b/nimplay/utils.nim index eafb098..7efdbf6 100644 --- a/nimplay/utils.nim +++ b/nimplay/utils.nim @@ -63,6 +63,7 @@ proc check_valid_variable_name*(node: NimNode, global_ctx: GlobalContext) = proc get_byte_size_of*(type_str: string): int = let BASE32_TYPES_NAMES: array = [ + "bool", "uint256", "uint128", "int128",