register methods (wip)
							parent
							
								
									3425934c39
								
							
						
					
					
						commit
						3c0fca9258
					
				| 
						 | 
					@ -166,6 +166,7 @@ pub fn (a array) last() voidptr {
 | 
				
			||||||
	return a.data + (a.len - 1) * a.element_size
 | 
						return a.data + (a.len - 1) * a.element_size
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
// array.left returns a new array using the same buffer as the given array
 | 
					// array.left returns a new array using the same buffer as the given array
 | 
				
			||||||
// with the first `n` elements of the given array.
 | 
					// with the first `n` elements of the given array.
 | 
				
			||||||
fn (a array) left(n int) array {
 | 
					fn (a array) left(n int) array {
 | 
				
			||||||
| 
						 | 
					@ -191,12 +192,7 @@ fn (a array) right(n int) array {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return a.slice(n, a.len)
 | 
						return a.slice(n, a.len)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
// used internally for [2..4]
 | 
					 | 
				
			||||||
fn (a array) slice2(start, _end int, end_max bool) array {
 | 
					 | 
				
			||||||
	end := if end_max { a.len } else { _end }
 | 
					 | 
				
			||||||
	return a.slice(start, end)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// array.slice returns an array using the same buffer as original array
 | 
					// array.slice returns an array using the same buffer as original array
 | 
				
			||||||
// but starting from the `start` element and ending with the element before
 | 
					// but starting from the `start` element and ending with the element before
 | 
				
			||||||
| 
						 | 
					@ -223,6 +219,29 @@ fn (a array) slice(start, _end int) array {
 | 
				
			||||||
	return res
 | 
						return res
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// used internally for [2..4]
 | 
				
			||||||
 | 
					fn (a array) slice2(start, _end int, end_max bool) array {
 | 
				
			||||||
 | 
						end := if end_max { a.len } else { _end }
 | 
				
			||||||
 | 
						return a.slice(start, end)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// array.clone returns an independent copy of a given array
 | 
				
			||||||
 | 
					pub fn (a array) clone() array {
 | 
				
			||||||
 | 
						mut size := a.cap * a.element_size
 | 
				
			||||||
 | 
						if size == 0 {
 | 
				
			||||||
 | 
							size++
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						arr := array{
 | 
				
			||||||
 | 
							len: a.len
 | 
				
			||||||
 | 
							cap: a.cap
 | 
				
			||||||
 | 
							element_size: a.element_size
 | 
				
			||||||
 | 
							data: calloc(size)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						C.memcpy(arr.data, a.data, a.cap * a.element_size)
 | 
				
			||||||
 | 
						return arr
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn (a array) slice_clone(start, _end int) array {
 | 
					fn (a array) slice_clone(start, _end int) array {
 | 
				
			||||||
	mut end := _end
 | 
						mut end := _end
 | 
				
			||||||
	if start > end {
 | 
						if start > end {
 | 
				
			||||||
| 
						 | 
					@ -282,21 +301,6 @@ pub fn (a array) reverse() array {
 | 
				
			||||||
	return arr
 | 
						return arr
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// array.clone returns an independent copy of a given array
 | 
					 | 
				
			||||||
pub fn (a array) clone() array {
 | 
					 | 
				
			||||||
	mut size := a.cap * a.element_size
 | 
					 | 
				
			||||||
	if size == 0 {
 | 
					 | 
				
			||||||
		size++
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	arr := array{
 | 
					 | 
				
			||||||
		len: a.len
 | 
					 | 
				
			||||||
		cap: a.cap
 | 
					 | 
				
			||||||
		element_size: a.element_size
 | 
					 | 
				
			||||||
		data: calloc(size)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	C.memcpy(arr.data, a.data, a.cap * a.element_size)
 | 
					 | 
				
			||||||
	return arr
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
// pub fn (a []int) free() {
 | 
					// pub fn (a []int) free() {
 | 
				
			||||||
[unsafe_fn]
 | 
					[unsafe_fn]
 | 
				
			||||||
| 
						 | 
					@ -364,7 +368,7 @@ pub fn (b []byte) hex() string {
 | 
				
			||||||
pub fn copy(dst, src []byte) int {
 | 
					pub fn copy(dst, src []byte) int {
 | 
				
			||||||
	if dst.len > 0 && src.len > 0 {
 | 
						if dst.len > 0 && src.len > 0 {
 | 
				
			||||||
		min := if dst.len < src.len { dst.len } else { src.len }
 | 
							min := if dst.len < src.len { dst.len } else { src.len }
 | 
				
			||||||
		C.memcpy(dst.data, src.left(min).data, dst.element_size * min)
 | 
							C.memcpy(dst.data, src[min..].data, dst.element_size * min)
 | 
				
			||||||
		return min
 | 
							return min
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return 0
 | 
						return 0
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -222,11 +222,8 @@ fn test_repeat() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn test_right() {
 | 
					fn test_right() {
 | 
				
			||||||
	a := [1, 2, 3, 4]
 | 
						a := [1, 2, 3, 4]
 | 
				
			||||||
	b := a.right(1)
 | 
					 | 
				
			||||||
	c := a[1..a.len]
 | 
						c := a[1..a.len]
 | 
				
			||||||
	d := a[1..]
 | 
						d := a[1..]
 | 
				
			||||||
	assert b[0] == 2
 | 
					 | 
				
			||||||
	assert b[1] == 3
 | 
					 | 
				
			||||||
	assert c[0] == 2
 | 
						assert c[0] == 2
 | 
				
			||||||
	assert c[1] == 3
 | 
						assert c[1] == 3
 | 
				
			||||||
	assert d[0] == 2
 | 
						assert d[0] == 2
 | 
				
			||||||
| 
						 | 
					@ -252,18 +249,13 @@ fn test_right_with_n_bigger_than_array_size() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn test_left() {
 | 
					fn test_left() {
 | 
				
			||||||
	a := [1, 2, 3]
 | 
						a := [1, 2, 3]
 | 
				
			||||||
	b := a.left(2)
 | 
					 | 
				
			||||||
	c := a[0..2]
 | 
						c := a[0..2]
 | 
				
			||||||
	d := a[..2]
 | 
						d := a[..2]
 | 
				
			||||||
    e := a.left(4)
 | 
					 | 
				
			||||||
	assert b[0] == 1
 | 
					 | 
				
			||||||
	assert b[1] == 2
 | 
					 | 
				
			||||||
	assert c[0] == 1
 | 
						assert c[0] == 1
 | 
				
			||||||
	assert c[1] == 2
 | 
						assert c[1] == 2
 | 
				
			||||||
	assert d[0] == 1
 | 
						assert d[0] == 1
 | 
				
			||||||
	assert d[1] == 2
 | 
						assert d[1] == 2
 | 
				
			||||||
    assert e[0] == 1
 | 
					    assert e[0] == 1
 | 
				
			||||||
    assert e[2] == 3
 | 
					 | 
				
			||||||
    assert e.len == 3
 | 
					    assert e.len == 3
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -149,6 +149,7 @@ $c_common_macros
 | 
				
			||||||
byte g_str_buf[1024];
 | 
					byte g_str_buf[1024];
 | 
				
			||||||
int load_so(byteptr);
 | 
					int load_so(byteptr);
 | 
				
			||||||
void reload_so();
 | 
					void reload_so();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
'
 | 
					'
 | 
				
			||||||
	js_headers = '
 | 
						js_headers = '
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -77,6 +77,18 @@ fn (p mut Parser) bool_expression() string {
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			p.cgen.set_placeholder(start_ph, '*($cast_typ*)')
 | 
								p.cgen.set_placeholder(start_ph, '*($cast_typ*)')
 | 
				
			||||||
			p.gen('.obj')
 | 
								p.gen('.obj')
 | 
				
			||||||
 | 
								// Make sure the sum type can be cast, otherwise throw a runtime error
 | 
				
			||||||
 | 
								/*
 | 
				
			||||||
 | 
								sum_type:= p.cgen.cur_line.all_after('*) (').replace('.obj', '.typ')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								n := cast_typ.all_after('__')
 | 
				
			||||||
 | 
								p.cgen.insert_before('if (($sum_type != SumType_$n) {
 | 
				
			||||||
 | 
					puts("runtime error: $p.file_name:$p.scanner.line_nr cannot cast sum type `$typ` to `$n`");
 | 
				
			||||||
 | 
					exit(1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					')
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			p.cgen.set_placeholder(start_ph, '($cast_typ)(')
 | 
								p.cgen.set_placeholder(start_ph, '($cast_typ)(')
 | 
				
			||||||
			p.gen(')')
 | 
								p.gen(')')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -137,7 +137,17 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
 | 
				
			||||||
		ti = p.parse_ti()
 | 
							ti = p.parse_ti()
 | 
				
			||||||
		p.return_ti = ti
 | 
							p.return_ti = ti
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if !is_method {
 | 
						if is_method {
 | 
				
			||||||
 | 
							ok := p.table.register_method(rec_ti, table.Fn{
 | 
				
			||||||
 | 
								name: name
 | 
				
			||||||
 | 
								args: args
 | 
				
			||||||
 | 
								return_ti: ti
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
							if !ok {
 | 
				
			||||||
 | 
								p.error('expected Struct')
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						else {
 | 
				
			||||||
		p.table.register_fn(table.Fn{
 | 
							p.table.register_fn(table.Fn{
 | 
				
			||||||
			name: name
 | 
								name: name
 | 
				
			||||||
			args: args
 | 
								args: args
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -423,19 +423,12 @@ 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()
 | 
				
			||||||
	typ := p.table.types[ti.idx] as types.Struct
 | 
						struc := p.table.types[ti.idx] as types.Struct
 | 
				
			||||||
	mut ok := false
 | 
					 | 
				
			||||||
	for field in typ.fields {
 | 
					 | 
				
			||||||
		if field.name == field_name {
 | 
					 | 
				
			||||||
			ok = true
 | 
					 | 
				
			||||||
			break
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if !ok {
 | 
					 | 
				
			||||||
		p.error('type `$typ.name` has no field or method `$field_name`')
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// Method call
 | 
						// Method call
 | 
				
			||||||
	if p.tok.kind == .lpar {
 | 
						if p.tok.kind == .lpar {
 | 
				
			||||||
 | 
							if !p.table.struct_has_method(struc, field_name) {
 | 
				
			||||||
 | 
								p.error('type `$struc.name` has no method `$field_name`')
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		p.next()
 | 
							p.next()
 | 
				
			||||||
		args := p.call_args()
 | 
							args := p.call_args()
 | 
				
			||||||
		println('method call $field_name')
 | 
							println('method call $field_name')
 | 
				
			||||||
| 
						 | 
					@ -447,6 +440,9 @@ 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) {
 | 
				
			||||||
 | 
							p.error('type `$struc.name` has no field  `$field_name`')
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
				// p.next()
 | 
									// p.next()
 | 
				
			||||||
				field := p.check_name()
 | 
									field := p.check_name()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -116,8 +116,234 @@ pub fn (t mut Table) register_fn(new_fn Fn) {
 | 
				
			||||||
	t.fns[new_fn.name] = new_fn
 | 
						t.fns[new_fn.name] = new_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')
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						mut struc := t.types[ti.idx] as types.Struct
 | 
				
			||||||
 | 
						if struc.methods.len == 0 {
 | 
				
			||||||
 | 
							struc.methods = make(0, 0, sizeof(types.Field))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						println('register method `$new_fn.name` struct=$struc.name ')
 | 
				
			||||||
 | 
						struc.methods << types.Field{
 | 
				
			||||||
 | 
							name: new_fn.name
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.types[ti.idx] = struc
 | 
				
			||||||
 | 
						return true
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn (t mut Table) new_tmp_var() string {
 | 
					pub fn (t mut Table) new_tmp_var() string {
 | 
				
			||||||
	t.tmp_cnt++
 | 
						t.tmp_cnt++
 | 
				
			||||||
	return 'tmp$t.tmp_cnt'
 | 
						return 'tmp$t.tmp_cnt'
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn (t &Table) struct_has_field(s &types.Struct, name string) bool {
 | 
				
			||||||
 | 
						println('struct_has_field($s.name, $name) s.idx=$s.idx types.len=$t.types.len s.parent_idx=$s.parent_idx')
 | 
				
			||||||
 | 
						// for typ in t.types {
 | 
				
			||||||
 | 
						// println('$typ.idx $typ.name')
 | 
				
			||||||
 | 
						// }
 | 
				
			||||||
 | 
						for field in s.fields {
 | 
				
			||||||
 | 
							if field.name == name {
 | 
				
			||||||
 | 
								return true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if s.parent_idx != 0 {
 | 
				
			||||||
 | 
							parent := t.types[s.parent_idx] as types.Struct
 | 
				
			||||||
 | 
							println('got parent $parent.name')
 | 
				
			||||||
 | 
							for field in parent.fields {
 | 
				
			||||||
 | 
								if field.name == name {
 | 
				
			||||||
 | 
									return true
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn (t &Table) struct_has_method(s &types.Struct, name string) bool {
 | 
				
			||||||
 | 
						for field in s.methods {
 | 
				
			||||||
 | 
							if field.name == name {
 | 
				
			||||||
 | 
								return true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[inline]
 | 
				
			||||||
 | 
					pub fn (t &Table) find_type_idx(name string) int {
 | 
				
			||||||
 | 
						return t.type_idxs[name]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[inline]
 | 
				
			||||||
 | 
					pub fn (t &Table) find_type(name string) ?types.Type {
 | 
				
			||||||
 | 
						idx := t.type_idxs[name]
 | 
				
			||||||
 | 
						if idx > 0 {
 | 
				
			||||||
 | 
							return t.types[idx]
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return none
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn (t mut Table) register_struct(typ types.Struct) int {
 | 
				
			||||||
 | 
						println('register_struct($typ.name)')
 | 
				
			||||||
 | 
						// existing
 | 
				
			||||||
 | 
						existing_idx := t.type_idxs[typ.name]
 | 
				
			||||||
 | 
						if existing_idx > 0 {
 | 
				
			||||||
 | 
							ex_type := t.types[existing_idx]
 | 
				
			||||||
 | 
							match ex_type {
 | 
				
			||||||
 | 
								types.Placeholder {
 | 
				
			||||||
 | 
									// override placeholder
 | 
				
			||||||
 | 
									println('overriding type placeholder `$it.name` with struct')
 | 
				
			||||||
 | 
									mut struct_type := types.Type{}
 | 
				
			||||||
 | 
									struct_type = {
 | 
				
			||||||
 | 
										typ |
 | 
				
			||||||
 | 
										idx:existing_idx
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									t.types[existing_idx] = struct_type
 | 
				
			||||||
 | 
									return existing_idx
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								types.Struct {
 | 
				
			||||||
 | 
									return existing_idx
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else {
 | 
				
			||||||
 | 
									panic('cannot register type `$typ.name`, another type with this name exists')
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// register
 | 
				
			||||||
 | 
						println('registering: $typ.name')
 | 
				
			||||||
 | 
						idx := t.types.len
 | 
				
			||||||
 | 
						t.type_idxs[typ.name] = idx
 | 
				
			||||||
 | 
						mut struct_type := types.Type{}
 | 
				
			||||||
 | 
						struct_type = {
 | 
				
			||||||
 | 
							typ |
 | 
				
			||||||
 | 
							idx:idx,
 | 
				
			||||||
 | 
							parent_idx:0,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.types << struct_type
 | 
				
			||||||
 | 
						return idx
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn (t mut Table) find_or_register_map(key_ti &types.TypeIdent, value_ti &types.TypeIdent) (int,string) {
 | 
				
			||||||
 | 
						name := 'map_${key_ti.name}_${value_ti.name}'
 | 
				
			||||||
 | 
						// existing
 | 
				
			||||||
 | 
						existing_idx := t.type_idxs[name]
 | 
				
			||||||
 | 
						if existing_idx > 0 {
 | 
				
			||||||
 | 
							return existing_idx,name
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// register
 | 
				
			||||||
 | 
						idx := t.types.len
 | 
				
			||||||
 | 
						mut map_type := types.Type{}
 | 
				
			||||||
 | 
						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
 | 
				
			||||||
 | 
						return idx,name
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn (t mut Table) find_or_register_array(elem_ti &types.TypeIdent, nr_dims int) (int,string) {
 | 
				
			||||||
 | 
						name := 'array_${elem_ti.name}' + if nr_dims > 1 { '_${nr_dims}d' } else { '' }
 | 
				
			||||||
 | 
						// existing
 | 
				
			||||||
 | 
						existing_idx := t.type_idxs[name]
 | 
				
			||||||
 | 
						if existing_idx > 0 {
 | 
				
			||||||
 | 
							return existing_idx,name
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// register
 | 
				
			||||||
 | 
						idx := t.types.len
 | 
				
			||||||
 | 
						mut array_type := types.Type{}
 | 
				
			||||||
 | 
						array_type = types.Array{
 | 
				
			||||||
 | 
							idx: 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
 | 
				
			||||||
 | 
						return idx,name
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn (t mut Table) find_or_register_array_fixed(elem_ti &types.TypeIdent, size int, nr_dims int) (int,string) {
 | 
				
			||||||
 | 
						name := 'array_fixed_${elem_ti.name}_${size}' + if nr_dims > 1 { '_${nr_dims}d' } else { '' }
 | 
				
			||||||
 | 
						// existing
 | 
				
			||||||
 | 
						existing_idx := t.type_idxs[name]
 | 
				
			||||||
 | 
						if existing_idx > 0 {
 | 
				
			||||||
 | 
							return existing_idx,name
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// register
 | 
				
			||||||
 | 
						idx := t.types.len
 | 
				
			||||||
 | 
						mut array_fixed_type := types.Type{}
 | 
				
			||||||
 | 
						array_fixed_type = types.ArrayFixed{
 | 
				
			||||||
 | 
							idx: idx
 | 
				
			||||||
 | 
							name: name
 | 
				
			||||||
 | 
							elem_type_idx: elem_ti.idx
 | 
				
			||||||
 | 
							elem_is_ptr: elem_ti.is_ptr()
 | 
				
			||||||
 | 
							size: size
 | 
				
			||||||
 | 
							nr_dims: nr_dims
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.type_idxs[name] = idx
 | 
				
			||||||
 | 
						t.types << array_fixed_type
 | 
				
			||||||
 | 
						return idx,name
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn (t mut Table) find_or_register_multi_return(mr_tis []types.TypeIdent) (int,string) {
 | 
				
			||||||
 | 
						mut name := 'multi_return'
 | 
				
			||||||
 | 
						for mr_ti in mr_tis {
 | 
				
			||||||
 | 
							name += '_$mr_ti.name'
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// existing
 | 
				
			||||||
 | 
						existing_idx := t.type_idxs[name]
 | 
				
			||||||
 | 
						if existing_idx > 0 {
 | 
				
			||||||
 | 
							return existing_idx,name
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// register
 | 
				
			||||||
 | 
						idx := t.types.len
 | 
				
			||||||
 | 
						mut mr_type := types.Type{}
 | 
				
			||||||
 | 
						mr_type = types.MultiReturn{
 | 
				
			||||||
 | 
							idx: idx
 | 
				
			||||||
 | 
							name: name
 | 
				
			||||||
 | 
							tis: mr_tis
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.type_idxs[name] = idx
 | 
				
			||||||
 | 
						t.types << mr_type
 | 
				
			||||||
 | 
						return idx,name
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn (t mut Table) find_or_register_variadic(variadic_ti &types.TypeIdent) (int,string) {
 | 
				
			||||||
 | 
						name := 'variadic_$variadic_ti.name'
 | 
				
			||||||
 | 
						// existing
 | 
				
			||||||
 | 
						existing_idx := t.type_idxs[name]
 | 
				
			||||||
 | 
						if existing_idx > 0 {
 | 
				
			||||||
 | 
							return existing_idx,name
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// register
 | 
				
			||||||
 | 
						idx := t.types.len
 | 
				
			||||||
 | 
						mut variadic_type := types.Type{}
 | 
				
			||||||
 | 
						variadic_type = types.Variadic{
 | 
				
			||||||
 | 
							idx: idx
 | 
				
			||||||
 | 
							ti: variadic_ti
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						t.type_idxs[name] = idx
 | 
				
			||||||
 | 
						t.types << variadic_type
 | 
				
			||||||
 | 
						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{
 | 
				
			||||||
 | 
							idx: idx
 | 
				
			||||||
 | 
							name: name
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						println('added placeholder: $name - $idx ')
 | 
				
			||||||
 | 
						t.types << pt
 | 
				
			||||||
 | 
						return idx
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,178 +0,0 @@
 | 
				
			||||||
// 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 table
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import v.types
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[inline]
 | 
					 | 
				
			||||||
pub fn (t &Table) find_type_idx(name string) int {
 | 
					 | 
				
			||||||
	return t.type_idxs[name]
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[inline]
 | 
					 | 
				
			||||||
pub fn (t &Table) find_type(name string) ?types.Type {
 | 
					 | 
				
			||||||
	idx := t.type_idxs[name]
 | 
					 | 
				
			||||||
	if idx > 0 {
 | 
					 | 
				
			||||||
		return t.types[idx]
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return none
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn (t mut Table) register_struct(typ types.Struct) int {
 | 
					 | 
				
			||||||
	// existing
 | 
					 | 
				
			||||||
	existing_idx := t.type_idxs[typ.name]
 | 
					 | 
				
			||||||
	if existing_idx > 0 {
 | 
					 | 
				
			||||||
		ex_type := t.types[existing_idx]
 | 
					 | 
				
			||||||
		match ex_type {
 | 
					 | 
				
			||||||
			types.Placeholder {
 | 
					 | 
				
			||||||
				// override placeholder
 | 
					 | 
				
			||||||
				println('overriding type placeholder `$it.name` with struct')
 | 
					 | 
				
			||||||
				mut struct_type := types.Type{}
 | 
					 | 
				
			||||||
				struct_type = {
 | 
					 | 
				
			||||||
					typ |
 | 
					 | 
				
			||||||
					idx:existing_idx
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				t.types[existing_idx] = struct_type
 | 
					 | 
				
			||||||
				return existing_idx
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			types.Struct {
 | 
					 | 
				
			||||||
				return existing_idx
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			else {
 | 
					 | 
				
			||||||
				panic('cannot register type `$typ.name`, another type with this name exists')
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// register
 | 
					 | 
				
			||||||
	println('registering: $typ.name')
 | 
					 | 
				
			||||||
	idx := t.types.len
 | 
					 | 
				
			||||||
	t.type_idxs[typ.name] = idx
 | 
					 | 
				
			||||||
	mut struct_type := types.Type{}
 | 
					 | 
				
			||||||
	struct_type = {
 | 
					 | 
				
			||||||
		typ |
 | 
					 | 
				
			||||||
		idx:idx
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	t.types << struct_type
 | 
					 | 
				
			||||||
	return idx
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn (t mut Table) find_or_register_map(key_ti &types.TypeIdent, value_ti &types.TypeIdent) (int,string) {
 | 
					 | 
				
			||||||
	name := 'map_${key_ti.name}_${value_ti.name}'
 | 
					 | 
				
			||||||
	// existing
 | 
					 | 
				
			||||||
	existing_idx := t.type_idxs[name]
 | 
					 | 
				
			||||||
	if existing_idx > 0 {
 | 
					 | 
				
			||||||
		return existing_idx,name
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// register
 | 
					 | 
				
			||||||
	idx := t.types.len
 | 
					 | 
				
			||||||
	mut map_type := types.Type{}
 | 
					 | 
				
			||||||
	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
 | 
					 | 
				
			||||||
	return idx,name
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn (t mut Table) find_or_register_array(elem_ti &types.TypeIdent, nr_dims int) (int,string) {
 | 
					 | 
				
			||||||
	name := 'array_${elem_ti.name}' + if nr_dims > 1 { '_${nr_dims}d' } else { '' }
 | 
					 | 
				
			||||||
	// existing
 | 
					 | 
				
			||||||
	existing_idx := t.type_idxs[name]
 | 
					 | 
				
			||||||
	if existing_idx > 0 {
 | 
					 | 
				
			||||||
		return existing_idx,name
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// register
 | 
					 | 
				
			||||||
	idx := t.types.len
 | 
					 | 
				
			||||||
	mut array_type := types.Type{}
 | 
					 | 
				
			||||||
	array_type = types.Array{
 | 
					 | 
				
			||||||
		idx: 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
 | 
					 | 
				
			||||||
	return idx,name
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn (t mut Table) find_or_register_array_fixed(elem_ti &types.TypeIdent, size int, nr_dims int) (int,string) {
 | 
					 | 
				
			||||||
	name := 'array_fixed_${elem_ti.name}_${size}' + if nr_dims > 1 { '_${nr_dims}d' } else { '' }
 | 
					 | 
				
			||||||
	// existing
 | 
					 | 
				
			||||||
	existing_idx := t.type_idxs[name]
 | 
					 | 
				
			||||||
	if existing_idx > 0 {
 | 
					 | 
				
			||||||
		return existing_idx,name
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// register
 | 
					 | 
				
			||||||
	idx := t.types.len
 | 
					 | 
				
			||||||
	mut array_fixed_type := types.Type{}
 | 
					 | 
				
			||||||
	array_fixed_type = types.ArrayFixed{
 | 
					 | 
				
			||||||
		idx: idx
 | 
					 | 
				
			||||||
		name: name
 | 
					 | 
				
			||||||
		elem_type_idx: elem_ti.idx
 | 
					 | 
				
			||||||
		elem_is_ptr: elem_ti.is_ptr()
 | 
					 | 
				
			||||||
		size: size
 | 
					 | 
				
			||||||
		nr_dims: nr_dims
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	t.type_idxs[name] = idx
 | 
					 | 
				
			||||||
	t.types << array_fixed_type
 | 
					 | 
				
			||||||
	return idx,name
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn (t mut Table) find_or_register_multi_return(mr_tis []types.TypeIdent) (int,string) {
 | 
					 | 
				
			||||||
	mut name := 'multi_return'
 | 
					 | 
				
			||||||
	for mr_ti in mr_tis {
 | 
					 | 
				
			||||||
		name += '_$mr_ti.name'
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// existing
 | 
					 | 
				
			||||||
	existing_idx := t.type_idxs[name]
 | 
					 | 
				
			||||||
	if existing_idx > 0 {
 | 
					 | 
				
			||||||
		return existing_idx,name
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// register
 | 
					 | 
				
			||||||
	idx := t.types.len
 | 
					 | 
				
			||||||
	mut mr_type := types.Type{}
 | 
					 | 
				
			||||||
	mr_type = types.MultiReturn{
 | 
					 | 
				
			||||||
		idx: idx
 | 
					 | 
				
			||||||
		name: name
 | 
					 | 
				
			||||||
		tis: mr_tis
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	t.type_idxs[name] = idx
 | 
					 | 
				
			||||||
	t.types << mr_type
 | 
					 | 
				
			||||||
	return idx,name
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn (t mut Table) find_or_register_variadic(variadic_ti &types.TypeIdent) (int,string) {
 | 
					 | 
				
			||||||
	name := 'variadic_$variadic_ti.name'
 | 
					 | 
				
			||||||
	// existing
 | 
					 | 
				
			||||||
	existing_idx := t.type_idxs[name]
 | 
					 | 
				
			||||||
	if existing_idx > 0 {
 | 
					 | 
				
			||||||
		return existing_idx,name
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// register
 | 
					 | 
				
			||||||
	idx := t.types.len
 | 
					 | 
				
			||||||
	mut variadic_type := types.Type{}
 | 
					 | 
				
			||||||
	variadic_type = types.Variadic{
 | 
					 | 
				
			||||||
		idx: idx
 | 
					 | 
				
			||||||
		ti: variadic_ti
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	t.type_idxs[name] = idx
 | 
					 | 
				
			||||||
	t.types << variadic_type
 | 
					 | 
				
			||||||
	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{
 | 
					 | 
				
			||||||
		idx: idx
 | 
					 | 
				
			||||||
		name: name
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	println('added placeholder: $name - $idx ')
 | 
					 | 
				
			||||||
	t.types << pt
 | 
					 | 
				
			||||||
	return idx
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -225,9 +225,11 @@ pub:
 | 
				
			||||||
pub struct Struct {
 | 
					pub struct Struct {
 | 
				
			||||||
pub:
 | 
					pub:
 | 
				
			||||||
	idx        int
 | 
						idx        int
 | 
				
			||||||
 | 
						parent_idx int
 | 
				
			||||||
	name       string
 | 
						name       string
 | 
				
			||||||
 | 
					pub mut:
 | 
				
			||||||
	fields     []Field
 | 
						fields     []Field
 | 
				
			||||||
	// methods
 | 
						methods    []Field // TODO Method
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct Field {
 | 
					pub struct Field {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue