table: allow type hold 8 flags at once
parent
2230cbae01
commit
edd56bc080
|
@ -19,7 +19,7 @@ pub fn (c &Checker) check_basic(got, expected table.Type) bool {
|
||||||
// and the other is not, is this correct behaviour?
|
// and the other is not, is this correct behaviour?
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if got_idx == table.none_type_idx && expected.flag_is(.optional) {
|
if got_idx == table.none_type_idx && expected.has_flag(.optional) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// allow pointers to be initialized with 0. TODO: use none instead
|
// allow pointers to be initialized with 0. TODO: use none instead
|
||||||
|
|
|
@ -826,7 +826,7 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
|
||||||
c.expected_type = exp_arg_typ
|
c.expected_type = exp_arg_typ
|
||||||
got_arg_typ := c.expr(arg.expr)
|
got_arg_typ := c.expr(arg.expr)
|
||||||
call_expr.args[i].typ = got_arg_typ
|
call_expr.args[i].typ = got_arg_typ
|
||||||
if method.is_variadic && got_arg_typ.flag_is(.variadic) && call_expr.args.len -
|
if method.is_variadic && got_arg_typ.has_flag(.variadic) && call_expr.args.len -
|
||||||
1 > i {
|
1 > i {
|
||||||
c.error('when forwarding a varg variable, it must be the final argument', call_expr.pos)
|
c.error('when forwarding a varg variable, it must be the final argument', call_expr.pos)
|
||||||
}
|
}
|
||||||
|
@ -1027,7 +1027,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
|
||||||
call_expr.args[i].typ = typ
|
call_expr.args[i].typ = typ
|
||||||
typ_sym := c.table.get_type_symbol(typ)
|
typ_sym := c.table.get_type_symbol(typ)
|
||||||
arg_typ_sym := c.table.get_type_symbol(arg.typ)
|
arg_typ_sym := c.table.get_type_symbol(arg.typ)
|
||||||
if f.is_variadic && typ.flag_is(.variadic) && call_expr.args.len - 1 > i {
|
if f.is_variadic && typ.has_flag(.variadic) && call_expr.args.len - 1 > i {
|
||||||
c.error('when forwarding a varg variable, it must be the final argument', call_expr.pos)
|
c.error('when forwarding a varg variable, it must be the final argument', call_expr.pos)
|
||||||
}
|
}
|
||||||
if arg.is_mut && !call_arg.is_mut {
|
if arg.is_mut && !call_arg.is_mut {
|
||||||
|
@ -1100,7 +1100,7 @@ fn (mut c Checker) type_implements(typ, inter_typ table.Type, pos token.Position
|
||||||
pub fn (mut c Checker) check_expr_opt_call(expr ast.Expr, ret_type table.Type) table.Type {
|
pub fn (mut c Checker) check_expr_opt_call(expr ast.Expr, ret_type table.Type) table.Type {
|
||||||
if expr is ast.CallExpr {
|
if expr is ast.CallExpr {
|
||||||
call_expr := expr as ast.CallExpr
|
call_expr := expr as ast.CallExpr
|
||||||
if call_expr.return_type.flag_is(.optional) {
|
if call_expr.return_type.has_flag(.optional) {
|
||||||
if call_expr.or_block.kind == .absent {
|
if call_expr.or_block.kind == .absent {
|
||||||
if ret_type != table.void_type {
|
if ret_type != table.void_type {
|
||||||
c.error('${call_expr.name}() returns an option, but you missed to add an `or {}` block to it',
|
c.error('${call_expr.name}() returns an option, but you missed to add an `or {}` block to it',
|
||||||
|
@ -1110,7 +1110,7 @@ pub fn (mut c Checker) check_expr_opt_call(expr ast.Expr, ret_type table.Type) t
|
||||||
c.check_or_expr(call_expr.or_block, ret_type)
|
c.check_or_expr(call_expr.or_block, ret_type)
|
||||||
}
|
}
|
||||||
// remove optional flag
|
// remove optional flag
|
||||||
return ret_type.set_flag(.unset)
|
return ret_type.clear_flag(.optional)
|
||||||
} else if call_expr.or_block.kind == .block {
|
} else if call_expr.or_block.kind == .block {
|
||||||
c.error('unexpected `or` block, the function `$call_expr.name` does not return an optional',
|
c.error('unexpected `or` block, the function `$call_expr.name` does not return an optional',
|
||||||
call_expr.pos)
|
call_expr.pos)
|
||||||
|
@ -1124,7 +1124,7 @@ pub fn (mut c Checker) check_expr_opt_call(expr ast.Expr, ret_type table.Type) t
|
||||||
|
|
||||||
pub fn (mut c Checker) check_or_expr(mut or_expr ast.OrExpr, ret_type table.Type) {
|
pub fn (mut c Checker) check_or_expr(mut or_expr ast.OrExpr, ret_type table.Type) {
|
||||||
if or_expr.kind == .propagate {
|
if or_expr.kind == .propagate {
|
||||||
if !c.cur_fn.return_type.flag_is(.optional) && c.cur_fn.name != 'main' {
|
if !c.cur_fn.return_type.has_flag(.optional) && c.cur_fn.name != 'main' {
|
||||||
c.error('to propagate the optional call, `${c.cur_fn.name}` must itself return an optional',
|
c.error('to propagate the optional call, `${c.cur_fn.name}` must itself return an optional',
|
||||||
or_expr.pos)
|
or_expr.pos)
|
||||||
}
|
}
|
||||||
|
@ -1193,7 +1193,7 @@ pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) table.T
|
||||||
sym := c.table.get_type_symbol(c.unwrap_generic(typ))
|
sym := c.table.get_type_symbol(c.unwrap_generic(typ))
|
||||||
field_name := selector_expr.field_name
|
field_name := selector_expr.field_name
|
||||||
// variadic
|
// variadic
|
||||||
if typ.flag_is(.variadic) {
|
if typ.has_flag(.variadic) {
|
||||||
if field_name == 'len' {
|
if field_name == 'len' {
|
||||||
return table.int_type
|
return table.int_type
|
||||||
}
|
}
|
||||||
|
@ -1228,7 +1228,7 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) {
|
||||||
}
|
}
|
||||||
expected_type := c.expected_type
|
expected_type := c.expected_type
|
||||||
expected_type_sym := c.table.get_type_symbol(expected_type)
|
expected_type_sym := c.table.get_type_symbol(expected_type)
|
||||||
exp_is_optional := expected_type.flag_is(.optional)
|
exp_is_optional := expected_type.has_flag(.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
|
||||||
|
@ -1258,8 +1258,8 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) {
|
||||||
}
|
}
|
||||||
for i, exp_type in expected_types {
|
for i, exp_type in expected_types {
|
||||||
got_typ := got_types[i]
|
got_typ := got_types[i]
|
||||||
if got_typ.flag_is(.optional) &&
|
if got_typ.has_flag(.optional) &&
|
||||||
(!exp_type.flag_is(.optional) || c.table.type_to_str(got_typ) != c.table.type_to_str(exp_type)) {
|
(!exp_type.has_flag(.optional) || c.table.type_to_str(got_typ) != c.table.type_to_str(exp_type)) {
|
||||||
pos := return_stmt.exprs[i].position()
|
pos := return_stmt.exprs[i].position()
|
||||||
c.error('cannot use `${c.table.type_to_str(got_typ)}` as type `${c.table.type_to_str(exp_type)}` in return argument', pos)
|
c.error('cannot use `${c.table.type_to_str(got_typ)}` as type `${c.table.type_to_str(exp_type)}` in return argument', pos)
|
||||||
}
|
}
|
||||||
|
@ -1977,7 +1977,7 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type {
|
||||||
}
|
}
|
||||||
typ = c.expr(it.expr)
|
typ = c.expr(it.expr)
|
||||||
}
|
}
|
||||||
is_optional := typ.flag_is(.optional)
|
is_optional := typ.has_flag(.optional)
|
||||||
ident.kind = .variable
|
ident.kind = .variable
|
||||||
ident.info = ast.IdentVar{
|
ident.info = ast.IdentVar{
|
||||||
typ: typ
|
typ: typ
|
||||||
|
@ -1993,7 +1993,7 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type {
|
||||||
it.typ = typ
|
it.typ = typ
|
||||||
// unwrap optional (`println(x)`)
|
// unwrap optional (`println(x)`)
|
||||||
if is_optional {
|
if is_optional {
|
||||||
return typ.set_flag(.unset)
|
return typ.clear_flag(.optional)
|
||||||
}
|
}
|
||||||
return typ
|
return typ
|
||||||
}
|
}
|
||||||
|
|
|
@ -324,7 +324,7 @@ fn (g &Gen) typ(t table.Type) string {
|
||||||
// T => int etc
|
// T => int etc
|
||||||
return g.typ(g.cur_generic_type)
|
return g.typ(g.cur_generic_type)
|
||||||
}
|
}
|
||||||
if t.flag_is(.optional) {
|
if t.has_flag(.optional) {
|
||||||
// Register an optional if it's not registered yet
|
// Register an optional if it's not registered yet
|
||||||
return g.register_optional(t)
|
return g.register_optional(t)
|
||||||
}
|
}
|
||||||
|
@ -844,7 +844,7 @@ fn (mut g Gen) for_in(it ast.ForInStmt) {
|
||||||
}
|
}
|
||||||
g.stmts(it.stmts)
|
g.stmts(it.stmts)
|
||||||
g.writeln('}')
|
g.writeln('}')
|
||||||
} else if it.cond_type.flag_is(.variadic) {
|
} else if it.cond_type.has_flag(.variadic) {
|
||||||
g.writeln('// FOR IN cond_type/variadic')
|
g.writeln('// FOR IN cond_type/variadic')
|
||||||
i := if it.key_var in ['', '_'] { g.new_tmp_var() } else { it.key_var }
|
i := if it.key_var in ['', '_'] { g.new_tmp_var() } else { it.key_var }
|
||||||
styp := g.typ(it.cond_type)
|
styp := g.typ(it.cond_type)
|
||||||
|
@ -901,7 +901,7 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type, expected_type table.Type)
|
||||||
got_deref_type := got_type.deref()
|
got_deref_type := got_type.deref()
|
||||||
deref_sym := g.table.get_type_symbol(got_deref_type)
|
deref_sym := g.table.get_type_symbol(got_deref_type)
|
||||||
deref_will_match := expected_type in [got_type, got_deref_type, deref_sym.parent_idx]
|
deref_will_match := expected_type in [got_type, got_deref_type, deref_sym.parent_idx]
|
||||||
got_is_opt := got_type.flag_is(.optional)
|
got_is_opt := got_type.has_flag(.optional)
|
||||||
if deref_will_match || got_is_opt {
|
if deref_will_match || got_is_opt {
|
||||||
g.write('*')
|
g.write('*')
|
||||||
}
|
}
|
||||||
|
@ -1015,7 +1015,7 @@ fn (mut g Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) {
|
||||||
1 {
|
1 {
|
||||||
// multi return
|
// multi return
|
||||||
// TODO Handle in if_expr
|
// TODO Handle in if_expr
|
||||||
is_optional := return_type.flag_is(.optional)
|
is_optional := return_type.has_flag(.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 = ')
|
||||||
|
@ -1289,7 +1289,7 @@ fn (mut g Gen) autofree_scope_vars(pos int) string {
|
||||||
// continue
|
// continue
|
||||||
// }
|
// }
|
||||||
v := *it
|
v := *it
|
||||||
is_optional := v.typ.flag_is(.optional)
|
is_optional := v.typ.has_flag(.optional)
|
||||||
if is_optional {
|
if is_optional {
|
||||||
// TODO: free optionals
|
// TODO: free optionals
|
||||||
continue
|
continue
|
||||||
|
@ -1644,7 +1644,7 @@ fn (mut g Gen) assign_expr(node ast.AssignExpr) {
|
||||||
}
|
}
|
||||||
else {}
|
else {}
|
||||||
}
|
}
|
||||||
gen_or := is_call && return_type.flag_is(.optional)
|
gen_or := is_call && return_type.has_flag(.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)
|
||||||
|
@ -1662,7 +1662,7 @@ fn (mut g Gen) assign_expr(node ast.AssignExpr) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
g.is_assign_lhs = true
|
g.is_assign_lhs = true
|
||||||
if node.right_type.flag_is(.optional) {
|
if node.right_type.has_flag(.optional) {
|
||||||
g.right_is_opt = true
|
g.right_is_opt = true
|
||||||
}
|
}
|
||||||
mut str_add := false
|
mut str_add := false
|
||||||
|
@ -1719,7 +1719,7 @@ fn (mut g Gen) assign_expr(node ast.AssignExpr) {
|
||||||
if gen_or {
|
if gen_or {
|
||||||
// g.write('/*777 $tmp_opt*/')
|
// g.write('/*777 $tmp_opt*/')
|
||||||
g.or_block(tmp_opt, or_block, return_type)
|
g.or_block(tmp_opt, or_block, return_type)
|
||||||
unwrapped_type_str := g.typ(return_type.set_flag(.unset))
|
unwrapped_type_str := g.typ(return_type.clear_flag(.optional))
|
||||||
ident := node.left as ast.Ident
|
ident := node.left as ast.Ident
|
||||||
if ident.kind != .blank_ident && ident.info is ast.IdentVar {
|
if ident.kind != .blank_ident && ident.info is ast.IdentVar {
|
||||||
ident_var := ident.info as ast.IdentVar
|
ident_var := ident.info as ast.IdentVar
|
||||||
|
@ -2207,7 +2207,7 @@ fn (mut g 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 := node.left_type.is_ptr()
|
left_is_ptr := node.left_type.is_ptr()
|
||||||
if node.left_type.flag_is(.variadic) {
|
if node.left_type.has_flag(.variadic) {
|
||||||
g.expr(node.left)
|
g.expr(node.left)
|
||||||
g.write('.args')
|
g.write('.args')
|
||||||
g.write('[')
|
g.write('[')
|
||||||
|
@ -2339,7 +2339,7 @@ fn (mut g Gen) return_statement(node ast.Return) {
|
||||||
// got to do a correct check for multireturn
|
// got to do a correct check for multireturn
|
||||||
sym := g.table.get_type_symbol(g.fn_decl.return_type)
|
sym := g.table.get_type_symbol(g.fn_decl.return_type)
|
||||||
fn_return_is_multi := sym.kind == .multi_return
|
fn_return_is_multi := sym.kind == .multi_return
|
||||||
fn_return_is_optional := g.fn_decl.return_type.flag_is(.optional)
|
fn_return_is_optional := g.fn_decl.return_type.has_flag(.optional)
|
||||||
// handle promoting none/error/function returning 'Option'
|
// handle promoting none/error/function returning 'Option'
|
||||||
if fn_return_is_optional {
|
if fn_return_is_optional {
|
||||||
optional_none := node.exprs[0] is ast.None
|
optional_none := node.exprs[0] is ast.None
|
||||||
|
@ -2418,7 +2418,7 @@ fn (mut g Gen) return_statement(node ast.Return) {
|
||||||
// normal return
|
// normal return
|
||||||
return_sym := g.table.get_type_symbol(node.types[0])
|
return_sym := g.table.get_type_symbol(node.types[0])
|
||||||
// `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 && !node.types[0].flag_is(.optional) && return_sym.name !=
|
if fn_return_is_optional && !node.types[0].has_flag(.optional) && return_sym.name !=
|
||||||
'Option' {
|
'Option' {
|
||||||
styp := g.base_type(g.fn_decl.return_type)
|
styp := g.base_type(g.fn_decl.return_type)
|
||||||
opt_type := g.typ(g.fn_decl.return_type)
|
opt_type := g.typ(g.fn_decl.return_type)
|
||||||
|
@ -2631,7 +2631,7 @@ fn (mut g Gen) struct_init(struct_init ast.StructInit) {
|
||||||
// unions thould have exactly one explicit initializer
|
// unions thould have exactly one explicit initializer
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if field.typ.flag_is(.optional) {
|
if field.typ.has_flag(.optional) {
|
||||||
// TODO handle/require optionals in inits
|
// TODO handle/require optionals in inits
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -2813,7 +2813,7 @@ fn (mut g Gen) write_types(types []table.TypeSymbol) {
|
||||||
// if this is the case then we are going to
|
// if this is the case then we are going to
|
||||||
// buffer manip out in front of the struct
|
// buffer manip out in front of the struct
|
||||||
// write the optional in and then continue
|
// write the optional in and then continue
|
||||||
if field.typ.flag_is(.optional) {
|
if field.typ.has_flag(.optional) {
|
||||||
// Dont use g.typ() here becuase it will register
|
// Dont use g.typ() here becuase it will register
|
||||||
// optional and we dont want that
|
// optional and we dont want that
|
||||||
last_text := g.type_definitions.after(start_pos).clone()
|
last_text := g.type_definitions.after(start_pos).clone()
|
||||||
|
@ -3102,7 +3102,7 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
|
||||||
fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype table.Type) ?bool {
|
fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype table.Type) ?bool {
|
||||||
sym := g.table.get_type_symbol(etype)
|
sym := g.table.get_type_symbol(etype)
|
||||||
sym_has_str_method, str_method_expects_ptr, _ := sym.str_method_info()
|
sym_has_str_method, str_method_expects_ptr, _ := sym.str_method_info()
|
||||||
if etype.flag_is(.variadic) {
|
if etype.has_flag(.variadic) {
|
||||||
str_fn_name := g.gen_str_for_type(etype)
|
str_fn_name := g.gen_str_for_type(etype)
|
||||||
g.write('${str_fn_name}(')
|
g.write('${str_fn_name}(')
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
|
@ -3294,7 +3294,7 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type table.
|
||||||
expr_stmt := stmt as ast.ExprStmt
|
expr_stmt := stmt as ast.ExprStmt
|
||||||
g.stmt_path_pos << g.out.len
|
g.stmt_path_pos << g.out.len
|
||||||
g.write('*(${mr_styp}*) ${cvar_name}.data = ')
|
g.write('*(${mr_styp}*) ${cvar_name}.data = ')
|
||||||
is_opt_call := expr_stmt.expr is ast.CallExpr && expr_stmt.typ.flag_is(.optional)
|
is_opt_call := expr_stmt.expr is ast.CallExpr && expr_stmt.typ.has_flag(.optional)
|
||||||
if is_opt_call {
|
if is_opt_call {
|
||||||
g.write('*(${mr_styp}*) ')
|
g.write('*(${mr_styp}*) ')
|
||||||
}
|
}
|
||||||
|
@ -3858,7 +3858,7 @@ fn (mut g Gen) gen_str_for_type_with_styp(typ table.Type, styp string) string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if varg, generate str for varg
|
// if varg, generate str for varg
|
||||||
if typ.flag_is(.variadic) {
|
if typ.has_flag(.variadic) {
|
||||||
varg_already_generated_key := 'varg_$already_generated_key'
|
varg_already_generated_key := 'varg_$already_generated_key'
|
||||||
if varg_already_generated_key !in g.str_types {
|
if varg_already_generated_key !in g.str_types {
|
||||||
g.gen_str_for_varg(styp, str_fn_name, sym_has_str_method)
|
g.gen_str_for_varg(styp, str_fn_name, sym_has_str_method)
|
||||||
|
|
|
@ -430,7 +430,7 @@ fn (mut g Gen) method_call(node ast.CallExpr) {
|
||||||
}
|
}
|
||||||
g.expr(node.left)
|
g.expr(node.left)
|
||||||
is_variadic := node.expected_arg_types.len > 0 && node.expected_arg_types[node.expected_arg_types.len -
|
is_variadic := node.expected_arg_types.len > 0 && node.expected_arg_types[node.expected_arg_types.len -
|
||||||
1].flag_is(.variadic)
|
1].has_flag(.variadic)
|
||||||
if node.args.len > 0 || is_variadic {
|
if node.args.len > 0 || is_variadic {
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
}
|
}
|
||||||
|
@ -523,7 +523,7 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
|
||||||
styp = styp.replace('*', '')
|
styp = styp.replace('*', '')
|
||||||
}
|
}
|
||||||
mut str_fn_name := g.gen_str_for_type_with_styp(typ, styp)
|
mut str_fn_name := g.gen_str_for_type_with_styp(typ, styp)
|
||||||
if g.autofree && !typ.flag_is(.optional) {
|
if g.autofree && !typ.has_flag(.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
|
||||||
|
@ -565,7 +565,7 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
|
||||||
g.write('*')
|
g.write('*')
|
||||||
}
|
}
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
if !typ.flag_is(.variadic) && sym.kind == .struct_ && styp != 'ptr' && !sym.has_method('str') {
|
if !typ.has_flag(.variadic) && sym.kind == .struct_ && styp != 'ptr' && !sym.has_method('str') {
|
||||||
g.write(', 0') // trailing 0 is initial struct indent count
|
g.write(', 0') // trailing 0 is initial struct indent count
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -599,8 +599,8 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) call_args(args []ast.CallArg, expected_types []table.Type) {
|
fn (mut g Gen) call_args(args []ast.CallArg, expected_types []table.Type) {
|
||||||
is_variadic := expected_types.len > 0 && expected_types[expected_types.len - 1].flag_is(.variadic)
|
is_variadic := expected_types.len > 0 && expected_types[expected_types.len - 1].has_flag(.variadic)
|
||||||
is_forwarding_varg := args.len > 0 && args[args.len - 1].typ.flag_is(.variadic)
|
is_forwarding_varg := args.len > 0 && args[args.len - 1].typ.has_flag(.variadic)
|
||||||
gen_vargs := is_variadic && !is_forwarding_varg
|
gen_vargs := is_variadic && !is_forwarding_varg
|
||||||
for i, arg in args {
|
for i, arg in args {
|
||||||
if gen_vargs && i == expected_types.len - 1 {
|
if gen_vargs && i == expected_types.len - 1 {
|
||||||
|
|
|
@ -908,7 +908,7 @@ fn (mut g JsGen) gen_for_in_stmt(it ast.ForInStmt) {
|
||||||
g.inside_loop = false
|
g.inside_loop = false
|
||||||
g.stmts(it.stmts)
|
g.stmts(it.stmts)
|
||||||
g.writeln('}')
|
g.writeln('}')
|
||||||
} else if it.kind == .array || it.cond_type.flag_is(.variadic) {
|
} else if it.kind == .array || it.cond_type.has_flag(.variadic) {
|
||||||
// `for num in nums {`
|
// `for num in nums {`
|
||||||
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.val_type)
|
// styp := g.typ(it.val_type)
|
||||||
|
|
|
@ -36,8 +36,8 @@ pub mut:
|
||||||
is_public bool
|
is_public bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// max of 8
|
||||||
pub enum TypeFlag {
|
pub enum TypeFlag {
|
||||||
unset
|
|
||||||
optional
|
optional
|
||||||
variadic
|
variadic
|
||||||
generic
|
generic
|
||||||
|
@ -99,29 +99,33 @@ pub fn (t Type) deref() Type {
|
||||||
return (((int(t) >> 24) & 0xff) << 24) | ((nr_muls - 1) << 16) | (u16(t) & 0xffff)
|
return (((int(t) >> 24) & 0xff) << 24) | ((nr_muls - 1) << 16) | (u16(t) & 0xffff)
|
||||||
}
|
}
|
||||||
|
|
||||||
// return the flag that is set on `t`
|
// set `flag` on `t` and return `t`
|
||||||
[inline]
|
|
||||||
pub fn (t Type) flag() TypeFlag {
|
|
||||||
return (int(t) >> 24) & 0xff
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the flag on `t` to `flag` and return it
|
|
||||||
[inline]
|
[inline]
|
||||||
pub fn (t Type) set_flag(flag TypeFlag) Type {
|
pub fn (t Type) set_flag(flag TypeFlag) Type {
|
||||||
return (int(flag) << 24) | (((int(t) >> 16) & 0xff) << 16) | (u16(t) & 0xffff)
|
return ((((int(t) >> 24) & 0xff) | 1 << int(flag)) << 24) | (((int(t) >> 16) & 0xff) << 16) | (u16(t) & 0xffff)
|
||||||
}
|
}
|
||||||
|
|
||||||
// return true if the flag set on `t` is `flag`
|
// clear `flag` on `t` and return `t`
|
||||||
|
pub fn (t Type) clear_flag(flag TypeFlag) Type {
|
||||||
|
return (((((int(t) >> 24) & 0xff) & ~(1 << int(flag))) << 24) ) | (((int(t) >> 16) & 0xff) << 16) | (u16(t) & 0xffff)
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear all flags
|
||||||
|
pub fn (t Type) clear_flags() Type {
|
||||||
|
return 0 | (((int(t) >> 16) & 0xff) << 16) | (u16(t) & 0xffff)
|
||||||
|
}
|
||||||
|
|
||||||
|
// return true if `flag` is set in `t`
|
||||||
[inline]
|
[inline]
|
||||||
pub fn (t Type) flag_is(flag TypeFlag) bool {
|
pub fn (t Type) has_flag(flag TypeFlag) bool {
|
||||||
return (int(t) >> 24) & 0xff == flag
|
return (((int(t) >> 24) & 0xff) >> int(flag)) & 1 == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
// return new type with TypeSymbol idx set to `idx`
|
// return new type with TypeSymbol idx set to `idx`
|
||||||
[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 > 65535 {
|
||||||
panic('new_type_id: idx must be between 1 & 65536')
|
panic('new_type_id: idx must be between 1 & 65535')
|
||||||
}
|
}
|
||||||
return idx
|
return idx
|
||||||
}
|
}
|
||||||
|
@ -129,8 +133,8 @@ pub fn new_type(idx int) Type {
|
||||||
// return new type with TypeSymbol idx set to `idx` & nr_muls set to `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, nr_muls int) Type {
|
pub fn new_type_ptr(idx, nr_muls int) Type {
|
||||||
if idx < 1 || idx > 65536 {
|
if idx < 1 || idx > 65535 {
|
||||||
panic('new_type_ptr: idx must be between 1 & 65536')
|
panic('new_type_ptr: idx must be between 1 & 65535')
|
||||||
}
|
}
|
||||||
if nr_muls < 0 || nr_muls > 255 {
|
if nr_muls < 0 || nr_muls > 255 {
|
||||||
panic('new_type_ptr: nr_muls must be between 0 & 255')
|
panic('new_type_ptr: nr_muls must be between 0 & 255')
|
||||||
|
@ -673,7 +677,7 @@ pub fn (table &Table) type_to_str(t Type) string {
|
||||||
mut res := sym.name
|
mut res := sym.name
|
||||||
if sym.kind == .multi_return {
|
if sym.kind == .multi_return {
|
||||||
res = '('
|
res = '('
|
||||||
if t.flag_is(.optional) {
|
if t.has_flag(.optional) {
|
||||||
res = '?' + res
|
res = '?' + res
|
||||||
}
|
}
|
||||||
mr_info := sym.info as MultiReturn
|
mr_info := sym.info as MultiReturn
|
||||||
|
@ -706,7 +710,7 @@ pub fn (table &Table) type_to_str(t Type) string {
|
||||||
if nr_muls > 0 {
|
if nr_muls > 0 {
|
||||||
res = strings.repeat(`&`, nr_muls) + res
|
res = strings.repeat(`&`, nr_muls) + res
|
||||||
}
|
}
|
||||||
if t.flag_is(.optional) {
|
if t.has_flag(.optional) {
|
||||||
if sym.kind == .void {
|
if sym.kind == .void {
|
||||||
res = '?'
|
res = '?'
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -417,9 +417,9 @@ pub fn (mut t 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 typ.flag_is(.variadic) {
|
if typ.has_flag(.variadic) {
|
||||||
// ...string => string
|
// ...string => string
|
||||||
return typ.set_flag(.unset)
|
return typ.clear_flag(.variadic)
|
||||||
}
|
}
|
||||||
if typ_sym.kind == .array {
|
if typ_sym.kind == .array {
|
||||||
// Check index type
|
// Check index type
|
||||||
|
|
Loading…
Reference in New Issue