add structs

This commit is contained in:
Luna 2019-08-26 10:49:43 -03:00
parent 45ae160b76
commit 19fd9daebf
4 changed files with 86 additions and 13 deletions

View file

@ -42,7 +42,7 @@ fn main(a int) int {
//println(p.x) //println(p.x)
} }
//struct Point { struct Point {
// x int x int
// y int y int
//} }

View file

@ -12,6 +12,7 @@ pub const NodeType = enum {
Root, Root,
FnDecl, FnDecl,
ConstDecl, ConstDecl,
Struct,
Block, Block,
Expr, Expr,
Stmt, Stmt,
@ -184,19 +185,46 @@ pub const Stmt = union(enum) {
} }
}; };
pub const FieldList = std.ArrayList(StructField);
pub const StructField = struct {
name: Token,
typ: Token,
mutable: bool = true,
public: bool = true,
};
pub const Struct = struct {
name: Token,
fields: FieldList,
};
pub const Node = union(NodeType) { pub const Node = union(NodeType) {
Root: NodeList, Root: NodeList,
FnDecl: FnDecl, FnDecl: FnDecl,
ConstDecl: ConstList, ConstDecl: ConstList,
Struct: Struct,
Block: StmtList, Block: StmtList,
Expr: *Expr, Expr: *Expr,
Stmt: *Stmt, Stmt: *Stmt,
};
pub fn mkRoot(allocator: *std.mem.Allocator) !*Node { pub fn mkRoot(allocator: *std.mem.Allocator) !*Node {
var node = try allocator.create(Node); var node = try allocator.create(Node);
node.* = Node{ .Root = NodeList.init(allocator) }; node.* = Node{ .Root = NodeList.init(allocator) };
return node; return node;
} }
pub fn mkStructDecl(allocator: *std.mem.Allocator, name: Token, fields: FieldList) !*Node {
var node = try allocator.create(Node);
node.* = Node{
.Struct = Struct{
.name = name,
.fields = fields,
},
};
return node;
}
};

View file

@ -74,12 +74,31 @@ pub fn printNode(node: *Node, ident: usize) void {
std.debug.warn("\n"); std.debug.warn("\n");
}, },
.Stmt => |stmt| blk: { .Stmt => |stmt| {
printIdent(ident); printIdent(ident);
printStmt(ident, stmt); printStmt(ident, stmt);
std.debug.warn("\n"); std.debug.warn("\n");
}, },
.Struct => |struc| {
print(ident, "(struct {} (\n", struc.name.lexeme);
for (struc.fields.toSlice()) |field| {
printIdent(ident + 1);
if (field.mutable) {
std.debug.warn("(mut ");
} else {
std.debug.warn("(");
}
if (field.public) {
std.debug.warn("pub ");
}
std.debug.warn("{} {})\n", field.name.lexeme, field.typ.lexeme);
}
print(ident, "))\n");
},
else => { else => {
print(ident, "unknown node: {}\n", node); print(ident, "unknown node: {}\n", node);
}, },

View file

@ -311,7 +311,7 @@ pub const Parser = struct {
} }
pub fn parse(self: *Parser) !*ast.Node { pub fn parse(self: *Parser) !*ast.Node {
var root = try ast.mkRoot(self.allocator); var root = try Node.mkRoot(self.allocator);
var token_opt: ?Token = null; var token_opt: ?Token = null;
@ -389,11 +389,37 @@ pub const Parser = struct {
return self.mkConstDecl(consts); return self.mkConstDecl(consts);
} }
fn parseStructDecl(self: *@This()) !*Node {
var fields = ast.FieldList.init(self.allocator);
errdefer fields.deinit();
_ = try self.consumeSingle(.Struct);
var name = try self.consumeSingle(.Identifier);
_ = try self.consumeSingle(.LeftBrace);
while (!self.check(.RightBrace)) {
// TODO mut and pub
const field_name = try self.consumeSingle(.Identifier);
const field_type = try self.consumeSingle(.Identifier);
try fields.append(ast.StructField{
.name = field_name,
.typ = field_type,
});
}
_ = try self.consumeSingle(.RightBrace);
return Node.mkStructDecl(self.allocator, name, fields);
}
fn parseTopDecl(self: *@This()) !*Node { fn parseTopDecl(self: *@This()) !*Node {
return switch (self.peek().ttype) { return switch (self.peek().ttype) {
.Fn => try self.parseFnDecl(), .Fn => try self.parseFnDecl(),
.Const => try self.parseConstDecl(), .Const => try self.parseConstDecl(),
// TODO .Struct => try self.parseStructDecl(), .Struct => try self.parseStructDecl(),
else => |ttype| blk: { else => |ttype| blk: {
self.doError("(basic) expected fn/const, got {}\n", ttype); self.doError("(basic) expected fn/const, got {}\n", ttype);