@@ -294,6 +294,9 @@ def make_array_access(id_, lineno, arglist):
294294 """ Creates an array access. A(x1, x2, ..., xn).
295295 This is an RVALUE (Read the element)
296296 """
297+ for i , arg in enumerate (arglist ):
298+ arg .value = make_typecast (TYPE .by_name (api .constants .TYPE .to_string (gl .BOUND_TYPE )), arg .value , arg .lineno )
299+
297300 return symbols .ARRAYACCESS .make_node (id_ , arglist , lineno )
298301
299302
@@ -379,10 +382,10 @@ def make_call(id_, lineno, args):
379382 return make_func_call (id_ , lineno , args )
380383
381384
382- def make_param_decl (id_ , lineno , typedef ):
385+ def make_param_decl (id_ , lineno , typedef , is_array = False ):
383386 """ Wrapper that creates a param declaration
384387 """
385- return SYMBOL_TABLE .declare_param (id_ , lineno , typedef )
388+ return SYMBOL_TABLE .declare_param (id_ , lineno , typedef , is_array )
386389
387390
388391def make_type (typename , lineno , implicit = False ):
@@ -1047,43 +1050,13 @@ def p_assignment(p):
10471050 syntax_error (p .lineno (i ), 'Cannot assign an array to an scalar variable' )
10481051 return
10491052
1050- if variable .class_ == CLASS .array :
1051- if q1class_ != variable .class_ :
1052- syntax_error (p .lineno (i ), 'Cannot assign an scalar to an array variable' )
1053- return
1054-
1055- if q [1 ].type_ != variable .type_ :
1056- syntax_error (p .lineno (i ), 'Arrays must have the same element type' )
1057- return
1058-
1059- if variable .memsize != q [1 ].memsize :
1060- syntax_error (p .lineno (i ), "Arrays '%s' and '%s' must have the same size" %
1061- (variable .name , q [1 ].name ))
1062- return
1063-
1064- if variable .count != q [1 ].count :
1065- warning (p .lineno (i ), "Arrays '%s' and '%s' don't have the same number of dimensions" %
1066- (variable .name , q [1 ].name ))
1067- else :
1068- for b1 , b2 in zip (variable .bounds , q [1 ].bounds ):
1069- if b1 .count != b2 .count :
1070- warning (p .lineno (i ), "Arrays '%s' and '%s' don't have the same dimensions" %
1071- (variable .name , q [1 ].name ))
1072- break
1073- # Array copy
1074- variable .accessed = True
1075- p [0 ] = make_sentence ('ARRAYCOPY' , variable , q [1 ])
1076- return
1077-
10781053 expr = make_typecast (variable .type_ , q [1 ], p .lineno (i ))
10791054 p [0 ] = make_sentence ('LET' , variable , expr )
10801055
10811056
10821057def p_lexpr (p ):
10831058 """ lexpr : ID EQ
10841059 | LET ID EQ
1085- | ARRAY_ID EQ
1086- | LET ARRAY_ID EQ
10871060 """
10881061 global LET_ASSIGNMENT
10891062
@@ -1099,6 +1072,49 @@ def p_lexpr(p):
10991072 SYMBOL_TABLE .access_id (p [i ], p .lineno (i ))
11001073
11011074
1075+ def p_array_copy (p ):
1076+ """ statement : ARRAY_ID EQ ARRAY_ID
1077+ | LET ARRAY_ID EQ ARRAY_ID
1078+ """
1079+ if p [1 ] == 'LET' :
1080+ array_id1 , array_id2 = p [2 ], p [4 ]
1081+ l1 , l2 = p .lineno (2 ), p .lineno (4 )
1082+ else :
1083+ array_id1 , array_id2 = p [1 ], p [3 ]
1084+ l1 , l2 = p .lineno (1 ), p .lineno (3 )
1085+
1086+ larray = SYMBOL_TABLE .access_id (array_id1 , l1 )
1087+ rarray = SYMBOL_TABLE .access_id (array_id2 , l2 )
1088+
1089+ if larray is None or rarray is None :
1090+ p [0 ] = None
1091+ return
1092+
1093+ if larray .type_ != rarray .type_ :
1094+ syntax_error (l1 , 'Arrays must have the same element type' )
1095+ return
1096+
1097+ if larray .memsize != rarray .memsize :
1098+ syntax_error (l1 , "Arrays '%s' and '%s' must have the same size" %
1099+ (array_id1 , array_id2 ))
1100+ return
1101+
1102+ if larray .count != rarray .count :
1103+ warning (l1 , "Arrays '%s' and '%s' don't have the same number of dimensions" %
1104+ (larray .name , rarray .name ))
1105+ else :
1106+ for b1 , b2 in zip (larray .bounds , rarray .bounds ):
1107+ if b1 .count != b2 .count :
1108+ warning (l1 , "Arrays '%s' and '%s' don't have the same dimensions" %
1109+ (array_id1 , array_id2 ))
1110+ break
1111+ # Array copy
1112+ larray .accessed = True
1113+ rarray .accessed = True
1114+ p [0 ] = make_sentence ('ARRAYCOPY' , larray , rarray )
1115+ return
1116+
1117+
11021118def p_arr_assignment (p ):
11031119 """ statement : ARRAY_ID arg_list EQ expr
11041120 | LET ARRAY_ID arg_list EQ expr
@@ -2543,7 +2559,6 @@ def p_exprstr_file(p):
25432559
25442560def p_id_expr (p ):
25452561 """ bexpr : ID
2546- | ARRAY_ID
25472562 """
25482563 entry = SYMBOL_TABLE .access_id (p [1 ], p .lineno (1 ), default_class = CLASS .var )
25492564 if entry is None :
@@ -2557,7 +2572,7 @@ def p_id_expr(p):
25572572
25582573 p [0 ] = entry
25592574
2560- if entry .class_ == CLASS .array :
2575+ if entry .class_ == CLASS .array : # HINT: This should never happen now
25612576 if not LET_ASSIGNMENT :
25622577 syntax_error (p .lineno (1 ), "Variable '%s' is an array and cannot be used in this context" % p [1 ])
25632578 p [0 ] = None
@@ -2769,18 +2784,40 @@ def p_arg_list_arg(p):
27692784
27702785
27712786def p_arguments (p ):
2772- """ arguments : arguments COMMA expr
2787+ """ arguments : argument
2788+ """
2789+ if p [1 ] is None :
2790+ p [0 ] = None
2791+ return
2792+
2793+ p [0 ] = make_arg_list (p [1 ])
2794+
2795+
2796+ def p_arguments_argument (p ):
2797+ """ arguments : arguments COMMA argument
27732798 """
27742799 if p [1 ] is None or p [3 ] is None :
27752800 p [0 ] = None
27762801 else :
2777- p [0 ] = make_arg_list (p [1 ], make_argument ( p [3 ], p . lineno ( 2 )) )
2802+ p [0 ] = make_arg_list (p [1 ], p [3 ])
27782803
27792804
27802805def p_argument (p ):
2781- """ arguments : expr %prec ID
2806+ """ argument : expr
27822807 """
2783- p [0 ] = make_arg_list (make_argument (p [1 ], p .lineno (1 )))
2808+ p [0 ] = make_argument (p [1 ], p .lineno (1 ))
2809+
2810+
2811+ def p_argument_array (p ):
2812+ """ argument : ARRAY_ID
2813+ """
2814+ entry = SYMBOL_TABLE .access_array (p [1 ], p .lineno (1 ))
2815+ if entry is None :
2816+ p [0 ] = None
2817+ return
2818+
2819+ entry .accessed = True
2820+ p [0 ] = make_argument (entry , p .lineno (1 ))
27842821
27852822
27862823def p_funcdecl (p ):
@@ -2960,18 +2997,42 @@ def p_param_byref_definition(p):
29602997def p_param_byval_definition (p ):
29612998 """ param_definition : BYVAL param_def
29622999 """
2963- p [0 ] = p [2 ]
3000+ param_def = p [2 ]
3001+ p [0 ] = param_def
29643002
29653003 if p [0 ] is not None :
2966- p [0 ].byref = False
3004+ if param_def .class_ == CLASS .array :
3005+ api .errmsg .syntax_error_cannot_pass_array_by_value (p .lineno (1 ), param_def .name )
3006+ p [0 ] = None
3007+ return
3008+ param_def .byref = False
29673009
29683010
29693011def p_param_definition (p ):
29703012 """ param_definition : param_def
29713013 """
2972- p [0 ] = p [1 ]
3014+ param_def = p [1 ]
3015+ p [0 ] = param_def
29733016 if p [0 ] is not None :
2974- p [0 ].byref = OPTIONS .byref .value
3017+ if param_def .class_ == CLASS .array :
3018+ param_def .byref = True
3019+ else :
3020+ param_def .byref = OPTIONS .byref .value
3021+
3022+
3023+ def p_param_def_array (p ):
3024+ """ param_def : ID LP RP typedef
3025+ """
3026+ typeref = p [4 ]
3027+ if typeref is None :
3028+ p [0 ] = None
3029+ return
3030+
3031+ lineno = p .lineno (1 )
3032+ id_ = p [1 ]
3033+
3034+ api .check .check_type_is_explicit (lineno , id_ , typeref )
3035+ p [0 ] = make_param_decl (id_ , lineno , typeref , is_array = True )
29753036
29763037
29773038def p_param_def_type (p ):
0 commit comments