From: Brendan Hansen Date: Wed, 8 Mar 2023 12:24:45 +0000 (-0600) Subject: added: single quote character literals X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=7f3294f2a23f62f727543083e9c79b13aed35c9b;p=onyx.git added: single quote character literals changed: no re-declaration specifier is now `~` --- diff --git a/compiler/include/lex.h b/compiler/include/lex.h index cd437ece..23818d58 100644 --- a/compiler/include/lex.h +++ b/compiler/include/lex.h @@ -74,6 +74,7 @@ typedef enum TokenType { Token_Type_Symbol, Token_Type_Literal_String, + Token_Type_Literal_Char, Token_Type_Literal_Integer, Token_Type_Literal_Float, Token_Type_Literal_True, diff --git a/compiler/src/lex.c b/compiler/src/lex.c index 46c466b9..3e4a91c7 100644 --- a/compiler/src/lex.c +++ b/compiler/src/lex.c @@ -71,6 +71,7 @@ static const char* token_type_names[] = { "TOKEN_TYPE_SYMBOL", "TOKEN_TYPE_LITERAL_STRING", + "TOKEN_TYPE_LITERAL_CHAR", "TOKEN_TYPE_LITERAL_INTEGER", "TOKEN_TYPE_LITERAL_FLOAT", "true", @@ -243,14 +244,15 @@ whitespace_skipped: goto token_parsed; } - // String literal - if (*tk.text == '"') { + // String/Character literal + if (*tk.text == '"' || *tk.text == '\'') { u64 len = 0; u64 slash_count = 0; + char ch = *tk.text; INCREMENT_CURR_TOKEN(tokenizer); - while (!(*tokenizer->curr == '"' && slash_count == 0)) { + while (!(*tokenizer->curr == ch && slash_count == 0)) { len++; // if (*tokenizer->curr == '\n') { @@ -270,7 +272,7 @@ whitespace_skipped: INCREMENT_CURR_TOKEN(tokenizer); tk.text++; - tk.type = Token_Type_Literal_String; + tk.type = ch == '"' ? Token_Type_Literal_String : Token_Type_Literal_Char; tk.length = len; goto token_parsed; } diff --git a/compiler/src/parser.c b/compiler/src/parser.c index 465ae793..c6cbccce 100644 --- a/compiler/src/parser.c +++ b/compiler/src/parser.c @@ -605,6 +605,25 @@ static AstTyped* parse_factor(OnyxParser* parser) { break; } + case Token_Type_Literal_Char: { + AstNumLit* char_lit = make_node(AstNumLit, Ast_Kind_NumLit); + char_lit->flags |= Ast_Flag_Comptime; + char_lit->type_node = (AstType *) &basic_type_int_unsized; + char_lit->token = expect_token(parser, Token_Type_Literal_Char); + char_lit->was_char_literal = 1; + + i8 dest = '\0'; + i32 length = string_process_escape_seqs((char *) &dest, char_lit->token->text, 1); + char_lit->value.i = (u32) dest; + + if (length != 1) { + onyx_report_error(char_lit->token->pos, Error_Critical, "Expected only a single character in character literal."); + } + + retval = (AstTyped *) char_lit; + break; + } + case '#': { if (parse_possible_directive(parser, "file_contents")) { AstFileContents* fc = make_node(AstFileContents, Ast_Kind_File_Contents); @@ -1322,7 +1341,7 @@ static i32 parse_possible_compound_symbol_declaration(OnyxParser* parser, AstNod while (peek_token(token_offset)->type == Token_Type_Symbol) { token_offset += 1; - if (peek_token(token_offset)->type == '\'') token_offset += 1; + if (peek_token(token_offset)->type == '~') token_offset += 1; if (peek_token(token_offset)->type != ',') break; token_offset += 1; @@ -1344,7 +1363,7 @@ static i32 parse_possible_compound_symbol_declaration(OnyxParser* parser, AstNod AstNode* sym_node = make_symbol(parser->allocator, local_sym); bh_arr_push(local_compound->exprs, (AstTyped *) sym_node); - if (!consume_token_if_next(parser, '\'')) { + if (!consume_token_if_next(parser, '~')) { AstLocal* new_local = make_local(parser->allocator, local_sym, NULL); if (prev_local == NULL) { first_local = new_local; @@ -1394,7 +1413,7 @@ static i32 parse_possible_symbol_declaration(OnyxParser* parser, AstNode** ret) // If the token after the symbol is a comma, assume this is a compound declaration. if (peek_token(1)->type == ',' || - (peek_token(1)->type == '\'' && peek_token(2)->type == ',')) { + (peek_token(1)->type == '~' && peek_token(2)->type == ',')) { return parse_possible_compound_symbol_declaration(parser, ret); } diff --git a/core/conv/format.onyx b/core/conv/format.onyx index e6e3a564..3c0dc145 100644 --- a/core/conv/format.onyx +++ b/core/conv/format.onyx @@ -443,7 +443,7 @@ format_any :: (output: &Format_Output, formatting: &Format, v: any) { case u8 { value := *(cast(&u8) v.data); - if value > 31 { + if formatting.interpret_numbers { output->write(value); } else { diff --git a/core/string/string.onyx b/core/string/string.onyx index ba6e4c66..07fa5d97 100644 --- a/core/string/string.onyx +++ b/core/string/string.onyx @@ -651,6 +651,10 @@ bisect :: (s: str, substr: str) -> (str, str) { // Used by dyn_str // +to_dyn_str :: (x: str, allocator := context.allocator) -> dyn_str { + return (package core.array).make(x, allocator); +} + delete :: macro (x: &dyn_str, idx: u32) -> u8 { return (package core.array).delete(x, idx); } diff --git a/core/time/date.onyx b/core/time/date.onyx index ec865414..9e2e99cd 100644 --- a/core/time/date.onyx +++ b/core/time/date.onyx @@ -81,8 +81,8 @@ Date :: struct { @conv.Custom_Parse_Proc.{ Date } (d: &Date, text: str, _: Allocator) -> bool { year, t := string.bisect(text, #char "-"); - month, t' := string.bisect(t, #char "-"); - day, t' := string.bisect(t, #char "-"); + month, t~ := string.bisect(t, #char "-"); + day, t~ := string.bisect(t, #char "-"); d.year = ~~ conv.str_to_i64(year); d.month = ~~ (conv.str_to_i64(month) - 1); diff --git a/examples/50_misc.onyx b/examples/50_misc.onyx index feb89ef5..4b0e4b75 100644 --- a/examples/50_misc.onyx +++ b/examples/50_misc.onyx @@ -47,10 +47,10 @@ multiple_declaration_improvements :: () { // You're trying to declare a new variable k, while using the old variable // s in the same declaration. To get around this issue, there is a special // syntax you can use that tell the compiler that s is a not a new - // variable, but the same one as above. You simple place a ' after the + // variable, but the same one as above. You simple place a ~ after the // variable that you want to reuse. - k, s' := multiple_returns(); + k, s~ := multiple_returns(); printf("k: {}\ns: {}\n\n", k, s); // diff --git a/misc/onyx-mode.el b/misc/onyx-mode.el index 5f8e5ab6..338e7c4d 100644 --- a/misc/onyx-mode.el +++ b/misc/onyx-mode.el @@ -97,6 +97,8 @@ ;; Strings ("\\\".*\\\"" . font-lock-string-face) + ("\\\'.*\\\'" . font-lock-string-face) + ;; Numbers (,(onyx-wrap-word-rx onyx-number-rx) . font-lock-constant-face) diff --git a/misc/onyx.sublime-syntax b/misc/onyx.sublime-syntax index 1bbf0fea..3f917e28 100644 --- a/misc/onyx.sublime-syntax +++ b/misc/onyx.sublime-syntax @@ -15,6 +15,9 @@ contexts: - match: '"' scope: punctuation.definition.string.begin.onyx push: double_quoted_string + - match: "'" + scope: punctuation.definition.string.begin.onyx + push: single_quoted_string # Comments begin with a '//' and finish at the end of the line - match: '//' @@ -92,6 +95,14 @@ contexts: # 1: variable # 2: variable + single_quoted_string: + - meta_scope: string.quoted.single.onyx + - match: '\\.' + scope: constant.character.escape.onyx + - match: "'" + scope: punctuation.definition.string.end.onyx + pop: true + double_quoted_string: - meta_scope: string.quoted.double.onyx - match: '\\.' diff --git a/misc/onyx.vim b/misc/onyx.vim index 53eccd91..0eb3647a 100644 --- a/misc/onyx.vim +++ b/misc/onyx.vim @@ -49,6 +49,7 @@ syn match onyxDirective "\#[a-zA-Z_]\+" syn match onyxTag "@[a-zA-Z0-9_]\+" syn region onyxString start=+"+ skip=+\\\\\|\\"+ end=+"\|$+ extend contains=@Spell +syn region onyxString start=+'+ skip=+\\\\\|\\'+ end=+'\|$+ extend contains=@Spell syn region onyxMultiString start=+"""+ end=+"""+ extend contains=@Spell hi def link onyxKeyword Statement diff --git a/misc/vscode/onyx-0.1.5.vsix b/misc/vscode/onyx-0.1.5.vsix index 82722466..e0dbf32b 100644 Binary files a/misc/vscode/onyx-0.1.5.vsix and b/misc/vscode/onyx-0.1.5.vsix differ diff --git a/tests/aoc-2020/day11.onyx b/tests/aoc-2020/day11.onyx index e8be0fa7..ca09764b 100644 --- a/tests/aoc-2020/day11.onyx +++ b/tests/aoc-2020/day11.onyx @@ -76,7 +76,7 @@ main :: (args: [] cstr) { gos.height = 0; while !string.empty(file) { - line, file' := string.bisect(file, #char "\n"); + line, file~ := string.bisect(file, #char "\n"); for ch: line do switch ch { case #char "." do array.push(&gos.seats, SeatState.Floor); case #char "L" do array.push(&gos.seats, SeatState.Empty); diff --git a/tests/aoc-2020/day14.onyx b/tests/aoc-2020/day14.onyx index 080c7c1c..f031e09b 100644 --- a/tests/aoc-2020/day14.onyx +++ b/tests/aoc-2020/day14.onyx @@ -89,7 +89,7 @@ main :: (args: [] cstr) { string.advance(&file, 3); i := 35; - m, file' := string.bisect(file, #char "\n"); + m, file~ := string.bisect(file, #char "\n"); for ch: m { switch ch { case #char "0" do mask[i] = 0; diff --git a/tests/aoc-2020/day17.onyx b/tests/aoc-2020/day17.onyx index 59f77091..eb3ef596 100644 --- a/tests/aoc-2020/day17.onyx +++ b/tests/aoc-2020/day17.onyx @@ -60,7 +60,7 @@ main :: (args: [] cstr) { z := 0; while !string.empty(file) { - line, file' := string.bisect(file, #char "\n"); + line, file~ := string.bisect(file, #char "\n"); x := 0; for ch: line { diff --git a/tests/aoc-2020/day19.onyx b/tests/aoc-2020/day19.onyx index 6d14bfb5..955f5602 100644 --- a/tests/aoc-2020/day19.onyx +++ b/tests/aoc-2020/day19.onyx @@ -162,7 +162,7 @@ main :: (args: [] cstr) { valid_count := 0; string.advance_line(&file); while !string.empty(file) { - line, file' := string.bisect(file, #char "\n"); + line, file~ := string.bisect(file, #char "\n"); if cyk_algorithm(&grammar, line) do valid_count += 1; } diff --git a/tests/aoc-2020/day20.onyx b/tests/aoc-2020/day20.onyx index 7a4eecd4..7ddf6a8a 100644 --- a/tests/aoc-2020/day20.onyx +++ b/tests/aoc-2020/day20.onyx @@ -267,7 +267,7 @@ main :: (args: [] cstr) { td := cast(&bool) raw_alloc(tile_allocator, sizeof TileData); for y: 0 .. 10 { - line, file' := string.bisect(file, #char "\n"); + line, file~ := string.bisect(file, #char "\n"); for x: 0 .. 10 { td[x + y * TILE_DATA_WIDTH] = (line[x] == #char "#"); diff --git a/tests/char_literals b/tests/char_literals new file mode 100644 index 00000000..03d094e4 --- /dev/null +++ b/tests/char_literals @@ -0,0 +1,4 @@ +az +r is the 17 of the alphabet. + +Something else diff --git a/tests/char_literals.onyx b/tests/char_literals.onyx new file mode 100644 index 00000000..af73600b --- /dev/null +++ b/tests/char_literals.onyx @@ -0,0 +1,20 @@ +use core + + +main :: () { + s: dyn_str; + defer string.free(&s); + + string.append(&s, .['a', 'z']); + + println(s); + + + + x := 'r' - 'a'; + printf("{} is the {} of the alphabet.\n", 'r', x); + + a_newline := '\n'; + printf("{}", a_newline); + println("Something else"); +} \ No newline at end of file