rvirding / luerl

Lua in Erlang
Apache License 2.0
1.03k stars 141 forks source link

string.gmatch #150

Open markmeeus opened 1 year ago

markmeeus commented 1 year ago

There is this closed issue related to string.gmatch: https://github.com/rvirding/luerl/issues/43

I would guess that the trickiness of implementing this is the stateful iterator gmatch should return. Erl_func can't have mutable variables. However, in Lua a table can be called as well, when it has a __call in its metatable. So I found a way to implement gmatch in Lua itself:

string.gmatch = function(str, pattern) 
    local callable = {
        nextPos = 0,
        str = str,
        pattern = pattern
    }
    local mt = {}

    function mt.__call(table)            
        match_start, match_end = string.find(table.str, table.pattern, table.nextPos)    

        if(match_start == nil) then        
            return nil;
        else
            table.nextPos = match_end + 1;            
            return string.sub(table.str, match_start, match_end)
        end
    end

    setmetatable(callable, mt)
    return callable
end

for word in string.gmatch("The big {brown} fox jumped {over} the lazy {dog}.","{(.-)}") do print(word) end

It looks quite possible to implement this in luerl, since all we need to be able to do is in the erl_func:

Would it make sense to implement is like this?

rvirding commented 1 year ago

@markmeeus I am slowly getting around to looking through old stuff. It would be nice to do it in erlang. I checked pairs and ipairs but they return a function to get the next pair. Must think a bit about this.