From 8f2595c71bce8d2f14de334d6e1b6378cc9f7cbf Mon Sep 17 00:00:00 2001 From: Nic Gaffney Date: Tue, 18 Feb 2025 16:44:48 -0600 Subject: Pre-repair --- src/codegen.zig | 50 ++++++++++++++++++++++++++++-------- src/main.zig | 14 +++++----- src/parser.zig | 78 +++++++++++++++++++++++++++++++------------------------- src/symtable.zig | 6 ++++- src/tokenize.zig | 47 ++++++++++++---------------------- 5 files changed, 110 insertions(+), 85 deletions(-) (limited to 'src') diff --git a/src/codegen.zig b/src/codegen.zig index 51908c1..e9ec53b 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -65,7 +65,7 @@ pub const Generator = struct { fn genExit(self: *Generator, exit: parse.NodeExit) !void { const expr = exit; - const val = self.genExpr(expr); + const val = try self.genExpr(expr); _ = core.LLVMBuildRet(self.builder, val); } @@ -74,7 +74,7 @@ pub const Generator = struct { const table = stmt.symtable; const symbol = table.getValue(nodeVar.ident.ident).?; - const value = self.genExpr(nodeVar.expr); + const value = try self.genExpr(nodeVar.expr); const ptr = try self.genAlloc(toLLVMtype(nodeVar.expr.typ.?, table).?, nodeVar.ident.ident); _ = core.LLVMBuildStore(self.builder, value, ptr); try self.references.put(symbol.id, ptr); @@ -86,8 +86,9 @@ pub const Generator = struct { const table = stmt.symtable; const symbol = table.getValue(nodeVar.ident.ident).?; const ptr = try self.genAlloc(toLLVMtype(nodeVar.expr.typ.?, table), nodeVar.ident.ident); - const value = self.genExpr(nodeVar.expr); + const value = try self.genExpr(nodeVar.expr); _ = core.LLVMBuildStore(self.builder, value, ptr); + std.debug.print("\t\t\tGenerated Value {s}\n", .{nodeVar.ident.ident}); try self.references.put(symbol.id, ptr); } @@ -107,9 +108,9 @@ pub const Generator = struct { return core.LLVMBuildAlloca(builder, typ, str); } - fn asBasicType(typ: symb.SymbType) ?types.LLVMTypeKind { + fn asBasicType(typ: symb.SymbType) ?types.LLVMTypeRef { return switch (typ) { - .Integer => types.LLVMTypeKind.LLVMIntegerTypeKind, + .Integer => core.LLVMInt32Type(), else => null, }; } @@ -120,7 +121,7 @@ pub const Generator = struct { const symbol = table.get(stmt.kind.assignVar.ident.ident).?; if (!symbol.Value.mut) return CodegenError.Immutable; const ptr = self.references.get(symbol.Value.id).?; - const value = self.genExpr(stmt.kind.assignVar.expr); + const value = try self.genExpr(stmt.kind.assignVar.expr); _ = core.LLVMBuildStore(self.builder, value, ptr); } @@ -161,7 +162,7 @@ pub const Generator = struct { const block = ifkind.body; const expr = ifkind.expr; - const condition = self.genExpr(expr); + const condition = try self.genExpr(expr); const func = self.currentFunc.?; const then = core.LLVMAppendBasicBlock(func, "then"); @@ -181,6 +182,7 @@ pub const Generator = struct { } fn genStmt(self: *Generator, stmt: parse.NodeStmt) !void { + std.debug.print("======\n\tStmt: {any}\n======\n", .{stmt.kind}); try switch (stmt.kind) { .exit => |expr| self.genExit(expr), .function => self.genFunc(stmt), @@ -192,8 +194,32 @@ pub const Generator = struct { }; } - fn genExpr(self: *Generator, expr: parse.NodeExpr) types.LLVMValueRef { + fn genExpr(self: *Generator, expr: parse.NodeExpr) !types.LLVMValueRef { + std.debug.print("======\n\t\tExpr: {any}\n======\n", .{expr.kind}); return switch (expr.kind) { + .call => |callee| blk: { + const ident: [*:0]const u8 = try self.allocator.dupeZ(u8, callee.ident.ident); + const func = core.LLVMGetNamedFunction(self.module, ident); + const symbol = expr.symtable.get(callee.ident.ident).?; + const retType = asBasicType(symbol.Value.typ.Function.output.*); + + const paramTypes = ([_]types.LLVMTypeRef{})[0..0]; + var args = std.ArrayList(types.LLVMValueRef).init(self.allocator); + for (callee.args.items) |item| + try args.append(try self.genExpr(item)); + + const typ = core.LLVMFunctionType(retType.?, @ptrCast(@constCast(paramTypes)), 0, 0); + const call = core.LLVMBuildCall2( + self.builder, + typ, + func, + @ptrCast(args.items), + 0, + // @intCast(callee.args.items.len), + "", + ); + break :blk call; + }, .ident => blk: { const table = expr.symtable; const symbol = table.getValue(expr.kind.ident.ident).?; @@ -202,8 +228,9 @@ pub const Generator = struct { }, .intLit => |int| core.LLVMConstInt(core.LLVMInt32TypeInContext(self.context), @intCast(int.intLit), 1), .binaryOp => |exp| blk: { - const lhs = self.genExpr(exp.lhs.*); - const rhs = self.genExpr(exp.rhs.*); + const lhs = try self.genExpr(exp.lhs.*); + const rhs = try self.genExpr(exp.rhs.*); + std.debug.print("\n\n\tLHS: {any}\n\tRHS: {any}\n\tOP: {any}\n\n", .{ lhs, rhs, exp.op }); break :blk switch (exp.op) { .plus => core.LLVMBuildAdd(self.builder, lhs, rhs, "add"), @@ -220,8 +247,9 @@ pub const Generator = struct { pub fn generate(self: *Generator) ![]const u8 { try switch (self.root.kind) { .block => |b| { - for (b) |stmt| + for (b) |stmt| { try self.genStmt(stmt); + } }, else => error.InvalidTop, }; diff --git a/src/main.zig b/src/main.zig index 613d8f9..9e53ecd 100644 --- a/src/main.zig +++ b/src/main.zig @@ -5,6 +5,12 @@ const gen = @import("codegen.zig"); const symb = @import("symtable.zig"); pub fn main() !void { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + const alc = gpa.allocator(); + defer _ = gpa.deinit(); + var arena = std.heap.ArenaAllocator.init(alc); + defer arena.deinit(); + var allocator = arena.allocator(); if (std.os.argv.len < 2) { std.debug.print( \\info: Usage: calico [input file] @@ -13,10 +19,6 @@ pub fn main() !void { return; } - var gpa = std.heap.GeneralPurposeAllocator(.{}){}; - var allocator = gpa.allocator(); - defer _ = gpa.deinit(); - var args = std.process.args(); _ = args.skip(); const inputFileName = args.next(); @@ -58,12 +60,10 @@ pub fn main() !void { try pop.populateSymtable(&treeNode); // Codegen - var arena = std.heap.ArenaAllocator.init(allocator); - var generator = gen.Generator.init(arena.allocator(), tree); + var generator = gen.Generator.init(allocator, tree); defer generator.deinit(); const code = try generator.generate(); try outWriter.writeAll(code); - arena.deinit(); const binFile = try getFileName(allocator, out_name, ""); defer allocator.free(binFile); diff --git a/src/parser.zig b/src/parser.zig index 129bf94..46d148e 100644 --- a/src/parser.zig +++ b/src/parser.zig @@ -142,39 +142,29 @@ pub const Parser = struct { self.nodes.deinit(); } - // fn parseExpr(self: *Parser) !NodeExpr { - // var typ: ?TypeIdent = null; - // const kind = try blk: { - // try switch (self.tokens.peek().?) { - // .intLit => { - // typ = TypeIdent{ - // .ident = "i32", - // .list = false, - // }; - // break :blk ExprKind{ .intLit = (try self.tokens.consume(.intLit)).? }; - // }, - // .ident => { - // const ident = (try self.tokens.consume(.ident)).?; - // typ = TypeIdent{ - // .ident = "i32", - // .list = false, - // }; - // break :blk ExprKind{ .ident = ident }; - // }, - // else => break :blk ParsingError.InvalidExpression, - // }; - // }; - // return NodeExpr{ - // .id = self.reserveId(), - // .kind = kind, - // .isConst = kind.isConstant(), - // .typ = typ, - // .symtable = self.top, - // }; - // } + fn parseCall(self: *Parser, typ: ?TypeIdent, expr: NodeExpr) ParsingError!NodeExpr { + if (self.tokens.peek().? != .openParen) return expr; + _ = try self.tokens.consume(.openParen); + var args = std.ArrayList(NodeExpr).init(self.allocator); + while (self.tokens.peek().? != .closeParen) { + try args.append(try self.parseExpr()); + if (self.tokens.peek().? != .comma) break; + } + _ = try self.tokens.consume(.closeParen); + + const kind = ExprKind{ .call = .{ .ident = expr.kind.ident, .args = args } }; + return NodeExpr{ + .kind = kind, + .isConst = false, + .typ = typ, + .id = self.reserveId(), + .symtable = self.top, + }; + } fn parseExpr(self: *Parser) !NodeExpr { var typ: ?TypeIdent = null; + var isIdent = false; const kind: ExprKind = try blk: { try switch (self.tokens.peek().?) { .intLit => { @@ -190,6 +180,7 @@ pub const Parser = struct { .ident = "i32", .list = false, }; + isIdent = true; break :blk ExprKind{ .ident = ident }; }, else => break :blk ParsingError.InvalidExpression, @@ -213,10 +204,13 @@ pub const Parser = struct { &.{.eqleql}, }; - return try genBinOp(self, precTable[0], typ, lhsptr) //. - orelse try genBinOp(self, precTable[1], typ, lhsptr) //. - orelse try genBinOp(self, precTable[2], typ, lhsptr) //. - orelse lhs; + return try self.genBinOp(precTable[0], typ, lhsptr) //. + orelse try self.genBinOp(precTable[1], typ, lhsptr) //. + orelse try self.genBinOp(precTable[2], typ, lhsptr) //. + orelse if (isIdent) blk: { + break :blk try self.parseCall(typ, lhsptr.*); + } //. + else lhs; } fn genBinOp(self: *Parser, comptime ops: []const tok.TokenType, typ: ?TypeIdent, lhs: *NodeExpr) ParsingError!?NodeExpr { @@ -313,8 +307,12 @@ pub const Parser = struct { fn parseBlock(self: *Parser) !NodeStmt { _ = try self.tokens.consume(.openBrace); var stmtArr = std.ArrayList(NodeStmt).init(self.allocator); + const top = self.top; + const child = try self.top.makeChild(); + self.top = child; while (!tok.checkType(self.tokens.peek().?, .closeBrace)) try stmtArr.append(try self.parseStmt()); + self.top = top; _ = try self.tokens.consume(.closeBrace); const kind = StmtKind{ .block = try stmtArr.toOwnedSlice(), @@ -323,7 +321,7 @@ pub const Parser = struct { return NodeStmt{ .id = self.reserveId(), .kind = kind, - .symtable = try self.top.makeChild(), + .symtable = child, }; } @@ -378,6 +376,11 @@ pub const Parser = struct { fn parseConstant(self: *Parser) !NodeStmt { _ = try self.tokens.consume(.constant); + var typ: ?TypeIdent = null; + if ((self.tokens.peek().?) == .colon) { + _ = try self.tokens.consume(.colon); + typ = .{ .ident = (try self.tokens.consume(.ident)).?.ident, .list = false }; + } const ident = (try self.tokens.consume(.ident)).?; _ = try self.tokens.consume(.equal); const expr = try self.parseExpr(); @@ -444,6 +447,10 @@ pub const NodeIntlit = Token; pub const NodeIdent = Token; pub const NodeBlock = []const NodeStmt; pub const NodeBinOp = Token; +pub const NodeCall = struct { + ident: NodeIdent, + args: std.ArrayList(NodeExpr), +}; pub const StmtKind = union(enum) { ifstmt: NodeIf, @@ -458,6 +465,7 @@ pub const StmtKind = union(enum) { pub const ExprKind = union(enum) { intLit: NodeIntlit, ident: NodeIdent, + call: NodeCall, binaryOp: struct { lhs: *NodeExpr, rhs: *NodeExpr, diff --git a/src/symtable.zig b/src/symtable.zig index 60e871c..8a5bd8a 100644 --- a/src/symtable.zig +++ b/src/symtable.zig @@ -80,6 +80,7 @@ pub const SymbolTable = struct { const scope = try self.allocator.create(Scope); scope.par = self.scope; scope.symbs = std.StringHashMap(Symbol).init(self.allocator); + // scope.symbs = self.scope.?.symbs; const stable: *SymbolTable = try self.allocator.create(SymbolTable); stable.* = .{ .scope = scope, @@ -88,7 +89,7 @@ pub const SymbolTable = struct { return stable; } - pub fn parent(self: SymbolTable) ?*SymbolTable { + pub fn parent(self: SymbolTable) ?*Scope { if (self.scope) |scope| if (scope.par) |par| return par; @@ -101,6 +102,7 @@ pub const SymbolTable = struct { } pub fn get(self: SymbolTable, ident: []const u8) ?Symbol { + if (!self.contains(ident)) if (self.parent()) |par| return par.symbs.get(ident); if (self.scope) |scope| return scope.symbs.get(ident); return null; } @@ -174,6 +176,7 @@ pub const Populator = struct { if (value.expr.typ) |typ| typ else pars.TypeIdent{ .ident = "i32", .list = false }, false, ); + std.debug.print("Value: {s}\nSymbol: {any}\n", .{ value.ident.ident, symbol }); if (!try table.insert(value.ident.ident, symbol)) return error.FailedToInsert; }, .block => { @@ -245,6 +248,7 @@ pub const Populator = struct { }; return value.toSymb(); } + std.debug.print("Unknown Type: {s}\n", .{typ.ident}); return error.UnknownType; } }; diff --git a/src/tokenize.zig b/src/tokenize.zig index 6fc0ebc..252bca4 100644 --- a/src/tokenize.zig +++ b/src/tokenize.zig @@ -16,6 +16,7 @@ pub const TokenType = enum { variable, exit, fun, + import, // Operators plus, minus, @@ -32,6 +33,8 @@ pub const TokenType = enum { openParen, closeParen, arrow, + colon, + comma, }; pub const Token = union(TokenType) { @@ -44,6 +47,7 @@ pub const Token = union(TokenType) { variable, exit, fun, + import, // Operators plus, minus, @@ -60,38 +64,12 @@ pub const Token = union(TokenType) { openParen, closeParen, arrow, - - pub fn toTokenType(self: Token) TokenType { - switch (self) { - .ident => .ident, - .intLit => .intLit, - // Keywords - .ifstmt => .ifstmt, - .constant => .constant, - .variable => .variable, - .exit => .exit, - .fun => .fun, - // => Operators .=> - .plus => .plus, - .minus => .minus, - .star => .star, - .slash => .slash, - .semiCol => .semiCol, - .equal => .equal, - .eqleql => .eqleql, - .lessthan => .lessthan, - .greaterthan => .greaterthan, - // => Symbols .=> - .openBrace => .openBrace, - .closeBrace => .closeBrace, - .openParen => .openParen, - .closeParen => .closeParen, - .arrow => .arrow, - } - } + colon, + comma, pub fn fromChar(char: u8) !Token { return switch (char) { + ',' => .comma, '+' => .plus, '-' => .minus, '*' => .star, @@ -104,7 +82,11 @@ pub const Token = union(TokenType) { ')' => .closeParen, '<' => .lessthan, '>' => .greaterthan, - else => TokenizeError.UnknownToken, + ':' => .colon, + else => blk: { + std.debug.print("Invalid char: {c}\n", .{char}); + break :blk TokenizeError.UnknownToken; + }, }; } @@ -115,6 +97,7 @@ pub const Token = union(TokenType) { if (eql(u8, str, "var")) return .variable; if (eql(u8, str, "fn")) return .fun; if (eql(u8, str, "if")) return .ifstmt; + if (eql(u8, str, "import")) return .import; return Token{ .ident = str }; } }; @@ -156,8 +139,10 @@ pub fn Iterator(comptime typ: type) type { pub fn consume(self: *Iterator(typ), comptime expected: TokenType) !?typ { if (typ != Token) return error.TokenIteratorOnly; - if (!checkType(self.peek().?, expected)) + if (!checkType(self.peek().?, expected)) { + std.debug.print("Expected {any} got {any} \n", .{ expected, self.peek().? }); return TokenizeError.ExpectedToken; + } return self.next(); } -- cgit v1.2.3