parser: minor `match` simplification

pull/6104/head
Alexander Medvednikov 2020-08-10 19:54:38 +02:00
parent c3cdfa1c96
commit 88988817d0
7 changed files with 50 additions and 25 deletions

View File

@ -411,6 +411,7 @@ pub fn (b []byte) clone() []byte {
return res return res
} }
// TODO remove this once runes are implemented
pub fn (b []byte) bytestr() string { pub fn (b []byte) bytestr() string {
return bytes2string(b) return bytes2string(b)
} }

View File

@ -21,7 +21,7 @@ pub fn (mut b Builder) build_x64(v_files []string, out_file string) {
t2 := time.ticks() t2 := time.ticks()
check_time := t2 - t1 check_time := t2 - t1
b.timing_message('CHECK', check_time) b.timing_message('CHECK', check_time)
x64.gen(b.parsed_files, out_file, b.pref) x64.gen(b.parsed_files, b.table, out_file, b.pref)
t3 := time.ticks() t3 := time.ticks()
gen_time := t3 - t2 gen_time := t3 - t2
b.timing_message('x64 GEN', gen_time) b.timing_message('x64 GEN', gen_time)

View File

@ -1589,6 +1589,9 @@ pub fn (mut c Checker) enum_decl(decl ast.EnumDecl) {
pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
c.expected_type = table.none_type // TODO a hack to make `x := if ... work` c.expected_type = table.none_type // TODO a hack to make `x := if ... work`
defer {
c.expected_type = table.void_type
}
right_first := assign_stmt.right[0] right_first := assign_stmt.right[0]
mut right_len := assign_stmt.right.len mut right_len := assign_stmt.right.len
if right_first is ast.CallExpr || right_first is ast.IfExpr || right_first is ast.MatchExpr { if right_first is ast.CallExpr || right_first is ast.IfExpr || right_first is ast.MatchExpr {
@ -1720,6 +1723,10 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
assign_stmt.op !in [.assign, .decl_assign] && !c.inside_unsafe { assign_stmt.op !in [.assign, .decl_assign] && !c.inside_unsafe {
c.warn('pointer arithmetic is only allowed in `unsafe` blocks', assign_stmt.pos) c.warn('pointer arithmetic is only allowed in `unsafe` blocks', assign_stmt.pos)
} }
if c.pref.translated {
// TODO fix this in C2V instead, for example cast enums to int before using `|` on them.
return
}
// Single side check // Single side check
match assign_stmt.op { match assign_stmt.op {
.assign {} // No need to do single side check for =. But here put it first for speed. .assign {} // No need to do single side check for =. But here put it first for speed.
@ -1774,7 +1781,6 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
right.position()) right.position())
} }
} }
c.expected_type = table.void_type
} }
fn (mut c Checker) check_array_init_para_type(para string, expr ast.Expr, pos token.Position) { fn (mut c Checker) check_array_init_para_type(para string, expr ast.Expr, pos token.Position) {

View File

@ -49,6 +49,7 @@ fn (mut g Gen) gen_str_for_type_with_styp(typ table.Type, styp string) string {
table.Struct { g.gen_str_for_struct(it, styp, str_fn_name) } table.Struct { g.gen_str_for_struct(it, styp, str_fn_name) }
table.Map { g.gen_str_for_map(it, styp, str_fn_name) } table.Map { g.gen_str_for_map(it, styp, str_fn_name) }
table.MultiReturn { g.gen_str_for_multi_return(it, styp, str_fn_name) } table.MultiReturn { g.gen_str_for_multi_return(it, styp, str_fn_name) }
table.SumType {}
else { verror("could not generate string method $str_fn_name for type \'$styp\'") } else { verror("could not generate string method $str_fn_name for type \'$styp\'") }
} }
} }

View File

