Compare commits
2 Commits
ea4dd5fde4
...
a95d0e7fd8
Author | SHA1 | Date |
---|---|---|
Luna | a95d0e7fd8 | |
Luna | 182d831408 |
|
@ -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);
|
var metadata = try ctx.resolveVarType(vari.lexeme, true);
|
||||||
try ctx.insertMetadata(expr, metadata);
|
try ctx.insertMetadata(expr, metadata.?);
|
||||||
return metadata.typ;
|
return metadata.?.typ;
|
||||||
},
|
},
|
||||||
|
|
||||||
.Get => |get| {
|
.Get => |get| {
|
||||||
|
|
|
@ -100,10 +100,7 @@ pub const Codegen = struct {
|
||||||
builder: var,
|
builder: var,
|
||||||
expr: *const ast.Expr,
|
expr: *const ast.Expr,
|
||||||
) anyerror!llvm.LLVMValueRef {
|
) anyerror!llvm.LLVMValueRef {
|
||||||
// TODO if expr is Variable, we should do a variable lookup
|
// TODO Assign modifies the symbol table
|
||||||
// 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
|
||||||
|
@ -242,22 +239,27 @@ pub const Codegen = struct {
|
||||||
|
|
||||||
var metadata = kv_opt.?.value;
|
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) {
|
return switch (metadata.using) {
|
||||||
.Function => blk: {
|
.Function => blk: {
|
||||||
var param = metadata.from_function.?.parameters.get(vari.lexeme).?.value;
|
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);
|
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
|
// 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);
|
var var_metadata = (try self.ctx.resolveVarType(name, false)).?;
|
||||||
|
|
||||||
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);
|
||||||
|
@ -382,6 +384,10 @@ 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);
|
||||||
},
|
},
|
||||||
|
|
|
@ -146,12 +146,26 @@ 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);
|
||||||
|
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(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);
|
||||||
|
std.debug.warn("VARMETA create from fndecl={}, meta={}\n", @ptrToInt(func), @ptrToInt(meta));
|
||||||
|
meta.* = VariableMetadata{ .typ = typ, .from_function = func, .using = .Function };
|
||||||
|
return meta;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -350,41 +364,62 @@ pub const CompilationContext = struct {
|
||||||
self: *@This(),
|
self: *@This(),
|
||||||
scope_opt: ?*Scope,
|
scope_opt: ?*Scope,
|
||||||
name: []const u8,
|
name: []const u8,
|
||||||
) ?VariableMetadata {
|
create_meta: bool,
|
||||||
|
) 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);
|
if (create_meta) {
|
||||||
|
return try VariableMetadata.withScope(
|
||||||
|
self.allocator,
|
||||||
|
scope,
|
||||||
|
kv.value,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
} else {
|
} 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.
|
/// Resolve a given name's type, assuming it is a variable.
|
||||||
pub fn resolveVarType(self: *@This(), name: []const u8) !VariableMetadata {
|
pub fn resolveVarType(
|
||||||
var var_type: ?VariableMetadata = null;
|
self: *@This(),
|
||||||
|
name: []const u8,
|
||||||
|
create_meta: bool,
|
||||||
|
) !?*VariableMetadata {
|
||||||
|
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, create_meta);
|
||||||
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| {
|
||||||
|
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);
|
||||||
_ = try self.metadata_map.put(ptr, meta);
|
std.debug.warn("COMP CTX inserting metadata, expr={}, meta={}\n", @ptrToInt(ptr), @ptrToInt(metadata));
|
||||||
|
_ = try self.metadata_map.put(ptr, metadata);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue