diff --git a/src/analysis.zig b/src/analysis.zig index acb9b6d..34b9ef9 100644 --- a/src/analysis.zig +++ b/src/analysis.zig @@ -279,9 +279,9 @@ pub const TypeSolver = struct { .Variable => |vari| { self.setErrToken(vari); - var metadata = try ctx.resolveVarType(vari.lexeme); - try ctx.insertMetadata(expr, metadata); - return metadata.typ; + var metadata = try ctx.resolveVarType(vari.lexeme, true); + try ctx.insertMetadata(expr, metadata.?); + return metadata.?.typ; }, .Get => |get| { diff --git a/src/codegen.zig b/src/codegen.zig index ce6e787..9f2c12b 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -100,10 +100,7 @@ pub const Codegen = struct { builder: var, expr: *const ast.Expr, ) anyerror!llvm.LLVMValueRef { - // TODO if expr is Variable, we should do a variable lookup - // in a symbol table, going up in scope, etc. - - // TODO Assign modify symbol table + // TODO Assign modifies the symbol table return switch (expr.*) { // TODO handle all literals, construct llvm values for them @@ -242,22 +239,27 @@ pub const Codegen = struct { var metadata = kv_opt.?.value; + var buf = try self.allocator.alloc(u8, 512); + errdefer self.allocator.free(buf); + + var load_str = try std.fmt.bufPrint(buf, "{}_loaded", vari.lexeme); + + var load_cstr = try std.cstr.addNullByte(self.allocator, load_str); + errdefer self.allocator.free(load_cstr); + + std.debug.warn("!! LOAD FROM VAR META {}\n", @ptrToInt(metadata)); + return switch (metadata.using) { .Function => blk: { var param = metadata.from_function.?.parameters.get(vari.lexeme).?.value; - - var buf = try self.allocator.alloc(u8, 512); - errdefer self.allocator.free(buf); - - var load_str = try std.fmt.bufPrint(buf, "{}_loaded", param.name); - - var load_cstr = try std.cstr.addNullByte(self.allocator, load_str); - errdefer self.allocator.free(load_cstr); - break :blk llvm.LLVMBuildLoad(builder, param.llvm_alloca.?, load_cstr.ptr); }, - .Scope => @panic("TODO local variables"), + .Scope => blk: { + var llvm_alloca = metadata.llvm_alloca.?; + //var var_typ = metadata.from_scope.?.env.get(vari.lexeme).?.value; + break :blk llvm.LLVMBuildLoad(builder, llvm_alloca, load_cstr.ptr); + }, }; }, @@ -367,7 +369,7 @@ pub const Codegen = struct { // analyze pass and the current scope contains the variable's // type(hopefully), so we resolve it const name = vardecl.name.lexeme; - var var_metadata = try self.ctx.resolveVarType(name); + var var_metadata = (try self.ctx.resolveVarType(name, false)).?; var name_cstr = try std.cstr.addNullByte(self.allocator, name); errdefer self.allocator.free(name_cstr); @@ -381,8 +383,11 @@ pub const Codegen = struct { ); stmt.*.VarDecl.llvm_alloca = variable; + var_metadata.*.llvm_alloca = variable; + std.debug.warn("!! DECL VAR {} => {}\n", @ptrToInt(var_metadata), variable); + var llvm_expr = try self.emitExpr(builder, vardecl.value); _ = llvm.LLVMBuildStore(builder, llvm_expr, variable); }, diff --git a/src/comp_ctx.zig b/src/comp_ctx.zig index f691c7d..75fbb97 100644 --- a/src/comp_ctx.zig +++ b/src/comp_ctx.zig @@ -152,6 +152,7 @@ pub const VariableMetadata = struct { typ: SymbolUnderlyingType, ) !*VariableMetadata { var meta = try allocator.create(VariableMetadata); + std.debug.warn("VARMETA create from scope={}, meta={}\n", @ptrToInt(scope), @ptrToInt(meta)); meta.* = VariableMetadata{ .typ = typ, .from_scope = scope, .using = .Scope }; return meta; } @@ -162,6 +163,7 @@ pub const VariableMetadata = struct { typ: SymbolUnderlyingType, ) !*VariableMetadata { var meta = try allocator.create(VariableMetadata); + std.debug.warn("VARMETA create from fndecl={}, meta={}\n", @ptrToInt(func), @ptrToInt(meta)); meta.* = VariableMetadata{ .typ = typ, .from_function = func, .using = .Function }; return meta; } @@ -362,35 +364,53 @@ pub const CompilationContext = struct { self: *@This(), scope_opt: ?*Scope, name: []const u8, + create_meta: bool, ) error{OutOfMemory}!?*VariableMetadata { if (scope_opt == null) return null; var scope = scope_opt.?; var kv_opt = scope.env.get(name); if (kv_opt) |kv| { - return try VariableMetadata.withScope(self.allocator, scope, kv.value); + if (create_meta) { + return try VariableMetadata.withScope( + self.allocator, + scope, + kv.value, + ); + } else { + return null; + } } else { - return self.resolveVarTypeInScope(scope.parent, name); + return self.resolveVarTypeInScope(scope.parent, name, create_meta); } } /// 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, + create_meta: bool, + ) !?*VariableMetadata { var var_type: ?*VariableMetadata = null; if (self.current_scope) |scope| { - var_type = try self.resolveVarTypeInScope(scope, name); + var_type = try self.resolveVarTypeInScope(scope, name, create_meta); if (var_type) |typ| return typ; } if (self.cur_function) |cur_function| { var kv_opt = cur_function.parameters.get(name); - if (kv_opt) |kv| - return try VariableMetadata.withParam( - self.allocator, - cur_function, - kv.value.typ, - ); + if (kv_opt) |kv| { + if (create_meta) { + return try VariableMetadata.withParam( + self.allocator, + cur_function, + kv.value.typ, + ); + } else { + return null; + } + } } std.debug.warn("Unknown name {}\n", name); @@ -399,6 +419,7 @@ pub const CompilationContext = struct { pub fn insertMetadata(self: *@This(), ptr: *const ast.Expr, metadata: *VariableMetadata) !void { std.debug.assert(ast.ExprType(ptr.*) == .Variable); + std.debug.warn("COMP CTX inserting metadata, expr={}, meta={}\n", @ptrToInt(ptr), @ptrToInt(metadata)); _ = try self.metadata_map.put(ptr, metadata); } };