From cb46bf314ed54fe6549eaa6fc7cbf277afa29cc9 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Thu, 5 Dec 2019 18:47:29 +0300 Subject: [PATCH] get_type.v --- vlib/builtin/int_test.v | 12 +++ vlib/compiler/{parser2.v => get_type.v} | 98 +++++++++++++++++-------- vlib/compiler/parser.v | 2 +- vlib/compiler/table.v | 2 +- 4 files changed, 80 insertions(+), 34 deletions(-) rename vlib/compiler/{parser2.v => get_type.v} (62%) diff --git a/vlib/builtin/int_test.v b/vlib/builtin/int_test.v index ecf5d84844..d3fedf73d7 100644 --- a/vlib/builtin/int_test.v +++ b/vlib/builtin/int_test.v @@ -92,3 +92,15 @@ fn test_cmp() { assert 1 ⩾ 0 } */ + +type myint int +type mystring string + +fn test_int_alias() { + /* + i := myint(2) + s := mystring('hi') + ss := s + '!' + assert i + 10 == 12 + */ +} diff --git a/vlib/compiler/parser2.v b/vlib/compiler/get_type.v similarity index 62% rename from vlib/compiler/parser2.v rename to vlib/compiler/get_type.v index 8eb40ad5fe..877979d00d 100644 --- a/vlib/compiler/parser2.v +++ b/vlib/compiler/get_type.v @@ -1,12 +1,42 @@ +// Copyright (c) 2019 Alexander Medvednikov. All rights reserved. +// Use of this source code is governed by an MIT license +// that can be found in the LICENSE file. + module compiler -import strings +import ( + strings +) -fn (p mut Parser) get_type2() Type { +fn (p mut Parser) get_type3() Type{ mut mul := false mut nr_muls := 0 mut typ := '' mut cat := TypeCategory.struct_ + // multiple returns + if p.tok == .lpar { + //p.warn('`()` are no longer necessary in multiple returns' + + //'\nuse `fn foo() int, int {` instead of `fn foo() (int, int) {`') + // if p.inside_tuple {p.error('unexpected (')} + // p.inside_tuple = true + p.check(.lpar) + mut types := []string + for { + types << p.get_type() + if p.tok != .comma { + break + } + p.check(.comma) + } + p.check(.rpar) + // p.inside_tuple = false + typ = p.register_multi_return_stuct(types) + return Type { + name: typ + mod: p.mod + cat: cat + } + } // fn type if p.tok == .key_fn { mut f := Fn{name: '_', mod: p.mod} @@ -15,7 +45,7 @@ fn (p mut Parser) get_type2() Type { p.fn_args(mut f) // Same line, it's a return type if p.scanner.line_nr == line_nr { - if p.tok == .name { + if p.tok in [.name, .mul, .amp, .lsbr, .question, .lpar] { f.typ = p.get_type() } else { @@ -37,36 +67,22 @@ fn (p mut Parser) get_type2() Type { return fn_typ } // arrays ([]int) - mut is_arr := false - mut is_arr2 := false// [][]int TODO remove this and allow unlimited levels of arrays + mut arr_level := 0 is_question := p.tok == .question if is_question { p.check(.question) } - if p.tok == .lsbr { + for p.tok == .lsbr { p.check(.lsbr) // [10]int if p.tok == .number { - typ = '[$p.lit]' + typ += '[$p.lit]' p.next() } else { - is_arr = true + arr_level++ } p.check(.rsbr) - // [10][3]int - if p.tok == .lsbr { - p.next() - if p.tok == .number { - typ += '[$p.lit]' - p.check(.number) - } - else { - is_arr2 = true - } - p.check(.rsbr) - } - cat = .array } // map[string]int if !p.builtin_mod && p.tok == .name && p.lit == 'map' { @@ -82,10 +98,11 @@ fn (p mut Parser) get_type2() Type { p.register_map(typ) return Type{name: typ} } - // + // ptr/ref + mut warn := false for p.tok == .mul { if p.first_pass() { - p.warn('use `&Foo` instead of `*Foo`') + warn = true } mul = true nr_muls++ @@ -96,7 +113,13 @@ fn (p mut Parser) get_type2() Type { nr_muls++ p.check(.amp) } - typ += p.lit + // generic type check + ti := p.cur_fn.dispatch_of.inst + if p.lit in ti.keys() { + typ += ti[p.lit] + } else { + typ += p.lit + } // C.Struct import if p.lit == 'C' && p.peek() == .dot { p.next() @@ -104,13 +127,16 @@ fn (p mut Parser) get_type2() Type { typ = p.lit } else { + if warn && p.mod != 'ui' { + p.warn('use `&Foo` instead of `*Foo`') + } // Module specified? (e.g. gx.Image) if p.peek() == .dot { // try resolve full submodule if !p.builtin_mod && p.import_table.known_alias(typ) { mod := p.import_table.resolve_alias(typ) if mod.contains('.') { - typ = mod.replace('.', '_dot_') + typ = mod_gen_name(mod) } } p.next() @@ -132,9 +158,16 @@ fn (p mut Parser) get_type2() Type { // for q in p.table.types { // println(q.name) // } - p.error('unknown type `$typ`') + mut t_suggest, tc_suggest := p.table.find_misspelled_type(typ, p, 0.50) + if t_suggest.len > 0 { + t_suggest = '. did you mean: ($tc_suggest) `$t_suggest`' + } + p.error('unknown type `$typ`$t_suggest') } } + else if !t.is_public && t.mod != p.mod && !p.is_vgen && t.name != '' && !p.first_pass() { + p.error('type `$t.name` is private') + } } if typ == 'void' { p.error('unknown type `$typ`') @@ -143,13 +176,12 @@ fn (p mut Parser) get_type2() Type { typ += strings.repeat(`*`, nr_muls) } // Register an []array type - if is_arr2 { - typ = 'array_array_$typ' - p.register_array(typ) - } - else if is_arr { - typ = 'array_$typ' + if arr_level > 0 { + // p.log('ARR TYPE="$typ" run=$p.pass') // We come across "[]User" etc ? + for i := 0; i < arr_level; i++ { + typ = 'array_$typ' + } p.register_array(typ) } p.next() @@ -158,9 +190,11 @@ fn (p mut Parser) get_type2() Type { p.table.register_type_with_parent(typ, 'Option') } /* + TODO this is not needed? if typ.last_index('__') > typ.index('__') { p.error('2 __ in gettype(): typ="$typ"') } */ return Type{name: typ, cat: cat} } + diff --git a/vlib/compiler/parser.v b/vlib/compiler/parser.v index 4767d1879c..2bdb6b3564 100644 --- a/vlib/compiler/parser.v +++ b/vlib/compiler/parser.v @@ -740,7 +740,7 @@ fn (p mut Parser) type_decl() { if p.tok == .key_struct { p.error('use `struct $name {` instead of `type $name struct {`') } - parent := p.get_type2() + parent := p.get_type3() nt_pair := p.table.cgen_name_type_pair(name, parent.name) // TODO dirty C typedef hacks for DOOM // Unknown type probably means it's a struct, and it's used before the struct is defined, diff --git a/vlib/compiler/table.v b/vlib/compiler/table.v index 1ffb9cea3e..7ec10b122e 100644 --- a/vlib/compiler/table.v +++ b/vlib/compiler/table.v @@ -715,7 +715,7 @@ fn (p mut Parser) check_types2(got_, expected_ string, throw bool) bool { return false } else { - p.error('expected type `$expected`, but got `$got`') + p.error('cannot convert `$got` to `$expected`') } } return true