scanner: make `0o` prefix the only way to define octals
parent
9d2a60bb11
commit
7d2eb4f604
|
@ -117,6 +117,20 @@ fn test_hex() {
|
||||||
fn test_oct() {
|
fn test_oct() {
|
||||||
x1 := 0o12
|
x1 := 0o12
|
||||||
assert x1 == 10
|
assert x1 == 10
|
||||||
x2 := 012
|
x2 := 00000o350
|
||||||
assert x2 == 10
|
assert x2 == 232
|
||||||
|
x3 := 000o00073
|
||||||
|
assert x3 == 59
|
||||||
|
x4 := 00000000
|
||||||
|
assert x4 == 0
|
||||||
|
x5 := 00000195
|
||||||
|
assert x5 == 195
|
||||||
|
x6 := -0o744
|
||||||
|
assert x6 == -484
|
||||||
|
x7 := -000o000042
|
||||||
|
assert x7 == -34
|
||||||
|
x8 := -0000112
|
||||||
|
assert x8 == -112
|
||||||
|
x9 := -000
|
||||||
|
assert x9 == 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -346,6 +346,19 @@ fn (s mut Scanner) scan() ScanRes {
|
||||||
}
|
}
|
||||||
// `123`, `.123`
|
// `123`, `.123`
|
||||||
else if c.is_digit() || (c == `.` && nextc.is_digit()) {
|
else if c.is_digit() || (c == `.` && nextc.is_digit()) {
|
||||||
|
if !s.inside_string {
|
||||||
|
// In C ints with `0` prefix are octal (in V they're decimal), so discarding heading zeros is needed.
|
||||||
|
mut start_pos := s.pos
|
||||||
|
for start_pos < s.text.len && s.text[start_pos] == `0` {
|
||||||
|
start_pos++
|
||||||
|
}
|
||||||
|
mut prefix_zero_num := start_pos - s.pos // how many prefix zeros should be jumped
|
||||||
|
// for 0b, 0o, 0x the heading zero shouldn't be jumped
|
||||||
|
if c == `0` && start_pos < s.text.len && !s.text[start_pos].is_digit() {
|
||||||
|
prefix_zero_num--
|
||||||
|
}
|
||||||
|
s.pos += prefix_zero_num // jump these zeros
|
||||||
|
}
|
||||||
num := s.ident_number()
|
num := s.ident_number()
|
||||||
return scan_res(.number, num)
|
return scan_res(.number, num)
|
||||||
}
|
}
|
||||||
|
|
|
@ -290,13 +290,13 @@ pub fn open_file(path string, mode string, options ...int) ?File {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mut permission := 0666
|
mut permission := 0o666
|
||||||
if options.len > 0 {
|
if options.len > 0 {
|
||||||
permission = options[0]
|
permission = options[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
$if windows {
|
$if windows {
|
||||||
if permission < 0600 {
|
if permission < 0o600 {
|
||||||
permission = 0x0100
|
permission = 0x0100
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -33,11 +33,11 @@ fn test_unsetenv() {
|
||||||
fn test_open_file() {
|
fn test_open_file() {
|
||||||
filename := './test1.txt'
|
filename := './test1.txt'
|
||||||
hello := 'hello world!'
|
hello := 'hello world!'
|
||||||
os.open_file(filename, "r+", 0666) or {
|
os.open_file(filename, "r+", 0o666) or {
|
||||||
assert err == "No such file or directory"
|
assert err == "No such file or directory"
|
||||||
}
|
}
|
||||||
|
|
||||||
mut file := os.open_file(filename, "w+", 0666) or { panic(err) }
|
mut file := os.open_file(filename, "w+", 0o666) or { panic(err) }
|
||||||
file.write(hello)
|
file.write(hello)
|
||||||
file.close()
|
file.close()
|
||||||
|
|
||||||
|
@ -278,11 +278,11 @@ fn test_is_executable_writable_readable() {
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
$if !windows {
|
$if !windows {
|
||||||
os.chmod(file_name, 0600) // mark as readable && writable, but NOT executable
|
os.chmod(file_name, 0o600) // mark as readable && writable, but NOT executable
|
||||||
assert os.is_writable(file_name)
|
assert os.is_writable(file_name)
|
||||||
assert os.is_readable(file_name)
|
assert os.is_readable(file_name)
|
||||||
assert !os.is_executable(file_name)
|
assert !os.is_executable(file_name)
|
||||||
os.chmod(file_name, 0700) // mark as executable too
|
os.chmod(file_name, 0o700) // mark as executable too
|
||||||
assert os.is_executable(file_name)
|
assert os.is_executable(file_name)
|
||||||
} $else {
|
} $else {
|
||||||
assert os.is_writable(file_name)
|
assert os.is_writable(file_name)
|
||||||
|
|
|
@ -11,7 +11,7 @@ fn test_atoi() {
|
||||||
fn test_parse_int() {
|
fn test_parse_int() {
|
||||||
// Different bases
|
// Different bases
|
||||||
assert strconv.parse_int('16', 16, 0) == 0x16
|
assert strconv.parse_int('16', 16, 0) == 0x16
|
||||||
assert strconv.parse_int('16', 8, 0) == 016
|
assert strconv.parse_int('16', 8, 0) == 0o16
|
||||||
assert strconv.parse_int('11', 2, 0) == 3
|
assert strconv.parse_int('11', 2, 0) == 3
|
||||||
// Different bit sizes
|
// Different bit sizes
|
||||||
assert strconv.parse_int('127', 10, 8) == 127
|
assert strconv.parse_int('127', 10, 8) == 127
|
||||||
|
|
|
@ -92,7 +92,7 @@ pub fn (g mut Gen) generate_elf_footer() {
|
||||||
mut f := os.create(g.out_name) or {
|
mut f := os.create(g.out_name) or {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
os.chmod(g.out_name, 0775) // make it an executable
|
os.chmod(g.out_name, 0o775) // make it an executable
|
||||||
f.write_bytes(g.buf.data, g.buf.len)
|
f.write_bytes(g.buf.data, g.buf.len)
|
||||||
f.close()
|
f.close()
|
||||||
println('x64 elf binary has been successfully generated')
|
println('x64 elf binary has been successfully generated')
|
||||||
|
|
|
@ -340,6 +340,19 @@ pub fn (s mut Scanner) scan() token.Token {
|
||||||
}
|
}
|
||||||
// `123`, `.123`
|
// `123`, `.123`
|
||||||
else if c.is_digit() || (c == `.` && nextc.is_digit()) {
|
else if c.is_digit() || (c == `.` && nextc.is_digit()) {
|
||||||
|
if !s.inside_string {
|
||||||
|
// In C ints with `0` prefix are octal (in V they're decimal), so discarding heading zeros is needed.
|
||||||
|
mut start_pos := s.pos
|
||||||
|
for start_pos < s.text.len && s.text[start_pos] == `0` {
|
||||||
|
start_pos++
|
||||||
|
}
|
||||||
|
mut prefix_zero_num := start_pos - s.pos // how many prefix zeros should be jumped
|
||||||
|
// for 0b, 0o, 0x the heading zero shouldn't be jumped
|
||||||
|
if c == `0` && start_pos < s.text.len && !s.text[start_pos].is_digit() {
|
||||||
|
prefix_zero_num--
|
||||||
|
}
|
||||||
|
s.pos += prefix_zero_num // jump these zeros
|
||||||
|
}
|
||||||
num := s.ident_number()
|
num := s.ident_number()
|
||||||
return s.scan_res(.number, num)
|
return s.scan_res(.number, num)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue