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");...@@ -2,14 +2,19 @@ const std = @import("std");
2const Type = @import("../type.zig").Type;2const Type = @import("../type.zig").Type;
33
4pub const Node = struct {4pub const Node = struct {
5 tag: Tag,5 /// If the tag value is less than Tag.no_payload_count, then no pointer
6 // type: Type = Type.initTag(.noreturn),6 /// dereference is needed.
7 tag_if_small_enough: usize,
8 ptr_otherwise: *Payload,
79
8 pub const Tag = enum {10 pub const Tag = enum {
9 null_literal,11 null_literal,
10 undefined_literal,12 undefined_literal,
11 opaque_literal,13 opaque_literal,
12 bool_literal,14 true_literal,
15 false_literal,
16 // After this, the tag requires a payload.
17
13 int,18 int,
14 float,19 float,
15 string,20 string,
...@@ -39,12 +44,18 @@ pub const Node = struct {...@@ -39,12 +44,18 @@ pub const Node = struct {
39 discard,44 discard,
40 block,45 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
42 pub fn Type(tag: Tag) ?type {50 pub fn Type(tag: Tag) ?type {
43 return switch (tag) {51 return switch (tag) {
44 .null_literal => null,52 .null_literal,
45 .undefined_literal => null,53 .undefined_literal,
46 .opaque_literal => null,54 .opaque_literal,
47 .bool_literal,55 .true_literal,
56 .false_litral,
57 => @compileError("Type Tag " ++ @tagName(t) ++ " has no payload"),
58
48 .int,59 .int,
49 .float,60 .float,
50 .string,61 .string,
...@@ -54,144 +65,186 @@ pub const Node = struct {...@@ -54,144 +65,186 @@ pub const Node = struct {
54 .field_access_arrow,65 .field_access_arrow,
55 .warning,66 .warning,
56 .failed_decl,67 .failed_decl,
57 => Value,68 => Payload.Value,
58 .@"if" => If,69 .@"if" => Payload.If,
59 .@"while" => While,70 .@"while" => Payload.While,
60 .@"switch" => Switch,71 .@"switch" => Payload.Switch,
61 .@"break" => Break,72 .@"break" => Payload.Break,
62 .call => Call,73 .call => Payload.Call,
63 .array_access,74 .array_access,
64 .std_mem_zeroes,75 .std_mem_zeroes,
65 .@"return",76 .@"return",
66 .discard,77 .discard,
67 => SingleArg,78 => Payload.SingleArg,
68 .var_decl => VarDecl,79 .var_decl => Payload.VarDecl,
69 .func => Func,80 .func => Payload.Func,
70 .@"enum" => Enum,81 .@"enum" => Payload.Enum,
71 .@"struct", .@"union" => Record,82 .@"struct", .@"union" => Payload.Record,
72 .array_init => ArrayInit,83 .array_init => Payload.ArrayInit,
73 .container_init => ContainerInit,84 .container_init => Payload.ContainerInit,
74 .std_meta_cast => Infix,85 .std_meta_cast => Payload.Infix,
75 .block => Block,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,
76 };100 };
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;
77 }106 }
78 };107 };
108};
109
110pub const Payload = struct {
111 tag: Tag,
79112
80 pub const Infix = struct {113 pub const Infix = struct {
81 base: Node,114 base: Node,
82 lhs: *Node,115 data: struct {
83 rhs: *Node,116 lhs: *Node,
117 rhs: *Node,
118 },
84 };119 };
85120
86 pub const Value = struct {121 pub const Value = struct {
87 base: Node,122 base: Node,
88 val: []const u8,123 data: []const u8,
89 };124 };
90125
91 pub const SingleArg = struct {126 pub const SingleArg = struct {
92 base: Node,127 base: Node,
93 index: *Node,128 data: *Node,
94 };129 };
95130
96 pub const If = struct {131 pub const If = struct {
97 base: Node = .{ .tag = .@"if" },132 base: Node = .{ .tag = .@"if" },
98 cond: *Node,133 data: struct {
99 then: *Node,134 cond: *Node,
100 @"else": ?*Node,135 then: *Node,
136 @"else": ?*Node,
137 },
101 };138 };
102139
103 pub const While = struct {140 pub const While = struct {
104 base: Node = .{ .tag = .@"while" },141 base: Node = .{ .tag = .@"while" },
105 cond: *Node,142 data: struct {
106 body: *Node,143 cond: *Node,
144 body: *Node,
145 },
107 };146 };
108147
109 pub const Switch = struct {148 pub const Switch = struct {
110 base: Node = .{ .tag = .@"switch" },149 base: Node = .{ .tag = .@"switch" },
111 cond: *Node,150 data: struct {
112 cases: []Prong,151 cond: *Node,
113 default: ?[]const u8,152 cases: []Prong,
153 default: ?[]const u8,
114154
115 pub const Prong = struct {155 pub const Prong = struct {
116 lhs: *Node,156 lhs: *Node,
117 rhs: ?*Node,157 rhs: ?*Node,
118 label: []const u8,158 label: []const u8,
119 };159 };
160 },
120 };161 };
121162
122 pub const Break = struct {163 pub const Break = struct {
123 base: Node = .{ .tag = .@"break" },164 base: Node = .{ .tag = .@"break" },
124 label: ?[]const u8,165 data: struct {
125 rhs: ?*Node,166 label: ?[]const u8,
167 rhs: ?*Node,
168 },
126 };169 };
127170
128 pub const Call = struct {171 pub const Call = struct {
129 base: Node = .{.call},172 base: Node = .{.call},
130 lhs: *Node,173 data: struct {
131 args: []*Node,174 lhs: *Node,
175 args: []*Node,
176 },
132 };177 };
133178
134 pub const VarDecl = struct {179 pub const VarDecl = struct {
135 base: Node = .{ .tag = .var_decl },180 base: Node = .{ .tag = .var_decl },
136 @"pub": bool,181 data: struct {
137 @"const": bool,182 @"pub": bool,
138 @"extern": bool,183 @"const": bool,
139 @"export": bool,184 @"extern": bool,
140 name: []const u8,185 @"export": bool,
141 type: Type,186 name: []const u8,
142 init: *Node,187 type: Type,
188 init: *Node,
189 },
143 };190 };
144191
145 pub const Func = struct {192 pub const Func = struct {
146 base: Node = .{.func},193 base: Node = .{.func},
147 @"pub": bool,194 data: struct {
148 @"extern": bool,195 @"pub": bool,
149 @"export": bool,196 @"extern": bool,
150 name: []const u8,197 @"export": bool,
151 cc: std.builtin.CallingConvention,198 name: []const u8,
152 params: []Param,199 cc: std.builtin.CallingConvention,
153 return_type: Type,200 params: []Param,
154 body: ?*Node,201 return_type: Type,
155202 body: ?*Node,
156 pub const Param = struct {203
157 @"noalias": bool,204 pub const Param = struct {
158 name: ?[]const u8,205 @"noalias": bool,
159 type: Type,206 name: ?[]const u8,
160 };207 type: Type,
208 };
209 },
161 };210 };
162211
163 pub const Enum = struct {212 pub const Enum = struct {
164 base: Node = .{ .tag = .@"enum" },213 base: Node = .{ .tag = .@"enum" },
165 name: ?[]const u8,214 data: struct {
166 fields: []Field,215 name: ?[]const u8,
216 fields: []Field,
167217
168 pub const Field = struct {218 pub const Field = struct {
169 name: []const u8,219 name: []const u8,
170 value: ?[]const u8,220 value: ?[]const u8,
171 };221 };
222 },
172 };223 };
173224
174 pub const Record = struct {225 pub const Record = struct {
175 base: Node,226 base: Node,
176 name: ?[]const u8,227 data: struct {
177 @"packed": bool,228 name: ?[]const u8,
178 fields: []Field,229 @"packed": bool,
230 fields: []Field,
179231
180 pub const Field = struct {232 pub const Field = struct {
181 name: []const u8,233 name: []const u8,
182 type: Type,234 type: Type,
183 alignment: c_uint,235 alignment: c_uint,
184 };236 };
237 },
185 };238 };
186239
187 pub const ArrayInit = struct {240 pub const ArrayInit = struct {
188 base: Node = .{ .tag = .array_init },241 base: Node = .{ .tag = .array_init },
189 values: []*Node,242 data: []*Node,
190 };243 };
191244
192 pub const ContainerInit = struct {245 pub const ContainerInit = struct {
193 base: Node = .{ .tag = .container_init },246 base: Node = .{ .tag = .container_init },
194 values: []Initializer,247 data: []Initializer,
195248
196 pub const Initializer = struct {249 pub const Initializer = struct {
197 name: []const u8,250 name: []const u8,
...@@ -201,7 +254,14 @@ pub const Node = struct {...@@ -201,7 +254,14 @@ pub const Node = struct {
201254
202 pub const Block = struct {255 pub const Block = struct {
203 base: Node = .{ .tag = .block },256 base: Node = .{ .tag = .block },
204 label: ?[]const u8,257 data: struct {
205 stmts: []*Node,258 label: ?[]const u8,
259 stmts: []*Node,
260 },
206 };261 };
207};262};
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 {...@@ -3408,6 +3408,11 @@ pub const Type = extern union {
3408 };3408 };
3409 }3409 }
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
3411 pub fn create(comptime t: Tag, ally: *Allocator, data: Data(t)) error{OutOfMemory}!Type {3416 pub fn create(comptime t: Tag, ally: *Allocator, data: Data(t)) error{OutOfMemory}!Type {
3412 const ptr = try ally.create(t.Type());3417 const ptr = try ally.create(t.Type());
3413 ptr.* = .{3418 ptr.* = .{