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)
}
'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 {

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) {
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{

View File

@ -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
}

View File

@ -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)
)