Commit 0b9247fb63
Changed files (2)
std
std/zig/ast.zig
@@ -18,6 +18,7 @@ pub const Node = struct {
InfixOp,
PrefixOp,
SuffixOp,
+ FieldInitializer,
IntegerLiteral,
FloatLiteral,
StringLiteral,
@@ -45,6 +46,7 @@ pub const Node = struct {
Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).iterate(index),
Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).iterate(index),
Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).iterate(index),
+ Id.FieldInitializer => @fieldParentPtr(NodeFieldInitializer, "base", base).iterate(index),
Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).iterate(index),
Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).iterate(index),
Id.StringLiteral => @fieldParentPtr(NodeStringLiteral, "base", base).iterate(index),
@@ -73,6 +75,7 @@ pub const Node = struct {
Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).firstToken(),
Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).firstToken(),
Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).firstToken(),
+ Id.FieldInitializer => @fieldParentPtr(NodeFieldInitializer, "base", base).firstToken(),
Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).firstToken(),
Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).firstToken(),
Id.StringLiteral => @fieldParentPtr(NodeStringLiteral, "base", base).firstToken(),
@@ -101,6 +104,7 @@ pub const Node = struct {
Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).lastToken(),
Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).lastToken(),
Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).lastToken(),
+ Id.FieldInitializer => @fieldParentPtr(NodeFieldInitializer, "base", base).lastToken(),
Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).lastToken(),
Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).lastToken(),
Id.StringLiteral => @fieldParentPtr(NodeStringLiteral, "base", base).lastToken(),
@@ -526,6 +530,30 @@ pub const NodePrefixOp = struct {
}
};
+pub const NodeFieldInitializer = struct {
+ base: Node,
+ dot_token: Token,
+ name_token: Token,
+ expr: &Node,
+
+ pub fn iterate(self: &NodeFieldInitializer, index: usize) ?&Node {
+ var i = index;
+
+ if (i < 1) return self.expr;
+ i -= 1;
+
+ return null;
+ }
+
+ pub fn firstToken(self: &NodeFieldInitializer) Token {
+ return self.dot_token;
+ }
+
+ pub fn lastToken(self: &NodeFieldInitializer) Token {
+ return self.expr.lastToken();
+ }
+};
+
pub const NodeSuffixOp = struct {
base: Node,
lhs: &Node,
@@ -537,7 +565,7 @@ pub const NodeSuffixOp = struct {
ArrayAccess: &Node,
Slice: SliceRange,
ArrayInitializer: ArrayList(&Node),
- StructInitializer: ArrayList(&Node),
+ StructInitializer: ArrayList(&NodeFieldInitializer),
};
const CallInfo = struct {
std/zig/parser.zig
@@ -77,6 +77,12 @@ pub const Parser = struct {
ptr: &Token,
};
+ const ExprListState = struct {
+ list: &ArrayList(&ast.Node),
+ end: Token.Id,
+ ptr: &Token,
+ };
+
const State = union(enum) {
TopLevel,
TopLevelExtern: ?Token,
@@ -88,7 +94,7 @@ pub const Parser = struct {
InfixOp: &ast.NodeInfixOp,
PrefixOp: &ast.NodePrefixOp,
SuffixOp: &ast.NodeSuffixOp,
- SliceOrArrayAccess,
+ SliceOrArrayAccess: &ast.NodeSuffixOp,
AddrOfModifiers: &ast.NodePrefixOp.AddrOfInfo,
TypeExpr: DestPtr,
VarDecl: &ast.NodeVarDecl,
@@ -104,8 +110,8 @@ pub const Parser = struct {
FnDef: &ast.NodeFnProto,
Block: &ast.NodeBlock,
Statement: &ast.NodeBlock,
- ExprListItemOrEnd: &ArrayList(&ast.Node),
- ExprListCommaOrEnd: &ArrayList(&ast.Node),
+ ExprListItemOrEnd: ExprListState,
+ ExprListCommaOrEnd: ExprListState,
};
/// Returns an AST tree, allocated with the parser's allocator.
@@ -529,13 +535,14 @@ pub const Parser = struct {
.Operand = &node.base
});
try stack.append(State.AfterOperand);
- try stack.append(State {.ExprListItemOrEnd = &node.params });
try stack.append(State {
- .ExpectTokenSave = ExpectTokenSave {
- .id = Token.Id.LParen,
+ .ExprListItemOrEnd = ExprListState {
+ .list = &node.params,
+ .end = Token.Id.RParen,
.ptr = &node.rparen_token,
- },
+ }
});
+ try stack.append(State { .ExpectToken = Token.Id.LParen, });
continue;
},
Token.Id.StringLiteral => {
@@ -587,6 +594,46 @@ pub const Parser = struct {
}
},
+ State.SliceOrArrayAccess => |node| {
+ var token = self.getNextToken();
+
+ switch (token.id) {
+ Token.Id.Ellipsis2 => {
+ const start = node.op.ArrayAccess;
+ node.op = ast.NodeSuffixOp.SuffixOp {
+ .Slice = ast.NodeSuffixOp.SliceRange {
+ .start = start,
+ .end = undefined,
+ }
+ };
+ try stack.append(State { .SuffixOp = node });
+ try stack.append(State.AfterOperand);
+
+ const rbracket_token = self.getNextToken();
+ if (rbracket_token.id != Token.Id.RBracket) {
+ self.putBackToken(rbracket_token);
+ try stack.append(State {
+ .ExpectTokenSave = ExpectTokenSave {
+ .id = Token.Id.RBracket,
+ .ptr = &node.rtoken,
+ }
+ });
+ try stack.append(State { .Expression = DestPtr { .NullableField = &node.op.Slice.end } });
+ } else {
+ node.rtoken = rbracket_token;
+ }
+ continue;
+ },
+ Token.Id.RBracket => {
+ node.rtoken = token;
+ try stack.append(State { .SuffixOp = node });
+ try stack.append(State.AfterOperand);
+ continue;
+ },
+ else => return self.parseError(token, "expected ']' or '..', found {}", @tagName(token.id))
+ }
+ },
+
State.AfterOperand => {
// we'll either get an infix operator (like != or ^),
// or a postfix operator (like () or {}),
@@ -610,7 +657,13 @@ pub const Parser = struct {
});
try stack.append(State { .SuffixOp = node });
try stack.append(State.AfterOperand);
- try stack.append(State {.ExprListItemOrEnd = &node.op.Call.params });
+ try stack.append(State {
+ .ExprListItemOrEnd = ExprListState {
+ .list = &node.op.Call.params,
+ .end = Token.Id.RParen,
+ .ptr = &node.rtoken,
+ }
+ });
try stack.append(State {
.ExpectTokenSave = ExpectTokenSave {
.id = Token.Id.LParen,
@@ -620,8 +673,17 @@ pub const Parser = struct {
continue;
} else if (token.id == Token.Id.LBracket) {
- try stack.append(State.SliceOrArrayAccess);
- try stack.append(State.ExpectOperand);
+ const node = try arena.create(ast.NodeSuffixOp);
+ *node = ast.NodeSuffixOp {
+ .base = self.initNode(ast.Node.Id.SuffixOp),
+ .lhs = undefined,
+ .op = ast.NodeSuffixOp.SuffixOp {
+ .ArrayAccess = undefined,
+ },
+ .rtoken = undefined,
+ };
+ try stack.append(State { .SliceOrArrayAccess = node });
+ try stack.append(State { .Expression = DestPtr { .Field = &node.op.ArrayAccess }});
continue;
// TODO: Parse postfix operator
@@ -637,48 +699,6 @@ pub const Parser = struct {
try dest_ptr.store(expression);
break;
},
- State.SliceOrArrayAccess => {
- var rbracket_or_ellipsis2_token = self.getNextToken();
-
- switch (rbracket_or_ellipsis2_token.id) {
- Token.Id.Ellipsis2 => {
- const node = try self.createSuffixOp(arena, ast.NodeSuffixOp.SuffixOp {
- .Slice = ast.NodeSuffixOp.SliceRange {
- .start = expression,
- .end = null,
- }
- });
-
- try stack.append(State { .SuffixOp = node });
- try stack.append(State.AfterOperand);
-
- const rbracket_token = self.getNextToken();
- if (rbracket_token.id != Token.Id.RBracket) {
- self.putBackToken(rbracket_token);
- try stack.append(State {
- .ExpectTokenSave = ExpectTokenSave {
- .id = Token.Id.RBracket,
- .ptr = &node.rtoken,
- }
- });
- try stack.append(State { .Expression = DestPtr { .NullableField = &node.op.Slice.end } });
- } else {
- node.rtoken = rbracket_token;
- }
- break;
- },
- Token.Id.RBracket => {
- const node = try self.createSuffixOp(arena, ast.NodeSuffixOp.SuffixOp {
- .ArrayAccess = expression
- });
- node.rtoken = token;
- try stack.append(State { .SuffixOp = node });
- try stack.append(State.AfterOperand);
- break;
- },
- else => return self.parseError(token, "expected ']' or '..', found {}", @tagName(token.id))
- }
- },
State.InfixOp => |infix_op| {
infix_op.rhs = expression;
infix_op.lhs = popSuffixOp(&stack);
@@ -697,26 +717,31 @@ pub const Parser = struct {
}
},
- State.ExprListItemOrEnd => |params| {
+ State.ExprListItemOrEnd => |expr_list_state| {
var token = self.getNextToken();
switch (token.id) {
Token.Id.RParen => continue,
else => {
self.putBackToken(token);
- stack.append(State { .ExprListCommaOrEnd = params }) catch unreachable;
- try stack.append(State { .Expression = DestPtr{.List = params} });
+ stack.append(State { .ExprListCommaOrEnd = expr_list_state }) catch unreachable;
+ try stack.append(State { .Expression = DestPtr{.List = expr_list_state.list} });
},
}
},
- State.ExprListCommaOrEnd => |params| {
+ State.ExprListCommaOrEnd => |expr_list_state| {
var token = self.getNextToken();
switch (token.id) {
Token.Id.Comma => {
- stack.append(State { .ExprListItemOrEnd = params }) catch unreachable;
+ stack.append(State { .ExprListItemOrEnd = expr_list_state }) catch unreachable;
+ },
+ else => {
+ const IdTag = @TagType(Token.Id);
+ if (IdTag(expr_list_state.end) == token.id)
+ continue;
+
+ return self.parseError(token, "expected ',' or {}, found {}", @tagName(expr_list_state.end), @tagName(token.id));
},
- Token.Id.RParen => continue,
- else => return self.parseError(token, "expected ',' or ')', found {}", @tagName(token.id)),
}
},
@@ -933,7 +958,6 @@ pub const Parser = struct {
State.PrefixOp => unreachable,
State.SuffixOp => unreachable,
State.Operand => unreachable,
- State.SliceOrArrayAccess => unreachable,
}
}
}
@@ -1649,6 +1673,11 @@ pub const Parser = struct {
try stack.append(RenderState { .Expression = suffix_op.lhs });
},
+ ast.Node.Id.FieldInitializer => {
+ const field_init = @fieldParentPtr(ast.NodeFieldInitializer, "base", base);
+ try stream.print(".{} = ", self.tokenizer.getTokenSlice(field_init.name_token));
+ try stack.append(RenderState { .Expression = field_init.expr });
+ },
ast.Node.Id.IntegerLiteral => {
const integer_literal = @fieldParentPtr(ast.NodeIntegerLiteral, "base", base);
try stream.print("{}", self.tokenizer.getTokenSlice(integer_literal.token));