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 {
p.cgen.consts << 'const char * __SumTypeNames__${name}[] = {'
p.cgen.consts << ' "$name",'
for ctype_name in ctype_names {
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
if is_sum_type && vname.len > 0 {
// 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{
p.gen('tos3("$type_of_var")')
}

View File

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

View File

@ -245,13 +245,46 @@ fn (f mut Fmt) stmt(node ast.Stmt) {
f.expr(it.expr)
f.writeln('')
}
ast.Import {
// already handled in f.imports
}
ast.TypeDecl {
f.type_decl( it )
}
else {
println('unknown node')
eprintln('fmt stmt: unknown node: ' + typeof(node))
// 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) {
if node.is_pub {
f.write('pub ')
@ -526,7 +559,7 @@ fn (f mut Fmt) expr(node ast.Expr) {
}
}
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
}
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)
if expected_ocontent != result_ocontent {
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
}
type FooBar = Foo | Bar
const (
reserved_types = {
'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)
name := p.check_name()
mut sum_variants := []table.Type
// type SumType = A | B | c
if p.tok.kind == .assign {
// type SumType = A | B | c
p.next()
for {
variant_type := p.parse_type()
@ -1732,21 +1732,28 @@ fn (p mut Parser) type_decl() ast.TypeDecl {
variants: sum_variants
}
})
return ast.SumTypeDecl{
name: name
is_pub: is_pub
sub_types: sum_variants
}
}
// type MyType int
else {
parent_type := p.parse_type()
pid := table.type_idx(parent_type)
p.table.register_type_symbol(table.TypeSymbol{
kind: .alias
name: p.prepend_mod(name)
parent_idx: table.type_idx(parent_type)
parent_idx: pid
info: table.Alias{
foo: ''
}
})
}
return ast.TypeDecl{
return ast.AliasTypeDecl{
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'
}
.sum_type{
'sum_type'
}
.alias{
'alias'
}
.enum_{
'enum'
}
else {
'unknown'}
'unknown'
}
}
return k_str
}
@ -405,6 +415,7 @@ pub mut:
}
pub struct SumType {
pub:
variants []Type
}