Repository navigation
Releases: ozzenerol/ktm-lang
Release list
v0.28.3
A program that clears the history before it ends leaves nothing for memsafe to report.
Fixes
term.historyClear()frees the history's list as well as its lines, and the path given toterm.historyFileis kept without allocating, so-Memsafeno longer lists them as still in use at exit. The file keeps its lines, and lines added after the clear still go into it.
v0.28.2
A prompt of several lines for term.readLine.
Fixes
term.readLinewith a prompt that holds a newline ("[bold]app>[/]\n") wrote the prompt again at every key, so the screen filled with prompts and the cursor drifted. The lines before the prompt's last are written once now, and only the last is redrawn with what is typed.
v0.28.1
Two fixes found by a program built on term.readLine.
Fixes
- A parameter's default value is checked against its type, as an argument is. A literal for a
Stringparameter (String path = ".history") compiled and handed the function a String of garbage, which crashed later in whatever used it; it is an error now that says to take au8[]. A default that would only warn as an argument (an integer for a pointer) warns. - An uncaught error that passed through a
deferis traced from where it was thrown. The trace began at the function whose defer ran, and the calls below it were missing: an error deep in a package showed up as a line ofmain. Athrow(e)from a catch is shown at its own line, not at the catch's closing brace.
v0.28.0
Reading what people type, with line editing and a history, as GNU readline does.
term: reading lines
term.readLine(prompt, &line)shows a prompt (markup allowed) and reads a line;falsewhen the input ends (Ctrl-D on an empty line, or the end of a pipe). On a terminal the line can be edited with the keys of bash: Left/Right, Home/End, Ctrl-A/E/B/F, a word at a time with Ctrl-Left/Right and Alt-B/F, Backspace, Delete, Ctrl-W, Ctrl-U, Ctrl-K; Ctrl-L clears the screen and Ctrl-C drops the line. A long line scrolls sideways. From a pipe or a file, lines are read as they come.- The history: Up/Down (Ctrl-P/N) go through the lines typed before, which
readLineadds by itself (not empty lines or a repeat).term.historyFile(path)keeps them between runs;historyAdd,historyAuto,historyMax,historyLen,historyAtandhistoryClearmanage it. term.readPassword(prompt, &line)reads a line without showing it and keeps it out of the history.term.clear()clears the terminal.- The terminal guide builds a small interactive program with them.
v0.27.1
Range for over a map, closable sidebars and chapter descriptions on the docs site, and a steadier test.
Fixes
for (auto e : m)over amap.Mapgives each entry, withe.keyande.value, in the order the keys were added; deleted keys are skipped. It works on a map held by value, through a pointer or as a field, withbreakandcontinue. Before, it was refused with "Range for loop must be on a struct with both a 'size' and 'entries' property". Ranging overm.entriesnow says to range over the map itself.- Docs site: the language chapters and the Quick Guides list their descriptions on the index pages, and every chapter page has a meta description.
- Docs site: every sidebar can be closed: the chapter lists, "On this page" and both panes of the library browser. Each keeps its tab where it was, and the site remembers what you closed.
- Test 534 (
coro.waitChild) no longer fails now and then on a loaded machine: its children end in a fixed order whatever their start-up time.
v0.27.0
A new standard library module for the output of command-line programs, and two Quick Guides.
term: terminal output
term.print(fmt, ...)isprintfwith colors written as markup:"[green]passed[/] %d tests, [bold red]%d failed[/]". Colors, backgrounds ([white on blue]) and styles (bold,dim,italic,underline,reverse,strike);[/]closes the last tag. The values filled in by%sare never read as markup.term.eprintwrites to stderr,term.formatinto aString.term.success,term.info,term.warnandterm.errorwrite one line after a green✓, a blue•, a yellow!or a red✗(warnings and errors to stderr);term.titlea bold line.- Colors are on for a terminal and off for a pipe or a file, with
NO_COLORset orTERM=dumb;FORCE_COLORandterm.setColorsturn them on. Without colors the markup is removed and the text stays. term.table(headers...)andt.row(cells...): cells of any type (text, numbers, bools, enums,Strings) in lined-up columns, numbers on the right, markup that doesn't count in the width.t.align,t.border(boxlines or amarkdowntable) andt.format()for the table as aString.term.progress(label, total): a progress bar on stderr, redrawn in place on a terminal, with the time taken atp.done(). Lines written withtermwhile it runs go above it; in a pipe only the last line is written.
Documentation
- Two new Quick Guides: Command-line flags with the
flagmodule, and Terminal output withterm.
v0.26.0
SQLite with arguments and structs, go-to-definition into packages, man pages, and Quick Guides.
SQLite: queries with arguments, rows into structs
db.exec(query, args...)runs one statement with its?s filled from the arguments and answers how many rows it changed. An argument can be an integer,bool, enum (stored by name), float, text (u8[],String,u8 *),sql.blob(bytes), a struct or slice (as JSON), or a pointer to one of them; a null pointer is NULL.sql.queryAll<T>(db, query, args...)returns every row as avec.Vec<T>,sql.queryOne<T>the first (sql.ERR_NO_ROWSwhen there is none). Columns fill a struct's fields by name (@key,@skip); a pointer field is null for NULL; any otherTtakes the first column, sosql.queryOne<i64>(db, "INSERT ... RETURNING id", ...)gives the new id.sql.free(reflect.of(x))frees what they allocated.- Failures throw
sql.ERR_SQLwith SQLite's message;db.errorCode()tells a broken constraint apart (sql.CONSTRAINT_UNIQUE,NOTNULL,FOREIGNKEY,CHECK,PRIMARYKEY).db.lastInsertId()is the last row's id. - The
sql.Param,sql.selectand prepared-statement calls work as before. The SQLite guide uses the new calls.
LSP
- Go to definition and hover reach a package's names:
pg.connect,pg.Conn, a sub-package (postgres.driver) and an import under another name. Before, only the standard library's and methods on a package's types did. - Go to definition reaches generic functions:
vec.new<i64>,json.decode<T>,pg.queryAll<T>. - Hover shows a package's names as the code writes them (
pg.Conn *pg.connect(...)), not the compiler's internal path. A package under areplaceopens at its real path.
Documentation
man ktm: the language guide and the standard library as man pages (ktm-<module>(3),ktm-guide-<chapter>(7)), installed on Linux.- Quick Guides: one task each, from an empty directory to a working program: database migrations, logging, SQLite and PostgreSQL. Every code block has a Copy button.
v0.25.0
Two changes to the language that make a program that compiled before fail to: both say what to write instead.
Changes you may notice
adis gone (v0.24.0 renamed itscoped).adin front of a declaration is an error that says to writescoped; anywhere elseadis an ordinary name. The packages moved too: ktm-pg v0.2.1, ktm-jwt v0.2.1 and ktm-migrate v0.1.1 usescoped(ktm getthem; older versions don't build any more).- A program or package can't give
StringorErrormethods of its own (void String.shout()), as it can't for any library type: their methods are the standard library's. Write a function that takes one instead:void shout(String *s).
v0.24.0
Threads without C, a clearer name for ad, and an LSP that imports for you.
Changes you may notice
adis spelledscoped:scoped String s = str.from("x");freessat the end of its block, asaddid.adstill works, with a warning at it that says to writescoped(none for the files of a package in the module cache); it will be removed in a later minor.thread.Pool's fieldrunis nowrunning(the name is the newrun()method).poolNew,poolEnqueue,poolWait,poolStopandpoolReleasework as before, for one more minor.
The thread module
thread.spawn(&f, &arg)runsf(T *)on a new thread, typed, with no casts;join()waits and throws what the thread threw, with its code, message, file and line. A spawned thread has ktm's runtime: crash reports,try,threadlocal.thread.Mutex(withguard()forscoped),Cond,RwLockandOnce: ready as declared, no setup, nothing to free.thread.go(&f, &arg, &wg)with athread.WaitGroup,thread.each(items, &f)over a slice on every core,thread.Channel<T>(buffered or not) and a typedthread.pool(n)withrun()andwait(); each wait throws the first error its threads threw.- The threads chapter of the docs teaches the module, with C's threads last.
LSP
- Completion offers names from modules a file doesn't import yet (the library, the project's own modules and its
ktm.modpackages) and adds theimportwhen one is picked; quick fixes add a missing import for an unknown name. - A correct file no longer shows errors: files of a package repository (a
ktm.modwithmodule pg;in a directory named otherwise) were read as stray programs, open files kept errors after the file they import was fixed, and an imported file's warnings showed up in every importer. - An error in a
returnno longer also warns that the function may not return a value.
Fixes
- macOS: a caught
throwleft the thread's signal mask garbled, so a thread started or a program run afterwards blocked SIGSEGV, and a crash in it spun forever instead of being reported.
v0.23.2
Fixes, most of them to the compiler. Two make programs that were wrong fail loudly: a printf-style format whose values don't match it no longer compiles, and an integer division by zero on arm64 crashes as it does on x86_64.
- An inlined call whose body declares a local from a parameter (
i64 *p = (i64 *)w;) kept the argument's value: given an array element, a dereference or a field (f(slot[0])), the parameter read garbage. Wrong code since inlining came in; plain locals as arguments were right. - printf-style formats (
printf,str.format,appendFormatand your own functions that take one) check each value's type against its conversion, not only their count:%sof a number,%dof text or a float and%fof an integer are compile errors that say which value is wrong. - An integer division or
%by zero crashes on arm64 with "integer division by zero" and exit status 136, as on x86_64, compiled and in the JIT. It gave 0 and the program went on. - The smallest
i64divided by -1 (and%-1) crashes on every platform with "integer overflow in division"; x86_64 called it a division by zero and arm64 gave the dividend. - A crash inside C code (printf given a bad
%s) names the ktm line that called it and every caller up tomain. x86_64 could name rt.crash or a function that had already returned and losemain; Linux arm64 showed only "in C code". - A module's
extern "c"function is called by the module's name for it (libc.strlen): a program function with the same C name no longer takes those calls. - A method can be defined through a type alias of its struct.
- An error in an
asmfunction is reported on its instruction's line, not the line after it.