Seems I managed to bring the macro/generics processing to its limits.

Compiling the following program fails with a compile error from gcc: 
    
    
    import macros
    
    type
       Expression* = ref object of RootObj
       
       VarExpression = ref object of Expression
          name: string
       
       StringExpression = ref object of Expression
          value: string
       
       IntExpression = ref object of Expression
          value: int
       
       OpExpression = ref object of Expression
         name: string
         args: seq[Expression]
       
       AssignmentKind = enum
         akCopy, akInsert, akUpdate, akDelete
       
       AttrUpdate* = object
         name: string
         exp: Expression
       
       Assignment* = ref object
         case kind: AssignmentKind
         of akCopy:
           copyDest: string
         of akInsert:
           insertDest: string
           insertFlags: int
         of akUpdate:
           updateDest: string
           updateCond: Expression
           attrUpdates: seq[AttrUpdate]
         of akDelete:
           deleteDest: string
           deleteCond: Expression
    
    proc `$=`(exp1: Expression, val: int): Expression =
      ## Creates a = expression
      result = OpExpression(name: "=", args: @[exp1, IntExpression(value: val)])
    
    macro V(varname: untyped): Expression =
      ## Converts an identifier to a variable name.
      result = newCall("toVar", @[toStrLit(varname)])
    
    proc toVar(varname: string): VarExpression =
      result = VarExpression(name: varname)
    
    proc toExpr(s: string): Expression =
      ## Converts a string value to an expression.
      return StringExpression(value: s)
    
    proc updateAssignment(tbName: string, cond: Expression,
                     attrUpdates: varargs[AttrUpdate]): Assignment =
      result = new Assignment
      result.kind = akUpdate
      result.updateDest = tbName
      result.updateCond = cond
      
      result.attrUpdates = newSeq[AttrUpdate](attrUpdates.len)
      for i in 0..<result.attrUpdates.len:
        result.attrUpdates[i] = attrUpdates[i]
    
    macro myUpdate(dest: untyped, cond: Expression,
                  assigns: varargs[AttrUpdate]): Assignment =
      result = newCall("updateAssignment", toStrLit(dest), cond, assigns)
    
    proc attributeAssignment(dest: string, src: Expression): AttrUpdate =
      result.name = dest
      result.exp = src
    
    macro `:=`(dest: untyped, src: Expression): AttrUpdate =
      result = newCall("attributeAssignment", toStrLit(dest), src)
    
    proc assign3*(assigns: varargs[Assignment]): int =
      result = 0
    
    discard assign3(myUpdate(t3, V(n) $= 1, s := toExpr("Bar")))
    
    
    Run

When compiling with nim 0.17.2 I get the following error: (Didn't try with 
newer versions)

Error:
    
    
    execution of an external compiler program 'gcc -c  -w  -I/usr/lib/nim -o 
/home/rene/projects/nidurodb/test/nimcache/assigntest.o 
/home/rene/projects/nidurodb/test/nimcache/assigntest.c' failed with exit code: 
1
    
    ::
    /home/rene/projects/nidurodb/test/nimcache/assigntest.c: In function 
‘NimMainModule’:
    /home/rene/projects/nidurodb/test/nimcache/assigntest.c:782:112: error: 
‘T5_Len_0’ undeclared (first use in this function)
      T1_[0] = updateAssignment_W9aVjf64l6HNbKHPkoTWOgA(((NimStringDesc*) 
&TM_rFCIiNhfswqwZJUDLErU2g_15
    ), T4_, T5_, T5_Len_0);
                 ^~~~~~~~
    
    

Reply via email to