Showing posts with label nimrod. Show all posts
Showing posts with label nimrod. Show all posts

Friday, June 15, 2012

Nimrod macro

So finally some macro stuff in Nimrod programming language I managed to write.
import macros

when false:
    dumpTree:
        type
            PMyObj* = ref TMyObj 
            TMyObj* = object of TObject
                a, b : int

        proc newTMyObj*() : PMyObj =
            var o : PMyObj
            new(o)
            #initTMyObj(o[])
            return o    
    
#proc initTMyObj*(o : var TMyObj) = nil
    
when false:
    proc newTMyObj*() : PMyObj =
        var o : PMyObj
        new(o)
        #initTMyObj(o[])
        return o
    
    
macro objdecl(clsbase : expr) : stmt =
    result = newNimNode(nnkStmtList)#, clsbase)
    #for i in 1..clsbase.len-1:
    #echo(repr(clsbase[i]))
    let clsName = repr(clsbase[1])
    let baseName = repr(clsbase[2])
    let tname = "T" & clsName
    let pname = "P" & clsName
    echo("base = " & baseName & ", type = " & tname)
    var fields = clsbase[3][0][0] # [0] skip stmt list, [0] skip var section
    
    
    echo("fields = " & repr(fields))
    
    
    # start 'type' section
    var tsection = newNimNode(nnkTypeSection)
    result.add(tsection)
    
    block:
        # define 'type' node for Pclass * = ref Tclass
        var tnode = newNimNode(nnkTypeDef)
        tsection.add(tnode)
        
        # define type name with * operator
        var tpostf = newNimNode(nnkPostfix)
        tpostf.add(newIdentNode("*"))
        tpostf.add(newIdentNode(pname))
        tnode.add(tpostf)
        
        # don't know why but need an empty node
        tnode.add(newNimNode(nnkEmpty))
        
        # the actual type = ref
        var reft = newNimNode(nnkRefTy)
        reft.add(newIdentNode(tname))
        tnode.add(reft)
    
    
    block:
        # define 'type' node for Tclass * = object of base
        var tnode = newNimNode(nnkTypeDef)
        tsection.add(tnode)
        
        # define type name with * operator
        var tpostf = newNimNode(nnkPostfix)
        tpostf.add(newIdentNode("*"))
        tpostf.add(newIdentNode(tname))
        tnode.add(tpostf)
        
        # don't know why but need an empty node
        tnode.add(newNimNode(nnkEmpty))
        
        # the actual type = object of
        var objt = newNimNode(nnkObjectTy)
        tnode.add(objt)
        
        # needed, don't know why
        objt.add(newNimNode(nnkEmpty))
        
        var inh = newNimNode(nnkOfInherit)
        objt.add(inh)
        inh.add(newIdentNode(baseName))
        
        var recs = newNimNode(nnkRecList)
        objt.add(recs)
        
        recs.add(fields)
        
        #var identDefs = newNimNode(nnkIdentDefs)
        #recs.add(identDefs)
        
        #identDefs.add(getAST(fields))
        #for i in 0..len(fields)-1:
        #    identDefs.add(fields[i])
            
            
        # needed, don't know why
        #identDefs.add(newNimNode(nnkEmpty))
        
    
    #echo(fields.len)
    echo(treeRepr(tsection))
    #echo(repr(tsection))
    
    
    
    
    
    #tnode.add(new
    
    
template declClass(clsName : expr, baseCls : expr, fields : stmt) : stmt = 
    
    
    objdecl(clsName, baseCls, fields)
    when false:
        #`P clsName`* = ref `T clsName`
        #`T clsName`* = object of baseCls
        #    putfields

    proc `new clsName`() : `P clsName` =
        var o : `P clsName`
        new(o)
        return o
        
    
        
# ----- the usage:
    
 
declClass MyTempClass, TObject:
    var x, y : int
    

      
var o = newMyTempClass()
o.x = 3
echo("x,y = " & $o.x & " " & $o.y)

Wednesday, May 23, 2012

Nimrod programming language

Very interesting language, spotted when looking for Vala (generates C code) -)

http://nimrod-code.org/index.html