Validation commands are pretty low-level and are inconvenient to write
by hand, at least because of huge quantity of TAKEs.
-@command{tcl/schema-marshal} utility gives ability to convert much more
+@command{tcl/schema.tcl} utility gives ability to convert much more
nicer schemas written on Tcl language to the KEKS-encoded commands. We
call that Tcl-written schemas KEKS/Schema.
@verbatiminclude ../tcl/schemas/pub-load.tcl
@verbatiminclude ../tcl/schemas/pub-sig-tbs.tcl
-@command{schema-marshal} calls @code{schemas@{s0 cmds0 s1 cmds1 ...@}}
+@command{schema.tcl} calls @code{schemas@{s0 cmds0 s1 cmds1 ...@}}
commands to produce an encoded map with @code{cmds*} commands for
@code{s*} schemas. There is @code{field} command that helps creation of
commands related to the field.
#!/usr/bin/env tclsh
-# schema-marshal -- Convert Tcl schemas to KEKS representation
+# schema.tcl -- Convert Tcl schemas to KEKS representation
# Copyright (C) 2024-2025 Sergey Matveev <stargrave@stargrave.org>
#
# This program is free software: you can redistribute it and/or modify
# You should have received a copy of the GNU Lesser General Public
# License along with this program. If not, see <http://www.gnu.org/licenses/>.
-source [file join [file dirname $::argv0] keks.tcl]
-namespace import KEKS::*
+package require KEKS
+
+namespace eval KEKS::Schema {
+
+set version 0.1.0
proc TAKE {k} {
if {[string is digit $k]} {
proc TIMEPREC {p} {subst {LIST {{STR TP} {INT $p}}}}
proc UTC {} {return {LIST {{STR UTC}}}}
-proc schema-process {v} {
- upvar _pairs _pairs
- foreach {name cmds} $v {
- set _cmds {}
- if {$name == "schema-include"} {
- set fd [open [file join $cmds]]
- set inc [read $fd]
- close $fd
- schema-process $inc
- continue
- }
- foreach cmd $cmds {eval $cmd}
- lappend _pairs $name [list LIST $_cmds]
- }
-}
-
-proc schemas {v} {
- set _pairs {}
- schema-process $v
- MAP $_pairs
-}
-
set timeprecArgs [dict create s 0 ms 3 us 6 ns 9 ps 12 fs 15 as 18]
set knownTypes {bin blob bool hexlet int list magic map nil set str tai}
proc field {k types args} {
- upvar _cmds _cmds
+ upvar _cmds _cmds buf buf
if {[lindex $types 0] == "with"} {
lappend _cmds [TAKE $k]
lappend _cmds [SCHEMA [lindex $types 1]]
set i [lsearch -glob $args "prec=*"]
if {$i != -1} {
set p [string range [lindex $args $i] 5 end]
- global timeprecArgs
+ variable timeprecArgs
set p [dict get $timeprecArgs $p]
lappend _cmds [TAKE $k]
lappend _cmds [TIMEPREC $p]
set s [lindex [lindex $args $i] 1]
lappend _cmds [TAKE $k]
lappend _cmds [EACH]
- global knownTypes
+ variable knownTypes
if {[lsearch -exact $knownTypes $s] == -1} {
lappend _cmds [SCHEMA $s]
} {
}
}
-set _schema {}
-foreach f $::argv {lappend _schema schema-include $f}
-MAGIC schema
-schemas $_schema
-puts [binary encode hex $::KEKS::buf]
+proc process {v} {
+ upvar _pairs _pairs buf buf
+ foreach {name cmds} $v {
+ set _cmds {}
+ if {$name == "schema-include"} {
+ set fd [open [file join $cmds]]
+ set inc [read $fd]
+ close $fd
+ process $inc
+ continue
+ }
+ foreach cmd $cmds {eval $cmd}
+ lappend _pairs $name [list LIST $_cmds]
+ }
+}
+
+proc do {v} {
+ upvar buf buf
+ set _pairs {}
+ process $v
+ MAP $_pairs
+}
+
+namespace export TAKE EXISTS !EXISTS EACH EQ TYPE GT LT SCHEMA TIMEPREC UTC
+namespace export do process field
+
+}
+
+package provide KEKS::Schema $KEKS::Schema::version
+
+namespace import KEKS::*
+
+if {[info exists argv0] && ([file tail [info script]] eq [file tail $argv0])} {
+ set _schema {}
+ foreach f $::argv {lappend _schema schema-include $f}
+ set buf ""
+ MAGIC schema
+ KEKS::Schema::do $_schema
+ puts [binary encode hex $buf]
+}