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

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

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