Compare commits
No commits in common. "e69451cdd9e8f7fcb176a09c8264dea9f3c4c7cc" and "5036be02e33b3775e771cdf7dacfe9f6e1b95ee5" have entirely different histories.
e69451cdd9
...
5036be02e3
4 changed files with 15 additions and 81 deletions
|
@ -4,12 +4,8 @@ fn f() i32 {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn f2() i32 {
|
|
||||||
return f() + 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
piss = 1 + 3
|
piss = f() + 3
|
||||||
)
|
)
|
||||||
|
|
||||||
enum B {
|
enum B {
|
||||||
|
|
|
@ -23,20 +23,12 @@ fn mkLLVMBool(val: bool) llvm.LLVMValueRef {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const LLVMTable = std.StringHashMap(llvm.LLVMValueRef);
|
|
||||||
pub const LLVMValueList = std.ArrayList(llvm.LLVMValueRef);
|
|
||||||
|
|
||||||
pub const Codegen = struct {
|
pub const Codegen = struct {
|
||||||
allocator: *std.mem.Allocator,
|
allocator: *std.mem.Allocator,
|
||||||
ctx: *comp.CompilationContext,
|
ctx: *comp.CompilationContext,
|
||||||
llvm_table: LLVMTable,
|
|
||||||
|
|
||||||
pub fn init(allocator: *std.mem.Allocator, ctx: *comp.CompilationContext) Codegen {
|
pub fn init(allocator: *std.mem.Allocator, ctx: *comp.CompilationContext) Codegen {
|
||||||
return Codegen{
|
return Codegen{ .allocator = allocator, .ctx = ctx };
|
||||||
.allocator = allocator,
|
|
||||||
.ctx = ctx,
|
|
||||||
.llvm_table = LLVMTable.init(allocator),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn typeToLLVM(self: *@This(), typ: comp.SymbolUnderlyingType) !llvm.LLVMTypeRef {
|
fn typeToLLVM(self: *@This(), typ: comp.SymbolUnderlyingType) !llvm.LLVMTypeRef {
|
||||||
|
@ -69,11 +61,7 @@ pub const Codegen = struct {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emitExpr(
|
fn emitExpr(self: *Codegen, builder: var, expr: *const ast.Expr) anyerror!llvm.LLVMValueRef {
|
||||||
self: *Codegen,
|
|
||||||
builder: var,
|
|
||||||
expr: *const ast.Expr,
|
|
||||||
) anyerror!llvm.LLVMValueRef {
|
|
||||||
// TODO if expr is Variable, we should do a variable lookup
|
// TODO if expr is Variable, we should do a variable lookup
|
||||||
// in a symbol table, going up in scope, etc.
|
// in a symbol table, going up in scope, etc.
|
||||||
|
|
||||||
|
@ -166,36 +154,6 @@ pub const Codegen = struct {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
.Call => |call| {
|
|
||||||
const name = call.callee.*.Variable.lexeme;
|
|
||||||
//var sym = try self.ctx.fetchGlobalSymbol(func_name, .Function);
|
|
||||||
|
|
||||||
var llvm_func = self.llvm_table.get(name);
|
|
||||||
if (llvm_func == null) {
|
|
||||||
std.debug.warn("Function '{}' not found\n", name);
|
|
||||||
return CompileError.EmitError;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO args
|
|
||||||
var args = LLVMValueList.init(self.allocator);
|
|
||||||
errdefer args.deinit();
|
|
||||||
|
|
||||||
for (call.arguments.toSlice()) |arg_expr| {
|
|
||||||
var arg_val = try self.emitExpr(builder, &arg_expr);
|
|
||||||
try args.append(arg_val);
|
|
||||||
}
|
|
||||||
|
|
||||||
var args_slice = args.toSlice();
|
|
||||||
|
|
||||||
return llvm.LLVMBuildCall(
|
|
||||||
builder,
|
|
||||||
llvm_func.?.value,
|
|
||||||
args_slice.ptr,
|
|
||||||
@intCast(c_uint, args_slice.len),
|
|
||||||
c"call",
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
else => {
|
else => {
|
||||||
std.debug.warn("Got unexpected expr {}\n", ast.ExprType(expr.*));
|
std.debug.warn("Got unexpected expr {}\n", ast.ExprType(expr.*));
|
||||||
return CompileError.EmitError;
|
return CompileError.EmitError;
|
||||||
|
@ -331,7 +289,6 @@ pub const Codegen = struct {
|
||||||
);
|
);
|
||||||
|
|
||||||
var func = llvm.LLVMAddFunction(mod, name_cstr.ptr, llvm_ret_type);
|
var func = llvm.LLVMAddFunction(mod, name_cstr.ptr, llvm_ret_type);
|
||||||
_ = try self.llvm_table.put(name, func);
|
|
||||||
|
|
||||||
var buf = try self.allocator.alloc(u8, 512);
|
var buf = try self.allocator.alloc(u8, 512);
|
||||||
var entry_lbl = try std.fmt.bufPrint(buf, "fn_{}_entry", name);
|
var entry_lbl = try std.fmt.bufPrint(buf, "fn_{}_entry", name);
|
||||||
|
@ -371,9 +328,6 @@ pub const Codegen = struct {
|
||||||
|
|
||||||
var global = llvm.LLVMAddGlobal(mod, const_llvm_type, const_name.ptr);
|
var global = llvm.LLVMAddGlobal(mod, const_llvm_type, const_name.ptr);
|
||||||
|
|
||||||
// TODO maybe put builder at main function so we can still
|
|
||||||
// call other functions inside consts?
|
|
||||||
|
|
||||||
var builder = llvm.LLVMCreateBuilder();
|
var builder = llvm.LLVMCreateBuilder();
|
||||||
var expr_llvm_val = try self.emitExpr(builder, constdecl.expr);
|
var expr_llvm_val = try self.emitExpr(builder, constdecl.expr);
|
||||||
|
|
||||||
|
@ -408,10 +362,10 @@ pub const Codegen = struct {
|
||||||
return CompileError.LLVMError;
|
return CompileError.LLVMError;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (llvm.LLVMWriteBitcodeToFile(mod, c"awoo.bc") != 0) {
|
if (llvm.LLVMWriteBitcodeToFile(mod, c"awoo.bc") != 0) {
|
||||||
// std.debug.warn("error writing bitcode to file: {}\n", sliceify(err));
|
std.debug.warn("error writing bitcode to file: {}\n", sliceify(err));
|
||||||
// return CompileError.LLVMError;
|
return CompileError.LLVMError;
|
||||||
//}
|
}
|
||||||
|
|
||||||
std.debug.warn("cgen: verify llvm module\n");
|
std.debug.warn("cgen: verify llvm module\n");
|
||||||
_ = llvm.LLVMVerifyModule(
|
_ = llvm.LLVMVerifyModule(
|
||||||
|
|
|
@ -181,26 +181,4 @@ pub const CompilationContext = struct {
|
||||||
pub fn insertConst(self: *@This(), constdecl: ast.SingleConst, typ: SymbolUnderlyingType) !void {
|
pub fn insertConst(self: *@This(), constdecl: ast.SingleConst, typ: SymbolUnderlyingType) !void {
|
||||||
_ = try self.symbol_table.put(constdecl.name.lexeme, SymbolData{ .Const = typ });
|
_ = try self.symbol_table.put(constdecl.name.lexeme, SymbolData{ .Const = typ });
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fetchGlobalSymbol(
|
|
||||||
self: *@This(),
|
|
||||||
identifier: []const u8,
|
|
||||||
typ: SymbolType,
|
|
||||||
) !SymbolData {
|
|
||||||
var sym_kv = self.symbol_table.get(identifier);
|
|
||||||
if (sym_kv == null) {
|
|
||||||
std.debug.warn("Unknown {} '{}'\n", typ, identifier);
|
|
||||||
return CompilationError.TypeError;
|
|
||||||
}
|
|
||||||
|
|
||||||
var value = sym_kv.?.value;
|
|
||||||
var sym_typ = SymbolType(value);
|
|
||||||
|
|
||||||
if (sym_typ != typ) {
|
|
||||||
std.debug.warn("Expected {}, got {}\n", sym_typ, typ);
|
|
||||||
return CompilationError.TypeError;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sym_kv.?.value;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -150,8 +150,14 @@ pub const TypeSolver = struct {
|
||||||
std.debug.assert(ast.ExprType(call.callee.*) == .Variable);
|
std.debug.assert(ast.ExprType(call.callee.*) == .Variable);
|
||||||
const func_name = call.callee.*.Variable.lexeme;
|
const func_name = call.callee.*.Variable.lexeme;
|
||||||
|
|
||||||
var symbol = try ctx.fetchGlobalSymbol(func_name, .Function);
|
var sym_kv = ctx.symbol_table.get(func_name);
|
||||||
var func_sym = symbol.Function;
|
if (sym_kv == null) {
|
||||||
|
self.doError("Unknown function '{}'\n", func_name);
|
||||||
|
return CompileError.TypeError;
|
||||||
|
}
|
||||||
|
|
||||||
|
std.debug.assert(comp.SymbolType(sym_kv.?.value) == .Function);
|
||||||
|
var func_sym = sym_kv.?.value.Function;
|
||||||
|
|
||||||
// TODO check parameter type mismatches between
|
// TODO check parameter type mismatches between
|
||||||
// call.arguments and func_sym.parameters
|
// call.arguments and func_sym.parameters
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue