Skip to content

Commit

Permalink
add raw string literals
Browse files Browse the repository at this point in the history
  • Loading branch information
Christopher James committed Oct 25, 2024
1 parent 1d20376 commit bd65033
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 1 deletion.
26 changes: 25 additions & 1 deletion bootstrap/stage0.c
Original file line number Diff line number Diff line change
Expand Up @@ -2119,6 +2119,7 @@ void compiler_lexer_Lexer_inc(compiler_lexer_Lexer *this);
char compiler_lexer_Lexer_peek(compiler_lexer_Lexer *this, u32 offset);
void compiler_lexer_Lexer_lex_char_literal(compiler_lexer_Lexer *this);
void compiler_lexer_Lexer_lex_string_literal(compiler_lexer_Lexer *this, bool has_seen_f);
void compiler_lexer_Lexer_lex_raw_string_literal(compiler_lexer_Lexer *this);
compiler_tokens_Token *compiler_lexer_Lexer_lex_int_literal_different_base(compiler_lexer_Lexer *this);
compiler_tokens_Token *compiler_lexer_Lexer_lex_numeric_literal_helper(compiler_lexer_Lexer *this);
void compiler_lexer_Lexer_lex_numeric_literal(compiler_lexer_Lexer *this);
Expand Down Expand Up @@ -10567,6 +10568,26 @@ void compiler_lexer_Lexer_lex_string_literal(compiler_lexer_Lexer *this, bool ha
compiler_lexer_Lexer_push(this, compiler_tokens_Token_new(compiler_tokens_TokenType_StringLiteral, (std_span_Span){.start=start_loc, .end=this->loc}, text));
}}

void compiler_lexer_Lexer_lex_raw_string_literal(compiler_lexer_Lexer *this) {
std_span_Location start_loc = this->loc;
char end_char = compiler_lexer_Lexer_cur(this);
u32 start = (this->i + 1);
std_buffer_Buffer buffer = std_buffer_Buffer_make(16);
compiler_lexer_Lexer_inc(this);
while ((this->i < this->source_len) && (compiler_lexer_Lexer_cur(this) != end_char)) {
if (compiler_lexer_Lexer_cur(this)=='\\') {
std_buffer_Buffer_write_char(&buffer, '\\');
}
std_buffer_Buffer_write_char(&buffer, compiler_lexer_Lexer_cur(this));
compiler_lexer_Lexer_inc(this);
}
compiler_lexer_Lexer_inc(this);
if (this->i >= this->source_len) {
std_vector_Vector__11_push(this->errors, compiler_errors_Error_new((std_span_Span){.start=this->loc, .end=this->loc}, "Unterminated string literal"));
}
compiler_lexer_Lexer_push(this, compiler_tokens_Token_new(compiler_tokens_TokenType_StringLiteral, (std_span_Span){.start=start_loc, .end=this->loc}, std_buffer_Buffer_str(buffer)));
}

compiler_tokens_Token *compiler_lexer_Lexer_lex_int_literal_different_base(compiler_lexer_Lexer *this) {
std_span_Location start_loc = this->loc;
u32 start = this->i;
Expand All @@ -10585,7 +10606,7 @@ compiler_tokens_Token *compiler_lexer_Lexer_lex_int_literal_different_base(compi
}
} break;
default: {
if(!(false)) { ae_assert_fail("/home/mindful-dev/ocen/compiler/lexer.oc:150:24: Assertion failed: `false`", "Invalid base for int literal"); exit(1); }
if(!(false)) { ae_assert_fail("/home/mindful-dev/ocen/compiler/lexer.oc:173:24: Assertion failed: `false`", "Invalid base for int literal"); exit(1); }
} break;
}
u32 len = (this->i - start);
Expand Down Expand Up @@ -10843,6 +10864,9 @@ std_vector_Vector__9 *compiler_lexer_Lexer_lex(compiler_lexer_Lexer *this) {
if (c=='f' && compiler_lexer_Lexer_peek(this, 1)=='"') {
compiler_lexer_Lexer_inc(this);
compiler_lexer_Lexer_lex_string_literal(this, true);
} else if (c=='r' && compiler_lexer_Lexer_peek(this, 1)=='"') {
compiler_lexer_Lexer_inc(this);
compiler_lexer_Lexer_lex_raw_string_literal(this);
} else if (char_is_digit(c)) {
compiler_lexer_Lexer_lex_numeric_literal(this);
} else if (char_is_alpha(c) || c=='_') {
Expand Down
27 changes: 27 additions & 0 deletions compiler/lexer.oc
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,29 @@ def Lexer::lex_string_literal(&this, has_seen_f: bool) {
}
}

def Lexer::lex_raw_string_literal(&this) {
let start_loc = .loc
let end_char = .cur()
let start = .i + 1
let buffer = Buffer::make()
.inc()
while .i < .source_len and .cur() != end_char {
if .cur() == '\\' {
buffer += '\\'
}
buffer += .cur()
.inc()
}

.inc()

if .i >= .source_len {
.errors.push(Error::new(Span(.loc, .loc), "Unterminated string literal"))
}

.push(Token::new(StringLiteral, Span(start_loc, .loc), buffer.str()))
}

def Lexer::lex_int_literal_different_base(&this): &Token {
let start_loc = .loc
let start = .i
Expand Down Expand Up @@ -306,6 +329,10 @@ def Lexer::lex(&this): &Vector<&Token> {
.inc()
.lex_string_literal(has_seen_f: true)
}
c == 'r' and .peek(1) == '"' => {
.inc()
.lex_raw_string_literal()
}
c.is_digit() => .lex_numeric_literal()
c.is_alpha() or c == '_' => {
let start = .i
Expand Down
6 changes: 6 additions & 0 deletions tests/raw_string_literals.oc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/// out: "\\t\\n\\r\\x1b\\x7f"
def main() {
let s = r"\t\n\r\x1b\x7f"
println(`{s}`)
}

0 comments on commit bd65033

Please sign in to comment.