1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

table: simplify/generalise type fns & remove calls

This commit is contained in:
joe-conigliaro 2020-04-04 16:37:11 +11:00
parent bf59828897
commit c9e290b36f
No known key found for this signature in database
GPG Key ID: C12F7136C08206F1
6 changed files with 65 additions and 81 deletions

View File

@ -372,7 +372,7 @@ pub fn (c mut Checker) selector_expr(selector_expr mut ast.SelectorExpr) table.T
typ_sym := c.table.get_type_symbol(typ) typ_sym := c.table.get_type_symbol(typ)
field_name := selector_expr.field field_name := selector_expr.field
// variadic // variadic
if table.type_is_variadic(typ) { if table.type_is(typ, .variadic) {
if field_name == 'len' { if field_name == 'len' {
return table.int_type return table.int_type
} }
@ -401,7 +401,7 @@ pub fn (c mut Checker) return_stmt(return_stmt mut ast.Return) {
} }
expected_type := c.fn_return_type expected_type := c.fn_return_type
expected_type_sym := c.table.get_type_symbol(expected_type) expected_type_sym := c.table.get_type_symbol(expected_type)
exp_is_optional := table.type_is_optional(expected_type) exp_is_optional := table.type_is(expected_type, .optional)
mut expected_types := [expected_type] mut expected_types := [expected_type]
if expected_type_sym.kind == .multi_return { if expected_type_sym.kind == .multi_return {
mr_info := expected_type_sym.info as table.MultiReturn mr_info := expected_type_sym.info as table.MultiReturn
@ -874,14 +874,15 @@ pub fn (c mut Checker) ident(ident mut ast.Ident) table.Type {
if typ == 0 { if typ == 0 {
typ = c.expr(var.expr) typ = c.expr(var.expr)
} }
is_optional := table.type_is(typ, .optional)
ident.kind = .variable ident.kind = .variable
ident.info = ast.IdentVar{ ident.info = ast.IdentVar{
typ: typ typ: typ
is_optional: table.type_is_optional(typ) is_optional: is_optional
} }
// unwrap optional (`println(x)`) // unwrap optional (`println(x)`)
if table.type_is_optional(typ) { if is_optional {
return table.type_clear_extra(typ) return table.type_set(typ, .unset)
} }
return typ return typ
} }

View File

@ -162,7 +162,7 @@ pub fn (g mut Gen) typ(t table.Type) string {
styp = 'struct $styp' styp = 'struct $styp'
} }
} }
if table.type_is_optional(t) { if table.type_is(t, .optional) {
styp = 'Option_' + styp styp = 'Option_' + styp
if !(styp in g.optionals) { if !(styp in g.optionals) {
g.definitions.writeln('typedef Option $styp;') g.definitions.writeln('typedef Option $styp;')
@ -506,7 +506,7 @@ fn (g mut Gen) for_in(it ast.ForInStmt) {
g.stmts(it.stmts) g.stmts(it.stmts)
g.writeln('}') g.writeln('}')
} }
else if table.type_is_variadic(it.cond_type) { else if table.type_is(it.cond_type, .variadic) {
g.writeln('// FOR IN') g.writeln('// FOR IN')
i := if it.key_var == '' { g.new_tmp_var() } else { it.key_var } i := if it.key_var == '' { g.new_tmp_var() } else { it.key_var }
styp := g.typ(it.cond_type) styp := g.typ(it.cond_type)
@ -597,7 +597,7 @@ fn (g mut Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
} }
else {} else {}
} }
is_optional := table.type_is_optional(return_type) is_optional := table.type_is(return_type, .optional)
mr_var_name := 'mr_$assign_stmt.pos.pos' mr_var_name := 'mr_$assign_stmt.pos.pos'
mr_styp := g.typ(return_type) mr_styp := g.typ(return_type)
g.write('$mr_styp $mr_var_name = ') g.write('$mr_styp $mr_var_name = ')
@ -644,7 +644,7 @@ fn (g mut Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
} }
else {} else {}
} }
gen_or := is_call && table.type_is_optional(return_type) gen_or := is_call && table.type_is(return_type, .optional)
g.is_assign_rhs = true g.is_assign_rhs = true
if ident.kind == .blank_ident { if ident.kind == .blank_ident {
if is_call { if is_call {
@ -846,10 +846,11 @@ fn (g mut Gen) free_scope_vars(pos int) {
// } // }
var := *it var := *it
sym := g.table.get_type_symbol(var.typ) sym := g.table.get_type_symbol(var.typ)
if sym.kind == .array && !table.type_is_optional(var.typ) { is_optional := table.type_is(var.typ, .optional)
if sym.kind == .array && !is_optional {
g.writeln('array_free($var.name); // autofreed') g.writeln('array_free($var.name); // autofreed')
} }
if sym.kind == .string && !table.type_is_optional(var.typ) { if sym.kind == .string && !is_optional {
// Don't free simple string literals. // Don't free simple string literals.
t := typeof(var.expr) t := typeof(var.expr)
match var.expr { match var.expr {
@ -1220,7 +1221,7 @@ fn (g mut Gen) assign_expr(node ast.AssignExpr) {
} }
else {} else {}
} }
gen_or := is_call && table.type_is_optional(return_type) gen_or := is_call && table.type_is(return_type, .optional)
tmp_opt := if gen_or { g.new_tmp_var() } else { '' } tmp_opt := if gen_or { g.new_tmp_var() } else { '' }
if gen_or { if gen_or {
rstyp := g.typ(return_type) rstyp := g.typ(return_type)
@ -1239,7 +1240,7 @@ fn (g mut Gen) assign_expr(node ast.AssignExpr) {
} }
else { else {
g.is_assign_lhs = true g.is_assign_lhs = true
if table.type_is_optional(node.right_type) { if table.type_is(node.right_type, .optional) {
g.right_is_opt = true g.right_is_opt = true
} }
mut str_add := false mut str_add := false
@ -1672,7 +1673,7 @@ fn (g mut Gen) index_expr(node ast.IndexExpr) {
if !is_range { if !is_range {
sym := g.table.get_type_symbol(node.left_type) sym := g.table.get_type_symbol(node.left_type)
left_is_ptr := table.type_is_ptr(node.left_type) left_is_ptr := table.type_is_ptr(node.left_type)
if table.type_is_variadic(node.left_type) { if table.type_is(node.left_type, .variadic) {
g.expr(node.left) g.expr(node.left)
g.write('.args') g.write('.args')
g.write('[') g.write('[')
@ -1778,7 +1779,7 @@ fn (g mut Gen) return_statement(node ast.Return) {
g.writeln(' 0;') g.writeln(' 0;')
return return
} }
fn_return_is_optional := table.type_is_optional(g.fn_decl.return_type) fn_return_is_optional := table.type_is(g.fn_decl.return_type, .optional)
// multiple returns // multiple returns
if node.exprs.len > 1 { if node.exprs.len > 1 {
g.write(' ') g.write(' ')
@ -1806,7 +1807,7 @@ fn (g mut Gen) return_statement(node ast.Return) {
else if node.exprs.len == 1 { else if node.exprs.len == 1 {
g.write(' ') g.write(' ')
// `return opt_ok(expr)` for functions that expect an optional // `return opt_ok(expr)` for functions that expect an optional
if fn_return_is_optional && !table.type_is_optional(node.types[0]) { if fn_return_is_optional && !table.type_is(node.types[0], .optional) {
mut is_none := false mut is_none := false
mut is_error := false mut is_error := false
expr0 := node.exprs[0] expr0 := node.exprs[0]
@ -1958,7 +1959,7 @@ fn (g mut Gen) assoc(node ast.Assoc) {
} }
fn (g mut Gen) call_args(args []ast.CallArg, expected_types []table.Type) { fn (g mut Gen) call_args(args []ast.CallArg, expected_types []table.Type) {
is_variadic := expected_types.len > 0 && table.type_is_variadic(expected_types[expected_types.len - 1]) is_variadic := expected_types.len > 0 && table.type_is(expected_types[expected_types.len - 1], .variadic)
mut arg_no := 0 mut arg_no := 0
for arg in args { for arg in args {
if is_variadic && arg_no == expected_types.len - 1 { if is_variadic && arg_no == expected_types.len - 1 {
@ -2371,7 +2372,7 @@ fn (g mut Gen) method_call(node ast.CallExpr) {
} }
g.expr(node.left) g.expr(node.left)
is_variadic := node.expected_arg_types.len > 0 && is_variadic := node.expected_arg_types.len > 0 &&
table.type_is_variadic(node.expected_arg_types[node.expected_arg_types.len - 1]) table.type_is(node.expected_arg_types[node.expected_arg_types.len - 1], .variadic)
if node.args.len > 0 || is_variadic { if node.args.len > 0 || is_variadic {
g.write(', ') g.write(', ')
} }
@ -2436,7 +2437,7 @@ fn (g mut Gen) fn_call(node ast.CallExpr) {
g.str_types << styp g.str_types << styp
g.gen_str_for_type(sym, styp) g.gen_str_for_type(sym, styp)
} }
if g.autofree && !table.type_is_optional(typ) { if g.autofree && !table.type_is(typ, .optional) {
// Create a temporary variable so that the value can be freed // Create a temporary variable so that the value can be freed
tmp := g.new_tmp_var() tmp := g.new_tmp_var()
// tmps << tmp // tmps << tmp

View File

@ -202,7 +202,7 @@ fn (p mut Parser) fn_args() ([]table.Arg,bool) {
} }
mut arg_type := p.parse_type() mut arg_type := p.parse_type()
if is_variadic { if is_variadic {
arg_type = table.type_to_variadic(arg_type) arg_type = table.type_set(arg_type, .variadic)
} }
if p.tok.kind == .comma { if p.tok.kind == .comma {
if is_variadic { if is_variadic {
@ -236,7 +236,7 @@ fn (p mut Parser) fn_args() ([]table.Arg,bool) {
} }
mut typ := p.parse_type() mut typ := p.parse_type()
if is_variadic { if is_variadic {
typ = table.type_to_variadic(typ) typ = table.type_set(typ, .variadic)
} }
for arg_name in arg_names { for arg_name in arg_names {
args << table.Arg{ args << table.Arg{

View File

@ -115,7 +115,7 @@ pub fn (p mut Parser) parse_type() table.Type {
} }
mut typ := p.parse_any_type(is_c, nr_muls > 0) mut typ := p.parse_any_type(is_c, nr_muls > 0)
if is_optional { if is_optional {
typ = table.type_to_optional(typ) typ = table.type_set(typ, .optional)
} }
if nr_muls > 0 { if nr_muls > 0 {
typ = table.type_set_nr_muls(typ, nr_muls) typ = table.type_set_nr_muls(typ, nr_muls)

View File

@ -1,3 +1,15 @@
// Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved.
// Use of this source code is governed by an MIT license
// that can be found in the LICENSE file.
//
// Type layout information (32 bits)
// flag (8 bits) | nr_muls (8 bits) | idx (16 bits)
// pack: (int(flag)<<24) | (nr_muls<<16) | u16(idx)
// unpack:
// flag: (int(type)>>24) & 0xff
// nr_muls: (int(type)>>16) & 0xff
// idx: u16(type) & 0xffff
module table module table
import ( import (
@ -17,10 +29,9 @@ mut:
kind Kind kind Kind
name string name string
methods []Fn methods []Fn
// is_sum bool
} }
pub enum TypeExtra { pub enum TypeFlag {
unset unset
optional optional
variadic variadic
@ -35,90 +46,71 @@ pub fn (types []Type) contains(typ Type) bool {
return false return false
} }
// return underlying TypeSymbol idx // return TypeSymbol idx for `t`
[inline] [inline]
pub fn type_idx(t Type) int { pub fn type_idx(t Type) int {
return u16(t) & 0xffff return u16(t) & 0xffff
} }
// return nr_muls // return nr_muls for `t`
[inline] [inline]
pub fn type_nr_muls(t Type) int { pub fn type_nr_muls(t Type) int {
return (int(t)>>16) & 0xff return (int(t)>>16) & 0xff
} }
// return true if pointer (nr_muls>0) // return true if `t` is a pointer (nr_muls>0)
[inline] [inline]
pub fn type_is_ptr(t Type) bool { pub fn type_is_ptr(t Type) bool {
return type_nr_muls(t) > 0 // || t == voidptr_type_idx return (int(t)>>16) & 0xff > 0
} }
// set nr_muls on Type and return it // set nr_muls on `t` and return it
[inline] [inline]
pub fn type_set_nr_muls(t Type, nr_muls int) Type { pub fn type_set_nr_muls(t Type, nr_muls int) Type {
if nr_muls < 0 || nr_muls > 255 { if nr_muls < 0 || nr_muls > 255 {
panic('typ_set_nr_muls: nr_muls must be between 0 & 255') panic('typ_set_nr_muls: nr_muls must be between 0 & 255')
} }
return (int(type_extra(t))<<24) | (nr_muls<<16) | u16(type_idx(t)) return (((int(t)>>24) & 0xff)<<24) | (nr_muls<<16) | (u16(t) & 0xffff)
} }
// increments nr_nuls on Type and return it // increments nr_nuls on `t` and return it
[inline] [inline]
pub fn type_to_ptr(t Type) Type { pub fn type_to_ptr(t Type) Type {
nr_muls := type_nr_muls(t) nr_muls := (int(t)>>16) & 0xff
if nr_muls == 255 { if nr_muls == 255 {
panic('type_to_pre: nr_muls is already at max of 255') panic('type_to_pre: nr_muls is already at max of 255')
} }
return (int(type_extra(t))<<24) | ((nr_muls + 1)<<16) | u16(type_idx(t)) return (((int(t)>>24) & 0xff)<<24) | ((nr_muls + 1)<<16) | (u16(t) & 0xffff)
} }
// decrement nr_muls on Type and return it // decrement nr_muls on `t` and return it
[inline] [inline]
pub fn type_deref(t Type) Type { pub fn type_deref(t Type) Type {
nr_muls := type_nr_muls(t) nr_muls := (int(t)>>16) & 0xff
if nr_muls == 0 { if nr_muls == 0 {
panic('deref: type `$t` is not a pointer') panic('deref: type `$t` is not a pointer')
} }
return (int(type_extra(t))<<24) | ((nr_muls - 1)<<16) | u16(type_idx(t)) return (((int(t)>>24) & 0xff)<<24) | ((nr_muls - 1)<<16) | (u16(t) & 0xffff)
} }
// return the flag that is set on `t`
[inline] [inline]
pub fn type_clear_extra(t Type) Type { pub fn type_flag(t Type) TypeFlag {
return type_set_extra(t, .unset)
}
// return extra info
[inline]
pub fn type_extra(t Type) TypeExtra {
return (int(t)>>24) & 0xff return (int(t)>>24) & 0xff
} }
// set extra info // set the flag on `t` to `flag` and return it
[inline] [inline]
pub fn type_set_extra(t Type, extra TypeExtra) Type { pub fn type_set(t Type, flag TypeFlag) Type {
return (int(extra)<<24) | (type_nr_muls(t)<<16) | u16(type_idx(t)) return (int(flag)<<24) | (((int(t)>>16) & 0xff)<<16) | (u16(t) & 0xffff)
} }
// return true if the flag set on `t` is `flag`
[inline] [inline]
pub fn type_is_optional(t Type) bool { pub fn type_is(t Type, flag TypeFlag) bool {
return type_extra(t) == .optional return (int(t)>>24) & 0xff == flag
} }
[inline] // return new type with TypeSymbol idx set to `idx`
pub fn type_to_optional(t Type) Type {
return type_set_extra(t, .optional)
}
[inline]
pub fn type_is_variadic(t Type) bool {
return type_extra(t) == .variadic
}
[inline]
pub fn type_to_variadic(t Type) Type {
return type_set_extra(t, .variadic)
}
// new type with idx of TypeSymbol, not pointer (nr_muls=0)
[inline] [inline]
pub fn new_type(idx int) Type { pub fn new_type(idx int) Type {
if idx < 1 || idx > 65536 { if idx < 1 || idx > 65536 {
@ -127,34 +119,24 @@ pub fn new_type(idx int) Type {
return idx return idx
} }
// return Type idx of TypeSymbol & specify if ptr (nr_muls) // return new type with TypeSymbol idx set to `idx` & nr_muls set to `nr_muls`
[inline] [inline]
pub fn new_type_ptr(idx int, nr_muls int) Type { pub fn new_type_ptr(idx int, nr_muls int) Type {
if idx < 1 || idx > 65536 { if idx < 1 || idx > 65536 {
panic('typ_ptr: idx must be between 1 & 65536') panic('new_type_ptr: idx must be between 1 & 65536')
} }
if nr_muls < 0 || nr_muls > 255 { if nr_muls < 0 || nr_muls > 255 {
panic('typ_ptr: nr_muls must be between 0 & 255') panic('new_type_ptr: nr_muls must be between 0 & 255')
} }
return (nr_muls<<16) | u16(idx) return (nr_muls<<16) | u16(idx)
} }
/*
pub fn is_number(typ Type) bool {
typ_sym := c.table.get_type_symbol(typ)
return typ_sym.is_int()
//idx := type_idx(typ)
//return idx in [int_type_idx, byte_type_idx, u64_type_idx]
}
*/
pub fn is_number(typ Type) bool { pub fn is_number(typ Type) bool {
return type_idx(typ) in number_type_idxs return type_idx(typ) in number_type_idxs
} }
pub const ( pub const (
// primitive types // primitive types
void_type_idx = 1 void_type_idx = 1
voidptr_type_idx = 2 voidptr_type_idx = 2
byteptr_type_idx = 3 byteptr_type_idx = 3
@ -630,7 +612,7 @@ pub fn (table &Table) type_to_str(t Type) string {
res = vals[vals.len - 2] + '.' + vals[vals.len - 1] res = vals[vals.len - 2] + '.' + vals[vals.len - 1]
} }
} }
if type_is_optional(t) { if type_is(t, .optional) {
res = '?' + res res = '?' + res
} }
nr_muls := type_nr_muls(t) nr_muls := type_nr_muls(t)

View File

@ -385,9 +385,9 @@ pub fn (t mut Table) add_placeholder_type(name string) int {
[inline] [inline]
pub fn (t &Table) value_type(typ Type) Type { pub fn (t &Table) value_type(typ Type) Type {
typ_sym := t.get_type_symbol(typ) typ_sym := t.get_type_symbol(typ)
if type_is_variadic(typ) { if type_is(typ, .variadic) {
// ...string => string // ...string => string
return type_clear_extra(typ) return type_set(typ, .unset)
} }
else if typ_sym.kind == .array { else if typ_sym.kind == .array {
// Check index type // Check index type