cgen: enum str()
parent
1388532bd4
commit
6bba7d4e3a
|
@ -17,7 +17,7 @@ indent_size = 2
|
||||||
[*.md]
|
[*.md]
|
||||||
trim_trailing_whitespace = false
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
[*.txt]
|
[*.{txt,out}]
|
||||||
insert_final_newline = false
|
insert_final_newline = false
|
||||||
|
|
||||||
[Makefile]
|
[Makefile]
|
||||||
|
|
|
@ -367,7 +367,7 @@ fn (g mut Gen) stmt(node ast.Stmt) {
|
||||||
g.expr(it.default_exprs[j])
|
g.expr(it.default_exprs[j])
|
||||||
expr := g.out.after(pos)
|
expr := g.out.after(pos)
|
||||||
g.out.go_back(expr.len)
|
g.out.go_back(expr.len)
|
||||||
g.typedefs.writeln('$expr ,')
|
g.typedefs.writeln('$expr,')
|
||||||
} else {
|
} else {
|
||||||
g.typedefs.writeln('\t${name}_$val, // $j')
|
g.typedefs.writeln('\t${name}_$val, // $j')
|
||||||
}
|
}
|
||||||
|
@ -1210,10 +1210,10 @@ fn (g mut Gen) typeof_expr(node ast.TypeOf) {
|
||||||
fn (g mut Gen) enum_expr(node ast.Expr) {
|
fn (g mut Gen) enum_expr(node ast.Expr) {
|
||||||
match node {
|
match node {
|
||||||
ast.EnumVal {
|
ast.EnumVal {
|
||||||
g.write('$it.val.capitalize()')
|
g.write(it.val)
|
||||||
}
|
}
|
||||||
else {
|
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 {}
|
// else {}
|
||||||
// }
|
// }
|
||||||
|
sym := g.table.get_type_symbol(node.expr_types[i])
|
||||||
sfmt := node.expr_fmts[i]
|
sfmt := node.expr_fmts[i]
|
||||||
if sfmt.len > 0 {
|
if sfmt.len > 0 {
|
||||||
fspec := sfmt[sfmt.len - 1]
|
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')
|
verror('only V strings can be formatted with a ${sfmt} format')
|
||||||
}
|
}
|
||||||
g.write('%' + sfmt[1..])
|
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')
|
g.write('%.*s')
|
||||||
} else {
|
} else {
|
||||||
g.write('%d')
|
match node.exprs[i] {
|
||||||
|
ast.EnumVal { g.write('%.*s') }
|
||||||
|
else { g.write('%d') }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g.write('", ')
|
g.write('", ')
|
||||||
|
@ -2297,7 +2301,39 @@ fn (g mut Gen) string_inter_literal(node ast.StringInterLiteral) {
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
g.write(' ? "true" : "false"')
|
g.write(' ? "true" : "false"')
|
||||||
} else {
|
} else {
|
||||||
g.expr(expr)
|
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 {
|
if i < node.exprs.len - 1 {
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
|
@ -2466,9 +2502,15 @@ fn (g mut Gen) fn_call(node ast.CallExpr) {
|
||||||
g.expr(node.args[0].expr)
|
g.expr(node.args[0].expr)
|
||||||
g.writeln('); ${print_method}($tmp); string_free($tmp); //MEM2 $styp')
|
g.writeln('); ${print_method}($tmp); string_free($tmp); //MEM2 $styp')
|
||||||
} else if sym.kind == .enum_ {
|
} else if sym.kind == .enum_ {
|
||||||
g.write('${print_method}(tos3("')
|
expr := node.args[0].expr
|
||||||
g.enum_expr(node.args[0].expr)
|
is_var := match expr {
|
||||||
g.write('"))')
|
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 {
|
} 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)
|
||||||
|
@ -2962,15 +3004,32 @@ fn (g mut Gen) go_stmt(node ast.GoStmt) {
|
||||||
|
|
||||||
// already generated styp, reuse it
|
// already generated styp, reuse it
|
||||||
fn (g mut Gen) gen_str_for_type(sym table.TypeSymbol, styp string) {
|
fn (g mut Gen) gen_str_for_type(sym table.TypeSymbol, styp string) {
|
||||||
s := styp.replace('.', '__')
|
|
||||||
match sym.info {
|
match sym.info {
|
||||||
table.Struct {}
|
table.Struct {
|
||||||
|
g.gen_str_for_struct(it, styp)
|
||||||
|
}
|
||||||
|
table.Enum {
|
||||||
|
g.gen_str_for_enum(it, styp)
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
println('str() not a struct $sym.name')
|
println('cannot generate str() for $sym.name')
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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')
|
g.definitions.write('string ${s}_str($styp a) { return _STR("$styp {\\n')
|
||||||
for field in info.fields {
|
for field in info.fields {
|
||||||
fmt := type_to_fmt(field.typ)
|
fmt := type_to_fmt(field.typ)
|
||||||
|
|
|
@ -1873,6 +1873,7 @@ fn (p mut Parser) enum_decl() ast.EnumDecl {
|
||||||
name: name
|
name: name
|
||||||
info: table.Enum{
|
info: table.Enum{
|
||||||
vals: vals
|
vals: vals
|
||||||
|
default_exprs: default_exprs
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return ast.EnumDecl{
|
return ast.EnumDecl{
|
||||||
|
|
|
@ -14,6 +14,7 @@ module table
|
||||||
|
|
||||||
import (
|
import (
|
||||||
strings
|
strings
|
||||||
|
v.ast
|
||||||
)
|
)
|
||||||
|
|
||||||
pub type Type int
|
pub type Type int
|
||||||
|
@ -546,6 +547,7 @@ pub mut:
|
||||||
pub struct Enum {
|
pub struct Enum {
|
||||||
pub mut:
|
pub mut:
|
||||||
vals []string
|
vals []string
|
||||||
|
default_exprs []ast.Expr
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Alias {
|
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}')
|
||||||
|
}
|
|
@ -1 +1 @@
|
||||||
hello world
|
hello world
|
|
@ -3,4 +3,4 @@ Hello, web developers!
|
||||||
Hello, tools developers!
|
Hello, tools developers!
|
||||||
Hello, science developers!
|
Hello, science developers!
|
||||||
Hello, systems developers!
|
Hello, systems developers!
|
||||||
Hello, embedded developers!
|
Hello, embedded developers!
|
|
@ -1,4 +1,4 @@
|
||||||
CHANGELOG.md
|
CHANGELOG.md
|
||||||
CODE_OF_CONDUCT.md
|
CODE_OF_CONDUCT.md
|
||||||
CONTRIBUTING.md
|
CONTRIBUTING.md
|
||||||
README.md
|
README.md
|
Loading…
Reference in New Issue