From 2fe0e805697133cd7878a1b955275070086c611e Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Tue, 31 Mar 2020 19:43:11 +0200 Subject: [PATCH] cgen: enum default values --- vlib/v/ast/ast.v | 23 ++++++++++++----------- vlib/v/gen/cgen.v | 33 +++++++++++++++++++-------------- vlib/v/parser/parser.v | 18 ++++++++++-------- vlib/v/tests/enum_test.v | 18 ++++++++++++------ 4 files changed, 53 insertions(+), 39 deletions(-) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 1e34575fba..5501dcc3d3 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -10,15 +10,15 @@ import ( pub type TypeDecl = AliasTypeDecl | SumTypeDecl | FnTypeDecl -pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral | -FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | -PostfixExpr | AssignExpr | PrefixExpr | IndexExpr | RangeExpr | MatchExpr | CastExpr | -EnumVal | Assoc | SizeOf | None | MapInit | IfGuardExpr | ParExpr | OrExpr | ConcatExpr | +pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral | +FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | +PostfixExpr | AssignExpr | PrefixExpr | IndexExpr | RangeExpr | MatchExpr | CastExpr | +EnumVal | Assoc | SizeOf | None | MapInit | IfGuardExpr | ParExpr | OrExpr | ConcatExpr | Type | AsCast | TypeOf | StringInterLiteral -pub type Stmt = GlobalDecl | FnDecl | Return | Module | Import | ExprStmt | -ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt | -HashStmt | AssignStmt | EnumDecl | TypeDecl | DeferStmt | GotoLabel | GotoStmt | +pub type Stmt = GlobalDecl | FnDecl | Return | Module | Import | ExprStmt | +ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt | +HashStmt | AssignStmt | EnumDecl | TypeDecl | DeferStmt | GotoLabel | GotoStmt | LineComment | MultiLineComment | AssertStmt | UnsafeStmt | GoStmt | Block // pub type Type = StructType | ArrayType // pub struct StructType { @@ -474,9 +474,10 @@ mut: pub struct EnumDecl { pub: - name string - is_pub bool - vals []string + name string + is_pub bool + vals []string + default_exprs []Expr } pub struct AliasTypeDecl { @@ -627,7 +628,7 @@ pub: pub struct TypeOf { pub: - expr Expr + expr Expr mut: expr_type table.Type } diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index af6dc0881c..a481d3ac1c 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -322,16 +322,22 @@ fn (g mut Gen) stmt(node ast.Stmt) { g.defer_stmts << defer_stmt } ast.EnumDecl { - g.writeln('//') - /* name := it.name.replace('.', '__') g.definitions.writeln('typedef enum {') - for i, val in it.vals { - g.definitions.writeln('\t${name}_$val, // $i') + for j, val in it.vals { + if j < it.default_exprs.len { + g.definitions.write('\t${name}_$val = ') + pos := g.out.len + g.expr(it.default_exprs[j]) + expr := g.out.after(pos) + g.out.go_back(expr.len) + g.definitions.writeln('$expr ,') + } + else { + g.definitions.writeln('\t${name}_$val, // $j') + } } - g.definitions.writeln('} $name;') - */ - + g.definitions.writeln('} $name;\n') } ast.ExprStmt { g.expr(it.expr) @@ -2070,13 +2076,6 @@ fn (g mut Gen) write_types(types []table.TypeSymbol) { } // table.Alias, table.SumType { TODO table.Alias {} - table.Enum { - g.definitions.writeln('typedef enum {') - for j, val in it.vals { - g.definitions.writeln('\t${name}_$val, // $j') - } - g.definitions.writeln('} $name;\n') - } table.SumType { g.definitions.writeln('// Sum type') g.definitions.writeln(' @@ -2359,12 +2358,18 @@ fn (g mut Gen) fn_call(node ast.CallExpr) { g.definitions.writeln('string ${styp}_str($styp* x) { return tos3("TODO_str"); }') } if g.autofree && !table.type_is_optional(typ) { + // Create a temporary variable so that the value can be freed tmp := g.new_tmp_var() // tmps << tmp g.write('string $tmp = ${styp}_str(') g.expr(node.args[0].expr) g.writeln('); println($tmp); string_free($tmp); //MEM2 $styp') } + else if sym.kind == .enum_ { + g.write('println(int_str(') + g.expr(node.args[0].expr) + g.write('))') + } else { // `println(int_str(10))` // sym := g.table.get_type_symbol(node.args[0].typ) diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index d854ade247..30a3d55fb3 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -52,7 +52,7 @@ pub fn parse_stmt(text string, table &table.Table, scope &ast.Scope) ast.Stmt { pref: &pref.Preferences{} scope: scope // scope: &ast.Scope{start_pos: 0, parent: 0} - + } p.init_parse_fns() p.read_first_token() @@ -71,13 +71,13 @@ pub fn parse_file(path string, table &table.Table, comments_mode scanner.Comment table: table file_name: path pref: pref // &pref.Preferences{} - + scope: &ast.Scope{ start_pos: 0 parent: 0 } // comments_mode: comments_mode - + } p.read_first_token() // p.scope = &ast.Scope{start_pos: p.tok.position(), parent: 0} @@ -688,7 +688,7 @@ pub fn (p mut Parser) name_expr() ast.Expr { p.expr_mod = '' return ast.EnumVal{ enum_name: enum_name // lp.prepend_mod(enum_name) - + val: val pos: p.tok.position() mod: mod @@ -778,7 +778,7 @@ pub fn (p mut Parser) expr(precedence int) ast.Expr { node = ast.SizeOf{ typ: sizeof_type // type_name: type_name - + } } .key_typeof { @@ -1049,7 +1049,7 @@ fn (p mut Parser) infix_expr(left ast.Expr) ast.Expr { left: left right: right // right_type: typ - + op: op pos: pos } @@ -1454,7 +1454,7 @@ fn (p mut Parser) const_decl() ast.ConstDecl { fields << ast.Field{ name: name // typ: typ - + } exprs << expr // TODO: once consts are fixed reg here & update in checker @@ -1814,13 +1814,14 @@ fn (p mut Parser) enum_decl() ast.EnumDecl { name := p.prepend_mod(p.check_name()) p.check(.lcbr) mut vals := []string + mut default_exprs := []ast.Expr for p.tok.kind != .eof && p.tok.kind != .rcbr { val := p.check_name() vals << val // p.warn('enum val $val') if p.tok.kind == .assign { p.next() - p.expr(0) + default_exprs << p.expr(0) } } p.check(.rcbr) @@ -1835,6 +1836,7 @@ fn (p mut Parser) enum_decl() ast.EnumDecl { name: name is_pub: is_pub vals: vals + default_exprs: default_exprs } } diff --git a/vlib/v/tests/enum_test.v b/vlib/v/tests/enum_test.v index 1decd66a8c..a28ea03e90 100644 --- a/vlib/v/tests/enum_test.v +++ b/vlib/v/tests/enum_test.v @@ -23,11 +23,9 @@ fn test_enum() { assert Color.red == .red assert Color.blue == .blue assert Color.green == .green - assert Color.red != .blue assert Color.red != .green assert Color.blue != .green - mut color := Color.red assert color == .red color = .green @@ -47,9 +45,15 @@ fn test_match() { color := Color.green num := 3 match color { - .red { assert false } - .green { assert true } - else { assert false } + .red { + assert false + } + .green { + assert true + } + else { + assert false + } } println(color) assert num == 3 @@ -70,7 +74,7 @@ fn test_nums() { assert d == -10 } - +/* enum Expr { BoolExpr(bool) IntExpr(int) @@ -98,6 +102,8 @@ fn test_typed_enum() { } */ } +*/ + /* fn test_typed_enum() {