From 9781a28df7874e8d918fcbd67f8e686ddadd01a2 Mon Sep 17 00:00:00 2001 From: Luna Date: Tue, 27 Aug 2019 12:31:02 -0300 Subject: [PATCH] add enum support --- examples/hello.v | 6 ++++++ src/ast.zig | 20 ++++++++++++++++++++ src/ast_printer.zig | 14 ++++++++++++++ src/parser.zig | 20 ++++++++++++++++++++ 4 files changed, 60 insertions(+) diff --git a/examples/hello.v b/examples/hello.v index ba91ed7..b0f03c1 100644 --- a/examples/hello.v +++ b/examples/hello.v @@ -79,3 +79,9 @@ pub mut: pub mut mut: f int } + +enum Color { + red green blue + cyan + alpha +} diff --git a/src/ast.zig b/src/ast.zig index bbb4956..773d9c5 100644 --- a/src/ast.zig +++ b/src/ast.zig @@ -5,6 +5,7 @@ const Token = tokens.Token; pub const NodeList = std.ArrayList(*Node); pub const StmtList = std.ArrayList(*Stmt); pub const ExprList = std.ArrayList(*Expr); +pub const TokenList = std.ArrayList(Token); pub const ParamList = std.ArrayList(ParamDecl); pub const ConstList = std.ArrayList(SingleConst); @@ -13,6 +14,7 @@ pub const NodeType = enum { FnDecl, ConstDecl, Struct, + Enum, Block, Stmt, }; @@ -239,11 +241,17 @@ pub const Struct = struct { fields: FieldList, }; +pub const Enum = struct { + name: Token, + fields: TokenList, +}; + pub const Node = union(NodeType) { Root: NodeList, FnDecl: FnDecl, ConstDecl: ConstList, Struct: Struct, + Enum: Enum, Block: StmtList, @@ -266,4 +274,16 @@ pub const Node = union(NodeType) { return node; } + + pub fn mkEnumDecl(allocator: *std.mem.Allocator, name: Token, fields: TokenList) !*Node { + var node = try allocator.create(Node); + node.* = Node{ + .Enum = Enum{ + .name = name, + .fields = fields, + }, + }; + + return node; + } }; diff --git a/src/ast_printer.zig b/src/ast_printer.zig index 5e41240..6360035 100644 --- a/src/ast_printer.zig +++ b/src/ast_printer.zig @@ -81,6 +81,20 @@ pub fn printNode(node: *Node, ident: usize) void { print(ident, "))\n"); }, + .Enum => |decl| { + print(ident, "(enum {} (\n", decl.name.lexeme); + + for (decl.fields.toSlice()) |field| { + print( + ident + 1, + "{}\n", + field.lexeme, + ); + } + + print(ident, "))\n"); + }, + .Root => { for (node.Root.toSlice()) |child| { printNode(child, ident + 1); diff --git a/src/parser.zig b/src/parser.zig index 0675378..197b69f 100644 --- a/src/parser.zig +++ b/src/parser.zig @@ -582,11 +582,31 @@ pub const Parser = struct { } } + fn parseEnumDecl(self: *@This()) !*Node { + _ = try self.consumeSingle(.Enum); + + var fields = ast.TokenList.init(self.allocator); + errdefer fields.deinit(); + + const name = try self.consumeSingle(.Identifier); + + _ = try self.consumeSingle(.LeftBrace); + + while (!self.check(.RightBrace)) { + try fields.append(try self.consumeSingle(.Identifier)); + } + + _ = try self.consumeSingle(.RightBrace); + + return try Node.mkEnumDecl(self.allocator, name, fields); + } + fn parseTopDecl(self: *@This()) !*Node { return switch (self.peek().ttype) { .Fn => try self.parseFnDecl(), .Const => try self.parseConstDecl(), .Struct => try self.parseStructDecl(), + .Enum => try self.parseEnumDecl(), else => |ttype| blk: { self.doError("expected Fn, Const, Struct, got {}\n", ttype);