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)
}
//struct Point {
// x int
// y int
//}
struct Point {
x int
y int
}

View File

@ -12,6 +12,7 @@ pub const NodeType = enum {
Root,
FnDecl,
ConstDecl,
Struct,
Block,
Expr,
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) {
Root: NodeList,
FnDecl: FnDecl,
ConstDecl: ConstList,
Struct: Struct,
Block: StmtList,
Expr: *Expr,
Stmt: *Stmt,
};
pub fn mkRoot(allocator: *std.mem.Allocator) !*Node {
var node = try allocator.create(Node);
node.* = Node{ .Root = NodeList.init(allocator) };
return node;
}
pub fn mkRoot(allocator: *std.mem.Allocator) !*Node {
var node = try allocator.create(Node);
node.* = Node{ .Root = NodeList.init(allocator) };
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");
},
.Stmt => |stmt| blk: {
.Stmt => |stmt| {
printIdent(ident);
printStmt(ident, stmt);
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 => {
print(ident, "unknown node: {}\n", node);
},

View File

@ -311,7 +311,7 @@ pub const Parser = struct {
}
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;
@ -389,11 +389,37 @@ pub const Parser = struct {
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 {
return switch (self.peek().ttype) {
.Fn => try self.parseFnDecl(),
.Const => try self.parseConstDecl(),
// TODO .Struct => try self.parseStructDecl(),
.Struct => try self.parseStructDecl(),
else => |ttype| blk: {
self.doError("(basic) expected fn/const, got {}\n", ttype);