Files
aego/script/token/token.go
T
sanspie cf68c71f05 Stage 6: coroutines, signals, ScriptRef, workspace CLI, editor tooling
Language: yield/signal/coroutine become keywords, start is contextual.
Coroutine methods (func Name() coroutine) with start and
yield / wait / frames / fixed / await; signals with Emit/Connect and
Connection handles; ScriptRef<T> and node.GetScript<T>() for fields,
plain methods and signals of other scripts. Diagnostics AES2050-AES2059.

Bytecode v3: ScriptRefs, XFields, XMethods and Connects tables resolved by
name in vm.Link, per-script signals, coroutine flag on functions; new
opcodes START/YIELD/EMIT/CONNECT/DISCONNECT/CONNECTED/COSTOP/CORUN/
SELFREF/GETSCRIPT/GETXF/SETXF/CALLR, checked by verify.

Runtime: script/coroutine scheduler (frames/fixed counters, time heap,
await lists; only due coroutines are visited) and script/signal registry
(snapshot per Emit, deferred removal, no allocations in steady state).
Hot reload cancels coroutines of changed scripts, rebinds connections by
name and signature, then runs Reloaded.

Tooling: script/build removed, aego check/test/dump run on the workspace
(test builds include _test.aes); langsvc completion, hover, signatures and
semantic tokens for the new syntax; editor highlighting, snippets with
placeholders, coroutine/signal profiler graphs and stats.

Docs (script.md sections 16-19, editor.md, ARCHITECTURE), test fixtures and
golden files, platformer enemies wired to the player, scriptreload demo,
and run.Config.FrameTime for deterministic headless fixed steps.

Modules (6.5): engine/module registry and ComponentBuilder are the one
registration path for engine subsystems and native code; render2d,
render3d and script/engine are modules over scene/frame, the script
component moved to scene/scriptcomp, and scene/components and
scene/systems are gone. Editor inspector, templates, picking shapes and
extension hooks are driven by descriptors and editor/builtins; sdk gains
Component/EditorHook; depcheck checks the module graph and the
aego_runtime graph.

Also: stop tracking built tool binaries; gl33 activates the scratch unit
before binding for texture updates.

Verification: typed component method adapters (Method0..2, Proc0..2)
with direct field access and no allocations; app.Build as the single
construction path for run and the editor; modules attach per scene
document; depcheck aego_editor pass; diagnostic codes in one place and
every code covered by a test; indexed coroutine heaps with eager
cancel; dead component references and nil intrinsics fault with
AES6004, host faults keep their code; GC roots of struct fields checked
in verify and vm.Link; 255-field limit; AES4010 for script packages
shadowing host modules; architecture registry D111-D147.

Golden: the harness renders on the thread that owns the GL context,
ReadPixels returns rows in memory order (render targets are top-down per
D17), and the first rendering references are committed.
2026-10-12 14:22:08 +03:00

265 lines
3.7 KiB
Go

package token
import "strconv"
type Kind uint8
const (
Illegal Kind = iota
EOF
Ident
Int
Float
String
Add
Sub
Mul
Quo
Rem
Eq
Ne
Lt
Le
Gt
Ge
AndAnd
OrOr
Not
Assign
Define
AddAssign
SubAssign
MulAssign
QuoAssign
RemAssign
Inc
Dec
Period
Comma
Semicolon
Colon
LParen
RParen
LBrack
RBrack
LBrace
RBrace
At
keywordBeg
Package
Import
Script
Type
Struct
Enum
Var
Const
Func
Return
If
Else
For
Switch
Case
Default
Break
Continue
True
False
Nil
Yield
Signal
Coroutine
keywordEnd
reservedBeg
Await
Select
Go
Chan
Defer
Interface
Map
reservedEnd
)
var names = [...]string{
Illegal: "ILLEGAL",
EOF: "EOF",
Ident: "IDENT",
Int: "INT",
Float: "FLOAT",
String: "STRING",
Add: "+",
Sub: "-",
Mul: "*",
Quo: "/",
Rem: "%",
Eq: "==",
Ne: "!=",
Lt: "<",
Le: "<=",
Gt: ">",
Ge: ">=",
AndAnd: "&&",
OrOr: "||",
Not: "!",
Assign: "=",
Define: ":=",
AddAssign: "+=",
SubAssign: "-=",
MulAssign: "*=",
QuoAssign: "/=",
RemAssign: "%=",
Inc: "++",
Dec: "--",
Period: ".",
Comma: ",",
Semicolon: ";",
Colon: ":",
LParen: "(",
RParen: ")",
LBrack: "[",
RBrack: "]",
LBrace: "{",
RBrace: "}",
At: "@",
Package: "package",
Import: "import",
Script: "script",
Type: "type",
Struct: "struct",
Enum: "enum",
Var: "var",
Const: "const",
Func: "func",
Return: "return",
If: "if",
Else: "else",
For: "for",
Switch: "switch",
Case: "case",
Default: "default",
Break: "break",
Continue: "continue",
True: "true",
False: "false",
Nil: "nil",
Yield: "yield",
Signal: "signal",
Coroutine: "coroutine",
Await: "await",
Select: "select",
Go: "go",
Chan: "chan",
Defer: "defer",
Interface: "interface",
Map: "map",
}
var keywords = func() map[string]Kind {
m := make(map[string]Kind, int(reservedEnd-keywordBeg))
for k := keywordBeg + 1; k < keywordEnd; k++ {
m[names[k]] = k
}
for k := reservedBeg + 1; k < reservedEnd; k++ {
m[names[k]] = k
}
return m
}()
func (k Kind) String() string {
if int(k) < len(names) && names[k] != "" {
return names[k]
}
return "token(" + strconv.Itoa(int(k)) + ")"
}
func Lookup(ident string) Kind {
if k, ok := keywords[ident]; ok {
return k
}
return Ident
}
func (k Kind) IsKeyword() bool {
return k > keywordBeg && k < keywordEnd
}
func (k Kind) IsReserved() bool {
return k > reservedBeg && k < reservedEnd
}
func (k Kind) IsLiteral() bool {
return k == Int || k == Float || k == String
}
func (k Kind) IsOperator() bool {
return k >= Add && k <= At
}
func (k Kind) IsAssign() bool {
return k == Assign || (k >= AddAssign && k <= RemAssign)
}
func (k Kind) AssignOp() Kind {
switch k {
case AddAssign:
return Add
case SubAssign:
return Sub
case MulAssign:
return Mul
case QuoAssign:
return Quo
case RemAssign:
return Rem
}
return Illegal
}
const (
LowestPrec = 0
UnaryPrec = 6
)
func (k Kind) Precedence() int {
switch k {
case OrOr:
return 1
case AndAnd:
return 2
case Eq, Ne, Lt, Le, Gt, Ge:
return 3
case Add, Sub:
return 4
case Mul, Quo, Rem:
return 5
}
return LowestPrec
}
type Token struct {
Kind Kind
Start uint32
End uint32
Text string
Value string
}
func (t Token) IsAuto() bool {
return t.Kind == Semicolon && t.Text == "\n"
}
func (t Token) String() string {
switch {
case t.IsAuto():
return "newline"
case t.Kind == Ident || t.Kind.IsLiteral():
return t.Kind.String() + "(" + t.Text + ")"
}
return t.Kind.String()
}