rename if_st to if_statement

pull/2997/head
Alexander Medvednikov 2019-12-06 19:21:26 +03:00
parent bf1b751f47
commit e3b5d7fd7c
3 changed files with 122 additions and 121 deletions

View File

@ -743,7 +743,7 @@ fn (p mut Parser) factor() string {
return p.assoc() return p.assoc()
} }
.key_if { .key_if {
typ = p.if_st(true, 0) typ = p.if_statement(true, 0)
return typ return typ
} }
.key_match { .key_match {

View File

@ -8,14 +8,14 @@ import (
strings strings
) )
// Returns typ if used as expression // Returns type if used as expression
fn (p mut Parser) match_statement(is_expr bool) string { fn (p mut Parser) match_statement(is_expr bool) string {
p.check(.key_match) p.check(.key_match)
p.fspace() p.fspace()
typ, expr := p.tmp_expr() typ, expr := p.tmp_expr()
if typ.starts_with('array_') { if typ.starts_with('array_') {
p.error('arrays cannot be compared') p.error('arrays cannot be compared')
} }
// is it safe to use p.cgen.insert_before ??? // is it safe to use p.cgen.insert_before ???
tmp_var := p.get_tmp() tmp_var := p.get_tmp()
p.cgen.insert_before('$typ $tmp_var = $expr;') p.cgen.insert_before('$typ $tmp_var = $expr;')
@ -37,7 +37,7 @@ fn (p mut Parser) match_statement(is_expr bool) string {
p.check(.key_else) p.check(.key_else)
if p.tok == .arrow { if p.tok == .arrow {
p.error(warn_match_arrow) p.error(warn_match_arrow)
} }
// unwrap match if there is only else // unwrap match if there is only else
if i == 0 { if i == 0 {
@ -169,7 +169,7 @@ fn (p mut Parser) match_statement(is_expr bool) string {
if p.tok == .arrow { if p.tok == .arrow {
p.error(warn_match_arrow) p.error(warn_match_arrow)
p.check(.arrow) p.check(.arrow)
} }
// statements are dissallowed (if match is expression) so user cant declare variables there and so on // statements are dissallowed (if match is expression) so user cant declare variables there and so on
if is_expr { if is_expr {
@ -221,4 +221,120 @@ fn (p mut Parser) switch_statement() {
'https://vlang.io/docs#match') 'https://vlang.io/docs#match')
} }
fn (p mut Parser) if_statement(is_expr bool, elif_depth int) string {
if is_expr {
//if p.fileis('if_expr') {
//println('IF EXPR')
//}
p.inside_if_expr = true
p.gen('((')
}
else {
p.gen('if (')
}
p.next()
p.fspace()
// `if a := opt() { }` syntax
if p.tok == .name && p.peek() == .decl_assign {
p.check_not_reserved()
option_tmp := p.get_tmp()
var_name := p.lit
p.next()
p.check(.decl_assign)
p.is_var_decl = true
option_type, expr := p.tmp_expr()// := p.bool_expression()
p.is_var_decl = false
typ := option_type[7..]
// Option_User tmp = get_user(1);
// if (tmp.ok) {
// User user = *(User*)tmp.data;
// [statements]
// }
p.cgen.insert_before('$option_type $option_tmp = $expr; ')
p.check(.lcbr)
p.genln(option_tmp + '.ok) {')
p.genln('$typ $var_name = *($typ*) $option_tmp . data;')
p.register_var(Var {
name: var_name
typ: typ
is_mut: false // TODO
//is_alloc: p.is_alloc || typ.starts_with('array_')
//line_nr: p.tokens[ var_token_idx ].line_nr
//token_idx: var_token_idx
})
p.statements()
p.returns = false
return 'void'
} else {
p.check_types(p.bool_expression(), 'bool')
}
if is_expr {
p.gen(') ? (')
}
else {
p.genln(') {')
}
p.fspace()
p.check(.lcbr)
mut typ := ''
// if { if hack
if p.tok == .key_if && p.inside_if_expr {
typ = p.factor()
p.next()
}
else {
typ = p.statements()
}
if_returns := p.returns
p.returns = false
if p.tok == .key_else {
if !p.inside_if_expr {
p.fgen_nl()
}
p.check(.key_else)
p.fspace()
if p.tok == .key_if {
if is_expr {
p.gen(') : (')
nested := p.if_statement(is_expr, elif_depth + 1)
nested_returns := p.returns
p.returns = if_returns && nested_returns
return nested
}
else {
p.gen(' else ')
nested := p.if_statement(is_expr, 0)
nested_returns := p.returns
p.returns = if_returns && nested_returns
return nested
}
// return ''
}
if is_expr {
p.gen(') : (')
}
else {
p.genln(' else { ')
}
p.check(.lcbr)
// statements() returns the type of the last statement
first_typ := typ
typ = p.statements()
p.inside_if_expr = false
if is_expr {
p.check_types(first_typ, typ)
p.gen(strings.repeat(`)`, 2 * (elif_depth + 1)))
}
else_returns := p.returns
p.returns = if_returns && else_returns
return typ
}
p.inside_if_expr = false
if p.fileis('test_test') {
println('if ret typ="$typ" line=$p.scanner.line_nr')
}
return typ
}

View File

@ -1276,7 +1276,7 @@ fn (p mut Parser) statement(add_semi bool) string {
p.comp_time() p.comp_time()
} }
.key_if { .key_if {
p.if_st(false, 0) p.if_statement(false, 0)
} }
.key_for { .key_for {
p.for_st() p.for_st()
@ -2638,121 +2638,6 @@ fn (p mut Parser) get_tmp_counter() int {
} }
fn (p mut Parser) if_st(is_expr bool, elif_depth int) string {
if is_expr {
//if p.fileis('if_expr') {
//println('IF EXPR')
//}
p.inside_if_expr = true
p.gen('((')
}
else {
p.gen('if (')
}
p.next()
p.fspace()
// `if a := opt() { }` syntax
if p.tok == .name && p.peek() == .decl_assign {
p.check_not_reserved()
option_tmp := p.get_tmp()
var_name := p.lit
p.next()
p.check(.decl_assign)
p.is_var_decl = true
option_type, expr := p.tmp_expr()// := p.bool_expression()
p.is_var_decl = false
typ := option_type[7..]
// Option_User tmp = get_user(1);
// if (tmp.ok) {
// User user = *(User*)tmp.data;
// [statements]
// }
p.cgen.insert_before('$option_type $option_tmp = $expr; ')
p.check(.lcbr)
p.genln(option_tmp + '.ok) {')
p.genln('$typ $var_name = *($typ*) $option_tmp . data;')
p.register_var(Var {
name: var_name
typ: typ
is_mut: false // TODO
//is_alloc: p.is_alloc || typ.starts_with('array_')
//line_nr: p.tokens[ var_token_idx ].line_nr
//token_idx: var_token_idx
})
p.statements()
p.returns = false
return 'void'
} else {
p.check_types(p.bool_expression(), 'bool')
}
if is_expr {
p.gen(') ? (')
}
else {
p.genln(') {')
}
p.fspace()
p.check(.lcbr)
mut typ := ''
// if { if hack
if p.tok == .key_if && p.inside_if_expr {
typ = p.factor()
p.next()
}
else {
typ = p.statements()
}
if_returns := p.returns
p.returns = false
if p.tok == .key_else {
if !p.inside_if_expr {
p.fgen_nl()
}
p.check(.key_else)
p.fspace()
if p.tok == .key_if {
if is_expr {
p.gen(') : (')
nested := p.if_st(is_expr, elif_depth + 1)
nested_returns := p.returns
p.returns = if_returns && nested_returns
return nested
}
else {
p.gen(' else ')
nested := p.if_st(is_expr, 0)
nested_returns := p.returns
p.returns = if_returns && nested_returns
return nested
}
// return ''
}
if is_expr {
p.gen(') : (')
}
else {
p.genln(' else { ')
}
p.check(.lcbr)
// statements() returns the type of the last statement
first_typ := typ
typ = p.statements()
p.inside_if_expr = false
if is_expr {
p.check_types(first_typ, typ)
p.gen(strings.repeat(`)`, 2 * (elif_depth + 1)))
}
else_returns := p.returns
p.returns = if_returns && else_returns
return typ
}
p.inside_if_expr = false
if p.fileis('test_test') {
println('if ret typ="$typ" line=$p.scanner.line_nr')
}
return typ
}
fn (p mut Parser) assert_statement() { fn (p mut Parser) assert_statement() {
if p.first_pass() { if p.first_pass() {
return return