diff --git a/examples/hello.ry b/examples/hello.ry index 9be2bf2..6e79137 100644 --- a/examples/hello.ry +++ b/examples/hello.ry @@ -42,10 +42,6 @@ fn multwo(num: i32, double_flag: bool) i32 { } } -fn multwo_with_one(b: i32) i32 { - return multwo(b, false) + b; -} - fn add(a: i32, b: i32) i32 { return 69 + 69; } diff --git a/src/analysis.zig b/src/analysis.zig index f5c4897..31e9762 100644 --- a/src/analysis.zig +++ b/src/analysis.zig @@ -186,8 +186,6 @@ pub const TypeSolver = struct { // TODO make return type optional and so, skip exprs that // fail to be fully resolved, instead of returning CompileError - - // TODO make the expr ptr a const since we want to implicit cast things pub fn resolveExprType( self: *@This(), ctx: *comp.CompilationContext, @@ -202,6 +200,7 @@ pub const TypeSolver = struct { // all numeric operations return numeric types .Add, .Sub, .Mul, .Div, .Mod => left_type, + // TODO check left and right as numeric .Greater, .GreaterEqual, .Less, .LessEqual => blk: { try self.expectSymUnTypeNumeric(left_type); try self.expectSymUnTypeNumeric(right_type); @@ -227,8 +226,7 @@ pub const TypeSolver = struct { return switch (literal) { .Bool => SymbolUnderlyingType{ .Bool = {} }, - // TODO recast Integer32 as Integer64 if the type we're - // checking into is Integer64, but not the other way. + // TODO determine its i64 depending of parseInt results .Integer32 => SymbolUnderlyingType{ .Integer32 = {} }, .Integer64 => SymbolUnderlyingType{ .Integer64 = {} }, .Float => SymbolUnderlyingType{ .Double = {} }, @@ -258,31 +256,13 @@ pub const TypeSolver = struct { var symbol = try ctx.fetchGlobalSymbol(func_name, .Function); var func_sym = symbol.Function; - for (call.arguments.toSlice()) |arg_expr, idx| { - var param_type = func_sym.parameter_list.at(idx); - var arg_type = try self.resolveExprType(ctx, &arg_expr); - - self.expectSymUnTypeEqual(arg_type, param_type) catch { - self.doError( - "Expected parameter {} to be {}, got {}", - idx, - @tagName(comp.SymbolUnderlyingTypeEnum(param_type)), - @tagName(comp.SymbolUnderlyingTypeEnum(arg_type)), - ); - - return CompileError.TypeError; - }; - } + // TODO check parameter type mismatches between + // call.arguments and func_sym.parameters return func_sym.return_type; }, - .Variable => |vari| { - self.setErrToken(vari); - var metadata = try ctx.resolveVarType(vari.lexeme); - try ctx.insertMetadata(expr, metadata); - return metadata.typ; - }, + // TODO analysis for .Variable .Get => |get| { var target = get.target.*; diff --git a/src/ast.zig b/src/ast.zig index 02093ed..e1e3205 100644 --- a/src/ast.zig +++ b/src/ast.zig @@ -141,11 +141,6 @@ pub const SetExpr = struct { value: *Expr, }; -pub const VariableExpr = struct { - tok: Token, - metadata: ?*comp.VariableMetadata = null, -}; - pub const Expr = union(ExprType) { Assign: AssignExpr, @@ -155,7 +150,6 @@ pub const Expr = union(ExprType) { Struct: StructExpr, Variable: Token, - Grouping: *Expr, Call: CallExpr, diff --git a/src/comp_ctx.zig b/src/comp_ctx.zig index e50a5e9..0a407e3 100644 --- a/src/comp_ctx.zig +++ b/src/comp_ctx.zig @@ -1,10 +1,7 @@ const std = @import("std"); const ast = @import("ast.zig"); -pub const CompilationError = error{ - TypeError, - UnknownName, -}; +pub const CompilationError = error{TypeError}; pub const SymbolTable = std.hash_map.StringHashMap(SymbolData); pub const TypeList = std.ArrayList(SymbolUnderlyingType); @@ -79,8 +76,6 @@ 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, - parameter_list: TypeList, - scope: *Scope, /// Find a given identifier in the function. Can resolve to either a parameter @@ -128,31 +123,6 @@ const builtin_type_identifiers = [_][]const u8{ "i32", "i64", "bool" }; const builtin_types = [_]SymbolUnderlyingTypeEnum{ .Integer32, .Integer64, .Bool }; -const Using = enum { - Scope, - Function, -}; - -pub const VariableMetadata = struct { - typ: SymbolUnderlyingType, - - using: Using, - - from_scope: ?*Scope = null, - from_function: ?*FunctionSymbol = null, - - pub fn withScope(scope: *Scope, typ: SymbolUnderlyingType) VariableMetadata { - return VariableMetadata{ .typ = typ, .from_scope = scope, .using = .Scope }; - } - - pub fn withParam(func: *FunctionSymbol, typ: SymbolUnderlyingType) VariableMetadata { - return VariableMetadata{ .typ = typ, .from_function = func, .using = .Function }; - } -}; - -// TODO rm const? -pub const VariableMetadataMap = std.AutoHashMap(*const ast.Expr, VariableMetadata); - /// Represents the context for a full compiler run. /// This is used to manage the symbol table for the compilation unit, etc. pub const CompilationContext = struct { @@ -162,21 +132,13 @@ pub const CompilationContext = struct { cur_function: ?*FunctionSymbol = null, current_scope: ?*Scope = null, - metadata_map: VariableMetadataMap, - pub fn init(allocator: *std.mem.Allocator) CompilationContext { return CompilationContext{ .allocator = allocator, .symbol_table = SymbolTable.init(allocator), - .metadata_map = VariableMetadataMap.init(allocator), }; } - pub fn deinit(self: *@This()) void { - self.symbol_table.deinit(); - self.metadata_map.deinit(); - } - /// Create a new scope out of the current one and set it as the current. pub fn bumpScope(self: *@This(), scope_id: ?[]const u8) !void { if (self.current_scope == null) { @@ -277,7 +239,6 @@ pub const CompilationContext = struct { .decl = decl, .return_type = ret_type, .parameters = type_map, - .parameter_list = param_types, .scope = scope, }, }); @@ -325,43 +286,4 @@ pub const CompilationContext = struct { return sym_kv.?.value; } - - fn resolveVarTypeInScope( - self: *@This(), - scope_opt: ?*Scope, - name: []const u8, - ) ?VariableMetadata { - if (scope_opt == null) return null; - var scope = scope_opt.?; - - var kv_opt = scope.env.get(name); - if (kv_opt) |kv| { - return VariableMetadata.withScope(scope, kv.value); - } else { - return self.resolveVarTypeInScope(scope.parent, name); - } - } - - /// Resolve a given name's type, assuming it is a variable. - pub fn resolveVarType(self: *@This(), name: []const u8) !VariableMetadata { - var var_type: ?VariableMetadata = null; - - if (self.current_scope) |scope| { - var_type = self.resolveVarTypeInScope(scope, name); - if (var_type) |typ| return typ; - } - - if (self.cur_function) |cur_function| { - var kv_opt = cur_function.parameters.get(name); - if (kv_opt) |kv| return VariableMetadata.withParam(cur_function, kv.value); - } - - std.debug.warn("Unknown name {}\n", name); - return CompilationError.UnknownName; - } - - pub fn insertMetadata(self: *@This(), ptr: *const ast.Expr, metadata: VariableMetadata) !void { - std.debug.assert(ast.ExprType(ptr.*) == .Variable); - _ = try self.metadata_map.put(ptr, metadata); - } }; diff --git a/src/parsers.zig b/src/parsers.zig index 026d11e..3bb8572 100644 --- a/src/parsers.zig +++ b/src/parsers.zig @@ -412,9 +412,9 @@ pub const Parser = struct { return expr; } - fn mkVariable(self: *Parser, tok: Token) !*ast.Expr { + fn mkVariable(self: *Parser, variable: Token) !*ast.Expr { var expr = try self.allocator.create(Expr); - expr.* = Expr{ .Variable = tok }; + expr.* = Expr{ .Variable = variable }; return expr; }