proc main(): void {
Str[3] parts = split("north,south", ",")
echo parts[0]
health := 3
echo hive.math.max(0, health)
}$ hive check colony.hive
colony.hive:1: in `main`: the declaration of `parts` wants Str[3] and this is Str[dyn]
colony.hive:1: in `main`: the first argument of `hive.math.max` wants Float and this is Int
colony.hive:1: in `main`: the second argument of `hive.math.max` wants Float and this is Int
# All three land on line 1, the line `main` is declared on: after the
# loader, a position is a declaration's.$ hive check guard.hive
guard.hive:1: in `main`: cannot prove this index is in range: it is a computed expression, and there is nothing to hang a guard on. Bind it to a name first, then guard that
$ hive check shouted.hive
shouted.hive:5: `Proc` is a keyword written the wrong way: every keyword in Hive is lower case, and only lower case. Write `proc` — or, if a name was meant, one the language has not already taken. A keyword is reserved however it is spelled, so `Proc` is no more a name than `proc` is.$ hive check main.hive
main.hive:2: cannot read `lib/missing.hive`: open lib/missing.hive: no such file or directory
# With the import fixed, the mistake inside the module is reported there,
# by the name the module gives it.
$ hive check main.hive
lib/text.hive:1: in `shout`: `+` wants two of one type, and these are Str and Int
$ hive build
hive: `hive build` needs an entrypoint: `hive build <entrypoint.hive>`." In Vim or Neovim. hive check runs every compiler pass and stops before
" the Go toolchain, so it answers as fast as the front end does and writes
" nothing next to the file — which is what makes it usable on every save.
setlocal makeprg=hive\ check\ %:S
setlocal errorformat=%f:%l:\ %m,%-G%.%#
" :make fills the quickfix list, and :cn walks the errors. The %-G item
" drops every line that is not a diagnostic.Every diagnostic opens with where it happened — file:line: message — which is the shape editors expect, so wiring one up takes a compile command and a pattern. A compile error has nothing in front of it. A usage error, like hive build with no entrypoint, starts with hive:, because it is about what was typed rather than about anybody's source. Both go to standard error and exit with 1, so hive emit main.hive > main.go never writes an error into the Go. A failing test is an answer rather than a malfunction, so its report goes to standard output.
What a message says is held to one standard:
parts wants Str[3] and this is Str[dyn], never "type mismatch";sort that cannot sort in place names both fixes;hive.math.max(0, health) is refused because Hive never widens a number behind your back;Each pass reports everything it finds, but the passes run one after another and the first to find anything stops the rest. A program with a type error and an unguarded index hears about the type error, and about the index once it gets that far. The lexer, the parser and the loader point at the exact line, and an import naming no file is reported on the line of its import. The passes after them see one flat program, so what they find lands on a declaration — its line, and in `main`: — in the file the declaration came from, named the way that file spells it.