comp_ctx: use more pointers to variable metadata

This commit is contained in:
Luna 2019-09-28 20:52:45 -03:00
parent ea4dd5fde4
commit 182d831408
2 changed files with 30 additions and 15 deletions

View file

@ -381,6 +381,7 @@ pub const Codegen = struct {
); );
stmt.*.VarDecl.llvm_alloca = variable; stmt.*.VarDecl.llvm_alloca = variable;
var_metadata.*.llvm_alloca = variable;
var llvm_expr = try self.emitExpr(builder, vardecl.value); var llvm_expr = try self.emitExpr(builder, vardecl.value);
_ = llvm.LLVMBuildStore(builder, llvm_expr, variable); _ = llvm.LLVMBuildStore(builder, llvm_expr, variable);

View file

@ -146,12 +146,24 @@ pub const VariableMetadata = struct {
from_scope: ?*Scope = null, from_scope: ?*Scope = null,
from_function: ?*FunctionSymbol = null, from_function: ?*FunctionSymbol = null,
pub fn withScope(scope: *Scope, typ: SymbolUnderlyingType) VariableMetadata { pub fn withScope(
return VariableMetadata{ .typ = typ, .from_scope = scope, .using = .Scope }; allocator: *std.mem.Allocator,
scope: *Scope,
typ: SymbolUnderlyingType,
) !*VariableMetadata {
var meta = try allocator.create(VariableMetadata);
meta.* = VariableMetadata{ .typ = typ, .from_scope = scope, .using = .Scope };
return meta;
} }
pub fn withParam(func: *FunctionSymbol, typ: SymbolUnderlyingType) VariableMetadata { pub fn withParam(
return VariableMetadata{ .typ = typ, .from_function = func, .using = .Function }; allocator: *std.mem.Allocator,
func: *FunctionSymbol,
typ: SymbolUnderlyingType,
) !*VariableMetadata {
var meta = try allocator.create(VariableMetadata);
meta.* = VariableMetadata{ .typ = typ, .from_function = func, .using = .Function };
return meta;
} }
}; };
@ -350,41 +362,43 @@ pub const CompilationContext = struct {
self: *@This(), self: *@This(),
scope_opt: ?*Scope, scope_opt: ?*Scope,
name: []const u8, name: []const u8,
) ?VariableMetadata { ) error{OutOfMemory}!?*VariableMetadata {
if (scope_opt == null) return null; if (scope_opt == null) return null;
var scope = scope_opt.?; var scope = scope_opt.?;
var kv_opt = scope.env.get(name); var kv_opt = scope.env.get(name);
if (kv_opt) |kv| { if (kv_opt) |kv| {
return VariableMetadata.withScope(scope, kv.value); return try VariableMetadata.withScope(self.allocator, scope, kv.value);
} else { } else {
return self.resolveVarTypeInScope(scope.parent, name); return self.resolveVarTypeInScope(scope.parent, name);
} }
} }
/// Resolve a given name's type, assuming it is a variable. /// Resolve a given name's type, assuming it is a variable.
pub fn resolveVarType(self: *@This(), name: []const u8) !VariableMetadata { pub fn resolveVarType(self: *@This(), name: []const u8) !*VariableMetadata {
var var_type: ?VariableMetadata = null; var var_type: ?*VariableMetadata = null;
if (self.current_scope) |scope| { if (self.current_scope) |scope| {
var_type = self.resolveVarTypeInScope(scope, name); var_type = try self.resolveVarTypeInScope(scope, name);
if (var_type) |typ| return typ; if (var_type) |typ| return typ;
} }
if (self.cur_function) |cur_function| { if (self.cur_function) |cur_function| {
var kv_opt = cur_function.parameters.get(name); var kv_opt = cur_function.parameters.get(name);
if (kv_opt) |kv| return VariableMetadata.withParam(cur_function, kv.value.typ); if (kv_opt) |kv|
return try VariableMetadata.withParam(
self.allocator,
cur_function,
kv.value.typ,
);
} }
std.debug.warn("Unknown name {}\n", name); std.debug.warn("Unknown name {}\n", name);
return CompilationError.UnknownName; return CompilationError.UnknownName;
} }
pub fn insertMetadata(self: *@This(), ptr: *const ast.Expr, metadata: VariableMetadata) !void { pub fn insertMetadata(self: *@This(), ptr: *const ast.Expr, metadata: *VariableMetadata) !void {
var meta = try self.allocator.create(VariableMetadata);
meta.* = metadata;
std.debug.assert(ast.ExprType(ptr.*) == .Variable); std.debug.assert(ast.ExprType(ptr.*) == .Variable);
_ = try self.metadata_map.put(ptr, meta); _ = try self.metadata_map.put(ptr, metadata);
} }
}; };