From 746655c1d541487724288d83059291143ecb0fbb Mon Sep 17 00:00:00 2001 From: joe-conigliaro Date: Wed, 25 Sep 2019 21:53:44 +1000 Subject: [PATCH] compiler: re assignable blank identifier `_` & no longer a variable --- compiler/gen_c.v | 28 ++++++++++++++++++++++++++++ compiler/gen_js.v | 9 +++++++++ compiler/parser.v | 29 +++++++++++++++++++++-------- 3 files changed, 58 insertions(+), 8 deletions(-) diff --git a/compiler/gen_c.v b/compiler/gen_c.v index 0a97577912..7b054e0809 100644 --- a/compiler/gen_c.v +++ b/compiler/gen_c.v @@ -68,6 +68,34 @@ fn (p mut Parser) gen_fn_decl(f Fn, typ, str_args string) { p.genln('$dll_export_linkage$typ $fn_name_cgen($str_args) {') } +// blank identifer assignment `_ = 111` +fn (p mut Parser) gen_blank_identifier_assign() { + p.next() + p.check(.assign) + pos := p.cgen.add_placeholder() + mut typ := p.bool_expression() + tmp := p.get_tmp() + // handle or + if p.tok == .key_orelse { + p.cgen.set_placeholder(pos, '$typ $tmp = ') + p.genln(';') + 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.genln('string err = $tmp . error;') + p.statements() + p.returns = false + } + p.gen(';') +} + fn types_to_c(types []Type, table &Table) string { mut sb := strings.new_builder(10) for t in types { diff --git a/compiler/gen_js.v b/compiler/gen_js.v index 7b42f6945c..a3bf9235ef 100644 --- a/compiler/gen_js.v +++ b/compiler/gen_js.v @@ -33,6 +33,15 @@ fn (p mut Parser) gen_fn_decl(f Fn, typ, _str_args string) { } } +fn (p mut Parser) gen_blank_identifier_assign() { + typ := p.bool_expression() + or_else := p.tok == .key_orelse + //tmp := p.get_tmp() + if or_else { + //panic('optionals todo') + } +} + fn types_to_c(types []Type, table &Table) string { mut sb := strings.new_builder(10) for t in types { diff --git a/compiler/parser.v b/compiler/parser.v index 4782ee22f2..49da5664e8 100644 --- a/compiler/parser.v +++ b/compiler/parser.v @@ -1196,6 +1196,10 @@ fn (p mut Parser) statement(add_semi bool) string { //p.log('var decl') p.var_decl() } + // `_ = 777` + else if p.lit == '_' && p.peek() == .assign { + p.gen_blank_identifier_assign() + } else { // panic and exit count as returns since they stop the function if p.lit == 'panic' || p.lit == 'exit' { @@ -1373,15 +1377,13 @@ fn (p mut Parser) var_decl() { types = t.replace('_V_MulRet_', '').replace('_PTR_', '*').split('_V_') } for i, name in names { - typ := types[i] - if names.len > 1 { - if names.len != types.len { - mr_fn := p.cgen.cur_line.find_between('=', '(').trim_space() - p.error('assignment mismatch: ${names.len} variables but `$mr_fn` returns $types.len values.') - } - p.gen(';\n') - p.gen('$typ $name = ${mr_var_name}.var_$i') + if name == '_' { + // if names.len == 1 { + // p.error('no new variables on left side of :=') + // } + continue } + typ := types[i] // println('var decl tok=${p.strtok()} ismut=$is_mut') var_scanner_pos := p.scanner.get_scanner_pos() // name := p.check_name() @@ -1395,6 +1397,14 @@ fn (p mut Parser) var_decl() { if name.len > 1 && contains_capital(name) { p.error('variable names cannot contain uppercase letters, use snake_case instead') } + if names.len > 1 { + if names.len != types.len { + mr_fn := p.cgen.cur_line.find_between('=', '(').trim_space() + p.error('assignment mismatch: ${names.len} variables but `$mr_fn` returns $types.len values.') + } + p.gen(';\n') + p.gen('$typ $name = ${mr_var_name}.var_$i') + } // p.check_space(.decl_assign) // := // typ := p.gen_var_decl(name, is_static) p.register_var(Var { @@ -1588,6 +1598,9 @@ fn (p mut Parser) name_expr() string { } // Variable for { // TODO remove + if name == '_' { + p.error('cannot use `_` as value.') + } mut v := p.find_var_check_new_var(name) or { break } if ptr { p.gen('& /*v*/ ')