Skip to content

Commit 4eb6898

Browse files
committed
refactor: grammar of struct def and func decl
1 parent 2741148 commit 4eb6898

3 files changed

Lines changed: 30 additions & 17 deletions

File tree

docs/tealang.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,13 @@ typed_array_decl := identifier < : > < [ > typeSpec < ; > num < ] > // ar
112112
varDecl := typed_array_decl
113113
| typed_scalar_decl
114114
| scalar_decl
115+
116+
typedVarDecl := typed_array_decl
117+
| typed_scalar_decl
115118
```
116119

120+
`varDecl` (with optional type) is used in `let` statements where type inference is allowed. `typedVarDecl` (type required) is used for struct fields and function parameters where types are mandatory.
121+
117122
Since `typeSpec` includes reference types (`&[T]`), a `typed_scalar_decl` like `arr: &[i32]` declares a slice reference parameter. This form is only valid in function parameter lists — it cannot appear in `let` statements or struct fields. This constraint is enforced semantically, not syntactically.
118123

119124
Examples:
@@ -155,11 +160,12 @@ let count = 0; // type inference scalar
155160

156161
## Structure Definitions
157162

158-
Define custom types using the `struct` keyword with named fields. Struct fields use `varDecl` (scalars and arrays only; reference types are not permitted as struct fields).
163+
Define custom types using the `struct` keyword with named fields. Struct fields must have type annotations (reference types are not permitted as struct fields).
159164

160165
```
161-
structDef := < struct > identifier < { > varDeclList < } >
162-
varDeclList := varDecl (< , > varDecl)*
166+
structDef := < struct > identifier < { > typedVarDeclList < } >
167+
typedVarDeclList := typedVarDecl (< , > typedVarDecl)*
168+
typedVarDecl := typed_array_decl | typed_scalar_decl
163169
```
164170

165171
Example:
@@ -176,13 +182,13 @@ struct Node {
176182

177183
### Function Declarations
178184

179-
Declare function signatures with optional return types. Function parameters use `varDecl`, which includes reference-typed parameters like `arr: &[i32]` via `typeSpec`.
185+
Declare function signatures with optional return types. Function parameters must have type annotations, including reference-typed parameters like `arr: &[i32]` via `typeSpec`.
180186

181187
```
182188
fnDeclStmt := fnDecl < ; >
183189
fnDecl := < fn > identifier < ( > paramDecl? < ) > < -> > typeSpec // with return type
184190
| < fn > identifier < ( > paramDecl? < ) > // without return type
185-
paramDecl := varDeclList
191+
paramDecl := typedVarDeclList
186192
```
187193

188194
Examples:

src/parser/decl.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,18 +62,18 @@ impl<'a> ParseContext<'a> {
6262
for inner in pair.into_inner() {
6363
match inner.as_rule() {
6464
Rule::identifier => identifier = inner.as_str().to_string(),
65-
Rule::var_decl_list => decls = self.parse_var_decl_list(inner)?,
65+
Rule::typed_var_decl_list => decls = self.parse_typed_var_decl_list(inner)?,
6666
_ => {}
6767
}
6868
}
6969

7070
Ok(Box::new(ast::StructDef { identifier, decls }))
7171
}
7272

73-
pub(crate) fn parse_var_decl_list(&self, pair: Pair) -> ParseResult<Vec<ast::VarDecl>> {
73+
pub(crate) fn parse_typed_var_decl_list(&self, pair: Pair) -> ParseResult<Vec<ast::VarDecl>> {
7474
let mut decls = Vec::new();
7575
for inner in pair.into_inner() {
76-
if inner.as_rule() == Rule::var_decl {
76+
if inner.as_rule() == Rule::typed_var_decl {
7777
decls.push(*self.parse_var_decl(inner)?);
7878
}
7979
}
@@ -326,9 +326,9 @@ impl<'a> ParseContext<'a> {
326326
fn parse_param_decl(&self, pair: Pair) -> ParseResult<Box<ast::ParamDecl>> {
327327
let pair_for_error = pair.clone();
328328
for inner in pair.into_inner() {
329-
if inner.as_rule() == Rule::var_decl_list {
329+
if inner.as_rule() == Rule::typed_var_decl_list {
330330
return Ok(Box::new(ast::ParamDecl {
331-
decls: self.parse_var_decl_list(inner)?,
331+
decls: self.parse_typed_var_decl_list(inner)?,
332332
}));
333333
}
334334
}

src/tealang.pest

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -156,14 +156,21 @@ program_element = {
156156
// Define a structure with named fields
157157
// Example: "struct Node { value:i32, next:i32 }"
158158
struct_def = {
159-
kw_struct ~ identifier ~ lbrace ~ var_decl_list ~ rbrace
159+
kw_struct ~ identifier ~ lbrace ~ typed_var_decl_list ~ rbrace
160160
}
161161

162-
// Variable declarations
163-
// List of variable declarations separated by commas
162+
// Typed variable declaration: must have a type annotation (no untyped scalars)
163+
// Used for struct fields and function parameters where types are mandatory
164+
// Examples: "n:i32", "arr: [i32; 100]", "input: &[i32]"
165+
typed_var_decl = {
166+
identifier ~ colon ~ lbracket ~ type_spec ~ semicolon ~ num ~ rbracket // array with type
167+
| identifier ~ colon ~ type_spec // scalar with type (also handles &[T] via type_spec)
168+
}
169+
170+
// Typed variable declaration list: comma-separated typed declarations
164171
// Example: "x:i32, y:i32, z:i32"
165-
var_decl_list = {
166-
var_decl ~ (comma ~ var_decl)*
172+
typed_var_decl_list = {
173+
typed_var_decl ~ (comma ~ typed_var_decl)*
167174
}
168175

169176
// Variable declaration: can be array or scalar, with or without type annotation
@@ -210,10 +217,10 @@ fn_decl = {
210217
| kw_fn ~ identifier ~ lparen ~ param_decl? ~ rparen
211218
}
212219

213-
// Parameter declaration: list of parameter variables
220+
// Parameter declaration: list of parameter variables (types required)
214221
// Example: "x:i32, y:i32" in "fn add(x:i32, y:i32) -> i32 { }"
215222
param_decl = {
216-
var_decl_list
223+
typed_var_decl_list
217224
}
218225

219226
// Function definition: declaration with implementation

0 commit comments

Comments
 (0)