all: support `mut volatile x := 123` declarations (#11940)
parent
76e360ce86
commit
bf2569a9a8
|
@ -5530,6 +5530,7 @@ type
|
||||||
typeof
|
typeof
|
||||||
union
|
union
|
||||||
unsafe
|
unsafe
|
||||||
|
volatile
|
||||||
__offsetof
|
__offsetof
|
||||||
```
|
```
|
||||||
See also [V Types](#v-types).
|
See also [V Types](#v-types).
|
||||||
|
|
|
@ -703,6 +703,7 @@ pub mut:
|
||||||
typ Type
|
typ Type
|
||||||
is_mut bool
|
is_mut bool
|
||||||
is_static bool
|
is_static bool
|
||||||
|
is_volatile bool
|
||||||
is_optional bool
|
is_optional bool
|
||||||
share ShareType
|
share ShareType
|
||||||
}
|
}
|
||||||
|
@ -996,6 +997,7 @@ pub mut:
|
||||||
left_types []Type
|
left_types []Type
|
||||||
right_types []Type
|
right_types []Type
|
||||||
is_static bool // for translated code only
|
is_static bool // for translated code only
|
||||||
|
is_volatile bool // for disabling variable access optimisations (needed for hardware drivers)
|
||||||
is_simple bool // `x+=2` in `for x:=1; ; x+=2`
|
is_simple bool // `x+=2` in `for x:=1; ; x+=2`
|
||||||
has_cross_var bool
|
has_cross_var bool
|
||||||
}
|
}
|
||||||
|
|
|
@ -1719,6 +1719,9 @@ pub fn (mut f Fmt) ident(node ast.Ident) {
|
||||||
if var_info.is_static {
|
if var_info.is_static {
|
||||||
f.write('static ')
|
f.write('static ')
|
||||||
}
|
}
|
||||||
|
if var_info.is_volatile {
|
||||||
|
f.write('volatile ')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
f.write_language_prefix(node.language)
|
f.write_language_prefix(node.language)
|
||||||
if node.name == 'it' && f.it_name != '' && !f.inside_lambda { // allow `it` in lambdas
|
if node.name == 'it' && f.it_name != '' && !f.inside_lambda { // allow `it` in lambdas
|
||||||
|
|
|
@ -2374,6 +2374,9 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
||||||
if assign_stmt.is_static {
|
if assign_stmt.is_static {
|
||||||
g.write('static ')
|
g.write('static ')
|
||||||
}
|
}
|
||||||
|
if assign_stmt.is_volatile {
|
||||||
|
g.write('volatile ')
|
||||||
|
}
|
||||||
mut return_type := ast.void_type
|
mut return_type := ast.void_type
|
||||||
is_decl := assign_stmt.op == .decl_assign
|
is_decl := assign_stmt.op == .decl_assign
|
||||||
g.assign_op = assign_stmt.op
|
g.assign_op = assign_stmt.op
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
volatile int *zzz = HEAP(int, (123));
|
||||||
|
volatile int* pzzz = &(*(zzz));
|
|
@ -0,0 +1,2 @@
|
||||||
|
123
|
||||||
|
&123
|
|
@ -0,0 +1,4 @@
|
||||||
|
mut volatile zzz := 123
|
||||||
|
mut volatile pzzz := &zzz
|
||||||
|
println(zzz)
|
||||||
|
println(&int(voidptr(pzzz)))
|
|
@ -156,6 +156,7 @@ fn (mut p Parser) partial_assign_stmt(left []ast.Expr, left_comments []ast.Comme
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mut is_static := false
|
mut is_static := false
|
||||||
|
mut is_volatile := false
|
||||||
for i, lx in left {
|
for i, lx in left {
|
||||||
match mut lx {
|
match mut lx {
|
||||||
ast.Ident {
|
ast.Ident {
|
||||||
|
@ -174,6 +175,9 @@ fn (mut p Parser) partial_assign_stmt(left []ast.Expr, left_comments []ast.Comme
|
||||||
}
|
}
|
||||||
is_static = true
|
is_static = true
|
||||||
}
|
}
|
||||||
|
if iv.is_volatile {
|
||||||
|
is_volatile = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
r0 := right[0]
|
r0 := right[0]
|
||||||
mut v := ast.Var{
|
mut v := ast.Var{
|
||||||
|
@ -232,5 +236,6 @@ fn (mut p Parser) partial_assign_stmt(left []ast.Expr, left_comments []ast.Comme
|
||||||
has_cross_var: has_cross_var
|
has_cross_var: has_cross_var
|
||||||
is_simple: p.inside_for && p.tok.kind == .lcbr
|
is_simple: p.inside_for && p.tok.kind == .lcbr
|
||||||
is_static: is_static
|
is_static: is_static
|
||||||
|
is_volatile: is_volatile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,7 +32,7 @@ pub fn (mut p Parser) check_expr(precedence int) ?ast.Expr {
|
||||||
}
|
}
|
||||||
// Prefix
|
// Prefix
|
||||||
match p.tok.kind {
|
match p.tok.kind {
|
||||||
.key_mut, .key_shared, .key_atomic, .key_static {
|
.key_mut, .key_shared, .key_atomic, .key_static, .key_volatile {
|
||||||
ident := p.parse_ident(ast.Language.v)
|
ident := p.parse_ident(ast.Language.v)
|
||||||
node = ident
|
node = ident
|
||||||
if p.inside_defer {
|
if p.inside_defer {
|
||||||
|
|
|
@ -865,7 +865,7 @@ fn (mut p Parser) asm_stmt(is_top_level bool) ast.AsmStmt {
|
||||||
mut arch := pref.arch_from_string(p.tok.lit) or { pref.Arch._auto }
|
mut arch := pref.arch_from_string(p.tok.lit) or { pref.Arch._auto }
|
||||||
mut is_volatile := false
|
mut is_volatile := false
|
||||||
mut is_goto := false
|
mut is_goto := false
|
||||||
if p.tok.lit == 'volatile' && p.tok.kind == .name {
|
if p.tok.kind == .key_volatile {
|
||||||
arch = pref.arch_from_string(p.peek_tok.lit) or { pref.Arch._auto }
|
arch = pref.arch_from_string(p.peek_tok.lit) or { pref.Arch._auto }
|
||||||
is_volatile = true
|
is_volatile = true
|
||||||
p.next()
|
p.next()
|
||||||
|
@ -1820,6 +1820,10 @@ pub fn (mut p Parser) parse_ident(language ast.Language) ast.Ident {
|
||||||
if is_static {
|
if is_static {
|
||||||
p.next()
|
p.next()
|
||||||
}
|
}
|
||||||
|
is_volatile := p.tok.kind == .key_volatile
|
||||||
|
if is_volatile {
|
||||||
|
p.next()
|
||||||
|
}
|
||||||
if p.tok.kind != .name {
|
if p.tok.kind != .name {
|
||||||
p.error('unexpected token `$p.tok.lit`')
|
p.error('unexpected token `$p.tok.lit`')
|
||||||
return ast.Ident{
|
return ast.Ident{
|
||||||
|
@ -1838,6 +1842,7 @@ pub fn (mut p Parser) parse_ident(language ast.Language) ast.Ident {
|
||||||
info: ast.IdentVar{
|
info: ast.IdentVar{
|
||||||
is_mut: false
|
is_mut: false
|
||||||
is_static: false
|
is_static: false
|
||||||
|
is_volatile: false
|
||||||
}
|
}
|
||||||
scope: p.scope
|
scope: p.scope
|
||||||
}
|
}
|
||||||
|
@ -1861,6 +1866,7 @@ pub fn (mut p Parser) parse_ident(language ast.Language) ast.Ident {
|
||||||
info: ast.IdentVar{
|
info: ast.IdentVar{
|
||||||
is_mut: is_mut
|
is_mut: is_mut
|
||||||
is_static: is_static
|
is_static: is_static
|
||||||
|
is_volatile: is_volatile
|
||||||
share: ast.sharetype_from_flags(is_shared, is_atomic)
|
share: ast.sharetype_from_flags(is_shared, is_atomic)
|
||||||
}
|
}
|
||||||
scope: p.scope
|
scope: p.scope
|
||||||
|
|
|
@ -60,7 +60,6 @@ struct ReservedKeywords {
|
||||||
typedef int
|
typedef int
|
||||||
unsigned int
|
unsigned int
|
||||||
void int
|
void int
|
||||||
volatile int
|
|
||||||
while int
|
while int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,18 +119,16 @@ fn test_at() {
|
||||||
|
|
||||||
fn test_reserved_keywords() {
|
fn test_reserved_keywords() {
|
||||||
// Make sure we can initialize them correctly using full syntax.
|
// Make sure we can initialize them correctly using full syntax.
|
||||||
rk_holder := ReservedKeywords{0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3}
|
rk_holder := ReservedKeywords{0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3}
|
||||||
// Test a few as it'll take too long to test all. If it's initialized
|
// Test a few as it'll take too long to test all. If it's initialized
|
||||||
// correctly, other fields are also probably valid.
|
// correctly, other fields are also probably valid.
|
||||||
assert rk_holder.unix == 5
|
assert rk_holder.unix == 5
|
||||||
assert rk_holder.while == 3
|
assert rk_holder.while == 3
|
||||||
rk_holder2 := ReservedKeywords{
|
rk_holder2 := ReservedKeywords{
|
||||||
inline: 9
|
inline: 9
|
||||||
volatile: 11
|
|
||||||
}
|
}
|
||||||
// Make sure partial initialization works too.
|
// Make sure partial initialization works too.
|
||||||
assert rk_holder2.inline == 9
|
assert rk_holder2.inline == 9
|
||||||
assert rk_holder2.volatile == 11
|
|
||||||
assert rk_holder2.while == 0 // Zero value as not specified.
|
assert rk_holder2.while == 0 // Zero value as not specified.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
fn test_volatile_var() {
|
||||||
|
mut volatile zzz := 123
|
||||||
|
assert zzz == 123
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_volatile_pointer() {
|
||||||
|
x := 123
|
||||||
|
y := 456
|
||||||
|
mut volatile p := unsafe { &x }
|
||||||
|
println(p)
|
||||||
|
p = unsafe { &y }
|
||||||
|
println(p)
|
||||||
|
assert unsafe { *p == y }
|
||||||
|
}
|
|
@ -126,6 +126,7 @@ pub enum Kind {
|
||||||
key_union
|
key_union
|
||||||
key_pub
|
key_pub
|
||||||
key_static
|
key_static
|
||||||
|
key_volatile
|
||||||
key_unsafe
|
key_unsafe
|
||||||
keyword_end
|
keyword_end
|
||||||
_end_
|
_end_
|
||||||
|
@ -303,6 +304,7 @@ fn build_token_str() []string {
|
||||||
s[Kind.key_global] = '__global'
|
s[Kind.key_global] = '__global'
|
||||||
s[Kind.key_union] = 'union'
|
s[Kind.key_union] = 'union'
|
||||||
s[Kind.key_static] = 'static'
|
s[Kind.key_static] = 'static'
|
||||||
|
s[Kind.key_volatile] = 'volatile'
|
||||||
s[Kind.key_as] = 'as'
|
s[Kind.key_as] = 'as'
|
||||||
s[Kind.key_defer] = 'defer'
|
s[Kind.key_defer] = 'defer'
|
||||||
s[Kind.key_match] = 'match'
|
s[Kind.key_match] = 'match'
|
||||||
|
|
Loading…
Reference in New Issue