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);
1120 foreach (Property p in current_container.Properties) {
1121 if (p.Name == evt_target) {
1122 Location loc = lexer.Location;
1124 Statement addhnd = (Statement) new AddHandler ((Expression) $6,
1125 DecomposeQI((string) $2, loc),
1126 DecomposeQI(evt_target, loc), loc);
1128 current_container.AddEventHandler (addhnd);
1137 : FUNCTION identifier opt_type_character
1138 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS opt_type_with_ranks opt_implement_clause EOL
1140 current_local_parameters = (Parameters) $5;
1141 member_location = lexer.Location;
1144 Expression ftype = ($7 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $7;
1146 // Structure members are Public by default
1147 if ((current_container is Struct) && (current_modifiers == 0))
1148 current_modifiers = Modifiers.PUBLIC;
1149 // Add local var declaration
1151 ArrayList retval = new ArrayList ();
1152 retval.Add (new VariableDeclaration ((string) $2, (Expression) ftype, lexer.Location));
1153 declare_local_variables ((Expression) ftype, retval, lexer.Location);
1158 Expression ftype = ($7 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $7;
1160 Method method = new Method ((Expression) ftype, (int) current_modifiers, (string) $2,
1161 (Parameters) current_local_parameters, (Attributes) current_attributes,/* (Attributes) currx ent_attributes, */
1162 (Expression) $8, member_location);
1163 method.Block = end_block();
1169 : STRUCTURE identifier EOL
1170 opt_implement_clause
1173 string full_struct_name = MakeName ((string) $2);
1175 // Module members are static by default, but structures *can't* be declared static
1176 // so we must fix it, if mbas was the one actually responsible for this
1177 // instead of triggering an error.
1178 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1179 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1181 new_struct = new Struct (current_container, full_struct_name,
1182 (int) current_modifiers,
1183 (Attributes) current_attributes, lexer.Location);
1184 current_container = new_struct;
1185 current_container.Namespace = current_namespace;
1186 RootContext.Tree.RecordDecl (full_struct_name, new_struct);
1188 opt_struct_member_declarations
1190 Struct new_struct = (Struct) current_container;
1193 new_struct.Bases = (ArrayList) $4;
1195 current_container = current_container.Parent;
1196 CheckDef (current_container.AddStruct (new_struct), new_struct.Name, new_struct.Location);
1202 opt_struct_member_declarations
1204 | struct_member_declarations
1207 struct_member_declarations
1208 : struct_member_declaration
1209 | struct_member_declarations struct_member_declaration
1212 struct_member_declaration
1214 struct_member_declarator
1217 struct_member_declarator
1219 | constant_declaration
1220 | constructor_declaration
1221 | method_declaration
1223 Method method = (Method) $1;
1224 CheckDef (current_container.AddMethod (method), method.Name, method.Location);
1226 | property_declaration
1228 | type_spec_declaration
1231 * This is only included so we can flag error 575:
1232 * destructors only allowed on class types
1234 //| destructor_declaration
1238 : EVENT identifier AS type EOL
1240 VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
1242 Event e = new Event ((Expression) $4, var.identifier,
1243 null, current_modifiers, null, null,
1244 current_attributes, lexer.Location);
1246 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1249 | EVENT identifier opt_event_params EOL
1251 string delName = (string) $2;
1252 delName = delName + "EventHandler";
1253 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate
1254 (current_container, TypeManager.system_void_expr,
1255 (int) current_modifiers, MakeName(delName), (Parameters) $3,
1256 (Attributes) current_attributes, lexer.Location);
1258 del.Namespace = current_namespace;
1259 CheckDef (current_container.AddDelegate (del), del.Name, lexer.Location);
1261 Event e = new Event (DecomposeQI (delName, lexer.Location),
1263 null, current_modifiers, null, null,
1264 current_attributes, lexer.Location);
1266 CheckDef (current_container.AddEvent (e), e.Name, e.Location);
1271 : /* empty */ { $$ = Parameters.EmptyReadOnlyParameters; }
1272 | OPEN_PARENS CLOSE_PARENS { $$ = Parameters.EmptyReadOnlyParameters; }
1273 | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS { $$ = $2; }
1277 : ENUM identifier opt_type_spec EOL
1278 opt_enum_member_declarations
1280 Location enum_location = lexer.Location;
1281 string full_name = MakeName ((string) $2);
1282 Expression enum_type = ($3 == null) ? TypeManager.system_int32_expr : (Expression) $3;
1283 ArrayList enum_members = (ArrayList) $5;
1285 // Module members are static by default, but enums *can't* be declared static
1286 // so we must fix it if mbas was the one actually responsible for this
1287 // instead of triggering an error.
1288 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1289 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1291 Mono.MonoBASIC.Enum e = new Mono.MonoBASIC.Enum (current_container, enum_type,
1292 (int) current_modifiers, full_name,
1293 (Attributes) current_attributes, enum_location);
1295 foreach (VariableDeclaration ev in enum_members) {
1296 Location loc = (Location) ev.Location;
1298 CheckDef (e.AddEnumMember (ev.identifier,
1299 (Expression) ev.expression_or_array_initializer,
1300 loc, ev.OptAttributes), ev.identifier, loc);
1303 e.Namespace = current_namespace;
1305 CheckDef (current_container.AddEnum (e), full_name, enum_location);
1306 RootContext.Tree.RecordDecl (full_name, e);
1312 opt_enum_member_declarations
1313 : /* empty */ { $$ = new ArrayList (); }
1314 | enum_member_declarations { $$ = $1; }
1317 enum_member_declarations
1318 : enum_member_declaration
1320 ArrayList l = new ArrayList ();
1325 | enum_member_declarations enum_member_declaration
1327 ArrayList l = (ArrayList) $1;
1335 enum_member_declaration
1336 : opt_attributes identifier EOL
1338 $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
1340 | opt_attributes identifier
1342 $$ = lexer.Location;
1344 ASSIGN expression EOL
1346 $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
1350 interface_declaration
1351 : INTERFACE identifier EOL
1353 Interface new_interface;
1354 string full_interface_name = MakeName ((string) $2);
1356 new_interface = new Interface (current_container, full_interface_name, (int) current_modifiers,
1357 (Attributes) current_attributes, lexer.Location);
1358 if (current_interface != null) {
1359 Location l = lexer.Location;
1360 Report.Error (-2, l, "Internal compiler error: interface inside interface");
1362 current_interface = new_interface;
1363 new_interface.Namespace = current_namespace;
1364 RootContext.Tree.RecordDecl (full_interface_name, new_interface);
1369 Interface new_interface = (Interface) current_interface;
1372 new_interface.Bases = (ArrayList) $5;
1374 current_interface = null;
1375 CheckDef (current_container.AddInterface (new_interface),
1376 new_interface.Name, new_interface.Location);
1383 : /* empty */ { $$ = null; }
1388 : INHERITS interface_type_list { $$ = $2; }
1394 ArrayList interfaces = new ArrayList ();
1396 interfaces.Add ($1);
1399 | interface_type_list COMMA interface_type
1401 ArrayList interfaces = (ArrayList) $1;
1402 interfaces.Add ($3);
1408 : opt_interface_member_declarations
1411 opt_interface_member_declarations
1413 | interface_member_declarations
1416 interface_member_declarations
1417 : interface_member_declaration
1418 | interface_member_declarations interface_member_declaration
1421 interface_member_declaration
1422 : interface_method_declaration
1424 InterfaceMethod m = (InterfaceMethod) $1;
1426 CheckDef (current_interface.AddMethod (m), m.Name, m.Location);
1428 | interface_property_declaration
1430 InterfaceProperty p = (InterfaceProperty) $1;
1432 CheckDef (current_interface.AddProperty (p), p.Name, p.Location);
1434 | interface_event_declaration
1436 InterfaceEvent e = (InterfaceEvent) $1;
1438 CheckDef (current_interface.AddEvent (e), e.Name, lexer.Location);
1443 : /* empty */ { $$ = false; }
1444 | NEW { $$ = true; }
1447 interface_method_declaration
1449 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
1451 $$ = new InterfaceMethod (TypeManager.system_void_expr, (string) $2, false,
1452 (Parameters) $4, current_attributes, lexer.Location);
1454 | FUNCTION identifier opt_type_character
1455 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS AS type
1457 if ($3 != null && $3 != $8)
1458 Report.Error (-1, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text
1460 $$ = new InterfaceMethod (
1461 (Expression) $8, (string) $2, false, (Parameters) $5,
1462 current_attributes, lexer.Location);
1464 | FUNCTION identifier type_character
1465 OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1467 $$ = new InterfaceMethod (
1468 (Expression) $3, (string) $2, false, (Parameters) $5,
1469 current_attributes, lexer.Location);
1473 interface_property_declaration
1474 : opt_modifiers PROPERTY identifier
1476 opt_formal_parameter_list
1477 CLOSE_PARENS opt_type_spec EOL
1479 // FIXME we MUST pass property parameters
1480 $$ = new InterfaceProperty ((Expression) $6, (string) $2, false,
1481 true, true, current_attributes,
1486 interface_event_declaration
1487 : opt_attributes opt_new EVENT type identifier EOL
1489 $$ = new InterfaceEvent ((Expression) $4, (string) $5, (bool) $2, (Attributes) $1,
1494 property_declaration
1495 : abstruct_propery_declaration
1496 | non_abstruct_propery_declaration
1499 abstruct_propery_declaration
1500 : MUSTOVERRIDE PROPERTY identifier opt_type_character opt_property_parameters AS type EOL
1502 Expression ftype = ($7 == null) ? (($4 == null) ?
1503 TypeManager.system_object_expr : (Expression) $4 ) : (Expression) $7;
1505 if (current_container is Module)
1506 Report.Error (30503, "Properties in a Module cannot be declared 'MustOverride'.");
1508 if (current_container is Struct)
1509 Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
1511 current_modifiers |= Modifiers.ABSTRACT;
1513 current_local_parameters = (Parameters) $5;
1514 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1515 get_parameters = current_local_parameters.Copy (lexer.Location);
1516 set_parameters = current_local_parameters.Copy (lexer.Location);
1520 get_parameters = Parameters.EmptyReadOnlyParameters;
1521 set_parameters = new Parameters (null, null ,lexer.Location);
1523 Parameter implicit_value_parameter = new Parameter (
1524 ftype, "Value", Parameter.Modifier.NONE, null);
1526 set_parameters.AppendParameter (implicit_value_parameter);
1528 lexer.PropertyParsing = true;
1530 Accessor get_block = new Accessor (null, null);
1531 Accessor set_block = new Accessor (null, null);
1533 Property prop = new Property ((Expression) ftype, (string) $3, current_modifiers,
1534 get_block, set_block, current_attributes, lexer.Location,
1535 null, get_parameters, set_parameters, null);
1537 if (!(current_container is Class))
1538 Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
1540 CheckDef (current_container.AddProperty (prop), prop.Name, lexer.Location);
1542 get_implicit_value_parameter_type = null;
1543 set_implicit_value_parameter_type = null;
1544 get_parameters = null;
1545 set_parameters = null;
1546 current_local_parameters = null;
1551 non_abstruct_propery_declaration
1552 : PROPERTY identifier opt_type_character opt_property_parameters AS type opt_implement_clause EOL
1554 get_implicit_value_parameter_type =
1555 ($6 == null) ? (($3 == null) ?
1556 TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $6;
1557 get_implicit_value_parameter_name = (string) $2;
1559 current_local_parameters = (Parameters) $4;
1560 if (current_local_parameters != Parameters.EmptyReadOnlyParameters) {
1561 get_parameters = current_local_parameters.Copy (lexer.Location);
1562 set_parameters = current_local_parameters.Copy (lexer.Location);
1566 get_parameters = Parameters.EmptyReadOnlyParameters;
1567 set_parameters = new Parameters (null, null ,lexer.Location);
1569 lexer.PropertyParsing = true;
1571 $$ = lexer.Location;
1573 accessor_declarations
1576 lexer.PropertyParsing = false;
1579 Pair pair = (Pair) $10;
1581 Accessor get_block = null;
1582 Accessor set_block = null;
1584 if (pair.First != null){
1585 get_block = (Accessor) pair.First;
1588 if (pair.Second != null) {
1589 set_block = (Accessor) pair.Second;
1592 Location loc = lexer.Location;
1594 // Structure members are Public by default
1595 if ((current_container is Struct) && (current_modifiers == 0))
1596 current_modifiers = Modifiers.PUBLIC;
1598 prop = new Property ((Expression) /*$6*/ get_implicit_value_parameter_type,
1599 (string) $2, current_modifiers, get_block, set_block,
1600 current_attributes, loc, set_implicit_value_parameter_name,
1601 get_parameters, set_parameters, (Expression) $7);
1603 CheckDef (current_container.AddProperty (prop), prop.Name, loc);
1604 get_implicit_value_parameter_type = null;
1605 set_implicit_value_parameter_type = null;
1606 get_parameters = null;
1607 set_parameters = null;
1608 current_local_parameters = null;
1612 opt_property_parameters
1615 $$ = Parameters.EmptyReadOnlyParameters;
1617 | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
1623 opt_implement_clause
1628 | IMPLEMENTS qualified_identifier
1630 $$ = DecomposeQI ((string)$2, lexer.Location);
1634 accessor_declarations
1635 : get_accessor_declaration opt_set_accessor_declaration
1637 $$ = new Pair ($1, $2);
1639 | set_accessor_declaration opt_get_accessor_declaration
1641 $$ = new Pair ($2, $1);
1645 opt_get_accessor_declaration
1646 : /* empty */ { $$ = null; }
1647 | get_accessor_declaration
1650 opt_set_accessor_declaration
1651 : /* empty */ { $$ = null; }
1652 | set_accessor_declaration
1655 get_accessor_declaration
1656 : opt_attributes GET EOL
1658 if ((current_modifiers & Modifiers.WRITEONLY) != 0)
1659 Report.Error (30023, "'WriteOnly' properties cannot have a 'Get' accessor");
1661 current_local_parameters = get_parameters;
1663 lexer.PropertyParsing = false;
1666 // Add local var declaration
1668 ArrayList retval = new ArrayList ();
1669 retval.Add (new VariableDeclaration (get_implicit_value_parameter_name, get_implicit_value_parameter_type, lexer.Location));
1670 declare_local_variables (get_implicit_value_parameter_type, retval, lexer.Location);
1675 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
1676 current_local_parameters = null;
1677 lexer.PropertyParsing = true;
1681 set_accessor_declaration
1682 : opt_attributes SET opt_set_parameter EOL
1684 if ((current_modifiers & Modifiers.READONLY) != 0)
1685 Report.Error (30022, "'ReadOnly' properties cannot have a 'Set' accessor");
1687 Parameter implicit_value_parameter = new Parameter (
1688 set_implicit_value_parameter_type,
1689 set_implicit_value_parameter_name,
1690 Parameter.Modifier.NONE, null);
1692 current_local_parameters = set_parameters;
1693 current_local_parameters.AppendParameter (implicit_value_parameter);
1696 lexer.PropertyParsing = false;
1701 $$ = new Accessor ((Block) end_block(), (Attributes) $1);
1702 current_local_parameters = null;
1703 lexer.PropertyParsing = true;
1710 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type; // TypeManager.system_object_expr;
1711 set_implicit_value_parameter_name = "Value";
1713 |OPEN_PARENS CLOSE_PARENS
1715 set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type;
1716 set_implicit_value_parameter_name = "Value";
1718 | OPEN_PARENS opt_parameter_modifier opt_identifier opt_type_spec CLOSE_PARENS
1720 Parameter.Modifier pm = (Parameter.Modifier)$2;
1721 if ((pm | Parameter.Modifier.VAL) != 0)
1722 Report.Error (31065,
1724 "Set cannot have a paremeter modifier other than 'ByVal'");
1726 set_implicit_value_parameter_type = (Expression) $4;
1728 if (set_implicit_value_parameter_type != get_implicit_value_parameter_type)
1729 Report.Error (31064,
1731 "Set value parameter type can not be different from property type");
1734 set_implicit_value_parameter_name = (string) $3;
1736 set_implicit_value_parameter_name = "Value";
1742 variable_declarators EOL
1744 int mod = (int) current_modifiers;
1747 VariableDeclaration.FixupTypes ((ArrayList) $2);
1748 VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
1750 if (current_container is Module)
1751 mod = mod | Modifiers.STATIC;
1753 // Structure members are Public by default
1754 if ((current_container is Struct) && (mod == 0))
1755 mod = Modifiers.PUBLIC;
1757 if ((mod & Modifiers.Accessibility) == 0)
1758 mod |= Modifiers.PRIVATE;
1760 foreach (VariableDeclaration var in (ArrayList) $2){
1761 Location l = var.Location;
1762 Field field = new Field (var.type, mod, var.identifier,
1763 var.expression_or_array_initializer,
1764 (Attributes) null, l);
1766 CheckDef (current_container.AddField (field), field.Name, l);
1771 withevents_declaration
1772 : opt_dim_stmt WITHEVENTS variable_declarators EOL
1774 // Module members are static by default, but delegates *can't* be declared static
1775 // so we must fix it, if mbas was the one actually responsible for this
1776 // instead of triggering an error.
1777 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1778 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1780 /* WithEvents Fields must be resolved into properties
1781 with a bit of magic behind the scenes */
1783 VariableDeclaration.FixupTypes ((ArrayList) $3);
1785 foreach (VariableDeclaration var in (ArrayList) $3) {
1786 // 1 - We create a private field
1787 Location l = var.Location;
1789 if ((current_modifiers & Modifiers.STATIC) > 0)
1790 Report.Error (30234, l, "'Static' is not valid on a WithEvents declaration.");
1792 Field field = new Field (var.type, Modifiers.PRIVATE, "_" + var.identifier,
1793 var.expression_or_array_initializer,
1794 (Attributes) null, l);
1796 CheckDef (current_container.AddField (field), field.Name, l);
1798 // 2 - Public property
1800 prop = BuildSimpleProperty (var.type, (string) var.identifier,
1801 field, (int) current_modifiers,
1802 (Attributes) current_attributes, l);
1804 CheckDef (current_container.AddProperty (prop), prop.Name, l);
1814 delegate_declaration
1816 identifier OPEN_PARENS
1817 opt_formal_parameter_list
1821 Location l = lexer.Location;
1822 // Module members are static by default, but delegates *can't* be declared static
1823 // so we must fix it, if mbas was the one actually responsible for this
1824 // instead of triggering an error.
1825 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1826 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1828 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (current_container,
1829 TypeManager.system_void_expr,
1830 (int) current_modifiers,
1831 MakeName ((string) $3), (Parameters) $5,
1832 (Attributes) current_attributes, l);
1834 del.Namespace = current_namespace;
1835 CheckDef (current_container.AddDelegate (del), del.Name, l);
1838 identifier OPEN_PARENS
1839 opt_formal_parameter_list
1840 CLOSE_PARENS AS type EOL
1842 Location l = lexer.Location;
1844 // Module members are static by default, but delegates *can't* be declared static
1845 // so we must fix it, if mbas was the one actually responsible for this
1846 // instead of triggering an error.
1847 if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
1848 current_modifiers = (current_modifiers & ~Modifiers.STATIC);
1850 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (
1852 (Expression) $8, (int) current_modifiers, MakeName ((string) $3),
1853 (Parameters) $5, (Attributes) current_attributes, l);
1855 del.Namespace = current_namespace;
1856 CheckDef (current_container.AddDelegate (del), del.Name, l);
1863 | HANDLES qualified_identifier
1865 $$ = (Expression) DecomposeQI ((string)$2, lexer.Location);
1867 | HANDLES MYBASE DOT qualified_identifier
1869 // FIXME: this is blatantly wrong and crash-prone
1870 $$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location);
1876 | OPEN_PARENS CLOSE_PARENS
1879 constructor_declaration
1880 : SUB NEW OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
1882 current_local_parameters = (Parameters) $4;
1884 oob_stack.Push (lexer.Location);
1886 Location l = (Location) oob_stack.Pop ();
1887 $$ = new Constructor ((string) "New", (Parameters) $4, (ConstructorInitializer) null, l);
1892 Constructor c = (Constructor) $1;
1893 c.Block = (Block) end_block();
1894 c.ModFlags = (int) current_modifiers;
1895 c.OptAttributes = current_attributes;
1897 c.Initializer = CheckConstructorInitializer (ref c.Block.statements);
1899 CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
1900 current_local_parameters = null;
1905 opt_formal_parameter_list
1908 $$ = Parameters.EmptyReadOnlyParameters;
1910 | formal_parameter_list
1913 //Parameter p = ((Parameters) $1).FixedParameters[0];
1917 formal_parameter_list
1920 ArrayList pars_list = (ArrayList) $1;
1922 Parameter [] pars = new Parameter [pars_list.Count];
1923 pars_list.CopyTo (pars);
1924 $$ = new Parameters (pars, null, lexer.Location);
1926 | fixed_parameters COMMA parameter_array
1928 ArrayList pars_list = (ArrayList) $1;
1930 Parameter [] pars = new Parameter [pars_list.Count];
1931 pars_list.CopyTo (pars);
1933 $$ = new Parameters (pars, (Parameter) $3, lexer.Location);
1937 $$ = new Parameters (null, (Parameter) $1, lexer.Location);
1944 ArrayList pars = new ArrayList ();
1949 | fixed_parameters COMMA fixed_parameter
1951 ArrayList pars = (ArrayList) $1;
1960 opt_parameter_modifier
1961 identifier opt_type_character opt_rank_specifiers opt_type_spec opt_variable_initializer
1963 Parameter.Modifier pm = (Parameter.Modifier)$2;
1964 bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
1967 if (opt_parm && ($7 == null))
1968 Report.Error (999, "Optional parameters must have a default value");
1971 if ((pm & Parameter.Modifier.REF) !=0)
1972 pm = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF;
1974 pm = Parameter.Modifier.NONE; //FIXME: should take into account BYREF
1977 if ($4 != null && $6 != null && $4 != $6)
1978 Report.Error (-1, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text
1980 ptype = (Expression)(($6 == null) ? (($4 == null) ? TypeManager.system_object_expr : $4) : $6);
1982 string t = ptype.ToString() + VariableDeclaration.BuildRank ((ArrayList) $5);
1983 ptype = DecomposeQI (t, lexer.Location);
1985 $$ = new Parameter (ptype, (string) $3, pm,
1986 (Attributes) $1, (Expression) $7, opt_parm);
1991 : PARAM_ARRAY identifier opt_parens AS type
1993 string s_patype = ((Expression) $5).ToString();
1997 Expression patype = DecomposeQI (s_patype, Location.Null);
1998 $$ = new Parameter (patype, (string) $2, Parameter.Modifier.PARAMS, null);
1999 // note ("type must be a single-dimension array type");
2006 | OPEN_PARENS CLOSE_PARENS
2010 opt_parameter_modifier
2011 : /* empty */ { $$ = Parameter.Modifier.VAL; }
2012 | parameter_modifiers { $$ = $1; }
2016 : parameter_modifiers parameter_modifier { $$ = (Parameter.Modifier)$1 | (Parameter.Modifier)$2; }
2017 | parameter_modifier { $$ = $1; }
2021 : BYREF { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
2022 | BYVAL { $$ = Parameter.Modifier.VAL; }
2023 | OPTIONAL { $$ = Parameter.Modifier.OPTIONAL; }
2028 | statement_list end_of_stmt
2033 | statement_list end_of_stmt statement
2037 declaration_statement
2039 if ($1 != null && (Block) $1 != current_block){
2040 current_block.AddStatement ((Statement) $1);
2041 current_block = (Block) $1;
2044 | embedded_statement
2046 Statement s = (Statement) $1;
2048 current_block.AddStatement ((Statement) $1);
2051 | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
2053 AddHandler ((Expression) $2, (string) $5);
2055 | RAISEEVENT identifier opt_raise_event_args //OPEN_PARENS opt_argument_list CLOSE_PARENS
2057 RaiseEvent ((string) $2, (ArrayList) $3);
2059 /* | array_handling_statement */
2060 /* | empty_statement */
2063 Statement s = (Statement) $1;
2065 current_block.AddStatement ((Statement) $1);
2069 opt_raise_event_args
2070 : /* empty */ { $$ = null; }
2071 | OPEN_PARENS opt_argument_list CLOSE_PARENS
2078 : identifier COLON end_of_stmt
2080 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2082 if (!current_block.AddLabel ((string) $1, labeled)){
2083 Location l = lexer.Location;
2084 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2086 current_block.AddStatement (labeled);
2092 : expression_statement
2093 | selection_statement
2094 | iteration_statement
2097 | array_handling_statement
2103 $$ = new EmptyStatement ();
2109 : WITH expression end_of_stmt /* was : WITH qualified_identifier end_of_stmt */
2111 // was : Expression e = DecomposeQI ((string) $2, lexer.Location);
2112 Expression e = (Expression) $2;
2119 Block b = end_block();
2126 array_handling_statement
2132 : REDIM opt_preserve redim_clauses
2134 ArrayList list = (ArrayList) $3;
2135 ReDim r = new ReDim (list, (bool) $2, lexer.Location);
2142 : /* empty */ { $$ = false; }
2143 | PRESERVE { $$ = true; }
2149 ArrayList clauses = new ArrayList ();
2154 | redim_clauses COMMA redim_clause
2156 ArrayList clauses = (ArrayList) ($1);
2164 : invocation_expression
2166 Invocation i = (Invocation) $1;
2167 RedimClause rc = new RedimClause (i.expr, i.Arguments);
2173 : ERASE erase_clauses
2175 ArrayList list = (ArrayList) $2;
2176 foreach(Expression e in list)
2178 Erase r = new Erase (e, lexer.Location);
2187 ArrayList clauses = new ArrayList ();
2192 | erase_clauses COMMA erase_clause
2194 ArrayList clauses = (ArrayList) ($1);
2202 : primary_expression
2207 | continue_statement
2208 | */return_statement
2218 $$ = new Goto (current_block, (string) $2, lexer.Location);
2223 : THROW opt_expression
2225 $$ = new Throw ((Expression) $2, lexer.Location);
2232 $$ = new Exit ((ExitType)$2, lexer.Location);
2237 : DO { $$ = ExitType.DO; }
2238 | FOR { $$ = ExitType.FOR; }
2239 | WHILE { $$ = ExitType.WHILE; }
2240 | SELECT { $$ = ExitType.SELECT; }
2241 | SUB { $$ = ExitType.SUB; }
2242 | FUNCTION { $$ = ExitType.FUNCTION; }
2243 | PROPERTY { $$ = ExitType.PROPERTY; }
2244 | TRY { $$ = ExitType.TRY; }
2247 : RETURN opt_expression
2249 $$ = new Return ((Expression) $2, lexer.Location);
2261 : FOR EACH identifier IN
2263 oob_stack.Push (lexer.Location);
2265 expression end_of_stmt
2269 Block foreach_block = current_block;
2270 Location l = lexer.Location;
2271 LocalVariableReference v = null;
2274 vi = foreach_block.GetVariableInfo ((string) $3);
2276 // Get a reference to this variable.
2277 v = new LocalVariableReference (foreach_block, (string) $3, l, vi, false);
2280 Report.Error (451, "Name '" + (string) $3 + "' is not declared.");
2287 Block foreach_block = current_block;
2288 LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
2289 Block prev_block = end_block();
2290 Location l = (Location) oob_stack.Pop ();
2294 f = new Foreach (null, v, (Expression) $6, (Statement) $9, l);
2304 if (!UseExtendedSyntax)
2310 if (iterator_container == null){
2311 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2314 iterator_container.SetYields ();
2315 $$ = new Yield ((Expression) $2, lexer.Location);
2320 if (!UseExtendedSyntax)
2326 if (iterator_container == null){
2327 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2330 iterator_container.SetYields ();
2331 $$ = new YieldBreak (lexer.Location);
2351 tmp_catch_clauses = (ArrayList) $5;
2360 ArrayList s = new ArrayList ();
2362 foreach (Catch cc in (ArrayList) tmp_catch_clauses) {
2369 // Now s contains the list of specific catch clauses
2370 // and g contains the general one.
2371 Block b = end_block();
2373 $$ = new Try ((Block) b, s, g, null, lexer.Location);
2380 tmp_block = end_block();
2390 ArrayList s = new ArrayList ();
2391 ArrayList catch_list = (ArrayList) tmp_catch_clauses;
2393 if (catch_list != null){
2394 foreach (Catch cc in catch_list) {
2402 $$ = new Try ((Block) tmp_block, s, g, (Block) end_block(), lexer.Location);
2408 : /* empty */ { $$ = null; }
2415 ArrayList l = new ArrayList ();
2420 | catch_clauses catch_clause
2422 ArrayList l = (ArrayList) $1;
2430 : /* empty */ { $$ = null; }
2435 : CATCH opt_catch_args end_of_stmt
2437 Expression type = null;
2441 DictionaryEntry cc = (DictionaryEntry) $2;
2442 type = (Expression) cc.Key;
2443 id = (string) cc.Value;
2446 ArrayList one = new ArrayList ();
2447 Location loc = lexer.Location;
2449 one.Add (new VariableDeclaration (id, type, loc));
2453 current_block = new Block (current_block);
2454 Block b = declare_local_variables (type, one, loc);
2460 opt_statement_list {
2461 Expression type = null;
2463 Block b_catch = current_block;
2466 DictionaryEntry cc = (DictionaryEntry) $2;
2467 type = (Expression) cc.Key;
2468 id = (string) cc.Value;
2472 // FIXME: I can change this for an assignment.
2474 while (current_block != (Block) $1)
2475 current_block = current_block.Parent;
2479 $$ = new Catch (type, id , (Block)b_catch, lexer.Location);
2484 : /* empty */ { $$ = null; }
2489 : identifier AS type
2491 $$ = new DictionaryEntry ($3, $1);
2497 : DO opt_do_construct end_of_stmt
2500 oob_stack.Push (lexer.Location);
2503 LOOP opt_do_construct
2505 Expression t_before = (Expression) $2;
2506 Expression t_after = (Expression) $7;
2509 if ((t_before != null) && (t_after != null))
2510 Report.Error (30238, "'Loop' cannot have a condition if matching 'Do' has one.");
2512 if ((t_before == null) && (t_after == null))
2513 t = new BoolLiteral (true);
2515 t = (t_before != null) ? t_before : t_after;
2517 DoOptions test_type = (t_before != null) ? DoOptions.TEST_BEFORE : DoOptions.TEST_AFTER;
2519 if (((do_type == DoOptions.WHILE) && (test_type == DoOptions.TEST_BEFORE)) ||
2520 ((do_type == DoOptions.UNTIL) && (test_type == DoOptions.TEST_AFTER)))
2521 t = new Unary (Unary.Operator.LogicalNot, (Expression) t, lexer.Location);
2523 $$ = new Do ((Statement) end_block(), (Expression) t, test_type, lexer.Location);
2528 : /* empty */ { $$ = null; }
2529 | while_or_until boolean_expression
2531 do_type = (DoOptions)$1;
2532 $$ = (Expression) $2;
2537 : WHILE { $$ = DoOptions.WHILE; }
2538 | UNTIL { $$ = DoOptions.UNTIL; }
2545 oob_stack.Push (lexer.Location);
2547 boolean_expression end_of_stmt
2551 Location l = (Location) oob_stack.Pop ();
2552 Block b = end_block();
2553 Expression e = (Expression) $3;
2554 $$ = new While ((Expression) e, (Statement) b, l);
2560 : FOR identifier ASSIGN expression TO expression opt_step end_of_stmt
2567 Block statement = end_block();
2568 Expression for_var = (Expression) DecomposeQI ((string)$2, lexer.Location);;
2570 Expression assign_expr = new Assign (for_var, (Expression) $4, lexer.Location);
2571 Expression test_expr = new Binary (Binary.Operator.LessThanOrEqual,
2572 for_var, (Expression) $6, lexer.Location);
2573 Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
2574 for_var, (Expression) $7, lexer.Location), lexer.Location);
2576 Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, lexer.Location);
2577 Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, lexer.Location);
2579 $$ = new For (assign_stmt, test_expr, step_stmt, statement, lexer.Location);
2584 : /* empty */ { $$ = new IntLiteral ((Int32) 1); }
2585 | STEP expression { $$ = $2; }
2594 : if_statement_open opt_then if_statement_rest
2598 | if_statement_open THEN pre_embedded_statement
2600 Location l = (Location) oob_stack.Pop ();
2601 tmp_expr = (Expression)expr_stack.Pop();
2602 $$ = new If ((Expression) tmp_expr, end_block(), l);
2606 pre_embedded_statement
2607 : embedded_statement
2609 Statement s = (Statement) $1;
2611 current_block.AddStatement ((Statement) $1);
2616 : IF boolean_expression
2618 oob_stack.Push (lexer.Location);
2620 tmp_expr = (Expression) $2;
2621 expr_stack.Push(tmp_expr);
2635 Location l = (Location) oob_stack.Pop ();
2636 Expression expr = (Expression)expr_stack.Pop();
2637 $$ = new If ((Expression) expr, (Statement) end_block(), l);
2643 Block bl = end_block();
2644 tmp_blocks.Push(bl);
2650 Location l = (Location) oob_stack.Pop ();
2651 tmp_expr = (Expression)expr_stack.Pop();
2652 tmp_block = (Block) tmp_blocks.Pop();
2653 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, (Statement) end_block(), l);
2657 ELSEIF boolean_expression opt_then
2659 tmp_expr = (Expression) $4;
2660 expr_stack.Push(tmp_expr);
2661 tmp_block = end_block();
2662 tmp_blocks.Push(tmp_block);
2665 else_if_statement_rest
2667 Statement stmt = (Statement) statement_stack.Pop();
2668 Block bl = (Block) tmp_blocks.Pop();
2669 Expression expr = (Expression)expr_stack.Pop();
2670 Location l = (Location) oob_stack.Pop ();
2671 $$ = (Statement) new If ((Expression) expr, (Statement) bl , stmt , l);
2676 else_if_statement_rest
2681 Location l = (Location) oob_stack.Pop ();
2683 Expression expr = (Expression)expr_stack.Pop();
2684 Statement stmt = (Statement) new If ((Expression) expr, (Statement) end_block(), l);
2685 statement_stack.Push(stmt);
2691 Block bl = end_block();
2692 tmp_blocks.Push(bl);
2698 Location l = (Location) oob_stack.Pop ();
2700 Expression expr = (Expression)expr_stack.Pop();
2701 Block bl = (Block)tmp_blocks.Pop();
2702 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl , (Statement) end_block(), l);
2703 statement_stack.Push(stmt);
2707 ELSEIF boolean_expression opt_then
2709 expr_stack.Push((Expression) $4);
2710 Block bl = end_block();
2711 tmp_blocks.Push(bl);
2714 else_if_statement_rest
2716 Location l = (Location) oob_stack.Pop ();
2718 Statement tmp_stmt = (Statement)statement_stack.Pop();
2719 Block bl = (Block) tmp_blocks.Pop();
2720 Expression expr = (Expression)expr_stack.Pop();
2721 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl, tmp_stmt , l);
2722 statement_stack.Push(stmt);
2727 : SELECT opt_case expression end_of_stmt
2729 oob_stack.Push (lexer.Location);
2730 switch_stack.Push (current_block);
2735 $$ = new Switch ((Expression) $3, (ArrayList) $6, (Location) oob_stack.Pop ());
2736 current_block = (Block) switch_stack.Pop ();
2741 : /* empty */ { $$ = null; }
2742 | case_sections { $$ = $1; }
2746 : case_sections case_section
2748 ArrayList sections = (ArrayList) $1;
2755 ArrayList sections = new ArrayList ();
2769 : CASE case_clauses ends
2775 //Block topmost = current_block;
2776 Block topmost = end_block();
2778 while (topmost.Implicit)
2779 topmost = topmost.Parent;
2781 // FIXME: This is a horrible hack which MUST go
2782 topmost.statements.Add (new Break (lexer.Location));
2783 $$ = new SwitchSection ((ArrayList) $2, topmost);
2786 /* FIXME: we should somehow flag an error
2787 (BC30321 'Case' cannot follow a 'Case Else'
2788 in the same 'Select' statement.)
2789 if Case Else is not the last of the Case clauses
2796 //Block topmost = current_block;
2797 Block topmost = end_block();
2799 while (topmost.Implicit)
2800 topmost = topmost.Parent;
2802 // FIXME: This is a horrible hack which MUST go
2803 topmost.statements.Add (new Break (lexer.Location));
2805 ArrayList a = new ArrayList();
2806 a.Add (new SwitchLabel (null, lexer.Location));
2807 $$ = new SwitchSection ((ArrayList) a, topmost);
2814 ArrayList labels = new ArrayList ();
2819 | case_clauses COMMA case_clause
2821 ArrayList labels = (ArrayList) ($1);
2829 : opt_is comparison_operator expression
2832 $$ = new SwitchLabel ((Expression) $1, lexer.Location);
2854 expression_statement
2855 : statement_expression
2862 statement_expression
2863 : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
2864 | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
2865 | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
2868 object_creation_expression
2869 : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
2871 $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
2875 $$ = new New ((Expression) $2, new ArrayList(), lexer.Location);
2879 array_creation_expression
2880 : object_creation_expression array_initializer
2883 ArrayList dims = new ArrayList();
2885 if (n.Arguments != null) {
2886 foreach (Argument a in n.Arguments) {
2891 Expression atype = n.RequestedType;
2893 ArrayList init = (ArrayList) $2;
2894 if (init.Count == 0)
2897 if (VariableDeclaration.IndexesSpecifiedInRank(dims)) {
2898 VariableDeclaration.VBFixIndexList (ref dims);
2899 $$ = new ArrayCreation (atype, dims, "", init, lexer.Location);
2903 string rank = VariableDeclaration.BuildRank (dims);
2904 $$ = new ArrayCreation (atype, rank, (ArrayList) $2, lexer.Location);
2906 //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
2910 delegate_creation_expression
2911 : NEW type OPEN_PARENS ADDRESSOF opt_argument_list CLOSE_PARENS
2913 New n = new New ((Expression) $2, (ArrayList) $5, lexer.Location);
2915 Console.WriteLine("empty");
2921 : object_creation_expression
2922 | array_creation_expression
2923 | delegate_creation_expression
2926 declaration_statement
2927 : local_variable_declaration
2930 DictionaryEntry de = (DictionaryEntry) $1;
2932 $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
2935 | local_constant_declaration
2938 DictionaryEntry de = (DictionaryEntry) $1;
2940 $$ = declare_local_constant ((Expression) de.Key, (ArrayList) de.Value);
2945 local_variable_declaration
2946 : DIM variable_declarators
2948 $$ = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), $2);
2953 local_constant_declaration
2954 : CONST constant_declarators
2957 $$ = new DictionaryEntry (DecomposeQI("_local_consts_", lexer.Location), $2);
2963 constant_declarators
2964 : constant_declarator
2966 ArrayList decl = new ArrayList ();
2972 | constant_declarators COMMA constant_declarator
2974 ArrayList decls = (ArrayList) $1;
2983 : variable_name opt_type_decl opt_variable_initializer
2985 VarName vname = (VarName) $1;
2986 string varname = (string) vname.Name;
2987 current_rank_specifiers = (ArrayList) vname.Rank;
2988 object varinit = $3;
2989 ArrayList a_dims = null;
2991 if (varinit == null)
2993 30438, lexer.Location, "Constant should have a value"
2996 if (vname.Type != null && $2 != null)
2998 30302, lexer.Location,
2999 "Type character cannot be used with explicit type declaration" );
3001 Expression vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3003 if (current_rank_specifiers != null)
3005 Report.Error (30424, lexer.Location, "Constant doesn't support array");
3009 $$ = new VariableDeclaration (varname, vartype, varinit, lexer.Location, null);
3013 variable_declarators
3014 : variable_declarator
3016 ArrayList decl = new ArrayList ();
3017 decl.AddRange ((ArrayList) $1);
3020 | variable_declarators COMMA variable_declarator
3022 ArrayList decls = (ArrayList) $1;
3023 decls.AddRange ((ArrayList) $3);
3029 : variable_names opt_type_decl opt_variable_initializer
3031 ArrayList names = (ArrayList) $1;
3032 object varinit = $3;
3033 ArrayList VarDeclarations = new ArrayList();
3035 ArrayList a_dims = null;
3037 if ((names.Count > 1) && (varinit != null))
3039 30671, lexer.Location,
3040 "Multiple variables with single type can not have " +
3041 "a explicit initialization" );
3044 foreach (VarName vname in names)
3046 string varname = (string) vname.Name;
3047 current_rank_specifiers = (ArrayList) vname.Rank;
3051 if(vname.Type != null && $2 != null)
3053 30302, lexer.Location,
3054 "Type character cannot be used with explicit type declaration" );
3056 // Some checking is required for particularly weird declarations
3057 // like Dim a As Integer(,)
3059 vartype = (Expression) ((Pair) $2).First;
3061 /*if ($3 != null && $3 is ArrayList)
3062 Report.Error (205, "End of statement expected.");*/
3064 ArrayList args = (ArrayList) ((Pair) $2).Second;
3065 if (current_rank_specifiers != null)
3066 Report.Error (31087, lexer.Location,
3067 "Array types specified in too many places");
3069 if (VariableDeclaration.IndexesSpecifiedInRank (args))
3070 Report.Error (30638, "Array bounds cannot appear in type specifiers.");
3072 current_rank_specifiers = new ArrayList ();
3073 current_rank_specifiers.Add (args);
3075 /*string s_vartype = vartype.ToString();
3078 for (int x = 0; x < args.Count; x++)
3082 vartype = DecomposeQI(s_vartype, Location.Null); */
3085 vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3087 // if the variable is an array with explicit bound
3088 // and having explicit initialization throw exception
3089 if (current_rank_specifiers != null && varinit != null)
3091 bool broken = false;
3092 foreach (ArrayList exprs in current_rank_specifiers)
3094 foreach (Expression expr in exprs)
3096 if (!((Expression)expr is EmptyExpression ))
3099 30672, lexer.Location,
3100 "Array declared with explicit bound " +
3101 " can not have explicit initialization");
3112 Check for a declaration like Dim a(2) or Dim a(2,3)
3113 If this is the case, we must generate an ArrayCreationExpression
3114 and, in case, add the initializer after the array has been created.
3116 if (VariableDeclaration.IsArrayDecl (this)) {
3117 if (VariableDeclaration.IndexesSpecified(current_rank_specifiers)) {
3118 a_dims = (ArrayList) current_rank_specifiers;
3119 VariableDeclaration.VBFixIndexLists (ref a_dims);
3120 varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, lexer.Location);
3122 vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (this), lexer.Location);
3125 if (vartype is New) {
3126 if (varinit != null) {
3127 Report.Error (30205, lexer.Location, "End of statement expected");
3133 vartype = ((New)vartype).RequestedType;
3136 VarDeclarations.Add (new VariableDeclaration (varname, vartype, varinit, lexer.Location, null));
3138 $$ = VarDeclarations;
3145 ArrayList list = new ArrayList ();
3149 | variable_names COMMA variable_name
3151 ArrayList list = (ArrayList) $1;
3158 : identifier opt_type_character opt_array_name_modifier
3160 $$ = new VarName ($1, $2, $3);
3171 $$ = (Expression) $2;
3177 | AS type rank_specifiers
3179 $$ = TypeManager.system_object_expr;
3188 | AS type OPEN_PARENS /*opt_argument_list*/ opt_dim_separators CLOSE_PARENS
3190 $$ = new Pair ($2, $4);
3194 New n = new New ((Expression)$3, null, lexer.Location);
3195 $$ = (Expression) n;
3197 | AS NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
3199 New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
3200 $$ = (Expression) n;
3202 | AS NEW type OPEN_PARENS ADDRESSOF opt_argument_list CLOSE_PARENS
3204 New n = new New ((Expression)$3, (ArrayList) $6, lexer.Location);
3205 $$ = (Expression) n;
3209 opt_array_name_modifier
3210 : /* empty */ { $$ = null; }
3211 | array_type_modifier { $$ = $1; }
3215 : rank_specifiers { $$ = $1; }
3218 opt_variable_initializer
3219 : /* empty */ { $$ = null; }
3220 | ASSIGN variable_initializer { $$ = $2; }
3223 variable_initializer
3236 : OPEN_BRACE CLOSE_BRACE
3238 ArrayList list = new ArrayList ();
3241 | OPEN_BRACE variable_initializer_list CLOSE_BRACE
3243 $$ = (ArrayList) $2;
3247 variable_initializer_list
3248 : variable_initializer
3250 ArrayList list = new ArrayList ();
3254 | variable_initializer_list COMMA variable_initializer
3256 ArrayList list = (ArrayList) $1;
3277 ArrayList rs = new ArrayList();
3281 | rank_specifiers rank_specifier
3283 ArrayList rs = (ArrayList) $1;
3290 : OPEN_PARENS opt_dim_separators CLOSE_PARENS
3299 ArrayList ds = new ArrayList();
3300 ds.Add (new EmptyExpression());
3305 ArrayList ds = (ArrayList) $1;
3306 ds.Add (new EmptyExpression());
3318 ArrayList ds = new ArrayList();
3319 ds.Add (new EmptyExpression());
3322 | dim_separators COMMA
3324 ArrayList ds = (ArrayList) $1;
3325 ds.Add (new EmptyExpression());
3333 ArrayList ds = new ArrayList();
3334 ds.Add ((Expression) $1);
3337 | dim_specifiers COMMA expression
3339 ArrayList ds = (ArrayList) $1;
3340 ds.Add ((Expression) $3);
3352 | qualified_identifier
3354 string name = (string) $1;
3356 $$ = DecomposeQI (name, lexer.Location);
3358 | parenthesized_expression
3360 | invocation_expression
3372 | LITERAL_DATE { $$ = new DateLiteral ((DateTime)lexer.Value); }
3373 | LITERAL_CHARACTER { $$ = new CharLiteral ((char) lexer.Value); }
3374 | LITERAL_STRING { $$ = new StringLiteral ((string) lexer.Value); }
3375 | NOTHING { $$ = NullLiteral.Null; }
3379 : LITERAL_SINGLE { $$ = new FloatLiteral ((float) lexer.Value); }
3380 | LITERAL_DOUBLE { $$ = new DoubleLiteral ((double) lexer.Value); }
3381 | LITERAL_DECIMAL { $$ = new DecimalLiteral ((decimal) lexer.Value); }
3386 object v = lexer.Value;
3389 $$ = new IntLiteral ((Int32)v);
3390 else if (v is short)
3391 $$ = new ShortLiteral ((Int16)v);
3393 $$ = new LongLiteral ((Int64)v);
3395 Console.WriteLine ("OOPS. Unexpected result from scanner");
3401 : TRUE { $$ = new BoolLiteral (true); }
3402 | FALSE { $$ = new BoolLiteral (false); }
3405 parenthesized_expression
3406 : OPEN_PARENS expression CLOSE_PARENS
3411 : primary_expression DOT identifier
3414 string id_name = (string)$3;
3415 if (id_name.ToUpper() == "NEW")
3417 $$ = new MemberAccess ((Expression) $1, id_name, lexer.Location);
3421 if (with_stack.Count > 0) {
3422 Expression e = (Expression) with_stack.Peek();
3423 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3431 /* | primary_expression DOT NEW
3433 $$ = new MemberAccess ((Expression) $1, (string) ".ctor", lexer.Location);
3435 | predefined_type DOT identifier
3438 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
3441 if (with_stack.Count > 0) {
3442 Expression e = (Expression) with_stack.Peek();
3443 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3457 invocation_expression
3458 : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
3461 Location l = lexer.Location;
3462 Report.Error (1, l, "THIS IS CRAZY");
3464 $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
3465 // Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($3 != null) ? ((ArrayList) $3).Count : 0);
3470 : MYBASE DOT IDENTIFIER
3472 string id_name = (string) $3;
3473 if (id_name.ToUpper() == "NEW")
3475 $$ = new BaseAccess (id_name, lexer.Location);
3479 $$ = new BaseAccess ("New", lexer.Location);
3487 The 'argument' rule returns an 'empty' argument
3488 of type NoArg (used for default arguments in invocations)
3489 if no arguments are actually passed.
3491 If there is only one argument and it is o type NoArg,
3492 we return a null (empty) list
3494 ArrayList args = (ArrayList) $1;
3495 if (args.Count == 1 &&
3496 ((Argument)args[0]).ArgType == Argument.AType.NoArg)
3506 ArrayList list = new ArrayList ();
3510 | argument_list COMMA argument
3512 ArrayList list = (ArrayList) $1;
3521 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
3523 | BYREF variable_reference
3525 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
3529 $$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
3534 : expression {/* note ("section 5.4"); */ $$ = $1; }
3540 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
3545 : conditional_expression { $$ = $1; }
3546 | negation_expression
3547 /*| assignment_expression*/
3558 $$ = new This (current_block, lexer.Location);
3562 // FIXME: This is actually somewhat different from Me
3563 // because it is for accessing static (classifier) methods/properties/fields
3564 $$ = new This (current_block, lexer.Location);
3569 : primary_expression
3570 /*| NOT prefixed_unary_expression
3572 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
3574 | cast_expression */
3578 : cast_operator OPEN_PARENS expression CLOSE_PARENS
3580 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
3582 | CTYPE OPEN_PARENS expression COMMA type CLOSE_PARENS
3584 $$ = new Cast ((Expression) $5, (Expression) $3, lexer.Location);
3589 : CBOOL { $$ = TypeManager.system_boolean_expr; }
3590 | CBYTE { $$ = TypeManager.system_byte_expr; }
3591 | CCHAR { $$ = TypeManager.system_char_expr; }
3592 | CDATE { $$ = TypeManager.system_date_expr; }
3593 | CDBL { $$ = TypeManager.system_double_expr; }
3594 | CDEC { $$ = TypeManager.system_decimal_expr; }
3595 | CINT { $$ = TypeManager.system_int32_expr; }
3596 | CLNG { $$ = TypeManager.system_int64_expr; }
3597 | COBJ { $$ = TypeManager.system_object_expr; }
3598 | CSHORT { $$ = TypeManager.system_int16_expr; }
3599 | CSNG { $$ = TypeManager.system_single_expr; }
3600 | CSTR { $$ = TypeManager.system_string_expr; }
3604 // The idea to split this out is from Rhys' grammar
3605 // to solve the problem with casts.
3607 prefixed_unary_expression
3609 | PLUS prefixed_unary_expression
3611 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
3613 | MINUS prefixed_unary_expression
3615 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
3619 multiplicative_expression
3620 : prefixed_unary_expression
3621 | multiplicative_expression STAR prefixed_unary_expression
3623 $$ = new Binary (Binary.Operator.Multiply,
3624 (Expression) $1, (Expression) $3, lexer.Location);
3626 | multiplicative_expression DIV prefixed_unary_expression
3628 $$ = new Binary (Binary.Operator.Division,
3629 (Expression) $1, (Expression) $3, lexer.Location);
3631 | multiplicative_expression OP_IDIV prefixed_unary_expression
3633 $$ = new Binary (Binary.Operator.Division,
3634 (Expression) $1, (Expression) $3, lexer.Location);
3636 | multiplicative_expression MOD prefixed_unary_expression
3638 $$ = new Binary (Binary.Operator.Modulus,
3639 (Expression) $1, (Expression) $3, lexer.Location);
3644 : multiplicative_expression
3645 | additive_expression PLUS multiplicative_expression
3647 $$ = new Binary (Binary.Operator.Addition,
3648 (Expression) $1, (Expression) $3, lexer.Location);
3650 | additive_expression MINUS multiplicative_expression
3652 $$ = new Binary (Binary.Operator.Subtraction,
3653 (Expression) $1, (Expression) $3, lexer.Location);
3655 | additive_expression OP_CONCAT multiplicative_expression
3657 // FIXME: This should only work for String expressions
3658 // We probably need to use something from the runtime
3659 $$ = new Binary (Binary.Operator.Addition,
3660 (Expression) $1, (Expression) $3, lexer.Location);
3664 relational_expression
3665 : additive_expression
3666 | relational_expression OP_LT additive_expression
3668 $$ = new Binary (Binary.Operator.LessThan,
3669 (Expression) $1, (Expression) $3, lexer.Location);
3671 | relational_expression OP_GT additive_expression
3673 $$ = new Binary (Binary.Operator.GreaterThan,
3674 (Expression) $1, (Expression) $3, lexer.Location);
3676 | relational_expression OP_LE additive_expression
3678 $$ = new Binary (Binary.Operator.LessThanOrEqual,
3679 (Expression) $1, (Expression) $3, lexer.Location);
3681 | relational_expression OP_GE additive_expression
3683 $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
3684 (Expression) $1, (Expression) $3, lexer.Location);
3686 | relational_expression IS unary_expression
3688 $$ = new Binary (Binary.Operator.Equality,
3689 (Expression) $1, (Expression) $3, lexer.Location);
3691 | relational_expression AS type_name
3693 $$ = new As ((Expression) $1, (Expression) $3, lexer.Location);
3698 : relational_expression
3699 | equality_expression ASSIGN relational_expression
3701 $$ = new Binary (Binary.Operator.Equality,
3702 (Expression) $1, (Expression) $3, lexer.Location);
3704 | equality_expression OP_NE relational_expression
3706 $$ = new Binary (Binary.Operator.Inequality,
3707 (Expression) $1, (Expression) $3, lexer.Location);
3712 : equality_expression
3713 | and_expression AND equality_expression
3715 $$ = new Binary (Binary.Operator.BitwiseAnd,
3716 (Expression) $1, (Expression) $3, lexer.Location);
3720 exclusive_or_expression
3722 | exclusive_or_expression OP_XOR and_expression
3724 $$ = new Binary (Binary.Operator.ExclusiveOr,
3725 (Expression) $1, (Expression) $3, lexer.Location);
3729 conditional_and_expression
3730 : exclusive_or_expression
3731 | conditional_and_expression AND exclusive_or_expression
3733 $$ = new Binary (Binary.Operator.LogicalAnd,
3734 (Expression) $1, (Expression) $3, lexer.Location);
3736 | conditional_and_expression ANDALSO exclusive_or_expression
3737 { // FIXME: this is likely to be broken
3738 $$ = new Binary (Binary.Operator.LogicalAnd,
3739 (Expression) $1, (Expression) $3, lexer.Location);
3743 conditional_or_expression
3744 : conditional_and_expression
3745 | conditional_or_expression OR conditional_and_expression
3747 $$ = new Binary (Binary.Operator.LogicalOr,
3748 (Expression) $1, (Expression) $3, lexer.Location);
3750 | conditional_or_expression ORELSE conditional_and_expression
3751 { // FIXME: this is likely to be broken
3752 $$ = new Binary (Binary.Operator.LogicalOr,
3753 (Expression) $1, (Expression) $3, lexer.Location);
3757 conditional_expression
3758 : conditional_or_expression
3761 assignment_expression
3762 : prefixed_unary_expression ASSIGN expression
3764 $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
3766 | prefixed_unary_expression ASSIGN ADDRESSOF expression
3768 // fixme: this is not working
3770 // type of d has to get resolved somewhere
3771 //$$ = new New ((Expression) $1, (ArrayList) $4, lexer.Location);
3772 $$ = new Assign ((Expression) $1, (Expression) $4, lexer.Location);
3774 | prefixed_unary_expression OP_MULT_ASSIGN expression
3776 Location l = lexer.Location;
3778 $$ = new CompoundAssign (
3779 Binary.Operator.Multiply, (Expression) $1, (Expression) $3, l);
3781 | prefixed_unary_expression OP_DIV_ASSIGN expression
3783 Location l = lexer.Location;
3785 $$ = new CompoundAssign (
3786 Binary.Operator.Division, (Expression) $1, (Expression) $3, l);
3788 | prefixed_unary_expression OP_IDIV_ASSIGN expression
3790 Location l = lexer.Location;
3792 $$ = new CompoundAssign (
3793 Binary.Operator.Division, (Expression) $1, (Expression) $3, l);
3795 | prefixed_unary_expression OP_ADD_ASSIGN expression
3797 Location l = lexer.Location;
3799 $$ = new CompoundAssign (
3800 Binary.Operator.Addition, (Expression) $1, (Expression) $3, l);
3802 | prefixed_unary_expression OP_SUB_ASSIGN expression
3804 Location l = lexer.Location;
3806 $$ = new CompoundAssign (
3807 Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, l);
3809 | prefixed_unary_expression OP_CONCAT_ASSIGN expression
3811 Location l = lexer.Location;
3813 $$ = new CompoundAssign (
3814 Binary.Operator.Addition, (Expression) $1, (Expression) $3, l);
3818 /*constant_expression
3828 : type_name { /* class_type */
3830 This does interfaces, delegates, struct_types, class_types,
3831 parent classes, and more! 4.2
3833 $$ = DecomposeQI ((string) $1, lexer.Location);
3843 ArrayList types = new ArrayList ();
3848 | type_list COMMA type
3850 ArrayList types = (ArrayList) $1;
3858 : namespace_or_type_name
3861 namespace_or_type_name
3862 : qualified_identifier
3865 /* Built-in / Integral types */
3867 : OBJECT { $$ = TypeManager.system_object_expr; }
3868 | STRING { $$ = TypeManager.system_string_expr; }
3869 | BOOLEAN { $$ = TypeManager.system_boolean_expr; }
3870 | DECIMAL { $$ = TypeManager.system_decimal_expr; }
3871 | SINGLE { $$ = TypeManager.system_single_expr; }
3872 | DOUBLE { $$ = TypeManager.system_double_expr; }
3873 | DATE { $$ = TypeManager.system_date_expr; }
3879 | BYTE { $$ = TypeManager.system_byte_expr; }
3880 | SHORT { $$ = TypeManager.system_int16_expr; }
3881 | LONG { $$ = TypeManager.system_int64_expr; }
3882 | INTEGER { $$ = TypeManager.system_int32_expr; }
3883 | CHAR { $$ = TypeManager.system_char_expr; }
3899 public Tokenizer Lexer {
3905 public static Expression DecomposeQI (string name, Location loc)
3909 if (name.IndexOf ('.') == -1){
3910 return new SimpleName (name, loc);
3912 int pos = name.LastIndexOf (".");
3913 string left = name.Substring (0, pos);
3914 string right = name.Substring (pos + 1);
3916 o = DecomposeQI (left, loc);
3918 return new MemberAccess (o, right, loc);
3922 Block declare_local_variables (Expression dummy_type, ArrayList variable_declarators, Location loc)
3924 Block implicit_block;
3925 ArrayList inits = null;
3928 // We use the `Used' property to check whether statements
3929 // have been added to the current block. If so, we need
3930 // to create another block to contain the new declaration
3931 // otherwise, as an optimization, we use the same block to
3932 // add the declaration.
3934 // FIXME: A further optimization is to check if the statements
3935 // that were added were added as part of the initialization
3936 // below. In which case, no other statements have been executed
3937 // and we might be able to reduce the number of blocks for
3938 // situations like this:
3940 // int j = 1; int k = j + 1;
3943 VariableDeclaration.FixupTypes (variable_declarators);
3945 if (current_block.Used) {
3946 implicit_block = new Block (current_block, true, loc, Location.Null);
3947 implicit_block.AddChildVariableNames (current_block);
3949 implicit_block = current_block;
3951 foreach (VariableDeclaration decl in variable_declarators){
3952 Expression type = decl.type;
3953 if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
3954 if (decl.expression_or_array_initializer != null){
3956 inits = new ArrayList ();
3963 return implicit_block;
3965 foreach (VariableDeclaration decl in inits){
3968 Expression type = decl.type;
3970 if ((decl.expression_or_array_initializer is Expression) ||
3971 (decl.expression_or_array_initializer is New)) {
3972 expr = (Expression) decl.expression_or_array_initializer;
3974 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
3976 expr = new ArrayCreation (type, "", init, decl.Location);
3979 LocalVariableReference var;
3980 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
3982 assign = new Assign (var, expr, decl.Location);
3984 implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
3987 return implicit_block;
3990 Block declare_local_constant (Expression dummy_type, ArrayList variable_declarators)
3992 Block implicit_block;
3993 VariableDeclaration.FixupTypes (variable_declarators);
3995 if (current_block.Used)
3996 implicit_block = new Block (current_block, true);
3998 implicit_block = current_block;
4000 foreach (VariableDeclaration decl in variable_declarators){
4001 Expression type = decl.type;
4002 implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
4003 current_local_parameters, decl.Location);
4006 return implicit_block;
4014 public VarName (object n, object t, object r)
4024 // A class used to pass around variable declarations and constants
4026 public class VariableDeclaration {
4027 public string identifier;
4028 public object expression_or_array_initializer;
4029 public Location Location;
4030 public Attributes OptAttributes;
4031 public Expression type;
4032 public ArrayList dims;
4034 public VariableDeclaration (string id, Expression t, object eoai, Location l, Attributes opt_attrs)
4036 this.identifier = id;
4037 this.expression_or_array_initializer = eoai;
4039 this.OptAttributes = opt_attrs;
4044 public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
4048 public VariableDeclaration (string id, Expression t, Location l) : this (id, t, null, l, null)
4052 public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) : this
4053 (id, TypeManager.system_object_expr, eoai, l, opt_attrs)
4057 public static ArrayCreation BuildArrayCreator (Expression vartype, ArrayList a_dims, ArrayList varinit, Location l)
4059 // FIXME : This is broken: only the first rank is parsed
4060 return new ArrayCreation (vartype, (ArrayList) a_dims[0], "", varinit, l);
4063 public static void FixupTypes (ArrayList vars)
4065 int varcount = vars.Count;
4066 VariableDeclaration last_var = (VariableDeclaration) vars[varcount - 1];
4068 if (last_var.type == null)
4069 last_var.type = TypeManager.system_object_expr;
4071 Expression cur_type = last_var.type;
4072 int n = varcount - 1;
4075 VariableDeclaration var = (VariableDeclaration) vars[n--];
4076 if (var.type == null)
4077 var.type = cur_type;
4079 cur_type = var.type;
4083 public static bool IndexesSpecifiedInRank (ArrayList IndexList)
4087 if (IndexList != null) {
4088 foreach (Expression e in IndexList)
4089 if (!(e is EmptyExpression)) {
4098 public static bool IndexesSpecified (ArrayList ranks)
4102 if (ranks != null) {
4103 foreach (ArrayList IndexList in ranks) {
4104 if (IndexesSpecifiedInRank (IndexList)) {
4113 public static string StripDims (string varname, ref string d)
4115 string res = varname;
4118 if (varname.IndexOf("[") >= 0) {
4119 dres = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
4120 res = varname.Substring(0, varname.IndexOf("["));
4126 public static string StripDims (string varname)
4130 return (StripDims(varname, ref dres));
4133 public static string StripIndexesFromDims (string dims)
4135 StringBuilder sb = new StringBuilder();
4137 foreach (char c in dims)
4138 if (c == ',' || c == ']' || c == '[')
4141 return sb.ToString();
4144 public static string BuildRank (ArrayList rank)
4149 for (int x = 0; x < (rank.Count -1 ); x++)
4156 public static string BuildRanks (Parser t)
4160 foreach (ArrayList rank in t.current_rank_specifiers)
4161 res += BuildRank (rank);
4166 public static void VBFixIndexList (ref ArrayList IndexList)
4168 if (IndexList != null) {
4169 for (int x = 0; x < IndexList.Count; x++) {
4170 Expression e = (Expression) IndexList[x];
4171 if (!(e is EmptyExpression)) {
4172 IndexList[x] = new Binary (Binary.Operator.Addition, e, new IntLiteral(1), Location.Null);
4178 public static bool IsArrayDecl (Parser t)
4180 // return (varname.IndexOf("[") >= 0);
4181 return (t.current_rank_specifiers != null);
4184 public static void VBFixIndexLists (ref ArrayList ranks)
4186 if (ranks != null) {
4187 for (int x = 0; x < ranks.Count; x++) {
4188 ArrayList IndexList = (ArrayList) ranks[x];
4189 VBFixIndexList (ref IndexList);
4194 public static void FixupArrayTypes (ArrayList vars)
4196 int varcount = vars.Count;
4199 foreach (VariableDeclaration var in vars) {
4200 if (var.identifier.EndsWith(",")) {
4201 dims = "[" + var.identifier.Substring(var.identifier.IndexOf (","),
4202 var.identifier.LastIndexOf(",")) + "]";
4203 var.identifier = var.identifier.Substring (0, var.identifier.IndexOf (","));
4204 var.type = new ComposedCast (var.type, (string) dims, var.Location);
4211 public Property BuildSimpleProperty (Expression p_type, string name,
4212 Field p_fld, int mod_flags,
4213 Attributes attrs, Location loc)
4216 Block get_block, set_block;
4217 Accessor acc_set, acc_get;
4218 StatementExpression a_set;
4223 Parameter implicit_value_parameter = new Parameter (p_type, "value", Parameter.Modifier.NONE, null);
4224 args = new Parameter [1];
4225 args [0] = implicit_value_parameter;
4227 Parameters set_params = new Parameters (args, null, loc);
4228 a_set = new StatementExpression ((ExpressionStatement) new Assign ((Expression) DecomposeQI(p_fld.Name, loc),
4229 (Expression) new SimpleName("value", loc), loc), loc);
4231 set_block = new Block (current_block, set_params, loc, Location.Null);
4232 set_block.AddStatement ((Statement) a_set);
4233 acc_set = new Accessor (set_block, attrs);
4236 a_get = (Statement) new Return ((Expression) DecomposeQI(p_fld.Name, loc), loc);
4237 get_block = new Block (current_block, null, loc, Location.Null);
4238 get_block.AddStatement ((Statement) a_get);
4239 acc_get = new Accessor (get_block, attrs);
4241 p = new Property (p_type, name, mod_flags, (Accessor) acc_get, (Accessor) acc_set, attrs, loc);
4248 current_block = new Block (current_block, current_local_parameters,
4249 lexer.Location, Location.Null);
4256 while (current_block.Implicit)
4257 current_block = current_block.Parent;
4259 res = current_block;
4261 current_block.SetEndLocation (lexer.Location);
4262 current_block = current_block.Parent;
4267 private void AddHandler (Expression evt_definition, string handler_name)
4269 AddHandler (current_block, evt_definition, handler_name);
4272 void CheckAttributeTarget (string a)
4276 case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
4280 Location l = lexer.Location;
4281 Report.Error (658, l, "`" + a + "' is an invalid attribute target");
4286 private void AddHandler (Block b, Expression evt_id, string handler_name)
4288 Location loc = lexer.Location;
4289 string evt_target = evt_id.ToString();
4290 evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.'));
4291 Statement s = (Statement) new AddHandler (evt_id, DecomposeQI(handler_name, loc), DecomposeQI(evt_target, loc), loc);
4295 private void RaiseEvent (string evt_name, ArrayList args)
4297 Location loc = lexer.Location;
4299 Invocation evt_call = new Invocation (DecomposeQI(evt_name, loc), args, lexer.Location);
4300 Statement s = (Statement)(new StatementExpression ((ExpressionStatement) evt_call, loc));
4301 current_block.AddStatement (s);
4304 // FIXME: THIS DOES NOT WORK!!!
4305 private void RemoveHandler (Block b, Expression evt_definition, string handler_name)
4307 Location loc = lexer.Location;
4308 ArrayList neh_args = new ArrayList();
4309 neh_args.Add (new Argument (DecomposeQI(handler_name, loc), Argument.AType.Expression));
4311 ExpressionStatement se = (ExpressionStatement)new New (DecomposeQI("System.EventHandler", loc), neh_args, loc);
4313 CompoundAssign ca = new CompoundAssign (
4314 Binary.Operator.Subtraction, evt_definition, (Expression) se, loc);
4316 Statement s = (Statement)(new StatementExpression ((ExpressionStatement) ca, loc));
4321 // This method is used to get at the complete string representation of
4322 // a fully-qualified type name, hiding inside a MemberAccess ;-)
4323 // This is necessary because local_variable_type admits primary_expression
4324 // as the type of the variable. So we do some extra checking
4326 string GetQualifiedIdentifier (Expression expr)
4328 if (expr is SimpleName)
4329 return ((SimpleName)expr).Name;
4330 else if (expr is MemberAccess)
4331 return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
4333 throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
4337 private void RemoveHandler (Expression evt_definition, string handler_name)
4339 RemoveHandler (current_block, evt_definition, handler_name);
4342 private ConstructorInitializer CheckConstructorInitializer (ref ArrayList s)
4344 ConstructorInitializer ci = null;
4347 if (s[0] is StatementExpression && ((StatementExpression) s[0]).expr is Invocation) {
4348 Invocation i = (Invocation) ((StatementExpression) s[0]).expr;
4350 if (i.expr is BaseAccess) {
4351 BaseAccess ba = (BaseAccess) i.expr;
4352 if (ba.member == "New" || ba.member == ".ctor") {
4353 ci = new ConstructorBaseInitializer (i.Arguments, current_local_parameters, lexer.Location);
4357 if (i.expr.ToString() == "Mono.MonoBASIC.This..ctor") {
4358 ci = new ConstructorThisInitializer (i.Arguments, current_local_parameters, lexer.Location);
4366 void Error_ExpectingTypeName (Location l, Expression expr)
4368 if (expr is Invocation){
4369 Report.Error (1002, l, "; expected");
4371 Report.Error (-1, l, "Invalid Type definition");
4375 static bool AlwaysAccept (MemberInfo m, object filterCriteria) {
4379 private void ReportError9998()
4381 Report.Error (29998, lexer.Location, "This construct is only available in MonoBASIC extended syntax.");
4384 protected override int parse ()
4386 RootContext.InitializeImports(ImportsList);
4387 current_namespace = new Namespace (null, RootContext.RootNamespace);
4388 current_container = RootContext.Tree.Types;
4389 current_container.Namespace = current_namespace;
4390 oob_stack = new Stack ();
4391 switch_stack = new Stack ();
4392 expr_stack = new Stack ();
4393 tmp_blocks = new Stack();
4394 with_stack = new Stack();
4395 statement_stack = new Stack();
4397 UseExtendedSyntax = name.EndsWith(".mbs");
4398 OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
4399 OptionStrict = InitialOptionStrict || UseExtendedSyntax;
4400 OptionCompareBinary = InitialOptionCompareBinary;
4402 lexer = new Tokenizer (input, name, defines);
4403 StringBuilder value = new StringBuilder ();
4405 if (yacc_verbose_flag)
4406 yyparse (lexer, new yydebug.yyDebugSimple ());
4409 } catch (Exception e) {
4410 Report.Error (29999, lexer.Location, lexer.location + "\nParsing error in " + lexer.ref_name + "\n" + e.ToString());
4413 RootContext.VerifyImports();
4415 return Report.Errors;