std-c parser declaratorIsFunction and small fixes
This commit is contained in:
parent
8b713ce889
commit
83b4163591
@ -435,6 +435,12 @@ pub const Node = struct {
|
|||||||
pub const DeclaratorList = Root.DeclList;
|
pub const DeclaratorList = Root.DeclList;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub const RecordDeclarator = struct {
|
||||||
|
base: Node = Node{ .id = .RecordField },
|
||||||
|
declarator: *Declarator,
|
||||||
|
// bit_field_expr: ?*Expr,
|
||||||
|
};
|
||||||
|
|
||||||
pub const TypeQual = struct {
|
pub const TypeQual = struct {
|
||||||
@"const": ?TokenIndex = null,
|
@"const": ?TokenIndex = null,
|
||||||
atomic: ?TokenIndex = null,
|
atomic: ?TokenIndex = null,
|
||||||
|
@ -124,7 +124,7 @@ const Parser = struct {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn declareSymbol(parser: *Parser, decl_spec: *Node.DeclSpec, dr: *Node.Declarator) Error!void {
|
fn declareSymbol(parser: *Parser, type_spec: Node.TypeSpec, dr: *Node.Declarator) Error!void {
|
||||||
return; // TODO
|
return; // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,7 +185,7 @@ const Parser = struct {
|
|||||||
const dr = @fieldParentPtr(Node.Declarator, "base", (try parser.declarator(.Must)) orelse return parser.err(.{
|
const dr = @fieldParentPtr(Node.Declarator, "base", (try parser.declarator(.Must)) orelse return parser.err(.{
|
||||||
.ExpectedDeclarator = .{ .token = parser.it.index },
|
.ExpectedDeclarator = .{ .token = parser.it.index },
|
||||||
}));
|
}));
|
||||||
try parser.declareSymbol(&ds, dr);
|
try parser.declareSymbol(ds.type_spec, dr);
|
||||||
try node.declarators.push(&dr.base);
|
try node.declarators.push(&dr.base);
|
||||||
if (parser.eatToken(.Comma)) |_| {} else break;
|
if (parser.eatToken(.Comma)) |_| {} else break;
|
||||||
}
|
}
|
||||||
@ -196,7 +196,7 @@ const Parser = struct {
|
|||||||
var first_dr = try parser.declarator(.Must);
|
var first_dr = try parser.declarator(.Must);
|
||||||
if (first_dr != null and declaratorIsFunction(first_dr.?)) {
|
if (first_dr != null and declaratorIsFunction(first_dr.?)) {
|
||||||
const dr = @fieldParentPtr(Node.Declarator, "base", first_dr.?);
|
const dr = @fieldParentPtr(Node.Declarator, "base", first_dr.?);
|
||||||
try parser.declareSymbol(&ds, dr);
|
try parser.declareSymbol(ds.type_spec, dr);
|
||||||
var old_decls = Node.FnDecl.OldDeclList.init(parser.arena);
|
var old_decls = Node.FnDecl.OldDeclList.init(parser.arena);
|
||||||
const body = if (parser.eatToken(.Semicolon)) |_|
|
const body = if (parser.eatToken(.Semicolon)) |_|
|
||||||
null
|
null
|
||||||
@ -263,7 +263,7 @@ const Parser = struct {
|
|||||||
}
|
}
|
||||||
var dr = @fieldParentPtr(Node.Declarator, "base", first_dr.?);
|
var dr = @fieldParentPtr(Node.Declarator, "base", first_dr.?);
|
||||||
while (true) {
|
while (true) {
|
||||||
try parser.declareSymbol(&ds, dr);
|
try parser.declareSymbol(ds.type_spec, dr);
|
||||||
if (parser.eatToken(.Equal)) |tok| {
|
if (parser.eatToken(.Equal)) |tok| {
|
||||||
try node.initializers.push((try parser.initializer(dr)) orelse return parser.err(.{
|
try node.initializers.push((try parser.initializer(dr)) orelse return parser.err(.{
|
||||||
.ExpectedInitializer = .{ .token = parser.it.index },
|
.ExpectedInitializer = .{ .token = parser.it.index },
|
||||||
@ -280,8 +280,27 @@ const Parser = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn declaratorIsFunction(dr: *Node) bool {
|
fn declaratorIsFunction(node: *Node) bool {
|
||||||
return false; // TODO
|
if (node.id != .Declarator) return false;
|
||||||
|
assert(node.id == .Declarator);
|
||||||
|
const dr = @fieldParentPtr(Node.Declarator, "base", node);
|
||||||
|
if (dr.suffix != .Fn) return false;
|
||||||
|
switch (dr.prefix) {
|
||||||
|
.None, .Identifer => return true,
|
||||||
|
.Complex => |inner| {
|
||||||
|
var inner_node = inner.inner;
|
||||||
|
while (true) {
|
||||||
|
if (inner_node.id != .Declarator) return false;
|
||||||
|
assert(inner_node.id == .Declarator);
|
||||||
|
const inner_dr = @fieldParentPtr(Node.Declarator, "base", inner_node);
|
||||||
|
if (inner_dr.pointer != null) return false;
|
||||||
|
switch (inner_dr.prefix) {
|
||||||
|
.None, .Identifer => return true,
|
||||||
|
.Complex => |c| inner_node = c.inner,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// StaticAssert <- Keyword_static_assert LPAREN ConstExpr COMMA STRINGLITERAL RPAREN SEMICOLON
|
/// StaticAssert <- Keyword_static_assert LPAREN ConstExpr COMMA STRINGLITERAL RPAREN SEMICOLON
|
||||||
@ -292,12 +311,11 @@ const Parser = struct {
|
|||||||
_ = try parser.expectToken(.Comma);
|
_ = try parser.expectToken(.Comma);
|
||||||
const str = try parser.expectToken(.StringLiteral);
|
const str = try parser.expectToken(.StringLiteral);
|
||||||
_ = try parser.expectToken(.RParen);
|
_ = try parser.expectToken(.RParen);
|
||||||
const semicolon = try parser.expectToken(.Semicolon);
|
|
||||||
const node = try parser.arena.create(Node.StaticAssert);
|
const node = try parser.arena.create(Node.StaticAssert);
|
||||||
node.* = .{
|
node.* = .{
|
||||||
.assert = tok,
|
.assert = tok,
|
||||||
.expr = const_expr,
|
.expr = const_expr,
|
||||||
.semicolon = semicolon,
|
.semicolon = try parser.expectToken(.Semicolon),
|
||||||
};
|
};
|
||||||
return &node.base;
|
return &node.base;
|
||||||
}
|
}
|
||||||
@ -761,6 +779,8 @@ const Parser = struct {
|
|||||||
.ty = ty,
|
.ty = ty,
|
||||||
});
|
});
|
||||||
if (parser.eatToken(.LBrace)) |lbrace| {
|
if (parser.eatToken(.LBrace)) |lbrace| {
|
||||||
|
const scope = parser.pushScope();
|
||||||
|
defer parser.popScope(scope);
|
||||||
var fields = Node.RecordType.FieldList.init(parser.arena);
|
var fields = Node.RecordType.FieldList.init(parser.arena);
|
||||||
while (true) {
|
while (true) {
|
||||||
if (parser.eatToken(.RBrace)) |rbrace| {
|
if (parser.eatToken(.RBrace)) |rbrace| {
|
||||||
@ -796,7 +816,9 @@ const Parser = struct {
|
|||||||
.semicolon = undefined,
|
.semicolon = undefined,
|
||||||
};
|
};
|
||||||
while (true) {
|
while (true) {
|
||||||
try node.declarators.push(try parser.recordDeclarator());
|
const rdr = try parser.recordDeclarator();
|
||||||
|
try parser.declareSymbol(type_spec, rdr.declarator);
|
||||||
|
try node.declarators.push(&rdr.base);
|
||||||
if (parser.eatToken(.Comma)) |_| {} else break;
|
if (parser.eatToken(.Comma)) |_| {} else break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -836,16 +858,19 @@ const Parser = struct {
|
|||||||
/// / LPAREN Declarator RPAREN
|
/// / LPAREN Declarator RPAREN
|
||||||
/// / (none) // if named != .Must
|
/// / (none) // if named != .Must
|
||||||
/// DeclaratorSuffix
|
/// DeclaratorSuffix
|
||||||
/// <. DeclaratorPrefix (LBRACKET ArrayDeclarator? RBRACKET)*
|
/// <- DeclaratorPrefix (LBRACKET ArrayDeclarator? RBRACKET)*
|
||||||
/// / DeclaratorPrefix LPAREN (ParamDecl (COMMA ParamDecl)* (COMMA ELLIPSIS)?)? RPAREN
|
/// / DeclaratorPrefix LPAREN (ParamDecl (COMMA ParamDecl)* (COMMA ELLIPSIS)?)? RPAREN
|
||||||
fn declarator(parser: *Parser, named: Named) Error!?*Node {
|
fn declarator(parser: *Parser, named: Named) Error!?*Node {
|
||||||
const ptr = try parser.pointer();
|
const ptr = try parser.pointer();
|
||||||
var node: *Node.Declarator = undefined;
|
var node: *Node.Declarator = undefined;
|
||||||
|
var inner_fn = false;
|
||||||
|
|
||||||
// prefix
|
// prefix
|
||||||
if (parser.eatToken(.LParen)) |lparen| {
|
if (parser.eatToken(.LParen)) |lparen| {
|
||||||
const inner = (try parser.declarator(named)) orelse return parser.err(.{
|
const inner = (try parser.declarator(named)) orelse return parser.err(.{
|
||||||
.ExpectedDeclarator = .{ .token = lparen + 1 },
|
.ExpectedDeclarator = .{ .token = lparen + 1 },
|
||||||
});
|
});
|
||||||
|
inner_fn = declaratorIsFunction(inner);
|
||||||
node = try parser.arena.create(Node.Declarator);
|
node = try parser.arena.create(Node.Declarator);
|
||||||
node.* = .{
|
node.* = .{
|
||||||
.pointer = ptr,
|
.pointer = ptr,
|
||||||
@ -885,6 +910,10 @@ const Parser = struct {
|
|||||||
}
|
}
|
||||||
// suffix
|
// suffix
|
||||||
if (parser.eatToken(.LParen)) |lparen| {
|
if (parser.eatToken(.LParen)) |lparen| {
|
||||||
|
if (inner_fn)
|
||||||
|
return parser.err(.{
|
||||||
|
.InvalidDeclarator = .{ .token = lparen },
|
||||||
|
});
|
||||||
node.suffix = .{
|
node.suffix = .{
|
||||||
.Fn = .{
|
.Fn = .{
|
||||||
.lparen = lparen,
|
.lparen = lparen,
|
||||||
@ -894,11 +923,16 @@ const Parser = struct {
|
|||||||
};
|
};
|
||||||
try parser.paramDecl(node);
|
try parser.paramDecl(node);
|
||||||
node.suffix.Fn.rparen = try parser.expectToken(.RParen);
|
node.suffix.Fn.rparen = try parser.expectToken(.RParen);
|
||||||
} else {
|
} else if (parser.eatToken(.LBracket)) |tok| {
|
||||||
while (try parser.arrayDeclarator()) |arr| {
|
if (inner_fn)
|
||||||
if (node.suffix == .None)
|
return parser.err(.{
|
||||||
|
.InvalidDeclarator = .{ .token = tok },
|
||||||
|
});
|
||||||
node.suffix = .{ .Array = Node.Declarator.Arrays.init(parser.arena) };
|
node.suffix = .{ .Array = Node.Declarator.Arrays.init(parser.arena) };
|
||||||
try node.suffix.Array.push(arr);
|
var lbrace = tok;
|
||||||
|
while (true) {
|
||||||
|
try node.suffix.Array.push(try parser.arrayDeclarator(lbrace));
|
||||||
|
if (parser.eatToken(.LBracket)) |t| lbrace = t else break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (parser.eatToken(.LParen) orelse parser.eatToken(.LBracket)) |tok|
|
if (parser.eatToken(.LParen) orelse parser.eatToken(.LBracket)) |tok|
|
||||||
@ -914,8 +948,7 @@ const Parser = struct {
|
|||||||
/// / TypeQual+ (ASTERISK / Keyword_static AssignmentExpr)
|
/// / TypeQual+ (ASTERISK / Keyword_static AssignmentExpr)
|
||||||
/// / TypeQual+ AssignmentExpr?
|
/// / TypeQual+ AssignmentExpr?
|
||||||
/// / AssignmentExpr
|
/// / AssignmentExpr
|
||||||
fn arrayDeclarator(parser: *Parser) !?*Node.Array {
|
fn arrayDeclarator(parser: *Parser, lbracket: TokenIndex) !*Node.Array {
|
||||||
const lbracket = parser.eatToken(.LBracket) orelse return null;
|
|
||||||
const arr = try parser.arena.create(Node.Array);
|
const arr = try parser.arena.create(Node.Array);
|
||||||
arr.* = .{
|
arr.* = .{
|
||||||
.lbracket = lbracket,
|
.lbracket = lbracket,
|
||||||
@ -1046,6 +1079,8 @@ const Parser = struct {
|
|||||||
|
|
||||||
/// CompoundStmt <- LBRACE (Declaration / Stmt)* RBRACE
|
/// CompoundStmt <- LBRACE (Declaration / Stmt)* RBRACE
|
||||||
fn compoundStmt(parser: *Parser) Error!?*Node {
|
fn compoundStmt(parser: *Parser) Error!?*Node {
|
||||||
|
const scope = parser.pushScope();
|
||||||
|
defer parser.popScope(scope);
|
||||||
const lbrace = parser.eatToken(.LBrace) orelse return null;
|
const lbrace = parser.eatToken(.LBrace) orelse return null;
|
||||||
const body_node = try parser.arena.create(Node.CompoundStmt);
|
const body_node = try parser.arena.create(Node.CompoundStmt);
|
||||||
body_node.* = .{
|
body_node.* = .{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user