std.zig: Major refactor

* There now exists a few function to allocate all nodes in parser.zig
* ast.zig now have a table of Ids and their corrisponding type
master
Jimmi Holst Christensen 2018-04-11 10:37:04 +02:00
parent f43711e5fb
commit dae287524d
2 changed files with 991 additions and 1011 deletions

View File

@ -9,38 +9,34 @@ pub const Node = struct {
comment: ?&NodeLineComment,
pub const Id = enum {
// Top level
Root,
VarDecl,
Use,
ErrorSetDecl,
ContainerDecl,
StructField,
UnionTag,
EnumTag,
Identifier,
AsyncAttribute,
FnProto,
ParamDecl,
Block,
TestDecl,
// Statements
VarDecl,
Defer,
Comptime,
Payload,
PointerPayload,
PointerIndexPayload,
Else,
Switch,
SwitchCase,
SwitchElse,
While,
For,
If,
// Operators
InfixOp,
PrefixOp,
SuffixOp,
GroupedExpression,
// Control flow
Switch,
While,
For,
If,
ControlFlowExpression,
Suspend,
FieldInitializer,
// Type expressions
VarType,
ErrorType,
FnProto,
// Primary expressions
IntegerLiteral,
FloatLiteral,
StringLiteral,
@ -50,180 +46,143 @@ pub const Node = struct {
NullLiteral,
UndefinedLiteral,
ThisLiteral,
Unreachable,
Identifier,
GroupedExpression,
BuiltinCall,
ErrorSetDecl,
ContainerDecl,
Asm,
Comptime,
Block,
// Misc
LineComment,
SwitchCase,
SwitchElse,
Else,
Payload,
PointerPayload,
PointerIndexPayload,
StructField,
UnionTag,
EnumTag,
AsmInput,
AsmOutput,
Unreachable,
ErrorType,
VarType,
BuiltinCall,
LineComment,
TestDecl,
AsyncAttribute,
ParamDecl,
FieldInitializer,
};
pub fn iterate(base: &Node, index: usize) ?&Node {
return switch (base.id) {
Id.Root => @fieldParentPtr(NodeRoot, "base", base).iterate(index),
Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).iterate(index),
Id.Use => @fieldParentPtr(NodeUse, "base", base).iterate(index),
Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).iterate(index),
Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).iterate(index),
Id.StructField => @fieldParentPtr(NodeStructField, "base", base).iterate(index),
Id.UnionTag => @fieldParentPtr(NodeUnionTag, "base", base).iterate(index),
Id.EnumTag => @fieldParentPtr(NodeEnumTag, "base", base).iterate(index),
Id.Identifier => @fieldParentPtr(NodeIdentifier, "base", base).iterate(index),
Id.AsyncAttribute => @fieldParentPtr(NodeAsyncAttribute, "base", base).iterate(index),
Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).iterate(index),
Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).iterate(index),
Id.Block => @fieldParentPtr(NodeBlock, "base", base).iterate(index),
Id.Defer => @fieldParentPtr(NodeDefer, "base", base).iterate(index),
Id.Comptime => @fieldParentPtr(NodeComptime, "base", base).iterate(index),
Id.Payload => @fieldParentPtr(NodePayload, "base", base).iterate(index),
Id.PointerPayload => @fieldParentPtr(NodePointerPayload, "base", base).iterate(index),
Id.PointerIndexPayload => @fieldParentPtr(NodePointerIndexPayload, "base", base).iterate(index),
Id.Else => @fieldParentPtr(NodeSwitch, "base", base).iterate(index),
Id.Switch => @fieldParentPtr(NodeSwitch, "base", base).iterate(index),
Id.SwitchCase => @fieldParentPtr(NodeSwitchCase, "base", base).iterate(index),
Id.SwitchElse => @fieldParentPtr(NodeSwitchElse, "base", base).iterate(index),
Id.While => @fieldParentPtr(NodeWhile, "base", base).iterate(index),
Id.For => @fieldParentPtr(NodeFor, "base", base).iterate(index),
Id.If => @fieldParentPtr(NodeIf, "base", base).iterate(index),
Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).iterate(index),
Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).iterate(index),
Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).iterate(index),
Id.GroupedExpression => @fieldParentPtr(NodeGroupedExpression, "base", base).iterate(index),
Id.ControlFlowExpression => @fieldParentPtr(NodeControlFlowExpression, "base", base).iterate(index),
Id.Suspend => @fieldParentPtr(NodeSuspend, "base", base).iterate(index),
Id.FieldInitializer => @fieldParentPtr(NodeFieldInitializer, "base", base).iterate(index),
Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).iterate(index),
Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).iterate(index),
Id.StringLiteral => @fieldParentPtr(NodeStringLiteral, "base", base).iterate(index),
Id.MultilineStringLiteral => @fieldParentPtr(NodeMultilineStringLiteral, "base", base).iterate(index),
Id.CharLiteral => @fieldParentPtr(NodeCharLiteral, "base", base).iterate(index),
Id.BoolLiteral => @fieldParentPtr(NodeBoolLiteral, "base", base).iterate(index),
Id.NullLiteral => @fieldParentPtr(NodeNullLiteral, "base", base).iterate(index),
Id.UndefinedLiteral => @fieldParentPtr(NodeUndefinedLiteral, "base", base).iterate(index),
Id.ThisLiteral => @fieldParentPtr(NodeThisLiteral, "base", base).iterate(index),
Id.Asm => @fieldParentPtr(NodeAsm, "base", base).iterate(index),
Id.AsmInput => @fieldParentPtr(NodeAsmInput, "base", base).iterate(index),
Id.AsmOutput => @fieldParentPtr(NodeAsmOutput, "base", base).iterate(index),
Id.Unreachable => @fieldParentPtr(NodeUnreachable, "base", base).iterate(index),
Id.ErrorType => @fieldParentPtr(NodeErrorType, "base", base).iterate(index),
Id.VarType => @fieldParentPtr(NodeVarType, "base", base).iterate(index),
Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).iterate(index),
Id.LineComment => @fieldParentPtr(NodeLineComment, "base", base).iterate(index),
Id.TestDecl => @fieldParentPtr(NodeTestDecl, "base", base).iterate(index),
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);
}
unreachable;
}
pub fn firstToken(base: &Node) Token {
return switch (base.id) {
Id.Root => @fieldParentPtr(NodeRoot, "base", base).firstToken(),
Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).firstToken(),
Id.Use => @fieldParentPtr(NodeUse, "base", base).firstToken(),
Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).firstToken(),
Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).firstToken(),
Id.StructField => @fieldParentPtr(NodeStructField, "base", base).firstToken(),
Id.UnionTag => @fieldParentPtr(NodeUnionTag, "base", base).firstToken(),
Id.EnumTag => @fieldParentPtr(NodeEnumTag, "base", base).firstToken(),
Id.Identifier => @fieldParentPtr(NodeIdentifier, "base", base).firstToken(),
Id.AsyncAttribute => @fieldParentPtr(NodeAsyncAttribute, "base", base).firstToken(),
Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).firstToken(),
Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).firstToken(),
Id.Block => @fieldParentPtr(NodeBlock, "base", base).firstToken(),
Id.Defer => @fieldParentPtr(NodeDefer, "base", base).firstToken(),
Id.Comptime => @fieldParentPtr(NodeComptime, "base", base).firstToken(),
Id.Payload => @fieldParentPtr(NodePayload, "base", base).firstToken(),
Id.PointerPayload => @fieldParentPtr(NodePointerPayload, "base", base).firstToken(),
Id.PointerIndexPayload => @fieldParentPtr(NodePointerIndexPayload, "base", base).firstToken(),
Id.Else => @fieldParentPtr(NodeSwitch, "base", base).firstToken(),
Id.Switch => @fieldParentPtr(NodeSwitch, "base", base).firstToken(),
Id.SwitchCase => @fieldParentPtr(NodeSwitchCase, "base", base).firstToken(),
Id.SwitchElse => @fieldParentPtr(NodeSwitchElse, "base", base).firstToken(),
Id.While => @fieldParentPtr(NodeWhile, "base", base).firstToken(),
Id.For => @fieldParentPtr(NodeFor, "base", base).firstToken(),
Id.If => @fieldParentPtr(NodeIf, "base", base).firstToken(),
Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).firstToken(),
Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).firstToken(),
Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).firstToken(),
Id.GroupedExpression => @fieldParentPtr(NodeGroupedExpression, "base", base).firstToken(),
Id.ControlFlowExpression => @fieldParentPtr(NodeControlFlowExpression, "base", base).firstToken(),
Id.Suspend => @fieldParentPtr(NodeSuspend, "base", base).firstToken(),
Id.FieldInitializer => @fieldParentPtr(NodeFieldInitializer, "base", base).firstToken(),
Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).firstToken(),
Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).firstToken(),
Id.StringLiteral => @fieldParentPtr(NodeStringLiteral, "base", base).firstToken(),
Id.MultilineStringLiteral => @fieldParentPtr(NodeMultilineStringLiteral, "base", base).firstToken(),
Id.CharLiteral => @fieldParentPtr(NodeCharLiteral, "base", base).firstToken(),
Id.BoolLiteral => @fieldParentPtr(NodeBoolLiteral, "base", base).firstToken(),
Id.NullLiteral => @fieldParentPtr(NodeNullLiteral, "base", base).firstToken(),
Id.UndefinedLiteral => @fieldParentPtr(NodeUndefinedLiteral, "base", base).firstToken(),
Id.Unreachable => @fieldParentPtr(NodeUnreachable, "base", base).firstToken(),
Id.ThisLiteral => @fieldParentPtr(NodeThisLiteral, "base", base).firstToken(),
Id.Asm => @fieldParentPtr(NodeAsm, "base", base).firstToken(),
Id.AsmInput => @fieldParentPtr(NodeAsmInput, "base", base).firstToken(),
Id.AsmOutput => @fieldParentPtr(NodeAsmOutput, "base", base).firstToken(),
Id.ErrorType => @fieldParentPtr(NodeErrorType, "base", base).firstToken(),
Id.VarType => @fieldParentPtr(NodeVarType, "base", base).firstToken(),
Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).firstToken(),
Id.LineComment => @fieldParentPtr(NodeLineComment, "base", base).firstToken(),
Id.TestDecl => @fieldParentPtr(NodeTestDecl, "base", base).firstToken(),
};
inline for (idTypeTable) |id_type_pair| {
if (base.id == id_type_pair.id)
return @fieldParentPtr(id_type_pair.Type, "base", base).firstToken();
}
unreachable;
}
pub fn lastToken(base: &Node) Token {
return switch (base.id) {
Id.Root => @fieldParentPtr(NodeRoot, "base", base).lastToken(),
Id.VarDecl => @fieldParentPtr(NodeVarDecl, "base", base).lastToken(),
Id.Use => @fieldParentPtr(NodeUse, "base", base).lastToken(),
Id.ErrorSetDecl => @fieldParentPtr(NodeErrorSetDecl, "base", base).lastToken(),
Id.ContainerDecl => @fieldParentPtr(NodeContainerDecl, "base", base).lastToken(),
Id.StructField => @fieldParentPtr(NodeStructField, "base", base).lastToken(),
Id.UnionTag => @fieldParentPtr(NodeUnionTag, "base", base).lastToken(),
Id.EnumTag => @fieldParentPtr(NodeEnumTag, "base", base).lastToken(),
Id.Identifier => @fieldParentPtr(NodeIdentifier, "base", base).lastToken(),
Id.AsyncAttribute => @fieldParentPtr(NodeAsyncAttribute, "base", base).lastToken(),
Id.FnProto => @fieldParentPtr(NodeFnProto, "base", base).lastToken(),
Id.ParamDecl => @fieldParentPtr(NodeParamDecl, "base", base).lastToken(),
Id.Block => @fieldParentPtr(NodeBlock, "base", base).lastToken(),
Id.Defer => @fieldParentPtr(NodeDefer, "base", base).lastToken(),
Id.Comptime => @fieldParentPtr(NodeComptime, "base", base).lastToken(),
Id.Payload => @fieldParentPtr(NodePayload, "base", base).lastToken(),
Id.PointerPayload => @fieldParentPtr(NodePointerPayload, "base", base).lastToken(),
Id.PointerIndexPayload => @fieldParentPtr(NodePointerIndexPayload, "base", base).lastToken(),
Id.Else => @fieldParentPtr(NodeElse, "base", base).lastToken(),
Id.Switch => @fieldParentPtr(NodeSwitch, "base", base).lastToken(),
Id.SwitchCase => @fieldParentPtr(NodeSwitchCase, "base", base).lastToken(),
Id.SwitchElse => @fieldParentPtr(NodeSwitchElse, "base", base).lastToken(),
Id.While => @fieldParentPtr(NodeWhile, "base", base).lastToken(),
Id.For => @fieldParentPtr(NodeFor, "base", base).lastToken(),
Id.If => @fieldParentPtr(NodeIf, "base", base).lastToken(),
Id.InfixOp => @fieldParentPtr(NodeInfixOp, "base", base).lastToken(),
Id.PrefixOp => @fieldParentPtr(NodePrefixOp, "base", base).lastToken(),
Id.SuffixOp => @fieldParentPtr(NodeSuffixOp, "base", base).lastToken(),
Id.GroupedExpression => @fieldParentPtr(NodeGroupedExpression, "base", base).lastToken(),
Id.ControlFlowExpression => @fieldParentPtr(NodeControlFlowExpression, "base", base).lastToken(),
Id.Suspend => @fieldParentPtr(NodeSuspend, "base", base).lastToken(),
Id.FieldInitializer => @fieldParentPtr(NodeFieldInitializer, "base", base).lastToken(),
Id.IntegerLiteral => @fieldParentPtr(NodeIntegerLiteral, "base", base).lastToken(),
Id.FloatLiteral => @fieldParentPtr(NodeFloatLiteral, "base", base).lastToken(),
Id.StringLiteral => @fieldParentPtr(NodeStringLiteral, "base", base).lastToken(),
Id.MultilineStringLiteral => @fieldParentPtr(NodeMultilineStringLiteral, "base", base).lastToken(),
Id.CharLiteral => @fieldParentPtr(NodeCharLiteral, "base", base).lastToken(),
Id.BoolLiteral => @fieldParentPtr(NodeBoolLiteral, "base", base).lastToken(),
Id.NullLiteral => @fieldParentPtr(NodeNullLiteral, "base", base).lastToken(),
Id.UndefinedLiteral => @fieldParentPtr(NodeUndefinedLiteral, "base", base).lastToken(),
Id.ThisLiteral => @fieldParentPtr(NodeThisLiteral, "base", base).lastToken(),
Id.Asm => @fieldParentPtr(NodeAsm, "base", base).lastToken(),
Id.AsmInput => @fieldParentPtr(NodeAsmInput, "base", base).lastToken(),
Id.AsmOutput => @fieldParentPtr(NodeAsmOutput, "base", base).lastToken(),
Id.Unreachable => @fieldParentPtr(NodeUnreachable, "base", base).lastToken(),
Id.ErrorType => @fieldParentPtr(NodeErrorType, "base", base).lastToken(),
Id.VarType => @fieldParentPtr(NodeVarType, "base", base).lastToken(),
Id.BuiltinCall => @fieldParentPtr(NodeBuiltinCall, "base", base).lastToken(),
Id.LineComment => @fieldParentPtr(NodeLineComment, "base", base).lastToken(),
Id.TestDecl => @fieldParentPtr(NodeTestDecl, "base", base).lastToken(),
};
inline for (idTypeTable) |id_type_pair| {
if (base.id == id_type_pair.id)
return @fieldParentPtr(id_type_pair.Type, "base", base).lastToken();
}
unreachable;
}
};
@ -482,18 +441,18 @@ pub const NodeEnumTag = struct {
pub const NodeIdentifier = struct {
base: Node,
name_token: Token,
token: Token,
pub fn iterate(self: &NodeIdentifier, index: usize) ?&Node {
return null;
}
pub fn firstToken(self: &NodeIdentifier) Token {
return self.name_token;
return self.token;
}
pub fn lastToken(self: &NodeIdentifier) Token {
return self.name_token;
return self.token;
}
};

File diff suppressed because it is too large Load Diff