change symbol table to use pointers to heap allocated symbols

This commit is contained in:
Luna 2019-09-28 13:17:11 -03:00
parent 93811c986d
commit a136a377ce
6 changed files with 53 additions and 38 deletions

View file

@ -31,6 +31,10 @@ fn test_function() B {
return B.b;
}
fn func_refer_param(b: i32) i32 {
return b * 231 + b;
}
fn multwo(num: i32, double_flag: bool) i32 {
if (double_flag) {
var truthy = true;
@ -41,10 +45,6 @@ fn multwo(num: i32, double_flag: bool) i32 {
}
}
fn func_refer_param(b: i32) i32 {
return b * 231 + b;
}
fn add(a: i32, b: i32) i32 {
return a + b;
}

View file

@ -80,7 +80,7 @@ pub const TypeSolver = struct {
return null;
}
return switch (sym.?.value) {
return switch (sym.?.value.*) {
.Struct => SymbolUnderlyingType{ .Struct = val },
.Enum => SymbolUnderlyingType{ .Enum = val },
@ -88,7 +88,7 @@ pub const TypeSolver = struct {
self.doError(
"expected struct or enum for '{}', got {}",
val,
@tagName(comp.SymbolType(sym.?.value)),
@tagName(comp.SymbolType(sym.?.value.*)),
);
break :blk null;
},

View file

@ -24,7 +24,6 @@ pub const NodeType = enum {
pub const ParamDecl = struct {
name: Token,
typ: Token,
};
pub const MethodData = struct {

View file

@ -388,7 +388,7 @@ pub fn printContext(ctx: CompilationContext) void {
var it = ctx.symbol_table.iterator();
while (it.next()) |kv| {
switch (kv.value) {
switch (kv.value.*) {
.Function => |fn_sym| {
std.debug.warn(
"function {} returns {}\n",

View file

@ -54,7 +54,7 @@ pub const Codegen = struct {
.Struct, .Enum => |lex| blk: {
var sym_data = self.ctx.symbol_table.get(lex).?.value;
break :blk switch (sym_data) {
break :blk switch (sym_data.*) {
.Struct => unreachable,
.Enum => llvm.LLVMInt32Type(),
else => {
@ -74,7 +74,7 @@ pub const Codegen = struct {
fn emitForVariableType(self: *@This(), vari: var, get: var, kv: var) !llvm.LLVMValueRef {
var sym = kv.value;
switch (sym) {
switch (sym.*) {
.Enum => |map| {
var val = map.get(get.name.lexeme);
if (val == null) {
@ -89,7 +89,7 @@ pub const Codegen = struct {
.Struct => @panic("TODO handle struct"),
else => {
std.debug.warn("Invalid get target: {}\n", comp.SymbolType(sym));
std.debug.warn("Invalid get target: {}\n", comp.SymbolType(sym.*));
return CompileError.EmitError;
},
}
@ -239,7 +239,8 @@ pub const Codegen = struct {
// var llvm_func = self.llvm_table.get(self.current_function_name.?).?.value;
// break :blk llvm.LLVMGetParam(llvm_func, @intCast(c_uint, param.idx));
break :blk param.llvm_alloca;
std.debug.warn("fn param alloca {} {}\n", param.name, param.llvm_alloca);
break :blk param.llvm_alloca.?;
},
.Scope => @panic("TODO local variables"),
@ -287,12 +288,14 @@ pub const Codegen = struct {
var then_branch = ifstmt.then_branch.toSlice();
for (then_branch) |_, idx| {
// keep emitting until branch has ret
if (!then_rets)
try self.emitStmt(builder, &then_branch[idx]);
var then_stmt = &then_branch[idx];
switch (then_stmt) {
if (!then_rets)
try self.emitStmt(builder, then_stmt);
// TODO break? lol
switch (then_stmt.*) {
.Return => then_rets = true,
else => {},
}
@ -318,10 +321,12 @@ pub const Codegen = struct {
var else_slice = else_block.toSlice();
for (else_slice) |_, idx| {
// keep emitting until branch has ret
if (!else_rets)
try self.emitStmt(builder, &else_slice[idx]);
var else_stmt = &else_slice[idx];
switch (else_stmt) {
if (!else_rets)
try self.emitStmt(builder, else_stmt);
switch (else_stmt.*) {
.Return => else_rets = true,
else => {},
}
@ -361,7 +366,7 @@ pub const Codegen = struct {
name_cstr.ptr,
);
vardecl.llvm_alloca = variable;
stmt.*.VarDecl.llvm_alloca = variable;
var llvm_expr = try self.emitExpr(builder, vardecl.value);
_ = llvm.LLVMBuildStore(builder, llvm_expr, variable);
@ -374,10 +379,10 @@ pub const Codegen = struct {
}
}
fn getFnSymbol(self: *@This(), name: []const u8) comp.FunctionSymbol {
fn getFnSymbol(self: *@This(), name: []const u8) *comp.FunctionSymbol {
var fn_sym_search = self.ctx.symbol_table.get(name).?.value;
std.debug.assert(comp.SymbolType(fn_sym_search) == .Function);
return fn_sym_search.Function;
std.debug.assert(comp.SymbolType(fn_sym_search.*) == .Function);
return &fn_sym_search.Function;
}
/// Emit LLVM ir for the given node.
@ -427,13 +432,16 @@ pub const Codegen = struct {
// to have the ability to mutate parameters, we must allocate them on
// the stack
var params_slice = decl.params.toSlice();
for (params_slice) |param_node, idx| {
var param = fn_sym.parameters.get(param_node.name.lexeme).?.value;
const name_cstr = try std.cstr.addNullByte(self.allocator, param_node.name.lexeme);
errdefer self.allocator.free(name_cstr);
const param_name_cstr = try std.cstr.addNullByte(self.allocator, param_node.name.lexeme);
errdefer self.allocator.free(param_name_cstr);
var alloca = llvm.LLVMBuildAlloca(builder, try self.typeToLLVM(param.typ), name_cstr.ptr);
var alloca = llvm.LLVMBuildAlloca(builder, try self.typeToLLVM(param.typ), param_name_cstr.ptr);
std.debug.warn("SET PARAM LLVM ALLOCA {} to {}\n", param_node.name.lexeme, alloca);
param.llvm_alloca = alloca;
// TODO store register into stack param

View file

@ -7,7 +7,7 @@ pub const CompilationError = error{
UnknownName,
};
pub const SymbolTable = std.hash_map.StringHashMap(SymbolData);
pub const SymbolTable = std.hash_map.StringHashMap(*SymbolData);
pub const TypeList = std.ArrayList(SymbolUnderlyingType);
pub const SymbolUnderlyingTypeEnum = enum {
@ -81,7 +81,8 @@ pub const Parameter = struct {
idx: usize,
name: []const u8,
typ: SymbolUnderlyingType,
alloca: ?llvm.LLVMValueRef = null,
llvm_alloca: llvm.LLVMValueRef = null,
};
pub const ParameterMap = std.StringHashMap(Parameter);
@ -258,7 +259,9 @@ pub const CompilationContext = struct {
_ = try type_map.put(field.name.lexeme, field_types.at(idx));
}
_ = try self.symbol_table.put(struc.name.lexeme, SymbolData{ .Struct = type_map });
var symbol = try self.allocator.create(SymbolData);
symbol.* = SymbolData{ .Struct = type_map };
_ = try self.symbol_table.put(struc.name.lexeme, symbol);
}
pub fn insertFn(
@ -280,7 +283,8 @@ pub const CompilationContext = struct {
const lex = decl.func_name.lexeme;
_ = try self.symbol_table.put(lex, SymbolData{
var symbol = try self.allocator.create(SymbolData);
symbol.* = SymbolData{
.Function = FunctionSymbol{
.decl = decl,
.return_type = ret_type,
@ -288,7 +292,9 @@ pub const CompilationContext = struct {
.parameter_list = param_types,
.scope = scope,
},
});
};
_ = try self.symbol_table.put(lex, symbol);
var kv = self.symbol_table.get(lex);
self.cur_function = &kv.?.value.Function;
@ -303,20 +309,22 @@ pub const CompilationContext = struct {
_ = try ident_map.put(token.lexeme, @intCast(u32, idx));
}
_ = try self.symbol_table.put(enu.name.lexeme, SymbolData{
.Enum = ident_map,
});
var symbol = try self.allocator.create(SymbolData);
symbol.* = SymbolData{ .Enum = ident_map };
_ = try self.symbol_table.put(enu.name.lexeme, symbol);
}
pub fn insertConst(self: *@This(), constdecl: ast.SingleConst, typ: SymbolUnderlyingType) !void {
_ = try self.symbol_table.put(constdecl.name.lexeme, SymbolData{ .Const = typ });
var symbol = try self.allocator.create(SymbolData);
symbol.* = SymbolData{ .Const = typ };
_ = try self.symbol_table.put(constdecl.name.lexeme, symbol);
}
pub fn fetchGlobalSymbol(
self: *@This(),
identifier: []const u8,
typ: SymbolType,
) !SymbolData {
) !*SymbolData {
var sym_kv = self.symbol_table.get(identifier);
if (sym_kv == null) {
std.debug.warn("Unknown {} '{}'\n", typ, identifier);
@ -324,14 +332,14 @@ pub const CompilationContext = struct {
}
var value = sym_kv.?.value;
var sym_typ = SymbolType(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;
return value;
}
fn resolveVarTypeInScope(