diff --git a/compiler/parser.v b/compiler/parser.v index 25e718621f..ff9b299cb0 100644 --- a/compiler/parser.v +++ b/compiler/parser.v @@ -1335,7 +1335,7 @@ fn (p mut Parser) bterm() string { return typ } -// also called on *, &, . (enum) +// also called on *, &, @, . (enum) fn (p mut Parser) name_expr() string { p.log('\nname expr() pass=$p.run tok=${p.tok.str()} $p.lit') // print('known type:') @@ -2167,11 +2167,8 @@ fn (p mut Parser) factor() string { p.gen('$sizeof_typ)') p.fgen('$sizeof_typ)') return 'int' - case Token.amp: - return p.name_expr() - case Token.dot: - return p.name_expr()// `.green` (enum) - case Token.mul: + case Token.amp, Token.dot, Token.mul: + // (dot is for enum vals: `.green`) return p.name_expr() case Token.name: // map[string]int diff --git a/compiler/scanner.v b/compiler/scanner.v index dcaa432acd..351e3108be 100644 --- a/compiler/scanner.v +++ b/compiler/scanner.v @@ -388,6 +388,13 @@ fn (s mut Scanner) scan() ScanRes { return scan_res(.pipe, '') case `,`: return scan_res(.comma, '') + case `@`: + s.pos++ + name := s.ident_name() + if !is_key(name) { + s.error('@ must be used before keywords (e.g. `@type string`)') + } + return scan_res(.name, name) case `\r`: if nextc == `\n` { s.pos++ diff --git a/compiler/tests/struct_test.v b/compiler/tests/struct_test.v index d54d42a044..8f36f434a2 100644 --- a/compiler/tests/struct_test.v +++ b/compiler/tests/struct_test.v @@ -21,6 +21,10 @@ struct User { name string age int } + +struct Foo { + @type string +} fn test_struct_levels() { mut c := C{} @@ -54,3 +58,8 @@ fn test_struct_str() { println(u) // make sure the struct is printable // assert u.str() == '{name:"Bob", age:30}' // TODO } + +fn test_at() { + foo := Foo{ @type: 'test' } + println(foo.@type) +} diff --git a/compiler/token.v b/compiler/token.v index e1d3cec95c..dc69a0021c 100644 --- a/compiler/token.v +++ b/compiler/token.v @@ -34,6 +34,7 @@ enum Token { dollar left_shift righ_shift + //at // @ // = := += -= assign decl_assign @@ -148,6 +149,7 @@ fn build_token_str() []string { s[Token.dot] = '.' s[Token.dotdot] = '..' s[Token.comma] = ',' + //s[Token.at] = '@' s[Token.semicolon] = ';' s[Token.colon] = ':' s[Token.arrow] = '=>'