Complete current Ludus grammar.

This commit is contained in:
Scott Richmond 2023-12-15 20:20:35 -05:00
parent 4005a12358
commit de5be03c88
4 changed files with 138 additions and 97 deletions

2
justfile Normal file
View File

@ -0,0 +1,2 @@
build:
npx lezer-generator ludus.grammar -o ludus.js

View File

@ -1,10 +1,12 @@
@top Script { terminator* line+ } @precedence { line_end @left, line_break @left }
@top Script { (newline | terminator)* line+ }
@skip { space | comment } @skip { space | comment }
line { (expression | toplevel) terminator+ } line { (expression | toplevel) !line_end (newline | terminator)+ }
toplevel { Import | Use | Ns } toplevel { Import | Use | Ns | Test }
Import { silent<"import"> String silent<"as"> Word } Import { silent<"import"> String silent<"as"> Word }
@ -18,6 +20,8 @@ Ns {
"}" "}"
} }
Test { silent<"test"> String non_binding }
expression { non_binding | binding } expression { non_binding | binding }
binding { Let | Ref | Fn_Named | Fn_Compound } binding { Let | Ref | Fn_Named | Fn_Compound }
@ -33,11 +37,11 @@ synth_term { Args | Keyword }
arg_term { Placeholder | simple } arg_term { Placeholder | simple }
Args { Args {
("(" separator* ")") ("(" (newline | separator)* ")")
| ("(" | ("("
separator* (newline | separator)*
arg_term (separator+ arg_term)* arg_term ((newline | separator)+ arg_term)*
separator* (newline | separator)*
")") ")")
} }
@ -49,21 +53,13 @@ complex {
| If_Let | If_Let
| Match | Match
| When | When
//| Do | Do
//| Bind
| Loop | Loop
| Repeat | Repeat
| Each
} }
Repeat { silent<"repeat"> (Word | Number) Block } Repeat { silent<"repeat"> (Word | Number) Block }
// repeat 4 { thing () }
Each { silent<"each"> simple "do" (Fn_Clause | Fn_Clauses) }
// each [1, 2, 3] do (n) -> thing
Recur { silent<"recur"> Args } Recur { silent<"recur"> Args }
Loop { silent<"loop"> simple "with" (Fn_Clause | Fn_Clauses) } Loop { silent<"loop"> simple "with" (Fn_Clause | Fn_Clauses) }
@ -74,9 +70,9 @@ Fn_Clause { Tuple_Pattern "->" expression }
Fn_Clauses { Fn_Clauses {
"{" "{"
terminator* (newline | terminator)*
Fn_Clause (terminator+ Fn_Clause)* Fn_Clause ((newline | terminator)+ Fn_Clause)*
terminator* (newline | terminator)*
"}" "}"
} }
@ -87,84 +83,71 @@ Fn_Named { silent<"fn"> Word Fn_Clause }
Fn_Lambda { silent<"fn"> Fn_Clause } Fn_Lambda { silent<"fn"> Fn_Clause }
// TODO: figure out precedence with do/bind exprs // TODO: figure out precedence with do/bind exprs
// do_expr { Fn_Lambda | Synthetic | Word | Keyword } do_expr { Fn_Lambda | Synthetic | Word | Keyword }
// Do { Do {
// silent<"do"> simple (~ambig newline* ">" do_expr)+ silent<"do"> simple !line_break (newline* ">" do_expr)+
// } }
// Bind {
// silent<"bind">
// simple
// (!pipeline pipeline)+
// }
Pattern { Pattern {
Tuple_Pattern Tuple_Pattern
| List_Pattern | List_Pattern
| Dict_Pattern | Dict_Pattern
| Struct_Pattern
| atom | atom
| Placeholder | Placeholder
| Ignored
} }
Ignored { "_" Word }
Placeholder { "_" } Placeholder { "_" }
ellipsis { "..." } ellipsis { "..." }
Splattern { ellipsis (Word | Placeholder) } Splattern { ellipsis (Word | Placeholder | Ignored) }
Tuple_Pattern { Tuple_Pattern {
("(" separator* ")") ("(" (newline | separator)* ")")
| ("(" | ("("
separator* (newline | separator)*
(Pattern separator+)* (Pattern | Splattern) (Pattern (newline | separator)+)* (Pattern | Splattern)
separator* (newline | separator)*
")") ")")
} }
List_Pattern { List_Pattern {
("[" separator* "]") ("[" (newline | separator)* "]")
| ("[" | ("["
separator* (newline | separator)*
(Pattern separator+)* (Pattern | Splattern) (Pattern (newline | separator)+)* (Pattern | Splattern)
separator* (newline | separator)*
"]") "]")
} }
Assoc_Pattern { Word | (Keyword Pattern) } Assoc_Pattern { Word | (Keyword Pattern) }
Dict_Pattern { Dict_Pattern {
("#{" separator* "}") ("#{" (newline | separator)* "}")
| ("#{" | ("#{"
separator* (newline | separator)*
(Assoc_Pattern separator+)* (Assoc_Pattern | Splattern) (Assoc_Pattern (newline | separator)+)* (Assoc_Pattern | Splattern)
separator* (newline | separator)*
"}") "}")
} }
Struct_Pattern { Let { silent<"let"> Pattern "=" !line_break newline* non_binding }
("@{" separator* "}")
| ("@{"
separator*
(Assoc_Pattern separator+)* (Assoc_Pattern | Splattern)
separator*
"}")
}
Let { silent<"let"> Pattern "=" non_binding }
Else { silent<"else"> } Else { silent<"else"> }
Match_Clause {(Pattern | Else) "->" newline* expression} Match_Clause {(Pattern | Else) "->" !line_break newline* expression}
match_body { match_body {
Match_Clause Match_Clause
| ( | (
"{" "{"
terminator* (newline | terminator)*
Match_Clause (terminator+ Match_Clause)* Match_Clause ((newline | terminator)+ Match_Clause)*
terminator* (newline | terminator)*
"}" "}"
) )
} }
@ -177,35 +160,36 @@ Match {
} }
When_Clause { When_Clause {
(simple | Placeholder | Else) "->" newline* expression (simple | Placeholder | Else) "->" !line_break newline* expression
} }
When { When {
silent<"when"> "{" silent<"when">
terminator* "{"
When_Clause (terminator+ When_Clause)* (newline | terminator)*
terminator* When_Clause ((newline | terminator)+ When_Clause)*
(newline | terminator)*
"}" "}"
} }
If { If {
silent<"if"> simple newline* silent<"if"> simple !line_break newline*
silent<"then"> expression newline* silent<"then"> expression !line_break newline*
silent<"else"> expression silent<"else"> expression
} }
If_Let { If_Let {
silent<"if"> silent<"let"> silent<"if"> silent<"let">
Pattern "=" simple newline* Pattern "=" simple !line_break newline*
silent<"then"> expression newline* silent<"then"> expression !line_break newline*
silent<"else"> expression silent<"else"> expression
} }
Block { Block {
"{" "{"
terminator* (newline | terminator)*
expression (terminator+ expression)* expression ((newline | terminator)+ expression)*
terminator* (newline | terminator)*
"}" "}"
} }
@ -214,16 +198,15 @@ collection {
| List | List
| Set | Set
| Dict | Dict
| Struct
} }
Tuple { Tuple {
( "(" // non-empty ( "(" // non-empty
separator* (newline | separator)*
non_binding (separator+ non_binding)* non_binding ((newline | separator)+ non_binding)*
separator* (newline | separator)*
")" ) ")" )
| "(" separator* ")" // empty | "(" (newline | separator)* ")" // empty
} }
Splat { ellipsis Word } Splat { ellipsis Word }
@ -232,20 +215,20 @@ linear_term { Splat | non_binding }
List { List {
("[" ("["
separator* (newline | separator)*
linear_term (separator+ linear_term)* linear_term ((newline | separator)+ linear_term)*
separator* (newline | separator)*
"]" ) "]" )
| "[" separator* "]" | "[" (newline | separator)* "]"
} }
Set { Set {
("${" ("${"
separator* (newline | separator)*
linear_term (separator+ linear_term)* linear_term ((newline | separator)+ linear_term)*
separator* (newline | separator)*
"}") "}")
| "${" separator* "}" | "${" (newline | separator)* "}"
} }
assoc_term { Word | (Keyword non_binding) } assoc_term { Word | (Keyword non_binding) }
@ -254,20 +237,11 @@ dict_term { assoc_term | Splat }
Dict { Dict {
("#{" ("#{"
separator* (newline | separator)*
dict_term (separator+ dict_term)* dict_term ((newline | separator)+ dict_term)*
separator* (newline | separator)*
"}" ) "}" )
| "#{" separator* "}" | "#{" (newline | separator)* "}"
}
Struct {
("@{"
separator*
assoc_term (separator+ assoc_term)*
separator*
"}")
| "@{" separator* "}"
} }
atom { Boolean | Nil | String | Number | Keyword | Word } atom { Boolean | Nil | String | Number | Keyword | Word }
@ -290,7 +264,7 @@ Nil { silent<"nil"> }
int { $[1-9]$[0-9]* | "0" } int { $[1-9]$[0-9]* | "0" }
float { ("0" | int ) "." $[0-9]+} float { ("0" | int ) "." $[0-9]+}
Number { "-"? (int | float) } Number { "-"? (int | float) }
separator { $[,\n] } separator { "," }
terminator { $[;\n] } terminator { ";" }
newline { "\n" } newline { "\n" }
} }

18
ludus.js Normal file

File diff suppressed because one or more lines are too long

47
ludus.terms.js Normal file
View File

@ -0,0 +1,47 @@
// This file was generated by lezer-generator. You probably shouldn't edit it.
export const
Script = 1,
Boolean = 2,
Word = 3,
Nil = 6,
String = 7,
Number = 8,
Keyword = 9,
Tuple = 10,
List = 11,
Splat = 12,
Set = 13,
Dict = 14,
Synthetic = 15,
Args = 16,
Placeholder = 17,
Fn_Lambda = 18,
Fn_Clause = 19,
Tuple_Pattern = 20,
Pattern = 21,
List_Pattern = 22,
Splattern = 23,
Ignored = 24,
Dict_Pattern = 25,
Assoc_Pattern = 26,
Recur = 27,
Block = 28,
If = 29,
If_Let = 30,
Match = 31,
Match_Clause = 32,
Else = 33,
When = 34,
When_Clause = 35,
Do = 36,
Loop = 37,
Fn_Clauses = 38,
Repeat = 39,
Let = 40,
Ref = 41,
Fn_Named = 42,
Fn_Compound = 43,
Import = 44,
Use = 45,
Ns = 46,
Test = 47