From bf035abadfafbaa1158910de2a8d977de2db4197 Mon Sep 17 00:00:00 2001 From: Luna Date: Thu, 26 Sep 2019 00:11:48 -0300 Subject: [PATCH] add lots of TODOs for variables and type analysis of statements - comp_ctx: replace Function.symbols to Function.env --- examples/hello.ry | 10 ++++------ src/codegen.zig | 18 +++++++++++++++++- src/comp_ctx.zig | 8 +++++++- src/types.zig | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 8 deletions(-) diff --git a/examples/hello.ry b/examples/hello.ry index ca959ab..3c0c53c 100644 --- a/examples/hello.ry +++ b/examples/hello.ry @@ -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 diff --git a/src/codegen.zig b/src/codegen.zig index c92f452..012373c 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -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; }, } diff --git a/src/comp_ctx.zig b/src/comp_ctx.zig index 827c460..f223bf9 100644 --- a/src/comp_ctx.zig +++ b/src/comp_ctx.zig @@ -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 { diff --git a/src/types.zig b/src/types.zig index 8afa4c3..c2c21b6 100644 --- a/src/types.zig +++ b/src/types.zig @@ -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);