I'm working on a Nim port of the Lua pattern matching code. Lua patterns are a 
bit like regular expressions, but simpler. The implementation is pretty small, 
however, compared to regular expressions, and the port is pure Nim and does not 
require any shared libraries like PCRE for the re and nre libs.

The current code is available at 
[https://github.com/zevv/nimpat](https://github.com/zevv/nimpat)/

The basic pattern matching is functional, a single proc 'match' is implemented, 
and can be used like this:
    
    
    proc match(src: string, pat: string): seq[string]
    
    let src = "3 foxes: 0x44111"
    let pat = "(%d+) ([^:]+): 0x(%x+)"
    let caps = src.match("(%d+) ([^:]+): 0x(%x+)")
    echo "$1 $2 $3" % [ caps[0], caps[1], caps[2]]
    

The pattern "(%d+) ([^:]+): 0x(%x+)" translates to

  * (%d+): a maximum number of numeric chars
  * ([^:]+): all characters up to a colon
  * (%x+): one or more hex characters



I am now looking for a friendly API for the library, as getting the returned 
matches in a seq is a bit cumbersome to use. Ideally I would like to do pattern 
captures like in Lua allowing direct assignment to variables from a proc and/or 
iterator:
    
    
    local a, b, c = src:match(pat)
    
    for a, b, c in src:gmatch(pat) do
       ...
    end
    

In Nim that would be something like this, using tuples.
    
    
    let (a, b, c) = src.match(pat)
    
    for a, b, c in src.gmatch(pat):
       ...
    

I have been trying to implement this in Nim, but I can not get this to work 
because (quote Araq) "overloading doesn't look at the return types"

So this does not work:
    
    
    iterator gmatch(src, pat: string): (string) =
      let c = src.match(pat)
      yield (c[0])
    
    iterator gmatch(src, pat: string): (string, string) =
      let c = src.match(pat)
      yield (c[0], c[1])
    
    iterator gmatch(src, pat: string): (string, string, string) =
      let c = src.match(pat)
      yield (c[0], c[1], c[2])
    
    nimpat.nim(357, 14) Error: ambiguous call; both nimpat.gmatch(src: string, 
pat: string)[declared in nimpat.nim(348, 9)] and nimpat.gmatch(src: string, 
pat: string)[declared in nimpat.nim(352, 9)] match for: (string, string)
    

Araqs next remark was to "write a macro", but my Nim-fu is not up to that yet, 
I'm afraid.

So, would it be possible to get this to work, and how would I proceed from here?

Thanks,

Ico

Reply via email to