Skip to content

Commit

Permalink
Added len() function
Browse files Browse the repository at this point in the history
Closes #120

Now all objects that have __len__() defined can be called with len(), even with classes!
```
class Test
{
    fun __constructor__(){};
    fun __len__()
    {
        return 10
    }
}
len(Test()) # 10
len("test") # 4
len([1,2,3]) # 3
```
  • Loading branch information
Vardan2009 committed May 28, 2024
1 parent c24d8de commit 2fbcdfd
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 1 deletion.
10 changes: 10 additions & 0 deletions core/builtin_funcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,15 @@ def execute_print(self, exec_ctx: Context) -> RTResult[Value]:
@args(["value"])
def execute_print_ret(self, exec_ctx: Context) -> RTResult[Value]:
return RTResult[Value]().success(String(str(exec_ctx.symbol_table.get("value"))))

@args(["value"])
def execute_len(self,exec_ctx: Context) -> RTResult[Value]:
val = exec_ctx.symbol_table.get("value")
try:
ret = int(len(val))
return RTResult[Value]().success(Number(ret))
except TypeError:
return RTResult[Value]().failure(Error(self.pos_start,self.pos_end,"TypeError","Object has no len()"))

@args(["value"])
def execute_input(self, exec_ctx: Context) -> RTResult[Value]:
Expand Down Expand Up @@ -552,6 +561,7 @@ def create_global_symbol_table() -> SymbolTable:
ret.set("cls", BuiltInFunction("clear"))
ret.set("require", BuiltInFunction("require"))
ret.set("exit", BuiltInFunction("exit"))
ret.set("len",BuiltInFunction("len"))
# Datatype validator methods
ret.set("is_num", BuiltInFunction("is_num"))
ret.set("is_int", BuiltInFunction("is_int"))
Expand Down
8 changes: 8 additions & 0 deletions core/datatypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ class Iterator(Value):
def __init__(self, generator: Generator[RTResult[Value], None, None]) -> None:
super().__init__()
self.it = generator

def __len__(self): return len(self.it)

def iter(self) -> Iterator:
return self
Expand Down Expand Up @@ -1099,6 +1101,12 @@ class Instance(BaseInstance):
def __init__(self, parent_class: Class) -> None:
super().__init__(parent_class, None)

def __len__(self):
try:
return self.operator("__len__")[0].value
except AttributeError:
return Null.null()

def bind_method(self, method: BaseFunction) -> RTResult[BaseFunction]:
method = method.copy()
if method.symbol_table is None:
Expand Down
2 changes: 1 addition & 1 deletion stdlib/array.rn
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class Array {
return (this.list)[start:end]
}

fun len() -> arr_len(this.list)
fun __len__() -> arr_len(this.list)
fun is_empty() -> this.list == []
fun to_string() -> str(this.list)
fun is_array() -> true
Expand Down

0 comments on commit 2fbcdfd

Please sign in to comment.