guise-lang/doc/syntax.org

665 lines
14 KiB
Org Mode
Executable File

#+TITLE: Guise Syntax Specification (BNF)
#+AUTHOR: Guise Language Project
#+DATE: 2025-01-04
* Introduction
This document provides a formal BNF (Backus-Naur Form) grammar specification for the Guise programming language. Guise is a purely functional, statically-typed, stack-based language with S-expression syntax.
* Notation Conventions
- =<name>= : Non-terminal symbol
- ="literal"= : Terminal symbol (literal text)
- =|= : Alternative (or)
- =*= : Zero or more repetitions
- =+= : One or more repetitions
- =?= : Optional (zero or one)
- =()= : Grouping
* Lexical Elements
** Whitespace
#+BEGIN_SRC bnf
<whitespace> ::= <space> | <tab> | <newline> | <carriage-return>
<ws> ::= <whitespace>*
#+END_SRC
** Comments
#+BEGIN_SRC bnf
<comment> ::= ";;" <any-char-except-newline>* <newline>
#+END_SRC
** Identifiers
#+BEGIN_SRC bnf
<identifier> ::= <initial> <subsequent>*
<initial> ::= <letter> | <special-initial>
<subsequent> ::= <initial> | <digit> | <special-subsequent>
<letter> ::= "a" | "b" | ... | "z" | "A" | "B" | ... | "Z"
<digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
<special-initial> ::= "!" | "$" | "%" | "&" | "*" | "/" | ":" | "<" | "="
| ">" | "?" | "^" | "_" | "~" | "+" | "-"
<special-subsequent> ::= <special-initial> | "." | "@" | "#"
#+END_SRC
Examples: =square=, =make-point=, =++=, =foo->bar=, =h:helper=
** Literals
*** Numbers
#+BEGIN_SRC bnf
<number> ::= <prefix>? <complex>
<complex> ::= <real>
| <real> "+" <imag> "i"
| <real> "-" <imag> "i"
| <imag> "i"
| "+" "i"
| "-" "i"
<real> ::= <sign>? <ureal>
<imag> ::= <sign>? <ureal>
<ureal> ::= <uinteger>
| <uinteger> "/" <uinteger>
| <decimal>
<decimal> ::= <uinteger> <suffix>
| "." <digit>+ <suffix>
| <digit>+ "." <digit>* <suffix>
<uinteger> ::= <digit>+
<suffix> ::= <exponent>?
<exponent> ::= ("e" | "E") <sign>? <digit>+
<prefix> ::= <radix> <exactness>?
| <exactness> <radix>?
<radix> ::= "#b" | "#B" ; binary
| "#o" | "#O" ; octal
| "#d" | "#D" ; decimal
| "#x" | "#X" ; hexadecimal
<exactness> ::= "#e" | "#E" ; exact
| "#i" | "#I" ; inexact
<sign> ::= "+" | "-"
<digit> ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
#+END_SRC
Examples:
- Decimal: =42=, =-17=, =3.14=, =2.5e10=, =-1.23e-4=
- Binary: =#b11010= (26), =#b-1010= (-10)
- Octal: =#o77= (63), =#o-755= (-493)
- Hexadecimal: =#xab= (171), =#xFF= (255), =#x-1a= (-26)
- Explicit decimal: =#d100= (100)
- Rational: =1/2=, =22/7=, =-3/4=
- Complex: =3+4i=, =-2-5i=, =1.5+2.5i=
- Exactness: =#e3.14= (exact), =#i5= (inexact)
- Combined: =#b#e1010= (exact binary)
*** Strings
#+BEGIN_SRC bnf
<string> ::= '"' <string-char>* '"'
<string-char>::= <any-char-except-quote-or-backslash>
| <escape-sequence>
<escape-sequence> ::= "\\" | "\"" | "\n" | "\t" | "\r"
#+END_SRC
Examples: ="hello"=, ="Hello, World!"=, ="line1\nline2"=
*** Booleans
#+BEGIN_SRC bnf
<boolean> ::= "#t" | "#f" | "#true" | "#false"
#+END_SRC
*** Characters
#+BEGIN_SRC bnf
<character> ::= "#\\" <any-char>
| "#\\newline" | "#\\space" | "#\\tab"
#+END_SRC
Examples: =#\a=, =#\Z=, =#\newline=, =#\space=
*** Symbols
#+BEGIN_SRC bnf
<symbol> ::= <identifier>
#+END_SRC
Note: In Guise, all identifiers are symbols when they appear as literals.
** Keywords
#+BEGIN_SRC bnf
<keyword> ::= "define" | "module" | "import" | "public" | "private"
| "quotation" | "match" | "let"
| "sum" | "product" | "⊕" | "⊗"
| "only" | "prefix" | "rename" | "except"
#+END_SRC
** Type Markers
#+BEGIN_SRC bnf
<arrow> ::= "->"
<sum-marker> ::= "⊕" | "sum"
<prod-marker>::= "⊗" | "product"
#+END_SRC
* Expressions
** Program
#+BEGIN_SRC bnf
<program> ::= <top-level>*
<top-level> ::= <definition>
| <module-def>
| <import-stmt>
| <expression>
#+END_SRC
** Atomic Expressions
#+BEGIN_SRC bnf
<atom> ::= <number>
| <string>
| <boolean>
| <character>
| <symbol>
#+END_SRC
** Quotations
#+BEGIN_SRC bnf
<quotation> ::= "'" "(" <expression>* ")"
| "(" "quotation" <expression>* ")"
#+END_SRC
Examples:
- ='(dup *)=
- ='(1 +)=
- ='()=
- =(quotation dup dup * *)=
** List Literals
#+BEGIN_SRC bnf
<list-literal> ::= "#(" <expression>* ")"
#+END_SRC
Examples:
- =#(1 2 3)=
- =#("a" "b" "c")=
- =#(#(1 2) #(3 4))= (nested)
** Sequences
#+BEGIN_SRC bnf
<sequence> ::= "(" <expression>* ")"
<expression> ::= <atom>
| <quotation>
| <list-literal>
| <sequence>
#+END_SRC
* Type Annotations
** Type Variables
#+BEGIN_SRC bnf
<type-var> ::= "'" <letter> <letter-or-digit>*
#+END_SRC
Examples: ='a=, ='b=, ='result=, ='T=
** Primitive Types
#+BEGIN_SRC bnf
<prim-type> ::= "int" | "float" | "number"
| "bool" | "string" | "char" | "symbol"
#+END_SRC
** Compound Types
#+BEGIN_SRC bnf
<compound-type> ::= <quotation-type>
| <list-type>
| <tuple-type>
| <custom-type>
<quotation-type> ::= "(" "quot" "(" <stack-effect> ")" ")"
<list-type> ::= "(" "list" <type> ")"
<tuple-type> ::= "(" "tuple" <type>+ ")"
<custom-type> ::= <identifier>
#+END_SRC
Examples:
- =(quot (int -> int))=
- =(quot ('a -> 'a 'a))=
- =(list int)=
- =(tuple float float)=
- =Point=, =Maybe=
** Type Expressions
#+BEGIN_SRC bnf
<type> ::= <type-var>
| <prim-type>
| <compound-type>
#+END_SRC
** Stack Effects
#+BEGIN_SRC bnf
<stack-effect> ::= <type>* <arrow> <type>*
#+END_SRC
Examples:
- =number -> number=
- =int int -> int=
- ='a -> 'a 'a=
- ='a 'b -> 'b 'a=
- =-> int= (nullary, produces int)
- =int ->= (consumes int, produces nothing)
* Definitions
** Word Definitions
#+BEGIN_SRC bnf
<word-def> ::= "(" "define" <visibility>? <identifier>
"(" <stack-effect> ")" <expression>* ")"
<visibility> ::= "public" | "private"
#+END_SRC
Examples:
#+BEGIN_SRC scheme
(define square (number -> number)
(dup *))
(define public distance (Point Point -> float)
(x. swap x. - dup *
y. swap y. - dup *
+ sqrt))
(define private helper (int -> int)
(2 *))
#+END_SRC
** Primitive Definitions
#+BEGIN_SRC bnf
<prim-def> ::= "(" "define" "primitive" <identifier>
"(" <stack-effect> ")" ")"
#+END_SRC
Example:
#+BEGIN_SRC scheme
(define primitive dup ('a -> 'a 'a))
(define primitive + (number number -> number))
#+END_SRC
** Product Type Definitions (Tuples)
#+BEGIN_SRC bnf
<product-def> ::= "(" "define" <visibility>? <identifier> <prod-marker>?
<field-spec>+ <default-spec>* ")"
<field-spec> ::= "(" <identifier> <type> ")"
<default-spec>::= "(" <identifier> <type> "=" <expression> ")"
#+END_SRC
Examples:
#+BEGIN_SRC scheme
;; Implicit product type
(define Point (x float) (y float))
;; Explicit with ⊗
(define Vec3 (x float) (y float) (z float))
;; With explicit defaults
(define Config
(port int = 8080)
(host string = "localhost")
(debug bool = #f))
;; Public tuple in module
(define public Person (name string) (age int))
#+END_SRC
** Sum Type Definitions
#+BEGIN_SRC bnf
<sum-def> ::= "(" "define" <visibility>? <identifier> <sum-marker>
<variant>+ ")"
<variant> ::= "(" <identifier> <type>* ")"
#+END_SRC
Examples:
#+BEGIN_SRC scheme
;; Basic sum type with ⊕
(define Maybe
(Just 'a)
(Nothing))
;; Using 'sum' keyword
(define Either sum
(Left 'a)
(Right 'b))
;; Result type
(define Result
(Ok 'ok)
(Err 'err))
;; Enum-style
(define Color sum
(Red)
(Green)
(Blue)
(RGB int int int))
;; Recursive type
(define List
(Nil)
(Cons 'a (List 'a)))
#+END_SRC
** Module Definitions
#+BEGIN_SRC bnf
<module-def> ::= "(" "define" "module" <identifier>
<import-stmt>?
<module-body>* ")"
<module-body>::= <word-def>
| <prim-def>
| <product-def>
| <sum-def>
#+END_SRC
Example:
#+BEGIN_SRC scheme
(define module math
(import
(helpers (prefix h:))
(numeric-types (only int float)))
(define public square (number -> number)
(dup *))
(define public cube (number -> number)
(dup dup * *))
(define private internal-helper (int -> int)
(2 *)))
#+END_SRC
* Module System
** Import Statements
#+BEGIN_SRC bnf
<import-stmt> ::= "(" "import" <import-spec>+ ")"
<import-spec> ::= <identifier>
| "(" <identifier> <import-modifier>+ ")"
<import-modifier> ::= <only-modifier>
| <prefix-modifier>
| <rename-modifier>
| <except-modifier>
#+END_SRC
** Import Modifiers
#+BEGIN_SRC bnf
<only-modifier> ::= "(" "only" <identifier>+ ")"
<prefix-modifier> ::= "(" "prefix" <identifier> ")"
<rename-modifier> ::= "(" "rename" <rename-pair>+ ")"
<except-modifier> ::= "(" "except" <identifier>+ ")"
<rename-pair> ::= "(" <identifier> <identifier> ")"
#+END_SRC
Examples:
#+BEGIN_SRC scheme
;; Simple import
(import stack-ops numeric-types)
;; Only specific bindings
(import (math (only square cube)))
;; With prefix
(import (helpers (prefix h:)))
;; With rename
(import (geometry (rename (distance point-distance))))
;; Multiple modifiers
(import
(numeric-types (only int float) (prefix num:)))
;; Except modifier
(import (collections (except filter map)))
;; Complex example
(import
stack-ops
(math (only square) (prefix m:))
(geometry (rename (distance dist)))
(collections (except fold)))
#+END_SRC
* Pattern Matching (Future)
** Match Expressions
#+BEGIN_SRC bnf
<match-expr> ::= "(" "match" <match-case>+ ")"
<match-case> ::= "(" <pattern> "→" <expression>* ")"
<pattern> ::= <literal-pattern>
| <variable-pattern>
| <variant-pattern>
| <tuple-pattern>
| <wildcard-pattern>
<literal-pattern> ::= <number> | <string> | <boolean>
<variable-pattern> ::= <identifier>
<variant-pattern> ::= "(" <identifier> <pattern>* ")"
<tuple-pattern> ::= "(" <identifier> <pattern>* ")"
<wildcard-pattern> ::= "_"
#+END_SRC
Examples:
#+BEGIN_SRC scheme
;; Match on Maybe
(42 make-just match
(Nothing 0)
((Just x) x))
;; Match on list
(my-list match
(Nil 0)
((Cons x xs) (xs length 1 +)))
;; Match on custom tuple
(point match
((Point x y) (x y + 2 /)))
#+END_SRC
* Lexical Scoping (Future)
** Let Bindings
#+BEGIN_SRC bnf
<let-expr> ::= "(" "let" "(" <binding>+ ")" <expression>* ")"
<binding> ::= "(" <identifier> ")"
| "(" <identifier>+ ")"
#+END_SRC
Example:
#+BEGIN_SRC scheme
;; Bind single value
(5 let ((x))
(x x *))
;; Bind multiple values
(1 2 3 let ((z y x))
(x y + z *))
#+END_SRC
* Complete Grammar Summary
#+BEGIN_SRC bnf
;; ========================================
;; LEXICAL ELEMENTS
;; ========================================
<identifier> ::= <initial> <subsequent>*
<number> ::= <integer> | <float>
<string> ::= '"' <string-char>* '"'
<boolean> ::= "#t" | "#f"
<character> ::= "#\\" <any-char>
<comment> ::= ";;" <text> <newline>
;; ========================================
;; EXPRESSIONS
;; ========================================
<program> ::= <top-level>*
<top-level> ::= <definition> | <module-def> | <import-stmt> | <expression>
<expression> ::= <atom>
| <quotation>
| <list-literal>
| <sequence>
<atom> ::= <number> | <string> | <boolean> | <character> | <symbol>
<quotation> ::= "'" "(" <expression>* ")" | "(" "quotation" <expression>* ")"
<list-literal>::= "#(" <expression>* ")"
<sequence> ::= "(" <expression>* ")"
;; ========================================
;; TYPES
;; ========================================
<type> ::= <type-var> | <prim-type> | <compound-type>
<type-var> ::= "'" <identifier>
<prim-type> ::= "int" | "float" | "number" | "bool" | "string" | "char"
<compound-type> ::= <quotation-type> | <list-type> | <tuple-type> | <custom-type>
<stack-effect> ::= <type>* "->" <type>*
;; ========================================
;; DEFINITIONS
;; ========================================
<definition> ::= <word-def> | <prim-def> | <product-def> | <sum-def>
<word-def> ::= "(" "define" <visibility>? <identifier>
"(" <stack-effect> ")" <expression>* ")"
<prim-def> ::= "(" "define" "primitive" <identifier>
"(" <stack-effect> ")" ")"
<product-def> ::= "(" "define" <visibility>? <identifier> <prod-marker>?
<field-spec>+ ")"
<sum-def> ::= "(" "define" <visibility>? <identifier> <sum-marker>
<variant>+ ")"
<module-def> ::= "(" "define" "module" <identifier>
<import-stmt>? <module-body>* ")"
;; ========================================
;; MODULE SYSTEM
;; ========================================
<import-stmt> ::= "(" "import" <import-spec>+ ")"
<import-spec> ::= <identifier> | "(" <identifier> <import-modifier>+ ")"
<import-modifier> ::= "(" "only" <identifier>+ ")"
| "(" "prefix" <identifier> ")"
| "(" "rename" <rename-pair>+ ")"
| "(" "except" <identifier>+ ")"
#+END_SRC
* Examples
** Simple Expressions
#+BEGIN_SRC scheme
;; Stack operations
(5 3 +) ; → 8
(dup *) ; → square top of stack
(swap drop) ; → keep second element
;; With quotations
'(dup *) ; → push quotation
(5 '(dup *) call) ; → 25
#+END_SRC
** Word Definitions
#+BEGIN_SRC scheme
;; Basic word
(define square (number -> number)
(dup *))
;; Multiple inputs/outputs
(define pythagorean (number number -> number)
(dup * swap dup * + sqrt))
;; Higher-order
(define twice ('a (quot ('a -> 'a)) -> 'a)
(dup call call))
#+END_SRC
** Type Definitions
#+BEGIN_SRC scheme
;; Product type (tuple)
(define Point (x float) (y float))
;; Sum type (tagged union)
(define Maybe
(Just 'a)
(Nothing))
;; Using the types
(3.0 4.0 make-point) ; Creates Point
(42 make-just) ; Creates Maybe
#+END_SRC
** Modules
#+BEGIN_SRC scheme
;; Define a module
(define module math
(import (helpers (prefix h:)))
(define public square (number -> number)
(dup *))
(define private helper (number -> number)
(2 *)))
;; Use a module
(import math)
(5 square) ; → 25
#+END_SRC