vig/src/ast.zig

312 lines
5.9 KiB
Zig
Raw Normal View History

const std = @import("std");
2019-06-05 23:29:03 +00:00
const tokens = @import("tokens.zig");
const Token = tokens.Token;
pub const NodeList = std.ArrayList(*Node);
2019-08-24 19:00:22 +00:00
pub const StmtList = std.ArrayList(*Stmt);
2019-08-24 01:13:26 +00:00
pub const ExprList = std.ArrayList(*Expr);
2019-08-27 15:31:02 +00:00
pub const TokenList = std.ArrayList(Token);
2019-08-23 18:52:04 +00:00
pub const ParamList = std.ArrayList(ParamDecl);
pub const ConstList = std.ArrayList(SingleConst);
pub const NodeType = enum {
Root,
FnDecl,
ConstDecl,
2019-08-26 13:49:43 +00:00
Struct,
2019-08-27 15:31:02 +00:00
Enum,
2019-08-24 01:13:26 +00:00
Block,
2019-08-24 19:00:22 +00:00
Stmt,
};
2019-07-01 18:55:19 +00:00
pub const ParamDecl = struct {
2019-08-23 18:52:04 +00:00
name: Token,
typ: Token,
2019-07-01 18:55:19 +00:00
};
2019-08-26 23:31:15 +00:00
pub const MethodData = struct {
variable: Token,
typ: Token,
mutable: bool,
};
pub const FnDecl = struct {
2019-07-01 18:25:07 +00:00
func_name: Token,
2019-07-01 18:55:19 +00:00
params: ParamList,
return_type: Token,
2019-08-24 19:00:22 +00:00
body: StmtList,
2019-08-26 23:31:15 +00:00
method: ?*MethodData,
};
pub const SingleConst = struct {
name: Token,
2019-08-24 19:00:22 +00:00
expr: *Expr,
};
2019-08-24 01:13:26 +00:00
pub const BinaryExpr = struct {
left: *Expr,
op: Token,
right: *Expr,
};
pub const UnaryExpr = struct {
op: Token,
right: *Expr,
};
2019-08-25 16:21:22 +00:00
// looks like a BinaryExpr, but is not a BinaryExpr
pub const LogicalExpr = struct {
left: *Expr,
op: Token,
right: *Expr,
};
2019-08-24 01:13:26 +00:00
pub const LiteralExpr = union(enum) {
Bool: bool,
Integer: []const u8,
Float: []const u8,
String: []const u8,
2019-08-27 15:19:10 +00:00
Array: ExprList,
2019-08-24 01:13:26 +00:00
};
2019-08-25 13:27:50 +00:00
pub const AssignExpr = struct {
name: Token,
value: *Expr,
};
pub const ExprType = enum {
Assign,
// vardecls as expressions is a hack
VarDecl,
2019-08-25 13:27:50 +00:00
Binary,
Unary,
2019-08-25 16:21:22 +00:00
Logical,
2019-08-25 13:27:50 +00:00
Literal,
Variable,
2019-08-26 01:41:25 +00:00
Call,
2019-08-26 14:59:32 +00:00
Struct,
2019-08-25 13:27:50 +00:00
Grouping,
2019-08-26 16:15:08 +00:00
Get,
2019-08-26 16:29:45 +00:00
Set,
2019-08-25 13:27:50 +00:00
};
pub const VarDecl = struct {
assign: AssignExpr,
mutable: bool = false,
};
2019-08-26 01:41:25 +00:00
pub const CallExpr = struct {
callee: *Expr,
paren: Token,
arguments: ExprList,
};
2019-08-26 14:59:32 +00:00
pub const StructInit = struct {
field: Token,
expr: *Expr,
};
pub const StructInitList = std.ArrayList(StructInit);
pub const StructExpr = struct {
name: Token,
inits: StructInitList,
};
2019-08-26 16:15:08 +00:00
pub const GetExpr = struct {
struc: *Expr,
name: Token,
};
2019-08-26 16:29:45 +00:00
pub const SetExpr = struct {
struc: *Expr,
field: Token,
value: *Expr,
};
2019-08-25 13:27:50 +00:00
pub const Expr = union(ExprType) {
Assign: AssignExpr,
VarDecl: VarDecl,
2019-08-25 15:31:57 +00:00
2019-08-24 01:13:26 +00:00
Binary: BinaryExpr,
Unary: UnaryExpr,
2019-08-25 16:21:22 +00:00
Logical: LogicalExpr,
2019-08-24 01:13:26 +00:00
Literal: LiteralExpr,
2019-08-26 14:59:32 +00:00
Struct: StructExpr,
2019-08-25 15:31:57 +00:00
Variable: Token,
2019-08-24 01:13:26 +00:00
Grouping: *Expr,
2019-08-26 01:41:25 +00:00
Call: CallExpr,
2019-08-26 16:29:45 +00:00
2019-08-26 16:15:08 +00:00
Get: GetExpr,
2019-08-26 16:29:45 +00:00
Set: SetExpr,
2019-08-24 01:13:26 +00:00
};
pub const Block = std.ArrayList(*Stmt);
2019-08-25 15:31:57 +00:00
pub const IfStmt = struct {
condition: *Expr,
then_branch: Block,
else_branch: ?Block,
};
pub const LoopStmt = struct {
condition: ?*Expr,
then_branch: Block,
2019-08-25 15:31:57 +00:00
};
2019-08-29 17:30:33 +00:00
pub const ForStmt = struct {
index: ?Token,
value: Token,
array: Token,
block: Block,
};
2019-08-24 19:00:22 +00:00
pub const Stmt = union(enum) {
Expr: *Expr,
Println: *Expr,
2019-08-25 15:31:57 +00:00
If: IfStmt,
Loop: LoopStmt,
2019-08-29 17:30:33 +00:00
For: ForStmt,
2019-08-24 19:00:22 +00:00
2019-08-26 02:16:13 +00:00
Return: ReturnStmt,
pub const ReturnStmt = struct {
keyword: Token,
value: *Expr,
};
2019-08-24 19:00:22 +00:00
pub fn mkPrintln(allocator: *std.mem.Allocator, expr: *Expr) !*Stmt {
var stmt = try allocator.create(Stmt);
stmt.* = Stmt{ .Println = expr };
return stmt;
2019-08-24 19:00:22 +00:00
}
2019-08-25 16:02:40 +00:00
pub fn mkIfStmt(
allocator: *std.mem.Allocator,
condition: *Expr,
then: Block,
else_branch: ?Block,
2019-08-25 16:02:40 +00:00
) !*Stmt {
var stmt = try allocator.create(Stmt);
stmt.* = Stmt{
2019-08-25 16:02:40 +00:00
.If = IfStmt{
.condition = condition,
.then_branch = then,
.else_branch = else_branch,
},
};
return stmt;
}
pub fn mkLoop(
allocator: *std.mem.Allocator,
condition: ?*Expr,
then: Block,
) !*Stmt {
var stmt = try allocator.create(Stmt);
stmt.* = Stmt{
.Loop = LoopStmt{
.condition = condition,
.then_branch = then,
},
};
return stmt;
2019-08-25 16:02:40 +00:00
}
2019-08-26 02:16:13 +00:00
2019-08-29 17:30:33 +00:00
pub fn mkFor(allocator: *std.mem.Allocator, index: ?Token, value: Token, array: Token, block: Block) !*Stmt {
var stmt = try allocator.create(Stmt);
stmt.* = Stmt{
.For = ForStmt{
.index = index,
.value = value,
.array = array,
.block = block,
},
};
return stmt;
}
2019-08-26 02:16:13 +00:00
pub fn mkReturn(allocator: *std.mem.Allocator, tok: Token, value: *Expr) !*Stmt {
var stmt = try allocator.create(Stmt);
stmt.* = Stmt{
.Return = ReturnStmt{
.keyword = tok,
.value = value,
},
};
return stmt;
}
2019-08-24 19:00:22 +00:00
};
2019-08-26 13:49:43 +00:00
pub const FieldList = std.ArrayList(StructField);
pub const StructField = struct {
name: Token,
typ: Token,
2019-08-27 00:31:01 +00:00
mutable: bool = false,
public: bool = false,
mutable_outside: bool = false,
2019-08-26 13:49:43 +00:00
};
pub const Struct = struct {
name: Token,
fields: FieldList,
};
2019-08-27 15:31:02 +00:00
pub const Enum = struct {
name: Token,
fields: TokenList,
};
pub const Node = union(NodeType) {
Root: NodeList,
FnDecl: FnDecl,
ConstDecl: ConstList,
2019-08-26 13:49:43 +00:00
Struct: Struct,
2019-08-27 15:31:02 +00:00
Enum: Enum,
2019-08-24 14:07:23 +00:00
2019-08-24 19:00:22 +00:00
Block: StmtList,
Stmt: *Stmt,
2019-06-05 23:29:03 +00:00
2019-08-26 13:49:43 +00:00
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;
}
2019-08-27 15:31:02 +00:00
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;
}
2019-08-26 13:49:43 +00:00
};