Commit 6e57243a79
Changed files (3)
src
std
src/ir.cpp
@@ -6523,6 +6523,8 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop
case NodeTypeFieldAccessExpr:
{
IrInstruction *ptr_instruction = ir_gen_field_access(irb, scope, node);
+ if (ptr_instruction == irb->codegen->invalid_instruction)
+ return ptr_instruction;
if (lval.is_ptr)
return ptr_instruction;
@@ -15556,6 +15558,8 @@ static TypeTableEntry *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira,
}
ensure_complete_type(ira->codegen, container_type);
+ if (type_is_invalid(container_type))
+ return ira->codegen->builtin_types.entry_invalid;
TypeStructField *field = find_struct_type_field(container_type, field_name);
if (field == nullptr) {
std/zig/ast.zig
@@ -6,7 +6,6 @@ const mem = std.mem;
pub const Node = struct {
id: Id,
- comment: ?&NodeLineComment,
pub const Id = enum {
// Top level
@@ -74,1750 +73,1686 @@ pub const Node = struct {
FieldInitializer,
};
- const IdTypePair = struct {
- id: Id,
- Type: type,
- };
-
- // TODO: When @field exists, we could generate this by iterating over all members of `Id`,
- // and making an array of `IdTypePair { .id = @field(Id, @memberName(Id, i)), .Type = @field(ast, "Node" ++ @memberName(Id, i)) }`
- const idTypeTable = []IdTypePair {
- IdTypePair { .id = Id.Root, .Type = NodeRoot },
- IdTypePair { .id = Id.Use, .Type = NodeUse },
- IdTypePair { .id = Id.TestDecl, .Type = NodeTestDecl },
-
- IdTypePair { .id = Id.VarDecl, .Type = NodeVarDecl },
- IdTypePair { .id = Id.Defer, .Type = NodeDefer },
-
- IdTypePair { .id = Id.InfixOp, .Type = NodeInfixOp },
- IdTypePair { .id = Id.PrefixOp, .Type = NodePrefixOp },
- IdTypePair { .id = Id.SuffixOp, .Type = NodeSuffixOp },
-
- IdTypePair { .id = Id.Switch, .Type = NodeSwitch },
- IdTypePair { .id = Id.While, .Type = NodeWhile },
- IdTypePair { .id = Id.For, .Type = NodeFor },
- IdTypePair { .id = Id.If, .Type = NodeIf },
- IdTypePair { .id = Id.ControlFlowExpression, .Type = NodeControlFlowExpression },
- IdTypePair { .id = Id.Suspend, .Type = NodeSuspend },
-
- IdTypePair { .id = Id.VarType, .Type = NodeVarType },
- IdTypePair { .id = Id.ErrorType, .Type = NodeErrorType },
- IdTypePair { .id = Id.FnProto, .Type = NodeFnProto },
-
- IdTypePair { .id = Id.IntegerLiteral, .Type = NodeIntegerLiteral },
- IdTypePair { .id = Id.FloatLiteral, .Type = NodeFloatLiteral },
- IdTypePair { .id = Id.StringLiteral, .Type = NodeStringLiteral },
- IdTypePair { .id = Id.MultilineStringLiteral, .Type = NodeMultilineStringLiteral },
- IdTypePair { .id = Id.CharLiteral, .Type = NodeCharLiteral },
- IdTypePair { .id = Id.BoolLiteral, .Type = NodeBoolLiteral },
- IdTypePair { .id = Id.NullLiteral, .Type = NodeNullLiteral },
- IdTypePair { .id = Id.UndefinedLiteral, .Type = NodeUndefinedLiteral },
- IdTypePair { .id = Id.ThisLiteral, .Type = NodeThisLiteral },
- IdTypePair { .id = Id.Unreachable, .Type = NodeUnreachable },
- IdTypePair { .id = Id.Identifier, .Type = NodeIdentifier },
- IdTypePair { .id = Id.GroupedExpression, .Type = NodeGroupedExpression },
- IdTypePair { .id = Id.BuiltinCall, .Type = NodeBuiltinCall },
- IdTypePair { .id = Id.ErrorSetDecl, .Type = NodeErrorSetDecl },
- IdTypePair { .id = Id.ContainerDecl, .Type = NodeContainerDecl },
- IdTypePair { .id = Id.Asm, .Type = NodeAsm },
- IdTypePair { .id = Id.Comptime, .Type = NodeComptime },
- IdTypePair { .id = Id.Block, .Type = NodeBlock },
-
- IdTypePair { .id = Id.LineComment, .Type = NodeLineComment },
- IdTypePair { .id = Id.SwitchCase, .Type = NodeSwitchCase },
- IdTypePair { .id = Id.SwitchElse, .Type = NodeSwitchElse },
- IdTypePair { .id = Id.Else, .Type = NodeElse },
- IdTypePair { .id = Id.Payload, .Type = NodePayload },
- IdTypePair { .id = Id.PointerPayload, .Type = NodePointerPayload },
- IdTypePair { .id = Id.PointerIndexPayload, .Type = NodePointerIndexPayload },
- IdTypePair { .id = Id.StructField, .Type = NodeStructField },
- IdTypePair { .id = Id.UnionTag, .Type = NodeUnionTag },
- IdTypePair { .id = Id.EnumTag, .Type = NodeEnumTag },
- IdTypePair { .id = Id.AsmInput, .Type = NodeAsmInput },
- IdTypePair { .id = Id.AsmOutput, .Type = NodeAsmOutput },
- IdTypePair { .id = Id.AsyncAttribute, .Type = NodeAsyncAttribute },
- IdTypePair { .id = Id.ParamDecl, .Type = NodeParamDecl },
- IdTypePair { .id = Id.FieldInitializer, .Type = NodeFieldInitializer },
- };
-
- pub fn IdToType(comptime id: Id) type {
- inline for (idTypeTable) |id_type_pair| {
- if (id == id_type_pair.id)
- return id_type_pair.Type;
- }
-
- unreachable;
- }
-
- pub fn typeToId(comptime T: type) Id {
- inline for (idTypeTable) |id_type_pair| {
- if (T == id_type_pair.Type)
- return id_type_pair.id;
- }
-
- unreachable;
- }
-
pub fn iterate(base: &Node, index: usize) ?&Node {
- inline for (idTypeTable) |id_type_pair| {
- if (base.id == id_type_pair.id)
- return @fieldParentPtr(id_type_pair.Type, "base", base).iterate(index);
+ comptime var i = 0;
+ inline while (i < @memberCount(Id)) : (i += 1) {
+ if (base.id == @field(Id, @memberName(Id, i))) {
+ const T = @field(Node, @memberName(Id, i));
+ return @fieldParentPtr(T, "base", base).iterate(index);
+ }
}
-
unreachable;
}
pub fn firstToken(base: &Node) Token {
- inline for (idTypeTable) |id_type_pair| {
- if (base.id == id_type_pair.id)
- return @fieldParentPtr(id_type_pair.Type, "base", base).firstToken();
+ comptime var i = 0;
+ inline while (i < @memberCount(Id)) : (i += 1) {
+ if (base.id == @field(Id, @memberName(Id, i))) {
+ const T = @field(Node, @memberName(Id, i));
+ return @fieldParentPtr(T, "base", base).firstToken();
+ }
}
-
unreachable;
}
pub fn lastToken(base: &Node) Token {
- inline for (idTypeTable) |id_type_pair| {
- if (base.id == id_type_pair.id)
- return @fieldParentPtr(id_type_pair.Type, "base", base).lastToken();
+ comptime var i = 0;
+ inline while (i < @memberCount(Id)) : (i += 1) {
+ if (base.id == @field(Id, @memberName(Id, i))) {
+ const T = @field(Node, @memberName(Id, i));
+ return @fieldParentPtr(T, "base", base).lastToken();
+ }
}
-
unreachable;
}
-};
-pub const NodeRoot = struct {
- base: Node,
- decls: ArrayList(&Node),
- eof_token: Token,
-
- pub fn iterate(self: &NodeRoot, index: usize) ?&Node {
- if (index < self.decls.len) {
- return self.decls.items[self.decls.len - index - 1];
+ pub fn typeToId(comptime T: type) Id {
+ comptime var i = 0;
+ inline while (i < @memberCount(Id)) : (i += 1) {
+ if (T == @field(Node, @memberName(Id, i))) {
+ return @field(Id, @memberName(Id, i));
+ }
}
- return null;
- }
-
- pub fn firstToken(self: &NodeRoot) Token {
- return if (self.decls.len == 0) self.eof_token else self.decls.at(0).firstToken();
+ unreachable;
}
- pub fn lastToken(self: &NodeRoot) Token {
- return if (self.decls.len == 0) self.eof_token else self.decls.at(self.decls.len - 1).lastToken();
- }
-};
+ pub const Root = struct {
+ base: Node,
+ decls: ArrayList(&Node),
+ eof_token: Token,
-pub const NodeVarDecl = struct {
- base: Node,
- visib_token: ?Token,
- name_token: Token,
- eq_token: Token,
- mut_token: Token,
- comptime_token: ?Token,
- extern_export_token: ?Token,
- lib_name: ?&Node,
- type_node: ?&Node,
- align_node: ?&Node,
- init_node: ?&Node,
- semicolon_token: Token,
-
- pub fn iterate(self: &NodeVarDecl, index: usize) ?&Node {
- var i = index;
-
- if (self.type_node) |type_node| {
- if (i < 1) return type_node;
- i -= 1;
+ pub fn iterate(self: &Root, index: usize) ?&Node {
+ if (index < self.decls.len) {
+ return self.decls.items[self.decls.len - index - 1];
+ }
+ return null;
}
- if (self.align_node) |align_node| {
- if (i < 1) return align_node;
- i -= 1;
+ pub fn firstToken(self: &Root) Token {
+ return if (self.decls.len == 0) self.eof_token else self.decls.at(0).firstToken();
}
- if (self.init_node) |init_node| {
- if (i < 1) return init_node;
- i -= 1;
+ pub fn lastToken(self: &Root) Token {
+ return if (self.decls.len == 0) self.eof_token else self.decls.at(self.decls.len - 1).lastToken();
}
+ };
- return null;
- }
-
- pub fn firstToken(self: &NodeVarDecl) Token {
- if (self.visib_token) |visib_token| return visib_token;
- if (self.comptime_token) |comptime_token| return comptime_token;
- if (self.extern_export_token) |extern_export_token| return extern_export_token;
- assert(self.lib_name == null);
- return self.mut_token;
- }
-
- pub fn lastToken(self: &NodeVarDecl) Token {
- return self.semicolon_token;
- }
-};
-
-pub const NodeUse = struct {
- base: Node,
- visib_token: ?Token,
- expr: &Node,
- semicolon_token: Token,
-
- pub fn iterate(self: &NodeUse, index: usize) ?&Node {
- var i = index;
+ pub const VarDecl = struct {
+ base: Node,
+ comments: ?&LineComment,
+ visib_token: ?Token,
+ name_token: Token,
+ eq_token: Token,
+ mut_token: Token,
+ comptime_token: ?Token,
+ extern_export_token: ?Token,
+ lib_name: ?&Node,
+ type_node: ?&Node,
+ align_node: ?&Node,
+ init_node: ?&Node,
+ semicolon_token: Token,
+
+ pub fn iterate(self: &VarDecl, index: usize) ?&Node {
+ var i = index;
+
+ if (self.type_node) |type_node| {
+ if (i < 1) return type_node;
+ i -= 1;
+ }
- if (i < 1) return self.expr;
- i -= 1;
+ if (self.align_node) |align_node| {
+ if (i < 1) return align_node;
+ i -= 1;
+ }
- return null;
- }
+ if (self.init_node) |init_node| {
+ if (i < 1) return init_node;
+ i -= 1;
+ }
- pub fn firstToken(self: &NodeUse) Token {
- if (self.visib_token) |visib_token| return visib_token;
- return self.expr.firstToken();
- }
+ return null;
+ }
- pub fn lastToken(self: &NodeUse) Token {
- return self.semicolon_token;
- }
-};
+ pub fn firstToken(self: &VarDecl) Token {
+ if (self.visib_token) |visib_token| return visib_token;
+ if (self.comptime_token) |comptime_token| return comptime_token;
+ if (self.extern_export_token) |extern_export_token| return extern_export_token;
+ assert(self.lib_name == null);
+ return self.mut_token;
+ }
-pub const NodeErrorSetDecl = struct {
- base: Node,
- error_token: Token,
- decls: ArrayList(&Node),
- rbrace_token: Token,
+ pub fn lastToken(self: &VarDecl) Token {
+ return self.semicolon_token;
+ }
+ };
- pub fn iterate(self: &NodeErrorSetDecl, index: usize) ?&Node {
- var i = index;
+ pub const Use = struct {
+ base: Node,
+ visib_token: ?Token,
+ expr: &Node,
+ semicolon_token: Token,
- if (i < self.decls.len) return self.decls.at(i);
- i -= self.decls.len;
+ pub fn iterate(self: &Use, index: usize) ?&Node {
+ var i = index;
- return null;
- }
+ if (i < 1) return self.expr;
+ i -= 1;
- pub fn firstToken(self: &NodeErrorSetDecl) Token {
- return self.error_token;
- }
+ return null;
+ }
- pub fn lastToken(self: &NodeErrorSetDecl) Token {
- return self.rbrace_token;
- }
-};
+ pub fn firstToken(self: &Use) Token {
+ if (self.visib_token) |visib_token| return visib_token;
+ return self.expr.firstToken();
+ }
-pub const NodeContainerDecl = struct {
- base: Node,
- ltoken: Token,
- layout: Layout,
- kind: Kind,
- init_arg_expr: InitArg,
- fields_and_decls: ArrayList(&Node),
- rbrace_token: Token,
-
- const Layout = enum {
- Auto,
- Extern,
- Packed,
+ pub fn lastToken(self: &Use) Token {
+ return self.semicolon_token;
+ }
};
- const Kind = enum {
- Struct,
- Enum,
- Union,
- };
+ pub const ErrorSetDecl = struct {
+ base: Node,
+ error_token: Token,
+ decls: ArrayList(&Node),
+ rbrace_token: Token,
- const InitArg = union(enum) {
- None,
- Enum,
- Type: &Node,
- };
+ pub fn iterate(self: &ErrorSetDecl, index: usize) ?&Node {
+ var i = index;
- pub fn iterate(self: &NodeContainerDecl, index: usize) ?&Node {
- var i = index;
+ if (i < self.decls.len) return self.decls.at(i);
+ i -= self.decls.len;
- switch (self.init_arg_expr) {
- InitArg.Type => |t| {
- if (i < 1) return t;
- i -= 1;
- },
- InitArg.None,
- InitArg.Enum => { }
+ return null;
}
- if (i < self.fields_and_decls.len) return self.fields_and_decls.at(i);
- i -= self.fields_and_decls.len;
+ pub fn firstToken(self: &ErrorSetDecl) Token {
+ return self.error_token;
+ }
- return null;
- }
+ pub fn lastToken(self: &ErrorSetDecl) Token {
+ return self.rbrace_token;
+ }
+ };
- pub fn firstToken(self: &NodeContainerDecl) Token {
- return self.ltoken;
- }
+ pub const ContainerDecl = struct {
+ base: Node,
+ ltoken: Token,
+ layout: Layout,
+ kind: Kind,
+ init_arg_expr: InitArg,
+ fields_and_decls: ArrayList(&Node),
+ rbrace_token: Token,
+
+ const Layout = enum {
+ Auto,
+ Extern,
+ Packed,
+ };
- pub fn lastToken(self: &NodeContainerDecl) Token {
- return self.rbrace_token;
- }
-};
+ const Kind = enum {
+ Struct,
+ Enum,
+ Union,
+ };
+
+ const InitArg = union(enum) {
+ None,
+ Enum,
+ Type: &Node,
+ };
-pub const NodeStructField = struct {
- base: Node,
- visib_token: ?Token,
- name_token: Token,
- type_expr: &Node,
+ pub fn iterate(self: &ContainerDecl, index: usize) ?&Node {
+ var i = index;
- pub fn iterate(self: &NodeStructField, index: usize) ?&Node {
- var i = index;
+ switch (self.init_arg_expr) {
+ InitArg.Type => |t| {
+ if (i < 1) return t;
+ i -= 1;
+ },
+ InitArg.None,
+ InitArg.Enum => { }
+ }
- if (i < 1) return self.type_expr;
- i -= 1;
+ if (i < self.fields_and_decls.len) return self.fields_and_decls.at(i);
+ i -= self.fields_and_decls.len;
- return null;
- }
+ return null;
+ }
- pub fn firstToken(self: &NodeStructField) Token {
- if (self.visib_token) |visib_token| return visib_token;
- return self.name_token;
- }
+ pub fn firstToken(self: &ContainerDecl) Token {
+ return self.ltoken;
+ }
- pub fn lastToken(self: &NodeStructField) Token {
- return self.type_expr.lastToken();
- }
-};
+ pub fn lastToken(self: &ContainerDecl) Token {
+ return self.rbrace_token;
+ }
+ };
-pub const NodeUnionTag = struct {
- base: Node,
- name_token: Token,
- type_expr: ?&Node,
+ pub const StructField = struct {
+ base: Node,
+ visib_token: ?Token,
+ name_token: Token,
+ type_expr: &Node,
- pub fn iterate(self: &NodeUnionTag, index: usize) ?&Node {
- var i = index;
+ pub fn iterate(self: &StructField, index: usize) ?&Node {
+ var i = index;
- if (self.type_expr) |type_expr| {
- if (i < 1) return type_expr;
+ if (i < 1) return self.type_expr;
i -= 1;
- }
- return null;
- }
+ return null;
+ }
- pub fn firstToken(self: &NodeUnionTag) Token {
- return self.name_token;
- }
+ pub fn firstToken(self: &StructField) Token {
+ if (self.visib_token) |visib_token| return visib_token;
+ return self.name_token;
+ }
- pub fn lastToken(self: &NodeUnionTag) Token {
- if (self.type_expr) |type_expr| {
- return type_expr.lastToken();
+ pub fn lastToken(self: &StructField) Token {
+ return self.type_expr.lastToken();
}
+ };
- return self.name_token;
- }
-};
+ pub const UnionTag = struct {
+ base: Node,
+ name_token: Token,
+ type_expr: ?&Node,
-pub const NodeEnumTag = struct {
- base: Node,
- name_token: Token,
- value: ?&Node,
+ pub fn iterate(self: &UnionTag, index: usize) ?&Node {
+ var i = index;
- pub fn iterate(self: &NodeEnumTag, index: usize) ?&Node {
- var i = index;
+ if (self.type_expr) |type_expr| {
+ if (i < 1) return type_expr;
+ i -= 1;
+ }
- if (self.value) |value| {
- if (i < 1) return value;
- i -= 1;
+ return null;
}
- return null;
- }
+ pub fn firstToken(self: &UnionTag) Token {
+ return self.name_token;
+ }
- pub fn firstToken(self: &NodeEnumTag) Token {
- return self.name_token;
- }
+ pub fn lastToken(self: &UnionTag) Token {
+ if (self.type_expr) |type_expr| {
+ return type_expr.lastToken();
+ }
- pub fn lastToken(self: &NodeEnumTag) Token {
- if (self.value) |value| {
- return value.lastToken();
+ return self.name_token;
}
+ };
- return self.name_token;
- }
-};
-
-pub const NodeIdentifier = struct {
- base: Node,
- token: Token,
+ pub const EnumTag = struct {
+ base: Node,
+ name_token: Token,
+ value: ?&Node,
- pub fn iterate(self: &NodeIdentifier, index: usize) ?&Node {
- return null;
- }
+ pub fn iterate(self: &EnumTag, index: usize) ?&Node {
+ var i = index;
- pub fn firstToken(self: &NodeIdentifier) Token {
- return self.token;
- }
+ if (self.value) |value| {
+ if (i < 1) return value;
+ i -= 1;
+ }
- pub fn lastToken(self: &NodeIdentifier) Token {
- return self.token;
- }
-};
+ return null;
+ }
-pub const NodeAsyncAttribute = struct {
- base: Node,
- async_token: Token,
- allocator_type: ?&Node,
- rangle_bracket: ?Token,
+ pub fn firstToken(self: &EnumTag) Token {
+ return self.name_token;
+ }
- pub fn iterate(self: &NodeAsyncAttribute, index: usize) ?&Node {
- var i = index;
+ pub fn lastToken(self: &EnumTag) Token {
+ if (self.value) |value| {
+ return value.lastToken();
+ }
- if (self.allocator_type) |allocator_type| {
- if (i < 1) return allocator_type;
- i -= 1;
+ return self.name_token;
}
+ };
- return null;
- }
-
- pub fn firstToken(self: &NodeAsyncAttribute) Token {
- return self.async_token;
- }
+ pub const Identifier = struct {
+ base: Node,
+ token: Token,
- pub fn lastToken(self: &NodeAsyncAttribute) Token {
- if (self.rangle_bracket) |rangle_bracket| {
- return rangle_bracket;
+ pub fn iterate(self: &Identifier, index: usize) ?&Node {
+ return null;
}
- return self.async_token;
- }
-};
+ pub fn firstToken(self: &Identifier) Token {
+ return self.token;
+ }
-pub const NodeFnProto = struct {
- base: Node,
- visib_token: ?Token,
- fn_token: Token,
- name_token: ?Token,
- params: ArrayList(&Node),
- return_type: ReturnType,
- var_args_token: ?Token,
- extern_export_inline_token: ?Token,
- cc_token: ?Token,
- async_attr: ?&NodeAsyncAttribute,
- body_node: ?&Node,
- lib_name: ?&Node, // populated if this is an extern declaration
- align_expr: ?&Node, // populated if align(A) is present
-
- pub const ReturnType = union(enum) {
- Explicit: &Node,
- InferErrorSet: &Node,
+ pub fn lastToken(self: &Identifier) Token {
+ return self.token;
+ }
};
- pub fn iterate(self: &NodeFnProto, index: usize) ?&Node {
- var i = index;
+ pub const AsyncAttribute = struct {
+ base: Node,
+ async_token: Token,
+ allocator_type: ?&Node,
+ rangle_bracket: ?Token,
- if (self.body_node) |body_node| {
- if (i < 1) return body_node;
- i -= 1;
- }
+ pub fn iterate(self: &AsyncAttribute, index: usize) ?&Node {
+ var i = index;
- switch (self.return_type) {
- // TODO allow this and next prong to share bodies since the types are the same
- ReturnType.Explicit => |node| {
- if (i < 1) return node;
+ if (self.allocator_type) |allocator_type| {
+ if (i < 1) return allocator_type;
i -= 1;
- },
- ReturnType.InferErrorSet => |node| {
- if (i < 1) return node;
- i -= 1;
- },
+ }
+
+ return null;
}
- if (self.align_expr) |align_expr| {
- if (i < 1) return align_expr;
- i -= 1;
+ pub fn firstToken(self: &AsyncAttribute) Token {
+ return self.async_token;
}
- if (i < self.params.len) return self.params.items[self.params.len - i - 1];
- i -= self.params.len;
+ pub fn lastToken(self: &AsyncAttribute) Token {
+ if (self.rangle_bracket) |rangle_bracket| {
+ return rangle_bracket;
+ }
- if (self.lib_name) |lib_name| {
- if (i < 1) return lib_name;
- i -= 1;
+ return self.async_token;
}
+ };
- return null;
- }
+ pub const FnProto = struct {
+ base: Node,
+ comments: ?&LineComment,
+ visib_token: ?Token,
+ fn_token: Token,
+ name_token: ?Token,
+ params: ArrayList(&Node),
+ return_type: ReturnType,
+ var_args_token: ?Token,
+ extern_export_inline_token: ?Token,
+ cc_token: ?Token,
+ async_attr: ?&AsyncAttribute,
+ body_node: ?&Node,
+ lib_name: ?&Node, // populated if this is an extern declaration
+ align_expr: ?&Node, // populated if align(A) is present
+
+ pub const ReturnType = union(enum) {
+ Explicit: &Node,
+ InferErrorSet: &Node,
+ };
- pub fn firstToken(self: &NodeFnProto) Token {
- if (self.visib_token) |visib_token| return visib_token;
- if (self.extern_export_inline_token) |extern_export_inline_token| return extern_export_inline_token;
- assert(self.lib_name == null);
- if (self.cc_token) |cc_token| return cc_token;
- return self.fn_token;
- }
+ pub fn iterate(self: &FnProto, index: usize) ?&Node {
+ var i = index;
- pub fn lastToken(self: &NodeFnProto) Token {
- if (self.body_node) |body_node| return body_node.lastToken();
- switch (self.return_type) {
- // TODO allow this and next prong to share bodies since the types are the same
- ReturnType.Explicit => |node| return node.lastToken(),
- ReturnType.InferErrorSet => |node| return node.lastToken(),
- }
- }
-};
+ if (self.body_node) |body_node| {
+ if (i < 1) return body_node;
+ i -= 1;
+ }
-pub const NodeParamDecl = struct {
- base: Node,
- comptime_token: ?Token,
- noalias_token: ?Token,
- name_token: ?Token,
- type_node: &Node,
- var_args_token: ?Token,
+ switch (self.return_type) {
+ // TODO allow this and next prong to share bodies since the types are the same
+ ReturnType.Explicit => |node| {
+ if (i < 1) return node;
+ i -= 1;
+ },
+ ReturnType.InferErrorSet => |node| {
+ if (i < 1) return node;
+ i -= 1;
+ },
+ }
- pub fn iterate(self: &NodeParamDecl, index: usize) ?&Node {
- var i = index;
+ if (self.align_expr) |align_expr| {
+ if (i < 1) return align_expr;
+ i -= 1;
+ }
- if (i < 1) return self.type_node;
- i -= 1;
+ if (i < self.params.len) return self.params.items[self.params.len - i - 1];
+ i -= self.params.len;
- return null;
- }
+ if (self.lib_name) |lib_name| {
+ if (i < 1) return lib_name;
+ i -= 1;
+ }
- pub fn firstToken(self: &NodeParamDecl) Token {
- if (self.comptime_token) |comptime_token| return comptime_token;
- if (self.noalias_token) |noalias_token| return noalias_token;
- if (self.name_token) |name_token| return name_token;
- return self.type_node.firstToken();
- }
+ return null;
+ }
- pub fn lastToken(self: &NodeParamDecl) Token {
- if (self.var_args_token) |var_args_token| return var_args_token;
- return self.type_node.lastToken();
- }
-};
+ pub fn firstToken(self: &FnProto) Token {
+ if (self.visib_token) |visib_token| return visib_token;
+ if (self.extern_export_inline_token) |extern_export_inline_token| return extern_export_inline_token;
+ assert(self.lib_name == null);
+ if (self.cc_token) |cc_token| return cc_token;
+ return self.fn_token;
+ }
-pub const NodeBlock = struct {
- base: Node,
- label: ?Token,
- lbrace: Token,
- statements: ArrayList(&Node),
- rbrace: Token,
+ pub fn lastToken(self: &FnProto) Token {
+ if (self.body_node) |body_node| return body_node.lastToken();
+ switch (self.return_type) {
+ // TODO allow this and next prong to share bodies since the types are the same
+ ReturnType.Explicit => |node| return node.lastToken(),
+ ReturnType.InferErrorSet => |node| return node.lastToken(),
+ }
+ }
+ };
- pub fn iterate(self: &NodeBlock, index: usize) ?&Node {
- var i = index;
+ pub const ParamDecl = struct {
+ base: Node,
+ comptime_token: ?Token,
+ noalias_token: ?Token,
+ name_token: ?Token,
+ type_node: &Node,
+ var_args_token: ?Token,
- if (i < self.statements.len) return self.statements.items[i];
- i -= self.statements.len;
+ pub fn iterate(self: &ParamDecl, index: usize) ?&Node {
+ var i = index;
- return null;
- }
+ if (i < 1) return self.type_node;
+ i -= 1;
- pub fn firstToken(self: &NodeBlock) Token {
- if (self.label) |label| {
- return label;
+ return null;
}
- return self.lbrace;
- }
+ pub fn firstToken(self: &ParamDecl) Token {
+ if (self.comptime_token) |comptime_token| return comptime_token;
+ if (self.noalias_token) |noalias_token| return noalias_token;
+ if (self.name_token) |name_token| return name_token;
+ return self.type_node.firstToken();
+ }
- pub fn lastToken(self: &NodeBlock) Token {
- return self.rbrace;
- }
-};
+ pub fn lastToken(self: &ParamDecl) Token {
+ if (self.var_args_token) |var_args_token| return var_args_token;
+ return self.type_node.lastToken();
+ }
+ };
-pub const NodeDefer = struct {
- base: Node,
- defer_token: Token,
- kind: Kind,
- expr: &Node,
+ pub const Block = struct {
+ base: Node,
+ label: ?Token,
+ lbrace: Token,
+ statements: ArrayList(&Node),
+ rbrace: Token,
- const Kind = enum {
- Error,
- Unconditional,
- };
+ pub fn iterate(self: &Block, index: usize) ?&Node {
+ var i = index;
- pub fn iterate(self: &NodeDefer, index: usize) ?&Node {
- var i = index;
+ if (i < self.statements.len) return self.statements.items[i];
+ i -= self.statements.len;
- if (i < 1) return self.expr;
- i -= 1;
+ return null;
+ }
- return null;
- }
+ pub fn firstToken(self: &Block) Token {
+ if (self.label) |label| {
+ return label;
+ }
- pub fn firstToken(self: &NodeDefer) Token {
- return self.defer_token;
- }
+ return self.lbrace;
+ }
- pub fn lastToken(self: &NodeDefer) Token {
- return self.expr.lastToken();
- }
-};
+ pub fn lastToken(self: &Block) Token {
+ return self.rbrace;
+ }
+ };
-pub const NodeComptime = struct {
- base: Node,
- comptime_token: Token,
- expr: &Node,
+ pub const Defer = struct {
+ base: Node,
+ defer_token: Token,
+ kind: Kind,
+ expr: &Node,
- pub fn iterate(self: &NodeComptime, index: usize) ?&Node {
- var i = index;
+ const Kind = enum {
+ Error,
+ Unconditional,
+ };
- if (i < 1) return self.expr;
- i -= 1;
+ pub fn iterate(self: &Defer, index: usize) ?&Node {
+ var i = index;
- return null;
- }
+ if (i < 1) return self.expr;
+ i -= 1;
- pub fn firstToken(self: &NodeComptime) Token {
- return self.comptime_token;
- }
+ return null;
+ }
- pub fn lastToken(self: &NodeComptime) Token {
- return self.expr.lastToken();
- }
-};
+ pub fn firstToken(self: &Defer) Token {
+ return self.defer_token;
+ }
-pub const NodePayload = struct {
- base: Node,
- lpipe: Token,
- error_symbol: &Node,
- rpipe: Token,
+ pub fn lastToken(self: &Defer) Token {
+ return self.expr.lastToken();
+ }
+ };
- pub fn iterate(self: &NodePayload, index: usize) ?&Node {
- var i = index;
+ pub const Comptime = struct {
+ base: Node,
+ comptime_token: Token,
+ expr: &Node,
- if (i < 1) return self.error_symbol;
- i -= 1;
+ pub fn iterate(self: &Comptime, index: usize) ?&Node {
+ var i = index;
- return null;
- }
+ if (i < 1) return self.expr;
+ i -= 1;
- pub fn firstToken(self: &NodePayload) Token {
- return self.lpipe;
- }
+ return null;
+ }
- pub fn lastToken(self: &NodePayload) Token {
- return self.rpipe;
- }
-};
+ pub fn firstToken(self: &Comptime) Token {
+ return self.comptime_token;
+ }
-pub const NodePointerPayload = struct {
- base: Node,
- lpipe: Token,
- ptr_token: ?Token,
- value_symbol: &Node,
- rpipe: Token,
+ pub fn lastToken(self: &Comptime) Token {
+ return self.expr.lastToken();
+ }
+ };
- pub fn iterate(self: &NodePointerPayload, index: usize) ?&Node {
- var i = index;
+ pub const Payload = struct {
+ base: Node,
+ lpipe: Token,
+ error_symbol: &Node,
+ rpipe: Token,
- if (i < 1) return self.value_symbol;
- i -= 1;
+ pub fn iterate(self: &Payload, index: usize) ?&Node {
+ var i = index;
- return null;
- }
+ if (i < 1) return self.error_symbol;
+ i -= 1;
- pub fn firstToken(self: &NodePointerPayload) Token {
- return self.lpipe;
- }
+ return null;
+ }
- pub fn lastToken(self: &NodePointerPayload) Token {
- return self.rpipe;
- }
-};
+ pub fn firstToken(self: &Payload) Token {
+ return self.lpipe;
+ }
-pub const NodePointerIndexPayload = struct {
- base: Node,
- lpipe: Token,
- ptr_token: ?Token,
- value_symbol: &Node,
- index_symbol: ?&Node,
- rpipe: Token,
+ pub fn lastToken(self: &Payload) Token {
+ return self.rpipe;
+ }
+ };
- pub fn iterate(self: &NodePointerIndexPayload, index: usize) ?&Node {
- var i = index;
+ pub const PointerPayload = struct {
+ base: Node,
+ lpipe: Token,
+ ptr_token: ?Token,
+ value_symbol: &Node,
+ rpipe: Token,
- if (i < 1) return self.value_symbol;
- i -= 1;
+ pub fn iterate(self: &PointerPayload, index: usize) ?&Node {
+ var i = index;
- if (self.index_symbol) |index_symbol| {
- if (i < 1) return index_symbol;
+ if (i < 1) return self.value_symbol;
i -= 1;
- }
- return null;
- }
+ return null;
+ }
- pub fn firstToken(self: &NodePointerIndexPayload) Token {
- return self.lpipe;
- }
+ pub fn firstToken(self: &PointerPayload) Token {
+ return self.lpipe;
+ }
- pub fn lastToken(self: &NodePointerIndexPayload) Token {
- return self.rpipe;
- }
-};
+ pub fn lastToken(self: &PointerPayload) Token {
+ return self.rpipe;
+ }
+ };
-pub const NodeElse = struct {
- base: Node,
- else_token: Token,
- payload: ?&Node,
- body: &Node,
+ pub const PointerIndexPayload = struct {
+ base: Node,
+ lpipe: Token,
+ ptr_token: ?Token,
+ value_symbol: &Node,
+ index_symbol: ?&Node,
+ rpipe: Token,
- pub fn iterate(self: &NodeElse, index: usize) ?&Node {
- var i = index;
+ pub fn iterate(self: &PointerIndexPayload, index: usize) ?&Node {
+ var i = index;
- if (self.payload) |payload| {
- if (i < 1) return payload;
+ if (i < 1) return self.value_symbol;
i -= 1;
- }
- if (i < 1) return self.body;
- i -= 1;
-
- return null;
- }
+ if (self.index_symbol) |index_symbol| {
+ if (i < 1) return index_symbol;
+ i -= 1;
+ }
- pub fn firstToken(self: &NodeElse) Token {
- return self.else_token;
- }
+ return null;
+ }
- pub fn lastToken(self: &NodeElse) Token {
- return self.body.lastToken();
- }
-};
+ pub fn firstToken(self: &PointerIndexPayload) Token {
+ return self.lpipe;
+ }
-pub const NodeSwitch = struct {
- base: Node,
- switch_token: Token,
- expr: &Node,
- cases: ArrayList(&NodeSwitchCase),
- rbrace: Token,
+ pub fn lastToken(self: &PointerIndexPayload) Token {
+ return self.rpipe;
+ }
+ };
- pub fn iterate(self: &NodeSwitch, index: usize) ?&Node {
- var i = index;
+ pub const Else = struct {
+ base: Node,
+ else_token: Token,
+ payload: ?&Node,
+ body: &Node,
- if (i < 1) return self.expr;
- i -= 1;
+ pub fn iterate(self: &Else, index: usize) ?&Node {
+ var i = index;
- if (i < self.cases.len) return &self.cases.at(i).base;
- i -= self.cases.len;
+ if (self.payload) |payload| {
+ if (i < 1) return payload;
+ i -= 1;
+ }
- return null;
- }
+ if (i < 1) return self.body;
+ i -= 1;
- pub fn firstToken(self: &NodeSwitch) Token {
- return self.switch_token;
- }
+ return null;
+ }
- pub fn lastToken(self: &NodeSwitch) Token {
- return self.rbrace;
- }
-};
+ pub fn firstToken(self: &Else) Token {
+ return self.else_token;
+ }
-pub const NodeSwitchCase = struct {
- base: Node,
- items: ArrayList(&Node),
- payload: ?&Node,
- expr: &Node,
+ pub fn lastToken(self: &Else) Token {
+ return self.body.lastToken();
+ }
+ };
- pub fn iterate(self: &NodeSwitchCase, index: usize) ?&Node {
- var i = index;
+ pub const Switch = struct {
+ base: Node,
+ switch_token: Token,
+ expr: &Node,
+ cases: ArrayList(&SwitchCase),
+ rbrace: Token,
- if (i < self.items.len) return self.items.at(i);
- i -= self.items.len;
+ pub fn iterate(self: &Switch, index: usize) ?&Node {
+ var i = index;
- if (self.payload) |payload| {
- if (i < 1) return payload;
+ if (i < 1) return self.expr;
i -= 1;
- }
- if (i < 1) return self.expr;
- i -= 1;
+ if (i < self.cases.len) return &self.cases.at(i).base;
+ i -= self.cases.len;
- return null;
- }
+ return null;
+ }
- pub fn firstToken(self: &NodeSwitchCase) Token {
- return self.items.at(0).firstToken();
- }
+ pub fn firstToken(self: &Switch) Token {
+ return self.switch_token;
+ }
- pub fn lastToken(self: &NodeSwitchCase) Token {
- return self.expr.lastToken();
- }
-};
+ pub fn lastToken(self: &Switch) Token {
+ return self.rbrace;
+ }
+ };
-pub const NodeSwitchElse = struct {
- base: Node,
- token: Token,
+ pub const SwitchCase = struct {
+ base: Node,
+ items: ArrayList(&Node),
+ payload: ?&Node,
+ expr: &Node,
- pub fn iterate(self: &NodeSwitchElse, index: usize) ?&Node {
- return null;
- }
+ pub fn iterate(self: &SwitchCase, index: usize) ?&Node {
+ var i = index;
- pub fn firstToken(self: &NodeSwitchElse) Token {
- return self.token;
- }
+ if (i < self.items.len) return self.items.at(i);
+ i -= self.items.len;
- pub fn lastToken(self: &NodeSwitchElse) Token {
- return self.token;
- }
-};
+ if (self.payload) |payload| {
+ if (i < 1) return payload;
+ i -= 1;
+ }
-pub const NodeWhile = struct {
- base: Node,
- label: ?Token,
- inline_token: ?Token,
- while_token: Token,
- condition: &Node,
- payload: ?&Node,
- continue_expr: ?&Node,
- body: &Node,
- @"else": ?&NodeElse,
-
- pub fn iterate(self: &NodeWhile, index: usize) ?&Node {
- var i = index;
-
- if (i < 1) return self.condition;
- i -= 1;
-
- if (self.payload) |payload| {
- if (i < 1) return payload;
+ if (i < 1) return self.expr;
i -= 1;
- }
- if (self.continue_expr) |continue_expr| {
- if (i < 1) return continue_expr;
- i -= 1;
+ return null;
}
- if (i < 1) return self.body;
- i -= 1;
+ pub fn firstToken(self: &SwitchCase) Token {
+ return self.items.at(0).firstToken();
+ }
- if (self.@"else") |@"else"| {
- if (i < 1) return &@"else".base;
- i -= 1;
+ pub fn lastToken(self: &SwitchCase) Token {
+ return self.expr.lastToken();
}
+ };
- return null;
- }
+ pub const SwitchElse = struct {
+ base: Node,
+ token: Token,
- pub fn firstToken(self: &NodeWhile) Token {
- if (self.label) |label| {
- return label;
+ pub fn iterate(self: &SwitchElse, index: usize) ?&Node {
+ return null;
}
- if (self.inline_token) |inline_token| {
- return inline_token;
+ pub fn firstToken(self: &SwitchElse) Token {
+ return self.token;
}
- return self.while_token;
- }
-
- pub fn lastToken(self: &NodeWhile) Token {
- if (self.@"else") |@"else"| {
- return @"else".body.lastToken();
+ pub fn lastToken(self: &SwitchElse) Token {
+ return self.token;
}
+ };
- return self.body.lastToken();
- }
-};
-
-pub const NodeFor = struct {
- base: Node,
- label: ?Token,
- inline_token: ?Token,
- for_token: Token,
- array_expr: &Node,
- payload: ?&Node,
- body: &Node,
- @"else": ?&NodeElse,
+ pub const While = struct {
+ base: Node,
+ label: ?Token,
+ inline_token: ?Token,
+ while_token: Token,
+ condition: &Node,
+ payload: ?&Node,
+ continue_expr: ?&Node,
+ body: &Node,
+ @"else": ?&Else,
+
+ pub fn iterate(self: &While, index: usize) ?&Node {
+ var i = index;
+
+ if (i < 1) return self.condition;
+ i -= 1;
- pub fn iterate(self: &NodeFor, index: usize) ?&Node {
- var i = index;
+ if (self.payload) |payload| {
+ if (i < 1) return payload;
+ i -= 1;
+ }
- if (i < 1) return self.array_expr;
- i -= 1;
+ if (self.continue_expr) |continue_expr| {
+ if (i < 1) return continue_expr;
+ i -= 1;
+ }
- if (self.payload) |payload| {
- if (i < 1) return payload;
+ if (i < 1) return self.body;
i -= 1;
- }
- if (i < 1) return self.body;
- i -= 1;
+ if (self.@"else") |@"else"| {
+ if (i < 1) return &@"else".base;
+ i -= 1;
+ }
- if (self.@"else") |@"else"| {
- if (i < 1) return &@"else".base;
- i -= 1;
+ return null;
}
- return null;
- }
+ pub fn firstToken(self: &While) Token {
+ if (self.label) |label| {
+ return label;
+ }
- pub fn firstToken(self: &NodeFor) Token {
- if (self.label) |label| {
- return label;
- }
+ if (self.inline_token) |inline_token| {
+ return inline_token;
+ }
- if (self.inline_token) |inline_token| {
- return inline_token;
+ return self.while_token;
}
- return self.for_token;
- }
+ pub fn lastToken(self: &While) Token {
+ if (self.@"else") |@"else"| {
+ return @"else".body.lastToken();
+ }
- pub fn lastToken(self: &NodeFor) Token {
- if (self.@"else") |@"else"| {
- return @"else".body.lastToken();
+ return self.body.lastToken();
}
+ };
- return self.body.lastToken();
- }
-};
+ pub const For = struct {
+ base: Node,
+ label: ?Token,
+ inline_token: ?Token,
+ for_token: Token,
+ array_expr: &Node,
+ payload: ?&Node,
+ body: &Node,
+ @"else": ?&Else,
-pub const NodeIf = struct {
- base: Node,
- if_token: Token,
- condition: &Node,
- payload: ?&Node,
- body: &Node,
- @"else": ?&NodeElse,
+ pub fn iterate(self: &For, index: usize) ?&Node {
+ var i = index;
- pub fn iterate(self: &NodeIf, index: usize) ?&Node {
- var i = index;
+ if (i < 1) return self.array_expr;
+ i -= 1;
- if (i < 1) return self.condition;
- i -= 1;
+ if (self.payload) |payload| {
+ if (i < 1) return payload;
+ i -= 1;
+ }
- if (self.payload) |payload| {
- if (i < 1) return payload;
+ if (i < 1) return self.body;
i -= 1;
- }
- if (i < 1) return self.body;
- i -= 1;
+ if (self.@"else") |@"else"| {
+ if (i < 1) return &@"else".base;
+ i -= 1;
+ }
- if (self.@"else") |@"else"| {
- if (i < 1) return &@"else".base;
- i -= 1;
+ return null;
}
- return null;
- }
+ pub fn firstToken(self: &For) Token {
+ if (self.label) |label| {
+ return label;
+ }
- pub fn firstToken(self: &NodeIf) Token {
- return self.if_token;
- }
+ if (self.inline_token) |inline_token| {
+ return inline_token;
+ }
- pub fn lastToken(self: &NodeIf) Token {
- if (self.@"else") |@"else"| {
- return @"else".body.lastToken();
+ return self.for_token;
}
- return self.body.lastToken();
- }
-};
+ pub fn lastToken(self: &For) Token {
+ if (self.@"else") |@"else"| {
+ return @"else".body.lastToken();
+ }
-pub const NodeInfixOp = struct {
- base: Node,
- op_token: Token,
- lhs: &Node,
- op: InfixOp,
- rhs: &Node,
-
- const InfixOp = union(enum) {
- Add,
- AddWrap,
- ArrayCat,
- ArrayMult,
- Assign,
- AssignBitAnd,
- AssignBitOr,
- AssignBitShiftLeft,
- AssignBitShiftRight,
- AssignBitXor,
- AssignDiv,
- AssignMinus,
- AssignMinusWrap,
- AssignMod,
- AssignPlus,
- AssignPlusWrap,
- AssignTimes,
- AssignTimesWarp,
- BangEqual,
- BitAnd,
- BitOr,
- BitShiftLeft,
- BitShiftRight,
- BitXor,
- BoolAnd,
- BoolOr,
- Catch: ?&Node,
- Div,
- EqualEqual,
- ErrorUnion,
- GreaterOrEqual,
- GreaterThan,
- LessOrEqual,
- LessThan,
- MergeErrorSets,
- Mod,
- Mult,
- MultWrap,
- Period,
- Range,
- Sub,
- SubWrap,
- UnwrapMaybe,
+ return self.body.lastToken();
+ }
};
- pub fn iterate(self: &NodeInfixOp, index: usize) ?&Node {
- var i = index;
+ pub const If = struct {
+ base: Node,
+ if_token: Token,
+ condition: &Node,
+ payload: ?&Node,
+ body: &Node,
+ @"else": ?&Else,
- if (i < 1) return self.lhs;
- i -= 1;
+ pub fn iterate(self: &If, index: usize) ?&Node {
+ var i = index;
- switch (self.op) {
- InfixOp.Catch => |maybe_payload| {
- if (maybe_payload) |payload| {
- if (i < 1) return payload;
- i -= 1;
- }
- },
-
- InfixOp.Add,
- InfixOp.AddWrap,
- InfixOp.ArrayCat,
- InfixOp.ArrayMult,
- InfixOp.Assign,
- InfixOp.AssignBitAnd,
- InfixOp.AssignBitOr,
- InfixOp.AssignBitShiftLeft,
- InfixOp.AssignBitShiftRight,
- InfixOp.AssignBitXor,
- InfixOp.AssignDiv,
- InfixOp.AssignMinus,
- InfixOp.AssignMinusWrap,
- InfixOp.AssignMod,
- InfixOp.AssignPlus,
- InfixOp.AssignPlusWrap,
- InfixOp.AssignTimes,
- InfixOp.AssignTimesWarp,
- InfixOp.BangEqual,
- InfixOp.BitAnd,
- InfixOp.BitOr,
- InfixOp.BitShiftLeft,
- InfixOp.BitShiftRight,
- InfixOp.BitXor,
- InfixOp.BoolAnd,
- InfixOp.BoolOr,
- InfixOp.Div,
- InfixOp.EqualEqual,
- InfixOp.ErrorUnion,
- InfixOp.GreaterOrEqual,
- InfixOp.GreaterThan,
- InfixOp.LessOrEqual,
- InfixOp.LessThan,
- InfixOp.MergeErrorSets,
- InfixOp.Mod,
- InfixOp.Mult,
- InfixOp.MultWrap,
- InfixOp.Period,
- InfixOp.Range,
- InfixOp.Sub,
- InfixOp.SubWrap,
- InfixOp.UnwrapMaybe => {},
- }
-
- if (i < 1) return self.rhs;
- i -= 1;
-
- return null;
- }
+ if (i < 1) return self.condition;
+ i -= 1;
- pub fn firstToken(self: &NodeInfixOp) Token {
- return self.lhs.firstToken();
- }
+ if (self.payload) |payload| {
+ if (i < 1) return payload;
+ i -= 1;
+ }
- pub fn lastToken(self: &NodeInfixOp) Token {
- return self.rhs.lastToken();
- }
-};
+ if (i < 1) return self.body;
+ i -= 1;
-pub const NodePrefixOp = struct {
- base: Node,
- op_token: Token,
- op: PrefixOp,
- rhs: &Node,
-
- const PrefixOp = union(enum) {
- AddrOf: AddrOfInfo,
- ArrayType: &Node,
- Await,
- BitNot,
- BoolNot,
- Cancel,
- Deref,
- MaybeType,
- Negation,
- NegationWrap,
- Resume,
- SliceType: AddrOfInfo,
- Try,
- UnwrapMaybe,
- };
+ if (self.@"else") |@"else"| {
+ if (i < 1) return &@"else".base;
+ i -= 1;
+ }
- const AddrOfInfo = struct {
- align_expr: ?&Node,
- bit_offset_start_token: ?Token,
- bit_offset_end_token: ?Token,
- const_token: ?Token,
- volatile_token: ?Token,
- };
+ return null;
+ }
- pub fn iterate(self: &NodePrefixOp, index: usize) ?&Node {
- var i = index;
+ pub fn firstToken(self: &If) Token {
+ return self.if_token;
+ }
- 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.Await,
- PrefixOp.BitNot,
- PrefixOp.BoolNot,
- PrefixOp.Cancel,
- PrefixOp.Deref,
- PrefixOp.MaybeType,
- PrefixOp.Negation,
- PrefixOp.NegationWrap,
- PrefixOp.Try,
- PrefixOp.Resume,
- PrefixOp.UnwrapMaybe => {},
- }
-
- if (i < 1) return self.rhs;
- i -= 1;
-
- return null;
- }
+ pub fn lastToken(self: &If) Token {
+ if (self.@"else") |@"else"| {
+ return @"else".body.lastToken();
+ }
- pub fn firstToken(self: &NodePrefixOp) Token {
- return self.op_token;
- }
+ return self.body.lastToken();
+ }
+ };
- pub fn lastToken(self: &NodePrefixOp) Token {
- return self.rhs.lastToken();
- }
-};
+ pub const InfixOp = struct {
+ base: Node,
+ op_token: Token,
+ lhs: &Node,
+ op: Op,
+ rhs: &Node,
+
+ pub const Op = union(enum) {
+ Add,
+ AddWrap,
+ ArrayCat,
+ ArrayMult,
+ Assign,
+ AssignBitAnd,
+ AssignBitOr,
+ AssignBitShiftLeft,
+ AssignBitShiftRight,
+ AssignBitXor,
+ AssignDiv,
+ AssignMinus,
+ AssignMinusWrap,
+ AssignMod,
+ AssignPlus,
+ AssignPlusWrap,
+ AssignTimes,
+ AssignTimesWarp,
+ BangEqual,
+ BitAnd,
+ BitOr,
+ BitShiftLeft,
+ BitShiftRight,
+ BitXor,
+ BoolAnd,
+ BoolOr,
+ Catch: ?&Node,
+ Div,
+ EqualEqual,
+ ErrorUnion,
+ GreaterOrEqual,
+ GreaterThan,
+ LessOrEqual,
+ LessThan,
+ MergeErrorSets,
+ Mod,
+ Mult,
+ MultWrap,
+ Period,
+ Range,
+ Sub,
+ SubWrap,
+ UnwrapMaybe,
+ };
-pub const NodeFieldInitializer = struct {
- base: Node,
- period_token: Token,
- name_token: Token,
- expr: &Node,
+ pub fn iterate(self: &InfixOp, index: usize) ?&Node {
+ var i = index;
- pub fn iterate(self: &NodeFieldInitializer, index: usize) ?&Node {
- var i = index;
+ if (i < 1) return self.lhs;
+ i -= 1;
- if (i < 1) return self.expr;
- i -= 1;
+ switch (self.op) {
+ Op.Catch => |maybe_payload| {
+ if (maybe_payload) |payload| {
+ if (i < 1) return payload;
+ i -= 1;
+ }
+ },
+
+ Op.Add,
+ Op.AddWrap,
+ Op.ArrayCat,
+ Op.ArrayMult,
+ Op.Assign,
+ Op.AssignBitAnd,
+ Op.AssignBitOr,
+ Op.AssignBitShiftLeft,
+ Op.AssignBitShiftRight,
+ Op.AssignBitXor,
+ Op.AssignDiv,
+ Op.AssignMinus,
+ Op.AssignMinusWrap,
+ Op.AssignMod,
+ Op.AssignPlus,
+ Op.AssignPlusWrap,
+ Op.AssignTimes,
+ Op.AssignTimesWarp,
+ Op.BangEqual,
+ Op.BitAnd,
+ Op.BitOr,
+ Op.BitShiftLeft,
+ Op.BitShiftRight,
+ Op.BitXor,
+ Op.BoolAnd,
+ Op.BoolOr,
+ Op.Div,
+ Op.EqualEqual,
+ Op.ErrorUnion,
+ Op.GreaterOrEqual,
+ Op.GreaterThan,
+ Op.LessOrEqual,
+ Op.LessThan,
+ Op.MergeErrorSets,
+ Op.Mod,
+ Op.Mult,
+ Op.MultWrap,
+ Op.Period,
+ Op.Range,
+ Op.Sub,
+ Op.SubWrap,
+ Op.UnwrapMaybe => {},
+ }
- return null;
- }
+ if (i < 1) return self.rhs;
+ i -= 1;
- pub fn firstToken(self: &NodeFieldInitializer) Token {
- return self.period_token;
- }
+ return null;
+ }
- pub fn lastToken(self: &NodeFieldInitializer) Token {
- return self.expr.lastToken();
- }
-};
+ pub fn firstToken(self: &InfixOp) Token {
+ return self.lhs.firstToken();
+ }
-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(&NodeFieldInitializer),
+ pub fn lastToken(self: &InfixOp) Token {
+ return self.rhs.lastToken();
+ }
};
- const CallInfo = struct {
- params: ArrayList(&Node),
- async_attr: ?&NodeAsyncAttribute,
- };
+ pub const PrefixOp = struct {
+ base: Node,
+ op_token: Token,
+ op: Op,
+ rhs: &Node,
+
+ const Op = union(enum) {
+ AddrOf: AddrOfInfo,
+ ArrayType: &Node,
+ Await,
+ BitNot,
+ BoolNot,
+ Cancel,
+ Deref,
+ MaybeType,
+ Negation,
+ NegationWrap,
+ Resume,
+ SliceType: AddrOfInfo,
+ Try,
+ UnwrapMaybe,
+ };
- const SliceRange = struct {
- start: &Node,
- end: ?&Node,
- };
+ const AddrOfInfo = struct {
+ align_expr: ?&Node,
+ bit_offset_start_token: ?Token,
+ bit_offset_end_token: ?Token,
+ const_token: ?Token,
+ volatile_token: ?Token,
+ };
- pub fn iterate(self: &NodeSuffixOp, index: usize) ?&Node {
- var i = index;
+ pub fn iterate(self: &PrefixOp, index: usize) ?&Node {
+ var i = index;
+
+ switch (self.op) {
+ Op.SliceType => |addr_of_info| {
+ if (addr_of_info.align_expr) |align_expr| {
+ if (i < 1) return align_expr;
+ i -= 1;
+ }
+ },
+ Op.AddrOf => |addr_of_info| {
+ if (addr_of_info.align_expr) |align_expr| {
+ if (i < 1) return align_expr;
+ i -= 1;
+ }
+ },
+ Op.ArrayType => |size_expr| {
+ if (i < 1) return size_expr;
+ i -= 1;
+ },
+ Op.Await,
+ Op.BitNot,
+ Op.BoolNot,
+ Op.Cancel,
+ Op.Deref,
+ Op.MaybeType,
+ Op.Negation,
+ Op.NegationWrap,
+ Op.Try,
+ Op.Resume,
+ Op.UnwrapMaybe => {},
+ }
- if (i < 1) return self.lhs;
- i -= 1;
+ if (i < 1) return self.rhs;
+ 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;
+ return null;
+ }
- 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).base;
- i -= fields.len;
- },
- }
-
- return null;
- }
+ pub fn firstToken(self: &PrefixOp) Token {
+ return self.op_token;
+ }
- pub fn firstToken(self: &NodeSuffixOp) Token {
- return self.lhs.firstToken();
- }
+ pub fn lastToken(self: &PrefixOp) Token {
+ return self.rhs.lastToken();
+ }
+ };
- pub fn lastToken(self: &NodeSuffixOp) Token {
- return self.rtoken;
- }
-};
+ pub const FieldInitializer = struct {
+ base: Node,
+ period_token: Token,
+ name_token: Token,
+ expr: &Node,
-pub const NodeGroupedExpression = struct {
- base: Node,
- lparen: Token,
- expr: &Node,
- rparen: Token,
+ pub fn iterate(self: &FieldInitializer, index: usize) ?&Node {
+ var i = index;
- pub fn iterate(self: &NodeGroupedExpression, index: usize) ?&Node {
- var i = index;
+ if (i < 1) return self.expr;
+ i -= 1;
- if (i < 1) return self.expr;
- i -= 1;
+ return null;
+ }
- return null;
- }
+ pub fn firstToken(self: &FieldInitializer) Token {
+ return self.period_token;
+ }
- pub fn firstToken(self: &NodeGroupedExpression) Token {
- return self.lparen;
- }
+ pub fn lastToken(self: &FieldInitializer) Token {
+ return self.expr.lastToken();
+ }
+ };
- pub fn lastToken(self: &NodeGroupedExpression) Token {
- return self.rparen;
- }
-};
+ pub const SuffixOp = struct {
+ base: Node,
+ lhs: &Node,
+ op: Op,
+ rtoken: Token,
+
+ const Op = union(enum) {
+ Call: CallInfo,
+ ArrayAccess: &Node,
+ Slice: SliceRange,
+ ArrayInitializer: ArrayList(&Node),
+ StructInitializer: ArrayList(&FieldInitializer),
+ };
+
+ const CallInfo = struct {
+ params: ArrayList(&Node),
+ async_attr: ?&AsyncAttribute,
+ };
-pub const NodeControlFlowExpression = struct {
- base: Node,
- ltoken: Token,
- kind: Kind,
- rhs: ?&Node,
+ const SliceRange = struct {
+ start: &Node,
+ end: ?&Node,
+ };
- const Kind = union(enum) {
- Break: ?&Node,
- Continue: ?&Node,
- Return,
- };
+ pub fn iterate(self: &SuffixOp, index: usize) ?&Node {
+ var i = index;
- pub fn iterate(self: &NodeControlFlowExpression, index: usize) ?&Node {
- var i = index;
+ if (i < 1) return self.lhs;
+ i -= 1;
- switch (self.kind) {
- Kind.Break => |maybe_label| {
- if (maybe_label) |label| {
- if (i < 1) return label;
+ switch (self.op) {
+ Op.Call => |call_info| {
+ if (i < call_info.params.len) return call_info.params.at(i);
+ i -= call_info.params.len;
+ },
+ Op.ArrayAccess => |index_expr| {
+ if (i < 1) return index_expr;
i -= 1;
- }
- },
- Kind.Continue => |maybe_label| {
- if (maybe_label) |label| {
- if (i < 1) return label;
+ },
+ Op.Slice => |range| {
+ if (i < 1) return range.start;
i -= 1;
- }
- },
- Kind.Return => {},
+
+ if (range.end) |end| {
+ if (i < 1) return end;
+ i -= 1;
+ }
+ },
+ Op.ArrayInitializer => |exprs| {
+ if (i < exprs.len) return exprs.at(i);
+ i -= exprs.len;
+ },
+ Op.StructInitializer => |fields| {
+ if (i < fields.len) return &fields.at(i).base;
+ i -= fields.len;
+ },
+ }
+
+ return null;
}
- if (self.rhs) |rhs| {
- if (i < 1) return rhs;
- i -= 1;
+ pub fn firstToken(self: &SuffixOp) Token {
+ return self.lhs.firstToken();
}
- return null;
- }
+ pub fn lastToken(self: &SuffixOp) Token {
+ return self.rtoken;
+ }
+ };
- pub fn firstToken(self: &NodeControlFlowExpression) Token {
- return self.ltoken;
- }
+ pub const GroupedExpression = struct {
+ base: Node,
+ lparen: Token,
+ expr: &Node,
+ rparen: Token,
+
+ pub fn iterate(self: &GroupedExpression, index: usize) ?&Node {
+ var i = index;
- pub fn lastToken(self: &NodeControlFlowExpression) Token {
- if (self.rhs) |rhs| {
- return rhs.lastToken();
+ if (i < 1) return self.expr;
+ i -= 1;
+
+ return null;
}
- switch (self.kind) {
- Kind.Break => |maybe_label| {
- if (maybe_label) |label| {
- return label.lastToken();
- }
- },
- Kind.Continue => |maybe_label| {
- if (maybe_label) |label| {
- return label.lastToken();
- }
- },
- Kind.Return => return self.ltoken,
+ pub fn firstToken(self: &GroupedExpression) Token {
+ return self.lparen;
}
- return self.ltoken;
- }
-};
+ pub fn lastToken(self: &GroupedExpression) Token {
+ return self.rparen;
+ }
+ };
-pub const NodeSuspend = struct {
- base: Node,
- suspend_token: Token,
- payload: ?&Node,
- body: ?&Node,
+ pub const ControlFlowExpression = struct {
+ base: Node,
+ ltoken: Token,
+ kind: Kind,
+ rhs: ?&Node,
- pub fn iterate(self: &NodeSuspend, index: usize) ?&Node {
- var i = index;
+ const Kind = union(enum) {
+ Break: ?&Node,
+ Continue: ?&Node,
+ Return,
+ };
- if (self.payload) |payload| {
- if (i < 1) return payload;
- i -= 1;
+ pub fn iterate(self: &ControlFlowExpression, index: usize) ?&Node {
+ var i = index;
+
+ switch (self.kind) {
+ Kind.Break => |maybe_label| {
+ if (maybe_label) |label| {
+ if (i < 1) return label;
+ i -= 1;
+ }
+ },
+ Kind.Continue => |maybe_label| {
+ if (maybe_label) |label| {
+ if (i < 1) return label;
+ i -= 1;
+ }
+ },
+ Kind.Return => {},
+ }
+
+ if (self.rhs) |rhs| {
+ if (i < 1) return rhs;
+ i -= 1;
+ }
+
+ return null;
}
- if (self.body) |body| {
- if (i < 1) return body;
- i -= 1;
+ pub fn firstToken(self: &ControlFlowExpression) Token {
+ return self.ltoken;
}
- return null;
- }
+ pub fn lastToken(self: &ControlFlowExpression) Token {
+ if (self.rhs) |rhs| {
+ return rhs.lastToken();
+ }
- pub fn firstToken(self: &NodeSuspend) Token {
- return self.suspend_token;
- }
+ switch (self.kind) {
+ Kind.Break => |maybe_label| {
+ if (maybe_label) |label| {
+ return label.lastToken();
+ }
+ },
+ Kind.Continue => |maybe_label| {
+ if (maybe_label) |label| {
+ return label.lastToken();
+ }
+ },
+ Kind.Return => return self.ltoken,
+ }
- pub fn lastToken(self: &NodeSuspend) Token {
- if (self.body) |body| {
- return body.lastToken();
+ return self.ltoken;
}
+ };
+
+ pub const Suspend = struct {
+ base: Node,
+ suspend_token: Token,
+ payload: ?&Node,
+ body: ?&Node,
+
+ pub fn iterate(self: &Suspend, index: usize) ?&Node {
+ var i = index;
+
+ if (self.payload) |payload| {
+ if (i < 1) return payload;
+ i -= 1;
+ }
- if (self.payload) |payload| {
- return payload.lastToken();
+ if (self.body) |body| {
+ if (i < 1) return body;
+ i -= 1;
+ }
+
+ return null;
}
- return self.suspend_token;
- }
-};
+ pub fn firstToken(self: &Suspend) Token {
+ return self.suspend_token;
+ }
-pub const NodeIntegerLiteral = struct {
- base: Node,
- token: Token,
+ pub fn lastToken(self: &Suspend) Token {
+ if (self.body) |body| {
+ return body.lastToken();
+ }
- pub fn iterate(self: &NodeIntegerLiteral, index: usize) ?&Node {
- return null;
- }
+ if (self.payload) |payload| {
+ return payload.lastToken();
+ }
- pub fn firstToken(self: &NodeIntegerLiteral) Token {
- return self.token;
- }
+ return self.suspend_token;
+ }
+ };
- pub fn lastToken(self: &NodeIntegerLiteral) Token {
- return self.token;
- }
-};
+ pub const IntegerLiteral = struct {
+ base: Node,
+ token: Token,
-pub const NodeFloatLiteral = struct {
- base: Node,
- token: Token,
+ pub fn iterate(self: &IntegerLiteral, index: usize) ?&Node {
+ return null;
+ }
- pub fn iterate(self: &NodeFloatLiteral, index: usize) ?&Node {
- return null;
- }
+ pub fn firstToken(self: &IntegerLiteral) Token {
+ return self.token;
+ }
- pub fn firstToken(self: &NodeFloatLiteral) Token {
- return self.token;
- }
+ pub fn lastToken(self: &IntegerLiteral) Token {
+ return self.token;
+ }
+ };
- pub fn lastToken(self: &NodeFloatLiteral) Token {
- return self.token;
- }
-};
+ pub const FloatLiteral = struct {
+ base: Node,
+ token: Token,
-pub const NodeBuiltinCall = struct {
- base: Node,
- builtin_token: Token,
- params: ArrayList(&Node),
- rparen_token: Token,
+ pub fn iterate(self: &FloatLiteral, index: usize) ?&Node {
+ return null;
+ }
- pub fn iterate(self: &NodeBuiltinCall, index: usize) ?&Node {
- var i = index;
+ pub fn firstToken(self: &FloatLiteral) Token {
+ return self.token;
+ }
- if (i < self.params.len) return self.params.at(i);
- i -= self.params.len;
+ pub fn lastToken(self: &FloatLiteral) Token {
+ return self.token;
+ }
+ };
- return null;
- }
+ pub const BuiltinCall = struct {
+ base: Node,
+ builtin_token: Token,
+ params: ArrayList(&Node),
+ rparen_token: Token,
- pub fn firstToken(self: &NodeBuiltinCall) Token {
- return self.builtin_token;
- }
+ pub fn iterate(self: &BuiltinCall, index: usize) ?&Node {
+ var i = index;
- pub fn lastToken(self: &NodeBuiltinCall) Token {
- return self.rparen_token;
- }
-};
+ if (i < self.params.len) return self.params.at(i);
+ i -= self.params.len;
-pub const NodeStringLiteral = struct {
- base: Node,
- token: Token,
+ return null;
+ }
- pub fn iterate(self: &NodeStringLiteral, index: usize) ?&Node {
- return null;
- }
+ pub fn firstToken(self: &BuiltinCall) Token {
+ return self.builtin_token;
+ }
- pub fn firstToken(self: &NodeStringLiteral) Token {
- return self.token;
- }
+ pub fn lastToken(self: &BuiltinCall) Token {
+ return self.rparen_token;
+ }
+ };
- pub fn lastToken(self: &NodeStringLiteral) Token {
- return self.token;
- }
-};
+ pub const StringLiteral = struct {
+ base: Node,
+ token: Token,
-pub const NodeMultilineStringLiteral = struct {
- base: Node,
- tokens: ArrayList(Token),
+ pub fn iterate(self: &StringLiteral, index: usize) ?&Node {
+ return null;
+ }
- pub fn iterate(self: &NodeMultilineStringLiteral, index: usize) ?&Node {
- return null;
- }
+ pub fn firstToken(self: &StringLiteral) Token {
+ return self.token;
+ }
- pub fn firstToken(self: &NodeMultilineStringLiteral) Token {
- return self.tokens.at(0);
- }
+ pub fn lastToken(self: &StringLiteral) Token {
+ return self.token;
+ }
+ };
- pub fn lastToken(self: &NodeMultilineStringLiteral) Token {
- return self.tokens.at(self.tokens.len - 1);
- }
-};
+ pub const MultilineStringLiteral = struct {
+ base: Node,
+ tokens: ArrayList(Token),
-pub const NodeCharLiteral = struct {
- base: Node,
- token: Token,
+ pub fn iterate(self: &MultilineStringLiteral, index: usize) ?&Node {
+ return null;
+ }
- pub fn iterate(self: &NodeCharLiteral, index: usize) ?&Node {
- return null;
- }
+ pub fn firstToken(self: &MultilineStringLiteral) Token {
+ return self.tokens.at(0);
+ }
- pub fn firstToken(self: &NodeCharLiteral) Token {
- return self.token;
- }
+ pub fn lastToken(self: &MultilineStringLiteral) Token {
+ return self.tokens.at(self.tokens.len - 1);
+ }
+ };
- pub fn lastToken(self: &NodeCharLiteral) Token {
- return self.token;
- }
-};
+ pub const CharLiteral = struct {
+ base: Node,
+ token: Token,
-pub const NodeBoolLiteral = struct {
- base: Node,
- token: Token,
+ pub fn iterate(self: &CharLiteral, index: usize) ?&Node {
+ return null;
+ }
- pub fn iterate(self: &NodeBoolLiteral, index: usize) ?&Node {
- return null;
- }
+ pub fn firstToken(self: &CharLiteral) Token {
+ return self.token;
+ }
- pub fn firstToken(self: &NodeBoolLiteral) Token {
- return self.token;
- }
+ pub fn lastToken(self: &CharLiteral) Token {
+ return self.token;
+ }
+ };
- pub fn lastToken(self: &NodeBoolLiteral) Token {
- return self.token;
- }
-};
+ pub const BoolLiteral = struct {
+ base: Node,
+ token: Token,
-pub const NodeNullLiteral = struct {
- base: Node,
- token: Token,
+ pub fn iterate(self: &BoolLiteral, index: usize) ?&Node {
+ return null;
+ }
- pub fn iterate(self: &NodeNullLiteral, index: usize) ?&Node {
- return null;
- }
+ pub fn firstToken(self: &BoolLiteral) Token {
+ return self.token;
+ }
- pub fn firstToken(self: &NodeNullLiteral) Token {
- return self.token;
- }
+ pub fn lastToken(self: &BoolLiteral) Token {
+ return self.token;
+ }
+ };
- pub fn lastToken(self: &NodeNullLiteral) Token {
- return self.token;
- }
-};
+ pub const NullLiteral = struct {
+ base: Node,
+ token: Token,
-pub const NodeUndefinedLiteral = struct {
- base: Node,
- token: Token,
+ pub fn iterate(self: &NullLiteral, index: usize) ?&Node {
+ return null;
+ }
- pub fn iterate(self: &NodeUndefinedLiteral, index: usize) ?&Node {
- return null;
- }
+ pub fn firstToken(self: &NullLiteral) Token {
+ return self.token;
+ }
- pub fn firstToken(self: &NodeUndefinedLiteral) Token {
- return self.token;
- }
+ pub fn lastToken(self: &NullLiteral) Token {
+ return self.token;
+ }
+ };
- pub fn lastToken(self: &NodeUndefinedLiteral) Token {
- return self.token;
- }
-};
+ pub const UndefinedLiteral = struct {
+ base: Node,
+ token: Token,
-pub const NodeThisLiteral = struct {
- base: Node,
- token: Token,
+ pub fn iterate(self: &UndefinedLiteral, index: usize) ?&Node {
+ return null;
+ }
- pub fn iterate(self: &NodeThisLiteral, index: usize) ?&Node {
- return null;
- }
+ pub fn firstToken(self: &UndefinedLiteral) Token {
+ return self.token;
+ }
- pub fn firstToken(self: &NodeThisLiteral) Token {
- return self.token;
- }
+ pub fn lastToken(self: &UndefinedLiteral) Token {
+ return self.token;
+ }
+ };
- pub fn lastToken(self: &NodeThisLiteral) Token {
- return self.token;
- }
-};
+ pub const ThisLiteral = struct {
+ base: Node,
+ token: Token,
-pub const NodeAsmOutput = struct {
- base: Node,
- symbolic_name: &Node,
- constraint: &Node,
- kind: Kind,
+ pub fn iterate(self: &ThisLiteral, index: usize) ?&Node {
+ return null;
+ }
- const Kind = union(enum) {
- Variable: &NodeIdentifier,
- Return: &Node
+ pub fn firstToken(self: &ThisLiteral) Token {
+ return self.token;
+ }
+
+ pub fn lastToken(self: &ThisLiteral) Token {
+ return self.token;
+ }
};
- pub fn iterate(self: &NodeAsmOutput, index: usize) ?&Node {
- var i = index;
+ pub const AsmOutput = struct {
+ base: Node,
+ symbolic_name: &Node,
+ constraint: &Node,
+ kind: Kind,
- if (i < 1) return self.symbolic_name;
- i -= 1;
+ const Kind = union(enum) {
+ Variable: &Identifier,
+ Return: &Node
+ };
- if (i < 1) return self.constraint;
- i -= 1;
+ pub fn iterate(self: &AsmOutput, index: usize) ?&Node {
+ var i = index;
- switch (self.kind) {
- Kind.Variable => |variable_name| {
- if (i < 1) return &variable_name.base;
- i -= 1;
- },
- Kind.Return => |return_type| {
- if (i < 1) return return_type;
- i -= 1;
+ if (i < 1) return self.symbolic_name;
+ i -= 1;
+
+ if (i < 1) return self.constraint;
+ i -= 1;
+
+ switch (self.kind) {
+ Kind.Variable => |variable_name| {
+ if (i < 1) return &variable_name.base;
+ i -= 1;
+ },
+ Kind.Return => |return_type| {
+ if (i < 1) return return_type;
+ i -= 1;
+ }
}
- }
- return null;
- }
+ return null;
+ }
- pub fn firstToken(self: &NodeAsmOutput) Token {
- return self.symbolic_name.firstToken();
- }
+ pub fn firstToken(self: &AsmOutput) Token {
+ return self.symbolic_name.firstToken();
+ }
- pub fn lastToken(self: &NodeAsmOutput) Token {
- return switch (self.kind) {
- Kind.Variable => |variable_name| variable_name.lastToken(),
- Kind.Return => |return_type| return_type.lastToken(),
- };
- }
-};
+ pub fn lastToken(self: &AsmOutput) Token {
+ return switch (self.kind) {
+ Kind.Variable => |variable_name| variable_name.lastToken(),
+ Kind.Return => |return_type| return_type.lastToken(),
+ };
+ }
+ };
-pub const NodeAsmInput = struct {
- base: Node,
- symbolic_name: &Node,
- constraint: &Node,
- expr: &Node,
+ pub const AsmInput = struct {
+ base: Node,
+ symbolic_name: &Node,
+ constraint: &Node,
+ expr: &Node,
- pub fn iterate(self: &NodeAsmInput, index: usize) ?&Node {
- var i = index;
+ pub fn iterate(self: &AsmInput, index: usize) ?&Node {
+ var i = index;
- if (i < 1) return self.symbolic_name;
- i -= 1;
+ if (i < 1) return self.symbolic_name;
+ i -= 1;
- if (i < 1) return self.constraint;
- i -= 1;
+ if (i < 1) return self.constraint;
+ i -= 1;
- if (i < 1) return self.expr;
- i -= 1;
+ if (i < 1) return self.expr;
+ i -= 1;
- return null;
- }
+ return null;
+ }
- pub fn firstToken(self: &NodeAsmInput) Token {
- return self.symbolic_name.firstToken();
- }
+ pub fn firstToken(self: &AsmInput) Token {
+ return self.symbolic_name.firstToken();
+ }
- pub fn lastToken(self: &NodeAsmInput) Token {
- return self.expr.lastToken();
- }
-};
+ pub fn lastToken(self: &AsmInput) Token {
+ return self.expr.lastToken();
+ }
+ };
-pub const NodeAsm = struct {
- base: Node,
- asm_token: Token,
- volatile_token: ?Token,
- template: &Node,
- //tokens: ArrayList(AsmToken),
- outputs: ArrayList(&NodeAsmOutput),
- inputs: ArrayList(&NodeAsmInput),
- cloppers: ArrayList(&Node),
- rparen: Token,
+ pub const Asm = struct {
+ base: Node,
+ asm_token: Token,
+ volatile_token: ?Token,
+ template: &Node,
+ //tokens: ArrayList(AsmToken),
+ outputs: ArrayList(&AsmOutput),
+ inputs: ArrayList(&AsmInput),
+ cloppers: ArrayList(&Node),
+ rparen: Token,
- pub fn iterate(self: &NodeAsm, index: usize) ?&Node {
- var i = index;
+ pub fn iterate(self: &Asm, index: usize) ?&Node {
+ var i = index;
- if (i < self.outputs.len) return &self.outputs.at(index).base;
- i -= self.outputs.len;
+ if (i < self.outputs.len) return &self.outputs.at(index).base;
+ i -= self.outputs.len;
- if (i < self.inputs.len) return &self.inputs.at(index).base;
- i -= self.inputs.len;
+ if (i < self.inputs.len) return &self.inputs.at(index).base;
+ i -= self.inputs.len;
- if (i < self.cloppers.len) return self.cloppers.at(index);
- i -= self.cloppers.len;
+ if (i < self.cloppers.len) return self.cloppers.at(index);
+ i -= self.cloppers.len;
- return null;
- }
+ return null;
+ }
- pub fn firstToken(self: &NodeAsm) Token {
- return self.asm_token;
- }
+ pub fn firstToken(self: &Asm) Token {
+ return self.asm_token;
+ }
- pub fn lastToken(self: &NodeAsm) Token {
- return self.rparen;
- }
-};
+ pub fn lastToken(self: &Asm) Token {
+ return self.rparen;
+ }
+ };
-pub const NodeUnreachable = struct {
- base: Node,
- token: Token,
+ pub const Unreachable = struct {
+ base: Node,
+ token: Token,
- pub fn iterate(self: &NodeUnreachable, index: usize) ?&Node {
- return null;
- }
+ pub fn iterate(self: &Unreachable, index: usize) ?&Node {
+ return null;
+ }
- pub fn firstToken(self: &NodeUnreachable) Token {
- return self.token;
- }
+ pub fn firstToken(self: &Unreachable) Token {
+ return self.token;
+ }
- pub fn lastToken(self: &NodeUnreachable) Token {
- return self.token;
- }
-};
+ pub fn lastToken(self: &Unreachable) Token {
+ return self.token;
+ }
+ };
-pub const NodeErrorType = struct {
- base: Node,
- token: Token,
+ pub const ErrorType = struct {
+ base: Node,
+ token: Token,
- pub fn iterate(self: &NodeErrorType, index: usize) ?&Node {
- return null;
- }
+ pub fn iterate(self: &ErrorType, index: usize) ?&Node {
+ return null;
+ }
- pub fn firstToken(self: &NodeErrorType) Token {
- return self.token;
- }
+ pub fn firstToken(self: &ErrorType) Token {
+ return self.token;
+ }
- pub fn lastToken(self: &NodeErrorType) Token {
- return self.token;
- }
-};
+ pub fn lastToken(self: &ErrorType) Token {
+ return self.token;
+ }
+ };
-pub const NodeVarType = struct {
- base: Node,
- token: Token,
+ pub const VarType = struct {
+ base: Node,
+ token: Token,
- pub fn iterate(self: &NodeVarType, index: usize) ?&Node {
- return null;
- }
+ pub fn iterate(self: &VarType, index: usize) ?&Node {
+ return null;
+ }
- pub fn firstToken(self: &NodeVarType) Token {
- return self.token;
- }
+ pub fn firstToken(self: &VarType) Token {
+ return self.token;
+ }
- pub fn lastToken(self: &NodeVarType) Token {
- return self.token;
- }
-};
+ pub fn lastToken(self: &VarType) Token {
+ return self.token;
+ }
+ };
-pub const NodeLineComment = struct {
- base: Node,
- lines: ArrayList(Token),
+ pub const LineComment = struct {
+ base: Node,
+ lines: ArrayList(Token),
- pub fn iterate(self: &NodeLineComment, index: usize) ?&Node {
- return null;
- }
+ pub fn iterate(self: &LineComment, index: usize) ?&Node {
+ return null;
+ }
- pub fn firstToken(self: &NodeLineComment) Token {
- return self.lines.at(0);
- }
+ pub fn firstToken(self: &LineComment) Token {
+ return self.lines.at(0);
+ }
- pub fn lastToken(self: &NodeLineComment) Token {
- return self.lines.at(self.lines.len - 1);
- }
-};
+ pub fn lastToken(self: &LineComment) Token {
+ return self.lines.at(self.lines.len - 1);
+ }
+ };
-pub const NodeTestDecl = struct {
- base: Node,
- test_token: Token,
- name: &Node,
- body_node: &Node,
+ pub const TestDecl = struct {
+ base: Node,
+ comments: ?&LineComment,
+ test_token: Token,
+ name: &Node,
+ body_node: &Node,
- pub fn iterate(self: &NodeTestDecl, index: usize) ?&Node {
- var i = index;
+ pub fn iterate(self: &TestDecl, index: usize) ?&Node {
+ var i = index;
- if (i < 1) return self.body_node;
- i -= 1;
+ if (i < 1) return self.body_node;
+ i -= 1;
- return null;
- }
+ return null;
+ }
- pub fn firstToken(self: &NodeTestDecl) Token {
- return self.test_token;
- }
+ pub fn firstToken(self: &TestDecl) Token {
+ return self.test_token;
+ }
- pub fn lastToken(self: &NodeTestDecl) Token {
- return self.body_node.lastToken();
- }
+ pub fn lastToken(self: &TestDecl) Token {
+ return self.body_node.lastToken();
+ }
+ };
};
+
std/zig/parser.zig
@@ -18,10 +18,10 @@ pub const Parser = struct {
put_back_tokens: [2]Token,
put_back_count: usize,
source_file_name: []const u8,
- pending_line_comment_node: ?&ast.NodeLineComment,
+ pending_line_comment_node: ?&ast.Node.LineComment,
pub const Tree = struct {
- root_node: &ast.NodeRoot,
+ root_node: &ast.Node.Root,
arena_allocator: std.heap.ArenaAllocator,
pub fn deinit(self: &Tree) void {
@@ -66,22 +66,24 @@ pub const Parser = struct {
extern_export_token: ?Token,
lib_name: ?&ast.Node,
list: &ArrayList(&ast.Node),
+ comments: ?&ast.Node.LineComment,
};
const TopLevelExternOrFieldCtx = struct {
visib_token: Token,
- container_decl: &ast.NodeContainerDecl,
+ container_decl: &ast.Node.ContainerDecl,
};
const ExternTypeCtx = struct {
opt_ctx: OptionalCtx,
extern_token: Token,
+ comments: ?&ast.Node.LineComment,
};
const ContainerKindCtx = struct {
opt_ctx: OptionalCtx,
ltoken: Token,
- layout: ast.NodeContainerDecl.Layout,
+ layout: ast.Node.ContainerDecl.Layout,
};
const ExpectTokenSave = struct {
@@ -132,7 +134,7 @@ pub const Parser = struct {
const AsyncEndCtx = struct {
ctx: OptionalCtx,
- attribute: &ast.NodeAsyncAttribute,
+ attribute: &ast.Node.AsyncAttribute,
};
const ErrorTypeOrSetDeclCtx = struct {
@@ -141,13 +143,13 @@ pub const Parser = struct {
};
const ParamDeclEndCtx = struct {
- fn_proto: &ast.NodeFnProto,
- param_decl: &ast.NodeParamDecl,
+ fn_proto: &ast.Node.FnProto,
+ param_decl: &ast.Node.ParamDecl,
};
const ComptimeStatementCtx = struct {
comptime_token: Token,
- block: &ast.NodeBlock,
+ block: &ast.Node.Block,
};
const OptionalCtx = union(enum) {
@@ -190,24 +192,24 @@ pub const Parser = struct {
TopLevelExternOrField: TopLevelExternOrFieldCtx,
ContainerKind: ContainerKindCtx,
- ContainerInitArgStart: &ast.NodeContainerDecl,
- ContainerInitArg: &ast.NodeContainerDecl,
- ContainerDecl: &ast.NodeContainerDecl,
+ ContainerInitArgStart: &ast.Node.ContainerDecl,
+ ContainerInitArg: &ast.Node.ContainerDecl,
+ ContainerDecl: &ast.Node.ContainerDecl,
VarDecl: VarDeclCtx,
- VarDeclAlign: &ast.NodeVarDecl,
- VarDeclEq: &ast.NodeVarDecl,
+ VarDeclAlign: &ast.Node.VarDecl,
+ VarDeclEq: &ast.Node.VarDecl,
- FnDef: &ast.NodeFnProto,
- FnProto: &ast.NodeFnProto,
- FnProtoAlign: &ast.NodeFnProto,
- FnProtoReturnType: &ast.NodeFnProto,
+ FnDef: &ast.Node.FnProto,
+ FnProto: &ast.Node.FnProto,
+ FnProtoAlign: &ast.Node.FnProto,
+ FnProtoReturnType: &ast.Node.FnProto,
- ParamDecl: &ast.NodeFnProto,
- ParamDeclAliasOrComptime: &ast.NodeParamDecl,
- ParamDeclName: &ast.NodeParamDecl,
+ ParamDecl: &ast.Node.FnProto,
+ ParamDeclAliasOrComptime: &ast.Node.ParamDecl,
+ ParamDeclName: &ast.Node.ParamDecl,
ParamDeclEnd: ParamDeclEndCtx,
- ParamDeclComma: &ast.NodeFnProto,
+ ParamDeclComma: &ast.Node.FnProto,
MaybeLabeledExpression: MaybeLabeledExpressionCtx,
LabeledExpression: LabelCtx,
@@ -215,39 +217,39 @@ pub const Parser = struct {
While: LoopCtx,
WhileContinueExpr: &?&ast.Node,
For: LoopCtx,
- Else: &?&ast.NodeElse,
+ Else: &?&ast.Node.Else,
- Block: &ast.NodeBlock,
- Statement: &ast.NodeBlock,
+ Block: &ast.Node.Block,
+ Statement: &ast.Node.Block,
ComptimeStatement: ComptimeStatementCtx,
Semicolon: &&ast.Node,
- AsmOutputItems: &ArrayList(&ast.NodeAsmOutput),
- AsmOutputReturnOrType: &ast.NodeAsmOutput,
- AsmInputItems: &ArrayList(&ast.NodeAsmInput),
+ AsmOutputItems: &ArrayList(&ast.Node.AsmOutput),
+ AsmOutputReturnOrType: &ast.Node.AsmOutput,
+ AsmInputItems: &ArrayList(&ast.Node.AsmInput),
AsmClopperItems: &ArrayList(&ast.Node),
ExprListItemOrEnd: ExprListCtx,
ExprListCommaOrEnd: ExprListCtx,
- FieldInitListItemOrEnd: ListSave(&ast.NodeFieldInitializer),
- FieldInitListCommaOrEnd: ListSave(&ast.NodeFieldInitializer),
- FieldListCommaOrEnd: &ast.NodeContainerDecl,
+ FieldInitListItemOrEnd: ListSave(&ast.Node.FieldInitializer),
+ FieldInitListCommaOrEnd: ListSave(&ast.Node.FieldInitializer),
+ FieldListCommaOrEnd: &ast.Node.ContainerDecl,
IdentifierListItemOrEnd: ListSave(&ast.Node),
IdentifierListCommaOrEnd: ListSave(&ast.Node),
- SwitchCaseOrEnd: ListSave(&ast.NodeSwitchCase),
- SwitchCaseCommaOrEnd: ListSave(&ast.NodeSwitchCase),
+ SwitchCaseOrEnd: ListSave(&ast.Node.SwitchCase),
+ SwitchCaseCommaOrEnd: ListSave(&ast.Node.SwitchCase),
SwitchCaseFirstItem: &ArrayList(&ast.Node),
SwitchCaseItem: &ArrayList(&ast.Node),
SwitchCaseItemCommaOrEnd: &ArrayList(&ast.Node),
- SuspendBody: &ast.NodeSuspend,
- AsyncAllocator: &ast.NodeAsyncAttribute,
+ SuspendBody: &ast.Node.Suspend,
+ AsyncAllocator: &ast.Node.AsyncAttribute,
AsyncEnd: AsyncEndCtx,
ExternType: ExternTypeCtx,
- SliceOrArrayAccess: &ast.NodeSuffixOp,
- SliceOrArrayType: &ast.NodePrefixOp,
- AddrOfModifiers: &ast.NodePrefixOp.AddrOfInfo,
+ SliceOrArrayAccess: &ast.Node.SuffixOp,
+ SliceOrArrayType: &ast.Node.PrefixOp,
+ AddrOfModifiers: &ast.Node.PrefixOp.AddrOfInfo,
Payload: OptionalCtx,
PointerPayload: OptionalCtx,
@@ -310,8 +312,8 @@ pub const Parser = struct {
errdefer arena_allocator.deinit();
const arena = &arena_allocator.allocator;
- const root_node = try self.createNode(arena, ast.NodeRoot,
- ast.NodeRoot {
+ const root_node = try self.createNode(arena, ast.Node.Root,
+ ast.Node.Root {
.base = undefined,
.decls = ArrayList(&ast.Node).init(arena),
// initialized when we get the eof token
@@ -334,43 +336,19 @@ pub const Parser = struct {
// warn("\n");
//}
- // look for line comments
- while (true) {
- if (self.eatToken(Token.Id.LineComment)) |line_comment| {
- const node = blk: {
- if (self.pending_line_comment_node) |comment_node| {
- break :blk comment_node;
- } else {
- const comment_node = try arena.create(ast.NodeLineComment);
- *comment_node = ast.NodeLineComment {
- .base = ast.Node {
- .id = ast.Node.Id.LineComment,
- .comment = null,
- },
- .lines = ArrayList(Token).init(arena),
- };
- self.pending_line_comment_node = comment_node;
- break :blk comment_node;
- }
- };
- try node.lines.append(line_comment);
- continue;
- }
- break;
- }
-
// This gives us 1 free append that can't fail
const state = stack.pop();
switch (state) {
State.TopLevel => {
+ const comments = try self.eatComments(arena);
const token = self.getNextToken();
switch (token.id) {
Token.Id.Keyword_test => {
stack.append(State.TopLevel) catch unreachable;
- const block = try self.createNode(arena, ast.NodeBlock,
- ast.NodeBlock {
+ const block = try self.createNode(arena, ast.Node.Block,
+ ast.Node.Block {
.base = undefined,
.label = null,
.lbrace = undefined,
@@ -378,9 +356,10 @@ pub const Parser = struct {
.rbrace = undefined,
}
);
- const test_node = try self.createAttachNode(arena, &root_node.decls, ast.NodeTestDecl,
- ast.NodeTestDecl {
+ const test_node = try self.createAttachNode(arena, &root_node.decls, ast.Node.TestDecl,
+ ast.Node.TestDecl {
.base = undefined,
+ .comments = comments,
.test_token = token,
.name = undefined,
.body_node = &block.base,
@@ -413,8 +392,8 @@ pub const Parser = struct {
continue;
},
Token.Id.Keyword_comptime => {
- const block = try self.createNode(arena, ast.NodeBlock,
- ast.NodeBlock {
+ const block = try self.createNode(arena, ast.Node.Block,
+ ast.Node.Block {
.base = undefined,
.label = null,
.lbrace = undefined,
@@ -422,8 +401,8 @@ pub const Parser = struct {
.rbrace = undefined,
}
);
- const node = try self.createAttachNode(arena, &root_node.decls, ast.NodeComptime,
- ast.NodeComptime {
+ const node = try self.createAttachNode(arena, &root_node.decls, ast.Node.Comptime,
+ ast.Node.Comptime {
.base = undefined,
.comptime_token = token,
.expr = &block.base,
@@ -506,6 +485,7 @@ pub const Parser = struct {
continue;
},
State.TopLevelDecl => |ctx| {
+ const comments = try self.eatComments(arena);
const token = self.getNextToken();
switch (token.id) {
Token.Id.Keyword_use => {
@@ -513,8 +493,8 @@ pub const Parser = struct {
return self.parseError(token, "Invalid token {}", @tagName((??ctx.extern_export_inline_token).id));
}
- const node = try self.createAttachNode(arena, ctx.decls, ast.NodeUse,
- ast.NodeUse {
+ const node = try self.createAttachNode(arena, ctx.decls, ast.Node.Use,
+ ast.Node.Use {
.base = undefined,
.visib_token = ctx.visib_token,
.expr = undefined,
@@ -539,6 +519,7 @@ pub const Parser = struct {
stack.append(State {
.VarDecl = VarDeclCtx {
+ .comments = comments,
.visib_token = ctx.visib_token,
.lib_name = ctx.lib_name,
.comptime_token = null,
@@ -551,9 +532,10 @@ pub const Parser = struct {
},
Token.Id.Keyword_fn, Token.Id.Keyword_nakedcc,
Token.Id.Keyword_stdcallcc, Token.Id.Keyword_async => {
- const fn_proto = try self.createAttachNode(arena, ctx.decls, ast.NodeFnProto,
- ast.NodeFnProto {
+ const fn_proto = try self.createAttachNode(arena, ctx.decls, ast.Node.FnProto,
+ ast.Node.FnProto {
.base = undefined,
+ .comments = comments,
.visib_token = ctx.visib_token,
.name_token = null,
.fn_token = undefined,
@@ -583,8 +565,8 @@ pub const Parser = struct {
continue;
},
Token.Id.Keyword_async => {
- const async_node = try self.createNode(arena, ast.NodeAsyncAttribute,
- ast.NodeAsyncAttribute {
+ const async_node = try self.createNode(arena, ast.Node.AsyncAttribute,
+ ast.Node.AsyncAttribute {
.base = undefined,
.async_token = token,
.allocator_type = null,
@@ -616,9 +598,9 @@ pub const Parser = struct {
},
State.TopLevelExternOrField => |ctx| {
if (self.eatToken(Token.Id.Identifier)) |identifier| {
- std.debug.assert(ctx.container_decl.kind == ast.NodeContainerDecl.Kind.Struct);
- const node = try self.createAttachNode(arena, &ctx.container_decl.fields_and_decls, ast.NodeStructField,
- ast.NodeStructField {
+ std.debug.assert(ctx.container_decl.kind == ast.Node.ContainerDecl.Kind.Struct);
+ const node = try self.createAttachNode(arena, &ctx.container_decl.fields_and_decls, ast.Node.StructField,
+ ast.Node.StructField {
.base = undefined,
.visib_token = ctx.visib_token,
.name_token = identifier,
@@ -647,15 +629,15 @@ pub const Parser = struct {
State.ContainerKind => |ctx| {
const token = self.getNextToken();
- const node = try self.createToCtxNode(arena, ctx.opt_ctx, ast.NodeContainerDecl,
- ast.NodeContainerDecl {
+ const node = try self.createToCtxNode(arena, ctx.opt_ctx, ast.Node.ContainerDecl,
+ ast.Node.ContainerDecl {
.base = undefined,
.ltoken = ctx.ltoken,
.layout = ctx.layout,
.kind = switch (token.id) {
- Token.Id.Keyword_struct => ast.NodeContainerDecl.Kind.Struct,
- Token.Id.Keyword_union => ast.NodeContainerDecl.Kind.Union,
- Token.Id.Keyword_enum => ast.NodeContainerDecl.Kind.Enum,
+ Token.Id.Keyword_struct => ast.Node.ContainerDecl.Kind.Struct,
+ Token.Id.Keyword_union => ast.Node.ContainerDecl.Kind.Union,
+ Token.Id.Keyword_enum => ast.Node.ContainerDecl.Kind.Enum,
else => {
return self.parseError(token, "expected {}, {} or {}, found {}",
@tagName(Token.Id.Keyword_struct),
@@ -664,7 +646,7 @@ pub const Parser = struct {
@tagName(token.id));
},
},
- .init_arg_expr = ast.NodeContainerDecl.InitArg.None,
+ .init_arg_expr = ast.Node.ContainerDecl.InitArg.None,
.fields_and_decls = ArrayList(&ast.Node).init(arena),
.rbrace_token = undefined,
}
@@ -690,11 +672,11 @@ pub const Parser = struct {
const init_arg_token = self.getNextToken();
switch (init_arg_token.id) {
Token.Id.Keyword_enum => {
- container_decl.init_arg_expr = ast.NodeContainerDecl.InitArg.Enum;
+ container_decl.init_arg_expr = ast.Node.ContainerDecl.InitArg.Enum;
},
else => {
self.putBackToken(init_arg_token);
- container_decl.init_arg_expr = ast.NodeContainerDecl.InitArg { .Type = undefined };
+ container_decl.init_arg_expr = ast.Node.ContainerDecl.InitArg { .Type = undefined };
stack.append(State { .Expression = OptionalCtx { .Required = &container_decl.init_arg_expr.Type } }) catch unreachable;
},
}
@@ -705,9 +687,9 @@ pub const Parser = struct {
switch (token.id) {
Token.Id.Identifier => {
switch (container_decl.kind) {
- ast.NodeContainerDecl.Kind.Struct => {
- const node = try self.createAttachNode(arena, &container_decl.fields_and_decls, ast.NodeStructField,
- ast.NodeStructField {
+ ast.Node.ContainerDecl.Kind.Struct => {
+ const node = try self.createAttachNode(arena, &container_decl.fields_and_decls, ast.Node.StructField,
+ ast.Node.StructField {
.base = undefined,
.visib_token = null,
.name_token = token,
@@ -720,9 +702,9 @@ pub const Parser = struct {
try stack.append(State { .ExpectToken = Token.Id.Colon });
continue;
},
- ast.NodeContainerDecl.Kind.Union => {
- const node = try self.createAttachNode(arena, &container_decl.fields_and_decls, ast.NodeUnionTag,
- ast.NodeUnionTag {
+ ast.Node.ContainerDecl.Kind.Union => {
+ const node = try self.createAttachNode(arena, &container_decl.fields_and_decls, ast.Node.UnionTag,
+ ast.Node.UnionTag {
.base = undefined,
.name_token = token,
.type_expr = null,
@@ -734,9 +716,9 @@ pub const Parser = struct {
try stack.append(State { .IfToken = Token.Id.Colon });
continue;
},
- ast.NodeContainerDecl.Kind.Enum => {
- const node = try self.createAttachNode(arena, &container_decl.fields_and_decls, ast.NodeEnumTag,
- ast.NodeEnumTag {
+ ast.Node.ContainerDecl.Kind.Enum => {
+ const node = try self.createAttachNode(arena, &container_decl.fields_and_decls, ast.Node.EnumTag,
+ ast.Node.EnumTag {
.base = undefined,
.name_token = token,
.value = null,
@@ -752,7 +734,7 @@ pub const Parser = struct {
},
Token.Id.Keyword_pub => {
switch (container_decl.kind) {
- ast.NodeContainerDecl.Kind.Struct => {
+ ast.Node.ContainerDecl.Kind.Struct => {
try stack.append(State {
.TopLevelExternOrField = TopLevelExternOrFieldCtx {
.visib_token = token,
@@ -809,9 +791,10 @@ pub const Parser = struct {
State.VarDecl => |ctx| {
- const var_decl = try self.createAttachNode(arena, ctx.list, ast.NodeVarDecl,
- ast.NodeVarDecl {
+ const var_decl = try self.createAttachNode(arena, ctx.list, ast.Node.VarDecl,
+ ast.Node.VarDecl {
.base = undefined,
+ .comments = ctx.comments,
.visib_token = ctx.visib_token,
.mut_token = ctx.mut_token,
.comptime_token = ctx.comptime_token,
@@ -881,8 +864,8 @@ pub const Parser = struct {
const token = self.getNextToken();
switch(token.id) {
Token.Id.LBrace => {
- const block = try self.createNode(arena, ast.NodeBlock,
- ast.NodeBlock {
+ const block = try self.createNode(arena, ast.Node.Block,
+ ast.Node.Block {
.base = undefined,
.label = null,
.lbrace = token,
@@ -924,7 +907,7 @@ pub const Parser = struct {
const token = self.getNextToken();
switch (token.id) {
Token.Id.Bang => {
- fn_proto.return_type = ast.NodeFnProto.ReturnType { .InferErrorSet = undefined };
+ fn_proto.return_type = ast.Node.FnProto.ReturnType { .InferErrorSet = undefined };
stack.append(State {
.TypeExprBegin = OptionalCtx { .Required = &fn_proto.return_type.InferErrorSet },
}) catch unreachable;
@@ -934,15 +917,15 @@ pub const Parser = struct {
// TODO: this is a special case. Remove this when #760 is fixed
if (token.id == Token.Id.Keyword_error) {
if (self.isPeekToken(Token.Id.LBrace)) {
- fn_proto.return_type = ast.NodeFnProto.ReturnType {
- .Explicit = &(try self.createLiteral(arena, ast.NodeErrorType, token)).base
+ fn_proto.return_type = ast.Node.FnProto.ReturnType {
+ .Explicit = &(try self.createLiteral(arena, ast.Node.ErrorType, token)).base
};
continue;
}
}
self.putBackToken(token);
- fn_proto.return_type = ast.NodeFnProto.ReturnType { .Explicit = undefined };
+ fn_proto.return_type = ast.Node.FnProto.ReturnType { .Explicit = undefined };
stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &fn_proto.return_type.Explicit }, }) catch unreachable;
continue;
},
@@ -954,8 +937,8 @@ pub const Parser = struct {
if (self.eatToken(Token.Id.RParen)) |_| {
continue;
}
- const param_decl = try self.createAttachNode(arena, &fn_proto.params, ast.NodeParamDecl,
- ast.NodeParamDecl {
+ const param_decl = try self.createAttachNode(arena, &fn_proto.params, ast.Node.ParamDecl,
+ ast.Node.ParamDecl {
.base = undefined,
.comptime_token = null,
.noalias_token = null,
@@ -1026,15 +1009,15 @@ pub const Parser = struct {
continue;
}
- _ = try self.createToCtxLiteral(arena, ctx.opt_ctx, ast.NodeIdentifier, ctx.label);
+ _ = try self.createToCtxLiteral(arena, ctx.opt_ctx, ast.Node.Identifier, ctx.label);
continue;
},
State.LabeledExpression => |ctx| {
const token = self.getNextToken();
switch (token.id) {
Token.Id.LBrace => {
- const block = try self.createToCtxNode(arena, ctx.opt_ctx, ast.NodeBlock,
- ast.NodeBlock {
+ const block = try self.createToCtxNode(arena, ctx.opt_ctx, ast.Node.Block,
+ ast.Node.Block {
.base = undefined,
.label = ctx.label,
.lbrace = token,
@@ -1123,8 +1106,8 @@ pub const Parser = struct {
}
},
State.While => |ctx| {
- const node = try self.createToCtxNode(arena, ctx.opt_ctx, ast.NodeWhile,
- ast.NodeWhile {
+ const node = try self.createToCtxNode(arena, ctx.opt_ctx, ast.Node.While,
+ ast.Node.While {
.base = undefined,
.label = ctx.label,
.inline_token = ctx.inline_token,
@@ -1153,8 +1136,8 @@ pub const Parser = struct {
continue;
},
State.For => |ctx| {
- const node = try self.createToCtxNode(arena, ctx.opt_ctx, ast.NodeFor,
- ast.NodeFor {
+ const node = try self.createToCtxNode(arena, ctx.opt_ctx, ast.Node.For,
+ ast.Node.For {
.base = undefined,
.label = ctx.label,
.inline_token = ctx.inline_token,
@@ -1175,8 +1158,8 @@ pub const Parser = struct {
},
State.Else => |dest| {
if (self.eatToken(Token.Id.Keyword_else)) |else_token| {
- const node = try self.createNode(arena, ast.NodeElse,
- ast.NodeElse {
+ const node = try self.createNode(arena, ast.Node.Else,
+ ast.Node.Else {
.base = undefined,
.else_token = else_token,
.payload = null,
@@ -1210,6 +1193,7 @@ pub const Parser = struct {
}
},
State.Statement => |block| {
+ const comments = try self.eatComments(arena);
const token = self.getNextToken();
switch (token.id) {
Token.Id.Keyword_comptime => {
@@ -1224,6 +1208,7 @@ pub const Parser = struct {
Token.Id.Keyword_var, Token.Id.Keyword_const => {
stack.append(State {
.VarDecl = VarDeclCtx {
+ .comments = comments,
.visib_token = null,
.comptime_token = null,
.extern_export_token = null,
@@ -1235,13 +1220,13 @@ pub const Parser = struct {
continue;
},
Token.Id.Keyword_defer, Token.Id.Keyword_errdefer => {
- const node = try self.createAttachNode(arena, &block.statements, ast.NodeDefer,
- ast.NodeDefer {
+ const node = try self.createAttachNode(arena, &block.statements, ast.Node.Defer,
+ ast.Node.Defer {
.base = undefined,
.defer_token = token,
.kind = switch (token.id) {
- Token.Id.Keyword_defer => ast.NodeDefer.Kind.Unconditional,
- Token.Id.Keyword_errdefer => ast.NodeDefer.Kind.Error,
+ Token.Id.Keyword_defer => ast.Node.Defer.Kind.Unconditional,
+ Token.Id.Keyword_errdefer => ast.Node.Defer.Kind.Error,
else => unreachable,
},
.expr = undefined,
@@ -1252,8 +1237,8 @@ pub const Parser = struct {
continue;
},
Token.Id.LBrace => {
- const inner_block = try self.createAttachNode(arena, &block.statements, ast.NodeBlock,
- ast.NodeBlock {
+ const inner_block = try self.createAttachNode(arena, &block.statements, ast.Node.Block,
+ ast.Node.Block {
.base = undefined,
.label = null,
.lbrace = token,
@@ -1274,11 +1259,13 @@ pub const Parser = struct {
}
},
State.ComptimeStatement => |ctx| {
+ const comments = try self.eatComments(arena);
const token = self.getNextToken();
switch (token.id) {
Token.Id.Keyword_var, Token.Id.Keyword_const => {
stack.append(State {
.VarDecl = VarDeclCtx {
+ .comments = comments,
.visib_token = null,
.comptime_token = ctx.comptime_token,
.extern_export_token = null,
@@ -1316,8 +1303,8 @@ pub const Parser = struct {
continue;
}
- const node = try self.createNode(arena, ast.NodeAsmOutput,
- ast.NodeAsmOutput {
+ const node = try self.createNode(arena, ast.Node.AsmOutput,
+ ast.Node.AsmOutput {
.base = undefined,
.symbolic_name = undefined,
.constraint = undefined,
@@ -1340,11 +1327,11 @@ pub const Parser = struct {
const token = self.getNextToken();
switch (token.id) {
Token.Id.Identifier => {
- node.kind = ast.NodeAsmOutput.Kind { .Variable = try self.createLiteral(arena, ast.NodeIdentifier, token) };
+ node.kind = ast.Node.AsmOutput.Kind { .Variable = try self.createLiteral(arena, ast.Node.Identifier, token) };
continue;
},
Token.Id.Arrow => {
- node.kind = ast.NodeAsmOutput.Kind { .Return = undefined };
+ node.kind = ast.Node.AsmOutput.Kind { .Return = undefined };
try stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &node.kind.Return } });
continue;
},
@@ -1362,8 +1349,8 @@ pub const Parser = struct {
continue;
}
- const node = try self.createNode(arena, ast.NodeAsmInput,
- ast.NodeAsmInput {
+ const node = try self.createNode(arena, ast.Node.AsmInput,
+ ast.Node.AsmInput {
.base = undefined,
.symbolic_name = undefined,
.constraint = undefined,
@@ -1415,8 +1402,8 @@ pub const Parser = struct {
continue;
}
- const node = try self.createNode(arena, ast.NodeFieldInitializer,
- ast.NodeFieldInitializer {
+ const node = try self.createNode(arena, ast.Node.FieldInitializer,
+ ast.Node.FieldInitializer {
.base = undefined,
.period_token = undefined,
.name_token = undefined,
@@ -1485,8 +1472,8 @@ pub const Parser = struct {
continue;
}
- const node = try self.createNode(arena, ast.NodeSwitchCase,
- ast.NodeSwitchCase {
+ const node = try self.createNode(arena, ast.Node.SwitchCase,
+ ast.Node.SwitchCase {
.base = undefined,
.items = ArrayList(&ast.Node).init(arena),
.payload = null,
@@ -1512,8 +1499,8 @@ pub const Parser = struct {
State.SwitchCaseFirstItem => |case_items| {
const token = self.getNextToken();
if (token.id == Token.Id.Keyword_else) {
- const else_node = try self.createAttachNode(arena, case_items, ast.NodeSwitchElse,
- ast.NodeSwitchElse {
+ const else_node = try self.createAttachNode(arena, case_items, ast.Node.SwitchElse,
+ ast.Node.SwitchElse {
.base = undefined,
.token = token,
}
@@ -1564,24 +1551,24 @@ pub const Parser = struct {
switch (node.id) {
ast.Node.Id.FnProto => {
- const fn_proto = @fieldParentPtr(ast.NodeFnProto, "base", node);
+ const fn_proto = @fieldParentPtr(ast.Node.FnProto, "base", node);
fn_proto.async_attr = ctx.attribute;
continue;
},
ast.Node.Id.SuffixOp => {
- const suffix_op = @fieldParentPtr(ast.NodeSuffixOp, "base", node);
- if (suffix_op.op == ast.NodeSuffixOp.SuffixOp.Call) {
+ const suffix_op = @fieldParentPtr(ast.Node.SuffixOp, "base", node);
+ if (suffix_op.op == ast.Node.SuffixOp.Op.Call) {
suffix_op.op.Call.async_attr = ctx.attribute;
continue;
}
return self.parseError(node.firstToken(), "expected {}, found {}.",
- @tagName(ast.NodeSuffixOp.SuffixOp.Call),
+ @tagName(ast.Node.SuffixOp.Op.Call),
@tagName(suffix_op.op));
},
else => {
return self.parseError(node.firstToken(), "expected {} or {}, found {}.",
- @tagName(ast.NodeSuffixOp.SuffixOp.Call),
+ @tagName(ast.Node.SuffixOp.Op.Call),
@tagName(ast.Node.Id.FnProto),
@tagName(node.id));
}
@@ -1591,9 +1578,10 @@ pub const Parser = struct {
State.ExternType => |ctx| {
if (self.eatToken(Token.Id.Keyword_fn)) |fn_token| {
- const fn_proto = try self.createToCtxNode(arena, ctx.opt_ctx, ast.NodeFnProto,
- ast.NodeFnProto {
+ const fn_proto = try self.createToCtxNode(arena, ctx.opt_ctx, ast.Node.FnProto,
+ ast.Node.FnProto {
.base = undefined,
+ .comments = ctx.comments,
.visib_token = null,
.name_token = null,
.fn_token = fn_token,
@@ -1616,7 +1604,7 @@ pub const Parser = struct {
.ContainerKind = ContainerKindCtx {
.opt_ctx = ctx.opt_ctx,
.ltoken = ctx.extern_token,
- .layout = ast.NodeContainerDecl.Layout.Extern,
+ .layout = ast.Node.ContainerDecl.Layout.Extern,
},
}) catch unreachable;
continue;
@@ -1626,8 +1614,8 @@ pub const Parser = struct {
switch (token.id) {
Token.Id.Ellipsis2 => {
const start = node.op.ArrayAccess;
- node.op = ast.NodeSuffixOp.SuffixOp {
- .Slice = ast.NodeSuffixOp.SliceRange {
+ node.op = ast.Node.SuffixOp.Op {
+ .Slice = ast.Node.SuffixOp.SliceRange {
.start = start,
.end = null,
}
@@ -1653,8 +1641,8 @@ pub const Parser = struct {
},
State.SliceOrArrayType => |node| {
if (self.eatToken(Token.Id.RBracket)) |_| {
- node.op = ast.NodePrefixOp.PrefixOp {
- .SliceType = ast.NodePrefixOp.AddrOfInfo {
+ node.op = ast.Node.PrefixOp.Op {
+ .SliceType = ast.Node.PrefixOp.AddrOfInfo {
.align_expr = null,
.bit_offset_start_token = null,
.bit_offset_end_token = null,
@@ -1667,7 +1655,7 @@ pub const Parser = struct {
continue;
}
- node.op = ast.NodePrefixOp.PrefixOp { .ArrayType = undefined };
+ node.op = ast.Node.PrefixOp.Op { .ArrayType = undefined };
stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &node.rhs } }) catch unreachable;
try stack.append(State { .ExpectToken = Token.Id.RBracket });
try stack.append(State { .Expression = OptionalCtx { .Required = &node.op.ArrayType } });
@@ -1723,8 +1711,8 @@ pub const Parser = struct {
continue;
}
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodePayload,
- ast.NodePayload {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.Payload,
+ ast.Node.Payload {
.base = undefined,
.lpipe = token,
.error_symbol = undefined,
@@ -1754,8 +1742,8 @@ pub const Parser = struct {
continue;
}
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodePointerPayload,
- ast.NodePointerPayload {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.PointerPayload,
+ ast.Node.PointerPayload {
.base = undefined,
.lpipe = token,
.ptr_token = null,
@@ -1792,8 +1780,8 @@ pub const Parser = struct {
continue;
}
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodePointerIndexPayload,
- ast.NodePointerIndexPayload {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.PointerIndexPayload,
+ ast.Node.PointerIndexPayload {
.base = undefined,
.lpipe = token,
.ptr_token = null,
@@ -1826,8 +1814,8 @@ pub const Parser = struct {
const token = self.getNextToken();
switch (token.id) {
Token.Id.Keyword_return, Token.Id.Keyword_break, Token.Id.Keyword_continue => {
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeControlFlowExpression,
- ast.NodeControlFlowExpression {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.ControlFlowExpression,
+ ast.Node.ControlFlowExpression {
.base = undefined,
.ltoken = token,
.kind = undefined,
@@ -1839,31 +1827,31 @@ pub const Parser = struct {
switch (token.id) {
Token.Id.Keyword_break => {
- node.kind = ast.NodeControlFlowExpression.Kind { .Break = null };
+ node.kind = ast.Node.ControlFlowExpression.Kind { .Break = null };
try stack.append(State { .Identifier = OptionalCtx { .RequiredNull = &node.kind.Break } });
try stack.append(State { .IfToken = Token.Id.Colon });
},
Token.Id.Keyword_continue => {
- node.kind = ast.NodeControlFlowExpression.Kind { .Continue = null };
+ node.kind = ast.Node.ControlFlowExpression.Kind { .Continue = null };
try stack.append(State { .Identifier = OptionalCtx { .RequiredNull = &node.kind.Continue } });
try stack.append(State { .IfToken = Token.Id.Colon });
},
Token.Id.Keyword_return => {
- node.kind = ast.NodeControlFlowExpression.Kind.Return;
+ node.kind = ast.Node.ControlFlowExpression.Kind.Return;
},
else => unreachable,
}
continue;
},
Token.Id.Keyword_try, Token.Id.Keyword_cancel, Token.Id.Keyword_resume => {
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodePrefixOp,
- ast.NodePrefixOp {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.PrefixOp,
+ ast.Node.PrefixOp {
.base = undefined,
.op_token = token,
.op = switch (token.id) {
- Token.Id.Keyword_try => ast.NodePrefixOp.PrefixOp { .Try = void{} },
- Token.Id.Keyword_cancel => ast.NodePrefixOp.PrefixOp { .Cancel = void{} },
- Token.Id.Keyword_resume => ast.NodePrefixOp.PrefixOp { .Resume = void{} },
+ Token.Id.Keyword_try => ast.Node.PrefixOp.Op { .Try = void{} },
+ Token.Id.Keyword_cancel => ast.Node.PrefixOp.Op { .Cancel = void{} },
+ Token.Id.Keyword_resume => ast.Node.PrefixOp.Op { .Resume = void{} },
else => unreachable,
},
.rhs = undefined,
@@ -1891,12 +1879,12 @@ pub const Parser = struct {
const lhs = opt_ctx.get() ?? continue;
if (self.eatToken(Token.Id.Ellipsis3)) |ellipsis3| {
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
- ast.NodeInfixOp {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,
+ ast.Node.InfixOp {
.base = undefined,
.lhs = lhs,
.op_token = ellipsis3,
- .op = ast.NodeInfixOp.InfixOp.Range,
+ .op = ast.Node.InfixOp.Op.Range,
.rhs = undefined,
}
);
@@ -1915,8 +1903,8 @@ pub const Parser = struct {
const token = self.getNextToken();
if (tokenIdToAssignment(token.id)) |ass_id| {
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
- ast.NodeInfixOp {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,
+ ast.Node.InfixOp {
.base = undefined,
.lhs = lhs,
.op_token = token,
@@ -1944,8 +1932,8 @@ pub const Parser = struct {
const token = self.getNextToken();
if (tokenIdToUnwrapExpr(token.id)) |unwrap_id| {
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
- ast.NodeInfixOp {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,
+ ast.Node.InfixOp {
.base = undefined,
.lhs = lhs,
.op_token = token,
@@ -1957,7 +1945,7 @@ pub const Parser = struct {
stack.append(State { .UnwrapExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
try stack.append(State { .Expression = OptionalCtx { .Required = &node.rhs } });
- if (node.op == ast.NodeInfixOp.InfixOp.Catch) {
+ if (node.op == ast.Node.InfixOp.Op.Catch) {
try stack.append(State { .Payload = OptionalCtx { .Optional = &node.op.Catch } });
}
continue;
@@ -1977,12 +1965,12 @@ pub const Parser = struct {
const lhs = opt_ctx.get() ?? continue;
if (self.eatToken(Token.Id.Keyword_or)) |or_token| {
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
- ast.NodeInfixOp {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,
+ ast.Node.InfixOp {
.base = undefined,
.lhs = lhs,
.op_token = or_token,
- .op = ast.NodeInfixOp.InfixOp.BoolOr,
+ .op = ast.Node.InfixOp.Op.BoolOr,
.rhs = undefined,
}
);
@@ -2002,12 +1990,12 @@ pub const Parser = struct {
const lhs = opt_ctx.get() ?? continue;
if (self.eatToken(Token.Id.Keyword_and)) |and_token| {
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
- ast.NodeInfixOp {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,
+ ast.Node.InfixOp {
.base = undefined,
.lhs = lhs,
.op_token = and_token,
- .op = ast.NodeInfixOp.InfixOp.BoolAnd,
+ .op = ast.Node.InfixOp.Op.BoolAnd,
.rhs = undefined,
}
);
@@ -2028,8 +2016,8 @@ pub const Parser = struct {
const token = self.getNextToken();
if (tokenIdToComparison(token.id)) |comp_id| {
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
- ast.NodeInfixOp {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,
+ ast.Node.InfixOp {
.base = undefined,
.lhs = lhs,
.op_token = token,
@@ -2056,12 +2044,12 @@ pub const Parser = struct {
const lhs = opt_ctx.get() ?? continue;
if (self.eatToken(Token.Id.Pipe)) |pipe| {
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
- ast.NodeInfixOp {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,
+ ast.Node.InfixOp {
.base = undefined,
.lhs = lhs,
.op_token = pipe,
- .op = ast.NodeInfixOp.InfixOp.BitOr,
+ .op = ast.Node.InfixOp.Op.BitOr,
.rhs = undefined,
}
);
@@ -2081,12 +2069,12 @@ pub const Parser = struct {
const lhs = opt_ctx.get() ?? continue;
if (self.eatToken(Token.Id.Caret)) |caret| {
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
- ast.NodeInfixOp {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,
+ ast.Node.InfixOp {
.base = undefined,
.lhs = lhs,
.op_token = caret,
- .op = ast.NodeInfixOp.InfixOp.BitXor,
+ .op = ast.Node.InfixOp.Op.BitXor,
.rhs = undefined,
}
);
@@ -2106,12 +2094,12 @@ pub const Parser = struct {
const lhs = opt_ctx.get() ?? continue;
if (self.eatToken(Token.Id.Ampersand)) |ampersand| {
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
- ast.NodeInfixOp {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,
+ ast.Node.InfixOp {
.base = undefined,
.lhs = lhs,
.op_token = ampersand,
- .op = ast.NodeInfixOp.InfixOp.BitAnd,
+ .op = ast.Node.InfixOp.Op.BitAnd,
.rhs = undefined,
}
);
@@ -2132,8 +2120,8 @@ pub const Parser = struct {
const token = self.getNextToken();
if (tokenIdToBitShift(token.id)) |bitshift_id| {
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
- ast.NodeInfixOp {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,
+ ast.Node.InfixOp {
.base = undefined,
.lhs = lhs,
.op_token = token,
@@ -2161,8 +2149,8 @@ pub const Parser = struct {
const token = self.getNextToken();
if (tokenIdToAddition(token.id)) |add_id| {
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
- ast.NodeInfixOp {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,
+ ast.Node.InfixOp {
.base = undefined,
.lhs = lhs,
.op_token = token,
@@ -2190,8 +2178,8 @@ pub const Parser = struct {
const token = self.getNextToken();
if (tokenIdToMultiply(token.id)) |mult_id| {
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
- ast.NodeInfixOp {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,
+ ast.Node.InfixOp {
.base = undefined,
.lhs = lhs,
.op_token = token,
@@ -2219,12 +2207,12 @@ pub const Parser = struct {
const lhs = opt_ctx.get() ?? continue;
if (self.isPeekToken(Token.Id.Period)) {
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeSuffixOp,
- ast.NodeSuffixOp {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.SuffixOp,
+ ast.Node.SuffixOp {
.base = undefined,
.lhs = lhs,
- .op = ast.NodeSuffixOp.SuffixOp {
- .StructInitializer = ArrayList(&ast.NodeFieldInitializer).init(arena),
+ .op = ast.Node.SuffixOp.Op {
+ .StructInitializer = ArrayList(&ast.Node.FieldInitializer).init(arena),
},
.rtoken = undefined,
}
@@ -2232,7 +2220,7 @@ pub const Parser = struct {
stack.append(State { .CurlySuffixExpressionEnd = opt_ctx.toRequired() }) catch unreachable;
try stack.append(State { .IfToken = Token.Id.LBrace });
try stack.append(State {
- .FieldInitListItemOrEnd = ListSave(&ast.NodeFieldInitializer) {
+ .FieldInitListItemOrEnd = ListSave(&ast.Node.FieldInitializer) {
.list = &node.op.StructInitializer,
.ptr = &node.rtoken,
}
@@ -2240,11 +2228,11 @@ pub const Parser = struct {
continue;
}
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeSuffixOp,
- ast.NodeSuffixOp {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.SuffixOp,
+ ast.Node.SuffixOp {
.base = undefined,
.lhs = lhs,
- .op = ast.NodeSuffixOp.SuffixOp {
+ .op = ast.Node.SuffixOp.Op {
.ArrayInitializer = ArrayList(&ast.Node).init(arena),
},
.rtoken = undefined,
@@ -2272,12 +2260,12 @@ pub const Parser = struct {
const lhs = opt_ctx.get() ?? continue;
if (self.eatToken(Token.Id.Bang)) |bang| {
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
- ast.NodeInfixOp {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,
+ ast.Node.InfixOp {
.base = undefined,
.lhs = lhs,
.op_token = bang,
- .op = ast.NodeInfixOp.InfixOp.ErrorUnion,
+ .op = ast.Node.InfixOp.Op.ErrorUnion,
.rhs = undefined,
}
);
@@ -2290,8 +2278,8 @@ pub const Parser = struct {
State.PrefixOpExpression => |opt_ctx| {
const token = self.getNextToken();
if (tokenIdToPrefixOp(token.id)) |prefix_id| {
- var node = try self.createToCtxNode(arena, opt_ctx, ast.NodePrefixOp,
- ast.NodePrefixOp {
+ var node = try self.createToCtxNode(arena, opt_ctx, ast.Node.PrefixOp,
+ ast.Node.PrefixOp {
.base = undefined,
.op_token = token,
.op = prefix_id,
@@ -2301,8 +2289,8 @@ pub const Parser = struct {
// Treat '**' token as two derefs
if (token.id == Token.Id.AsteriskAsterisk) {
- const child = try self.createNode(arena, ast.NodePrefixOp,
- ast.NodePrefixOp {
+ const child = try self.createNode(arena, ast.Node.PrefixOp,
+ ast.Node.PrefixOp {
.base = undefined,
.op_token = token,
.op = prefix_id,
@@ -2314,7 +2302,7 @@ pub const Parser = struct {
}
stack.append(State { .TypeExprBegin = OptionalCtx { .Required = &node.rhs } }) catch unreachable;
- if (node.op == ast.NodePrefixOp.PrefixOp.AddrOf) {
+ if (node.op == ast.Node.PrefixOp.Op.AddrOf) {
try stack.append(State { .AddrOfModifiers = &node.op.AddrOf });
}
continue;
@@ -2327,8 +2315,8 @@ pub const Parser = struct {
State.SuffixOpExpressionBegin => |opt_ctx| {
if (self.eatToken(Token.Id.Keyword_async)) |async_token| {
- const async_node = try self.createNode(arena, ast.NodeAsyncAttribute,
- ast.NodeAsyncAttribute {
+ const async_node = try self.createNode(arena, ast.Node.AsyncAttribute,
+ ast.Node.AsyncAttribute {
.base = undefined,
.async_token = async_token,
.allocator_type = null,
@@ -2358,12 +2346,12 @@ pub const Parser = struct {
const token = self.getNextToken();
switch (token.id) {
Token.Id.LParen => {
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeSuffixOp,
- ast.NodeSuffixOp {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.SuffixOp,
+ ast.Node.SuffixOp {
.base = undefined,
.lhs = lhs,
- .op = ast.NodeSuffixOp.SuffixOp {
- .Call = ast.NodeSuffixOp.CallInfo {
+ .op = ast.Node.SuffixOp.Op {
+ .Call = ast.Node.SuffixOp.CallInfo {
.params = ArrayList(&ast.Node).init(arena),
.async_attr = null,
}
@@ -2382,11 +2370,11 @@ pub const Parser = struct {
continue;
},
Token.Id.LBracket => {
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeSuffixOp,
- ast.NodeSuffixOp {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.SuffixOp,
+ ast.Node.SuffixOp {
.base = undefined,
.lhs = lhs,
- .op = ast.NodeSuffixOp.SuffixOp {
+ .op = ast.Node.SuffixOp.Op {
.ArrayAccess = undefined,
},
.rtoken = undefined
@@ -2398,12 +2386,12 @@ pub const Parser = struct {
continue;
},
Token.Id.Period => {
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeInfixOp,
- ast.NodeInfixOp {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.InfixOp,
+ ast.Node.InfixOp {
.base = undefined,
.lhs = lhs,
.op_token = token,
- .op = ast.NodeInfixOp.InfixOp.Period,
+ .op = ast.Node.InfixOp.Op.Period,
.rhs = undefined,
}
);
@@ -2422,39 +2410,39 @@ pub const Parser = struct {
const token = self.getNextToken();
switch (token.id) {
Token.Id.IntegerLiteral => {
- _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeStringLiteral, token);
+ _ = try self.createToCtxLiteral(arena, opt_ctx, ast.Node.StringLiteral, token);
continue;
},
Token.Id.FloatLiteral => {
- _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeFloatLiteral, token);
+ _ = try self.createToCtxLiteral(arena, opt_ctx, ast.Node.FloatLiteral, token);
continue;
},
Token.Id.CharLiteral => {
- _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeCharLiteral, token);
+ _ = try self.createToCtxLiteral(arena, opt_ctx, ast.Node.CharLiteral, token);
continue;
},
Token.Id.Keyword_undefined => {
- _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeUndefinedLiteral, token);
+ _ = try self.createToCtxLiteral(arena, opt_ctx, ast.Node.UndefinedLiteral, token);
continue;
},
Token.Id.Keyword_true, Token.Id.Keyword_false => {
- _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeBoolLiteral, token);
+ _ = try self.createToCtxLiteral(arena, opt_ctx, ast.Node.BoolLiteral, token);
continue;
},
Token.Id.Keyword_null => {
- _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeNullLiteral, token);
+ _ = try self.createToCtxLiteral(arena, opt_ctx, ast.Node.NullLiteral, token);
continue;
},
Token.Id.Keyword_this => {
- _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeThisLiteral, token);
+ _ = try self.createToCtxLiteral(arena, opt_ctx, ast.Node.ThisLiteral, token);
continue;
},
Token.Id.Keyword_var => {
- _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeVarType, token);
+ _ = try self.createToCtxLiteral(arena, opt_ctx, ast.Node.VarType, token);
continue;
},
Token.Id.Keyword_unreachable => {
- _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeUnreachable, token);
+ _ = try self.createToCtxLiteral(arena, opt_ctx, ast.Node.Unreachable, token);
continue;
},
Token.Id.StringLiteral, Token.Id.MultilineStringLiteralLine => {
@@ -2462,8 +2450,8 @@ pub const Parser = struct {
continue;
},
Token.Id.LParen => {
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeGroupedExpression,
- ast.NodeGroupedExpression {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.GroupedExpression,
+ ast.Node.GroupedExpression {
.base = undefined,
.lparen = token,
.expr = undefined,
@@ -2480,8 +2468,8 @@ pub const Parser = struct {
continue;
},
Token.Id.Builtin => {
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeBuiltinCall,
- ast.NodeBuiltinCall {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.BuiltinCall,
+ ast.Node.BuiltinCall {
.base = undefined,
.builtin_token = token,
.params = ArrayList(&ast.Node).init(arena),
@@ -2499,8 +2487,8 @@ pub const Parser = struct {
continue;
},
Token.Id.LBracket => {
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodePrefixOp,
- ast.NodePrefixOp {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.PrefixOp,
+ ast.Node.PrefixOp {
.base = undefined,
.op_token = token,
.op = undefined,
@@ -2524,7 +2512,7 @@ pub const Parser = struct {
.ContainerKind = ContainerKindCtx {
.opt_ctx = opt_ctx,
.ltoken = token,
- .layout = ast.NodeContainerDecl.Layout.Packed,
+ .layout = ast.Node.ContainerDecl.Layout.Packed,
},
}) catch unreachable;
continue;
@@ -2534,6 +2522,7 @@ pub const Parser = struct {
.ExternType = ExternTypeCtx {
.opt_ctx = opt_ctx,
.extern_token = token,
+ .comments = null,
},
}) catch unreachable;
continue;
@@ -2544,7 +2533,7 @@ pub const Parser = struct {
.ContainerKind = ContainerKindCtx {
.opt_ctx = opt_ctx,
.ltoken = token,
- .layout = ast.NodeContainerDecl.Layout.Auto,
+ .layout = ast.Node.ContainerDecl.Layout.Auto,
},
}) catch unreachable;
continue;
@@ -2559,9 +2548,10 @@ pub const Parser = struct {
continue;
},
Token.Id.Keyword_fn => {
- const fn_proto = try self.createToCtxNode(arena, opt_ctx, ast.NodeFnProto,
- ast.NodeFnProto {
+ const fn_proto = try self.createToCtxNode(arena, opt_ctx, ast.Node.FnProto,
+ ast.Node.FnProto {
.base = undefined,
+ .comments = null,
.visib_token = null,
.name_token = null,
.fn_token = token,
@@ -2580,9 +2570,10 @@ pub const Parser = struct {
continue;
},
Token.Id.Keyword_nakedcc, Token.Id.Keyword_stdcallcc => {
- const fn_proto = try self.createToCtxNode(arena, opt_ctx, ast.NodeFnProto,
- ast.NodeFnProto {
+ const fn_proto = try self.createToCtxNode(arena, opt_ctx, ast.Node.FnProto,
+ ast.Node.FnProto {
.base = undefined,
+ .comments = null,
.visib_token = null,
.name_token = null,
.fn_token = undefined,
@@ -2607,15 +2598,15 @@ pub const Parser = struct {
continue;
},
Token.Id.Keyword_asm => {
- const node = try self.createToCtxNode(arena, opt_ctx, ast.NodeAsm,
- ast.NodeAsm {
+ const node = try self.createToCtxNode(arena, opt_ctx, ast.Node.Asm,
+ ast.Node.Asm {
.base = undefined,
.asm_token = token,
.volatile_token = null,
.template = undefined,
- //.tokens = ArrayList(ast.NodeAsm.AsmToken).init(arena),
- .outputs = ArrayList(&ast.NodeAsmOutput).init(arena),
- .inputs = ArrayList(&ast.NodeAsmInput).init(arena),
+ //.tokens = ArrayList(ast.Node.Asm.AsmToken).init(arena),
+ .outputs = ArrayList(&ast.Node.AsmOutput).init(arena),
+ .inputs = ArrayList(&ast.Node.AsmInput).init(arena),
.cloppers = ArrayList(&ast.Node).init(arena),
.rparen = undefined,
}
@@ -2666,12 +2657,12 @@ pub const Parser = struct {
State.ErrorTypeOrSetDecl => |ctx| {
if (self.eatToken(Token.Id.LBrace) == null) {
- _ = try self.createToCtxLiteral(arena, ctx.opt_ctx, ast.NodeErrorType, ctx.error_token);
+ _ = try self.createToCtxLiteral(arena, ctx.opt_ctx, ast.Node.ErrorType, ctx.error_token);
continue;
}
- const node = try self.createToCtxNode(arena, ctx.opt_ctx, ast.NodeErrorSetDecl,
- ast.NodeErrorSetDecl {
+ const node = try self.createToCtxNode(arena, ctx.opt_ctx, ast.Node.ErrorSetDecl,
+ ast.Node.ErrorSetDecl {
.base = undefined,
.error_token = ctx.error_token,
.decls = ArrayList(&ast.Node).init(arena),
@@ -2702,7 +2693,7 @@ pub const Parser = struct {
},
State.Identifier => |opt_ctx| {
if (self.eatToken(Token.Id.Identifier)) |ident_token| {
- _ = try self.createToCtxLiteral(arena, opt_ctx, ast.NodeIdentifier, ident_token);
+ _ = try self.createToCtxLiteral(arena, opt_ctx, ast.Node.Identifier, ident_token);
continue;
}
@@ -2750,6 +2741,33 @@ pub const Parser = struct {
}
}
+ fn eatComments(self: &Parser, arena: &mem.Allocator) !?&ast.Node.LineComment {
+ var result: ?&ast.Node.LineComment = null;
+ while (true) {
+ if (self.eatToken(Token.Id.LineComment)) |line_comment| {
+ const node = blk: {
+ if (result) |comment_node| {
+ break :blk comment_node;
+ } else {
+ const comment_node = try arena.create(ast.Node.LineComment);
+ *comment_node = ast.Node.LineComment {
+ .base = ast.Node {
+ .id = ast.Node.Id.LineComment,
+ },
+ .lines = ArrayList(Token).init(arena),
+ };
+ result = comment_node;
+ break :blk comment_node;
+ }
+ };
+ try node.lines.append(line_comment);
+ continue;
+ }
+ break;
+ }
+ return result;
+ }
+
fn requireSemiColon(node: &const ast.Node) bool {
var n = node;
while (true) {
@@ -2770,7 +2788,7 @@ pub const Parser = struct {
ast.Node.Id.LineComment,
ast.Node.Id.TestDecl => return false,
ast.Node.Id.While => {
- const while_node = @fieldParentPtr(ast.NodeWhile, "base", n);
+ const while_node = @fieldParentPtr(ast.Node.While, "base", n);
if (while_node.@"else") |@"else"| {
n = @"else".base;
continue;
@@ -2779,7 +2797,7 @@ pub const Parser = struct {
return while_node.body.id != ast.Node.Id.Block;
},
ast.Node.Id.For => {
- const for_node = @fieldParentPtr(ast.NodeFor, "base", n);
+ const for_node = @fieldParentPtr(ast.Node.For, "base", n);
if (for_node.@"else") |@"else"| {
n = @"else".base;
continue;
@@ -2788,7 +2806,7 @@ pub const Parser = struct {
return for_node.body.id != ast.Node.Id.Block;
},
ast.Node.Id.If => {
- const if_node = @fieldParentPtr(ast.NodeIf, "base", n);
+ const if_node = @fieldParentPtr(ast.Node.If, "base", n);
if (if_node.@"else") |@"else"| {
n = @"else".base;
continue;
@@ -2797,20 +2815,20 @@ pub const Parser = struct {
return if_node.body.id != ast.Node.Id.Block;
},
ast.Node.Id.Else => {
- const else_node = @fieldParentPtr(ast.NodeElse, "base", n);
+ const else_node = @fieldParentPtr(ast.Node.Else, "base", n);
n = else_node.body;
continue;
},
ast.Node.Id.Defer => {
- const defer_node = @fieldParentPtr(ast.NodeDefer, "base", n);
+ const defer_node = @fieldParentPtr(ast.Node.Defer, "base", n);
return defer_node.expr.id != ast.Node.Id.Block;
},
ast.Node.Id.Comptime => {
- const comptime_node = @fieldParentPtr(ast.NodeComptime, "base", n);
+ const comptime_node = @fieldParentPtr(ast.Node.Comptime, "base", n);
return comptime_node.expr.id != ast.Node.Id.Block;
},
ast.Node.Id.Suspend => {
- const suspend_node = @fieldParentPtr(ast.NodeSuspend, "base", n);
+ const suspend_node = @fieldParentPtr(ast.Node.Suspend, "base", n);
if (suspend_node.body) |body| {
return body.id != ast.Node.Id.Block;
}
@@ -2825,11 +2843,11 @@ pub const Parser = struct {
fn parseStringLiteral(self: &Parser, arena: &mem.Allocator, token: &const Token) !?&ast.Node {
switch (token.id) {
Token.Id.StringLiteral => {
- return &(try self.createLiteral(arena, ast.NodeStringLiteral, token)).base;
+ return &(try self.createLiteral(arena, ast.Node.StringLiteral, token)).base;
},
Token.Id.MultilineStringLiteralLine => {
- const node = try self.createNode(arena, ast.NodeMultilineStringLiteral,
- ast.NodeMultilineStringLiteral {
+ const node = try self.createNode(arena, ast.Node.MultilineStringLiteral,
+ ast.Node.MultilineStringLiteral {
.base = undefined,
.tokens = ArrayList(Token).init(arena),
}
@@ -2856,8 +2874,8 @@ pub const Parser = struct {
fn parseBlockExpr(self: &Parser, stack: &ArrayList(State), arena: &mem.Allocator, ctx: &const OptionalCtx, token: &const Token) !bool {
switch (token.id) {
Token.Id.Keyword_suspend => {
- const node = try self.createToCtxNode(arena, ctx, ast.NodeSuspend,
- ast.NodeSuspend {
+ const node = try self.createToCtxNode(arena, ctx, ast.Node.Suspend,
+ ast.Node.Suspend {
.base = undefined,
.suspend_token = *token,
.payload = null,
@@ -2870,8 +2888,8 @@ pub const Parser = struct {
return true;
},
Token.Id.Keyword_if => {
- const node = try self.createToCtxNode(arena, ctx, ast.NodeIf,
- ast.NodeIf {
+ const node = try self.createToCtxNode(arena, ctx, ast.Node.If,
+ ast.Node.If {
.base = undefined,
.if_token = *token,
.condition = undefined,
@@ -2912,18 +2930,18 @@ pub const Parser = struct {
return true;
},
Token.Id.Keyword_switch => {
- const node = try self.createToCtxNode(arena, ctx, ast.NodeSwitch,
- ast.NodeSwitch {
+ const node = try self.createToCtxNode(arena, ctx, ast.Node.Switch,
+ ast.Node.Switch {
.base = undefined,
.switch_token = *token,
.expr = undefined,
- .cases = ArrayList(&ast.NodeSwitchCase).init(arena),
+ .cases = ArrayList(&ast.Node.SwitchCase).init(arena),
.rbrace = undefined,
}
);
stack.append(State {
- .SwitchCaseOrEnd = ListSave(&ast.NodeSwitchCase) {
+ .SwitchCaseOrEnd = ListSave(&ast.Node.SwitchCase) {
.list = &node.cases,
.ptr = &node.rbrace,
},
@@ -2935,8 +2953,8 @@ pub const Parser = struct {
return true;
},
Token.Id.Keyword_comptime => {
- const node = try self.createToCtxNode(arena, ctx, ast.NodeComptime,
- ast.NodeComptime {
+ const node = try self.createToCtxNode(arena, ctx, ast.Node.Comptime,
+ ast.Node.Comptime {
.base = undefined,
.comptime_token = *token,
.expr = undefined,
@@ -2946,8 +2964,8 @@ pub const Parser = struct {
return true;
},
Token.Id.LBrace => {
- const block = try self.createToCtxNode(arena, ctx, ast.NodeBlock,
- ast.NodeBlock {
+ const block = try self.createToCtxNode(arena, ctx, ast.Node.Block,
+ ast.Node.Block {
.base = undefined,
.label = null,
.lbrace = *token,
@@ -2978,88 +2996,88 @@ pub const Parser = struct {
}
}
- fn tokenIdToAssignment(id: &const Token.Id) ?ast.NodeInfixOp.InfixOp {
+ fn tokenIdToAssignment(id: &const Token.Id) ?ast.Node.InfixOp.Op {
// TODO: We have to cast all cases because of this:
// error: expected type '?InfixOp', found '?@TagType(InfixOp)'
return switch (*id) {
- Token.Id.AmpersandEqual => ast.NodeInfixOp.InfixOp { .AssignBitAnd = void{} },
- Token.Id.AngleBracketAngleBracketLeftEqual => ast.NodeInfixOp.InfixOp { .AssignBitShiftLeft = void{} },
- Token.Id.AngleBracketAngleBracketRightEqual => ast.NodeInfixOp.InfixOp { .AssignBitShiftRight = void{} },
- Token.Id.AsteriskEqual => ast.NodeInfixOp.InfixOp { .AssignTimes = void{} },
- Token.Id.AsteriskPercentEqual => ast.NodeInfixOp.InfixOp { .AssignTimesWarp = void{} },
- Token.Id.CaretEqual => ast.NodeInfixOp.InfixOp { .AssignBitXor = void{} },
- Token.Id.Equal => ast.NodeInfixOp.InfixOp { .Assign = void{} },
- Token.Id.MinusEqual => ast.NodeInfixOp.InfixOp { .AssignMinus = void{} },
- Token.Id.MinusPercentEqual => ast.NodeInfixOp.InfixOp { .AssignMinusWrap = void{} },
- Token.Id.PercentEqual => ast.NodeInfixOp.InfixOp { .AssignMod = void{} },
- Token.Id.PipeEqual => ast.NodeInfixOp.InfixOp { .AssignBitOr = void{} },
- Token.Id.PlusEqual => ast.NodeInfixOp.InfixOp { .AssignPlus = void{} },
- Token.Id.PlusPercentEqual => ast.NodeInfixOp.InfixOp { .AssignPlusWrap = void{} },
- Token.Id.SlashEqual => ast.NodeInfixOp.InfixOp { .AssignDiv = void{} },
+ Token.Id.AmpersandEqual => ast.Node.InfixOp.Op { .AssignBitAnd = void{} },
+ Token.Id.AngleBracketAngleBracketLeftEqual => ast.Node.InfixOp.Op { .AssignBitShiftLeft = void{} },
+ Token.Id.AngleBracketAngleBracketRightEqual => ast.Node.InfixOp.Op { .AssignBitShiftRight = void{} },
+ Token.Id.AsteriskEqual => ast.Node.InfixOp.Op { .AssignTimes = void{} },
+ Token.Id.AsteriskPercentEqual => ast.Node.InfixOp.Op { .AssignTimesWarp = void{} },
+ Token.Id.CaretEqual => ast.Node.InfixOp.Op { .AssignBitXor = void{} },
+ Token.Id.Equal => ast.Node.InfixOp.Op { .Assign = void{} },
+ Token.Id.MinusEqual => ast.Node.InfixOp.Op { .AssignMinus = void{} },
+ Token.Id.MinusPercentEqual => ast.Node.InfixOp.Op { .AssignMinusWrap = void{} },
+ Token.Id.PercentEqual => ast.Node.InfixOp.Op { .AssignMod = void{} },
+ Token.Id.PipeEqual => ast.Node.InfixOp.Op { .AssignBitOr = void{} },
+ Token.Id.PlusEqual => ast.Node.InfixOp.Op { .AssignPlus = void{} },
+ Token.Id.PlusPercentEqual => ast.Node.InfixOp.Op { .AssignPlusWrap = void{} },
+ Token.Id.SlashEqual => ast.Node.InfixOp.Op { .AssignDiv = void{} },
else => null,
};
}
- fn tokenIdToUnwrapExpr(id: @TagType(Token.Id)) ?ast.NodeInfixOp.InfixOp {
+ fn tokenIdToUnwrapExpr(id: @TagType(Token.Id)) ?ast.Node.InfixOp.Op {
return switch (id) {
- Token.Id.Keyword_catch => ast.NodeInfixOp.InfixOp { .Catch = null },
- Token.Id.QuestionMarkQuestionMark => ast.NodeInfixOp.InfixOp { .UnwrapMaybe = void{} },
+ Token.Id.Keyword_catch => ast.Node.InfixOp.Op { .Catch = null },
+ Token.Id.QuestionMarkQuestionMark => ast.Node.InfixOp.Op { .UnwrapMaybe = void{} },
else => null,
};
}
- fn tokenIdToComparison(id: @TagType(Token.Id)) ?ast.NodeInfixOp.InfixOp {
+ fn tokenIdToComparison(id: @TagType(Token.Id)) ?ast.Node.InfixOp.Op {
return switch (id) {
- Token.Id.BangEqual => ast.NodeInfixOp.InfixOp { .BangEqual = void{} },
- Token.Id.EqualEqual => ast.NodeInfixOp.InfixOp { .EqualEqual = void{} },
- Token.Id.AngleBracketLeft => ast.NodeInfixOp.InfixOp { .LessThan = void{} },
- Token.Id.AngleBracketLeftEqual => ast.NodeInfixOp.InfixOp { .LessOrEqual = void{} },
- Token.Id.AngleBracketRight => ast.NodeInfixOp.InfixOp { .GreaterThan = void{} },
- Token.Id.AngleBracketRightEqual => ast.NodeInfixOp.InfixOp { .GreaterOrEqual = void{} },
+ Token.Id.BangEqual => ast.Node.InfixOp.Op { .BangEqual = void{} },
+ Token.Id.EqualEqual => ast.Node.InfixOp.Op { .EqualEqual = void{} },
+ Token.Id.AngleBracketLeft => ast.Node.InfixOp.Op { .LessThan = void{} },
+ Token.Id.AngleBracketLeftEqual => ast.Node.InfixOp.Op { .LessOrEqual = void{} },
+ Token.Id.AngleBracketRight => ast.Node.InfixOp.Op { .GreaterThan = void{} },
+ Token.Id.AngleBracketRightEqual => ast.Node.InfixOp.Op { .GreaterOrEqual = void{} },
else => null,
};
}
- fn tokenIdToBitShift(id: @TagType(Token.Id)) ?ast.NodeInfixOp.InfixOp {
+ fn tokenIdToBitShift(id: @TagType(Token.Id)) ?ast.Node.InfixOp.Op {
return switch (id) {
- Token.Id.AngleBracketAngleBracketLeft => ast.NodeInfixOp.InfixOp { .BitShiftLeft = void{} },
- Token.Id.AngleBracketAngleBracketRight => ast.NodeInfixOp.InfixOp { .BitShiftRight = void{} },
+ Token.Id.AngleBracketAngleBracketLeft => ast.Node.InfixOp.Op { .BitShiftLeft = void{} },
+ Token.Id.AngleBracketAngleBracketRight => ast.Node.InfixOp.Op { .BitShiftRight = void{} },
else => null,
};
}
- fn tokenIdToAddition(id: @TagType(Token.Id)) ?ast.NodeInfixOp.InfixOp {
+ fn tokenIdToAddition(id: @TagType(Token.Id)) ?ast.Node.InfixOp.Op {
return switch (id) {
- Token.Id.Minus => ast.NodeInfixOp.InfixOp { .Sub = void{} },
- Token.Id.MinusPercent => ast.NodeInfixOp.InfixOp { .SubWrap = void{} },
- Token.Id.Plus => ast.NodeInfixOp.InfixOp { .Add = void{} },
- Token.Id.PlusPercent => ast.NodeInfixOp.InfixOp { .AddWrap = void{} },
- Token.Id.PlusPlus => ast.NodeInfixOp.InfixOp { .ArrayCat = void{} },
+ Token.Id.Minus => ast.Node.InfixOp.Op { .Sub = void{} },
+ Token.Id.MinusPercent => ast.Node.InfixOp.Op { .SubWrap = void{} },
+ Token.Id.Plus => ast.Node.InfixOp.Op { .Add = void{} },
+ Token.Id.PlusPercent => ast.Node.InfixOp.Op { .AddWrap = void{} },
+ Token.Id.PlusPlus => ast.Node.InfixOp.Op { .ArrayCat = void{} },
else => null,
};
}
- fn tokenIdToMultiply(id: @TagType(Token.Id)) ?ast.NodeInfixOp.InfixOp {
+ fn tokenIdToMultiply(id: @TagType(Token.Id)) ?ast.Node.InfixOp.Op {
return switch (id) {
- Token.Id.Slash => ast.NodeInfixOp.InfixOp { .Div = void{} },
- Token.Id.Asterisk => ast.NodeInfixOp.InfixOp { .Mult = void{} },
- Token.Id.AsteriskAsterisk => ast.NodeInfixOp.InfixOp { .ArrayMult = void{} },
- Token.Id.AsteriskPercent => ast.NodeInfixOp.InfixOp { .MultWrap = void{} },
- Token.Id.Percent => ast.NodeInfixOp.InfixOp { .Mod = void{} },
- Token.Id.PipePipe => ast.NodeInfixOp.InfixOp { .MergeErrorSets = void{} },
+ Token.Id.Slash => ast.Node.InfixOp.Op { .Div = void{} },
+ Token.Id.Asterisk => ast.Node.InfixOp.Op { .Mult = void{} },
+ Token.Id.AsteriskAsterisk => ast.Node.InfixOp.Op { .ArrayMult = void{} },
+ Token.Id.AsteriskPercent => ast.Node.InfixOp.Op { .MultWrap = void{} },
+ Token.Id.Percent => ast.Node.InfixOp.Op { .Mod = void{} },
+ Token.Id.PipePipe => ast.Node.InfixOp.Op { .MergeErrorSets = void{} },
else => null,
};
}
- fn tokenIdToPrefixOp(id: @TagType(Token.Id)) ?ast.NodePrefixOp.PrefixOp {
+ fn tokenIdToPrefixOp(id: @TagType(Token.Id)) ?ast.Node.PrefixOp.Op {
return switch (id) {
- Token.Id.Bang => ast.NodePrefixOp.PrefixOp { .BoolNot = void{} },
- Token.Id.Tilde => ast.NodePrefixOp.PrefixOp { .BitNot = void{} },
- Token.Id.Minus => ast.NodePrefixOp.PrefixOp { .Negation = void{} },
- Token.Id.MinusPercent => ast.NodePrefixOp.PrefixOp { .NegationWrap = void{} },
- Token.Id.Asterisk, Token.Id.AsteriskAsterisk => ast.NodePrefixOp.PrefixOp { .Deref = void{} },
- Token.Id.Ampersand => ast.NodePrefixOp.PrefixOp {
- .AddrOf = ast.NodePrefixOp.AddrOfInfo {
+ Token.Id.Bang => ast.Node.PrefixOp.Op { .BoolNot = void{} },
+ Token.Id.Tilde => ast.Node.PrefixOp.Op { .BitNot = void{} },
+ Token.Id.Minus => ast.Node.PrefixOp.Op { .Negation = void{} },
+ Token.Id.MinusPercent => ast.Node.PrefixOp.Op { .NegationWrap = void{} },
+ Token.Id.Asterisk, Token.Id.AsteriskAsterisk => ast.Node.PrefixOp.Op { .Deref = void{} },
+ Token.Id.Ampersand => ast.Node.PrefixOp.Op {
+ .AddrOf = ast.Node.PrefixOp.AddrOfInfo {
.align_expr = null,
.bit_offset_start_token = null,
.bit_offset_end_token = null,
@@ -3067,10 +3085,10 @@ pub const Parser = struct {
.volatile_token = null,
},
},
- Token.Id.QuestionMark => ast.NodePrefixOp.PrefixOp { .MaybeType = void{} },
- Token.Id.QuestionMarkQuestionMark => ast.NodePrefixOp.PrefixOp { .UnwrapMaybe = void{} },
- Token.Id.Keyword_await => ast.NodePrefixOp.PrefixOp { .Await = void{} },
- Token.Id.Keyword_try => ast.NodePrefixOp.PrefixOp { .Try = void{ } },
+ Token.Id.QuestionMark => ast.Node.PrefixOp.Op { .MaybeType = void{} },
+ Token.Id.QuestionMarkQuestionMark => ast.Node.PrefixOp.Op { .UnwrapMaybe = void{} },
+ Token.Id.Keyword_await => ast.Node.PrefixOp.Op { .Await = void{} },
+ Token.Id.Keyword_try => ast.Node.PrefixOp.Op { .Try = void{ } },
else => null,
};
}
@@ -3080,11 +3098,7 @@ pub const Parser = struct {
*node = *init_to;
node.base = blk: {
const id = ast.Node.typeToId(T);
- if (self.pending_line_comment_node) |comment_node| {
- self.pending_line_comment_node = null;
- break :blk ast.Node {.id = id, .comment = comment_node};
- }
- break :blk ast.Node {.id = id, .comment = null };
+ break :blk ast.Node {.id = id};
};
return node;
@@ -3183,7 +3197,7 @@ pub const Parser = struct {
indent: usize,
};
- pub fn renderAst(self: &Parser, stream: var, root_node: &ast.NodeRoot) !void {
+ pub fn renderAst(self: &Parser, stream: var, root_node: &ast.Node.Root) !void {
var stack = self.initUtilityArrayList(RenderAstFrame);
defer self.deinitUtilityArrayList(stack);
@@ -3215,14 +3229,14 @@ pub const Parser = struct {
ParamDecl: &ast.Node,
Text: []const u8,
Expression: &ast.Node,
- VarDecl: &ast.NodeVarDecl,
+ VarDecl: &ast.Node.VarDecl,
Statement: &ast.Node,
- FieldInitializer: &ast.NodeFieldInitializer,
+ FieldInitializer: &ast.Node.FieldInitializer,
PrintIndent,
Indent: usize,
};
- pub fn renderSource(self: &Parser, stream: var, root_node: &ast.NodeRoot) !void {
+ pub fn renderSource(self: &Parser, stream: var, root_node: &ast.Node.Root) !void {
var stack = self.initUtilityArrayList(RenderState);
defer self.deinitUtilityArrayList(stack);
@@ -3256,7 +3270,8 @@ pub const Parser = struct {
RenderState.TopLevelDecl => |decl| {
switch (decl.id) {
ast.Node.Id.FnProto => {
- const fn_proto = @fieldParentPtr(ast.NodeFnProto, "base", decl);
+ const fn_proto = @fieldParentPtr(ast.Node.FnProto, "base", decl);
+ try self.renderComments(stream, fn_proto, indent);
if (fn_proto.body_node) |body_node| {
stack.append(RenderState { .Expression = body_node}) catch unreachable;
@@ -3268,7 +3283,7 @@ pub const Parser = struct {
try stack.append(RenderState { .Expression = decl });
},
ast.Node.Id.Use => {
- const use_decl = @fieldParentPtr(ast.NodeUse, "base", decl);
+ const use_decl = @fieldParentPtr(ast.Node.Use, "base", decl);
if (use_decl.visib_token) |visib_token| {
try stream.print("{} ", self.tokenizer.getTokenSlice(visib_token));
}
@@ -3277,18 +3292,19 @@ pub const Parser = struct {
try stack.append(RenderState { .Expression = use_decl.expr });
},
ast.Node.Id.VarDecl => {
- const var_decl = @fieldParentPtr(ast.NodeVarDecl, "base", decl);
+ const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", decl);
try stack.append(RenderState { .VarDecl = var_decl});
},
ast.Node.Id.TestDecl => {
- const test_decl = @fieldParentPtr(ast.NodeTestDecl, "base", decl);
+ const test_decl = @fieldParentPtr(ast.Node.TestDecl, "base", decl);
+ try self.renderComments(stream, test_decl, indent);
try stream.print("test ");
try stack.append(RenderState { .Expression = test_decl.body_node });
try stack.append(RenderState { .Text = " " });
try stack.append(RenderState { .Expression = test_decl.name });
},
ast.Node.Id.StructField => {
- const field = @fieldParentPtr(ast.NodeStructField, "base", decl);
+ const field = @fieldParentPtr(ast.Node.StructField, "base", decl);
if (field.visib_token) |visib_token| {
try stream.print("{} ", self.tokenizer.getTokenSlice(visib_token));
}
@@ -3296,7 +3312,7 @@ pub const Parser = struct {
try stack.append(RenderState { .Expression = field.type_expr});
},
ast.Node.Id.UnionTag => {
- const tag = @fieldParentPtr(ast.NodeUnionTag, "base", decl);
+ const tag = @fieldParentPtr(ast.Node.UnionTag, "base", decl);
try stream.print("{}", self.tokenizer.getTokenSlice(tag.name_token));
if (tag.type_expr) |type_expr| {
@@ -3305,7 +3321,7 @@ pub const Parser = struct {
}
},
ast.Node.Id.EnumTag => {
- const tag = @fieldParentPtr(ast.NodeEnumTag, "base", decl);
+ const tag = @fieldParentPtr(ast.Node.EnumTag, "base", decl);
try stream.print("{}", self.tokenizer.getTokenSlice(tag.name_token));
if (tag.value) |value| {
@@ -3324,6 +3340,7 @@ pub const Parser = struct {
},
RenderState.FieldInitializer => |field_init| {
+ //TODO try self.renderComments(stream, field_init, indent);
try stream.print(".{}", self.tokenizer.getTokenSlice(field_init.name_token));
try stream.print(" = ");
try stack.append(RenderState { .Expression = field_init.expr });
@@ -3369,7 +3386,8 @@ pub const Parser = struct {
},
RenderState.ParamDecl => |base| {
- const param_decl = @fieldParentPtr(ast.NodeParamDecl, "base", base);
+ const param_decl = @fieldParentPtr(ast.Node.ParamDecl, "base", base);
+ // TODO try self.renderComments(stream, param_decl, indent);
if (param_decl.comptime_token) |comptime_token| {
try stream.print("{} ", self.tokenizer.getTokenSlice(comptime_token));
}
@@ -3390,11 +3408,11 @@ pub const Parser = struct {
},
RenderState.Expression => |base| switch (base.id) {
ast.Node.Id.Identifier => {
- const identifier = @fieldParentPtr(ast.NodeIdentifier, "base", base);
+ const identifier = @fieldParentPtr(ast.Node.Identifier, "base", base);
try stream.print("{}", self.tokenizer.getTokenSlice(identifier.token));
},
ast.Node.Id.Block => {
- const block = @fieldParentPtr(ast.NodeBlock, "base", base);
+ const block = @fieldParentPtr(ast.Node.Block, "base", base);
if (block.label) |label| {
try stream.print("{}: ", self.tokenizer.getTokenSlice(label));
}
@@ -3430,17 +3448,17 @@ pub const Parser = struct {
}
},
ast.Node.Id.Defer => {
- const defer_node = @fieldParentPtr(ast.NodeDefer, "base", base);
+ const defer_node = @fieldParentPtr(ast.Node.Defer, "base", base);
try stream.print("{} ", self.tokenizer.getTokenSlice(defer_node.defer_token));
try stack.append(RenderState { .Expression = defer_node.expr });
},
ast.Node.Id.Comptime => {
- const comptime_node = @fieldParentPtr(ast.NodeComptime, "base", base);
+ const comptime_node = @fieldParentPtr(ast.Node.Comptime, "base", base);
try stream.print("{} ", self.tokenizer.getTokenSlice(comptime_node.comptime_token));
try stack.append(RenderState { .Expression = comptime_node.expr });
},
ast.Node.Id.AsyncAttribute => {
- const async_attr = @fieldParentPtr(ast.NodeAsyncAttribute, "base", base);
+ const async_attr = @fieldParentPtr(ast.Node.AsyncAttribute, "base", base);
try stream.print("{}", self.tokenizer.getTokenSlice(async_attr.async_token));
if (async_attr.allocator_type) |allocator_type| {
@@ -3450,7 +3468,7 @@ pub const Parser = struct {
}
},
ast.Node.Id.Suspend => {
- const suspend_node = @fieldParentPtr(ast.NodeSuspend, "base", base);
+ const suspend_node = @fieldParentPtr(ast.Node.Suspend, "base", base);
try stream.print("{}", self.tokenizer.getTokenSlice(suspend_node.suspend_token));
if (suspend_node.body) |body| {
@@ -3464,10 +3482,10 @@ pub const Parser = struct {
}
},
ast.Node.Id.InfixOp => {
- const prefix_op_node = @fieldParentPtr(ast.NodeInfixOp, "base", base);
+ const prefix_op_node = @fieldParentPtr(ast.Node.InfixOp, "base", base);
try stack.append(RenderState { .Expression = prefix_op_node.rhs });
- if (prefix_op_node.op == ast.NodeInfixOp.InfixOp.Catch) {
+ if (prefix_op_node.op == ast.Node.InfixOp.Op.Catch) {
if (prefix_op_node.op.Catch) |payload| {
try stack.append(RenderState { .Text = " " });
try stack.append(RenderState { .Expression = payload });
@@ -3475,49 +3493,49 @@ pub const Parser = struct {
try stack.append(RenderState { .Text = " catch " });
} else {
const text = switch (prefix_op_node.op) {
- ast.NodeInfixOp.InfixOp.Add => " + ",
- ast.NodeInfixOp.InfixOp.AddWrap => " +% ",
- ast.NodeInfixOp.InfixOp.ArrayCat => " ++ ",
- ast.NodeInfixOp.InfixOp.ArrayMult => " ** ",
- ast.NodeInfixOp.InfixOp.Assign => " = ",
- ast.NodeInfixOp.InfixOp.AssignBitAnd => " &= ",
- ast.NodeInfixOp.InfixOp.AssignBitOr => " |= ",
- ast.NodeInfixOp.InfixOp.AssignBitShiftLeft => " <<= ",
- ast.NodeInfixOp.InfixOp.AssignBitShiftRight => " >>= ",
- ast.NodeInfixOp.InfixOp.AssignBitXor => " ^= ",
- ast.NodeInfixOp.InfixOp.AssignDiv => " /= ",
- ast.NodeInfixOp.InfixOp.AssignMinus => " -= ",
- ast.NodeInfixOp.InfixOp.AssignMinusWrap => " -%= ",
- ast.NodeInfixOp.InfixOp.AssignMod => " %= ",
- ast.NodeInfixOp.InfixOp.AssignPlus => " += ",
- ast.NodeInfixOp.InfixOp.AssignPlusWrap => " +%= ",
- ast.NodeInfixOp.InfixOp.AssignTimes => " *= ",
- ast.NodeInfixOp.InfixOp.AssignTimesWarp => " *%= ",
- ast.NodeInfixOp.InfixOp.BangEqual => " != ",
- ast.NodeInfixOp.InfixOp.BitAnd => " & ",
- ast.NodeInfixOp.InfixOp.BitOr => " | ",
- ast.NodeInfixOp.InfixOp.BitShiftLeft => " << ",
- ast.NodeInfixOp.InfixOp.BitShiftRight => " >> ",
- ast.NodeInfixOp.InfixOp.BitXor => " ^ ",
- ast.NodeInfixOp.InfixOp.BoolAnd => " and ",
- ast.NodeInfixOp.InfixOp.BoolOr => " or ",
- ast.NodeInfixOp.InfixOp.Div => " / ",
- ast.NodeInfixOp.InfixOp.EqualEqual => " == ",
- ast.NodeInfixOp.InfixOp.ErrorUnion => "!",
- ast.NodeInfixOp.InfixOp.GreaterOrEqual => " >= ",
- ast.NodeInfixOp.InfixOp.GreaterThan => " > ",
- ast.NodeInfixOp.InfixOp.LessOrEqual => " <= ",
- ast.NodeInfixOp.InfixOp.LessThan => " < ",
- ast.NodeInfixOp.InfixOp.MergeErrorSets => " || ",
- ast.NodeInfixOp.InfixOp.Mod => " % ",
- ast.NodeInfixOp.InfixOp.Mult => " * ",
- ast.NodeInfixOp.InfixOp.MultWrap => " *% ",
- ast.NodeInfixOp.InfixOp.Period => ".",
- ast.NodeInfixOp.InfixOp.Sub => " - ",
- ast.NodeInfixOp.InfixOp.SubWrap => " -% ",
- ast.NodeInfixOp.InfixOp.UnwrapMaybe => " ?? ",
- ast.NodeInfixOp.InfixOp.Range => " ... ",
- ast.NodeInfixOp.InfixOp.Catch => unreachable,
+ ast.Node.InfixOp.Op.Add => " + ",
+ ast.Node.InfixOp.Op.AddWrap => " +% ",
+ ast.Node.InfixOp.Op.ArrayCat => " ++ ",
+ ast.Node.InfixOp.Op.ArrayMult => " ** ",
+ ast.Node.InfixOp.Op.Assign => " = ",
+ ast.Node.InfixOp.Op.AssignBitAnd => " &= ",
+ ast.Node.InfixOp.Op.AssignBitOr => " |= ",
+ ast.Node.InfixOp.Op.AssignBitShiftLeft => " <<= ",
+ ast.Node.InfixOp.Op.AssignBitShiftRight => " >>= ",
+ ast.Node.InfixOp.Op.AssignBitXor => " ^= ",
+ ast.Node.InfixOp.Op.AssignDiv => " /= ",
+ ast.Node.InfixOp.Op.AssignMinus => " -= ",
+ ast.Node.InfixOp.Op.AssignMinusWrap => " -%= ",
+ ast.Node.InfixOp.Op.AssignMod => " %= ",
+ ast.Node.InfixOp.Op.AssignPlus => " += ",
+ ast.Node.InfixOp.Op.AssignPlusWrap => " +%= ",
+ ast.Node.InfixOp.Op.AssignTimes => " *= ",
+ ast.Node.InfixOp.Op.AssignTimesWarp => " *%= ",
+ ast.Node.InfixOp.Op.BangEqual => " != ",
+ ast.Node.InfixOp.Op.BitAnd => " & ",
+ ast.Node.InfixOp.Op.BitOr => " | ",
+ ast.Node.InfixOp.Op.BitShiftLeft => " << ",
+ ast.Node.InfixOp.Op.BitShiftRight => " >> ",
+ ast.Node.InfixOp.Op.BitXor => " ^ ",
+ ast.Node.InfixOp.Op.BoolAnd => " and ",
+ ast.Node.InfixOp.Op.BoolOr => " or ",
+ ast.Node.InfixOp.Op.Div => " / ",
+ ast.Node.InfixOp.Op.EqualEqual => " == ",
+ ast.Node.InfixOp.Op.ErrorUnion => "!",
+ ast.Node.InfixOp.Op.GreaterOrEqual => " >= ",
+ ast.Node.InfixOp.Op.GreaterThan => " > ",
+ ast.Node.InfixOp.Op.LessOrEqual => " <= ",
+ ast.Node.InfixOp.Op.LessThan => " < ",
+ ast.Node.InfixOp.Op.MergeErrorSets => " || ",
+ ast.Node.InfixOp.Op.Mod => " % ",
+ ast.Node.InfixOp.Op.Mult => " * ",
+ ast.Node.InfixOp.Op.MultWrap => " *% ",
+ ast.Node.InfixOp.Op.Period => ".",
+ ast.Node.InfixOp.Op.Sub => " - ",
+ ast.Node.InfixOp.Op.SubWrap => " -% ",
+ ast.Node.InfixOp.Op.UnwrapMaybe => " ?? ",
+ ast.Node.InfixOp.Op.Range => " ... ",
+ ast.Node.InfixOp.Op.Catch => unreachable,
};
try stack.append(RenderState { .Text = text });
@@ -3525,10 +3543,10 @@ pub const Parser = struct {
try stack.append(RenderState { .Expression = prefix_op_node.lhs });
},
ast.Node.Id.PrefixOp => {
- const prefix_op_node = @fieldParentPtr(ast.NodePrefixOp, "base", base);
+ const prefix_op_node = @fieldParentPtr(ast.Node.PrefixOp, "base", base);
try stack.append(RenderState { .Expression = prefix_op_node.rhs });
switch (prefix_op_node.op) {
- ast.NodePrefixOp.PrefixOp.AddrOf => |addr_of_info| {
+ ast.Node.PrefixOp.Op.AddrOf => |addr_of_info| {
try stream.write("&");
if (addr_of_info.volatile_token != null) {
try stack.append(RenderState { .Text = "volatile "});
@@ -3542,7 +3560,7 @@ pub const Parser = struct {
try stack.append(RenderState { .Expression = align_expr});
}
},
- ast.NodePrefixOp.PrefixOp.SliceType => |addr_of_info| {
+ ast.Node.PrefixOp.Op.SliceType => |addr_of_info| {
try stream.write("[]");
if (addr_of_info.volatile_token != null) {
try stack.append(RenderState { .Text = "volatile "});
@@ -3556,29 +3574,29 @@ pub const Parser = struct {
try stack.append(RenderState { .Expression = align_expr});
}
},
- ast.NodePrefixOp.PrefixOp.ArrayType => |array_index| {
+ ast.Node.PrefixOp.Op.ArrayType => |array_index| {
try stack.append(RenderState { .Text = "]"});
try stack.append(RenderState { .Expression = array_index});
try stack.append(RenderState { .Text = "["});
},
- ast.NodePrefixOp.PrefixOp.BitNot => try stream.write("~"),
- ast.NodePrefixOp.PrefixOp.BoolNot => try stream.write("!"),
- ast.NodePrefixOp.PrefixOp.Deref => try stream.write("*"),
- ast.NodePrefixOp.PrefixOp.Negation => try stream.write("-"),
- ast.NodePrefixOp.PrefixOp.NegationWrap => try stream.write("-%"),
- ast.NodePrefixOp.PrefixOp.Try => try stream.write("try "),
- ast.NodePrefixOp.PrefixOp.UnwrapMaybe => try stream.write("??"),
- ast.NodePrefixOp.PrefixOp.MaybeType => try stream.write("?"),
- ast.NodePrefixOp.PrefixOp.Await => try stream.write("await "),
- ast.NodePrefixOp.PrefixOp.Cancel => try stream.write("cancel "),
- ast.NodePrefixOp.PrefixOp.Resume => try stream.write("resume "),
+ ast.Node.PrefixOp.Op.BitNot => try stream.write("~"),
+ ast.Node.PrefixOp.Op.BoolNot => try stream.write("!"),
+ ast.Node.PrefixOp.Op.Deref => try stream.write("*"),
+ ast.Node.PrefixOp.Op.Negation => try stream.write("-"),
+ ast.Node.PrefixOp.Op.NegationWrap => try stream.write("-%"),
+ ast.Node.PrefixOp.Op.Try => try stream.write("try "),
+ ast.Node.PrefixOp.Op.UnwrapMaybe => try stream.write("??"),
+ ast.Node.PrefixOp.Op.MaybeType => try stream.write("?"),
+ ast.Node.PrefixOp.Op.Await => try stream.write("await "),
+ ast.Node.PrefixOp.Op.Cancel => try stream.write("cancel "),
+ ast.Node.PrefixOp.Op.Resume => try stream.write("resume "),
}
},
ast.Node.Id.SuffixOp => {
- const suffix_op = @fieldParentPtr(ast.NodeSuffixOp, "base", base);
+ const suffix_op = @fieldParentPtr(ast.Node.SuffixOp, "base", base);
switch (suffix_op.op) {
- ast.NodeSuffixOp.SuffixOp.Call => |call_info| {
+ ast.Node.SuffixOp.Op.Call => |call_info| {
try stack.append(RenderState { .Text = ")"});
var i = call_info.params.len;
while (i != 0) {
@@ -3597,13 +3615,13 @@ pub const Parser = struct {
try stack.append(RenderState { .Expression = &async_attr.base });
}
},
- ast.NodeSuffixOp.SuffixOp.ArrayAccess => |index_expr| {
+ ast.Node.SuffixOp.Op.ArrayAccess => |index_expr| {
try stack.append(RenderState { .Text = "]"});
try stack.append(RenderState { .Expression = index_expr});
try stack.append(RenderState { .Text = "["});
try stack.append(RenderState { .Expression = suffix_op.lhs });
},
- ast.NodeSuffixOp.SuffixOp.Slice => |range| {
+ ast.Node.SuffixOp.Op.Slice => |range| {
try stack.append(RenderState { .Text = "]"});
if (range.end) |end| {
try stack.append(RenderState { .Expression = end});
@@ -3613,7 +3631,7 @@ pub const Parser = struct {
try stack.append(RenderState { .Text = "["});
try stack.append(RenderState { .Expression = suffix_op.lhs });
},
- ast.NodeSuffixOp.SuffixOp.StructInitializer => |field_inits| {
+ ast.Node.SuffixOp.Op.StructInitializer => |field_inits| {
if (field_inits.len == 0) {
try stack.append(RenderState { .Text = "{}" });
try stack.append(RenderState { .Expression = suffix_op.lhs });
@@ -3634,7 +3652,7 @@ pub const Parser = struct {
try stack.append(RenderState { .Text = " {\n"});
try stack.append(RenderState { .Expression = suffix_op.lhs });
},
- ast.NodeSuffixOp.SuffixOp.ArrayInitializer => |exprs| {
+ ast.Node.SuffixOp.Op.ArrayInitializer => |exprs| {
if (exprs.len == 0) {
try stack.append(RenderState { .Text = "{}" });
try stack.append(RenderState { .Expression = suffix_op.lhs });
@@ -3658,7 +3676,7 @@ pub const Parser = struct {
}
},
ast.Node.Id.ControlFlowExpression => {
- const flow_expr = @fieldParentPtr(ast.NodeControlFlowExpression, "base", base);
+ const flow_expr = @fieldParentPtr(ast.Node.ControlFlowExpression, "base", base);
if (flow_expr.rhs) |rhs| {
try stack.append(RenderState { .Expression = rhs });
@@ -3666,34 +3684,34 @@ pub const Parser = struct {
}
switch (flow_expr.kind) {
- ast.NodeControlFlowExpression.Kind.Break => |maybe_label| {
+ ast.Node.ControlFlowExpression.Kind.Break => |maybe_label| {
try stream.print("break");
if (maybe_label) |label| {
try stream.print(" :");
try stack.append(RenderState { .Expression = label });
}
},
- ast.NodeControlFlowExpression.Kind.Continue => |maybe_label| {
+ ast.Node.ControlFlowExpression.Kind.Continue => |maybe_label| {
try stream.print("continue");
if (maybe_label) |label| {
try stream.print(" :");
try stack.append(RenderState { .Expression = label });
}
},
- ast.NodeControlFlowExpression.Kind.Return => {
+ ast.Node.ControlFlowExpression.Kind.Return => {
try stream.print("return");
},
}
},
ast.Node.Id.Payload => {
- const payload = @fieldParentPtr(ast.NodePayload, "base", base);
+ const payload = @fieldParentPtr(ast.Node.Payload, "base", base);
try stack.append(RenderState { .Text = "|"});
try stack.append(RenderState { .Expression = payload.error_symbol });
try stack.append(RenderState { .Text = "|"});
},
ast.Node.Id.PointerPayload => {
- const payload = @fieldParentPtr(ast.NodePointerPayload, "base", base);
+ const payload = @fieldParentPtr(ast.Node.PointerPayload, "base", base);
try stack.append(RenderState { .Text = "|"});
try stack.append(RenderState { .Expression = payload.value_symbol });
@@ -3704,7 +3722,7 @@ pub const Parser = struct {
try stack.append(RenderState { .Text = "|"});
},
ast.Node.Id.PointerIndexPayload => {
- const payload = @fieldParentPtr(ast.NodePointerIndexPayload, "base", base);
+ const payload = @fieldParentPtr(ast.Node.PointerIndexPayload, "base", base);
try stack.append(RenderState { .Text = "|"});
if (payload.index_symbol) |index_symbol| {
@@ -3721,69 +3739,69 @@ pub const Parser = struct {
try stack.append(RenderState { .Text = "|"});
},
ast.Node.Id.GroupedExpression => {
- const grouped_expr = @fieldParentPtr(ast.NodeGroupedExpression, "base", base);
+ const grouped_expr = @fieldParentPtr(ast.Node.GroupedExpression, "base", base);
try stack.append(RenderState { .Text = ")"});
try stack.append(RenderState { .Expression = grouped_expr.expr });
try stack.append(RenderState { .Text = "("});
},
ast.Node.Id.FieldInitializer => {
- const field_init = @fieldParentPtr(ast.NodeFieldInitializer, "base", base);
+ const field_init = @fieldParentPtr(ast.Node.FieldInitializer, "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);
+ const integer_literal = @fieldParentPtr(ast.Node.IntegerLiteral, "base", base);
try stream.print("{}", self.tokenizer.getTokenSlice(integer_literal.token));
},
ast.Node.Id.FloatLiteral => {
- const float_literal = @fieldParentPtr(ast.NodeFloatLiteral, "base", base);
+ const float_literal = @fieldParentPtr(ast.Node.FloatLiteral, "base", base);
try stream.print("{}", self.tokenizer.getTokenSlice(float_literal.token));
},
ast.Node.Id.StringLiteral => {
- const string_literal = @fieldParentPtr(ast.NodeStringLiteral, "base", base);
+ const string_literal = @fieldParentPtr(ast.Node.StringLiteral, "base", base);
try stream.print("{}", self.tokenizer.getTokenSlice(string_literal.token));
},
ast.Node.Id.CharLiteral => {
- const char_literal = @fieldParentPtr(ast.NodeCharLiteral, "base", base);
+ const char_literal = @fieldParentPtr(ast.Node.CharLiteral, "base", base);
try stream.print("{}", self.tokenizer.getTokenSlice(char_literal.token));
},
ast.Node.Id.BoolLiteral => {
- const bool_literal = @fieldParentPtr(ast.NodeCharLiteral, "base", base);
+ const bool_literal = @fieldParentPtr(ast.Node.CharLiteral, "base", base);
try stream.print("{}", self.tokenizer.getTokenSlice(bool_literal.token));
},
ast.Node.Id.NullLiteral => {
- const null_literal = @fieldParentPtr(ast.NodeNullLiteral, "base", base);
+ const null_literal = @fieldParentPtr(ast.Node.NullLiteral, "base", base);
try stream.print("{}", self.tokenizer.getTokenSlice(null_literal.token));
},
ast.Node.Id.ThisLiteral => {
- const this_literal = @fieldParentPtr(ast.NodeThisLiteral, "base", base);
+ const this_literal = @fieldParentPtr(ast.Node.ThisLiteral, "base", base);
try stream.print("{}", self.tokenizer.getTokenSlice(this_literal.token));
},
ast.Node.Id.Unreachable => {
- const unreachable_node = @fieldParentPtr(ast.NodeUnreachable, "base", base);
+ const unreachable_node = @fieldParentPtr(ast.Node.Unreachable, "base", base);
try stream.print("{}", self.tokenizer.getTokenSlice(unreachable_node.token));
},
ast.Node.Id.ErrorType => {
- const error_type = @fieldParentPtr(ast.NodeErrorType, "base", base);
+ const error_type = @fieldParentPtr(ast.Node.ErrorType, "base", base);
try stream.print("{}", self.tokenizer.getTokenSlice(error_type.token));
},
ast.Node.Id.VarType => {
- const var_type = @fieldParentPtr(ast.NodeVarType, "base", base);
+ const var_type = @fieldParentPtr(ast.Node.VarType, "base", base);
try stream.print("{}", self.tokenizer.getTokenSlice(var_type.token));
},
ast.Node.Id.ContainerDecl => {
- const container_decl = @fieldParentPtr(ast.NodeContainerDecl, "base", base);
+ const container_decl = @fieldParentPtr(ast.Node.ContainerDecl, "base", base);
switch (container_decl.layout) {
- ast.NodeContainerDecl.Layout.Packed => try stream.print("packed "),
- ast.NodeContainerDecl.Layout.Extern => try stream.print("extern "),
- ast.NodeContainerDecl.Layout.Auto => { },
+ ast.Node.ContainerDecl.Layout.Packed => try stream.print("packed "),
+ ast.Node.ContainerDecl.Layout.Extern => try stream.print("extern "),
+ ast.Node.ContainerDecl.Layout.Auto => { },
}
switch (container_decl.kind) {
- ast.NodeContainerDecl.Kind.Struct => try stream.print("struct"),
- ast.NodeContainerDecl.Kind.Enum => try stream.print("enum"),
- ast.NodeContainerDecl.Kind.Union => try stream.print("union"),
+ ast.Node.ContainerDecl.Kind.Struct => try stream.print("struct"),
+ ast.Node.ContainerDecl.Kind.Enum => try stream.print("enum"),
+ ast.Node.ContainerDecl.Kind.Union => try stream.print("union"),
}
try stack.append(RenderState { .Text = "}"});
@@ -3823,9 +3841,9 @@ pub const Parser = struct {
try stack.append(RenderState { .Text = "{"});
switch (container_decl.init_arg_expr) {
- ast.NodeContainerDecl.InitArg.None => try stack.append(RenderState { .Text = " "}),
- ast.NodeContainerDecl.InitArg.Enum => try stack.append(RenderState { .Text = "(enum) "}),
- ast.NodeContainerDecl.InitArg.Type => |type_expr| {
+ ast.Node.ContainerDecl.InitArg.None => try stack.append(RenderState { .Text = " "}),
+ ast.Node.ContainerDecl.InitArg.Enum => try stack.append(RenderState { .Text = "(enum) "}),
+ ast.Node.ContainerDecl.InitArg.Type => |type_expr| {
try stack.append(RenderState { .Text = ") "});
try stack.append(RenderState { .Expression = type_expr});
try stack.append(RenderState { .Text = "("});
@@ -3833,7 +3851,7 @@ pub const Parser = struct {
}
},
ast.Node.Id.ErrorSetDecl => {
- const err_set_decl = @fieldParentPtr(ast.NodeErrorSetDecl, "base", base);
+ const err_set_decl = @fieldParentPtr(ast.Node.ErrorSetDecl, "base", base);
try stream.print("error ");
try stack.append(RenderState { .Text = "}"});
@@ -3866,7 +3884,7 @@ pub const Parser = struct {
try stack.append(RenderState { .Text = "{"});
},
ast.Node.Id.MultilineStringLiteral => {
- const multiline_str_literal = @fieldParentPtr(ast.NodeMultilineStringLiteral, "base", base);
+ const multiline_str_literal = @fieldParentPtr(ast.Node.MultilineStringLiteral, "base", base);
try stream.print("\n");
var i : usize = 0;
@@ -3878,11 +3896,11 @@ pub const Parser = struct {
try stream.writeByteNTimes(' ', indent + indent_delta);
},
ast.Node.Id.UndefinedLiteral => {
- const undefined_literal = @fieldParentPtr(ast.NodeUndefinedLiteral, "base", base);
+ const undefined_literal = @fieldParentPtr(ast.Node.UndefinedLiteral, "base", base);
try stream.print("{}", self.tokenizer.getTokenSlice(undefined_literal.token));
},
ast.Node.Id.BuiltinCall => {
- const builtin_call = @fieldParentPtr(ast.NodeBuiltinCall, "base", base);
+ const builtin_call = @fieldParentPtr(ast.Node.BuiltinCall, "base", base);
try stream.print("{}(", self.tokenizer.getTokenSlice(builtin_call.builtin_token));
try stack.append(RenderState { .Text = ")"});
var i = builtin_call.params.len;
@@ -3896,13 +3914,13 @@ pub const Parser = struct {
}
},
ast.Node.Id.FnProto => {
- const fn_proto = @fieldParentPtr(ast.NodeFnProto, "base", base);
+ const fn_proto = @fieldParentPtr(ast.Node.FnProto, "base", base);
switch (fn_proto.return_type) {
- ast.NodeFnProto.ReturnType.Explicit => |node| {
+ ast.Node.FnProto.ReturnType.Explicit => |node| {
try stack.append(RenderState { .Expression = node});
},
- ast.NodeFnProto.ReturnType.InferErrorSet => |node| {
+ ast.Node.FnProto.ReturnType.InferErrorSet => |node| {
try stack.append(RenderState { .Expression = node});
try stack.append(RenderState { .Text = "!"});
},
@@ -3960,7 +3978,7 @@ pub const Parser = struct {
},
ast.Node.Id.LineComment => @panic("TODO render line comment in an expression"),
ast.Node.Id.Switch => {
- const switch_node = @fieldParentPtr(ast.NodeSwitch, "base", base);
+ const switch_node = @fieldParentPtr(ast.Node.Switch, "base", base);
try stream.print("{} (", self.tokenizer.getTokenSlice(switch_node.switch_token));
try stack.append(RenderState { .Text = "}"});
@@ -3994,7 +4012,7 @@ pub const Parser = struct {
try stack.append(RenderState { .Expression = switch_node.expr });
},
ast.Node.Id.SwitchCase => {
- const switch_case = @fieldParentPtr(ast.NodeSwitchCase, "base", base);
+ const switch_case = @fieldParentPtr(ast.Node.SwitchCase, "base", base);
try stack.append(RenderState { .Expression = switch_case.expr });
if (switch_case.payload) |payload| {
@@ -4016,11 +4034,11 @@ pub const Parser = struct {
}
},
ast.Node.Id.SwitchElse => {
- const switch_else = @fieldParentPtr(ast.NodeSwitchElse, "base", base);
+ const switch_else = @fieldParentPtr(ast.Node.SwitchElse, "base", base);
try stream.print("{}", self.tokenizer.getTokenSlice(switch_else.token));
},
ast.Node.Id.Else => {
- const else_node = @fieldParentPtr(ast.NodeElse, "base", base);
+ const else_node = @fieldParentPtr(ast.Node.Else, "base", base);
try stream.print("{}", self.tokenizer.getTokenSlice(else_node.else_token));
switch (else_node.body.id) {
@@ -4045,7 +4063,7 @@ pub const Parser = struct {
}
},
ast.Node.Id.While => {
- const while_node = @fieldParentPtr(ast.NodeWhile, "base", base);
+ const while_node = @fieldParentPtr(ast.Node.While, "base", base);
if (while_node.label) |label| {
try stream.print("{}: ", self.tokenizer.getTokenSlice(label));
}
@@ -4095,7 +4113,7 @@ pub const Parser = struct {
try stack.append(RenderState { .Text = "(" });
},
ast.Node.Id.For => {
- const for_node = @fieldParentPtr(ast.NodeFor, "base", base);
+ const for_node = @fieldParentPtr(ast.Node.For, "base", base);
if (for_node.label) |label| {
try stream.print("{}: ", self.tokenizer.getTokenSlice(label));
}
@@ -4138,7 +4156,7 @@ pub const Parser = struct {
try stack.append(RenderState { .Text = "(" });
},
ast.Node.Id.If => {
- const if_node = @fieldParentPtr(ast.NodeIf, "base", base);
+ const if_node = @fieldParentPtr(ast.Node.If, "base", base);
try stream.print("{} ", self.tokenizer.getTokenSlice(if_node.if_token));
switch (if_node.body.id) {
@@ -4185,7 +4203,7 @@ pub const Parser = struct {
try stack.append(RenderState { .Text = "(" });
},
ast.Node.Id.Asm => {
- const asm_node = @fieldParentPtr(ast.NodeAsm, "base", base);
+ const asm_node = @fieldParentPtr(ast.Node.Asm, "base", base);
try stream.print("{} ", self.tokenizer.getTokenSlice(asm_node.asm_token));
if (asm_node.volatile_token) |volatile_token| {
@@ -4272,7 +4290,7 @@ pub const Parser = struct {
try stack.append(RenderState { .Text = "(" });
},
ast.Node.Id.AsmInput => {
- const asm_input = @fieldParentPtr(ast.NodeAsmInput, "base", base);
+ const asm_input = @fieldParentPtr(ast.Node.AsmInput, "base", base);
try stack.append(RenderState { .Text = ")"});
try stack.append(RenderState { .Expression = asm_input.expr});
@@ -4283,14 +4301,14 @@ pub const Parser = struct {
try stack.append(RenderState { .Text = "["});
},
ast.Node.Id.AsmOutput => {
- const asm_output = @fieldParentPtr(ast.NodeAsmOutput, "base", base);
+ const asm_output = @fieldParentPtr(ast.Node.AsmOutput, "base", base);
try stack.append(RenderState { .Text = ")"});
switch (asm_output.kind) {
- ast.NodeAsmOutput.Kind.Variable => |variable_name| {
+ ast.Node.AsmOutput.Kind.Variable => |variable_name| {
try stack.append(RenderState { .Expression = &variable_name.base});
},
- ast.NodeAsmOutput.Kind.Return => |return_type| {
+ ast.Node.AsmOutput.Kind.Return => |return_type| {
try stack.append(RenderState { .Expression = return_type});
try stack.append(RenderState { .Text = "-> "});
},
@@ -4312,15 +4330,10 @@ pub const Parser = struct {
ast.Node.Id.ParamDecl => unreachable,
},
RenderState.Statement => |base| {
- if (base.comment) |comment| {
- for (comment.lines.toSliceConst()) |line_token| {
- try stream.print("{}\n", self.tokenizer.getTokenSlice(line_token));
- try stream.writeByteNTimes(' ', indent);
- }
- }
switch (base.id) {
ast.Node.Id.VarDecl => {
- const var_decl = @fieldParentPtr(ast.NodeVarDecl, "base", base);
+ const var_decl = @fieldParentPtr(ast.Node.VarDecl, "base", base);
+ try self.renderComments(stream, var_decl, indent);
try stack.append(RenderState { .VarDecl = var_decl});
},
else => {
@@ -4337,6 +4350,14 @@ pub const Parser = struct {
}
}
+ fn renderComments(self: &Parser, stream: var, node: var, indent: usize) !void {
+ const comment = node.comments ?? return;
+ for (comment.lines.toSliceConst()) |line_token| {
+ try stream.print("{}\n", self.tokenizer.getTokenSlice(line_token));
+ try stream.writeByteNTimes(' ', indent);
+ }
+ }
+
fn initUtilityArrayList(self: &Parser, comptime T: type) ArrayList(T) {
const new_byte_count = self.utility_bytes.len - self.utility_bytes.len % @sizeOf(T);
self.utility_bytes = self.util_allocator.alignedShrink(u8, utility_bytes_align, self.utility_bytes, new_byte_count);
@@ -4411,6 +4432,14 @@ fn testCanonical(source: []const u8) !void {
}
}
+test "zig fmt: preserve top level comments" {
+ try testCanonical(
+ \\// top level comment
+ \\test "hi" {}
+ \\
+ );
+}
+
test "zig fmt: get stdout or fail" {
try testCanonical(
\\const std = @import("std");