summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNic Gaffney <gaffney_nic@protonmail.com>2025-02-18 16:44:48 -0600
committerNic Gaffney <gaffney_nic@protonmail.com>2025-02-18 16:44:48 -0600
commit8f2595c71bce8d2f14de334d6e1b6378cc9f7cbf (patch)
tree6d6ca8b19c42d26bc965ac851eac643d3f1e4e5e /src
parentc77c9a42cd048a9f68aedf4fed5bfa8a2a4051d6 (diff)
downloadcalico-8f2595c71bce8d2f14de334d6e1b6378cc9f7cbf.tar.gz
Pre-repair
Diffstat (limited to 'src')
-rw-r--r--src/codegen.zig50
-rw-r--r--src/main.zig14
-rw-r--r--src/parser.zig78
-rw-r--r--src/symtable.zig6
-rw-r--r--src/tokenize.zig47
5 files changed, 110 insertions, 85 deletions
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();
}