From 38e5f0d1cfc58cf4fd7587bb67c36092d6ab3e93 Mon Sep 17 00:00:00 2001 From: joe-conigliaro Date: Thu, 9 Jan 2020 03:14:42 +1100 Subject: [PATCH] v: initial type work for methods / struct fields --- vlib/v/parser/a_type.v | 32 ++++----- vlib/v/parser/parser.v | 8 ++- vlib/v/table/table.v | 127 ++++++++++++++++++++++++----------- vlib/v/types/types.v | 148 ++++++++++++++++++++--------------------- 4 files changed, 184 insertions(+), 131 deletions(-) diff --git a/vlib/v/parser/a_type.v b/vlib/v/parser/a_type.v index 73542ff76d..d77ebef7da 100644 --- a/vlib/v/parser/a_type.v +++ b/vlib/v/parser/a_type.v @@ -98,52 +98,52 @@ pub fn (p mut Parser) parse_ti() types.TypeIdent { return p.parse_map_ti(nr_muls) } 'voidptr' { - return types.new_builtin_ti(.voidptr, nr_muls) + return types.new_ti(.voidptr, 'voidptr', types.voidptr_type_idx, nr_muls) } 'byteptr' { - return types.new_builtin_ti(.byteptr, nr_muls) + return types.new_ti(.byteptr, 'byteptr', types.byteptr_type_idx, nr_muls) } 'charptr' { - return types.new_builtin_ti(.charptr, nr_muls) + return types.new_ti(.charptr, 'charptr', types.charptr_type_idx, nr_muls) } 'i8' { - return types.new_builtin_ti(.i8, nr_muls) + return types.new_ti(.i8, 'i8', types.i8_type_idx, nr_muls) } 'i16' { - return types.new_builtin_ti(.i16, nr_muls) + return types.new_ti(.i16, 'i16', types.i16_type_idx, nr_muls) } 'int' { - return types.new_builtin_ti(.int, nr_muls) + return types.new_ti(.int, 'int', types.int_type_idx, nr_muls) } 'i64' { - return types.new_builtin_ti(.i64, nr_muls) + return types.new_ti(.i64, 'i64', types.i64_type_idx, nr_muls) } 'byte' { - return types.new_builtin_ti(.byte, nr_muls) + return types.new_ti(.byte, 'byte', types.byte_type_idx, nr_muls) } 'u16' { - return types.new_builtin_ti(.u16, nr_muls) + return types.new_ti(.u16, 'u16', types.u16_type_idx, nr_muls) } 'u32' { - return types.new_builtin_ti(.u32, nr_muls) + return types.new_ti(.u32, 'u32', types.u32_type_idx, nr_muls) } 'u64' { - return types.new_builtin_ti(.u64, nr_muls) + return types.new_ti(.u64, 'u64', types.u64_type_idx, nr_muls) } 'f32' { - return types.new_builtin_ti(.f32, nr_muls) + return types.new_ti(.f32, 'f32', types.f32_type_idx, nr_muls) } 'f64' { - return types.new_builtin_ti(.f64, nr_muls) + return types.new_ti(.f64, 'f64', types.f64_type_idx, nr_muls) } 'string' { - return types.new_builtin_ti(.string, nr_muls) + return types.new_ti(.string, 'string', types.string_type_idx, nr_muls) } 'char' { - return types.new_builtin_ti(.char, nr_muls) + return types.new_ti(.char, 'char', types.charptr_type_idx, nr_muls) } 'bool' { - return types.new_builtin_ti(.bool, nr_muls) + return types.new_ti(.bool, 'bool', types.bool_type_idx, nr_muls) } // struct / enum / placeholder else { diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index e1b7dde0a9..552d92647f 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -423,6 +423,10 @@ fn (p mut Parser) index_expr(left ast.Expr) (ast.Expr,types.TypeIdent) { fn (p mut Parser) dot_expr(left ast.Expr, ti types.TypeIdent) (ast.Expr,types.TypeIdent) { p.next() field_name := p.check_name() + println('# $ti.name $ti.idx - $field_name') + if ti.kind != .void { + println('#### void type in dot_expr - field: $field_name') + } struc := p.table.types[ti.idx] as types.Struct // Method call if p.tok.kind == .lpar { @@ -441,6 +445,7 @@ fn (p mut Parser) dot_expr(left ast.Expr, ti types.TypeIdent) (ast.Expr,types.Ty return node,types.int_ti } if !p.table.struct_has_field(struc, field_name) { + // t := p.error('type `$struc.name` has no field `$field_name`') } /* @@ -676,7 +681,8 @@ fn (p mut Parser) parse_number_literal() (ast.Expr,types.TypeIdent) { // val: lit.f64() val: lit } - ti = types.new_builtin_ti(.f64, 0) + // ti = types.new_builtin_ti(.f64, 0) + ti = types.new_ti(.f64, 'f64', types.f64_type_idx, 0) } else { node = ast.IntegerLiteral{ diff --git a/vlib/v/table/table.v b/vlib/v/table/table.v index 8f634178bf..3f80d5612f 100644 --- a/vlib/v/table/table.v +++ b/vlib/v/table/table.v @@ -14,6 +14,7 @@ pub mut: local_vars []Var // fns Hashmap fns map[string]Fn + methods [][]Fn // unknown_calls []ast.CallExpr tmp_cnt int @@ -34,19 +35,61 @@ pub: } pub fn new_table() &Table { - // mut t := &Table{} - // t.register_type(types.void_type) - // t.register_type(types.int_type) - // t.register_type(types.string_type) - // t.register_type(types.f64_type) - // t.register_type(types.bool_type) - // t.register_type(types.voidptr_type) mut t := &Table{} + t.register_builtin_types() + return t +} + +pub fn (t mut Table) register_builtin_types() { // add dummy type at 0 so nothing can go there // save index check, 0 will mean not found - t.types << types.Type{} - t.type_idxs['dymmy_type_at_idx_0'] = 0 - return t + t.register_type(types.Type{}, 'dymmy_type_at_idx_0', 0) + t.register_type(types.Primitive{ + idx: types.void_type_idx + kind: .void + }, 'void', types.void_type_idx) + t.register_type(types.Primitive{ + idx: types.voidptr_type_idx + kind: .voidptr + }, 'voidptr', types.voidptr_type_idx) + t.register_type(types.Primitive{ + idx: types.charptr_type_idx + kind: .charptr + }, 'charptr', types.charptr_type_idx) + t.register_type(types.Primitive{ + idx: types.byteptr_type_idx + kind: .byteptr + }, 'byteptr', types.byteptr_type_idx) + t.register_type(types.Int{ + types.i8_type_idx,8,false}, 'i8', types.i8_type_idx) + t.register_type(types.Int{ + types.i16_type_idx,16,false}, 'i16', types.i16_type_idx) + t.register_type(types.Int{ + types.i64_type_idx,32,false}, 'int', types.int_type_idx) + t.register_type(types.Int{ + types.i64_type_idx,64,false}, 'i64', types.i64_type_idx) + t.register_type(types.Int{ + types.u16_type_idx,16,true}, 'u16', types.u16_type_idx) + t.register_type(types.Int{ + types.u32_type_idx,32,true}, 'u32', types.u32_type_idx) + t.register_type(types.Int{ + types.u64_type_idx,64,true}, 'u64', types.u64_type_idx) + t.register_type(types.Float{ + types.f64_type_idx,32}, 'f32', types.f32_type_idx) + t.register_type(types.Float{ + types.f64_type_idx,64}, 'f64', types.f64_type_idx) + t.register_type(types.String{ + types.string_type_idx}, 'string', types.string_type_idx) + t.register_type(types.Primitive{ + idx: types.char_type_idx + kind: .char + }, 'char', types.char_type_idx) + t.register_type(types.Primitive{ + idx: types.byte_type_idx + kind: .byte + }, 'byte', types.byte_type_idx) + t.register_type(types.Bool{ + types.bool_type_idx}, 'bool', types.bool_type_idx) } pub fn (t &Table) find_var(name string) ?Var { @@ -118,6 +161,7 @@ pub fn (t mut Table) register_fn(new_fn Fn) { pub fn (t mut Table) register_method(ti types.TypeIdent, new_fn Fn) bool { println('register method `$new_fn.name` tiname=$ti.name ') + /* match t.types[ti.idx] { types.Struct { println('got struct') @@ -135,6 +179,12 @@ pub fn (t mut Table) register_method(ti types.TypeIdent, new_fn Fn) bool { name: new_fn.name } t.types[ti.idx] = struc + */ + println('register method `$new_fn.name` struct=$ti.name ') + + println('##### $ti.idx - $t.methods.len') + + t.methods[ti.idx] << new_fn return true } @@ -166,7 +216,7 @@ pub fn (t &Table) struct_has_field(s &types.Struct, name string) bool { } pub fn (t &Table) struct_has_method(s &types.Struct, name string) bool { - for field in s.methods { + for field in t.methods[s.idx] { if field.name == name { return true } @@ -188,6 +238,17 @@ pub fn (t &Table) find_type(name string) ?types.Type { return none } +[inline] +pub fn (t mut Table) register_type(typ types.Type, name string, idx int) { + // sanity check + if idx != t.types.len { + panic('error registering type $name, type.idx must = table.types.len (got `$idx` expected `$t.types.len`') + } + t.type_idxs[name] = idx + t.types << typ + t.methods << []Fn +} + pub fn (t mut Table) register_struct(typ types.Struct) int { println('register_struct($typ.name)') // existing @@ -217,14 +278,12 @@ pub fn (t mut Table) register_struct(typ types.Struct) int { // register println('registering: $typ.name') idx := t.types.len - t.type_idxs[typ.name] = idx - mut struct_type := types.Type{} - struct_type = { + struct_type := { typ | idx:idx, parent_idx:0, } - t.types << struct_type + t.register_type(struct_type, typ.name, idx) return idx } @@ -237,14 +296,12 @@ pub fn (t mut Table) find_or_register_map(key_ti &types.TypeIdent, value_ti &typ } // register idx := t.types.len - mut map_type := types.Type{} - map_type = types.Map{ + map_type := types.Map{ name: name key_type_idx: key_ti.idx value_type_idx: value_ti.idx } - t.type_idxs[name] = idx - t.types << map_type + t.register_type(map_type, name, idx) return idx,name } @@ -256,17 +313,17 @@ pub fn (t mut Table) find_or_register_array(elem_ti &types.TypeIdent, nr_dims in return existing_idx,name } // register + parent_idx := t.type_idxs['array'] idx := t.types.len - mut array_type := types.Type{} - array_type = types.Array{ + array_type := types.Array{ idx: idx + parent_idx: parent_idx name: name elem_type_idx: elem_ti.idx elem_is_ptr: elem_ti.is_ptr() nr_dims: nr_dims } - t.type_idxs[name] = idx - t.types << array_type + t.register_type(array_type, name, idx) return idx,name } @@ -279,8 +336,7 @@ pub fn (t mut Table) find_or_register_array_fixed(elem_ti &types.TypeIdent, size } // register idx := t.types.len - mut array_fixed_type := types.Type{} - array_fixed_type = types.ArrayFixed{ + array_fixed_type := types.ArrayFixed{ idx: idx name: name elem_type_idx: elem_ti.idx @@ -288,8 +344,7 @@ pub fn (t mut Table) find_or_register_array_fixed(elem_ti &types.TypeIdent, size size: size nr_dims: nr_dims } - t.type_idxs[name] = idx - t.types << array_fixed_type + t.register_type(array_fixed_type, name, idx) return idx,name } @@ -305,14 +360,12 @@ pub fn (t mut Table) find_or_register_multi_return(mr_tis []types.TypeIdent) (in } // register idx := t.types.len - mut mr_type := types.Type{} - mr_type = types.MultiReturn{ + mr_type := types.MultiReturn{ idx: idx name: name tis: mr_tis } - t.type_idxs[name] = idx - t.types << mr_type + t.register_type(mr_type, name, idx) return idx,name } @@ -325,25 +378,21 @@ pub fn (t mut Table) find_or_register_variadic(variadic_ti &types.TypeIdent) (in } // register idx := t.types.len - mut variadic_type := types.Type{} - variadic_type = types.Variadic{ + variadic_type := types.Variadic{ idx: idx ti: variadic_ti } - t.type_idxs[name] = idx - t.types << variadic_type + t.register_type(variadic_type, name, idx) return idx,name } pub fn (t mut Table) add_placeholder_type(name string) int { idx := t.types.len - t.type_idxs[name] = t.types.len - mut pt := types.Type{} - pt = types.Placeholder{ + ph_type := types.Placeholder{ idx: idx name: name } println('added placeholder: $name - $idx ') - t.types << pt + t.register_type(ph_type, name, idx) return idx } diff --git a/vlib/v/types/types.v b/vlib/v/types/types.v index f193c8cdc5..aa16a54a2a 100644 --- a/vlib/v/types/types.v +++ b/vlib/v/types/types.v @@ -3,6 +3,26 @@ // that can be found in the LICENSE file. module types +pub const ( + void_type_idx = 1 + voidptr_type_idx = 2 + charptr_type_idx = 3 + byteptr_type_idx = 4 + i8_type_idx = 5 + i16_type_idx = 6 + int_type_idx = 7 + i64_type_idx = 8 + u16_type_idx = 9 + u32_type_idx = 10 + u64_type_idx = 11 + f32_type_idx = 12 + f64_type_idx = 13 + string_type_idx = 14 + char_type_idx = 15 + byte_type_idx = 16 + bool_type_idx = 17 +) + pub enum Kind { placeholder void, @@ -32,8 +52,8 @@ pub enum Kind { variadic } -pub type Type = Placeholder | Void | Voidptr | Charptr | Byteptr | Const | Enum | Struct | -Int | Float | String | Char | Byte | Bool | Array | ArrayFixed | Map | MultiReturn | Variadic +pub type Type = Placeholder | Primitive | Const | Enum | Struct | Int | Float | + String | Bool | Array | ArrayFixed | Map | MultiReturn | Variadic pub struct TypeIdent { pub: @@ -63,6 +83,13 @@ pub fn new_builtin_ti(kind Kind, nr_muls int) TypeIdent { } } +pub const ( + void_ti = new_ti(.void, 'void', void_type_idx, 0) + int_ti = new_ti(.int, 'int', int_type_idx, 0) + string_ti = new_ti(.string, 'string', string_type_idx, 0) + bool_ti = new_ti(.bool, 'bool', bool_type_idx, 0) +) + [inline] pub fn (ti &TypeIdent) is_ptr() bool { return ti.nr_muls > 0 @@ -202,13 +229,12 @@ pub: // kind Kind } -pub struct Void {} - -pub struct Voidptr {} - -pub struct Charptr {} - -pub struct Byteptr {} +// Void | Voidptr | Charptr | Byteptr +pub struct Primitive { +pub: + idx int + kind Kind +} pub struct Const { pub: @@ -240,25 +266,31 @@ pub: pub struct Int { pub: + idx int bit_size u32 is_unsigned bool } pub struct Float { +pub: + idx int bit_size u32 } -pub struct String {} +pub struct String { +pub: + idx int +} -pub struct Char {} - -pub struct Byte {} - -pub struct Bool {} +pub struct Bool { +pub: + idx int +} pub struct Array { pub: idx int + parent_idx int name string elem_type_kind Kind elem_type_idx int @@ -269,6 +301,7 @@ pub: pub struct ArrayFixed { pub: idx int + parent_idx int name string elem_type_kind Kind elem_type_idx int @@ -300,20 +333,31 @@ pub: ti TypeIdent } -pub fn (t Void) str() string { - return 'void' -} - -pub fn (t Voidptr) str() string { - return 'voidptr' -} - -pub fn (t Charptr) str() string { - return 'charptr' -} - -pub fn (t Byteptr) str() string { - return 'byteptr' +pub fn (t Primitive) str() string { + s := match t.kind { + .void { + 'void' + } + .voidptr { + 'voidptr' + } + .charptr { + 'charptr' + } + .byteptr { + 'byteptr' + } + .char { + 'char' + } + .byte { + 'byte' + } + else { + 'unknown' + } + } + return s } pub fn (t Const) str() string { @@ -340,14 +384,6 @@ pub fn (t String) str() string { return 'string' } -pub fn (t Char) str() string { - return 'char' -} - -pub fn (t Byte) str() string { - return 'byte' -} - pub fn (t Array) str() string { return t.name } @@ -373,41 +409,3 @@ pub fn (s &Struct) has_field(name string) bool { } */ - - -pub const ( - void_type = Void{} - voidptr_type = Voidptr{} - charptr_type = Charptr{} - byteptr_type = Byteptr{} - i8_type = Int{ - 8,false} - i16_type = Int{ - 16,false} - int_type = Int{ - 32,false} - i64_type = Int{ - 64,false} - byte_type = Int{ - 8,true} - u16_type = Int{ - 16,true} - u32_type = Int{ - 32,true} - u64_type = Int{ - 64,true} - f32_type = Float{ - 32} - f64_type = Float{ - 64} - string_type = String{} - char_type = Char{} - bool_type = Bool{} -) - -pub const ( - void_ti = new_builtin_ti(.void, 0) - int_ti = new_builtin_ti(.int, 0) - string_ti = new_builtin_ti(.string, 0) - bool_ti = new_builtin_ti(.bool, 0) -)