mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
translate-c: make Node more like Type
This commit is contained in:
parent
6ecec4c8b7
commit
d835f5cce5
@ -2,14 +2,19 @@ const std = @import("std");
|
||||
const Type = @import("../type.zig").Type;
|
||||
|
||||
pub const Node = struct {
|
||||
tag: Tag,
|
||||
// type: Type = Type.initTag(.noreturn),
|
||||
/// If the tag value is less than Tag.no_payload_count, then no pointer
|
||||
/// dereference is needed.
|
||||
tag_if_small_enough: usize,
|
||||
ptr_otherwise: *Payload,
|
||||
|
||||
pub const Tag = enum {
|
||||
null_literal,
|
||||
undefined_literal,
|
||||
opaque_literal,
|
||||
bool_literal,
|
||||
true_literal,
|
||||
false_literal,
|
||||
// After this, the tag requires a payload.
|
||||
|
||||
int,
|
||||
float,
|
||||
string,
|
||||
@ -39,12 +44,18 @@ pub const Node = struct {
|
||||
discard,
|
||||
block,
|
||||
|
||||
pub const last_no_payload_tag = Tag.false_literal;
|
||||
pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
|
||||
|
||||
pub fn Type(tag: Tag) ?type {
|
||||
return switch (tag) {
|
||||
.null_literal => null,
|
||||
.undefined_literal => null,
|
||||
.opaque_literal => null,
|
||||
.bool_literal,
|
||||
.null_literal,
|
||||
.undefined_literal,
|
||||
.opaque_literal,
|
||||
.true_literal,
|
||||
.false_litral,
|
||||
=> @compileError("Type Tag " ++ @tagName(t) ++ " has no payload"),
|
||||
|
||||
.int,
|
||||
.float,
|
||||
.string,
|
||||
@ -54,144 +65,186 @@ pub const Node = struct {
|
||||
.field_access_arrow,
|
||||
.warning,
|
||||
.failed_decl,
|
||||
=> Value,
|
||||
.@"if" => If,
|
||||
.@"while" => While,
|
||||
.@"switch" => Switch,
|
||||
.@"break" => Break,
|
||||
.call => Call,
|
||||
=> Payload.Value,
|
||||
.@"if" => Payload.If,
|
||||
.@"while" => Payload.While,
|
||||
.@"switch" => Payload.Switch,
|
||||
.@"break" => Payload.Break,
|
||||
.call => Payload.Call,
|
||||
.array_access,
|
||||
.std_mem_zeroes,
|
||||
.@"return",
|
||||
.discard,
|
||||
=> SingleArg,
|
||||
.var_decl => VarDecl,
|
||||
.func => Func,
|
||||
.@"enum" => Enum,
|
||||
.@"struct", .@"union" => Record,
|
||||
.array_init => ArrayInit,
|
||||
.container_init => ContainerInit,
|
||||
.std_meta_cast => Infix,
|
||||
.block => Block,
|
||||
=> Payload.SingleArg,
|
||||
.var_decl => Payload.VarDecl,
|
||||
.func => Payload.Func,
|
||||
.@"enum" => Payload.Enum,
|
||||
.@"struct", .@"union" => Payload.Record,
|
||||
.array_init => Payload.ArrayInit,
|
||||
.container_init => Payload.ContainerInit,
|
||||
.std_meta_cast => Payload.Infix,
|
||||
.block => Payload.Block,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn init(comptime t: Tag) Node {
|
||||
comptime std.debug.assert(@enumToInt(t) < Tag.no_payload_count);
|
||||
return .{ .tag_if_small_enough = @enumToInt(t) };
|
||||
}
|
||||
|
||||
pub fn create(comptime t: Tag, ally: *Allocator, data: Data(t)) error{OutOfMemory}!Node {
|
||||
const ptr = try ally.create(t.Type());
|
||||
ptr.* = .{
|
||||
.base = .{ .tag = t },
|
||||
.data = data,
|
||||
};
|
||||
return Node{ .ptr_otherwise = &ptr.base };
|
||||
}
|
||||
|
||||
pub fn Data(comptime t: Tag) type {
|
||||
return std.meta.fieldInfo(t.Type(), .data).field_type;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
pub const Payload = struct {
|
||||
tag: Tag,
|
||||
|
||||
pub const Infix = struct {
|
||||
base: Node,
|
||||
lhs: *Node,
|
||||
rhs: *Node,
|
||||
data: struct {
|
||||
lhs: *Node,
|
||||
rhs: *Node,
|
||||
},
|
||||
};
|
||||
|
||||
pub const Value = struct {
|
||||
base: Node,
|
||||
val: []const u8,
|
||||
data: []const u8,
|
||||
};
|
||||
|
||||
pub const SingleArg = struct {
|
||||
base: Node,
|
||||
index: *Node,
|
||||
data: *Node,
|
||||
};
|
||||
|
||||
pub const If = struct {
|
||||
base: Node = .{ .tag = .@"if" },
|
||||
cond: *Node,
|
||||
then: *Node,
|
||||
@"else": ?*Node,
|
||||
data: struct {
|
||||
cond: *Node,
|
||||
then: *Node,
|
||||
@"else": ?*Node,
|
||||
},
|
||||
};
|
||||
|
||||
pub const While = struct {
|
||||
base: Node = .{ .tag = .@"while" },
|
||||
cond: *Node,
|
||||
body: *Node,
|
||||
data: struct {
|
||||
cond: *Node,
|
||||
body: *Node,
|
||||
},
|
||||
};
|
||||
|
||||
pub const Switch = struct {
|
||||
base: Node = .{ .tag = .@"switch" },
|
||||
cond: *Node,
|
||||
cases: []Prong,
|
||||
default: ?[]const u8,
|
||||
data: struct {
|
||||
cond: *Node,
|
||||
cases: []Prong,
|
||||
default: ?[]const u8,
|
||||
|
||||
pub const Prong = struct {
|
||||
lhs: *Node,
|
||||
rhs: ?*Node,
|
||||
label: []const u8,
|
||||
};
|
||||
pub const Prong = struct {
|
||||
lhs: *Node,
|
||||
rhs: ?*Node,
|
||||
label: []const u8,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
pub const Break = struct {
|
||||
base: Node = .{ .tag = .@"break" },
|
||||
label: ?[]const u8,
|
||||
rhs: ?*Node,
|
||||
data: struct {
|
||||
label: ?[]const u8,
|
||||
rhs: ?*Node,
|
||||
},
|
||||
};
|
||||
|
||||
pub const Call = struct {
|
||||
base: Node = .{.call},
|
||||
lhs: *Node,
|
||||
args: []*Node,
|
||||
data: struct {
|
||||
lhs: *Node,
|
||||
args: []*Node,
|
||||
},
|
||||
};
|
||||
|
||||
pub const VarDecl = struct {
|
||||
base: Node = .{ .tag = .var_decl },
|
||||
@"pub": bool,
|
||||
@"const": bool,
|
||||
@"extern": bool,
|
||||
@"export": bool,
|
||||
name: []const u8,
|
||||
type: Type,
|
||||
init: *Node,
|
||||
data: struct {
|
||||
@"pub": bool,
|
||||
@"const": bool,
|
||||
@"extern": bool,
|
||||
@"export": bool,
|
||||
name: []const u8,
|
||||
type: Type,
|
||||
init: *Node,
|
||||
},
|
||||
};
|
||||
|
||||
pub const Func = struct {
|
||||
base: Node = .{.func},
|
||||
@"pub": bool,
|
||||
@"extern": bool,
|
||||
@"export": bool,
|
||||
name: []const u8,
|
||||
cc: std.builtin.CallingConvention,
|
||||
params: []Param,
|
||||
return_type: Type,
|
||||
body: ?*Node,
|
||||
data: struct {
|
||||
@"pub": bool,
|
||||
@"extern": bool,
|
||||
@"export": bool,
|
||||
name: []const u8,
|
||||
cc: std.builtin.CallingConvention,
|
||||
params: []Param,
|
||||
return_type: Type,
|
||||
body: ?*Node,
|
||||
|
||||
pub const Param = struct {
|
||||
@"noalias": bool,
|
||||
name: ?[]const u8,
|
||||
type: Type,
|
||||
};
|
||||
pub const Param = struct {
|
||||
@"noalias": bool,
|
||||
name: ?[]const u8,
|
||||
type: Type,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
pub const Enum = struct {
|
||||
base: Node = .{ .tag = .@"enum" },
|
||||
name: ?[]const u8,
|
||||
fields: []Field,
|
||||
data: struct {
|
||||
name: ?[]const u8,
|
||||
fields: []Field,
|
||||
|
||||
pub const Field = struct {
|
||||
name: []const u8,
|
||||
value: ?[]const u8,
|
||||
};
|
||||
pub const Field = struct {
|
||||
name: []const u8,
|
||||
value: ?[]const u8,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
pub const Record = struct {
|
||||
base: Node,
|
||||
name: ?[]const u8,
|
||||
@"packed": bool,
|
||||
fields: []Field,
|
||||
data: struct {
|
||||
name: ?[]const u8,
|
||||
@"packed": bool,
|
||||
fields: []Field,
|
||||
|
||||
pub const Field = struct {
|
||||
name: []const u8,
|
||||
type: Type,
|
||||
alignment: c_uint,
|
||||
};
|
||||
pub const Field = struct {
|
||||
name: []const u8,
|
||||
type: Type,
|
||||
alignment: c_uint,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
pub const ArrayInit = struct {
|
||||
base: Node = .{ .tag = .array_init },
|
||||
values: []*Node,
|
||||
data: []*Node,
|
||||
};
|
||||
|
||||
pub const ContainerInit = struct {
|
||||
base: Node = .{ .tag = .container_init },
|
||||
values: []Initializer,
|
||||
data: []Initializer,
|
||||
|
||||
pub const Initializer = struct {
|
||||
name: []const u8,
|
||||
@ -201,7 +254,14 @@ pub const Node = struct {
|
||||
|
||||
pub const Block = struct {
|
||||
base: Node = .{ .tag = .block },
|
||||
label: ?[]const u8,
|
||||
stmts: []*Node,
|
||||
data: struct {
|
||||
label: ?[]const u8,
|
||||
stmts: []*Node,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
/// Converts the nodes into a Zig ast and then renders it.
|
||||
pub fn render(allocator: *Allocator, nodes: []const Node) !void {
|
||||
@panic("TODO");
|
||||
}
|
||||
|
||||
@ -3408,6 +3408,11 @@ pub const Type = extern union {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn init(comptime t: Tag) Type {
|
||||
comptime std.debug.assert(@enumToInt(t) < Tag.no_payload_count);
|
||||
return .{ .tag_if_small_enough = @enumToInt(t) };
|
||||
}
|
||||
|
||||
pub fn create(comptime t: Tag, ally: *Allocator, data: Data(t)) error{OutOfMemory}!Type {
|
||||
const ptr = try ally.create(t.Type());
|
||||
ptr.* = .{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user