diff --git a/examples/hello.ry b/examples/hello.ry index 3b05145..fc0e890 100644 --- a/examples/hello.ry +++ b/examples/hello.ry @@ -1,13 +1,36 @@ +const ( + test_var = 1 + 3 +) + fn f() i32 { - var a = 3; - a = 2; - return a + 23; + // var a = 3; + // return a; + return 2; } 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; } @@ -29,6 +52,10 @@ 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"); diff --git a/src/analysis.zig b/src/analysis.zig index 68792fe..34b9ef9 100644 --- a/src/analysis.zig +++ b/src/analysis.zig @@ -280,7 +280,7 @@ pub const TypeSolver = struct { .Variable => |vari| { self.setErrToken(vari); var metadata = try ctx.resolveVarType(vari.lexeme, true); - try ctx.insertMetadata(vari.lexeme, metadata.?); + try ctx.insertMetadata(expr, metadata.?); return metadata.?.typ; }, @@ -339,17 +339,10 @@ pub const TypeSolver = struct { } }, - .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; + else => { + std.debug.warn("TODO resolve expr {}\n", ast.ExprType(expr.*)); + unreachable; }, - - .Set => @panic("TODO analysis of Set exprs"), } } diff --git a/src/ast.zig b/src/ast.zig index f8136b6..85eb602 100644 --- a/src/ast.zig +++ b/src/ast.zig @@ -187,19 +187,7 @@ pub const VarDeclStmt = struct { llvm_alloca: ?llvm.LLVMValueRef = null, }; -pub const StmtType = enum { - Expr, - Println, - - VarDecl, - If, - Loop, - For, - - Return, -}; - -pub const Stmt = union(StmtType) { +pub const Stmt = union(enum) { Expr: *Expr, Println: *Expr, diff --git a/src/ast_printer.zig b/src/ast_printer.zig index 181a3c2..ad6ec20 100644 --- a/src/ast_printer.zig +++ b/src/ast_printer.zig @@ -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, @ptrToInt(scope)); + print(ident, "scope '{}' at addr {}\n", scope.id, &scope); var it = scope.env.iterator(); while (it.next()) |kv| { diff --git a/src/codegen.zig b/src/codegen.zig index ccf191f..9f2c12b 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -220,8 +220,6 @@ 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 @@ -229,10 +227,10 @@ pub const Codegen = struct { }, .Variable => |vari| { - var kv_opt = self.ctx.current_scope.?.meta_map.get(vari.lexeme); + var kv_opt = self.ctx.metadata_map.get(expr); if (kv_opt == null) { - std.debug.warn("variable {} not fully analyzed\n", vari.lexeme); + std.debug.warn("variable {} not fully analyzed\n", vari); return CompileError.EmitError; } @@ -240,7 +238,6 @@ 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); @@ -250,6 +247,8 @@ 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; @@ -272,8 +271,6 @@ 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), @@ -372,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 = self.ctx.current_scope.?.meta_map.get(name).?.value; + 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); @@ -475,15 +472,13 @@ 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); }, diff --git a/src/comp_ctx.zig b/src/comp_ctx.zig index 0d4246c..75fbb97 100644 --- a/src/comp_ctx.zig +++ b/src/comp_ctx.zig @@ -39,7 +39,6 @@ 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, @@ -57,9 +56,7 @@ pub const Scope = struct { .children = ScopeList.init(allocator), .allocator = allocator, .id = id, - .meta_map = VariableMetadataMap.init(allocator), }; - return scope; } @@ -103,9 +100,6 @@ 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 @@ -176,7 +170,7 @@ pub const VariableMetadata = struct { }; // TODO rm const? -pub const VariableMetadataMap = std.StringHashMap(*VariableMetadata); +pub const VariableMetadataMap = std.AutoHashMap(*const ast.Expr, *VariableMetadata); /// Represents the context for a full compiler run. /// This is used to manage the symbol table for the compilation unit, etc. @@ -187,15 +181,19 @@ 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. @@ -311,8 +309,6 @@ pub const CompilationContext = struct { .parameters = param_map, .parameter_list = param_types, .scope = scope, - - .meta_map = VariableMetadataMap.init(self.allocator), }, }; @@ -421,15 +417,9 @@ pub const CompilationContext = struct { return CompilationError.UnknownName; } - 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; - } + 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); } };