parser: `[]int{cap:cap, len:len}` syntax; minor fixes

pull/4404/head^2
Alexander Medvednikov 2020-04-14 18:09:59 +02:00
parent 893d14ef8f
commit ec10831318
7 changed files with 79 additions and 26 deletions

View File

@ -691,3 +691,8 @@ fn test_hex(){
st1 := [byte(0x41)].repeat(100)
assert st1.hex() == "41".repeat(100)
}
fn test_array_with_cap() {
a := []int{cap:10, len:1 }
//assert a.len == 1
}

View File

@ -444,6 +444,9 @@ pub fn (c mut Checker) call_fn(call_expr mut ast.CallExpr) table.Type {
if typ_sym.kind == .void && arg_typ_sym.kind == .string {
continue
}
if f.is_generic {
continue
}
if typ_sym.kind == .array_fixed {
}
// println('fixed')
@ -1333,7 +1336,6 @@ pub fn (c mut Checker) match_expr(node mut ast.MatchExpr) table.Type {
c.error('match 0 cond type', node.pos)
}
type_sym := c.table.get_type_symbol(cond_type)
// all_possible_left_subtypes is a histogram of
// type => how many times it was used in the match
mut all_possible_left_subtypes := map[string]int
@ -1343,7 +1345,7 @@ pub fn (c mut Checker) match_expr(node mut ast.MatchExpr) table.Type {
match type_sym.info {
table.SumType {
for v in it.variants {
all_possible_left_subtypes[ int(v).str() ] = 0
all_possible_left_subtypes[int(v).str()] = 0
}
}
table.Enum {
@ -1362,12 +1364,14 @@ pub fn (c mut Checker) match_expr(node mut ast.MatchExpr) table.Type {
ast.Type {
tidx := table.type_idx(it.typ)
stidx := tidx.str()
all_possible_left_subtypes[ stidx ] = all_possible_left_subtypes[ stidx ] + 1
all_possible_left_subtypes[stidx] = all_possible_left_subtypes[stidx] +
1
}
ast.EnumVal {
all_possible_left_enum_vals[ it.val ] = all_possible_left_enum_vals[ it.val ] + 1
all_possible_left_enum_vals[it.val] = all_possible_left_enum_vals[it.val] +
1
}
else{}
else {}
}
}
}
@ -1376,20 +1380,22 @@ pub fn (c mut Checker) match_expr(node mut ast.MatchExpr) table.Type {
unhandled := []string
match type_sym.info {
table.SumType {
for k,v in all_possible_left_subtypes {
for k, v in all_possible_left_subtypes {
if v == 0 {
err = true
unhandled << '`' + c.table.type_to_str( table.new_type( k.int() ) ) + '`'
unhandled << '`' + c.table.type_to_str(table.new_type(k.int())) + '`'
}
if v > 1 {
err = true
multiple_type_name := '`' + c.table.type_to_str( table.new_type( k.int() ) ) + '`'
c.error('a match case for $multiple_type_name is handled more than once', node.pos)
multiple_type_name := '`' + c.table.type_to_str(table.new_type(k.int())) +
'`'
c.error('a match case for $multiple_type_name is handled more than once',
node.pos)
}
}
}
table.Enum {
for k,v in all_possible_left_enum_vals {
for k, v in all_possible_left_enum_vals {
if v == 0 {
err = true
unhandled << '`.$k`'
@ -1397,11 +1403,14 @@ pub fn (c mut Checker) match_expr(node mut ast.MatchExpr) table.Type {
if v > 1 {
err = true
multiple_enum_val := '`.$k`'
c.error('a match case for $multiple_enum_val is handled more than once', node.pos)
c.error('a match case for $multiple_enum_val is handled more than once',
node.pos)
}
}
}
else { err = true }
else {
err = true
}
}
if err {
if unhandled.len > 0 {
@ -1410,7 +1419,6 @@ pub fn (c mut Checker) match_expr(node mut ast.MatchExpr) table.Type {
c.error(err_details, node.pos)
}
}
c.expected_type = cond_type
mut ret_type := table.void_type
for branch in node.branches {

View File

@ -553,6 +553,15 @@ fn (f mut Fmt) expr(node ast.Expr) {
f.write(it.val)
}
ast.MapInit {
if it.keys.len == 0 {
if it.value_type == 0 {
f.write('map[string]int') // TODO
return
}
f.write('map[string]')
f.write(f.type_to_str(it.value_type))
return
}
f.writeln('{')
f.indent++
for i, key in it.keys {

View File

@ -212,9 +212,13 @@ pub fn (g mut Gen) typ(t table.Type) string {
if table.type_is(t, .optional) {
// Register an optional
styp = 'Option_' + styp
if table.type_is_ptr(t) {
styp = styp.replace('*', '_ptr')
}
if !(styp in g.optionals) {
// println(styp)
g.typedefs2.writeln('typedef Option $styp;')
x := styp // .replace('*', '_ptr') // handle option ptrs
g.typedefs2.writeln('typedef Option $x;')
g.optionals << styp
}
}
@ -1744,7 +1748,11 @@ fn (g mut Gen) return_statement(node ast.Return) {
mut styp := g.typ(g.fn_decl.return_type)
if fn_return_is_optional { // && !table.type_is(node.types[0], .optional) && node.types[0] !=
styp = styp[7..] // remove 'Option_'
g.write('opt_ok(& ($styp []) { ')
mut x := styp
if x.ends_with('_ptr') {
x = x.replace('_ptr', '*')
}
g.write('opt_ok(&($x/*X*/[]) { ')
}
g.write('($styp){')
for i, expr in node.exprs {
@ -1783,9 +1791,13 @@ fn (g mut Gen) return_statement(node ast.Return) {
}
if !is_none && !is_error {
styp := g.typ(g.fn_decl.return_type)[7..] // remove 'Option_'
g.write('/*:)$return_sym.name*/opt_ok(&($styp []) { ')
mut x := styp
if x.ends_with('_ptr') {
x = x.replace('_ptr', '*')
}
g.write('/*:)$return_sym.name*/opt_ok(&($x[]) { ')
g.expr(node.exprs[0])
g.writeln(' }, sizeof($styp));')
g.writeln(' }, sizeof($x));')
return
}
// g.write('/*OPTIONAL*/')

View File

@ -141,7 +141,8 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
p.next()
}
// <T>
if p.tok.kind == .lt {
is_generic := p.tok.kind == .lt
if is_generic {
p.next()
p.next()
p.check(.gt)
@ -169,6 +170,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
args: args
return_type: return_type
is_variadic: is_variadic
is_generic: is_generic
})
} else {
if is_c {
@ -185,6 +187,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
return_type: return_type
is_variadic: is_variadic
is_c: is_c
is_generic: is_generic
})
}
// Body

View File

@ -1351,15 +1351,12 @@ fn (p mut Parser) array_init() ast.ArrayInit {
// p.check_comment()
}
line_nr := p.tok.line_nr
$if tinyc {
// NB: do not remove the next line without testing
// v selfcompilation with tcc first
tcc_stack_bug := 12345
}
last_pos = p.tok.position()
p.check(.rsbr)
// [100]byte
if exprs.len == 1 && p.tok.kind in [.name, .amp] && p.tok.line_nr == line_nr {
@ -1376,6 +1373,22 @@ fn (p mut Parser) array_init() ast.ArrayInit {
last_pos = p.tok.position()
p.next()
}
if p.tok.kind == .lcbr && exprs.len == 0 {
// `[]int{ len: 10, cap: 100}` syntax
p.next()
for p.tok.kind != .rcbr {
key := p.check_name()
p.check(.colon)
if !(key in ['len', 'cap', 'init']) {
p.error('wrong field `$key`, expecting `len`, `cap`, or `init`')
}
p.expr(0)
if p.tok.kind != .rcbr {
p.check(.comma)
}
}
p.check(.rcbr)
}
pos := token.Position{
line_nr: first_pos.line_nr
pos: first_pos.pos
@ -1594,7 +1607,9 @@ fn (p mut Parser) struct_decl() ast.StructDecl {
// p.expr(0)
default_expr = p.expr(0)
match default_expr {
ast.EnumVal { it.typ = typ }
ast.EnumVal {
it.typ = typ
}
// TODO: implement all types??
else {}
}
@ -1865,8 +1880,8 @@ fn (p mut Parser) match_expr() ast.MatchExpr {
if p.tok.kind == .key_else {
is_else = true
p.next()
} else if p.tok.kind == .name && (p.tok.lit in table.builtin_type_names ||
(p.tok.lit[0].is_capital() && !p.tok.lit.is_upper()) || p.peek_tok.kind == .dot) {
} else if p.tok.kind == .name && (p.tok.lit in table.builtin_type_names || (p.tok.lit[0].is_capital() &&
!p.tok.lit.is_upper()) || p.peek_tok.kind == .dot) {
// Sum type match
// if sym.kind == .sum_type {
// p.warn('is sum')
@ -1993,7 +2008,7 @@ fn (p mut Parser) type_decl() ast.TypeDecl {
name := p.check_name()
mut sum_variants := []table.Type
if p.tok.kind == .assign {
p.next() // TODO require `=`
p.next() // TODO require `=`
}
if p.tok.kind == .key_fn {
// function type: `type mycallback fn(string, int)`
@ -2005,7 +2020,7 @@ fn (p mut Parser) type_decl() ast.TypeDecl {
typ: fn_type
}
}
first_type := p.parse_type() // need to parse the first type before we can check if it's `type A = X | Y`
first_type := p.parse_type() // need to parse the first type before we can check if it's `type A = X | Y`
if p.tok.kind == .pipe {
p.check(.pipe)
sum_variants << first_type

View File

@ -25,6 +25,7 @@ pub:
return_type Type
is_variadic bool
is_c bool
is_generic bool
}
pub struct Arg {