parser: `[]int{cap:cap, len:len}` syntax; minor fixes
parent
893d14ef8f
commit
ec10831318
|
@ -691,3 +691,8 @@ fn test_hex(){
|
||||||
st1 := [byte(0x41)].repeat(100)
|
st1 := [byte(0x41)].repeat(100)
|
||||||
assert st1.hex() == "41".repeat(100)
|
assert st1.hex() == "41".repeat(100)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_array_with_cap() {
|
||||||
|
a := []int{cap:10, len:1 }
|
||||||
|
//assert a.len == 1
|
||||||
|
}
|
||||||
|
|
|
@ -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 {
|
if typ_sym.kind == .void && arg_typ_sym.kind == .string {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if f.is_generic {
|
||||||
|
continue
|
||||||
|
}
|
||||||
if typ_sym.kind == .array_fixed {
|
if typ_sym.kind == .array_fixed {
|
||||||
}
|
}
|
||||||
// println('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)
|
c.error('match 0 cond type', node.pos)
|
||||||
}
|
}
|
||||||
type_sym := c.table.get_type_symbol(cond_type)
|
type_sym := c.table.get_type_symbol(cond_type)
|
||||||
|
|
||||||
// all_possible_left_subtypes is a histogram of
|
// all_possible_left_subtypes is a histogram of
|
||||||
// type => how many times it was used in the match
|
// type => how many times it was used in the match
|
||||||
mut all_possible_left_subtypes := map[string]int
|
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 {
|
match type_sym.info {
|
||||||
table.SumType {
|
table.SumType {
|
||||||
for v in it.variants {
|
for v in it.variants {
|
||||||
all_possible_left_subtypes[ int(v).str() ] = 0
|
all_possible_left_subtypes[int(v).str()] = 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
table.Enum {
|
table.Enum {
|
||||||
|
@ -1362,12 +1364,14 @@ pub fn (c mut Checker) match_expr(node mut ast.MatchExpr) table.Type {
|
||||||
ast.Type {
|
ast.Type {
|
||||||
tidx := table.type_idx(it.typ)
|
tidx := table.type_idx(it.typ)
|
||||||
stidx := tidx.str()
|
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 {
|
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
|
unhandled := []string
|
||||||
match type_sym.info {
|
match type_sym.info {
|
||||||
table.SumType {
|
table.SumType {
|
||||||
for k,v in all_possible_left_subtypes {
|
for k, v in all_possible_left_subtypes {
|
||||||
if v == 0 {
|
if v == 0 {
|
||||||
err = true
|
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 {
|
if v > 1 {
|
||||||
err = true
|
err = true
|
||||||
multiple_type_name := '`' + c.table.type_to_str( table.new_type( k.int() ) ) + '`'
|
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)
|
'`'
|
||||||
|
c.error('a match case for $multiple_type_name is handled more than once',
|
||||||
|
node.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
table.Enum {
|
table.Enum {
|
||||||
for k,v in all_possible_left_enum_vals {
|
for k, v in all_possible_left_enum_vals {
|
||||||
if v == 0 {
|
if v == 0 {
|
||||||
err = true
|
err = true
|
||||||
unhandled << '`.$k`'
|
unhandled << '`.$k`'
|
||||||
|
@ -1397,11 +1403,14 @@ pub fn (c mut Checker) match_expr(node mut ast.MatchExpr) table.Type {
|
||||||
if v > 1 {
|
if v > 1 {
|
||||||
err = true
|
err = true
|
||||||
multiple_enum_val := '`.$k`'
|
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 err {
|
||||||
if unhandled.len > 0 {
|
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.error(err_details, node.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c.expected_type = cond_type
|
c.expected_type = cond_type
|
||||||
mut ret_type := table.void_type
|
mut ret_type := table.void_type
|
||||||
for branch in node.branches {
|
for branch in node.branches {
|
||||||
|
|
|
@ -553,6 +553,15 @@ fn (f mut Fmt) expr(node ast.Expr) {
|
||||||
f.write(it.val)
|
f.write(it.val)
|
||||||
}
|
}
|
||||||
ast.MapInit {
|
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.writeln('{')
|
||||||
f.indent++
|
f.indent++
|
||||||
for i, key in it.keys {
|
for i, key in it.keys {
|
||||||
|
|
|
@ -212,9 +212,13 @@ pub fn (g mut Gen) typ(t table.Type) string {
|
||||||
if table.type_is(t, .optional) {
|
if table.type_is(t, .optional) {
|
||||||
// Register an optional
|
// Register an optional
|
||||||
styp = 'Option_' + styp
|
styp = 'Option_' + styp
|
||||||
|
if table.type_is_ptr(t) {
|
||||||
|
styp = styp.replace('*', '_ptr')
|
||||||
|
}
|
||||||
if !(styp in g.optionals) {
|
if !(styp in g.optionals) {
|
||||||
// println(styp)
|
// println(styp)
|
||||||
g.typedefs2.writeln('typedef Option $styp;')
|
x := styp // .replace('*', '_ptr') // handle option ptrs
|
||||||
|
g.typedefs2.writeln('typedef Option $x;')
|
||||||
g.optionals << styp
|
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)
|
mut styp := g.typ(g.fn_decl.return_type)
|
||||||
if fn_return_is_optional { // && !table.type_is(node.types[0], .optional) && node.types[0] !=
|
if fn_return_is_optional { // && !table.type_is(node.types[0], .optional) && node.types[0] !=
|
||||||
styp = styp[7..] // remove 'Option_'
|
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){')
|
g.write('($styp){')
|
||||||
for i, expr in node.exprs {
|
for i, expr in node.exprs {
|
||||||
|
@ -1783,9 +1791,13 @@ fn (g mut Gen) return_statement(node ast.Return) {
|
||||||
}
|
}
|
||||||
if !is_none && !is_error {
|
if !is_none && !is_error {
|
||||||
styp := g.typ(g.fn_decl.return_type)[7..] // remove 'Option_'
|
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.expr(node.exprs[0])
|
||||||
g.writeln(' }, sizeof($styp));')
|
g.writeln(' }, sizeof($x));')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// g.write('/*OPTIONAL*/')
|
// g.write('/*OPTIONAL*/')
|
||||||
|
|
|
@ -141,7 +141,8 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
|
||||||
p.next()
|
p.next()
|
||||||
}
|
}
|
||||||
// <T>
|
// <T>
|
||||||
if p.tok.kind == .lt {
|
is_generic := p.tok.kind == .lt
|
||||||
|
if is_generic {
|
||||||
p.next()
|
p.next()
|
||||||
p.next()
|
p.next()
|
||||||
p.check(.gt)
|
p.check(.gt)
|
||||||
|
@ -169,6 +170,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
|
||||||
args: args
|
args: args
|
||||||
return_type: return_type
|
return_type: return_type
|
||||||
is_variadic: is_variadic
|
is_variadic: is_variadic
|
||||||
|
is_generic: is_generic
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
if is_c {
|
if is_c {
|
||||||
|
@ -185,6 +187,7 @@ fn (p mut Parser) fn_decl() ast.FnDecl {
|
||||||
return_type: return_type
|
return_type: return_type
|
||||||
is_variadic: is_variadic
|
is_variadic: is_variadic
|
||||||
is_c: is_c
|
is_c: is_c
|
||||||
|
is_generic: is_generic
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// Body
|
// Body
|
||||||
|
|
|
@ -1351,15 +1351,12 @@ fn (p mut Parser) array_init() ast.ArrayInit {
|
||||||
// p.check_comment()
|
// p.check_comment()
|
||||||
}
|
}
|
||||||
line_nr := p.tok.line_nr
|
line_nr := p.tok.line_nr
|
||||||
|
|
||||||
$if tinyc {
|
$if tinyc {
|
||||||
// NB: do not remove the next line without testing
|
// NB: do not remove the next line without testing
|
||||||
// v selfcompilation with tcc first
|
// v selfcompilation with tcc first
|
||||||
tcc_stack_bug := 12345
|
tcc_stack_bug := 12345
|
||||||
}
|
}
|
||||||
|
|
||||||
last_pos = p.tok.position()
|
last_pos = p.tok.position()
|
||||||
|
|
||||||
p.check(.rsbr)
|
p.check(.rsbr)
|
||||||
// [100]byte
|
// [100]byte
|
||||||
if exprs.len == 1 && p.tok.kind in [.name, .amp] && p.tok.line_nr == line_nr {
|
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()
|
last_pos = p.tok.position()
|
||||||
p.next()
|
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{
|
pos := token.Position{
|
||||||
line_nr: first_pos.line_nr
|
line_nr: first_pos.line_nr
|
||||||
pos: first_pos.pos
|
pos: first_pos.pos
|
||||||
|
@ -1594,7 +1607,9 @@ fn (p mut Parser) struct_decl() ast.StructDecl {
|
||||||
// p.expr(0)
|
// p.expr(0)
|
||||||
default_expr = p.expr(0)
|
default_expr = p.expr(0)
|
||||||
match default_expr {
|
match default_expr {
|
||||||
ast.EnumVal { it.typ = typ }
|
ast.EnumVal {
|
||||||
|
it.typ = typ
|
||||||
|
}
|
||||||
// TODO: implement all types??
|
// TODO: implement all types??
|
||||||
else {}
|
else {}
|
||||||
}
|
}
|
||||||
|
@ -1865,8 +1880,8 @@ fn (p mut Parser) match_expr() ast.MatchExpr {
|
||||||
if p.tok.kind == .key_else {
|
if p.tok.kind == .key_else {
|
||||||
is_else = true
|
is_else = true
|
||||||
p.next()
|
p.next()
|
||||||
} else if p.tok.kind == .name && (p.tok.lit in table.builtin_type_names ||
|
} else if p.tok.kind == .name && (p.tok.lit in table.builtin_type_names || (p.tok.lit[0].is_capital() &&
|
||||||
(p.tok.lit[0].is_capital() && !p.tok.lit.is_upper()) || p.peek_tok.kind == .dot) {
|
!p.tok.lit.is_upper()) || p.peek_tok.kind == .dot) {
|
||||||
// Sum type match
|
// Sum type match
|
||||||
// if sym.kind == .sum_type {
|
// if sym.kind == .sum_type {
|
||||||
// p.warn('is sum')
|
// p.warn('is sum')
|
||||||
|
|
|
@ -25,6 +25,7 @@ pub:
|
||||||
return_type Type
|
return_type Type
|
||||||
is_variadic bool
|
is_variadic bool
|
||||||
is_c bool
|
is_c bool
|
||||||
|
is_generic bool
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Arg {
|
pub struct Arg {
|
||||||
|
|
Loading…
Reference in New Issue