Compare commits

...

4 Commits

Author SHA1 Message Date
Luna 36361b3d13 readme: enums are done 2019-08-27 12:31:43 -03:00
Luna 9781a28df7 add enum support 2019-08-27 12:31:02 -03:00
Luna 622f0e8d81 readme: arrays done 2019-08-27 12:21:33 -03:00
Luna 6ab7cdbe20 add array parsing 2019-08-27 12:19:10 -03:00
5 changed files with 95 additions and 3 deletions

View File

@ -35,12 +35,10 @@ negatively charged towards
## wip
- no `for` yet
- no arrays yet
- no `map` yet
- no `in` yet (probably will be dropped)
- no `module`, `import` yet
- no interfaces yet
- no enums yet
- no generics yet
- no attributes yet (`[live]`, `[skip]`)
- no `defer` yet

View File

@ -61,6 +61,8 @@ fn main(a int) int {
str.len -= 1
str.len *= 1
str.len /= 1
awoo := [1, 2, a(), b + 2, c(31) * d]
}
fn (v Typ) voidfunc() {}
@ -77,3 +79,9 @@ pub mut:
pub mut mut:
f int
}
enum Color {
red green blue
cyan
alpha
}

View File

@ -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,
};
@ -64,6 +66,7 @@ pub const LiteralExpr = union(enum) {
Integer: []const u8,
Float: []const u8,
String: []const u8,
Array: ExprList,
};
pub const AssignExpr = struct {
@ -238,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,
@ -265,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;
}
};

View File

@ -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);
@ -146,6 +160,10 @@ pub fn printExpr(expr: *Expr) void {
.Integer => |val| std.debug.warn("{}", val),
.Float => |val| std.debug.warn("{}", val),
.String => |val| std.debug.warn("'{}'", val),
.Array => |exprs| {
parenthetize("array", exprs.toSlice());
},
else => |typ| std.debug.warn("UnknownLiteral-{}", typ),
}
},

View File

@ -350,6 +350,17 @@ pub const Parser = struct {
return expr;
}
fn mkArray(self: *Parser, exprs: ast.ExprList) !*ast.Expr {
var expr = try self.allocator.create(Expr);
expr.* = Expr{
.Literal = ast.LiteralExpr{
.Array = exprs,
},
};
return expr;
}
fn mkVariable(self: *Parser, variable: Token) !*ast.Expr {
var expr = try self.allocator.create(Expr);
expr.* = Expr{ .Variable = variable };
@ -571,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);
@ -1000,7 +1031,23 @@ pub const Parser = struct {
.String => try self.mkString(lexeme),
.Identifier => try self.mkVariable(self.peek()),
.LeftParen => blk: {
// type checking for arrays happens at later stages
.LeftSquare => {
_ = try self.consumeSingle(.LeftSquare);
var exprs = ast.ExprList.init(self.allocator);
errdefer exprs.deinit();
while (!self.check(.RightSquare)) {
try exprs.append(try self.parseExpr());
if (self.check(.Comma)) _ = try self.consumeSingle(.Comma);
}
_ = try self.consumeSingle(.RightSquare);
return try self.mkArray(exprs);
},
.LeftParen => {
_ = try self.nextToken();
var expr = try self.parseExpr();
_ = try self.consume(.RightParen, "Expected ')' after expression");