3 // Mono.MonoBASIC.Parser.cs (from .jay): The Parser for the MonoBASIC compiler
5 // Author: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com)
7 // Licensed under the terms of the GNU GPL
9 // Copyright (C) 2001 A Rafael D Teixeira
15 namespace Mono.MonoBASIC
19 using System.Reflection;
20 using System.Collections;
25 /// The MonoBASIC Parser
28 public class Parser : GenericParser
33 /// Current block is used to add statements as we find
39 /// Tmp block is used to store block endings in if/select's
44 /// Tmp block is used to store tmp copies of expressions
49 /// Tmp catch is used to store catch clauses in try..catch..finally
51 ArrayList tmp_catch_clauses;
54 /// Current interface is used by the various declaration
55 /// productions in the interface declaration to "add"
56 /// the interfaces as we find them.
58 Interface current_interface;
61 /// This is used by the unary_expression code to resolve
62 /// a name against a parameter.
64 Parameters current_local_parameters;
67 /// This are used when parsing parameters in property
70 Parameters set_parameters;
71 Parameters get_parameters;
74 /// This is used by the sub_header parser to store modifiers
75 /// to be passed to sub/constructor
77 int current_modifiers;
80 /// This is used by the sub_header parser to store attributes
81 /// to be passed to sub/constructor
83 Attributes current_attributes;
86 /// Using during property parsing to describe the implicit
87 /// value parameter that is passed to the "set" accessor
90 string get_implicit_value_parameter_name;
93 // Using during property parsing to describe the implicit
94 // value parameter that is passed to the "set" and "get"accesor
95 // methods (properties and indexers).
97 Expression get_implicit_value_parameter_type;
100 /// Using during property parsing to describe the implicit
101 /// value parameter that is passed to the "set" accessor
104 string set_implicit_value_parameter_name;
107 // Using during property parsing to describe the implicit
108 // value parameter that is passed to the "set" and "get"accesor
109 // methods (properties and indexers).
111 Expression set_implicit_value_parameter_type;
113 Location member_location;
115 // An out-of-band stack.
119 ArrayList current_rank_specifiers;
127 // Expression stack for nested ifs
131 Stack statement_stack;
133 // A stack for With expressions.
138 static public bool InitialOptionExplicit = false;
139 static public bool InitialOptionStrict = false;
140 static public bool InitialOptionCompareBinary = true;
141 static public ArrayList ImportsList = null;
145 bool OptionCompareBinary;
147 static public bool UseExtendedSyntax; // for ".mbs" files
149 bool implicit_modifiers;
151 public override string[] extensions()
153 string [] list = { ".vb", ".mbs" };
160 %token NONE /* This token is never returned by our lexer */
161 %token ERROR // This is used not by the parser, but by the tokenizer.
165 *These are the MonoBASIC keywords
254 %token NOTINHERITABLE
255 %token NOTOVERRIDABLE
310 %token YIELD // MonoBASIC extension
312 /* MonoBASIC single character operators/punctuation. */
314 %token OPEN_BRACKET "["
315 %token CLOSE_BRACKET "]"
316 %token OPEN_PARENS "("
317 %token OPEN_BRACE "{"
318 %token CLOSE_BRACE "}"
319 %token CLOSE_PARENS ")"
335 %token EXCLAMATION "!"
338 %token LONGTYPECHAR "&"
340 %token SINGLETYPECHAR "!"
341 %token NUMBER_SIGN "#"
342 %token DOLAR_SIGN "$"
344 %token ATTR_ASSIGN ":="
346 /* MonoBASIC multi-character operators. */
351 //%token OP_MODULUS //"mod"
352 %token OP_MULT_ASSIGN "*="
353 %token OP_DIV_ASSIGN "/="
354 %token OP_IDIV_ASSIGN "\\="
355 %token OP_ADD_ASSIGN "+="
356 %token OP_SUB_ASSIGN "-="
357 %token OP_CONCAT_ASSIGN "&="
358 %token OP_EXP_ASSIGN "^="
360 /* VB.NET 2003 new bit-shift operators */
361 %token OP_SHIFT_LEFT "<<"
362 %token OP_SHIFT_RIGHT ">>"
365 %token LITERAL_INTEGER "int literal"
366 %token LITERAL_SINGLE "float literal"
367 %token LITERAL_DOUBLE "double literal"
368 %token LITERAL_DECIMAL "decimal literal"
369 %token LITERAL_CHARACTER "character literal"
370 %token LITERAL_STRING "string literal"
371 %token LITERAL_DATE "datetime literal"
375 /* Add precedence rules to solve dangling else s/r conflict */
384 %left OP_SHIFT_LEFT OP_SHIFT_RIGHT
386 %left STAR DIV PERCENT
387 %right BITWISE_NOT CARRET UMINUS
388 %nonassoc OP_INC OP_DEC
390 %left OPEN_BRACKET OPEN_BRACE
395 %start compilation_unit
399 : opt_option_directives
400 opt_imports_directives
409 opt_option_directives
416 | option_directives option_directive
420 : option_explicit_directive
421 | option_strict_directive
422 | option_compare_directive
451 option_explicit_directive
452 : OPTION EXPLICIT on_off EOL
454 if (!UseExtendedSyntax)
455 OptionExplicit = (bool)$3;
458 9999, lexer.Location,
459 "In MonoBASIC extended syntax explicit declaration is always required. So OPTION EXPLICIT is deprecated");
464 option_strict_directive
465 : OPTION STRICT on_off EOL
467 if (!UseExtendedSyntax)
468 OptionStrict = (bool)$3;
471 9999, lexer.Location,
472 "In MonoBASIC extended syntax strict assignability is always required. So OPTION STRICT is deprecated");
476 option_compare_directive
477 : OPTION COMPARE text_or_binary EOL
479 OptionCompareBinary = (bool)$3;
490 | declarations declaration
494 : namespace_declaration
500 if ($1 is Class || $1 is Struct || $1 is Module ){
501 TypeContainer c = (TypeContainer) $1;
502 mod_flags = c.ModFlags;
507 if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
509 1527, lexer.Location,
510 "Namespace elements cannot be explicitly " +
511 "declared private or protected in '" + name + "'");
526 : PERCENT { $$ = TypeManager.system_int32_expr; }
527 | LONGTYPECHAR { $$ = TypeManager.system_int64_expr; }
528 | AT_SIGN { $$ = TypeManager.system_decimal_expr; }
529 | SINGLETYPECHAR { $$ = TypeManager.system_single_expr; }
530 | NUMBER_SIGN { $$ = TypeManager.system_double_expr; }
531 | DOLAR_SIGN { $$ = TypeManager.system_string_expr; }
535 : /* empty */ { $$ = null; }
536 | type_character { $$ = $1; }
542 | qualified_identifier DOT identifier
544 $$ = (($1).ToString ()) + "." + ($3.ToString ());
548 opt_imports_directives
555 | imports_directives imports_directive
559 : IMPORTS imports_terms EOL
564 | imports_terms COMMA imports_terms
568 : qualified_identifier
570 RootContext.SourceBeingCompiled.Imports ((string) $1, lexer.Location);
572 | qualified_identifier ASSIGN qualified_identifier
574 RootContext.SourceBeingCompiled.ImportsWithAlias ((string) $1, (string) $3, lexer.Location);
580 | attribute_sections { $$ = $1; }
586 AttributeSection sect = (AttributeSection) $1;
588 if (sect.Target == "assembly")
589 RootContext.AddGlobalAttributeSection (current_container, sect);
591 $$ = new Attributes ((AttributeSection) $1, lexer.Location);
595 FIXME: we should check if extended syntax is enabled;
596 otherwise an exception should be thrown since VB.NET
597 only allows one attribute section
599 | attribute_sections attribute_section
601 Attributes attrs = null;
602 AttributeSection sect = (AttributeSection) $2;
604 if (sect.Target == "assembly")
605 RootContext.AddGlobalAttributeSection (current_container, sect);
608 attrs = (Attributes) $1;
609 attrs.AddAttributeSection (sect);
617 : OP_LT attribute_target_specifier attribute_list OP_GT
619 string target = null;
622 target = (string) $2;
624 $$ = new AttributeSection (target, (ArrayList) $3);
626 | OP_LT attribute_list OP_GT
628 $$ = new AttributeSection (null, (ArrayList) $2);
632 attribute_target_specifier
633 : attribute_target COLON
642 CheckAttributeTarget ((string) $1);
645 | EVENT { $$ = "event"; }
646 | RETURN { $$ = "return"; }
652 ArrayList attrs = new ArrayList ();
658 | attribute_list COMMA attribute
660 ArrayList attrs = (ArrayList) $1;
672 opt_attribute_arguments
674 $$ = new Mono.MonoBASIC.Attribute ((string) $1, (ArrayList) $3, (Location) $2);
682 opt_attribute_arguments
683 : /* empty */ { $$ = null; }
684 | OPEN_PARENS attribute_arguments CLOSE_PARENS
691 : opt_positional_argument_list
696 ArrayList args = new ArrayList ();
702 | positional_argument_list COMMA named_argument_list
704 ArrayList args = new ArrayList ();
710 | named_argument_list
712 ArrayList args = new ArrayList ();
721 opt_positional_argument_list
722 : /* empty */ { $$ = null; }
723 | positional_argument_list
726 positional_argument_list
729 ArrayList args = new ArrayList ();
730 args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
734 | positional_argument_list COMMA expression
736 ArrayList args = (ArrayList) $1;
737 args.Add (new Argument ((Expression) $3, Argument.AType.Expression));
746 ArrayList args = new ArrayList ();
751 | named_argument_list COMMA named_argument
753 ArrayList args = (ArrayList) $1;
761 : identifier ATTR_ASSIGN expression
763 $$ = new DictionaryEntry (
765 new Argument ((Expression) $3, Argument.AType.Expression));
769 namespace_declaration
770 : opt_attributes NAMESPACE qualified_identifier EOL
772 Attributes attrs = (Attributes) $1;
775 foreach (AttributeSection asec in attrs.AttributeSections)
776 if (asec.Target == "assembly")
777 RootContext.AddGlobalAttributeSection (current_container, asec);
780 current_namespace = RootContext.Tree.RecordNamespace(current_namespace, name, (string)$3);
782 opt_imports_directives
786 current_namespace = current_namespace.Parent;
794 current_attributes = (Attributes) $1;
795 current_modifiers = (int) $2;
797 type_spec_declaration
800 type_spec_declaration
803 | interface_declaration
804 | delegate_declaration
810 : CLASS identifier EOL opt_inherits opt_implements
812 // Module members are static by default, but Class *can't* be declared static
813 // so we must fix it, if mbas was the one actually responsible for this
814 // instead of triggering an error.
815 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
816 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
821 name = MakeName ((string) $2);
822 new_class = new Class (current_container, name, current_modifiers,
823 (Attributes) current_attributes, lexer.Location);
825 current_container = new_class;
826 current_container.Namespace = current_namespace;
827 RootContext.Tree.RecordDecl (name, new_class);
829 opt_class_member_declarations
832 Class new_class = (Class) current_container;
833 new_class.Bases = (ArrayList) $4;
835 current_container = current_container.Parent;
836 CheckDef (current_container.AddClass (new_class), new_class.Name, new_class.Location);
843 : /* empty */ { $$ = null; }
844 | INHERITS type_list EOL { $$ = $2; }
848 : /* empty */ { $$ = null; }
849 | IMPLEMENTS type_list EOL { $$ = $2; }
853 : /* empty */ { $$ = (int) 0; current_modifiers = 0; }
854 | modifiers { $$ = $1; current_modifiers = (int) $1; }
864 if ((m1 & m2) != 0) {
865 Location l = lexer.Location;
866 Report.Error (1004, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
868 $$ = (int) (m1 | m2);
873 : PUBLIC { $$ = Modifiers.PUBLIC; }
874 | PROTECTED { $$ = Modifiers.PROTECTED; }
875 | PRIVATE { $$ = Modifiers.PRIVATE; }
876 | SHARED { $$ = Modifiers.STATIC; }
877 | FRIEND { $$ = Modifiers.INTERNAL; }
878 | NOTINHERITABLE { $$ = Modifiers.SEALED; }
879 | OVERRIDABLE { $$ = Modifiers.VIRTUAL; }
880 | NOTOVERRIDABLE { $$ = Modifiers.NONVIRTUAL; }
881 | OVERRIDES { $$ = Modifiers.OVERRIDE; }
882 | OVERLOADS { $$ = Modifiers.NEW; }
883 | SHADOWS { $$ = Modifiers.SHADOWS; }
884 | MUSTINHERIT { $$ = Modifiers.ABSTRACT; }
885 | READONLY { $$ = Modifiers.READONLY; }
886 | DEFAULT { $$ = Modifiers.DEFAULT; }
887 | WRITEONLY { $$ = Modifiers.WRITEONLY; }
891 : MODULE identifier EOL
895 name = MakeName((string) $2);
896 new_module = new Module(current_container,
898 current_modifiers, // already checks then
899 (Attributes) current_attributes,
901 current_container = new_module;
902 current_container.Namespace = current_namespace;
903 RootContext.Tree.RecordDecl(name, new_module);
905 opt_module_member_declarations
908 Module new_module = (Module)current_container;
910 current_container = current_container.Parent;
911 CheckDef (current_container.AddClass(new_module), new_module.Name, new_module.Location);
913 TypeManager.AddStandardModule(new_module);
919 opt_module_member_declarations
921 | module_member_declarations
924 module_member_declarations
925 : module_member_declaration
926 | module_member_declarations module_member_declaration
929 module_member_declaration
933 current_attributes = (Attributes) $1;
934 current_modifiers = ((int)$2) | Modifiers.STATIC;
935 bool explicit_static = (((int) $2 & Modifiers.STATIC) > 0);
936 implicit_modifiers = (!explicit_static);
938 module_member_declarator
940 implicit_modifiers = false;
945 module_member_declarator
946 : constructor_declaration
949 Method method = (Method) $1;
950 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
953 | withevents_declaration /* This is a field but must be treated specially, see below */
954 | constant_declaration
955 | property_declaration
957 | type_spec_declaration
961 : CONST constant_declarators EOL
963 // Module members are static by default, but constants *can't* be declared static
964 // so we must fix it, if mbas was the one actually responsible for this
965 // instead of triggering an error.
966 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
967 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
969 int mod = (int) current_modifiers;
971 // Structure members are Public by default
972 if ((current_container is Struct) && (mod == 0))
973 mod = Modifiers.PUBLIC;
975 ArrayList consts = (ArrayList) $2;
978 VariableDeclaration.FixupTypes ((ArrayList) $2);
979 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
981 foreach (VariableDeclaration var in (ArrayList) $2){
982 Location l = var.Location;
983 Const vconstant = new Const ((Expression)var.type, (String)var.identifier,
984 (Expression)var.expression_or_array_initializer,
985 mod, (Attributes) null, l);
987 CheckDef (current_container.AddConstant (vconstant), vconstant.Name, l);
993 opt_class_member_declarations
995 | class_member_declarations
998 class_member_declarations
999 : class_member_declaration
1000 | class_member_declarations class_member_declaration
1003 class_member_declaration
1007 current_attributes = (Attributes) $1;
1008 current_modifiers = (int) $2;
1010 class_member_declarator
1016 class_member_declarator
1017 : constructor_declaration
1018 | method_declaration
1020 Method method = (Method) $1;
1021 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1024 | constant_declaration
1025 | property_declaration
1027 | withevents_declaration /* This is a field but must be treated specially, see below */
1028 | type_spec_declaration
1035 | must_override_declaration
1038 must_override_declaration
1039 : must_override_sub_declaration
1040 | must_override_func_declaration
1043 must_override_sub_declaration
1044 : MUSTOVERRIDE SUB identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
1046 if (current_container is Module)
1047 Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
1049 if (current_container is Struct)
1050 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1052 current_modifiers |= Modifiers.ABSTRACT;
1054 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $3,
1055 (Parameters) $5, null, null, lexer.Location);
1057 if (!(current_container is Class))
1058 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1060 // FIXME ASAP: This will crash the compiler at resolution time
1066 must_override_func_declaration
1067 : MUSTOVERRIDE FUNCTION identifier opt_type_character OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS opt_type_with_ranks EOL
1069 Expression ftype = ($8 == null) ? (($4 == null) ? TypeManager.
1070 system_object_expr : (Expression) $4 ) : (Expression) $8;
1072 if (current_container is Module)
1073 Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
1075 if (current_container is Struct)
1076 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1078 current_modifiers |= Modifiers.ABSTRACT;
1080 Method method = new Method ((Expression) ftype, (int) current_modifiers,
1081 (string) $3,(Parameters) $6, null, null,
1084 if (!(current_container is Class))
1085 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1092 : SUB identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS opt_evt_handler opt_implement_clause EOL
1094 current_local_parameters = (Parameters) $4;
1097 // Structure members are Public by default
1098 if ((current_container is Struct) && (current_modifiers == 0))
1099 current_modifiers = Modifiers.PUBLIC;
1101 member_location = lexer.Location;
1106 Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $2,
1107 (Parameters) current_local_parameters, (Attributes) current_attributes,
1108 (Expression) $7, member_location);
1110 method.Block = (Block) end_block();
1114 // we have an event handler to take care of
1116 string evt_def = ((MemberAccess)$6).ToString();
1117 int pos = evt_def.LastIndexOf (".");
1118 string evt_target = evt_def.Substring (0, pos);
1121 if (current_container.Properties != null) {
1122 foreach (Property p in current_container.Properties) {
1123 if (p.Name == evt_target) {
1124 Location loc = lexer.Location;
1126 Statement addhnd = (Statement) new AddHandler ((Expression) $6,
1127 DecomposeQI((string) $2, loc),
1128 DecomposeQI(evt_target, loc), loc);
1130 current_container.AddEventHandler (addhnd);
1138 Report.Error(30506, lexer.Location,
1139 evt_target + " is not declared with WithEvents");
1146 : FUNCTION identifier opt_type_character
1147 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS opt_type_with_ranks opt_implement_clause EOL
1149 current_local_parameters = (Parameters) $5;
1150 member_location = lexer.Location;
1153 Expression ftype = ($7 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $7;
1155 // Structure members are Public by default
1156 if ((current_container is Struct) && (current_modifiers == 0))
1157 current_modifiers = Modifiers.PUBLIC;
1158 // Add local var declaration
1160 ArrayList retval = new ArrayList ();
1161 retval.Add (new VariableDeclaration ((string) $2, (Expression) ftype, lexer.Location));
1162 declare_local_variables ((Expression) ftype, retval, lexer.Location);
1167 Expression ftype = ($7 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $7;
1169 Method method = new Method ((Expression) ftype, (int) current_modifiers, (string) $2,
1170 (Parameters) current_local_parameters, (Attributes) current_attributes,/* (Attributes) currx ent_attributes, */
1171 (Expression) $8, member_location);
1172 method.Block = end_block();
1178 : STRUCTURE identifier EOL
1179 opt_implement_clause
1182 string full_struct_name = MakeName ((string) $2);
1184 // Module members are static by default, but structures *can't* be declared static
1185 // so we must fix it, if mbas was the one actually responsible for this
1186 // instead of triggering an error.
1187 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1188 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1190 new_struct = new Struct (current_container, full_struct_name,
1191 (int) current_modifiers,
1192 (Attributes) current_attributes, lexer.Location);
1193 current_container = new_struct;
1194 current_container.Namespace = current_namespace;
1195 RootContext.Tree.RecordDecl (full_struct_name, new_struct);
1197 opt_struct_member_declarations
1199 Struct new_struct = (Struct) current_container;
1202 new_struct.Bases = (ArrayList) $4;
1204 current_container = current_container.Parent;
1205 CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
1211 opt_struct_member_declarations
1213 | struct_member_declarations
1216 struct_member_declarations
1217 : struct_member_declaration
1218 | struct_member_declarations struct_member_declaration
1221 struct_member_declaration
1223 struct_member_declarator
1226 struct_member_declarator
1228 | constant_declaration
1229 | constructor_declaration
1230 | method_declaration
1232 Method method = (Method) $1;
1233 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1235 | property_declaration
1237 | type_spec_declaration
1240 * This is only included so we can flag error 575:
1241 * destructors only allowed on class types
1243 //| destructor_declaration
1247 : EVENT identifier AS type EOL
1249 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
1251 Event e = new Event ((Expression) $4, var.identifier,
1252 null, current_modifiers, null, null,
1253 current_attributes, lexer.Location);
1255 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1258 | EVENT identifier opt_event_params EOL
1260 string delName = (string) $2;
1261 delName = delName + "EventHandler";
1262 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
1263 (current_container, TypeManager.system_void_expr,
1264 (int) current_modifiers, MakeName(delName), (Parameters) $3,
1265 (Attributes) current_attributes, lexer.Location);
1267 del.Namespace = current_namespace;
1268 CheckDef (current_container.AddDelegate (del), del.Name, lexer.Location);
1270 Event e = new Event (DecomposeQI (delName, lexer.Location),
1272 null, current_modifiers, null, null,
1273 current_attributes, lexer.Location);
1275 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1280 : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; }
1281 | OPEN_PARENS CLOSE_PARENS { $$ = Parameters.EmptyReadOnlyParameters; }
1282 | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS { $$ = $2; }
1286 : ENUM identifier opt_type_spec EOL
1287 opt_enum_member_declarations
1289 Location enum_location = lexer.Location;
1290 string full_name = MakeName ((string) $2);
1291 Expression enum_type = ($3 == null) ? TypeManager.system_int32_expr : (Expression) $3;
1292 ArrayList enum_members = (ArrayList) $5;
1294 // Module members are static by default, but enums *can't* be declared static
1295 // so we must fix it if mbas was the one actually responsible for this
1296 // instead of triggering an error.
1297 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1298 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1300 Mono.MonoBASIC.Enum e = new Mono.MonoBASIC.Enum (current_container, enum_type,
1301 (int) current_modifiers, full_name,
1302 (Attributes) current_attributes, enum_location);
1304 foreach (VariableDeclaration ev in enum_members) {
1305 Location loc = (Location) ev.Location;
1307 CheckDef (e.AddEnumMember (ev.identifier,
1308 (Expression) ev.expression_or_array_initializer,
1309 loc, ev.OptAttributes), ev.identifier, loc);
1312 e.Namespace = current_namespace;
1314 CheckDef (current_container.AddEnum (e), full_name, enum_location);
1315 RootContext.Tree.RecordDecl (full_name, e);
1321 opt_enum_member_declarations
1322 : /* empty */ { $$ = new ArrayList (); }
1323 | enum_member_declarations { $$ = $1; }
1326 enum_member_declarations
1327 : enum_member_declaration
1329 ArrayList l = new ArrayList ();
1334 | enum_member_declarations enum_member_declaration
1336 ArrayList l = (ArrayList) $1;
1344 enum_member_declaration
1345 : opt_attributes identifier EOL
1347 $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
1349 | opt_attributes identifier
1351 $$ = lexer.Location;
1353 ASSIGN expression EOL
1355 $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
1359 interface_declaration
1360 : INTERFACE identifier EOL
1362 Interface new_interface;
1363 string full_interface_name = MakeName ((string) $2);
1365 new_interface = new Interface (current_container, full_interface_name, (int) current_modifiers,
1366 (Attributes) current_attributes, lexer.Location);
1367 if (current_interface != null) {
1368 Location l = lexer.Location;
1369 Report.Error (-2, l, "Internal compiler error: interface inside interface");
1371 current_interface = new_interface;
1372 new_interface.Namespace = current_namespace;
1373 RootContext.Tree.RecordDecl (full_interface_name, new_interface);
1378 Interface new_interface = (Interface) current_interface;
1381 new_interface.Bases = (ArrayList) $5;
1383 current_interface = null;
1384 CheckDef (current_container.AddInterface (new_interface),
1385 new_interface.Name, new_interface.Location);
1392 : /* empty */ { $$ = null; }
1397 : INHERITS interface_type_list { $$ = $2; }
1403 ArrayList interfaces = new ArrayList ();
1405 interfaces.Add ($1);
1408 | interface_type_list COMMA interface_type
1410 ArrayList interfaces = (ArrayList) $1;
1411 interfaces.Add ($3);
1417 : opt_interface_member_declarations
1420 opt_interface_member_declarations
1422 | interface_member_declarations
1425 interface_member_declarations
1426 : interface_member_declaration
1427 | interface_member_declarations interface_member_declaration
1430 interface_member_declaration
1431 : interface_method_declaration
1433 InterfaceMethod m = (InterfaceMethod) $1;
1435 CheckDef (current_interface.AddMethod (m), m.Name, m.Location);
1437 | interface_property_declaration
1439 InterfaceProperty p = (InterfaceProperty) $1;
1441 CheckDef (current_interface.AddProperty (p), p.Name, p.Location);
1443 | interface_event_declaration
1445 InterfaceEvent e = (InterfaceEvent) $1;
1447 CheckDef (current_interface.AddEvent (e), e.Name, lexer.Location);
1452 : /* empty */ { $$ = false; }
1453 | NEW { $$ = true; }
1456 interface_method_declaration
1458 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
1460 $$ = new InterfaceMethod (TypeManager.system_void_expr, (string) $2, false,
1461 (Parameters) $4, current_attributes, lexer.Location);
1463 | FUNCTION identifier opt_type_character
1464 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS AS type
1466 if ($3 != null && $3 != $8)
1467 Report.Error (-1, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text
1469 $$ = new InterfaceMethod (
1470 (Expression) $8, (string) $2, false, (Parameters) $5,
1471 current_attributes, lexer.Location);
1473 | FUNCTION identifier type_character
1474 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1476 $$ = new InterfaceMethod (
1477 (Expression) $3, (string) $2, false, (Parameters) $5,
1478 current_attributes, lexer.Location);
1482 interface_property_declaration
1483 : opt_modifiers PROPERTY identifier
1485 opt_formal_parameter_list
1486 CLOSE_PARENS opt_type_spec EOL
1488 // FIXME we MUST pass property parameters
1489 $$ = new InterfaceProperty ((Expression) $6, (string) $2, false,
1490 true, true, current_attributes,
1495 interface_event_declaration
1496 : opt_attributes opt_new EVENT type identifier EOL
1498 $$ = new InterfaceEvent ((Expression) $4, (string) $5, (bool) $2, (Attributes) $1,
1503 property_declaration
1504 : abstruct_propery_declaration
1505 | non_abstruct_propery_declaration
1508 abstruct_propery_declaration
1509 : MUSTOVERRIDE PROPERTY identifier opt_type_character opt_property_parameters AS type EOL
1511 Expression ftype = ($7 == null) ? (($4 == null) ?
1512 TypeManager.system_object_expr : (Expression) $4 ) : (Expression) $7;
1514 if (current_container is Module)
1515 Report.Error (30503, "Properties in a Module cannot be declared 'MustOverride'.");
1517 if (current_container is Struct)
1518 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1520 current_modifiers |= Modifiers.ABSTRACT;
1522 current_local_parameters = (Parameters) $5;
1523 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1524 get_parameters = current_local_parameters.Copy (lexer.Location);
1525 set_parameters = current_local_parameters.Copy (lexer.Location);
1529 get_parameters = Parameters.EmptyReadOnlyParameters;
1530 set_parameters = new Parameters (null, null ,lexer.Location);
1532 Parameter implicit_value_parameter = new Parameter (
1533 ftype, "Value", Parameter.Modifier.NONE, null);
1535 set_parameters.AppendParameter (implicit_value_parameter);
1537 lexer.PropertyParsing = true;
1539 Accessor get_block = new Accessor (null, null);
1540 Accessor set_block = new Accessor (null, null);
1542 Property prop = new Property ((Expression) ftype, (string) $3, current_modifiers,
1543 get_block, set_block, current_attributes, lexer.Location,
1544 null, get_parameters, set_parameters, null);
1546 if (!(current_container is Class))
1547 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1549 CheckDef (current_container.AddProperty (prop), prop.Name, lexer.Location);
1551 get_implicit_value_parameter_type = null;
1552 set_implicit_value_parameter_type = null;
1553 get_parameters = null;
1554 set_parameters = null;
1555 current_local_parameters = null;
1560 non_abstruct_propery_declaration
1561 : PROPERTY identifier opt_type_character opt_property_parameters AS type opt_implement_clause EOL
1563 get_implicit_value_parameter_type =
1564 ($6 == null) ? (($3 == null) ?
1565 TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $6;
1566 get_implicit_value_parameter_name = (string) $2;
1568 current_local_parameters = (Parameters) $4;
1569 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1570 get_parameters = current_local_parameters.Copy (lexer.Location);
1571 set_parameters = current_local_parameters.Copy (lexer.Location);
1575 get_parameters = Parameters.EmptyReadOnlyParameters;
1576 set_parameters = new Parameters (null, null ,lexer.Location);
1578 lexer.PropertyParsing = true;
1580 $$ = lexer.Location;
1582 accessor_declarations
1585 lexer.PropertyParsing = false;
1588 Pair pair = (Pair) $10;
1590 Accessor get_block = null;
1591 Accessor set_block = null;
1593 if (pair.First != null){
1594 get_block = (Accessor) pair.First;
1597 if (pair.Second != null) {
1598 set_block = (Accessor) pair.Second;
1601 Location loc = lexer.Location;
1603 // Structure members are Public by default
1604 if ((current_container is Struct) && (current_modifiers == 0))
1605 current_modifiers = Modifiers.PUBLIC;
1607 prop = new Property ((Expression) /*$6*/ get_implicit_value_parameter_type,
1608 (string) $2, current_modifiers, get_block, set_block,
1609 current_attributes, loc, set_implicit_value_parameter_name,
1610 get_parameters, set_parameters, (Expression) $7);
1612 CheckDef (current_container.AddProperty (prop), prop.Name, loc);
1613 get_implicit_value_parameter_type = null;
1614 set_implicit_value_parameter_type = null;
1615 get_parameters = null;
1616 set_parameters = null;
1617 current_local_parameters = null;
1621 opt_property_parameters
1624 $$ = Parameters.EmptyReadOnlyParameters;
1626 | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1632 opt_implement_clause
1637 | IMPLEMENTS qualified_identifier
1639 $$ = DecomposeQI ((string)$2, lexer.Location);
1643 accessor_declarations
1644 : get_accessor_declaration opt_set_accessor_declaration
1646 $$ = new Pair ($1, $2);
1648 | set_accessor_declaration opt_get_accessor_declaration
1650 $$ = new Pair ($2, $1);
1654 opt_get_accessor_declaration
1655 : /* empty */ { $$ = null; }
1656 | get_accessor_declaration
1659 opt_set_accessor_declaration
1660 : /* empty */ { $$ = null; }
1661 | set_accessor_declaration
1664 get_accessor_declaration
1665 : opt_attributes GET EOL
1667 if ((current_modifiers & Modifiers.WRITEONLY) != 0)
1668 Report.Error (30023, "'WriteOnly' properties cannot have a 'Get' accessor");
1670 current_local_parameters = get_parameters;
1672 lexer.PropertyParsing = false;
1675 // Add local var declaration
1677 ArrayList retval = new ArrayList ();
1678 retval.Add (new VariableDeclaration (get_implicit_value_parameter_name, get_implicit_value_parameter_type, lexer.Location));
1679 declare_local_variables (get_implicit_value_parameter_type, retval, lexer.Location);
1684 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
1685 current_local_parameters = null;
1686 lexer.PropertyParsing = true;
1690 set_accessor_declaration
1691 : opt_attributes SET opt_set_parameter EOL
1693 if ((current_modifiers & Modifiers.READONLY) != 0)
1694 Report.Error (30022, "'ReadOnly' properties cannot have a 'Set' accessor");
1696 Parameter implicit_value_parameter = new Parameter (
1697 set_implicit_value_parameter_type,
1698 set_implicit_value_parameter_name,
1699 Parameter.Modifier.NONE, null);
1701 current_local_parameters = set_parameters;
1702 current_local_parameters.AppendParameter (implicit_value_parameter);
1705 lexer.PropertyParsing = false;
1710 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
1711 current_local_parameters = null;
1712 lexer.PropertyParsing = true;
1719 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type; // TypeManager.system_object_expr;
1720 set_implicit_value_parameter_name = "Value";
1722 |OPEN_PARENS CLOSE_PARENS
1724 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type;
1725 set_implicit_value_parameter_name = "Value";
1727 | OPEN_PARENS opt_parameter_modifier opt_identifier opt_type_spec CLOSE_PARENS
1729 Parameter.Modifier pm = (Parameter.Modifier)$2;
1730 if ((pm | Parameter.Modifier.VAL) != 0)
1731 Report.Error (31065,
1733 "Set cannot have a paremeter modifier other than 'ByVal'");
1735 set_implicit_value_parameter_type = (Expression) $4;
1737 if (set_implicit_value_parameter_type != get_implicit_value_parameter_type)
1738 Report.Error (31064,
1740 "Set value parameter type can not be different from property type");
1743 set_implicit_value_parameter_name = (string) $3;
1745 set_implicit_value_parameter_name = "Value";
1751 variable_declarators EOL
1753 int mod = (int) current_modifiers;
1756 VariableDeclaration.FixupTypes ((ArrayList) $2);
1757 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
1759 if (current_container is Module)
1760 mod = mod | Modifiers.STATIC;
1762 // Structure members are Public by default
1763 if ((current_container is Struct) && (mod == 0))
1764 mod = Modifiers.PUBLIC;
1766 if ((mod & Modifiers.Accessibility) == 0)
1767 mod |= Modifiers.PRIVATE;
1769 foreach (VariableDeclaration var in (ArrayList) $2){
1770 Location l = var.Location;
1771 Field field = new Field (var.type, mod, var.identifier,
1772 var.expression_or_array_initializer,
1773 (Attributes) null, l);
1775 CheckDef (current_container.AddField (field), field.Name, l);
1780 withevents_declaration
1781 : opt_dim_stmt WITHEVENTS variable_declarators EOL
1783 // Module members are static by default, but delegates *can't* be declared static
1784 // so we must fix it, if mbas was the one actually responsible for this
1785 // instead of triggering an error.
1786 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1787 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1789 /* WithEvents Fields must be resolved into properties
1790 with a bit of magic behind the scenes */
1792 VariableDeclaration.FixupTypes ((ArrayList) $3);
1794 foreach (VariableDeclaration var in (ArrayList) $3) {
1795 // 1 - We create a private field
1796 Location l = var.Location;
1798 if ((current_modifiers & Modifiers.STATIC) > 0)
1799 Report.Error (30234, l, "'Static' is not valid on a WithEvents declaration.");
1801 Field field = new Field (var.type, Modifiers.PRIVATE, "_" + var.identifier,
1802 var.expression_or_array_initializer,
1803 (Attributes) null, l);
1805 CheckDef (current_container.AddField (field), field.Name, l);
1807 // 2 - Public property
1809 prop = BuildSimpleProperty (var.type, (string) var.identifier,
1810 field, (int) current_modifiers,
1811 (Attributes) current_attributes, l);
1813 CheckDef (current_container.AddProperty (prop), prop.Name, l);
1823 delegate_declaration
1825 identifier OPEN_PARENS
1826 opt_formal_parameter_list
1830 Location l = lexer.Location;
1831 // Module members are static by default, but delegates *can't* be declared static
1832 // so we must fix it, if mbas was the one actually responsible for this
1833 // instead of triggering an error.
1834 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1835 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1837 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (current_container,
1838 TypeManager.system_void_expr,
1839 (int) current_modifiers,
1840 MakeName ((string) $3), (Parameters) $5,
1841 (Attributes) current_attributes, l);
1843 del.Namespace = current_namespace;
1844 CheckDef (current_container.AddDelegate (del), del.Name, l);
1847 identifier OPEN_PARENS
1848 opt_formal_parameter_list
1849 CLOSE_PARENS opt_type_spec EOL
1851 Location l = lexer.Location;
1853 // Module members are static by default, but delegates *can't* be declared static
1854 // so we must fix it, if mbas was the one actually responsible for this
1855 // instead of triggering an error.
1856 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1857 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1859 Expression ftype = ($7 == null) ? TypeManager.system_object_expr : (Expression) $7;
1861 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (
1863 ftype, (int) current_modifiers, MakeName ((string) $3),
1864 (Parameters) $5, (Attributes) current_attributes, l);
1866 del.Namespace = current_namespace;
1867 CheckDef (current_container.AddDelegate (del), del.Name, l);
1874 | HANDLES qualified_identifier
1876 $$ = (Expression) DecomposeQI ((string)$2, lexer.Location);
1878 | HANDLES MYBASE DOT qualified_identifier
1880 // FIXME: this is blatantly wrong and crash-prone
1881 $$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location);
1887 | OPEN_PARENS CLOSE_PARENS
1890 constructor_declaration
1891 : SUB NEW OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
1893 current_local_parameters = (Parameters) $4;
1895 oob_stack.Push (lexer.Location);
1897 Location l = (Location) oob_stack.Pop ();
1898 $$ = new Constructor ((string) "New", (Parameters) $4, (ConstructorInitializer) null, l);
1903 Constructor c = (Constructor) $1;
1904 c.Block = (Block) end_block();
1905 c.ModFlags = (int) current_modifiers;
1906 c.OptAttributes = current_attributes;
1908 c.Initializer = CheckConstructorInitializer (ref c.Block.statements);
1910 CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
1911 current_local_parameters = null;
1916 opt_formal_parameter_list
1919 $$ = Parameters.EmptyReadOnlyParameters;
1921 | formal_parameter_list
1924 //Parameter p = ((Parameters) $1).FixedParameters[0];
1928 formal_parameter_list
1931 ArrayList pars_list = (ArrayList) $1;
1933 Parameter [] pars = new Parameter [pars_list.Count];
1934 pars_list.CopyTo (pars);
1935 $$ = new Parameters (pars, null, lexer.Location);
1937 | fixed_parameters COMMA parameter_array
1939 ArrayList pars_list = (ArrayList) $1;
1941 Parameter [] pars = new Parameter [pars_list.Count];
1942 pars_list.CopyTo (pars);
1944 $$ = new Parameters (pars, (Parameter) $3, lexer.Location);
1948 $$ = new Parameters (null, (Parameter) $1, lexer.Location);
1955 ArrayList pars = new ArrayList ();
1960 | fixed_parameters COMMA fixed_parameter
1962 ArrayList pars = (ArrayList) $1;
1971 opt_parameter_modifier
1972 identifier opt_type_character opt_rank_specifiers opt_type_spec opt_variable_initializer
1974 Parameter.Modifier pm = (Parameter.Modifier)$2;
1975 bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
1978 if (opt_parm && ($7 == null))
1979 Report.Error (999, "Optional parameters must have a default value");
1982 if ((pm & Parameter.Modifier.REF) !=0)
1983 pm = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF;
1985 pm = Parameter.Modifier.NONE; //FIXME: should take into account BYREF
1988 if ($4 != null && $6 != null && $4 != $6)
1989 Report.Error (-1, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text
1991 ptype = (Expression)(($6 == null) ? (($4 == null) ? TypeManager.system_object_expr : $4) : $6);
1993 string t = ptype.ToString() + VariableDeclaration.BuildRank ((ArrayList) $5);
1994 ptype = DecomposeQI (t, lexer.Location);
1996 $$ = new Parameter (ptype, (string) $3, pm,
1997 (Attributes) $1, (Expression) $7, opt_parm);
2002 : PARAM_ARRAY identifier opt_parens AS type
2004 string s_patype = ((Expression) $5).ToString();
2008 Expression patype = DecomposeQI (s_patype, Location.Null);
2009 $$ = new Parameter (patype, (string) $2, Parameter.Modifier.PARAMS, null);
2010 // note ("type must be a single-dimension array type");
2017 | OPEN_PARENS CLOSE_PARENS
2021 opt_parameter_modifier
2022 : /* empty */ { $$ = Parameter.Modifier.VAL; }
2023 | parameter_modifiers { $$ = $1; }
2027 : parameter_modifiers parameter_modifier { $$ = (Parameter.Modifier)$1 | (Parameter.Modifier)$2; }
2028 | parameter_modifier { $$ = $1; }
2032 : BYREF { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
2033 | BYVAL { $$ = Parameter.Modifier.VAL; }
2034 | OPTIONAL { $$ = Parameter.Modifier.OPTIONAL; }
2039 | statement_list end_of_stmt
2044 | statement_list end_of_stmt statement
2048 declaration_statement
2050 if ($1 != null && (Block) $1 != current_block){
2051 current_block.AddStatement ((Statement) $1);
2052 current_block = (Block) $1;
2055 | embedded_statement
2057 Statement s = (Statement) $1;
2059 current_block.AddStatement ((Statement) $1);
2062 | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
2064 AddHandler ((Expression) $2, (string) $5);
2066 | REMOVEHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
2068 RemoveHandler ((Expression) $2, (string) $5);
2070 | RAISEEVENT identifier opt_raise_event_args //OPEN_PARENS opt_argument_list CLOSE_PARENS
2072 RaiseEvent ((string) $2, (ArrayList) $3);
2074 /* | array_handling_statement */
2075 /* | empty_statement */
2078 Statement s = (Statement) $1;
2080 current_block.AddStatement ((Statement) $1);
2084 opt_raise_event_args
2085 : /* empty */ { $$ = null; }
2086 | OPEN_PARENS opt_argument_list CLOSE_PARENS
2093 : identifier COLON end_of_stmt
2095 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2097 if (!current_block.AddLabel ((string) $1, labeled)){
2098 Location l = lexer.Location;
2099 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2101 current_block.AddStatement (labeled);
2107 : expression_statement
2108 | selection_statement
2109 | iteration_statement
2112 | array_handling_statement
2118 $$ = new EmptyStatement ();
2124 : WITH expression end_of_stmt /* was : WITH qualified_identifier end_of_stmt */
2126 // was : Expression e = DecomposeQI ((string) $2, lexer.Location);
2127 Expression e = (Expression) $2;
2134 Block b = end_block();
2141 array_handling_statement
2147 : REDIM opt_preserve redim_clauses
2149 ArrayList list = (ArrayList) $3;
2150 ReDim r = new ReDim (list, (bool) $2, lexer.Location);
2157 : /* empty */ { $$ = false; }
2158 | PRESERVE { $$ = true; }
2164 ArrayList clauses = new ArrayList ();
2169 | redim_clauses COMMA redim_clause
2171 ArrayList clauses = (ArrayList) ($1);
2179 : invocation_expression
2181 Invocation i = (Invocation) $1;
2182 RedimClause rc = new RedimClause (i.expr, i.Arguments);
2188 : ERASE erase_clauses
2190 ArrayList list = (ArrayList) $2;
2191 foreach(Expression e in list)
2193 Erase r = new Erase (e, lexer.Location);
2202 ArrayList clauses = new ArrayList ();
2207 | erase_clauses COMMA erase_clause
2209 ArrayList clauses = (ArrayList) ($1);
2217 : primary_expression
2222 | continue_statement
2223 | */return_statement
2233 $$ = new Goto (current_block, (string) $2, lexer.Location);
2238 : THROW opt_expression
2240 $$ = new Throw ((Expression) $2, lexer.Location);
2247 $$ = new Exit ((ExitType)$2, lexer.Location);
2252 : DO { $$ = ExitType.DO; }
2253 | FOR { $$ = ExitType.FOR; }
2254 | WHILE { $$ = ExitType.WHILE; }
2255 | SELECT { $$ = ExitType.SELECT; }
2256 | SUB { $$ = ExitType.SUB; }
2257 | FUNCTION { $$ = ExitType.FUNCTION; }
2258 | PROPERTY { $$ = ExitType.PROPERTY; }
2259 | TRY { $$ = ExitType.TRY; }
2262 : RETURN opt_expression
2264 $$ = new Return ((Expression) $2, lexer.Location);
2276 : FOR EACH identifier IN
2278 oob_stack.Push (lexer.Location);
2280 expression end_of_stmt
2284 Block foreach_block = current_block;
2285 Location l = lexer.Location;
2286 LocalVariableReference v = null;
2289 vi = foreach_block.GetVariableInfo ((string) $3);
2291 // Get a reference to this variable.
2292 v = new LocalVariableReference (foreach_block, (string) $3, l, vi, false);
2295 Report.Error (451, "Name '" + (string) $3 + "' is not declared.");
2302 Block foreach_block = current_block;
2303 LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
2304 Block prev_block = end_block();
2305 Location l = (Location) oob_stack.Pop ();
2309 f = new Foreach (null, v, (Expression) $6, (Statement) $9, l);
2319 if (!UseExtendedSyntax)
2325 if (iterator_container == null){
2326 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2329 iterator_container.SetYields ();
2330 $$ = new Yield ((Expression) $2, lexer.Location);
2335 if (!UseExtendedSyntax)
2341 if (iterator_container == null){
2342 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2345 iterator_container.SetYields ();
2346 $$ = new YieldBreak (lexer.Location);
2366 tmp_catch_clauses = (ArrayList) $5;
2375 ArrayList s = new ArrayList ();
2377 foreach (Catch cc in (ArrayList) tmp_catch_clauses) {
2384 // Now s contains the list of specific catch clauses
2385 // and g contains the general one.
2386 Block b = end_block();
2388 $$ = new Try ((Block) b, s, g, null, lexer.Location);
2395 tmp_block = end_block();
2405 ArrayList s = new ArrayList ();
2406 ArrayList catch_list = (ArrayList) tmp_catch_clauses;
2408 if (catch_list != null){
2409 foreach (Catch cc in catch_list) {
2417 $$ = new Try ((Block) tmp_block, s, g, (Block) end_block(), lexer.Location);
2423 : /* empty */ { $$ = null; }
2430 ArrayList l = new ArrayList ();
2435 | catch_clauses catch_clause
2437 ArrayList l = (ArrayList) $1;
2445 : /* empty */ { $$ = null; }
2450 : CATCH opt_catch_args end_of_stmt
2452 Expression type = null;
2456 DictionaryEntry cc = (DictionaryEntry) $2;
2457 type = (Expression) cc.Key;
2458 id = (string) cc.Value;
2461 ArrayList one = new ArrayList ();
2462 Location loc = lexer.Location;
2464 one.Add (new VariableDeclaration (id, type, loc));
2468 current_block = new Block (current_block);
2469 Block b = declare_local_variables (type, one, loc);
2475 opt_statement_list {
2476 Expression type = null;
2478 Block b_catch = current_block;
2481 DictionaryEntry cc = (DictionaryEntry) $2;
2482 type = (Expression) cc.Key;
2483 id = (string) cc.Value;
2487 // FIXME: I can change this for an assignment.
2489 while (current_block != (Block) $1)
2490 current_block = current_block.Parent;
2494 $$ = new Catch (type, id , (Block)b_catch, lexer.Location);
2499 : /* empty */ { $$ = null; }
2504 : identifier AS type
2506 $$ = new DictionaryEntry ($3, $1);
2512 : DO opt_do_construct end_of_stmt
2515 oob_stack.Push (lexer.Location);
2518 LOOP opt_do_construct
2520 Expression t_before = (Expression) $2;
2521 Expression t_after = (Expression) $7;
2524 if ((t_before != null) && (t_after != null))
2525 Report.Error (30238, "'Loop' cannot have a condition if matching 'Do' has one.");
2527 if ((t_before == null) && (t_after == null))
2528 t = new BoolLiteral (true);
2530 t = (t_before != null) ? t_before : t_after;
2532 DoOptions test_type = (t_before != null) ? DoOptions.TEST_BEFORE : DoOptions.TEST_AFTER;
2534 if (((do_type == DoOptions.WHILE) && (test_type == DoOptions.TEST_BEFORE)) ||
2535 ((do_type == DoOptions.UNTIL) && (test_type == DoOptions.TEST_AFTER)))
2536 t = new Unary (Unary.Operator.LogicalNot, (Expression) t, lexer.Location);
2538 $$ = new Do ((Statement) end_block(), (Expression) t, test_type, lexer.Location);
2543 : /* empty */ { $$ = null; }
2544 | while_or_until boolean_expression
2546 do_type = (DoOptions)$1;
2547 $$ = (Expression) $2;
2552 : WHILE { $$ = DoOptions.WHILE; }
2553 | UNTIL { $$ = DoOptions.UNTIL; }
2560 oob_stack.Push (lexer.Location);
2562 boolean_expression end_of_stmt
2566 Location l = (Location) oob_stack.Pop ();
2567 Block b = end_block();
2568 Expression e = (Expression) $3;
2569 $$ = new While ((Expression) e, (Statement) b, l);
2575 : FOR identifier ASSIGN expression TO expression opt_step end_of_stmt
2582 Block statement = end_block();
2583 Expression for_var = (Expression) DecomposeQI ((string)$2, lexer.Location);;
2585 Expression assign_expr = new Assign (for_var, (Expression) $4, lexer.Location);
2586 Expression test_expr = new Binary (Binary.Operator.LessThanOrEqual,
2587 for_var, (Expression) $6, lexer.Location);
2588 Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
2589 for_var, (Expression) $7, lexer.Location), lexer.Location);
2591 Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, lexer.Location);
2592 Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, lexer.Location);
2594 $$ = new For (assign_stmt, test_expr, step_stmt, statement, lexer.Location);
2599 : /* empty */ { $$ = new IntLiteral ((Int32) 1); }
2600 | STEP expression { $$ = $2; }
2609 : if_statement_open opt_then if_statement_rest
2613 | if_statement_open THEN pre_embedded_statement
2615 Location l = (Location) oob_stack.Pop ();
2616 tmp_expr = (Expression)expr_stack.Pop();
2617 $$ = new If ((Expression) tmp_expr, end_block(), l);
2621 pre_embedded_statement
2622 : embedded_statement
2624 Statement s = (Statement) $1;
2626 current_block.AddStatement ((Statement) $1);
2631 : IF boolean_expression
2633 oob_stack.Push (lexer.Location);
2635 tmp_expr = (Expression) $2;
2636 expr_stack.Push(tmp_expr);
2650 Location l = (Location) oob_stack.Pop ();
2651 Expression expr = (Expression)expr_stack.Pop();
2652 $$ = new If ((Expression) expr, (Statement) end_block(), l);
2658 Block bl = end_block();
2659 tmp_blocks.Push(bl);
2665 Location l = (Location) oob_stack.Pop ();
2666 tmp_expr = (Expression)expr_stack.Pop();
2667 tmp_block = (Block) tmp_blocks.Pop();
2668 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, (Statement) end_block(), l);
2672 ELSEIF boolean_expression opt_then
2674 tmp_expr = (Expression) $4;
2675 expr_stack.Push(tmp_expr);
2676 tmp_block = end_block();
2677 tmp_blocks.Push(tmp_block);
2680 else_if_statement_rest
2682 Statement stmt = (Statement) statement_stack.Pop();
2683 Block bl = (Block) tmp_blocks.Pop();
2684 Expression expr = (Expression)expr_stack.Pop();
2685 Location l = (Location) oob_stack.Pop ();
2686 $$ = (Statement) new If ((Expression) expr, (Statement) bl , stmt , l);
2691 else_if_statement_rest
2696 Location l = (Location) oob_stack.Pop ();
2698 Expression expr = (Expression)expr_stack.Pop();
2699 Statement stmt = (Statement) new If ((Expression) expr, (Statement) end_block(), l);
2700 statement_stack.Push(stmt);
2706 Block bl = end_block();
2707 tmp_blocks.Push(bl);
2713 Location l = (Location) oob_stack.Pop ();
2715 Expression expr = (Expression)expr_stack.Pop();
2716 Block bl = (Block)tmp_blocks.Pop();
2717 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl , (Statement) end_block(), l);
2718 statement_stack.Push(stmt);
2722 ELSEIF boolean_expression opt_then
2724 expr_stack.Push((Expression) $4);
2725 Block bl = end_block();
2726 tmp_blocks.Push(bl);
2729 else_if_statement_rest
2731 Location l = (Location) oob_stack.Pop ();
2733 Statement tmp_stmt = (Statement)statement_stack.Pop();
2734 Block bl = (Block) tmp_blocks.Pop();
2735 Expression expr = (Expression)expr_stack.Pop();
2736 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl, tmp_stmt , l);
2737 statement_stack.Push(stmt);
2742 : SELECT opt_case expression end_of_stmt
2744 oob_stack.Push (lexer.Location);
2745 switch_stack.Push (current_block);
2750 $$ = new Switch ((Expression) $3, (ArrayList) $6, (Location) oob_stack.Pop ());
2751 current_block = (Block) switch_stack.Pop ();
2756 : /* empty */ { $$ = null; }
2757 | case_sections { $$ = $1; }
2761 : case_sections case_section
2763 ArrayList sections = (ArrayList) $1;
2770 ArrayList sections = new ArrayList ();
2784 : CASE case_clauses ends
2790 //Block topmost = current_block;
2791 Block topmost = end_block();
2793 while (topmost.Implicit)
2794 topmost = topmost.Parent;
2796 // FIXME: This is a horrible hack which MUST go
2797 topmost.statements.Add (new Break (lexer.Location));
2798 $$ = new SwitchSection ((ArrayList) $2, topmost);
2801 /* FIXME: we should somehow flag an error
2802 (BC30321 'Case' cannot follow a 'Case Else'
2803 in the same 'Select' statement.)
2804 if Case Else is not the last of the Case clauses
2811 //Block topmost = current_block;
2812 Block topmost = end_block();
2814 while (topmost.Implicit)
2815 topmost = topmost.Parent;
2817 // FIXME: This is a horrible hack which MUST go
2818 topmost.statements.Add (new Break (lexer.Location));
2820 ArrayList a = new ArrayList();
2821 a.Add (new SwitchLabel (null, lexer.Location));
2822 $$ = new SwitchSection ((ArrayList) a, topmost);
2829 ArrayList labels = new ArrayList ();
2834 | case_clauses COMMA case_clause
2836 ArrayList labels = (ArrayList) ($1);
2844 : opt_is comparison_operator expression
2847 $$ = new SwitchLabel ((Expression) $1, lexer.Location);
2869 expression_statement
2870 : statement_expression
2877 statement_expression
2878 : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
2879 | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
2880 | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
2883 object_creation_expression
2884 : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
2886 $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
2890 $$ = new New ((Expression) $2, new ArrayList(), lexer.Location);
2894 array_creation_expression
2895 : object_creation_expression array_initializer
2898 ArrayList dims = new ArrayList();
2900 if (n.Arguments != null) {
2901 foreach (Argument a in n.Arguments) {
2906 Expression atype = n.RequestedType;
2908 ArrayList init = (ArrayList) $2;
2909 if (init.Count == 0)
2912 if (VariableDeclaration.IndexesSpecifiedInRank(dims)) {
2913 VariableDeclaration.VBFixIndexList (ref dims);
2914 $$ = new ArrayCreation (atype, dims, "", init, lexer.Location);
2918 string rank = VariableDeclaration.BuildRank (dims);
2919 $$ = new ArrayCreation (atype, rank, (ArrayList) $2, lexer.Location);
2921 //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
2925 delegate_creation_expression
2926 : NEW type OPEN_PARENS ADDRESSOF expression CLOSE_PARENS
2928 ArrayList args = new ArrayList();
2929 Argument arg = new Argument ((Expression) $5, Argument.AType.Expression);
2932 New n = new New ((Expression) $2, (ArrayList) args, lexer.Location);
2938 : object_creation_expression
2939 | array_creation_expression
2940 | delegate_creation_expression
2943 declaration_statement
2944 : local_variable_declaration
2947 DictionaryEntry de = (DictionaryEntry) $1;
2949 $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
2952 | local_constant_declaration
2955 DictionaryEntry de = (DictionaryEntry) $1;
2957 $$ = declare_local_constant ((Expression) de.Key, (ArrayList) de.Value);
2962 local_variable_declaration
2963 : DIM variable_declarators
2965 $$ = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), $2);
2970 local_constant_declaration
2971 : CONST constant_declarators
2974 $$ = new DictionaryEntry (DecomposeQI("_local_consts_", lexer.Location), $2);
2980 constant_declarators
2981 : constant_declarator
2983 ArrayList decl = new ArrayList ();
2989 | constant_declarators COMMA constant_declarator
2991 ArrayList decls = (ArrayList) $1;
3000 : variable_name opt_type_decl opt_variable_initializer
3002 VarName vname = (VarName) $1;
3003 string varname = (string) vname.Name;
3004 current_rank_specifiers = (ArrayList) vname.Rank;
3005 object varinit = $3;
3006 ArrayList a_dims = null;
3008 if (varinit == null)
3010 30438, lexer.Location, "Constant should have a value"
3013 if (vname.Type != null && $2 != null)
3015 30302, lexer.Location,
3016 "Type character cannot be used with explicit type declaration" );
3018 Expression vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3020 if (current_rank_specifiers != null)
3022 Report.Error (30424, lexer.Location, "Constant doesn't support array");
3026 $$ = new VariableDeclaration (varname, vartype, varinit, lexer.Location, null);
3030 variable_declarators
3031 : variable_declarator
3033 ArrayList decl = new ArrayList ();
3034 decl.AddRange ((ArrayList) $1);
3037 | variable_declarators COMMA variable_declarator
3039 ArrayList decls = (ArrayList) $1;
3040 decls.AddRange ((ArrayList) $3);
3046 : variable_names opt_type_decl opt_variable_initializer
3048 ArrayList names = (ArrayList) $1;
3049 object varinit = $3;
3050 ArrayList VarDeclarations = new ArrayList();
3052 ArrayList a_dims = null;
3054 if ((names.Count > 1) && (varinit != null))
3056 30671, lexer.Location,
3057 "Multiple variables with single type can not have " +
3058 "a explicit initialization" );
3061 foreach (VarName vname in names)
3063 string varname = (string) vname.Name;
3064 current_rank_specifiers = (ArrayList) vname.Rank;
3068 if(vname.Type != null && $2 != null)
3070 30302, lexer.Location,
3071 "Type character cannot be used with explicit type declaration" );
3073 // Some checking is required for particularly weird declarations
3074 // like Dim a As Integer(,)
3076 vartype = (Expression) ((Pair) $2).First;
3078 /*if ($3 != null && $3 is ArrayList)
3079 Report.Error (205, "End of statement expected.");*/
3081 ArrayList args = (ArrayList) ((Pair) $2).Second;
3082 if (current_rank_specifiers != null)
3083 Report.Error (31087, lexer.Location,
3084 "Array types specified in too many places");
3086 if (VariableDeclaration.IndexesSpecifiedInRank (args))
3087 Report.Error (30638, "Array bounds cannot appear in type specifiers.");
3089 current_rank_specifiers = new ArrayList ();
3090 current_rank_specifiers.Add (args);
3092 /*string s_vartype = vartype.ToString();
3095 for (int x = 0; x < args.Count; x++)
3099 vartype = DecomposeQI(s_vartype, Location.Null); */
3102 vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3104 // if the variable is an array with explicit bound
3105 // and having explicit initialization throw exception
3106 if (current_rank_specifiers != null && varinit != null)
3108 bool broken = false;
3109 foreach (ArrayList exprs in current_rank_specifiers)
3111 foreach (Expression expr in exprs)
3113 if (!((Expression)expr is EmptyExpression ))
3116 30672, lexer.Location,
3117 "Array declared with explicit bound " +
3118 " can not have explicit initialization");
3129 Check for a declaration like Dim a(2) or Dim a(2,3)
3130 If this is the case, we must generate an ArrayCreationExpression
3131 and, in case, add the initializer after the array has been created.
3133 if (VariableDeclaration.IsArrayDecl (this)) {
3134 if (VariableDeclaration.IndexesSpecified(current_rank_specifiers)) {
3135 a_dims = (ArrayList) current_rank_specifiers;
3136 VariableDeclaration.VBFixIndexLists (ref a_dims);
3137 varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, lexer.Location);
3139 vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (this), lexer.Location);
3142 if (vartype is New) {
3143 if (varinit != null) {
3144 Report.Error (30205, lexer.Location, "End of statement expected");
3150 vartype = ((New)vartype).RequestedType;
3153 VarDeclarations.Add (new VariableDeclaration (varname, vartype, varinit, lexer.Location, null));
3155 $$ = VarDeclarations;
3162 ArrayList list = new ArrayList ();
3166 | variable_names COMMA variable_name
3168 ArrayList list = (ArrayList) $1;
3175 : identifier opt_type_character opt_array_name_modifier
3177 $$ = new VarName ($1, $2, $3);
3188 $$ = (Expression) $2;
3194 | AS type rank_specifiers
3196 $$ = TypeManager.system_object_expr;
3205 | AS type OPEN_PARENS /*opt_argument_list*/ opt_dim_separators CLOSE_PARENS
3207 $$ = new Pair ($2, $4);
3211 New n = new New ((Expression)$3, null, lexer.Location);
3212 $$ = (Expression) n;
3214 | AS NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
3216 New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
3217 $$ = (Expression) n;
3219 | AS NEW type OPEN_PARENS ADDRESSOF expression CLOSE_PARENS
3221 ArrayList args = new ArrayList();
3222 Argument arg = new Argument ((Expression) $6, Argument.AType.Expression);
3225 New n = new New ((Expression)$3, (ArrayList) args, lexer.Location);
3226 $$ = (Expression) n;
3230 opt_array_name_modifier
3231 : /* empty */ { $$ = null; }
3232 | array_type_modifier { $$ = $1; }
3236 : rank_specifiers { $$ = $1; }
3239 opt_variable_initializer
3240 : /* empty */ { $$ = null; }
3241 | ASSIGN variable_initializer { $$ = $2; }
3244 variable_initializer
3257 : OPEN_BRACE CLOSE_BRACE
3259 ArrayList list = new ArrayList ();
3262 | OPEN_BRACE variable_initializer_list CLOSE_BRACE
3264 $$ = (ArrayList) $2;
3268 variable_initializer_list
3269 : variable_initializer
3271 ArrayList list = new ArrayList ();
3275 | variable_initializer_list COMMA variable_initializer
3277 ArrayList list = (ArrayList) $1;
3298 ArrayList rs = new ArrayList();
3302 | rank_specifiers rank_specifier
3304 ArrayList rs = (ArrayList) $1;
3311 : OPEN_PARENS opt_dim_separators CLOSE_PARENS
3320 ArrayList ds = new ArrayList();
3321 ds.Add (new EmptyExpression());
3326 ArrayList ds = (ArrayList) $1;
3327 ds.Add (new EmptyExpression());
3339 ArrayList ds = new ArrayList();
3340 ds.Add (new EmptyExpression());
3343 | dim_separators COMMA
3345 ArrayList ds = (ArrayList) $1;
3346 ds.Add (new EmptyExpression());
3354 ArrayList ds = new ArrayList();
3355 ds.Add ((Expression) $1);
3358 | dim_specifiers COMMA expression
3360 ArrayList ds = (ArrayList) $1;
3361 ds.Add ((Expression) $3);
3373 | qualified_identifier
3375 string name = (string) $1;
3377 $$ = DecomposeQI (name, lexer.Location);
3379 | parenthesized_expression
3381 | invocation_expression
3393 | LITERAL_DATE { $$ = new DateLiteral ((DateTime)lexer.Value); }
3394 | LITERAL_CHARACTER { $$ = new CharLiteral ((char) lexer.Value); }
3395 | LITERAL_STRING { $$ = new StringLiteral ((string) lexer.Value); }
3396 | NOTHING { $$ = NullLiteral.Null; }
3400 : LITERAL_SINGLE { $$ = new FloatLiteral ((float) lexer.Value); }
3401 | LITERAL_DOUBLE { $$ = new DoubleLiteral ((double) lexer.Value); }
3402 | LITERAL_DECIMAL { $$ = new DecimalLiteral ((decimal) lexer.Value); }
3407 object v = lexer.Value;
3410 $$ = new IntLiteral ((Int32)v);
3411 else if (v is short)
3412 $$ = new ShortLiteral ((Int16)v);
3414 $$ = new LongLiteral ((Int64)v);
3416 Console.WriteLine ("OOPS. Unexpected result from scanner");
3422 : TRUE { $$ = new BoolLiteral (true); }
3423 | FALSE { $$ = new BoolLiteral (false); }
3426 parenthesized_expression
3427 : OPEN_PARENS expression CLOSE_PARENS
3432 : primary_expression DOT identifier
3435 string id_name = (string)$3;
3436 if (id_name.ToUpper() == "NEW")
3438 $$ = new MemberAccess ((Expression) $1, id_name, lexer.Location);
3442 if (with_stack.Count > 0) {
3443 Expression e = (Expression) with_stack.Peek();
3444 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3452 /* | primary_expression DOT NEW
3454 $$ = new MemberAccess ((Expression) $1, (string) ".ctor", lexer.Location);
3456 | predefined_type DOT identifier
3459 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
3462 if (with_stack.Count > 0) {
3463 Expression e = (Expression) with_stack.Peek();
3464 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3478 invocation_expression
3479 : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
3482 Location l = lexer.Location;
3483 Report.Error (1, l, "THIS IS CRAZY");
3485 $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
3486 // Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($3 != null) ? ((ArrayList) $3).Count : 0);
3491 : MYBASE DOT IDENTIFIER
3493 string id_name = (string) $3;
3494 if (id_name.ToUpper() == "NEW")
3496 $$ = new BaseAccess (id_name, lexer.Location);
3500 $$ = new BaseAccess ("New", lexer.Location);
3508 The 'argument' rule returns an 'empty' argument
3509 of type NoArg (used for default arguments in invocations)
3510 if no arguments are actually passed.
3512 If there is only one argument and it is o type NoArg,
3513 we return a null (empty) list
3515 ArrayList args = (ArrayList) $1;
3516 if (args.Count == 1 &&
3517 ((Argument)args[0]).ArgType == Argument.AType.NoArg)
3527 ArrayList list = new ArrayList ();
3531 | argument_list COMMA argument
3533 ArrayList list = (ArrayList) $1;
3542 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
3544 | BYREF variable_reference
3546 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
3550 $$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
3552 /*| ADDRESSOF expression
3554 $$ = new Argument ((Expression) $2, Argument.AType.AddressOf);
3559 : expression {/* note ("section 5.4"); */ $$ = $1; }
3565 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
3570 : conditional_expression { $$ = $1; }
3571 | negation_expression
3572 /*| assignment_expression*/
3583 $$ = new This (current_block, lexer.Location);
3587 // FIXME: This is actually somewhat different from Me
3588 // because it is for accessing static (classifier) methods/properties/fields
3589 $$ = new This (current_block, lexer.Location);
3594 : primary_expression
3595 /*| NOT prefixed_unary_expression
3597 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
3599 | cast_expression */
3603 : cast_operator OPEN_PARENS expression CLOSE_PARENS
3605 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
3607 | CTYPE OPEN_PARENS expression COMMA type CLOSE_PARENS
3609 $$ = new Cast ((Expression) $5, (Expression) $3, lexer.Location);
3614 : CBOOL { $$ = TypeManager.system_boolean_expr; }
3615 | CBYTE { $$ = TypeManager.system_byte_expr; }
3616 | CCHAR { $$ = TypeManager.system_char_expr; }
3617 | CDATE { $$ = TypeManager.system_date_expr; }
3618 | CDBL { $$ = TypeManager.system_double_expr; }
3619 | CDEC { $$ = TypeManager.system_decimal_expr; }
3620 | CINT { $$ = TypeManager.system_int32_expr; }
3621 | CLNG { $$ = TypeManager.system_int64_expr; }
3622 | COBJ { $$ = TypeManager.system_object_expr; }
3623 | CSHORT { $$ = TypeManager.system_int16_expr; }
3624 | CSNG { $$ = TypeManager.system_single_expr; }
3625 | CSTR { $$ = TypeManager.system_string_expr; }
3629 // The idea to split this out is from Rhys' grammar
3630 // to solve the problem with casts.
3632 prefixed_unary_expression
3634 | PLUS prefixed_unary_expression
3636 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
3638 | MINUS prefixed_unary_expression
3640 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
3644 multiplicative_expression
3645 : prefixed_unary_expression
3646 | multiplicative_expression STAR prefixed_unary_expression
3648 $$ = new Binary (Binary.Operator.Multiply,
3649 (Expression) $1, (Expression) $3, lexer.Location);
3651 | multiplicative_expression DIV prefixed_unary_expression
3653 $$ = new Binary (Binary.Operator.Division,
3654 (Expression) $1, (Expression) $3, lexer.Location);
3656 | multiplicative_expression OP_IDIV prefixed_unary_expression
3658 $$ = new Binary (Binary.Operator.Division,
3659 (Expression) $1, (Expression) $3, lexer.Location);
3661 | multiplicative_expression MOD prefixed_unary_expression
3663 $$ = new Binary (Binary.Operator.Modulus,
3664 (Expression) $1, (Expression) $3, lexer.Location);
3669 : multiplicative_expression
3670 | additive_expression PLUS multiplicative_expression
3672 $$ = new Binary (Binary.Operator.Addition,
3673 (Expression) $1, (Expression) $3, lexer.Location);
3675 | additive_expression MINUS multiplicative_expression
3677 $$ = new Binary (Binary.Operator.Subtraction,
3678 (Expression) $1, (Expression) $3, lexer.Location);
3680 | additive_expression OP_CONCAT multiplicative_expression
3682 // FIXME: This should only work for String expressions
3683 // We probably need to use something from the runtime
3684 $$ = new Binary (Binary.Operator.Addition,
3685 (Expression) $1, (Expression) $3, lexer.Location);
3689 relational_expression
3690 : additive_expression
3691 | relational_expression OP_LT additive_expression
3693 $$ = new Binary (Binary.Operator.LessThan,
3694 (Expression) $1, (Expression) $3, lexer.Location);
3696 | relational_expression OP_GT additive_expression
3698 $$ = new Binary (Binary.Operator.GreaterThan,
3699 (Expression) $1, (Expression) $3, lexer.Location);
3701 | relational_expression OP_LE additive_expression
3703 $$ = new Binary (Binary.Operator.LessThanOrEqual,
3704 (Expression) $1, (Expression) $3, lexer.Location);
3706 | relational_expression OP_GE additive_expression
3708 $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
3709 (Expression) $1, (Expression) $3, lexer.Location);
3711 | relational_expression IS unary_expression
3713 $$ = new Binary (Binary.Operator.Equality,
3714 (Expression) $1, (Expression) $3, lexer.Location);
3716 | relational_expression AS type_name
3718 $$ = new As ((Expression) $1, (Expression) $3, lexer.Location);
3723 : relational_expression
3724 | equality_expression ASSIGN relational_expression
3726 $$ = new Binary (Binary.Operator.Equality,
3727 (Expression) $1, (Expression) $3, lexer.Location);
3729 | equality_expression OP_NE relational_expression
3731 $$ = new Binary (Binary.Operator.Inequality,
3732 (Expression) $1, (Expression) $3, lexer.Location);
3737 : equality_expression
3738 | and_expression AND equality_expression
3740 $$ = new Binary (Binary.Operator.BitwiseAnd,
3741 (Expression) $1, (Expression) $3, lexer.Location);
3745 exclusive_or_expression
3747 | exclusive_or_expression OP_XOR and_expression
3749 $$ = new Binary (Binary.Operator.ExclusiveOr,
3750 (Expression) $1, (Expression) $3, lexer.Location);
3754 conditional_and_expression
3755 : exclusive_or_expression
3756 | conditional_and_expression AND exclusive_or_expression
3758 $$ = new Binary (Binary.Operator.LogicalAnd,
3759 (Expression) $1, (Expression) $3, lexer.Location);
3761 | conditional_and_expression ANDALSO exclusive_or_expression
3762 { // FIXME: this is likely to be broken
3763 $$ = new Binary (Binary.Operator.LogicalAnd,
3764 (Expression) $1, (Expression) $3, lexer.Location);
3768 conditional_or_expression
3769 : conditional_and_expression
3770 | conditional_or_expression OR conditional_and_expression
3772 $$ = new Binary (Binary.Operator.LogicalOr,
3773 (Expression) $1, (Expression) $3, lexer.Location);
3775 | conditional_or_expression ORELSE conditional_and_expression
3776 { // FIXME: this is likely to be broken
3777 $$ = new Binary (Binary.Operator.LogicalOr,
3778 (Expression) $1, (Expression) $3, lexer.Location);
3782 conditional_expression
3783 : conditional_or_expression
3786 assignment_expression
3787 : prefixed_unary_expression ASSIGN expression
3789 $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
3791 | prefixed_unary_expression ASSIGN ADDRESSOF expression
3793 ArrayList args = new ArrayList();
3794 Argument arg = new Argument ((Expression) $4, Argument.AType.Expression);
3797 New n = new New ((Expression) $1, (ArrayList) args, lexer.Location);
3798 n.isDelegate = true;
3799 $$ = new Assign ((Expression) $1, (Expression) n, lexer.Location);
3801 | prefixed_unary_expression OP_MULT_ASSIGN expression
3803 Location l = lexer.Location;
3805 $$ = new CompoundAssign (
3806 Binary.Operator.Multiply, (Expression) $1, (Expression) $3, l);
3808 | prefixed_unary_expression OP_DIV_ASSIGN expression
3810 Location l = lexer.Location;
3812 $$ = new CompoundAssign (
3813 Binary.Operator.Division, (Expression) $1, (Expression) $3, l);
3815 | prefixed_unary_expression OP_IDIV_ASSIGN expression
3817 Location l = lexer.Location;
3819 $$ = new CompoundAssign (
3820 Binary.Operator.Division, (Expression) $1, (Expression) $3, l);
3822 | prefixed_unary_expression OP_ADD_ASSIGN expression
3824 Location l = lexer.Location;
3826 $$ = new CompoundAssign (
3827 Binary.Operator.Addition, (Expression) $1, (Expression) $3, l);
3829 | prefixed_unary_expression OP_SUB_ASSIGN expression
3831 Location l = lexer.Location;
3833 $$ = new CompoundAssign (
3834 Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, l);
3836 | prefixed_unary_expression OP_CONCAT_ASSIGN expression
3838 Location l = lexer.Location;
3840 $$ = new CompoundAssign (
3841 Binary.Operator.Addition, (Expression) $1, (Expression) $3, l);
3845 /*constant_expression
3855 : type_name { /* class_type */
3857 This does interfaces, delegates, struct_types, class_types,
3858 parent classes, and more! 4.2
3860 $$ = DecomposeQI ((string) $1, lexer.Location);
3870 ArrayList types = new ArrayList ();
3875 | type_list COMMA type
3877 ArrayList types = (ArrayList) $1;
3885 : namespace_or_type_name
3888 namespace_or_type_name
3889 : qualified_identifier
3892 /* Built-in / Integral types */
3894 : OBJECT { $$ = TypeManager.system_object_expr; }
3895 | STRING { $$ = TypeManager.system_string_expr; }
3896 | BOOLEAN { $$ = TypeManager.system_boolean_expr; }
3897 | DECIMAL { $$ = TypeManager.system_decimal_expr; }
3898 | SINGLE { $$ = TypeManager.system_single_expr; }
3899 | DOUBLE { $$ = TypeManager.system_double_expr; }
3900 | DATE { $$ = TypeManager.system_date_expr; }
3906 | BYTE { $$ = TypeManager.system_byte_expr; }
3907 | SHORT { $$ = TypeManager.system_int16_expr; }
3908 | LONG { $$ = TypeManager.system_int64_expr; }
3909 | INTEGER { $$ = TypeManager.system_int32_expr; }
3910 | CHAR { $$ = TypeManager.system_char_expr; }
3926 public Tokenizer Lexer {
3932 public static Expression DecomposeQI (string name, Location loc)
3936 if (name.IndexOf ('.') == -1){
3937 return new SimpleName (name, loc);
3939 int pos = name.LastIndexOf (".");
3940 string left = name.Substring (0, pos);
3941 string right = name.Substring (pos + 1);
3943 o = DecomposeQI (left, loc);
3945 return new MemberAccess (o, right, loc);
3949 Block declare_local_variables (Expression dummy_type, ArrayList variable_declarators, Location loc)
3951 Block implicit_block;
3952 ArrayList inits = null;
3955 // We use the `Used' property to check whether statements
3956 // have been added to the current block. If so, we need
3957 // to create another block to contain the new declaration
3958 // otherwise, as an optimization, we use the same block to
3959 // add the declaration.
3961 // FIXME: A further optimization is to check if the statements
3962 // that were added were added as part of the initialization
3963 // below. In which case, no other statements have been executed
3964 // and we might be able to reduce the number of blocks for
3965 // situations like this:
3967 // int j = 1; int k = j + 1;
3970 VariableDeclaration.FixupTypes (variable_declarators);
3972 if (current_block.Used) {
3973 implicit_block = new Block (current_block, true, loc, Location.Null);
3974 implicit_block.AddChildVariableNames (current_block);
3976 implicit_block = current_block;
3978 foreach (VariableDeclaration decl in variable_declarators){
3979 Expression type = decl.type;
3980 if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
3981 if (decl.expression_or_array_initializer != null){
3983 inits = new ArrayList ();
3990 return implicit_block;
3992 foreach (VariableDeclaration decl in inits){
3995 Expression type = decl.type;
3997 if ((decl.expression_or_array_initializer is Expression) ||
3998 (decl.expression_or_array_initializer is New)) {
3999 expr = (Expression) decl.expression_or_array_initializer;
4001 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
4003 expr = new ArrayCreation (type, "", init, decl.Location);
4006 LocalVariableReference var;
4007 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
4009 assign = new Assign (var, expr, decl.Location);
4011 implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
4014 return implicit_block;
4017 Block declare_local_constant (Expression dummy_type, ArrayList variable_declarators)
4019 Block implicit_block;
4020 VariableDeclaration.FixupTypes (variable_declarators);
4022 if (current_block.Used)
4023 implicit_block = new Block (current_block, true);
4025 implicit_block = current_block;
4027 foreach (VariableDeclaration decl in variable_declarators){
4028 Expression type = decl.type;
4029 implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
4030 current_local_parameters, decl.Location);
4033 return implicit_block;
4041 public VarName (object n, object t, object r)
4051 // A class used to pass around variable declarations and constants
4053 public class VariableDeclaration {
4054 public string identifier;
4055 public object expression_or_array_initializer;
4056 public Location Location;
4057 public Attributes OptAttributes;
4058 public Expression type;
4059 public ArrayList dims;
4061 public VariableDeclaration (string id, Expression t, object eoai, Location l, Attributes opt_attrs)
4063 this.identifier = id;
4064 this.expression_or_array_initializer = eoai;
4066 this.OptAttributes = opt_attrs;
4071 public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
4075 public VariableDeclaration (string id, Expression t, Location l) : this (id, t, null, l, null)
4079 public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) : this
4080 (id, TypeManager.system_object_expr, eoai, l, opt_attrs)
4084 public static ArrayCreation BuildArrayCreator (Expression vartype, ArrayList a_dims, ArrayList varinit, Location l)
4086 // FIXME : This is broken: only the first rank is parsed
4087 return new ArrayCreation (vartype, (ArrayList) a_dims[0], "", varinit, l);
4090 public static void FixupTypes (ArrayList vars)
4092 int varcount = vars.Count;
4093 VariableDeclaration last_var = (VariableDeclaration) vars[varcount - 1];
4095 if (last_var.type == null)
4096 last_var.type = TypeManager.system_object_expr;
4098 Expression cur_type = last_var.type;
4099 int n = varcount - 1;
4102 VariableDeclaration var = (VariableDeclaration) vars[n--];
4103 if (var.type == null)
4104 var.type = cur_type;
4106 cur_type = var.type;
4110 public static bool IndexesSpecifiedInRank (ArrayList IndexList)
4114 if (IndexList != null) {
4115 foreach (Expression e in IndexList)
4116 if (!(e is EmptyExpression)) {
4125 public static bool IndexesSpecified (ArrayList ranks)
4129 if (ranks != null) {
4130 foreach (ArrayList IndexList in ranks) {
4131 if (IndexesSpecifiedInRank (IndexList)) {
4140 public static string StripDims (string varname, ref string d)
4142 string res = varname;
4145 if (varname.IndexOf("[") >= 0) {
4146 dres = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
4147 res = varname.Substring(0, varname.IndexOf("["));
4153 public static string StripDims (string varname)
4157 return (StripDims(varname, ref dres));
4160 public static string StripIndexesFromDims (string dims)
4162 StringBuilder sb = new StringBuilder();
4164 foreach (char c in dims)
4165 if (c == ',' || c == ']' || c == '[')
4168 return sb.ToString();
4171 public static string BuildRank (ArrayList rank)
4176 for (int x = 0; x < (rank.Count -1 ); x++)
4183 public static string BuildRanks (Parser t)
4187 foreach (ArrayList rank in t.current_rank_specifiers)
4188 res += BuildRank (rank);
4193 public static void VBFixIndexList (ref ArrayList IndexList)
4195 if (IndexList != null) {
4196 for (int x = 0; x < IndexList.Count; x++) {
4197 Expression e = (Expression) IndexList[x];
4198 if (!(e is EmptyExpression)) {
4199 IndexList[x] = new Binary (Binary.Operator.Addition, e, new IntLiteral(1), Location.Null);
4205 public static bool IsArrayDecl (Parser t)
4207 // return (varname.IndexOf("[") >= 0);
4208 return (t.current_rank_specifiers != null);
4211 public static void VBFixIndexLists (ref ArrayList ranks)
4213 if (ranks != null) {
4214 for (int x = 0; x < ranks.Count; x++) {
4215 ArrayList IndexList = (ArrayList) ranks[x];
4216 VBFixIndexList (ref IndexList);
4221 public static void FixupArrayTypes (ArrayList vars)
4223 int varcount = vars.Count;
4226 foreach (VariableDeclaration var in vars) {
4227 if (var.identifier.EndsWith(",")) {
4228 dims = "[" + var.identifier.Substring(var.identifier.IndexOf (","),
4229 var.identifier.LastIndexOf(",")) + "]";
4230 var.identifier = var.identifier.Substring (0, var.identifier.IndexOf (","));
4231 var.type = new ComposedCast (var.type, (string) dims, var.Location);
4238 public Property BuildSimpleProperty (Expression p_type, string name,
4239 Field p_fld, int mod_flags,
4240 Attributes attrs, Location loc)
4243 Block get_block, set_block;
4244 Accessor acc_set, acc_get;
4245 StatementExpression a_set;
4250 Parameter implicit_value_parameter = new Parameter (p_type, "value", Parameter.Modifier.NONE, null);
4251 args = new Parameter [1];
4252 args [0] = implicit_value_parameter;
4254 Parameters set_params = new Parameters (args, null, loc);
4255 a_set = new StatementExpression ((ExpressionStatement) new Assign ((Expression) DecomposeQI(p_fld.Name, loc),
4256 (Expression) new SimpleName("value", loc), loc), loc);
4258 set_block = new Block (current_block, set_params, loc, Location.Null);
4259 set_block.AddStatement ((Statement) a_set);
4260 acc_set = new Accessor (set_block, attrs);
4263 a_get = (Statement) new Return ((Expression) DecomposeQI(p_fld.Name, loc), loc);
4264 get_block = new Block (current_block, null, loc, Location.Null);
4265 get_block.AddStatement ((Statement) a_get);
4266 acc_get = new Accessor (get_block, attrs);
4268 p = new Property (p_type, name, mod_flags, (Accessor) acc_get, (Accessor) acc_set, attrs, loc);
4275 current_block = new Block (current_block, current_local_parameters,
4276 lexer.Location, Location.Null);
4283 while (current_block.Implicit)
4284 current_block = current_block.Parent;
4286 res = current_block;
4288 current_block.SetEndLocation (lexer.Location);
4289 current_block = current_block.Parent;
4294 private void AddHandler (Expression evt_definition, string handler_name)
4296 AddHandler (current_block, evt_definition, handler_name);
4299 void CheckAttributeTarget (string a)
4303 case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
4307 Location l = lexer.Location;
4308 Report.Error (658, l, "`" + a + "' is an invalid attribute target");
4313 private void AddHandler (Block b, Expression evt_id, string handler_name)
4315 Location loc = lexer.Location;
4316 string evt_target = evt_id.ToString();
4317 evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.'));
4318 Statement s = (Statement) new AddHandler (evt_id, DecomposeQI(handler_name, loc), DecomposeQI(evt_target, loc), loc);
4322 private void RaiseEvent (string evt_name, ArrayList args)
4324 Location loc = lexer.Location;
4326 Invocation evt_call = new Invocation (DecomposeQI(evt_name, loc), args, lexer.Location);
4327 Statement s = (Statement)(new StatementExpression ((ExpressionStatement) evt_call, loc));
4328 current_block.AddStatement (s);
4331 private void RemoveHandler (Block b, Expression evt_definition, string handler_name)
4333 Location loc = lexer.Location;
4334 string evt_target = evt_definition.ToString();
4335 evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.'));
4336 Statement s = (Statement) new RemoveHandler (evt_definition, DecomposeQI(handler_name, loc), DecomposeQI(evt_target, loc), loc);
4341 // This method is used to get at the complete string representation of
4342 // a fully-qualified type name, hiding inside a MemberAccess ;-)
4343 // This is necessary because local_variable_type admits primary_expression
4344 // as the type of the variable. So we do some extra checking
4346 string GetQualifiedIdentifier (Expression expr)
4348 if (expr is SimpleName)
4349 return ((SimpleName)expr).Name;
4350 else if (expr is MemberAccess)
4351 return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
4353 throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
4357 private void RemoveHandler (Expression evt_definition, string handler_name)
4359 RemoveHandler (current_block, evt_definition, handler_name);
4362 private ConstructorInitializer CheckConstructorInitializer (ref ArrayList s)
4364 ConstructorInitializer ci = null;
4367 if (s[0] is StatementExpression && ((StatementExpression) s[0]).expr is Invocation) {
4368 Invocation i = (Invocation) ((StatementExpression) s[0]).expr;
4370 if (i.expr is BaseAccess) {
4371 BaseAccess ba = (BaseAccess) i.expr;
4372 if (ba.member == "New" || ba.member == ".ctor") {
4373 ci = new ConstructorBaseInitializer (i.Arguments, current_local_parameters, lexer.Location);
4377 if (i.expr.ToString() == "Mono.MonoBASIC.This..ctor") {
4378 ci = new ConstructorThisInitializer (i.Arguments, current_local_parameters, lexer.Location);
4386 void Error_ExpectingTypeName (Location l, Expression expr)
4388 if (expr is Invocation){
4389 Report.Error (1002, l, "; expected");
4391 Report.Error (-1, l, "Invalid Type definition");
4395 static bool AlwaysAccept (MemberInfo m, object filterCriteria) {
4399 private void ReportError9998()
4401 Report.Error (29998, lexer.Location, "This construct is only available in MonoBASIC extended syntax.");
4404 protected override int parse ()
4406 RootContext.InitializeImports(ImportsList);
4407 current_namespace = new Namespace (null, RootContext.RootNamespace);
4408 current_container = RootContext.Tree.Types;
4409 current_container.Namespace = current_namespace;
4410 oob_stack = new Stack ();
4411 switch_stack = new Stack ();
4412 expr_stack = new Stack ();
4413 tmp_blocks = new Stack();
4414 with_stack = new Stack();
4415 statement_stack = new Stack();
4417 UseExtendedSyntax = name.EndsWith(".mbs");
4418 OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
4419 OptionStrict = InitialOptionStrict || UseExtendedSyntax;
4420 OptionCompareBinary = InitialOptionCompareBinary;
4422 lexer = new Tokenizer (input, name, defines);
4423 StringBuilder value = new StringBuilder ();
4425 if (yacc_verbose_flag)
4426 yyparse (lexer, new yydebug.yyDebugSimple ());
4429 } catch (Exception e) {
4430 Report.Error (29999, lexer.Location, lexer.location + "\nParsing error in " + lexer.ref_name + "\n" + e.ToString());
4433 RootContext.VerifyImports();
4435 return Report.Errors;