compiler: vargs - for loop support & indexing / dot fixes
parent
5ac62bbb75
commit
7311db60a0
|
@ -886,6 +886,7 @@ fn (p mut Parser) fn_call_args(f mut Fn) &Fn {
|
||||||
p.gen('/*YY f=$f.name arg=$arg.name is_moved=$arg.is_moved*/string_clone(')
|
p.gen('/*YY f=$f.name arg=$arg.name is_moved=$arg.is_moved*/string_clone(')
|
||||||
}
|
}
|
||||||
mut typ := p.bool_expression()
|
mut typ := p.bool_expression()
|
||||||
|
if typ.starts_with('...') { typ = typ.right(3) }
|
||||||
if clone {
|
if clone {
|
||||||
p.gen(')')
|
p.gen(')')
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ fn (p mut Parser) gen_var_decl(name string, is_static bool) string {
|
||||||
// `[typ] [name] = bool_expression();`
|
// `[typ] [name] = bool_expression();`
|
||||||
pos := p.cgen.add_placeholder()
|
pos := p.cgen.add_placeholder()
|
||||||
mut typ := p.bool_expression()
|
mut typ := p.bool_expression()
|
||||||
|
if typ.starts_with('...') { typ = typ.right(3) }
|
||||||
//p.gen('/*after expr*/')
|
//p.gen('/*after expr*/')
|
||||||
// Option check ? or {
|
// Option check ? or {
|
||||||
or_else := p.tok == .key_orelse
|
or_else := p.tok == .key_orelse
|
||||||
|
@ -284,6 +285,12 @@ fn (p mut Parser) gen_for_map_header(i, tmp, var_typ, val, typ string) {
|
||||||
p.genln('$var_typ $val = $def; map_get($tmp, $i, & $val);')
|
p.genln('$var_typ $val = $def; map_get($tmp, $i, & $val);')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (p mut Parser) gen_for_varg_header(i, varg, var_typ, val string) {
|
||||||
|
p.genln('for (int $i = 0; $i < ${varg}->len; $i++) {')
|
||||||
|
if val == '_' { return }
|
||||||
|
p.genln('$var_typ $val = (($var_typ *) $varg->args)[$i];')
|
||||||
|
}
|
||||||
|
|
||||||
fn (p mut Parser) gen_array_init(typ string, no_alloc bool, new_arr_ph int, nr_elems int) {
|
fn (p mut Parser) gen_array_init(typ string, no_alloc bool, new_arr_ph int, nr_elems int) {
|
||||||
mut new_arr := 'new_array_from_c_array'
|
mut new_arr := 'new_array_from_c_array'
|
||||||
if no_alloc {
|
if no_alloc {
|
||||||
|
|
|
@ -8,7 +8,8 @@ const (
|
||||||
|
|
||||||
fn (p mut Parser) gen_var_decl(name string, is_static bool) string {
|
fn (p mut Parser) gen_var_decl(name string, is_static bool) string {
|
||||||
p.gen('var $name /* typ */ = ')
|
p.gen('var $name /* typ */ = ')
|
||||||
typ := p.bool_expression()
|
mut typ := p.bool_expression()
|
||||||
|
if typ.starts_with('...') { typ = typ.right(3) }
|
||||||
or_else := p.tok == .key_orelse
|
or_else := p.tok == .key_orelse
|
||||||
//tmp := p.get_tmp()
|
//tmp := p.get_tmp()
|
||||||
if or_else {
|
if or_else {
|
||||||
|
@ -121,6 +122,12 @@ fn (p mut Parser) gen_for_map_header(i, tmp, var_typ, val, typ string) {
|
||||||
p.genln('var $val = $tmp[$i];')
|
p.genln('var $val = $tmp[$i];')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (p mut Parser) gen_for_varg_header(i, varg, var_typ, val string) {
|
||||||
|
p.genln('for (var $i = 0; $i < ${varg}.len; $i++) {')
|
||||||
|
if val == '_' { return }
|
||||||
|
p.genln('var $val = ${varg}.args[$i];')
|
||||||
|
}
|
||||||
|
|
||||||
fn (p mut Parser) gen_array_init(typ string, no_alloc bool, new_arr_ph int, nr_elems int) {
|
fn (p mut Parser) gen_array_init(typ string, no_alloc bool, new_arr_ph int, nr_elems int) {
|
||||||
p.cgen.set_placeholder(new_arr_ph, '[')
|
p.cgen.set_placeholder(new_arr_ph, '[')
|
||||||
p.gen(']')
|
p.gen(']')
|
||||||
|
|
|
@ -1954,10 +1954,8 @@ fn (p mut Parser) dot(str_typ_ string, method_ph int) string {
|
||||||
mut str_typ := str_typ_
|
mut str_typ := str_typ_
|
||||||
p.check(.dot)
|
p.check(.dot)
|
||||||
is_variadic_arg := str_typ.starts_with('...')
|
is_variadic_arg := str_typ.starts_with('...')
|
||||||
if is_variadic_arg {
|
if is_variadic_arg { str_typ = str_typ.right(3) }
|
||||||
str_typ = str_typ.right(3)
|
mut typ := p.find_type(str_typ)
|
||||||
}
|
|
||||||
typ := p.find_type(str_typ)
|
|
||||||
if typ.name.len == 0 {
|
if typ.name.len == 0 {
|
||||||
p.error('dot(): cannot find type `$str_typ`')
|
p.error('dot(): cannot find type `$str_typ`')
|
||||||
}
|
}
|
||||||
|
@ -1973,10 +1971,7 @@ fn (p mut Parser) dot(str_typ_ string, method_ph int) string {
|
||||||
//}
|
//}
|
||||||
has_field := p.table.type_has_field(typ, p.table.var_cgen_name(field_name))
|
has_field := p.table.type_has_field(typ, p.table.var_cgen_name(field_name))
|
||||||
mut has_method := p.table.type_has_method(typ, field_name)
|
mut has_method := p.table.type_has_method(typ, field_name)
|
||||||
if is_variadic_arg {
|
if is_variadic_arg && field_name == 'len' {
|
||||||
if field_name != 'len' {
|
|
||||||
p.error('the only field you can access on variadic args is `.len`')
|
|
||||||
}
|
|
||||||
p.gen('->$field_name')
|
p.gen('->$field_name')
|
||||||
p.next()
|
p.next()
|
||||||
return 'int'
|
return 'int'
|
||||||
|
@ -2192,25 +2187,23 @@ fn (p mut Parser) index_expr(typ_ string, fn_ph int) string {
|
||||||
p.expr_var = v
|
p.expr_var = v
|
||||||
}
|
}
|
||||||
// accessing variadiac args
|
// accessing variadiac args
|
||||||
if !p.first_pass() && is_variadic_arg {
|
if is_variadic_arg {
|
||||||
typ = typ.right(3)
|
// TODO: why was this here?
|
||||||
if p.calling_c {
|
// if p.calling_c {
|
||||||
p.error('you cannot currently pass varg to a C function.')
|
// p.error('you cannot currently pass varg to a C function.')
|
||||||
|
// }
|
||||||
|
if is_indexer {
|
||||||
|
l := p.cgen.cur_line.trim_space()
|
||||||
|
index_val := l.right(l.last_index(' ')).trim_space()
|
||||||
|
p.cgen.resetln(l.left(fn_ph))
|
||||||
|
p.table.varg_access << VargAccess{
|
||||||
|
fn_name: p.cur_fn.name,
|
||||||
|
tok_idx: p.token_idx,
|
||||||
|
index: index_val.int()
|
||||||
|
}
|
||||||
|
p.cgen.set_placeholder(fn_ph, '${v.name}->args[$index_val]')
|
||||||
|
return typ
|
||||||
}
|
}
|
||||||
if !is_indexer {
|
|
||||||
p.error('You must use array access syntax for variadic arguments.')
|
|
||||||
}
|
|
||||||
varg_type := typ.right(3)
|
|
||||||
l := p.cgen.cur_line.trim_space()
|
|
||||||
index_val := l.right(l.last_index(' ')).trim_space()
|
|
||||||
p.cgen.resetln(l.left(fn_ph))
|
|
||||||
p.table.varg_access << VargAccess{
|
|
||||||
fn_name: p.cur_fn.name,
|
|
||||||
tok_idx: p.token_idx,
|
|
||||||
index: index_val.int()
|
|
||||||
}
|
|
||||||
p.cgen.set_placeholder(fn_ph, '${v.name}->args[$index_val]')
|
|
||||||
return typ
|
|
||||||
}
|
}
|
||||||
// TODO move this from index_expr()
|
// TODO move this from index_expr()
|
||||||
// TODO if p.tok in ...
|
// TODO if p.tok in ...
|
||||||
|
@ -3264,21 +3257,27 @@ fn (p mut Parser) for_st() {
|
||||||
p.fgen(' ')
|
p.fgen(' ')
|
||||||
tmp := p.get_tmp()
|
tmp := p.get_tmp()
|
||||||
p.cgen.start_tmp()
|
p.cgen.start_tmp()
|
||||||
typ := p.bool_expression()
|
mut typ := p.bool_expression()
|
||||||
is_arr := typ.starts_with('array_')
|
is_arr := typ.starts_with('array_')
|
||||||
is_map := typ.starts_with('map_')
|
is_map := typ.starts_with('map_')
|
||||||
is_str := typ == 'string'
|
is_str := typ == 'string'
|
||||||
if !is_arr && !is_str && !is_map {
|
is_variadic_arg := typ.starts_with('...')
|
||||||
|
if is_variadic_arg { typ = typ.right(3) }
|
||||||
|
if !is_arr && !is_str && !is_map && !is_variadic_arg {
|
||||||
p.error('cannot range over type `$typ`')
|
p.error('cannot range over type `$typ`')
|
||||||
}
|
}
|
||||||
expr := p.cgen.end_tmp()
|
expr := p.cgen.end_tmp()
|
||||||
if p.is_js {
|
if !is_variadic_arg {
|
||||||
p.genln('var $tmp = $expr;')
|
if p.is_js {
|
||||||
} else {
|
p.genln('var $tmp = $expr;')
|
||||||
p.genln('$typ $tmp = $expr;')
|
} else {
|
||||||
}
|
p.genln('$typ $tmp = $expr;')
|
||||||
|
}
|
||||||
|
}
|
||||||
pad := if is_arr { 6 } else { 4 }
|
pad := if is_arr { 6 } else { 4 }
|
||||||
var_typ := if is_str { 'byte' } else { typ.right(pad) }
|
var_typ := if is_str { 'byte' }
|
||||||
|
else if is_variadic_arg { typ }
|
||||||
|
else { typ.right(pad) }
|
||||||
// typ = strings.Replace(typ, "_ptr", "*", -1)
|
// typ = strings.Replace(typ, "_ptr", "*", -1)
|
||||||
mut i_var_type := 'int'
|
mut i_var_type := 'int'
|
||||||
if is_arr {
|
if is_arr {
|
||||||
|
@ -3292,6 +3291,9 @@ fn (p mut Parser) for_st() {
|
||||||
i_var_type = 'byte'
|
i_var_type = 'byte'
|
||||||
p.gen_for_str_header(i, tmp, var_typ, val)
|
p.gen_for_str_header(i, tmp, var_typ, val)
|
||||||
}
|
}
|
||||||
|
else if is_variadic_arg {
|
||||||
|
p.gen_for_varg_header(i, expr, typ, val)
|
||||||
|
}
|
||||||
// Register temp vars
|
// Register temp vars
|
||||||
if i != '_' {
|
if i != '_' {
|
||||||
p.register_var(Var {
|
p.register_var(Var {
|
||||||
|
@ -3317,9 +3319,11 @@ fn (p mut Parser) for_st() {
|
||||||
p.fspace()
|
p.fspace()
|
||||||
tmp := p.get_tmp()
|
tmp := p.get_tmp()
|
||||||
p.cgen.start_tmp()
|
p.cgen.start_tmp()
|
||||||
typ := p.bool_expression()
|
mut typ := p.bool_expression()
|
||||||
expr := p.cgen.end_tmp()
|
expr := p.cgen.end_tmp()
|
||||||
is_range := p.tok == .dotdot
|
is_range := p.tok == .dotdot
|
||||||
|
is_variadic_arg := typ.starts_with('...')
|
||||||
|
if is_variadic_arg { typ = typ.right(3) }
|
||||||
mut range_end := ''
|
mut range_end := ''
|
||||||
if is_range {
|
if is_range {
|
||||||
p.check_types(typ, 'int')
|
p.check_types(typ, 'int')
|
||||||
|
@ -3330,24 +3334,32 @@ fn (p mut Parser) for_st() {
|
||||||
}
|
}
|
||||||
is_arr := typ.contains('array')
|
is_arr := typ.contains('array')
|
||||||
is_str := typ == 'string'
|
is_str := typ == 'string'
|
||||||
if !is_arr && !is_str && !is_range {
|
if !is_arr && !is_str && !is_range && !is_variadic_arg {
|
||||||
p.error('cannot range over type `$typ`')
|
p.error('cannot range over type `$typ`')
|
||||||
}
|
}
|
||||||
if p.is_js {
|
if !is_variadic_arg {
|
||||||
p.genln('var $tmp = $expr;')
|
if p.is_js {
|
||||||
} else {
|
p.genln('var $tmp = $expr;')
|
||||||
p.genln('$typ $tmp = $expr;')
|
} else {
|
||||||
|
p.genln('$typ $tmp = $expr;')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// TODO var_type := if...
|
// TODO var_type := if...
|
||||||
mut var_type := ''
|
i := p.get_tmp()
|
||||||
|
mut var_type := typ
|
||||||
if is_arr {
|
if is_arr {
|
||||||
var_type = typ.right(6)// all after `array_`
|
var_type = typ.right(6)// all after `array_`
|
||||||
|
p.gen_for_header(i, tmp, var_type, val)
|
||||||
}
|
}
|
||||||
else if is_str {
|
else if is_str {
|
||||||
var_type = 'byte'
|
var_type = 'byte'
|
||||||
|
p.gen_for_str_header(i, tmp, var_type, val)
|
||||||
}
|
}
|
||||||
else if is_range {
|
else if is_range {
|
||||||
var_type = 'int'
|
var_type = 'int'
|
||||||
|
p.gen_for_range_header(i, range_end, tmp, var_type, val)
|
||||||
|
} else if is_variadic_arg {
|
||||||
|
p.gen_for_varg_header(i, expr, typ, val)
|
||||||
}
|
}
|
||||||
// println('for typ=$typ vartyp=$var_typ')
|
// println('for typ=$typ vartyp=$var_typ')
|
||||||
// Register temp var
|
// Register temp var
|
||||||
|
@ -3359,16 +3371,6 @@ fn (p mut Parser) for_st() {
|
||||||
is_changed: true
|
is_changed: true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
i := p.get_tmp()
|
|
||||||
if is_arr {
|
|
||||||
p.gen_for_header(i, tmp, var_type, val)
|
|
||||||
}
|
|
||||||
else if is_str {
|
|
||||||
p.gen_for_str_header(i, tmp, var_type, val)
|
|
||||||
}
|
|
||||||
else if is_range {
|
|
||||||
p.gen_for_range_header(i, range_end, tmp, var_type, val)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// `for a < b {`
|
// `for a < b {`
|
||||||
p.gen('while (')
|
p.gen('while (')
|
||||||
|
|
Loading…
Reference in New Issue