Skip to content

Commit

Permalink
📂 ezr v2.0.0.0.0 (part 2.5)!
Browse files Browse the repository at this point in the history
  • Loading branch information
Uralstech committed Nov 2, 2022
1 parent 349409b commit 5782702
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 57 deletions.
4 changes: 3 additions & 1 deletion AFTERINSTALL.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ THANK YOU FOR DOWNLOADING EZRSHELL
- 'type_of' function now returns name of input values' class (eg: type_of('abc') = 'String')
- 'convert' function 'type' input should be [STRING] literals 'String', 'Int', 'Float' or 'Bool'

[02-11-22] ezr v2.0.0.0.0 (part 2.5)!
- HUGE optimizations for dictionary type

Other news
- ezr v2 will be released in parts! Here's what you can expect from part III:
- Optimizations for dictionary type
- New tuple type

-----------------------------------------------------------------------------------------------------
Expand Down
Binary file modified Builds/ezrShell v2m0 Installer.exe
Binary file not shown.
17 changes: 9 additions & 8 deletions examples/ezr-python-library-template/lib_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,23 @@

# ezr value classes
# -----------------
# Value() -> Parent of all value classes
# BaseFunction(name) -> Parent of Functions and Objects
# Value() -> Parent of all returnable value classes
# BaseFunction(name) -> Parent of Functions, Objects and Function-derivatives
#
# Nothing() -> NOTHING value
#
# Bool(True / False) -> Boolean value
# 'Bool(True)' -> Boolean value of True
# 'Bool(True)' -> true
# Number(value) -> Int / Float value
# 'Number(4)' -> Int value of 4
# 'Number(4.45)' -> Float value of 4.45
# 'Number(4)' -> 4
# 'Number(4.45)' -> 4.45
# String(value) -> Str value
# 'String('Hello!')' -> Str value of 'Hello!'
# 'String('Hello!')' -> 'Hello!'
# List(values) -> List of any values
# 'List([String('t'), Number(3), Bool(False)])' -> List of values ['t', 3, false]
# 'List([String('t'), Number(3), Bool(False)])' -> ['t', 3, false]
# Dict(pairs) -> Dictionary of any values
# 'Dict([(String('t'), Number(3)), (Bool(False), List([Number(4)]))])' -> Dict of values {'t' : 3, false : [4]}
# 'key1 = String('t'); key2 = Bool(False)
# Dict({hash(key1):(key1, Number(3)), hash(key2):(key2, List([Number(4)]))})' -> {'t' : 3, false : [4]}
#
# Function(name, body_node, arg_names, should_auto_return) -> Function definition
# Object(name, body_node, arg_names) -> Object definition
Expand Down
63 changes: 15 additions & 48 deletions ezr.py
Original file line number Diff line number Diff line change
Expand Up @@ -1859,65 +1859,32 @@ def __hash__(self):
return hash(tuple(self.elements))

class Dict(Value):
def __init__(self, pairs):
def __init__(self, dict):
super().__init__()
self.pairs = pairs
self.resolve_collisions()

def resolve_collisions(self, start=0):
if len(self.pairs) == 0: return

check_value = hash(self.pairs[start][0])
collided_indices = []

for i in range(start+1, len(self.pairs)):
if hash(self.pairs[i][0]) == check_value:
collided_indices.append(i)

for i in range(len(collided_indices)):
self.pairs[start] = (self.pairs[start][0], self.pairs[collided_indices[i]-i][1])
del self.pairs[collided_indices[i]-i]

if start < len(self.pairs)-1: self.resolve_collisions(start+1)
self.dict = dict

def key_exists(self, keyToFind):
found = False
index = 0

for index, (key, value) in enumerate(self.pairs):
if hash(key) == hash(keyToFind):
found = True; break

return found, index

def has_element(self, other):
for key, value in self.pairs:
if hash(value) == hash(other): return True
if hash(other) in self.dict.keys(): return True
return False

def added_to(self, other):
if isinstance(other, Dict):
self.pairs.extend(other.pairs)
self.resolve_collisions()

