From a9463a180d28e95508a1ce974e8e15825711cbb1 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Wed, 17 Jul 2019 01:43:59 +0200 Subject: [PATCH] new match statement --- compiler/parser.v | 23 ++++++++++++++++------- compiler/scanner.v | 4 ++++ compiler/tests/match_test.v | 11 +++++++++++ compiler/token.v | 5 ++++- 4 files changed, 35 insertions(+), 8 deletions(-) create mode 100644 compiler/tests/match_test.v diff --git a/compiler/parser.v b/compiler/parser.v index ea74aed482..b3647c2b00 100644 --- a/compiler/parser.v +++ b/compiler/parser.v @@ -946,7 +946,7 @@ fn (p mut Parser) statements_no_curly_end() string { mut i := 0 mut last_st_typ := '' for p.tok != .rcbr && p.tok != .eof && p.tok != .key_case && - p.tok != .key_default { + p.tok != .key_default && p.peek() != .arrow { // println(p.tok.str()) // p.print_tok() last_st_typ = p.statement(true) @@ -961,7 +961,7 @@ fn (p mut Parser) statements_no_curly_end() string { p.error('more than 50 000 statements in function `$p.cur_fn.name`') } } - if p.tok != .key_case && p.tok != .key_default { + if p.tok != .key_case && p.tok != .key_default && p.peek() != .arrow { // p.next() p.check(.rcbr) } @@ -1044,7 +1044,7 @@ fn (p mut Parser) statement(add_semi bool) string { p.if_st(false, 0) case Token.key_for: p.for_st() - case Token.key_switch: + case Token.key_switch, Token.key_match: p.switch_statement() case Token.key_mut, Token.key_static: p.var_decl() @@ -3031,14 +3031,18 @@ fn (p mut Parser) for_st() { } fn (p mut Parser) switch_statement() { - p.check(.key_switch) + if p.tok == .key_switch { + p.check(.key_switch) + } else { + p.check(.key_match) + } p.cgen.start_tmp() typ := p.bool_expression() expr := p.cgen.end_tmp() p.check(.lcbr) mut i := 0 - for p.tok == .key_case || p.tok == .key_default { - if p.tok == .key_default { + for p.tok == .key_case || p.tok == .key_default || p.peek() == .arrow || p.tok == .key_else { + if p.tok == .key_default || p.tok == .key_else { p.genln('else { // default:') p.check(.key_default) p.check(.colon) @@ -3071,7 +3075,12 @@ fn (p mut Parser) switch_statement() { p.check(.comma) got_comma = true } - p.check(.colon) + if p.tok == .colon { + p.check(.colon) + } + else { + p.check(.arrow) + } p.gen(')) {') p.genln('/* case */') p.statements() diff --git a/compiler/scanner.v b/compiler/scanner.v index 8426cd0cb5..1dd2b64bcd 100644 --- a/compiler/scanner.v +++ b/compiler/scanner.v @@ -430,6 +430,10 @@ fn (s mut Scanner) scan() ScanRes { s.pos++ return scan_res(.eq, '') } + else if nextc == `>` { + s.pos++ + return scan_res(.arrow, '') + } else { return scan_res(.assign, '') } diff --git a/compiler/tests/match_test.v b/compiler/tests/match_test.v new file mode 100644 index 0000000000..d873f587f9 --- /dev/null +++ b/compiler/tests/match_test.v @@ -0,0 +1,11 @@ +fn test_switch() { + a := 3 + mut b := 0 + match a { + 2 => println('two') + 3 => println('three') + b = 3 + 4 => println('4') + } + assert b == 3 +} diff --git a/compiler/token.v b/compiler/token.v index 309540f806..f68b409af0 100644 --- a/compiler/token.v +++ b/compiler/token.v @@ -27,6 +27,7 @@ enum Token { comma semicolon colon + arrow // => amp hash dollar @@ -90,7 +91,7 @@ enum Token { key_import_const key_in key_interface - MATCH + key_match key_module key_mut key_return @@ -148,6 +149,7 @@ fn build_token_str() []string { s[Token.comma] = ',' s[Token.semicolon] = ';' s[Token.colon] = ':' + s[Token.arrow] = '=>' s[Token.assign] = '=' s[Token.decl_assign] = ':=' s[Token.plus_assign] = '+=' @@ -215,6 +217,7 @@ fn build_token_str() []string { s[Token.key_static] = 'static' s[Token.key_as] = 'as' s[Token.key_defer] = 'defer' + s[Token.key_match] = 'match' return s }