Skip to content
beloch

Grammar

The grammar of the language, in one place. := defines, | separates alternatives, [ … ] is optional, ( … ) groups, * and + repeat, quoted strings are keywords, upper-case names are tokens, and ; starts a comment that runs to the end of the line. The parsers in packages/core and packages/grammar are held to it. Each section below names the page that says what its rules mean.

Overview.

Sheets.

library    := annotation* [ unit_decl ] shape_def*
unit_decl  := "unit" WORD
sheet      := "square" [ number ]
            | WORD number*
number     := RATIONAL | WORD
shape_def  := "shape" WORD "(" WORD* ")" "{" "paper" sheet shape_stmt*
              "trim" "to" flap_operand [ "{" export_entry+ "}" ] "}"
shape_stmt := write_stmt | bind_stmt | apply_stmt | export_stmt

Free points.

free_point := "free" "on" line_operand "from" point_operand [ ( "at" | "by" ) number ]

Operands; the type of each slot is under Parameter types.

point_operand := POINT_NAME
               | "(" line_operand "*" line_operand ")"      ; the meet, in parentheses as an operand
               | ".[" line_operand+ "]"                      ; the meet of two or more
               | "(" point_operand ")"
line_operand  := CREASE_NAME
               | point_operand "*" point_operand              ; the join, a point on each side
               | "--[" constraint+ "]"                       ; the join of every constraint
               | line_operand "&" constraint                 ; filter
               | line_operand "\" constraint                 ; drop
               | "[" line_operand+ "]"                       ; union
               | "(" line_operand ")"
constraint    := point_operand | CREASE_NAME | "#[" point_operand+ "]"
flap_operand  := point_operand | line_operand | "#[" point_operand+ "]"

Names and definitions. Which kind an export entry keeps across as is checked after parsing.

bind_stmt    := line_binding
              | CREASE_NAME "=" line_operand
              | POINT_NAME "=" line_operand "*" line_operand
              | POINT_NAME "=" ".[" line_operand+ "]"
              | POINT_NAME "=" free_point
def_stmt     := "def" WORD "(" param* ")" "{" body_stmt* "}"
param        := POINT_NAME | CREASE_NAME
body_stmt    := annotation* ( write_stmt | bind_stmt | apply_stmt | export_stmt )
apply_stmt   := [ INSTANCE_NAME "=" ] "apply" WORD "(" apply_arg* ")"
apply_arg    := point_operand | line_operand
export_stmt  := "export" [ "{" export_entry+ "}" ] INSTANCE_NAME
export_entry := ( POINT_NAME | CREASE_NAME ) [ "!" ] [ "as" ( POINT_NAME | CREASE_NAME ) ]

Write statements.

write_stmt := verb item* [ "as" CREASE_NAME [ "!" ] | "into" CREASE_NAME ]
verb       := "mark" | "fold" | "unfold" | "reverse" | "flatten" | "squash" | "flip"
item       := "(" item_body ")"
item_body  := fold_item | unfold_item | reverse_item | mark_item | flatten_item
            | squash_item
fold_item    := axis
              | side_item
              | "up" "to" flap_operand
              | "mountain"
              | ( "over" | "under" ) flap_operand
unfold_item  := line_operand
              | [ toward_subject ] "toward" ( point_operand | line_operand )
              | "moving" flap_operand [ "up" | "down" ]
              | "up" "to" flap_operand
reverse_item := axis
              | side_item
              | "outside"
              | line_operand ( "mountain" | "valley" )
mark_item    := axis
              | side_item
              | "on" flap_operand
              | "between" point_operand point_operand
              | "at" point_operand
              | "mountain" | "valley"
flatten_item := line_operand [ "mountain" | "valley" ]
              | flap_operand "over" flap_operand
              | "staying" point_operand+
              | "on" flap_operand
              | "toward" point_operand
squash_item  := line_operand "onto" ( point_operand | line_operand )
side_item    := [ toward_subject ] "toward" ( point_operand | line_operand )
              | "moving" flap_operand
axis         := construction_body | line_operand

Constructions.

construction_body := "align" CREASE_NAME* align_part+
                   | prose_axiom
align_part        := alignment
                   | "(" "heading" line_operand ")"
alignment         := "(" [ CREASE_NAME ] object "onto" [ CREASE_NAME ] object ")"
                   | "(" [ CREASE_NAME ] "through" point_operand ")"
                   | "(" [ CREASE_NAME ] "perp" line_operand ")"
object            := point_operand | line_operand
prose_axiom       := "through" point_operand point_operand
                   | "map" point_operand "onto" point_operand
                   | "perp" line_operand "through" point_operand
                   | "map" point_operand "onto" line_operand "perp" line_operand
                   | "map" line_operand "onto" line_operand
                   | "map" point_operand "onto" line_operand "through" point_operand
                   | "map" point_operand "onto" line_operand
                         "and" point_operand "onto" line_operand
line_binding      := CREASE_NAME "=" "(" construction_body ")" side_item*
toward_subject := point_operand | line_operand

Annotations.

annotation := "@" WORD arg* NEWLINE
            | "@" WORD ":" WORD value* NEWLINE
arg        := value | WORD
value      := flap_operand | TEXT | RATIONAL