parser: handle several errors in types; cgen: objC includes

pull/6144/head
Alexander Medvednikov 2020-08-16 19:16:59 +02:00
parent 191c908f3a
commit f965ddae49
7 changed files with 48 additions and 14 deletions

View File

@ -4,7 +4,8 @@
V is a statically typed compiled programming language designed for building maintainable software.
It's similar to Go and its design has also been influenced by Oberon, Rust, Swift, and Python.
It's similar to Go and its design has also been influenced by Oberon, Rust, Swift,
Kotlin, and Python.
V is a very simple language. Going through this documentation will take you about half an hour,
and by the end of it you will have pretty much learned the entire language.

View File

@ -1,11 +1,13 @@
vlib/v/checker/tests/unknown_method_suggest_name.v:7:2: error: unknown type `hash.crc32.Crc33`. Did you mean `crc32.Crc32` ?
vlib/v/checker/tests/unknown_method_suggest_name.v:7:2: error: unknown type `hash.crc32.Crc33`.
Did you mean `crc32.Crc32`?
5 | y int
6 | z int
7 | ccc crc32.Crc33
| ~~~~~~~~~~~~~~~
8 | }
9 |
vlib/v/checker/tests/unknown_method_suggest_name.v:27:9: error: unknown method: `Point.tranzlate`. Did you mean `translate` ?
vlib/v/checker/tests/unknown_method_suggest_name.v:27:9: error: unknown method: `Point.tranzlate`.
Did you mean `translate`?
25 | p := Point{1, 2, 3}
26 | v := Vector{5, 5, 10}
27 | z := p.tranzlate(v)

View File

@ -863,8 +863,14 @@ fn (mut g Gen) stmt(node ast.Stmt) {
// #include etc
typ := node.val.all_before(' ')
if typ == 'include' {
g.includes.writeln('// added by module `$node.mod`:')
g.includes.writeln('#$node.val')
if node.val.contains('.m') {
// Objective C code import, include it after V types, so that e.g. `string` is
// available there
g.definitions.writeln('#$node.val')
} else {
g.includes.writeln('// added by module `$node.mod`:')
g.includes.writeln('#$node.val')
}
}
if typ == 'define' {
g.includes.writeln('#$node.val')
@ -880,6 +886,8 @@ fn (mut g Gen) stmt(node ast.Stmt) {
ast.Return {
g.write_defer_stmts_when_needed()
if g.pref.autofree {
g.writeln('// ast.Return free')
// g.autofree_scope_vars(node.pos.pos)
g.write_autofree_stmts_when_needed(node)
}
g.return_statement(node)

View File

@ -641,6 +641,8 @@ fn (mut g Gen) call_args(args []ast.CallArg, expected_types []table.Type) {
g.expr(arg.expr)
} else if g.autofree && g.pref.experimental && arg.typ == table.string_type &&
g.tmp_idxs.len > 0 && i in g.tmp_idxs {
// Save expressions in temp variables so that they can be freed later.
// `foo(str + str2) => x := str + str2; foo(x); x.free()`
g.write('_arg_expr_${g.called_fn_name}_$i')
} else {
g.ref_or_deref_arg(arg, expected_types[i])

View File

@ -141,6 +141,9 @@ pub fn (mut p Parser) parse_type() table.Type {
nr_muls++
p.next()
}
if p.tok.kind == .mul {
p.error('use `&Type` instead of `*Type` when declaring references')
}
// &Type
for p.tok.kind == .amp {
nr_muls++
@ -190,6 +193,9 @@ pub fn (mut p Parser) parse_any_type(language table.Language, is_ptr, check_dot
p.check(.dot)
// prefix with full module
name = '${p.imports[name]}.$p.tok.lit'
if !p.tok.lit[0].is_capital() {
p.error('imported types must start with a capital letter')
}
} else if p.expr_mod != '' {
name = p.expr_mod + '.' + name
} else if p.mod != 'builtin' && name !in p.table.type_idxs && name.len > 1 {
@ -224,6 +230,10 @@ pub fn (mut p Parser) parse_any_type(language table.Language, is_ptr, check_dot
defer {
p.next()
}
if name == '' {
// This means the developer is using some wrong syntax like `x: int` instead of `x int`
p.error('bad type syntax')
}
match name {
'voidptr' {
return table.voidptr_type

View File

@ -36,6 +36,11 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
}
name_pos := p.tok.position()
mut name := p.check_name()
// defer {
// if name.contains('App') {
// println('end of struct decl $name')
// }
// }
if name.len == 1 && name[0].is_capital() {
p.error_with_pos('single letter capital names are reserved for generic template types.',
name_pos)
@ -153,12 +158,11 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
pos: field_start_pos.pos
len: p.tok.position().pos - field_start_pos.pos
}
/*
if name == '_net_module_s' {
s := p.table.get_type_symbol(typ)
println('XXXX' + s.str())
}
*/
// if name == '_net_module_s' {
// if name.contains('App') {
// s := p.table.get_type_symbol(typ)
// println('struct decl field type ' + s.str())
// }
// Comments after type (same line)
line_pos := field_pos.line_nr
for p.tok.kind == .comment && line_pos + 1 == p.tok.line_nr {
@ -267,6 +271,13 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
fn (mut p Parser) struct_init(short_syntax bool) ast.StructInit {
first_pos := p.tok.position()
/*
defer {
if p.fileis('x.v') {
p.warn('end of struct init $short_syntax')
}
}
*/
typ := if short_syntax { table.void_type } else { p.parse_type() }
p.expr_mod = ''
// sym := p.table.get_type_symbol(typ)

View File

@ -38,11 +38,11 @@ pub fn new_suggestion(wanted string, possibilities []string) Suggestion {
}
pub fn (mut s Suggestion) add(val string) {
if val in [ s.wanted, s.swanted ] {
if val in [s.wanted, s.swanted] {
return
}
sval := short_module_name(val)
if sval in [ s.wanted, s.swanted ] {
if sval in [s.wanted, s.swanted] {
return
}
s.known << Possibility{
@ -69,7 +69,7 @@ pub fn (s Suggestion) say(msg string) string {
if top_posibility.similarity > 0.10 {
val := top_posibility.value
if !val.starts_with('[]') {
res += '. Did you mean `$val` ?'
res += '.\nDid you mean `$val`?'
}
}
}