add basic resolution of enums to llvm types
- pass ctx to codegen - add better type solver error for unhandled nodes
This commit is contained in:
parent
6b3d54aed7
commit
0b0a8896bb
4 changed files with 57 additions and 42 deletions
|
@ -1,16 +1,13 @@
|
|||
// import std;
|
||||
|
||||
struct B {
|
||||
field i32
|
||||
enum B {
|
||||
a
|
||||
b
|
||||
c
|
||||
}
|
||||
|
||||
struct Awoo {
|
||||
b B
|
||||
other_field i32
|
||||
}
|
||||
|
||||
fn test_function() Awoo {
|
||||
return 1;
|
||||
fn test_function() B {
|
||||
return B.a;
|
||||
}
|
||||
|
||||
fn multwo(num: i32, double_flag: bool) i32 {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
const std = @import("std");
|
||||
const ast = @import("ast.zig");
|
||||
const llvm = @import("llvm.zig");
|
||||
const comp = @import("comp_ctx.zig");
|
||||
const types = @import("types.zig");
|
||||
|
||||
fn sliceify(non_slice: ?[*]const u8) []const u8 {
|
||||
if (non_slice == null) return "";
|
||||
|
@ -13,19 +15,6 @@ pub const CompileError = error{
|
|||
TypeError,
|
||||
};
|
||||
|
||||
/// Does not account for custom types e.g structs, better type resolution
|
||||
/// should be found
|
||||
fn basicTypeToLLVM(ret_type: []const u8) !llvm.LLVMTypeRef {
|
||||
if (std.mem.eql(u8, ret_type, "i32")) {
|
||||
return llvm.LLVMInt32Type();
|
||||
} else if (std.mem.eql(u8, ret_type, "bool")) {
|
||||
return llvm.LLVMInt1Type();
|
||||
} else {
|
||||
std.debug.warn("Invalid return type: {}\n", ret_type);
|
||||
return CompileError.TypeError;
|
||||
}
|
||||
}
|
||||
|
||||
fn mkLLVMBool(val: bool) llvm.LLVMValueRef {
|
||||
if (val) {
|
||||
return llvm.LLVMConstInt(llvm.LLVMInt1Type(), 1, 1);
|
||||
|
@ -36,9 +25,40 @@ fn mkLLVMBool(val: bool) llvm.LLVMValueRef {
|
|||
|
||||
pub const Codegen = struct {
|
||||
allocator: *std.mem.Allocator,
|
||||
ctx: *comp.CompilationContext,
|
||||
|
||||
pub fn init(allocator: *std.mem.Allocator) Codegen {
|
||||
return Codegen{ .allocator = allocator };
|
||||
pub fn init(allocator: *std.mem.Allocator, ctx: *comp.CompilationContext) Codegen {
|
||||
return Codegen{ .allocator = allocator, .ctx = ctx };
|
||||
}
|
||||
|
||||
fn typeToLLVM(self: *@This(), typ: comp.SymbolUnderlyingType) !llvm.LLVMTypeRef {
|
||||
return switch (typ) {
|
||||
.Integer32 => llvm.LLVMInt32Type(),
|
||||
.Integer64 => llvm.LLVMInt64Type(),
|
||||
.Bool => llvm.LLVMInt1Type(),
|
||||
|
||||
.OpaqueType => |val| {
|
||||
std.debug.warn("Invalid return type: {}\n", val);
|
||||
return CompileError.TypeError;
|
||||
},
|
||||
|
||||
.Struct, .Enum => |lex| blk: {
|
||||
var sym_data = self.ctx.symbol_table.get(lex).?.value;
|
||||
break :blk switch (sym_data) {
|
||||
.Struct => unreachable,
|
||||
.Enum => llvm.LLVMInt32Type(),
|
||||
else => {
|
||||
std.debug.warn("Function {} is not a type\n", lex);
|
||||
return CompileError.TypeError;
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
else => {
|
||||
std.debug.warn("TODO handle {}\n", typ);
|
||||
return CompileError.TypeError;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
fn emitExpr(self: *Codegen, builder: var, expr: *const ast.Expr) anyerror!llvm.LLVMValueRef {
|
||||
|
@ -191,16 +211,7 @@ pub const Codegen = struct {
|
|||
}
|
||||
}
|
||||
|
||||
fn emitBlock(self: *Codegen, builder: var, block: ast.Block) !llvm.LLVMValueRef {
|
||||
var entry = llvm.LLVMAppendBasicBlock(func, entry_lbl_cstr.ptr);
|
||||
|
||||
var builder = llvm.LLVMCreateBuilder();
|
||||
llvm.LLVMPositionBuilderAtEnd(builder, entry);
|
||||
for (block.toSlice()) |stmt| {
|
||||
try self.emitStmt(builder, &stmt);
|
||||
}
|
||||
}
|
||||
|
||||
/// Emit LLVM ir for the given node.
|
||||
fn genNode(
|
||||
self: *Codegen,
|
||||
mod: llvm.LLVMModuleRef,
|
||||
|
@ -210,21 +221,25 @@ pub const Codegen = struct {
|
|||
.Root => @panic("Should not have gotten Root"),
|
||||
.FnDecl => |decl| {
|
||||
const name = decl.func_name.lexeme;
|
||||
|
||||
var fn_sym_search = self.ctx.symbol_table.get(name).?.value;
|
||||
std.debug.assert(comp.SymbolType(fn_sym_search) == .Function);
|
||||
var fn_sym = fn_sym_search.Function;
|
||||
|
||||
const name_cstr = try std.cstr.addNullByte(self.allocator, name);
|
||||
errdefer self.allocator.free(name_cstr);
|
||||
|
||||
const fn_ret_type = decl.return_type.lexeme;
|
||||
|
||||
var param_types = llvm.LLVMTypeList.init(self.allocator);
|
||||
errdefer param_types.deinit();
|
||||
|
||||
for (decl.params.toSlice()) |param| {
|
||||
// TODO better type resolution
|
||||
try param_types.append(try basicTypeToLLVM(param.typ.lexeme));
|
||||
try param_types.append(try self.typeToLLVM(fn_sym.parameters.get(
|
||||
param.name.lexeme,
|
||||
).?.value));
|
||||
}
|
||||
|
||||
var llvm_ret_type = llvm.LLVMFunctionType(
|
||||
try basicTypeToLLVM(fn_ret_type),
|
||||
try self.typeToLLVM(fn_sym.return_type),
|
||||
param_types.toSlice().ptr,
|
||||
@intCast(c_uint, param_types.len),
|
||||
0,
|
||||
|
@ -257,7 +272,7 @@ pub const Codegen = struct {
|
|||
|
||||
else => {
|
||||
std.debug.warn("TODO handle node type {}\n", @tagName(node.*));
|
||||
unreachable;
|
||||
return;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ pub fn run(allocator: *std.mem.Allocator, slice: []const u8) !Result {
|
|||
std.debug.warn("symbol table\n");
|
||||
printer.printContext(ctx);
|
||||
|
||||
var cgen = codegen.Codegen.init(allocator);
|
||||
var cgen = codegen.Codegen.init(allocator, &ctx);
|
||||
try cgen.gen(root);
|
||||
|
||||
return Result.Ok;
|
||||
|
|
|
@ -149,7 +149,10 @@ pub const TypeSolver = struct {
|
|||
// TODO infer type of expr in const
|
||||
//.ConstDecl => {},
|
||||
|
||||
else => unreachable,
|
||||
else => {
|
||||
std.debug.warn("TODO type analysis of {}\n", node.*);
|
||||
return CompileError.TypeError;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue