table: simplify/generalise type fns & remove calls

pull/4224/head
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)
field_name := selector_expr.field
// variadic
if table.type_is_variadic(typ) {
if table.type_is(typ, .variadic) {
if field_name == 'len' {
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_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]
if expected_type_sym.kind == .multi_return {
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 {
typ = c.expr(var.expr)
}
is_optional := table.type_is(typ, .optional)
ident.kind = .variable
ident.info = ast.IdentVar{
typ: typ
is_optional: table.type_is_optional(typ)
is_optional: is_optional
}
// unwrap optional (`println(x)`)
if table.type_is_optional(typ) {
return table.type_clear_extra(typ)
if is_optional {
return table.type_set(typ, .unset)
}
return typ
}

View File

@ -162,7 +162,7 @@ pub fn (g mut Gen) typ(t table.Type) string {
styp = 'struct $styp'
}
}
if table.type_is_optional(t) {
if table.type_is(t, .optional) {
styp = 'Option_' + styp
if !(styp in g.optionals) {
g.definitions.writeln('typedef Option $styp;')
@ -506,7 +506,7 @@ fn (g mut Gen) for_in(it ast.ForInStmt) {
g.stmts(it.stmts)
g.writeln('}')
}
else if table.type_is_variadic(it.cond_type) {
else if table.type_is(it.cond_type, .variadic) {
g.writeln('// FOR IN')
i := if it.key_var == '' { g.new_tmp_var() } else { it.key_var }
styp := g.typ(it.cond_type)
@ -597,7 +597,7 @@ fn (g mut Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
}
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_styp := g.typ(return_type)
g.write('$mr_styp $mr_var_name = ')
@ -644,7 +644,7 @@ fn (g mut Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
}
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
if ident.kind == .blank_ident {
if is_call {
@ -846,10 +846,11 @@ fn (g mut Gen) free_scope_vars(pos int) {
// }
var := *it
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')
}
if sym.kind == .string && !table.type_is_optional(var.typ) {
if sym.kind == .string && !is_optional {
// Don't free simple string literals.
t := typeof(var.expr)
match var.expr {
@ -1220,7 +1221,7 @@ fn (g mut Gen) assign_expr(node ast.AssignExpr) {
}
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 { '' }
if gen_or {
rstyp := g.typ(return_type)
@ -1239,7 +1240,7 @@ fn (g mut Gen) assign_expr(node ast.AssignExpr) {
}
else {
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
}
mut str_add := false
@ -1672,7 +1673,7 @@ fn (g mut Gen) index_expr(node ast.IndexExpr) {
if !is_range {
sym := g.table.get_type_symbol(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.write('.args')
g.write('[')
@ -1778,7 +1779,7 @@ fn (g mut Gen) return_statement(node ast.Return) {
g.writeln(' 0;')
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
if node.exprs.len > 1 {
g.write(' ')
@ -1806,7 +1807,7 @@ fn (g mut Gen) return_statement(node ast.Return) {
else if node.exprs.len == 1 {
g.write(' ')
// `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_error := false
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) {
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
for arg in args {
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)
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 {
g.write(', ')
}
@ -2436,7 +2437,7 @@ fn (g mut Gen) fn_call(node ast.CallExpr) {
g.str_types << 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
tmp := g.new_tmp_var()
// tmps << tmp

View File

@ -202,7 +202,7 @@ fn (p mut Parser) fn_args() ([]table.Arg,bool) {
}
mut arg_type := p.parse_type()
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 is_variadic {
@ -236,7 +236,7 @@ fn (p mut Parser) fn_args() ([]table.Arg,bool) {
}
mut typ := p.parse_type()
if is_variadic {
typ = table.type_to_variadic(typ)
typ = table.type_set(typ, .variadic)
}
for arg_name in arg_names {
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)
if is_optional {
typ = table.type_to_optional(typ)
typ = table.type_set(typ, .optional)
}
if nr_muls > 0 {
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
import (
@ -17,10 +29,9 @@ mut:
kind Kind
name string
methods []Fn
// is_sum bool
}
pub enum TypeExtra {
pub enum TypeFlag {
unset
optional
variadic
@ -35,90 +46,71 @@ pub fn (types []Type) contains(typ Type) bool {
return false
}
// return underlying TypeSymbol idx
// return TypeSymbol idx for `t`
[inline]
pub fn type_idx(t Type) int {
return u16(t) & 0xffff
}
// return nr_muls
// return nr_muls for `t`
[inline]
pub fn type_nr_muls(t Type) int {
return (int(t)>>16) & 0xff
}
// return true if pointer (nr_muls>0)
// return true if `t` is a pointer (nr_muls>0)
[inline]
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]
pub fn type_set_nr_muls(t Type, nr_muls int) Type {
if nr_muls < 0 || nr_muls > 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]
pub fn type_to_ptr(t Type) Type {
nr_muls := type_nr_muls(t)
nr_muls := (int(t)>>16) & 0xff
if nr_muls == 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]
pub fn type_deref(t Type) Type {
nr_muls := type_nr_muls(t)
nr_muls := (int(t)>>16) & 0xff
if nr_muls == 0 {
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]
pub fn type_clear_extra(t Type) Type {
return type_set_extra(t, .unset)
}
// return extra info
[inline]
pub fn type_extra(t Type) TypeExtra {
pub fn type_flag(t Type) TypeFlag {
return (int(t)>>24) & 0xff
}
// set extra info
// set the flag on `t` to `flag` and return it
[inline]
pub fn type_set_extra(t Type, extra TypeExtra) Type {
return (int(extra)<<24) | (type_nr_muls(t)<<16) | u16(type_idx(t))
pub fn type_set(t Type, flag TypeFlag) Type {
return (int(flag)<<24) | (((int(t)>>16) & 0xff)<<16) | (u16(t) & 0xffff)
}
// return true if the flag set on `t` is `flag`
[inline]
pub fn type_is_optional(t Type) bool {
return type_extra(t) == .optional
pub fn type_is(t Type, flag TypeFlag) bool {
return (int(t)>>24) & 0xff == flag
}
[inline]
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)
// return new type with TypeSymbol idx set to `idx`
[inline]
pub fn new_type(idx int) Type {
if idx < 1 || idx > 65536 {
@ -127,34 +119,24 @@ pub fn new_type(idx int) Type {
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]
pub fn new_type_ptr(idx int, nr_muls int) Type {
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 {
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)
}
/*
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 {
return type_idx(typ) in number_type_idxs
}
pub const (
// primitive types
// primitive types
void_type_idx = 1
voidptr_type_idx = 2
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]
}
}
if type_is_optional(t) {
if type_is(t, .optional) {
res = '?' + res
}
nr_muls := type_nr_muls(t)

View File

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