dusk: AstGen expressions
This commit is contained in:
parent
858ba2eca5
commit
0d45438316
5 changed files with 164 additions and 27 deletions
|
|
@ -537,10 +537,14 @@ pub const Node = struct {
|
|||
|
||||
// ####### Literals #######
|
||||
|
||||
/// TOK : k_true, k_false
|
||||
/// TOK : k_true
|
||||
/// LHS : --
|
||||
/// RHS : --
|
||||
bool_literal,
|
||||
bool_true,
|
||||
/// TOK : k_false
|
||||
/// LHS : --
|
||||
/// RHS : --
|
||||
bool_false,
|
||||
/// TOK : number
|
||||
/// LHS : --
|
||||
/// RHS : --
|
||||
|
|
|
|||
|
|
@ -135,6 +135,7 @@ pub fn genGlobalVariable(self: *AstGen, scope: *Scope, node: Ast.Index) !IR.Inst
|
|||
std.debug.assert(self.tree.nodeTag(node) == .global_variable);
|
||||
|
||||
const inst = try self.reserveInst();
|
||||
const rhs = self.tree.nodeRHS(node);
|
||||
const gv = self.tree.extraData(Ast.Node.GlobalVarDecl, self.tree.nodeLHS(node));
|
||||
// for (self.tree.spanToList(gv.attrs), 0..) |attr_node, i| {
|
||||
// const attr = switch (self.tree.nodeTag(attr_node)) {
|
||||
|
|
@ -170,6 +171,11 @@ pub fn genGlobalVariable(self: *AstGen, scope: *Scope, node: Ast.Index) !IR.Inst
|
|||
};
|
||||
}
|
||||
|
||||
var expr = IR.Inst.Ref.none;
|
||||
if (rhs != Ast.null_index) {
|
||||
expr = try self.genExpr(scope, rhs);
|
||||
}
|
||||
|
||||
const name_index = try self.addString(self.declNameLoc(node).?.slice(self.tree.source));
|
||||
self.instructions.items[inst] = .{
|
||||
.tag = .global_variable_decl,
|
||||
|
|
@ -180,6 +186,7 @@ pub fn genGlobalVariable(self: *AstGen, scope: *Scope, node: Ast.Index) !IR.Inst
|
|||
.addr_space = addr_space,
|
||||
.access_mode = access_mode,
|
||||
.attrs = 0, // TODO
|
||||
.expr = expr,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
@ -278,6 +285,59 @@ pub fn genStruct(self: *AstGen, scope: *Scope, node: Ast.Index) !IR.Inst.Ref {
|
|||
return IR.Inst.toRef(inst);
|
||||
}
|
||||
|
||||
pub fn genExpr(self: *AstGen, scope: *Scope, node: Ast.Index) !IR.Inst.Ref {
|
||||
const tag = self.tree.nodeTag(node);
|
||||
const lhs = self.tree.nodeLHS(node);
|
||||
const rhs = self.tree.nodeRHS(node);
|
||||
|
||||
switch (tag) {
|
||||
.bool_true => return .true_literal,
|
||||
.bool_false => return .true_literal,
|
||||
else => {},
|
||||
}
|
||||
|
||||
const inst_index = try self.reserveInst();
|
||||
const inst: IR.Inst = switch (tag) {
|
||||
.number_literal => .{ .tag = .integer_literal, .data = .{ .integer_literal = 1 } },
|
||||
.not => .{ .tag = .not, .data = .{ .ref = try self.genExpr(scope, lhs) } },
|
||||
.negate => .{ .tag = .negate, .data = .{ .ref = try self.genExpr(scope, lhs) } },
|
||||
.deref => .{ .tag = .deref, .data = .{ .ref = try self.genExpr(scope, lhs) } },
|
||||
.addr_of => .{ .tag = .addr_of, .data = .{ .ref = try self.genExpr(scope, lhs) } },
|
||||
.mul => .{ .tag = .mul, .data = .{ .binary = .{ .lhs = try self.genExpr(scope, lhs), .rhs = try self.genExpr(scope, rhs) } } },
|
||||
.div => .{ .tag = .div, .data = .{ .binary = .{ .lhs = try self.genExpr(scope, lhs), .rhs = try self.genExpr(scope, rhs) } } },
|
||||
.mod => .{ .tag = .mod, .data = .{ .binary = .{ .lhs = try self.genExpr(scope, lhs), .rhs = try self.genExpr(scope, rhs) } } },
|
||||
.add => .{ .tag = .add, .data = .{ .binary = .{ .lhs = try self.genExpr(scope, lhs), .rhs = try self.genExpr(scope, rhs) } } },
|
||||
.sub => .{ .tag = .sub, .data = .{ .binary = .{ .lhs = try self.genExpr(scope, lhs), .rhs = try self.genExpr(scope, rhs) } } },
|
||||
.shift_left => .{ .tag = .shift_left, .data = .{ .binary = .{ .lhs = try self.genExpr(scope, lhs), .rhs = try self.genExpr(scope, rhs) } } },
|
||||
.shift_right => .{ .tag = .shift_right, .data = .{ .binary = .{ .lhs = try self.genExpr(scope, lhs), .rhs = try self.genExpr(scope, rhs) } } },
|
||||
.binary_and => .{ .tag = .binary_and, .data = .{ .binary = .{ .lhs = try self.genExpr(scope, lhs), .rhs = try self.genExpr(scope, rhs) } } },
|
||||
.binary_or => .{ .tag = .binary_or, .data = .{ .binary = .{ .lhs = try self.genExpr(scope, lhs), .rhs = try self.genExpr(scope, rhs) } } },
|
||||
.binary_xor => .{ .tag = .binary_xor, .data = .{ .binary = .{ .lhs = try self.genExpr(scope, lhs), .rhs = try self.genExpr(scope, rhs) } } },
|
||||
.circuit_and => .{ .tag = .circuit_and, .data = .{ .binary = .{ .lhs = try self.genExpr(scope, lhs), .rhs = try self.genExpr(scope, rhs) } } },
|
||||
.circuit_or => .{ .tag = .circuit_or, .data = .{ .binary = .{ .lhs = try self.genExpr(scope, lhs), .rhs = try self.genExpr(scope, rhs) } } },
|
||||
.equal => .{ .tag = .equal, .data = .{ .binary = .{ .lhs = try self.genExpr(scope, lhs), .rhs = try self.genExpr(scope, rhs) } } },
|
||||
.not_equal => .{ .tag = .not_equal, .data = .{ .binary = .{ .lhs = try self.genExpr(scope, lhs), .rhs = try self.genExpr(scope, rhs) } } },
|
||||
.less => .{ .tag = .less, .data = .{ .binary = .{ .lhs = try self.genExpr(scope, lhs), .rhs = try self.genExpr(scope, rhs) } } },
|
||||
.less_equal => .{ .tag = .less_equal, .data = .{ .binary = .{ .lhs = try self.genExpr(scope, lhs), .rhs = try self.genExpr(scope, rhs) } } },
|
||||
.greater => .{ .tag = .greater, .data = .{ .binary = .{ .lhs = try self.genExpr(scope, lhs), .rhs = try self.genExpr(scope, rhs) } } },
|
||||
.greater_equal => .{ .tag = .greater_equal, .data = .{ .binary = .{ .lhs = try self.genExpr(scope, lhs), .rhs = try self.genExpr(scope, rhs) } } },
|
||||
.index_access => .{ .tag = .index, .data = .{ .binary = .{ .lhs = try self.genExpr(scope, lhs), .rhs = try self.genExpr(scope, rhs) } } },
|
||||
.component_access => .{ .tag = .member_access, .data = .{ .binary = .{ .lhs = try self.genExpr(scope, lhs), .rhs = try self.genExpr(scope, rhs) } } },
|
||||
.bitcast => .{ .tag = .bitcast, .data = .{ .binary = .{ .lhs = try self.genExpr(scope, lhs), .rhs = try self.genType(scope, rhs) } } },
|
||||
.ident_expr => .{
|
||||
.tag = .ident,
|
||||
.data = .{ .name = try self.addString(self.tree.tokenLoc(self.tree.nodeToken(node)).slice(self.tree.source)) },
|
||||
},
|
||||
else => {
|
||||
std.debug.print("WTF REALLY\n", .{});
|
||||
unreachable;
|
||||
},
|
||||
};
|
||||
|
||||
self.instructions.items[inst_index] = inst;
|
||||
return IR.Inst.toRef(inst_index);
|
||||
}
|
||||
|
||||
pub fn addString(self: *AstGen, str: []const u8) error{OutOfMemory}!u32 {
|
||||
const len = str.len + 1;
|
||||
try self.strings.ensureUnusedCapacity(self.allocator, len);
|
||||
|
|
|
|||
|
|
@ -187,6 +187,9 @@ pub const Inst = struct {
|
|||
/// data is binary (lhs is expr, rhs is type)
|
||||
bitcast,
|
||||
|
||||
/// data is name
|
||||
ident,
|
||||
|
||||
pub fn isDecl(self: Tag) bool {
|
||||
return switch (self) {
|
||||
.global_variable_decl, .struct_decl => true,
|
||||
|
|
@ -197,6 +200,8 @@ pub const Inst = struct {
|
|||
|
||||
pub const Data = union {
|
||||
ref: Ref,
|
||||
/// index to null-terminated string in `strings`
|
||||
name: u32,
|
||||
global_variable_decl: GlobalVariableDecl,
|
||||
struct_decl: StructDecl,
|
||||
struct_member: StructMember,
|
||||
|
|
@ -234,6 +239,7 @@ pub const Inst = struct {
|
|||
access_mode: AccessMode,
|
||||
/// length of attributes
|
||||
attrs: u4 = 0,
|
||||
expr: Ref = .none,
|
||||
|
||||
pub const AddressSpace = enum {
|
||||
none,
|
||||
|
|
@ -442,6 +448,6 @@ pub const Inst = struct {
|
|||
};
|
||||
|
||||
comptime {
|
||||
std.debug.assert(@sizeOf(Inst) <= 24);
|
||||
std.debug.assert(@sizeOf(Inst) <= 32);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1452,9 +1452,13 @@ pub fn primaryExpr(p: *Parser) !?Ast.Index {
|
|||
const main_token = p.tok_i;
|
||||
if (try p.callExpr()) |call| return call;
|
||||
switch (p.getToken(.tag, main_token)) {
|
||||
.k_true, .k_false => {
|
||||
.k_true => {
|
||||
_ = p.advanceToken();
|
||||
return try p.addNode(.{ .tag = .bool_literal, .main_token = main_token });
|
||||
return try p.addNode(.{ .tag = .bool_true, .main_token = main_token });
|
||||
},
|
||||
.k_false => {
|
||||
_ = p.advanceToken();
|
||||
return try p.addNode(.{ .tag = .bool_false, .main_token = main_token });
|
||||
},
|
||||
.number => {
|
||||
_ = p.advanceToken();
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ fn Printer(comptime Writer: type) type {
|
|||
const inst = self.ir.instructions[index];
|
||||
|
||||
if (decl_scope and inst.tag.isDecl()) {
|
||||
try self.writer.print("%{d}", .{index});
|
||||
try self.writer.print("&[{d}]", .{index});
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -45,8 +45,41 @@ fn Printer(comptime Writer: type) type {
|
|||
.global_variable_decl => try self.printGlobalVariable(indent, index),
|
||||
.struct_decl => try self.printStructDecl(indent, index),
|
||||
.struct_member => try self.printStructMember(indent, index),
|
||||
.integer_literal => {
|
||||
try self.writer.print("int({d})", .{inst.data.integer_literal});
|
||||
},
|
||||
.float_literal => {
|
||||
try self.writer.print("float({d})", .{inst.data.float_literal});
|
||||
},
|
||||
.mul,
|
||||
.div,
|
||||
.mod,
|
||||
.add,
|
||||
.sub,
|
||||
.shift_left,
|
||||
.shift_right,
|
||||
.binary_and,
|
||||
.binary_or,
|
||||
.binary_xor,
|
||||
.circuit_and,
|
||||
.circuit_or,
|
||||
.equal,
|
||||
.not_equal,
|
||||
.less,
|
||||
.less_equal,
|
||||
.greater,
|
||||
.greater_equal,
|
||||
=> {
|
||||
try self.instStart(index);
|
||||
defer self.instEnd() catch unreachable;
|
||||
try self.printInst(indent, inst.data.binary.lhs, true);
|
||||
try self.writer.writeAll(", ");
|
||||
try self.printInst(indent, inst.data.binary.rhs, true);
|
||||
},
|
||||
else => {
|
||||
try self.writer.print("%{d} = {s}{{TODO}},\n", .{ index, @tagName(inst.tag) });
|
||||
try self.instStart(index);
|
||||
defer self.instEnd() catch unreachable;
|
||||
try self.writer.writeAll("TODO");
|
||||
},
|
||||
}
|
||||
},
|
||||
|
|
@ -56,60 +89,90 @@ fn Printer(comptime Writer: type) type {
|
|||
fn printGlobalVariable(self: @This(), indent: u16, index: IR.Inst.Index) anyerror!void {
|
||||
const inst = self.ir.instructions[index];
|
||||
|
||||
try self.instStart(index);
|
||||
defer self.instEnd(indent) catch unreachable;
|
||||
try self.instBlockStart(index);
|
||||
defer self.instBlockEnd(indent) catch unreachable;
|
||||
|
||||
try self.printIndent(indent + 1);
|
||||
try self.writer.writeAll(".type = ");
|
||||
try self.printField(indent + 1, "type");
|
||||
try self.printInst(indent + 2, inst.data.global_variable_decl.type, true);
|
||||
try self.writer.writeAll(",\n");
|
||||
|
||||
try self.printField(indent + 1, "value");
|
||||
try self.printInst(indent + 2, inst.data.global_variable_decl.expr, true);
|
||||
try self.writer.writeAll(",\n");
|
||||
}
|
||||
|
||||
fn printStructDecl(self: @This(), indent: u16, index: IR.Inst.Index) anyerror!void {
|
||||
const inst = self.ir.instructions[index];
|
||||
|
||||
try self.instStart(index);
|
||||
defer self.instEnd(indent) catch unreachable;
|
||||
try self.instBlockStart(index);
|
||||
defer self.instBlockEnd(indent) catch unreachable;
|
||||
|
||||
try self.printIndent(indent + 1);
|
||||
try self.writer.print(".name = \"{s}\",\n", .{self.ir.getStr(inst.data.struct_decl.name)});
|
||||
try self.printField(indent + 1, "name");
|
||||
try self.printStr(inst.data.struct_decl.name);
|
||||
try self.writer.writeAll(",\n");
|
||||
|
||||
try self.printField(indent + 1, "members");
|
||||
try self.listStart();
|
||||
const members = std.mem.sliceTo(self.ir.refs[inst.data.struct_decl.members..], .none);
|
||||
try self.printIndent(indent + 1);
|
||||
try self.writer.writeAll(".members = [\n");
|
||||
for (members) |member| {
|
||||
try self.printIndent(indent + 2);
|
||||
try self.printStructMember(indent + 2, member.toIndex().?);
|
||||
}
|
||||
try self.printIndent(indent + 1);
|
||||
try self.writer.writeAll("],\n");
|
||||
try self.listEnd(indent + 1);
|
||||
}
|
||||
|
||||
fn printStructMember(self: @This(), indent: u16, index: IR.Inst.Index) anyerror!void {
|
||||
const inst = self.ir.instructions[index];
|
||||
|
||||
try self.instStart(index);
|
||||
defer self.instEnd(indent) catch unreachable;
|
||||
try self.instBlockStart(index);
|
||||
defer self.instBlockEnd(indent) catch unreachable;
|
||||
|
||||
try self.printIndent(indent + 1);
|
||||
try self.writer.print(".name = \"{s}\",\n", .{self.ir.getStr(inst.data.struct_member.name)});
|
||||
try self.printField(indent + 1, "name");
|
||||
try self.printStr(inst.data.struct_member.name);
|
||||
try self.writer.writeAll(",\n");
|
||||
|
||||
try self.printIndent(indent + 1);
|
||||
try self.writer.writeAll(".type = ");
|
||||
try self.printField(indent + 1, "type");
|
||||
try self.printInst(indent + 2, inst.data.struct_member.type, true);
|
||||
try self.writer.writeAll(",\n");
|
||||
}
|
||||
|
||||
fn instStart(self: @This(), index: IR.Inst.Index) !void {
|
||||
const inst = self.ir.instructions[index];
|
||||
try self.writer.print("%{d} = {s}{{\n", .{ index, @tagName(inst.tag) });
|
||||
try self.writer.print("[{d}] = {s}(", .{ index, @tagName(inst.tag) });
|
||||
}
|
||||
|
||||
fn instEnd(self: @This(), indent: u16) !void {
|
||||
fn instEnd(self: @This()) !void {
|
||||
try self.writer.writeAll(")");
|
||||
}
|
||||
|
||||
fn instBlockStart(self: @This(), index: IR.Inst.Index) !void {
|
||||
const inst = self.ir.instructions[index];
|
||||
try self.writer.print("[{d}] = {s}{{\n", .{ index, @tagName(inst.tag) });
|
||||
}
|
||||
|
||||
fn instBlockEnd(self: @This(), indent: u16) !void {
|
||||
try self.printIndent(indent);
|
||||
try self.writer.writeAll("},\n");
|
||||
}
|
||||
|
||||
fn listStart(self: @This()) !void {
|
||||
try self.writer.writeAll("{\n");
|
||||
}
|
||||
|
||||
fn listEnd(self: @This(), indent: u16) !void {
|
||||
try self.printIndent(indent);
|
||||
try self.writer.writeAll("},\n");
|
||||
}
|
||||
|
||||
fn printField(self: @This(), indent: u16, name: []const u8) !void {
|
||||
try self.printIndent(indent);
|
||||
try self.writer.print("{s} -> ", .{name});
|
||||
}
|
||||
|
||||
fn printStr(self: @This(), name_index: u32) !void {
|
||||
try self.writer.print("\"{s}\"", .{self.ir.getStr(name_index)});
|
||||
}
|
||||
|
||||
fn printIndent(self: @This(), indent: u16) !void {
|
||||
try self.writer.writeByteNTimes(' ', indent * indention_size);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue