checker/parser: allow for fixed array with sizes defined with a const
							parent
							
								
									514d989a27
								
							
						
					
					
						commit
						217e6f3b8e
					
				|  | @ -302,7 +302,6 @@ pub fn (s Socket) close() ?int { | |||
| pub const ( | ||||
| 	CRLF = '\r\n' | ||||
| 	MAX_READ = 400 | ||||
| 	xxx = 400 | ||||
| 	MSG_PEEK = 0x02 | ||||
| ) | ||||
| // write - write a string with CRLF after it over the socket s
 | ||||
|  | @ -317,7 +316,6 @@ pub fn (s Socket) write(str string) ?int { | |||
| 
 | ||||
| // read_line - retrieves a line from the socket s (i.e. a string ended with \n)
 | ||||
| pub fn (s Socket) read_line() string { | ||||
| 	//mut buf2 := [xxx]byte // where C.recv will store the network data
 | ||||
| 	mut buf := [MAX_READ]byte // where C.recv will store the network data
 | ||||
| 	mut res := '' // The final result, including the ending \n.
 | ||||
| 	for { | ||||
|  | @ -385,4 +383,3 @@ pub fn (s Socket) get_port() int { | |||
| 	C.getsockname(s.sockfd, &addr, &size) | ||||
| 	return C.ntohs(addr.sin_port) | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -588,6 +588,8 @@ pub struct ArrayInit { | |||
| pub: | ||||
| 	pos       token.Position | ||||
| 	exprs     []Expr | ||||
| 	is_fixed  bool | ||||
| 	mod       string | ||||
| mut: | ||||
| 	elem_type table.Type | ||||
| 	typ       table.Type | ||||
|  |  | |||
|  | @ -56,7 +56,8 @@ pub fn (s &Scope) is_known(name string) bool { | |||
| 
 | ||||
| pub fn (s &Scope) find_var(name string) ?Var { | ||||
| 	if obj := s.find(name) { | ||||
| 		match obj { | ||||
| 		v := ScopeObject(obj) | ||||
| 		match v { | ||||
| 			Var { | ||||
| 				return *it | ||||
| 			} | ||||
|  | @ -68,7 +69,8 @@ pub fn (s &Scope) find_var(name string) ?Var { | |||
| 
 | ||||
| pub fn (s &Scope) find_const(name string) ?ConstField { | ||||
| 	if obj := s.find(name) { | ||||
| 		match obj { | ||||
| 		cf := ScopeObject(obj) | ||||
| 		match cf { | ||||
| 			ConstField { | ||||
| 				return *it | ||||
| 			} | ||||
|  |  | |||
|  | @ -85,6 +85,9 @@ pub fn (x Expr) str() string { | |||
| 		PrefixExpr { | ||||
| 			return it.op.str() + it.right.str() | ||||
| 		} | ||||
| 		CharLiteral { | ||||
| 			return '`$it.val`' | ||||
| 		} | ||||
| 		IntegerLiteral { | ||||
| 			return it.val | ||||
| 		} | ||||
|  |  | |||
|  | @ -706,7 +706,7 @@ pub fn (c mut Checker) array_init(array_init mut ast.ArrayInit) table.Type { | |||
| 		idx := c.table.find_or_register_array(elem_type, 1) | ||||
| 		array_init.typ = table.new_type(idx) | ||||
| 		array_init.elem_type = elem_type | ||||
| 	} else if array_init.exprs.len == 1 && array_init.elem_type != table.void_type { | ||||
| 	} else if array_init.is_fixed && array_init.exprs.len == 1 && array_init.elem_type != table.void_type { | ||||
| 		// [50]byte
 | ||||
| 		mut fixed_size := 1 | ||||
| 		match array_init.exprs[0] { | ||||
|  | @ -714,19 +714,23 @@ pub fn (c mut Checker) array_init(array_init mut ast.ArrayInit) table.Type { | |||
| 				fixed_size = it.val.int() | ||||
| 			} | ||||
| 			ast.Ident { | ||||
| 				/* | ||||
| 				QTODO | ||||
| 				scope := c.file.scope.innermost(array_init.pos.pos) | ||||
| 				if obj := c.file.global_scope.find(it.name) { | ||||
| 				//if obj := c.file.global_scope.find_const(it.name) {
 | ||||
| 				//if  obj := scope.find(it.name) {
 | ||||
| 				//scope := c.file.scope.innermost(array_init.pos.pos)
 | ||||
| 				//eprintln('scope: ${scope.str()}')
 | ||||
| 				//scope.find(it.name) or {
 | ||||
| 				//	c.error('undefined: `$it.name`', array_init.pos)
 | ||||
| 				//}
 | ||||
| 				mut full_const_name := if it.mod == 'main' { it.name } else {it.mod + '.' + it.name } | ||||
| 				if  obj := c.file.global_scope.find_const( full_const_name ) { | ||||
| 					cf := ast.ConstField(obj) | ||||
| 					if cint := is_const_integer(cf) { | ||||
| 						fixed_size = cint.val.int() | ||||
| 					} | ||||
| 				} else { | ||||
| 					c.error(it.name, array_init.pos) | ||||
| 					c.error('non existant integer const $full_const_name while initializing the size of a static array', array_init.pos) | ||||
| 				} | ||||
| 				scope.find(it.name) or { | ||||
| 					c.error('undefined: `$it.name`', array_init.pos) | ||||
| 				} | ||||
| */ | ||||
| 			} | ||||
| 			else { | ||||
| 			} else { | ||||
| 				c.error('expecting `int` for fixed size', array_init.pos) | ||||
| 			} | ||||
| 		} | ||||
|  | @ -737,6 +741,16 @@ pub fn (c mut Checker) array_init(array_init mut ast.ArrayInit) table.Type { | |||
| 	return array_init.typ | ||||
| } | ||||
| 
 | ||||
| fn is_const_integer(cfield ast.ConstField) ?ast.IntegerLiteral { | ||||
| 	match cfield.expr { | ||||
| 		ast.IntegerLiteral { | ||||
| 			return *it | ||||
| 		} | ||||
| 		else {} | ||||
| 	} | ||||
| 	return none | ||||
| } | ||||
| 
 | ||||
| fn (c mut Checker) stmt(node ast.Stmt) { | ||||
| 	// c.expected_type = table.void_type
 | ||||
| 	match mut node { | ||||
|  |  | |||
|  | @ -723,7 +723,7 @@ fn (g mut Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { | |||
| 				mut is_fixed_array_init := false | ||||
| 				match val { | ||||
| 					ast.ArrayInit { | ||||
| 						is_fixed_array_init = right_sym.kind == .array_fixed | ||||
| 						is_fixed_array_init = it.is_fixed | ||||
| 					} | ||||
| 					else {} | ||||
| 				} | ||||
|  | @ -740,15 +740,15 @@ fn (g mut Gen) gen_assign_stmt(assign_stmt ast.AssignStmt) { | |||
| 						return | ||||
| 					} | ||||
| 				} | ||||
| 				if !is_fixed_array_init { | ||||
| 				if is_fixed_array_init { | ||||
| 					g.write('= {0}') | ||||
| 				} else { | ||||
| 					g.write(' = ') | ||||
| 					if !is_decl { | ||||
| 						g.expr_with_cast(val, assign_stmt.left_types[i], ident_var_info.typ) | ||||
| 					} else { | ||||
| 						g.expr(val) | ||||
| 					} | ||||
| 				} else if is_fixed_array_init { | ||||
| 					g.write('= {0}') | ||||
| 				} | ||||
| 				if gen_or { | ||||
| 					g.or_block(ident.name, or_stmts, return_type) | ||||
|  |  | |||
|  | @ -513,19 +513,28 @@ fn (p mut Parser) range_expr(low ast.Expr) ast.Expr { | |||
| 	return node | ||||
| } | ||||
| */ | ||||
| 
 | ||||
| pub fn (p &Parser) error(s string) { | ||||
| 	p.error_with_pos(s, p.tok.position()) | ||||
| } | ||||
| 
 | ||||
| pub fn (p &Parser) warn(s string) { | ||||
| 	p.warn_with_pos(s, p.tok.position()) | ||||
| } | ||||
| 
 | ||||
| pub fn (p &Parser) error_with_pos(s string, pos token.Position) { | ||||
| 	mut kind := 'error:' | ||||
| 	if p.pref.is_verbose { | ||||
| 		print_backtrace() | ||||
| 		kind = 'parser error:' | ||||
| 	} | ||||
| 	ferror := util.formatted_error(kind, s, p.file_name, p.tok.position()) | ||||
| 	ferror := util.formatted_error(kind, s, p.file_name, pos) | ||||
| 	eprintln(ferror) | ||||
| 	exit(1) | ||||
| } | ||||
| 
 | ||||
| pub fn (p &Parser) warn(s string) { | ||||
| 	ferror := util.formatted_error('warning:', s, p.file_name, p.tok.position()) | ||||
| pub fn (p &Parser) warn_with_pos(s string, pos token.Position) { | ||||
| 	ferror := util.formatted_error('warning:', s, p.file_name, pos) | ||||
| 	eprintln(ferror) | ||||
| } | ||||
| 
 | ||||
|  | @ -1298,6 +1307,7 @@ fn (p mut Parser) array_init() ast.ArrayInit { | |||
| 	mut array_type := table.void_type | ||||
| 	mut elem_type := table.void_type | ||||
| 	mut exprs := []ast.Expr | ||||
| 	is_fixed := false | ||||
| 	if p.tok.kind == .rsbr { | ||||
| 		// []typ => `[]` and `typ` must be on the same line
 | ||||
| 		line_nr := p.tok.line_nr | ||||
|  | @ -1311,7 +1321,7 @@ fn (p mut Parser) array_init() ast.ArrayInit { | |||
| 			array_type = table.new_type(idx) | ||||
| 		} | ||||
| 	} else { | ||||
| 		// [1,2,3]
 | ||||
| 		// [1,2,3] or [const]byte
 | ||||
| 		for i := 0; p.tok.kind != .rsbr; i++ { | ||||
| 			expr := p.expr(0) | ||||
| 			exprs << expr | ||||
|  | @ -1325,7 +1335,7 @@ fn (p mut Parser) array_init() ast.ArrayInit { | |||
| 		// [100]byte
 | ||||
| 		if exprs.len == 1 && p.tok.kind in [.name, .amp] && p.tok.line_nr == line_nr { | ||||
| 			elem_type = p.parse_type() | ||||
| 			// p.warn('fixed size array')
 | ||||
| 			is_fixed = true | ||||
| 		} | ||||
| 	} | ||||
| 	// !
 | ||||
|  | @ -1343,6 +1353,8 @@ fn (p mut Parser) array_init() ast.ArrayInit { | |||
| 		len: len | ||||
| 	} | ||||
| 	return ast.ArrayInit{ | ||||
| 		is_fixed: is_fixed | ||||
| 		mod: p.mod | ||||
| 		elem_type: elem_type | ||||
| 		typ: array_type | ||||
| 		exprs: exprs | ||||
|  |  | |||
|  | @ -0,0 +1,39 @@ | |||
| const ( | ||||
| 	sbuffer_size = 10 | ||||
| ) | ||||
| 
 | ||||
| fn test_hardcoded_static_arr(){ | ||||
| 	myints := [10]int | ||||
| 	size := sizeof( myints ) | ||||
| 	assert size == 40 | ||||
| } | ||||
| 
 | ||||
| fn test_const_based_static_arr(){ | ||||
| 	myints := [sbuffer_size]int | ||||
| 	size := sizeof( myints ) | ||||
| 	assert size == 40 | ||||
| } | ||||
| 
 | ||||
| fn test_const_based_static_arr_of_f64(){ | ||||
| 	myf64 := [sbuffer_size]f64 | ||||
| 	size := sizeof( myf64 ) | ||||
| 	assert size == 80 | ||||
| } | ||||
| 
 | ||||
| fn test_const_based_static_arr_of_f32(){ | ||||
| 	myf32 := [sbuffer_size]f32 | ||||
| 	size := sizeof( myf32 ) | ||||
| 	assert size == 40 | ||||
| } | ||||
| 
 | ||||
| fn test_const_based_static_arr_of_i8(){ | ||||
| 	myi8 := [sbuffer_size]i8 | ||||
| 	size := sizeof( myi8 ) | ||||
| 	assert size == 10 | ||||
| } | ||||
| 
 | ||||
| fn test_const_based_static_arr_of_i16(){ | ||||
| 	myi16 := [sbuffer_size]i16 | ||||
| 	size := sizeof( myi16 ) | ||||
| 	assert size == 20 | ||||
| } | ||||
|  | @ -10,6 +10,10 @@ pub: | |||
| 	len     int // length of the literal in the source
 | ||||
| } | ||||
| 
 | ||||
| pub fn (pos Position) str() string { | ||||
| 	return 'Position{ line_nr: $pos.line_nr, pos: $pos.pos, len: $pos.len }' | ||||
| } | ||||
| 
 | ||||
| [inline] | ||||
| pub fn (tok &Token) position() Position { | ||||
| 	return Position{ | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue