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 {
struc: *Expr,
target: *Expr,
name: Token,
};

View file

@ -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| {

View file

@ -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;
},
}

View file

@ -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),
);

View file

@ -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.*));