get_type.v

pull/2997/head
Alexander Medvednikov 2019-12-05 18:47:29 +03:00
parent 0a38b307cd
commit cb46bf314e
4 changed files with 80 additions and 34 deletions

View File

@ -92,3 +92,15 @@ fn test_cmp() {
assert 1 0 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
*/
}

View File

@ -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 module compiler
import strings import (
strings
)
fn (p mut Parser) get_type2() Type { fn (p mut Parser) get_type3() Type{
mut mul := false mut mul := false
mut nr_muls := 0 mut nr_muls := 0
mut typ := '' mut typ := ''
mut cat := TypeCategory.struct_ 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 // fn type
if p.tok == .key_fn { if p.tok == .key_fn {
mut f := Fn{name: '_', mod: p.mod} mut f := Fn{name: '_', mod: p.mod}
@ -15,7 +45,7 @@ fn (p mut Parser) get_type2() Type {
p.fn_args(mut f) p.fn_args(mut f)
// Same line, it's a return type // Same line, it's a return type
if p.scanner.line_nr == line_nr { 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() f.typ = p.get_type()
} }
else { else {
@ -37,36 +67,22 @@ fn (p mut Parser) get_type2() Type {
return fn_typ return fn_typ
} }
// arrays ([]int) // arrays ([]int)
mut is_arr := false mut arr_level := 0
mut is_arr2 := false// [][]int TODO remove this and allow unlimited levels of arrays
is_question := p.tok == .question is_question := p.tok == .question
if is_question { if is_question {
p.check(.question) p.check(.question)
} }
if p.tok == .lsbr { for p.tok == .lsbr {
p.check(.lsbr) p.check(.lsbr)
// [10]int // [10]int
if p.tok == .number { if p.tok == .number {
typ = '[$p.lit]' typ += '[$p.lit]'
p.next() p.next()
} }
else { else {
is_arr = true arr_level++
} }
p.check(.rsbr) 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 // map[string]int
if !p.builtin_mod && p.tok == .name && p.lit == 'map' { 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) p.register_map(typ)
return Type{name: typ} return Type{name: typ}
} }
// // ptr/ref
mut warn := false
for p.tok == .mul { for p.tok == .mul {
if p.first_pass() { if p.first_pass() {
p.warn('use `&Foo` instead of `*Foo`') warn = true
} }
mul = true mul = true
nr_muls++ nr_muls++
@ -96,7 +113,13 @@ fn (p mut Parser) get_type2() Type {
nr_muls++ nr_muls++
p.check(.amp) 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 // C.Struct import
if p.lit == 'C' && p.peek() == .dot { if p.lit == 'C' && p.peek() == .dot {
p.next() p.next()
@ -104,13 +127,16 @@ fn (p mut Parser) get_type2() Type {
typ = p.lit typ = p.lit
} }
else { else {
if warn && p.mod != 'ui' {
p.warn('use `&Foo` instead of `*Foo`')
}
// Module specified? (e.g. gx.Image) // Module specified? (e.g. gx.Image)
if p.peek() == .dot { if p.peek() == .dot {
// try resolve full submodule // try resolve full submodule
if !p.builtin_mod && p.import_table.known_alias(typ) { if !p.builtin_mod && p.import_table.known_alias(typ) {
mod := p.import_table.resolve_alias(typ) mod := p.import_table.resolve_alias(typ)
if mod.contains('.') { if mod.contains('.') {
typ = mod.replace('.', '_dot_') typ = mod_gen_name(mod)
} }
} }
p.next() p.next()
@ -132,9 +158,16 @@ fn (p mut Parser) get_type2() Type {
// for q in p.table.types { // for q in p.table.types {
// println(q.name) // 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' { if typ == 'void' {
p.error('unknown type `$typ`') p.error('unknown type `$typ`')
@ -143,13 +176,12 @@ fn (p mut Parser) get_type2() Type {
typ += strings.repeat(`*`, nr_muls) typ += strings.repeat(`*`, nr_muls)
} }
// Register an []array type // Register an []array type
if is_arr2 { if arr_level > 0 {
typ = 'array_array_$typ' // p.log('ARR TYPE="$typ" run=$p.pass')
p.register_array(typ)
}
else if is_arr {
typ = 'array_$typ'
// We come across "[]User" etc ? // We come across "[]User" etc ?
for i := 0; i < arr_level; i++ {
typ = 'array_$typ'
}
p.register_array(typ) p.register_array(typ)
} }
p.next() p.next()
@ -158,9 +190,11 @@ fn (p mut Parser) get_type2() Type {
p.table.register_type_with_parent(typ, 'Option') p.table.register_type_with_parent(typ, 'Option')
} }
/* /*
TODO this is not needed?
if typ.last_index('__') > typ.index('__') { if typ.last_index('__') > typ.index('__') {
p.error('2 __ in gettype(): typ="$typ"') p.error('2 __ in gettype(): typ="$typ"')
} }
*/ */
return Type{name: typ, cat: cat} return Type{name: typ, cat: cat}
} }

View File

@ -740,7 +740,7 @@ fn (p mut Parser) type_decl() {
if p.tok == .key_struct { if p.tok == .key_struct {
p.error('use `struct $name {` instead of `type $name 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) nt_pair := p.table.cgen_name_type_pair(name, parent.name)
// TODO dirty C typedef hacks for DOOM // TODO dirty C typedef hacks for DOOM
// Unknown type probably means it's a struct, and it's used before the struct is defined, // Unknown type probably means it's a struct, and it's used before the struct is defined,

View File

@ -715,7 +715,7 @@ fn (p mut Parser) check_types2(got_, expected_ string, throw bool) bool {
return false return false
} }
else { else {
p.error('expected type `$expected`, but got `$got`') p.error('cannot convert `$got` to `$expected`')
} }
} }
return true return true