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
 | 
				
			||||||
| 
						 | 
					@ -1362,10 +1364,12 @@ 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 {}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
| 
						 | 
					@ -1383,8 +1387,10 @@ pub fn (c mut Checker) match_expr(node mut ast.MatchExpr) table.Type {
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					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)
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
| 
						 | 
					@ -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