Compare commits

...

3 Commits

6 changed files with 58 additions and 51 deletions

View File

@ -1,36 +1,13 @@
const (
test_var = 1 + 3
)
fn f() i32 {
// var a = 3;
// return a;
return 2;
var a = 3;
a = 2;
return a + 23;
}
fn f2() i32 {
return f() + 2;
}
//fn f2() bool {
// return 1 > 10;
//}
enum B {
a
b
c
}
enum C {
blah
bluh
}
fn test_function() B {
return B.b;
}
fn func_refer_param(b: i32) i32 {
return b * 231 + b;
}
@ -52,10 +29,6 @@ fn add(a: i32, b: i32) i32 {
return a + b;
}
fn and_fn() bool {
return true and false;
}
// type is void by default
//fn main() {
// print("piss\n");

View File

@ -280,7 +280,7 @@ pub const TypeSolver = struct {
.Variable => |vari| {
self.setErrToken(vari);
var metadata = try ctx.resolveVarType(vari.lexeme, true);
try ctx.insertMetadata(expr, metadata.?);
try ctx.insertMetadata(vari.lexeme, metadata.?);
return metadata.?.typ;
},
@ -339,10 +339,17 @@ pub const TypeSolver = struct {
}
},
else => {
std.debug.warn("TODO resolve expr {}\n", ast.ExprType(expr.*));
unreachable;
.Assign => |assign| {
var var_type = ctx.current_scope.?.env.get(
assign.name.lexeme,
).?.value;
var value_type = try self.resolveExprType(ctx, assign.value);
try self.expectSymUnTypeEqual(var_type, value_type);
return var_type;
},
.Set => @panic("TODO analysis of Set exprs"),
}
}

View File

@ -187,7 +187,19 @@ pub const VarDeclStmt = struct {
llvm_alloca: ?llvm.LLVMValueRef = null,
};
pub const Stmt = union(enum) {
pub const StmtType = enum {
Expr,
Println,
VarDecl,
If,
Loop,
For,
Return,
};
pub const Stmt = union(StmtType) {
Expr: *Expr,
Println: *Expr,

View File

@ -353,7 +353,7 @@ fn prettyType(typ: SymbolUnderlyingType) []const u8 {
}
pub fn printScope(scope: *Scope, ident: usize) void {
print(ident, "scope '{}' at addr {}\n", scope.id, &scope);
print(ident, "scope '{}' at addr {}\n", scope.id, @ptrToInt(scope));
var it = scope.env.iterator();
while (it.next()) |kv| {

View File

@ -220,6 +220,8 @@ pub const Codegen = struct {
// we will also need to repeat the step for the type resolver
//var typ = self.findCurrent(assign.name);
@panic("TODO finish Assign emitting");
var assign_expr = try self.emitExpr(builder, assign.value);
// TODO rm null
@ -227,10 +229,10 @@ pub const Codegen = struct {
},
.Variable => |vari| {
var kv_opt = self.ctx.metadata_map.get(expr);
var kv_opt = self.ctx.current_scope.?.meta_map.get(vari.lexeme);
if (kv_opt == null) {
std.debug.warn("variable {} not fully analyzed\n", vari);
std.debug.warn("variable {} not fully analyzed\n", vari.lexeme);
return CompileError.EmitError;
}
@ -238,6 +240,7 @@ pub const Codegen = struct {
// is coming from the scope or from the function
var metadata = kv_opt.?.value;
std.debug.warn("!! LOAD FROM VAR META {}\n", @ptrToInt(metadata));
var buf = try self.allocator.alloc(u8, 512);
errdefer self.allocator.free(buf);
@ -247,8 +250,6 @@ pub const Codegen = struct {
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;
@ -271,6 +272,8 @@ pub const Codegen = struct {
}
fn emitStmt(self: *Codegen, builder: var, stmt: *ast.Stmt) anyerror!void {
std.debug.warn("cgen: emitting stmt {}\n", ast.StmtType(stmt.*));
switch (stmt.*) {
.Expr => |expr| _ = try self.emitExpr(builder, expr),
@ -369,7 +372,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, false)).?;
var var_metadata = self.ctx.current_scope.?.meta_map.get(name).?.value;
var name_cstr = try std.cstr.addNullByte(self.allocator, name);
errdefer self.allocator.free(name_cstr);
@ -472,13 +475,15 @@ pub const Codegen = struct {
}
self.ctx.setScope(fn_sym.scope);
defer self.ctx.dumpScope();
// TODO check if stmt is return and if we already
// returned before
var body_slice = decl.body.toSlice();
for (body_slice) |_, idx| {
try self.emitStmt(builder, &body_slice[idx]);
}
self.ctx.dumpScope();
std.debug.warn("cgen: generated function '{}'\n", name);
},

View File

@ -39,6 +39,7 @@ pub const ScopeList = std.ArrayList(*Scope);
pub const Scope = struct {
parent: ?*Scope,
env: UnderlyingTypeMap,
meta_map: VariableMetadataMap,
/// List of children in the scope.
children: ScopeList,
@ -56,7 +57,9 @@ pub const Scope = struct {
.children = ScopeList.init(allocator),
.allocator = allocator,
.id = id,
.meta_map = VariableMetadataMap.init(allocator),
};
return scope;
}
@ -100,6 +103,9 @@ pub const FunctionSymbol = struct {
parameter_list: TypeList,
scope: *Scope,
// only contains metadata for parameters (i really need to simplify this)
meta_map: VariableMetadataMap,
};
// structs are hashmaps pointing to SymbolUnderlyingType
@ -170,7 +176,7 @@ pub const VariableMetadata = struct {
};
// TODO rm const?
pub const VariableMetadataMap = std.AutoHashMap(*const ast.Expr, *VariableMetadata);
pub const VariableMetadataMap = std.StringHashMap(*VariableMetadata);
/// Represents the context for a full compiler run.
/// This is used to manage the symbol table for the compilation unit, etc.
@ -181,19 +187,15 @@ pub const CompilationContext = struct {
cur_function: ?*FunctionSymbol = null,
current_scope: ?*Scope = null,
metadata_map: VariableMetadataMap,
pub fn init(allocator: *std.mem.Allocator) CompilationContext {
return CompilationContext{
.allocator = allocator,
.symbol_table = SymbolTable.init(allocator),
.metadata_map = VariableMetadataMap.init(allocator),
};
}
pub fn deinit(self: *@This()) void {
self.symbol_table.deinit();
self.metadata_map.deinit();
}
/// Create a new scope out of the current one and set it as the current.
@ -309,6 +311,8 @@ pub const CompilationContext = struct {
.parameters = param_map,
.parameter_list = param_types,
.scope = scope,
.meta_map = VariableMetadataMap.init(self.allocator),
},
};
@ -417,9 +421,15 @@ pub const CompilationContext = struct {
return CompilationError.UnknownName;
}
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);
pub fn insertMetadata(self: *@This(), name: []const u8, metadata: *VariableMetadata) !void {
if (self.current_scope) |scope| {
_ = try scope.meta_map.put(name, metadata);
return;
}
if (self.cur_function) |func| {
_ = try func.meta_map.put(name, metadata);
return;
}
}
};