Hi, mratsin.

Thank you for the link to your work. By studying your first example, I was able 
to create a Lisp like AST, however I could not discover a way to convert it to 
a Nim AST. Could you take a look at my program, and suggest a way of converting 
it into a functional Nim macro? By the way, I changed symbol to symb, since the 
compiler issues a warning against using symbol.
    
    
    import os, strutils, macros
    
    type
      SExprKind = enum
        IntScalar, FloatScalar, St, Sym, consp
      SExpr = ref object
        case kind: SExprKind
        of IntScalar: intVal: int
        of FloatScalar: floatVal: float
        of Sym: symb: string
        of St: str: string
        of consp: car, cdr: SExpr
    
    template mI(a:int): SExpr=
       SExpr(kind: IntScalar, intVal: a)
    
    template sy(s: string): SExpr=
      SExpr(kind: Sym, symb: `s`)
    
    template mS(s:string): SExpr=
      SExpr(kind: St, str: s)
    
    template car(s:SExpr) : SExpr=
      if s == nil: s
      else: s.car
    
    template cdr(s:SExpr) : Sexpr=
      if s == nil: s
      else: s.cdr
    
    template cons(x:SExpr, y:SExpr) : SExpr=
      SExpr(kind: consp, car: x, cdr: y)
    
    proc `$`*(se: SExpr): string =
      case se.kind
      of IntScalar: result= $se.intVal
      of FloatScalar: result = $se.floatVal
      of ST: result = '"' & se.str & '"'
      of Sym: result = se.symb
      of consp:
        result.add("(")
        var r = se
        if r != nil:
          result.add($r.car)
          r= r.cdr
        while r != nil:
          result.add(indent($r.car, 2))
          r= r.cdr
        result.add(")")
    
    
    proc walkAST(e:SExpr): NimNode =
       case e.kind:
         of Sym: return newIdentNode e.symb
         of IntScalar: return newLit e.intVal
         else: return newLit "Erro"
    
    let ii{.compileTime.} = "i".sy.walkAST
    
    macro iter(jj: untyped, c1: untyped, c2: untyped, stm: untyped): untyped=
      let
        jx= jj.strVal
        p= int(c1.intVal)
      result= nnkStmtList.newTree(
        nnkForStmt.newTree(jx.sy.walkAST,
            infix(p.mI.walkAST, "..", c2), stm))
    
    proc main() =
      iter(j, 2, paramStr(1).parseInt):
        echo j, cons("hi".sy, cons(cons("world".sy, nil), nil))
    
    main()
    
    
    Run

Reply via email to