Compare commits

..

No commits in common. "a95d0e7fd8d976821a5d18bcece0a4408a07f875" and "ea4dd5fde48a886bbe78b885f13d61a4eaf7bd91" have entirely different histories.

3 changed files with 34 additions and 75 deletions

View file

@ -279,9 +279,9 @@ pub const TypeSolver = struct {
.Variable => |vari| { .Variable => |vari| {
self.setErrToken(vari); self.setErrToken(vari);
var metadata = try ctx.resolveVarType(vari.lexeme, true); var metadata = try ctx.resolveVarType(vari.lexeme);
try ctx.insertMetadata(expr, metadata.?); try ctx.insertMetadata(expr, metadata);
return metadata.?.typ; return metadata.typ;
}, },
.Get => |get| { .Get => |get| {

View file

@ -100,7 +100,10 @@ pub const Codegen = struct {
builder: var, builder: var,
expr: *const ast.Expr, expr: *const ast.Expr,
) anyerror!llvm.LLVMValueRef { ) anyerror!llvm.LLVMValueRef {
// TODO Assign modifies the symbol table // 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
return switch (expr.*) { return switch (expr.*) {
// TODO handle all literals, construct llvm values for them // TODO handle all literals, construct llvm values for them
@ -239,27 +242,22 @@ pub const Codegen = struct {
var metadata = kv_opt.?.value; var metadata = kv_opt.?.value;
return switch (metadata.using) {
.Function => blk: {
var param = metadata.from_function.?.parameters.get(vari.lexeme).?.value;
var buf = try self.allocator.alloc(u8, 512); var buf = try self.allocator.alloc(u8, 512);
errdefer self.allocator.free(buf); errdefer self.allocator.free(buf);
var load_str = try std.fmt.bufPrint(buf, "{}_loaded", vari.lexeme); var load_str = try std.fmt.bufPrint(buf, "{}_loaded", param.name);
var load_cstr = try std.cstr.addNullByte(self.allocator, load_str); var load_cstr = try std.cstr.addNullByte(self.allocator, load_str);
errdefer self.allocator.free(load_cstr); 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;
break :blk llvm.LLVMBuildLoad(builder, param.llvm_alloca.?, load_cstr.ptr); break :blk llvm.LLVMBuildLoad(builder, param.llvm_alloca.?, load_cstr.ptr);
}, },
.Scope => blk: { .Scope => @panic("TODO local variables"),
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);
},
}; };
}, },
@ -369,7 +367,7 @@ pub const Codegen = struct {
// analyze pass and the current scope contains the variable's // analyze pass and the current scope contains the variable's
// type(hopefully), so we resolve it // type(hopefully), so we resolve it
const name = vardecl.name.lexeme; const name = vardecl.name.lexeme;
var var_metadata = (try self.ctx.resolveVarType(name, false)).?; var var_metadata = try self.ctx.resolveVarType(name);
var name_cstr = try std.cstr.addNullByte(self.allocator, name); var name_cstr = try std.cstr.addNullByte(self.allocator, name);
errdefer self.allocator.free(name_cstr); errdefer self.allocator.free(name_cstr);
@ -384,10 +382,6 @@ pub const Codegen = struct {
stmt.*.VarDecl.llvm_alloca = variable; 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); var llvm_expr = try self.emitExpr(builder, vardecl.value);
_ = llvm.LLVMBuildStore(builder, llvm_expr, variable); _ = llvm.LLVMBuildStore(builder, llvm_expr, variable);
}, },

View file

@ -146,26 +146,12 @@ pub const VariableMetadata = struct {
from_scope: ?*Scope = null, from_scope: ?*Scope = null,
from_function: ?*FunctionSymbol = null, from_function: ?*FunctionSymbol = null,
pub fn withScope( pub fn withScope(scope: *Scope, typ: SymbolUnderlyingType) VariableMetadata {
allocator: *std.mem.Allocator, return VariableMetadata{ .typ = typ, .from_scope = scope, .using = .Scope };
scope: *Scope,
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;
} }
pub fn withParam( pub fn withParam(func: *FunctionSymbol, typ: SymbolUnderlyingType) VariableMetadata {
allocator: *std.mem.Allocator, return VariableMetadata{ .typ = typ, .from_function = func, .using = .Function };
func: *FunctionSymbol,
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;
} }
}; };
@ -364,62 +350,41 @@ pub const CompilationContext = struct {
self: *@This(), self: *@This(),
scope_opt: ?*Scope, scope_opt: ?*Scope,
name: []const u8, name: []const u8,
create_meta: bool, ) ?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| {
if (create_meta) { return VariableMetadata.withScope(scope, kv.value);
return try VariableMetadata.withScope(
self.allocator,
scope,
kv.value,
);
} else { } else {
return null; return self.resolveVarTypeInScope(scope.parent, name);
}
} else {
return self.resolveVarTypeInScope(scope.parent, name, create_meta);
} }
} }
/// 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( pub fn resolveVarType(self: *@This(), name: []const u8) !VariableMetadata {
self: *@This(), var var_type: ?VariableMetadata = null;
name: []const u8,
create_meta: bool,
) !?*VariableMetadata {
var var_type: ?*VariableMetadata = null;
if (self.current_scope) |scope| { if (self.current_scope) |scope| {
var_type = try self.resolveVarTypeInScope(scope, name, create_meta); var_type = 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| { if (kv_opt) |kv| return VariableMetadata.withParam(cur_function, kv.value.typ);
if (create_meta) {
return try VariableMetadata.withParam(
self.allocator,
cur_function,
kv.value.typ,
);
} else {
return null;
}
}
} }
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);
std.debug.warn("COMP CTX inserting metadata, expr={}, meta={}\n", @ptrToInt(ptr), @ptrToInt(metadata)); _ = try self.metadata_map.put(ptr, meta);
_ = try self.metadata_map.put(ptr, metadata);
} }
}; };