vfmt: alias type and sum type + sum type fix

pull/3954/head
Delyan Angelov 2020-03-07 18:37:55 +02:00 committed by GitHub
parent fbf80dc315
commit 5e541e1f11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 125 additions and 32 deletions

View File

@ -901,6 +901,7 @@ fn (p mut Parser) type_decl() {
}) })
if p.pass == .main { if p.pass == .main {
p.cgen.consts << 'const char * __SumTypeNames__${name}[] = {' p.cgen.consts << 'const char * __SumTypeNames__${name}[] = {'
p.cgen.consts << ' "$name",'
for ctype_name in ctype_names { for ctype_name in ctype_names {
p.cgen.consts << ' "$ctype_name",' p.cgen.consts << ' "$ctype_name",'
} }

View File

@ -831,7 +831,9 @@ fn (p mut Parser) factor() string {
is_sum_type := type_of_var in p.table.sum_types is_sum_type := type_of_var in p.table.sum_types
if is_sum_type && vname.len > 0 { if is_sum_type && vname.len > 0 {
// TODO: make this work for arbitrary sumtype expressions, not just simple vars // TODO: make this work for arbitrary sumtype expressions, not just simple vars
p.gen('${vname}.typ == 0 ? tos3("typeof(): typ == 0") : tos3(__SumTypeNames__${type_of_var}[${vname}.typ - 1])') // NB: __SumTypeNames__[xxx][0] is the name of the sumtype itself;
// idx>0 are the names of the sumtype children
p.gen('tos3(__SumTypeNames__${type_of_var}[${vname}.typ])')
}else{ }else{
p.gen('tos3("$type_of_var")') p.gen('tos3("$type_of_var")')
} }

View File

@ -8,6 +8,8 @@ import (
v.table v.table
) )
pub type TypeDecl = AliasTypeDecl | SumTypeDecl
pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral | pub type Expr = InfixExpr | IfExpr | StringLiteral | IntegerLiteral | CharLiteral |
FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr | FloatLiteral | Ident | CallExpr | BoolLiteral | StructInit | ArrayInit | SelectorExpr | PostfixExpr |
AssignExpr | PrefixExpr | MethodCallExpr | IndexExpr | RangeExpr | MatchExpr | AssignExpr | PrefixExpr | MethodCallExpr | IndexExpr | RangeExpr | MatchExpr |
@ -439,10 +441,18 @@ pub:
vals []string vals []string
} }
pub struct TypeDecl { pub struct AliasTypeDecl {
pub: pub:
name string name string
is_pub bool is_pub bool
parent_type table.Type
}
pub struct SumTypeDecl {
pub:
name string
is_pub bool
sub_types []table.Type
} }
pub struct DeferStmt { pub struct DeferStmt {

View File

@ -127,7 +127,7 @@ fn (f mut Fmt) stmt(node ast.Stmt) {
f.writeln('continue') f.writeln('continue')
} }
else {} else {}
} }
} }
ast.ConstDecl { ast.ConstDecl {
if it.is_pub { if it.is_pub {
@ -245,13 +245,46 @@ fn (f mut Fmt) stmt(node ast.Stmt) {
f.expr(it.expr) f.expr(it.expr)
f.writeln('') f.writeln('')
} }
ast.Import {
// already handled in f.imports
}
ast.TypeDecl {
f.type_decl( it )
}
else { else {
println('unknown node') eprintln('fmt stmt: unknown node: ' + typeof(node))
// exit(1) // exit(1)
} }
} }
} }
fn (f mut Fmt) type_decl(node ast.TypeDecl) {
match node {
ast.AliasTypeDecl {
if it.is_pub {
f.write('pub ')
}
ptype := f.table.type_to_str( it.parent_type )
f.write('type $it.name $ptype')
}
ast.SumTypeDecl {
if it.is_pub {
f.write('pub ')
}
f.write('type $it.name = ')
mut sum_type_names := []string
for t in it.sub_types {
sum_type_names << f.table.type_to_str(t)
}
f.write( sum_type_names.join(' | ') )
}
else {
eprintln('fmt type_decl: unknown ' + typeof(node))
}
}
f.writeln('\n')
}
fn (f mut Fmt) struct_decl(node ast.StructDecl) { fn (f mut Fmt) struct_decl(node ast.StructDecl) {
if node.is_pub { if node.is_pub {
f.write('pub ') f.write('pub ')
@ -526,7 +559,7 @@ fn (f mut Fmt) expr(node ast.Expr) {
} }
} }
else { else {
println('fmt expr: unhandled node ') // + typeof(node)) eprintln('fmt expr: unhandled node ' + typeof(node))
} }
} }
} }

