Commit b424cd75ab
Changed files (2)
std
std/zig/ast.zig
@@ -17,6 +17,7 @@ pub const Node = struct {
Block,
InfixOp,
PrefixOp,
+ SuffixOp,
IntegerLiteral,
FloatLiteral,
StringLiteral,
@@ -29,9 +30,6 @@ pub const Node = struct {
Unreachable,
ErrorType,
BuiltinCall,
- Call,
- ArrayAccess,
- SliceExpression,
LineComment,
TestDecl,
};
@@ -46,6 +44,7 @@ pub const Node = struct {
Id.Block => @fieldParentPtr(NodeBlock, "base", base).iterate(index),
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.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).iterate(index),
Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).iterate(index),
Id.StringLiteral => @fieldParentPtr(NodeStringLiteral, "base", base).iterate(index),
@@ -58,9 +57,6 @@ pub const Node = struct {
Id.Unreachable => @fieldParentPtr(NodeUnreachable, "base", base).iterate(index),
Id.ErrorType => @fieldParentPtr(NodeErrorType, "base", base).iterate(index),
Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).iterate(index),
- Id.Call => @fieldParentPtr(NodeCall, "base", base).iterate(index),
- Id.ArrayAccess => @fieldParentPtr(NodeArrayAccess, "base", base).iterate(index),
- Id.SliceExpression => @fieldParentPtr(NodeSliceExpression, "base", base).iterate(index),
Id.LineComment => @fieldParentPtr(NodeLineComment, "base", base).iterate(index),
Id.TestDecl => @fieldParentPtr(NodeTestDecl, "base", base).iterate(index),
};
@@ -76,6 +72,7 @@ pub const Node = struct {
Id.Block => @fieldParentPtr(NodeBlock, "base", base).firstToken(),
Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).firstToken(),
Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).firstToken(),
+ Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).firstToken(),
Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).firstToken(),
Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).firstToken(),
Id.StringLiteral => @fieldParentPtr(NodeStringLiteral, "base", base).firstToken(),
@@ -88,9 +85,6 @@ pub const Node = struct {
Id.ThisLiteral => @fieldParentPtr(NodeThisLiteral, "base", base).firstToken(),
Id.ErrorType => @fieldParentPtr(NodeErrorType, "base", base).firstToken(),
Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).firstToken(),
- Id.Call => @fieldParentPtr(NodeCall, "base", base).firstToken(),
- Id.ArrayAccess => @fieldParentPtr(NodeArrayAccess, "base", base).firstToken(),
- Id.SliceExpression => @fieldParentPtr(NodeSliceExpression, "base", base).firstToken(),
Id.LineComment => @fieldParentPtr(NodeLineComment, "base", base).firstToken(),
Id.TestDecl => @fieldParentPtr(NodeTestDecl, "base", base).firstToken(),
};
@@ -106,6 +100,7 @@ pub const Node = struct {
Id.Block => @fieldParentPtr(NodeBlock, "base", base).lastToken(),
Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).lastToken(),
Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).lastToken(),
+ Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).lastToken(),
Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).lastToken(),
Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).lastToken(),
Id.StringLiteral => @fieldParentPtr(NodeStringLiteral, "base", base).lastToken(),
@@ -118,9 +113,6 @@ pub const Node = struct {
Id.Unreachable => @fieldParentPtr(NodeUnreachable, "base", base).lastToken(),
Id.ErrorType => @fieldParentPtr(NodeErrorType, "base", base).lastToken(),
Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).lastToken(),
- Id.Call => @fieldParentPtr(NodeCall, "base", base).lastToken(),
- Id.ArrayAccess => @fieldParentPtr(NodeArrayAccess, "base", base).lastToken(),
- Id.SliceExpression => @fieldParentPtr(NodeSliceExpression, "base", base).lastToken(),
Id.LineComment => @fieldParentPtr(NodeLineComment, "base", base).lastToken(),
Id.TestDecl => @fieldParentPtr(NodeTestDecl, "base", base).lastToken(),
};
@@ -493,20 +485,28 @@ pub const NodePrefixOp = struct {
var i = index;
switch (self.op) {
+ PrefixOp.SliceType => |addr_of_info| {
+ if (addr_of_info.align_expr) |align_expr| {
+ if (i < 1) return align_expr;
+ i -= 1;
+ }
+ },
PrefixOp.AddrOf => |addr_of_info| {
if (addr_of_info.align_expr) |align_expr| {
if (i < 1) return align_expr;
i -= 1;
}
},
+ PrefixOp.ArrayType => |size_expr| {
+ if (i < 1) return size_expr;
+ i -= 1;
+ },
PrefixOp.BitNot,
PrefixOp.BoolNot,
PrefixOp.Deref,
PrefixOp.Negation,
PrefixOp.NegationWrap,
PrefixOp.Return,
- PrefixOp.ArrayType,
- PrefixOp.SliceType,
PrefixOp.Try,
PrefixOp.UnwrapMaybe => {},
}
@@ -526,6 +526,76 @@ pub const NodePrefixOp = struct {
}
};
+pub const NodeSuffixOp = struct {
+ base: Node,
+ lhs: &Node,
+ op: SuffixOp,
+ rtoken: Token,
+
+ const SuffixOp = union(enum) {
+ Call: CallInfo,
+ ArrayAccess: &Node,
+ Slice: SliceRange,
+ ArrayInitializer: ArrayList(&Node),
+ StructInitializer: ArrayList(&Node),
+ };
+
+ const CallInfo = struct {
+ params: ArrayList(&Node),
+ is_async: bool,
+ };
+
+ const SliceRange = struct {
+ start: &Node,
+ end: ?&Node,
+ };
+
+ pub fn iterate(self: &NodeSuffixOp, index: usize) ?&Node {
+ var i = index;
+
+ if (i < 1) return self.lhs;
+ i -= 1;
+
+ switch (self.op) {
+ SuffixOp.Call => |call_info| {
+ if (i < call_info.params.len) return call_info.params.at(i);
+ i -= call_info.params.len;
+ },
+ SuffixOp.ArrayAccess => |index_expr| {
+ if (i < 1) return index_expr;
+ i -= 1;
+ },
+ SuffixOp.Slice => |range| {
+ if (i < 1) return range.start;
+ i -= 1;
+
+ if (range.end) |end| {
+ if (i < 1) return end;
+ i -= 1;
+ }
+ },
+ SuffixOp.ArrayInitializer => |exprs| {
+ if (i < exprs.len) return exprs.at(i);
+ i -= exprs.len;
+ },
+ SuffixOp.StructInitializer => |fields| {
+ if (i < fields.len) return fields.at(i);
+ i -= fields.len;
+ },
+ }
+
+ return null;
+ }
+
+ pub fn firstToken(self: &NodeSuffixOp) Token {
+ return self.lhs.firstToken();
+ }
+
+ pub fn lastToken(self: &NodeSuffixOp) Token {
+ return self.rtoken;
+ }
+};
+
pub const NodeIntegerLiteral = struct {
base: Node,
token: Token,
@@ -584,91 +654,6 @@ pub const NodeBuiltinCall = struct {
}
};
-pub const NodeCall = struct {
- base: Node,
- callee: &Node,
- params: ArrayList(&Node),
- rparen_token: Token,
-
- pub fn iterate(self: &NodeCall, index: usize) ?&Node {
- var i = index;
-
- if (i < 1) return self.callee;
- i -= 1;
-
- if (i < self.params.len) return self.params.at(i);
- i -= self.params.len;
-
- return null;
- }
-
- pub fn firstToken(self: &NodeCall) Token {
- return self.callee.firstToken();
- }
-
- pub fn lastToken(self: &NodeCall) Token {
- return self.rparen_token;
- }
-};
-
-pub const NodeArrayAccess = struct {
- base: Node,
- expr: &Node,
- index: &Node,
- rbracket_token: Token,
-
- pub fn iterate(self: &NodeArrayAccess, index: usize) ?&Node {
- var i = index;
-
- if (i < 1) return self.expr;
- i -= 1;
-
- if (i < 1) return self.index;
- i -= 1;
-
- return null;
- }
-
- pub fn firstToken(self: &NodeArrayAccess) Token {
- return self.expr.firstToken();
- }
-
- pub fn lastToken(self: &NodeArrayAccess) Token {
- return self.rbracket_token;
- }
-};
-
-pub const NodeSliceExpression = struct {
- base: Node,
- expr: &Node,
- start: &Node,
- end: ?&Node,
- rbracket_token: Token,
-
- pub fn iterate(self: &NodeSliceExpression, index: usize) ?&Node {
- var i = index;
-
- if (i < 1) return self.callee;
- i -= 1;
-
- if (i < 1) return self.start;
- i -= 1;
-
- if (i < 1) return self.end;
- i -= 1;
-
- return null;
- }
-
- pub fn firstToken(self: &NodeSliceExpression) Token {
- return self.expr.firstToken();
- }
-
- pub fn lastToken(self: &NodeSliceExpression) Token {
- return self.rbracket_token;
- }
-};
-
pub const NodeStringLiteral = struct {
base: Node,
token: Token,
std/zig/parser.zig
@@ -87,7 +87,7 @@ pub const Parser = struct {
AfterOperand,
InfixOp: &ast.NodeInfixOp,
PrefixOp: &ast.NodePrefixOp,
- SuffixOp: &ast.Node,
+ SuffixOp: &ast.NodeSuffixOp,
SliceOrArrayAccess,
AddrOfModifiers: &ast.NodePrefixOp.AddrOfInfo,
TypeExpr: DestPtr,
@@ -602,20 +602,19 @@ pub const Parser = struct {
} else if (token.id == Token.Id.LParen) {
self.putBackToken(token);
- const node = try arena.create(ast.NodeCall);
- *node = ast.NodeCall {
- .base = self.initNode(ast.Node.Id.Call),
- .callee = undefined,
- .params = ArrayList(&ast.Node).init(arena),
- .rparen_token = undefined,
- };
- try stack.append(State { .SuffixOp = &node.base });
+ const node = try self.createSuffixOp(arena, ast.NodeSuffixOp.SuffixOp {
+ .Call = ast.NodeSuffixOp.CallInfo {
+ .params = ArrayList(&ast.Node).init(arena),
+ .is_async = false, // TODO: ASYNC
+ }
+ });
+ try stack.append(State { .SuffixOp = node });
try stack.append(State.AfterOperand);
- try stack.append(State {.ExprListItemOrEnd = &node.params });
+ try stack.append(State {.ExprListItemOrEnd = &node.op.Call.params });
try stack.append(State {
.ExpectTokenSave = ExpectTokenSave {
.id = Token.Id.LParen,
- .ptr = &node.rparen_token,
+ .ptr = &node.rtoken,
},
});
continue;
@@ -643,16 +642,14 @@ pub const Parser = struct {
switch (rbracket_or_ellipsis2_token.id) {
Token.Id.Ellipsis2 => {
- const node = try arena.create(ast.NodeSliceExpression);
- *node = ast.NodeSliceExpression {
- .base = self.initNode(ast.Node.Id.SliceExpression),
- .expr = undefined,
- .start = expression,
- .end = null,
- .rbracket_token = undefined,
- };
-
- try stack.append(State { .SuffixOp = &node.base });
+ 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();
@@ -661,24 +658,21 @@ pub const Parser = struct {
try stack.append(State {
.ExpectTokenSave = ExpectTokenSave {
.id = Token.Id.RBracket,
- .ptr = &node.rbracket_token,
+ .ptr = &node.rtoken,
}
});
- try stack.append(State { .Expression = DestPtr { .NullableField = &node.end } });
+ try stack.append(State { .Expression = DestPtr { .NullableField = &node.op.Slice.end } });
} else {
- node.rbracket_token = rbracket_token;
+ node.rtoken = rbracket_token;
}
break;
},
Token.Id.RBracket => {
- const node = try arena.create(ast.NodeArrayAccess);
- *node = ast.NodeArrayAccess {
- .base = self.initNode(ast.Node.Id.ArrayAccess),
- .expr = undefined,
- .index = expression,
- .rbracket_token = token,
- };
- try stack.append(State { .SuffixOp = &node.base });
+ 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;
},
@@ -950,27 +944,8 @@ pub const Parser = struct {
while (true) {
switch (stack.pop()) {
State.SuffixOp => |suffix_op| {
- switch (suffix_op.id) {
- ast.Node.Id.Call => {
- const call = @fieldParentPtr(ast.NodeCall, "base", suffix_op);
- *left_leaf_ptr = &call.base;
- left_leaf_ptr = &call.callee;
- continue;
- },
- ast.Node.Id.ArrayAccess => {
- const arr_access = @fieldParentPtr(ast.NodeArrayAccess, "base", suffix_op);
- *left_leaf_ptr = &arr_access.base;
- left_leaf_ptr = &arr_access.expr;
- continue;
- },
- ast.Node.Id.SliceExpression => {
- const slice_expr = @fieldParentPtr(ast.NodeSliceExpression, "base", suffix_op);
- *left_leaf_ptr = &slice_expr.base;
- left_leaf_ptr = &slice_expr.expr;
- continue;
- },
- else => unreachable,
- }
+ *left_leaf_ptr = &suffix_op.base;
+ left_leaf_ptr = &suffix_op.lhs;
},
State.Operand => |operand| {
*left_leaf_ptr = operand;
@@ -1172,6 +1147,18 @@ pub const Parser = struct {
return node;
}
+ fn createSuffixOp(self: &Parser, arena: &mem.Allocator, op: &const ast.NodeSuffixOp.SuffixOp) !&ast.NodeSuffixOp {
+ const node = try arena.create(ast.NodeSuffixOp);
+
+ *node = ast.NodeSuffixOp {
+ .base = self.initNode(ast.Node.Id.SuffixOp),
+ .lhs = undefined,
+ .op = *op,
+ .rtoken = undefined,
+ };
+ return node;
+ }
+
fn createIdentifier(self: &Parser, arena: &mem.Allocator, name_token: &const Token) !&ast.NodeIdentifier {
const node = try arena.create(ast.NodeIdentifier);
@@ -1625,6 +1612,43 @@ pub const Parser = struct {
ast.NodePrefixOp.PrefixOp.UnwrapMaybe => try stream.write("??"),
}
},
+ ast.Node.Id.SuffixOp => {
+ const suffix_op = @fieldParentPtr(ast.NodeSuffixOp, "base", base);
+
+ switch (suffix_op.op) {
+ ast.NodeSuffixOp.SuffixOp.Call => |call_info| {
+ try stack.append(RenderState { .Text = ")"});
+ var i = call_info.params.len;
+ while (i != 0) {
+ i -= 1;
+ const param_node = call_info.params.at(i);
+ try stack.append(RenderState { .Expression = param_node});
+ if (i != 0) {
+ try stack.append(RenderState { .Text = ", " });
+ }
+ }
+ try stack.append(RenderState { .Text = "("});
+ },
+ ast.NodeSuffixOp.SuffixOp.ArrayAccess => |index_expr| {
+ try stack.append(RenderState { .Text = "]"});
+ try stack.append(RenderState { .Expression = index_expr});
+ try stack.append(RenderState { .Text = "["});
+ },
+ ast.NodeSuffixOp.SuffixOp.Slice => |range| {
+ try stack.append(RenderState { .Text = "]"});
+ if (range.end) |end| {
+ try stack.append(RenderState { .Expression = end});
+ }
+ try stack.append(RenderState { .Text = ".."});
+ try stack.append(RenderState { .Expression = range.start});
+ try stack.append(RenderState { .Text = "["});
+ },
+ ast.NodeSuffixOp.SuffixOp.StructInitializer => @panic("TODO: StructInitializer"),
+ ast.NodeSuffixOp.SuffixOp.ArrayInitializer => @panic("TODO: ArrayInitializer"),
+ }
+
+ try stack.append(RenderState { .Expression = suffix_op.lhs });
+ },
ast.Node.Id.IntegerLiteral => {
const integer_literal = @fieldParentPtr(ast.NodeIntegerLiteral, "base", base);
try stream.print("{}", self.tokenizer.getTokenSlice(integer_literal.token));
@@ -1693,39 +1717,6 @@ pub const Parser = struct {
}
}
},
- ast.Node.Id.Call => {
- const call = @fieldParentPtr(ast.NodeCall, "base", base);
- try stack.append(RenderState { .Text = ")"});
- var i = call.params.len;
- while (i != 0) {
- i -= 1;
- const param_node = call.params.at(i);
- try stack.append(RenderState { .Expression = param_node});
- if (i != 0) {
- try stack.append(RenderState { .Text = ", " });
- }
- }
- try stack.append(RenderState { .Text = "("});
- try stack.append(RenderState { .Expression = call.callee });
- },
- ast.Node.Id.ArrayAccess => {
- const arr_access = @fieldParentPtr(ast.NodeArrayAccess, "base", base);
- try stack.append(RenderState { .Text = "]"});
- try stack.append(RenderState { .Expression = arr_access.index});
- try stack.append(RenderState { .Text = "["});
- try stack.append(RenderState { .Expression = arr_access.expr });
- },
- ast.Node.Id.SliceExpression => {
- const slice_expr = @fieldParentPtr(ast.NodeSliceExpression, "base", base);
- try stack.append(RenderState { .Text = "]"});
- if (slice_expr.end) |end| {
- try stack.append(RenderState { .Expression = end});
- }
- try stack.append(RenderState { .Text = ".."});
- try stack.append(RenderState { .Expression = slice_expr.start});
- try stack.append(RenderState { .Text = "["});
- try stack.append(RenderState { .Expression = slice_expr.expr});
- },
ast.Node.Id.FnProto => @panic("TODO fn proto in an expression"),
ast.Node.Id.LineComment => @panic("TODO render line comment in an expression"),