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

@ -127,7 +127,7 @@ fn (f mut Fmt) stmt(node ast.Stmt) {
f.writeln('continue')
}
else {}
}
}
}
ast.ConstDecl {
if it.is_pub {
@ -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

@ -56,7 +56,7 @@ pub fn parse_stmt(text string, table &table.Table, scope &ast.Scope) ast.Stmt {
pref: &pref.Preferences{}
scope: scope
// scope: &ast.Scope{start_pos: 0, parent: 0}
}
p.init_parse_fns()
p.read_first_token()
@ -80,7 +80,7 @@ pub fn parse_file(path string, table &table.Table, comments_mode scanner.Comment
parent: 0
}
// comments_mode: comments_mode
}
p.read_first_token()
// p.scope = &ast.Scope{start_pos: p.tok.position(), parent: 0}
@ -614,7 +614,7 @@ pub fn (p mut Parser) name_expr() ast.Expr {
p.expr_mod = ''
return ast.EnumVal{
enum_name: enum_name // lp.prepend_mod(enum_name)
val: val
pos: p.tok.position()
}
@ -941,7 +941,7 @@ fn (p mut Parser) infix_expr(left ast.Expr) ast.Expr {
left: left
right: right
// right_type: typ
op: op
pos: pos
}
@ -1052,7 +1052,7 @@ fn (p mut Parser) for_statement() ast.Stmt {
p.scope.register_var(ast.VarDecl{
name: var_name
// expr: cond
})
stmts := p.parse_block()
// println('nr stmts=$stmts.len')
@ -1147,11 +1147,11 @@ fn (p mut Parser) if_expr() ast.Expr {
stmts: stmts
else_stmts: else_stmts
// typ: typ
pos: pos
has_else: has_else
// left: left
}
return node
}
@ -1325,7 +1325,7 @@ fn (p mut Parser) const_decl() ast.ConstDecl {
fields << ast.Field{
name: name
// typ: typ
}
exprs << expr
// TODO: once consts are fixed reg here & update in checker
@ -1536,12 +1536,12 @@ fn (p mut Parser) var_decl_and_assign_stmt() ast.Stmt {
return ast.VarDecl{
name: ident.name
// name2: name2
expr: expr // p.expr(token.lowest_prec)
is_mut: info0.is_mut
// typ: typ
pos: p.tok.position()
}
// return p.var_decl(ident[0], exprs[0])
@ -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()
p.table.register_type_symbol(table.TypeSymbol{
kind: .alias
name: p.prepend_mod(name)
parent_idx: table.type_idx(parent_type)
info: table.Alias{
foo: ''
}
})
}
return ast.TypeDecl{
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: pid
info: table.Alias{
foo: ''
}
})
return ast.AliasTypeDecl{
name: name
is_pub: is_pub
parent_type: parent_type
}
}

View File

@ -7,7 +7,7 @@ import (
strings
)
pub type TypeInfo = Array | ArrayFixed | Map | Struct |
pub type TypeInfo = Array | ArrayFixed | Map | Struct |
MultiReturn | Alias | Enum | SumType
pub struct TypeSymbol {
@ -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
}