@ -10,11 +10,13 @@ import v.errors
import v.pref import v.pref
import term import term
import strings import strings
import v.table
pub struct Gen { pub struct Gen {
out_name string out_name string
pref &pref.Preferences // Preferences shared from V struct pref &pref.Preferences // Preferences shared from V struct
mut: mut:
table &table.Table
buf []byte buf []byte
sect_header_name_pos int sect_header_name_pos int
offset i64 offset i64
@ -78,8 +80,9 @@ enum Size {
_64 _64
} }
pub fn gen(files []ast.File, out_name string, pref &pref.Preferences) { pub fn gen(files []ast.File, table &table.Table, out_name string, pref &pref.Preferences) {
mut g := Gen{ mut g := Gen{
table: table
sect_header_name_pos: 0 sect_header_name_pos: 0
out_name: out_name out_name: out_name
pref: pref pref: pref
@ -725,11 +728,22 @@ fn (mut g Gen) assign_stmt(node ast.AssignStmt) {
g.allocate_var(name, 4, 0) g.allocate_var(name, 4, 0)
// `mov DWORD PTR [rbp-0x8],eax` // `mov DWORD PTR [rbp-0x8],eax`
offset := g.get_var_offset(name) offset := g.get_var_offset(name)
println('ASS $name offset=$offset.hex2()') println('infix assignment $name offset=$offset.hex2()')
g.mov_reg_to_rbp(offset, .eax) g.mov_reg_to_rbp(offset, .eax)
} }
ast.StructInit {
sym := g.table.get_type_symbol(right.typ)
// println(sym)
// println(typeof(sym.info))
info := sym.info as table.Struct
for field in info.fields {
field_name := name + '.' + field.name
println(field_name)
g.allocate_var(field_name, 4, 0)
}
}
else { else {
g.error_with_pos('assign_stmt unhandled expr: ' + typeof(right), right.position()) g.error_with_pos('x64 assign_stmt unhandled expr: ' + typeof(right), right.position())
} }
} }
// } // }

View File

@ -152,7 +152,9 @@ fn (mut p Parser) match_expr() ast.MatchExpr {
p.next() p.next()
var_name = p.check_name() var_name = p.check_name()
} }
if p.tok.kind == .lcbr {
p.check(.lcbr) p.check(.lcbr)
}
mut branches := []ast.MatchBranch{} mut branches := []ast.MatchBranch{}
for { for {
branch_first_pos := p.tok.position() branch_first_pos := p.tok.position()
@ -164,8 +166,8 @@ fn (mut p Parser) match_expr() ast.MatchExpr {
if p.tok.kind == .key_else { if p.tok.kind == .key_else {
is_else = true is_else = true
p.next() p.next()
} else if p.tok.kind == .name && !(p.tok.lit == 'C' && p.peek_tok.kind == .dot) && } else if p.tok.kind == .name && !(p.tok.lit == 'C' &&
(p.tok.lit in table.builtin_type_names || p.tok.lit[0].is_capital() || p.peek_tok.kind == .dot) && (p.tok.lit in table.builtin_type_names || p.tok.lit[0].is_capital() ||
(p.peek_tok.kind == .dot && p.peek_tok2.lit[0].is_capital())) { (p.peek_tok.kind == .dot && p.peek_tok2.lit[0].is_capital())) {
if var_name.len == 0 { if var_name.len == 0 {
match cond { match cond {
@ -256,7 +258,7 @@ fn (mut p Parser) match_expr() ast.MatchExpr {
post_comments: post_comments post_comments: post_comments
} }
p.close_scope() p.close_scope()
if p.tok.kind == .rcbr { if p.tok.kind == .rcbr || is_else {
break break
} }
} }
@ -266,7 +268,9 @@ fn (mut p Parser) match_expr() ast.MatchExpr {
pos: match_first_pos.pos pos: match_first_pos.pos
len: match_last_pos.pos - match_first_pos.pos + match_last_pos.len len: match_last_pos.pos - match_first_pos.pos + match_last_pos.len
} }
if p.tok.kind == .rcbr {
p.check(.rcbr) p.check(.rcbr)
}
// return ast.StructInit{} // return ast.StructInit{}
return ast.MatchExpr{ return ast.MatchExpr{
branches: branches branches: branches

View File

@ -11,7 +11,7 @@ pub fn (c Color) str() string {
fn test_match_integers() { fn test_match_integers() {
mut a := 3 mut a := 3
mut b := 0 mut b := 0
match a { match a
2 { 2 {
println('two') println('two')
} }
@ -25,7 +25,6 @@ fn test_match_integers() {
else { else {
println('???') println('???')
} }
}
assert b == 3 assert b == 3
assert match 2 { assert match 2 {
1 { 2 } 1 { 2 }