This document specifies the grammar rules and syntax of the CURSED programming language. The grammar follows Go-like structure but uses Gen Z slang keywords.
A CURSED program consists of one or more source files organized into packages. Each source file belongs to a single package and consists of package declarations, imports, and top-level declarations.
SourceFile = PackageClause ";" { ImportDecl ";" } { TopLevelDecl ";" } .
PackageClause = "vibe" PackageName .
PackageName = identifier .
Imports declare dependencies on other packages.
ImportDecl = "yeet" ( ImportSpec | "(" { ImportSpec ";" } ")" ) .
ImportSpec = [ identifier | "." ] ImportPath .
ImportPath = string_lit .
Example:
vibe main
yeet (
"fmt"
tea "strings"
)
Declarations introduce new identifiers and bind them to constants, types, variables, functions, or packages.
Declaration = ConstDecl | TypeDecl | VarDecl | FuncDecl .
TopLevelDecl = Declaration | MethodDecl .
ConstDecl = "facts" ( ConstSpec | "(" { ConstSpec ";" } ")" ) .
ConstSpec = IdentifierList [ Type ] "=" ExpressionList .
Example:
facts (
PI = 3.14159
E = 2.71828
)
VarDecl = "sus" ( VarSpec | "(" { VarSpec ";" } ")" ) .
VarSpec = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) .
Example:
sus name tea = "World"
sus age, height = 25, 180.5
TypeDecl = "be_like" ( TypeSpec | "(" { TypeSpec ";" } ")" ) .
TypeSpec = TypeName Type .
Example:
be_like Person squad {
name tea
age normie
}
FuncDecl = "slay" FunctionName [ TypeParameters ] Signature [ FunctionBody ] .
FunctionName = identifier .
FunctionBody = Block .
Example:
slay add(x, y normie) normie {
yolo x + y
}
Statements control execution.
Statement = Declaration | SimpleStmt |
IfStmt | SwitchStmt | ForStmt |
Block | ReturnStmt | BreakStmt | ContinueStmt .
SimpleStmt = EmptyStmt | ExpressionStmt | Assignment | ShortVarDecl |
IncDecStmt .
IfStmt = "lowkey" [ SimpleStmt ";" ] Expression Block [ "highkey" ( IfStmt | Block ) ] .
Example:
lowkey x > 0 {
yolo x
} highkey lowkey x < 0 {
yolo -x
} highkey {
yolo 0
}
Parentheses around the condition expression are optional:
lowkey (x > 0) {
yolo x
}
Both forms are valid in CURSED.
SwitchStmt = ExprSwitchStmt | TypeSwitchStmt .
ExprSwitchStmt = "vibe_check" [ SimpleStmt ";" ] [ Expression ] "{" { ExprCaseClause } "}" .
ExprCaseClause = ExprSwitchCase ":" StatementList .
ExprSwitchCase = "mood" ExpressionList | "basic" .
Example:
vibe_check day {
mood "Monday", "Tuesday":
print("Start of week")
mood "Friday":
print("End of week")
basic:
print("Mid-week")
}
ForStmt = "bestie" [ Condition | ForClause | RangeClause ] Block .
Condition = Expression .
ForClause = [ InitStmt ] ";" [ Condition ] ";" [ PostStmt ] .
RangeClause = [ ExpressionList "=" | IdentifierList ":=" ] "flex" Expression .
Examples:
bestie i := 0; i < 10; i++ {
print(i)
}
bestie x < 100 {
x = x * 2
}
bestie {
doSomething()
lowkey done() {
ghosted
}
}
bestie _, val := flex items {
process(val)
}
WhileStmt = "periodt" Expression Block .
Example:
periodt x > 0 {
x--
}
ReturnStmt = "yolo" [ ExpressionList ] .
Example:
yolo x + y
BreakStmt = "ghosted" [ Label ] .
ContinueStmt = "simp" [ Label ] .
Example:
bestie {
lowkey someCondition() {
ghosted
}
lowkey otherCondition() {
simp
}
}
Expressions compute values.
Expression = UnaryExpr | Expression binary_op Expression .
UnaryExpr = PrimaryExpr | unary_op UnaryExpr .
PrimaryExpr = Operand | Conversion | PrimaryExpr Selector | PrimaryExpr Index | PrimaryExpr Slice | PrimaryExpr TypeAssertion | PrimaryExpr Arguments .
Operand = Literal | OperandName | "(" Expression ")" .
Literal = BasicLit | CompositeLit | FunctionLit .
BasicLit = int_lit | float_lit | string_lit .
OperandName = identifier | QualifiedIdentifier .
QualifiedIdentifier = identifier "." identifier .
Selector = "." identifier .
Index = "[" Expression "]" .
Slice = "[" [ Expression ] ":" [ Expression ] [ ":" Expression ] "]" .
TypeAssertion = ".(" Type ")" .
Example:
x.field
arr[i]
slice[i:j]
value.(tea)
Arguments = "(" [ ( ExpressionList [ "," ] ) | Type [ "," ExpressionList [ "," ] ] ] ")" .
ExpressionList = Expression { "," Expression } .
Example:
fmt.Println("Hello, world!")
add(1, 2)
GoStmt = "stan" Expression .
SendStmt = Channel "<-" Expression .
Channel = Expression .
Example:
stan doSomething()
ch <- value
x := <-ch
DeferStmt = "later" Expression .
Example:
later file.Close()
CURSED follows Go's error handling pattern:
slay doSomething() (tea, Error) {
lowkey err != cap {
yolo "", err
}
yolo "success", cap
}
result, err := doSomething()
lowkey err != cap {
handleError(err)
}