parser: move duplicate code into single function

pull/2595/head
joe-conigliaro 2019-10-31 21:49:57 +11:00 committed by Alexander Medvednikov
parent b1730b768d
commit 5acdf425ab
2 changed files with 48 additions and 64 deletions

View File

@ -21,42 +21,8 @@ fn (p mut Parser) gen_var_decl(name string, is_static bool) string {
//p.gen('/*after expr*/')
// Option check ? or {
or_else := p.tok == .key_orelse
tmp := p.get_tmp()
if or_else {
// Option_User tmp = get_user(1);
// if (!tmp.ok) { or_statement }
// User user = *(User*)tmp.data;
// p.assigned_var = ''
p.cgen.set_placeholder(pos, '$typ $tmp = ')
p.genln(';')
if !typ.starts_with('Option_') {
p.error('`or` block cannot be applied to non-optional type')
}
typ = typ.replace('Option_', '')
p.next()
p.check(.lcbr)
p.genln('if (!$tmp .ok) {')
p.register_var(Var {
name: 'err'
typ: 'string'
is_mut: false
is_used: true
})
p.register_var(Var {
name: 'errcode'
typ: 'int'
is_mut: false
is_used: true
})
p.genln('string err = $tmp . error;')
p.genln('int errcode = $tmp . ecode;')
p.statements()
p.genln('$typ $name = *($typ*) $tmp . data;')
if !p.returns && p.prev_tok2 != .key_continue && p.prev_tok2 != .key_break {
p.error('`or` block must return/exit/continue/break/panic')
}
p.returns = false
return typ
return p.gen_handle_option_or_else(typ, name, pos)
}
gen_name := p.table.var_cgen_name(name)
mut nt_gen := p.table.cgen_name_type_pair(gen_name, typ)
@ -102,19 +68,33 @@ fn (p mut Parser) gen_blank_identifier_assign() {
is_indexer := p.peek() == .lsbr
is_fn_call, next_expr := p.is_next_expr_fn_call()
pos := p.cgen.add_placeholder()
mut typ := p.bool_expression()
typ := p.bool_expression()
if !is_indexer && !is_fn_call {
p.error_with_token_index('assigning `$next_expr` to `_` is redundant', assign_error_tok_idx)
}
tmp := p.get_tmp()
// handle or
if p.tok == .key_orelse {
p.cgen.set_placeholder(pos, '$typ $tmp = ')
p.gen_handle_option_or_else(typ, '', pos)
} else {
if is_fn_call {
p.gen(';')
} else {
p.cgen.resetln('{$typ _ = $p.cgen.cur_line;}')
}
}
}
fn (p mut Parser) gen_handle_option_or_else(_typ, name string, fn_call_ph int) string {
mut typ := _typ
if !typ.starts_with('Option_') {
p.error('`or` block cannot be applied to non-optional type')
}
is_assign := name.len > 0
tmp := p.get_tmp()
p.cgen.set_placeholder(fn_call_ph, '$typ $tmp = ')
typ = typ[7..]
p.genln(';')
typ = typ.replace('Option_', '')
p.next()
p.check(.key_orelse)
p.check(.lcbr)
p.genln('if (!$tmp .ok) {')
p.register_var(Var {
name: 'err'
typ: 'string'
@ -127,17 +107,18 @@ fn (p mut Parser) gen_blank_identifier_assign() {
is_mut: false
is_used: true
})
p.genln('if (!$tmp .ok) {')
p.genln('string err = $tmp . error;')
p.genln('int errcode = $tmp . ecode;')
p.statements()
if is_assign {
p.genln('$typ $name = *($typ*) $tmp . data;')
}
if !p.returns && p.prev_tok2 != .key_continue && p.prev_tok2 != .key_break {
p.error('`or` block must return/exit/continue/break/panic')
}
p.returns = false
} else {
if is_fn_call {
p.gen(';')
} else {
p.cgen.resetln('{$typ _ = $p.cgen.cur_line;}')
}
}
return typ
}
fn types_to_c(types []Type, table &Table) string {

View File

@ -11,9 +11,8 @@ fn (p mut Parser) gen_var_decl(name string, is_static bool) string {
mut typ := p.bool_expression()
if typ.starts_with('...') { typ = typ[3..] }
or_else := p.tok == .key_orelse
//tmp := p.get_tmp()
if or_else {
//panic('optionals todo')
// return p.gen_handle_option_or_else(typ, name, pos)
}
return typ
}
@ -46,12 +45,16 @@ fn (p mut Parser) gen_blank_identifier_assign() {
p.error_with_token_index('assigning `$next_expr` to `_` is redundant', assign_error_tok_idx)
}
or_else := p.tok == .key_orelse
//tmp := p.get_tmp()
if or_else {
//panic('optionals todo')
// return p.gen_handle_option_or_else(typ, '', pos)
}
}
// TODO: optionals
fn (p mut Parser) gen_handle_option_or_else(_typ, name string, fn_call_ph int) string {
return _typ
}
fn types_to_c(types []Type, table &Table) string {
mut sb := strings.new_builder(10)
for t in types {