Skip to content

Commit

Permalink
feat: char literal
Browse files Browse the repository at this point in the history
closes #172
  • Loading branch information
giann committed Sep 6, 2023
1 parent 02b0dfe commit e8157c1
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
- `Buffer.readUserData`, `Buffer.writeUserData`
- `std.serialize` takes any buzz value and return a serializable version of it (objects become maps, etc.) provided the data is has no circular reference and does not contain not serializable values (functions, fibers, etc.)
- UTF8 helpers: `str.utf8Len`, `str.utf8Codepoints`, `str.utf8Valid`
- New integer literal for single chars: `'A' == 65`

## Changed

Expand Down
6 changes: 5 additions & 1 deletion src/lib/serialize.buzz
Original file line number Diff line number Diff line change
Expand Up @@ -356,5 +356,9 @@ export fun jsonEncode(Boxed data) > str !> CircularReference, NotSerializable {
|| @param str json The JSON string
|| @return Boxed
export fun jsonDecode(str json) > Boxed !> JsonParseError, WriteWhileReadingError {
return Boxed{ data = JsonParser{ source = json }.next() };
return Boxed{
data = JsonParser{
source = json
}.next()
};
}
37 changes: 37 additions & 0 deletions src/scanner.zig
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ pub const Scanner = struct {
'=' => self.makeToken(if (self.match('=')) .EqualEqual else .Equal, null, null, null),
'"' => self.string(false),
'`' => self.string(true),
'\'' => self.byte(),
'@' => self.atIdentifier(),
'|' => self.docblock(),
'$' => self.pattern(),
Expand Down Expand Up @@ -276,6 +277,42 @@ pub const Scanner = struct {
);
}

fn byte(self: *Self) Token {
const is_escape_sequence = self.match('\\');
const literal_integer = if (is_escape_sequence)
self.advance()
else
self.advance();

if (is_escape_sequence and literal_integer != '\\' and literal_integer != '\'') {
return self.makeToken(
.Error,
"Invalid escape sequence in char literal.",
null,
null,
);
}

// Skip closing
if (self.isEOF() or self.peek() != '\'') {
return self.makeToken(
.Error,
"Unterminated char literal.",
null,
null,
);
} else {
_ = self.advance();
}

return self.makeToken(
.IntegerValue,
null,
null,
@intCast(literal_integer),
);
}

fn binary(self: *Self) !Token {
var peeked: u8 = self.peek();
while (peeked == '0' or peeked == '1') {
Expand Down
16 changes: 16 additions & 0 deletions tests/001-basic-types.buzz
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
import "std";

test "Basic types" {
str string = "hello world";
float floating = 3.14;
int integer = 3;
bool boolean = true;
}

test "Char literal" {
int char = 'A';

assert(char == 65, message: "Could use char literal");

int quote = '\'';

assert(quote == 39, message: "Could escape ' in char literal");

int slash = '\\';

assert(slash == 92, message: "Could escape \\ in char literal");
}

0 comments on commit e8157c1

Please sign in to comment.