cgen: enum default values

pull/4170/head
Alexander Medvednikov 2020-03-31 19:43:11 +02:00
parent 43f72246aa
commit 2fe0e80569
4 changed files with 53 additions and 39 deletions

View File

@ -10,15 +10,15 @@ import (
pub type TypeDecl = AliasTypeDecl | SumTypeDecl | FnTypeDecl pub type TypeDecl = AliasTypeDecl | SumTypeDecl | FnTypeDecl
pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral | pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral |
FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr |
PostfixExpr | AssignExpr | PrefixExpr | IndexExpr | RangeExpr | MatchExpr | CastExpr | PostfixExpr | AssignExpr | PrefixExpr | IndexExpr | RangeExpr | MatchExpr | CastExpr |
EnumVal | Assoc | SizeOf | None | MapInit | IfGuardExpr | ParExpr | OrExpr | ConcatExpr | EnumVal | Assoc | SizeOf | None | MapInit | IfGuardExpr | ParExpr | OrExpr | ConcatExpr |
Type | AsCast | TypeOf | StringInterLiteral Type | AsCast | TypeOf | StringInterLiteral
pub type Stmt = GlobalDecl | FnDecl | Return | Module | Import | ExprStmt | pub type Stmt = GlobalDecl | FnDecl | Return | Module | Import | ExprStmt |
ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt | ForStmt | StructDecl | ForCStmt | ForInStmt | CompIf | ConstDecl | Attr | BranchStmt |
HashStmt | AssignStmt | EnumDecl | TypeDecl | DeferStmt | GotoLabel | GotoStmt | HashStmt | AssignStmt | EnumDecl | TypeDecl | DeferStmt | GotoLabel | GotoStmt |
LineComment | MultiLineComment | AssertStmt | UnsafeStmt | GoStmt | Block LineComment | MultiLineComment | AssertStmt | UnsafeStmt | GoStmt | Block
// pub type Type = StructType | ArrayType // pub type Type = StructType | ArrayType
// pub struct StructType { // pub struct StructType {
@ -474,9 +474,10 @@ mut:
pub struct EnumDecl { pub struct EnumDecl {
pub: pub:
name string name string
is_pub bool is_pub bool
vals []string vals []string
default_exprs []Expr
} }
pub struct AliasTypeDecl { pub struct AliasTypeDecl {
@ -627,7 +628,7 @@ pub:
pub struct TypeOf { pub struct TypeOf {
pub: pub:
expr Expr expr Expr
mut: mut:
expr_type table.Type expr_type table.Type
} }

View File

@ -322,16 +322,22 @@ fn (g mut Gen) stmt(node ast.Stmt) {
g.defer_stmts << defer_stmt g.defer_stmts << defer_stmt
} }
ast.EnumDecl { ast.EnumDecl {
g.writeln('//')
/*
name := it.name.replace('.', '__') name := it.name.replace('.', '__')
g.definitions.writeln('typedef enum {') g.definitions.writeln('typedef enum {')
for i, val in it.vals { for j, val in it.vals {
g.definitions.writeln('\t${name}_$val, // $i') 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 { ast.ExprStmt {
g.expr(it.expr) 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.SumType { TODO
table.Alias {} 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 { table.SumType {
g.definitions.writeln('// Sum type') g.definitions.writeln('// Sum type')
g.definitions.writeln(' 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"); }') g.definitions.writeln('string ${styp}_str($styp* x) { return tos3("TODO_str"); }')
} }
if g.autofree && !table.type_is_optional(typ) { if g.autofree && !table.type_is_optional(typ) {
// Create a temporary variable so that the value can be freed
tmp := g.new_tmp_var() tmp := g.new_tmp_var()
// tmps << tmp // tmps << tmp
g.write('string $tmp = ${styp}_str(') g.write('string $tmp = ${styp}_str(')
g.expr(node.args[0].expr) g.expr(node.args[0].expr)
g.writeln('); println($tmp); string_free($tmp); //MEM2 $styp') 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 { else {
// `println(int_str(10))` // `println(int_str(10))`
// sym := g.table.get_type_symbol(node.args[0].typ) // sym := g.table.get_type_symbol(node.args[0].typ)

View File

@ -52,7 +52,7 @@ pub fn parse_stmt(text string, table &table.Table, scope &ast.Scope) ast.Stmt {
pref: &pref.Preferences{} pref: &pref.Preferences{}
scope: scope scope: scope
// scope: &ast.Scope{start_pos: 0, parent: 0} // scope: &ast.Scope{start_pos: 0, parent: 0}
} }
p.init_parse_fns() p.init_parse_fns()
p.read_first_token() p.read_first_token()
@ -71,13 +71,13 @@ pub fn parse_file(path string, table &table.Table, comments_mode scanner.Comment
table: table table: table
file_name: path file_name: path
pref: pref // &pref.Preferences{} pref: pref // &pref.Preferences{}
scope: &ast.Scope{ scope: &ast.Scope{
start_pos: 0 start_pos: 0
parent: 0 parent: 0
} }
// comments_mode: comments_mode // comments_mode: comments_mode
} }
p.read_first_token() p.read_first_token()
// p.scope = &ast.Scope{start_pos: p.tok.position(), parent: 0} // 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 = '' p.expr_mod = ''
return ast.EnumVal{ return ast.EnumVal{
enum_name: enum_name // lp.prepend_mod(enum_name) enum_name: enum_name // lp.prepend_mod(enum_name)
val: val val: val
pos: p.tok.position() pos: p.tok.position()
mod: mod mod: mod
@ -778,7 +778,7 @@ pub fn (p mut Parser) expr(precedence int) ast.Expr {
node = ast.SizeOf{ node = ast.SizeOf{
typ: sizeof_type typ: sizeof_type
// type_name: type_name // type_name: type_name
} }
} }
.key_typeof { .key_typeof {
@ -1049,7 +1049,7 @@ fn (p mut Parser) infix_expr(left ast.Expr) ast.Expr {
left: left left: left
right: right right: right
// right_type: typ // right_type: typ
op: op op: op
pos: pos pos: pos
} }
@ -1454,7 +1454,7 @@ fn (p mut Parser) const_decl() ast.ConstDecl {
fields << ast.Field{ fields << ast.Field{
name: name name: name
// typ: typ // typ: typ
} }
exprs << expr exprs << expr
// TODO: once consts are fixed reg here & update in checker // 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()) name := p.prepend_mod(p.check_name())
p.check(.lcbr) p.check(.lcbr)
mut vals := []string mut vals := []string
mut default_exprs := []ast.Expr
for p.tok.kind != .eof && p.tok.kind != .rcbr { for p.tok.kind != .eof && p.tok.kind != .rcbr {
val := p.check_name() val := p.check_name()
vals << val vals << val
// p.warn('enum val $val') // p.warn('enum val $val')
if p.tok.kind == .assign { if p.tok.kind == .assign {
p.next() p.next()
p.expr(0) default_exprs << p.expr(0)
} }
} }
p.check(.rcbr) p.check(.rcbr)
@ -1835,6 +1836,7 @@ fn (p mut Parser) enum_decl() ast.EnumDecl {
name: name name: name
is_pub: is_pub is_pub: is_pub
vals: vals vals: vals
default_exprs: default_exprs
} }
} }

View File

@ -23,11 +23,9 @@ fn test_enum() {
assert Color.red == .red assert Color.red == .red
assert Color.blue == .blue assert Color.blue == .blue
assert Color.green == .green assert Color.green == .green
assert Color.red != .blue assert Color.red != .blue
assert Color.red != .green assert Color.red != .green
assert Color.blue != .green assert Color.blue != .green
mut color := Color.red mut color := Color.red
assert color == .red assert color == .red
color = .green color = .green
@ -47,9 +45,15 @@ fn test_match() {
color := Color.green color := Color.green
num := 3 num := 3
match color { match color {
.red { assert false } .red {
.green { assert true } assert false
else { assert false } }
.green {
assert true
}
else {
assert false
}
} }
println(color) println(color)
assert num == 3 assert num == 3
@ -70,7 +74,7 @@ fn test_nums() {
assert d == -10 assert d == -10
} }
/*
enum Expr { enum Expr {
BoolExpr(bool) BoolExpr(bool)
IntExpr(int) IntExpr(int)
@ -98,6 +102,8 @@ fn test_typed_enum() {
} }
*/ */
} }
*/
/* /*
fn test_typed_enum() { fn test_typed_enum() {