add lots of TODOs for variables and type analysis of statements
- comp_ctx: replace Function.symbols to Function.env
This commit is contained in:
parent
45275d73db
commit
bf035abadf
4 changed files with 75 additions and 8 deletions
|
@ -1,7 +1,9 @@
|
|||
// import std;
|
||||
const (
|
||||
test_var = 1 + 3
|
||||
)
|
||||
|
||||
fn f() i32 {
|
||||
var a = 2;
|
||||
var a = 3;
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
@ -9,10 +11,6 @@ fn f2() i32 {
|
|||
return f() + 2;
|
||||
}
|
||||
|
||||
const (
|
||||
piss = 1 + 3
|
||||
)
|
||||
|
||||
enum B {
|
||||
a
|
||||
b
|
||||
|
|
|
@ -192,6 +192,22 @@ pub const Codegen = struct {
|
|||
);
|
||||
},
|
||||
|
||||
// TODO finish this
|
||||
.Assign => |assign| {
|
||||
// TODO find assign.name on the "parent context", we should have
|
||||
// a way to do name resolution that is completely relative to
|
||||
// where we currently are, and go up in scope. so that we find
|
||||
// the LLVMValueRef.
|
||||
|
||||
// we will also need to repeat the step for the type resolver
|
||||
|
||||
//var typ = self.findCurrent(assign.name);
|
||||
var assign_expr = try self.emitExpr(builder, assign.value);
|
||||
|
||||
// TODO rm null
|
||||
return llvm.LLVMBuildStore(builder, null, assign_expr);
|
||||
},
|
||||
|
||||
else => {
|
||||
std.debug.warn("Got unexpected expr {}\n", ast.ExprType(expr.*));
|
||||
return CompileError.EmitError;
|
||||
|
@ -286,7 +302,7 @@ pub const Codegen = struct {
|
|||
},
|
||||
|
||||
else => {
|
||||
std.debug.warn("Got unexpected statement {}\n", stmt.*);
|
||||
std.debug.warn("Got unexpected stmt {}\n", stmt.*);
|
||||
return CompileError.EmitError;
|
||||
},
|
||||
}
|
||||
|
|
|
@ -29,6 +29,12 @@ pub const SymbolUnderlyingType = union(SymbolUnderlyingTypeEnum) {
|
|||
Enum: []const u8,
|
||||
};
|
||||
|
||||
pub const Scope = std.StringHashMap(SymbolUnderlyingType);
|
||||
pub const Environment = struct {
|
||||
parent: *Environment,
|
||||
scope: Scope,
|
||||
};
|
||||
|
||||
// functions, for our purposes, other than symbols, have:
|
||||
// - a return type
|
||||
// - TODO parameters
|
||||
|
@ -39,7 +45,7 @@ pub const FunctionSymbol = struct {
|
|||
/// Parameters for a function are also a table instead of an ArrayList
|
||||
/// because we want to resolve identifiers to them.
|
||||
parameters: UnderlyingTypeMap,
|
||||
symbols: SymbolTable,
|
||||
env: *Environment,
|
||||
|
||||
/// Find a given identifier in the function. Can resolve to either a parameter
|
||||
pub fn findSymbol(self: *const @This(), identifier: []const u8) ?SymbolData {
|
||||
|
|
|
@ -170,6 +170,45 @@ pub const TypeSolver = struct {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn nodePass(
|
||||
self: *@This(),
|
||||
ctx: *comp.CompilationContext,
|
||||
stmt: ast.Stmt,
|
||||
) !void {
|
||||
switch (stmt) {
|
||||
|
||||
// There are no side-effects to the type system when the statement
|
||||
// is just an expression or a println. we just resolve it
|
||||
// to ensure we dont have type errors.
|
||||
.Expr => |expr_ptr| try self.resolveExprType(ctx, expr_ptr),
|
||||
.Println => |expr_ptr| try self.resolveExprType(ctx, expr_ptr),
|
||||
|
||||
// VarDecl means we check the type of the expression and
|
||||
// insert it into the context, however we need to know a pointer
|
||||
// to where we are, scope-wise, we don't have that info here,
|
||||
// so it should be implicit into the context.
|
||||
.VarDecl => @panic("TODO vardecl"),
|
||||
|
||||
// If create two scopes for each branch of the if
|
||||
.If => @panic("TODO ifstmt"),
|
||||
|
||||
// Loop (creates 1 scope) asserts that the expression
|
||||
// type is a bool
|
||||
.Loop => @panic("TODO loop"),
|
||||
|
||||
// For (creates 1 scope) receives arrays, which we dont have yet
|
||||
.For => @panic("TODO for"),
|
||||
|
||||
// Returns dont cause any type system things as they deal with
|
||||
// values, however, we must ensure that the expression type
|
||||
// matches the function type (must fetch from context, or we could
|
||||
// pull a hack with err contexts, lol)
|
||||
.Return => @panic("TODO return"),
|
||||
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn nodePass(
|
||||
self: *@This(),
|
||||
ctx: *comp.CompilationContext,
|
||||
|
@ -194,6 +233,14 @@ pub const TypeSolver = struct {
|
|||
try parameters.append(param_type.?);
|
||||
}
|
||||
|
||||
// TODO scopes: bump scope
|
||||
|
||||
for (decl.body.toSlice()) |stmt| {
|
||||
try self.stmtPass(ctx, stmt);
|
||||
}
|
||||
|
||||
// TODO scopes: down scope
|
||||
|
||||
// TODO symbols and scope resolution, that's
|
||||
// its own can of worms
|
||||
var symbols = comp.SymbolTable.init(self.allocator);
|
||||
|
|
Loading…
Reference in a new issue