summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNic Gaffney <gaffney_nic@protonmail.com>2024-08-07 02:28:47 -0500
committerNic Gaffney <gaffney_nic@protonmail.com>2024-08-07 02:28:47 -0500
commit068ff09a96ad3cdea31d788c053ea3d544713e39 (patch)
treee70ce509d4b87bba8eadc0e12697865a5c71fcce /src
parentba10363947d2f666ebbead0c6c04576e2d93babd (diff)
downloadcalico-068ff09a96ad3cdea31d788c053ea3d544713e39.tar.gz
Updated codegen to allow defining / assigning variables
Diffstat (limited to 'src')
-rw-r--r--src/codegen.zig114
-rw-r--r--src/main.zig3
-rw-r--r--src/parser.zig6
-rw-r--r--src/symtable.zig18
4 files changed, 83 insertions, 58 deletions
diff --git a/src/codegen.zig b/src/codegen.zig
index e2889a6..6dde45d 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -8,6 +8,7 @@ const target = llvm.target;
const types = llvm.types;
const CodegenError = error{
+ Immutable,
OutOfMemory,
};
@@ -30,6 +31,7 @@ pub const Generator = struct {
module: types.LLVMModuleRef,
currentFunc: ?types.LLVMValueRef,
currentFuncIsVoid: bool,
+ references: std.AutoHashMap(u32, types.LLVMValueRef),
pub fn init(allocator: std.mem.Allocator, root: parse.NodeStmt) Generator {
_ = target.LLVMInitializeNativeTarget();
@@ -48,6 +50,7 @@ pub const Generator = struct {
.module = module,
.currentFunc = null,
.currentFuncIsVoid = false,
+ .references = std.AutoHashMap(u32, types.LLVMValueRef).init(allocator),
};
}
@@ -62,61 +65,63 @@ pub const Generator = struct {
fn genExit(self: *Generator, exit: parse.NodeExit) !void {
const expr = exit;
- const val = core.LLVMConstInt(core.LLVMInt32Type(), switch (expr.kind) {
- .intLit => |i| @intCast(i.intLit),
- .ident => unreachable,
- }, 0);
+ const val = self.genExpr(expr);
_ = core.LLVMBuildRet(self.builder, val);
}
- fn genVar(self: *Generator, value: parse.NodeVar) !void {
- const str = try std.fmt.allocPrint(self.allocator,
- \\section .data
- \\ {s}: dw {d}
- \\
- , .{ value.ident.ident, switch (value.expr.kind) {
- .intLit => |intlit| intlit.intLit,
- else => return error.NotImplemented,
- } });
- defer self.allocator.free(str);
- try self.code.insertSlice(0, str);
+ fn genVar(self: *Generator, stmt: parse.NodeStmt) !void {
+ const nodeVar = stmt.kind.defVar;
+
+ const table = stmt.symtable;
+ const symbol = table.getValue(nodeVar.ident.ident).?;
+ const value = 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);
+ }
+
+ fn genValue(self: *Generator, stmt: parse.NodeStmt) !void {
+ const nodeVar = stmt.kind.defValue;
+
+ 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);
+ _ = core.LLVMBuildStore(self.builder, value, ptr);
+ try self.references.put(symbol.id, ptr);
}
- fn genValue(self: *Generator, value: parse.NodeValue) !void {
- const str = try std.fmt.allocPrint(self.allocator,
- \\section .data
- \\ {s}: dw {d}
- \\
- , .{ value.ident.ident, switch (value.expr.kind) {
- .intLit => |intlit| intlit.intLit,
- else => return error.NotImplemented,
- } });
- defer self.allocator.free(str);
- try self.code.insertSlice(0, str);
+ fn genAlloc(self: *Generator, typ: types.LLVMTypeRef, ident: []const u8) !types.LLVMValueRef {
+ const builder = core.LLVMCreateBuilderInContext(self.context);
+
+ const entryFunc = self.currentFunc.?;
+ const entry = core.LLVMGetFirstBasicBlock(entryFunc).?;
+
+ if (core.LLVMGetFirstInstruction(entry)) |first| {
+ core.LLVMPositionBuilderBefore(builder, first);
+ } else {
+ core.LLVMPositionBuilderAtEnd(builder, entry);
+ }
+
+ const str: [*:0]const u8 = try self.allocator.dupeZ(u8, ident);
+ return core.LLVMBuildAlloca(builder, typ, str);
}
- fn genAssign(self: *Generator, assign: parse.NodeAssign) !void {
- const newCode =
- switch (assign.expr.kind) {
- .intLit => |intlit| try std.fmt.allocPrint(self.allocator,
- \\ mov rax, {d}
- \\ mov [{s}], rax
- \\
- , .{
- intlit.intLit,
- assign.ident.ident,
- }),
- .ident => |ident| try std.fmt.allocPrint(self.allocator,
- \\ mov rax, [{s}]
- \\ mov [{s}], rax
- \\
- , .{
- ident.ident,
- assign.ident.ident,
- }),
+ fn asBasicType(typ: symb.SymbType) ?types.LLVMTypeKind {
+ return switch (typ) {
+ .Integer => types.LLVMTypeKind.LLVMIntegerTypeKind,
+ else => null,
};
- try self.code.appendSlice(newCode);
- self.allocator.free(newCode);
+ }
+
+ fn genAssign(self: *Generator, stmt: parse.NodeStmt) !void {
+ std.debug.print("assign\n", .{});
+ const table = stmt.symtable;
+ 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);
+ _ = core.LLVMBuildStore(self.builder, value, ptr);
}
fn genBlock(self: *Generator, block: []const parse.NodeStmt) CodegenError!void {
@@ -155,10 +160,25 @@ pub const Generator = struct {
try switch (stmt.kind) {
.exit => |expr| self.genExit(expr),
.function => self.genFunc(stmt),
+ .defValue => self.genValue(stmt),
+ .defVar => self.genVar(stmt),
+ .assignVar => self.genAssign(stmt),
else => {},
};
}
+ fn genExpr(self: *Generator, expr: parse.NodeExpr) types.LLVMValueRef {
+ return switch (expr.kind) {
+ .ident => blk: {
+ const table = expr.symtable;
+ const symbol = table.getValue(expr.kind.ident.ident).?;
+ const ptr = self.references.get(symbol.id).?;
+ break :blk core.LLVMBuildLoad2(self.builder, toLLVMtype(expr.typ.?, table), ptr, "");
+ },
+ .intLit => |int| core.LLVMConstInt(core.LLVMInt32TypeInContext(self.context), @intCast(int.intLit), 1),
+ };
+ }
+
pub fn generate(self: *Generator) ![]const u8 {
try switch (self.root.kind) {
.block => |b| {
diff --git a/src/main.zig b/src/main.zig
index 248640b..d748461 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -53,8 +53,8 @@ pub fn main() !void {
var parser = parse.Parser.init(allocator, tokens, symbTable);
defer parser.deinit();
const tree = try parser.parse();
- var pop = symb.Populator.init(allocator);
var treeNode = tree.asNode();
+ var pop = symb.Populator.init(allocator);
try pop.populateSymtable(&treeNode);
// Codegen
@@ -69,6 +69,7 @@ pub fn main() !void {
const ldproc = try std.process.Child.run(.{ .argv = &ldargv, .allocator = allocator });
defer allocator.free(ldproc.stdout);
defer allocator.free(ldproc.stderr);
+ std.debug.print("code: \n{s}", .{code});
}
/// Get file extension based on filename
diff --git a/src/parser.zig b/src/parser.zig
index fa0acec..8cd539f 100644
--- a/src/parser.zig
+++ b/src/parser.zig
@@ -140,12 +140,8 @@ pub const Parser = struct {
},
.ident => {
const ident = (try self.tokens.consume(.ident)).?;
- const symbType = if (self.top.get(ident.ident)) |sym|
- sym.Type
- else
- return ParsingError.UnknownIdentifier;
typ = TypeIdent{
- .ident = symbType.toString(),
+ .ident = "i32",
.list = false,
};
break :blk ExprKind{ .ident = ident };
diff --git a/src/symtable.zig b/src/symtable.zig
index 72eecc7..f37ee12 100644
--- a/src/symtable.zig
+++ b/src/symtable.zig
@@ -159,8 +159,9 @@ pub const Populator = struct {
switch (node.*) {
.Stmt => |stmt| {
const table: *SymbolTable = stmt.symtable;
- try switch (stmt.kind) {
+ switch (stmt.kind) {
.defVar => |variable| {
+ std.debug.print("Populated {s}\n", .{variable.ident.ident});
const symbol: Symbol = try self.buildValueSymb(
table,
if (variable.expr.typ) |typ| typ else pars.TypeIdent{ .ident = "i32", .list = false },
@@ -174,12 +175,17 @@ pub const Populator = struct {
if (value.expr.typ) |typ| typ else pars.TypeIdent{ .ident = "i32", .list = false },
false,
);
+ std.debug.print("Populated {s}\n", .{value.ident.ident});
if (!try table.insert(value.ident.ident, symbol)) return error.FailedToInsert;
},
.block => {
const children = try stmt.children(self.allocator);
defer self.allocator.free(children);
- for (children) |child| try self.populateSymtable(&child);
+ std.debug.print("Populated Block\n", .{});
+ for (children) |child| {
+ std.debug.print("Child: {d}\n", .{child.Stmt.id});
+ try self.populateSymtable(&child);
+ }
},
.function => |fun| {
const symbol: Symbol = try self.buildFunctionSymb(
@@ -187,12 +193,14 @@ pub const Populator = struct {
fun.args,
fun.retType,
);
+ std.debug.print("Populated Function {s}\n", .{fun.ident.ident});
if (!try table.insert(fun.ident.ident, symbol)) return error.FailedToInsert;
+ const children = try stmt.children(self.allocator);
+ for (children) |child| try self.populateSymtable(&child);
},
- .exit => {},
- else => error.Unimplemented,
- };
+ else => {},
+ }
},
else => {
for (try node.children(self.allocator)) |child|