KonLang English

Thư viện

Thư viện nằm sẵn trong kon.exe và được viết bằng Kon, kèm các cầu nối C nhỏ để gọi hệ điều hành. Nó lấp chỗ trống cho đến khi Kon có thư viện chuẩn đầy đủ.

Cách dùng

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

Không phải chép file, cũng không phải thêm cờ. Trang tra cứu liệt kê mọi hàm.

std/text

Chữ là UTF-8, và vị trí tính theo byte.

TênCông dụng
fromInt, fromUintSố nguyên thành chữ
fromFloat(value, decimals)Số thập phân cố định, tối đa 9 chữ số; trả none nếu không biểu diễn được
fromFloatShortestChữ ngắn nhất mà đọc lại vẫn đúng giá trị số thực
parseInt, parseUint, parseFloatChữ thành số, hoặc none. Có kiểm tra giới hạn, số thực làm tròn chính xác
find, findFrom, containsTìm kiếm
startsWith, endsWith, equal, isText, compareSo sánh
split, lines, join, trim, replace, substringTách và ghép
toLowerAscii, toUpperAsciiChỉ A đến Z; chữ có dấu giữ nguyên
readFile, writeFile, appendFileĐọc ghi cả file chữ. File ghi xong hoàn chỉnh hoặc không có gì
argument, listDirectory, isDirectoryAtTham số chương trình và danh sách thư mục dạng chữ
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

Đọc chặt chẽ theo RFC 8259, và cho kết quả khớp với JSON.parse của JavaScript trên 3.000 tài liệu ngẫu nhiên cùng các bản bị làm hỏng. Hỏi thứ không tồn tại sẽ nhận giá trị mặc định của bạn, dù chuỗi lời gọi sâu đến đâu.

TênCông dụng
parse, loadTừ chữ hoặc file. isValid và errorText cho biết sai gì, ở dòng nào
root, get, getAt, item, first, next, keyOf, countTìm giá trị
numberOr, intOr, boolOr, textOrĐọc giá trị, hoặc lấy giá trị mặc định
isNull, isBool, isNumber, isText, isArray, isObject, existsHỏi đó là gì
document, newObject, newArray, newNumber, newText, newBool, newNullTạo giá trị
set, setAt, push, setRootGhép chúng lại
toText(pretty), save(path)Xuất ra
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, tra tên miền, timeout, và server cho giao thức theo dòng xử lý nhiều client trong một luồng. Chưa có HTTP hay TLS, nên tự nó chưa truy cập được phần lớn web.

TênCông dụng
connect, connectWithin, listen, acceptKết nối TCP, có timeout
readLine, read, readToEnd, writeLine, writeText, writeAllGửi và nhận
bindUdp, sendTo, receiveDatagram UDP
resolveCác địa chỉ của một tên máy
setTimeout, setNonBlocking, waitReadableTránh bị treo
serve, poll, sendLine, broadcast, disconnectServer cho nhiều client
lastErrorVì sao lệnh vừa rồi lỗi, viết thành một câu
import "std/net.kon" as net
import "std/text.kon" as text

// Một chương trình ở cả hai đầu, qua loopback của máy này.
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

Một server chat hoàn chỉnh:

import "std/net.kon" as net

// Server chat: mỗi dòng từ một client được gửi cho mọi client còn lại.
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
}

Dùng xong thì đóng socket bằng close. Kon chưa có destructor, nên socket bị bỏ quên sẽ mở đến khi chương trình kết thúc.

std/hash

SHA-256, để biết nội dung có thay đổi không.

TênCông dụng
sha256, sha256TextMã băm gồm 64 chữ số hex

std/sys

File dạng byte, đồng hồ và tham số. Phần lớn chương trình nên dùng std/text ở trên nó.

TênCông dụng
readFile, writeFile, appendFile, removeFile, existsFile dạng List<u8>, ghi nguyên tử
makeDirectory, isDirectory, listDirectory, removeDirectoryAtThư mục
monotonicMillis, unixMillis, sleepMillisThời gian
argumentCount, argumentTham số chương trình

std/path

TênCông dụng
join, baseName, stem, extension, parent, isAbsoluteĐường dẫn dạng chữ. Trên Windows dùng được cả / và \
walk(folder)Mọi file trong một thư mục, đã sắp xếp

std/args

--ten là cờ, còn --ten=gia_tri mang giá trị. Giá trị luôn cần dấu =, nên cờ không bao giờ nuốt nhầm từ phía sau.

TênCông dụng
read, parseĐọc dòng lệnh
has, valueOr, positional, countHỏi về dòng lệnh

std/process

Chạy chương trình khác mà không qua shell, nên dấu cách và ký hiệu trong tham số được giữ nguyên, và chữ từ bên ngoài không biến thành lệnh mới được.

TênCông dụng
command(program)Danh sách với tên chương trình đứng đầu; thêm tham số vào đó
run, runKeptChạy và chờ. runKept giữ lại output và lỗi cùng nhau
didStart, succeeded, exitCode, outputText, outputBytesKết quả ra sao

Cấu trúc dữ liệu

TênCông dụng
mapMap<K, V> generic, với hàm băm và so sánh của bạn
intmapIntMap, bảng nhanh từ i64 sang i64
intsetIntSet
dequeIntDeque, hàng đợi hai đầu
heapMinHeap, hàng đợi ưu tiên
gridGrid, bản đồ 2D có tìm đường ngắn nhất
sortsortI64, O(n log n) kể cả trường hợp xấu nhất

Số

TênCông dụng
mathmin, max, clamp, abs, gcd, căn bậc hai nguyên, luỹ thừa, sin và cos theo độ
fixedSố thập phân không dùng số thực
randomBộ sinh số lặp lại được. Không dùng cho bảo mật

Đồ hoạ và âm thanh

std/gfx mở cửa sổ, vẽ bằng phần mềm và đọc bàn phím, chuột. std/audio là bộ tổng hợp âm viết bằng Kon, và std/kit thêm các hàm hỗ trợ làm game. Chúng đã được dùng để thử sức ngôn ngữ qua các game nhỏ: trò cát rơi, một game arcade, một game platformer và một thế giới khối 3D khoảng 155 FPS, tất cả vẽ bằng phần mềm. Hiện chỉ chạy trên Windows.

Giới hạn

  • Phần lớn cấu trúc dữ liệu chỉ chứa số nguyên. map là cái generic duy nhất đến nay.
  • Dữ liệu qua C từng byte một, nên file rất lớn sẽ chậm hơn mức cần thiết. Việc này hết khi Kon truyền được con trỏ sang C.
  • Chữ cố định chưa thay được cho String, nên phải viết text.of(",").
  • Giá trị tạm chưa truyền được vào chỗ cần view, nên phải gán vào biến trước.
  • sinDegrees là xấp xỉ, chính xác khoảng 0,2%.