cgen: enum str()
parent
1388532bd4
commit
6bba7d4e3a
|
@ -17,7 +17,7 @@ indent_size = 2
|
|||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.txt]
|
||||
[*.{txt,out}]
|
||||
insert_final_newline = false
|
||||
|
||||
[Makefile]
|
||||
|
|
|
@ -1210,10 +1210,10 @@ fn (g mut Gen) typeof_expr(node ast.TypeOf) {
|
|||
fn (g mut Gen) enum_expr(node ast.Expr) {
|
||||
match node {
|
||||
ast.EnumVal {
|
||||
g.write('$it.val.capitalize()')
|
||||
g.write(it.val)
|
||||
}
|
||||
else {
|
||||
println(term.red('cgen.enum_expr(): bad node ' + typeof(node)))
|
||||
g.expr(node)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2260,6 +2260,7 @@ fn (g mut Gen) string_inter_literal(node ast.StringInterLiteral) {
|
|||
// }
|
||||
// else {}
|
||||
// }
|
||||
sym := g.table.get_type_symbol(node.expr_types[i])
|
||||
sfmt := node.expr_fmts[i]
|
||||
if sfmt.len > 0 {
|
||||
fspec := sfmt[sfmt.len - 1]
|
||||
|
@ -2267,10 +2268,13 @@ fn (g mut Gen) string_inter_literal(node ast.StringInterLiteral) {
|
|||
verror('only V strings can be formatted with a ${sfmt} format')
|
||||
}
|
||||
g.write('%' + sfmt[1..])
|
||||
} else if node.expr_types[i] == table.string_type || node.expr_types[i] == table.bool_type {
|
||||
} else if node.expr_types[i] in [table.string_type, table.bool_type] || sym.kind == .enum_ {
|
||||
g.write('%.*s')
|
||||
} else {
|
||||
g.write('%d')
|
||||
match node.exprs[i] {
|
||||
ast.EnumVal { g.write('%.*s') }
|
||||
else { g.write('%d') }
|
||||
}
|
||||
}
|
||||
}
|
||||
g.write('", ')
|
||||
|
@ -2296,9 +2300,41 @@ fn (g mut Gen) string_inter_literal(node ast.StringInterLiteral) {
|
|||
g.write(' ? 4 : 5, ')
|
||||
g.expr(expr)
|
||||
g.write(' ? "true" : "false"')
|
||||
} else {
|
||||
sym := g.table.get_type_symbol(node.expr_types[i])
|
||||
if sym.kind == .enum_ {
|
||||
is_var := match node.exprs[i] {
|
||||
ast.SelectorExpr { true }
|
||||
ast.Ident { true }
|
||||
else { false }
|
||||
}
|
||||
if is_var {
|
||||
styp := g.typ(node.expr_types[i])
|
||||
if !sym.has_method('str') && !(styp in g.str_types) {
|
||||
// Generate an automatic str() method if this type doesn't have it already
|
||||
g.str_types << styp
|
||||
g.gen_str_for_type(sym, styp)
|
||||
}
|
||||
g.write('${styp}_str(')
|
||||
g.enum_expr(expr)
|
||||
g.write(')')
|
||||
g.write('.len, ')
|
||||
g.write('${styp}_str(')
|
||||
g.enum_expr(expr)
|
||||
g.write(').str')
|
||||
} else {
|
||||
g.write('tos3("')
|
||||
g.enum_expr(expr)
|
||||
g.write('")')
|
||||
g.write('.len, ')
|
||||
g.write('"')
|
||||
g.enum_expr(expr)
|
||||
g.write('"')
|
||||
}
|
||||
} else {
|
||||
g.expr(expr)
|
||||
}
|
||||
}
|
||||
if i < node.exprs.len - 1 {
|
||||
g.write(', ')
|
||||
}
|
||||
|
@ -2466,9 +2502,15 @@ fn (g mut Gen) fn_call(node ast.CallExpr) {
|
|||
g.expr(node.args[0].expr)
|
||||
g.writeln('); ${print_method}($tmp); string_free($tmp); //MEM2 $styp')
|
||||
} else if sym.kind == .enum_ {
|
||||
g.write('${print_method}(tos3("')
|
||||
g.enum_expr(node.args[0].expr)
|
||||
g.write('"))')
|
||||
expr := node.args[0].expr
|
||||
is_var := match expr {
|
||||
ast.SelectorExpr { true }
|
||||
ast.Ident { true }
|
||||
else { false }
|
||||
}
|
||||
g.write(if is_var { '${print_method}(${styp}_str(' } else { '${print_method}(tos3("' })
|
||||
g.enum_expr(expr)
|
||||
g.write(if is_var { '))' } else { '"))' })
|
||||
} else {
|
||||
// `println(int_str(10))`
|
||||
// sym := g.table.get_type_symbol(node.args[0].typ)
|
||||
|
@ -2962,15 +3004,32 @@ fn (g mut Gen) go_stmt(node ast.GoStmt) {
|
|||
|
||||
// already generated styp, reuse it
|
||||
fn (g mut Gen) gen_str_for_type(sym table.TypeSymbol, styp string) {
|
||||
s := styp.replace('.', '__')
|
||||
match sym.info {
|
||||
table.Struct {}
|
||||
table.Struct {
|
||||
g.gen_str_for_struct(it, styp)
|
||||
}
|
||||
table.Enum {
|
||||
g.gen_str_for_enum(it, styp)
|
||||
}
|
||||
else {
|
||||
println('str() not a struct $sym.name')
|
||||
return
|
||||
println('cannot generate str() for $sym.name')
|
||||
}
|
||||
}
|
||||
info := sym.info as table.Struct
|
||||
}
|
||||
|
||||
fn (g mut Gen) gen_str_for_enum(info table.Enum, styp string) {
|
||||
s := styp.replace('.', '__')
|
||||
g.definitions.write('string ${s}_str($styp a) {\n\tswitch(a) {\n')
|
||||
for i, expr in info.default_exprs {
|
||||
val := info.vals[i]
|
||||
int_expr := expr as ast.IntegerLiteral
|
||||
g.definitions.write('\t\tcase $int_expr.val: return tos3("$val");\n')
|
||||
}
|
||||
g.definitions.write('\t\tdefault: return tos3("unknown enum value"); } }\n')
|
||||
}
|
||||
|
||||
fn (g mut Gen) gen_str_for_struct(info table.Struct, styp string) {
|
||||
s := styp.replace('.', '__')
|
||||
g.definitions.write('string ${s}_str($styp a) { return _STR("$styp {\\n')
|
||||
for field in info.fields {
|
||||
fmt := type_to_fmt(field.typ)
|
||||
|
|
|
@ -1873,6 +1873,7 @@ fn (p mut Parser) enum_decl() ast.EnumDecl {
|
|||
name: name
|
||||
info: table.Enum{
|
||||
vals: vals
|
||||
default_exprs: default_exprs
|
||||
}
|
||||
})
|
||||
return ast.EnumDecl{
|
||||
|
|
|
@ -14,6 +14,7 @@ module table
|
|||
|
||||
import (
|
||||
strings
|
||||
v.ast
|
||||
)
|
||||
|
||||
pub type Type int
|
||||
|
@ -546,6 +547,7 @@ pub mut:
|
|||
pub struct Enum {
|
||||
pub mut:
|
||||
vals []string
|
||||
default_exprs []ast.Expr
|
||||
}
|
||||
|
||||
pub struct Alias {
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
yellow
|
||||
green
|
||||
green
|
||||
interp: green
|
||||
interp: green
|
|
@ -0,0 +1,21 @@
|
|||
module main
|
||||
|
||||
enum Color {
|
||||
green = 5
|
||||
red = 2
|
||||
yellow = 1
|
||||
}
|
||||
|
||||
struct A{
|
||||
color Color
|
||||
}
|
||||
|
||||
fn main() {
|
||||
col := Color.green
|
||||
a := A{color: col}
|
||||
println(Color.yellow)
|
||||
println(col)
|
||||
println(a.color)
|
||||
println('interp: ${col}')
|
||||
println('interp: ${a.color}')
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
module main
|
||||
|
||||
enum Color {
|
||||
green = 5
|
||||
red = 2
|
||||
yellow = 1
|
||||
}
|
||||
|
||||
struct A{
|
||||
color Color
|
||||
}
|
||||
|
||||
fn main() {
|
||||
col := Color.green
|
||||
a := A{color: col}
|
||||
println(Color.yellow)
|
||||
println(col)
|
||||
println(a.color)
|
||||
println('interp: ${col}')
|
||||
println('interp: ${a.color}')
|
||||
}
|
Loading…
Reference in New Issue