Compare commits

..

No commits in common. "7def9abc5ab97df661933d292b3c73b60d70f844" and "3f9408247767769c16c951bc433fe74affa015a0" have entirely different histories.

5 changed files with 8 additions and 116 deletions

View file

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

View file

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

View file

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

View file

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

View file

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