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 AS type 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 Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate (
1861 (Expression) $8, (int) current_modifiers, MakeName ((string) $3),
1862 (Parameters) $5, (Attributes) current_attributes, l);
1864 del.Namespace = current_namespace;
1865 CheckDef (current_container.AddDelegate (del), del.Name, l);
1872 | HANDLES qualified_identifier
1874 $$ = (Expression) DecomposeQI ((string)$2, lexer.Location);
1876 | HANDLES MYBASE DOT qualified_identifier
1878 // FIXME: this is blatantly wrong and crash-prone
1879 $$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location);
1885 | OPEN_PARENS CLOSE_PARENS
1888 constructor_declaration
1889 : SUB NEW OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS EOL
1891 current_local_parameters = (Parameters) $4;
1893 oob_stack.Push (lexer.Location);
1895 Location l = (Location) oob_stack.Pop ();
1896 $$ = new Constructor ((string) "New", (Parameters) $4, (ConstructorInitializer) null, l);
1901 Constructor c = (Constructor) $1;
1902 c.Block = (Block) end_block();
1903 c.ModFlags = (int) current_modifiers;
1904 c.OptAttributes = current_attributes;
1906 c.Initializer = CheckConstructorInitializer (ref c.Block.statements);
1908 CheckDef (current_container.AddConstructor(c), c.Name, c.Location);
1909 current_local_parameters = null;
1914 opt_formal_parameter_list
1917 $$ = Parameters.EmptyReadOnlyParameters;
1919 | formal_parameter_list
1922 //Parameter p = ((Parameters) $1).FixedParameters[0];
1926 formal_parameter_list
1929 ArrayList pars_list = (ArrayList) $1;
1931 Parameter [] pars = new Parameter [pars_list.Count];
1932 pars_list.CopyTo (pars);
1933 $$ = new Parameters (pars, null, lexer.Location);
1935 | fixed_parameters COMMA parameter_array
1937 ArrayList pars_list = (ArrayList) $1;
1939 Parameter [] pars = new Parameter [pars_list.Count];
1940 pars_list.CopyTo (pars);
1942 $$ = new Parameters (pars, (Parameter) $3, lexer.Location);
1946 $$ = new Parameters (null, (Parameter) $1, lexer.Location);
1953 ArrayList pars = new ArrayList ();
1958 | fixed_parameters COMMA fixed_parameter
1960 ArrayList pars = (ArrayList) $1;
1969 opt_parameter_modifier
1970 identifier opt_type_character opt_rank_specifiers opt_type_spec opt_variable_initializer
1972 Parameter.Modifier pm = (Parameter.Modifier)$2;
1973 bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
1976 if (opt_parm && ($7 == null))
1977 Report.Error (999, "Optional parameters must have a default value");
1980 if ((pm & Parameter.Modifier.REF) !=0)
1981 pm = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF;
1983 pm = Parameter.Modifier.NONE; //FIXME: should take into account BYREF
1986 if ($4 != null && $6 != null && $4 != $6)
1987 Report.Error (-1, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text
1989 ptype = (Expression)(($6 == null) ? (($4 == null) ? TypeManager.system_object_expr : $4) : $6);
1991 string t = ptype.ToString() + VariableDeclaration.BuildRank ((ArrayList) $5);
1992 ptype = DecomposeQI (t, lexer.Location);
1994 $$ = new Parameter (ptype, (string) $3, pm,
1995 (Attributes) $1, (Expression) $7, opt_parm);
2000 : PARAM_ARRAY identifier opt_parens AS type
2002 string s_patype = ((Expression) $5).ToString();
2006 Expression patype = DecomposeQI (s_patype, Location.Null);
2007 $$ = new Parameter (patype, (string) $2, Parameter.Modifier.PARAMS, null);
2008 // note ("type must be a single-dimension array type");
2015 | OPEN_PARENS CLOSE_PARENS
2019 opt_parameter_modifier
2020 : /* empty */ { $$ = Parameter.Modifier.VAL; }
2021 | parameter_modifiers { $$ = $1; }
2025 : parameter_modifiers parameter_modifier { $$ = (Parameter.Modifier)$1 | (Parameter.Modifier)$2; }
2026 | parameter_modifier { $$ = $1; }
2030 : BYREF { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
2031 | BYVAL { $$ = Parameter.Modifier.VAL; }
2032 | OPTIONAL { $$ = Parameter.Modifier.OPTIONAL; }
2037 | statement_list end_of_stmt
2042 | statement_list end_of_stmt statement
2046 declaration_statement
2048 if ($1 != null && (Block) $1 != current_block){
2049 current_block.AddStatement ((Statement) $1);
2050 current_block = (Block) $1;
2053 | embedded_statement
2055 Statement s = (Statement) $1;
2057 current_block.AddStatement ((Statement) $1);
2060 | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF qualified_identifier
2062 AddHandler ((Expression) $2, (string) $5);
2064 | RAISEEVENT identifier opt_raise_event_args //OPEN_PARENS opt_argument_list CLOSE_PARENS
2066 RaiseEvent ((string) $2, (ArrayList) $3);
2068 /* | array_handling_statement */
2069 /* | empty_statement */
2072 Statement s = (Statement) $1;
2074 current_block.AddStatement ((Statement) $1);
2078 opt_raise_event_args
2079 : /* empty */ { $$ = null; }
2080 | OPEN_PARENS opt_argument_list CLOSE_PARENS
2087 : identifier COLON end_of_stmt
2089 LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
2091 if (!current_block.AddLabel ((string) $1, labeled)){
2092 Location l = lexer.Location;
2093 Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
2095 current_block.AddStatement (labeled);
2101 : expression_statement
2102 | selection_statement
2103 | iteration_statement
2106 | array_handling_statement
2112 $$ = new EmptyStatement ();
2118 : WITH expression end_of_stmt /* was : WITH qualified_identifier end_of_stmt */
2120 // was : Expression e = DecomposeQI ((string) $2, lexer.Location);
2121 Expression e = (Expression) $2;
2128 Block b = end_block();
2135 array_handling_statement
2141 : REDIM opt_preserve redim_clauses
2143 ArrayList list = (ArrayList) $3;
2144 ReDim r = new ReDim (list, (bool) $2, lexer.Location);
2151 : /* empty */ { $$ = false; }
2152 | PRESERVE { $$ = true; }
2158 ArrayList clauses = new ArrayList ();
2163 | redim_clauses COMMA redim_clause
2165 ArrayList clauses = (ArrayList) ($1);
2173 : invocation_expression
2175 Invocation i = (Invocation) $1;
2176 RedimClause rc = new RedimClause (i.expr, i.Arguments);
2182 : ERASE erase_clauses
2184 ArrayList list = (ArrayList) $2;
2185 foreach(Expression e in list)
2187 Erase r = new Erase (e, lexer.Location);
2196 ArrayList clauses = new ArrayList ();
2201 | erase_clauses COMMA erase_clause
2203 ArrayList clauses = (ArrayList) ($1);
2211 : primary_expression
2216 | continue_statement
2217 | */return_statement
2227 $$ = new Goto (current_block, (string) $2, lexer.Location);
2232 : THROW opt_expression
2234 $$ = new Throw ((Expression) $2, lexer.Location);
2241 $$ = new Exit ((ExitType)$2, lexer.Location);
2246 : DO { $$ = ExitType.DO; }
2247 | FOR { $$ = ExitType.FOR; }
2248 | WHILE { $$ = ExitType.WHILE; }
2249 | SELECT { $$ = ExitType.SELECT; }
2250 | SUB { $$ = ExitType.SUB; }
2251 | FUNCTION { $$ = ExitType.FUNCTION; }
2252 | PROPERTY { $$ = ExitType.PROPERTY; }
2253 | TRY { $$ = ExitType.TRY; }
2256 : RETURN opt_expression
2258 $$ = new Return ((Expression) $2, lexer.Location);
2270 : FOR EACH identifier IN
2272 oob_stack.Push (lexer.Location);
2274 expression end_of_stmt
2278 Block foreach_block = current_block;
2279 Location l = lexer.Location;
2280 LocalVariableReference v = null;
2283 vi = foreach_block.GetVariableInfo ((string) $3);
2285 // Get a reference to this variable.
2286 v = new LocalVariableReference (foreach_block, (string) $3, l, vi, false);
2289 Report.Error (451, "Name '" + (string) $3 + "' is not declared.");
2296 Block foreach_block = current_block;
2297 LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
2298 Block prev_block = end_block();
2299 Location l = (Location) oob_stack.Pop ();
2303 f = new Foreach (null, v, (Expression) $6, (Statement) $9, l);
2313 if (!UseExtendedSyntax)
2319 if (iterator_container == null){
2320 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2323 iterator_container.SetYields ();
2324 $$ = new Yield ((Expression) $2, lexer.Location);
2329 if (!UseExtendedSyntax)
2335 if (iterator_container == null){
2336 Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
2339 iterator_container.SetYields ();
2340 $$ = new YieldBreak (lexer.Location);
2360 tmp_catch_clauses = (ArrayList) $5;
2369 ArrayList s = new ArrayList ();
2371 foreach (Catch cc in (ArrayList) tmp_catch_clauses) {
2378 // Now s contains the list of specific catch clauses
2379 // and g contains the general one.
2380 Block b = end_block();
2382 $$ = new Try ((Block) b, s, g, null, lexer.Location);
2389 tmp_block = end_block();
2399 ArrayList s = new ArrayList ();
2400 ArrayList catch_list = (ArrayList) tmp_catch_clauses;
2402 if (catch_list != null){
2403 foreach (Catch cc in catch_list) {
2411 $$ = new Try ((Block) tmp_block, s, g, (Block) end_block(), lexer.Location);
2417 : /* empty */ { $$ = null; }
2424 ArrayList l = new ArrayList ();
2429 | catch_clauses catch_clause
2431 ArrayList l = (ArrayList) $1;
2439 : /* empty */ { $$ = null; }
2444 : CATCH opt_catch_args end_of_stmt
2446 Expression type = null;
2450 DictionaryEntry cc = (DictionaryEntry) $2;
2451 type = (Expression) cc.Key;
2452 id = (string) cc.Value;
2455 ArrayList one = new ArrayList ();
2456 Location loc = lexer.Location;
2458 one.Add (new VariableDeclaration (id, type, loc));
2462 current_block = new Block (current_block);
2463 Block b = declare_local_variables (type, one, loc);
2469 opt_statement_list {
2470 Expression type = null;
2472 Block b_catch = current_block;
2475 DictionaryEntry cc = (DictionaryEntry) $2;
2476 type = (Expression) cc.Key;
2477 id = (string) cc.Value;
2481 // FIXME: I can change this for an assignment.
2483 while (current_block != (Block) $1)
2484 current_block = current_block.Parent;
2488 $$ = new Catch (type, id , (Block)b_catch, lexer.Location);
2493 : /* empty */ { $$ = null; }
2498 : identifier AS type
2500 $$ = new DictionaryEntry ($3, $1);
2506 : DO opt_do_construct end_of_stmt
2509 oob_stack.Push (lexer.Location);
2512 LOOP opt_do_construct
2514 Expression t_before = (Expression) $2;
2515 Expression t_after = (Expression) $7;
2518 if ((t_before != null) && (t_after != null))
2519 Report.Error (30238, "'Loop' cannot have a condition if matching 'Do' has one.");
2521 if ((t_before == null) && (t_after == null))
2522 t = new BoolLiteral (true);
2524 t = (t_before != null) ? t_before : t_after;
2526 DoOptions test_type = (t_before != null) ? DoOptions.TEST_BEFORE : DoOptions.TEST_AFTER;
2528 if (((do_type == DoOptions.WHILE) && (test_type == DoOptions.TEST_BEFORE)) ||
2529 ((do_type == DoOptions.UNTIL) && (test_type == DoOptions.TEST_AFTER)))
2530 t = new Unary (Unary.Operator.LogicalNot, (Expression) t, lexer.Location);
2532 $$ = new Do ((Statement) end_block(), (Expression) t, test_type, lexer.Location);
2537 : /* empty */ { $$ = null; }
2538 | while_or_until boolean_expression
2540 do_type = (DoOptions)$1;
2541 $$ = (Expression) $2;
2546 : WHILE { $$ = DoOptions.WHILE; }
2547 | UNTIL { $$ = DoOptions.UNTIL; }
2554 oob_stack.Push (lexer.Location);
2556 boolean_expression end_of_stmt
2560 Location l = (Location) oob_stack.Pop ();
2561 Block b = end_block();
2562 Expression e = (Expression) $3;
2563 $$ = new While ((Expression) e, (Statement) b, l);
2569 : FOR identifier ASSIGN expression TO expression opt_step end_of_stmt
2576 Block statement = end_block();
2577 Expression for_var = (Expression) DecomposeQI ((string)$2, lexer.Location);;
2579 Expression assign_expr = new Assign (for_var, (Expression) $4, lexer.Location);
2580 Expression test_expr = new Binary (Binary.Operator.LessThanOrEqual,
2581 for_var, (Expression) $6, lexer.Location);
2582 Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
2583 for_var, (Expression) $7, lexer.Location), lexer.Location);
2585 Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, lexer.Location);
2586 Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, lexer.Location);
2588 $$ = new For (assign_stmt, test_expr, step_stmt, statement, lexer.Location);
2593 : /* empty */ { $$ = new IntLiteral ((Int32) 1); }
2594 | STEP expression { $$ = $2; }
2603 : if_statement_open opt_then if_statement_rest
2607 | if_statement_open THEN pre_embedded_statement
2609 Location l = (Location) oob_stack.Pop ();
2610 tmp_expr = (Expression)expr_stack.Pop();
2611 $$ = new If ((Expression) tmp_expr, end_block(), l);
2615 pre_embedded_statement
2616 : embedded_statement
2618 Statement s = (Statement) $1;
2620 current_block.AddStatement ((Statement) $1);
2625 : IF boolean_expression
2627 oob_stack.Push (lexer.Location);
2629 tmp_expr = (Expression) $2;
2630 expr_stack.Push(tmp_expr);
2644 Location l = (Location) oob_stack.Pop ();
2645 Expression expr = (Expression)expr_stack.Pop();
2646 $$ = new If ((Expression) expr, (Statement) end_block(), l);
2652 Block bl = end_block();
2653 tmp_blocks.Push(bl);
2659 Location l = (Location) oob_stack.Pop ();
2660 tmp_expr = (Expression)expr_stack.Pop();
2661 tmp_block = (Block) tmp_blocks.Pop();
2662 $$ = new If ((Expression) tmp_expr, (Statement) tmp_block, (Statement) end_block(), l);
2666 ELSEIF boolean_expression opt_then
2668 tmp_expr = (Expression) $4;
2669 expr_stack.Push(tmp_expr);
2670 tmp_block = end_block();
2671 tmp_blocks.Push(tmp_block);
2674 else_if_statement_rest
2676 Statement stmt = (Statement) statement_stack.Pop();
2677 Block bl = (Block) tmp_blocks.Pop();
2678 Expression expr = (Expression)expr_stack.Pop();
2679 Location l = (Location) oob_stack.Pop ();
2680 $$ = (Statement) new If ((Expression) expr, (Statement) bl , stmt , l);
2685 else_if_statement_rest
2690 Location l = (Location) oob_stack.Pop ();
2692 Expression expr = (Expression)expr_stack.Pop();
2693 Statement stmt = (Statement) new If ((Expression) expr, (Statement) end_block(), l);
2694 statement_stack.Push(stmt);
2700 Block bl = end_block();
2701 tmp_blocks.Push(bl);
2707 Location l = (Location) oob_stack.Pop ();
2709 Expression expr = (Expression)expr_stack.Pop();
2710 Block bl = (Block)tmp_blocks.Pop();
2711 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl , (Statement) end_block(), l);
2712 statement_stack.Push(stmt);
2716 ELSEIF boolean_expression opt_then
2718 expr_stack.Push((Expression) $4);
2719 Block bl = end_block();
2720 tmp_blocks.Push(bl);
2723 else_if_statement_rest
2725 Location l = (Location) oob_stack.Pop ();
2727 Statement tmp_stmt = (Statement)statement_stack.Pop();
2728 Block bl = (Block) tmp_blocks.Pop();
2729 Expression expr = (Expression)expr_stack.Pop();
2730 Statement stmt = (Statement) new If ((Expression) expr, (Statement) bl, tmp_stmt , l);
2731 statement_stack.Push(stmt);
2736 : SELECT opt_case expression end_of_stmt
2738 oob_stack.Push (lexer.Location);
2739 switch_stack.Push (current_block);
2744 $$ = new Switch ((Expression) $3, (ArrayList) $6, (Location) oob_stack.Pop ());
2745 current_block = (Block) switch_stack.Pop ();
2750 : /* empty */ { $$ = null; }
2751 | case_sections { $$ = $1; }
2755 : case_sections case_section
2757 ArrayList sections = (ArrayList) $1;
2764 ArrayList sections = new ArrayList ();
2778 : CASE case_clauses ends
2784 //Block topmost = current_block;
2785 Block topmost = end_block();
2787 while (topmost.Implicit)
2788 topmost = topmost.Parent;
2790 // FIXME: This is a horrible hack which MUST go
2791 topmost.statements.Add (new Break (lexer.Location));
2792 $$ = new SwitchSection ((ArrayList) $2, topmost);
2795 /* FIXME: we should somehow flag an error
2796 (BC30321 'Case' cannot follow a 'Case Else'
2797 in the same 'Select' statement.)
2798 if Case Else is not the last of the Case clauses
2805 //Block topmost = current_block;
2806 Block topmost = end_block();
2808 while (topmost.Implicit)
2809 topmost = topmost.Parent;
2811 // FIXME: This is a horrible hack which MUST go
2812 topmost.statements.Add (new Break (lexer.Location));
2814 ArrayList a = new ArrayList();
2815 a.Add (new SwitchLabel (null, lexer.Location));
2816 $$ = new SwitchSection ((ArrayList) a, topmost);
2823 ArrayList labels = new ArrayList ();
2828 | case_clauses COMMA case_clause
2830 ArrayList labels = (ArrayList) ($1);
2838 : opt_is comparison_operator expression
2841 $$ = new SwitchLabel ((Expression) $1, lexer.Location);
2863 expression_statement
2864 : statement_expression
2871 statement_expression
2872 : invocation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
2873 | object_creation_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
2874 | assignment_expression { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location); }
2877 object_creation_expression
2878 : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
2880 $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
2884 $$ = new New ((Expression) $2, new ArrayList(), lexer.Location);
2888 array_creation_expression
2889 : object_creation_expression array_initializer
2892 ArrayList dims = new ArrayList();
2894 if (n.Arguments != null) {
2895 foreach (Argument a in n.Arguments) {
2900 Expression atype = n.RequestedType;
2902 ArrayList init = (ArrayList) $2;
2903 if (init.Count == 0)
2906 if (VariableDeclaration.IndexesSpecifiedInRank(dims)) {
2907 VariableDeclaration.VBFixIndexList (ref dims);
2908 $$ = new ArrayCreation (atype, dims, "", init, lexer.Location);
2912 string rank = VariableDeclaration.BuildRank (dims);
2913 $$ = new ArrayCreation (atype, rank, (ArrayList) $2, lexer.Location);
2915 //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
2919 delegate_creation_expression
2920 : NEW type OPEN_PARENS ADDRESSOF opt_argument_list CLOSE_PARENS
2922 New n = new New ((Expression) $2, (ArrayList) $5, lexer.Location);
2924 Console.WriteLine("empty");
2930 : object_creation_expression
2931 | array_creation_expression
2932 | delegate_creation_expression
2935 declaration_statement
2936 : local_variable_declaration
2939 DictionaryEntry de = (DictionaryEntry) $1;
2941 $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
2944 | local_constant_declaration
2947 DictionaryEntry de = (DictionaryEntry) $1;
2949 $$ = declare_local_constant ((Expression) de.Key, (ArrayList) de.Value);
2954 local_variable_declaration
2955 : DIM variable_declarators
2957 $$ = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), $2);
2962 local_constant_declaration
2963 : CONST constant_declarators
2966 $$ = new DictionaryEntry (DecomposeQI("_local_consts_", lexer.Location), $2);
2972 constant_declarators
2973 : constant_declarator
2975 ArrayList decl = new ArrayList ();
2981 | constant_declarators COMMA constant_declarator
2983 ArrayList decls = (ArrayList) $1;
2992 : variable_name opt_type_decl opt_variable_initializer
2994 VarName vname = (VarName) $1;
2995 string varname = (string) vname.Name;
2996 current_rank_specifiers = (ArrayList) vname.Rank;
2997 object varinit = $3;
2998 ArrayList a_dims = null;
3000 if (varinit == null)
3002 30438, lexer.Location, "Constant should have a value"
3005 if (vname.Type != null && $2 != null)
3007 30302, lexer.Location,
3008 "Type character cannot be used with explicit type declaration" );
3010 Expression vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3012 if (current_rank_specifiers != null)
3014 Report.Error (30424, lexer.Location, "Constant doesn't support array");
3018 $$ = new VariableDeclaration (varname, vartype, varinit, lexer.Location, null);
3022 variable_declarators
3023 : variable_declarator
3025 ArrayList decl = new ArrayList ();
3026 decl.AddRange ((ArrayList) $1);
3029 | variable_declarators COMMA variable_declarator
3031 ArrayList decls = (ArrayList) $1;
3032 decls.AddRange ((ArrayList) $3);
3038 : variable_names opt_type_decl opt_variable_initializer
3040 ArrayList names = (ArrayList) $1;
3041 object varinit = $3;
3042 ArrayList VarDeclarations = new ArrayList();
3044 ArrayList a_dims = null;
3046 if ((names.Count > 1) && (varinit != null))
3048 30671, lexer.Location,
3049 "Multiple variables with single type can not have " +
3050 "a explicit initialization" );
3053 foreach (VarName vname in names)
3055 string varname = (string) vname.Name;
3056 current_rank_specifiers = (ArrayList) vname.Rank;
3060 if(vname.Type != null && $2 != null)
3062 30302, lexer.Location,
3063 "Type character cannot be used with explicit type declaration" );
3065 // Some checking is required for particularly weird declarations
3066 // like Dim a As Integer(,)
3068 vartype = (Expression) ((Pair) $2).First;
3070 /*if ($3 != null && $3 is ArrayList)
3071 Report.Error (205, "End of statement expected.");*/
3073 ArrayList args = (ArrayList) ((Pair) $2).Second;
3074 if (current_rank_specifiers != null)
3075 Report.Error (31087, lexer.Location,
3076 "Array types specified in too many places");
3078 if (VariableDeclaration.IndexesSpecifiedInRank (args))
3079 Report.Error (30638, "Array bounds cannot appear in type specifiers.");
3081 current_rank_specifiers = new ArrayList ();
3082 current_rank_specifiers.Add (args);
3084 /*string s_vartype = vartype.ToString();
3087 for (int x = 0; x < args.Count; x++)
3091 vartype = DecomposeQI(s_vartype, Location.Null); */
3094 vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
3096 // if the variable is an array with explicit bound
3097 // and having explicit initialization throw exception
3098 if (current_rank_specifiers != null && varinit != null)
3100 bool broken = false;
3101 foreach (ArrayList exprs in current_rank_specifiers)
3103 foreach (Expression expr in exprs)
3105 if (!((Expression)expr is EmptyExpression ))
3108 30672, lexer.Location,
3109 "Array declared with explicit bound " +
3110 " can not have explicit initialization");
3121 Check for a declaration like Dim a(2) or Dim a(2,3)
3122 If this is the case, we must generate an ArrayCreationExpression
3123 and, in case, add the initializer after the array has been created.
3125 if (VariableDeclaration.IsArrayDecl (this)) {
3126 if (VariableDeclaration.IndexesSpecified(current_rank_specifiers)) {
3127 a_dims = (ArrayList) current_rank_specifiers;
3128 VariableDeclaration.VBFixIndexLists (ref a_dims);
3129 varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, lexer.Location);
3131 vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (this), lexer.Location);
3134 if (vartype is New) {
3135 if (varinit != null) {
3136 Report.Error (30205, lexer.Location, "End of statement expected");
3142 vartype = ((New)vartype).RequestedType;
3145 VarDeclarations.Add (new VariableDeclaration (varname, vartype, varinit, lexer.Location, null));
3147 $$ = VarDeclarations;
3154 ArrayList list = new ArrayList ();
3158 | variable_names COMMA variable_name
3160 ArrayList list = (ArrayList) $1;
3167 : identifier opt_type_character opt_array_name_modifier
3169 $$ = new VarName ($1, $2, $3);
3180 $$ = (Expression) $2;
3186 | AS type rank_specifiers
3188 $$ = TypeManager.system_object_expr;
3197 | AS type OPEN_PARENS /*opt_argument_list*/ opt_dim_separators CLOSE_PARENS
3199 $$ = new Pair ($2, $4);
3203 New n = new New ((Expression)$3, null, lexer.Location);
3204 $$ = (Expression) n;
3206 | AS NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
3208 New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
3209 $$ = (Expression) n;
3211 | AS NEW type OPEN_PARENS ADDRESSOF opt_argument_list CLOSE_PARENS
3213 New n = new New ((Expression)$3, (ArrayList) $6, lexer.Location);
3214 $$ = (Expression) n;
3218 opt_array_name_modifier
3219 : /* empty */ { $$ = null; }
3220 | array_type_modifier { $$ = $1; }
3224 : rank_specifiers { $$ = $1; }
3227 opt_variable_initializer
3228 : /* empty */ { $$ = null; }
3229 | ASSIGN variable_initializer { $$ = $2; }
3232 variable_initializer
3245 : OPEN_BRACE CLOSE_BRACE
3247 ArrayList list = new ArrayList ();
3250 | OPEN_BRACE variable_initializer_list CLOSE_BRACE
3252 $$ = (ArrayList) $2;
3256 variable_initializer_list
3257 : variable_initializer
3259 ArrayList list = new ArrayList ();
3263 | variable_initializer_list COMMA variable_initializer
3265 ArrayList list = (ArrayList) $1;
3286 ArrayList rs = new ArrayList();
3290 | rank_specifiers rank_specifier
3292 ArrayList rs = (ArrayList) $1;
3299 : OPEN_PARENS opt_dim_separators CLOSE_PARENS
3308 ArrayList ds = new ArrayList();
3309 ds.Add (new EmptyExpression());
3314 ArrayList ds = (ArrayList) $1;
3315 ds.Add (new EmptyExpression());
3327 ArrayList ds = new ArrayList();
3328 ds.Add (new EmptyExpression());
3331 | dim_separators COMMA
3333 ArrayList ds = (ArrayList) $1;
3334 ds.Add (new EmptyExpression());
3342 ArrayList ds = new ArrayList();
3343 ds.Add ((Expression) $1);
3346 | dim_specifiers COMMA expression
3348 ArrayList ds = (ArrayList) $1;
3349 ds.Add ((Expression) $3);
3361 | qualified_identifier
3363 string name = (string) $1;
3365 $$ = DecomposeQI (name, lexer.Location);
3367 | parenthesized_expression
3369 | invocation_expression
3381 | LITERAL_DATE { $$ = new DateLiteral ((DateTime)lexer.Value); }
3382 | LITERAL_CHARACTER { $$ = new CharLiteral ((char) lexer.Value); }
3383 | LITERAL_STRING { $$ = new StringLiteral ((string) lexer.Value); }
3384 | NOTHING { $$ = NullLiteral.Null; }
3388 : LITERAL_SINGLE { $$ = new FloatLiteral ((float) lexer.Value); }
3389 | LITERAL_DOUBLE { $$ = new DoubleLiteral ((double) lexer.Value); }
3390 | LITERAL_DECIMAL { $$ = new DecimalLiteral ((decimal) lexer.Value); }
3395 object v = lexer.Value;
3398 $$ = new IntLiteral ((Int32)v);
3399 else if (v is short)
3400 $$ = new ShortLiteral ((Int16)v);
3402 $$ = new LongLiteral ((Int64)v);
3404 Console.WriteLine ("OOPS. Unexpected result from scanner");
3410 : TRUE { $$ = new BoolLiteral (true); }
3411 | FALSE { $$ = new BoolLiteral (false); }
3414 parenthesized_expression
3415 : OPEN_PARENS expression CLOSE_PARENS
3420 : primary_expression DOT identifier
3423 string id_name = (string)$3;
3424 if (id_name.ToUpper() == "NEW")
3426 $$ = new MemberAccess ((Expression) $1, id_name, lexer.Location);
3430 if (with_stack.Count > 0) {
3431 Expression e = (Expression) with_stack.Peek();
3432 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3440 /* | primary_expression DOT NEW
3442 $$ = new MemberAccess ((Expression) $1, (string) ".ctor", lexer.Location);
3444 | predefined_type DOT identifier
3447 $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
3450 if (with_stack.Count > 0) {
3451 Expression e = (Expression) with_stack.Peek();
3452 $$ = new MemberAccess (e, (string) $3, lexer.Location);
3466 invocation_expression
3467 : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
3470 Location l = lexer.Location;
3471 Report.Error (1, l, "THIS IS CRAZY");
3473 $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
3474 // Console.WriteLine ("Invocation: {0} with {1} arguments", $1, ($3 != null) ? ((ArrayList) $3).Count : 0);
3479 : MYBASE DOT IDENTIFIER
3481 string id_name = (string) $3;
3482 if (id_name.ToUpper() == "NEW")
3484 $$ = new BaseAccess (id_name, lexer.Location);
3488 $$ = new BaseAccess ("New", lexer.Location);
3496 The 'argument' rule returns an 'empty' argument
3497 of type NoArg (used for default arguments in invocations)
3498 if no arguments are actually passed.
3500 If there is only one argument and it is o type NoArg,
3501 we return a null (empty) list
3503 ArrayList args = (ArrayList) $1;
3504 if (args.Count == 1 &&
3505 ((Argument)args[0]).ArgType == Argument.AType.NoArg)
3515 ArrayList list = new ArrayList ();
3519 | argument_list COMMA argument
3521 ArrayList list = (ArrayList) $1;
3530 $$ = new Argument ((Expression) $1, Argument.AType.Expression);
3532 | BYREF variable_reference
3534 $$ = new Argument ((Expression) $2, Argument.AType.Ref);
3538 $$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
3543 : expression {/* note ("section 5.4"); */ $$ = $1; }
3549 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
3554 : conditional_expression { $$ = $1; }
3555 | negation_expression
3556 /*| assignment_expression*/
3567 $$ = new This (current_block, lexer.Location);
3571 // FIXME: This is actually somewhat different from Me
3572 // because it is for accessing static (classifier) methods/properties/fields
3573 $$ = new This (current_block, lexer.Location);
3578 : primary_expression
3579 /*| NOT prefixed_unary_expression
3581 $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
3583 | cast_expression */
3587 : cast_operator OPEN_PARENS expression CLOSE_PARENS
3589 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
3591 | CTYPE OPEN_PARENS expression COMMA type CLOSE_PARENS
3593 $$ = new Cast ((Expression) $5, (Expression) $3, lexer.Location);
3598 : CBOOL { $$ = TypeManager.system_boolean_expr; }
3599 | CBYTE { $$ = TypeManager.system_byte_expr; }
3600 | CCHAR { $$ = TypeManager.system_char_expr; }
3601 | CDATE { $$ = TypeManager.system_date_expr; }
3602 | CDBL { $$ = TypeManager.system_double_expr; }
3603 | CDEC { $$ = TypeManager.system_decimal_expr; }
3604 | CINT { $$ = TypeManager.system_int32_expr; }
3605 | CLNG { $$ = TypeManager.system_int64_expr; }
3606 | COBJ { $$ = TypeManager.system_object_expr; }
3607 | CSHORT { $$ = TypeManager.system_int16_expr; }
3608 | CSNG { $$ = TypeManager.system_single_expr; }
3609 | CSTR { $$ = TypeManager.system_string_expr; }
3613 // The idea to split this out is from Rhys' grammar
3614 // to solve the problem with casts.
3616 prefixed_unary_expression
3618 | PLUS prefixed_unary_expression
3620 $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
3622 | MINUS prefixed_unary_expression
3624 $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
3628 multiplicative_expression
3629 : prefixed_unary_expression
3630 | multiplicative_expression STAR prefixed_unary_expression
3632 $$ = new Binary (Binary.Operator.Multiply,
3633 (Expression) $1, (Expression) $3, lexer.Location);
3635 | multiplicative_expression DIV prefixed_unary_expression
3637 $$ = new Binary (Binary.Operator.Division,
3638 (Expression) $1, (Expression) $3, lexer.Location);
3640 | multiplicative_expression OP_IDIV prefixed_unary_expression
3642 $$ = new Binary (Binary.Operator.Division,
3643 (Expression) $1, (Expression) $3, lexer.Location);
3645 | multiplicative_expression MOD prefixed_unary_expression
3647 $$ = new Binary (Binary.Operator.Modulus,
3648 (Expression) $1, (Expression) $3, lexer.Location);
3653 : multiplicative_expression
3654 | additive_expression PLUS multiplicative_expression
3656 $$ = new Binary (Binary.Operator.Addition,
3657 (Expression) $1, (Expression) $3, lexer.Location);
3659 | additive_expression MINUS multiplicative_expression
3661 $$ = new Binary (Binary.Operator.Subtraction,
3662 (Expression) $1, (Expression) $3, lexer.Location);
3664 | additive_expression OP_CONCAT multiplicative_expression
3666 // FIXME: This should only work for String expressions
3667 // We probably need to use something from the runtime
3668 $$ = new Binary (Binary.Operator.Addition,
3669 (Expression) $1, (Expression) $3, lexer.Location);
3673 relational_expression
3674 : additive_expression
3675 | relational_expression OP_LT additive_expression
3677 $$ = new Binary (Binary.Operator.LessThan,
3678 (Expression) $1, (Expression) $3, lexer.Location);
3680 | relational_expression OP_GT additive_expression
3682 $$ = new Binary (Binary.Operator.GreaterThan,
3683 (Expression) $1, (Expression) $3, lexer.Location);
3685 | relational_expression OP_LE additive_expression
3687 $$ = new Binary (Binary.Operator.LessThanOrEqual,
3688 (Expression) $1, (Expression) $3, lexer.Location);
3690 | relational_expression OP_GE additive_expression
3692 $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
3693 (Expression) $1, (Expression) $3, lexer.Location);
3695 | relational_expression IS unary_expression
3697 $$ = new Binary (Binary.Operator.Equality,
3698 (Expression) $1, (Expression) $3, lexer.Location);
3700 | relational_expression AS type_name
3702 $$ = new As ((Expression) $1, (Expression) $3, lexer.Location);
3707 : relational_expression
3708 | equality_expression ASSIGN relational_expression
3710 $$ = new Binary (Binary.Operator.Equality,
3711 (Expression) $1, (Expression) $3, lexer.Location);
3713 | equality_expression OP_NE relational_expression
3715 $$ = new Binary (Binary.Operator.Inequality,
3716 (Expression) $1, (Expression) $3, lexer.Location);
3721 : equality_expression
3722 | and_expression AND equality_expression
3724 $$ = new Binary (Binary.Operator.BitwiseAnd,
3725 (Expression) $1, (Expression) $3, lexer.Location);
3729 exclusive_or_expression
3731 | exclusive_or_expression OP_XOR and_expression
3733 $$ = new Binary (Binary.Operator.ExclusiveOr,
3734 (Expression) $1, (Expression) $3, lexer.Location);
3738 conditional_and_expression
3739 : exclusive_or_expression
3740 | conditional_and_expression AND exclusive_or_expression
3742 $$ = new Binary (Binary.Operator.LogicalAnd,
3743 (Expression) $1, (Expression) $3, lexer.Location);
3745 | conditional_and_expression ANDALSO exclusive_or_expression
3746 { // FIXME: this is likely to be broken
3747 $$ = new Binary (Binary.Operator.LogicalAnd,
3748 (Expression) $1, (Expression) $3, lexer.Location);
3752 conditional_or_expression
3753 : conditional_and_expression
3754 | conditional_or_expression OR conditional_and_expression
3756 $$ = new Binary (Binary.Operator.LogicalOr,
3757 (Expression) $1, (Expression) $3, lexer.Location);
3759 | conditional_or_expression ORELSE conditional_and_expression
3760 { // FIXME: this is likely to be broken
3761 $$ = new Binary (Binary.Operator.LogicalOr,
3762 (Expression) $1, (Expression) $3, lexer.Location);
3766 conditional_expression
3767 : conditional_or_expression
3770 assignment_expression
3771 : prefixed_unary_expression ASSIGN expression
3773 $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
3775 | prefixed_unary_expression ASSIGN ADDRESSOF expression
3777 // fixme: this is not working
3779 // type of d has to get resolved somewhere
3780 //$$ = new New ((Expression) $1, (ArrayList) $4, lexer.Location);
3781 $$ = new Assign ((Expression) $1, (Expression) $4, lexer.Location);
3783 | prefixed_unary_expression OP_MULT_ASSIGN expression
3785 Location l = lexer.Location;
3787 $$ = new CompoundAssign (
3788 Binary.Operator.Multiply, (Expression) $1, (Expression) $3, l);
3790 | prefixed_unary_expression OP_DIV_ASSIGN expression
3792 Location l = lexer.Location;
3794 $$ = new CompoundAssign (
3795 Binary.Operator.Division, (Expression) $1, (Expression) $3, l);
3797 | prefixed_unary_expression OP_IDIV_ASSIGN expression
3799 Location l = lexer.Location;
3801 $$ = new CompoundAssign (
3802 Binary.Operator.Division, (Expression) $1, (Expression) $3, l);
3804 | prefixed_unary_expression OP_ADD_ASSIGN expression
3806 Location l = lexer.Location;
3808 $$ = new CompoundAssign (
3809 Binary.Operator.Addition, (Expression) $1, (Expression) $3, l);
3811 | prefixed_unary_expression OP_SUB_ASSIGN expression
3813 Location l = lexer.Location;
3815 $$ = new CompoundAssign (
3816 Binary.Operator.Subtraction, (Expression) $1, (Expression) $3, l);
3818 | prefixed_unary_expression OP_CONCAT_ASSIGN expression
3820 Location l = lexer.Location;
3822 $$ = new CompoundAssign (
3823 Binary.Operator.Addition, (Expression) $1, (Expression) $3, l);
3827 /*constant_expression
3837 : type_name { /* class_type */
3839 This does interfaces, delegates, struct_types, class_types,
3840 parent classes, and more! 4.2
3842 $$ = DecomposeQI ((string) $1, lexer.Location);
3852 ArrayList types = new ArrayList ();
3857 | type_list COMMA type
3859 ArrayList types = (ArrayList) $1;
3867 : namespace_or_type_name
3870 namespace_or_type_name
3871 : qualified_identifier
3874 /* Built-in / Integral types */
3876 : OBJECT { $$ = TypeManager.system_object_expr; }
3877 | STRING { $$ = TypeManager.system_string_expr; }
3878 | BOOLEAN { $$ = TypeManager.system_boolean_expr; }
3879 | DECIMAL { $$ = TypeManager.system_decimal_expr; }
3880 | SINGLE { $$ = TypeManager.system_single_expr; }
3881 | DOUBLE { $$ = TypeManager.system_double_expr; }
3882 | DATE { $$ = TypeManager.system_date_expr; }
3888 | BYTE { $$ = TypeManager.system_byte_expr; }
3889 | SHORT { $$ = TypeManager.system_int16_expr; }
3890 | LONG { $$ = TypeManager.system_int64_expr; }
3891 | INTEGER { $$ = TypeManager.system_int32_expr; }
3892 | CHAR { $$ = TypeManager.system_char_expr; }
3908 public Tokenizer Lexer {
3914 public static Expression DecomposeQI (string name, Location loc)
3918 if (name.IndexOf ('.') == -1){
3919 return new SimpleName (name, loc);
3921 int pos = name.LastIndexOf (".");
3922 string left = name.Substring (0, pos);
3923 string right = name.Substring (pos + 1);
3925 o = DecomposeQI (left, loc);
3927 return new MemberAccess (o, right, loc);
3931 Block declare_local_variables (Expression dummy_type, ArrayList variable_declarators, Location loc)
3933 Block implicit_block;
3934 ArrayList inits = null;
3937 // We use the `Used' property to check whether statements
3938 // have been added to the current block. If so, we need
3939 // to create another block to contain the new declaration
3940 // otherwise, as an optimization, we use the same block to
3941 // add the declaration.
3943 // FIXME: A further optimization is to check if the statements
3944 // that were added were added as part of the initialization
3945 // below. In which case, no other statements have been executed
3946 // and we might be able to reduce the number of blocks for
3947 // situations like this:
3949 // int j = 1; int k = j + 1;
3952 VariableDeclaration.FixupTypes (variable_declarators);
3954 if (current_block.Used) {
3955 implicit_block = new Block (current_block, true, loc, Location.Null);
3956 implicit_block.AddChildVariableNames (current_block);
3958 implicit_block = current_block;
3960 foreach (VariableDeclaration decl in variable_declarators){
3961 Expression type = decl.type;
3962 if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
3963 if (decl.expression_or_array_initializer != null){
3965 inits = new ArrayList ();
3972 return implicit_block;
3974 foreach (VariableDeclaration decl in inits){
3977 Expression type = decl.type;
3979 if ((decl.expression_or_array_initializer is Expression) ||
3980 (decl.expression_or_array_initializer is New)) {
3981 expr = (Expression) decl.expression_or_array_initializer;
3983 ArrayList init = (ArrayList) decl.expression_or_array_initializer;
3985 expr = new ArrayCreation (type, "", init, decl.Location);
3988 LocalVariableReference var;
3989 var = new LocalVariableReference (implicit_block, decl.identifier, loc);
3991 assign = new Assign (var, expr, decl.Location);
3993 implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
3996 return implicit_block;
3999 Block declare_local_constant (Expression dummy_type, ArrayList variable_declarators)
4001 Block implicit_block;
4002 VariableDeclaration.FixupTypes (variable_declarators);
4004 if (current_block.Used)
4005 implicit_block = new Block (current_block, true);
4007 implicit_block = current_block;
4009 foreach (VariableDeclaration decl in variable_declarators){
4010 Expression type = decl.type;
4011 implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
4012 current_local_parameters, decl.Location);
4015 return implicit_block;
4023 public VarName (object n, object t, object r)
4033 // A class used to pass around variable declarations and constants
4035 public class VariableDeclaration {
4036 public string identifier;
4037 public object expression_or_array_initializer;
4038 public Location Location;
4039 public Attributes OptAttributes;
4040 public Expression type;
4041 public ArrayList dims;
4043 public VariableDeclaration (string id, Expression t, object eoai, Location l, Attributes opt_attrs)
4045 this.identifier = id;
4046 this.expression_or_array_initializer = eoai;
4048 this.OptAttributes = opt_attrs;
4053 public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
4057 public VariableDeclaration (string id, Expression t, Location l) : this (id, t, null, l, null)
4061 public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) : this
4062 (id, TypeManager.system_object_expr, eoai, l, opt_attrs)
4066 public static ArrayCreation BuildArrayCreator (Expression vartype, ArrayList a_dims, ArrayList varinit, Location l)
4068 // FIXME : This is broken: only the first rank is parsed
4069 return new ArrayCreation (vartype, (ArrayList) a_dims[0], "", varinit, l);
4072 public static void FixupTypes (ArrayList vars)
4074 int varcount = vars.Count;
4075 VariableDeclaration last_var = (VariableDeclaration) vars[varcount - 1];
4077 if (last_var.type == null)
4078 last_var.type = TypeManager.system_object_expr;
4080 Expression cur_type = last_var.type;
4081 int n = varcount - 1;
4084 VariableDeclaration var = (VariableDeclaration) vars[n--];
4085 if (var.type == null)
4086 var.type = cur_type;
4088 cur_type = var.type;
4092 public static bool IndexesSpecifiedInRank (ArrayList IndexList)
4096 if (IndexList != null) {
4097 foreach (Expression e in IndexList)
4098 if (!(e is EmptyExpression)) {
4107 public static bool IndexesSpecified (ArrayList ranks)
4111 if (ranks != null) {
4112 foreach (ArrayList IndexList in ranks) {
4113 if (IndexesSpecifiedInRank (IndexList)) {
4122 public static string StripDims (string varname, ref string d)
4124 string res = varname;
4127 if (varname.IndexOf("[") >= 0) {
4128 dres = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
4129 res = varname.Substring(0, varname.IndexOf("["));
4135 public static string StripDims (string varname)
4139 return (StripDims(varname, ref dres));
4142 public static string StripIndexesFromDims (string dims)
4144 StringBuilder sb = new StringBuilder();
4146 foreach (char c in dims)
4147 if (c == ',' || c == ']' || c == '[')
4150 return sb.ToString();
4153 public static string BuildRank (ArrayList rank)
4158 for (int x = 0; x < (rank.Count -1 ); x++)
4165 public static string BuildRanks (Parser t)
4169 foreach (ArrayList rank in t.current_rank_specifiers)
4170 res += BuildRank (rank);
4175 public static void VBFixIndexList (ref ArrayList IndexList)
4177 if (IndexList != null) {
4178 for (int x = 0; x < IndexList.Count; x++) {
4179 Expression e = (Expression) IndexList[x];
4180 if (!(e is EmptyExpression)) {
4181 IndexList[x] = new Binary (Binary.Operator.Addition, e, new IntLiteral(1), Location.Null);
4187 public static bool IsArrayDecl (Parser t)
4189 // return (varname.IndexOf("[") >= 0);
4190 return (t.current_rank_specifiers != null);
4193 public static void VBFixIndexLists (ref ArrayList ranks)
4195 if (ranks != null) {
4196 for (int x = 0; x < ranks.Count; x++) {
4197 ArrayList IndexList = (ArrayList) ranks[x];
4198 VBFixIndexList (ref IndexList);
4203 public static void FixupArrayTypes (ArrayList vars)
4205 int varcount = vars.Count;
4208 foreach (VariableDeclaration var in vars) {
4209 if (var.identifier.EndsWith(",")) {
4210 dims = "[" + var.identifier.Substring(var.identifier.IndexOf (","),
4211 var.identifier.LastIndexOf(",")) + "]";
4212 var.identifier = var.identifier.Substring (0, var.identifier.IndexOf (","));
4213 var.type = new ComposedCast (var.type, (string) dims, var.Location);
4220 public Property BuildSimpleProperty (Expression p_type, string name,
4221 Field p_fld, int mod_flags,
4222 Attributes attrs, Location loc)
4225 Block get_block, set_block;
4226 Accessor acc_set, acc_get;
4227 StatementExpression a_set;
4232 Parameter implicit_value_parameter = new Parameter (p_type, "value", Parameter.Modifier.NONE, null);
4233 args = new Parameter [1];
4234 args [0] = implicit_value_parameter;
4236 Parameters set_params = new Parameters (args, null, loc);
4237 a_set = new StatementExpression ((ExpressionStatement) new Assign ((Expression) DecomposeQI(p_fld.Name, loc),
4238 (Expression) new SimpleName("value", loc), loc), loc);
4240 set_block = new Block (current_block, set_params, loc, Location.Null);
4241 set_block.AddStatement ((Statement) a_set);
4242 acc_set = new Accessor (set_block, attrs);
4245 a_get = (Statement) new Return ((Expression) DecomposeQI(p_fld.Name, loc), loc);
4246 get_block = new Block (current_block, null, loc, Location.Null);
4247 get_block.AddStatement ((Statement) a_get);
4248 acc_get = new Accessor (get_block, attrs);
4250 p = new Property (p_type, name, mod_flags, (Accessor) acc_get, (Accessor) acc_set, attrs, loc);
4257 current_block = new Block (current_block, current_local_parameters,
4258 lexer.Location, Location.Null);
4265 while (current_block.Implicit)
4266 current_block = current_block.Parent;
4268 res = current_block;
4270 current_block.SetEndLocation (lexer.Location);
4271 current_block = current_block.Parent;
4276 private void AddHandler (Expression evt_definition, string handler_name)
4278 AddHandler (current_block, evt_definition, handler_name);
4281 void CheckAttributeTarget (string a)
4285 case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
4289 Location l = lexer.Location;
4290 Report.Error (658, l, "`" + a + "' is an invalid attribute target");
4295 private void AddHandler (Block b, Expression evt_id, string handler_name)
4297 Location loc = lexer.Location;
4298 string evt_target = evt_id.ToString();
4299 evt_target = evt_target.Substring (0, evt_target.LastIndexOf('.'));
4300 Statement s = (Statement) new AddHandler (evt_id, DecomposeQI(handler_name, loc), DecomposeQI(evt_target, loc), loc);
4304 private void RaiseEvent (string evt_name, ArrayList args)
4306 Location loc = lexer.Location;
4308 Invocation evt_call = new Invocation (DecomposeQI(evt_name, loc), args, lexer.Location);
4309 Statement s = (Statement)(new StatementExpression ((ExpressionStatement) evt_call, loc));
4310 current_block.AddStatement (s);
4313 // FIXME: THIS DOES NOT WORK!!!
4314 private void RemoveHandler (Block b, Expression evt_definition, string handler_name)
4316 Location loc = lexer.Location;
4317 ArrayList neh_args = new ArrayList();
4318 neh_args.Add (new Argument (DecomposeQI(handler_name, loc), Argument.AType.Expression));
4320 ExpressionStatement se = (ExpressionStatement)new New (DecomposeQI("System.EventHandler", loc), neh_args, loc);
4322 CompoundAssign ca = new CompoundAssign (
4323 Binary.Operator.Subtraction, evt_definition, (Expression) se, loc);
4325 Statement s = (Statement)(new StatementExpression ((ExpressionStatement) ca, loc));
4330 // This method is used to get at the complete string representation of
4331 // a fully-qualified type name, hiding inside a MemberAccess ;-)
4332 // This is necessary because local_variable_type admits primary_expression
4333 // as the type of the variable. So we do some extra checking
4335 string GetQualifiedIdentifier (Expression expr)
4337 if (expr is SimpleName)
4338 return ((SimpleName)expr).Name;
4339 else if (expr is MemberAccess)
4340 return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
4342 throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
4346 private void RemoveHandler (Expression evt_definition, string handler_name)
4348 RemoveHandler (current_block, evt_definition, handler_name);
4351 private ConstructorInitializer CheckConstructorInitializer (ref ArrayList s)
4353 ConstructorInitializer ci = null;
4356 if (s[0] is StatementExpression && ((StatementExpression) s[0]).expr is Invocation) {
4357 Invocation i = (Invocation) ((StatementExpression) s[0]).expr;
4359 if (i.expr is BaseAccess) {
4360 BaseAccess ba = (BaseAccess) i.expr;
4361 if (ba.member == "New" || ba.member == ".ctor") {
4362 ci = new ConstructorBaseInitializer (i.Arguments, current_local_parameters, lexer.Location);
4366 if (i.expr.ToString() == "Mono.MonoBASIC.This..ctor") {
4367 ci = new ConstructorThisInitializer (i.Arguments, current_local_parameters, lexer.Location);
4375 void Error_ExpectingTypeName (Location l, Expression expr)
4377 if (expr is Invocation){
4378 Report.Error (1002, l, "; expected");
4380 Report.Error (-1, l, "Invalid Type definition");
4384 static bool AlwaysAccept (MemberInfo m, object filterCriteria) {
4388 private void ReportError9998()
4390 Report.Error (29998, lexer.Location, "This construct is only available in MonoBASIC extended syntax.");
4393 protected override int parse ()
4395 RootContext.InitializeImports(ImportsList);
4396 current_namespace = new Namespace (null, RootContext.RootNamespace);
4397 current_container = RootContext.Tree.Types;
4398 current_container.Namespace = current_namespace;
4399 oob_stack = new Stack ();
4400 switch_stack = new Stack ();
4401 expr_stack = new Stack ();
4402 tmp_blocks = new Stack();
4403 with_stack = new Stack();
4404 statement_stack = new Stack();
4406 UseExtendedSyntax = name.EndsWith(".mbs");
4407 OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
4408 OptionStrict = InitialOptionStrict || UseExtendedSyntax;
4409 OptionCompareBinary = InitialOptionCompareBinary;
4411 lexer = new Tokenizer (input, name, defines);
4412 StringBuilder value = new StringBuilder ();
4414 if (yacc_verbose_flag)
4415 yyparse (lexer, new yydebug.yyDebugSimple ());
4418 } catch (Exception e) {
4419 Report.Error (29999, lexer.Location, lexer.location + "\nParsing error in " + lexer.ref_name + "\n" + e.ToString());
4422 RootContext.VerifyImports();
4424 return Report.Errors;