mirror of https://github.com/status-im/nimplay.git
Basic getting works now.
This commit is contained in:
parent
6678882031
commit
55cf1b34fb
|
@ -56,3 +56,6 @@ contract("MapStorage"):
|
||||||
|
|
||||||
|
|
||||||
# tx = contract_.functions.set_name(b"key", b"value").buildTransaction({'from': acct.address, 'nonce': w3.eth.getTransactionCount(acct.address)})
|
# tx = contract_.functions.set_name(b"key", b"value").buildTransaction({'from': acct.address, 'nonce': w3.eth.getTransactionCount(acct.address)})
|
||||||
|
# signed = acct.signTransaction(tx)
|
||||||
|
# tx_hash = w3.eth.sendRawTransaction(signed.rawTransaction)
|
||||||
|
# receipt = w3.eth.waitForTransactionReceipt(tx_hash)
|
||||||
|
|
|
@ -5,8 +5,8 @@ contract("Registry"):
|
||||||
|
|
||||||
names: StorageTable[bytes32, bytes32]
|
names: StorageTable[bytes32, bytes32]
|
||||||
|
|
||||||
proc set_name*(k: bytes32, v: bytes32) {.self,msg.} =
|
proc set_name*(k: bytes32, v: bytes32) {.self.} =
|
||||||
self.names[k] = v
|
self.names[k] = v
|
||||||
|
|
||||||
# proc get_name(k: bytes32) {.self.} =
|
proc get_name*(k: bytes32): bytes32 {.self.} =
|
||||||
# self.names[k]
|
self.names[k]
|
||||||
|
|
|
@ -55,14 +55,14 @@ proc is_log_statement(node: NimNode, global_ctx: GlobalContext): bool =
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
proc has_self_assignment(node: NimNode, global_ctx: GlobalContext): bool =
|
proc has_self_assignment(node: NimNode): bool =
|
||||||
if node.kind == nnkAsgn:
|
if node.kind == nnkAsgn:
|
||||||
if is_dot_variable(node[0]) and node[0][0].strVal == "self":
|
if is_dot_variable(node[0]) and node[0][0].strVal == "self":
|
||||||
return true
|
return true
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
|
||||||
proc has_self_storage_table(node: NimNode, global_ctx: GlobalContext): bool =
|
proc has_self_storage_table_set(node: NimNode): bool =
|
||||||
if node.kind == nnkAsgn and node[0].kind == nnkBracketExpr:
|
if node.kind == nnkAsgn and node[0].kind == nnkBracketExpr:
|
||||||
if is_dot_variable(node[0][0]) and node[0][0][0].strVal == "self":
|
if is_dot_variable(node[0][0]) and node[0][0][0].strVal == "self":
|
||||||
echo treeRepr(node)
|
echo treeRepr(node)
|
||||||
|
@ -70,14 +70,22 @@ proc has_self_storage_table(node: NimNode, global_ctx: GlobalContext): bool =
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
|
||||||
|
proc has_self_storage_table_get(node: NimNode): bool =
|
||||||
|
if node.kind == nnkBracketExpr and is_dot_variable(node[0]):
|
||||||
|
return true
|
||||||
|
return false
|
||||||
|
|
||||||
|
|
||||||
proc is_keyword(node: NimNode, global_ctx: GlobalContext): (bool, string) =
|
proc is_keyword(node: NimNode, global_ctx: GlobalContext): (bool, string) =
|
||||||
if is_message_sender(node):
|
if is_message_sender(node):
|
||||||
return (true, "msg.sender")
|
return (true, "msg.sender")
|
||||||
if is_message_value(node):
|
if is_message_value(node):
|
||||||
return (true, "msg.value")
|
return (true, "msg.value")
|
||||||
elif has_self_storage_table(node, global_ctx):
|
elif has_self_storage_table_set(node):
|
||||||
return (true, "set_table_self."& strVal(node[0][0][1]))
|
return (true, "set_table_self." & strVal(node[0][0][1]))
|
||||||
elif has_self_assignment(node, global_ctx):
|
elif has_self_storage_table_get(node):
|
||||||
|
return (true, "get_table_self." & strVal(node[0][1]))
|
||||||
|
elif has_self_assignment(node):
|
||||||
return (true, "set_self." & strVal(node[0][1]))
|
return (true, "set_self." & strVal(node[0][1]))
|
||||||
elif has_self(node, global_ctx):
|
elif has_self(node, global_ctx):
|
||||||
return (true, "self." & strVal(node[1]))
|
return (true, "self." & strVal(node[1]))
|
||||||
|
@ -90,8 +98,14 @@ proc is_keyword(node: NimNode, global_ctx: GlobalContext): (bool, string) =
|
||||||
proc find_builtin_keywords(func_body: NimNode, used_keywords: var seq[string], global_ctx: GlobalContext) =
|
proc find_builtin_keywords(func_body: NimNode, used_keywords: var seq[string], global_ctx: GlobalContext) =
|
||||||
for child in func_body:
|
for child in func_body:
|
||||||
let (is_kw, kw_key_name) = is_keyword(child, global_ctx)
|
let (is_kw, kw_key_name) = is_keyword(child, global_ctx)
|
||||||
var setter_kw = false
|
var
|
||||||
for proposed_setter_kw in @["set_" & kw_key_name, "set_table_" & kw_key_name]:
|
setter_kw = false
|
||||||
|
setter_exemption_list = @[
|
||||||
|
"set_" & kw_key_name,
|
||||||
|
"set_table_" & kw_key_name,
|
||||||
|
"get_table_" & kw_key_name,
|
||||||
|
]
|
||||||
|
for proposed_setter_kw in setter_exemption_list:
|
||||||
if proposed_setter_kw in used_keywords:
|
if proposed_setter_kw in used_keywords:
|
||||||
setter_kw = true
|
setter_kw = true
|
||||||
if is_kw and not setter_kw:
|
if is_kw and not setter_kw:
|
||||||
|
@ -141,7 +155,11 @@ proc generate_defines(keywords: seq[string], global_ctx: GlobalContext): (NimNod
|
||||||
tmp_vars[kw] = new_proc_name
|
tmp_vars[kw] = new_proc_name
|
||||||
stmts.add(new_proc)
|
stmts.add(new_proc)
|
||||||
elif kw.startsWith("set_table_self."):
|
elif kw.startsWith("set_table_self."):
|
||||||
var (new_proc, new_proc_name) = generate_storage_table_func(kw, global_ctx)
|
var (new_proc, new_proc_name) = generate_storage_table_set_func(kw, global_ctx)
|
||||||
|
tmp_vars[kw] = new_proc_name
|
||||||
|
stmts.add(new_proc)
|
||||||
|
elif kw.startsWith("get_table_self."):
|
||||||
|
var (new_proc, new_proc_name) = generate_storage_table_get_func(kw, global_ctx)
|
||||||
tmp_vars[kw] = new_proc_name
|
tmp_vars[kw] = new_proc_name
|
||||||
stmts.add(new_proc)
|
stmts.add(new_proc)
|
||||||
elif kw.startsWith("self."):
|
elif kw.startsWith("self."):
|
||||||
|
@ -153,7 +171,7 @@ proc generate_defines(keywords: seq[string], global_ctx: GlobalContext): (NimNod
|
||||||
|
|
||||||
proc check_keyword_defines(keywords_used: seq[string], local_ctx: LocalContext) =
|
proc check_keyword_defines(keywords_used: seq[string], local_ctx: LocalContext) =
|
||||||
for keyword in keywords_used:
|
for keyword in keywords_used:
|
||||||
var base = keyword.replace("set_", "").replace("table_", "")
|
var base = keyword.replace("set_", "").replace("get_", "").replace("table_", "")
|
||||||
if "." in base:
|
if "." in base:
|
||||||
base = base.split(".")[0]
|
base = base.split(".")[0]
|
||||||
if not (base in local_ctx.sig.pragma_base_keywords):
|
if not (base in local_ctx.sig.pragma_base_keywords):
|
||||||
|
@ -167,13 +185,12 @@ proc get_keyword_defines*(proc_def: NimNode, global_ctx: GlobalContext, local_ct
|
||||||
var
|
var
|
||||||
keywords_used: seq[string]
|
keywords_used: seq[string]
|
||||||
find_builtin_keywords(proc_def, keywords_used, global_ctx)
|
find_builtin_keywords(proc_def, keywords_used, global_ctx)
|
||||||
echo keywords_used
|
|
||||||
echo "%^%^%^%^%^"
|
|
||||||
keywords_used = deduplicate(keywords_used)
|
keywords_used = deduplicate(keywords_used)
|
||||||
check_keyword_defines(keywords_used, local_ctx)
|
check_keyword_defines(keywords_used, local_ctx)
|
||||||
let (global_define_stmts, global_keyword_map) = generate_defines(keywords_used, global_ctx)
|
let (global_define_stmts, global_keyword_map) = generate_defines(keywords_used, global_ctx)
|
||||||
return (global_define_stmts, global_keyword_map)
|
return (global_define_stmts, global_keyword_map)
|
||||||
|
|
||||||
|
|
||||||
proc get_next_storage_node(kw_key_name: string, global_keyword_map: Table[string, string], current_node: NimNode): NimNode =
|
proc get_next_storage_node(kw_key_name: string, global_keyword_map: Table[string, string], current_node: NimNode): NimNode =
|
||||||
if kw_key_name.startsWith("self."):
|
if kw_key_name.startsWith("self."):
|
||||||
return nnkCall.newTree(
|
return nnkCall.newTree(
|
||||||
|
@ -183,7 +200,15 @@ proc get_next_storage_node(kw_key_name: string, global_keyword_map: Table[string
|
||||||
return nnkCall.newTree(
|
return nnkCall.newTree(
|
||||||
newIdentNode(global_keyword_map[kw_key_name]),
|
newIdentNode(global_keyword_map[kw_key_name]),
|
||||||
current_node[1]
|
current_node[1]
|
||||||
|
)
|
||||||
|
elif kw_key_name.startsWith("get_table_self."):
|
||||||
|
var call_func = nnkCall.newTree(
|
||||||
|
newIdentNode(global_keyword_map[kw_key_name]),
|
||||||
)
|
)
|
||||||
|
echo treeRepr(current_node)
|
||||||
|
for param in current_node[1..current_node.len - 1]: # key params
|
||||||
|
call_func.add(param)
|
||||||
|
return call_func
|
||||||
elif kw_key_name.startsWith("set_table_self."):
|
elif kw_key_name.startsWith("set_table_self."):
|
||||||
var call_func = nnkCall.newTree(
|
var call_func = nnkCall.newTree(
|
||||||
newIdentNode(global_keyword_map[kw_key_name]),
|
newIdentNode(global_keyword_map[kw_key_name]),
|
||||||
|
@ -191,10 +216,8 @@ proc get_next_storage_node(kw_key_name: string, global_keyword_map: Table[string
|
||||||
for param in current_node[0][1..current_node.len - 1]: # key params
|
for param in current_node[0][1..current_node.len - 1]: # key params
|
||||||
call_func.add(param)
|
call_func.add(param)
|
||||||
call_func.add(current_node[1]) # val param
|
call_func.add(current_node[1]) # val param
|
||||||
echo treeRepr(call_func)
|
|
||||||
return call_func
|
return call_func
|
||||||
else:
|
else:
|
||||||
|
|
||||||
raise newException(ParserError, "Unknown global self keyword")
|
raise newException(ParserError, "Unknown global self keyword")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -238,22 +238,21 @@ template get_util_functions() {.dirty.} =
|
||||||
if Uint128.fromBytesBE(b) > 0.stuint(128):
|
if Uint128.fromBytesBE(b) > 0.stuint(128):
|
||||||
revert(nil, 0)
|
revert(nil, 0)
|
||||||
|
|
||||||
proc exit_message(s: string) =
|
proc exitMessage(s: string) =
|
||||||
revert(cstring(s), s.len.int32)
|
revert(cstring(s), s.len.int32)
|
||||||
|
|
||||||
proc concat[I1, I2: static[int]; T](a: array[I1, T], b: array[I2, T]): array[I1 + I2, T] =
|
proc concat[I1, I2: static[int]; T](a: array[I1, T], b: array[I2, T]): array[I1 + I2, T] =
|
||||||
result[0..a.high] = a
|
result[0..a.high] = a
|
||||||
result[a.len..result.high] = b
|
result[a.len..result.high] = b
|
||||||
|
|
||||||
proc setTableValue[N](table_id: int32, key: array[N, byte], value: var bytes32) =
|
proc getHashedKey[N](table_id: int32, key: array[N, byte]): bytes32 =
|
||||||
type CombinedKey {.packed.} = object
|
type CombinedKey {.packed.} = object
|
||||||
table_id: int32
|
table_id: int32
|
||||||
key: array[N, byte]
|
key: array[N, byte]
|
||||||
|
|
||||||
var
|
var
|
||||||
sha256_address: array[20, byte]
|
hashed_key {.noinit.}: bytes32
|
||||||
combined_key: CombinedKey
|
combined_key: CombinedKey
|
||||||
hashed_key: bytes32
|
sha256_address: array[20, byte]
|
||||||
|
|
||||||
sha256_address[19] = 2'u8
|
sha256_address[19] = 2'u8
|
||||||
combined_key.table_id = table_id
|
combined_key.table_id = table_id
|
||||||
|
@ -267,14 +266,25 @@ template get_util_functions() {.dirty.} =
|
||||||
sizeof(combined_key).int32, # dataLength
|
sizeof(combined_key).int32, # dataLength
|
||||||
)
|
)
|
||||||
if res == 1: # call failed
|
if res == 1: # call failed
|
||||||
exit_message("Could not call sha256 in setTableValue")
|
exitMessage("Could not call sha256 in setTableValue")
|
||||||
# raise newException(Exception, "Could not call sha256 in setTableValue")
|
# raise newException(Exception, "Could not call sha256 in setTableValue")
|
||||||
if getReturnDataSize() != 32.int32:
|
if getReturnDataSize() != 32.int32:
|
||||||
exit_message("Could not call sha256, Incorrect return size")
|
exitMessage("Could not call sha256, Incorrect return size")
|
||||||
|
|
||||||
returnDataCopy(addr hashed_key, 0.int32, 32.int32)
|
returnDataCopy(addr hashed_key, 0.int32, 32.int32)
|
||||||
|
|
||||||
|
hashed_key # return
|
||||||
|
|
||||||
|
proc setTableValue[N](table_id: int32, key: array[N, byte], value: var bytes32) =
|
||||||
|
var hashed_key = getHashedKey(table_id, key)
|
||||||
storageStore(hashed_key, addr value)
|
storageStore(hashed_key, addr value)
|
||||||
|
|
||||||
|
proc getTableValue[N](table_id: int32, key: array[N, byte], ): bytes32 =
|
||||||
|
var
|
||||||
|
value: bytes32
|
||||||
|
hashed_key: bytes32 = getHashedKey(table_id, key)
|
||||||
|
storageLoad(hashed_key, addr value)
|
||||||
|
value # return
|
||||||
|
|
||||||
|
|
||||||
proc get_getter_func(var_struct: VariableType): NimNode =
|
proc get_getter_func(var_struct: VariableType): NimNode =
|
||||||
let
|
let
|
||||||
|
|
|
@ -6,9 +6,9 @@ import tables
|
||||||
import ./types
|
import ./types
|
||||||
|
|
||||||
|
|
||||||
proc generate_storage_get_func*(storage_keword: string, global_ctx: GlobalContext): (NimNode, string) =
|
proc generate_storage_get_func*(storage_keyword: string, global_ctx: GlobalContext): (NimNode, string) =
|
||||||
var
|
var
|
||||||
global_var_name = storage_keword.split(".")[1]
|
global_var_name = storage_keyword.split(".")[1]
|
||||||
new_proc_name = fmt"get_{global_var_name}_from_storage"
|
new_proc_name = fmt"get_{global_var_name}_from_storage"
|
||||||
var_info = global_ctx.global_variables[global_var_name]
|
var_info = global_ctx.global_variables[global_var_name]
|
||||||
slot_number = var_info.slot
|
slot_number = var_info.slot
|
||||||
|
@ -61,27 +61,6 @@ proc generate_storage_get_func*(storage_keword: string, global_ctx: GlobalContex
|
||||||
return tmp
|
return tmp
|
||||||
""")
|
""")
|
||||||
return (new_proc, new_proc_name)
|
return (new_proc, new_proc_name)
|
||||||
# elif var_info.var_type == "StorageTable":
|
|
||||||
# var
|
|
||||||
# key_param_arr: seq[string]
|
|
||||||
# value_type = var_info.key_types[^1]
|
|
||||||
# table_id = var_info.slot
|
|
||||||
# key_count = 0
|
|
||||||
# for x in var_info.key_types[0..^1]:
|
|
||||||
# key_param_arr.add(
|
|
||||||
# fmt"key{key_count}:" & x
|
|
||||||
# )
|
|
||||||
# inc(key_count)
|
|
||||||
|
|
||||||
# var new_proc = parseStmt(fmt"""
|
|
||||||
# proc {new_proc_name}({key_param_arr.join(",")}): {value_type} =
|
|
||||||
# var
|
|
||||||
# tmp {{.noinit.}}: bytes32
|
|
||||||
# pos = {$slot_number}.stuint(32).toByteArrayBE
|
|
||||||
# storageLoad(pos, addr tmp)
|
|
||||||
# return tmp
|
|
||||||
# """)
|
|
||||||
# return (new_proc, new_proc_name)
|
|
||||||
else:
|
else:
|
||||||
raise newException(ParserError, var_info.var_type & " storage is not supported at the moment.")
|
raise newException(ParserError, var_info.var_type & " storage is not supported at the moment.")
|
||||||
|
|
||||||
|
@ -136,12 +115,12 @@ proc generate_storage_set_func*(storage_keyword: string, global_ctx: GlobalConte
|
||||||
raise newException(ParserError, var_info.var_type & " storage is not supported at the moment.")
|
raise newException(ParserError, var_info.var_type & " storage is not supported at the moment.")
|
||||||
|
|
||||||
|
|
||||||
proc generate_storage_table_func*(storage_keyword: string, global_ctx: GlobalContext): (NimNode, string) =
|
proc generate_storage_table_set_func*(storage_keyword: string, global_ctx: GlobalContext): (NimNode, string) =
|
||||||
var
|
var
|
||||||
key_param_arr: seq[string]
|
key_param_arr: seq[string]
|
||||||
global_var_name = storage_keyword.split(".")[1]
|
global_var_name = storage_keyword.split(".")[1]
|
||||||
var_info = global_ctx.global_variables[global_var_name]
|
var_info = global_ctx.global_variables[global_var_name]
|
||||||
new_proc_name = fmt"set_{global_var_name}_in_storage"
|
new_proc_name = fmt"set_{global_var_name}_in_storage_table"
|
||||||
value_type = var_info.key_types[^1]
|
value_type = var_info.key_types[^1]
|
||||||
table_id = var_info.slot
|
table_id = var_info.slot
|
||||||
key_count = 0
|
key_count = 0
|
||||||
|
@ -159,8 +138,37 @@ proc generate_storage_table_func*(storage_keyword: string, global_ctx: GlobalCon
|
||||||
raise newException(ParserError, "Only one key storage is supported at the moment.")
|
raise newException(ParserError, "Only one key storage is supported at the moment.")
|
||||||
|
|
||||||
var new_proc = parseStmt(fmt"""
|
var new_proc = parseStmt(fmt"""
|
||||||
proc {new_proc_name}({key_param_arr.join(",")}, val: {var_info.key_types[^1]}) =
|
proc {new_proc_name}({key_param_arr.join(",")}, val: {value_type}) =
|
||||||
var tmp_val = val
|
var tmp_val = val
|
||||||
setTableValue({table_id}.int32, {combined_key}, tmp_val)
|
setTableValue({table_id}.int32, {combined_key}, tmp_val)
|
||||||
""")
|
""")
|
||||||
return (new_proc, new_proc_name)
|
return (new_proc, new_proc_name)
|
||||||
|
|
||||||
|
|
||||||
|
proc generate_storage_table_get_func*(storage_keyword: string, global_ctx: GlobalContext): (NimNode, string) =
|
||||||
|
var
|
||||||
|
key_param_arr: seq[string]
|
||||||
|
global_var_name = storage_keyword.split(".")[1]
|
||||||
|
new_proc_name = fmt"get_{global_var_name}_in_storage_table"
|
||||||
|
var_info = global_ctx.global_variables[global_var_name]
|
||||||
|
value_type = var_info.key_types[^1]
|
||||||
|
table_id = var_info.slot
|
||||||
|
key_count = 0
|
||||||
|
combined_key = ""
|
||||||
|
|
||||||
|
for x in var_info.key_types[0..^2]:
|
||||||
|
key_param_arr.add(
|
||||||
|
fmt"key{key_count}: " & x
|
||||||
|
)
|
||||||
|
inc(key_count)
|
||||||
|
|
||||||
|
if key_param_arr.len == 1:
|
||||||
|
combined_key = "key0"
|
||||||
|
else:
|
||||||
|
raise newException(ParserError, "Only one key storage is supported at the moment.")
|
||||||
|
|
||||||
|
var new_proc = parseStmt(fmt"""
|
||||||
|
proc {new_proc_name}({key_param_arr.join(",")}): {value_type} =
|
||||||
|
getTableValue({table_id}.int32, {combined_key})
|
||||||
|
""")
|
||||||
|
return (new_proc, new_proc_name)
|
||||||
|
|
Loading…
Reference in New Issue