Skip to content

Commit 350914c

Browse files
authored
Fix prompt-fiddle highlighting (#2082)
This was generated mostly with claude-code. - Add a lezer grammar test suite - Fix the lezer grammar - Add grammar rules for expression functions - Allow comments in expr fns Before: <img width="517" alt="Screenshot 2025-06-27 at 9 57 44 PM" src="https://github.com/user-attachments/assets/65f62318-6ecc-46cd-a580-65e1b6496fae" /> After: <img width="531" alt="Screenshot 2025-06-27 at 11 07 33 PM" src="https://github.com/user-attachments/assets/7609503e-d831-45cd-96ad-4d8f4a107f54" /> <!-- ELLIPSIS_HIDDEN --> ---- > [!IMPORTANT] > Fixes BAML grammar issues and adds comprehensive test suite for improved language support. > > - **Grammar Fixes**: > - Fix `expr_block` in `datamodel.pest` to allow comments and empty lines in expression functions. > - Update `stmt` rule to allow trailing comments and optional newlines. > - Add grammar rules for expression functions in `syntax.grammar`. > - **Testing**: > - Add a lezer grammar test suite in `test/test.cjs` and `test/test.js`. > - Add test cases for class, enum, function, and expression function declarations in `test/cases/`. > - **Misc**: > - Update `package.json` to change test script to use `test/test.cjs`. > > <sup>This description was created by </sup>[<img alt="Ellipsis" src="https://img.shields.io/badge/Ellipsis-blue?color=175173">](https://www.ellipsis.dev?ref=BoundaryML%2Fbaml&utm_source=github&utm_medium=referral)<sup> for df01047. You can [customize](https://app.ellipsis.dev/BoundaryML/settings/summaries) this summary. It will automatically update as commits are pushed.</sup> <!-- ELLIPSIS_HIDDEN -->
1 parent 64ff518 commit 350914c

26 files changed

Lines changed: 976 additions & 18 deletions

engine/baml-lib/ast/src/parser/datamodel.pest

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,11 +233,11 @@ top_level_assignment = { stmt }
233233
expr_fn = { ("function" | "fn") ~ identifier ~ named_argument_list ~ ARROW? ~ field_type_chain? ~ expr_block }
234234

235235
// Body of a function (including curly brackets).
236-
expr_block = { BLOCK_OPEN ~ NEWLINE? ~ (stmt ~ NEWLINE)* ~ expression ~ NEWLINE? ~ BLOCK_CLOSE }
236+
expr_block = { BLOCK_OPEN ~ NEWLINE? ~ (stmt | comment_block | empty_lines)* ~ expression ~ NEWLINE? ~ BLOCK_CLOSE }
237237

238238
// Statement.
239239
// Currently the only statement is a let-binding.
240-
stmt = { let_expr ~ SEMICOLON? }
240+
stmt = { let_expr ~ SEMICOLON? ~ trailing_comment? ~ NEWLINE? }
241241

242242
// Let-binding statement.
243243
let_expr = { "let" ~ identifier ~ "=" ~ expression }

engine/baml-lib/ast/src/parser/parse_expr.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,14 @@ pub fn parse_expr_block(token: Pair<'_>, diagnostics: &mut Diagnostics) -> Optio
146146
Rule::NEWLINE => {
147147
continue;
148148
}
149+
Rule::comment_block => {
150+
// Skip comments in function bodies
151+
continue;
152+
}
153+
Rule::empty_lines => {
154+
// Skip empty lines in function bodies
155+
continue;
156+
}
149157
_ => {
150158
diagnostics.push_error(DatamodelError::new_static(
151159
"Internal Error: Parser only allows statements and expressions in function body.",

engine/baml-lib/baml/tests/validation_files/expr/builtin.baml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,18 @@ function GetTodoMissingTypeArg() -> Todo {
2121
})
2222
}
2323

24+
// warning: Workflow functions are experimental, and will break in the future.
25+
// --> expr/builtin.baml:8
26+
// |
27+
// 7 |
28+
// 8 | function GetTodo() -> Todo {
29+
// |
30+
// warning: Workflow functions are experimental, and will break in the future.
31+
// --> expr/builtin.baml:16
32+
// |
33+
// 15 |
34+
// 16 | function GetTodoMissingTypeArg() -> Todo {
35+
// |
2436
// error: Generic function std::fetch_value must have a type argument. Try adding a type argument like this: std::fetch_value<Type>
2537
// --> expr/builtin.baml:17
2638
// |

engine/baml-lib/baml/tests/validation_files/expr/constructors.baml

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,27 @@ class Person {
1919
name string
2020
age int
2121
poem string
22-
}
22+
}
23+
24+
// warning: Variable assignment is experimental, and will break in the future.
25+
// --> expr/constructors.baml:6
26+
// |
27+
// 5 |
28+
// 6 | let x = MyClass { a: 1, b: "2" };
29+
// |
30+
// warning: Variable assignment is experimental, and will break in the future.
31+
// --> expr/constructors.baml:8
32+
// |
33+
// 7 |
34+
// 8 | let y = MyClass { a: 1, ..x };
35+
// |
36+
// warning: Variable assignment is experimental, and will break in the future.
37+
// --> expr/constructors.baml:11
38+
// |
39+
// 10 |
40+
// 11 | let default_person = Person {
41+
// 12 | name: "John Doe",
42+
// 13 | age: 20,
43+
// 14 | poem: "Never was there a man more plain."
44+
// 15 | };
45+
// |

engine/baml-lib/baml/tests/validation_files/expr/constructors_invalid.baml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ fn Foo() -> Bar {
1818
x
1919
}
2020

21+
// warning: Workflow functions are experimental, and will break in the future.
22+
// --> expr/constructors_invalid.baml:6
23+
// |
24+
// 5 |
25+
// 6 | fn Foo() -> Bar {
26+
// |
2127
// error: Error validating: Bar.a expected type int, but found string
2228
// --> expr/constructors_invalid.baml:7
2329
// |

engine/baml-lib/baml/tests/validation_files/expr/constructors_nested.baml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ class Bar {
88

99
let x = Foo { bar: Bar { name: 10 }};
1010

11+
// warning: Variable assignment is experimental, and will break in the future.
12+
// --> expr/constructors_nested.baml:9
13+
// |
14+
// 8 |
15+
// 9 | let x = Foo { bar: Bar { name: 10 }};
16+
// |
1117
// error: Error validating: Bar.name expected type string, but found int
1218
// --> expr/constructors_nested.baml:9
1319
// |

engine/baml-lib/baml/tests/validation_files/expr/expr_fn.baml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ function Foo(x: int) -> int {
44
}
55

66
fn Bar(x: int) -> int {
7+
// test
78
let y = x;
89
x
910
}
@@ -13,4 +14,17 @@ test TestBar {
1314
args {
1415
x 1
1516
}
16-
}
17+
}
18+
19+
// warning: Workflow functions are experimental, and will break in the future.
20+
// --> expr/expr_fn.baml:1
21+
// |
22+
// |
23+
// 1 | function Foo(x: int) -> int {
24+
// |
25+
// warning: Workflow functions are experimental, and will break in the future.
26+
// --> expr/expr_fn.baml:6
27+
// |
28+
// 5 |
29+
// 6 | fn Bar(x: int) -> int {
30+
// |

engine/baml-lib/baml/tests/validation_files/expr/expr_full.baml

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
function MakePoem(length: int) -> string {
32
client GPT4o
43
prompt #"Write a poem {{ length }} lines long."#
@@ -68,4 +67,39 @@ client<llm> GPT4o {
6867
test TestMakePoem() {
6968
functions [MakePoem]
7069
args { length 4 }
71-
}
70+
}
71+
72+
// warning: Workflow functions are experimental, and will break in the future.
73+
// --> expr/expr_full.baml:27
74+
// |
75+
// 26 |
76+
// 27 | function Pipeline() -> string {
77+
// |
78+
// warning: Workflow functions are experimental, and will break in the future.
79+
// --> expr/expr_full.baml:37
80+
// |
81+
// 36 |
82+
// 37 | function Pyramid() -> string {
83+
// |
84+
// warning: Workflow functions are experimental, and will break in the future.
85+
// --> expr/expr_full.baml:41
86+
// |
87+
// 40 |
88+
// 41 | function OuterPyramid() -> string {
89+
// |
90+
// warning: Variable assignment is experimental, and will break in the future.
91+
// --> expr/expr_full.baml:19
92+
// |
93+
// 18 |
94+
// 19 | let poem = MakePoem(10);
95+
// |
96+
// warning: Variable assignment is experimental, and will break in the future.
97+
// --> expr/expr_full.baml:21
98+
// |
99+
// 20 |
100+
// 21 | let another = {
101+
// 22 | let x = MakePoem(10);
102+
// 23 | let y = MakePoem(5);
103+
// 24 | CombinePoems(x,y)
104+
// 25 | };
105+
// |

engine/baml-lib/baml/tests/validation_files/expr/expr_list.baml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,17 @@ function Id(x: int) -> int {
44

55
function Go(x: int) -> int[] {
66
[x, Id(x), 3]
7-
}
7+
}
8+
9+
// warning: Workflow functions are experimental, and will break in the future.
10+
// --> expr/expr_list.baml:1
11+
// |
12+
// |
13+
// 1 | function Id(x: int) -> int {
14+
// |
15+
// warning: Workflow functions are experimental, and will break in the future.
16+
// --> expr/expr_list.baml:5
17+
// |
18+
// 4 |
19+
// 5 | function Go(x: int) -> int[] {
20+
// |
Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
11
function A(x: int) -> int {
22
x
3-
}
3+
}
4+
5+
// warning: Workflow functions are experimental, and will break in the future.
6+
// --> expr/expr_small.baml:1
7+
// |
8+
// |
9+
// 1 | function A(x: int) -> int {
10+
// |

0 commit comments

Comments
 (0)