v: initial type work for methods / struct fields

pull/3375/head
joe-conigliaro 2020-01-09 03:14:42 +11:00 committed by Alexander Medvednikov
parent 526f12feff
commit 38e5f0d1cf
4 changed files with 184 additions and 131 deletions

View File

@ -98,52 +98,52 @@ pub fn (p mut Parser) parse_ti() types.TypeIdent {
return p.parse_map_ti(nr_muls) return p.parse_map_ti(nr_muls)
} }
'voidptr' { 'voidptr' {
return types.new_builtin_ti(.voidptr, nr_muls) return types.new_ti(.voidptr, 'voidptr', types.voidptr_type_idx, nr_muls)
} }
'byteptr' { 'byteptr' {
return types.new_builtin_ti(.byteptr, nr_muls) return types.new_ti(.byteptr, 'byteptr', types.byteptr_type_idx, nr_muls)
} }
'charptr' { 'charptr' {
return types.new_builtin_ti(.charptr, nr_muls) return types.new_ti(.charptr, 'charptr', types.charptr_type_idx, nr_muls)
} }
'i8' { 'i8' {
return types.new_builtin_ti(.i8, nr_muls) return types.new_ti(.i8, 'i8', types.i8_type_idx, nr_muls)
} }
'i16' { 'i16' {
return types.new_builtin_ti(.i16, nr_muls) return types.new_ti(.i16, 'i16', types.i16_type_idx, nr_muls)
} }
'int' { 'int' {
return types.new_builtin_ti(.int, nr_muls) return types.new_ti(.int, 'int', types.int_type_idx, nr_muls)
} }
'i64' { 'i64' {
return types.new_builtin_ti(.i64, nr_muls) return types.new_ti(.i64, 'i64', types.i64_type_idx, nr_muls)
} }
'byte' { 'byte' {
return types.new_builtin_ti(.byte, nr_muls) return types.new_ti(.byte, 'byte', types.byte_type_idx, nr_muls)
} }
'u16' { 'u16' {
return types.new_builtin_ti(.u16, nr_muls) return types.new_ti(.u16, 'u16', types.u16_type_idx, nr_muls)
} }
'u32' { 'u32' {
return types.new_builtin_ti(.u32, nr_muls) return types.new_ti(.u32, 'u32', types.u32_type_idx, nr_muls)
} }
'u64' { 'u64' {
return types.new_builtin_ti(.u64, nr_muls) return types.new_ti(.u64, 'u64', types.u64_type_idx, nr_muls)
} }
'f32' { 'f32' {
return types.new_builtin_ti(.f32, nr_muls) return types.new_ti(.f32, 'f32', types.f32_type_idx, nr_muls)
} }
'f64' { 'f64' {
return types.new_builtin_ti(.f64, nr_muls) return types.new_ti(.f64, 'f64', types.f64_type_idx, nr_muls)
} }
'string' { 'string' {
return types.new_builtin_ti(.string, nr_muls) return types.new_ti(.string, 'string', types.string_type_idx, nr_muls)
} }
'char' { 'char' {
return types.new_builtin_ti(.char, nr_muls) return types.new_ti(.char, 'char', types.charptr_type_idx, nr_muls)
} }
'bool' { 'bool' {
return types.new_builtin_ti(.bool, nr_muls) return types.new_ti(.bool, 'bool', types.bool_type_idx, nr_muls)
} }
// struct / enum / placeholder // struct / enum / placeholder
else { else {

View File

@ -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) { fn (p mut Parser) dot_expr(left ast.Expr, ti types.TypeIdent) (ast.Expr,types.TypeIdent) {
p.next() p.next()
field_name := p.check_name() 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 struc := p.table.types[ti.idx] as types.Struct
// Method call // Method call
if p.tok.kind == .lpar { 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 return node,types.int_ti
} }
if !p.table.struct_has_field(struc, field_name) { if !p.table.struct_has_field(struc, field_name) {
// t :=
p.error('type `$struc.name` has no field `$field_name`') 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.f64()
val: lit 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 { else {
node = ast.IntegerLiteral{ node = ast.IntegerLiteral{

View File

@ -14,6 +14,7 @@ pub mut:
local_vars []Var local_vars []Var
// fns Hashmap // fns Hashmap
fns map[string]Fn fns map[string]Fn
methods [][]Fn
// //
unknown_calls []ast.CallExpr unknown_calls []ast.CallExpr
tmp_cnt int tmp_cnt int
@ -34,19 +35,61 @@ pub:
} }
pub fn new_table() &Table { 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{} 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 // add dummy type at 0 so nothing can go there
// save index check, 0 will mean not found // save index check, 0 will mean not found
t.types << types.Type{} t.register_type(types.Type{}, 'dymmy_type_at_idx_0', 0)
t.type_idxs['dymmy_type_at_idx_0'] = 0 t.register_type(types.Primitive{
return t 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 { 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 { pub fn (t mut Table) register_method(ti types.TypeIdent, new_fn Fn) bool {
println('register method `$new_fn.name` tiname=$ti.name ') println('register method `$new_fn.name` tiname=$ti.name ')
/*
match t.types[ti.idx] { match t.types[ti.idx] {
types.Struct { types.Struct {
println('got 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 name: new_fn.name
} }
t.types[ti.idx] = struc 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 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 { 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 { if field.name == name {
return true return true
} }
@ -188,6 +238,17 @@ pub fn (t &Table) find_type(name string) ?types.Type {
return none 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 { pub fn (t mut Table) register_struct(typ types.Struct) int {
println('register_struct($typ.name)') println('register_struct($typ.name)')
// existing // existing
@ -217,14 +278,12 @@ pub fn (t mut Table) register_struct(typ types.Struct) int {
// register // register
println('registering: $typ.name') println('registering: $typ.name')
idx := t.types.len idx := t.types.len
t.type_idxs[typ.name] = idx struct_type := {
mut struct_type := types.Type{}
struct_type = {
typ | typ |
idx:idx, idx:idx,
parent_idx:0, parent_idx:0,
} }
t.types << struct_type t.register_type(struct_type, typ.name, idx)
return idx return idx
} }
@ -237,14 +296,12 @@ pub fn (t mut Table) find_or_register_map(key_ti &types.TypeIdent, value_ti &typ
} }
// register // register
idx := t.types.len idx := t.types.len
mut map_type := types.Type{} map_type := types.Map{
map_type = types.Map{
name: name name: name
key_type_idx: key_ti.idx key_type_idx: key_ti.idx
value_type_idx: value_ti.idx value_type_idx: value_ti.idx
} }
t.type_idxs[name] = idx t.register_type(map_type, name, idx)
t.types << map_type
return idx,name 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 return existing_idx,name
} }
// register // register
parent_idx := t.type_idxs['array']
idx := t.types.len idx := t.types.len
mut array_type := types.Type{} array_type := types.Array{
array_type = types.Array{
idx: idx idx: idx
parent_idx: parent_idx
name: name name: name
elem_type_idx: elem_ti.idx elem_type_idx: elem_ti.idx
elem_is_ptr: elem_ti.is_ptr() elem_is_ptr: elem_ti.is_ptr()
nr_dims: nr_dims nr_dims: nr_dims
} }
t.type_idxs[name] = idx t.register_type(array_type, name, idx)
t.types << array_type
return idx,name return idx,name
} }
@ -279,8 +336,7 @@ pub fn (t mut Table) find_or_register_array_fixed(elem_ti &types.TypeIdent, size
} }
// register // register
idx := t.types.len idx := t.types.len
mut array_fixed_type := types.Type{} array_fixed_type := types.ArrayFixed{
array_fixed_type = types.ArrayFixed{
idx: idx idx: idx
name: name name: name
elem_type_idx: elem_ti.idx 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 size: size
nr_dims: nr_dims nr_dims: nr_dims
} }
t.type_idxs[name] = idx t.register_type(array_fixed_type, name, idx)
t.types << array_fixed_type
return idx,name return idx,name
} }
@ -305,14 +360,12 @@ pub fn (t mut Table) find_or_register_multi_return(mr_tis []types.TypeIdent) (in
} }
// register // register
idx := t.types.len idx := t.types.len
mut mr_type := types.Type{} mr_type := types.MultiReturn{
mr_type = types.MultiReturn{
idx: idx idx: idx
name: name name: name
tis: mr_tis tis: mr_tis
} }
t.type_idxs[name] = idx t.register_type(mr_type, name, idx)
t.types << mr_type
return idx,name return idx,name
} }
@ -325,25 +378,21 @@ pub fn (t mut Table) find_or_register_variadic(variadic_ti &types.TypeIdent) (in
} }
// register // register
idx := t.types.len idx := t.types.len
mut variadic_type := types.Type{} variadic_type := types.Variadic{
variadic_type = types.Variadic{
idx: idx idx: idx
ti: variadic_ti ti: variadic_ti
} }
t.type_idxs[name] = idx t.register_type(variadic_type, name, idx)
t.types << variadic_type
return idx,name return idx,name
} }
pub fn (t mut Table) add_placeholder_type(name string) int { pub fn (t mut Table) add_placeholder_type(name string) int {
idx := t.types.len idx := t.types.len
t.type_idxs[name] = t.types.len ph_type := types.Placeholder{
mut pt := types.Type{}
pt = types.Placeholder{
idx: idx idx: idx
name: name name: name
} }
println('added placeholder: $name - $idx ') println('added placeholder: $name - $idx ')
t.types << pt t.register_type(ph_type, name, idx)
return idx return idx
} }

View File

@ -3,6 +3,26 @@
// that can be found in the LICENSE file. // that can be found in the LICENSE file.
module types 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 { pub enum Kind {
placeholder placeholder
void, void,
@ -32,8 +52,8 @@ pub enum Kind {
variadic variadic
} }
pub type Type = Placeholder | Void | Voidptr | Charptr | Byteptr | Const | Enum | Struct | pub type Type = Placeholder | Primitive | Const | Enum | Struct | Int | Float |
Int | Float | String | Char | Byte | Bool | Array | ArrayFixed | Map | MultiReturn | Variadic String | Bool | Array | ArrayFixed | Map | MultiReturn | Variadic
pub struct TypeIdent { pub struct TypeIdent {
pub: 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] [inline]
pub fn (ti &TypeIdent) is_ptr() bool { pub fn (ti &TypeIdent) is_ptr() bool {
return ti.nr_muls > 0 return ti.nr_muls > 0
@ -202,13 +229,12 @@ pub:
// kind Kind // kind Kind
} }
pub struct Void {} // Void | Voidptr | Charptr | Byteptr
pub struct Primitive {
pub struct Voidptr {} pub:
idx int
pub struct Charptr {} kind Kind
}
pub struct Byteptr {}
pub struct Const { pub struct Const {
pub: pub:
@ -240,25 +266,31 @@ pub:
pub struct Int { pub struct Int {
pub: pub:
idx int
bit_size u32 bit_size u32
is_unsigned bool is_unsigned bool
} }
pub struct Float { pub struct Float {
pub:
idx int
bit_size u32 bit_size u32
} }
pub struct String {} pub struct String {
pub:
idx int
}
pub struct Char {} pub struct Bool {
pub:
pub struct Byte {} idx int
}
pub struct Bool {}
pub struct Array { pub struct Array {
pub: pub:
idx int idx int
parent_idx int
name string name string
elem_type_kind Kind elem_type_kind Kind
elem_type_idx int elem_type_idx int
@ -269,6 +301,7 @@ pub:
pub struct ArrayFixed { pub struct ArrayFixed {
pub: pub:
idx int idx int
parent_idx int
name string name string
elem_type_kind Kind elem_type_kind Kind
elem_type_idx int elem_type_idx int
@ -300,20 +333,31 @@ pub:
ti TypeIdent ti TypeIdent
} }
pub fn (t Void) str() string { pub fn (t Primitive) str() string {
return 'void' s := match t.kind {
} .void {
'void'
pub fn (t Voidptr) str() string { }
return 'voidptr' .voidptr {
} 'voidptr'
}
pub fn (t Charptr) str() string { .charptr {
return 'charptr' 'charptr'
} }
.byteptr {
pub fn (t Byteptr) str() string { 'byteptr'
return 'byteptr' }
.char {
'char'
}
.byte {
'byte'
}
else {
'unknown'
}
}
return s
} }
pub fn (t Const) str() string { pub fn (t Const) str() string {
@ -340,14 +384,6 @@ pub fn (t String) str() string {
return '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 { pub fn (t Array) str() string {
return t.name 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)
)