authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-01-31 12:55:33+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-02-16 16:37:07+02:00
logd835f5cce5fc3b296f55e208905d9ff4d368e497
treedefa873d5bc10497d98599534068b409cdaa782d
parent6ecec4c8b761c9f8f272602ccb2abdfd9656c71c
signature Commit is signed but in an unrecognized format.

translate-c: make Node more like Type


2 files changed, 147 insertions(+), 82 deletions(-)

src/translate_c/ast.zig+142-82
......@@ -2,14 +2,19 @@ const std = @import("std");
22const Type = @import("../type.zig").Type;
33
44pub const Node = struct {
5 tag: Tag,
6 // type: Type = Type.initTag(.noreturn),
5 /// If the tag value is less than Tag.no_payload_count, then no pointer
6 /// dereference is needed.
7 tag_if_small_enough: usize,
8 ptr_otherwise: *Payload,
79
810 pub const Tag = enum {
911 null_literal,
1012 undefined_literal,
1113 opaque_literal,
12 bool_literal,
14 true_literal,
15 false_literal,
16 // After this, the tag requires a payload.
17
1318 int,
1419 float,
1520 string,
......@@ -39,12 +44,18 @@ pub const Node = struct {
3944 discard,
4045 block,
4146
47 pub const last_no_payload_tag = Tag.false_literal;
48 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
49
4250 pub fn Type(tag: Tag) ?type {
4351 return switch (tag) {
44 .null_literal => null,
45 .undefined_literal => null,
46 .opaque_literal => null,
47 .bool_literal,
52 .null_literal,
53 .undefined_literal,
54 .opaque_literal,
55 .true_literal,
56 .false_litral,
57 => @compileError("Type Tag " ++ @tagName(t) ++ " has no payload"),
58
4859 .int,
4960 .float,
5061 .string,
......@@ -54,144 +65,186 @@ pub const Node = struct {
5465 .field_access_arrow,
5566 .warning,
5667 .failed_decl,
57 => Value,
58 .@"if" => If,
59 .@"while" => While,
60 .@"switch" => Switch,
61 .@"break" => Break,
62 .call => Call,
68 => Payload.Value,
69 .@"if" => Payload.If,
70 .@"while" => Payload.While,
71 .@"switch" => Payload.Switch,
72 .@"break" => Payload.Break,
73 .call => Payload.Call,
6374 .array_access,
6475 .std_mem_zeroes,
6576 .@"return",
6677 .discard,
67 => SingleArg,
68 .var_decl => VarDecl,
69 .func => Func,
70 .@"enum" => Enum,
71 .@"struct", .@"union" => Record,
72 .array_init => ArrayInit,
73 .container_init => ContainerInit,
74 .std_meta_cast => Infix,
75 .block => Block,
78 => Payload.SingleArg,
79 .var_decl => Payload.VarDecl,
80 .func => Payload.Func,
81 .@"enum" => Payload.Enum,
82 .@"struct", .@"union" => Payload.Record,
83 .array_init => Payload.ArrayInit,
84 .container_init => Payload.ContainerInit,
85 .std_meta_cast => Payload.Infix,
86 .block => Payload.Block,
87 };
88 }
89
90 pub fn init(comptime t: Tag) Node {
91 comptime std.debug.assert(@enumToInt(t) < Tag.no_payload_count);
92 return .{ .tag_if_small_enough = @enumToInt(t) };
93 }
94
95 pub fn create(comptime t: Tag, ally: *Allocator, data: Data(t)) error{OutOfMemory}!Node {
96 const ptr = try ally.create(t.Type());
97 ptr.* = .{
98 .base = .{ .tag = t },
99 .data = data,
76100 };
101 return Node{ .ptr_otherwise = &ptr.base };
102 }
103
104 pub fn Data(comptime t: Tag) type {
105 return std.meta.fieldInfo(t.Type(), .data).field_type;
77106 }
78107 };
108};
109
110pub const Payload = struct {
111 tag: Tag,
79112
80113 pub const Infix = struct {
81114 base: Node,
82 lhs: *Node,
83 rhs: *Node,
115 data: struct {
116 lhs: *Node,
117 rhs: *Node,
118 },
84119 };
85120
86121 pub const Value = struct {
87122 base: Node,
88 val: []const u8,
123 data: []const u8,
89124 };
90125
91126 pub const SingleArg = struct {
92127 base: Node,
93 index: *Node,
128 data: *Node,
94129 };
95130
96131 pub const If = struct {
97132 base: Node = .{ .tag = .@"if" },
98 cond: *Node,
99 then: *Node,
100 @"else": ?*Node,
133 data: struct {
134 cond: *Node,
135 then: *Node,
136 @"else": ?*Node,
137 },
101138 };
102139
103140 pub const While = struct {
104141 base: Node = .{ .tag = .@"while" },
105 cond: *Node,
106 body: *Node,
142 data: struct {
143 cond: *Node,
144 body: *Node,
145 },
107146 };
108147
109148 pub const Switch = struct {
110149 base: Node = .{ .tag = .@"switch" },
111 cond: *Node,
112 cases: []Prong,
113 default: ?[]const u8,
150 data: struct {
151 cond: *Node,
152 cases: []Prong,
153 default: ?[]const u8,
114154
115 pub const Prong = struct {
116 lhs: *Node,
117 rhs: ?*Node,
118 label: []const u8,
119 };
155 pub const Prong = struct {
156 lhs: *Node,
157 rhs: ?*Node,
158 label: []const u8,
159 };
160 },
120161 };
121162
122163 pub const Break = struct {
123164 base: Node = .{ .tag = .@"break" },
124 label: ?[]const u8,
125 rhs: ?*Node,
165 data: struct {
166 label: ?[]const u8,
167 rhs: ?*Node,
168 },
126169 };
127170
128171 pub const Call = struct {
129172 base: Node = .{.call},
130 lhs: *Node,
131 args: []*Node,
173 data: struct {
174 lhs: *Node,
175 args: []*Node,
176 },
132177 };
133178
134179 pub const VarDecl = struct {
135180 base: Node = .{ .tag = .var_decl },
136 @"pub": bool,
137 @"const": bool,
138 @"extern": bool,
139 @"export": bool,
140 name: []const u8,
141 type: Type,
142 init: *Node,
181 data: struct {
182 @"pub": bool,
183 @"const": bool,
184 @"extern": bool,
185 @"export": bool,
186 name: []const u8,
187 type: Type,
188 init: *Node,
189 },
143190 };
144191
145192 pub const Func = struct {
146193 base: Node = .{.func},
147 @"pub": bool,
148 @"extern": bool,
149 @"export": bool,
150 name: []const u8,
151 cc: std.builtin.CallingConvention,
152 params: []Param,
153 return_type: Type,
154 body: ?*Node,
155
156 pub const Param = struct {
157 @"noalias": bool,
158 name: ?[]const u8,
159 type: Type,
160 };
194 data: struct {
195 @"pub": bool,
196 @"extern": bool,
197 @"export": bool,
198 name: []const u8,
199 cc: std.builtin.CallingConvention,
200 params: []Param,
201 return_type: Type,
202 body: ?*Node,
203
204 pub const Param = struct {
205 @"noalias": bool,
206 name: ?[]const u8,
207 type: Type,
208 };
209 },
161210 };
162211
163212 pub const Enum = struct {
164213 base: Node = .{ .tag = .@"enum" },
165 name: ?[]const u8,
166 fields: []Field,
214 data: struct {
215 name: ?[]const u8,
216 fields: []Field,
167217
168 pub const Field = struct {
169 name: []const u8,
170 value: ?[]const u8,
171 };
218 pub const Field = struct {
219 name: []const u8,
220 value: ?[]const u8,
221 };
222 },
172223 };
173224
174225 pub const Record = struct {
175226 base: Node,
176 name: ?[]const u8,
177 @"packed": bool,
178 fields: []Field,
227 data: struct {
228 name: ?[]const u8,
229 @"packed": bool,
230 fields: []Field,
179231
180 pub const Field = struct {
181 name: []const u8,
182 type: Type,
183 alignment: c_uint,
184 };
232 pub const Field = struct {
233 name: []const u8,
234 type: Type,
235 alignment: c_uint,
236 };
237 },
185238 };
186239
187240 pub const ArrayInit = struct {
188241 base: Node = .{ .tag = .array_init },
189 values: []*Node,
242 data: []*Node,
190243 };
191244
192245 pub const ContainerInit = struct {
193246 base: Node = .{ .tag = .container_init },
194 values: []Initializer,
247 data: []Initializer,
195248
196249 pub const Initializer = struct {
197250 name: []const u8,
......@@ -201,7 +254,14 @@ pub const Node = struct {
201254
202255 pub const Block = struct {
203256 base: Node = .{ .tag = .block },
204 label: ?[]const u8,
205 stmts: []*Node,
257 data: struct {
258 label: ?[]const u8,
259 stmts: []*Node,
260 },
206261 };
207262};
263
264/// Converts the nodes into a Zig ast and then renders it.
265pub fn render(allocator: *Allocator, nodes: []const Node) !void {
266 @panic("TODO");
267}
src/type.zig+5
......@@ -3408,6 +3408,11 @@ pub const Type = extern union {
34083408 };
34093409 }
34103410
3411 pub fn init(comptime t: Tag) Type {
3412 comptime std.debug.assert(@enumToInt(t) < Tag.no_payload_count);
3413 return .{ .tag_if_small_enough = @enumToInt(t) };
3414 }
3415
34113416 pub fn create(comptime t: Tag, ally: *Allocator, data: Data(t)) error{OutOfMemory}!Type {
34123417 const ptr = try ally.create(t.Type());
34133418 ptr.* = .{