self.dict.update(other.dict)
return Nothing().set_context(self.context), None
return None, Value.illegal_operation(self, other)

def subbed_by(self, other):
if other.__hash__:
found, index = self.key_exists(other)

if found:
self.pairs.pop(index)
if hash(other) in self.dict.keys():
self.dict.pop(hash(other))
return Nothing().set_context(self.context), None

return None, RuntimeError(other.start_pos, other.end_pos, RTE_DICTKEY, f'Key \'{str(other)}\' does not exist', self.context)
return None, RuntimeError(other.start_pos, other.end_pos, RTE_DICTKEY, f'Illegal operation for [DICTIONARY] as key \'{str(other)}\' is not hashable', self.context)

def compare_lte(self, other):
if other.__hash__:
found, index = self.key_exists(other)
if found: return self.pairs[index][1].set_context(self.context), None
if hash(other) in self.dict.keys(): return self.dict[hash(other)][1].set_context(self.context), None

return None, RuntimeError(other.start_pos, other.end_pos, RTE_DICTKEY, f'Key \'{str(other)}\' does not exist', self.context)
return None, RuntimeError(other.start_pos, other.end_pos, RTE_DICTKEY, f'Illegal operation for [DICTIONARY] as key \'{str(other)}\' is not hashable', self.context)
Expand All @@ -1943,20 +1910,20 @@ def check_in(self, other):
return None, Value.illegal_operation(self, other)

def is_true(self):
return len(self.pairs) > 0
return len(self.dict) > 0

def copy(self):
copy_ = Dict(self.pairs)
copy_ = Dict(self.dict)
copy_.set_context(self.context)
copy_.set_pos(self.start_pos, self.end_pos)
return copy_

def __repr__(self):
return '{' + ", ".join([f"{repr(key)} : {repr(value)}" for key, value in self.pairs]) + '}'
return '{' + ", ".join([f"{key} : {repr(value)}" for key, value in self.dict.values()]) + '}'

def __hash__(self):
hash_value = hash(0)
for i in self.pairs: hash_value ^= hash(i)
for key in self.dict.keys(): hash_value ^= key ^ hash(self.dict[key])
return hash_value

class BaseFunction(Value):
Expand Down Expand Up @@ -2158,7 +2125,7 @@ def execute_len(self, context):
if not isinstance(value, (List, Dict, String)): return res.failure(RuntimeError(self.start_pos, self.end_pos, RTE_INCORRECTTYPE, 'Argument must be a [LIST], [DICTIONARY] or [STRING]', context))

if isinstance(value, List): return res.success(Number(len(value.elements)))
elif isinstance(value, Dict): return res.success(Number(len(value.pairs)))
elif isinstance(value, Dict): return res.success(Number(len(value.dict)))
elif isinstance(value, String): return res.success(Number(len(value.value)))
return res.success(Nothing())
execute_len.arg_names = ['value']
Expand Down Expand Up @@ -2369,7 +2336,7 @@ def visit_ListNode(self, node, context):

def visit_DictNode(self, node, context):
res = RuntimeResult()
pairs = []
main_dict = {}

for key_node, value_node in node.pair_nodes:
key = res.register(self.visit(key_node, context))
Expand All @@ -2379,9 +2346,9 @@ def visit_DictNode(self, node, context):
if res.should_return(): return res

if not key.__hash__: return res.failure(RuntimeError(key.start_pos, key.end_pos, RTE_DICTKEY, f'Key \'{str(key)}\' is invalid as it is not hashable', context))
pairs.append((key, value))
main_dict[hash(key)] = (repr(key), value)

return res.success(Dict(pairs).set_context(context).set_pos(node.start_pos, node.end_pos))
return res.success(Dict(main_dict).set_context(context).set_pos(node.start_pos, node.end_pos))

def visit_VarAccessNode(self, node, context):
res = RuntimeResult()
Expand Down

0 comments on commit 5782702

Please sign in to comment.