aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjjanzen <jjanzen@jjanzen.ca>2025-03-04 20:40:26 -0600
committerjjanzen <jjanzen@jjanzen.ca>2025-03-04 20:40:26 -0600
commit2ee94b959442f4cf6da73403cfb91a6fbafae452 (patch)
treeb8ba6c8932b7069a9ca10ff8b3df147954600e4a
parent4af81abcc1c9555011677da25b89061ce6bc605e (diff)
cleanupHEADmain
-rw-r--r--src/main.zig7
-rw-r--r--src/parser.zig165
2 files changed, 94 insertions, 78 deletions
diff --git a/src/main.zig b/src/main.zig
index c8a3f67..c7892a0 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -15,10 +15,3 @@ pub fn main() !void {
try bw.flush(); // don't forget to flush!
}
-
-test "simple test" {
- var list = std.ArrayList(i32).init(std.testing.allocator);
- defer list.deinit(); // try commenting this out and see if zig detects the memory leak!
- try list.append(42);
- try std.testing.expectEqual(@as(i32, 42), list.pop());
-}
diff --git a/src/parser.zig b/src/parser.zig
index 51ea0ac..08466ad 100644
--- a/src/parser.zig
+++ b/src/parser.zig
@@ -1,36 +1,6 @@
const std = @import("std");
const opcodes = @import("opcodes.zig");
-/// A number's value can be pure or point to a register
-const NumberType = enum {
- pure,
- register,
-};
-const NumberValue = union(NumberType) {
- pure: u64,
- register: u8,
-};
-
-/// An expression's result can be a NumberValue or a string
-const ExpressionResultType = enum {
- number,
- string,
-};
-const ExpressionResult = union(ExpressionResultType) {
- number: NumberValue,
- string: []const u8,
-};
-
-/// A constant can be a number of a string
-const ConstantType = enum {
- number,
- string,
-};
-const ConstantValue = union(ConstantType) {
- number: u64,
- string: []const u8,
-};
-
/// The Parser reads a provided input and assembles it into MMIX object code
pub const Parser = struct {
allocator: std.mem.Allocator,
@@ -84,6 +54,16 @@ pub const Parser = struct {
}
}
+ /// A number's value can be pure or point to a register
+ const NumberType = enum {
+ pure,
+ register,
+ };
+ const NumberValue = union(NumberType) {
+ pure: u64,
+ register: u8,
+ };
+
const DecimalError = std.fmt.ParseIntError;
/// Determine whether the cursor points at a valid integer in base 10
@@ -213,6 +193,16 @@ pub const Parser = struct {
UnexpectedSymbol,
};
+ /// A constant can be a number of a string
+ const ConstantType = enum {
+ number,
+ string,
+ };
+ const ConstantValue = union(ConstantType) {
+ number: u64,
+ string: []const u8,
+ };
+
/// Determine whether the cursor points at a valid constant
/// The constant may be a string or a number
/// Move the cursor past the constant and return it
@@ -321,6 +311,16 @@ pub const Parser = struct {
FractionalDivisionOversizedNumerator,
};
+ /// An expression's result can be a NumberValue or a string
+ const ExpressionResultType = enum {
+ number,
+ string,
+ };
+ const ExpressionResult = union(ExpressionResultType) {
+ number: NumberValue,
+ string: []const u8,
+ };
+
/// Determine whether the cursor points at a valid expression
/// Move the cursor past the expression, evaluate it, and return its value
fn identifyExpression(self: *Parser) ExpressionError!ExpressionResult {
@@ -616,6 +616,19 @@ pub const Parser = struct {
return opcodes.parseOp(self.allocator, self.input[start..end]);
}
+ const LineContents = struct {
+ allocator: std.mem.Allocator,
+ symbol_text: ?[]const u8,
+ opcode: opcodes.Operation,
+ expressions: std.ArrayList(?ExpressionResult),
+ unresolved_expressions: std.AutoHashMap(usize, u4),
+ };
+
+ fn identifyLine(self: *Parser) !LineContents {
+ _ = self;
+ return error.NotImplemented;
+ }
+
pub fn init(allocator: std.mem.Allocator, input: []const u8) !Parser {
var p = Parser{
.allocator = allocator,
@@ -626,6 +639,7 @@ pub const Parser = struct {
.object = std.ArrayList(u8).init(allocator),
};
+ // Populate the symbol table with backwards references
try p.symbols.put("0B", NumberValue{ .pure = 0 });
try p.symbols.put("1B", NumberValue{ .pure = 0 });
try p.symbols.put("2B", NumberValue{ .pure = 0 });
@@ -646,6 +660,15 @@ pub const Parser = struct {
}
};
+// ===========================================================================//
+// _____ _____ _____ _____ _____ //
+// |_ _| ___/ ___|_ _/ ___| //
+// | | | |__ \ `--. | | \ `--. //
+// | | | __| `--. \ | | `--. \ //
+// | | | |___/\__/ / | | /\__/ / //
+// \_/ \____/\____/ \_/ \____/ //
+// ===========================================================================//
+
test "normal ascii characters are recognized as symbol chars" {
const chars = "qwertyuiopasdfghjklzxcvbnm1234567890QWERTYUIOPASDFGHJKLZXCVBNM_";
@@ -941,11 +964,11 @@ test "constants are recognized" {
"\"hello \"world",
};
- const expected = [_]ConstantValue{
- ConstantValue{ .number = 1234567890 },
- ConstantValue{ .number = 0x1234567890abcdef },
- ConstantValue{ .number = 'a' },
- ConstantValue{ .string = "hello " },
+ const expected = [_]Parser.ConstantValue{
+ Parser.ConstantValue{ .number = 1234567890 },
+ Parser.ConstantValue{ .number = 0x1234567890abcdef },
+ Parser.ConstantValue{ .number = 'a' },
+ Parser.ConstantValue{ .string = "hello " },
};
for (0..4) |i| {
@@ -992,15 +1015,15 @@ test "basic primaries are identified" {
"$123",
};
- const expected = [_]ExpressionResult{
- ExpressionResult{ .number = NumberValue{ .pure = 1234 } },
- ExpressionResult{ .number = NumberValue{ .pure = 0 } },
- ExpressionResult{ .number = NumberValue{ .pure = 'a' } },
- ExpressionResult{ .string = "hello world" },
- ExpressionResult{ .number = NumberValue{ .pure = 1234 } },
- ExpressionResult{ .number = NumberValue{ .pure = 0xFFFFFFFFFFFFFFFF } },
- ExpressionResult{ .number = NumberValue{ .pure = 0xFFFFFFFFFFFFFFFF } },
- ExpressionResult{ .number = NumberValue{ .register = 123 } },
+ const expected = [_]Parser.ExpressionResult{
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .pure = 1234 } },
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .pure = 0 } },
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .pure = 'a' } },
+ Parser.ExpressionResult{ .string = "hello world" },
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .pure = 1234 } },
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .pure = 0xFFFFFFFFFFFFFFFF } },
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .pure = 0xFFFFFFFFFFFFFFFF } },
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .register = 123 } },
};
for (0..test_cases.len) |i| {
@@ -1048,16 +1071,16 @@ test "valid terms are recognized" {
"\"hello\"",
};
- const expected = [_]ExpressionResult{
- ExpressionResult{ .number = NumberValue{ .pure = 408 } },
- ExpressionResult{ .number = NumberValue{ .pure = 11 } },
- ExpressionResult{ .number = NumberValue{ .pure = 12297829382473034410 } },
- ExpressionResult{ .number = NumberValue{ .pure = 1 } },
- ExpressionResult{ .number = NumberValue{ .pure = 4 } },
- ExpressionResult{ .number = NumberValue{ .pure = 1 } },
- ExpressionResult{ .number = NumberValue{ .pure = 0xAA } },
- ExpressionResult{ .number = NumberValue{ .register = 12 } },
- ExpressionResult{ .string = "hello" },
+ const expected = [_]Parser.ExpressionResult{
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .pure = 408 } },
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .pure = 11 } },
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .pure = 12297829382473034410 } },
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .pure = 1 } },
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .pure = 4 } },
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .pure = 1 } },
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .pure = 0xAA } },
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .register = 12 } },
+ Parser.ExpressionResult{ .string = "hello" },
};
for (0..test_cases.len) |i| {
@@ -1079,10 +1102,10 @@ test "terms compute the entire chain" {
"3*3%8<<2>>1",
};
- const expected = [_]ExpressionResult{
- ExpressionResult{ .number = NumberValue{ .pure = 120 } },
- ExpressionResult{ .number = NumberValue{ .pure = 3 } },
- ExpressionResult{ .number = NumberValue{ .pure = 2 } },
+ const expected = [_]Parser.ExpressionResult{
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .pure = 120 } },
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .pure = 3 } },
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .pure = 2 } },
};
for (0..test_cases.len) |i| {
@@ -1140,25 +1163,25 @@ test "expressions are recognized" {
"$$12",
};
- const expected = [_]ExpressionResult{
- ExpressionResult{ .number = NumberValue{ .pure = 3 } },
- ExpressionResult{ .number = NumberValue{ .pure = 1 } },
- ExpressionResult{ .number = NumberValue{ .pure = 0xFFFFFFFFFFFFFFFF } },
- ExpressionResult{ .number = NumberValue{ .pure = 0xAA } },
- ExpressionResult{ .number = NumberValue{ .pure = 0x55 } },
- ExpressionResult{ .number = NumberValue{ .pure = 30 } },
- ExpressionResult{ .number = NumberValue{ .pure = 50 } },
- ExpressionResult{ .number = NumberValue{ .pure = 0xab00000100 } },
- ExpressionResult{ .string = "hello" },
- ExpressionResult{ .number = NumberValue{ .register = 12 } },
- ExpressionResult{ .number = NumberValue{ .register = 12 } },
+ const expected = [_]Parser.ExpressionResult{
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .pure = 3 } },
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .pure = 1 } },
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .pure = 0xFFFFFFFFFFFFFFFF } },
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .pure = 0xAA } },
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .pure = 0x55 } },
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .pure = 30 } },
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .pure = 50 } },
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .pure = 0xab00000100 } },
+ Parser.ExpressionResult{ .string = "hello" },
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .register = 12 } },
+ Parser.ExpressionResult{ .number = Parser.NumberValue{ .register = 12 } },
};
for (0..test_cases.len) |i| {
var parser = try Parser.init(std.testing.allocator, test_cases[i]);
defer parser.deinit();
- try parser.symbols.put("k", NumberValue{ .pure = 0xcdef00 });
+ try parser.symbols.put("k", Parser.NumberValue{ .pure = 0xcdef00 });
const symbol = try parser.identifyExpression();