Skip to content

Commit

Permalink
Merge pull request #5 from probably-neb/merging_int_arr
Browse files Browse the repository at this point in the history
Int Array
  • Loading branch information
dleiferives authored May 14, 2024
2 parents 83cfa93 + 6326014 commit fe767d9
Show file tree
Hide file tree
Showing 8 changed files with 520 additions and 72 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
zig-cache
zig-out
/kcov-output/
TODO.dylan
5 changes: 4 additions & 1 deletion Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ run-suite-test name: ensure-test-suite
echo -e "${BLUE}Building Test Suite Test...${NC}"
just build-suite-test {{name}}
echo -e "${GREEN}BUILD SUCCESS${NC}"

dir="{{TEST_SUITE}}/{{name}}"
bin="$dir/{{name}}"

Expand All @@ -71,6 +72,8 @@ run-suite-test name: ensure-test-suite
build-suite-test name: build
#!/usr/bin/env bash
set -euxo pipefail
name="{{name}}"
name="${name#array_}"
dir="{{TEST_SUITE}}/{{name}}"
{{minipp}} -i "$dir/{{name}}.mini" -o "$dir/{{name}}.ll"
{{minipp}} -i "$dir/${name}.mini" -o "$dir/{{name}}.ll"
clang "$dir/{{name}}.ll" -o "$dir/{{name}}"
5 changes: 3 additions & 2 deletions mini.ebnf
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ types -> {type-declaration}∗
type-declaration -> 'struct' id '{' nested-decl '}' ';'
nested-decl -> decl ';' { decl ';'}∗
decl -> 'type' id
type -> 'int' | 'bool' | 'struct' id
type -> 'int' | 'bool' | 'struct' id | 'int_array'
declarations -> {declaration}∗
declaration -> 'type' id-list ';'
id-list -> id {',' id}∗
Expand All @@ -30,6 +30,7 @@ simple -> term {{ '+' | '−' } term}∗
term -> unary {{ '' | '/' } unary}∗
unary -> { '!' | '' }∗ selector
selector -> factor {'.' id}∗
factor -> '(' expression ')' | id {arguments}opt | number | 'true' | 'false' | 'new' id | 'null'
factor -> '(' expression ')' | id {arguments}opt | number | 'true' |
| 'false' | 'new' id | 'null' | 'new' 'int_array' '[' number ']' |
arguments -> '(' {expression { ',' expression}∗}opt ')'
number -> {'0' | '1' | ... | '9'}{ '0' | '1' | ... | '9'}∗
32 changes: 31 additions & 1 deletion src/ast.zig
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ pub const Node = struct {
.BoolType,
.IntType,
.StructType,
.IntArrayType,
}),
/// when kind is `StructType` points to the idenfifier
/// of the struct
Expand All @@ -203,6 +204,7 @@ pub const Node = struct {
BoolType,
IntType,
StructType,
IntArrayType,
Void,
Read,
Identifier,
Expand Down Expand Up @@ -445,7 +447,13 @@ pub const Node = struct {
},
/// A chain of `.ident` selectors
SelectorChain: struct {
ident: Ref(.Identifier),
/// TODO: change ident to something that can be used for array access
/// and struct access
ident: RefOneOf(.{
.Identifier,
// Expression is used for array access
.Expression,
}),
/// Pointer to `SelectorChain`
/// null if last in chain
next: ?Ref(.SelectorChain) = null,
Expand Down Expand Up @@ -556,6 +564,10 @@ pub const Node = struct {
/// pointer to the identifier being allocated
ident: Ref(.Identifier),
},
NewIntArray: struct {
/// The space to allocate for the array
length: Ref(.Number),
},
/// keyword `null`
Null,
/// This is a special node that is used to reserve space for the AST
Expand Down Expand Up @@ -773,6 +785,7 @@ pub const Node = struct {
const name = nameToken._range.getSubStrFromStr(ast.input);
return .{ .Struct = name };
},
.IntArrayType => return .IntArray,
else => unreachable,
}
} else {
Expand Down Expand Up @@ -801,6 +814,7 @@ pub const Node = struct {
const name = nameToken._range.getSubStrFromStr(ast.input);
return .{ .Struct = name };
},
.IntArrayType => return .IntArray,
else => unreachable,
}
}
Expand Down Expand Up @@ -884,6 +898,7 @@ pub const Node = struct {
pub const Type = union(enum) {
Bool,
Int,
IntArray,
Null,
Void,
Struct: []const u8,
Expand Down Expand Up @@ -946,6 +961,7 @@ const KindTagDupe = enum {
BoolType,
IntType,
StructType,
IntArrayType,
Void,
Read,
Identifier,
Expand Down Expand Up @@ -1349,3 +1365,17 @@ test "ast.getGloablStructTypeFromName_notFound" {
const ty = ast.getDeclarationGlobalFromName("b");
try ting.expect(ty == null);
}

test "ast.int_array_main" {
errdefer log.print();
const input = "fun main() void { int_array a; a = new int_array[10]; }";
var ast = try testMe(input);
_ = ast.getFunctionDeclarationTypeFromName("main", "a");
}

test "ast.int_array_access" {
errdefer log.print();
const input = "fun main() void { int_array a; a = new int_array[10]; a[0] = 1; }";
var ast = try testMe(input);
_ = ast;
}
1 change: 1 addition & 0 deletions src/ir/ir.zig
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ pub fn astTypeToIRType(self: *IR, astType: Ast.Type) Type {
.Bool => .bool,
.Void => .void,
.Null => std.debug.panic("FUCK WE HAVE TO HANDLE NULL TYPE\n", .{}),
.IntArray => utils.todo("Handle the array type", .{}),
.Struct => |name| blk: {
const structID = self.internIdent(name);
break :blk .{ .strct = structID };
Expand Down
73 changes: 67 additions & 6 deletions src/lexer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ pub const TokenKind = enum {
RParen,
LCurly,
RCurly,
LBracket,
RBracket,
Semicolon,
Eof,
Or,
Expand All @@ -118,6 +120,7 @@ pub const TokenKind = enum {
KeywordTrue,
KeywordVoid,
KeywordWhile,
KeywordIntArray,
Unset,

// NOTE: bool, int, void shouldn't be valid keywords, (valid /type/ names)
Expand All @@ -142,6 +145,7 @@ pub const TokenKind = enum {
.{ "true", TokenKind.KeywordTrue },
.{ "void", TokenKind.KeywordVoid },
.{ "while", TokenKind.KeywordWhile },
.{ "int_array", TokenKind.KeywordIntArray },
});

pub fn equals(self: TokenKind, other: TokenKind) bool {
Expand Down Expand Up @@ -250,7 +254,7 @@ pub const Lexer = struct {
lxr.skip_whitespace();

const info: TokInfo = switch (lxr.ch) {
'a'...'z', 'A'...'Z' => lxr.ident_or_builtin(),
'a'...'z', 'A'...'Z' => try lxr.ident_or_builtin(),
'0'...'9' => .{ .kind = TokenKind.Number, .range = try lxr.read_number() },
else => blk: {
const pos = lxr.pos;
Expand Down Expand Up @@ -328,19 +332,29 @@ pub const Lexer = struct {
}
}

fn read_ident(lxr: *Lexer) Range {
fn read_ident(lxr: *Lexer) !Range {
const pos = lxr.pos;
// NOTE: no need to check first char is not numeric here
// because if first char was numeric we would have called
// read_number instead
while (std.ascii.isAlphanumeric(lxr.ch)) {
var hasUnderscore = false;
while (std.ascii.isAlphanumeric(lxr.ch) or lxr.ch == '_') {
hasUnderscore = hasUnderscore or lxr.ch == '_';
lxr.step();
}
return Range{ .start = pos, .end = lxr.pos };
const range = Range{ .start = pos, .end = lxr.pos };
if (hasUnderscore) {
const ident = lxr.slice(range);
if (!std.mem.eql(u8, ident, "int_array")) {
log.err("error: only ident allowed to have underscore is `int_array` not {s}\n", .{ident});
return error.InvalidToken;
}
}
return range;
}

fn ident_or_builtin(lxr: *Lexer) TokInfo {
const range = lxr.read_ident();
fn ident_or_builtin(lxr: *Lexer) !TokInfo {
const range = try lxr.read_ident();
const ident = lxr.slice(range);
const kw = TokenKind.keywords.get(ident);
if (kw) |kw_kind| {
Expand Down Expand Up @@ -371,6 +385,8 @@ pub const Lexer = struct {
')' => .RParen,
'{' => .LCurly,
'}' => .RCurly,
'[' => .LBracket,
']' => .RBracket,
'+' => .Plus,
'*' => .Mul,
'/' => .Div,
Expand Down Expand Up @@ -454,6 +470,18 @@ test "add" {
defer testAlloc.free(tokens);
}

test "brackets" {
const tokens = try expect_results_in_tokens("new int_array[10]", &[_]TokenKind{
.KeywordNew,
.KeywordIntArray,
.LBracket,
.Number,
.RBracket,
.Eof,
});
defer testAlloc.free(tokens);
}

test "simple_struct" {
const content = "struct SimpleStruct { int x; int y; }";
const tokens = try expect_results_in_tokens(content, &[_]TokenKind{
Expand Down Expand Up @@ -583,3 +611,36 @@ test "comment" {
});
defer testAlloc.free(tokens);
}

test "lexer.checkArrayAccess" {
const source = "fun main() void {int_array a; a = new int_array[10]; a[0] = 1;}";
const tokens = try expect_results_in_tokens(source, &[_]TokenKind{
.KeywordFun,
.Identifier,
.LParen,
.RParen,
.KeywordVoid,
.LCurly,
.KeywordIntArray,
.Identifier,
.Semicolon,
.Identifier,
.Eq,
.KeywordNew,
.KeywordIntArray,
.LBracket,
.Number,
.RBracket,
.Semicolon,
.Identifier,
.LBracket,
.Number,
.RBracket,
.Eq,
.Number,
.Semicolon,
.RCurly,
.Eof,
});
defer testAlloc.free(tokens);
}
Loading

0 comments on commit fe767d9

Please sign in to comment.