# Tekt **Repository Path**: qwe12345678/Tekt ## Basic Information - **Project Name**: Tekt - **Description**: No description available - **Primary Language**: Haskell - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-02-13 - **Last Updated**: 2026-03-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Tekt Programming Language v1.1 > v1.1 目标:在保留 v1.0 风格的基础上,消除语法/EBNF/示例不一致点,补齐指针/可见性/history/go/宏等缺口,降低 `{}` 歧义,使规范更可实现。 --- ## Table of Contents 1. [Philosophy & Overview](#1-philosophy--overview) 2. [Lexical Structure](#2-lexical-structure) 3. [Layout & Indentation](#3-layout--indentation) 4. [Literals](#4-literals) 5. [Operators & Precedence](#5-operators--precedence) 6. [Type System](#6-type-system) 7. [Declarations & Visibility](#7-declarations--visibility) 8. [Functions](#8-functions) 9. [Structs, Enums, Interfaces, Impl](#9-structs-enums-interfaces-impl) 10. [Statements](#10-statements) 11. [Expressions](#11-expressions) 12. [Pattern Matching](#12-pattern-matching) 13. [Error Handling](#13-error-handling) 14. [Concurrency](#14-concurrency) 15. [Reactive Streams (Flux)](#15-reactive-streams-flux) 16. [Memory, RAII & Lifecycle](#16-memory-raii--lifecycle) 17. [Metaprogramming & Compile-Time Reflection](#17-metaprogramming--compile-time-reflection) 18. [Contracts & Constraints](#18-contracts--constraints) 19. [Testing & Documentation](#19-testing--documentation) 20. [Modules](#20-modules) 21. [Adaptive Execution (Evolve)](#21-adaptive-execution-evolve) 22. [Interoperability](#22-interoperability) 23. [Complete Formal Grammar (EBNF)](#23-complete-formal-grammar-ebnf) 24. [Tooling](#24-tooling) 25. [Examples](#25-examples) --- ## 1. Philosophy & Overview **Tekt** is a systems-capable, general-purpose language designed around: 1. **Clarity over cleverness** — constructs have one obvious meaning. 2. **Expressions first** — `if/match/try` are expressions; loops are expressions whose value is `unit` by default. 3. **Visible effects** — `throws`, `async`, `pure`, `unsafe` are explicit. 4. **Time-aware** — first-class reactive streams (`flux`) + history tracking variables. 5. **Adaptive execution** — `@evolve` enables multiple implementations selected by runtime metrics. ### Key Decisions (v1.1) - **No implicit conversions** (casts are explicit via `as`). - **No null**: use `T?` (optional) with `nil`. - **Result type**: `T ! E` (success or error). - **Interfaces are structural**, but interface *types* use `dyn Interface` for erased/boxed values. - **Braces ambiguity reduced**: - `{ ... }` is a **block** unless it contains a `:` token at top level. - Map literal requires at least one `:` entry; **empty map must be written `{:}`**. --- ## 2. Lexical Structure ### 2.1 Encoding - UTF-8, BOM ignored. - Shebang allowed: first line `#!...` treated as comment. ### 2.2 Whitespace & Indentation - Spaces or tabs. - Mixed indentation in one file is a compile error. ### 2.3 Comments ```tekt // line /* block (nestable) */ /// doc ``` ### 2.4 Identifiers - Unicode letters + digits + `_`. - Keywords can be used if escaped: `` `type` ``. ### 2.5 Keywords (Reserved) ``` fn struct enum interface impl type import as from where mod pub const let mut use defer return break continue yield if then else match when try catch throw throws wrap guard require ensure async await spawn go chan select timeout pure unsafe macro comptime self true false nil and or not is transient ephemeral permanent map set dyn ignore ``` > Notes: > - `wrap` is reserved for `? wrap ...`. > - `ignore` is reserved for `use ... else ignore`. ### 2.6 Automatic Semicolons (Newline Rules) - Inside `() [] {} <>` newlines are whitespace. - Outside bracket context, newline terminates a statement unless the line ends with a continuation token: ``` = + - * / % | & ^ < > . ? : , => -> |> ~> && || .. ..= ** as ``` --- ## 3. Layout & Indentation Both indentation blocks and brace blocks exist and are equivalent. ```ebnf Suite = IndentSuite | BraceSuite ; IndentSuite = NEWLINE INDENT { Stmt NEWLINE } DEDENT ; BraceSuite = "{" { Stmt (";" | NEWLINE) } "}" ; ``` --- ## 4. Literals ### 4.1 Numbers - `0x`, `0o`, `0b`, `_` separators. - Optional suffix: `42i64`, `1.0f32`. ### 4.2 Bool & Nil - `true`, `false`, `nil` (`nil` only inhabits optional `T?`) ### 4.3 Strings - `"..."` with escapes and interpolation `{ Expr }` - `r"..."` raw - `"""..."""` multiline (strips common indentation) ### 4.4 Duration `500ms`, `2h`, `30s`, units: `ns us ms s min h d` ### 4.5 Rune `'a'`, `'\n'`, `'\u{1F600}'` --- ## 5. Operators & Precedence ### 5.1 Precedence (high → low) 1. Postfix: `f()` `a[i]` `a.b` `a?.b` `a?` `a!` `a@1` `a@@key` `f` 2. `**` (right) 3. Unary: `+ - ! not await * &` 4. `as` (left) — cast binds tighter than comparisons 5. `* / %` 6. `+ -` 7. `<< >>` 8. `& ^ |` (bitwise) 9. `== != < <= > >= is` 10. `.. ..=` (range) 11. `??` 12. `&& / and` 13. `|| / or` 14. `|>` `~>` 15. Assign: `= += -= *= /= %= ??= &&= ||= <<= >>= &= |= ^=` (right) ### 5.2 Special Postfix Operators | Operator | Meaning | |---|---| | `expr?` | propagate error from `throws` function (sugar for early return) | | `expr? wrap F` | propagate after mapping/wrapping error via `F(err)` | | `expr!` | force unwrap optional/result; panics on `nil`/error | | `a?.b` | optional chaining; yields `nil` if `a` is `nil` | | `x@N` | history access (no whitespace): previous value N steps back | | `flux@@key` | observe/snapshot flux with a key/strategy expression | --- ## 6. Type System ### 6.1 Type Syntax (core) - Optional: `T?` - Result: `T ! E` - Union/intersection types are supported in type position: - `A | B` (union) - `A & B` (intersection) ### 6.2 Primitive Types `int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 float32 float64 bool string rune byte unit never` ### 6.3 Pointer & Reference Types - Safe references: `&T`, `&mut T` - Raw pointers (unsafe): `*T`, `*mut T` ### 6.4 Interface Types (`dyn`) Interfaces are structural for conformance, but **storing an interface as a value** uses `dyn`: - `dyn Display` is an erased, boxed interface value (fat pointer). - `Display` in type position is sugar for `dyn Display` in v1.1 (configurable by compiler flag; recommended: keep sugar enabled). ### 6.5 Type Constructors - `[]T` slice - `[N]T` array - `map[K]V` - `set[T]` - `(A, B, ...)` tuple - `fn(...) -> T effects` - `chan` - `flux` ### 6.6 Generic Constraints `T: A + B` means `T` must satisfy interfaces `A` and `B`. ### 6.7 Optional Construction - `nil` is none - `some(expr)` constructs a `T?` (builtin) Pattern matching uses `nil` and `some(x)`. --- ## 7. Declarations & Visibility ### 7.1 Visibility - `pub` public - `pub(mod)` module-visible - `pub(parent)` parent module-visible - default: file-private Visibility can appear on top-level declarations and struct fields. ### 7.2 Imports ```tekt import std/collections { HashMap, BTreeSet } import net/http as http import "github.com/user/lib" ``` ### 7.3 Const & Var ```tekt const MAX = 1024 let x = 42 mut y: int = 0 ``` ### 7.4 Attributes ```tekt @deprecated("Use new_function") @inline pub fn old() -> int => 1 ``` --- ## 8. Functions ### 8.1 Effects - `async`: allows `await` - `throws(E?)`: can throw errors (default error type is `dyn Error`) - `pure`: no side effects / deterministic (as defined by compiler) - `unsafe`: allows raw pointer deref, FFI calls, etc. ### 8.2 Declaration ```tekt fn add(a: int, b: int) -> int => a + b fn read(path: string) -> string throws(IOError) fs.read_file(path)? fn main() throws async let v = await http.get("...")? println(v) ``` ### 8.3 Lambdas ```tekt let inc = x => x + 1 let add2 = (a, b) => a + b ``` ### 8.4 Implicit lambda `$0, $1` ```tekt items.filter($0 > 10) pairs.sort_by($0.age - $1.age) ``` ### 8.5 Partial application `_` ```tekt let add1 = add(_, 1) ``` --- ## 9. Structs, Enums, Interfaces, Impl ### 9.1 Struct ```tekt pub struct User pub name: string mut age: int = 0 ``` Struct literal and spread: ```tekt let u = User { name: "A", age: 10 } let u2 = User { ...u, age: 11 } ``` ### 9.2 Enum (ADT) ```tekt enum Result Ok(T) Err(E) ``` ### 9.3 Interface (structural) ```tekt interface Error fn message(self) -> string fn source(self) -> (dyn Error)? ``` ### 9.4 Impl ```tekt impl Error for IOError fn message(self) -> string => self.message fn source(self) -> (dyn Error)? => nil ``` --- ## 10. Statements Includes: - `let/mut/const` - assignment - `return/throw/break/continue/yield` - `defer` - `use` - `guard` - `require/ensure` - control: `if/for/match/try/select` - `spawn/go` - declarations ### 10.1 `use` (RAII) `use` requires the value implements `Drop`: ```tekt interface Drop fn drop(self) -> unit ``` ```tekt use f = fs.open(path)? else throw defer println("leaving scope") ``` `use ... else`: - `else throw`: propagate current error - `else ignore`: treat as `unit` - `else Expr`: provide fallback value ### 10.2 `defer` Supports expression or suite: ```tekt defer file.close() defer log("cleanup") cleanup() ``` ### 10.3 `guard` ```tekt guard x > 0 else return nil guard let u = find_user(id) else return nil ``` --- ## 11. Expressions ### 11.1 If / If-let ```tekt let v = if x > 0 then 1 else -1 if let some(u) = maybe_user println(u.name) else println("none") ``` ### 11.2 Match ```tekt match v 0 => "zero" n when n > 0 => "pos" _ => "neg" ``` ### 11.3 For `for` is an expression whose value is `unit` unless used inside a generator (`yield`). ```tekt for i in 0..10 println(i) ``` ### 11.4 Try/Catch (expression) ```tekt let cfg = try load() catch default_cfg() ``` ### 11.5 Map/Set/List literals ```tekt let a = [1, 2, 3] let m = {"a": 1, "b": 2} let empty_map: map[string]int = {:} let s = set[1, 2, 3] ``` --- ## 12. Pattern Matching Patterns appear in `let`, params, `match`, `if let`, `guard let`, `for`. Optional patterns: - `nil` - `some(x)` Pinned match: - `^name` matches existing binding. --- ## 13. Error Handling - `throws(E)` declares throwable effect. - `throw expr` throws. - `expr?` propagates error. - `try ... catch ...` handles. Error mapping: ```tekt read_file(path)? wrap AppError.io ``` --- ## 14. Concurrency ### 14.1 `spawn` and structured concurrency - `spawn expr` starts a child task and returns `Task`. - All child tasks spawned in a scope are joined when the scope exits **unless detached** (not in v1.1). - If a child throws and is awaited/joined, the error is rethrown in the parent. ```tekt fn work() -> int throws async 1 fn main() throws async let t = spawn work() let v = await t ``` ### 14.2 `go` `go expr` is sugar for `spawn expr` but discards the handle (fire-and-forget within scope rules). ```tekt go log_event(e) ``` ### 14.3 Channels & select ```tekt let ch = chan(buffer: 10) ch.send(1) let v = ch.recv() select msg from ch => handle(msg) timeout 1s => on_timeout() _ => idle() ``` --- ## 15. Reactive Streams (Flux) `flux` is a stream over time. - observe: `stream@@key` - map/filter/debounce/etc in `std/flux` --- ## 16. Memory, RAII & Lifecycle Lifecycle hints (no semantic guarantee, only optimization hints): - `transient` - `ephemeral` - `permanent` ```tekt transient temp = 1 + 2 ephemeral buf = make_buffer() permanent cache = build_cache() ``` ### History variables ```tekt @history(depth: 5) mut counter = 0 counter = 1 counter = 2 let prev = counter@1 // 1 ``` Rules: - `x@N` has **no whitespace** and only valid if `x` is a history variable. --- ## 17. Metaprogramming & Compile-Time Reflection ### 17.1 `comptime` `comptime { ... }` runs at compile time. ### 17.2 Macros (quasi-quote & splice) Macro bodies are normal Tekt code plus: - `$(Expr)` splice expression into AST - `$(for ... ) ... $(end)` repetition (compile-time) (Exact AST API is in `std/reflect`.) --- ## 18. Contracts & Constraints - `require cond, "msg"` - `ensure cond, "msg"` (where `result` binds to return value in scope) --- ## 19. Testing & Documentation ```tekt test "addition" assert add(2, 3) == 5 ``` --- ## 20. Modules ```tekt mod math.vector pub fn dot(a: Vec3, b: Vec3) -> float64 a.x*b.x + a.y*b.y + a.z*b.z ``` --- ## 21. Adaptive Execution (Evolve) `@evolve` enables `case` blocks inside a function body. ```tekt @evolve(metric: "latency", mode: "ab_test") fn sort_items(items: []int) -> []int case quick quick_sort(items) case merge merge_sort(items) ``` --- ## 22. Interoperability ### 22.1 C FFI ```tekt @extern("C") unsafe fn puts(s: *byte) -> int ``` Raw pointer deref requires `unsafe`. --- ## 23. Complete Formal Grammar (EBNF) > 说明:EBNF 只覆盖“语法结构”;缩进插入(INDENT/DEDENT)、自动分号插入属于词法/布局规则,不在 EBNF 中完全表达。 ```ebnf (* ========= FILE ========= *) File = { NEWLINE } { ImportDecl NEWLINE } { TopItem NEWLINE } EOF ; TopItem = Attr* ( Decl | Stmt ) ; (* ========= ATTRIBUTES & VISIBILITY ========= *) Attr = "@" Identifier [ "(" AttrArgs ")" ] ; AttrArgs = AttrArg { "," AttrArg } [ "," ] ; AttrArg = Expr | Identifier ":" Expr ; Vis = "pub" [ "(" ("mod" | "parent") ")" ] ; (* ========= IMPORTS ========= *) ImportDecl = "import" ImportSpec ; ImportSpec = ImportPath [ "as" Identifier ] | ImportPath "{" ImportList "}" ; ImportPath = Identifier { "/" Identifier } | StringLit ; ImportList = Identifier { "," Identifier } [ "," ] ; (* ========= DECLARATIONS ========= *) Decl = FnDecl | StructDecl | EnumDecl | InterfaceDecl | ImplDecl | TypeAliasDecl | ConstDecl | VarDecl | ModDecl | MacroDecl | TestDecl | ExampleDecl ; TypeAliasDecl = "type" Identifier GenericParams? "=" Type ; ConstDecl = Vis? "const" Identifier ( ":" Type )? "=" Expr ; VarDecl = Vis? ( "let" | "mut" | Lifecycle ) Pattern ( ":" Type )? "=" Expr ; Lifecycle = "transient" | "ephemeral" | "permanent" ; ModDecl = "mod" QualIdent ; (* ========= FUNCTIONS ========= *) FnDecl = Vis? "fn" Identifier GenericParams? "(" ParamList? ")" ( "->" Type )? EffectList? ( "=>" Expr | Suite ) ; GenericParams = "<" GenericParam { "," GenericParam } [ "," ] ">" ; GenericParam = Identifier ( ":" Constraint )? ( "=" Type )? ; Constraint = NamedType { "+" NamedType } ; ParamList = Param { "," Param } [ "," ] ; Param = Identifier ":" Type ( "=" Expr )? | "self" ( ":" Type )? | Identifier ":" Type "..." ; EffectList = Effect { Effect } ; Effect = "throws" [ "(" Type ")" ] | "async" | "pure" | "unsafe" ; (* ========= STRUCTS ========= *) StructDecl = Vis? "struct" Identifier GenericParams? Suite ; FieldDecl = Attr* Vis? [ "mut" ] Identifier ":" Type [ "=" Expr ] ; (* ========= ENUMS ========= *) EnumDecl = Vis? "enum" Identifier GenericParams? [ "(" Type ")" ] Suite ; EnumVariant = Attr* Identifier [ "(" EnumFieldList? ")" ] [ "=" Expr ] ; EnumFieldList = EnumField { "," EnumField } [ "," ] ; EnumField = [ Identifier ":" ] Type ; (* ========= INTERFACES ========= *) InterfaceDecl = Vis? "interface" Identifier GenericParams? [ ":" NamedType { "+" NamedType } ] Suite ; (* ========= IMPL ========= *) ImplDecl = "impl" Type [ "for" Type ] [ "where" WhereClause ] Suite ; WhereClause = WhereItem { "," WhereItem } ; WhereItem = Identifier ":" Constraint ; (* ========= MACROS ========= *) MacroDecl = Vis? "macro" Identifier "(" ParamList? ")" Suite ; (* ========= TEST/EXAMPLE ========= *) TestDecl = Attr* "test" StringLit Suite ; ExampleDecl = Attr* "example" [ StringLit ] Suite ; (* ========= TYPES ========= *) Type = ResultType ; ResultType = UnionType [ "!" UnionType ] ; (* T ! E *) UnionType = InterType { "|" InterType } ; InterType = PostfixType { "&" PostfixType } ; PostfixType = PrimaryType [ "?" ] ; PrimaryType = NamedType | SliceType | ArrayType | MapType | SetType | TupleType | FuncType | ChanType | FluxType | RefType | PtrType | DynType | ParenType ; NamedType = QualIdent TypeArgs? ; QualIdent = Identifier { "." Identifier } ; TypeArgs = "<" Type { "," Type } [ "," ] ">" ; SliceType = "[" "]" Type ; ArrayType = "[" IntLit "]" Type ; MapType = "map" "[" Type "]" Type ; SetType = "set" "[" Type "]" ; TupleType = "(" Type "," Type { "," Type } [ "," ] ")" ; FuncType = "fn" "(" ParamTypeList? ")" ( "->" Type )? EffectList? ; ParamTypeList = Type { "," Type } [ "," ] ; ChanType = "chan" "<" Type ">" ; FluxType = "flux" "<" Type ">" ; RefType = "&" [ "mut" ] Type ; PtrType = "*" [ "mut" ] Type ; DynType = "dyn" NamedType ; ParenType = "(" Type ")" ; (* ========= STATEMENTS ========= *) Stmt = LabeledStmt | SimpleStmt | BlockStmt ; LabeledStmt = Identifier ":" ( ForStmt | SelectStmt ) ; SimpleStmt = VarDecl | AssignStmt | ExprStmt | ReturnStmt | ThrowStmt | BreakStmt | ContinueStmt | YieldStmt | DeferStmt | UseStmt | GuardStmt | RequireStmt | EnsureStmt | SpawnStmt | GoStmt ; AssignStmt = LValue AssignOp Expr ; AssignOp = "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "&&=" | "||=" | "??=" | "<<=" | ">>=" | "&=" | "|=" | "^=" ; LValue = Identifier | LValue "." Identifier | LValue "[" Expr "]" | "(" LValue { "," LValue } ")" ; ReturnStmt = "return" Expr? ; ThrowStmt = "throw" Expr ; BreakStmt = "break" Identifier? ; ContinueStmt= "continue" Identifier? ; YieldStmt = "yield" Expr ; DeferStmt = "defer" ( Expr | Suite ) ; SpawnStmt = "spawn" Expr ; GoStmt = "go" Expr ; UseStmt = "use" Pattern ( ":" Type )? "=" Expr ( "else" UseElse )? ; UseElse = "ignore" | "throw" | Expr ; GuardStmt = "guard" ( Expr | "let" Pattern "=" Expr ) "else" ( SimpleStmt | Suite ) ; RequireStmt = "require" Expr ( "," Expr )? ; EnsureStmt = "ensure" Expr ( "," Expr )? ; BlockStmt = IfExpr | ForStmt | MatchExpr | TryExpr | SelectStmt | Decl ; ForStmt = "for" ForHead? Suite ; ForHead = Pattern "in" Expr | Pattern "," Pattern "in" Expr ; SelectStmt = "select" Suite ; (* Arms are parsed as statements inside Suite; implementor enforces arm forms *) ExprStmt = Expr ; (* ========= EXPRESSIONS ========= *) Expr = IfExpr ; IfExpr = "if" Expr "then" Expr "else" Expr | "if" Expr Suite ( "else" "if" Expr Suite )* ( "else" Suite )? | IfLetExpr | MatchExpr ; IfLetExpr = "if" "let" Pattern "=" Expr Suite ( "else" Suite )? ; MatchExpr = "match" Expr Suite | TryExpr ; TryExpr = "try" ( Expr | Suite ) CatchClause+ ; CatchClause = "catch" Pattern? ( "=>" Expr | Suite ) ; (* Pipe / compose / logic / arithmetic with casts *) PipeExpr = ComposeExpr { "|>" ComposeExpr } ; ComposeExpr = LogicOrExpr { "~>" LogicOrExpr } ; LogicOrExpr = LogicAndExpr { ( "||" | "or" ) LogicAndExpr } ; LogicAndExpr= CoalesceExpr { ( "&&" | "and" ) CoalesceExpr } ; CoalesceExpr= CompareExpr { "??" CompareExpr } ; CompareExpr = RangeExpr { CompareOp RangeExpr } ; CompareOp = "==" | "!=" | "<" | "<=" | ">" | ">=" | "is" ; RangeExpr = CastExpr [ ( ".." | "..=" ) CastExpr ] ; CastExpr = BitOrExpr { "as" Type } ; BitOrExpr = BitXorExpr { "|" BitXorExpr } ; BitXorExpr = BitAndExpr { "^" BitAndExpr } ; BitAndExpr = ShiftExpr { "&" ShiftExpr } ; ShiftExpr = AddExpr { ( "<<" | ">>" ) AddExpr } ; AddExpr = MulExpr { ( "+" | "-" ) MulExpr } ; MulExpr = PowExpr { ( "*" | "/" | "%" ) PowExpr } ; PowExpr = UnaryExpr ( "**" PowExpr )? ; UnaryExpr = ( "+" | "-" | "!" | "not" | "await" | "*" | "&" [ "mut" ] ) UnaryExpr | PostfixExpr ; PostfixExpr = PrimaryExpr { PostfixOp } ; PostfixOp = CallOp | IndexOp | FieldOp | OptChainOp | ErrorPropOp | ForceUnwrapOp | TypeArgOp | ObserveOp | HistoryOp ; CallOp = "(" ArgList? ")" ; ArgList = Arg { "," Arg } [ "," ] ; Arg = ( Identifier ":" )? Expr | "..." Expr ; IndexOp = "[" Expr "]" ; FieldOp = "." Identifier ; OptChainOp = "?." Identifier ; ErrorPropOp = "?" [ "wrap" Expr ] ; ForceUnwrapOp = "!" ; TypeArgOp = "<" Type { "," Type } [ "," ] ">" ; ObserveOp = "@@" Expr ; (* postfix with argument *) HistoryOp = "@" IntLit ; (* no-whitespace in concrete syntax *) PrimaryExpr = Identifier | Literal | ParenExpr | ListLit | MapLit | SetLit | StructLit | LambdaExpr | SpawnExpr | ImplicitParam | "_" ; ParenExpr = "(" Expr ")" | "(" Expr "," Expr { "," Expr } [ "," ] ")" ; Literal = IntLit | FloatLit | StringLit | RawStringLit | MultiStringLit | RuneLit | DurationLit | "true" | "false" | "nil" ; ListLit = "[" ExprList? "]" ; ExprList = Expr { "," Expr } [ "," ] ; MapLit = "{" MapBody "}" ; MapBody = ":" (* empty map: {:} *) | MapEntry { "," MapEntry } [ "," ] ; MapEntry = Expr ":" Expr ; SetLit = "set" "[" ExprList? "]" ; StructLit = NamedType "{" StructInitList? "}" ; StructInitList = StructInitItem { "," StructInitItem } [ "," ] ; StructInitItem = Identifier ":" Expr | "..." Expr ; LambdaExpr = Identifier "=>" Expr | "(" ParamNames? ")" "=>" Expr | "fn" GenericParams? "(" ParamList? ")" ( "->" Type )? EffectList? Suite ; ParamNames = Identifier { "," Identifier } ; ImplicitParam = "$" DecLit ; SpawnExpr = "spawn" Expr ; (* ========= PATTERNS ========= *) Pattern = "_" | Identifier | Literal | TuplePattern | SlicePattern | StructPattern | EnumPattern | RangePattern | OrPattern | TypePattern | PinnedPattern | SomePattern ; SomePattern = "some" "(" Pattern ")" ; TuplePattern= "(" Pattern ( "," Pattern )+ [ "," ] ")" ; SlicePattern= "[" ( Pattern { "," Pattern } )? ( "," "..." Identifier? )? "]" ; StructPattern = Identifier "{" StructPatField { "," StructPatField } [ "," ] "}" ; StructPatField= Identifier ( ":" Pattern )? ; EnumPattern = Identifier [ "(" PatternList? ")" ] ; PatternList = Pattern { "," Pattern } [ "," ] ; RangePattern= Expr ( ".." | "..=" ) Expr ; OrPattern = Pattern "|" Pattern ; TypePattern = Identifier "is" Type ; PinnedPattern = "^" Identifier ; (* ========= LAYOUT ========= *) Suite = IndentSuite | BraceSuite ; IndentSuite = NEWLINE INDENT { Stmt NEWLINE } DEDENT ; BraceSuite = "{" { Stmt ( ";" | NEWLINE ) } "}" ; ``` --- ## 24. Tooling ```bash tekt build tekt run tekt test tekt bench tekt fmt tekt check tekt doc ``` --- ## 25. Examples ### 25.1 Hello ```tekt fn main() println("Hello, Tekt!") ``` ### 25.2 Optional + match ```tekt fn find(id: int) -> string? if id == 1 then some("admin") else nil fn main() let u = find(1) match u some(name) => println(name) nil => println("none") ``` ### 25.3 Empty map literal ```tekt let m1 = {"a": 1} let m2: map[string]int = {:} ``` ### 25.4 Concurrency ```tekt fn work(x: int) -> int throws async x + 1 fn main() throws async let t = spawn work(41) println(await t) ``` 14. Concurrency (续) 14.4 Task API 与取消语义 Tekt 采用结构化并发 (Structured Concurrency)。每一个由 spawn 创建的 Task 都绑定到其创建时的作用域(Scope)。 Task 核心接口 在 std/task 中定义: interface Task fn await(self) -> T throws // 等待结束,若任务抛出异常则重传 fn cancel(self) // 触发取消请求 fn is_cancelled(self) -> bool // 检查是否已收到取消请求 fn is_completed(self) -> bool // 检查是否运行结束 取消传播规则 * 协同式取消:Task.cancel() 仅设置取消标志。任务体应通过 Task.check_cancellation() 或在执行 await / sleep / chan.recv 等阻塞操作时由运行时自动触发 CancellationError。 * 父子传播:当一个作用域退出(因为完成、异常或被取消)时,所有在该作用域内 spawn 且未 detach 的任务都会自动接收到取消信号。 * 结果处理:被取消的任务在 await 时会抛出 CancellationError。 14.5 select 与 Task/Chan 交互 select 是 Tekt 处理异步事件的核心多路复用器,支持同时监听通道和任务状态。 select msg from ch => process(msg) val from spawn work() => println("Task finished: {val}") timeout 1s => log("operation timed out") * Task 交互:当 select 作用于 Task 时,它在任务完成(成功或抛出异常)时就绪。 * 公平性:若多个分支同时就绪,运行时将伪随机选择一个分支执行,防止通道饥饿。 17. Metaprogramming & Reflection (续) 17.3 std/reflect 最小 AST 接口 宏在编译期接收的是 TokenStream 或 AST 节点,并通过 std/reflect 提供的枚举进行操作。 enum AstNode Identifier(string) Literal(Lit) Expr(ExprKind) Stmt(StmtKind) Type(TypeKind) Block([]AstNode) interface MacroContext fn error(self, node: AstNode, msg: string) -> never fn fresh_id(self, prefix: string) -> string // 生成唯一标识符(Hygiene) 17.4 $(...) 允许拼接的节点集合 在 macro 内部,使用 $() 将变量注入回生成的代码。支持以下插值: * $(ident): 注入标识符(作为变量名、函数名等)。 * $(expr): 注入完整的表达式节点。 * $(stmt): 注入语句。 * $(ty): 注入类型定义。 * $(...)* 或 $(...)+: 注入重复序列(配合 for 宏循环)。 示例:自动生成 Getter macro gen_getter(name: Ident, ty: Type) quote pub fn get_$(name)(self) -> $(ty) => self.$(name) end 17.5 卫生 (Hygiene) 规则 Tekt 宏默认是 完全卫生 (Fully Hygienic) 的: * 定义域隔离:在宏内部定义的局部变量会被运行时自动重命名(例如 x 变为 x_123),以防污染宏调用处的变量空间。 * 符号查找:宏内引用的外部函数/类型在其定义处的作用域进行解析,而不是在调用处。 * 显式逃逸:如果宏需要操作调用处的变量(非卫生),必须使用 std/reflect 中的 raw_ident 或在插值时声明。 23. EBNF 更新 (部分) 为了支持上述宏语法,需在 EBNF 中增加插值节点: (* 宏定义与插值 *) MacroDecl = Vis? "macro" Identifier "(" ParamList? ")" Suite ; MacroInterpolation = "$" ( Identifier | "(" Expr ")" | "(" ForMacro ")" ) ; ForMacro = "for" Identifier "in" Expr Suite "end" ; (* 更新 PrimaryExpr 以包含插值 *) PrimaryExpr = ... | MacroInterpolation ;