mirror of
https://github.com/Nexoniarz/Finch.git
synced 2026-11-03 16:54:25 +00:00
docs, Kate and VS Code: const, if as a value, """ text, 1e9, str(x, 2), min/max/abs/clamp, import a/b and as, fs, C unions and macros
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016GzNP6r8dg6WDxUVZy8wjL
This commit is contained in:
parent
f2d6480749
commit
17863ecf7b
8 changed files with 163 additions and 35 deletions
10
README.md
10
README.md
|
|
@ -90,7 +90,7 @@ Pick the guide that fits you:
|
||||||
|
|
||||||
| | |
|
| | |
|
||||||
|---|---|
|
|---|---|
|
||||||
| Variables | `x := 5` (inferred) or `int x = 5` |
|
| Variables | `x := 5` (inferred) or `int x = 5`; `const W = 640` |
|
||||||
| Types | `int` `float` `bool` `char` `str`, sized `i8`…`i64` `u8`…`u64` `f32` `f64`, arrays `[]T`, maps `map[K]V`, pointers `ptr[T]` |
|
| Types | `int` `float` `bool` `char` `str`, sized `i8`…`i64` `u8`…`u64` `f32` `f64`, arrays `[]T`, maps `map[K]V`, pointers `ptr[T]` |
|
||||||
| Functions | `fn add(int a, int b) -> int { return a + b }` |
|
| Functions | `fn add(int a, int b) -> int { return a + b }` |
|
||||||
| Structs | `struct Point { … }` with one field per line (`int x`, `int y = 0`); create with `Point(1, 2)` or `Point(x: 1)` |
|
| Structs | `struct Point { … }` with one field per line (`int x`, `int y = 0`); create with `Point(1, 2)` or `Point(x: 1)` |
|
||||||
|
|
@ -99,11 +99,11 @@ Pick the guide that fits you:
|
||||||
| Maps | `ages := ["ann": 31]`, `ages["bob"] = 25`, `ages.has("cy")`, `counts[w] += 1`, `for k, v in ages { }` |
|
| Maps | `ages := ["ann": 31]`, `ages["bob"] = 25`, `ages.has("cy")`, `counts[w] += 1`, `for k, v in ages { }` |
|
||||||
| Errors | `fn parse(str s) -> int! { … return error("bad") }` → `parse(s) or 0`, `parse(s) or { … }`, `try parse(s)` |
|
| Errors | `fn parse(str s) -> int! { … return error("bad") }` → `parse(s) or 0`, `parse(s) or { … }`, `try parse(s)` |
|
||||||
| Text | `"a" + "b"`, `str(42)`, `int("42")`, `s.split(",")`, `s.upper()`, `s[0]` |
|
| Text | `"a" + "b"`, `str(42)`, `int("42")`, `s.split(",")`, `s.upper()`, `s[0]` |
|
||||||
| Control | `if` / `else if` / `else`, `while`, `for i in 0..10`, `break`, `continue`, `defer` |
|
| Control | `if` / `else if` / `else` (also as a value), `while`, `for i in 0..10`, `break`, `continue`, `defer` |
|
||||||
| Memory | automatic for arrays, text and structs; `new(...)` / `free(...)` for your own heap structures |
|
| Memory | automatic for arrays, text and structs; `new(...)` / `free(...)` for your own heap structures |
|
||||||
| Enums, match | `enum Color { Red, Green }`, `match c { Red -> ... else -> ... }` (also as a value) |
|
| Enums, match | `enum Color { Red, Green }`, `match c { Red -> ... else -> ... }` (also as a value) |
|
||||||
| Generics | `fn max[T](T a, T b) -> T`, `struct Stack[T]`, `Stack[int]()` |
|
| Generics | `fn max[T](T a, T b) -> T`, `struct Stack[T]`, `Stack[int]()` |
|
||||||
| Modules | `import shapes` → `shapes.area(b)`; the standard library: `json`, `path`, `time`, `proc` |
|
| Modules | `import shapes` → `shapes.area(b)`; the standard library: `json`, `path`, `time`, `proc`, `fs` |
|
||||||
| C interop | `import "stdio.h"`, `link "glfw"`, `link "mine.c"`, `addr(fn)` for callbacks |
|
| C interop | `import "stdio.h"`, `link "glfw"`, `link "mine.c"`, `addr(fn)` for callbacks |
|
||||||
| I/O | `print(...)`, `input("? ")`, `read_file`, `write_file`, `shell` |
|
| I/O | `print(...)`, `input("? ")`, `read_file`, `write_file`, `shell` |
|
||||||
| Tools | `finch run/build/ir/lsp`, `--target windows/arm64/macos`, `-g` for gdb/lldb, `-O0` |
|
| Tools | `finch run/build/ir/lsp`, `--target windows/arm64/macos`, `-g` for gdb/lldb, `-O0` |
|
||||||
|
|
@ -146,14 +146,14 @@ Pick the guide that fits you:
|
||||||
- [x] macOS and ARM64 (Linux and Apple Silicon), with their C calling conventions; Kate support
|
- [x] macOS and ARM64 (Linux and Apple Silicon), with their C calling conventions; Kate support
|
||||||
- [x] Methods on structs, maps, errors as values (`!`, `or`, `try`)
|
- [x] Methods on structs, maps, errors as values (`!`, `or`, `try`)
|
||||||
- [x] Generics (`fn max[T]`, `struct Stack[T]`), `match`, enums
|
- [x] Generics (`fn max[T]`, `struct Stack[T]`), `match`, enums
|
||||||
- [x] A standard library in Finch: `json`, `path`, `time`, `proc`
|
- [x] A standard library in Finch: `json`, `path`, `time`, `proc`, `fs`
|
||||||
|
|
||||||
## Layout
|
## Layout
|
||||||
|
|
||||||
```
|
```
|
||||||
src/ the compiler, in Finch: lexer, parser, AST, code generation (to LLVM IR as text), C import (libclang) and
|
src/ the compiler, in Finch: lexer, parser, AST, code generation (to LLVM IR as text), C import (libclang) and
|
||||||
the C calling conventions, the language server, the driver
|
the C calling conventions, the language server, the driver
|
||||||
std/ the standard library, in Finch: json, path, time, proc
|
std/ the standard library, in Finch: json, path, time, proc, fs
|
||||||
runtime/ the small C runtime linked into every program
|
runtime/ the small C runtime linked into every program
|
||||||
bootstrap/ build.sh and the seeds: the compiler's own LLVM IR, one per system
|
bootstrap/ build.sh and the seeds: the compiler's own LLVM IR, one per system
|
||||||
examples/ example programs
|
examples/ example programs
|
||||||
|
|
|
||||||
10
README.pl.md
10
README.pl.md
|
|
@ -90,7 +90,7 @@ Wybierz przewodnik dla siebie:
|
||||||
|
|
||||||
| | |
|
| | |
|
||||||
|---|---|
|
|---|---|
|
||||||
| Zmienne | `x := 5` (typ zgadnięty) albo `int x = 5` |
|
| Zmienne | `x := 5` (typ zgadnięty) albo `int x = 5`; `const W = 640` |
|
||||||
| Typy | `int` `float` `bool` `char` `str`, z rozmiarem `i8`…`i64` `u8`…`u64` `f32` `f64`, tablice `[]T`, mapy `map[K]V`, wskaźniki `ptr[T]` |
|
| Typy | `int` `float` `bool` `char` `str`, z rozmiarem `i8`…`i64` `u8`…`u64` `f32` `f64`, tablice `[]T`, mapy `map[K]V`, wskaźniki `ptr[T]` |
|
||||||
| Funkcje | `fn add(int a, int b) -> int { return a + b }` |
|
| Funkcje | `fn add(int a, int b) -> int { return a + b }` |
|
||||||
| Struktury | `struct Punkt { … }` z jednym polem na linijkę (`int x`, `int y = 0`); tworzenie przez `Punkt(1, 2)` albo `Punkt(x: 1)` |
|
| Struktury | `struct Punkt { … }` z jednym polem na linijkę (`int x`, `int y = 0`); tworzenie przez `Punkt(1, 2)` albo `Punkt(x: 1)` |
|
||||||
|
|
@ -99,11 +99,11 @@ Wybierz przewodnik dla siebie:
|
||||||
| Mapy | `wiek := ["ania": 31]`, `wiek["bob"] = 25`, `wiek.has("cy")`, `ile[s] += 1`, `for k, v in wiek { }` |
|
| Mapy | `wiek := ["ania": 31]`, `wiek["bob"] = 25`, `wiek.has("cy")`, `ile[s] += 1`, `for k, v in wiek { }` |
|
||||||
| Błędy | `fn parsuj(str s) -> int! { … return error("zły") }` → `parsuj(s) or 0`, `parsuj(s) or { … }`, `try parsuj(s)` |
|
| Błędy | `fn parsuj(str s) -> int! { … return error("zły") }` → `parsuj(s) or 0`, `parsuj(s) or { … }`, `try parsuj(s)` |
|
||||||
| Tekst | `"a" + "b"`, `str(42)`, `int("42")`, `s.split(",")`, `s.upper()`, `s[0]` |
|
| Tekst | `"a" + "b"`, `str(42)`, `int("42")`, `s.split(",")`, `s.upper()`, `s[0]` |
|
||||||
| Sterowanie | `if` / `else if` / `else`, `while`, `for i in 0..10`, `break`, `continue`, `defer` |
|
| Sterowanie | `if` / `else if` / `else` (też jako wartość), `while`, `for i in 0..10`, `break`, `continue`, `defer` |
|
||||||
| Pamięć | automatyczna dla tablic, tekstów i struktur; `new(...)` / `free(...)` dla własnych struktur na stercie |
|
| Pamięć | automatyczna dla tablic, tekstów i struktur; `new(...)` / `free(...)` dla własnych struktur na stercie |
|
||||||
| Enumy, match | `enum Kolor { Czerwony, Zielony }`, `match k { Czerwony -> ... else -> ... }` (także jako wartość) |
|
| Enumy, match | `enum Kolor { Czerwony, Zielony }`, `match k { Czerwony -> ... else -> ... }` (także jako wartość) |
|
||||||
| Generyki | `fn max[T](T a, T b) -> T`, `struct Stos[T]`, `Stos[int]()` |
|
| Generyki | `fn max[T](T a, T b) -> T`, `struct Stos[T]`, `Stos[int]()` |
|
||||||
| Moduły | `import ksztalty` → `ksztalty.pole(p)`; biblioteka standardowa: `json`, `path`, `time`, `proc` |
|
| Moduły | `import ksztalty` → `ksztalty.pole(p)`; biblioteka standardowa: `json`, `path`, `time`, `proc`, `fs` |
|
||||||
| Współpraca z C | `import "stdio.h"`, `link "glfw"`, `link "moje.c"`, `addr(fn)` dla callbacków |
|
| Współpraca z C | `import "stdio.h"`, `link "glfw"`, `link "moje.c"`, `addr(fn)` dla callbacków |
|
||||||
| Wejście/wyjście | `print(...)`, `input("? ")`, `read_file`, `write_file`, `shell` |
|
| Wejście/wyjście | `print(...)`, `input("? ")`, `read_file`, `write_file`, `shell` |
|
||||||
| Narzędzia | `finch run/build/ir/lsp`, `--target windows/arm64/macos`, `-g` dla gdb/lldb, `-O0` |
|
| Narzędzia | `finch run/build/ir/lsp`, `--target windows/arm64/macos`, `-g` dla gdb/lldb, `-O0` |
|
||||||
|
|
@ -146,14 +146,14 @@ Wybierz przewodnik dla siebie:
|
||||||
- [x] macOS i ARM64 (Linux i Apple Silicon) z ich konwencjami wywołań C; obsługa Kate
|
- [x] macOS i ARM64 (Linux i Apple Silicon) z ich konwencjami wywołań C; obsługa Kate
|
||||||
- [x] Metody w strukturach, mapy, błędy jako wartości (`!`, `or`, `try`)
|
- [x] Metody w strukturach, mapy, błędy jako wartości (`!`, `or`, `try`)
|
||||||
- [x] Typy generyczne (`fn max[T]`, `struct Stos[T]`), `match`, enumy
|
- [x] Typy generyczne (`fn max[T]`, `struct Stos[T]`), `match`, enumy
|
||||||
- [x] Biblioteka standardowa w Finchu: `json`, `path`, `time`, `proc`
|
- [x] Biblioteka standardowa w Finchu: `json`, `path`, `time`, `proc`, `fs`
|
||||||
|
|
||||||
## Struktura
|
## Struktura
|
||||||
|
|
||||||
```
|
```
|
||||||
src/ kompilator, w Finchu: lekser, parser, AST, generowanie kodu (do LLVM IR jako tekst), import C (libclang)
|
src/ kompilator, w Finchu: lekser, parser, AST, generowanie kodu (do LLVM IR jako tekst), import C (libclang)
|
||||||
i konwencje wywołań C, serwer języka, sterownik
|
i konwencje wywołań C, serwer języka, sterownik
|
||||||
std/ biblioteka standardowa, w Finchu: json, path, time, proc
|
std/ biblioteka standardowa, w Finchu: json, path, time, proc, fs
|
||||||
runtime/ mały runtime w C dołączany do każdego programu
|
runtime/ mały runtime w C dołączany do każdego programu
|
||||||
bootstrap/ build.sh i ziarna: własny LLVM IR kompilatora, po jednym na system
|
bootstrap/ build.sh i ziarna: własny LLVM IR kompilatora, po jednym na system
|
||||||
examples/ przykładowe programy
|
examples/ przykładowe programy
|
||||||
|
|
|
||||||
|
|
@ -53,9 +53,10 @@ One statement per line, no semicolons, `{` on the same line, no brackets around
|
||||||
|---|---|
|
|---|---|
|
||||||
| `x := 5` | new variable, type inferred |
|
| `x := 5` | new variable, type inferred |
|
||||||
| `int x = 5` | new variable, type written |
|
| `int x = 5` | new variable, type written |
|
||||||
| `int x` | zero / `""` / `[]` / `null` / the struct's defaults |
|
| `int x` | zero / `""` / `[]` / `null` / the struct's defaults (also of the structs inside it) |
|
||||||
| `x = 7` | assign |
|
| `x = 7` | assign |
|
||||||
| `x += 1` `-=` `*=` `/=` `%=` | update |
|
| `x += 1` `-=` `*=` `/=` `%=` | update |
|
||||||
|
| `const W = 640`, `const f32 G = 9.8` | a constant (top level of a file; `shapes.W` from a module) |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -64,10 +65,10 @@ One statement per line, no semicolons, `{` on the same line, no brackets around
|
||||||
| Type | Example |
|
| Type | Example |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `int` (= `i64`) | `42`, `-7`, `0xFF`, `1_000_000` |
|
| `int` (= `i64`) | `42`, `-7`, `0xFF`, `1_000_000` |
|
||||||
| `float` (= `f64`) | `3.14` |
|
| `float` (= `f64`) | `3.14`, `1e9`, `2.5e-3` |
|
||||||
| `bool` | `true`, `false` |
|
| `bool` | `true`, `false` |
|
||||||
| `char` | `'A'`, `'\n'` |
|
| `char` | `'A'`, `'\n'` |
|
||||||
| `str` | `"text\t\"quoted\""` |
|
| `str` | `"text\t\"quoted\""`, `"""` several lines `"""` (the closing quotes' indentation is removed) |
|
||||||
| `i8 i16 i32 i64` | signed, sized |
|
| `i8 i16 i32 i64` | signed, sized |
|
||||||
| `u8 u16 u32 u64` | unsigned, sized |
|
| `u8 u16 u32 u64` | unsigned, sized |
|
||||||
| `f32 f64` | floats |
|
| `f32 f64` | floats |
|
||||||
|
|
@ -99,6 +100,7 @@ Escapes: `\n \t \r \0 \\ \" \'`.
|
||||||
|
|
||||||
```c
|
```c
|
||||||
if a > b { … } else if a == b { … } else { … }
|
if a > b { … } else if a == b { … } else { … }
|
||||||
|
x := if a > b { a } else { b } // as a value: one value per branch, else needed
|
||||||
while x > 0 { … }
|
while x > 0 { … }
|
||||||
for i in 0..10 { … } // 0 … 9
|
for i in 0..10 { … } // 0 … 9
|
||||||
for item in list { … } // every element (or char of a str)
|
for item in list { … } // every element (or char of a str)
|
||||||
|
|
@ -234,7 +236,7 @@ Fallible built-ins: `int(s)`, `float(s)`, `read_file`, `write_file`, `delete_fil
|
||||||
| `s.replace(a, b)` | every a → b |
|
| `s.replace(a, b)` | every a → b |
|
||||||
| `s.repeat(n)` | n times |
|
| `s.repeat(n)` | n times |
|
||||||
| `s.bytes()` | `[]u8` |
|
| `s.bytes()` | `[]u8` |
|
||||||
| `s.ptr` | `ptr[char]` (for C) |
|
| `s.ptr` | `ptr[char]` (for C; a `str` also goes to a `const char *` parameter as it is) |
|
||||||
| `==` `!=` `<` `>` | compare |
|
| `==` `!=` `<` `>` | compare |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -250,7 +252,8 @@ Fallible built-ins: `int(s)`, `float(s)`, `read_file`, `write_file`, `delete_fil
|
||||||
| `u8(300)` | `44` (keeps the low bits) |
|
| `u8(300)` | `44` (keeps the low bits) |
|
||||||
| `char(66)` | `'B'` |
|
| `char(66)` | `'B'` |
|
||||||
| `bool(0)` | `false` |
|
| `bool(0)` | `false` |
|
||||||
| `str(42)`, `str(1.5)`, `str(true)`, `str('c')` | text |
|
| `str(42)`, `str(1.5)`, `str(true)`, `str('c')` | text (a float: the shortest text that is the same number) |
|
||||||
|
| `str(3.14159, 2)` | `"3.14"` (that many digits after the point) |
|
||||||
| `str([1, 2])`, `str(m)`, `str(point)` | the same text `print` shows |
|
| `str([1, 2])`, `str(m)`, `str(point)` | the same text `print` shows |
|
||||||
| `int("x") or 0`, `float(s) or 0.0` | a number, or the fallback |
|
| `int("x") or 0`, `float(s) or 0.0` | a number, or the fallback |
|
||||||
| `str(bytes)` | `[]u8` → text |
|
| `str(bytes)` | `[]u8` → text |
|
||||||
|
|
@ -273,7 +276,8 @@ Automatic only when nothing is lost: smaller → bigger number, any int → floa
|
||||||
| `file_exists(path)` | bool |
|
| `file_exists(path)` | bool |
|
||||||
| `delete_file(path)` | bool |
|
| `delete_file(path)` | bool |
|
||||||
| `shell(command)` | run a command, its exit code |
|
| `shell(command)` | run a command, its exit code |
|
||||||
| `exit(code)` | stop the program now |
|
| `exit(code)` | stop the program now (also ends an `or { }` block) |
|
||||||
|
| `min(a, b, …)`, `max(a, b, …)`, `abs(x)`, `clamp(x, lo, hi)` | for any numbers (your own function of that name wins) |
|
||||||
| `error(message)` | `return error("…")` in a `-> T!` function |
|
| `error(message)` | `return error("…")` in a `-> T!` function |
|
||||||
| `addr(x)` | pointer to x; `addr(fn)` = C callback |
|
| `addr(x)` | pointer to x; `addr(fn)` = C callback |
|
||||||
| `new(value)` | value on the heap → `ptr[T]` |
|
| `new(value)` | value on the heap → `ptr[T]` |
|
||||||
|
|
@ -311,6 +315,8 @@ import shapes // shapes.fch next to this file (or in FINCH_PATH)
|
||||||
shapes.area(b) // its functions
|
shapes.area(b) // its functions
|
||||||
shapes.Box(2, 3) // its structs
|
shapes.Box(2, 3) // its structs
|
||||||
shapes.Box other // in declarations
|
shapes.Box other // in declarations
|
||||||
|
import ui/button // ui/button.fch: button.draw()
|
||||||
|
import ui/button as btn // another name: btn.draw()
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -334,6 +340,10 @@ shapes.Box other // in declarations
|
||||||
| `T *` | `ptr[T]` |
|
| `T *` | `ptr[T]` |
|
||||||
| `void *`, handles | `ptr` |
|
| `void *`, handles | `ptr` |
|
||||||
| `T x[N]` (in a struct) | `[N]T` |
|
| `T x[N]` (in a struct) | `[N]T` |
|
||||||
|
| `union U` | `U`: `U u`, `u.field`, `U(field: v)`, by pointer to C (not by value) |
|
||||||
|
| `#define N 4`, `"text"`, `(1u << 3)`, `((Uint64)2)` | constants (not function-like macros) |
|
||||||
|
|
||||||
|
A C function's `char *` result is a `str` already; structs by value work on every target (System V, Windows x64, ARM64).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -397,9 +407,10 @@ s := Stack[int]() Stack[int] t Pair[str, int]("age", 31) // ne
|
||||||
| `path` | `join(a, b)` `base(p)` `dir(p)` `ext(p)` `stem(p)` `parts(p)` `clean(p)` `is_abs(p)` |
|
| `path` | `join(a, b)` `base(p)` `dir(p)` `ext(p)` `stem(p)` `parts(p)` `clean(p)` `is_abs(p)` |
|
||||||
| `time` | `now()` `millis()` `sleep(ms)` `date(t)` `local(t)` `format(t, fmt)` `days_in_month(y, m)` |
|
| `time` | `now()` `millis()` `sleep(ms)` `date(t)` `local(t)` `format(t, fmt)` `days_in_month(y, m)` |
|
||||||
| `proc` | `run(cmd)` `output(cmd)` (fails with its output) `env(name, fallback)` `pid()` `cwd()` |
|
| `proc` | `run(cmd)` `output(cmd)` (fails with its output) `env(name, fallback)` `pid()` `cwd()` |
|
||||||
|
| `fs` | `read_bytes(p)` `write_bytes(p, data)` `exists(p)` `is_dir(p)` `mkdir(p)` `list(dir)` `remove_dir(p)` `data_dir(app)` |
|
||||||
| `json` | `parse(text)` `stringify(v)` `pretty(v)` `new_text/number/bool/null/list/object` `v.get(k)` `v.at(i)` `v.set(k, x)` `v.push(x)` `v.has(k)` `v.str_or(d)` `v.int_or(d)` `v.float_or(d)` `v.bool_or(d)` |
|
| `json` | `parse(text)` `stringify(v)` `pretty(v)` `new_text/number/bool/null/list/object` `v.get(k)` `v.at(i)` `v.set(k, x)` `v.push(x)` `v.has(k)` `v.str_or(d)` `v.int_or(d)` `v.float_or(d)` `v.bool_or(d)` |
|
||||||
|
|
||||||
## Keywords
|
## Keywords
|
||||||
|
|
||||||
`fn return if else while for in break continue true false null import link struct enum match defer or try`
|
`fn return if else while for in break continue true false null import link struct enum match defer or try const export`
|
||||||
(and `self` inside methods)
|
(and `self` inside methods)
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,19 @@ x += 1 // also -= *= /= %=
|
||||||
- Names: ASCII letters, digits and `_`, not starting with a digit. Non-ASCII letters are allowed only inside strings.
|
- Names: ASCII letters, digits and `_`, not starting with a digit. Non-ASCII letters are allowed only inside strings.
|
||||||
Type names (`int`, `u8`, …), built-in function names and keywords are reserved.
|
Type names (`int`, `u8`, …), built-in function names and keywords are reserved.
|
||||||
|
|
||||||
**Keywords:** `fn return if else while for in break continue true false null import link struct defer`
|
**Keywords:** `fn return if else while for in break continue true false null import link struct enum match defer or try const export`
|
||||||
|
|
||||||
|
### Constants
|
||||||
|
|
||||||
|
```c
|
||||||
|
const WIDTH = 640
|
||||||
|
const HEIGHT = WIDTH / 2 // from other constants
|
||||||
|
const f32 GRAVITY = 9.8 // with a type
|
||||||
|
const TITLE = "My game"
|
||||||
|
```
|
||||||
|
|
||||||
|
A constant is written at the top level of a file, next to the functions, and can't be changed. It is made of
|
||||||
|
numbers, text, `true`/`false`, chars, other constants and operators; a module's constant is `shapes.SIDES`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -316,6 +328,13 @@ Notes:
|
||||||
|
|
||||||
## 8. Control flow
|
## 8. Control flow
|
||||||
|
|
||||||
|
`if` can also give a value; each branch holds one value, and the `else` is needed:
|
||||||
|
|
||||||
|
```c
|
||||||
|
label := if score > 100 { "high" } else if score > 10 { "mid" } else { "low" }
|
||||||
|
f32 speed = if running { 2.5 } else { 1.0 }
|
||||||
|
```
|
||||||
|
|
||||||
```c
|
```c
|
||||||
if x > 10 {
|
if x > 10 {
|
||||||
...
|
...
|
||||||
|
|
@ -485,7 +504,21 @@ s[0] = 'J' // change a character
|
||||||
| `s.ptr` | a `ptr[char]` for C (valid while `s` lives) |
|
| `s.ptr` | a `ptr[char]` for C (valid while `s` lives) |
|
||||||
|
|
||||||
`str` keeps its length, so `.len` is instant, and it is always NUL-terminated, so passing it
|
`str` keeps its length, so `.len` is instant, and it is always NUL-terminated, so passing it
|
||||||
to C as `char*` works.
|
to C as `char*` works. The other way round, a C function that gives back a `char *` gives you a `str`
|
||||||
|
(a copy is made when you keep it), and `str(p)` reads a `ptr[char]` you got some other way.
|
||||||
|
|
||||||
|
Text over several lines goes between `"""`. The line break after the opening quotes is dropped, and so is the
|
||||||
|
indentation of the closing quotes, from every line, so the text can be indented with your code:
|
||||||
|
|
||||||
|
```c
|
||||||
|
shader := """
|
||||||
|
#version 330
|
||||||
|
void main() { gl_Position = vec4(0.0); }
|
||||||
|
"""
|
||||||
|
```
|
||||||
|
|
||||||
|
Numbers as text: `str(x)` is the shortest text that reads back as the same number (`0.1`, `0.30000000000000004`,
|
||||||
|
`1e+20`); `str(x, 2)` always has two digits after the point (`3.14`).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -642,6 +675,8 @@ fn main() {
|
||||||
|
|
||||||
- Everything in a module is used with the module's name in front: `shapes.area`, `shapes.Box`.
|
- Everything in a module is used with the module's name in front: `shapes.area`, `shapes.Box`.
|
||||||
- A module doesn't have `main`. Modules can import other modules.
|
- A module doesn't have `main`. Modules can import other modules.
|
||||||
|
- Modules in folders: `import ui/button` loads `ui/button.fch` and is used as `button.draw()`.
|
||||||
|
- Another name: `import ui/button as btn` → `btn.draw()`. Two imports can't use the same name.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -742,8 +777,10 @@ Both work directly; `examples/opengl.fch` and `examples/vulkan.fch` are complete
|
||||||
|
|
||||||
### What does not work yet
|
### What does not work yet
|
||||||
|
|
||||||
- C **unions** by value, and structs with **bit fields** by value (pointers to them work).
|
- C **unions** and structs with **bit fields** passed to or returned from a C function **by value** (pointers to them
|
||||||
- **Function-like macros** and macros that are not a single number.
|
work, and so do unions as variables: `SDL_Event e`, `e.type`, `e.key.key`, `SDL_PollEvent(addr(e))`).
|
||||||
|
- **Function-like macros** (`#define MAX(a, b) ...`) and macros that make a struct (raylib's `RAYWHITE`).
|
||||||
|
Macros that are a number, a text or an expression of them (`(1u << 3)`, `((Uint64)1)`, `(A | B)`) work.
|
||||||
- `long double`, 128-bit integers.
|
- `long double`, 128-bit integers.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -1035,6 +1072,10 @@ library's second, so your own file of the same name wins.
|
||||||
| `time` | `now()`, `millis()` (a clock for measuring), `sleep(ms)`, `date(t)`, `local(t)`, `format(t, "%Y-%m-%d")`, `days_in_month` |
|
| `time` | `now()`, `millis()` (a clock for measuring), `sleep(ms)`, `date(t)`, `local(t)`, `format(t, "%Y-%m-%d")`, `days_in_month` |
|
||||||
| `proc` | `run(cmd)` (the exit code), `output(cmd)` (what it printed; an error if it failed), `env(name, fallback)`, `pid()`, `cwd()` |
|
| `proc` | `run(cmd)` (the exit code), `output(cmd)` (what it printed; an error if it failed), `env(name, fallback)`, `pid()`, `cwd()` |
|
||||||
| `json` | `parse(text)`, `stringify(v)`, `pretty(v)`, and the value type `Json` with `get`, `at`, `set`, `push`, `has`, `str_or`, `int_or` ... |
|
| `json` | `parse(text)`, `stringify(v)`, `pretty(v)`, and the value type `Json` with `get`, `at`, `set`, `push`, `has`, `str_or`, `int_or` ... |
|
||||||
|
| `fs` | `read_bytes(p)` / `write_bytes(p, data)` (`[]u8`, any bytes), `exists`, `is_dir`, `mkdir` (with the folders above), `list` (sorted names), `remove_dir`, `data_dir(app)` (a folder for the user's saves) |
|
||||||
|
|
||||||
|
`min(a, b, ...)`, `max(a, b, ...)`, `abs(x)` and `clamp(x, lo, hi)` work on any numbers without an import (a function of
|
||||||
|
your own with the same name wins).
|
||||||
|
|
||||||
```
|
```
|
||||||
import json
|
import json
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,19 @@ x += 1 // także -= *= /= %=
|
||||||
- Nazwy: litery ASCII, cyfry i `_`, bez cyfry na początku. Polskie litery tylko w tekstach w cudzysłowie.
|
- Nazwy: litery ASCII, cyfry i `_`, bez cyfry na początku. Polskie litery tylko w tekstach w cudzysłowie.
|
||||||
Nazwy typów (`int`, `u8`, …), funkcji wbudowanych i słowa kluczowe są zarezerwowane.
|
Nazwy typów (`int`, `u8`, …), funkcji wbudowanych i słowa kluczowe są zarezerwowane.
|
||||||
|
|
||||||
**Słowa kluczowe:** `fn return if else while for in break continue true false null import link struct defer`
|
**Słowa kluczowe:** `fn return if else while for in break continue true false null import link struct enum match defer or try const export`
|
||||||
|
|
||||||
|
### Stałe
|
||||||
|
|
||||||
|
```c
|
||||||
|
const SZEROKOSC = 640
|
||||||
|
const WYSOKOSC = SZEROKOSC / 2 // z innych stałych
|
||||||
|
const f32 GRAWITACJA = 9.8 // z typem
|
||||||
|
const TYTUL = "Moja gra"
|
||||||
|
```
|
||||||
|
|
||||||
|
Stałą piszesz na najwyższym poziomie pliku, obok funkcji, i nie da się jej zmienić. Składa się z liczb, tekstu,
|
||||||
|
`true`/`false`, znaków, innych stałych i operatorów; stała z modułu to `ksztalty.BOKI`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -316,6 +328,13 @@ Uwagi:
|
||||||
|
|
||||||
## 8. Sterowanie przebiegiem
|
## 8. Sterowanie przebiegiem
|
||||||
|
|
||||||
|
`if` może też dawać wartość; każda gałąź to jedna wartość, a `else` jest wymagane:
|
||||||
|
|
||||||
|
```c
|
||||||
|
opis := if wynik > 100 { "dużo" } else if wynik > 10 { "średnio" } else { "mało" }
|
||||||
|
f32 predkosc = if biegnie { 2.5 } else { 1.0 }
|
||||||
|
```
|
||||||
|
|
||||||
```c
|
```c
|
||||||
if x > 10 {
|
if x > 10 {
|
||||||
...
|
...
|
||||||
|
|
@ -487,7 +506,21 @@ s[0] = 'D' // zmiana znaku
|
||||||
| `s.ptr` | `ptr[char]` dla C (ważny, dopóki żyje `s`) |
|
| `s.ptr` | `ptr[char]` dla C (ważny, dopóki żyje `s`) |
|
||||||
|
|
||||||
`str` pamięta swoją długość, więc `.len` działa natychmiast. Zawsze kończy się zerem, więc
|
`str` pamięta swoją długość, więc `.len` działa natychmiast. Zawsze kończy się zerem, więc
|
||||||
przekazanie go do C jako `char*` działa.
|
przekazanie go do C jako `char*` działa. W drugą stronę: funkcja C, która zwraca `char *`, daje ci `str`
|
||||||
|
(kopia powstaje, gdy go zachowujesz), a `str(p)` czyta `ptr[char]` zdobyty inaczej.
|
||||||
|
|
||||||
|
Tekst w kilku liniach piszesz między `"""`. Znak nowej linii zaraz po otwarciu znika, a z każdej linii znika
|
||||||
|
wcięcie zamykających cudzysłowów, więc tekst może być wcięty razem z kodem:
|
||||||
|
|
||||||
|
```c
|
||||||
|
shader := """
|
||||||
|
#version 330
|
||||||
|
void main() { gl_Position = vec4(0.0); }
|
||||||
|
"""
|
||||||
|
```
|
||||||
|
|
||||||
|
Liczby jako tekst: `str(x)` to najkrótszy tekst, który czyta się z powrotem jako ta sama liczba (`0.1`,
|
||||||
|
`0.30000000000000004`, `1e+20`); `str(x, 2)` ma zawsze dwie cyfry po kropce (`3.14`).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -644,6 +677,8 @@ fn main() {
|
||||||
|
|
||||||
- Wszystkiego z modułu używasz z jego nazwą z przodu: `ksztalty.pole`, `ksztalty.Pudlo`.
|
- Wszystkiego z modułu używasz z jego nazwą z przodu: `ksztalty.pole`, `ksztalty.Pudlo`.
|
||||||
- Moduł nie ma `main`. Moduły mogą importować inne moduły.
|
- Moduł nie ma `main`. Moduły mogą importować inne moduły.
|
||||||
|
- Moduły w folderach: `import ui/przycisk` wczytuje `ui/przycisk.fch`, a używasz go jako `przycisk.rysuj()`.
|
||||||
|
- Inna nazwa: `import ui/przycisk as p` → `p.rysuj()`. Dwa importy nie mogą mieć tej samej nazwy.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -744,8 +779,10 @@ Oba działają bezpośrednio; `examples/opengl.fch` i `examples/vulkan.fch` to k
|
||||||
|
|
||||||
### Co jeszcze nie działa
|
### Co jeszcze nie działa
|
||||||
|
|
||||||
- **Unie** C przez wartość i struktury z **polami bitowymi** przez wartość (wskaźniki do nich działają).
|
- **Unie** C i struktury z **polami bitowymi** przekazywane do funkcji C albo zwracane z niej **przez wartość**
|
||||||
- **Makra-funkcje** i makra, które nie są pojedynczą liczbą.
|
(wskaźniki do nich działają, unie jako zmienne też: `SDL_Event e`, `e.type`, `e.key.key`, `SDL_PollEvent(addr(e))`).
|
||||||
|
- **Makra-funkcje** (`#define MAX(a, b) ...`) i makra, które tworzą strukturę (`RAYWHITE` z raylib).
|
||||||
|
Makra będące liczbą, tekstem albo wyrażeniem z nich (`(1u << 3)`, `((Uint64)1)`, `(A | B)`) działają.
|
||||||
- `long double`, liczby 128-bitowe.
|
- `long double`, liczby 128-bitowe.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -1039,6 +1076,10 @@ bibliotece — więc Twój własny plik o tej nazwie ma pierwszeństwo.
|
||||||
| `time` | `now()`, `millis()` (zegar do mierzenia), `sleep(ms)`, `date(t)`, `local(t)`, `format(t, "%Y-%m-%d")`, `days_in_month` |
|
| `time` | `now()`, `millis()` (zegar do mierzenia), `sleep(ms)`, `date(t)`, `local(t)`, `format(t, "%Y-%m-%d")`, `days_in_month` |
|
||||||
| `proc` | `run(cmd)` (kod wyjścia), `output(cmd)` (co wypisało; błąd, jeśli się nie udało), `env(nazwa, domyślna)`, `pid()`, `cwd()` |
|
| `proc` | `run(cmd)` (kod wyjścia), `output(cmd)` (co wypisało; błąd, jeśli się nie udało), `env(nazwa, domyślna)`, `pid()`, `cwd()` |
|
||||||
| `json` | `parse(tekst)`, `stringify(v)`, `pretty(v)` oraz typ wartości `Json` z `get`, `at`, `set`, `push`, `has`, `str_or`, `int_or` ... |
|
| `json` | `parse(tekst)`, `stringify(v)`, `pretty(v)` oraz typ wartości `Json` z `get`, `at`, `set`, `push`, `has`, `str_or`, `int_or` ... |
|
||||||
|
| `fs` | `read_bytes(p)` / `write_bytes(p, dane)` (`[]u8`, dowolne bajty), `exists`, `is_dir`, `mkdir` (z folderami wyżej), `list` (posortowane nazwy), `remove_dir`, `data_dir(app)` (folder na zapisy użytkownika) |
|
||||||
|
|
||||||
|
`min(a, b, ...)`, `max(a, b, ...)`, `abs(x)` i `clamp(x, od, do)` działają na dowolnych liczbach bez importu (twoja
|
||||||
|
własna funkcja o tej samej nazwie wygrywa).
|
||||||
|
|
||||||
```
|
```
|
||||||
import json
|
import json
|
||||||
|
|
|
||||||
|
|
@ -52,9 +52,10 @@ Jedna instrukcja na linijkę, bez średników, `{` w tej samej linijce, bez nawi
|
||||||
|---|---|
|
|---|---|
|
||||||
| `x := 5` | nowa zmienna, typ zgadnięty |
|
| `x := 5` | nowa zmienna, typ zgadnięty |
|
||||||
| `int x = 5` | nowa zmienna, typ podany |
|
| `int x = 5` | nowa zmienna, typ podany |
|
||||||
| `int x` | zero / `""` / `[]` / `null` / wartości domyślne struktury |
|
| `int x` | zero / `""` / `[]` / `null` / wartości domyślne struktury (też struktur w niej) |
|
||||||
| `x = 7` | przypisanie |
|
| `x = 7` | przypisanie |
|
||||||
| `x += 1` `-=` `*=` `/=` `%=` | zmiana |
|
| `x += 1` `-=` `*=` `/=` `%=` | zmiana |
|
||||||
|
| `const W = 640`, `const f32 G = 9.8` | stała (na najwyższym poziomie pliku; `ksztalty.W` z modułu) |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -63,10 +64,10 @@ Jedna instrukcja na linijkę, bez średników, `{` w tej samej linijce, bez nawi
|
||||||
| Typ | Przykład |
|
| Typ | Przykład |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `int` (= `i64`) | `42`, `-7`, `0xFF`, `1_000_000` |
|
| `int` (= `i64`) | `42`, `-7`, `0xFF`, `1_000_000` |
|
||||||
| `float` (= `f64`) | `3.14` |
|
| `float` (= `f64`) | `3.14`, `1e9`, `2.5e-3` |
|
||||||
| `bool` | `true` (prawda), `false` (fałsz) |
|
| `bool` | `true` (prawda), `false` (fałsz) |
|
||||||
| `char` | `'A'`, `'\n'` |
|
| `char` | `'A'`, `'\n'` |
|
||||||
| `str` | `"tekst\t\"w cudzysłowie\""` |
|
| `str` | `"tekst\t\"w cudzysłowie\""`, `"""` kilka linii `"""` (wcięcie zamykających cudzysłowów znika) |
|
||||||
| `i8 i16 i32 i64` | ze znakiem, z rozmiarem |
|
| `i8 i16 i32 i64` | ze znakiem, z rozmiarem |
|
||||||
| `u8 u16 u32 u64` | bez znaku, z rozmiarem |
|
| `u8 u16 u32 u64` | bez znaku, z rozmiarem |
|
||||||
| `f32 f64` | zmiennoprzecinkowe |
|
| `f32 f64` | zmiennoprzecinkowe |
|
||||||
|
|
@ -98,6 +99,7 @@ Znaki specjalne: `\n \t \r \0 \\ \" \'`.
|
||||||
|
|
||||||
```c
|
```c
|
||||||
if a > b { … } else if a == b { … } else { … }
|
if a > b { … } else if a == b { … } else { … }
|
||||||
|
x := if a > b { a } else { b } // jako wartość: jedna wartość na gałąź, else wymagane
|
||||||
while x > 0 { … }
|
while x > 0 { … }
|
||||||
for i in 0..10 { … } // 0 … 9
|
for i in 0..10 { … } // 0 … 9
|
||||||
for el in lista { … } // każdy element (albo znak str)
|
for el in lista { … } // każdy element (albo znak str)
|
||||||
|
|
@ -233,7 +235,7 @@ Funkcje wbudowane, które mogą się nie udać: `int(s)`, `float(s)`, `read_file
|
||||||
| `s.replace(a, b)` | każde a → b |
|
| `s.replace(a, b)` | każde a → b |
|
||||||
| `s.repeat(n)` | n razy |
|
| `s.repeat(n)` | n razy |
|
||||||
| `s.bytes()` | `[]u8` |
|
| `s.bytes()` | `[]u8` |
|
||||||
| `s.ptr` | `ptr[char]` (dla C) |
|
| `s.ptr` | `ptr[char]` (dla C; `str` trafia też do parametru `const char *` bez zmian) |
|
||||||
| `==` `!=` `<` `>` | porównanie |
|
| `==` `!=` `<` `>` | porównanie |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -249,7 +251,8 @@ Funkcje wbudowane, które mogą się nie udać: `int(s)`, `float(s)`, `read_file
|
||||||
| `u8(300)` | `44` (zostawia najniższe bity) |
|
| `u8(300)` | `44` (zostawia najniższe bity) |
|
||||||
| `char(66)` | `'B'` |
|
| `char(66)` | `'B'` |
|
||||||
| `bool(0)` | `false` |
|
| `bool(0)` | `false` |
|
||||||
| `str(42)`, `str(1.5)`, `str(true)`, `str('c')` | tekst |
|
| `str(42)`, `str(1.5)`, `str(true)`, `str('c')` | tekst (float: najkrótszy tekst, który jest tą samą liczbą) |
|
||||||
|
| `str(3.14159, 2)` | `"3.14"` (tyle cyfr po kropce) |
|
||||||
| `str([1, 2])`, `str(m)`, `str(punkt)` | ten sam tekst, który pokazuje `print` |
|
| `str([1, 2])`, `str(m)`, `str(punkt)` | ten sam tekst, który pokazuje `print` |
|
||||||
| `int("x") or 0`, `float(s) or 0.0` | liczba albo wartość zapasowa |
|
| `int("x") or 0`, `float(s) or 0.0` | liczba albo wartość zapasowa |
|
||||||
| `str(bajty)` | `[]u8` → tekst |
|
| `str(bajty)` | `[]u8` → tekst |
|
||||||
|
|
@ -272,7 +275,8 @@ Automatycznie tylko wtedy, gdy nic nie ginie: mniejsza → większa liczba, dowo
|
||||||
| `file_exists(sciezka)` | czy plik istnieje |
|
| `file_exists(sciezka)` | czy plik istnieje |
|
||||||
| `delete_file(sciezka)` | usuń plik |
|
| `delete_file(sciezka)` | usuń plik |
|
||||||
| `shell(polecenie)` | uruchom polecenie, jego kod wyjścia |
|
| `shell(polecenie)` | uruchom polecenie, jego kod wyjścia |
|
||||||
| `exit(kod)` | zakończ program od razu |
|
| `exit(kod)` | zakończ program od razu (kończy też blok `or { }`) |
|
||||||
|
| `min(a, b, …)`, `max(a, b, …)`, `abs(x)`, `clamp(x, od, do)` | dla dowolnych liczb (twoja funkcja o tej nazwie wygrywa) |
|
||||||
| `error(komunikat)` | `return error("…")` w funkcji `-> T!` |
|
| `error(komunikat)` | `return error("…")` w funkcji `-> T!` |
|
||||||
| `addr(x)` | wskaźnik na x; `addr(fn)` = callback dla C |
|
| `addr(x)` | wskaźnik na x; `addr(fn)` = callback dla C |
|
||||||
| `new(wartosc)` | wartość na stercie → `ptr[T]` |
|
| `new(wartosc)` | wartość na stercie → `ptr[T]` |
|
||||||
|
|
@ -310,6 +314,8 @@ import ksztalty // ksztalty.fch obok tego pliku (albo w FINCH_PATH)
|
||||||
ksztalty.pole(b) // jego funkcje
|
ksztalty.pole(b) // jego funkcje
|
||||||
ksztalty.Pudlo(2, 3) // jego struktury
|
ksztalty.Pudlo(2, 3) // jego struktury
|
||||||
ksztalty.Pudlo inne // w deklaracjach
|
ksztalty.Pudlo inne // w deklaracjach
|
||||||
|
import ui/przycisk // ui/przycisk.fch: przycisk.rysuj()
|
||||||
|
import ui/przycisk as p // inna nazwa: p.rysuj()
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -333,6 +339,10 @@ ksztalty.Pudlo inne // w deklaracjach
|
||||||
| `T *` | `ptr[T]` |
|
| `T *` | `ptr[T]` |
|
||||||
| `void *`, uchwyty | `ptr` |
|
| `void *`, uchwyty | `ptr` |
|
||||||
| `T x[N]` (w strukturze) | `[N]T` |
|
| `T x[N]` (w strukturze) | `[N]T` |
|
||||||
|
| `union U` | `U`: `U u`, `u.pole`, `U(pole: v)`, przez wskaźnik do C (nie przez wartość) |
|
||||||
|
| `#define N 4`, `"tekst"`, `(1u << 3)`, `((Uint64)2)` | stałe (bez makr-funkcji) |
|
||||||
|
|
||||||
|
Wynik `char *` z funkcji C to od razu `str`; struktury przez wartość działają na każdym systemie (System V, Windows x64, ARM64).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -396,6 +406,7 @@ s := Stos[int]() Stos[int] t Para[str, int]("wiek", 31) // ni
|
||||||
| `path` | `join(a, b)` `base(p)` `dir(p)` `ext(p)` `stem(p)` `parts(p)` `clean(p)` `is_abs(p)` |
|
| `path` | `join(a, b)` `base(p)` `dir(p)` `ext(p)` `stem(p)` `parts(p)` `clean(p)` `is_abs(p)` |
|
||||||
| `time` | `now()` `millis()` `sleep(ms)` `date(t)` `local(t)` `format(t, fmt)` `days_in_month(r, m)` |
|
| `time` | `now()` `millis()` `sleep(ms)` `date(t)` `local(t)` `format(t, fmt)` `days_in_month(r, m)` |
|
||||||
| `proc` | `run(cmd)` `output(cmd)` (błąd z jego wyjściem) `env(nazwa, domyślna)` `pid()` `cwd()` |
|
| `proc` | `run(cmd)` `output(cmd)` (błąd z jego wyjściem) `env(nazwa, domyślna)` `pid()` `cwd()` |
|
||||||
|
| `fs` | `read_bytes(p)` `write_bytes(p, dane)` `exists(p)` `is_dir(p)` `mkdir(p)` `list(folder)` `remove_dir(p)` `data_dir(app)` |
|
||||||
| `json` | `parse(tekst)` `stringify(v)` `pretty(v)` `new_text/number/bool/null/list/object` `v.get(k)` `v.at(i)` `v.set(k, x)` `v.push(x)` `v.has(k)` `v.str_or(d)` `v.int_or(d)` `v.float_or(d)` `v.bool_or(d)` |
|
| `json` | `parse(tekst)` `stringify(v)` `pretty(v)` `new_text/number/bool/null/list/object` `v.get(k)` `v.at(i)` `v.set(k, x)` `v.push(x)` `v.has(k)` `v.str_or(d)` `v.int_or(d)` `v.float_or(d)` `v.bool_or(d)` |
|
||||||
|
|
||||||
## Słowa kluczowe
|
## Słowa kluczowe
|
||||||
|
|
@ -416,5 +427,7 @@ s := Stos[int]() Stos[int] t Para[str, int]("wiek", 31) // ni
|
||||||
| `defer` | odłóż (na koniec bloku) |
|
| `defer` | odłóż (na koniec bloku) |
|
||||||
| `or` | albo (co zrobić przy porażce) |
|
| `or` | albo (co zrobić przy porażce) |
|
||||||
| `try` | spróbuj (porażkę przekaż dalej) |
|
| `try` | spróbuj (porażkę przekaż dalej) |
|
||||||
|
| `const` | stała |
|
||||||
|
| `export` | wystaw (funkcja dla programu w C) |
|
||||||
| `self` | sam (w metodzie: struktura, na której ją wywołano) |
|
| `self` | sam (w metodzie: struktura, na której ją wywołano) |
|
||||||
| `map` | mapa |
|
| `map` | mapa |
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
Install: copy to ~/.local/share/org.kde.syntax-highlighting/syntax/finch.xml
|
Install: copy to ~/.local/share/org.kde.syntax-highlighting/syntax/finch.xml
|
||||||
(or run editors/kate/install.sh), then restart Kate.
|
(or run editors/kate/install.sh), then restart Kate.
|
||||||
-->
|
-->
|
||||||
<language name="Finch" version="2" kateversion="5.0" section="Sources" extensions="*.fch"
|
<language name="Finch" version="3" kateversion="5.0" section="Sources" extensions="*.fch"
|
||||||
mimetype="text/x-finch" indenter="cstyle" author="The Finch authors" license="Apache-2.0">
|
mimetype="text/x-finch" indenter="cstyle" author="The Finch authors" license="Apache-2.0">
|
||||||
<highlighting>
|
<highlighting>
|
||||||
<list name="keywords">
|
<list name="keywords">
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
<item>struct</item>
|
<item>struct</item>
|
||||||
<item>enum</item>
|
<item>enum</item>
|
||||||
<item>export</item>
|
<item>export</item>
|
||||||
|
<item>const</item>
|
||||||
</list>
|
</list>
|
||||||
<list name="control">
|
<list name="control">
|
||||||
<item>if</item>
|
<item>if</item>
|
||||||
|
|
@ -79,6 +80,7 @@
|
||||||
<Detect2Chars char="/" char1="*" attribute="Comment" context="BlockComment" beginRegion="Comment"/>
|
<Detect2Chars char="/" char1="*" attribute="Comment" context="BlockComment" beginRegion="Comment"/>
|
||||||
<DetectChar char="{" attribute="Symbol" beginRegion="Brace"/>
|
<DetectChar char="{" attribute="Symbol" beginRegion="Brace"/>
|
||||||
<DetectChar char="}" attribute="Symbol" endRegion="Brace"/>
|
<DetectChar char="}" attribute="Symbol" endRegion="Brace"/>
|
||||||
|
<StringDetect String=""""" attribute="String" context="LongString" beginRegion="LongString"/>
|
||||||
<DetectChar char=""" attribute="String" context="String"/>
|
<DetectChar char=""" attribute="String" context="String"/>
|
||||||
<DetectChar char="'" attribute="Char" context="Char"/>
|
<DetectChar char="'" attribute="Char" context="Char"/>
|
||||||
|
|
||||||
|
|
@ -91,7 +93,8 @@
|
||||||
<keyword String="builtins" attribute="Built-in"/>
|
<keyword String="builtins" attribute="Built-in"/>
|
||||||
|
|
||||||
<RegExpr String="\b0[xX][0-9a-fA-F_]+\b" attribute="Hex"/>
|
<RegExpr String="\b0[xX][0-9a-fA-F_]+\b" attribute="Hex"/>
|
||||||
<RegExpr String="\b[0-9][0-9_]*\.[0-9][0-9_]*([eE][+-]?[0-9]+)?\b" attribute="Float"/>
|
<RegExpr String="\b[0-9][0-9_]*(\.[0-9][0-9_]*)?[eE][+-]?[0-9]+\b" attribute="Float"/>
|
||||||
|
<RegExpr String="\b[0-9][0-9_]*\.[0-9][0-9_]*\b" attribute="Float"/>
|
||||||
<RegExpr String="\b[0-9][0-9_]*\b" attribute="Decimal"/>
|
<RegExpr String="\b[0-9][0-9_]*\b" attribute="Decimal"/>
|
||||||
|
|
||||||
<!-- a call: name( ; method or field after a dot -->
|
<!-- a call: name( ; method or field after a dot -->
|
||||||
|
|
@ -136,6 +139,11 @@
|
||||||
<DetectChar char=""" attribute="String" context="#pop"/>
|
<DetectChar char=""" attribute="String" context="#pop"/>
|
||||||
</context>
|
</context>
|
||||||
|
|
||||||
|
<context name="LongString" attribute="String" lineEndContext="#stay">
|
||||||
|
<RegExpr String="\\[ntr0\\"']" attribute="Escape"/>
|
||||||
|
<StringDetect String=""""" attribute="String" context="#pop" endRegion="LongString"/>
|
||||||
|
</context>
|
||||||
|
|
||||||
<context name="Char" attribute="Char" lineEndContext="#pop">
|
<context name="Char" attribute="Char" lineEndContext="#pop">
|
||||||
<RegExpr String="\\[ntr0\\"']" attribute="Escape"/>
|
<RegExpr String="\\[ntr0\\"']" attribute="Escape"/>
|
||||||
<DetectChar char="'" attribute="Char" context="#pop"/>
|
<DetectChar char="'" attribute="Char" context="#pop"/>
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,9 @@
|
||||||
{
|
{
|
||||||
"include": "#comments"
|
"include": "#comments"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"include": "#longstrings"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"include": "#strings"
|
"include": "#strings"
|
||||||
},
|
},
|
||||||
|
|
@ -125,7 +128,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "storage.type.struct.finch",
|
"name": "storage.type.struct.finch",
|
||||||
"match": "\\b(struct|enum)\\b"
|
"match": "\\b(struct|enum|const)\\b"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "storage.modifier.finch",
|
"name": "storage.modifier.finch",
|
||||||
|
|
@ -243,13 +246,24 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "constant.numeric.float.finch",
|
"name": "constant.numeric.float.finch",
|
||||||
"match": "\\b\\d[\\d_]*\\.\\d[\\d_]*\\b"
|
"match": "\\b\\d[\\d_]*(\\.\\d[\\d_]*([eE][+-]?\\d+)?|[eE][+-]?\\d+)\\b"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "constant.numeric.integer.finch",
|
"name": "constant.numeric.integer.finch",
|
||||||
"match": "\\b\\d[\\d_]*\\b"
|
"match": "\\b\\d[\\d_]*\\b"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"longstrings": {
|
||||||
|
"name": "string.quoted.triple.finch",
|
||||||
|
"begin": "\"\"\"",
|
||||||
|
"end": "\"\"\"",
|
||||||
|
"patterns": [
|
||||||
|
{
|
||||||
|
"name": "constant.character.escape.finch",
|
||||||
|
"match": "\\\\[ntr0\\\\\"']"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue