The casing conventions have not been set, but there is no universe where
we allow $ as a recommended identifier character. we had this initially
because JavaScript allows it, but in practice people just use it in
frameworks to mean "magic". (see jQuery, Svelte, Qwik, etc)4 files changed, 15 insertions(+), 23 deletions(-)
CHANGELOG.md+3-2| ... | @@ -1,9 +1,10 @@ | ... | @@ -1,9 +1,10 @@ |
| 1 | ## 0.1.4 | 1 | ## 0.1.4 |
| 2 | 2 | ||
| 3 | - feat: implement string identifiers | 3 | - feat: implement basic struct types (#42) |
| 4 | - feat: implement basic struct types | 4 | - feat: implement string identifiers (#54) |
| 5 | - feat: include a `README.html` alongside compiler with documentation and code samples. | 5 | - feat: include a `README.html` alongside compiler with documentation and code samples. |
| 6 | - feat(transform): include a warning for leading zero in numbers | 6 | - feat(transform): include a warning for leading zero in numbers |
| 7 | - feat(tokenizer): `$` is no longer valid in identifiers | ||
| 7 | - fix(sema): miscompilation using left side of all binary expression for both sides | 8 | - fix(sema): miscompilation using left side of all binary expression for both sides |
| 8 | - fix(sema): handle recursive function calls | 9 | - fix(sema): handle recursive function calls |
| 9 | - fix(sema): quit block analysis when hitting `noreturn` | 10 | - fix(sema): quit block analysis when hitting `noreturn` |
src/core/Report.zig+1-6| ... | @@ -1130,12 +1130,7 @@ fn formatIdImpl( | ... | @@ -1130,12 +1130,7 @@ fn formatIdImpl( |
| 1130 | var i: usize = 0; | 1130 | var i: usize = 0; |
| 1131 | while (i < inner.len) { | 1131 | while (i < inner.len) { |
| 1132 | switch (inner[i]) { | 1132 | switch (inner[i]) { |
| 1133 | 'a'...'z', | 1133 | 'a'...'z', 'A'...'Z', '0'...'9', '_' => { |
| 1134 | 'A'...'Z', | ||
| 1135 | '0'...'9', | ||
| 1136 | '_', | ||
| 1137 | '$', | ||
| 1138 | => { | ||
| 1139 | i += 1; | 1134 | i += 1; |
| 1140 | continue; | 1135 | continue; |
| 1141 | }, | 1136 | }, |
src/core/Tokenizer.zig+3-3| ... | @@ -322,7 +322,7 @@ pub fn next(t: *Tokenizer) !?Token { | ... | @@ -322,7 +322,7 @@ pub fn next(t: *Tokenizer) !?Token { |
| 322 | switch (t.byte()) { | 322 | switch (t.byte()) { |
| 323 | ' ', '\t', '\n', '\r' => unreachable, // call skipWhitespace | 323 | ' ', '\t', '\n', '\r' => unreachable, // call skipWhitespace |
| 324 | 324 | ||
| 325 | 'a'...'z', 'A'...'Z', '_', '$' => { | 325 | 'a'...'z', 'A'...'Z', '_' => { |
| 326 | const start = t.pos; | 326 | const start = t.pos; |
| 327 | t.pos += 1; | 327 | t.pos += 1; |
| 328 | return try t.tokenizeIdentifier(start); | 328 | return try t.tokenizeIdentifier(start); |
| ... | @@ -563,7 +563,7 @@ fn codePoint(t: Tokenizer) !struct { u3, u21 } { | ... | @@ -563,7 +563,7 @@ fn codePoint(t: Tokenizer) !struct { u3, u21 } { |
| 563 | 563 | ||
| 564 | fn isAtIdentifierStart(t: *Tokenizer) !bool { | 564 | fn isAtIdentifierStart(t: *Tokenizer) !bool { |
| 565 | switch (t.byte()) { | 565 | switch (t.byte()) { |
| 566 | 'a'...'z', 'A'...'Z', '_', '$' => return true, | 566 | 'a'...'z', 'A'...'Z', '_' => return true, |
| 567 | else => return false, | 567 | else => return false, |
| 568 | 0x80...0xFF => { | 568 | 0x80...0xFF => { |
| 569 | _, const code_point = try t.codePoint(); | 569 | _, const code_point = try t.codePoint(); |
| ... | @@ -578,7 +578,7 @@ fn tokenizeIdentifier(t: *Tokenizer, start_byte: u32) !Token { | ... | @@ -578,7 +578,7 @@ fn tokenizeIdentifier(t: *Tokenizer, start_byte: u32) !Token { |
| 578 | 578 | ||
| 579 | while (true) { | 579 | while (true) { |
| 580 | switch (t.byte()) { | 580 | switch (t.byte()) { |
| 581 | 'a'...'z', 'A'...'Z', '0'...'9', '_', '$' => { | 581 | 'a'...'z', 'A'...'Z', '0'...'9', '_' => { |
| 582 | t.pos += 1; | 582 | t.pos += 1; |
| 583 | }, | 583 | }, |
| 584 | 0x80...0xFF => { | 584 | 0x80...0xFF => { |
src/core/Transform.zig+8-12| ... | @@ -6,8 +6,8 @@ | ... | @@ -6,8 +6,8 @@ |
| 6 | //! - Annotating expression statements with `.discard` and `.ensure_void` | 6 | //! - Annotating expression statements with `.discard` and `.ensure_void` |
| 7 | //! - Flattening nested expressions into instruction sequences. | 7 | //! - Flattening nested expressions into instruction sequences. |
| 8 | //! | 8 | //! |
| 9 | //! Some trivial diagnostics such as unused variables, unknown result locations, and | 9 | //! Some trivial diagnostics such as unused variables, unknown result types, |
| 10 | //! invalid assignment targets are also reported here. | 10 | //! invalid assignment targets, and other style issues are also reported here. |
| 11 | gpa: Allocator, | 11 | gpa: Allocator, |
| 12 | ast: Ast, | 12 | ast: Ast, |
| 13 | insts: Inst.List = .{}, | 13 | insts: Inst.List = .{}, |
| ... | @@ -22,9 +22,9 @@ scopes: std.ArrayListUnmanaged(Scope) = .{}, | ... | @@ -22,9 +22,9 @@ scopes: std.ArrayListUnmanaged(Scope) = .{}, |
| 22 | report: Report.Builder, | 22 | report: Report.Builder, |
| 23 | 23 | ||
| 24 | pub const Error = error{ | 24 | pub const Error = error{ |
| 25 | OutOfMemory, | 25 | /// A `Report` will contain at least one error. |
| 26 | TransformFail, | 26 | TransformFail, |
| 27 | }; | 27 | } || Allocator.Error; |
| 28 | 28 | ||
| 29 | pub fn transform( | 29 | pub fn transform( |
| 30 | ast: Ast, | 30 | ast: Ast, |
| ... | @@ -61,7 +61,7 @@ pub fn transform( | ... | @@ -61,7 +61,7 @@ pub fn transform( |
| 61 | 61 | ||
| 62 | try t.insts.setCapacity(t.gpa, t.insts.len); | 62 | try t.insts.setCapacity(t.gpa, t.insts.len); |
| 63 | 63 | ||
| 64 | return Teg{ | 64 | return .{ |
| 65 | .insts = t.insts.toOwnedSlice(), | 65 | .insts = t.insts.toOwnedSlice(), |
| 66 | .string_bytes = try t.string_bytes.toOwnedSlice(t.gpa), | 66 | .string_bytes = try t.string_bytes.toOwnedSlice(t.gpa), |
| 67 | .extra = try t.extra.toOwnedStore(t.gpa), | 67 | .extra = try t.extra.toOwnedStore(t.gpa), |
| ... | @@ -142,18 +142,14 @@ const Scope = struct { | ... | @@ -142,18 +142,14 @@ const Scope = struct { |
| 142 | } | 142 | } |
| 143 | }; | 143 | }; |
| 144 | 144 | ||
| 145 | const ScratchType = enum { | ||
| 146 | ref, | ||
| 147 | index, | ||
| 148 | }; | ||
| 149 | |||
| 150 | const BlockContext = struct { | 145 | const BlockContext = struct { |
| 151 | node_base: i32, | 146 | node_base: i32, |
| 152 | return_target: ?*?Inst.Index = null, | 147 | return_target: ?*?Inst.Index = null, |
| 153 | break_target: ?*BreakTarget = null, | 148 | break_target: ?*BreakTarget = null, |
| 154 | 149 | ||
| 155 | /// This struct is always stored on the stack; the idea is to pass | 150 | /// This struct is always stored on the stack; the idea is to pass mutable |
| 156 | /// mutable pointers to it. When `break :brk` is encountered | 151 | /// pointers to it. When `break :brk` is encountered, it will generate the |
| 152 | /// block instruction. This way, redundant blocks are never created. | ||
| 157 | const BreakTarget = struct { | 153 | const BreakTarget = struct { |
| 158 | label: ?[]const u8, | 154 | label: ?[]const u8, |
| 159 | /// This allows `continue` as well as implicit break targeting. | 155 | /// This allows `continue` as well as implicit break targeting. |