From e39fc2606d63a783c7eb74e0be8a82ca4c5fb6ab Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Wed, 18 Sep 2013 15:11:18 -0700 Subject: [PATCH] Allow for integral suffixes after a char literal This way you can say 'a'u8 instead of ('a' as u8). --- src/etc/vim/syntax/rust.vim | 4 +- src/libsyntax/parse/lexer.rs | 80 +++++++++++++--------- src/test/run-pass/char-literal-suffixes.rs | 32 +++++++++ 3 files changed, 82 insertions(+), 34 deletions(-) create mode 100644 src/test/run-pass/char-literal-suffixes.rs diff --git a/src/etc/vim/syntax/rust.vim b/src/etc/vim/syntax/rust.vim index 0a95f31b0675d..68fa09a287d49 100644 --- a/src/etc/vim/syntax/rust.vim +++ b/src/etc/vim/syntax/rust.vim @@ -146,7 +146,7 @@ syn match rustMacro '#\w\(\w\)*' contains=rustAssert,rustFail syn match rustFormat display "%\(\d\+\$\)\=[-+' #0*]*\(\d*\|\*\|\*\d\+\$\)\(\.\(\d*\|\*\|\*\d\+\$\)\)\=\([hlLjzt]\|ll\|hh\)\=\([aAbdiuoxXDOUfFeEgGcCsSpn?]\|\[\^\=.[^]]*\]\)" contained syn match rustFormat display "%%" contained -syn match rustSpecial display contained /\\\([nrt\\'"]\|x\x\{2}\|u\x\{4}\|U\x\{8}\)/ +syn match rustSpecial display contained /\\\([nrt\\'"0]\|x\x\{2}\|u\x\{4}\|U\x\{8}\)/ syn match rustStringContinuation display contained /\\\n\s*/ syn region rustString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=rustTodo,rustFormat,rustSpecial,rustStringContinuation @@ -180,7 +180,7 @@ syn region rustGenericLifetimeCandidate display start=/\%(<\|,\s*\)\@<='/ end=/[ "rustLifetime must appear before rustCharacter, or chars will get the lifetime highlighting syn match rustLifetime display "\'\%([^[:cntrl:][:space:][:punct:][:digit:]]\|_\)\%([^[:cntrl:][:punct:][:space:]]\|_\)*" -syn match rustCharacter /'\([^'\\]\|\\\([nrt\\'"]\|x\x\{2}\|u\x\{4}\|U\x\{8}\)\)'/ contains=rustSpecial +syn match rustCharacter /'\([^'\\]\|\\\([nrt\\'"0]\|x\x\{2}\|u\x\{4}\|U\x\{8}\)\)'\(u8\|u16\|u32\|u64\|u\|i8\|i16\|i32\|i64\|i\)\?/ contains=rustSpecial syn region rustCommentML start="/\*" end="\*/" contains=rustTodo syn region rustComment start="//" end="$" contains=rustTodo keepend diff --git a/src/libsyntax/parse/lexer.rs b/src/libsyntax/parse/lexer.rs index 0bc9e61927436..c66b52e90a4f4 100644 --- a/src/libsyntax/parse/lexer.rs +++ b/src/libsyntax/parse/lexer.rs @@ -409,38 +409,9 @@ fn scan_number(c: char, rdr: @mut StringReader) -> token::Token { base = 2u; } num_str = scan_digits(rdr, base); - c = rdr.curr; - nextch(rdr); - if c == 'u' || c == 'i' { - let signed = c == 'i'; - let mut tp = { - if signed { either::Left(ast::ty_i) } - else { either::Right(ast::ty_u) } - }; - bump(rdr); - c = rdr.curr; - if c == '8' { - bump(rdr); - tp = if signed { either::Left(ast::ty_i8) } - else { either::Right(ast::ty_u8) }; - } - n = nextch(rdr); - if c == '1' && n == '6' { - bump(rdr); - bump(rdr); - tp = if signed { either::Left(ast::ty_i16) } - else { either::Right(ast::ty_u16) }; - } else if c == '3' && n == '2' { - bump(rdr); - bump(rdr); - tp = if signed { either::Left(ast::ty_i32) } - else { either::Right(ast::ty_u32) }; - } else if c == '6' && n == '4' { - bump(rdr); - bump(rdr); - tp = if signed { either::Left(ast::ty_i64) } - else { either::Right(ast::ty_u64) }; - } + let int_suff = scan_integral_suffix(rdr); + if int_suff.is_some() { + let tp = int_suff.unwrap(); if num_str.len() == 0u { rdr.fatal(~"no valid digits found for number"); } @@ -520,6 +491,43 @@ fn scan_number(c: char, rdr: @mut StringReader) -> token::Token { } } +fn scan_integral_suffix(rdr: @mut StringReader) + -> Option> { + let mut c = rdr.curr; + if c == 'u' || c == 'i' { + let signed = c == 'i'; + let mut tp = { + if signed { either::Left(ast::ty_i) } + else { either::Right(ast::ty_u) } + }; + bump(rdr); + c = rdr.curr; + if c == '8' { + bump(rdr); + tp = if signed { either::Left(ast::ty_i8) } + else { either::Right(ast::ty_u8) }; + } + let n = nextch(rdr); + if c == '1' && n == '6' { + bump(rdr); + bump(rdr); + tp = if signed { either::Left(ast::ty_i16) } + else { either::Right(ast::ty_u16) }; + } else if c == '3' && n == '2' { + bump(rdr); + bump(rdr); + tp = if signed { either::Left(ast::ty_i32) } + else { either::Right(ast::ty_u32) }; + } else if c == '6' && n == '4' { + bump(rdr); + bump(rdr); + tp = if signed { either::Left(ast::ty_i64) } + else { either::Right(ast::ty_u64) }; + } + Some(tp) + } else { None } +} + fn scan_numeric_escape(rdr: @mut StringReader, n_hex_digits: uint) -> char { let mut accum_int = 0; let mut i = n_hex_digits; @@ -712,6 +720,14 @@ fn next_token_inner(rdr: @mut StringReader) -> token::Token { rdr.fatal(~"unterminated character constant"); } bump(rdr); // advance curr past token + let int_suff = scan_integral_suffix(rdr); + if int_suff.is_some() { + let tp = int_suff.unwrap(); + match tp { + either::Left(t) => return token::LIT_INT(c2 as i64, t), + either::Right(t) => return token::LIT_UINT(c2 as u64, t) + } + } return token::LIT_CHAR(c2 as u32); } '"' => { diff --git a/src/test/run-pass/char-literal-suffixes.rs b/src/test/run-pass/char-literal-suffixes.rs new file mode 100644 index 0000000000000..ff42e243e7037 --- /dev/null +++ b/src/test/run-pass/char-literal-suffixes.rs @@ -0,0 +1,32 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let a: int = 'a'i; + assert_eq!(a, 97i); + let a: i8 = 'a'i8; + assert_eq!(a, 97i8); + let a: i16 = 'a'i16; + assert_eq!(a, 97i16); + let a: i32 = 'a'i32; + assert_eq!(a, 97i32); + let a: i64 = 'a'i64; + assert_eq!(a, 97i64); + let a: uint = 'a'u; + assert_eq!(a, 97u); + let a: u8 = 'a'u8; + assert_eq!(a, 97u8); + let a: u16 = 'a'u16; + assert_eq!(a, 97u16); + let a: u32 = 'a'u32; + assert_eq!(a, 97u32); + let a: u64 = 'a'u64; + assert_eq!(a, 97u64); +}