get_type.v
parent
0a38b307cd
commit
cb46bf314e
|
@ -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
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
|
@ -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}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue