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