checker: check enum
parent
6ac64c8586
commit
320fad49c5
|
@ -494,12 +494,19 @@ mut:
|
||||||
typ table.Type
|
typ table.Type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct EnumField {
|
||||||
|
name string
|
||||||
|
pos token.Position
|
||||||
|
exprs []Expr
|
||||||
|
}
|
||||||
|
|
||||||
pub struct EnumDecl {
|
pub struct EnumDecl {
|
||||||
pub:
|
pub:
|
||||||
name string
|
name string
|
||||||
is_pub bool
|
is_pub bool
|
||||||
vals []string
|
fields []EnumField
|
||||||
default_exprs []Expr
|
// vals []string
|
||||||
|
// default_exprs []Expr
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AliasTypeDecl {
|
pub struct AliasTypeDecl {
|
||||||
|
|
|
@ -560,6 +560,20 @@ pub fn (c mut Checker) return_stmt(return_stmt mut ast.Return) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (c mut Checker) enum_decl(decl ast.EnumDecl) {
|
||||||
|
for field in decl.fields {
|
||||||
|
for expr in field.exprs {
|
||||||
|
match expr {
|
||||||
|
ast.IntegerLiteral {}
|
||||||
|
ast.PrefixExpr {}
|
||||||
|
else {
|
||||||
|
c.error("default value for enum has to be an integer", field.pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn (c mut Checker) assign_stmt(assign_stmt mut ast.AssignStmt) {
|
pub fn (c mut Checker) assign_stmt(assign_stmt mut 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`
|
||||||
if assign_stmt.left.len > assign_stmt.right.len {
|
if assign_stmt.left.len > assign_stmt.right.len {
|
||||||
|
@ -737,9 +751,6 @@ fn (c mut Checker) stmt(node ast.Stmt) {
|
||||||
c.stmts(it.else_stmts)
|
c.stmts(it.else_stmts)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast.DeferStmt {
|
|
||||||
c.stmts(it.stmts)
|
|
||||||
}
|
|
||||||
ast.ConstDecl {
|
ast.ConstDecl {
|
||||||
mut field_names := []string
|
mut field_names := []string
|
||||||
mut field_order := []int
|
mut field_order := []int
|
||||||
|
@ -776,6 +787,12 @@ fn (c mut Checker) stmt(node ast.Stmt) {
|
||||||
it.fields = ordered_fields
|
it.fields = ordered_fields
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ast.DeferStmt {
|
||||||
|
c.stmts(it.stmts)
|
||||||
|
}
|
||||||
|
ast.EnumDecl {
|
||||||
|
c.enum_decl(it)
|
||||||
|
}
|
||||||
ast.ExprStmt {
|
ast.ExprStmt {
|
||||||
etype := c.expr(it.expr)
|
etype := c.expr(it.expr)
|
||||||
c.expected_type = table.void_type
|
c.expected_type = table.void_type
|
||||||
|
|
|
@ -208,8 +208,17 @@ fn (f mut Fmt) stmt(node ast.Stmt) {
|
||||||
}
|
}
|
||||||
name := it.name.after('.')
|
name := it.name.after('.')
|
||||||
f.writeln('enum $name {')
|
f.writeln('enum $name {')
|
||||||
for val in it.vals {
|
for field in it.fields {
|
||||||
f.writeln('\t' + val)
|
f.write('\t$field.name')
|
||||||
|
if field.exprs.len > 0 {
|
||||||
|
f.write(' = ')
|
||||||
|
for expr in field.exprs {
|
||||||
|
f.expr(expr)
|
||||||
|
}
|
||||||
|
f.writeln(',')
|
||||||
|
} else {
|
||||||
|
f.writeln('')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
f.writeln('}\n')
|
f.writeln('}\n')
|
||||||
}
|
}
|
||||||
|
|
|
@ -363,21 +363,23 @@ fn (g mut Gen) stmt(node ast.Stmt) {
|
||||||
g.defer_stmts << defer_stmt
|
g.defer_stmts << defer_stmt
|
||||||
}
|
}
|
||||||
ast.EnumDecl {
|
ast.EnumDecl {
|
||||||
name := it.name.replace('.', '__')
|
enum_name := it.name.replace('.', '__')
|
||||||
g.typedefs.writeln('typedef enum {')
|
g.typedefs.writeln('typedef enum {')
|
||||||
for j, val in it.vals {
|
for field in it.fields {
|
||||||
if j < it.default_exprs.len {
|
g.typedefs.write('\t${enum_name}_$field.name')
|
||||||
g.typedefs.write('\t${name}_$val = ')
|
if field.exprs.len > 0 {
|
||||||
pos := g.out.len
|
g.typedefs.write(' = ')
|
||||||
g.expr(it.default_exprs[j])
|
|
||||||
expr := g.out.after(pos)
|
|
||||||
g.out.go_back(expr.len)
|
|
||||||
g.typedefs.writeln('$expr,')
|
|
||||||
} else {
|
|
||||||
g.typedefs.writeln('\t${name}_$val, // $j')
|
|
||||||
}
|
}
|
||||||
|
for expr in field.exprs {
|
||||||
|
pos := g.out.len
|
||||||
|
g.expr(expr)
|
||||||
|
expr_str := g.out.after(pos)
|
||||||
|
g.out.go_back(expr_str.len)
|
||||||
|
g.typedefs.write('$expr_str')
|
||||||
|
}
|
||||||
|
g.typedefs.writeln(',')
|
||||||
}
|
}
|
||||||
g.typedefs.writeln('} $name;\n')
|
g.typedefs.writeln('} $enum_name;\n')
|
||||||
}
|
}
|
||||||
ast.ExprStmt {
|
ast.ExprStmt {
|
||||||
g.expr(it.expr)
|
g.expr(it.expr)
|
||||||
|
|
|
@ -1848,15 +1848,19 @@ 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
|
// mut default_exprs := []ast.Expr
|
||||||
|
mut fields := []ast.EnumField
|
||||||
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()
|
||||||
|
pos := p.tok.position()
|
||||||
vals << val
|
vals << val
|
||||||
|
mut exprs := []ast.Expr
|
||||||
// p.warn('enum val $val')
|
// p.warn('enum val $val')
|
||||||
if p.tok.kind == .assign {
|
if p.tok.kind == .assign {
|
||||||
p.next()
|
p.next()
|
||||||
default_exprs << p.expr(0)
|
exprs << p.expr(0)
|
||||||
}
|
}
|
||||||
|
fields << ast.EnumField{val, pos, exprs}
|
||||||
// Allow commas after enum, helpful for
|
// Allow commas after enum, helpful for
|
||||||
// enum Color {
|
// enum Color {
|
||||||
// r,g,b
|
// r,g,b
|
||||||
|
@ -1876,8 +1880,9 @@ fn (p mut Parser) enum_decl() ast.EnumDecl {
|
||||||
return ast.EnumDecl{
|
return ast.EnumDecl{
|
||||||
name: name
|
name: name
|
||||||
is_pub: is_pub
|
is_pub: is_pub
|
||||||
vals: vals
|
// vals: vals
|
||||||
default_exprs: default_exprs
|
// default_exprs: default_exprs
|
||||||
|
fields: fields
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue