diff --git a/src/ast.zig b/src/ast.zig index cb166d1..7a5c4cd 100644 --- a/src/ast.zig +++ b/src/ast.zig @@ -128,7 +128,7 @@ pub const StructExpr = struct { }; pub const GetExpr = struct { - struc: *Expr, + target: *Expr, name: Token, }; diff --git a/src/ast_printer.zig b/src/ast_printer.zig index 29e714d..ac42790 100644 --- a/src/ast_printer.zig +++ b/src/ast_printer.zig @@ -272,7 +272,7 @@ pub fn printExpr(expr: *const Expr) void { .Get => |get| { warn("("); - printExpr(get.struc); + printExpr(get.target); warn(".{})", get.name.lexeme); }, @@ -370,7 +370,7 @@ fn prettyType(typ: SymbolUnderlyingType) []const u8 { } pub fn printScope(scope: *Scope, ident: usize) void { - print(ident, "scope at addr {}\n", scope); + print(ident, "scope at addr {}\n", &scope); var it = scope.env.iterator(); while (it.next()) |kv| { @@ -405,7 +405,7 @@ pub fn printContext(ctx: CompilationContext) void { // go through scopes std.debug.warn("scope info:\n"); - printScope(fn_sym.scope, 0); + printScope(fn_sym.scope, 1); }, .Struct => |typemap| { diff --git a/src/codegen.zig b/src/codegen.zig index 012373c..d481a7f 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -121,10 +121,9 @@ pub const Codegen = struct { }, .Get => |get| { - // TODO rename get.struc to get.target - var struc = get.struc.*; + var target = get.target.*; - switch (struc) { + switch (target) { .Variable => |vari| { // first, we must check if the target is a type // and emit accordingly @@ -158,7 +157,7 @@ pub const Codegen = struct { }, else => { - std.debug.warn("Invalid get target: {}\n", ast.ExprType(struc)); + std.debug.warn("Invalid get target: {}\n", ast.ExprType(target)); return CompileError.EmitError; }, } diff --git a/src/parsers.zig b/src/parsers.zig index 04f9bf1..2e278cc 100644 --- a/src/parsers.zig +++ b/src/parsers.zig @@ -320,11 +320,11 @@ pub const Parser = struct { return expr; } - fn mkGet(self: *@This(), struc: *Expr, name: Token) !*Expr { + fn mkGet(self: *@This(), target: *Expr, name: Token) !*Expr { var expr = try self.allocator.create(Expr); expr.* = Expr{ .Get = ast.GetExpr{ - .struc = struc, + .target = target, .name = name, }, }; @@ -906,11 +906,11 @@ pub const Parser = struct { return self.doError("can not initialize struct field"); }, - .Equal => return try self.mkSet(get.struc, get.name, value), + .Equal => return try self.mkSet(get.target, get.name, value), .PlusEqual, .MinusEqual, .StarEqual, .SlashEqual => { return try self.mkSet( - get.struc, + get.target, get.name, try self.mkBinary(expr, binop.?, value), ); diff --git a/src/types.zig b/src/types.zig index 1d5cae0..dfe384b 100644 --- a/src/types.zig +++ b/src/types.zig @@ -159,9 +159,43 @@ pub const TypeSolver = struct { return func_sym.return_type; }, - // TODO variable resolution + // TODO analysis for .Variable - // TODO Get (for structs and enums) + .Get => |get| { + var target = get.target.*; + if (ast.ExprType(target) != .Variable) { + std.debug.warn("Expected Variable as get target, got {}\n", ast.ExprType(target)); + return CompileError.TypeError; + } + + const lexeme = target.Variable.lexeme; + var global_typ_opt = self.resolveGlobalType(ctx, lexeme); + + // TODO: + // - name resolution for when global_typ is null + analysis of + // the name's type + // - analysis for structs + + if (global_typ_opt == null) @panic("TODO name resolution"); + + var global_typ = global_typ_opt.?; + + switch (global_typ) { + + // TODO we need to fetch the given + // struct field (on get.name) type and return it + .Struct => @panic("TODO analysis of struct"), + .Enum => return global_typ, + else => { + std.debug.warn( + "Expected Struct/Enum as get target, got {}\n", + comp.SymbolUnderlyingTypeEnum(global_typ), + ); + + return CompileError.TypeError; + }, + } + }, else => { std.debug.warn("TODO resolve expr {}\n", ast.ExprType(expr.*));