Syntax: OOC

include stdint, stdlib, memory, ./myheader // C includes, "./" means relative
use gtk, yajit // .use files define include paths, libraries, sourcepath extensions
import rock/middle/[FunctionCall, VariableAccess, Expression], gtk/Button // import other ooc files

Representable: interface {
    toString: func -> String
}

String: cover from Char* implements Representable {
    length: extern(strlen) func -> Int
    toString: func -> String { this } // implicit return
}

/**
 * Dereference is actually a node used in rock (ooc compiler in ooc)
 * You generate html docs with rock+sonofaj+sphinx, see http://docs.ooc-lang.org
 * @author nddrylliog
 */
Dereference: class extends Expression implements Representable {

    expr: Expression
    count := 0

    /* ~ is a suffix, =expr is an Assign-arg, .token is a Member-arg */
    init: func ~addressOf (=expr, .token) {
        super(token)
    }

    accept: func (visitor: Visitor) {
        visitor visitDereference(this)
    }

    getType: func -> Type { expr getType() ? expr getType() dereference() : null }

    toString: func -> String {
        return expr toString() + "@"
    }

    /**
     * @return Responses OK if the node is resolved now, Responses LOOP otherwise
     */
    resolve: func (trail: Trail, res: Resolver) -> Response {

        trail push(this)
        {
            response := expr resolve(trail, res)
            if(!response ok()) {
                trail pop(this)
                return response
            }
        }
        trail pop(this)

        return Responses OK

    }

    replace: func (oldie, kiddo: Node) -> Bool {
        // here the match is used implicitly for the returne xception
        match oldie {
            case expr => expr = kiddo; true
            case      => false
        }
    }

}

pointerFiddling: func (p: Int*) -> Float* {
    printf("%d, %d, %d\n", p@, (p+1)@, (p+2)@)
    // qualifiers are okay in decl-assigns, casting is done with 'as'
    i := static const 42 as Float
    return i&
}

reference: func (i: Int@) {
    i = 4
}

main: func {
    Dereference new(expr, token)
    a := 3
    reference(a&)
    "a = %d" format(a) println()
}

List: class <T> extends Enumerable<T> {

    data: T*

    get: func (i: Int) -> T {
        data[i]
    }

}

"Bye world!" println()