Custom Query Programming

NEW QUERY defines a custom multi-word command; QUERY calls it. It works the way operations do — define once, call by name — except the name is a sequence of words, and some of those words can be values supplied at call time.

Implementation pending. This design is specified below. Runtime implementation is in progress.

Shape

A query is a list of steps. STEP declares one; NEXT moves to the following one; END closes the sequence.

A Three-Word Command
NEW QUERY AS OPEN
  STEP "Tell"
NEXT
  STEP "the"
NEXT
  STEP "time"
  NEW DATE AND TIME SET ?now
  AFTER EMIT ?now
END
CLOSE
Calling It
QUERY Tell the time
QUERY is mandatory. A custom query is only ever reached through the QUERY verb. Writing Tell the time on its own is an unrecognized verb and a FATAL error, exactly as any other unknown statement is — the runtime does not guess that a bare statement might be a custom command.

Any step may carry OcaltQL code, which runs when that step is matched. A step with no code contributes only its word.

Literal Words

STEP "word"
NEW QUERY AS OPEN
  STEP "deploy"
NEXT
  STEP "now"
  EMIT "deploying"
END
CLOSE
AFTER QUERY deploy now

SKIPPABLE

A step marked SKIPPABLE may be omitted at call time. Its code does not run when it is skipped.

An Optional Word
NEW QUERY AS OPEN
  STEP "Tell"
NEXT
  STEP "the" SKIPPABLE
NEXT
  STEP "time"
  NEW DATE AND TIME SET ?now
  AFTER EMIT ?now
END
CLOSE

AFTER QUERY Tell the time
AFTER QUERY Tell time
(* Both call the same query *)

A Word From a Variable

Placing a variable before STEP makes that variable’s value the step’s word. This is resolved at registration — it fixes the word, it does not accept a value at call time.

NEXT ?var / STEP
STRING "release" SET ?verb
AFTER NEW QUERY AS OPEN
  STEP "start"
NEXT ?verb
  STEP
END
CLOSE
AFTER QUERY start release
(* The second word is fixed as "release" — whatever ?verb held when
   the query was defined *)

Accepting Values

STEP VALUE accepts whatever is written in that position at call time. Inside that step’s code, the global !VALUE holds what was supplied.

STEP VALUE
NEW QUERY AS OPEN
  STEP "greet"
NEXT
  STEP VALUE
  EMIT "hello " & !VALUE
END
CLOSE

AFTER QUERY greet "Bongani"
AFTER STRING "Kea" SET ?name
AFTER QUERY greet ?name
VALUE declares; !VALUE reads. STEP VALUE is the declaration — it says this step accepts something rather than matching a fixed word. Inside that step’s code the supplied value is the global !VALUE, like any other global.
A value may be written as a variable or as a string in any of the three quote forms — "...", '...' or `...`. A value step is not skippable; pass an empty string or an empty variable when there is nothing to give.

Typed and Constrained Values

Form Accepts
STEP VALUEAnything — a variable or a string
STEP VALUE NUMBERNumbers only
STEP VALUE NUMBER MIN 2 MAX 99A number within that range
STEP VALUE STRING MIN 5 MAX 10A string of that length
STEP VALUE EXCEPT "," AND "*"Any string containing none of the exceptions
A Numeric Range, With Code
NEW QUERY AS OPEN
  STEP "add"
NEXT
  STEP "one" "to" SKIPPABLE
NEXT
  STEP VALUE NUMBER MIN 2 MAX 99
  CALCULATE !VALUE + 1 SET ?answer
  AFTER EMIT ?answer
END
CLOSE
AFTER QUERY add one to 41
(* Emits 42 *)
Length and Exclusions
NEW QUERY AS OPEN
  STEP "user"
NEXT
  STEP VALUE STRING MIN 5 MAX 10
  EMIT "username: " & !VALUE
END
CLOSE

AFTER NEW QUERY AS OPEN
  STEP "tag"
NEXT
  STEP VALUE EXCEPT "," AND "*"
  EMIT "tag: " & !VALUE
END
CLOSE
A value that fails its constraint does not match. If no other alternative fits, the call is a catchable E7002 — the steps that did match have already run.

Alternatives

Two forms. OR STEP gives a step more than one acceptable word. FALLBACK gives the whole position an alternative step to try when the preceding one does not match.

OR STEP — Either Word
NEW QUERY AS OPEN
  STEP "show" OR STEP "display"
NEXT
  STEP "status"
  EMIT "all systems go"
END
CLOSE
AFTER QUERY show status
AFTER QUERY display status
FALLBACK — A Different Step Entirely
NEW QUERY AS OPEN
  STEP "set"
NEXT
  STEP "optionA"
  EMIT "took option A"
FALLBACK
  STEP "optionB"
  EMIT "took option B"
END
CLOSE
AFTER QUERY set optionB
(* Emits: took option B *)

CASE and SEPARATOR

Matching is case-insensitive and space-separated by default. Both are set on the query itself, and apply to every step in it.

Case-Sensitive, Dot-Separated
NEW QUERY CASE "sensitive" SEPARATOR "." AS OPEN
  STEP "Tell"
NEXT
  STEP "the"
NEXT
  STEP "time"
  NEW DATE AND TIME SET ?now
  AFTER EMIT ?now
END
CLOSE
AFTER QUERY Tell.the.time
With a separator other than a space, a step’s word may itself contain spaces — STEP "second last word" is one step when the separator is ".".

Persistent Queries

NEW PERSISTENT QUERY registers across executions, exactly as persistent operations do. Define it once; call it from any later script.

Define Once, Call Later
NEW PERSISTENT QUERY AS OPEN
  STEP "deploy"
NEXT
  STEP VALUE
  EMIT "deploying " & !VALUE
END
CLOSE

(* ...any later script... *)

QUERY deploy "api"

When a Call Fails

Situation Result
A statement matches no verbFATALUnrecognized verb. No custom-query lookup is attempted; only QUERY reaches a custom query.
QUERY with a first word matching no registered queryE7002 — catchable
A later step does not match, or a value fails its constraintE7002 — catchable. Steps already matched have run, and their output stands.
Catching a Failed Call
NEW QUERY AS OPEN
  STEP "Tell"
NEXT
  STEP "the"
  EMIT "the..."
END
CLOSE
AFTER QUERY Tell the zzz OR CATCH ERROR SET ?e
AFTER EMIT "|" & ?e("code")
(* Emits: the...|E7002 *)

Full Verb Reference

Verb Description
NEW QUERY [CASE "sensitive"] [SEPARATOR "x"] AS OPEN ... END CLOSEDefine a custom multi-word command
NEW PERSISTENT QUERY ... AS OPEN ... END CLOSESame, registered across executions
STEP "word" [SKIPPABLE]A literal word, optionally omittable
NEXT ?var then STEPThe variable’s value at registration becomes the word
STEP VALUE [NUMBER|STRING] [MIN n MAX n] [EXCEPT "a" AND "b"]Accept a value at call time, optionally typed and constrained. !VALUE holds it inside the step.
STEP "a" OR STEP "b"Either word matches this step
NEXT / FALLBACK / ENDAdvance a step, offer an alternative step, close the sequence
QUERY word word ...Call a custom query. Mandatory — there is no bare form.