nest

Nest Programming Language

Nest is a language on top of TCL. It was originally meant to be used for a persistence package for OpenACS (http://www.openacs.org ) but the time has passed. The actual code does not exceed 500 lines. Its output can be compiled into C code (or any other target language). In other words, nest provides a language to write other languages.

You can find the "nest" package here: nest-1.5

You may find my templating presentation in EuroTCL 2013 relevant: https://www.tcl-lang.org/community/tcl2013/EuroTcl/presentations/EuroTcl2013-Demetriou-WebTemplating.pdf

You can follow the development here: https://github.com/neophytos-sk/nest

Dependencies:

History:

  • nest-1.5 (2014-12-02) - simpler examples, added tests dir
  • nest-1.1 (2014-12-01) - dispatcher construct, object methods e.g. "$(msg4) sayhi world"
  • nest-1.0 (2014-11-30) - alias/forward, inst/decl mode, class/object aliases, struct/slot, template/pair - 322 lines

Notes:

  • check out the definition of the struct construct in nest, I think it's cool:
    alias {object} nest {object_helper}

    alias {class} with_mode {decl} nest

    meta {class} {class {object}} {struct} {
        varchar name
        varchar type
        varchar nsp
        varchar default_value = ""

        multiple struct slot = {} {
            varchar name
            varchar type
            varchar meta
            varchar default_value = ""
            bool optional_p = false
            varchar container = ""
        }

        varchar pk
        bool is_final_if_no_scope

    }
  • also, check the pair construct, nest-style:
    generic_type {pair} {typefirst typesecond} {
        ${typefirst} {first}
        ${typesecond} {second}
    } {object_helper}
    proc lambda {params body args} {

        set {llength_params} [llength ${params}]
        set {llength_args} [llength ${args}]

        if { ${llength_params} - 1 <= ${llength_args} } {
            set {last_param} [lindex ${params} {end}]
            if { ${llength_params} == ${llength_args} || ${last_param} eq {args} } {
                unset {llength_params} {llength_args}
                return [uplevel 0 ${body} [if {${params} eq {}} {
                    # llength_params == 0 and llength_args == 0
                    unset {last_param} {params} {body} {args}
                } elseif { ${last_param} ne {args} } {
                    # llength_params == llength_args
                    lassign ${args} {*}[concat ${params} \
                        [unset {last_param} {params} {body} {args}]]
                } else {
                    # (llength_params - 1 <= llength_args) and last_param eq {args}
                    set {args} [lassign ${args} {*}[lrange [concat ${params} \
                        [unset {last_param} {params} {body} {args}]] 0 {end-1}]]
                    set {} {}
                }]]
            }
        }

        if { ${args} eq {} } {
            return [list {lambda} ${params} ${body}]
        } elseif {${llength_params} >= ${llength_args}} {
            return \
                [list {lambda} [lrange ${params} ${llength_args} {end}] \
                    [concat \
                        [list lassign ${args} \
                            {*}[lrange ${params} 0 [expr {${llength_args} - 1}]]] 
                    { ; } 
                    ${body}]]
        } else {
            error "lambda: more args than params"
        }

    } 

PS. Before the chicken and the egg, it was the nest.