KonLang Tiếng Việt

Library

It ships inside kon.exe and is written in Kon, with small C bridges for operating system calls. It fills the gap until Kon has its full standard library.

Using it

import "std/text.kon" as text
import "std/json.kon" as json

func main(): i32 {
    let source = text.of("[1, 2, 3]")
    let doc = json.parse(source)
    print(doc.count(doc.root()))
    return 0
}
3

There are no files to copy and no flags to add. The reference lists every function.

std/text

Text is UTF-8, and positions count bytes.

NameWhat it does
fromInt, fromUintWhole number to text
fromFloat(value, decimals)Fixed decimals, up to 9, or none if it cannot be shown
fromFloatShortestThe shortest text that reads back as exactly this float
parseInt, parseUint, parseFloatText to number, or none. Limits are checked, and floats round correctly
find, findFrom, containsSearch
startsWith, endsWith, equal, isText, compareCompare
split, lines, join, trim, replace, substringTake apart and put together
toLowerAscii, toUpperAsciiA to Z only; other letters stay as they are
readFile, writeFile, appendFileWhole text files. A write appears complete or not at all
argument, listDirectory, isDirectoryAtProgram arguments and folder listings as text
import "std/text.kon" as text

func main(): i32 {
    let row = text.of("An, 8.5 ,Hà Nội")
    let comma = text.of(",")
    let cells = text.split(row, comma)
    let score = text.trim(cells[1])
    let value = text.parseFloat(score)
    match value {
        some(number) => { print(number * 2.0) }
        none => { return 1 }
    }
    print(cells[2])
    return 0
}
17 Hà Nội

std/json

Reads strictly by RFC 8259, and agreed with JavaScript's JSON.parse on 3,000 random documents and their damaged copies. Asking about something absent gives your fallback, however deep the chain.

NameWhat it does
parse, loadFrom text or a file. isValid and errorText say what went wrong and on which line
root, get, getAt, item, first, next, keyOf, countFind values
numberOr, intOr, boolOr, textOrRead a value, or your fallback
isNull, isBool, isNumber, isText, isArray, isObject, existsAsk what it is
document, newObject, newArray, newNumber, newText, newBool, newNullMake values
set, setAt, push, setRootPut them together
toText(pretty), save(path)Write it out
import "std/json.kon" as json

func main(): i32 {
    var doc = json.document()
    let root = doc.newObject()
    doc.setRoot(root)
    let hp = doc.newNumber(100.0)
    let added = doc.set(root, "hp", hp)
    if !doc.save("save.json") { return 1 }

    let back = json.load("save.json")
    print(back.numberOr(back.get(back.root(), "hp"), 0.0))
    print(back.numberOr(back.get(back.root(), "mana"), 5.0))
    return 0
}
100 5

std/net

TCP, UDP, host lookup, timeouts, and a server for line-based protocols that handles many clients in one thread. There is no HTTP or TLS yet, so it cannot reach most of the web on its own.

NameWhat it does
connect, connectWithin, listen, acceptTCP connections, with timeouts
readLine, read, readToEnd, writeLine, writeText, writeAllSending and receiving
bindUdp, sendTo, receiveUDP datagrams
resolveThe addresses of a host name
setTimeout, setNonBlocking, waitReadableNot getting stuck
serve, poll, sendLine, broadcast, disconnectA server for many clients
lastErrorWhy the last call failed, in a sentence
import "std/net.kon" as net
import "std/text.kon" as text

// One program on both ends, over this machine's loopback.
func main(): i32 {
    let opened = net.listen("127.0.0.1", 0)
    match take opened {
        some(found) => {
            var listener = take found
            let address = listener.localAddress()
            match take address {
                some(place) => {
                    let attempt = net.connect("127.0.0.1", place.port)
                    match take attempt {
                        some(client) => {
                            var stream = take client
                            let incoming = listener.accept()
                            match take incoming {
                                some(other) => {
                                    var peer = take other
                                    let line = text.of("xin chào")
                                    if !stream.writeLine(line) { return 1 }
                                    let got = peer.readLine()
                                    match take got {
                                        some(value) => { print(value) }
                                        none => { return 2 }
                                    }
                                }
                                none => { return 3 }
                            }
                        }
                        none => { return 4 }
                    }
                }
                none => { return 5 }
            }
        }
        none => { return 6 }
    }
    return 0
}
xin chào

A whole chat server:

import "std/net.kon" as net

// A chat server: every line from one client goes to all the others.
func main(): i32 {
    let started = net.serve("127.0.0.1", 9000)
    match take started {
        some(found) => {
            var server = take found
            while true {
                let events = server.poll(1000)
                var at: u64 = 0
                while at < events.length {
                    if events[at].isLine() {
                        let line = events[at].lineText()
                        let count = server.broadcast(line, events[at].clientId())
                    }
                    at += 1
                }
            }
        }
        none => {
            let why = net.lastError()
            print(why)
            return 1
        }
    }
    return 0
}

Close a socket with close when you are done. Kon has no destructors yet, so one that is dropped stays open until the program ends.

std/hash

SHA-256, to tell whether content has changed.

NameWhat it does
sha256, sha256TextThe hash as 64 hex digits

std/sys

Files as bytes, clocks and arguments. Most programs want std/text on top of it.

NameWhat it does
readFile, writeFile, appendFile, removeFile, existsFiles as List<u8>, with atomic writes
makeDirectory, isDirectory, listDirectory, removeDirectoryAtFolders
monotonicMillis, unixMillis, sleepMillisTime
argumentCount, argumentProgram arguments

std/path

NameWhat it does
join, baseName, stem, extension, parent, isAbsolutePaths as text. Both / and \ work on Windows
walk(folder)Every file under a folder, in sorted order

std/args

--name is a flag and --name=value carries a value. A value always needs the =, so a flag can never swallow the word after it.

NameWhat it does
read, parseRead the command line
has, valueOr, positional, countAsk about it

std/process

Runs another program without a shell, so spaces and symbols in an argument reach it as they are, and text from outside cannot turn into extra commands.

NameWhat it does
command(program)A list with the program first; add arguments to it
run, runKeptRun and wait. runKept keeps its output and errors together
didStart, succeeded, exitCode, outputText, outputBytesWhat happened

Data structures

NameWhat it does
mapMap<K, V>, generic, with your own hash and equality
intmapIntMap, a fast table from i64 to i64
intsetIntSet
dequeIntDeque, a queue with both ends
heapMinHeap, a priority queue
gridGrid, a 2D map with shortest paths
sortsortI64, O(n log n) in the worst case

Numbers

NameWhat it does
mathmin, max, clamp, abs, gcd, integer square root, powers, sine and cosine in degrees
fixedFractions without floats
randomA repeatable generator. Not for security

Graphics and sound

std/gfx opens a window, draws to a software canvas and reads the keyboard and mouse. std/audio is a synthesizer written in Kon, and std/kit adds helpers for games. They have been used to test the language on small games: a falling-sand toy, an arcade game, a platformer and a 3D block world at about 155 frames per second, all drawn in software. Windows only for now.

Limits

  • Most data structures hold integers. map is the one generic so far.
  • Bytes cross into C one at a time, so very large files are slower than they need to be. This goes away when Kon can pass pointers to C.
  • A literal cannot yet stand in for a String, so needles are written text.of(",").
  • A temporary value cannot be passed where a view is expected, so bind it to a name first.
  • sinDegrees is an approximation, accurate to about 0.2%.