authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-12-05 00:20:23-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-12-05 00:20:23-05:00
log08d531143f0b373cbc54e037fa526fb00d9db398
treecb9526f4c6441fdb4237791ead9baec30235f1a4
parent3976981ab3370d099535d79d42bd82d5924df7f5

parser skeleton


1 files changed, 173 insertions(+), 55 deletions(-)

src-self-hosted/main.zig+173-55
...@@ -5,60 +5,66 @@ const heap = @import("std").heap;...@@ -5,60 +5,66 @@ const heap = @import("std").heap;
5const warn = @import("std").debug.warn;5const warn = @import("std").debug.warn;
6const assert = @import("std").debug.assert;6const assert = @import("std").debug.assert;
7const mem = @import("std").mem;7const mem = @import("std").mem;
8const ArrayList = @import("std").ArrayList;
9
810
9const Token = struct {11const Token = struct {
10 id: Id,12 id: Id,
11 start: usize,13 start: usize,
12 end: usize,14 end: usize,
1315
14 const Keyword = enum {16 const KeywordId = struct {
15 @"align",17 bytes: []const u8,
16 @"and",18 id: Id,
17 @"asm",19 };
18 @"break",20
19 @"coldcc",21 const keywords = []KeywordId {
20 @"comptime",22 KeywordId{.bytes="align", .id = Id {.Keyword_align = {}}},
21 @"const",23 KeywordId{.bytes="and", .id = Id {.Keyword_and = {}}},
22 @"continue",24 KeywordId{.bytes="asm", .id = Id {.Keyword_asm = {}}},
23 @"defer",25 KeywordId{.bytes="break", .id = Id {.Keyword_break = {}}},
24 @"else",26 KeywordId{.bytes="coldcc", .id = Id {.Keyword_coldcc = {}}},
25 @"enum",27 KeywordId{.bytes="comptime", .id = Id {.Keyword_comptime = {}}},
26 @"error",28 KeywordId{.bytes="const", .id = Id {.Keyword_const = {}}},
27 @"export",29 KeywordId{.bytes="continue", .id = Id {.Keyword_continue = {}}},
28 @"extern",30 KeywordId{.bytes="defer", .id = Id {.Keyword_defer = {}}},
29 @"false",31 KeywordId{.bytes="else", .id = Id {.Keyword_else = {}}},
30 @"fn",32 KeywordId{.bytes="enum", .id = Id {.Keyword_enum = {}}},
31 @"for",33 KeywordId{.bytes="error", .id = Id {.Keyword_error = {}}},
32 @"goto",34 KeywordId{.bytes="export", .id = Id {.Keyword_export = {}}},
33 @"if",35 KeywordId{.bytes="extern", .id = Id {.Keyword_extern = {}}},
34 @"inline",36 KeywordId{.bytes="false", .id = Id {.Keyword_false = {}}},
35 @"nakedcc",37 KeywordId{.bytes="fn", .id = Id {.Keyword_fn = {}}},
36 @"noalias",38 KeywordId{.bytes="for", .id = Id {.Keyword_for = {}}},
37 @"null",39 KeywordId{.bytes="goto", .id = Id {.Keyword_goto = {}}},
38 @"or",40 KeywordId{.bytes="if", .id = Id {.Keyword_if = {}}},
39 @"packed",41 KeywordId{.bytes="inline", .id = Id {.Keyword_inline = {}}},
40 @"pub",42 KeywordId{.bytes="nakedcc", .id = Id {.Keyword_nakedcc = {}}},
41 @"return",43 KeywordId{.bytes="noalias", .id = Id {.Keyword_noalias = {}}},
42 @"stdcallcc",44 KeywordId{.bytes="null", .id = Id {.Keyword_null = {}}},
43 @"struct",45 KeywordId{.bytes="or", .id = Id {.Keyword_or = {}}},
44 @"switch",46 KeywordId{.bytes="packed", .id = Id {.Keyword_packed = {}}},
45 @"test",47 KeywordId{.bytes="pub", .id = Id {.Keyword_pub = {}}},
46 @"this",48 KeywordId{.bytes="return", .id = Id {.Keyword_return = {}}},
47 @"true",49 KeywordId{.bytes="stdcallcc", .id = Id {.Keyword_stdcallcc = {}}},
48 @"undefined",50 KeywordId{.bytes="struct", .id = Id {.Keyword_struct = {}}},
49 @"union",51 KeywordId{.bytes="switch", .id = Id {.Keyword_switch = {}}},
50 @"unreachable",52 KeywordId{.bytes="test", .id = Id {.Keyword_test = {}}},
51 @"use",53 KeywordId{.bytes="this", .id = Id {.Keyword_this = {}}},
52 @"var",54 KeywordId{.bytes="true", .id = Id {.Keyword_true = {}}},
53 @"volatile",55 KeywordId{.bytes="undefined", .id = Id {.Keyword_undefined = {}}},
54 @"while",56 KeywordId{.bytes="union", .id = Id {.Keyword_union = {}}},
57 KeywordId{.bytes="unreachable", .id = Id {.Keyword_unreachable = {}}},
58 KeywordId{.bytes="use", .id = Id {.Keyword_use = {}}},
59 KeywordId{.bytes="var", .id = Id {.Keyword_var = {}}},
60 KeywordId{.bytes="volatile", .id = Id {.Keyword_volatile = {}}},
61 KeywordId{.bytes="while", .id = Id {.Keyword_while = {}}},
55 };62 };
5663
57 fn getKeyword(bytes: []const u8) -> ?Keyword {64 fn getKeyword(bytes: []const u8) -> ?Id {
58 comptime var i = 0;65 for (keywords) |kw| {
59 inline while (i < @memberCount(Keyword)) : (i += 1) {66 if (mem.eql(u8, kw.bytes, bytes)) {
60 if (mem.eql(u8, @memberName(Keyword, i), bytes)) {67 return kw.id;
61 return Keyword(i);
62 }68 }
63 }69 }
64 return null;70 return null;
...@@ -69,7 +75,6 @@ const Token = struct {...@@ -69,7 +75,6 @@ const Token = struct {
69 const Id = union(enum) {75 const Id = union(enum) {
70 Invalid,76 Invalid,
71 Identifier,77 Identifier,
72 Keyword: Keyword,
73 StringLiteral: StrLitKind,78 StringLiteral: StrLitKind,
74 Eof,79 Eof,
75 Builtin,80 Builtin,
...@@ -83,6 +88,46 @@ const Token = struct {...@@ -83,6 +88,46 @@ const Token = struct {
83 Period,88 Period,
84 Minus,89 Minus,
85 Arrow,90 Arrow,
91 Keyword_align,
92 Keyword_and,
93 Keyword_asm,
94 Keyword_break,
95 Keyword_coldcc,
96 Keyword_comptime,
97 Keyword_const,
98 Keyword_continue,
99 Keyword_defer,
100 Keyword_else,
101 Keyword_enum,
102 Keyword_error,
103 Keyword_export,
104 Keyword_extern,
105 Keyword_false,
106 Keyword_fn,
107 Keyword_for,
108 Keyword_goto,
109 Keyword_if,
110 Keyword_inline,
111 Keyword_nakedcc,
112 Keyword_noalias,
113 Keyword_null,
114 Keyword_or,
115 Keyword_packed,
116 Keyword_pub,
117 Keyword_return,
118 Keyword_stdcallcc,
119 Keyword_struct,
120 Keyword_switch,
121 Keyword_test,
122 Keyword_this,
123 Keyword_true,
124 Keyword_undefined,
125 Keyword_union,
126 Keyword_unreachable,
127 Keyword_use,
128 Keyword_var,
129 Keyword_volatile,
130 Keyword_while,
86 };131 };
87};132};
88133
...@@ -193,8 +238,8 @@ const Tokenizer = struct {...@@ -193,8 +238,8 @@ const Tokenizer = struct {
193 State.Identifier => switch (c) {238 State.Identifier => switch (c) {
194 'a'...'z', 'A'...'Z', '_', '0'...'9' => {},239 'a'...'z', 'A'...'Z', '_', '0'...'9' => {},
195 else => {240 else => {
196 if (Token.getKeyword(self.buffer[result.start..self.index])) |keyword_id| {241 if (Token.getKeyword(self.buffer[result.start..self.index])) |id| {
197 result.id = Token.Id { .Keyword = keyword_id };242 result.id = id;
198 }243 }
199 break;244 break;
200 },245 },
...@@ -251,6 +296,73 @@ const Tokenizer = struct {...@@ -251,6 +296,73 @@ const Tokenizer = struct {
251 }296 }
252};297};
253298
299const AstNode = struct {
300
301};
302
303const Parser = struct {
304 tokenizer: &Tokenizer,
305 allocator: &mem.Allocator,
306
307 fn init(tokenizer: &Tokenizer, allocator: &mem.Allocator) -> Parser {
308 return Parser {
309 .tokenizer = tokenizer,
310 .allocator = allocator,
311 };
312 }
313
314 const StackFrame = struct {
315
316 };
317
318 const State = enum {
319 TopLevel,
320 Expression,
321 };
322
323 fn parse(self: &Parser) -> %void {
324 var stack = ArrayList(StackFrame).init(self.allocator);
325 defer stack.deinit();
326
327 var state = State.TopLevel;
328 while (true) {
329 const token = self.tokenizer.next();
330 switch (state) {
331 State.TopLevel => switch (token.id) {
332 Token.Id.Keyword_pub => {
333 const next_token = self.tokenizer.next();
334 switch (next_token.id) {
335 Token.Id.Keyword_fn => {
336 const fn_name = self.tokenizer.next();
337 if (@TagType(Token.Id)(fn_name.id) != Token.Id.Identifier) {
338 @panic("parse error");
339 }
340
341 const lparen = self.tokenizer.next();
342 if (@TagType(Token.Id)(lparen.id) != Token.Id.LParen) {
343 @panic("parse error");
344 }
345 },
346 Token.Id.Keyword_const => @panic("TODO"),
347 Token.Id.Keyword_var => @panic("TODO"),
348 Token.Id.Keyword_use => @panic("TODO"),
349 else => @panic("parse error"),
350 }
351 },
352 Token.Id.Keyword_const => @panic("TODO"),
353 Token.Id.Keyword_var => @panic("TODO"),
354 Token.Id.Keyword_fn => @panic("TODO"),
355 Token.Id.Keyword_export => @panic("TODO"),
356 Token.Id.Keyword_use => @panic("TODO"),
357 Token.Id.Keyword_comptime => @panic("TODO"),
358 else => @panic("parse error"),
359 },
360 State.Expression => @panic("TODO"),
361 }
362 }
363 }
364};
365
254366
255pub fn main() -> %void {367pub fn main() -> %void {
256 main2() %% |err| {368 main2() %% |err| {
...@@ -271,12 +383,18 @@ pub fn main2() -> %void {...@@ -271,12 +383,18 @@ pub fn main2() -> %void {
271383
272 warn("{}", target_file_buf);384 warn("{}", target_file_buf);
273385
274 var tokenizer = Tokenizer.init(target_file_buf);386 {
275 while (true) {387 var tokenizer = Tokenizer.init(target_file_buf);
276 const token = tokenizer.next();388 while (true) {
277 tokenizer.dump(token);389 const token = tokenizer.next();
278 if (@TagType(Token.Id)(token.id) == Token.Id.Eof) {390 tokenizer.dump(token);
279 break;391 if (@TagType(Token.Id)(token.id) == Token.Id.Eof) {
392 break;
393 }
280 }394 }
281 }395 }
396
397 var tokenizer = Tokenizer.init(target_file_buf);
398 var parser = Parser.init(&tokenizer, allocator);
399 %return parser.parse();
282}400}