ffi 2.5 green: name: Type; field body items in #jni_class
New `JniFieldDecl` AST struct (name + field_type); `JniClassMember`
gains a `field` variant. After consuming a member-name identifier
in the body loop, the parser branches on the next token: `:` →
field path (parse type expr + `;`), `::` → method path (existing).
`static` fields aren't part of the grammar yet and error explicitly
("static fields not yet supported"); only instance fields land here.
Lowering to JNI `Get<Type>Field` / `Set<Type>Field` arrives in 2.13.
124/124 examples green.
This commit is contained in:
@@ -541,8 +541,14 @@ pub const JniMethodDecl = struct {
|
|||||||
is_static: bool = false, // true for `static name :: ...`
|
is_static: bool = false, // true for `static name :: ...`
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const JniFieldDecl = struct {
|
||||||
|
name: []const u8,
|
||||||
|
field_type: *Node, // type_expr node
|
||||||
|
};
|
||||||
|
|
||||||
pub const JniClassMember = union(enum) {
|
pub const JniClassMember = union(enum) {
|
||||||
method: JniMethodDecl,
|
method: JniMethodDecl,
|
||||||
|
field: JniFieldDecl,
|
||||||
extends: []const u8, // sx-side alias name (right of `#extends`)
|
extends: []const u8, // sx-side alias name (right of `#extends`)
|
||||||
implements: []const u8, // sx-side alias name (right of `#implements`)
|
implements: []const u8, // sx-side alias name (right of `#implements`)
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1071,13 +1071,28 @@ pub const Parser = struct {
|
|||||||
self.advance(); // consume `static`
|
self.advance(); // consume `static`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Field: name: Type; (instance field — JNI Get/Set<Type>Field)
|
||||||
// Method: name :: (args...) -> Ret;
|
// Method: name :: (args...) -> Ret;
|
||||||
// (Fields, #desc override land in later steps.)
|
|
||||||
if (self.current.tag != .identifier) {
|
if (self.current.tag != .identifier) {
|
||||||
return self.fail("expected method name in '#jni_class' body");
|
return self.fail("expected member name in '#jni_class' body");
|
||||||
}
|
}
|
||||||
const method_name = self.tokenSlice(self.current);
|
const member_name = self.tokenSlice(self.current);
|
||||||
self.advance();
|
self.advance();
|
||||||
|
|
||||||
|
if (self.current.tag == .colon) {
|
||||||
|
if (is_static) {
|
||||||
|
return self.fail("static fields not yet supported in '#jni_class' body");
|
||||||
|
}
|
||||||
|
self.advance(); // consume `:`
|
||||||
|
const field_type = try self.parseTypeExpr();
|
||||||
|
try self.expect(.semicolon);
|
||||||
|
try members.append(self.allocator, .{ .field = .{
|
||||||
|
.name = member_name,
|
||||||
|
.field_type = field_type,
|
||||||
|
} });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
try self.expect(.colon_colon);
|
try self.expect(.colon_colon);
|
||||||
try self.expect(.l_paren);
|
try self.expect(.l_paren);
|
||||||
|
|
||||||
@@ -1109,7 +1124,7 @@ pub const Parser = struct {
|
|||||||
try self.expect(.semicolon);
|
try self.expect(.semicolon);
|
||||||
|
|
||||||
try members.append(self.allocator, .{ .method = .{
|
try members.append(self.allocator, .{ .method = .{
|
||||||
.name = method_name,
|
.name = member_name,
|
||||||
.params = try param_types.toOwnedSlice(self.allocator),
|
.params = try param_types.toOwnedSlice(self.allocator),
|
||||||
.param_names = try param_names.toOwnedSlice(self.allocator),
|
.param_names = try param_names.toOwnedSlice(self.allocator),
|
||||||
.return_type = return_type,
|
.return_type = return_type,
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
1
|
0
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
/Users/agra/projects/sx/examples/ffi-jni-class-05-field.sx:12:6: error: expected '::'
|
parse-only ok
|
||||||
|
|||||||
Reference in New Issue
Block a user