add get expr analysis

- rename GetExpr.struc to GetExpr.target
This commit is contained in:
Luna 2019-09-26 18:03:39 -03:00
parent 64e39a6f1e
commit fc9f5d9ce0
5 changed files with 47 additions and 14 deletions

View File

@ -128,7 +128,7 @@ pub const StructExpr = struct {
}; };
pub const GetExpr = struct { pub const GetExpr = struct {
struc: *Expr, target: *Expr,
name: Token, name: Token,
}; };

View File

@ -272,7 +272,7 @@ pub fn printExpr(expr: *const Expr) void {
.Get => |get| { .Get => |get| {
warn("("); warn("(");
printExpr(get.struc); printExpr(get.target);
warn(".{})", get.name.lexeme); warn(".{})", get.name.lexeme);
}, },
@ -370,7 +370,7 @@ fn prettyType(typ: SymbolUnderlyingType) []const u8 {
} }
pub fn printScope(scope: *Scope, ident: usize) void { 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(); var it = scope.env.iterator();
while (it.next()) |kv| { while (it.next()) |kv| {
@ -405,7 +405,7 @@ pub fn printContext(ctx: CompilationContext) void {
// go through scopes // go through scopes
std.debug.warn("scope info:\n"); std.debug.warn("scope info:\n");
printScope(fn_sym.scope, 0); printScope(fn_sym.scope, 1);
}, },
.Struct => |typemap| { .Struct => |typemap| {

View File

@ -121,10 +121,9 @@ pub const Codegen = struct {
}, },
.Get => |get| { .Get => |get| {
// TODO rename get.struc to get.target var target = get.target.*;
var struc = get.struc.*;
switch (struc) { switch (target) {
.Variable => |vari| { .Variable => |vari| {
// first, we must check if the target is a type // first, we must check if the target is a type
// and emit accordingly // and emit accordingly
@ -158,7 +157,7 @@ pub const Codegen = struct {
}, },
else => { else => {
std.debug.warn("Invalid get target: {}\n", ast.ExprType(struc)); std.debug.warn("Invalid get target: {}\n", ast.ExprType(target));
return CompileError.EmitError; return CompileError.EmitError;
}, },
} }

View File

@ -320,11 +320,11 @@ pub const Parser = struct {
return expr; 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); var expr = try self.allocator.create(Expr);
expr.* = Expr{ expr.* = Expr{
.Get = ast.GetExpr{ .Get = ast.GetExpr{
.struc = struc, .target = target,
.name = name, .name = name,
}, },
}; };
@ -906,11 +906,11 @@ pub const Parser = struct {
return self.doError("can not initialize struct field"); 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 => { .PlusEqual, .MinusEqual, .StarEqual, .SlashEqual => {
return try self.mkSet( return try self.mkSet(
get.struc, get.target,
get.name, get.name,
try self.mkBinary(expr, binop.?, value), try self.mkBinary(expr, binop.?, value),
); );

View File

@ -159,9 +159,43 @@ pub const TypeSolver = struct {
return func_sym.return_type; 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 => { else => {
std.debug.warn("TODO resolve expr {}\n", ast.ExprType(expr.*)); std.debug.warn("TODO resolve expr {}\n", ast.ExprType(expr.*));