View File

@ -46,7 +46,7 @@ fn test_fmt() {
continue continue
} }
table := table.new_table() table := table.new_table()
file_ast := parser.parse_file(ipath, table, .skip_comments) file_ast := parser.parse_file(ipath, table, .parse_comments)
result_ocontent := fmt.fmt(file_ast, table) result_ocontent := fmt.fmt(file_ast, table)
if expected_ocontent != result_ocontent { if expected_ocontent != result_ocontent {
fmt_bench.fail() fmt_bench.fail()

View File

@ -0,0 +1,5 @@
import (
math as m
os
math.complex as c
)

View File

@ -0,0 +1,3 @@
import math as m
import os
import math.complex as c

View File

@ -129,6 +129,8 @@ struct Bar {
val int val int
} }
type FooBar = Foo | Bar
const ( const (
reserved_types = { reserved_types = {
'i8': true 'i8': true

View File

@ -0,0 +1,9 @@
// Sumtype
type FooBar = Foo | Bar
pub type PublicBar = Foo | Bar | FooBar
// Alias type
type MyInt int
pub type Abc f32

View File

@ -0,0 +1,10 @@
// Sumtype
type FooBar= Foo | Bar
pub type PublicBar = Foo | Bar | FooBar
// Alias type
type MyInt int
pub type Abc f32

View File

@ -1714,8 +1714,8 @@ fn (p mut Parser) type_decl() ast.TypeDecl {
p.check(.key_type) p.check(.key_type)
name := p.check_name() name := p.check_name()
mut sum_variants := []table.Type mut sum_variants := []table.Type
// type SumType = A | B | c
if p.tok.kind == .assign { if p.tok.kind == .assign {
// type SumType = A | B | c
p.next() p.next()
for { for {
variant_type := p.parse_type() variant_type := p.parse_type()
@ -1732,21 +1732,28 @@ fn (p mut Parser) type_decl() ast.TypeDecl {
variants: sum_variants variants: sum_variants
} }
}) })
return ast.SumTypeDecl{
name: name
is_pub: is_pub
sub_types: sum_variants
}
} }
// type MyType int // type MyType int
else { parent_type := p.parse_type()
parent_type := p.parse_type() pid := table.type_idx(parent_type)
p.table.register_type_symbol(table.TypeSymbol{ p.table.register_type_symbol(table.TypeSymbol{
kind: .alias kind: .alias
name: p.prepend_mod(name) name: p.prepend_mod(name)
parent_idx: table.type_idx(parent_type) parent_idx: pid
info: table.Alias{ info: table.Alias{
foo: '' foo: ''
} }
}) })
} return ast.AliasTypeDecl{
return ast.TypeDecl{
name: name name: name
is_pub: is_pub
parent_type: parent_type
} }
} }

View File

@ -344,8 +344,18 @@ pub fn (k Kind) str() string {
.multi_return{ .multi_return{
'multi_return' 'multi_return'
} }
.sum_type{
'sum_type'
}
.alias{
'alias'
}
.enum_{
'enum'
}
else { else {
'unknown'} 'unknown'
}
} }
return k_str return k_str
} }
@ -405,6 +415,7 @@ pub mut:
} }
pub struct SumType { pub struct SumType {
pub:
variants []Type variants []Type
} }